diff --git a/.claude/README.md b/.claude/README.md index 5316eaee3c..87ad3d3ddf 100644 --- a/.claude/README.md +++ b/.claude/README.md @@ -208,7 +208,7 @@ Automatically runs heading validation when you submit a prompt: 4. **Update Navigation** - - Manually edit mkdocs.yml to add new content + - Manually edit `docs/en/mkdocs.yml` to add new content - Or just ask Claude to update it 5. **Preview Locally** @@ -233,5 +233,6 @@ Consider also using: ## Additional Resources - **CONTRIBUTING.md** - Full contribution guidelines +- **TRANSLATING.md** - Translation guide (all translations are AI-generated) - **Training Site** - https://training.nextflow.io - **Nextflow Docs** - https://www.nextflow.io/docs/latest/ diff --git a/.claude/commands/add-exercise.md b/.claude/skills/add-exercise/SKILL.md similarity index 80% rename from .claude/commands/add-exercise.md rename to .claude/skills/add-exercise/SKILL.md index 96d99e75a7..724d4bbeca 100644 --- a/.claude/commands/add-exercise.md +++ b/.claude/skills/add-exercise/SKILL.md @@ -1,8 +1,13 @@ --- -description: Add an exercise with solution to an existing lesson +name: add-exercise +description: Add an interactive exercise with solution to an existing lesson. Creates properly formatted exercise and solution admonition blocks. Use when a lesson needs hands-on practice. --- -Add an exercise with solution to an existing training lesson. Follow these steps: +Add an exercise with solution to an existing training lesson. + +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory structure and file conventions. + +Follow these steps: 1. Ask the user: diff --git a/.claude/skills/check-highlights/SKILL.md b/.claude/skills/check-highlights/SKILL.md index 69b24df876..125d721532 100644 --- a/.claude/skills/check-highlights/SKILL.md +++ b/.claude/skills/check-highlights/SKILL.md @@ -7,6 +7,8 @@ description: Verify that hl_lines attributes in markdown code blocks correctly h Verify that `hl_lines` attributes in markdown code blocks are correctly set to highlight the intended lines. +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for file conventions. + ## Critical Understanding **`hl_lines` is snippet-relative, NOT related to `linenums`**: @@ -26,13 +28,6 @@ process FOO { <- displayed as line 21 (snippet line 1) ` ``` -## When to Use - -- After writing or editing code blocks with highlights -- When reviewing Before/After comparison blocks -- When a user reports highlights look wrong -- As part of lesson review/validation - ## How to Check For each code block with `hl_lines`: diff --git a/.claude/skills/check-inline-code/SKILL.md b/.claude/skills/check-inline-code/SKILL.md index 02c89dfd17..cbc8f78120 100644 --- a/.claude/skills/check-inline-code/SKILL.md +++ b/.claude/skills/check-inline-code/SKILL.md @@ -7,6 +7,8 @@ description: Review inline code in markdown files for proper formatting and synt Review inline code in markdown files for proper formatting and appropriate use of syntax highlighting. +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for file conventions. + ## What to Check ### 1. Missing Backticks diff --git a/.claude/skills/docker-setup/SKILL.md b/.claude/skills/docker-setup/SKILL.md index 7699443f85..6cff9b1465 100644 --- a/.claude/skills/docker-setup/SKILL.md +++ b/.claude/skills/docker-setup/SKILL.md @@ -200,7 +200,7 @@ docker stop nf-training && docker rm nf-training ## Notes -- Always verify you're in the repository root before starting (check for `mkdocs.yml`) +- Always verify you're in the repository root before starting (check for `docs/en/mkdocs.yml`) - The container uses `sleep infinity` so it persists across multiple command executions - Symlink must be recreated each time the container restarts - For long sessions, periodically check container is still running: `docker ps | grep nf-training` diff --git a/.claude/skills/find-todos/SKILL.md b/.claude/skills/find-todos/SKILL.md index e07938f020..bcd5253494 100644 --- a/.claude/skills/find-todos/SKILL.md +++ b/.claude/skills/find-todos/SKILL.md @@ -12,25 +12,21 @@ Execute from repository root. See [../shared/repo-conventions.md](../shared/repo ## Tasks to Perform 1. **Search Markdown Files** - - Use Grep to find TODO and FIXME in `docs/**/*.md` - Capture file path, line number, and full comment - Note context (which module/lesson) 2. **Search Nextflow Scripts** - - Find TODO/FIXME in `**/*.nf` files - Distinguish between training examples and solution code - Note if in core examples or side-quests 3. **Search Configuration Files** - - - Check `mkdocs.yml` + - Check `docs/en/mkdocs.yml` - Check `.github/**/*.yml` and `.github/**/*.py` - Check `CONTRIBUTING.md` 4. **Categorize Results** - - **High Priority**: Marked as FIXME, TODO(urgent), or blocking - **Documentation**: TODOs in markdown files - **Code**: TODOs in .nf or .py files @@ -42,82 +38,32 @@ Execute from repository root. See [../shared/repo-conventions.md](../shared/repo ## Output Format -Provide an organized report: - -```` +``` # TODO/FIXME Report ## Summary -- Total items: 23 -- High priority: 3 -- Documentation: 15 -- Code: 4 -- Configuration: 1 +Total items, High priority count, by category (Documentation/Code/Configuration) ## High Priority Items - -### docs/hello_nextflow/03_hello_workflow.md:156 -```markdown - -```` +[List FIXME and urgent items with file:line and context] ## Documentation TODOs - -### By File - -**docs/side_quests/debugging.md** (5 items) - -- Line 45: TODO: Add example of common error message -- Line 89: TODO: Include screenshot of trace report -- ... - -**docs/nf4_science/genomics/01_per_sample_variant_calling.md** (3 items) - -- Line 234: TODO: Verify this command works with latest GATK -- ... +[Group by file with line numbers] ## Code TODOs - -### hello-nextflow/hello-world.nf:23 - -```groovy -// TODO: Add error handling for missing files -``` - -## Configuration TODOs - -### CONTRIBUTING.md:204 - -Known limitation documented - needs upstream fix in mkdocs plugin +[Group by file with line numbers] ## Recommendations - -1. **Immediate attention** (3 items): - - - Fix blocking issues in hello_nextflow - - Update genomics examples for latest tools - -2. **Next sprint** (8 items): - - - Complete debugging module exercises - - Add missing screenshots - -3. **Low priority** (12 items): - - Style improvements - - Nice-to-have features +1. Immediate attention: [blocking items] +2. Next sprint: [significant items] +3. Low priority: [nice-to-haves] ## Files with Most TODOs - -1. docs/side_quests/debugging.md (5) -2. docs/nf4_science/genomics/01_per_sample_variant_calling.md (3) -3. hello-nextflow/hello-world.nf (2) - +[Top 3-5 files] ``` ## Notes -- Use Grep tool with pattern `TODO|FIXME` (case insensitive) -- Show enough context to understand what needs doing +- Use Grep with pattern `TODO|FIXME` (case insensitive) - Distinguish between legitimate TODOs and example comments in training materials - Provide actionable priorities, not just a list -``` diff --git a/.claude/commands/new-lesson.md b/.claude/skills/new-lesson/SKILL.md similarity index 83% rename from .claude/commands/new-lesson.md rename to .claude/skills/new-lesson/SKILL.md index 2dadd168a1..ee1fcd2486 100644 --- a/.claude/commands/new-lesson.md +++ b/.claude/skills/new-lesson/SKILL.md @@ -1,9 +1,12 @@ --- -description: Create a new lesson page within an existing training module +name: new-lesson +description: Create a new numbered lesson page within an existing training module. Use when adding a new topic like '05_error_handling.md' to an existing course. --- Create a new lesson page within an existing training module. +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory structure and file conventions. + **Note**: A "module" is a complete training course (like "Hello Nextflow" or "Side Quests"), while a "lesson" is a single numbered page within that module (like "01_hello_world.md"). Follow these steps: @@ -99,10 +102,11 @@ process EXAMPLE { - Clear explanations for beginners 5. Remind the user to: - - Add the lesson to `mkdocs.yml` nav section in the correct module + - Add the lesson to `docs/en/mkdocs.yml` nav section in the correct module - Create corresponding Nextflow example scripts if needed - Add solution files for any exercises in `[module]/solutions/` - Test any Nextflow examples before committing - Run heading validation: `uv run .github/check_headings.py --fix docs/**/*.md` - Preview locally with `mkdocs serve` or Docker to verify formatting + - Translations are handled automatically - when merged to master, the translation workflow will create PRs for each language ```` diff --git a/.claude/commands/new-module.md b/.claude/skills/new-module/SKILL.md similarity index 63% rename from .claude/commands/new-module.md rename to .claude/skills/new-module/SKILL.md index d782654df2..8d216a3b80 100644 --- a/.claude/commands/new-module.md +++ b/.claude/skills/new-module/SKILL.md @@ -1,8 +1,13 @@ --- -description: Scaffold a new complete training module with all standard files +name: new-module +description: Scaffold a complete new training module with standard directory structure, index, orientation, lessons, survey, and next-steps files. Use when creating a new course like 'Advanced Pipelines' or a new domain module. --- -Create a new training module in this repository. Follow these steps: +Create a new training module in this repository. + +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory structure and file conventions. + +Follow these steps: 1. Ask the user for: @@ -30,7 +35,7 @@ Create a new training module in this repository. Follow these steps: - Appropriate use of admonitions - Code examples with proper formatting -4. Add the module to mkdocs.yml navigation structure +4. Add the module to `docs/en/mkdocs.yml` navigation structure 5. Remind the user to: - Create any associated Nextflow example scripts in the root-level directory @@ -38,3 +43,4 @@ Create a new training module in this repository. Follow these steps: - Test all examples thoroughly - Run validation tools before committing - Preview the site locally + - Translations are handled automatically - when merged to master, the translation workflow will create PRs for each language diff --git a/.claude/commands/preview.md b/.claude/skills/preview/SKILL.md similarity index 55% rename from .claude/commands/preview.md rename to .claude/skills/preview/SKILL.md index e0afa9c252..5f71f8556b 100644 --- a/.claude/commands/preview.md +++ b/.claude/skills/preview/SKILL.md @@ -1,9 +1,12 @@ --- -description: Start local preview server to view training materials +name: preview +description: Start local MkDocs preview server to view training material changes. Use when editing documentation, checking formatting, or testing how content renders before committing. --- Start the local MkDocs preview server to view changes to training materials. +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory structure. + **First, check if a server is already running:** ```bash @@ -16,27 +19,13 @@ docker ps --filter "ancestor=ghcr.io/nextflow-io/training-mkdocs:latest" --forma **Start the server using Docker (recommended):** ```bash -docker run --rm -d -p 8000:8000 -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest -``` - -**Alternative options:** - -If you encounter issues with social cards: - -```bash -docker run --rm -p 8000:8000 -e 'CARDS=false' -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest +docker run --rm -d -p 8000:8000 -v ${PWD}:/docs -w /docs/docs/en ghcr.io/nextflow-io/training-mkdocs:latest ``` -If you have Python environment set up: +**Alternative - using uv:** ```bash -mkdocs serve -``` - -Or without social cards: - -```bash -CARDS=false mkdocs serve +uv run _scripts/docs.py serve ``` **After starting the server:** @@ -46,10 +35,7 @@ CARDS=false mkdocs serve - Check console for any build errors - Use `/stop-preview` command or Ctrl+C to stop the server -**Note:** The initial build may take a few minutes as it builds documentation in multiple languages (en, pt, es, fr, it, ko). Wait for the "Serving on" message before accessing the site. - **Common issues:** -- If social cards fail, use CARDS=false option - If port 8000 is busy, use `/stop-preview` to stop other servers - If changes don't appear, check for markdown syntax errors in the console diff --git a/.claude/skills/run-tutorial/SKILL.md b/.claude/skills/run-tutorial/SKILL.md index 3c0776d23f..69a6bdff07 100644 --- a/.claude/skills/run-tutorial/SKILL.md +++ b/.claude/skills/run-tutorial/SKILL.md @@ -85,11 +85,11 @@ Use `TodoWrite` to track progress through phases and sections. Record any issues found. Do not proceed to Phase 2 until validation completes. ``` -### Phase 2: Progressive Execution (Core Unique Value) +### Phase 2: Progressive Execution -**CRITICAL**: Complete ALL steps (2.1-2.6) for EACH section before moving to the next section. Do NOT batch multiple sections together. The entire point of this skill is to catch issues that only appear when following the tutorial step-by-step. +Complete steps 2.1-2.6 for each section before moving to the next. Do not batch sections together. -For each numbered section in the lesson (0, 1, 2, 3...): +For each numbered section in the lesson: #### 2.1 Read and Understand @@ -99,13 +99,11 @@ For each numbered section in the lesson (0, 1, 2, 3...): #### 2.2 Verify Current State Matches "Before" -**This is the key unique check**: Before applying any code change: +Before applying any code change: -1. Read the current file content using the `Read` tool +1. Read the current file content 2. Compare with the "Before" block in the documentation -3. If they don't match, **STOP and report the discrepancy** - - This catches issues where earlier steps didn't work correctly - - This catches documentation that skipped steps +3. If they don't match, stop and report the discrepancy #### 2.3 Apply Code Changes Progressively @@ -125,16 +123,13 @@ For each numbered section in the lesson (0, 1, 2, 3...): - Compare console output with documented "Output" blocks - See [references/acceptable-differences.md](references/acceptable-differences.md) for what to flag vs. ignore -#### 2.6 Confirm Section Complete Before Proceeding +#### 2.6 Confirm Section Complete -**MANDATORY**: Before moving to the next section: +Before moving to the next section: 1. Verify the workflow/script ran successfully (exit code 0) 2. Confirm output matches documentation (within acceptable differences) 3. Update `TodoWrite` to mark section complete -4. Only then proceed to section N+1 - -**Why this matters**: Skipping incremental testing defeats the purpose of this skill. A tutorial might work when you jump to the final solution but fail at intermediate steps - exactly the bugs learners encounter. ### Phase 3: Final Verification @@ -207,8 +202,6 @@ Categorize as Critical / Warning / Minor Table with file, line, current, proposed, reason ``` -**IMPORTANT**: Always read actual section headings from the document. Do not guess. - --- ## Special Cases diff --git a/.claude/skills/shared/repo-conventions.md b/.claude/skills/shared/repo-conventions.md index 73a09ef44a..15114668f5 100644 --- a/.claude/skills/shared/repo-conventions.md +++ b/.claude/skills/shared/repo-conventions.md @@ -5,7 +5,8 @@ Shared reference for all training repository skills. ## Working Directory All skill commands execute from the **repository root** - the directory containing: -- `mkdocs.yml` + +- `docs/en/mkdocs.yml` - `docs/` - `.github/` @@ -13,25 +14,27 @@ Verify location before running commands. Use paths relative to repository root. ## Directory Mapping -| Content Type | Documentation | Working Directory | Solutions | -|--------------|---------------|-------------------|-----------| -| hello_nextflow | `docs/hello_nextflow/` | `hello-nextflow/` | `hello-nextflow/solutions/` | -| hello_nf-core | `docs/hello_nf-core/` | `hello-nf-core/` | `hello-nf-core/solutions/` | -| nf4_science/genomics | `docs/nf4_science/genomics/` | `nf4-science/genomics/` | `nf4-science/genomics/solutions/` | -| nf4_science/rnaseq | `docs/nf4_science/rnaseq/` | `nf4-science/rnaseq/` | `nf4-science/rnaseq/solutions/` | -| side_quests/* | `docs/side_quests/.md` | `side-quests//` | `side-quests/solutions//` | +| Content Type | Documentation | Working Directory | Solutions | +| -------------------- | ------------------------------------ | ----------------------- | --------------------------------- | +| hello_nextflow | `docs/en/docs/hello_nextflow/` | `hello-nextflow/` | `hello-nextflow/solutions/` | +| hello_nf-core | `docs/en/docs/hello_nf-core/` | `hello-nf-core/` | `hello-nf-core/solutions/` | +| nf4_science/genomics | `docs/en/docs/nf4_science/genomics/` | `nf4-science/genomics/` | `nf4-science/genomics/solutions/` | +| nf4_science/rnaseq | `docs/en/docs/nf4_science/rnaseq/` | `nf4-science/rnaseq/` | `nf4-science/rnaseq/solutions/` | +| side_quests/\* | `docs/en/docs/side_quests/.md` | `side-quests//` | `side-quests/solutions//` | **Note**: Documentation uses underscores (`hello_nextflow`), working directories use hyphens (`hello-nextflow`). ## Common Paths -| Purpose | Path | -|---------|------| -| Heading checker | `.github/check_headings.py` | -| MkDocs config | `mkdocs.yml` | -| Site navigation | `mkdocs.yml` (nav section) | -| Devcontainer config | `.devcontainer/devcontainer.json` | -| Contributing guide | `CONTRIBUTING.md` | +| Purpose | Path | +| ----------------------- | ---------------------------------- | +| Heading checker | `.github/check_headings.py` | +| MkDocs config (English) | `docs/en/mkdocs.yml` | +| Site navigation | `docs/en/mkdocs.yml` (nav section) | +| Translation configs | `docs/{lang}/mkdocs.yml` | +| Devcontainer config | `.devcontainer/devcontainer.json` | +| Contributing guide | `CONTRIBUTING.md` | +| Translation guide | `TRANSLATING.md` | ## File Conventions @@ -54,6 +57,7 @@ Verify location before running commands. Use paths relative to repository root. ### Nextflow Version Read from devcontainer.json: + ```bash grep -o '"NXF_VER":\s*"[^"]*"' .devcontainer/devcontainer.json | cut -d'"' -f4 ``` diff --git a/.claude/commands/stop-preview.md b/.claude/skills/stop-preview/SKILL.md similarity index 69% rename from .claude/commands/stop-preview.md rename to .claude/skills/stop-preview/SKILL.md index b184b31ba1..231e65678b 100644 --- a/.claude/commands/stop-preview.md +++ b/.claude/skills/stop-preview/SKILL.md @@ -1,9 +1,12 @@ --- -description: Stop the running MkDocs preview server +name: stop-preview +description: Stop a running MkDocs preview server. Use when port 8000 is busy, switching tasks, or done editing documentation. --- Stop the MkDocs preview server that is running in the background. +See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory structure. + This will: 1. Find any running Docker containers with the training-mkdocs image diff --git a/.claude/skills/validate/SKILL.md b/.claude/skills/validate/SKILL.md index f48b0d1399..7b56d3d557 100644 --- a/.claude/skills/validate/SKILL.md +++ b/.claude/skills/validate/SKILL.md @@ -13,14 +13,15 @@ See [../shared/repo-conventions.md](../shared/repo-conventions.md) for directory This skill MUST invoke other skills during validation. **Do not skip these.** -| Task | Skill | When | -|------|-------|------| -| Check code block highlights | `/check-highlights` | Always | +| Task | Skill | When | +| ---------------------------- | -------------------- | ------ | +| Check code block highlights | `/check-highlights` | Always | | Check inline code formatting | `/check-inline-code` | Always | ## Scope Ask user to specify what to validate if not clear: + - Specific side quest (e.g., "debugging") - Specific module (e.g., "hello_nextflow") - Entire repository (only if explicitly requested) @@ -30,13 +31,11 @@ Ask user to specify what to validate if not clear: Based on the user's request, determine the scope: 1. **Specific side quest** (e.g., "debugging"): - - Documentation file: `docs/side_quests/{name}.md` - Example scripts: `side-quests/{name}/**/*.nf` - Solution files: `side-quests/solutions/{name}/**/*.nf` 2. **Specific module** (e.g., "hello_nextflow"): - - Documentation files: `docs/{module}/**/*.md` - Example scripts: `{module}/**/*.nf` or `hello-nextflow/**/*.nf` - Solution files: `{module}/solutions/**/*.nf` @@ -49,33 +48,28 @@ Based on the user's request, determine the scope: Perform the following checks **only on files within the determined scope**: 1. **Check Heading Numbering** - - Run: `uv run .github/check_headings.py [scoped-path]/**/*.md` - Report any heading numbering issues found - If errors exist, ask if user wants to auto-fix with `--fix` flag 2. **Find TODO/FIXME Comments** - - Search markdown files in scope - Search Nextflow scripts in scope - Categorize by priority (high, medium, low) - Report files with most TODOs 3. **Check Nextflow Script Conventions** - - Find .nf files in scope - Verify they start with `#!/usr/bin/env nextflow` - Check for DSL2 syntax - Report any that don't follow conventions 4. **Find Orphaned Files** - - - Check if main documentation file is referenced in mkdocs.yml + - Check if main documentation file is referenced in `docs/en/mkdocs.yml` - Look for solution files without corresponding exercise documentation - Report any orphaned files within scope 5. **Verify Admonition Syntax** - - Search for common admonition formatting errors in scoped files - Check for proper indentation (4 spaces) - Report any malformed admonitions @@ -97,7 +91,6 @@ Perform the following checks **only on files within the determined scope**: ``` 8. **Check Writing Style** - - Search for LLM-style patterns that should be avoided: - `Let's` or `let's` at start of sentences - `Remember when` or `Remember that` callbacks @@ -109,67 +102,7 @@ Perform the following checks **only on files within the determined scope**: 9. **Deep Lesson Review** (when reviewing a specific lesson file) - If the user asks to review a specific lesson, perform this comprehensive checklist: - - a. **Structure Check**: - - - [ ] Proper heading numbering with trailing periods - - [ ] Heading levels match numbering depth (## for 1., ### for 1.1.) - - [ ] Each major section has "### Takeaway" - - [ ] Each major section has "### What's next?" - - [ ] Logical flow from simple to complex - - [ ] Clear learning objectives stated or implied - - b. **Formatting Check**: - - - [ ] Code blocks have proper titles, line numbers, and highlighting - - [ ] Console output properly formatted with `console title="Output"` - - [ ] File paths use proper markdown formatting - - [ ] Before/After comparisons use tabbed blocks - - [ ] Admonitions properly formatted and indented - - [ ] Each sentence on new line (for clean diffs) - - c. **Content Check**: - - - [ ] Technical accuracy of Nextflow code - - [ ] Commands are correct and runnable - - [ ] Parameter syntax correct (-- for pipeline, - for Nextflow) - - [ ] Examples progress logically - - [ ] Common pitfalls addressed - - [ ] Edge cases explained - - d. **Teaching Effectiveness**: - - - [ ] Clear explanations for beginners - - [ ] Concepts introduced before use - - [ ] Examples are relevant and motivating - - [ ] Exercises appropriate for skill level - - [ ] Solutions available for exercises - - [ ] Good use of tips and warnings - - e. **Cross-References**: - - - [ ] Links to related lessons work - - [ ] References to files/scripts are correct - - [ ] External links are valid - - [ ] Prerequisites clearly stated - - f. **Examples & Code**: - - - [ ] All Nextflow examples are syntactically correct - - [ ] Variable names are clear and consistent - - [ ] Comments explain non-obvious code - - [ ] Examples can be run as shown - - [ ] Output examples match what code produces - - g. **Writing Style** (see CLAUDE.md for full guidelines): - - - [ ] No LLM-style interjections ("Let's", "Remember when...?", "Don't worry") - - [ ] No exclamation-based emphasis ("Much faster!", "So powerful!") - - [ ] Em-dash elaborations replaced with periods or semicolons - - [ ] List explanations use colons, not hyphens - - [ ] Single clear explanation per concept (not multiple phrasings) - - [ ] Professional, direct tone throughout + If the user asks to review a specific lesson, use the checklist in [references/deep-review-checklist.md](references/deep-review-checklist.md). ## Output Format diff --git a/.claude/skills/validate/references/deep-review-checklist.md b/.claude/skills/validate/references/deep-review-checklist.md new file mode 100644 index 0000000000..702765228a --- /dev/null +++ b/.claude/skills/validate/references/deep-review-checklist.md @@ -0,0 +1,65 @@ +# Deep Lesson Review Checklist + +Use this checklist when reviewing a specific lesson file. + +## Structure + +- [ ] Proper heading numbering with trailing periods +- [ ] Heading levels match numbering depth (## for 1., ### for 1.1.) +- [ ] Each major section has "### Takeaway" +- [ ] Each major section has "### What's next?" +- [ ] Logical flow from simple to complex +- [ ] Clear learning objectives stated or implied + +## Formatting + +- [ ] Code blocks have proper titles, line numbers, and highlighting +- [ ] Console output properly formatted with `console title="Output"` +- [ ] File paths use proper markdown formatting +- [ ] Before/After comparisons use tabbed blocks +- [ ] Admonitions properly formatted and indented +- [ ] Each sentence on new line (for clean diffs) + +## Content Accuracy + +- [ ] Technical accuracy of Nextflow code +- [ ] Commands are correct and runnable +- [ ] Parameter syntax correct (-- for pipeline, - for Nextflow) +- [ ] Examples progress logically +- [ ] Common pitfalls addressed +- [ ] Edge cases explained + +## Teaching Effectiveness + +- [ ] Clear explanations for beginners +- [ ] Concepts introduced before use +- [ ] Examples are relevant and motivating +- [ ] Exercises appropriate for skill level +- [ ] Solutions available for exercises +- [ ] Good use of tips and warnings + +## Cross-References + +- [ ] Links to related lessons work +- [ ] References to files/scripts are correct +- [ ] External links are valid +- [ ] Prerequisites clearly stated + +## Examples & Code + +- [ ] All Nextflow examples are syntactically correct +- [ ] Variable names are clear and consistent +- [ ] Comments explain non-obvious code +- [ ] Examples can be run as shown +- [ ] Output examples match what code produces + +## Writing Style + +See CLAUDE.md for full guidelines. + +- [ ] No LLM-style interjections ("Let's", "Remember when...?", "Don't worry") +- [ ] No exclamation-based emphasis ("Much faster!", "So powerful!") +- [ ] Em-dash elaborations replaced with periods or semicolons +- [ ] List explanations use colons, not hyphens +- [ ] Single clear explanation per concept (not multiple phrasings) +- [ ] Professional, direct tone throughout diff --git a/.github/check_headings.py b/.github/check_headings.py index a4d6da7252..e7c8a7e9cf 100644 --- a/.github/check_headings.py +++ b/.github/check_headings.py @@ -58,8 +58,20 @@ def check_heading_numbering(content: str, fix: bool = False) -> Tuple[List[tuple fixed_lines = [] last_depth_nums = {} last_level_depth = 0 + in_code_block = False for i, line in enumerate(lines): + # Track code block state (``` or ~~~) + if line.strip().startswith("```") or line.strip().startswith("~~~"): + in_code_block = not in_code_block + fixed_lines.append(line) + continue + + # Skip lines inside code blocks + if in_code_block: + fixed_lines.append(line) + continue + if not is_heading(line): fixed_lines.append(line) continue diff --git a/.github/mkdocs.Dockerfile b/.github/mkdocs.Dockerfile index 54fc120e0e..489931feb5 100644 --- a/.github/mkdocs.Dockerfile +++ b/.github/mkdocs.Dockerfile @@ -1,4 +1,5 @@ FROM squidfunk/mkdocs-material -COPY requirements.txt . -RUN pip install -r requirements.txt +RUN pip install \ + mkdocs-enumerate-headings-plugin>=0.6.0 \ + mkdocs-quiz>=1.5.0 diff --git a/.github/workflows/docker-mkdocs.yml b/.github/workflows/docker-mkdocs.yml index acb0c2c87e..e3b42e6e93 100644 --- a/.github/workflows/docker-mkdocs.yml +++ b/.github/workflows/docker-mkdocs.yml @@ -7,7 +7,6 @@ on: paths: - ".github/mkdocs.Dockerfile" - ".github/workflows/docker-mkdocs.yml" - - "requirements.txt" push: branches: [master] diff --git a/.github/workflows/docs-dev.yml b/.github/workflows/docs-dev.yml index f56410b7b7..19633a9ed5 100644 --- a/.github/workflows/docs-dev.yml +++ b/.github/workflows/docs-dev.yml @@ -1,8 +1,6 @@ name: Publish docs [dev] on: - release: - types: [published] push: branches: [master] @@ -10,7 +8,50 @@ permissions: contents: write jobs: + discover-languages: + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.find.outputs.languages }} + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: docs + + - name: Find language directories + id: find + run: | + # Find all directories under docs/ that contain mkdocs.yml + langs=$(find docs -maxdepth 2 -name "mkdocs.yml" -exec dirname {} \; | xargs -n1 basename | sort | jq -R -s -c 'split("\n") | map(select(length > 0))') + echo "languages=$langs" >> $GITHUB_OUTPUT + echo "Found languages: $langs" + + build: + needs: discover-languages + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + lang: ${{ fromJson(needs.discover-languages.outputs.languages) }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Dependencies + run: pip install mkdocs-material mkdocs-enumerate-headings-plugin mkdocs-quiz + + - name: Build ${{ matrix.lang }} docs + run: mkdocs build -f docs/${{ matrix.lang }}/mkdocs.yml -d site-${{ matrix.lang }} + + - uses: actions/upload-artifact@v4 + with: + name: site-${{ matrix.lang }} + path: site-${{ matrix.lang }}/ + deploy: + needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -19,15 +60,81 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: 3.10.6 + python-version: "3.12" - name: Install Dependencies - run: pip install -r requirements.txt + run: pip install mkdocs-material mkdocs-enumerate-headings-plugin mkdocs-quiz + + - uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Combine language builds + run: | + mkdir -p combined + # English goes to root + cp -r artifacts/site-en/* combined/ + # Other languages go to subdirectories (discover from artifacts) + for dir in artifacts/site-*; do + lang=$(basename "$dir" | sed 's/site-//') + if [ "$lang" != "en" ] && [ -d "$dir" ]; then + mkdir -p "combined/$lang" + cp -r "$dir"/* "combined/$lang/" + fi + done - name: Configure git run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Build Docs Website - run: mike deploy --push --alias-type copy --update-aliases 0.dev development + - name: Deploy to gh-pages + run: | + VERSION="0.dev" + ALIAS="development" + + # Fetch gh-pages if it exists + git fetch origin gh-pages:gh-pages 2>/dev/null || true + + # Check if gh-pages exists + if git show-ref --verify --quiet refs/heads/gh-pages; then + git checkout gh-pages + # Remove old version directories + rm -rf "$VERSION" "$ALIAS" + else + git checkout --orphan gh-pages + git rm -rf . 2>/dev/null || true + fi + + # Copy combined site to version directory + cp -r combined "$VERSION" + cp -r combined "$ALIAS" + + # Update versions.json for mike compatibility + python3 << 'EOF' + import json + from pathlib import Path + + versions_file = Path("versions.json") + if versions_file.exists(): + versions = json.loads(versions_file.read_text()) + else: + versions = [] + + # Remove existing entry for this version + versions = [v for v in versions if v.get("version") != "0.dev"] + + # Add new entry at the beginning + versions.insert(0, { + "version": "0.dev", + "title": "0.dev", + "aliases": ["development"] + }) + + versions_file.write_text(json.dumps(versions, indent=2)) + EOF + + # Commit and push + git add -A + git commit -m "Deploy development docs" --allow-empty + git push origin gh-pages --force diff --git a/.github/workflows/docs-release.yml b/.github/workflows/docs-release.yml index 71f30b3b2b..6c81d98fe9 100644 --- a/.github/workflows/docs-release.yml +++ b/.github/workflows/docs-release.yml @@ -14,7 +14,50 @@ permissions: contents: write jobs: + discover-languages: + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.find.outputs.languages }} + steps: + - uses: actions/checkout@v4 + with: + sparse-checkout: docs + + - name: Find language directories + id: find + run: | + # Find all directories under docs/ that contain mkdocs.yml + langs=$(find docs -maxdepth 2 -name "mkdocs.yml" -exec dirname {} \; | xargs -n1 basename | sort | jq -R -s -c 'split("\n") | map(select(length > 0))') + echo "languages=$langs" >> $GITHUB_OUTPUT + echo "Found languages: $langs" + + build: + needs: discover-languages + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + lang: ${{ fromJson(needs.discover-languages.outputs.languages) }} + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install Dependencies + run: pip install mkdocs-material mkdocs-enumerate-headings-plugin mkdocs-quiz + + - name: Build ${{ matrix.lang }} docs + run: mkdocs build -f docs/${{ matrix.lang }}/mkdocs.yml -d site-${{ matrix.lang }} + + - uses: actions/upload-artifact@v4 + with: + name: site-${{ matrix.lang }} + path: site-${{ matrix.lang }}/ + deploy: + needs: build runs-on: ubuntu-latest steps: - name: Set version variable @@ -26,25 +69,103 @@ jobs: - uses: actions/setup-python@v5 with: - python-version: 3.10.6 + python-version: "3.12" - - name: Install Dependencies - run: pip install -r requirements.txt + - uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Combine language builds + run: | + mkdir -p combined + # English goes to root + cp -r artifacts/site-en/* combined/ + # Other languages go to subdirectories (discover from artifacts) + for dir in artifacts/site-*; do + lang=$(basename "$dir" | sed 's/site-//') + if [ "$lang" != "en" ] && [ -d "$dir" ]; then + mkdir -p "combined/$lang" + cp -r "$dir"/* "combined/$lang/" + fi + done - name: Configure git run: | git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Build Docs Website - run: mike deploy --alias-type copy --update-aliases $VERSION latest + - name: Deploy to gh-pages + run: | + ALIAS="latest" + + # Fetch gh-pages if it exists + git fetch origin gh-pages:gh-pages 2>/dev/null || true + + # Check if gh-pages exists + if git show-ref --verify --quiet refs/heads/gh-pages; then + git checkout gh-pages + # Remove old version directories (but keep other versions) + rm -rf "$VERSION" "$ALIAS" + else + git checkout --orphan gh-pages + git rm -rf . 2>/dev/null || true + fi + + # Copy combined site to version directory + cp -r combined "$VERSION" + cp -r combined "$ALIAS" + + # Update versions.json for mike compatibility + python3 << 'EOF' + import json + import os + from pathlib import Path + + version = os.environ["VERSION"] + versions_file = Path("versions.json") + if versions_file.exists(): + versions = json.loads(versions_file.read_text()) + else: + versions = [] + + # Remove existing entry for this version + versions = [v for v in versions if v.get("version") != version] + + # Remove 'latest' alias from other versions + for v in versions: + if "aliases" in v: + v["aliases"] = [a for a in v["aliases"] if a != "latest"] + + # Add new entry at the beginning (after dev versions) + new_entry = { + "version": version, + "title": version, + "aliases": ["latest"] + } + + # Insert after any dev versions + insert_idx = 0 + for i, v in enumerate(versions): + if v.get("version", "").endswith(".dev"): + insert_idx = i + 1 + else: + break + versions.insert(insert_idx, new_entry) + + versions_file.write_text(json.dumps(versions, indent=2)) + EOF + + # Commit and push + git add -A + git commit -m "Deploy $VERSION docs" + git push origin gh-pages - name: Pin GitHub Codespaces version run: | - git checkout gh-pages + # Update Codespaces links to use the release version find "$VERSION" -type f -exec sed -i "s|ref=master|ref=$VERSION|g" {} + find latest -type f -exec sed -i "s|ref=master|ref=$VERSION|g" {} + git add . git status - git commit -m "[automated] Pin GitHub Codespaces link versions" - git push --set-upstream origin gh-pages + git commit -m "[automated] Pin GitHub Codespaces link versions" || true + git push origin gh-pages diff --git a/.github/workflows/translate-auto.yml b/.github/workflows/translate-auto.yml new file mode 100644 index 0000000000..a184ceee36 --- /dev/null +++ b/.github/workflows/translate-auto.yml @@ -0,0 +1,138 @@ +name: Auto-update Translations + +# Automatically update translations when English content changes +on: + push: + branches: + - master + paths: + - "docs/en/docs/**/*.md" + + # Allow manual trigger + workflow_dispatch: + +jobs: + detect-changes: + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.check.outputs.languages }} + has_outdated: ${{ steps.check.outputs.has_outdated }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - uses: astral-sh/setup-uv@v4 + + - name: Check for outdated translations + id: check + working-directory: _scripts + run: | + # Check each language for outdated translations + # Discover translation languages (all language dirs except 'en') + languages_with_outdated="" + + for lang in $(find ../docs -maxdepth 2 -name "mkdocs.yml" -exec dirname {} \; | xargs -n1 basename | sort | grep -v '^en$'); do + outdated=$(uv run python translate.py list-outdated "$lang" 2>/dev/null | grep -c "docs/" || echo "0") + if [ "$outdated" -gt 0 ]; then + echo "Found $outdated outdated files for $lang" + if [ -n "$languages_with_outdated" ]; then + languages_with_outdated="$languages_with_outdated,$lang" + else + languages_with_outdated="$lang" + fi + fi + done + + if [ -n "$languages_with_outdated" ]; then + echo "Languages with outdated translations: $languages_with_outdated" + echo "has_outdated=true" >> $GITHUB_OUTPUT + # Convert to JSON array for matrix + json_array=$(echo "$languages_with_outdated" | sed 's/,/","/g' | sed 's/^/["/' | sed 's/$/"]/') + echo "languages=$json_array" >> $GITHUB_OUTPUT + else + echo "No outdated translations found" + echo "has_outdated=false" >> $GITHUB_OUTPUT + echo "languages=[]" >> $GITHUB_OUTPUT + fi + + update-translations: + needs: detect-changes + if: needs.detect-changes.outputs.has_outdated == 'true' + runs-on: ubuntu-latest + strategy: + fail-fast: false + max-parallel: 2 # Limit parallel API calls + matrix: + language: ${{ fromJson(needs.detect-changes.outputs.languages) }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - uses: astral-sh/setup-uv@v4 + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update outdated translations + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + working-directory: _scripts + run: | + echo "Updating outdated translations for ${{ matrix.language }}..." + uv run python translate.py update-outdated --language ${{ matrix.language }} + + - name: Check for changes + id: changes + run: | + if [ -n "$(git status --porcelain docs/${{ matrix.language }}/)" ]; then + echo "has_changes=true" >> $GITHUB_OUTPUT + else + echo "has_changes=false" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.changes.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + LANG="${{ matrix.language }}" + BRANCH="auto-translate-${LANG}-$(date +%Y%m%d-%H%M%S)" + + git checkout -b "$BRANCH" + git add "docs/${LANG}/" + git commit -m "Update ${LANG} translations to match latest English content" + git push origin "$BRANCH" + + gh pr create \ + --title "Update ${{ matrix.language }} translations" \ + --body "$(cat <=1.5.2 + - tree + - conda diff --git a/.seqera/studio-config.yaml b/.seqera/studio-config.yaml new file mode 100644 index 0000000000..105a10d3a0 --- /dev/null +++ b/.seqera/studio-config.yaml @@ -0,0 +1,22 @@ +schemaVersion: "0.0.1" +kind: "studio-config" +session: + name: "Nextflow Training" + description: "Nextflow training materials development environment" + template: + kind: "registry" + registry: "cr.seqera.io/public/data-studio-vscode:1.101.2-0.10-rc" + clone: + enabled: true + path: "/workspace/training" + dependencies: + condaEnvironmentFile: "environment.yaml" + environmentVariables: + - name: NXF_HOME + value: "/workspace/.nextflow" + - name: NXF_EDGE + value: "0" + - name: NXF_VER + value: "25.10.2" + - name: NXF_SYNTAX_PARSER + value: "v2" diff --git a/CLAUDE.md b/CLAUDE.md index 26e6737d5f..bebc200c54 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ This repository contains training materials for Nextflow, built with Material fo - **Purpose**: Educational materials teaching Nextflow workflow development - **Build system**: MkDocs with Material theme and custom plugins -- **Languages**: Multiple (en, pt, es, fr, it, ko) - be aware when editing +- **Languages**: Multiple (en, pt, es, fr, it, ko, pl, tr) - translations are AI-generated, see TRANSLATING.md - **Target audience**: Scientists and developers learning Nextflow ## Common Commands @@ -14,7 +14,7 @@ This repository contains training materials for Nextflow, built with Material fo ### Preview locally ```bash -docker run --rm -it -p 8000:8000 -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest +docker run --rm -it -p 8000:8000 -v ${PWD}:/docs -w /docs/docs/en ghcr.io/nextflow-io/training-mkdocs:latest # View at http://0.0.0.0:8000/ ``` @@ -33,13 +33,16 @@ prettier --write docs/**/*.md ## Repository Structure -- `docs/` - All training content (markdown) - - `hello_nextflow/` - Basic Nextflow introduction - - `hello_nf-core/` - nf-core framework training - - `nf4_science/` - Domain-specific training (genomics, RNAseq) - - `side_quests/` - Advanced topics +- `docs/en/` - English training content (source) + - `docs/` - Markdown content + - `hello_nextflow/` - Basic Nextflow introduction + - `hello_nf-core/` - nf-core framework training + - `nf4_science/` - Domain-specific training (genomics, RNAseq) + - `side_quests/` - Advanced topics + - `mkdocs.yml` - Site navigation and configuration +- `docs/{lang}/` - Translated content (pt, es, fr, it, ko, pl, tr) +- `_scripts/` - Translation and build scripts - `hello-nextflow/`, `nf4-science/`, etc. - Example Nextflow scripts for lessons -- `mkdocs.yml` - Site navigation and configuration - `.github/check_headings.py` - Validates heading numbering ## Important Conventions @@ -157,11 +160,10 @@ module_name/ ## Gotchas -1. **Social cards are slow**: If preview is slow, disable with `CARDS=false` -2. **Multilingual builds**: Initial build takes minutes due to multiple languages -3. **Heading validation**: Auto-runs on commit via pre-commit hook -4. **Excalidraw diagrams**: Must use `.excalidraw.svg` extension for editability -5. **Module vs Lesson**: Module = entire course (e.g. "Hello Nextflow"), Lesson = single page (e.g. "01_hello_world.md") +1. **Multilingual builds**: Initial build takes minutes due to multiple languages +2. **Heading validation**: Auto-runs on commit via pre-commit hook +3. **Excalidraw diagrams**: Must use `.excalidraw.svg` extension for editability +4. **Module vs Lesson**: Module = entire course (e.g. "Hello Nextflow"), Lesson = single page (e.g. "01_hello_world.md") ## Testing Nextflow Examples @@ -192,6 +194,7 @@ nextflow run example.nf -resume # verify caching works ## Resources - **Full contribution guide**: See CONTRIBUTING.md +- **Translation guide**: See TRANSLATING.md (all translations are AI-generated) - **Training site**: https://training.nextflow.io - **Nextflow docs**: https://nextflow.io/docs/latest/ - **MkDocs Material**: https://squidfunk.github.io/mkdocs-material/ diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..d165b200d7 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,14 @@ +# Default owners for everything +* @nextflow-io/training + +# Translations - per-language teams +/docs/pt/ @nextflow-io/training-lang-pt +/docs/es/ @nextflow-io/training-lang-es +/docs/fr/ @nextflow-io/training-lang-fr +/docs/it/ @nextflow-io/training-lang-it +/docs/ko/ @nextflow-io/training-lang-ko +/docs/pl/ @nextflow-io/training-lang-pl +/docs/tr/ @nextflow-io/training-lang-tr + +# Translation scripts +/_scripts/ @nextflow-io/training diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b32f3a752c..f6448b8344 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,9 @@ A short version for this training site is below. If you are used to using Docker and don't want to mess around with Python, you can run the following command to preview the site: ```bash -docker run --rm -it -p 8000:8000 -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest +docker run --rm -it -p 8000:8000 -v ${PWD}:/docs \ + -w /docs/docs/en \ + ghcr.io/nextflow-io/training-mkdocs:latest ``` This uses a custom image with all required mkdocs plugins. @@ -58,41 +60,80 @@ INFO - [21:52:17] Watching paths for changes: 'docs', 'mkdocs.yml' INFO - [21:52:17] Serving on http://0.0.0.0:8000/ ``` +> Note: The working directory is `docs/en` so paths are relative to that. + Visit in your web browser to view the site. Pages will automatically refresh when you save changes in your editor. -### Python +### Python (uv) -If you have a recent version of Python installed, then local installation should be as simple as: +If you have Python installed, we recommend using [uv](https://docs.astral.sh/uv/) to manage dependencies. +Install uv, then run: ```bash -pip install -r requirements.txt +uv run _scripts/docs.py live ``` -Once installed, you can view the site by running: +This will automatically install all dependencies and start a local preview server. +The log output will show a URL, probably - open this in your browser to view the site. +Pages will automatically refresh when you save changes in your editor. + +To build all languages: ```bash -mkdocs serve +uv run _scripts/docs.py build-all ``` -The log output will show a URL, probably - open this in your browser to view the site. -Pages will automatically refresh when you save changes in your editor. +## Translations -### Social cards +Training materials are available in multiple languages. -If you're having trouble with the social sharing card images, set the environment variable `CARDS` to `false`: +> [!WARNING] +> All translations are **generated and maintained by AI**. +> Do not submit manual translations - they will be overwritten by automated updates. -```bash -CARDS=false mkdocs serve -``` +### For Readers -```bash -docker run --rm -it -p 8000:8000 -e 'CARDS=false' -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest -``` +If you find a translation error: + +1. Check if it's a glossary issue (wrong term used consistently) +2. Open an issue describing: language, file, current text, expected text +3. A maintainer will update the translation prompt and regenerate + +### For Contributors + +To improve translations, update the LLM prompts - not the translated files directly: + +- **Language-specific rules**: Edit `docs//llm-prompt.md` +- **General formatting rules**: Edit `_scripts/general-llm-prompt.md` + +Then use the GitHub Actions workflow to regenerate: + +1. Go to **Actions** → **Translate** → **Run workflow** +2. Select the language and `translate-page` command +3. The workflow will regenerate the translation with your prompt changes + +### Why AI-Only? + +Manual translations don't scale and aren't maintainable: + +- They get overwritten when English content changes +- There's no way to track intentional vs accidental differences +- The same errors reappear in new content +- Quality varies between contributors + +By using AI with carefully tuned prompts, we ensure: + +- Consistent terminology across all pages +- Automatic updates when English changes +- Reproducible, auditable translations +- Easy fixes via prompt improvements + +For detailed information, see [TRANSLATING.md](TRANSLATING.md). ## Announcement banner -If there is an announcement banner, you can enable and customise it using the following config in `mkdocs.yml`: +If there is an announcement banner, you can enable and customise it using the following config in `docs/en/mkdocs.yml`: ```yaml extra: @@ -103,7 +144,7 @@ extra: register_url: https://nf-co.re/events/2024/training-foundational-march ``` -If you need more customisation, edit `docs/assets/overrides/main.html` +If you need more customisation, edit `docs/en/overrides/main.html` ## Figures & diagrams @@ -173,7 +214,7 @@ uv run .github/check_headings.py docs/**/*.md uv run .github/check_headings.py --fix docs/**/*.md ``` -Otherwise, run `pip install typer rich` then `python .github/check_headings.py`. +Otherwise, run `uv run .github/check_headings.py` which handles dependencies automatically. The script runs automatically in CI on markdown file changes via GitHub Actions, and will cause a CI failure if any incorrect headings are found. @@ -293,7 +334,7 @@ I recommend the [Todo Tree VSCode extension](https://marketplace.visualstudio.co A list of key ones also included here: -- Remove plugin install from Phil's GitHub fork in `requirements.txt` and `.github/mkdocs.Dockerfile` when [this PR](https://github.com/timvink/mkdocs-enumerate-headings-plugin/pull/33) is merged +- Remove plugin install from Phil's GitHub fork in `.github/mkdocs.Dockerfile` and `_scripts/docs.py` when [this PR](https://github.com/timvink/mkdocs-enumerate-headings-plugin/pull/33) is merged ## Preview Release @@ -349,7 +390,7 @@ The script caches: - Built docs for your version - Generated TLS certificates -A hash of source files (`docs/`, `mkdocs.yml`) is computed to detect changes. +A hash of source files (`docs/en/`) is computed to detect changes. If you modify source files, the docs will be rebuilt automatically on the next run. Use `--clean` to delete the work directory on exit, or manually remove `.preview-release/` to force a fresh build. diff --git a/LICENSE.md b/LICENSE.md index d433d7ab29..18180ec25e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -4,7 +4,7 @@ -Creative Commons License +Creative Commons License ### You are free to: diff --git a/README.md b/README.md index a301b5243b..81b756388b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,6 @@ We welcome fixes and improvements from the community. Please fork the repository This training material is developed and maintained by [Seqera](https://seqera.io) and released under an open-source license ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) for the benefit of the community. You are welcome to reuse these materials according to the terms of the license. If you are an instructor running your own trainings, we'd love to hear about how it goes and what we could do to make it easier. -Creative Commons License +Creative Commons License > Copyright 2025, Seqera. All examples and descriptions are licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. diff --git a/TRANSLATING.md b/TRANSLATING.md index 97a01f4657..04e6b589ee 100644 --- a/TRANSLATING.md +++ b/TRANSLATING.md @@ -1,103 +1,447 @@ -# 🌐 Translation Guide +# Translation Guide -## Contribution model +This document describes how translations work for the Nextflow training materials. -The typical workflow for contributing with translation is as follows: + +> [!WARNING] +> **All translations are generated and maintained by AI.** +> Do not submit manual translations - they will be overwritten by automated updates. +> Instead, improve the translation prompts to fix issues permanently. + -1. Make a _fork_ of the GitHub repository to your own account -2. Work locally (see below) and make your changes - - Check if the language you want to translate to is already enabled in the `mkdocs.yml` file. If it isn't do it according to [this](https://github.com/nextflow-io/training/pull/163/files#diff-98d0f806abc9af24e6a7c545d3d77e8f9ad57643e27211d7a7b896113e420ed2) example. - - If you want to improve an already existing translation, the file already exists and the language is already set up. Simply open the file and work on it. Otherwise, create the new file with the following pattern: If the original file in English is `filename.md`, you will create in the same folder a new file named `filename.language_code.md`, where `language_code` is the language code that you can find [here](https://en.wikipedia.org/wiki/ISO_639-1), for the language you wish to translate to. Pay attention to the language code, as it has to be the same that is specified in the `mkdocs.yml` file for that language. - - Ideally, for new files, copy-paste the original English contents into the new file and commit _before_ starting to translate. This way, it's easier to review your pull request by seeing the original file in English vs the translated changes you did. -3. Commit and push to your forked repository -4. Open a pull-request against the main repo, which can be reviewed and merged -5. Tag other contributors with @ requesting a review. Pull Requests should only be merged if they have at least a single review. +## Overview -**Important**: Avoid making changes to both the original files in English and in their respective translated versions in the **same commit**. This breaks GitLocalize, which is the system that monitors what files need to be synced. +Translations are managed through a combination of: -The training website is built using [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). -It's a static site generator designed for documentation websites which is fast and lightweight and comes with a lot of nice features. -We use the open-source version of the tool (not any of the "insiders" features, currently). +1. **LLM prompts** that define translation rules and glossaries +2. **GitHub Actions** that automatically regenerate translations +3. **Human review** to catch errors and improve prompts -To make changes, you should run the website locally so that you can preview changes. +The key insight: **to fix a translation, fix the prompt** - not the translated file. -## Preview +### Contents -See the [mkdocs material docs](https://squidfunk.github.io/mkdocs-material/getting-started/) for full installation instructions in order to see the preview of the training material with your changes/translations. A short version for this training site is below. +- [How to Improve Existing Translations](#how-to-improve-existing-translations) +- [How Automatic Translation Updates Work](#how-automatic-translation-updates-work) +- [Reviewing Translation PRs](#reviewing-translation-prs) +- [How to Add a Missing Course](#how-to-add-a-missing-course) +- [How to Add a New Language](#how-to-add-a-new-language) +- [Directory Structure](#directory-structure) +- [CLI Reference (For Maintainers)](#cli-reference-for-maintainers) -### Docker +--- -If you are used to using Docker and don't want to mess around with Python, you can run the following command to preview the site: +## How to Improve Existing Translations -```bash -docker run --rm -it -p 8000:8000 -v ${PWD}:/docs ghcr.io/nextflow-io/training-mkdocs:latest +Found a translation error or want to suggest an improvement? Here's how to fix it the right way. + +```mermaid +flowchart TD + A[Find translation error] --> B{Type of issue?} + B -->|Wrong term| C[Update glossary in
docs/LANG/llm-prompt.md] + B -->|Wrong style/tone| D[Update grammar rules in
docs/LANG/llm-prompt.md] + B -->|Structural issue| E[Update rules in
_scripts/general-llm-prompt.md] + C --> F[Open PR with prompt change] + D --> F + E --> F + F --> G[Trigger translation workflow
on PR branch] + G --> H[Review updated translation] + H --> I{Correct?} + I -->|Yes| J[Merge PR] + I -->|No| B ``` -This uses a custom image with all required mkdocs plugins. -You should get some output that looks like this: +> [!NOTE] +> The translation workflow can only run on branches in the main repository, not on forks. +> If you'd like to contribute translation improvements and need write access, please open an issue to request it. + +### The Right Way: Update the Prompt + +The **only** sustainable way to fix translations is to improve the LLM prompts: + +1. **For language-specific issues** (terminology, tone, grammar): + + - Edit `docs//llm-prompt.md` + - Add glossary terms, clarify rules, provide examples + +2. **For structural issues** (code blocks, formatting, links): + + - Edit `_scripts/general-llm-prompt.md` + - Add rules with before/after examples + +3. **Re-run the translation** via GitHub Actions: + + - Go to **Actions** → **Translate** → **Run workflow** + - Select language and command (`translate-page` or `update-outdated`) + +4. **Submit a PR** with both the prompt change and regenerated translation + +### Why Not Edit Translations Directly? + +- Direct edits are **overwritten** when English content changes +- There's no way to track why a translation differs from the AI output +- Future maintainers won't know which changes were intentional +- The same error will reappear in new content + +### Reporting Issues + +If you find errors but can't fix the prompts yourself: + +1. Open a GitHub issue +2. Include: language, file path, current text, expected text +3. Explain why the current translation is wrong +4. A maintainer will update the prompt and re-run + +--- + +## Understanding the Translation Prompts + +The translation system uses two types of prompts: + +### General Prompt (`_scripts/general-llm-prompt.md`) + +Contains rules that apply to ALL languages: + +- What to translate vs keep in English +- Code block handling (never translate syntax, always translate comments) +- Formatting preservation (links, anchors, admonitions) +- Technical term lists (Nextflow keywords, operators, directives) +- Validation requirements + +### Language-Specific Prompts (`docs//llm-prompt.md`) + +Contains rules specific to each language: + +- Grammar and tone (formal/informal) +- Terms that get translated (with exact translations) +- Admonition titles +- Common expressions +- Language-specific mistakes to avoid + +### Prompt Precedence + +When prompts conflict, **language-specific rules override general rules**. This allows languages to customize behavior (e.g., French keeps "workflow" in English even though it could theoretically be translated). + +### Contributing Prompt Improvements -```console -INFO - Documentation built in 27.56 seconds -INFO - [21:52:17] Watching paths for changes: 'docs', 'mkdocs.yml' -INFO - [21:52:17] Serving on http://0.0.0.0:8000/ +If you're a native speaker and want to improve translation quality: + +1. **Read the current prompt** for your language in `docs//llm-prompt.md` +2. **Identify the issue type**: + - Wrong term → Add/update entry in "Terms to Translate" + - Wrong tone → Clarify in "Grammar & Tone" section + - Repeated error → Add to "Common Mistakes" section +3. **Provide examples** showing wrong vs correct translations +4. **Test your change** by running the translation workflow +5. **Submit a PR** with both prompt change and sample output + +Good prompt improvements include: + +- Adding missing glossary terms +- Clarifying ambiguous rules with examples +- Adding common mistakes that keep occurring +- Regional spelling/grammar preferences + +--- + +## How Automatic Translation Updates Work + +When English source files are modified, translations are automatically updated via GitHub Actions: + +```mermaid +flowchart TD + A[English file changed] --> B[GitHub Actions triggered] + B --> C[Detect outdated translations] + C --> D{Any outdated?} + D -->|No| E[Done] + D -->|Yes| F[AI updates changed sections] + F --> G[Create PR for each language] + G --> H[Human review] + H --> I{Approved?} + I -->|Yes| J[Merge PR] + I -->|No| K[Update llm-prompt.md] + K --> L[Re-run translation] + L --> H ``` -Visit in your web browser to view the site. -Pages will automatically refresh when you save changes in your editor. +### Key Points + +- The AI makes **minimal changes**, updating only sections that changed in English +- Translations preserve line-by-line structure for easy diff review +- Each language gets a separate PR for independent review/merge +- The system uses git commit timestamps to detect outdated files + +--- + +## Reviewing Translation PRs + +When reviewing a translation PR (whether automatic or triggered manually), follow these guidelines: + +### What to Check + +1. **Technical accuracy** + + - Are Nextflow concepts correctly explained? + - Are code examples unchanged (only comments translated)? + - Are technical terms used consistently with the glossary? + +2. **Formatting preservation** + + - Are code blocks intact and properly formatted? + - Are admonitions (note, tip, warning) correctly structured? + - Are heading anchors preserved (`{ #anchor-name }`)? + - Are links working (URLs unchanged, only link text translated)? + +3. **Language quality** + - Is the tone appropriate (formal/informal per language)? + - Are translations natural and readable? + - Are there any obvious errors or awkward phrasings? + +### How to Handle Issues + + +> [!CAUTION] +> **Do NOT suggest changes directly to translation PRs.** +> Direct edits will be overwritten on the next automatic update. +> Instead, update the translation prompts and re-run the translation. + + +When you find an issue during review: + +```mermaid +flowchart TD + A[Find translation error] --> B{Type of issue?} + B -->|Wrong term| C[Update glossary in
docs/LANG/llm-prompt.md] + B -->|Wrong style/tone| D[Update grammar rules in
docs/LANG/llm-prompt.md] + B -->|Structural issue| E[Update rules in
_scripts/general-llm-prompt.md] + C --> F[Commit prompt change to same PR] + D --> F + E --> F + F --> G[Trigger translation workflow] + G --> H[Review updated translation] +``` + +#### Workflow for Fixing Issues + +1. **Edit the appropriate prompt file** in the same PR branch: + + - Language-specific issues → `docs//llm-prompt.md` + - General formatting issues → `_scripts/general-llm-prompt.md` + +2. **Trigger the translation workflow** to regenerate: + + - Go to **Actions** → **Translate** → **Run workflow** + - Select the language and `translate-page` or `update-outdated` + - Target the PR branch (not `master`) -### Python +3. **Review the updated translation** to verify the fix -If you have a recent version of Python installed, then local installation should be as simple as: +4. **Approve and merge** once the translation is correct + +#### Example: Fixing a Wrong Term + +If "workflow" is incorrectly translated as "flujo" instead of "flujo de trabajo" in Spanish: + +1. In the PR branch, edit `docs/es/llm-prompt.md` +2. Add or update the glossary entry: + + | English | Spanish | + | -------- | ------------------------------ | + | workflow | flujo de trabajo (NOT "flujo") | + +3. Run the translation workflow targeting this branch +4. Verify the fix in the updated PR + +### Approving PRs + +Once you've verified the translation quality: + +1. Check that CI passes (build succeeds) +2. Approve the PR +3. Merge (squash merge recommended) + +--- + +## How to Add a Missing Course + +If a language exists but is missing content (e.g., Portuguese has `hello_nextflow/` but not `nf4_science/`): + +### Using GitHub Actions (Recommended) + +1. Go to **Actions** → **Translate** → **Run workflow** +2. Select language (e.g., `pt`) +3. Select command: `add-missing` +4. Optionally specify a filter (e.g., `nf4_science`) +5. The workflow creates a PR with translations + +### Using the CLI (Requires API Key) + +For maintainers with `ANTHROPIC_API_KEY` access: ```bash -pip install -r requirements.txt +cd _scripts + +# Check what's missing +uv run python translate.py list-missing pt + +# Translate one file at a time (recommended for large files) +uv run python translate.py translate-page -l pt -p nf4_science/index.md + +# Or translate all missing with a filter +uv run python translate.py add-missing -l pt --include nf4_science ``` -Once installed, you can view the site by running: +### After Translation + +1. Review the generated translations +2. Check if any prompt updates are needed +3. Submit a PR + +--- + +## How to Add a New Language + +### Step 1: Create Language Structure + +Use the GitHub Actions workflow or CLI: ```bash -mkdocs serve +cd _scripts +uv run python docs.py new-lang ``` -The log output will show a URL, probably - open this in your browser to view the site. -Pages will automatically refresh when you save changes in your editor. +This creates: + +- `docs//mkdocs.yml` - MkDocs config +- `docs//llm-prompt.md` - Translation prompt (requires customization) +- `docs//docs/.gitkeep` - Placeholder + +### Step 2: Customize the Translation Prompt + +Edit `docs//llm-prompt.md` to define: + +1. **Grammar preferences** + + - Formal or informal tone + - Regional spelling conventions + - Specific grammar rules -Even though it's required that you read this document in order to contribute with translations, it's really important that you also check the [CONTRIBUTING.md](https://github.com/nextflow-io/training/blob/master/CONTRIBUTING.md) file. +2. **Glossary** -## Translation Glossaries + - Terms to keep in English + - Terms to translate (with exact translations) + - Common mistakes to avoid -In order to keep consistency in translations, every language should have a translation glossary where common technical terms and terms related to Nextflow have an official translation to be followed by future translators. Ideally, these links should point to an online spreadsheet where anyone can comment and make suggestions, but not edit. +3. **Admonition titles** + - Translations for Note, Tip, Warning, Exercise, Solution -- [Portuguese](https://docs.google.com/spreadsheets/d/1HUa3BO2kwukhX4EXQ-1blXeP5iueUdM23OwDRpfarDg/edit?usp=sharing) +See existing language prompts for examples (e.g., `docs/pt/llm-prompt.md`). -## Merging +### Step 3: Register the Language -Aiming at a more comprehensive git history, pull request commits will be [squashed](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) with a commit message outlining: +Add the language code to: -- What file(s)/page(s) the PR translated (preferably, 1 PR per file) -- What training material the translated file(s)/page(s) is/are part of -- What language it was translated into +1. `_scripts/docs.py` - `SUPPORTED_LANGS` list +2. `docs/en/mkdocs.yml` - `extra.alternate` for language switcher +3. `.github/workflows/translate.yml` - language dropdown options -The squashing is done by the maintainers of the GitHub repository, so if you're doing a contribution, you don't have to worry about that. This practice gives more freedom/space for contributors to get into more detail in their commit title/message without having to add the info outlined above. For example: +### Step 4: Generate Initial Translations -PR: Translate to Brazilian Portuguese the Seqera Platform section of the basic training +Use GitHub Actions: -- Commit #1: Add missing translations to sections 1 and 2 -- Commit #2: Add translated image to section 3 -- Commit #3: Translate sections 4, 5 and 6 +1. Go to **Actions** → **Translate** → **Run workflow** +2. Select the new language +3. Select command: `add-missing` +4. Filter to `hello_nextflow` for initial testing -Squashed commit to merge: +### Step 5: Review and Iterate +1. Review the PR with generated translations +2. Update `llm-prompt.md` to fix any issues +3. Re-run translations as needed +4. Merge when satisfied + +--- + +## Directory Structure + +``` +docs/ +├── en/ # English (source) +│ ├── mkdocs.yml # Main config +│ ├── overrides/ # Theme customization +│ └── docs/ # English content +├── pt/ # Portuguese +│ ├── mkdocs.yml # Inherits from en +│ ├── llm-prompt.md # Translation rules +│ └── docs/ # Translated content +├── es/ # Spanish +│ └── ... +└── ... + +_scripts/ +├── translate.py # Translation CLI +├── general-llm-prompt.md # Shared translation rules +└── docs.py # Build/serve CLI +``` + +## CLI Reference (For Maintainers) + +> [!NOTE] +> The CLI requires `ANTHROPIC_API_KEY` for translation commands. +> Community contributors should use GitHub Actions instead. + +All commands run from `_scripts/` directory: + +```bash +cd _scripts ``` -Translate to Brazilian Portuguese the Seqera Platform section of the Basic Training - - Add missing translations to sections 1 and 2 - - Add translated image to section 3 - - Translate sections 4, 5 and 6 +### List Commands (No API key required) + +```bash +# List files that need translation +uv run python translate.py list-missing + +# List translations older than English source +uv run python translate.py list-outdated + +# List translated files with no English source (orphans) +uv run python translate.py list-removable +``` + +### Translation Commands (Require ANTHROPIC_API_KEY) + +```bash +# Translate a single file +uv run python translate.py translate-page -l -p + +# Translate all missing files +uv run python translate.py add-missing -l + +# Translate missing files matching pattern +uv run python translate.py add-missing -l --include hello_nextflow + +# Update outdated translations (smart minimal diff) +uv run python translate.py update-outdated -l + +# Remove orphaned translations +uv run python translate.py remove-removable -l +``` + +### Preview Commands (No API key required) + +```bash +# Serve docs locally +uv run python docs.py serve + +# Build docs +uv run python docs.py build-lang ``` -It doesn't have to explicitly state every single commit in the PR. +--- -## Notes +## References -In the original version in English, it happens that many keywords are written just like the words in English (`value` channel factory for value channels). When translating to other languages, it doesn't make sense to use the back ticks for the translated word, _valor_, for example, as _valor_ is not a Nextflow keyword. In such circumstances, the keyword should be placed between parenthesis with the back ticks, or the back ticks should be simply ignored for the translation. +- [FastAPI Translation System](https://github.com/fastapi/fastapi/tree/master/scripts) - Inspiration for this implementation +- [Portuguese Glossary](https://docs.google.com/spreadsheets/d/1HUa3BO2kwukhX4EXQ-1blXeP5iueUdM23OwDRpfarDg/edit) diff --git a/_scripts/doc_parsing_utils.py b/_scripts/doc_parsing_utils.py new file mode 100644 index 0000000000..e18f4483c5 --- /dev/null +++ b/_scripts/doc_parsing_utils.py @@ -0,0 +1,700 @@ +""" +Utilities for extracting and validating document elements. + +Adapted from FastAPI's doc_parsing_utils.py for Nextflow training. +""" + +import re +from typing import TypedDict, Union + +# Header patterns +HEADER_WITH_PERMALINK_RE = re.compile(r"^(#{1,6}) (.+?)(\s*\{\s*#.*\s*\})?\s*$") +HEADER_LINE_RE = re.compile(r"^(#{1,6}) (.+?)(?:\s*\{\s*(#.*)\s*\})?\s*$") + +# Link patterns +MARKDOWN_LINK_RE = re.compile( + r"(?.*?)\]" # link text (non-greedy) + r"\(" + r"(?P[^)\s]+)" # url (no spaces and `)`) + r'(?:\s+["\'](?P.*?)["\'])?' # optional title in "" or '' + r"\)" + r"(?:\s*\{(?P<attrs>[^}]*)\})?" # optional attributes in {} +) + +HTML_LINK_RE = re.compile(r"<a\s+[^>]*>.*?</a>") +HTML_LINK_TEXT_RE = re.compile(r"<a\b([^>]*)>(.*?)</a>") +HTML_LINK_OPEN_TAG_RE = re.compile(r"<a\b([^>]*)>") +HTML_ATTR_RE = re.compile(r'(\w+)\s*=\s*([\'"])(.*?)\2') + +# Code block patterns +CODE_BLOCK_LANG_RE = re.compile(r"^`{3,4}([\w-]*)", re.MULTILINE) + +# Comment patterns for code +SLASHES_COMMENT_RE = re.compile( + r"^(?P<code>.*?)(?P<comment>(?:(?<= )// .*)|(?:^// .*))?$" +) + +HASH_COMMENT_RE = re.compile(r"^(?P<code>.*?)(?P<comment>(?:(?<= )# .*)|(?:^# .*))?$") + +# Multi-line block comment patterns (for Groovy/Nextflow/Java) +# Matches: /* or opening of block comment +BLOCK_COMMENT_START_RE = re.compile(r"^\s*/\*") +# Matches: */ or closing of block comment +BLOCK_COMMENT_END_RE = re.compile(r"\*/\s*$") +# Matches lines inside block comment: * comment text +BLOCK_COMMENT_LINE_RE = re.compile(r"^(?P<prefix>\s*\*\s?)(?P<comment>.*)$") + + +class HeaderPermalinkInfo(TypedDict): + line_no: int + hashes: str + title: str + permalink: str + + +class MarkdownLinkInfo(TypedDict): + line_no: int + url: str + text: str + title: Union[str, None] + attributes: Union[str, None] + full_match: str + + +class HTMLLinkAttribute(TypedDict): + name: str + quote: str + value: str + + +class HtmlLinkInfo(TypedDict): + line_no: int + full_tag: str + attributes: list[HTMLLinkAttribute] + text: str + + +class MultilineCodeBlockInfo(TypedDict): + lang: str + start_line_no: int + content: list[str] + + +# Header permalinks +# -------------------------------------------------------------------------------------- + + +def extract_header_permalinks(lines: list[str]) -> list[HeaderPermalinkInfo]: + """ + Extract list of header permalinks from the given lines. + + Return list of HeaderPermalinkInfo, where each dict contains: + - `line_no` - line number (1-based) + - `hashes` - string of hashes representing header level (e.g., "###") + - `permalink` - permalink string (e.g., "{#permalink}") + """ + headers: list[HeaderPermalinkInfo] = [] + in_code_block3 = False + in_code_block4 = False + + for line_no, line in enumerate(lines, start=1): + if not (in_code_block3 or in_code_block4): + if line.startswith("```"): + count = len(line) - len(line.lstrip("`")) + if count == 3: + in_code_block3 = True + continue + elif count >= 4: + in_code_block4 = True + continue + + header_match = HEADER_WITH_PERMALINK_RE.match(line) + if header_match: + hashes, title, permalink = header_match.groups() + headers.append( + HeaderPermalinkInfo( + hashes=hashes, + line_no=line_no, + permalink=permalink or "", + title=title, + ) + ) + + elif in_code_block3: + if line.startswith("```"): + count = len(line) - len(line.lstrip("`")) + if count == 3: + in_code_block3 = False + continue + + elif in_code_block4: + if line.startswith("````"): + count = len(line) - len(line.lstrip("`")) + if count >= 4: + in_code_block4 = False + continue + + return headers + + +def remove_header_permalinks(lines: list[str]) -> list[str]: + """Remove permalinks from headers in the given lines.""" + modified_lines: list[str] = [] + for line in lines: + header_match = HEADER_WITH_PERMALINK_RE.match(line) + if header_match: + hashes, title, _permalink = header_match.groups() + modified_line = f"{hashes} {title}" + modified_lines.append(modified_line) + else: + modified_lines.append(line) + return modified_lines + + +def replace_header_permalinks( + text: list[str], + header_permalinks: list[HeaderPermalinkInfo], + original_header_permalinks: list[HeaderPermalinkInfo], +) -> list[str]: + """ + Replace permalinks in the given text with the permalinks from the original document. + + Fail if the number or level of headers does not match the original. + """ + modified_text: list[str] = text.copy() + + if len(header_permalinks) != len(original_header_permalinks): + raise ValueError( + "Number of headers with permalinks does not match the number in the " + "original document " + f"({len(header_permalinks)} vs {len(original_header_permalinks)})" + ) + + for header_no in range(len(header_permalinks)): + header_info = header_permalinks[header_no] + original_header_info = original_header_permalinks[header_no] + + if header_info["hashes"] != original_header_info["hashes"]: + raise ValueError( + "Header levels do not match between document and original document" + f" (found {header_info['hashes']}, expected {original_header_info['hashes']})" + f" for header #{header_no + 1} in line {header_info['line_no']}" + ) + line_no = header_info["line_no"] - 1 + hashes = header_info["hashes"] + title = header_info["title"] + permalink = original_header_info["permalink"] + if permalink: + modified_text[line_no] = f"{hashes} {title}{permalink}" + else: + modified_text[line_no] = f"{hashes} {title}" + + return modified_text + + +# Markdown links +# -------------------------------------------------------------------------------------- + + +def extract_markdown_links(lines: list[str]) -> list[MarkdownLinkInfo]: + """ + Extract all markdown links from the given lines. + + Return list of MarkdownLinkInfo, where each dict contains: + - `line_no` - line number (1-based) + - `url` - link URL + - `text` - link text + - `title` - link title (if any) + """ + links: list[MarkdownLinkInfo] = [] + for line_no, line in enumerate(lines, start=1): + for m in MARKDOWN_LINK_RE.finditer(line): + links.append( + MarkdownLinkInfo( + line_no=line_no, + url=m.group("url"), + text=m.group("text"), + title=m.group("title"), + attributes=m.group("attrs"), + full_match=m.group(0), + ) + ) + return links + + +def _construct_markdown_link( + url: str, + text: str, + title: Union[str, None], + attributes: Union[str, None], +) -> str: + """Construct a markdown link.""" + if title: + link = f'[{text}]({url} "{title}")' + else: + link = f"[{text}]({url})" + + if attributes: + link += f"{{{attributes}}}" + + return link + + +def replace_markdown_links( + text: list[str], + links: list[MarkdownLinkInfo], + original_links: list[MarkdownLinkInfo], +) -> list[str]: + """ + Replace markdown links in the given text with the original links. + + Fail if the number of links does not match the original. + """ + if len(links) != len(original_links): + raise ValueError( + "Number of markdown links does not match the number in the " + "original document " + f"({len(links)} vs {len(original_links)})" + ) + + modified_text = text.copy() + for i, link_info in enumerate(links): + link_text = link_info["text"] + link_title = link_info["title"] + original_link_info = original_links[i] + + # Replace with original URL but translated text + replacement_link = _construct_markdown_link( + url=original_link_info["url"], + text=link_text, + title=link_title, + attributes=original_link_info["attributes"], + ) + line_no = link_info["line_no"] - 1 + modified_line = modified_text[line_no] + modified_line = modified_line.replace( + link_info["full_match"], replacement_link, 1 + ) + modified_text[line_no] = modified_line + + return modified_text + + +# HTML links +# -------------------------------------------------------------------------------------- + + +def extract_html_links(lines: list[str]) -> list[HtmlLinkInfo]: + """ + Extract all HTML links from the given lines. + + Return list of HtmlLinkInfo, where each dict contains: + - `line_no` - line number (1-based) + - `full_tag` - full HTML link tag + - `attributes` - list of HTMLLinkAttribute (name, quote, value) + - `text` - link text + """ + links = [] + for line_no, line in enumerate(lines, start=1): + for html_link in HTML_LINK_RE.finditer(line): + link_str = html_link.group(0) + + link_text_match = HTML_LINK_TEXT_RE.match(link_str) + assert link_text_match is not None + link_text = link_text_match.group(2) + assert isinstance(link_text, str) + + link_open_tag_match = HTML_LINK_OPEN_TAG_RE.match(link_str) + assert link_open_tag_match is not None + link_open_tag = link_open_tag_match.group(1) + assert isinstance(link_open_tag, str) + + attributes: list[HTMLLinkAttribute] = [] + for attr_name, attr_quote, attr_value in re.findall( + HTML_ATTR_RE, link_open_tag + ): + assert isinstance(attr_name, str) + assert isinstance(attr_quote, str) + assert isinstance(attr_value, str) + attributes.append( + HTMLLinkAttribute( + name=attr_name, quote=attr_quote, value=attr_value + ) + ) + links.append( + HtmlLinkInfo( + line_no=line_no, + full_tag=link_str, + attributes=attributes, + text=link_text, + ) + ) + return links + + +def _construct_html_link( + link_text: str, + attributes: list[HTMLLinkAttribute], +) -> str: + """Reconstruct HTML link.""" + attrs_str = " ".join( + f"{attribute['name']}={attribute['quote']}{attribute['value']}{attribute['quote']}" + for attribute in attributes + ) + return f"<a {attrs_str}>{link_text}</a>" + + +def replace_html_links( + text: list[str], + links: list[HtmlLinkInfo], + original_links: list[HtmlLinkInfo], +) -> list[str]: + """ + Replace HTML links in the given text with the links from the original document. + + Fail if the number of links does not match the original. + """ + if len(links) != len(original_links): + raise ValueError( + "Number of HTML links does not match the number in the " + "original document " + f"({len(links)} vs {len(original_links)})" + ) + + modified_text = text.copy() + for link_index, link in enumerate(links): + original_link_info = original_links[link_index] + + # Replace with original attributes but translated text + replacement_link = _construct_html_link( + link_text=link["text"], + attributes=original_link_info["attributes"], + ) + line_no = link["line_no"] - 1 + modified_text[line_no] = modified_text[line_no].replace( + link["full_tag"], replacement_link, 1 + ) + + return modified_text + + +# Multiline code blocks +# -------------------------------------------------------------------------------------- + + +def get_code_block_lang(line: str) -> str: + """Extract language from code block fence line.""" + match = CODE_BLOCK_LANG_RE.match(line) + if match: + return match.group(1) + return "" + + +def extract_multiline_code_blocks(text: list[str]) -> list[MultilineCodeBlockInfo]: + """Extract all multiline code blocks from text.""" + blocks: list[MultilineCodeBlockInfo] = [] + + in_code_block3 = False + in_code_block4 = False + current_block_lang = "" + current_block_start_line = -1 + current_block_lines = [] + + for line_no, line in enumerate(text, start=1): + stripped = line.lstrip() + + # Detect opening fence + if not (in_code_block3 or in_code_block4): + if stripped.startswith("```"): + current_block_start_line = line_no + count = len(stripped) - len(stripped.lstrip("`")) + if count == 3: + in_code_block3 = True + current_block_lang = get_code_block_lang(stripped) + current_block_lines = [line] + continue + elif count >= 4: + in_code_block4 = True + current_block_lang = get_code_block_lang(stripped) + current_block_lines = [line] + continue + + # Detect closing fence + elif in_code_block3: + if stripped.startswith("```"): + count = len(stripped) - len(stripped.lstrip("`")) + if count == 3: + current_block_lines.append(line) + blocks.append( + MultilineCodeBlockInfo( + lang=current_block_lang, + start_line_no=current_block_start_line, + content=current_block_lines, + ) + ) + in_code_block3 = False + current_block_lang = "" + current_block_start_line = -1 + current_block_lines = [] + continue + current_block_lines.append(line) + + elif in_code_block4: + if stripped.startswith("````"): + count = len(stripped) - len(stripped.lstrip("`")) + if count >= 4: + current_block_lines.append(line) + blocks.append( + MultilineCodeBlockInfo( + lang=current_block_lang, + start_line_no=current_block_start_line, + content=current_block_lines, + ) + ) + in_code_block4 = False + current_block_lang = "" + current_block_start_line = -1 + current_block_lines = [] + continue + current_block_lines.append(line) + + return blocks + + +def _split_hash_comment(line: str) -> tuple[str, Union[str, None]]: + """Split a line into code and hash-style comment.""" + match = HASH_COMMENT_RE.match(line) + if match: + code = match.group("code").rstrip() + comment = match.group("comment") + return code, comment + return line.rstrip(), None + + +def _split_slashes_comment(line: str) -> tuple[str, Union[str, None]]: + """Split a line into code and slash-style comment.""" + match = SLASHES_COMMENT_RE.match(line) + if match: + code = match.group("code").rstrip() + comment = match.group("comment") + return code, comment + return line, None + + +def _is_block_comment_start(line: str) -> bool: + """Check if line starts a block comment (/*...).""" + return bool(BLOCK_COMMENT_START_RE.match(line)) + + +def _is_block_comment_end(line: str) -> bool: + """Check if line ends a block comment (...*/).""" + return bool(BLOCK_COMMENT_END_RE.search(line)) + + +def _split_block_comment_line(line: str) -> tuple[str, Union[str, None]]: + """ + Split a line inside a block comment into prefix and comment content. + + For lines like: " * This is a comment" + Returns: (" * ", "This is a comment") + """ + match = BLOCK_COMMENT_LINE_RE.match(line) + if match: + return match.group("prefix"), match.group("comment") + return line, None + + +def replace_multiline_code_block( + block_a: MultilineCodeBlockInfo, block_b: MultilineCodeBlockInfo +) -> list[str]: + """ + Replace multiline code block `a` with block `b` leaving comments intact. + + Syntax of comments depends on the language of the code block. + Raises ValueError if the blocks are not compatible. + """ + start_line = block_a["start_line_no"] + end_line_no = start_line + len(block_a["content"]) - 1 + + if block_a["lang"] != block_b["lang"]: + raise ValueError( + f"Code block (lines {start_line}-{end_line_no}) " + "has different language than the original block " + f"('{block_a['lang']}' vs '{block_b['lang']}')" + ) + if len(block_a["content"]) != len(block_b["content"]): + raise ValueError( + f"Code block (lines {start_line}-{end_line_no}) " + "has different number of lines than the original block " + f"({len(block_a['content'])} vs {len(block_b['content'])})" + ) + + block_language = block_a["lang"].lower() + + # Skip mermaid diagrams + if block_language in {"mermaid"}: + if block_a != block_b: + print( + f"Skipping mermaid code block replacement (lines {start_line}-{end_line_no}). " + "This should be checked manually." + ) + return block_a["content"].copy() + + code_block: list[str] = [] + in_block_comment = False + + for line_a, line_b in zip(block_a["content"], block_b["content"]): + line_a_comment: Union[str, None] = None + + # Handle comments based on language + if block_language in { + "python", + "py", + "sh", + "bash", + "dockerfile", + "requirements", + "gitignore", + "toml", + "yaml", + "yml", + "hash-style-comments", + }: + # Hash-style comments only + _line_a_code, line_a_comment = _split_hash_comment(line_a) + _line_b_code, line_b_comment = _split_hash_comment(line_b) + res_line = line_b + if line_b_comment and line_a_comment: + res_line = res_line.replace(line_b_comment, line_a_comment, 1) + code_block.append(res_line) + elif block_language in { + "nextflow", + "groovy", + "nf", + "java", + "kotlin", + "block-and-hash-comments", + }: + # Languages with both hash (#) and block (/* */) comments + # Check for block comment boundaries + starts_block = _is_block_comment_start(line_a) + ends_block = _is_block_comment_end(line_a) + + if starts_block: + in_block_comment = True + # Lines like "/* comment */" or "/*" - keep translated version + code_block.append(line_a) + elif ends_block and in_block_comment: + in_block_comment = False + # Lines like " */" or "comment */" - keep translated version + code_block.append(line_a) + elif in_block_comment: + # Inside block comment - lines like " * comment text" + # Keep the translated comment content from line_a + code_block.append(line_a) + else: + # Outside block comment - handle hash comments + _line_a_code, line_a_comment = _split_hash_comment(line_a) + _line_b_code, line_b_comment = _split_hash_comment(line_b) + res_line = line_b + if line_b_comment and line_a_comment: + res_line = res_line.replace(line_b_comment, line_a_comment, 1) + code_block.append(res_line) + elif block_language in {"console", "json", "slash-style-comments"}: + _line_a_code, line_a_comment = _split_slashes_comment(line_a) + _line_b_code, line_b_comment = _split_slashes_comment(line_b) + res_line = line_b + if line_b_comment and line_a_comment: + res_line = res_line.replace(line_b_comment, line_a_comment, 1) + code_block.append(res_line) + else: + code_block.append(line_b) + + return code_block + + +def replace_multiline_code_blocks_in_text( + text: list[str], + code_blocks: list[MultilineCodeBlockInfo], + original_code_blocks: list[MultilineCodeBlockInfo], +) -> list[str]: + """ + Update each code block in `text` with the corresponding code block from + `original_code_blocks` with comments taken from `code_blocks`. + """ + if len(code_blocks) != len(original_code_blocks): + raise ValueError( + "Number of code blocks does not match the number in the original document " + f"({len(code_blocks)} vs {len(original_code_blocks)})" + ) + + modified_text = text.copy() + for block, original_block in zip(code_blocks, original_code_blocks): + updated_content = replace_multiline_code_block(block, original_block) + + start_line_index = block["start_line_no"] - 1 + for i, updated_line in enumerate(updated_content): + modified_text[start_line_index + i] = updated_line + + return modified_text + + +# All checks +# -------------------------------------------------------------------------------------- + + +def check_translation( + doc_lines: list[str], + en_doc_lines: list[str], + auto_fix: bool, + path: str, +) -> list[str]: + """ + Check and optionally fix a translation against the English source. + + Fixes: + - Header permalinks + - Markdown links + - HTML links + - Code blocks (preserve code, keep translated comments) + """ + # Fix permalinks + en_permalinks = extract_header_permalinks(en_doc_lines) + doc_permalinks = extract_header_permalinks(doc_lines) + fixed_doc_lines = replace_header_permalinks( + doc_lines, doc_permalinks, en_permalinks + ) + if auto_fix and (fixed_doc_lines != doc_lines): + print(f"Fixing header permalinks in: {path}") + doc_lines = fixed_doc_lines + + # Fix markdown links + en_markdown_links = extract_markdown_links(en_doc_lines) + doc_markdown_links = extract_markdown_links(doc_lines) + fixed_doc_lines = replace_markdown_links( + doc_lines, doc_markdown_links, en_markdown_links + ) + if auto_fix and (fixed_doc_lines != doc_lines): + print(f"Fixing markdown links in: {path}") + doc_lines = fixed_doc_lines + + # Fix HTML links + en_html_links = extract_html_links(en_doc_lines) + doc_html_links = extract_html_links(doc_lines) + fixed_doc_lines = replace_html_links(doc_lines, doc_html_links, en_html_links) + if auto_fix and (fixed_doc_lines != doc_lines): + print(f"Fixing HTML links in: {path}") + doc_lines = fixed_doc_lines + + # Fix multiline code blocks + en_code_blocks = extract_multiline_code_blocks(en_doc_lines) + doc_code_blocks = extract_multiline_code_blocks(doc_lines) + fixed_doc_lines = replace_multiline_code_blocks_in_text( + doc_lines, doc_code_blocks, en_code_blocks + ) + if auto_fix and (fixed_doc_lines != doc_lines): + print(f"Fixing multiline code blocks in: {path}") + doc_lines = fixed_doc_lines + + return doc_lines diff --git a/_scripts/docs.py b/_scripts/docs.py new file mode 100644 index 0000000000..410564e722 --- /dev/null +++ b/_scripts/docs.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer>=0.12.0", +# "pyyaml>=6.0", +# "rich>=13.0.0", +# # MkDocs and plugins +# "mkdocs", +# "mkdocs-material", +# "pymdown-extensions>=10.12", +# "mkdocs-enumerate-headings-plugin>=0.6.0", +# "mkdocs-quiz>=1.5.4", +# "mike", +# ] +# /// +""" +Build and language management commands for Nextflow training docs. + +Usage: + uv run docs.py build-lang en + uv run docs.py build-all + uv run docs.py live pt +""" + +import json +import os +import shutil +import subprocess +import sys +from http.server import HTTPServer, SimpleHTTPRequestHandler +from multiprocessing import Pool +from pathlib import Path + +import typer +import yaml +from rich.console import Console + +app = typer.Typer(help="Nextflow Training Documentation Tools") +console = Console() + +# Must be run from repo root +REPO_ROOT = Path(__file__).parent.parent +DOCS_PATH = REPO_ROOT / "docs" +EN_DOCS_PATH = DOCS_PATH / "en" +SITE_PATH = REPO_ROOT / "site" +BUILD_SITE_PATH = REPO_ROOT / "site_build" + + +def get_supported_langs() -> set[str]: + """ + Load supported languages from language_names.yml. + + This is the single source of truth for which languages are supported. + """ + return set(get_language_names().keys()) + + +def get_language_names() -> dict[str, str]: + """ + Load language code to native name mapping from language_names.yml. + + This is the single source of truth for which languages are supported. + """ + lang_file = DOCS_PATH / "language_names.yml" + if not lang_file.exists(): + console.print(f"[red]Error:[/red] Language file not found: {lang_file}") + raise typer.Exit(code=1) + return yaml.safe_load(lang_file.read_text(encoding="utf-8")) + + +def get_lang_paths() -> list[Path]: + """Get all language directories.""" + return sorted(DOCS_PATH.iterdir()) + + +MKDOCS_TEMPLATE = """\ +INHERIT: ../en/mkdocs.yml +theme: + language: {lang} + custom_dir: ../en/overrides +extra: + consent: + title: "Cookie consent" + description: >- + We use cookies to recognize your repeated visits and preferences, as well + as to measure the effectiveness of our documentation and whether users + find what they're searching for. With your consent, you're helping us to + make our training materials better. + Find out more on + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">how we use cookies</a>. + cookies: + posthog: "PostHog Analytics" +""" + + +@app.command() +def new_lang(lang: str): + """Generate a new docs translation directory for a language.""" + lang = lang.lower() + new_path = DOCS_PATH / lang + + if new_path.exists(): + console.print(f"[red]Error:[/red] Language already exists: {lang}") + raise typer.Exit(code=1) + + new_path.mkdir() + (new_path / "mkdocs.yml").write_text( + MKDOCS_TEMPLATE.format(lang=lang), + encoding="utf-8", + ) + (new_path / "llm-prompt.md").write_text( + f"# Translation Rules for {lang}\n\nTODO: Add language-specific translation rules here.\n", + encoding="utf-8", + ) + + # Copy ui-strings.yml from English as a starting point + en_ui_strings = EN_DOCS_PATH / "ui-strings.yml" + if en_ui_strings.exists(): + ui_strings_content = en_ui_strings.read_text(encoding="utf-8") + # Add TODO comment at the top + ui_strings_content = ( + f"# TODO: Translate these UI strings to {lang}\n" + ui_strings_content + ) + (new_path / "ui-strings.yml").write_text(ui_strings_content, encoding="utf-8") + + (new_path / "docs").mkdir() + + console.print(f"[green]Created:[/green] {new_path}") + console.print("\nNext steps:") + console.print(f" 1. Edit {new_path}/llm-prompt.md to add translation rules") + console.print(f" 2. Translate {new_path}/ui-strings.yml") + console.print(f" 3. Translate extra.consent in {new_path}/mkdocs.yml") + console.print(f" 4. Add '{lang}: <native name>' to docs/language_names.yml") + console.print( + " 5. Run 'uv run docs.py sync-language-picker' to update language picker" + ) + + +@app.command() +def build_lang(lang: str): + """Build the docs for a language.""" + lang = lang.lower() + lang_path = DOCS_PATH / lang + + if not lang_path.is_dir(): + console.print(f"[red]Error:[/red] Language directory not found: {lang_path}") + raise typer.Exit(code=1) + + console.print(f"Building docs for: [cyan]{lang}[/cyan]") + build_site_dist_path = BUILD_SITE_PATH / lang + + if lang == "en": + dist_path = SITE_PATH + else: + dist_path = SITE_PATH / lang + shutil.rmtree(dist_path, ignore_errors=True) + + shutil.rmtree(build_site_dist_path, ignore_errors=True) + result = subprocess.run( + ["mkdocs", "build", "--site-dir", str(build_site_dist_path)], + cwd=lang_path, + capture_output=True, + text=True, + ) + if result.returncode != 0: + console.print(f"[red]Error building {lang}:[/red]") + console.print(result.stdout) + console.print(result.stderr) + raise subprocess.CalledProcessError(result.returncode, result.args) + shutil.copytree(build_site_dist_path, dist_path, dirs_exist_ok=True) + + console.print(f"[green]Built:[/green] {lang}") + + +@app.command() +def build_all(): + """Build docs for all supported languages.""" + shutil.rmtree(SITE_PATH, ignore_errors=True) + supported = get_supported_langs() + langs = [p.name for p in get_lang_paths() if p.is_dir() and p.name in supported] + + console.print(f"Building {len(langs)} languages: {', '.join(langs)}") + + cpu_count = os.cpu_count() or 1 + pool_size = min(cpu_count * 2, len(langs)) + + with Pool(pool_size) as p: + p.map(build_lang, langs) + + console.print("[green]All builds complete[/green]") + + +@app.command() +def serve(): + """Serve the built site (run build-all first).""" + if not SITE_PATH.exists(): + console.print("[red]Error:[/red] Site not built. Run 'build-all' first.") + raise typer.Exit(code=1) + + os.chdir(SITE_PATH) + server = HTTPServer(("", 8008), SimpleHTTPRequestHandler) + console.print("Serving at: [link]http://127.0.0.1:8008[/link]") + server.serve_forever() + + +@app.command() +def live(lang: str = "en", dirty: bool = False): + """Serve docs with live reload for a specific language.""" + lang = lang.lower() + lang_path = DOCS_PATH / lang + + if not lang_path.is_dir(): + console.print(f"[red]Error:[/red] Language not found: {lang}") + raise typer.Exit(code=1) + + args = ["mkdocs", "serve", "--dev-addr", "127.0.0.1:8008"] + if dirty: + args.append("--dirty") + + console.print(f"Serving [cyan]{lang}[/cyan] at [link]http://127.0.0.1:8008[/link]") + subprocess.run(args, cwd=lang_path, check=True) + + +@app.command() +def langs_json(): + """Output supported languages as JSON (for CI).""" + supported = get_supported_langs() + langs = [p.name for p in get_lang_paths() if p.is_dir() and p.name in supported] + print(json.dumps(sorted(langs))) + + +@app.command() +def check_config(lang: str): + """Verify a language's mkdocs.yml inherits correctly.""" + lang = lang.lower() + config_path = DOCS_PATH / lang / "mkdocs.yml" + + if not config_path.exists(): + console.print(f"[red]Error:[/red] Config not found: {config_path}") + raise typer.Exit(code=1) + + config = yaml.safe_load(config_path.read_text(encoding="utf-8")) + + if config.get("INHERIT") != "../en/mkdocs.yml": + console.print( + f"[red]Error:[/red] {config_path} must have 'INHERIT: ../en/mkdocs.yml'" + ) + raise typer.Exit(code=1) + + console.print(f"[green]OK:[/green] {config_path}") + + +@app.command() +def sync_language_picker(): + """Update the language picker in docs/en/mkdocs.yml from language_names.yml.""" + import re + + mkdocs_path = EN_DOCS_PATH / "mkdocs.yml" + if not mkdocs_path.exists(): + console.print(f"[red]Error:[/red] mkdocs.yml not found: {mkdocs_path}") + raise typer.Exit(code=1) + + lang_names = get_language_names() + content = mkdocs_path.read_text(encoding="utf-8") + + # Build the new alternate section + # English first (primary language), then others alphabetically + alternate_lines = [" alternate:"] + lang_codes = ["en"] + sorted(k for k in lang_names.keys() if k != "en") + for lang_code in lang_codes: + name = lang_names[lang_code] + # English goes to root, others to /{lang}/ + link = "/" if lang_code == "en" else f"/{lang_code}/" + alternate_lines.append(f" - name: {name}") + alternate_lines.append(f" link: {link}") + alternate_lines.append(f" lang: {lang_code}") + new_alternate = "\n".join(alternate_lines) + + # Pattern to match the existing alternate section + # Matches from " alternate:" to the next unindented or less-indented line + pattern = r"( alternate:\n(?: .*\n)+)" + + if not re.search(pattern, content): + console.print( + "[red]Error:[/red] Could not find alternate section in mkdocs.yml" + ) + raise typer.Exit(code=1) + + new_content = re.sub(pattern, new_alternate + "\n", content) + + if new_content == content: + console.print("[green]Language picker already up to date[/green]") + return + + mkdocs_path.write_text(new_content, encoding="utf-8") + console.print(f"[green]Updated:[/green] {mkdocs_path}") + console.print(f"Languages: {', '.join(sorted(lang_names.keys()))}") + + +if __name__ == "__main__": + # Ensure we're running from repo root + if not DOCS_PATH.exists(): + console.print("[red]Error:[/red] Must run from repository root") + sys.exit(1) + app() diff --git a/_scripts/general-llm-prompt.md b/_scripts/general-llm-prompt.md new file mode 100644 index 0000000000..ea035335da --- /dev/null +++ b/_scripts/general-llm-prompt.md @@ -0,0 +1,768 @@ +# Translation Instructions + +You are translating Nextflow training documentation from English to another language. +The content is wrapped in `%%%` markers - do not include these markers in your output. + +Your goal is to produce a translation that: + +- Reads naturally in the target language +- Preserves all technical accuracy +- Maintains identical formatting and structure +- Keeps all code executable (no translation of code syntax) +- Matches the tone specified in the language-specific prompt + +--- + +## Prompt Precedence + +When this general prompt and the language-specific prompt give conflicting guidance, **the language-specific prompt takes precedence**. Language prompts can override any rule in this general prompt to accommodate language-specific needs. + +For example, this prompt says "workflow" can be translated in prose, but the French prompt specifies keeping it in English (common in French tech writing). Follow the French prompt in that case. + +--- + +## Tone and Style + +Each language has specific tone guidance in its `llm-prompt.md` file (formal vs informal, regional variants, etc.). Follow that guidance. + +General principles: + +- **Educational but approachable**: This is training material, not formal documentation +- **Preserve personality**: If the English has humor or encouragement (e.g., "Congratulations!", "Take a short break"), translate these naturally rather than removing them +- **Natural expressions**: Use expressions natural to the target language rather than word-for-word translations +- **Consistency**: Use the same term for the same concept throughout + +--- + +## General Rules + +### What to Translate + +- Prose text and explanations +- Comments inside code blocks +- Admonition titles (the text in quotes) +- Tab titles +- Link text (but NOT URLs or anchors) +- Frontmatter `title` and `description` values +- Alt text for images + +### What to Keep in English + +- All code (except comments) +- URLs, file paths, and anchors +- Nextflow keywords and syntax +- Tool names (Nextflow, Docker, GitHub, etc.) +- File format names (FASTQ, BAM, CSV, etc.) +- Technical identifiers and variable names +- Course/module names: "Hello Nextflow", "Hello Channels", "Hello nf-core" - keep as proper nouns + +### Technical Terms Reference (Keep in English) + +The following technical terms must remain in English across all languages. This is the authoritative list - language-specific prompts should not duplicate it. + +#### Nextflow Core Keywords + +These appear as syntax and must never be translated in code: + +`process`, `workflow`, `channel`, `emit`, `take`, `main`, `input`, `output`, `script`, `shell`, `exec`, `params`, `val`, `path`, `tuple`, `env`, `stdin`, `stdout`, `file` + +#### Operators + +All operator names remain in English: + +`map`, `filter`, `collect`, `flatten`, `groupTuple`, `join`, `combine`, `mix`, `merge`, `view`, `first`, `last`, `take`, `branch`, `multiMap`, `splitCsv`, `splitFastq`, `splitFasta`, `splitText`, `toList`, `toSortedList`, `unique`, `distinct`, `count`, `min`, `max`, `sum`, `buffer`, `collate`, `cross`, `tap`, `set`, `ifEmpty`, `randomSample` + +#### Directives + +All directive names remain in English: + +`publishDir`, `container`, `conda`, `memory`, `cpus`, `time`, `errorStrategy`, `maxRetries`, `maxErrors`, `queue`, `scratch`, `storeDir`, `tag`, `label`, `cache`, `executor`, `disk`, `accelerator`, `arch`, `beforeScript`, `afterScript`, `clusterOptions`, `machineType`, `module`, `penv`, `pod`, `resourceLabels`, `stageInMode`, `stageOutMode` + +#### Channel Types + +- queue channel +- value channel + +#### Execution Concepts + +- resume +- cache / caching +- work directory +- staging / unstaging +- executor / executors +- job + +#### Tools & Platforms + +Nextflow, nf-core, Docker, Singularity, Apptainer, Conda, Mamba, GitHub, GitLab, Bitbucket, Gitpod, GitHub Codespaces, Seqera Platform, Wave, Fusion, Groovy, AWS, GCP, Azure, HPC, SLURM, PBS, LSF, SGE + +#### File Formats & Extensions + +FASTQ, FASTA, BAM, SAM, VCF, BED, GFF, GTF, CSV, TSV, JSON, YAML, `.nf`, `nextflow.config`, `main.nf`, `modules.nf`, `workflows.nf` + +#### Programming Concepts + +closure, shebang, glob / globbing, regex, string, boolean, integer, list, map (data structure), set, tuple, DSL2 + +--- + +## Code Blocks + +Code blocks are critical - the code must remain executable. + +### Rules + +1. **Never translate code syntax** - only translate comments +2. **Always translate code comments** - comments are not executable and should be in the target language +3. **Preserve exact indentation and spacing** +4. **Keep all Nextflow keywords in English**: `process`, `workflow`, `channel`, `emit`, `take`, `main`, `input`, `output`, `script`, `shell`, `exec`, `params`, `val`, `path`, `tuple`, `env` +5. **Keep all operators in English**: `map`, `filter`, `collect`, `view`, `flatten`, `groupTuple`, `join`, `combine`, `mix`, `splitCsv`, `splitFastq`, etc. +6. **Keep all directives in English**: `publishDir`, `container`, `conda`, `memory`, `cpus`, `time`, `errorStrategy`, `tag`, `label`, `cache`, `executor`, etc. + +### Examples + +**Groovy/Nextflow code:** + +English: + +```groovy +// Define the input channel +params.reads = "data/*_{1,2}.fastq.gz" + +// Create a channel from the input files +Channel + .fromFilePairs(params.reads) // Creates tuple of (sample_id, [file1, file2]) + .set { reads_ch } +``` + +Portuguese translation: + +```groovy +// Define o canal de entrada +params.reads = "data/*_{1,2}.fastq.gz" + +// Cria um canal a partir dos arquivos de entrada +Channel + .fromFilePairs(params.reads) // Cria tupla de (sample_id, [file1, file2]) + .set { reads_ch } +``` + +**Bash/console code:** + +English: + +```bash +# Run the workflow +nextflow run main.nf --reads "data/*.fastq.gz" + +# Check the output +ls -la results/ +``` + +Spanish translation: + +```bash +# Ejecutar el flujo de trabajo +nextflow run main.nf --reads "data/*.fastq.gz" + +# Verificar la salida +ls -la results/ +``` + +**Config files:** + +English: + +```groovy +// Configuration for local execution +process { + executor = 'local' + cpus = 2 // Number of CPUs per task + memory = '4 GB' // Memory allocation +} +``` + +French translation: + +```groovy +// Configuration pour l'exécution locale +process { + executor = 'local' + cpus = 2 // Nombre de CPUs par tâche + memory = '4 GB' // Allocation de mémoire +} +``` + +### Console Output + +Never translate console output - it shows exactly what the user will see: + +```console +N E X T F L O W ~ version 24.04.0 +Launching `main.nf` [happy_darwin] - revision: a1b2c3d4 +executor > local (3) +[a1/b2c3d4] process > FASTQC (sample1) [100%] 3 of 3 ✔ +``` + +Keep this exactly as shown - do not translate any part of it. + +--- + +## Admonitions + +Admonitions use special syntax. Translate the title (in quotes) but keep the keyword. + +### Standard Admonitions + +English: + +```markdown +!!! note "Important Note" + + This is important information that users should know. + +!!! tip "Pro Tip" + + This is a helpful suggestion. + +!!! warning "Caution" + + This warns about potential issues. +``` + +Portuguese: + +```markdown +!!! note "Nota Importante" + + Esta é uma informação importante que os usuários devem saber. + +!!! tip "Dica" + + Esta é uma sugestão útil. + +!!! warning "Cuidado" + + Isto alerta sobre possíveis problemas. +``` + +### Collapsible Admonitions + +The `???` syntax creates collapsible blocks. `???+` means expanded by default. + +English: + +```markdown +??? tip "Click to expand" + + Hidden content here. + +???+ note "Expanded by default" + + This content is visible initially. +``` + +Keep the `???` or `???+` syntax exactly as-is. + +### Exercise and Solution Blocks + +These are custom admonitions used throughout the training: + +English: + +````markdown +!!! exercise "Exercise" + + Try running the workflow with different parameters. + +??? solution "Solution" + + Here's how to do it: + ```bash + nextflow run main.nf --input "*.fastq" + ``` +```` + +Translate "Exercise" and "Solution" per the language glossary. + +--- + +## Headings + +### Numbered Headings + +Preserve the numbering format exactly: + +English: + +```markdown +## 1. Getting Started + +### 1.1. Prerequisites + +### 1.2. Installation +``` + +Spanish: + +```markdown +## 1. Primeros Pasos + +### 1.1. Requisitos Previos + +### 1.2. Instalación +``` + +### Heading Anchors + +**Critical**: Preserve anchor IDs exactly. These are used for linking. + +English: + +```markdown +## 1. Getting Started { #getting-started } + +### 1.1. Prerequisites { #prerequisites } +``` + +Portuguese: + +```markdown +## 1. Primeiros Passos { #getting-started } + +### 1.1. Pré-requisitos { #prerequisites } +``` + +The anchor `{ #getting-started }` must NOT be translated. + +--- + +## Links + +### Internal Links + +Translate the link text, keep the URL and anchor unchanged: + +English: + +```markdown +See the [installation guide](../setup/install.md#docker) for details. +``` + +French: + +```markdown +Consultez le [guide d'installation](../setup/install.md#docker) pour plus de détails. +``` + +### External Links + +Same rule - translate text, keep URL: + +English: + +```markdown +Visit the [Nextflow documentation](https://nextflow.io/docs/latest/) for more information. +``` + +German: + +```markdown +Besuchen Sie die [Nextflow-Dokumentation](https://nextflow.io/docs/latest/) für weitere Informationen. +``` + +### Reference-Style Links + +Keep reference definitions unchanged: + +English: + +```markdown +Read more about [channels][channels-docs]. + +[channels-docs]: https://nextflow.io/docs/latest/channel.html +``` + +Italian: + +```markdown +Leggi di più sui [canali][channels-docs]. + +[channels-docs]: https://nextflow.io/docs/latest/channel.html +``` + +--- + +## Tabs + +Tab blocks use `===` syntax. Translate the tab title: + +English: + +```markdown +=== "Gitpod" + + Click the button below to launch in Gitpod. + +=== "Local" + + Run the following command locally. +``` + +Korean: + +```markdown +=== "Gitpod" + + 아래 버튼을 클릭하여 Gitpod에서 실행하세요. + +=== "로컬" + + 다음 명령을 로컬에서 실행하세요. +``` + +Note: Keep tool names like "Gitpod" in English. + +### Common Tab Labels + +These tabs appear frequently in Before/After code comparisons: + +| English | Translate | Examples | +| ------- | --------- | -------------------------------------------------------------- | +| After | Yes | Depois (pt), Después (es), Dopo (it), Nach (de), 후 (ko) | +| Before | Yes | Antes (pt/es), Prima (it), Vor (de), 전 (ko) | +| Gitpod | No | Keep in English | +| Local | Sometimes | Local (pt/es), Locale (it), Lokal (de) - check language prompt | + +--- + +## Standard Section Headers + +These recurring section headers appear throughout the training and should be translated consistently: + +| English | Notes | +| ------------------ | ------------------------------------------- | +| Takeaway | Summary section at end of lessons | +| What's next? | Transition to next section | +| Warmup | Initial exercise at start of lessons | +| Directory contents | Shows file listing | +| Output | In code block titles, often kept in English | + +Check the language-specific `llm-prompt.md` for the correct translations. If not specified, translate naturally. + +--- + +## Page Titles + +Page titles (the `# Heading` at the top of each page) follow these rules: + +1. **Translate the descriptive text** (e.g., "Part 1", "Getting Started") +2. **Keep course/module names in English** (e.g., "Hello World", "Hello Channels") + +Example: + +- English: `# Part 1: Hello World` +- Spanish: `# Parte 1: Hello World` +- Korean: `# 파트 1: Hello World` +- German: `# Teil 1: Hello World` + +--- + +## Frontmatter + +YAML frontmatter appears at the top of files. Translate only `title` and `description`: + +English: + +```yaml +--- +title: Getting Started with Nextflow +description: Learn the basics of writing Nextflow pipelines +hide: + - toc +--- +``` + +Spanish: + +```yaml +--- +title: Primeros Pasos con Nextflow +description: Aprenda los fundamentos de escribir pipelines en Nextflow +hide: + - toc +--- +``` + +Keep all other keys and values unchanged (`hide`, `toc`, etc.). + +--- + +## Special Elements + +### Keyboard Keys + +Keep `kbd` tags and their content: + +```markdown +Press ++ctrl+c++ to cancel. +Press ++cmd+shift+p++ to open the command palette. +``` + +Do not translate key names. + +### Icons + +Keep icon syntax unchanged: + +```markdown +:material-check: Completed +:warning: Be careful +``` + +Translate the text after the icon, not the icon itself. + +### Variables and Placeholders + +Keep placeholders in angle brackets: + +English: + +```markdown +Replace `<username>` with your GitHub username. +``` + +French: + +```markdown +Remplacez `<username>` par votre nom d'utilisateur GitHub. +``` + +### Snippets + +The `--8<--` syntax includes external files. Never modify these: + +```markdown +--8<-- "docs/hello_nextflow/img/diagram.svg" +``` + +--- + +## Formatting Preservation + +### Line Breaks + +Maintain the same line break pattern as the source: + +- If the source has one sentence per line, keep one sentence per line +- If the source has multiple sentences on one line, keep them together +- Preserve blank lines between paragraphs + +### Lists + +Preserve list formatting exactly: + +English: + +```markdown +- First item +- Second item + - Nested item + - Another nested item +- Third item + +1. Numbered item +2. Another numbered item +``` + +### Tables + +Keep table structure, translate cell content: + +English: + +```markdown +| Parameter | Description | Default | +| ---------- | ---------------- | ---------- | +| `--reads` | Input files | None | +| `--outdir` | Output directory | `results/` | +``` + +Portuguese: + +```markdown +| Parâmetro | Descrição | Padrão | +| ---------- | ------------------- | ---------- | +| `--reads` | Arquivos de entrada | Nenhum | +| `--outdir` | Diretório de saída | `results/` | +``` + +Note: Keep parameter names (like `--reads`) in English as they are code. + +--- + +## Common Mistakes to Avoid + +1. **Translating code syntax** + + - Wrong: `Canal.fromPath(...)` + - Right: `Channel.fromPath(...)` + +2. **Translating URLs or anchors** + + - Wrong: `[texto](../configuracao/instalar.md#docker)` + - Right: `[texto](../setup/install.md#docker)` + +3. **Translating console output** + + - Keep exactly as shown in English + +4. **Translating placeholder syntax** + + - Wrong: `<nome-de-usuario>` + - Right: `<username>` + +5. **Breaking admonition syntax** + + - Wrong: `!!! nota "Título"` + - Right: `!!! note "Título"` + +6. **Modifying heading anchors** + + - Wrong: `## Título { #titulo }` + - Right: `## Título { #original-anchor }` + +7. **Inconsistent terminology** + - Always use the same translation for a term throughout + - Follow the glossary in `llm-prompt.md` + +--- + +## Quality Checklist + +Before submitting your translation, verify: + +- [ ] All code blocks have unchanged syntax (only comments translated) +- [ ] All links work (URLs and anchors unchanged) +- [ ] All heading anchors preserved +- [ ] Admonition keywords unchanged (`note`, `tip`, `warning`, etc.) +- [ ] Consistent terminology throughout +- [ ] Natural, readable language +- [ ] Proper grammar and spelling for the target language +- [ ] Same formatting as original (line breaks, indentation, lists) + +--- + +## AI Translation Notice + +All translated pages include a notice informing readers that the content was translated with AI assistance. This notice should be included in new translations. + +### For the Homepage (index.md) + +Add a note admonition immediately **before** the "Catalog of Nextflow training courses" heading (the `## Catalog...` H2 heading). This places it after the introductory grid cards but before the course listings. + +```markdown +</div> + +!!! note "AI-Assisted Translation Title" + + Brief explanation that this translation was created using AI with human oversight. + Welcome feedback and improvements. + Link to [translation guide](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md). + +## Catalog of Nextflow training courses +``` + +The admonition title and content should be translated naturally into the target language. + +### For All Other Pages + +Add an inline notice immediately after the first heading: + +```markdown +# Page Title + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Short notice about AI translation - [link text](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> +``` + +The notice text should be brief (one line) and translated into the target language. Examples: + +| Language | Notice Text | +| ---------- | ---------------------------------------------------------------------------------- | +| German | `KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](...)` | +| Spanish | `Traducción asistida por IA - [más información y sugerencias](...)` | +| French | `Traduction assistée par IA - [en savoir plus et suggérer des améliorations](...)` | +| Portuguese | `Tradução assistida por IA - [saiba mais e sugira melhorias](...)` | + +Keep the CSS class `ai-translation-notice`, the icon `:material-information-outline:{ .ai-translation-notice-icon }`, and the URL unchanged. + +--- + +## UI Strings File + +Each language directory contains a `ui-strings.yml` file with translations for UI elements that appear on course landing pages. When translating a new language or updating translations, this file must also be translated. + +### Location + +``` +docs/<lang>/ui-strings.yml +``` + +### Contents + +The file contains: + +1. **Index page headings**: Labels for course landing page sections +2. **Default content**: Standard text used when courses don't provide custom content + +### Example + +English (`docs/en/ui-strings.yml`): + +```yaml +index_page: + course_summary: "Course summary" + additional_information: "Additional information" + technical_requirements: "Technical requirements" + learning_objectives: "Learning objectives" + audience_prerequisites: "Audience & prerequisites" + course_videos: "Course videos" + +defaults: + technical_requirements: >- + You will need a GitHub account OR a local installation of Nextflow. + See [Environment options](../envsetup/index.md) for more details. + videos: >- + Videos are available for each chapter, featuring an instructor working + through the exercises. The video for each part of the course is embedded + at the top of the corresponding page. +``` + +### Translation Rules + +- Translate all string values naturally into the target language +- Keep the YAML structure and keys unchanged +- The markdown link in `defaults.technical_requirements` should have translated link text but keep the URL unchanged +- Follow the same tone guidance as for content translation (formal/informal per language) + +--- + +## Output Validation + +After completing a translation, verify the following before submitting: + +### Critical Checks (Breaking if Wrong) + +1. **Code blocks executable**: All Nextflow/Groovy/Bash code must run unchanged +2. **Links functional**: All URLs and anchors preserved exactly +3. **Heading anchors intact**: `{ #anchor-name }` syntax unchanged +4. **Admonition keywords valid**: Only `note`, `tip`, `warning`, `danger`, `example`, `quote`, `exercise`, `solution` etc. +5. **Markdown syntax valid**: No broken tables, lists, or code fences + +### Quality Checks + +1. **No translated Nextflow syntax**: `Channel`, `process`, `workflow` etc. remain English in code +2. **Console output unchanged**: Nextflow execution output kept exactly as-is +3. **Consistent terminology**: Same translation for same term throughout +4. **Natural language**: Reads fluently, not word-for-word translation +5. **Formatting preserved**: Same line breaks, indentation, spacing as source diff --git a/_scripts/mkdocs_hooks.py b/_scripts/mkdocs_hooks.py new file mode 100644 index 0000000000..3f3463ef3f --- /dev/null +++ b/_scripts/mkdocs_hooks.py @@ -0,0 +1,179 @@ +""" +MkDocs hooks for English fallback and translation warning injection. + +Adapted from FastAPI's mkdocs_hooks.py for Nextflow training. +""" + +from functools import lru_cache +from pathlib import Path +from typing import Any, Union + +import material +from mkdocs.config.defaults import MkDocsConfig +from mkdocs.structure.files import File, Files +from mkdocs.structure.nav import Link, Navigation, Section +from mkdocs.structure.pages import Page + + +@lru_cache +def get_missing_translation_content(docs_dir: str) -> str: + """Load the missing translation warning content.""" + docs_dir_path = Path(docs_dir) + missing_translation_path = docs_dir_path.parent.parent / "missing-translation.md" + return missing_translation_path.read_text(encoding="utf-8") + + +@lru_cache +def get_mkdocs_material_langs() -> list[str]: + """Get list of supported MkDocs Material language codes.""" + material_path = Path(material.__file__).parent + material_langs_path = material_path / "templates" / "partials" / "languages" + langs = [file.stem for file in material_langs_path.glob("*.html")] + return langs + + +class EnFile(File): + """Marker class for files that are English fallbacks.""" + + pass + + +def on_config(config: MkDocsConfig, **kwargs: Any) -> MkDocsConfig: + """ + Hook to auto-detect language from directory structure and set theme.language. + + Also adjusts site_url for non-English languages. + """ + available_langs = get_mkdocs_material_langs() + dir_path = Path(config.docs_dir) + lang = dir_path.parent.name + + if lang in available_langs: + config.theme["language"] = lang + + if not (config.site_url or "").endswith(f"{lang}/") and lang != "en": + config.site_url = f"{config.site_url}{lang}/" + + return config + + +def resolve_file(*, item: str, files: Files, config: MkDocsConfig) -> None: + """ + Check if a file exists in the current language's docs. + If not, add the English version as a fallback. + """ + item_path = Path(config.docs_dir) / item + if not item_path.is_file(): + en_src_dir = (Path(config.docs_dir) / "../../en/docs").resolve() + potential_path = en_src_dir / item + if potential_path.is_file(): + files.append( + EnFile( + path=item, + src_dir=str(en_src_dir), + dest_dir=config.site_dir, + use_directory_urls=config.use_directory_urls, + ) + ) + + +def resolve_files(*, items: list[Any], files: Files, config: MkDocsConfig) -> None: + """Recursively resolve files from nav items.""" + for item in items: + if isinstance(item, str): + resolve_file(item=item, files=files, config=config) + elif isinstance(item, dict): + for value in item.values(): + if isinstance(value, str): + resolve_file(item=value, files=files, config=config) + elif isinstance(value, list): + resolve_files(items=value, files=files, config=config) + + +def on_files(files: Files, *, config: MkDocsConfig) -> Files: + """ + Hook to add missing files from English as fallback. + + This ensures all nav items are available even if not translated. + """ + resolve_files(items=config.nav or [], files=files, config=config) + + # Also resolve theme assets + if "logo" in config.theme: + resolve_file(item=config.theme["logo"], files=files, config=config) + if "favicon" in config.theme: + resolve_file(item=config.theme["favicon"], files=files, config=config) + + # Resolve extra CSS and JS + resolve_files(items=config.extra_css, files=files, config=config) + resolve_files(items=config.extra_javascript, files=files, config=config) + + return files + + +def generate_renamed_section_items( + items: list[Union[Page, Section, Link]], *, config: MkDocsConfig +) -> list[Union[Page, Section, Link]]: + """ + Recursively process nav items to use page titles for section names. + """ + new_items: list[Union[Page, Section, Link]] = [] + for item in items: + if isinstance(item, Section): + new_title = item.title + new_children = generate_renamed_section_items(item.children, config=config) + first_child = new_children[0] if new_children else None + if isinstance(first_child, Page): + if first_child.file.src_path.endswith("index.md"): + # Read the source so that the title is parsed and available + first_child.read_source(config=config) + new_title = first_child.title or new_title + # Modify existing section to preserve collapsed state + item.title = new_title.split("{ #")[0].strip() + item.children = new_children + new_items.append(item) + else: + new_items.append(item) + return new_items + + +def on_nav( + nav: Navigation, *, config: MkDocsConfig, files: Files, **kwargs: Any +) -> Navigation: + """Hook to rename sections based on their index page titles.""" + new_items = generate_renamed_section_items(nav.items, config=config) + return Navigation(items=new_items, pages=nav.pages) + + +def on_pre_page(page: Page, *, config: MkDocsConfig, files: Files) -> Page: + """Hook called before page processing.""" + return page + + +def on_page_markdown( + markdown: str, *, page: Page, config: MkDocsConfig, files: Files +) -> str: + """ + Hook to prepend missing-translation warning to fallback pages. + + If a page is an English fallback (EnFile), add the warning banner + after the first heading. + """ + # Set clean title for social cards (without permalink) + title = page.title or "" + clean_title = title.split("{ #")[0].strip() + if clean_title: + page.meta.setdefault("social", {}) + page.meta["social"].setdefault("cards_layout_options", {}) + page.meta["social"]["cards_layout_options"]["title"] = clean_title + + # Add missing translation warning for English fallback pages + if isinstance(page.file, EnFile): + missing_translation_content = get_missing_translation_content(config.docs_dir) + header = "" + body = markdown + if markdown.startswith("#"): + header, _, body = markdown.partition("\n\n") + return f"{header}\n\n{missing_translation_content}\n\n{body}" + + return markdown diff --git a/_scripts/translate.py b/_scripts/translate.py new file mode 100644 index 0000000000..6e20d57a78 --- /dev/null +++ b/_scripts/translate.py @@ -0,0 +1,473 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "anthropic>=0.40.0", +# "gitpython>=3.1.0", +# "typer>=0.12.0", +# "pyyaml>=6.0", +# "rich>=13.0.0", +# "pygithub>=2.0.0", +# ] +# /// +""" +LLM-powered translation using Anthropic Claude. + +Usage: + uv run translate.py list-missing pt + uv run translate.py translate-page --language pt --en-path docs/en/docs/index.md + uv run translate.py update-outdated --language pt +""" + +import json +import secrets +import subprocess +import sys +from functools import lru_cache +from pathlib import Path + +import anthropic +import git +import typer +import yaml +from github import Github +from rich.console import Console +from rich.progress import Progress, SpinnerColumn, TextColumn + +app = typer.Typer(help="Translation tools for Nextflow training docs") +console = Console() + +# Must be run from repo root +REPO_ROOT = Path(__file__).parent.parent +DOCS_PATH = REPO_ROOT / "docs" +EN_DOCS_PATH = DOCS_PATH / "en" / "docs" +SCRIPTS_PATH = REPO_ROOT / "_scripts" + +# Model to use for translations +# Using alias to automatically get the latest Sonnet version +# Sonnet is ~40% cheaper than Opus and recommended for translation tasks +MODEL = "claude-sonnet-4-5" + +# Priority directories for translation (most important first) +PRIORITY_DIRS = ["hello_nextflow", "hello_nf-core", "nf4_science", "envsetup"] + + +@lru_cache +def get_general_prompt() -> str: + """Load the general translation prompt.""" + prompt_path = SCRIPTS_PATH / "general-llm-prompt.md" + return prompt_path.read_text(encoding="utf-8") + + +@lru_cache +def get_langs() -> dict[str, str]: + """Load language names from YAML file.""" + return yaml.safe_load( + (DOCS_PATH / "language_names.yml").read_text(encoding="utf-8") + ) + + +def get_lang_prompt(lang: str) -> str: + """Load language-specific prompt.""" + prompt_path = DOCS_PATH / lang / "llm-prompt.md" + if not prompt_path.exists(): + console.print(f"[red]Error:[/red] Prompt file not found: {prompt_path}") + raise typer.Exit(code=1) + return prompt_path.read_text(encoding="utf-8") + + +def to_lang_path(en_path: Path, lang: str) -> Path: + """Convert an English docs path to a language-specific path.""" + rel_path = en_path.relative_to(EN_DOCS_PATH) + return DOCS_PATH / lang / "docs" / rel_path + + +def to_en_path(lang_path: Path, lang: str) -> Path: + """Convert a language-specific path to an English docs path.""" + rel_path = lang_path.relative_to(DOCS_PATH / lang / "docs") + return EN_DOCS_PATH / rel_path + + +def iter_en_docs() -> list[Path]: + """ + Iterate English markdown files in priority order. + + Returns files in this order: + 1. Root-level .md files + 2. Priority directories (hello_nextflow, etc.) + 3. Remaining directories + """ + paths: list[Path] = [] + + # Root level files first + paths.extend(sorted(EN_DOCS_PATH.glob("*.md"))) + + # Priority directories + for dir_name in PRIORITY_DIRS: + dir_path = EN_DOCS_PATH / dir_name + if dir_path.exists(): + paths.extend(sorted(dir_path.rglob("*.md"))) + + # Remaining directories (skip already processed) + priority_prefixes = tuple(str(EN_DOCS_PATH / d) for d in PRIORITY_DIRS) + for path in sorted(EN_DOCS_PATH.rglob("*.md")): + if path.parent == EN_DOCS_PATH: + continue # Already added root files + if str(path).startswith(priority_prefixes): + continue # Already added priority dirs + paths.append(path) + + return paths + + +def check_api_key() -> None: + """Check that ANTHROPIC_API_KEY is set and provide helpful error if not.""" + import os + + if not os.environ.get("ANTHROPIC_API_KEY"): + console.print( + "[red]Error:[/red] ANTHROPIC_API_KEY environment variable not set" + ) + console.print() + console.print("[dim]To fix this, set the environment variable:[/dim]") + console.print(" export ANTHROPIC_API_KEY='your-api-key-here'") + console.print() + console.print("[dim]Get your API key from:[/dim]") + console.print(" https://console.anthropic.com/settings/keys") + raise typer.Exit(code=1) + + +def resolve_en_path(en_path: Path) -> Path: + """ + Resolve an English docs path to an absolute path. + + Accepts paths in several formats: + - Absolute path: /full/path/to/docs/en/docs/file.md + - Relative to repo root: docs/en/docs/file.md + - Relative to EN_DOCS_PATH: hello_nextflow/index.md + """ + # If already absolute and exists, use it + if en_path.is_absolute() and en_path.exists(): + return en_path + + # Try as relative to current directory + if en_path.exists(): + return en_path.resolve() + + # Try as relative to repo root + repo_relative = REPO_ROOT / en_path + if repo_relative.exists(): + return repo_relative + + # Try as relative to EN_DOCS_PATH (e.g., "hello_nextflow/index.md") + en_docs_relative = EN_DOCS_PATH / en_path + if en_docs_relative.exists(): + return en_docs_relative + + # Return original for error message + return en_path + + +@app.command() +def translate_page( + language: str = typer.Option(..., "--language", "-l", envvar="LANGUAGE"), + en_path: Path = typer.Option(..., "--en-path", "-p", envvar="EN_PATH"), +): + """Translate a single page from English to another language.""" + check_api_key() + + if language == "en": + console.print("[red]Error:[/red] Cannot translate to English (source language)") + raise typer.Exit(code=1) + + # Resolve the path + en_path = resolve_en_path(en_path) + + if not en_path.exists(): + console.print(f"[red]Error:[/red] Source file not found: {en_path}") + raise typer.Exit(code=1) + + langs = get_langs() + if language not in langs: + console.print(f"[red]Error:[/red] Unknown language: {language}") + raise typer.Exit(code=1) + + language_name = langs[language] + out_path = to_lang_path(en_path, language) + out_path.parent.mkdir(parents=True, exist_ok=True) + + original_content = en_path.read_text(encoding="utf-8") + old_translation = ( + out_path.read_text(encoding="utf-8") if out_path.exists() else None + ) + + console.print(f"Translating [cyan]{en_path.name}[/cyan] to {language_name}") + + # Build prompt + prompt_parts = [get_general_prompt(), get_lang_prompt(language)] + + if old_translation: + console.print(" [dim]Updating existing translation[/dim]") + prompt_parts.extend( + [ + "There is an existing translation that may be outdated. Update only where necessary:", + "- Add new parts from the English source", + "- Remove parts deleted from the English source", + "- Update changed parts", + "- Fix any violations of current instructions", + "- Otherwise preserve the translation LINE-BY-LINE, AS-IS", + "", + "Do NOT rephrase correct lines or change formatting unless required.", + "Minimize diffs for easier human review.", + "", + "Previous translation:", + f"%%%\n{old_translation}%%%", + ] + ) + + prompt_parts.extend( + [ + f"Translate to {language} ({language_name}).", + "Original content:", + f"%%%\n{original_content}%%%", + ] + ) + + prompt = "\n\n".join(prompt_parts) + + with Progress( + SpinnerColumn(), + TextColumn("[progress.description]{task.description}"), + console=console, + ) as progress: + progress.add_task("Calling Claude API...", total=None) + client = anthropic.Anthropic() + message = client.messages.create( + model=MODEL, + max_tokens=16384, + messages=[{"role": "user", "content": prompt}], + ) + + out_content = f"{message.content[0].text.strip()}\n" + out_path.write_text(out_content, encoding="utf-8", newline="\n") + console.print(f" [green]Saved:[/green] {out_path}") + + +@app.command() +def list_missing(language: str): + """List English files that haven't been translated.""" + missing = [] + for en_path in iter_en_docs(): + lang_path = to_lang_path(en_path, language) + if not lang_path.exists(): + missing.append(en_path) + + if not missing: + console.print(f"[green]All files translated for {language}[/green]") + return + + console.print(f"[yellow]Missing translations for {language}:[/yellow]") + for path in missing: + console.print(f" {path.relative_to(REPO_ROOT)}") + console.print(f"\nTotal: {len(missing)} files") + + +@app.command() +def list_outdated(language: str): + """List translations older than their English source (by git commit time).""" + repo = git.Repo(REPO_ROOT) + outdated = [] + + for en_path in iter_en_docs(): + lang_path = to_lang_path(en_path, language) + if not lang_path.exists(): + continue + + en_commits = list(repo.iter_commits(paths=str(en_path), max_count=1)) + lang_commits = list(repo.iter_commits(paths=str(lang_path), max_count=1)) + + if not en_commits or not lang_commits: + continue + + if lang_commits[0].committed_datetime < en_commits[0].committed_datetime: + outdated.append(en_path) + + if not outdated: + console.print(f"[green]All translations up to date for {language}[/green]") + return + + console.print(f"[yellow]Outdated translations for {language}:[/yellow]") + for path in outdated: + console.print(f" {path.relative_to(REPO_ROOT)}") + console.print(f"\nTotal: {len(outdated)} files") + + +@app.command() +def list_removable(language: str): + """List translation files without English source (orphaned).""" + lang_docs = DOCS_PATH / language / "docs" + if not lang_docs.exists(): + console.print(f"[red]Error:[/red] Language docs not found: {lang_docs}") + raise typer.Exit(code=1) + + removable = [] + for lang_path in lang_docs.rglob("*.md"): + en_path = to_en_path(lang_path, language) + if not en_path.exists(): + removable.append(lang_path) + + if not removable: + console.print(f"[green]No orphaned files for {language}[/green]") + return + + console.print(f"[yellow]Orphaned files for {language}:[/yellow]") + for path in removable: + console.print(f" {path.relative_to(REPO_ROOT)}") + console.print(f"\nTotal: {len(removable)} files") + + +@app.command() +def update_outdated( + language: str = typer.Option(..., "--language", "-l", envvar="LANGUAGE"), +): + """Update all outdated translations for a language.""" + repo = git.Repo(REPO_ROOT) + outdated = [] + + for en_path in iter_en_docs(): + lang_path = to_lang_path(en_path, language) + if not lang_path.exists(): + continue + + en_commits = list(repo.iter_commits(paths=str(en_path), max_count=1)) + lang_commits = list(repo.iter_commits(paths=str(lang_path), max_count=1)) + + if en_commits and lang_commits: + if lang_commits[0].committed_datetime < en_commits[0].committed_datetime: + outdated.append(en_path) + + if not outdated: + console.print(f"[green]All translations up to date for {language}[/green]") + return + + console.print(f"Updating {len(outdated)} outdated translations...") + for i, en_path in enumerate(outdated, 1): + console.print(f"\n[{i}/{len(outdated)}] {en_path.name}") + translate_page(language=language, en_path=en_path) + + +@app.command() +def add_missing( + language: str = typer.Option(..., "--language", "-l", envvar="LANGUAGE"), + include: str = typer.Option( + None, + "--include", + "-i", + help="Only translate files matching this pattern (e.g., 'hello_nextflow')", + ), +): + """Translate all missing files for a language.""" + missing = [] + for en_path in iter_en_docs(): + # Filter by include pattern if specified + if include and include not in str(en_path): + continue + lang_path = to_lang_path(en_path, language) + if not lang_path.exists(): + missing.append(en_path) + + if not missing: + if include: + console.print( + f"[green]All matching files already translated for {language}[/green]" + ) + else: + console.print(f"[green]All files already translated for {language}[/green]") + return + + console.print(f"Translating {len(missing)} missing files...") + for i, en_path in enumerate(missing, 1): + console.print(f"\n[{i}/{len(missing)}] {en_path.name}") + translate_page(language=language, en_path=en_path) + + +@app.command() +def remove_removable( + language: str = typer.Option(..., "--language", "-l", envvar="LANGUAGE"), +): + """Remove orphaned translation files (no English source).""" + lang_docs = DOCS_PATH / language / "docs" + removed = 0 + + for lang_path in lang_docs.rglob("*.md"): + en_path = to_en_path(lang_path, language) + if not en_path.exists(): + lang_path.unlink() + console.print(f"[red]Removed:[/red] {lang_path.relative_to(REPO_ROOT)}") + removed += 1 + + console.print(f"\nRemoved {removed} orphaned files") + + +@app.command() +def make_pr( + language: str = typer.Option(None, "--language", "-l", envvar="LANGUAGE"), + command: str = typer.Option(None, "--command", "-c", envvar="COMMAND"), + github_token: str = typer.Option(..., envvar="GITHUB_TOKEN"), + github_repository: str = typer.Option(..., envvar="GITHUB_REPOSITORY"), +): + """Create a PR with translation changes (for CI use).""" + repo = git.Repo(REPO_ROOT) + + if not repo.is_dirty(untracked_files=True): + console.print("[yellow]No changes to commit[/yellow]") + return + + # Configure git + subprocess.run( + ["git", "config", "user.name", "github-actions[bot]"], check=True, cwd=REPO_ROOT + ) + subprocess.run( + ["git", "config", "user.email", "github-actions[bot]@users.noreply.github.com"], + check=True, + cwd=REPO_ROOT, + ) + + # Create branch + branch_name = ( + f"translate-{language or 'all'}-{command or 'update'}-{secrets.token_hex(4)}" + ) + subprocess.run(["git", "checkout", "-b", branch_name], check=True, cwd=REPO_ROOT) + + # Commit + subprocess.run(["git", "add", "docs/"], check=True, cwd=REPO_ROOT) + message = "Update translations" + if language: + message += f" for {language}" + if command: + message += f" ({command})" + subprocess.run(["git", "commit", "-m", message], check=True, cwd=REPO_ROOT) + + # Push + subprocess.run(["git", "push", "origin", branch_name], check=True, cwd=REPO_ROOT) + + # Create PR + g = Github(github_token) + gh_repo = g.get_repo(github_repository) + body = f"""{message} + +This PR was created automatically using LLM translation. + +Prompt file: https://github.com/{github_repository}/blob/master/docs/{language}/llm-prompt.md + +To improve translations, edit the prompt file rather than individual translations.""" + + pr = gh_repo.create_pull(title=message, body=body, base="master", head=branch_name) + console.print(f"[green]Created PR:[/green] {pr.html_url}") + + +if __name__ == "__main__": + if not DOCS_PATH.exists(): + console.print("[red]Error:[/red] Must run from repository root") + sys.exit(1) + app() diff --git a/_scripts/translation_fixer.py b/_scripts/translation_fixer.py new file mode 100644 index 0000000000..2e96a5051e --- /dev/null +++ b/_scripts/translation_fixer.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "typer>=0.12.0", +# "rich>=13.0.0", +# ] +# /// +""" +Post-process translations to fix common LLM mistakes. + +Usage: + uv run translation_fixer.py fix-all pt + uv run translation_fixer.py fix-pages docs/pt/docs/index.md +""" + +import sys +from pathlib import Path + +import typer +from rich.console import Console + +from doc_parsing_utils import check_translation + +app = typer.Typer(help="Fix common issues in translated documents") +console = Console() + +# Must be run from repo root +REPO_ROOT = Path(__file__).parent.parent +DOCS_PATH = REPO_ROOT / "docs" +EN_DOCS_PATH = DOCS_PATH / "en" / "docs" + + +def fix_one_page(path: Path) -> bool: + """ + Fix a translated document by comparing it to the English version. + + Returns True if successful. Raises on error (fail loud). + """ + # Determine language from path + try: + lang_code = path.relative_to(DOCS_PATH).parts[0] + except ValueError: + console.print(f"[red]Error:[/red] Path not in docs/: {path}") + raise typer.Exit(code=1) + + if lang_code == "en": + console.print(f"[yellow]Skipping English file:[/yellow] {path}") + return True + + # Find English source + rel_path = path.relative_to(DOCS_PATH / lang_code / "docs") + en_path = EN_DOCS_PATH / rel_path + + if not en_path.exists(): + console.print(f"[red]Error:[/red] English source not found: {en_path}") + raise typer.Exit(code=1) + + doc_lines = path.read_text(encoding="utf-8").splitlines() + en_doc_lines = en_path.read_text(encoding="utf-8").splitlines() + + # This will raise ValueError if structure doesn't match - that's intentional + fixed_lines = check_translation( + doc_lines=doc_lines, + en_doc_lines=en_doc_lines, + auto_fix=True, + path=str(path), + ) + + # Write back + fixed_lines.append("") # Ensure trailing newline + path.write_text("\n".join(fixed_lines), encoding="utf-8") + return True + + +@app.command() +def fix_all(language: str): + """Fix all translation files for a language.""" + lang_docs = DOCS_PATH / language / "docs" + + if not lang_docs.exists(): + console.print(f"[red]Error:[/red] Language docs not found: {lang_docs}") + raise typer.Exit(code=1) + + files = list(lang_docs.rglob("*.md")) + console.print(f"Fixing {len(files)} files for {language}...") + + for path in files: + console.print(f" {path.name}", end=" ") + fix_one_page(path) + console.print("[green]OK[/green]") + + console.print(f"\n[green]Fixed {len(files)} files[/green]") + + +@app.command() +def fix_pages(paths: list[Path]): + """Fix specific translation files.""" + for path in paths: + if not path.exists(): + console.print(f"[red]Error:[/red] File not found: {path}") + raise typer.Exit(code=1) + + console.print(f"Fixing {path}...", end=" ") + fix_one_page(path) + console.print("[green]OK[/green]") + + +if __name__ == "__main__": + if not DOCS_PATH.exists(): + console.print("[red]Error:[/red] Must run from repository root") + sys.exit(1) + app() diff --git a/docs/de/docs/envsetup/01_setup.md b/docs/de/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..f2743cf997 --- /dev/null +++ b/docs/de/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces ist eine webbasierte Plattform, die es uns ermöglicht, eine vorkonfigurierte Umgebung für das Training bereitzustellen, unterstützt durch virtuelle Maschinen in der Cloud. +Die Plattform wird von GitHub (das zu Microsoft gehört) betrieben und ist kostenlos (mit Nutzungskontingenten) für jeden mit einem GitHub-Konto zugänglich. + +!!! warning "Warnung" + + Konten, die mit Organisationen verbunden sind, können bestimmten zusätzlichen Einschränkungen unterliegen. + In diesem Fall musst du möglicherweise ein unabhängiges persönliches Konto verwenden oder stattdessen eine lokale Installation nutzen. + +## Erstellen eines GitHub-Kontos + +Du kannst ein kostenloses GitHub-Konto auf der [GitHub-Startseite](https://github.com/) erstellen. + +## Starten deines GitHub Codespace + +Sobald du bei GitHub angemeldet bist, öffne diesen Link in deinem Browser, um die Nextflow-Trainingsumgebung zu öffnen: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Alternativ kannst du auf den unten gezeigten Button klicken, der in jedem Trainingskurs wiederholt wird (typischerweise auf der Orientierungsseite). + +[![In GitHub Codespaces öffnen](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Dir sollte eine Seite angezeigt werden, auf der du einen neuen GitHub Codespace erstellen kannst: + +![Einen GitHub Codespace erstellen](img/codespaces_create.png) + +### Konfiguration + +Für die allgemeine Nutzung solltest du nichts konfigurieren müssen. +Sofern nicht anders im Kurs angegeben, den du beginnst, kannst du einfach auf den Hauptbutton klicken, um fortzufahren. + +Es ist jedoch möglich, die Umgebung anzupassen, indem du auf den Button "Change options" klickst. + +??? info "Konfigurationsoptionen" + + Wenn du auf den Button "Change options" klickst, erhältst du die Möglichkeit, Folgendes anzupassen: + + #### Branch + + Dies ermöglicht dir, eine andere Version der Trainingsmaterialien auszuwählen. + Der `master`-Branch enthält im Allgemeinen Fehlerbehebungen und Materialien, die kürzlich entwickelt und genehmigt wurden, aber noch nicht auf der Website veröffentlicht wurden. + Andere Branches enthalten laufende Arbeiten, die möglicherweise nicht vollständig funktionsfähig sind. + + #### Maschinentyp + + Dies ermöglicht dir, die virtuelle Maschine anzupassen, die du zum Durcharbeiten des Trainings verwendest. + + Die Verwendung einer Maschine mit mehr Kernen ermöglicht es dir, Nextflows Fähigkeit zur Parallelisierung der Workflow-Ausführung besser zu nutzen. + Dies verbraucht jedoch dein kostenloses Kontingent schneller, daher empfehlen wir nicht, diese Einstellung zu ändern, es sei denn, es wird in den Anweisungen des Kurses empfohlen, den du planst zu absolvieren. + + Siehe 'GitHub Codespaces-Kontingente' unten für weitere Details zu Kontingenten. + +### Startzeit + +Das erstmalige Öffnen einer neuen GitHub Codespaces-Umgebung kann mehrere Minuten dauern, da das System deine virtuelle Maschine einrichten muss. Mache dir also keine Sorgen, wenn es eine Wartezeit gibt. +Es sollte jedoch nicht länger als fünf Minuten dauern. + +## Navigation in der Trainingsoberfläche + +Sobald dein GitHub Codespace geladen ist, solltest du etwas Ähnliches wie das Folgende sehen (das je nach deinen Kontoeinstellungen im hellen Modus geöffnet werden kann): + +![GitHub Codespaces Willkommen](img/codespaces_welcome.png) + +Dies ist die Oberfläche der VSCode IDE, einer beliebten Anwendung zur Codeentwicklung, die wir für die Nextflow-Entwicklung empfehlen. + +- **Der Haupteditor** ist der Bereich, in dem Nextflow-Code und andere Textdateien geöffnet werden. Hier wirst du Code bearbeiten. Wenn du den Codespace öffnest, zeigt dieser dir eine Vorschau der `README.md`-Datei. +- **Das Terminal** unter dem Haupteditor ermöglicht es dir, Befehle auszuführen. Hier wirst du alle Befehlszeilen ausführen, die in den Kursanweisungen gegeben werden. +- **Die Seitenleiste** ermöglicht es dir, deine Umgebung anzupassen und grundlegende Aufgaben durchzuführen (Kopieren, Einfügen, Dateien öffnen, Suchen, Git usw.). Standardmäßig ist sie im Datei-Explorer geöffnet, der es dir ermöglicht, den Inhalt des Repositorys zu durchsuchen. Das Klicken auf eine Datei im Explorer öffnet sie im Haupteditorfenster. + +Du kannst die relativen Proportionen der Fensterbereiche nach Belieben anpassen. + +<!-- TODO (future) Link to development best practices side quest? --> + +## Weitere Hinweise zur Verwendung von GitHub Codespaces + +### Wiederaufnahme einer Sitzung + +Sobald du eine Umgebung erstellt hast, kannst du sie einfach fortsetzen oder neu starten und dort weitermachen, wo du aufgehört hast. +Deine Umgebung wird nach 30 Minuten Inaktivität in den Timeout gehen und deine Änderungen bis zu 2 Wochen speichern. + +Du kannst eine Umgebung unter <https://github.com/codespaces/> wieder öffnen. +Frühere Umgebungen werden aufgelistet. +Klicke auf eine Sitzung, um sie fortzusetzen. + +![GitHub Codespace-Sitzungen auflisten](img/codespaces_list.png) + +Wenn du die URL für deine frühere GitHub Codespaces-Umgebung gespeichert hast, kannst du sie einfach in deinem Browser öffnen. +Alternativ klicke auf denselben Button, den du ursprünglich zum Erstellen verwendet hast: + +[![In GitHub Codespaces öffnen](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Du solltest die frühere Sitzung sehen. Die Standardoption ist, sie fortzusetzen: + +![Einen GitHub Codespace fortsetzen](img/codespaces_resume.png) + +### Dateien auf deinem lokalen Rechner speichern + +Um eine Datei aus dem Explorer-Panel zu speichern, klicke mit der rechten Maustaste auf die Datei und wähle `Download`. + +### Verwaltung der GitHub Codespaces-Kontingente + +GitHub Codespaces gibt dir bis zu 15 GB-Monat Speicherplatz pro Monat und 120 Core-Stunden pro Monat. +Dies entspricht etwa 60 Stunden der Standard-Umgebungslaufzeit mit dem Standard-Workspace (2 Kerne, 8 GB RAM und 32 GB Speicher). + +Du kannst sie mit mehr Ressourcen erstellen (siehe Erklärung oben), aber dies verbraucht deine kostenlose Nutzung schneller und du hast weniger Stunden Zugang zu diesem Space. +Wenn du beispielsweise eine 4-Kern-Maschine anstelle der 2-Kern-Standardmaschine auswählst, ist dein Kontingent in der Hälfte der Zeit aufgebraucht. + +Optional kannst du Zugang zu mehr Ressourcen erwerben. + +Weitere Informationen findest du in der GitHub-Dokumentation: +[Über die Abrechnung für GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/de/docs/envsetup/02_local.md b/docs/de/docs/envsetup/02_local.md new file mode 100644 index 0000000000..ac33aed532 --- /dev/null +++ b/docs/de/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Manuelle Installation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Es ist möglich, alles, was du zum Ausführen des Trainings benötigst, manuell in deiner eigenen lokalen Umgebung zu installieren. + +Hier haben wir dokumentiert, wie das auf Standard-POSIX-kompatiblen Systemen geht (unter der Annahme eines persönlichen Rechners wie eines Laptops). +Beachte, dass einige Details je nach deinem spezifischen System unterschiedlich sein können. + +!!! tip "Tipp" + + Bevor du fortfährst, hast du den [Devcontainers-Ansatz](03_devcontainer.md) in Betracht gezogen? + Er stellt alle notwendigen Tools und Abhängigkeiten bereit, ohne dass eine manuelle Installation erforderlich ist. + +## Allgemeine Softwareanforderungen + +Nextflow kann auf jedem POSIX-kompatiblen System (Linux, macOS, Windows Subsystem for Linux usw.) mit installiertem Java verwendet werden. +Unsere Trainingskurse haben einige zusätzliche Anforderungen. + +Insgesamt musst du die folgende Software installiert haben: + +- Bash oder eine gleichwertige Shell +- [Java 11 (oder höher, bis 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (oder höher) +- [VSCode](https://code.visualstudio.com) mit der [Nextflow-Erweiterung](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +Die VSCode-Anwendung ist technisch optional, aber wir empfehlen dringend, sie sowohl für das Durcharbeiten der Kurse als auch für deine Nextflow-Entwicklungsarbeit im Allgemeinen zu verwenden. + +Das Nextflow-Dokumentationshandbuch enthält Anweisungen zur Installation dieser Abhängigkeiten unter [Umgebungseinrichtung](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow und nf-core tools + +Du musst Nextflow selbst sowie die nf-core tools installieren, wie in den unten verlinkten Artikeln beschrieben: + +- [Nextflow-Installation](https://www.nextflow.io/docs/latest/install.html) +- [nf-core tools](https://nf-co.re/docs/nf-core-tools/installation) + +Wir empfehlen die Self-Install-Option für Nextflow und die PyPI-Option für nf-core tools. + +!!! warning "Versionskompatibilität" + + <!-- Any update to this content needs to be copied to the home page --> + **Ab Januar 2026 erfordern alle unsere Nextflow-Trainingskurse Nextflow Version 25.10.2 oder höher mit aktivierter strikter v2-Syntax, sofern nicht anders angegeben.** + + Weitere Informationen zu Versionsanforderungen und strikter v2-Syntax findest du im [Nextflow-Versionen](../info/nxf_versions.md)-Leitfaden. + + Ältere Versionen des Trainingsmaterials, die früherer Syntax entsprechen, sind über den Versionsauswähler in der Menüleiste dieser Webseite verfügbar. + +## Trainingsmaterialien + +Der einfachste Weg, die Trainingsmaterialien herunterzuladen, ist das Klonen des gesamten Repositorys mit diesem Befehl: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Jeder Kurs hat sein eigenes Verzeichnis. +Um einen Kurs durchzuarbeiten, öffne ein Terminalfenster (idealerweise innerhalb der VSCode-Anwendung) und wechsle mit `cd` in das entsprechende Verzeichnis. + +Du kannst dann den Kursanweisungen auf der Website folgen. diff --git a/docs/de/docs/envsetup/03_devcontainer.md b/docs/de/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..6ddcfe704d --- /dev/null +++ b/docs/de/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Lokale Devcontainers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Wenn du eine lokale Docker-Installation hast oder bereit bist, eine zu installieren, ist der einfachste Weg, lokal mit diesen Materialien zu arbeiten, die Devcontainer-Funktion von Visual Studio Code zu verwenden. Dieser Ansatz stellt alle notwendigen Tools und Abhängigkeiten bereit, ohne dass eine manuelle Installation erforderlich ist. + +## Anforderungen + +Um das lokale Devcontainer-Setup zu verwenden, benötigst du: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Eine lokale Docker-Installation, zum Beispiel: + - [Docker Desktop](https://docs.docker.com/get-docker/) (für Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (für Linux) + - [Colima](https://github.com/abiosoft/colima) (Alternative für macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (in Docker Desktop enthalten, kann aber bei anderen Docker-Setups eine separate Installation erfordern) +- [Dev Containers-Erweiterung](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) für VS Code + +Deine Docker-Installation muss laufen, bevor du versuchst, den Devcontainer zu öffnen. + +Um zu überprüfen, ob Docker buildx verfügbar ist, führe aus: + +```bash +docker buildx version +``` + +Wenn dieser Befehl fehlschlägt, musst du die buildx-Erweiterung installieren, bevor du fortfährst. + +## Einrichtungsanleitung + +Folge diesen Schritten, um deine lokale Umgebung mit VS Code Devcontainers einzurichten: + +### Installiere die "Dev Containers"-Erweiterung in VS Code + +- Öffne VS Code +- Gehe zu Extensions (Strg+Umschalt+X oder Cmd+Umschalt+X auf macOS) +- Suche nach "Dev Containers" +- Klicke auf "Install" + +![Installation der Dev Containers-Erweiterung in VS Code](img/install_extension.png) + +### Klone das Repository: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Öffne das Repository in VS Code: + +- Starte VS Code +- Wähle **Datei -> Ordner öffnen** aus dem Menü +- Navigiere zum gerade geklonten Training-Repository-Ordner und wähle ihn aus +- Klicke auf **Öffnen** + +### In Container erneut öffnen + +Wenn VS Code dich auffordert, "In Container erneut öffnen", klicke darauf. Alternativ: + +- Drücke F1 (oder Strg+Umschalt+P / Cmd+Umschalt+P auf macOS) +- Tippe "Dev Containers: Reopen in Container" +- **Wichtig**: Wenn du aufgefordert wirst, eine Konfiguration auszuwählen, wähle die **local-dev** Devcontainer-Konfiguration + +![Aufforderung zum erneuten Öffnen im Container](img/reopen_prompt.png) + +![Auswahl der lokalen Konfiguration](img/select_local_config.png) + +Warte, bis der Container erstellt ist. Dies kann beim ersten Mal einige Minuten dauern, da alle notwendigen Komponenten heruntergeladen und eingerichtet werden. + +Sobald der Container erstellt und ausgeführt wird, hast du eine vollständig konfigurierte Umgebung mit allen installierten notwendigen Tools, einschließlich: + +- Java +- Nextflow +- Docker +- Git +- Und alle anderen für das Training erforderlichen Abhängigkeiten + +![VS Code mit laufendem Devcontainer](img/running_container.png) + +## Vorteile der Verwendung von Devcontainers + +Die Verwendung des Devcontainer-Ansatzes bietet mehrere Vorteile: + +- **Konsistenz**: Stellt eine konsistente Entwicklungsumgebung über verschiedene Maschinen hinweg sicher +- **Einfachheit**: Alle Abhängigkeiten sind vorinstalliert und konfiguriert +- **Isolation**: Die Entwicklungsumgebung ist von deinem lokalen System isoliert +- **Reproduzierbarkeit**: Jeder, der den Devcontainer verwendet, erhält dasselbe Setup +- **Keine manuelle Installation**: Keine Notwendigkeit, Java, Nextflow und andere Tools manuell zu installieren + +## Überprüfung deiner Umgebung + +Sobald dein Devcontainer läuft, kannst du überprüfen, ob alles korrekt eingerichtet ist, indem du ausführst: + +```bash +nextflow info +``` + +Dies sollte die Nextflow-Version und Laufzeitinformationen anzeigen und bestätigen, dass deine Umgebung korrekt konfiguriert ist. + +## Fehlerbehebung + +Wenn du Probleme mit dem Devcontainer-Setup hast: + +1. Stelle sicher, dass deine Docker-Installation (Docker Desktop, Colima, Docker Engine usw.) läuft, bevor du den Devcontainer öffnest +2. Überprüfe, dass du die **local-dev**-Konfiguration ausgewählt hast, wenn du dazu aufgefordert wurdest +3. Überprüfe, ob Docker buildx installiert ist und funktioniert, indem du `docker buildx version` ausführst +4. Wenn der Container nicht erstellt werden kann, versuche ihn neu zu erstellen, indem du den Befehl "Dev Containers: Rebuild Container" ausführst +5. Bei anhaltenden Problemen siehe den [VS Code Dev Containers-Fehlerbehebungsleitfaden](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/de/docs/envsetup/index.md b/docs/de/docs/envsetup/index.md new file mode 100644 index 0000000000..9419e17e78 --- /dev/null +++ b/docs/de/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Umgebungsoptionen +description: Optionen zum Einrichten deiner Umgebung für die Nextflow-Trainings +hide: + - toc + - footer +--- + +# Umgebungsoptionen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Wir möchten eine konsistente und gründlich getestete Umgebung bereitstellen, die es Lernenden ermöglicht, sich auf das Erlernen von Nextflow zu konzentrieren, ohne Zeit und Mühe für die Softwareverwaltung aufwenden zu müssen. +Zu diesem Zweck haben wir eine containerisierte Umgebung entwickelt, die alle notwendige Software, Codedateien und Beispieldaten enthält, um alle unsere Kurse durchzuarbeiten. + +Diese containerisierte Umgebung kann sofort auf GitHub Codespaces oder lokal in VS Code mit der Devcontainers-Erweiterung ausgeführt werden. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **GitHub Codespaces** + + *** + + GitHub Codespaces ist ein webbasierter Dienst, der es uns ermöglicht, eine vorkonfigurierte Umgebung für das Training bereitzustellen, mit allen Tools und Daten inklusive, unterstützt durch virtuelle Maschinen in der Cloud. Er ist kostenlos für jeden mit einem GitHub-Konto zugänglich. + + [GitHub Codespaces verwenden:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Lokale Devcontainers** + + *** + + VS Code mit Devcontainers bietet eine lokal ausgeführte, containerisierte Entwicklungsumgebung mit allen vorinstallierten Trainingstools. Sie bietet dieselbe vorkonfigurierte Umgebung wie Codespaces, läuft aber vollständig auf deiner lokalen Hardware. + + [Devcontainers lokal verwenden :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Anleitung zur manuellen Installation + +Wenn keine der oben genannten Optionen deinen Anforderungen entspricht, kannst du diese Umgebung auf deinem eigenen lokalen System replizieren, indem du die Software-Abhängigkeiten manuell installierst und das Training-Repository klonst. + +[Manuelle Installation :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Einstellung von Gitpod" + + Das Nextflow-Training verwendete bis Februar 2025 [Gitpod](https://gitpod.io). + Allerdings entschieden sich die Macher von Gitpod, die kostenlose Funktionalität zugunsten des [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex)-Systems einzustellen. + Aus diesem Grund sind wir zu GitHub Codespaces gewechselt, das ebenfalls eine Ein-Klick-Entwicklungsumgebung ohne vorherige Einrichtung bietet. + + Je nachdem, wann du dich bei Gitpod angemeldet hast und wann genau der Dienst eingestellt wird, kannst du das Training möglicherweise noch in deren alter Cloud-IDE starten, obwohl wir keinen zuverlässigen Zugang für die Zukunft garantieren können: + [In Gitpod öffnen](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/de/docs/hello_nextflow/00_orientation.md b/docs/de/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..51db6a6f34 --- /dev/null +++ b/docs/de/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Erste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Sieh dir [die gesamte Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal an. + +:green_book: Das Videotranskript ist [hier](./transcripts/00_orientation.md) verfügbar. +/// + +!!! tip "Tipp" + + Die YouTube-Videos haben einige Superkräfte! + + - :fontawesome-solid-closed-captioning: Hochwertige (manuell kuratierte) Untertitel. Schalte sie mit dem :material-subtitles: Symbol ein + - :material-bookmark: Videokapitel in der Zeitleiste, die den Seitenüberschriften entsprechen. + +## Trainingsumgebung starten + +Um die vorgefertigte Umgebung zu nutzen, die wir auf GitHub Codespaces bereitstellen, klicke auf den Button "Open in GitHub Codespaces" unten. Für weitere Optionen siehe [Umgebungsoptionen](../envsetup/index.md). + +Wir empfehlen, die Trainingsumgebung in einem neuen Browser-Tab oder -Fenster zu öffnen (verwende Rechtsklick, Strg-Klick oder Cmd-Klick je nach Gerät), damit du weiterlesen kannst, während die Umgebung lädt. +Du musst diese Anweisungen parallel geöffnet halten, um den Kurs durchzuarbeiten. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Grundlagen der Umgebung + +Diese Trainingsumgebung enthält alle Software, den Code und die Daten, die zum Durcharbeiten des Trainingskurses erforderlich sind, sodass du selbst nichts installieren musst. + +Der Codespace ist mit einer VSCode-Oberfläche eingerichtet, die einen Dateisystem-Explorer, einen Code-Editor und eine Terminal-Shell umfasst. +Alle Anweisungen während des Kurses (z.B. 'öffne die Datei', 'bearbeite den Code' oder 'führe diesen Befehl aus') beziehen sich auf diese drei Teile der VScode-Oberfläche, sofern nicht anders angegeben. + +Wenn du diesen Kurs selbstständig durcharbeitest, mache dich bitte mit den [Grundlagen der Umgebung](../envsetup/01_setup.md) für weitere Details vertraut. + +### Versionsanforderungen + +Dieses Training ist für Nextflow 25.10.2 oder höher **mit aktiviertem v2 Syntax-Parser** konzipiert. +Wenn du eine lokale oder benutzerdefinierte Umgebung verwendest, stelle bitte sicher, dass du die korrekten Einstellungen wie [hier](../info/nxf_versions.md) dokumentiert verwendest. + +## Vorbereitung + +Sobald dein Codespace läuft, musst du zwei Dinge tun, bevor du mit dem Training beginnst: das Arbeitsverzeichnis für diesen spezifischen Kurs festlegen und einen Blick auf die bereitgestellten Materialien werfen. + +### Arbeitsverzeichnis festlegen + +Standardmäßig öffnet der Codespace mit dem Arbeitsverzeichnis im Stammverzeichnis aller Trainingskurse, aber für diesen Kurs werden wir im Verzeichnis `hello-nextflow/` arbeiten. + +Wechsle jetzt das Verzeichnis, indem du diesen Befehl im Terminal ausführst: + +```bash +cd hello-nextflow/ +``` + +Du kannst VSCode auf dieses Verzeichnis fokussieren lassen, sodass nur die relevanten Dateien in der Datei-Explorer-Seitenleiste angezeigt werden: + +```bash +code . +``` + +!!! tip "Tipp" + + Falls du aus irgendeinem Grund dieses Verzeichnis verlässt (z.B. wenn dein Codespace in den Ruhezustand geht), kannst du immer den vollständigen Pfad verwenden, um dorthin zurückzukehren, vorausgesetzt du arbeitest in der Github Codespaces Trainingsumgebung: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Schauen wir uns nun den Inhalt an. + +### Bereitgestellte Materialien erkunden + +Du kannst den Inhalt dieses Verzeichnisses über den Datei-Explorer auf der linken Seite des Trainingsarbeitsbereichs erkunden. +Alternativ kannst du den `tree`-Befehl verwenden. + +Im gesamten Kurs verwenden wir die Ausgabe von `tree`, um die Verzeichnisstruktur und den Inhalt in einer lesbaren Form darzustellen, manchmal mit geringfügigen Änderungen zur Klarheit. + +Hier generieren wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 2 +``` + +??? abstract "Verzeichnisinhalt" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Klicke auf das farbige Kästchen, um den Abschnitt zu erweitern und seinen Inhalt anzuzeigen. +Wir verwenden ausklappbare Abschnitte wie diesen, um erwartete Befehlsausgaben kompakt darzustellen. + +- **Die `.nf`-Dateien** sind Workflow-Skripte, die nach dem Teil des Kurses benannt sind, in dem sie verwendet werden. + +- **Die Datei `nextflow.config`** ist eine Konfigurationsdatei, die minimale Umgebungseigenschaften festlegt. + Du kannst sie vorerst ignorieren. + +- **Die Datei `greetings.csv`** unter `data/` enthält Eingabedaten, die wir im größten Teil des Kurses verwenden werden. Sie wird in Teil 2 (Channels) beschrieben, wenn wir sie zum ersten Mal einführen. + +- **Die `test-params.*`-Dateien** sind Konfigurationsdateien, die wir in Teil 6 (Konfiguration) verwenden werden. Du kannst sie vorerst ignorieren. + +- **Das `solutions`-Verzeichnis** enthält die fertigen Workflow-Skripte, die aus jedem Schritt des Kurses resultieren. + Sie sind als Referenz gedacht, um deine Arbeit zu überprüfen und eventuelle Probleme zu beheben. + +## Bereitschafts-Checkliste + +Bist du bereit? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Meine Umgebung läuft +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend festgelegt + +Wenn du alle Kästchen abhaken kannst, bist du startklar. + +**Um zu [Teil 1: Hello World](./01_hello_world.md) fortzufahren, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite.** diff --git a/docs/de/docs/hello_nextflow/01_hello_world.md b/docs/de/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..efcc662ac6 --- /dev/null +++ b/docs/de/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Teil 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Siehe [die gesamte Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal. + +:green_book: Das Videotranskript ist [hier](./transcripts/01_hello_world.md) verfügbar. +/// + +In diesem ersten Teil des Hello Nextflow Trainingskurses führen wir dich mit einem sehr einfachen, domänenunabhängigen Hello World Beispiel an das Thema heran. Dieses werden wir schrittweise erweitern, um die Verwendung grundlegender Nextflow-Logik und -Komponenten zu demonstrieren. + +??? info "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, den Text "Hello, World!" auf das Ausgabegerät, wie die Konsole oder das Terminal, zu drucken oder in eine Datei zu schreiben. + +--- + +## 0. Aufwärmen: Ein Hello World Beispiel direkt ausführen + +Lass uns dies mit einem einfachen Befehl demonstrieren, den wir direkt im Terminal ausführen, um zu zeigen, was er macht, bevor wir ihn in Nextflow einbetten. + +!!! tip "Tipp" + + Denke daran, dass du dich jetzt im Verzeichnis `hello-nextflow/` befinden solltest, wie auf der Seite [Erste Schritte](00_orientation.md) beschrieben. + +### 0.1. Das Terminal zur Begrüßung auffordern + +Führe den folgenden Befehl in deinem Terminal aus. + +```bash +echo 'Hello World!' +``` + +??? success "Befehlsausgabe" + + ```console + Hello World! + ``` + +Dies gibt den Text 'Hello World' direkt im Terminal aus. + +### 0.2. Die Ausgabe in eine Datei schreiben + +Bei der Ausführung von Pipelines geht es hauptsächlich darum, Daten aus Dateien zu lesen und Ergebnisse in andere Dateien zu schreiben. Lass uns den Befehl so modifizieren, dass die Textausgabe in eine Datei geschrieben wird, um das Beispiel etwas relevanter zu machen. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Befehlsausgabe" + + ```console + + ``` + +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 zum Beispiel mit dem Dienstprogramm `cat` von der Befehlszeile aus. + +??? abstract "Dateiinhalt" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Dies werden wir mit unserem allerersten Nextflow-Workflow zu replizieren versuchen. + +### Zusammenfassung + +Du weißt jetzt, wie man einen einfachen Befehl im Terminal ausführt, der etwas Text ausgibt, und optional, wie man ihn dazu bringt, die Ausgabe in eine Datei zu schreiben. + +### Was kommt als Nächstes? + +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 macht wie zuvor (es gibt 'Hello World!' aus), aber mit Nextflow. + +Um dir den Einstieg zu erleichtern, öffnen wir das Workflow-Skript, damit du ein Gefühl für seine Struktur bekommst. +Dann führen wir es aus und suchen nach seinen 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-Bereich. + +??? full-code "Vollständige Codedatei" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() + } + ``` + +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 Datenflusslogik beschreibt, die die verschiedenen Schritte verbindet. + +Wir werden uns zuerst den **process**-Block genauer ansehen, dann werden wir uns den **workflow**-Block ansehen. + +#### 1.1.1. Die `process`-Definition + +Der erste Codeblock beschreibt einen **process**. + +Die Prozessdefinition beginnt mit dem Schlüsselwort `process`, gefolgt vom Prozessnamen und schließlich dem Prozesskörper, der von geschweiften Klammern begrenzt wird. +Der Prozesskörper muss einen script-Block enthalten, der den auszuführenden Befehl angibt, der alles sein kann, was du in einem Befehlszeilen-Terminal ausführen könntest. + +```groovy title="hello-world.nf" linenums="3" +/* +* Verwende echo, um 'Hello World!' in eine Datei zu schreiben +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Hier haben wir einen **process** namens `sayHello`, der seine **output** in eine Datei namens `output.txt` schreibt. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +Dies ist eine sehr minimale Prozessdefinition, die nur eine `output`-Definition und das auszuführende `script` enthält. + +Die `output`-Definition enthält den `path`-Qualifier, der Nextflow mitteilt, dass dies als Pfad behandelt werden soll (umfasst sowohl Verzeichnispfade als auch Dateien). +Ein weiterer 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 nach Abschluss der Ausführung danach suchen kann. +Dies ist notwendig, um zu überprüfen, ob der Befehl erfolgreich ausgeführt wurde, und um die Ausgabe bei Bedarf an nachgelagerte Prozesse weiterzugeben. Ausgaben, die nicht mit dem übereinstimmen, was im output-Block deklariert ist, werden nicht an nachgelagerte Prozesse weitergegeben. + +!!! warning "Warnung" + + Dieses Beispiel ist fragil, weil wir den Ausgabedateinamen an zwei verschiedenen Stellen (im script- und im output-Block) fest eincodiert haben. + Wenn wir einen ändern, aber nicht den anderen, wird das Skript nicht mehr funktionieren. + Später wirst du lernen, wie du Variablen verwenden kannst, 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-Körper, der von geschweiften Klammern begrenzt wird. + +Hier haben wir einen **workflow**, der aus einem `main:`-Block (der sagt 'dies ist der Hauptteil des Workflows') besteht, der einen Aufruf des `sayHello`-Prozesses enthält. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() +} +``` + +Dies ist eine sehr minimale **workflow**-Definition. +In einer realen Pipeline enthält der Workflow typischerweise mehrere Aufrufe von **Prozessen**, die durch **Channels** verbunden sind, und die Prozesse erwarten eine oder mehrere variable **Eingabe(n)**. + +Variable Eingaben behandeln wir später in diesem Modul. Teil 3 erklärt, wie du mehrere Prozesse hinzufügst und durch Channels verbindest. + +!!! tip "Tipp" + + Technisch gesehen ist die `main:`-Zeile für einfache Workflows wie diesen nicht erforderlich, daher könntest du auf Workflows stoßen, die sie nicht haben. + Aber wir werden sie brauchen, um Workflow-Level-Outputs zu nutzen, also können wir sie gleich von Anfang an einbeziehen. + +### 1.2. Den Workflow ausführen + +Code anzuschauen macht nicht annähernd so viel Spaß 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: + +```bash +nextflow run hello-world.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +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: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Dies sagt uns, dass der `sayHello`-Prozess einmal erfolgreich ausgeführt wurde (`1 of 1 ✔`). + +Wichtig ist, dass diese Zeile dir auch sagt, wo du die Ausgabe des `sayHello`-Prozessaufrufs findest. +Lass uns das jetzt anschauen. + +#### 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 ist, um es eindeutig zu machen, in dem es alle notwendigen Eingaben bereitstellt (standardmäßig mit Symlinks), Hilfsdateien schreibt und Logs sowie alle Ausgaben des Prozesses ausgibt. + +Der Pfad zu diesem Unterverzeichnis wird in verkürzter Form in eckigen Klammern in der Konsolenausgabe angezeigt. +Wenn wir uns ansehen, was wir für den oben gezeigten Lauf bekommen haben, beginnt die Konsolenlogzeile für den sayHello-Prozess mit `[65/7be2fa]`. Das entspricht dem folgenden Verzeichnispfad: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +Lass uns einen Blick darauf werfen, was dort drin ist. + +??? abstract "Verzeichnisinhalt" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "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 Logdateien sind jedoch so eingestellt, dass sie im Terminal unsichtbar sind. Wenn du also `ls` oder `tree` verwenden möchtest, um sie anzuzeigen, musst du die entsprechende Option zum Anzeigen unsichtbarer Dateien setzen. + + ```bash + tree -a work + ``` + +Das Erste, was du dir ansehen möchtest, ist die tatsächliche Ausgabe des Workflows, d.h. die Datei `output.txt`, die vom `sayHello`-Prozess erzeugt wurde. +Öffne sie und du findest die Begrüßung `Hello World!`, was der Sinn unseres minimalistischen Workflows war. + +??? abstract "Dateiinhalt" + + ```console title="output.txt" + Hello World! + ``` + +Es hat funktioniert! + +Zugegeben, das mag wie viel Wrapper-Code für ein so winziges Ergebnis erscheinen, aber der Wert all dieses Wrapper-Codes wird offensichtlicher, sobald wir beginnen, Eingabedateien zu lesen und mehrere Schritte miteinander zu verbinden. + +Davon abgesehen, lass uns auch die anderen Dateien in diesem Verzeichnis ansehen. Das sind Hilfs- und Logdateien, die Nextflow im Rahmen der Task-Ausführung erstellt hat. + +- **`.command.begin`**: Metadaten zum Beginn der Ausführung des Prozessaufrufs +- **`.command.err`**: Fehlermeldungen (`stderr`), die vom Prozessaufruf ausgegeben wurden +- **`.command.log`**: Vollständige Logausgabe, die vom Prozessaufruf ausgegeben wurde +- **`.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 sich aus dem Befehl ergab + +Die Datei `.command.sh` ist besonders nützlich, weil sie dir den Hauptbefehl zeigt, den Nextflow ausgeführt hat, ohne all die Buchhaltung und Task-/Umgebungseinrichtung. + +??? abstract "Dateiinhalt" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Dies entspricht dem, was wir zuvor manuell ausgeführt haben. + +In diesem Fall ist es sehr einfach, weil der Prozessbefehl fest eincodiert war, aber später im Kurs wirst du Prozessbefehle sehen, die eine gewisse 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 beheben möchtest. + +### 1.3. Den Workflow erneut ausführen + +Versuche, den Workflow ein paar Mal erneut auszuführen, und sieh dir dann die Task-Verzeichnisse unter `work/` an. + +??? abstract "Verzeichnisinhalt" + + ```console + 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 Logdateien erstellt wurde. +Dies zeigt dir, dass das mehrmalige Ausführen desselben Workflows die Ergebnisse vorheriger Läufe nicht überschreibt. + +### Zusammenfassung + +Du weißt, wie man ein einfaches Nextflow-Skript entschlüsselt, es ausführt und die Ausgabe sowie die relevanten Logdateien im work-Verzeichnis findet. + +### Was kommt als Nächstes? + +Lerne, wie du die Workflow-Ausgaben an einen bequemeren Ort veröffentlichen kannst. + +--- + +## 2. Ausgaben veröffentlichen + +Wie du gerade gelernt hast, ist die von unserer Pipeline erzeugte Ausgabe mehrere Ebenen tief in einem Arbeitsverzeichnis vergraben. +Dies geschieht absichtlich; Nextflow kontrolliert 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 mit [Workflow-Level-Output-Definitionen](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs) in ein bestimmtes Verzeichnis zu veröffentlichen. + +### 2.1. Grundlegende Verwendung + +Dies wird zwei neue Code-Elemente beinhalten: + +1. Einen `publish:`-Block innerhalb des `workflow`-Körpers, der Prozessausgaben deklariert. +2. Einen `output`-Block zum 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-Körper hinzufügen (dasselbe Code-Element wie der `main:`-Block) und die Ausgabe des `sayHello()`-Prozesses auflisten. + +Füge in der Workflow-Skriptdatei `hello-world.nf` die folgenden Codezeilen hinzu: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() + } + ``` + +Du siehst, dass wir uns auf die Ausgabe des Prozesses einfach mit `sayHello().out` beziehen und ihr einen beliebigen Namen `first_output` zuweisen können. + +#### 2.1.2. Einen `output:`-Block zum Skript hinzufügen + +Jetzt müssen wir nur noch den `output:`-Block hinzufügen, in dem der Pfad des Ausgabeverzeichnisses angegeben wird. Beachte, dass dieser neue Block **außerhalb** und **unterhalb** des `workflow`-Blocks innerhalb des Skripts sitzt. + +Füge in der Workflow-Skriptdatei `hello-world.nf` die folgenden Codezeilen hinzu: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Wir können dies verwenden, um allen im `workflow`-Block deklarierten Prozessausgaben spezifische Pfade zuzuweisen. +Später wirst du Möglichkeiten kennenlernen, ausgeklügelte Ausgabeverzeichnisstrukturen zu generieren, aber jetzt codieren wir der Einfachheit halber einen minimalen Pfad fest ein. + +#### 2.1.3. Den Workflow ausführen + +Führe jetzt das modifizierte Workflow-Skript aus: + +```bash +nextflow run hello-world.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +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. + +??? abstract "Verzeichnisinhalt" + + ```console hl_lines="10-11 22" + . + ├── 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 Verzeichnis `results` 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 das work-Unterverzeichnis durchsuchen zu müssen. + +### 2.2. Einen benutzerdefinierten Speicherort festlegen + +Ein Standardspeicherort ist großartig, aber du möchtest vielleicht anpassen, wo die Ergebnisse gespeichert werden und wie sie organisiert sind. + +Du möchtest zum Beispiel deine Ausgaben in Unterverzeichnisse organisieren. +Der einfachste Weg, das zu tun, ist, pro Ausgabe einen spezifischen Ausgabepfad zuzuweisen. + +#### 2.2.1. Den Ausgabepfad modifizieren + +Auch hier ist das Modifizieren des Veröffentlichungsverhaltens für eine bestimmte Ausgabe wirklich einfach. +Um einen benutzerdefinierten Speicherort festzulegen, bearbeite einfach den `path` entsprechend: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Da dies auf der Ebene der einzelnen Ausgabe festgelegt wird, kannst du verschiedene Speicherorte und Unterverzeichnisse entsprechend deinen Bedürfnissen angeben. + +#### 2.2.2. Den Workflow erneut ausführen + +Lass es uns ausprobieren. + +```bash +nextflow run hello-world.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Diesmal wird das Ergebnis in das angegebene Unterverzeichnis geschrieben. + +??? abstract "Verzeichnisinhalt" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Du siehst, dass das Ergebnis der vorherigen Ausführung immer noch da ist. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +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 Ausgabeverzeichnisses der obersten Ebene zu ändern (der durch die spezielle Variable `outputDir` gesteuert wird). +Wir werden diese Optionen in späteren Trainings 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, für die du nicht mehrere Kopien speichern möchtest. +Wenn du jedoch irgendwann das work-Verzeichnis löschst (wir werden Bereinigungsoperationen 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 mode-Direktive hinzufügen + +Dieser Teil ist wirklich einfach. +Füge einfach `mode 'copy'` zur relevanten Workflow-Level-Output-Definition hinzu: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Dies setzt den Veröffentlichungsmodus für diese spezifische Ausgabe. + +#### 2.3.2. Den Workflow erneut ausführen + +Lass es uns ausprobieren. + +```bash +nextflow run hello-world.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Diesmal, wenn du dir die Ergebnisse ansiehst, ist die Datei eine echte Kopie anstatt nur ein Symlink. + +??? abstract "Verzeichnisinhalt" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Da dies auch auf der Ebene der einzelnen Ausgabe festgelegt wird, kannst du den Veröffentlichungsmodus sehr granular festlegen. +Dies wird besonders praktisch sein, wenn wir zu mehrstufigen Pipelines übergehen, wo du vielleicht nur endgültige Ausgaben kopieren und Zwischenausgaben als Symlinks belassen möchtest. + +Wie bereits erwähnt, gibt es andere, ausgeklügeltere Optionen zur Steuerung, wie Ausgaben veröffentlicht werden. +Wir werden dir zeigen, wie du sie beim Arbeiten mit Nextflow verwendest. + +### 2.4. Hinweis zu `publishDir`-Direktiven auf Prozessebene + +Bis vor kurzem war die etablierte Methode, Ausgaben zu veröffentlichen, 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 Prozessdefinition hinzugefügt: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Du wirst dieses Codemuster immer noch überall in älteren Nextflow-Pipelines und Prozessmodulen finden, daher ist es wichtig, es zu kennen. +Wir empfehlen jedoch nicht, es in neuer Arbeit zu verwenden, da es in zukünftigen Versionen der Nextflow-Sprache eventuell nicht mehr erlaubt sein wird. + +### Zusammenfassung + +Du weißt, wie man Workflow-Ausgaben an einen bequemeren Ort veröffentlicht. + +### Was kommt als Nächstes? + +Lerne, wie du eine variable Eingabe über einen Befehlszeilenparameter bereitstellst und Standardwerte effektiv nutzt. + +--- + +## 3. Eine variable Eingabe verwenden, die über die Befehlszeile übergeben wird + +In seinem aktuellen Zustand verwendet unser Workflow eine in den Prozessbefehl fest eincodierte Begrüßung. +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: + +1. Den Prozess so ändern, dass er eine variable Eingabe erwartet +2. Einen Befehlszeilenparameter einrichten, um Benutzereingaben zu erfassen +3. Die Eingabe an den Prozess im Workflow-Körper übergeben + +Lass uns diese Änderungen nacheinander vornehmen. + +### 3.1. Den `sayHello`-Prozess ändern, um eine variable Eingabe zu erwarten + +Wir müssen die Prozessdefinition bearbeiten, um (1) eine Eingabevariable zu akzeptieren und (2) diese Variable in der Befehlszeile zu verwenden. + +#### 3.1.1. Einen input-Block zur Prozessdefinition hinzufügen + +Zuerst passen wir die Prozessdefinition an, um eine Eingabe namens `greeting` zu akzeptieren. + +Nimm im Prozessblock die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +Der Variable `greeting` wird `val` vorangestellt, 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 eincodierten Wert gegen den Wert der Eingabevariable aus, die wir erwarten zu erhalten. + +Nimm im Prozessblock die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +Das `$`-Symbol und die geschweiften Klammern (`{ }`) sagen Nextflow, dass dies ein Variablenname ist, der durch den tatsächlichen Eingabewert ersetzt werden muss (=interpoliert). + +!!! tip "Tipp" + + Die geschweiften Klammern (`{ }`) waren in früheren Versionen von Nextflow technisch optional, daher siehst du vielleicht ä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 Befehlszeilenparameter einrichten, um Benutzereingaben zu erfassen + +Wir könnten einfach eine Eingabe direkt fest eincodieren, indem wir den Prozessaufruf `sayHello('Hello World!')` machen. +Wenn wir jedoch echte Arbeit mit unserem Workflow erledigen, werden wir seine Eingaben von der Befehlszeile aus steuern wollen. + +Gute Nachricht: Nextflow hat ein eingebautes Workflow-Parameter-System namens `params`, das es einfach macht, CLI-Parameter zu deklarieren und zu verwenden. + +Die allgemeine Syntax ist, `params.<parameter_name>` zu deklarieren, um Nextflow mitzuteilen, dass es einen `--<parameter_name>`-Parameter auf der Befehlszeile erwartet. + +Hier wollen wir einen Parameter namens `--input` erstellen, also müssen wir irgendwo im Workflow `params.input` deklarieren. +Im Prinzip können wir es überall hinschreiben; aber da wir es dem `sayHello()`-Prozessaufruf geben wollen, können wir es dort direkt einfügen, indem wir `sayHello(params.input)` schreiben. + +Nimm im Workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // Eine Begrüßung ausgeben + sayHello(params.input) + ``` + +=== "Vorher" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // Eine Begrüßung ausgeben + sayHello() + ``` + +Dies sagt Nextflow, den `sayHello`-Prozess mit dem über den `--input`-Parameter bereitgestellten Wert auszuführen. + +Tatsächlich haben wir die oben skizzierten Schritte (2) und (3) in einem Zug erledigt. + +### 3.3. Den Workflow-Befehl ausführen + +Lass es uns ausführen! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Wenn du alle diese Änderungen richtig gemacht hast, solltest du eine weitere erfolgreiche Ausführung erhalten. + +Öffne unbedingt die Ausgabedatei, um zu überprüfen, dass du jetzt die neue Version der Begrüßung hast. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Beachte, dass 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. + +!!! tip "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 einzelnen Bindestrich (`-`). + +### 3.4. Standardwerte für Befehlszeilenparameter verwenden + +Ok, das war praktisch, aber in vielen Fällen ist es sinnvoll, 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 + +Lass uns dem `input`-Parameter einen Standardwert geben, indem wir ihn vor der Workflow-Definition deklarieren. + +```groovy title="hello-world.nf" linenums="20" +/* + * Pipeline-Parameter + */ +params { + input: String = 'Holà mundo!' +} +``` + +Wie du siehst, können wir den Typ der Eingabe angeben, die 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 "Info" + + In älteren Workflows siehst du vielleicht, 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. +So kannst du alle konfigurierbaren Parameter auf einen Blick leicht 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 Befehlszeile angeben zu müssen. + +```bash +nextflow run hello-world.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +Die Ausgabe wird an derselben Stelle wie zuvor sein, aber der Inhalt sollte mit dem neuen Text aktualisiert sein. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow hat den Standardwert des greeting-Parameters verwendet, um die Ausgabe zu erstellen. + +#### 3.4.3. Den Standardwert überschreiben + +Wenn du den Parameter auf der Befehlszeile angibst, überschreibt der CLI-Wert den Standardwert. + +Probiere es aus: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Auch hier solltest du die entsprechend aktualisierte Ausgabe in deinem results-Verzeichnis finden. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Hinweis" + + In Nextflow gibt es mehrere Stellen, an denen du Werte für Parameter angeben kannst. + Wenn derselbe Parameter an mehreren Stellen auf verschiedene Werte gesetzt wird, bestimmt Nextflow anhand der [hier](https://www.nextflow.io/docs/latest/config.html) beschriebenen Rangfolge, welcher Wert verwendet wird. + + Wir werden dies in Teil 6 (Konfiguration) ausführlicher behandeln. + +### Zusammenfassung + +Du weißt, wie man eine einfache variable Eingabe verwendet, die zur Laufzeit über einen Befehlszeilenparameter bereitgestellt wird, sowie wie man Standardwerte einrichtet, verwendet und überschreibt. + +### Was kommt als Nächstes? + +Lerne, wie du Ausführungen bequemer verwalten kannst. + +--- + +## 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 dein Leben einfacher machen 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. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. Einen Workflow mit `-resume` erneut starten + +Manchmal möchtest du eine Pipeline, die du bereits zuvor gestartet hast, erneut ausführen, 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, die bereits mit genau demselben Code, denselben Einstellungen und Eingaben ausgeführt wurden, übersprungen. +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: + +- 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 der Produktion ausführst und etwas schief geht, kannst du in vielen Fällen das Problem beheben und die Pipeline neu starten, und sie wird von der Fehlerstelle aus weiterlaufen, 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: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Die Konsolenausgabe sollte vertraut aussehen, aber es gibt eine Sache, die im Vergleich zu vorher ein wenig anders ist. + +Achte auf das `cached:`-Bit, das in der Prozessstatuszeile (Zeile 5) hinzugefügt wurde, was bedeutet, dass Nextflow erkannt hat, dass es diese Arbeit bereits erledigt hat und einfach das Ergebnis vom vorherigen erfolgreichen Lauf wiederverwendet hat. + +Du kannst auch sehen, dass der work-Unterverzeichnis-Hash derselbe ist wie beim vorherigen Lauf. +Nextflow zeigt buchstäblich auf die vorherige Ausführung und sagt "Das habe ich schon dort drüben gemacht." + +!!! tip "Tipp" + + Wenn du eine Pipeline mit `resume` erneut ausführst, überschreibt Nextflow keine Dateien, die außerhalb des work-Verzeichnisses von zuvor erfolgreich ausgeführten Ausführungen veröffentlicht wurden. + +### 4.2. Das Log vergangener Ausführungen inspizieren + +Ob du eine neue Pipeline entwickelst oder Pipelines in der Produktion ausführst, irgendwann musst du wahrscheinlich Informationen über vergangene Läufe nachschlagen. +So geht's. + +Immer wenn du einen Nextflow-Workflow startest, wird eine Zeile in eine Logdatei namens `history` geschrieben, unter einem versteckten Verzeichnis namens `.nextflow` im aktuellen Arbeitsverzeichnis. + +??? abstract "Dateiinhalt" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Diese Datei gibt dir den Zeitstempel, Laufnamen, Status, Revisions-ID, Session-ID und die vollständige Befehlszeile 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`. + +```bash +nextflow log +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Dies gibt den Inhalt der Logdatei im Terminal aus, ergänzt um eine Kopfzeile. + +Du wirst bemerken, dass sich die Session-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 Session-ID gleich. + +Nextflow verwendet die Session-ID, um Lauf-Caching-Informationen unter dem Verzeichnis `cache` zu gruppieren, das sich ebenfalls unter `.nextflow` befindet. + +### 4.3. Ältere work-Verzeichnisse löschen + +Während des Entwicklungsprozesses wirst du deine Entwurfs-Pipeline typischerweise sehr oft ausführen, was zur Ansammlung vieler Dateien in vielen Unterverzeichnissen 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](https://www.nextflow.io/docs/latest/reference/cli.html#clean), 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 aktuellsten erfolgreichen Lauf, bei dem du `-resume` nicht verwendet hast; in unserem Fall war der Laufname `golden_cantor`. + +Der Laufname ist die maschinengenerierte zweiteilige Zeichenkette, die in eckigen Klammern in der Konsolenausgabezeile `Launching (...)` angezeigt wird. +Du kannst auch das Nextflow-Log verwenden, um einen Lauf basierend auf seinem Zeitstempel und/oder seiner Befehlszeile nachzuschlagen. + +#### 4.3.2. Einen Probelauf durchführen + +Zuerst verwenden wir das Probelauf-Flag `-n`, um zu überprüfen, was bei dem Befehl gelöscht wird: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Befehlsausgabe" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +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 in der Ausgabe siehst, hast du entweder keinen gültigen Laufnamen angegeben oder es gibt keine vergangenen Läufe zu löschen. Stelle sicher, dass du `golden_cantor` im Beispielbefehl durch den entsprechenden letzten Laufnamen in deinem Log ersetzt. + +#### 4.3.3. Mit dem Löschen fortfahren + +Wenn die Ausgabe wie erwartet aussieht und du mit dem Löschen fortfahren möchtest, führe den Befehl mit dem `-f`-Flag anstelle von `-n` erneut aus: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Befehlsausgabe" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Die Ausgabe sollte ähnlich wie zuvor sein, aber jetzt mit 'Removed' anstelle von 'Would remove'. +Beachte, dass dies nicht die zweistelligen Unterverzeichnisse (wie `a3/` oben) entfernt, aber deren Inhalte leert. + +!!! warning "Warnung" + + Das Löschen von work-Unterverzeichnissen aus vergangenen Läufen entfernt sie aus dem Nextflow-Cache und löscht alle Ausgaben, die in diesen Verzeichnissen gespeichert waren. + Das bedeutet, dass Nextflows Fähigkeit, die Ausführung fortzusetzen, ohne die entsprechenden Prozesse erneut auszuführen, beeinträchtigt wird. + + Du bist verantwortlich für das Speichern aller Ausgaben, die dir wichtig sind oder auf die du dich verlassen willst! Das ist der Hauptgrund, warum wir den `copy`-Modus anstelle des `symlink`-Modus für die `publish`-Direktive bevorzugen. + +### Zusammenfassung + +Du weißt, wie man Ausgaben in ein bestimmtes Verzeichnis veröffentlicht, eine Pipeline erneut startet, ohne Schritte zu wiederholen, die bereits auf identische Weise ausgeführt wurden, und den `nextflow clean`-Befehl verwendet, um alte work-Verzeichnisse zu bereinigen. + +Allgemeiner gesagt, weißt du, wie man einen einfachen Nextflow-Workflow interpretiert, seine Ausführung verwaltet und Ausgaben abruft. + +### Was kommt als Nächstes? + +Mach eine kleine Pause, du hast sie dir verdient! + +Wenn du bereit bist, gehe zu [**Teil 2: Hello Channels**](./02_hello_channels.md), um zu lernen, wie du Channels verwendest, um Eingaben in deinen Workflow einzuspeisen, was es dir ermöglicht, Nextflows eingebaute Datenflussparallelisierung und andere leistungsstarke Funktionen zu nutzen. + +--- + +## Quiz + +<quiz> +Was sind die mindestens erforderlichen Komponenten eines Nextflow-Prozesses? +- [ ] Nur input- und output-Blöcke +- [x] Output- und script-Blöcke +- [ ] Input-, output- und script-Blöcke +- [ ] Nur ein script-Block + +Mehr erfahren: [1.1.1. Die process-Definition](#111-die-process-definition) +</quiz> + +<quiz> +Was ist der Zweck des output-Blocks in einem Prozess? +- [ ] Ergebnisse auf der Konsole ausgeben +- [ ] Dateien im work-Verzeichnis speichern +- [x] Erwartete Ausgaben des Prozesses deklarieren +- [ ] Umgebungsvariablen definieren + +Mehr erfahren: [1.1.1. Die process-Definition](#111-die-process-definition) +</quiz> + +<quiz> +Welcher Befehl wird verwendet, um einen Nextflow-Workflow auszuführen? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Welche Datei im work-Verzeichnis eines Tasks enthält den tatsächlich ausgeführten Befehl? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Mehr erfahren: [1.2.2. Die Ausgabe und Logs im `work`-Verzeichnis finden](#122-die-ausgabe-und-logs-im-work-verzeichnis-finden) +</quiz> + +<quiz> +Was macht das `-resume`-Flag? +- [ ] Startet den Workflow von Anfang an neu +- [ ] Pausiert den Workflow +- [x] Überspringt Prozesse, die bereits erfolgreich abgeschlossen wurden +- [ ] Erstellt ein Backup des Workflows + +Mehr erfahren: [4.1. Einen Workflow mit `-resume` erneut starten](#41-einen-workflow-mit--resume-erneut-starten) +</quiz> + +<quiz> +Was ist der Standardmodus für die Veröffentlichung von Workflow-Ausgaben? +- [ ] Dateien in das Ausgabeverzeichnis kopieren +- [x] Symbolische Links im Ausgabeverzeichnis erstellen +- [ ] Dateien in das Ausgabeverzeichnis verschieben +- [ ] Dateien im Ausgabeverzeichnis komprimieren + +Mehr erfahren: [2.3. Den Veröffentlichungsmodus auf Kopieren setzen](#23-den-veröffentlichungsmodus-auf-kopieren-setzen) +</quiz> + +<quiz> +Wie übergibst du einen Parameterwert an einen Nextflow-Workflow von der Befehlszeile? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +Mehr erfahren: [3.2. Einen Befehlszeilenparameter einrichten, um Benutzereingaben zu erfassen](#32-einen-befehlszeilenparameter-einrichten-um-benutzereingaben-zu-erfassen) +</quiz> + +<quiz> +Wie referenzierst du eine Variable innerhalb eines Nextflow-script-Blocks? +- [ ] Mit `%variable%`-Syntax +- [x] Mit `#!groovy ${variable}`-Syntax +- [ ] Mit `{{variable}}`-Syntax +- [ ] Mit `[variable]`-Syntax +</quiz> diff --git a/docs/de/docs/hello_nextflow/02_hello_channels.md b/docs/de/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..3b1614f049 --- /dev/null +++ b/docs/de/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Teil 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Siehe [die gesamte Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal. + +:green_book: Das Videotranskript ist [hier](./transcripts/02_hello_channels.md) verfügbar. +/// + +In Teil 1 dieses Kurses (Hello World) haben wir dir gezeigt, wie du einem process eine variable Eingabe übergibst, indem du die Eingabe direkt im process-Aufruf angibst: `sayHello(params.input)`. +Das war ein bewusst vereinfachter Ansatz. +In der Praxis hat dieser Ansatz wesentliche Einschränkungen; er funktioniert nämlich nur für sehr einfache Fälle, bei denen wir den process nur einmal mit einem einzelnen Wert ausführen möchten. +In den meisten realistischen Workflow-Anwendungsfällen wollen wir mehrere Werte verarbeiten (z.B. experimentelle Daten für mehrere Proben), daher brauchen wir einen ausgefeilteren Weg, um Eingaben zu handhaben. + +Dafür sind Nextflow **channels** da. +Channels sind Warteschlangen, die entwickelt wurden, um Eingaben effizient zu handhaben und sie von einem Schritt zum nächsten in mehrstufigen Workflows zu transportieren, während sie eingebaute Parallelität und viele zusätzliche Vorteile bieten. + +In diesem Teil des Kurses lernst du, wie du einen channel verwendest, um mehrere Eingaben aus verschiedenen Quellen zu handhaben. +Du lernst auch, **Operatoren** zu verwenden, um channel-Inhalte nach Bedarf zu transformieren. + +??? info "Wie du von diesem Abschnitt aus beginnen kannst" + + Dieser Abschnitt des Kurses setzt voraus, dass du Teil 1 des [Hello Nextflow](./index.md)-Kurses abgeschlossen hast, aber wenn du mit den dort behandelten Grundlagen vertraut bist, kannst du von hier aus starten, ohne etwas Besonderes tun zu müssen. + +--- + +## 0. Aufwärmübung: `hello-channels.nf` ausführen + +Wir werden das Workflow-Skript `hello-channels.nf` als Ausgangspunkt verwenden. +Es entspricht dem Skript, das durch das Durcharbeiten von Teil 1 dieses Trainingskurses erstellt wurde, außer dass wir das Ausgabeziel geändert haben: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Um sicherzustellen, dass alles funktioniert, führe das Skript einmal aus, bevor du Änderungen vornimmst: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Wie zuvor findest du die Ausgabedatei `output.txt` im Verzeichnis `results/hello_channels` (wie im `output`-Block des Workflow-Skripts oben angegeben). + +??? abstract "Verzeichnisinhalte" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Dateiinhalte" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Wenn das bei dir funktioniert hat, bist du bereit, etwas über channels zu lernen. + +--- + +## 1. Variable Eingaben explizit über einen channel bereitstellen + +Wir werden einen **channel** erstellen, um die variable Eingabe an den `sayHello()`-process zu übergeben, anstatt uns auf die implizite Handhabung zu verlassen, die gewisse Einschränkungen hat. + +### 1.1. Einen Eingabe-channel erstellen + +Es gibt verschiedene **channel factories**, die wir verwenden können, um einen channel einzurichten. +Um die Dinge vorerst einfach zu halten, werden wir die grundlegendste channel factory namens `channel.of` verwenden, die einen channel mit einem einzelnen Wert erstellt. +Funktional wird dies ähnlich sein wie zuvor, aber anstatt Nextflow einen channel implizit erstellen zu lassen, tun wir dies jetzt explizit. + +Dies ist die Codezeile, die wir verwenden werden: + +```console title="Syntax" +greeting_ch = channel.of('Hello Channels!') +``` + +Dies erstellt einen channel namens `greeting_ch` unter Verwendung der `channel.of()` channel factory, die einen einfachen queue channel einrichtet, und lädt den String `'Hello Channels!'` als Begrüßungswert. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Hinweis" + + Wir wechseln vorübergehend zurück zu fest codierten Strings, anstatt einen CLI-Parameter zu verwenden, um die Lesbarkeit zu verbessern. Wir werden zurück zu CLI-Parametern wechseln, sobald wir behandelt haben, was auf Ebene des channels passiert. + +Füge im workflow-Block den channel factory-Code hinzu: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello Channels!') + // Eine Begrüßung ausgeben + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Dies ist noch nicht funktionsfähig, da wir die Eingabe für den process-Aufruf noch nicht umgestellt haben. + +### 1.2. Den channel als Eingabe zum process-Aufruf hinzufügen + +Jetzt müssen wir unseren neu erstellten channel tatsächlich in den `sayHello()`-process-Aufruf einbinden und den CLI-Parameter ersetzen, den wir zuvor direkt bereitgestellt haben. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello Channels!') + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello Channels!') + // Eine Begrüßung ausgeben + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Dies sagt Nextflow, den `sayHello`-process auf den Inhalt des `greeting_ch`-channels auszuführen. + +Jetzt ist unser Workflow richtig funktionsfähig; es ist das explizite Äquivalent zum Schreiben von `sayHello('Hello Channels!')`. + +### 1.3. Den Workflow ausführen + +Lass ihn laufen! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Wenn du beide Änderungen korrekt vorgenommen hast, solltest du eine erfolgreiche Ausführung erhalten. +Du kannst das Ergebnisverzeichnis überprüfen, um dich zu vergewissern, dass das Ergebnis noch dasselbe ist wie zuvor. + +??? abstract "Dateiinhalte" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Wir haben also die Flexibilität unseres Workflows erhöht, während wir dasselbe Endergebnis erzielen. +Das mag so erscheinen, als würden wir mehr Code für keinen greifbaren Nutzen schreiben, aber der Wert wird deutlich, sobald wir anfangen, mehr Eingaben zu handhaben. + +Als Vorschau darauf schauen wir uns noch eine Sache an, bevor wir weitermachen: einen kleinen, aber praktischen Vorteil der Verwendung eines expliziten channels zur Verwaltung von Dateneingaben. + +### 1.4. `view()` verwenden, um channel-Inhalte zu inspizieren + +Nextflow channels sind so aufgebaut, dass wir mit Operatoren auf ihre Inhalte einwirken können, was wir später in diesem Kapitel ausführlich behandeln werden. + +Vorerst zeigen wir dir nur, wie du einen super einfachen Operator namens [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) verwendest, um die Inhalte eines channels zu inspizieren. +Du kannst `view()` als Debugging-Werkzeug betrachten, wie eine `print()`-Anweisung in Python oder deren Äquivalent in anderen Sprachen. + +Füge diese kleine Zeile zum workflow-Block hinzu: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello Channels!') + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello Channels!') + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Die genaue Anzahl der Leerzeichen spielt keine Rolle, solange es ein Vielfaches von 4 ist; wir zielen nur darauf ab, den Anfang der `.view()`-Anweisung mit dem `.of()`-Teil der channel-Konstruktion auszurichten. + +Führe jetzt den Workflow erneut aus: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Wie du sehen kannst, gibt dies die channel-Inhalte in der Konsole aus. +Hier haben wir nur ein Element, aber wenn wir im nächsten Abschnitt anfangen, mehrere Werte in den channel zu laden, wirst du sehen, dass dies so eingestellt ist, dass ein Element pro Zeile ausgegeben wird. + +### Zusammenfassung + +Du weißt, wie du eine grundlegende channel factory verwendest, um eine Eingabe an einen process zu übergeben. + +### Was kommt als Nächstes? + +Lerne, wie du channels verwendest, damit der Workflow über mehrere Eingabewerte iteriert. + +--- + +## 2. Den Workflow so modifizieren, dass er mit mehreren Eingabewerten läuft + +Workflows werden typischerweise auf Stapel von Eingaben ausgeführt, die in großen Mengen verarbeitet werden sollen, daher wollen wir den Workflow aufrüsten, um mehrere Eingabewerte zu akzeptieren. + +### 2.1. Mehrere Begrüßungen in den Eingabe-channel laden + +Praktischerweise ist die `channel.of()` channel factory, die wir verwendet haben, durchaus bereit, mehr als einen Wert zu akzeptieren, daher müssen wir das überhaupt nicht ändern. +Wir können einfach mehrere Werte in den channel laden. + +Machen wir sie zu `'Hello'`, `'Bonjour'` und `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Im Diagramm wird der channel in Grün dargestellt, und die Reihenfolge der Elemente wird wie Murmeln in einer Röhre dargestellt: das zuerst geladene ist rechts, dann das zweite in der Mitte, dann das dritte links._ + +#### 2.1.1. Weitere Begrüßungen hinzufügen + +Nimm vor dem workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + +```groovy title="hello-channels.nf" linenums="30" hl_lines="2" +// Einen Channel für Eingaben erstellen +greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() +``` + +=== "Vorher" + +```groovy title="hello-channels.nf" linenums="30" hl_lines="2" +// Einen Channel für Eingaben erstellen +greeting_ch = channel.of('Hello Channels') + .view() +``` + +Die Dokumentation sagt uns, dass das funktionieren sollte. Kann es wirklich so einfach sein? + +#### 2.1.2. Den Befehl ausführen und die Log-Ausgabe betrachten + +Lass uns es versuchen. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Es scheint tatsächlich gut gelaufen zu sein. +Der Ausführungsmonitor zeigt, dass `3 von 3` Aufrufe für den `sayHello`-process gemacht wurden, und wir sehen die drei Begrüßungen, die durch die `view()`-Anweisung aufgelistet werden, eine pro Zeile wie versprochen. + +Allerdings gibt es im Ergebnisverzeichnis immer noch nur eine Ausgabe: + +??? abstract "Verzeichnisinhalte" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Dateiinhalte" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Du solltest eine der drei Begrüßungen darin sehen, aber die, die du bekommen hast, könnte anders sein als hier gezeigt. +Kannst du dir vorstellen, warum das so sein könnte? + +Wenn wir zurück auf den Ausführungsmonitor schauen, hat er uns nur einen Unterverzeichnispfad gegeben (`f4/c9962c`). +Lass uns dort hineinschauen. + +??? abstract "Verzeichnisinhalte" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Dateiinhalte" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +Das ist nicht einmal dieselbe Begrüßung, die wir im Ergebnisverzeichnis bekommen haben! Was geht hier vor? + +An diesem Punkt müssen wir dir sagen, dass das ANSI-Logging-System standardmäßig das Logging von mehreren Aufrufen desselben process auf derselben Zeile schreibt. +Also landen die Statusmeldungen von allen drei Aufrufen des sayHello()-process an derselben Stelle. + +Glücklicherweise können wir dieses Verhalten deaktivieren, um die vollständige Liste der process-Aufrufe zu sehen. + +#### 2.1.3. Den Befehl erneut mit der Option `-ansi-log false` ausführen + +Um das Logging zu erweitern und eine Zeile pro process-Aufruf anzuzeigen, füge `-ansi-log false` zum Befehl hinzu. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Diesmal sehen wir alle drei process-Ausführungen und ihre zugehörigen work-Unterverzeichnisse in der Ausgabe aufgelistet. + +Das ist viel besser, zumindest für einen einfachen Workflow. +Für einen komplexen Workflow oder eine große Anzahl von Eingaben würde die vollständige Liste, die im Terminal ausgegeben wird, etwas überwältigend werden. +Deshalb ist `-ansi-log false` nicht das Standardverhalten. + +!!! tip "Tipp" + + Die Art und Weise, wie der Status gemeldet wird, ist zwischen den beiden Logging-Modi etwas unterschiedlich. + Im komprimierten Modus meldet Nextflow, ob Aufrufe erfolgreich abgeschlossen wurden oder nicht. + In diesem erweiterten Modus wird nur gemeldet, dass sie eingereicht wurden. + +Wie auch immer, jetzt da wir die Unterverzeichnisse jedes process-Aufrufs haben, können wir nach ihren Logs und Ausgaben suchen. + +??? abstract "Verzeichnisinhalte" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Dateiinhalte" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Dies zeigt, dass alle drei processes erfolgreich ausgeführt wurden (juhu). + +Allerdings haben wir immer noch das Problem, dass es nur eine Ausgabedatei im Ergebnisverzeichnis gibt. + +Du erinnerst dich vielleicht, dass wir den Ausgabedateinamen für den `sayHello`-process fest codiert haben, sodass alle drei Aufrufe eine Datei namens `output.txt` produziert haben. + +Solange die Ausgabedateien in den work-Unterverzeichnissen bleiben, isoliert von den anderen processes, ist das in Ordnung. +Aber wenn sie in dasselbe Ergebnisverzeichnis veröffentlicht werden, wird die, die zuerst dort kopiert wurde, von der nächsten überschrieben, und so weiter. + +### 2.2. Sicherstellen, dass die Ausgabedateinamen eindeutig sind + +Wir können weiterhin alle Ausgaben in dasselbe Ergebnisverzeichnis veröffentlichen, aber wir müssen sicherstellen, dass sie eindeutige Namen haben werden. +Genauer gesagt müssen wir den ersten process so modifizieren, dass er einen Dateinamen dynamisch generiert, sodass die endgültigen Dateinamen eindeutig sein werden. + +Wie machen wir also die Dateinamen eindeutig? +Ein gängiger Weg, das zu tun, ist, ein eindeutiges Stück Metadaten aus den Eingaben (die vom Eingabe-channel empfangen wurden) als Teil des Ausgabedateinamens zu verwenden. +Hier werden wir der Einfachheit halber nur die Begrüßung selbst verwenden, da sie nur ein kurzer String ist, und sie dem Basis-Ausgabedateinamen voranstellen. + +#### 2.2.1. Einen dynamischen Ausgabedateinamen konstruieren + +Nimm im process-Block die folgenden Codeänderungen vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Stelle sicher, dass du `output.txt` sowohl in der Ausgabedefinition als auch im `script:`-Befehlsblock ersetzt. + +!!! tip "Tipp" + + In der Ausgabedefinition MUSST du doppelte Anführungszeichen um den Ausgabedateinamensausdruck verwenden (NICHT einfache Anführungszeichen), sonst schlägt es fehl. + +Dies sollte jedes Mal einen eindeutigen Ausgabedateinamen produzieren, wenn der process aufgerufen wird, sodass er von den Ausgaben anderer Aufrufe desselben process im Ausgabeverzeichnis unterschieden werden kann. + +#### 2.2.2. Den Workflow ausführen + +Lass ihn laufen. Beachte, dass wir wieder mit den Standard-ANSI-Log-Einstellungen ausführen. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Zurück in der Zusammenfassungsansicht wird die Ausgabe wieder auf einer Zeile zusammengefasst. +Schau in das `results`-Verzeichnis, um zu sehen, ob alle Ausgabebegrüßungen da sind. + +??? abstract "Verzeichnisinhalte" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Ja! Und sie haben jeweils die erwarteten Inhalte. + +??? abstract "Dateiinhalte" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Erfolg! Jetzt können wir so viele Begrüßungen hinzufügen, wie wir möchten, ohne uns Sorgen zu machen, dass Ausgabedateien überschrieben werden. + +!!! tip "Tipp" + + In der Praxis ist das Benennen von Dateien basierend auf den Eingabedaten selbst fast immer unpraktisch. + Der bessere Weg, dynamische Dateinamen zu generieren, ist, Metadaten zusammen mit den Eingabedateien an einen process zu übergeben. + Die Metadaten werden typischerweise über ein 'Sample Sheet' oder Äquivalente bereitgestellt. + Du wirst später in deinem Nextflow-Training lernen, wie du das machst (siehe [Metadaten-Side Quest](../side_quests/metadata.md)). + +### Zusammenfassung + +Du weißt, wie du mehrere Eingabeelemente durch einen channel führst. + +### Was kommt als Nächstes? + +Lerne, einen Operator zu verwenden, um die Inhalte eines channels zu transformieren. + +--- + +## 3. Mehrere Eingaben über ein Array bereitstellen + +Wir haben dir gerade gezeigt, wie du mehrere Eingabeelemente handhabst, die direkt in der channel factory fest codiert waren. +Was ist, wenn wir diese mehreren Eingaben auf eine andere Weise bereitstellen wollten? + +Stell dir zum Beispiel vor, wir richten eine Eingabevariable ein, die ein Array von Elementen enthält wie dieses: + +`greetings_array = ['Hello','Bonjour','Holà']` + +Können wir das in unseren Ausgabe-channel laden und erwarten, dass es funktioniert? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Lass uns das herausfinden. + +### 3.1. Ein Array von Werten als Eingabe für den channel bereitstellen + +Der gesunde Menschenverstand legt nahe, dass wir einfach ein Array von Werten anstelle eines einzelnen Wertes übergeben können sollten. +Lass uns es versuchen; wir müssen die Eingabevariable einrichten und sie in die channel factory laden. + +#### 3.1.1. Die Eingabevariable einrichten + +Lass uns die `greetings_array`-Variable, die wir uns gerade vorgestellt haben, Realität werden lassen, indem wir sie zum workflow-Block hinzufügen: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Dies ist noch nicht funktionsfähig, wir haben nur eine Deklaration für das Array hinzugefügt. + +#### 3.1.2. Das Array von Begrüßungen als Eingabe für die channel factory setzen + +Jetzt werden wir die Werte `'Hello','Bonjour','Holà'`, die derzeit in der channel factory fest codiert sind, durch das `greetings_array` ersetzen, das wir gerade erstellt haben. + +Nimm im workflow-Block die folgende Änderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Dies sollte jetzt funktionsfähig sein. + +#### 3.1.3. Den Workflow ausführen + +Lass uns versuchen, ihn auszuführen: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Befehlsausgabe" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +Oh nein! Es gibt einen Fehler! + +Schau dir die Ausgabe von `view()` und die Fehlermeldungen an. + +Es sieht so aus, als hätte Nextflow versucht, einen einzelnen process-Aufruf auszuführen, wobei `[Hello, Bonjour, Holà]` als Stringwert verwendet wurde, anstatt die drei Strings im Array als separate Werte zu verwenden. + +Es ist also die 'Verpackung', die das Problem verursacht. +Wie bringen wir Nextflow dazu, das Array zu entpacken und die einzelnen Strings in den channel zu laden? + +### 3.2. Einen Operator verwenden, um channel-Inhalte zu transformieren + +Hier kommen **[Operatoren](https://www.nextflow.io/docs/latest/reference/operator.html)** ins Spiel. +Du hast bereits den `.view()`-Operator verwendet, der nur hineinschaut, was drin ist. +Jetzt werden wir uns Operatoren ansehen, die es uns ermöglichen, auf die Inhalte eines channels einzuwirken. + +Wenn du durch die [Liste der Operatoren](https://www.nextflow.io/docs/latest/reference/operator.html) in der Nextflow-Dokumentation blätterst, wirst du [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten) finden, das genau das tut, was wir brauchen: den Inhalt eines Arrays entpacken und sie als einzelne Elemente ausgeben. + +#### 3.2.1. Den `flatten()`-Operator hinzufügen + +Um den `flatten()`-Operator auf unseren Eingabe-channel anzuwenden, hängen wir ihn an die channel factory-Deklaration an. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Hier haben wir den Operator für die Lesbarkeit in der nächsten Zeile hinzugefügt, aber du kannst Operatoren auch auf derselben Zeile wie die channel factory hinzufügen, wenn du möchtest, so: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Die `view()`-Anweisung(en) verfeinern + +Wir könnten dies jetzt sofort ausführen, um zu testen, ob es funktioniert, aber während wir dabei sind, werden wir verfeinern, wie wir die channel-Inhalte inspizieren. + +Wir wollen den Inhalt vor und nach der Anwendung des `flatten()`-Operators vergleichen können, also werden wir ein zweites hinzufügen, UND wir werden etwas Code hinzufügen, um sie in der Ausgabe deutlicher zu beschriften. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Du siehst, wir haben eine zweite `.view`-Anweisung hinzugefügt, und für jede von ihnen haben wir die leeren Klammern (`()`) durch geschweifte Klammern mit etwas Code ersetzt, wie `{ greeting -> "Before flatten: $greeting" }`. + +Diese werden _closures_ genannt. Der Code, den sie enthalten, wird für jedes Element im channel ausgeführt. +Wir definieren eine temporäre Variable für den inneren Wert, hier `greeting` genannt (aber es könnte ein beliebiger Name sein), die nur innerhalb des Gültigkeitsbereichs dieser closure verwendet wird. + +In diesem Beispiel repräsentiert `$greeting` jedes einzelne Element, das in den channel geladen wurde. +Dies führt zu sauber beschrifteter Konsolenausgabe. + +!!! info + + In einigen Pipelines siehst du möglicherweise eine spezielle Variable namens `$it`, die innerhalb von Operator-closures verwendet wird. + Dies ist eine _implizite_ Variable, die einen Kurzform-Zugriff auf die innere Variable ermöglicht, + ohne sie mit einem `->` definieren zu müssen. + + Wir bevorzugen die explizite Form, um die Klarheit des Codes zu unterstützen. Die `$it`-Syntax wird nicht empfohlen und wird langsam aus der Nextflow-Sprache auslaufen. + +#### 3.2.3. Den Workflow ausführen + +Schließlich kannst du versuchen, den Workflow erneut auszuführen! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Diesmal funktioniert es UND gibt uns den zusätzlichen Einblick, wie die Inhalte des channels vor und nach der Ausführung des `flatten()`-Operators aussehen. + +- Du siehst, dass wir eine einzelne `Before flatten:`-Anweisung bekommen, weil zu diesem Zeitpunkt der channel ein Element enthält, das ursprüngliche Array. + Dann bekommen wir drei separate `After flatten:`-Anweisungen, eine für jede Begrüßung, die jetzt einzelne Elemente im channel sind. + +Wichtig ist, dass dies bedeutet, dass jedes Element jetzt separat vom Workflow verarbeitet werden kann. + +!!! tip "Tipp" + + Es ist technisch möglich, dieselben Ergebnisse zu erzielen, indem man eine andere channel factory verwendet, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), die einen impliziten Mapping-Schritt in ihrer Operation enthält. + Hier haben wir uns entschieden, das nicht zu verwenden, um die Verwendung eines Operators an einem einfachen Anwendungsfall zu demonstrieren. + +### Zusammenfassung + +Du weißt, wie du einen Operator wie `flatten()` verwendest, um die Inhalte eines channels zu transformieren, und wie du den `view()`-Operator verwendest, um channel-Inhalte vor und nach der Anwendung eines Operators zu inspizieren. + +### Was kommt als Nächstes? + +Lerne, wie du den Workflow so einrichtest, dass er eine Datei als Quelle von Eingabewerten verwendet. + +--- + +## 4. Eingabewerte aus einer CSV-Datei lesen + +Realistischerweise werden wir selten, wenn überhaupt, von einem Array von Werten ausgehen. +Höchstwahrscheinlich haben wir eine oder mehrere Dateien, die die zu verarbeitenden Daten enthalten, in irgendeiner Art von strukturiertem Format. + +Wir haben eine CSV-Datei namens `greetings.csv` vorbereitet, die mehrere Eingabebegrüßungen enthält und die Art von tabellarischen Daten nachahmt, die du in einer echten Datenanalyse verarbeiten möchtest, gespeichert unter `data/`. +(Die Zahlen sind nicht bedeutsam, sie sind nur zu Illustrationszwecken da.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Unsere nächste Aufgabe ist es, unseren Workflow anzupassen, um die Werte aus dieser Datei einzulesen. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Lass uns sehen, wie wir das bewerkstelligen können. + +### 4.1. Das Skript so modifizieren, dass es eine CSV-Datei als Quelle von Begrüßungen erwartet + +Um loszulegen, müssen wir zwei wichtige Änderungen am Skript vornehmen: + +- Den Eingabeparameter so umstellen, dass er auf die CSV-Datei zeigt +- Die channel factory auf eine umstellen, die für das Handhaben einer Datei ausgelegt ist + +#### 4.1.1. Den Eingabeparameter so umstellen, dass er auf die CSV-Datei zeigt + +Erinnerst du dich an den `params.input`-Parameter, den wir in Teil 1 eingerichtet haben? +Wir werden ihn aktualisieren, um auf die CSV-Datei zu zeigen, die unsere Begrüßungen enthält. + +Nimm die folgende Änderung an der Parameterdeklaration vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline-Parameter + */ + input: String = 'Holà mundo!' + ``` + +Dies setzt voraus, dass die Datei am selben Ort wie der Workflow-Code liegt. +Wie du mit anderen Datenspeicherorten umgehst, lernst du in späteren Kursen. + +#### 4.1.2. Zu einer channel factory wechseln, die für das Handhaben einer Datei ausgelegt ist + +Da wir jetzt eine Datei anstelle von einfachen Strings als Eingabe verwenden wollen, können wir die `channel.of()` channel factory von vorher nicht verwenden. +Wir müssen zu einer neuen channel factory wechseln, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), die einige eingebaute Funktionalitäten für das Handhaben von Dateipfaden hat. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // Ein Array von Eingabe-Begrüßungen deklarieren + greetings_array = ['Hello','Bonjour','Holà'] + // Einen Channel für Eingaben erstellen + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Du wirst bemerken, dass wir die channel-Eingabe zurück zu `param.input` gewechselt und die `greetings_array`-Deklaration gelöscht haben, da wir sie nicht mehr brauchen werden. +Wir haben auch `flatten()` und die zweite `view()`-Anweisung auskommentiert. + +#### 4.1.3. Den Workflow ausführen + +Lass uns versuchen, den Workflow mit der neuen channel factory und der Eingabedatei auszuführen. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Befehlsausgabe" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Oh nein, es funktioniert nicht. Schau dir den Anfang der Konsolenausgabe und die Fehlermeldung an. +Der Teil `Command executed:` ist hier besonders hilfreich. + +Das sieht vielleicht ein bisschen vertraut aus. +Es sieht so aus, als hätte Nextflow versucht, einen einzelnen process-Aufruf auszuführen, wobei der Dateipfad selbst als Stringwert verwendet wurde. +Also hat es den Dateipfad korrekt aufgelöst, aber es hat nicht wirklich seinen Inhalt geparst, was wir wollten. + +Wie bringen wir Nextflow dazu, die Datei zu öffnen und ihren Inhalt in den channel zu laden? + +Klingt so, als bräuchten wir einen weiteren [Operator](https://www.nextflow.io/docs/latest/reference/operator.html)! + +### 4.2. Den `splitCsv()`-Operator verwenden, um die Datei zu parsen + +Wenn wir wieder durch die Liste der Operatoren schauen, finden wir [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), das dafür ausgelegt ist, CSV-formatierten Text zu parsen und zu teilen. + +#### 4.2.1. `splitCsv()` auf den channel anwenden + +Um den Operator anzuwenden, hängen wir ihn wie zuvor an die channel factory-Zeile an. + +Nimm im workflow-Block die folgende Codeänderung vor, um `flatten()` durch `splitcsv()` zu ersetzen (nicht auskommentiert): + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Wie du sehen kannst, haben wir auch die vorher/nachher `view()`-Anweisungen aktualisiert. +Technisch hätten wir denselben Variablennamen (`greeting`) verwenden können, aber wir haben ihn auf etwas Passenderes (`csv`) aktualisiert, um den Code für andere lesbarer zu machen. + +#### 4.2.2. Den Workflow erneut ausführen + +Lass uns versuchen, den Workflow mit der hinzugefügten CSV-Parsing-Logik auszuführen. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Befehlsausgabe" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Interessanterweise schlägt dies auch fehl, aber mit einem anderen Fehler. +Diesmal hat Nextflow den Inhalt der Datei geparst (juhu!), aber es hat jede Zeile als Array geladen, und jedes Array ist ein Element im channel. + +Wir müssen ihm sagen, dass es nur die erste Spalte in jeder Zeile nehmen soll. +Wie entpacken wir das also? + +Wir haben zuvor `flatten()` verwendet, um die Inhalte eines channels zu entpacken, aber das würde hier nicht funktionieren, weil flatten _alles_ entpackt (versuche es gerne, wenn du es selbst sehen möchtest). + +Stattdessen werden wir einen anderen Operator namens `map()` verwenden, der wirklich nützlich ist und in Nextflow-Pipelines häufig vorkommt. + +### 4.3. Den `map()`-Operator verwenden, um die Begrüßungen zu extrahieren + +Der [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map)-Operator ist ein sehr praktisches kleines Werkzeug, das es uns ermöglicht, alle Arten von Mappings auf die Inhalte eines channels durchzuführen. + +In diesem Fall werden wir ihn verwenden, um das eine Element zu extrahieren, das wir aus jeder Zeile in unserer Datendatei wollen. +So sieht die Syntax aus: + +```groovy title="Syntax" +.map { row -> row[0] } +``` + +Das bedeutet 'für jede Zeile im channel, nimm das 0. (erste) Element, das sie enthält'. + +Also wenden wir das auf unser CSV-Parsing an. + +#### 4.3.1. `map()` auf den channel anwenden + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Du siehst, wir haben einen weiteren `view()`-Aufruf hinzugefügt, um zu bestätigen, dass der Operator das tut, was wir erwarten. + +#### 4.3.2. Den Workflow ausführen + +Lass uns das noch einmal ausführen: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Diesmal sollte es ohne Fehler laufen. + +Wenn du dir die Ausgabe der `view()`-Anweisungen anschaust, siehst du Folgendes: + +- Eine einzelne `Before splitCsv:`-Anweisung: zu diesem Zeitpunkt enthält der channel ein Element, den ursprünglichen Dateipfad. +- Drei separate `After splitCsv:`-Anweisungen: eine für jede Begrüßung, aber jede ist in einem Array enthalten, das dieser Zeile in der Datei entspricht. +- Drei separate `After map:`-Anweisungen: eine für jede Begrüßung, die jetzt einzelne Elemente im channel sind. + +Beachte, dass die Zeilen in deiner Ausgabe in einer anderen Reihenfolge erscheinen können. + +Du kannst auch die Ausgabedateien ansehen, um zu überprüfen, dass jede Begrüßung korrekt extrahiert und durch den Workflow verarbeitet wurde. + +Wir haben dasselbe Ergebnis wie zuvor erzielt, aber jetzt haben wir viel mehr Flexibilität, um weitere Elemente zum channel von Begrüßungen hinzuzufügen, die wir verarbeiten möchten, indem wir eine Eingabedatei modifizieren, ohne Code zu ändern. +Du wirst in einem späteren Training anspruchsvollere Ansätze für das Handhaben komplexer Eingaben lernen. + +### Zusammenfassung + +Du weißt, wie du den `.fromPath()` channel-Konstruktor und die Operatoren `splitCsv()` und `map()` verwendest, um eine Datei mit Eingabewerten einzulesen und sie angemessen zu handhaben. + +Allgemeiner hast du ein grundlegendes Verständnis davon, wie Nextflow **channels** verwendet, um Eingaben für processes zu verwalten, und **Operatoren**, um ihre Inhalte zu transformieren. + +### Was kommt als Nächstes? + +Mach eine große Pause, du hast in diesem Teil hart gearbeitet! + +Wenn du bereit bist, gehe zu [**Teil 3: Hallo Workflow**](./03_hello_workflow.md), um zu lernen, wie du weitere Schritte hinzufügst und sie zu einem richtigen Workflow verbindest. + +--- + +## Quiz + +<quiz> +Was ist ein channel in Nextflow? +- [ ] Eine Dateipfadspezifikation +- [ ] Eine process-Definition +- [x] Eine warteschlangenartige Struktur zum Übergeben von Daten zwischen processes +- [ ] Eine Konfigurationseinstellung + +Mehr erfahren: [1.1. Einen Eingabe-channel erstellen](#11-einen-eingabe-channel-erstellen) +</quiz> + +<quiz> +Was wird dieser Code ausgeben? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (eine einzelne Liste) +- [x] Jedes Element in einer separaten Zeile: `Hello`, `Bonjour`, `Hola` +- [ ] Nichts (channels drucken standardmäßig nicht) +- [ ] Einen Fehler (ungültige Syntax) + +Mehr erfahren: [1.1. Einen Eingabe-channel erstellen](#11-einen-eingabe-channel-erstellen) +</quiz> + +<quiz> +Wenn ein channel mehrere Werte enthält, wie handhabt Nextflow die process-Ausführung? +- [ ] Der process läuft einmal mit allen Werten +- [x] Der process läuft einmal für jeden Wert im channel +- [ ] Der process läuft nur mit dem ersten Wert +- [ ] Der process läuft nur mit dem letzten Wert + +Mehr erfahren: [2. Den Workflow so modifizieren, dass er mit mehreren Eingabewerten läuft](#2-den-workflow-so-modifizieren-dass-er-mit-mehreren-eingabewerten-lauft) +</quiz> + +<quiz> +Was macht der `flatten()`-Operator? +- [ ] Kombiniert mehrere channels zu einem +- [ ] Sortiert channel-Elemente +- [x] Entpackt Arrays in einzelne Elemente +- [ ] Entfernt doppelte Elemente + +Mehr erfahren: [3.2.1. Den `flatten()`-Operator hinzufügen](#321-den-flatten-operator-hinzufugen) +</quiz> + +<quiz> +Was ist der Zweck des `view()`-Operators? +- [ ] Channel-Inhalte zu filtern +- [ ] Channel-Elemente zu transformieren +- [x] Channel-Inhalte zu inspizieren und zu debuggen +- [ ] Channel-Inhalte in eine Datei zu speichern + +Mehr erfahren: [1.4. `view()` verwenden, um channel-Inhalte zu inspizieren](#14-view-verwenden-um-channel-inhalte-zu-inspizieren) +</quiz> + +<quiz> +Was macht `splitCsv()`? +- [ ] Erstellt eine CSV-Datei aus channel-Inhalten +- [ ] Teilt einen String durch Kommas +- [x] Parst eine CSV-Datei in Arrays, die jede Zeile repräsentieren +- [ ] Führt mehrere CSV-Dateien zusammen + +Mehr erfahren: [4.2. Den `splitCsv()`-Operator verwenden, um die Datei zu parsen](#42-den-splitcsv-operator-verwenden-um-die-datei-zu-parsen) +</quiz> + +<quiz> +Was ist der Zweck des `map()`-Operators? +- [ ] Elemente aus einem channel zu filtern +- [ ] Mehrere channels zu kombinieren +- [x] Jedes Element in einem channel zu transformieren +- [ ] Elemente in einem channel zu zählen + +Mehr erfahren: [4.3. Den `map()`-Operator verwenden, um die Begrüßungen zu extrahieren](#43-den-map-operator-verwenden-um-die-begrussungen-zu-extrahieren) +</quiz> + +<quiz> +Warum ist es wichtig, dynamische Ausgabedateinamen zu verwenden, wenn mehrere Eingaben verarbeitet werden? +- [ ] Um die Leistung zu verbessern +- [ ] Um Speicherplatz zu reduzieren +- [x] Um zu verhindern, dass sich Ausgabedateien gegenseitig überschreiben +- [ ] Um die resume-Funktionalität zu aktivieren + +Mehr erfahren: [2.2. Sicherstellen, dass die Ausgabedateinamen eindeutig sind](#22-sicherstellen-dass-die-ausgabedateinamen-eindeutig-sind) +</quiz> diff --git a/docs/de/docs/hello_nextflow/03_hello_workflow.md b/docs/de/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..f0ccb18955 --- /dev/null +++ b/docs/de/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Teil 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Siehe [die gesamte Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal. + +:green_book: Das Videotranskript ist [hier](./transcripts/03_hello_workflow.md) verfügbar. +/// + +Die meisten realen Workflows umfassen mehr als einen Schritt. +In diesem Trainingsmodul lernst du, wie du processes in einem mehrstufigen Workflow verbindest. + +Dies wird dir den Nextflow-Weg beibringen, um Folgendes zu erreichen: + +1. Daten von einem process zum nächsten fließen lassen +2. Ausgaben von mehreren process-Aufrufen in einen einzelnen process-Aufruf sammeln +3. Mehr als eine Eingabe an einen process übergeben +4. Mehrere Ausgaben aus einem process handhaben + +Zur Demonstration werden wir weiterhin auf dem domänenunabhängigen Hello World-Beispiel aus den Teilen 1 und 2 aufbauen. +Diesmal werden wir die folgenden Änderungen an unserem Workflow vornehmen, um besser widerzuspiegeln, wie Leute tatsächliche Workflows erstellen: + +1. Einen zweiten Schritt hinzufügen, der die Begrüßung in Großbuchstaben umwandelt. +2. Einen dritten Schritt hinzufügen, der alle transformierten Begrüßungen sammelt und sie in eine einzelne Datei schreibt. +3. Einen Parameter hinzufügen, um die endgültige Ausgabedatei zu benennen, und diesen als sekundäre Eingabe an den Sammelschritt übergeben. +4. Den Sammelschritt auch eine einfache Statistik über das Verarbeitete berichten lassen. + +??? info "Wie du von diesem Abschnitt aus beginnen kannst" + + Dieser Abschnitt des Kurses setzt voraus, dass du die Teile 1-2 des [Hello Nextflow](./index.md)-Kurses abgeschlossen hast, aber wenn du mit den dort behandelten Grundlagen vertraut bist, kannst du von hier aus starten, ohne etwas Besonderes tun zu müssen. + +--- + +## 0. Aufwärmübung: `hello-workflow.nf` ausführen + +Wir werden das Workflow-Skript `hello-workflow.nf` als Ausgangspunkt verwenden. +Es entspricht dem Skript, das durch das Durcharbeiten von Teil 2 dieses Trainingskurses erstellt wurde, außer dass wir die `view()`-Anweisungen entfernt und das Ausgabeziel geändert haben: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Um sicherzustellen, dass alles funktioniert, führe das Skript einmal aus, bevor du Änderungen vornimmst: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Wie zuvor findest du die Ausgabedateien an dem im `output`-Block angegebenen Ort. +Für dieses Kapitel ist es unter `results/hello_workflow/`. + +??? abstract "Verzeichnisinhalte" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Wenn das bei dir funktioniert hat, bist du bereit zu lernen, wie man einen mehrstufigen Workflow zusammenstellt. + +--- + +## 1. Einen zweiten Schritt zum Workflow hinzufügen + +Wir werden einen Schritt hinzufügen, um jede Begrüßung in Großbuchstaben umzuwandeln. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +Dazu müssen wir drei Dinge tun: + +- Den Befehl definieren, den wir für die Großbuchstaben-Umwandlung verwenden werden. +- Einen neuen process schreiben, der den Großbuchstaben-Befehl umhüllt. +- Den neuen process im workflow-Block aufrufen und so einrichten, dass er die Ausgabe des `sayHello()`-process als Eingabe nimmt. + +### 1.1. Den Großbuchstaben-Befehl definieren und im Terminal testen + +Für die Umwandlung der Begrüßungen in Großbuchstaben werden wir ein klassisches UNIX-Tool namens `tr` für 'text replacement' verwenden, mit der folgenden Syntax: + +```bash title="Syntax" +tr '[a-z]' '[A-Z]' +``` + +Dies ist ein sehr naiver Textersetzungs-Einzeiler, der keine akzentuierten Buchstaben berücksichtigt, also wird zum Beispiel 'Holà' zu 'HOLà', aber er wird für die Demonstration der Nextflow-Konzepte gut genug funktionieren, und das ist, was zählt. + +Um es auszuprobieren, können wir den Befehl `echo 'Hello World'` ausführen und seine Ausgabe an den `tr`-Befehl pipen: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +Die Ausgabe ist eine Textdatei namens `UPPER-output.txt`, die die Großbuchstaben-Version des `Hello World`-Strings enthält. + +??? abstract "Dateiinhalte" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +Das ist im Grunde das, was wir mit unserem Workflow versuchen werden zu tun. + +### 1.2. Den Großbuchstaben-Schritt als Nextflow process schreiben + +Wir können unseren neuen process nach dem ersten modellieren, da wir alle dieselben Komponenten verwenden wollen. + +Füge die folgende process-Definition zum Workflow-Skript hinzu, direkt unter dem ersten: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Verwende ein Textersetzungstool, um die Begrüßung in Großbuchstaben umzuwandeln + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +In diesem Fall setzen wir den zweiten Ausgabedateinamen basierend auf dem Eingabedateinamen zusammen, ähnlich wie wir es ursprünglich für die Ausgabe des ersten process getan haben. + +### 1.3. Einen Aufruf des neuen process im workflow-Block hinzufügen + +Jetzt müssen wir Nextflow sagen, dass es den process, den wir gerade definiert haben, tatsächlich aufrufen soll. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Dies ist noch nicht funktionsfähig, weil wir nicht angegeben haben, was in den `convertToUpper()`-process eingegeben werden soll. + +### 1.4. Die Ausgabe des ersten process an den zweiten process übergeben + +Jetzt müssen wir die Ausgabe des `sayHello()`-process in den `convertToUpper()`-process fließen lassen. + +Praktischerweise verpackt Nextflow automatisch die Ausgabe eines process in einen channel namens `<process>.out`. +Also ist die Ausgabe des `sayHello`-process ein channel namens `sayHello.out`, den wir direkt in den Aufruf von `convertToUpper()` einstecken können. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper() + ``` + +Für einen einfachen Fall wie diesen (eine Ausgabe zu einer Eingabe) ist das alles, was wir tun müssen, um zwei processes zu verbinden! + +### 1.5. Die Workflow-Ausgabeveröffentlichung einrichten + +Zum Schluss aktualisieren wir die Workflow-Ausgaben, um auch die Ergebnisse des zweiten process zu veröffentlichen. + +#### 1.5.1. Den `publish:`-Abschnitt des `workflow`-Blocks aktualisieren + +Nimm im `workflow`-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +Die Logik ist dieselbe wie zuvor. + +#### 1.5.2. Den `output`-Block aktualisieren + +Nimm im `output`-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Wieder ist die Logik dieselbe wie zuvor. + +Dies zeigt dir, dass du die Ausgabeeinstellungen auf einer sehr granularen Ebene kontrollieren kannst, für jede einzelne Ausgabe. +Versuche gerne, die Pfade oder den Veröffentlichungsmodus für einen der processes zu ändern, um zu sehen, was passiert. + +Natürlich bedeutet das, dass wir hier einige Informationen wiederholen, was unpraktisch werden könnte, wenn wir den Speicherort für alle Ausgaben auf dieselbe Weise aktualisieren wollten. +Später im Kurs lernst du, wie du diese Einstellungen für mehrere Ausgaben auf strukturierte Weise konfigurierst. + +### 1.6. Den Workflow mit `-resume` ausführen + +Lass uns das mit dem `-resume`-Flag testen, da wir den ersten Schritt des Workflows bereits erfolgreich ausgeführt haben. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +In der Konsolenausgabe gibt es jetzt eine zusätzliche Zeile, die dem neuen process entspricht, den wir gerade hinzugefügt haben. + +Du findest die Ausgaben im Verzeichnis `results/hello_workflow`, wie im `output`-Block festgelegt. + +??? abstract "Verzeichnisinhalte" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Das ist praktisch! Aber es lohnt sich trotzdem, einen Blick in das work-Verzeichnis eines der Aufrufe des zweiten process zu werfen. + +??? abstract "Verzeichnisinhalte" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Beachte, dass es zwei `*-output`-Dateien gibt: die Ausgabe des ersten process sowie die Ausgabe des zweiten. + +Die Ausgabe des ersten process ist dort, weil Nextflow sie dort **gestageed** hat, um alles Notwendige für die Ausführung innerhalb desselben Unterverzeichnisses zu haben. + +Es handelt sich jedoch tatsächlich um einen symbolischen Link, der auf die Originaldatei im Unterverzeichnis des ersten process-Aufrufs zeigt. +Standardmäßig verwendet Nextflow, wenn es auf einer einzelnen Maschine wie hier ausgeführt wird, symbolische Links anstelle von Kopien, um Eingabe- und Zwischendateien zu stagen. + +Bevor du weitermachst, denke darüber nach, wie wir nur die Ausgabe von `sayHello` mit der Eingabe von `convertToUpper` verbunden haben und die beiden processes nacheinander ausgeführt werden konnten. +Nextflow hat die harte Arbeit erledigt, einzelne Eingabe- und Ausgabedateien zu handhaben und sie zwischen den beiden Befehlen für uns weiterzugeben. + +Das ist einer der Gründe, warum Nextflow channels so mächtig sind: Sie kümmern sich um die Routinearbeit, die beim Verbinden von Workflow-Schritten anfällt. + +### Zusammenfassung + +Du weißt, wie du processes verketten kannst, indem du die Ausgabe eines Schritts als Eingabe für den nächsten Schritt bereitstellst. + +### Was kommt als Nächstes? + +Lerne, wie du Ausgaben von gestapelten process-Aufrufen sammelst und sie in einen einzelnen process einspeist. + +--- + +## 2. Einen dritten Schritt hinzufügen, um alle Begrüßungen zu sammeln + +Wenn wir einen process verwenden, um eine Transformation auf jedes der Elemente in einem channel anzuwenden, wie wir es hier mit den mehreren Begrüßungen tun, wollen wir manchmal Elemente aus dem Ausgabe-channel dieses process sammeln und sie in einen anderen process einspeisen, der eine Art Analyse oder Zusammenfassung durchführt. + +Zur Demonstration werden wir einen neuen Schritt zu unserer Pipeline hinzufügen, der alle vom `convertToUpper`-process produzierten Großbuchstaben-Begrüßungen sammelt und sie in eine einzelne Datei schreibt. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Um die Überraschung nicht zu verderben, aber das wird einen sehr nützlichen Operator beinhalten. + +### 2.1. Den Sammelbefehl definieren und im Terminal testen + +Der Sammelschritt, den wir zu unserem Workflow hinzufügen wollen, wird den `cat`-Befehl verwenden, um mehrere Großbuchstaben-Begrüßungen in eine einzelne Datei zu verketten. + +Lass uns den Befehl für sich allein im Terminal ausführen, um zu überprüfen, dass er wie erwartet funktioniert, genau wie wir es zuvor getan haben. + +Führe Folgendes in deinem Terminal aus: + +```bash +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 +``` + +Die Ausgabe ist eine Textdatei namens `COLLECTED-output.txt`, die die Großbuchstaben-Versionen der ursprünglichen Begrüßungen enthält. + +??? abstract "Dateiinhalte" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Das ist das Ergebnis, das wir mit unserem Workflow erreichen wollen. + +### 2.2. Einen neuen process für den Sammelschritt erstellen + +Lass uns einen neuen process erstellen und ihn `collectGreetings()` nennen. +Wir können beginnen, ihn basierend auf dem zu schreiben, was wir bisher gesehen haben. + +#### 2.2.1. Die 'offensichtlichen' Teile des process schreiben + +Füge die folgende process-Definition zum Workflow-Skript hinzu: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Großbuchstaben-Begrüßungen in einer einzelnen Ausgabedatei sammeln + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +Das ist, was wir mit Zuversicht basierend auf dem, was du bisher gelernt hast, schreiben können. +Aber das ist nicht funktionsfähig! +Es lässt die Eingabedefinition(en) und die erste Hälfte des Skriptbefehls aus, weil wir herausfinden müssen, wie wir das schreiben. + +#### 2.2.2. Eingaben für `collectGreetings()` definieren + +Wir müssen die Begrüßungen von allen Aufrufen des `convertToUpper()`-process sammeln. +Was wissen wir, dass wir vom vorherigen Schritt im Workflow bekommen können? + +Der von `convertToUpper()` ausgegebene channel wird die Pfade zu den einzelnen Dateien enthalten, die die Großbuchstaben-Begrüßungen enthalten. +Das entspricht einem Eingabeslot; nennen wir ihn der Einfachheit halber `input_files`. + +Nimm im process-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Beachte, dass wir das `path`-Präfix verwenden, obwohl wir erwarten, dass dies mehrere Dateien enthält. + +#### 2.2.3. Den Verkettungsbefehl zusammenstellen + +Hier könnten die Dinge etwas knifflig werden, weil wir in der Lage sein müssen, eine beliebige Anzahl von Eingabedateien zu handhaben. +Konkret können wir den Befehl nicht im Voraus schreiben, also müssen wir Nextflow sagen, wie es ihn zur Laufzeit basierend auf den Eingaben, die in den process fließen, zusammenstellen soll. + +Mit anderen Worten, wenn wir einen Eingabe-channel haben, der das Element `[file1.txt, file2.txt, file3.txt]` enthält, brauchen wir Nextflow, um das in `cat file1.txt file2.txt file3.txt` umzuwandeln. + +Glücklicherweise macht Nextflow das gerne für uns, wenn wir einfach `cat ${input_files}` in den Skriptbefehl schreiben. + +Nimm im process-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +Theoretisch sollte dies jede beliebige Anzahl von Eingabedateien handhaben können. + +!!! tip "Tipp" + + Einige Kommandozeilenwerkzeuge erfordern die Angabe eines Arguments (wie `-input`) für jede Eingabedatei. + In diesem Fall müssten wir ein bisschen zusätzliche Arbeit leisten, um den Befehl zusammenzustellen. + Du kannst ein Beispiel dafür im [Nextflow for Genomics](../../nf4_science/genomics/)-Trainingskurs sehen. + +### 2.3. Den Sammelschritt zum Workflow hinzufügen + +Jetzt sollten wir nur noch den Sammel-process auf der Ausgabe des Großbuchstaben-Schritts aufrufen müssen. + +#### 2.3.1. Die process-Aufrufe verbinden + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out) + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="75" + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + } + ``` + +Dies verbindet die Ausgabe von `convertToUpper()` mit der Eingabe von `collectGreetings()`. + +#### 2.3.2. Den Workflow mit `-resume` ausführen + +Lass uns es versuchen. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Es läuft erfolgreich, einschließlich des dritten Schritts. + +Schau dir jedoch die Anzahl der Aufrufe für `collectGreetings()` in der letzten Zeile an. +Wir haben nur einen erwartet, aber es sind drei. + +Schau dir jetzt den Inhalt der endgültigen Ausgabedatei an. + +??? abstract "Dateiinhalte" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Oh nein. Der Sammelschritt wurde einzeln auf jede Begrüßung ausgeführt, was NICHT das ist, was wir wollten. + +Wir müssen etwas tun, um Nextflow explizit zu sagen, dass wir wollen, dass dieser dritte Schritt auf allen Elementen im vom `convertToUpper()` ausgegebenen channel läuft. + +### 2.4. Einen Operator verwenden, um die Begrüßungen in eine einzelne Eingabe zu sammeln + +Ja, wieder einmal ist die Antwort auf unser Problem ein Operator. + +Konkret werden wir den treffend benannten [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect)-Operator verwenden. + +#### 2.4.1. Den `collect()`-Operator hinzufügen + +Diesmal wird es etwas anders aussehen, weil wir den Operator nicht im Kontext einer channel factory hinzufügen; wir fügen ihn zu einem Ausgabe-channel hinzu. + +Wir nehmen das `convertToUpper.out` und hängen den `collect()`-Operator an, was uns `convertToUpper.out.collect()` gibt. +Wir können das direkt in den `collectGreetings()`-process-Aufruf einstecken. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Einige `view()`-Anweisungen hinzufügen + +Lass uns auch ein paar `view()`-Anweisungen einfügen, um die Zustände des channel-Inhalts vor und nach zu visualisieren. + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + + // Optionale view-Anweisungen + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="73" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + } + ``` + +Die `view()`-Anweisungen können überall platziert werden, wo du möchtest; wir haben sie für die Lesbarkeit direkt nach dem Aufruf platziert. + +#### 2.4.3. Den Workflow erneut mit `-resume` ausführen + +Lass uns es versuchen: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + 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] + ``` + +Es läuft erfolgreich, obwohl die Log-Ausgabe möglicherweise etwas unordentlicher aussieht als dies (wir haben es für die Lesbarkeit aufgeräumt). + +Diesmal wurde der dritte Schritt nur einmal aufgerufen! + +Wenn du dir die Ausgabe der `view()`-Anweisungen anschaust, siehst du Folgendes: + +- Drei `Before collect:`-Anweisungen, eine für jede Begrüßung: zu diesem Zeitpunkt sind die Dateipfade einzelne Elemente im channel. +- Eine einzelne `After collect:`-Anweisung: die drei Dateipfade sind jetzt in ein einzelnes Element verpackt. + +Schau dir den Inhalt der endgültigen Ausgabedatei an. + +??? abstract "Dateiinhalte" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Diesmal haben wir alle drei Begrüßungen in der endgültigen Ausgabedatei. Erfolg! + +!!! note "Hinweis" + + Wenn du dies mehrmals ohne `-resume` ausführst, wirst du sehen, dass sich die Reihenfolge der Begrüßungen von einem Lauf zum nächsten ändert. + Dies zeigt dir, dass die Reihenfolge, in der Elemente durch process-Aufrufe fließen, nicht garantiert konsistent ist. + +#### 2.4.4. `view()`-Anweisungen für die Lesbarkeit entfernen + +Bevor du zum nächsten Abschnitt übergehst, empfehlen wir, die `view()`-Anweisungen zu löschen, um die Konsolenausgabe nicht zu überladen. + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="73" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + + // Optionale view-Anweisungen + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +Dies ist im Grunde die umgekehrte Operation von Punkt 2.4.2. + +### Zusammenfassung + +Du weißt, wie du Ausgaben aus einem Stapel von process-Aufrufen sammelst und sie in einen gemeinsamen Analyse- oder Zusammenfassungsschritt einspeist. + +### Was kommt als Nächstes? + +Lerne, wie du mehr als eine Eingabe an einen process übergibst. + +--- + +## 3. Mehr als eine Eingabe an einen process übergeben + +Wir wollen in der Lage sein, der endgültigen Ausgabedatei einen bestimmten Namen zu geben, um nachfolgende Stapel von Begrüßungen verarbeiten zu können, ohne die endgültigen Ergebnisse zu überschreiben. + +Zu diesem Zweck werden wir die folgenden Verfeinerungen am Workflow vornehmen: + +- Den Sammel-process so modifizieren, dass er einen benutzerdefinierten Namen für die Ausgabedatei akzeptiert +- Einen Kommandozeilenparameter zum Workflow hinzufügen und ihn an den Sammel-process übergeben + +### 3.1. Den Sammel-process modifizieren + +Wir müssen die zusätzliche Eingabe deklarieren und sie in den Ausgabedateinamen integrieren. + +#### 3.1.1. Die zusätzliche Eingabe deklarieren + +Gute Nachricht: Wir können so viele Eingabevariablen deklarieren, wie wir wollen, in der process-Definition. +Nennen wir diese `batch_name`. + +Nimm im process-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Du kannst deine processes so einrichten, dass sie so viele Eingaben erwarten, wie du möchtest. +Im Moment sind diese alle als erforderliche Eingaben eingerichtet; du _musst_ einen Wert angeben, damit der Workflow funktioniert. + +Die Handhabung erforderlicher und optionaler Eingaben behandeln fortgeschrittene Kurse. + +#### 3.1.2. Die `batch_name`-Variable im Ausgabedateinamen verwenden + +Wir können die Variable auf dieselbe Weise in den Ausgabedateinamen einfügen, wie wir zuvor dynamische Dateinamen zusammengestellt haben. + +Nimm im process-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Dies richtet den process ein, den `batch_name`-Wert zu verwenden, um einen spezifischen Dateinamen für die endgültige Ausgabe des Workflows zu generieren. + +### 3.2. Einen `batch`-Kommandozeilenparameter hinzufügen + +Jetzt brauchen wir einen Weg, den Wert für `batch_name` zu liefern und ihn an den process-Aufruf zu übergeben. + +#### 3.2.1. `params` verwenden, um den Parameter einzurichten + +Du weißt bereits, wie du das `params`-System verwendest, um CLI-Parameter zu deklarieren. +Lass uns das verwenden, um einen `batch`-Parameter zu deklarieren (mit einem Standardwert, weil wir faul sind). + +Nimm im Abschnitt für Pipeline-Parameter die folgenden Codeänderungen vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Genau wie wir es für `--input` demonstriert haben, kannst du diesen Standardwert überschreiben, indem du einen Wert mit `--batch` auf der Kommandozeile angibst. + +#### 3.2.2. Den `batch`-Parameter an den process übergeben + +Um den Wert des Parameters an den process zu übergeben, müssen wir ihn im process-Aufruf hinzufügen. + +Nimm im workflow-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect()) + ``` + +Du siehst, dass um mehrere Eingaben an einen process zu übergeben, du sie einfach in den Aufruf-Klammern auflistest, durch Kommas getrennt. + +!!! warning "Warnung" + + Du MUSST die Eingaben an den process in der EXAKT GLEICHEN REIHENFOLGE übergeben, wie sie im Eingabedefinitionsblock des process aufgelistet sind. + +### 3.3. Den Workflow ausführen + +Lass uns versuchen, dies mit einem Stapelnamen auf der Kommandozeile auszuführen. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Es läuft erfolgreich und produziert die gewünschte Ausgabe: + +??? abstract "Dateiinhalte" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Solange wir den Parameter entsprechend angeben, werden nachfolgende Läufe auf anderen Eingabestapeln keine vorherigen Ergebnisse überschreiben. + +### Zusammenfassung + +Du weißt, wie du mehr als eine Eingabe an einen process übergibst. + +### Was kommt als Nächstes? + +Lerne, wie du mehrere Ausgaben ausgibst und sie bequem handhabst. + +--- + +## 4. Eine Ausgabe zum Sammelschritt hinzufügen + +Bisher haben wir processes verwendet, die jeweils nur eine Ausgabe produzierten. +Wir konnten auf ihre jeweiligen Ausgaben sehr bequem mit der `<process>.out`-Syntax zugreifen, die wir sowohl im Kontext der Übergabe einer Ausgabe an den nächsten process (z.B. `convertToUpper(sayHello.out)`) als auch im Kontext des `publish:`-Abschnitts (z.B. `first_output = sayHello.out`) verwendet haben. + +Was passiert, wenn ein process mehr als eine Ausgabe produziert? +Wie handhaben wir die mehreren Ausgaben? +Können wir eine bestimmte Ausgabe auswählen und verwenden? + +Alles ausgezeichnete Fragen, und die kurze Antwort ist ja, das können wir! + +Mehrere Ausgaben werden in separate channels verpackt. +Wir können entweder wählen, diesen Ausgabe-channels Namen zu geben, was es einfach macht, sie später einzeln zu referenzieren, oder wir können sie per Index referenzieren. + +Lass uns mit einem Beispiel eintauchen. + +Zur Demonstration sagen wir, dass wir die Anzahl der Begrüßungen zählen wollen, die für einen gegebenen Eingabestapel gesammelt werden, und sie in einer Datei berichten wollen. + +### 4.1. Den process so modifizieren, dass er die Anzahl der Begrüßungen zählt und ausgibt + +Dies erfordert zwei wichtige Änderungen an der process-Definition: wir brauchen einen Weg, die Begrüßungen zu zählen und eine Berichtsdatei zu schreiben, dann müssen wir diese Berichtsdatei zum `output`-Block des process hinzufügen. + +#### 4.1.1. Die Anzahl der gesammelten Begrüßungen zählen + +Praktischerweise erlaubt Nextflow uns, beliebigen Code im `script:`-Block der process-Definition hinzuzufügen, was wirklich praktisch ist, um solche Dinge zu tun. + +Das bedeutet, wir können Nextflows eingebaute `size()`-Funktion verwenden, um die Anzahl der Dateien im `input_files`-Array zu erhalten, und das Ergebnis mit einem `echo`-Befehl in eine Datei schreiben. + +Nimm im `collectGreetings`-process-Block die folgenden Codeänderungen vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +Die `count_greetings`-Variable wird zur Laufzeit berechnet. + +#### 4.1.2. Die Berichtsdatei ausgeben und Ausgaben benennen + +Im Prinzip müssen wir nur die Berichtsdatei zum `output:`-Block hinzufügen. + +Aber während wir dabei sind, werden wir auch einige `emit:`-Tags zu unseren Ausgabedeklarationen hinzufügen. Diese werden es uns ermöglichen, die Ausgaben per Namen auszuwählen, anstatt Positionsindizes verwenden zu müssen. + +Nimm im process-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +Die `emit:`-Tags sind optional, und wir hätten ein Tag nur zu einer der Ausgaben hinzufügen können. +Aber wie das Sprichwort sagt, warum nicht beides? + +!!! tip "Tipp" + + Wenn du die Ausgaben eines process nicht mit `emit:` benennst, kannst du trotzdem einzeln auf sie zugreifen, indem du ihren jeweiligen (nullbasierten) Index verwendest. + Zum Beispiel würdest du `<process>.out[0]` verwenden, um die erste Ausgabe zu bekommen, `<process>.out[1]` für die zweite Ausgabe, und so weiter. + + Wir bevorzugen es, Ausgaben zu benennen, weil es sonst zu einfach ist, versehentlich den falschen Index zu greifen, besonders wenn der process viele Ausgaben produziert. + +### 4.2. Die Workflow-Ausgaben aktualisieren + +Jetzt, da wir zwei Ausgaben aus dem `collectGreetings`-process haben, enthält die `collectGreetings.out`-Ausgabe zwei channels: + +- `collectGreetings.out.outfile` enthält die endgültige Ausgabedatei +- `collectGreetings.out.report` enthält die Berichtsdatei + +Wir müssen die Workflow-Ausgaben entsprechend aktualisieren. + +#### 4.2.1. Den `publish:`-Abschnitt aktualisieren + +Nimm im `workflow`-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Wie du sehen kannst, ist das Referenzieren spezifischer process-Ausgaben jetzt trivial. +Wenn wir in Teil 5 (Containers) einen weiteren Schritt zu unserer Pipeline hinzufügen, werden wir in der Lage sein, leicht auf `collectGreetings.out.outfile` zu verweisen und es dem neuen process zu übergeben (Spoiler: der neue process heißt `cowpy`). + +Aber für jetzt aktualisieren wir die Workflow-Level-Ausgaben fertig. + +#### 4.2.2. Den `output`-Block aktualisieren + +Nimm im `output`-Block die folgende Codeänderung vor: + +=== "Nachher" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Wir müssen die `collected`-Ausgabedefinition nicht aktualisieren, da sich dieser Name nicht geändert hat. +Wir müssen nur die neue Ausgabe hinzufügen. + +### 4.3. Den Workflow ausführen + +Lass uns versuchen, dies mit dem aktuellen Stapel von Begrüßungen auszuführen. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Wenn du ins Verzeichnis `results/hello_workflow/` schaust, findest du die neue Berichtsdatei `trio-report.txt`. +Öffne sie, um zu überprüfen, dass der Workflow korrekt die Anzahl der verarbeiteten Begrüßungen berichtet hat. + +??? abstract "Dateiinhalte" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +Du kannst gerne weitere Begrüßungen zur CSV hinzufügen und testen, was passiert. + +### Zusammenfassung + +Du weißt, wie du einen process mehrere benannte Ausgaben ausgeben lässt und wie du sie auf Workflow-Ebene angemessen handhabst. + +Allgemeiner verstehst du die wichtigsten Prinzipien, die beim Verbinden von processes auf gängige Weise involviert sind. + +### Was kommt als Nächstes? + +Mach eine extra lange Pause, du hast sie verdient. + +Wenn du bereit bist, gehe zu [**Teil 4: Hallo Module**](./04_hello_modules.md), um zu lernen, wie du deinen Code für bessere Wartbarkeit und Code-Effizienz modularisierst. + +--- + +## Quiz + +<quiz> +Wie greifst du auf die Ausgabe eines process im workflow-Block zu? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Mehr erfahren: [1.4. Die Ausgabe des ersten process an den zweiten process übergeben](#14-die-ausgabe-des-ersten-process-an-den-zweiten-process-ubergeben) +</quiz> + +<quiz> +Was bestimmt die Reihenfolge der process-Ausführung in Nextflow? +- [ ] Die Reihenfolge, in der processes im workflow-Block geschrieben sind +- [ ] Alphabetische Reihenfolge nach process-Namen +- [x] Datenabhängigkeiten zwischen processes +- [ ] Zufällige Reihenfolge für parallele Ausführung + +Mehr erfahren: [1.4. Die Ausgabe des ersten process an den zweiten process übergeben](#14-die-ausgabe-des-ersten-process-an-den-zweiten-process-ubergeben) +</quiz> + +<quiz> +Welcher Operator sollte `???` ersetzen, um alle Ausgaben in eine einzelne Liste für den nachfolgenden process zu sammeln? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Mehr erfahren: [2.4. Einen Operator verwenden, um die Begrüßungen in eine einzelne Eingabe zu sammeln](#24-einen-operator-verwenden-um-die-begrussungen-in-eine-einzelne-eingabe-zu-sammeln) +</quiz> + +<quiz> +Wann solltest du den `collect()`-Operator verwenden? +- [ ] Wenn du Elemente parallel verarbeiten möchtest +- [ ] Wenn du channel-Inhalte filtern musst +- [x] Wenn ein nachfolgender process alle Elemente von einem vorgelagerten process benötigt +- [ ] Wenn du Daten auf mehrere processes aufteilen möchtest + +Mehr erfahren: [2.4. Einen Operator verwenden, um die Begrüßungen in eine einzelne Eingabe zu sammeln](#24-einen-operator-verwenden-um-die-begrussungen-in-eine-einzelne-eingabe-zu-sammeln) +</quiz> + +<quiz> +Wie greifst du auf eine benannte Ausgabe von einem process zu? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Mehr erfahren: [4.1.2. Die Berichtsdatei ausgeben und Ausgaben benennen](#412-die-berichtsdatei-ausgeben-und-ausgaben-benennen) +</quiz> + +<quiz> +Was ist die korrekte Syntax, um eine Ausgabe in einem process zu benennen? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Mehr erfahren: [4.1.2. Die Berichtsdatei ausgeben und Ausgaben benennen](#412-die-berichtsdatei-ausgeben-und-ausgaben-benennen) +</quiz> + +<quiz> +Was muss bei der Übergabe mehrerer Eingaben an einen process zutreffen? +- [ ] Alle Eingaben müssen vom gleichen Typ sein +- [ ] Eingaben müssen in alphabetischer Reihenfolge übergeben werden +- [x] Die Reihenfolge der Eingaben muss mit der im Eingabeblock definierten Reihenfolge übereinstimmen +- [ ] Nur zwei Eingaben können gleichzeitig übergeben werden + +Mehr erfahren: [3. Mehr als eine Eingabe an einen process übergeben](#3-mehr-als-eine-eingabe-an-einen-process-ubergeben) +</quiz> diff --git a/docs/de/docs/hello_nextflow/04_hello_modules.md b/docs/de/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..0bb120230b --- /dev/null +++ b/docs/de/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Teil 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Siehe [die gesamte Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal. + +:green_book: Das Videotranskript ist [hier](./transcripts/04_hello_modules.md) verfügbar. +/// + +Dieser Abschnitt behandelt, wie du deinen Workflow-Code organisierst, um die Entwicklung und Wartung deiner Pipeline effizienter und nachhaltiger zu gestalten. +Konkret werden wir demonstrieren, wie man **Module** verwendet. + +In Nextflow ist ein **Modul** eine einzelne process-Definition, die für sich allein in einer eigenständigen Codedatei gekapselt ist. +Um ein Modul in einem Workflow zu verwenden, fügst du einfach eine einzeilige Import-Anweisung zu deiner Workflow-Codedatei hinzu; dann kannst du den process genauso in den Workflow integrieren, wie du es normalerweise tun würdest. +Das ermöglicht es, process-Definitionen in mehreren Workflows wiederzuverwenden, ohne mehrere Kopien des Codes zu produzieren. + +Als wir anfingen, unseren Workflow zu entwickeln, haben wir alles in einer einzigen Codedatei geschrieben. +Jetzt werden wir die processes in einzelne Module auslagern. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Dies wird unseren Code besser teilbar, flexibler und wartbarer machen. + +??? info "Wie du von diesem Abschnitt aus beginnen kannst" + + Dieser Abschnitt des Kurses setzt voraus, dass du die Teile 1-3 des [Hello Nextflow](./index.md)-Kurses abgeschlossen hast, aber wenn du mit den dort behandelten Grundlagen vertraut bist, kannst du von hier aus starten, ohne etwas Besonderes tun zu müssen. + +--- + +## 0. Aufwärmübung: `hello-modules.nf` ausführen + +Wir werden das Workflow-Skript `hello-modules.nf` als Ausgangspunkt verwenden. +Es entspricht dem Skript, das durch das Durcharbeiten von Teil 3 dieses Trainingskurses erstellt wurde, außer dass wir die Ausgabeziele geändert haben: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Um sicherzustellen, dass alles funktioniert, führe das Skript einmal aus, bevor du Änderungen vornimmst: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Wie zuvor findest du die Ausgabedateien in dem im `output`-Block angegebenen Verzeichnis (hier `results/hello_modules/`). + +??? abstract "Verzeichnisinhalte" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Wenn das bei dir funktioniert hat, bist du bereit zu lernen, wie du deinen Workflow-Code modularisierst. + +--- + +## 1. Ein Verzeichnis zum Speichern von Modulen erstellen + +Es ist eine bewährte Praxis, deine Module in einem bestimmten Verzeichnis zu speichern. +Du kannst dieses Verzeichnis beliebig nennen, aber die Konvention ist, es `modules/` zu nennen. + +```bash +mkdir modules +``` + +!!! tip "Tipp" + + Hier zeigen wir dir, wie du **lokale Module** verwendest, also Module, die lokal im selben Repository wie der Rest des Workflow-Codes gespeichert sind, im Gegensatz zu Remote-Modulen, die in anderen (entfernten) Repositories gespeichert sind. + Für weitere Informationen über **Remote-Module**, siehe die [Dokumentation](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Ein Modul für `sayHello()` erstellen + +In seiner einfachsten Form ist das Umwandeln eines bestehenden process in ein Modul kaum mehr als eine Kopier-und-Einfüge-Operation. +Wir werden einen Dateistub für das Modul erstellen, den relevanten Code hinüberkopieren und ihn dann aus der Haupt-Workflow-Datei löschen. + +Dann müssen wir nur noch eine Import-Anweisung hinzufügen, damit Nextflow weiß, dass es den relevanten Code zur Laufzeit einziehen soll. + +### 2.1. Einen Dateistub für das neue Modul erstellen + +Lass uns eine leere Datei für das Modul namens `sayHello.nf` erstellen. + +```bash +touch modules/sayHello.nf +``` + +Dies gibt uns einen Platz, um den process-Code zu platzieren. + +### 2.2. Den `sayHello`-process-Code in die Moduldatei verschieben + +Kopiere die gesamte process-Definition von der Workflow-Datei in die Moduldatei und stelle sicher, dass du auch den `#!/usr/bin/env nextflow`-Shebang mit kopierst. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Sobald das erledigt ist, lösche die process-Definition aus der Workflow-Datei, aber stelle sicher, dass du den Shebang an Ort und Stelle lässt. + +### 2.3. Eine Import-Deklaration vor dem workflow-Block hinzufügen + +Die Syntax für das Importieren eines lokalen Moduls ist ziemlich unkompliziert: + +```groovy title="Syntax: Import-Deklaration" +include { <MODULE_NAME> } from '<path_to_module>' +``` + +Lass uns das oberhalb des `params`-Blocks einfügen und es entsprechend ausfüllen. + +=== "Nachher" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Vorher" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Du siehst, wir haben den Modulnamen `sayHello` und den Pfad zu der Datei, die den Modulcode enthält, `./modules/sayHello.nf`, ausgefüllt. + +### 2.4. Den Workflow ausführen + +Wir führen den Workflow mit im Wesentlichen demselben Code und denselben Eingaben wie zuvor aus, also lass ihn uns mit dem `-resume`-Flag ausführen und sehen, was passiert. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Dies sollte sehr schnell laufen, weil alles im Cache ist. +Du kannst gerne die veröffentlichten Ausgaben überprüfen. + +Nextflow hat erkannt, dass es immer noch dieselbe Arbeit zu erledigen gibt, auch wenn der Code auf mehrere Dateien aufgeteilt ist. + +### Zusammenfassung + +Du weißt, wie du einen process in ein lokales Modul extrahierst und weißt, dass dies die Wiederaufnahmefähigkeit des Workflows nicht beeinträchtigt. + +### Was kommt als Nächstes? + +Übe das Erstellen weiterer Module. +Sobald du eines gemacht hast, kannst du eine Million weitere machen... +Aber lass uns vorerst nur noch zwei weitere machen. + +--- + +## 3. Den `convertToUpper()`-process modularisieren + +### 3.1. Einen Dateistub für das neue Modul erstellen + +Erstelle eine leere Datei für das Modul namens `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Den `convertToUpper`-process-Code in die Moduldatei verschieben + +Kopiere die gesamte process-Definition von der Workflow-Datei in die Moduldatei und stelle sicher, dass du auch den `#!/usr/bin/env nextflow`-Shebang mit kopierst. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Verwende ein Textersetzungstool, um die Begrüßung in Großbuchstaben umzuwandeln + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Sobald das erledigt ist, lösche die process-Definition aus der Workflow-Datei, aber stelle sicher, dass du den Shebang an Ort und Stelle lässt. + +### 3.3. Eine Import-Deklaration vor dem `params`-Block hinzufügen + +Füge die Import-Deklaration oberhalb des `params`-Blocks ein und fülle sie entsprechend aus. + +=== "Nachher" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Vorher" + + ```groovy title="hello-modules.nf" linenums="23" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Dies sollte jetzt sehr vertraut aussehen. + +### 3.4. Den Workflow erneut ausführen + +Führe dies mit dem `-resume`-Flag aus. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Dies sollte immer noch dieselbe Ausgabe wie zuvor produzieren. + +Zwei erledigt, noch eines übrig! + +--- + +## 4. Den `collectGreetings()`-process modularisieren + +### 4.1. Einen Dateistub für das neue Modul erstellen + +Erstelle eine leere Datei für das Modul namens `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Den `collectGreetings`-process-Code in die Moduldatei verschieben + +Kopiere die gesamte process-Definition von der Workflow-Datei in die Moduldatei und stelle sicher, dass du auch den `#!/usr/bin/env nextflow`-Shebang mit kopierst. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Großbuchstaben-Begrüßungen in einer einzelnen Ausgabedatei sammeln + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Sobald das erledigt ist, lösche die process-Definition aus der Workflow-Datei, aber stelle sicher, dass du den Shebang an Ort und Stelle lässt. + +### 4.3. Eine Import-Deklaration vor dem `params`-Block hinzufügen + +Füge die Import-Deklaration oberhalb des `params`-Blocks ein und fülle sie entsprechend aus. + +=== "Nachher" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Vorher" + + ```groovy title="hello-modules.nf" linenums="3" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline-Parameter + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Das letzte! + +### 4.4. Den Workflow ausführen + +Führe dies mit dem `-resume`-Flag aus. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Dies sollte immer noch dieselbe Ausgabe wie zuvor produzieren. + +### Zusammenfassung + +Du weißt, wie du mehrere processes in einem Workflow modularisierst. + +Herzlichen Glückwunsch, du hast all diese Arbeit geleistet und absolut nichts hat sich daran geändert, wie die Pipeline funktioniert! + +Scherz beiseite, jetzt ist dein Code modularer, und wenn du dich entscheidest, eine andere Pipeline zu schreiben, die einen dieser processes aufruft, musst du nur eine kurze Import-Anweisung eingeben, um das relevante Modul zu verwenden. +Das ist besser als den Code zu kopieren und einzufügen, denn wenn du dich später entscheidest, das Modul zu verbessern, werden alle deine Pipelines die Verbesserungen erben. + +### Was kommt als Nächstes? + +Mach eine kurze Pause, wenn du möchtest. + +Wenn du bereit bist, gehe zu [**Teil 5: Hallo Container**](./05_hello_containers.md), um zu lernen, wie du Container verwendest, um Softwareabhängigkeiten bequemer und reproduzierbarer zu verwalten. + +--- + +## Quiz + +<quiz> +Was ist ein Modul in Nextflow? +- [ ] Eine Konfigurationsdatei +- [x] Eine eigenständige Datei, die eine einzelne process-Definition enthält +- [ ] Eine Workflow-Definition +- [ ] Ein channel-Operator + +Mehr erfahren: [2. Ein Modul für `sayHello()` erstellen](#2-ein-modul-fur-sayhello-erstellen) +</quiz> + +<quiz> +Was ist die empfohlene Namenskonvention für Moduldateien? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Wo sollten Moduldateien gespeichert werden? +- [ ] Im selben Verzeichnis wie der Workflow +- [ ] In einem `bin/`-Verzeichnis +- [x] In einem `modules/`-Verzeichnis +- [ ] In einem `lib/`-Verzeichnis + +Mehr erfahren: [1. Ein Verzeichnis zum Speichern von Modulen erstellen](#1-ein-verzeichnis-zum-speichern-von-modulen-erstellen) +</quiz> + +<quiz> +Was ist die korrekte Syntax, um ein Modul zu importieren? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Mehr erfahren: [2.3. Eine Import-Deklaration hinzufügen](#23-eine-import-deklaration-vor-dem-workflow-block-hinzufugen) +</quiz> + +<quiz> +Was passiert mit der `-resume`-Funktionalität bei der Verwendung von Modulen? +- [ ] Sie funktioniert nicht mehr +- [ ] Sie erfordert zusätzliche Konfiguration +- [x] Sie funktioniert genauso wie zuvor +- [ ] Sie funktioniert nur für lokale Module +</quiz> + +<quiz> +Was sind die Vorteile der Verwendung von Modulen? (Wähle alle zutreffenden aus) +- [x] Wiederverwendbarkeit von Code über Workflows hinweg +- [x] Einfachere Wartung +- [x] Bessere Organisation von Workflow-Code +- [ ] Schnellere Ausführungsgeschwindigkeit +</quiz> diff --git a/docs/de/docs/hello_nextflow/05_hello_containers.md b/docs/de/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..f26c9c23d3 --- /dev/null +++ b/docs/de/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1030 @@ +# Teil 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Sieh dir [die ganze Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal an. + +:green_book: Das Videotranskript ist [hier](./transcripts/05_hello_containers.md) verfügbar. +/// + +In den Teilen 1-4 dieses Kurses hast du gelernt, wie du die grundlegenden Bausteine von Nextflow verwendest, um einen einfachen Workflow zu erstellen, der Text verarbeiten, die Ausführung bei mehreren Eingaben parallelisieren und die Ergebnisse zur weiteren Verarbeitung sammeln kann. + +Du warst jedoch auf grundlegende UNIX-Tools beschränkt, die in deiner Umgebung verfügbar sind. +Reale Aufgaben erfordern oft verschiedene Tools und Pakete, die standardmäßig nicht enthalten sind. +Normalerweise müsstest du diese Tools installieren, ihre Abhängigkeiten verwalten und eventuelle Konflikte lösen. + +Das ist alles sehr mühsam und nervig, daher zeigen wir dir, wie du **Container** verwendest, um dieses Problem viel bequemer zu lösen. + +Ein **Container** ist eine leichtgewichtige, eigenständige, ausführbare Softwareeinheit, die aus einem Container-**Image** erstellt wird und alles enthält, was zum Ausführen einer Anwendung benötigt wird, einschließlich Code, Systembibliotheken und Einstellungen. +Wie du dir vorstellen kannst, wird das sehr hilfreich sein, um deine Pipelines reproduzierbarer zu machen. + +Beachte, dass wir dies mit [Docker](https://www.docker.com/get-started/) lehren, aber Nextflow unterstützt auch [mehrere andere Container-Technologien](https://www.nextflow.io/docs/latest/container.html#). + +??? info "Wie du von diesem Abschnitt aus beginnst" + + Dieser Abschnitt des Kurses setzt voraus, dass du die Teile 1-4 des [Hello Nextflow](./index.md)-Kurses abgeschlossen hast und eine vollständig funktionierende Pipeline hast. + + Wenn du den Kurs von diesem Punkt aus beginnst, musst du das `modules`-Verzeichnis aus den Lösungen kopieren: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Aufwärmen: `hello-containers.nf` ausführen + +Wir werden das Workflow-Script `hello-containers.nf` als Ausgangspunkt verwenden. +Es entspricht dem Script, das durch Durcharbeiten von Teil 4 dieses Kurses entstanden ist, außer dass wir die Ausgabeziele geändert haben: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Um sicherzustellen, dass alles funktioniert, führe das Script einmal aus, bevor du Änderungen vornimmst: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Wie zuvor findest du die Ausgabedateien in dem im `output`-Block angegebenen Verzeichnis (`results/hello_containers/`). + +??? abstract "Verzeichnisinhalt" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Wenn das bei dir funktioniert hat, bist du bereit zu lernen, wie man Container verwendet. + +--- + +## 1. Einen Container 'manuell' verwenden + +Was wir tun möchten, ist einen Schritt zu unserem Workflow hinzuzufügen, der einen Container zur Ausführung verwendet. + +Allerdings werden wir zuerst einige grundlegende Konzepte und Operationen durchgehen, um dein Verständnis davon zu festigen, was Container sind, bevor wir sie in Nextflow verwenden. + +### 1.1. Das Container-Image herunterladen + +Um einen Container zu verwenden, lädst du normalerweise ein Container-Image von einer Container-Registry herunter oder _pullst_ es, und führst dann das Container-Image aus, um eine Container-Instanz zu erstellen. + +Die allgemeine Syntax ist wie folgt: + +```bash title="Syntax" +docker pull '<container>' +``` + +Der `docker pull`-Teil ist die Anweisung an das Container-System, ein Container-Image aus einem Repository zu pullen. + +Der `'<container>'`-Teil ist die URI-Adresse des Container-Images. + +Als Beispiel pullen wir ein Container-Image, das [cowpy](https://github.com/jeffbuttars/cowpy) enthält, eine Python-Implementierung eines Tools namens `cowsay`, das ASCII-Kunst generiert, um beliebige Texteingaben auf lustige Weise anzuzeigen. + +```txt title="Beispiel" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Es gibt verschiedene Repositories, in denen du veröffentlichte Container finden kannst. +Wir haben den [Seqera Containers](https://seqera.io/containers/)-Service verwendet, um dieses Docker-Container-Image aus dem `cowpy`-Conda-Paket zu generieren: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Führe den vollständigen Pull-Befehl aus: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Befehlsausgabe" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Wenn du das Image noch nie heruntergeladen hast, kann dies eine Minute dauern. +Sobald es fertig ist, hast du eine lokale Kopie des Container-Images. + +### 1.2. Den Container verwenden, um `cowpy` als einmaligen Befehl auszuführen + +Eine sehr häufige Art, wie Leute Container verwenden, ist sie direkt auszuführen, _d.h._ nicht-interaktiv. +Das ist großartig für einmalige Befehle. + +Die allgemeine Syntax ist wie folgt: + +```bash title="Syntax" +docker run --rm '<container>' [tool command] +``` + +Der `docker run --rm '<container>'`-Teil ist die Anweisung an das Container-System, eine Container-Instanz aus einem Container-Image zu starten und einen Befehl darin auszuführen. +Das `--rm`-Flag teilt dem System mit, die Container-Instanz nach Abschluss des Befehls herunterzufahren. + +Die `[tool command]`-Syntax hängt vom verwendeten Tool und der Einrichtung des Containers ab. +Beginnen wir einfach mit `cowpy`. + +Vollständig zusammengestellt sieht der Container-Ausführungsbefehl so aus; führe ihn aus. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Befehlsausgabe" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Das System hat den Container gestartet, den `cowpy`-Befehl mit seinen Parametern ausgeführt, die Ausgabe an die Konsole gesendet und schließlich die Container-Instanz heruntergefahren. + +### 1.3. Den Container verwenden, um `cowpy` interaktiv auszuführen + +Du kannst einen Container auch interaktiv ausführen, was dir eine Shell-Eingabeaufforderung innerhalb des Containers gibt und es dir ermöglicht, mit dem Befehl zu experimentieren. + +#### 1.3.1. Den Container starten + +Um interaktiv auszuführen, fügen wir einfach `-it` zum `docker run`-Befehl hinzu. +Optional können wir die Shell angeben, die wir innerhalb des Containers verwenden möchten, indem wir z.B. `/bin/bash` an den Befehl anhängen. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Beachte, dass sich deine Eingabeaufforderung zu etwas wie `(base) root@b645838b3314:/tmp#` ändert, was anzeigt, dass du dich jetzt innerhalb des Containers befindest. + +Du kannst dies überprüfen, indem du `ls /` ausführst, um den Verzeichnisinhalt vom Wurzelverzeichnis des Dateisystems aufzulisten: + +```bash +ls / +``` + +??? abstract "Befehlsausgabe" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Wir verwenden hier `ls` anstelle von `tree`, weil das `tree`-Tool in diesem Container nicht verfügbar ist. +Du kannst sehen, dass das Dateisystem innerhalb des Containers sich vom Dateisystem auf deinem Host-System unterscheidet. + +Eine Einschränkung dessen, was wir gerade getan haben, ist, dass der Container standardmäßig vollständig vom Host-System isoliert ist. +Das bedeutet, dass der Container auf keine Dateien auf dem Host-System zugreifen kann, es sei denn, du erlaubst es ausdrücklich. + +Wir zeigen dir gleich, wie das geht. + +#### 1.3.2. Die gewünschten Tool-Befehle ausführen + +Jetzt, da du dich innerhalb des Containers befindest, kannst du den `cowpy`-Befehl direkt ausführen und ihm einige Parameter geben. +Zum Beispiel sagt die Tool-Dokumentation, dass wir den Charakter ('Cowacter') mit `-c` ändern können. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Befehlsausgabe" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Jetzt zeigt die Ausgabe den Linux-Pinguin Tux anstelle der Standard-Kuh, weil wir den Parameter `-c tux` angegeben haben. + +Da du dich innerhalb des Containers befindest, kannst du den `cowpy`-Befehl beliebig oft ausführen und die Eingabeparameter variieren, ohne dich mit Docker-Befehlen befassen zu müssen. + +!!! tip "Tipp" + + Verwende das '-c'-Flag, um einen anderen Charakter auszuwählen, einschließlich: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Das ist cool. Noch cooler wäre es, wenn wir unsere `greetings.csv` als Eingabe verwenden könnten. +Aber da wir keinen Zugriff auf das Dateisystem haben, können wir das nicht. + +Lass uns das beheben. + +#### 1.3.3. Den Container verlassen + +Um den Container zu verlassen, kannst du `exit` an der Eingabeaufforderung eingeben oder die Tastenkombination ++ctrl+d++ verwenden. + +```bash +exit +``` + +Deine Eingabeaufforderung sollte jetzt wieder so aussehen wie vor dem Starten des Containers. + +#### 1.3.4. Daten in den Container einbinden + +Wie bereits erwähnt, ist der Container standardmäßig vom Host-System isoliert. + +Um dem Container den Zugriff auf das Host-Dateisystem zu ermöglichen, kannst du ein **Volume** vom Host-System in den Container **einbinden** (mounten), indem du die folgende Syntax verwendest: + +```bash title="Syntax" +-v <outside_path>:<inside_path> +``` + +In unserem Fall wird `<outside_path>` das aktuelle Arbeitsverzeichnis sein, also können wir einfach einen Punkt (`.`) verwenden, und `<inside_path>` ist nur ein Alias, den wir erfinden; nennen wir es `/my_project` (der innere Pfad muss absolut sein). + +Um ein Volume einzubinden, ersetzen wir die Pfade und fügen das Volume-Mounting-Argument zum Docker-Run-Befehl wie folgt hinzu: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Dies bindet das aktuelle Arbeitsverzeichnis als Volume ein, das unter `/my_project` innerhalb des Containers zugänglich sein wird. + +Du kannst überprüfen, ob es funktioniert, indem du den Inhalt von `/my_project` auflistest: + +```bash +ls /my_project +``` + +??? success "Befehlsausgabe" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Du kannst jetzt den Inhalt des Arbeitsverzeichnisses von innerhalb des Containers sehen, einschließlich der `greetings.csv`-Datei unter `data/`. + +Dies hat effektiv einen Tunnel durch die Containerwand etabliert, den du verwenden kannst, um auf diesen Teil deines Dateisystems zuzugreifen. + +#### 1.3.5. Die eingebundenen Daten verwenden + +Jetzt, da wir das Arbeitsverzeichnis in den Container eingebunden haben, können wir den `cowpy`-Befehl verwenden, um den Inhalt der `greetings.csv`-Datei anzuzeigen. + +Dazu verwenden wir `cat /my_project/data/greetings.csv | `, um den Inhalt der CSV-Datei an den `cowpy`-Befehl zu übergeben. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Befehlsausgabe" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Dies erzeugt die gewünschte ASCII-Kunst eines Truthahns, der unsere Beispiel-Grüße aufsagt! +Nur dass hier der Truthahn die vollständigen Zeilen wiederholt anstatt nur die Grüße. +Wir wissen bereits, dass unser Nextflow-Workflow das besser machen wird! + +Experimentiere gerne mit diesem Befehl. +Wenn du fertig bist, verlasse den Container wie zuvor: + +```bash +exit +``` + +Du befindest dich wieder in deiner normalen Shell. + +### Erkenntnisse + +Du kannst Container pullen und einmalig oder interaktiv ausführen. Du kannst Daten im Container zugänglich machen und Tools mit echten Daten testen, ohne lokale Installationen. + +### Was kommt als Nächstes? + +Lerne, wie man Container für die Ausführung von Nextflow-Prozessen verwendet. + +--- + +## 2. Container in Nextflow verwenden + +Nextflow hat eingebaute Unterstützung für die Ausführung von Prozessen innerhalb von Containern, damit du Tools ausführen kannst, die nicht in deiner Rechenumgebung installiert sind. +Das bedeutet, dass du jedes beliebige Container-Image verwenden kannst, um deine Prozesse auszuführen, und Nextflow kümmert sich um das Pullen des Images, das Einbinden der Daten und das Ausführen des Prozesses darin. + +Um dies zu demonstrieren, werden wir einen `cowpy`-Schritt zur Pipeline hinzufügen, die wir entwickelt haben, nach dem `collectGreetings`-Schritt. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Muh, wenn du bereit bist einzutauchen! + +### 2.1. Ein `cowpy`-Modul schreiben + +Zuerst erstellen wir das `cowpy`-Prozess-Modul. + +#### 2.1.1. Eine Datei-Vorlage für das neue Modul erstellen + +Erstelle eine leere Datei für das Modul namens `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +Das gibt uns einen Platz für den Prozess-Code. + +#### 2.1.2. Den `cowpy`-Prozess-Code in die Modul-Datei kopieren + +Wir können unseren `cowpy`-Prozess nach den anderen Prozessen modellieren, die wir zuvor geschrieben haben. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// ASCII-Kunst mit cowpy generieren +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Der Prozess erwartet eine `input_file`, die die Grüße enthält, sowie einen `character`-Wert. + +Die Ausgabe wird eine neue Textdatei sein, die die vom `cowpy`-Tool generierte ASCII-Kunst enthält. + +### 2.2. cowpy zum Workflow hinzufügen + +Jetzt müssen wir das Modul importieren und den Prozess aufrufen. + +#### 2.2.1. Den `cowpy`-Prozess in `hello-containers.nf` importieren + +Füge die Import-Deklaration über dem Workflow-Block ein und fülle sie entsprechend aus. + +=== "Nachher" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Vorher" + + ```groovy title="hello-containers.nf" linenums="3" + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Jetzt ist das `cowpy`-Modul für die Verwendung im Workflow verfügbar. + +#### 2.2.2. Einen Aufruf des `cowpy`-Prozesses im Workflow hinzufügen + +Verbinden wir den `cowpy()`-Prozess mit der Ausgabe des `collectGreetings()`-Prozesses, der, wie du dich vielleicht erinnerst, zwei Ausgaben produziert: + +- `collectGreetings.out.outfile` enthält die Ausgabedatei <--_was wir wollen_ +- `collectGreetings.out.report` enthält die Berichtsdatei mit der Anzahl der Grüße pro Batch + +Nimm im Workflow-Block folgende Code-Änderung vor: + +=== "Nachher" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Vorher" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Beachte, dass wir einen neuen CLI-Parameter, `params.character`, deklariert haben, um anzugeben, welcher Charakter die Grüße sagen soll. + +#### 2.2.3. Den `character`-Parameter zum `params`-Block hinzufügen + +Dies ist technisch optional, aber es ist die empfohlene Praxis und eine Gelegenheit, einen Standardwert für den Charakter festzulegen, während wir dabei sind. + +=== "Nachher" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Vorher" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Jetzt können wir faul sein und das Tippen des character-Parameters in unseren Befehlszeilen überspringen. + +#### 2.2.4. Die Workflow-Ausgaben aktualisieren + +Wir müssen die Workflow-Ausgaben aktualisieren, um die Ausgabe des `cowpy`-Prozesses zu veröffentlichen. + +##### 2.2.4.1. Den `publish:`-Abschnitt aktualisieren + +Nimm im `workflow`-Block folgende Code-Änderung vor: + +=== "Nachher" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Vorher" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +Der `cowpy`-Prozess produziert nur eine Ausgabe, also können wir uns darauf auf die übliche Weise beziehen, indem wir `.out` anhängen. + +Aber für jetzt beenden wir die Aktualisierung der Workflow-Level-Ausgaben. + +##### 2.2.4.2. Den `output`-Block aktualisieren + +Wir müssen die finale `cowpy_art`-Ausgabe zum `output`-Block hinzufügen. Während wir dabei sind, bearbeiten wir auch die Veröffentlichungsziele, da unsere Pipeline jetzt vollständig ist und wir wissen, welche Ausgaben uns wirklich wichtig sind. + +Nimm im `output`-Block folgende Code-Änderungen vor: + +=== "Nachher" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Jetzt werden die veröffentlichten Ausgaben etwas besser organisiert sein. + +#### 2.2.5. Den Workflow ausführen + +Nur zur Zusammenfassung, das ist, was wir anstreben: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Denkst du, es wird funktionieren? + +Lass uns die vorherigen veröffentlichten Ausgaben löschen, um einen sauberen Stand zu haben, und den Workflow mit dem `-resume`-Flag ausführen. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Befehlsausgabe (zur Klarheit bearbeitet)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +Oh nein, es gibt einen Fehler! +Der Fehlercode `error exit status (127)` bedeutet, dass die angeforderte ausführbare Datei nicht gefunden wurde. + +Das ergibt Sinn, da wir das `cowpy`-Tool aufrufen, aber wir haben noch keinen Container angegeben (ups). + +### 2.3. Einen Container verwenden, um den `cowpy`-Prozess auszuführen + +Wir müssen einen Container angeben und Nextflow anweisen, ihn für den `cowpy()`-Prozess zu verwenden. + +#### 2.3.1. Einen Container für `cowpy` angeben + +Wir können dasselbe Image verwenden, das wir direkt im ersten Abschnitt dieses Tutorials verwendet haben. + +Bearbeite das `cowpy.nf`-Modul, um die `container`-Direktive zur Prozessdefinition wie folgt hinzuzufügen: + +=== "Nachher" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Vorher" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Dies teilt Nextflow mit, dass _wenn die Verwendung von Docker aktiviert ist_, es das hier angegebene Container-Image verwenden soll, um den Prozess auszuführen. + +#### 2.3.2. Die Verwendung von Docker über die `nextflow.config`-Datei aktivieren + +Beachte, dass wir sagten _'wenn die Verwendung von Docker aktiviert ist'_. Standardmäßig ist sie es nicht, also müssen wir Nextflow mitteilen, dass es Docker verwenden darf. +Dazu werden wir das Thema des nächsten und letzten Teils dieses Kurses (Teil 6) leicht vorwegnehmen, der die Konfiguration behandelt. + +Eine der Hauptmöglichkeiten, die Nextflow für die Konfiguration der Workflow-Ausführung bietet, ist die Verwendung einer `nextflow.config`-Datei. +Wenn eine solche Datei im aktuellen Verzeichnis vorhanden ist, lädt Nextflow sie automatisch und wendet die enthaltene Konfiguration an. + +Wir haben eine `nextflow.config`-Datei mit einer einzigen Codezeile bereitgestellt, die Docker explizit deaktiviert: `docker.enabled = false`. + +Jetzt ändern wir das auf `true`, um Docker zu aktivieren: + +=== "Nachher" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Vorher" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Tipp" + + Es ist möglich, die Docker-Ausführung über die Befehlszeile pro Ausführung mit dem Parameter `-with-docker <container>` zu aktivieren. + Das erlaubt uns jedoch nur, einen Container für den gesamten Workflow anzugeben, während der gerade gezeigte Ansatz es uns ermöglicht, einen anderen Container pro Prozess anzugeben. + Das ist besser für Modularität, Code-Wartung und Reproduzierbarkeit. + +#### 2.3.3. Den Workflow mit aktiviertem Docker ausführen + +Führe den Workflow mit dem `-resume`-Flag aus: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Diesmal funktioniert es tatsächlich! +Wie üblich findest du die Workflow-Ausgaben im entsprechenden Ergebnisverzeichnis, obwohl sie diesmal etwas übersichtlicher organisiert sind, mit nur dem Bericht und der finalen Ausgabe auf der obersten Ebene, und alle Zwischendateien in einem Unterverzeichnis verstaut. + +??? abstract "Verzeichnisinhalt" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Die finale ASCII-Kunst-Ausgabe befindet sich im Verzeichnis `results/hello_containers/`, unter dem Namen `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Und da ist er, unser wunderschöner Truthahn, der die Grüße wie gewünscht sagt. + +#### 2.3.4. Untersuchen, wie Nextflow die containerisierte Aufgabe gestartet hat + +Als letzten Abschluss dieses Abschnitts werfen wir einen Blick auf das Work-Unterverzeichnis für einen der `cowpy`-Prozessaufrufe, um etwas mehr Einblick zu bekommen, wie Nextflow unter der Haube mit Containern arbeitet. + +Überprüfe die Ausgabe deines `nextflow run`-Befehls, um den Pfad zum Work-Unterverzeichnis für den `cowpy`-Prozess zu finden. +Wenn wir uns ansehen, was wir für die oben gezeigte Ausführung erhalten haben, beginnt die Konsolenprotokollzeile für den `cowpy`-Prozess mit `[98/656c6c]`. +Das entspricht dem folgenden abgekürzten Verzeichnispfad: `work/98/656c6c`. + +In diesem Verzeichnis findest du die `.command.run`-Datei, die alle Befehle enthält, die Nextflow in deinem Namen während der Ausführung der Pipeline ausgeführt hat. + +??? abstract "Dateiinhalt" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + ... + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + ... + ``` + +Wenn du in dieser Datei nach `nxf_launch` suchst, solltest du so etwas sehen: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Wie du sehen kannst, verwendet Nextflow den `docker run`-Befehl, um den Prozessaufruf zu starten. +Es bindet auch das entsprechende Work-Unterverzeichnis in den Container ein, setzt das Arbeitsverzeichnis innerhalb des Containers entsprechend und führt unser templated Bash-Script in der `.command.sh`-Datei aus. + +All die harte Arbeit, die wir im ersten Abschnitt manuell erledigen mussten? Nextflow erledigt das für uns hinter den Kulissen! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Erkenntnisse + +Du weißt, wie man Container in Nextflow verwendet, um Prozesse auszuführen. + +### Was kommt als Nächstes? + +Mach eine Pause! + +Wenn du bereit bist, gehe zu [**Teil 6: Hello Config**](./06_hello_config.md) weiter, um zu lernen, wie du die Ausführung deiner Pipeline an deine Infrastruktur anpasst sowie die Konfiguration von Eingaben und Parametern verwaltest. + +Es ist der allerletzte Teil, und dann bist du mit diesem Kurs fertig! + +--- + +## Quiz + +<quiz> +Was ist ein Container? +- [ ] Eine Art virtuelle Maschine +- [ ] Ein Dateikomprimierungsformat +- [x] Eine leichtgewichtige, eigenständige ausführbare Einheit, die alles enthält, was zum Ausführen einer Anwendung benötigt wird +- [ ] Ein Netzwerkprotokoll +</quiz> + +<quiz> +Was ist der Unterschied zwischen einem Container-Image und einer Container-Instanz? +- [ ] Sie sind dasselbe +- [x] Ein Image ist eine Vorlage; eine Instanz ist ein laufender Container, der aus diesem Image erstellt wurde +- [ ] Eine Instanz ist eine Vorlage; ein Image ist ein laufender Container +- [ ] Images sind für Docker; Instanzen sind für Singularity +</quiz> + +<quiz> +Was macht das `-v`-Flag in einem `docker run`-Befehl? +- [ ] Aktiviert ausführliche Ausgabe +- [ ] Validiert den Container +- [x] Bindet ein Volume vom Host-System in den Container ein +- [ ] Gibt die Version des Containers an + +Mehr erfahren: [1.3.4. Daten in den Container einbinden](#134-daten-in-den-container-einbinden) +</quiz> + +<quiz> +Warum musst du Volumes einbinden, wenn du Container verwendest? +- [ ] Um die Container-Leistung zu verbessern +- [ ] Um Speicherplatz zu sparen +- [x] Weil Container standardmäßig vom Host-Dateisystem isoliert sind +- [ ] Um Netzwerke zu aktivieren + +Mehr erfahren: [1.3.4. Daten in den Container einbinden](#134-daten-in-den-container-einbinden) +</quiz> + +<quiz> +Wie gibst du einen Container für einen Nextflow-Prozess an? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Mehr erfahren: [2.3.1. Einen Container für cowpy angeben](#231-einen-container-für-cowpy-angeben) +</quiz> + +<quiz> +Welche `nextflow.config`-Einstellung aktiviert Docker für deinen Workflow? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Mehr erfahren: [2.3.2. Die Verwendung von Docker über die `nextflow.config`-Datei aktivieren](#232-die-verwendung-von-docker-über-die-nextflowconfig-datei-aktivieren) +</quiz> + +<quiz> +Was handhabt Nextflow automatisch, wenn ein Prozess in einem Container ausgeführt wird? (Wähle alle zutreffenden aus) +- [x] Das Container-Image bei Bedarf pullen +- [x] Das Work-Verzeichnis einbinden +- [x] Das Prozess-Script innerhalb des Containers ausführen +- [x] Die Container-Instanz nach der Ausführung bereinigen + +Mehr erfahren: [2.3.4. Untersuchen, wie Nextflow die containerisierte Aufgabe gestartet hat](#234-untersuchen-wie-nextflow-die-containerisierte-aufgabe-gestartet-hat) +</quiz> diff --git a/docs/de/docs/hello_nextflow/06_hello_config.md b/docs/de/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..d78d185653 --- /dev/null +++ b/docs/de/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1419 @@ +# Teil 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Sieh dir [die ganze Playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) auf dem Nextflow YouTube-Kanal an. + +:green_book: Das Videotranskript ist [hier](./transcripts/06_hello_config.md) verfügbar. +/// + +Dieser Abschnitt wird untersuchen, wie du die Konfiguration deiner Nextflow-Pipeline einrichtest und verwaltest, damit du ihr Verhalten anpassen, sie an verschiedene Umgebungen anpassen und die Ressourcennutzung optimieren kannst, _ohne eine einzige Zeile des Workflow-Codes selbst zu ändern_. + +Es gibt mehrere Möglichkeiten, dies zu tun, die kombiniert werden können und gemäß der [hier](https://www.nextflow.io/docs/latest/config.html) beschriebenen Vorrangordnung interpretiert werden. + +In diesem Teil des Kurses zeigen wir dir den einfachsten und häufigsten Konfigurationsdatei-Mechanismus, die `nextflow.config`-Datei, die du bereits in Teil 5: Hello Containers kennengelernt hast. + +Wir gehen wesentliche Komponenten der Nextflow-Konfiguration durch, wie Prozess-Direktiven, Executors, Profile und Parameterdateien. +Indem du lernst, diese Konfigurationsoptionen effektiv zu nutzen, kannst du die Flexibilität, Skalierbarkeit und Leistung deiner Pipelines verbessern. + +??? info "Wie du von diesem Abschnitt aus beginnst" + + Dieser Abschnitt des Kurses setzt voraus, dass du die Teile 1-5 des [Hello Nextflow](./index.md)-Kurses abgeschlossen hast und eine vollständig funktionierende Pipeline hast. + + Wenn du den Kurs von diesem Punkt aus beginnst, musst du das `modules`-Verzeichnis und die `nextflow.config`-Datei aus den Lösungen kopieren: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + Die `nextflow.config`-Datei enthält die Zeile `docker.enabled = true`, die die Verwendung von Docker-Containern aktiviert. + + Wenn du mit der Hello-Pipeline nicht vertraut bist oder eine Auffrischung brauchst, sieh dir [diese Infoseite](../info/hello_pipeline.md) an. + +--- + +## 0. Aufwärmen: `hello-config.nf` ausführen + +Wir werden das Workflow-Script `hello-config.nf` als Ausgangspunkt verwenden. +Es entspricht dem Script, das durch Durcharbeiten von Teil 5 dieses Kurses entstanden ist, außer dass wir die Ausgabeziele geändert haben: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Um sicherzustellen, dass alles funktioniert, führe das Script einmal aus, bevor du Änderungen vornimmst: + +```bash +nextflow run hello-config.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Wie zuvor findest du die Ausgabedateien in dem im `output`-Block angegebenen Verzeichnis (`results/hello_config/`). + +??? abstract "Verzeichnisinhalt" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Die finale ASCII-Kunst-Ausgabe befindet sich im Verzeichnis `results/hello_config/`, unter dem Namen `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Wenn das bei dir funktioniert hat, bist du bereit zu lernen, wie man Pipelines konfiguriert. + +--- + +## 1. Workflow-Eingabeparameter verwalten + +Wir beginnen mit einem Aspekt der Konfiguration, der einfach eine Erweiterung dessen ist, womit wir bisher gearbeitet haben: die Verwaltung von Eingabeparametern. + +Derzeit ist unser Workflow so eingerichtet, dass er mehrere Parameterwerte über die Befehlszeile akzeptiert, wobei Standardwerte in einem `params`-Block im Workflow-Script selbst festgelegt sind. +Möglicherweise möchtest du diese Standardwerte jedoch überschreiben, ohne entweder Parameter in der Befehlszeile angeben oder die ursprüngliche Script-Datei ändern zu müssen. + +Es gibt mehrere Möglichkeiten, das zu tun; wir zeigen dir drei grundlegende Wege, die sehr häufig verwendet werden. + +### 1.1. Standardwerte in `nextflow.config` verschieben + +Dies ist der einfachste Ansatz, obwohl er möglicherweise am wenigsten flexibel ist, da die Haupt-`nextflow.config`-Datei nicht etwas ist, das du für jeden Lauf bearbeiten möchtest. +Aber es hat den Vorteil, die Belange des _Deklarierens_ der Parameter im Workflow (was definitiv dorthin gehört) vom Bereitstellen von _Standardwerten_ zu trennen, die eher in einer Konfigurationsdatei zu Hause sind. + +Lass uns das in zwei Schritten tun. + +#### 1.1.1. Einen `params`-Block in der Konfigurationsdatei erstellen + +Nimm folgende Code-Änderungen in der `nextflow.config`-Datei vor: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Beachte, dass wir den `params`-Block nicht einfach vom Workflow in die Konfigurationsdatei kopiert haben. +Die Syntax ist etwas anders. +In der Workflow-Datei sind das typisierte Deklarationen. +In der Konfiguration sind das Wertzuweisungen. + +Technisch gesehen reicht dies aus, um die Standardwerte zu überschreiben, die noch in der Workflow-Datei angegeben sind. +Du könntest zum Beispiel den Charakter ändern und den Workflow ausführen, um dich zu vergewissern, dass der in der Konfigurationsdatei festgelegte Wert den in der Workflow-Datei festgelegten überschreibt. + +Aber im Sinne der vollständigen Verlagerung der Konfiguration in die Konfigurationsdatei, entfernen wir diese Werte vollständig aus der Workflow-Datei. + +#### 1.1.2. Die Werte aus dem `params`-Block in der Workflow-Datei entfernen + +Nimm folgende Code-Änderungen an der `hello-config.nf`-Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Vorher" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline-Parameter + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Jetzt setzt die Workflow-Datei selbst keine Standardwerte für diese Parameter. + +#### 1.1.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert. + +```bash +nextflow run hello-config.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Dies produziert dieselbe Ausgabe wie zuvor. + +Die finale ASCII-Kunst-Ausgabe befindet sich im Verzeichnis `results/hello_config/`, unter dem Namen `cowpy-COLLECTED-batch-output.txt`, wie zuvor. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funktional hat diese Verschiebung nichts geändert, aber konzeptionell ist es etwas sauberer, die Standardwerte in der Konfigurationsdatei zu haben. + +### 1.2. Eine laufspezifische Konfigurationsdatei verwenden + +Das ist großartig, aber manchmal möchtest du vielleicht einige temporäre Experimente mit anderen Standardwerten durchführen, ohne die Hauptkonfigurationsdatei zu ändern. +Du kannst das tun, indem du eine neue `nextflow.config`-Datei in einem Unterverzeichnis erstellst, das du als Arbeitsverzeichnis für deine Experimente verwendest. + +#### 1.2.1. Das Arbeitsverzeichnis mit einer leeren Konfiguration erstellen + +Beginnen wir mit dem Erstellen eines neuen Verzeichnisses und wechseln hinein: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Dann erstelle eine leere Konfigurationsdatei in diesem Verzeichnis: + +```bash +touch nextflow.config +``` + +Dies erzeugt eine leere Datei. + +#### 1.2.2. Die experimentelle Konfiguration einrichten + +Öffne jetzt die neue Datei und füge die Parameter hinzu, die du anpassen möchtest: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Beachte, dass der Pfad zur Eingabedatei die Verzeichnisstruktur widerspiegeln muss. + +#### 1.2.3. Die Pipeline ausführen + +Wir können jetzt unsere Pipeline aus unserem neuen Arbeitsverzeichnis ausführen. +Stelle sicher, dass du den Pfad entsprechend anpasst! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Dies erstellt einen neuen Satz von Verzeichnissen unter `tux-run/` einschließlich `tux-run/work/` und `tux-run/results/`. + +Bei diesem Lauf kombiniert Nextflow die `nextflow.config` in unserem aktuellen Verzeichnis mit der `nextflow.config` im Stammverzeichnis der Pipeline und überschreibt dadurch den Standard-Charakter (turkey) mit dem tux-Charakter. + +Die finale Ausgabedatei sollte den tux-Charakter enthalten, der die Grüße sagt. + +??? abstract "Dateiinhalt" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Das war's; jetzt hast du einen Bereich zum Experimentieren, ohne deine 'normale' Konfiguration zu ändern. + +!!! warning "Warnung" + + Stelle sicher, dass du zum vorherigen Verzeichnis zurückwechselst, bevor du zum nächsten Abschnitt übergehst! + + ```bash + cd .. + ``` + +Schauen wir uns jetzt eine weitere nützliche Möglichkeit an, Parameterwerte festzulegen. + +### 1.3. Eine Parameterdatei verwenden + +Der Unterverzeichnis-Ansatz funktioniert gut zum Experimentieren, erfordert aber etwas Einrichtung und dass du Pfade entsprechend anpasst. +Es gibt einen einfacheren Ansatz, wenn du deine Pipeline mit einem bestimmten Satz von Werten ausführen möchtest, oder es jemand anderem mit minimalem Aufwand ermöglichen möchtest. + +Nextflow ermöglicht es uns, Parameter über eine Parameterdatei im YAML- oder JSON-Format anzugeben, was es sehr bequem macht, alternative Sätze von Standardwerten sowie laufspezifische Parameterwerte zu verwalten und zu verteilen. + +#### 1.3.1. Die Beispiel-Parameterdatei untersuchen + +Um dies zu demonstrieren, stellen wir eine Beispiel-Parameterdatei im aktuellen Verzeichnis bereit, genannt `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Diese Parameterdatei enthält ein Schlüssel-Wert-Paar für jede der Eingaben, die wir angeben möchten. +Beachte die Verwendung von Doppelpunkten (`:`) anstelle von Gleichheitszeichen (`=`), wenn du die Syntax mit der Konfigurationsdatei vergleichst. +Die Config-Datei ist in Groovy geschrieben, während die Parameterdatei in YAML geschrieben ist. + +!!! info + + Wir stellen auch eine JSON-Version der Parameterdatei als Beispiel bereit, aber wir werden hier nicht damit arbeiten. + Probiere sie gerne selbst aus. + +#### 1.3.2. Die Pipeline ausführen + +Um den Workflow mit dieser Parameterdatei auszuführen, füge einfach `-params-file <filename>` zum Basisbefehl hinzu. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Die finale Ausgabedatei sollte den stegosaurus-Charakter enthalten, der die Grüße sagt. + +??? abstract "Dateiinhalt" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Die Verwendung einer Parameterdatei mag übertrieben erscheinen, wenn du nur wenige Parameter angeben musst, aber einige Pipelines erwarten Dutzende von Parametern. +In diesen Fällen ermöglicht uns die Verwendung einer Parameterdatei, Parameterwerte zur Laufzeit bereitzustellen, ohne massive Befehlszeilen eingeben oder das Workflow-Script ändern zu müssen. + +Es macht es auch einfacher, Parametersätze an Kollegen zu verteilen oder als ergänzende Informationen für eine Veröffentlichung bereitzustellen. +Das macht deine Arbeit reproduzierbarer für andere. + +### Erkenntnisse + +Du weißt, wie du die wichtigsten Konfigurationsoptionen für die Verwaltung von Workflow-Eingaben nutzen kannst. + +### Was kommt als Nächstes? + +Lerne, wie du verwaltest, wo und wie deine Workflow-Ausgaben veröffentlicht werden. + +--- + +## 2. Workflow-Ausgaben verwalten + +Bisher haben wir alle Pfade für Workflow-Level-Ausgabedeklarationen hartcodiert, und wie wir beim Hinzufügen mehrerer Ausgaben festgestellt haben, kann dabei etwas Wiederholung auftreten. + +Schauen wir uns einige gängige Möglichkeiten an, wie du dies flexibler konfigurieren kannst. + +### 2.1. Den `outputDir`-Verzeichnisnamen anpassen + +Für jedes Kapitel dieses Kurses haben wir Ausgaben in ein anderes Unterverzeichnis veröffentlicht, das in den Ausgabedefinitionen hartcodiert ist. + +Ändern wir das, um einen benutzerdefinierbaren Parameter zu verwenden. +Wir könnten einen ganz neuen Parameter dafür erstellen, aber verwenden wir den `batch`-Parameter, da er direkt verfügbar ist. + +#### 2.1.1. Einen Wert für `outputDir` in der Konfigurationsdatei festlegen + +Der Pfad, den Nextflow zum Veröffentlichen von Ausgaben verwendet, wird durch die Option `outputDir` gesteuert. +Um den Pfad für alle Ausgaben zu ändern, kannst du einen Wert für diese Option in der `nextflow.config`-Konfigurationsdatei festlegen. + +Füge folgenden Code zur `nextflow.config`-Datei hinzu: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Dies ersetzt den eingebauten Standardpfad, `results/`, durch `results/` plus den Wert des `batch`-Parameters als Unterverzeichnis. +Du könntest auch den `results`-Teil ändern, wenn du möchtest. + +Für eine temporäre Änderung könntest du diese Option von der Befehlszeile aus mit dem Parameter `-output-dir` in deinem Befehl setzen (aber dann könntest du den `batch`-Parameterwert nicht verwenden). + +#### 2.1.2. Den wiederholten Teil des hartcodierten Pfads entfernen + +Wir haben immer noch ein Unterverzeichnis in den Ausgabeoptionen hartcodiert, also entfernen wir das jetzt. + +Nimm folgende Code-Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +Wir hätten auch einfach `${params.batch}` zu jedem Pfad hinzufügen können, anstatt den `outputDir`-Standard zu ändern, aber das ist prägnanter. + +#### 2.1.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen über die Befehlszeile auf `outdir` setzen. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Dies produziert dieselbe Ausgabe wie zuvor, außer dass wir diesmal unsere Ausgaben unter `results/outdir/` finden. + +??? abstract "Verzeichnisinhalt" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Du kannst diesen Ansatz mit benutzerdefinierten Pfaddefinitionen kombinieren, um jede gewünschte Verzeichnishierarchie zu konstruieren. + +### 2.2. Ausgaben nach Prozess organisieren + +Eine beliebte Möglichkeit, Ausgaben weiter zu organisieren, ist es, sie nach Prozess zu ordnen, _d.h._ Unterverzeichnisse für jeden in der Pipeline ausgeführten Prozess zu erstellen. + +#### 2.2.1. Die Ausgabepfade durch eine Referenz auf Prozessnamen ersetzen + +Alles, was du tun musst, ist den Namen des Prozesses als `<task>.name` in der Ausgabepfad-Deklaration zu referenzieren. + +Nimm folgende Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Dies entfernt die verbleibenden hartcodierten Elemente aus der Ausgabepfad-Konfiguration. + +#### 2.2.2. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen über die Befehlszeile auf `pnames` setzen. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Dies produziert dieselbe Ausgabe wie zuvor, außer dass wir diesmal unsere Ausgaben unter `results/pnames/` finden, und sie sind nach Prozess gruppiert. + +??? abstract "Verzeichnisinhalt" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Beachte, dass wir hier die Unterscheidung zwischen `intermediates` gegenüber finalen Ausgaben auf der obersten Ebene aufgehoben haben. +Du könntest natürlich diese Ansätze mischen, zum Beispiel indem du den Pfad der ersten Ausgabe als `intermediates/${sayHello.process}` setzt. + +### 2.3. Den Veröffentlichungsmodus auf Workflow-Ebene festlegen + +Schließlich können wir im Sinne der Reduzierung von repetitivem Code die pro-Ausgabe-`mode`-Deklarationen durch eine einzelne Zeile in der Konfiguration ersetzen. + +#### 2.3.1. `workflow.output.mode` zur Konfigurationsdatei hinzufügen + +Füge folgenden Code zur `nextflow.config`-Datei hinzu: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Genau wie bei der `outputDir`-Option würde es ausreichen, `workflow.output.mode` einen Wert in der Konfigurationsdatei zu geben, um das zu überschreiben, was in der Workflow-Datei festgelegt ist, aber entfernen wir den unnötigen Code trotzdem. + +#### 2.3.2. Den Ausgabemodus aus der Workflow-Datei entfernen + +Nimm folgende Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Vorher" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +Das ist doch prägnanter, oder? + +#### 2.3.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen über die Befehlszeile auf `outmode` setzen. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Dies produziert dieselbe Ausgabe wie zuvor, außer dass wir diesmal unsere Ausgaben unter `results/outmode/` finden. +Sie sind alle noch echte Kopien, keine Symlinks. + +??? abstract "Verzeichnisinhalt" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Der Hauptgrund, warum du möglicherweise immer noch die pro-Ausgabe-Methode zum Festlegen des Modus verwenden möchtest, ist, wenn du innerhalb desselben Workflows mischen möchtest, _d.h._ einige Ausgaben kopieren und einige als Symlinks haben möchtest. + +Es gibt viele andere Optionen, die du auf diese Weise anpassen kannst, aber hoffentlich gibt dir dies einen Eindruck von der Bandbreite der Optionen und wie du sie effektiv nutzen kannst, um deinen Präferenzen gerecht zu werden. + +### Erkenntnisse + +Du weißt, wie du die Benennung und Struktur der Verzeichnisse steuerst, in denen deine Ausgaben veröffentlicht werden, sowie den Workflow-Ausgabe-Veröffentlichungsmodus. + +### Was kommt als Nächstes? + +Lerne, wie du deine Workflow-Konfiguration an deine Rechenumgebung anpasst, beginnend mit der Software-Paketierungstechnologie. + +--- + +## 3. Eine Software-Paketierungstechnologie auswählen + +Bisher haben wir uns Konfigurationselemente angesehen, die steuern, wie Eingaben hineingehen und wo Ausgaben herauskommen. Jetzt ist es an der Zeit, uns genauer auf die Anpassung deiner Workflow-Konfiguration an deine Rechenumgebung zu konzentrieren. + +Der erste Schritt auf diesem Weg ist die Angabe, woher die Softwarepakete kommen, die in jedem Schritt ausgeführt werden. +Sind sie bereits in der lokalen Rechenumgebung installiert? +Müssen wir Images abrufen und über ein Container-System ausführen? +Oder müssen wir Conda-Pakete abrufen und eine lokale Conda-Umgebung erstellen? + +Im allerersten Teil dieses Kurses (Teile 1-4) haben wir einfach lokal installierte Software in unserem Workflow verwendet. +Dann haben wir in Teil 5 Docker-Container und die `nextflow.config`-Datei eingeführt, die wir verwendet haben, um die Verwendung von Docker-Containern zu aktivieren. + +Lass uns jetzt sehen, wie wir eine alternative Software-Paketierungsoption über die `nextflow.config`-Datei konfigurieren können. + +### 3.1. Docker deaktivieren und Conda in der Config-Datei aktivieren + +Stellen wir uns vor, wir arbeiten auf einem HPC-Cluster und der Administrator erlaubt die Verwendung von Docker aus Sicherheitsgründen nicht. +Glücklicherweise unterstützt Nextflow mehrere andere Container-Technologien wie Singularity (das auf HPC weiter verbreitet ist) sowie Software-Paketmanager wie Conda. + +Wir können unsere Konfigurationsdatei ändern, um Conda anstelle von Docker zu verwenden. +Dazu ändern wir den Wert von `docker.enabled` auf `false` und fügen eine Direktive hinzu, die die Verwendung von Conda aktiviert: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Dies ermöglicht es Nextflow, Conda-Umgebungen für Prozesse zu erstellen und zu nutzen, die Conda-Pakete angegeben haben. +Das bedeutet, dass wir jetzt eines davon zu unserem `cowpy`-Prozess hinzufügen müssen! + +### 3.2. Ein Conda-Paket in der Prozessdefinition angeben + +Wir haben bereits die URI für ein Conda-Paket abgerufen, das das `cowpy`-Tool enthält: `conda-forge::cowpy==1.1.5` + +Jetzt fügen wir die URI zur `cowpy`-Prozessdefinition hinzu, indem wir die `conda`-Direktive verwenden: + +=== "Nachher" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Vorher" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Um klar zu sein, wir _ersetzen_ nicht die `docker`-Direktive, wir _fügen_ eine alternative Option hinzu. + +!!! tip "Tipp" + + Es gibt einige verschiedene Möglichkeiten, die URI für ein bestimmtes Conda-Paket zu erhalten. + Wir empfehlen die Verwendung der [Seqera Containers](https://seqera.io/containers/)-Suchabfrage, die dir eine URI gibt, die du kopieren und einfügen kannst, auch wenn du nicht vorhast, einen Container daraus zu erstellen. + +### 3.3. Den Workflow ausführen, um zu überprüfen, dass er Conda verwenden kann + +Probieren wir es aus. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Befehlsausgabe" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Dies sollte ohne Probleme funktionieren und dieselben Ausgaben wie zuvor unter `results/conda` produzieren. + +Hinter den Kulissen hat Nextflow die Conda-Pakete abgerufen und die Umgebung erstellt, was normalerweise etwas Arbeit erfordert; es ist also schön, dass wir das nicht selbst tun müssen! + +!!! note "Hinweis" + + Dies läuft schnell, weil das `cowpy`-Paket ziemlich klein ist, aber wenn du mit großen Paketen arbeitest, kann es beim ersten Mal etwas länger dauern als üblich, und du könntest sehen, dass die Konsolenausgabe für eine Minute oder so 'hängen bleibt', bevor sie abgeschlossen wird. + Das ist normal und liegt an der zusätzlichen Arbeit, die Nextflow beim ersten Mal erledigt, wenn du ein neues Paket verwendest. + +Aus unserer Sicht sieht es so aus, als würde es genauso funktionieren wie mit Docker, obwohl die Mechanik im Backend etwas anders ist. + +Das bedeutet, dass wir bereit sind, mit Conda-Umgebungen zu arbeiten, wenn nötig. + +??? info "Docker und Conda mischen" + + Da diese Direktiven pro Prozess zugewiesen werden, ist es möglich, 'zu mischen', _d.h._ einige Prozesse in deinem Workflow mit Docker und andere mit Conda auszuführen, zum Beispiel wenn die Recheninfrastruktur, die du verwendest, beides unterstützt. + In diesem Fall würdest du sowohl Docker als auch Conda in deiner Konfigurationsdatei aktivieren. + Wenn beide für einen bestimmten Prozess verfügbar sind, wird Nextflow Container priorisieren. + + Und wie bereits erwähnt, unterstützt Nextflow mehrere andere Software-Paketierungs- und Container-Technologien, du bist also nicht nur auf diese beiden beschränkt. + +### Erkenntnisse + +Du weißt, wie du konfigurierst, welches Softwarepaket jeder Prozess verwenden soll, und wie du zwischen Technologien wechseln kannst. + +### Was kommt als Nächstes? + +Lerne, wie du die Ausführungsplattform änderst, die Nextflow verwendet, um die eigentliche Arbeit zu erledigen. + +--- + +## 4. Eine Ausführungsplattform auswählen + +Bis jetzt haben wir unsere Pipeline mit dem lokalen Executor ausgeführt. +Dieser führt jede Aufgabe auf der Maschine aus, auf der Nextflow läuft. +Wenn Nextflow startet, schaut es sich die verfügbaren CPUs und den Speicher an. +Wenn die Ressourcen der zur Ausführung bereiten Aufgaben die verfügbaren Ressourcen übersteigen, hält Nextflow die letzten Aufgaben von der Ausführung zurück, bis eine oder mehrere der früheren Aufgaben abgeschlossen sind und die notwendigen Ressourcen freigeben. + +Der lokale Executor ist bequem und effizient, aber er ist auf diese einzelne Maschine beschränkt. Bei großen Arbeitslasten kann die lokale Maschine zum Engpass werden: wenn einzelne Aufgaben mehr Ressourcen brauchen als verfügbar, oder wenn zu viele Aufgaben anfallen. + +Nextflow unterstützt [viele verschiedene Ausführungs-Backends](https://www.nextflow.io/docs/latest/executor.html), einschließlich HPC-Scheduler (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor und andere) sowie Cloud-Ausführungs-Backends wie (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes und mehr). + +### 4.1. Ein anderes Backend anvisieren + +Die Wahl des Executors wird durch eine Prozess-Direktive namens `executor` festgelegt. +Standardmäßig ist sie auf `local` gesetzt, daher ist die folgende Konfiguration impliziert: + +```groovy title="Eingebaute Konfiguration" +process { + executor = 'local' +} +``` + +Um den Executor auf ein anderes Backend zu setzen, gibst du einfach den gewünschten Executor mit einer ähnlichen Syntax an, wie oben für Ressourcenzuweisungen beschrieben (siehe [Dokumentation](https://www.nextflow.io/docs/latest/executor.html) für alle Optionen). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Warnung" + + Wir können dies in der Trainingsumgebung nicht tatsächlich testen, weil sie nicht für die Verbindung mit einem HPC eingerichtet ist. + +### 4.2. Mit backend-spezifischer Syntax für Ausführungsparameter umgehen + +Die meisten Hochleistungsrechenplattformen erlauben (und erfordern manchmal), dass du bestimmte Parameter wie Ressourcenzuweisungsanfragen und -beschränkungen (z.B. Anzahl der CPUs und Speicher) und den Namen der zu verwendenden Job-Warteschlange angibst. + +Leider verwendet jedes dieser Systeme unterschiedliche Technologien, Syntaxen und Konfigurationen, um zu definieren, wie ein Job definiert und an den entsprechenden Scheduler übermittelt werden soll. + +??? abstract "Beispiele" + + Zum Beispiel muss derselbe Job, der 8 CPUs und 4GB RAM benötigt und in der Warteschlange "my-science-work" ausgeführt werden soll, je nach Backend auf unterschiedliche Weise ausgedrückt werden. + + ```bash title="Config für SLURM / Übermittlung mit sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config für PBS / Übermittlung mit qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config für SGE / Übermittlung mit qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Glücklicherweise vereinfacht Nextflow all das. +Es bietet eine standardisierte Syntax, damit du die relevanten Eigenschaften wie `cpus`, `memory` und `queue` (siehe Dokumentation für andere Eigenschaften) nur einmal angeben kannst. +Dann wird Nextflow zur Laufzeit diese Einstellungen verwenden, um die entsprechenden backend-spezifischen Scripts basierend auf der Executor-Einstellung zu generieren. + +Wir werden diese standardisierte Syntax im nächsten Abschnitt behandeln. + +### Erkenntnisse + +Du weißt jetzt, wie du den Executor änderst, um verschiedene Arten von Recheninfrastruktur zu nutzen. + +### Was kommt als Nächstes? + +Lerne, wie du Ressourcenzuweisungen und -beschränkungen in Nextflow evaluierst und ausdrückst. + +--- + +## 5. Rechenressourcen-Zuweisungen steuern + +Die meisten Hochleistungsrechenplattformen erlauben (und erfordern manchmal), dass du bestimmte Ressourcenzuweisungsparameter wie Anzahl der CPUs und Speicher angibst. + +Standardmäßig verwendet Nextflow eine einzelne CPU und 2GB Speicher für jeden Prozess. +Die entsprechenden Prozess-Direktiven heißen `cpus` und `memory`, daher ist die folgende Konfiguration impliziert: + +```groovy title="Eingebaute Konfiguration" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Du kannst diese Werte ändern, entweder für alle Prozesse oder für bestimmte benannte Prozesse, indem du zusätzliche Prozess-Direktiven in deiner Konfigurationsdatei verwendest. +Nextflow wird sie in die entsprechenden Anweisungen für den gewählten Executor übersetzen. + +Aber woher weißt du, welche Werte du verwenden sollst? + +### 5.1. Den Workflow ausführen, um einen Ressourcennutzungsbericht zu generieren + +Wenn du nicht im Voraus weißt, wie viel CPU und Speicher deine Prozesse wahrscheinlich benötigen werden, kannst du ein Ressourcen-Profiling durchführen, das heißt, du führst den Workflow mit einigen Standard-Zuweisungen aus, zeichnest auf, wie viel jeder Prozess verwendet hat, und schätzt von dort aus, wie du die Basis-Zuweisungen anpassen solltest. + +Praktischerweise enthält Nextflow eingebaute Tools dafür und wird auf Anfrage gerne einen Bericht für dich erstellen. + +Dazu füge `-with-report <filename>.html` zu deiner Befehlszeile hinzu. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Der Bericht ist eine HTML-Datei, die du herunterladen und in deinem Browser öffnen kannst. Du kannst auch mit der rechten Maustaste darauf klicken im Datei-Explorer auf der linken Seite und auf `Show preview` klicken, um ihn in der Trainingsumgebung anzuzeigen. + +Nimm dir ein paar Minuten, um den Bericht durchzusehen und zu schauen, ob du einige Möglichkeiten zur Anpassung der Ressourcen identifizieren kannst. +Klicke unbedingt auf die Tabs, die die Nutzungsergebnisse als Prozentsatz dessen zeigen, was zugewiesen wurde. +Es gibt [Dokumentation](https://www.nextflow.io/docs/latest/reports.html), die alle verfügbaren Funktionen beschreibt. + +### 5.2. Ressourcenzuweisungen für alle Prozesse festlegen + +Das Profiling zeigt, dass die Prozesse in unserem Trainings-Workflow sehr leichtgewichtig sind, also reduzieren wir die Standard-Speicherzuweisung auf 1GB pro Prozess. + +Füge Folgendes zu deiner `nextflow.config`-Datei hinzu, vor dem Pipeline-Parameter-Abschnitt: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Das wird helfen, den Rechenverbrauch zu reduzieren. + +### 5.3. Ressourcenzuweisungen für einen bestimmten Prozess festlegen + +Gleichzeitig werden wir so tun, als ob der `cowpy`-Prozess mehr Ressourcen benötigt als die anderen, nur um zu demonstrieren, wie man Zuweisungen für einen einzelnen Prozess anpasst. + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Mit dieser Konfiguration werden alle Prozesse 1GB Speicher und eine einzelne CPU (der implizierte Standard) anfordern, außer dem `cowpy`-Prozess, der 2GB und 2 CPUs anfordern wird. + +!!! tip "Tipp" + + Wenn du eine Maschine mit wenigen CPUs hast und eine hohe Anzahl pro Prozess zuweist, könntest du sehen, dass Prozessaufrufe hintereinander in die Warteschlange gestellt werden. + Das liegt daran, dass Nextflow sicherstellt, dass wir nicht mehr CPUs anfordern als verfügbar sind. + +### 5.4. Den Workflow mit der aktualisierten Konfiguration ausführen + +Probieren wir das aus, indem wir einen anderen Dateinamen für den Profiling-Bericht angeben, damit wir die Leistung vor und nach den Konfigurationsänderungen vergleichen können. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Du wirst wahrscheinlich keinen echten Unterschied bemerken, da dies eine so kleine Arbeitslast ist, aber das ist der Ansatz, den du verwenden würdest, um die Leistung und Ressourcenanforderungen eines realen Workflows zu analysieren. + +Es ist sehr nützlich, wenn deine Prozesse unterschiedliche Ressourcenanforderungen haben. Es ermöglicht dir, die Ressourcenzuweisungen, die du für jeden Prozess einrichtest, basierend auf tatsächlichen Daten richtig zu dimensionieren, nicht auf Vermutungen. + +!!! tip "Tipp" + + Dies ist nur ein kleiner Vorgeschmack dessen, was du tun kannst, um deine Ressourcennutzung zu optimieren. + Nextflow selbst hat eine wirklich raffinierte [dynamische Wiederholungslogik](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) eingebaut, um Jobs, die aufgrund von Ressourcenbeschränkungen fehlschlagen, automatisch zu wiederholen. + Zusätzlich bietet die Seqera Platform KI-gestützte Tools zur automatischen Optimierung deiner Ressourcenzuweisungen. + +### 5.5. Ressourcenlimits hinzufügen + +Abhängig davon, welchen Rechen-Executor und welche Recheninfrastruktur du verwendest, kann es Einschränkungen geben, was du zuweisen kannst (oder musst). +Zum Beispiel kann dein Cluster erfordern, dass du innerhalb bestimmter Grenzen bleibst. + +Du kannst die `resourceLimits`-Direktive verwenden, um die relevanten Beschränkungen festzulegen. Die Syntax sieht so aus, wenn sie allein in einem Process-Block steht: + +```groovy title="Syntax-Beispiel" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow wird diese Werte in die entsprechenden Anweisungen übersetzen, abhängig vom Executor, den du angegeben hast. + +Wir werden das nicht ausführen, da wir in der Trainingsumgebung keinen Zugang zu relevanter Infrastruktur haben. +Wenn du jedoch versuchen würdest, den Workflow mit Ressourcenzuweisungen auszuführen, die diese Limits überschreiten, und dann den `sbatch`-Befehl in der `.command.run`-Script-Datei nachschlagen würdest, würdest du sehen, dass die Anfragen, die tatsächlich an den Executor gesendet werden, bei den durch `resourceLimits` angegebenen Werten gedeckelt sind. + +??? info "Institutionelle Referenzkonfigurationen" + + Das nf-core-Projekt hat eine [Sammlung von Konfigurationsdateien](https://nf-co.re/configs/) zusammengestellt, die von verschiedenen Institutionen weltweit geteilt werden und eine breite Palette von HPC- und Cloud-Executors abdecken. + + Diese geteilten Configs sind sowohl für Personen wertvoll, die dort arbeiten und daher einfach die Konfiguration ihrer Institution direkt nutzen können, als auch als Modell für Personen, die eine Konfiguration für ihre eigene Infrastruktur entwickeln möchten. + +### Erkenntnisse + +Du weißt, wie du einen Profiling-Bericht erstellst, um die Ressourcennutzung zu bewerten, und wie du Ressourcenzuweisungen für alle Prozesse und/oder für einzelne Prozesse änderst sowie Ressourcenbeschränkungen für die Ausführung auf HPC festlegst. + +### Was kommt als Nächstes? + +Lerne, wie du voreingestellte Konfigurationsprofile einrichtest und zur Laufzeit zwischen ihnen wechselst. + +--- + +## 6. Profile verwenden, um zwischen voreingestellten Konfigurationen zu wechseln + +Wir haben dir eine Reihe von Möglichkeiten gezeigt, wie du deine Pipeline-Konfiguration anpassen kannst, abhängig vom Projekt, an dem du arbeitest, oder der Rechenumgebung, die du verwendest. + +Möglicherweise möchtest du zwischen alternativen Einstellungen wechseln, abhängig davon, welche Recheninfrastruktur du verwendest. Zum Beispiel könntest du lokal auf deinem Laptop entwickeln und kleine Tests durchführen, dann vollständige Arbeitslasten auf HPC oder Cloud ausführen. + +Nextflow ermöglicht es dir, beliebig viele Profile einzurichten, die verschiedene Konfigurationen beschreiben, die du dann zur Laufzeit mit einem Befehlszeilenargument auswählen kannst, anstatt die Konfigurationsdatei selbst ändern zu müssen. + +### 6.1. Profile für den Wechsel zwischen lokaler Entwicklung und Ausführung auf HPC erstellen + +Lass uns zwei alternative Profile einrichten; eines für die Ausführung kleiner Lasten auf einem normalen Computer, wo wir Docker-Container verwenden werden, und eines für die Ausführung auf einem Universitäts-HPC mit einem Slurm-Scheduler, wo wir Conda-Pakete verwenden werden. + +#### 6.1.1. Die Profile einrichten + +Füge Folgendes zu deiner `nextflow.config`-Datei hinzu, nach dem Pipeline-Parameter-Abschnitt, aber vor den Ausgabe-Einstellungen: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Du siehst, dass wir für das Universitäts-HPC auch Ressourcenbeschränkungen angeben. + +#### 6.1.2. Den Workflow mit einem Profil ausführen + +Um ein Profil in unserer Nextflow-Befehlszeile anzugeben, verwenden wir das Argument `-profile`. + +Versuchen wir, den Workflow mit der `my_laptop`-Konfiguration auszuführen. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Wie du sehen kannst, ermöglicht uns das, zur Laufzeit sehr bequem zwischen Konfigurationen zu wechseln. + +!!! warning "Warnung" + + Das `univ_hpc`-Profil wird in der Trainingsumgebung nicht richtig funktionieren, da wir keinen Zugang zu einem Slurm-Scheduler haben. + +Wenn wir in Zukunft andere Konfigurationselemente finden, die immer mit diesen zusammen auftreten, können wir sie einfach zu den entsprechenden Profilen hinzufügen. +Wir können auch zusätzliche Profile erstellen, wenn es andere Konfigurationselemente gibt, die wir zusammenfassen möchten. + +### 6.2. Ein Profil mit Testparametern erstellen + +Profile sind nicht nur für Infrastrukturkonfiguration. +Wir können sie auch verwenden, um Standardwerte für Workflow-Parameter festzulegen, um es anderen zu erleichtern, den Workflow auszuprobieren, ohne selbst geeignete Eingabewerte sammeln zu müssen. +Du kannst dies als Alternative zur Verwendung einer Parameterdatei betrachten. + +#### 6.2.1. Das Profil einrichten + +Die Syntax zum Ausdrücken von Standardwerten in diesem Kontext sieht so aus, für ein Profil, das wir `test` nennen: + +```groovy title="Syntax-Beispiel" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Wenn wir ein Testprofil für unseren Workflow hinzufügen, wird der `profiles`-Block zu: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Genau wie bei technischen Konfigurationsprofilen kannst du mehrere verschiedene Profile einrichten, die Parameter unter beliebigen Namen angeben. + +#### 6.2.2. Den Workflow lokal mit dem Testprofil ausführen + +Praktischerweise schließen sich Profile nicht gegenseitig aus, sodass wir mehrere Profile in unserer Befehlszeile mit der folgenden Syntax angeben können: `-profile <profile1>,<profile2>` (für beliebig viele Profile). + +Wenn du Profile kombinierst, die Werte für dieselben Konfigurationselemente festlegen und in derselben Konfigurationsdatei beschrieben sind, wird Nextflow den Konflikt lösen, indem es den Wert verwendet, den es zuletzt gelesen hat (_d.h._ was später in der Datei kommt). +Wenn die widersprüchlichen Einstellungen in verschiedenen Konfigurationsquellen festgelegt sind, gilt die Standard-[Vorrangordnung](https://www.nextflow.io/docs/latest/config.html). + +Versuchen wir, das Testprofil zu unserem vorherigen Befehl hinzuzufügen: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Dies wird Docker wo möglich verwenden und Ausgaben unter `results/test` produzieren, und diesmal ist der Charakter das komische Duo `dragonandcow`. + +??? abstract "Dateiinhalt" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + ... + ``` + +### Erkenntnisse + +Du weißt, wie du Profile erstellst, um einfach zwischen voreingestellten Konfigurationsoptionen zur Laufzeit zu wechseln. + +### Was kommt als Nächstes? + +Herzlichen Glückwunsch, du hast Hello Nextflow abgeschlossen! + +Mach eine Pause und klopfe dir auf die Schulter. Du hast heute viel gelernt und bist nun bereit, die Welt der Nextflow-Workflow-Entwicklung zu erkunden. + +Gehe zu [**Nächste Schritte**](./next_steps.md) weiter, um zu sehen, was du als Nächstes tun kannst. diff --git a/docs/de/docs/hello_nextflow/index.md b/docs/de/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..7525ad0ac3 --- /dev/null +++ b/docs/de/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Starten und Verwalten der Ausführung von Nextflow-Workflows + - Finden und Interpretieren von Ausgaben (Ergebnissen) und Log-Dateien, die von Nextflow generiert werden + - Beheben grundlegender Probleme + - Erstellen eines einfachen mehrstufigen Workflows aus Nextflow-Kernkomponenten + - Unterscheiden zwischen wesentlichen Arten von channel factories und Operatoren und deren effektive Nutzung in einem einfachen Workflow + - Konfigurieren der Pipeline-Ausführung für gängige Rechenplattformen einschließlich HPC und Cloud + - Anwenden von Best Practices für Reproduzierbarkeit, Portabilität und Code-Wiederverwendung, die Pipelines FAIR machen, einschließlich Code-Modularität und Software-Container + audience_prerequisites: + - "**Zielgruppe:** Dieser Kurs ist für Lernende konzipiert, die komplett neu bei Nextflow sind und eigene Pipelines entwickeln möchten." + - "**Fähigkeiten:** Grundlegende Vertrautheit mit der Befehlszeile, grundlegenden Scripting-Konzepten und gängigen Dateiformaten wird vorausgesetzt." + - "**Fachgebiet:** Die Übungen sind alle fachgebietsunabhängig, daher ist kein wissenschaftliches Vorwissen erforderlich." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow ist eine praxisorientierte Einführung in den Aufbau reproduzierbarer und skalierbarer Datenanalyse-Workflows.** + +In praktischen Übungen lernst du die Pipeline-Entwicklung mit Nextflow: Prozesse definieren, Pipelines verbinden, Dateien und Dependencies verwalten, Ausführung parallelisieren und Workflows in verschiedenen Umgebungen starten. + +Nach diesem Kurs kannst du eigene Workflows mit Nextflow entwickeln und ausführen. + +<!-- additional_information --> + +## Kursübersicht + +Dieser Kurs ist praxisorientiert konzipiert, mit zielgerichteten Übungen, die Informationen schrittweise einführen. + +Du wirst eine einfache Nextflow-Pipeline entwickeln, die einige Texteingaben nimmt, einige Transformationsschritte ausführt und eine einzelne Textdatei mit einem ASCII-Bild einer Figur ausgibt, die den transformierten Text sagt. + +### Lektionsplan + +Um dich nicht mit Konzepten und Code zu überfordern, haben wir dies in sechs Teile aufgeteilt, die sich jeweils auf bestimmte Aspekte der Pipeline-Entwicklung mit Nextflow konzentrieren. + +| Kurskapitel | Zusammenfassung | Geschätzte Dauer | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| [Teil 1: Hello World](./01_hello_world.md) | Grundlegende Komponenten und Prinzipien beim Zusammenstellen und Ausführen eines Nextflow-Workflows | 30 Min. | +| [Teil 2: Hello Channels](./02_hello_channels.md) | Verwendung von channels und Operatoren zur Verarbeitung von Eingaben und müheloser Parallelisierung | 45 Min. | +| [Teil 3: Hello Workflow](./03_hello_workflow.md) | Verwendung von channels zum Verketten mehrerer Schritte und Handhabung des Datentransfers zwischen Schritten | 60 Min. | +| [Teil 4: Hello Modules](./04_hello_modules.md) | Anwendung von Code-Modularitätsprinzipien zur Erhöhung der Wiederverwendbarkeit und Verringerung des Wartungsaufwands | 20 Min. | +| [Teil 5: Hello Containers](./05_hello_containers.md) | Verwendung von Containern als Mechanismus zur Verwaltung von Software-Abhängigkeiten und Erhöhung der Reproduzierbarkeit | 60 Min. | +| [Teil 6: Hello Config](./06_hello_config.md) | Anpassung des Pipeline-Verhaltens und Optimierung der Nutzung in verschiedenen Rechenumgebungen | 60 Min. | + +Nach Abschluss dieses Kurses bist du bereit, reproduzierbare Workflows für deine eigenen Projekte zu entwickeln. + +Bereit, den Kurs zu starten? + +[Los geht's :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/de/docs/hello_nextflow/next_steps.md b/docs/de/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..91017fbe44 --- /dev/null +++ b/docs/de/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Kurszusammenfassung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herzlichen Glückwunsch zum Abschluss des Hello Nextflow-Trainingskurses! + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Siehe die [ganze Playlist auf dem Nextflow YouTube-Kanal](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Du kannst das [Video-Transkript](./transcripts/07_next_steps.md) neben dem Video lesen. +/// + +## Dein Weg + +Du hast mit einem einfachen Workflow begonnen, der einen fest codierten Befehl ausführte. +Im Laufe von sechs Teilen hast du diesen einfachen Workflow in eine modulare mehrstufige Pipeline verwandelt, die wichtige Funktionen von Nextflow nutzt, einschließlich channels, Operatoren, integrierter Container-Unterstützung und Konfigurationsoptionen. + +### Was du gebaut hast + +- Die endgültige Form des Hello-Workflows nimmt als Eingabe eine CSV-Datei mit Textbegrüßungen. +- Die vier Schritte sind als Nextflow-Prozesse implementiert (`sayHello`, `convertToUpper`, `collectGreetings` und `cowpy`), die in separaten Moduldateien gespeichert sind. +- Die Ergebnisse werden in einem Verzeichnis namens `results/` veröffentlicht. +- Die endgültige Ausgabe der Pipeline ist eine einfache Textdatei mit ASCII-Kunst einer Figur, die die in Großbuchstaben konvertierten Begrüßungen sagt. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Schreibt jede Begrüßung in ihre eigene Ausgabedatei (_z.B._ "Hello-output.txt") +2. **`convertToUpper`:** Konvertiert jede Begrüßung in Großbuchstaben (_z.B._ "HELLO") +3. **`collectGreetings`:** Sammelt alle Großbuchstaben-Begrüßungen in einer einzigen Batch-Datei +4. **`cowpy`:** Generiert ASCII-Kunst mit dem `cowpy`-Tool + +Die Workflow-Konfiguration unterstützt die flexible und reproduzierbare Bereitstellung von Eingaben und Parametern. + +### Erworbene Fähigkeiten + +Durch diesen praxisorientierten Kurs hast du gelernt, wie du: + +- Nextflow-Kernkomponenten beschreiben und nutzen kannst, um einen einfachen mehrstufigen Workflow zu erstellen +- Weiterführende Konzepte wie Operatoren und channel factories beschreiben kannst +- Einen Nextflow-Workflow lokal starten kannst +- Ausgaben (Ergebnisse) und Log-Dateien, die von Nextflow generiert werden, finden und interpretieren kannst +- Grundlegende Probleme beheben kannst + +Du bist jetzt mit dem Grundwissen ausgestattet, um eigene Pipelines in Nextflow zu entwickeln. + +## Nächste Schritte zum Aufbau deiner Fähigkeiten + +Hier sind unsere Top-3-Vorschläge, was du als Nächstes tun solltest: + +- Wende Nextflow auf einen wissenschaftlichen Analyse-Anwendungsfall an mit [Nextflow für die Wissenschaft](../nf4_science/index.md) +- Starte mit nf-core mit [Hello nf-core](../../hello_nf-core/index.md) +- Erkunde fortgeschrittenere Nextflow-Funktionen mit den [Side Quests](../side_quests/index.md) + +Schließlich empfehlen wir dir, einen Blick auf [**Seqera Platform**](https://seqera.io/) zu werfen, eine Cloud-basierte Plattform, die von den Entwicklern von Nextflow entwickelt wurde und es noch einfacher macht, deine Workflows zu starten und zu verwalten, sowie deine Daten zu verwalten und Analysen interaktiv in jeder Umgebung auszuführen. + +## Feedback-Umfrage + +Bevor du weitermachst, nimm dir bitte eine Minute Zeit, um die Kursumfrage auszufüllen! Dein Feedback hilft uns, unsere Trainingsmaterialien für alle zu verbessern. + +[Zur Umfrage :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/de/docs/hello_nextflow/survey.md b/docs/de/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..b030b73956 --- /dev/null +++ b/docs/de/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Feedback-Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bevor du weitermachst, fülle bitte diese kurze 5-Fragen-Umfrage aus, um das Training zu bewerten und uns Feedback zu geben. + +Das sollte weniger als eine Minute dauern. Vielen Dank, dass du uns hilfst, unsere Trainingsmaterialien für alle zu verbessern! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/de/docs/hello_nextflow/transcripts/00_orientation.md b/docs/de/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..00e9f653bf --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Einführung - Video-Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtiger Hinweis" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../00_orientation.md) zurück. + +## Willkommen + +Hallo, willkommen zu Hello Nextflow. Mein Name ist Phil Ewels. Ich bin Product Manager für Open Source bei Seqera und freue mich sehr, dich heute durch diesen ersten Nextflow-Trainingskurs zu führen. + +Wir werden die Grundlagen von Nextflow durchgehen und erklären, wie man Pipelines schreibt, ausführt und konfiguriert. + +Und du wirst deine eigene einfache mehrstufige Pipeline erstellen. Wir werden Begriffe wie Operatoren und Channel Factories behandeln, und am Ende des Kurses bist du bereit, mit dem Erstellen deiner eigenen Bioinformatik-Pipelines zu beginnen. + +Falls du Fragen hast, melde dich bitte auf community.seqera.io. Wir haben dort eine sehr aktive Nextflow-Community mit einem Bereich, der speziell dem Training gewidmet ist. Lass uns einfach wissen, wo du nicht weiterkommst, und jemand wird dir helfen können. + +Gut. Dann lass uns anfangen. + +## Trainings-Website + +Das gesamte Trainingsmaterial für die Nextflow-Kurse findest du auf training.nextflow.io. Du kannst es in deinem Webbrowser aufrufen. Starte das jetzt und wir können uns gemeinsam umschauen. + +Ich werde das mit Version 2.1.1 durchführen. Wir veröffentlichen hier und da kleinere Updates und Korrekturen. Wenn es also ein wenig abweicht, ist das kein Problem. Sollte das Material aber zu weit abgedriftet sein, kannst du immer diese Versionsauswahl oben verwenden, um genau die Version des Materials auszuwählen, über die ich sprechen werde. + +Wenn du eher ein Heller-Modus-Mensch bist, kannst du das Theme für die Website hier ändern. + +Hier findest du auch Übersetzungen, auch wenn zum Zeitpunkt der Aufnahme wirklich nur Englisch verfügbar ist, das dieses neue Material abdeckt. + +Und du kannst auch den gesamten Quellcode für die Trainings-Website und alles, womit wir arbeiten werden, auf GitHub einsehen. + +Die Startseite hier listet alle verschiedenen Trainingsmaterial-Kurse auf, die wir haben. Wenn ich nach unten scrolle, sehen wir Nextflow for newcomers mit dem Hello Nextflow-Kurs, den wir hier machen werden. Du siehst auch alle anderen Kurse, die wir haben und die auf ähnliche Weise funktionieren. + +## Umgebungseinrichtung + +Ich werde tatsächlich mit diesem ersten ganz oben beginnen, der für alle Trainingskurse gemeinsam ist, und es geht speziell um die Einrichtung unserer Umgebung. + +Ich klicke darauf, und es bringt mich zu diesem Abschnitt, wo wir Anweisungen für die lokale Entwicklung sehen können. Wenn du deinen eigenen Laptop mit deiner eigenen Kopie von VS Code und deinen eigenen Software-Installationen verwenden möchtest, oder was wir von den meisten Leuten erwarten, nämlich etwas namens GitHub Codespaces zu verwenden. + +Codespaces ist ein von GitHub bereitgestellter Service, bei dem ein Webserver in der Cloud ausgeführt wird, mit dem du dich verbinden kannst. Auf diesem Server ist VS Code installiert, das du in deinem Webbrowser ausführen kannst, oder wenn du möchtest, mit deiner lokalen Installation von VS Code verbinden kannst. Die gesamte Berechnung, alle Dateien, alle Bearbeitungen geschehen remote, was bedeutet, dass die gesamte Software, die du benötigst, vorinstalliert ist und für alle gleich ist. + +## Erstellen eines GitHub Codespace + +Um den Codespace mit allem, was wir brauchen, zu erstellen, suche nach den Buttons im Dokumentationsmaterial, die "Open in GitHub Codespaces" sagen. Ich werde das jetzt anklicken und in einem neuen Tab öffnen. Und mir wird diese Webseite präsentiert. Du siehst, dass dies vorkonfiguriert ist mit nextflow-io training. + +Ich kann einfach auf create new codespace klicken. Aber tatsächlich empfehlen wir, eine etwas größere Maschine für das Nextflow-Training mit vier CPUs statt zwei zu verwenden. Du kannst ändern, welche Version des Materials verwendet wird. Das ist standardmäßig auf 2.1.1 eingestellt, weil das die Version der Dokumentation ist, von der ich den Link gefolgt bin. Aber ich könnte es auch auf einen bestimmten Branch des Repositorys setzen, wenn ich möchte. + +Jetzt werde ich auf create codespace klicken. Und es wird beginnen, die Umgebung für mich einzurichten. + +## Codespace-Erstellung + +Beim ersten Mal wird das ziemlich lange dauern, also ist jetzt ein guter Zeitpunkt, um eine Tasse Tee zu holen. Mach es dir bequem, unterhalte dich mit der Person neben dir. + +Wenn es dich interessiert, kannst du hier auf building codespace klicken, um die Logs der Einrichtung zu sehen. Und du siehst hier, dass es ein Docker-Image mit allem, was ich brauche, herunterlädt und die Umgebung konfiguriert. + +Du musst nur beim ersten Mal so lange warten, wenn du einen Codespace erstellst. Wenn du zu github.com/codespaces gehst, siehst du alle verschiedenen Codespaces, die du geöffnet hast. Hier ist der, den ich gerade erstellt habe. Beim nächsten Mal kannst du hierher gehen und den vorherigen Codespace auswählen und direkt wieder hineinspringen. Und es ist ein viel, viel schnellerer Prozess, diese bestehende Umgebung aufzuwärmen. Das behält auch alle Änderungen bei, die du an VS Code und an den Dateien vorgenommen hast, sodass du deinen Fortschritt nicht verlierst, wenn du gehst und zurückkommst. + +Du kannst hier auf die drei Punkte klicken, um andere Aktionen durchzuführen. Zum Beispiel, wenn du ihn mit zwei CPUs konfiguriert hast und jetzt vier möchtest, kannst du den Maschinentyp ändern. Oder wenn du von vorne anfangen und einen frischen Start haben möchtest, kannst du den Codespace löschen. + +## Einführung in VS Code + +Okay, Codespaces ist mit der Einrichtung meiner Umgebung fertig und präsentiert mir jetzt VS Code im Webbrowser. + +Wenn du VS Code kennst, wird sich das sehr vertraut anfühlen. Falls du es noch nicht benutzt hast, ist es ziemlich einfach. Es gibt ein paar verschiedene Teile der Seite, die du kennen solltest. + +Hier auf der linken Seite haben wir die Seitenleiste. Du siehst den Explorer mit all den verschiedenen Dateien aus dem GitHub-Repository des Training-Repos. + +Mit diesen Buttons unten links können verschiedene Werkzeuge in der Seitenleiste angezeigt werden. Ich kann alle Dateien im gesamten Projekt durchsuchen. Ich kann mit Git arbeiten, kann mit GitHub arbeiten, all solche verschiedenen Dinge. + +Oben ist das Hauptmenü. Der Datei-Explorer ist derjenige, den wir hier am meisten offen haben werden, und du kannst mit der rechten Maustaste auf eine dieser Dateien klicken und die normalen Dinge tun, die du erwarten würdest. Möglicherweise musst du einige Warnungen wie diese durchklicken, wo es um Ausschneiden und Kopieren geht, und du kannst auch auf deine lokale Maschine herunterladen. + +Wenn der Codespace lädt, zeigt er uns eine Vorschau der Markdown-Datei in diesem Hauptbereich hier. Das ist genau dasselbe wie das, was auf github.com gerendert wird. Ich kann das schließen, und wenn ich doppelt auf diese Readme-Datei klicke, siehst du, dass sie als Code im Code-Editor geöffnet wird, und genau wie bei jeder anderen Datei können wir diesen Code direkt bearbeiten. + +Schließlich haben wir hier unten das Terminalfenster. Ich habe mir die Logs beim Erstellen angesehen, also ist das, was es gerade zeigt. Ich kann auch diesen Plus-Button drücken, um eine neue Terminal-Sitzung zu starten. Das läuft nicht auf meiner Maschine. Denk daran, das läuft in der Cloud, und wenn ich tree mit Tiefe zwei mache, siehst du alle dieselben Dateien hier, die auch links waren. + +## Nur "hello-nextflow"-Dateien anzeigen + +Dieses GitHub-Repository enthält alle verschiedenen Trainingssets, nicht nur das, was wir machen. Wenn du möchtest, kannst du dich nur auf den Hello-Nextflow-Ordner konzentrieren. Eine Möglichkeit, das ein wenig aufzuräumen, ist, zum Menü Datei zu gehen und dann "Ordner zum Arbeitsbereich hinzufügen" auszuwählen. + +Wir klicken darauf, gehen zu training, Hello nextflow, und klicken auf Hinzufügen. Es wird deinen Bildschirm aktualisieren. Und dann haben wir im Explorer jetzt zwei verschiedene Arbeitsbereiche, den, den wir vorher für training hatten, und einen mit nur Hello Nextflow. + +Wenn du möchtest, kannst du mit der rechten Maustaste auf training klicken und "Ordner aus Arbeitsbereich entfernen" klicken, um ihn vollständig aus der Seitenleiste zu entfernen. + +Jetzt haben wir nur die Dateien für diesen bestimmten Trainingskurs in der Seitenleiste. Ich kann diese Warnung ausblenden, und jetzt kann ich dasselbe im Terminal hier machen und cd für Verzeichniswechsel machen. Hello Nextflow. Und wieder haben wir hier dieselben Dateien, die in der Seitenleiste sind. + +## Hello Nextflow: Dateien + +Schauen wir uns diese Dateien für den Hello-Nextflow-Kurs an. + +Wir haben eine Reihe von .nf-Dateien, die für Nextflow sind, und es gibt eine dieser Dateien für jedes Kapitel des Trainingskurses. Wir werden diese Dateien durcharbeiten und sie in den Übungen modifizieren. + +Wir haben auch eine nextflow.config-Datei, die nur grundlegende Konfigurationseinstellungen für das Ausführen von Nextflow in dieser Umgebung enthält, um die du dir zu diesem Zeitpunkt keine Sorgen machen musst. Eine greetings.csv-Datei, die wir für die Verarbeitung von Daten verwenden werden und die im nächsten Teil dieses Kurses eingeführt wird, und eine test-params.json-Datei, die in Teil sechs verwendet wird und die du vorerst ignorieren kannst. + +Diese Nextflow-Dateien sind nur der Anfang jeder Übung. Wenn du sehen möchtest, wie sie aussehen sollten, wenn sie fertig sind, kannst du in ein solutions-Verzeichnis gehen, und dort sind die Antworten für jeden Teil des Trainingskurses, sodass du eine funktionierende Version dessen sehen kannst, worauf du hinarbeitest. + +## Ein Terminal öffnen + +Falls du irgendwann das Terminal schließt und dich nicht erinnern kannst, wie du zurückkommst, mach dir keine Sorgen. Diese Buttons oben rechts öffnen und schließen verschiedene Panels im Arbeitsbereich. Klick also auf dieses hier für das untere Panel und es wird wieder erscheinen. Und stelle nur sicher, dass du hier terminal ausgewählt hast. Du kannst auch diesen Button hier klicken, den Pfeil auf der rechten Seite eines Terminals, um es im Vollbildmodus anzuzeigen. + +Du wirst sehen, dass ich das ziemlich oft mache, weil ich VS Code vergrößert habe, damit du den Text lesen kannst. Abhängig von deiner Bildschirmgröße musst du das möglicherweise tun oder auch nicht. Dasselbe gilt für das Minimieren des Seitenpanels. + +Gut. Das reicht für die Umgebung. Ich denke, wir sind bereit anzufangen. Komm im nächsten Video zu mir zurück für Kapitel eins. + +[Nächstes Video-Transkript :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/de/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..820eae9e2f --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Teil 1: Hello World - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../01_hello_world.md) zurück. + + Die im Transkript angegebenen Abschnittsnummern dienen nur zur Orientierung und umfassen möglicherweise nicht alle Abschnittsnummern des Materials. + +## Willkommen + +Hi, willkommen zu Kapitel Eins von Hello Nextflow. + +In diesem ersten Teil eines sechsteiligen Kurses gehen wir auf die grundlegenden Basics von Nextflow ein. Wir beginnen damit, einige Befehle in einem Terminal auszuführen, und dann schauen wir uns an, wie wir diese Bash-Befehle in ein Nextflow-Skript einbauen können. + +Wir werden versuchen, diese erste Nextflow-Pipeline auszuführen, sehen, was Nextflow macht, wo es läuft, welche Dateien es erstellt und was der Zweck dieser Dateien ist. + +Also gut, legen wir los. + +## training.nextflow.io + +Als Erstes, geh zu training.nextflow.io. Genau wie vorher ist das gesamte Material hier verfasst, und ich werde es Schritt für Schritt durcharbeiten. Ich zeige meinen Bildschirm, während ich die Schritte des Trainings durchführe, aber alles, was ich sage, steht im Trainingsmaterial, sodass du es in deinem eigenen Tempo verfolgen kannst und dort alles geschrieben findest. + +Dieses Video hat auch Videotranskript aktiviert, also fühl dich frei, diese einzuschalten und genau zu verfolgen, was ich sage, während ich es sage. + +Okay, gehen wir zu Hello Nextflow. Das ist der Kurs, den wir heute machen werden, und wir haben die Orientierung bereits im ersten Video gemacht, also gehen wir direkt zu Teil eins. Hello World. + +Okay, ich verlasse jetzt dieses Trainingsmaterial und wechsle in meine Code Spaces-Umgebung. Das ist das, was wir im ersten Video eingerichtet haben. Hoffentlich hast du etwas, das sehr ähnlich aussieht in deinem eigenen System. Ich verwende VS Code und schaue mir das Trainingsmaterial an, und ich habe das Verzeichnis in das hello Nextflow-Verzeichnis gewechselt. + +## 0. Aufwärmen: Hello World direkt ausführen + +Okay. Beginnen wir mit ein paar Basics, die hoffentlich jedem vertraut vorkommen. Ich fange einfach an, indem ich einen sehr einfachen Befehl im Terminal schreibe. Hier unten werde ich sagen 'echo Hello World!"' Enter drücken und, keine Überraschungen, das Terminal macht, was ich verlange, und gibt diesen String zurück. Hello World. + +Okay, dann drücke ich nach oben, um diesen Befehl zu holen und ihn ein bisschen mehr zu bearbeiten. Lass uns diesmal diese Ausgabe in eine Datei umleiten. Ich werde es stattdessen in output.txt schreiben und Enter drücken, nichts im Terminal dieses Mal, weil die Ausgabe nicht ins Terminal kam. Sie ging in diese Datei. + +Ich kann dann diese Datei lesen, indem ich 'cat output.txt' mache, drücke dort Tab, um den Dateinamen automatisch zu erweitern, und da ist es. Die Datei ist da. + +Ich kann diese Datei auch in der Seitenleiste im Datei-Explorer in VS Code sehen. Ich kann sie doppelklicken und hier öffnen. Wenn du sie in VS Code öffnen möchtest, ohne etwas anzuklicken, kannst du auch "code" und dann "output.txt" machen, und es macht das Gleiche. + +Großartig. Das ist der erste Schritt. Sehr einfach. + +## 1. Das Hello World Workflow-Starterskript untersuchen + +Okay. Wir werden jetzt genau das Gleiche machen, aber in Nextflow, anstatt direkt im Terminal. + +Wir werden das erste Beispielskript verwenden, um zu beginnen, diese Datei heißt Hello World. Ich kann "ls" machen, um es in einem Terminal anzuzeigen, und ich bin auf Mac, also kann ich Befehl-Klick machen, um diese Datei zu öffnen, oder ich hätte einfach in der Seitenleiste hier doppelklicken können. + +Es gibt ein paar Dinge, die wir in dieser Datei sehen können. Ganz oben gibt es eine Hash-Anweisung, die sagt, dass dies eine Nextflow-Datei ist und wie sie ausgeführt werden könnte. Es gibt hier einige Kommentare, nur reguläre Code-Kommentare in hellgrau, die die Ausführung nicht beeinflussen und uns nur helfen, das Skript zu lesen. + +Und dann gibt es zwei Hauptstrukturen. Es gibt hier einen Process und einen Workflow. + +Processes in Nextflow sind die Schritte der Pipeline. Sie sind die Teile, die tatsächlich die Logik ausführen und die Verarbeitung durchführen. + +Der Workflow dann am Ende fügt diese Processes zusammen und steuert die Logik des Workflows, wie alles miteinander verbunden ist. + +Wir beginnen damit, uns einen Process anzusehen. Wir kommen gleich zum Workflow zurück. + +## 1.2 Die Process-Definition + +Also beginnt jeder Process mit einem Schlüsselwort process. Hat einen Namen und dann hat es einige geschweifte Klammern, und alles innerhalb dieser geschweiften Klammern ist dieser einzelne Process. + +Ein Process muss einen Script-Abschnitt haben, und hier enthalten ist ein Bash-Snippet in einem mehrzeiligen String, der der Teil des Codes ist, der tatsächlich in der Rechenumgebung ausgeführt wird. + +Wir haben hier auch eine Output-Anweisung, die Nextflow mitteilt, welche Dateien vom Script erstellt werden sollen. Beachte, dass die Ausgabe hier ein Schlüsselwort path hat, das Nextflow mitteilt, dass dies eine Datei ist, kein Wert oder ein String. + +Innerhalb des Script-Blocks ist dies nur eine reguläre Bash-Anweisung, und es ist genau das Gleiche wie das, was wir im Terminal geschrieben haben. Wir echoieren Hello World in eine Datei namens output.txt. Dieses output.txt wird dann von der Output-Definition aufgenommen. Die Output-Definition macht eigentlich nichts. Sie teilt Nextflow nur mit, was zu erwarten ist, und wenn diese Datei nicht erstellt würde, würde Nextflow einen Fehler werfen. + +Beachte, dass dieses Beispiel kein großartiges ist, weil wir den Dateinamen hier hartcodiert haben, output.txt und output.txt. Wenn eines davon geändert würde, würde das einen Fehler in unserem Workflow verursachen. + +Es gibt einen besseren Weg, dies mit Variablen zu tun, was wir gleich behandeln werden. + +## 1.3 Die Workflow-Definition + +Okay. Wenn wir nach unten zum Workflow gehen, können wir sehen, dass wir einen Kommentar haben und dann führen wir den Process namens sayHello aus. Dies ist das gleiche Schlüsselwort, das hier oben ist. Dies ist so einfach, wie ein Workflow sein kann. Wir rufen nur einen einzelnen Process ohne variable Eingabe auf, also verbinden wir ihn nicht mit etwas anderem. Im späteren Teil dieses Kurses werden wir darüber sprechen, wie man dies leistungsfähiger macht, indem man variable Eingaben verwendet und Dinge mit Channels verbindet. + +## 2. Den Workflow ausführen + +Okay, das ist alles, was wir brauchen. Lass uns sehen, ob wir es ausführen können und sehen, was passiert. Ich werde einfach das Terminal löschen und dann werde ich "nextflow run" machen, und ich werde den Dateinamen aufrufen, der hello-world.nf ist. Das ist alles, was wir brauchen, um eine Nextflow-Pipeline auszuführen. Diese Pipeline nimmt keine Eingabe, also brauchen wir keine anderen Argumente. + +Lass uns Enter drücken und sehen, was passiert. + +Okay. Hoffentlich solltest du eine Ausgabe haben, die so aussieht. Wir haben ein paar Informationen, die uns sagen, dass Nextflow gelaufen ist und welche Version es verwendet hat. Sagt uns, welches Skript gestartet wurde, und es gibt uns einen zufällig generierten Namen für diese bestimmte Workflow-Ausführung. In diesem Fall wurde meiner "gloomy_crick" genannt. + +Der wichtigste Teil hiervon ist jedoch, dass es uns sagt, welche Schritte in der Pipeline gelaufen sind. Du kannst sehen, dass unser Process namens sayHello gelaufen ist, und er ist einmal gelaufen und war zu hundert Prozent vollständig. + +Dieser Teil hier ist der Hash für diese bestimmte Workflow-Aufgabe. Jeder Process läuft ein oder mehrere Male, und jede dieser Ausführungen wird eine Aufgabe genannt. + +## 2.2. Die Ausgabe und Logs im work-Verzeichnis finden + +Jede Aufgabe bekommt ihr eigenes isoliertes Verzeichnis, in dem sie läuft, also ist sie vom Rest der Ausführung des Workflows getrennt. Dieser Hash entspricht der Dateistruktur innerhalb des work-Verzeichnisses. Wenn ich "tree work" mache, können wir a0 sehen, und dann eine längere Version eines kurzen Hashs, und dann unsere output.txt-Datei. Du kannst es auch in einer Seitenleiste sehen. + +Du kannst in der Seitenleiste sehen, dass es hier einige zusätzliche Dateien gibt. Der Grund, warum diese nicht im Terminal aufgetaucht sind, ist, dass sie versteckte Dateien sind, sie beginnen mit einem Punkt. Und tatsächlich, wenn ich "tree -a" für alle mache, und "work", können wir sie hier sehen. + +Diese Dot-Dateien sind in jedem einzelnen work-Verzeichnis vorhanden, das Nextflow erstellt, und jede hat eine etwas andere Aufgabe. Erstens enthält .command.begin nur einige Anweisungen für Nextflow, die die Aufgabe einrichten, bevor sie läuft. .command.run sind die tatsächlichen Anweisungen, die von Nextflow selbst ausgeführt werden. Dann ist .command.sh wahrscheinlich die interessanteste. Dies ist das Skript, das von unserem Process-Block-Script aufgelöst wurde. + +Wenn ich es öffne, kannst du sehen, wir haben unser "echo Hello World" in die output.txt-Datei. Dies ist genau das Gleiche wie unser Process in diesem Fall, aber wenn wir irgendwelche Variablen in unserem Nextflow-Code haben, wird jede Aufgabe eine andere .command.sh haben, und du kannst sehen, wie diese Variablen aufgelöst wurden. + +Die anderen Dateien haben damit zu tun, wie die Aufgabe ausgeführt wurde. Also sind .command.err, .log und .out die Standardfehler, Standardausgabe und die beiden kombiniert. Und .exitcode teilt Nextflow mit, wie diese Aufgabe mit welchem Exit-Code ausgeführt wurde, ob sie erfolgreich war oder nicht. + +Schließlich haben wir unsere output.txt-Datei und tatsächlich, "Hello World", das ist, was wir erwarten, und das ist, was erstellt wurde. + +Okay, großartig. Das war dein allererster Nextflow-Lauf. Herzlichen Glückwunsch. Es ist wirklich so einfach. + +Als Nächstes werden wir darauf eingehen, wie man dies etwas bequemer macht, sodass wir den Code nicht jedes Mal bearbeiten müssen, wenn wir eine Änderung an der Ausführung der Pipeline vornehmen möchten. + +## 3. Workflow-Ausführungen verwalten + +Diese Verzeichnisstruktur ist großartig, um alle Aufgaben getrennt und alles organisiert zu halten, aber natürlich ist es nicht sehr bequem, deine Ausgabedateien zu finden. Du möchtest nicht durch Mengen verschachtelter Verzeichnisse graben, um die Ergebnisse deiner Pipeline zu finden. + +## 3.1. Ausgaben veröffentlichen + +Die gute Nachricht ist, du sollst das nicht. Die work-Verzeichnisse sind wirklich nur für Nextflow, um sie selbst zu verwenden. Also werden wir eine Funktion für Nextflow namens "publishDir" verwenden. + +Wir gehen zurück zu unserem Workflow, gehen zum Process. Wir können hier eine neue Anweisung hinzufügen, die eine Direktive genannt wird. Dies ist, was Nextflow diese Dinge am Anfang von Processes nennt, die die Funktionsweise erweitern, und die, die wir verwenden werden, heißt publishDir. + +Du kannst sehen, ich habe hier angefangen zu tippen, und die Nextflow-Erweiterung für VS Code hat mir die Direktive vorgeschlagen, also kann ich einfach Enter drücken. + +Okay. Ich werde dies mit einem Verzeichnis namens "results" verfolgen, und wir werden ihm sagen, dass es die Ausgabedateien dorthin kopieren soll. Also werde ich sagen mode copy. Großartig. Werde speichern und lass uns den Workflow erneut ausführen. + +nextflow run hello-world.nf + +Es läuft genau gleich. Beachte aber, wir haben dieses Mal einen etwas anderen Hash. Nextflow wird jedes Mal, wenn du den Workflow ausführst, einen anderen Hash verwenden. Und wir haben infolgedessen einen anderen Satz von work-Verzeichnissen. Bereiche, einer heißt EB stattdessen, aber du kannst sehen, alle Dateien sind gleich. Was jedoch neu ist dieses Mal, ist, dass wir auch ein Verzeichnis namens "results" haben. + +Innerhalb von "results" hier haben wir unsere Ausgabedatei. Das ist, was wir Nextflow gesagt haben zu tun. Wir sagten, speichere die Ergebnisdateien in einem Verzeichnis namens "results" und kopiere sie dorthin. Und so ist dies jetzt viel einfacher zu finden. Es ist einfach dort neben dem Ort, wo wir einen Workflow gestartet haben, und all die verschiedenen Dateien können dort organisiert werden, wie auch immer wir wünschen, unabhängig davon, wo oder wie Nextflow die tatsächliche Ausführung durchgeführt hat. + +Beachte, dass publishDir Symlinks handhaben kann, was gut ist, wenn du auf einem gemeinsam genutzten Dateisystem arbeitest und Platz sparen möchtest. Und auch musst du nicht alle Dateien definieren, die von einem Process erstellt werden, als Ausgabe. + +Nextflow wird nur die Dinge kopieren, die in diesem Output-Block definiert sind. Also wenn du Zwischendateien hast, die vom Schritt erstellt werden, die nicht downstream von diesem Process benötigt werden, definierst du sie einfach nicht in der Ausgabe, und sie werden nicht in publishDir auftauchen. Also ist dies ein Weg, deine Ausgabedateien von einer Pipeline sauber zu halten und Zwischendateien einfach zu löschen, sobald der Arbeitsplatz fertig ist. + +Eine kurze Bemerkung hier. Es gibt neue Nextflow-Syntax, die kommt, genannt workflow output definitions, die schließlich publishDir ersetzen wird. Dies gibt uns eine Möglichkeit, alle Ausgaben von einem Workflow auf Pipeline-Ebene unten im Workflow-Block zu definieren. Dies ist in den Nextflow-Docs beschrieben, wenn du es ausprobieren möchtest. Aber für jetzt wird publishDir noch eine Weile da sein, also haben wir das noch in einem Training für 2025. + +## 3.2. Einen Workflow mit -resume neu starten + +Okay. Ich erwähnte, dass das work-Verzeichnis hier jetzt zwei Sätze von Ergebnissen mit einem anderen Hash von jeder Ausführung des Workflows hat. Das ist gut. Aber manchmal wollen wir Schritte nicht jedes Mal neu berechnen, wenn wir es nicht brauchen. + +Vielleicht baust du deinen Workflow iterativ auf und du fügst Schritte hinzu, und du möchtest, dass die ersten Schritte einfach die gecachten Versionen wiederverwenden. Oder vielleicht ist etwas auf deinem Rechensystem in der Mitte deines Workflows schief gegangen, und du möchtest, dass es dort weitermacht, wo es aufgehört hat, aber die Schritte überspringt, die es bereits abgeschlossen hatte. + +Nextflow hat eingebaute Funktionalität dafür namens resume. Lass es uns ausprobieren. Also zuerst einmal werde ich mir einfach das work-Verzeichnis ansehen, damit wir uns erinnern können, was dort war. + +Und dann werde ich "nextflow run hello-world.nf" machen, und ich werde hier einen einzigen Befehl hinzufügen, "-resume". + +Beachte, einzelner Bindestrich, das ist wirklich wichtig. Ich werde es ausführen, und die Ausgabe wird im Grunde genau gleich aussehen, mit ein paar kleinen Unterschieden. + +Beachte hier, es steht "cached" in grau. Das bedeutet, dass Nextflow die Aufgabe nicht ausgeführt hat. Dieses Mal fand es etwas, das dem entsprach, was Anforderungen waren, und es verwendete diese Ausgaben direkt wieder, anstatt den Schritt erneut auszuführen. + +Und tatsächlich, wenn du dir den Hash hier anschaust, kannst du sehen, dies entspricht dem vorhandenen Hash, den wir von einem vorherigen Lauf hatten. + +## 3.3. Ältere work-Verzeichnisse löschen + +Okay. Aber wenn du iterativ entwickelst, wirst du eine Menge dieser Workflow-Dateien aufbauen. Das kann ein Problem sein, wenn du möglicherweise wenig Platz hast. + +Nextflow kann uns helfen, diese work-Verzeichnisse mit ein paar Hilfsbefehlen aufzuräumen. Wenn ich "nextflow log" mache, das wird mir eine Liste aller verschiedenen Workflow-Läufe geben, die ich in diesem Verzeichnis gemacht habe, und sie haben die Laufnamen hier. Du kannst den gloomy quick sehen, der der erste war, den wir ausgeführt haben, und dann diese beiden neuen. + +Wir können jetzt diesen Namen nehmen und diese mit dem "nextflow clean"-Befehl verwenden. Ich kann einen einzelnen Laufnamen angeben. Oder noch besser, ich kann Nextflow sagen, alles vor einem einzelnen Workflow-Namen zu löschen mit "-before", und ich werde "stupefied_shaw" eingeben. Das war mein letzter Lauf, "-n". + +Der "-n"-Befehl sagte Nextflow, es als Probelauf zu machen, ohne tatsächlich etwas wirklich zu löschen, und es sagt uns, welche der Hash-Verzeichnisse es entfernt hätte. Tatsächlich ist es nur das eine von der ersten Ausführung. Beide der zweiten Ausführungen verwenden das gleiche Hash-Verzeichnis. + +Ich werde es noch einmal ausführen, aber jetzt anstelle von "-n" für Probelauf, werde ich "-f" für force machen, und es hat dieses Hash-Verzeichnis entfernt. Jetzt, wenn ich "tree work" mache, können wir sehen, wir haben nur noch diese Ausgabedatei übrig. + +Großartig. Also haben wir es geschafft, dort eine ganze Menge Festplattenspeicher aufzuräumen. + +Ein paar Dinge zu beachten beim Löschen von work-Verzeichnissen, wenn du Sachen in dein results-Verzeichnis symlinkt, werden diese Symlink-Quellen jetzt gelöscht, und deine Ergebnisse werden für immer weg sein. Deshalb ist die Verwendung des copy-Modus eine sicherere Sache zu tun, und generell das, was wir empfehlen. + +Zweitens hängt die Resume-Funktionalität von Nextflow von diesen work-Verzeichnissen ab. Also wenn du sie löschst und du Nextflow wieder ausführst, wird die Resume-Funktionalität nicht mehr funktionieren. Also liegt es an dir, im Auge zu behalten, welche Dinge du möglicherweise brauchst oder nicht brauchst, und lösche Dinge nur, wenn du sicher bist, dass es sicher ist, dies zu tun. + +Die andere Sache, die wir tun können, ist, wir können einfach das gesamte work-Verzeichnis löschen, wenn wir unseren Workflow-Lauf beendet haben und wir sicher sind, dass wir es nicht mehr brauchen. + +Also kann ich "rm -r work" machen. Ich weiß, es war nichts Wichtiges darin. Ich habe meine Ergebnisse, die mir wichtig sind, im results-Verzeichnis, wo wir sie kopiert haben. Und so war es sicher, das work-Verzeichnis zu löschen. Es liegt an dir, welchen dieser Ansätze du verwendest. + +## 4. Eine variable Eingabe verwenden, die über die Befehlszeile übergeben wird + +Okay, was kommt als Nächstes? Ich erwähnte, dass wir einige der Werte in unserem Workflow-Skript hier hartcodiert hatten, die output.txt-Datei, und dass es einen besseren Weg geben könnte, dies zu tun. + +Lass uns damit beginnen. Was wir tun werden, sind drei Dinge. Wir werden eine neue Eingabe zum Process hinzufügen. Wir werden dem Process-Script sagen, wie es diese Eingabe verwenden soll, und dann werden wir es im Workflow verdrahten, sodass wir es dynamisch mit einem Befehlszeilen-Flag beim Ausführen von Nextflow verwenden können. + +Also zuerst die wichtigsten Dinge. Lass uns hier einen Input-Block hinzufügen. Genau wie bei der Ausgabe. Dies ist ein neuer Abschnitt für den Process, und ich werde sagen, "val greeting". + +Beachte hier, ich sage "val", was sagt, dass dies eine Variable ist, kein Pfad. + +Ich kann dann nach unten ins Script gehen und dann kann ich diesen hartcodierten Text hier herausnehmen und $greeting machen. Dies funktioniert genau wie jede andere Programmiersprache. Wir definieren hier eine Variable, und wir referenzieren sie innerhalb dieses Script-Blocks. Wenn Nextflow diesen Process ausführt, wird die Variable interpoliert. Und wenn wir uns diese .command.sh-Datei ansehen, werden wir den tatsächlichen hartcodierten String hier stattdessen sehen. + +## 4.1.3. Einen CLI-Parameter einrichten und ihn als Eingabe für den Process-Aufruf bereitstellen + +Okay, aber wo stellen wir die Variable bereit? Als Nächstes gehen wir zum Workflow-Abschnitt runter, und du kannst sehen, dass die Erweiterung hier sagt, wir erwarten jetzt eine Eingabe, und es hat mir eine Warnung gegeben. + +Nun, das Einfachste, was wir tun könnten, ist einfach hartcodieren. Ich könnte "Hello World" schreiben und diesen String-Input für den Process bereitstellen. Aber wieder würde das wirklich keine Probleme lösen. Wir müssten immer noch zurückgehen und den Pipeline-Code jedes Mal bearbeiten, wenn wir etwas ändern wollten, was nicht gut ist. + +Die gute Nachricht ist, dass Nextflow ein eingebautes System hat, um Befehlszeilenargumente zu handhaben, genannt Parameter. Also kann ich stattdessen eine dieser speziellen Variablen namens params verwenden, und ich kann sie nennen, wie ich will, aber ich werde greeting sagen, damit es mit der Workflow-Logik übereinstimmt. + +Speichern drücken und lass uns sehen, was wir damit machen können. + +Also wenn ich zurück zum Terminal gehe. Also machen wir "nextflow run hello-world.nf". Genau wie vorher, aber der entscheidende Unterschied ist, wir machen --greeting + +Beachte, es gibt hier zwei Bindestriche, weil dies ein Parameter ist. Als wir den Workflow vorher resumed haben, war das ein einzelner Bindestrich. Das liegt daran, dass resume eine Kern-Nextflow-Option ist, und dies ist ein Parameter, der spezifisch für unsere Pipeline ist. + +Verwechsele die beiden nicht. Es ist einfach, das zu tun. Wenn du --resume statt nur einem Bindestrich gemacht hättest, dann wäre das "params.resume", was nichts machen würde. Ebenso, wenn du einen einzelnen Bindestrich hier gemacht hättest, würde Nextflow es nicht als Schlüsselargument erkennen. + +Also ist es --greeting, was params.greeting entspricht. + +Ich kann diesem jetzt folgen mit welchem Text auch immer ich will. Also bin ich gerade in Schweden, also werde ich sagen, "Hej världen". + +Also lass uns es ausführen, sehen, was passiert, Moment der Wahrheit. + +Okay, also kannst du sehen, dass der Process erneut gelaufen ist, genau wie vorher, sayHello mit einer einzelnen Ausführung. + +Dies wird die Datei überschrieben haben, die im publishDir "results"-Verzeichnis war. Also sei vorsichtig, wenn du die Dateien erneut ausführst, weil Dinge im published air überschrieben werden. + +Ich kann jetzt "code results/output.txt" machen, und tatsächlich wurde unsere Ausgabe aktualisiert und sagt jetzt "Hej världen". + +## 4.2. Standardwerte für Befehlszeilenparameter verwenden + +Okay, das ist großartig. Aber das Problem jetzt ist, dass unser Workflow darauf angewiesen ist, dass wir diesen Parameter immer definieren, und es ist schön, vernünftige Standards zu haben, damit die Dinge auf vernünftige Weise für deinen Workflow laufen, es sei denn, du überschreibst die Standards. + +Also der Weg, wie wir das machen, ist, indem wir einen Standardwert für den Parameter in unserem Workflow-Skript setzen. + +Also wenn ich zurück zu meiner hello-world.nf-Datei gehe, kann ich ins Skript gehen, direkt über workflow, "params.greeting" tippen und es wie jede andere Variable definieren. Also lass uns hier einen String eingeben und sagen wir "Holà mundo!" + +Jetzt hat dieser Parameter einen Standard definiert, der hier verwendet wird, oder wir können ihn immer noch auf der Befehlszeile mit --greeting überschreiben, genau wie wir es vorher gemacht haben. + +Also lass uns überprüfen, ob es funktioniert. "nextflow run hello-world.nf" + +Dieses Mal keine Befehlszeilenargumente, und überprüfen, ob es das Richtige gemacht hat. + +"code results/output.txt". Und da ist es. Wir haben unseren Standard bekommen. + +Okay, lass es uns noch einmal versuchen, nur überprüfen, dass ich dir keine Lügen erzähle. Lass uns es noch einmal ausführen, aber --greeting machen, und das Beispiel aus einem Trainingsmaterial verwenden, lass uns sagen "Konnichiwa!" + +Führt den Workflow erneut aus, und tatsächlich wurde unsere Ausgabedatei oben gerade mit dem neuen Wert aktualisiert, den wir auf der Befehlszeile bereitgestellt haben. + +Großartig. Dies ist ein wirklich zentraler Aspekt beim Schreiben eines jeden Nextflow-Workflows. Vernünftige Standards in deinem Pipeline-Code definieren, aber es sehr einfach machen, für den Endbenutzer zu konfigurieren, indem man Befehlszeilenargumente im Terminal hat. + +Beachte, dass der Endbenutzer die Konfiguration an mehreren verschiedenen Stellen überschreiben kann. Du kannst eine Config-Datei in deinem Home-Verzeichnis haben, die auf jeden einzelnen Nextflow-Lauf angewendet wird, den du machst. Du kannst eine Config-Datei in einem Launch-Verzeichnis haben. Du kannst eine Config-Datei in einem Pipeline-Verzeichnis haben. All diese verschiedenen Config-Orte werden in einer bestimmten Reihenfolge geladen, die in den Nextflow-Docs beschrieben ist. + +Okay, das ist das Ende von Abschnitt eins. Wir hatten unser allererstes Workflow-Skript in Nextflow mit einem Process und einem Workflow. Wir haben uns Eingaben, Ausgaben, Scripts und Publishing angeschaut und wie man Parameter und einen Input-Channel in unseren Process verdrahtet. + +Herzlichen Glückwunsch, dein erster Schritt zum Schreiben von Nextflow-Code ist abgeschlossen. + +Mach eine kleine Pause und ich sehe dich in ein paar Minuten zurück für Kapitel zwei. + +[Nächstes Videotranskript :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/de/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..503835185b --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Teil 2: Hello Channels - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../02_hello_channels.md) zurück. + + Die im Transkript angezeigten Abschnittsnummern dienen nur zur Orientierung und enthalten möglicherweise nicht alle Abschnittsnummern aus den Materialien. + +## Willkommen + +Hi, willkommen zu Teil zwei von Hello Nextflow. + +Dieses Kapitel heißt Hello Channels. Wir werden über diesen grundlegenden Teil von Nextflow sprechen. + +Channels sind die Dinge, die die verschiedenen Schritte in deiner Pipeline verbinden, die Art und Weise, wie deine Daten und Logik durch deinen Workflow fließen. + +Okay, lass uns eintauchen. + +Beginnen wir damit, zu training.nextflow.io zu gehen + +Hello Nextflow in der Seitenleiste und klicke auf Teil zwei. Hello Channels. + +Das gesamte Material ist hier aufgeschrieben, sodass du in deinem eigenen Tempo folgen und alles nachholen kannst, was du vielleicht verpasst hast. + +Sobald du die Website geöffnet hast, kannst du Codespaces laden und wir machen dort weiter, wo wir am Ende des letzten Kapitels aufgehört haben. + +## 0. Aufwärmen: hello-channels.nf ausführen + +Für dieses Kapitel werden wir eine andere Datei bearbeiten. Diese heißt Hello Channels, du findest sie also in der Seitenleiste, doppelklicke darauf, um sie zu öffnen. + +Wenn du gerade von Kapitel eins kommst, wird dir diese Datei sehr bekannt vorkommen. Der Ausgangspunkt hier ist im Grunde dort, wo wir Kapitel eins beendet haben, mit unserem process namens sayHello, unserer Eingabe, Ausgabe, unserem publishDir und unserem params.greeting und unserem einfachen workflow. + +Wir beginnen mit einer neuen Datei, also ist es für alle eine ebene Spielfläche, aber du kannst mit deiner vorherigen Datei fortfahren, wenn du möchtest. + +Beachte, ich habe auch alle .nextflow\*-Dateien und die work-Verzeichnisse hier gelöscht, nur damit es ein sauberer Ausgangspunkt ist. Es ist nicht wichtig, ob du das tust oder nicht, das liegt bei dir. + +Okay. Lass uns zunächst überprüfen, dass diese Pipeline noch wie erwartet funktioniert. Ich werde das Terminal hier aufrufen. + +Gib "nextflow run hello-channels.nf" ein und drücke Enter. + +Es wird diesen kleinen Workflow ausführen, unseren sayHello-Schritt ausführen, ein work-Verzeichnis mit diesem Hash generieren, und hier ist unser results-Ordner und da ist unsere Ausgabedatei, genau wie wir es von unserem Standard-params.greeting erwartet haben. + +Das ist großartig. Genau wie in Kapitel eins, funktioniert wie erwartet. + +## 1. Variable Eingaben explizit über einen channel bereitstellen + +In Kapitel eins hast du bereits channels verwendet, du hast es nur nicht bemerkt. Als wir hier einen String angegeben haben, hat Nextflow automatisch einen channel um diesen String für uns erstellt, einfach weil es wusste, dass wir einen process aufrufen, also brauchten wir einen Eingabe-channel. + +Das erste, was wir tun werden, ist, es explizit zu machen, indem wir den channel tatsächlich selbst aufschreiben. + +## 1.1. Einen Eingabe-channel erstellen + +Ich gehe also zum workflow hier am Ende des Skripts, und ich werde greeting_ch sagen. Das ist eine Konvention, die wir oft in Nextflow-Code verwenden, ein Unterstrich ch am Ende eines Variablennamens zu haben, wenn es ein channel ist, nur damit es leicht zu erkennen ist, dass es ein channel ist, aber du musst das nicht tun. Gleich channel of Hello Channels. + +Was wir gerade verwendet haben, wird in der Nextflow-Sprache als "Channel Factory" bezeichnet. Das ist dieses Ding hier, wir setzen diese Variable auf einen neuen channel, und diese channel factory hier erstellt einen channel für uns auf eine bestimmte Weise. + +Es gibt eine Handvoll verschiedener channel factories, die Nextflow hat, um channels aus verschiedenen Arten von Eingaben zu erstellen. Dot of ist die einfachste und nimmt einfach alle Strings, die wir ihr geben. + +Beachte, wenn ich in VS Code über diese Wörter fahre, gibt mir die Nextflow-Erweiterung ein Popup, das erklärt, was diese Syntax macht, und es gibt auch einen "Mehr lesen"-Text am unteren Rand dieses Popup-Fensters. + +Wenn ich darauf klicke, öffnet es die Nextflow-Dokumentation in einem neuen Tab und führt mich direkt zur Dokumentation für diese spezifische Sache. In diesem Fall für channel.of. + +## 1.2. Den channel als Eingabe zum process-Aufruf hinzufügen + +Beachte, dass die Erweiterung uns auch eine Warnung gibt, die besagt, dass wir hier einen neuen channel erstellt haben, aber er wird von nichts verwendet. + +Also, lass uns das beheben. Ich nehme den neuen channel-Namen und werde dieses params.greeting durch unseren neuen channel ersetzen. + +Beachte, dass wir jetzt das Kommandozeilen-Flag --greeting nicht mehr verwenden, params.greeting wird nicht verwendet, wir gehen zurück zum Hardcodieren dieses Strings. Das ist okay. Ich versuche nur, die Dinge einfach zu halten. Wir kommen später zurück und verwenden die params wieder. + +## 1.3. Den workflow-Befehl erneut ausführen + +Okay, lass uns nur noch einmal überprüfen, dass dies funktioniert. Rufe das Terminal auf und beachte nochmal. Nextflow run hello channels. Überprüfe output.txt, und da ist es. + +Tolles Beispiel, das genau dasselbe tut wie zuvor, aber jetzt ist die Logik zumindest ein bisschen klarer. Wir sind explizit beim Schreiben eines neuen channels. + +Wir haben effektiv einfach mehr Code geschrieben, um dasselbe zu tun. Aber das wird mehr Sinn ergeben, wenn wir mit der Art und Weise, wie wir unsere channels erstellen, etwas komplizierter werden. + +## 2. Den Workflow modifizieren, um mit mehreren Eingabewerten zu arbeiten + +Okay, lass uns das ein bisschen interessanter machen. Es ist sehr selten, dass du eine Nextflow-Pipeline auf einer einzigen Eingabe ausführen möchtest, also lass uns ihr mehrere Eingaben geben. + +## 2.1. Mehrere Grüße in den Eingabe-channel laden + +Aus der Dokumentation hier. Ich werde diese verschiedenen Strings kopieren, drei davon. Hello, Bonjour, Olà. Oh, hoffe. Copilot schlägt ein paar andere vor. Also lass uns diese mit Tab Enter eingeben. + +Die Nextflow-Dokumentation hier sagt uns, dass wir diesem Operator mehrere Werte geben können, also sollte es funktionieren, aber lass es uns ausprobieren und sehen, was passiert. + +## 2.1.2. Den Befehl ausführen und die Log-Ausgabe betrachten + +Nun. Ja und nein. Lass uns sehen. Es sagt, dass fünf von fünf Aufgaben hier ausgeführt wurden, aber es zeigt uns nur einen Hash, was ein bisschen seltsam ist. Das ist okay. Alles ist wie erwartet hier. Standardmäßig verwendet Nextflow eine spezielle Art der Ausgabe an ein Terminal namens ANSI-Kontrollcodes, was bedeutet, dass es bestimmte Zeilen überschreibt, um eine schöne komprimierte Ansicht aller verschiedenen Prozesse zu geben, die ausgeführt werden. + +Das macht viel mehr Sinn, wenn du größere Workflows hast und Hunderte oder Tausende verschiedener Proben ausführst. Du kannst einfach so viel Ausgabe auf dem Terminal generieren, dass es unmöglich ist, sie anzuschauen, während diese aktualisierende Ansicht dir einen Echtzeit-Fortschritt gibt. + +## 2.1.3. Den Befehl erneut mit der Option -ansi-log false ausführen + +Wenn du möchtest, kannst du es erneut ausführen, und diesmal werde ich ein zusätzliches Nextflow-Kernargument mit einem einzelnen Bindestrich verwenden und sagen: "-ansi-log false". Dies verwendet die vorherige Version der Nextflow-Log-Ausgabe. Und hier kannst du alle einzelnen Prozesse sehen, die gestartet wurden. + +Es liegt bei dir, ob du dies tust oder nicht. Die Ausgabe von Nextflow ist in beiden Fällen genau gleich. + +## 2.2. Sicherstellen, dass die Ausgabedateinamen eindeutig sind + +Okay, schauen wir uns die Ausgabedateien an, dann gehen wir zu results. Aber es gibt nur eine einzige Ausgabedatei. Was ist passiert? Wir haben gesehen, dass der process viele Male ausgeführt wurde. Wir können ins work-Verzeichnis gehen und alle verschiedenen Hashes sehen, alle Aufgaben wurden ordnungsgemäß ausgeführt. Aber wenn du dich an unseren process hier erinnerst, speichern wir alles in einer output.txt-Datei und veröffentlichen diese dann in diesem Verzeichnis. + +Die gleiche Datei wurde also fünfmal erstellt und dann fünfmal überschrieben. Und wir haben nur, welche Aufgabe auch immer zuletzt ausgeführt wurde. + +## 2.2.1. Einen dynamischen Ausgabedateinamen konstruieren + +Die Art, wie wir das beheben, ist die Verwendung eines dynamischen Ausgabedateinamens. Hier haben wir bereits eine Variable namens greeting innerhalb des process, also können wir diese im Ausgabedateinamen verwenden. Ich kopiere das und mache $greeting-output.txt. + +Ich werde das in Anführungszeichen setzen, nur damit bash nicht durch irgendwelche Leerzeichen verwirrt wird, die hier hineinschleichen könnten. Und dann nehme ich denselben Dateinamen und aktualisiere die Ausgabe hier. + +Es ist wirklich wichtig, dass die Ausgabe damit übereinstimmt, denn sonst wird diese Datei nicht gefunden und Nextflow wird abstürzen. + +Ich werde noch eine wirklich wichtige Änderung vornehmen, nämlich diese einfachen Anführungszeichen durch doppelte Anführungszeichen ersetzen. Beachte, dass sich die Farbe des Codes geändert hat, als ich das tat. Diese Variable wird nur erweitert, wenn wir doppelte Anführungszeichen verwenden. Wenn ich hier einfache Anführungszeichen verwende, wird es als literaler Wert verwendet, und ich würde eine einzelne Datei namens $greeting-output bekommen, was nicht das ist, was ich will. + +## 2.2.2. Den Workflow ausführen + +Also lass uns die doppelten Anführungszeichen zurücksetzen und es versuchen. + +Ich werde nur mein Verzeichnis aufräumen, bevor ich beginne, damit es einfach ist, die neuen Dateien zu sehen. Ich werde alles löschen, was .nextflow, work und results heißt. + +Und ich werde diesen Nextflow-Befehl erneut ausführen und sehen, welche Dateien erstellt werden. Es führt also die fünf Prozesse dort aus. Wenn du sehr genau zugeschaut hast, hast du vielleicht gesehen, dass sich diese Zeile aktualisiert hat, während sie lief. + +Und jetzt können wir ins results-Verzeichnis gehen, und tatsächlich haben wir fünf verschiedene Ausgaben, und sie sind alle mit dem jeweiligen Gruß vorangestellt. + +Wenn ich jede davon öffne, werden wir sehen, dass sie jeweils den entsprechenden Gruß enthalten. Fantastisch. Das ist es, was wir wollen. + +## 3. Einen Operator verwenden, um den Inhalt eines channels zu transformieren + +Okay, jetzt wissen wir, was channels sind und was channel factories sind. Was ist mit Operatoren? Dies ist ein weiterer Begriff für einen Teil der Nextflow-Sprache, der eine Reihe von Funktionen ist, die es uns ermöglichen, auf channels zu operieren, um bestimmte Dinge mit ihnen zu tun. Nextflow kommt mit einer Reihe von Operatoren, die es uns ermöglichen, channels auf verschiedene Arten zu manipulieren. + +## 3.1. Ein Array von Werten als Eingabe für den channel bereitstellen + +Lass uns das mit einem Beispiel durcharbeiten. Nehmen wir an, wir möchten diese Eingabe-Strings nehmen, aber anstatt sie direkt in eine channel factory zu stecken, möchten wir sie als Array definieren. + +## 3.1.1. Die Eingabevariable einrichten + +Ich werde diese nehmen und das als neue Zeile darüber machen und sagen, greetings, array. + +Da haben wir's. Ich nehme diese Array-Variable und stecke sie in das channel.of und speichere. + +## 3.1.3. Den Workflow ausführen + +Jetzt, lass uns sehen, was passiert. Zurück zu meinem Terminal. Ich werde nur all diese temporären Dateien wieder aufräumen. Und lass uns den Workflow ausführen. + +Nicht gut. Okay. Es ist kaputt gegangen. Das ist okay. Ich habe erwartet, dass es diesmal kaputt geht. Das Debuggen dessen, was schief läuft, wenn ein Nextflow-Workflow fehlschlägt, ist ein wichtiger Teil davon, ein Nextflow-Entwickler zu sein. Das wird oft passieren, und es ist wichtig zu verstehen, was die Fehlermeldung sagt und wie man damit umgeht. + +Die Nextflow-Fehlermeldungen sind tatsächlich ziemlich strukturiert. Sie sagen uns, welcher process schief gelaufen ist. Sie geben uns eine Fehlermeldung für einen Grund. Sie sagen, was der Befehl war, den es zu führen versuchte innerhalb dieser speziellen Aufgabe, was der Exit-Status war, was die Ausgabe war und wo dieses Aufgaben-work-Verzeichnis war. + +Beachte, dass ich dies in VS Code mit Option anklicken kann und es in einer Seitenleiste öffnet, sodass ich direkt dorthin gehen und alle diese versteckten Dateien ansehen kann, über die wir im vorherigen Kapitel gesprochen haben, einschließlich der .command.sh-Datei. Diese kannst du sehen, ist dieselbe wie die Befehle, die hier ausgeführt wurden. + +Indem wir uns diese Datei ansehen, können wir ein Gefühl dafür bekommen, was hier schief gelaufen sein könnte, anstatt eine einzelne Aufgabe für jedes Element im Array auszuführen, wie es beim letzten Mal tat, hat es einfach das gesamte Array auf einmal als String bereitgestellt. Also müssen wir dieses Array in einzelne Werte entpacken, bevor wir es in den channel übergeben. Lass uns zurückgehen und sehen, ob wir das mit einem Operator tun können. + +## 3.2. Einen Operator verwenden, um channel-Inhalte zu transformieren + +In diesem Fall werden wir das Array nicht ändern, bevor wir es in den channel übergeben. Wir werden den channel so anpassen, dass er sich so verhält, wie wir es erwarten. Wir werden das tun, indem wir den flatten-Operator verwenden, kannst du dot anfangen zu tippen, und wir können sehen, dass die VS Code-Erweiterung beginnt, alle verschiedenen verfügbaren Operatoren vorzuschlagen. + +## 3.2.1. Den flatten()-Operator hinzufügen + +Und ich wähle flatten aus. Beachte, dass Leerzeichen in diesem Kontext für Nextflow keine Rolle spielen. Du kannst diese Operatoren also auf eine neue Zeile setzen, wenn du möchtest. Ich kann das also hier ablegen und einrücken, sodass es unter ".of" sitzt, und du wirst sehen, dass die Leute oft viele Operatoren wie diesen auf einen channel verketten und ihn auf diese Weise einrücken, damit er leichter zu lesen ist. + +Du kannst auch sehen, wie zuvor kann ich darüber fahren und lesen, was der flatten-Operator macht, und auch einem Link zur Dokumentation folgen, wenn ich möchte. + +Dieser Operator nimmt also diesen channel, der ein einzelnes Array darin hat, und trennt die Array-Werte. + +## 3.2.2. view() hinzufügen, um channel-Inhalte zu inspizieren + +Wir können in die channels hineinschauen, indem wir den speziellen view-Operator verwenden, und ich werde hier ein paar davon hinzufügen. Das ist ein bisschen wie die Verwendung von Print-Anweisungen in anderen Sprachen. Ich werde also dot view machen und dann diese geschweiften Klammern verwenden. + +Das wird closure genannt. Das gibt im Grunde zusätzlichen Code an den view-Operator, den er auf jedem Element innerhalb des channels ausführt. In diesem Fall werde ich sagen greeting before flatten. Greeting. + +Ich definiere hier eine Variable, die nur innerhalb des Geltungsbereichs dieser closure liegt. Diese Variable wird also nur hier verwendet, und ich könnte sie nennen, wie ich wollte. Es ist nicht wirklich wichtig. Ich verwende nur greeting, um es leicht lesbar zu machen. + +In einigen Nextflow-Pipelines siehst du vielleicht, dass Leute eine spezielle implizite Variable namens "$it" verwenden. So. Das ist eine spezielle Variable innerhalb von Nextflow-Code, die eine Abkürzung ist, sodass du die kleine Definition einer Variablen nicht machen musst. Im Laufe der Zeit denken wir jedoch, dass dies für Leute, die neu bei Nextflow sind, nicht sehr klar ist, und wir raten von der Verwendung von "$it" jetzt ab. + +Also werde ich beim vorherigen Verhalten von greeting bleiben und es so verwenden, weil das expliziter ist und klarer ist, was vor sich geht. + +Ich werde dann diese Zeile kopieren und genau dasselbe noch einmal nach den flatten-Argumenten machen. Der view-Operator ist ein bisschen speziell, weil er etwas mit den Elementen macht, aber er gibt sie auch einfach an den nächsten Operator weiter, sodass wir ihn in der Mitte einer Kette von Operationen wie dieser verketten können, und er wird den Status dort drucken und weitermachen. Hoffentlich wird uns das zeigen, wie der channel vor und nach dem flatten-Operator aussieht. + +## 3.2.3. Den Workflow ausführen + +Lass es uns ausprobieren. Räume alles im Workspace auf. Führe die Pipeline erneut aus. + +Okay, wir können sehen, dass es unsere fünf Prozesse erneut ausgeführt hat. Es ist nicht mit einem Fehler abgestürzt, das ist definitiv gut. Und jetzt haben wir das before flatten und es hat sicher genug unser Array und wir haben after flatten, fünfmal gedruckt, einmal für jedes Element des Arrays. Das ist genau das, worauf wir gehofft hatten. Das sind wirklich gute Nachrichten. Und das passt genau zu dem, was wir vom Code erwarten würden. + +Wir brauchen diese Debug-Anweisungen nicht mehr, also kann ich sie entweder auskommentieren oder löschen. Ich werde sie löschen, nur um meinen Code schön und sauber zu halten. Okay, toll. Dieses Beispiel funktioniert jetzt schön und wir können beginnen zu sehen, wie channels etwas kompliziertere Logik machen können. + +## 4. Einen Operator verwenden, um Eingabewerte aus einer CSV-Datei zu parsen + +Jetzt werden wir versuchen, dies mit einer Datei mit einer Reihe von Eingaben zu tun. Das ist eine sehr übliche Art, Nextflow-Pipelines zu schreiben, indem man ein Sample Sheet oder ein CSV mit Metadaten verwendet. + +## 4.1. Das Skript modifizieren, um eine CSV-Datei als Quelle der Grüße zu erwarten + +Wenn ich zur Seitenleiste gehe, kannst du greetings.csv im Beispiel-Repository sehen, und das ist eine sehr, sehr einfache CSV-Datei, die nur drei Zeilen mit drei verschiedenen Grüßen enthält. Lass uns sehen, ob wir diese CSV-Datei innerhalb unseres Workflows verwenden können. + +Ich werde jetzt wieder params verwenden, wie wir es in Kapitel eins getan haben, damit wir eine Kommandozeilen-Eingabe haben können. + +Ich werde dieses greetings-Array löschen. + +## 4.1.1. Den Eingabeparameter auf die CSV-Datei umstellen + +Ich setze params greeting auf den Dateinamen, der greetings.csv ist, und ich werde diese spezielle Variable verwenden, um den channel zu generieren. Ich werde das da reinstecken, und die Fehler verschwinden. Denk daran, dass dies diese Variable jetzt standardmäßig setzt. Wenn ich also die Pipeline ohne Argumente ausführe, wird sie greetings.csv verwenden, aber ich könnte --greeting machen, um diese Variable zu überschreiben, wenn ich wollte. + +## 4.1.2. Zu einer channel factory wechseln, die für eine Datei ausgelegt ist + +Okay, wir übergeben jetzt eine Datei statt eines Strings oder eines Arrays von Strings, also brauchen wir wahrscheinlich eine andere channel factory. + +Wir werden "of" loswerden, das wir bisher verwendet haben, und stattdessen .fromPath verwenden. Dies tut genau das, wonach es klingt. Es erstellt einen channel mit Pfaden anstelle von Werten, unter Verwendung eines String-Dateinamens oder Globs. Ich werde auch den flatten-Operator entfernen, da wir diesen nicht mehr benötigen, jetzt, da wir eine Datei übergeben. + +## 4.1.3. Den Workflow ausführen + +Ich werde speichern, das Terminal öffnen, den Workflow ausführen und dann sehen, was passiert. + +Okay. Es ist wieder abgestürzt. Keine Sorge. Ich habe diesen auch erwartet. Schauen wir uns die Fehlermeldung an und sehen, ob wir herausfinden können, was schief läuft. Hier können wir den ausgeführten Befehl sehen, und ein bisschen wie zuvor, wo wir das ganze Array gedruckt hatten. Jetzt wird der Dateipfad in den Befehl geechot, anstatt durch den Inhalt der Datei zu gehen. + +## 4.2. Den splitCsv()-Operator verwenden, um die Datei zu parsen + +Um also den Inhalt der Datei stattdessen zu verwenden, brauchen wir einen anderen Operator. Der Operator, den wir dafür verwenden werden, heißt splitCsv. Macht Sinn, weil es eine CSV-Datei ist, die wir laden. + +## 4.2.1. splitCsv() auf den channel anwenden + +Ok, also splitCsv. Klammer schließen. Wir brauchen hier keine Argumente. Und wieder werde ich einige view-Operatoren verwenden, um einen Einblick zu geben, was hier vor sich geht. + +.view csv after splitCsv. Before split Csv. + +## 4.2.2. Den Workflow erneut ausführen + +Okay, lass uns das ausführen und sehen, was passiert. + +Okay, wir haben diesmal etwas mehr Ausgabe, aber es ist immer noch fehlgeschlagen. Wir können uns die view-Anweisungen ansehen, und hier kannst du before split CSV sehen, und wir haben einen Dateipfad, wie wir in der vorherigen Fehlermeldung gesehen haben. After split CSV haben wir jetzt drei Werte, die den drei Zeilen in der CSV-Datei entsprechen. + +Du kannst jedoch sehen, dass jeder dieser Werte von eckigen Klammern umgeben ist. Jeder von ihnen war also ein eigenes Array, und das hat uns dasselbe Gebiet gegeben, das wir vorher hatten, wo es versucht, ein Array zu echoen, anstatt nur einen einzelnen String. + +Wenn wir an eine CSV-Datei denken, macht das irgendwie Sinn. Typischerweise hat eine CSV-Datei Zeilen und Spalten, also macht split CSV ein zweidimensionales Array. Die erste Dimension des Arrays ist jede Zeile, und dann gibt es eine zweite Dimension, die jede Spalte für jede Zeile ist. + +Hier haben wir also nur einen einzigen Wert auf jeder Zeile, also haben wir eine einzige Spalte, also haben wir ein Ein-Element-Array für jede Zeile der Datei. + +Das ist in Ordnung. Wir brauchen nur einen weiteren Operator, um dieses Array für jede Zeile der geparsten CSV-Datei zu kollabieren. Lass uns das aufräumen. Werde das Terminal los und sehen, was wir tun können. + +## 4.3. Den map()-Operator verwenden, um die Grüße zu extrahieren + +Jetzt könnten wir den flatten-Operator wieder verwenden, den wir vorher verwendet haben. Wir haben gesehen, wie dieser ein Array in eine Reihe von Werten kollabieren kann, was hier sehr gut funktionieren würde. Aber ich werde die Gelegenheit nutzen, um einen anderen Operator zu demonstrieren, der innerhalb von Workflows sehr häufig ist, genannt der map-Operator. + +## 4.3.1. map() auf den channel anwenden + +Ich werde dot map machen und ich werde item item[0] machen. + +Wenn du viel Code in anderen Sprachen schreibst, bist du vielleicht bereits mit dem map-Operator vertraut. Er nimmt ein iterierbares Objekt, wie ein Array oder einen channel, und er führt eine Operation auf jedem Wert davon aus. + +Hier sagen wir, dass wir eine Variable namens item innerhalb des Geltungsbereichs dieser closure definieren sollten, und dann wollen wir nur den ersten Wert in diesem Array zurückgeben. Also item Index null. + +Dies flacht das Array effektiv ab. Du kannst sehen, wie wir dies erweitern könnten, um komplexer zu sein: Wenn unsere CSV-Datei sechs Spalten hätte, wir aber nur an der vierten Spalte interessiert sind, könnten wir hier auf einen bestimmten Index zugreifen. Oder jede andere Art von Operation auf dem Wert durchführen, bevor wir ihn an die nachgelagerte Verarbeitung weitergeben. + +Der map-Operator ist also extrem flexibel und sehr leistungsfähig zum Modifizieren von channels im Flug. Lass uns eine weitere view-Anweisung einbauen, nur damit wir sehen können, was sie in unserer Ausführung macht. Kann diese Zeile nehmen und nach unten verschieben. Und after map. + +## 4.3.2. Den Workflow ein letztes Mal ausführen + +Lass uns das Terminal aufrufen und versuchen, den Workflow auszuführen. + +Okay, diesmal keine Fehler. Das ist ein gutes Zeichen. Wir können jetzt alle diese verschiedenen Ausgaben von den view-Anweisungen durchgehen. Before split CSV hatten wir einen einzelnen Pfad. After split CSV hatten wir die Ein-Wert-Arrays, und dann after map haben wir nur die Werte ohne Array-Syntax. Lass uns zum results-Verzeichnis gehen, und hier sind unsere Ausgabedateien, die sich genau so verhalten, wie wir es wollten. + +Es gibt hier einen kleinen Bonus. Du kannst tatsächlich sehen, dass die view-Operatoren in der Reihenfolge, in der sie die Ausgabe gemacht haben, leicht durcheinander sind. Dies liegt daran, dass Nextflow die Parallelisierung dieser verschiedenen Aufgaben durchführt. Nachdem es also das CSV gesplittet hat, gibt es drei Elemente in diesem channel, und es handhabt die Verarbeitung dieser drei Elemente automatisch parallel. Das bedeutet, dass die Reihenfolge der Ausgaben stochastisch ist und variieren kann. In diesem Fall geschah es nur, dass einige der view-Operatoren zurückkehrten, nachdem der nachfolgende Schritt abgeschlossen war, und so kam es in dieser Reihenfolge. + +Wenn ich denselben Workflow erneut ausführe. Dann ist es tatsächlich in einer anderen Reihenfolge gekommen, und diesmal haben wir die split CSVs und die maps in der Reihenfolge, die wir erwarten würden. + +Bedenke also, du kannst dich nicht auf die Reihenfolge der Ausgaben einer process-Aufgabe verlassen, weil Nextflow diese Parallelisierung automatisch für dich handhabt. Nextflow macht das für dich mit seiner Datenfluss-Logik, und das ist die wahre Stärke von Nextflow. + +Okay, das ist wahrscheinlich eines der wichtigsten Kapitel des gesamten Trainings. Sobald du channels, channel factories und Operatoren verstehst, beginnst du, die Stärke von Nextflow zu verstehen und was es als Programmiersprache einzigartig macht. Diese Funktionalität ermöglicht es Nextflow, alle deine Workflows für dich zu parallelisieren und extrem komplexe Workflow-Logik mit einer sehr sauberen Syntax und einem Push-Datenfluss-Modell zu generieren. Es kann zunächst ein etwas seltsames Konzept sein, aber sobald du dich daran gewöhnt hast, Code wie diesen zu schreiben, wird es sich schnell natürlich anfühlen, und bevor du es weißt, wirst du fantastische Workflows schreiben. + +Mach eine Pause, eine Tasse Tee, geh ein bisschen herum und lass uns zu Kapitel drei übergehen, wo wir beginnen, diese Konzepte in komplexere Workflows zu erweitern. Wir sehen uns im nächsten Video. + +[Nächstes Video-Transkript :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/de/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..8eb6340bc0 --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Teil 3: Hello Workflow - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../03_hello_workflow.md) zurück. + + Die im Transkript angezeigten Abschnittsnummern dienen nur zur Orientierung und enthalten möglicherweise nicht alle Abschnittsnummern aus den Materialien. + +## Willkommen + +Hallo, willkommen zu Teil drei des "Hello Nextflow" Trainingskurses. + +Dieses Kapitel heißt "Hello Workflow". + +In Kapitel zwei haben wir einen einfachen Workflow mit einem Prozess erstellt, aber in der Realität sind Pipelines nützlich, weil sie mehrere Analyseschritte miteinander verketten können. + +In diesem Kapitel werden wir dieses anfängliche Beispiel nehmen und es etwas realistischer erweitern. + +Wir werden einige zusätzliche Schritte hinzufügen und uns ansehen, wie wir Channels verwenden, um diese Schritte zu verbinden. + +Wir werden uns mehrere Aufgaben ansehen, die in einen einzigen Prozess zusammengefasst werden können, und wir werden uns Prozesse ansehen, die mehrere Eingaben und mehrere Ausgaben haben können. + +Okay, lass uns anfangen. + +Also, fangen wir an. Wie zuvor. Lass uns zu training.nextflow.io gehen. Hello Nextflow, Kapitel drei. Hello Workflow. Und lass uns unseren Workspace öffnen. Ich habe alle meine Arbeitsdateien aus den vorherigen Kapiteln aufgeräumt und werde Hello Workflow öffnen. + +Das ist jetzt dieselbe Datei, an der wir bisher gearbeitet haben, das sollte also vertraut aussehen. Wir haben unseren say hello Prozess. Wir haben unseren params.greeting mit seiner greetings CSV Datei, und wir haben unseren Workflow unten, der diese CSV Datei lädt, den Channel erstellt und ihn an unseren Prozess übergibt. + +## 0. Aufwärmen: hello-workflow.nf ausführen + +Wenn du möchtest, können wir das ausprobieren und überprüfen, ob es wie erwartet funktioniert. Öffne ein Terminal für nextflow run hello workflow nf und drücke Enter. + +Okay, super. Unsere drei Prozesse laufen. Wir haben unser results Verzeichnis mit unseren drei Ausgaben. Bonjour. Hello. Holà. Also lass uns diese Dateien schließen, das Terminal schließen und zurück zum Skript gehen. + +## 1. Einen zweiten Schritt zum Workflow hinzufügen + +Okay. Für unser Beispiel bleiben wir einfach und versuchen, domänenunabhängig zu bleiben. Unser zweiter Prozess wird diese Zeichenketten, diese Wörter, einfach auf eine einfache Weise manipulieren. Wir werden den translate Unix-Befehl verwenden, um diese Dateien zu nehmen und sie alle in Großbuchstaben umzuwandeln. Das machen wir mit dem "tr" Befehl. + +## 1.1. Den Großschreibungsbefehl definieren und im Terminal testen + +Wir können das einfach im Bash-Terminal ausprobieren und sehen, ob es funktioniert. Du machst echo, Hello World, und übergibst das dann mit dem Pipe-Zeichen an tr, und wir geben ihm ein Erkennungsmuster, a bis z und wohin es übersetzt werden soll. A bis Z in Großbuchstaben. + +Das ist sehr einfach, weil es buchstäblich die A bis Z Zeichen macht. Es wird also nicht bei allem funktionieren, was Akzente hat oder so. Aber für die Zwecke des Beispiels solltest du das Bild verstehen. + +Werde Enter drücken und es druckt ins Terminal, HELLO WORLD in Großbuchstaben. Und genau wie zuvor könnten wir das zu einer Datei umleiten, wenn wir wollten. Outfile. + +Okay. Lass uns das aufräumen. + +## 1.1. Den Großschreibungsschritt als Nextflow Prozess schreiben + +Lass uns zurück zu unserem Skript gehen und einen neuen Prozess schreiben, um diesen Bash-Befehl zu handhaben. Ich werde den vorherigen Prozess kopieren, ihn darunter einfügen und ihn convert to upper nennen. Für Großbuchstaben. Ich werde dasselbe publishDir results verwenden, aber ich werde hier ein paar Änderungen vornehmen. Anstatt ein val zu nehmen, werde ich ein path input file nehmen, und ich werde hier ein Präfix upper haben, damit unsere Ausgabedateien die Ausgabe nicht überschreiben. Und ich werde den Variablennamen aus der Eingabe verwenden. Und dann werde ich das Skript hier unten ändern, und stattdessen werde ich cat für die Eingabedatei verwenden und genau wie wir es in Bash TR gemacht haben, a-z, upper input file .txt. Okay, lass uns speichern. + +## 1.2. Einen Aufruf des neuen Prozesses im Workflow-Block hinzufügen + +Jetzt, wenn ich nach unten scrolle, müssen wir diesen Prozess tatsächlich aufrufen. Nur den Prozess zum Skript hinzuzufügen reicht nicht aus. Wir müssen Nextflow sagen, dass wir diesen Prozess ausführen müssen und wo das zu tun ist. + +Also werde ich hier convert to upper schreiben und + +okay, wir bekommen hier einen Fehler, der sagt, es erwartet ein Argument. Sicher, wir müssen etwas an diesen Prozess übergeben, damit er tatsächlich etwas zu tun hat. + +## 1.3. Die Ausgabe des ersten Prozesses an den zweiten Prozess übergeben + +Was wir tun werden, ist, dass wir die Ausgabe von diesem Prozess nehmen werden. Also nehme ich den Namen, say hello, und wenn ich dot out mache. + +Für ein einfaches Beispiel wie dieses, wo wir einen Prozess haben, der nur eine Ausgabe hat, und wir das an einen neuen Prozess übergeben, der also eine Eingabe hat, sollte das alles sein, was wir brauchen. Also werde ich speichern, das Terminal aufrufen und lass uns das nochmal ausführen. + +## 1.4. Den Workflow erneut ausführen + +Jetzt habe ich mein work Verzeichnis vom letzten Mal, als ich diesen Workflow ausgeführt habe, nicht aufgeräumt. Ich werde es nochmal ausführen und ich werde das als Gelegenheit nutzen, um zu zeigen, wie partielles Caching funktioniert. Also wenn ich einzelnes Minus resume mache. Hoffentlich sollte es die Ausgaben von diesem ersten Prozess wiederverwenden, die genau dieselben waren wie beim letzten Mal, als ich ausgeführt habe. Aber jetzt haben wir hier einen neuen Prozess, der vorher nicht gelaufen ist, der von Grund auf neu läuft. Und tatsächlich kannst du sehen, dass der erste Prozess die Cache-Ausgaben verwendet hat und die zweite Ausgabe drei von drei ausgeführt hat. Du kannst auch sehen, dass wir jetzt beide unsere Prozesse hier haben, unser erster Prozess, say hello, lief dreimal, und unser zweiter Prozess convert to upper lief dreimal. + +Wenn ich das nochmal ausführe, zur Erinnerung, mit -ansi-log false, sollten wir sehen, dass sechs verschiedene Prozessaufgaben laufen, drei für jeden von ihnen. Das macht also genau das, was wir erhofft haben. Der erste Prozess läuft dreimal, übergibt diese Ausgaben an einen zweiten Prozess, der dann dreimal läuft. + +Also lass uns ins work Verzeichnis schauen und sehen, wie Nextflow diese Dateieingaben handhabt. Wenn ich dieses Hash-Verzeichnis hier vom zweiten Prozess nehme, können wir wieder den tree Befehl mit -a verwenden, nur um diese Dateien anzusehen. Du kannst hier drin sehen, dass wir unsere Eingabedatei haben, die die Bonjour-output.txt Datei ist, und das ist tatsächlich ein Symlink. Das ist es, was uns dieser Pfeil zeigt, und er zeigt auf die Datei im vorherigen work Verzeichnis. + +Das macht Sinn. Nextflow handhabt die Ausführung jeder Aufgabe in ihrem eigenen gekapselten Verzeichnis, also ist es vollständig in sich geschlossen. Allerdings muss es die Dateien von einem vorherigen Schritt als Eingabe bereitstellen. Anstatt außerhalb des work Verzeichnisses zu greifen, um diese Dateien zu bekommen, stellt Nextflow sie ins work Verzeichnis bereit. + +Wenn wir ein gemeinsames Dateisystem wie hier haben, macht es das mit einem Symlink, sodass es keinen zusätzlichen Dateiplatz verwendet. Wenn wir Cloud-Speicher mit Buckets an verschiedenen Orten verwenden, würde es diese Dateien abrufen und sie tatsächlich ins work Verzeichnis kopieren. + +Lass uns die command sh Datei ansehen. Wenn ich code work, command sh mache, kannst du sehen, tatsächlich greift es auf diese Datei aus dem lokalen Verzeichnis zu. Also ist alles sehr in sich geschlossen und sauber. + +Wir können auch das results Verzeichnis überprüfen und sicherstellen, dass diese Dateien ordnungsgemäß ausgegeben wurden. Und tatsächlich, in results, können wir alle Ausgabedateien vom ersten Prozess und alle Ausgabedateien vom zweiten sehen. Und sie sind alle in Großbuchstaben, wie wir gehofft hatten. + +Hier beginnt die Kraft von Nextflow zu glänzen. Mit sehr minimalem Code hat Nextflow die parallele Ausführung dieser Aufgaben mit sauberer Kapselung in separaten work Verzeichnissen und dem Bereitstellen von Ein- und Ausgabedateien und Dateiveröffentlichung automatisch für uns direkt aus der Box gehandhabt. Du kannst also sehen, wie wertvoll diese Funktionalität wirklich ist, wenn wir die Komplexität unserer Analyse-Workflows skalieren. + +## 2. Einen dritten Schritt hinzufügen, um alle Grüße zu sammeln + +Okay. Diese Schritte waren eins-zu-eins. Wir hatten eine Ausgabe vom ersten Prozess, die zu einer Eingabe für den zweiten Prozess ging. Als nächstes werden wir darüber sprechen, wie man diese verschiedenen Ausgaben in einer einzigen Prozessaufgabe sammelt, was wiederum eine sehr häufige Sache ist. Also lass uns schnell das Terminal aufrufen und einen Probelauf machen. + +## 2.1. Den Sammelbefehl definieren und im Terminal testen + +Ich werde schummeln und den Beispiel-Bash-Code aus dem Trainingsmaterial kopieren und einfach Enter drücken. + +Was wir hier sehen können, ist, dass wir diesen echo Befehl dreimal zu drei verschiedenen Ausgabedateien ausgeführt haben, die ich hier sehen kann. Und dann den cat Befehl verwendet haben, um die Ausgabe jeder dieser drei verschiedenen Dateien zu drucken und das zu einer einzigen gesammelten Datei umzuleiten. + +Und wenn ich "cat COLLECTED-output" mache, kannst du sehen, es hat die Inhalte dieser drei verschiedenen Dateien, jetzt in einer einzigen Datei. + +## 2.2. Einen neuen Prozess für den Sammelschritt erstellen + +Also lass uns sehen, ob wir dasselbe innerhalb unserer Nextflow Pipeline replizieren können. + +Lass uns nach oben scrollen und einen dritten Prozess erstellen. Ich werde diesen vorherigen kopieren, und diesmal werde ich ihn Collect Greetings nennen. + +Im Bash-Terminal haben wir es collected output txt genannt. Also werde ich hier denselben path output sagen. Und ich werde die Umleitung hier machen, damit es auf dieselbe Weise gespeichert wird. + +Okay. Wir müssen ändern, was am Anfang dieses Befehls passiert, und wir müssen darüber nachdenken, was hier die Eingabedatei ist. Tatsächlich wird dieser Prozess mehrere Eingabedateien nehmen. Ich werde path behalten und ich werde das zu einer neuen Variable namens input files, Plural, ändern. + +Ich werde sie dann wieder catten, wie wir es in unserem Bash-Skript gemacht haben. Und ich werde hier die Variable verwenden. + +Jetzt könntest du denken, das würde nicht funktionieren. Wir haben zuvor Fehler gesehen, wo ein Array von Zeichenketten oder ein Array von Pfaden an einen Prozess übergeben wurde und das einen Fehler verursacht hat. Aber tatsächlich wird Nextflow das hier automatisch für uns auf die richtige Weise handhaben. Es wird mehrere verschiedene Eingabedateien nehmen, und es wird einfach die verschiedenen Dateipfade hier drucken. + +Natürlich hilft es, dass der cat Befehl eine Reihe von Dateinamen wie diesen nehmen kann. Wenn ich einen anderen Befehl verwenden würde, der ein Argument vor jedem Dateipfad oder so erfordert, müssten wir hier etwas mehr Code und Logik haben, um die Iteration dieser Dateipfade handhaben zu können. Aber in diesem Fall sollte es einfach funktionieren. + +## 2.3. Den Sammelschritt zum Workflow hinzufügen + +Okay, lass uns runter zum Workflow gehen und unseren neuen Prozess hinzufügen. Collect greetings. Und wieder nehmen wir die Ausgabe von convert to upper out. Lass uns das speichern. + +Probieren wir es aus. nextflow run hello workflow. + +Okay, der Workflow lief, aber etwas ist hier etwas seltsam. Wir haben drei Ausführungen des ersten Schritts, was wir erwarten. Drei Aufgaben für den zweiten, aber wir haben auch drei Aufgaben am Ende, wenn wir erwartet haben, nur eine einzige Aufgabe hier zu haben, die alle Ausgaben zusammenführt. + +Wenn wir in unser results Verzeichnis gehen. Wir sehen auch, dass die gesammelte Ausgabe nur einen einzigen Wert hat statt aller drei. Das liegt daran, dass diese Ausgabedatei dreimal mit drei verschiedenen Werten überschrieben wurde. + +Das macht Sinn, weil wir hier eine Ausgabe zu einer Eingabe auf dieselbe Weise übergeben haben wie im vorherigen Schritt. + +## 2.4. Einen Operator verwenden, um die Grüße in eine einzige Eingabe zu sammeln + +Also brauchen wir hier einen Operator, um diesen Channel mit drei Elementen zu nehmen und sie zu einem einzigen Element zusammenzufassen, sodass dieser finale Prozess nur einmal läuft. + +Dafür werden wir den collect Operator verwenden. Ich kann das direkt innerhalb des Workflows machen. Ich kann .out machen und hier am Ende zu einem Operator verketten .collect. + +Speichern. Und dann für die Zwecke dieses Trainings werde ich auch einige view Operatoren machen, wie wir es zuvor getan haben, damit wir einen Blick auf diesen Channel vor und nach der Verwendung des collect Operators werfen können, damit wir verstehen können, was passiert. + +Ich werde diesen Channel nehmen, das collect loswerden und dot view greetings machen, und dann werde ich diese Zeile duplizieren, den collect Operator hinzufügen. Und das zu after ändern. + +Das ist getrennt davon, wo wir das aufrufen, aber das ist in Ordnung, weil wir dieselben Operator-Aufrufe auf demselben Ausgabe-Channel verwenden. + +Okay, lass uns speichern und im Terminal ausprobieren. Werde nextflow run machen. Hello, workflow. Unser Skript erneut ausführen. + +Okay. Das sieht besser aus. Wie zuvor können wir sehen, dass die ersten beiden Prozesse dreimal laufen und jetzt lief unser finaler Prozess nur einmal. + +Wenn wir uns ansehen, was vom view Operator gedruckt wurde, hier unten, sagten wir before collect, was diese Ausgabe hier ist, und das wurde dreimal gedruckt. Und du kannst sehen, es gibt einen einzelnen Pfad für jeden von denen. Und dann nach collect kannst du sehen, dass wir dieses Array von drei Pfaden haben. Also ist das wie erwartet. + +Okay, lass uns die results Datei überprüfen und sehen, ob es diesmal das ist, was wir erwarten. Tatsächlich, es gibt jetzt drei Zeilen in der Datei - das hat diese drei Ausgaben erfolgreich zu einer einzigen Ausgabedatei zusammengefügt. Fantastisch. + +Okay, ich werde aufräumen und lass uns zum nächsten Schritt gehen. Und ich werde diese view Anweisungen löschen, nur um die Dinge sauber zu halten. + +## 3. Mehr als eine Eingabe an einen Prozess übergeben, um die finale Ausgabedatei eindeutig zu benennen + +Okay. Bisher haben alle unsere Prozesse nur eine einzige Eingabe genommen. Wir werden jetzt eine Übung machen, wo wir mehr als eine Eingabe zu einem Prozess hinzufügen, um zu sehen, wie das funktioniert. Dafür werden wir dieses collect greetings Beispiel verwenden. + +Jedes Mal, wenn ich den Workflow ausgeführt habe, hat es diese Datei im results Verzeichnis überschrieben, was vielleicht nicht das ist, was wir wollen. + +## 3.1. Den Sammelprozess modifizieren, um einen benutzerdefinierten Namen für die Ausgabedatei zu akzeptieren + +Also für dieses Beispiel werden wir einen zusätzlichen Parameter übergeben, damit wir den Ausgabedateinamen anpassen können. + +Eine zweite Eingabe zu einem Prozess hinzuzufügen ist sehr einfach. Ich füge einfach eine zweite Zeile im input Block hinzu. Diesmal wird es ein value sein, anstatt ein path, weil wir einen String übergeben wollen, und ich werde es batch underscore name nennen. + +Ich kann diese Variable jetzt im script Block verwenden, und ich werde collected dash dollar batch name sagen. + +Ich verwende hier geschweifte Klammern um den Variablennamen. Das ist nur, um es vom Rest eines Strings getrennt zu halten, und es wird wahrscheinlich in diesem Fall nicht gebraucht, aber ich denke, es macht es einfacher zu lesen. + +Okay. Schließlich, denke daran, den Ausgabe-path zu aktualisieren, weil sich jetzt der Dateiname geändert hat, also werde ich dasselbe tun und den batch name in die Ausgabe von path wie erwartet einfügen. + +## 3.2. Einen Batch-Befehlszeilenparameter hinzufügen + +Wir müssen jetzt einen batch name von irgendwo übergeben, und ich werde einen zweiten Parameter erstellen, um das zu tun, damit wir es auf der Befehlszeile machen können, wenn wir den Workflow ausführen. + +Also werde ich params batch name machen, und standardmäßig, lass uns das test batch nennen. Jetzt kann ich diese spezielle Parameter-Variable unten verwenden, wo wir den Prozess aufrufen. + +Und tatsächlich sagt uns VS Code, dass es jetzt nicht genug Argumente für diesen Prozess gibt und dass es eine zweite Eingabe erwartet. + +Mache einfach Komma und übergebe unsere neue Variable und der Fehler verschwindet. + +Beachte, dass die Reihenfolge der Eingaben hier wirklich wichtig ist. Die erste Prozesseingabe war der path, und die zweite Eingabe ist der Name. Wenn ich die Reihenfolge hier ändere, muss ich auch die Reihenfolge ändern, wenn ich den Prozess aufrufe. Andernfalls. Als nächstes werden wir den falschen Channel zur falschen Eingabe übergeben. + +## 3.3. Den Workflow ausführen + +Okay, lass uns es ausprobieren und sehen, ob es funktioniert. Lass uns "nextflow run hello- workflow machen. Okay, es lief wie zuvor. Lass uns ins results Verzeichnis schauen. + +Tatsächlich, unser Dateiname hier heißt jetzt " collected test batch output txt". Fantastisch. + +Und jetzt lass uns sehen, ob wir das überschreiben können, indem wir nochmal ausführen. Diesmal werde ich --batch_name machen, um mit diesem speziellen Parametervariablennamen hier übereinzustimmen. Und ich werde es demo output nennen. + +Den Workflow nochmal ausführen und wir werden sehen, ob etwas passiert. + +Okay, wir haben jetzt ein collected demo output .txt. Und weil dieser Dateiname anders ist als jener, hat es ihn nicht überschrieben. Beide sind jetzt im results Verzeichnis vorhanden. + +## 4. Eine Ausgabe zum Sammelschritt hinzufügen + +Okay, dort haben wir also gezeigt, wie man mehrere Eingaben an einen Prozess gibt, aber wie ist es mit mehreren Ausgaben? Für dieses Beispiel werden wir die Anzahl der Grüße berechnen, die verarbeitet werden, und das als sekundäre Ausgabe für diesen collect greeting Schritt ausgeben. + +## 4.1. Den Prozess modifizieren, um die Anzahl der Grüße zu zählen und auszugeben + +Wir werden hier einen kleinen Trick machen. Nextflow Prozesse haben diesen script Block mit einem mehrzeiligen String, und der wird als Bash-Ausgabe an den dot Befehl dot sh übergeben. Aber wir können tatsächlich beliebigen benutzerdefinierten Code darüber schreiben, und der wird als Teil einer Aufgabe ausgeführt, aber nicht im Bash-Skript enthalten. + +Eine der eingebauten Funktionen in der Nextflow Syntax heißt size. Also werde ich die path Eingabe nehmen, und ich werde count underscore greetings sagen, nur um einen Variablennamen zu definieren. Ich werde die input files nehmen und ich werde "size" darauf aufrufen. + +Diese Funktion wird die Größe dieses Eingabe-Channels zählen und sie einer Variable zuweisen. + +Wir können diese Variable jetzt als Teil des output Blocks zurückgeben. Also sagen wir val, weil es ein Wert ist, keine Datei. Und count greetings. + +Jetzt reicht das für sich selbst aus, und wir könnten jetzt auf diese verschiedenen Ausgaben von diesem Prozess zugreifen. Allerdings müssten wir auf sie in einer positionellen Weise zugreifen. Also mit einem Index-Schlüssel wie null und eins. + +Um es ein bisschen einfacher zu machen, an die Ausgaben zu kommen, können wir sie benennen und wir machen das, indem wir eine emit Anweisung verwenden. + +Also machen wir Komma emit out file oder wie auch immer ich das nennen möchte. Und ich mache hier emit count. Das ist im Grunde nur ein Dekorator, der uns hilft, etwas saubereren Code zu schreiben, damit wir später im workflow Block leicht auf die spezifischen Ausgaben verweisen können. + +## 4.2. Die Ausgabe am Ende des Workflows berichten + +Okay. Wenn ich runter zum workflow Block scrolle, kann ich jetzt die Ausgaben von collect greetings nehmen, collect greetings machen, dot out, und wir können unsere zwei benannten Ausgaben sehen, die hier von der VS Code Extension vorgeschlagen werden. Sehr praktisch. + +Also werde ich dot count machen, um den count Wert zu bekommen, den wir gerade erstellt haben, und ich werde view machen, damit es in der Befehlszeile gedruckt wird. Damit wir es sehen können, wenn wir den Workflow ausführen. + +Lass uns hier etwas in die Closure schreiben, nur um es ein bisschen schöner zu machen. num greetings, there were greetings greetings. + +Und uns ist die andere Ausgabe eigentlich egal, weil wir sie nicht als Eingabe für irgendwelche anderen Prozesse verwenden. Aber du kannst sehen, wie wir das leicht als Eingabe für einen anderen Prozess übergeben könnten, wenn wir wollten, downstream. + +## 4.3. Den Workflow ausführen + +Wir werden speichern. Lass uns ins Terminal schauen und es ausprobieren. + +Okay, fantastisch. Hier sind wir. There are three greetings. Das ist genau richtig. + +Okay, super. Das ist das Ende dieses Kapitels. Wir sind fertig, weil wir es soweit geschafft haben. Du baust jetzt einen ziemlich realistischen Workflow auf, wo wir in der Lage sind, Eingaben und Ausgaben und Logik innerhalb unseres Workflows zu handhaben. + +Wenn diese Workflow-Dateien länger werden, beginnen sie ein wenig unhandlich zu werden. Also werden wir im nächsten Kapitel uns ansehen, wie wir Nextflow Code in separate Dateien modularisieren können, sodass es einfacher ist, den Code innerhalb des Workflows zu finden und zu pflegen. + +Begleite uns im nächsten Video für Kapitel vier. Hello Modules. + +[Nächstes Video-Transkript :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/de/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..d9d427290f --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Teil 4: Hello Modules - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../04_hello_modules.md) zurück. + + Die im Transkript angezeigten Abschnittsnummern dienen nur zur Orientierung und enthalten möglicherweise nicht alle Abschnittsnummern aus den Materialien. + +## Willkommen + +Hi, willkommen zu Teil Vier des Hello Nextflow Trainingskurses. + +Dieses Kapitel heißt Hello Modules, und wir werden darüber sprechen, wie man Nextflow-Code modularisiert. Was wir tun werden, ist unser Workflow-Skript zu nehmen und es in separate Dateien aufzuteilen. + +Das macht den Code einfacher zu navigieren und zu warten, wenn dein Workflow größer wird, und ermöglicht es auch, Module zwischen Pipelines zu teilen, sodass du, wenn du mehrere Pipelines mit demselben Tool hast, diesen Prozess nur einmal schreiben musst. + +Ein klassisches Beispiel dafür ist das nf-core Modules Repository, das Tausende verschiedener Tools in gebrauchsfertigen Modulen hat, die du installieren und in deinem Workflow verwenden kannst. + +Nextflow kann auch mit Sub-Workflows arbeiten, die wie Module sind, aber mehrere Prozesse haben. Das liegt außerhalb des Umfangs dieses Trainings, aber es funktioniert im Grunde auf die gleiche Weise. + +Okay. Lass uns einen Blick darauf werfen. + +Wie üblich beginne mit dem Aufrufen von training.nextflow.io. + +Gehe zu "Hello Nextflow" in der Seitenleiste, und wir machen Teil vier: "Hello Modules". + +Ich werde jetzt in meine GitHub Codespaces Umgebung springen und mir die Datei "hello-modules" ansehen. + +Genau wie zuvor starten wir am Endpunkt des vorherigen Kapitels, also sollte dir dieses Skript bekannt vorkommen. Wir haben unsere drei Prozesse, say hello, convert to upper und collect greetings, und einen einfachen Workflow, der diese drei Befehle ausführt und am Ende eine Nachricht ausgibt. Wir haben zwei Parameter namens greeting und batch, die den Namen angeben, der für die gesammelte Ausgabedatei am Ende verwendet wird. + +## 0. Aufwärmen: hello-modules.nf ausführen + +Wir können überprüfen, dass dieser Workflow noch wie erwartet funktioniert, indem wir nextflow run hello modules ausführen. + +Großartig. Es hat drei Aufgaben mit jedem dieser Prozesse ausgeführt, eine collect-Aufgabe, und es hat uns mitgeteilt, dass es drei Grüße in diesem Batch gibt. Wenn wir in results gehen, haben wir hier unsere verschiedenen Ausgabedateien, einschließlich der gesammelten test batch Ausgabe. + +## 1. Ein Verzeichnis zum Speichern von Modulen erstellen + +Richtig. Lass uns etwas Modularisierung vornehmen. + +Es ist generell eine gute Idee, Module in einen Unterordner in deinem Pipeline-Repository zu legen, einfach um die Dinge aufgeräumt zu halten. Du kannst das nennen, wie du willst, aber per Konvention nennen wir es normalerweise modules. + +Also lass uns loslegen, gehe in ein Terminal und mache make dir modules. Du kannst sehen, wie es in der Seitenleiste in VS Code hier auftaucht. + +## 2. Ein Modul für sayHello() erstellen + +Ich werde dann eine neue Datei für mein erstes Modul erstellen. Du kannst "touch" oder "code" verwenden oder du kannst das in der Seitenleiste machen, es ist wirklich egal. Also werde ich code modules machen und ich werde es nach dem Prozess benennen. Also sayHello.nf. NF ist eine traditionelle Dateierweiterung für Nextflow-Dateien. + +Werde hier speichern und wir können sehen, wie unsere neue Moduldatei auftaucht. + +## 2.2. Den sayHello Prozess-Code in die Moduldatei verschieben + +Richtig, als Nächstes werde ich den Modulcode aus dem Workflow nehmen. Ich werde auch den Shebang hier nehmen und den zuerst kopieren, damit es eindeutig eine Nextflow-Datei ist. Und dann werde ich diesen Prozess nehmen und ich werde ihn ausschneiden. Also werde ich ihn aus meinem Haupt-Workflow-Skript entfernen und ich werde ihn in dieses neue Modul einfügen. + +Das ist der gesamte Inhalt, den diese Moduldatei enthalten wird. Nur ein einzelner Prozess, kein Workflow, keine Logik, nur ein Prozess allein. + +Ich kann diese Datei jetzt schließen. + +## 2.3. Eine Import-Deklaration vor dem Workflow-Block hinzufügen + +Jetzt fehlt meinem Workflow dieser erste Prozess, also müssen wir ihn zurückbringen, indem wir ihn importieren. Die Syntax dafür ist sehr ähnlich zu anderen Programmiersprachen, also könnte sie sich vertraut anfühlen. Wir machen include geschweifte Klammern, den Namen des Prozesses, say hello, und dann from dem Dateipfad modules, say hello, nf. Fantastisch. + +Ein paar Tricks hier. Die VS Code Erweiterung ist clever in dieser Hinsicht. Sie erkennt diesen Dateipfad und du kannst mit der Maus darüber fahren und auf Link folgen klicken. Oder ich bin auf Mac, ich kann Option-Klick machen und es öffnet diese Datei. So können wir schnell zu ihr springen. + +Dieser Prozessname wird jetzt vom Workflow hier unten verwendet, und wir können dasselbe hier machen. Es zeigt uns ein bisschen Information über diesen Prozess, und wieder kann ich Option halten, darauf klicken, und es wird ihn im Editor öffnen. + +Es ist also eine wirklich schnelle Möglichkeit, wenn du viele Dateien für deine verschiedenen Prozesse hast, schnell in deiner Codebasis in VS Code zu navigieren. + +Okay. Das ist im Grunde alles für dieses Kapitel. Jetzt machen wir einfach dasselbe noch einmal für die anderen Prozesse. + +## 3. Den convertToUpper() Prozess modularisieren + +Also lass uns hier eine neue Datei erstellen. Nenne sie Convert to upper nf. Wieder den Shebang kopieren. Und dann den Prozess ausschneiden. + +Den Prozessnamen dort kopieren, ein neues include-Statement mit dem neuen Prozessnamen einfügen. + +## 4. Den collectGreetings() Prozess modularisieren + +Und dann dasselbe für den dritten Prozess machen. Neue Datei, collect greetings, + +den Shebang machen. Den Prozess ausschneiden, den Prozess einfügen, und ein neues include-Statement machen. + +Jetzt kannst du hier sehen, dass ich eine Fehlerunterstreichung habe, die sagt invalid include source. Und das ist tatsächlich ein echter Fehler, den ich gemacht habe, weil ich ein bisschen zu schnell unterwegs war. Wenn du genau hinsiehst, kannst du sehen, dass ich das T verpasst habe in convert to upper. + +Also hat VS Code mir sehr hilfreich mitgeteilt, dass ich dort einen Fehler gemacht habe. Wenn ich diesen Dateinamen korrigiere, verschwindet der Fehler. Es ist ein gutes Beispiel dafür, warum die Fehlerprüfung in VS Code so nützlich ist für das Schreiben von Nextflow-Code. Sonst hätte ich das nicht bemerkt und hätte es erst viel später herausgefunden, wenn ich versucht hätte, den Workflow auszuführen. + +Unser Haupt-Pipeline-Skript sieht jetzt viel einfacher aus. Es hat keine Prozesse mehr drin, wir haben nur drei include-Statements und unseren Workflow. Wir haben nichts an der Logik des Workflows geändert. Wir haben nichts am Prozess-Code geändert, also sollte es hoffentlich auf genau die gleiche Weise funktionieren. + +## 4.4. Den Workflow ausführen, um zu überprüfen, dass er dasselbe tut wie zuvor + +Lass uns das überprüfen. Ich werde ein Terminal öffnen und ich werde genau denselben Befehl wie zuvor ausführen. + +Sicher genug, es hat unsere Prozesse ausgeführt, say hello, convert to upper, collect greetings, und uns wieder drei Grüße gegeben. + +Also haben wir unseren Code herumverschoben, aber wir haben nichts daran geändert, wie der Workflow ausgeführt wird, und er ist komplett unverändert. Der einzige Unterschied ist, dass wir jetzt saubereren Code haben, einfacher zu warten und einfacher mit anderen zu teilen. + +Und das war's. Es war ein kurzes Kapitel. Es ist ein einfaches Konzept, aber es ist sehr mächtig und zentral dafür, wie wir komplexere Nextflow-Workflows schreiben. Also ist es wichtig, dass du es verstehst und dir angewöhnst, es zu verwenden. + +Im nächsten Kapitel werden wir das Tempo ein wenig wechseln und aufhören, so viel über die Syntax des Schreibens von Nextflow-Code nachzudenken, und ein wenig darüber nachdenken, wie wir Software in den Prozessen selbst verwenden. Begleite uns in Teil fünf für Hello Containers. + +[Nächstes Videotranskript :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/de/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..b836b86973 --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Teil 5: Hallo Container - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../05_hello_containers.md) zurück. + + Die im Transkript gezeigten Abschnittsnummern dienen nur zur Orientierung und umfassen möglicherweise nicht alle Abschnittsnummern in den Materialien. + +## Willkommen + +Hallo, willkommen zu Teil Fünf des Hello Nextflow Trainingskurses. + +Dieses Kapitel heißt Hallo Container. Wir werden darüber sprechen, wie Nextflow mit Tools wie Docker und Singularity integriert wird, um Software-Container zu verwenden und Software für die Nutzer deiner Pipeline bereitzustellen. + +Das bedeutet, dass Leute, die deine Pipeline ausführen, nicht selbst alle verschiedenen Tools installieren müssen. Nextflow erledigt das für sie. + +Container sind eine extrem leistungsstarke Technologie und entscheidend für Reproduzierbarkeit und Benutzerfreundlichkeit. Wir beginnen mit einer kurzen Einführung in Container selbst, führen einige Docker-Befehle manuell aus und integrieren dann dieselben Container in unsere Nextflow-Pipeline. + +Okay. Lass uns anfangen. + +Wie zuvor starten wir mit dem Laden des Trainingsmaterials. Gehe zu training.nextflow.io. Hello Nextflow, Kapitel Fünf, Hallo Container. + +Ich wechsle in meine Codespaces-Umgebung und auf der linken Seite sehen wir hello containers dot nf. + +Wie zuvor ist dies dasselbe Skript, mit dem wir das vorherige Kapitel vier beendet haben, es sollte also vertraut aussehen. + +Wir haben unsere Befehlszeilenparameter zur Angabe der Eingabedatei und des Batch-Namens. Wir binden unsere drei Module ein, und wir haben unseren Workflow, in dem wir die drei Prozesse ausführen. + +## 0. Aufwärmen: hello-containers.nf ausführen + +Du kannst diesen Workflow gerne erneut ausführen und überprüfen, ob er die Ausgaben erzeugt, die du erwartest. Vorerst werde ich ihn tatsächlich schließen und ins Terminal eintauchen. + +## 1. Einen Container 'manuell' verwenden + +Zu Beginn dieses Kapitels werden wir eine kleine Wiederholung der Container-Technologie machen. Wenn du sehr vertraut mit Docker oder Singularity oder anderen Container-Technologien bist, dann betrachte dies als Auffrischung oder überspringe es gerne komplett. + +Nextflow unterstützt viele verschiedene Arten von Container-Technologien. Dazu gehören Docker, Singularity, Podman, Shifter, Charliecloud und mehr. + +In diesem Training konzentrieren wir uns auf Docker. Das ist in den Code Spaces vorinstalliert und ist eine der beliebtesten Container-Technologien, besonders wenn du auf deinem eigenen Computer oder Laptop entwickelst. + +Wenn du in einer akademischen Umgebung auf einem gemeinsam genutzten HPC arbeitest, wirst du vielleicht feststellen, dass Singularity verfügbar ist und nicht Docker. Das ist in Ordnung. Alle Konzepte sind genau gleich. Ein paar der manuellen Befehle sind unterschiedlich, aber wenn du Docker verstehst, verstehst du auch Singularity. + +Tatsächlich ist Singularity auch in der Code Spaces-Umgebung installiert. Wenn du möchtest, kannst du also versuchen, dieselben Aufgaben mit Singularity anstelle von Docker zu erledigen. + +Okay, was ist also Container-Technologie? Die Idee hinter Docker ist, dass es ein Image aus einer entfernten Quelle holen kann. Es auf deine lokale Maschine herunterladen und dann einen Container basierend auf diesem Image erstellen kann. + +Dieser laufende Container ist ein bisschen wie eine virtuelle Maschine, die auf deinem Computer läuft. Er ist von deiner Umgebung isoliert und kommt vorpaketiert mit einem Betriebssystem und einer Reihe verfügbarer Software. + +## 1.1. Das Container-Image herunterladen + +Die Syntax, die wir benötigen, um ein bereits existierendes Image zu holen, ist "docker pull". Ich werde das also in mein Terminal tippen, aber jetzt brauchen wir ein Image zum Experimentieren. + +Du kannst Images selbst erstellen. Du kannst sie auf öffentlichen Registries wie Docker Hub oder quay.io finden. Aber eine wirklich gute Möglichkeit, schnell Images zu bekommen, ist die Verwendung von Seqera Containers. + +Dies ist ein kostenloser Community-Service, den wir 2024 erstellt haben und den du ohne Login oder ähnliches nutzen kannst. + +Wenn du zu seqera.io/containers gehst oder oben auf Containers klickst, wird dir eine Suchoberfläche präsentiert und du kannst den Namen eines beliebigen Tools eingeben, das in Conda oder im Python Package Index verfügbar ist. + +Standardmäßig durchsucht es die Bioconda- und Conda Forge-Kanäle, aber du kannst jedem Conda-Kanal ein Präfix voranstellen, wenn du möchtest. + +Zum Spaß verwenden wir cowpy. Ich werde cowpy eingeben. Es gibt mir Ergebnisse aus dem Python Package Index und Conda Forge. Ich werde darauf klicken, um es zu meinem Container hinzuzufügen. Ich könnte hier mehrere Pakete hinzufügen, wenn ich wollte. Wähle Docker, wähle linux/amd64 und klicke auf Get Container. + +Dies erstellt das Image bei Bedarf für mich, falls es noch nicht erstellt wurde, und gibt mir eine URL, die ich kopieren kann. + +Wenn du interessiert bist, kannst du auf View Build Details klicken, und das führt dich zu einer Seite, die die verwendete Conda-Umgebungsdatei und das vollständige Build-Protokoll für den Build zeigt, zusammen mit den Ergebnissen des Sicherheitsscans. + +Wenn ich zurück zu meinen Code Spaces gehe, kann ich jetzt diesen Container-Namen einfügen und Enter drücken. + +Docker lädt jetzt alle verschiedenen Schichten innerhalb dieses Container-Images herunter und teilt uns dann mit, dass dieses Image zur Verwendung verfügbar ist. + +## Ein Singularity-Image herunterladen + +Wenn du Singularity verwendest, ist der Prozess im Grunde derselbe. Wir wählen unsere Image-Pakete aus, wählen cowpy. Jetzt wählen wir Singularity anstelle von Docker und klicken auf Get Container. Das gibt uns eine Image-URL mit oras://. Oder wenn du möchtest, kannst du https:// verwenden, indem du dieses Kästchen ankreuzt. Kopiere diese URL. Jetzt gehe zu Code Spaces. Wir haben tatsächlich Apptainer in diesem Space installiert, was dasselbe ist wie Singularity, aber sie sind aneinander aliasiert. Also werde ich apptainer pull machen und dann werde ich es cowpy sif nennen, aber du kannst es nennen, wie du willst. Füge die URL ein. Und das wird dieses Image für mich herunterladen. + +Ich könnte ls -lh machen und cowpy.sif sehen + +Singularity unterscheidet sich von Docker darin, dass Singularity alle Images in flachen Dateien speichert, während Docker eine Registry hat, in der es alle Schichten separat auf deinem Host-Rechner aufbewahrt, und es hat einen laufenden Daemon, um das alles zu verfolgen. + +## 1.2. Den Container verwenden, um cowpy als einmaligen Befehl auszuführen + +Okay, lass uns zurück zu Docker gehen. Wir können jetzt versuchen, dieses Image, das wir erstellt haben, auszuführen, indem wir docker run machen. + +Ich werde dash dash rm machen, was nur eine einmalige Ausführung des Images durchführt. Und ich werde die Image-URL einfügen. Und dann beendest du dies mit einem Befehl, den du ausführen möchtest. + +Das Image, das wir generiert haben, hatte cowpy installiert, also lass uns cowpy versuchen. + +Da haben wir es. Es hat unseren Befehl ausgeführt. Ich habe cowpy nicht lokal installiert. Du kannst sehen, wenn ich versuche es auszuführen, existiert es nicht. Jedoch habe ich es in diesem Befehl mit Docker ausgeführt und es hat korrekt diese Ausgabe erzeugt. + +## 1.3. Den Container verwenden, um cowpy interaktiv auszuführen + +Wir können noch weiter gehen, wenn wir möchten, und einen Container interaktiv starten und darin herumsehen. Wieder mache ich "docker run dash dash rm". Jetzt werde ich dash it machen, was Docker sagt, dass wir ein interaktives Terminal wollen. Ich mache wieder die Image-URL, und dieses Mal, anstatt cowpy zu machen, werde ich bin bash machen, weil der Befehl, den wir ausführen wollen, bash ist. + +Das bringt uns in diesen laufenden Container und du kannst sehen, dass sich die Eingabeaufforderung jetzt geändert hat. + +Wenn ich LS slash mache, kannst du sehen, dass die Verzeichnisse hier anders sind. + +Wenn ich hier rechts ein zweites Terminal öffne, das einfach in GitHub Code Spaces läuft, und LS slash mache, siehst du, dass wir Verzeichnisse wie workspaces und temp haben, während es drüben in Docker anders ist. + +Diese Umgebung ist also innerhalb von Docker vollständig getrennt und von meiner Host-Umgebung isoliert. Das ist eine gute Sache, weil das die Ausführung dieses Befehls im Docker-Image isoliert und es zwischen verschiedenen Personen auf verschiedenen Host-Systemen reproduzierbar hält. + +Wenn du Daten von deinem Host-System innerhalb des Docker-Images verwenden möchtest, musst du das explizit in den Container mounten. + +Wir werden das gleich machen. + +## 1.3.2. Die gewünschten Tool-Befehle ausführen + +Aber zuerst, lass uns sehen, ob wir cowpy ausführen können. Da nochmal, der Befehl ist jetzt direkt auf der Befehlszeile verfügbar, und wir können anfangen, komplexere Dinge zu tun und Argumente zu übergeben. Hello containers und anstelle der Kuh, lass uns den Tux-Pinguin nehmen. Mal sehen, was wir noch haben. + +Lass uns Käse machen. Wunderbar. Wie wäre es mit Drache und Kuh? Ziemlich gut. + +## 1.3.3. Den Container verlassen + +Okay. Ich kann nicht viel mehr machen, weil ich keine Daten in diesem Container habe. Also lass uns aus diesem laufenden Image aussteigen und sehen, ob wir einige Daten in den Container mounten können. Ich kann das machen, indem ich Strg D mache oder exit tippe. Okay, ich bin jetzt zurück in meinem regulären GitHub Code Space. + +## 1.3.4. Daten in den Container mounten + +Um einige Daten in den Docker-Container zu mounten, muss ich dash V verwenden. Also werde ich meinen vorherigen Docker-Befehl nehmen, zum Anfang zurückgehen und dash v machen. Ich werde "." für das aktuelle lokale Arbeitsverzeichnis machen, und dann einen Doppelpunkt, um zu sagen, wo das im Host-Verzeichnis gemountet werden soll, und mache slash data. Das mountet also dieses bestimmte Verzeichnis in den Container bei slash data. + +Wenn ich jetzt LS slash mache, können wir sehen, dass wir ein neues Verzeichnis namens data haben, und wenn ich LS data mache, kannst du alle Dateien sehen, die wir hier in der Seitenleiste haben. Fantastisch. + +## 1.3.5. Die gemounteten Daten verwenden + +Jetzt können wir anfangen, einige der Dateien zu verwenden, die auf dem Host-System sind, innerhalb des Docker-Images. Also kann ich cat data greetings csv sagen. Wenn du dich erinnerst, das ist unsere CSV-Datei mit unseren verschiedenen Grüßen von vorhin, und ich kann das zu cowpy pipen. Fantastisch. Jetzt kommen wir irgendwohin. + +Okay. Das reicht für die interaktive Ausführung von Docker. Hoffentlich hast du jetzt ein Gefühl dafür, was Docker ungefähr ist und wie man es sowohl verwendet, um einen Befehl einmalig auszuführen, als auch ein Image interaktiv zu verwenden. Wenn du Singularity verwendest, sind die Befehle alle sehr ähnlich, außer dass du Dinge wie apptainer exec oder apptainer run oder singularity exec oder singularity run machst. + +## 2. Container in Nextflow verwenden + +Als Nächstes gehen wir zurück zu unserem Nextflow-Workflow und sehen, wie man diese Technologie innerhalb der Nextflow-Pipeline verwendet. + +Lass uns das Terminal schließen und Hello Containers wieder öffnen. + +## 2.1. Ein cowpy-Modul schreiben + +Um bei unserem cowpy-Beispiel zu bleiben, lass uns einen neuen Prozess in unserem Workflow erstellen, der cowpy verwendet. Lass uns zu Modulen gehen, eine neue Datei erstellen und sie cowpy nf nennen. Ich werde jetzt ein bisschen schummeln und den Code aus dem Trainingsmaterial kopieren und auf Speichern drücken. Und schauen wir uns das an. + +Das ist also ein einfacher Prozess. Hoffentlich verstehst du jetzt, wie die Bausteine eines Prozesses aussehen. Wir haben wieder unser publishDir, das zu results geht. Wir haben zwei Eingaben, eine Eingabedatei und einen String namens character. Wir haben eine Ausgabe cowpy input file, und wir haben ein Skript, das genau so aussieht, wie das, was wir vor einer Sekunde manuell in unserem Docker-Image ausgeführt haben: cat, um eine Datei zu drucken, das auf cowpy zu pipen, zu sagen, welche Art von cowpy-Charakter wir verwenden wollen, und das in die Ausgabedatei auszugeben, die wir hier als Ausgabe übergeben. + +## 2.2. cowpy zum Workflow hinzufügen + +Okay, lass uns zurück zu unserem Workflow gehen, diesen neuen Prozess importieren. Also cowpy from modules cowpy nf. Lass uns einen neuen Parameter erstellen, damit wir angeben können, welchen Charakter wir wollten. Sagen wir standardmäßig Turkey. Und dann lass uns diesen neuen Prozess am Ende des Workflows aufrufen, + +cowpy. Und lass uns die Ausgabe hier von Collect Greetings verwenden. Also collect greetings out, out file hier. Und dann brauchen wir ein zweites Argument, das die neuen params sind, die wir gerade gemacht haben. params dot character. + +## 2.2.4. Den Workflow ausführen, um zu überprüfen, dass er funktioniert + +Okay, lass uns sehen, ob unser neuer Prozess funktioniert. Nextflow run hello containers. Das sollte diese ersten drei Prozesse ausführen und dann versuchen, cowpy am Ende auszuführen. + +Wir haben einen Fehler. Was es hier sagt, cowpy hatte einen Fehler und es hatte einen Exit-Status 127 und tatsächlich, Befehl sh cowpy command not found. + +Wir haben Nextflow nicht gesagt, dass wir ein Docker-Image für cowpy verfügbar haben, also hat es versucht, es auf unserem Host-System auszuführen, und wir haben cowpy nicht auf unserem Host-System installiert, also hat es einen Fehler ausgelöst. + +## 2.3. Einen Container verwenden, um es auszuführen + +Was wir also tun müssen, ist Nextflow zu sagen, dass wir einen Container verfügbar haben. Lass uns zu unserem cowpy-Prozess gehen und wir werden eine neue Direktive oben im Prozess hinzufügen, die container heißt. + +Wir finden dann unser Image, kopieren die URL und setzen das in einen String. + +Das reicht allein nicht aus, weil eine Nextflow-Pipeline mehrere Möglichkeiten haben kann, Software anzugeben. Ich könnte auch conda conda-forge cowpy machen, zum Beispiel. Und Nextflow muss wissen, welche dieser Technologien du verwenden möchtest. + +## 2.3.2. Die Verwendung von Docker über die nextflow.config-Datei aktivieren + +Um also mit aktiviertem Docker auszuführen, werden wir uns etwas vorgreifen und die Nextflow-Config-Datei verwenden, was etwas ist, das wir im nächsten Kapitel ausführlicher behandeln werden. Du kannst in diesem Verzeichnis sehen, dass wir eine Datei namens Nextflow Config haben, und hier hast du bereits docker.enabled False. + +Wir werden das auf True ändern, um Docker zu aktivieren, und dann können wir versuchen, den Workflow erneut auszuführen. + +## 2.3.3. Den Workflow mit aktiviertem Docker ausführen + +Nextflow run hello containers nf und dieses Mal wurde cowpy erfolgreich ausgeführt. Lass uns in Results nachsehen. cowpy collected test und da ist unser Truthahn. Wunderbar. + +Im Hintergrund dort wusste Nextflow also, dass es einen Container für diesen Prozess verfügbar hatte. + +Es hat das Image geholt und die Befehle für uns ausgeführt. + +## 2.3.4. Untersuchen, wie Nextflow die containerisierte Aufgabe gestartet hat + +Wenn du neugierig bist, können wir tatsächlich genau sehen, was es gemacht hat, indem wir in das Arbeitsverzeichnis schauen. Wenn ich code work mache, und dann den Hash und dann command run, was, wenn du dich erinnerst, die tatsächliche Datei ist, die für diese Aufgabe ausgeführt wird, können wir hineingehen und nach einer Funktion namens NXF launch suchen. Und hier kannst du den genauen Docker-Befehl sehen, den Nextflow verwendet hat, der viel wie das aussieht, was wir manuell im Terminal vorhin gemacht haben. Docker run. Dieses Host-Verzeichnis in den Container binden, und dann die Container-URL angeben. + +Es gibt hier also keine Magie. Es ist nur so, dass Nextflow automatisch die schwere Arbeit für dich erledigt auf eine Weise, die bedeutet, dass du einfach Container in deiner Pipeline angeben kannst, die dann für jeden anderen, der deinen Workflow ausführt, leicht verfügbar sind. Und diese Leute müssen nicht mehr darüber nachdenken, Software zu verwalten, um deine Analyse-Pipeline auszuführen. + +Sehr, sehr einfach, sehr bequem und auch wirklich reproduzierbar. Rundum gut. + +Okay, großartige Arbeit. Das ist das Ende von Kapitel Fünf. Schließ dich uns im nächsten Video für Teil sechs an, das der letzte Teil dieses Hello Nextflow Trainings ist, wo wir ausführlicher über Nextflow-Konfiguration sprechen werden. + +Wir sehen uns im nächsten Video. + +[Nächstes Video-Transkript :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/de/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..e9e1c1ddec --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Teil 6: Hello Config - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../06_hello_config.md) zurück. + + Die im Transkript angezeigten Abschnittsnummern dienen nur zur Orientierung und umfassen möglicherweise nicht alle Abschnittsnummern im Material. + +## Willkommen + +Hallo, willkommen zu Teil sechs des Hello Nextflow Trainingskurses. + +Dieses Kapitel heißt Hello Config und ist der letzte Teil unseres Trainingskurses. + +In diesem Kapitel werden wir über Nextflow-Konfiguration sprechen. Die Nextflow-Konfiguration ist wirklich leistungsstark. Sie ermöglicht es uns, dieselbe Pipeline auf mehreren verschiedenen Computing-Infrastrukturen mit unterschiedlicher Software-Bereitstellung und verschiedenen Optionen in der Pipeline selbst auszuführen. + +Das bedeutet, dass du Nextflow-Pipelines, die von anderen Leuten erstellt wurden, auf deinem System ausführen kannst, obwohl sie möglicherweise für eine völlig andere Infrastruktur erstellt wurden. Diese Fähigkeit, Nextflow zu konfigurieren, macht Workflows wirklich portabel und gemeinsam nutzbar. + +In diesem Kapitel werden wir den Workflow verwenden, den wir in früheren Teilen erstellt haben, aber wir werden den Workflow-Code überhaupt nicht bearbeiten. Wir werden uns nur unsere Nextflow-Konfigurationsdatei ansehen und sehen, wie das Ändern der Konfiguration die Art und Weise verändert, wie Nextflow läuft. + +Okay, lass uns anfangen. + +Genau wie zuvor, lass uns damit beginnen, zu training.nextflow.io zu gehen. Gehe links zu Hello Nextflow und Kapitel sechs, Hello config. Ich werde jetzt in meine GitHub Codespaces-Umgebung gehen und das Skript überprüfen, das wir verwenden werden. + +## 0. Aufwärmen: Überprüfe, dass Docker aktiviert ist und führe den Hello Config Workflow aus + +Dieses hier heißt Hello Config und beginnt dort, wo wir vorher waren. Also sieht es genau gleich aus mit unseren drei Parametern: Greetings für die CSV-Datei, batch für den Ausgabe-Batch-Namen und character für den Cowpy-Namen. Wir haben unsere vier Imports der verschiedenen Prozesse, und dann haben wir einen Workflow, in dem wir sie miteinander verknüpfen. + +Ich werde diese Datei jetzt tatsächlich schließen, weil wir die Nextflow-Datei in diesem Kapitel überhaupt nicht anfassen werden. Wir werden rein innerhalb der Konfigurationsdatei arbeiten. Wenn ich in die Nextflow.config-Datei schaue, die wir im vorherigen Kapitel fünf kurz betrachtet haben, können wir sehen, dass wir hier eine einzelne Anweisung haben: Docker enabled equals true, die Nextflow mitteilt, Docker zu verwenden, wenn dieser Workflow ausgeführt wird. + +Ich verwende Nextflow.config im Pipeline-Stammverzeichnis hier, die automatisch geladen wird, wenn ich Nextflow ausführe. Aber denk daran, Nextflow kann Konfigurationsdateien von mehreren Orten laden. + +Wenn ich mit Nextflow docs zu Configuration gehe, kannst du eine Liste dieser Orte und eine Priorität sehen, in der sie geladen werden. + +Okay. Lass uns überprüfen, dass unser Workflow wie erwartet ausgeführt wird. Öffne ein Terminal. Mache Nextflow run hello-config und drücke Enter. Wir sollten diese vier Prozesse laufen haben, die mit einem Cowpy-Befehl enden. Tatsächlich hat das richtig funktioniert. Ich hatte Docker aktiviert, es hat Docker heruntergeladen und Cowpy für mich ausgeführt, genau wie am Ende von Kapitel fünf. + +## 1. Bestimme, welche Software-Packaging-Technologie verwendet werden soll + +Okay. Sagen wir, ich arbeite auf einem HPC und ich habe Docker nicht installiert. Das Beste in diesem Szenario wäre, Singularity oder Apptainer zu verwenden. Wenn ich das tun würde, würde ich in das Modul cowpy gehen und diesen Container ändern, um das Singularity-Image zu verwenden, wie ich im vorherigen Kapitel gezeigt habe, mit einem oras://, das du auch von Seqera Containers bekommen kannst. + +Ich würde dann zu Nextflow.config gehen, Docker enabled auf false setzen und singularity enabled equals true machen. Oder, wenn Apptainer verwendet wird, apptainer enabled equals true und das würde funktionieren. + +Nextflow unterstützt auch andere Technologien neben Containern, etwas mit dem du vielleicht vertraut bist, ist conda. Hier können wir conda enabled equals true machen und Docker auf false setzen. conda verwendet nicht dieselbe container-Direktive. Stattdessen können wir hier eine neue hinzufügen, die conda heißt. Wir spezifizieren dann das conda-Paket, das wir verwenden möchten. Es ist gute Praxis, so spezifisch wie möglich zu sein, um zu versuchen, die Pipeline so reproduzierbar wie möglich zu machen. Also werde ich den conda-Channel spezifizieren, conda-forge, und dann cowpy, und die exakte Version, die 1.1.5 war. + +Ich könnte auch einfach cowpy schreiben, wenn ich wollte, aber das könnte bei verschiedenen Ausführungen der Pipeline zu einer anderen Version von cowpy führen. + +Das Schöne daran ist, dass ich die Docker-Direktive überhaupt nicht angefasst habe. Dieses Docker-Image ist immer noch da. Ich stelle jetzt nur zwei Alternativen bereit, und diese können ein- oder ausgeschaltet werden, indem man allein eine Konfigurationsdatei verwendet. + +## 1.3. Führe den Workflow aus, um zu überprüfen, dass er Conda verwenden kann + +Conda ist jetzt aktiviert, also lass es uns ausprobieren. + +Großartig. Es läuft und du kannst sehen, dass hier eine Nachricht von Nextflow ist, die besagt, dass Nextflow eine Conda-Umgebung für mich erstellt, und es verwendet diesen Cache-Speicherort. + +Im Hintergrund führt Nextflow "conda create"-Befehle für mich aus, um eine neue isolierte Conda-Umgebung mit nur den Paketen zu erstellen, die ich möchte, und installiert und holt dann diese Conda-Pakete, damit es den Prozess ausführen kann. + +Du kannst sehen, dass es dort ein bisschen Zeit genommen hat, weil es die Umgebung erstellt und die Software zum ersten Mal installiert hat. Allerdings ist diese Umgebung gecacht, also wenn ich denselben Nextflow-Befehl erneut ausführe, sollte es viel schneller sein, weil es dieselbe Conda-Umgebung wiederverwenden wird. + +Eines der coolen Dinge daran ist, dass diese Direktiven auf Prozessebene spezifiziert werden können, nicht nur für den gesamten Workflow. Also wenn du möchtest, kannst du mischen und kombinieren, welche Technologie für verschiedene Prozesse verwendet wird. + +## 2. Weise Rechenressourcen mit Prozessdirektiven zu + +Die Nextflow-Konfigurationsdatei kann viel mehr als nur Software-Packaging. Wir können Nextflow auch sagen, wie die Schritte in der Pipeline tatsächlich ausgeführt werden sollen. Ein Beispiel ist, einem Host-System mitzuteilen, welche Ressourcen für jede ausgeführte Aufgabe verfügbar gemacht werden sollten. + +Standardmäßig gibt Nextflow nicht sehr viel. Es gibt eine einzelne CPU und nur zwei Gigabyte Speicher für jeden Prozess. + +Das ist wahrscheinlich etwas, das wir ändern möchten, damit Prozesse, die lange laufen, mehr Ressourcen haben können und schneller laufen, aber es kann schwierig sein zu wissen, was man einem Prozess zuweisen soll. Nextflow hat einige nette Tricks auf Lager, um dir dabei zu helfen. + +## 2.1. Führe den Workflow aus, um einen Ressourcennutzungsbericht zu generieren + +Lass uns den Workflow erneut ausführen. Dieses Mal werde ich ein zusätzliches Argument hinzufügen, nämlich -with-report. Es ist eine Nextflow-Kernoption, also ist es ein einzelner Bindestrich. Und dann ein beliebiger Dateiname. In diesem Fall werde ich es report-config-one.html nennen. + +Ich werde den Workflow erneut ausführen. Er wird genau wie zuvor laufen, aber er wird mir einen zusätzlichen Hilfsbericht geben, der, wie du sehen kannst, jetzt hier in der Seitenleiste aufgetaucht ist. + +Ich werde auf diese Datei rechtsklicken, auf Download klicken, was sie von GitHub Codespaces auf mein lokales System herunterlädt, damit ich sie dann leicht im Webbrowser hier oben ansehen kann. + +Dieser Bericht kann für jeden Nextflow-Durchlauf generiert werden und enthält viele Informationen. Er beginnt oben mit einigen Metadaten darüber, welcher Befehl verwendet wurde, wann der Workflow lief, wie lange es dauerte, aber wenn du nach unten scrollst, bekommen wir detailliertere Informationen über die Ressourcen, die von jedem Schritt in der Pipeline verwendet wurden. + +Da jeder Prozess mehrmals für verschiedene Aufgaben läuft, haben wir ein Boxplot, das die Variation der Ressourcen zeigt, die wir für jeden Prozess verwendet haben. + +Wenn ich ein bisschen weiter nach unten scrolle, sehe ich ähnliche Informationen über verwendeten Speicher und Aufgabendauer. Auch Lese-/Schreibvorgänge auf der Festplatte. + +Du kannst dir vorstellen, dass dies bei einer großen Pipeline mit lang laufenden Aufgaben sehr informativ sein kann, wie man die Konfiguration der Ressourcen, die du anforderst, fein abstimmt, damit du nicht zu viel anforderst, aber auch genug bereitstellst, damit es schnell läuft. + +Wenn ich den Bericht weiter nach unten scrolle, sehen wir auch eine Aufgabentabelle, die uns detaillierte Informationen über jede einzelne Aufgabe zeigt, die im Workflow ausgeführt wurde. Dies beinhaltet Informationen wie das aufgelöste Skript, das ausgeführt wurde. + +Okay, lass uns zurück zu unserer Konfigurationsdatei gehen. Wir haben gesehen, dass wir für unseren Workflow wirklich nicht viel benötigt haben, also lass uns Nextflow mitteilen, dass wir nur ein Gigabyte Speicher für jeden Prozess im Workflow benötigen. + +Wenn wir es jetzt so auf Prozessebene definieren, wird dies auf jeden einzelnen Prozess in der Pipeline angewendet. + +## 2.3. Setze Ressourcenzuweisungen für einen einzelnen Prozess + +Lass uns der Argumentation halber so tun, als würde cowpy wirklich viel schwere Arbeit leisten und mehr Ressourcen als die anderen Aufgaben benötigen. Wir können hier einen zusätzlichen Konfigurationsblock definieren, der nur auf diesen Prozess angewendet wird, indem wir withName cowpy verwenden. + +Das nennt man einen Konfigurationsselektor, und wir können hier verschiedene Muster definieren, um verschiedene Prozesse zu matchen. Zum Beispiel könnte ich cow\* machen. Ich folge dem dann mit einigen geschweiften Klammern und lass uns ihm zwei Gigabyte Speicher statt einem geben und sagen wir zwei CPUs. + +Jetzt wird Nextflow jedem Prozess im Workflow ein Gigabyte geben, außer dieser Anforderung, die spezifischer ist. Also überschreibt sie es. Und nur für alle Prozesse, die cowpy heißen, werden zwei Gigs Speicher und zwei CPUs bekommen. + +Beachte, dass Nextflow clever in Bezug auf Ressourcennutzung ist. Also wenn du anfängst, diese Zahlen auf höhere Werte zu setzen, wirst du sehen, dass Nextflow beginnt, Job-Einreichungen nacheinander in die Warteschlange zu stellen, anstatt sie alle parallel auszuführen, damit es nicht mehr als die verfügbaren Ressourcen anfordert. + +## 2.4. Führe den Workflow mit der geänderten Konfiguration aus + +Lass uns versuchen, den Workflow erneut auszuführen und lass uns dieses Mal einen neuen Bericht speichern. + +Okay, wir können diese Datei herunterladen und einen Blick darauf werfen. + +Ja, unüberraschend sieht es im Grunde genau gleich aus, weil dies ein Dummy-Workflow ist, der nichts Echtes macht. Aber du kannst dir vorstellen, wie dieser iterative Ansatz, Limits zu definieren und echte Workflows mit dieser Art von Berichterstattung durchzuführen, es dir ermöglicht, einen evidenzbasierten Ansatz zum Setzen angemessener Konfiguration zu verfolgen und wirklich das Beste aus den dir zur Verfügung stehenden Rechenressourcen zu machen. + +Du kannst anfangen, wirklich clever zu sein. Nextflow hat eine eingebaute Fähigkeit, Fehler erneut zu versuchen, und du kannst das in deiner Konfigurationsdatei nutzen, indem du eine Closure wie diese verwendest und dynamisch die Ressourcen setzt, die verfügbar gemacht werden. Also habe ich hier Nextflow gesagt, diese zwei Gigabyte mit dem retry-Versuch zu multiplizieren. Also wird der zweite Versuch vier Gigs bekommen, der dritte Versuch sechs Gigs und so weiter. Das geht ein bisschen über den Rahmen dieses Trainingskurses hinaus, aber wenn du interessiert bist, schau dir die Nextflow-Dokumentation an, die einen schönen Abschnitt über dynamische Retry-Logik hat. + +## 2.5. Füge Ressourcenlimits hinzu + +Nun, eine Sache, die dir daran auffallen könnte, ist, dass diese Art von Sache es ziemlich einfach machen kann, versehentlich über die auf deinem System verfügbaren Ressourcen hinauszugehen. Wenn du mehr Ressourcen anforderst, als verfügbar sind, wird Nextflow einen Fehler über deine Konfiguration werfen und den Durchlauf anhalten. Um das zu vermeiden, kannst du etwas verwenden, das Ressourcenlimits genannt wird. + +Unter dem process-Scope in unserem Workflow können wir Ressourcenlimits wie dieses definieren, das ein Array nimmt, und wir können den maximalen Speicher, CPUs und Zeit spezifizieren, die auf diesem System verfügbar sind. + +Das Setzen hoher Werte hier erhöht nicht die Menge an Ressourcen, die angefordert werden. Wir werden immer noch ein Gigabyte in unseren Anforderungen verwenden, aber es bedeutet, dass wenn eine dieser Anforderungen 750 erreicht, sie diese Obergrenze erreichen wird und nicht mehr als das angefordert wird, was bedeutet, dass Nextflow weiter laufen wird und nicht wegen nicht verfügbarer Ressourcen abstürzen wird. + +Also ist das eine nette Schutzmaßnahme, die man verwenden kann, besonders wenn du dynamische Logik mit deiner Ressourcenzuweisung verwendest. + +Die andere Situation, wo dies wirklich nützlich ist, ist, wenn du Pipelines verwendest, die öffentlich sind und nicht von dir kontrolliert werden. Sie könnten mit Konfigurationsstandards kommen, und Nextflow wird automatisch den richtigen Ansatz verfolgen, alle Ressourcenanforderungen zu begrenzen, um auf deinem System zu laufen. + +Okay, großartig. Wir haben über Software gesprochen. Wir haben über Ressourcenzuweisung gesprochen und wir haben verschiedene Scopes von Konfiguration beschrieben, sowohl für alle Prozesse als auch für spezifische Prozesse. + +## 3. Verwende eine Parameterdatei, um Workflow-Parameter zu speichern + +Okay, als Nächstes werden wir unsere Aufmerksamkeit auf Parameter richten. Wir können Parameter in der Konfigurationsdatei definieren, genau wie wir es zuvor im Nextflow-Skript getan haben. Also params.greeting equals hello oder verwende params-Scope und setze foo equals bar. + +Und das ist großartig, um Standardwerte für deinen Workflow zu setzen. Wenn du jedoch Pipelines ausführst, kann es schön sein, Parameter in einer JSON- oder einer YAML-Datei zu spezifizieren. + +Die Verwendung einer Datei wie dieser ist viel besser als das Spezifizieren von Kommandozeilenoptionen mit --. Denn wenn du einen Workflow ausführst, musst du möglicherweise viele Parameter spezifizieren und es kann mühsam sein, sie alle in einer einzigen CLI zu schreiben und fehleranfällig. Außerdem ist es unwahrscheinlich, dass du dich an alle Parameter erinnern wirst, die du verwendet hast, also wenn du das in eine Datei kodierst, ist es einfacher, den Workflow in Zukunft erneut mit denselben Parametern zu starten. + +Wir haben hier eine Beispieldatei namens test-params, und du kannst sehen, dass diese die drei Parameter spezifiziert, die wir in unserem Workflow haben, mit drei verschiedenen Werten. Persönlich finde ich YAML einfacher zu schreiben als JSON. Also nur um zu demonstrieren, dass es funktioniert, werde ich eine neue Datei namens test.yaml erstellen und diese hineinkopieren, die Anführungszeichen loswerden und speichern. + +Diese JSON- und YAML-Dateien können einfacher zu schreiben sein, da sie eine vertrautere Syntax haben. Aber beachte, dass diese nur für Parameter sind und sie nur Schlüssel-Wert-Syntax wie diese akzeptieren. + +## 3.1. Führe den Workflow mit einer Parameterdatei aus + +Lass es uns ausprobieren. Mache denselben Befehl wie zuvor. Entferne den Bericht und ich werde -params-file test-params.yaml machen. + +Nein, das ist eine Nextflow-Kernoption, also ist es ein einzelner Bindestrich. + +Okay. Es hat den Workflow ausgeführt und es hat die Parameter in dieser YAML-Datei verwendet, anstatt dass ich sie alle in der Kommandozeile spezifiziere. Mag wie Overkill nur für dieses einfache Beispiel erscheinen, aber du kannst dir vorstellen, wenn du 10 oder 20 verschiedene Parameter hast, kann es mühsam sein, sie manuell einzutippen, und das ist einfach viel einfacher in einem Code-Editor zu bearbeiten und zum Zweck der Reproduzierbarkeit festzuhalten. + +## 3. Bestimme, welche Executors verwendet werden sollen, um die Arbeit zu erledigen + +Okay. Wir haben über Software-Packaging mit Docker und conda gesprochen. Wir haben über Prozessressourcenanforderungen mit CPUs und Speicher gesprochen. Und wir haben ein bisschen darüber gesprochen, wie man Parameter beim Ausführen von Workflows spezifiziert. + +Die letzten Teile der Konfiguration sind wirklich die Ausführung, die zugrunde liegende Computing-Infrastruktur selbst, und das ist das wahre Juwel in der Krone von Nextflow: dass wir denselben Workflow über mehrere verschiedene Computing-Infrastrukturen hinweg ausführen können. + +Ich werde tatsächlich für eine Sekunde zum geschriebenen Trainingsmaterial wechseln. Unter diesem Teil des Trainings können wir einige verschiedene Beispiele sehen, wie verschiedene Executors, in diesem Fall HPC-Scheduler, die Ressourcenanforderungen definieren, die benötigt werden, um einen Job einzureichen. + +Also für Slurm hast du diese SBATCH-Header, die --mem und die CPU-Nummer definieren. Wenn du PBS verwendest, hast du andere Header, und wenn du Grid Engine verwendest, hast du wieder andere Header. + +Du kannst dir vorstellen, dass es noch unterschiedlicher ist, wenn du in der Cloud ausführen möchtest, sei es AWS Batch, Google Cloud, Azure oder mehr. + +Jede dieser zugrunde liegenden Computing-Infrastrukturen wird Executor genannt und Nextflow weiß, wie man mit all diesen verschiedenen Executors kommuniziert, um Jobs mit der korrekten Syntax einzureichen. + +Die gute Nachricht ist, dass du darüber nicht Bescheid wissen musst. Alles, was du tun musst, ist Nextflow zu sagen, welchen Executor es verwenden soll. + +## 3.1. Auf ein anderes Backend abzielen + +Wir gehen zurück zu unserer Konfigurationsdatei und dem Prozess machen wir executor, und ich werde local tippen. + +Local ist tatsächlich der Standard, wenn du keinen anderen Executor spezifizierst, wird local verwendet, und das bedeutet einfach dein Host-System, wo auch immer du Nextflow gestartet hast. + +Ich könnte stattdessen Slurm spezifizieren. Und das würde Slurm-Jobs einreichen, oder ich könnte AWS Batch sagen, und das würde Jobs an AWS Batch einreichen. + +Du benötigst in einigen Fällen zusätzliche Konfiguration, zum Beispiel benötigt das Ausführen in der Cloud bestimmte Anmeldeinformationen, aber wirklich ist das der Kern davon, und es kann so einfach sein wie eine oder zwei Zeilen Konfiguration, um deinen Workflow in einer völlig anderen Computing-Umgebung auszuführen. + +Obwohl wir auf einem einfachen System innerhalb von Codespaces laufen, kann ich trotzdem ein bisschen damit herumspielen und so tun, als würden wir auf Slurm laufen. Wenn ich dann den Workflow erneut starte, Nextflow run hello-config. Es wird fehlschlagen, weil es nicht in der Lage sein wird, Jobs an Slurm einzureichen. Aber wir können immer noch in die Arbeitsverzeichnisse gehen und sehen, was Nextflow getan hat. Also wenn wir zu diesem Arbeitsverzeichnis gehen und uns .command.run ansehen. Du kannst oben in dieser Datei sehen, dass wir jetzt diese sbatch-Header-Zeilen haben, die versucht haben, die für den Slurm-Job benötigten Ressourcen zu spezifizieren. + +## 4. Verwende Profile, um voreingestellte Konfigurationen auszuwählen + +Okay, wir sind fast da. Der letzte Teil dieses Kapitels ist das Sprechen über Konfigurationsprofile. Wenn du deine Pipeline auf mehreren verschiedenen Systemen ausführst, könnte es ärgerlich sein, all diese verschiedenen Nextflow-Konfigurationsdateien zu haben, die du jedes Mal spezifizieren musst. + +Stattdessen kannst du Gruppierungen von Konfiguration innerhalb deiner Nextflow-Konfigurationsdatei kodieren und diese Gruppen ein- und ausschalten, indem du ein Profil-Flag verwendest. Lass uns sehen, wie das aussieht. + +## 4.1. Erstelle Profile zum Wechseln zwischen lokaler Entwicklung und Ausführung auf HPC + +Wir werden in unserem Beispiel hier zwei Profile erstellen, eines für meinen Laptop und eines für ein schwereres HPC-System. Ich werde ein bisschen schummeln und einfach den Code aus dem Trainingsmaterial kopieren und hier einfügen. + +Wir haben einen neuen Scope namens profiles, und dann haben wir einen Namen für jedes Profil, der beliebig sein kann. Und darin haben wir Konfiguration, die genau gleich aussieht wie die Top-Level-Konfiguration, die wir bereits geschrieben haben. Also haben wir wieder process-Scope, Docker-Scope. + +Beim Profil namens my_laptop sage ich, dass es mit dem local-Executor ausgeführt werden soll, also auf meinem Host-System, und Docker verwendet werden soll. + +Beim university_hpc-Profil hier sage ich, Slurm zu verwenden, um Jobs einzureichen, conda statt Docker zu verwenden, und ich spezifiziere verschiedene Ressourcenlimits, die zur Systemgröße von Nodes auf dem von mir verwendeten HPC passen könnten. + +Standardmäßig wird keine dieser Konfigurationen verwendet, wenn ich Nextflow ausführe, ich muss spezifizieren, dass ich eines dieser Profile verwenden möchte. + +## 4.2. Führe den Workflow mit einem Profil aus + +Lass uns nextflow run hello-config machen. Und ich werde -profile machen, einzelner Bindestrich, weil es eine Nextflow-Kernoption ist. Und dann der Name, den ich ihm gegeben habe, nämlich my_laptop. Nextflow sollte jetzt den Konfigurationsblock verwenden, der innerhalb dieses Konfigurationsprofils spezifiziert wurde, und ihn anwenden, wenn es Nextflow ausführt. Wenn ich den anderen Konfigurationsblock verwenden wollte, müsste ich nur diesen Profilnamen wechseln. Viel einfacher zu merken. Viel einfacher zu verwenden. + +## 4.3. Erstelle ein Test-Profil + +Beachte, dass die Profile jede Art von Konfiguration haben können, also muss es nicht mit deiner Ausführungsumgebung zusammenhängen. Zum Beispiel, lass uns hier ein neues Profil erstellen, das einen Satz von Parametern hat. Wir können das zu tux ändern und zu my profile ändern, und jetzt, wenn wir profile test machen, wird es diese Parameter spezifizieren, die die Parameter überschreiben werden, die auf der obersten Ebene des Workflows spezifiziert sind. + +Wenn du Nextflow ausführst, kannst du mehrere Profile verketten und sie werden nacheinander angewendet. + +## 4.4. Führe den Workflow lokal mit dem Test-Profil aus + +Also kann ich den vorherigen Befehl nehmen und Komma test machen. Das wird zuerst die my_laptop-Konfiguration anwenden und dann die test-Konfiguration anwenden. Wenn es eine Überschneidung gibt, wird das Profil auf der rechten Seite jede Konfiguration in vorherigen Profilen überschreiben. Wenn ich Enter drücke, lass uns sehen, was passiert. + +Okay, wir haben hier eine neue Ergebnisdatei. Du kannst das My Profile sehen, das ich als eine der Optionen spezifiziert habe. Und wir können auch cowpy, my profile sehen, und tatsächlich, da ist tux. Also hat das funktioniert. + +## Zusammenfassung + +Okay! Fantastisch. Das war's. Du hast es bis zum Ende des Kurses geschafft. Du bekommst ein bisschen Feier-Konfetti. Gut gemacht für das Beenden dieses Kapitels. + +[Nächstes Video-Transkript :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/de/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/de/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..f5e40ae5de --- /dev/null +++ b/docs/de/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Nächste Schritte - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Wichtige Hinweise" + + Diese Seite zeigt nur das Transkript. Für vollständige Schritt-für-Schritt-Anleitungen kehre zum [Kursmaterial](../05_hello_containers.md) zurück. + +## Willkommen + +Herzlichen Glückwunsch, du hast es geschafft. Du hast den ersten Nextflow-Trainingskurs namens Hello Nextflow abgeschlossen. + +Gut gemacht. Vielen Dank, dass du durchgehalten hast, und wir schätzen die Zeit und Mühe, die du in das Erlernen von Nextflow investiert hast, sehr. Wir hoffen wirklich, dass es für deine Arbeit nützlich sein wird. + +## Nächste Schritte + +Für die nächsten Schritte halte Ausschau nach dem Trainingsportal: training.nextflow.io. Wir stellen dort ständig neues Kursmaterial bereit und aktualisieren es auch. Du kannst dort möglicherweise fortgeschrittenere Trainings oder Trainings finden, die spezifisch für ein Forschungsfeld sind, das dich interessiert. + +Schau dir insbesondere die Nextflow for Science-Seite an. Diese bietet eine Reihe kurzer Kurse, die eigenständig sind und das, was du in Hello Nextflow gelernt hast, auf spezifische Anwendungsfälle erweitern. + +Es gibt einen für Genomik und auch einen für RNA-seq. Wir hoffen, bald weitere anbieten zu können. + +## Side Quests + +Es gibt viele Dinge, über die wir in Hello Nextflow hätten sprechen können, die aber zu detailliert gewesen wären. Einige dieser Dinge stellen wir in Side Quests ein, die kurze Kurse zu spezifischen Themen sind. + +Es gibt auch die größeren Fundamentals Training- und Advanced Training-Kurse, die möglicherweise Inhalte enthalten, die dich interessieren. + +## nf-core + +Es wurde einmal oder zweimal in diesem Kurs erwähnt, aber schau dir definitiv das nf-core-Projekt an. Es gibt dort über hundert Pipelines für verschiedene Arten von Daten, also ist es durchaus möglich, dass du möglicherweise keine eigene Pipeline erstellen musst. + +Es gibt auch fast eineinhalbtausend Process-Module, bei denen du, wenn du die nf-core-Developer-Tooling verwendest, eine Pipeline erstellen und diese Module in Sekundenschnelle importieren kannst. + +## Seqera Platform + +Zuletzt noch ein kurzer Hinweis auf Seqera Platform. Dies ist ohne Zweifel der beste Weg, Nextflow in der Praxis auszuführen. Es ist eine cloudbasierte Plattform, aber du verbindest deine eigene Compute-Infrastruktur, sei es dein eigenes Cloud-Konto auf AWS, Google Batch oder Azure, oder sogar dein eigenes HPC. Der kostenlose Tarif steht jedem zur Verfügung, und wenn du im akademischen Bereich tätig bist, kannst du dich für unser Academic Program für kostenlosen Zugang auf Pro-Level bewerben. + +Seqera Platform geht über eine grafische Oberfläche zum Starten und Überwachen von Workflows hinaus. Es gibt auch zusätzliche Tools wie Data Studios zum Ausführen interaktiver Sessions und grundlegende Tools wie Fusion, das schnelleren und günstigeren Zugriff auf Daten über die Cloud ermöglicht. + +## Support und Veranstaltungen + +Denke daran, wenn du jemals auf Probleme stößt, geh einfach zu community.seqera.io. Unser Forum dort ist sehr aktiv, die Nextflow-Community ist super stark und es stehen fast immer Leute bereit, um zu helfen, sei es für Training oder alles, was mit deiner täglichen Nutzung von Nextflow zu tun hat. + +Und natürlich ist ein großartiger nächster Schritt, an einer unserer Community-Veranstaltungen teilzunehmen, sei es ein nf-core-Hackathon oder eines der Nextflow Summit-Events. Sie machen großen Spaß, und es wäre wirklich schön, dich dort zu treffen und darüber zu sprechen, wofür du Nextflow verwendest. + +## Danksagungen + +Ich möchte allen, die an der Erstellung dieses Trainingsmaterials beteiligt waren, ein riesiges Dankeschön aussprechen. Ich habe es präsentiert, aber wirklich die ganze harte Arbeit wurde vom Training-Team bei Seqera geleistet. Insbesondere Geraldine, die enorm viel Arbeit in die Neugestaltung dieses Materials gesteckt hat. + +Auch Marcel, Ken, Adam, John, andere aus dem Scientific Development Team und andere in der Community. + +## Feedback-Umfrage + +Jetzt, da du den Kurs abgeschlossen hast, würden wir gerne wissen, was du davon hältst. Auf training.nextflow.io findest du eine Feedback-Umfrage unter dem Hello Nextflow-Abschnitt. + +Es gibt nur vier Fragen, aber es ist wirklich wichtig für uns. Wenn nichts anderes, zeigt es uns ungefähr, wie viele Leute das Training machen. Es sagt uns auch, ob es dir gefallen hat, und wenn du Vorschläge hast, lass sie bitte am Ende da. Wir lesen jede einzelne Einreichung. + +Wenn du Fehler bemerkst, ist alles Open Source auf GitHub, sodass du ein Issue erstellen oder einen Pull Request machen oder uns eine Nachricht im Forum senden kannst. Wir würden gerne hören, was du davon gehalten hast und wie wir es verbessern könnten. Nochmals vielen Dank. Wir hoffen, dich bald zu sehen. diff --git a/docs/de/docs/hello_nf-core/00_orientation.md b/docs/de/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..4a0a3183d0 --- /dev/null +++ b/docs/de/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Erste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Eine Trainingsumgebung starten + +Um die vorgefertigte Umgebung zu nutzen, die wir auf GitHub Codespaces bereitstellen, klicke auf die Schaltfläche "Open in GitHub Codespaces" unten. Für andere Optionen siehe [Umgebungsoptionen](../envsetup/index.md). + +Wir empfehlen, die Trainingsumgebung in einem neuen Browser-Tab oder -Fenster zu öffnen (verwende Rechtsklick, Strg-Klick oder Cmd-Klick, je nach deinem System), damit du weiterlesen kannst, während die Umgebung lädt. +Du musst diese Anleitung parallel geöffnet halten, um den Kurs durchzuarbeiten. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Grundlagen der Umgebung + +Diese Trainingsumgebung enthält alle Software, Code und Daten, die zum Durcharbeiten des Trainingskurses notwendig sind, sodass du nichts selbst installieren musst. + +Der Codespace ist mit einer VSCode-Oberfläche eingerichtet, die einen Dateisystem-Explorer, einen Code-Editor und eine Terminal-Shell umfasst. +Alle Anweisungen, die während des Kurses gegeben werden (z.B. 'öffne die Datei', 'bearbeite den Code' oder 'führe diesen Befehl aus'), beziehen sich auf diese drei Teile der VSCode-Oberfläche, sofern nicht anders angegeben. + +Wenn du diesen Kurs selbstständig durcharbeitest, mache dich bitte mit den [Grundlagen der Umgebung](../envsetup/01_setup.md) vertraut, um weitere Details zu erfahren. + +### Versionsanforderungen + +Dieses Training ist für **Nextflow 25.10.2** oder neuer **mit DEAKTIVIERTEM v2-Syntax-Parser** konzipiert. + +#### Wenn du unsere Trainingsumgebung verwendest: + +Du MUSST den folgenden Befehl ausführen, bevor du fortfährst: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Wenn du eine lokale oder benutzerdefinierte Umgebung verwendest: + +Bitte stelle sicher, dass du die korrekten Einstellungen verwendest, wie [hier](../info/nxf_versions.md) dokumentiert. + +Das Training erfordert zusätzlich **nf-core tools 3.4.1**. +Wenn du eine andere Version der nf-core-Tools verwendest, könntest du Schwierigkeiten haben, dem Training zu folgen. + +Du kannst überprüfen, welche Version in deiner Umgebung installiert ist, indem du den Befehl `nf-core --version` verwendest. + +## Bereit zum Arbeiten + +Sobald dein Codespace läuft, musst du zwei Dinge tun, bevor du ins Training einsteigst: Setze dein Arbeitsverzeichnis für diesen spezifischen Kurs und wirf einen Blick auf die bereitgestellten Materialien. + +### Das Arbeitsverzeichnis setzen + +Standardmäßig öffnet der Codespace mit dem Arbeitsverzeichnis im Stammverzeichnis aller Trainingskurse, aber für diesen Kurs werden wir im Verzeichnis `hello-nf-core/` arbeiten. + +Wechsle jetzt das Verzeichnis, indem du diesen Befehl im Terminal ausführst: + +```bash +cd hello-nf-core/ +``` + +!!! tip "Tipp" + + Solltest du aus irgendeinem Grund aus diesem Verzeichnis herauswechseln (z.B. wenn dein Codespace in den Ruhemodus geht), kannst du immer den vollständigen Pfad verwenden, um dorthin zurückzukehren, vorausgesetzt du arbeitest in der GitHub Codespaces Trainingsumgebung: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Lass uns nun einen Blick auf den Inhalt dieses Verzeichnisses werfen. + +### Die bereitgestellten Materialien erkunden + +Du kannst den Inhalt dieses Verzeichnisses mit dem Datei-Explorer auf der linken Seite des Trainings-Arbeitsbereichs erkunden. +Alternativ kannst du den Befehl `tree` verwenden. + +Im Verlauf des Kurses verwenden wir die Ausgabe von `tree`, um die Verzeichnisstruktur und -inhalte in einer lesbaren Form darzustellen, manchmal mit kleinen Änderungen zur besseren Übersicht. + +Hier erzeugen wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 2 +``` + +??? abstract "Verzeichnisinhalte" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Klicke auf das farbige Feld, um den Abschnitt zu erweitern und seinen Inhalt anzuzeigen. +Wir verwenden aufklappbare Abschnitte wie diesen, um die erwartete Befehlsausgabe auf prägnante Weise einzubinden. + +- **Die Datei `greetings.csv`** ist eine CSV-Datei mit einigen minimalen Spaltendaten, die wir zu Testzwecken verwenden. + +- **Das Verzeichnis `original-hello`** enthält eine Kopie des Quellcodes, der durch das Durcharbeiten der vollständigen Hello Nextflow Trainingsreihe entsteht (mit aktiviertem Docker). + +- **Das Verzeichnis `solutions`** enthält die fertigen Workflow-Skripte, die aus jedem Schritt des Kurses resultieren. + Sie sind als Referenz gedacht, um deine Arbeit zu überprüfen und eventuell auftretende Probleme zu beheben. + +## Bereitschafts-Checkliste + +Denkst du, du bist bereit loszulegen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Meine Umgebung ist eingerichtet und läuft +- [ ] Ich habe sichergestellt, dass der Syntax-Parser auf **v1** gesetzt ist +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend gesetzt + +Wenn du alle Kästchen abhaken kannst, kann es losgehen. + +**Um mit Teil 1 fortzufahren, klicke auf den Pfeil unten rechts auf dieser Seite.** diff --git a/docs/de/docs/hello_nf-core/01_run_demo.md b/docs/de/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..a495b5207a --- /dev/null +++ b/docs/de/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# Teil 1: Eine Demo-Pipeline ausführen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil des Hello nf-core Trainingskurses zeigen wir dir, wie du eine nf-core Pipeline finden und ausprobieren kannst, wie der Code organisiert ist und wie er sich von einfachem Nextflow-Code unterscheidet, wie er in [Hello Nextflow](../hello_nextflow/index.md) gezeigt wird. + +Wir werden eine Pipeline namens nf-core/demo verwenden, die vom nf-core-Projekt als Teil seines Pipeline-Inventars zur Demonstration der Code-Struktur und Tool-Operationen gepflegt wird. + +Stelle sicher, dass dein Arbeitsverzeichnis auf `hello-nf-core/` gesetzt ist, wie auf der Seite [Erste Schritte](./00_orientation.md) beschrieben. + +--- + +## 1. Die nf-core/demo Pipeline finden und abrufen + +Beginnen wir damit, die nf-core/demo Pipeline auf der Projektwebsite unter [nf-co.re](https://nf-co.re) zu finden, die alle Informationen zentralisiert, wie: allgemeine Dokumentation und Hilfe-Artikel, Dokumentation für jede der Pipelines, Blogbeiträge, Event-Ankündigungen und so weiter. + +### 1.1. Die Pipeline auf der Website finden + +Gehe in deinem Webbrowser zu [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) und tippe `demo` in die Suchleiste. + +![search results](./img/search-results.png) + +Klicke auf den Pipeline-Namen, `demo`, um auf die Pipeline-Dokumentationsseite zuzugreifen. + +Jede veröffentlichte Pipeline hat eine eigene Seite, die die folgenden Dokumentationsabschnitte enthält: + +- **Introduction:** Eine Einführung und Übersicht über die Pipeline +- **Usage:** Beschreibungen, wie die Pipeline ausgeführt wird +- **Parameters:** Gruppierte Pipeline-Parameter mit Beschreibungen +- **Output:** Beschreibungen und Beispiele der erwarteten Ausgabedateien +- **Results:** Beispiel-Ausgabedateien, die aus dem vollständigen Testdatensatz generiert wurden +- **Releases & Statistics:** Pipeline-Versionsverlauf und Statistiken + +Wann immer du erwägst, eine neue Pipeline zu übernehmen, solltest du die Pipeline-Dokumentation zuerst sorgfältig lesen, um zu verstehen, was sie tut und wie sie konfiguriert werden sollte, bevor du versuchst, sie auszuführen. + +Schau dir das jetzt an und sieh, ob du herausfinden kannst: + +- Welche Tools die Pipeline ausführen wird (Prüfe den Tab: `Introduction`) +- Welche Eingaben und Parameter die Pipeline akzeptiert oder benötigt (Prüfe den Tab: `Parameters`) +- Was sind die Ausgaben, die von der Pipeline produziert werden (Prüfe den Tab: `Output`) + +#### 1.1.1. Pipeline-Übersicht + +Der Tab `Introduction` bietet eine Übersicht über die Pipeline, einschließlich einer visuellen Darstellung (genannt U-Bahn-Karte) und einer Liste von Tools, die als Teil der Pipeline ausgeführt werden. + +![pipeline subway map](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Beispiel-Befehlszeile + +Die Dokumentation bietet auch eine Beispiel-Eingabedatei (weiter unten ausführlicher besprochen) und eine Beispiel-Befehlszeile. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Du wirst bemerken, dass der Beispielbefehl KEINE Workflow-Datei angibt, sondern nur die Referenz zum Pipeline-Repository, `nf-core/demo`. + +Wenn es auf diese Weise aufgerufen wird, wird Nextflow annehmen, dass der Code auf eine bestimmte Weise organisiert ist. +Lass uns den Code abrufen, damit wir diese Struktur untersuchen können. + +### 1.2. Den Pipeline-Code abrufen + +Nachdem wir festgestellt haben, dass die Pipeline für unsere Zwecke geeignet zu sein scheint, lass sie uns ausprobieren. +Glücklicherweise macht es Nextflow einfach, Pipelines aus korrekt formatierten Repositories abzurufen, ohne irgendetwas manuell herunterladen zu müssen. + +Kehren wir zum Terminal zurück und führen Folgendes aus: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Befehlsausgabe" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow führt einen `pull` des Pipeline-Codes durch, was bedeutet, dass es das vollständige Repository auf deine lokale Festplatte herunterlädt. + +Um es klarzustellen: Du kannst dies mit jeder Nextflow-Pipeline tun, die entsprechend auf GitHub eingerichtet ist, nicht nur mit nf-core Pipelines. +Allerdings ist nf-core die größte Open-Source-Sammlung von Nextflow-Pipelines. + +Du kannst Nextflow veranlassen, dir eine Liste der Pipelines zu geben, die du auf diese Weise abgerufen hast: + +```bash +nextflow list +``` + +??? success "Befehlsausgabe" + + ```console + nf-core/demo + ``` + +Du wirst bemerken, dass die Dateien nicht in deinem aktuellen Arbeitsverzeichnis sind. +Standardmäßig speichert Nextflow sie unter `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Verzeichnisinhalt" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note "Hinweis" + + Der vollständige Pfad kann auf deinem System abweichen, wenn du nicht unsere Trainingsumgebung verwendest. + +Nextflow hält den heruntergeladenen Quellcode absichtlich 'aus dem Weg' nach dem Prinzip, dass diese Pipelines eher wie Bibliotheken verwendet werden sollten als Code, mit dem du direkt interagieren würdest. + +Für die Zwecke dieses Trainings möchten wir jedoch herumstöbern können und sehen, was drin ist. +Um das zu erleichtern, erstellen wir einen symbolischen Link zu diesem Ort von unserem aktuellen Arbeitsverzeichnis aus. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Dies erstellt eine Verknüpfung, die es einfacher macht, den gerade heruntergeladenen Code zu durchsuchen. + +```bash +tree -L 2 pipelines +``` + +```console title="Verzeichnisinhalt" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Jetzt können wir bei Bedarf leichter in den Quellcode schauen. + +Aber zuerst, lass uns unsere erste nf-core Pipeline ausführen! + +### Zusammenfassung + +Du weißt jetzt, wie du eine Pipeline über die nf-core-Website finden und eine lokale Kopie des Quellcodes abrufen kannst. + +### Wie geht es weiter? + +Lerne, wie du eine nf-core Pipeline mit minimalem Aufwand ausprobieren kannst. + +--- + +## 2. Die Pipeline mit ihrem Testprofil ausprobieren + +Praktischerweise kommt jede nf-core Pipeline mit einem Testprofil. +Dies ist ein minimaler Satz von Konfigurationseinstellungen für die Pipeline, um mit einem kleinen Testdatensatz ausgeführt zu werden, der im [nf-core/test-datasets](https://github.com/nf-core/test-datasets) Repository gehostet wird. +Es ist eine großartige Möglichkeit, eine Pipeline schnell in kleinem Maßstab auszuprobieren. + +!!! note "Hinweis" + + Das Konfigurationsprofil-System von Nextflow ermöglicht es dir, einfach zwischen verschiedenen Container-Engines oder Ausführungsumgebungen zu wechseln. + Für weitere Details siehe [Hello Nextflow Teil 6: Konfiguration](../hello_nextflow/06_hello_config.md). + +### 2.1. Das Testprofil untersuchen + +Es ist gute Praxis, zu prüfen, was das Testprofil einer Pipeline spezifiziert, bevor man sie ausführt. +Das `test`-Profil für `nf-core/demo` befindet sich in der Konfigurationsdatei `conf/test.config` und ist unten gezeigt. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Eingabedaten + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Du wirst sofort bemerken, dass der Kommentarblock oben ein Verwendungsbeispiel enthält, das zeigt, wie die Pipeline mit diesem Testprofil ausgeführt wird. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Die einzigen Dinge, die wir angeben müssen, sind das, was zwischen spitzen Klammern im Beispielbefehl gezeigt wird: `<docker/singularity>` und `<OUTDIR>`. + +Zur Erinnerung: `<docker/singularity>` bezieht sich auf die Wahl des Container-Systems. Alle nf-core Pipelines sind darauf ausgelegt, mit Containern (Docker, Singularity, etc.) verwendbar zu sein, um Reproduzierbarkeit zu gewährleisten und Software-Installationsprobleme zu eliminieren. +Also müssen wir angeben, ob wir Docker oder Singularity verwenden möchten, um die Pipeline zu testen. + +Der Teil `--outdir <OUTDIR>` bezieht sich auf das Verzeichnis, in das Nextflow die Ausgaben der Pipeline schreiben wird. +Wir müssen einen Namen dafür angeben, den wir einfach erfinden können. +Wenn es noch nicht existiert, wird Nextflow es zur Laufzeit für uns erstellen. + +Weiter zum Abschnitt nach dem Kommentarblock zeigt uns das Testprofil, was für das Testen vorkonfiguriert wurde: am wichtigsten ist, dass der Parameter `input` bereits so eingestellt ist, dass er auf einen Testdatensatz zeigt, sodass wir keine eigenen Daten bereitstellen müssen. +Wenn du dem Link zur vorkonfigurierten Eingabe folgst, wirst du sehen, dass es sich um eine CSV-Datei handelt, die Probenidentifikatoren und Dateipfade für mehrere experimentelle Proben enthält. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Dies wird als Samplesheet bezeichnet und ist die häufigste Form der Eingabe für nf-core Pipelines. + +!!! note "Hinweis" + + Mach dir keine Sorgen, wenn du mit den Datenformaten und -typen nicht vertraut bist, es ist nicht wichtig für das Folgende. + +Dies bestätigt also, dass wir alles haben, was wir brauchen, um die Pipeline auszuprobieren. + +### 2.2. Die Pipeline ausführen + +Entscheiden wir uns, Docker für das Container-System zu verwenden und `demo-results` als Ausgabeverzeichnis, und wir sind bereit, den Testbefehl auszuführen: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Wenn deine Ausgabe damit übereinstimmt, Glückwunsch! Du hast gerade deine erste nf-core Pipeline ausgeführt. + +Du wirst bemerken, dass es viel mehr Konsolenausgabe gibt als wenn du eine einfache Nextflow-Pipeline ausführst. +Es gibt einen Header, der eine Zusammenfassung der Pipeline-Version, Eingaben und Ausgaben sowie einige Konfigurationselemente enthält. + +!!! note "Hinweis" + + Deine Ausgabe wird unterschiedliche Zeitstempel, Ausführungsnamen und Dateipfade zeigen, aber die Gesamtstruktur und Prozessausführung sollte ähnlich sein. + +Weiter zur Ausführungsausgabe, schauen wir uns die Zeilen an, die uns sagen, welche Prozesse ausgeführt wurden: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Dies sagt uns, dass drei Prozesse ausgeführt wurden, die den drei Tools entsprechen, die auf der Pipeline-Dokumentationsseite auf der nf-core-Website gezeigt werden: FASTQC, SEQTK_TRIM und MULTIQC. + +Die vollständigen Prozessnamen wie hier gezeigt, wie `NFCORE_DEMO:DEMO:MULTIQC`, sind länger als das, was du im einführenden Hello Nextflow Material gesehen haben könntest. +Diese enthalten die Namen ihrer übergeordneten Workflows und spiegeln die Modularität des Pipeline-Codes wider. +Wir werden in Kürze näher darauf eingehen. + +### 2.3. Die Ausgaben der Pipeline untersuchen + +Schauen wir uns schließlich das `demo-results`-Verzeichnis an, das von der Pipeline produziert wurde. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Verzeichnisinhalt" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Das mag wie viel erscheinen. +Um mehr über die Ausgaben der `nf-core/demo` Pipeline zu erfahren, schau dir ihre [Dokumentationsseite](https://nf-co.re/demo/1.0.2/docs/output/) an. + +In diesem Stadium ist wichtig zu beobachten, dass die Ergebnisse nach Modul organisiert sind, und es gibt zusätzlich ein Verzeichnis namens `pipeline_info`, das verschiedene mit Zeitstempeln versehene Berichte über die Pipeline-Ausführung enthält. + +Zum Beispiel zeigt dir die Datei `execution_timeline_*`, welche Prozesse ausgeführt wurden, in welcher Reihenfolge und wie lange sie zur Ausführung benötigten: + +![execution timeline report](./img/execution_timeline.png) + +!!! note "Hinweis" + + Hier wurden die Aufgaben nicht parallel ausgeführt, weil wir auf einer minimalistischen Maschine in Github Codespaces laufen. + Um diese parallel laufen zu sehen, versuche die CPU-Zuweisung deines Codespace und die Ressourcenlimits in der Testkonfiguration zu erhöhen. + +Diese Berichte werden automatisch für alle nf-core Pipelines generiert. + +### Zusammenfassung + +Du weißt, wie man eine nf-core Pipeline mit ihrem integrierten Testprofil ausführt und wo man ihre Ausgaben findet. + +### Wie geht es weiter? + +Lerne, wie der Pipeline-Code organisiert ist. + +--- + +## 3. Die Pipeline-Code-Struktur untersuchen + +Nachdem wir die Pipeline erfolgreich als Benutzer ausgeführt haben, lass uns die Perspektive wechseln und schauen, wie nf-core Pipelines intern strukturiert sind. + +Das nf-core-Projekt setzt strenge Richtlinien durch, wie Pipelines strukturiert sind und wie der Code organisiert, konfiguriert und dokumentiert wird. +Zu verstehen, wie dies alles organisiert ist, ist der erste Schritt zur Entwicklung deiner eigenen nf-core-kompatiblen Pipelines, was wir in Teil 2 dieses Kurses angehen werden. + +Schauen wir uns an, wie der Pipeline-Code im `nf-core/demo` Repository organisiert ist, unter Verwendung des `pipelines` Symlinks, den wir früher erstellt haben. + +Du kannst entweder `tree` verwenden oder den Datei-Explorer benutzen, um das `nf-core/demo`-Verzeichnis zu finden und zu öffnen. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Verzeichnisinhalt" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Da ist eine Menge los, also gehen wir das Schritt für Schritt an. + +Zunächst lass uns bemerken, dass du auf der obersten Ebene eine README-Datei mit zusammenfassenden Informationen sowie Hilfsdateien finden kannst, die Projektinformationen wie Lizenzierung, Beitragsrichtlinien, Zitate und Verhaltenskodex zusammenfassen. +Detaillierte Pipeline-Dokumentation befindet sich im `docs`-Verzeichnis. +All dieser Inhalt wird verwendet, um die Webseiten auf der nf-core-Website programmatisch zu generieren, sodass sie immer mit dem Code auf dem neuesten Stand sind. + +Nun, für den Rest werden wir unsere Erkundung in drei Phasen aufteilen: + +1. Pipeline-Code-Komponenten (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Pipeline-Konfiguration +3. Eingaben und Validierung + +Beginnen wir mit den Pipeline-Code-Komponenten. +Wir werden uns auf die Dateihierarchie und strukturelle Organisation konzentrieren, anstatt in den Code innerhalb einzelner Dateien einzutauchen. + +### 3.1. Pipeline-Code-Komponenten + +Die Standard-nf-core Pipeline-Code-Organisation folgt einer modularen Struktur, die darauf ausgelegt ist, die Code-Wiederverwendung zu maximieren, wie in [Hello Modules](../hello_nextflow/04_hello_modules.md), Teil 4 des [Hello Nextflow](../hello_nextflow/index.md) Kurses eingeführt, obwohl dies in echter nf-core-Manier mit etwas zusätzlicher Komplexität implementiert wird. +Insbesondere machen nf-core Pipelines reichlich Gebrauch von Subworkflows, d.h. Workflow-Skripten, die von einem übergeordneten Workflow importiert werden. + +Das mag etwas abstrakt klingen, also schauen wir uns an, wie dies in der Praxis in der `nf-core/demo` Pipeline verwendet wird. + +!!! note "Hinweis" + + Wir werden nicht den tatsächlichen Code durchgehen, _wie_ diese modularen Komponenten verbunden sind, weil es eine zusätzliche Komplexität gibt, die mit der Verwendung von Subworkflows verbunden ist, die verwirrend sein kann, und das Verständnis davon ist in dieser Phase des Trainings nicht notwendig. + Vorerst werden wir uns auf die Gesamtorganisation und Logik konzentrieren. + +#### 3.1.1. Allgemeiner Überblick + +So sehen die Beziehungen zwischen den relevanten Code-Komponenten für die `nf-core/demo` Pipeline aus: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +Es gibt ein sogenanntes _Entrypoint_-Skript namens `main.nf`, das als Wrapper für zwei Arten von verschachtelten Workflows fungiert: der Workflow, der die eigentliche Analyselogik enthält, befindet sich unter `workflows/` und heißt `demo.nf`, und eine Reihe von Haushalts-Workflows unter `subworkflows/`. +Der `demo.nf` Workflow greift auf **Module** zu, die sich unter `modules/` befinden; diese enthalten die **Prozesse**, die die eigentlichen Analyseschritte durchführen werden. + +!!! note "Hinweis" + + Subworkflows sind nicht auf Haushaltsfunktionen beschränkt, und sie können Prozessmodule verwenden. + + Die hier gezeigte `nf-core/demo` Pipeline befindet sich zufällig auf der einfacheren Seite des Spektrums, aber andere nf-core Pipelines (wie `nf-core/rnaseq`) verwenden Subworkflows, die an der eigentlichen Analyse beteiligt sind. + +Lass uns nun diese Komponenten nacheinander durchgehen. + +#### 3.1.2. Das Entrypoint-Skript: `main.nf` + +Das `main.nf`-Skript ist der Entrypoint, von dem Nextflow startet, wenn wir `nextflow run nf-core/demo` ausführen. +Das bedeutet, wenn du `nextflow run nf-core/demo` ausführst, um die Pipeline zu starten, findet und führt Nextflow automatisch das `main.nf`-Skript aus. +Dies funktioniert für jede Nextflow-Pipeline, die dieser konventionellen Benennung und Struktur folgt, nicht nur für nf-core Pipelines. + +Die Verwendung eines Entrypoint-Skripts macht es einfach, standardisierte 'Haushalts'-Subworkflows vor und nach der eigentlichen Analyse auszuführen. +Wir werden diese durchgehen, nachdem wir den eigentlichen Analyse-Workflow und seine Module durchgesehen haben. + +#### 3.1.3. Das Analyse-Skript: `workflows/demo.nf` + +Der `workflows/demo.nf` Workflow ist der Ort, an dem die zentrale Logik der Pipeline gespeichert ist. +Er ist ähnlich strukturiert wie ein normaler Nextflow-Workflow, außer dass er darauf ausgelegt ist, von einem übergeordneten Workflow aufgerufen zu werden, was ein paar zusätzliche Funktionen erfordert. +Wir werden die relevanten Unterschiede im nächsten Teil dieses Kurses behandeln, wenn wir die Konvertierung der einfachen Hello-Pipeline aus Hello Nextflow in eine nf-core-kompatible Form angehen. + +Der `demo.nf` Workflow greift auf **Module** zu, die sich unter `modules/` befinden, die wir als Nächstes durchgehen werden. + +!!! note "Hinweis" + + Einige nf-core Analyse-Workflows zeigen zusätzliche Verschachtelungsebenen, indem sie Subworkflows niedrigerer Ebene aufrufen. + Dies wird hauptsächlich verwendet, um zwei oder mehr Module, die häufig zusammen verwendet werden, in leicht wiederverwendbare Pipeline-Segmente zu verpacken. + Du kannst einige Beispiele sehen, indem du verfügbare [nf-core subworkflows](https://nf-co.re/subworkflows/) auf der nf-core-Website durchsuchst. + + Wenn das Analyse-Skript Subworkflows verwendet, werden diese unter dem `subworkflows/`-Verzeichnis gespeichert. + +#### 3.1.4. Die Module + +Die Module sind der Ort, wo der Prozesscode lebt, wie in [Teil 4 des Hello Nextflow Trainingskurses](../hello_nextflow/04_hello_modules.md) beschrieben. + +Im nf-core-Projekt werden Module unter Verwendung einer mehrstufigen verschachtelten Struktur organisiert, die sowohl ihre Herkunft als auch ihren Inhalt widerspiegeln. +Auf der obersten Ebene werden Module als entweder `nf-core` oder `local` (nicht Teil des nf-core-Projekts) unterschieden und dann weiter in ein Verzeichnis platziert, das nach dem/den Tool(s) benannt ist, das/die sie umschließen. +Wenn das Tool zu einem Toolkit gehört (d.h. einem Paket, das mehrere Tools enthält), dann gibt es eine Zwischenverzeichnisebene, die nach dem Toolkit benannt ist. + +Du kannst dies in der Praxis auf die `nf-core/demo` Pipeline-Module angewendet sehen: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Verzeichnisinhalt" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Hier siehst du, dass die Module `fastqc` und `multiqc` auf der obersten Ebene innerhalb der `nf-core` Module sitzen, während das `trim` Modul unter dem Toolkit sitzt, zu dem es gehört, `seqtk`. +In diesem Fall gibt es keine `local` Module. + +Die Modul-Code-Datei, die den Prozess beschreibt, heißt immer `main.nf` und wird von Tests und `.yml`-Dateien begleitet, die wir vorerst ignorieren werden. + +Zusammengenommen sind der Entrypoint-Workflow, der Analyse-Workflow und die Module ausreichend, um die 'interessanten' Teile der Pipeline auszuführen. +Wir wissen jedoch, dass es dort auch Haushalts-Subworkflows gibt, also schauen wir uns diese jetzt an. + +#### 3.1.5. Die Haushalts-Subworkflows + +Wie Module werden Subworkflows in `local` und `nf-core` Verzeichnisse unterschieden, und jeder Subworkflow hat seine eigene verschachtelte Verzeichnisstruktur mit seinem eigenen `main.nf`-Skript, Tests und `.yml`-Datei. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Verzeichnisinhalt" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Wie oben erwähnt, enthält die `nf-core/demo` Pipeline keine analysespezifischen Subworkflows, sodass alle Subworkflows, die wir hier sehen, sogenannte 'Haushalts'- oder 'Utility'-Workflows sind, wie durch das Präfix `utils_` in ihren Namen bezeichnet. +Diese Subworkflows sind es, die den schicken nf-core-Header in der Konsolenausgabe erzeugen, neben anderen zusätzlichen Funktionen. + +!!! tip "Tipp" + + Abgesehen von ihrem Benennungsmuster ist ein weiterer Hinweis darauf, dass diese Subworkflows keine wirklich analysebezogene Funktion ausführen, dass sie überhaupt keine Prozesse aufrufen. + +Dies vervollständigt die Zusammenfassung der Kern-Code-Komponenten, die die `nf-core/demo` Pipeline ausmachen. +Schauen wir uns nun die verbleibenden Elemente an, über die du ein wenig wissen solltest, bevor du in die Entwicklung eintauchst: Pipeline-Konfiguration und Eingabevalidierung. + +### 3.2. Pipeline-Konfiguration + +Du hast bereits gelernt, dass Nextflow viele Optionen zur Konfiguration der Pipeline-Ausführung bietet, sei es in Bezug auf Eingaben und Parameter, Rechenressourcen und andere Aspekte der Orchestrierung. +Das nf-core-Projekt wendet hochstandardisierte Richtlinien für die Pipeline-Konfiguration an, die darauf abzielen, auf den flexiblen Anpassungsoptionen von Nextflow aufzubauen, auf eine Weise, die größere Konsistenz und Wartbarkeit über Pipelines hinweg bietet. + +Die zentrale Konfigurationsdatei `nextflow.config` wird verwendet, um Standardwerte für Parameter und andere Konfigurationsoptionen festzulegen. +Die Mehrheit dieser Konfigurationsoptionen wird standardmäßig angewendet, während andere (z.B. Software-Abhängigkeitsprofile) als optionale Profile enthalten sind. + +Es gibt mehrere zusätzliche Konfigurationsdateien, die im `conf`-Ordner gespeichert sind und die standardmäßig oder optional als Profile zur Konfiguration hinzugefügt werden können: + +- `base.config`: Eine 'leere Slate'-Konfigurationsdatei, geeignet für die allgemeine Verwendung in den meisten High-Performance-Computing-Umgebungen. Diese definiert breite Bins der Ressourcennutzung, die beispielsweise praktisch auf Module angewendet werden können. +- `modules.config`: Zusätzliche Modul-Direktiven und Argumente. +- `test.config`: Ein Profil zum Ausführen der Pipeline mit minimalen Testdaten, das wir verwendet haben, als wir die Demo-Pipeline ausgeführt haben. +- `test_full.config`: Ein Profil zum Ausführen der Pipeline mit einem vollständigen Testdatensatz. + +Wir werden einige dieser Dateien später im Kurs berühren. + +### 3.3. Eingaben und Validierung + +Wie wir bereits festgestellt haben, als wir das Testprofil der `nf-core/demo` Pipeline untersucht haben, ist sie darauf ausgelegt, als Eingabe ein Samplesheet zu nehmen, das Dateipfade und Probenidentifikatoren enthält. +Die Dateipfade verwiesen auf echte Daten, die sich im `nf-core/test-datasets` Repository befinden. + +Ein Beispiel-Samplesheet wird auch unter dem `assets`-Verzeichnis bereitgestellt, obwohl die Pfade in diesem nicht real sind. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Dieses spezielle Samplesheet ist ziemlich einfach, aber einige Pipelines laufen auf Samplesheets, die komplexer sind, mit viel mehr Metadaten, die mit den primären Eingaben verbunden sind. + +Leider, weil diese Dateien schwierig mit dem Auge zu überprüfen sein können, ist eine unsachgemäße Formatierung von Eingabedaten eine sehr häufige Ursache für Pipeline-Fehler. +Ein verwandtes Problem ist, wenn Parameter falsch bereitgestellt werden. + +Die Lösung für diese Probleme besteht darin, automatisierte Validierungsprüfungen auf allen Eingabedateien auszuführen, um sicherzustellen, dass sie die erwarteten Arten von Informationen enthalten, korrekt formatiert, und auf Parametern, um sicherzustellen, dass sie vom erwarteten Typ sind. +Dies wird Eingabevalidierung genannt und sollte idealerweise _vor_ dem Versuch, eine Pipeline auszuführen, durchgeführt werden, anstatt darauf zu warten, dass die Pipeline fehlschlägt, um herauszufinden, dass es ein Problem mit den Eingaben gab. + +Genau wie bei der Konfiguration ist das nf-core-Projekt sehr eigenwillig bezüglich der Eingabevalidierung und empfiehlt die Verwendung des [nf-schema plugin](https://nextflow-io.github.io/nf-schema/latest/), ein Nextflow-Plugin, das umfassende Validierungsfähigkeiten für Nextflow-Pipelines bietet. + +Wir werden dieses Thema in Teil 5 dieses Kurses ausführlicher behandeln. +Sei dir vorerst bewusst, dass es zu diesem Zweck zwei JSON-Dateien gibt, `nextflow_schema.json` und `assets/schema_input.json`. + +Die `nextflow_schema.json` ist eine Datei, die verwendet wird, um Informationen über die Pipeline-Parameter zu speichern, einschließlich Typ, Beschreibung und Hilfetext in einem maschinenlesbaren Format. +Dies wird für verschiedene Zwecke verwendet, einschließlich automatisierter Parametervalidierung, Hilfetextgenerierung und interaktiver Parameter-Formular-Darstellung in UI-Schnittstellen. + +Die `schema_input.json` ist eine Datei, die verwendet wird, um die Struktur des Eingabe-Samplesheets zu definieren. +Jede Spalte kann einen Typ, ein Muster, eine Beschreibung und einen Hilfetext in einem maschinenlesbaren Format haben. +Das Schema wird für verschiedene Zwecke verwendet, einschließlich automatisierter Validierung und der Bereitstellung hilfreicher Fehlermeldungen. + +### Zusammenfassung + +Du weißt, was die Hauptkomponenten einer nf-core Pipeline sind und wie der Code organisiert ist; wo sich die Hauptelemente der Konfiguration befinden; und du bist dir bewusst, wofür die Eingabevalidierung da ist. + +### Wie geht es weiter? + +Mach eine Pause! Das war eine Menge. Wenn du dich erfrischt und bereit fühlst, gehe zum nächsten Abschnitt über, um das Gelernte anzuwenden und eine nf-core-kompatible Pipeline zu schreiben. + +!!! tip "Tipp" + + Wenn du lernen möchtest, wie man Workflows mit Subworkflows komponiert, bevor du zum nächsten Teil übergehst, schau dir die [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest an. diff --git a/docs/de/docs/hello_nf-core/02_rewrite_hello.md b/docs/de/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..fa0984fad3 --- /dev/null +++ b/docs/de/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1367 @@ +# Teil 2: Hello für nf-core umschreiben + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem zweiten Teil des Hello nf-core Trainingskurses zeigen wir dir, wie du eine nf-core-kompatible Version der Pipeline erstellst, die im [Hello Nextflow](../hello_nextflow/index.md) Einsteigerkurs entwickelt wurde. + +Dir ist im ersten Abschnitt des Trainings aufgefallen, dass nf-core-Pipelines einer ziemlich aufwendigen Struktur mit vielen zusätzlichen Dateien folgen. +All das von Grund auf zu erstellen wäre sehr mühsam, deshalb hat die nf-core-Community Werkzeuge entwickelt, um dies stattdessen aus einer Vorlage zu erstellen und den Prozess zu beschleunigen. + +Wir zeigen dir, wie du diese Werkzeuge verwendest, um ein Pipeline-Gerüst zu erstellen, und dann bestehenden 'normalen' Pipeline-Code auf das nf-core-Gerüst anzupassen. + +Falls du mit der Hello-Pipeline nicht vertraut bist oder eine Auffrischung brauchst, schau dir [diese Infoseite](../info/hello_pipeline.md) an. + +--- + +## 1. Ein neues Pipeline-Projekt erstellen + +Zuerst erstellen wir das Gerüst für die neue Pipeline. + +!!! note "Hinweis" + + Stelle sicher, dass du dich im Terminal im Verzeichnis `hello-nf-core` befindest. + +### 1.1. Das vorlagenbasierte Pipeline-Erstellungswerkzeug ausführen + +Lass uns damit beginnen, eine neue Pipeline mit dem Befehl `nf-core pipelines create` zu erstellen. +Dieser erstellt ein neues Pipeline-Gerüst unter Verwendung der nf-core-Basisvorlage, angepasst mit einem Pipeline-Namen, einer Beschreibung und einem Autor. + +```bash +nf-core pipelines create +``` + +Das Ausführen dieses Befehls öffnet eine Text User Interface (TUI) zur Pipeline-Erstellung: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Diese TUI fordert dich auf, grundlegende Informationen über deine Pipeline anzugeben und bietet dir die Auswahl an Funktionen, die du in dein Pipeline-Gerüst einbeziehen oder ausschließen möchtest. + +- Klicke auf dem Willkommensbildschirm auf **Let's go!**. +- Auf dem Bildschirm `Choose pipeline type` klicke auf **Custom**. +- Gib deine Pipeline-Details wie folgt ein (ersetze `< DEIN NAME >` durch deinen eigenen Namen) und klicke dann auf **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < DEIN NAME > +``` + +- Auf dem Template features Bildschirm stelle `Toggle all features` auf **off**, dann **aktiviere** selektiv die folgenden Optionen. Überprüfe deine Auswahl und klicke auf **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- Auf dem Bildschirm `Final details` klicke auf **Finish**. Warte, bis die Pipeline erstellt wurde, dann klicke auf **Continue**. +- Auf dem Bildschirm Create GitHub repository klicke auf **Finish without creating a repo**. Dies zeigt Anweisungen zum späteren Erstellen eines GitHub-Repositories an. Ignoriere diese und klicke auf **Close**. + +Sobald die TUI sich schließt, solltest du die folgende Konsolenausgabe sehen. + +??? success "Befehlsausgabe" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +Es gibt keine explizite Bestätigung in der Konsolenausgabe, dass die Pipeline-Erstellung funktioniert hat, aber du solltest ein neues Verzeichnis namens `core-hello` sehen. + +Sieh dir den Inhalt des neuen Verzeichnisses an, um zu sehen, wie viel Arbeit du dir durch die Verwendung der Vorlage erspart hast. + +```bash +tree core-hello +``` + +??? abstract "Verzeichnisinhalt" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +Das sind eine Menge Dateien! + +Hoffentlich erkennst du viele davon als dieselben, die wir bei der Untersuchung der `nf-core/demo`-Pipeline-Struktur kennengelernt haben. +Aber keine Sorge, wenn du dich noch etwas verloren fühlst; wir werden im Verlauf dieses Trainings gemeinsam die wichtigen Teile durchgehen. + +!!! note "Hinweis" + + Ein wichtiger Unterschied im Vergleich zur `nf-core/demo`-Pipeline, die wir im ersten Teil dieses Trainings untersucht haben, ist, dass es kein `modules`-Verzeichnis gibt. + Das liegt daran, dass wir uns nicht dafür entschieden haben, eines der Standard-nf-core-Module einzubeziehen. + +### 1.2. Testen, dass das Gerüst funktionsfähig ist + +Glaub es oder nicht, auch wenn du noch keine Module hinzugefügt hast, um echte Arbeit zu leisten, kann das Pipeline-Gerüst tatsächlich mit dem Testprofil ausgeführt werden, auf die gleiche Weise wie wir die `nf-core/demo`-Pipeline ausgeführt haben. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Dies zeigt dir, dass die gesamte grundlegende Verkabelung vorhanden ist. +Wo sind also die Ausgaben? Gibt es welche? + +Tatsächlich wurde ein neues Ergebnisverzeichnis namens `core-hello-results` erstellt, das die standardmäßigen Ausführungsberichte enthält: + +```bash +tree core-hello-results +``` + +??? abstract "Verzeichnisinhalt" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Du kannst einen Blick in die Berichte werfen, um zu sehen, was ausgeführt wurde, und die Antwort ist: überhaupt nichts! + +![leerer Execution-Timeline-Bericht](./img/execution_timeline_empty.png) + +Schauen wir uns an, was tatsächlich im Code steht. + +### 1.3. Den Platzhalter-Workflow untersuchen + +Wenn du in die Datei `main.nf` schaust, siehst du, dass sie einen Workflow namens `HELLO` aus `workflows/hello` importiert. + +Dies entspricht dem `workflows/demo.nf`-Workflow, dem wir in Teil 1 begegnet sind, und dient als Platzhalter-Workflow für unseren Workflow von Interesse, mit bereits vorhandener nf-core-Funktionalität. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // Channel: Samplesheet eingelesen von --input + main: + + ch_versions = channel.empty() + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // Channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Im Vergleich zu einem grundlegenden Nextflow-Workflow wie dem, der in [Hello Nextflow](../hello_nextflow/index.md) entwickelt wurde, wirst du hier ein paar Dinge bemerken, die neu sind (hervorgehobene Zeilen oben): + +- Der Workflow-Block hat einen Namen +- Workflow-Eingaben werden mit dem Schlüsselwort `take:` deklariert und die Kanal-Konstruktion wird in den übergeordneten Workflow verschoben +- Workflow-Inhalt wird in einem `main:`-Block platziert +- Ausgaben werden mit dem Schlüsselwort `emit:` deklariert + +Dies sind optionale Funktionen von Nextflow, die den Workflow **komponierbar** machen, was bedeutet, dass er aus einem anderen Workflow heraus aufgerufen werden kann. + +!!! note "Komponierbare Workflows im Detail" + + Der [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest untersucht die Workflow-Komposition viel ausführlicher, einschließlich wie man mehrere Workflows zusammensetzt und komplexe Datenflüsse zwischen ihnen verwaltet. Wir führen die Komponierbarkeit hier ein, weil sie eine grundlegende Anforderung der nf-core-Template-Architektur ist, die verschachtelte Workflows verwendet, um Pipeline-Initialisierung, den Hauptanalyse-Workflow und Abschlussaufgaben in separate, wiederverwendbare Komponenten zu organisieren. + +Wir müssen die relevante Logik aus unserem Workflow von Interesse in diese Struktur einbinden. +Der erste Schritt dafür ist, unseren ursprünglichen Workflow komponierbar zu machen. + +### Zusammenfassung + +Du weißt jetzt, wie man ein Pipeline-Gerüst mit nf-core-Tools erstellt. + +### Was kommt als Nächstes? + +Lerne, wie man einen einfachen Workflow komponierbar macht als Vorbereitung darauf, ihn nf-core-kompatibel zu machen. + +--- + +## 2. Den ursprünglichen Hello Nextflow-Workflow komponierbar machen + +Jetzt ist es Zeit, mit der Integration unseres Workflows in das nf-core-Gerüst zu beginnen. +Zur Erinnerung: Wir arbeiten mit dem Workflow aus unserem [Hello Nextflow](../hello_nextflow/index.md) Trainingskurs. + +!!! tip "Tipp" + + Falls du mit dieser Pipeline nicht vertraut bist oder eine Auffrischung brauchst, siehe [Die Hello-Pipeline](../info/hello_pipeline.md). + +Wir stellen dir eine saubere, voll funktionsfähige Kopie des abgeschlossenen Hello Nextflow-Workflows im Verzeichnis `original-hello` zusammen mit seinen Modulen und der Standard-CSV-Datei zur Verfügung, die sie als Eingabe erwartet. + +```bash +tree original-hello/ +``` + +??? abstract "Verzeichnisinhalt" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Führe sie gerne aus, um dich selbst zu überzeugen, dass sie funktioniert: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Lass uns die Workflow-Datei `hello.nf` öffnen, um den Code zu inspizieren, der unten vollständig gezeigt wird (die Prozesse nicht mitgezählt, die in Modulen sind): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline-Parameter +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Module einbinden +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Wie du sehen kannst, wurde dieser Workflow als einfacher unbenannter Workflow geschrieben, der eigenständig ausgeführt werden kann. +Um ihn aus einem übergeordneten Workflow heraus ausführbar zu machen, wie es die nf-core-Vorlage erfordert, müssen wir ihn **komponierbar** machen. + +Gehen wir die notwendigen Änderungen Schritt für Schritt durch. + +### 2.1. Den Workflow benennen + +Zuerst geben wir dem Workflow einen Namen, damit wir ihn aus einem übergeordneten Workflow referenzieren können. + +=== "Nachher" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Vorher" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Für Workflow-Namen gelten die gleichen Konventionen wie für Modulnamen. + +### 2.2. Kanal-Konstruktion durch `take` ersetzen + +Ersetze nun die Kanal-Konstruktion durch eine einfache `take`-Anweisung, die erwartete Eingaben deklariert. + +=== "Nachher" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // Channel für Begrüßungen + greeting_ch + ``` + +=== "Vorher" + + ```groovy title="original-hello/hello.nf" linenums="18" + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Dies überlässt die Details, wie die Eingaben bereitgestellt werden, dem übergeordneten Workflow. + +Während wir dabei sind, können wir auch die Zeile `params.greeting = 'greetings.csv'` auskommentieren + +=== "Nachher" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Vorher" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Hinweis" + + Falls du die Nextflow Language Server Extension installiert hast, wird der Syntax-Checker deinen Code mit roten Wellenlinien markieren. + Das liegt daran, dass du, wenn du eine `take:`-Anweisung einfügst, auch ein `main:` haben musst. + + Das fügen wir im nächsten Schritt hinzu. + +### 2.3. Workflow-Operationen mit `main`-Anweisung einleiten + +Als Nächstes füge eine `main`-Anweisung vor den restlichen Operationen hinzu, die im Körper des Workflows aufgerufen werden. + +=== "Nachher" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Vorher" + + ```groovy title="original-hello/hello.nf" linenums="21" + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Dies sagt im Grunde 'das ist es, was dieser Workflow _macht_'. + +### 2.4. `emit`-Anweisung hinzufügen + +Füge schließlich eine `emit`-Anweisung hinzu, die deklariert, was die finalen Ausgaben des Workflows sind. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Dies ist eine neue Ergänzung zum Code im Vergleich zum ursprünglichen Workflow. + +### 2.5. Zusammenfassung der abgeschlossenen Änderungen + +Wenn du alle Änderungen wie beschrieben vorgenommen hast, sollte dein Workflow jetzt so aussehen: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' (auskommentiert) +params.batch = 'test-batch' +params.character = 'turkey' + +// Module einbinden +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // Channel für Begrüßungen + greeting_ch + + main: + + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Dies beschreibt alles, was Nextflow braucht, AUSSER was in den Eingabekanal eingespeist werden soll. +Das wird im übergeordneten Workflow definiert, auch **Einstiegspunkt**-Workflow genannt. + +### 2.6. Einen Dummy-Einstiegspunkt-Workflow erstellen + +Bevor wir unseren komponierbaren Workflow in das komplexe nf-core-Gerüst integrieren, überprüfen wir, ob er korrekt funktioniert. +Wir können einen einfachen Dummy-Einstiegspunkt-Workflow erstellen, um den komponierbaren Workflow isoliert zu testen. + +Erstelle eine leere Datei namens `main.nf` im selben `original-hello`-Verzeichnis. + +```bash +touch original-hello/main.nf +``` + +Kopiere den folgenden Code in die Datei `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// Den Workflow-Code aus der hello.nf-Datei importieren +include { HELLO } from './hello.nf' + +// Eingabeparameter deklarieren +params.greeting = 'greetings.csv' + +workflow { + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // Den importierten Workflow mit dem Channel der Begrüßungen aufrufen + HELLO(greeting_ch) + + // Die vom Workflow ausgegebenen Ergebnisse anzeigen + HELLO.out.view { output -> "Output: $output" } +} +``` + +Hier gibt es zwei wichtige Beobachtungen: + +- Die Syntax zum Aufrufen des importierten Workflows ist im Wesentlichen dieselbe wie die Syntax zum Aufrufen von Modulen. +- Alles, was mit dem Einbringen der Eingaben in den Workflow zu tun hat (Eingabeparameter und Kanal-Konstruktion), wird jetzt in diesem übergeordneten Workflow deklariert. + +!!! note "Hinweis" + + Die Benennung der Einstiegspunkt-Workflow-Datei `main.nf` ist eine Konvention, keine Anforderung. + + Wenn du dieser Konvention folgst, kannst du die Angabe des Workflow-Dateinamens in deinem `nextflow run`-Befehl weglassen. + Nextflow sucht automatisch nach einer Datei namens `main.nf` im Ausführungsverzeichnis. + + Du kannst die Einstiegspunkt-Workflow-Datei jedoch auch anders benennen, wenn du möchtest. + In diesem Fall stelle sicher, dass du den Workflow-Dateinamen in deinem `nextflow run`-Befehl angibst. + +### 2.7. Testen, dass der Workflow läuft + +Wir haben endlich alle Teile, die wir brauchen, um zu überprüfen, dass der komponierbare Workflow funktioniert. +Lass uns ihn ausführen! + +```bash +nextflow run ./original-hello +``` + +Hier siehst du den Vorteil der Verwendung der `main.nf`-Namenskonvention. +Hätten wir den Einstiegspunkt-Workflow `something_else.nf` genannt, hätten wir `nextflow run original-hello/something_else.nf` ausführen müssen. + +Wenn du alle Änderungen korrekt vorgenommen hast, sollte dies bis zum Abschluss laufen. + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Das bedeutet, wir haben unseren HELLO-Workflow erfolgreich auf komponierbar aktualisiert. + +### Zusammenfassung + +Du weißt, wie man einen Workflow komponierbar macht, indem man ihm einen Namen gibt und `take`-, `main`- und `emit`-Anweisungen hinzufügt, und wie man ihn aus einem Einstiegspunkt-Workflow aufruft. + +### Was kommt als Nächstes? + +Lerne, wie man einen einfachen komponierbaren Workflow auf das nf-core-Gerüst aufpfropft. + +--- + +## 3. Die aktualisierte Workflow-Logik in den Platzhalter-Workflow einpassen + +Nachdem wir überprüft haben, dass unser komponierbarer Workflow korrekt funktioniert, kehren wir zum nf-core-Pipeline-Gerüst zurück, das wir in Abschnitt 1 erstellt haben. +Wir wollen den komponierbaren Workflow, den wir gerade entwickelt haben, in die nf-core-Template-Struktur integrieren, sodass das Endergebnis ungefähr so aussehen sollte. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Wie machen wir das? Werfen wir einen Blick auf den aktuellen Inhalt des `HELLO`-Workflows in `core-hello/workflows/hello.nf` (das nf-core-Gerüst). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // Channel: Samplesheet eingelesen von --input + main: + + ch_versions = channel.empty() + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // Channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Insgesamt macht dieser Code nur sehr wenig abgesehen von einiger Buchhaltung, die damit zu tun hat, die Version aller Softwaretools zu erfassen, die in der Pipeline ausgeführt werden. + +Wir müssen den relevanten Code aus der komponierbaren Version des ursprünglichen Workflows hinzufügen, den wir in Abschnitt 2 entwickelt haben. + +Wir werden dies in den folgenden Phasen angehen: + +1. Module kopieren und Modul-Importe einrichten +2. Die `take`-Deklaration so lassen wie sie ist +3. Die Workflow-Logik zum `main`-Block hinzufügen +4. Den `emit`-Block aktualisieren + +!!! note "Hinweis" + + Wir werden die Versionserfassung bei diesem ersten Durchgang ignorieren und in einem späteren Teil dieses Trainings zeigen, wie man das verdrahtet. + +### 3.1. Module kopieren und Modul-Importe einrichten + +Die vier Prozesse aus unserem Hello Nextflow-Workflow sind als Module in `original-hello/modules/` gespeichert. +Wir müssen diese Module in die nf-core-Projektstruktur (unter `core-hello/modules/local/`) kopieren und Import-Anweisungen zur nf-core-Workflow-Datei hinzufügen. + +Lass uns zuerst die Moduldateien von `original-hello/` nach `core-hello/` kopieren: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Du solltest jetzt das Verzeichnis der Module unter `core-hello/` aufgelistet sehen. + +```bash +tree core-hello/modules +``` + +??? abstract "Verzeichnisinhalt" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Jetzt richten wir die Modul-Import-Anweisungen ein. + +Das waren die Import-Anweisungen im `original-hello/hello.nf`-Workflow: + +```groovy title="original-hello/hello.nf" linenums="9" +// Module einbinden +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Öffne die Datei `core-hello/workflows/hello.nf` und übertrage diese Import-Anweisungen hinein, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Zwei weitere interessante Beobachtungen hier: + +- Wir haben die Formatierung der Import-Anweisungen angepasst, um der nf-core-Stilkonvention zu folgen. +- Wir haben die relativen Pfade zu den Modulen aktualisiert, um widerzuspiegeln, dass sie jetzt auf einer anderen Verschachtelungsebene gespeichert sind. + +### 3.2. Die `take`-Deklaration so lassen wie sie ist + +Das nf-core-Projekt hat viel vorgebaute Funktionalität rund um das Konzept des Samplesheets, das typischerweise eine CSV-Datei mit spaltenförmigen Daten ist. +Da dies im Wesentlichen das ist, was unsere `greetings.csv`-Datei ist, behalten wir die aktuelle `take`-Deklaration bei und aktualisieren einfach den Namen des Eingabekanals im nächsten Schritt. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // Channel: Samplesheet eingelesen von --input +``` + +Die Eingabebehandlung wird oberhalb dieses Workflows erfolgen (nicht in dieser Codedatei). + +### 3.3. Die Workflow-Logik zum `main`-Block hinzufügen + +Jetzt, da unsere Module dem Workflow zur Verfügung stehen, können wir die Workflow-Logik in den `main`-Block einfügen. + +Zur Erinnerung: Dies ist der relevante Code im ursprünglichen Workflow, der sich nicht viel geändert hat, als wir ihn komponierbar gemacht haben (wir haben nur die Zeile `main:` hinzugefügt): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) +``` + +Wir müssen den Code, der nach `main:` kommt, in die neue Version des Workflows kopieren. + +Es gibt bereits etwas Code dort, der damit zu tun hat, die Versionen der Tools zu erfassen, die vom Workflow ausgeführt werden. Das lassen wir vorerst in Ruhe (wir werden uns später mit den Tool-Versionen befassen). +Wir behalten die Initialisierung `ch_versions = channel.empty()` oben bei, fügen dann unsere Workflow-Logik ein und behalten den Versionskollationscode am Ende. +Diese Reihenfolge macht Sinn, weil in einer echten Pipeline die Prozesse Versionsinformationen ausgeben würden, die dem `ch_versions`-Kanal hinzugefügt würden, während der Workflow läuft. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // Channel: Samplesheet eingelesen von --input + + main: + + ch_versions = Channel.empty() + + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // Channel: [ path(versions.yml) ] + + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // Channel: Samplesheet eingelesen von --input + main: + + ch_versions = Channel.empty() + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // Channel: [ path(versions.yml) ] + + } + ``` + +Du wirst bemerken, dass wir auch eine Leerzeile vor `main:` hinzugefügt haben, um den Code lesbarer zu machen. + +Das sieht großartig aus, aber wir müssen noch den Namen des Kanals aktualisieren, den wir an den `sayHello()`-Prozess übergeben, von `greeting_ch` zu `ch_samplesheet`, wie unten gezeigt, damit er mit dem übereinstimmt, was unter dem `take:`-Schlüsselwort geschrieben steht. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // Eine Begrüßung ausgeben (aktualisiert für die nf-core-Konvention für Samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + ``` + +Jetzt ist die Workflow-Logik korrekt verdrahtet. + +### 3.4. Den `emit`-Block aktualisieren + +Schließlich müssen wir den `emit`-Block aktualisieren, um die Deklaration der finalen Ausgaben des Workflows einzubeziehen. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // Channel: [ path(versions.yml) ] + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // Channel: [ path(versions.yml) ] + ``` + +Damit sind die Änderungen abgeschlossen, die wir am HELLO-Workflow selbst vornehmen müssen. +An diesem Punkt haben wir die Gesamt-Code-Struktur erreicht, die wir umsetzen wollten. + +### Zusammenfassung + +Du weißt, wie man die Kernstücke eines komponierbaren Workflows in einen nf-core-Platzhalter-Workflow einfügt. + +### Was kommt als Nächstes? + +Lerne, wie man die Handhabung der Eingaben im nf-core-Pipeline-Gerüst anpasst. + +--- + +## 4. Die Eingabebehandlung anpassen + +Nachdem wir unsere Workflow-Logik erfolgreich in das nf-core-Gerüst integriert haben, müssen wir uns noch einem kritischen Teil widmen: sicherstellen, dass unsere Eingabedaten korrekt verarbeitet werden. +Die nf-core-Vorlage kommt mit ausgeklügelter Eingabebehandlung, die für komplexe Genomik-Datensätze entwickelt wurde, also müssen wir sie anpassen, damit sie mit unserer einfacheren `greetings.csv`-Datei funktioniert. + +### 4.1. Identifizieren, wo Eingaben behandelt werden + +Der erste Schritt ist herauszufinden, wo die Eingabebehandlung durchgeführt wird. + +Du erinnerst dich vielleicht, dass wir, als wir den Hello Nextflow-Workflow umgeschrieben haben, um ihn komponierbar zu machen, die Eingabeparameter-Deklaration eine Ebene höher verschoben haben, in den `main.nf`-Einstiegspunkt-Workflow. +Also schauen wir uns den obersten `main.nf`-Einstiegspunkt-Workflow an, der als Teil des Pipeline-Gerüsts erstellt wurde: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Haupt-Analyse-Pipeline abhängig vom Eingabetyp ausführen +// +workflow CORE_HELLO { + + take: + samplesheet // Channel: Samplesheet eingelesen von --input + + main: + + // + // WORKFLOW: Pipeline ausführen + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Initialisierungsaufgaben ausführen + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Haupt-Workflow ausführen + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Abschlussaufgaben ausführen + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Das nf-core-Projekt macht starken Gebrauch von verschachtelten Subworkflows, daher kann dieser Teil bei der ersten Annäherung etwas verwirrend sein. + +Was hier wichtig ist, ist, dass zwei Workflows definiert sind: + +- `CORE_HELLO` ist ein dünner Wrapper zum Ausführen des HELLO-Workflows, den wir gerade in `core-hello/workflows/hello.nf` angepasst haben. +- Ein unbenannter Workflow, der `CORE_HELLO` sowie zwei andere Subworkflows aufruft, `PIPELINE_INITIALISATION` und `PIPELINE_COMPLETION`. + +Hier ist ein Diagramm, wie sie zueinander in Beziehung stehen: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Wichtig ist, dass wir auf dieser Ebene keinen Code finden können, der einen Eingabekanal konstruiert, nur Verweise auf ein Samplesheet, das über den Parameter `--input` bereitgestellt wird. + +Etwas Herumstöbern offenbart, dass die Eingabebehandlung vom Subworkflow `PIPELINE_INITIALISATION` durchgeführt wird, passenderweise, der aus `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf` importiert wird. + +Wenn wir diese Datei öffnen und nach unten scrollen, kommen wir zu diesem Codeblock: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Channel aus der Eingabedatei erstellen, die über params.input bereitgestellt wird + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +Dies ist die Kanal-Factory, die das Samplesheet parst und es in einer Form weitergibt, die bereit ist, vom HELLO-Workflow konsumiert zu werden. + +!!! note "Hinweis" + + Die Syntax oben unterscheidet sich etwas von dem, was wir bisher verwendet haben, aber grundsätzlich ist dies: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + äquivalent zu diesem: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Dieser Code umfasst einige Parse- und Validierungsschritte, die sehr spezifisch für das Beispiel-Samplesheet sind, das mit der nf-core-Pipeline-Vorlage enthalten ist, das zum Zeitpunkt des Schreibens sehr domänenspezifisch und für unser einfaches Pipeline-Projekt nicht geeignet ist. + +### 4.2. Den vorlagenbasierten Eingabekanalcode ersetzen + +Die gute Nachricht ist, dass die Bedürfnisse unserer Pipeline viel einfacher sind, sodass wir all das durch den Kanalkonstruktionscode ersetzen können, den wir im ursprünglichen Hello Nextflow-Workflow entwickelt haben. + +Zur Erinnerung: So sah die Kanal-Konstruktion aus (wie im Solutions-Verzeichnis zu sehen): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Also müssen wir das nur in den Initialisierungs-Workflow einfügen, mit kleinen Änderungen: Wir aktualisieren den Kanalnamen von `greeting_ch` zu `ch_samplesheet` und den Parameternamen von `params.greeting` zu `params.input` (siehe hervorgehobene Zeile). + +=== "Nachher" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Channel aus der Eingabedatei erstellen, die über params.input bereitgestellt wird + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Vorher" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Channel aus der Eingabedatei erstellen, die über params.input bereitgestellt wird + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Damit sind die Änderungen abgeschlossen, die wir vornehmen müssen, um die Eingabeverarbeitung zum Laufen zu bringen. + +In seiner aktuellen Form ermöglicht uns dies nicht, die integrierten Fähigkeiten von nf-core zur Schema-Validierung zu nutzen, aber das können wir später hinzufügen. +Vorerst konzentrieren wir uns darauf, es so einfach wie möglich zu halten, um etwas zu erreichen, das wir erfolgreich mit Testdaten ausführen können. + +### 4.3. Das Testprofil aktualisieren + +Apropos Testdaten und Parameter, lass uns das Testprofil für diese Pipeline aktualisieren, um das `greetings.csv`-Mini-Samplesheet anstelle des in der Vorlage bereitgestellten Beispiel-Samplesheets zu verwenden. + +Unter `core-hello/conf` finden wir zwei vorlagenbasierte Testprofile: `test.config` und `test_full.config`, die dazu gedacht sind, eine kleine Datenprobe und eine in voller Größe zu testen. +Angesichts des Zwecks unserer Pipeline gibt es nicht wirklich einen Sinn, ein Full-Size-Testprofil einzurichten, also kannst du `test_full.config` gerne ignorieren oder löschen. +Wir konzentrieren uns darauf, `test.config` so einzurichten, dass es mit unserer `greetings.csv`-Datei mit ein paar Standardparametern läuft. + +#### 4.3.1. Die `greetings.csv`-Datei kopieren + +Zuerst müssen wir die `greetings.csv`-Datei an einen geeigneten Platz in unserem Pipeline-Projekt kopieren. +Typischerweise werden kleine Testdateien im `assets`-Verzeichnis gespeichert, also kopieren wir die Datei aus unserem Arbeitsverzeichnis. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Jetzt ist die `greetings.csv`-Datei bereit, als Testeingabe verwendet zu werden. + +#### 4.3.2. Die `test.config`-Datei aktualisieren + +Jetzt können wir die `test.config`-Datei wie folgt aktualisieren: + +=== "Nachher" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Eingabedaten + input = "${projectDir}/assets/greetings.csv" + + // Weitere Parameter + batch = 'test' + character = 'tux' + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Eingabedaten + // TODO nf-core: Pfade zu deinen Testdaten auf nf-core/test-datasets angeben + // TODO nf-core: Erforderliche Parameter für den Test angeben, damit keine Kommandozeilen-Flags benötigt werden + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Wichtige Punkte: + +- **Verwendung von `${projectDir}`**: Dies ist eine implizite Nextflow-Variable, die auf das Verzeichnis zeigt, in dem sich das Haupt-Workflow-Skript befindet (die Pipeline-Root). Ihre Verwendung stellt sicher, dass der Pfad funktioniert, unabhängig davon, wo die Pipeline ausgeführt wird. +- **Absolute Pfade**: Durch die Verwendung von `${projectDir}` erstellen wir einen absoluten Pfad, was wichtig für Testdaten ist, die mit der Pipeline ausgeliefert werden. +- **Testdaten-Speicherort**: nf-core-Pipelines speichern Testdaten typischerweise im `assets/`-Verzeichnis innerhalb des Pipeline-Repositories für kleine Testdateien oder verweisen auf externe Testdatensätze für größere Dateien. + +Und während wir dabei sind, lass uns die Standard-Ressourcenlimits verschärfen, um sicherzustellen, dass dies auf sehr einfachen Maschinen läuft (wie den minimalen VMs in Github Codespaces): + +=== "Nachher" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Damit sind die Code-Modifikationen abgeschlossen, die wir vornehmen müssen. + +### 4.4. Die Pipeline mit dem Testprofil ausführen + +Das war eine Menge, aber wir können endlich versuchen, die Pipeline auszuführen! +Beachte, dass wir `--validate_params false` zur Befehlszeile hinzufügen müssen, weil wir die Validierung noch nicht eingerichtet haben (das kommt später). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Wenn du alle Änderungen korrekt vorgenommen hast, sollte dies bis zum Abschluss laufen. + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Wie du sehen kannst, hat dies die typische nf-core-Zusammenfassung am Anfang dank des Initialisierungs-Subworkflows produziert, und die Zeilen für jedes Modul zeigen jetzt die vollständigen PIPELINE:WORKFLOW:Modul-Namen. + +### 4.5. Die Pipeline-Ausgaben finden + +Die Frage ist jetzt: Wo sind die Ausgaben der Pipeline? +Und die Antwort ist ziemlich interessant: Es gibt jetzt zwei verschiedene Orte, an denen man nach den Ergebnissen suchen kann. + +Wie du dich vielleicht von früher erinnerst, produzierte unsere erste Ausführung des neu erstellten Workflows ein Verzeichnis namens `core-hello-results/`, das verschiedene Ausführungsberichte und Metadaten enthielt. + +```bash +tree core-hello-results +``` + +??? abstract "Verzeichnisinhalt" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution diff --git a/docs/de/docs/hello_nf-core/03_use_module.md b/docs/de/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..fcdd633f48 --- /dev/null +++ b/docs/de/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Teil 3: Ein nf-core-Modul verwenden + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem dritten Teil des Hello nf-core Trainingskurses zeigen wir dir, wie du ein existierendes nf-core-Modul findest, installierst und in deiner Pipeline verwendest. + +Einer der großen Vorteile der Arbeit mit nf-core ist die Möglichkeit, vorgefertigte, getestete Module aus dem [nf-core/modules](https://github.com/nf-core/modules) Repository zu nutzen. +Anstatt jeden Prozess von Grund auf neu zu schreiben, kannst du von der Community gepflegte Module installieren und verwenden, die Best Practices folgen. + +Um zu demonstrieren, wie das funktioniert, werden wir das eigene `collectGreetings`-Modul durch das `cat/cat`-Modul aus nf-core/modules in der `core-hello`-Pipeline ersetzen. + +??? info "Wie du von diesem Abschnitt aus beginnst" + + Dieser Abschnitt des Kurses setzt voraus, dass du [Teil 2: Hello für nf-core umschreiben](./02_rewrite_hello.md) abgeschlossen hast und eine funktionierende `core-hello`-Pipeline besitzt. + + Falls du Teil 2 nicht abgeschlossen hast oder für diesen Teil neu beginnen möchtest, kannst du die `core-hello-part2`-Lösung als Ausgangspunkt verwenden. + Führe diesen Befehl innerhalb des `hello-nf-core/`-Verzeichnisses aus: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Das gibt dir eine voll funktionsfähige nf-core-Pipeline, die bereit ist für das Hinzufügen von Modulen. + Du kannst testen, ob sie erfolgreich läuft, indem du folgenden Befehl ausführst: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Ein passendes nf-core-Modul finden und installieren + +Zuerst lernen wir, wie man ein existierendes nf-core-Modul findet und in unsere Pipeline installiert. + +Wir werden versuchen, den `collectGreetings`-Prozess zu ersetzen, der den Unix-`cat`-Befehl verwendet, um mehrere Grußdateien in eine einzige zu verketten. +Das Verketten von Dateien ist eine sehr häufige Operation, daher liegt es nahe, dass es bereits ein Modul in nf-core gibt, das für diesen Zweck entwickelt wurde. + +Lass uns eintauchen. + +### 1.1. Verfügbare Module auf der nf-core-Website durchsuchen + +Das nf-core-Projekt pflegt einen zentralen Katalog von Modulen unter [https://nf-co.re/modules](https://nf-co.re/modules). + +Navigiere zur Modulseite in deinem Webbrowser und verwende die Suchleiste, um nach 'concatenate' zu suchen. + +![Modul-Suchergebnisse](./img/module-search-results.png) + +Wie du sehen kannst, gibt es einige Ergebnisse, viele davon Module, die für das Verketten sehr spezifischer Dateitypen entwickelt wurden. +Unter ihnen solltest du eines namens `cat_cat` sehen, das universell einsetzbar ist. + +!!! note "Namenskonvention für Module" + + Der Unterstrich (`_`) wird als Platzhalter für den Schrägstrich (`/`) in Modulnamen verwendet. + + nf-core-Module folgen der Namenskonvention `software/command`, wenn ein Tool mehrere Befehle bereitstellt, wie `samtools/view` (samtools-Paket, view-Befehl) oder `gatk/haplotypecaller` (GATK-Paket, HaplotypeCaller-Befehl). + Für Tools, die nur einen Hauptbefehl bereitstellen, verwenden Module eine einzelne Ebene wie `fastqc` oder `multiqc`. + +Klicke auf das `cat_cat`-Modulfeld, um die Moduldokumentation anzuzeigen. + +Die Modulseite zeigt: + +- Eine kurze Beschreibung: "A module for concatenation of gzipped or uncompressed files" +- Installationsbefehl: `nf-core modules install cat/cat` +- Struktur der Eingabe- und Ausgabekanäle +- Verfügbare Parameter + +### 1.2. Verfügbare Module von der Kommandozeile auflisten + +Alternativ kannst du auch direkt von der Kommandozeile aus mit nf-core-Tools nach Modulen suchen. + +```bash +nf-core modules list remote +``` + +Dies zeigt eine Liste aller verfügbaren Module im nf-core/modules Repository an, ist aber etwas weniger praktisch, wenn du den Namen des Moduls, nach dem du suchst, nicht bereits kennst. +Wenn du ihn jedoch kennst, kannst du die Liste mit `grep` filtern, um spezifische Module zu finden: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Befehlsausgabe" + + ```console + │ cat/cat + ``` + +Beachte nur, dass der `grep`-Ansatz nur Ergebnisse mit dem Suchbegriff im Namen herausfiltern wird, was bei `cat_cat` nicht funktionieren würde. + +### 1.3. Detaillierte Informationen über das Modul erhalten + +Um detaillierte Informationen über ein bestimmtes Modul von der Kommandozeile aus zu sehen, verwende den `info`-Befehl: + +```bash +nf-core modules info cat/cat +``` + +Dies zeigt die Dokumentation über das Modul an, einschließlich seiner Eingaben, Ausgaben und grundlegender Nutzungsinformationen. + +??? success "Befehlsausgabe" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +Das ist genau die gleiche Information, die du auch auf der Website findest. + +### 1.4. Das cat/cat-Modul installieren + +Jetzt, da wir das gewünschte Modul gefunden haben, müssen wir es zum Quellcode unserer Pipeline hinzufügen. + +Die gute Nachricht ist, dass das nf-core-Projekt Werkzeuge enthält, die diesen Teil einfach machen. +Speziell der `nf-core modules install`-Befehl ermöglicht es, das Abrufen des Codes und das Verfügbarmachen für dein Projekt in einem einzigen Schritt zu automatisieren. + +Navigiere zu deinem Pipeline-Verzeichnis und führe den Installationsbefehl aus: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +Das Tool wird dich möglicherweise zuerst auffordern, einen Repository-Typ anzugeben. +(Falls nicht, springe zu "Schließlich wird das Tool mit der Installation des Moduls fortfahren.") + +??? success "Befehlsausgabe" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Falls ja, drücke Enter, um die Standardantwort (`Pipeline`) zu akzeptieren und fortzufahren. + +Das Tool wird dann anbieten, die Konfiguration deines Projekts zu ändern, um diese Aufforderung in Zukunft zu vermeiden. + +??? success "Befehlsausgabe" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +Warum nicht diese praktische Automatisierung nutzen! +Drücke Enter, um die Standardantwort (ja) zu akzeptieren. + +Schließlich wird das Tool mit der Installation des Moduls fortfahren. + +??? success "Befehlsausgabe" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Der Befehl erledigt automatisch: + +- Herunterladen der Moduldateien nach `modules/nf-core/cat/cat/` +- Aktualisierung der `modules.json`, um das installierte Modul zu verfolgen +- Bereitstellung der korrekten `include`-Anweisung zur Verwendung im Workflow + +!!! tip + + Stelle immer sicher, dass dein aktuelles Arbeitsverzeichnis das Wurzelverzeichnis deines Pipeline-Projekts ist, bevor du den Modulinstallationsbefehl ausführst. + +Lass uns überprüfen, ob das Modul korrekt installiert wurde: + +```bash +tree -L 4 modules +``` + +??? abstract "Verzeichnisinhalt" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +Du kannst die Installation auch überprüfen, indem du das nf-core-Dienstprogramm bittest, lokal installierte Module aufzulisten: + +```bash +nf-core modules list local +``` + +??? success "Befehlsausgabe" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Dies bestätigt, dass das `cat/cat`-Modul nun Teil des Quellcodes deines Projekts ist. + +Um das neue Modul jedoch tatsächlich zu verwenden, müssen wir es in unsere Pipeline importieren. + +### 1.5. Die Modulimporte aktualisieren + +Lass uns die `include`-Anweisung für das `collectGreetings`-Modul durch die für `CAT_CAT` im Importbereich des `workflows/hello.nf` Workflows ersetzen. + +Zur Erinnerung, das Modulinstallationstool hat uns die exakte Anweisung gegeben, die wir verwenden sollen: + +```groovy title="Import-Anweisung, die vom Installationsbefehl erzeugt wurde" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Beachte, dass die nf-core-Konvention darin besteht, Großbuchstaben für Modulnamen beim Importieren zu verwenden. + +Öffne [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) und nimm folgende Ersetzung vor: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Beachte, wie sich der Pfad für das nf-core-Modul von den lokalen Modulen unterscheidet: + +- **nf-core-Modul**: `'../modules/nf-core/cat/cat/main'` (verweist auf `main.nf`) +- **Lokales Modul**: `'../modules/local/collectGreetings.nf'` (einzelne Dateireferenz) + +Das Modul ist jetzt für den Workflow verfügbar, also müssen wir nur noch den Aufruf von `collectGreetings` durch `CAT_CAT` ersetzen. Richtig? + +Nicht so schnell. + +An diesem Punkt könntest du versucht sein, direkt einzusteigen und Code zu bearbeiten, aber es lohnt sich, einen Moment innezuhalten und sorgfältig zu prüfen, was das neue Modul erwartet und was es produziert. + +Wir werden das als separaten Abschnitt behandeln, weil es einen neuen Mechanismus beinhaltet, den wir noch nicht behandelt haben: Metadaten-Maps. + +!!! note + + Du kannst optional die Datei `collectGreetings.nf` löschen: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Du möchtest sie jedoch vielleicht als Referenz behalten, um die Unterschiede zwischen lokalen und nf-core-Modulen zu verstehen. + +### Zusammenfassung + +Du weißt jetzt, wie du ein nf-core-Modul findest und es für dein Projekt verfügbar machst. + +### Wie geht's weiter? + +Bewerte, was ein neues Modul benötigt, und identifiziere wichtige Änderungen, die nötig sind, um es in eine Pipeline zu integrieren. + +--- + +## 2. Die Anforderungen des neuen Moduls bewerten + +Konkret müssen wir die **Schnittstelle** des Moduls untersuchen, d.h. seine Eingabe- und Ausgabedefinitionen, und sie mit der Schnittstelle des Moduls vergleichen, das wir ersetzen möchten. +Dadurch können wir feststellen, ob wir das neue Modul einfach als direkten Ersatz behandeln können oder ob wir einige Anpassungen in der Verkabelung vornehmen müssen. + +Idealerweise solltest du das tun, _bevor_ du das Modul überhaupt installierst, aber hey, besser spät als nie. +(Übrigens gibt es einen `uninstall`-Befehl, um Module loszuwerden, die du nicht mehr möchtest.) + +!!! note + + Der CAT_CAT-Prozess enthält eine ziemlich clevere Handhabung verschiedener Komprimierungstypen, Dateierweiterungen usw., die für das, was wir dir hier zeigen wollen, nicht streng relevant sind, daher werden wir das meiste davon ignorieren und uns nur auf die wichtigen Teile konzentrieren. + +### 2.1. Die Schnittstellen der beiden Module vergleichen + +Zur Erinnerung, so sieht die Schnittstelle zu unserem `collectGreetings`-Modul aus: + +```groovy title="modules/local/collectGreetings.nf (Auszug)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +Das `collectGreetings`-Modul nimmt zwei Eingaben entgegen: + +- `input_files` enthält eine oder mehrere Eingabedateien zur Verarbeitung; +- `batch_name` ist ein Wert, den wir verwenden, um der Ausgabedatei einen ausführungsspezifischen Namen zuzuweisen, was eine Form von Metadaten darstellt. + +Nach Abschluss gibt `collectGreetings` einen einzelnen Dateipfad aus, der mit dem Tag `outfile` ausgegeben wird. + +Im Vergleich dazu ist die Schnittstelle des `cat/cat`-Moduls komplexer: + +```groovy title="modules/nf-core/cat/cat/main.nf (Auszug)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +Das CAT_CAT-Modul nimmt eine einzelne Eingabe entgegen, aber diese Eingabe ist ein Tupel, das zwei Dinge enthält: + +- `meta` ist eine Struktur, die Metadaten enthält, genannt Metamap; +- `files_in` enthält eine oder mehrere Eingabedateien zur Verarbeitung, entsprechend `collectGreetings`' `input_files`. + +Nach Abschluss liefert CAT_CAT seine Ausgaben in zwei Teilen: + +- Ein weiteres Tupel, das die Metamap und die verkettete Ausgabedatei enthält, ausgegeben mit dem Tag `file_out`; +- Eine `versions.yml`-Datei, die Informationen über die verwendete Softwareversion erfasst, ausgegeben mit dem Tag `versions`. + +Beachte auch, dass die Ausgabedatei standardmäßig basierend auf einem Identifikator benannt wird, der Teil der Metadaten ist (Code hier nicht gezeigt). + +Das mag wie viel erscheinen, wenn man nur den Code betrachtet, daher hier ein Diagramm, das dir hilft zu visualisieren, wie alles zusammenpasst. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Du kannst sehen, dass die beiden Module ähnliche Eingabeanforderungen in Bezug auf den Inhalt haben (eine Menge von Eingabedateien plus einige Metadaten), aber sehr unterschiedliche Erwartungen dafür, wie dieser Inhalt verpackt ist. +Wenn wir die Versionsdatei vorerst ignorieren, ist auch ihre Hauptausgabe gleichwertig (eine verkettete Datei), außer dass CAT_CAT auch die Metamap zusammen mit der Ausgabedatei ausgibt. + +Die Verpackungsunterschiede werden relativ einfach zu handhaben sein, wie du gleich sehen wirst. +Um den Metamap-Teil zu verstehen, müssen wir dir jedoch zusätzlichen Kontext geben. + +### 2.2. Metamaps verstehen + +Wir haben dir gerade gesagt, dass das CAT_CAT-Modul eine Metadaten-Map als Teil seines Eingabe-Tupels erwartet. +Lass uns ein paar Minuten nehmen, um genauer zu betrachten, was das ist. + +Die **Metadaten-Map**, oft kurz als **Metamap** bezeichnet, ist eine Map im Groovy-Stil, die Informationen über Dateneinheiten enthält. +Im Kontext von Nextflow-Pipelines können Dateneinheiten alles sein, was du möchtest: einzelne Proben, Chargen von Proben oder ganze Datensätze. + +Per Konvention wird eine nf-core-Metamap `meta` genannt und enthält das erforderliche Feld `id`, das zum Benennen von Ausgaben und Verfolgen von Dateneinheiten verwendet wird. + +Zum Beispiel könnte eine typische Metadaten-Map so aussehen: + +```groovy title="Beispiel einer Metamap auf Probenebene" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +Oder in einem Fall, in dem die Metadaten auf Chargenebene angehängt sind: + +```groovy title="Beispiel einer Metamap auf Chargenebene" +[id: 'batch1', date: '25.10.01'] +``` + +Lass uns das nun in den Kontext des `CAT_CAT`-Prozesses setzen, der erwartet, dass die Eingabedateien in ein Tupel mit einer Metamap verpackt sind, und die Metamap auch als Teil des Ausgabe-Tupels ausgibt. + +```groovy title="modules/nf-core/cat/cat/main.nf (Auszug)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +Dadurch durchläuft jede Dateneinheit die Pipeline mit den relevanten Metadaten versehen. +Nachfolgende Prozesse können dann auch problemlos auf diese Metadaten zugreifen. + +Erinnerst du dich daran, dass wir dir gesagt haben, dass die von `CAT_CAT` ausgegebene Datei basierend auf einem Identifikator benannt wird, der Teil der Metadaten ist? +Das ist der relevante Code: + +```groovy title="modules/nf-core/cat/cat/main.nf (Auszug)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Das bedeutet ungefähr Folgendes: Wenn ein `prefix` über das externe Task-Parametersystem (`task.ext`) bereitgestellt wird, verwende diesen, um die Ausgabedatei zu benennen; andernfalls erstelle einen mit `${meta.id}`, was dem `id`-Feld in der Metamap entspricht. + +Du kannst dir den eingehenden Eingabekanal in dieses Modul mit Inhalten wie diesem vorstellen: + +```groovy title="Beispiel für Eingabekanal-Inhalte" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Dann kommen die Ausgabekanal-Inhalte so heraus: + +```groovy title="Beispiel für Ausgabekanal-Inhalte" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Wie bereits erwähnt, ist das `tuple val(meta), path(files_in)` Eingabe-Setup ein Standardmuster, das in allen nf-core-Modulen verwendet wird. + +Hoffentlich kannst du allmählich sehen, wie nützlich das sein kann. +Es ermöglicht dir nicht nur, Ausgaben basierend auf Metadaten zu benennen, sondern du kannst auch Dinge tun wie verschiedene Parameterwerte anzuwenden, und in Kombination mit bestimmten Operatoren kannst du sogar Daten gruppieren, sortieren oder herausfiltern, während sie durch die Pipeline fließen. + +!!! note "Mehr über Metadaten erfahren" + + Für eine umfassende Einführung in die Arbeit mit Metadaten in Nextflow-Workflows, einschließlich wie man Metadaten aus Samplesheets liest und sie zur Anpassung der Verarbeitung verwendet, siehe die Side Quest [Metadaten in Workflows](../side_quests/metadata). + +### 2.3. Vorzunehmende Änderungen zusammenfassen + +Basierend auf dem, was wir überprüft haben, sind dies die wichtigsten Änderungen, die wir an unserer Pipeline vornehmen müssen, um das `cat/cat`-Modul zu nutzen: + +- Eine Metamap erstellen, die den Chargennamen enthält; +- Die Metamap in ein Tupel mit der Menge der zu verkettenden Eingabedateien verpacken (kommend aus `convertToUpper`); +- Den Aufruf von `collectGreetings()` zu `CAT_CAT` ändern; +- Die Ausgabedatei aus dem vom `CAT_CAT`-Prozess produzierten Tupel extrahieren, bevor sie an `cowpy` übergeben wird. + +Das sollte reichen! Jetzt, da wir einen Plan haben, sind wir bereit loszulegen. + +### Zusammenfassung + +Du weißt jetzt, wie du die Eingabe- und Ausgabeschnittstelle eines neuen Moduls bewertest, um seine Anforderungen zu identifizieren, und du hast gelernt, wie Metamaps von nf-core-Pipelines verwendet werden, um Metadaten eng mit den Daten verbunden zu halten, während sie durch eine Pipeline fließen. + +### Wie geht's weiter? + +Das neue Modul in einen Workflow integrieren. + +--- + +## 3. CAT_CAT in den `hello.nf` Workflow integrieren + +Jetzt, da du alles über Metamaps weißt (oder zumindest genug für die Zwecke dieses Kurses), ist es an der Zeit, die oben skizzierten Änderungen tatsächlich zu implementieren. + +Der Klarheit halber werden wir dies aufschlüsseln und jeden Schritt separat behandeln. + +!!! note + + Alle unten gezeigten Änderungen werden an der Workflow-Logik im `main`-Block in der `core-hello/workflows/hello.nf` Workflow-Datei vorgenommen. + +### 3.1. Eine Metadaten-Map erstellen + +Zuerst müssen wir eine Metadaten-Map für `CAT_CAT` erstellen, wobei wir bedenken, dass nf-core-Module mindestens ein `id`-Feld in der Metamap benötigen. + +Da wir keine anderen Metadaten benötigen, können wir es einfach halten und so etwas verwenden: + +```groovy title="Syntaxbeispiel" +def cat_meta = [id: 'test'] +``` + +Außer dass wir den `id`-Wert nicht fest codieren wollen; wir wollen den Wert des `params.batch`-Parameters verwenden. +Der Code wird also: + +```groovy title="Syntaxbeispiel" +def cat_meta = [id: params.batch] +``` + +Ja, es ist buchstäblich so einfach, eine grundlegende Metamap zu erstellen. + +Lass uns diese Zeilen nach dem `convertToUpper`-Aufruf hinzufügen und den `collectGreetings`-Aufruf entfernen: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Dies erstellt eine einfache Metadaten-Map, bei der die `id` auf unseren Chargennamen gesetzt ist (was bei Verwendung des Testprofils `test` sein wird). + +### 3.2. Einen Kanal mit Metadaten-Tupeln erstellen + +Als Nächstes transformieren wir den Kanal von Dateien in einen Kanal von Tupeln, die Metadaten und Dateien enthalten: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // Kanal mit Metadaten und Dateien im Tupel-Format erstellen + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Die Zeile, die wir hinzugefügt haben, erreicht zwei Dinge: + +- `.collect()` sammelt alle Dateien aus der `convertToUpper`-Ausgabe in eine einzelne Liste +- `.map { files -> tuple(cat_meta, files) }` erstellt ein Tupel `[metadata, files]` im Format, das `CAT_CAT` erwartet + +Das ist alles, was wir tun müssen, um das Eingabe-Tupel für `CAT_CAT` einzurichten. + +### 3.3. Das CAT_CAT-Modul aufrufen + +Rufe nun `CAT_CAT` auf dem neu erstellten Kanal auf: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // Kanal mit Metadaten und Dateien im Tupel-Format erstellen + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // Dateien mit dem nf-core cat/cat-Modul verketten + CAT_CAT(ch_for_cat) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // Kanal mit Metadaten und Dateien im Tupel-Format erstellen + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Dies vervollständigt den kniffligsten Teil dieser Ersetzung, aber wir sind noch nicht ganz fertig: wir müssen noch aktualisieren, wie wir die verkettete Ausgabe an den `cowpy`-Prozess übergeben. + +### 3.4. Die Ausgabedatei aus dem Tupel für `cowpy` extrahieren + +Zuvor hat der `collectGreetings`-Prozess einfach eine Datei produziert, die wir direkt an `cowpy` übergeben konnten. +Der `CAT_CAT`-Prozess produziert jedoch ein Tupel, das zusätzlich zur Ausgabedatei die Metamap enthält. + +Da `cowpy` noch keine Metadaten-Tupel akzeptiert (das werden wir im nächsten Teil des Kurses beheben), müssen wir die Ausgabedatei aus dem von `CAT_CAT` produzierten Tupel extrahieren, bevor wir sie an `cowpy` übergeben: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // Kanal mit Metadaten und Dateien im Tupel-Format erstellen + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // Die Begrüßungen verketten + CAT_CAT(ch_for_cat) + + // Datei aus dem Tupel extrahieren, da cowpy noch keine Metadaten verwendet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // Eine Begrüßung ausgeben + sayHello(ch_samplesheet) + + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + + // Metadaten-Map mit Chargennamen als ID erstellen + def cat_meta = [ id: params.batch ] + + // Kanal mit Metadaten und Dateien im Tupel-Format erstellen + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // Die Begrüßungen verketten + CAT_CAT(ch_for_cat) + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Die `.map{ meta, file -> file }`-Operation extrahiert die Datei aus dem `[metadata, file]`-Tupel, das von `CAT_CAT` produziert wurde, in einen neuen Kanal, `ch_for_cowpy`. + +Dann ist es nur noch eine Sache, `ch_for_cowpy` anstelle von `collectGreetings.out.outfile` in dieser letzten Zeile an `cowpy` zu übergeben. + +!!! note + + Im nächsten Teil des Kurses werden wir `cowpy` aktualisieren, damit es direkt mit Metadaten-Tupeln funktioniert, sodass dieser Extraktionsschritt nicht mehr notwendig sein wird. + +### 3.5. Den Workflow testen + +Lass uns testen, ob der Workflow mit dem neu integrierten `cat/cat`-Modul funktioniert: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Dies sollte relativ schnell laufen. + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Beachte, dass `CAT_CAT` jetzt in der Liste der Prozessausführungen anstelle von `collectGreetings` erscheint. + +Und das war's! Wir verwenden jetzt ein robustes, von der Community kuratiertes Modul anstelle von eigenem Prototyp-Code für diesen Schritt in der Pipeline. + +### Zusammenfassung + +Du weißt jetzt, wie du: + +- nf-core-Module findest und installierst +- Die Anforderungen eines nf-core-Moduls bewertest +- Eine einfache Metadaten-Map zur Verwendung mit einem nf-core-Modul erstellst +- Ein nf-core-Modul in deinen Workflow integrierst + +### Wie geht's weiter? + +Lerne, deine lokalen Module anzupassen, um nf-core-Konventionen zu folgen. +Wir zeigen dir auch, wie du neue nf-core-Module aus einer Vorlage mit den nf-core-Werkzeugen erstellst. diff --git a/docs/de/docs/hello_nf-core/04_make_module.md b/docs/de/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..cbf1ea0082 --- /dev/null +++ b/docs/de/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1088 @@ +# Teil 4: Ein nf-core-Modul erstellen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem vierten Teil des Hello nf-core Trainingskurses zeigen wir dir, wie du ein nf-core-Modul erstellst, indem du die wichtigsten Konventionen anwendest, die Module portabel und wartbar machen. + +Das nf-core-Projekt stellt einen Befehl (`nf-core modules create`) bereit, der automatisch korrekt strukturierte Modulvorlagen generiert, ähnlich wie bei dem, was wir für den Workflow in Teil 2 verwendet haben. +Zu Lehrzwecken werden wir jedoch damit beginnen, es manuell zu machen: Wir transformieren das lokale `cowpy`-Modul in deiner `core-hello`-Pipeline Schritt für Schritt in ein Modul im nf-core-Stil. +Danach zeigen wir dir, wie du die vorlagenbasierte Modulerstellung nutzt, um in Zukunft effizienter zu arbeiten. + +??? info "Wie du von diesem Abschnitt aus beginnst" + + Dieser Abschnitt setzt voraus, dass du [Teil 3: Ein nf-core-Modul verwenden](./03_use_module.md) abgeschlossen hast und das `CAT_CAT`-Modul in deine Pipeline integriert hast. + + Wenn du Teil 3 nicht abgeschlossen hast oder für diesen Teil neu beginnen möchtest, kannst du die Lösung `core-hello-part3` als Ausgangspunkt verwenden. + Führe diese Befehle im Verzeichnis `hello-nf-core/` aus: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Dies gibt dir eine Pipeline mit dem bereits integrierten `CAT_CAT`-Modul. + Du kannst testen, ob sie erfolgreich läuft, indem du den folgenden Befehl ausführst: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. `cowpy` in ein nf-core-Modul transformieren + +In diesem Abschnitt wenden wir nf-core-Konventionen auf das lokale `cowpy`-Modul in deiner `core-hello`-Pipeline an und transformieren es in ein Modul, das den Community-Standards von nf-core folgt. + +Dies ist der aktuelle Code für das `cowpy`-Prozessmodul: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Wir werden die folgenden nf-core-Konventionen schrittweise anwenden: + +1. **Den Prozessnamen zu `COWPY` in Großbuchstaben ändern**, um der Konvention zu folgen. +2. **`COWPY` aktualisieren, um Metadaten-Tupel zu verwenden**, um Probenmetadaten durch den Workflow zu propagieren. +3. **Tool-Argument-Konfiguration mit `ext.args` zentralisieren**, um die Vielseitigkeit des Moduls zu erhöhen und gleichzeitig die Schnittstelle minimal zu halten. +4. **Ausgabe-Benennung mit `ext.prefix` standardisieren**, um Konsistenz zu fördern. +5. **Die Publishing-Konfiguration zentralisieren**, um Konsistenz zu fördern. + +Nach jedem Schritt führen wir die Pipeline aus, um zu testen, dass alles wie erwartet funktioniert. + +!!! warning "Arbeitsverzeichnis" + + Stelle sicher, dass du dich im Verzeichnis `core-hello` (dein Pipeline-Stammverzeichnis) befindest, für alle Dateibearbeitungen und Befehlsausführungen in diesem Abschnitt. + + ```bash + cd core-hello + ``` + +### 1.1. Den Prozessnamen in Großbuchstaben ändern + +Dies ist rein eine stilistische Konvention (es gibt keine technische Rechtfertigung), aber da es die Norm für nf-core-Module ist, sollten wir uns daran halten. + +Wir müssen drei Änderungssets vornehmen: + +1. Den Prozessnamen im Modul aktualisieren +2. Die Modul-Import-Anweisung im Workflow-Header aktualisieren +3. Den Prozessaufruf und die Emit-Deklaration im Workflow-Body aktualisieren + +Los geht's! + +#### 1.1.1. Den Prozessnamen im Modul aktualisieren + +Öffne die Moduldatei `cowpy.nf` (unter `core-hello/modules/local/`) und ändere den Prozessnamen in Großbuchstaben: + +=== "Nachher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Vorher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +In diesem Fall ist die Großschreibung völlig unkompliziert. + +Wenn der Prozessname aus mehreren Wörtern bestünde, zum Beispiel wenn wir einen Prozess namens MyCowpyTool ursprünglich in CamelCase hätten, wäre die nf-core-Konvention, Unterstriche zu verwenden, um sie zu trennen, was MY_COWPY_TOOL ergäbe. + +#### 1.1.2. Die Modul-Import-Anweisung aktualisieren + +Prozessnamen sind case-sensitiv, daher müssen wir, nachdem wir den Prozessnamen geändert haben, die Modul-Import-Anweisung entsprechend im Workflow-Header von `hello.nf` aktualisieren: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Wir könnten einen Alias in der Import-Anweisung verwenden, um zu vermeiden, dass wir Aufrufe des Prozesses aktualisieren müssen, aber das würde den Sinn der Übernahme der Großbuchstaben-Konvention etwas verfehlen. + +#### 1.1.3. Den Prozessaufruf und die Emit-Deklaration aktualisieren + +Also aktualisieren wir jetzt die beiden Referenzen auf den Prozess im Workflow-Block von `hello.nf`: + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // ASCII-Kunst der Begrüßungen mit cowpy generieren + COWPY(CAT_CAT.out.file_out) + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(CAT_CAT.out.file_out) + + // + // Software-Versionen sammeln und speichern + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Stelle sicher, dass du **beide** Änderungen vornimmst, sonst erhältst du einen Fehler, wenn du dies ausführst. + +#### 1.1.4. Die Pipeline ausführen, um sie zu testen + +Lass uns den Workflow ausführen, um zu testen, dass nach diesen Änderungen alles korrekt funktioniert. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Gut, das funktioniert! Lass uns nun zu substanzielleren Änderungen übergehen. + +### 1.2. `COWPY` aktualisieren, um Metadaten-Tupel zu verwenden + +In der aktuellen Version der `core-hello`-Pipeline extrahieren wir die Datei aus dem Ausgabe-Tupel von `CAT_CAT`, um sie an `COWPY` zu übergeben, wie in der oberen Hälfte des Diagramms unten gezeigt. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Es wäre besser, wenn `COWPY` Metadaten-Tupel direkt akzeptieren würde, sodass Metadaten durch den Workflow fließen können, wie in der unteren Hälfte des Diagramms gezeigt. + +Zu diesem Zweck müssen wir die folgenden Änderungen vornehmen: + +1. Die Eingabe- und Ausgabedefinitionen aktualisieren +2. Den Prozessaufruf im Workflow aktualisieren +3. Den Emit-Block im Workflow aktualisieren + +Nachdem wir all das getan haben, führen wir die Pipeline aus, um zu testen, dass alles noch wie zuvor funktioniert. + +#### 1.2.1. Die Eingabe- und Ausgabedefinitionen aktualisieren + +Kehre zur Moduldatei `cowpy.nf` zurück und ändere sie so, dass sie Metadaten-Tupel akzeptiert, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Vorher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Wie du sehen kannst, haben wir sowohl die **Haupteingabe** als auch die **Ausgabe** in ein Tupel geändert, das dem Muster `tuple val(meta), path(input_file)` folgt, das in Teil 3 dieses Trainings eingeführt wurde. +Für die Ausgabe haben wir auch diese Gelegenheit genutzt, um `emit: cowpy_output` hinzuzufügen, um dem Ausgabekanal einen beschreibenden Namen zu geben. + +Jetzt, da wir geändert haben, was der Prozess erwartet, müssen wir aktualisieren, was wir ihm im Prozessaufruf bereitstellen. + +#### 1.2.2. Den Prozessaufruf im Workflow aktualisieren + +Die gute Nachricht ist, dass diese Änderung den Prozessaufruf vereinfachen wird. +Da die Ausgabe von `CAT_CAT` und die Eingabe von `COWPY` jetzt die gleiche 'Form' haben, d.h. beide aus einer `tuple val(meta), path(input_file)`-Struktur bestehen, können wir sie einfach direkt verbinden, anstatt die Datei explizit aus der Ausgabe des `CAT_CAT`-Prozesses extrahieren zu müssen. + +Öffne die Workflow-Datei `hello.nf` (unter `core-hello/workflows/`) und aktualisiere den Aufruf von `COWPY` wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // ASCII-Kunst der Begrüßungen mit cowpy generieren + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // Die Datei aus dem Tupel extrahieren, da cowpy noch keine Metadaten verwendet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // ASCII-Kunst der Begrüßungen mit cowpy generieren + COWPY(ch_for_cowpy, params.character) + ``` + +Wir rufen jetzt `COWPY` direkt mit `CAT_CAT.out.file_out` auf. + +Dadurch müssen wir den `ch_for_cowpy`-Kanal nicht mehr konstruieren, sodass diese Zeile (und ihre Kommentarzeile) vollständig gelöscht werden kann. + +#### 1.2.3. Den Emit-Block im Workflow aktualisieren + +Da `COWPY` jetzt eine benannte Ausgabe, `cowpy_output`, ausgibt, können wir den `emit:`-Block des `hello.nf`-Workflows aktualisieren, um diese zu verwenden. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Dies ist technisch nicht erforderlich, aber es ist gute Praxis, auf benannte Ausgaben zu verweisen, wann immer möglich. + +#### 1.2.4. Die Pipeline ausführen, um sie zu testen + +Lass uns den Workflow ausführen, um zu testen, dass nach diesen Änderungen alles korrekt funktioniert. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Die Pipeline sollte erfolgreich laufen, wobei Metadaten nun von `CAT_CAT` durch `COWPY` fließen. + +Damit ist abgeschlossen, was wir tun mussten, um `COWPY` Metadaten-Tupel verarbeiten zu lassen. +Schauen wir uns nun an, was wir sonst noch tun können, um die nf-core-Modulmuster zu nutzen. + +### 1.3. Tool-Argument-Konfiguration mit `ext.args` zentralisieren + +In seinem aktuellen Zustand erwartet der `COWPY`-Prozess, einen Wert für den `character`-Parameter zu erhalten. +Daher müssen wir jedes Mal, wenn wir den Prozess aufrufen, einen Wert angeben, auch wenn wir mit den vom Tool gesetzten Standardwerten zufrieden wären. +Für `COWPY` ist dies zugegebenermaßen kein großes Problem, aber für Tools mit vielen optionalen Parametern kann es ziemlich umständlich werden. + +Das nf-core-Projekt empfiehlt die Verwendung einer Nextflow-Funktion namens [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext), um Tool-Argumente bequemer über Konfigurationsdateien zu verwalten. + +Anstatt Prozesseingaben für jede Tool-Option zu deklarieren, schreibst du das Modul so, dass es `ext.args` bei der Konstruktion seiner Befehlszeile referenziert. +Dann ist es nur noch eine Frage der Einrichtung der `ext.args`-Variable, um die Argumente und Werte zu halten, die du in der Datei `modules.config` verwenden möchtest, die Konfigurationsdetails für alle Module konsolidiert. +Nextflow fügt diese Argumente mit ihren Werten zur Laufzeit in die Tool-Befehlszeile ein. + +Lass uns diesen Ansatz auf das `COWPY`-Modul anwenden. +Wir müssen die folgenden Änderungen vornehmen: + +1. Das `COWPY`-Modul aktualisieren +2. `ext.args` in der Datei `modules.config` konfigurieren +3. Den `hello.nf`-Workflow aktualisieren + +Nachdem wir all das getan haben, führen wir die Pipeline aus, um zu testen, dass alles noch wie zuvor funktioniert. + +#### 1.3.1. Das `COWPY`-Modul aktualisieren + +Lass es uns tun. +Öffne die Moduldatei `cowpy.nf` (unter `core-hello/modules/local/`) und ändere sie so, dass sie auf `ext.args` verweist, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Du kannst sehen, dass wir drei Änderungen vorgenommen haben. + +1. **Im `input:`-Block haben wir die Eingabe `val character` entfernt.** + Von nun an werden wir dieses Argument über die `ext.args`-Konfiguration bereitstellen, wie weiter unten beschrieben. + +2. **Im `script:`-Block haben wir die Zeile `def args = task.ext.args ?: ''` hinzugefügt.** + Diese Zeile verwendet den `?:`-Operator, um den Wert der `args`-Variable zu bestimmen: den Inhalt von `task.ext.args`, wenn er nicht leer ist, oder eine leere Zeichenkette, wenn er es ist. + Beachte, dass wir zwar allgemein auf `ext.args` verweisen, dieser Code jedoch `task.ext.args` referenzieren muss, um die `ext.args`-Konfiguration auf Modulebene herauszuziehen. + +3. **In der Befehlszeile haben wir `-c "$character"` durch `$args` ersetzt.** + Hier fügt Nextflow alle Tool-Argumente ein, die in `ext.args` in der Datei `modules.config` gesetzt sind. + +Dadurch ist die Modulschnittstelle jetzt einfacher: Sie erwartet nur die wesentlichen Metadaten- und Dateieingaben. + +!!! note + + Der `?:`-Operator wird oft 'Elvis-Operator' genannt, weil er wie ein seitwärts gedrehtes Elvis-Presley-Gesicht aussieht, wobei das `?`-Zeichen die Welle in seinen Haaren symbolisiert. + +#### 1.3.2. `ext.args` in der Datei `modules.config` konfigurieren + +Nachdem wir die `character`-Deklaration aus dem Modul entfernt haben, müssen wir sie zu `ext.args` in der Konfigurationsdatei `modules.config` hinzufügen. + +Konkret werden wir dieses kleine Code-Stück zum `process {}`-Block hinzufügen: + +```groovy title="Hinzuzufügender Code" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +Die `withName:`-Syntax weist diese Konfiguration nur dem `COWPY`-Prozess zu, und `ext.args = { "-c ${params.character}" }` komponiert einfach eine Zeichenkette, die den Wert des `character`-Parameters enthält. +Beachte die Verwendung der geschweiften Klammern, die Nextflow anweisen, den Wert des Parameters zur Laufzeit zu evaluieren. + +Macht das Sinn? Lass es uns hinzufügen. + +Öffne `conf/modules.config` und füge den Konfigurationscode innerhalb des `process {}`-Blocks hinzu, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Hoffentlich kannst du dir vorstellen, dass alle Module in einer Pipeline ihre `ext.args` in dieser Datei spezifiziert haben, mit den folgenden Vorteilen: + +- Die **Modulschnittstelle bleibt einfach** - Sie akzeptiert nur die wesentlichen Metadaten- und Dateieingaben +- Die **Pipeline stellt immer noch `params.character` bereit** - Endbenutzer können es weiterhin wie zuvor konfigurieren +- Das **Modul ist jetzt portabel** - Es kann in anderen Pipelines wiederverwendet werden, ohne einen bestimmten Parameternamen zu erwarten +- Die Konfiguration ist **zentralisiert** in `modules.config`, wodurch die Workflow-Logik sauber bleibt + +Indem wir die Datei `modules.config` als den Ort verwenden, an dem alle Pipelines die Konfiguration pro Modul zentralisieren, machen wir unsere Module über verschiedene Pipelines hinweg wiederverwendbarer. + +#### 1.3.3. Den `hello.nf`-Workflow aktualisieren + +Da das `COWPY`-Modul den `character`-Parameter nicht mehr als Eingabe benötigt, müssen wir den Workflow-Aufruf entsprechend aktualisieren. + +Öffne die Workflow-Datei `hello.nf` (unter `core-hello/workflows/`) und aktualisiere den Aufruf von `COWPY` wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // ASCII-Kunst der Begrüßungen mit cowpy generieren + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Vorher" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // ASCII-Kunst der Begrüßungen mit cowpy generieren + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +Der Workflow-Code ist jetzt sauberer: Wir müssen `params.character` nicht direkt an den Prozess übergeben. +Die Modulschnittstelle wird minimal gehalten, was sie portabler macht, während die Pipeline die explizite Option weiterhin über die Konfiguration bereitstellt. + +#### 1.3.4. Die Pipeline ausführen, um sie zu testen + +Lass uns testen, dass der Workflow immer noch wie erwartet funktioniert, indem wir einen anderen Charakter angeben, um zu überprüfen, dass die `ext.args`-Konfiguration funktioniert. + +Führe diesen Befehl mit `kosh` aus, einer der... rätselhafteren Optionen: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dies sollte wie zuvor erfolgreich laufen. + +Lass uns überprüfen, dass die `ext.args`-Konfiguration funktioniert hat, indem wir die Ausgabe überprüfen. +Finde die Ausgabe im Dateibrowser oder verwende den Aufgaben-Hash (der Teil `38/eb29ea` im obigen Beispiel), um die Ausgabedatei anzusehen: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Befehlsausgabe" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +Du solltest die ASCII-Art mit dem `kosh`-Charakter sehen, was bestätigt, dass die `ext.args`-Konfiguration funktioniert hat! + +??? info "(Optional) Die Befehlsdatei inspizieren" + + Wenn du genau sehen möchtest, wie die Konfiguration angewendet wurde, kannst du die `.command.sh`-Datei inspizieren: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Du wirst den `cowpy`-Befehl mit dem Argument `-c kosh` sehen: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Dies zeigt, dass die `.command.sh`-Datei basierend auf der `ext.args`-Konfiguration korrekt generiert wurde. + +Nimm dir einen Moment Zeit, um darüber nachzudenken, was wir hier erreicht haben. +Dieser Ansatz hält die Modulschnittstelle auf wesentliche Daten (Dateien, Metadaten und alle obligatorischen probenbezogenen Parameter) fokussiert, während Optionen, die das Verhalten des Tools steuern, separat über die Konfiguration gehandhabt werden. + +Dies mag für ein einfaches Tool wie `cowpy` unnötig erscheinen, aber es kann für Datenanalyse-Tools mit vielen optionalen Argumenten einen großen Unterschied machen. + +Zusammenfassung der Vorteile dieses Ansatzes: + +- **Saubere Schnittstelle**: Das Modul konzentriert sich auf wesentliche Dateneingaben (Metadaten und Dateien) +- **Flexibilität**: Benutzer können Tool-Argumente über die Konfiguration angeben, einschließlich probenspezifischer Werte +- **Konsistenz**: Alle nf-core-Module folgen diesem Muster +- **Portabilität**: Module können ohne fest codierte Tool-Optionen wiederverwendet werden +- **Keine Workflow-Änderungen**: Das Hinzufügen oder Ändern von Tool-Optionen erfordert keine Aktualisierung des Workflow-Codes + +!!! note + + Das `ext.args`-System hat leistungsstarke zusätzliche Funktionen, die hier nicht behandelt werden, einschließlich des dynamischen Wechselns von Argumentwerten basierend auf Metadaten. Siehe die [nf-core-Modulspezifikationen](https://nf-co.re/docs/guidelines/components/modules) für weitere Details. + +### 1.4. Ausgabe-Benennung mit `ext.prefix` standardisieren + +Nachdem wir dem `COWPY`-Prozess nun Zugriff auf die Metamap gegeben haben, können wir ein weiteres nützliches nf-core-Muster nutzen: die Benennung von Ausgabedateien basierend auf Metadaten. + +Hier werden wir eine Nextflow-Funktion namens `ext.prefix` verwenden, die es uns ermöglicht, die Benennung von Ausgabedateien über Module hinweg mit `meta.id` (der Kennung, die in der Metamap enthalten ist) zu standardisieren, während wir Module bei Bedarf weiterhin individuell konfigurieren können. + +Dies wird ähnlich sein wie das, was wir mit `ext.args` gemacht haben, mit ein paar Unterschieden, die wir im Laufe der Zeit detailliert erläutern werden. + +Lass uns diesen Ansatz auf das `COWPY`-Modul anwenden. +Wir müssen die folgenden Änderungen vornehmen: + +1. Das `COWPY`-Modul aktualisieren +2. `ext.prefix` in der Datei `modules.config` konfigurieren + +(Keine Änderungen am Workflow erforderlich.) + +Nachdem wir das getan haben, führen wir die Pipeline aus, um zu testen, dass alles noch wie zuvor funktioniert. + +#### 1.4.1. Das `COWPY`-Modul aktualisieren + +Öffne die Moduldatei `cowpy.nf` (unter `core-hello/modules/local/`) und ändere sie so, dass sie auf `ext.prefix` verweist, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Du kannst sehen, dass wir drei Änderungen vorgenommen haben. + +1. **Im `script:`-Block haben wir die Zeile `prefix = task.ext.prefix ?: "${meta.id}"` hinzugefügt.** + Diese Zeile verwendet den `?:`-Operator, um den Wert der `prefix`-Variable zu bestimmen: den Inhalt von `task.ext.prefix`, wenn er nicht leer ist, oder die Kennung aus der Metamap (`meta.id`), wenn er es ist. + Beachte, dass wir zwar allgemein auf `ext.prefix` verweisen, dieser Code jedoch `task.ext.prefix` referenzieren muss, um die `ext.prefix`-Konfiguration auf Modulebene herauszuziehen. + +2. **In der Befehlszeile haben wir `cowpy-${input_file}` durch `${prefix}.txt` ersetzt.** + Hier fügt Nextflow den durch die obige Zeile bestimmten Wert von `prefix` ein. + +3. **Im `output:`-Block haben wir `path("cowpy-${input_file}")` durch `path("${prefix}.txt")` ersetzt.** + Dies wiederholt einfach, wie der Dateipfad gemäß dem in der Befehlszeile Geschriebenen sein wird. + +Dadurch wird der Name der Ausgabedatei nun mit einem sinnvollen Standard (der Kennung aus der Metamap) kombiniert mit der entsprechenden Dateiformaterweiterung konstruiert. + +#### 1.4.2. `ext.prefix` in der Datei `modules.config` konfigurieren + +In diesem Fall ist der sinnvolle Standard nach unserem Geschmack nicht ausreichend ausdrucksstark; wir möchten ein benutzerdefiniertes Benennungsmuster verwenden, das den Tool-Namen enthält, `cowpy-<id>.txt`, wie wir es zuvor hatten. + +Wir tun dies, indem wir `ext.prefix` in `modules.config` konfigurieren, genau wie wir es für den `character`-Parameter mit `ext.args` getan haben, außer dass diesmal der Block `withName: 'COWPY' {}` bereits existiert und wir nur die folgende Zeile hinzufügen müssen: + +```groovy title="Hinzuzufügender Code" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Dies wird die gewünschte Zeichenkette komponieren. +Beachte, dass wir erneut geschweifte Klammern verwenden, diesmal um Nextflow anzuweisen, den Wert von `meta.id` zur Laufzeit zu evaluieren. + +Lass es uns hinzufügen. + +Öffne `conf/modules.config` und füge den Konfigurationscode innerhalb des `process {}`-Blocks hinzu, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Vorher" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Falls du dich fragst: Die `ext.prefix`-Closure hat Zugriff auf das richtige Stück Metadaten, weil die Konfiguration im Kontext der Prozessausführung ausgewertet wird, wo Metadaten verfügbar sind. + +#### 1.4.3. Die Pipeline ausführen, um sie zu testen + +Lass uns testen, dass der Workflow immer noch wie erwartet funktioniert. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Schaue dir die Ausgabe im Ergebnisverzeichnis an. +Du solltest die cowpy-Ausgabedatei mit der gleichen Benennung wie zuvor sehen: `cowpy-test.txt`, basierend auf dem Standard-Batch-Namen. + +??? abstract "Verzeichnisinhalt" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Ändere gerne die `ext.prefix`-Konfiguration in `conf/modules.config`, um dich zu überzeugen, dass du das Benennungsmuster ändern kannst, ohne Änderungen am Modul- oder Workflow-Code vornehmen zu müssen. + +Alternativ kannst du dies auch erneut mit einem anderen auf der Befehlszeile angegebenen `--batch`-Parameter ausführen, um dich zu überzeugen, dass dieser Teil weiterhin spontan anpassbar ist. + +Dies zeigt, wie `ext.prefix` es dir ermöglicht, deine bevorzugte Benennungskonvention beizubehalten und gleichzeitig die Modulschnittstelle flexibel zu halten. + +Zusammenfassung der Vorteile dieses Ansatzes: + +- **Standardisierte Benennung**: Ausgabedateien werden typischerweise mit Proben-IDs aus Metadaten benannt +- **Konfigurierbar**: Benutzer können die Standardbenennung bei Bedarf überschreiben +- **Konsistent**: Alle nf-core-Module folgen diesem Muster +- **Vorhersagbar**: Es ist einfach zu wissen, wie Ausgabedateien heißen werden + +Ziemlich gut, oder? +Nun, es gibt noch eine wichtige Änderung, die wir vornehmen müssen, um unser Modul an die nf-core-Richtlinien anzupassen. + +### 1.5. Die Publishing-Konfiguration zentralisieren + +Du hast vielleicht bemerkt, dass wir Ausgaben in zwei verschiedene Verzeichnisse veröffentlicht haben: + +- **`results`** — Das ursprüngliche Ausgabeverzeichnis, das wir von Anfang an für unsere lokalen Module verwendet haben, individuell mit per-Modul `publishDir`-Direktiven gesetzt; +- **`core-hello-results`** — Das Ausgabeverzeichnis, das mit `--outdir` auf der Befehlszeile gesetzt wurde, das die nf-core-Logs und die von `CAT_CAT` veröffentlichten Ergebnisse erhalten hat. + +Dies ist unordentlich und suboptimal; es wäre besser, einen Ort für alles zu haben. +Natürlich könnten wir in jedes unserer lokalen Module gehen und die `publishDir`-Direktive manuell aktualisieren, um das Verzeichnis `core-hello-results` zu verwenden, aber was ist beim nächsten Mal, wenn wir das Ausgabeverzeichnis ändern? + +Einzelne Module Publishing-Entscheidungen treffen zu lassen, ist eindeutig nicht der richtige Weg, insbesondere in einer Welt, in der dasselbe Modul in vielen verschiedenen Pipelines von Personen verwendet werden könnte, die unterschiedliche Bedürfnisse oder Präferenzen haben. +Wir möchten in der Lage sein, auf Ebene der Workflow-Konfiguration zu kontrollieren, wo Ausgaben veröffentlicht werden. + +"Hey", könntest du sagen, "`CAT_CAT` sendet seine Ausgaben an `--outdir`. Vielleicht sollten wir dessen `publishDir`-Direktive kopieren?" + +Ja, das ist eine großartige Idee. + +Außer dass es keine `publishDir`-Direktive hat. (Schau mal, sieh dir den Modulcode an.) + +Das liegt daran, dass nf-core-Pipelines die Kontrolle auf Workflow-Ebene zentralisieren, indem sie `publishDir` in `conf/modules.config` konfigurieren, anstatt in einzelnen Modulen. +Konkret deklariert die nf-core-Vorlage eine Standard-`publishDir`-Direktive (mit einer vordefinierten Verzeichnisstruktur), die für alle Module gilt, es sei denn, eine überschreibende Direktive wird bereitgestellt. + +Klingt das nicht großartig? Könnte es sein, dass wir, um diese Standarddirektive zu nutzen, nur die aktuelle `publishDir`-Direktive aus unseren lokalen Modulen entfernen müssen? + +Lass uns das bei `COWPY` ausprobieren, um zu sehen, was passiert, dann schauen wir uns den Code für die Standardkonfiguration an, um zu verstehen, wie sie funktioniert. + +Schließlich werden wir demonstrieren, wie man das Standardverhalten bei Bedarf überschreibt. + +#### 1.5.1. Die `publishDir`-Direktive aus `COWPY` entfernen + +Lass uns das tun. +Öffne die Moduldatei `cowpy.nf` (unter `core-hello/modules/local/`) und entferne die `publishDir`-Direktive, wie unten gezeigt. + +=== "Nachher" + + ```groovy title="core-hello/modules/local/cowpy.nf (Auszug)" linenums="1" + #!/usr/bin/env nextflow + + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Vorher" + + ```groovy title="core-hello/modules/local/cowpy.nf (Auszug)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // ASCII-Kunst mit cowpy generieren (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +Das war's! + +#### 1.5.2. Die Pipeline ausführen, um sie zu testen + +Lass uns sehen, was passiert, wenn wir die Pipeline jetzt ausführen. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Schaue dir dein aktuelles Arbeitsverzeichnis an. +Jetzt enthält `core-hello-results` auch die Ausgaben des `COWPY`-Moduls. + +??? abstract "Verzeichnisinhalt" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Du kannst sehen, dass Nextflow diese Hierarchie von Verzeichnissen basierend auf den Namen des Workflows und des Moduls erstellt hat. + +Der verantwortliche Code befindet sich in der Datei `conf/modules.config`. +Dies ist die Standard-`publishDir`-Konfiguration, die Teil der nf-core-Vorlage ist und für alle Prozesse gilt: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Dies mag kompliziert aussehen, also schauen wir uns jede der drei Komponenten an: + +- **`path:`** Bestimmt das Ausgabeverzeichnis basierend auf dem Prozessnamen. + Der vollständige Name eines in `task.process` enthaltenen Prozesses umfasst die Hierarchie von Workflow- und Modulimporten (wie `CORE_HELLO:HELLO:CAT_CAT`). + Die `tokenize`-Operationen entfernen diese Hierarchie, um nur den Prozessnamen zu erhalten, nehmen dann den ersten Teil vor einem Unterstrich (falls zutreffend) und konvertieren ihn in Kleinbuchstaben. + Dies bestimmt, dass die Ergebnisse von `CAT_CAT` nach `${params.outdir}/cat/` veröffentlicht werden. +- **`mode:`** Steuert, wie Dateien veröffentlicht werden (copy, symlink usw.). + Dies ist über den Parameter `params.publish_dir_mode` konfigurierbar. +- **`saveAs:`** Filtert, welche Dateien veröffentlicht werden sollen. + Dieses Beispiel schließt `versions.yml`-Dateien aus, indem es `null` für sie zurückgibt und verhindert, dass sie veröffentlicht werden. + +Dies bietet eine konsistente Logik zur Organisation von Ausgaben. + +Die Ausgabe sieht noch besser aus, wenn alle Module in einer Pipeline diese Konvention übernehmen, also lösche gerne die `publishDir`-Direktiven aus den anderen Modulen in deiner Pipeline. +Dieser Standard wird auch auf Module angewendet, die wir nicht explizit geändert haben, um den nf-core-Richtlinien zu folgen. + +Allerdings kannst du entscheiden, dass du deine Eingaben anders organisieren möchtest, und die gute Nachricht ist, dass dies einfach zu tun ist. + +#### 1.5.3. Den Standard überschreiben + +Um die Standard-`publishDir`-Direktive zu überschreiben, kannst du einfach deine eigenen Direktiven zur Datei `conf/modules.config` hinzufügen. + +Du könntest beispielsweise den Standard für einen einzelnen Prozess mit dem `withName:`-Selektor überschreiben, wie in diesem Beispiel, wo wir eine benutzerdefinierte `publishDir`-Direktive für den 'COWPY'-Prozess hinzufügen. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +Wir werden diese Änderung nicht tatsächlich vornehmen, aber spiele gerne damit herum und sieh, welche Logik du implementieren kannst. + +Der Punkt ist, dass dieses System dir das Beste aus beiden Welten gibt: Konsistenz standardmäßig und die Flexibilität, die Konfiguration bei Bedarf anzupassen. + +Zusammenfassend erhältst du: + +- **Single Source of Truth**: Alle Publishing-Konfigurationen befinden diff --git a/docs/de/docs/hello_nf-core/05_input_validation.md b/docs/de/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..ca99861ee0 --- /dev/null +++ b/docs/de/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Teil 5: Eingabevalidierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem fünften Teil des Hello nf-core Trainingskurses zeigen wir dir, wie du das nf-schema Plugin verwendest, um Pipeline-Eingaben und Parameter zu validieren. + +??? info "Wie du von diesem Abschnitt aus beginnen kannst" + + Dieser Abschnitt setzt voraus, dass du [Teil 4: Ein nf-core Modul erstellen](./04_make_module.md) abgeschlossen und das `COWPY` Prozessmodul auf nf-core Standards in deiner Pipeline aktualisiert hast. + + Falls du Teil 4 nicht abgeschlossen hast oder für diesen Teil neu beginnen möchtest, kannst du die `core-hello-part4` Lösung als Ausgangspunkt verwenden. + Führe diese Befehle innerhalb des `hello-nf-core/` Verzeichnisses aus: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Dies gibt dir eine Pipeline mit dem bereits auf nf-core Standards aktualisierten `COWPY` Modul. + Du kannst testen, ob es erfolgreich läuft, indem du folgenden Befehl ausführst: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Aufwärmen: Ein bisschen Hintergrund + +### 0.1. Warum Validierung wichtig ist + +Stell dir vor, du lässt deine Pipeline zwei Stunden laufen, nur damit sie abstürzt, weil ein Benutzer eine Datei mit der falschen Erweiterung angegeben hat. Oder du verbringst Stunden mit dem Debugging kryptischer Fehlermeldungen, nur um herauszufinden, dass ein Parameter falsch geschrieben wurde. Ohne Eingabevalidierung sind solche Szenarien häufig. + +Betrachte dieses Beispiel: + +```console title="Ohne Validierung" +$ nextflow run my-pipeline --input data.txt --output results + +...2 Stunden später... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +Die Pipeline hat ungültige Eingaben akzeptiert und lief stundenlang, bevor sie fehlschlug. Mit ordentlicher Validierung: + +```console title="Mit Validierung" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +Die Pipeline schlägt sofort mit klaren, umsetzbaren Fehlermeldungen fehl. Das spart Zeit, Rechenressourcen und Frustration. + +### 0.2. Das nf-schema Plugin + +Das [nf-schema Plugin](https://nextflow-io.github.io/nf-schema/latest/) ist ein Nextflow Plugin, das umfassende Validierungsfähigkeiten für Nextflow Pipelines bereitstellt. +Während nf-schema mit jedem Nextflow Workflow funktioniert, ist es die Standard-Validierungslösung für alle nf-core Pipelines. + +nf-schema bietet mehrere Hauptfunktionen: + +- **Parametervalidierung**: Validiert Pipeline-Parameter gegen `nextflow_schema.json` +- **Sample Sheet Validierung**: Validiert Eingabedateien gegen `assets/schema_input.json` +- **Channel-Konvertierung**: Konvertiert validierte Sample Sheets in Nextflow Channels +- **Hilfetext-Generierung**: Generiert automatisch `--help` Ausgabe aus Schema-Definitionen +- **Parameter-Zusammenfassung**: Zeigt an, welche Parameter von den Standardwerten abweichen + +nf-schema ist der Nachfolger des veralteten nf-validation Plugins und verwendet standard [JSON Schema Draft 2020-12](https://json-schema.org/) für die Validierung. + +??? info "Was sind Nextflow Plugins?" + + Plugins sind Erweiterungen, die der Nextflow Sprache selbst neue Funktionalität hinzufügen. Sie werden über einen `plugins{}` Block in `nextflow.config` installiert und können Folgendes bereitstellen: + + - Neue Funktionen und Klassen, die importiert werden können (wie `samplesheetToList`) + - Neue DSL-Features und Operatoren + - Integration mit externen Diensten + + Das nf-schema Plugin wird in `nextflow.config` spezifiziert: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Sobald es installiert ist, kannst du Funktionen aus Plugins mit der Syntax `include { functionName } from 'plugin/plugin-name'` importieren. + +### 0.3. Zwei Schema-Dateien für zwei Arten von Validierung + +Eine nf-core Pipeline verwendet zwei separate Schema-Dateien, die zwei Arten von Validierung entsprechen: + +| Schema-Datei | Zweck | Validiert | +| -------------------------- | ----------------------- | ------------------------------------------------------ | +| `nextflow_schema.json` | Parametervalidierung | Kommandozeilen-Flags: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Eingabedatenvalidierung | Inhalte von Sample Sheets und Eingabedateien | + +Beide Schemas verwenden das JSON Schema Format, ein weit verbreiteter Standard zur Beschreibung und Validierung von Datenstrukturen. + +**Parametervalidierung** validiert Kommandozeilenparameter (Flags wie `--outdir`, `--batch`, `--input`): + +- Prüft Parametertypen, Bereiche und Formate +- Stellt sicher, dass erforderliche Parameter angegeben sind +- Validiert, dass Dateipfade existieren +- Definiert in `nextflow_schema.json` + +**Eingabedatenvalidierung** validiert die Struktur von Sample Sheets und Manifest-Dateien (CSV/TSV-Dateien, die deine Daten beschreiben): + +- Prüft Spaltenstruktur und Datentypen +- Validiert, dass im Sample Sheet referenzierte Dateipfade existieren +- Stellt sicher, dass erforderliche Felder vorhanden sind +- Definiert in `assets/schema_input.json` + +!!! warning "Was Eingabedatenvalidierung NICHT tut" + + Eingabedatenvalidierung prüft die Struktur von *Manifest-Dateien* (Sample Sheets, CSV-Dateien), NICHT den Inhalt deiner eigentlichen Datendateien (FASTQ, BAM, VCF, etc.). + + Für große Datenmengen sollte die Validierung von Dateiinhalten (wie die Überprüfung der BAM-Integrität) in Pipeline-Prozessen erfolgen, die auf Worker-Knoten laufen, nicht während der Validierungsphase auf der orchestrierenden Maschine. + +### 0.4. Wann sollte Validierung stattfinden? + +```mermaid +graph LR + A[Benutzer führt Pipeline aus] --> B[Parametervalidierung] + B -->|✓ Gültig| C[Eingabedatenvalidierung] + B -->|✗ Ungültig| D[Fehler: Parameter korrigieren] + C -->|✓ Gültig| E[Pipeline wird ausgeführt] + C -->|✗ Ungültig| F[Fehler: Eingabedaten korrigieren] +``` + +Validierung sollte **bevor** irgendwelche Pipeline-Prozesse laufen stattfinden, um schnelles Feedback zu geben und verschwendete Rechenzeit zu verhindern. + +Lass uns nun diese Prinzipien in der Praxis anwenden, beginnend mit der Parametervalidierung. + +--- + +## 1. Parametervalidierung (nextflow_schema.json) + +Beginnen wir damit, Parametervalidierung zu unserer Pipeline hinzuzufügen. Dies validiert Kommandozeilen-Flags wie `--input`, `--outdir` und `--batch`. + +### 1.1. Validierung so konfigurieren, dass Eingabedatei-Validierung übersprungen wird + +Das nf-core Pipeline-Template kommt mit bereits installiertem und konfiguriertem nf-schema: + +- Das nf-schema Plugin wird über den `plugins{}` Block in `nextflow.config` installiert +- Parametervalidierung ist standardmäßig über `params.validate_params = true` aktiviert +- Die Validierung wird vom `UTILS_NFSCHEMA_PLUGIN` Subworkflow während der Pipeline-Initialisierung durchgeführt + +Das Validierungsverhalten wird über den `validation{}` Bereich in `nextflow.config` gesteuert. + +Da wir zuerst an der Parametervalidierung arbeiten (dieser Abschnitt) und das Eingabedaten-Schema erst in Abschnitt 2 konfigurieren werden, müssen wir nf-schema vorübergehend anweisen, die Validierung der Dateiinhalte des `input` Parameters zu überspringen. + +Öffne `nextflow.config` und finde den `validation` Block (um Zeile 246). Füge `ignoreParams` hinzu, um die Eingabedatei-Validierung zu überspringen: + +=== "Nachher" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Diese Konfiguration weist nf-schema an: + +- **`defaultIgnoreParams`**: Validierung komplexer Parameter wie `genomes` überspringen (von Template-Entwicklern festgelegt) +- **`ignoreParams`**: Validierung der Dateiinhalte des `input` Parameters überspringen (vorübergehend; wir werden dies in Abschnitt 2 wieder aktivieren) +- **`monochromeLogs`**: Farbige Ausgabe in Validierungsmeldungen deaktivieren, wenn auf `true` gesetzt (gesteuert durch `params.monochrome_logs`) + +!!! note "Warum den input Parameter ignorieren?" + + Der `input` Parameter in `nextflow_schema.json` hat `"schema": "assets/schema_input.json"`, was nf-schema anweist, die *Inhalte* der Eingabe-CSV-Datei gegen dieses Schema zu validieren. + Da wir dieses Schema noch nicht konfiguriert haben, ignorieren wir diese Validierung vorübergehend. + Wir werden diese Einstellung in Abschnitt 2 nach der Konfiguration des Eingabedaten-Schemas entfernen. + +### 1.2. Das Parameter-Schema untersuchen + +Schauen wir uns einen Abschnitt der `nextflow_schema.json` Datei an, die mit unserem Pipeline-Template kam: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +Das Parameter-Schema ist in Gruppen organisiert. Hier ist die `input_output_options` Gruppe: + +```json title="core-hello/nextflow_schema.json (Auszug)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Jede hier beschriebene Eingabe hat die folgenden Haupteigenschaften, die validiert werden können: + +- **`type`**: Datentyp (string, integer, boolean, number) +- **`format`**: Spezielle Formate wie `file-path` oder `directory-path` +- **`exists`**: Bei Dateipfaden prüfen, ob die Datei existiert +- **`pattern`**: Regulärer Ausdruck, dem der Wert entsprechen muss +- **`required`**: Array von Parameternamen, die angegeben werden müssen +- **`mimetype`**: Erwarteter Datei-Mimetype für die Validierung + +Wenn du ein scharfes Auge hast, bemerkst du vielleicht, dass der `batch` Eingabeparameter, den wir verwendet haben, noch nicht im Schema definiert ist. +Wir werden ihn im nächsten Abschnitt hinzufügen. + +??? info "Woher kommen Schema-Parameter?" + + Die Schema-Validierung verwendet `nextflow.config` als Basis für Parameterdefinitionen. + Parameter, die anderswo in deinen Workflow-Skripten deklariert sind (wie in `main.nf` oder Moduldateien), werden **nicht** automatisch vom Schema-Validator erfasst. + + Das bedeutet, du solltest deine Pipeline-Parameter immer in `nextflow.config` deklarieren und dann ihre Validierungsregeln in `nextflow_schema.json` definieren. + +### 1.3. Den batch Parameter hinzufügen + +Während das Schema eine JSON-Datei ist, die manuell bearbeitet werden kann, ist **manuelle Bearbeitung fehleranfällig und nicht empfohlen**. +Stattdessen bietet nf-core ein interaktives GUI-Tool, das die JSON Schema Syntax für dich handhabt und deine Änderungen validiert: + +```bash +nf-core pipelines schema build +``` + +Du solltest etwas Ähnliches sehen: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Tippe `y` und drücke Enter, um die interaktive Web-Oberfläche zu starten. + +Dein Browser öffnet sich und zeigt den Parameter Schema Builder: + +![Schema Builder Oberfläche](./img/schema_build.png) + +Um den `batch` Parameter hinzuzufügen: + +1. Klicke auf den **"Add parameter"** Button oben +2. Verwende den Ziehgriff (⋮⋮), um den neuen Parameter in die "Input/output options" Gruppe zu verschieben, unterhalb des `input` Parameters +3. Fülle die Parameterdetails aus: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: aktiviere die Checkbox + - Optional wähle ein Icon aus dem Icon-Picker (z.B. `fas fa-layer-group`) + +![Hinzufügen des batch Parameters](./img/schema_add.png) + +Wenn du fertig bist, klicke auf den **"Finished"** Button oben rechts. + +Zurück in deinem Terminal siehst du: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Drücke `Ctrl+C`, um den Schema Builder zu beenden. + +Das Tool hat nun deine `nextflow_schema.json` Datei mit dem neuen `batch` Parameter aktualisiert und dabei die gesamte JSON Schema Syntax korrekt gehandhabt. + +### 1.4. Die Änderungen überprüfen + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (Auszug)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Du solltest sehen, dass der `batch` Parameter zum Schema hinzugefügt wurde und das "required" Feld nun `["input", "outdir", "batch"]` zeigt. + +### 1.5. Parametervalidierung testen + +Lass uns nun testen, dass die Parametervalidierung korrekt funktioniert. + +Versuche zuerst, ohne den erforderlichen `input` Parameter zu laufen: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Befehlsausgabe" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Perfekt! Die Validierung erfasst die fehlenden erforderlichen Parameter, bevor die Pipeline läuft. + +Versuche es nun mit einem gültigen Satz von Parametern: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Die Pipeline sollte erfolgreich laufen, und der `batch` Parameter wird nun validiert. + +### Fazit + +Du hast gelernt, wie du das interaktive `nf-core pipelines schema build` Tool verwendest, um Parameter zu `nextflow_schema.json` hinzuzufügen und hast Parametervalidierung in Aktion gesehen. +Die Web-Oberfläche übernimmt die gesamte JSON Schema Syntax für dich und macht es einfach, komplexe Parameter-Schemas ohne fehleranfällige manuelle JSON-Bearbeitung zu verwalten. + +### Was kommt als Nächstes? + +Jetzt, wo die Parametervalidierung funktioniert, fügen wir Validierung für die Eingabedatei-Inhalte hinzu. + +--- + +## 2. Eingabedatenvalidierung (schema_input.json) + +Wir werden Validierung für die Inhalte unserer Eingabe-CSV-Datei hinzufügen. +Während die Parametervalidierung Kommandozeilen-Flags prüft, stellt die Eingabedatenvalidierung sicher, dass die Daten innerhalb der CSV-Datei korrekt strukturiert sind. + +### 2.1. Das greetings.csv Format verstehen + +Erinnern wir uns daran, wie unsere Eingabe aussieht: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Dies ist eine einfache CSV mit: + +- Drei Spalten (keine Kopfzeile) +- In jeder Zeile: eine Begrüßung, eine Sprache und eine Punktzahl +- Die ersten beiden Spalten sind Textstrings ohne besondere Formatanforderungen +- Die dritte Spalte ist eine Ganzzahl + +Für unsere Pipeline ist nur die erste Spalte erforderlich. + +### 2.2. Die Schema-Struktur entwerfen + +Für unseren Anwendungsfall wollen wir: + +1. CSV-Eingabe mit mindestens einer Spalte akzeptieren +2. Das erste Element jeder Zeile als Begrüßungsstring behandeln +3. Sicherstellen, dass Begrüßungen nicht leer sind und nicht mit Leerzeichen beginnen +4. Sicherstellen, dass das Sprachfeld mit einem der unterstützten Sprachcodes übereinstimmt (en, fr, es, it, de) +5. Sicherstellen, dass das Punktzahlfeld eine Ganzzahl mit einem Wert zwischen 0 und 100 ist + +Wir strukturieren dies als Array von Objekten, wobei jedes Objekt mindestens ein `greeting` Feld hat. + +### 2.3. Die Schema-Datei aktualisieren + +Das nf-core Pipeline-Template enthält ein Standard-`assets/schema_input.json`, das für Paired-End-Sequenzierdaten entwickelt wurde. +Wir müssen es durch ein einfacheres Schema für unseren Begrüßungs-Anwendungsfall ersetzen. + +Öffne `assets/schema_input.json` und ersetze die `properties` und `required` Abschnitte: + +=== "Nachher" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Vorher" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Die wichtigsten Änderungen: + +- **`description`**: Aktualisiert, um "greetings file" zu erwähnen +- **`properties`**: `sample`, `fastq_1` und `fastq_2` ersetzt durch `greeting`, `language` und `score` + - **`type:`** Erzwingt entweder string (`greeting`, `language`) oder integer (`score`) + - **`pattern: "^\\S.*$"`**: Begrüßung muss mit einem Nicht-Leerzeichen-Zeichen beginnen (kann danach aber Leerzeichen enthalten) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: Sprachcode muss in der unterstützten Menge sein + - **`"minimum": 0` und `"maximum": 100`**: Punktzahlwert muss zwischen 0 und 100 liegen + - **`errorMessage`**: Benutzerdefinierte Fehlermeldung, die bei fehlgeschlagener Validierung angezeigt wird +- **`required`**: Von `["sample", "fastq_1"]` zu `["greeting"]` geändert + +### 2.4. Eine Kopfzeile zur greetings.csv Datei hinzufügen + +Wenn nf-schema eine CSV-Datei liest, erwartet es, dass die erste Zeile Spaltenüberschriften enthält, die mit den Feldnamen im Schema übereinstimmen. + +Für unseren einfachen Fall müssen wir unserer Greetings-Datei eine Kopfzeile hinzufügen: + +=== "Nachher" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Vorher" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Nun hat die CSV-Datei eine Kopfzeile, die mit den Feldnamen in unserem Schema übereinstimmt. + +Der letzte Schritt ist, die Validierung im Pipeline-Code mit `samplesheetToList` zu implementieren. + +### 2.5. Validierung in der Pipeline implementieren + +Jetzt müssen wir unser einfaches CSV-Parsing durch die `samplesheetToList` Funktion von nf-schema ersetzen, die das Samplesheet validieren und parsen wird. + +Die `samplesheetToList` Funktion: + +1. Liest das Eingabe-Sample Sheet (CSV, TSV, JSON oder YAML) +2. Validiert es gegen das bereitgestellte JSON Schema +3. Gibt eine Groovy-Liste zurück, bei der jeder Eintrag einer Zeile entspricht +4. Wirft hilfreiche Fehlermeldungen, wenn die Validierung fehlschlägt + +Lass uns den Code für die Eingabebehandlung aktualisieren: + +Öffne `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` und finde den Abschnitt, in dem wir den Eingabekanal erstellen (um Zeile 80). + +Wir müssen: + +1. Die `samplesheetToList` Funktion verwenden (bereits im Template importiert) +2. Die Eingabe validieren und parsen +3. Nur die Begrüßungsstrings für unseren Workflow extrahieren + +Beachte zunächst, dass die `samplesheetToList` Funktion bereits am Anfang der Datei importiert ist (das nf-core Template enthält dies standardmäßig): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subworkflow mit Funktionalität spezifisch für die core/hello Pipeline +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Aktualisiere nun den Code zur Channel-Erstellung: + +=== "Nachher" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Channel aus der Eingabedatei erstellen, die über params.input bereitgestellt wird + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Vorher" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Channel aus der Eingabedatei erstellen, die über params.input bereitgestellt wird + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Lass uns aufschlüsseln, was sich geändert hat: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Validiert die Eingabedatei gegen unser Schema und gibt eine Liste zurück +2. **`Channel.fromList(...)`**: Konvertiert die Liste in einen Nextflow Channel + +Dies vervollständigt die Implementierung der Eingabedatenvalidierung mit `samplesheetToList` und JSON Schemas. + +Jetzt, wo wir das Eingabedaten-Schema konfiguriert haben, können wir die vorübergehende Ignore-Einstellung entfernen, die wir zuvor hinzugefügt haben. + +### 2.6. Eingabevalidierung wieder aktivieren + +Öffne `nextflow.config` und entferne die `ignoreParams` Zeile aus dem `validation` Block: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Nun wird nf-schema sowohl Parametertypen ALS AUCH die Eingabedatei-Inhalte validieren. + +### 2.7. Eingabevalidierung testen + +Lass uns überprüfen, dass unsere Validierung funktioniert, indem wir sowohl gültige als auch ungültige Eingaben testen. + +#### 2.7.1. Test mit gültiger Eingabe + +Bestätige zunächst, dass die Pipeline erfolgreich mit gültiger Eingabe läuft. +Beachte, dass wir `--validate_params false` nicht mehr benötigen, da die Validierung funktioniert! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Befehlsausgabe" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Großartig! Die Pipeline läuft erfolgreich und die Validierung wird stillschweigend bestanden. +Die Warnung über `--character` ist nur informativ, da er nicht im Schema definiert ist. +Wenn du möchtest, verwende das Gelernte, um auch für diesen Parameter Validierung hinzuzufügen! + +#### 2.7.2. Test mit ungültiger Eingabe + +Validierung zu bestehen ist immer ein gutes Gefühl, aber lass uns sicherstellen, dass die Validierung tatsächlich Fehler fängt. + +Um eine Testdatei mit einem ungültigen Spaltennamen zu erstellen, beginne damit, eine Kopie der `greetings.csv` Datei zu erstellen: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Öffne nun die Datei und ändere den Namen der ersten Spalte in der Kopfzeile von `greeting` zu `message`: + +=== "Nachher" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Vorher" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Dies stimmt nicht mit unserem Schema überein, daher sollte die Validierung einen Fehler werfen. + +Versuche, die Pipeline mit dieser ungültigen Eingabe auszuführen: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Perfekt! Die Validierung hat den Fehler erfasst und eine klare, hilfreiche Fehlermeldung bereitgestellt, die auf Folgendes hinweist: + +- Welche Datei bei der Validierung fehlgeschlagen ist +- Welcher Eintrag (Zeile 1, die erste Datenzeile) das Problem hat +- Was das spezifische Problem ist (fehlendes erforderliches Feld `greeting`) + +Die Schema-Validierung stellt sicher, dass Eingabedateien die korrekte Struktur haben, bevor die Pipeline läuft, was Zeit spart und verwirrende Fehler später in der Ausführung verhindert. + +Wenn du möchtest, kannst du gerne andere Greetings-Eingabedateien erstellen, die das Schema auf andere lustige Weisen verletzen. + +### Fazit + +Du hast sowohl Parametervalidierung als auch Eingabedatenvalidierung implementiert und getestet. Deine Pipeline validiert nun Eingaben vor der Ausführung und bietet schnelles Feedback und klare Fehlermeldungen. + +!!! tip "Weiterführende Literatur" + + Um mehr über erweiterte Validierungsfunktionen und -muster zu erfahren, schaue dir die [nf-schema Dokumentation](https://nextflow-io.github.io/nf-schema/latest/) an. Der `nf-core pipelines schema build` Befehl bietet eine interaktive GUI zur Verwaltung komplexer Schemas. + +### Was kommt als Nächstes? + +Du hast alle fünf Teile des Hello nf-core Trainingskurses abgeschlossen! + +Fahre mit der [Zusammenfassung](summary.md) fort, um über das Gelernte und Gebaute zu reflektieren. diff --git a/docs/de/docs/hello_nf-core/index.md b/docs/de/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..5a37e6f102 --- /dev/null +++ b/docs/de/docs/hello_nf-core/index.md @@ -0,0 +1,65 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - nf-core Pipelines abrufen, ausführen und verwalten + - Die Code-Struktur und Projektorganisation von nf-core Pipelines beschreiben + - Eine grundlegende nf-core kompatible Pipeline aus einem Template erstellen + - Einen einfachen Nextflow Workflow auf nf-core Standards upgraden + - nf-core Module zu einer nf-core kompatiblen Pipeline hinzufügen + - Eigene Module zu nf-core beisteuern + - Eingaben und Parameter mit nf-core Tooling validieren + audience_prerequisites: + - "**Zielgruppe:** Dieser Kurs richtet sich an Lernende, die bereits mit den Grundlagen von Nextflow vertraut sind und lernen möchten, nf-core Ressourcen und Best Practices zu nutzen." + - "**Fähigkeiten:** Vertrautheit mit der Kommandozeile, grundlegende Scripting-Konzepte und gängige Dateiformate werden vorausgesetzt." + - "**Kurse:** Der Kurs [Hello Nextflow](../hello_nextflow/index.md) oder gleichwertige Kenntnisse müssen abgeschlossen sein." + - "**Fachgebiet:** Die Übungen sind alle fachgebietsneutral, daher ist kein spezifisches wissenschaftliches Vorwissen erforderlich." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core ist eine praktische Einführung in die Nutzung von nf-core Ressourcen und Best Practices.** + +![nf-core logo](./img/nf-core-logo.png) + +Durch praktische Beispiele und angeleitete Übungen lernst du, nf-core kompatible Module und Pipelines zu nutzen und zu entwickeln sowie nf-core Tooling effektiv einzusetzen. + +Nach diesem Kurs kannst du Pipelines nach nf-core Best Practices entwickeln. + +<!-- additional_information --> + +## Kursübersicht + +Dieser Kurs ist darauf ausgelegt, praktisch zu sein, mit zielorientierten Übungen, die so strukturiert sind, dass Informationen schrittweise eingeführt werden. + +Du wirst in [**nf-core**](https://nf-co.re/) eingeführt, eine Community-Initiative zur Entwicklung und Pflege einer kuratierten Sammlung wissenschaftlicher Pipelines, die mit Nextflow erstellt wurden, sowie relevantes Tooling und Richtlinien, die offene Entwicklung, Testing und Peer Review fördern ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +nf-core Pipelines sind modular, skalierbar und portabel. So lassen sie sich leicht anpassen und mit eigenen Daten ausführen. Die Best-Practice-Richtlinien sorgen für robuste, gut dokumentierte und validierte Pipelines. Das verbessert die Reproduzierbarkeit wissenschaftlicher Analysen. + +Wir werden in diesem Kurs nicht alles abdecken, was es über nf-core Pipelines zu wissen gibt, denn nf-core umfasst viele Features und Konventionen, die die Community über Jahre entwickelt hat. +Stattdessen konzentrieren wir uns auf die wesentlichen Konzepte, die dir helfen werden, loszulegen und zu verstehen, wie nf-core funktioniert. + +### Lektionsplan + +Wir haben dies in fünf Teile unterteilt, die sich jeweils auf bestimmte Aspekte der Nutzung von nf-core Ressourcen konzentrieren. + +| Kurskapitel | Zusammenfassung | Geschätzte Dauer | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| [Teil 1: Eine Demo-Pipeline ausführen](./01_run_demo.md) | Führe eine bestehende nf-core Pipeline aus und untersuche ihre Code-Struktur, um ein Gefühl dafür zu bekommen, was diese Pipelines von einfachen Nextflow Workflows unterscheidet | 30 Min. | +| [Teil 2: Hello für nf-core umschreiben](./02_rewrite_hello.md) | Passe einen bestehenden Workflow an das nf-core Template-Gerüst an, ausgehend vom einfachen Workflow aus dem Kurs [Hello Nextflow](../hello_nextflow/index.md) | 60 Min. | +| [Teil 3: Ein nf-core Modul verwenden](./03_use_module.md) | Erkunde die Community-Modulbibliothek und lerne, vorgefertigte, getestete Module zu integrieren, die gängige Bioinformatik-Tools wrappen | 30 Min. | +| [Teil 4: Ein nf-core Modul erstellen](./04_make_module.md) | Erstelle dein eigenes nf-core-style Modul unter Verwendung der spezifischen Struktur, Namenskonventionen und Metadaten-Anforderungen, die von nf-core etabliert wurden | 30 Min. | +| [Teil 5: Eingabevalidierung hinzufügen](./05_input_validation.md) | Implementiere Eingabevalidierung sowohl für Kommandozeilen-Parameter als auch für Eingabedateien mit nf-schema | 30 Min. | + +Am Ende dieses Kurses kannst du den enormen Reichtum an Ressourcen nutzen, die das nf-core Projekt bietet. + +Bereit, den Kurs zu beginnen? + +[Mit dem Lernen beginnen :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/de/docs/hello_nf-core/next_steps.md b/docs/de/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..078d62fb6c --- /dev/null +++ b/docs/de/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Kurszusammenfassung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herzlichen Glückwunsch zum Abschluss des Hello nf-core Trainingskurses! 🎉 + +<!-- placeholder for video --> + +## Dein Fortschritt + +Du hast damit begonnen, eine Demo-Pipeline abzurufen und auszuführen, und dich dann an die Umwandlung eines einfachen Nextflow-Workflows in eine nf-core-Pipeline herangewagt. +Du hast gelernt, wie man ein Pipeline-Gerüst mithilfe einer Vorlage erstellt und die bestehende Pipeline auf dieses Gerüst aufpfropft. +Dann hast du die Pipeline schrittweise verfeinert, indem du eines der lokalen Module durch ein nf-core-Modul ersetzt, ein weiteres lokales Modul an nf-core-Standards angepasst und eine Eingabevalidierung hinzugefügt hast. + +### Was du erstellt hast + +Deine finale `core-hello`-Pipeline verfügt nun über: + +- **Standardisierte Struktur** unter Verwendung der nf-core-Vorlage mit organisierten Verzeichnissen für Workflows, Subworkflows, Module und Konfiguration +- **Community-Module** aus dem nf-core-Repository (`cat/cat`) neben deinen benutzerdefinierten Modulen +- **Umfassende Validierung**, die sowohl Parameter als auch Eingabedaten prüft, bevor die Pipeline läuft +- **Professionelle Konfiguration** mit Profilen für verschiedene Ausführungsumgebungen +- **Vollständige Dokumentation** und Metadaten gemäß nf-core-Konventionen + +### Erworbene Kernkompetenzen + +Durch diesen praxisorientierten Kurs hast du gelernt: + +1. **Navigieren und verstehen** der nf-core-Pipeline-Struktur durch Erkunden einer bestehenden Pipeline +2. **Workflows umstrukturieren**, damit sie komponierbar sind und in die nf-core-Vorlage passen +3. **Vorgefertigte Module finden und integrieren** aus dem Community-Repository +4. **Benutzerdefinierte Module erstellen** nach nf-core-Standards für Benennung, Struktur und Metadaten +5. **Validierung implementieren** mit nf-schema, um Fehler frühzeitig mit klarem Feedback abzufangen + +Du bist jetzt mit dem grundlegenden Wissen ausgestattet, um produktionsreife nf-core-Pipelines zu erstellen, die den Best Practices der Community folgen. + +## Nächste Schritte zum Ausbau deiner Fähigkeiten + +Hier sind unsere Top 3 Vorschläge, was du als Nächstes tun kannst: + +- Wende Nextflow auf einen wissenschaftlichen Analyse-Anwendungsfall an mit [Nextflow for Science](../nf4_science/index.md) +- Erkunde fortgeschrittenere Nextflow-Features mit den [Side Quests](../side_quests/index.md) +- Beteilige dich, indem du der [nf-core-Community beitrittst](https://nf-co.re/join). + +Schließlich empfehlen wir dir, einen Blick auf [**Seqera Platform**](https://seqera.io/) zu werfen, eine cloudbasierte Plattform, die von den Entwicklern von Nextflow entwickelt wurde und es noch einfacher macht, deine Workflows zu starten und zu verwalten, sowie deine Daten zu managen und Analysen interaktiv in jeder Umgebung auszuführen. + +## Feedback-Umfrage + +Bevor du weitermachst, nimm dir bitte eine Minute Zeit, um die Kursumfrage auszufüllen! Dein Feedback hilft uns, unsere Trainingsmaterialien für alle zu verbessern. + +[Zur Umfrage :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/de/docs/hello_nf-core/survey.md b/docs/de/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..1c295173bc --- /dev/null +++ b/docs/de/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Feedback-Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bevor du weitermachst, fülle bitte diese kurze Umfrage mit 5 Fragen aus, um das Training zu bewerten und uns Feedback zu geben. + +Das Ausfüllen sollte weniger als eine Minute dauern. Vielen Dank, dass du uns hilfst, unsere Trainingsmaterialien für alle zu verbessern! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/de/docs/help.md b/docs/de/docs/help.md new file mode 100644 index 0000000000..6e71d2e91a --- /dev/null +++ b/docs/de/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Hilfe erhalten +description: Hilfreiche Ressourcen bei Problemen mit dem Nextflow-Training +hide: + - toc + - footer +--- + +# Hilfe erhalten + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Egal ob du Schwierigkeiten beim Einstieg hast, mittendrin nicht weiterkommst oder eine Anschlussfrage hast - zögere nicht, dich zu melden! Unser Community-Team ist hier, um zu helfen, und die Nextflow-Community insgesamt ist sehr aktiv, inklusiv und hilfsbereit. + +Hier sind die wichtigsten verfügbaren Optionen, je nachdem, wonach du suchst. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Community-Forum__ + + --- + + Unser Community-Forum hat eine Kategorie, die dem Training gewidmet ist. Das ist ein großartiger Ort, um Fragen zu stellen oder Probleme zu melden, die du mit dem Training hast. Möglicherweise findest du sogar heraus, dass deine Frage bereits gestellt - und beantwortet wurde! + + [Zum Trainingsforum:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Slack-Kanal__ + + --- + + Wenn du auf Slack bist, kannst du uns gerne im Trainingskanal im Nextflow Slack Workspace kontaktieren. Der Nextflow Slack ist ein großartiger Ort, um mit anderen Entwicklern zu chatten und sich mit der Nextflow-Community im Allgemeinen auszutauschen. + + [Dem Nextflow Slack beitreten :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __GitHub Issues__ + + --- + + Wenn du einen Fehler in den Trainingsmaterialien entdeckst, melde ihn bitte, indem du ein Issue im GitHub-Repository eröffnest. Ob es sich um einen Tippfehler, ein Formatierungsproblem oder einen tatsächlichen Bug handelt, der den Code betrifft - lass es uns wissen, damit wir es beheben können! Wir freuen uns auch über direkte PRs. + + [Ein Issue melden:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Seqera AI-Assistent__ + + --- + + Seqera AI ist ein KI-Assistent, der auf Nextflow- und nf-core-Ressourcen trainiert wurde. Er kann dir helfen, deinen Code zu debuggen, Nextflow-Konzepte zu erklären und schneller nach Dokumentation zu suchen. Stell es dir wie einen Tutor vor, der rund um die Uhr verfügbar ist, während du die Kurse durcharbeitest. + + [Seqera AI fragen:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Nextflow-Dokumentation__ + + --- + + Die offizielle Dokumentation ist der ultimative Leitfaden zu allen Sprachfunktionen und Konfigurationsoptionen. Nutze sie parallel zu diesem Training, um tiefer in spezifische Themen einzutauchen, erweiterte Funktionen zu erkunden und detaillierte Syntaxreferenzen zu finden. + + [Die Dokumentation durchsuchen:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Professioneller Support__ + + --- + + Nextflow ist eine kostenlose, quelloffene Software, die von [Seqera](https://seqera.io/) entwickelt wird, einem Unternehmen mit Hauptsitz in Spanien und Niederlassungen in Großbritannien und den USA. Wir bieten professionelle Support-Dienste für Nextflow an, einschließlich maßgeschneiderter Schulungen. + + [Kontakt aufnehmen:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/de/docs/index.md b/docs/de/docs/index.md new file mode 100644 index 0000000000..5ece94f351 --- /dev/null +++ b/docs/de/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Startseite +description: Willkommen im Nextflow Community-Trainingsportal! +hide: + - toc + - footer +--- + +# Nextflow Training + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Selbstlernkurse__ + + --- + + **Willkommen im Nextflow Community-Trainingsportal!** + + Die unten aufgeführten Trainingskurse sind als Selbstlernressource konzipiert. + Du kannst sie jederzeit eigenständig durcharbeiten, entweder in der webbasierten Umgebung, die wir über Github Codespaces bereitstellen, oder in deiner eigenen Umgebung. + + [Kurse erkunden :material-arrow-right:](#katalog-der-nextflow-trainingskurse){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Zusätzliche Informationen__ + + --- + + ??? warning "Versionskompatibilität" + + <!-- Any update to this content needs to be copied to the local installation page --> + **Ab Januar 2026 erfordern alle unsere Nextflow-Trainingskurse Nextflow Version 25.10.2 oder höher mit aktivierter strikter Syntax, sofern nicht anders angegeben.** + + Weitere Informationen zu Versionsanforderungen und strikter Syntax findest du im [Nextflow-Dokumentations-Migrationshandbuch](https://nextflow.io/docs/latest/strict-syntax.html). + + Ältere Versionen des Trainingsmaterials, die früherer Syntax entsprechen, sind über den Versionsauswähler in der Menüleiste dieser Webseite verfügbar. + + ??? terminal "Umgebungsoptionen" + + Wir bieten eine webbasierte Trainingsumgebung an, in der alles vorinstalliert ist, was du für das Training benötigst. Diese ist über Github Codespaces verfügbar (erfordert ein kostenloses GitHub-Konto). + + [![In GitHub Codespaces öffnen](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Wenn dies nicht deinen Anforderungen entspricht, siehe die anderen [Umgebungsoptionen](./envsetup/index.md). + + ??? learning "Trainingsveranstaltungen" + + Wenn du lieber an einem Nextflow-Training im Rahmen einer strukturierten Veranstaltung teilnehmen möchtest, gibt es viele Möglichkeiten dazu. Wir empfehlen, die folgenden Optionen zu prüfen: + + - **[Training Weeks]()** werden vierteljährlich vom Community-Team organisiert + - **[Seqera Events](https://seqera.io/events/)** beinhalten Präsenztrainings, die von Seqera organisiert werden (suche nach 'Seqera Sessions' und 'Nextflow Summit') + - **[Nextflow Ambassadors]()** organisieren Veranstaltungen für ihre lokale Community + - **[nf-core events](https://nf-co.re/events)** beinhalten Community-Hackathons + + ??? people "Informationen für Trainer" + + Wenn du als Dozent eigene Trainings durchführst, kannst du unsere Materialien gerne direkt aus dem Trainingsportal verwenden, solange du die entsprechende Quellenangabe machst. Siehe 'Credits und Beiträge' unten für Details. + + Außerdem würden wir gerne von dir erfahren, wie wir deine Trainingsarbeit besser unterstützen können! Bitte kontaktiere uns unter [community@seqera.io](mailto:community@seqera.io) oder im Community-Forum (siehe Seite [Hilfe](help.md)). + + ??? licensing "Open-Source-Lizenz und Beitragsrichtlinien" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Dieses Trainingsmaterial wird von [Seqera](https://seqera.io) entwickelt und gepflegt und unter einer Open-Source-Lizenz ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) zum Nutzen der Community veröffentlicht. Wenn du dieses Material auf eine Weise nutzen möchtest, die außerhalb des Geltungsbereichs der Lizenz liegt (beachte die Einschränkungen bei kommerzieller Nutzung und Weiterverbreitung), kontaktiere uns bitte unter [community@seqera.io](mailto:community@seqera.io), um deine Anfrage zu besprechen. + + Wir freuen uns über Verbesserungen, Korrekturen und Fehlermeldungen aus der Community. Jede Seite hat ein :material-file-edit-outline: Symbol oben rechts, das zum Code-Repository verlinkt, wo du Probleme melden oder Änderungen am Trainingsmaterial per Pull Request vorschlagen kannst. Siehe die \`README.md\` im Repository für weitere Details. + +</div> + +!!! note "KI-gestützte Übersetzung" + + Diese Übersetzung wurde mit künstlicher Intelligenz erstellt und von menschlichen Übersetzern überprüft. + Wir freuen uns über Feedback und Verbesserungsvorschläge. + Weitere Informationen findest du in unserer [Übersetzungsanleitung](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md). + +## Katalog der Nextflow-Trainingskurse + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Einführungskurse__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow für Einsteiger {.mt-1} + + Fachbereichsunabhängige Kurse für alle, die komplett neu bei Nextflow sind. Jeder Kurs besteht aus mehreren Modulen, die Fähigkeiten schrittweise aufbauen. + + ??? courses "**Hello Nextflow:** Lerne, eigene Pipelines zu entwickeln" + + Dieser Kurs behandelt die Kernkomponenten der Nextflow-Sprache ausführlich genug, um einfache, aber voll funktionsfähige Pipelines zu entwickeln, plus Schlüsselelemente des Pipeline-Designs, der Entwicklung und der Konfigurationspraktiken. + + [Hello Nextflow Training starten :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Lerne, bestehende Pipelines auszuführen" + + Eine kompakte Einführung in die Ausführung und Konfiguration von Nextflow-Pipelines, basierend auf dem Hello Nextflow-Entwicklerkurs, aber mit weniger Fokus auf Code. Behandelt Ausführung, Ausgaben, grundlegende Codestruktur und Konfiguration für verschiedene Rechenumgebungen. + + [Nextflow Run Training starten :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow für die Wissenschaft {.mt-1} + + Lerne, die in 'Hello Nextflow' vorgestellten Konzepte und Komponenten auf spezifische wissenschaftliche Anwendungsfälle anzuwenden. + + ??? courses "**Nextflow für Genomik** (Variantenanalyse)" + + Für Forscher, die lernen möchten, eigene Genomik-Pipelines zu entwickeln. Der Kurs verwendet einen Anwendungsfall zur Variantenanalyse, um zu demonstrieren, wie man eine einfache, aber funktionale Genomik-Pipeline entwickelt. + + [Nextflow für Genomik Training starten :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow für RNAseq** (Bulk-RNAseq)" + + Für Forscher, die lernen möchten, eigene RNAseq-Pipelines zu entwickeln. Der Kurs verwendet einen Bulk-RNAseq-Verarbeitungs-Anwendungsfall, um zu demonstrieren, wie man eine einfache, aber funktionale RNAseq-Pipeline entwickelt. + + [Nextflow für RNAseq Training starten :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow für Bildgebung** (Spatial Omics)" + + Für Forscher in der Bildgebung und Spatial Omics, die lernen möchten, Analyse-Pipelines auszuführen und anzupassen. Der Kurs verwendet die nf-core/molkart-Pipeline, um eine biologisch relevante Pipeline bereitzustellen und zu demonstrieren, wie man Nextflow-Pipelines und Workflows ausführt, konfiguriert und Eingaben verwaltet. + + [Nextflow für Bildgebung Training starten :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Fortgeschrittenenkurse__ + + --- + + ### :material-bridge:{.nextflow-primary} Von Nextflow zu nf-core {.mt-1} + + Lerne, Code und Best Practices aus dem [nf-core](https://nf-co.re/) Community-Projekt zu nutzen. + + Diese Kurse helfen dir, von den Nextflow-Grundlagen zu den nf-core Best Practices zu gelangen. + Verstehe, wie und warum die nf-core-Community Pipelines entwickelt, und wie du beitragen und diese Techniken wiederverwenden kannst. + + ??? courses "**Hello nf-core:** Erste Schritte mit nf-core" + + Für Entwickler, die lernen möchten, [nf-core](https://nf-co.re/)-konforme Pipelines auszuführen und zu entwickeln. Der Kurs behandelt die Struktur von nf-core-Pipelines ausführlich genug, um einfache, aber voll funktionsfähige Pipelines zu entwickeln, die dem nf-core-Template und den Entwicklungs-Best-Practices folgen, sowie bestehende nf-core-Module zu verwenden. + + [Hello nf-core Training starten :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Fortgeschrittenes Nextflow-Training {.mt-1} + + Lerne fortgeschrittene Konzepte und Mechanismen für die Entwicklung und Bereitstellung von Nextflow-Pipelines zur Lösung realer Anwendungsfälle. + + ??? courses "**Side Quests:** Vertiefungen zu eigenständigen Themen" + + Eigenständige Minikurse für Nextflow-Entwickler, die ihr Repertoire erweitern und/oder ihre Fähigkeiten zu bestimmten Themen vertiefen möchten. Sie werden linear präsentiert, können aber in beliebiger Reihenfolge absolviert werden (siehe Abhängigkeiten in jeder Minikurs-Übersicht). + + [Side Quests durchstöbern :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Training Collections:** Empfohlene Lernpfade durch die Side Quests" + + Training Collections kombinieren mehrere Side Quests, um eine umfassende Lernerfahrung zu einem bestimmten Thema oder Anwendungsfall zu bieten. + + [Training Collections durchstöbern :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Auf der Suche nach archivierten Trainingsmaterialien?" + + Ältere Trainingsmaterialien (Fundamentals Training, Advanced Training und andere experimentelle Kurse) wurden aus dem Trainingsportal entfernt, da sie nicht mit der strikten Nextflow 3.0-Syntax kompatibel sind. + Wenn du Zugriff auf diese Materialien benötigst, sind sie in der [Git-Historie](https://github.com/nextflow-io/training) vor Januar 2026 verfügbar. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/de/docs/info/conventions.md b/docs/de/docs/info/conventions.md new file mode 100644 index 0000000000..5d1588edf8 --- /dev/null +++ b/docs/de/docs/info/conventions.md @@ -0,0 +1 @@ +Wir verwenden das Präfix `ch_` für alle Channel-Variablen, um deutlich zu machen, dass es sich um Nextflow-Channels handelt. diff --git a/docs/de/docs/info/hello_pipeline.md b/docs/de/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..54c19334a9 --- /dev/null +++ b/docs/de/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Die Hello-Pipeline +description: Zusammenfassung dessen, was die Hello-Pipeline tut und wie sie strukturiert ist. +hide: + - toc + - footer +--- + +# Die Hello-Pipeline + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Die meisten unserer Trainingskurse verwenden eine einfache domänenunabhängige pipeline, um Nextflow-Konzepte und -Mechanismen zu demonstrieren. +Der Hello Nextflow-Kurs zeigt, wie diese pipeline Schritt für Schritt entwickelt wird, wobei jede Design- und Implementierungsentscheidung erklärt wird. +Andere Trainings verwenden diese pipeline oder Teile davon als Ausgangspunkt. + +Diese Seite fasst den Zustand der pipeline nach Abschluss des Hello Nextflow-Kurses zusammen. + +### Kurzbeschreibung + +Der Hello-workflow nimmt eine CSV-Datei mit Grüßen, schreibt sie in separate Dateien, konvertiert jede in Großbuchstaben, sammelt sie wieder zusammen und gibt eine einzelne Textdatei aus, die ein ASCII-Bild einer lustigen Figur enthält, die die Grüße sagt. + +### Workflow-Schritte (Prozesse) + +Die vier Schritte sind als Nextflow-processes implementiert (`sayHello`, `convertToUpper`, `collectGreetings` und `cowpy`), die in separaten Modul-Dateien gespeichert sind. + +1. **`sayHello`:** Schreibt jeden Gruß in eine eigene Ausgabedatei (z.B. "Hello-output.txt") +2. **`convertToUpper`:** Konvertiert jeden Gruß in Großbuchstaben (z.B. "HELLO") +3. **`collectGreetings`:** Sammelt alle Großbuchstaben-Grüße in einer einzelnen Batch-Datei +4. **`cowpy`:** Generiert ASCII-Kunst mit dem `cowpy`-Tool + +### Diagramm + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Ergebnisse + +Die Ergebnisse werden in einem Verzeichnis namens `results/` veröffentlicht, und die endgültige Ausgabe der pipeline (bei Ausführung mit Standardparametern) ist eine Klartextdatei mit ASCII-Kunst eines Truthahns, der die Grüße in Großbuchstaben sagt. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Je nach Kurs, in dem die pipeline vorgestellt wird, können kleine Abweichungen in den Details auftreten. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/de/docs/info/nxf_versions.md b/docs/de/docs/info/nxf_versions.md new file mode 100644 index 0000000000..48cc34409d --- /dev/null +++ b/docs/de/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Nextflow-Versionen +description: Verständnis und Verwaltung der Entwicklung von Nextflow-Syntaxversionen +hide: + - toc + - footer +--- + +## Aktuell unterstützte Nextflow-Syntaxversion & Anforderungen + +Ab Version 3.0 des Trainingsportals basieren alle unsere Trainingskurse auf der Nextflow-Version 25.10.2, sofern auf der Kursindexseite nicht anders angegeben (außer veraltete oder anderweitig archivierte Materialien, die möglicherweise keinen Versionshinweis enthalten). + +Da die Kurse jetzt typisierte Eingaben auf workflow-Ebene sowie workflow-Ebene-Ausgabe-Direktiven verwenden, erfordern sie die Verwendung des V2-Syntaxparsers. +Wenn du die Umgebung verwendest, die wir über [Github Codespaces](../envsetup/01_setup.md) oder [lokale Devcontainer](../envsetup/03_devcontainer.md) bereitstellen, musst du nichts unternehmen, es sei denn, dies wird in den Kursanweisungen speziell erwähnt. +Wenn du jedoch planst, die Trainings in deiner eigenen Umgebung durchzuarbeiten ([Manuelle Installation](../envsetup/02_local.md)), musst du sicherstellen, dass du Nextflow Version 25.10.2 oder höher mit aktiviertem v2-Syntaxparser verwendest. + +## Ältere Versionen der Trainingsmaterialien + +Unsere Trainingsmaterialien sind seit Februar 2025 versioniert. + +Du kannst auf ältere Versionen der Trainingsmaterialien zugreifen, die mit Nextflow-Versionen **vor 25.10.2** funktionieren, über das Dropdown-Menü oben auf jeder Seite, das die nummerierte Version der Trainingsmaterialien anzeigt. +Wenn du eine ältere Version der Trainingsmaterialien auswählst, geben Links zur Trainingsumgebung automatisch die entsprechende Version der Umgebung an. + +## Weitere Informationen zu Nextflow-Syntaxversionen + +Nextflow hat zwei unterschiedliche Versionierungskonzepte, die manchmal verwechselt werden: **DSL-Versionen** und **Syntaxparser-Versionen**. + +**DSL1 vs DSL2** bezieht sich auf grundlegend unterschiedliche Arten, Nextflow-pipelines zu schreiben. +DSL1 war die ursprüngliche Syntax, bei der processes implizit über channels verbunden wurden. +DSL2, eingeführt in Nextflow 20.07, fügte Modularitätsfunktionen hinzu: die Möglichkeit, processes und workflows aus anderen Dateien zu importieren, explizite `workflow`-Blöcke und benannte process-Ausgaben. +DSL1 wurde in Nextflow 22.03 als veraltet markiert und in 22.12 entfernt. +Aller moderner Nextflow-Code verwendet DSL2. + +**Syntaxparser v1 vs v2** bezieht sich auf verschiedene Parser, die beide mit DSL2-Code funktionieren. +Der v1-Parser ist der ursprüngliche, tolerantere Parser. +Der v2-Parser ist strenger und ermöglicht neue Sprachfunktionen wie statische Typisierung (typisierte Eingaben und Ausgaben) und workflow-Ebene-Ausgabe-Direktiven. +Der v2-Parser bietet auch bessere Fehlermeldungen und erkennt mehr Fehler zur Parse-Zeit statt zur Laufzeit. +Der v2-Parser wird in Nextflow 26.04 zum Standard. + +Zusammenfassend: DSL2 ist die Sprache, die du schreibst; die Syntaxparser-Version bestimmt, wie streng diese Sprache interpretiert wird und welche erweiterten Funktionen verfügbar sind. + +### Überprüfen und Einstellen der Nextflow-Version + +Du kannst überprüfen, welche Version von Nextflow auf deinem System installiert ist, indem du den Befehl `nextflow --version` verwendest. + +Weitere Informationen zum Aktualisieren deiner Nextflow-Version findest du in der Referenzdokumentation unter [Updating Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Aktivieren des v2-Syntaxparsers + +Um den v2-Syntaxparser für deine aktuelle Sitzung zu **aktivieren**, führe den folgenden Befehl in deinem Terminal aus: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Um dies dauerhaft zu machen (bis v2 in Nextflow 26.04 zum Standard wird), füge den export-Befehl zu deinem Shell-Profil hinzu (`~/.bashrc`, `~/.zshrc`, etc.): + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Beachte, dass die Umgebungsvariable `NXF_SYNTAX_PARSER=v2` eine vorübergehende Anforderung ist. +Ab Nextflow 26.04 wird der v2-Parser zum Standard und diese Einstellung wird nicht mehr benötigt. + +### Deaktivieren des v2-Syntaxparsers + +Um den v2-Syntaxparser für deine aktuelle Sitzung zu **deaktivieren**, führe den folgenden Befehl in deinem Terminal aus: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migrieren von bestehendem Code + +Anleitungen zur Migration von bestehendem Code zur Einhaltung neuerer Nextflow-Versionen findest du in den [Migration Notes](https://www.nextflow.io/docs/latest/migrations/index.html) in der Referenzdokumentation. + +Diese beiden Artikel sind besonders hilfreich für die Migration zur neuesten Version: + +- [Migrating to workflow outputs](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrating to static types](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Beide Funktionen werden ab Version 3.0 der Trainingsmaterialien im Anfängertraining behandelt. + +Je nach Generation des Nextflow-Codes, den du migrieren möchtest, kannst du möglicherweise den größten Teil davon mit dem Nextflow-Linter mithilfe des Befehls `nextflow lint -format` erledigen. +Weitere Details findest du in der CLI-Referenz für [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint). + +Wir hoffen, dass dies hilfreich sein wird. +Wenn du Hilfe benötigst, melde dich auf Slack oder im Forum. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/de/docs/nextflow_run/00_orientation.md b/docs/de/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..7c3a8726f4 --- /dev/null +++ b/docs/de/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Erste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Eine Trainingsumgebung starten + +Um die vorgefertigte Umgebung zu verwenden, die wir auf GitHub Codespaces bereitstellen, klicke auf die Schaltfläche "Open in GitHub Codespaces" unten. Für andere Optionen siehe [Umgebungsoptionen](../envsetup/index.md). + +Wir empfehlen, die Trainingsumgebung in einem neuen Browser-Tab oder -Fenster zu öffnen (verwende Rechtsklick, Strg-Klick oder Cmd-Klick je nach Gerät), damit du weiterlesen kannst, während die Umgebung lädt. +Du musst diese Anleitung parallel geöffnet halten, um den Kurs durchzuarbeiten. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Grundlagen der Umgebung + +Diese Trainingsumgebung enthält alle Software, den Code und die Daten, die zum Durcharbeiten des Kurses notwendig sind, sodass du nichts selbst installieren musst. + +Der Codespace ist mit einer VSCode-Oberfläche eingerichtet, die einen Dateisystem-Explorer, einen Code-Editor und eine Terminal-Shell enthält. +Alle Anweisungen während des Kurses (z.B. 'öffne die Datei', 'bearbeite den Code' oder 'führe diesen Befehl aus') beziehen sich auf diese drei Teile der VSCode-Oberfläche, sofern nicht anders angegeben. + +Wenn du diesen Kurs selbstständig durcharbeitest, mache dich bitte mit den [Grundlagen der Umgebung](../envsetup/01_setup.md) für weitere Details vertraut. + +### Versionsanforderungen + +Dieses Training ist für Nextflow 25.10.2 oder später **mit aktiviertem v2-Syntax-Parser** konzipiert. +Wenn du eine lokale oder benutzerdefinierte Umgebung verwendest, stelle bitte sicher, dass du die richtigen Einstellungen wie [hier](../info/nxf_versions.md) dokumentiert verwendest. + +## Bereit zum Arbeiten + +Sobald dein Codespace läuft, musst du zwei Dinge tun, bevor du in das Training eintauchst: dein Arbeitsverzeichnis für diesen speziellen Kurs festlegen und dir die bereitgestellten Materialien ansehen. + +### Das Arbeitsverzeichnis festlegen + +Standardmäßig öffnet sich der Codespace mit dem Arbeitsverzeichnis am Stamm aller Trainingskurse, aber für diesen Kurs werden wir im Verzeichnis `nextflow-run/` arbeiten. + +Wechsle jetzt das Verzeichnis, indem du diesen Befehl im Terminal ausführst: + +```bash +cd nextflow-run/ +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis konzentriert, sodass nur die relevanten Dateien in der Datei-Explorer-Seitenleiste angezeigt werden: + +```bash +code . +``` + +!!! tip "Tipp" + + Wenn du aus irgendeinem Grund dieses Verzeichnis verlässt (z.B. dein Codespace geht in den Schlafmodus), kannst du immer den vollständigen Pfad verwenden, um dorthin zurückzukehren, vorausgesetzt du arbeitest in der GitHub Codespaces-Trainingsumgebung: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Schauen wir uns jetzt den Inhalt an. + +### Die bereitgestellten Materialien erkunden + +Du kannst den Inhalt dieses Verzeichnisses erkunden, indem du den Datei-Explorer auf der linken Seite des Trainingsarbeitsbereichs verwendest. +Alternativ kannst du den Befehl `tree` verwenden. + +Während des gesamten Kurses verwenden wir die Ausgabe von `tree`, um Verzeichnisstruktur und -inhalt in lesbarer Form darzustellen, manchmal mit kleineren Anpassungen zur Klarheit. + +Hier generieren wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 2 +``` + +??? abstract "Verzeichnisinhalt" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Klicke auf das farbige Feld, um den Abschnitt zu erweitern und seinen Inhalt anzuzeigen. +Wir verwenden solche einklappbaren Abschnitte, um erwartete Befehlsausgaben sowie Verzeichnis- und Dateiinhalte kompakt darzustellen. + +- **Die `.nf`-Dateien** sind Workflow-Scripts, die basierend darauf nummeriert sind, in welchem Teil des Kurses sie verwendet werden. + +- **Die Datei `nextflow.config`** ist eine Konfigurationsdatei, die minimale Umgebungseigenschaften festlegt. + Du kannst sie vorerst ignorieren. + +- **Die Datei `greetings.csv`** unter `data/` enthält Eingabedaten, die wir im größten Teil des Kurses verwenden werden. Sie wird in Teil 2 (Pipelines ausführen) beschrieben, wenn wir sie zum ersten Mal einführen. + +- **Die `test-params.*`-Dateien** sind Konfigurationsdateien, die wir in Teil 3 (Konfiguration) verwenden werden. Du kannst sie vorerst ignorieren. + +- **Das `solutions`-Verzeichnis** enthält den Endzustand des Workflows und seiner Hilfsdateien (Config und Module), die sich aus dem Abschluss des Kurses ergeben. + Sie sind als Referenz gedacht, um deine Arbeit zu überprüfen und eventuelle Probleme zu beheben. + +## Bereitschafts-Checkliste + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Meine Umgebung ist eingerichtet und läuft +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend festgelegt + +Wenn du alle Kästchen abhaken kannst, bist du startklar. + +**Um zu [Teil 1: Grundlegende Operationen](./01_basics.md) fortzufahren, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite.** diff --git a/docs/de/docs/nextflow_run/01_basics.md b/docs/de/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..54d3046369 --- /dev/null +++ b/docs/de/docs/nextflow_run/01_basics.md @@ -0,0 +1,736 @@ +# Teil 1: Grundlegende Operationen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil des Nextflow Run-Trainingskurses steigen wir mit einem sehr grundlegenden, fachunabhängigen Hello World-Beispiel in das Thema ein, das wir verwenden werden, um wesentliche Operationen zu demonstrieren und auf die entsprechenden Nextflow-Code-Komponenten hinzuweisen. + +??? info "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 dem Ausgabegerät wie der Konsole oder dem Terminal auszugeben oder in eine Datei zu schreiben. + +--- + +## 1. Ein Hello World direkt ausführen + +Demonstrieren wir dieses Konzept mit einem einfachen Befehl, den wir direkt im Terminal ausführen, um zu zeigen, was er tut, bevor wir ihn in Nextflow einpacken. + +!!! tip "Tipp" + + Denke daran, dass du dich jetzt im Verzeichnis `nextflow-run/` befinden solltest, wie auf der Seite [Erste Schritte](00_orientation.md) beschrieben. + +### 1.1. Das Terminal "Hallo" sagen lassen + +Führe folgenden Befehl in deinem Terminal aus. + +```bash +echo 'Hello World!' +``` + +??? success "Befehlsausgabe" + + ```console + Hello World! + ``` + +Dies gibt den Text 'Hello World' direkt im Terminal aus. + +### 1.2. Die Ausgabe in eine Datei schreiben + +Beim Ausführen von Pipelines geht es hauptsächlich darum, Daten aus Dateien zu lesen und Ergebnisse in andere Dateien zu schreiben, also modifizieren wir den Befehl so, dass die Textausgabe in eine Datei geschrieben wird, um das Beispiel etwas relevanter zu machen. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Befehlsausgabe" + + ```console + + ``` + +Dies gibt nichts im Terminal aus. + +### 1.3. Die Ausgabe finden + +Der Text 'Hello World' sollte jetzt in der Ausgabedatei sein, die wir angegeben haben, namens `output.txt`. +Du kannst sie im Datei-Explorer öffnen oder von der Befehlszeile aus mit dem `cat`-Tool zum Beispiel. + +??? abstract "Dateiinhalt" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Das ist es, was wir mit unserem allerersten Nextflow-Workflow replizieren werden. + +### Erkenntnisse + +Du weißt jetzt, wie man einen einfachen Befehl im Terminal ausführt, der etwas Text ausgibt, und optional, wie man ihn die Ausgabe in eine Datei schreiben lässt. + +### Was kommt als Nächstes? + +Finde heraus, was es braucht, um einen Nextflow-Workflow auszuführen, der dasselbe Ergebnis erzielt. + +--- + +## 2. Den Workflow ausführen + +Wir stellen dir ein Workflow-Script namens `1-hello.nf` zur Verfügung, das einen Eingabe-Gruß über ein Befehlszeilenargument namens `--input` nimmt und eine Textdatei produziert, die diesen Gruß enthält. + +Wir werden uns den Code noch nicht ansehen; zuerst schauen wir uns an, wie es aussieht, ihn auszuführen. + +### 2.1. Den Workflow starten und die Ausführung überwachen + +Führe im Terminal folgenden Befehl aus: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +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: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Das sagt uns, dass der `sayHello`-Prozess einmal erfolgreich ausgeführt wurde (`1 of 1 ✔`). + +Das ist großartig, aber du fragst dich vielleicht: wo ist die Ausgabe? + +### 2.2. Die Ausgabedatei im `results`-Verzeichnis finden + +Dieser Workflow ist so konfiguriert, dass er seine Ausgabe in ein results-Verzeichnis veröffentlicht. +Wenn du dein aktuelles Verzeichnis anschaust, wirst du sehen, dass Nextflow beim Ausführen des Workflows ein neues Verzeichnis namens `results` erstellt hat, sowie ein Unterverzeichnis namens `1-hello` darunter, das eine Datei namens `output.txt` enthält. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Öffne die Datei; der Inhalt sollte mit dem String übereinstimmen, den du in der Befehlszeile angegeben hast. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +Das ist großartig, unser Workflow hat getan, was er sollte! + +Beachte jedoch, dass das 'veröffentlichte' Ergebnis eine Kopie (oder in einigen Fällen ein symbolischer Link) der tatsächlichen Ausgabe ist, die Nextflow produziert hat, als es den Workflow ausführte. + +Also werden wir jetzt unter die Haube schauen, um zu sehen, wo Nextflow die Arbeit tatsächlich ausgeführt hat. + +!!! warning "Warnung" + + Nicht alle Workflows werden so eingerichtet sein, dass sie Ausgaben in ein results-Verzeichnis veröffentlichen, und/oder die Verzeichnisnamen und -struktur können unterschiedlich sein. + Etwas später in diesem Abschnitt zeigen wir dir, wie du herausfindest, wo dieses Verhalten festgelegt ist. + +### 2.3. Die ursprüngliche Ausgabe und Protokolle im `work/`-Verzeichnis finden + +Wenn du einen Workflow ausführst, erstellt Nextflow ein eigenes 'Aufgabenverzeichnis' für jeden einzelnen Aufruf jedes Prozesses im Workflow (=jeden Schritt in der Pipeline). +Für jeden wird es die notwendigen Eingaben bereitstellen, die relevanten Anweisungen ausführen und Ausgaben und Protokolldateien in dieses eine Verzeichnis schreiben, das automatisch mit einem Hash benannt wird, um es einzigartig zu machen. + +Alle diese Aufgabenverzeichnisse leben unter einem Verzeichnis namens `work` in deinem aktuellen Verzeichnis (wo du den Befehl ausführst). + +Das mag verwirrend klingen, also schauen wir uns an, wie das in der Praxis aussieht. + +Wenn wir auf die Konsolenausgabe für den zuvor ausgeführten Workflow zurückgehen, hatten wir diese Zeile: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Siehst du, wie die Zeile mit `[a3/7be2fa]` beginnt? +Das ist eine abgekürzte Form des Aufgabenverzeichnispfads für diesen einen Prozessaufruf und sagt dir, wo du die Ausgabe des `sayHello`-Prozessaufrufs innerhalb des `work/`-Verzeichnispfads findest. + +Du kannst den vollständigen Pfad finden, indem du folgenden Befehl eingibst (ersetze `a3/7be2fa` durch das, was du in deinem eigenen Terminal siehst) und die Tab-Taste drückst, um den Pfad automatisch zu vervollständigen, oder ein Sternchen hinzufügst: + +```bash +ls work/a3/7be2fa* +``` + +Dies sollte den vollständigen Verzeichnispfad ergeben: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Schauen wir uns an, was dort drin ist. + +??? abstract "Verzeichnisinhalt" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Siehst du nicht dasselbe?" + + Die genauen Unterverzeichnisnamen werden auf deinem System anders sein. + + Wenn du den Inhalt des Aufgabenunterverzeichnisses im VSCode-Datei-Explorer durchsuchst, siehst du alle Dateien sofort. + Die Protokolldateien sind jedoch so eingestellt, dass sie im Terminal unsichtbar sind, also wenn du `ls` oder `tree` verwenden möchtest, um sie anzuzeigen, musst du die entsprechende Option zum Anzeigen unsichtbarer Dateien setzen. + + ```bash + tree -a work + ``` + +Du solltest sofort die `output.txt`-Datei erkennen, die tatsächlich die ursprüngliche Ausgabe des `sayHello`-Prozesses ist, die in das `results`-Verzeichnis veröffentlicht wurde. +Wenn du sie öffnest, wirst du den `Hello World!`-Gruß wieder finden. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +Was ist also mit all den anderen Dateien? + +Das sind die Hilfs- und Protokolldateien, die Nextflow als Teil der Aufgabenausführung geschrieben hat: + +- **`.command.begin`**: Sentinel-Datei, die erstellt wird, sobald die Aufgabe gestartet wird. +- **`.command.err`**: Fehlermeldungen (`stderr`), die vom Prozessaufruf ausgegeben werden +- **`.command.log`**: Vollständige Protokollausgabe, die vom Prozessaufruf ausgegeben wird +- **`.command.out`**: Reguläre Ausgabe (`stdout`) vom Prozessaufruf +- **`.command.run`**: Vollständiges Script, das von Nextflow ausgeführt wird, 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 resultiert + +Die `.command.sh`-Datei ist besonders nützlich, weil sie dir den Hauptbefehl zeigt, den Nextflow ausgeführt hat, ohne die gesamte Buchführung und Aufgaben-/Umgebungseinrichtung. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Das bestätigt also, dass der Workflow denselben Befehl zusammengestellt hat, den wir zuvor direkt auf der Befehlszeile ausgeführt haben. + +Wenn etwas schief geht und du Fehler beheben musst, kann es nützlich sein, das `command.sh`-Script anzusehen, um genau zu überprüfen, welchen Befehl Nextflow basierend auf den Workflow-Anweisungen, Variableninterpolation usw. zusammengestellt hat. + +### 2.4. Den Workflow mit verschiedenen Grüßen erneut ausführen + +Versuche, den Workflow einige Male mit verschiedenen Werten für das `--input`-Argument erneut auszuführen, und schaue dann die Aufgabenverzeichnisse an. + +??? abstract "Verzeichnisinhalt" + + ```console + work + ├── 0f + │ └── 52b7e07b0e274a80843fca48ed21b8 + │ ├── .command.begin + │ ├── .command.err + │ ├── .command.log + │ ├── .command.out + │ ├── .command.run + │ ├── .command.sh + │ ├── .exitcode + │ └── output.txt + ├── 67 + │ ├── 134e6317f90726c6c17ad53234a32b + │ │ ├── ... + │ │ └── output.txt + │ └── e029f2e75305874a9ab263d21ebc2c + │ ├── ... + │ └── output.txt + ... + ``` + +Du siehst, dass für jeden Lauf ein neues Unterverzeichnis mit einem vollständigen Satz von Ausgabe- und Protokolldateien erstellt wurde. + +Im Gegensatz dazu, wenn du das `results`-Verzeichnis anschaust, gibt es immer noch nur einen Satz von Ergebnissen, und der Inhalt der Ausgabedatei entspricht dem, was du zuletzt ausgeführt hast. + +??? abstract "Verzeichnisinhalt" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Das zeigt dir, dass die veröffentlichten Ergebnisse durch nachfolgende Ausführungen überschrieben werden, während die Aufgabenverzeichnisse unter `work/` erhalten bleiben. + +### Erkenntnisse + +Du weißt, wie man ein einfaches Nextflow-Script ausführt, seine Ausführung überwacht und seine Ausgaben findet. + +### Was kommt als Nächstes? + +Lerne, wie man ein grundlegendes Nextflow-Script liest und identifiziert, wie seine Komponenten mit seiner Funktionalität zusammenhängen. + +--- + +## 3. Das Hello World Workflow-Starter-Script untersuchen + +Was wir dort getan haben, war im Grunde, das Workflow-Script wie eine Black Box zu behandeln. +Jetzt, da wir gesehen haben, was es tut, öffnen wir die Box und schauen hinein. + +Unser Ziel hier ist nicht, die Syntax von Nextflow-Code auswendig zu lernen, sondern eine grundlegende Intuition zu entwickeln, was die Hauptkomponenten sind und wie sie organisiert sind. + +### 3.1. Die Gesamtstruktur des Codes untersuchen + +Du findest das `1-hello.nf`-Script in deinem aktuellen Verzeichnis, das `nextflow-run` sein sollte. Öffne es im Editor-Bereich. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline-Parameter + */ + params { + input: String + } + + workflow { + + main: + // Eine Begrüßung ausgeben + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Ein Nextflow-Workflow-Script enthält typischerweise eine oder mehrere **Prozess**-Definitionen, den **Workflow** selbst und einige optionale Blöcke wie **params** und **output**. + +Jeder **Prozess** beschreibt, welche Operation(en) der entsprechende Schritt in der Pipeline ausführen soll, während der **Workflow** die Datenflusslogik beschreibt, die die verschiedenen Schritte verbindet. + +Schauen wir uns zuerst den **Prozess**-Block genauer an, dann schauen wir uns den **Workflow**-Block an. + +### 3.2. Die `process`-Definition + +Der erste Code-Block beschreibt einen **Prozess**. +Die Prozessdefinition 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, der alles sein kann, was du in einem Befehlszeilen-Terminal ausführen könntest. + +```groovy title="1-hello.nf" linenums="3" +/* +* Verwende echo, um eine Begrüßung in eine Datei zu schreiben +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Hier haben wir einen **Prozess** namens `sayHello`, der eine **Eingabe**-Variable namens `greeting` nimmt und seine **Ausgabe** in eine Datei namens `output.txt` schreibt. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +Dies ist eine sehr minimale Prozessdefinition, die nur eine `input`-Definition, eine `output`-Definition und das auszuführende `script` enthält. + +Die `input`-Definition enthält den `val`-Qualifier, der Nextflow mitteilt, einen Wert irgendeiner Art zu erwarten (kann ein String, eine Zahl, was auch immer sein). + +Die `output`-Definition enthält den `path`-Qualifier, der Nextflow mitteilt, dass dies als Pfad behandelt werden soll (umfasst sowohl Verzeichnispfade als auch Dateien). + +### 3.3. Die `workflow`-Definition + +Der zweite Code-Block 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 und einem `publish:`-Block besteht. +Der `main:`-Block ist der Haupt-Body des Workflows und der `publish:`-Block listet die Ausgaben auf, die in das `results`-Verzeichnis veröffentlicht werden sollen. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // Eine Begrüßung ausgeben + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +In diesem Fall enthält der `main:`-Block einen Aufruf des `sayHello`-Prozesses und gibt ihm eine Eingabe namens `params.input` als Gruß. + +Wie wir gleich ausführlicher besprechen werden, enthält `params.input` den Wert, den wir dem `--input`-Parameter in unserer Befehlszeile gegeben haben. + +Der `publish:`-Block listet die Ausgabe des `sayHello()`-Prozessaufrufs auf, die er als `sayHello.out` bezeichnet und den Namen `first_output` gibt (das kann alles sein, was der Workflow-Autor möchte). + +Dies ist eine sehr minimale **Workflow**-Definition. +In einer realen Pipeline enthält der Workflow typischerweise mehrere Aufrufe von **Prozessen**, die durch **Channels** verbunden sind, und es können Standardwerte für die variablen Eingaben eingerichtet sein. + +Wir werden das in Teil 2 des Kurses behandeln. +Für jetzt schauen wir uns genauer an, wie unser Workflow Eingaben und Ausgaben handhabt. + +### 3.4. Das `params`-System der Befehlszeilenparameter + +Das `params.input`, das wir dem `sayHello()`-Prozessaufruf geben, ist ein raffiniertes Stück Nextflow-Code und lohnt sich, eine extra Minute darüber zu verbringen. + +Wie oben erwähnt, übergeben wir so den Wert des `--input`-Befehlszeilenparameters an den `sayHello()`-Prozessaufruf. +Tatsächlich reicht es aus, einfach `params.someParameterName` zu deklarieren, um dem Workflow einen Parameter namens `--someParameterName` von der Befehlszeile zu geben. + +Hier haben wir diese Parameterdeklaration formalisiert, indem wir einen `params`-Block eingerichtet haben, der den Typ der Eingabe angibt, die der Workflow erwartet (Nextflow 25.10.2 und später). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline-Parameter + */ +params { + input: String +} +``` + +Unterstützte Typen umfassen `String`, `Integer`, `Float`, `Boolean` und `Path`. + +!!! tip "Tipp" + + Workflow-Parameter, die mit dem `params`-System deklariert werden, nehmen immer zwei Bindestriche auf der Befehlszeile (`--`). + Das unterscheidet sie von Nextflow-Level-Parametern, die nur einen Bindestrich nehmen (`-`). + +### 3.5. Die `publish`-Direktive + +Am anderen Ende des Workflows haben wir bereits einen Blick auf den `publish:`-Block geworfen. +Das ist eine Hälfte des Ausgabehandhabungssystems; die andere Hälfte ist der `output`-Block, der sich unten befindet. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Das gibt an, dass die `first_output`-Ausgabe, die im `publish:`-Block aufgelistet ist, in ein Unterverzeichnis namens `1-hello` unter dem Standard-`results`-Ausgabeverzeichnis kopiert werden soll. + +Die Zeile `mode 'copy'` überschreibt das Standardverhalten des Systems, das darin besteht, einen symbolischen Link (oder Symlink) auf die ursprüngliche Datei im `work/`-Verzeichnis zu erstellen, anstatt einer richtigen Kopie. + +Es gibt mehr Optionen als hier angezeigt, um das Veröffentlichungsverhalten zu steuern; wir werden später einige behandeln. +Du wirst auch sehen, dass wenn ein Workflow mehrere Ausgaben generiert, jede auf diese Weise im `output`-Block aufgelistet wird. + +??? info "Ältere Syntax zum Veröffentlichen von Ausgaben mit `publishDir`" + + Bis vor kurzem war die etablierte Methode zum Veröffentlichen von Ausgaben, es auf der Ebene jedes einzelnen Prozesses mit einer `publishDir`-Direktive zu tun. + + Du wirst dieses Code-Muster überall in älteren Nextflow-Pipelines und Prozessmodulen finden, daher ist es wichtig, davon zu wissen. + + Anstatt einen `publish:`-Block im Workflow und einen `output`-Block auf oberster Ebene zu haben, würdest du eine `publishDir`-Zeile in der `sayHello`-Prozessdefinition sehen: + + ```groovy title="Syntax-Beispiel" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + Wir empfehlen jedoch nicht, dies in neuer Arbeit zu verwenden, da es in zukünftigen Versionen der Nextflow-Sprache irgendwann nicht mehr erlaubt sein wird. + +### Erkenntnisse + +Du weißt jetzt, wie ein einfacher Nextflow-Workflow strukturiert ist und wie die grundlegenden Komponenten mit seiner Funktionalität zusammenhängen. + +### Was kommt als Nächstes? + +Lerne, deine Workflow-Ausführungen bequem zu verwalten. + +--- + +## 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 des Workflow-Managements gibt, die dir das Leben erleichtern werden. + +Hier zeigen wir dir, wie du die `resume`-Funktion nutzt, wenn du denselben Workflow neu starten musst, wie du die Ausführungsprotokolle mit `nextflow log` überprüfst und wie du ältere Work-Verzeichnisse mit `nextflow clean` löschst. + +### 4.1. Einen Workflow mit `-resume` neu starten + +Manchmal möchtest du eine Pipeline erneut ausführen, die du zuvor bereits gestartet hast, ohne Arbeit zu wiederholen, die bereits erfolgreich abgeschlossen wurde. + +Nextflow hat eine Option namens `-resume`, die dir das ermöglicht. +Konkret werden in diesem Modus alle Prozesse, die bereits mit exakt demselben Code, denselben Einstellungen und Eingaben ausgeführt wurden, übersprungen. +Das bedeutet, Nextflow wird nur Prozesse ausführen, die du seit dem letzten Lauf hinzugefügt oder geändert hast, oder denen du neue Einstellungen oder Eingaben gibst. + +Es gibt zwei Hauptvorteile dabei: + +- Wenn du gerade dabei bist, eine Pipeline zu entwickeln, kannst du schneller iterieren, da du nur die Prozesse ausführen musst, an denen du aktiv arbeitest, um deine Änderungen zu testen. +- Wenn du eine Pipeline in der Produktion ausführst und etwas schief geht, kannst du in vielen Fällen das Problem beheben und die Pipeline neu starten, und sie wird vom Punkt des Fehlers aus 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: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Die Konsolenausgabe sollte vertraut aussehen, aber es gibt eine Sache, die ein bisschen anders ist als vorher. + +Suche nach dem `cached:`-Teil, der in der Prozessstatuszeile (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 hat. + +Du kannst auch sehen, dass der Work-Unterverzeichnis-Hash derselbe ist wie im vorherigen Lauf. +Nextflow zeigt dir buchstäblich auf die vorherige Ausführung und sagt "Das habe ich schon dort drüben gemacht." + +!!! tip "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 Protokoll vergangener Ausführungen überprüfen + +Immer wenn du einen Nextflow-Workflow startest, wird eine Zeile in eine Protokolldatei namens `history` geschrieben, unter einem versteckten Verzeichnis namens `.nextflow` im aktuellen Arbeitsverzeichnis. + +??? abstract "Dateiinhalt" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + ... + ``` + +Diese Datei gibt dir den Zeitstempel, Laufnamen, Status, Revisions-ID, Sitzungs-ID und die vollständige Befehlszeile für jeden Nextflow-Lauf, der aus dem aktuellen Arbeitsverzeichnis gestartet wurde. + +Eine bequemere Möglichkeit, auf diese Informationen zuzugreifen, ist der Befehl `nextflow log`. + +```bash +nextflow log +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + ... + ``` + +Das gibt den Inhalt der Protokolldatei im Terminal aus, ergänzt durch eine Kopfzeile. + +Du wirst bemerken, dass sich die Sitzungs-ID ä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 + +Wenn du viele Pipelines ausführst, können sich sehr viele Dateien über viele Unterverzeichnisse ansammeln. +Da die Unterverzeichnisse zufällig benannt sind, ist es schwierig, anhand ihrer Namen zu erkennen, welche älteren gegenüber neueren Läufen entsprechen. + +Glücklicherweise enthält Nextflow einen hilfreichen `clean`-Unterbefehl, der automatisch die Work-Unterverzeichnisse für vergangene Läufe löschen kann, die du nicht mehr benötigst. + +#### 4.3.1. Löschkriterien festlegen + +Es gibt mehrere [Optionen](https://www.nextflow.io/docs/latest/reference/cli.html#clean), um festzulegen, was gelöscht werden soll. + +Hier zeigen wir dir ein Beispiel, das alle Unterverzeichnisse von Läufen vor einem bestimmten Lauf löscht, der über seinen Laufnamen angegeben wird. + +Schau dir den letzten erfolgreichen Lauf an, bei dem du nicht `-resume` verwendet hast; in unserem Fall war der Laufname `backstabbing_swartz`. + +Der Laufname ist der maschinengenerierte zweiteilige String, der in eckigen Klammern in der `Launching (...)`-Konsolenausgabezeile angezeigt wird. +Du kannst auch das Nextflow-Protokoll verwenden, um einen Lauf basierend auf seinem Zeitstempel und/oder seiner Befehlszeile nachzuschlagen. + +#### 4.3.2. Einen Probelauf durchführen + +Zuerst verwenden wir das Probelauf-Flag `-n`, um zu überprüfen, was bei dem Befehl gelöscht wird: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Befehlsausgabe" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Deine Ausgabe wird andere Aufgabenverzeichnisnamen haben und möglicherweise eine andere Anzahl von Zeilen, aber sie sollte ähnlich wie das Beispiel aussehen. + +Wenn du keine Zeilen in der Ausgabe siehst, hast du entweder keinen gültigen Laufnamen angegeben oder es gibt keine vergangenen Läufe zum Löschen. Stelle sicher, dass du `backstabbing_swartz` im Beispielbefehl durch den entsprechenden letzten Laufnamen in deinem Protokoll änderst. + +#### 4.3.3. Mit dem Löschen fortfahren + +Wenn die Ausgabe wie erwartet aussieht und du mit dem Löschen fortfahren möchtest, führe den Befehl mit dem `-f`-Flag anstelle von `-n` erneut aus: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Befehlsausgabe" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Die Ausgabe sollte ähnlich wie vorher sein, aber jetzt sagt sie 'Removed' anstelle von 'Would remove'. +Beachte, dass dies nicht die zweistelligen Unterverzeichnisse (wie `eb/` oben) entfernt, aber ihren Inhalt leert. + +!!! warning "Warnung" + + Das Löschen von Work-Unterverzeichnissen von vergangenen Läufen entfernt sie aus Nextflows Cache und löscht alle Ausgaben, die in diesen Verzeichnissen gespeichert waren. + Das bedeutet, es bricht Nextflows Fähigkeit, die Ausführung fortzusetzen, ohne die entsprechenden Prozesse erneut auszuführen. + + Du bist verantwortlich dafür, alle Ausgaben zu sichern, die dir wichtig sind! Das ist der Hauptgrund, warum wir den `copy`-Modus anstelle des `symlink`-Modus für die `publish`-Direktive bevorzugen. + +### Erkenntnisse + +Du weißt, wie du eine Pipeline neu startest, ohne Schritte zu wiederholen, die bereits identisch ausgeführt wurden, das Ausführungsprotokoll überprüfst und den `nextflow clean`-Befehl verwendest, um alte Work-Verzeichnisse zu bereinigen. + +### Was kommt als Nächstes? + +Mach eine kleine Pause! Du hast gerade die Bausteine der Nextflow-Syntax und grundlegende Nutzungsanweisungen aufgenommen. + +Im nächsten Abschnitt dieses Trainings werden wir uns vier sukzessiv realistischere Versionen der Hello World-Pipeline ansehen, die demonstrieren werden, wie Nextflow dir ermöglicht, mehrere Eingaben effizient zu verarbeiten, Workflows auszuführen, die aus mehreren miteinander verbundenen Schritten bestehen, modulare Code-Komponenten zu nutzen und Container für größere Reproduzierbarkeit und Portabilität zu verwenden. + +--- + +## Quiz + +<quiz> +Was repräsentiert `[a3/7be2fa]` in der Konsolenausgabezeile `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`? +- [ ] Die Prozess-Versionsnummer +- [ ] Ein eindeutiger Lauf-Identifikator +- [x] Der abgekürzte Pfad zum Work-Verzeichnis der Aufgabe +- [ ] Die Prüfsumme der Ausgabedatei + +Mehr erfahren: [2.3. Die ursprüngliche Ausgabe und Protokolle im `work/`-Verzeichnis finden](#23-die-ursprungliche-ausgabe-und-protokolle-im-work-verzeichnis-finden) +</quiz> + +<quiz> +Was ist der Zweck der `.command.sh`-Datei in einem Aufgabenverzeichnis? +- [ ] Sie speichert die Konfigurationseinstellungen der Aufgabe +- [x] Sie zeigt den tatsächlichen Befehl, der vom Prozess ausgeführt wurde +- [ ] Sie enthält Fehlermeldungen von fehlgeschlagenen Aufgaben +- [ ] Sie listet Eingabedateien auf, die für die Aufgabe bereitgestellt wurden + +Mehr erfahren: [2.3. Die ursprüngliche Ausgabe und Protokolle im `work/`-Verzeichnis finden](#23-die-ursprungliche-ausgabe-und-protokolle-im-work-verzeichnis-finden) +</quiz> + +<quiz> +Was passiert mit veröffentlichten Ergebnissen, wenn du einen Workflow ohne `-resume` erneut ausführst? +- [ ] Sie werden in separaten Verzeichnissen mit Zeitstempel aufbewahrt +- [x] Sie werden von der neuen Ausführung überschrieben +- [ ] Nextflow verhindert das Überschreiben und schlägt fehl +- [ ] Sie werden automatisch gesichert + +Mehr erfahren: [2.4. Den Workflow mit verschiedenen Grüßen erneut ausführen](#24-den-workflow-mit-verschiedenen-grussen-erneut-ausfuhren) +</quiz> + +<quiz> +Was zeigt diese Konsolenausgabe an? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] Die Aufgabe ist fehlgeschlagen und wurde übersprungen +- [ ] Die Aufgabe wartet in einer Warteschlange +- [x] Nextflow hat Ergebnisse von einer vorherigen identischen Ausführung wiederverwendet +- [ ] Die Aufgabe wurde manuell abgebrochen + +Mehr erfahren: [4.1. Einen Workflow mit `-resume` neu starten](#41-einen-workflow-mit--resume-neu-starten) +</quiz> + +<quiz> +Wo speichert Nextflow den Ausführungsverlauf, den der Befehl `nextflow log` anzeigt? +- [ ] Im results-Verzeichnis +- [ ] Im work-Verzeichnis +- [x] In der `.nextflow/history`-Datei +- [ ] In `nextflow.config` + +Mehr erfahren: [4.2. Das Protokoll vergangener Ausführungen überprüfen](#42-das-protokoll-vergangener-ausfuhrungen-uberprufen) +</quiz> + +<quiz> +Was ist der Zweck des `params`-Blocks in einer Workflow-Datei? +- [ ] Um Prozess-Ressourcenanforderungen zu definieren +- [ ] Um den Executor zu konfigurieren +- [x] Um Workflow-Eingabeparameter zu deklarieren und zu typisieren +- [ ] Um Ausgabe-Veröffentlichungsoptionen anzugeben + +Mehr erfahren: [3.4. Das params-System der Befehlszeilenparameter](#34-das-params-system-der-befehlszeilenparameter) +</quiz> + +<quiz> +Was macht `mode 'copy'` im `output`-Block des Workflows? +- [ ] Erstellt ein Backup des work-Verzeichnisses +- [x] Erstellt eine vollständige Kopie der Dateien anstelle von symbolischen Links +- [ ] Kopiert das Workflow-Script zu results +- [ ] Aktiviert inkrementelles Datei-Kopieren + +Mehr erfahren: [3.5. Die publish-Direktive](#35-die-publish-direktive) +</quiz> + +<quiz> +Was ist das empfohlene Flag für den `nextflow clean`-Befehl, bevor tatsächlich Dateien gelöscht werden? +- [x] `-n` (Probelauf), um eine Vorschau dessen zu sehen, was gelöscht würde +- [ ] `-v` (verbose), um detaillierte Ausgabe zu sehen +- [ ] `-a` (all), um alle Verzeichnisse auszuwählen +- [ ] `-q` (quiet), um Warnungen zu unterdrücken + +Mehr erfahren: [4.3. Ältere Work-Verzeichnisse löschen](#43-altere-work-verzeichnisse-loschen) +</quiz> diff --git a/docs/de/docs/nextflow_run/02_pipeline.md b/docs/de/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..87a374a0fb --- /dev/null +++ b/docs/de/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1416 @@ +# Teil 2: Echte Pipelines ausführen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In Teil 1 dieses Kurses (Grundlegende Operationen ausführen) haben wir mit einem Beispiel-Workflow begonnen, der nur minimale Funktionen hatte, um die Code-Komplexität gering zu halten. +Zum Beispiel verwendete `1-hello.nf` einen Kommandozeilen-Parameter (`--input`), um jeweils einen einzelnen Wert zu übergeben. + +Allerdings verwenden die meisten realen Pipelines anspruchsvollere Funktionen, um eine effiziente Verarbeitung großer Datenmengen im großen Maßstab zu ermöglichen und mehrere Verarbeitungsschritte anzuwenden, die durch manchmal komplexe Logik miteinander verkettet sind. + +In diesem Teil des Trainings demonstrieren wir Schlüsselfunktionen realer Pipelines, indem wir erweiterte Versionen der ursprünglichen Hello World Pipeline ausprobieren. + +## 1. Eingabedaten aus einer Datei verarbeiten + +In einer realen Pipeline möchten wir typischerweise mehrere Datenpunkte (oder Datenreihen) verarbeiten, die in einer oder mehreren Eingabedateien enthalten sind. +Und wo immer möglich, möchten wir die Verarbeitung unabhängiger Daten parallel ausführen, um die Wartezeit für die Analyse zu verkürzen. + +Um zu demonstrieren, wie Nextflow das macht, haben wir eine CSV-Datei namens `greetings.csv` vorbereitet, die mehrere Eingabe-Grüße enthält und die Art von spaltenbasierten Daten nachahmt, die du in einer echten Datenanalyse verarbeiten möchtest. +Beachte, dass die Zahlen keine Bedeutung haben; sie dienen nur zur Veranschaulichung. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Wir haben auch eine verbesserte Version des ursprünglichen Workflows geschrieben, jetzt `2a-inputs.nf` genannt, die die CSV-Datei einliest, die Grüße extrahiert und jeden davon in eine separate Datei schreibt. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Lass uns zuerst den Workflow ausführen, und wir werden uns den relevanten Nextflow-Code danach ansehen. + +### 1.1. Den Workflow ausführen + +Führe den folgenden Befehl in deinem Terminal aus. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Spannenderweise scheint dies anzuzeigen, dass '3 von 3' Aufrufe für den process gemacht wurden, was ermutigend ist, da es drei Datenzeilen in der CSV gab, die wir als Eingabe bereitgestellt haben. +Dies deutet darauf hin, dass der `sayHello()` process dreimal aufgerufen wurde, einmal für jede Eingabezeile. + +### 1.2. Die veröffentlichten Ausgaben im `results`-Verzeichnis finden + +Schauen wir uns das 'results'-Verzeichnis an, um zu sehen, ob unser Workflow immer noch eine Kopie unserer Ausgaben dorthin schreibt. + +??? abstract "Verzeichnisinhalte" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Ja! Wir sehen ein neues Verzeichnis namens `2a-inputs` mit drei Ausgabedateien mit unterschiedlichen Namen, praktischerweise. + +Du kannst jede davon öffnen, um dich zu vergewissern, dass sie den entsprechenden Gruß-String enthält. + +??? abstract "Dateiinhalte" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Dies bestätigt, dass jeder Gruß in der Eingabedatei entsprechend verarbeitet wurde. + +### 1.3. Die ursprünglichen Ausgaben und Logs finden + +Du hast vielleicht bemerkt, dass die Konsolenausgabe oben nur auf ein task-Verzeichnis verwies. +Bedeutet das, dass alle drei Aufrufe von `sayHello()` innerhalb dieses einen task-Verzeichnisses ausgeführt wurden? + +#### 1.3.1. Das im Terminal angegebene task-Verzeichnis untersuchen + +Schauen wir uns dieses `8e/0eb066` task-Verzeichnis an. + +??? abstract "Verzeichnisinhalte" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Wir finden nur die Ausgabe, die einem der Grüße entspricht (sowie die Hilfsdateien, wenn wir die Anzeige versteckter Dateien aktivieren). + +Was passiert hier also? + +Standardmäßig schreibt das ANSI-Logging-System die Statusinformationen für alle Aufrufe desselben process in dieselbe Zeile. +Daher zeigte es uns nur einen der drei task-Verzeichnispfade (`8e/0eb066`) in der Konsolenausgabe. +Es gibt zwei weitere, die dort nicht aufgeführt sind. + +#### 1.3.2. Das Terminal mehr Details anzeigen lassen + +Wir können das Logging-Verhalten ändern, um die vollständige Liste der process-Aufrufe zu sehen, indem wir `-ansi-log false` zum Befehl wie folgt hinzufügen: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Diesmal sehen wir alle drei process-Ausführungen und ihre zugehörigen work-Unterverzeichnisse in der Ausgabe aufgelistet. +Das Deaktivieren des ANSI-Loggings verhinderte auch, dass Nextflow Farben in der Terminal-Ausgabe verwendete. + +Beachte, dass die Art und Weise, wie der Status gemeldet wird, zwischen den beiden Logging-Modi etwas unterschiedlich ist. +Im komprimierten Modus meldet Nextflow, ob Aufrufe erfolgreich abgeschlossen wurden oder nicht. +In diesem erweiterten Modus meldet es nur, dass sie übermittelt wurden. + +Dies bestätigt, dass der `sayHello()` process dreimal aufgerufen wird, und für jeden wird ein separates task-Verzeichnis erstellt. + +Wenn wir in jedes der dort aufgelisteten task-Verzeichnisse schauen, können wir überprüfen, dass jedes einem der Grüße entspricht. + +??? abstract "Verzeichnisinhalte" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Dies bestätigt, dass jeder process-Aufruf isoliert von allen anderen ausgeführt wird. +Das hat viele Vorteile, einschließlich der Vermeidung von Kollisionen, wenn der process Zwischendateien mit nicht-eindeutigen Namen erzeugt. + +!!! tip "Tipp" + + Bei einem komplexen Workflow oder einer großen Anzahl von Eingaben kann es etwas überwältigend werden, die vollständige Liste im Terminal ausgeben zu lassen, daher verwenden die Leute `-ansi-log false` normalerweise nicht im Routinebetrieb. + +### 1.4. Den Workflow-Code untersuchen + +Diese Version des Workflows ist also in der Lage, eine CSV-Datei mit Eingaben einzulesen, die Eingaben separat zu verarbeiten und die Ausgaben eindeutig zu benennen. + +Schauen wir uns an, was das im Workflow-Code ermöglicht. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline-Parameter + */ + params { + input: Path + } + + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Auch hier musst du die Code-Syntax nicht auswendig lernen, aber es ist gut zu lernen, Schlüsselkomponenten des Workflows zu erkennen, die wichtige Funktionalität bieten. + +#### 1.4.1. Die Eingabedaten aus der CSV laden + +Dies ist der interessanteste Teil: Wie haben wir von der Übernahme eines einzelnen Wertes von der Kommandozeile auf eine CSV-Datei umgestellt, sie geparst und die einzelnen Grüße verarbeitet, die sie enthält? + +In Nextflow machen wir das mit einem **channel**: einem Konstrukt, das entwickelt wurde, um Eingaben effizient zu handhaben und sie von einem Schritt zum nächsten in mehrstufigen Workflows zu transportieren, während es eingebaute Parallelität und viele zusätzliche Vorteile bietet. + +Lass es uns aufschlüsseln. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) +``` + +Dieser Code erstellt einen channel namens `greeting_ch`, der die CSV-Datei liest, sie parst und die erste Spalte aus jeder Zeile extrahiert. +Das Ergebnis ist ein channel, der `Hello`, `Bonjour` und `Holà` enthält. + +??? tip "Wie funktioniert das?" + + Hier ist, was diese Zeile auf Deutsch bedeutet: + + - `channel.fromPath` ist eine **channel factory**, die einen channel aus Dateipfad(en) erstellt + - `(params.input)` gibt an, dass der Dateipfad durch `--input` auf der Kommandozeile bereitgestellt wird + + Mit anderen Worten, diese Zeile sagt Nextflow: Nimm den mit `--input` angegebenen Dateipfad und bereite dich darauf vor, seinen Inhalt als Eingabedaten zu behandeln. + + Dann wenden die nächsten beiden Zeilen **Operatoren** an, die das eigentliche Parsen der Datei und das Laden der Daten in die entsprechende Datenstruktur durchführen: + + - `.splitCsv()` sagt Nextflow, dass es die CSV-Datei in ein Array parsen soll, das Zeilen und Spalten repräsentiert + - `.map { line -> line[0] }` sagt Nextflow, dass es nur das Element in der ersten Spalte aus jeder Zeile nehmen soll + + In der Praxis also, ausgehend von der folgenden CSV-Datei: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Haben wir das in ein Array transformiert, das so aussieht: + + ```txt title="Array-Inhalte" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + Und dann haben wir das erste Element aus jeder der drei Zeilen genommen und sie in einen Nextflow channel geladen, der jetzt enthält: `Hello`, `Bonjour` und `Holà`. + + Wenn du channels und Operatoren im Detail verstehen möchtest, einschließlich wie du sie selbst schreibst, siehe [Hello Nextflow Teil 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Den process für jeden Gruß aufrufen + +Als nächstes geben wir in der letzten Zeile des `main:`-Blocks des Workflows den geladenen `greeting_ch` channel als Eingabe für den `sayHello()` process an. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) +``` + +Dies sagt Nextflow, dass es den process einzeln auf jedes Element im channel ausführen soll, _d.h._ auf jeden Gruß. +Und weil Nextflow so clever ist, wird es diese process-Aufrufe parallel ausführen, wenn möglich, abhängig von der verfügbaren Recheninfrastruktur. + +So kannst du eine effiziente und skalierbare Verarbeitung vieler Daten (viele Proben oder Datenpunkte, was auch immer deine Forschungseinheit ist) mit vergleichsweise sehr wenig Code erreichen. + +#### 1.4.3. Wie die Ausgaben benannt werden + +Schließlich lohnt es sich, einen kurzen Blick auf den process-Code zu werfen, um zu sehen, wie wir die Ausgabedateien eindeutig benennen. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Du siehst, dass sich im Vergleich zur Version dieses process in `1-hello.nf` die Ausgabe-Deklaration und der relevante Teil des Befehls geändert haben, um den Gruß-Wert in den Ausgabedateinamen aufzunehmen. + +Dies ist eine Möglichkeit sicherzustellen, dass die Ausgabedateinamen nicht kollidieren, wenn sie im gemeinsamen results-Verzeichnis veröffentlicht werden. + +Und das ist die einzige Änderung, die wir innerhalb der process-Deklaration vornehmen mussten! + +### Zusammenfassung + +Du verstehst auf einem grundlegenden Niveau, wie channels und Operatoren uns ermöglichen, mehrere Eingaben effizient zu verarbeiten. + +### Was kommt als Nächstes? + +Entdecke, wie mehrstufige Workflows aufgebaut sind und wie sie funktionieren. + +--- + +## 2. Mehrstufige Workflows ausführen + +Die meisten realen Workflows umfassen mehr als einen Schritt. +Lass uns auf dem aufbauen, was wir gerade über channels gelernt haben, und schauen, wie Nextflow channels und Operatoren verwendet, um processes in einem mehrstufigen Workflow miteinander zu verbinden. + +Zu diesem Zweck stellen wir dir einen Beispiel-Workflow zur Verfügung, der drei separate Schritte miteinander verkettet und Folgendes demonstriert: + +1. Daten von einem process zum nächsten fließen lassen +2. Ausgaben von mehreren process-Aufrufen in einem einzigen process-Aufruf sammeln + +Konkret haben wir eine erweiterte Version des Workflows namens `2b-multistep.nf` erstellt, die jeden Eingabe-Gruß nimmt, ihn in Großbuchstaben umwandelt und dann alle großgeschriebenen Grüße in einer einzigen Ausgabedatei sammelt. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Wie zuvor werden wir den Workflow zuerst ausführen und dann den Code ansehen, um zu sehen, was neu ist. + +### 2.1. Den Workflow ausführen + +Führe den folgenden Befehl in deinem Terminal aus: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Du siehst, dass wie versprochen mehrere Schritte als Teil des Workflows ausgeführt wurden; die ersten beiden (`sayHello` und `convertToUpper`) wurden vermutlich auf jeden einzelnen Gruß ausgeführt, und der dritte (`collectGreetings`) wird nur einmal ausgeführt worden sein, auf den Ausgaben aller drei `convertToUpper`-Aufrufe. + +### 2.2. Die Ausgaben finden + +Lass uns überprüfen, dass das tatsächlich passiert ist, indem wir einen Blick in das `results`-Verzeichnis werfen. + +??? abstract "Verzeichnisinhalte" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Wie du sehen kannst, haben wir ein neues Verzeichnis namens `2b-multistep`, und es enthält einiges mehr Dateien als zuvor. +Einige der Dateien wurden in einem Unterverzeichnis namens `intermediates` gruppiert, während sich zwei Dateien auf der obersten Ebene befinden. + +Diese beiden sind die Endergebnisse des mehrstufigen Workflows. +Nimm dir eine Minute Zeit, um die Dateinamen anzusehen und ihren Inhalt zu überprüfen, um zu bestätigen, dass sie das sind, was du erwartest. + +??? abstract "Dateiinhalte" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +Die erste enthält unsere drei Grüße, großgeschrieben und wie versprochen in einer einzigen Datei gesammelt. +Die zweite ist eine Berichtsdatei, die einige Informationen über den Lauf zusammenfasst. + +### 2.3. Den Code untersuchen + +Schauen wir uns den Code an und identifizieren die Schlüsselmuster für mehrstufige Workflows. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Use a text replacement tool to convert the greeting to uppercase + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Da passiert viel, aber der offensichtlichste Unterschied im Vergleich zur vorherigen Version des Workflows ist, dass es jetzt mehrere process-Definitionen gibt und entsprechend mehrere process-Aufrufe im workflow-Block. + +Schauen wir uns das genauer an und sehen, ob wir die interessantesten Teile identifizieren können. + +#### 2.3.1. Workflow-Struktur visualisieren + +Wenn du VSCode mit der Nextflow-Erweiterung verwendest, kannst du ein hilfreiches Diagramm bekommen, das zeigt, wie die processes verbunden sind, indem du auf den kleinen `DAG preview`-Link klickst, der direkt über dem workflow-Block in jedem Nextflow-Script angezeigt wird. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Das gibt dir einen schönen Überblick darüber, wie die processes verbunden sind und was sie produzieren. + +Du siehst, dass wir zusätzlich zum ursprünglichen `sayHello` process jetzt auch `convertToUpper` und `collectGreetings` haben, die mit den Namen der processes übereinstimmen, die wir in der Konsolenausgabe gesehen haben. +Die beiden neuen process-Definitionen sind auf die gleiche Weise strukturiert wie der `sayHello` process, außer dass `collectGreetings` einen zusätzlichen Eingabe-Parameter namens `batch` nimmt und zwei Ausgaben produziert. + +Wir werden nicht im Detail auf den Code für jeden eingehen, aber wenn du neugierig bist, kannst du die Details in [Teil 2 von Hello Nextflow](../hello_nextflow/03_hello_workflow.md) nachschlagen. + +Für jetzt lass uns untersuchen, wie die processes miteinander verbunden sind. + +#### 2.3.2. Wie die processes verbunden sind + +Das wirklich Interessante hier ist, wie die process-Aufrufe im `main:`-Block des Workflows miteinander verkettet sind. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Du kannst sehen, dass der erste process-Aufruf, `sayHello(greeting_ch)`, unverändert ist. +Dann bezieht sich der nächste process-Aufruf, zu `convertToUpper`, auf die Ausgabe von `sayHello` als `sayHello.out`. + +Das Muster ist einfach: `processName.out` bezieht sich auf den Ausgabe-channel eines process, der direkt an den nächsten process übergeben werden kann. +So transportieren wir Daten von einem Schritt zum nächsten in Nextflow. + +#### 2.3.3. Ein process kann mehrere Eingaben nehmen + +Der dritte process-Aufruf, zu `collectGreetings`, ist etwas anders. + +```groovy title="2b-multistep.nf" linenums="77" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Du siehst, dass diesem Aufruf zwei Eingaben gegeben werden, `convertToUpper.out.collect()` und `params.batch`. +Wenn wir das `.collect()`-Teil für jetzt ignorieren, können wir das als `collectGreetings(input1, input2)` verallgemeinern. + +Das entspricht den beiden Eingabe-Deklarationen im process-Modul: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Wenn Nextflow das parst, wird es die erste Eingabe im Aufruf `path input_files` zuweisen und die zweite `val batch_name`. + +Jetzt weißt du also, dass ein process mehrere Eingaben nehmen kann, und wie der Aufruf im workflow-Block aussieht. + +Lass uns nun einen genaueren Blick auf diese erste Eingabe werfen, `convertToUpper.out.collect()`. + +#### 2.3.4. Was `collect()` im `collectGreetings`-Aufruf tut + +Um die Ausgabe von `sayHello` an `convertToUpper` zu übergeben, haben wir einfach auf den Ausgabe-channel von `sayHello` als `sayHello.out` verwiesen. Aber für den nächsten Schritt sehen wir einen Verweis auf `convertToUpper.out.collect()`. + +Was ist dieses `collect()`-Teil und was tut es? + +Es ist natürlich ein Operator. Genau wie die `splitCsv`- und `map`-Operatoren, die wir vorher kennengelernt haben. +Diesmal heißt der Operator `collect` und wird auf den Ausgabe-channel angewendet, der von `convertToUpper` produziert wird. + +Der `collect`-Operator wird verwendet, um die Ausgaben von mehreren Aufrufen desselben process zu sammeln und sie in ein einzelnes channel-Element zu verpacken. + +Im Kontext dieses Workflows nimmt er die drei großgeschriebenen Grüße im `convertToUpper.out` channel --die drei separate channel-Elemente sind und normalerweise in separaten Aufrufen vom nächsten process behandelt würden-- und verpackt sie in ein einzelnes Element. + +In praktischeren Begriffen: Wenn wir `collect()` nicht auf die Ausgabe von `convertToUpper()` anwenden würden, bevor wir sie an `collectGreetings()` füttern, würde Nextflow einfach `collectGreetings()` unabhängig auf jeden Gruß ausführen, was unser Ziel nicht erreichen würde. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +Im Gegensatz dazu erlaubt uns die Verwendung von `collect()`, alle separaten großgeschriebenen Grüße, die vom zweiten Schritt des Workflows produziert wurden, zu nehmen und sie alle zusammen einem einzigen Aufruf im dritten Schritt der Pipeline zuzuführen. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +So bekommen wir alle Grüße zurück in dieselbe Datei. + +Es gibt viele andere [Operatoren](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page), die verfügbar sind, um Transformationen auf den Inhalt von channels zwischen process-Aufrufen anzuwenden. + +Das gibt Pipeline-Entwicklern viel Flexibilität für die Anpassung der Flusslogik ihrer Pipeline. +Der Nachteil ist, dass es manchmal schwieriger machen kann, zu entziffern, was die Pipeline tut. + +#### 2.3.5. Ein Eingabe-Parameter kann einen Standardwert haben + +Du hast vielleicht bemerkt, dass `collectGreetings` eine zweite Eingabe nimmt, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Das übergibt einen CLI-Parameter namens `--batch` an den Workflow. +Allerdings haben wir beim Starten des Workflows vorhin keinen `--batch`-Parameter angegeben. + +Was passiert da? +Schau dir den `params`-Block an: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Es ist ein Standardwert im Workflow konfiguriert, also müssen wir ihn nicht angeben. +Aber wenn wir einen auf der Kommandozeile angeben, wird der von uns angegebene Wert anstelle des Standards verwendet. + +Probier es aus: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Befehlsausgabe" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Du solltest neue Endausgaben sehen, die mit deinem benutzerdefinierten Batch-Namen benannt sind. + +??? abstract "Verzeichnisinhalte" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Dies ist ein Aspekt der Eingabe-Konfiguration, den wir in Teil 3 ausführlicher behandeln werden, aber für jetzt ist das Wichtige zu wissen, dass Eingabe-Parameter Standardwerte haben können. + +#### 2.3.6. Ein process kann mehrere Ausgaben produzieren + +In der `collectGreetings` process-Definition sehen wir die folgenden Ausgabe-Deklarationen: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Auf die dann im `publish:`-Block mit dem mit `emit:` angegebenen Namen verwiesen wird: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Das macht es einfach, spezifische Ausgaben einzeln an andere processes im Workflow zu übergeben, in Kombination mit verschiedenen Operatoren. + +#### 2.3.7. Veröffentlichte Ausgaben können organisiert werden + +Im `output`-Block haben wir benutzerdefinierte Pfade verwendet, um Zwischenergebnisse zu gruppieren, um es einfacher zu machen, nur die Endausgaben des Workflows herauszupicken. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Es gibt anspruchsvollere Möglichkeiten, veröffentlichte Ausgaben zu organisieren; wir werden einige davon im Teil über Konfiguration ansprechen. + +!!! tip "Möchtest du mehr über das Erstellen von Workflows erfahren?" + + Für eine detaillierte Behandlung des Aufbaus mehrstufiger Workflows, siehe [Hello Nextflow Teil 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Zusammenfassung + +Du verstehst auf einem grundlegenden Niveau, wie mehrstufige Workflows unter Verwendung von channels und Operatoren aufgebaut werden und wie sie funktionieren. +Du hast auch gesehen, dass processes mehrere Eingaben nehmen und mehrere Ausgaben produzieren können, und dass diese auf strukturierte Weise veröffentlicht werden können. + +### Was kommt als Nächstes? + +Lerne, wie Nextflow Pipelines modularisiert werden können, um Code-Wiederverwendung und Wartbarkeit zu fördern. + +--- + +## 3. Modularisierte Pipelines ausführen + +Bisher bestanden alle Workflows, die wir uns angesehen haben, aus einer einzigen Workflow-Datei, die den gesamten relevanten Code enthielt. + +Allerdings profitieren reale Pipelines typischerweise davon, _modularisiert_ zu sein, was bedeutet, dass der Code in verschiedene Dateien aufgeteilt wird. +Das kann ihre Entwicklung und Wartung effizienter und nachhaltiger machen. + +Hier werden wir die häufigste Form der Code-Modularität in Nextflow demonstrieren, nämlich die Verwendung von **Modulen**. + +In Nextflow ist ein **Modul** eine einzelne process-Definition, die für sich allein in einer eigenständigen Code-Datei gekapselt ist. +Um ein Modul in einem Workflow zu verwenden, fügst du einfach eine einzeilige import-Anweisung zu deiner Workflow-Code-Datei hinzu; dann kannst du den process genauso in den Workflow integrieren, wie du es normalerweise tun würdest. +Das macht es möglich, process-Definitionen in mehreren Workflows wiederzuverwenden, ohne mehrere Kopien des Codes zu erzeugen. + +Bis jetzt haben wir Workflows ausgeführt, die alle ihre processes in einer monolithischen Code-Datei enthalten hatten. +Jetzt werden wir sehen, wie es aussieht, wenn die processes in einzelnen Modulen gespeichert sind. + +Wir haben natürlich wieder einen geeigneten Workflow für Demonstrationszwecke vorbereitet, genannt `2c-modules.nf`, zusammen mit einer Reihe von Modulen, die sich im `modules/`-Verzeichnis befinden. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Verzeichnisinhalte" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Du siehst, dass es vier Nextflow-Dateien gibt, jede nach einem der processes benannt. +Du kannst die `cowpy.nf`-Datei für jetzt ignorieren; wir kommen später dazu. + +### 3.1. Den Code untersuchen + +Diesmal werden wir zuerst den Code ansehen. +Beginne damit, die `2c-modules.nf` Workflow-Datei zu öffnen. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Du siehst, dass die Workflow-Logik genau dieselbe ist wie in der vorherigen Version des Workflows. +Allerdings ist der process-Code aus der Workflow-Datei verschwunden, und stattdessen gibt es `include`-Anweisungen, die auf separate Dateien unter `modules` verweisen. + +```groovy title="hello-modules.nf" linenums="3" +// Module einbinden +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Öffne eine dieser Dateien und du findest den Code für den entsprechenden process. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Verwende echo, um 'Hello World!' in eine Datei zu schreiben + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Wie du sehen kannst, hat sich der process-Code nicht geändert; er wurde nur in eine einzelne Modul-Datei kopiert, anstatt in der Haupt-Workflow-Datei zu sein. +Das Gleiche gilt für die anderen beiden processes. + +Also schauen wir uns an, wie es aussieht, diese neue Version auszuführen. + +### 3.2. Den Workflow ausführen + +Führe diesen Befehl in deinem Terminal aus, mit dem `-resume`-Flag: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Du wirst bemerken, dass alle process-Ausführungen erfolgreich aus dem cache geladen wurden, was bedeutet, dass Nextflow erkannt hat, dass es die angeforderte Arbeit bereits erledigt hat, obwohl der Code aufgeteilt wurde und die Haupt-Workflow-Datei umbenannt wurde. + +Nichts davon ist für Nextflow wichtig; was zählt, ist das Job-Script, das generiert wird, nachdem der gesamte Code zusammengezogen und ausgewertet wurde. + +!!! tip "Tipp" + + Es ist auch möglich, einen Abschnitt eines Workflows als 'Subworkflow' zu kapseln, der in eine größere Pipeline importiert werden kann, aber das liegt außerhalb des Umfangs dieses Kurses. + + Du kannst mehr über die Entwicklung zusammensetzbarer Workflows in der Side Quest über [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/) erfahren. + +### Zusammenfassung + +Du weißt, wie processes in eigenständigen Modulen gespeichert werden können, um Code-Wiederverwendung zu fördern und die Wartbarkeit zu verbessern. + +### Was kommt als Nächstes? + +Lerne, Container für die Verwaltung von Software-Abhängigkeiten zu verwenden. + +--- + +## 4. Containerisierte Software verwenden + +Bisher haben die Workflows, die wir als Beispiele verwendet haben, nur sehr grundlegende Textverarbeitungsoperationen mit UNIX-Tools ausgeführt, die in unserer Umgebung verfügbar sind. + +Allerdings erfordern reale Pipelines typischerweise spezialisierte Tools und Pakete, die standardmäßig in den meisten Umgebungen nicht enthalten sind. +Normalerweise müsstest du diese Tools installieren, ihre Abhängigkeiten verwalten und eventuelle Konflikte lösen. + +Das ist alles sehr mühsam und nervig. +Ein viel besserer Weg, dieses Problem anzugehen, ist die Verwendung von **Containern**. + +Ein **Container** ist eine leichtgewichtige, eigenständige, ausführbare Einheit von Software, die aus einem Container-**Image** erstellt wird und alles enthält, was zum Ausführen einer Anwendung benötigt wird, einschließlich Code, Systembibliotheken und Einstellungen. + +!!! tip "Tipp" + + Wir vermitteln dies mit der Technologie [Docker](https://www.docker.com/get-started/), aber Nextflow unterstützt auch [mehrere andere Container-Technologien](https://www.nextflow.io/docs/latest/container.html#). + +### 4.1. Einen Container direkt verwenden + +Zuerst versuchen wir, direkt mit einem Container zu interagieren. +Das wird helfen, dein Verständnis davon zu festigen, was Container sind, bevor wir sie in Nextflow verwenden. + +#### 4.1.1. Das Container-Image pullen + +Um einen Container zu verwenden, lädst du normalerweise ein Container-Image aus einer Container-Registry herunter oder "pullst" es, und führst dann das Container-Image aus, um eine Container-Instanz zu erstellen. + +Die allgemeine Syntax ist wie folgt: + +```bash title="Syntax" +docker pull '<container>' +``` + +- `docker pull` ist die Anweisung an das Container-System, ein Container-Image aus einem Repository zu pullen. +- `'<container>'` ist die URI-Adresse des Container-Images. + +Als Beispiel pullen wir ein Container-Image, das [cowpy](https://github.com/jeffbuttars/cowpy) enthält, eine Python-Implementierung eines Tools namens `cowsay`, das ASCII-Kunst generiert, um beliebige Texteingaben auf unterhaltsame Weise anzuzeigen. + +Es gibt verschiedene Repositories, in denen du veröffentlichte Container finden kannst. +Wir haben den [Seqera Containers](https://seqera.io/containers/) Dienst verwendet, um dieses Docker Container-Image aus dem `cowpy` Conda-Paket zu generieren: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Führe den vollständigen pull-Befehl aus: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Befehlsausgabe" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Das sagt dem System, das angegebene Image herunterzuladen. +Sobald der Download abgeschlossen ist, hast du eine lokale Kopie des Container-Images. + +#### 4.1.2. Den Container starten + +Container können als einmaliger Befehl ausgeführt werden, aber du kannst sie auch interaktiv verwenden, was dir eine Shell-Eingabeaufforderung innerhalb des Containers gibt und es dir ermöglicht, mit dem Befehl zu spielen. + +Die allgemeine Syntax ist wie folgt: + +```bash title="Syntax" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'` ist die Anweisung an das Container-System, eine Container-Instanz aus einem Container-Image zu starten und einen Befehl darin auszuführen. +- `--rm` sagt dem System, die Container-Instanz herunterzufahren, nachdem der Befehl abgeschlossen ist. + +Vollständig zusammengesetzt sieht der Container-Ausführungsbefehl so aus: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Führe diesen Befehl aus, und du solltest sehen, dass sich deine Eingabeaufforderung in etwas wie `(base) root@b645838b3314:/tmp#` ändert, was anzeigt, dass du dich jetzt innerhalb des Containers befindest. + +Du kannst das überprüfen, indem du `ls` ausführst, um Verzeichnisinhalte aufzulisten: + +```bash +ls / +``` + +??? success "Befehlsausgabe" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Du siehst, dass das Dateisystem innerhalb des Containers sich vom Dateisystem auf deinem Host-System unterscheidet. + +!!! tip "Tipp" + + Wenn du einen Container ausführst, ist er standardmäßig vom Host-System isoliert. + Das bedeutet, dass der Container auf keine Dateien auf dem Host-System zugreifen kann, es sei denn, du erlaubst es ihm ausdrücklich, indem du angibst, dass du ein Volume als Teil des `docker run`-Befehls mounten möchtest, mit der folgenden Syntax: + + ```bash title="Syntax" + -v <außerhalb_pfad>:<innerhalb_pfad> + ``` + + Das etabliert effektiv einen Tunnel durch die Container-Wand, den du verwenden kannst, um auf diesen Teil deines Dateisystems zuzugreifen. + + Das wird ausführlicher in [Teil 5 von Hello Nextflow](../hello_nextflow/05_hello_containers.md) behandelt. + +#### 4.1.3. Das `cowpy`-Tool ausführen + +Von innerhalb des Containers kannst du den `cowpy`-Befehl direkt ausführen. + +```bash +cowpy "Hello Containers" +``` + +??? success "Befehlsausgabe" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Das produziert ASCII-Kunst des Standard-Kuh-Charakters (oder 'Cowacter') mit einer Sprechblase, die den von uns angegebenen Text enthält. + +Jetzt, da du die grundlegende Verwendung getestet hast, kannst du versuchen, ihm einige Parameter zu geben. +Zum Beispiel sagt die Tool-Dokumentation, dass wir den Charakter mit `-c` setzen können. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Befehlsausgabe" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Diesmal zeigt die ASCII-Kunst-Ausgabe den Linux-Pinguin Tux, weil wir den Parameter `-c tux` angegeben haben. + +Da du dich innerhalb des Containers befindest, kannst du den cowpy-Befehl so oft ausführen, wie du möchtest, mit unterschiedlichen Eingabe-Parametern, ohne dir Sorgen machen zu müssen, irgendwelche Bibliotheken auf deinem System selbst zu installieren. + +??? tip "Andere verfügbare Charaktere" + + Verwende das '-c' Flag, um einen anderen Charakter auszuwählen, einschließlich: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Fühl dich frei, damit herumzuspielen. +Wenn du fertig bist, verlasse den Container mit dem `exit`-Befehl: + +```bash +exit +``` + +Du findest dich in deiner normalen Shell wieder. + +### 4.2. Einen Container in einem Workflow verwenden + +Wenn wir eine Pipeline ausführen, möchten wir Nextflow sagen können, welchen Container es bei jedem Schritt verwenden soll, und wichtigerweise möchten wir, dass es all die Arbeit handhabt, die wir gerade gemacht haben: den Container pullen, ihn starten, den Befehl ausführen und den Container herunterfahren, wenn er fertig ist. + +Gute Nachrichten: Das ist genau das, was Nextflow für uns tun wird. +Wir müssen nur einen Container für jeden process angeben. + +Um zu demonstrieren, wie das funktioniert, haben wir eine weitere Version unseres Workflows erstellt, die `cowpy` auf der Datei mit den gesammelten Grüßen ausführt, die im dritten Schritt produziert wurde. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Das sollte eine Datei ausgeben, die die ASCII-Kunst mit den drei Grüßen in der Sprechblase enthält. + +#### 4.2.1. Den Code untersuchen + +Der Workflow ist sehr ähnlich zum vorherigen, plus der extra Schritt, um `cowpy` auszuführen. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Module einbinden + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // Einen Channel für Eingaben aus einer CSV-Datei erstellen + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // Eine Begrüßung ausgeben + sayHello(greeting_ch) + // Die Begrüßung in Großbuchstaben umwandeln + convertToUpper(sayHello.out) + // Alle Begrüßungen in einer Datei sammeln + collectGreetings(convertToUpper.out.collect(), params.batch) + // ASCII-Kunst der Begrüßungen mit cowpy generieren + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Du siehst, dass dieser Workflow einen `cowpy` process aus einer Modul-Datei importiert und ihn auf der Ausgabe des `collectGreetings()`-Aufrufs ausführt, plus einem Eingabe-Parameter namens `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// ASCII-Kunst mit cowpy generieren +cowpy(collectGreetings.out, params.character) +``` + +Der `cowpy` process, der den cowpy-Befehl zum Generieren von ASCII-Kunst umhüllt, ist im `cowpy.nf`-Modul definiert. + +??? full-code "Vollständige Code-Datei" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Der `cowpy` process erfordert zwei Eingaben: den Pfad zu einer Eingabedatei, die den Text enthält, der in die Sprechblase kommt (`input_file`), und einen Wert für die character-Variable. + +Wichtig ist, dass er auch die Zeile `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'` enthält, die auf die Container-URI verweist, die wir vorher verwendet haben. + +#### 4.2.2. Überprüfen, dass Docker in der Konfiguration aktiviert ist + +Wir werden Teil 3 dieses Trainingskurses etwas vorwegnehmen, indem wir die `nextflow.config` Konfigurationsdatei vorstellen, die eine der Hauptmöglichkeiten ist, die Nextflow bietet, um die Workflow-Ausführung zu konfigurieren. +Wenn eine Datei namens `nextflow.config` im aktuellen Verzeichnis vorhanden ist, wird Nextflow sie automatisch laden und jede darin enthaltene Konfiguration anwenden. + +Zu diesem Zweck haben wir eine `nextflow.config`-Datei mit einer einzigen Codezeile eingefügt, die Docker aktiviert. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Diese Konfiguration sagt Nextflow, Docker für jeden process zu verwenden, der einen kompatiblen Container angibt. + +!!! tip "Tipp" + + Es ist technisch möglich, die Docker-Ausführung von der Kommandozeile aus zu aktivieren, auf Basis jeder Ausführung, unter Verwendung des Parameters `-with-docker <container>`. + Allerdings erlaubt uns das nur, einen Container für den gesamten Workflow anzugeben, während der Ansatz, den wir dir gerade gezeigt haben, es uns ermöglicht, einen anderen Container pro process anzugeben. + Letzteres ist viel besser für Modularität, Code-Wartung und Reproduzierbarkeit. + +#### 4.2.3. Den Workflow ausführen + +Nur zur Rekapitulation, das ist, was wir gleich ausführen werden: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Denkst du, es wird funktionieren? + +Lass uns den Workflow mit dem `-resume`-Flag ausführen und angeben, dass wir den Charakter als turkey haben wollen. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +Die ersten drei Schritte wurden aus dem cache geladen, da wir sie zuvor schon ausgeführt haben, aber der `cowpy` process ist neu, also wird der tatsächlich ausgeführt. + +Du kannst die Ausgabe des `cowpy`-Schritts im `results`-Verzeichnis finden. + +??? abstract "Dateiinhalte" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Du siehst, dass der Charakter alle Grüße sagt, da er auf der Datei mit den gesammelten großgeschriebenen Grüßen ausgeführt wurde. + +Noch wichtiger ist, dass wir das als Teil unserer Pipeline ausführen konnten, ohne eine richtige Installation von cowpy und all seinen Abhängigkeiten machen zu müssen. +Und wir können jetzt die Pipeline mit Mitarbeitern teilen und sie auf ihrer Infrastruktur ausführen lassen, ohne dass sie etwas installieren müssen, abgesehen von Docker oder einer seiner Alternativen (wie Singularity/Apptainer), wie oben erwähnt. + +#### 4.2.4. Untersuchen, wie Nextflow die containerisierte Aufgabe gestartet hat + +Als abschließende Coda zu diesem Abschnitt, schauen wir uns das work-Unterverzeichnis für einen der `cowpy` process-Aufrufe an, um etwas mehr Einblick zu bekommen, wie Nextflow mit Containern unter der Haube arbeitet. + +Überprüfe die Ausgabe deines `nextflow run`-Befehls, um den Pfad zum work-Unterverzeichnis für den `cowpy` process zu finden. +Wenn wir uns ansehen, was wir für den oben gezeigten Lauf bekommen haben, beginnt die Konsolen-Log-Zeile für den `cowpy` process mit `[7f/caf718]`. +Das entspricht dem folgenden abgekürzten Verzeichnispfad: `work/7f/caf718`. + +In diesem Verzeichnis findest du die `.command.run`-Datei, die alle Befehle enthält, die Nextflow in deinem Namen im Verlauf der Pipeline-Ausführung ausgeführt hat. + +??? abstract "Dateiinhalte" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + ... + ``` + +### Zusammenfassung + +Du weißt, wie man Containern für die Verwaltung von Software-Abhängigkeiten in Nextflow Pipelines verwendet, und wie man sie sowohl direkt als auch innerhalb eines Workflows ausführt. + +### Was kommt als Nächstes? + +Lerne, wie du die Konfiguration deiner Workflow-Ausführungen anpassen kannst, um verschiedene Rechen-Plattformen zu unterstützen und die Reproduzierbarkeit deiner Analysen zu verbessern. diff --git a/docs/de/docs/nextflow_run/03_config.md b/docs/de/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..9a1b22bfb4 --- /dev/null +++ b/docs/de/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Teil 3: Ausführungskonfiguration + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dieser Abschnitt wird erkunden, wie man die Konfiguration einer Nextflow Pipeline verwaltet, um ihr Verhalten anzupassen, sie an verschiedene Umgebungen anzupassen und die Ressourcennutzung zu optimieren - _ohne eine einzige Zeile des Workflow-Codes selbst zu ändern_. + +Es gibt mehrere Möglichkeiten, dies zu tun, die kombiniert werden können und gemäß der [hier](https://www.nextflow.io/docs/latest/config.html) beschriebenen Rangfolge interpretiert werden. + +In diesem Teil des Kurses werden wir dir den einfachsten und gebräuchlichsten Konfigurationsdatei-Mechanismus zeigen, die `nextflow.config`-Datei, die du bereits im Abschnitt über Container in Teil 2 kennengelernt hast. + +Wir werden wesentliche Komponenten der Nextflow-Konfiguration durchgehen, wie process-Direktiven, executors, profiles und Parameter-Dateien. +Indem du lernst, diese Konfigurationsoptionen effektiv zu nutzen, kannst du die Flexibilität, Skalierbarkeit und Leistung von Nextflow Pipelines voll ausschöpfen. + +Um diese Konfigurationselemente zu üben, werden wir eine frische Kopie des Workflows ausführen, den wir zuletzt am Ende von Teil 2 dieses Trainingskurses ausgeführt haben, umbenannt in `3-main.nf`. + +Wenn du mit der Hello Pipeline nicht vertraut bist oder eine Auffrischung gebrauchen könntest, siehe [diese Info-Seite](../info/hello_pipeline.md). + +--- + +## 1. Workflow-Eingabe-Parameter verwalten + +??? example "Szenario" + + Du hast eine Pipeline heruntergeladen und möchtest sie wiederholt mit denselben Eingabedateien und Einstellungen ausführen, aber du möchtest nicht jedes Mal alle Parameter eintippen. + Oder vielleicht richtest du die Pipeline für einen Kollegen ein, der sich nicht wohl mit Kommandozeilen-Argumenten fühlt. + +Wir beginnen mit einem Aspekt der Konfiguration, der einfach eine Erweiterung dessen ist, womit wir bisher gearbeitet haben: die Verwaltung von Eingabe-Parametern. + +Derzeit ist unser Workflow so eingerichtet, dass er mehrere Parameter-Werte über die Kommandozeile akzeptiert, die in einem `params`-Block im Workflow-Script selbst deklariert sind. +Einer hat einen Standardwert, der als Teil seiner Deklaration gesetzt ist. + +Allerdings möchtest du vielleicht Standardwerte für alle setzen oder den bestehenden Standard überschreiben, ohne entweder Parameter auf der Kommandozeile angeben oder die Originaldatei ändern zu müssen. + +Es gibt mehrere Möglichkeiten, das zu tun; wir werden dir drei grundlegende Wege zeigen, die sehr häufig verwendet werden. + +### 1.1. Werte in `nextflow.config` einrichten + +Das ist der einfachste Ansatz, obwohl er möglicherweise am wenigsten flexibel ist, da die Haupt-`nextflow.config`-Datei nichts ist, was du für jeden Lauf bearbeiten möchtest. +Aber es hat den Vorteil, die Anliegen der _Deklaration_ der Parameter im Workflow (was definitiv dorthin gehört) von der Bereitstellung von _Standardwerten_ zu trennen, die eher in einer Konfigurationsdatei zu Hause sind. + +Lass uns das in zwei Schritten machen. + +#### 1.1.1. Einen `params`-Block in der Konfigurationsdatei erstellen + +Nimm die folgenden Code-Änderungen in der `nextflow.config`-Datei vor: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Beachte, dass wir nicht einfach den `params`-Block vom Workflow in die Konfigurationsdatei kopiert haben. +Für den `batch`-Parameter, der bereits einen Standardwert deklariert hatte, ist die Syntax etwas anders. +In der Workflow-Datei ist das eine typisierte Deklaration. +In der Konfiguration sind das Wertzuweisungen. + +Technisch reicht das aus, um die noch in der Workflow-Datei angegebenen Standardwerte zu überschreiben. +Du könntest den Standardwert für `batch` ändern und den Workflow ausführen, um dich zu vergewissern, dass der in der Konfigurationsdatei gesetzte Wert den in der Workflow-Datei gesetzten überschreibt. + +Aber im Sinne davon, die Konfiguration vollständig in die Konfigurationsdatei zu verschieben, lass uns diesen Standardwert ganz aus der Workflow-Datei entfernen. + +#### 1.1.2. Den Standardwert für `batch` in der Workflow-Datei entfernen + +Nimm die folgende Code-Änderung an der `3-main.nf` Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Vorher" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline-Parameter + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Jetzt setzt die Workflow-Datei selbst keine Standardwerte mehr für diese Parameter. + +#### 1.1.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, ohne irgendwelche Parameter in der Kommandozeile anzugeben. + +```bash +nextflow run 3-main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Das produziert immer noch dieselbe Ausgabe wie zuvor. + +Die finale ASCII-Kunst-Ausgabe befindet sich im `results/3-main/`-Verzeichnis unter dem Namen `cowpy-COLLECTED-batch-output.txt`, wie zuvor. + +??? abstract "Dateiinhalte" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funktional hat diese Verschiebung nichts geändert, aber konzeptionell ist es etwas sauberer, die Standardwerte in der Konfigurationsdatei zu setzen. + +### 1.2. Eine lauf-spezifische Konfigurationsdatei verwenden + +??? example "Szenario" + + Du möchtest mit verschiedenen Einstellungen experimentieren, ohne deine Haupt-Konfigurationsdatei zu ändern. + +Du kannst das tun, indem du eine neue `nextflow.config`-Datei in einem Unterverzeichnis erstellst, das du als Arbeitsverzeichnis für deine Experimente verwenden wirst. + +#### 1.2.1. Das Arbeitsverzeichnis mit einer leeren Konfiguration erstellen + +Lass uns beginnen, indem wir ein neues Verzeichnis erstellen und hineinwechseln: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Dann erstelle eine leere Konfigurationsdatei in diesem Verzeichnis: + +```bash +touch nextflow.config +``` + +Das erzeugt eine leere Datei. + +#### 1.2.2. Die experimentelle Konfiguration einrichten + +Öffne jetzt die neue Datei und füge die Parameter hinzu, die du anpassen möchtest: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Beachte, dass der Pfad zur Eingabedatei die Verzeichnisstruktur widerspiegeln muss. + +#### 1.2.3. Die Pipeline ausführen + +Wir können jetzt unsere Pipeline von innerhalb unseres neuen Arbeitsverzeichnisses ausführen. +Stelle sicher, den Pfad entsprechend anzupassen! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Das wird neue Verzeichnisse unter `tux-run/` erstellen, einschließlich `tux-run/work/` und `tux-run/results/`. + +In diesem Lauf kombiniert Nextflow die `nextflow.config` in unserem aktuellen Verzeichnis mit der `nextflow.config` im Stammverzeichnis der Pipeline und überschreibt dadurch den Standard-Charakter (turkey) mit dem tux-Charakter. + +Die finale Ausgabedatei sollte den tux-Charakter enthalten, der die Grüße sagt. + +??? abstract "Dateiinhalte" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Das war's; jetzt hast du einen Raum zum Experimentieren, ohne deine 'normale' Konfiguration zu ändern. + +!!! warning "Warnung" + + Stelle sicher, dass du zum vorherigen Verzeichnis zurückwechselst, bevor du zum nächsten Abschnitt übergehst! + + ```bash + cd .. + ``` + +Jetzt schauen wir uns eine weitere nützliche Möglichkeit an, Parameter-Werte zu setzen. + +### 1.3. Eine Parameter-Datei verwenden + +??? example "Szenario" + + Du musst exakte Ausführungs-Parameter mit einem Mitarbeiter teilen oder sie für eine Publikation aufzeichnen. + +Der Unterverzeichnis-Ansatz funktioniert großartig zum Experimentieren, aber er erfordert etwas Einrichtung und verlangt, dass du Pfade entsprechend anpasst. +Es gibt einen einfacheren Ansatz für den Fall, dass du deine Pipeline mit einem bestimmten Satz von Werten ausführen oder jemand anderem ermöglichen möchtest, dies mit minimalem Aufwand zu tun. + +Nextflow erlaubt uns, Parameter über eine Parameter-Datei im YAML- oder JSON-Format anzugeben, was es sehr bequem macht, alternative Sätze von Standardwerten sowie lauf-spezifische Parameter-Werte zu verwalten und zu verteilen. + +#### 1.3.1. Die Beispiel-Parameter-Datei untersuchen + +Um das zu demonstrieren, stellen wir eine Beispiel-Parameter-Datei im aktuellen Verzeichnis bereit, genannt `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Diese Parameter-Datei enthält ein Schlüssel-Wert-Paar für jede der Eingaben, die wir angeben möchten. +Beachte die Verwendung von Doppelpunkten (`:`) anstelle von Gleichheitszeichen (`=`), wenn du die Syntax mit der Konfigurationsdatei vergleichst. +Die config-Datei ist in Groovy geschrieben, während die Parameter-Datei in YAML geschrieben ist. + +!!! info "Hinweis" + + Wir stellen auch eine JSON-Version der Parameter-Datei als Beispiel bereit, aber wir werden hier nicht damit ausführen. + Fühl dich frei, diese auf eigene Faust auszuprobieren. + +#### 1.3.2. Die Pipeline ausführen + +Um den Workflow mit dieser Parameter-Datei auszuführen, füge einfach `-params-file <dateiname>` zum Basis-Befehl hinzu. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Die finale Ausgabedatei sollte den stegosaurus-Charakter enthalten, der die Grüße sagt. + +??? abstract "Dateiinhalte" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Die Verwendung einer Parameter-Datei mag übertrieben erscheinen, wenn du nur ein paar Parameter angeben musst, aber einige Pipelines erwarten Dutzende von Parametern. +In diesen Fällen erlaubt uns die Verwendung einer Parameter-Datei, Parameter-Werte zur Laufzeit bereitzustellen, ohne massive Kommandozeilen eintippen zu müssen und ohne das Workflow-Script zu ändern. + +Es macht es auch einfacher, Sätze von Parametern an Mitarbeiter zu verteilen oder als Zusatzinformationen für eine Publikation zum Beispiel. +Das macht deine Arbeit für andere reproduzierbarer. + +### Zusammenfassung + +Du weißt, wie du wichtige Konfigurationsoptionen für die Verwaltung von Workflow-Eingaben nutzen kannst. + +### Was kommt als Nächstes? + +Lerne, wie du verwalten kannst, wo und wie deine Workflow-Ausgaben veröffentlicht werden. + +--- + +## 2. Workflow-Ausgaben verwalten + +??? example "Szenario" + + Deine Pipeline veröffentlicht Ausgaben in ein fest codiertes Verzeichnis, aber du möchtest die Ergebnisse nach Projekt- oder Experimentnamen organisieren, ohne jedes Mal den Workflow-Code bearbeiten zu müssen. + +Der Workflow, den wir geerbt haben, verwendet Pfade für Workflow-Level-Ausgabe-Deklarationen, was nicht besonders flexibel ist und viel Wiederholung beinhaltet. + +Schauen wir uns ein paar gängige Möglichkeiten an, wie du das konfigurieren könntest, um flexibler zu sein. + +### 2.1. Den `outputDir`-Verzeichnisnamen anpassen + +Jede Version des Workflows, die wir bisher ausgeführt haben, hat ihre Ausgaben in ein anderes Unterverzeichnis veröffentlicht, das in den Ausgabe-Definitionen fest codiert ist. + +Lass uns das ändern, um einen benutzer-konfigurierbaren Parameter zu verwenden. +Wir könnten einen ganz neuen Parameter dafür erstellen, aber lass uns den `batch`-Parameter verwenden, da er direkt verfügbar ist. + +#### 2.1.1. Einen Wert für `outputDir` in der Konfigurationsdatei setzen + +Der Pfad, den Nextflow zum Veröffentlichen von Ausgaben verwendet, wird durch die `outputDir`-Option gesteuert. +Um den Pfad für alle Ausgaben zu ändern, kannst du in der `nextflow.config`-Konfigurationsdatei einen Wert für diese Option setzen. + +Füge den folgenden Code zur `nextflow.config`-Datei hinzu: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline-Parameter + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Das wird den eingebauten Standardpfad `results/` durch `results/` plus dem Wert des `batch`-Parameters als Unterverzeichnis ersetzen. +Du könntest auch den `results`-Teil ändern, wenn du möchtest. + +Für eine temporäre Änderung könntest du diese Option von der Kommandozeile aus setzen, indem du den `-output-dir`-Parameter in deinem Befehl verwendest (aber dann könntest du nicht den `batch`-Parameter-Wert verwenden). + +#### 2.1.2. Den wiederholten Teil des fest codierten Pfades entfernen + +Wir haben immer noch ein Unterverzeichnis fest codiert in den Ausgabe-Optionen, also lass uns das jetzt loswerden. + +Nimm die folgenden Code-Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +Wir hätten auch einfach `${params.batch}` zu jedem Pfad hinzufügen können, anstatt den `outputDir`-Standard zu ändern, aber das ist prägnanter. + +#### 2.1.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen auf `outdir` von der Kommandozeile setzen. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Das produziert immer noch dieselbe Ausgabe wie zuvor, außer dass wir unsere Ausgaben diesmal unter `results/outdir/` finden. + +??? abstract "Verzeichnisinhalte" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Du kannst diesen Ansatz mit benutzerdefinierten Pfad-Definitionen kombinieren, um jede gewünschte Verzeichnishierarchie zu konstruieren. + +### 2.2. Ausgaben nach process organisieren + +Eine beliebte Möglichkeit, Ausgaben weiter zu organisieren, ist es nach process zu tun, _d.h._ Unterverzeichnisse für jeden in der Pipeline ausgeführten process zu erstellen. + +#### 2.2.1. Die Ausgabe-Pfade durch einen Verweis auf process-Namen ersetzen + +Alles, was du tun musst, ist den Namen des process als `<task>.name` in der Ausgabe-Pfad-Deklaration zu referenzieren. + +Nimm die folgenden Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Vorher" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Das entfernt die verbleibenden fest codierten Elemente aus der Ausgabe-Pfad-Konfiguration. + +#### 2.2.2. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen auf `pnames` von der Kommandozeile setzen. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Das produziert immer noch dieselbe Ausgabe wie zuvor, außer dass wir unsere Ausgaben diesmal unter `results/pnames/` finden, und sie sind nach process gruppiert. + +??? abstract "Verzeichnisinhalte" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Beachte, dass wir hier die Unterscheidung zwischen `intermediates` versus finalen Ausgaben auf der obersten Ebene gelöscht haben. +Du könntest natürlich diese Ansätze mischen und kombinieren, zum Beispiel indem du den Pfad der ersten Ausgabe als `intermediates/${sayHello.name}` setzt. + +### 2.3. Den publish-Modus auf Workflow-Ebene setzen + +Schließlich können wir im Sinne der Reduzierung der Menge an sich wiederholendem Code die pro-Ausgabe `mode`-Deklarationen durch eine einzelne Zeile in der Konfiguration ersetzen. + +#### 2.3.1. `workflow.output.mode` zur Konfigurationsdatei hinzufügen + +Füge den folgenden Code zur `nextflow.config`-Datei hinzu: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Genau wie bei der `outputDir`-Option würde es ausreichen, `workflow.output.mode` einen Wert in der Konfigurationsdatei zu geben, um zu überschreiben, was in der Workflow-Datei gesetzt ist, aber lass uns den unnötigen Code trotzdem entfernen. + +#### 2.3.2. Den output-Modus aus der Workflow-Datei entfernen + +Nimm die folgenden Änderungen in der Workflow-Datei vor: + +=== "Nachher" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Vorher" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +Das ist prägnanter, nicht wahr? + +#### 2.3.3. Die Pipeline ausführen + +Lass uns testen, dass es korrekt funktioniert, indem wir den Batch-Namen auf `outmode` von der Kommandozeile setzen. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Das produziert immer noch dieselbe Ausgabe wie zuvor, außer dass wir unsere Ausgaben diesmal unter `results/outmode/` finden. +Es sind immer noch alles echte Kopien, keine Symlinks. + +??? abstract "Verzeichnisinhalte" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Der Hauptgrund, warum du vielleicht immer noch die pro-Ausgabe-Art des Setzens des mode verwenden möchtest, ist, wenn du innerhalb desselben Workflows mischen und kombinieren möchtest, _d.h._ einige Ausgaben kopiert und einige per Symlink verlinkt haben möchtest. + +Es gibt viele andere Optionen, die du auf diese Weise anpassen kannst, aber hoffentlich gibt dir das einen Eindruck von der Bandbreite der Optionen und wie du sie effektiv nutzen kannst, um deinen Präferenzen zu entsprechen. + +### Zusammenfassung + +Du weißt, wie du die Benennung und Struktur der Verzeichnisse kontrollieren kannst, in denen deine Ausgaben veröffentlicht werden, sowie den Workflow-Ausgabe-Veröffentlichungsmodus. + +### Was kommt als Nächstes? + +Lerne, wie du deine Workflow-Konfiguration an deine Rechenumgebung anpassen kannst, beginnend mit der Software-Paketierungstechnologie. + +--- + +## 3. Eine Software-Paketierungstechnologie auswählen + +Bisher haben wir Konfigurationselemente betrachtet, die steuern, wie Eingaben hineingehen und wo Ausgaben herauskommen. Jetzt ist es an der Zeit, uns spezieller darauf zu konzentrieren, deine Workflow-Konfiguration an deine Rechenumgebung anzupassen. + +Der erste Schritt auf diesem Weg ist anzugeben, woher die Software-Pakete kommen werden, die in jedem Schritt ausgeführt werden. +Sind sie bereits in der lokalen Rechenumgebung installiert? +Müssen wir Images abrufen und sie über ein Container-System ausführen? +Oder müssen wir Conda-Pakete abrufen und eine lokale Conda-Umgebung erstellen? + +Im allerersten Teil dieses Trainingskurses (Teile 1-4) haben wir in unserem Workflow einfach lokal installierte Software verwendet. +Dann haben wir in Teil 5 Docker-Container und die `nextflow.config`-Datei eingeführt, die wir verwendet haben, um die Verwendung von Docker-Containern zu aktivieren. + +Jetzt schauen wir uns an, wie wir eine alternative Software-Paketierungsoption über die `nextflow.config`-Datei konfigurieren können. + +### 3.1. Docker deaktivieren und Conda in der config-Datei aktivieren + +??? example "Szenario" + + Du verschiebst deine Pipeline auf einen HPC-Cluster, wo Docker aus Sicherheitsgründen nicht erlaubt ist. + Der Cluster unterstützt Singularity und Conda, also musst du deine Konfiguration entsprechend umstellen. + +Nextflow unterstützt mehrere Container-Technologien einschließlich Singularity (das auf HPC weiter verbreitet ist), sowie Software-Paketmanager wie Conda. + +Wir können unsere Konfigurationsdatei ändern, um Conda anstelle von Docker zu verwenden. +Dazu setzen wir den Wert von `docker.enabled` auf `false` und fügen eine Direktive hinzu, die die Verwendung von Conda aktiviert: + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Das wird Nextflow erlauben, Conda-Umgebungen für processes zu erstellen und zu nutzen, die Conda-Pakete angegeben haben. +Das bedeutet, dass wir jetzt eines davon zu unserem `cowpy` process hinzufügen müssen! + +### 3.2. Ein Conda-Paket in der process-Definition angeben + +Wir haben bereits die URI für ein Conda-Paket abgerufen, das das `cowpy`-Tool enthält: `conda-forge::cowpy==1.1.5` + +Jetzt fügen wir die URI zur `cowpy` process-Definition hinzu, indem wir die `conda`-Direktive verwenden: + +=== "Nachher" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Vorher" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Um das klarzustellen, wir _ersetzen_ nicht die `docker`-Direktive, wir _fügen_ eine alternative Option hinzu. + +!!! tip "Tipp" + + Es gibt einige verschiedene Möglichkeiten, die URI für ein bestimmtes Conda-Paket zu bekommen. + Wir empfehlen, die [Seqera Containers](https://seqera.io/containers/) Suchabfrage zu verwenden, die dir eine URI gibt, die du kopieren und einfügen kannst, selbst wenn du nicht planst, einen Container daraus zu erstellen. + +### 3.3. Den Workflow ausführen, um zu verifizieren, dass er Conda verwenden kann + +Lass es uns ausprobieren. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Befehlsausgabe" + + ```console title="Ausgabe" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Das sollte ohne Probleme funktionieren und dieselben Ausgaben wie zuvor unter `results/conda` produzieren. + +Hinter den Kulissen hat Nextflow die Conda-Pakete abgerufen und die Umgebung erstellt, was normalerweise etwas Arbeit erfordert; also ist es schön, dass wir nichts davon selbst machen müssen! + +!!! info "Hinweis" + + Das läuft schnell, weil das `cowpy`-Paket ziemlich klein ist, aber wenn du mit großen Paketen arbeitest, kann es beim ersten Mal etwas länger dauern als üblich, und du könntest sehen, dass die Konsolenausgabe für eine Minute oder so 'stecken bleibt', bevor sie abgeschlossen ist. + Das ist normal und liegt an der zusätzlichen Arbeit, die Nextflow beim ersten Mal macht, wenn du ein neues Paket verwendest. + +Aus unserer Sicht sieht es so aus, als ob es genau so funktioniert wie mit Docker, obwohl die Mechanik im Hintergrund etwas anders ist. + +Das bedeutet, dass wir bereit sind, bei Bedarf mit Conda-Umgebungen auszuführen. + +??? info "Docker und Conda mischen und kombinieren" + + Da diese Direktiven pro process zugewiesen werden, ist es möglich, zu 'mischen und kombinieren', _d.h._ einige der processes in deinem Workflow so zu konfigurieren, dass sie mit Docker laufen und andere mit Conda, zum Beispiel, wenn die von dir verwendete Recheninfrastruktur beides unterstützt. + In diesem Fall würdest du sowohl Docker als auch Conda in deiner Konfigurationsdatei aktivieren. + Wenn beide für einen bestimmten process verfügbar sind, wird Nextflow Container priorisieren. + + Und wie bereits erwähnt, unterstützt Nextflow mehrere andere Software-Paketierungs- und Container-Technologien, sodass du nicht auf nur diese beiden beschränkt bist. + +### Zusammenfassung + +Du weißt, wie du konfigurierst, welches Software-Paket jeder process verwenden soll, und wie du zwischen Technologien wechselst. + +### Was kommt als Nächstes? + +Lerne, wie du die Ausführungsplattform änderst, die Nextflow verwendet, um die eigentliche Arbeit zu erledigen. + +--- + +## 4. Eine Ausführungsplattform auswählen + +??? example "Szenario" + + Du hast deine Pipeline auf deinem Laptop entwickelt und getestet, aber jetzt musst du sie auf Tausenden von Proben ausführen. + Deine Institution hat einen HPC-Cluster mit einem Slurm-Scheduler, den du stattdessen verwenden möchtest. + +Bis jetzt haben wir unsere Pipeline mit dem local executor ausgeführt. +Dieser führt jede Aufgabe auf der Maschine aus, auf der Nextflow läuft. +Wenn Nextflow startet, schaut es sich die verfügbaren CPUs und den Speicher an. +Wenn die Ressourcen der zur Ausführung bereiten Aufgaben die verfügbaren Ressourcen überschreiten, wird Nextflow die letzten Aufgaben von der Ausführung zurückhalten, bis eine oder mehrere der früheren Aufgaben beendet sind und die notwendigen Ressourcen freigeben. + +Der local executor ist bequem und effizient, aber er ist auf diese einzelne Maschine beschränkt. Bei sehr großen Workloads könntest du feststellen, dass deine lokale Maschine ein Engpass ist, entweder weil du eine einzelne Aufgabe hast, die mehr Ressourcen erfordert als du verfügbar hast, oder weil du so viele Aufgaben hast, dass das Warten darauf, dass eine einzelne Maschine sie ausführt, zu lange dauern würde. + +Nextflow unterstützt [viele verschiedene Ausführungs-Backends](https://www.nextflow.io/docs/latest/executor.html), einschließlich HPC-Scheduler (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor und andere) sowie Cloud-Ausführungs-Backends (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes und mehr). + +### 4.1. Ein anderes Backend anvisieren + +Die Wahl des executor wird durch eine process-Direktive namens `executor` gesetzt. +Standardmäßig ist sie auf `local` gesetzt, also ist die folgende Konfiguration impliziert: + +```groovy title="Eingebaute Konfiguration" +process { + executor = 'local' +} +``` + +Um den executor auf ein anderes Backend zu setzen, würdest du einfach den gewünschten executor mit ähnlicher Syntax angeben, wie oben für Ressourcenzuweisungen beschrieben (siehe [Dokumentation](https://www.nextflow.io/docs/latest/executor.html) für alle Optionen). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Warnung" + + Wir können das in der Trainingsumgebung nicht wirklich testen, weil sie nicht eingerichtet ist, um sich mit einem HPC zu verbinden. + +### 4.2. Mit Backend-spezifischer Syntax für Ausführungsparameter umgehen + +Die meisten Hochleistungs-Rechenplattformen erlauben (und erfordern manchmal), dass du bestimmte Parameter wie Ressourcenzuweisungsanfragen und -beschränkungen (z.B. Anzahl der CPUs und Speicher) und den Namen der zu verwendenden Job-Queue angibst. + +Leider verwendet jedes dieser Systeme unterschiedliche Technologien, Syntaxen und Konfigurationen, um zu definieren, wie ein Job definiert und an den entsprechenden Scheduler übermittelt werden soll. + +??? abstract "Beispiele" + + Zum Beispiel muss derselbe Job, der 8 CPUs und 4GB RAM benötigt und auf der Queue "my-science-work" ausgeführt werden soll, je nach Backend auf unterschiedliche Weise ausgedrückt werden. + + ```bash title="Config für SLURM / übermitteln mit sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config für PBS / übermitteln mit qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config für SGE / übermitteln mit qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Glücklicherweise vereinfacht Nextflow all das. +Es bietet eine standardisierte Syntax, sodass du die relevanten Eigenschaften wie `cpus`, `memory` und `queue` (siehe Dokumentation für andere Eigenschaften) nur einmal angeben kannst. +Dann wird Nextflow zur Laufzeit diese Einstellungen verwenden, um die entsprechenden Backend-spezifischen Scripts basierend auf der executor-Einstellung zu generieren. + +Wir werden diese standardisierte Syntax im nächsten Abschnitt behandeln. + +### Zusammenfassung + +Du weißt jetzt, wie du den executor änderst, um verschiedene Arten von Recheninfrastruktur zu verwenden. + +### Was kommt als Nächstes? + +Lerne, wie du Rechenressourcenzuweisungen und -beschränkungen in Nextflow ausdrückst. + +--- + +## 5. Rechenressourcenzuweisungen steuern + +??? example "Szenario" + + Deine Pipeline schlägt auf dem Cluster immer fehl, weil Aufgaben wegen Überschreitung von Speicherlimits beendet werden. + Oder vielleicht werden dir Ressourcen berechnet, die du nicht nutzt, und du möchtest die Kosten optimieren. + +Die meisten Hochleistungs-Rechenplattformen erlauben (und erfordern manchmal), dass du bestimmte Ressourcenzuweisungsparameter wie Anzahl der CPUs und Speicher angibst. + +Standardmäßig wird Nextflow eine einzelne CPU und 2GB Speicher für jeden process verwenden. +Die entsprechenden process-Direktiven heißen `cpus` und `memory`, also ist die folgende Konfiguration impliziert: + +```groovy title="Eingebaute Konfiguration" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Du kannst diese Werte ändern, entweder für alle processes oder für bestimmte benannte processes, indem du zusätzliche process-Direktiven in deiner Konfigurationsdatei verwendest. +Nextflow wird sie in die entsprechenden Anweisungen für den gewählten executor übersetzen. + +Aber woher weißt du, welche Werte du verwenden sollst? + +### 5.1. Den Workflow ausführen, um einen Ressourcennutzungsbericht zu generieren + +??? example "Szenario" + + Du weißt nicht, wie viel Speicher oder CPU deine processes brauchen und möchtest vermeiden, Ressourcen zu verschwenden oder Jobs beenden zu lassen. + +Wenn du nicht im Voraus weißt, wie viel CPU und Speicher deine processes wahrscheinlich brauchen, kannst du etwas Ressourcen-Profiling machen, was bedeutet, dass du den Workflow mit einigen Standardzuweisungen ausführst, aufzeichnest, wie viel jeder process verwendet hat, und von dort aus schätzt, wie du die Basiszuweisungen anpassen kannst. + +Praktischerweise enthält Nextflow eingebaute Tools dafür und wird auf Anfrage gerne einen Bericht für dich generieren. + +Um das zu tun, füge `-with-report <dateiname>.html` zu deiner Kommandozeile hinzu. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Der Bericht ist eine HTML-Datei, die du herunterladen und in deinem Browser öffnen kannst. Du kannst auch mit der rechten Maustaste darauf im Datei-Explorer auf der linken Seite klicken und auf `Show preview` klicken, um sie in der Trainingsumgebung anzuzeigen. + +Nimm dir ein paar Minuten Zeit, um den Bericht durchzusehen und zu schauen, ob du einige Möglichkeiten zur Anpassung der Ressourcen identifizieren kannst. +Stelle sicher, dass du auf die Tabs klickst, die die Nutzungsergebnisse als Prozentsatz dessen zeigen, was zugewiesen wurde. +Es gibt [Dokumentation](https://www.nextflow.io/docs/latest/reports.html), die alle verfügbaren Funktionen beschreibt. + +### 5.2. Ressourcenzuweisungen für alle processes setzen + +Das Profiling zeigt, dass die processes in unserem Trainings-Workflow sehr leichtgewichtig sind, also lass uns die Standard-Speicherzuweisung auf 1GB pro process reduzieren. + +Füge das Folgende zu deiner `nextflow.config`-Datei hinzu, vor dem Abschnitt mit den Pipeline-Parametern: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Das wird helfen, die Menge an Rechenleistung zu reduzieren, die wir verbrauchen. + +### 5.3. Ressourcenzuweisungen für einen bestimmten process setzen + +Gleichzeitig werden wir so tun, als ob der `cowpy` process mehr Ressourcen benötigt als die anderen, nur um zu demonstrieren, wie man Zuweisungen für einen einzelnen process anpasst. + +=== "Nachher" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Mit dieser Konfiguration werden alle processes 1GB Speicher und eine einzelne CPU (der implizierte Standard) anfordern, außer dem `cowpy` process, der 2GB und 2 CPUs anfordern wird. + +!!! info "Hinweis" + + Wenn du eine Maschine mit wenigen CPUs hast und du eine hohe Anzahl pro process zuweist, könntest du sehen, dass process-Aufrufe hintereinander in die Warteschlange gestellt werden. + Das liegt daran, dass Nextflow sicherstellt, dass wir nicht mehr CPUs anfordern als verfügbar sind. + +### 5.4. Den Workflow mit der aktualisierten Konfiguration ausführen + +Lass uns das ausprobieren, indem wir einen anderen Dateinamen für den Profiling-Bericht angeben, damit wir die Leistung vor und nach den Konfigurationsänderungen vergleichen können. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Du wirst wahrscheinlich keinen echten Unterschied bemerken, da dies ein so kleiner Workload ist, aber das ist der Ansatz, den du verwenden würdest, um die Leistung und Ressourcenanforderungen eines realen Workflows zu analysieren. + +Es ist sehr nützlich, wenn deine processes unterschiedliche Ressourcenanforderungen haben. Es befähigt dich, die Ressourcenzuweisungen, die du für jeden process einrichtest, basierend auf tatsächlichen Daten richtig zu dimensionieren, nicht auf Vermutungen. + +!!! tip "Tipp" + + Das ist nur ein kleiner Vorgeschmack auf das, was du tun kannst, um deine Ressourcennutzung zu optimieren. + Nextflow selbst hat wirklich raffinierte [dynamische Wiederholungslogik](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) eingebaut, um Jobs, die aufgrund von Ressourcenbeschränkungen fehlschlagen, erneut zu versuchen. + Zusätzlich bietet die Seqera Platform auch KI-gesteuerte Tools zur automatischen Optimierung deiner Ressourcenzuweisungen. + +### 5.5. Ressourcenlimits hinzufügen + +Abhängig davon, welchen Rechen-executor und welche Recheninfrastruktur du verwendest, kann es einige Einschränkungen geben, was du zuweisen kannst (oder musst). +Zum Beispiel kann dein Cluster verlangen, dass du innerhalb bestimmter Limits bleibst. + +Du kannst die `resourceLimits`-Direktive verwenden, um die relevanten Beschränkungen zu setzen. Die Syntax sieht so aus, wenn sie allein in einem process-Block steht: + +```groovy title="Syntax-Beispiel" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow wird diese Werte in die entsprechenden Anweisungen übersetzen, abhängig vom executor, den du angegeben hast. + +Wir werden das nicht ausführen, da wir keinen Zugang zu relevanter Infrastruktur in der Trainingsumgebung haben. +Wenn du jedoch versuchen würdest, den Workflow mit Ressourcenzuweisungen auszuführen, die diese Limits überschreiten, und dann den `sbatch`-Befehl in der `.command.run`-Script-Datei nachschlagen würdest, würdest du sehen, dass die Anforderungen, die tatsächlich an den executor gesendet werden, auf die durch `resourceLimits` angegebenen Werte begrenzt sind. + +??? info "Institutionelle Referenzkonfigurationen" + + Das nf-core-Projekt hat eine [Sammlung von Konfigurationsdateien](https://nf-co.re/configs/) zusammengestellt, die von verschiedenen Institutionen auf der ganzen Welt geteilt werden und eine breite Palette von HPC- und Cloud-executors abdecken. + + Diese geteilten Configs sind sowohl für Leute wertvoll, die dort arbeiten und daher einfach die Konfiguration ihrer Institution sofort nutzen können, als auch als Modell für Leute, die eine Konfiguration für ihre eigene Infrastruktur entwickeln möchten. + +### Zusammenfassung + +Du weißt, wie du einen Profiling-Bericht generierst, um die Ressourcennutzung zu bewerten, und wie du Ressourcenzuweisungen für alle processes und/oder für einzelne processes änderst, sowie Ressourcenbeschränkungen für die Ausführung auf HPC setzt. + +### Was kommt als Nächstes? + +Lerne, wie du voreingestellte Konfigurationsprofile einrichtest und zur Laufzeit zwischen ihnen wechselst. + +--- + +## 6. Profile verwenden, um zwischen voreingestellten Konfigurationen zu wechseln + +??? example "Szenario" + + Du wechselst regelmäßig zwischen dem Ausführen von Pipelines auf deinem Laptop für die Entwicklung und auf dem HPC deiner Institution für Produktionsläufe. + Du bist es leid, jedes Mal manuell Konfigurationseinstellungen zu ändern, wenn du die Umgebung wechselst. + +Wir haben dir eine Reihe von Möglichkeiten gezeigt, wie du deine Pipeline-Konfiguration anpassen kannst, abhängig vom Projekt, an dem du arbeitest, oder der Rechenumgebung, die du verwendest. + +Du möchtest vielleicht zwischen alternativen Einstellungen wechseln, abhängig davon, welche Recheninfrastruktur du verwendest. Zum Beispiel möchtest du vielleicht lokal auf deinem Laptop entwickeln und kleine Tests ausführen, dann vollständige Workloads auf HPC oder Cloud ausführen. + +Nextflow ermöglicht es dir, beliebig viele Profile einzurichten, die verschiedene Konfigurationen beschreiben, die du dann zur Laufzeit mit einem Kommandozeilen-Argument auswählen kannst, anstatt die Konfigurationsdatei selbst ändern zu müssen. + +### 6.1. Profile für das Wechseln zwischen lokaler Entwicklung und Ausführung auf HPC erstellen + +Lass uns zwei alternative Profile einrichten; eines für das Ausführen kleiner Lasten auf einem normalen Computer, wo wir Docker-Container verwenden werden, und eines für das Ausführen auf einem Universitäts-HPC mit einem Slurm-Scheduler, wo wir Conda-Pakete verwenden werden. + +#### 6.1.1. Die Profile einrichten + +Füge das Folgende zu deiner `nextflow.config`-Datei hinzu, nach dem Abschnitt mit den Pipeline-Parametern, aber vor den Ausgabe-Einstellungen: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Du siehst, dass wir für das Universitäts-HPC auch Ressourcenbeschränkungen angeben. + +#### 6.1.2. Den Workflow mit einem Profil ausführen + +Um ein Profil in unserer Nextflow-Kommandozeile anzugeben, verwenden wir das `-profile`-Argument. + +Lass uns versuchen, den Workflow mit der `my_laptop`-Konfiguration auszuführen. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Wie du sehen kannst, erlaubt uns das, sehr bequem zur Laufzeit zwischen Konfigurationen zu wechseln. + +!!! warning "Warnung" + + Das `univ_hpc`-Profil wird in der Trainingsumgebung nicht richtig laufen, da wir keinen Zugang zu einem Slurm-Scheduler haben. + +Wenn wir in Zukunft andere Konfigurationselemente finden, die immer gemeinsam mit diesen auftreten, können wir sie einfach zum entsprechenden Profil/zu den entsprechenden Profilen hinzufügen. +Wir können auch zusätzliche Profile erstellen, wenn es andere Konfigurationselemente gibt, die wir zusammenfassen möchten. + +### 6.2. Ein Profil mit Test-Parametern erstellen + +??? example "Szenario" + + Du möchtest, dass andere deine Pipeline schnell ausprobieren können, ohne ihre eigenen Eingabedaten sammeln zu müssen. + +Profile sind nicht nur für Infrastruktur-Konfiguration. +Wir können sie auch verwenden, um Standardwerte für Workflow-Parameter zu setzen, um es anderen einfacher zu machen, den Workflow auszuprobieren, ohne selbst geeignete Eingabewerte sammeln zu müssen. +Du kannst das als Alternative zur Verwendung einer Parameter-Datei betrachten. + +#### 6.2.1. Das Profil einrichten + +Die Syntax für das Ausdrücken von Standardwerten in diesem Kontext sieht so aus, für ein Profil, das wir `test` nennen: + +```groovy title="Syntax-Beispiel" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Wenn wir ein test-Profil für unseren Workflow hinzufügen, wird der `profiles`-Block: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Genau wie für technische Konfigurationsprofile kannst du mehrere verschiedene Profile einrichten, die Parameter unter einem beliebigen Namen angeben, den du magst. + +#### 6.2.2. Den Workflow lokal mit dem test-Profil ausführen + +Praktischerweise schließen sich Profile nicht gegenseitig aus, sodass wir mehrere Profile in unserer Kommandozeile mit der folgenden Syntax angeben können `-profile <profil1>,<profil2>` (für eine beliebige Anzahl von Profilen). + +Wenn du Profile kombinierst, die Werte für dieselben Konfigurationselemente setzen und in derselben Konfigurationsdatei beschrieben sind, wird Nextflow den Konflikt lösen, indem es den Wert verwendet, den es zuletzt eingelesen hat (_d.h._ was auch immer später in der Datei kommt). +Wenn die widersprüchlichen Einstellungen in verschiedenen Konfigurationsquellen gesetzt sind, gilt die Standard-[Rangfolge](https://www.nextflow.io/docs/latest/config.html). + +Lass uns versuchen, das test-Profil zu unserem vorherigen Befehl hinzuzufügen: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Das wird Docker verwenden, wo möglich, und Ausgaben unter `results/test` produzieren, und diesmal ist der Charakter das komische Duo `dragonandcow`. + +??? abstract "Dateiinhalte" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Das bedeutet, solange wir alle Testdatendateien mit dem Workflow-Code verteilen, kann jeder den Workflow schnell ausprobieren, ohne eigene Eingaben über die Kommandozeile oder eine Parameter-Datei bereitstellen zu müssen. + +!!! tip "Tipp" + + Wir können für größere Dateien, die extern gespeichert sind, auf URLs verweisen. + Nextflow wird sie automatisch herunterladen, solange eine offene Verbindung besteht. + + Für mehr Details, siehe die Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. `nextflow config` verwenden, um die aufgelöste Konfiguration zu sehen + +Wie oben erwähnt, kann manchmal derselbe Parameter auf verschiedene Werte in Profilen gesetzt sein, die du kombinieren möchtest. +Und allgemeiner gibt es zahlreiche Orte, an denen Konfigurationselemente gespeichert werden können, und manchmal können dieselben Eigenschaften an verschiedenen Orten auf verschiedene Werte gesetzt sein. + +Nextflow wendet eine festgelegte [Rangfolge](https://www.nextflow.io/docs/latest/config.html) an, um Konflikte zu lösen, aber das kann schwierig sein, selbst zu bestimmen. +Und selbst wenn nichts im Konflikt steht, kann es mühsam sein, alle möglichen Orte nachzuschlagen, an denen Dinge konfiguriert sein könnten. + +Glücklicherweise enthält Nextflow ein praktisches Hilfsprogramm namens `config`, das diesen gesamten Prozess für dich automatisieren kann. + +Das `config`-Tool wird alle Inhalte in deinem aktuellen Arbeitsverzeichnis erkunden, alle Konfigurationsdateien aufsaugen und die vollständig aufgelöste Konfiguration produzieren, die Nextflow verwenden würde, um den Workflow auszuführen. +Das ermöglicht es dir herauszufinden, welche Einstellungen verwendet werden, ohne etwas starten zu müssen. + +#### 6.3.1. Die Standardkonfiguration auflösen + +Führe diesen Befehl aus, um die Konfiguration aufzulösen, die standardmäßig angewendet würde. + +```bash +nextflow config +``` + +??? success "Befehlsausgabe" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Das zeigt dir die Basiskonfiguration, die du bekommst, wenn du nichts Extra in der Kommandozeile angibst. + +#### 6.3.2. Die Konfiguration mit spezifischen aktivierten Einstellungen auflösen + +Wenn du Kommandozeilen-Parameter angibst, z.B. ein oder mehrere Profile aktivierst oder eine Parameter-Datei lädst, wird der Befehl diese zusätzlich berücksichtigen. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Befehlsausgabe" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Das wird besonders nützlich für komplexe Projekte, die mehrere Konfigurationsebenen beinhalten. + +### Zusammenfassung + +Du weißt, wie du Profile verwendest, um zur Laufzeit mit minimalem Aufwand eine voreingestellte Konfiguration auszuwählen. +Allgemeiner weißt du, wie du deine Workflow-Ausführungen konfigurierst, um verschiedenen Rechenplattformen zu entsprechen und die Reproduzierbarkeit deiner Analysen zu verbessern. + +### Was kommt als Nächstes? + +Lerne, wie du Pipelines direkt aus Remote-Repositories wie GitHub ausführst. + +--- + +## 7. Pipelines aus Remote-Repositories ausführen + +??? example "Szenario" + + Du möchtest eine etablierte Pipeline wie die von nf-core ausführen, ohne den Code selbst herunterladen und verwalten zu müssen. + +Bisher haben wir Workflow-Scripts ausgeführt, die sich im aktuellen Verzeichnis befinden. +In der Praxis wirst du oft Pipelines ausführen wollen, die in Remote-Repositories gespeichert sind, wie GitHub. + +Nextflow macht das einfach: Du kannst jede Pipeline direkt von einer Git-Repository-URL ausführen, ohne sie vorher manuell herunterladen zu müssen. + +### 7.1. Eine Pipeline von GitHub ausführen + +Die grundlegende Syntax für das Ausführen einer Remote-Pipeline ist `nextflow run <repository>`, wobei `<repository>` ein GitHub-Repository-Pfad wie `nextflow-io/hello`, eine vollständige URL oder ein Pfad zu GitLab, Bitbucket oder anderen Git-Hosting-Diensten sein kann. + +Versuche, die offizielle Nextflow "hello" Demo-Pipeline auszuführen: + +```bash +nextflow run nextflow-io/hello +``` + +Das erste Mal, wenn du eine Remote-Pipeline ausführst, lädt Nextflow sie herunter und speichert sie lokal im cache. +Nachfolgende Ausführungen verwenden die gecachte Version, es sei denn, du forderst explizit ein Update an. + +### 7.2. Eine Version für Reproduzierbarkeit angeben + +Standardmäßig führt Nextflow die neueste Version vom Standard-Branch aus. +Du kannst eine bestimmte Version, einen Branch oder einen Commit mit dem `-r`-Flag angeben: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Das Angeben exakter Versionen ist essentiell für die Reproduzierbarkeit. + +### Zusammenfassung + +Du weißt, wie du Pipelines direkt von GitHub und anderen Remote-Repositories ausführst, und wie du Versionen für die Reproduzierbarkeit angibst. + +### Was kommt als Nächstes? + +Klopf dir kräftig auf die Schulter! +Du weißt alles, was du wissen musst, um mit dem Ausführen und Verwalten von Nextflow Pipelines zu beginnen. + +Das schließt diesen Kurs ab, aber wenn du eifrig weiterlernen möchtest, haben wir zwei Hauptempfehlungen: + +- Wenn du tiefer in die Entwicklung eigener Pipelines eintauchen möchtest, schau dir [Hello Nextflow](../hello_nextflow/index.md) an, einen Kurs für Anfänger, der denselben allgemeinen Verlauf wie dieser abdeckt, aber viel mehr ins Detail über channels und Operatoren geht. +- Wenn du weiterhin lernen möchtest, wie man Nextflow Pipelines ausführt, ohne tiefer in den Code einzusteigen, schau dir den ersten Teil von [Hello nf-core](../hello_nf-core/index.md) an, der die Tools zum Finden und Ausführen von Pipelines aus dem äußerst beliebten [nf-core](https://nf-co.re/) Projekt vorstellt. + +Viel Spaß! + +--- + +## Quiz + +<quiz> +Wenn Parameter-Werte sowohl in der Workflow-Datei als auch in `nextflow.config` gesetzt sind, welcher hat Vorrang? +- [ ] Der Wert aus der Workflow-Datei +- [x] Der Wert aus der Konfigurationsdatei +- [ ] Der zuerst gefundene Wert +- [ ] Es verursacht einen Fehler + +Mehr erfahren: [1.1. Set up values in `nextflow.config`](#11-set-up-values-in-nextflowconfig) +</quiz> + +<quiz> +Was ist der Syntax-Unterschied zwischen dem Setzen eines Parameter-Standards in einer Workflow-Datei vs. einer config-Datei? +- [ ] Sie verwenden dieselbe Syntax +- [x] Workflow verwendet typisierte Deklaration (`#!groovy param: Type = value`), config verwendet Zuweisung (`#!groovy param = value`) +- [ ] Config verwendet typisierte Deklaration, Workflow verwendet Zuweisung +- [ ] Nur config-Dateien können Standardwerte setzen + +Mehr erfahren: [1.1. Set up values in `nextflow.config`](#11-set-up-values-in-nextflowconfig) +</quiz> + +<quiz> +Wie gibst du eine Parameter-Datei an, wenn du einen Workflow ausführst? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Mehr erfahren: [1.3. Use a parameter file](#13-use-a-parameter-file) +</quiz> + +<quiz> +Was steuert die `outputDir`-Konfigurationsoption? +- [ ] Den Ort des work directory +- [x] Den Basispfad, wo Workflow-Ausgaben veröffentlicht werden +- [ ] Das Verzeichnis für Log-Dateien +- [ ] Den Ort der Modul-Dateien + +Mehr erfahren: [2.1. Customize the outputDir directory name](#21-customize-the-outputdir-directory-name) +</quiz> + +<quiz> +Wie referenzierst du einen process-Namen dynamisch in der Ausgabe-Pfad-Konfiguration? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Mehr erfahren: [2.2. Organize outputs by process](#22-organize-outputs-by-process) +</quiz> + +<quiz> +Wenn sowohl Docker als auch Conda aktiviert sind und ein process beide Direktiven hat, welche wird priorisiert? +- [x] Docker (containers) +- [ ] Conda +- [ ] Die zuerst im process definierte +- [ ] Es verursacht einen Fehler + +Mehr erfahren: [3. Select a software packaging technology](#3-select-a-software-packaging-technology) +</quiz> + +<quiz> +Was ist der Standard-executor in Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Mehr erfahren: [4. Select an execution platform](#4-select-an-execution-platform) +</quiz> + +<quiz> +Welcher Befehl generiert einen Ressourcennutzungsbericht? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Mehr erfahren: [5.1. Run the workflow to generate a resource utilization report](#51-run-the-workflow-to-generate-a-resource-utilization-report) +</quiz> + +<quiz> +Wie setzt du Ressourcenanforderungen für einen bestimmten process namens `cowpy` in der config-Datei? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Mehr erfahren: [5.3. Set resource allocations for a specific process](#53-set-resource-allocations-for-a-specific-process) +</quiz> + +<quiz> +Was macht die `resourceLimits`-Direktive? +- [ ] Setzt minimale Ressourcenanforderungen +- [ ] Weist Ressourcen zu processes zu +- [x] Begrenzt die maximalen Ressourcen, die angefordert werden können +- [ ] Überwacht die Ressourcennutzung in Echtzeit + +Mehr erfahren: [5.5. Add resource limits](#55-add-resource-limits) +</quiz> + +<quiz> +Wie gibst du mehrere Profile in einem einzelnen Befehl an? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Mehr erfahren: [6. Use profiles to switch between preset configurations](#6-use-profiles-to-switch-between-preset-configurations) +</quiz> + +<quiz> +Welcher Befehl zeigt die vollständig aufgelöste Konfiguration, die Nextflow verwenden würde? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Mehr erfahren: [6.3. Use `nextflow config` to see the resolved configuration](#63-use-nextflow-config-to-see-the-resolved-configuration) +</quiz> + +<quiz> +Wofür können Profile verwendet werden? (Wähle alle zutreffenden aus) +- [x] Definieren von infrastrukturspezifischen Einstellungen (executors, containers) +- [x] Setzen von Ressourcenlimits für verschiedene Umgebungen +- [x] Bereitstellen von Test-Parametern für einfaches Workflow-Testen +- [ ] Definieren neuer processes + +Mehr erfahren: [6. Use profiles to switch between preset configurations](#6-use-profiles-to-switch-between-preset-configurations) +</quiz> diff --git a/docs/de/docs/nextflow_run/index.md b/docs/de/docs/nextflow_run/index.md new file mode 100644 index 0000000000..9486e6f716 --- /dev/null +++ b/docs/de/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow-Workflows starten und ihre Ausführung verwalten + - Ausgaben (Ergebnisse) und Protokolldateien finden und interpretieren + - Kernkomponenten von Nextflow in einem einfachen mehrstufigen Workflow erkennen + - Pipeline-Ausführung für gängige Rechenplattformen einschließlich HPC und Cloud konfigurieren + - Best Practices für Reproduzierbarkeit, Portabilität und Code-Wiederverwendung zusammenfassen, die Pipelines FAIR machen, einschließlich Code-Modularität und Software-Container + audience_prerequisites: + - "**Zielgruppe:** Dieser Kurs richtet sich an Lernende, die völlig neu bei Nextflow sind und bestehende Pipelines ausführen möchten." + - "**Kenntnisse:** Grundlegende Vertrautheit mit der Befehlszeile, grundlegenden Scripting-Konzepten und gängigen Dateiformaten wird vorausgesetzt." + - "**Fachgebiet:** Die Übungen sind alle fachunabhängig, sodass keine wissenschaftlichen Vorkenntnisse erforderlich sind." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run ist eine praktische Einführung in die Ausführung reproduzierbarer und skalierbarer Datenanalyse-Workflows.** + +Durch praktische Beispiele und geführte Übungen lernst du die Grundlagen der Verwendung von Nextflow, einschließlich der Ausführung von Pipelines, der Verwaltung von Dateien und Software-Abhängigkeiten, der mühelosen Parallelisierung der Ausführung und der Ausführung von Workflows in verschiedenen Rechenumgebungen. + +Nach diesem Kurs kannst du Workflows mit Nextflow ausführen. + +<!-- additional_information --> + +## Kursübersicht + +### Was du tun wirst + +Dieser Kurs ist praxisorientiert, mit zielgerichteten Übungen, die Informationen schrittweise einführen. + +Du wirst mehrere Versionen einer Nextflow-Pipeline ausführen, die Texteingaben verarbeitet. +Du beginnst mit einer einfachen Version, die aus einem einzelnen Schritt besteht, und gelangst schließlich zu einer mehrstufigen Version, die eine CSV-Datei mit tabellarischen Texteingaben nimmt, einige Transformationsschritte ausführt und eine einzelne Textdatei ausgibt, die ein ASCII-Bild eines Charakters enthält, der den transformierten Text sagt. + +Dieser Kurs konzentriert sich auf das Ausführen von Pipelines (benannt nach dem Kernbefehl `nextflow run`). +Wenn du eine Einführung in die Entwicklung von Nextflow-Pipelines suchst, siehe [Hello Nextflow](../hello_nextflow/index.md). + +### Lehrplan + +Wir haben dies in drei Teile unterteilt, die sich jeweils auf bestimmte Aspekte des Ausführens und Verwaltens von Pipelines konzentrieren, die in Nextflow geschrieben sind. + +| Kurskapitel | Zusammenfassung | Geschätzte Dauer | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------- | +| [Teil 1: Grundlegende Operationen](./01_basics.md) | Starten und Verwalten der Ausführung eines einfachen Workflows | 30 Min | +| [Teil 2: Echte Pipelines ausführen](./02_pipeline.md) | Komplexe Eingaben verarbeiten, mehrstufige Workflows ausführen, Container verwenden und mühelos parallelisieren | 60 Min | +| [Teil 3: Konfiguration](./03_config.md) | Pipeline-Verhalten anpassen und Nutzung in verschiedenen Rechenumgebungen optimieren | 60 Min | + +Nach Abschluss dieses Kurses bist du bereit, reproduzierbare Workflows für deine eigenen Projekte auszuführen. + +Bereit, den Kurs zu beginnen? + +[Jetzt lernen :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/de/docs/nextflow_run/next_steps.md b/docs/de/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..9750ca6288 --- /dev/null +++ b/docs/de/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Kurszusammenfassung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herzlichen Glückwunsch zum Abschluss des Nextflow Run-Trainingskurses! 🎉 + +<!-- placeholder for video --> + +## Dein Fortschritt + +Du hast mit einem sehr grundlegenden Workflow begonnen und gelernt, ihn auszuführen, die Ausgaben zu finden und seine Ausführung zu verwalten. +Dann hast du dich durch immer komplexere Versionen dieses Workflows gearbeitet und gelernt, die wesentlichen Konzepte und Mechanismen zu erkennen, die Nextflow-Pipelines antreiben, einschließlich Channels und Operatoren, Code-Modularisierung und Container. +Schließlich hast du gelernt, wie du die Konfiguration einer Pipeline an deine Präferenzen und deine Recheninfrastruktur anpasst. + +### Was du gelernt hast + +Du bist jetzt in der Lage, die Ausführung der Hello-Pipeline zu verwalten, zu beschreiben, wie sie strukturiert ist, und die wichtigsten Code-Teile zu identifizieren. + +- Die endgültige Form des Hello-Workflows nimmt als Eingabe eine CSV-Datei, die Text-Grüße enthält. +- Die vier Schritte sind als Nextflow-Prozesse (`sayHello`, `convertToUpper`, `collectGreetings` und `cowpy`) implementiert und in separaten Modul-Dateien gespeichert. +- Die Ergebnisse werden in ein Verzeichnis namens `results/` veröffentlicht. +- Die finale Ausgabe der Pipeline ist eine einfache Textdatei, die ASCII-Kunst eines Charakters enthält, der die großgeschriebenen Grüße sagt. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Schreibt jeden Gruß in seine eigene Ausgabedatei (_z.B._ "Hello-output.txt") +2. **`convertToUpper`:** Konvertiert jeden Gruß in Großbuchstaben (_z.B._ "HELLO") +3. **`collectGreetings`:** Sammelt alle großgeschriebenen Grüße in einer einzelnen Batch-Datei +4. **`cowpy`:** Generiert ASCII-Kunst mit dem `cowpy`-Tool + +Die Workflow-Konfiguration unterstützt die flexible und reproduzierbare Bereitstellung von Eingaben und Parametern. + +### Erworbene Fähigkeiten + +Durch diesen praxisorientierten Kurs hast du gelernt, wie man: + +- Einen Nextflow-Workflow lokal startet +- Ausgaben (Ergebnisse) und Protokolldateien, die von Nextflow generiert werden, findet und interpretiert +- Die Kernkomponenten von Nextflow erkennt, die einen einfachen mehrstufigen Workflow ausmachen +- Fortgeschrittene Konzepte wie Operatoren und Channel-Factories beschreibt +- Pipelines für verschiedene Rechenumgebungen konfiguriert + +Du bist jetzt mit dem grundlegenden Wissen ausgestattet, um bestehende Nextflow-Pipelines in deine eigene Arbeit zu integrieren. + +## Nächste Schritte zum Aufbau deiner Fähigkeiten + +Hier sind unsere Top-Vorschläge, was du als Nächstes tun kannst: + +- Führe Nextflow nicht nur aus, schreibe es! Werde ein Nextflow-Entwickler mit [Hello Nextflow](../hello_nextflow/index.md) +- Wende Nextflow auf einen wissenschaftlichen Analyse-Anwendungsfall an mit [Nextflow for Science](../nf4_science/index.md) +- Starte mit nf-core mit [Hello nf-core](../hello_nf-core/index.md) +- Lerne Troubleshooting-Techniken mit der [Debugging Side Quest](../side_quests/debugging.md) + +Schließlich empfehlen wir dir einen Blick auf [**Seqera Platform**](https://seqera.io/), eine Cloud-basierte Plattform, die von den Erstellern von Nextflow entwickelt wurde und es noch einfacher macht, deine Workflows zu starten und zu verwalten, deine Daten zu verwalten und Analysen interaktiv in jeder Umgebung auszuführen. + +## Hilfe bekommen + +Für Hilfe-Ressourcen und Community-Support siehe die [Hilfe-Seite](../help.md). + +## Feedback-Umfrage + +Bevor du weitergehst, nimm dir bitte eine Minute Zeit, um die Kurs-Umfrage auszufüllen! Dein Feedback hilft uns, unsere Trainingsmaterialien für alle zu verbessern. + +[Zur Umfrage :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/de/docs/nextflow_run/survey.md b/docs/de/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..6acf90cc8e --- /dev/null +++ b/docs/de/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Feedback-Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bevor du weitergehst, fülle bitte diese kurze 5-Fragen-Umfrage aus, um das Training zu bewerten und uns Feedback zu geben. + +Das sollte weniger als eine Minute dauern. Vielen Dank, dass du uns hilfst, unsere Trainingsmaterialien für alle zu verbessern! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/de/docs/nf4_science/genomics/00_orientation.md b/docs/de/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..039e188b58 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Die Trainingsumgebung enthält alle Software, den Code und die Daten, die für diesen Trainingskurs notwendig sind, sodass du nichts selbst installieren musst. +Du benötigst jedoch einen (kostenlosen) Account, um dich anzumelden, und solltest dir ein paar Minuten Zeit nehmen, um dich mit der Oberfläche vertraut zu machen. + +Falls du dies noch nicht getan hast, folge bitte [diesem Link](../../../envsetup/), bevor du weiter fortfährst. + +## Bereitgestellte Materialien + +Während dieses Trainingskurses arbeiten wir im Verzeichnis `nf4-science/genomics/`, in das du wechseln musst, wenn du den Trainings-Workspace öffnest. +Dieses Verzeichnis enthält alle Code-Dateien, Testdaten und Zusatzdateien, die du benötigst. + +Du kannst gerne den Inhalt dieses Verzeichnisses erkunden; am einfachsten geht das mit dem Datei-Explorer auf der linken Seite des Trainings-Workspace in der VSCode-Oberfläche. +Alternativ kannst du den Befehl `tree` verwenden. +Im Laufe des Kurses nutzen wir die Ausgabe von `tree`, um die Verzeichnisstruktur und den Inhalt in lesbarer Form darzustellen, manchmal mit kleinen Änderungen zur besseren Übersicht. + +Hier erstellen wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 2 +``` + +Wenn du dies innerhalb von `nf4-science/genomics` ausführst, solltest du folgende Ausgabe sehen: + +```console title="Verzeichnisinhalt" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Hinweis" + + Mach dir keine Sorgen, falls das viel erscheint; wir werden die relevanten Teile bei jedem Schritt des Kurses durchgehen. + Dies soll dir nur einen Überblick geben. + +**Hier ist eine Zusammenfassung dessen, was du für den Einstieg wissen solltest:** + +- **Die `.nf`-Dateien** sind Workflow-Skripte, die nach dem entsprechenden Teil des Kurses benannt sind, in dem sie verwendet werden. + +- **Die Datei `nextflow.config`** ist eine Konfigurationsdatei, die minimale Umgebungseigenschaften festlegt. + Du kannst sie vorerst ignorieren. + +- **Das Verzeichnis `data`** enthält Eingabedaten und zugehörige Ressourcen, die später im Kurs beschrieben werden. + +- **Das Verzeichnis `solutions`** enthält Moduldateien und Testkonfigurationen, die aus den Teilen 3 und 4 des Kurses resultieren. + Sie sind als Referenz gedacht, um deine Arbeit zu überprüfen und eventuelle Probleme zu beheben. + +!!!tip "Tipp" + + Falls du aus irgendeinem Grund aus diesem Verzeichnis herausnavigierst, kannst du jederzeit mit diesem Befehl zurückkehren: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Um den Kurs zu beginnen, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite. diff --git a/docs/de/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/de/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..b469de8e0c --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1037 @@ +# Teil 1: Variantenerkennung pro Probe + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil dieses Kurses zeigen wir dir, wie du eine einfache Varianten-Pipeline erstellst, die GATK-Variantenerkennung auf einzelne Sequenzierungsproben anwendet. + +### Methodenübersicht + +Variantenerkennung ist eine genomische Analysemethode, die darauf abzielt, Variationen in einer Genomsequenz relativ zu einem Referenzgenom zu identifizieren. +Hier werden wir Tools und Methoden verwenden, die für die Erkennung kurzer Varianten entwickelt wurden, _d.h._ SNPs und Indels. + +![GATK pipeline](img/gatk-pipeline.png) + +Eine vollständige Varianten-Pipeline umfasst typischerweise viele Schritte, einschließlich Mapping zum Referenzgenom (manchmal als Genom-Alignment bezeichnet) sowie Variantenfilterung und -priorisierung. +Der Einfachheit halber konzentrieren wir uns in diesem Teil des Kurses nur auf den Variantenerkennungsteil. + +### Datensatz + +Wir stellen die folgenden Daten und zugehörige Ressourcen bereit: + +- **Ein Referenzgenom**, das aus einer kleinen Region des menschlichen Chromosoms 20 (aus hg19/b37) und seinen Zusatzdateien (Index und Sequenzwörterbuch) besteht. +- **Drei Gesamtgenom-Sequenzierungsproben**, die einem Familientrio (Mutter, Vater und Sohn) entsprechen, die auf einen kleinen Datenausschnitt auf Chromosom 20 reduziert wurden, um die Dateigrößen klein zu halten. + Dies sind Illumina-Short-Read-Sequenzierungsdaten, die bereits auf das Referenzgenom gemappt wurden und im [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf)-Format (Binary Alignment Map, eine komprimierte Version von SAM, Sequence Alignment Map) bereitgestellt werden. +- **Eine Liste genomischer Intervalle**, d.h. Koordinaten auf dem Genom, wo unsere Proben Daten haben, die für die Variantenerkennung geeignet sind, bereitgestellt im BED-Format. + +### Workflow + +In diesem Teil des Kurses werden wir einen Workflow entwickeln, der Folgendes tut: + +1. Generiere eine Indexdatei für jede BAM-Eingabedatei mit [Samtools](https://www.htslib.org/) +2. Führe GATK HaplotypeCaller auf jeder BAM-Eingabedatei aus, um Variantenaufrufe pro Probe im VCF-Format (Variant Call Format) zu generieren + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note "Hinweis" + + Indexdateien sind ein häufiges Merkmal bioinformatischer Dateiformate; sie enthalten Informationen über die Struktur der Hauptdatei, die es Tools wie GATK ermöglichen, auf eine Teilmenge der Daten zuzugreifen, ohne die gesamte Datei lesen zu müssen. + Dies ist wichtig, weil diese Dateien sehr groß werden können. + +--- + +## 0. Aufwärmen: Teste die Samtools- und GATK-Befehle interaktiv + +Zuerst möchten wir die Befehle manuell ausprobieren, bevor wir versuchen, sie in einen Workflow zu verpacken. +Die Tools, die wir benötigen (Samtools und GATK), sind nicht in der GitHub Codespaces-Umgebung installiert, also werden wir sie über Container verwenden (siehe [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Hinweis" + + Stelle sicher, dass du im Verzeichnis `nf4-science/genomics` bist, sodass der letzte Teil des Pfads, der angezeigt wird, wenn du `pwd` eingibst, `genomics` ist. + +### 0.1. Indexiere eine BAM-Eingabedatei mit Samtools + +Wir werden einen Samtools-Container herunterladen, ihn interaktiv starten und den Befehl `samtools index` auf eine der BAM-Dateien anwenden. + +#### 0.1.1. Lade den Samtools-Container herunter + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.1.2. Starte den Samtools-Container interaktiv + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.1.3. Führe den Indexierungsbefehl aus + +Die [Samtools-Dokumentation](https://www.htslib.org/doc/samtools-index.html) gibt uns die Befehlszeile, um eine BAM-Datei zu indexieren. + +Wir müssen nur die Eingabedatei angeben; das Tool generiert automatisch einen Namen für die Ausgabe, indem es `.bai` an den Eingabedateinamen anhängt. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Dies sollte sofort abgeschlossen sein, und du solltest jetzt eine Datei namens `reads_mother.bam.bai` im selben Verzeichnis wie die ursprüngliche BAM-Eingabedatei sehen. + +??? abstract "Verzeichnisinhalt" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Verlasse den Samtools-Container + +```bash +exit +``` + +### 0.2. Rufe Varianten mit GATK HaplotypeCaller auf + +Wir werden einen GATK-Container herunterladen, ihn interaktiv starten und den Befehl `gatk HaplotypeCaller` auf die BAM-Datei anwenden, die wir gerade indexiert haben. + +#### 0.2.1. Lade den GATK-Container herunter + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.2.2. Starte den GATK-Container interaktiv + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.2.3. Führe den Variantenerkennungsbefehl aus + +Die [GATK-Dokumentation](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) gibt uns die Befehlszeile, um Variantenerkennung auf einer BAM-Datei durchzuführen. + +Wir müssen die BAM-Eingabedatei (`-I`) sowie das Referenzgenom (`-R`), einen Namen für die Ausgabedatei (`-O`) und eine Liste genomischer Intervalle zur Analyse (`-L`) angeben. + +Wir müssen jedoch nicht den Pfad zur Indexdatei angeben; das Tool sucht automatisch danach im selben Verzeichnis, basierend auf der etablierten Namens- und Platzierungskonvention. +Dasselbe gilt für die Zusatzdateien des Referenzgenoms (Index- und Sequenzwörterbuchdateien, `*.fai` und `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Die Ausgabedatei `reads_mother.vcf` wird in deinem Arbeitsverzeichnis im Container erstellt, sodass du sie im VS Code-Datei-Explorer nicht sehen wirst, es sei denn, du änderst den Ausgabedateipfad. +Es ist jedoch eine kleine Testdatei, sodass du sie mit `cat` öffnen und den Inhalt anzeigen kannst. +Wenn du ganz nach oben zum Anfang der Datei scrollst, findest du einen Header, der aus vielen Zeilen mit Metadaten besteht, gefolgt von einer Liste von Variantenaufrufen, einer pro Zeile. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Jede Zeile beschreibt eine mögliche Variante, die in den Sequenzierungsdaten der Probe identifiziert wurde. Für Anleitungen zur Interpretation des VCF-Formats siehe [diesen hilfreichen Artikel](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +Die Ausgabe-VCF-Datei wird von einer Indexdatei namens `reads_mother.vcf.idx` begleitet, die automatisch von GATK erstellt wurde. +Sie hat dieselbe Funktion wie die BAM-Indexdatei, um Tools zu ermöglichen, Teilmengen von Daten zu suchen und abzurufen, ohne die gesamte Datei zu laden. + +#### 0.2.4. Verlasse den GATK-Container + +```bash +exit +``` + +### Zusammenfassung + +Du weißt, wie du die Samtools-Indexierung und GATK-Variantenerkennungsbefehle in ihren jeweiligen Containern testest. + +### Was kommt als Nächstes? + +Lerne, wie du diese Befehle in einen zweistufigen Workflow verpackst, der Container zur Ausführung der Arbeit verwendet. + +--- + +## 1. Schreibe einen einstufigen Workflow, der Samtools index auf einer BAM-Datei ausführt + +Wir stellen dir eine Workflow-Datei, `genomics-1.nf`, zur Verfügung, die die Hauptteile des Workflows umreißt. +Sie ist nicht funktionsfähig; ihr Zweck ist es nur, als Skelett zu dienen, das du zum Schreiben des tatsächlichen Workflows verwenden wirst. + +### 1.1. Definiere den Indexierungsprozess + +Beginnen wir mit dem Schreiben eines Prozesses, den wir `SAMTOOLS_INDEX` nennen werden, der die Indexierungsoperation beschreibt. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Generiere BAM-Indexdatei + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Du solltest alle Teile aus dem wiedererkennen, was du in Teil 1 & Teil 2 dieser Trainingsreihe gelernt hast. + +Dieser Prozess wird von uns verlangen, einen Dateipfad über die Eingabe `input_bam` zu übergeben, also richten wir das als Nächstes ein. + +### 1.2. Füge eine Eingabeparameterdeklaration hinzu + +Am Anfang der Datei, unter dem Abschnitt `Pipeline parameters`, deklarieren wir einen CLI-Parameter namens `reads_bam` und geben ihm einen Standardwert. +Auf diese Weise können wir faul sein und die Eingabe nicht angeben, wenn wir den Befehl zum Starten der Pipeline eingeben (für Entwicklungszwecke). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Pipeline parameters + */ +params { + // Primäre Eingabe + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Jetzt haben wir einen Prozess bereit, sowie einen Parameter, um ihm eine Eingabe zum Ausführen zu geben, also verbinden wir diese Dinge zusammen. + +!!! note "Hinweis" + + `${projectDir}` ist eine eingebaute Nextflow-Variable, die auf das Verzeichnis zeigt, in dem sich das aktuelle Nextflow-Workflow-Skript (`genomics-1.nf`) befindet. + + Dies macht es einfach, auf Dateien, Datenverzeichnisse und andere Ressourcen zu verweisen, die im Workflow-Repository enthalten sind, ohne absolute Pfade fest zu codieren. + +### 1.3. Füge einen workflow-Block hinzu, um SAMTOOLS_INDEX auszuführen + +Im `workflow`-Block müssen wir einen **channel** einrichten, um die Eingabe an den `SAMTOOLS_INDEX`-Prozess zu übergeben; dann können wir den Prozess selbst aufrufen, um auf den Inhalten dieses Channels zu laufen. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Erstelle Eingabekanal (einzelne Datei über CLI-Parameter) + reads_ch = channel.fromPath(params.reads_bam) + + // Erstelle Indexdatei für Eingabe-BAM-Datei + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +Der workflow-Block hat zwei Abschnitte: + +- `main:` enthält die Channel-Operationen und Prozessaufrufe +- `publish:` deklariert, welche Ausgaben veröffentlicht werden sollen, und weist sie benannten Zielen zu + +Du wirst bemerken, dass wir dieselbe `.fromPath`-Channel-Factory verwenden, wie wir sie in [Hello Channels](../../hello_nextflow/02_hello_channels.md) verwendet haben. +Tatsächlich machen wir etwas sehr Ähnliches. +Der Unterschied ist, dass wir Nextflow sagen, nur den Dateipfad selbst in den Channel als Eingabeelement zu laden, anstatt seinen Inhalt einzulesen. + +### 1.4. Füge einen output-Block hinzu, um zu definieren, wo Ergebnisse veröffentlicht werden + +Nach dem workflow-Block fügen wir einen `output`-Block hinzu, der angibt, wo die Workflow-Ausgaben veröffentlicht werden sollen. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Jedes benannte Ziel aus dem `publish:`-Abschnitt (wie `bam_index`) erhält seinen eigenen Block, in dem du den Ausgabepfad relativ zum Basis-Ausgabeverzeichnis konfigurieren kannst. + +!!! note "Hinweis" + + Obwohl die Datendateien, die wir hier verwenden, sehr klein sind, können sie in der Genomik sehr groß werden. + Standardmäßig erstellt Nextflow symbolische Links zu den Ausgabedateien im Veröffentlichungsverzeichnis, was unnötige Dateikopien vermeidet. + Du kannst dieses Verhalten mit der Option `mode` ändern (z.B. `mode 'copy'`), um stattdessen tatsächliche Kopien zu erstellen. + Beachte, dass Symlinks kaputt gehen, wenn du dein `work`-Verzeichnis aufräumst, sodass du für Produktions-Workflows möglicherweise `mode 'copy'` verwenden möchtest. + +### 1.5. Konfiguriere das Ausgabeverzeichnis + +Das Basis-Ausgabeverzeichnis wird über die Konfigurationsoption `outputDir` festgelegt. Füge sie zu `nextflow.config` hinzu: + +=== "Danach" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Vorher" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Führe den Workflow aus, um zu überprüfen, dass der Indexierungsschritt funktioniert + +Lass uns den Workflow ausführen! Zur Erinnerung: Wir müssen keine Eingabe in der Befehlszeile angeben, weil wir einen Standardwert für die Eingabe festgelegt haben, als wir den Eingabeparameter deklariert haben. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Du kannst überprüfen, dass die Indexdatei korrekt generiert wurde, indem du im work-Verzeichnis oder im results-Verzeichnis nachsiehst. + +??? abstract "Work-Verzeichnisinhalt" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Results-Verzeichnisinhalt" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +Da ist sie! + +### Zusammenfassung + +Du weißt, wie du ein Genomik-Tool in einen einstufigen Nextflow-Workflow verpackst und es mit einem Container ausführen lässt. + +### Was kommt als Nächstes? + +Füge einen zweiten Schritt hinzu, der die Ausgabe des ersten verwendet. + +--- + +## 2. Füge einen zweiten Prozess hinzu, um GATK HaplotypeCaller auf der indexierten BAM-Datei auszuführen + +Jetzt, da wir einen Index für unsere Eingabedatei haben, können wir mit dem Einrichten des Variantenerkennungsschritts fortfahren, der der interessante Teil des Workflows ist. + +### 2.1. Definiere den Variantenerkennungsprozess + +Lass uns einen Prozess schreiben, den wir `GATK_HAPLOTYPECALLER` nennen werden, der die Variantenerkennungsoperation beschreibt. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Rufe Varianten mit GATK HaplotypeCaller auf + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Du wirst bemerken, dass wir hier eine neue Syntax (`emit:`) eingeführt haben, um jeden unserer Ausgabekanäle eindeutig zu benennen, und die Gründe dafür werden bald klar werden. + +Dieser Befehl benötigt einige weitere Eingaben, weil GATK mehr Informationen benötigt, um die Analyse durchzuführen, verglichen mit einem einfachen Indexierungsjob. +Aber du wirst feststellen, dass im Eingabeblock noch mehr Eingaben definiert sind, als im GATK-Befehl aufgelistet sind. Warum ist das so? + +!!! note "Hinweis" + + GATK weiß, dass es nach der BAM-Indexdatei und den Zusatzdateien des Referenzgenoms suchen muss, weil es sich der Konventionen bewusst ist, die diese Dateien umgeben. + Nextflow ist jedoch so konzipiert, dass es domänenunabhängig ist und nichts über bioinformatische Dateiformatanforderungen weiß. + +Wir müssen Nextflow explizit mitteilen, dass es diese Dateien zur Laufzeit im Arbeitsverzeichnis bereitstellen muss; andernfalls wird es das nicht tun, und GATK wird (zu Recht) einen Fehler werfen, dass die Indexdateien fehlen. + +Ebenso müssen wir die Indexdatei der Ausgabe-VCF (die Datei `"${input_bam}.vcf.idx"`) explizit auflisten, damit Nextflow weiß, dass es diese Datei im Auge behalten muss, falls sie in nachfolgenden Schritten benötigt wird. + +### 2.2. Füge Definitionen für Zusatzeingaben hinzu + +Da unser neuer Prozess erwartet, dass einige zusätzliche Dateien bereitgestellt werden, richten wir einige CLI-Parameter für sie unter dem Abschnitt `Pipeline parameters` ein, zusammen mit einigen Standardwerten (aus denselben Gründen wie zuvor). + +```groovy title="genomics-1.nf" linenums="8" + // Zusatzdateien + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Erstelle Variablen, um die Zusatzdateipfade zu halten + +Während Hauptdateneingaben dynamisch durch Channels geleitet werden, gibt es zwei Ansätze für die Handhabung von Zusatzdateien. Der empfohlene Ansatz ist das Erstellen expliziter Channels, was den Datenfluss klarer und konsistenter macht. Alternativ kann die Funktion file() zum Erstellen von Variablen für einfachere Fälle verwendet werden, insbesondere wenn du dieselbe Datei in mehreren Prozessen referenzieren musst - beachte jedoch, dass dies immer noch implizit Channels erstellt. <!-- TODO: Klarstellen: Ist das immer noch notwendig bei typisierten Eingaben? --> + +Füge dies zum workflow-Block hinzu (nach der Erstellung von `reads_ch`, innerhalb des `main:`-Abschnitts): + +```groovy title="genomics-1.nf" linenums="79" + // Lade die Dateipfade für die Zusatzdateien (Referenz und Intervalle) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Dies macht die Zusatzdateipfade verfügbar, um sie als Eingabe für alle Prozesse bereitzustellen, die sie benötigen. + +### 2.4. Füge einen Aufruf zum workflow-Block hinzu, um GATK_HAPLOTYPECALLER auszuführen + +Jetzt, da wir unseren zweiten Prozess eingerichtet haben und alle Eingaben und Zusatzdateien bereit und verfügbar sind, können wir einen Aufruf zum `GATK_HAPLOTYPECALLER`-Prozess im workflow-Body hinzufügen. + +```groovy title="genomics-1.nf" linenums="88" + // Rufe Varianten aus der indexierten BAM-Datei auf + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Du solltest die `*.out`-Syntax aus Teil 1 dieser Trainingsreihe wiedererkennen; wir sagen Nextflow, dass es die von `SAMTOOLS_INDEX` ausgegebene Channel-Ausgabe nimmt und diese in den `GATK_HAPLOTYPECALLER`-Prozessaufruf einsteckt. + +!!! note "Hinweis" + + Du wirst bemerken, dass die Eingaben im Aufruf des Prozesses in genau derselben Reihenfolge bereitgestellt werden, in der sie im Eingabeblock des Prozesses aufgelistet sind. + In Nextflow sind Eingaben positionsabhängig, was bedeutet, dass du _derselben Reihenfolge folgen musst_; und natürlich muss es die gleiche Anzahl von Elementen geben. + +### 2.5. Aktualisiere den publish-Abschnitt und den output-Block + +Wir müssen den `publish:`-Abschnitt aktualisieren, um die VCF-Ausgaben einzuschließen, und entsprechende Ziele im `output`-Block hinzufügen. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Führe den Workflow aus, um zu überprüfen, dass der Variantenerkennungsschritt funktioniert + +Lass uns den erweiterten Workflow mit `-resume` ausführen, sodass wir den Indexierungsschritt nicht erneut ausführen müssen. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Wenn wir jetzt die Konsolenausgabe betrachten, sehen wir die beiden aufgelisteten Prozesse. + +Der erste Prozess wurde dank des Cachings übersprungen, wie erwartet, während der zweite Prozess ausgeführt wurde, da er brandneu ist. + +Du findest die Ausgabedateien im results-Verzeichnis (als symbolische Links zum work-Verzeichnis). + +??? abstract "Verzeichnisinhalt" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Wenn du die VCF-Datei öffnest, solltest du denselben Inhalt sehen wie in der Datei, die du durch direktes Ausführen des GATK-Befehls im Container generiert hast. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Dies ist die Ausgabe, die uns wichtig ist, für jede Probe in unserer Studie zu generieren. + +### Zusammenfassung + +Du weißt, wie man einen sehr einfachen zweistufigen Workflow erstellt, der echte Analysearbeit leistet und in der Lage ist, mit Eigenheiten genomischer Dateiformate wie den Zusatzdateien umzugehen. + +### Was kommt als Nächstes? + +Mache den Workflow so, dass er mehrere Proben in großen Mengen verarbeitet. + +--- + +## 3. Passe den Workflow an, um auf mehreren Proben zu laufen + +Es ist schön und gut, einen Workflow zu haben, der die Verarbeitung einer einzelnen Probe automatisieren kann, aber was ist, wenn du 1000 Proben hast? +Musst du ein Bash-Skript schreiben, das durch alle deine Proben läuft? + +Nein, zum Glück! Mache einfach eine kleine Anpassung am Code und Nextflow wird das auch für dich erledigen. + +### 3.1. Verwandle die Eingabeparameterdeklaration in ein Array, das die drei Proben auflistet + +Lass uns diesen Standarddateipfad in der Eingabe-BAM-Dateideklaration in ein Array verwandeln, das Dateipfade für unsere drei Testproben auflistet, oben unter dem Abschnitt `Pipeline parameters`. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="7" + // Primäre Eingabe (Array von drei Proben) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="7" + // Primäre Eingabe + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note "Hinweis" + + Wenn du typisierte Parameterdeklarationen verwendest (wie `reads_bam: Path`), kannst du keinen Array-Wert zuweisen. + Für Arrays lasse die Typannotation weg. + +Und das ist tatsächlich alles, was wir tun müssen, weil die Channel-Factory, die wir im workflow-Body verwenden (`.fromPath`), genauso gerne mehrere Dateipfade akzeptiert, um sie in den Eingabekanal zu laden, wie sie einen einzelnen geladen hat. + +!!! note "Hinweis" + + Normalerweise würdest du die Liste der Proben nicht in deine Workflow-Datei fest codieren wollen, aber wir tun das hier, um die Dinge einfach zu halten. + Wir werden später in dieser Trainingsreihe elegantere Möglichkeiten für die Handhabung von Eingaben präsentieren. + +### 3.2. Führe den Workflow aus, um zu überprüfen, dass er auf allen drei Proben läuft + +Lass uns versuchen, den Workflow jetzt auszuführen, da die Verkabelung so eingerichtet ist, dass sie auf allen drei Testproben läuft. + +```bash +nextflow run genomics-1.nf -resume +``` + +Lustige Sache: Dies _könnte funktionieren_, ODER es _könnte fehlschlagen_. Hier ist zum Beispiel eine Ausführung, die erfolgreich war: + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Wenn deine Workflow-Ausführung erfolgreich war, führe sie erneut aus, bis du einen Fehler wie diesen erhältst: + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Wenn du die GATK-Befehlsfehlerausgabe betrachtest, wird es eine Zeile wie diese geben: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Nun, das ist seltsam, wenn man bedenkt, dass wir die BAM-Dateien explizit im ersten Schritt des Workflows indexiert haben. Könnte es ein Problem mit der Verkabelung geben? + +#### 3.2.1. Überprüfe die work-Verzeichnisse für die relevanten Aufrufe + +Lass uns einen Blick in das work-Verzeichnis für den fehlgeschlagenen `GATK_HAPLOTYPECALLER`-Prozessaufruf werfen, der in der Konsolenausgabe aufgelistet ist. + +??? abstract "Verzeichnisinhalt" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Achte besonders auf die Namen der BAM-Datei und des BAM-Index, die in diesem Verzeichnis aufgelistet sind: `reads_son.bam` und `reads_father.bam.bai`. + +Was zum Teufel? Nextflow hat eine Indexdatei in diesem Prozessaufruf-work-Verzeichnis bereitgestellt, aber es ist die falsche. Wie konnte das passieren? + +#### 3.2.2. Verwende den [view()-Operator](https://www.nextflow.io/docs/latest/reference/operator.html#view), um Channel-Inhalte zu inspizieren + +Füge diese beiden Zeilen im workflow-Body vor dem `GATK_HAPLOTYPER`-Prozessaufruf hinzu: + +```groovy title="genomics-1.nf" linenums="84" + // temporäre Diagnose + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Führe dann den Workflow-Befehl erneut aus. + +```bash +nextflow run genomics-1.nf +``` + +Wieder einmal kann dies erfolgreich sein oder fehlschlagen. Hier ist eine erfolgreiche Ausführung: + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +Und hier ist eine fehlgeschlagene: + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Du musst sie möglicherweise mehrmals ausführen, damit sie erneut fehlschlägt. +Dieser Fehler wird sich nicht konsistent reproduzieren, weil er von einer gewissen Variabilität in den Ausführungszeiten der einzelnen Prozessaufrufe abhängt. + +So sieht die Ausgabe der beiden `.view()`-Aufrufe aus, die wir für eine fehlgeschlagene Ausführung hinzugefügt haben: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +Die ersten drei Zeilen entsprechen dem Eingabekanal und die zweite dem Ausgabekanal. +Du kannst sehen, dass die BAM-Dateien und Indexdateien für die drei Proben nicht in derselben Reihenfolge aufgelistet sind! + +!!! note "Hinweis" + + Wenn du einen Nextflow-Prozess auf einem Channel aufrufst, der mehrere Elemente enthält, wird Nextflow versuchen, die Ausführung so weit wie möglich zu parallelisieren, und wird Ausgaben in der Reihenfolge sammeln, in der sie verfügbar werden. + Die Folge ist, dass die entsprechenden Ausgaben in einer anderen Reihenfolge gesammelt werden können als die ursprünglichen Eingaben eingegeben wurden. + +Wie derzeit geschrieben, geht unser Workflow-Skript davon aus, dass die Indexdateien aus dem Indexierungsschritt in derselben Mutter/Vater/Sohn-Reihenfolge herauskommen, wie die Eingaben gegeben wurden. +Aber das ist nicht garantiert der Fall, weshalb manchmal (aber nicht immer) die falschen Dateien im zweiten Schritt gepaart werden. + +Um dies zu beheben, müssen wir sicherstellen, dass die BAM-Dateien und ihre Indexdateien zusammen durch die Channels reisen. + +!!! tip "Tipp" + + Die `view()`-Anweisungen im Workflow-Code tun nichts, sodass es kein Problem ist, sie drin zu lassen. + Sie werden jedoch deine Konsolenausgabe überladen, daher empfehlen wir, sie zu entfernen, wenn du mit der Fehlerbehebung fertig bist. + +### 3.3. Ändere die Ausgabe des SAMTOOLS_INDEX-Prozesses in ein Tupel, das die Eingabedatei und ihren Index zusammenhält + +Der einfachste Weg, um sicherzustellen, dass eine BAM-Datei und ihr Index eng verbunden bleiben, besteht darin, sie zusammen in ein Tupel zu verpacken, das aus der Indexaufgabe herauskommt. + +!!! note "Hinweis" + + Ein **Tupel** ist eine endliche, geordnete Liste von Elementen, die häufig zum Zurückgeben mehrerer Werte aus einer Funktion verwendet wird. Tupel sind besonders nützlich für die Übergabe mehrerer Ein- oder Ausgaben zwischen Prozessen, während ihre Zuordnung und Reihenfolge erhalten bleibt. + +Zuerst ändern wir die Ausgabe des `SAMTOOLS_INDEX`-Prozesses, um die BAM-Datei in ihre Ausgabedeklaration aufzunehmen. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +Auf diese Weise wird jede Indexdatei eng mit ihrer ursprünglichen BAM-Datei gekoppelt, und die Gesamtausgabe des Indexierungsschritts wird ein einzelner Channel sein, der Dateipaare enthält. + +### 3.4. Ändere die Eingabe zum GATK_HAPLOTYPECALLER-Prozess zu einem Tupel + +Da wir die 'Form' der Ausgabe des ersten Prozesses im Workflow geändert haben, müssen wir die Eingabedefinition des zweiten Prozesses aktualisieren, damit sie übereinstimmt. + +Konkret, wo wir zuvor zwei separate Eingabepfade im Eingabeblock des `GATK_HAPLOTYPECALLER`-Prozesses deklariert haben, deklarieren wir jetzt eine einzelne Eingabe, die der Struktur des von `SAMTOOLS_INDEX` ausgegebenen Tupels entspricht. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Natürlich müssen wir, da wir jetzt die Form der Eingaben geändert haben, die `GATK_HAPLOTYPECALLER` erwartet, den Prozessaufruf entsprechend im workflow-Body aktualisieren. + +### 3.5. Aktualisiere den Aufruf von GATK_HAPLOTYPECALLER im workflow-Block + +Wir müssen nicht mehr das ursprüngliche `reads_ch` an den `GATK_HAPLOTYPECALLER`-Prozess übergeben, da die BAM-Datei jetzt in die Channel-Ausgabe von `SAMTOOLS_INDEX` gebündelt ist. + +Als Ergebnis können wir diese Zeile einfach löschen. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +Das ist die gesamte Neu-Verkabelung, die notwendig ist, um das Index-Mismatch-Problem zu lösen. + +### 3.6. Aktualisiere den publish-Abschnitt und den output-Block für das Tupel + +Da `SAMTOOLS_INDEX.out` jetzt ein Tupel ist, das sowohl die BAM als auch ihren Index enthält, werden beide Dateien zusammen veröffentlicht. +Wir benennen das Ziel von `bam_index` in `indexed_bam` um, um widerzuspiegeln, dass es jetzt beide Dateien enthält. + +=== "Danach" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Wir müssen auch den output-Block aktualisieren, um den neuen Zielnamen zu verwenden: + +=== "Danach" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Führe den Workflow aus, um zu überprüfen, dass er jedes Mal korrekt auf allen drei Proben funktioniert + +Natürlich liegt der Beweis im Pudding, also lass uns den Workflow einige Male erneut ausführen, um sicherzustellen, dass dies zukünftig zuverlässig funktioniert. + +```bash +nextflow run genomics-1.nf +``` + +Dieses Mal (und jedes Mal) sollte alles korrekt laufen: + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Das results-Verzeichnis enthält jetzt sowohl BAM- als auch BAI-Dateien für jede Probe (aus dem Tupel), zusammen mit den VCF-Ausgaben: + +??? abstract "Results-Verzeichnisinhalt" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Wenn du möchtest, kannst du `.view()` erneut verwenden, um einen Blick darauf zu werfen, wie die Inhalte des `SAMTOOLS_INDEX`-Ausgabekanals aussehen: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Du wirst sehen, dass der Channel die drei erwarteten Tupel enthält (Dateipfade zur besseren Lesbarkeit gekürzt). + +```console title="Ausgabe" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Das wird zukünftig viel sicherer sein. + +### Zusammenfassung + +Du weißt, wie du deinen Workflow auf mehreren Proben (unabhängig) ausführen lässt. + +### Was kommt als Nächstes? + +Mache es einfacher, Proben in großen Mengen zu handhaben. + +--- + +## 4. Lasse den Workflow eine Textdatei akzeptieren, die mehrere Eingabedateien enthält + +Eine sehr häufige Methode, um mehrere Dateneingabedateien an einen Workflow zu übergeben, besteht darin, dies mit einer Textdatei zu tun, die die Dateipfade enthält. +Es kann so einfach sein wie eine Textdatei, die einen Dateipfad pro Zeile auflistet und sonst nichts, oder die Datei kann zusätzliche Metadaten enthalten, in welchem Fall sie oft als Samplesheet bezeichnet wird. + +Hier zeigen wir dir, wie du den einfachen Fall machst. + +### 4.1. Untersuche die bereitgestellte Textdatei, die die Eingabedateipfade auflistet + +Wir haben bereits eine Textdatei erstellt, die die Eingabedateipfade auflistet, genannt `sample_bams.txt`, die du im Verzeichnis `data/` finden kannst. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Wie du sehen kannst, haben wir einen Dateipfad pro Zeile aufgelistet, und es sind absolute Pfade. + +!!! note "Hinweis" + + Die Dateien, die wir hier verwenden, befinden sich nur auf dem lokalen Dateisystem deines GitHub Codespaces, aber wir könnten auch auf Dateien im Cloud-Speicher verweisen. + +### 4.2. Aktualisiere den Parameterstandardwert + +Lass uns den Standardwert für unseren `reads_bam`-Eingabeparameter ändern, um auf die `sample_bams.txt`-Datei zu zeigen. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="7" + // Primäre Eingabe (Datei mit Eingabedateien, eine pro Zeile) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="7" + // Primäre Eingabe (Array von drei Proben) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +Auf diese Weise können wir weiterhin faul sein, aber die Liste der Dateien lebt nicht mehr im Workflow-Code selbst, was ein großer Schritt in die richtige Richtung ist. + +### 4.3. Aktualisiere die Channel-Factory, um Zeilen aus einer Datei zu lesen + +Derzeit behandelt unsere Eingabe-Channel-Factory alle Dateien, die wir ihr geben, als die Dateneingaben, die wir dem Indexierungsprozess zuführen möchten. +Da wir ihr jetzt eine Datei geben, die Eingabedateipfade auflistet, müssen wir ihr Verhalten ändern, um die Datei zu parsen und die darin enthaltenen Dateipfade als Dateneingaben zu behandeln. + +Glücklicherweise können wir das sehr einfach tun, indem wir einfach den [`.splitText()`-Operator](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) zum Channel-Konstruktionsschritt hinzufügen. + +=== "Danach" + + ```groovy title="genomics-1.nf" linenums="68" + // Erstelle Eingabekanal aus einer Textdatei, die Eingabedateipfade auflistet + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Vorher" + + ```groovy title="genomics-1.nf" linenums="68" + // Erstelle Eingabekanal (einzelne Datei über CLI-Parameter) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip "Tipp" + + Dies ist eine weitere großartige Gelegenheit, den `.view()`-Operator zu verwenden, um zu sehen, wie die Channel-Inhalte vor und nach der Anwendung eines Operators aussehen. + +### 4.4. Führe den Workflow aus, um zu überprüfen, dass er korrekt funktioniert + +Lass uns den Workflow noch einmal ausführen. Dies sollte dasselbe Ergebnis wie zuvor produzieren, richtig? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3 diff --git a/docs/de/docs/nf4_science/genomics/02_joint_calling.md b/docs/de/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..d77154cfc7 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1020 @@ +# Teil 2: Joint Calling auf einer Kohorte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil dieses Kurses hast du eine Variant-Calling-Pipeline erstellt, die komplett linear war und die Daten jeder Probe unabhängig von den anderen verarbeitet hat. +In einem echten Genomik-Anwendungsfall musst du jedoch normalerweise die Variant Calls mehrerer Proben gemeinsam betrachten. + +In diesem zweiten Teil zeigen wir dir, wie du Channels und Channel-Operatoren verwendest, um Joint Variant Calling mit GATK zu implementieren, aufbauend auf der Pipeline aus Teil 1. + +### Übersicht über die Methode + +Die GATK-Variant-Calling-Methode, die wir im ersten Teil dieses Kurses verwendet haben, hat einfach Variant Calls pro Probe generiert. +Das ist in Ordnung, wenn du dir nur die Varianten jeder Probe isoliert ansehen möchtest, aber das liefert nur begrenzte Informationen. +Es ist oft interessanter zu betrachten, wie sich Variant Calls über mehrere Proben hinweg unterscheiden, und dafür bietet GATK eine alternative Methode namens Joint Variant Calling, die wir hier demonstrieren. + +Joint Variant Calling beinhaltet die Generierung einer speziellen Art von Variant-Ausgabe namens GVCF (für Genomic VCF) für jede Probe, dann die Kombination der GVCF-Daten aller Proben und schließlich die Durchführung einer statistischen Analyse namens 'Joint Genotyping'. + +![Joint-Analyse](img/joint-calling.png) + +Das Besondere an einer Proben-GVCF ist, dass sie Einträge enthält, die Sequenzdatenstatistiken über alle Positionen im Zielbereich des Genoms zusammenfassen, nicht nur die Positionen, an denen das Programm Hinweise auf Variation gefunden hat. +Das ist entscheidend für die Joint-Genotyping-Berechnung ([weiterführende Informationen](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +Die GVCF wird von GATK HaplotypeCaller erzeugt, demselben Tool, das wir in Teil 1 verwendet haben, mit einem zusätzlichen Parameter (`-ERC GVCF`). +Die Kombination der GVCFs erfolgt mit GATK GenomicsDBImport, das die Calls pro Probe in einen Datenspeicher (analog zu einer Datenbank) kombiniert, dann wird die eigentliche 'Joint Genotyping'-Analyse mit GATK GenotypeGVCFs durchgeführt. + +### Workflow + +Um zusammenzufassen, in diesem Teil des Kurses werden wir einen Workflow entwickeln, der Folgendes tut: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Generiere eine Indexdatei für jede BAM-Eingabedatei mit Samtools +2. Führe GATK HaplotypeCaller auf jeder BAM-Eingabedatei aus, um eine GVCF mit genomischen Variant Calls pro Probe zu generieren +3. Sammle alle GVCFs und kombiniere sie in einen GenomicsDB-Datenspeicher +4. Führe Joint Genotyping auf dem kombinierten GVCF-Datenspeicher aus, um eine VCF auf Kohorten-Ebene zu erzeugen + +Wir wenden dies auf denselben Datensatz wie in Teil 1 an. + +--- + +## 0. Aufwärmen: Samtools und GATK direkt ausführen + +Genau wie zuvor möchten wir die Befehle manuell ausprobieren, bevor wir versuchen, sie in einen Workflow zu verpacken. + +!!! note + + Stelle sicher, dass du im richtigen Arbeitsverzeichnis bist: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Eine BAM-Eingabedatei mit Samtools indizieren + +Dieser erste Schritt ist derselbe wie in Teil 1, sollte sich also sehr vertraut anfühlen, aber dieses Mal müssen wir es für alle drei Proben tun. + +!!! note + + Wir haben technisch gesehen bereits Indexdateien für die drei Proben durch unsere Pipeline generiert, also könnten wir diese aus dem Ergebnisverzeichnis holen. Es ist jedoch sauberer, dies einfach manuell zu wiederholen, und es dauert nur eine Minute. + +#### 0.1.1. Den Samtools-Container interaktiv starten + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.1.2. Den Indizierungsbefehl für die drei Proben ausführen + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Genau wie zuvor sollte dies die Indexdateien im selben Verzeichnis wie die entsprechenden BAM-Dateien erzeugen. + +??? abstract "Verzeichnisinhalt" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Jetzt, da wir Indexdateien für alle drei Proben haben, können wir mit der Generierung der GVCFs für jede von ihnen fortfahren. + +#### 0.1.3. Den Samtools-Container verlassen + +```bash +exit +``` + +### 0.2. Varianten mit GATK HaplotypeCaller im GVCF-Modus aufrufen + +Dieser zweite Schritt ist dem sehr ähnlich, was wir in Teil 1 getan haben: Hello Genomics, aber wir werden GATK jetzt im 'GVCF-Modus' ausführen. + +#### 0.2.1. Den GATK-Container interaktiv starten + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +#### 0.2.2. Den Variant-Calling-Befehl mit der GVCF-Option ausführen + +Um eine genomische VCF (GVCF) zu erzeugen, fügen wir die Option `-ERC GVCF` zum Basisbefehl hinzu, was den GVCF-Modus von HaplotypeCaller aktiviert. + +Wir ändern auch die Dateierweiterung für die Ausgabedatei von `.vcf` zu `.g.vcf`. +Dies ist technisch gesehen keine Anforderung, aber es ist eine stark empfohlene Konvention. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Dies erzeugt die GVCF-Ausgabedatei `reads_mother.g.vcf` im aktuellen Arbeitsverzeichnis im Container. + +Wenn du sie mit `cat` anzeigst, um den Inhalt zu sehen, wirst du feststellen, dass sie viel länger ist als die entsprechende VCF, die wir in Teil 1 generiert haben. Du kannst nicht einmal zum Anfang der Datei hochscrollen, und die meisten Zeilen sehen ganz anders aus als das, was wir in der VCF in Teil 1 gesehen haben. + +```console title="Ausgabe" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Diese repräsentieren Nicht-Varianten-Regionen, in denen der Variant Caller keine Hinweise auf Variation gefunden hat, daher hat er einige Statistiken erfasst, die sein Vertrauen in das Fehlen von Variation beschreiben. Dies ermöglicht es, zwischen zwei sehr unterschiedlichen Fällen zu unterscheiden: (1) es gibt qualitativ hochwertige Daten, die zeigen, dass die Probe homozygot-Referenz ist, und (2) es sind nicht genügend gute Daten verfügbar, um eine Bestimmung vorzunehmen. + +In einer GVCF gibt es typischerweise viele solcher Nicht-Varianten-Zeilen, mit einer kleineren Anzahl von Varianten-Einträgen, die dazwischen verstreut sind. Versuche, `head -176` auf der GVCF auszuführen, um nur die ersten 176 Zeilen der Datei zu laden, um einen tatsächlichen Variant Call zu finden. + +```console title="Ausgabe" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +Die zweite Zeile zeigt den ersten Varianten-Eintrag in der Datei, der der ersten Variante in der VCF-Datei entspricht, die wir uns in Teil 1 angesehen haben. + +Genau wie die ursprüngliche VCF wird auch die GVCF-Ausgabedatei von einer Indexdatei begleitet, genannt `reads_mother.g.vcf.idx`. + +#### 0.2.3. Den Prozess auf den anderen beiden Proben wiederholen + +Um den Joint-Genotyping-Schritt zu testen, benötigen wir GVCFs für alle drei Proben, also generieren wir diese jetzt manuell. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Sobald dies abgeschlossen ist, solltest du drei Dateien mit der Endung `.g.vcf` in deinem aktuellen Verzeichnis haben (eine pro Probe) und ihre jeweiligen Indexdateien mit der Endung `.g.vcf.idx`. + +### 0.3. Joint Genotyping ausführen + +Jetzt, da wir alle GVCFs haben, können wir endlich den Joint-Genotyping-Ansatz zur Generierung von Variant Calls für eine Kohorte von Proben ausprobieren. +Zur Erinnerung: Es ist eine zweistufige Methode, die darin besteht, die Daten aus allen GVCFs in einen Datenspeicher zu kombinieren und dann die eigentliche Joint-Genotyping-Analyse durchzuführen, um die finale VCF der gemeinsam aufgerufenen Varianten zu generieren. + +#### 0.3.1. Alle Proben-GVCFs kombinieren + +Dieser erste Schritt verwendet ein weiteres GATK-Tool namens GenomicsDBImport, um die Daten aus allen GVCFs in einen GenomicsDB-Datenspeicher zu kombinieren. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Die Ausgabe dieses Schritts ist effektiv ein Verzeichnis, das eine Reihe weiterer verschachtelter Verzeichnisse enthält, die die kombinierten Variantendaten in Form mehrerer verschiedener Dateien enthalten. +Du kannst darin herumstöbern, aber du wirst schnell sehen, dass dieses Datenspeicherformat nicht dafür gedacht ist, direkt von Menschen gelesen zu werden. + +!!! note + + GATK enthält Tools, die es ermöglichen, Variant-Call-Daten aus dem Datenspeicher bei Bedarf zu inspizieren und zu extrahieren. + +#### 0.3.2. Die eigentliche Joint-Genotyping-Analyse ausführen + +Dieser zweite Schritt verwendet noch ein weiteres GATK-Tool namens GenotypeGVCFs, um Variantenstatistiken und individuelle Genotypen im Lichte der über alle Proben in der Kohorte verfügbaren Daten neu zu berechnen. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Dies erzeugt die VCF-Ausgabedatei `family_trio.vcf` im aktuellen Arbeitsverzeichnis im Container. +Es ist eine weitere relativ kleine Datei, sodass du diese Datei mit `cat` anzeigen kannst, um ihren Inhalt zu sehen, und nach oben scrollen kannst, um die ersten Variantenzeilen zu finden. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Dies sieht eher wie die ursprüngliche VCF aus, die wir in Teil 1 generiert haben, außer dass wir diesmal Informationen auf Genotyp-Ebene für alle drei Proben haben. +Die letzten drei Spalten in der Datei sind die Genotyp-Blöcke für die Proben, aufgelistet in alphabetischer Reihenfolge. + +Wenn wir uns die aufgerufenen Genotypen für unser Test-Familien-Trio für die allererste Variante ansehen, sehen wir, dass der Vater heterozygot-variant (`0/1`) ist und Mutter und Sohn beide homozygot-variant (`1/1`) sind. + +Das ist letztendlich die Information, die wir aus dem Datensatz extrahieren möchten! Also lass uns all dies in einen Nextflow-Workflow packen, damit wir dies im großen Maßstab tun können. + +#### 0.3.3. Den GATK-Container verlassen + +```bash +exit +``` + +### Erkenntnis + +Du weißt, wie du die einzelnen Befehle, die am Joint Variant Calling beteiligt sind, im Terminal ausführst, um zu überprüfen, dass sie die gewünschten Informationen erzeugen. + +### Was kommt als Nächstes? + +Diese Befehle in eine tatsächliche Pipeline verpacken. + +--- + +## 1. Den Variant-Calling-Schritt pro Probe modifizieren, um eine GVCF zu erzeugen + +Die gute Nachricht ist, dass wir nicht ganz von vorne anfangen müssen, da wir bereits einen Workflow geschrieben haben, der einen Teil dieser Arbeit in Teil 1 erledigt. +Allerdings erzeugt diese Pipeline VCF-Dateien, wohingegen wir jetzt GVCF-Dateien wollen, um das Joint Genotyping durchzuführen. +Wir müssen also damit beginnen, den GVCF-Variant-Calling-Modus zu aktivieren und die Dateierweiterung der Ausgabe zu aktualisieren. + +!!! note + + Der Einfachheit halber werden wir mit einer neuen Kopie des GATK-Workflows arbeiten, wie er am Ende von Teil 1 steht, aber unter einem anderen Namen: `genomics-2.nf`. + +### 1.1. HaplotypeCaller mitteilen, eine GVCF auszugeben, und die Ausgabeerweiterung aktualisieren + +Öffnen wir die Datei `genomics-2.nf` im Code-Editor. +Sie sollte sehr vertraut aussehen, aber du kannst sie gerne ausführen, wenn du dich davon überzeugen möchtest, dass sie wie erwartet läuft. + +Wir werden damit beginnen, zwei Änderungen vorzunehmen: + +- Füge den Parameter `-ERC GVCF` zum GATK-HaplotypeCaller-Befehl hinzu; +- Aktualisiere den Ausgabedateipfad, um die entsprechende `.g.vcf`-Erweiterung zu verwenden, gemäß der GATK-Konvention. + +Stelle sicher, dass du einen Backslash (`\`) am Ende der vorherigen Zeile hinzufügst, wenn du `-ERC GVCF` hinzufügst. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +Und das ist alles, was nötig ist, um HaplotypeCaller dazu zu bringen, GVCFs statt VCFs zu generieren, oder? + +### 1.2. Die Pipeline ausführen, um zu überprüfen, dass du GVCFs generieren kannst + +Der Nextflow-Ausführungsbefehl ist derselbe wie zuvor, bis auf den Workflow-Dateinamen selbst. +Stelle sicher, dass du ihn entsprechend aktualisierst. + +```bash +nextflow run genomics-2.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +Und die Ausgabe ist... ganz rot! Oh nein. + +Der ausgeführte Befehl ist korrekt, also hatten wir recht, dass das ausreichte, um das Verhalten des GATK-Tools zu ändern. +Aber schau dir diese Zeile über die fehlende Ausgabedatei an. Fällt dir etwas auf? + +Das stimmt, wir haben vergessen, Nextflow mitzuteilen, dass es einen neuen Dateinamen erwarten soll. Ups. + +### 1.3. Die Ausgabedateierweiterung auch im Prozessausgabe-Block aktualisieren + +Denn es reicht nicht aus, nur die Dateierweiterung im Tool-Befehl selbst zu ändern, du musst Nextflow auch mitteilen, dass sich der erwartete Ausgabedateiname geändert hat. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Die Publish-Ziele für die neuen GVCF-Ausgaben aktualisieren + +Da wir jetzt GVCFs statt VCFs erzeugen, sollten wir den `publish:`-Abschnitt des Workflows aktualisieren, um aussagekräftigere Namen zu verwenden. +Wir werden die GVCF-Dateien auch der Übersichtlichkeit halber in ihr eigenes Unterverzeichnis organisieren. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Den Output-Block für die neue Verzeichnisstruktur aktualisieren + +Wir müssen auch den `output`-Block aktualisieren, um die GVCF-Dateien in ein `gvcf`-Unterverzeichnis zu legen. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Die Pipeline erneut ausführen + +Lass uns sie diesmal mit `-resume` ausführen. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Diesmal funktioniert es. + +Die Nextflow-Ausgabe selbst sieht nicht anders aus (verglichen mit einem erfolgreichen Lauf im normalen VCF-Modus), aber jetzt können wir die `.g.vcf`-Dateien und ihre jeweiligen Indexdateien für alle drei Proben finden, organisiert in Unterverzeichnissen. + +??? abstract "Verzeichnisinhalt (Symlinks gekürzt)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Wenn du eine der GVCF-Dateien öffnest und durchblätterst, kannst du überprüfen, dass GATK HaplotypeCaller GVCF-Dateien wie angefordert erzeugt hat. + +### Erkenntnis + +Okay, diese hier war minimal in Bezug auf das Nextflow-Lernen... +Aber es war eine schöne Gelegenheit, die Bedeutung des Prozessausgabe-Blocks zu wiederholen! + +### Was kommt als Nächstes? + +Lerne, die Inhalte eines Channels zu sammeln und sie als einzelne Eingabe an den nächsten Prozess weiterzugeben. + +--- + +## 2. Die GVCF-Daten über alle Proben hinweg sammeln und kombinieren + +Wir müssen jetzt die Daten aus allen Proben-GVCFs in eine Form kombinieren, die die Joint-Genotyping-Analyse unterstützt, die wir durchführen möchten. + +### 2.1. Den Prozess definieren, der die GVCFs kombiniert + +Zur Erinnerung an das, was wir früher im Aufwärmabschnitt getan haben: Das Kombinieren der GVCFs ist eine Aufgabe für das GATK-Tool GenomicsDBImport, das einen Datenspeicher im sogenannten GenomicsDB-Format erzeugt. + +Lass uns einen neuen Prozess schreiben, um zu definieren, wie das funktionieren wird, basierend auf dem Befehl, den wir früher im Aufwärmabschnitt verwendet haben. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Kombiniere GVCFs in einen GenomicsDB-Datenspeicher + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +Was denkst du, sieht vernünftig aus? + +Lass es uns verdrahten und sehen, was passiert. + +### 2.2. Einen `cohort_name`-Parameter mit einem Standardwert hinzufügen + +Wir müssen einen beliebigen Namen für die Kohorte angeben. +Später in der Trainingsreihe wirst du lernen, wie du Proben-Metadaten für so etwas verwendest, aber vorerst deklarieren wir einfach einen CLI-Parameter mit `params` und geben ihm der Einfachheit halber einen Standardwert. + +```groovy title="genomics-2.nf" linenums="16" + // Basisname für finale Ausgabedatei + cohort_name: String = "family_trio" +``` + +### 2.3. Die Ausgaben von GATK_HAPLOTYPECALLER über die Proben hinweg sammeln + +Wenn wir einfach den Ausgabe-Channel vom `GATK_HAPLOTYPECALLER`-Prozess so wie er ist einstecken würden, würde Nextflow den Prozess für jede Proben-GVCF separat aufrufen. +Wir möchten jedoch alle drei GVCFs (und ihre Indexdateien) so bündeln, dass Nextflow sie alle zusammen an einen einzelnen Prozessaufruf übergibt. + +Gute Nachrichten: Wir können das mit dem `collect()`-Channel-Operator tun. Fügen wir die folgenden Zeilen zum `workflow`-Body hinzu, direkt nach dem Aufruf von GATK_HAPLOTYPECALLER: + +```groovy title="genomics-2.nf" linenums="118" +// Sammle Variant-Calling-Ausgaben über Proben hinweg +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Erscheint das etwas kompliziert? Lass uns das aufschlüsseln und in einfache Sprache übersetzen. + +1. Wir nehmen den Ausgabe-Channel vom `GATK_HAPLOTYPECALLER`-Prozess, der mit der `.out`-Eigenschaft referenziert wird. +2. Jedes 'Element', das aus dem Channel kommt, ist ein Paar von Dateien: die GVCF und ihre Indexdatei, in dieser Reihenfolge, weil das die Reihenfolge ist, in der sie im Prozessausgabe-Block aufgelistet sind. Praktischerweise können wir, weil wir in der letzten Session die Ausgaben dieses Prozesses benannt haben (mit `emit:`), die GVCFs einerseits durch Hinzufügen von `.vcf` und die Indexdateien andererseits durch Hinzufügen von `.idx` nach der `.out`-Eigenschaft herauspicken. Hätten wir diese Ausgaben nicht benannt, hätten wir sie mit `.out[0]` bzw. `.out[1]` referenzieren müssen. +3. Wir hängen den `collect()`-Channel-Operator an, um alle GVCF-Dateien zusammen in ein einzelnes Element in einem neuen Channel namens `all_gvcfs_ch` zu bündeln, und machen dasselbe mit den Indexdateien, um den neuen Channel namens `all_idxs_ch` zu bilden. + +!!! tip + + Wenn du dir schwer vorstellen kannst, was hier genau passiert, denke daran, dass du den `view()`-Operator verwenden kannst, um den Inhalt von Channels vor und nach der Anwendung von Channel-Operatoren zu inspizieren. + +Die resultierenden `all_gvcfs_ch`- und `all_idxs_ch`-Channels sind das, was wir in den `GATK_GENOMICSDB`-Prozess einstecken werden, den wir gerade geschrieben haben. + +!!! note + + Falls du dich gefragt hast: Wir sammeln die GVCFs und ihre Indexdateien separat, weil der GATK-GenomicsDBImport-Befehl nur die GVCF-Dateipfade sehen möchte. Glücklicherweise müssen wir uns nicht um die Reihenfolge der Dateien kümmern wie bei BAMs und ihrem Index in Teil 1, da Nextflow alle Dateien zusammen zur Ausführung bereitstellt. + +### 2.4. Einen Aufruf zum Workflow-Block hinzufügen, um GATK_GENOMICSDB auszuführen + +Wir haben einen Prozess und wir haben Eingabe-Channels. Wir müssen nur den Prozessaufruf hinzufügen. + +```groovy title="genomics-2.nf" linenums="122" + // Kombiniere GVCFs in einen GenomicsDB-Datenspeicher + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, alles ist verdrahtet. + +### 2.5. Den Workflow ausführen + +Lass uns sehen, ob das funktioniert. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Es läuft ziemlich schnell, da wir mit `-resume` laufen, aber es schlägt fehl! + +Ah. Auf der positiven Seite sehen wir, dass Nextflow den `GATK_GENOMICSDB`-Prozess aufgenommen hat und ihn speziell nur einmal aufgerufen hat. +Das deutet darauf hin, dass der `collect()`-Ansatz bis zu einem gewissen Grad funktioniert hat. +Aber, und das ist ein großes Aber, der Prozessaufruf ist fehlgeschlagen. + +Wenn wir uns die Konsolenausgabe oben genauer ansehen, können wir sehen, dass der ausgeführte Befehl nicht korrekt ist. + +Kannst du den Fehler erkennen? +Schau dir diesen Teil an: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Wir haben `gatk GenomicsDBImport` mehrere GVCF-Dateien für ein einzelnes `-V`-Argument gegeben, aber das Tool erwartet ein separates `-V`-Argument für jede GVCF-Datei. + +Zur Erinnerung, das war der Befehl, den wir im Container ausgeführt haben: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Das bedeutet also, dass wir unser Bündel von GVCF-Dateien irgendwie in einen korrekt formatierten Befehlsstring umwandeln müssen. + +### 2.6. Eine Befehlszeile mit einem separaten `-V`-Argument für jede Eingabe-GVCF konstruieren + +Hier kommt es uns zugute, dass Nextflow auf Groovy basiert, denn es wird uns ermöglichen, einige ziemlich einfache String-Manipulationen zu verwenden, um den notwendigen Befehlsstring zu konstruieren. + +Speziell unter Verwendung dieser Syntax: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Noch einmal, lass uns das in seine Komponenten aufschlüsseln. + +1. Zuerst nehmen wir den Inhalt des `all_gvcfs`-Eingabe-Channels und wenden `.collect()` darauf an (genau wie vorher). +2. Das ermöglicht es uns, jeden einzelnen GVCF-Dateipfad im Bündel an die **Closure**, `{ gvcf -> "-V ${gvcf}" }`, zu übergeben, wobei `gvcf` sich auf diesen GVCF-Dateipfad bezieht. + Die Closure ist eine Mini-Funktion, die wir verwenden, um `-V ` dem Dateipfad voranzustellen, in der Form von `"-V ${gvcf}"`. +3. Dann verwenden wir `.join(' ')`, um alle drei Strings mit einem einzigen Leerzeichen als Trennzeichen zu verketten. + +Mit einem konkreten Beispiel sieht es so aus: + +1. Wir haben drei Dateien: + + `[A.ext, B.ext, C.ext]` + +2. Die Closure modifiziert jede einzelne, um die Strings zu erstellen: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. Die `.join(' ')`-Operation generiert den finalen String: + + `"-V A.ext -V B.ext -V C.ext"` + +Sobald wir diesen String haben, können wir ihn einer lokalen Variable `gvcfs_line` zuweisen, die mit dem `def`-Schlüsselwort definiert ist: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, also haben wir unser String-Manipulations-Ding. Wo platzieren wir es? + +Wir möchten, dass dies irgendwo innerhalb der Prozessdefinition steht, weil wir es machen möchten, _nachdem_ wir die GVCF-Dateipfade in den Prozess kanalisiert haben. +Das liegt daran, dass Nextflow sie als Dateipfade sehen muss, um die Dateien selbst korrekt zur Ausführung bereitzustellen. + +Aber _wo_ im Prozess können wir das hinzufügen? + +Fun Fact: Du kannst beliebigen Code nach `script:` und vor den `"""` hinzufügen! + +Großartig, dann fügen wir unsere String-Manipulations-Zeile dort hinzu und aktualisieren den `gatk GenomicsDBImport`-Befehl, um den verketteten String zu verwenden, den sie erzeugt. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Das sollte alles sein, was nötig ist, um die Eingaben korrekt an `gatk GenomicsDBImport` zu übergeben. + +!!! tip + + Wenn du den `gatk GenomicsDBImport`-Befehl aktualisierst, stelle sicher, dass du das `-V `-Präfix entfernst, wenn du die `${gvcfs_line}`-Variable einsetzt. + +### 2.7. Den Workflow ausführen, um zu überprüfen, dass er die GenomicsDB-Ausgabe wie erwartet generiert + +Alles klar, lass uns sehen, ob das das Problem behoben hat. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha! Es scheint jetzt zu funktionieren. + +Die ersten beiden Schritte wurden erfolgreich übersprungen, und der dritte Schritt hat diesmal einwandfrei funktioniert. +Der GenomicsDB-Datenspeicher wird im Work-Verzeichnis erstellt, aber nicht in den Ergebnissen veröffentlicht, da es nur ein Zwischenformat ist, das wir für Joint Genotyping verwenden werden. + +Übrigens mussten wir nichts Besonderes tun, um damit umzugehen, dass die Ausgabe ein Verzeichnis anstelle einer einzelnen Datei ist. + +### Erkenntnis + +Jetzt weißt du, wie du Ausgaben aus einem Channel sammelst und sie als einzelne Eingabe an einen anderen Prozess bündelst. +Du weißt auch, wie du eine Befehlszeile konstruierst, um Eingaben an ein bestimmtes Tool mit der entsprechenden Syntax zu übergeben. + +### Was kommt als Nächstes? + +Lerne, wie du einen zweiten Befehl zum selben Prozess hinzufügst. + +--- + +## 3. Den Joint-Genotyping-Schritt als Teil desselben Prozesses ausführen + +Jetzt, da wir die kombinierten genomischen Variant Calls haben, können wir das Joint-Genotyping-Tool ausführen, das die finale Ausgabe erzeugt, die uns tatsächlich interessiert: die VCF der Variant Calls auf Kohorten-Ebene. + +Aus logistischen Gründen entscheiden wir uns, das Joint Genotyping innerhalb desselben Prozesses einzuschließen. + +### 3.1. Den Prozess von GATK_GENOMICSDB in GATK_JOINTGENOTYPING umbenennen + +Da der Prozess mehr als ein Tool ausführt, ändern wir seinen Namen, um sich auf die Gesamtoperation zu beziehen, anstatt auf einen einzelnen Tool-Namen. + +=== "Danach" + + ```groovy title="genomics-2.nf" + /* + * Kombiniere GVCFs in einen GenomicsDB-Datenspeicher und führe Joint Genotyping aus, um Calls auf Kohorten-Ebene zu erzeugen + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" + /* + * Kombiniere GVCFs in einen GenomicsDB-Datenspeicher + */ + process GATK_GENOMICSDB { + ``` + +Denke daran, deine Prozessnamen so beschreibend wie möglich zu halten, um die Lesbarkeit für deine Kollegen – und dein zukünftiges Ich – zu maximieren! + +### 3.2. Den Joint-Genotyping-Befehl zum GATK_JOINTGENOTYPING-Prozess hinzufügen + +Füge einfach den zweiten Befehl nach dem ersten innerhalb des Script-Abschnitts hinzu. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Die beiden Befehle werden seriell ausgeführt, auf die gleiche Weise, wie sie ausgeführt würden, wenn wir sie manuell im Terminal ausführen würden. + +### 3.3. Die Referenzgenomdateien zu den GATK_JOINTGENOTYPING-Prozess-Eingabedefinitionen hinzufügen + +Der zweite Befehl benötigt die Referenzgenomdateien, also müssen wir diese zu den Prozesseingaben hinzufügen. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Es mag lästig erscheinen, diese auszutippen, aber denke daran, du tippst sie nur einmal, und dann kannst du den Workflow eine Million Mal ausführen. Lohnt sich das? + +### 3.4. Die Prozessausgabedefinition aktualisieren, um die VCF mit Variant Calls auf Kohorten-Ebene auszugeben + +Wir kümmern uns nicht wirklich darum, den GenomicsDB-Datenspeicher zu speichern, der nur ein Zwischenformat ist, das nur aus logistischen Gründen existiert, also können wir ihn einfach aus dem Output-Block entfernen, wenn wir möchten. + +Die Ausgabe, an der wir tatsächlich interessiert sind, ist die VCF, die vom Joint-Genotyping-Befehl erzeugt wird. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Wir sind fast fertig! + +### 3.5. Den Prozessaufruf von GATK_GENOMICSDB in GATK_JOINTGENOTYPING aktualisieren + +Vergessen wir nicht, den Prozessaufruf im Workflow-Body von GATK_GENOMICSDB in GATK_JOINTGENOTYPING umzubenennen. Und während wir dabei sind, sollten wir auch die Referenzgenomdateien als Eingaben hinzufügen, da wir sie dem Joint-Genotyping-Tool bereitstellen müssen. + +=== "Danach" + + ```groovy title="genomics-2.nf" linenums="126" + // Kombiniere GVCFs in einen GenomicsDB-Datenspeicher und wende Joint Genotyping an + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Davor" + + ```groovy title="genomics-2.nf" linenums="126" + // Kombiniere GVCFs in einen GenomicsDB-Datenspeicher + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Jetzt ist der Prozess vollständig verdrahtet. + +### 3.6. Die gemeinsame VCF zum Publish-Abschnitt hinzufügen + +Wir müssen die gemeinsamen VCF-Ausgaben vom neuen Prozess veröffentlichen. +Füge diese Zeilen zum `publish:`-Abschnitt des Workflows hinzu: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Die gemeinsamen VCF-Ziele zum Output-Block hinzufügen + +Füge schließlich Output-Ziele für die gemeinsamen VCF-Dateien hinzu. +Wir werden sie im Root des Ergebnisverzeichnisses platzieren, da dies die finale Ausgabe ist. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Jetzt sollte alles vollständig verdrahtet sein. + +### 3.8. Den Workflow ausführen + +Schließlich können wir den modifizierten Workflow ausführen... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Und es funktioniert! + +Du findest die finale Ausgabedatei `family_trio.joint.vcf` (und ihren Dateiindex) im Ergebnisverzeichnis. + +??? abstract "Verzeichnisinhalt (Symlinks gekürzt)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Wenn du der skeptische Typ bist, kannst du auf die gemeinsame VCF-Datei klicken, um sie zu öffnen, und überprüfen, dass der Workflow dieselben Variant Calls generiert hat, die du erhalten hast, indem du die Tools zu Beginn dieses Abschnitts manuell ausgeführt hast. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Du hast jetzt einen automatisierten, vollständig reproduzierbaren Joint-Variant-Calling-Workflow! + +!!! note + + Bedenke, dass die Datendateien, die wir dir gegeben haben, nur einen winzigen Teil von Chromosom 20 abdecken. + Die tatsächliche Größe eines Variant-Callsets würde in Millionen von Varianten gezählt werden. + Deshalb verwenden wir nur winzige Teilmengen von Daten zu Trainingszwecken! + +### Erkenntnis + +Du weißt, wie du einige gängige diff --git a/docs/de/docs/nf4_science/genomics/03_modules.md b/docs/de/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..8f6351d1e5 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Teil 3: Code in Module verschieben + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil dieses Kurses hast du eine Variant-Calling-Pipeline erstellt, die vollständig linear war und die Daten jeder Probe unabhängig von den anderen verarbeitet hat. + +Im zweiten Teil haben wir dir gezeigt, wie du Channels und Channel-Operatoren verwendest, um Joint-Variant-Calling mit GATK zu implementieren und dabei auf der Pipeline aus Teil 1 aufzubauen. + +In diesem Teil zeigen wir dir, wie du den Code in diesem Workflow in Module umwandelst. Um diesem Teil des Trainings zu folgen, solltest du Teil 1 und Teil 2 sowie [Hello Modules](../../../hello_nextflow/hello_modules.md) abgeschlossen haben, das die Grundlagen von Modulen behandelt. + +--- + +## 0. Aufwärmen + +Als wir begonnen haben, unseren Workflow zu entwickeln, haben wir alles in eine einzige Code-Datei gepackt. +Jetzt ist es an der Zeit, unseren Code zu **modularisieren**, _d.h._ die Prozess-Definitionen in Module zu extrahieren. + +Wir beginnen mit demselben Workflow wie in Teil 2, den wir für dich in der Datei `genomics-3.nf` bereitgestellt haben. + +!!! note "Hinweis" + + Stelle sicher, dass du im richtigen Arbeitsverzeichnis bist: + `cd /workspaces/training/nf4-science/genomics` + +Führe den Workflow aus, um den Ausgangspunkt zu überprüfen: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Ausgabe" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Es gibt nun ein `work`-Verzeichnis und ein `results_genomics`-Verzeichnis in deinem Projektverzeichnis. + +### Zusammenfassung + +Du bist bereit, mit der Modularisierung deines Workflows zu beginnen. + +### Wie geht es weiter? + +Verschiebe die Prozesse des Genomics-Workflows in Module. + +--- + +## 1. Prozesse in Module verschieben + +Wie du in [Hello Modules](../../../hello_nextflow/hello_modules.md) gelernt hast, kannst du ein Modul einfach erstellen, indem du die Prozess-Definition in eine eigene Datei kopierst, in einem beliebigen Verzeichnis, und du kannst diese Datei beliebig benennen. + +Aus Gründen, die später klar werden (insbesondere wenn wir zum Testen kommen), werden wir in diesem Training der Konvention folgen, die Datei `main.nf` zu nennen und sie in eine Verzeichnisstruktur zu legen, die nach dem Toolkit und dem Befehl benannt ist. + +### 1.1. Erstelle ein Modul für den `SAMTOOLS_INDEX`-Prozess + +Im Fall des `SAMTOOLS_INDEX`-Prozesses ist 'samtools' das Toolkit und 'index' der Befehl. Wir erstellen also eine Verzeichnisstruktur `modules/samtools/index` und legen die `SAMTOOLS_INDEX`-Prozess-Definition in die `main.nf`-Datei in diesem Verzeichnis. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Öffne die `main.nf`-Datei und kopiere die `SAMTOOLS_INDEX`-Prozess-Definition hinein. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * BAM-Index-Datei generieren + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Entferne dann die `SAMTOOLS_INDEX`-Prozess-Definition aus `genomics-3.nf` und füge eine Import-Deklaration für das Modul vor der nächsten Prozess-Definition hinzu, so wie hier: + +=== "Nachher" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Module einbinden + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Varianten mit GATK HaplotypeCaller aufrufen + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Vorher" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Varianten mit GATK HaplotypeCaller aufrufen + */ + process GATK_HAPLOTYPECALLER { + ``` + +Du kannst den Workflow jetzt erneut ausführen, und er sollte immer noch auf die gleiche Weise funktionieren. Wenn du das Flag `-resume` verwendest, sollten nicht einmal neue Aufgaben ausgeführt werden müssen: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Erstelle Module für die Prozesse `GATK_HAPLOTYPECALLER` und `GATK_JOINTGENOTYPING` + +Wiederhole die gleichen Schritte für die verbleibenden Prozesse. +Für jeden Prozess: + +1. Erstelle die Verzeichnisstruktur (`modules/gatk/haplotypecaller/` und `modules/gatk/jointgenotyping/`) +2. Erstelle eine `main.nf`-Datei mit der Prozess-Definition +3. Entferne die Prozess-Definition aus `genomics-3.nf` +4. Füge eine Import-Deklaration für das Modul hinzu + +Überprüfe nach Abschluss, ob deine Modulverzeichnisstruktur korrekt ist, indem du Folgendes ausführst: + +```bash +tree modules/ +``` + +??? abstract "Verzeichnisinhalte" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Du solltest auch etwas wie dies in der Haupt-Workflow-Datei haben, nach dem Parameterabschnitt: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Zusammenfassung + +Du hast das Modularisieren eines Workflows geübt, mit dem Genomics-Workflow als Beispiel. + +### Wie geht es weiter? + +Teste den modularisierten Workflow. + +--- + +## 2. Den modularisierten Workflow testen + +Führe den modularisierten Workflow aus, um zu überprüfen, dass alles noch funktioniert. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Ausgabe" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Alles funktioniert noch, einschließlich der Wiederaufnahmefähigkeit der Pipeline. +Die Ergebnisse werden weiterhin im Verzeichnis `results_genomics` veröffentlicht. + +```console title="Verzeichnisinhalte" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Zusammenfassung + +Du hast einen Workflow modularisiert und überprüft, dass er immer noch genauso funktioniert wie zuvor. + +### Wie geht es weiter? + +Fasse zusammen, was du gelernt hast, und schau voraus auf das Testen. + +--- + +## 3. Zusammenfassung + +Du hast den Workflow modularisiert, und nichts hat sich an der Funktionsweise der Pipeline geändert. +Das ist beabsichtigt: Du hast den Code umstrukturiert, ohne seine Funktion zu beeinflussen. + +Die Module enthalten nur die Prozess-Logik, was sie sauber und wiederverwendbar macht. +Das Haupt-Script kontrolliert, was wo veröffentlicht wird, während die Module auf ihre Berechnungsaufgabe fokussiert bleiben. + +Du hast eine Grundlage für Dinge geschaffen, die deinen Code einfacher wartbar machen. +Du kannst jetzt zum Beispiel Tests zu deiner Pipeline hinzufügen, indem du das nf-test-Framework verwendest. +Das werden wir uns im nächsten Teil dieses Kurses ansehen. diff --git a/docs/de/docs/nf4_science/genomics/04_testing.md b/docs/de/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..1df6a65760 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Teil 4: Tests hinzufügen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil dieses Kurses hast du eine Varianten-Calling-Pipeline erstellt, die vollständig linear war und die Daten jeder Probe unabhängig von den anderen verarbeitet hat. + +Im zweiten Teil haben wir dir gezeigt, wie du Channels und Channel-Operatoren verwendest, um gemeinsames Varianten-Calling mit GATK zu implementieren. + +Im dritten Teil haben wir die Pipeline modularisiert. + +In diesem Teil des Trainings zeigen wir dir, wie du [**nf-test**](https://www.nf-test.com/) verwendest, ein Test-Framework, das sich gut in Nextflow integriert und es einfach macht, sowohl Tests auf Modul-Ebene als auch auf Workflow-Ebene zu deiner Pipeline hinzuzufügen. Um diesem Teil des Trainings zu folgen, solltest du Teil 1, Teil 2 und Teil 3 abgeschlossen haben, sowie die [nf-test Side Quest](../../side_quests/nf-test.md), die die Grundlagen von nf-test behandelt und erklärt, warum Testen wichtig ist. + +--- + +## 0. Aufwärmen + +!!! note "Hinweis" + + Stelle sicher, dass du im richtigen Arbeitsverzeichnis bist: + `cd /workspaces/training/nf4-science/genomics` + +Wenn du die vorherigen Teile dieses Trainingskurses durchgearbeitet hast, solltest du eine funktionierende Version der Genomik-Pipeline mit der entsprechenden Modulverzeichnisstruktur haben. + +??? abstract "Verzeichnisinhalte" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Dieses Modulverzeichnis findest du im `solutions`-Verzeichnis, falls du es benötigst. + +Wir beginnen mit demselben Workflow wie in Teil 3, den wir dir in der Datei `genomics-4.nf` bereitgestellt haben. Genau wie bei der [nf-test Side Quest](../../side_quests/nf-test.md) werden wir den drei Prozessen in dieser Pipeline verschiedene Arten von Tests hinzufügen sowie einen Test auf Workflow-Ebene. + +### 0.1. Prüfen, ob der Workflow läuft + +Bevor wir mit dem Hinzufügen von Tests beginnen, stelle sicher, dass der Workflow wie erwartet läuft. + +```bash +nextflow run genomics-4.nf -resume +``` + +Das sollte inzwischen sehr vertraut aussehen, wenn du diesen Trainingskurs von Anfang an durchgearbeitet hast. + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Wie zuvor wird es jetzt ein `work`-Verzeichnis und ein `results_genomics`-Verzeichnis in deinem Projektverzeichnis geben. Diese Ergebnisse werden wir später beim Testen tatsächlich verwenden. Aber ab jetzt werden wir das `nf-test`-Paket verwenden, um die Pipeline zu testen. + +### 0.2. `nf-test` initialisieren + +Wie bei der [nf-test Side Quest](../../side_quests/nf-test.md) müssen wir das `nf-test`-Paket initialisieren. + +```bash +nf-test init +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "nf-test.config-Inhalte" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Es erstellt auch ein `tests`-Verzeichnis mit einer Konfigurationsdatei-Vorlage. + +### Zusammenfassung + +Jetzt sind wir bereit, Tests für unsere Genomik-Pipeline zu schreiben. + +### Wie geht es weiter? + +Schreibe grundlegende Tests, die prüfen, ob die Prozessaufrufe erfolgreich waren und die richtigen Ausgaben produziert haben. + +--- + +## 1. Einen Prozess auf Erfolg und übereinstimmende Ausgaben testen + +Wir beginnen mit dem Testen des `SAMTOOLS_INDEX`-Prozesses, der Indexdateien für BAM-Dateien erstellt, um effizienten Direktzugriff zu ermöglichen. Dies ist ein guter erster Testfall, weil: + +1. Er eine einzelne, klar definierte Eingabe hat (eine BAM-Datei) +2. Er eine vorhersagbare Ausgabe produziert (eine BAI-Indexdatei) +3. Die Ausgabe bei identischen Eingaben identisch sein sollte + +### 1.1. Eine Test-Datei-Vorlage generieren + +Generiere zunächst eine Test-Datei-Vorlage: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Befehlsausgabe" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Dies erstellt eine Datei im selben Verzeichnis wie `main.nf`. +Du kannst im Datei-Explorer zu dem Verzeichnis navigieren und die Datei öffnen, die folgenden Code enthalten sollte: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Die anfänglichen Assertions sollten aus der [nf-test Side Quest](../../side_quests/nf-test.md) bekannt sein: + +- `assert process.success` besagt, dass wir erwarten, dass der Prozess erfolgreich läuft und ohne Fehler abgeschlossen wird. +- `snapshot(process.out).match()` besagt, dass wir erwarten, dass das Ergebnis des Laufs mit dem Ergebnis eines vorherigen Laufs identisch ist (falls zutreffend). + Wir besprechen dies später ausführlicher. + +Mit diesem Ausgangspunkt müssen wir die richtigen Test-Eingaben für den samtools index-Prozess hinzufügen und gegebenenfalls Parameter. + +### 1.2. Die Test-Datei verschieben und den Script-Pfad aktualisieren + +Bevor wir mit dem Ausfüllen des Tests beginnen, müssen wir die Datei an ihren endgültigen Speicherort verschieben. Ein Teil des Grundes, warum wir ein Verzeichnis für jedes Modul hinzugefügt haben, ist, dass wir jetzt Tests in einem `tests`-Verzeichnis zusammen mit der `main.nf`-Datei jedes Moduls ablegen können. Erstelle dieses Verzeichnis und verschiebe die Test-Datei dorthin. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Jetzt können wir den `script`-Abschnitt der Test-Datei zu einem relativen Pfad vereinfachen: + +=== "Nachher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Vorher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Dies teilt dem Test mit, wo die `main.nf`-Datei des Moduls zu finden ist, ohne den vollständigen Pfad angeben zu müssen. + +### 1.3. Test-Eingaben für SAMTOOLS_INDEX bereitstellen + +Die Vorlagendatei enthält einen Platzhalter, den wir durch eine tatsächliche Test-Eingabe ersetzen müssen, die für die Eingabe von `samtools index` geeignet ist. Die passende Eingabe ist eine BAM-Datei, die wir im Verzeichnis `data/bam` verfügbar haben. + +=== "Nachher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Vorher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Den Test basierend auf der Funktionalität benennen + +Wie wir zuvor gelernt haben, ist es eine gute Praxis, den Test so umzubenennen, dass er im Kontext des Tests sinnvoll ist. + +=== "Nachher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Dies nimmt eine beliebige Zeichenkette, wir könnten also alles eingeben, was wir wollen. + Hier wählen wir, uns auf den Dateinamen und sein Format zu beziehen. + +=== "Vorher" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Den Test ausführen und die Ausgabe untersuchen + +Führe den Test aus: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Wie wir zuvor gelernt haben, hat dies die grundlegende Assertion über den Erfolg des Prozesses verifiziert und eine Snapshot-Datei basierend auf der Ausgabe des Prozesses erstellt. Wir können den Inhalt der Snapshot-Datei in der Datei `tests/modules/samtools/index/tests/main.nf.test.snap` sehen: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Wir können den Test auch erneut ausführen und sehen, dass er besteht, weil die Ausgabe mit dem Snapshot identisch ist: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Weitere Tests zu `SAMTOOLS_INDEX` hinzufügen + +Manchmal ist es nützlich, eine Reihe verschiedener Eingabedateien zu testen, um sicherzustellen, dass wir auf verschiedene potenzielle Probleme testen. Füge Tests für die BAM-Dateien von Mutter und Vater im Trio aus unseren Testdaten hinzu. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Dann kannst du den Test erneut ausführen: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Beachte die Warnung, die sich auf die Wirkung des Parameters `--update-snapshot` bezieht. + +!!! note "Hinweis" + + Hier verwenden wir Testdaten, die wir zuvor verwendet haben, um die wissenschaftlichen Ausgaben der Pipeline zu demonstrieren. + Wenn wir geplant hätten, diese Tests in einer Produktionsumgebung zu betreiben, hätten wir kleinere Eingaben zu Testzwecken generiert. + + Im Allgemeinen ist es wichtig, Unit-Tests so leicht wie möglich zu halten, indem man die kleinsten notwendigen und ausreichenden Datenmengen zur Bewertung der Prozessfunktionalität verwendet, da sich sonst die Gesamtlaufzeit erheblich summieren kann. + Eine Test-Suite, die zu lange dauert, um regelmäßig ausgeführt zu werden, ist eine Test-Suite, die wahrscheinlich im Interesse der Schnelligkeit übersprungen wird. + +### Zusammenfassung + +Du hast deinen ersten Modultest für einen Genomik-Prozess geschrieben und verifiziert, dass `SAMTOOLS_INDEX` korrekt Indexdateien für verschiedene BAM-Dateien erstellt. Die Test-Suite stellt sicher, dass: + +1. Der Prozess erfolgreich läuft +2. Indexdateien erstellt werden +3. Die Ausgaben über Läufe hinweg konsistent sind +4. Der Prozess für alle Proben-BAM-Dateien funktioniert + +### Wie geht es weiter? + +Lerne, wie du Tests für andere Prozesse in unserem Genomik-Workflow schreibst, indem du die setup-Methode verwendest, um verkettete Prozesse zu handhaben. Wir werden auch prüfen, ob Ausgaben, insbesondere unsere VCF-Dateien, erwartete Variantenaufrufe enthalten. + +--- + +## 2. Tests zu einem verketteten Prozess hinzufügen und auf Inhalte testen + +Um `GATK_HAPLOTYPECALLER` zu testen, müssen wir dem Prozess die Ausgabe von `SAMTOOLS_INDEX` als Eingabe bereitstellen. Wir könnten das tun, indem wir `SAMTOOLS_INDEX` ausführen, seine Ausgaben abrufen und sie mit den Testdaten für den Workflow speichern. Das ist tatsächlich der empfohlene Ansatz für eine ausgereifte Pipeline, aber nf-test bietet einen alternativen Ansatz mit der `setup`-Methode. + +Mit der setup-Methode können wir den `SAMTOOLS_INDEX`-Prozess als Teil des Test-Setups auslösen und dann seine Ausgabe als Eingabe für `GATK_HAPLOTYPECALLER` verwenden. Das hat einen Preis: Wir müssen den `SAMTOOLS_INDEX`-Prozess jedes Mal ausführen, wenn wir den Test für `GATK_HAPLOTYPECALLER` durchführen. Vielleicht entwickeln wir jedoch noch den Workflow und wollen keine Testdaten vorab generieren, die wir später möglicherweise ändern müssen. Der `SAMTOOLS_INDEX`-Prozess ist auch sehr schnell, sodass die Vorteile des Vorab-Generierens und Speicherns seiner Ausgaben vielleicht vernachlässigbar sind. So funktioniert die setup-Methode. + +### 2.1. Die Test-Datei generieren und platzieren + +Wie zuvor generieren wir zunächst die Datei-Vorlage: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Befehlsausgabe" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Dies erzeugt die folgende Test-Vorlage: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Die Test-Datei verschieben und den Script-Pfad aktualisieren + +Wir erstellen ein Verzeichnis für die Test-Datei zusammen mit der `main.nf`-Datei des Moduls: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +Und verschieben die Test-Vorlagendatei dorthin: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Vergiss nicht, den Script-Pfad zu aktualisieren: + +=== "Nachher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Vorher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Eingaben mit der setup-Methode bereitstellen + +Wir fügen vor dem `when`-Block einen `setup`-Block ein, in dem wir einen Lauf des `SAMTOOLS_INDEX`-Prozesses auf einer unserer ursprünglichen Eingabedateien auslösen können. Denke auch daran, wie zuvor den Testnamen in etwas Aussagekräftiges zu ändern. + +=== "Nachher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Vorher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Dann können wir auf die Ausgabe dieses Prozesses im `when`-Block verweisen, wo wir die Test-Eingaben spezifizieren: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Führe diese Änderung durch und führe den Test erneut aus: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Es erzeugt auch wie zuvor eine Snapshot-Datei. + +### 2.4. Erneut ausführen und Fehler beobachten + +Interessanterweise wird der Test fehlschlagen, wenn du genau denselben Befehl noch einmal ausführst. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +Die Fehlermeldung sagt dir, dass es Unterschiede zwischen den Snapshots für die beiden Läufe gab; insbesondere sind die md5sum-Werte für die VCF-Dateien unterschiedlich. + +Warum? Um es kurz zu machen: Das HaplotypeCaller-Tool fügt einen Zeitstempel in den VCF-Header ein, der jedes Mal anders ist (per Definition). +Folglich können wir nicht einfach erwarten, dass die Dateien identische md5sums haben, selbst wenn sie in Bezug auf die Variantenaufrufe selbst identischen Inhalt haben. + +Wie gehen wir damit um? + +### 2.5. Eine Inhaltsassertion-Methode verwenden, um eine bestimmte Variante zu prüfen + +Eine Möglichkeit, das Problem zu lösen, besteht darin, eine [andere Art von Assertion](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions) zu verwenden. +In diesem Fall werden wir auf spezifischen Inhalt prüfen, anstatt Identität zu behaupten. +Genauer gesagt lassen wir das Tool die Zeilen der VCF-Datei lesen und prüfen auf das Vorhandensein bestimmter Zeilen. + +In der Praxis ersetzen wir die zweite Assertion im `then`-Block wie folgt: + +=== "Nachher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Vorher" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Hier lesen wir den vollständigen Inhalt der VCF-Ausgabedatei ein und suchen nach einer Inhaltsübereinstimmung, was bei einer kleinen Testdatei in Ordnung ist, aber du würdest das nicht bei einer größeren Datei tun wollen. +Stattdessen könntest du dich entscheiden, bestimmte Zeilen einzulesen. + +Dieser Ansatz erfordert eine sorgfältigere Auswahl dessen, was wir als "Signal" zum Testen verwenden möchten. +Auf der positiven Seite kann es verwendet werden, um mit großer Präzision zu testen, ob ein Analyse-Tool konsistent "schwierige" Merkmale (wie seltene Varianten) identifizieren kann, während es sich weiterentwickelt. + +### 2.6. Erneut ausführen und Erfolg beobachten + +Sobald wir den Test auf diese Weise geändert haben, können wir den Test mehrmals ausführen, und er wird konsistent bestehen. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Weitere Tests hinzufügen + +Füge ähnliche Tests für die Mutter- und Vaterproben hinzu: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Den Testbefehl ausführen + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Das vervollständigt den grundlegenden Testplan für diesen zweiten Schritt in der Pipeline. Weiter zum dritten und letzten Test auf Modulebene! + +### Zusammenfassung + +Du hast gelernt, wie man: + +1. Prozesse testet, die von Ausgaben anderer Prozesse abhängen +2. Spezifische genomische Varianten in VCF-Ausgabedateien verifiziert +3. Nicht-deterministische Ausgaben handhabt, indem man spezifischen Inhalt prüft +4. Variantenaufruf über mehrere Proben hinweg testet + +### Wie geht es weiter? + +Lerne, wie man Tests schreibt, die vorab generierte Testdaten für den Joint-Genotyping-Schritt verwenden. + +--- + +## 3. Vorab generierte Testdaten verwenden + +Für den Joint-Genotyping-Schritt verwenden wir einen anderen Ansatz - die Verwendung vorab generierter Testdaten. Dies ist oft vorzuziehen für: + +1. Komplexe Prozesse mit mehreren Abhängigkeiten +2. Prozesse, die lange laufen +3. Prozesse, die Teil einer stabilen Produktions-Pipeline sind + +### 3.1. Testdaten generieren + +Untersuche die Ergebnisse, die wir zu Beginn dieses Abschnitts generiert haben: + +```bash +tree results_genomics/ +``` + +```console title="Inhalt des Ergebnisverzeichnisses" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +Der Joint-Genotyping-Schritt benötigt die von den Haplotype-Caller-Schritten erzeugten VCF-Dateien als Eingaben, zusammen mit den Indizes. Also lass uns die Ergebnisse, die wir haben, in das Test-Verzeichnis des `jointgenotyping`-Moduls kopieren. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Jetzt können wir diese Dateien als Eingaben für den Test verwenden, den wir für den Joint-Genotyping-Schritt schreiben werden. + +### 3.2. Die Test-Datei-Vorlage generieren + +Wie zuvor generieren wir zunächst die Datei-Vorlage: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Befehlsausgabe" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Dies erzeugt die folgende Test-Vorlage: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Die Test-Datei verschieben und den Script-Pfad aktualisieren + +Diesmal haben wir bereits ein Verzeichnis für Tests zusammen mit der `main.nf`-Datei des Moduls, sodass wir die Test-Vorlagendatei dorthin verschieben können: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +Und vergiss nicht, den Script-Pfad zu aktualisieren: + +=== "Nachher" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Vorher" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Eingaben bereitstellen + +Fülle die Eingaben basierend auf den Prozess-Eingabedefinitionen aus und benenne den Test entsprechend um: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Inhaltsassertions verwenden + +Die Ausgabe des Joint-Genotyping-Schritts ist wieder eine VCF-Datei, also werden wir wieder eine Inhaltsassertion verwenden. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Durch die Überprüfung des Inhalts einer bestimmten Variante in der Ausgabedatei verifiziert dieser Test, dass: + +1. Der Joint-Genotyping-Prozess erfolgreich läuft +2. Die Ausgabe-VCF alle drei Proben in der richtigen Reihenfolge enthält +3. Eine spezifische Variante korrekt aufgerufen wird mit: + - Genauen Genotypen für jede Probe (0/1 für Vater, 1/1 für Mutter und Sohn) + - Korrekten Read-Tiefen und Genotyp-Qualitäten + - Populationsweiten Statistiken wie Allelfrequenz (AF=0.833) + +Wir haben nicht die gesamte Datei als Snapshot gespeichert, aber indem wir eine spezifische Variante überprüfen, können wir sicher sein, dass der Joint-Genotyping-Prozess wie erwartet funktioniert. + +### 3.6. Den Test ausführen + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +Der Test besteht und verifiziert, dass unser Joint-Genotyping-Prozess korrekt: + +1. Individuelle Proben-VCFs kombiniert +2. Gemeinsames Varianten-Calling durchführt +3. Eine Multi-Proben-VCF mit konsistenten Genotyp-Aufrufen über Läufe hinweg produziert + +### Zusammenfassung + +Du weißt, wie man: + +- Zuvor generierte Ergebnisse als Eingaben für Tests verwendet +- Tests mit vorab generierten Testdaten schreibt + +### Wie geht es weiter? + +Füge einen Test auf Workflow-Ebene hinzu, um zu verifizieren, dass die gesamte Varianten-Calling-Pipeline end-to-end funktioniert. + +--- + +## 4. Einen Test auf Workflow-Ebene hinzufügen + +Jetzt testen wir die vollständige Varianten-Calling-Pipeline, von BAM-Dateien bis zu Joint-Genotypen. Dies verifiziert, dass: + +1. Alle Prozesse korrekt zusammenarbeiten +2. Daten ordnungsgemäß zwischen den Schritten fließen +3. Abschließende Variantenaufrufe konsistent sind + +### 4.1. Den Workflow-Test generieren + +Generiere eine Test-Datei für die vollständige Pipeline: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Befehlsausgabe" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Dies erstellt eine grundlegende Test-Vorlage: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Korrigiere einfach den Namen zu etwas Aussagekräftigem (du wirst bald sehen, warum das nützlich ist). + +=== "Nachher" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Vorher" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "Hinweis" + + In diesem Fall kann die Test-Datei dort bleiben, wo `nf-test` sie erstellt hat. + +### 4.2. Eingabeparameter spezifizieren + +Wir müssen noch Eingaben spezifizieren, was auf Workflow-Ebene etwas anders gemacht wird als bei Tests auf Modulebene. +Es gibt mehrere Möglichkeiten, dies zu tun, einschließlich durch Angabe eines Profils. +Ein einfacherer Weg ist jedoch, einen `params {}`-Block in der `nextflow.config`-Datei einzurichten, die `nf-test init` ursprünglich im `tests`-Verzeichnis erstellt hat. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow-Konfigurationsdatei zum Ausführen von Tests +======================================================================================== +*/ + +// Ausgabeverzeichnis für Workflow-Ausgaben +outputDir = 'results_genomics' + +/* + * Pipeline-Parameter + */ + +params { + // Primäre Eingabe (Datei mit Eingabedateien, eine pro Zeile) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Zusatzdateien + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Basisname für abschließende Ausgabedatei + cohort_name = "family_trio" +} +``` + +Wenn wir den Test ausführen, übernimmt `nf-test` diese Konfigurationsdatei und zieht die Eingaben entsprechend heran. + +### 4.3. Den Workflow-Test ausführen + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +Der Test besteht und bestätigt, dass unsere vollständige Varianten-Calling-Pipeline: + +1. Alle Proben erfolgreich verarbeitet +2. Alle Schritte korrekt verkettet + +### 4.4. ALLE Tests ausführen + +nf-test hat noch einen weiteren Trick auf Lager. Wir können alle Tests auf einmal ausführen! Ändere die `nf-test.config`-Datei so, dass nf-test in jedem Verzeichnis nach nf-test-Dateien sucht. Du kannst dies tun, indem du den `testsDir`-Parameter änderst: + +=== "Nachher" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Vorher" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Jetzt können wir einfach nf-test ausführen und es wird _jeden einzelnen Test_ in unserem Repository ausführen: + +```bash +nf-test test +``` + +??? success "Befehlsausgabe" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +8 Tests mit 1 Befehl! Wir haben lange damit verbracht, viele Tests zu konfigurieren, aber als es darum ging, sie auszuführen, war es sehr schnell und einfach. Du kannst sehen, wie nützlich das bei der Wartung einer großen Pipeline ist, die Hunderte verschiedener Elemente enthalten könnte. Wir investieren Zeit in das Schreiben von Tests einmal, damit wir Zeit sparen können, wenn wir sie viele Male ausführen. + +Außerdem können wir das automatisieren! Stell dir vor, Tests laufen jedes Mal, wenn du oder ein Kollege versucht, neuen Code hinzuzufügen. So stellen wir sicher, dass unsere Pipelines einen hohen Standard aufrechterhalten. + +## Zusammenfassung + +Du weißt jetzt, wie man mehrere Arten von Tests für deine Genomik-Pipeline mit nf-test schreibt und ausführt. Dieses Test-Framework hilft sicherzustellen, dass dein Varianten-Calling-Workflow konsistente, zuverlässige Ergebnisse über verschiedene Umgebungen hinweg produziert und wenn du Code-Änderungen vornimmst. + +Du hast gelernt, kritische Komponenten zu testen wie: + +- Den `SAMTOOLS_INDEX`-Prozess, der BAM-Dateien für Varianten-Calling vorbereitet +- Den `GATK_HAPLOTYPECALLER`-Prozess, der Varianten in einzelnen Proben identifiziert +- Den `GATK_JOINTGENOTYPING`-Prozess, der Variantenaufrufe über eine Kohorte hinweg kombiniert + +Du hast auch verschiedene Teststrategien implementiert, die spezifisch für Genomik-Daten sind: + +- Verifizieren, dass VCF-Dateien erwartete Variantenaufrufe enthalten, trotz nicht-deterministischer Elemente wie Zeitstempel +- Testen mit einem Familien-Trio-Datensatz, um die ordnungsgemäße Variantenidentifikation über verwandte Proben hinweg sicherzustellen +- Überprüfen auf spezifische genomische Koordinaten und Varianteninformationen in deinen Ausgabedateien + +Diese Testfähigkeiten sind wesentlich für die Entwicklung robuster Bioinformatik-Pipelines, die zuverlässig Genomdaten verarbeiten und genaue Variantenaufrufe produzieren können. Während du weiterhin mit Nextflow für Genomik-Analysen arbeitest, wird dir diese Test-Grundlage helfen, qualitativ hochwertigen Code aufrechtzuerhalten, der vertrauenswürdige wissenschaftliche Ergebnisse produziert. diff --git a/docs/de/docs/nf4_science/genomics/05_configuration.md b/docs/de/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..3aff117d24 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Teil 3: Ressourcen-Profiling und -Optimierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +DIES IST EIN PLATZHALTER + +!!!note "Hinweis" + + Dieses Trainingsmodul wird derzeit überarbeitet. + +--- + +TODO + +### 1.1. Führe den Workflow aus, um einen Bericht zur Ressourcennutzung zu erstellen + +Damit Nextflow den Bericht automatisch generiert, füge einfach `-with-report <dateiname>.html` zu deinem Befehl hinzu. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +Der Bericht ist eine HTML-Datei, die du herunterladen und in deinem Browser öffnen kannst. Du kannst auch mit der rechten Maustaste im Datei-Explorer auf der linken Seite darauf klicken und `Show preview` auswählen, um ihn in VS Code anzuzeigen. + +Nimm dir ein paar Minuten Zeit, um den Bericht durchzusehen und zu prüfen, ob du einige Möglichkeiten zur Anpassung der Ressourcen identifizieren kannst. +Klicke unbedingt auf die Tabs, die die Nutzungsergebnisse als Prozentsatz der zugewiesenen Ressourcen anzeigen. +Es gibt eine [Dokumentation](https://www.nextflow.io/docs/latest/reports.html), die alle verfügbaren Funktionen beschreibt. + +<!-- TODO: insert images --> + +Eine Beobachtung ist, dass `GATK_JOINTGENOTYPING` sehr CPU-hungrig zu sein scheint, was Sinn macht, da es viele komplexe Berechnungen durchführt. +Wir könnten also versuchen, diese zu erhöhen und sehen, ob sich die Laufzeit dadurch verkürzt. + +Allerdings scheinen wir bei den Speicherzuweisungen über das Ziel hinausgeschossen zu sein; alle Prozesse nutzen nur einen Bruchteil dessen, was wir ihnen geben. +Das sollten wir wieder herunterregeln und Ressourcen sparen. + +### 1.2. Passe Ressourcenzuweisungen für einen bestimmten Prozess an + +Wir können Ressourcenzuweisungen für einen bestimmten Prozess mit dem `withName`-Prozess-Selektor angeben. +Die Syntax sieht folgendermaßen aus, wenn sie allein in einem process-Block steht: + +```groovy title="Syntax" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Fügen wir das zum bestehenden process-Block in der `nextflow.config`-Datei hinzu. + +```groovy title="nextflow.config" linenums="11" +process { + // Standardwerte für alle Prozesse + cpus = 2 + memory = 2.GB + // Zuweisungen für einen bestimmten Prozess + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Mit dieser Angabe gelten die Standardeinstellungen für alle Prozesse **außer** dem `GATK_JOINTGENOTYPING`-Prozess, der eine besondere Ausnahme ist und deutlich mehr CPU bekommt. +Hoffentlich sollte das einen Effekt haben. + +### 1.3. Führe den Workflow erneut mit der geänderten Konfiguration aus + +Lass uns den Workflow erneut mit der geänderten Konfiguration und mit aktiviertem Reporting-Flag ausführen, aber beachte, dass wir dem Bericht einen anderen Namen geben, damit wir sie unterscheiden können. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Auch hier wirst du wahrscheinlich keinen wesentlichen Unterschied in der Laufzeit bemerken, da dies eine so kleine Arbeitslast ist und die Tools mehr Zeit mit Nebenaufgaben verbringen als mit der eigentlichen 'echten' Arbeit. + +Der zweite Bericht zeigt jedoch, dass unsere Ressourcennutzung jetzt ausgewogener ist. + +<!-- **TODO: screenshots?** --> + +Wie du sehen kannst, ist dieser Ansatz nützlich, wenn deine Prozesse unterschiedliche Ressourcenanforderungen haben. Er ermöglicht es dir, die Ressourcenzuweisungen, die du für jeden Prozess einrichtest, basierend auf tatsächlichen Daten und nicht auf Vermutungen optimal anzupassen. + +!!!note "Hinweis" + + Dies ist nur ein kleiner Vorgeschmack darauf, was du tun kannst, um deine Ressourcennutzung zu optimieren. + Nextflow selbst hat eine wirklich clevere [dynamische Wiederholungslogik](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) eingebaut, um Jobs, die aufgrund von Ressourcenbeschränkungen fehlschlagen, erneut zu versuchen. + Darüber hinaus bietet die Seqera Platform KI-gestützte Tools zur automatischen Optimierung deiner Ressourcenzuweisungen. + + Wir werden beide Ansätze in einem kommenden Teil dieses Trainingskurses behandeln. + +Allerdings kann es je nach verwendetem Computing-Executor und Compute-Infrastruktur einige Einschränkungen geben, was du zuweisen kannst (oder musst). Dein Cluster könnte beispielsweise verlangen, dass du innerhalb bestimmter Grenzen bleibst, die nicht gelten, wenn du woanders ausführst. diff --git a/docs/de/docs/nf4_science/genomics/index.md b/docs/de/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..1fbf91ded6 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/index.md @@ -0,0 +1,42 @@ +--- +title: Nextflow für Genomik +hide: + - toc +--- + +# Nextflow für Genomik + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dieser Trainingskurs richtet sich an Forschende im Bereich Genomik und verwandten Feldern, die daran interessiert sind, Datenanalyse-Pipelines zu entwickeln oder anzupassen. +Er baut auf dem [Hello Nextflow](../../hello_nextflow/) Einsteiger-Training auf und zeigt, wie du Nextflow im spezifischen Kontext der Genomik-Domäne nutzen kannst. + +Konkret demonstriert dieser Kurs, wie du eine einfache Variant-Calling-Pipeline mit [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit) implementierst, einem weit verbreiteten Softwarepaket zur Analyse von High-Throughput-Sequenzierungsdaten. + +Los geht's! Klicke auf die Schaltfläche „Open in GitHub Codespaces" unten, um die Trainingsumgebung zu starten (am besten in einem separaten Tab), und lies dann weiter, während sie lädt. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Lernziele + +Durch die Bearbeitung dieses Kurses lernst du, wie du grundlegende Nextflow-Konzepte und -Werkzeuge auf einen typischen Genomik-Anwendungsfall anwendest. + +Am Ende dieses Workshops kannst du: + +- Einen linearen Workflow zu schreiben, um Variant Calling auf eine einzelne Probe anzuwenden +- Zusatzdateien wie Index-Dateien und Referenzgenom-Ressourcen angemessen zu handhaben +- Das Dataflow-Paradigma von Nextflow zu nutzen, um Variant Calling pro Probe zu parallelisieren +- Multi-Sample Variant Calling mit relevanten Channel-Operatoren zu implementieren +- Tests pro Schritt und Ende-zu-Ende-Pipeline-Tests zu implementieren, die genomik-spezifische Besonderheiten angemessen behandeln + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Voraussetzungen + +Der Kurs setzt ein Mindestmaß an Vertrautheit mit Folgendem voraus: + +- Werkzeuge und Dateiformate, die in diesem wissenschaftlichen Bereich häufig verwendet werden +- Erfahrung mit der Kommandozeile +- Grundlegende Nextflow-Konzepte und -Werkzeuge, die im [Hello Nextflow](../../hello_nextflow/) Einsteiger-Training behandelt werden. + +Für technische Anforderungen und Umgebungs-Setup siehe den Mini-Kurs [Environment Setup](../../envsetup/). diff --git a/docs/de/docs/nf4_science/genomics/next_steps.md b/docs/de/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..e27f02fa56 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Nächste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herzlichen Glückwunsch nochmal zum Abschluss des Nextflow For Genomics Trainingskurses und vielen Dank für das Ausfüllen unserer Umfrage! + +--- + +## 1. Die 3 besten Wege, um deine Nextflow-Kenntnisse zu verbessern + +Hier sind unsere drei wichtigsten Empfehlungen, was du als Nächstes tun kannst, basierend auf dem Kurs, den du gerade abgeschlossen hast. + +### 1.1. Wende Nextflow auf andere wissenschaftliche Anwendungsfälle an + +**Schau dir die Seite [Nextflow for Science](../index.md) an**, um eine Liste weiterer kurzer eigenständiger Kurse zu finden, die zeigen, wie du die grundlegenden Konzepte und Mechanismen aus Hello Nextflow auf gängige wissenschaftliche Anwendungsfälle anwenden kannst. + +Falls du deinen Bereich nicht durch einen passenden Anwendungsfall vertreten siehst, lass es uns im [Community-Forum](https://community.seqera.io/) wissen, damit wir ihn zu unserer Entwicklungsliste hinzufügen können. + +### 1.2. Starte mit nf-core + +**[nf-core](https://nf-co.re/)** ist eine weltweite kollaborative Initiative zur Entwicklung standardisierter Open-Source-Pipelines für eine Vielzahl wissenschaftlicher Forschungsanwendungen. +Das Projekt umfasst [über 100 Pipelines](https://nf-co.re/pipelines/), die sofort einsatzbereit sind, sowie [weit über 1400 Prozessmodule](https://nf-co.re/modules/), die du in deine eigenen Projekte integrieren kannst, sowie ein umfangreiches Set an Entwicklertools. + +Der Trainingskurs **[Hello nf-core](../../hello_nf-core/index.md)** führt dich in die von der nf-core-Community betreuten Pipelines und das Entwicklungs-Framework ein, die dir helfen, reproduzierbare, skalierbare und standardisierte Workflows zu schreiben. Du lernst, wie du bestehende nf-core-Pipelines verwendest, zu ihrer Entwicklung beiträgst und sogar beginnst, deine eigenen zu erstellen – unterstützt durch Best Practices und eine lebendige Community. Wenn du bereit bist, deine Nextflow-Kenntnisse in realen Projekten anzuwenden, ist dies der perfekte nächste Schritt. + +### 1.3. Beherrsche fortgeschrittenere Nextflow-Features + +In den Hello-Kursen halten wir die technische Komplexität absichtlich niedrig, um dich nicht mit Informationen zu überlasten, die du für den Einstieg in Nextflow nicht benötigst. +Wenn du mit deiner Arbeit fortfährst, wirst du lernen wollen, wie du das vollständige Feature-Set und die Leistungsfähigkeit von Nextflow nutzen kannst. + +Zu diesem Zweck arbeiten wir derzeit an einer **Sammlung von [Side Quests](../side_quests/index.md)**, die als kurze eigenständige Kurse konzipiert sind und tief in spezifische Themen wie Testen und Metadaten-Handling eintauchen. + +--- + +## 2. Schau dir Seqera Platform an + +**[Seqera Platform](https://seqera.io/) ist der beste Weg, Nextflow in der Praxis zu nutzen.** + +Es ist eine cloudbasierte Plattform, die von den Entwicklern von Nextflow erstellt wurde und die du mit deiner eigenen Compute-Infrastruktur (ob lokal, HPC oder Cloud) verbinden kannst, um das Starten und Verwalten deiner Workflows sowie das Verwalten deiner Daten und das interaktive Ausführen von Analysen in einer Cloud-Umgebung deutlich zu erleichtern. + +Der Free Tier steht jedem kostenlos zur Verfügung (mit Nutzungskontingenten). +Qualifizierte Akademiker können kostenlosen Zugang auf Pro-Ebene (ohne Nutzungsbeschränkungen) über das [Academic Program](https://seqera.io/academic/program/) erhalten. + +Wirf einen Blick auf die [Seqera Platform Tutorials](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase), um zu sehen, ob dies für dich nützlich sein könnte. + +--- + +### Das war's für jetzt! + +**Viel Erfolg mit Nextflow! Zögere nicht, uns im [Community-Forum](https://community.seqera.io/) mitzuteilen, was wir sonst noch tun könnten.** diff --git a/docs/de/docs/nf4_science/genomics/survey.md b/docs/de/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..c7313de168 --- /dev/null +++ b/docs/de/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Feedback-Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bevor du weitermachst, fülle bitte diese kurze Umfrage mit 5 Fragen aus, um das Training zu bewerten und uns Feedback zu geben. + +Das Ausfüllen sollte weniger als eine Minute dauern. Vielen Dank, dass du uns hilfst, unsere Trainingsmaterialien für alle zu verbessern! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/de/docs/nf4_science/imaging/00_orientation.md b/docs/de/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..5862227222 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Diese Orientierung setzt voraus, dass du die Trainingsumgebung bereits geöffnet hast, indem du auf den Button "Open in GitHub Codespaces" geklickt hast. +Falls nicht, tue dies bitte jetzt, idealerweise in einem zweiten Browserfenster oder -tab, damit du auf diese Anweisungen zurückgreifen kannst. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Anforderung an die Maschinengröße" + + Stelle sicher, dass du beim Erstellen deines Codespace für diesen Trainingskurs eine **8-Core-Maschine** auswählst. Die Bioimaging-Workflows benötigen zusätzliche Rechenressourcen. + +## GitHub Codespaces + +Die GitHub Codespaces-Umgebung enthält alle Software, den Code und die Daten, die notwendig sind, um diesen Trainingskurs durchzuarbeiten, sodass du nichts selbst installieren musst. +Du benötigst jedoch einen (kostenlosen) GitHub-Account, um dich anzumelden, und wenn du mit der Oberfläche nicht vertraut bist, solltest du dir ein paar Minuten Zeit nehmen, um dich damit vertraut zu machen, indem du den Mini-Kurs [GitHub Codespaces Orientation](../../envsetup/index.md) absolvierst. + +## Docker-Images vorab herunterladen + +Sobald du deinen Codespace geöffnet hast, lass uns alle Docker-Images herunterladen, die wir für diesen Trainingskurs benötigen. +Das spart später Zeit und sorgt für eine reibungslose Ausführung der Workflows. + +Öffne einen neuen Terminal-Tab und führe folgenden Befehl aus: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Dieser Befehl lädt alle notwendigen Docker-Images im Hintergrund herunter. +Du kannst mit dem Rest der Orientierung fortfahren, während dies läuft. + +!!!tip "Tipp" + + Die `-stub`-Flag ermöglicht es der Pipeline, schnell zu laufen, ohne echte Daten zu verarbeiten, was perfekt zum Herunterladen von Images ist. Du kannst den Fortschritt im Terminal-Tab überwachen. + +## Arbeitsverzeichnis + +Im Verlauf dieses Trainingskurses werden wir im Verzeichnis `nf4-science/imaging/` arbeiten. + +Wechsle jetzt das Verzeichnis, indem du diesen Befehl im Terminal ausführst: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "Tipp" + + Falls du aus irgendeinem Grund dieses Verzeichnis verlässt, kannst du jederzeit den vollständigen Pfad verwenden, um dorthin zurückzukehren, vorausgesetzt du arbeitest in der GitHub Codespaces-Trainingsumgebung: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Um nun mit dem Kurs zu beginnen, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite.** diff --git a/docs/de/docs/nf4_science/imaging/01_basics.md b/docs/de/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..15fe25d9b7 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Teil 1: Grundlegende Operationen ausführen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Im ersten Teil des Nextflow für Bioimaging Trainingskurses verwenden wir ein sehr einfaches, domänenunabhängiges Hello World Beispiel, um wesentliche Operationen zu demonstrieren und auf die entsprechenden Nextflow Code-Komponenten hinzuweisen. + +## 1. Den Workflow ausführen + +Wir stellen dir ein Workflow-Skript namens `hello-world.nf` zur Verfügung, das eine Eingabe über ein Befehlszeilenargument namens `--greeting` entgegennimmt und eine Textdatei mit dieser Begrüßung erzeugt. +Wir werden uns den Code noch nicht ansehen; zuerst schauen wir uns an, wie es aussieht, wenn man ihn ausführt. + +### 1.1. Den Workflow starten und die Ausführung überwachen + +Führe im Terminal folgenden Befehl aus: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +Deine Konsolenausgabe sollte in etwa so aussehen: + +```console title="Ausgabe" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Glückwunsch, du hast gerade deinen ersten Nextflow Workflow ausgeführt! + +Die wichtigste Ausgabe hier ist die letzte Zeile (Zeile 6): + +```console title="Ausgabe" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Dies zeigt uns, dass der `sayHello` Prozess einmal erfolgreich ausgeführt wurde (`1 of 1 ✔`). + +Das ist großartig, aber du fragst dich vielleicht: wo ist die Ausgabe? + +### 1.2. Die Ausgabedatei im `results` Verzeichnis finden + +Dieser Workflow ist so konfiguriert, dass er seine Ausgabe in ein Verzeichnis namens `results` veröffentlicht. +Wenn du dir dein aktuelles Verzeichnis ansiehst, wirst du sehen, dass Nextflow beim Ausführen des Workflows ein neues Verzeichnis namens `results` erstellt hat, das eine Datei namens `output.txt` enthält. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Öffne die Datei; der Inhalt sollte mit der Begrüßung übereinstimmen, die du auf der Befehlszeile angegeben hast. + +<details> + <summary>Dateiinhalt</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +Das ist großartig, unser Workflow hat getan, was er sollte! + +Beachte jedoch, dass das 'veröffentlichte' Ergebnis eine Kopie (oder in manchen Fällen ein Symlink) der tatsächlichen Ausgabe ist, die Nextflow bei der Ausführung des Workflows erzeugt hat. + +Jetzt werden wir also unter die Haube schauen, um zu sehen, wo Nextflow tatsächlich die Arbeit ausgeführt hat. + +!!! warning "Warnung" + + Nicht alle Workflows sind so eingerichtet, dass sie Ausgaben in ein results Verzeichnis veröffentlichen, und/oder der Verzeichnisname kann unterschiedlich sein. + Etwas weiter unten in diesem Abschnitt zeigen wir dir, wie du herausfindest, wo dieses Verhalten festgelegt ist. + +### 1.3. Die ursprüngliche Ausgabe und Logs im `work/` Verzeichnis finden + +Wenn du einen Workflow ausführst, erstellt Nextflow für jeden einzelnen Aufruf jedes Prozesses im Workflow (=jeden Schritt in der Pipeline) ein eigenes 'Aufgabenverzeichnis'. +Für jedes wird es die notwendigen Eingaben bereitstellen, die relevanten Anweisung(en) ausführen und Ausgaben sowie Logdateien innerhalb dieses einen Verzeichnisses schreiben, das automatisch mit einem Hash benannt wird, um es eindeutig zu machen. + +Alle diese Aufgabenverzeichnisse befinden sich unter einem Verzeichnis namens `work` in deinem aktuellen Verzeichnis (wo du den Befehl ausführst). + +Das klingt vielleicht verwirrend, also schauen wir uns an, wie das in der Praxis aussieht. + +Zurück zur Konsolenausgabe für den Workflow, den wir vorhin ausgeführt haben, hatten wir diese Zeile: + +```console title="Auszug der Befehlsausgabe" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Siehst du, wie die Zeile mit `[a3/7be2fa]` beginnt? +Das ist eine gekürzte Form des Aufgabenverzeichnispfads für diesen einen Prozessaufruf und zeigt dir, wo du die Ausgabe des `sayHello` Prozessaufrufs innerhalb des `work/` Verzeichnispfads findest. + +Du kannst den vollständigen Pfad finden, indem du folgenden Befehl eingibst (ersetze `a3/7be2fa` mit dem, was du in deinem eigenen Terminal siehst) und die Tab-Taste drückst, um den Pfad zu vervollständigen oder ein Sternchen hinzuzufügen: + +```bash +tree work/a3/7be2fa* +``` + +Dies sollte den vollständigen Verzeichnispfad ergeben: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Schauen wir uns an, was sich darin befindet. + +!!! Tip "Tipp" + + Wenn du den Inhalt des Aufgabenunterverzeichnisses im VSCode Datei-Explorer durchsuchst, siehst du alle Dateien sofort. + Allerdings sind die Logdateien so eingestellt, dass sie im Terminal unsichtbar sind. Wenn du also `ls` oder `tree` verwenden möchtest, um sie anzuzeigen, musst du die entsprechende Option zum Anzeigen unsichtbarer Dateien setzen. + + ```bash + tree -a work + ``` + +Die genauen Unterverzeichnisnamen werden auf deinem System unterschiedlich sein. + +<details> + <summary>Verzeichnisinhalt</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Du solltest sofort die `output.txt` Datei erkennen, die tatsächlich die ursprüngliche Ausgabe des `sayHello` Prozesses ist, die in das `results` Verzeichnis veröffentlicht wurde. +Wenn du sie öffnest, wirst du die `Hello World!` Begrüßung wieder finden. + +<details> + <summary>Dateiinhalt von output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +Was ist also mit all diesen anderen Dateien? + +Dies sind die Hilfs- und Logdateien, die Nextflow als Teil der Aufgabenausführung geschrieben hat: + +- **`.command.begin`**: Sentinel-Datei, die erstellt wird, sobald die Aufgabe gestartet wird. +- **`.command.err`**: Fehlermeldungen (`stderr`), die vom Prozessaufruf ausgegeben wurden +- **`.command.log`**: Vollständige Logausgabe, die vom Prozessaufruf ausgegeben wurde +- **`.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 `.command.sh` Datei ist besonders nützlich, weil sie dir den Hauptbefehl zeigt, den Nextflow ausgeführt hat, ohne die gesamte Buchführung und Aufgaben-/Umgebungseinrichtung. + +<details> + <summary>Dateiinhalt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Tipp" + + Wenn etwas schiefgeht und du Fehlersuche betreiben musst, kann es nützlich sein, das `command.sh` Skript anzuschauen, um genau zu prüfen, welchen Befehl Nextflow basierend auf den Workflow-Anweisungen, Variableninterpolation usw. zusammengestellt hat. + +### 1.4. Optionale Übung: erneut mit verschiedenen Begrüßungen ausführen + +Versuche, den Workflow mehrmals mit verschiedenen Werten für das `--greeting` Argument erneut auszuführen, und schaue dir dann sowohl den Inhalt des `results/` Verzeichnisses als auch die Aufgabenverzeichnisse an. + +Beobachte, wie die Ausgaben und Logs isolierter Aufgabenverzeichnisse erhalten bleiben, während der Inhalt des `results` Verzeichnisses von der Ausgabe nachfolgender Ausführungen überschrieben wird. + +### Zusammenfassung + +Du weißt, wie man ein einfaches Nextflow Skript ausführt, seine Ausführung überwacht und seine Ausgaben findet. + +### Was kommt als Nächstes? + +Lerne, wie man ein grundlegendes Nextflow Skript liest und erkennt, wie seine Komponenten mit seiner Funktionalität zusammenhängen. + +--- + +## 2. Das Hello World Workflow Starter-Skript untersuchen + +Was wir dort gemacht haben, war im Grunde, das Workflow-Skript wie eine Black Box zu behandeln. +Jetzt, da wir gesehen haben, was es tut, lass uns die Box öffnen und hineinschauen. + +_Das Ziel hier ist nicht, die Syntax von Nextflow Code auswendig zu lernen, sondern eine grundlegende Intuition dafür zu entwickeln, was die Hauptkomponenten sind und wie sie organisiert sind._ + +### 2.1. Die gesamte Code-Struktur untersuchen + +Lass uns das `hello-world.nf` Skript im Editor-Fenster öffnen. + +<details> + <summary>Code</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Verwende echo, um eine Begrüßung in eine Datei zu schreiben + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // gib eine Begrüßung aus + sayHello(params.greeting) +} +``` + +</details> + +Ein Nextflow Skript umfasst zwei Haupttypen von Kernkomponenten: einen oder mehrere **Prozesse** und den **Workflow** selbst. +Jeder **Prozess** beschreibt, welche Operation(en) der entsprechende Schritt in der Pipeline durchführen soll, während der **Workflow** die Datenflusslogik beschreibt, die die verschiedenen Schritte verbindet. + +Schauen wir uns zuerst den **Prozess**-Block genauer an, dann betrachten wir den **Workflow**-Block. + +### 2.2. Die `process` Definition + +Der erste Codeblock beschreibt einen **Prozess**. +Die Prozessdefinition beginnt mit dem Schlüsselwort `process`, gefolgt vom Prozessnamen und schließlich dem Prozesskörper, der durch geschweifte Klammern begrenzt wird. +Der Prozesskörper muss einen script-Block enthalten, der den auszuführenden Befehl angibt, was alles sein kann, was du in einem Befehlszeilenterminal ausführen könntest. + +Hier haben wir einen **Prozess** namens `sayHello`, der eine **Eingabe**-Variable namens `greeting` nimmt und seine **Ausgabe** in eine Datei namens `output.txt` schreibt. + +<details> + <summary>Code</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Verwende echo, um eine Begrüßung in eine Datei zu schreiben + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +Dies ist eine sehr minimale Prozessdefinition, die nur eine `input` Definition, eine `output` Definition und das `script` zur Ausführung enthält. + +Die `input` Definition enthält den `val` Qualifier, der Nextflow mitteilt, dass ein Wert irgendeiner Art erwartet wird (kann ein String, eine Zahl, was auch immer sein). + +Die `output` Definition enthält den `path` Qualifier, der Nextflow mitteilt, dass dies als Pfad behandelt werden soll (umfasst sowohl Verzeichnispfade als auch Dateien). + +!!! Tip "Tipp" + + Die Ausgabedefinition _bestimmt_ nicht, welche Ausgabe erstellt wird. + Sie _deklariert_ einfach, wo die erwarteten Ausgabedatei(en) zu finden sind, 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 nachgelagerte Prozesse weiterzugeben. + Erzeugte Ausgabe, die nicht mit dem übereinstimmt, was im output-Block deklariert ist, wird nicht an nachgelagerte Prozesse weitergegeben. + +In einer realen Pipeline enthält ein Prozess normalerweise zusätzliche Informationen wie Prozessdirektiven, die wir in Kürze einführen werden. + +### 2.3. 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-Körper, der durch geschweifte Klammern begrenzt wird. + +Hier haben wir einen **Workflow**, der aus einem Aufruf des `sayHello` Prozesses besteht, der eine Eingabe `params.greeting` nimmt, die den Wert enthält, den wir dem `--greeting` Parameter gegeben haben. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // gib eine Begrüßung aus + sayHello(params.greeting) +} +``` + +Dies ist eine sehr minimale **Workflow**-Definition. +In einer realen Pipeline enthält der Workflow typischerweise mehrere Aufrufe von **Prozessen**, die durch **Channels** verbunden sind, und es können Standardwerte für die variablen Eingaben eingerichtet sein. + +Wir werden dies in Aktion sehen, wenn wir nf-core/molkart in Teil 2 des Kurses ausführen. + +### 2.4. Das `params` System von Befehlszeilenparametern + +Das `params.greeting`, das wir dem `sayHello()` Prozessaufruf übergeben, ist ein cleveres Stück Nextflow Code und ist es wert, eine zusätzliche Minute darauf zu verwenden. + +Wie oben erwähnt, geben wir so den Wert des `--greeting` Befehlszeilenparameters an den `sayHello()` Prozessaufruf weiter. +Tatsächlich ermöglicht die einfache Deklaration von `params.someParameterName` uns, dem Workflow einen Parameter namens `--someParameterName` von der Befehlszeile aus zu geben. + +!!! Tip "Tipp" + + Diese Workflow-Parameter, die mit dem `params` System deklariert werden, verwenden immer zwei Bindestriche (`--`). + Dies unterscheidet sie von Nextflow-Parametern, die nur einen Bindestrich (`-`) verwenden. + +### Zusammenfassung + +Du weißt jetzt, wie ein einfacher Nextflow Workflow strukturiert ist und wie die grundlegenden Komponenten mit seiner Funktionalität zusammenhängen. + +### Was kommt als Nächstes? + +Lerne, deine Workflow-Ausführungen bequem zu verwalten. + +--- + +## 3. Workflow-Ausführungen verwalten + +Zu wissen, wie man Workflows startet und Ausgaben abruft, ist großartig, aber du wirst schnell feststellen, dass es ein paar andere Aspekte der Workflow-Verwaltung gibt, die dir das Leben erleichtern werden. + +Hier zeigen wir dir, wie du die `resume` Funktion nutzen kannst, wenn du denselben Workflow erneut starten musst, wie du die Ausführungslogs mit `nextflow log` einsehen kannst und wie du ältere work Verzeichnisse mit `nextflow clean` löschen kannst. + +### 3.1. Einen Workflow mit `-resume` erneut starten + +Manchmal wirst du eine Pipeline erneut ausführen wollen, die du bereits zuvor gestartet hast, ohne bereits erfolgreich abgeschlossene Arbeiten erneut durchzuführen. + +Nextflow hat eine Option namens `-resume`, die dir dies ermöglicht. +Konkret werden in diesem Modus alle Prozesse übersprungen, die bereits mit exakt demselben Code, denselben Einstellungen und 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 zur Verfügung stellst. + +Dies hat zwei Hauptvorteile: + +- Wenn du gerade eine Pipeline entwickelst, 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 im Produktionsbetrieb ausführst und etwas schiefgeht, kannst du in vielen Fällen das Problem beheben und die Pipeline erneut starten, und sie wird vom Fehlerpunkt aus weiterlaufen, 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: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Achte auf den `cached:` Teil, der in der Prozessstatuszeile (Zeile 5) hinzugefügt wurde, was bedeutet, dass Nextflow erkannt hat, dass es diese Arbeit bereits erledigt hat und einfach das Ergebnis aus dem vorherigen erfolgreichen Lauf wiederverwendet. + +Du kannst auch sehen, dass der work Unterverzeichnis-Hash derselbe ist wie im vorherigen Lauf. +Nextflow zeigt dir buchstäblich auf die vorherige Ausführung und sagt "Das habe ich bereits dort drüben gemacht." + +!!! Tip "Tipp" + + Wenn du eine Pipeline mit `resume` erneut ausführst, überschreibt Nextflow keine Dateien, die von einem Prozessaufruf, der zuvor erfolgreich ausgeführt wurde, in ein `publishDir` Verzeichnis geschrieben wurden. + +### 3.2. Das Log vergangener Ausführungen einsehen + +Jedes Mal, wenn du einen Nextflow Workflow startest, wird eine Zeile in eine Logdatei namens `history` geschrieben, unter einem versteckten Verzeichnis namens `.nextflow` im aktuellen Arbeitsverzeichnis. + +Eine bequemere Möglichkeit, auf diese Informationen zuzugreifen, ist die Verwendung des `nextflow log` Befehls. + +```bash +nextflow log +``` + +Dies gibt den Inhalt der Logdatei im Terminal aus und zeigt dir den Zeitstempel, Laufnamen, Status und die vollständige Befehlszeile für jeden Nextflow Lauf, der aus dem aktuellen Arbeitsverzeichnis heraus gestartet wurde. + +### 3.3. Ältere work Verzeichnisse löschen + +Während des Entwicklungsprozesses führst du deine Entwurfs-Pipelines typischerweise sehr oft aus, was zu einer Ansammlung von sehr vielen Dateien über viele Unterverzeichnisse führen kann. +Da die Unterverzeichnisse zufällig benannt sind, ist es schwierig, anhand ihrer Namen zu erkennen, welche älter und welche aktueller sind. + +Nextflow enthält einen praktischen `clean` Unterbefehl, der automatisch die work Unterverzeichnisse für vergangene Läufe löschen kann, die dich nicht mehr interessieren, mit mehreren [Optionen](https://www.nextflow.io/docs/latest/reference/cli.html#clean), um zu steuern, was gelöscht wird. + +Du kannst das Nextflow Log verwenden, um einen Lauf anhand seines Zeitstempels und/oder seiner Befehlszeile nachzuschlagen, und dann `nextflow clean -before <run_name> -f` verwenden, um work Verzeichnisse von früheren Läufen zu löschen. + +!!! Warning "Warnung" + + Das Löschen von work Unterverzeichnissen aus vergangenen Läufen entfernt sie aus dem Nextflow Cache und löscht alle Ausgaben, die in diesen Verzeichnissen gespeichert waren. + Das bedeutet, dass es Nextflows Fähigkeit zerstört, 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! Wenn du die `publishDir` Direktive für diesen Zweck verwendest, stelle sicher, dass du den `copy` Modus verwendest, nicht den `symlink` Modus. + +### Zusammenfassung + +Du weißt, wie man eine Pipeline erneut startet, ohne Schritte zu wiederholen, die bereits auf identische Weise ausgeführt wurden, das Ausführungslog einsieht und den `nextflow clean` Befehl verwendest, um alte work Verzeichnisse aufzuräumen. + +### Was kommt als Nächstes? + +Jetzt, da du grundlegende Nextflow Operationen verstehst, bist du bereit, eine echte Bioimaging Pipeline mit nf-core/molkart auszuführen. diff --git a/docs/de/docs/nf4_science/imaging/02_run_molkart.md b/docs/de/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..9bd8502c72 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Teil 2: nf-core/molkart ausführen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In Teil 1 haben wir einen einfachen Hello-World-Workflow ausgeführt, um die Grundlagen der Nextflow-Ausführung zu verstehen. +Jetzt werden wir eine echte Bioimaging-Pipeline ausführen: **nf-core/molkart**. + +Diese Pipeline verarbeitet Molecular Cartography-Daten zur räumlichen Transkriptomik von Resolve Bioscience. +Die Nextflow-Muster, die du hier lernst, gelten jedoch für jede nf-core-Pipeline oder Produktions-Workflow. + +## 1. nf-core-Pipelines verstehen + +Bevor wir die Pipeline ausführen, lass uns verstehen, was nf-core ist und warum es für die Ausführung von Workflows wichtig ist. + +### 1.1. Was ist nf-core? + +[nf-core](https://nf-co.re/) ist eine Community-gesteuerte Sammlung hochwertiger Nextflow-Pipelines. +Alle nf-core-Pipelines folgen der gleichen Struktur und Konventionen, was bedeutet, dass du alle anderen ausführen kannst, sobald du eine gelernt hast. + +Hauptmerkmale von nf-core-Pipelines: + +- **Standardisierte Struktur**: Alle Pipelines haben konsistente Parameternamen und Verwendungsmuster +- **Integrierte Testdaten**: Jede Pipeline enthält Testprofile zur schnellen Validierung +- **Umfassende Dokumentation**: Detaillierte Gebrauchsanweisungen und Parameterbeschreibungen +- **Qualitätskontrolle**: Automatisierte QC-Berichte mit MultiQC +- **Container-Unterstützung**: Vorgefertigte Container für Reproduzierbarkeit + +!!! tip "Möchtest du mehr über nf-core erfahren?" + + Für eine ausführliche Einführung in die Entwicklung von nf-core-Pipelines sieh dir den Kurs [Hello nf-core](../../hello_nf-core/index.md) an. + Er behandelt, wie man nf-core-Pipelines von Grund auf erstellt und anpasst. + +### 1.2. Die molkart-Pipeline + +![nf-core/molkart-Pipeline](img/molkart.png) + +Die [nf-core/molkart](https://nf-co.re/molkart)-Pipeline verarbeitet räumliche Transkriptomik-Bilddaten durch mehrere Phasen: + +1. **Bildvorverarbeitung**: Gittermuster-Füllung und optional Kontrastverbesserung +2. **Zellsegmentierung**: Mehrere Algorithmus-Optionen (Cellpose, Mesmer, ilastik, Stardist) +3. **Spot-Zuweisung**: Transkript-Spots segmentierten Zellen zuweisen +4. **Qualitätskontrolle**: Umfassende QC-Berichte generieren + +Die wichtigsten Ausgaben sind: + +- Zell-nach-Transkript-Zähltabellen +- Segmentierungsmasken +- MultiQC-Qualitätskontrollbericht + +--- + +## 2. molkart mit Testdaten ausführen + +Bevor wir beginnen, lass uns das molkart-Repository lokal klonen, damit wir seinen Code inspizieren können: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Dies erstellt ein `molkart/`-Verzeichnis mit dem vollständigen Pipeline-Quellcode. + +!!! note "Warum klonen wir lokal?" + + Normalerweise würdest du nf-core-Pipelines direkt von GitHub mit `nextflow run nf-core/molkart -r 1.2.0` ausführen. + Nextflow lädt automatisch die angeforderte Pipeline-Version für dich nach `$HOME/.nextflow/assets/nf-core/molkart` herunter und führt sie von dort aus. + Für dieses Training klonen wir die Pipeline jedoch in ein anderes lokales Verzeichnis, damit wir den Code leichter inspizieren können. + +### 2.1. Container-Anforderungen verstehen + +Bevor wir die vollständige Pipeline ausführen, lass uns lernen, warum Container für nf-core-Pipelines unerlässlich sind. + +Lass uns versuchen, die Pipeline mit dem Testdatensatz und den Parametern aus der molkart-Testkonfiguration auszuführen: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Lass uns diese Parameter aufschlüsseln: + +- `--input`: Pfad zum Samplesheet mit Sample-Metadaten +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Parameter für Gittermuster-Füllung +- `--clahe_pyramid_tile`: Kernel-Größe für Kontrastverbesserung +- `--segmentation_method`: Welche(r) Algorithmus/Algorithmen für Zellsegmentierung verwendet werden soll(en) +- `--outdir`: Wo die Ergebnisse gespeichert werden sollen + +!!! Warning "Dieser Befehl wird fehlschlagen - das ist beabsichtigt!" + + Wir führen dies absichtlich ohne Container aus, um zu demonstrieren, warum sie benötigt werden. + +Nach einigen Momenten siehst du einen Fehler wie diesen: + +??? failure "Befehlsausgabe" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**Was passiert hier?** + +Der Fehler `command not found` (Exit-Status 127) bedeutet, dass Nextflow versucht hat, `duplicate_finder.py` auszuführen, es aber nicht auf deinem System finden konnte. +Das liegt daran, dass: + +1. Die Pipeline erwartet, dass spezialisierte Bioinformatik-Software installiert ist +2. Diese Tools (wie `duplicate_finder.py`, `apply_clahe.dask.py`, etc.) nicht Teil von Standard-Linux-Distributionen sind +3. Ohne Container versucht Nextflow, Befehle direkt auf deinem lokalen Computer auszuführen + +**Woher sollen diese Tools kommen?** + +Lass uns eines der Prozessmodule inspizieren, um zu sehen, wie es seine Software-Anforderungen deklariert. + +Öffne das CLAHE-Vorverarbeitungsmodul: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Sieh dir Zeile 5 an - du wirst sehen: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Diese Zeile teilt Nextflow mit: "Um diesen Prozess auszuführen, verwende das Docker-Image `ghcr.io/schapirolabor/molkart-local:v0.0.4`, das alle erforderliche Software enthält." + +Jeder Prozess deklariert, welches Container-Image seine benötigten Tools bereitstellt. +Nextflow verwendet diese Container jedoch nur, wenn du es ihm sagst! + +**Die Lösung: Docker in der Konfiguration aktivieren** + +### 2.2. Docker konfigurieren und die Pipeline starten + +Um Docker zu aktivieren, müssen wir `docker.enabled` von `false` auf `true` in der `nextflow.config`-Datei ändern. + +Öffne die Konfigurationsdatei: + +```bash +code nextflow.config +``` + +Ändere `docker.enabled = false` zu `docker.enabled = true`: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Führe nun die Pipeline erneut mit dem gleichen Befehl aus: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Dieses Mal wird Nextflow: + +1. Die `docker.enabled = true`-Einstellung aus der Konfiguration lesen +2. Die erforderlichen Docker-Images herunterladen (nur beim ersten Mal) +3. Jeden Prozess innerhalb seines angegebenen Containers ausführen +4. Erfolgreich ausgeführt werden, weil alle Tools innerhalb der Container verfügbar sind + +!!! Tip "Warum Container wichtig sind" + + Die meisten nf-core-Pipelines **erfordern** Containerisierung (Docker, Singularity, Podman, etc.), weil: + + - Sie spezialisierte Bioinformatik-Software verwenden, die nicht in Standardumgebungen verfügbar ist + - Container Reproduzierbarkeit gewährleisten - die exakt gleichen Software-Versionen laufen überall + - Du nicht manuell Dutzende von Tools und ihre Abhängigkeiten installieren musst + + Für weitere Details über Container in Nextflow siehe [Hello Containers](../../hello_nextflow/05_hello_containers.md) aus dem Hello-Nextflow-Training. + +### 2.3. Ausführung überwachen + +Während die Pipeline läuft, siehst du eine Ausgabe ähnlich dieser: + +??? success "Befehlsausgabe" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Beachte, wie diese Ausgabe detaillierter ist als unser Hello-World-Beispiel, wegen der nf-core-Konventionen, denen die Pipeline folgt: + +- Pipeline zeigt ihre Version und ihr Logo +- Konfigurationsparameter werden angezeigt +- Mehrere Prozesse laufen parallel (angezeigt durch mehrere Prozesszeilen) +- Prozessnamen enthalten den vollständigen Modulpfad (z.B. `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Prozessausführung verstehen + +Die Executor-Zeile `executor > local (22)` sagt dir: + +- **executor**: Welche Compute-Umgebung verwendet wird (`local` = dein Computer) +- **(22)**: Gesamtzahl der gestarteten Aufgaben + +Jede Prozesszeile zeigt: + +- **Hash** (`[1a/2b3c4d]`): Work-Verzeichnis-Identifier (wie vorher) +- **Prozessname**: Vollständiger Modulpfad und Prozessname +- **Eingabe-Identifier**: Sample-Name in Klammern +- **Fortschritt**: Prozentsatz abgeschlossen und Zählung (z.B. `1 of 1 ✔`) + +### Fazit + +Du weißt, wie man eine nf-core-Pipeline mit Testdaten startet und ihre Ausführungsausgabe interpretiert. + +### Was kommt als Nächstes? + +Lerne, wo du die Ergebnisse findest und wie du sie interpretierst. + +--- + +## 3. Ausgaben finden und untersuchen + +Wenn die Pipeline erfolgreich abgeschlossen ist, siehst du eine Abschlussmeldung und Ausführungszusammenfassung. + +### 3.1. Das Ergebnisverzeichnis finden + +Standardmäßig schreiben nf-core-Pipelines Ausgaben in ein Verzeichnis, das durch den Parameter `outdir` angegeben ist, den wir auf `results/` gesetzt haben. + +Liste den Inhalt auf: + +```bash +tree results/ +``` + +Du solltest mehrere Unterverzeichnisse sehen: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Jedes Unterverzeichnis enthält Ausgaben aus einer bestimmten Phase der Pipeline: + +- **mindagap/**: Gittergefüllte Bilder aus dem MindaGap-Vorverarbeitungsschritt +- **clahe/**: Kontrastverbesserte Bilder aus der CLAHE-Vorverarbeitung +- **stack/**: Multi-Channel-Bild-Stacks, die für die Segmentierung erstellt wurden +- **segmentation/**: Segmentierungsergebnisse von verschiedenen Algorithmen (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Zell-nach-Transkript-Zähltabellen +- **anndata/**: AnnData-Objekte mit Zell-nach-Transkript-Matrizen und räumlichen Koordinaten +- **molkartqc/**: Qualitätskontrollmetriken für Spot-Zuweisung +- **multiqc/**: Umfassender Qualitätskontrollbericht +- **pipeline_info/**: Ausführungsberichte und Logs + +### 3.2. Den MultiQC-Bericht untersuchen + +Der MultiQC-Bericht ist eine umfassende HTML-Datei, die Qualitätsmetriken aus allen Pipeline-Schritten aggregiert. + +Öffne den Bericht im Dateibrowser und klicke dann auf den Button "Show Preview", um ihn direkt in VS Code gerendert zu sehen. + +Der Bericht enthält: + +- Allgemeine Statistiken für alle Proben +- Vorverarbeitungsmetriken +- Segmentierungsqualitätsmetriken +- Anzahl erkannter Zellen und Spots + +!!! Tip + + MultiQC-Berichte sind typischerweise in allen nf-core-Pipelines enthalten. + Sie bieten immer einen Überblick über die Pipeline-Ausführung und Datenqualität. + +### 3.3. Die Zell-nach-Transkript-Tabellen untersuchen + +Die wichtigste wissenschaftliche Ausgabe ist die Zell-nach-Transkript-Zähltabelle. +Diese sagt dir, wie viele von jedem Transkript in jeder Zelle erkannt wurden. + +Navigiere zum spot2cell-Verzeichnis: + +```bash +ls results/spot2cell/ +``` + +Du findest Dateien wie: + +- `cellxgene_mem_only_cellpose.csv`: Zell-nach-Transkript-Tabelle mit Cellpose-Segmentierung +- `cellxgene_mem_only_mesmer.csv`: Zell-nach-Transkript-Tabelle mit Mesmer-Segmentierung +- `cellxgene_mem_only_stardist.csv`: Zell-nach-Transkript-Tabelle mit Stardist-Segmentierung + +Wir haben in diesem Testdatensatz nur 1 Probe ausgeführt, aber in einem echten Experiment hätten wir diese Tabellen für jede Probe. +Beachte, wie Nextflow in der Lage ist, mehrere Segmentierungsmethoden parallel zu verarbeiten, was es einfach macht, Ergebnisse zu vergleichen. + +### 3.4. Ausführungsberichte ansehen + +Nextflow generiert automatisch mehrere Ausführungsberichte. + +Überprüfe das pipeline_info-Verzeichnis: + +```bash +ls results/pipeline_info/ +``` + +Wichtige Dateien: + +- **execution_report.html**: Zeitachse und Ressourcennutzungsvisualisierung +- **execution_timeline.html**: Gantt-Diagramm der Prozessausführung +- **execution_trace.txt**: Detaillierte Aufgabenausführungsmetriken +- **pipeline_dag.html**: Gerichteter azyklischer Graph, der die Workflow-Struktur zeigt + +Öffne den Ausführungsbericht, um die Ressourcennutzung zu sehen: + +```bash +code results/pipeline_info/execution_report.html +``` + +Dies zeigt: + +- Wie lange jeder Prozess gedauert hat +- CPU- und Speichernutzung +- Welche Aufgaben gecacht wurden vs. ausgeführt wurden + +!!! Tip + + Diese Berichte sind unglaublich nützlich für die Optimierung der Ressourcenzuteilung und die Fehlerbehebung bei Leistungsproblemen. + +### Fazit + +Du weißt, wie man Pipeline-Ausgaben findet, Qualitätskontrollberichte untersucht und auf Ausführungsmetriken zugreift. + +### Was kommt als Nächstes? + +Lerne über das Work-Verzeichnis und wie Nextflow Zwischendateien verwaltet. + +--- + +## 4. Das Work-Verzeichnis erkunden + +Genau wie bei unserem Hello-World-Beispiel findet die gesamte eigentliche Arbeit im `work/`-Verzeichnis statt. + +### 4.1. Die Struktur des Work-Verzeichnisses verstehen + +Das Work-Verzeichnis enthält ein Unterverzeichnis für jede Aufgabe, die ausgeführt wurde. +Für diese Pipeline mit 12 Aufgaben wird es 12 Work-Unterverzeichnisse geben. + +Liste das Work-Verzeichnis auf: + +```bash +ls -d work/*/*/ | head -5 +``` + +Dies zeigt die ersten 5 Aufgabenverzeichnisse. + +### 4.2. Ein Aufgabenverzeichnis inspizieren + +Wähle einen der Segmentierungsprozess-Hashes aus der Konsolenausgabe (z.B. `[3m/4n5o6p]`) und schau hinein: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Du wirst sehen: + +- **.command.\*-Dateien**: Nextflow-Ausführungsskripte und Logs (wie vorher) +- **Gestufte Eingabedateien**: Symlinks zu den tatsächlichen Eingabedateien +- **Ausgabedateien**: Segmentierungsmasken, Zwischenergebnisse, etc. + +Der Hauptunterschied zu Hello World: + +- Echte Pipelines stufen große Eingabedateien (Bilder, Referenzdaten) +- Ausgabedateien können ziemlich groß sein (Segmentierungsmasken, verarbeitete Bilder) +- Mehrere Eingabe- und Ausgabedateien pro Aufgabe + +!!! Tip + + Wenn ein Prozess fehlschlägt, kannst du zu seinem Work-Verzeichnis navigieren, `.command.err` für Fehlermeldungen untersuchen und sogar `.command.sh` manuell erneut ausführen, um das Problem zu debuggen. + +### 4.3. Aufräumen des Work-Verzeichnisses + +Das Work-Verzeichnis kann über mehrere Pipeline-Läufe hinweg ziemlich groß werden. +Wie wir in Teil 1 gelernt haben, kannst du `nextflow clean` verwenden, um Work-Verzeichnisse von alten Läufen zu entfernen. + +Für nf-core-Pipelines mit großen Zwischendateien ist es jedoch besonders wichtig, regelmäßig aufzuräumen. + +### Fazit + +Du verstehst, wie nf-core-Pipelines ihre Work-Verzeichnisse organisieren und wie man einzelne Aufgaben zum Debuggen inspiziert. + +### Was kommt als Nächstes? + +Lerne über den Nextflow-Cache und wie man fehlgeschlagene Pipeline-Läufe fortsetzt. + +--- + +## 5. Einen Pipeline-Lauf fortsetzen + +Eine der leistungsstärksten Funktionen von Nextflow ist die Fähigkeit, eine Pipeline vom Fehlerpunkt aus fortzusetzen. + +### 5.1. Der Cache-Mechanismus + +Wenn du eine Pipeline mit `-resume` ausführst, prüft Nextflow: + +1. Den Cache für jede Aufgabe +2. Wenn Eingaben, Code und Parameter identisch sind, wird das gecachte Ergebnis wiederverwendet +3. Nur Aufgaben werden erneut ausgeführt, die sich geändert haben oder fehlgeschlagen sind + +Dies ist für langläufige Pipelines unerlässlich, bei denen Fehler spät in der Ausführung auftreten können. + +### 5.2. Resume mit molkart ausprobieren + +Führe den gleichen Befehl erneut aus, aber füge `-resume` hinzu: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Du solltest eine Ausgabe wie diese sehen: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Beachte `cached: 2` oder `cached: 1` für jeden Prozess - nichts wurde erneut ausgeführt! + +### 5.3. Wann Resume nützlich ist + +Resume ist besonders wertvoll, wenn: + +- Eine Pipeline aufgrund von Ressourcenlimits fehlschlägt (kein Speicher mehr, Zeitlimit überschritten) +- Du nachgelagerte Prozesse ändern musst, ohne vorgelagerte Schritte erneut auszuführen +- Deine Netzwerkverbindung während des Datendownloads abbricht +- Du zusätzliche Ausgaben hinzufügen möchtest, ohne Berechnungen zu wiederholen + +!!! Warning + + Resume funktioniert nur, wenn du die Eingabedaten, den Pipeline-Code oder die Parameter nicht geändert hast. + Wenn du eines davon änderst, wird Nextflow betroffene Aufgaben korrekt erneut ausführen. + +### Fazit + +Du weißt, wie man `-resume` verwendet, um Pipelines effizient erneut auszuführen, ohne erfolgreiche Aufgaben zu wiederholen. + +### Was kommt als Nächstes? + +Jetzt, da du nf-core/molkart mit Testdaten ausführen kannst, bist du bereit zu lernen, wie man es für deine eigenen Datensätze konfiguriert. diff --git a/docs/de/docs/nf4_science/imaging/03_inputs.md b/docs/de/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..86232afaf0 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Teil 3: Eingaben organisieren + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In Teil 2 haben wir molkart mit mehreren Parametern über die Kommandozeile ausgeführt. +Jetzt lernen wir zwei bessere Ansätze zum Verwalten von Eingaben kennen: **Parameterdateien** und **Samplesheets**. + +## 1. Parameterdateien verwenden + +### 1.1. Das Problem mit langen Befehlszeilen + +Erinnere dich an unseren Befehl aus Teil 2: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Das funktioniert, ist aber schwer zu reproduzieren, zu teilen oder zu ändern. +Was, wenn du dieselbe Analyse nächsten Monat erneut ausführen musst? +Was, wenn ein Kollege genau deine Einstellungen verwenden möchte? + +### 1.2. Lösung: Verwende eine Parameterdatei + +Erstelle eine Datei namens `params.yaml`: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Jetzt wird dein Befehl zu: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +Das war's! Die Parameterdatei dokumentiert deine exakte Konfiguration und macht es einfach, sie erneut auszuführen oder zu teilen. + +### 1.3. Parameter überschreiben + +Du kannst immer noch spezifische Parameter über die Kommandozeile überschreiben: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +Die obige Zeile ändert die `segmentation_method` zu `stardist` und den Namen von `--outdir` zu `stardist_results` anstelle der Parameter in der `params.yaml`-Datei. +Außerdem kannst du sehen, dass das `-resume`-Flag es uns ermöglicht hat, die Vorverarbeitungsergebnisse aus dem vorherigen Lauf wiederzuverwenden, was Zeit spart. +Du kannst dieses Muster nutzen, um schnell verschiedene Variationen der Pipeline zu testen. + +### Fazit + +Parameterdateien machen deine Analysen reproduzierbar und einfach zu teilen. +Verwende sie für jede echte Analysearbeit. + +### Wie geht es weiter? + +Erfahre, wie Samplesheets Informationen über mehrere Proben organisieren. + +--- + +## 2. Das Samplesheet-Muster + +### 2.1. Was ist ein Samplesheet? + +Ein Samplesheet ist eine CSV-Datei, die deine Eingabeproben beschreibt. +Jede Zeile ist eine Probe, und die Spalten spezifizieren die Dateien und Metadaten für diese Probe. + +Schauen wir uns das Samplesheet an, das wir verwendet haben: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Die Spalten sind: + +- `sample`: Eindeutige Proben-Kennung +- `nuclear_image`: Kernfärbungsbild (TIFF) +- `spot_table`: Transkript-Spots (TXT) +- `membrane_image`: Membranfärbungsbild (TIFF, optional) + +### 2.2. Dateipfade + +Samplesheets akzeptieren mehrere Pfadtypen: + +- **URLs**: Nextflow lädt automatisch herunter (wie oben gezeigt) +- **Lokale Pfade**: `data/nuclear.tiff` oder `/absolute/path/to/nuclear.tiff` +- **Cloud-Speicher**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Du kannst Pfadtypen im selben Samplesheet mischen. + +### 2.3. Dein eigenes Samplesheet erstellen + +Lass uns zunächst die Testdaten lokal herunterladen: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Jetzt ändern wir das Samplesheet, um auf diese lokalen Dateien zu verweisen: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Warnung" + + Beachte, dass die Pfade im Samplesheet relativ zu dem Ort sind, an dem du Nextflow **ausführst**, nicht wo sich das Samplesheet befindet. + +Lass uns schließlich nf-core/molkart noch einmal mit dem Samplesheet mit lokalen Dateipfaden ausführen: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Wie du sehen kannst, führt Nextflow diesen Lauf ähnlich aus wie bei den Dateien, die von Github heruntergeladen wurden. Dies ist eine der großartigen Funktionen von Nextflow: Es bereitet die Daten für dich korrekt vor, unabhängig davon, wo sie sich befinden. + +### Fazit + +Samplesheets organisieren Multi-Proben-Datensätze auf eine Weise, die es dir ermöglicht, deine Metadaten zusammen mit den Dateipfaden explizit zu definieren. +Die meisten nf-core-Pipelines verwenden dieses Muster. + +### Wie geht es weiter? + +Nachdem wir Eingaben behandelt haben, lass uns untersuchen, wie man Nextflow-Pipelines für verschiedene Rechenumgebungen konfiguriert. diff --git a/docs/de/docs/nf4_science/imaging/04_config.md b/docs/de/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..80bbf8b721 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Teil 4: Konfiguration + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In den Teilen 1-3 haben wir gelernt, wie man Nextflow ausführt, eine nf-core Pipeline ausführt und Eingaben mit Parameterdateien und Samplesheets verwaltet. +Jetzt werden wir erkunden, wie man Pipelines für verschiedene Rechenumgebungen mit **Konfigurationsdateien** und **Profilen** konfiguriert. + +## Lernziele + +Am Ende dieses Teils kannst du: + +- Zu verstehen, wie Nextflow Konfigurationen aus mehreren Quellen auflöst +- nf-core eingebaute Profile für Container und Tests zu verwenden +- Eigene Profile für verschiedene Rechenumgebungen zu erstellen +- Ressourcenanforderungen mit Process-Labels anzupassen +- Ressourcenlimits in eingeschränkten Umgebungen zu verwalten +- Aufgelöste Konfigurationen mit `nextflow config` zu inspizieren + +--- + +## 1. Nextflow-Konfiguration verstehen + +### 1.1. Was ist eine Konfigurationsdatei? + +Nextflow verwendet Konfigurationsdateien, um **Workflow-Logik** (was zu tun ist) von **Ausführungseinstellungen** (wie und wo es zu tun ist) zu trennen. + +Konfigurationsdateien steuern: + +- Container-Engines (Docker, Singularity, Conda) +- Rechenressourcen (CPUs, Speicher, Zeit) +- Ausführungsplattformen (lokal, HPC, Cloud) +- Pipeline-Parameter + +### 1.2. Konfigurationspriorität + +Nextflow lädt Konfigurationen aus mehreren Quellen, wobei spätere Quellen frühere überschreiben: + +1. **Pipeline-Konfiguration**: `nextflow.config` im Pipeline-Repository +2. **Verzeichnis-Konfiguration**: `nextflow.config` in deinem aktuellen Arbeitsverzeichnis +3. **Benutzer-Konfiguration**: `~/.nextflow/config` +4. **Befehlszeile**: Parameter und Optionen, die direkt übergeben werden + +Dieser geschichtete Ansatz ermöglicht es dir, Standardeinstellungen in der Pipeline zu behalten, mit benutzerspezifischen Einstellungen zu überschreiben und schnelle Anpassungen über die Befehlszeile vorzunehmen. + +### 1.3. Unsere aktuelle Konfiguration + +Schauen wir uns die Konfiguration an, die wir bisher verwendet haben: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Kommentieren wir die Zeile `docker.enabled = true` aus Teil 2 aus oder ändern sie zurück und finden heraus, wie wir das gleiche Ergebnis mit einem Profil in molkart erreichen können. + +--- + +## 2. Profile verwenden + +### 2.1. Was sind Profile? + +Profile sind benannte Konfigurationssätze, die mit dem `-profile`-Flag über den `nextflow run`-Befehl aktiviert werden können. +Sie erleichtern den Wechsel zwischen verschiedenen Rechenszenarien, ohne Konfigurationsdateien bearbeiten zu müssen. + +Alle nf-core Pipelines kommen mit einer Reihe von Standardprofilen, die wir nutzen können. + +### 2.2. Eingebaute Profile inspizieren + +Schauen wir sie uns in der `molkart/nextflow.config`-Datei an, die mit der Pipeline-Codebasis verknüpft ist: + +```bash +code molkart/nextflow.config +``` + +Suche nach dem `profiles`-Block: + +```groovy title="molkart/nextflow.config (Auszug)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Häufige Container-Profile: + +- `docker`: Docker-Container verwenden (am häufigsten für lokale Entwicklung) +- `singularity`: Singularity/Apptainer verwenden (häufig auf HPC) +- `conda`: Conda-Umgebungen verwenden +- `apptainer`: Apptainer-Container verwenden + +### 2.3. Erneut ausführen mit Profilen anstelle von nextflow.config + +Nachdem wir die Docker-Konfiguration in unserer lokalen `nextflow.config`-Datei deaktiviert haben und Profile verstehen, führen wir die Pipeline mit dem `-profile`-Flag erneut aus. + +Zuvor in Teil 3 haben wir eine `params.yaml`-Datei mit unseren benutzerdefinierten Parametern erstellt. +Wir können diese nun mit dem eingebauten Docker-Profil kombinieren: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Schauen wir uns an, was jedes Flag bewirkt: + +- `-profile docker`: Aktiviert das Docker-Profil aus molkarts `nextflow.config`, das `docker.enabled = true` setzt +- `-params-file params.yaml`: Lädt alle Pipeline-Parameter aus unserer YAML-Datei +- `-resume`: Verwendet zwischengespeicherte Ergebnisse aus vorherigen Ausführungen wieder + +Da wir `-resume` verwenden, prüft Nextflow, ob sich seit der letzten Ausführung etwas geändert hat. +Wenn Parameter, Eingaben und Code gleich sind, werden alle Aufgaben aus dem Cache abgerufen und die Pipeline wird fast sofort abgeschlossen. + +```console title="Ausgabe (Auszug)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Beachte, dass alle Prozesse `cached: 2` oder `cached: 1` anzeigen - nichts wurde erneut ausgeführt! + +### 2.4. Test-Profile + +Test-Profile bieten schnelle Möglichkeiten, Standardeingabeparameter und Datendateien anzugeben, damit du überprüfen kannst, ob die Pipeline funktioniert. +nf-core Pipelines enthalten immer mindestens zwei Test-Profile: + +- `test`: Kleiner Datensatz mit schnellen Parametern für schnelles Testen +- `test_full`: Umfassenderer Test mit größeren Daten + +Schauen wir uns das `test`-Profil in molkart genauer an, das mit der `includeConfig`-Direktive eingebunden wird: + +```groovy title="molkart/nextflow.config (Auszug)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Das bedeutet, wann immer wir die Pipeline mit `-profile test` ausführen, lädt Nextflow die Konfiguration aus `conf/test.config`. + +```groovy title="molkart/conf/test.config (Auszug)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Beachte, dass dieses Profil dieselben Parameter enthält, die wir zuvor in unserer `params.yaml`-Datei verwendet haben. + +Du kannst mehrere Profile aktivieren, indem du sie durch Kommas trennst. +Nutzen wir das, um unsere Pipeline zu testen, ohne unsere Parameterdatei zu benötigen: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Dies kombiniert: + +- `docker`: Docker-Container aktivieren +- `test`: Test-Datensatz und -Parameter verwenden + +Profile werden von links nach rechts angewendet, spätere Profile überschreiben also frühere, wenn sie dieselben Werte setzen. + +### Fazit + +nf-core Pipelines kommen mit eingebauten Profilen für Container, Tests und spezielle Umgebungen. +Du kannst mehrere Profile kombinieren, um die benötigte Konfiguration aufzubauen. + +### Was kommt als Nächstes? + +Lerne, wie du eigene Profile für verschiedene Rechenumgebungen erstellst. + +--- + +## 3. Eigene Profile erstellen + +### 3.1. Profile für den Wechsel zwischen lokaler Entwicklung und Ausführung auf HPC erstellen + +Erstellen wir eigene Profile für zwei Szenarien: + +1. Lokale Entwicklung mit Docker +2. Universitäts-HPC mit Slurm-Scheduler und Singularity + +Füge Folgendes zu deiner `nextflow.config` hinzu: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Jetzt kannst du einfach zwischen Umgebungen wechseln: + +```bash +# Für lokale Entwicklung +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Für HPC (wenn verfügbar) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "Hinweis" + + Wir können das HPC-Profil in dieser Trainingsumgebung nicht testen, da wir keinen Zugang zu einem Slurm-Scheduler haben. + Aber dies zeigt, wie du es für die praktische Anwendung konfigurieren würdest. + +### 3.2. `nextflow config` verwenden, um Konfigurationen zu inspizieren + +Der `nextflow config`-Befehl zeigt die vollständig aufgelöste Konfiguration, ohne die Pipeline auszuführen. + +Standardkonfiguration anzeigen: + +```bash +nextflow config ./molkart +``` + +Konfiguration mit einem bestimmten Profil anzeigen: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Dies ist äußerst nützlich für: + +- Debugging von Konfigurationsproblemen +- Verstehen, welche Werte tatsächlich verwendet werden +- Prüfen, wie mehrere Profile interagieren + +### Fazit + +Eigene Profile ermöglichen es dir, mit einem einzigen Befehlszeilen-Flag zwischen verschiedenen Rechenumgebungen zu wechseln. +Verwende `nextflow config`, um die aufgelöste Konfiguration vor der Ausführung zu inspizieren. + +### Was kommt als Nächstes? + +Lerne, wie du Ressourcenanforderungen für einzelne Prozesse mithilfe des Process-Label-Systems von nf-core anpasst. + +--- + +## 4. Ressourcenanforderungen anpassen + +### 4.1. Process-Labels in nf-core Pipelines verstehen + +Zur Vereinfachung verwenden nf-core Pipelines [**Process-Labels**](https://www.nextflow.io/docs/latest/reference/process.html#process-label), um die Ressourcenzuweisung über alle Pipelines hinweg zu standardisieren. +Jeder Prozess ist mit einem Label wie `process_low`, `process_medium` oder `process_high` versehen, um niedrige, mittlere bzw. hohe Rechenressourcenanforderungen zu beschreiben. +Diese Labels werden in einer der Konfigurationsdateien im `conf/`-Verzeichnis der Pipeline in spezifische Ressourcenanforderungen umgewandelt. + +```groovy title="molkart/conf/base.config (Auszug)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Beachte den `task.attempt`-Multiplikator - dieser ermöglicht es nachfolgenden Aufgabenwiederholungen, mehr Ressourcen anzufordern, wenn die Pipeline mit `process.maxRetries > 1` konfiguriert ist. + +### 4.2. Ressourcen für bestimmte Prozesse überschreiben + +Für feinere Kontrolle kannst du einzelne Prozesse nach Namen ansprechen: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Wenn wir versuchen, diese Pipeline mit der obigen Überschreibung auszuführen, wird der `CELLPOSE`-Prozess 16 CPUs und 32 GB Speicher anfordern anstelle des durch sein Label definierten Standards. +Dies wird dazu führen, dass die Pipeline in unserer aktuellen Umgebung fehlschlägt, da wir nicht so viel RAM zur Verfügung haben. +Wir werden im nächsten Abschnitt lernen, wie man solche Fehler verhindert. + +!!! tip "Tipp" + + Um Prozessnamen zu finden, schaue in die Pipeline-Ausführungsausgabe oder prüfe `.nextflow.log`. + Prozessnamen folgen dem Muster `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### Fazit + +nf-core Pipelines verwenden Process-Labels zur Standardisierung der Ressourcenzuweisung. +Du kannst Ressourcen nach Label überschreiben (betrifft mehrere Prozesse) oder nach Namen (betrifft einen bestimmten Prozess). + +### Was kommt als Nächstes? + +Lerne, wie du Ressourcenlimits in eingeschränkten Umgebungen wie GitHub Codespaces verwaltest. + +--- + +## 5. Ressourcen in eingeschränkten Umgebungen verwalten + +### 5.1. Das Ressourcenlimit-Problem + +Wenn wir versuchen würden, molkart mit einem Prozess auszuführen, der 16 CPUs und 32 GB Speicher anfordert (wie in Abschnitt 4.2 gezeigt), würde dies in unserer aktuellen Umgebung fehlschlagen, weil wir nicht so viele Ressourcen zur Verfügung haben. +In einer Cluster-Umgebung mit größeren Knoten würden solche Anforderungen an den Scheduler übermittelt. + +In eingeschränkten Umgebungen wie GitHub Codespaces würde Nextflow ohne Limits die Ausführung von Prozessen verweigern, die die verfügbaren Ressourcen überschreiten. + +### 5.2. Ressourcenlimits setzen + +Die `resourceLimits`-Direktive begrenzt Ressourcenanforderungen auf angegebene Werte: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Dies teilt Nextflow mit: "Wenn ein Prozess mehr als 2 CPUs oder 7 GB Speicher anfordert, begrenze es stattdessen auf diese Limits." + +### 5.3. Ressourcenlimits zu eigenen Profilen hinzufügen + +Aktualisiere deine eigenen Profile, um angemessene Limits einzuschließen: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "Warnung" + + Zu niedrige Ressourcenlimits können dazu führen, dass Prozesse fehlschlagen oder langsam laufen. + Die Pipeline muss möglicherweise weniger speicherintensive Algorithmen verwenden oder Daten in kleineren Blöcken verarbeiten. + +### Fazit + +Verwende `resourceLimits`, um Pipelines in ressourcenbeschränkten Umgebungen auszuführen, indem du Prozessressourcenanforderungen begrenzt. +Verschiedene Profile können unterschiedliche Limits haben, die für ihre Umgebung angemessen sind. + +### Was kommt als Nächstes? + +Du hast das Kern-Training "Nextflow für Bioimaging" abgeschlossen! + +--- + +## Zusammenfassung + +Du verstehst jetzt, wie man Nextflow-Pipelines für verschiedene Rechenumgebungen konfiguriert. + +Wichtige Fähigkeiten, die du gelernt hast: + +- **Konfigurationspriorität**: Wie Nextflow Einstellungen aus mehreren Quellen auflöst +- **nf-core Profile**: Verwendung eingebauter Profile für Container, Tests und Hilfsprogramme +- **Eigene Profile**: Erstellen eigener Profile für verschiedene Umgebungen +- **Process-Labels**: Verstehen und Überschreiben von Ressourcenanforderungen nach Label +- **Ressourcenlimits**: Verwalten eingeschränkter Umgebungen mit `resourceLimits` +- **Konfigurationsinspektion**: Verwendung von `nextflow config` zum Debuggen und Überprüfen von Einstellungen + +Diese Konfigurationsfähigkeiten sind auf jede Nextflow-Pipeline übertragbar und helfen dir, Workflows effizient auf lokalen Rechnern, HPC-Clustern und Cloud-Plattformen auszuführen. + +### Was kommt als Nächstes? + +Herzlichen Glückwunsch zum Abschluss des Kurses "Nextflow für Bioimaging"! + +Nächste Schritte: + +- Fülle die Kursumfrage aus, um Feedback zu geben +- Schau dir [Hello Nextflow](../hello_nextflow/index.md) an, um mehr über die Entwicklung von Workflows zu lernen +- Erkunde [Hello nf-core](../hello_nf-core/index.md), um tiefer in die nf-core Werkzeuge einzutauchen +- Durchsuche andere Kurse in den [Trainingssammlungen](../training_collections/index.md) diff --git a/docs/de/docs/nf4_science/imaging/index.md b/docs/de/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..f6e3195621 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/index.md @@ -0,0 +1,40 @@ +```markdown +--- +title: Nextflow run für Bildgebung +hide: + - toc +--- + +# Nextflow run für Bildgebung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dieser Trainingskurs richtet sich an Forschende im Bereich Bildgebung und räumliche Biologie, die daran interessiert sind, Datenanalyse-Pipelines auszuführen und anzupassen. +Er vermittelt grundlegende Nextflow-Konzepte für das Ausführen, Organisieren und Konfigurieren von Workflows anhand von [nf-core/molkart](https://nf-co.re/molkart), einer Pipeline zur Verarbeitung von Molecular Cartography Spatial-Transkriptomik-Daten. +Die hier erlernten Fähigkeiten sind auf jede Nextflow- oder nf-core-Pipeline übertragbar. + +Los geht's! Klicke unten auf die Schaltfläche "Open in GitHub Codespaces", um die Trainingsumgebung zu starten (vorzugsweise in einem separaten Tab), und lies dann weiter, während sie lädt. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Lernziele + +Durch die Bearbeitung dieses Kurses lernst du, wie du grundlegende Nextflow-Konzepte und -Tools auf die Ausführung von Bildgebungsanalyse-Pipelines anwendest. + +Am Ende dieses Workshops kannst du: + +- Einen Nextflow-Workflow lokal zu starten und die Ausführung zu überwachen +- Von Nextflow generierte Ausgaben (Ergebnisse) und Log-Dateien zu finden und zu interpretieren +- Eine nf-core-Pipeline mit Testdaten und benutzerdefinierten Eingaben auszuführen +- Die Pipeline-Ausführung mithilfe von Profilen und Parameterdateien zu konfigurieren +- Eingaben mithilfe von Samplesheets und Befehlszeilenparametern zu verwalten + +## Zielgruppe & Voraussetzungen + +Dieser Kurs setzt ein Mindestmaß an Vertrautheit mit Folgendem voraus: + +- Erfahrung mit der Befehlszeile +- Grundlegende Vertrautheit mit Bildgebungsdateiformaten (TIFF-Bilder, tabellarische Daten) + +Für technische Anforderungen und die Einrichtung der Umgebung siehe den Mini-Kurs [Umgebungseinrichtung](../../envsetup/). +``` diff --git a/docs/de/docs/nf4_science/imaging/next_steps.md b/docs/de/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..2739447170 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Nächste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herzlichen Glückwunsch zum Abschluss des Nextflow for Bioimaging Trainings! + +Du hast jetzt die grundlegenden Fähigkeiten, um Nextflow Pipelines für die Analyse von Bilddaten auszuführen und zu konfigurieren. + +## Weiterlernen + +Hier sind einige empfohlene nächste Schritte, um dein Nextflow-Wissen zu vertiefen: + +### Weitere nf-core Pipelines erkunden + +- **Alle Pipelines durchsuchen**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Eigene Pipelines entwickeln + +Wenn du lernen möchtest, wie man Nextflow Pipelines schreibt: + +- **[Hello Nextflow](../../hello_nextflow/)**: Umfassendes Nextflow-Entwicklungstraining +- **[Side Quests](../../side_quests/)**: Fortgeschrittene Themen für Pipeline-Entwickler + +### Der Community beitreten + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Hilfe erhalten und mit anderen Nutzern in Kontakt treten +- **[nf-core Slack](https://nf-co.re/join)**: Der nf-core Community beitreten +- **[Seqera Community Forum](https://community.seqera.io)**: Fragen stellen und Erfahrungen teilen + +### Zusätzliche Ressourcen + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Vollständige Referenzdokumentation +- **[nf-core Documentation](https://nf-co.re/docs)**: Richtlinien und Best Practices + +## Mitmachen + +- **Zu nf-core beitragen**: Hilf mit, Pipelines oder Dokumentation zu verbessern +- **Deine Workflows teilen**: Steuere deine eigenen Pipelines zur Community bei +- **An Veranstaltungen teilnehmen**: Nimm am Nextflow Summit und Community-Trainings teil + +Vielen Dank, dass du mit uns gelernt hast! diff --git a/docs/de/docs/nf4_science/imaging/survey.md b/docs/de/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..97490d6592 --- /dev/null +++ b/docs/de/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Vielen Dank, dass du das Nextflow für Bioimaging Training abgeschlossen hast! + +Wir würden uns sehr über dein Feedback freuen, um dieses Trainingsmaterial zu verbessern. + +Bitte nimm dir ein paar Minuten Zeit, um unsere kurze Umfrage auszufüllen: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Deine Antworten helfen uns zu verstehen, was gut funktioniert hat und was wir für zukünftige Lernende verbessern können. + +Vielen Dank für deine Zeit und Teilnahme! diff --git a/docs/de/docs/nf4_science/index.md b/docs/de/docs/nf4_science/index.md new file mode 100644 index 0000000000..efea905fc4 --- /dev/null +++ b/docs/de/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow für die Wissenschaft +hide: + - toc +--- + +# Nextflow für die Wissenschaft + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dies sind Kurse, die zeigen, wie du die Konzepte und Komponenten aus dem [Hello Nextflow](../hello_nextflow/) Anfängerkurs auf spezifische wissenschaftliche Anwendungsfälle anwenden kannst. Jeder Kurs besteht aus einer Reihe von Trainingsmodulen, die so gestaltet sind, dass Lernende ihre Fähigkeiten schrittweise aufbauen können. + +!!! exercise "Nextflow für Genomik" + + !!! tip inline end "" + + :material-run-fast: Lerne, eine Pipeline für Genomik in Nextflow zu entwickeln. + + Dies ist ein Kurs für Forschende, die lernen möchten, wie sie ihre eigenen Genomik-Pipelines entwickeln. Der Kurs verwendet einen Variant-Calling-Anwendungsfall, um zu demonstrieren, wie man eine einfache, aber funktionale Genomik-Pipeline entwickelt. + + [Starte das Nextflow für Genomik Training :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Nextflow für RNAseq" + + !!! tip inline end "" + + :material-run-fast: Lerne, eine Pipeline für RNAseq-Datenverarbeitung in Nextflow zu entwickeln. + + Dies ist ein Kurs für Forschende, die lernen möchten, wie sie ihre eigenen RNAseq-Pipelines entwickeln. Der Kurs verwendet einen Bulk-RNAseq-Verarbeitungs-Anwendungsfall, um zu demonstrieren, wie man eine einfache, aber funktionale RNAseq-Pipeline entwickelt. + + [Starte das Nextflow für RNAseq Training :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Nextflow für Bioimaging" + + !!! tip inline end "" + + :material-run-fast: Lerne, Pipelines für Bilddaten in Nextflow auszuführen. + + Dies ist ein Kurs für Forschende, die lernen möchten, wie sie Bioimaging-Pipelines ausführen und konfigurieren. Der Kurs verwendet nf-core/molkart, um wesentliche Nextflow-Nutzungsmuster zu demonstrieren, die auf jede Pipeline anwendbar sind. + + [Starte das Nextflow für Bioimaging Training :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Lass uns wissen, welche anderen Bereiche und Anwendungsfälle du hier gerne behandelt sehen würdest, indem du im [Training-Bereich](https://community.seqera.io/c/training/) des Community-Forums postest. diff --git a/docs/de/docs/nf4_science/rnaseq/00_orientation.md b/docs/de/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..1c271c2f6b --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Die Trainingsumgebung enthält alle Software, Code und Daten, die zum Durcharbeiten dieses Trainingskurses notwendig sind, sodass du nichts selbst installieren musst. +Allerdings benötigst du einen (kostenlosen) Account zum Anmelden, und du solltest dir ein paar Minuten Zeit nehmen, um dich mit der Benutzeroberfläche vertraut zu machen. + +Falls du dies noch nicht getan hast, absolviere bitte den Mini-Kurs [Environment Setup](../../envsetup/), bevor du fortfährst. + +## Bereitgestellte Materialien + +Während dieses Trainingskurses arbeiten wir im Verzeichnis `nf4-science/rnaseq/`, in das du wechseln musst, wenn du den Trainingsarbeitsbereich öffnest. +Dieses Verzeichnis enthält alle Code-Dateien, Testdaten und zusätzlichen Dateien, die du benötigen wirst. + +Erkunde gerne den Inhalt dieses Verzeichnisses; am einfachsten geht das mit dem Datei-Explorer auf der linken Seite des Trainingsarbeitsbereichs in der VSCode-Oberfläche. +Alternativ kannst du den Befehl `tree` verwenden. +Während des Kurses verwenden wir die Ausgabe von `tree`, um die Verzeichnisstruktur und den Inhalt in lesbarer Form darzustellen, manchmal mit geringfügigen Änderungen zur besseren Lesbarkeit. + +Hier erstellen wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 3 +``` + +??? success "Verzeichnisinhalt" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note "Hinweis" + + Keine Sorge, wenn das viel erscheint; wir gehen die relevanten Teile bei jedem Schritt des Kurses durch. + Dies soll dir nur einen Überblick verschaffen. + +**Hier ist eine Zusammenfassung dessen, was du zum Einstieg wissen solltest:** + +- **Die Datei `rnaseq.nf`** ist die Grundstruktur des Workflow-Scripts, das wir entwickeln werden. + +- **Die Datei `nextflow.config`** ist eine Konfigurationsdatei, die minimale Umgebungseigenschaften festlegt. Du kannst sie vorerst ignorieren. + +- **Das Verzeichnis `data`** enthält Eingabedaten und zugehörige Ressourcen: + + - _Ein Referenzgenom_ namens `genome.fa`, das aus einer kleinen Region des menschlichen Chromosoms 20 besteht (aus hg19/b37). + - _RNAseq-Daten_, die auf eine kleine Region reduziert wurden, um die Dateigrößen klein zu halten, im Verzeichnis `reads/`. + - _CSV-Dateien_, die die IDs und Pfade der Beispieldatendateien auflisten, zur Stapelverarbeitung. + +- **Das Verzeichnis `solutions`** enthält die fertigen Workflow-Scripts und Module, die aus jedem Schritt des Kurses resultieren. + Sie sind als Referenz gedacht, um deine Arbeit zu überprüfen und eventuelle Probleme zu beheben. + Die Nummer im Dateinamen entspricht dem Schritt des relevanten Kursteils. + +!!!tip "Tipp" + + Falls du aus irgendeinem Grund dieses Verzeichnis verlässt, kannst du jederzeit diesen Befehl ausführen, um dorthin zurückzukehren: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Um nun mit dem Kurs zu beginnen, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite. diff --git a/docs/de/docs/nf4_science/rnaseq/01_method.md b/docs/de/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..8664f7e4dc --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Teil 1: Methodenübersicht und manuelles Testen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Es gibt mehrere gültige Methoden zur Verarbeitung und Analyse von Bulk-RNAseq-Daten. +Für diesen Kurs folgen wir der Methode, die [hier](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) von Dr. Simon Andrews und Dr. Laura Biggins am [Babraham Institute](https://www.babraham.ac.uk/) beschrieben wird. + +Unser Ziel ist es, einen Workflow zu entwickeln, der die folgenden Verarbeitungsschritte implementiert: initiale Qualitätskontrolle der Reads in einer Bulk-RNAseq-Probe durchführen, Adaptersequenzen aus den Reads trimmen, die Reads auf ein Referenzgenom alignieren und einen umfassenden Qualitätskontroll-Bericht (QC) erstellen. + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** QC der Read-Daten vor dem Trimmen mit FastQC durchführen +- **TRIM_GALORE:** Adaptersequenzen trimmen und QC nach dem Trimmen mit Trim Galore durchführen (bündelt Cutadapt und FastQC) +- **HISAT2_ALIGN:** Reads mit Hisat2 auf das Referenzgenom alignieren +- **MULTIQC:** Einen umfassenden QC-Bericht mit MultiQC generieren + +Bevor wir jedoch mit dem Schreiben von Workflow-Code beginnen, werden wir die Befehle manuell an einigen Testdaten ausprobieren. +Die benötigten Tools sind in der GitHub Codespaces-Umgebung nicht installiert, daher werden wir sie über Container verwenden (siehe [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Hinweis" + + Stelle sicher, dass du dich im Verzeichnis `nf4-science/rnaseq` befindest. Der letzte Teil des Pfads, der angezeigt wird, wenn du `pwd` eingibst, sollte `rnaseq` sein. + +--- + +## 1. Initiale QC und Adapter-Trimming + +Wir werden ein Container-Image herunterladen, das sowohl `fastqc` als auch `trim_galore` installiert hat, es interaktiv starten und die Trimming- und QC-Befehle auf einer der Beispieldateien ausführen. + +### 1.1. Container herunterladen + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Dies gibt dir die folgende Konsolenausgabe, während das System das Image herunterlädt: + +??? success "Befehlsausgabe" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Container interaktiv starten + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Befehlsausgabe" + + ```console + + ``` +--> + +Dein Prompt ändert sich zu etwas wie `(base) root@b645838b3314:/tmp#`, was anzeigt, dass du dich jetzt innerhalb des Containers befindest. + +Der Teil `-v ./data:/data` des Befehls ermöglicht es uns, auf den Inhalt des Verzeichnisses `data/` von innerhalb des Containers zuzugreifen. + +```bash +ls /data/reads +``` + +??? success "Befehlsausgabe" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Ersten `fastqc`-Befehl ausführen + +Lass uns `fastqc` ausführen, um Qualitätskontroll-Metriken der Read-Daten zu sammeln. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Befehlsausgabe" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Dies sollte sehr schnell ablaufen. +Du findest die Ausgabedateien im selben Verzeichnis wie die ursprünglichen Daten: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Ausgabe" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Adaptersequenzen mit `trim_galore` trimmen + +Jetzt führen wir `trim_galore` aus, das Cutadapt und FastQC bündelt, um die Adaptersequenzen zu trimmen und Post-Trimming-QC-Metriken zu sammeln. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +Das Flag `--fastqc` bewirkt, dass der Befehl automatisch einen QC-Sammelschritt ausführt, nachdem das Trimmen abgeschlossen ist. + +_Die Ausgabe ist sehr ausführlich, daher ist das Folgende gekürzt._ + +??? success "Befehlsausgabe" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Du findest die Ausgabedateien im Arbeitsverzeichnis: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Ausgabe" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Ausgabedateien in das Dateisystem außerhalb des Containers verschieben + +Alles, was im Container verbleibt, wird für zukünftige Arbeiten nicht zugänglich sein, also verschieben wir diese in ein neues Verzeichnis. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Container beenden + +```bash +exit +``` + +--- + +## 2. Reads auf das Referenzgenom alignieren + +Wir werden ein Container-Image herunterladen, das `hisat2` installiert hat, es interaktiv starten und den Alignment-Befehl ausführen, um die RNAseq-Daten auf ein Referenzgenom zu alignieren. + +### 2.1. `hisat2`-Container herunterladen + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Befehlsausgabe" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. `hisat2`-Container interaktiv starten + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +Der Befehl ist derselbe wie zuvor, mit der entsprechenden Container-URI ausgetauscht. + +### 2.3. Hisat2-Genom-Indexdateien erstellen + +Hisat2 benötigt die Genomreferenz in einem sehr spezifischen Format und kann nicht einfach die Datei `genome.fa` im FASTA-Format verarbeiten, die wir bereitstellen. Daher nutzen wir diese Gelegenheit, um die entsprechenden Ressourcen zu erstellen. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +Die Ausgabe ist sehr ausführlich, daher ist das Folgende gekürzt: + +<!-- TODO: switch to full output --> + +??? success "Befehlsausgabe" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Dies erstellt mehrere Genom-Indexdateien, die du im Arbeitsverzeichnis finden kannst. + +```bash +ls genome_index.* +``` + +```console title="Ausgabe" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Wir werden diese gleich verwenden, aber zuerst erstellen wir einen gzippten Tarball mit diesen Genom-Indexdateien; wir werden sie später benötigen und das Generieren dieser Dateien ist normalerweise nichts, was wir als Teil eines Workflows tun möchten. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Dies speichert einen Tarball `genome_index.tar.gz`, der die Genom-Indexdateien enthält, im Verzeichnis `data/` auf unserem Dateisystem, was in Teil 2 dieses Kurses nützlich sein wird. + +### 2.4. `hisat2`-Befehl ausführen + +Jetzt können wir den Alignment-Befehl ausführen, der den Alignment-Schritt mit `hisat2` durchführt und dann die Ausgabe an `samtools` weiterleitet, um die Ausgabe als BAM-Datei zu schreiben. + +Die Read-Dateneingabe ist die Datei `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz`, die wir im vorherigen Schritt mit `trim_galore` generiert haben. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Befehlsausgabe" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Dies läuft fast sofort ab, weil es sich um eine sehr kleine Testdatei handelt. +In der Realität könnte dies bei entsprechender Größe viel länger dauern. + +Wieder kannst du die Ausgabedateien im Arbeitsverzeichnis finden: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Ausgabe" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Ausgabedateien in das Dateisystem außerhalb des Containers verschieben + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Container beenden + +```bash +exit +``` + +--- + +## 3. Umfassenden QC-Bericht generieren + +Wir werden ein Container-Image herunterladen, das `multiqc` installiert hat, es interaktiv starten und einen Berichtsgenerierungsbefehl auf den Vorher/Nachher-FastQC-Berichtsdateien ausführen. + +### 3.1. `multiqc`-Container herunterladen + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Befehlsausgabe" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. `multiqc`-Container interaktiv starten + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. `multiqc`-Befehl ausführen + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Befehlsausgabe" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC kann Verzeichnisse nach kompatiblen QC-Berichten durchsuchen und aggregiert alles, was es findet. + +Hier sehen wir, dass das Tool alle drei QC-Berichte gefunden hat, die wir generiert haben: die initiale QC, die wir mit `fastqc` durchgeführt haben, den Post-Trimming-Bericht von `cutadapt` (erstellt über `trim_galore`) und die Post-Alignment-QC, die von `hisat2` produziert wurde. + +Die Ausgabedateien befinden sich wieder im Arbeitsverzeichnis: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Ausgabe" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Ausgabedateien in das Dateisystem außerhalb des Containers verschieben + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Container beenden + +```bash +exit +``` + +--- + +### Zusammenfassung + +Du hast alle einzelnen Befehle interaktiv in den entsprechenden Containern getestet. + +### Wie geht es weiter? + +Lerne, wie du dieselben Befehle in einen mehrstufigen Workflow verpackst, der Container zur Ausführung der Arbeit verwendet. diff --git a/docs/de/docs/nf4_science/rnaseq/02_single-sample.md b/docs/de/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..725988c9ea --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Teil 2: Implementierung für eine einzelne Probe + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem Teil des Kurses werden wir den einfachstmöglichen Workflow schreiben, der alle Befehle aus Teil 1 zusammenfasst, um ihre Ausführung zu automatisieren. Dabei werden wir zunächst nur eine Probe gleichzeitig verarbeiten. + +Wir werden dies in drei Schritten tun: + +1. Einen einstufigen Workflow schreiben, der den ersten QC-Schritt ausführt +2. Adapter-Trimming und Post-Trimming-QC hinzufügen +3. Alignment zum Referenzgenom hinzufügen + +!!! warning "Voraussetzung" + + Du musst Teil 1 des Kurses durcharbeiten, bevor du mit dieser Lektion beginnst. + Insbesondere durch das Durcharbeiten der Abschnitte 2.1-3 wird die Genom-Indexdatei (`data/genome_index.tar.gz`) erstellt, die für den Alignment-Schritt in dieser Lektion benötigt wird. + +--- + +## 1. Einen einstufigen Workflow schreiben, der die erste QC ausführt + +Beginnen wir damit, einen einfachen Workflow zu schreiben, der das FastQC-Tool auf eine FASTQ-Datei mit Single-End-RNAseq-Reads anwendet. + +Wir stellen dir eine Workflow-Datei, `rnaseq.nf`, zur Verfügung, die die Hauptteile des Workflows skizziert. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Modul-INCLUDE-Anweisungen + +/* + * Pipeline parameters + */ + +// Primäre Eingabe + +workflow { + + // Eingabe-Channel erstellen + + // Prozesse aufrufen + +} +``` + +Beachte, dass dieser Workflow-Code zwar korrekt, aber noch nicht funktionsfähig ist; sein Zweck ist es lediglich, als Gerüst zu dienen, das du zum Schreiben des eigentlichen Workflows verwenden wirst. + +### 1.1. Ein Verzeichnis zum Speichern von Modulen erstellen + +Wir werden eigenständige Module für jeden Prozess erstellen, um sie einfacher verwalten und wiederverwenden zu können. Erstellen wir also ein Verzeichnis zum Speichern. + +```bash +mkdir modules +``` + +### 1.2. Ein Modul für den Prozess zur Erfassung von QC-Metriken erstellen + +Erstellen wir eine Moduldatei namens `modules/fastqc.nf`, um den `FASTQC`-Prozess unterzubringen: + +```bash +touch modules/fastqc.nf +``` + +Öffne die Datei im Code-Editor und kopiere den folgenden Code hinein: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Du solltest alle Teile aus dem wiedererkennen, was du in Teil 1 & Teil 2 dieser Trainingsreihe gelernt hast; die einzige nennenswerte Änderung ist, dass wir diesmal `mode: symlink` für die `publishDir`-Direktive verwenden und einen Parameter zur Definition von `publishDir` verwenden. + +!!! note "Hinweis" + + Obwohl die Datendateien, die wir hier verwenden, sehr klein sind, können sie in der Genomik sehr groß werden. Zu Demonstrationszwecken in der Trainingsumgebung verwenden wir den 'symlink'-Veröffentlichungsmodus, um unnötige Dateikopien zu vermeiden. Du solltest dies in deinen finalen Workflows nicht tun, da du Ergebnisse verlierst, wenn du dein `work`-Verzeichnis aufräumst. + +### 1.3. Das Modul in die Workflow-Datei importieren + +Füge die Anweisung `include { FASTQC } from './modules/fastqc.nf'` zur Datei `rnaseq.nf` hinzu: + +```groovy title="rnaseq.nf" linenums="3" +// Modul-INCLUDE-Anweisungen +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Eine Eingabedeklaration hinzufügen + +Deklariere einen Eingabeparameter mit einem Standardwert: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Primäre Eingabe + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Einen Eingabekanal im Workflow-Block erstellen + +Verwende eine einfache `.fromPath()`-Channel-Factory, um den Eingabekanal zu erstellen: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Eingabe-Channel aus einem Dateipfad erstellen + read_ch = channel.fromPath(params.reads) + + // Prozesse aufrufen + +} +``` + +### 1.6. Den `FASTQC`-Prozess auf dem Eingabekanal aufrufen + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Eingabe-Channel aus einem Dateipfad erstellen + read_ch = channel.fromPath(params.reads) + + // Initiale Qualitätskontrolle + FASTQC(read_ch) + +} +``` + +### 1.7. Den Workflow ausführen, um zu testen, ob er funktioniert + +Wir könnten den `--reads`-Parameter verwenden, um eine Eingabe von der Befehlszeile aus anzugeben, aber während der Entwicklung können wir faul sein und einfach den eingerichteten Teststandard verwenden. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Dies sollte sehr schnell ausgeführt werden, wenn du Teil 1 durchgearbeitet hast und den Container bereits heruntergeladen hast. +Wenn du ihn übersprungen hast, wird Nextflow den Container für dich herunterladen; du musst nichts dafür tun, aber du musst möglicherweise bis zu einer Minute warten. + +Du findest die Ausgaben unter `results/fastqc`, wie im `FASTQC`-Prozess durch die `publishDir`-Direktive angegeben. + +```bash +ls results/fastqc +``` + +```console title="Output" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Adapter-Trimming und Post-Trimming-Qualitätskontrolle hinzufügen + +Wir werden den Trim_Galore-Wrapper verwenden, der Cutadapt für das Trimming selbst und FastQC für die Post-Trimming-Qualitätskontrolle bündelt. + +### 2.1. Ein Modul für den Trimming- und QC-Prozess erstellen + +Erstellen wir eine Moduldatei namens `modules/trim_galore.nf`, um den `TRIM_GALORE`-Prozess unterzubringen: + +```bash +touch modules/trim_galore.nf +``` + +Öffne die Datei im Code-Editor und kopiere den folgenden Code hinein: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Das Modul in die Workflow-Datei importieren + +Füge die Anweisung `include { TRIM_GALORE } from './modules/trim_galore.nf'` zur Datei `rnaseq.nf` hinzu: + +```groovy title="rnaseq.nf" linenums="3" +// Modul-INCLUDE-Anweisungen +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Den Prozess auf dem Eingabekanal aufrufen + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Eingabe-Channel aus einem Dateipfad erstellen + read_ch = channel.fromPath(params.reads) + + // Initiale Qualitätskontrolle + FASTQC(read_ch) + + // Adapter-Trimming und Post-Trimming-QC + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Den Workflow ausführen, um zu testen, ob er funktioniert + +```bash +nextflow run rnaseq.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Dies sollte ebenfalls sehr schnell ausgeführt werden, da wir mit einer so kleinen Eingabedatei arbeiten. + +Du findest die Ausgaben unter `results/trimming`, wie im `TRIM_GALORE`-Prozess durch die `publishDir`-Direktive angegeben. + +```bash +ls results/trimming +``` + +```console title="Output" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Die Reads zum Referenzgenom alignieren + +Schließlich können wir den Genom-Alignment-Schritt mit Hisat2 ausführen, der auch FastQC-ähnliche Qualitätskontrollmetriken ausgibt. + +### 3.1. Ein Modul für den HiSat2-Prozess erstellen + +Erstellen wir eine Moduldatei namens `modules/hisat2_align.nf`, um den `HISAT2_ALIGN`-Prozess unterzubringen: + +```bash +touch modules/hisat2_align.nf +``` + +Öffne die Datei im Code-Editor und kopiere den folgenden Code hinein: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Das Modul in die Workflow-Datei importieren + +Füge die Anweisung `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` zur Datei `rnaseq.nf` hinzu: + +```groovy title="rnaseq.nf" linenums="3" +// Modul-INCLUDE-Anweisungen +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Eine Parameterdeklaration hinzufügen, um den Genomindex bereitzustellen + +Deklariere einen Eingabeparameter mit einem Standardwert: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Primäre Eingabe + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Referenzgenom-Archiv + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Den `HISAT2_ALIGN`-Prozess auf den getrimmten Reads aufrufen, die von `TRIM_GALORE` ausgegeben wurden + +Die getrimmten Reads befinden sich im `TRIM_GALORE.out.trimmed_reads`-Channel, der vom vorherigen Schritt ausgegeben wurde. + +Zusätzlich verwenden wir `file (params.hisat2_index_zip)`, um dem Hisat2-Tool das gezippte Genom-Index-Tarball bereitzustellen. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Eingabe-Channel aus einem Dateipfad erstellen + read_ch = channel.fromPath(params.reads) + + // Initiale Qualitätskontrolle + FASTQC(read_ch) + + // Adapter-Trimming und Post-Trimming-QC + TRIM_GALORE(read_ch) + + // Alignment zum Referenzgenom + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Den Workflow ausführen, um zu testen, ob er funktioniert + +```bash +nextflow run rnaseq.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Du findest die Ausgaben unter `results/align`, wie im `HISAT2_ALIGN`-Prozess durch die `publishDir`-Direktive angegeben. + +```bash +ls results/align +``` + +```console title="Output" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Dies vervollständigt die grundlegende Verarbeitung, die wir auf jede Probe anwenden müssen. + +_Wir werden die MultiQC-Report-Aggregation in Teil 2 hinzufügen, nachdem wir den Workflow so angepasst haben, dass er mehrere Proben gleichzeitig akzeptiert._ + +--- + +### Zusammenfassung + +Du weißt jetzt, wie du alle Kernschritte zur individuellen Verarbeitung von Single-End-RNAseq-Proben zusammenfasst. + +### Wie geht es weiter? + +Lerne, wie du den Workflow anpasst, um mehrere Proben parallel zu verarbeiten, QC-Reports über alle Schritte für alle Proben zu aggregieren und die Ausführung des Workflows mit Paired-End-RNAseq-Daten zu ermöglichen. diff --git a/docs/de/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/de/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..fcba8e9479 --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Teil 3: Implementierung für mehrere Proben mit Paired-End-Daten + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In diesem letzten Teil des Kurses werden wir unseren einfachen Workflow auf die nächste Stufe heben, indem wir ihn in ein leistungsstarkes Batch-Automatisierungswerkzeug verwandeln, das eine beliebige Anzahl von Proben verarbeiten kann. +Und dabei werden wir ihn auch auf Paired-End-Daten umstellen, die in neueren Studien häufiger vorkommen. + +Wir werden dies in drei Schritten tun: + +1. Den Workflow so anpassen, dass er mehrere Eingabeproben akzeptiert und die Ausführung parallelisiert +2. Umfassende QC-Berichtsgenerierung hinzufügen +3. Auf Paired-End-RNAseq-Daten umstellen + +--- + +## 1. Den Workflow so anpassen, dass er mehrere Eingabeproben akzeptiert und die Ausführung parallelisiert + +Wir müssen ändern, wie wir die Eingabe verwalten. + +### 1.1. Die primäre Eingabe auf eine CSV-Datei mit Dateipfaden anstelle einer einzelnen Datei ändern + +Wir stellen eine CSV-Datei zur Verfügung, die Proben-IDs und FASTQ-Dateipfade im Verzeichnis `data/` enthält. +Diese CSV-Datei enthält eine Kopfzeile. +Beachte, dass die FASTQ-Dateipfade absolute Pfade sind. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Lass uns den primären Eingabeparameter in `input_csv` umbenennen und den Standardwert auf den Pfad zur Datei `single-end.csv` ändern. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Primäre Eingabe + input_csv: Path = "data/single-end.csv" + + // Referenzgenom-Archiv + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Die Eingabe-Channel-Factory aktualisieren, um eine CSV-Datei als Eingabe zu verarbeiten + +Wir möchten den Inhalt der Datei in den Channel laden anstatt nur des Dateipfads selbst, also verwenden wir den Operator `.splitCsv()`, um das CSV-Format zu parsen, dann den Operator `.map()`, um die spezifische Information zu extrahieren, die wir möchten (den FASTQ-Dateipfad). + +```groovy title="rnaseq.nf" linenums="16" + // Channel aus dem Inhalt einer CSV-Datei erstellen + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Den Workflow ausführen, um zu testen, ob er funktioniert + +```bash +nextflow run rnaseq.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Diesmal sehen wir, dass jeder Schritt 6 Mal ausgeführt wird, für jede der 6 Datendateien, die wir bereitgestellt haben. + +Das war alles, was nötig war, um den Workflow auf mehreren Dateien laufen zu lassen! +Nextflow kümmert sich um die gesamte Parallelisierung für uns. + +--- + +## 2. Vor-Verarbeitungs-QC-Metriken in einem einzelnen MultiQC-Bericht aggregieren + +All dies erzeugt viele QC-Berichte, und wir möchten nicht durch einzelne Berichte graben müssen. +Dies ist der perfekte Punkt, um einen MultiQC-Berichtsaggregationsschritt einzufügen! + +### 2.1. Ein Modul für den QC-Aggregationsprozess erstellen + +Lass uns eine Moduldatei namens `modules/multiqc.nf` erstellen, um den Prozess `MULTIQC` zu beherbergen: + +```bash +touch modules/multiqc.nf +``` + +Öffne die Datei im Code-Editor und kopiere den folgenden Code hinein: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Das Modul in die Workflow-Datei importieren + +Füge die Anweisung `include { MULTIQC } from './modules/multiqc.nf'` zur Datei `rnaseq.nf` hinzu: + +```groovy title="rnaseq.nf" linenums="3" +// Modul-INCLUDE-Anweisungen +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Einen Parameter `report_id` hinzufügen und ihm einen sinnvollen Standardwert geben + +```groovy title="rnaseq.nf" linenums="9" +params { + // Primäre Eingabe + input_csv: Path = "data/single-end.csv" + + // Referenzgenom-Archiv + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Bericht-ID + report_id: String = "all_single-end" +} +``` + +### 2.4. Den Prozess mit den Ausgaben der vorherigen Schritte aufrufen + +Wir müssen dem Prozess `MULTIQC` alle QC-bezogenen Ausgaben aus den vorherigen Schritten geben. + +Dafür werden wir den Operator `.mix()` verwenden, der mehrere Channels in einen einzigen aggregiert. + +Wenn wir vier Prozesse namens A, B, C und D mit jeweils einem einfachen Channel `.out` hätten, würde die Syntax so aussehen: `A.out.mix( B.out, C.out, D.out )`. Wie du siehst, wendest du ihn auf den ersten der Channels an, die du kombinieren möchtest (egal welchen), und fügst einfach alle anderen, durch Kommas getrennt, in den Klammern hinzu, die folgen. + +Im Fall unseres Workflows haben wir folgende Ausgaben zu aggregieren: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Das Syntaxbeispiel wird also zu: + +```groovy title=".mix() im MULTIQC-Aufruf anwenden" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Das sammelt QC-Berichte pro Probe. +Da wir sie aber über alle Proben hinweg aggregieren möchten, müssen wir den Operator `collect()` hinzufügen, um die Berichte für alle Proben in einen einzigen Aufruf von `MULTIQC` zu ziehen. +Und wir müssen ihm auch den Parameter `report_id` geben. + +Das ergibt Folgendes: + +```groovy title="Der vollständige MULTIQC-Aufruf" linenums="33" + // Umfassende QC-Berichtsgenerierung + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Im Kontext des vollständigen Workflow-Blocks sieht es am Ende so aus: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Channel aus dem Inhalt einer CSV-Datei erstellen + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// Anfängliche Qualitätskontrolle + FASTQC(read_ch) + + // Adapter-Trimming und Post-Trimming-QC + TRIM_GALORE(read_ch) + + // Alignment zu einem Referenzgenom + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Umfassende QC-Berichtsgenerierung + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Den Workflow ausführen, um zu testen, ob er funktioniert + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Diesmal sehen wir einen einzelnen Aufruf von MULTIQC, der nach den gecachten Prozessaufrufen hinzugefügt wurde: + +Du findest die Ausgaben unter `results/trimming`, wie im Prozess `TRIM_GALORE` durch die Direktive `publishDir` angegeben. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Ausgabe" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Die letzte Datei `all_single-end.html` ist der vollständige aggregierte Bericht, praktisch in eine einfach zu durchsuchende HTML-Datei verpackt. + +--- + +## 3. Verarbeitung von Paired-End-RNAseq-Daten ermöglichen + +Momentan kann unser Workflow nur Single-End-RNAseq-Daten verarbeiten. +Es wird zunehmend üblich, Paired-End-RNAseq-Daten zu sehen, also möchten wir in der Lage sein, diese zu verarbeiten. + +Den Workflow völlig unabhängig vom Datentyp zu machen, würde etwas fortgeschrittenere Nextflow-Sprachfeatures erfordern, also werden wir das hier nicht tun, aber wir können eine Paired-End-Verarbeitungsversion erstellen, um zu demonstrieren, was angepasst werden muss. + +### 3.1. Eine Kopie des Workflows namens `rnaseq_pe.nf` erstellen + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Den Standard-`input_csv` ändern, um auf die Paired-End-Daten zu zeigen + +Wir stellen eine zweite CSV-Datei zur Verfügung, die Proben-IDs und gepaarte FASTQ-Dateipfade im Verzeichnis `data/` enthält + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Lass uns den Standardwert von `input_csv` auf den Pfad zur Datei `paired-end.csv` ändern. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Primäre Eingabe + input_csv: Path = "data/paired-end.csv" + + // Referenzgenom-Archiv + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Bericht-ID + report_id: String = "all_single-end" +} +``` + +### 3.3. Die Channel-Factory aktualisieren + +Wir müssen dem Operator `.map()` sagen, dass er jetzt beide FASTQ-Dateipfade greifen soll. + +Also wird `row -> file(row.fastq_path)` zu `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Channel aus dem Inhalt einer CSV-Datei erstellen + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Eine Paired-End-Version des FASTQC-Prozesses erstellen + +Lass uns eine Kopie des Moduls erstellen, damit wir beide Versionen zur Hand haben. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Öffne die neue Moduldatei `fastqc_pe.nf` im Code-Editor und nimm folgende Code-Änderungen vor: + +- Ändere `fastqc $reads` zu `fastqc ${reads}` im `script`-Block (Zeile 17), damit die Eingabe `reads` entpackt wird, da es jetzt ein Tupel aus zwei Pfaden statt eines einzelnen Pfads ist. +- Ersetze `${reads.simpleName}` durch einen Platzhalter (`*`), um zu vermeiden, dass die Ausgabedateien einzeln behandelt werden müssen. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Technisch gesehen verallgemeinert dies den Prozess `FASTQC` auf eine Weise, die ihn in die Lage versetzt, entweder Single-End- oder Paired-End-RNAseq-Daten zu verarbeiten. + +Aktualisiere abschließend die Modul-Import-Anweisung, um die Paired-End-Version des Moduls zu verwenden. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Eine Paired-End-Version des TRIM_GALORE-Prozesses erstellen + +Erstelle eine Kopie des Moduls, damit wir beide Versionen zur Hand haben. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Öffne die neue Moduldatei `trim_galore_pe.nf` im Code-Editor und nimm folgende Code-Änderungen vor: + +- Ändere die Eingabedeklaration von `path reads` zu `tuple path(read1), path(read2)` +- Aktualisiere den Befehl im `script`-Block, ersetze `$reads` durch `--paired ${read1} ${read2}` +- Aktualisiere die Ausgabedeklarationen, um die hinzugefügten Dateien und verschiedenen Benennungskonventionen zu berücksichtigen, verwende Platzhalter, um zu vermeiden, dass alles aufgelistet werden muss. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Aktualisiere abschließend die Modul-Import-Anweisung, um die Paired-End-Version des Moduls zu verwenden. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Den Aufruf des MULTIQC-Prozesses aktualisieren, um zwei Berichte von TRIM_GALORE zu erwarten + +Der Prozess `TRIM_GALORE` erzeugt jetzt einen zusätzlichen Ausgabe-Channel, also müssen wir diesen an MultiQC weiterleiten. + +Ersetze `TRIM_GALORE.out.fastqc_reports,` durch `TRIM_GALORE.out.fastqc_reports_1,` plus `TRIM_GALORE.out.fastqc_reports_2,`: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Umfassende QC-Berichtsgenerierung + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Während wir bei MultiQC sind, lass uns auch den Standardwert des Parameters `report_id` von `"all_single-end"` zu `"all_paired-end"` aktualisieren. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Primäre Eingabe + input_csv: Path = "data/paired-end.csv" + + // Referenzgenom-Archiv + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Bericht-ID + report_id: String = "all_paired-end" +} +``` + +### 3.7. Eine Paired-End-Version des HISAT2_ALIGN-Prozesses erstellen + +Erstelle eine Kopie des Moduls, damit wir beide Versionen zur Hand haben. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Öffne die neue Moduldatei `hisat2_align_pe.nf` im Code-Editor und nimm folgende Code-Änderungen vor: + +- Ändere die Eingabedeklaration von `path reads` zu `tuple path(read1), path(read2)` +- Aktualisiere den Befehl im `script`-Block, ersetze `-U $reads` durch `-1 ${read1} -2 ${read2}` +- Ersetze alle Instanzen von `${reads.simpleName}` durch `${read1.simpleName}` im Befehl im `script`-Block sowie in den Ausgabedeklarationen. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Aktualisiere abschließend die Modul-Import-Anweisung, um die Paired-End-Version des Moduls zu verwenden. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Den Workflow ausführen, um zu testen, ob er funktioniert + +Wir verwenden nicht `-resume`, da dies nicht cachen würde, und es gibt doppelt so viele Daten zu verarbeiten wie zuvor, aber es sollte trotzdem in weniger als einer Minute abgeschlossen sein. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +Und das war's! Jetzt haben wir zwei leicht divergierende Versionen unseres Workflows, eine für Single-End-Read-Daten und eine für Paired-End-Daten. +Der nächste logische Schritt wäre, den Workflow so zu gestalten, dass er beide Datentypen spontan akzeptiert, was außerhalb des Umfangs dieses Kurses liegt, aber wir könnten das in einem Folgekurs angehen. + +--- + +### Zusammenfassung + +Du weißt jetzt, wie du einen Einzelproben-Workflow anpasst, um die Verarbeitung mehrerer Proben zu parallelisieren, einen umfassenden QC-Bericht zu generieren und den Workflow bei Bedarf für Paired-End-Read-Daten anzupassen. + +### Wie geht es weiter? + +Herzlichen Glückwunsch, du hast den Nextflow For RNAseq Mini-Kurs abgeschlossen! Feiere deinen Erfolg und nimm dir eine wohlverdiente Pause! + +Als Nächstes bitten wir dich, eine sehr kurze Umfrage über deine Erfahrungen mit diesem Trainingskurs auszufüllen, dann führen wir dich zu einer Seite mit Links zu weiteren Trainingsressourcen und hilfreichen Links. diff --git a/docs/de/docs/nf4_science/rnaseq/index.md b/docs/de/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..6c984ed9f0 --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: Nextflow für RNAseq +hide: + - toc +--- + +# Nextflow für RNAseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dieser Trainingskurs richtet sich an Forscher im Bereich Transkriptomik und verwandter Fachgebiete, die daran interessiert sind, Datenanalyse-Pipelines zu entwickeln oder anzupassen. +Er baut auf dem [Hello Nextflow](../../hello_nextflow/) Einsteiger-Training auf und demonstriert, wie man Nextflow im spezifischen Kontext der Bulk-RNAseq-Analyse einsetzt. + +Konkret zeigt dieser Kurs, wie man eine einfache Bulk-RNAseq-Verarbeitungs-Pipeline implementiert, um Adaptersequenzen zu trimmen, die Reads an eine Genomreferenz zu alignieren und Qualitätskontrollen (QC) in mehreren Schritten durchzuführen. + +Lass uns anfangen! Klicke auf den Button "Open in GitHub Codespaces" unten, um die Trainingsumgebung zu starten (vorzugsweise in einem separaten Tab), und lies dann weiter, während sie lädt. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Lernziele + +Durch die Bearbeitung dieses Kurses lernst du, wie man grundlegende Nextflow-Konzepte und Tools auf einen typischen RNAseq-Anwendungsfall anwendet. + +Am Ende dieses Workshops kannst du: + +- Einen linearen Workflow zu schreiben, um grundlegende RNAseq-Verarbeitungs- und QC-Methoden anzuwenden +- Domänenspezifische Dateien wie FASTQ und Genomreferenzen angemessen zu handhaben +- Single-End- und Paired-End-Sequenzierungsdaten zu verarbeiten +- Nextflows Dataflow-Paradigma zu nutzen, um die RNAseq-Verarbeitung pro Probe zu parallelisieren +- QC-Reports über mehrere Schritte und Proben hinweg mit relevanten Channel-Operatoren zu aggregieren + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Voraussetzungen + +Der Kurs setzt eine minimale Vertrautheit mit Folgendem voraus: + +- Tools und Dateiformate, die in diesem wissenschaftlichen Bereich häufig verwendet werden +- Erfahrung mit der Kommandozeile +- Grundlegende Nextflow-Konzepte und Tools, die im [Hello Nextflow](../../hello_nextflow/) Einsteiger-Training behandelt werden. + +Für technische Anforderungen und Umgebungseinrichtung siehe den Mini-Kurs [Environment Setup](../../envsetup/). diff --git a/docs/de/docs/nf4_science/rnaseq/next_steps.md b/docs/de/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..ad2c1e1662 --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Nächste Schritte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nochmals herzlichen Glückwunsch zum Abschluss des Nextflow For RNAseq Trainingskurses und vielen Dank für das Ausfüllen unserer Umfrage! + +--- + +## 1. Die 3 besten Wege, deine Nextflow-Fähigkeiten zu verbessern + +Hier sind unsere drei wichtigsten Empfehlungen, was du als Nächstes tun kannst, basierend auf dem Kurs, den du gerade abgeschlossen hast. + +### 1.1. Nextflow auf andere wissenschaftliche Anwendungsfälle anwenden + +**Schau dir die Seite [Nextflow for Science](../nf4_science/index.md) an** für eine Liste weiterer kurzer eigenständiger Kurse, die zeigen, wie du die grundlegenden Konzepte und Mechanismen aus Hello Nextflow auf gängige wissenschaftliche Anwendungsfälle anwenden kannst. + +Wenn du dein Fachgebiet nicht durch einen passenden Anwendungsfall vertreten siehst, lass es uns im [Community-Forum](https://community.seqera.io/) wissen, damit wir es auf unsere Entwicklungsliste setzen können. + +### 1.2. Mit nf-core starten + +**[nf-core](https://nf-co.re/)** ist eine weltweite gemeinschaftliche Initiative zur Entwicklung standardisierter Open-Source-Pipelines für eine Vielzahl wissenschaftlicher Forschungsanwendungen. +Das Projekt umfasst [über 100 Pipelines](https://nf-co.re/pipelines/), die sofort einsatzbereit sind, und [weit über 1400 Process-Module](https://nf-co.re/modules/), die in deine eigenen Projekte integriert werden können, sowie ein umfangreiches Set an Entwicklertools. + +Der Trainingskurs **[Hello nf-core](../../hello_nf-core/index.md)** führt dich in die von der Community kuratierten Pipelines und das Entwicklungs-Framework von nf-core ein, die entwickelt wurden, um dir beim Schreiben reproduzierbarer, skalierbarer und standardisierter Workflows zu helfen. Du lernst, wie du bestehende nf-core-Pipelines verwendest, zu ihrer Entwicklung beiträgst und sogar mit dem Aufbau eigener Pipelines beginnst – unterstützt durch Best Practices und eine lebendige Community. Wenn du bereit bist, deine Nextflow-Kenntnisse in realen Projekten anzuwenden, ist dies der perfekte nächste Schritt. + +### 1.3. Fortgeschrittene Nextflow-Features meistern + +In den Hello-Kursen halten wir die technische Komplexität absichtlich niedrig, um dich nicht mit Informationen zu überlasten, die du nicht benötigst, um mit Nextflow zu starten. +Wenn du mit deiner Arbeit voranschreitest, wirst du lernen wollen, wie du den vollen Funktionsumfang und die Leistungsfähigkeit von Nextflow nutzt. + +Zu diesem Zweck arbeiten wir derzeit an einer **Sammlung von [Side Quests](../side_quests/index.md)**, die als kurze eigenständige Kurse konzipiert sind, die tief in spezifische Themen wie Testing und Metadaten-Handling eintauchen. + +--- + +## 2. Schau dir Seqera Platform an + +**[Seqera Platform](https://seqera.io/) ist der beste Weg, Nextflow in der Praxis auszuführen.** + +Es ist eine cloudbasierte Plattform, die von den Entwicklern von Nextflow entwickelt wurde und die du mit deiner eigenen Recheninfrastruktur (ob lokal, HPC oder Cloud) verbinden kannst, um das Starten und Verwalten deiner Workflows erheblich zu erleichtern sowie deine Daten zu verwalten und Analysen interaktiv in einer Cloud-Umgebung durchzuführen. + +Das Free Tier ist für jeden kostenlos nutzbar (mit Nutzungskontingenten). +Qualifizierte Akademiker können kostenlosen Zugang auf Pro-Level (ohne Nutzungsbeschränkungen) über das [Academic Program](https://seqera.io/academic/program/) erhalten. + +Wirf einen Blick auf die [Seqera Platform Tutorials](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase), um zu sehen, ob dies für dich nützlich sein könnte. + +--- + +### Das war's für jetzt! + +**Viel Erfolg mit Nextflow! Zögere nicht, uns im [Community-Forum](https://community.seqera.io/) mitzuteilen, was wir sonst noch tun könnten.** diff --git a/docs/de/docs/nf4_science/rnaseq/survey.md b/docs/de/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..b71f598ce8 --- /dev/null +++ b/docs/de/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Feedback-Umfrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bevor du weitermachst, fülle bitte diese kurze Umfrage mit 5 Fragen aus, um das Training zu bewerten und uns Feedback zu geben. + +Das Ausfüllen sollte weniger als eine Minute dauern. Vielen Dank, dass du uns hilfst, unsere Trainingsmaterialien für alle zu verbessern! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/de/docs/side_quests/README.md b/docs/de/docs/side_quests/README.md new file mode 100644 index 0000000000..c2bbfd98c4 --- /dev/null +++ b/docs/de/docs/side_quests/README.md @@ -0,0 +1 @@ +Das ist ein Platzhalter für zukünftige Side Quests (Vertiefungstrainings). Die Dokumentation hier besteht derzeit aus Entwürfen, die auf Inhalten aus anderen Quellen basieren. diff --git a/docs/de/docs/side_quests/debugging.md b/docs/de/docs/side_quests/debugging.md new file mode 100644 index 0000000000..1d281d3730 --- /dev/null +++ b/docs/de/docs/side_quests/debugging.md @@ -0,0 +1,1590 @@ +# Debugging von Workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Debugging ist eine kritische Fähigkeit, die dir Stunden der Frustration ersparen und dich zu einem effektiveren Nextflow-Entwickler machen kann. Im Laufe deiner Karriere, besonders wenn du gerade anfängst, wirst du beim Erstellen und Warten deiner Workflows auf Bugs stoßen. Systematische Debugging-Ansätze zu lernen wird dir helfen, Probleme schnell zu identifizieren und zu lösen. + +### Lernziele + +In dieser Side Quest werden wir **systematische Debugging-Techniken** für Nextflow-Workflows erkunden: + +- **Debugging von Syntaxfehlern**: Effektive Nutzung von IDE-Features und Nextflow-Fehlermeldungen +- **Channel-Debugging**: Diagnose von Datenfluss-Problemen und Channel-Strukturproblemen +- **Process-Debugging**: Untersuchung von Ausführungsfehlern und Ressourcenproblemen +- **Integrierte Debugging-Tools**: Nutzung von Nextflows Preview-Modus, Stub-Running und Work-Verzeichnissen +- **Systematische Ansätze**: Eine Vier-Phasen-Methodik für effizientes Debugging + +Am Ende wirst du eine robuste Debugging-Methodik haben, die frustrierende Fehlermeldungen in klare Wegweiser für Lösungen verwandelt. + +### Voraussetzungen + +Bevor du diese Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md) Tutorial oder einen gleichwertigen Einsteigerkurs abgeschlossen haben +- Mit grundlegenden Nextflow-Konzepten und -Mechanismen (Processes, Channels, Operatoren) vertraut sein + +**Optional:** Wir empfehlen, zuerst die Side Quest [IDE Features for Nextflow Development](./ide_features.md) zu absolvieren. +Diese bietet eine umfassende Abdeckung von IDE-Features, die Debugging unterstützen (Syntaxhervorhebung, Fehlererkennung usw.), die wir hier intensiv nutzen werden. + +--- + +## 0. Erste Schritte + +#### Öffne den Training-Codespace + +Falls du es noch nicht getan hast, öffne die Trainingsumgebung wie im [Environment Setup](../envsetup/index.md) beschrieben. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/debugging +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis fokussiert: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest eine Reihe von Beispiel-Workflows mit verschiedenen Arten von Bugs, die wir zum Üben verwenden werden: + +??? abstract "Verzeichnisinhalt" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Diese Dateien repräsentieren gängige Debugging-Szenarien, denen du in der realen Entwicklung begegnen wirst. + +#### Überprüfe die Aufgabenstellung + +Deine Herausforderung ist es, jeden Workflow auszuführen, die Fehler zu identifizieren und sie zu beheben. + +Für jeden fehlerhaften Workflow: + +1. **Führe den Workflow aus** und beobachte den Fehler +2. **Analysiere die Fehlermeldung**: Was sagt dir Nextflow? +3. **Lokalisiere das Problem** im Code anhand der bereitgestellten Hinweise +4. **Behebe den Bug** und verifiziere, dass deine Lösung funktioniert +5. **Setze die Datei zurück**, bevor du zum nächsten Abschnitt übergehst (verwende `git checkout <filename>`) + +Die Übungen steigern sich von einfachen Syntaxfehlern zu subtileren Laufzeitproblemen. +Lösungen werden inline diskutiert, aber versuche jede selbst zu lösen, bevor du weiterliest. + +#### Bereitschaftscheckliste + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace ist aktiv +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend eingestellt +- [ ] Ich verstehe die Aufgabenstellung + +Wenn du alle Kästchen abhaken kannst, kannst du loslegen. + +--- + +## 1. Syntaxfehler + +Syntaxfehler sind die häufigsten Fehler, denen du beim Schreiben von Nextflow-Code begegnen wirst. Sie treten auf, wenn der Code nicht den erwarteten Syntaxregeln der Nextflow-DSL entspricht. Diese Fehler verhindern, dass dein Workflow überhaupt läuft, daher ist es wichtig zu lernen, wie man sie schnell identifiziert und behebt. + +### 1.1. Fehlende Klammern + +Einer der häufigsten Syntaxfehler, und manchmal einer der komplexeren beim Debugging, sind **fehlende oder nicht übereinstimmende Klammern**. + +Beginnen wir mit einem praktischen Beispiel. + +#### Führe die Pipeline aus + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Schlüsselelemente von Syntaxfehlermeldungen:** + +- **Datei und Position**: Zeigt, welche Datei und welche Zeile/Spalte den Fehler enthält (`bad_syntax.nf:24:1`) +- **Fehlerbeschreibung**: Erklärt, was der Parser gefunden hat, das er nicht erwartet hat (`Unexpected input: '<EOF>'`) +- **EOF-Indikator**: Die `<EOF>` (End Of File) Nachricht zeigt an, dass der Parser das Ende der Datei erreicht hat, während er noch mehr Inhalt erwartet - ein klassisches Zeichen für nicht geschlossene Klammern + +#### Überprüfe den Code + +Jetzt schauen wir uns `bad_syntax.nf` an, um zu verstehen, was den Fehler verursacht: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Fehlende schließende Klammer für den Process + +workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) +} +``` + +Für dieses Beispiel haben wir einen Kommentar hinterlassen, der dir zeigt, wo der Fehler ist. Die Nextflow VSCode Extension sollte dir auch einige Hinweise geben, was falsch sein könnte, indem sie die nicht übereinstimmende Klammer rot markiert und das vorzeitige Ende der Datei hervorhebt: + +![Bad syntax](img/bad_syntax.png) + +**Debugging-Strategie für Klammerfehler:** + +1. Verwende VS Codes Klammerabgleich (platziere den Cursor neben einer Klammer) +2. Überprüfe das Problems-Panel auf klammerbezogene Meldungen +3. Stelle sicher, dass jede öffnende `{` eine entsprechende schließende `}` hat + +#### Behebe den Code + +Ersetze den Kommentar mit der fehlenden schließenden Klammer: + +=== "Nach" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Fehlende schließende Klammer hinzufügen + + workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) + } + ``` + +=== "Vorher" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Fehlende schließende Klammer für den Process + + workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) + } + ``` + +#### Führe die Pipeline aus + +Führe den Workflow jetzt erneut aus, um zu bestätigen, dass er funktioniert: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Verwendung falscher Process-Schlüsselwörter oder Direktiven + +Ein weiterer häufiger Syntaxfehler ist eine **ungültige Process-Definition**. Dies kann passieren, wenn du vergisst, erforderliche Blöcke zu definieren oder falsche Direktiven in der Process-Definition verwendest. + +#### Führe die Pipeline aus + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Überprüfe den Code + +Der Fehler zeigt eine "Invalid process definition" an und zeigt den Kontext um das Problem herum. Wenn wir uns die Zeilen 3-7 ansehen, können wir `inputs:` in Zeile 4 sehen, was das Problem ist. Schauen wir uns `invalid_process.nf` an: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // FEHLER: Sollte 'input' sein, nicht 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) +} +``` + +Wenn wir uns Zeile 4 im Fehlerkontext ansehen, können wir das Problem erkennen: Wir verwenden `inputs` anstelle der korrekten `input`-Direktive. Die Nextflow VSCode Extension wird dies ebenfalls kennzeichnen: + +![Invalid process message](img/invalid_process_message.png) + +#### Behebe den Code + +Ersetze das falsche Schlüsselwort durch das korrekte, indem du [die Dokumentation](https://www.nextflow.io/docs/latest/process.html#) konsultierst: + +=== "Nach" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Behoben: 'inputs' zu 'input' geändert + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) + } + ``` + +=== "Vorher" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // FEHLER: Sollte 'input' sein, nicht 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Eingabe-Channel erstellen + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Den Process mit dem Eingabe-Channel aufrufen + PROCESS_FILES(input_ch) + } + ``` + +#### Führe die Pipeline aus + +Führe den Workflow jetzt erneut aus, um zu bestätigen, dass er funktioniert: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Verwendung ungültiger Variablennamen + +Die Variablennamen, die du in deinen Script-Blöcken verwendest, müssen gültig sein und entweder aus Eingaben oder aus Groovy-Code vor dem Script abgeleitet werden. Aber wenn du zu Beginn der Pipeline-Entwicklung mit Komplexität jonglierst, ist es leicht, Fehler bei der Variablenbenennung zu machen, und Nextflow wird dich schnell darauf hinweisen. + +#### Führe die Pipeline aus + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Der Fehler wird zur Compile-Zeit abgefangen und zeigt direkt auf die undefinierte Variable in Zeile 17, mit einem Caret, das genau anzeigt, wo das Problem ist. + +#### Überprüfe den Code + +Schauen wir uns `no_such_var.nf` an: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // FEHLER: undefined_var nicht definiert + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +Die Fehlermeldung zeigt an, dass die Variable im Script-Template nicht erkannt wird, und dort siehst du es - `${undefined_var}` wird im Script-Block verwendet, aber nicht anderweitig definiert. + +#### Behebe den Code + +Wenn du einen 'No such variable'-Fehler erhältst, kannst du ihn beheben, indem du entweder die Variable definierst (durch Korrektur von Eingabevariablennamen oder Bearbeitung des Groovy-Codes vor dem Script) oder sie aus dem Script-Block entfernst, wenn sie nicht benötigt wird: + +=== "Nach" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Die Zeile mit undefined_var entfernt + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Vorher" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // FEHLER: undefined_var nicht definiert + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Führe die Pipeline aus + +Führe den Workflow jetzt erneut aus, um zu bestätigen, dass er funktioniert: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Schlechte Verwendung von Bash-Variablen + +Am Anfang mit Nextflow kann es schwierig sein, den Unterschied zwischen Nextflow (Groovy) und Bash-Variablen zu verstehen. Dies kann eine weitere Form des Variablenfehlers erzeugen, der auftritt, wenn man versucht, Variablen im Bash-Inhalt des Script-Blocks zu verwenden. + +#### Führe die Pipeline aus + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Überprüfe den Code + +Der Fehler zeigt auf Zeile 13, wo `${prefix}` verwendet wird. Schauen wir uns `bad_bash_var.nf` an, um zu sehen, was das Problem verursacht: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +In diesem Beispiel definieren wir die `prefix`-Variable in Bash, aber in einem Nextflow-Process wird die `$`-Syntax, die wir verwendet haben, um darauf zu verweisen (`${prefix}`), als Groovy-Variable interpretiert, nicht als Bash. Die Variable existiert nicht im Groovy-Kontext, also erhalten wir einen 'no such variable'-Fehler. + +#### Behebe den Code + +Wenn du eine Bash-Variable verwenden möchtest, musst du das Dollarzeichen so escapen: + +=== "Nach" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Vorher" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +Das sagt Nextflow, dies als Bash-Variable zu interpretieren. + +#### Führe die Pipeline aus + +Führe den Workflow jetzt erneut aus, um zu bestätigen, dass er funktioniert: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Groovy vs Bash-Variablen" + + Für einfache Variablenmanipulationen wie String-Verkettung oder Präfix-/Suffix-Operationen ist es normalerweise lesbarer, Groovy-Variablen im Script-Abschnitt zu verwenden anstatt Bash-Variablen im Script-Block: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Dieser Ansatz vermeidet die Notwendigkeit, Dollarzeichen zu escapen, und macht den Code einfacher zu lesen und zu warten. + +### 1.5. Anweisungen außerhalb des Workflow-Blocks + +Die Nextflow VSCode Extension hebt Probleme mit der Code-Struktur hervor, die Fehler verursachen werden. Ein häufiges Beispiel ist das Definieren von Channels außerhalb des `workflow {}`-Blocks - dies wird jetzt als Syntaxfehler durchgesetzt. + +#### Führe die Pipeline aus + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Die Fehlermeldung weist klar auf das Problem hin: Anweisungen (wie Channel-Definitionen) können nicht außerhalb eines Workflow- oder Process-Blocks mit Script-Deklarationen gemischt werden. + +#### Überprüfe den Code + +Schauen wir uns `badpractice_syntax.nf` an, um zu sehen, was den Fehler verursacht: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // FEHLER: Channel außerhalb des Workflows definiert + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +Die VSCode Extension wird auch die `input_ch`-Variable hervorheben, da sie außerhalb des Workflow-Blocks definiert ist: + +![Non-lethal syntax error](img/nonlethal.png) + +#### Behebe den Code + +Verschiebe die Channel-Definition in den Workflow-Block: + +=== "Nach" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Moved inside workflow block + PROCESS_FILES(input_ch) + } + ``` + +=== "Vorher" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // FEHLER: Channel außerhalb des Workflows definiert + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Führe die Pipeline aus + +Führe den Workflow erneut aus, um zu bestätigen, dass die Korrektur funktioniert: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Halte deine Input-Channels im Workflow-Block definiert und folge im Allgemeinen allen anderen Empfehlungen, die die Extension macht. + +### Zusammenfassung + +Du kannst Syntaxfehler systematisch identifizieren und beheben, indem du Nextflow-Fehlermeldungen und IDE-visuelle Indikatoren verwendest. Häufige Syntaxfehler umfassen fehlende Klammern, falsche Process-Schlüsselwörter, undefinierte Variablen und unsachgemäße Verwendung von Bash- vs. Nextflow-Variablen. Die VSCode Extension hilft, viele davon vor der Laufzeit zu erkennen. Mit diesen Syntax-Debugging-Fähigkeiten kannst du die häufigsten Nextflow-Syntaxfehler schnell beheben und dich komplexeren Laufzeitproblemen widmen. + +### Was kommt als Nächstes? + +Lerne, komplexere Channel-Strukturfehler zu debuggen, die auftreten, selbst wenn die Syntax korrekt ist. + +--- + +## 2. Channel-Strukturfehler + +Channel-Strukturfehler sind subtiler als Syntaxfehler, weil der Code syntaktisch korrekt ist, aber die Datenformen nicht zu dem passen, was Processes erwarten. Nextflow wird versuchen, die Pipeline auszuführen, könnte aber feststellen, dass die Anzahl der Eingaben nicht übereinstimmt und fehlschlagen. Diese Fehler treten typischerweise nur zur Laufzeit auf und erfordern ein Verständnis der Daten, die durch deinen Workflow fließen. + +!!! tip "Debugging von Channels mit `.view()`" + + Denke während dieses Abschnitts daran, dass du den `.view()`-Operator verwenden kannst, um Channel-Inhalte an jedem Punkt in deinem Workflow zu inspizieren. Dies ist eines der mächtigsten Debugging-Tools zum Verstehen von Channel-Strukturproblemen. Wir werden diese Technik in Abschnitt 2.4 im Detail erkunden, aber fühle dich frei, sie zu verwenden, während du durch die Beispiele arbeitest. + + ```groovy + my_channel.view() // Shows what's flowing through the channel + ``` + +### 2.1. Falsche Anzahl von Input-Channels + +Dieser Fehler tritt auf, wenn du eine andere Anzahl von Channels übergibst, als ein Process erwartet. + +#### Führe die Pipeline aus + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Überprüfe den Code + +Die Fehlermeldung gibt klar an, dass der Aufruf 1 Argument erwartet, aber 2 erhalten hat, und zeigt auf Zeile 23. Schauen wir uns `bad_number_inputs.nf` an: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Zwei separate Channels erstellen + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // FEHLER: 2 Channels übergeben, aber Process erwartet nur 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Du solltest den nicht übereinstimmenden `PROCESS_FILES`-Aufruf sehen, der mehrere Input-Channels bereitstellt, wenn der Process nur einen definiert. Die VSCode Extension wird auch den Process-Aufruf rot unterstreichen und eine Diagnosemeldung liefern, wenn du mit der Maus darüberfährst: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Behebe den Code + +Für dieses spezifische Beispiel erwartet der Process einen einzelnen Channel und benötigt den zweiten Channel nicht, also können wir es beheben, indem wir nur den `samples_ch`-Channel übergeben: + +=== "Nach" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Zwei separate Channels erstellen + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Behoben: Nur den Channel übergeben, den der Process erwartet + PROCESS_FILES(samples_ch) + } + ``` + +=== "Vorher" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Zwei separate Channels erstellen + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // FEHLER: 2 Channels übergeben, aber Process erwartet nur 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Führe die Pipeline aus + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Häufiger als in diesem Beispiel könntest du zusätzliche Eingaben zu einem Process hinzufügen und vergessen, den Workflow-Aufruf entsprechend zu aktualisieren, was zu dieser Art von Fehler führen kann. Glücklicherweise ist dies einer der leichter zu verstehenden und zu behebenden Fehler, da die Fehlermeldung recht klar über die Diskrepanz ist. + +### 2.2. Channel-Erschöpfung (Process läuft weniger oft als erwartet) + +Einige Channel-Strukturfehler sind viel subtiler und erzeugen überhaupt keine Fehler. Wahrscheinlich am häufigsten davon reflektiert eine Herausforderung, der neue Nextflow-Nutzer beim Verständnis gegenüberstehen, dass Queue-Channels erschöpft werden und keine Items mehr haben können, was bedeutet, dass der Workflow vorzeitig endet. + +#### Führe die Pipeline aus + +```bash +nextflow run exhausted.nf +``` + +??? success "Befehlsausgabe" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Dieser Workflow wird ohne Fehler abgeschlossen, aber er verarbeitet nur eine einzelne Probe! + +#### Überprüfe den Code + +Schauen wir uns `exhausted.nf` an, um zu sehen, ob das richtig ist: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Variablen im Groovy-Code vor dem Script definieren + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Der Process läuft nur einmal statt dreimal, weil der `reference_ch`-Channel ein Queue-Channel ist, der nach der ersten Process-Ausführung erschöpft ist. Wenn ein Channel erschöpft ist, stoppt der gesamte Process, selbst wenn andere Channels noch Items haben. + +Dies ist ein häufiges Muster, bei dem du eine einzelne Referenzdatei hast, die über mehrere Proben wiederverwendet werden muss. Die Lösung besteht darin, den Referenz-Channel in einen Value-Channel umzuwandeln, der unbegrenzt wiederverwendet werden kann. + +#### Behebe den Code + +Es gibt ein paar Möglichkeiten, dies zu adressieren, abhängig davon, wie viele Dateien betroffen sind. + +**Option 1**: Du hast eine einzelne Referenzdatei, die du häufig wiederverwendest. Du kannst einfach einen Value-Channel-Typ erstellen, der immer wieder verwendet werden kann. Es gibt drei Wege, dies zu tun: + +**1a** Verwende `channel.value()`: + +```groovy title="exhausted.nf (behoben - Option 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Value channel can be reused + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Verwende den `first()` [Operator](https://www.nextflow.io/docs/latest/reference/operator.html#first): + +```groovy title="exhausted.nf (behoben - Option 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Verwende den `collect()` [Operator](https://www.nextflow.io/docs/latest/reference/operator.html#collect): + +```groovy title="exhausted.nf (behoben - Option 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Option 2**: In komplexeren Szenarien, vielleicht wo du mehrere Referenzdateien für alle Proben im Proben-Channel hast, kannst du den `combine`-Operator verwenden, um einen neuen Channel zu erstellen, der die beiden Channels zu Tupeln kombiniert: + +```groovy title="exhausted.nf (behoben - Option 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Creates cartesian product + + PROCESS_FILES(combined_ch) +} +``` + +Der `.combine()`-Operator erzeugt ein kartesisches Produkt der beiden Channels, sodass jedes Item in `reference_ch` mit jedem Item in `input_ch` gepaart wird. Dies ermöglicht es dem Process, für jede Probe zu laufen und dabei trotzdem die Referenz zu verwenden. + +Dies erfordert, dass die Process-Eingabe angepasst wird. In unserem Beispiel müsste der Beginn der Process-Definition wie folgt angepasst werden: + +```groovy title="exhausted.nf (behoben - Option 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Dieser Ansatz ist möglicherweise nicht in allen Situationen geeignet. + +#### Führe die Pipeline aus + +Probiere eine der obigen Korrekturen aus und führe den Workflow erneut aus: + +```bash +nextflow run exhausted.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Du solltest jetzt sehen, dass alle drei Proben verarbeitet werden, anstatt nur eine. + +### 2.3. Falsche Channel-Inhaltsstruktur + +Wenn Workflows ein gewisses Maß an Komplexität erreichen, kann es etwas schwierig sein, den Überblick über die internen Strukturen jedes Channels zu behalten, und Menschen erzeugen häufig Diskrepanzen zwischen dem, was der Process erwartet, und dem, was der Channel tatsächlich enthält. Dies ist subtiler als das Problem, das wir früher besprochen haben, wo die Anzahl der Channels falsch war. In diesem Fall kannst du die richtige Anzahl von Input-Channels haben, aber die interne Struktur eines oder mehrerer dieser Channels stimmt nicht mit dem überein, was der Process erwartet. + +#### Führe die Pipeline aus + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Befehlsausgabe" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Überprüfe den Code + +Die eckigen Klammern in der Fehlermeldung liefern hier den Hinweis - der Process behandelt das Tupel als einen einzelnen Wert, was nicht das ist, was wir wollen. Schauen wir uns `bad_channel_shape.nf` an: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Du kannst sehen, dass wir einen Channel erstellen, der aus Tupeln besteht: `['sample1', 'file1.txt']`, aber der Process einen einzelnen Wert erwartet, `val sample_name`. Der ausgeführte Befehl zeigt, dass der Process versucht, eine Datei mit dem Namen `[sample3, file3.txt]_output.txt` zu erstellen, was nicht die beabsichtigte Ausgabe ist. + +#### Behebe den Code + +Um dies zu beheben, könnten wir, wenn der Process beide Eingaben benötigt, den Process so anpassen, dass er ein Tupel akzeptiert: + +=== "Option 1: Tupel im Process akzeptieren" + + === "Nach" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Behoben: Tuple akzeptieren + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Vorher" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Option 2: Erstes Element extrahieren" + + === "Nach" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Behoben: Erstes Element extrahieren + } + ``` + + === "Vorher" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Führe die Pipeline aus + +Wähle eine der Lösungen und führe den Workflow erneut aus: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Channel-Debugging-Techniken + +#### Verwendung von `.view()` zur Channel-Inspektion + +Das mächtigste Debugging-Tool für Channels ist der `.view()`-Operator. Mit `.view()` kannst du die Form deiner Channels in allen Phasen verstehen, um beim Debugging zu helfen. + +#### Führe die Pipeline aus + +Führe `bad_channel_shape_viewed.nf` aus, um dies in Aktion zu sehen: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Überprüfe den Code + +Schauen wir uns `bad_channel_shape_viewed.nf` an, um zu sehen, wie `.view()` verwendet wird: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debug: Show original channel content + .map { tuple -> tuple[0] } // Transform: Extract first element + .view { "After mapping: $it" } // Debug: Show transformed channel content + + PROCESS_FILES(input_ch) +} +``` + +#### Behebe den Code + +Um zu vermeiden, dass du in Zukunft übermäßig `.view()`-Operationen verwenden musst, um Channel-Inhalte zu verstehen, ist es ratsam, einige Kommentare hinzuzufügen: + +```groovy title="bad_channel_shape_viewed.nf (mit Kommentaren)" linenums="16" hl_lines="8 9" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Dies wird wichtiger, wenn deine Workflows an Komplexität zunehmen und die Channel-Struktur undurchsichtiger wird. + +#### Führe die Pipeline aus + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Zusammenfassung + +Viele Channel-Strukturfehler können mit gültiger Nextflow-Syntax erstellt werden. Du kannst Channel-Strukturfehler debuggen, indem du den Datenfluss verstehst, `.view()`-Operatoren zur Inspektion verwendest und Fehlermuster wie eckige Klammern erkennst, die auf unerwartete Tupelstrukturen hinweisen. + +### Was kommt als Nächstes? + +Lerne über Fehler, die durch Process-Definitionen erzeugt werden. + +--- + +## 3. Process-Strukturfehler + +Die meisten Fehler, denen du im Zusammenhang mit Processes begegnest, werden sich auf Fehler beziehen, die du bei der Formung des Befehls gemacht hast, oder auf Probleme im Zusammenhang mit der zugrunde liegenden Software. Allerdings kannst du, ähnlich wie bei den Channel-Problemen oben, Fehler in der Process-Definition machen, die nicht als Syntaxfehler qualifizieren, aber die zur Laufzeit Fehler verursachen werden. + +### 3.1. Fehlende Ausgabedateien + +Ein häufiger Fehler beim Schreiben von Processes ist es, etwas zu tun, das eine Diskrepanz zwischen dem, was der Process erwartet, und dem, was generiert wird, erzeugt. + +#### Führe die Pipeline aus + +```bash +nextflow run missing_output.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Überprüfe den Code + +Die Fehlermeldung zeigt an, dass der Process erwartet hat, eine Ausgabedatei namens `sample3.txt` zu erzeugen, aber das Script tatsächlich `sample3_output.txt` erstellt. Schauen wir uns die Process-Definition in `missing_output.nf` an: + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Expects: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Creates: sample3_output.txt + """ +} +``` + +Du solltest sehen, dass es eine Diskrepanz zwischen dem Ausgabedateinamen im `output:`-Block und dem im Script verwendeten gibt. Diese Diskrepanz führt dazu, dass der Process fehlschlägt. Wenn du auf diese Art von Fehler stößt, gehe zurück und überprüfe, dass die Ausgaben zwischen deiner Process-Definition und deinem Output-Block übereinstimmen. + +Wenn das Problem immer noch nicht klar ist, überprüfe das Work-Verzeichnis selbst, um die tatsächlich erstellten Ausgabedateien zu identifizieren: + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Für dieses Beispiel würde uns dies verdeutlichen, dass ein `_output`-Suffix in den Ausgabedateinamen einbezogen wird, entgegen unserer `output:`-Definition. + +#### Behebe den Code + +Behebe die Diskrepanz, indem du den Ausgabedateinamen konsistent machst: + +=== "Nach" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Behoben: Mit der Script-Ausgabe übereinstimmen + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Vorher" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Expects: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Creates: sample3_output.txt + """ + } + ``` + +#### Führe die Pipeline aus + +```bash +nextflow run missing_output.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [elated_hamilton] DSL2 - revision: 961938ee2b + + executor > local (3) + [16/1c437c] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +### 3.2. Fehlende Software + +Eine weitere Fehlerklasse tritt aufgrund von Fehlern bei der Software-Bereitstellung auf. `missing_software.nf` ist ein syntaktisch gültiger Workflow, aber er hängt von externer Software ab, um den `cowpy`-Befehl bereitzustellen, den er verwendet. + +#### Führe die Pipeline aus + +```bash +nextflow run missing_software.nf +``` + +??? failure "Befehlsausgabe" + + ```console hl_lines="12 18" diff --git a/docs/de/docs/side_quests/dev_environment.md b/docs/de/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..4f3f5701bf --- /dev/null +++ b/docs/de/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Entwicklungsumgebung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Moderne Integrierte Entwicklungsumgebungen (IDEs) können deine Nextflow-Entwicklungserfahrung dramatisch verändern. Dieser Side Quest konzentriert sich speziell darauf, VS Code und seine Nextflow-Erweiterung zu nutzen, um Code schneller zu schreiben, Fehler frühzeitig zu erkennen und effizient in komplexen Workflows zu navigieren. + +!!! note "Dies ist kein traditionelles Tutorial" + + Anders als andere Trainingsmodule ist dieser Leitfaden als Sammlung von schnellen Hinweisen, Tipps und praktischen Beispielen organisiert, nicht als Schritt-für-Schritt-Tutorial. Jeder Abschnitt kann unabhängig basierend auf deinen Interessen und aktuellen Entwicklungsbedürfnissen erkundet werden. Spring gerne herum und konzentriere dich auf die Features, die für deine Workflow-Entwicklung am unmittelbarsten nützlich sein werden. + +## Was du zuerst wissen solltest + +Dieser Leitfaden setzt voraus, dass du den [Hello Nextflow](../hello_nextflow/)-Trainingskurs abgeschlossen hast und mit grundlegenden Nextflow-Konzepten vertraut bist, einschließlich: + +- **Grundlegende Workflow-Struktur**: Verständnis von Processes, Workflows und wie sie zusammenarbeiten +- **Channel-Operationen**: Channels erstellen, Daten zwischen Processes weitergeben und grundlegende Operatoren verwenden +- **Module und Organisation**: Wiederverwendbare Module erstellen und include-Anweisungen verwenden +- **Grundlagen der Konfiguration**: `nextflow.config` für Parameter, Process-Direktiven und Profile verwenden + +## Was du hier lernen wirst + +Dieser Leitfaden konzentriert sich auf **IDE-Produktivitätsfeatures**, die dich zu einem effizienteren Nextflow-Entwickler machen werden: + +- **Erweitertes Syntax-Highlighting**: Verstehen, was VS Code dir über deine Codestruktur zeigt +- **Intelligente Auto-Vervollständigung**: Kontextbezogene Vorschläge für schnelleres Code-Schreiben nutzen +- **Fehlererkennung und Diagnose**: Syntaxfehler erkennen, bevor du deinen Workflow ausführst +- **Code-Navigation**: Schnell zwischen Processes, Modulen und Definitionen wechseln +- **Formatierung und Organisation**: Konsistenten, lesbaren Code-Stil beibehalten +- **KI-unterstützte Entwicklung** (optional): Moderne KI-Tools nutzen, die in deine IDE integriert sind + +!!! info "Warum IDE-Features jetzt?" + + Du hast wahrscheinlich bereits VS Code während des [Hello Nextflow](../hello_nextflow/)-Kurses verwendet, aber wir haben uns auf das Erlernen der Nextflow-Grundlagen konzentriert anstatt auf IDE-Features. Jetzt, da du mit grundlegenden Nextflow-Konzepten wie Processes, Workflows, Channels und Modulen vertraut bist, bist du bereit, die ausgefeilten IDE-Features zu nutzen, die dich zu einem effizienteren Entwickler machen werden. + + Denke daran als "Level-up" deiner Entwicklungsumgebung - der gleiche Editor, den du verwendet hast, hat viel leistungsfähigere Funktionen, die wirklich wertvoll werden, sobald du verstehst, wobei sie dir helfen. + +--- + +## 0. Setup und Aufwärmen + +Lass uns einen Arbeitsbereich speziell für die Erkundung von IDE-Features einrichten: + +```bash title="Navigiere zum IDE-Features-Verzeichnis" +cd side-quests/ide_features +``` + +Öffne dieses Verzeichnis in VS Code: + +```bash title="Öffne VS Code im aktuellen Verzeichnis" +code . +``` + +Das `ide_features`-Verzeichnis enthält Beispiel-Workflows, die verschiedene IDE-Features demonstrieren: + +```bash title="Zeige Verzeichnisstruktur" +tree . +``` + +```console title="Projektstruktur" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "Über die Beispieldateien" + + - `basic_workflow.nf` ist ein funktionierender einfacher Workflow, den du ausführen und ändern kannst + - `complex_workflow.nf` ist nur zur Illustration gedacht, um Navigationsfunktionen zu demonstrieren - er läuft möglicherweise nicht erfolgreich, zeigt aber eine realistische Multi-Datei-Workflow-Struktur + +### Tastaturkürzel + +Einige der Features in diesem Leitfaden verwenden optionale Tastaturkürzel. Du greifst möglicherweise über GitHub Codespaces im Browser auf dieses Material zu, und in diesem Fall funktionieren die Tastaturkürzel manchmal nicht wie erwartet, weil sie für andere Dinge in deinem System verwendet werden. + +Wenn du VS Code lokal ausführst, wie du es wahrscheinlich tun wirst, wenn du tatsächlich Workflows schreibst, funktionieren die Tastaturkürzel wie beschrieben. + +Wenn du einen Mac verwendest, verwenden einige (nicht alle) Tastaturkürzel "cmd" anstelle von "ctrl", und wir werden dies im Text wie `Ctrl/Cmd` angeben. + +### 0.1. Installation der Nextflow-Erweiterung + +!!! note "Verwendest du bereits Devcontainer?" + + Wenn du in **GitHub Codespaces** arbeitest oder einen **lokalen Devcontainer** verwendest, ist die Nextflow-Erweiterung wahrscheinlich bereits für dich installiert und konfiguriert. Du kannst die manuellen Installationsschritte unten überspringen und direkt mit der Erkundung der Erweiterungsfeatures fortfahren. + +Um die Erweiterung manuell zu installieren: + +1. Öffne VS Code +2. Gehe zur Extensions-Ansicht, indem du auf das Extensions-Symbol links klickst: ![Extensions-Symbol](img/extensions_icon.png) (Tastaturkürzel `Ctrl/Cmd+Shift+X`, wenn du VSCode lokal ausführst) +3. Suche nach "Nextflow" +4. Installiere die offizielle Nextflow-Erweiterung + +![Nextflow-Erweiterung installieren](img/install_extension.png) + +### 0.2. Arbeitsbereich-Layout + +Da du VS Code während Hello Nextflow verwendet hast, bist du bereits mit den Grundlagen vertraut. So organisierst du deinen Arbeitsbereich effizient für diese Session: + +- **Editor-Bereich**: Zum Anzeigen und Bearbeiten von Dateien. Du kannst diesen in mehrere Bereiche aufteilen, um Dateien nebeneinander zu vergleichen. +- **Datei-Explorer** Klick (![Datei-Explorer-Symbol](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): Die lokalen Dateien und Ordner auf deinem System. Halte dies links offen, um zwischen Dateien zu navigieren +- **Integriertes Terminal** (`Ctrl+Shift+` Backtick für Windows und MacOS): Ein Terminal zur Interaktion mit dem Computer unten. Verwende dies, um Nextflow oder andere Befehle auszuführen. +- **Problems-Panel** (`Ctrl+Shift+M`): VS Code zeigt hier alle Fehler und Probleme an, die es erkennt. Dies ist nützlich, um Probleme auf einen Blick hervorzuheben. + +Du kannst Panels herumziehen oder ausblenden (`Ctrl/Cmd+B` zum Umschalten der Seitenleiste), um dein Layout anzupassen, während wir die Beispiele durchgehen. + +### Zusammenfassung + +Du hast VS Code mit der Nextflow-Erweiterung eingerichtet und verstehst das Arbeitsbereich-Layout für effiziente Entwicklung. + +### Was kommt als Nächstes? + +Lerne, wie Syntax-Highlighting dir hilft, die Nextflow-Codestruktur auf einen Blick zu verstehen. + +--- + +## 1. Syntax-Highlighting und Code-Struktur + +Jetzt, da dein Arbeitsbereich eingerichtet ist, lass uns erkunden, wie das Syntax-Highlighting von VS Code dir hilft, Nextflow-Code effektiver zu lesen und zu schreiben. + +### 1.1. Nextflow-Syntax-Elemente + +Öffne `basic_workflow.nf`, um Syntax-Highlighting in Aktion zu sehen: + +![Syntax Showcase](img/syntax_showcase.png) + +Beachte, wie VS Code hervorhebt: + +- **Schlüsselwörter** (`process`, `workflow`, `input`, `output`, `script`) in unterschiedlichen Farben +- **String-Literale** und **Parameter** mit unterschiedlicher Gestaltung +- **Kommentare** in einer gedämpften Farbe +- **Variablen** und **Funktionsaufrufe** mit angemessener Betonung +- **Codeblöcke** mit korrekten Einrückungslinien + +!!! note "Theme-abhängige Farben" + + Die spezifischen Farben, die du siehst, hängen von deinem VS Code-Theme (Dark/Light-Modus), Farbeinstellungen und allen Anpassungen ab, die du vorgenommen hast. Das Wichtige ist, dass verschiedene Syntaxelemente visuell voneinander unterschieden werden, was die Codestruktur leichter verständlich macht, unabhängig von deinem gewählten Farbschema. + +### 1.2. Verständnis der Code-Struktur + +Das Syntax-Highlighting hilft dir, schnell zu identifizieren: + +- **Process-Grenzen**: Klare Unterscheidung zwischen verschiedenen Processes +- **Input/Output-Blöcke**: Einfach zu erkennende Datenfluss-Definitionen +- **Script-Blöcke**: Die tatsächlich ausgeführten Befehle +- **Channel-Operationen**: Datentransformationsschritte +- **Konfigurationsdirektiven**: Process-spezifische Einstellungen + +Diese visuelle Organisation wird unschätzbar wertvoll, wenn du mit komplexen Workflows arbeitest, die mehrere Processes und komplizierte Datenflüsse enthalten. + +### Zusammenfassung + +Du verstehst, wie das Syntax-Highlighting von VS Code dir hilft, die Nextflow-Codestruktur zu lesen und verschiedene Sprachelemente für schnellere Entwicklung zu identifizieren. + +### Was kommt als Nächstes? + +Lerne, wie intelligente Auto-Vervollständigung das Code-Schreiben mit kontextbezogenen Vorschlägen beschleunigt. + +--- + +## 2. Intelligente Auto-Vervollständigung + +Die Auto-Vervollständigungsfeatures von VS Code helfen dir, Code schneller und mit weniger Fehlern zu schreiben, indem sie basierend auf dem Kontext passende Optionen vorschlagen. + +### 2.1. Kontextbezogene Vorschläge + +Die Auto-Vervollständigungsoptionen variieren je nachdem, wo du dich in deinem Code befindest: + +#### Channel-Operationen + +Öffne `basic_workflow.nf` erneut und versuche, `channel.` im workflow-Block einzugeben: + +![Channel-Auto-Vervollständigung](img/autocomplete_channel.png) + +Du wirst Vorschläge sehen für: + +- `fromPath()` - Channel aus Dateipfaden erstellen +- `fromFilePairs()` - Channel aus gepaarten Dateien erstellen +- `of()` - Channel aus Werten erstellen +- `fromSRA()` - Channel aus SRA-Accessions erstellen +- Und viele mehr... + +Dies hilft dir, schnell die richtige Channel-Factory zu finden, ohne dir genaue Methodennamen merken zu müssen. + +Du kannst auch die Operatoren entdecken, die auf Channels angewendet werden können. Gib zum Beispiel `FASTQC.out.html.` ein, um verfügbare Operationen zu sehen: + +![Channel-Operationen-Auto-Vervollständigung](img/autocomplete_operators.png) + +#### Process-Direktiven + +Innerhalb eines Process-Script-Blocks, gib `task.` ein, um verfügbare Runtime-Eigenschaften zu sehen: + +![Task-Eigenschaften-Auto-Vervollständigung](img/autocomplete_task.png) + +#### Konfiguration + +Öffne nextflow.config und gib `process.` irgendwo ein, um verfügbare Process-Direktiven zu sehen: + +![Config-Auto-Vervollständigung](img/autocomplete_config.png) + +Du wirst Vorschläge sehen für: + +- `executor` +- `memory` +- `cpus` + +Dies spart Zeit beim Konfigurieren von Processes und funktioniert über verschiedene Konfigurationsbereiche hinweg. Versuche zum Beispiel, `docker.` einzugeben, um Docker-spezifische Konfigurationsoptionen zu sehen. + +### Zusammenfassung + +Du kannst die intelligente Auto-Vervollständigung von VS Code verwenden, um verfügbare Channel-Operationen, Process-Direktiven und Konfigurationsoptionen zu entdecken, ohne Syntax auswendig zu lernen. + +### Was kommt als Nächstes? + +Lerne, wie Echtzeit-Fehlererkennung dir hilft, Probleme zu erkennen, bevor du deinen Workflow ausführst, einfach durch das Lesen des Codes. + +## 3. Fehlererkennung und Diagnose + +Die Echtzeit-Fehlererkennung von VS Code hilft dir, Probleme zu erkennen, bevor du deinen Workflow ausführst. + +### 3.1. Syntaxfehler-Erkennung + +Lass uns einen absichtlichen Fehler erstellen, um die Erkennung in Aktion zu sehen. Öffne `basic_workflow.nf` und ändere den Process-Namen von `FASTQC` zu `FASTQ` (oder einen anderen ungültigen Namen). VS Code wird den Fehler im workflow-Block sofort mit einer roten Wellenlinie hervorheben: + +![Fehlerunterstreichung](img/error_underline.png) + +### 3.2. Problems-Panel + +Über die individuelle Fehlerhervorhebung hinaus bietet VS Code ein zentrales Problems-Panel, das alle Fehler, Warnungen und Informationsmeldungen über deinen Arbeitsbereich hinweg aggregiert. Öffne es mit `Ctrl/Cmd+Shift+M` und verwende das Filter-Symbol, um nur Fehler anzuzeigen, die für die aktuelle Datei relevant sind: + +![Problems-Panel filtern](img/active_file.png) + +Klicke auf ein Problem, um direkt zur problematischen Zeile zu springen + +![Problems-Panel](img/problems_panel.png) + +Behebe den Fehler, indem du den Process-Namen zurück zu `FASTQC` änderst. + +### 3.3. Häufige Fehlermuster + +Häufige Fehler in der Nextflow-Syntax umfassen: + +- **Fehlende Klammern**: Nicht übereinstimmende `{` oder `}` +- **Unvollständige Blöcke**: Fehlende erforderliche Abschnitte in Processes +- **Ungültige Syntax**: Fehlerhafte Nextflow DSL +- **Tippfehler in Schlüsselwörtern**: Falsch geschriebene Process-Direktiven +- **Channel-Nichtübereinstimmungen**: Typ-Inkompatibilitäten + +Der Nextflow Language Server hebt diese Probleme im Problems-Panel hervor. Du kannst diese frühzeitig überprüfen, um Syntaxfehler beim Ausführen einer Pipeline zu vermeiden. + +### Zusammenfassung + +Du kannst die Fehlererkennung und das Problems-Panel von VS Code verwenden, um Syntaxfehler und Probleme zu erkennen, bevor du deinen Workflow ausführst, was Zeit spart und Frustration verhindert. + +### Was kommt als Nächstes? + +Lerne, wie du effizient zwischen Processes, Modulen und Definitionen in komplexen Workflows navigierst. + +--- + +## 4. Code-Navigation und Symbol-Verwaltung + +Effiziente Navigation ist entscheidend, wenn du mit komplexen Workflows arbeitest, die sich über mehrere Dateien erstrecken. Um dies zu verstehen, ersetze die Process-Definition in `basic_workflow.nf` durch einen Import für das Modul, das wir dir bereitgestellt haben: + +=== "Nachher" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Vorher" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Gehe zu Definition + +Wenn du mit der Maus über einen Process-Namen wie `FASTQC` fährst, siehst du ein Popup mit dem Modul-Interface (Eingaben und Ausgaben): + +![Gehe zu Definition](img/syntax.png) + +Diese Funktion ist besonders wertvoll beim Erstellen von Workflows, da sie dir ermöglicht, das Modul-Interface zu verstehen, ohne die Moduldatei direkt zu öffnen. + +Du kannst schnell zu jeder Process-, Modul- oder Variablendefinition navigieren, indem du **Ctrl/Cmd-Klick** verwendest. Fahre mit der Maus über den Link zur Moduldatei oben im Script und folge dem Link wie vorgeschlagen: + +![Link folgen](img/follow_link.png) + +Das Gleiche funktioniert für Process-Namen. Gehe zurück zu `basic_workflow.nf` und probiere dies beim `FASTQC`-Process-Namen im workflow-Block aus. Dies verlinkt dich direkt zum Process-Namen (der in diesem Beispiel mit der Moduldatei identisch ist, aber Teil einer viel größeren Datei sein könnte). + +Um dorthin zurückzugehen, wo du warst, verwende **Alt+←** (oder **Ctrl+-** auf Mac). Dies ist eine leistungsstarke Möglichkeit, Code zu erkunden, ohne deinen Platz zu verlieren. + +Lass uns nun die Navigation in einem komplexeren Workflow mit `complex_workflow.nf` erkunden (die zuvor erwähnte reine Illustrationsdatei). Dieser Workflow enthält mehrere Processes, die in separaten Moduldateien definiert sind, sowie einige Inline-Processes. Während komplexe Multi-Datei-Strukturen manuell schwer zu navigieren sein können, macht die Fähigkeit, zu Definitionen zu springen, die Erkundung viel handhabbarer. + +1. Öffne `complex_workflow.nf` +2. Navigiere zu Modul-Definitionen +3. Verwende **Alt+←** (oder **Ctrl+-**), um zurückzunavigieren +4. Navigiere zum `FASTQC`-Process-Namen im workflow-Block. Dies verlinkt dich direkt zum Process-Namen (der in diesem Beispiel mit der Moduldatei identisch ist, aber Teil einer viel größeren Datei sein könnte). +5. Navigiere wieder zurück +6. Navigiere zum `TRIM_GALORE`-Process im workflow-Block. Dieser ist inline definiert, sodass er dich nicht zu einer separaten Datei bringt, aber er zeigt dir trotzdem die Process-Definition, und du kannst immer noch dorthin zurücknavigieren, wo du warst. + +### 4.2. Symbol-Navigation + +Während `complex_workflow.nf` noch geöffnet ist, kannst du eine Übersicht über alle Symbole in der Datei erhalten, indem du `@` in die Suchleiste oben in VSCode eingibst (das Tastaturkürzel ist `Ctrl/Cmd+Shift+O`, funktioniert aber möglicherweise nicht in Codespaces). Dies öffnet das Symbol-Navigationspanel, das alle Symbole in der aktuellen Datei auflistet: + +![Symbol-Navigation](img/symbols.png) + +Dies zeigt: + +- Alle Process-Definitionen +- Workflow-Definitionen (in dieser Datei sind zwei Workflows definiert) +- Funktionsdefinitionen + +Beginne mit dem Tippen, um Ergebnisse zu filtern. + +### 4.3. Alle Referenzen finden + +Zu verstehen, wo ein Process oder eine Variable in deiner Codebasis verwendet wird, kann sehr hilfreich sein. Wenn du beispielsweise alle Referenzen zum `FASTQC`-Process finden möchtest, beginne damit, zu seiner Definition zu navigieren. Du kannst dies tun, indem du `modules/fastqc.nf` direkt öffnest oder VS Codes Schnellnavigationsfunktion mit `Ctrl/Cmd-Klick` verwendest, wie wir es oben getan haben. Sobald du bei der Process-Definition bist, klicke mit der rechten Maustaste auf den `FASTQC`-Process-Namen und wähle "Find All References" aus dem Kontextmenü, um alle Instanzen zu sehen, wo er verwendet wird. + +![Referenzen finden](img/references.png) + +Diese Funktion zeigt alle Instanzen an, wo `FASTQC` innerhalb deines Arbeitsbereichs referenziert wird, einschließlich seiner Verwendung in den beiden unterschiedlichen Workflows. Diese Einsicht ist entscheidend, um die potenziellen Auswirkungen von Änderungen am `FASTQC`-Process zu beurteilen. + +### 4.4. Outline-Panel + +Das Outline-Panel, das sich in der Explorer-Seitenleiste befindet (klicke ![Explorer-Symbol](img/files_icon.png)), bietet eine bequeme Übersicht über alle Symbole in deiner aktuellen Datei. Diese Funktion ermöglicht es dir, schnell zu navigieren und die Struktur deines Codes zu verwalten, indem Funktionen, Variablen und andere Schlüsselelemente in einer hierarchischen Ansicht angezeigt werden. + +![Outline-Panel](img/outline.png) + +Verwende das Outline-Panel, um schnell zu verschiedenen Teilen deines Codes zu navigieren, ohne den Datei-Browser zu verwenden. + +### 4.5. DAG-Visualisierung + +Die Nextflow-Erweiterung von VS Code kann deinen Workflow als Directed Acyclic Graph (DAG) visualisieren. Dies hilft dir, den Datenfluss und die Abhängigkeiten zwischen Processes zu verstehen. Öffne `complex_workflow.nf` und klicke auf die "Preview DAG"-Schaltfläche über `workflow {` (der zweite `workflow`-Block in dieser Datei): + +![DAG-Vorschau](img/dag_preview.png) + +Dies ist nur der 'Entry'-Workflow, aber du kannst auch den DAG für die inneren Workflows in der Vorschau anzeigen, indem du auf die "Preview DAG"-Schaltfläche über dem workflow `RNASEQ_PIPELINE {` weiter oben klickst: + +![DAG-Vorschau innerer Workflow](img/dag_preview_inner.png) + +Für diesen Workflow kannst du die Knoten im DAG verwenden, um zu den entsprechenden Process-Definitionen im Code zu navigieren. Klicke auf einen Knoten, und er bringt dich zur relevanten Process-Definition im Editor. Besonders wenn ein Workflow zu einer großen Größe anwächst, kann dies dir wirklich helfen, im Code zu navigieren und zu verstehen, wie die Processes verbunden sind. + +### Zusammenfassung + +Du kannst komplexe Workflows effizient navigieren, indem du Gehe-zu-Definition, Symbolsuche, Referenzen finden und DAG-Visualisierung verwendest, um Codestruktur und Abhängigkeiten zu verstehen. + +### Was kommt als Nächstes? + +Lerne, wie du effektiv über mehrere miteinander verbundene Dateien in größeren Nextflow-Projekten hinweg arbeitest. + +## 5. Arbeiten über mehrere Dateien hinweg + +Echte Nextflow-Entwicklung beinhaltet die Arbeit mit mehreren miteinander verbundenen Dateien. Lass uns erkunden, wie VS Code dir hilft, komplexe Projekte effizient zu verwalten. + +### 5.1. Schnelle Datei-Navigation + +Während `complex_workflow.nf` geöffnet ist, wirst du bemerken, dass es mehrere Module importiert. Lass uns die schnelle Navigation zwischen ihnen üben. + +Drücke **Ctrl+P** (oder **Cmd+P**) und beginne "fast" einzugeben: + +VS Code zeigt dir passende Dateien an. Wähle `modules/fastqc.nf`, um sofort dorthin zu springen. Dies ist viel schneller als durch den Datei-Explorer zu klicken, wenn du ungefähr weißt, welche Datei du suchst. + +Probiere dies mit anderen Mustern aus: + +- Gib "star" ein, um die STAR-Alignment-Moduldatei zu finden (`star.nf`) +- Gib "utils" ein, um die Utility-Funktionsdatei zu finden (`utils.nf`) +- Gib "config" ein, um zu Konfigurationsdateien zu springen (`nextflow.config`) + +### 5.2. Split-Editor für Multi-Datei-Entwicklung + +Wenn du mit Modulen arbeitest, musst du oft sowohl den Haupt-Workflow als auch die Modul-Definitionen gleichzeitig sehen. Lass uns das einrichten: + +1. Öffne `complex_workflow.nf` +2. Öffne `modules/fastqc.nf` in einem neuen Tab +3. Rechtsklicke auf den `modules/fastqc.nf`-Tab und wähle "Split Right" +4. Jetzt kannst du beide Dateien nebeneinander sehen + +![Split-Editor](img/split_editor.png) + +Dies ist unschätzbar wertvoll, wenn: + +- Du Modul-Interfaces überprüfst, während du Workflow-Aufrufe schreibst, und die Vorschau nicht ausreicht +- Du ähnliche Processes über verschiedene Module hinweg vergleichst +- Du den Datenfluss zwischen Workflow und Modulen debuggst + +### 5.3. Projektweite Suche + +Manchmal musst du finden, wo bestimmte Muster in deinem gesamten Projekt verwendet werden. Drücke `Ctrl/Cmd+Shift+F`, um das Suchpanel zu öffnen. + +Versuche, über den Arbeitsbereich hinweg nach `publishDir` zu suchen: + +![Projektsuche](img/project_search.png) + +Dies zeigt dir jede Datei, die Publish-Verzeichnisse verwendet, und hilft dir: + +- Ausgabe-Organisationsmuster zu verstehen +- Beispiele für bestimmte Direktiven zu finden +- Konsistenz über Module hinweg sicherzustellen + +### Zusammenfassung + +Du kannst komplexe Multi-Datei-Projekte verwalten, indem du schnelle Datei-Navigation, Split-Editoren und projektweite Suche verwendest, um effizient über Workflows und Module hinweg zu arbeiten. + +### Was kommt als Nächstes? + +Lerne, wie Code-Formatierungs- und Wartungsfunktionen deine Workflows organisiert und lesbar halten. + +--- + +## 6. Code-Formatierung und Wartung + +Richtige Code-Formatierung ist nicht nur für die Ästhetik wichtig, sondern auch für die Verbesserung der Lesbarkeit, des Verständnisses und der Leichtigkeit der Aktualisierung komplexer Workflows. + +### 6.1. Automatische Formatierung in Aktion + +Öffne `basic_workflow.nf` und bringe die Formatierung absichtlich durcheinander: + +- Entferne einige Einrückungen: Markiere das gesamte Dokument und drücke `shift+tab` viele Male, um so viele Einrückungen wie möglich zu entfernen. +- Füge zusätzliche Leerzeichen an zufälligen Stellen hinzu: Bei der `channel.fromPath`-Anweisung füge 30 Leerzeichen nach der `(` hinzu. +- Breche einige Zeilen unbeholfen: Füge eine neue Zeile zwischen dem `.view {`-Operator und dem `Processing sample:`-String hinzu, füge aber keine entsprechende neue Zeile vor der schließenden Klammer `}` hinzu. + +Drücke jetzt `Shift+Alt+F` (oder `Shift+Option+F` auf MacOS) zum Auto-Formatieren: + +VS Code: + +- Behebt die Einrückung, um die Process-Struktur klar zu zeigen +- Richtet ähnliche Elemente konsistent aus +- Entfernt unnötige Leerzeichen +- Behält lesbare Zeilenumbrüche bei + +Beachte, dass die automatische Formatierung möglicherweise nicht jedes Code-Style-Problem löst. Der Nextflow Language Server zielt darauf ab, deinen Code ordentlich zu halten, respektiert aber auch deine persönlichen Vorlieben in bestimmten Bereichen. Wenn du beispielsweise die Einrückung innerhalb des `script`-Blocks eines Processes entfernst, lässt der Formatierer sie so, da du diesen Stil möglicherweise absichtlich bevorzugst. + +Derzeit gibt es keine strikte Style-Durchsetzung für Nextflow, daher bietet der Language Server etwas Flexibilität. Er wird jedoch konsequent Formatierungsregeln um Methoden- und Funktionsdefinitionen herum anwenden, um Klarheit zu erhalten. + +### 6.2. Code-Organisationsfunktionen + +#### Schnelles Kommentieren + +Wähle einen Codeblock in deinem Workflow aus und drücke **Ctrl+/** (oder **Cmd+/**), um ihn auszukommentieren: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +Dies ist perfekt für: + +- Vorübergehendes Deaktivieren von Teilen von Workflows während der Entwicklung +- Hinzufügen erklärender Kommentare zu komplexen Channel-Operationen +- Dokumentieren von Workflow-Abschnitten + +Verwende **Ctrl+/** (oder **Cmd+/**) erneut, um den Code zu entkommentieren. + +#### Code-Faltung für Übersicht + +Beachte in `complex_workflow.nf` die kleinen Pfeile neben Process-Definitionen. Klicke darauf, um Processes zu falten (zusammenklappen): + +![Code-Faltung](img/code_folding.png) + +Dies gibt dir eine High-Level-Übersicht über deine Workflow-Struktur, ohne dich in Implementierungsdetails zu verlieren. + +#### Klammer-Zuordnung + +Platziere deinen Cursor neben einer beliebigen `{` oder `}`-Klammer, und VS Code hebt die passende Klammer hervor. Verwende **Ctrl+Shift+\\** (oder **Cmd+Shift+\\**), um zwischen passenden Klammern zu springen. + +Dies ist entscheidend für: + +- Verständnis von Process-Grenzen +- Finden fehlender oder zusätzlicher Klammern +- Navigation in verschachtelten Workflow-Strukturen + +#### Mehrzeilige Auswahl und Bearbeitung + +Für die gleichzeitige Bearbeitung mehrerer Zeilen bietet VS Code leistungsstarke Multi-Cursor-Fähigkeiten: + +- **Mehrzeilige Auswahl**: Halte **Ctrl+Alt** (oder **Cmd+Option** für MacOS) und verwende Pfeiltasten, um mehrere Zeilen auszuwählen +- **Mehrzeilige Einrückung**: Wähle mehrere Zeilen aus und verwende **Tab** zum Einrücken oder **Shift+Tab** zum Ausrücken ganzer Blöcke + +Dies ist besonders nützlich für: + +- Konsistentes Einrücken ganzer Process-Blöcke +- Gleichzeitiges Hinzufügen von Kommentaren zu mehreren Zeilen +- Bearbeiten ähnlicher Parameter-Definitionen über mehrere Processes hinweg + +### Zusammenfassung + +Du kannst sauberen, lesbaren Code mit automatischer Formatierung, Kommentierungsfunktionen, Code-Faltung, Klammer-Zuordnung und mehrzeiliger Bearbeitung pflegen, um komplexe Workflows effizient zu organisieren. + +### Was kommt als Nächstes? + +Lerne, wie VS Code mit deinem breiteren Entwicklungs-Workflow über das bloße Bearbeiten von Code hinaus integriert. + +--- + +## 7. Entwicklungs-Workflow-Integration + +VS Code integriert sich gut mit deinem Entwicklungs-Workflow über das bloße Bearbeiten von Code hinaus. + +### 7.1. Versionskontroll-Integration + +!!! note "Codespaces und Git-Integration" + + Wenn du in **GitHub Codespaces** arbeitest, funktionieren einige Git-Integrationsfunktionen möglicherweise nicht wie erwartet, insbesondere Tastaturkürzel für Source Control. Du hast möglicherweise auch während des ersten Setups abgelehnt, das Verzeichnis als Git-Repository zu öffnen, was für Trainingszwecke in Ordnung ist. + +Wenn dein Projekt ein Git-Repository ist (wie dieses), zeigt VS Code: + +- Geänderte Dateien mit farbigen Indikatoren +- Git-Status in der Statusleiste +- Inline-Diff-Ansichten +- Commit- und Push-Funktionen + +Öffne das Source Control-Panel mit der Source Control-Schaltfläche (![Source Control-Symbol](img/source_control_icon.png)) (`Ctrl+Shift+G` oder `Cmd+Shift+G`, wenn du lokal mit VSCode arbeitest), um Git-Änderungen zu sehen und Commits direkt im Editor zu stagen. + +![Source Control-Panel](img/source_control.png) + +### 7.2. Workflows ausführen und inspizieren + +Lass uns einen Workflow ausführen und dann die Ergebnisse inspizieren. Im integrierten Terminal (`Ctrl+Shift+` Backtick in Windows und MacOS) führe den einfachen Workflow aus: + +```bash title="Führe den einfachen Workflow aus" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Während der Workflow läuft, siehst du Echtzeit-Ausgaben im Terminal. Nach Abschluss kannst du VS Code verwenden, um Ergebnisse zu inspizieren, ohne deinen Editor zu verlassen: + +1. **Navigiere zu work-Verzeichnissen**: Verwende den Datei-Explorer oder das Terminal, um `.nextflow/work` zu durchsuchen +2. **Öffne Log-Dateien**: Klicke auf Log-Dateipfade in der Terminal-Ausgabe, um sie direkt in VS Code zu öffnen +3. **Inspiziere Ausgaben**: Durchsuche veröffentlichte Ergebnisverzeichnisse im Datei-Explorer +4. **Zeige Ausführungsberichte an**: Öffne HTML-Berichte direkt in VS Code oder deinem Browser + +Dies hält alles an einem Ort, anstatt zwischen mehreren Anwendungen zu wechseln. + +### Zusammenfassung + +Du kannst VS Code mit Versionskontrolle und Workflow-Ausführung integrieren, um deinen gesamten Entwicklungsprozess von einer einzigen Oberfläche aus zu verwalten. + +### Was kommt als Nächstes? + +Sieh, wie all diese IDE-Features in deinem täglichen Entwicklungs-Workflow zusammenarbeiten. + +--- + +## 8. Zusammenfassung und Schnellnotizen + +Hier sind einige Schnellnotizen zu jedem der oben besprochenen IDE-Features: + +### 8.1. Starten eines neuen Features + +1. **Schnelles Datei-Öffnen** (`Ctrl+P` oder `Cmd+P`), um relevante existierende Module zu finden +2. **Split-Editor**, um ähnliche Processes nebeneinander anzuzeigen +3. **Symbol-Navigation** (`Ctrl+Shift+O` oder `Cmd+Shift+O`), um die Dateistruktur zu verstehen +4. **Auto-Vervollständigung**, um neuen Code schnell zu schreiben + +### 8.2. Debugging von Problemen + +1. **Problems-Panel** (`Ctrl+Shift+M` oder `Cmd+Shift+M`), um alle Fehler auf einmal zu sehen +2. **Gehe zu Definition** (`Ctrl-Klick` oder `Cmd-Klick`), um Process-Interfaces zu verstehen +3. **Alle Referenzen finden**, um zu sehen, wie Processes verwendet werden +4. **Projektweite Suche**, um ähnliche Muster oder Probleme zu finden + +### 8.3. Refactoring und Verbesserung + +1. **Projektweite Suche** (`Ctrl+Shift+F` oder `Cmd+Shift+F`), um Muster zu finden +2. **Auto-Formatierung** (`Shift+Alt+F` oder `Shift+Option+F`), um Konsistenz zu wahren +3. **Code-Faltung**, um dich auf Struktur zu konzentrieren +4. **Git-Integration**, um Änderungen zu verfolgen + +--- + +## Zusammenfassung + +Du hast jetzt eine Schnelltour durch die IDE-Features von VS Code für Nextflow-Entwicklung erhalten. Diese Tools werden dich deutlich produktiver machen, indem sie: + +- **Fehler reduzieren** durch Echtzeit-Syntaxprüfung +- **Entwicklung beschleunigen** mit intelligenter Auto-Vervollständigung +- **Navigation verbessern** in komplexen Multi-Datei-Workflows +- **Qualität erhalten** durch konsistente Formatierung +- **Verständnis verbessern** durch erweitertes Highlighting und Strukturvisualisierung + +Wir erwarten nicht, dass du dich an alles erinnerst, aber jetzt weißt du, dass diese Features existieren, und du wirst sie finden können, wenn du sie brauchst. Während du weiterhin Nextflow-Workflows entwickelst, werden diese IDE-Features zur zweiten Natur, sodass du dich auf das Schreiben von hochwertigem Code konzentrieren kannst, anstatt mit Syntax und Struktur zu ringen. + +### Was kommt als Nächstes? + +Wende diese IDE-Fähigkeiten an, während du andere Trainingsmodule durcharbeitest, zum Beispiel: + +- **[nf-test](nf-test.md)**: Erstelle umfassende Test-Suites für deine Workflows +- **[Hello nf-core](../../hello_nf-core/)**: Erstelle produktionsreife Pipelines mit Community-Standards + +Die wahre Kraft dieser IDE-Features zeigt sich, wenn du an größeren, komplexeren Projekten arbeitest. Beginne damit, sie schrittweise in deinen Workflow zu integrieren - innerhalb weniger Sessions werden sie zur zweiten Natur werden und transformieren, wie du an Nextflow-Entwicklung herangehst. + +Vom Erkennen von Fehlern, bevor sie dich verlangsamen, bis zum einfachen Navigieren in komplexen Codebasen - diese Tools werden dich zu einem selbstbewussteren und effizienteren Entwickler machen. + +Frohes Coden! diff --git a/docs/de/docs/side_quests/essential_scripting_patterns.md b/docs/de/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..1f155308d9 --- /dev/null +++ b/docs/de/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1080 @@ +# Wesentliche Nextflow-Skriptmuster + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow ist eine Programmiersprache, die auf der Java Virtual Machine läuft. Obwohl Nextflow auf [Groovy](http://groovy-lang.org/) basiert und viel von dessen Syntax teilt, ist Nextflow mehr als nur „Groovy mit Erweiterungen" – es ist eine eigenständige Sprache mit einer vollständig spezifizierten [Syntax](https://nextflow.io/docs/latest/reference/syntax.html) und [Standardbibliothek](https://nextflow.io/docs/latest/reference/stdlib.html). + +Du kannst viel Nextflow schreiben, ohne über die grundlegende Syntax für Variablen, Maps und Listen hinauszugehen. Die meisten Nextflow-Tutorials konzentrieren sich auf die Workflow-Orchestrierung (Channels, Prozesse und Datenfluss), und damit kommst du überraschend weit. + +Wenn du jedoch Daten manipulieren, komplexe Dateinamen parsen, bedingte Logik implementieren oder robuste Produktions-Workflows erstellen musst, hilft es, zwei verschiedene Aspekte deines Codes zu betrachten: **Dataflow** (Channels, Operatoren, Prozesse und Workflows) und **Scripting** (der Code innerhalb von Closures, Funktionen und Prozess-Scripts). Obwohl diese Unterscheidung etwas willkürlich ist – es ist alles Nextflow-Code – bietet sie ein nützliches mentales Modell, um zu verstehen, wann du deinen Pipeline orchestrierst und wann du Daten manipulierst. Die Beherrschung beider Aspekte verbessert deine Fähigkeit, klare, wartbare Workflows zu schreiben, dramatisch. + +### Lernziele + +Dieses Side Quest führt dich von grundlegenden Konzepten zu produktionsreifen Mustern. +Wir werden einen einfachen CSV-lesenden Workflow in einen ausgefeilten Bioinformatik-Pipeline verwandeln und ihn Schritt für Schritt durch realistische Herausforderungen weiterentwickeln: + +- **Grenzen verstehen:** Unterscheide zwischen Dataflow-Operationen und Scripting und verstehe, wie sie zusammenarbeiten +- **Datenmanipulation:** Extrahiere, transformiere und wähle Maps und Collections mit leistungsstarken Operatoren aus +- **String-Verarbeitung:** Parse komplexe Dateibenennungsschemata mit Regex-Mustern und meistere Variable Interpolation +- **Wiederverwendbare Funktionen:** Extrahiere komplexe Logik in benannte Funktionen für sauberere, wartbarere Workflows +- **Dynamische Logik:** Erstelle Prozesse, die sich an verschiedene Eingabetypen anpassen, und verwende Closures für dynamische Ressourcenzuweisung +- **Bedingtes Routing:** Route Proben intelligent durch verschiedene Prozesse basierend auf ihren Metadaten-Eigenschaften +- **Sichere Operationen:** Gehe mit fehlenden Daten elegant um mit Null-Safe-Operatoren und validiere Eingaben mit klaren Fehlermeldungen +- **Konfigurationsbasierte Handler:** Verwende Workflow-Event-Handler für Logging, Benachrichtigungen und Lifecycle-Management + +### Voraussetzungen + +Bevor du dieses Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md) Tutorial oder einen gleichwertigen Anfängerkurs abgeschlossen haben. +- Dich wohl fühlen mit grundlegenden Nextflow-Konzepten und -Mechanismen (Prozesse, Channels, Operatoren, Arbeiten mit Dateien, Metadaten) +- Grundlegende Vertrautheit mit gängigen Programmierkonstrukten haben (Variablen, Maps, Listen) + +Dieses Tutorial wird Programmierkonzepte erklären, sobald wir auf sie stoßen, du brauchst also keine umfangreiche Programmiererfahrung. +Wir beginnen mit grundlegenden Konzepten und bauen zu fortgeschrittenen Mustern auf. + +--- + +## 0. Los geht's + +#### Öffne den Training-Codespace + +Falls noch nicht geschehen, stelle sicher, dass du die Trainingsumgebung wie in [Environment Setup](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Überprüfe die Materialien + +Du findest eine Haupt-Workflow-Datei und ein `data`-Verzeichnis mit Beispieldateien. + +```console title="Verzeichnisinhalt" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Unsere Beispiel-CSV enthält Informationen über biologische Proben, die je nach ihren Eigenschaften unterschiedlich verarbeitet werden müssen: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Wir werden diesen realistischen Datensatz verwenden, um praktische Programmiertechniken zu erkunden, denen du in echten Bioinformatik-Workflows begegnen wirst. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Überprüfe die Aufgabe --> + +#### Bereitschafts-Checkliste + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace ist betriebsbereit +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend gesetzt +<!-- - [ ] Ich verstehe die Aufgabe --> + +Wenn du alle Kästchen ankreuzen kannst, kann's losgehen. + +--- + +## 1. Dataflow vs Scripting: Die Grenzen verstehen + +### 1.1. Identifizieren, was was ist + +Beim Schreiben von Nextflow-Workflows ist es wichtig, zwischen **Dataflow** (wie Daten durch Channels und Prozesse fließen) und **Scripting** (der Code, der Daten manipuliert und Entscheidungen trifft) zu unterscheiden. Lass uns einen Workflow erstellen, der zeigt, wie sie zusammenarbeiten. + +#### 1.1.1. Grundlegender Nextflow-Workflow + +Beginne mit einem einfachen Workflow, der nur die CSV-Datei liest (wir haben das bereits für dich in `main.nf` erledigt): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +Der `workflow`-Block definiert unsere Pipeline-Struktur, während `channel.fromPath()` einen Channel aus einem Dateipfad erstellt. Der `.splitCsv()`-Operator verarbeitet die CSV-Datei und konvertiert jede Zeile in eine Map-Datenstruktur. + +Führe diesen Workflow aus, um die rohen CSV-Daten zu sehen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Den Map-Operator hinzufügen + +Jetzt werden wir Scripting hinzufügen, um die Daten zu transformieren, mit dem `.map()`-Operator, den du wahrscheinlich bereits kennst. Dieser Operator nimmt eine 'Closure', in der wir Code schreiben können, um jedes Element zu transformieren. + +!!! note + + Eine **Closure** ist ein Codeblock, der herumgereicht und später ausgeführt werden kann. Denke daran wie an eine Funktion, die du inline definierst. Closures werden mit geschweiften Klammern `{ }` geschrieben und können Parameter annehmen. Sie sind grundlegend dafür, wie Nextflow-Operatoren funktionieren, und wenn du schon eine Weile Nextflow schreibst, hast du sie vielleicht bereits verwendet, ohne es zu merken! + +So sieht diese Map-Operation aus: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +Das ist unsere erste **Closure** – eine anonyme Funktion, die du als Argument übergeben kannst (ähnlich wie Lambdas in Python oder Arrow Functions in JavaScript). Closures sind essentiell für die Arbeit mit Nextflow-Operatoren. + +Die Closure `{ row -> return row }` nimmt einen Parameter `row` (könnte auch anders heißen: `item`, `sample`, etc.). + +Wenn der `.map()`-Operator jedes Channel-Element verarbeitet, übergibt er dieses Element an deine Closure. Hier enthält `row` jeweils eine CSV-Zeile. + +Wende diese Änderung an und führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +Du siehst die gleiche Ausgabe wie zuvor, weil wir einfach die Eingabe unverändert zurückgeben. Das bestätigt, dass der Map-Operator korrekt funktioniert. Jetzt fangen wir an, die Daten zu transformieren. + +#### 1.1.3. Eine Map-Datenstruktur erstellen + +Jetzt schreiben wir **Scripting**-Logik innerhalb unserer Closure, um jede Datenzeile zu transformieren. Hier verarbeiten wir einzelne Datenelemente, anstatt den Datenfluss zu orchestrieren. + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting für Datentransformation + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +Die `sample_meta`-Map ist eine Schlüssel-Wert-Datenstruktur (wie Dictionaries in Python, Objekte in JavaScript oder Hashes in Ruby), die verwandte Informationen speichert: Proben-ID, Organismus, Gewebetyp, Sequenzierungstiefe und Qualitätswert. + +Wir verwenden String-Manipulationsmethoden wie `.toLowerCase()` und `.replaceAll()`, um unsere Daten zu bereinigen, und Typkonvertierungsmethoden wie `.toInteger()` und `.toDouble()`, um String-Daten aus der CSV in die entsprechenden numerischen Typen zu konvertieren. + +Wende diese Änderung an und führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Bedingte Logik hinzufügen + +Jetzt fügen wir mehr Scripting hinzu – diesmal mit einem ternären Operator, um Entscheidungen basierend auf Datenwerten zu treffen. + +Nimm die folgende Änderung vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +Der ternäre Operator ist eine Kurzform für ein if/else-Statement, das dem Muster `Bedingung ? Wert_wenn_wahr : Wert_wenn_falsch` folgt. Diese Zeile bedeutet: „Wenn die Qualität größer als 40 ist, verwende 'high', ansonsten verwende 'normal'". Sein Cousin, der **Elvis-Operator** (`?:`), liefert Standardwerte, wenn etwas null oder leer ist – wir werden dieses Muster später in diesem Tutorial erkunden. + +Der Map-Additions-Operator `+` erstellt eine **neue Map**, anstatt die bestehende zu modifizieren. Diese Zeile erstellt eine neue Map, die alle Schlüssel-Wert-Paare von `sample_meta` plus den neuen `priority`-Schlüssel enthält. + +!!! Note + + Modifiziere niemals Maps, die in Closures übergeben werden – erstelle immer neue mit `+` (zum Beispiel). In Nextflow fließen die gleichen Daten oft gleichzeitig durch mehrere Operationen. Das In-Place-Modifizieren einer Map kann unvorhersehbare Nebeneffekte verursachen, wenn andere Operationen auf dasselbe Objekt verweisen. Das Erstellen neuer Maps stellt sicher, dass jede Operation ihre eigene saubere Kopie hat. + +Führe den geänderten Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Wir haben erfolgreich bedingte Logik hinzugefügt, um unsere Metadaten mit einer Prioritätsstufe basierend auf Qualitätswerten anzureichern. + +#### 1.1.5. Maps mit `.subMap()` aufteilen + +Während der `+`-Operator Schlüssel zu einer Map hinzufügt, musst du manchmal das Gegenteil tun – nur bestimmte Schlüssel extrahieren. Die `.subMap()`-Methode ist dafür perfekt. + +Fügen wir eine Zeile hinzu, um eine vereinfachte Version unserer Metadaten zu erstellen, die nur Identifikationsfelder enthält: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting für Datentransformation + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Nur ID-Felder: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting für Datentransformation + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Führe den geänderten Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Nur ID-Felder: [id:sample_001, organism:human, tissue:liver] + Nur ID-Felder: [id:sample_002, organism:mouse, tissue:brain] + Nur ID-Felder: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Dies zeigt sowohl die vollständigen Metadaten, die durch die `view()`-Operation angezeigt werden, als auch die extrahierte Teilmenge, die wir mit `println` ausgegeben haben. + +Die `.subMap()`-Methode nimmt eine Liste von Schlüsseln und gibt eine neue Map zurück, die nur diese Schlüssel enthält. Wenn ein Schlüssel in der ursprünglichen Map nicht existiert, wird er einfach nicht im Ergebnis enthalten. + +Dies ist besonders nützlich, wenn du verschiedene Metadaten-Versionen für verschiedene Prozesse erstellen musst – manche benötigen möglicherweise vollständige Metadaten, während andere nur minimale Identifikationsfelder brauchen. + +Entferne jetzt diese println-Anweisungen, um deinen Workflow in seinen vorherigen Zustand zurückzuversetzen, da wir sie nicht mehr brauchen. + +!!! tip "Zusammenfassung Map-Operationen" + + - **Schlüssel hinzufügen**: `map1 + [new_key: value]` - Erstellt neue Map mit zusätzlichen Schlüsseln + - **Schlüssel extrahieren**: `map1.subMap(['key1', 'key2'])` - Erstellt neue Map mit nur angegebenen Schlüsseln + - **Beide Operationen erstellen neue Maps** - Ursprüngliche Maps bleiben unverändert + +#### 1.1.6. Maps kombinieren und Ergebnisse zurückgeben + +Bisher haben wir nur das zurückgegeben, was die Nextflow-Community die 'Meta-Map' nennt, und wir haben die Dateien ignoriert, auf die sich diese Metadaten beziehen. Aber wenn du Nextflow-Workflows schreibst, möchtest du wahrscheinlich etwas mit diesen Dateien machen. + +Lass uns eine Channel-Struktur ausgeben, die aus einem Tupel von 2 Elementen besteht: der angereicherten Metadaten-Map und dem entsprechenden Dateipfad. Dies ist ein gängiges Muster in Nextflow zum Übergeben von Daten an Prozesse. + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Wende diese Änderung an und führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Diese `[meta, file]`-Tupel-Struktur ist ein gängiges Muster in Nextflow zum Übergeben von Metadaten und zugehörigen Dateien an Prozesse. + +!!! note + + **Maps und Metadaten**: Maps sind grundlegend für die Arbeit mit Metadaten in Nextflow. Für eine detailliertere Erklärung zum Arbeiten mit Metadaten-Maps siehe das [Working with metadata](./metadata.md) Side Quest. + +Unser Workflow demonstriert das Kernmuster: **Dataflow-Operationen** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orchestrieren, wie Daten durch die Pipeline fließen, während **Scripting** (Maps `[key: value]`, String-Methoden, Typkonvertierungen, ternäre Operatoren) innerhalb der `.map()`-Closure die Transformation einzelner Datenelemente übernimmt. + +### 1.2. Verschiedene Typen verstehen: Channel vs List + +Bis jetzt gut, wir können zwischen Dataflow-Operationen und Scripting unterscheiden. Aber was ist, wenn derselbe Methodenname in beiden Kontexten existiert? + +Ein perfektes Beispiel ist die `collect`-Methode, die sowohl für Channel-Typen als auch für List-Typen in der Nextflow-Standardbibliothek existiert. Die `collect()`-Methode auf einer List transformiert jedes Element, während der `collect()`-Operator auf einem Channel alle Channel-Emissionen in einem Single-Item-Channel sammelt. + +Lass uns dies mit einigen Beispieldaten demonstrieren, beginnend mit einer Auffrischung, was der Channel-`collect()`-Operator macht. Schau dir `collect.nf` an: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - gruppiert mehrere Channel-Emissionen zu einer +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Einzelnes Channel-Element: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "channel.collect() Ergebnis: ${list} (${list.size()} Elemente zu 1 gruppiert)" } +``` + +Schritte: + +- Definiere eine List von Proben-IDs +- Erstelle einen Channel mit `fromList()`, der jede Proben-ID separat emittiert +- Gib jedes Element mit `view()` aus, während es durchfließt +- Sammle alle Elemente in eine einzelne Liste mit dem Channel-`collect()`-Operator +- Gib das gesammelte Ergebnis (einzelnes Element, das alle Proben-IDs enthält) mit einem zweiten `view()` aus + +Wir haben die Struktur des Channels geändert, aber wir haben die Daten selbst nicht geändert. + +Führe den Workflow aus, um dies zu bestätigen: + +```bash +nextflow run collect.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Einzelnes Channel-Element: sample_001 + Einzelnes Channel-Element: sample_002 + Einzelnes Channel-Element: sample_003 + channel.collect() Ergebnis: [sample_001, sample_002, sample_003] (3 Elemente zu 1 gruppiert) + ``` + +`view()` gibt eine Ausgabe für jede Channel-Emission zurück, also wissen wir, dass diese einzelne Ausgabe alle 3 ursprünglichen Elemente gruppiert in eine Liste enthält. + +Jetzt lass uns die `collect`-Methode auf einer List in Aktion sehen. Modifiziere `collect.nf`, um die List-`collect`-Methode auf die ursprüngliche Liste der Proben-IDs anzuwenden: + +=== "Nachher" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - gruppiert mehrere Channel-Emissionen zu einer + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Einzelnes Channel-Element: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() Ergebnis: ${list} (${list.size()} Elemente zu 1 gruppiert)" } + + // List.collect() - transformiert jedes Element, erhält Struktur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() Ergebnis: ${formatted_ids} (${sample_ids.size()} Elemente in ${formatted_ids.size()} transformiert)" + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - gruppiert mehrere Channel-Emissionen zu einer + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Einzelnes Channel-Element: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() Ergebnis: ${list} (${list.size()} Elemente zu 1 gruppiert)" } + ``` + +In diesem neuen Snippet: + +- Definieren wir eine neue Variable `formatted_ids`, die die List-`collect`-Methode verwendet, um jede Proben-ID in der ursprünglichen Liste zu transformieren +- Geben das Ergebnis mit `println` aus + +Führe den geänderten Workflow aus: + +```bash +nextflow run collect.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + List.collect() Ergebnis: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 Elemente in 3 transformiert) + Einzelnes Channel-Element: sample_001 + Einzelnes Channel-Element: sample_002 + Einzelnes Channel-Element: sample_003 + channel.collect() Ergebnis: [sample_001, sample_002, sample_003] (3 Elemente zu 1 gruppiert) + ``` + +Diesmal haben wir NICHT die Struktur der Daten geändert, wir haben immer noch 3 Elemente in der Liste, aber wir HABEN jedes Element mit der List-`collect`-Methode transformiert, um eine neue Liste mit modifizierten Werten zu erzeugen. Dies ist ähnlich wie die Verwendung des `map`-Operators auf einem Channel, aber es arbeitet auf einer List-Datenstruktur anstatt einem Channel. + +`collect` ist ein Extremfall, den wir hier verwenden, um einen Punkt zu machen. Die Kernlektion ist, dass du beim Schreiben von Workflows immer zwischen **Datenstrukturen** (Lists, Maps, etc.) und **Channels** (Dataflow-Konstrukten) unterscheiden solltest. Operationen können Namen teilen, verhalten sich aber völlig unterschiedlich, je nachdem, auf welchem Typ sie aufgerufen werden. + +### 1.3. Der Spread-Operator (`*.`) - Kurzform für Eigenschaftsextraktion + +Verwandt mit der List-`collect`-Methode ist der Spread-Operator (`*.`), der eine prägnante Möglichkeit bietet, Eigenschaften aus Collections zu extrahieren. Es ist im Wesentlichen syntaktischer Zucker für ein gängiges `collect`-Muster. + +Fügen wir eine Demonstration zu unserer `collect.nf`-Datei hinzu: + +=== "Nachher" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - gruppiert mehrere Channel-Emissionen zu einer + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Einzelnes Channel-Element: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() Ergebnis: ${list} (${list.size()} Elemente zu 1 gruppiert)" } + + // List.collect() - transformiert jedes Element, erhält Struktur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() Ergebnis: ${formatted_ids} (${sample_ids.size()} Elemente in ${formatted_ids.size()} transformiert)" + + // Spread-Operator - prägnanter Eigenschaftszugriff + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Spread-Operator Ergebnis: ${all_ids}" + ``` + +=== "Vorher" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - gruppiert mehrere Channel-Emissionen zu einer + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Einzelnes Channel-Element: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() Ergebnis: ${list} (${list.size()} Elemente zu 1 gruppiert)" } + + // List.collect() - transformiert jedes Element, erhält Struktur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() Ergebnis: ${formatted_ids} (${sample_ids.size()} Elemente in ${formatted_ids.size()} transformiert)" + ``` + +Führe den aktualisierten Workflow aus: + +```bash title="Spread-Operator testen" +nextflow run collect.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + List.collect() Ergebnis: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 Elemente in 3 transformiert) + Spread-Operator Ergebnis: [s1, s2, s3] + Einzelnes Channel-Element: sample_001 + Einzelnes Channel-Element: sample_002 + Einzelnes Channel-Element: sample_003 + channel.collect() Ergebnis: [sample_001, sample_002, sample_003] (3 Elemente zu 1 gruppiert) + ``` + +Der Spread-Operator `*.` ist eine Kurzform für ein gängiges Collect-Muster: + +```groovy +// Diese sind äquivalent: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Funktioniert auch mit Methodenaufrufen: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +Der Spread-Operator ist besonders nützlich, wenn du eine einzelne Eigenschaft aus einer Liste von Objekten extrahieren musst – er ist lesbarer als das Ausschreiben der vollständigen `collect`-Closure. + +!!! tip "Wann Spread vs Collect verwenden" + + - **Verwende Spread (`*.`)** für einfachen Eigenschaftszugriff: `samples*.id`, `files*.name` + - **Verwende collect** für Transformationen oder komplexe Logik: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Fazit + +In diesem Abschnitt hast du gelernt: + +- **Dataflow vs Scripting**: Channel-Operatoren orchestrieren, wie Daten durch deine Pipeline fließen, während Scripting einzelne Datenelemente transformiert +- **Typen verstehen**: Derselbe Methodenname (wie `collect`) kann sich je nach Typ, auf dem er aufgerufen wird, unterschiedlich verhalten (Channel vs List) +- **Kontext ist wichtig**: Sei dir immer bewusst, ob du mit Channels (Dataflow) oder Datenstrukturen (Scripting) arbeitest + +Das Verstehen dieser Grenzen ist essentiell für Debugging, Dokumentation und das Schreiben wartbarer Workflows. + +Als Nächstes tauchen wir tiefer in String-Verarbeitungsfähigkeiten ein, die essentiell für den Umgang mit realen Daten sind. + +--- + +## 2. String-Verarbeitung und dynamische Script-Generierung + +Die Beherrschung der String-Verarbeitung unterscheidet brüchige Workflows von robusten Pipelines. Dieser Abschnitt behandelt das Parsen komplexer Dateinamen, dynamische Script-Generierung und Variable Interpolation. + +### 2.1. Pattern Matching und reguläre Ausdrücke + +Bioinformatik-Dateien haben oft komplexe Namenskonventionen, die Metadaten kodieren. Lass uns dies automatisch mit Pattern Matching und regulären Ausdrücken extrahieren. + +Wir kehren zu unserem `main.nf`-Workflow zurück und fügen etwas Pattern-Matching-Logik hinzu, um zusätzliche Probeninformationen aus Dateinamen zu extrahieren. Die FASTQ-Dateien in unserem Datensatz folgen Illumina-Namenskonventionen mit Namen wie `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Diese mögen kryptisch aussehen, aber sie kodieren tatsächlich nützliche Metadaten wie Proben-ID, Lane-Nummer und Read-Richtung. Wir werden Regex-Fähigkeiten verwenden, um diese Namen zu parsen. + +Nimm die folgende Änderung an deinem bestehenden `main.nf`-Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Scripting für Datentransformation + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Scripting für Datentransformation + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Dies demonstriert wichtige **String-Verarbeitungskonzepte**: + +1. **Reguläre Ausdrucks-Literale** mit `~/pattern/`-Syntax - dies erstellt ein Regex-Muster ohne die Notwendigkeit, Backslashes zu escapen +2. **Pattern Matching** mit dem `=~`-Operator - dies versucht, einen String gegen ein Regex-Muster zu matchen +3. **Matcher-Objekte**, die Gruppen mit `[0][1]`, `[0][2]`, etc. erfassen - `[0]` bezieht sich auf den gesamten Match, `[1]`, `[2]`, etc. beziehen sich auf erfasste Gruppen in Klammern + +Lass uns das Regex-Muster `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$` aufschlüsseln: + +| Muster | Passt | Erfasst | +| ------------------- | ------------------------------------------ | -------------------------------------- | +| `^(.+)` | Probenname vom Anfang | Gruppe 1: Probenname | +| `_S(\d+)` | Probennummer `_S1`, `_S2`, etc. | Gruppe 2: Probennummer | +| `_L(\d{3})` | Lane-Nummer `_L001` | Gruppe 3: Lane (3 Ziffern) | +| `_(R[12])` | Read-Richtung `_R1` oder `_R2` | Gruppe 4: Read-Richtung | +| `_(\d{3})` | Chunk-Nummer `_001` | Gruppe 5: Chunk (3 Ziffern) | +| `\.fastq(?:\.gz)?$` | Dateierweiterung `.fastq` oder `.fastq.gz` | Nicht erfasst (?: ist nicht erfassend) | + +Dies parst Illumina-Namenskonventionen, um Metadaten automatisch zu extrahieren. + +Führe den geänderten Workflow aus: + +```bash title="Pattern Matching testen" +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Dies zeigt die Metadaten, die aus den Dateinamen angereichert wurden. + +### 2.2. Dynamische Script-Generierung in Prozessen + +Prozess-Script-Blöcke sind im Wesentlichen mehrzeilige Strings, die an die Shell übergeben werden. Du kannst **bedingte Logik** (if/else, ternäre Operatoren) verwenden, um dynamisch verschiedene Script-Strings basierend auf Eingabe-Eigenschaften zu generieren. Dies ist essentiell für den Umgang mit verschiedenen Eingabetypen – wie Single-End vs Paired-End-Sequenzierungs-Reads – ohne Prozessdefinitionen zu duplizieren. + +Fügen wir einen Prozess zu unserem Workflow hinzu, der dieses Muster demonstriert. Öffne `modules/fastp.nf` und schau dir das an: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Der Prozess nimmt FASTQ-Dateien als Eingabe und führt das `fastp`-Tool aus, um Adapter zu trimmen und Reads niedriger Qualität zu filtern. Leider hat die Person, die diesen Prozess geschrieben hat, die Single-End-Reads nicht berücksichtigt, die wir in unserem Beispieldatensatz haben. Fügen wir ihn zu unserem Workflow hinzu und schauen, was passiert: + +Füge zuerst das Modul in der allerersten Zeile deines `main.nf`-Workflows ein: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Dann modifiziere den `workflow`-Block, um den `ch_samples`-Channel mit dem `FASTP`-Prozess zu verbinden: + +=== "Nachher" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Führe diesen geänderten Workflow aus: + +```bash +nextflow run main.nf +``` + +??? failure "Befehlsausgabe" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Du siehst, dass der Prozess versucht, `fastp` mit einem `null`-Wert für die zweite Eingabedatei auszuführen, was dazu führt, dass er fehlschlägt. Dies liegt daran, dass unser Datensatz Single-End-Reads enthält, aber der Prozess fest codiert ist, um Paired-End-Reads zu erwarten (zwei Eingabedateien gleichzeitig). + +Behebe dies, indem du bedingte Logik zum `FASTP`-Prozess-`script:`-Block hinzufügst. Ein if/else-Statement prüft die Anzahl der Read-Dateien und passt den Befehl entsprechend an. + +=== "Nachher" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Einfache Single-End vs Paired-End-Erkennung + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Jetzt kann der Workflow sowohl Single-End- als auch Paired-End-Reads elegant handhaben. Die bedingte Logik prüft die Anzahl der Eingabedateien und konstruiert den entsprechenden Befehl für `fastp`. Schauen wir, ob es funktioniert: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +Sieht gut aus! Wenn wir die tatsächlichen Befehle überprüfen, die ausgeführt wurden (passe für deinen Task-Hash an): + +```console title="Ausgeführte Befehle prüfen" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Können wir sehen, dass Nextflow korrekt den richtigen Befehl für Single-End-Reads ausgewählt hat: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Eine weitere häufige Verwendung dynamischer Script-Logik ist im [Nextflow for Science Genomics-Modul](../../nf4science/genomics/02_joint_calling) zu sehen. In diesem Modul kann der aufgerufene GATK-Prozess mehrere Eingabedateien annehmen, aber jede muss mit `-V` präfixiert werden, um eine korrekte Befehlszeile zu bilden. Der Prozess verwendet Scripting, um eine Collection von Eingabedateien (`all_gvcfs`) in die korrekten Befehlsargumente zu transformieren: + +```groovy title="Befehlszeilenmanipulation für GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Diese Muster der Verwendung von Scripting in Prozess-Script-Blöcken sind extrem leistungsfähig und können in vielen Szenarien angewendet werden – vom Umgang mit variablen Eingabetypen bis zum Erstellen komplexer Befehlszeilenargumente aus Datei-Collections, wodurch deine Prozesse wirklich an die vielfältigen Anforderungen realer Daten anpassbar werden. + +### 2.3. Variable Interpolation: Nextflow- und Shell-Variablen + +Prozess-Scripts mischen Nextflow-Variablen, Shell-Variablen und Command-Substitutions, jeweils mit unterschiedlicher Interpolations-Syntax. Die Verwendung der falschen Syntax verursacht Fehler. Lass uns diese mit einem Prozess erkunden, der einen Verarbeitungsbericht erstellt. + +Schau dir die Moduldatei `modules/generate_report.nf` an: + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Verarbeite ${reads}" > ${meta.id}_report.txt + echo "Probe: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Dieser Prozess schreibt einen einfachen Bericht mit der Proben-ID und dem Dateinamen. Lass uns ihn ausführen, um zu sehen, was passiert, wenn wir verschiedene Variablentypen mischen müssen. + +Füge den Prozess in deine `main.nf` ein und füge ihn zum Workflow hinzu: + +=== "Nachher" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def diff --git a/docs/de/docs/side_quests/ideas/containers.md b/docs/de/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..354b9bb52b --- /dev/null +++ b/docs/de/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Teil 1: Weitere Container + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Wie man Container Images findet oder erstellt + +Einige Softwareentwickler stellen Container Images für ihre Software bereit, die auf Container-Registries wie Docker Hub verfügbar sind, aber viele tun dies nicht. +In diesem optionalen Abschnitt zeigen wir dir zwei Möglichkeiten, wie du ein Container Image für Tools erhalten kannst, die du in deinen Nextflow Pipelines verwenden möchtest: die Verwendung von Seqera Containers und das selbstständige Erstellen des Container Images. + +Du wirst ein Container Image für das `quote` pip-Paket erhalten/erstellen, das in der Übung am Ende dieses Abschnitts verwendet wird. + +### 1.1. Ein Container Image von Seqera Containers erhalten + +Seqera Containers ist ein kostenloser Service, der Container Images für pip- und conda-installierbare Tools (einschließlich bioconda) erstellt. +Navigiere zu [Seqera Containers](https://www.seqera.io/containers/) und suche nach dem `quote` pip-Paket. + +![Seqera Containers](img/seqera-containers-1.png) + +Klicke auf „+Add" und dann auf „Get Container", um ein Container Image für das `quote` pip-Paket anzufordern. + +![Seqera Containers](img/seqera-containers-2.png) + +Wenn dies das erste Mal ist, dass ein Community-Container für diese Version des Pakets erstellt wird, kann es einige Minuten dauern, bis er fertiggestellt ist. +Klicke, um die URI (z. B. `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) des für dich erstellten Container Images zu kopieren. + +Du kannst nun das Container Image verwenden, um den `quote`-Befehl auszuführen und einen zufälligen Ausspruch von Grace Hopper zu erhalten. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Ausgabe: + +```console title="Ausgabe" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Das Container Image selbst erstellen + +Lass uns einige Build-Details von der Seqera Containers-Website verwenden, um das Container Image für das `quote` pip-Paket selbst zu erstellen. +Kehre zur Seqera Containers-Website zurück und klicke auf die Schaltfläche „Build Details". + +Das erste Element, das wir uns ansehen, ist das `Dockerfile`, eine Art Skript-Datei, die alle Befehle enthält, die zum Erstellen des Container Images benötigt werden. +Wir haben dem untenstehenden Dockerfile einige erklärende Kommentare hinzugefügt, um dir zu helfen zu verstehen, was jeder Teil macht. + +```Dockerfile title="Dockerfile" +# Starte vom micromamba-Basis-Docker-Image +FROM mambaorg/micromamba:1.5.10-noble +# Kopiere die Datei conda.yml in den Container +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Installiere verschiedene Utilities für Nextflow und die Pakete in der Datei conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Führe den Container als Root-Benutzer aus +USER root +# Setze die PATH-Umgebungsvariable, um das micromamba-Installationsverzeichnis einzuschließen +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +Das zweite Element, das wir uns ansehen, ist die Datei `conda.yml`, die die Liste der Pakete enthält, die im Container Image installiert werden müssen. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Kopiere den Inhalt dieser Dateien in die Stubs, die sich im Verzeichnis `containers/build` befinden, und führe dann den folgenden Befehl aus, um das Container Image selbst zu erstellen. + +!!! note "Hinweis" + + Wir verwenden das Flag `-t quote:latest`, um das Container Image mit dem Namen `quote` und dem Tag `latest` zu versehen. + Wir können diesen Tag verwenden, um uns auf das Container Image zu beziehen, wenn wir es auf diesem System ausführen. + +```bash +docker build -t quote:latest containers/build +``` + +Nachdem es fertig erstellt wurde, kannst du das gerade erstellte Container Image ausführen. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Zusammenfassung + +Du hast zwei verschiedene Möglichkeiten kennengelernt, ein Container Image für ein Tool zu erhalten, das du in deinen Nextflow Pipelines verwenden möchtest: die Verwendung von Seqera Containers und das selbstständige Erstellen des Container Images. + +### Wie geht es weiter? + +Du hast alles, was du brauchst, um mit dem [nächsten Kapitel](./04_hello_genomics.md) dieser Trainingsreihe fortzufahren. +Du kannst auch mit einer optionalen Übung fortfahren, um Zitate über Computer-/Biologie-Pioniere mit dem `quote`-Container abzurufen und sie mit dem `cowsay`-Container auszugeben. + +--- + +## 2. Lass die Kuh berühmte Wissenschaftler zitieren + +Dieser Abschnitt enthält einige zusätzliche Übungen, um das bisher Gelernte zu üben. +Die Durchführung dieser Übungen ist _nicht erforderlich_, um spätere Teile des Trainings zu verstehen, bietet aber eine unterhaltsame Möglichkeit, dein Wissen zu festigen, indem du herausfindest, wie du die Kuh berühmte Wissenschaftler zitieren lassen kannst. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Modifiziere das `hello-containers.nf`-Skript, um einen getQuote-Prozess zu verwenden + +Wir haben eine Liste von Computer- und Biologie-Pionieren in der Datei `containers/data/pioneers.csv`. +Auf hoher Ebene musst du für diese Übung Folgendes tun: + +- Modifiziere die Standard-`params.input_file`, um auf die Datei `pioneers.csv` zu verweisen. +- Erstelle einen `getQuote`-Prozess, der den `quote`-Container verwendet, um ein Zitat für jede Eingabe abzurufen. +- Verbinde die Ausgabe des `getQuote`-Prozesses mit dem `cowsay`-Prozess, um das Zitat anzuzeigen. + +Für das `quote`-Container Image kannst du entweder das verwenden, das du selbst in der vorherigen zusätzlichen Übung erstellt hast, oder das, das du von Seqera Containers erhalten hast. + +!!! tip "Tipp" + + Eine gute Wahl für den `script`-Block deines getQuote-Prozesses könnte sein: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Du findest eine Lösung für diese Übung in `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Modifiziere deine Nextflow-Pipeline, um sie im `quote`- und `sayHello`-Modus ausführen zu können. + +Füge deiner Pipeline etwas Verzweigungslogik hinzu, damit sie Eingaben akzeptieren kann, die sowohl für `quote` als auch für `sayHello` vorgesehen sind. +Hier ist ein Beispiel, wie man eine `if`-Anweisung in einem Nextflow Workflow verwendet: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "Tipp" + + Du kannst `new_ch = processName.out` verwenden, um der Ausgabe eines Prozesses einen Namen zuzuweisen. + +Du findest eine Lösung für diese Übung in `containers/solutions/hello-containers-4.2.nf`. + +### Zusammenfassung + +Du weißt, wie man Container in Nextflow verwendet, um Prozesse auszuführen, und wie man etwas Verzweigungslogik in deine Pipelines einbaut! + +### Wie geht es weiter? + +Feiere, mach eine Pause und trink etwas Wasser! + +Wenn du bereit bist, fahre mit Teil 3 dieser Trainingsreihe fort, um zu lernen, wie du das bisher Gelernte auf einen realistischeren Datenanalyse-Anwendungsfall anwenden kannst. diff --git a/docs/de/docs/side_quests/ideas/if_else.md b/docs/de/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..fa223b4760 --- /dev/null +++ b/docs/de/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Teil 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Lass die Kuh berühmte Wissenschaftler zitieren + +Dieser Abschnitt enthält einige zusätzliche Übungen, um das Gelernte zu vertiefen. +Diese Übungen sind _nicht erforderlich_, um spätere Teile des Trainings zu verstehen, bieten aber eine unterhaltsame Möglichkeit, deine Kenntnisse zu festigen, indem du herausfindest, wie du die Kuh berühmte Wissenschaftler zitieren lassen kannst. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Modifiziere das `hello-containers.nf`-Skript, um einen getQuote-Prozess zu verwenden + +Wir haben eine Liste von Computer- und Biologie-Pionieren in der Datei `containers/data/pioneers.csv`. +Auf hoher Ebene musst du für diese Übung: + +- Die Standard-`params.input_file` so ändern, dass sie auf die Datei `pioneers.csv` zeigt. +- Einen `getQuote`-Prozess erstellen, der den `quote`-Container verwendet, um für jede Eingabe ein Zitat abzurufen. +- Die Ausgabe des `getQuote`-Prozesses mit dem `cowsay`-Prozess verbinden, um das Zitat anzuzeigen. + +Für das `quote`-Container-Image kannst du entweder das verwenden, das du selbst in der vorherigen zusätzlichen Übung erstellt hast, oder das von Seqera Containers. + +!!! Hint + + Eine gute Wahl für den `script`-Block deines getQuote-Prozesses könnte sein: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Du findest eine Lösung für diese Übung in `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Modifiziere deine Nextflow-Pipeline, um sie in den Modi `quote` und `sayHello` ausführen zu können. + +Füge deiner Pipeline etwas Verzweigungslogik hinzu, um Eingaben sowohl für `quote` als auch für `sayHello` zu akzeptieren. +Hier ist ein Beispiel, wie du eine `if`-Anweisung in einem Nextflow-Workflow verwenden kannst: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + Du kannst `new_ch = processName.out` verwenden, um dem Ausgabe-Channel eines Prozesses einen Namen zuzuweisen. + +Du findest eine Lösung für diese Übung in `containers/solutions/hello-containers-4.2.nf`. + +### Zusammenfassung + +Du weißt jetzt, wie du Container in Nextflow verwendest, um Prozesse auszuführen, und wie du Verzweigungslogik in deine Pipelines einbaust! + +### Was kommt als Nächstes? + +Feiere, mach eine Pause und trink etwas Wasser! + +Wenn du bereit bist, fahre mit Teil 3 dieser Trainingsreihe fort, um zu lernen, wie du das bisher Gelernte auf einen realistischeren Datenanalyse-Anwendungsfall anwenden kannst. diff --git a/docs/de/docs/side_quests/index.md b/docs/de/docs/side_quests/index.md new file mode 100644 index 0000000000..c6d9201613 --- /dev/null +++ b/docs/de/docs/side_quests/index.md @@ -0,0 +1,38 @@ +# Side Quests + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dies ist eine Sammlung eigenständiger Mini-Kurse, die tiefer in spezifische Themen eintauchen. Du kannst sie in beliebiger Reihenfolge durchgehen. + +Lass uns loslegen! Klicke auf den Button „Open in GitHub Codespaces" unten, um die Trainingsumgebung zu starten (vorzugsweise in einem separaten Tab), und lies dann weiter, während sie lädt. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Voraussetzungen + +Die spezifischen Voraussetzungen jedes Mini-Kurses variieren und sind auf den entsprechenden Seiten dokumentiert. +Dennoch setzen sie alle ein minimales Verständnis der folgenden Punkte voraus: + +- Erfahrung mit der Kommandozeile +- Grundlegende Nextflow-Konzepte und -Werkzeuge, die im [Hello Nextflow](../../hello_nextflow/) Einsteiger-Trainingskurs behandelt werden. + +Für technische Anforderungen und die Einrichtung der Umgebung siehe den [Environment Setup](../../envsetup/) Mini-Kurs. + +**Wenn du zum ersten Mal in die Side Quests eintauchst, schau dir zuerst unbedingt die [Orientation](./orientation.md) Seite an!** + +Ansonsten wähle eine Side Quest aus der Tabelle unten aus. + +## Side Quests + +| Side Quest | Geschätzte Unterrichtszeit | +| -------------------------------------------------------------------------- | -------------------------- | +| [Nextflow development environment walkthrough](./ide_features.md) | 45 Min | +| [Essential Nextflow Scripting Patterns](./essential_scripting_patterns.md) | 90 Min | +| [Metadata in workflows](./metadata.md) | 45 Min | +| [Splitting and Grouping](./splitting_and_grouping.md) | 45 Min | +| [Testing with nf-test](./nf-test.md) | 1 Stunde | +| [Workflows of workflows](./workflows_of_workflows.md) | 30 Min | +| [Working with files](./working_with_files.md) | 45 Min | +| [Debugging workflows](./debugging.md) | 1 Stunde | + +Lass uns wissen, welche anderen Bereiche und Anwendungsfälle du hier gerne behandelt sehen würdest, indem du im [Training-Bereich](https://community.seqera.io/c/training/) des Community-Forums postest. diff --git a/docs/de/docs/side_quests/metadata.md b/docs/de/docs/side_quests/metadata.md new file mode 100644 index 0000000000..74ed676d24 --- /dev/null +++ b/docs/de/docs/side_quests/metadata.md @@ -0,0 +1,1135 @@ +# Metadaten und Meta-Maps + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bei jeder wissenschaftlichen Analyse arbeiten wir selten nur mit den reinen Datendateien. +Jede Datei kommt mit ihren eigenen zusätzlichen Informationen: was sie ist, woher sie stammt und was sie besonders macht. +Diese zusätzlichen Informationen nennen wir Metadaten. + +Metadaten sind Daten, die andere Daten beschreiben. +Metadaten verfolgen wichtige Details über Dateien und experimentelle Bedingungen und helfen dabei, Analysen auf die einzigartigen Eigenschaften jedes Datensatzes zuzuschneiden. + +Stell dir das wie einen Bibliothekskatalog vor: Während Bücher den eigentlichen Inhalt enthalten (Rohdaten), liefern die Katalogkarten wesentliche Informationen über jedes Buch – wann es veröffentlicht wurde, wer es geschrieben hat, wo man es findet (Metadaten). +In Nextflow-Pipelines können Metadaten verwendet werden, um: + +- Dateispezifische Informationen durch den gesamten Workflow hindurch zu verfolgen +- Prozesse basierend auf Dateimerkmalen zu konfigurieren +- Zusammengehörige Dateien für gemeinsame Analysen zu gruppieren + +### Lernziele + +In dieser Side Quest werden wir erkunden, wie man Metadaten in Workflows handhabt. +Ausgehend von einem einfachen Datenblatt (in der Bioinformatik oft als Samplesheet bezeichnet), das grundlegende Dateiinformationen enthält, wirst du lernen, wie man: + +- Dateimetadaten aus CSV-Dateien liest und verarbeitet +- Metadaten-Maps erstellt und manipuliert +- Neue Metadatenfelder während der Workflow-Ausführung hinzufügt +- Metadaten verwendet, um das Prozessverhalten anzupassen + +Diese Fähigkeiten helfen dir, robustere und flexiblere Pipelines zu erstellen, die komplexe Dateibeziehungen und Verarbeitungsanforderungen handhaben können. + +### Voraussetzungen + +Bevor du diese Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md)-Tutorial oder einen gleichwertigen Anfängerkurs abgeschlossen haben. +- Mit grundlegenden Nextflow-Konzepten und -Mechanismen vertraut sein (Prozesse, Channels, Operatoren) + +--- + +## 0. Erste Schritte + +#### Öffne den Training-Codespace + +Falls du es noch nicht getan hast, stelle sicher, dass du die Trainingsumgebung wie in der [Umgebungseinrichtung](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/metadata +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis fokussiert: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest eine Haupt-Workflow-Datei und ein `data`-Verzeichnis, das ein Datenblatt und eine Handvoll Datendateien enthält. + +??? abstract "Verzeichnisinhalt" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +Der Workflow in der `main.nf`-Datei ist ein Stub, den du schrittweise zu einem vollständig funktionierenden Workflow erweitern wirst. + +Das Datenblatt listet die Pfade zu den Datendateien und einige zugehörige Metadaten auf, organisiert in 3 Spalten: + +- `id`: selbsterklärend, eine ID, die der Datei zugewiesen wurde +- `character`: ein Charaktername, den wir später verwenden werden, um verschiedene Kreaturen zu zeichnen +- `data`: Pfade zu `.txt`-Dateien, die Begrüßungen in verschiedenen Sprachen enthalten + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Jede Datendatei enthält Begrüßungstext in einer von fünf Sprachen (fr: Französisch, de: Deutsch, es: Spanisch, it: Italienisch, en: Englisch). + +Wir stellen dir auch ein containerisiertes Sprachanalyse-Tool namens `langid` zur Verfügung. + +#### Überprüfe die Aufgabe + +Deine Herausforderung besteht darin, einen Nextflow-Workflow zu schreiben, der: + +1. Die Sprache in jeder Datei automatisch **identifiziert** +2. Dateien nach Sprachfamilie **gruppiert** (germanische vs. romanische Sprachen) +3. Die Verarbeitung für jede Datei basierend auf ihrer Sprache und Metadaten **anpasst** +4. Ausgaben nach Sprachgruppe **organisiert** + +Dies stellt ein typisches Workflow-Muster dar, bei dem dateispezifische Metadaten Verarbeitungsentscheidungen steuern; genau die Art von Problem, die Metadaten-Maps elegant lösen. + +#### Bereitschafts-Checkliste + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace ist aktiv +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend eingestellt +- [ ] Ich verstehe die Aufgabe + +Wenn du alle Kästchen abhaken kannst, kannst du loslegen. + +--- + +## 1. Metadaten aus einem Datenblatt laden + +Öffne die `main.nf`-Workflow-Datei, um den Workflow-Stub zu untersuchen, den wir dir als Ausgangspunkt geben. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Du siehst, dass wir eine grundlegende Channel-Factory eingerichtet haben, um das Beispiel-Datenblatt als Datei zu laden, aber das liest noch nicht den Inhalt der Datei ein. +Lass uns damit beginnen, das hinzuzufügen. + +### 1.1. Inhalt mit `splitCsv` einlesen + +Wir müssen einen Operator wählen, der den Dateiinhalt mit minimalem Aufwand unsererseits passend parst. +Da unser Datenblatt im CSV-Format vorliegt, ist dies ein Job für den [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv)-Operator, der jede Zeile in der Datei als Element im Channel lädt. + +Nimm die folgenden Änderungen vor, um eine `splitCsv()`-Operation zum Channel-Konstruktionscode hinzuzufügen, plus eine `view()`-Operation, um zu überprüfen, dass der Inhalt der Datei korrekt in den Channel geladen wird. + +=== "Nachher" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Beachte, dass wir die Option `header: true` verwenden, um Nextflow mitzuteilen, dass die erste Zeile der CSV-Datei die Header-Zeile ist. + +Lass uns schauen, was dabei herauskommt, ja? +Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Wir können sehen, dass der Operator eine Map von Schlüssel-Wert-Paaren für jede Zeile in der CSV-Datei erstellt hat, mit den Spaltenüberschriften als Schlüssel für die entsprechenden Werte. + +Jeder Map-Eintrag entspricht einer Spalte in unserem Datenblatt: + +- `id` +- `character` +- `recording` + +Das ist großartig! Es macht es einfach, auf spezifische Felder aus jeder Datei zuzugreifen. +Zum Beispiel könnten wir auf die Datei-ID mit `id` oder auf den txt-Dateipfad mit `recording` zugreifen. + +??? info "(Optional) Mehr über Maps" + + In Groovy, der Programmiersprache, auf der Nextflow aufbaut, ist eine Map eine Schlüssel-Wert-Datenstruktur ähnlich wie Dictionaries in Python, Objekte in JavaScript oder Hashes in Ruby. + + Hier ist ein ausführbares Skript, das zeigt, wie du eine Map definieren und auf ihren Inhalt zugreifen kannst: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Erstelle eine einfache Map + def my_map = [id:'sampleA', character:'squirrel'] + + // Gib die gesamte Map aus + println "map: ${my_map}" + + // Greife auf einzelne Werte mit Punkt-Notation zu + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Obwohl es keinen richtigen `workflow`-Block hat, kann Nextflow dies ausführen, als wäre es ein Workflow: + + ```bash + nextflow run examples/map_demo.nf + ``` + + Und hier ist, was du in der Ausgabe erwarten kannst: + + ```console title="Ausgabe" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Spezifische Felder mit `map` auswählen + +Nehmen wir an, wir möchten auf die `character`-Spalte aus dem Datenblatt zugreifen und sie ausgeben. +Wir können den Nextflow-`map`-Operator verwenden, um über jedes Element in unserem Channel zu iterieren und speziell den `character`-Eintrag aus dem Map-Objekt auszuwählen. + +Nimm die folgenden Änderungen am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Führe jetzt den Workflow erneut aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Erfolg! Wir haben die Map-Struktur aus unserem Datenblatt genutzt, um auf die Werte aus einzelnen Spalten für jede Zeile zuzugreifen. + +Jetzt, da wir das Datenblatt erfolgreich eingelesen haben und Zugriff auf die Daten in jeder Zeile haben, können wir beginnen, unsere Pipeline-Logik zu implementieren. + +### 1.3. Die Metadaten in einer 'Meta-Map' organisieren + +Im aktuellen Zustand des Workflows stehen die Eingabedateien (unter dem `recording`-Schlüssel) und die zugehörigen Metadaten (`id`, `character`) alle auf derselben Ebene, als wären sie alle in einem großen Beutel. +Die praktische Konsequenz ist, dass jeder Prozess, der diesen Channel konsumiert, mit dieser Struktur im Hinterkopf konfiguriert werden müsste: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +Das ist in Ordnung, solange sich die Anzahl der Spalten im Datenblatt nicht ändert. +Wenn du jedoch auch nur eine Spalte zum Datenblatt hinzufügst, wird die Form des Channels nicht mehr mit dem übereinstimmen, was der Prozess erwartet, und der Workflow wird Fehler produzieren. +Es macht den Prozess auch schwer mit anderen zu teilen, die möglicherweise leicht unterschiedliche Eingabedaten haben, und du musst möglicherweise Variablen in den Prozess hart codieren, die vom Script-Block nicht benötigt werden. + +Um dieses Problem zu vermeiden, müssen wir einen Weg finden, die Channel-Struktur konsistent zu halten, unabhängig davon, wie viele Spalten das Datenblatt enthält. + +Wir können das tun, indem wir alle Metadaten in einem Element innerhalb des Tupels sammeln, das wir die Metadaten-Map oder einfacher 'Meta-Map' nennen werden. + +Nimm die folgenden Änderungen an der `map`-Operation vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Wir haben unsere Channel-Elemente in ein Tupel umstrukturiert, das aus zwei Elementen besteht: der Meta-Map und dem entsprechenden Dateiobjekt. + +Lass uns den Workflow ausführen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console title="Meta-Map ansehen" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Jetzt enthält jedes Element im Channel zuerst die Metadaten-Map und zweitens das entsprechende Dateiobjekt: + +```console title="Beispiel-Ausgabestruktur" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +Als Ergebnis macht das Hinzufügen weiterer Spalten im Datenblatt mehr Metadaten in der `meta`-Map verfügbar, ändert aber nicht die Channel-Form. +Dies ermöglicht es uns, Prozesse zu schreiben, die den Channel konsumieren, ohne die Metadaten-Elemente in die Eingabespezifikation hart codieren zu müssen: + +```groovy title="Syntax-Beispiel" + input: + tuple val(meta), file(recording) +``` + +Dies ist eine weit verbreitete Konvention zur Organisation von Metadaten in Nextflow-Workflows. + +### Fazit + +In diesem Abschnitt hast du gelernt: + +- **Warum Metadaten wichtig sind:** Das Behalten von Metadaten bei deinen Daten bewahrt wichtige Dateiinformationen durch den gesamten Workflow hindurch. +- **Wie man Datenblätter einliest:** Verwendung von `splitCsv` zum Lesen von CSV-Dateien mit Header-Informationen und Umwandlung von Zeilen in strukturierte Daten +- **Wie man eine Meta-Map erstellt:** Trennung von Metadaten von Dateidaten unter Verwendung der Tupel-Struktur `[ [id:wert, ...], datei ]` + +--- + +## 2. Metadaten manipulieren + +Jetzt, da wir unsere Metadaten geladen haben, lass uns etwas damit machen! + +Wir werden ein Tool namens [`langid`](https://github.com/saffsd/langid.py) verwenden, um die Sprache zu identifizieren, die in der Aufnahmedatei jeder Kreatur enthalten ist. +Das Tool ist auf eine Reihe von Sprachen vortrainiert, und bei einem Textausschnitt gibt es eine Sprachvorhersage und einen zugehörigen Wahrscheinlichkeitswert aus, beide nach `stdout`. + +### 2.1. Importiere den Prozess und untersuche den Code + +Wir stellen dir ein vorgefertigtes Prozessmodul namens `IDENTIFY_LANGUAGE` zur Verfügung, das das `langid`-Tool umschließt, sodass du nur eine Include-Anweisung vor dem Workflow-Block hinzufügen musst. + +Nimm die folgende Änderung am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Du kannst die Moduldatei öffnen, um ihren Code zu untersuchen: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Verwende langid zur Vorhersage der Sprache jeder Eingabedatei +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Wie du sehen kannst, verwendet die Eingabedefinition dieselbe `tuple val(meta), path(file)`-Struktur, die wir gerade auf unseren Eingabe-Channel angewendet haben. + +Die Ausgabedefinition ist als Tupel mit einer ähnlichen Struktur wie die Eingabe strukturiert, außer dass sie auch `stdout` als drittes Element enthält. +Dieses `tuple val(meta), path(file), <output>`-Muster hält die Metadaten mit sowohl den Eingabedaten als auch den Ausgaben verbunden, während sie durch die Pipeline fließen. + +Beachte, dass wir hier Nextflows [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs)-Ausgabequalifizierer verwenden, weil das Tool seine Ausgabe direkt auf die Konsole ausgibt, anstatt eine Datei zu schreiben; und wir verwenden `sed` in der Befehlszeile, um den Wahrscheinlichkeitswert zu entfernen, die Zeichenkette durch Entfernen von Zeilenumbruchzeichen zu bereinigen und nur die Sprachvorhersage zurückzugeben. + +### 2.2. Füge einen Aufruf zu `IDENTIFY_LANGUAGE` hinzu + +Jetzt, da der Prozess dem Workflow zur Verfügung steht, können wir einen Aufruf zum `IDENTIFY_LANGUAGE`-Prozess hinzufügen, um ihn auf dem Daten-Channel auszuführen. + +Nimm die folgenden Änderungen am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Beachte, dass wir die ursprüngliche `.view()`-Operation in der Channel-Konstruktion entfernt haben. + +Wir können jetzt den Workflow ausführen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Ausgezeichnet! Wir haben jetzt eine Vorhersage darüber, welche Sprache jeder Charakter spricht. + +Und wie bereits erwähnt, haben wir auch die Eingabedatei und die Meta-Map in die Ausgabe aufgenommen, was bedeutet, dass beide mit den neuen Informationen verbunden bleiben, die wir gerade produziert haben. +Dies wird sich im nächsten Schritt als nützlich erweisen. + +!!! note + + Allgemeiner macht es dieses Muster, die Meta-Map mit Ergebnissen verbunden zu halten, einfacher, verwandte Ergebnisse zu verknüpfen, die dieselben Identifikatoren teilen. + + Wie du bereits gelernt hast, kannst du dich nicht auf die Reihenfolge der Elemente in Channels verlassen, um Ergebnisse über sie hinweg zuzuordnen. + Stattdessen musst du Schlüssel verwenden, um Daten korrekt zuzuordnen, und Meta-Maps bieten eine ideale Struktur für diesen Zweck. + + Wir untersuchen diesen Anwendungsfall detailliert in der Side Quest [Aufteilen & Gruppieren](./splitting_and_grouping.md). + +### 2.3. Erweitere Metadaten mit Prozessausgaben + +Da die Ergebnisse, die wir gerade produziert haben, selbst eine Form von Metadaten über den Inhalt der Dateien sind, wäre es nützlich, sie zu unserer Meta-Map hinzuzufügen. + +Allerdings wollen wir die bestehende Meta-Map nicht direkt modifizieren. +Aus technischer Sicht ist es _möglich_, das zu tun, aber es ist unsicher. + +Stattdessen erstellen wir eine neue Meta-Map, die den Inhalt der bestehenden Meta-Map plus ein neues `lang: lang_id`-Schlüssel-Wert-Paar enthält, das die neuen Informationen hält, unter Verwendung des `+`-Operators (eine Groovy-Funktion). +Und wir werden dies mit einer [`map`](https://www.nextflow.io/docs/latest/operator.html#map)-Operation kombinieren, um die alte Map durch die neue zu ersetzen. + +Hier sind die Änderungen, die du am Workflow vornehmen musst: + +=== "Nachher" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Wenn du mit dem `+`-Operator noch nicht vertraut bist oder wenn dies verwirrend erscheint, nimm dir ein paar Minuten Zeit, um die detaillierte Erklärung unten durchzugehen. + +??? info "Erstellung der neuen Meta-Map unter Verwendung des `+`-Operators" + + **Zuerst musst du wissen, dass wir den Inhalt von zwei Maps mit dem Groovy-Operator `+` zusammenführen können.** + + Nehmen wir an, wir haben die folgenden Maps: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Wir können sie so zusammenführen: + + ```groovy + new_map = map1 + map2 + ``` + + Der Inhalt von `new_map` wird sein: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Großartig! + + **Aber was ist, wenn du ein Feld hinzufügen musst, das noch nicht Teil einer Map ist?** + + Nehmen wir an, du beginnst wieder von `map1`, aber die Sprachvorhersage ist nicht in ihrer eigenen Map (es gibt kein `map2`). + Stattdessen wird sie in einer Variablen namens `lang_id` gehalten, und du weißt, dass du ihren Wert (`'fr'`) mit dem Schlüssel `lang` speichern möchtest. + + Du kannst tatsächlich folgendes tun: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Hier erstellt `[lang: new_info]` spontan eine neue unbenannte Map, und `map1 + ` führt `map1` mit der neuen unbenannten Map zusammen, wodurch der gleiche `new_map`-Inhalt wie zuvor entsteht. + + Praktisch, oder? + + **Lass uns das jetzt in den Kontext einer Nextflow `channel.map()`-Operation übertragen.** + + Der Code wird zu: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Dies macht folgendes: + + - `map1, lang_id ->` nimmt die zwei Elemente im Tupel + - `[map1 + [lang: lang_id]]` erstellt die neue Map wie oben detailliert + + Die Ausgabe ist eine einzelne unbenannte Map mit demselben Inhalt wie `new_map` in unserem obigen Beispiel. + Wir haben also effektiv transformiert: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + in: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Hoffentlich kannst du sehen, dass, wenn wir `map1` in `meta` ändern, das im Grunde alles ist, was wir brauchen, um die Sprachvorhersage zu unserer Meta-Map in unserem Workflow hinzuzufügen. + + Außer einer Sache! + + Im Fall unseres Workflows **müssen wir auch die Anwesenheit des `file`-Objekts im Tupel berücksichtigen**, das aus `meta, file, lang_id` besteht. + + Also würde der Code hier zu: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Wenn du Schwierigkeiten hast zu verstehen, warum die `file` sich in der `map`-Operation zu bewegen scheint, stelle dir vor, dass statt `[meta + [lang: lang_id], file]` diese Zeile `[new_map, file]` lautet. + Dies sollte deutlicher machen, dass wir einfach die `file` an ihrer ursprünglichen Position an zweiter Stelle im Tupel lassen. Wir haben nur den `new_info`-Wert genommen und ihn in die Map gefaltet, die an erster Stelle steht. + + **Und das bringt uns zurück zur `tuple val(meta), path(file)`-Channel-Struktur!** + +Sobald du sicher bist, dass du verstehst, was dieser Code macht, führe den Workflow aus, um zu sehen, ob es funktioniert hat: + +```bash +nextflow run main.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Ja, das stimmt! +Wir haben die Ausgabe des Prozesses von `meta, file, lang_id` sauber neu organisiert, sodass `lang_id` jetzt einer der Schlüssel in der Meta-Map ist, und die Tupel des Channels wieder dem `meta, file`-Modell entsprechen. + +<!-- TODO (future) Should we also show how to remove a key using subMap?! Or note where to find that. --> + +### 2.4. Weise eine Sprachgruppe mit bedingten Anweisungen zu + +Jetzt, da wir unsere Sprachvorhersagen haben, lass uns die Informationen verwenden, um einige neue Gruppierungen zuzuweisen. + +In unseren Beispieldaten können die von unseren Charakteren verwendeten Sprachen in germanische Sprachen (Englisch, Deutsch) und romanische Sprachen (Französisch, Spanisch, Italienisch) gruppiert werden. +Es könnte nützlich sein, diese Klassifizierung später in der Pipeline verfügbar zu haben, also lass uns diese Information zur Meta-Map hinzufügen. + +Und gute Nachrichten, dies ist noch ein Fall, der sich perfekt zur Verwendung des `map`-Operators eignet! + +Konkret werden wir eine Variable namens `lang_group` definieren, einfache bedingte Logik verwenden, um zu bestimmen, welchen Wert wir der `lang_group` für jedes Datenstück zuweisen sollen. + +Die allgemeine Syntax wird so aussehen: + +```groovy +.map { meta, file -> + + // bedingte Logik zur Definition von lang_group kommt hier hin + + [meta + [lang_group: lang_group], file] +} +``` + +Du kannst sehen, dass dies der spontanen Map-Zusammenführungsoperation sehr ähnlich ist, die wir im vorherigen Schritt verwendet haben. +Wir müssen nur die bedingten Anweisungen schreiben. + +Hier ist die bedingte Logik, die wir anwenden wollen: + +- Definiere eine Variable namens `lang_group` mit dem Standardwert `'unknown'`. +- Wenn `lang` entweder Deutsch (`'de'`) oder Englisch (`'en'`) ist, ändere `lang_group` zu `germanic`. +- Ansonsten, wenn `lang` in einer Liste enthalten ist, die Französisch (`'fr'`), Spanisch (`'es'`) und Italienisch (`'it'`) enthält, ändere `lang_group` zu `romance`. + +Versuche es selbst zu schreiben, wenn du bereits weißt, wie man bedingte Anweisungen in Nextflow schreibt. + +!!! tip + + Du kannst auf den Wert von `lang` innerhalb der Map-Operation mit `meta.lang` zugreifen. + +Du solltest am Ende die folgenden Änderungen am Workflow vornehmen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Hier sind die wichtigsten Punkte: + +- Wir verwenden `def lang_group = "unknown"`, um die `lang_group`-Variable mit Standardwert auf `unknown` gesetzt zu erstellen. +- Wir verwenden eine `if {} else if {}`-Struktur für die bedingte Logik, mit alternativen `.equals()`-Tests für die zwei germanischen Sprachen und einem Test auf Existenz in einer Liste für die drei romanischen Sprachen. +- Wir verwenden die `meta + [lang_group:lang_group]`-Zusammenführungsoperation wie zuvor, um die aktualisierte Meta-Map zu generieren. + +<!-- TODO (future) Add note/links to relevant docs in additional resources section --> + +Sobald das alles Sinn macht, führe den Workflow erneut aus, um das Ergebnis zu sehen: + +```bash +nextflow run main.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Wie du sehen kannst, behalten die Channel-Elemente ihre `[meta, file]`-Struktur bei, aber die Meta-Map enthält jetzt diese neue Klassifizierung. + +### Fazit + +In diesem Abschnitt hast du gelernt, wie man: + +- **Eingabe-Metadaten auf Ausgabe-Channels anwendet**: Das Kopieren von Metadaten auf diese Weise ermöglicht es uns, Ergebnisse später basierend auf Metadateninhalten zu verknüpfen. +- **Eigene Schlüssel erstellt**: Du hast zwei neue Schlüssel in deiner Meta-Map erstellt, die du mit `meta + [new_key:value]` in die bestehende Meta-Map zusammengeführt hast. Einen basierend auf einem berechneten Wert aus einem Prozess und einen basierend auf einer Bedingung, die du im `map`-Operator gesetzt hast. + +Diese ermöglichen es dir, neue und bestehende Metadaten mit Dateien zu verknüpfen, während du durch deine Pipeline fortschreitest. +Selbst wenn du Metadaten nicht als Teil eines Prozesses verwendest, macht es das Beibehalten der Meta-Map mit den Daten wie hier einfach, alle relevanten Informationen zusammenzuhalten. + +--- + +## 3. Meta-Map-Informationen in einem Prozess verwenden + +Jetzt, da du weißt, wie man die Meta-Map erstellt und aktualisiert, können wir zum wirklich spaßigen Teil kommen: die Metadaten tatsächlich in einem Prozess verwenden. + +Genauer gesagt, werden wir unserem Workflow einen zweiten Schritt hinzufügen, um jedes Tier als ASCII-Art zu zeichnen und es den aufgezeichneten Text in einer Sprechblase sagen zu lassen. +Wir werden dies mit einem Tool namens [`cowpy`](https://github.com/jeffbuttars/cowpy) tun. + +??? info "Was macht `cowpy`?" + + `cowpy` ist ein Befehlszeilen-Tool, das ASCII-Art generiert, um beliebige Texteingaben auf lustige Weise anzuzeigen. + Es ist eine Python-Implementierung des klassischen [cowsay](https://en.wikipedia.org/wiki/Cowsay)-Tools von Tony Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Optional kannst du einen Charakter (oder 'Cowacter') auswählen, der anstelle der Standard-Kuh verwendet werden soll. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Wenn du den Hello Nextflow-Kurs durchgearbeitet hast, hast du dieses Tool bereits in Aktion gesehen. +Wenn nicht, keine Sorge; wir werden alles abdecken, was du wissen musst, während wir weitermachen. + +### 3.1. Importiere den Prozess und untersuche den Code + +Wir stellen dir ein vorgefertigtes Prozessmodul namens `COWPY` zur Verfügung, das das `cowpy`-Tool umschließt, sodass du nur eine Include-Anweisung vor dem Workflow-Block hinzufügen musst. + +Nimm die folgende Änderung am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Du kannst die Moduldatei öffnen, um ihren Code zu untersuchen: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generiere ASCII-Art mit cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Wie du sehen kannst, ist dieser Prozess derzeit so konzipiert, dass er eine Eingabedatei (die den anzuzeigenden Text enthält) und einen Wert entgegennimmt, der den Charakter angibt, der in ASCII-Art gezeichnet werden soll, normalerweise auf Workflow-Ebene durch einen Befehlszeilenparameter bereitgestellt. + +### 3.2. Übergebe ein Meta-Map-Feld als Eingabe + +Als wir das `cowpy`-Tool im Hello Nextflow-Kurs verwendet haben, haben wir einen Befehlszeilenparameter verwendet, um zu bestimmen, welcher Charakter zum Zeichnen des finalen Bildes verwendet werden soll. +Das machte Sinn, weil wir nur ein Bild pro Ausführung der Pipeline generierten. + +In diesem Tutorial möchten wir jedoch ein geeignetes Bild für jedes Subjekt generieren, das wir verarbeiten, sodass die Verwendung eines Befehlszeilenparameters zu einschränkend wäre. + +Gute Nachrichten: Wir haben eine `character`-Spalte in unserem Datenblatt und daher in unserer Meta-Map. +Lass uns diese verwenden, um den Charakter festzulegen, den der Prozess für jeden Eintrag verwenden soll. + +Zu diesem Zweck müssen wir drei Dinge tun: + +1. Dem Ausgabe-Channel, der aus dem vorherigen Prozess kommt, einen Namen geben, damit wir bequemer damit arbeiten können. +2. Bestimmen, wie man auf die interessierenden Informationen zugreift +3. Einen Aufruf zum zweiten Prozess hinzufügen und die Informationen entsprechend einspeisen. + +Lass uns anfangen. + +#### 3.2.1. Benenne den vorherigen Ausgabe-Channel + +Wir haben die vorherigen Manipulationen direkt auf dem Ausgabe-Channel des ersten Prozesses angewendet, `IDENTIFY_LANGUAGE.out`. +Um den Inhalt dieses Channels an den nächsten Prozess weiterzugeben (und dies auf eine klare und leicht lesbare Weise zu tun), möchten wir ihm einen eigenen Namen geben, `ch_languages`. + +Wir können das mit dem [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set)-Operator tun. + +Ersetze im Haupt-Workflow den `.view()`-Operator durch `.set { ch_languages }` und füge eine Zeile hinzu, die testet, dass wir uns auf den Channel namentlich beziehen können. + +=== "Nachher" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Temporär: Blick in ch_languages + ch_languages.view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Führe langid aus, um die Sprache jeder Begrüßung zu identifizieren + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Lass uns das ausführen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Dies bestätigt, dass wir uns jetzt namentlich auf den Channel beziehen können. + +#### 3.2.2. Greife auf die Datei- und Charakter-Metadaten zu + +Wir wissen aus der Betrachtung des Modulcodes, dass der `COWPY`-Prozess erwartet, eine Textdatei und einen `character`-Wert zu erhalten. +Um den Aufruf zum `COWPY`-Prozess zu schreiben, müssen wir nur wissen, wie man das entsprechende Dateiobjekt und die Metadaten aus jedem Element im Channel extrahiert. + +Wie oft ist der einfachste Weg, das zu tun, eine `map`-Operation zu verwenden. + +Unser Channel enthält Tupel, die als `[meta, file]` strukturiert sind, sodass wir direkt auf das `file`-Objekt zugreifen können, und wir können auf den `character`-Wert, der innerhalb der Meta-Map gespeichert ist, zugreifen, indem wir ihn als `meta.character` referenzieren. + +Nimm im Haupt-Workflow die folgenden Code-Änderungen vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="34" + // Temporär: Zugriff auf Datei und Charakter + ch_languages.map { meta, file -> file }.view { file -> "File: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Character: " + character } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="34" + // Temporär: Blick in ch_languages + ch_languages.view() + ``` + +Beachte, dass wir Closures (wie `{ file -> "File: " + file }`) verwenden, um die Ausgabe der `.view`-Operationen lesbarer zu machen. + +Lass uns das ausführen: + +```bash +nextflow run main.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Character: squirrel + File: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + File: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Character: tux + Character: turkey + File: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + File: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Character: sheep + Character: moose + Character: stegosaurus + File: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + File: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + File: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Character: turtle + ``` + +_Die Dateipfade und Charakterwerte können in deiner Ausgabe in einer anderen Reihenfolge herauskommen._ + +Dies bestätigt, dass wir auf die Datei und den Charakter für jedes Element im Channel zugreifen können. + +#### 3.2.3. Rufe den `COWPY`-Prozess auf + +Jetzt lass uns alles zusammenfügen und tatsächlich den `COWPY`-Prozess auf dem `ch_languages`-Channel aufrufen. + +Nimm im Haupt-Workflow die folgenden Code-Änderungen vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="34" + // Führe cowpy aus, um ASCII-Art zu generieren + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="34" + // Temporär: Zugriff auf Datei und Charakter + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Du siehst, wir kopieren einfach die zwei Map-Operationen (minus die `.view()`-Anweisungen) als Eingaben für den Prozessaufruf. +Stelle nur sicher, dass du das Komma zwischen ihnen nicht vergisst! + +Es ist etwas umständlich, aber wir werden sehen, wie man das im nächsten Abschnitt verbessern kann. + +Lass uns das ausführen: + +```bash +nextflow run main.nf -resume +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Wenn du ins Ergebnisverzeichnis schaust, solltest du die einzelnen Dateien sehen, die die ASCII-Art jeder Begrüßung enthalten, gesprochen vom entsprechenden Charakter. + +??? abstract "Verzeichnis- und Beispieldateiinhalte" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola. diff --git a/docs/de/docs/side_quests/nf-test.md b/docs/de/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..1701f66da3 --- /dev/null +++ b/docs/de/docs/side_quests/nf-test.md @@ -0,0 +1,1194 @@ +# Testen mit nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Die systematische Überprüfung, dass jeder Teil deines Workflows das tut, was er soll, ist entscheidend für Reproduzierbarkeit und langfristige Wartbarkeit und kann während des Entwicklungsprozesses eine enorme Hilfe sein. + +Lass uns kurz darüber sprechen, warum Testen so wichtig ist. Wenn du einen Workflow entwickelst, ist eines der ersten Dinge, die du tun wirst, dir einige Testdaten zu besorgen, von denen du weißt, dass sie gültig sind und ein Ergebnis liefern sollten. Du fügst den ersten Process zur Pipeline hinzu und verbindest ihn mit deinen Eingaben, damit er funktioniert. Um dann zu überprüfen, ob alles funktioniert, führst du ihn mit den Testdaten aus. Angenommen, das funktioniert, gehst du zum nächsten Process weiter und führst die Testdaten erneut aus. Du wiederholst diesen Prozess, bis du eine Pipeline hast, mit der du zufrieden bist. + +Dann fügst du vielleicht einen einfachen true- oder false-Parameter wie `--skip_process` hinzu. Jetzt musst du die Pipeline zweimal ausführen, einmal mit jedem Parameter, um sicherzustellen, dass sie wie erwartet funktioniert. Aber Moment, wie überprüfen wir, ob `--skip_process` den Process tatsächlich überspringt? Wir müssen in den Ausgaben nachsehen oder die Logdateien prüfen! Das ist mühsam und fehleranfällig. + +Während du deine Pipeline entwickelst, wird sie schnell so komplex, dass das manuelle Testen jeder Iteration langsam und fehleranfällig ist. Wenn du einen Fehler findest, wird es außerdem sehr schwierig sein, genau zu bestimmen, woher in deiner Pipeline der Fehler kommt. Hier kommt das Testen ins Spiel. + +Testen ermöglicht es dir, systematisch zu überprüfen, dass jeder Teil deiner Pipeline wie erwartet funktioniert. Die Vorteile gut geschriebener Tests für einen Entwickler sind enorm: + +- **Vertrauen**: Da die Tests die gesamte Pipeline abdecken, kannst du sicher sein, dass Änderungen nichts anderes beeinflussen +- **Zuverlässigkeit**: Wenn mehrere Entwickler an der Pipeline arbeiten, wissen sie, dass die anderen Entwickler die Pipeline und jede Komponente nicht kaputt gemacht haben. +- **Transparenz**: Die Tests zeigen, wo eine Pipeline fehlschlägt, und erleichtern es, das Problem aufzuspüren. Sie dienen auch als eine Form der Dokumentation und zeigen, wie man einen Process oder Workflow ausführt. +- **Geschwindigkeit**: Da die Tests automatisiert sind, können sie sehr schnell und wiederholt ausgeführt werden. Du kannst schnell iterieren mit weniger Angst, neue Fehler einzuführen. + +Es gibt viele verschiedene Arten von Tests, die wir schreiben können: + +1. **Tests auf Modul-Ebene**: Für einzelne Processes +2. **Tests auf Workflow-Ebene**: Für einen einzelnen Workflow +3. **Tests auf Pipeline-Ebene**: Für die Pipeline als Ganzes +4. **Leistungstests**: Für die Geschwindigkeit und Effizienz der Pipeline +5. **Belastungstests**: Bewertung der Pipeline-Leistung unter extremen Bedingungen, um ihre Grenzen zu bestimmen + +Das Testen einzelner Processes ist analog zu Unit-Tests in anderen Sprachen. Das Testen des Workflows oder der gesamten Pipeline ist analog zu sogenannten Integrationstests in anderen Sprachen, bei denen wir die Interaktionen der Komponenten testen. + +[**nf-test**](https://www.nf-test.com/) ist ein Tool, mit dem du Tests auf Modul-, Workflow- und Pipeline-Ebene schreiben kannst. Kurz gesagt, ermöglicht es dir, systematisch zu überprüfen, dass jeder einzelne Teil der Pipeline wie erwartet funktioniert, _isoliert_. + +### Lernziele + +In dieser Side Quest lernst du, nf-test zu verwenden, um einen Test auf Workflow-Ebene für die Pipeline sowie Tests auf Modul-Ebene für die drei Processes zu schreiben, die sie aufruft. + +Am Ende dieser Side Quest wirst du die folgenden Techniken effektiv anwenden können: + +- nf-test in deinem Projekt initialisieren +- Tests auf Modul- und Workflow-Ebene generieren +- Gängige Arten von Assertions hinzufügen +- Verstehen, wann Snapshots vs. Content-Assertions verwendet werden sollten +- Tests für ein gesamtes Projekt ausführen + +Diese Fähigkeiten werden dir helfen, eine umfassende Teststrategie in deinen Pipeline-Projekten zu implementieren und sicherzustellen, dass sie robuster und wartbarer sind. + +### Voraussetzungen + +Bevor du diese Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md) Tutorial oder einen gleichwertigen Einsteigerkurs abgeschlossen haben. +- Mit grundlegenden Nextflow-Konzepten und -Mechanismen vertraut sein (Processes, Channels, Operatoren, Arbeiten mit Dateien, Metadaten) + +--- + +## 0. Erste Schritte + +#### Öffne den Training-Codespace + +Falls noch nicht geschehen, stelle sicher, dass du die Trainingsumgebung wie in [Environment Setup](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/nf-test +``` + +Du kannst VSCode auf dieses Verzeichnis fokussieren: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest eine Hauptworkflow-Datei und eine CSV-Datei namens `greetings.csv`, die die Eingabe für die Pipeline enthält. + +```console title="Verzeichnisinhalt" +. +├── greetings.csv +└── main.nf +``` + +Für eine detaillierte Beschreibung der Dateien siehe die [Aufwärmphase von Hello Nextflow](../hello_nextflow/00_orientation.md). + +Der Workflow, den wir testen werden, ist eine Teilmenge des Hello-Workflows, der in [Hello Workflow](../hello_nextflow/03_hello_workflow.md) erstellt wurde. + +??? example "Was macht der Hello Nextflow Workflow?" + + Falls du das [Hello Nextflow](../hello_nextflow/index.md) Training nicht gemacht hast, hier ist ein kurzer Überblick darüber, was dieser einfache Workflow macht. + + Der Workflow nimmt eine CSV-Datei mit Grüßen entgegen, führt vier aufeinanderfolgende Transformationsschritte darauf aus und gibt eine einzige Textdatei mit einem ASCII-Bild eines lustigen Charakters aus, der die Grüße sagt. + + Die vier Schritte sind als Nextflow-Processes (`sayHello`, `convertToUpper`, `collectGreetings` und `cowpy`) implementiert, die in separaten Moduldateien gespeichert sind. + + 1. **`sayHello`:** Schreibt jeden Gruß in seine eigene Ausgabedatei (z.B. "Hello-output.txt") + 2. **`convertToUpper`:** Konvertiert jeden Gruß in Großbuchstaben (z.B. "HELLO") + 3. **`collectGreetings`:** Sammelt alle großgeschriebenen Grüße in einer einzigen Batch-Datei + 4. **`cowpy`:** Generiert ASCII-Art mit dem `cowpy`-Tool + + Die Ergebnisse werden in einem Verzeichnis namens `results/` veröffentlicht, und die endgültige Ausgabe der Pipeline (wenn sie mit Standardparametern ausgeführt wird) ist eine einfache Textdatei mit ASCII-Art eines Charakters, der die großgeschriebenen Grüße sagt. + + In dieser Side Quest verwenden wir eine Zwischenform des Hello-Workflows, die nur die ersten beiden Processes enthält. + +Die Teilmenge, mit der wir arbeiten werden, besteht aus zwei Processes: `sayHello` und `convertToUpper`. +Den vollständigen Workflow-Code kannst du unten sehen. + +??? example "Workflow-Code" + + ```groovy title="main.nf" + /* + * Pipeline-Parameter + */ + params.input_file = "greetings.csv" + + /* + * Verwende echo, um 'Hello World!' auf der Standardausgabe auszugeben + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Verwende ein Textersetzungs-Utility, um den Gruß in Großbuchstaben umzuwandeln + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // erstelle einen Channel für Eingaben aus einer CSV-Datei + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // gib einen Gruß aus + sayHello(greeting_ch) + + // konvertiere den Gruß in Großbuchstaben + convertToUpper(sayHello.out) + } + ``` + +#### Führe den Workflow aus + +Lass uns den Workflow ausführen, um sicherzustellen, dass er wie erwartet funktioniert. + +```bash +nextflow run main.nf +``` + +```console title="Ergebnis der Workflow-Ausführung" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +HERZLICHEN GLÜCKWUNSCH! Du hast gerade einen Test ausgeführt! + +"Warte, was? Ich habe gerade den Workflow ausgeführt und er hat funktioniert! Wie ist das ein Test?" + +Gute Frage! + +Lass uns aufschlüsseln, was gerade passiert ist. + +Du hast den Workflow mit den Standardparametern ausgeführt, bestätigt, dass er funktioniert hat, und bist mit den Ergebnissen zufrieden. Das ist die Essenz des Testens. Wenn du das Hello Nextflow Training durchgearbeitet hast, ist dir vielleicht aufgefallen, dass wir jeden Abschnitt immer damit begonnen haben, den Workflow auszuführen, den wir als Ausgangspunkt verwendet haben, um zu bestätigen, dass alles korrekt eingerichtet ist. + +Das Testen von Software macht im Wesentlichen diesen Prozess für uns. + +#### Überprüfe die Aufgabe + +Deine Herausforderung besteht darin, standardisierte Tests zu diesem Workflow mit nf-test hinzuzufügen, um es einfach zu machen, zu überprüfen, dass jeder Teil weiterhin wie erwartet funktioniert, falls weitere Änderungen vorgenommen werden. + +#### Bereitschafts-Checkliste + +Denkst du, du bist bereit loszulegen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace ist aktiv +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend gesetzt +- [ ] Ich habe den Workflow erfolgreich ausgeführt +- [ ] Ich verstehe die Aufgabe + +Wenn du alle Kästchen abhaken kannst, bist du startklar. + +--- + +## 1. Initialisiere `nf-test` + +Das `nf-test`-Paket bietet einen Initialisierungsbefehl, der einige Dinge einrichtet, damit wir mit der Entwicklung von Tests für unser Projekt beginnen können. + +```bash +nf-test init +``` + +Dies sollte die folgende Ausgabe erzeugen: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Es erstellt auch ein `tests`-Verzeichnis, das eine Konfigurationsdatei-Vorlage enthält. + +### 1.1. Generiere einen nf-test + +`nf-test` kommt mit einer Reihe von Tools zum Erstellen von nf-test-Dateien, was uns den Großteil der Arbeit erspart. Diese befinden sich unter dem Unterbefehl `generate`. Lass uns einen Test für die Pipeline generieren: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Ausgabe" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Dies erstellt eine `main.nf.test`-Datei im `tests`-Verzeichnis. Dies ist unsere Testdatei auf Pipeline-Ebene. Wenn du `tree tests/` ausführst, solltest du so etwas sehen: + +```console title="Test-Verzeichnisinhalt" +tests/ +├── main.nf.test +└── nextflow.config +``` + +Die `main.nf.test`-Datei ist unsere Testdatei auf Pipeline-Ebene. Lass uns sie öffnen und den Inhalt ansehen. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Wir nehmen uns einen Moment Zeit, um die Struktur der Testdatei zu verstehen. + +Der `nextflow_pipeline`-Block ist der Einstiegspunkt für alle Tests auf Pipeline-Ebene. Er enthält Folgendes: + +- `name`: Der Name des Tests. +- `script`: Der Pfad zum Pipeline-Script. + +Der `test`-Block ist der eigentliche Test. Er enthält Folgendes: + +- `when`: Die Bedingungen, unter denen der Test ausgeführt werden soll. Dies beinhaltet die Parameter, die zum Ausführen der Pipeline verwendet werden. +- `then`: Die Assertions, die gemacht werden sollen. Dies beinhaltet die erwarteten Ergebnisse der Pipeline. + +In einfachem Deutsch liest sich die Logik des Tests wie folgt: +"**Wenn** diese _Parameter_ dieser _Pipeline_ bereitgestellt werden, **dann** erwarten wir, diese Ergebnisse zu sehen." + +Dies ist kein funktionaler Test, wir werden im nächsten Abschnitt demonstrieren, wie man ihn in einen umwandelt. + +### Eine Anmerkung zu Testnamen + +Im obigen Beispiel haben wir den Standardnamen "Should run without failures" verwendet, der für einen grundlegenden Test geeignet ist, der nur prüft, ob die Pipeline erfolgreich läuft. Da wir jedoch spezifischere Testfälle hinzufügen, sollten wir beschreibendere Namen verwenden, die angeben, was wir tatsächlich testen. Zum Beispiel: + +- "Should convert input to uppercase" - beim Testen spezifischer Funktionalität +- "Should handle empty input gracefully" - beim Testen von Grenzfällen +- "Should respect max memory parameter" - beim Testen von Ressourcenbeschränkungen +- "Should create expected output files" - beim Testen der Dateigenerierung + +Gute Testnamen sollten: + +1. Mit "Should" beginnen, um deutlich zu machen, was das erwartete Verhalten ist +2. Die spezifische Funktionalität oder das Szenario beschreiben, das getestet wird +3. Klar genug sein, dass man bei einem Testfehler weiß, welche Funktionalität defekt ist + +Während wir später weitere Assertions und spezifische Testfälle hinzufügen, werden wir diese beschreibenderen Namen verwenden, um deutlich zu machen, was jeder Test überprüft. + +### 1.2. Führe den Test aus + +Lass uns den Test ausführen, um zu sehen, was passiert. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test Pipeline-Fehler" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Der Test schlägt fehl! Was ist passiert? + +1. nf-test hat versucht, die Pipeline wie sie ist auszuführen, unter Verwendung der Einstellungen im `when`-Block: + +```groovy title="tests/main.nf.test" +when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } +} +``` + +2. nf-test hat den Status der Pipeline überprüft und ihn mit dem `when`-Block verglichen: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Beachte, wie nf-test gemeldet hat, dass die Pipeline fehlgeschlagen ist, und die Fehlermeldung von Nextflow bereitgestellt hat: + +```console title="Fehler" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Was war also das Problem? Denk daran, dass die Pipeline eine greetings.csv-Datei im Projektverzeichnis hat. Wenn nf-test die Pipeline ausführt, wird es nach dieser Datei suchen, kann sie aber nicht finden. Die Datei ist da, was passiert? Nun, wenn wir uns den Pfad ansehen, können wir sehen, dass der Test im Pfad `./nf-test/tests/longHashString/` stattfindet. Genau wie Nextflow erstellt nf-test ein neues Verzeichnis für jeden Test, um alles isoliert zu halten. Die Datendatei befindet sich nicht dort, also müssen wir den Pfad zur Datei im ursprünglichen Test korrigieren. + +Lass uns zurück zur Testdatei gehen und den Pfad zur Datei im `when`-Block ändern. + +Du fragst dich vielleicht, wie wir im Test auf das Root-Verzeichnis der Pipeline zeigen werden. Da dies eine häufige Situation ist, hat nf-test eine Reihe von globalen Variablen, die wir verwenden können, um uns das Leben zu erleichtern. Du findest die vollständige Liste [hier](https://www.nf-test.com/docs/testcases/global_variables/), aber in der Zwischenzeit werden wir die Variable `projectDir` verwenden, die das Root-Verzeichnis des Pipeline-Projekts bedeutet. + +_Vorher:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } +} +``` + +_Nachher:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Lass uns den Test erneut ausführen, um zu sehen, ob er funktioniert. + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline erfolgreich" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Erfolg! Die Pipeline läuft erfolgreich und der Test ist bestanden. Führe ihn so oft aus, wie du möchtest, und du wirst immer das gleiche Ergebnis erhalten! + +Standardmäßig ist die Nextflow-Ausgabe verborgen, aber um dich zu überzeugen, dass nf-test definitiv den Workflow ausführt, kannst du das `--verbose`-Flag verwenden: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Pipeline führt alle Processes aus" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Füge Assertions hinzu + +Eine einfache Überprüfung besteht darin, sicherzustellen, dass unsere Pipeline alle Processes ausführt, die wir erwarten, und keine stillschweigend überspringt. Denk daran, dass unsere Pipeline 6 Processes ausführt, einen namens `sayHello` und einen namens `convertToUpper` für jeden der 3 Grüße. + +Lass uns unserem Test eine Assertion hinzufügen, um zu prüfen, dass die Pipeline die erwartete Anzahl von Processes ausführt. Wir werden auch unseren Testnamen aktualisieren, um besser widerzuspiegeln, was wir testen. + +**Vorher:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Nachher:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Der Testname spiegelt nun besser wider, was wir tatsächlich überprüfen - nicht nur, dass die Pipeline ohne Fehler läuft, sondern dass sie die erwartete Anzahl von Processes ausführt. + +Lass uns den Test erneut ausführen, um zu sehen, ob er funktioniert. + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline erfolgreich mit Assertions" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Erfolg! Die Pipeline läuft erfolgreich und der Test ist bestanden. Jetzt haben wir begonnen, die Details der Pipeline zu testen, sowie den Gesamtstatus. + +### 1.4. Teste die Ausgabe + +Lass uns unserem Test eine Assertion hinzufügen, um zu prüfen, dass die Ausgabedatei erstellt wurde. Wir fügen sie als separaten Test mit einem aussagekräftigen Namen hinzu, um die Ergebnisse leichter interpretieren zu können. + +**Vorher:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Nachher:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Führe den Test erneut aus, um zu sehen, ob er funktioniert. + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline erfolgreich mit Datei-Assertions" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Erfolg! Die Tests sind bestanden, weil die Pipeline erfolgreich abgeschlossen wurde, die richtige Anzahl von Processes ausgeführt wurde und die Ausgabedateien erstellt wurden. Dies sollte dir auch zeigen, wie nützlich es ist, diese aussagekräftigen Namen für deine Tests zu verwenden. + +Das ist nur die Oberfläche, wir können weiterhin Assertions schreiben, um die Details der Pipeline zu überprüfen, aber für jetzt lass uns weitergehen und die Interna der Pipeline testen. + +### Fazit + +Du weißt, wie man einen nf-test für eine Pipeline schreibt. + +### Was kommt als Nächstes? + +Lerne, wie man einen Nextflow-Process testet. + +--- + +## 2. Teste einen Nextflow-Process + +Wir müssen nicht für jeden Teil der Pipeline Tests schreiben, aber je mehr Tests wir haben, desto umfassender können wir die Pipeline bewerten und desto sicherer können wir sein, dass sie wie erwartet funktioniert. In diesem Abschnitt werden wir beide Processes in der Pipeline als einzelne Einheiten testen. + +### 2.1. Teste den `sayHello`-Process + +Lass uns mit dem `sayHello`-Process beginnen. + +Lass uns den `nf-test generate`-Befehl erneut verwenden, um Tests für den Process zu generieren. + +```bash +nf-test generate process main.nf +``` + +```console title="Ausgabe" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Lass uns vorerst auf den `sayhello`-Process in der Datei `main.sayhello.nf.test` konzentrieren. + +Lass uns die Datei öffnen und den Inhalt ansehen. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Wie zuvor beginnen wir mit den Testdetails, gefolgt von den `when`- und `then`-Blöcken. Wir haben jedoch auch einen zusätzlichen `process`-Block, der es uns ermöglicht, die Eingaben für den Process zu definieren. + +Lass uns den Test ausführen, um zu sehen, ob er funktioniert. + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Process-Test schlägt fehl" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Der Test schlägt fehl, weil der `sayHello`-Process 1 Eingabe deklariert, aber mit 0 Argumenten aufgerufen wurde. Lass uns das beheben, indem wir eine Eingabe zum Process hinzufügen. Denk daran aus [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (und dem Aufwärmabschnitt oben), dass unser `sayHello`-Process eine einzelne Value-Eingabe nimmt, die wir bereitstellen müssen. Wir sollten auch den Testnamen korrigieren, um besser widerzuspiegeln, was wir testen. + +**Vorher:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Nachher:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Lass uns den Test erneut ausführen, um zu sehen, ob er funktioniert. + +```console title="nf-test Pipeline erfolgreich" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Erfolg! Der Test ist bestanden, weil der `sayHello`-Process erfolgreich ausgeführt wurde und die Ausgabe erstellt wurde. + +### 2.2. Überprüfe den vom Test erstellten Snapshot + +Wenn wir die Datei `tests/main.sayhello.nf.test` betrachten, können wir sehen, dass sie eine Methode `snapshot()` im Assertion-Block verwendet: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Dies teilt nf-test mit, einen Snapshot der Ausgabe des `sayHello`-Processes zu erstellen. Lass uns den Inhalt der Snapshot-Datei ansehen. + +```console title="Snapshot-Dateiinhalt" +code tests/main.sayhello.nf.test.snap +``` + +Wir werden es hier nicht ausdrucken, aber du solltest eine JSON-Datei sehen, die Details des Processes und der Process-Ausgaben enthält. Insbesondere können wir eine Zeile sehen, die so aussieht: + +```json title="Snapshot-Dateiinhalt" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Dies repräsentiert die Ausgaben, die vom `sayHello`-Process erstellt wurden, die wir explizit testen. Wenn wir den Test erneut ausführen, wird das Programm prüfen, ob die neue Ausgabe mit der ursprünglich aufgezeichneten Ausgabe übereinstimmt. Dies ist eine schnelle, einfache Möglichkeit zu testen, dass sich Process-Ausgaben nicht ändern, weshalb nf-test dies als Standard bereitstellt. + +!!!warning "Warnung" + + Das bedeutet, wir müssen sicher sein, dass die Ausgabe, die wir im ursprünglichen Lauf aufzeichnen, korrekt ist! + +Wenn sich im Laufe der zukünftigen Entwicklung etwas im Code ändert, das dazu führt, dass die Ausgabe anders ist, wird der Test fehlschlagen und wir müssen bestimmen, ob die Änderung erwartet ist oder nicht. + +- Wenn sich herausstellt, dass etwas im Code kaputt gegangen ist, müssen wir es reparieren, in der Erwartung, dass der reparierte Code den Test besteht. +- Wenn es sich um eine erwartete Änderung handelt (z.B. das Tool wurde verbessert und die Ergebnisse sind besser), dann müssen wir den Snapshot aktualisieren, um die neue Ausgabe als Referenz zum Abgleich zu akzeptieren. nf-test hat dafür einen Parameter `--update-snapshot`. + +Wir können den Test erneut ausführen und sehen, dass der Test bestehen sollte: + +```console title="nf-test Process erfolgreich mit Snapshot" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Erfolg! Der Test ist bestanden, weil der `sayHello`-Process erfolgreich ausgeführt wurde und die Ausgabe dem Snapshot entspricht. + +### 2.3. Alternative zu Snapshots: Direkte Content-Assertions + +Während Snapshots großartig sind, um Änderungen in der Ausgabe zu erfassen, möchtest du manchmal spezifischen Inhalt überprüfen, ohne so streng zu sein, dass die gesamte Datei übereinstimmen muss. Zum Beispiel: + +- Wenn Teile der Ausgabe sich ändern könnten (Zeitstempel, zufällige IDs usw.), aber bestimmte Schlüsselinhalte vorhanden sein müssen +- Wenn du nach spezifischen Mustern oder Werten in der Ausgabe suchen möchtest +- Wenn du den Test expliziter darüber machen möchtest, was Erfolg ausmacht + +So könnten wir unseren Test modifizieren, um spezifischen Inhalt zu überprüfen: + +**Vorher:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Nachher:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // Parameter hier definieren + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Beachte, dass nf-test die Process-Ausgaben als Liste von Listen sieht, also holt `process.out[0][0]` den ersten Teil des ersten Channel-Elements (oder 'Emission') von diesem Process. + +Dieser Ansatz: + +- Macht klar, was genau wir in der Ausgabe erwarten +- Ist widerstandsfähiger gegen irrelevante Änderungen in der Ausgabe +- Liefert bessere Fehlermeldungen, wenn Tests fehlschlagen +- Ermöglicht komplexere Validierungen (Regex-Muster, numerische Vergleiche usw.) + +Lass uns den Test ausführen, um zu sehen, ob er funktioniert. + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Process-Test schlägt fehl" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Teste den `convertToUpper`-Process + +Lass uns die Datei `tests/main.converttoupper.nf.test` öffnen und den Inhalt ansehen: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Dies ist ein ähnlicher Test wie beim `sayHello`-Process, aber er testet den `convertToUpper`-Process. Wir wissen, dass dieser fehlschlagen wird, weil genau wie bei `sayHello`, der `convertToUpper`-Process eine einzelne Path-Eingabe nimmt, aber wir keine angegeben haben. + +Wir müssen jetzt eine einzelne Eingabedatei für den convertToUpper-Process bereitstellen, die Text enthält, den wir in Großbuchstaben umwandeln möchten. Es gibt viele Möglichkeiten, wie wir das tun könnten: + +- Wir könnten eine dedizierte Datei zum Testen erstellen +- Wir könnten die vorhandene data/greetings.csv-Datei wiederverwenden +- Wir könnten sie spontan innerhalb des Tests erstellen + +Für jetzt lass uns die vorhandene data/greetings.csv-Datei wiederverwenden, unter Verwendung des Beispiels, das wir beim Pipeline-Level-Test verwendet haben. Wie zuvor können wir den Test benennen, um besser widerzuspiegeln, was wir testen, aber diesmal lass uns den Inhalt 'snapshotten', anstatt nach spezifischen Strings zu suchen (wie wir es im anderen Process getan haben). + +**Vorher:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + // Eingaben des Prozesses hier definieren. Beispiel: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Nachher:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // Parameter hier definieren. Beispiel: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Und führe den Test aus! + +```bash title="nf-test Pipeline erfolgreich" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test Process convertToUpper erfolgreich" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Beachte, wir haben eine Snapshot-Datei für den `convertToUpper`-Process bei `tests/main.converttoupper.nf.test.snap` erstellt. Wenn wir den Test erneut ausführen, sollten wir sehen, dass nf-test erneut besteht. + +```bash title="nf-test Process convertToUpper erfolgreich" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test Process convertToUpper erfolgreich" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Fazit + +Du weißt, wie man Tests für einen Nextflow-Process schreibt und ausführt. + +### Was kommt als Nächstes? + +Lerne, wie man Tests für alles auf einmal ausführt! + +## 3. Führe Tests für das gesamte Repository aus + +nf-test für jede Komponente auszuführen ist in Ordnung, aber mühsam und fehleranfällig. Können wir nicht einfach alles auf einmal testen? + +Ja, das können wir! + +Lass uns nf-test für das gesamte Repo ausführen. + +### 3.1. Führe nf-test für das gesamte Repo aus + +Wir können nf-test für das gesamte Repo ausführen, indem wir den Befehl `nf-test test` ausführen. + +```bash +nf-test test . +``` + +Beachte, wir verwenden einfach `.`, um alles von unserem aktuellen Verzeichnis aus auszuführen. Dies wird jeden Test einschließen! + +```console title="nf-test Repo erfolgreich" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Schau dir das an! Wir haben 4 Tests ausgeführt, 1 für jeden Process und 2 für die gesamte Pipeline mit einem einzigen Befehl. Stell dir vor, wie mächtig dies bei einer großen Codebasis ist! + +--- + +## Zusammenfassung + +In dieser Side Quest hast du gelernt, die Funktionen von nf-test zu nutzen, um Tests für einzelne Processes sowie End-to-End-Tests für die gesamte Pipeline zu erstellen und auszuführen. +Du bist dir jetzt der zwei Hauptansätze zur Ausgabevalidierung bewusst, Snapshots und direkte Content-Assertions, und wann welcher verwendet werden sollte. +Du weißt auch, wie man Tests entweder einzeln oder für ein gesamtes Projekt ausführt. + +Die Anwendung dieser Techniken in deiner eigenen Arbeit wird es dir ermöglichen sicherzustellen, dass: + +- Dein Code wie erwartet funktioniert +- Änderungen bestehende Funktionalität nicht kaputt machen +- Andere Entwickler mit Vertrauen beitragen können +- Probleme schnell identifiziert und behoben werden können +- Der Ausgabeinhalt den Erwartungen entspricht + +### Wichtige Muster + +1. Tests auf Pipeline-Ebene: + - Grundlegendes Erfolgstes + - Überprüfung der Process-Anzahl + - Überprüfung der Ausgabedatei-Existenz +2. Tests auf Process-Ebene +3. Zwei Ansätze zur Ausgabevalidierung: + - Verwendung von Snapshots für vollständige Ausgabeüberprüfung + - Verwendung direkter Content-Assertions für spezifische Inhaltsüberprüfungen +4. Ausführung aller Tests in einem Repository mit einem einzigen Befehl + +### Zusätzliche Ressourcen + +Schau dir die [nf-test-Dokumentation](https://www.nf-test.com/) an für fortgeschrittenere Testfunktionen und Best Practices. Du könntest: + +- Umfassendere Assertions zu deinen Tests hinzufügen +- Tests für Grenzfälle und Fehlerbedingungen schreiben +- Continuous Integration einrichten, um Tests automatisch auszuführen +- Mehr über andere Arten von Tests wie Workflow- und Modultests erfahren +- Fortgeschrittenere Content-Validierungstechniken erkunden + +**Denk daran:** Tests sind lebende Dokumentation darüber, wie sich dein Code verhalten sollte. Je mehr Tests du schreibst und je spezifischer deine Assertions sind, desto sicherer kannst du in die Zuverlässigkeit deiner Pipeline sein. + +--- + +## Was kommt als Nächstes? + +Kehre zum [Menü der Side Quests](./index.md) zurück oder klicke auf den Button unten rechts auf der Seite, um zum nächsten Thema in der Liste zu gelangen. diff --git a/docs/de/docs/side_quests/orientation.md b/docs/de/docs/side_quests/orientation.md new file mode 100644 index 0000000000..5094bd8b31 --- /dev/null +++ b/docs/de/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientierung + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Die GitHub Codespaces-Umgebung enthält alle Software, Code und Daten, die für dieses Training notwendig sind, sodass du nichts selbst installieren musst. +Du benötigst jedoch einen (kostenlosen) Account zum Einloggen und solltest dir ein paar Minuten Zeit nehmen, um dich mit der Benutzeroberfläche vertraut zu machen. + +Falls du das noch nicht getan hast, folge bitte [diesem Link](../../envsetup/), bevor du fortfährst. + +## Bereitgestellte Materialien + +Während dieses Trainings werden wir im Verzeichnis `side-quests/` arbeiten. +Dieses Verzeichnis enthält alle Code-Dateien, Testdaten und zusätzlichen Dateien, die du benötigst. + +Erkunde gerne den Inhalt dieses Verzeichnisses; am einfachsten geht das mit dem Datei-Explorer auf der linken Seite des GitHub Codespaces-Arbeitsbereichs. +Alternativ kannst du den Befehl `tree` verwenden. +Im Verlauf des Kurses nutzen wir die Ausgabe von `tree`, um Verzeichnisstrukturen und -inhalte in einer lesbaren Form darzustellen, manchmal mit kleinen Anpassungen zur besseren Übersichtlichkeit. + +Hier erstellen wir ein Inhaltsverzeichnis bis zur zweiten Ebene: + +```bash +tree . -L 2 +``` + +Wenn du dies innerhalb von `side-quests` ausführst, solltest du folgende Ausgabe sehen: + +```console title="Verzeichnisinhalt" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Hier ist eine Zusammenfassung dessen, was du zum Einstieg wissen solltest:** + +- **Jedes Verzeichnis entspricht einer einzelnen Side Quest.** + Deren Inhalte werden auf der entsprechenden Seite der Side Quest detailliert beschrieben. + +- **Das Verzeichnis `solutions`** enthält die vollständigen Workflow- und/oder Modul-Skripte, die aus den verschiedenen Schritten jeder Side Quest resultieren. + Sie dienen als Referenz, um deine Arbeit zu überprüfen und eventuell auftretende Probleme zu beheben. + +!!!tip + + Falls du aus irgendeinem Grund dieses Verzeichnis verlässt, kannst du jederzeit mit diesem Befehl zurückkehren: + + ```bash + cd /workspaces/training/side-quests + ``` + +Um nun mit dem Kurs zu beginnen, klicke auf den Pfeil in der unteren rechten Ecke dieser Seite. diff --git a/docs/de/docs/side_quests/splitting_and_grouping.md b/docs/de/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..4d951032ef --- /dev/null +++ b/docs/de/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,969 @@ +# Splitting und Grouping + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow bietet leistungsstarke Werkzeuge, um flexibel mit Daten zu arbeiten. Eine wichtige Fähigkeit ist das Aufteilen von Daten in verschiedene Streams und das anschließende Gruppieren zusammengehöriger Elemente. Dies ist besonders wertvoll in Bioinformatik-Workflows, wo du verschiedene Arten von Proben separat verarbeiten musst, bevor du die Ergebnisse für die Analyse kombinierst. + +Stell es dir wie das Sortieren von Post vor: Du trennst Briefe nach Zielort, verarbeitest jeden Stapel unterschiedlich und kombinierst dann Elemente, die an dieselbe Person gehen. Nextflow verwendet spezielle Operatoren, um dies mit wissenschaftlichen Daten zu erreichen. Dieser Ansatz ist auch allgemein als **scatter/gather**-Muster in verteiltem Computing und Bioinformatik-Workflows bekannt. + +Nextflows Channel-System steht im Mittelpunkt dieser Flexibilität. Channels verbinden verschiedene Teile deines Workflows und ermöglichen es den Daten, durch deine Analyse zu fließen. Du kannst mehrere Channels aus einer einzigen Datenquelle erstellen, jeden Channel unterschiedlich verarbeiten und dann Channels bei Bedarf wieder zusammenführen. Dieser Ansatz ermöglicht es dir, Workflows zu entwerfen, die auf natürliche Weise die verzweigenden und konvergierenden Pfade komplexer Bioinformatik-Analysen widerspiegeln. + +### Lernziele + +In dieser Side Quest lernst du, Daten mit Nextflows Channel-Operatoren aufzuteilen und zu gruppieren. +Wir beginnen mit einer CSV-Datei, die Probeninformationen und zugehörige Datendateien enthält, und manipulieren und reorganisieren diese Daten dann. + +Am Ende dieser Side Quest kannst du Datenströme effektiv trennen und kombinieren, indem du die folgenden Techniken verwendest: + +- Daten aus Dateien mit `splitCsv` einlesen +- Daten mit `filter` und `map` filtern und transformieren +- Zusammengehörige Daten mit `join` und `groupTuple` kombinieren +- Datenkombinationen mit `combine` für parallele Verarbeitung erstellen +- Datenstruktur mit `subMap` und Deduplizierungsstrategien optimieren +- Wiederverwendbare Funktionen mit benannten Closures erstellen, um dir bei der Manipulation von Channel-Strukturen zu helfen + +Diese Fähigkeiten helfen dir, Workflows zu erstellen, die mehrere Eingabedateien und verschiedene Datentypen effizient verarbeiten können, während sie eine saubere, wartbare Code-Struktur beibehalten. + +### Voraussetzungen + +Bevor du diese Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md)-Tutorial oder einen gleichwertigen Einsteigerkurs abgeschlossen haben. +- Dich mit grundlegenden Nextflow-Konzepten und -Mechanismen wohl fühlen (Prozesse, Channels, Operatoren, Arbeiten mit Dateien, Meta-Daten) + +**Optional:** Wir empfehlen, zuerst die Side Quest [Metadaten in Workflows](./metadata.md) abzuschließen. +Diese behandelt die Grundlagen des Einlesens von CSV-Dateien mit `splitCsv` und der Erstellung von Meta-Maps, die wir hier intensiv nutzen werden. + +--- + +## 0. Einstieg + +#### Öffne den Training-Codespace + +Falls du dies noch nicht getan hast, stelle sicher, dass du die Trainingsumgebung wie in [Environment Setup](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/splitting_and_grouping +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis konzentriert: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest eine Haupt-Workflow-Datei und ein `data`-Verzeichnis, das ein Samplesheet namens `samplesheet.csv` enthält. + +```console title="Verzeichnisinhalt" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +Das Samplesheet enthält Informationen über Proben von verschiedenen Patienten, einschließlich der Patienten-ID, der Probenwiederholungsnummer, des Typs (normal oder tumor) und Pfaden zu hypothetischen Datendateien (die nicht tatsächlich existieren, aber wir tun so, als ob). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Dieses Samplesheet listet acht Proben von drei Patienten (A, B, C) auf. + +Für jeden Patienten haben wir Proben vom Typ `tumor` (typischerweise aus Tumorbiopsien stammend) oder `normal` (aus gesundem Gewebe oder Blut entnommen). +Falls du mit Krebs-Analysen nicht vertraut bist, solltest du nur wissen, dass dies einem experimentellen Modell entspricht, das gepaarte Tumor/Normal-Proben verwendet, um kontrastive Analysen durchzuführen. + +Speziell für Patient A haben wir zwei Sätze technischer Replikate (Wiederholungen). + +!!! note + + Mach dir keine Sorgen, wenn du mit diesem experimentellen Design nicht vertraut bist, es ist nicht entscheidend für das Verständnis dieses Tutorials. + +#### Überprüfe die Aufgabe + +Deine Herausforderung besteht darin, einen Nextflow-Workflow zu schreiben, der: + +1. Probendaten aus einer CSV-Datei **einliest** und mit Meta-Maps strukturiert +2. Proben basierend auf dem Typ (normal vs. tumor) in verschiedene Channels **aufteilt** +3. Übereinstimmende Tumor/Normal-Paare nach Patienten-ID und Replikatnummer **verbindet** +4. Proben über genomische Intervalle für parallele Verarbeitung **verteilt** +5. Zusammengehörige Proben für die nachgelagerte Analyse wieder **gruppiert** + +Dies stellt ein häufiges Bioinformatik-Muster dar, bei dem du Daten für unabhängige Verarbeitung aufteilen und dann zusammengehörige Elemente für vergleichende Analysen wieder kombinieren musst. + +#### Bereitschafts-Checkliste + +Glaubst du, du bist bereit loszulegen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace läuft +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend eingestellt +- [ ] Ich verstehe die Aufgabe + +Wenn du alle Kästchen ankreuzen kannst, kann es losgehen. + +--- + +## 1. Probendaten einlesen + +### 1.1. Probendaten mit `splitCsv` einlesen und Meta-Maps erstellen + +Lass uns damit beginnen, die Probendaten mit `splitCsv` einzulesen und sie im Meta-Map-Muster zu organisieren. In der `main.nf` siehst du, dass wir bereits mit dem Workflow begonnen haben. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + In diesem Tutorial werden wir das Präfix `ch_` für alle Channel-Variablen verwenden, um klar anzuzeigen, dass sie Nextflow-Channels sind. + +Wenn du die Side Quest [Metadaten in Workflows](./metadata.md) abgeschlossen hast, wirst du dieses Muster wiedererkennen. Wir verwenden `splitCsv`, um die CSV zu lesen und strukturieren die Daten sofort mit einer Meta-Map, um Metadaten von Dateipfaden zu trennen. + +!!! info + + In diesem Training werden wir zwei verschiedenen Konzepten begegnen, die `map` genannt werden: + + - **Datenstruktur**: Die Groovy-Map (entspricht Dictionaries/Hashes in anderen Sprachen), die Schlüssel-Wert-Paare speichert + - **Channel-Operator**: Der `.map()`-Operator, der Elemente in einem Channel transformiert + + Wir werden im Kontext klären, welches wir meinen, aber diese Unterscheidung ist wichtig für die Arbeit mit Nextflow. + +Wende diese Änderungen auf `main.nf` an: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Dies kombiniert die `splitCsv`-Operation (Lesen der CSV mit Headern) und die `map`-Operation (Strukturierung der Daten als `[meta, file]`-Tupel) in einem Schritt. Wende diese Änderung an und führe die Pipeline aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Wir haben jetzt einen Channel, bei dem jedes Element ein `[meta, file]`-Tupel ist - Metadaten getrennt von Dateipfaden. Diese Struktur ermöglicht es uns, unsere Arbeitslast basierend auf Metadatenfeldern aufzuteilen und zu gruppieren. + +--- + +## 2. Daten filtern und transformieren + +### 2.1. Daten mit `filter` filtern + +Wir können den [`filter`-Operator](https://www.nextflow.io/docs/latest/operator.html#filter) verwenden, um die Daten basierend auf einer Bedingung zu filtern. Nehmen wir an, wir wollen nur normale Proben verarbeiten. Wir können dies tun, indem wir die Daten basierend auf dem `type`-Feld filtern. Lass uns dies vor dem `view`-Operator einfügen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Führe den Workflow erneut aus, um das gefilterte Ergebnis zu sehen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Wir haben die Daten erfolgreich gefiltert, um nur normale Proben einzuschließen. Lass uns zusammenfassen, wie dies funktioniert. + +Der `filter`-Operator nimmt eine Closure, die auf jedes Element im Channel angewendet wird. Wenn die Closure `true` zurückgibt, wird das Element eingeschlossen; wenn sie `false` zurückgibt, wird das Element ausgeschlossen. + +In unserem Fall wollen wir nur Proben behalten, bei denen `meta.type == 'normal'`. Die Closure verwendet das Tupel `meta,file`, um auf jede Probe zu verweisen, greift auf den Probentyp mit `meta.type` zu und prüft, ob er `'normal'` entspricht. + +Dies wird mit der einzelnen Closure erreicht, die wir oben eingeführt haben: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Separate gefilterte Channels erstellen + +Derzeit wenden wir den Filter auf den direkt aus der CSV erstellten Channel an, aber wir wollen dies auf mehr als eine Weise filtern, also lass uns die Logik umschreiben, um einen separaten gefilterten Channel für normale Proben zu erstellen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Führe die Pipeline aus, um die Ergebnisse zu sehen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Wir haben die Daten erfolgreich gefiltert und einen separaten Channel für normale Proben erstellt. + +Lass uns auch einen gefilterten Channel für die Tumorproben erstellen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Wir haben die normalen und Tumorproben in zwei verschiedene Channels aufgeteilt und eine Closure, die an `view()` übergeben wird, verwendet, um sie in der Ausgabe unterschiedlich zu kennzeichnen: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Zusammenfassung + +In diesem Abschnitt hast du gelernt: + +- **Daten filtern**: Wie man Daten mit `filter` filtert +- **Daten aufteilen**: Wie man Daten basierend auf einer Bedingung in verschiedene Channels aufteilt +- **Daten anzeigen**: Wie man `view` verwendet, um die Daten auszugeben und die Ausgabe verschiedener Channels zu kennzeichnen + +Wir haben jetzt die normalen und Tumorproben in zwei verschiedene Channels aufgeteilt. Als nächstes werden wir die normalen und Tumorproben basierend auf dem `id`-Feld verbinden. + +--- + +## 3. Channels nach Identifikatoren verbinden + +Im vorherigen Abschnitt haben wir die normalen und Tumorproben in zwei verschiedene Channels aufgeteilt. Diese könnten unabhängig voneinander mit spezifischen Prozessen oder Workflows basierend auf ihrem Typ verarbeitet werden. Aber was passiert, wenn wir die normalen und Tumorproben desselben Patienten vergleichen wollen? An diesem Punkt müssen wir sie wieder zusammenführen und sicherstellen, dass wir die Proben basierend auf ihrem `id`-Feld abgleichen. + +Nextflow enthält viele Methoden zum Kombinieren von Channels, aber in diesem Fall ist der am besten geeignete Operator [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Wenn du mit SQL vertraut bist, verhält er sich wie die `JOIN`-Operation, bei der wir den Schlüssel zum Verbinden und den Typ des Joins angeben. + +### 3.1. `map` und `join` verwenden, um basierend auf Patienten-ID zu kombinieren + +Wenn wir die [`join`-Dokumentation](https://www.nextflow.io/docs/latest/operator.html#join) überprüfen, sehen wir, dass er standardmäßig zwei Channels basierend auf dem ersten Element in jedem Tupel verbindet. + +#### 3.1.1. Datenstruktur überprüfen + +Wenn du die Konsolenausgabe nicht mehr verfügbar hast, lass uns die Pipeline ausführen, um unsere Datenstruktur zu überprüfen und zu sehen, wie wir sie ändern müssen, um auf dem `id`-Feld zu verbinden. + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Wir können sehen, dass das `id`-Feld das erste Element in jeder Meta-Map ist. Damit `join` funktioniert, sollten wir das `id`-Feld in jedem Tupel isolieren. Danach können wir einfach den `join`-Operator verwenden, um die beiden Channels zu kombinieren. + +#### 3.1.2. Das `id`-Feld isolieren + +Um das `id`-Feld zu isolieren, können wir den [`map`-Operator](https://www.nextflow.io/docs/latest/operator.html#map) verwenden, um ein neues Tupel mit dem `id`-Feld als erstes Element zu erstellen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Es mag subtil sein, aber du solltest sehen können, dass das erste Element in jedem Tupel das `id`-Feld ist. + +#### 3.1.3. Die beiden Channels kombinieren + +Jetzt können wir den `join`-Operator verwenden, um die beiden Channels basierend auf dem `id`-Feld zu kombinieren. + +Noch einmal werden wir `view` verwenden, um die verbundenen Ausgaben auszugeben. + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Es ist etwas schwer zu erkennen, weil es so breit ist, aber du solltest sehen können, dass die Proben nach dem `id`-Feld verbunden wurden. Jedes Tupel hat jetzt das Format: + +- `id`: Die Proben-ID +- `normal_meta_map`: Die Metadaten der normalen Probe einschließlich Typ, Replikat und Pfad zur BAM-Datei +- `normal_sample_file`: Die normale Probendatei +- `tumor_meta_map`: Die Metadaten der Tumorprobe einschließlich Typ, Replikat und Pfad zur BAM-Datei +- `tumor_sample`: Die Tumorprobe einschließlich Typ, Replikat und Pfad zur BAM-Datei + +!!! warning + + Der `join`-Operator verwirft alle nicht übereinstimmenden Tupel. In diesem Beispiel haben wir sichergestellt, dass alle Proben für Tumor und Normal übereinstimmen, aber wenn dies nicht wahr ist, musst du den Parameter `remainder: true` verwenden, um die nicht übereinstimmenden Tupel zu behalten. Überprüfe die [Dokumentation](https://www.nextflow.io/docs/latest/operator.html#join) für weitere Details. + +Jetzt weißt du, wie man `map` verwendet, um ein Feld in einem Tupel zu isolieren, und wie man `join` verwendet, um Tupel basierend auf dem ersten Feld zu kombinieren. +Mit diesem Wissen können wir erfolgreich Channels basierend auf einem gemeinsamen Feld kombinieren. + +Als nächstes betrachten wir die Situation, in der du auf mehreren Feldern verbinden möchtest. + +### 3.2. Auf mehreren Feldern verbinden + +Wir haben 2 Replikate für sampleA, aber nur 1 für sampleB und sampleC. In diesem Fall konnten wir sie effektiv verbinden, indem wir das `id`-Feld verwendeten, aber was würde passieren, wenn sie nicht synchron wären? Wir könnten die normalen und Tumorproben verschiedener Replikate durcheinanderbringen! + +Um dies zu vermeiden, können wir auf mehreren Feldern verbinden. Es gibt tatsächlich mehrere Möglichkeiten, dies zu erreichen, aber wir werden uns darauf konzentrieren, einen neuen Verbindungsschlüssel zu erstellen, der sowohl die Proben-`id` als auch die `replicate`-Nummer enthält. + +Beginnen wir damit, einen neuen Verbindungsschlüssel zu erstellen. Wir können dies auf die gleiche Weise wie zuvor tun, indem wir den [`map`-Operator](https://www.nextflow.io/docs/latest/operator.html#map) verwenden, um ein neues Tupel mit den `id`- und `repeat`-Feldern als erstes Element zu erstellen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Jetzt sollten wir sehen, dass die Verbindung erfolgt, aber sowohl die `id`- als auch die `repeat`-Felder verwendet werden. Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Beachte, wie wir ein Tupel mit zwei Elementen (`id`- und `repeat`-Felder) als erstes Element jedes verbundenen Ergebnisses haben. Dies zeigt, wie komplexe Elemente als Verbindungsschlüssel verwendet werden können, was ziemlich komplizierte Übereinstimmungen zwischen Proben aus denselben Bedingungen ermöglicht. + +Wenn du mehr Möglichkeiten erkunden möchtest, auf verschiedenen Schlüsseln zu verbinden, schau dir die [join-Operator-Dokumentation](https://www.nextflow.io/docs/latest/operator.html#join) für zusätzliche Optionen und Beispiele an. + +### 3.3. `subMap` verwenden, um einen neuen Verbindungsschlüssel zu erstellen + +Der vorherige Ansatz verliert die Feldnamen aus unserem Verbindungsschlüssel - die `id`- und `repeat`-Felder werden nur zu einer Liste von Werten. Um die Feldnamen für späteren Zugriff zu behalten, können wir die [`subMap`-Methode](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>) verwenden. + +Die `subMap`-Methode extrahiert nur die angegebenen Schlüssel-Wert-Paare aus einer Map. Hier extrahieren wir nur die `id`- und `repeat`-Felder, um unseren Verbindungsschlüssel zu erstellen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Jetzt haben wir einen neuen Verbindungsschlüssel, der nicht nur die `id`- und `repeat`-Felder enthält, sondern auch die Feldnamen beibehält, sodass wir später über den Namen auf sie zugreifen können, z.B. `meta.id` und `meta.repeat`. + +### 3.4. Eine benannte Closure in map verwenden + +Um Duplikation zu vermeiden und Fehler zu reduzieren, können wir eine benannte Closure verwenden. Eine benannte Closure ermöglicht es uns, eine wiederverwendbare Funktion zu erstellen, die wir an mehreren Stellen aufrufen können. + +Dazu definieren wir zuerst die Closure als neue Variable: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Wir haben die Map-Transformation als benannte Variable definiert, die wir wiederverwenden können. + +Beachte, dass wir den Dateipfad auch mit `file()` in ein Path-Objekt konvertieren, sodass jeder Prozess, der diesen Channel empfängt, die Datei korrekt verarbeiten kann (für weitere Informationen siehe [Arbeiten mit Dateien](./working_with_files.md)). + +Lass uns die Closure in unserem Workflow implementieren: + +=== "Nachher" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + Der `map`-Operator hat von der Verwendung von `{ }` zur Verwendung von `( )` gewechselt, um die Closure als Argument zu übergeben. Dies liegt daran, dass der `map`-Operator eine Closure als Argument erwartet und `{ }` verwendet wird, um eine anonyme Closure zu definieren. Beim Aufrufen einer benannten Closure verwende die `( )`-Syntax. + +Führe den Workflow noch einmal aus, um zu überprüfen, ob alles noch funktioniert: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Die Verwendung einer benannten Closure ermöglicht es uns, dieselbe Transformation an mehreren Stellen wiederzuverwenden, das Fehlerrisiko zu reduzieren und den Code lesbarer und wartbarer zu machen. + +### 3.5. Datenduplikation reduzieren + +Wir haben viele duplizierte Daten in unserem Workflow. Jedes Element in den verbundenen Proben wiederholt die `id`- und `repeat`-Felder. Da diese Informationen bereits im Gruppierungsschlüssel verfügbar sind, können wir diese Redundanz vermeiden. Zur Erinnerung: Unsere aktuelle Datenstruktur sieht so aus: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Da die `id`- und `repeat`-Felder im Gruppierungsschlüssel verfügbar sind, lass uns sie aus dem Rest jedes Channel-Elements entfernen, um Duplikation zu vermeiden. Wir können dies tun, indem wir die `subMap`-Methode verwenden, um eine neue Map nur mit dem `type`-Feld zu erstellen. Dieser Ansatz ermöglicht es uns, alle notwendigen Informationen beizubehalten und gleichzeitig Redundanz in unserer Datenstruktur zu eliminieren. + +=== "Nachher" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Jetzt gibt die Closure ein Tupel zurück, bei dem das erste Element die `id`- und `repeat`-Felder enthält und das zweite Element nur das `type`-Feld enthält. Dies eliminiert Redundanz, indem die `id`- und `repeat`-Informationen einmal im Gruppierungsschlüssel gespeichert werden, während alle notwendigen Informationen erhalten bleiben. + +Führe den Workflow aus, um zu sehen, wie dies aussieht: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Wir können sehen, dass wir die `id`- und `repeat`-Felder nur einmal im Gruppierungsschlüssel angeben und das `type`-Feld in den Probendaten haben. Wir haben keine Informationen verloren, aber wir haben es geschafft, unsere Channel-Inhalte prägnanter zu machen. + +### 3.6. Redundante Informationen entfernen + +Wir haben oben duplizierte Informationen entfernt, aber wir haben immer noch einige andere redundante Informationen in unseren Channels. + +Am Anfang haben wir die normalen und Tumorproben mit `filter` getrennt und sie dann basierend auf `id`- und `repeat`-Schlüsseln verbunden. Der `join`-Operator bewahrt die Reihenfolge, in der Tupel zusammengeführt werden. In unserem Fall, mit normalen Proben auf der linken Seite und Tumorproben auf der rechten, behält der resultierende Channel diese Struktur bei: `id, <normale Elemente>, <Tumor-Elemente>`. + +Da wir die Position jedes Elements in unserem Channel kennen, können wir die Struktur weiter vereinfachen, indem wir die Metadaten `[type:normal]` und `[type:tumor]` weglassen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Führe erneut aus, um das Ergebnis zu sehen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Zusammenfassung + +In diesem Abschnitt hast du gelernt: + +- **Tupel manipulieren**: Wie man `map` verwendet, um ein Feld in einem Tupel zu isolieren +- **Tupel verbinden**: Wie man `join` verwendet, um Tupel basierend auf dem ersten Feld zu kombinieren +- **Verbindungsschlüssel erstellen**: Wie man `subMap` verwendet, um einen neuen Verbindungsschlüssel zu erstellen +- **Benannte Closures**: Wie man eine benannte Closure in map verwendet +- **Verbinden auf mehreren Feldern**: Wie man auf mehreren Feldern verbindet für präzisere Übereinstimmung +- **Datenstruktur-Optimierung**: Wie man die Channel-Struktur durch Entfernen redundanter Informationen optimiert + +Du hast jetzt einen Workflow, der ein Samplesheet aufteilen, die normalen und Tumorproben filtern, sie nach Proben-ID und Replikatnummer verbinden und dann die Ergebnisse ausgeben kann. + +Dies ist ein häufiges Muster in Bioinformatik-Workflows, bei dem du Proben oder andere Arten von Daten nach unabhängiger Verarbeitung abgleichen musst, also ist es eine nützliche Fähigkeit. Als nächstes werden wir uns ansehen, wie man eine Probe mehrmals wiederholt. + +## 4. Proben über Intervalle verteilen + +Ein wichtiges Muster in Bioinformatik-Workflows ist die Verteilung der Analyse über genomische Regionen. Zum Beispiel kann Variant Calling parallelisiert werden, indem das Genom in Intervalle (wie Chromosomen oder kleinere Regionen) aufgeteilt wird. Diese Parallelisierungsstrategie verbessert die Pipeline-Effizienz erheblich, indem die Rechenlast auf mehrere Cores oder Nodes verteilt wird, was die Gesamtausführungszeit reduziert. + +Im folgenden Abschnitt demonstrieren wir, wie du deine Probendaten über mehrere genomische Intervalle verteilst. Wir paaren jede Probe mit jedem Intervall, was die parallele Verarbeitung verschiedener genomischer Regionen ermöglicht. Dies multipliziert unsere Datensatzgröße mit der Anzahl der Intervalle und erstellt mehrere unabhängige Analyseeinheiten, die später wieder zusammengeführt werden können. + +### 4.1. Proben mit `combine` über Intervalle verteilen + +Beginnen wir damit, einen Channel von Intervallen zu erstellen. Um das Leben einfach zu halten, verwenden wir einfach 3 Intervalle, die wir manuell definieren. In einem echten Workflow könntest du diese aus einer Dateieingabe einlesen oder sogar einen Channel mit vielen Intervalldateien erstellen. + +=== "Nachher" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Denk daran, wir wollen jede Probe für jedes Intervall wiederholen. Dies wird manchmal als kartesisches Produkt der Proben und Intervalle bezeichnet. Wir können dies erreichen, indem wir den [`combine`-Operator](https://www.nextflow.io/docs/latest/operator.html#combine) verwenden. Dies nimmt jedes Element aus Channel 1 und wiederholt es für jedes Element in Channel 2. Lass uns einen combine-Operator zu unserem Workflow hinzufügen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Lass uns es jetzt ausführen und sehen, was passiert: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Erfolg! Wir haben jede Probe für jedes einzelne Intervall in unserer 3-Intervall-Liste wiederholt. Wir haben die Anzahl der Elemente in unserem Channel effektiv verdreifacht. + +Es ist jedoch etwas schwer zu lesen, also werden wir es im nächsten Abschnitt aufräumen. + +### 4.2. Den Channel organisieren + +Wir können den `map`-Operator verwenden, um unsere Probendaten aufzuräumen und zu refaktorieren, damit sie leichter verständlich sind. Lass uns die Intervall-Zeichenkette zur Verbindungs-Map am ersten Element verschieben. + +=== "Nachher" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Lass uns Schritt für Schritt aufschlüsseln, was diese Map-Operation macht. + +Zuerst verwenden wir benannte Parameter, um den Code lesbarer zu machen. Durch die Verwendung der Namen `grouping_key`, `normal`, `tumor` und `interval` können wir auf die Elemente im Tupel nach Namen statt nach Index verweisen: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Als nächstes kombinieren wir den `grouping_key` mit dem `interval`-Feld. Der `grouping_key` ist eine Map, die `id`- und `repeat`-Felder enthält. Wir erstellen eine neue Map mit dem `interval` und führen sie mit Groovys Map-Addition (`+`) zusammen: + +```groovy + grouping_key + [interval: interval], +``` + +Schließlich geben wir dies als Tupel mit drei Elementen zurück: die kombinierte Metadaten-Map, die normale Probendatei und die Tumorprobendatei: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Lass uns es erneut ausführen und die Channel-Inhalte überprüfen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_ diff --git a/docs/de/docs/side_quests/workflows_of_workflows.md b/docs/de/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..97622dbaa3 --- /dev/null +++ b/docs/de/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Workflows von Workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Wenn du eine Pipeline entwickelst, stellst du oft fest, dass du ähnliche Abfolgen von Prozessen für verschiedene Datentypen oder Analyseschritte erstellst. Du könntest dazu neigen, diese Prozessabfolgen zu kopieren und einzufügen, was zu dupliziertem Code führt, der schwer zu warten ist; oder du erstellst einen einzigen riesigen Workflow, der schwer zu verstehen und zu modifizieren ist. + +Eine der mächtigsten Funktionen von Nextflow ist die Fähigkeit, komplexe Pipelines aus kleineren, wiederverwendbaren Workflow-Modulen zusammenzusetzen. Dieser modulare Ansatz macht Pipelines einfacher zu entwickeln, zu testen und zu warten. + +### Lernziele + +In dieser Side Quest werden wir erkunden, wie man Workflow-Module entwickelt, die separat getestet und verwendet werden können, wie man diese Module zu einer größeren Pipeline zusammensetzt und wie man den Datenfluss zwischen Modulen verwaltet. + +Am Ende dieser Side Quest kannst du: + +- Komplexe Pipelines in logische, wiederverwendbare Einheiten aufzuteilen +- Jedes Workflow-Modul unabhängig zu testen +- Workflows zu kombinieren, um neue Pipelines zu erstellen +- Gemeinsame Workflow-Module über verschiedene Pipelines hinweg zu teilen +- Deinen Code wartbarer und verständlicher zu machen + +Diese Fähigkeiten helfen dir, komplexe Pipelines zu erstellen und dabei eine saubere, wartbare Code-Struktur beizubehalten. + +### Voraussetzungen + +Bevor du diese Side Quest in Angriff nimmst, solltest du: + +- Das [Hello Nextflow](../hello_nextflow/README.md) Tutorial oder einen vergleichbaren Anfängerkurs abgeschlossen haben. +- Dich sicher im Umgang mit grundlegenden Nextflow-Konzepten und -Mechanismen fühlen (Prozesse, Channels, Operatoren, Module) + +--- + +## 0. Erste Schritte + +#### Öffne die Training-Codespace-Umgebung + +Falls du das noch nicht getan hast, stelle sicher, dass du die Trainingsumgebung wie in der [Umgebungseinrichtung](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/workflows_of_workflows +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis fokussiert: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest ein `modules`-Verzeichnis mit mehreren Prozessdefinitionen, die auf dem aufbauen, was du in 'Hello Nextflow' gelernt hast: + +```console title="Verzeichnisinhalt" +modules/ +├── say_hello.nf # Erstellt eine Begrüßung (aus Hello Nextflow) +├── say_hello_upper.nf # Konvertiert in Großbuchstaben (aus Hello Nextflow) +├── timestamp_greeting.nf # Fügt Zeitstempel zu Begrüßungen hinzu +├── validate_name.nf # Validiert Eingabenamen +└── reverse_text.nf # Kehrt Textinhalt um +``` + +#### Überprüfe die Aufgabenstellung + +Deine Herausforderung besteht darin, diese Module zu zwei separaten Workflows zusammenzusetzen, die wir dann zu einem Haupt-Workflow kombinieren werden: + +- Ein `GREETING_WORKFLOW`, der Namen validiert, Begrüßungen erstellt und Zeitstempel hinzufügt +- Ein `TRANSFORM_WORKFLOW`, der Text in Großbuchstaben umwandelt und umkehrt + +#### Bereitschafts-Checkliste + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Meine Codespace-Umgebung läuft +- [ ] Ich habe mein Arbeitsverzeichnis entsprechend eingestellt +- [ ] Ich verstehe die Aufgabenstellung + +Wenn du alle Kästchen ankreuzen kannst, bist du startklar. + +--- + +## 1. Erstelle den Greeting-Workflow + +Lass uns damit beginnen, einen Workflow zu erstellen, der Namen validiert und Begrüßungen mit Zeitstempel generiert. + +### 1.1. Erstelle die Workflow-Struktur + +```bash title="Erstelle Workflow-Verzeichnis und Datei" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Füge den ersten (Sub-)Workflow-Code hinzu + +Füge diesen Code zu `workflows/greeting.nf` hinzu: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Chain processes: validate -> create greeting -> add timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Dies ist ein vollständiger Workflow mit einer ähnlichen Struktur wie die, die du im 'Hello Nextflow' Tutorial gesehen hast, den wir unabhängig testen können. Lass uns das jetzt ausprobieren: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Das funktioniert wie erwartet, aber um es zusammensetzbar zu machen, müssen wir einige Dinge ändern. + +### 1.3. Mache den Workflow zusammensetzbar + +Zusammensetzbare Workflows haben einige Unterschiede zu denen, die du im 'Hello Nextflow' Tutorial gesehen hast: + +- Der Workflow-Block muss benannt werden +- Eingaben werden mit dem `take:`-Schlüsselwort deklariert +- Der Workflow-Inhalt wird im `main:`-Block platziert +- Ausgaben werden mit dem `emit:`-Schlüsselwort deklariert + +Lass uns den Greeting-Workflow aktualisieren, damit er dieser Struktur entspricht. Ändere den Code wie folgt: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Input channel with names + + main: + // Chain processes: validate -> create greeting -> add timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Original greetings + timestamped = timestamped_ch // Timestamped greetings +} +``` + +Du siehst, dass der Workflow jetzt benannt ist und einen `take:`- und `emit:`-Block hat, und diese sind die Verbindungen, die wir verwenden werden, um einen übergeordneten Workflow zusammenzusetzen. +Der Workflow-Inhalt wird ebenfalls im `main:`-Block platziert. Beachte auch, dass wir die `names_ch`-Eingabe-Channel-Deklaration entfernt haben, da dieser jetzt als Argument an den Workflow übergeben wird. + +Lass uns den Workflow erneut testen, um zu sehen, ob er wie erwartet funktioniert: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Dies weist dich auf ein weiteres neues Konzept hin, einen 'Entry-Workflow'. Der Entry-Workflow ist der Workflow, der aufgerufen wird, wenn du ein Nextflow-Skript ausführst. Standardmäßig verwendet Nextflow einen unbenannten Workflow als Entry-Workflow, wenn vorhanden, und das hast du bisher gemacht, mit Workflow-Blöcken, die so beginnen: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Aber unser Greeting-Workflow hat keinen unbenannten Workflow, sondern wir haben einen benannten Workflow: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +Deshalb hat Nextflow einen Fehler ausgegeben und nicht das getan, was wir wollten. + +Wir haben die `take:`/`emit:`-Syntax nicht hinzugefügt, damit wir den Workflow direkt aufrufen können - wir haben es getan, damit wir ihn mit anderen Workflows zusammensetzen können. Die Lösung besteht darin, ein Hauptskript mit einem unbenannten Entry-Workflow zu erstellen, der unseren benannten Workflow importiert und aufruft. + +### 1.4. Erstelle und teste den Haupt-Workflow + +Jetzt erstellen wir einen Haupt-Workflow, der den `greeting`-Workflow importiert und verwendet. + +Erstelle `main.nf`: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Beachte, dass unser Workflow-Eintrag in dieser Datei unbenannt ist, und das ist so, weil wir ihn als Entry-Workflow verwenden werden. + +Führe dies aus und sieh dir die Ausgabe an: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Es funktioniert! Wir haben den benannten Greeting-Workflow in einen Haupt-Workflow mit einem unbenannten Entry-`workflow`-Block eingebettet. Der Haupt-Workflow verwendet den `GREETING_WORKFLOW`-Workflow fast (nicht ganz) wie einen Prozess und übergibt den `names`-Channel als Argument. + +### Zusammenfassung + +In diesem Abschnitt hast du mehrere wichtige Konzepte gelernt: + +- **Benannte Workflows**: Erstellen eines benannten Workflows (`GREETING_WORKFLOW`), der importiert und wiederverwendet werden kann +- **Workflow-Schnittstellen**: Definition klarer Eingaben mit `take:` und Ausgaben mit `emit:`, um einen zusammensetzbaren Workflow zu erstellen +- **Entry-Points**: Verstehen, dass Nextflow einen unbenannten Entry-Workflow benötigt, um ein Skript auszuführen +- **Workflow-Zusammensetzung**: Importieren und Verwenden eines benannten Workflows innerhalb eines anderen Workflows +- **Workflow-Namensräume**: Zugriff auf Workflow-Ausgaben über den `.out`-Namensraum (`GREETING_WORKFLOW.out.greetings`) + +Du hast jetzt einen funktionierenden Greeting-Workflow, der: + +- Einen Channel mit Namen als Eingabe nimmt +- Jeden Namen validiert +- Eine Begrüßung für jeden gültigen Namen erstellt +- Zeitstempel zu den Begrüßungen hinzufügt +- Sowohl originale als auch mit Zeitstempel versehene Begrüßungen als Ausgaben bereitstellt + +Dieser modulare Ansatz ermöglicht es dir, den Greeting-Workflow unabhängig zu testen oder ihn als Komponente in größeren Pipelines zu verwenden. + +--- + +## 2. Füge den Transform-Workflow hinzu + +Lass uns jetzt einen Workflow erstellen, der Texttransformationen auf die Begrüßungen anwendet. + +### 2.1. Erstelle die Workflow-Datei + +```bash +touch workflows/transform.nf +``` + +### 2.2. Füge den Workflow-Code hinzu + +Füge diesen Code zu `workflows/transform.nf` hinzu: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Input channel with messages + + main: + // Apply transformations in sequence + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Uppercase greetings + reversed = reversed_ch // Reversed uppercase greetings +} +``` + +Wir werden die Erklärung der zusammensetzbaren Syntax hier nicht wiederholen, aber beachte, dass der benannte Workflow wieder mit einem `take:`- und `emit:`-Block deklariert ist und der Workflow-Inhalt im `main:`-Block platziert ist. + +### 2.3. Aktualisiere den Haupt-Workflow + +Aktualisiere `main.nf`, um beide Workflows zu verwenden: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Run the greeting workflow + GREETING_WORKFLOW(names) + + // Run the transform workflow + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // View results + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Führe die vollständige Pipeline aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Wenn du dir eine dieser umgekehrten Dateien ansiehst, wirst du sehen, dass es die umgekehrte Großbuchstabenversion der Begrüßung ist: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Umgekehrter Dateiinhalt" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Zusammenfassung + +Du solltest jetzt eine vollständige Pipeline haben, die: + +- Namen durch den Greeting-Workflow verarbeitet +- Die Begrüßungen mit Zeitstempel in den Transform-Workflow einspeist +- Sowohl Großbuchstaben- als auch umgekehrte Versionen der Begrüßungen produziert + +--- + +## Zusammenfassung + +In dieser Side Quest haben wir das mächtige Konzept der Workflow-Zusammensetzung in Nextflow erkundet, das es uns ermöglicht, komplexe Pipelines aus kleineren, wiederverwendbaren Komponenten zu erstellen. + +Dieser modulare Ansatz bietet mehrere Vorteile gegenüber monolithischen Pipelines: + +- Jeder Workflow kann unabhängig entwickelt, getestet und debuggt werden +- Workflows können über verschiedene Pipelines hinweg wiederverwendet werden +- Die Gesamtstruktur der Pipeline wird lesbarer und wartbarer +- Änderungen an einem Workflow wirken sich nicht zwangsläufig auf andere aus, wenn die Schnittstellen konsistent bleiben +- Entry-Points können konfiguriert werden, um verschiedene Teile deiner Pipeline nach Bedarf auszuführen + +_Es ist jedoch wichtig zu beachten, dass das Aufrufen von Workflows zwar ein bisschen wie das Aufrufen von Prozessen ist, aber nicht tatsächlich dasselbe ist. Du kannst beispielsweise keinen Workflow N-mal ausführen, indem du ihn mit einem Channel der Größe N aufrufst - du müsstest einen Channel der Größe N an den Workflow übergeben und intern iterieren._ + +Die Anwendung dieser Techniken in deiner eigenen Arbeit wird es dir ermöglichen, anspruchsvollere Nextflow-Pipelines zu erstellen, die komplexe bioinformatische Aufgaben bewältigen können und dabei wartbar und skalierbar bleiben. + +### Wichtige Muster + +1. **Workflow-Struktur**: Wir haben klare Eingaben und Ausgaben für jeden Workflow mit der `take:`- und `emit:`-Syntax definiert, um gut definierte Schnittstellen zwischen Komponenten zu erstellen, und die Workflow-Logik im `main:`-Block eingeschlossen. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Input channels are declared here + input_ch + + main: + // Workflow logic goes here + // This is where processes are called and channels are manipulated + result_ch = SOME_PROCESS(input_ch) + + emit: + // Output channels are declared here + output_ch = result_ch + } + ``` + +2. **Workflow-Imports:** Wir haben zwei unabhängige Workflow-Module erstellt und sie mit Include-Anweisungen in eine Haupt-Pipeline importiert. + + - Einen einzelnen Workflow einbinden + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Mehrere Workflows einbinden + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Mit Alias einbinden, um Namenskonflikte zu vermeiden + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Entry-Points**: Nextflow benötigt einen unbenannten Entry-Workflow, um zu wissen, wo die Ausführung beginnen soll. Dieser Entry-Workflow ruft deine benannten Workflows auf. + + - Unbenannter Workflow (Entry-Point) + + ```groovy + workflow { + // This is the entry point when the script is run + NAMED_WORKFLOW(input_ch) + } + ``` + + - Benannter Workflow (wird vom Entry-Workflow aufgerufen) + + ```groovy + workflow NAMED_WORKFLOW { + // Must be called from the entry workflow + } + ``` + +4. **Datenfluss verwalten:** Wir haben gelernt, wie man auf Workflow-Ausgaben über die Namensraum-Notation (`WORKFLOW_NAME.out.channel_name`) zugreift und sie an andere Workflows übergibt. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Zusätzliche Ressourcen + +- [Nextflow Workflow-Dokumentation](https://www.nextflow.io/docs/latest/workflow.html) +- [Channel-Operatoren-Referenz](https://www.nextflow.io/docs/latest/operator.html) +- [Error-Strategy-Dokumentation](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## Wie geht es weiter? + +Kehre zum [Menü der Side Quests](./index.md) zurück oder klicke auf den Button unten rechts auf der Seite, um mit dem nächsten Thema in der Liste fortzufahren. diff --git a/docs/de/docs/side_quests/working_with_files.md b/docs/de/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..f9c2c9131f --- /dev/null +++ b/docs/de/docs/side_quests/working_with_files.md @@ -0,0 +1,1185 @@ +# Verarbeitung von Datei-Eingaben + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Wissenschaftliche Analyse-Workflows beinhalten oft die Verarbeitung großer Mengen von Dateien. +Nextflow bietet leistungsstarke Werkzeuge, um Dateien effizient zu verarbeiten und hilft dir, deine Daten mit minimalem Code zu organisieren und zu verarbeiten. + +### Lernziele + +In dieser Side Quest werden wir erkunden, wie Nextflow mit Dateien umgeht, von grundlegenden Dateioperationen bis hin zu fortgeschritteneren Techniken für die Arbeit mit Dateisammlungen. +Du wirst lernen, wie man Metadaten aus Dateinamen extrahiert, was eine häufige Anforderung in wissenschaftlichen Analyse-Pipelines ist. + +Am Ende dieser Side Quest kannst du: + +- Path-Objekte aus Dateipfad-Strings mit der `file()`-Methode von Nextflow zu erstellen +- Auf Dateiattribute wie Name, Extension und übergeordnetes Verzeichnis zuzugreifen +- Sowohl lokale als auch entfernte Dateien transparent über URIs zu verarbeiten +- Channels zur Automatisierung der Dateiverarbeitung mit `channel.fromPath()` und `channel.fromFilePairs()` zu verwenden +- Metadaten aus Dateinamen mittels String-Manipulation zu extrahieren und zu strukturieren +- Zusammengehörige Dateien mittels Pattern Matching und Glob-Ausdrücken zu gruppieren +- Dateioperationen in Nextflow-Prozesse mit korrekter Input-Verarbeitung zu integrieren +- Prozess-Ausgaben mittels metadatengesteuerter Verzeichnisstrukturen zu organisieren + +Diese Fähigkeiten helfen dir, Workflows zu erstellen, die verschiedene Arten von Datei-Eingaben mit großer Flexibilität verarbeiten können. + +### Voraussetzungen + +Bevor du diese Side Quest angehst, solltest du: + +- Das [Hello Nextflow](../../hello_nextflow/)-Tutorial oder einen gleichwertigen Einsteigerkurs abgeschlossen haben. +- Mit grundlegenden Nextflow-Konzepten und -Mechanismen vertraut sein (Prozesse, Channels, Operatoren) + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. Erste Schritte + +#### Öffne die Trainingsumgebung im Codespace + +Falls du das noch nicht getan hast, stelle sicher, dass du die Trainingsumgebung wie in der [Umgebungseinrichtung](../envsetup/index.md) beschrieben öffnest. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Wechsle in das Projektverzeichnis + +Lass uns in das Verzeichnis wechseln, in dem sich die Dateien für dieses Tutorial befinden. + +```bash +cd side-quests/working_with_files +``` + +Du kannst VSCode so einstellen, dass es sich auf dieses Verzeichnis fokussiert: + +```bash +code . +``` + +#### Überprüfe die Materialien + +Du findest eine einfache Workflow-Datei namens `main.nf`, ein `modules`-Verzeichnis mit zwei Moduldateien und ein `data`-Verzeichnis mit einigen Beispieldateien. + +??? abstract "Verzeichnisinhalte" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Dieses Verzeichnis enthält Paired-End-Sequenzierungsdaten von drei Patienten (A, B, C). + +Für jeden Patienten haben wir Proben vom Typ `tumor` (typischerweise aus Tumorbiopsien) oder `normal` (aus gesundem Gewebe oder Blut). +Falls du mit Krebsanalysen nicht vertraut bist: Dies entspricht einem experimentellen Modell, das gepaarte Tumor/Normal-Proben für kontrastive Analysen verwendet. + +Speziell für Patient A haben wir zwei Sets technischer Replikate (Wiederholungen). + +Die Sequenzierungsdateien sind mit der typischen `_R1_`- und `_R2_`-Konvention für sogenannte 'Forward Reads' und 'Reverse Reads' benannt. + +_Mach dir keine Sorgen, wenn du mit diesem experimentellen Design nicht vertraut bist, es ist nicht kritisch für das Verständnis dieses Tutorials._ + +#### Überprüfe die Aufgabenstellung + +Deine Herausforderung besteht darin, einen Nextflow-Workflow zu schreiben, der: + +1. Eingabedateien mit Nextflows Dateiverarbeitungsmethoden **lädt** +2. Metadaten (Patienten-ID, Replikat, Probentyp) aus der Dateinamenstruktur **extrahiert** +3. Gepaarte Dateien (R1/R2) mit `channel.fromFilePairs()` **gruppiert** +4. Die Dateien mit einem bereitgestellten Analysemodul **verarbeitet** +5. Ausgaben in einer Verzeichnisstruktur basierend auf den extrahierten Metadaten **organisiert** + +#### Checkliste zur Bereitschaft + +Denkst du, du bist bereit einzutauchen? + +- [ ] Ich verstehe das Ziel dieses Kurses und seine Voraussetzungen +- [ ] Mein Codespace läuft +- [ ] Ich habe mein Arbeitsverzeichnis korrekt eingestellt +- [ ] Ich verstehe die Aufgabenstellung + +Wenn du alle Kästchen abhaken kannst, bist du startklar. + +--- + +## 1. Grundlegende Dateioperationen + +### 1.1. Identifiziere den Typ eines Objekts mit `.class` + +Wirf einen Blick auf die Workflow-Datei `main.nf`: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +Dies ist ein Mini-Workflow (ohne Prozesse), der auf einen einzelnen Dateipfad in seinem workflow verweist und ihn dann zusammen mit seiner Klasse auf der Konsole ausgibt. + +??? info "Was ist `.class`?" + + In Nextflow sagt uns `.class`, mit welchem Objekttyp wir arbeiten. Es ist wie die Frage "Was für eine Art von Ding ist das?" zu stellen, um herauszufinden, ob es ein String, eine Zahl, eine Datei oder etwas anderes ist. + Dies hilft uns, den Unterschied zwischen einem einfachen String und einem Path-Objekt in den nächsten Abschnitten zu illustrieren. + +Lass uns den Workflow ausführen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Wie du siehst, hat Nextflow den String-Pfad genau so ausgegeben, wie wir ihn geschrieben haben. + +Dies ist nur eine Textausgabe; Nextflow hat noch nichts Besonderes damit gemacht. +Wir haben auch bestätigt, dass dies aus Sicht von Nextflow nur ein String (der Klasse `java.lang.String`) ist. +Das macht Sinn, da wir Nextflow noch nicht mitgeteilt haben, dass es sich um eine Datei handelt. + +### 1.2. Erstelle ein Path-Objekt mit file() + +Wir können Nextflow mitteilen, wie Dateien zu verarbeiten sind, indem wir [Path-Objekte](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) aus Pfad-Strings erstellen. + +In unserem Workflow können wir den String-Pfad `data/patientA_rep1_normal_R1_001.fastq.gz` mit der `file()`-Methode in ein Path-Objekt umwandeln, das Zugriff auf Dateieigenschaften und -operationen bietet. + +Bearbeite `main.nf`, um den String wie folgt mit `file()` zu umschließen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Führe jetzt den Workflow erneut aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Dieses Mal siehst du den vollständigen absoluten Pfad statt des relativen Pfads, den wir als Eingabe bereitgestellt haben. + +Nextflow hat unseren String in ein Path-Objekt umgewandelt und ihn zur tatsächlichen Dateiposition im System aufgelöst. +Der Dateipfad wird nun absolut sein, wie in `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Beachte auch, dass die Path-Objekt-Klasse `sun.nio.fs.UnixPath` ist: Dies ist Nextflows Art, lokale Dateien zu repräsentieren. +Wie wir später sehen werden, haben entfernte Dateien andere Klassennamen (wie `nextflow.file.http.XPath` für HTTP-Dateien), aber sie funktionieren alle genau gleich und können identisch in deinen Workflows verwendet werden. + +!!! tip + + **Der Hauptunterschied:** + + - **Pfad-String**: Nur Text, den Nextflow als Zeichen behandelt + - **Path-Objekt**: Eine intelligente Dateireferenz, mit der Nextflow arbeiten kann + + Stell es dir so vor: Ein Pfad-String ist wie eine auf Papier geschriebene Adresse, während ein Path-Objekt wie eine im GPS-Gerät geladene Adresse ist, die weiß, wie man dorthin navigiert und dir Details über die Route mitteilen kann. + +### 1.3. Zugriff auf Dateiattribute + +Warum ist das hilfreich? Nun, da Nextflow jetzt versteht, dass `myFile` ein Path-Objekt und nicht nur ein String ist, können wir auf die verschiedenen Attribute des Path-Objekts zugreifen. + +Lass uns unseren Workflow aktualisieren, um die eingebauten Dateiattribute auszugeben: + +=== "Nachher" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Du siehst die verschiedenen Dateiattribute, die oben auf der Konsole ausgegeben werden. + +### 1.4. Die Datei an einen Prozess übergeben + +Der Unterschied zwischen Strings und Path-Objekten wird kritisch, wenn du anfängst, tatsächliche Workflows mit Prozessen zu erstellen. +Bisher haben wir überprüft, dass Nextflow unsere Eingabedatei nun als Datei behandelt, aber lass uns sehen, ob wir tatsächlich etwas mit dieser Datei in einem Prozess ausführen können. + +#### 1.4.1. Importiere den Prozess und untersuche den Code + +Wir stellen dir ein vorgefertigtes Prozessmodul namens `COUNT_LINES` zur Verfügung, das eine Dateieingabe nimmt und zählt, wie viele Zeilen sie enthält. + +Um den Prozess im Workflow zu verwenden, musst du nur eine include-Anweisung vor dem workflow-Block hinzufügen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Du kannst die Moduldatei öffnen, um ihren Code zu untersuchen: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Wie du siehst, ist es ein ziemlich einfaches kleines Script, das die Datei entpackt und zählt, wie viele Zeilen sie enthält. + +??? info "Was macht `debug true`?" + + Die `debug true`-Direktive in der Prozessdefinition veranlasst Nextflow, die Ausgabe deines Scripts (wie die Zeilenanzahl "40") direkt im Ausführungslog auszugeben. + Ohne dies würdest du nur den Prozessausführungsstatus sehen, aber nicht die tatsächliche Ausgabe deines Scripts. + + Für weitere Informationen zum Debuggen von Nextflow-Workflows siehe die Side Quest [Debugging Nextflow Workflows](debugging.md). + +#### 1.4.2. Füge einen Aufruf von `COUNT_LINES` hinzu + +Nun, da der Prozess für den Workflow verfügbar ist, können wir einen Aufruf des `COUNT_LINES`-Prozesses hinzufügen, um ihn auf der Eingabedatei auszuführen. + +Nimm folgende Änderungen am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Und jetzt führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Dies zeigt, dass wir in der Lage sind, die Datei innerhalb eines Prozesses angemessen zu verarbeiten. + +Konkret hat Nextflow folgende Operationen erfolgreich durchgeführt: + +- Die Datei ins Arbeitsverzeichnis gestaged +- Die .gz-Datei dekomprimiert +- Die Zeilen gezählt (40 Zeilen in diesem Fall) +- Ohne Fehler abgeschlossen + +Der Schlüssel zu dieser reibungslosen Operation ist, dass wir Nextflow explizit mitteilen, dass unsere Eingabe eine Datei ist und als solche behandelt werden soll. + +### 1.5. Fehlerbehebung bei grundlegenden Dateieingabe-Fehlern + +Dies führt oft zu Verwirrung bei Nextflow-Neulingen, also nehmen wir uns ein paar Minuten Zeit, um zu schauen, was passiert, wenn du es falsch machst. + +Es gibt zwei Hauptstellen, an denen du die Dateiverarbeitung falsch machen kannst: auf Workflow-Ebene und auf Prozess-Ebene. + +#### 1.5.1. Fehler auf Workflow-Ebene + +Lass uns sehen, was passiert, wenn wir zur Behandlung der Datei als String zurückkehren, wenn wir die Eingabe im workflow-Block angeben. + +Nimm folgende Änderungen am Workflow vor und stelle sicher, dass du die pfadspezifischen print-Anweisungen auskommentierst: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Print file attributes + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +Und jetzt führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Das ist der wichtige Teil: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Wenn du eine `path`-Eingabe spezifizierst, validiert Nextflow, dass du tatsächliche Dateireferenzen übergibst, nicht nur Strings. +Dieser Fehler teilt dir mit, dass `'data/patientA_rep1_normal_R1_001.fastq.gz'` kein gültiger Pfadwert ist, weil es ein String ist, kein Path-Objekt. + +Nextflow hat das Problem sofort erkannt und gestoppt, bevor der Prozess überhaupt gestartet wurde. + +#### 1.5.2. Fehler auf Prozess-Ebene + +Die andere Stelle, an der wir vergessen könnten zu spezifizieren, dass Nextflow die Eingabe als Datei behandeln soll, ist in der Prozessdefinition. + +!!! warning "Behalte den Workflow-Fehler aus 1.5.1" + + Damit dieser Test korrekt funktioniert, belasse den Workflow in seinem fehlerhaften Zustand (mit einem einfachen String statt `file()`). + In Kombination mit `val` im Prozess erzeugt dies den unten gezeigten Fehler. + +Nimm folgende Änderung am Modul vor: + +=== "Nachher" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Vorher" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +Und jetzt führe den Workflow erneut aus: + +```bash +nextflow run main.nf +``` + +??? failure "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Dies zeigt viele Details über den Fehler, da der Prozess so eingestellt ist, dass er Debugging-Informationen ausgibt, wie oben erwähnt. + +Dies sind die relevantesten Abschnitte: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Dies besagt, dass das System die Datei nicht finden konnte; wenn du jedoch den Pfad nachschlägst, gibt es dort eine Datei mit diesem Namen. + +Als wir dies ausführten, hat Nextflow den String-Wert an das Script weitergegeben, aber es hat die tatsächliche Datei nicht ins Arbeitsverzeichnis _gestaged_. +Also versuchte der Prozess, den relativen String `data/patientA_rep1_normal_R1_001.fastq.gz` zu verwenden, aber diese Datei existiert nicht im Prozess-Arbeitsverzeichnis. + +Zusammengenommen zeigen diese beiden Beispiele, wie wichtig es ist, Nextflow mitzuteilen, ob eine Eingabe als Datei verarbeitet werden soll. + +!!! note + + Stelle sicher, dass du beide absichtlichen Fehler korrigierst, bevor du mit dem nächsten Abschnitt fortfährst. + +### Zusammenfassung + +- Pfad-Strings vs. Path-Objekte: Strings sind nur Text, Path-Objekte sind intelligente Dateireferenzen +- Die `file()`-Methode wandelt einen String-Pfad in ein Path-Objekt um, mit dem Nextflow arbeiten kann +- Du kannst auf Dateieigenschaften wie `name`, `simpleName`, `extension` und `parent` [über Dateiattribute](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) zugreifen +- Die Verwendung von Path-Objekten anstelle von Strings ermöglicht es Nextflow, Dateien in deinem Workflow ordnungsgemäß zu verwalten +- Prozess-Input-Ergebnisse: Eine ordnungsgemäße Dateiverarbeitung erfordert Path-Objekte, keine Strings, um sicherzustellen, dass Dateien korrekt gestaged und für die Verwendung durch Prozesse zugänglich sind. + +--- + +## 2. Verwendung entfernter Dateien + +Eines der Hauptmerkmale von Nextflow ist die Fähigkeit, nahtlos zwischen lokalen Dateien (auf demselben Rechner) und entfernten, über das Internet zugänglichen Dateien zu wechseln. + +Wenn du es richtig machst, solltest du nie die Logik deines Workflows ändern müssen, um Dateien aus verschiedenen Speicherorten zu verarbeiten. +Alles, was du tun musst, um eine entfernte Datei zu verwenden, ist das entsprechende Präfix im Dateipfad anzugeben, wenn du ihn dem Workflow bereitstellst. + +Zum Beispiel hat `/path/to/data` kein Präfix, was darauf hinweist, dass es sich um einen 'normalen' lokalen Dateipfad handelt, während `s3://path/to/data` das `s3://`-Präfix enthält, was darauf hinweist, dass es sich in Amazons S3-Objektspeicher befindet. + +Viele verschiedene Protokolle werden unterstützt: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Um eines davon zu verwenden, gib einfach das entsprechende Präfix im String an, der dann technisch als Uniform Resource Identifier (URI) anstelle eines Dateipfads bezeichnet wird. +Nextflow übernimmt die Authentifizierung und das Staging der Dateien an den richtigen Ort, das Herunterladen oder Hochladen und alle anderen Dateioperationen, die du erwarten würdest. + +Die Hauptstärke dieses Systems besteht darin, dass es uns ermöglicht, zwischen Umgebungen zu wechseln, ohne die Pipeline-Logik zu ändern. +Du kannst zum Beispiel mit einem kleinen lokalen Testdatensatz entwickeln, bevor du zu einem vollständigen Testdatensatz wechselst, der sich in entferntem Speicher befindet, indem du einfach den URI änderst. + +### 2.1. Verwende eine Datei aus dem Internet + +Lass uns dies testen, indem wir den lokalen Pfad, den wir unserem Workflow bereitstellen, durch einen HTTPS-Pfad ersetzen, der auf eine Kopie derselben Daten zeigt, die in Github gespeichert ist. + +!!! warning + + Dies funktioniert nur, wenn du eine aktive Internetverbindung hast. + +Öffne `main.nf` erneut und ändere den Eingabepfad wie folgt: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Using a remote file from the internet + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Lass uns den Workflow ausführen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Es funktioniert! Du kannst sehen, dass sich sehr wenig geändert hat. + +Der eine Unterschied in der Konsolenausgabe ist, dass die Pfad-Objekt-Klasse jetzt `nextflow.file.http.XPath` ist, während sie für den lokalen Pfad `sun.nio.fs.UnixPath` war. +Du musst dir diese Klassen nicht merken; wir erwähnen dies nur, um zu demonstrieren, dass Nextflow die verschiedenen Speicherorte angemessen identifiziert und verarbeitet. + +Hinter den Kulissen hat Nextflow die Datei in ein Staging-Verzeichnis innerhalb des Arbeitsverzeichnisses heruntergeladen. +Diese gestaged Datei kann dann als lokale Datei behandelt und in das entsprechende Prozessverzeichnis per Symlink eingebunden werden. + +Du kannst überprüfen, dass dies geschehen ist, indem du den Inhalt des Arbeitsverzeichnisses an der Hash-Position des Prozesses ansiehst. + +??? abstract "Arbeitsverzeichnisinhalte" + + Wenn der Prozess-Hash `8a/2ab7ca` war, könntest du das Arbeitsverzeichnis erkunden: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Der Symlink zeigt auf eine gestaged Kopie der entfernten Datei, die Nextflow automatisch heruntergeladen hat. + +Beachte, dass bei größeren Dateien der Download-Schritt im Vergleich zur Ausführung auf lokalen Dateien zusätzliche Zeit in Anspruch nimmt. +Allerdings prüft Nextflow, ob es bereits eine gestaged Kopie hat, um unnötige Downloads zu vermeiden. +Wenn du also erneut auf derselben Datei ausführst und die gestaged Datei nicht gelöscht hast, wird Nextflow die gestaged Kopie verwenden. + +Dies zeigt, wie einfach es ist, mit Nextflow zwischen lokalen und entfernten Daten zu wechseln, was ein Hauptmerkmal von Nextflow ist. + +!!! note + + Die eine wichtige Ausnahme von diesem Prinzip ist, dass du keine Glob-Muster oder Verzeichnispfade mit HTTPS verwenden kannst, da HTTPS keine mehreren Dateien auflisten kann, sodass du exakte Datei-URLs angeben musst. + Andere Speicherprotokolle wie Blob Storage (`s3://`, `az://`, `gs://`) können jedoch sowohl Globs als auch Verzeichnispfade verwenden. + + So könntest du Glob-Muster mit Cloud-Speicher verwenden: + + ```groovy title="Cloud-Speicher-Beispiele (in dieser Umgebung nicht ausführbar)" + // S3 mit Glob-Mustern - würde mehrere Dateien matchen + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage mit Glob-Mustern + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage mit Glob-Mustern + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Wir zeigen dir im nächsten Abschnitt, wie du in der Praxis mit Globs arbeitest. + +### 2.2. Wechsle zurück zur lokalen Datei + +Wir werden für den Rest dieser Side Quest wieder unsere lokalen Beispieldateien verwenden, also lass uns den Workflow-Input zurück auf die ursprüngliche Datei umstellen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Zusammenfassung + +- Auf entfernte Daten wird über einen URI zugegriffen (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow lädt die Daten automatisch herunter und stellt sie am richtigen Ort bereit, solange diese Pfade an Prozesse übergeben werden +- Schreibe keine Logik zum Herunterladen oder Hochladen entfernter Dateien! +- Lokale und entfernte Dateien erzeugen verschiedene Objekttypen, funktionieren aber identisch +- **Wichtig**: HTTP/HTTPS funktionieren nur mit einzelnen Dateien (keine Glob-Muster) +- Cloud-Speicher (S3, Azure, GCS) unterstützt sowohl einzelne Dateien als auch Glob-Muster +- Du kannst nahtlos zwischen lokalen und entfernten Datenquellen wechseln, ohne Code-Logik zu ändern (solange das Protokoll deine erforderlichen Operationen unterstützt) + +--- + +## 3. Verwendung der `fromPath()` Channel Factory + +Bisher haben wir mit jeweils einer einzelnen Datei gearbeitet, aber in Nextflow möchten wir normalerweise einen Input-Channel mit mehreren zu verarbeitenden Eingabedateien erstellen. + +Eine naive Art, dies zu tun, wäre die `file()`-Methode mit [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) zu kombinieren, etwa so: + +```groovy title="Syntaxbeispiel" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Das funktioniert, ist aber umständlich. + +!!! tip "Wann `file()` vs. `channel.fromPath()` verwenden" + + - Verwende `file()`, wenn du ein einzelnes Path-Objekt für direkte Manipulation benötigst (Prüfen, ob eine Datei existiert, Lesen ihrer Attribute oder Übergabe an einen einzelnen Prozessaufruf) + - Verwende `channel.fromPath()`, wenn du einen Channel benötigst, der mehrere Dateien enthalten kann, insbesondere mit Glob-Mustern, oder wenn Dateien durch mehrere Prozesse fließen werden + +Hier kommt [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) ins Spiel: eine bequeme Channel Factory, die alle Funktionalität bündelt, die wir benötigen, um einen Channel aus einem oder mehreren statischen Datei-Strings sowie Glob-Mustern zu generieren. + +### 3.1. Füge die Channel Factory hinzu + +Lass uns unseren Workflow aktualisieren, um `channel.fromPath` zu verwenden. + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Print file attributes + /* Comment these out for now, we'll come back to them! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Count the lines in the file + // COUNT_LINES(myFile) + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +Wir haben auch den Code auskommentiert, der die Attribute ausgibt, und stattdessen eine `.view`-Anweisung hinzugefügt, um nur den Dateinamen auszugeben. + +Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Wie du sehen kannst, wird der Dateipfad als `Path`-Objekt im Channel geladen. +Dies ist ähnlich wie bei `file()`, nur dass wir jetzt einen Channel haben, in den wir bei Bedarf mehr Dateien laden können. + +Die Verwendung von `channel.fromPath()` ist eine bequeme Möglichkeit, einen neuen Channel zu erstellen, der mit einer Liste von Dateien gefüllt ist. + +### 3.2. Zeige Attribute von Dateien im Channel an + +In unserem ersten Versuch mit der Channel Factory haben wir den Code vereinfacht und nur den Dateinamen ausgegeben. + +Lass uns zurück zur Ausgabe der vollständigen Dateiattribute gehen: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Count the lines in the file + COUNT_LINES(ch_files) + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Count the lines in the file + // COUNT_LINES(ch_files) + ``` + +Wir aktivieren auch den `COUNT_LINES`-Prozessaufruf erneut, um zu überprüfen, dass die Dateiverarbeitung mit unserem Channel-basierten Ansatz noch korrekt funktioniert. + +Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Und da hast du es, dieselben Ergebnisse wie zuvor, aber jetzt haben wir die Datei in einem Channel, sodass wir mehr hinzufügen können. + +### 3.3. Verwendung eines Globs zum Matchen mehrerer Dateien + +Es gibt mehrere Möglichkeiten, mehr Dateien in den Channel zu laden. +Hier zeigen wir dir, wie man Glob-Muster verwendet, eine bequeme Möglichkeit, Datei- und Verzeichnisnamen basierend auf Wildcard-Zeichen zu matchen und abzurufen. +Der Prozess des Matchens dieser Muster wird "Globbing" oder "Filename Expansion" genannt. + +!!! note + + Wie bereits erwähnt, unterstützt Nextflow Globbing zur Verwaltung von Input- und Output-Dateien in den meisten Fällen, außer bei HTTPS-Dateipfaden, da HTTPS keine mehreren Dateien auflisten kann. + +Angenommen, wir möchten beide Dateien in einem Paar von Dateien abrufen, die mit einem bestimmten Patienten, `patientA`, assoziiert sind: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Da der einzige Unterschied zwischen den Dateinamen die Replikat-Nummer ist, _d.h._ die Zahl nach `R`, können wir das Wildcard-Zeichen `*` anstelle der Zahl wie folgt verwenden: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +Das ist das Glob-Muster, das wir benötigen. + +Jetzt müssen wir nur noch den Dateipfad in der Channel Factory aktualisieren, um dieses Glob-Muster wie folgt zu verwenden: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow erkennt automatisch, dass dies ein Glob-Muster ist und wird es entsprechend verarbeiten. + +Führe den Workflow aus, um dies zu testen: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Wie du sehen kannst, haben wir jetzt zwei Path-Objekte in unserem Channel, was zeigt, dass Nextflow die Dateinamen-Expansion korrekt durchgeführt und beide Dateien wie erwartet geladen und verarbeitet hat. + +Mit dieser Methode können wir beliebig viele oder wenige Dateien abrufen, indem wir einfach das Glob-Muster ändern. Wenn wir es großzügiger gestalten würden, zum Beispiel indem wir alle variablen Teile der Dateinamen durch `*` ersetzen (_z.B._ `data/patient*_rep*_*_R*_001.fastq.gz`), könnten wir alle Beispieldateien im `data`-Verzeichnis erfassen. + +### Zusammenfassung + +- `channel.fromPath()` erstellt einen Channel mit Dateien, die einem Muster entsprechen +- Jede Datei wird als separates Element im Channel ausgegeben +- Wir können ein Glob-Muster verwenden, um mehrere Dateien zu matchen +- Dateien werden automatisch in Path-Objekte mit vollständigen Attributen umgewandelt +- Die `.view()`-Methode ermöglicht die Inspektion der Channel-Inhalte + +--- + +## 4. Extraktion grundlegender Metadaten aus Dateinamen + +In den meisten wissenschaftlichen Bereichen ist es sehr üblich, Metadaten in den Namen der Dateien zu kodieren, die die Daten enthalten. +Zum Beispiel werden in der Bioinformatik Dateien mit Sequenzierungsdaten oft so benannt, dass Informationen über die Probe, Bedingung, Replikat und Read-Nummer kodiert sind. + +Wenn die Dateinamen nach einer konsistenten Konvention konstruiert sind, kannst du diese Metadaten auf standardisierte Weise extrahieren und im Verlauf deiner Analyse verwenden. +Das ist natürlich ein großes 'Wenn', und du solltest sehr vorsichtig sein, wenn du dich auf die Dateinamenstruktur verlässt; aber die Realität ist, dass dieser Ansatz sehr weit verbreitet ist, also schauen wir uns an, wie es in Nextflow gemacht wird. + +Im Fall unserer Beispieldaten wissen wir, dass die Dateinamen konsistent strukturierte Metadaten enthalten. +Zum Beispiel kodiert der Dateiname `patientA_rep1_normal_R2_001` Folgendes: + +- Patienten-ID: `patientA` +- Replikat-ID: `rep1` +- Probentyp: `normal` (im Gegensatz zu `tumor`) +- Read-Set: `R1` (im Gegensatz zu `R2`) + +Wir werden unseren Workflow in drei Schritten modifizieren, um diese Informationen abzurufen: + +1. Den `simpleName` der Datei abrufen, der die Metadaten enthält +2. Die Metadaten mit einer Methode namens `tokenize()` trennen +3. Eine Map verwenden, um die Metadaten zu organisieren + +!!! warning + + Du solltest niemals sensible Informationen in Dateinamen kodieren, wie Patientennamen oder andere identifizierende Merkmale, da dies die Privatsphäre von Patienten oder andere relevante Sicherheitsbeschränkungen gefährden kann. + +### 4.1. Abrufen des `simpleName` + +Der `simpleName` ist ein Dateiattribut, das dem Dateinamen ohne Pfad und Extension entspricht. + +Nimm folgende Änderungen am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +Dies ruft den `simpleName` ab und verknüpft ihn mit dem vollständigen Dateiobjekt über eine `map()`-Operation. + +Führe den Workflow aus, um zu testen, dass es funktioniert: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Jedes Element im Channel ist jetzt ein Tupel, das den `simpleName` und das ursprüngliche Dateiobjekt enthält. + +### 4.2. Extrahiere die Metadaten aus dem `simplename` + +Zu diesem Zeitpunkt sind die Metadaten, die wir wollen, im `simplename` eingebettet, aber wir können nicht direkt auf einzelne Elemente zugreifen. +Also müssen wir den `simplename` in seine Komponenten aufteilen. +Glücklicherweise sind diese Komponenten im ursprünglichen Dateinamen einfach durch Unterstriche getrennt, sodass wir eine gängige Nextflow-Methode namens `tokenize()` anwenden können, die perfekt für diese Aufgabe ist. + +Nimm folgende Änderungen am Workflow vor: + +=== "Nachher" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Vorher" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +Die `tokenize()`-Methode teilt den `simpleName`-String überall dort, wo sie Unterstriche findet, und gibt eine Liste mit den Teilstrings zurück. + +Führe den Workflow aus: + +```bash +nextflow run main.nf +``` + +??? success "Befehlsausgabe" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Jetzt enthält das Tupel für jedes Element in unserem Channel die Liste der Metadaten (_z.B._ `[patientA, rep1, normal, R1, 001]`) und das ursprüngliche Dateiobjekt. + +Das ist großartig! +Wir haben unsere Patienteninformationen von einem einzelnen String in eine Liste von Strings aufgeteilt. +Wir können nun jeden Teil der Patienteninformationen separat verarbeiten. + +### 4.3. Verwende eine Map zur Organisation der Metadaten + +Unsere Metadaten sind im Moment nur eine flache Liste. +Sie ist einfach genug zu verwenden, aber schwer zu lesen. + +```console +[patientA, rep1, normal, R1, 001] +``` + +Was ist das Element an Index 3? Kannst du es sagen, ohne auf die ursprüngliche Erklärung der Metadatenstruktur zurückzugreifen? + +Dies ist eine großartige Gelegen diff --git a/docs/de/docs/training_collections/architects_toolkit_1.md b/docs/de/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..efbb800215 --- /dev/null +++ b/docs/de/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: The Architect's Toolkit I +hide: + - toc +--- + +# The Architect's Toolkit I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Unsere Training Collections bieten kuratierte Lernpfade durch unsere fortgeschrittenen Trainingsmaterialien (genannt [Side Quests](../../side_quests)). Diese Sammlung behandelt vier wesentliche Themen, die häufig zusammen verwendet werden, um robuste und skalierbare Workflows zu erstellen. + +## Lernziele + +Am Ende dieser Sammlung wirst du Erfahrung haben mit: + +- **Komplexen modularen Workflow-Architekturen** - Kombination mehrerer Workflows zu zusammenhängenden Pipelines +- **Umfassenden Teststrategien** - Sicherstellen, dass deine Workflows zuverlässig und wartbar sind +- **Metadaten-Management** - Effektive Handhabung probenspezifischer Metadaten in deinen Workflows +- **Fortgeschrittener Datenverarbeitung** - Implementierung effizienter Muster zum Aufteilen und Gruppieren von Daten + +Diese Fähigkeiten ermöglichen es dir, robuste, skalierbare und wartbare Nextflow-Workflows für reale Anwendungen zu erstellen. + +## Zielgruppe & Voraussetzungen + +Diese Sammlung ist für Benutzer konzipiert, die das grundlegende Nextflow-Training abgeschlossen haben und tiefer in fortgeschrittene Workflow-Muster, Teststrategien und Techniken zur Daten- und Metadatenhandhabung einsteigen möchten. + +**Voraussetzungen** + +- Abschluss des [Hello Nextflow](../../hello_nextflow/)-Trainings oder gleichwertige Erfahrung +- Grundlegende Vertrautheit mit Nextflow-Syntax und -Konzepten +- Verständnis grundlegender Workflow-Entwicklungsmuster +- Erfahrung mit Kommandozeilen-Tools + +## Inhalte der Sammlung + +Diese Sammlung besteht aus vier Side Quests, die ergänzende Themen des Workflow-Engineerings behandeln: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - Komplexe Workflow-Architektur und -Komposition +2. **[Testing with nf-test](../../side_quests/nf-test)** - Teststrategien für Nextflow-Workflows +3. **[Metadata](../../side_quests/metadata)** - Handhabung von Metadaten für Elemente in Nextflow-Channels +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - Fortgeschrittene Datenverarbeitungsmuster + +Jeder Side Quest ist eigenständig und behandelt unabhängige Konzepte, aber wir empfehlen, sie in der oben aufgeführten Reihenfolge zu absolvieren, um eine logische Progression durch die Themen zu gewährleisten. + +## Wie du diese Sammlung verwendest + +Führe zuerst einen Strg+Klick (bzw. Cmd+Klick) auf die Schaltfläche "Open in GitHub Codespaces" unten aus, um die Trainingsumgebung in einem separaten Tab zu öffnen, und lies dann weiter, während sie lädt. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Sobald deine Umgebung läuft, arbeite die Sammlung wie folgt durch: + +1. In diesem Tab: Navigiere zum ersten oben aufgelisteten Side Quest, der schrittweise Entwicklungsübungen beschreibt. +2. In deinem Codespaces-Tab: Arbeite die Übungen für den Side Quest durch. +3. Wenn du einen Side Quest abgeschlossen hast, kehre zu dieser Seite zurück und navigiere zum nächsten in der obigen Liste. +4. Wenn du die Sammlung abgeschlossen hast, klicke auf die Schaltfläche unten, um eine sehr kurze Umfrage auszufüllen. Dein Feedback ermöglicht es uns, die Trainingsmaterialien für alle weiter zu verbessern. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Bereit anzufangen? Beginne mit dem ersten Modul oben! diff --git a/docs/de/docs/training_collections/index.md b/docs/de/docs/training_collections/index.md new file mode 100644 index 0000000000..a60c155a14 --- /dev/null +++ b/docs/de/docs/training_collections/index.md @@ -0,0 +1,29 @@ +--- +title: Training-Sammlungen +hide: + - toc +--- + +# Training-Sammlungen + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } KI-gestützte Übersetzung - [mehr erfahren & Verbesserungen vorschlagen](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dieser Abschnitt enthält kuratierte Sammlungen von Trainingsmodulen, die [Side Quests](../side_quests/index.md) genannt werden und darauf abzielen, eine umfassende Lernerfahrung zu einem bestimmten Thema oder Anwendungsfall zu bieten. + +## Voraussetzungen + +Jede Sammlung hat spezifische Voraussetzungen, die auf ihrer Indexseite dokumentiert sind. Die meisten Sammlungen setzen jedoch Folgendes voraus: + +- Erfahrung mit der Kommandozeile +- Grundlegende Nextflow-Konzepte und -Werkzeuge, die im [Hello Nextflow](../../hello_nextflow/) Anfänger-Trainingskurs behandelt werden + +Für technische Anforderungen und die Einrichtung der Umgebung siehe den [Environment Setup](../../envsetup/) Mini-Kurs. + +## Verfügbare Sammlungen + +- [The Architect's Toolkit I](./architects_toolkit_1.md) - Eine Sammlung von vier Side Quests, die Workflow-Architekturmuster für die Zusammenstellung komplexer Pipelines, die Implementierung von Teststrategien, das Metadaten-Management und das Gruppieren und Aufteilen von Daten behandeln. _Geschätzte Dauer: 4 Stunden im Gruppentraining._ + +## Neue Sammlungen vorschlagen + +Wir arbeiten aktiv an der Entwicklung zusätzlicher Side Quests und Sammlungen. +Du kannst gerne Themen vorschlagen, die deiner Meinung nach sinnvoll in einer Sammlung behandelt werden sollten, indem du im [Training-Bereich](https://community.seqera.io/c/training/) des Community-Forums postest. diff --git a/docs/de/llm-prompt.md b/docs/de/llm-prompt.md new file mode 100644 index 0000000000..40340be5dc --- /dev/null +++ b/docs/de/llm-prompt.md @@ -0,0 +1,162 @@ +# Translation Rules for German + +The target language for this translation is **German** (`de`). + +**Language name**: Use lowercase "deutsch" (not "Deutsch") in the language selector to match the style of other Romance languages (español, français, italiano, português). + +## 1. Grammar & Tone + +- Use informal tone (du instead of Sie) +- Use standard German (Hochdeutsch) spelling conventions +- Prefer active voice when possible +- Use gender-neutral language where appropriate, including gender stars for gender-specific suffixes, e.g. "Entwickler\*innen" + +## 2. Writing Style + +- Keep sentences short and direct; this is tutorial text, not academic writing +- Avoid overly formal or dated phrasing (e.g., "wissenschaftliche Rechenanforderungen" sounds archaic) +- Prefer modern, conversational German that feels natural for technical documentation +- Break complex sentences into simpler ones rather than using long subordinate clause chains + +Example: + +- Avoid: "Am Ende dieses Kurses wirst du gut vorbereitet sein, um die nächsten Schritte auf deiner Reise zur Entwicklung reproduzierbarer Workflows für deine wissenschaftlichen Rechenanforderungen anzugehen." +- Better: "Nach Abschluss dieses Kurses bist du bereit, reproduzierbare Workflows für deine eigenen Projekte zu entwickeln." + +## 3. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to German (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "Der Eingabekanal empfängt die Dateien..." (translate "channel" to "Kanal") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// Eine Begrüßung ausgeben` + +## 4. Code Comments + +**Always translate code comments to German.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// German translation +params.greeting = "Hello" // Standard-Begrüßung festlegen +``` + +## 5. Common Mistakes + +Avoid these translation errors specific to German: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Kanal.fromPath('*.fastq') +Prozess FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ Version 24.04.0 +Ausführer > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Overly formal or academic language + +```markdown +// Wrong - too formal/academic +Sie werden die Möglichkeit haben, wissenschaftliche Rechenanforderungen zu bewältigen... + +// Correct - conversational tutorial style +Du lernst, wie du Workflows für deine Projekte entwickelst... +``` + +### ❌ Long subordinate clause chains + +```markdown +// Wrong - German "Schachtelsätze" +Du wirst sehen, dass, wenn du den Workflow ausführst, der, wie wir bereits besprochen haben, mehrere Prozesse enthält, die Ergebnisse im Ausgabeverzeichnis erscheinen. + +// Correct - break into shorter sentences +Führe den Workflow aus. Er enthält mehrere Prozesse, wie wir bereits besprochen haben. Die Ergebnisse erscheinen im Ausgabeverzeichnis. +``` + +## 6. Terms to Translate + +These terms should be translated in prose (but kept in English in code): + +| English | German | +| ----------- | ---------------------- | +| channel | Kanal | +| process | Prozess | +| workflow | Workflow | +| pipeline | Pipeline | +| directive | Direktive | +| container | Container | +| input | Eingabe | +| output | Ausgabe | +| task | Aufgabe | +| tuple | Tupel | +| operator | Operator | +| parameter | Parameter | +| environment | Umgebung | +| directory | Verzeichnis | +| file | Datei | +| sample | Probe | +| alignment | Alignment | +| reference | Referenz | +| training | Training | +| module | Modul | +| command | Befehl | +| index | Index | +| run | ausführen / Ausführung | + +## 7. Admonition Titles + +| English | German | +| -------- | -------- | +| Note | Hinweis | +| Tip | Tipp | +| Warning | Warnung | +| Exercise | Übung | +| Solution | Lösung | +| Example | Beispiel | + +## 8. Section Headers + +These recurring section headers should be translated consistently: + +| English | German | +| ----------------- | ------------------- | +| Takeaway | Fazit | +| What's next? | Wie geht es weiter? | +| Warmup | Aufwärmen | +| Environment Setup | Umgebung einrichten | +| Getting Started | Erste Schritte | + +## 9. Tab Labels + +| English | German | +| ------- | ------ | +| After | Danach | +| Before | Vorher | +| Gitpod | Gitpod | +| Local | Lokal | diff --git a/docs/de/mkdocs.yml b/docs/de/mkdocs.yml new file mode 100644 index 0000000000..20fa06ec0d --- /dev/null +++ b/docs/de/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: de + custom_dir: ../en/overrides +extra: + consent: + title: "Cookie-Zustimmung" + description: >- + Wir verwenden Cookies, um Ihre wiederholten Besuche und Präferenzen zu erkennen + sowie die Effektivität unserer Dokumentation zu messen und festzustellen, ob + Benutzer*innen finden, wonach sie suchen. Mit Ihrer Zustimmung helfen Sie uns, + unsere Schulungsmaterialien zu verbessern. + Erfahren Sie mehr darüber, + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">wie wir Cookies verwenden</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/de/ui-strings.yml b/docs/de/ui-strings.yml new file mode 100644 index 0000000000..6aa544b6ea --- /dev/null +++ b/docs/de/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - German (Deutsch) +# Diese Strings werden von index_page_hook.py für Kurs-Startseiten +# und in mkdocs.yml für die Cookie-Zustimmung verwendet. + +index_page: + course_summary: "Kursübersicht" + additional_information: "Zusätzliche Informationen" + technical_requirements: "Technische Voraussetzungen" + learning_objectives: "Lernziele" + audience_prerequisites: "Zielgruppe & Voraussetzungen" + course_videos: "Kursvideos" + +defaults: + technical_requirements: >- + Du benötigst ein GitHub-Konto ODER eine lokale Installation von Nextflow. + Weitere Details findest du unter [Umgebungsoptionen](../envsetup/index.md). + videos: >- + Für jedes Kapitel sind Videos verfügbar, in denen ein*e Dozent*in + die Übungen durcharbeitet. Das Video für jeden Teil des Kurses ist + oben auf der entsprechenden Seite eingebettet. + view_playlist: "Playlist auf YouTube ansehen" diff --git a/docs/assets/fonts/degular/Degular-Black.woff b/docs/en/docs/assets/fonts/degular/Degular-Black.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Black.woff rename to docs/en/docs/assets/fonts/degular/Degular-Black.woff diff --git a/docs/assets/fonts/degular/Degular-Black.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Black.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Black.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Black.woff2 diff --git a/docs/assets/fonts/degular/Degular-BlackItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-BlackItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-BlackItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-BlackItalic.woff diff --git a/docs/assets/fonts/degular/Degular-BlackItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-BlackItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-BlackItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-BlackItalic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Bold.woff b/docs/en/docs/assets/fonts/degular/Degular-Bold.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Bold.woff rename to docs/en/docs/assets/fonts/degular/Degular-Bold.woff diff --git a/docs/assets/fonts/degular/Degular-Bold.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Bold.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Bold.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Bold.woff2 diff --git a/docs/assets/fonts/degular/Degular-BoldItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-BoldItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-BoldItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-BoldItalic.woff diff --git a/docs/assets/fonts/degular/Degular-BoldItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-BoldItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-BoldItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-BoldItalic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Italic.woff b/docs/en/docs/assets/fonts/degular/Degular-Italic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Italic.woff rename to docs/en/docs/assets/fonts/degular/Degular-Italic.woff diff --git a/docs/assets/fonts/degular/Degular-Italic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Italic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Italic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Italic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Light.woff b/docs/en/docs/assets/fonts/degular/Degular-Light.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Light.woff rename to docs/en/docs/assets/fonts/degular/Degular-Light.woff diff --git a/docs/assets/fonts/degular/Degular-Light.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Light.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Light.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Light.woff2 diff --git a/docs/assets/fonts/degular/Degular-LightItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-LightItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-LightItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-LightItalic.woff diff --git a/docs/assets/fonts/degular/Degular-LightItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-LightItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-LightItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-LightItalic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Medium.woff b/docs/en/docs/assets/fonts/degular/Degular-Medium.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Medium.woff rename to docs/en/docs/assets/fonts/degular/Degular-Medium.woff diff --git a/docs/assets/fonts/degular/Degular-Medium.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Medium.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Medium.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Medium.woff2 diff --git a/docs/assets/fonts/degular/Degular-MediumItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-MediumItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-MediumItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-MediumItalic.woff diff --git a/docs/assets/fonts/degular/Degular-MediumItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-MediumItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-MediumItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-MediumItalic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Regular.woff b/docs/en/docs/assets/fonts/degular/Degular-Regular.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Regular.woff rename to docs/en/docs/assets/fonts/degular/Degular-Regular.woff diff --git a/docs/assets/fonts/degular/Degular-Regular.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Regular.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Regular.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Regular.woff2 diff --git a/docs/assets/fonts/degular/Degular-Semibold.woff b/docs/en/docs/assets/fonts/degular/Degular-Semibold.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Semibold.woff rename to docs/en/docs/assets/fonts/degular/Degular-Semibold.woff diff --git a/docs/assets/fonts/degular/Degular-Semibold.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Semibold.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Semibold.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Semibold.woff2 diff --git a/docs/assets/fonts/degular/Degular-SemiboldItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-SemiboldItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-SemiboldItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-SemiboldItalic.woff diff --git a/docs/assets/fonts/degular/Degular-SemiboldItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-SemiboldItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-SemiboldItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-SemiboldItalic.woff2 diff --git a/docs/assets/fonts/degular/Degular-Thin.woff b/docs/en/docs/assets/fonts/degular/Degular-Thin.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-Thin.woff rename to docs/en/docs/assets/fonts/degular/Degular-Thin.woff diff --git a/docs/assets/fonts/degular/Degular-Thin.woff2 b/docs/en/docs/assets/fonts/degular/Degular-Thin.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-Thin.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-Thin.woff2 diff --git a/docs/assets/fonts/degular/Degular-ThinItalic.woff b/docs/en/docs/assets/fonts/degular/Degular-ThinItalic.woff similarity index 100% rename from docs/assets/fonts/degular/Degular-ThinItalic.woff rename to docs/en/docs/assets/fonts/degular/Degular-ThinItalic.woff diff --git a/docs/assets/fonts/degular/Degular-ThinItalic.woff2 b/docs/en/docs/assets/fonts/degular/Degular-ThinItalic.woff2 similarity index 100% rename from docs/assets/fonts/degular/Degular-ThinItalic.woff2 rename to docs/en/docs/assets/fonts/degular/Degular-ThinItalic.woff2 diff --git a/docs/assets/fonts/excalidraw/Cascadia.woff2 b/docs/en/docs/assets/fonts/excalidraw/Cascadia.woff2 similarity index 100% rename from docs/assets/fonts/excalidraw/Cascadia.woff2 rename to docs/en/docs/assets/fonts/excalidraw/Cascadia.woff2 diff --git a/docs/assets/fonts/excalidraw/Virgil.woff2 b/docs/en/docs/assets/fonts/excalidraw/Virgil.woff2 similarity index 100% rename from docs/assets/fonts/excalidraw/Virgil.woff2 rename to docs/en/docs/assets/fonts/excalidraw/Virgil.woff2 diff --git a/docs/assets/img/cc_by-nc-sa.svg b/docs/en/docs/assets/img/cc_by-nc-sa.svg similarity index 100% rename from docs/assets/img/cc_by-nc-sa.svg rename to docs/en/docs/assets/img/cc_by-nc-sa.svg diff --git a/docs/assets/img/helloworlddiagram.png b/docs/en/docs/assets/img/helloworlddiagram.png similarity index 100% rename from docs/assets/img/helloworlddiagram.png rename to docs/en/docs/assets/img/helloworlddiagram.png diff --git a/docs/assets/img/nextflow-icon.png b/docs/en/docs/assets/img/nextflow-icon.png similarity index 100% rename from docs/assets/img/nextflow-icon.png rename to docs/en/docs/assets/img/nextflow-icon.png diff --git a/docs/assets/img/nextflow-logo-white.png b/docs/en/docs/assets/img/nextflow-logo-white.png similarity index 100% rename from docs/assets/img/nextflow-logo-white.png rename to docs/en/docs/assets/img/nextflow-logo-white.png diff --git a/docs/assets/img/nextflow_logo_dark.png b/docs/en/docs/assets/img/nextflow_logo_dark.png similarity index 100% rename from docs/assets/img/nextflow_logo_dark.png rename to docs/en/docs/assets/img/nextflow_logo_dark.png diff --git a/docs/assets/img/seqera_logo.png b/docs/en/docs/assets/img/seqera_logo.png similarity index 100% rename from docs/assets/img/seqera_logo.png rename to docs/en/docs/assets/img/seqera_logo.png diff --git a/docs/assets/img/seqera_logo_dark.png b/docs/en/docs/assets/img/seqera_logo_dark.png similarity index 100% rename from docs/assets/img/seqera_logo_dark.png rename to docs/en/docs/assets/img/seqera_logo_dark.png diff --git a/docs/assets/img/seqera_logo_mono.svg b/docs/en/docs/assets/img/seqera_logo_mono.svg similarity index 100% rename from docs/assets/img/seqera_logo_mono.svg rename to docs/en/docs/assets/img/seqera_logo_mono.svg diff --git a/docs/assets/img/seqera_logo_white.png b/docs/en/docs/assets/img/seqera_logo_white.png similarity index 100% rename from docs/assets/img/seqera_logo_white.png rename to docs/en/docs/assets/img/seqera_logo_white.png diff --git a/docs/en/docs/assets/javascripts/consent-sync.js b/docs/en/docs/assets/javascripts/consent-sync.js new file mode 100644 index 0000000000..066e3d2c82 --- /dev/null +++ b/docs/en/docs/assets/javascripts/consent-sync.js @@ -0,0 +1,36 @@ +// Sync MkDocs Material settings across all language paths when written +// Intercepts localStorage.setItem to copy settings (consent, palette) to all languages +(function () { + // Get language paths from the language picker in the DOM + var langPaths = ["/"]; + document + .querySelectorAll(".md-select__link[hreflang]") + .forEach(function (link) { + var lang = link.getAttribute("hreflang"); + if (lang && lang !== "en") { + langPaths.push("/" + lang + "/"); + } + }); + + // Store original setItem + var originalSetItem = localStorage.setItem.bind(localStorage); + + // Override setItem to sync MkDocs Material settings + localStorage.setItem = function (key, value) { + // Call original first + originalSetItem(key, value); + + // Check if this is a MkDocs Material setting (e.g., /.__consent, /de/.__palette) + var match = key.match(/^(\/[a-z]{2}\/|\/)(.__\w+)$/); + if (match) { + var suffix = match[2]; // e.g., ".__consent" + // Copy to all other language paths + langPaths.forEach(function (path) { + var otherKey = path + suffix; + if (otherKey !== key) { + originalSetItem(otherKey, value); + } + }); + } + }; +})(); diff --git a/docs/en/docs/assets/javascripts/language-picker.js b/docs/en/docs/assets/javascripts/language-picker.js new file mode 100644 index 0000000000..9db36cef22 --- /dev/null +++ b/docs/en/docs/assets/javascripts/language-picker.js @@ -0,0 +1,83 @@ +// Fix language picker links to preserve current page when switching languages +// Also handles mike versioning prefixes (e.g., /latest/, /0.dev/) +(function () { + function fixLanguageLinks() { + var path = window.location.pathname; + + // Get known languages from the language picker in the DOM + var knownLangs = []; + var langLinks = document.querySelectorAll(".md-select__link[hreflang]"); + langLinks.forEach(function (link) { + var lang = link.getAttribute("hreflang"); + if (lang && knownLangs.indexOf(lang) === -1) { + knownLangs.push(lang); + } + }); + + if (knownLangs.length === 0) { + console.error("language-picker.js: Could not find language links in DOM"); + return; + } + + // Check if a segment looks like a mike version + // Versions are like: latest, stable, 0.dev, 1.0, 2.8.1, etc. + function isVersion(segment) { + return /^(latest|stable|\d+(\.\d+)*\.?dev|\d+(\.\d+)*)$/.test(segment); + } + + // Parse the current path to extract version prefix, language, and page path + // Handles: /page, /de/page, /latest/page, /latest/de/page + var versionPrefix = ""; + var pagePath = path; + + // Split path into segments + var segments = path.split("/").filter(function (s) { + return s.length > 0; + }); + + if (segments.length > 0) { + // Check if first segment is a version (not a language, and looks like a version) + if (knownLangs.indexOf(segments[0]) === -1 && isVersion(segments[0])) { + // First segment is a version prefix + versionPrefix = "/" + segments[0]; + segments.shift(); + } + + // Check if first/next segment is a language + if (segments.length > 0 && knownLangs.indexOf(segments[0]) !== -1) { + // Remove language from page path + segments.shift(); + } + + // Remaining segments are the page path + pagePath = "/" + segments.join("/"); + // Preserve trailing slash if original had one + if (path.endsWith("/") && !pagePath.endsWith("/")) { + pagePath += "/"; + } + } + + // Update each language link to preserve current page + langLinks.forEach(function (link) { + var lang = link.getAttribute("hreflang"); + var langPrefix = lang === "en" ? "" : "/" + lang; + var newHref = versionPrefix + langPrefix + pagePath; + // Ensure we don't end up with empty href + if (newHref === "") { + newHref = "/"; + } + link.setAttribute("href", newHref); + }); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", fixLanguageLinks); + } else { + fixLanguageLinks(); + } + + // Re-run after instant navigation (mkdocs-material uses RxJS) + if (typeof document$ !== "undefined") { + document$.subscribe(fixLanguageLinks); + } +})(); diff --git a/docs/assets/javascripts/posthog.js b/docs/en/docs/assets/javascripts/posthog.js similarity index 100% rename from docs/assets/javascripts/posthog.js rename to docs/en/docs/assets/javascripts/posthog.js diff --git a/docs/assets/stylesheets/extra.css b/docs/en/docs/assets/stylesheets/extra.css similarity index 96% rename from docs/assets/stylesheets/extra.css rename to docs/en/docs/assets/stylesheets/extra.css index e892158f99..7d99f47edb 100644 --- a/docs/assets/stylesheets/extra.css +++ b/docs/en/docs/assets/stylesheets/extra.css @@ -431,3 +431,24 @@ h3 .enumerate-headings-plugin { .md-content__inner { position: relative; } + +/* AI translation notice - inline text on translated pages */ +.ai-translation-notice { + color: #448aff; + font-size: 0.75rem; + margin-bottom: 1rem; + display: block; +} +.ai-translation-notice .twemoji { + vertical-align: -0.125em; + margin-right: 0.25rem; +} +.ai-translation-notice a { + color: inherit; + text-decoration: underline; +} + +/* Language selector dropdown - allow dynamic height */ +.md-select__inner { + max-height: min(80vh, 30rem) !important; +} diff --git a/docs/assets/stylesheets/fonts.css b/docs/en/docs/assets/stylesheets/fonts.css similarity index 100% rename from docs/assets/stylesheets/fonts.css rename to docs/en/docs/assets/stylesheets/fonts.css diff --git a/docs/envsetup/01_setup.md b/docs/en/docs/envsetup/01_setup.md similarity index 100% rename from docs/envsetup/01_setup.md rename to docs/en/docs/envsetup/01_setup.md diff --git a/docs/envsetup/02_local.md b/docs/en/docs/envsetup/02_local.md similarity index 100% rename from docs/envsetup/02_local.md rename to docs/en/docs/envsetup/02_local.md diff --git a/docs/envsetup/03_devcontainer.md b/docs/en/docs/envsetup/03_devcontainer.md similarity index 100% rename from docs/envsetup/03_devcontainer.md rename to docs/en/docs/envsetup/03_devcontainer.md diff --git a/docs/envsetup/img/codespaces_create.png b/docs/en/docs/envsetup/img/codespaces_create.png similarity index 100% rename from docs/envsetup/img/codespaces_create.png rename to docs/en/docs/envsetup/img/codespaces_create.png diff --git a/docs/envsetup/img/codespaces_list.png b/docs/en/docs/envsetup/img/codespaces_list.png similarity index 100% rename from docs/envsetup/img/codespaces_list.png rename to docs/en/docs/envsetup/img/codespaces_list.png diff --git a/docs/envsetup/img/codespaces_resume.png b/docs/en/docs/envsetup/img/codespaces_resume.png similarity index 100% rename from docs/envsetup/img/codespaces_resume.png rename to docs/en/docs/envsetup/img/codespaces_resume.png diff --git a/docs/envsetup/img/codespaces_welcome.png b/docs/en/docs/envsetup/img/codespaces_welcome.png similarity index 100% rename from docs/envsetup/img/codespaces_welcome.png rename to docs/en/docs/envsetup/img/codespaces_welcome.png diff --git a/docs/envsetup/img/install_extension.png b/docs/en/docs/envsetup/img/install_extension.png similarity index 100% rename from docs/envsetup/img/install_extension.png rename to docs/en/docs/envsetup/img/install_extension.png diff --git a/docs/envsetup/img/reopen_prompt.png b/docs/en/docs/envsetup/img/reopen_prompt.png similarity index 100% rename from docs/envsetup/img/reopen_prompt.png rename to docs/en/docs/envsetup/img/reopen_prompt.png diff --git a/docs/envsetup/img/running_container.png b/docs/en/docs/envsetup/img/running_container.png similarity index 100% rename from docs/envsetup/img/running_container.png rename to docs/en/docs/envsetup/img/running_container.png diff --git a/docs/envsetup/img/select_local_config.png b/docs/en/docs/envsetup/img/select_local_config.png similarity index 100% rename from docs/envsetup/img/select_local_config.png rename to docs/en/docs/envsetup/img/select_local_config.png diff --git a/docs/envsetup/index.md b/docs/en/docs/envsetup/index.md similarity index 100% rename from docs/envsetup/index.md rename to docs/en/docs/envsetup/index.md diff --git a/docs/hello_nextflow/00_orientation.md b/docs/en/docs/hello_nextflow/00_orientation.md similarity index 100% rename from docs/hello_nextflow/00_orientation.md rename to docs/en/docs/hello_nextflow/00_orientation.md diff --git a/docs/hello_nextflow/01_hello_world.md b/docs/en/docs/hello_nextflow/01_hello_world.md similarity index 100% rename from docs/hello_nextflow/01_hello_world.md rename to docs/en/docs/hello_nextflow/01_hello_world.md diff --git a/docs/hello_nextflow/02_hello_channels.md b/docs/en/docs/hello_nextflow/02_hello_channels.md similarity index 100% rename from docs/hello_nextflow/02_hello_channels.md rename to docs/en/docs/hello_nextflow/02_hello_channels.md diff --git a/docs/hello_nextflow/03_hello_workflow.md b/docs/en/docs/hello_nextflow/03_hello_workflow.md similarity index 100% rename from docs/hello_nextflow/03_hello_workflow.md rename to docs/en/docs/hello_nextflow/03_hello_workflow.md diff --git a/docs/hello_nextflow/04_hello_modules.md b/docs/en/docs/hello_nextflow/04_hello_modules.md similarity index 100% rename from docs/hello_nextflow/04_hello_modules.md rename to docs/en/docs/hello_nextflow/04_hello_modules.md diff --git a/docs/hello_nextflow/05_hello_containers.md b/docs/en/docs/hello_nextflow/05_hello_containers.md similarity index 100% rename from docs/hello_nextflow/05_hello_containers.md rename to docs/en/docs/hello_nextflow/05_hello_containers.md diff --git a/docs/hello_nextflow/06_hello_config.md b/docs/en/docs/hello_nextflow/06_hello_config.md similarity index 100% rename from docs/hello_nextflow/06_hello_config.md rename to docs/en/docs/hello_nextflow/06_hello_config.md diff --git a/docs/hello_nextflow/img/cpu-after.png b/docs/en/docs/hello_nextflow/img/cpu-after.png similarity index 100% rename from docs/hello_nextflow/img/cpu-after.png rename to docs/en/docs/hello_nextflow/img/cpu-after.png diff --git a/docs/hello_nextflow/img/cpu-before.png b/docs/en/docs/hello_nextflow/img/cpu-before.png similarity index 100% rename from docs/hello_nextflow/img/cpu-before.png rename to docs/en/docs/hello_nextflow/img/cpu-before.png diff --git a/docs/hello_nextflow/img/hello-collect.svg b/docs/en/docs/hello_nextflow/img/hello-collect.svg similarity index 100% rename from docs/hello_nextflow/img/hello-collect.svg rename to docs/en/docs/hello_nextflow/img/hello-collect.svg diff --git a/docs/hello_nextflow/img/hello-multistep.svg b/docs/en/docs/hello_nextflow/img/hello-multistep.svg similarity index 100% rename from docs/hello_nextflow/img/hello-multistep.svg rename to docs/en/docs/hello_nextflow/img/hello-multistep.svg diff --git a/docs/hello_nextflow/img/hello-pipeline-channel-multi.svg b/docs/en/docs/hello_nextflow/img/hello-pipeline-channel-multi.svg similarity index 100% rename from docs/hello_nextflow/img/hello-pipeline-channel-multi.svg rename to docs/en/docs/hello_nextflow/img/hello-pipeline-channel-multi.svg diff --git a/docs/hello_nextflow/img/hello-pipeline-channel.svg b/docs/en/docs/hello_nextflow/img/hello-pipeline-channel.svg similarity index 100% rename from docs/hello_nextflow/img/hello-pipeline-channel.svg rename to docs/en/docs/hello_nextflow/img/hello-pipeline-channel.svg diff --git a/docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg b/docs/en/docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg similarity index 100% rename from docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg rename to docs/en/docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg diff --git a/docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg b/docs/en/docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg similarity index 100% rename from docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg rename to docs/en/docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg diff --git a/docs/hello_nextflow/img/hello_pipeline_complete.svg b/docs/en/docs/hello_nextflow/img/hello_pipeline_complete.svg similarity index 100% rename from docs/hello_nextflow/img/hello_pipeline_complete.svg rename to docs/en/docs/hello_nextflow/img/hello_pipeline_complete.svg diff --git a/docs/hello_nextflow/img/hello_world.svg b/docs/en/docs/hello_nextflow/img/hello_world.svg similarity index 100% rename from docs/hello_nextflow/img/hello_world.svg rename to docs/en/docs/hello_nextflow/img/hello_world.svg diff --git a/docs/hello_nextflow/img/hello_world_input.svg b/docs/en/docs/hello_nextflow/img/hello_world_input.svg similarity index 100% rename from docs/hello_nextflow/img/hello_world_input.svg rename to docs/en/docs/hello_nextflow/img/hello_world_input.svg diff --git a/docs/hello_nextflow/img/hello_world_output.svg b/docs/en/docs/hello_nextflow/img/hello_world_output.svg similarity index 100% rename from docs/hello_nextflow/img/hello_world_output.svg rename to docs/en/docs/hello_nextflow/img/hello_world_output.svg diff --git a/docs/hello_nextflow/img/memory-after.png b/docs/en/docs/hello_nextflow/img/memory-after.png similarity index 100% rename from docs/hello_nextflow/img/memory-after.png rename to docs/en/docs/hello_nextflow/img/memory-after.png diff --git a/docs/hello_nextflow/img/memory-before.png b/docs/en/docs/hello_nextflow/img/memory-before.png similarity index 100% rename from docs/hello_nextflow/img/memory-before.png rename to docs/en/docs/hello_nextflow/img/memory-before.png diff --git a/docs/hello_nextflow/img/modules.svg b/docs/en/docs/hello_nextflow/img/modules.svg similarity index 100% rename from docs/hello_nextflow/img/modules.svg rename to docs/en/docs/hello_nextflow/img/modules.svg diff --git a/docs/hello_nextflow/img/report_cover.png b/docs/en/docs/hello_nextflow/img/report_cover.png similarity index 100% rename from docs/hello_nextflow/img/report_cover.png rename to docs/en/docs/hello_nextflow/img/report_cover.png diff --git a/docs/hello_nextflow/index.md b/docs/en/docs/hello_nextflow/index.md similarity index 100% rename from docs/hello_nextflow/index.md rename to docs/en/docs/hello_nextflow/index.md diff --git a/docs/hello_nextflow/next_steps.md b/docs/en/docs/hello_nextflow/next_steps.md similarity index 100% rename from docs/hello_nextflow/next_steps.md rename to docs/en/docs/hello_nextflow/next_steps.md diff --git a/docs/hello_nextflow/survey.md b/docs/en/docs/hello_nextflow/survey.md similarity index 100% rename from docs/hello_nextflow/survey.md rename to docs/en/docs/hello_nextflow/survey.md diff --git a/docs/hello_nextflow/transcripts/00_orientation.md b/docs/en/docs/hello_nextflow/transcripts/00_orientation.md similarity index 100% rename from docs/hello_nextflow/transcripts/00_orientation.md rename to docs/en/docs/hello_nextflow/transcripts/00_orientation.md diff --git a/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/en/docs/hello_nextflow/transcripts/01_hello_world.md similarity index 100% rename from docs/hello_nextflow/transcripts/01_hello_world.md rename to docs/en/docs/hello_nextflow/transcripts/01_hello_world.md diff --git a/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/en/docs/hello_nextflow/transcripts/02_hello_channels.md similarity index 100% rename from docs/hello_nextflow/transcripts/02_hello_channels.md rename to docs/en/docs/hello_nextflow/transcripts/02_hello_channels.md diff --git a/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/en/docs/hello_nextflow/transcripts/03_hello_workflow.md similarity index 100% rename from docs/hello_nextflow/transcripts/03_hello_workflow.md rename to docs/en/docs/hello_nextflow/transcripts/03_hello_workflow.md diff --git a/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/en/docs/hello_nextflow/transcripts/04_hello_modules.md similarity index 100% rename from docs/hello_nextflow/transcripts/04_hello_modules.md rename to docs/en/docs/hello_nextflow/transcripts/04_hello_modules.md diff --git a/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/en/docs/hello_nextflow/transcripts/05_hello_containers.md similarity index 100% rename from docs/hello_nextflow/transcripts/05_hello_containers.md rename to docs/en/docs/hello_nextflow/transcripts/05_hello_containers.md diff --git a/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/en/docs/hello_nextflow/transcripts/06_hello_config.md similarity index 100% rename from docs/hello_nextflow/transcripts/06_hello_config.md rename to docs/en/docs/hello_nextflow/transcripts/06_hello_config.md diff --git a/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/en/docs/hello_nextflow/transcripts/07_next_steps.md similarity index 100% rename from docs/hello_nextflow/transcripts/07_next_steps.md rename to docs/en/docs/hello_nextflow/transcripts/07_next_steps.md diff --git a/docs/hello_nf-core/00_orientation.md b/docs/en/docs/hello_nf-core/00_orientation.md similarity index 100% rename from docs/hello_nf-core/00_orientation.md rename to docs/en/docs/hello_nf-core/00_orientation.md diff --git a/docs/hello_nf-core/01_run_demo.md b/docs/en/docs/hello_nf-core/01_run_demo.md similarity index 100% rename from docs/hello_nf-core/01_run_demo.md rename to docs/en/docs/hello_nf-core/01_run_demo.md diff --git a/docs/hello_nf-core/02_rewrite_hello.md b/docs/en/docs/hello_nf-core/02_rewrite_hello.md similarity index 100% rename from docs/hello_nf-core/02_rewrite_hello.md rename to docs/en/docs/hello_nf-core/02_rewrite_hello.md diff --git a/docs/hello_nf-core/03_use_module.md b/docs/en/docs/hello_nf-core/03_use_module.md similarity index 100% rename from docs/hello_nf-core/03_use_module.md rename to docs/en/docs/hello_nf-core/03_use_module.md diff --git a/docs/hello_nf-core/04_make_module.md b/docs/en/docs/hello_nf-core/04_make_module.md similarity index 100% rename from docs/hello_nf-core/04_make_module.md rename to docs/en/docs/hello_nf-core/04_make_module.md diff --git a/docs/hello_nf-core/05_input_validation.md b/docs/en/docs/hello_nf-core/05_input_validation.md similarity index 100% rename from docs/hello_nf-core/05_input_validation.md rename to docs/en/docs/hello_nf-core/05_input_validation.md diff --git a/docs/hello_nf-core/img/core-hello.svg b/docs/en/docs/hello_nf-core/img/core-hello.svg similarity index 100% rename from docs/hello_nf-core/img/core-hello.svg rename to docs/en/docs/hello_nf-core/img/core-hello.svg diff --git a/docs/hello_nf-core/img/cowpy-inputs.svg b/docs/en/docs/hello_nf-core/img/cowpy-inputs.svg similarity index 100% rename from docs/hello_nf-core/img/cowpy-inputs.svg rename to docs/en/docs/hello_nf-core/img/cowpy-inputs.svg diff --git a/docs/hello_nf-core/img/execution_timeline.png b/docs/en/docs/hello_nf-core/img/execution_timeline.png similarity index 100% rename from docs/hello_nf-core/img/execution_timeline.png rename to docs/en/docs/hello_nf-core/img/execution_timeline.png diff --git a/docs/hello_nf-core/img/execution_timeline_empty.png b/docs/en/docs/hello_nf-core/img/execution_timeline_empty.png similarity index 100% rename from docs/hello_nf-core/img/execution_timeline_empty.png rename to docs/en/docs/hello_nf-core/img/execution_timeline_empty.png diff --git a/docs/hello_nf-core/img/execution_timeline_hello.png b/docs/en/docs/hello_nf-core/img/execution_timeline_hello.png similarity index 100% rename from docs/hello_nf-core/img/execution_timeline_hello.png rename to docs/en/docs/hello_nf-core/img/execution_timeline_hello.png diff --git a/docs/hello_nf-core/img/hello-nested-workflows.svg b/docs/en/docs/hello_nf-core/img/hello-nested-workflows.svg similarity index 100% rename from docs/hello_nf-core/img/hello-nested-workflows.svg rename to docs/en/docs/hello_nf-core/img/hello-nested-workflows.svg diff --git a/docs/hello_nf-core/img/module-search-results.png b/docs/en/docs/hello_nf-core/img/module-search-results.png similarity index 100% rename from docs/hello_nf-core/img/module-search-results.png rename to docs/en/docs/hello_nf-core/img/module-search-results.png diff --git a/docs/hello_nf-core/img/module_comparison.svg b/docs/en/docs/hello_nf-core/img/module_comparison.svg similarity index 100% rename from docs/hello_nf-core/img/module_comparison.svg rename to docs/en/docs/hello_nf-core/img/module_comparison.svg diff --git a/docs/hello_nf-core/img/nf-core-demo-subway-cropped.png b/docs/en/docs/hello_nf-core/img/nf-core-demo-subway-cropped.png similarity index 100% rename from docs/hello_nf-core/img/nf-core-demo-subway-cropped.png rename to docs/en/docs/hello_nf-core/img/nf-core-demo-subway-cropped.png diff --git a/docs/hello_nf-core/img/nf-core_demo_code_organization.svg b/docs/en/docs/hello_nf-core/img/nf-core_demo_code_organization.svg similarity index 100% rename from docs/hello_nf-core/img/nf-core_demo_code_organization.svg rename to docs/en/docs/hello_nf-core/img/nf-core_demo_code_organization.svg diff --git a/docs/hello_nf-core/img/schema_add.png b/docs/en/docs/hello_nf-core/img/schema_add.png similarity index 100% rename from docs/hello_nf-core/img/schema_add.png rename to docs/en/docs/hello_nf-core/img/schema_add.png diff --git a/docs/hello_nf-core/img/schema_build.png b/docs/en/docs/hello_nf-core/img/schema_build.png similarity index 100% rename from docs/hello_nf-core/img/schema_build.png rename to docs/en/docs/hello_nf-core/img/schema_build.png diff --git a/docs/hello_nf-core/img/search-results.png b/docs/en/docs/hello_nf-core/img/search-results.png similarity index 100% rename from docs/hello_nf-core/img/search-results.png rename to docs/en/docs/hello_nf-core/img/search-results.png diff --git a/docs/hello_nf-core/index.md b/docs/en/docs/hello_nf-core/index.md similarity index 100% rename from docs/hello_nf-core/index.md rename to docs/en/docs/hello_nf-core/index.md diff --git a/docs/hello_nf-core/next_steps.md b/docs/en/docs/hello_nf-core/next_steps.md similarity index 100% rename from docs/hello_nf-core/next_steps.md rename to docs/en/docs/hello_nf-core/next_steps.md diff --git a/docs/hello_nf-core/survey.md b/docs/en/docs/hello_nf-core/survey.md similarity index 100% rename from docs/hello_nf-core/survey.md rename to docs/en/docs/hello_nf-core/survey.md diff --git a/docs/help.md b/docs/en/docs/help.md similarity index 100% rename from docs/help.md rename to docs/en/docs/help.md diff --git a/docs/index.md b/docs/en/docs/index.md similarity index 99% rename from docs/index.md rename to docs/en/docs/index.md index 80c5bb7d0d..7f950ad916 100644 --- a/docs/index.md +++ b/docs/en/docs/index.md @@ -1,5 +1,5 @@ --- -title: Nextflow Training +title: Home description: Welcome to the Nextflow community training portal! hide: - toc diff --git a/docs/info/conventions.md b/docs/en/docs/info/conventions.md similarity index 100% rename from docs/info/conventions.md rename to docs/en/docs/info/conventions.md diff --git a/docs/info/hello_pipeline.md b/docs/en/docs/info/hello_pipeline.md similarity index 100% rename from docs/info/hello_pipeline.md rename to docs/en/docs/info/hello_pipeline.md diff --git a/docs/info/nxf_versions.md b/docs/en/docs/info/nxf_versions.md similarity index 100% rename from docs/info/nxf_versions.md rename to docs/en/docs/info/nxf_versions.md diff --git a/docs/nextflow_run/00_orientation.md b/docs/en/docs/nextflow_run/00_orientation.md similarity index 100% rename from docs/nextflow_run/00_orientation.md rename to docs/en/docs/nextflow_run/00_orientation.md diff --git a/docs/nextflow_run/01_basics.md b/docs/en/docs/nextflow_run/01_basics.md similarity index 100% rename from docs/nextflow_run/01_basics.md rename to docs/en/docs/nextflow_run/01_basics.md diff --git a/docs/nextflow_run/02_pipeline.md b/docs/en/docs/nextflow_run/02_pipeline.md similarity index 100% rename from docs/nextflow_run/02_pipeline.md rename to docs/en/docs/nextflow_run/02_pipeline.md diff --git a/docs/nextflow_run/03_config.md b/docs/en/docs/nextflow_run/03_config.md similarity index 100% rename from docs/nextflow_run/03_config.md rename to docs/en/docs/nextflow_run/03_config.md diff --git a/docs/nextflow_run/img/DAG-multistep.svg b/docs/en/docs/nextflow_run/img/DAG-multistep.svg similarity index 100% rename from docs/nextflow_run/img/DAG-multistep.svg rename to docs/en/docs/nextflow_run/img/DAG-multistep.svg diff --git a/docs/nextflow_run/img/DAG-preview.png b/docs/en/docs/nextflow_run/img/DAG-preview.png similarity index 100% rename from docs/nextflow_run/img/DAG-preview.png rename to docs/en/docs/nextflow_run/img/DAG-preview.png diff --git a/docs/nextflow_run/img/dag-workflow.svg b/docs/en/docs/nextflow_run/img/dag-workflow.svg similarity index 100% rename from docs/nextflow_run/img/dag-workflow.svg rename to docs/en/docs/nextflow_run/img/dag-workflow.svg diff --git a/docs/nextflow_run/img/hello-pipeline-cowpy.svg b/docs/en/docs/nextflow_run/img/hello-pipeline-cowpy.svg similarity index 100% rename from docs/nextflow_run/img/hello-pipeline-cowpy.svg rename to docs/en/docs/nextflow_run/img/hello-pipeline-cowpy.svg diff --git a/docs/nextflow_run/img/hello-pipeline-multi-inputs.svg b/docs/en/docs/nextflow_run/img/hello-pipeline-multi-inputs.svg similarity index 100% rename from docs/nextflow_run/img/hello-pipeline-multi-inputs.svg rename to docs/en/docs/nextflow_run/img/hello-pipeline-multi-inputs.svg diff --git a/docs/nextflow_run/img/hello-pipeline-multi-steps.svg b/docs/en/docs/nextflow_run/img/hello-pipeline-multi-steps.svg similarity index 100% rename from docs/nextflow_run/img/hello-pipeline-multi-steps.svg rename to docs/en/docs/nextflow_run/img/hello-pipeline-multi-steps.svg diff --git a/docs/nextflow_run/img/modules.svg b/docs/en/docs/nextflow_run/img/modules.svg similarity index 100% rename from docs/nextflow_run/img/modules.svg rename to docs/en/docs/nextflow_run/img/modules.svg diff --git a/docs/nextflow_run/img/sayhello_with_input.svg b/docs/en/docs/nextflow_run/img/sayhello_with_input.svg similarity index 100% rename from docs/nextflow_run/img/sayhello_with_input.svg rename to docs/en/docs/nextflow_run/img/sayhello_with_input.svg diff --git a/docs/nextflow_run/img/with-collect-operator.svg b/docs/en/docs/nextflow_run/img/with-collect-operator.svg similarity index 100% rename from docs/nextflow_run/img/with-collect-operator.svg rename to docs/en/docs/nextflow_run/img/with-collect-operator.svg diff --git a/docs/nextflow_run/img/without-collect-operator.svg b/docs/en/docs/nextflow_run/img/without-collect-operator.svg similarity index 100% rename from docs/nextflow_run/img/without-collect-operator.svg rename to docs/en/docs/nextflow_run/img/without-collect-operator.svg diff --git a/docs/nextflow_run/index.md b/docs/en/docs/nextflow_run/index.md similarity index 100% rename from docs/nextflow_run/index.md rename to docs/en/docs/nextflow_run/index.md diff --git a/docs/nextflow_run/next_steps.md b/docs/en/docs/nextflow_run/next_steps.md similarity index 100% rename from docs/nextflow_run/next_steps.md rename to docs/en/docs/nextflow_run/next_steps.md diff --git a/docs/nextflow_run/survey.md b/docs/en/docs/nextflow_run/survey.md similarity index 100% rename from docs/nextflow_run/survey.md rename to docs/en/docs/nextflow_run/survey.md diff --git a/docs/nf4_science/genomics/00_orientation.md b/docs/en/docs/nf4_science/genomics/00_orientation.md similarity index 100% rename from docs/nf4_science/genomics/00_orientation.md rename to docs/en/docs/nf4_science/genomics/00_orientation.md diff --git a/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/en/docs/nf4_science/genomics/01_per_sample_variant_calling.md similarity index 100% rename from docs/nf4_science/genomics/01_per_sample_variant_calling.md rename to docs/en/docs/nf4_science/genomics/01_per_sample_variant_calling.md diff --git a/docs/nf4_science/genomics/02_joint_calling.md b/docs/en/docs/nf4_science/genomics/02_joint_calling.md similarity index 100% rename from docs/nf4_science/genomics/02_joint_calling.md rename to docs/en/docs/nf4_science/genomics/02_joint_calling.md diff --git a/docs/nf4_science/genomics/03_modules.md b/docs/en/docs/nf4_science/genomics/03_modules.md similarity index 100% rename from docs/nf4_science/genomics/03_modules.md rename to docs/en/docs/nf4_science/genomics/03_modules.md diff --git a/docs/nf4_science/genomics/04_testing.md b/docs/en/docs/nf4_science/genomics/04_testing.md similarity index 100% rename from docs/nf4_science/genomics/04_testing.md rename to docs/en/docs/nf4_science/genomics/04_testing.md diff --git a/docs/nf4_science/genomics/05_configuration.md b/docs/en/docs/nf4_science/genomics/05_configuration.md similarity index 100% rename from docs/nf4_science/genomics/05_configuration.md rename to docs/en/docs/nf4_science/genomics/05_configuration.md diff --git a/docs/nf4_science/genomics/img/gatk-pipeline.png b/docs/en/docs/nf4_science/genomics/img/gatk-pipeline.png similarity index 100% rename from docs/nf4_science/genomics/img/gatk-pipeline.png rename to docs/en/docs/nf4_science/genomics/img/gatk-pipeline.png diff --git a/docs/nf4_science/genomics/img/haplotype-caller.excalidraw.svg b/docs/en/docs/nf4_science/genomics/img/haplotype-caller.excalidraw.svg similarity index 100% rename from docs/nf4_science/genomics/img/haplotype-caller.excalidraw.svg rename to docs/en/docs/nf4_science/genomics/img/haplotype-caller.excalidraw.svg diff --git a/docs/nf4_science/genomics/img/hello-gatk-1.svg b/docs/en/docs/nf4_science/genomics/img/hello-gatk-1.svg similarity index 100% rename from docs/nf4_science/genomics/img/hello-gatk-1.svg rename to docs/en/docs/nf4_science/genomics/img/hello-gatk-1.svg diff --git a/docs/nf4_science/genomics/img/hello-gatk-2.svg b/docs/en/docs/nf4_science/genomics/img/hello-gatk-2.svg similarity index 100% rename from docs/nf4_science/genomics/img/hello-gatk-2.svg rename to docs/en/docs/nf4_science/genomics/img/hello-gatk-2.svg diff --git a/docs/nf4_science/genomics/img/joint-calling.png b/docs/en/docs/nf4_science/genomics/img/joint-calling.png similarity index 100% rename from docs/nf4_science/genomics/img/joint-calling.png rename to docs/en/docs/nf4_science/genomics/img/joint-calling.png diff --git a/docs/nf4_science/genomics/img/memory-after.png b/docs/en/docs/nf4_science/genomics/img/memory-after.png similarity index 100% rename from docs/nf4_science/genomics/img/memory-after.png rename to docs/en/docs/nf4_science/genomics/img/memory-after.png diff --git a/docs/nf4_science/genomics/img/memory-before.png b/docs/en/docs/nf4_science/genomics/img/memory-before.png similarity index 100% rename from docs/nf4_science/genomics/img/memory-before.png rename to docs/en/docs/nf4_science/genomics/img/memory-before.png diff --git a/docs/nf4_science/genomics/img/variants.png b/docs/en/docs/nf4_science/genomics/img/variants.png similarity index 100% rename from docs/nf4_science/genomics/img/variants.png rename to docs/en/docs/nf4_science/genomics/img/variants.png diff --git a/docs/nf4_science/genomics/index.md b/docs/en/docs/nf4_science/genomics/index.md similarity index 100% rename from docs/nf4_science/genomics/index.md rename to docs/en/docs/nf4_science/genomics/index.md diff --git a/docs/nf4_science/genomics/next_steps.md b/docs/en/docs/nf4_science/genomics/next_steps.md similarity index 100% rename from docs/nf4_science/genomics/next_steps.md rename to docs/en/docs/nf4_science/genomics/next_steps.md diff --git a/docs/nf4_science/genomics/survey.md b/docs/en/docs/nf4_science/genomics/survey.md similarity index 100% rename from docs/nf4_science/genomics/survey.md rename to docs/en/docs/nf4_science/genomics/survey.md diff --git a/docs/nf4_science/imaging/00_orientation.md b/docs/en/docs/nf4_science/imaging/00_orientation.md similarity index 100% rename from docs/nf4_science/imaging/00_orientation.md rename to docs/en/docs/nf4_science/imaging/00_orientation.md diff --git a/docs/nf4_science/imaging/01_basics.md b/docs/en/docs/nf4_science/imaging/01_basics.md similarity index 100% rename from docs/nf4_science/imaging/01_basics.md rename to docs/en/docs/nf4_science/imaging/01_basics.md diff --git a/docs/nf4_science/imaging/02_run_molkart.md b/docs/en/docs/nf4_science/imaging/02_run_molkart.md similarity index 100% rename from docs/nf4_science/imaging/02_run_molkart.md rename to docs/en/docs/nf4_science/imaging/02_run_molkart.md diff --git a/docs/nf4_science/imaging/03_inputs.md b/docs/en/docs/nf4_science/imaging/03_inputs.md similarity index 100% rename from docs/nf4_science/imaging/03_inputs.md rename to docs/en/docs/nf4_science/imaging/03_inputs.md diff --git a/docs/nf4_science/imaging/04_config.md b/docs/en/docs/nf4_science/imaging/04_config.md similarity index 100% rename from docs/nf4_science/imaging/04_config.md rename to docs/en/docs/nf4_science/imaging/04_config.md diff --git a/docs/nf4_science/imaging/img/molkart.png b/docs/en/docs/nf4_science/imaging/img/molkart.png similarity index 100% rename from docs/nf4_science/imaging/img/molkart.png rename to docs/en/docs/nf4_science/imaging/img/molkart.png diff --git a/docs/nf4_science/imaging/index.md b/docs/en/docs/nf4_science/imaging/index.md similarity index 100% rename from docs/nf4_science/imaging/index.md rename to docs/en/docs/nf4_science/imaging/index.md diff --git a/docs/nf4_science/imaging/next_steps.md b/docs/en/docs/nf4_science/imaging/next_steps.md similarity index 100% rename from docs/nf4_science/imaging/next_steps.md rename to docs/en/docs/nf4_science/imaging/next_steps.md diff --git a/docs/nf4_science/imaging/survey.md b/docs/en/docs/nf4_science/imaging/survey.md similarity index 100% rename from docs/nf4_science/imaging/survey.md rename to docs/en/docs/nf4_science/imaging/survey.md diff --git a/docs/nf4_science/index.md b/docs/en/docs/nf4_science/index.md similarity index 100% rename from docs/nf4_science/index.md rename to docs/en/docs/nf4_science/index.md diff --git a/docs/nf4_science/rnaseq/00_orientation.md b/docs/en/docs/nf4_science/rnaseq/00_orientation.md similarity index 100% rename from docs/nf4_science/rnaseq/00_orientation.md rename to docs/en/docs/nf4_science/rnaseq/00_orientation.md diff --git a/docs/nf4_science/rnaseq/01_method.md b/docs/en/docs/nf4_science/rnaseq/01_method.md similarity index 100% rename from docs/nf4_science/rnaseq/01_method.md rename to docs/en/docs/nf4_science/rnaseq/01_method.md diff --git a/docs/nf4_science/rnaseq/02_single-sample.md b/docs/en/docs/nf4_science/rnaseq/02_single-sample.md similarity index 100% rename from docs/nf4_science/rnaseq/02_single-sample.md rename to docs/en/docs/nf4_science/rnaseq/02_single-sample.md diff --git a/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/en/docs/nf4_science/rnaseq/03_multi-sample.md similarity index 100% rename from docs/nf4_science/rnaseq/03_multi-sample.md rename to docs/en/docs/nf4_science/rnaseq/03_multi-sample.md diff --git a/docs/nf4_science/rnaseq/index.md b/docs/en/docs/nf4_science/rnaseq/index.md similarity index 100% rename from docs/nf4_science/rnaseq/index.md rename to docs/en/docs/nf4_science/rnaseq/index.md diff --git a/docs/nf4_science/rnaseq/next_steps.md b/docs/en/docs/nf4_science/rnaseq/next_steps.md similarity index 100% rename from docs/nf4_science/rnaseq/next_steps.md rename to docs/en/docs/nf4_science/rnaseq/next_steps.md diff --git a/docs/nf4_science/rnaseq/survey.md b/docs/en/docs/nf4_science/rnaseq/survey.md similarity index 100% rename from docs/nf4_science/rnaseq/survey.md rename to docs/en/docs/nf4_science/rnaseq/survey.md diff --git a/docs/side_quests/README.md b/docs/en/docs/side_quests/README.md similarity index 100% rename from docs/side_quests/README.md rename to docs/en/docs/side_quests/README.md diff --git a/docs/side_quests/debugging.md b/docs/en/docs/side_quests/debugging.md similarity index 100% rename from docs/side_quests/debugging.md rename to docs/en/docs/side_quests/debugging.md diff --git a/docs/side_quests/dev_environment.md b/docs/en/docs/side_quests/dev_environment.md similarity index 100% rename from docs/side_quests/dev_environment.md rename to docs/en/docs/side_quests/dev_environment.md diff --git a/docs/side_quests/essential_scripting_patterns.md b/docs/en/docs/side_quests/essential_scripting_patterns.md similarity index 100% rename from docs/side_quests/essential_scripting_patterns.md rename to docs/en/docs/side_quests/essential_scripting_patterns.md diff --git a/docs/side_quests/ideas/containers.md b/docs/en/docs/side_quests/ideas/containers.md similarity index 100% rename from docs/side_quests/ideas/containers.md rename to docs/en/docs/side_quests/ideas/containers.md diff --git a/docs/side_quests/ideas/if_else.md b/docs/en/docs/side_quests/ideas/if_else.md similarity index 100% rename from docs/side_quests/ideas/if_else.md rename to docs/en/docs/side_quests/ideas/if_else.md diff --git a/docs/side_quests/img/active_file.png b/docs/en/docs/side_quests/img/active_file.png similarity index 100% rename from docs/side_quests/img/active_file.png rename to docs/en/docs/side_quests/img/active_file.png diff --git a/docs/side_quests/img/autocomplete_channel.png b/docs/en/docs/side_quests/img/autocomplete_channel.png similarity index 100% rename from docs/side_quests/img/autocomplete_channel.png rename to docs/en/docs/side_quests/img/autocomplete_channel.png diff --git a/docs/side_quests/img/autocomplete_config.png b/docs/en/docs/side_quests/img/autocomplete_config.png similarity index 100% rename from docs/side_quests/img/autocomplete_config.png rename to docs/en/docs/side_quests/img/autocomplete_config.png diff --git a/docs/side_quests/img/autocomplete_operators.png b/docs/en/docs/side_quests/img/autocomplete_operators.png similarity index 100% rename from docs/side_quests/img/autocomplete_operators.png rename to docs/en/docs/side_quests/img/autocomplete_operators.png diff --git a/docs/side_quests/img/autocomplete_process.png b/docs/en/docs/side_quests/img/autocomplete_process.png similarity index 100% rename from docs/side_quests/img/autocomplete_process.png rename to docs/en/docs/side_quests/img/autocomplete_process.png diff --git a/docs/side_quests/img/autocomplete_task.png b/docs/en/docs/side_quests/img/autocomplete_task.png similarity index 100% rename from docs/side_quests/img/autocomplete_task.png rename to docs/en/docs/side_quests/img/autocomplete_task.png diff --git a/docs/side_quests/img/bad_syntax.png b/docs/en/docs/side_quests/img/bad_syntax.png similarity index 100% rename from docs/side_quests/img/bad_syntax.png rename to docs/en/docs/side_quests/img/bad_syntax.png diff --git a/docs/side_quests/img/code_folding.png b/docs/en/docs/side_quests/img/code_folding.png similarity index 100% rename from docs/side_quests/img/code_folding.png rename to docs/en/docs/side_quests/img/code_folding.png diff --git a/docs/side_quests/img/dag_preview.png b/docs/en/docs/side_quests/img/dag_preview.png similarity index 100% rename from docs/side_quests/img/dag_preview.png rename to docs/en/docs/side_quests/img/dag_preview.png diff --git a/docs/side_quests/img/dag_preview_inner.png b/docs/en/docs/side_quests/img/dag_preview_inner.png similarity index 100% rename from docs/side_quests/img/dag_preview_inner.png rename to docs/en/docs/side_quests/img/dag_preview_inner.png diff --git a/docs/side_quests/img/error_underline.png b/docs/en/docs/side_quests/img/error_underline.png similarity index 100% rename from docs/side_quests/img/error_underline.png rename to docs/en/docs/side_quests/img/error_underline.png diff --git a/docs/side_quests/img/extensions_icon.png b/docs/en/docs/side_quests/img/extensions_icon.png similarity index 100% rename from docs/side_quests/img/extensions_icon.png rename to docs/en/docs/side_quests/img/extensions_icon.png diff --git a/docs/side_quests/img/files_icon.png b/docs/en/docs/side_quests/img/files_icon.png similarity index 100% rename from docs/side_quests/img/files_icon.png rename to docs/en/docs/side_quests/img/files_icon.png diff --git a/docs/side_quests/img/finding.png b/docs/en/docs/side_quests/img/finding.png similarity index 100% rename from docs/side_quests/img/finding.png rename to docs/en/docs/side_quests/img/finding.png diff --git a/docs/side_quests/img/follow_link.png b/docs/en/docs/side_quests/img/follow_link.png similarity index 100% rename from docs/side_quests/img/follow_link.png rename to docs/en/docs/side_quests/img/follow_link.png diff --git a/docs/side_quests/img/incorrect_num_args.png b/docs/en/docs/side_quests/img/incorrect_num_args.png similarity index 100% rename from docs/side_quests/img/incorrect_num_args.png rename to docs/en/docs/side_quests/img/incorrect_num_args.png diff --git a/docs/side_quests/img/install_extension.png b/docs/en/docs/side_quests/img/install_extension.png similarity index 100% rename from docs/side_quests/img/install_extension.png rename to docs/en/docs/side_quests/img/install_extension.png diff --git a/docs/side_quests/img/invalid_process_message.png b/docs/en/docs/side_quests/img/invalid_process_message.png similarity index 100% rename from docs/side_quests/img/invalid_process_message.png rename to docs/en/docs/side_quests/img/invalid_process_message.png diff --git a/docs/side_quests/img/nf-core/nested.excalidraw.svg b/docs/en/docs/side_quests/img/nf-core/nested.excalidraw.svg similarity index 100% rename from docs/side_quests/img/nf-core/nested.excalidraw.svg rename to docs/en/docs/side_quests/img/nf-core/nested.excalidraw.svg diff --git a/docs/hello_nf-core/img/nf-core-logo.png b/docs/en/docs/side_quests/img/nf-core/nf-core-logo.png similarity index 100% rename from docs/hello_nf-core/img/nf-core-logo.png rename to docs/en/docs/side_quests/img/nf-core/nf-core-logo.png diff --git a/docs/side_quests/img/nf-core/nf-core-modules.png b/docs/en/docs/side_quests/img/nf-core/nf-core-modules.png similarity index 100% rename from docs/side_quests/img/nf-core/nf-core-modules.png rename to docs/en/docs/side_quests/img/nf-core/nf-core-modules.png diff --git a/docs/side_quests/img/nf-core/pipeline.excalidraw.svg b/docs/en/docs/side_quests/img/nf-core/pipeline.excalidraw.svg similarity index 100% rename from docs/side_quests/img/nf-core/pipeline.excalidraw.svg rename to docs/en/docs/side_quests/img/nf-core/pipeline.excalidraw.svg diff --git a/docs/side_quests/img/nf-core/pipeline_schema.png b/docs/en/docs/side_quests/img/nf-core/pipeline_schema.png similarity index 100% rename from docs/side_quests/img/nf-core/pipeline_schema.png rename to docs/en/docs/side_quests/img/nf-core/pipeline_schema.png diff --git a/docs/side_quests/img/nonlethal.png b/docs/en/docs/side_quests/img/nonlethal.png similarity index 100% rename from docs/side_quests/img/nonlethal.png rename to docs/en/docs/side_quests/img/nonlethal.png diff --git a/docs/side_quests/img/outline.png b/docs/en/docs/side_quests/img/outline.png similarity index 100% rename from docs/side_quests/img/outline.png rename to docs/en/docs/side_quests/img/outline.png diff --git a/docs/side_quests/img/problems_panel.png b/docs/en/docs/side_quests/img/problems_panel.png similarity index 100% rename from docs/side_quests/img/problems_panel.png rename to docs/en/docs/side_quests/img/problems_panel.png diff --git a/docs/side_quests/img/project_search.png b/docs/en/docs/side_quests/img/project_search.png similarity index 100% rename from docs/side_quests/img/project_search.png rename to docs/en/docs/side_quests/img/project_search.png diff --git a/docs/side_quests/img/references.png b/docs/en/docs/side_quests/img/references.png similarity index 100% rename from docs/side_quests/img/references.png rename to docs/en/docs/side_quests/img/references.png diff --git a/docs/side_quests/img/sai_explains.png b/docs/en/docs/side_quests/img/sai_explains.png similarity index 100% rename from docs/side_quests/img/sai_explains.png rename to docs/en/docs/side_quests/img/sai_explains.png diff --git a/docs/side_quests/img/seqeraai_errors.png b/docs/en/docs/side_quests/img/seqeraai_errors.png similarity index 100% rename from docs/side_quests/img/seqeraai_errors.png rename to docs/en/docs/side_quests/img/seqeraai_errors.png diff --git a/docs/side_quests/img/source_control.png b/docs/en/docs/side_quests/img/source_control.png similarity index 100% rename from docs/side_quests/img/source_control.png rename to docs/en/docs/side_quests/img/source_control.png diff --git a/docs/side_quests/img/source_control_icon.png b/docs/en/docs/side_quests/img/source_control_icon.png similarity index 100% rename from docs/side_quests/img/source_control_icon.png rename to docs/en/docs/side_quests/img/source_control_icon.png diff --git a/docs/side_quests/img/split_editor.png b/docs/en/docs/side_quests/img/split_editor.png similarity index 100% rename from docs/side_quests/img/split_editor.png rename to docs/en/docs/side_quests/img/split_editor.png diff --git a/docs/side_quests/img/symbols.png b/docs/en/docs/side_quests/img/symbols.png similarity index 100% rename from docs/side_quests/img/symbols.png rename to docs/en/docs/side_quests/img/symbols.png diff --git a/docs/side_quests/img/syntax.png b/docs/en/docs/side_quests/img/syntax.png similarity index 100% rename from docs/side_quests/img/syntax.png rename to docs/en/docs/side_quests/img/syntax.png diff --git a/docs/side_quests/img/syntax_showcase.png b/docs/en/docs/side_quests/img/syntax_showcase.png similarity index 100% rename from docs/side_quests/img/syntax_showcase.png rename to docs/en/docs/side_quests/img/syntax_showcase.png diff --git a/docs/side_quests/img/vscode_dropdown_error.png b/docs/en/docs/side_quests/img/vscode_dropdown_error.png similarity index 100% rename from docs/side_quests/img/vscode_dropdown_error.png rename to docs/en/docs/side_quests/img/vscode_dropdown_error.png diff --git a/docs/side_quests/index.md b/docs/en/docs/side_quests/index.md similarity index 100% rename from docs/side_quests/index.md rename to docs/en/docs/side_quests/index.md diff --git a/docs/side_quests/metadata.md b/docs/en/docs/side_quests/metadata.md similarity index 100% rename from docs/side_quests/metadata.md rename to docs/en/docs/side_quests/metadata.md diff --git a/docs/side_quests/nf-test.md b/docs/en/docs/side_quests/nf-test.md similarity index 100% rename from docs/side_quests/nf-test.md rename to docs/en/docs/side_quests/nf-test.md diff --git a/docs/side_quests/orientation.md b/docs/en/docs/side_quests/orientation.md similarity index 100% rename from docs/side_quests/orientation.md rename to docs/en/docs/side_quests/orientation.md diff --git a/docs/side_quests/splitting_and_grouping.md b/docs/en/docs/side_quests/splitting_and_grouping.md similarity index 100% rename from docs/side_quests/splitting_and_grouping.md rename to docs/en/docs/side_quests/splitting_and_grouping.md diff --git a/docs/side_quests/workflows_of_workflows.md b/docs/en/docs/side_quests/workflows_of_workflows.md similarity index 100% rename from docs/side_quests/workflows_of_workflows.md rename to docs/en/docs/side_quests/workflows_of_workflows.md diff --git a/docs/side_quests/working_with_files.md b/docs/en/docs/side_quests/working_with_files.md similarity index 100% rename from docs/side_quests/working_with_files.md rename to docs/en/docs/side_quests/working_with_files.md diff --git a/docs/training_collections/architects_toolkit_1.md b/docs/en/docs/training_collections/architects_toolkit_1.md similarity index 100% rename from docs/training_collections/architects_toolkit_1.md rename to docs/en/docs/training_collections/architects_toolkit_1.md diff --git a/docs/training_collections/index.md b/docs/en/docs/training_collections/index.md similarity index 100% rename from docs/training_collections/index.md rename to docs/en/docs/training_collections/index.md diff --git a/docs/assets/hooks/index_page_hook.py b/docs/en/hooks/index_page_hook.py similarity index 53% rename from docs/assets/hooks/index_page_hook.py rename to docs/en/hooks/index_page_hook.py index f243d26e9b..e033f4b032 100644 --- a/docs/assets/hooks/index_page_hook.py +++ b/docs/en/hooks/index_page_hook.py @@ -3,22 +3,73 @@ This hook transforms pages with `template: index_page` frontmatter, generating Material for MkDocs grid cards from structured frontmatter data. + +UI strings are loaded from ui-strings.yml in the language directory, +falling back to English if translations are not available. """ import re +from functools import lru_cache +from pathlib import Path -# Default content for various sections -DEFAULT_CONTENT = { - "technical_requirements": ( - "You will need a GitHub account OR a local installation of Nextflow. " - "See [Environment options](../envsetup/index.md) for more details." - ), - "videos": ( - "Videos are available for each chapter, featuring an instructor working " - "through the exercises. The video for each part of the course is embedded " - "at the top of the corresponding page." - ), -} +import yaml + +# Path to docs directory (parent of hooks directory's parent) +DOCS_PATH = Path(__file__).parent.parent.parent + + +@lru_cache +def load_ui_strings(lang: str) -> dict: + """ + Load UI strings for a language, falling back to English. + + Args: + lang: Language code (e.g., 'en', 'ko', 'de') + + Returns: + Dictionary with UI strings + """ + # Try language-specific file first + lang_file = DOCS_PATH / lang / "ui-strings.yml" + if lang_file.exists(): + strings = yaml.safe_load(lang_file.read_text(encoding="utf-8")) + if strings: + return strings + + # Fall back to English + en_file = DOCS_PATH / "en" / "ui-strings.yml" + if en_file.exists(): + return yaml.safe_load(en_file.read_text(encoding="utf-8")) + + # Ultimate fallback - hardcoded English defaults + return { + "index_page": { + "course_summary": "Course summary", + "additional_information": "Additional information", + "technical_requirements": "Technical requirements", + "learning_objectives": "Learning objectives", + "audience_prerequisites": "Audience & prerequisites", + "course_videos": "Course videos", + }, + "defaults": { + "technical_requirements": ( + "You will need a GitHub account OR a local installation of Nextflow. " + "See [Environment options](../envsetup/index.md) for more details." + ), + "videos": ( + "Videos are available for each chapter, featuring an instructor working " + "through the exercises. The video for each part of the course is embedded " + "at the top of the corresponding page." + ), + }, + } + + +def get_lang_from_config(config) -> str: + """Extract language code from MkDocs config.""" + # Try theme.language first + lang = config.get("theme", {}).get("language", "en") + return lang if lang else "en" def on_page_markdown(markdown, page, config, files): @@ -32,6 +83,12 @@ def on_page_markdown(markdown, page, config, files): if page.meta.get("page_type") != "index_page": return None + # Load UI strings for this language + lang = get_lang_from_config(config) + ui = load_ui_strings(lang) + labels = ui.get("index_page", {}) + defaults = ui.get("defaults", {}) + # Extract H1 heading h1_match = re.search(r"^# (.+)$", markdown, re.MULTILINE) if not h1_match: @@ -60,7 +117,9 @@ def on_page_markdown(markdown, page, config, files): # Generate additional information admonitions additional_info = page.meta.get("additional_information", {}) - admonitions = generate_admonitions(additional_info, page.file.src_path) + admonitions = generate_admonitions( + additional_info, page.file.src_path, labels, defaults + ) # Generate badge HTML if index_type is specified badge_html = "" @@ -68,18 +127,24 @@ def on_page_markdown(markdown, page, config, files): if index_type: badge_html = f'<span class="index-type-badge">{index_type}</span>\n\n' + # Get translated labels + course_summary = labels.get("course_summary", "Course summary") + additional_information = labels.get( + "additional_information", "Additional information" + ) + # Build the grid cards structure grid_content = f"""# {h1_title}{badge_html} <div class="grid cards" markdown> -- :material-book-open-variant:{{ .lg .middle }} __Course summary__ +- :material-book-open-variant:{{ .lg .middle }} __{course_summary}__ --- {indent_content(summary_content, 4)} -- :material-information-outline:{{ .lg .middle }} __Additional information__ +- :material-information-outline:{{ .lg .middle }} __{additional_information}__ --- @@ -92,18 +157,37 @@ def on_page_markdown(markdown, page, config, files): return grid_content -def generate_admonitions(additional_info, src_path): +def generate_admonitions(additional_info, src_path, labels, defaults): """Generate the admonition markdown from additional_information frontmatter.""" if not additional_info: return "" admonitions = [] + # Get translated labels with English fallbacks + tech_req_label = labels.get("technical_requirements", "Technical requirements") + learning_obj_label = labels.get("learning_objectives", "Learning objectives") + audience_label = labels.get("audience_prerequisites", "Audience & prerequisites") + videos_label = labels.get("course_videos", "Course videos") + + # Get default content with fallbacks + default_tech_req = defaults.get( + "technical_requirements", + "You will need a GitHub account OR a local installation of Nextflow. " + "See [Environment options](../envsetup/index.md) for more details.", + ) + default_videos = defaults.get( + "videos", + "Videos are available for each chapter, featuring an instructor working " + "through the exercises. The video for each part of the course is embedded " + "at the top of the corresponding page.", + ) + # Technical requirements tech_req = additional_info.get("technical_requirements") if tech_req: if tech_req is True: - content = DEFAULT_CONTENT["technical_requirements"] + content = default_tech_req elif isinstance(tech_req, str): content = tech_req else: @@ -111,7 +195,7 @@ def generate_admonitions(additional_info, src_path): f"Page '{src_path}': technical_requirements must be true or a string" ) admonitions.append( - f'??? terminal "Technical requirements"\n{indent_content(content, 4)}' + f'??? terminal "{tech_req_label}"\n{indent_content(content, 4)}' ) # Learning objectives (must be a list) @@ -127,7 +211,7 @@ def generate_admonitions(additional_info, src_path): ) items = "\n".join(f"- {item}" for item in learning_obj) admonitions.append( - f'??? learning "Learning objectives"\n{indent_content(items, 4)}' + f'??? learning "{learning_obj_label}"\n{indent_content(items, 4)}' ) # Audience & prerequisites (must be a list) @@ -142,9 +226,7 @@ def generate_admonitions(additional_info, src_path): f"Page '{src_path}': audience_prerequisites must be a list of strings" ) items = "\n".join(f"- {item}" for item in audience) - admonitions.append( - f'??? people "Audience & prerequisites"\n{indent_content(items, 4)}' - ) + admonitions.append(f'??? people "{audience_label}"\n{indent_content(items, 4)}') # Videos (videos and videos_playlist are mutually exclusive) videos = additional_info.get("videos") @@ -157,10 +239,11 @@ def generate_admonitions(additional_info, src_path): ) if videos_playlist: - content = f'{DEFAULT_CONTENT["videos"]}\n\n[View the playlist on YouTube]({videos_playlist}){{:target="_blank"}}' - admonitions.append(f'??? videos "Course videos"\n{indent_content(content, 4)}') + view_playlist = defaults.get("view_playlist", "View the playlist on YouTube") + content = f'{default_videos}\n\n[{view_playlist}]({videos_playlist}){{:target="_blank"}}' + admonitions.append(f'??? videos "{videos_label}"\n{indent_content(content, 4)}') elif videos: - admonitions.append(f'??? videos "Course videos"\n{indent_content(videos, 4)}') + admonitions.append(f'??? videos "{videos_label}"\n{indent_content(videos, 4)}') return "\n\n".join(admonitions) diff --git a/mkdocs.yml b/docs/en/mkdocs.yml similarity index 82% rename from mkdocs.yml rename to docs/en/mkdocs.yml index 57e6ef18e5..a1883f10e4 100644 --- a/mkdocs.yml +++ b/docs/en/mkdocs.yml @@ -4,7 +4,7 @@ repo_url: https://github.com/nextflow-io/training repo_name: nextflow-io/training nav: - - Home: index.md + - index.md - Nextflow Run: - nextflow_run/index.md - nextflow_run/00_orientation.md @@ -88,7 +88,7 @@ nav: theme: name: material - custom_dir: docs/assets/overrides + custom_dir: overrides language: en logo: assets/img/nextflow_logo_dark.png favicon: assets/img/nextflow-icon.png @@ -129,14 +129,17 @@ theme: people: octicons/people-16 licensing: octicons/law-16 videos: octicons/video-16 + extra_css: - assets/stylesheets/fonts.css - assets/stylesheets/extra.css extra_javascript: + - assets/javascripts/consent-sync.js - assets/javascripts/posthog.js + - assets/javascripts/language-picker.js -# Set in docs/assets/overrides/partials/copyright.html +# Set in overrides/partials/copyright.html # so that we can have links and stuff # copyright: Seqera @@ -164,7 +167,7 @@ extra: <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">how we use cookies</a>. cookies: posthog: PostHog Analytics - # Overridden in docs/assets/overrides/partials/social.html + # Overridden in overrides/partials/social.html # Still needs to be set to something here so that the partial is used social: - icon: fontawesome/brands/twitter @@ -173,6 +176,40 @@ extra: version: provider: mike alias: true + # Language picker + # Links use defined base paths; JS in main.html fixes for mike versioning + alternate: + - name: English + link: / + lang: en + - name: deutsch + link: /de/ + lang: de + - name: español + link: /es/ + lang: es + - name: français + link: /fr/ + lang: fr + - name: हिन्दी + link: /hi/ + lang: hi + - name: italiano + link: /it/ + lang: it + - name: 한국어 + link: /ko/ + lang: ko + - name: Polski + link: /pl/ + lang: pl + - name: português + link: /pt/ + lang: pt + - name: Türkçe + link: /tr/ + lang: tr + markdown_extensions: - admonition - attr_list @@ -187,8 +224,7 @@ markdown_extensions: - pymdownx.inlinehilite - pymdownx.keys - pymdownx.snippets: - base_path: ["."] - - pymdownx.snippets + base_path: ["../.."] - pymdownx.superfences: preserve_tabs: true custom_fences: @@ -204,6 +240,7 @@ markdown_extensions: - toc: title: On this page permalink: true + plugins: - enumerate-headings: restart_increment_after: @@ -229,51 +266,23 @@ plugins: - side_quests/*.md - training_collections/index.md - training_collections/advanced_workflow_development/index.md - - i18n: - docs_structure: suffix - fallback_to_default: true - languages: - - build: true - default: true - locale: en - name: English - - build: true - default: false - locale: pt - name: Português - - build: true - default: false - locale: es - name: Español - - build: true - default: false - locale: fr - name: Français - - build: true - default: false - locale: it - name: Italiano - - build: true - default: false - locale: ko - name: Korean - reconfigure_material: true - reconfigure_search: true + - search - mkdocs_quiz: progress_sidebar_position: bottom cli_run: "Nextflow Run": - "Basics": docs/nextflow_run/01_basics.md - "Pipeline": docs/nextflow_run/02_pipeline.md - "Config": docs/nextflow_run/03_config.md + "Basics": nextflow_run/01_basics.md + "Pipeline": nextflow_run/02_pipeline.md + "Config": nextflow_run/03_config.md "Hello Nextflow": - "Hello World": docs/hello_nextflow/01_hello_world.md - "Hello Channels": docs/hello_nextflow/02_hello_channels.md - "Hello Workflow": docs/hello_nextflow/03_hello_workflow.md - "Hello Modules": docs/hello_nextflow/04_hello_modules.md - "Hello Containers": docs/hello_nextflow/05_hello_containers.md - "Hello Config": docs/hello_nextflow/06_hello_config.md + "Hello World": hello_nextflow/01_hello_world.md + "Hello Channels": hello_nextflow/02_hello_channels.md + "Hello Workflow": hello_nextflow/03_hello_workflow.md + "Hello Modules": hello_nextflow/04_hello_modules.md + "Hello Containers": hello_nextflow/05_hello_containers.md + "Hello Config": hello_nextflow/06_hello_config.md hooks: - - docs/assets/hooks/index_page_hook.py + - ../../_scripts/mkdocs_hooks.py + - ../en/hooks/index_page_hook.py diff --git a/docs/assets/overrides/main.html b/docs/en/overrides/main.html similarity index 100% rename from docs/assets/overrides/main.html rename to docs/en/overrides/main.html diff --git a/docs/en/overrides/partials/actions.html b/docs/en/overrides/partials/actions.html new file mode 100644 index 0000000000..e9aae651eb --- /dev/null +++ b/docs/en/overrides/partials/actions.html @@ -0,0 +1,34 @@ +{#- Override of MkDocs Material actions.html to add translate icon for +translated pages. See: +https://github.com/squidfunk/mkdocs-material/blob/master/src/templates/partials/actions.html +-#} {% if page.edit_url %} {% if "content.action.edit" in features %} +<a + href="{{ page.edit_url }}" + title="{{ lang.t('action.edit') }}" + class="md-content__button md-icon" + rel="edit" +> + {% set icon = config.theme.icon.edit or "material/file-edit-outline" %} {% + include ".icons/" ~ icon ~ ".svg" %} +</a> +{% endif %} {% if "content.action.view" in features %} {% if "/blob/" in +page.edit_url %} {% set part = "blob" %} {% else %} {% set part = "edit" %} {% +endif %} +<a + href="{{ page.edit_url | replace(part, 'raw') }}" + title="{{ lang.t('action.view') }}" + class="md-content__button md-icon" +> + {% set icon = config.theme.icon.view or "material/file-eye-outline" %} {% + include ".icons/" ~ icon ~ ".svg" %} +</a> +{% endif %} {# Add translate icon for non-English pages #} {% if +config.theme.language and config.theme.language != "en" %} +<a + href="https://github.com/nextflow-io/training/blob/master/TRANSLATING.md" + title="Improve translation" + class="md-content__button md-icon" +> + {% include ".icons/material/translate-variant.svg" %} +</a> +{% endif %} {% endif %} diff --git a/docs/assets/overrides/partials/copyright.html b/docs/en/overrides/partials/copyright.html similarity index 100% rename from docs/assets/overrides/partials/copyright.html rename to docs/en/overrides/partials/copyright.html diff --git a/docs/assets/overrides/partials/social.html b/docs/en/overrides/partials/social.html similarity index 100% rename from docs/assets/overrides/partials/social.html rename to docs/en/overrides/partials/social.html diff --git a/docs/assets/overrides/partials/toc.html b/docs/en/overrides/partials/toc.html similarity index 100% rename from docs/assets/overrides/partials/toc.html rename to docs/en/overrides/partials/toc.html diff --git a/docs/en/ui-strings.yml b/docs/en/ui-strings.yml new file mode 100644 index 0000000000..a5f19102e6 --- /dev/null +++ b/docs/en/ui-strings.yml @@ -0,0 +1,24 @@ +# UI strings for translation - English source +# These strings are used by index_page_hook.py for course landing pages +# and in mkdocs.yml for cookie consent. +# +# When adding a new language, copy this file to docs/<lang>/ui-strings.yml +# and translate all values. + +index_page: + course_summary: "Course summary" + additional_information: "Additional information" + technical_requirements: "Technical requirements" + learning_objectives: "Learning objectives" + audience_prerequisites: "Audience & prerequisites" + course_videos: "Course videos" + +defaults: + technical_requirements: >- + You will need a GitHub account OR a local installation of Nextflow. + See [Environment options](../envsetup/index.md) for more details. + videos: >- + Videos are available for each chapter, featuring an instructor working + through the exercises. The video for each part of the course is embedded + at the top of the corresponding page. + view_playlist: "View the playlist on YouTube" diff --git a/docs/envsetup/01_setup.ko.md b/docs/envsetup/01_setup.ko.md deleted file mode 100644 index bc8c4e7ab3..0000000000 --- a/docs/envsetup/01_setup.ko.md +++ /dev/null @@ -1,81 +0,0 @@ -# GitHub Codespaces - -GitHub Codespaces는 팀이 효율적이고 안전하게 소프트웨어를 개발할 수 있도록 도와주는 클라우드 개발 환경입니다. -학습자에게 일관되고 철저히 검증된 환경을 제공할 수 있기 때문에, 저희는 이를 교육용 환경으로 사용하고 있습니다. - -## GitHub 계정 만들기 - -[GitHub 홈페이지](https://github.com/)에서 무료 GitHub 계정을 만들 수 있습니다. - -## GitHub Codespaces 실행하기 - -GitHub에 로그인한 후, 아래 링크를 브라우저에서 열면 교육용 환경이 실행됩니다: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> - -또한, 교육 포털 내 여러 페이지에 표시된 아래 버튼을 통해서도 접근할 수 있습니다. - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -링크를 열면 새로운 GitHub Codespace를 생성할 수 있는 화면이 표시됩니다: - -![Create a GitHub Codespace](img/codespaces_create.png) - -"Change options" 버튼을 클릭하면 사용할 머신의 사양을 설정할 수 있습니다. -코어 수가 더 많은 머신을 사용하면 Nextflow의 워크플로우 병렬 처리 기능을 더 효과적으로 활용할 수 있습니다. - -**Hello Nextflow, Nextflow for Science, nf-core 교육 과정의 경우 4코어 머신 사용을 권장합니다.** - -GitHub의 무료 플랜은 매월 120코어-시간의 Codespaces 사용량을 제공하며, 이는 4코어 머신 기준 약 30시간에 해당합니다. -(자세한 사용량 정보는 아래 참고) - -!!! warning - - GitHub Codespaces 환경을 처음 열 때는 몇 분 정도 시간이 걸릴 수 있습니다. - 그동안 차 한 잔을 준비하거나 이메일을 확인해 보세요. 그룹 교육 중이라면 간단히 소개 자료를 살펴보는 것도 괜찮겠죠. - -## GitHub Codespaces IDE 탐색하기 - -GitHub Codespaces가 로딩되면, 다음과 유사한 화면이 나타납니다 (계정 설정에 따라 밝은 테마일 수 있습니다): - -![GitHub Codespaces 환영 화면](img/codespaces_welcome.png) - -이것은 VSCode IDE의 인터페이스이며, Nextflow 개발에 적합한 인기 있는 코드 편집기입니다. - -- **사이드바(Sidebar)** 환경을 커스터마이즈하거나 파일 열기, 검색, Git 작업 등을 할 수 있습니다. 탐색기 아이콘을 클릭하면 현재 저장소에 포함된 파일들을 볼 수 있습니다. -- **터미널(Terminal)** 저장소 내 설치된 프로그램을 실행할 수 있습니다. 예: `nextflow`, `docker`. -- **파일 탐색기(File Explorer)** 파일을 열고 편집할 수 있습니다. 클릭 시 메인 편집기에 열립니다. -- **메인 편집기(Main Editor)** 예시로 `README.md` 파일이 미리 열려 있으며, 코드나 데이터 파일을 열면 이곳에 표시됩니다. - -## GitHub Codespaces 세션 다시 열기 - -한 번 생성한 환경은 쉽게 재개하거나 다시 시작할 수 있으며, 마지막 상태부터 이어서 작업할 수 있습니다. -30분 이상 아무 활동이 없으면 환경이 자동 종료되며, 변경 내용은 최대 2주 동안 저장됩니다. - -<https://github.com/codespaces/> 에서 이전 세션을 확인하고 재개할 수 있습니다. -리스트에서 원하는 세션을 클릭하면 다시 열립니다. - -![GitHub Codespace 세션 리스트](img/codespaces_list.png) - -이전 세션의 URL을 저장해 두었다면, 브라우저에서 다시 열 수 있습니다. -혹은 처음 생성할 때 클릭했던 버튼을 다시 클릭해도 됩니다: - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -이전 세션이 있다면 기본적으로 이어서 열도록 설정되어 있습니다: - -![GitHub Codespace 다시 열기](img/codespaces_resume.png) - -## GitHub Codespaces에서 파일을 로컬로 저장하기 - -파일 탐색기에서 원하는 파일을 마우스 오른쪽 클릭한 뒤 `Download`를 선택하면 로컬로 저장할 수 있습니다. - -## GitHub Codespaces 사용량 - -GitHub Codespaces는 매월 최대 15GB 저장 공간과 120 코어-시간을 제공합니다. -이는 기본 환경 기준으로 약 60시간 정도 사용할 수 있는 분량입니다 (2코어, 8GB RAM, 32GB 저장소 기준). - -GitHub Codespaces 환경은 사용자의 필요에 따라 구성할 수 있습니다. -더 높은 사양으로 환경을 생성할 수도 있지만, 이 경우 무료 사용량이 더 빨리 소모되어 사용할 수 있는 시간이 줄어들 수 있습니다. -추가 리소스가 필요한 경우, 유료로 구매하여 사용할 수도 있습니다. - -자세한 내용은 GitHub 공식 문서를 참고하세요: -[GitHub Codespaces 요금제 관련 문서](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/envsetup/01_setup.pt.md b/docs/envsetup/01_setup.pt.md deleted file mode 100644 index 4252f0253b..0000000000 --- a/docs/envsetup/01_setup.pt.md +++ /dev/null @@ -1,66 +0,0 @@ -# Gitpod - -Gitpod é um ambiente de desenvolvimento em nuvem feito para equipes desenvolverem software de forma segura e eficiente. Ele pode aprimorar sua experiência de desenvolvedor ao possibilitar que programe em um ambiente de desenvolvimento em nuvem. - -## Criando uma conta no Gitpod - -Você pode criar uma conta gratuita no [Gitpod](https://gitpod.io/) usando sua conta pré-existente no GitLab, GitHub ou Bitbucket. - -Você pode criar uma conta usando a [página de login do Gitpod](https://gitpod.io/login/). - -![Gitpod log in](img/login.png) - -Recomendamos que conecte sua conta do LinkedIn para receber um tempo adicional de uso de 50 horas. - -![Gitpod log in one step](img/onestepaway.png) - -Depois de selecionar seu editor e tema preferidos e conferir os detalhes do seu perfil, clique em continuar e sua conta será criada e já estará pronta para uso. - -!!! note - - Recomendamos que utilize o editor de texto VS Code. - -## Executando o Gitpod - -Clique na URL a seguir para executar o Gitpod: <https://gitpod.io/#https://github.com/nextflow-io/training> - -Essa URL é o repositório de treinamento do Nextflow prefixado com `https://gitpod.io/#`. - -Você também pode acessar o material clicando no botão abaixo. - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -Se você já estiver logado, seu ambiente no Gitpod começará a carregar. - -### Explore sua IDE no Gitpod - -Após o carregamento concluir, você poderá ver algo semelhante a isso: - -![Gitpod welcome](img/gitpod.welcome.png) - -- **A barra lateral** permite que você customize seu ambiente Gitpod e realize tarefas básicas (copiar, colar, abrir arquivos, buscar, git, etc.). Você pode clicar no explorador para ver que arquivos estão presentes em seu repositório. -- **O terminal** permite que você execute todos os programas no repositório. Por exemplo, `nextflow` e `docker` estão instalados e podem ser executados. -- **O explorador de arquivos** permite que você visualize e edite arquivos. Clicar em um arquivo no explorador irá abri-lo na janela principal. -- **O navegador** permite que você visualize o material de treinamento (<https://training.nextflow.io/>). Caso o feche acidentalmente, você pode iniciar o navegador novamente executando o seguinte comando no terminal: `gp preview https://training.nextflow.io`. - -### Recursos do Gitpod - -O Gitpod fornece 500 créditos gratuitos por mês, o que é equivalente a 50 horas de uso gratuito do ambiente de execução usando a área de trabalho padrão (até 4 núcleos, 8 GB de RAM e 30 GB de armazenamento). - -Também há a opção de uma área de trabalho maior, que fornece até 8 núcleos, 16 GB de RAM e 50 GB de armazenamento. No entanto, essa área de trabalho maior irá utilizar seus recursos mais rapidamente e você terá menos horas de acesso a ela. - -O ambiente Gitpod irá pausar após 30 minutos de inatividade e salvará suas mudanças por até 2 semanas. - -Mais informação sobre o Gitpod está disponível em [gitpod.io](https://www.gitpod.io). - -### Reiniciando uma sessão no Gitpod - -Você pode reiniciar um ambiente na página <https://gitpod.io/workspaces>. Ambientes anteriores serão listados nessa página. Basta selecionar a elipse (os três pontos) e então eselcionar `Open` para reiniciar um ambiente anterior. - -Se você salvou a URL de um ambiente anterior do Gitpod, para reiniciá-lo basta abrir a URL em seu navegador. - -Você também pode apenas iniciar um novo ambiente de treinamento na URL a seguir: <https://gitpod.io/#https://github.com/nextflow-io/training> - -### Salvando arquivos do Gitpod na sua máquina local - -Para salvar qualquer arquivo do painel do explorador, clique no arquivo com o botão direito do mouse e selcione `Download`. diff --git a/docs/envsetup/02_local.ko.md b/docs/envsetup/02_local.ko.md deleted file mode 100644 index 91949d6b32..0000000000 --- a/docs/envsetup/02_local.ko.md +++ /dev/null @@ -1,90 +0,0 @@ -# 로컬 설치 - -어떠한 이유로든 GitHub Codespaces 세션을 **사용할 수 없는 경우**, 모든 환경을 로컬에 설치하여 사용할수 있습니다. - -로컬 머신의 운영체제나 설정에 따라 요구 사항이 다를수 있습니다. - -## 요구 사항 - -Nextflow는 POSIX 호환 시스템(Linux, macOS, Windows Subsystem for Linux 등)에서 사용 가능합니다. - -**필수 구성 요소** - -- Bash -- [Java 11 이상 (최대 21까지 지원)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) -- [Git](https://git-scm.com/) -- [Docker](https://docs.docker.com/get-docker/) - -**선택 구성 요소** - -- [Singularity](https://github.com/sylabs/singularity) 2.5.x (이상) -- [Conda](https://conda.io/) 4.5 (이상) -- [Graphviz](http://www.graphviz.org/) -- [AWS CLI](https://aws.amazon.com/cli/) -- 사전에 설정된 AWS Batch 작업 실행 환경 - -## Nextflow 다운로드 - -터미널에서 다음 명령어를 실행하세요: - -```bash -wget -qO- https://get.nextflow.io | bash -``` - -또는 `curl` 명령어를 사용할수 있습니다: - -```bash -curl -s https://get.nextflow.io | bash -``` - -다음으로, 다운로드된 실행 파일에 실행 권한을 부여하세요: - -```bash -chmod +x nextflow -``` - -마지막으로, `nextflow` 실행 파일이 `$PATH`에 포함되어 있는지 확인하세요. 실행 파일은 `/usr/local/bin`, `/bin/` 등의 경로에 위치할 수 있습니다. - -## Docker - -Docker Desktop이 컴퓨터에서 실행되고 있는지 확인하세요. 설치하지 않았다면 [이 링크](https://docs.docker.com/get-docker/)를 통해 다운로드할 수 있습니다. - -## 교육 자료 - -[이 링크](https://training.nextflow.io/)에서 교육 자료를 확인할 수 있습니다. - -자료를 다운로드하려면 다음 명령어를 실행하세요요: - -```bash -git clone https://github.com/nextflow-io/training.git -``` - -이후, 터미널에서 `cd` 명령어를 사용해 해당 디렉토리로 이동하세요. 기본적으로 `hello-nextflow` 디렉토리로 이동하면 됩니다. - -## 설치 확인 - -다음 명령어를 실행하여 `nextflow`가 올바르게 설치되었는지 확인합니다: - -```bash -nextflow info -``` - -해당 명령어를 실행하면 현재 버전, 시스템 정보, 런타임 정보가 출력됩니다. - -!!! question "연습 문제" - - 환경이 제대로 작동하는지 확인하려면 다음 명령어를 실행해 보세요: - - ```bash - nextflow info - ``` - - 실행 결과에는 다음과 같은 Nextflow 버전 및 런타임 정보가 출력됩니다 (실제 버전은 다를 수 있습니다): - - ```console - Version: 23.10.1 build 5891 - Created: 12-01-2024 22:01 UTC - System: Linux 6.1.75-060175-generic - Runtime: Groovy 3.0.19 on OpenJDK 64-Bit Server VM 11.0.1-internal+0-adhoc..src - Encoding: UTF-8 (UTF-8) - ``` diff --git a/docs/envsetup/02_local.pt.md b/docs/envsetup/02_local.pt.md deleted file mode 100644 index 6698532158..0000000000 --- a/docs/envsetup/02_local.pt.md +++ /dev/null @@ -1,90 +0,0 @@ -# Instalação local - -Se você **não conseguiu** acessar o Gitpod, uma alternativa é instalar tudo localmente. - -Alguns dos requisitos podem ser diferentes, a depender da sua máquina local. - -## Requisitos - -Nextflow pode ser utilizado em qualquer sistema compatível com o POSIX (Linux, macOS, Subsistema Linux para Windows, etc.). - -**Requisitos** - -- Bash -- [Java 11 (ou posterior, até o 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) -- [Git](https://git-scm.com/) -- [Docker](https://docs.docker.com/get-docker/) - -**Requisitos opcionais** - -- [Singularity](https://github.com/sylabs/singularity) 2.5.x (ou posterior) -- [Conda](https://conda.io/) 4.5 (ou posterior) -- [Graphviz](http://www.graphviz.org/) -- [AWS CLI](https://aws.amazon.com/cli/) -- Um ambiente computacional configurado no AWS Batch - -## Baixando Nextflow - -Execute esse comando em seu terminal: - -```bash -wget -qO- https://get.nextflow.io | bash -``` - -Você também pode usar o comando `curl`: - -```bash -curl -s https://get.nextflow.io | bash -``` - -Em seguida, garanta que o binário baixado é executável: - -```bash -chmod +x nextflow -``` - -Por fim, garanta que o executável do `nextflow` está na sua `$PATH`. O executável pode estar presente em `/usr/local/bin`, `/bin/`, etc. - -## Docker - -Garanta que o Docker Desktop está rodando em sua máquina. Você pode baixar o Docker [aqui](https://docs.docker.com/get-docker/). - -## Material de treinamento - -Você pode ver o material de treinamento [aqui](https://training.nextflow.io/). - -Para baixar o material, execute esse comando: - -```bash -git clone https://github.com/nextflow-io/training.git -``` - -Então use `cd` para entrar no diretório `nf-training`. - -## Verificando sua instalação - -Verifique que você instalou `nextflow` corretamente executando o seguinte comando: - -```bash -nextflow info -``` - -Esse comando deve imprimir a versão, o sistema e o ambiente de execução atuais. - -!!! question "Exercise" - - Para testar que seu ambiente está funcionando corretamente, execute o seguinte comando: - - ```bash - nextflow info - ``` - - Esse comando deve trazer informação sobre a versão do Nextflow e sobre seu ambiente de execução: - - ```console - Version: 23.10.1 build 5891 - Created: 12-01-2024 22:01 UTC - System: Linux 6.1.75-060175-generic - Runtime: Groovy 3.0.19 on OpenJDK 64-Bit Server VM 11.0.1-internal+0-adhoc..src - Encoding: UTF-8 (UTF-8) - ``` diff --git a/docs/envsetup/index.ko.md b/docs/envsetup/index.ko.md deleted file mode 100644 index c86c607886..0000000000 --- a/docs/envsetup/index.ko.md +++ /dev/null @@ -1,23 +0,0 @@ -# 환경 설정 - -Nextflow 커뮤니티 교육 포털에서 제공하는 교육 과정들은 GitHub Codespaces 환경에서 사용하기에 최적화되어 있습니다. - -GitHub Codespaces는 웹 브라우저 또는 코드 편집기(예: VSCode)에서 접근 가능한 가상 머신을 제공하며, 필요한 모든 것이 사전 구성되어 있어 바로 사용하실 수 있습니다. - -이미 GitHub Codespaces 계정을 가지고 계시다면 아래 버튼을 클릭하세요. 처음 설정하는 경우에는 이 모듈을 계속 진행하여 계정을 설정해 주세요. - -그럼 시작해볼까요? - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -GitHub Codespaces에 대한 더 자세한 설정 방법은 [GitHub Codespaces env-setup docs](01_setup.md)를 참고하세요. -GitHub Codespaces를 사용할 수 없고 로컬 개발 환경을 사용하고자 하시는 경우, [documentation for local installation](02_local.md)를 참고하세요. - -!!! info "Gitpod 사용 중단 안내" - - Nextflow 교육은 2025년 2월까지 [Gitpod](https://gitpod.io)를 사용해왔습니다. - 그러나 Gitpod 개발사에서는 기존의 무료 기능을 중단하고, 새로운[Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex) 시스템으로 전환하기로 결정했습니다. - 그러한 이유로,저희는 Gitpod과 유사하게 별도의 설정 없이 클릭 한 번으로 개발 환경을 사용할 수 있는 GitHub Codespaces를 도입하게 되었습니다. - - Gitpod 가입 시기와 서비스 종료 시점에 따라, 이전 클라우드 IDE를 통해 교육 환경을 실행할 수 있을 수도 있습니다. 다만, 앞으로는 안정적인 접근이 보장되지 않을 수 있습니다. - [Open in Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/envsetup/index.pt.md b/docs/envsetup/index.pt.md deleted file mode 100644 index 70fe6b5669..0000000000 --- a/docs/envsetup/index.pt.md +++ /dev/null @@ -1,11 +0,0 @@ -# Configuração do ambiente - -Os cursos de treinamento oferecidos no portal de treinamento da comunidade de Nextflow são otimizados para uso dentro do nosso ambiente Gitpod. - -O Gitpod oferece uma máquina virtual com tudo já configurado para seu uso, acessável através do seu navegador ou integrados com seu editor de texto (por exemplo, VSCode). - -Se você já possui uma conta no Gitpod, clique no botão abaixo, caso contrário, continue nesse módulo para configurar sua conta. - -Vamos começar! - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) diff --git a/docs/es/docs/envsetup/01_setup.md b/docs/es/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..b83c040b01 --- /dev/null +++ b/docs/es/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces es una plataforma basada en web que nos permite proporcionar un entorno preconfigurado para el entrenamiento, respaldado por máquinas virtuales en la nube. +La plataforma es operada por Github (que es propiedad de Microsoft), y es accesible de forma gratuita (con cuotas de uso) para cualquier persona con una cuenta de Github. + +!!! warning "Advertencia" + + Las cuentas adjuntas a organizaciones pueden estar sujetas a ciertas restricciones adicionales. + Si ese es su caso, es posible que necesite usar una cuenta personal independiente, o usar una instalación local en su lugar. + +## Crear una cuenta de GitHub + +Puede crear una cuenta gratuita de GitHub desde la [página principal de GitHub](https://github.com/). + +## Iniciar su GitHub Codespace + +Una vez que haya iniciado sesión en GitHub, abra este enlace en su navegador para abrir el entorno de entrenamiento de Nextflow: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Alternativamente, puede hacer clic en el botón que se muestra a continuación, que se repite en cada curso de entrenamiento (normalmente en la página de Orientación). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Debería ver una página donde puede crear un nuevo GitHub Codespace: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Configuración + +Para uso general, no debería necesitar configurar nada. +A menos que se especifique lo contrario en el curso que está comenzando, simplemente puede hacer clic en el botón principal para continuar. + +Sin embargo, es posible personalizar el entorno haciendo clic en el botón "Change options". + +??? info "Opciones de configuración" + + Si hace clic en el botón "Change options", tendrá la opción de personalizar lo siguiente: + + #### Branch + + Esto le permite seleccionar una versión diferente de los materiales de entrenamiento. + La rama `master` generalmente contiene correcciones de errores y materiales que han sido recientemente desarrollados y aprobados pero que aún no se han publicado en el sitio web. + Otras ramas contienen trabajo en progreso que puede no ser completamente funcional. + + #### Machine type + + Esto le permite personalizar la máquina virtual que usará para trabajar en el entrenamiento. + + Usar una máquina con más núcleos le permite aprovechar mejor la capacidad de Nextflow para paralelizar la ejecución del flujo de trabajo. + Sin embargo, consumirá su asignación de cuota gratuita más rápido, por lo que no recomendamos cambiar esta configuración a menos que se aconseje en las instrucciones del curso que planea tomar. + + Consulte 'Cuotas de GitHub Codespaces' a continuación para más detalles sobre las cuotas. + +### Tiempo de inicio + +Abrir un nuevo entorno de GitHub Codespaces por primera vez puede tomar varios minutos, porque el sistema tiene que configurar su máquina virtual, así que no se preocupe si hay un tiempo de espera. +Sin embargo, no debería tomar más de cinco minutos. + +## Navegar por la interfaz de entrenamiento + +Una vez que su GitHub Codespaces haya cargado, debería ver algo similar a lo siguiente (que puede abrirse en modo claro dependiendo de las preferencias de su cuenta): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +Esta es la interfaz del IDE VSCode, una aplicación popular de desarrollo de código que recomendamos usar para el desarrollo de Nextflow. + +- **El editor principal** es donde se abrirán el código de Nextflow y otros archivos de texto. Aquí es donde editará el código. Cuando abra el codespace, esto le mostrará una vista previa del archivo `README.md`. +- **El terminal** debajo del editor principal le permite ejecutar comandos. Aquí es donde ejecutará todas las líneas de comando dadas en las instrucciones del curso. +- **La barra lateral** le permite personalizar su entorno y realizar tareas básicas (copiar, pegar, abrir archivos, buscar, git, etc.). Por defecto está abierta en el explorador de archivos, que le permite navegar por los contenidos del repositorio. Hacer clic en un archivo en el explorador lo abrirá dentro de la ventana del editor principal. + +Puede ajustar las proporciones relativas de los paneles de ventana como desee. + +<!-- TODO (futuro) ¿Enlace al side quest de mejores prácticas de desarrollo? --> + +## Otras notas sobre el uso de GitHub Codespaces + +### Reanudar una sesión + +Una vez que haya creado un entorno, puede reanudarlo o reiniciarlo fácilmente y continuar desde donde lo dejó. +Su entorno expirará después de 30 minutos de inactividad y guardará sus cambios hasta por 2 semanas. + +Puede reabrir un entorno desde <https://github.com/codespaces/>. +Los entornos anteriores estarán listados. +Haga clic en una sesión para reanudarla. + +![List GitHub Codespace sessions](img/codespaces_list.png) + +Si ha guardado la URL de su entorno anterior de GitHub Codespaces, simplemente puede abrirla en su navegador. +Alternativamente, haga clic en el mismo botón que usó para crearlo en primer lugar: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Debería ver la sesión anterior, la opción predeterminada es reanudarla: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Guardar archivos en su máquina local + +Para guardar cualquier archivo desde el panel del explorador, haga clic derecho en el archivo y seleccione `Download`. + +### Gestionar cuotas de GitHub Codespaces + +GitHub Codespaces le da hasta 15 GB-mes de almacenamiento por mes, y 120 horas-núcleo por mes. +Esto equivale a aproximadamente 60 horas de tiempo de ejecución del entorno predeterminado usando el espacio de trabajo estándar (2 núcleos, 8 GB de RAM y 32 GB de almacenamiento). + +Puede crearlos con más recursos (vea la explicación anterior), pero esto consumirá su uso gratuito más rápido y tendrá menos horas de acceso a este espacio. +Por ejemplo, si selecciona una máquina de 4 núcleos en lugar de la predeterminada de 2 núcleos, su cuota se agotará en la mitad del tiempo. + +Opcionalmente, puede comprar acceso a más recursos. + +Para más información, consulte la documentación de GitHub: +[Acerca de la facturación de GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/es/docs/envsetup/02_local.md b/docs/es/docs/envsetup/02_local.md new file mode 100644 index 0000000000..3e3a5f05f1 --- /dev/null +++ b/docs/es/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Instalación manual + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Es posible instalar todo lo que necesita para ejecutar el entrenamiento en su propio entorno local manualmente. + +Aquí hemos documentado cómo hacerlo en sistemas estándar compatibles con POSIX (asumiendo una máquina personal como una laptop). +Tenga en cuenta que algunos detalles pueden ser diferentes dependiendo de su sistema específico. + +!!! tip "Consejo" + + Antes de continuar, ¿ha considerado usar el [enfoque de Devcontainers](03_devcontainer.md)? + Proporciona todas las herramientas y dependencias necesarias sin requerir instalación manual. + +## Requisitos generales de software + +Nextflow se puede usar en cualquier sistema compatible con POSIX (Linux, macOS, Windows Subsystem for Linux, etc.) con Java instalado. +Nuestros cursos de entrenamiento tienen algunos requisitos adicionales. + +En total, necesitará tener instalado el siguiente software: + +- Bash o shell equivalente +- [Java 11 (o posterior, hasta 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (o posterior) +- [VSCode](https://code.visualstudio.com) con la [extensión de Nextflow](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +La aplicación VSCode es técnicamente opcional pero recomendamos encarecidamente que la use para trabajar en los cursos así como para su trabajo de desarrollo de Nextflow en general. + +El manual de documentación de Nextflow proporciona instrucciones para instalar estas dependencias en [Configuración del entorno](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow y herramientas de nf-core + +Necesitará instalar Nextflow en sí, además de las herramientas de nf-core, como se detalla en los artículos enlazados a continuación: + +- [Instalación de Nextflow](https://www.nextflow.io/docs/latest/install.html) +- [Herramientas de nf-core](https://nf-co.re/docs/nf-core-tools/installation) + +Recomendamos usar la opción de autoinstalación para Nextflow y la opción de PyPI para las herramientas de nf-core. + +!!! warning "Compatibilidad de versiones" + + <!-- Cualquier actualización de este contenido debe copiarse a la página principal --> + **A partir de enero de 2026, todos nuestros cursos de entrenamiento de Nextflow requieren la versión 25.10.2 o posterior de Nextflow, con la sintaxis estricta v2 activada, a menos que se indique lo contrario.** + + Para más información sobre los requisitos de versión y la sintaxis estricta v2, consulte la guía de [versiones de Nextflow](../info/nxf_versions.md). + + Las versiones anteriores del material de entrenamiento correspondientes a la sintaxis anterior están disponibles a través del selector de versiones en la barra de menú de esta página web. + +## Materiales de entrenamiento + +La forma más fácil de descargar los materiales de entrenamiento es clonar todo el repositorio usando este comando: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Cada curso tiene su propio directorio. +Para trabajar en un curso, abra una ventana de terminal (idealmente, desde dentro de la aplicación VSCode) y use `cd` para entrar en el directorio relevante. + +Luego puede seguir las instrucciones del curso proporcionadas en el sitio web. diff --git a/docs/es/docs/envsetup/03_devcontainer.md b/docs/es/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..e3ad79ac02 --- /dev/null +++ b/docs/es/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Devcontainers locales + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Si tiene una instalación local de Docker o está dispuesto a instalar una, la forma más fácil de trabajar localmente con estos materiales es usar la función de devcontainer de Visual Studio Code. Este enfoque proporciona todas las herramientas y dependencias necesarias sin requerir instalación manual. + +## Requisitos + +Para usar la configuración de devcontainer local, necesitará: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Una instalación local de Docker, por ejemplo: + - [Docker Desktop](https://docs.docker.com/get-docker/) (para Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (para Linux) + - [Colima](https://github.com/abiosoft/colima) (alternativa para macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (incluido en Docker Desktop, pero puede necesitar instalación separada con otras configuraciones de Docker) +- [Extensión Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) para VS Code + +Su instalación de Docker debe estar ejecutándose antes de intentar abrir el devcontainer. + +Para verificar que Docker buildx está disponible, ejecute: + +```bash +docker buildx version +``` + +Si este comando falla, necesitará instalar la extensión buildx antes de continuar. + +## Instrucciones de configuración + +Siga estos pasos para configurar su entorno local usando devcontainers de VS Code: + +### Instalar la extensión "Dev Containers" en VS Code + +- Abra VS Code +- Vaya a Extensiones (Ctrl+Shift+X o Cmd+Shift+X en macOS) +- Busque "Dev Containers" +- Haga clic en "Install" + +![Installing Dev Containers extension in VS Code](img/install_extension.png) + +### Clonar el repositorio: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Abrir el repositorio en VS Code: + +- Inicie VS Code +- Seleccione **File -> Open Folder** desde el menú +- Navegue hasta y seleccione la carpeta del repositorio de entrenamiento que acaba de clonar +- Haga clic en **Open** + +### Reabrir en contenedor + +Si VS Code le solicita "Reopen in Container", haga clic en él. Alternativamente: + +- Presione F1 (o Ctrl+Shift+P / Cmd+Shift+P en macOS) +- Escriba "Dev Containers: Reopen in Container" +- **Importante**: Cuando se le solicite seleccionar una configuración, elija la configuración de devcontainer **local-dev** + +![Reopen in Container prompt](img/reopen_prompt.png) + +![Selecting local configuration](img/select_local_config.png) + +Espere a que se construya el contenedor. Esto puede tomar unos minutos la primera vez ya que descarga y configura todos los componentes necesarios. + +Una vez que el contenedor esté construido y ejecutándose, tendrá un entorno completamente configurado con todas las herramientas necesarias instaladas, incluyendo: + +- Java +- Nextflow +- Docker +- Git +- Y todas las demás dependencias requeridas para el entrenamiento + +![VS Code with devcontainer running](img/running_container.png) + +## Beneficios de usar Devcontainers + +Usar el enfoque de devcontainer ofrece varias ventajas: + +- **Consistencia**: Asegura un entorno de desarrollo consistente en diferentes máquinas +- **Simplicidad**: Todas las dependencias están preinstaladas y configuradas +- **Aislamiento**: El entorno de desarrollo está aislado de su sistema local +- **Reproducibilidad**: Todos los que usan el devcontainer obtienen la misma configuración +- **Sin instalación manual**: No es necesario instalar manualmente Java, Nextflow y otras herramientas + +## Verificar su entorno + +Una vez que su devcontainer esté ejecutándose, puede verificar que todo esté configurado correctamente ejecutando: + +```bash +nextflow info +``` + +Esto debería mostrar la versión de Nextflow e información de tiempo de ejecución, confirmando que su entorno está correctamente configurado. + +## Solución de problemas + +Si encuentra problemas con la configuración del devcontainer: + +1. Asegúrese de que su instalación de Docker (Docker Desktop, Colima, Docker Engine, etc.) esté ejecutándose antes de abrir el devcontainer +2. Verifique que haya seleccionado la configuración **local-dev** cuando se le solicitó +3. Verifique que Docker buildx esté instalado y funcionando ejecutando `docker buildx version` +4. Si el contenedor no se construye, intente reconstruirlo ejecutando el comando "Dev Containers: Rebuild Container" +5. Para problemas persistentes, consulte la [guía de solución de problemas de VS Code Dev Containers](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/es/docs/envsetup/index.md b/docs/es/docs/envsetup/index.md new file mode 100644 index 0000000000..44c079087f --- /dev/null +++ b/docs/es/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Opciones de entorno +description: Opciones para configurar su entorno para los entrenamientos de Nextflow +hide: + - toc + - footer +--- + +# Opciones de entorno + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nuestro objetivo es proporcionar un entorno consistente y exhaustivamente probado que permita a los estudiantes concentrarse en aprender Nextflow sin tener que dedicar tiempo y esfuerzo a gestionar software. +Para ese fin, hemos desarrollado un entorno en contenedor que contiene todo el software necesario, archivos de código y datos de ejemplo para trabajar con todos nuestros cursos. + +Este entorno en contenedor puede ejecutarse directamente en Github Codespaces o localmente en VS Code con la extensión Devcontainers. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **Github Codespaces** + + *** + + GitHub Codespaces es un servicio basado en web que nos permite proporcionar un entorno preconstruido para el entrenamiento, con todas las herramientas y datos incluidos, respaldado por máquinas virtuales en la nube. Es accesible de forma gratuita para cualquier persona con una cuenta de Github. + + [Usar Github Codespaces:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Devcontainers locales** + + *** + + VS Code con Devcontainers proporciona un entorno de desarrollo en contenedor ejecutado localmente con todas las herramientas de entrenamiento preconfiguradas. Ofrece el mismo entorno preconstruido que Codespaces pero ejecutándose completamente en su hardware local. + + [Usar Devcontainers localmente :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Instrucciones para instalación manual + +Si ninguna de las opciones anteriores se adapta a sus necesidades, puede replicar este entorno en su propio sistema local instalando las dependencias de software manualmente y clonando el repositorio de entrenamiento. + +[Instalación manual :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Obsolescencia de Gitpod" + + El entrenamiento de Nextflow solía usar [Gitpod](https://gitpod.io) hasta febrero de 2025. + Sin embargo, los creadores de Gitpod decidieron retirar la funcionalidad gratuita en favor del sistema [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex). + Por esa razón, cambiamos a usar GitHub Codespaces, que también ofrece un entorno de desarrollo con un solo clic sin configuración previa. + + Dependiendo de cuándo se registró en Gitpod y cuándo exactamente retiren el servicio, es posible que aún pueda iniciar el entrenamiento en su antiguo IDE en la nube, aunque no podemos garantizar un acceso confiable en el futuro: + [Abrir en Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/es/docs/hello_nextflow/00_orientation.md b/docs/es/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..bc72937ee2 --- /dev/null +++ b/docs/es/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Comenzando + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/00_orientation.md). +/// + +!!! tip "Consejo" + + ¡Los videos de YouTube tienen algunas funciones especiales! + + - :fontawesome-solid-closed-captioning: Subtítulos de alta calidad (curados manualmente). Actívelos con el ícono :material-subtitles: + - :material-bookmark: Capítulos de video en la línea de tiempo que corresponden a los encabezados de la página. + +## Iniciar un entorno de entrenamiento + +Para usar el entorno preconstruido que proporcionamos en GitHub Codespaces, haga clic en el botón "Open in GitHub Codespaces" a continuación. Para otras opciones, consulte [Opciones de entorno](../envsetup/index.md). + +Recomendamos abrir el entorno de entrenamiento en una nueva pestaña o ventana del navegador (use clic derecho, ctrl-clic o cmd-clic dependiendo de su equipo) para que pueda seguir leyendo mientras el entorno carga. +Necesitará mantener estas instrucciones abiertas en paralelo para trabajar en el curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Conceptos básicos del entorno + +Este entorno de entrenamiento contiene todo el software, código y datos necesarios para trabajar en el curso de entrenamiento, por lo que no necesita instalar nada usted mismo. + +El codespace está configurado con una interfaz de VSCode, que incluye un explorador de sistema de archivos, un editor de código y una terminal. +Todas las instrucciones dadas durante el curso (por ejemplo, 'abra el archivo', 'edite el código' o 'ejecute este comando') se refieren a esas tres partes de la interfaz de VSCode a menos que se especifique lo contrario. + +Si está trabajando en este curso por su cuenta, familiarícese con los [conceptos básicos del entorno](../envsetup/01_setup.md) para más detalles. + +### Requisitos de versión + +Este entrenamiento está diseñado para Nextflow 25.10.2 o posterior **con el analizador de sintaxis v2 HABILITADO**. +Si está usando un entorno local o personalizado, asegúrese de estar usando la configuración correcta como se documenta [aquí](../info/nxf_versions.md). + +## Prepárese para trabajar + +Una vez que su codespace esté ejecutándose, hay dos cosas que debe hacer antes de sumergirse en el entrenamiento: establecer su directorio de trabajo para este curso específico, y echar un vistazo a los materiales proporcionados. + +### Establecer el directorio de trabajo + +Por defecto, el codespace se abre con el directorio de trabajo establecido en la raíz de todos los cursos de entrenamiento, pero para este curso, trabajaremos en el directorio `hello-nextflow/`. + +Cambie de directorio ahora ejecutando este comando en el terminal: + +```bash +cd hello-nextflow/ +``` + +Puede configurar VSCode para enfocarse en este directorio, de modo que solo los archivos relevantes se muestren en la barra lateral del explorador de archivos: + +```bash +code . +``` + +!!! tip "Consejo" + + Si por cualquier razón sale de este directorio (por ejemplo, su codespace se suspende), siempre puede usar la ruta completa para volver a él, asumiendo que está ejecutando esto dentro del entorno de entrenamiento de Github Codespaces: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Ahora echemos un vistazo a los contenidos. + +### Explorar los materiales proporcionados + +Puede explorar los contenidos de este directorio usando el explorador de archivos en el lado izquierdo del espacio de trabajo de entrenamiento. +Alternativamente, puede usar el comando `tree`. + +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenidos del directorio de forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 2 +``` + +??? abstract "Contenidos del directorio" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Haga clic en el cuadro coloreado para expandir la sección y ver sus contenidos. +Usamos secciones colapsables como esta para incluir la salida esperada de comandos de forma concisa. + +- **Los archivos `.nf`** son scripts de flujo de trabajo que se nombran según la parte del curso en la que se usan. + +- **El archivo `nextflow.config`** es un archivo de configuración que establece propiedades mínimas del entorno. + Puede ignorarlo por ahora. + +- **El archivo `greetings.csv`** bajo `data/` contiene datos de entrada que usaremos en la mayor parte del curso. Se describe en la Parte 2 (Channels), cuando lo introducimos por primera vez. + +- **Los archivos `test-params.*`** son archivos de configuración que usaremos en la Parte 6 (Configuration). Puede ignorarlos por ahora. + +- **El directorio `solutions`** contiene los scripts de flujo de trabajo completados que resultan de cada paso del curso. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + +## Lista de verificación de preparación + +¿Cree que está listo para sumergirse? + +- [ ] Entiendo el objetivo de este curso y sus prerrequisitos +- [ ] Mi entorno está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente + +Si puede marcar todas las casillas, está listo para continuar. + +**Para continuar a [Parte 1: Hello World](./01_hello_world.md), haga clic en la flecha en la esquina inferior derecha de esta página.** diff --git a/docs/es/docs/hello_nextflow/01_hello_world.md b/docs/es/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..f00113122f --- /dev/null +++ b/docs/es/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Parte 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/01_hello_world.md). +/// + +En esta primera parte del curso de entrenamiento Hello Nextflow, nos introducimos al tema con un ejemplo muy básico de Hello World independiente del dominio, que iremos construyendo progresivamente para demostrar el uso de la lógica y componentes fundamentales de Nextflow. + +??? info "¿Qué es un ejemplo Hello World?" + + Un "Hello World!" es un ejemplo minimalista destinado a demostrar la sintaxis básica y la estructura de un lenguaje de programación o framework de software. + El ejemplo típicamente consiste en imprimir la frase "Hello, World!" al dispositivo de salida, como la consola o terminal, o escribirla en un archivo. + +--- + +## 0. Calentamiento: Ejecutar un ejemplo Hello World directamente + +Demostremos esto con un comando simple que ejecutamos directamente en el terminal, para mostrar lo que hace antes de envolverlo en Nextflow. + +!!! tip "Consejo" + + Recuerde que ahora debería estar dentro del directorio `hello-nextflow/` como se describe en la página de [Comenzando](00_orientation.md). + +### 0.1. Hacer que el terminal diga hola + +Ejecute el siguiente comando en su terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Salida del comando" + + ```console + Hello World! + ``` + +Esto muestra el texto 'Hello World' directamente en el terminal. + +### 0.2. Escribir la salida a un archivo + +Ejecutar pipelines principalmente implica leer datos de archivos y escribir resultados en otros archivos, así que modifiquemos el comando para escribir la salida de texto en un archivo para hacer el ejemplo un poco más relevante. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Salida del comando" + + ```console + + ``` + +Esto no muestra nada en el terminal. + +### 0.3. Encontrar la salida + +El texto 'Hello World' ahora debería estar en el archivo de salida que especificamos, llamado `output.txt`. +Puede abrirlo en el explorador de archivos o desde la línea de comandos usando la utilidad `cat`, por ejemplo. + +??? abstract "Contenido del archivo" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Esto es lo que vamos a intentar replicar con nuestro primer flujo de trabajo de Nextflow. + +### Conclusión + +Ahora sabe cómo ejecutar un comando simple en el terminal que produce algún texto, y opcionalmente, cómo hacer que escriba la salida en un archivo. + +### ¿Qué sigue? + +Descubra cómo se vería esto escrito como un flujo de trabajo de Nextflow. + +--- + +## 1. Examinar el script y ejecutarlo + +Le proporcionamos un script de flujo de trabajo completamente funcional, aunque minimalista, llamado `hello-world.nf` que hace lo mismo que antes (escribir 'Hello World!') pero con Nextflow. + +Para comenzar, abramos el script del flujo de trabajo para que pueda tener una idea de cómo está estructurado. +Luego lo ejecutaremos y buscaremos sus salidas. + +### 1.1. Examinar el código + +Encontrará el script `hello-world.nf` en su directorio actual, que debería ser `hello-nextflow`. Ábralo en el panel del editor. + +??? full-code "Archivo de código completo" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usar echo para imprimir 'Hello World!' a un archivo + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // emitir un saludo + sayHello() + } + ``` + +Un script de flujo de trabajo de Nextflow típicamente incluye una o más definiciones de **process** y el **workflow** en sí, además de algunos bloques opcionales (no presentes aquí) que introduciremos más adelante. + +Cada **process** describe qué operación(es) debe realizar el paso correspondiente en el pipeline, mientras que el **workflow** describe la lógica de flujo de datos que conecta los diversos pasos. + +Vamos a examinar más de cerca el bloque **process** primero, luego veremos el bloque **workflow**. + +#### 1.1.1. La definición de `process` + +El primer bloque de código describe un **process**. + +La definición del proceso comienza con la palabra clave `process`, seguida del nombre del proceso y finalmente el cuerpo del proceso delimitado por llaves. +El cuerpo del proceso debe contener un bloque script que especifica el comando a ejecutar, que puede ser cualquier cosa que podría ejecutar en una terminal de línea de comandos. + +```groovy title="hello-world.nf" linenums="3" +/* +* Usar echo para imprimir 'Hello World!' a un archivo +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Aquí tenemos un **process** llamado `sayHello` que escribe su **output** en un archivo llamado `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +Esta es una definición de proceso muy mínima que solo contiene una definición de `output` y el `script` a ejecutar. + +La definición de `output` incluye el calificador `path`, que le dice a Nextflow que esto debe manejarse como una ruta (incluye tanto rutas de directorio como archivos). +Otro calificador común es `val`. + +Importante: la definición de salida no _determina_ qué salida se creará. +Simplemente _declara_ cuál es la salida esperada, para que Nextflow pueda buscarla una vez que la ejecución esté completa. +Esto es necesario para verificar que el comando se ejecutó correctamente y para pasar la salida a procesos posteriores si es necesario. La salida producida que no coincida con lo declarado en el bloque de salida no se pasará a procesos posteriores. + +!!! warning "Advertencia" + + Este ejemplo es frágil porque codificamos el nombre del archivo de salida en dos lugares separados (los bloques script y output). + Si cambiamos uno pero no el otro, el script fallará. + Más adelante, aprenderá formas de usar variables para mitigar este problema. + +En un pipeline del mundo real, un proceso generalmente contiene bloques adicionales como directivas y entradas, que introduciremos en breve. + +#### 1.1.2. La definición de `workflow` + +El segundo bloque de código describe el **workflow** en sí. +La definición del flujo de trabajo comienza con la palabra clave `workflow`, seguida de un nombre opcional, luego el cuerpo del flujo de trabajo delimitado por llaves. + +Aquí tenemos un **workflow** que consiste en un bloque `main:` (que dice 'este es el cuerpo principal del flujo de trabajo') que contiene una llamada al proceso `sayHello`. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // emitir un saludo + sayHello() +} +``` + +Esta es una definición de **workflow** muy mínima. +En un pipeline del mundo real, el flujo de trabajo típicamente contiene múltiples llamadas a **processes** conectados por **channels**, y los procesos esperan una o más **input(s)** variables. + +Aprenderá cómo agregar entradas variables más adelante en este módulo de entrenamiento; y aprenderá cómo agregar más procesos y conectarlos mediante canales en la Parte 3 de este curso. + +!!! tip "Consejo" + + Técnicamente, la línea `main:` no es requerida para flujos de trabajo simples como este, por lo que puede encontrar flujos de trabajo que no la tienen. + Pero la necesitaremos para aprovechar las salidas a nivel de flujo de trabajo, así que es mejor incluirla desde el principio. + +### 1.2. Ejecutar el flujo de trabajo + +Mirar código no es ni de lejos tan divertido como ejecutarlo, así que probemos esto en la práctica. + +#### 1.2.1. Iniciar el flujo de trabajo y monitorear la ejecución + +En el terminal, ejecute el siguiente comando: + +```bash +nextflow run hello-world.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Si la salida de su consola se parece a eso, ¡felicitaciones, acaba de ejecutar su primer flujo de trabajo de Nextflow! + +La salida más importante aquí es la última línea, que está resaltada en la salida anterior: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Esto nos dice que el proceso `sayHello` se ejecutó exitosamente una vez (`1 of 1 ✔`). + +Importante: esta línea también le dice dónde encontrar la salida de la llamada al proceso `sayHello`. +Veamos eso ahora. + +#### 1.2.2. Encontrar la salida y los logs en el directorio `work` + +Cuando ejecuta Nextflow por primera vez en un directorio dado, crea un directorio llamado `work` donde escribirá todos los archivos (y cualquier enlace simbólico) generados en el curso de la ejecución. + +Dentro del directorio `work`, Nextflow organiza las salidas y logs por llamada de proceso. +Para cada llamada de proceso, Nextflow crea un subdirectorio anidado, nombrado con un hash para hacerlo único, donde preparará todas las entradas necesarias (usando enlaces simbólicos por defecto), escribirá archivos auxiliares, y escribirá logs y cualquier salida del proceso. + +La ruta a ese subdirectorio se muestra en forma truncada entre corchetes en la salida de la consola. +Mirando lo que obtuvimos para la ejecución mostrada arriba, la línea de log de la consola para el proceso sayHello comienza con `[65/7be2fa]`. Eso corresponde a la siguiente ruta de directorio: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +Veamos qué hay ahí. + +??? abstract "Contenido del directorio" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "¿No ve lo mismo?" + + Los nombres exactos de los subdirectorios serán diferentes en su sistema. + + Si navega por los contenidos del subdirectorio de tarea en el explorador de archivos de VSCode, verá todos los archivos de inmediato. + Sin embargo, los archivos de log están configurados para ser invisibles en el terminal, así que si quiere usar `ls` o `tree` para verlos, necesitará establecer la opción relevante para mostrar archivos invisibles. + + ```bash + tree -a work + ``` + +Lo primero que quiere ver es la salida real del flujo de trabajo, es decir, el archivo `output.txt` producido por el proceso `sayHello`. +Ábralo y encontrará el saludo `Hello World!`, que era el objetivo de nuestro flujo de trabajo minimalista. + +??? abstract "Contenido del archivo" + + ```console title="output.txt" + Hello World! + ``` + +¡Funcionó! + +Es cierto que puede parecer mucho código envolvente para un resultado tan pequeño, pero el valor de todo ese código envolvente se volverá más obvio una vez que empecemos a leer archivos de entrada y encadenar múltiples pasos. + +Dicho esto, también veamos los otros archivos en ese directorio. Esos son archivos auxiliares y de log producidos por Nextflow como parte de la ejecución de la tarea. + +- **`.command.begin`**: Metadatos relacionados con el inicio de la ejecución de la llamada al proceso +- **`.command.err`**: Mensajes de error (`stderr`) emitidos por la llamada al proceso +- **`.command.log`**: Salida de log completa emitida por la llamada al proceso +- **`.command.out`**: Salida regular (`stdout`) de la llamada al proceso +- **`.command.run`**: Script completo ejecutado por Nextflow para ejecutar la llamada al proceso +- **`.command.sh`**: El comando que fue realmente ejecutado por la llamada al proceso +- **`.exitcode`**: El código de salida resultante del comando + +El archivo `.command.sh` es especialmente útil porque le dice el comando principal que Nextflow ejecutó, sin incluir toda la contabilidad y configuración de tarea/entorno. + +??? abstract "Contenido del archivo" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Esto coincide con lo que ejecutamos manualmente antes. + +En este caso es muy directo porque el comando del proceso estaba codificado de forma fija, pero más adelante en el curso verá comandos de proceso que involucran cierta interpolación de variables. +Eso hace especialmente valioso poder ver exactamente cómo Nextflow interpretó el código y qué comando se produjo cuando está solucionando problemas de una ejecución fallida. + +### 1.3. Ejecutar el flujo de trabajo de nuevo + +Intente volver a ejecutar el flujo de trabajo varias veces, luego mire los directorios de tareas bajo `work/`. + +??? abstract "Contenido del directorio" + + ```console + 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 + ``` + +Ve que se ha creado un nuevo subdirectorio con un conjunto completo de archivos de salida y log para cada ejecución. +Esto le muestra que ejecutar el mismo flujo de trabajo varias veces no sobrescribirá los resultados de ejecuciones anteriores. + +### Conclusión + +Sabe cómo descifrar un script simple de Nextflow, ejecutarlo y encontrar la salida y los archivos de log relevantes en el directorio de trabajo. + +### ¿Qué sigue? + +Aprenda a publicar las salidas del flujo de trabajo en una ubicación más conveniente. + +--- + +## 2. Publicar salidas + +Como acaba de aprender, la salida producida por nuestro pipeline está enterrada en un directorio de trabajo varios niveles de profundidad. +Esto se hace a propósito; Nextflow tiene el control de este directorio y no debemos interactuar con él. +Sin embargo, eso hace inconveniente recuperar las salidas que nos importan. + +Afortunadamente, Nextflow proporciona una forma de publicar salidas en un directorio designado usando [definiciones de salida a nivel de flujo de trabajo](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs). + +### 2.1. Uso básico + +Esto va a involucrar dos nuevas piezas de código: + +1. Un bloque `publish:` dentro del cuerpo del `workflow`, declarando las salidas del proceso. +2. Un bloque `output` en el script especificando opciones de salida como modo y ubicación. + +#### 2.1.1. Declarar la salida del proceso `sayHello` + +Necesitamos agregar un bloque `publish:` al cuerpo del flujo de trabajo (el mismo tipo de elemento de código que el bloque `main:`) y listar la salida del proceso `sayHello()`. + +En el archivo de script del flujo de trabajo `hello-world.nf`, agregue las siguientes líneas de código: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // emitir un saludo + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emitir un saludo + sayHello() + } + ``` + +Ve que podemos referirnos a la salida del proceso simplemente haciendo `sayHello().out`, y asignarle un nombre arbitrario, `first_output`. + +#### 2.1.2. Agregar un bloque `output:` al script + +Ahora solo necesitamos agregar el bloque `output:` donde se especificará la ruta del directorio de salida. Note que este nuevo bloque se ubica **fuera** y **debajo** del bloque `workflow` dentro del script. + +En el archivo de script del flujo de trabajo `hello-world.nf`, agregue las siguientes líneas de código: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // emitir un saludo + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emitir un saludo + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Podemos usar esto para asignar rutas específicas a cualquier salida de proceso declarada en el bloque `workflow`. +Más adelante, aprenderá sobre formas de generar estructuras de directorio de salida sofisticadas, pero por ahora, simplemente estamos codificando una ruta mínima para simplificar. + +#### 2.1.3. Ejecutar el flujo de trabajo + +Ahora ejecute el script de flujo de trabajo modificado: + +```bash +nextflow run hello-world.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +La salida del terminal debería parecer familiar. Externamente, nada ha cambiado. + +Sin embargo, revise su explorador de archivos: esta vez, Nextflow ha creado un nuevo directorio llamado `results/`. + +??? abstract "Contenido del directorio" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +Dentro del directorio `results`, encontramos un enlace simbólico al `output.txt` producido en el directorio de trabajo por el comando que acabamos de ejecutar. + +Esto nos permite recuperar fácilmente los archivos de salida sin tener que buscar en el subdirectorio de trabajo. + +### 2.2. Establecer una ubicación personalizada + +Tener una ubicación predeterminada es genial, pero puede querer personalizar dónde se guardan los resultados y cómo se organizan. + +Por ejemplo, puede querer organizar sus salidas en subdirectorios. +La forma más simple de hacer eso es asignar una ruta de salida específica por salida. + +#### 2.2.1. Modificar la ruta de salida + +Una vez más, modificar el comportamiento de publicación para una salida específica es realmente sencillo. +Para establecer una ubicación personalizada, simplemente edite el `path` de acuerdo: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Como esto se establece a nivel de la salida individual, puede especificar diferentes ubicaciones y subdirectorios para adaptarse a sus necesidades. + +#### 2.2.2. Ejecutar el flujo de trabajo de nuevo + +Probémoslo. + +```bash +nextflow run hello-world.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Esta vez el resultado se escribe bajo el subdirectorio especificado. + +??? abstract "Contenido del directorio" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Ve que el resultado de la ejecución anterior todavía está ahí. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +Puede usar tantos niveles de anidamiento como desee. +También es posible usar el nombre del proceso u otras variables para nombrar los directorios usados para organizar los resultados, y es posible cambiar el nombre predeterminado del directorio de salida de nivel superior (que es controlado por la variable especial `outputDir`). +Cubriremos estas opciones en entrenamientos posteriores. + +### 2.3. Establecer el modo de publicación a copia + +Por defecto, las salidas se publican como enlaces simbólicos desde el directorio `work`. +Eso significa que solo hay un único archivo en el sistema de archivos. + +Esto es genial cuando está tratando con archivos muy grandes, para los cuales no quiere almacenar múltiples copias. +Sin embargo, si elimina el directorio de trabajo en algún momento (cubriremos las operaciones de limpieza en breve), perderá acceso al archivo. +Así que necesita tener un plan para guardar copias de cualquier archivo importante en un lugar seguro. + +Una opción fácil es cambiar el modo de publicación a copia para las salidas que le importan. + +#### 2.3.1. Agregar la directiva de modo + +Esta parte es realmente sencilla. +Simplemente agregue `mode 'copy'` a la definición de salida a nivel de flujo de trabajo relevante: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Esto establece el modo de publicación para esa salida específica. + +#### 2.3.2. Ejecutar el flujo de trabajo de nuevo + +Probémoslo. + +```bash +nextflow run hello-world.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Esta vez, si mira los resultados, el archivo es una copia real en lugar de solo un enlace simbólico. + +??? abstract "Contenido del directorio" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Como esto también se establece a nivel de la salida individual, le permite establecer el modo de publicación de manera granular. +Esto será especialmente útil más adelante cuando pasemos a pipelines de múltiples pasos, donde puede querer solo copiar las salidas finales y dejar las salidas intermedias como enlaces simbólicos, por ejemplo. + +Como se señaló antes, hay otras opciones más sofisticadas para controlar cómo se publican las salidas. +Le mostraremos cómo usarlas a su debido tiempo en su viaje con Nextflow. + +### 2.4. Nota sobre directivas `publishDir` a nivel de proceso + +Hasta hace muy poco, la forma establecida de publicar salidas era hacerlo a nivel de cada proceso individual usando una directiva `publishDir`. + +Para lograr lo que acabamos de hacer para las salidas del proceso `sayHello`, habríamos agregado la siguiente línea a la definición del proceso: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Todavía encontrará este patrón de código en todos los pipelines más antiguos de Nextflow y módulos de proceso, por lo que es importante estar al tanto de él. +Sin embargo, no recomendamos usarlo en ningún trabajo nuevo ya que eventualmente se deshabilitará en futuras versiones del lenguaje Nextflow. + +### Conclusión + +Sabe cómo publicar salidas del flujo de trabajo en una ubicación más conveniente. + +### ¿Qué sigue? + +Aprenda a proporcionar una entrada variable a través de un parámetro de línea de comandos y utilizar valores predeterminados de manera efectiva. + +--- + +## 3. Usar una entrada variable pasada en la línea de comandos + +En su estado actual, nuestro flujo de trabajo usa un saludo codificado en el comando del proceso. +Queremos agregar algo de flexibilidad usando una variable de entrada, para poder cambiar más fácilmente el saludo en tiempo de ejecución. + +Esto requiere que hagamos tres conjuntos de cambios en nuestro script: + +1. Cambiar el proceso para esperar una entrada variable +2. Configurar un parámetro de línea de comandos para capturar la entrada del usuario +3. Pasar la entrada al proceso en el cuerpo del flujo de trabajo + +Hagamos estos cambios uno a la vez. + +### 3.1. Cambiar el proceso `sayHello` para esperar una entrada variable + +Necesitamos editar la definición del proceso para (1) aceptar una variable de entrada y (2) usar esa variable en la línea de comandos. + +#### 3.1.1. Agregar un bloque de entrada a la definición del proceso + +Primero, adaptemos la definición del proceso para aceptar una entrada llamada `greeting`. + +En el bloque del proceso, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +La variable `greeting` está prefijada con `val` para decirle a Nextflow que es un valor (no una ruta). + +#### 3.1.2. Editar el comando del proceso para usar la variable de entrada + +Ahora intercambiamos el valor original codificado por el valor de la variable de entrada que esperamos recibir. + +En el bloque del proceso, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +El símbolo `$` y las llaves (`{ }`) le dicen a Nextflow que este es un nombre de variable que necesita ser reemplazado con el valor de entrada real (=interpolado). + +!!! tip "Consejo" + + Las llaves (`{ }`) eran técnicamente opcionales en versiones anteriores de Nextflow, así que puede ver flujos de trabajo más antiguos donde esto está escrito como `echo '$greeting' > output.txt`. + +Ahora que el proceso `sayHello()` está listo para aceptar una entrada variable, necesitamos una forma de proporcionar un valor de entrada a la llamada del proceso a nivel de flujo de trabajo. + +### 3.2. Configurar un parámetro de línea de comandos para capturar la entrada del usuario + +Podríamos simplemente codificar una entrada directamente haciendo la llamada al proceso `sayHello('Hello World!')`. +Sin embargo, cuando estamos haciendo trabajo real con nuestro flujo de trabajo, querremos poder controlar sus entradas desde la línea de comandos. + +Buenas noticias: Nextflow tiene un sistema de parámetros de flujo de trabajo incorporado llamado `params`, que facilita declarar y usar parámetros CLI. + +La sintaxis general es declarar `params.<nombre_parametro>` para decirle a Nextflow que espere un parámetro `--<nombre_parametro>` en la línea de comandos. + +Aquí, queremos crear un parámetro llamado `--input`, así que necesitamos declarar `params.input` en algún lugar del flujo de trabajo. +En principio podemos escribirlo en cualquier lugar; pero como vamos a querer dárselo a la llamada del proceso `sayHello()`, podemos conectarlo directamente escribiendo `sayHello(params.input)`. + +En el bloque del flujo de trabajo, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emitir un saludo + sayHello(params.input) + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emitir un saludo + sayHello() + ``` + +Esto le dice a Nextflow que ejecute el proceso `sayHello` con el valor proporcionado a través del parámetro `--input`. + +En efecto, hemos logrado los pasos (2) y (3) descritos al inicio de la sección de una sola vez. + +### 3.3. Ejecutar el comando del flujo de trabajo + +¡Ejecutémoslo! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Si hizo todas estas ediciones correctamente, debería obtener otra ejecución exitosa. + +Asegúrese de abrir el archivo de salida para verificar que ahora tiene la nueva versión del saludo. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +¡Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Note cómo la nueva ejecución ha sobrescrito el archivo de salida publicado en el directorio `results`. +Sin embargo, los resultados de las ejecuciones anteriores todavía se conservan en los directorios de tareas bajo `work`. + +!!! tip "Consejo" + + Puede distinguir fácilmente los parámetros a nivel de Nextflow de los parámetros a nivel de pipeline. + + - Los parámetros que se aplican a un pipeline siempre llevan un doble guión (`--`). + - Los parámetros que modifican una configuración de Nextflow, _por ejemplo_ la función `-resume` que usamos antes, llevan un solo guión (`-`). + +### 3.4. Usar valores predeterminados para parámetros de línea de comandos + +Ok, eso fue conveniente, pero en muchos casos, tiene sentido proporcionar un valor predeterminado para un parámetro dado para no tener que especificarlo en cada ejecución. + +#### 3.4.1. Establecer un valor predeterminado para el parámetro CLI + +Démosle al parámetro `input` un valor predeterminado declarándolo antes de la definición del flujo de trabajo. + +```groovy title="hello-world.nf" linenums="20" +/* + * Parámetros del pipeline + */ +params { + input: String = 'Holà mundo!' +} +``` + +Como ve, podemos especificar el tipo de entrada que el flujo de trabajo espera (Nextflow 25.10.2 y posterior). +La sintaxis es `nombre: Tipo = valor_predeterminado`. +Los tipos soportados incluyen `String`, `Integer`, `Float`, `Boolean` y `Path`. + +!!! info "Información" + + En flujos de trabajo más antiguos, puede ver todo ese bloque `params` escrito simplemente como `input = 'Holà mundo!'`. + +A medida que agregue más parámetros a su pipeline, debería agregarlos todos a este bloque, ya sea que necesite o no darles un valor predeterminado. +Esto facilitará encontrar todos los parámetros configurables de un vistazo. + +#### 3.4.2. Ejecutar el flujo de trabajo de nuevo sin especificar el parámetro + +Ahora que tiene un valor predeterminado establecido, puede ejecutar el flujo de trabajo de nuevo sin tener que especificar un valor en la línea de comandos. + +```bash +nextflow run hello-world.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +La salida estará en el mismo lugar que antes, pero los contenidos deberían actualizarse con el nuevo texto. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow usó el valor predeterminado del parámetro greeting para crear la salida. + +#### 3.4.3. Sobrescribir el valor predeterminado + +Si proporciona el parámetro en la línea de comandos, el valor CLI sobrescribirá el valor predeterminado. + +Pruébelo: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Una vez más, debería encontrar la salida actualizada correspondiente en su directorio de resultados. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Nota" + + En Nextflow, hay múltiples lugares donde puede especificar valores para parámetros. + Si el mismo parámetro se establece con diferentes valores en múltiples lugares, Nextflow determinará qué valor usar basándose en el orden de precedencia que se describe [aquí](https://www.nextflow.io/docs/latest/config.html). + + Cubriremos esto en más detalle en la Parte 6 (Configuration). + +### Conclusión + +Sabe cómo usar una entrada variable simple proporcionada en tiempo de ejecución a través de un parámetro de línea de comandos, así como configurar, usar y sobrescribir valores predeterminados. + +### ¿Qué sigue? + +Aprenda a gestionar ejecuciones de manera más conveniente. + +--- + +## 4. Gestionar ejecuciones del flujo de trabajo + +Saber cómo iniciar flujos de trabajo y recuperar salidas es genial, pero encontrará rápidamente que hay algunos otros aspectos de la gestión de flujos de trabajo que harán su vida más fácil, especialmente si está desarrollando sus propios flujos de trabajo. + +Aquí le mostramos cómo usar la función `resume` cuando necesita volver a iniciar el mismo flujo de trabajo, cómo inspeccionar el log de ejecuciones pasadas con `nextflow log`, y cómo eliminar directorios de trabajo antiguos con `nextflow clean`. + +<!-- ¿Alguna otra opción interesante que deberíamos incluir? Se agregó log --> + +### 4.1. Volver a iniciar un flujo de trabajo con `-resume` + +A veces, querrá volver a ejecutar un pipeline que ya ha iniciado previamente sin rehacer ningún paso que ya se completó exitosamente. + +Nextflow tiene una opción llamada `-resume` que le permite hacer esto. +Específicamente, en este modo, cualquier proceso que ya se haya ejecutado con exactamente el mismo código, configuración y entradas se omitirá. +Esto significa que Nextflow solo ejecutará procesos que haya agregado o modificado desde la última ejecución, o a los cuales está proporcionando nuevas configuraciones o entradas. + +Hay dos ventajas clave de hacer esto: + +- Si está en medio del desarrollo de su pipeline, puede iterar más rápidamente ya que solo tiene que ejecutar el(los) proceso(s) en los que está trabajando activamente para probar sus cambios. +- Si está ejecutando un pipeline en producción y algo sale mal, en muchos casos puede solucionar el problema y volver a iniciar el pipeline, y reanudará la ejecución desde el punto de fallo, lo que puede ahorrarle mucho tiempo y cómputo. + +Para usarlo, simplemente agregue `-resume` a su comando y ejecútelo: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Salida del comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +La salida de la consola debería parecer familiar, pero hay algo que es un poco diferente comparado con antes. + +Busque la parte `cached:` que se ha agregado en la línea de estado del proceso (línea 5), que significa que Nextflow ha reconocido que ya hizo este trabajo y simplemente reutilizó el resultado de la ejecución exitosa anterior. + +También puede ver que el hash del subdirectorio de trabajo es el mismo que en la ejecución anterior. +Nextflow literalmente le está señalando la ejecución anterior y diciendo "Ya hice eso allí." + +!!! tip "Consejo" + + Cuando vuelve a ejecutar un pipeline con `resume`, Nextflow no sobrescribe ningún archivo publicado fuera del directorio de trabajo por ninguna ejecución que se ejecutó exitosamente anteriormente. + +### 4.2. Inspeccionar el log de ejecuciones pasadas + +Ya sea que esté desarrollando un nuevo pipeline o ejecutando pipelines en producción, en algún momento probablemente necesitará buscar información sobre ejecuciones pasadas. +Aquí está cómo hacerlo. + +Cada vez que inicia un flujo de trabajo de Nextflow, se escribe una línea en un archivo de log llamado `history`, bajo un directorio oculto llamado `.nextflow` en el directorio de trabajo actual. + +??? abstract "Contenido del archivo" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Este archivo le da la marca de tiempo, nombre de ejecución, estado, ID de revisión, ID de sesión y línea de comando completa para cada ejecución de Nextflow que se ha iniciado desde dentro del directorio de trabajo actual. + +Una forma más conveniente de acceder a esta información es usar el comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Salida del comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Esto mostrará los contenidos del archivo de log en el terminal, aumentado con una línea de encabezado. + +Notará que el ID de sesión cambia cada vez que ejecuta un nuevo comando `nextflow run`, EXCEPTO si está usando la opción `-resume`. +En ese caso, el ID de sesión permanece igual. + +Nextflow usa el ID de sesión para agrupar información de caché de ejecución bajo el directorio `cache`, también ubicado bajo `.nextflow`. + +### 4.3. Eliminar directorios de trabajo antiguos + +Durante el proceso de desarrollo, típicamente ejecutará su borrador de pipeline un gran número de veces, lo que puede llevar a una acumulación de muchos archivos en muchos subdirectorios. + +Afortunadamente Nextflow incluye un útil subcomando `clean` que puede eliminar automáticamente los subdirectorios de trabajo para ejecuciones pasadas que ya no le importan. + +#### 4.3.1. Determinar criterios de eliminación + +Hay múltiples [opciones](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para determinar qué eliminar. + +Aquí le mostramos un ejemplo que elimina todos los subdirectorios de ejecuciones antes de una ejecución dada, especificada usando su nombre de ejecución. + +Busque la ejecución exitosa más reciente donde no usó `-resume`; en nuestro caso el nombre de ejecución fue `golden_cantor`. + +El nombre de ejecución es la cadena de dos partes generada por la máquina que se muestra entre corchetes en la línea de salida de consola `Launching (...)`. +También puede usar el log de Nextflow para buscar una ejecución basada en su marca de tiempo y/o línea de comando. + +#### 4.3.2. Hacer una ejecución de prueba + +Primero usamos el flag de ejecución de prueba `-n` para verificar qué se eliminará dado el comando: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Salida del comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Su salida tendrá diferentes nombres de directorio de tarea y puede tener un número diferente de líneas, pero debería parecer similar al ejemplo. + +Si no ve ninguna línea de salida, o no proporcionó un nombre de ejecución válido o no hay ejecuciones pasadas para eliminar. Asegúrese de cambiar `golden_cantor` en el comando de ejemplo por el correspondiente nombre de ejecución más reciente en su log. + +#### 4.3.3. Proceder con la eliminación + +Si la salida parece como se esperaba y quiere proceder con la eliminación, vuelva a ejecutar el comando con el flag `-f` en lugar de `-n`: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Salida del comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +La salida debería ser similar a antes, pero ahora diciendo 'Removed' en lugar de 'Would remove'. +Note que esto no elimina los subdirectorios de dos caracteres (como `a3/` arriba) pero sí vacía sus contenidos. + +!!! Warning "Advertencia" + + Eliminar subdirectorios de trabajo de ejecuciones pasadas los elimina del caché de Nextflow y elimina cualquier salida que se almacenó en esos directorios. + Eso significa que rompe la capacidad de Nextflow de reanudar la ejecución sin volver a ejecutar los procesos correspondientes. + + ¡Usted es responsable de guardar cualquier salida que le importe o en la que planee confiar! Esa es la razón principal por la que preferimos usar el modo `copy` en lugar del modo `symlink` para la directiva `publish`. + +### Conclusión + +Sabe cómo publicar salidas en un directorio específico, volver a iniciar un pipeline sin repetir pasos que ya se ejecutaron de manera idéntica, y usar el comando `nextflow clean` para limpiar directorios de trabajo antiguos. + +Más generalmente, sabe cómo interpretar un flujo de trabajo simple de Nextflow, gestionar su ejecución y recuperar salidas. + +### ¿Qué sigue? + +¡Tómese un pequeño descanso, se lo ha ganado! + +Cuando esté listo, continúe a [**Parte 2: Hello Channels**](./02_hello_channels.md) para aprender cómo usar canales para alimentar entradas a su flujo de trabajo, lo que le permitirá aprovechar el paralelismo de flujo de datos integrado de Nextflow y otras características poderosas. + +--- + +## Cuestionario + +<quiz> +¿Cuáles son los componentes mínimos requeridos de un proceso de Nextflow? +- [ ] Solo bloques de entrada y salida +- [x] Bloques de salida y script +- [ ] Bloques de entrada, salida y script +- [ ] Solo un bloque de script + +Más información: [1.1.1. La definición de process](#111-la-definicion-de-process) +</quiz> + +<quiz> +¿Cuál es el propósito del bloque output en un proceso? +- [ ] Imprimir resultados en la consola +- [ ] Guardar archivos en el directorio de trabajo +- [x] Declarar las salidas esperadas del proceso +- [ ] Definir variables de entorno + +Más información: [1.1.1. La definición de process](#111-la-definicion-de-process) +</quiz> + +<quiz> +¿Qué comando se usa para ejecutar un flujo de trabajo de Nextflow? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Mirando el directorio de trabajo de una tarea, ¿qué archivo contiene el comando real que se ejecutó? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Más información: [1.2.2. Encontrar la salida y los logs en el directorio `work`](#122-encontrar-la-salida-y-los-logs-en-el-directorio-work) +</quiz> + +<quiz> +¿Qué hace el flag `-resume`? +- [ ] Reinicia el flujo de trabajo desde el principio +- [ ] Pausa el flujo de trabajo +- [x] Omite procesos que ya se completaron exitosamente +- [ ] Crea una copia de seguridad del flujo de trabajo + +Más información: [4.1. Volver a iniciar un flujo de trabajo con `-resume`](#41-volver-a-iniciar-un-flujo-de-trabajo-con--resume) +</quiz> + +<quiz> +¿Cuál es el modo predeterminado para publicar salidas del flujo de trabajo? +- [ ] Copiar archivos al directorio de salida +- [x] Crear enlaces simbólicos en el directorio de salida +- [ ] Mover archivos al directorio de salida +- [ ] Comprimir archivos en el directorio de salida + +Más información: [2.3. Establecer el modo de publicación a copia](#23-establecer-el-modo-de-publicacion-a-copia) +</quiz> + +<quiz> +¿Cómo se pasa un valor de parámetro a un flujo de trabajo de Nextflow desde la línea de comandos? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +Más información: [3.2. Configurar un parámetro de línea de comandos para capturar la entrada del usuario](#32-configurar-un-parametro-de-linea-de-comandos-para-capturar-la-entrada-del-usuario) +</quiz> + +<quiz> +¿Cómo se referencia una variable dentro de un bloque script de Nextflow? +- [ ] Usar sintaxis `%variable%` +- [x] Usar sintaxis `#!groovy ${variable}` +- [ ] Usar sintaxis `{{variable}}` +- [ ] Usar sintaxis `[variable]` +</quiz> diff --git a/docs/es/docs/hello_nextflow/02_hello_channels.md b/docs/es/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..20fdae26aa --- /dev/null +++ b/docs/es/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Parte 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/02_hello_channels.md). +/// + +En la Parte 1 de este curso (Hello World), le mostramos cómo proporcionar una entrada variable a un proceso proporcionando la entrada directamente en la llamada al proceso: `sayHello(params.input)`. +Ese fue un enfoque deliberadamente simplificado. +En la práctica, ese enfoque tiene limitaciones importantes; a saber, que solo funciona para casos muy simples donde solo queremos ejecutar el proceso una vez, con un único valor. +En la mayoría de los casos de uso reales de flujos de trabajo, queremos procesar múltiples valores (datos experimentales para múltiples muestras, por ejemplo), por lo que necesitamos una forma más sofisticada de manejar las entradas. + +Para eso sirven los **channels** de Nextflow. +Los channels son colas diseñadas para manejar entradas de manera eficiente y transportarlas de un paso a otro en flujos de trabajo de múltiples pasos, mientras proporcionan paralelismo integrado y muchos beneficios adicionales. + +En esta parte del curso, aprenderá cómo usar un channel para manejar múltiples entradas de una variedad de fuentes diferentes. +También aprenderá a usar **operadores** para transformar el contenido de los channels según sea necesario. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado la Parte 1 del curso [Hello Nextflow](./index.md), pero si se siente cómodo con los conceptos básicos cubiertos en esa sección, puede comenzar desde aquí sin hacer nada especial. + +--- + +## 0. Calentamiento: Ejecutar `hello-channels.nf` + +Vamos a usar el script de workflow `hello-channels.nf` como punto de partida. +Es equivalente al script producido al trabajar en la Parte 1 de este curso de entrenamiento, excepto que hemos cambiado el destino de salida: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Solo para asegurarse de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Como anteriormente, encontrará el archivo de salida llamado `output.txt` en el directorio `results/hello_channels` (como se especifica en el bloque `output` del script de workflow, mostrado arriba). + +??? abstract "Contenido del directorio" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenido del archivo" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Si eso funcionó para usted, está listo para aprender sobre channels. + +--- + +## 1. Proporcionar entradas variables a través de un channel explícitamente + +Vamos a crear un **channel** para pasar la entrada variable al proceso `sayHello()` en lugar de depender del manejo implícito, que tiene ciertas limitaciones. + +### 1.1. Crear un channel de entrada + +Hay una variedad de **channel factories** que podemos usar para configurar un channel. +Para mantener las cosas simples por ahora, vamos a usar la channel factory más básica, llamada `channel.of`, que creará un channel que contiene un único valor. +Funcionalmente esto será similar a cómo lo teníamos configurado antes, pero en lugar de que Nextflow cree un channel implícitamente, ahora lo estamos haciendo explícitamente. + +Esta es la línea de código que vamos a usar: + +```console title="Sintaxis" +greeting_ch = channel.of('Hello Channels!') +``` + +Esto crea un channel llamado `greeting_ch` usando la channel factory `channel.of()`, que configura un simple queue channel, y carga la cadena `'Hello Channels!'` para usar como valor de saludo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Nota" + + Estamos cambiando temporalmente a cadenas codificadas en lugar de usar un parámetro CLI por razones de legibilidad. Volveremos a usar parámetros CLI una vez que hayamos cubierto lo que está sucediendo a nivel del channel. + +En el bloque workflow, agregue el código de la channel factory: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emitir un saludo + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // emitir un saludo + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Esto aún no es funcional ya que todavía no hemos cambiado la entrada a la llamada del proceso. + +### 1.2. Agregar el channel como entrada a la llamada del proceso + +Ahora necesitamos conectar nuestro channel recién creado a la llamada del proceso `sayHello()`, reemplazando el parámetro CLI que proporcionábamos directamente antes. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emitir un saludo + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Esto le dice a Nextflow que ejecute el proceso `sayHello` sobre el contenido del channel `greeting_ch`. + +Ahora nuestro flujo de trabajo es correctamente funcional; es el equivalente explícito de escribir `sayHello('Hello Channels!')`. + +### 1.3. Ejecutar el flujo de trabajo + +¡Ejecutémoslo! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Si hizo ambas ediciones correctamente, debería obtener una ejecución exitosa. +Puede verificar el directorio de resultados para comprobar que el resultado sigue siendo el mismo que antes. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Así que hemos aumentado la flexibilidad de nuestro flujo de trabajo mientras logramos el mismo resultado final. +Esto puede parecer que estamos escribiendo más código sin ningún beneficio tangible, pero el valor se hará evidente tan pronto como comencemos a manejar más entradas. + +Como adelanto de eso, veamos una cosa más antes de continuar: un pequeño pero conveniente beneficio de usar un channel explícito para gestionar la entrada de datos. + +### 1.4. Usar `view()` para inspeccionar el contenido del channel + +Los channels de Nextflow están construidos de una manera que nos permite operar sobre su contenido usando operadores, que cubriremos en detalle más adelante en este capítulo. + +Por ahora, solo vamos a mostrarle cómo usar un operador súper simple llamado [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) para inspeccionar el contenido de un channel. +Puede pensar en `view()` como una herramienta de depuración, como una declaración `print()` en Python, o su equivalente en otros lenguajes. + +Agregue esta pequeña línea al bloque workflow: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels!') + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +La cantidad exacta de espacios no importa siempre que sea un múltiplo de 4; solo estamos tratando de alinear el inicio de la declaración `.view()` con la parte `.of()` de la construcción del channel. + +Ahora ejecute el flujo de trabajo nuevamente: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Como puede ver, esto muestra el contenido del channel en la consola. +Aquí solo tenemos un elemento, pero cuando comencemos a cargar múltiples valores en el channel en la siguiente sección, verá que esto está configurado para mostrar un elemento por línea. + +### Conclusión + +Sabe cómo usar una channel factory básica para proporcionar una entrada a un proceso. + +### ¿Qué sigue? + +Aprender cómo usar channels para hacer que el flujo de trabajo itere sobre múltiples valores de entrada. + +--- + +## 2. Modificar el flujo de trabajo para ejecutarse con múltiples valores de entrada + +Los flujos de trabajo típicamente se ejecutan en lotes de entradas que están destinadas a ser procesadas en masa, por lo que queremos actualizar el flujo de trabajo para aceptar múltiples valores de entrada. + +### 2.1. Cargar múltiples saludos en el channel de entrada + +Convenientemente, la channel factory `channel.of()` que hemos estado usando acepta felizmente más de un valor, por lo que no necesitamos modificar eso en absoluto. +Simplemente podemos cargar múltiples valores en el channel. + +Hagámoslos `'Hello'`, `'Bonjour'` y `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_En el diagrama, el channel se representa en verde, y el orden de los elementos se representa como canicas en una tubería: el primero cargado está a la derecha, luego el segundo en el medio, luego el tercero está a la izquierda._ + +#### 2.1.1. Agregar más saludos + +Antes del bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // crear un canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // crear un canal para entradas + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +La documentación nos dice que esto debería funcionar. ¿Puede ser realmente tan simple? + +#### 2.1.2. Ejecutar el comando y ver la salida del log + +Probémoslo. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Ciertamente parece haber funcionado bien. +El monitor de ejecución muestra que se hicieron `3 of 3` llamadas para el proceso `sayHello`, y vemos los tres saludos enumerados por la declaración `view()`, uno por línea como se prometió. + +Sin embargo, todavía hay solo una salida en el directorio de resultados: + +??? abstract "Contenido del directorio" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenido del archivo" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Debería ver uno de los tres saludos allí, pero el que obtuvo podría ser diferente de lo que se muestra aquí. +¿Puede pensar por qué podría ser así? + +Mirando hacia atrás en el monitor de ejecución, nos dio solo una ruta de subdirectorio (`f4/c9962c`). +Echemos un vistazo allí. + +??? abstract "Contenido del directorio" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenido del archivo" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +¡Ese ni siquiera es el mismo saludo que obtuvimos en el directorio de resultados! ¿Qué está pasando? + +En este punto, necesitamos decirle que por defecto, el sistema de logging ANSI escribe el logging de múltiples llamadas al mismo proceso en la misma línea. +Entonces el estado de las tres llamadas al proceso sayHello() están llegando al mismo lugar. + +Afortunadamente, podemos deshabilitar ese comportamiento para ver la lista completa de llamadas de proceso. + +#### 2.1.3. Ejecutar el comando nuevamente con la opción `-ansi-log false` + +Para expandir el logging y mostrar una línea por llamada de proceso, agregue `-ansi-log false` al comando. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Esta vez vemos las tres ejecuciones de proceso y sus subdirectorios de trabajo asociados listados en la salida. + +Eso es mucho mejor, al menos para un flujo de trabajo simple. +Para un flujo de trabajo complejo, o un gran número de entradas, tener la lista completa en el terminal sería un poco abrumador. +Por eso `-ansi-log false` no es el comportamiento predeterminado. + +!!! tip "Consejo" + + La forma en que se reporta el estado es un poco diferente entre los dos modos de logging. + En el modo condensado, Nextflow reporta si las llamadas se completaron exitosamente o no. + En este modo expandido, solo reporta que fueron enviadas. + +De todos modos, ahora que tenemos los subdirectorios de cada llamada de proceso, podemos buscar sus logs y salidas. + +??? abstract "Contenido del directorio" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenido del archivo" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Esto muestra que los tres procesos se ejecutaron exitosamente (¡yay!). + +Dicho esto, todavía tenemos el problema de que solo hay un archivo de salida en el directorio de resultados. + +Puede recordar que codificamos el nombre del archivo de salida para el proceso `sayHello`, por lo que las tres llamadas produjeron un archivo llamado `output.txt`. + +Mientras los archivos de salida permanezcan en los subdirectorios de trabajo, aislados de los otros procesos, eso está bien. +Pero cuando se publican en el mismo directorio de resultados, el que se copió allí primero es sobrescrito por el siguiente, y así sucesivamente. + +### 2.2. Asegurar que los nombres de archivo de salida sean únicos + +Podemos continuar publicando todas las salidas en el mismo directorio de resultados, pero necesitamos asegurar que tendrán nombres únicos. +Específicamente, necesitamos modificar el primer proceso para generar un nombre de archivo dinámicamente para que los nombres de archivo finales sean únicos. + +Entonces, ¿cómo hacemos que los nombres de archivo sean únicos? +Una forma común de hacer esto es usar alguna pieza única de metadatos de las entradas (recibida del channel de entrada) como parte del nombre del archivo de salida. +Aquí, por conveniencia, simplemente usaremos el saludo mismo ya que es solo una cadena corta, y lo antepondremos al nombre base del archivo de salida. + +#### 2.2.1. Construir un nombre de archivo de salida dinámico + +En el bloque process, haga los siguientes cambios de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Asegúrese de reemplazar `output.txt` tanto en la definición de salida como en el bloque de comando `script:`. + +!!! tip "Consejo" + + En la definición de salida, DEBE usar comillas dobles alrededor de la expresión del nombre de archivo (NO comillas simples), de lo contrario fallará. + +Esto debería producir un nombre de archivo de salida único cada vez que se llama al proceso, para que pueda distinguirse de las salidas de otras llamadas al mismo proceso en el directorio de salida. + +#### 2.2.2. Ejecutar el flujo de trabajo + +Ejecutémoslo. Note que volvemos a ejecutar con la configuración de log ANSI predeterminada. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Volviendo a la vista resumida, la salida se resume en una línea nuevamente. +Eche un vistazo al directorio `results` para ver si todos los saludos de salida están allí. + +??? abstract "Contenido del directorio" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +¡Sí! Y cada uno tiene el contenido esperado. + +??? abstract "Contenido del archivo" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +¡Éxito! Ahora podemos agregar tantos saludos como queramos sin preocuparnos de que los archivos de salida sean sobrescritos. + +!!! tip "Consejo" + + En la práctica, nombrar archivos basándose en los datos de entrada mismos es casi siempre poco práctico. + La mejor manera de generar nombres de archivo dinámicos es pasar metadatos a un proceso junto con los archivos de entrada. + Los metadatos típicamente se proporcionan a través de una 'hoja de muestras' o equivalentes. + Aprenderá cómo hacer eso más adelante en su entrenamiento de Nextflow (vea [Misión secundaria de Metadatos](../side_quests/metadata.md)). + +### Conclusión + +Sabe cómo alimentar múltiples elementos de entrada a través de un channel. + +### ¿Qué sigue? + +Aprender a usar un operador para transformar el contenido de un channel. + +--- + +## 3. Proporcionar múltiples entradas a través de un array + +Acabamos de mostrarle cómo manejar múltiples elementos de entrada que estaban codificados directamente en la channel factory. +¿Qué pasa si quisiéramos proporcionar esas múltiples entradas de una manera diferente? + +Por ejemplo, imagine que configuramos una variable de entrada que contiene un array de elementos así: + +`greetings_array = ['Hello','Bonjour','Holà']` + +¿Podemos cargar eso en nuestro channel de salida y esperar que funcione? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Averigüémoslo. + +### 3.1. Proporcionar un array de valores como entrada al channel + +El sentido común sugiere que deberíamos poder simplemente pasar un array de valores en lugar de un único valor. +Probémoslo; necesitaremos configurar la variable de entrada y cargarla en la channel factory. + +#### 3.1.1. Configurar la variable de entrada + +Tomemos la variable `greetings_array` que acabamos de imaginar y hagámosla realidad agregándola al bloque workflow: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crear un canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Esto aún no es funcional, solo hemos agregado una declaración para el array. + +#### 3.1.2. Establecer el array de saludos como entrada a la channel factory + +Ahora vamos a reemplazar los valores `'Hello','Bonjour','Holà'` actualmente codificados en la channel factory con el `greetings_array` que acabamos de crear. + +En el bloque workflow, haga el siguiente cambio: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Esto debería ser funcional ahora. + +#### 3.1.3. Ejecutar el flujo de trabajo + +Intentemos ejecutarlo: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Salida del comando" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +¡Oh no! ¡Hay un error! + +Mire la salida de `view()` y los mensajes de error. + +Parece que Nextflow intentó ejecutar una única llamada de proceso, usando `[Hello, Bonjour, Holà]` como un valor de cadena, en lugar de usar las tres cadenas en el array como valores separados. + +Entonces es el 'empaquetado' lo que está causando el problema. +¿Cómo hacemos que Nextflow desempaque el array y cargue las cadenas individuales en el channel? + +### 3.2. Usar un operador para transformar el contenido del channel + +Aquí es donde los **[operadores](https://www.nextflow.io/docs/latest/reference/operator.html)** entran en juego. +Ya ha usado el operador `.view()`, que solo mira lo que hay allí. +Ahora vamos a ver operadores que nos permiten actuar sobre el contenido de un channel. + +Si revisa la [lista de operadores](https://www.nextflow.io/docs/latest/reference/operator.html) en la documentación de Nextflow, encontrará [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), que hace exactamente lo que necesitamos: desempacar el contenido de un array y emitirlos como elementos individuales. + +#### 3.2.1. Agregar el operador `flatten()` + +Para aplicar el operador `flatten()` a nuestro channel de entrada, lo agregamos a la declaración de la channel factory. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Aquí agregamos el operador en la siguiente línea para legibilidad, pero puede agregar operadores en la misma línea que la channel factory si lo prefiere, así: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Refinar la(s) declaración(es) `view()` + +Podríamos ejecutar esto de inmediato para probar si funciona, pero mientras estamos en ello, vamos a refinar cómo inspeccionamos el contenido del channel. + +Queremos poder contrastar cómo se ve el contenido antes y después de aplicar el operador `flatten()`, así que vamos a agregar un segundo, Y vamos a agregar un poco de código para etiquetarlos más claramente en la salida. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Verá que hemos agregado una segunda declaración `.view`, y para cada una de ellas, hemos reemplazado los paréntesis vacíos (`()`) con llaves que contienen algo de código, como `{ greeting -> "Before flatten: $greeting" }`. + +Estas se llaman _closures_. El código que contienen se ejecutará para cada elemento en el channel. +Definimos una variable temporal para el valor interno, aquí llamada `greeting` (pero podría ser cualquier nombre arbitrario), que solo se usa dentro del alcance de esa closure. + +En este ejemplo, `$greeting` representa cada elemento individual cargado en el channel. +Esto resultará en una salida de consola bien etiquetada. + +!!! info "Información" + + En algunos pipelines puede ver una variable especial llamada `$it` usada dentro de closures de operadores. + Esta es una variable _implícita_ que permite un acceso abreviado a la variable interna, + sin necesidad de definirla con un `->`. + + Preferimos ser explícitos para ayudar a la claridad del código, por lo que la sintaxis `$it` está desaconsejada y gradualmente se eliminará del lenguaje Nextflow. + +#### 3.2.3. Ejecutar el flujo de trabajo + +¡Finalmente, puede intentar ejecutar el flujo de trabajo nuevamente! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Esta vez funciona Y nos da la información adicional sobre cómo se ve el contenido del channel antes y después de ejecutar el operador `flatten()`. + +- - Verá que obtenemos una única declaración `Before flatten:` porque en ese punto el channel contiene un elemento, el array original. + Luego obtenemos tres declaraciones `After flatten:` separadas, una para cada saludo, que ahora son elementos individuales en el channel. + +Importante, esto significa que cada elemento ahora puede ser procesado por separado por el flujo de trabajo. + +!!! tip "Consejo" + + Es técnicamente posible lograr los mismos resultados usando una channel factory diferente, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), que incluye un paso de mapeo implícito en su operación. + Aquí elegimos no usar eso para demostrar el uso de un operador en un caso de uso simple. + +### Conclusión + +Sabe cómo usar un operador como `flatten()` para transformar el contenido de un channel, y cómo usar el operador `view()` para inspeccionar el contenido del channel antes y después de aplicar un operador. + +### ¿Qué sigue? + +Aprender cómo hacer que el flujo de trabajo tome un archivo como su fuente de valores de entrada. + +--- + +## 4. Leer valores de entrada desde un archivo CSV + +Realisticamente, rara vez o nunca vamos a comenzar desde un array de valores. +Lo más probable es que tengamos uno o más archivos que contienen los datos que necesitan ser procesados, en algún tipo de formato estructurado. + +Hemos preparado un archivo CSV llamado `greetings.csv` que contiene varios saludos de entrada, imitando el tipo de datos columnares que podría querer procesar en un análisis de datos real, almacenado bajo `data/`. +(Los números no son significativos, solo están ahí con fines ilustrativos.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Nuestra próxima tarea es adaptar nuestro flujo de trabajo para leer los valores de este archivo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Veamos cómo podemos hacer que eso suceda. + +### 4.1. Modificar el script para esperar un archivo CSV como fuente de saludos + +Para comenzar, vamos a necesitar hacer dos cambios clave en el script: + +- Cambiar el parámetro de entrada para apuntar al archivo CSV +- Cambiar la channel factory a una diseñada para manejar un archivo + +#### 4.1.1. Cambiar el parámetro de entrada para apuntar al archivo CSV + +¿Recuerda el parámetro `params.input` que configuramos en la Parte 1? +Lo vamos a actualizar para apuntar al archivo CSV que contiene nuestros saludos. + +Haga la siguiente edición a la declaración del parámetro: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Parámetros del pipeline + */ + input: String = 'Holà mundo!' + ``` + +Esto asume que el archivo está ubicado junto con el código del flujo de trabajo. +Aprenderá cómo lidiar con otras ubicaciones de datos más adelante en su viaje con Nextflow. + +#### 4.1.2. Cambiar a una channel factory diseñada para manejar un archivo + +Ya que ahora queremos usar un archivo en lugar de cadenas simples como entrada, no podemos usar la channel factory `channel.of()` de antes. +Necesitamos cambiar a usar una nueva channel factory, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), que tiene alguna funcionalidad integrada para manejar rutas de archivos. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // crear un canal para entradas from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // declarar un array de saludos de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // crear un canal para entradas + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Notará que cambiamos la entrada del channel de nuevo a `param.input`, y eliminamos la declaración `greetings_array` ya que ya no la necesitaremos. +También hemos comentado el `flatten()` y la segunda declaración `view()`. + +#### 4.1.3. Ejecutar el flujo de trabajo + +Intentemos ejecutar el flujo de trabajo con la nueva channel factory y el archivo de entrada. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Salida del comando" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Oh no, no funciona. Eche un vistazo al inicio de la salida de la consola y el mensaje de error. +La parte `Command executed:` es especialmente útil aquí. + +Esto puede parecer un poco familiar. +Parece que Nextflow intentó ejecutar una única llamada de proceso usando la ruta del archivo mismo como un valor de cadena. +Así que ha resuelto la ruta del archivo correctamente, pero en realidad no analizó su contenido, que es lo que queríamos. + +¿Cómo hacemos que Nextflow abra el archivo y cargue su contenido en el channel? + +¡Parece que necesitamos otro [operador](https://www.nextflow.io/docs/latest/reference/operator.html)! + +### 4.2. Usar el operador `splitCsv()` para analizar el archivo + +Revisando la lista de operadores nuevamente, encontramos [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), que está diseñado para analizar y dividir texto con formato CSV. + +#### 4.2.1. Aplicar `splitCsv()` al channel + +Para aplicar el operador, lo agregamos a la línea de la channel factory como anteriormente. + +En el bloque workflow, haga el siguiente cambio de código para reemplazar `flatten()` con `splitcsv()` (sin comentar): + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // crear un canal para entradas from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // crear un canal para entradas from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Como puede ver, también actualizamos las declaraciones `view()` de antes/después. +Técnicamente podríamos haber usado el mismo nombre de variable (`greeting`) pero lo actualizamos a algo más apropiado (`csv`) para hacer el código más legible por otros. + +#### 4.2.2. Ejecutar el flujo de trabajo nuevamente + +Intentemos ejecutar el flujo de trabajo con la lógica de análisis CSV agregada. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Salida del comando" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Interesantemente, esto también falla, pero con un error diferente. +Esta vez Nextflow ha analizado el contenido del archivo (¡yay!) pero ha cargado cada fila como un array, y cada array es un elemento en el channel. + +Necesitamos decirle que solo tome la primera columna en cada fila. +Entonces, ¿cómo desempacamos esto? + +Anteriormente usamos `flatten()` para desempacar el contenido de un channel, pero eso no funcionaría aquí porque flatten desempaca _todo_ (siéntase libre de probarlo si quiere verlo por sí mismo). + +En cambio, usaremos otro operador llamado `map()` que es realmente útil y aparece mucho en los pipelines de Nextflow. + +### 4.3. Usar el operador `map()` para extraer los saludos + +El operador [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) es una pequeña herramienta muy práctica que nos permite hacer todo tipo de mapeos al contenido de un channel. + +En este caso, vamos a usarlo para extraer ese único elemento que queremos de cada fila en nuestro archivo de datos. +Así es como se ve la sintaxis: + +```groovy title="Sintaxis" +.map { row -> row[0] } +``` + +Esto significa 'para cada fila en el channel, tomar el elemento 0 (primero) que contiene'. + +Así que apliquemos eso a nuestro análisis CSV. + +#### 4.3.1. Aplicar `map()` al channel + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // crear un canal para entradas from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crear un canal para entradas from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Verá que agregamos otra llamada `view()` para confirmar que el operador hace lo que esperamos. + +#### 4.3.2. Ejecutar el flujo de trabajo + +Ejecutemos esto una vez más: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Esta vez debería ejecutarse sin error. + +Mirando la salida de las declaraciones `view()`, verá lo siguiente: + +- Una única declaración `Before splitCsv:`: en ese punto el channel contiene un elemento, la ruta original del archivo. +- Tres declaraciones `After splitCsv:` separadas: una para cada saludo, pero cada una está contenida dentro de un array que corresponde a esa línea en el archivo. +- Tres declaraciones `After map:` separadas: una para cada saludo, que ahora son elementos individuales en el channel. + +Note que las líneas pueden aparecer en un orden diferente en su salida. + +También puede mirar los archivos de salida para verificar que cada saludo fue correctamente extraído y procesado a través del flujo de trabajo. + +Hemos logrado el mismo resultado que antes, pero ahora tenemos mucha más flexibilidad para agregar más elementos al channel de saludos que queremos procesar modificando un archivo de entrada, sin modificar ningún código. +Aprenderá enfoques más sofisticados para manejar entradas complejas en un entrenamiento posterior. + +### Conclusión + +Sabe cómo usar el constructor de channel `.fromPath()` y los operadores `splitCsv()` y `map()` para leer un archivo de valores de entrada y manejarlos apropiadamente. + +Más generalmente, tiene una comprensión básica de cómo Nextflow usa **channels** para gestionar entradas a procesos y **operadores** para transformar su contenido. + +### ¿Qué sigue? + +¡Tome un gran descanso, trabajó duro en este! + +Cuando esté listo, continúe con [**Parte 3: Hola Workflow**](./03_hello_workflow.md) para aprender cómo agregar más pasos y conectarlos en un flujo de trabajo completo. + +--- + +## Cuestionario + +<quiz> +¿Qué es un channel en Nextflow? +- [ ] Una especificación de ruta de archivo +- [ ] Una definición de proceso +- [x] Una estructura tipo cola para pasar datos entre procesos +- [ ] Una configuración + +Aprenda más: [1.1. Crear un channel de entrada](#11-crear-un-channel-de-entrada) +</quiz> + +<quiz> +¿Qué producirá este código? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (una única lista) +- [x] Cada elemento en una línea separada: `Hello`, `Bonjour`, `Hola` +- [ ] Nada (los channels no imprimen por defecto) +- [ ] Un error (sintaxis inválida) + +Aprenda más: [1.1. Crear un channel de entrada](#11-crear-un-channel-de-entrada) +</quiz> + +<quiz> +Cuando un channel contiene múltiples valores, ¿cómo maneja Nextflow la ejecución del proceso? +- [ ] El proceso se ejecuta una vez con todos los valores +- [x] El proceso se ejecuta una vez por cada valor en el channel +- [ ] El proceso se ejecuta solo con el primer valor +- [ ] El proceso se ejecuta solo con el último valor + +Aprenda más: [2. Modificar el flujo de trabajo para ejecutarse con múltiples valores de entrada](#2-modificar-el-flujo-de-trabajo-para-ejecutarse-con-multiples-valores-de-entrada) +</quiz> + +<quiz> +¿Qué hace el operador `flatten()`? +- [ ] Combina múltiples channels en uno +- [ ] Ordena los elementos del channel +- [x] Desempaca arrays en elementos individuales +- [ ] Elimina elementos duplicados + +Aprenda más: [3.2.1. Agregar el operador `flatten()`](#321-agregar-el-operador-flatten) +</quiz> + +<quiz> +¿Cuál es el propósito del operador `view()`? +- [ ] Filtrar el contenido del channel +- [ ] Transformar elementos del channel +- [x] Inspeccionar y depurar el contenido del channel +- [ ] Guardar el contenido del channel en un archivo + +Aprenda más: [1.4. Usar `view()` para inspeccionar el contenido del channel](#14-usar-view-para-inspeccionar-el-contenido-del-channel) +</quiz> + +<quiz> +¿Qué hace `splitCsv()`? +- [ ] Crea un archivo CSV del contenido del channel +- [ ] Divide una cadena por comas +- [x] Analiza un archivo CSV en arrays que representan cada fila +- [ ] Fusiona múltiples archivos CSV + +Aprenda más: [4.2. Usar el operador `splitCsv()` para analizar el archivo](#42-usar-el-operador-splitcsv-para-analizar-el-archivo) +</quiz> + +<quiz> +¿Cuál es el propósito del operador `map()`? +- [ ] Filtrar elementos de un channel +- [ ] Combinar múltiples channels +- [x] Transformar cada elemento en un channel +- [ ] Contar elementos en un channel + +Aprenda más: [4.3. Usar el operador `map()` para extraer los saludos](#43-usar-el-operador-map-para-extraer-los-saludos) +</quiz> + +<quiz> +¿Por qué es importante usar nombres de archivo de salida dinámicos al procesar múltiples entradas? +- [ ] Para mejorar el rendimiento +- [ ] Para reducir el espacio en disco +- [x] Para evitar que los archivos de salida se sobrescriban entre sí +- [ ] Para habilitar la funcionalidad de resume + +Aprenda más: [2.2. Asegurar que los nombres de archivo de salida sean únicos](#22-asegurar-que-los-nombres-de-archivo-de-salida-sean-unicos) +</quiz> diff --git a/docs/es/docs/hello_nextflow/03_hello_workflow.md b/docs/es/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..91d497271b --- /dev/null +++ b/docs/es/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Parte 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/03_hello_workflow.md). +/// + +La mayoría de los flujos de trabajo del mundo real involucran más de un paso. +En este módulo de entrenamiento, aprenderá cómo conectar procesos juntos en un flujo de trabajo de múltiples pasos. + +Esto le enseñará la manera de Nextflow de lograr lo siguiente: + +1. Hacer que los datos fluyan de un proceso al siguiente +2. Recopilar salidas de múltiples llamadas de proceso en una única llamada de proceso +3. Pasar más de una entrada a un proceso +4. Manejar múltiples salidas que salen de un proceso + +Para demostrar, continuaremos construyendo sobre el ejemplo Hello World agnóstico de dominio de las Partes 1 y 2. +Esta vez, vamos a hacer los siguientes cambios a nuestro flujo de trabajo para reflejar mejor cómo las personas construyen flujos de trabajo reales: + +1. Agregar un segundo paso que convierte el saludo a mayúsculas. +2. Agregar un tercer paso que recopila todos los saludos transformados y los escribe en un único archivo. +3. Agregar un parámetro para nombrar el archivo de salida final y pasarlo como entrada secundaria al paso de recopilación. +4. Hacer que el paso de recopilación también reporte una estadística simple sobre lo que fue procesado. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado las Partes 1-2 del curso [Hello Nextflow](./index.md), pero si se siente cómodo con los conceptos básicos cubiertos en esas secciones, puede comenzar desde aquí sin hacer nada especial. + +--- + +## 0. Calentamiento: Ejecutar `hello-workflow.nf` + +Vamos a usar el script de workflow `hello-workflow.nf` como punto de partida. +Es equivalente al script producido al trabajar en la Parte 2 de este curso de entrenamiento, excepto que hemos eliminado las declaraciones `view()` y cambiado el destino de salida: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Solo para asegurarse de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Como anteriormente, encontrará los archivos de salida en la ubicación especificada en el bloque `output`. +Para este capítulo, está bajo `results/hello_workflow/`. + +??? abstract "Contenido del directorio" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Si eso funcionó para usted, está listo para aprender cómo ensamblar un flujo de trabajo de múltiples pasos. + +--- + +## 1. Agregar un segundo paso al flujo de trabajo + +Vamos a agregar un paso para convertir cada saludo a mayúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +Para ese fin, necesitamos hacer tres cosas: + +- Definir el comando que vamos a usar para hacer la conversión a mayúsculas. +- Escribir un nuevo proceso que envuelva el comando de mayúsculas. +- Llamar al nuevo proceso en el bloque workflow y configurarlo para tomar la salida del proceso `sayHello()` como entrada. + +### 1.1. Definir el comando de mayúsculas y probarlo en la terminal + +Para hacer la conversión de los saludos a mayúsculas, vamos a usar una herramienta clásica de UNIX llamada `tr` para 'reemplazo de texto', con la siguiente sintaxis: + +```bash title="Sintaxis" +tr '[a-z]' '[A-Z]' +``` + +Este es un reemplazo de texto de una línea muy ingenuo que no tiene en cuenta las letras acentuadas, por lo que por ejemplo 'Holà' se convertirá en 'HOLà', pero hará un trabajo suficientemente bueno para demostrar los conceptos de Nextflow y eso es lo que importa. + +Para probarlo, podemos ejecutar el comando `echo 'Hello World'` y canalizar su salida al comando `tr`: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +La salida es un archivo de texto llamado `UPPER-output.txt` que contiene la versión en mayúsculas de la cadena `Hello World`. + +??? abstract "Contenido del archivo" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +Eso es básicamente lo que vamos a intentar hacer con nuestro flujo de trabajo. + +### 1.2. Escribir el paso de mayúsculas como un proceso de Nextflow + +Podemos modelar nuestro nuevo proceso basándonos en el primero, ya que queremos usar todos los mismos componentes. + +Agregue la siguiente definición de proceso al script de workflow, justo debajo del primero: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Usar una herramienta de reemplazo de texto para convertir el saludo a mayúsculas + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +En este, componemos el segundo nombre de archivo de salida basado en el nombre de archivo de entrada, similar a lo que hicimos originalmente para la salida del primer proceso. + +### 1.3. Agregar una llamada al nuevo proceso en el bloque workflow + +Ahora necesitamos decirle a Nextflow que realmente llame al proceso que acabamos de definir. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Esto aún no es funcional porque no hemos especificado qué debe ser la entrada al proceso `convertToUpper()`. + +### 1.4. Pasar la salida del primer proceso al segundo proceso + +Ahora necesitamos hacer que la salida del proceso `sayHello()` fluya hacia el proceso `convertToUpper()`. + +Convenientemente, Nextflow empaqueta automáticamente la salida de un proceso en un channel llamado `<process>.out`. +Así que la salida del proceso `sayHello` es un channel llamado `sayHello.out`, que podemos conectar directamente a la llamada a `convertToUpper()`. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // convertir el saludo a mayúsculas + convertToUpper() + ``` + +Para un caso simple como este (una salida a una entrada), ¡eso es todo lo que necesitamos hacer para conectar dos procesos! + +### 1.5. Configurar la publicación de salida del flujo de trabajo + +Finalmente, actualicemos las salidas del flujo de trabajo para publicar también los resultados del segundo proceso. + +#### 1.5.1. Actualizar la sección `publish:` del bloque `workflow` + +En el bloque `workflow`, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +La lógica es la misma que anteriormente. + +#### 1.5.2. Actualizar el bloque `output` + +En el bloque `output`, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Una vez más, la lógica es la misma que antes. + +Esto le muestra que puede controlar la configuración de salida a un nivel muy granular, para cada salida individual. +Siéntase libre de intentar cambiar las rutas o el modo de publicación para uno de los procesos para ver qué sucede. + +Por supuesto, eso significa que estamos repitiendo alguna información aquí, lo que podría volverse inconveniente si quisiéramos actualizar la ubicación para todas las salidas de la misma manera. +Más adelante en el curso, aprenderá cómo configurar estos ajustes para múltiples salidas de manera estructurada. + +### 1.6. Ejecutar el flujo de trabajo con `-resume` + +Probemos esto usando la bandera `-resume`, ya que hemos ejecutado exitosamente el primer paso del flujo de trabajo. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Ahora hay una línea extra en la salida de la consola que corresponde al nuevo proceso que acabamos de agregar. + +Encontrará las salidas en el directorio `results/hello_workflow` como se establece en el bloque `output`. + +??? abstract "Contenido del directorio" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +¡Eso es conveniente! Pero aún vale la pena echar un vistazo dentro del directorio de trabajo de una de las llamadas al segundo proceso. + +??? abstract "Contenido del directorio" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Note que hay dos archivos `*-output`: la salida del primer proceso así como la salida del segundo. + +La salida del primer proceso está allí porque Nextflow la **preparó** (staged) allí para tener todo lo necesario para la ejecución dentro del mismo subdirectorio. + +Sin embargo, en realidad es un enlace simbólico que apunta al archivo original en el subdirectorio de la primera llamada de proceso. +Por defecto, cuando se ejecuta en una sola máquina como estamos haciendo aquí, Nextflow usa enlaces simbólicos en lugar de copias para preparar archivos de entrada e intermedios. + +Ahora, antes de continuar, piense en cómo todo lo que hicimos fue conectar la salida de `sayHello` a la entrada de `convertToUpper` y los dos procesos pudieron ejecutarse en serie. +Nextflow hizo el trabajo duro de manejar archivos de entrada y salida individuales y pasarlos entre los dos comandos por nosotros. + +Esta es una de las razones por las que los channels de Nextflow son tan poderosos: se encargan del trabajo tedioso involucrado en conectar pasos del flujo de trabajo. + +### Conclusión + +Sabe cómo encadenar procesos proporcionando la salida de un paso como entrada al siguiente paso. + +### ¿Qué sigue? + +Aprender cómo recopilar salidas de llamadas de proceso por lotes y alimentarlas en un único proceso. + +--- + +## 2. Agregar un tercer paso para recopilar todos los saludos + +Cuando usamos un proceso para aplicar una transformación a cada uno de los elementos en un channel, como estamos haciendo aquí con los múltiples saludos, a veces queremos recopilar elementos del channel de salida de ese proceso y alimentarlos en otro proceso que realiza algún tipo de análisis o suma. + +Para demostrar, agregaremos un nuevo paso a nuestro pipeline que recopila todos los saludos en mayúsculas producidos por el proceso `convertToUpper` y los escribe en un único archivo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Sin arruinar la sorpresa, esto va a involucrar un operador muy útil. + +### 2.1. Definir el comando de recopilación y probarlo en la terminal + +El paso de recopilación que queremos agregar a nuestro flujo de trabajo usará el comando `cat` para concatenar múltiples saludos en mayúsculas en un único archivo. + +Ejecutemos el comando por sí solo en la terminal para verificar que funciona como se espera, tal como hemos hecho anteriormente. + +Ejecute lo siguiente en su terminal: + +```bash +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 +``` + +La salida es un archivo de texto llamado `COLLECTED-output.txt` que contiene las versiones en mayúsculas de los saludos originales. + +??? abstract "Contenido del archivo" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Ese es el resultado que queremos lograr con nuestro flujo de trabajo. + +### 2.2. Crear un nuevo proceso para hacer el paso de recopilación + +Creemos un nuevo proceso y llamémoslo `collectGreetings()`. +Podemos comenzar a escribirlo basándonos en lo que hemos visto antes. + +#### 2.2.1. Escribir las partes 'obvias' del proceso + +Agregue la siguiente definición de proceso al script de workflow: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Recopilar saludos en mayúsculas en un único archivo de salida + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +Esto es lo que podemos escribir con confianza basándonos en lo que ha aprendido hasta ahora. +¡Pero esto no es funcional! +Deja fuera la(s) definición(es) de entrada y la primera mitad del comando script porque necesitamos descubrir cómo escribir eso. + +#### 2.2.2. Definir entradas a `collectGreetings()` + +Necesitamos recopilar los saludos de todas las llamadas al proceso `convertToUpper()`. +¿Qué sabemos que podemos obtener del paso anterior en el flujo de trabajo? + +El channel producido por `convertToUpper()` contendrá las rutas a los archivos individuales que contienen los saludos en mayúsculas. +Eso equivale a un slot de entrada; llamémoslo `input_files` por simplicidad. + +En el bloque process, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Note que usamos el prefijo `path` aunque esperamos que esto contenga múltiples archivos. + +#### 2.2.3. Componer el comando de concatenación + +Aquí es donde las cosas podrían ponerse un poco complicadas, porque necesitamos poder manejar un número arbitrario de archivos de entrada. +Específicamente, no podemos escribir el comando por adelantado, así que necesitamos decirle a Nextflow cómo componerlo en tiempo de ejecución basándose en qué entradas fluyen hacia el proceso. + +En otras palabras, si tenemos un channel de entrada que contiene el elemento `[file1.txt, file2.txt, file3.txt]`, necesitamos que Nextflow lo convierta en `cat file1.txt file2.txt file3.txt`. + +Afortunadamente, Nextflow está bastante feliz de hacer eso por nosotros si simplemente escribimos `cat ${input_files}` en el comando script. + +En el bloque process, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +En teoría esto debería manejar cualquier número arbitrario de archivos de entrada. + +!!! tip "Consejo" + + Algunas herramientas de línea de comandos requieren proporcionar un argumento (como `-input`) para cada archivo de entrada. + En ese caso, tendríamos que hacer un poco de trabajo extra para componer el comando. + Puede ver un ejemplo de esto en el curso de entrenamiento [Nextflow para Genómica](../../nf4_science/genomics/). + +### 2.3. Agregar el paso de recopilación al flujo de trabajo + +Ahora deberíamos solo necesitar llamar al proceso de recopilación sobre la salida del paso de mayúsculas. + +#### 2.3.1. Conectar las llamadas de proceso + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out) + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="75" + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + } + ``` + +Esto conecta la salida de `convertToUpper()` a la entrada de `collectGreetings()`. + +#### 2.3.2. Ejecutar el flujo de trabajo con `-resume` + +Probémoslo. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Salida del comando" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Se ejecuta exitosamente, incluyendo el tercer paso. + +Sin embargo, mire el número de llamadas para `collectGreetings()` en la última línea. +Solo esperábamos una, pero hay tres. + +Ahora eche un vistazo al contenido del archivo de salida final. + +??? abstract "Contenido del archivo" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Oh no. El paso de recopilación se ejecutó individualmente en cada saludo, lo cual NO es lo que queríamos. + +Necesitamos hacer algo para decirle a Nextflow explícitamente que queremos que ese tercer paso se ejecute en todos los elementos en el channel producido por `convertToUpper()`. + +### 2.4. Usar un operador para recopilar los saludos en una única entrada + +Sí, una vez más la respuesta a nuestro problema es un operador. + +Específicamente, vamos a usar el operador aptamente llamado [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect). + +#### 2.4.1. Agregar el operador `collect()` + +Esta vez va a verse un poco diferente porque no estamos agregando el operador en el contexto de una channel factory; lo estamos agregando a un channel de salida. + +Tomamos el `convertToUpper.out` y agregamos el operador `collect()`, lo que nos da `convertToUpper.out.collect()`. +Podemos conectar eso directamente a la llamada del proceso `collectGreetings()`. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Agregar algunas declaraciones `view()` + +También incluyamos un par de declaraciones `view()` para visualizar los estados antes y después del contenido del channel. + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + + // declaraciones view opcionales + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + } + ``` + +Las declaraciones `view()` pueden ir donde quiera; las pusimos justo después de la llamada para legibilidad. + +#### 2.4.3. Ejecutar el flujo de trabajo nuevamente con `-resume` + +Probémoslo: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Salida del comando" + + ```console + 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] + ``` + +Se ejecuta exitosamente, aunque la salida del log puede verse un poco más desordenada que esto (la limpiamos para legibilidad). + +¡Esta vez el tercer paso solo fue llamado una vez! + +Mirando la salida de las declaraciones `view()`, vemos lo siguiente: + +- Tres declaraciones `Before collect:`, una para cada saludo: en ese punto las rutas de archivo son elementos individuales en el channel. +- Una única declaración `After collect:`: las tres rutas de archivo ahora están empaquetadas en un único elemento. + +Eche un vistazo al contenido del archivo de salida final. + +??? abstract "Contenido del archivo" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Esta vez tenemos los tres saludos en el archivo de salida final. ¡Éxito! + +!!! note "Nota" + + Si ejecuta esto varias veces sin `-resume`, verá que el orden de los saludos cambia de una ejecución a la siguiente. + Esto le muestra que el orden en que los elementos fluyen a través de las llamadas de proceso no está garantizado que sea consistente. + +#### 2.4.4. Eliminar las declaraciones `view()` para legibilidad + +Antes de pasar a la siguiente sección, le recomendamos que elimine las declaraciones `view()` para evitar saturar la salida de la consola. + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="73" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + + // declaraciones view opcionales + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +Esto es básicamente la operación inversa del punto 2.4.2. + +### Conclusión + +Sabe cómo recopilar salidas de un lote de llamadas de proceso y alimentarlas en un análisis conjunto o paso de suma. + +### ¿Qué sigue? + +Aprender cómo pasar más de una entrada a un proceso. + +--- + +## 3. Pasar más de una entrada a un proceso + +Queremos poder nombrar el archivo de salida final con algo específico para poder procesar lotes subsiguientes de saludos sin sobrescribir los resultados finales. + +Para ese fin, vamos a hacer los siguientes refinamientos al flujo de trabajo: + +- Modificar el proceso recopilador para aceptar un nombre definido por el usuario para el archivo de salida +- Agregar un parámetro de línea de comandos al flujo de trabajo y pasarlo al proceso recopilador + +### 3.1. Modificar el proceso recopilador + +Vamos a necesitar declarar la entrada adicional e integrarla en el nombre del archivo de salida. + +#### 3.1.1. Declarar la entrada adicional + +Buenas noticias: podemos declarar tantas variables de entrada como queramos en la definición del proceso. +Llamemos a esta `batch_name`. + +En el bloque process, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Puede configurar sus procesos para esperar tantas entradas como quiera. +Ahora mismo, todas estas están configuradas como entradas requeridas; _debe_ proporcionar un valor para que el flujo de trabajo funcione. + +Aprenderá cómo gestionar entradas requeridas vs. opcionales más adelante en su viaje con Nextflow. + +#### 3.1.2. Usar la variable `batch_name` en el nombre del archivo de salida + +Podemos insertar la variable en el nombre del archivo de salida de la misma manera que hemos compuesto nombres de archivo dinámicos antes. + +En el bloque process, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Esto configura el proceso para usar el valor `batch_name` para generar un nombre de archivo específico para la salida final del flujo de trabajo. + +### 3.2. Agregar un parámetro de línea de comandos `batch` + +Ahora necesitamos una forma de suministrar el valor para `batch_name` y alimentarlo a la llamada del proceso. + +#### 3.2.1. Usar `params` para configurar el parámetro + +Ya sabe cómo usar el sistema `params` para declarar parámetros CLI. +Usemos eso para declarar un parámetro `batch` (con un valor predeterminado porque somos perezosos). + +En la sección de parámetros del pipeline, haga los siguientes cambios de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Al igual que demostramos para `--input`, puede sobrescribir ese valor predeterminado especificando un valor con `--batch` en la línea de comandos. + +#### 3.2.2. Pasar el parámetro `batch` al proceso + +Para proporcionar el valor del parámetro al proceso, necesitamos agregarlo en la llamada del proceso. + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect()) + ``` + +Verá que para proporcionar múltiples entradas a un proceso, simplemente las lista en los paréntesis de la llamada, separadas por comas. + +!!! warning "Advertencia" + + DEBE proporcionar las entradas al proceso en el MISMO ORDEN EXACTO en que están listadas en el bloque de definición de entrada del proceso. + +### 3.3. Ejecutar el flujo de trabajo + +Intentemos ejecutar esto con un nombre de lote en la línea de comandos. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Se ejecuta exitosamente y produce la salida deseada: + +??? abstract "Contenido del archivo" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Ahora, mientras especifiquemos el parámetro apropiadamente, las ejecuciones subsiguientes en otros lotes de entradas no sobrescribirán los resultados anteriores. + +### Conclusión + +Sabe cómo pasar más de una entrada a un proceso. + +### ¿Qué sigue? + +Aprender cómo emitir múltiples salidas y manejarlas convenientemente. + +--- + +## 4. Agregar una salida al paso recopilador + +Hasta ahora hemos estado usando procesos que solo producían una salida cada uno. +Pudimos acceder a sus salidas respectivas muy convenientemente usando la sintaxis `<process>.out`, que usamos tanto en el contexto de pasar una salida al siguiente proceso (ej. `convertToUpper(sayHello.out)`) como en el contexto de la sección `publish:` (ej. `first_output = sayHello.out`). + +¿Qué sucede cuando un proceso produce más de una? +¿Cómo manejamos las múltiples salidas? +¿Podemos seleccionar y usar una salida específica? + +¡Todas excelentes preguntas, y la respuesta corta es sí podemos! + +Las múltiples salidas serán empaquetadas en channels separados. +Podemos elegir dar nombres a esos channels de salida, lo que hace fácil referirnos a ellos individualmente más tarde, o podemos referirnos a ellos por índice. + +Profundicemos con un ejemplo. + +Para propósitos de demostración, digamos que queremos contar el número de saludos que se están recopilando para un lote dado de entradas y reportarlo en un archivo. + +### 4.1. Modificar el proceso para contar y producir el número de saludos + +Esto requerirá dos cambios clave en la definición del proceso: necesitamos una forma de contar los saludos y escribir un archivo de reporte, luego necesitamos agregar ese archivo de reporte al bloque `output` del proceso. + +#### 4.1.1. Contar el número de saludos recopilados + +Convenientemente, Nextflow nos permite agregar código arbitrario en el bloque `script:` de la definición del proceso, lo cual es muy útil para hacer cosas como esta. + +Eso significa que podemos usar la función incorporada `size()` de Nextflow para obtener el número de archivos en el array `input_files`, y escribir el resultado en un archivo con un comando `echo`. + +En el bloque del proceso `collectGreetings`, haga los siguientes cambios de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +La variable `count_greetings` será computada en tiempo de ejecución. + +#### 4.1.2. Emitir el archivo de reporte y nombrar las salidas + +En principio todo lo que necesitamos hacer es agregar el archivo de reporte al bloque `output:`. + +Sin embargo, mientras estamos en ello, también vamos a agregar algunas etiquetas `emit:` a nuestras declaraciones de salida. Estas nos permitirán seleccionar las salidas por nombre en lugar de tener que usar índices posicionales. + +En el bloque process, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +Las etiquetas `emit:` son opcionales, y podríamos haber agregado una etiqueta a solo una de las salidas. +Pero como dice el dicho, ¿por qué no ambas? + +!!! tip "Consejo" + + Si no nombra las salidas de un proceso usando `emit:`, aún puede acceder a ellas individualmente usando su respectivo índice (basado en cero). + Por ejemplo, usaría `<process>.out[0]` para obtener la primera salida, `<process>.out[1]` para obtener la segunda salida, y así sucesivamente. + + Preferimos nombrar las salidas porque de otra manera, es demasiado fácil tomar el índice incorrecto por error, especialmente cuando el proceso produce muchas salidas. + +### 4.2. Actualizar las salidas del flujo de trabajo + +Ahora que tenemos dos salidas saliendo del proceso `collectGreetings`, la salida `collectGreetings.out` contiene dos channels: + +- `collectGreetings.out.outfile` contiene el archivo de salida final +- `collectGreetings.out.report` contiene el archivo de reporte + +Necesitamos actualizar las salidas del flujo de trabajo en consecuencia. + +#### 4.2.1. Actualizar la sección `publish:` + +En el bloque `workflow`, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Como puede ver, referirse a salidas específicas de proceso ahora es trivial. +Cuando vayamos a agregar un paso más a nuestro pipeline en la Parte 5 (Contenedores), podremos referirnos fácilmente a `collectGreetings.out.outfile` y pasarlo al nuevo proceso (spoiler: el nuevo proceso se llama `cowpy`). + +Pero por ahora, terminemos de actualizar las salidas a nivel de flujo de trabajo. + +#### 4.2.2. Actualizar el bloque `output` + +En el bloque `output`, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +No necesitamos actualizar la definición de salida `collected` ya que ese nombre no ha cambiado. +Solo necesitamos agregar la nueva salida. + +### 4.3. Ejecutar el flujo de trabajo + +Intentemos ejecutar esto con el lote actual de saludos. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Si mira en el directorio `results/hello_workflow/`, encontrará el nuevo archivo de reporte, `trio-report.txt`. +Ábralo para verificar que el flujo de trabajo reportó correctamente el conteo de saludos que fueron procesados. + +??? abstract "Contenido del archivo" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +Siéntase libre de agregar más saludos al CSV y probar qué sucede. + +### Conclusión + +Sabe cómo hacer que un proceso emita múltiples salidas nombradas y cómo manejarlas apropiadamente a nivel de flujo de trabajo. + +Más generalmente, entiende los principios clave involucrados en conectar procesos juntos de maneras comunes. + +### ¿Qué sigue? + +Tome un descanso extra largo, se lo ha ganado. + +Cuando esté listo, continúe con [**Parte 4: Hello Modules**](./04_hello_modules.md) para aprender cómo modularizar su código para mejor mantenibilidad y eficiencia de código. + +--- + +## Cuestionario + +<quiz> +¿Cómo accede a la salida de un proceso en el bloque workflow? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Aprenda más: [1.4. Pasar la salida del primer proceso al segundo proceso](#14-pasar-la-salida-del-primer-proceso-al-segundo-proceso) +</quiz> + +<quiz> +¿Qué determina el orden de ejecución de procesos en Nextflow? +- [ ] El orden en que los procesos están escritos en el bloque workflow +- [ ] Orden alfabético por nombre de proceso +- [x] Dependencias de datos entre procesos +- [ ] Orden aleatorio para ejecución paralela + +Aprenda más: [1.4. Pasar la salida del primer proceso al segundo proceso](#14-pasar-la-salida-del-primer-proceso-al-segundo-proceso) +</quiz> + +<quiz> +¿Qué operador debería reemplazar `???` para reunir todas las salidas en una única lista para el proceso downstream? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Aprenda más: [2.4. Usar un operador para recopilar los saludos en una única entrada](#24-usar-un-operador-para-recopilar-los-saludos-en-una-unica-entrada) +</quiz> + +<quiz> +¿Cuándo debería usar el operador `collect()`? +- [ ] Cuando quiere procesar elementos en paralelo +- [ ] Cuando necesita filtrar el contenido del channel +- [x] Cuando un proceso downstream necesita todos los elementos de un proceso upstream +- [ ] Cuando quiere dividir datos a través de múltiples procesos + +Aprenda más: [2.4. Usar un operador para recopilar los saludos en una única entrada](#24-usar-un-operador-para-recopilar-los-saludos-en-una-unica-entrada) +</quiz> + +<quiz> +¿Cómo accede a una salida nombrada de un proceso? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Aprenda más: [4.1.2. Emitir el archivo de reporte y nombrar las salidas](#412-emitir-el-archivo-de-reporte-y-nombrar-las-salidas) +</quiz> + +<quiz> +¿Cuál es la sintaxis correcta para nombrar una salida en un proceso? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Aprenda más: [4.1.2. Emitir el archivo de reporte y nombrar las salidas](#412-emitir-el-archivo-de-reporte-y-nombrar-las-salidas) +</quiz> + +<quiz> +Cuando proporciona múltiples entradas a un proceso, ¿qué debe ser verdad? +- [ ] Todas las entradas deben ser del mismo tipo +- [ ] Las entradas deben proporcionarse en orden alfabético +- [x] El orden de las entradas debe coincidir con el orden definido en el bloque input +- [ ] Solo se pueden proporcionar dos entradas a la vez + +Aprenda más: [3. Pasar más de una entrada a un proceso](#3-pasar-mas-de-una-entrada-a-un-proceso) +</quiz> diff --git a/docs/es/docs/hello_nextflow/04_hello_modules.md b/docs/es/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..1841822bd5 --- /dev/null +++ b/docs/es/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Parte 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/04_hello_modules.md). +/// + +Esta sección cubre cómo organizar el código de su flujo de trabajo para hacer el desarrollo y mantenimiento de su pipeline más eficiente y sostenible. +Específicamente, vamos a demostrar cómo usar **módulos**. + +En Nextflow, un **módulo** es una única definición de proceso que está encapsulada por sí misma en un archivo de código independiente. +Para usar un módulo en un flujo de trabajo, solo agrega una declaración de importación de una línea a su archivo de código de workflow; luego puede integrar el proceso en el flujo de trabajo de la misma manera que normalmente lo haría. +Eso hace posible reutilizar definiciones de proceso en múltiples flujos de trabajo sin producir múltiples copias del código. + +Cuando comenzamos a desarrollar nuestro flujo de trabajo, escribimos todo en un único archivo de código. +Ahora vamos a mover los procesos a módulos individuales. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Esto hará nuestro código más compartible, flexible y mantenible. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado las Partes 1-3 del curso [Hello Nextflow](./index.md), pero si se siente cómodo con los conceptos básicos cubiertos en esas secciones, puede comenzar desde aquí sin hacer nada especial. + +--- + +## 0. Calentamiento: Ejecutar `hello-modules.nf` + +Vamos a usar el script de workflow `hello-modules.nf` como punto de partida. +Es equivalente al script producido al trabajar en la Parte 3 de este curso de entrenamiento, excepto que hemos cambiado los destinos de salida: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Solo para asegurarse de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Como anteriormente, encontrará los archivos de salida en el directorio especificado en el bloque `output` (aquí, `results/hello_modules/`). + +??? abstract "Contenido del directorio" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Si eso funcionó para usted, está listo para aprender cómo modularizar el código de su flujo de trabajo. + +--- + +## 1. Crear un directorio para almacenar módulos + +Es una buena práctica almacenar sus módulos en un directorio específico. +Puede llamar a ese directorio como quiera, pero la convención es llamarlo `modules/`. + +```bash +mkdir modules +``` + +!!! tip "Consejo" + + Aquí le estamos mostrando cómo usar **módulos locales**, es decir, módulos almacenados localmente en el mismo repositorio que el resto del código del flujo de trabajo, en contraste con módulos remotos, que se almacenan en otros repositorios (remotos). + Para más información sobre **módulos remotos**, vea la [documentación](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Crear un módulo para `sayHello()` + +En su forma más simple, convertir un proceso existente en un módulo es poco más que una operación de copiar y pegar. +Vamos a crear un archivo stub para el módulo, copiar el código relevante y luego eliminarlo del archivo de flujo de trabajo principal. + +Luego todo lo que necesitaremos hacer es agregar una declaración de importación para que Nextflow sepa que debe traer el código relevante en tiempo de ejecución. + +### 2.1. Crear un archivo stub para el nuevo módulo + +Creemos un archivo vacío para el módulo llamado `sayHello.nf`. + +```bash +touch modules/sayHello.nf +``` + +Esto nos da un lugar para poner el código del proceso. + +### 2.2. Mover el código del proceso `sayHello` al archivo del módulo + +Copie toda la definición del proceso desde el archivo de workflow al archivo del módulo, asegurándose de copiar también el shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usar echo para imprimir 'Hello World!' a un archivo + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Una vez hecho eso, elimine la definición del proceso del archivo de workflow, pero asegúrese de dejar el shebang en su lugar. + +### 2.3. Agregar una declaración de importación antes del bloque workflow + +La sintaxis para importar un módulo local es bastante sencilla: + +```groovy title="Sintaxis: Declaración de importación" +include { <MODULE_NAME> } from '<path_to_module>' +``` + +Insertemos eso arriba del bloque `params` y completémoslo apropiadamente. + +=== "Después" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Verá que hemos completado el nombre del módulo, `sayHello`, y la ruta al archivo que contiene el código del módulo, `./modules/sayHello.nf`. + +### 2.4. Ejecutar el flujo de trabajo + +Estamos ejecutando el flujo de trabajo con esencialmente el mismo código y entradas que antes, así que ejecutemos con la bandera `-resume` y veamos qué sucede. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Esto debería ejecutarse muy rápidamente porque todo está en caché. +Siéntase libre de verificar las salidas publicadas. + +Nextflow reconoció que sigue siendo el mismo trabajo por hacer, incluso si el código está dividido en múltiples archivos. + +### Conclusión + +Sabe cómo extraer un proceso en un módulo local y sabe que hacer esto no rompe la capacidad de reanudar del flujo de trabajo. + +### ¿Qué sigue? + +Practicar haciendo más módulos. +Una vez que ha hecho uno, puede hacer un millón más... +Pero por ahora hagamos solo dos más. + +--- + +## 3. Modularizar el proceso `convertToUpper()` + +### 3.1. Crear un archivo stub para el nuevo módulo + +Cree un archivo vacío para el módulo llamado `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Mover el código del proceso `convertToUpper` al archivo del módulo + +Copie toda la definición del proceso desde el archivo de workflow al archivo del módulo, asegurándose de copiar también el shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usar una herramienta de reemplazo de texto para convertir el saludo a mayúsculas + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Una vez hecho eso, elimine la definición del proceso del archivo de workflow, pero asegúrese de dejar el shebang en su lugar. + +### 3.3. Agregar una declaración de importación antes del bloque `params` + +Inserte la declaración de importación arriba del bloque `params` y complétela apropiadamente. + +=== "Después" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="23" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Esto debería empezar a verse muy familiar. + +### 3.4. Ejecutar el flujo de trabajo nuevamente + +Ejecute esto con la bandera `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Esto debería seguir produciendo la misma salida que anteriormente. + +¡Dos listos, uno más por hacer! + +--- + +## 4. Modularizar el proceso `collectGreetings()` + +### 4.1. Crear un archivo stub para el nuevo módulo + +Cree un archivo vacío para el módulo llamado `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Mover el código del proceso `collectGreetings` al archivo del módulo + +Copie toda la definición del proceso desde el archivo de workflow al archivo del módulo, asegurándose de copiar también el shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Recopilar saludos en mayúsculas en un único archivo de salida + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Una vez hecho eso, elimine la definición del proceso del archivo de workflow, pero asegúrese de dejar el shebang en su lugar. + +### 4.3. Agregar una declaración de importación antes del bloque `params` + +Inserte la declaración de importación arriba del bloque `params` y complétela apropiadamente. + +=== "Después" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="3" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Parámetros del pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +¡El último! + +### 4.4. Ejecutar el flujo de trabajo + +Ejecute esto con la bandera `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Esto debería seguir produciendo la misma salida que anteriormente. + +### Conclusión + +Sabe cómo modularizar múltiples procesos en un flujo de trabajo. + +¡Felicitaciones, ha hecho todo este trabajo y absolutamente nada ha cambiado en cómo funciona el pipeline! + +Bromas aparte, ahora su código es más modular, y si decide escribir otro pipeline que llame a uno de esos procesos, solo necesita escribir una corta declaración de importación para usar el módulo relevante. +Esto es mejor que copiar y pegar el código, porque si más tarde decide mejorar el módulo, todos sus pipelines heredarán las mejoras. + +### ¿Qué sigue? + +Tome un pequeño descanso si lo desea. + +Cuando esté listo, continúe con [**Parte 5: Hola Containers**](./05_hello_containers.md) para aprender cómo usar contenedores para gestionar dependencias de software de manera más conveniente y reproducible. + +--- + +## Cuestionario + +<quiz> +¿Qué es un módulo en Nextflow? +- [ ] Un archivo de configuración +- [x] Un archivo independiente que contiene una única definición de proceso +- [ ] Una definición de workflow +- [ ] Un operador de channel + +Aprenda más: [2. Crear un módulo para `sayHello()`](#2-crear-un-modulo-para-sayhello) +</quiz> + +<quiz> +¿Cuál es la convención de nombres recomendada para archivos de módulos? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +¿Dónde deberían almacenarse los archivos de módulos? +- [ ] En el mismo directorio que el workflow +- [ ] En un directorio `bin/` +- [x] En un directorio `modules/` +- [ ] En un directorio `lib/` + +Aprenda más: [1. Crear un directorio para almacenar módulos](#1-crear-un-directorio-para-almacenar-modulos) +</quiz> + +<quiz> +¿Cuál es la sintaxis correcta para importar un módulo? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Aprenda más: [2.3. Agregar una declaración de importación](#23-agregar-una-declaracion-de-importacion-antes-del-bloque-workflow) +</quiz> + +<quiz> +¿Qué sucede con la funcionalidad `-resume` cuando se usan módulos? +- [ ] Ya no funciona +- [ ] Requiere configuración adicional +- [x] Funciona igual que antes +- [ ] Solo funciona para módulos locales +</quiz> + +<quiz> +¿Cuáles son los beneficios de usar módulos? (Seleccione todos los que apliquen) +- [x] Reutilización de código entre flujos de trabajo +- [x] Mantenimiento más fácil +- [x] Mejor organización del código del flujo de trabajo +- [ ] Velocidad de ejecución más rápida +</quiz> diff --git a/docs/es/docs/hello_nextflow/05_hello_containers.md b/docs/es/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..28e141172f --- /dev/null +++ b/docs/es/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Parte 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/05_hello_containers.md). +/// + +En las Partes 1-4 de este curso de entrenamiento, aprendió cómo usar los bloques de construcción básicos de Nextflow para ensamblar un flujo de trabajo simple capaz de procesar algo de texto, paralelizar la ejecución si había múltiples entradas, y recopilar los resultados para procesamiento adicional. + +Sin embargo, estaba limitado a herramientas UNIX básicas disponibles en su entorno. +Las tareas del mundo real a menudo requieren varias herramientas y paquetes que no están incluidos por defecto. +Típicamente, necesitaría instalar estas herramientas, gestionar sus dependencias y resolver cualquier conflicto. + +Todo eso es muy tedioso y molesto, así que vamos a mostrarle cómo usar **contenedores** para resolver este problema de manera mucho más conveniente. + +Un **contenedor** es una unidad de software ligera, independiente y ejecutable creada a partir de una **imagen** de contenedor que incluye todo lo necesario para ejecutar una aplicación incluyendo código, bibliotecas del sistema y configuraciones. +Como puede imaginar, eso va a ser muy útil para hacer sus pipelines más reproducibles. + +Note que enseñaremos esto usando [Docker](https://www.docker.com/get-started/), pero tenga en cuenta que Nextflow soporta [varias otras tecnologías de contenedores](https://www.nextflow.io/docs/latest/container.html#) también. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado las Partes 1-4 del curso [Hello Nextflow](./index.md) y tiene un pipeline completo funcionando. + + Si está comenzando el curso desde este punto, necesitará copiar el directorio `modules` desde las soluciones: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Calentamiento: Ejecutar `hello-containers.nf` + +Vamos a usar el script de workflow `hello-containers.nf` como punto de partida. +Es equivalente al script producido al trabajar en la Parte 4 de este curso de entrenamiento, excepto que hemos cambiado los destinos de salida: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Solo para asegurarse de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Como anteriormente, encontrará los archivos de salida en el directorio especificado en el bloque `output` (`results/hello_containers/`). + +??? abstract "Contenido del directorio" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Si eso funcionó para usted, está listo para aprender cómo usar contenedores. + +--- + +## 1. Usar un contenedor 'manualmente' + +Lo que queremos hacer es agregar un paso a nuestro flujo de trabajo que usará un contenedor para la ejecución. + +Sin embargo, primero vamos a repasar algunos conceptos y operaciones básicas para solidificar su comprensión de qué son los contenedores antes de comenzar a usarlos en Nextflow. + +### 1.1. Descargar la imagen del contenedor + +Para usar un contenedor, usualmente descarga o _pull_ una imagen de contenedor de un registro de contenedores, y luego ejecuta la imagen del contenedor para crear una instancia de contenedor. + +La sintaxis general es la siguiente: + +```bash title="Sintaxis" +docker pull '<container>' +``` + +La parte `docker pull` es la instrucción al sistema de contenedores para descargar una imagen de contenedor de un repositorio. + +La parte `'<container>'` es la dirección URI de la imagen del contenedor. + +Como ejemplo, descarguemos una imagen de contenedor que contiene [cowpy](https://github.com/jeffbuttars/cowpy), una implementación en Python de una herramienta llamada `cowsay` que genera arte ASCII para mostrar entradas de texto arbitrarias de una manera divertida. + +```txt title="Ejemplo" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Hay varios repositorios donde puede encontrar contenedores publicados. +Usamos el servicio [Seqera Containers](https://seqera.io/containers/) para generar esta imagen de contenedor Docker desde el paquete Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Ejecute el comando de descarga completo: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Salida del comando" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Si nunca ha descargado la imagen antes, esto puede tardar un minuto en completarse. +Una vez que esté hecho, tiene una copia local de la imagen del contenedor. + +### 1.2. Usar el contenedor para ejecutar `cowpy` como un comando único + +Una forma muy común en que las personas usan contenedores es ejecutarlos directamente, _es decir_, no interactivamente. +Esto es genial para ejecutar comandos únicos. + +La sintaxis general es la siguiente: + +```bash title="Sintaxis" +docker run --rm '<container>' [tool command] +``` + +La parte `docker run --rm '<container>'` es la instrucción al sistema de contenedores para iniciar una instancia de contenedor desde una imagen de contenedor y ejecutar un comando en ella. +La bandera `--rm` le dice al sistema que apague la instancia del contenedor después de que el comando se haya completado. + +La sintaxis `[tool command]` depende de la herramienta que esté usando y cómo esté configurado el contenedor. +Comencemos simplemente con `cowpy`. + +Completamente ensamblado, el comando de ejecución del contenedor se ve así; adelante y ejecútelo. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Salida del comando" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +El sistema inició el contenedor, ejecutó el comando `cowpy` con sus parámetros, envió la salida a la consola y finalmente, apagó la instancia del contenedor. + +### 1.3. Usar el contenedor para ejecutar `cowpy` interactivamente + +También puede ejecutar un contenedor interactivamente, lo que le da un prompt de shell dentro del contenedor y le permite jugar con el comando. + +#### 1.3.1. Iniciar el contenedor + +Para ejecutar interactivamente, solo agregamos `-it` al comando `docker run`. +Opcionalmente, podemos especificar el shell que queremos usar dentro del contenedor agregando _ej._ `/bin/bash` al comando. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Note que su prompt cambia a algo como `(base) root@b645838b3314:/tmp#`, lo que indica que ahora está dentro del contenedor. + +Puede verificar esto ejecutando `ls /` para listar el contenido del directorio desde la raíz del sistema de archivos: + +```bash +ls / +``` + +??? abstract "Salida del comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Usamos `ls` aquí en lugar de `tree` porque la utilidad `tree` no está disponible en este contenedor. +Puede ver que el sistema de archivos dentro del contenedor es diferente del sistema de archivos en su sistema host. + +Una limitación de lo que acabamos de hacer es que el contenedor está completamente aislado del sistema host por defecto. +Esto significa que el contenedor no puede acceder a ningún archivo en el sistema host a menos que explícitamente se lo permita. + +Le mostraremos cómo hacer eso en un minuto. + +#### 1.3.2. Ejecutar el/los comando(s) de la herramienta deseada + +Ahora que está dentro del contenedor, puede ejecutar el comando `cowpy` directamente y darle algunos parámetros. +Por ejemplo, la documentación de la herramienta dice que podemos cambiar el personaje ('cowacter') con `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Salida del comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Ahora la salida muestra el pingüino de Linux, Tux, en lugar de la vaca predeterminada, porque especificamos el parámetro `-c tux`. + +Como está dentro del contenedor, puede ejecutar el comando `cowpy` tantas veces como quiera, variando los parámetros de entrada, sin tener que molestarse con los comandos de Docker. + +!!! Tip "Consejo" + + Use la bandera '-c' para elegir un personaje diferente, incluyendo: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Esto es genial. Lo que sería aún más genial es si pudiéramos alimentar nuestro `greetings.csv` como entrada en esto. +Pero como no tenemos acceso al sistema de archivos, no podemos. + +Arreglemos eso. + +#### 1.3.3. Salir del contenedor + +Para salir del contenedor, puede escribir `exit` en el prompt o usar el atajo de teclado ++ctrl+d++. + +```bash +exit +``` + +Su prompt ahora debería estar de vuelta a lo que era antes de que iniciara el contenedor. + +#### 1.3.4. Montar datos en el contenedor + +Como se señaló anteriormente, el contenedor está aislado del sistema host por defecto. + +Para permitir que el contenedor acceda al sistema de archivos del host, puede **montar** un **volumen** desde el sistema host en el contenedor usando la siguiente sintaxis: + +```bash title="Sintaxis" +-v <outside_path>:<inside_path> +``` + +En nuestro caso `<outside_path>` será el directorio de trabajo actual, así que podemos simplemente usar un punto (`.`), y `<inside_path>` es solo un alias que inventamos; llamémoslo `/my_project` (la ruta interna debe ser absoluta). + +Para montar un volumen, reemplazamos las rutas y agregamos el argumento de montaje de volumen al comando docker run de la siguiente manera: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Esto monta el directorio de trabajo actual como un volumen que será accesible bajo `/my_project` dentro del contenedor. + +Puede verificar que funciona listando el contenido de `/my_project`: + +```bash +ls /my_project +``` + +??? success "Salida del comando" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Ahora puede ver el contenido del directorio de trabajo desde dentro del contenedor, incluyendo el archivo `greetings.csv` bajo `data/`. + +Esto efectivamente estableció un túnel a través de la pared del contenedor que puede usar para acceder a esa parte de su sistema de archivos. + +#### 1.3.5. Usar los datos montados + +Ahora que hemos montado el directorio de trabajo en el contenedor, podemos usar el comando `cowpy` para mostrar el contenido del archivo `greetings.csv`. + +Para hacer esto, usaremos `cat /my_project/data/greetings.csv | ` para canalizar el contenido del archivo CSV al comando `cowpy`. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Salida del comando" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +¡Esto produce el arte ASCII deseado de un pavo recitando nuestros saludos de ejemplo! +Excepto que aquí el pavo está repitiendo las filas completas en lugar de solo los saludos. +¡Ya sabemos que nuestro flujo de trabajo de Nextflow hará un mejor trabajo! + +Siéntase libre de jugar con este comando. +Cuando haya terminado, salga del contenedor como anteriormente: + +```bash +exit +``` + +Se encontrará de vuelta en su shell normal. + +### Conclusión + +Sabe cómo descargar un contenedor y ejecutarlo ya sea como un comando único o interactivamente. También sabe cómo hacer que sus datos sean accesibles desde dentro de su contenedor, lo que le permite probar cualquier herramienta que le interese en datos reales sin tener que instalar ningún software en su sistema. + +### ¿Qué sigue? + +Aprender cómo usar contenedores para la ejecución de procesos de Nextflow. + +--- + +## 2. Usar contenedores en Nextflow + +Nextflow tiene soporte integrado para ejecutar procesos dentro de contenedores para permitirle ejecutar herramientas que no tiene instaladas en su entorno de cómputo. +Esto significa que puede usar cualquier imagen de contenedor que desee para ejecutar sus procesos, y Nextflow se encargará de descargar la imagen, montar los datos y ejecutar el proceso dentro de ella. + +Para demostrar esto, vamos a agregar un paso `cowpy` al pipeline que hemos estado desarrollando, después del paso `collectGreetings`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +¡Muu si está listo para sumergirse! + +### 2.1. Escribir un módulo `cowpy` + +Primero, creemos el módulo del proceso `cowpy`. + +#### 2.1.1. Crear un archivo stub para el nuevo módulo + +Cree un archivo vacío para el módulo llamado `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +Esto nos da un lugar para poner el código del proceso. + +#### 2.1.2. Copiar el código del proceso `cowpy` en el archivo del módulo + +Podemos modelar nuestro proceso `cowpy` en los otros procesos que hemos escrito anteriormente. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generar arte ASCII con cowpy +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +El proceso espera un `input_file` que contiene los saludos así como un valor `character`. + +La salida será un nuevo archivo de texto que contiene el arte ASCII generado por la herramienta `cowpy`. + +### 2.2. Agregar cowpy al flujo de trabajo + +Ahora necesitamos importar el módulo y llamar al proceso. + +#### 2.2.1. Importar el proceso `cowpy` en `hello-containers.nf` + +Inserte la declaración de importación arriba del bloque workflow y complétela apropiadamente. + +=== "Después" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="3" + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Ahora el módulo `cowpy` está disponible para usar en el flujo de trabajo. + +#### 2.2.2. Agregar una llamada al proceso `cowpy` en el flujo de trabajo + +Conectemos el proceso `cowpy()` a la salida del proceso `collectGreetings()`, que como recordará produce dos salidas: + +- `collectGreetings.out.outfile` contiene el archivo de salida <--_lo que queremos_ +- `collectGreetings.out.report` contiene el archivo de reporte con el conteo de saludos por lote + +En el bloque workflow, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Note que declaramos un nuevo parámetro CLI, `params.character`, para especificar qué personaje queremos que diga los saludos. + +#### 2.2.3. Agregar el parámetro `character` al bloque `params` + +Esto es técnicamente opcional pero es la práctica recomendada y es una oportunidad para establecer un valor predeterminado para el personaje mientras estamos en ello. + +=== "Después" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Ahora podemos ser perezosos y omitir escribir el parámetro character en nuestras líneas de comando. + +#### 2.2.4. Actualizar las salidas del flujo de trabajo + +Necesitamos actualizar las salidas del flujo de trabajo para publicar la salida del proceso `cowpy`. + +##### 2.2.4.1. Actualizar la sección `publish:` + +En el bloque `workflow`, haga el siguiente cambio de código: + +=== "Después" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +El proceso `cowpy` solo produce una salida así que podemos referirnos a ella de la manera usual agregando `.out`. + +Pero por ahora, terminemos de actualizar las salidas a nivel de flujo de trabajo. + +##### 2.2.4.2. Actualizar el bloque `output` + +Necesitamos agregar la salida final `cowpy_art` al bloque `output`. Mientras estamos en ello, también editemos los destinos de publicación ya que ahora nuestro pipeline está completo y sabemos qué salidas realmente nos importan. + +En el bloque `output`, haga los siguientes cambios de código: + +=== "Después" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Ahora las salidas publicadas estarán un poco más organizadas. + +#### 2.2.5. Ejecutar el flujo de trabajo + +Solo para recapitular, esto es lo que estamos buscando: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +¿Cree que va a funcionar? + +Eliminemos las salidas publicadas anteriores para tener una pizarra limpia, y ejecutemos el flujo de trabajo con la bandera `-resume`. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Salida del comando (editada para claridad)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +¡Oh no, hay un error! +El código de error dado por `error exit status (127)` significa que el ejecutable que pedimos no fue encontrado. + +Eso tiene sentido, ya que estamos llamando a la herramienta `cowpy` pero en realidad no hemos especificado un contenedor todavía (ups). + +### 2.3. Usar un contenedor para ejecutar el proceso `cowpy` + +Necesitamos especificar un contenedor y decirle a Nextflow que lo use para el proceso `cowpy()`. + +#### 2.3.1. Especificar un contenedor para `cowpy` + +Podemos usar la misma imagen que estábamos usando directamente en la primera sección de este tutorial. + +Edite el módulo `cowpy.nf` para agregar la directiva `container` a la definición del proceso de la siguiente manera: + +=== "Después" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Esto le dice a Nextflow que _si el uso de Docker está habilitado_, debería usar la imagen de contenedor especificada aquí para ejecutar el proceso. + +#### 2.3.2. Habilitar el uso de Docker a través del archivo `nextflow.config` + +Note que dijimos _'si el uso de Docker está habilitado'_. Por defecto, no lo está, así que necesitamos decirle a Nextflow que está permitido usar Docker. +Para ese fin, vamos a anticipar ligeramente el tema de la siguiente y última parte de este curso (Parte 6), que cubre la configuración. + +Una de las principales formas que ofrece Nextflow para configurar la ejecución del flujo de trabajo es usar un archivo `nextflow.config`. +Cuando tal archivo está presente en el directorio actual, Nextflow lo cargará automáticamente y aplicará cualquier configuración que contenga. + +Proporcionamos un archivo `nextflow.config` con una única línea de código que explícitamente deshabilita Docker: `docker.enabled = false`. + +Ahora, cambiemos eso a `true` para habilitar Docker: + +=== "Después" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Antes" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Consejo" + + Es posible habilitar la ejecución de Docker desde la línea de comandos, por ejecución, usando el parámetro `-with-docker <container>`. + Sin embargo, eso solo nos permite especificar un contenedor para todo el flujo de trabajo, mientras que el enfoque que acabamos de mostrarle nos permite especificar un contenedor diferente por proceso. + Esto es mejor para la modularidad, el mantenimiento del código y la reproducibilidad. + +#### 2.3.3. Ejecutar el flujo de trabajo con Docker habilitado + +Ejecute el flujo de trabajo con la bandera `-resume`: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +¡Esta vez sí funciona! +Como siempre puede encontrar las salidas del flujo de trabajo en el directorio de resultados correspondiente, aunque esta vez están un poco más organizadas, con solo el reporte y la salida final en el nivel superior, y todos los archivos intermedios apartados en un subdirectorio. + +??? abstract "Contenido del directorio" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +La salida final de arte ASCII está en el directorio `results/hello_containers/`, bajo el nombre `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Y ahí está, nuestro hermoso pavo diciendo los saludos como se deseaba. + +#### 2.3.4. Inspeccionar cómo Nextflow lanzó la tarea containerizada + +Como coda final a esta sección, echemos un vistazo al subdirectorio de trabajo para una de las llamadas del proceso `cowpy` para obtener un poco más de información sobre cómo Nextflow trabaja con contenedores bajo el capó. + +Verifique la salida de su comando `nextflow run` para encontrar la ruta al subdirectorio de trabajo para el proceso `cowpy`. +Mirando lo que obtuvimos para la ejecución mostrada arriba, la línea del log de consola para el proceso `cowpy` comienza con `[98/656c6c]`. +Eso corresponde a la siguiente ruta de directorio truncada: `work/98/656c6c`. + +En ese directorio, encontrará el archivo `.command.run` que contiene todos los comandos que Nextflow ejecutó en su nombre durante el curso de la ejecución del pipeline. + +??? abstract "Contenido del archivo" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Si busca `nxf_launch` en este archivo, debería ver algo como esto: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Como puede ver, Nextflow está usando el comando `docker run` para lanzar la llamada del proceso. +También monta el subdirectorio de trabajo correspondiente en el contenedor, establece el directorio de trabajo dentro del contenedor en consecuencia, y ejecuta nuestro script bash plantillado en el archivo `.command.sh`. + +¡Todo el trabajo duro que tuvimos que hacer manualmente en la primera sección? ¡Nextflow lo hace por nosotros detrás de escenas! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Conclusión + +Sabe cómo usar contenedores en Nextflow para ejecutar procesos. + +### ¿Qué sigue? + +¡Tome un descanso! + +Cuando esté listo, continúe con [**Parte 6: Hello Config**](./06_hello_config.md) para aprender cómo configurar la ejecución de su pipeline para adaptarse a su infraestructura así como gestionar la configuración de entradas y parámetros. + +¡Es la última parte, y luego habrá terminado con este curso! + +--- + +## Cuestionario + +<quiz> +¿Qué es un contenedor? +- [ ] Un tipo de máquina virtual +- [ ] Un formato de compresión de archivos +- [x] Una unidad ejecutable ligera e independiente que incluye todo lo necesario para ejecutar una aplicación +- [ ] Un protocolo de red +</quiz> + +<quiz> +¿Cuál es la diferencia entre una imagen de contenedor y una instancia de contenedor? +- [ ] Son lo mismo +- [x] Una imagen es una plantilla; una instancia es un contenedor en ejecución creado a partir de esa imagen +- [ ] Una instancia es una plantilla; una imagen es un contenedor en ejecución +- [ ] Las imágenes son para Docker; las instancias son para Singularity +</quiz> + +<quiz> +¿Qué hace la bandera `-v` en un comando `docker run`? +- [ ] Habilita salida verbosa +- [ ] Valida el contenedor +- [x] Monta un volumen del sistema host en el contenedor +- [ ] Especifica la versión del contenedor + +Aprenda más: [1.3.4. Montar datos en el contenedor](#134-montar-datos-en-el-contenedor) +</quiz> + +<quiz> +¿Por qué necesita montar volúmenes cuando usa contenedores? +- [ ] Para mejorar el rendimiento del contenedor +- [ ] Para ahorrar espacio en disco +- [x] Porque los contenedores están aislados del sistema de archivos del host por defecto +- [ ] Para habilitar la red + +Aprenda más: [1.3.4. Montar datos en el contenedor](#134-montar-datos-en-el-contenedor) +</quiz> + +<quiz> +¿Cómo especifica un contenedor para un proceso de Nextflow? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Aprenda más: [2.3.1. Especificar un contenedor para cowpy](#231-especificar-un-contenedor-para-cowpy) +</quiz> + +<quiz> +¿Qué configuración de `nextflow.config` habilita Docker para su flujo de trabajo? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Aprenda más: [2.3.2. Habilitar el uso de Docker a través del archivo `nextflow.config`](#232-habilitar-el-uso-de-docker-a-traves-del-archivo-nextflowconfig) +</quiz> + +<quiz> +¿Qué maneja automáticamente Nextflow cuando ejecuta un proceso en un contenedor? (Seleccione todos los que apliquen) +- [x] Descargar la imagen del contenedor si es necesario +- [x] Montar el directorio de trabajo +- [x] Ejecutar el script del proceso dentro del contenedor +- [x] Limpiar la instancia del contenedor después de la ejecución + +Aprenda más: [2.3.4. Inspeccionar cómo Nextflow lanzó la tarea containerizada](#234-inspeccionar-como-nextflow-lanzo-la-tarea-containerizada) +</quiz> diff --git a/docs/es/docs/hello_nextflow/06_hello_config.md b/docs/es/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..b2d211f06e --- /dev/null +++ b/docs/es/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# Parte 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea [la lista de reproducción completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) en el canal de YouTube de Nextflow. + +:green_book: La transcripción del video está disponible [aquí](./transcripts/06_hello_config.md). +/// + +Esta sección explorará cómo configurar y gestionar la configuración de su pipeline de Nextflow para que pueda personalizar su comportamiento, adaptarlo a diferentes entornos y optimizar el uso de recursos _sin alterar una sola línea del código del flujo de trabajo en sí_. + +Hay múltiples formas de hacer esto, que pueden usarse en combinación y se interpretan según el orden de precedencia descrito [aquí](https://www.nextflow.io/docs/latest/config.html). + +En esta parte del curso, vamos a mostrarle el mecanismo de archivo de configuración más simple y común, el archivo `nextflow.config`, que ya encontró en la Parte 5: Hola Containers. + +Repasaremos los componentes esenciales de la configuración de Nextflow como directivas de proceso, executors, perfiles y archivos de parámetros. +Al aprender a utilizar estas opciones de configuración efectivamente, puede mejorar la flexibilidad, escalabilidad y rendimiento de sus pipelines. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado las Partes 1-5 del curso [Hello Nextflow](./index.md) y tiene un pipeline completo funcionando. + + Si está comenzando el curso desde este punto, necesitará copiar el directorio `modules` y el archivo `nextflow.config` desde las soluciones: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + El archivo `nextflow.config` contiene la línea `docker.enabled = true` que habilita el uso de contenedores Docker. + + Si no está familiarizado con el pipeline Hello o podría usar un recordatorio, vea [esta página de información](../info/hello_pipeline.md). + +--- + +## 0. Calentamiento: Ejecutar `hello-config.nf` + +Vamos a usar el script de workflow `hello-config.nf` como punto de partida. +Es equivalente al script producido al trabajar en la Parte 5 de este curso de entrenamiento, excepto que hemos cambiado los destinos de salida: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Solo para asegurarse de que todo funciona, ejecute el script una vez antes de hacer cualquier cambio: + +```bash +nextflow run hello-config.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Como anteriormente, encontrará los archivos de salida en el directorio especificado en el bloque `output` (`results/hello_config/`). + +??? abstract "Contenido del directorio" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +La salida final de arte ASCII está en el directorio `results/hello_config/`, bajo el nombre `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Si eso funcionó para usted, está listo para aprender cómo configurar sus pipelines. + +--- + +## 1. Gestionar parámetros de entrada del flujo de trabajo + +Vamos a comenzar con un aspecto de la configuración que es simplemente una extensión de lo que hemos estado trabajando hasta ahora: la gestión de parámetros de entrada. + +Actualmente, nuestro flujo de trabajo está configurado para aceptar varios valores de parámetros a través de la línea de comandos, con valores predeterminados establecidos en un bloque `params` en el script del flujo de trabajo mismo. +Sin embargo, podría querer sobrescribir esos valores predeterminados sin tener que especificar parámetros en la línea de comandos ni modificar el archivo de script original. + +Hay múltiples formas de hacer eso; vamos a mostrarle tres formas básicas que son muy comúnmente usadas. + +### 1.1. Mover valores predeterminados a `nextflow.config` + +Este es el enfoque más simple, aunque posiblemente sea el menos flexible ya que el archivo `nextflow.config` principal no es algo que quiera estar editando para cada ejecución. +Pero tiene la ventaja de separar las preocupaciones de _declarar_ los parámetros en el flujo de trabajo (que definitivamente pertenece allí) versus suministrar _valores predeterminados_, que están más en casa en un archivo de configuración. + +Hagamos esto en dos pasos. + +#### 1.1.1. Crear un bloque `params` en el archivo de configuración + +Haga los siguientes cambios de código en el archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Parámetros del pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Note que no simplemente copiamos el bloque `params` del flujo de trabajo al archivo de configuración. +La sintaxis es un poco diferente. +En el archivo de flujo de trabajo, esas son declaraciones tipadas. +En la configuración, esas son asignaciones de valores. + +Técnicamente, esto es suficiente para sobrescribir los valores predeterminados aún especificados en el archivo de flujo de trabajo. +Podría modificar el personaje, por ejemplo, y ejecutar el flujo de trabajo para comprobar que el valor establecido en el archivo de configuración sobrescribe el establecido en el archivo de flujo de trabajo. + +Pero en el espíritu de mover la configuración completamente al archivo de configuración, eliminemos esos valores del archivo de flujo de trabajo por completo. + +#### 1.1.2. Eliminar los valores del bloque `params` en el archivo de flujo de trabajo + +Haga los siguientes cambios de código en el archivo de flujo de trabajo `hello-config.nf`: + +=== "Después" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Parámetros del pipeline + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Parámetros del pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Ahora el archivo de flujo de trabajo mismo no establece ningún valor predeterminado para estos parámetros. + +#### 1.1.3. Ejecutar el pipeline + +Probemos que funciona correctamente. + +```bash +nextflow run hello-config.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente. + +La salida final de arte ASCII está en el directorio `results/hello_config/`, bajo el nombre `cowpy-COLLECTED-batch-output.txt`, igual que antes. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funcionalmente, este movimiento no ha cambiado nada, pero conceptualmente es un poco más limpio tener los valores predeterminados establecidos en el archivo de configuración. + +### 1.2. Usar un archivo de configuración específico de ejecución + +Eso es genial, pero a veces podría querer ejecutar algunos experimentos temporales con diferentes valores predeterminados sin tocar el archivo de configuración principal. +Puede hacer eso creando un nuevo archivo `nextflow.config` en un subdirectorio que usará como directorio de trabajo para sus experimentos. + +#### 1.2.1. Crear el directorio de trabajo con una configuración en blanco + +Comencemos creando un nuevo directorio y entrando en él: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Luego, cree un archivo de configuración en blanco en ese directorio: + +```bash +touch nextflow.config +``` + +Esto produce un archivo vacío. + +#### 1.2.2. Configurar la configuración experimental + +Ahora abra el nuevo archivo y agregue los parámetros que quiere personalizar: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Note que la ruta al archivo de entrada debe reflejar la estructura de directorios. + +#### 1.2.3. Ejecutar el pipeline + +Ahora podemos ejecutar nuestro pipeline desde dentro de nuestro nuevo directorio de trabajo. +¡Asegúrese de adaptar la ruta en consecuencia! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Esto creará un nuevo conjunto de directorios bajo `tux-run/` incluyendo `tux-run/work/` y `tux-run/results/`. + +En esta ejecución, Nextflow combina el `nextflow.config` en nuestro directorio actual con el `nextflow.config` en el directorio raíz del pipeline, y así sobrescribe el personaje predeterminado (turkey) con el personaje tux. + +El archivo de salida final debería contener el personaje tux diciendo los saludos. + +??? abstract "Contenido del archivo" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Eso es todo; ahora tiene un espacio para experimentar sin modificar su configuración 'normal'. + +!!! warning "Advertencia" + + ¡Asegúrese de volver al directorio anterior antes de pasar a la siguiente sección! + + ```bash + cd .. + ``` + +Ahora veamos otra forma útil de establecer valores de parámetros. + +### 1.3. Usar un archivo de parámetros + +El enfoque del subdirectorio funciona muy bien para experimentar, pero involucra un poco de configuración y requiere que adapte las rutas en consecuencia. +Hay un enfoque más simple para cuando quiere ejecutar su pipeline con un conjunto específico de valores, o permitir que alguien más lo haga con mínimo esfuerzo. + +Nextflow nos permite especificar parámetros a través de un archivo de parámetros en formato YAML o JSON, lo que hace muy conveniente gestionar y distribuir conjuntos alternativos de valores predeterminados, por ejemplo, así como valores de parámetros específicos de ejecución. + +#### 1.3.1. Examinar el archivo de parámetros de ejemplo + +Para demostrar esto, proporcionamos un archivo de parámetros de ejemplo en el directorio actual, llamado `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Este archivo de parámetros contiene un par clave-valor para cada una de las entradas que queremos especificar. +Note el uso de dos puntos (`:`) en lugar de signos de igual (`=`) si compara la sintaxis con el archivo de configuración. +El archivo de configuración está escrito en Groovy, mientras que el archivo de parámetros está escrito en YAML. + +!!! info "Información" + + También proporcionamos una versión JSON del archivo de parámetros como ejemplo pero no vamos a ejecutarla aquí. + Siéntase libre de probar esa por su cuenta. + +#### 1.3.2. Ejecutar el pipeline + +Para ejecutar el flujo de trabajo con este archivo de parámetros, simplemente agregue `-params-file <filename>` al comando base. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +El archivo de salida final debería contener el personaje stegosaurus diciendo los saludos. + +??? abstract "Contenido del archivo" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usar un archivo de parámetros puede parecer excesivo cuando solo tiene unos pocos parámetros para especificar, pero algunos pipelines esperan docenas de parámetros. +En esos casos, usar un archivo de parámetros nos permitirá proporcionar valores de parámetros en tiempo de ejecución sin tener que escribir líneas de comando masivas y sin modificar el script de flujo de trabajo. + +También hace más fácil distribuir conjuntos de parámetros a colaboradores, o como información de soporte para una publicación, por ejemplo. +Esto hace que su trabajo sea más reproducible por otros. + +### Conclusión + +Sabe cómo aprovechar las opciones de configuración clave para gestionar entradas de flujo de trabajo. + +### ¿Qué sigue? + +Aprender cómo gestionar dónde y cómo se publican las salidas de su flujo de trabajo. + +--- + +## 2. Gestionar salidas del flujo de trabajo + +Hasta ahora hemos estado codificando todas las rutas para las declaraciones de salida a nivel de flujo de trabajo, y como notamos cuando comenzamos a agregar múltiples salidas, puede haber un poco de repetición involucrada. + +Veamos algunas formas comunes en que podría configurar esto para ser más flexible. + +### 2.1. Personalizar el nombre del directorio `outputDir` + +Para cada capítulo de este curso, hemos estado publicando salidas a un subdirectorio diferente codificado en las definiciones de salida. + +Cambiemos eso para usar un parámetro configurable por el usuario. +Podríamos crear un parámetro completamente nuevo para esto, pero usemos el parámetro `batch` ya que está justo ahí. + +#### 2.1.1. Establecer un valor para `outputDir` en el archivo de configuración + +La ruta que Nextflow usa para publicar salidas está controlada por la opción `outputDir`. +Para cambiar la ruta para todas las salidas, puede establecer un valor para esta opción en el archivo de configuración `nextflow.config`. + +Agregue el siguiente código al archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Parámetros del pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Configuración de salida + */ + outputDir = "results/${params.batch}" + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="9" + /* + * Parámetros del pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Esto reemplazará la ruta predeterminada incorporada, `results/`, con `results/` más el valor del parámetro `batch` como subdirectorio. +También podría cambiar la parte `results` si quisiera. + +Para un cambio temporal, podría establecer esta opción desde la línea de comandos usando el parámetro `-output-dir` en su comando (pero entonces no podría usar el valor del parámetro `batch`). + +#### 2.1.2. Eliminar la parte repetida de la ruta codificada + +Todavía tenemos un subdirectorio codificado en las opciones de salida, así que deshagámonos de eso ahora. + +Haga los siguientes cambios de código en el archivo de flujo de trabajo: + +=== "Después" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +También podríamos haber simplemente agregado `${params.batch}` a cada ruta en lugar de modificar el `outputDir` predeterminado, pero esto es más conciso. + +#### 2.1.3. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `outdir` desde la línea de comandos. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/outdir/`. + +??? abstract "Contenido del directorio" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Puede combinar este enfoque con definiciones de ruta personalizadas para construir cualquier jerarquía de directorios que desee. + +### 2.2. Organizar salidas por proceso + +Una forma popular de organizar las salidas aún más es hacerlo por proceso, _es decir_, crear subdirectorios para cada proceso ejecutado en el pipeline. + +#### 2.2.1. Reemplazar las rutas de salida por una referencia a los nombres de proceso + +Todo lo que necesita hacer es referenciar el nombre del proceso como `<task>.name` en la declaración de ruta de salida. + +Haga los siguientes cambios en el archivo de flujo de trabajo: + +=== "Después" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Esto elimina los elementos codificados restantes de la configuración de ruta de salida. + +#### 2.2.2. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `pnames` desde la línea de comandos. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/pnames/`, y están agrupadas por proceso. + +??? abstract "Contenido del directorio" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Note que aquí hemos borrado la distinción entre `intermediates` versus salidas finales siendo en el nivel superior. +Por supuesto podría mezclar y combinar estos enfoques, por ejemplo estableciendo la ruta de la primera salida como `intermediates/${sayHello.process}` + +### 2.3. Establecer el modo de publicación a nivel de flujo de trabajo + +Finalmente, en el espíritu de reducir la cantidad de código repetitivo, podemos reemplazar las declaraciones `mode` por salida con una única línea en la configuración. + +#### 2.3.1. Agregar `workflow.output.mode` al archivo de configuración + +Agregue el siguiente código al archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Configuración de salida + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="12" + /* + * Configuración de salida + */ + outputDir = "results/${params.batch}" + ``` + +Al igual que la opción `outputDir`, dar un valor a `workflow.output.mode` en el archivo de configuración sería suficiente para sobrescribir lo que está establecido en el archivo de flujo de trabajo, pero eliminemos el código innecesario de todos modos. + +#### 2.3.2. Eliminar el modo de salida del archivo de flujo de trabajo + +Haga los siguientes cambios en el archivo de flujo de trabajo: + +=== "Después" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +Eso es más conciso, ¿no? + +#### 2.3.3. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `outmode` desde la línea de comandos. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/outmode/`. +Siguen siendo todas copias apropiadas, no enlaces simbólicos. + +??? abstract "Contenido del directorio" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +La razón principal por la que aún podría querer usar la forma por salida de establecer el modo es si quiere mezclar y combinar dentro del mismo flujo de trabajo, _es decir_, tener algunas salidas copiadas y algunas enlazadas simbólicamente. + +Hay muchas otras opciones que puede personalizar de esta manera, pero esperamos que esto le dé una idea del rango de opciones y cómo utilizarlas efectivamente para adaptarse a sus preferencias. + +### Conclusión + +Sabe cómo controlar el nombre y la estructura de los directorios donde se publican sus salidas, así como el modo de publicación de salida del flujo de trabajo. + +### ¿Qué sigue? + +Aprender cómo adaptar la configuración de su flujo de trabajo a su entorno de cómputo, comenzando con la tecnología de empaquetado de software. + +--- + +## 3. Seleccionar una tecnología de empaquetado de software + +Hasta ahora hemos estado viendo elementos de configuración que controlan cómo entran las entradas y de dónde salen las salidas. Ahora es tiempo de enfocarnos más específicamente en adaptar la configuración de su flujo de trabajo a su entorno de cómputo. + +El primer paso en ese camino es especificar de dónde van a venir los paquetes de software que se ejecutarán en cada paso. +¿Ya están instalados en el entorno de cómputo local? +¿Necesitamos recuperar imágenes y ejecutarlas a través de un sistema de contenedores? +¿O necesitamos recuperar paquetes Conda y construir un entorno Conda local? + +En la primera parte de este curso de entrenamiento (Partes 1-4) solo usamos software instalado localmente en nuestro flujo de trabajo. +Luego en la Parte 5, introdujimos contenedores Docker y el archivo `nextflow.config`, que usamos para habilitar el uso de contenedores Docker. + +Ahora veamos cómo podemos configurar una opción alternativa de empaquetado de software a través del archivo `nextflow.config`. + +### 3.1. Deshabilitar Docker y habilitar Conda en el archivo de configuración + +Imaginemos que estamos trabajando en un clúster HPC y el administrador no permite el uso de Docker por razones de seguridad. +Afortunadamente para nosotros, Nextflow soporta múltiples otras tecnologías de contenedores incluyendo Singularity (que es más ampliamente usado en HPC), y gestores de paquetes de software como Conda. + +Podemos cambiar nuestro archivo de configuración para usar Conda en lugar de Docker. +Para hacerlo, cambiemos el valor de `docker.enabled` a `false`, y agreguemos una directiva habilitando el uso de Conda: + +=== "Después" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Esto permitirá a Nextflow crear y utilizar entornos Conda para procesos que tienen paquetes Conda especificados. +Lo que significa que ahora necesitamos agregar uno de esos a nuestro proceso `cowpy`! + +### 3.2. Especificar un paquete Conda en la definición del proceso + +Ya hemos recuperado el URI para un paquete Conda que contiene la herramienta `cowpy`: `conda-forge::cowpy==1.1.5` + +Ahora agregamos el URI a la definición del proceso `cowpy` usando la directiva `conda`: + +=== "Después" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Para ser claros, no estamos _reemplazando_ la directiva `docker`, estamos _agregando_ una opción alternativa. + +!!! tip "Consejo" + + Hay algunas formas diferentes de obtener el URI para un paquete conda dado. + Recomendamos usar la consulta de búsqueda de [Seqera Containers](https://seqera.io/containers/), que le dará un URI que puede copiar y pegar, incluso si no planea crear un contenedor a partir de él. + +### 3.3. Ejecutar el flujo de trabajo para verificar que puede usar Conda + +Probémoslo. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Salida del comando" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Esto debería funcionar sin problemas y producir las mismas salidas que anteriormente bajo `results/conda`. + +Detrás de escenas, Nextflow ha recuperado los paquetes Conda y creado el entorno, lo cual normalmente toma un poco de trabajo; ¡así que es bueno que no tengamos que hacer nada de eso nosotros mismos! + +!!! note "Nota" + + Esto se ejecuta rápidamente porque el paquete `cowpy` es bastante pequeño, pero si está trabajando con paquetes grandes, puede tomar un poco más de lo usual la primera vez, y podría ver la salida de la consola quedarse 'atascada' por un minuto más o menos antes de completarse. + Esto es normal y se debe al trabajo extra que Nextflow hace la primera vez que usa un nuevo paquete. + +Desde nuestro punto de vista, parece que funciona exactamente igual que ejecutar con Docker, aunque en el backend la mecánica es un poco diferente. + +Esto significa que estamos listos para ejecutar con entornos Conda si es necesario. + +??? info "Mezclar y combinar Docker y Conda" + + Ya que estas directivas se asignan por proceso, es posible 'mezclar y combinar', _es decir_, configurar algunos de los procesos en su flujo de trabajo para ejecutar con Docker y otros con Conda, por ejemplo, si la infraestructura de cómputo que está usando soporta ambos. + En ese caso, habilitaría tanto Docker como Conda en su archivo de configuración. + Si ambos están disponibles para un proceso dado, Nextflow priorizará contenedores. + + Y como se señaló anteriormente, Nextflow soporta múltiples otras tecnologías de empaquetado de software y contenedores, así que no está limitado a solo esas dos. + +### Conclusión + +Sabe cómo configurar qué paquete de software debería usar cada proceso, y cómo cambiar entre tecnologías. + +### ¿Qué sigue? + +Aprender cómo cambiar la plataforma de ejecución usada por Nextflow para realmente hacer el trabajo. + +--- + +## 4. Seleccionar una plataforma de ejecución + +Hasta ahora, hemos estado ejecutando nuestro pipeline con el executor local. +Esto ejecuta cada tarea en la máquina donde Nextflow está corriendo. +Cuando Nextflow comienza, mira los CPUs y memoria disponibles. +Si los recursos de las tareas listas para ejecutar exceden los recursos disponibles, Nextflow retendrá las últimas tareas de la ejecución hasta que una o más de las tareas anteriores hayan terminado, liberando los recursos necesarios. + +El executor local es conveniente y eficiente, pero está limitado a esa única máquina. Para cargas de trabajo muy grandes, puede descubrir que su máquina local es un cuello de botella, ya sea porque tiene una única tarea que requiere más recursos de los que tiene disponibles, o porque tiene tantas tareas que esperar a que una sola máquina las ejecute tomaría demasiado tiempo. + +Nextflow soporta [muchos backends de ejecución diferentes](https://www.nextflow.io/docs/latest/executor.html), incluyendo programadores HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor y otros) así como backends de ejecución en la nube (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes y más). + +### 4.1. Apuntar a un backend diferente + +La elección del executor se establece por una directiva de proceso llamada `executor`. +Por defecto está establecido a `local`, así que la siguiente configuración está implícita: + +```groovy title="Configuración incorporada" +process { + executor = 'local' +} +``` + +Para establecer el executor para apuntar a un backend diferente, simplemente especificaría el executor que quiere usando sintaxis similar a la descrita arriba para asignaciones de recursos (vea la [documentación](https://www.nextflow.io/docs/latest/executor.html) para todas las opciones). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Advertencia" + + En realidad no podemos probar esto en el entorno de entrenamiento porque no está configurado para conectarse a un HPC. + +### 4.2. Lidiar con sintaxis específica del backend para parámetros de ejecución + +La mayoría de las plataformas de computación de alto rendimiento permiten (y a veces requieren) que especifique ciertos parámetros como solicitudes y limitaciones de asignación de recursos (por ej. número de CPUs y memoria) y nombre de la cola de trabajos a usar. + +Desafortunadamente, cada uno de estos sistemas usa diferentes tecnologías, sintaxis y configuraciones para definir cómo un trabajo debería ser definido y enviado al programador relevante. + +??? abstract "Ejemplos" + + Por ejemplo, el mismo trabajo que requiere 8 CPUs y 4GB de RAM para ser ejecutado en la cola "my-science-work" necesita ser expresado de diferentes maneras dependiendo del backend. + + ```bash title="Config para SLURM / enviar usando sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config para PBS / enviar usando qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config para SGE / enviar usando qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Afortunadamente, Nextflow simplifica todo esto. +Proporciona una sintaxis estandarizada para que pueda especificar las propiedades relevantes como `cpus`, `memory` y `queue` (vea la documentación para otras propiedades) solo una vez. +Luego, en tiempo de ejecución, Nextflow usará esas configuraciones para generar los scripts específicos del backend apropiados basados en la configuración del executor. + +Cubriremos esa sintaxis estandarizada en la siguiente sección. + +### Conclusión + +Ahora sabe cómo cambiar el executor para usar diferentes tipos de infraestructura de cómputo. + +### ¿Qué sigue? + +Aprender cómo evaluar y expresar asignaciones y limitaciones de recursos en Nextflow. + +--- + +## 5. Controlar asignaciones de recursos de cómputo + +La mayoría de las plataformas de computación de alto rendimiento permiten (y a veces requieren) que especifique ciertos parámetros de asignación de recursos como número de CPUs y memoria. + +Por defecto, Nextflow usará un único CPU y 2GB de memoria para cada proceso. +Las directivas de proceso correspondientes se llaman `cpus` y `memory`, así que la siguiente configuración está implícita: + +```groovy title="Configuración incorporada" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Puede modificar estos valores, ya sea para todos los procesos o para procesos nombrados específicos, usando directivas de proceso adicionales en su archivo de configuración. +Nextflow las traducirá a las instrucciones apropiadas para el executor elegido. + +¿Pero cómo sabe qué valores usar? + +### 5.1. Ejecutar el flujo de trabajo para generar un reporte de utilización de recursos + +Si no sabe de antemano cuánto CPU y memoria es probable que necesiten sus procesos, puede hacer algo de perfilado de recursos, lo que significa que ejecuta el flujo de trabajo con algunas asignaciones predeterminadas, registra cuánto usó cada proceso, y de ahí, estima cómo ajustar las asignaciones base. + +Convenientemente, Nextflow incluye herramientas incorporadas para hacer esto, y felizmente generará un reporte para usted cuando lo solicite. + +Para hacerlo, agregue `-with-report <filename>.html` a su línea de comandos. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +El reporte es un archivo html, que puede descargar y abrir en su navegador. También puede hacer clic derecho en él en el explorador de archivos a la izquierda y hacer clic en `Show preview` para verlo en el entorno de entrenamiento. + +Tómese unos minutos para revisar el reporte y ver si puede identificar algunas oportunidades para ajustar recursos. +Asegúrese de hacer clic en las pestañas que muestran los resultados de utilización como porcentaje de lo que fue asignado. +Hay algo de [documentación](https://www.nextflow.io/docs/latest/reports.html) que describe todas las características disponibles. + +### 5.2. Establecer asignaciones de recursos para todos los procesos + +El perfilado muestra que los procesos en nuestro flujo de trabajo de entrenamiento son muy ligeros, así que reduzcamos la asignación de memoria predeterminada a 1GB por proceso. + +Agregue lo siguiente a su archivo `nextflow.config`, antes de la sección de parámetros del pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Configuración de procesos +*/ +process { + memory = 1.GB +} +``` + +Eso ayudará a reducir la cantidad de cómputo que consumimos. + +### 5.3. Establecer asignaciones de recursos para un proceso específico + +Al mismo tiempo, vamos a pretender que el proceso `cowpy` requiere más recursos que los otros, solo para que podamos demostrar cómo ajustar asignaciones para un proceso individual. + +=== "Después" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Configuración de procesos + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="4" + /* + * Configuración de procesos + */ + process { + memory = 1.GB + } + ``` + +Con esta configuración, todos los procesos solicitarán 1GB de memoria y un único CPU (el predeterminado implícito), excepto el proceso `cowpy`, que solicitará 2GB y 2 CPUs. + +!!! tip "Consejo" + + Si tiene una máquina con pocos CPUs y asigna un número alto por proceso, podría ver llamadas de proceso siendo encoladas detrás de otras. + Esto es porque Nextflow asegura que no solicitemos más CPUs de los que están disponibles. + +### 5.4. Ejecutar el flujo de trabajo con la configuración actualizada + +Probemos eso, suministrando un nombre de archivo diferente para el reporte de perfilado para que podamos comparar el rendimiento antes y después de los cambios de configuración. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Probablemente no notará ninguna diferencia real ya que esta es una carga de trabajo tan pequeña, pero este es el enfoque que usaría para analizar el rendimiento y los requisitos de recursos de un flujo de trabajo del mundo real. + +Es muy útil cuando sus procesos tienen diferentes requisitos de recursos. Le permite dimensionar correctamente las asignaciones de recursos que configura para cada proceso basándose en datos reales, no en suposiciones. + +!!! tip "Consejo" + + Esto es solo un pequeño adelanto de lo que puede hacer para optimizar su uso de recursos. + Nextflow mismo tiene una [lógica de reintento dinámica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) realmente elegante incorporada para reintentar trabajos que fallan debido a limitaciones de recursos. + Adicionalmente, la Plataforma Seqera ofrece herramientas impulsadas por IA para optimizar sus asignaciones de recursos automáticamente también. + +### 5.5. Agregar límites de recursos + +Dependiendo de qué executor de cómputo e infraestructura de cómputo esté usando, puede haber algunas restricciones sobre lo que puede (o debe) asignar. +Por ejemplo, su clúster puede requerir que permanezca dentro de ciertos límites. + +Puede usar la directiva `resourceLimits` para establecer las limitaciones relevantes. La sintaxis se ve así cuando está por sí sola en un bloque process: + +```groovy title="Ejemplo de sintaxis" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow traducirá estos valores a las instrucciones apropiadas dependiendo del executor que especificó. + +No vamos a ejecutar esto, ya que no tenemos acceso a infraestructura relevante en el entorno de entrenamiento. +Sin embargo, si intentara ejecutar el flujo de trabajo con asignaciones de recursos que excedan estos límites, luego buscara el comando `sbatch` en el archivo de script `.command.run`, vería que las solicitudes que realmente se envían al executor están limitadas a los valores especificados por `resourceLimits`. + +??? info "Configuraciones de referencia institucionales" + + El proyecto nf-core ha compilado una [colección de archivos de configuración](https://nf-co.re/configs/) compartidos por varias instituciones alrededor del mundo, cubriendo una amplia gama de executors HPC y de nube. + + Esas configuraciones compartidas son valiosas tanto para las personas que trabajan allí y por lo tanto pueden simplemente utilizar la configuración de su institución directamente, como un modelo para personas que buscan desarrollar una configuración para su propia infraestructura. + +### Conclusión + +Sabe cómo generar un reporte de perfilado para evaluar la utilización de recursos y cómo modificar las asignaciones de recursos para todos los procesos y/o para procesos individuales, así como establecer limitaciones de recursos para ejecutar en HPC. + +### ¿Qué sigue? + +Aprender cómo configurar perfiles de configuración preestablecidos y cambiar entre ellos en tiempo de ejecución. + +--- + +## 6. Usar perfiles para cambiar entre configuraciones preestablecidas + +Le hemos mostrado varias formas en que puede personalizar la configuración de su pipeline dependiendo del proyecto en el que está trabajando o el entorno de cómputo que está usando. + +Puede querer cambiar entre configuraciones alternativas dependiendo de qué infraestructura de cómputo está usando. Por ejemplo, podría querer desarrollar y ejecutar pruebas de pequeña escala localmente en su laptop, luego ejecutar cargas de trabajo a escala completa en HPC o nube. + +Nextflow le permite configurar cualquier número de perfiles que describen diferentes configuraciones, que luego puede seleccionar en tiempo de ejecución usando un argumento de línea de comandos, en lugar de tener que modificar el archivo de configuración mismo. + +### 6.1. Crear perfiles para cambiar entre desarrollo local y ejecución en HPC + +Configuremos dos perfiles alternativos; uno para ejecutar cargas pequeñas en una computadora regular, donde usaremos contenedores Docker, y uno para ejecutar en un HPC universitario con un programador Slurm, donde usaremos paquetes Conda. + +#### 6.1.1. Configurar los perfiles + +Agregue lo siguiente a su archivo `nextflow.config`, después de la sección de parámetros del pipeline pero antes de la configuración de salida: + +```groovy title="nextflow.config" linenums="24" +/* +* Perfiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Verá que para el HPC universitario, también estamos especificando limitaciones de recursos. + +#### 6.1.2. Ejecutar el flujo de trabajo con un perfil + +Para especificar un perfil en nuestra línea de comandos de Nextflow, usamos el argumento `-profile`. + +Intentemos ejecutar el flujo de trabajo con la configuración `my_laptop`. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Como puede ver, esto nos permite alternar entre configuraciones muy convenientemente en tiempo de ejecución. + +!!! warning "Advertencia" + + El perfil `univ_hpc` no se ejecutará correctamente en el entorno de entrenamiento ya que no tenemos acceso a un programador Slurm. + +Si en el futuro encontramos otros elementos de configuración que siempre co-ocurren con estos, simplemente podemos agregarlos al(los) perfil(es) correspondiente(s). +También podemos crear perfiles adicionales si hay otros elementos de configuración que queramos agrupar. + +### 6.2. Crear un perfil de parámetros de prueba + +Los perfiles no son solo para configuración de infraestructura. +También podemos usarlos para establecer valores predeterminados para parámetros de flujo de trabajo, para hacer más fácil para otros probar el flujo de trabajo sin tener que reunir valores de entrada apropiados ellos mismos. +Puede considerar esto una alternativa a usar un archivo de parámetros. + +#### 6.2.1. Configurar el perfil + +La sintaxis para expresar valores predeterminados en este contexto se ve así, para un perfil que nombramos `test`: + +```groovy title="Ejemplo de sintaxis" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Si agregamos un perfil de prueba para nuestro flujo de trabajo, el bloque `profiles` se convierte en: + +```groovy title="nextflow.config" linenums="24" +/* +* Perfiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Al igual que para los perfiles de configuración técnica, puede configurar múltiples perfiles diferentes especificando parámetros bajo cualquier nombre arbitrario que desee. + +#### 6.2.2. Ejecutar el flujo de trabajo localmente con el perfil de prueba + +Convenientemente, los perfiles no son mutuamente excluyentes, así que podemos especificar múltiples perfiles en nuestra línea de comandos usando la siguiente sintaxis `-profile <profile1>,<profile2>` (para cualquier número de perfiles). + +Si combina perfiles que establecen valores para los mismos elementos de configuración y están descritos en el mismo archivo de configuración, Nextflow resolverá el conflicto usando cualquier valor que haya leído último (_es decir_, lo que viene después en el archivo). +Si las configuraciones en conflicto están establecidas en diferentes fuentes de configuración, se aplica el [orden de precedencia](https://www.nextflow.io/docs/latest/config.html) predeterminado. + +Intentemos agregar el perfil de prueba a nuestro comando anterior: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Esto usará Docker donde sea posible y producirá salidas bajo `results/test`, y esta vez el personaje es el dúo cómico `dragonandcow`. + +??? abstract "Contenido del archivo" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Esto significa que mientras distribuyamos cualquier archivo de datos de prueba con el código del flujo de trabajo, cualquiera puede probar rápidamente el flujo de trabajo sin tener que suministrar sus propias entradas a través de la línea de comandos o un archivo de parámetros. + +!!! tip "Consejo" + + Podemos apuntar a URLs para archivos más grandes que están almacenados externamente. + Nextflow los descargará automáticamente mientras haya una conexión abierta. + + Para más detalles, vea la Misión Secundaria [Trabajando con Archivos](../side_quests/working_with_files.md) + +### 6.3. Usar `nextflow config` para ver la configuración resuelta + +Como se señaló arriba, a veces el mismo parámetro puede establecerse a diferentes valores en perfiles que quiere combinar. +Y más generalmente, hay numerosos lugares donde los elementos de configuración pueden almacenarse, y a veces las mismas propiedades pueden establecerse a diferentes valores en diferentes lugares. + +Nextflow aplica un [orden de precedencia](https://www.nextflow.io/docs/latest/config.html) establecido para resolver cualquier conflicto, pero eso puede ser complicado de determinar usted mismo. +E incluso si nada está en conflicto, puede ser tedioso buscar todos los lugares posibles donde las cosas podrían estar configuradas. + +Afortunadamente, Nextflow incluye una herramienta de utilidad conveniente llamada `config` que puede automatizar todo ese proceso por usted. + +La herramienta `config` explorará todos los contenidos en su directorio de trabajo actual, aspirará cualquier archivo de configuración, y producirá la configuración completamente resuelta que Nextflow usaría para ejecutar el flujo de trabajo. +Esto le permite averiguar qué configuraciones se usarán sin tener que lanzar nada. + +#### 6.3.1. Resolver la configuración predeterminada + +Ejecute este comando para resolver la configuración que se aplicaría por defecto. + +```bash +nextflow config +``` + +??? success "Salida del comando" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Esto le muestra la configuración base que obtiene si no especifica nada extra en la línea de comandos. + +#### 6.3.2. Resolver la configuración con configuraciones específicas activadas + +Si proporciona parámetros de línea de comandos, ej. habilitando uno o más perfiles o cargando un archivo de parámetros, el comando adicionalmente tomará esos en cuenta. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Salida del comando" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Esto se vuelve especialmente útil para proyectos complejos que involucran múltiples capas de configuración. + +### Conclusión + +Sabe cómo usar perfiles para seleccionar una configuración preestablecida en tiempo de ejecución con mínimo esfuerzo. +Más generalmente, sabe cómo configurar las ejecuciones de su flujo de trabajo para adaptarse a diferentes plataformas de cómputo y mejorar la reproducibilidad de sus análisis. + +### ¿Qué sigue? + +¡Celebre y dese una gran palmada en la espalda! Ha completado su primer curso de desarrollador de Nextflow. + +Diríjase al [resumen final del curso](./next_steps.md) para revisar lo que aprendió y descubrir qué viene después. + +--- + +## Cuestionario + +<quiz> +¿Cuál es el nombre del archivo de configuración que Nextflow carga automáticamente? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +¿Qué tiene precedencia cuando el mismo parámetro está establecido tanto en el archivo de configuración como en la línea de comandos? +- [ ] El valor del archivo de configuración +- [x] El valor de la línea de comandos +- [ ] El primer valor encontrado +- [ ] Ninguno; causa un error + +Aprenda más: [1.1. Mover valores predeterminados a `nextflow.config`](#11-mover-valores-predeterminados-a-nextflowconfig) +</quiz> + +<quiz> +¿Puede tener tanto Docker como Conda habilitados en la misma configuración? +- [x] Sí, Nextflow puede usar ambos dependiendo de las directivas del proceso +- [ ] No, solo uno puede estar habilitado a la vez +- [ ] Sí, pero solo en perfiles +- [ ] No, son mutuamente excluyentes +</quiz> + +<quiz> +Si tanto Docker como Conda están habilitados y un proceso tiene ambas directivas, ¿cuál se prioriza? +- [x] Docker (contenedores) +- [ ] Conda +- [ ] El primero definido +- [ ] Causa un error + +Aprenda más: [3. Seleccionar una tecnología de empaquetado de software](#3-seleccionar-una-tecnologia-de-empaquetado-de-software) +</quiz> + +<quiz> +¿Cuál es la asignación de memoria predeterminada para los procesos de Nextflow? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] Sin límite +</quiz> + +<quiz> +¿Cómo establece los requisitos de recursos para un proceso específico en el archivo de configuración? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +Aprenda más: [5.3. Establecer asignaciones de recursos para un proceso específico](#53-establecer-asignaciones-de-recursos-para-un-proceso-especifico) +</quiz> + +<quiz> +¿Qué opción de línea de comandos genera un reporte de utilización de recursos? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +Aprenda más: [5.1. Ejecutar el flujo de trabajo para generar un reporte de utilización de recursos](#51-ejecutar-el-flujo-de-trabajo-para-generar-un-reporte-de-utilizacion-de-recursos) +</quiz> + +<quiz> +¿Qué hace la directiva `resourceLimits`? +- [ ] Establece requisitos mínimos de recursos +- [ ] Asigna recursos a procesos +- [x] Limita los recursos máximos que pueden solicitarse +- [ ] Monitorea el uso de recursos + +Aprenda más: [5.5. Agregar límites de recursos](#55-agregar-limites-de-recursos) +</quiz> + +<quiz> +¿Cuál es el executor predeterminado en Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Aprenda más: [4. Seleccionar una plataforma de ejecución](#4-seleccionar-una-plataforma-de-ejecucion) +</quiz> + +<quiz> +¿Cómo especifica un archivo de parámetros al ejecutar Nextflow? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +Aprenda más: [1.3. Usar un archivo de parámetros](#13-usar-un-archivo-de-parametros) +</quiz> + +<quiz> +¿Para qué pueden usarse los perfiles? (Seleccione todos los que apliquen) +- [x] Definir configuraciones específicas de infraestructura +- [x] Establecer límites de recursos para diferentes entornos +- [x] Proporcionar parámetros de prueba +- [ ] Definir nuevos procesos + +Aprenda más: [6. Usar perfiles para cambiar entre configuraciones preestablecidas](#6-usar-perfiles-para-cambiar-entre-configuraciones-preestablecidas) +</quiz> + +<quiz> +¿Cómo especifica múltiples perfiles en un único comando? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Aprenda más: [6. Usar perfiles para cambiar entre configuraciones preestablecidas](#6-usar-perfiles-para-cambiar-entre-configuraciones-preestablecidas) +</quiz> diff --git a/docs/es/docs/hello_nextflow/index.md b/docs/es/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..d55fc8ad54 --- /dev/null +++ b/docs/es/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Iniciar y gestionar la ejecución de flujos de trabajo de Nextflow + - Encontrar e interpretar salidas (resultados) y archivos de registro generados por Nextflow + - Solucionar problemas básicos + - Construir un flujo de trabajo simple de múltiples pasos a partir de componentes principales de Nextflow + - Distinguir entre tipos esenciales de channel factories y operadores y utilizarlos efectivamente en un flujo de trabajo simple + - Configurar la ejecución de pipelines para ejecutar en plataformas de cómputo comunes incluyendo HPC y nube + - Aplicar mejores prácticas de reproducibilidad, portabilidad y reutilización de código que hacen los pipelines FAIR, incluyendo modularidad del código y contenedores de software + audience_prerequisites: + - "**Audiencia:** Este curso está diseñado para estudiantes que son completamente nuevos en Nextflow y quieren desarrollar sus propios pipelines." + - "**Habilidades:** Se asume cierta familiaridad con la línea de comandos, conceptos básicos de scripting y formatos de archivo comunes." + - "**Dominio:** Los ejercicios son todos independientes del dominio, por lo que no se requiere conocimiento científico previo." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow es una introducción práctica a la construcción de flujos de trabajo de análisis de datos reproducibles y escalables.** + +Trabajando a través de ejemplos prácticos y ejercicios guiados, aprenderá los fundamentos del desarrollo de pipelines con Nextflow, incluyendo cómo definir procesos, conectarlos en pipelines, gestionar archivos y dependencias de software, paralelizar la ejecución sin esfuerzo y ejecutar flujos de trabajo en diferentes entornos de cómputo. + +Se llevará las habilidades y la confianza para comenzar a desarrollar y ejecutar sus propios flujos de trabajo con Nextflow. + +<!-- additional_information --> + +## Descripción general del curso + +Este curso está diseñado para ser práctico, con ejercicios orientados a objetivos estructurados para introducir información gradualmente. + +Desarrollará un pipeline simple de Nextflow que toma algunas entradas de texto, ejecuta algunos pasos de transformación, y produce un único archivo de texto que contiene una imagen ASCII de un personaje diciendo el texto transformado. + +### Plan de lecciones + +Para evitar abrumarle con conceptos y código, hemos dividido esto en seis partes que se enfocarán cada una en aspectos específicos del desarrollo de pipelines con Nextflow. + +| Capítulo del curso | Resumen | Duración estimada | +| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ----------------- | +| [Parte 1: Hello World](./01_hello_world.md) | Componentes básicos y principios involucrados en ensamblar y ejecutar un flujo de trabajo de Nextflow | 30 mins | +| [Parte 2: Hello Channels](./02_hello_channels.md) | Usar canales y operadores para procesar entradas y paralelizar la ejecución sin esfuerzo | 45 mins | +| [Parte 3: Hello Workflow](./03_hello_workflow.md) | Usar canales para encadenar múltiples pasos juntos y manejar la transferencia de datos entre pasos | 60 mins | +| [Parte 4: Hello Modules](./04_hello_modules.md) | Aplicar principios de modularidad de código para aumentar la reutilización y disminuir la carga de mantenimiento | 20 mins | +| [Parte 5: Hello Containers](./05_hello_containers.md) | Usar contenedores como mecanismo para gestionar dependencias de software y aumentar la reproducibilidad | 60 mins | +| [Parte 6: Hello Config](./06_hello_config.md) | Personalizar el comportamiento del pipeline y optimizar el uso en diferentes entornos computacionales | 60 mins | + +Al final de este curso, estará bien preparado para abordar los próximos pasos en su viaje para desarrollar flujos de trabajo reproducibles para sus necesidades de computación científica. + +¿Listo para tomar el curso? + +[Comenzar :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/es/docs/hello_nextflow/next_steps.md b/docs/es/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..90852fd52d --- /dev/null +++ b/docs/es/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Resumen del curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicitaciones por completar el curso de entrenamiento Hello Nextflow! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Vea la [lista de reproducción completa en el canal de YouTube de Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Puede leer la [transcripción del video](./transcripts/07_next_steps.md) junto con el video. +/// + +## Su viaje + +Comenzó con un flujo de trabajo muy básico que ejecutaba un comando codificado de forma fija. +A lo largo de seis partes, transformó ese flujo de trabajo básico en un pipeline modular de múltiples pasos que ejercita características clave de Nextflow incluyendo canales, operadores, soporte integrado para contenedores y opciones de configuración. + +### Lo que construyó + +- La forma final del flujo de trabajo Hello toma como entrada un archivo CSV que contiene saludos de texto. +- Los cuatro pasos están implementados como procesos de Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` y `cowpy`) almacenados en archivos de módulo separados. +- Los resultados se publican en un directorio llamado `results/`. +- La salida final del pipeline es un archivo de texto plano que contiene arte ASCII de un personaje diciendo los saludos en mayúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Escribe cada saludo en su propio archivo de salida (por ejemplo, "Hello-output.txt") +2. **`convertToUpper`:** Convierte cada saludo a mayúsculas (por ejemplo, "HELLO") +3. **`collectGreetings`:** Recopila todos los saludos en mayúsculas en un único archivo de lote +4. **`cowpy`:** Genera arte ASCII usando la herramienta `cowpy` + +La configuración del flujo de trabajo soporta proporcionar entradas y parámetros de manera flexible y reproducible. + +### Habilidades adquiridas + +A través de este curso práctico, ha aprendido cómo: + +- Describir y utilizar componentes principales de Nextflow suficientes para construir un flujo de trabajo simple de múltiples pasos +- Describir conceptos de siguiente nivel como operadores y channel factories +- Iniciar un flujo de trabajo de Nextflow localmente +- Encontrar e interpretar salidas (resultados) y archivos de registro generados por Nextflow +- Solucionar problemas básicos + +Ahora está equipado con el conocimiento fundamental para comenzar a desarrollar sus propios pipelines en Nextflow. + +## Próximos pasos para desarrollar sus habilidades + +Aquí están nuestras 3 principales sugerencias sobre qué hacer a continuación: + +- Aplicar Nextflow a un caso de uso de análisis científico con [Nextflow para Ciencia](../nf4_science/index.md) +- Comenzar con nf-core con [Hello nf-core](../../hello_nf-core/index.md) +- Explorar características más avanzadas de Nextflow con los [Side Quests](../side_quests/index.md) + +Finalmente, le recomendamos que eche un vistazo a [**Seqera Platform**](https://seqera.io/), una plataforma basada en la nube desarrollada por los creadores de Nextflow que hace aún más fácil iniciar y gestionar sus flujos de trabajo, así como gestionar sus datos y ejecutar análisis interactivamente en cualquier entorno. + +## Encuesta de retroalimentación + +Antes de continuar, ¡por favor tome un minuto para completar la encuesta del curso! Su retroalimentación nos ayuda a mejorar nuestros materiales de entrenamiento para todos. + +[Completar la encuesta :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/es/docs/hello_nextflow/survey.md b/docs/es/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..d64b0d3c0e --- /dev/null +++ b/docs/es/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Encuesta de retroalimentación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, por favor complete esta breve encuesta de 5 preguntas para calificar el entrenamiento, compartir cualquier comentario que pueda tener sobre su experiencia, y hacernos saber qué más podríamos hacer para ayudarle en su viaje con Nextflow. + +Esto debería tomarle menos de un minuto en completar. ¡Gracias por ayudarnos a mejorar nuestros materiales de entrenamiento para todos! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/es/docs/hello_nextflow/transcripts/00_orientation.md b/docs/es/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..c3eddafe75 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Orientación - Transcripción del Video + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Nota importante" + + Esta página muestra únicamente la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../00_orientation.md). + +## Bienvenida + +Hola, bienvenido a Hello Nextflow. Mi nombre es Phil Ewels. Soy Product Manager para Open Source en Seqera, y estoy encantado de estar aquí hoy para guiarlo a través de este primer curso de entrenamiento de Nextflow. + +Vamos a repasar los conceptos básicos de Nextflow, explicando cómo escribir y ejecutar pipelines y configurarlos. + +Y usted va a construir su propio pipeline simple de múltiples pasos. Cubriremos terminología como operadores y channel factories, y al final del curso, estará listo para comenzar a construir sus propios pipelines de bioinformática. + +Si tiene alguna pregunta, por favor comuníquese en community.seqera.io. Tenemos una comunidad de Nextflow muy activa, hay una sección dedicada al entrenamiento, así que simplemente déjenos saber dónde está atascado y alguien podrá ayudar. + +Bien. Empecemos. + +## Sitio Web de Entrenamiento + +Todo el material de entrenamiento para los cursos de Nextflow se encuentra en training.nextflow.io. Puede acceder en su navegador web. Así que ábralo ahora y podemos echar un vistazo. + +Estaré ejecutando esto con la versión 2.1.1. Publicamos pequeñas actualizaciones y correcciones de vez en cuando, así que no se preocupe si es un poco diferente, pero si el material ha cambiado demasiado, siempre puede usar este selector de versión en la parte superior para elegir la versión exacta de los materiales de los que voy a hablar. + +Si prefiere el modo claro, puede cambiar el tema del sitio web aquí. + +Vea las traducciones aquí, aunque al momento de esta grabación, realmente solo está el inglés, que cubre este nuevo material. + +Y también vea todo el código fuente del sitio web de entrenamiento y todo con lo que trabajaremos en GitHub. + +La página de inicio aquí enumera todos los diferentes cursos de material de entrenamiento que tenemos. Así que desplazo hacia abajo, veremos Nextflow para principiantes con el curso Hello Nextflow que haremos aquí. Puede ver todos los demás cursos que también tenemos, que funcionan de manera similar. + +## Configuración del Entorno + +De hecho, voy a comenzar usando este primero en la parte superior, que es común para todos los cursos de entrenamiento, y específicamente se trata de configurar nuestro entorno. + +Hago clic, me lleva a esta sección, y podemos ver instrucciones para desarrollar localmente. Si desea usar su propia computadora portátil con su propia copia de VS Code y sus propias instalaciones de software, o lo que esperamos que haga la mayoría de la gente, que es usar algo llamado GitHub Codespaces. + +Codespaces es un servicio proporcionado por GitHub donde ejecutan un servidor web en la nube, al que puede conectarse. Ese servidor tiene VS Code instalado, donde puede ejecutarlo en su navegador web, o si lo prefiere, conectarlo a su instalación local de VS Code. Toda la computación, todos los archivos, toda la edición ocurre de forma remota, lo que significa que todo el software que necesita viene preinstalado y es el mismo para todos. + +## Crear un GitHub Codespace + +Para crear el codespace con todo lo que necesitamos, busque los botones en el material de documentación, que dicen "Open in GitHub Codespaces". Voy a hacer clic en eso ahora, abrirlo en una nueva pestaña. Y se me presenta esta página web. Ahora puede ver que esto está preconfigurado para establecerse con nextflow-io training. + +Simplemente puedo hacer clic en crear nuevo codespace. Pero en realidad recomendamos que usemos una máquina un poco más grande para el entrenamiento de Nextflow con cuatro CPUs en lugar de dos. Puede cambiar qué versión del material usa. Así que esto está predeterminado a 2.1.1 porque esa es la versión de la documentación desde la que seguí el enlace. Pero también podría establecerlo en una rama específica del repositorio si lo deseo. + +Ahora voy a hacer clic en crear codespace. Y va a comenzar a configurar el entorno para mí. + +## Creación de Codespace + +Ahora, la primera vez que haga esto, va a tomar bastante tiempo, así que ahora es un buen momento para ir y tomar una taza de té. Póngase cómodo, charle con la persona sentada a su lado. + +Si está interesado, puede hacer clic en building codespace aquí abajo para ver los registros de la configuración. Y puede ver aquí que está descargando una imagen de Docker con todo lo que necesito y configurando el entorno. + +Ahora, solo tiene que esperar así la primera vez que cree un codespace. Si va a github.com/codespaces aquí, verá todos los diferentes Codespaces que tiene abiertos. Aquí está el que acabo de crear. La próxima vez que haga esto, puede ir aquí y puede seleccionar el codespace anterior y simplemente volver directamente a él. Y es un proceso mucho, mucho más rápido para calentar ese entorno existente. Eso también mantendrá todos los cambios que haya realizado en VS Code y en los archivos, por lo que no perderá su progreso si se va y regresa. + +Puede hacer clic en los tres puntos aquí para hacer otras acciones. Por ejemplo, si lo configuró con dos CPUs y ahora quiere cuatro, puede cambiar el tipo de máquina. O si quiere comenzar desde cero y fresco, puede eliminar el codespace. + +## Introducción a VS Code + +Bien, Codespaces ha terminado de configurar mi entorno y ahora se presenta con VS Code en el navegador web. + +Si está acostumbrado a VS Code. Esto se sentirá muy familiar si no lo ha usado antes, es bastante simple. Hay algunas partes diferentes de la página de las que debe estar al tanto. + +Aquí a la izquierda, tenemos la barra lateral. Puede ver el Explorador configurado con todos los diferentes archivos en el repositorio de GitHub del repositorio de entrenamiento. + +En estos botones en la parte inferior izquierda, pueden haber diferentes herramientas. En la barra lateral. Puedo buscar todos los archivos en todo el proyecto. Puedo trabajar con Git, puedo trabajar con GitHub, todo tipo de cosas así. + +En la parte superior aquí está el menú principal. El explorador de archivos es el que tendremos más aquí, y puede hacer clic derecho en cualquiera de estos archivos y hacer las cosas normales que esperaría. Es posible que deba hacer clic en algunas advertencias como esta donde puede cortar, copiar y también puede descargar a su máquina local. + +Cuando se carga el codespace, nos da una vista previa del archivo markdown en esta área principal aquí. Este es el mismo que el que se renderiza en github.com. Puedo cerrar eso y si hago doble clic en ese archivo Readme, verá que lo abre como código en el editor de código y al igual que con cualquier otro archivo, podemos editar este código directamente. + +Finalmente, aquí abajo, tenemos la ventana de terminal. Estaba viendo los registros mientras se construía, así que eso es lo que está mostrando actualmente. También puedo presionar este botón más para iniciar una nueva sesión de terminal. Esto no se está ejecutando en mi máquina. Recuerde, esto se está ejecutando en la nube, y si hago tree tres a profundidad de dos, verá todos los mismos archivos aquí, que estaban a la izquierda. + +## Mostrar solo archivos "hello-nextflow" + +Este repositorio de GitHub contiene todos los diferentes conjuntos de entrenamiento, no solo el que estamos haciendo. Así que si lo desea, puede enfocarse solo en la carpeta Hello Nextflow. Una forma de limpiar esto un poco es ir al menú archivo y luego agregar carpeta al espacio de trabajo. + +Hacemos clic en eso, vamos a training. Hello nextflow, y hacemos clic en agregar. Actualizará su pantalla. Y luego en el Explorador, ahora tenemos dos espacios de trabajo diferentes, el que teníamos antes para training y uno con solo Hello Nextflow. + +Si lo desea, puede hacer clic derecho en training y hacer clic en eliminar carpeta del espacio de trabajo para deshacerse de ella de la barra lateral por completo. + +Ahora tenemos solo archivos para este curso de entrenamiento en particular en el lateral. Puedo ocultar esa advertencia y ahora puedo hacer lo mismo en el terminal aquí y hacer CD para cambiar directorio. Hello, Nextflow. Y nuevamente, tenemos los mismos archivos aquí, que están en la barra lateral. + +## Hello Nextflow: archivos + +Mirando estos archivos para el curso Hello Nextflow. + +Tenemos un montón de archivos .nf, que son para Nextflow, y hay uno de estos archivos para cada uno de los capítulos del curso de entrenamiento. Trabajaremos a través de estos archivos y los modificaremos en los ejercicios. + +También tenemos un archivo nextflow.config, que solo tiene configuraciones básicas de configuración para ejecutar Nextflow en este entorno, de las que realmente no necesita preocuparse en este punto. Un archivo greetings.csv, que usaremos para procesar datos, que se introducirá en la siguiente parte de este curso, y un archivo test-params.json, que se usará en la parte seis y puede ignorar por ahora. + +Estos archivos de Nextflow son solo el comienzo de cada ejercicio. Si desea ver cómo deberían verse cuando estén terminados, puede ir a un directorio solutions y están las respuestas para cada parte del curso de entrenamiento, por lo que puede ver una versión funcional de lo que está apuntando. + +## Abrir un terminal + +Si en algún momento cierra el terminal y no puede recordar cómo volver, no se preocupe por eso. Estos botones en la parte superior derecha abren y cierran diferentes paneles en el espacio de trabajo. Así que haga clic en este para el panel inferior y reaparecerá. Y solo asegúrese de que tenga terminal seleccionado aquí. También puede hacer clic en este botón aquí, la flecha en el lado derecho de un terminal para ponerlo en pantalla completa. + +Me verá haciendo eso bastante porque tengo VS Code ampliado para que pueda leer el texto. Dependiendo del tamaño de su pantalla, es posible que necesite o no hacer esto. Lo mismo ocurre con minimizar el panel lateral. + +Bien. Eso es suficiente para el entorno. Creo que estamos listos para comenzar. Acompáñeme de vuelta en el siguiente video para el capítulo uno. + +[Siguiente transcripción del video :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/es/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..a14cfa8611 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Parte 1: Hola Mundo - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra solo la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../01_hello_world.md). + + Los números de sección mostrados en la transcripción se proporcionan solo con fines indicativos y pueden no incluir todos los números de sección en los materiales. + +## Bienvenida + +Hola, bienvenidos al Capítulo Uno de Hola Nextflow. + +En esta primera parte de un curso de seis partes, vamos a ver lo más básico de Nextflow. Comenzaremos ejecutando algunos comandos en una terminal, y luego tomaremos esos comandos Bash y veremos cómo construirlos en un script de Nextflow. + +Intentaremos ejecutar ese primer pipeline de Nextflow, veremos qué hace Nextflow, dónde se ejecuta, qué archivos crea, y cuál es el propósito de esos archivos. + +Muy bien, comencemos. + +## training.nextflow.io + +Primero que nada, vayan a training.nextflow.io. Al igual que antes, todo el material está escrito aquí, y lo trabajaré paso a paso. Mostraré mi pantalla mientras realizo los pasos del entrenamiento, pero todo lo que estoy diciendo está en el material de entrenamiento para que puedan seguirlo a su propio ritmo, y pueden encontrarlo todo escrito allí. + +Este video también tiene subtítulos habilitados, así que siéntanse libres de activarlos y seguir exactamente lo que digo mientras lo digo. + +Bien, vayamos a Hola Nextflow. Ese es el curso que vamos a hacer hoy, y ya hicimos la orientación en el primer video, así que iremos directamente a la parte uno. Hola Mundo. + +Bien, voy a dejar este material de entrenamiento ahora y saltar a mi entorno de Code Spaces. Esto es lo que configuramos en el primer video. Espero que tengan algo que se vea muy similar a esto en su propio sistema. Estoy usando VS Code y estoy viendo el material de entrenamiento y he cambiado de directorios al directorio hello Nextflow. + +## 0. Calentamiento: Ejecutar Hola Mundo directamente + +Bien. Comencemos con un par de conceptos básicos, que espero sean familiares para todos. Voy a comenzar simplemente escribiendo un comando muy básico en la terminal. Aquí abajo voy a decir 'echo Hola Mundo!' presiono enter y, sin sorpresas, la terminal hace lo que le pido y devuelve esa cadena. Hola mundo. + +Bien, luego voy a presionar arriba para obtener ese comando y editarlo un poco más. Esta vez vamos a redirigir esa salida a un archivo. Voy a escribirlo en output.txt y presionar enter, nada en la terminal esta vez porque la salida no vino a la terminal. Fue a ese archivo. + +Luego puedo leer ese archivo haciendo 'cat output.txt' presiono tab allí para expandir automáticamente el nombre del archivo y ahí está. El archivo está ahí. + +También puedo ver ese archivo en la barra lateral en el explorador de archivos en VS Code. Puedo hacer doble clic en él y abrirlo aquí. Si quieren abrirlo en VS Code sin hacer clic en nada, también pueden hacer "code" y luego "output.txt" y hace lo mismo. + +Genial. Ese es el primer paso. Muy simple. + +## 1. Examinar el script inicial del workflow Hola Mundo + +Bien. Ahora vamos a hacer exactamente lo mismo, pero en Nextflow, en lugar de directamente en la terminal. + +Vamos a usar el primer script de ejemplo para comenzar, este archivo se llama Hello World. Puedo hacer "ls" para verlo en una terminal, y estoy en Mac, así que puedo hacer command clic para abrir ese archivo, o podría haber simplemente hecho doble clic en la barra lateral aquí. + +Hay algunas cosas que podemos ver en este archivo. Justo arriba, hay una declaración hash que dice que este es un archivo Nextflow y así es como podría ejecutarse. Hay algunos comentarios aquí, solo comentarios regulares de código en gris claro, que no afectan la ejecución, y solo nos ayudan a leer el script. + +Y luego hay dos estructuras principales. Hay un process aquí y un workflow. + +Los processes en Nextflow son los pasos del pipeline. Son las partes que realmente hacen la lógica y realizan el procesamiento. + +El workflow entonces en la parte inferior une estos procesos juntos y gobierna la lógica del workflow, cómo todo se conecta entre sí. + +Vamos a comenzar viendo un process. Volveremos al workflow en un momento. + +## 1.2 La definición del process + +Entonces cada process comienza con una palabra clave process. Tiene un nombre y luego tiene algunos corchetes y todo dentro de esos corchetes es ese único process. + +Un process debe tener una sección script, y contenido aquí hay un fragmento de bash en una cadena multilínea, que es la parte del código que realmente se ejecuta en el entorno de cómputo. + +También tenemos una declaración output aquí, que le dice a Nextflow, qué archivos se espera que sean creados por el script. Note que el output aquí tiene una palabra clave path, que le dice a Nextflow que esto es un archivo, no un valor, o una cadena. + +Dentro del bloque script, esto es solo una declaración bash regular, y es exactamente lo mismo que escribimos en la terminal. Estamos haciendo echo de hola mundo a un archivo llamado output.txt. Este output.txt es luego recogido por la definición de output. La definición de output en realidad no está haciendo nada. Solo está diciéndole a Nextflow qué esperar, y si este archivo no se creara, Nextflow lanzaría un error. + +Note que este ejemplo no es muy bueno porque hemos codificado el nombre del archivo aquí, output.txt y output.txt. Si cualquiera de estos se cambiara, eso causaría un error en nuestro workflow. + +Hay una mejor manera de hacer esto con variables, que cubriremos en un minuto. + +## 1.3 La definición del workflow + +Bien. Bajando al workflow, podemos ver que tenemos un comentario y luego ejecutamos el process llamado sayHello. Esta es la misma palabra clave que está aquí arriba. Esto es tan simple como puede ser un workflow. Solo estamos llamando a un único process sin entrada variable, así que no lo estamos conectando a nada más. En la parte posterior de este curso, hablaremos sobre cómo hacer esto más poderoso usando entradas variables y conectando cosas con channels. + +## 2. Ejecutar el workflow + +Bien, esto es todo lo que necesitamos. Veamos si podemos ejecutarlo y ver qué sucede. Voy a simplemente limpiar la terminal y luego voy a hacer "nextflow run", y voy a llamar al nombre del archivo, que es hello-world.nf. Eso es todo lo que necesitamos para ejecutar un pipeline de Nextflow. Este pipeline no toma ninguna entrada, así que no necesitamos ningún otro argumento. + +Presionemos enter y veamos qué pasa. + +Bien. Esperemos que deberían tener alguna salida, que se vea así. Tenemos algunos fragmentos de información que nos dicen que Nextflow se ejecutó y qué versión estaba usando. Nos dice qué script se lanzó y nos da un nombre generado aleatoriamente para esta ejecución particular del workflow. En este caso, el mío se llamó "gloomy_crick". + +La parte más importante de esto, sin embargo, es que nos dice qué pasos se ejecutaron en el pipeline. Pueden ver que nuestro process llamado sayHello se ejecutó, y se ejecutó una vez y estuvo cien por ciento completo. + +Esta parte aquí es el hash para esa tarea particular del workflow. Cada process se ejecuta una o más veces, y cada una de esas ejecuciones se llama una tarea. + +## 2.2. Encontrar la salida y los logs en el directorio work + +Cada tarea obtiene su propio directorio aislado donde se ejecuta, por lo que está separado del resto de la ejecución del workflow. Este hash corresponde a la estructura de archivos dentro del directorio work. Si hago "tree work", podemos ver a0, y luego una versión más larga del hash corto, y luego nuestro archivo output.txt. También pueden verlo en una barra lateral. + +Pueden ver en la barra lateral que hay algunos archivos adicionales aquí. La razón por la que estos no aparecieron en una terminal es porque son archivos ocultos, comienzan con un punto. Y de hecho, si hago "tree -a" para todos, y "work", podemos verlos aquí. + +Estos archivos con punto están presentes en cada directorio work que Nextflow crea, y cada uno tiene una tarea ligeramente diferente. Primero .command.begin simplemente incluye algunas instrucciones para Nextflow que configuran la tarea antes de que se ejecute. .command.run son las instrucciones reales ejecutadas por Nextflow mismo. Luego .command.sh es probablemente el más interesante. Este es el script que fue resuelto desde nuestro bloque script del process. + +Si lo abro, pueden ver que tenemos nuestro "echo Hello World" al archivo output.txt. Esto es exactamente lo mismo que nuestro process en este caso, pero si tenemos alguna variable dentro de nuestro código Nextflow, cada tarea tendrá un .command.sh diferente, y pueden ver cómo se resolvieron esas variables. + +Los otros archivos tienen que ver con cómo se ejecutó la tarea. Entonces .command.err, .log y .out son el error estándar, salida estándar y los dos combinados. Y .exitcode le dice a Nextflow cómo se ejecutó esta tarea con qué código de salida, si fue exitosa o no. + +Finalmente, tenemos nuestro archivo output.txt y efectivamente, "Hello World" esto es lo que estábamos esperando y esto es lo que se creó. + +Bien, genial. Esa fue su primera ejecución de Nextflow. Felicitaciones. Realmente es así de simple. + +A continuación, vamos a ver cómo hacer esto un poco más conveniente para que no tengamos que editar el código cada vez que queramos hacer un cambio en cómo se ejecuta el pipeline. + +## 3. Gestionar ejecuciones del workflow + +Esta estructura de directorios es genial para mantener todas las tareas separadas y todo organizado, pero por supuesto, no es muy conveniente para encontrar sus archivos de salida. No quieren estar excavando a través de montones de directorios anidados tratando de encontrar los resultados de su pipeline. + +## 3.1. Publicar salidas + +La buena noticia es que no se supone que lo hagan. Los directorios work son realmente solo para que Nextflow los use. Así que lo que vamos a hacer es usar una función para Nextflow llamada "publishDir". + +Volvemos a nuestro workflow, vamos al process. Podemos agregar una nueva declaración aquí llamada directiva. Esto es lo que Nextflow llama estas cosas en la parte superior de los procesos que aumentan cómo funciona la funcionalidad, y la que vamos a usar se llama publishDir. + +Pueden ver que he comenzado a escribir aquí y la extensión de Nextflow para VS Code me ha sugerido la directiva, así que solo puedo presionar enter. + +Bien. Voy a seguir esto con un directorio llamado "results" y vamos a decirle que copie los archivos de salida allí. Así que voy a decir mode copy. Genial. Voy a guardar y ejecutemos el workflow nuevamente. + +nextflow run hello-world.nf + +Se ejecuta exactamente igual. Aunque note que tenemos un hash ligeramente diferente esta vez. Nextflow, usará un hash diferente cada vez que ejecute el workflow. Y tenemos un conjunto diferente de directorios work como resultado. Áreas, uno llamado EB en su lugar, pero pueden ver que todos los archivos son los mismos. Sin embargo, lo que es nuevo esta vez es que también tenemos un directorio llamado "results". + +Dentro de "results" aquí tenemos nuestro archivo de salida. Eso es lo que le dijimos a Nextflow que hiciera. Dijimos, guarda los archivos de resultados en un directorio llamado "results" y cópialos allí. Y así esto ahora es mucho más fácil de encontrar. Está justo allí junto a donde lanzamos un workflow y todos los diferentes archivos se pueden organizar allí como deseemos, independientemente de dónde o cómo Nextflow ejecutó la ejecución real. + +Note que publishDir puede manejar enlaces simbólicos, lo cual es bueno si está trabajando en un sistema de archivos compartido y desea ahorrar espacio. Y también no tiene que definir todos los archivos que son creados por un process como una salida. + +Nextflow solo copiará las cosas que están definidas en este bloque output. Así que si tiene archivos intermedios creados por el paso, que no son necesarios más adelante de este process, simplemente no los define en output y no aparecerán en el publishDir. Entonces esta es una forma de mantener sus archivos de salida de un pipeline limpios y eliminar fácilmente archivos intermedios una vez que el lugar de trabajo haya terminado. + +Una nota rápida aquí. Hay una nueva sintaxis de Nextflow que viene llamada workflow output definitions, que eventualmente reemplazará publishDir. Esto nos da una forma de definir todas las salidas de un workflow a nivel de pipeline en el bloque workflow. Esto se describe en los documentos de Nextflow si quieren probarlo. Pero por ahora, publishDir estará presente por un tiempo, así que todavía lo tenemos en un entrenamiento para 2025. + +## 3.2. Relanzar un workflow con -resume + +Bien. Mencioné que el directorio work aquí ahora tiene dos conjuntos de resultados con un hash diferente de cada vez que ejecutamos el workflow. Eso es bueno. Sin embargo, a veces no queremos volver a calcular pasos cada vez si no lo necesitamos. + +Tal vez estén construyendo iterativamente su workflow y estén agregando pasos y quieren que los primeros pasos simplemente reutilicen las versiones en caché. O tal vez algo salió mal en su sistema de cómputo a mitad de camino a través de su workflow y quieren que continúe desde donde se quedó, pero omita los pasos que ya había completado. + +Nextflow tiene funcionalidad incorporada para esto llamada resume. Probémoslo. Entonces primero, solo voy a echar un vistazo al directorio work para que podamos recordar qué había allí. + +Y luego voy a hacer "nextflow run hello-world.nf" y voy a agregar un único comando aquí, "-resume". + +Note, guión simple, eso es realmente importante. Voy a ejecutarlo y la salida va a verse básicamente exactamente igual, con un par de pequeñas diferencias. + +Note aquí dice "cached" en gris. Eso significa que Nextflow no ejecutó la tarea. Esta vez encontró algo que coincidía con lo que eran los requisitos y reutilizó esas salidas directamente en lugar de volver a ejecutar el paso. + +Y efectivamente, si miran el hash aquí, pueden ver que esto corresponde al hash existente que teníamos de una ejecución anterior. + +## 3.3. Eliminar directorios work antiguos + +Bien. Pero si están desarrollando iterativamente, van a acumular muchos de estos archivos de workflow. Eso puede ser un problema si pueden tener poco espacio. + +Nextflow puede ayudarnos a limpiar estos directorios work con un par de comandos de ayuda. Si hago "nextflow log". Eso me dará una lista de todas las diferentes ejecuciones de workflow que he hecho en este directorio, y tienen los nombres de ejecución aquí. Pueden ver el gloomy quick que fue el primero que ejecutamos, y luego estos dos nuevos. + +Ahora podemos tomar ese nombre y usarlos con el comando "nextflow clean". Puedo especificar un único nombre de ejecución. O incluso mejor, puedo decirle a Nextflow que elimine todo antes de un único nombre de workflow con "-before", y voy a poner "stupefied_shaw". Esa fue mi ejecución más reciente, "-n". + +El comando "-n" le dijo a Nextflow que lo hiciera como una ejecución en seco sin realmente eliminar nada de verdad, y nos dice cuáles de los directorios hash habrían sido eliminados. Efectivamente, es solo ese del primer ejecución. Ambas ejecuciones segundas usan el mismo directorio hash. + +Voy a ejecutarlo de nuevo, pero ahora en lugar de "-n" para ejecución en seco, voy a hacer "-f" para forzar y ha eliminado ese directorio hash. Ahora si hago "tree work", podemos ver, solo tenemos este archivo de salida restante. + +Genial. Así que hemos logrado limpiar un montón de espacio en disco allí. + +Un par de cosas a tener en cuenta al eliminar directorios work, si enlazan simbólicamente cosas a su directorio de resultados, esas fuentes de enlace simbólico ahora serán eliminadas y sus resultados se habrán ido para siempre. Por eso usar el modo copy es una cosa más segura de hacer, y generalmente lo que recomendamos. + +En segundo lugar, la funcionalidad resume de Nextflow depende de estos directorios work. Entonces, si los eliminan y ejecutan Nextflow nuevamente, la funcionalidad resume ya no funcionará. Así que depende de ustedes hacer un seguimiento de qué cosas pueden necesitar o pueden no necesitar, y solo eliminar cosas cuando estén seguros de que es seguro hacerlo. + +La otra cosa que podemos hacer es simplemente eliminar todo el directorio work si hemos terminado nuestra ejecución del workflow y estamos seguros de que ya no lo necesitamos. + +Entonces puedo hacer "rm -r work". Sé que no había nada importante allí. Tengo mis resultados que me importan en el directorio results donde los copiamos. Y así fue seguro eliminar el directorio work. Depende de ustedes cuál de estos enfoques usan. + +## 4. Usar una entrada variable pasada en la línea de comandos + +Bien, ¿qué sigue? Mencioné que habíamos codificado algunos de los valores en nuestro script de workflow aquí, el archivo output.txt, y que podría haber una mejor manera de hacer eso. + +Hagamos un comienzo en esto. Lo que vamos a hacer son tres cosas. Vamos a agregar una nueva entrada al process. Vamos a decirle al script del process cómo usar esa entrada, y luego vamos a conectarlo en el workflow para que podamos usarlo dinámicamente con una bandera de línea de comandos al ejecutar Nextflow. + +Entonces primero que nada. Agreguemos un bloque input aquí. Igual que output. Esta es una nueva sección para el process, y voy a decir, "val greeting". + +Note aquí, estoy diciendo "val", lo que dice que esto es una variable, no un path. + +Luego puedo bajar al script y luego puedo sacar este texto codificado aquí y hacer $greeting. Esto funciona como cualquier otro lenguaje de programación. Estamos definiendo una variable aquí y la estamos referenciando dentro de este bloque script. Cuando Nextflow ejecute este process, la variable será interpolada. Y cuando vayamos y miremos ese archivo .command.sh, veremos la cadena real codificada aquí en su lugar. + +## 4.1.3. Configurar un parámetro CLI y proporcionarlo como entrada a la llamada del process + +Bien, pero ¿dónde proporcionamos la variable? A continuación bajamos a la sección workflow, y pueden ver que la extensión aquí está diciendo, ahora esperamos una entrada, y me ha dado una advertencia. + +Ahora, lo más simple que podríamos hacer es simplemente codificarlo. Podría escribir "Hello World" y proporcionar esa entrada de cadena al process. Pero nuevamente, eso realmente no resolvería ningún problema. Todavía tendríamos que volver y editar el código del pipeline cada vez que quisiéramos cambiar algo, lo cual no es bueno. + +La buena noticia es que Nextflow tiene un sistema incorporado para manejar argumentos de línea de comandos llamados parámetros. Entonces en su lugar, puedo usar una de estas variables especiales llamada params y puedo llamarla como quiera, pero voy a decir greeting para que coincida con la lógica del workflow. + +Guardar y veamos qué podemos hacer con esto. + +Entonces si vuelvo a la terminal. Entonces hacemos "nextflow run hello-world.nf". Justo como antes, pero la diferencia clave es que hacemos --greeting + +Note, hay dos guiones aquí porque este es un parámetro. Cuando reanudamos el workflow antes, eso fue un guión simple. Eso es porque resume es una opción central de Nextflow, y este es un parámetro que es específico para nuestro pipeline. + +No mezclen los dos. Es fácil hacer eso. Si hicieran --resume en lugar de solo un guión, entonces eso sería "params.resume", lo que no haría nada. Del mismo modo, si hicieran un guión simple aquí, Nextflow no lo reconocería como un argumento clave. + +Entonces es --greeting, que corresponde a parameters greeting. + +Ahora puedo seguir eso con cualquier texto que quiera. Entonces estoy en Suecia en este momento, así que voy a decir, "Hej världen". + +Entonces ejecutémoslo, veamos qué sucede, momento de la verdad. + +Bien, entonces pueden ver que el process se ejecutó nuevamente, justo como antes, sayHello con una única ejecución. + +Esto habrá sobrescrito el archivo que estaba en el directorio publishDir "results". Y así tengan cuidado cuando estén volviendo a ejecutar los archivos porque las cosas en el directorio publicado serán sobrescritas. + +Ahora puedo hacer "code results/output.txt", y efectivamente, nuestra salida ha sido actualizada y ahora dice "Hej världen". + +## 4.2. Usar valores predeterminados para parámetros de línea de comandos + +Bien, eso es genial. Pero el problema ahora es que nuestro workflow depende de que siempre definamos este parámetro, y es bueno tener valores predeterminados sensatos para que las cosas se ejecuten de una manera sensata para su workflow a menos que sobrescriban los valores predeterminados. + +Entonces la forma en que hacemos eso es estableciendo un valor predeterminado para el parámetro en nuestro script de workflow. + +Entonces si vuelvo a mi archivo hello-world.nf, puedo ir al script justo encima del workflow, escribir "params.greeting" y definirlo como cualquier otra variable. Entonces pongamos una cadena aquí y digamos "¡Hola mundo!" + +Ahora este parámetro tiene un valor predeterminado definido, que se usará aquí, o todavía podemos sobrescribirlo en la línea de comandos con --greeting, justo como lo hicimos antes. + +Entonces verifiquemos que funcione. "nextflow run hello-world.nf" + +Sin argumentos de línea de comandos esta vez, y verifiquemos si hizo lo correcto. + +"code results/output.txt". Y ahí está. Obtuvimos nuestro valor predeterminado. + +Bien, intentemos de nuevo, solo para verificar que no les esté diciendo ninguna mentira. Ejecutémoslo de nuevo, pero hagamos --greeting, y usemos el ejemplo del material de entrenamiento, digamos "¡Konnichiwa!" + +Vuelve a ejecutar, el workflow, y efectivamente, nuestro archivo de salida en la parte superior acaba de actualizarse con el nuevo valor que proporcionamos en la línea de comandos. + +Genial. Este es un aspecto realmente central para escribir cualquier workflow de Nextflow. Definir valores predeterminados sensatos en su código de pipeline, pero hacerlo muy fácil de configurar para el usuario final teniendo argumentos de línea de comandos en la terminal. + +Note que el usuario final puede sobrescribir la configuración en múltiples lugares diferentes. Pueden tener un archivo de configuración en su directorio principal, que se aplica a cada ejecución de Nextflow que hagan. Pueden tener un archivo de configuración en un directorio de lanzamiento. Pueden tener un archivo de configuración en un directorio de pipeline. Todas estas diferentes ubicaciones de configuración se cargan en un orden específico, que se describe en los documentos de Nextflow. + +Bien, ese es el final de la sección uno. Hemos tenido nuestro primer script de workflow en Nextflow con un process y un workflow. Hemos visto entradas, salidas, scripts y publicación, y cómo conectar parámetros y un canal de entrada a nuestro process. + +Felicitaciones, su primer paso hacia escribir código de Nextflow está completo. + +Tomen un pequeño descanso y los veré de vuelta en unos minutos para el capítulo dos. + +[Siguiente transcripción de video :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/es/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..84902efae2 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Parte 2: Hola Channels - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra únicamente la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../02_hello_channels.md). + + Los números de sección mostrados en la transcripción se proporcionan solo con fines indicativos y pueden no incluir todos los números de sección de los materiales. + +## Bienvenida + +Hola, bienvenidos a la parte dos de Hello Nextflow. + +Este capítulo se llama Hello Channels. Vamos a hablar sobre esta parte fundamental de Nextflow. + +Los channels son las cosas que conectan los diferentes pasos en su pipeline, la forma en que sus datos y lógica fluyen a través de su flujo de trabajo. + +Está bien, comencemos. + +Comencemos yendo a training.nextflow.io + +Hello Nextflow en la barra lateral y haciendo clic en la parte dos. Hello Channels. + +Todo el material está escrito aquí abajo para que pueda seguir a su propio ritmo y capturar cualquier cosa que haya podido perder. + +Una vez que tenga el sitio web abierto, puede cargar Codespaces y continuaremos desde donde estábamos al final del último capítulo. + +## 0. Calentamiento: Ejecutar hello-channels.nf + +Para este capítulo, vamos a editar un archivo diferente. Este se llama Hello Channels, así que puede encontrarlo en la barra lateral, haga doble clic para abrirlo. + +Ahora, si acaba de venir del capítulo uno, este archivo le resultará muy familiar. El punto de partida aquí es básicamente donde terminamos el capítulo uno, con nuestro proceso llamado sayHello, nuestra entrada, salida, nuestro publishDir y nuestro params.greeting, y nuestro flujo de trabajo simple. + +Estamos comenzando con un archivo nuevo, por lo que es un terreno nivelado para todos, pero puede continuar con su archivo anterior si lo prefiere. + +Nota, también he eliminado todos los archivos .nextflow\* y los directorios work aquí, solo para que sea un punto de partida limpio. No importa si hace eso o no, depende de usted. + +Está bien. Comencemos verificando que este pipeline todavía funciona como esperamos. Voy a mostrar el terminal aquí. + +Hacer "nextflow run hello-channels.nf" y presionar enter. + +Va a ejecutar ese pequeño flujo de trabajo, ejecuta nuestro paso sayHello, genera un directorio work con ese hash, y aquí está nuestra carpeta de resultados y ahí está nuestro archivo de salida, tal como esperábamos de nuestro params.greeting predeterminado. + +Eso es genial. Exactamente lo mismo que el capítulo uno, funcionando como esperamos. + +## 1. Proporcionar entradas variables mediante un channel explícitamente + +En el capítulo uno, ya estaba usando channels, simplemente no se daba cuenta. Cuando especificamos una cadena aquí, Nextflow automáticamente creó un channel alrededor de esa cadena para nosotros, solo porque sabía que estábamos llamando a un proceso, así que necesitábamos un canal de entrada. + +Lo primero que vamos a hacer es hacerlo explícito escribiendo realmente el channel en sí. + +## 1.1. Crear un canal de entrada + +Entonces voy a ir al workflow aquí en la parte inferior del script, y voy a decir greeting_ch. Esta es una convención que a menudo usamos en código Nextflow de tener un guión bajo ch al final de un nombre de variable cuando es un channel, solo para que sea fácil identificar que es un channel, pero no tiene que hacer eso. Igual a channel of Hello Channels. + +Lo que acabamos de usar es algo llamado "Channel Factory" en el lenguaje de Nextflow. Esto es esto aquí, estamos estableciendo esta variable a un nuevo channel, y este channel factory aquí está creando un channel para nosotros de una manera particular. + +Hay un puñado de diferentes channel factories que Nextflow tiene, para crear channels desde diferentes tipos de entradas. Dot of es el más simple, y simplemente toma cualquier cadena que le demos. + +Note que cuando paso el cursor sobre estas palabras en VS Code, la extensión de Nextflow me está dando una ventana emergente explicando lo que hace esta sintaxis, y también hay un texto de leer más en la parte inferior de esa ventana emergente. + +Si hago clic en eso, abrirá los documentos de Nextflow en una nueva pestaña y me llevará directamente a la documentación para esta cosa específica. En este caso para channel.of. + +## 1.2. Agregar el channel como entrada a la llamada del proceso + +Note que la extensión también nos está dando una advertencia, diciendo que hemos creado un nuevo channel aquí, pero no está siendo usado por nada. + +Entonces, arreglemos eso. Voy a tomar el nuevo nombre del channel y voy a reemplazar este params.greeting con nuestro nuevo channel. + +Note que ya no estamos usando la bandera de línea de comandos --greeting ahora, params.greeting no se está usando, estamos volviendo a codificar esta cadena de forma fija. Está bien. Solo estoy tratando de mantener las cosas simples. Volveremos más tarde y usaremos los params nuevamente. + +## 1.3. Ejecutar el comando workflow nuevamente + +Está bien, verifiquemos que esto funciona. Abro el terminal y noto de nuevo. Nextflow run hello channels. Verifico output.txt, y ahí está. + +Gran ejemplo un poco aburrido, haciendo exactamente lo mismo que hicimos antes, pero ahora al menos la lógica es un poco más clara. Estamos siendo explícitos sobre escribir un nuevo channel. + +Efectivamente acabamos de escribir más código para hacer lo mismo. Pero esto comenzará a tener más sentido a medida que nos volvamos un poco más complicados con la forma en que creamos nuestros channels. + +## 2. Modificar el workflow para ejecutar en múltiples valores de entrada + +Está bien, hagamos esto un poco más interesante. Es muy raro que quiera ejecutar un pipeline de Nextflow en una sola entrada, así que démosle varias entradas. + +## 2.1. Cargar múltiples saludos en el canal de entrada + +Desde los documentos aquí. Voy a copiar estas diferentes cadenas, tres de ellas. Hello, Bonjour, Olà. Oh, obtengo Esperanza. Copilot está sugiriendo un par más. Entonces tabulemos e ingresemos esos. + +Los documentos de Nextflow aquí nos dicen que podemos dar múltiples valores a este operador, por lo que debería funcionar, pero probémoslo y veamos qué sucede. + +## 2.1.2. Ejecutar el comando y observar la salida del registro + +Bueno. Sí y no. Veamos. Dice que cinco de cinco tareas se han ejecutado aquí, pero solo nos muestra un hash, lo cual es un poco extraño. Está bien. Todo está como se esperaba aquí. Por defecto. Nextflow usa un tipo especial de salida a un terminal llamado códigos de control ANSI, lo que significa que sobrescribe ciertas líneas para dar una vista comprimida agradable de todos los diferentes procesos que se están ejecutando. + +Esto tiene mucho más sentido cuando tiene flujos de trabajo más grandes y está ejecutando cientos o miles de muestras diferentes. Puede generar tanta salida en el terminal que es imposible de ver, mientras que esta vista de actualización le da un progreso en tiempo real. + +## 2.1.3. Ejecutar el comando nuevamente con la opción -ansi-log false + +Si lo desea, puede ejecutarlo de nuevo, y esta vez voy a usar un argumento central adicional de Nextflow con un solo guión diciendo, "-ansi-log false". Esto usa la versión anterior de la salida de registro de Nextflow. Y aquí puede ver todos los procesos individuales que se han lanzado. + +Depende de usted si hace esto o no. La salida de Nextflow es exactamente la misma en ambos casos. + +## 2.2. Asegurar que los nombres de los archivos de salida sean únicos + +Está bien, echemos un vistazo a los archivos de salida, luego iremos a results. Pero solo hay un único archivo de salida. ¿Qué pasó? Vimos que el proceso se había ejecutado muchas veces. Podemos ir al directorio work y ver todos los diferentes hashes, todas las tareas se ejecutaron correctamente. Pero si recuerda en nuestro proceso aquí, estamos guardando todo en un archivo output.txt y luego publicando eso en este directorio. + +Entonces, el mismo archivo fue creado cinco veces, y luego fue sobrescrito cinco veces. Y solo tenemos la tarea que sucedió ejecutarse al último. + +## 2.2.1. Construir un nombre de archivo de salida dinámico + +La forma en que arreglamos esto es usando un nombre de archivo de salida dinámico. Aquí ya tenemos una variable llamada greeting dentro del proceso, por lo que podemos usar eso en el nombre del archivo de salida. Copio eso y hago $greeting-output.txt. + +Voy a rodear esto entre comillas, solo para que bash no se confunda con ningún espacio que pueda colarse aquí. Y luego voy a tomar el mismo nombre de archivo y actualizar la salida aquí. + +Es realmente importante que la salida coincida con esto, porque de lo contrario, este archivo no se encontrará y Nextflow se bloqueará. + +Voy a hacer una edición más realmente importante, que es que voy a cambiar estas comillas simples por comillas dobles. Note que el color del código cambió cuando hice eso. Esta variable solo se expande si usamos comillas dobles. Si uso comillas simples aquí, se usa como un valor literal, y obtendría un solo archivo llamado $greeting-output, que no es lo que quiero. + +## 2.2.2. Ejecutar el workflow + +Entonces pongamos las comillas dobles de nuevo y probémoslo. + +Solo voy a limpiar mi directorio antes de comenzar, para que sea fácil ver los nuevos archivos. Voy a eliminar cualquier cosa llamada .nextflow, work y results. + +Y voy a ejecutar ese comando Nextflow de nuevo y veamos qué archivos se crean. Entonces ejecuta los cinco procesos allí. Si estaba mirando muy de cerca, podría haber visto que la línea se actualizaba mientras se estaba ejecutando. + +Y ahora podemos ir al directorio results, y efectivamente, tenemos cinco salidas diferentes, y todas tienen el prefijo del saludo diferente. + +Si abro cada uno de estos, veremos que cada uno contiene el saludo correspondiente. Fantástico. Eso es lo que queremos. + +## 3. Usar un operador para transformar el contenido de un channel + +Está bien, entonces ahora sabemos qué son los channels y sabemos qué son los channel factories. ¿Qué hay de los operadores? Este es otro término para parte del lenguaje Nextflow, que es una serie de funciones que nos permiten operar en channels para hacer ciertas cosas con ellos. Nextflow viene con un conjunto de operadores, que nos permiten manipular channels de diversas maneras. + +## 3.1. Proporcionar un array de valores como entrada al channel + +Trabajemos a través de esto con un ejemplo. Digamos que queremos tomar estas cadenas de entrada, pero en lugar de simplemente ponerlas directamente en un channel factory, queremos definirlas como un array. + +## 3.1.1. Configurar la variable de entrada + +Entonces voy a tomar estas y hacer eso como una nueva línea arriba y decir, greetings, array. + +Ahí vamos. Voy a tomar esa variable de array y ponerla en el channel.of, y presiono guardar. + +## 3.1.3. Ejecutar el workflow + +Ahora, veamos qué pasa. Vuelvo a mi terminal. Voy a limpiar todos esos archivos temporales de nuevo. Y ejecutemos el workflow. + +No está bien. Está bien. Se rompió. Está bien. Esperaba que se rompiera esta vez. Depurar qué sale mal cuando un workflow de Nextflow falla es una parte clave de ser un desarrollador de Nextflow. Esto sucederá mucho y es importante entender qué dice el mensaje de error y cómo tratarlo. + +Los mensajes de error de Nextflow son en realidad bastante estructurados. Nos dice qué proceso salió mal. Nos da un mensaje de error por una razón. Dice cuál fue el comando que intentó ejecutar dentro de esa tarea particular, cuál fue el estado de salida, cuál fue la salida en donde estaba ese directorio work de la tarea. + +Note que puedo hacer clic con opción en esto en VS Code y lo abre en una barra lateral para que pueda ir directamente allí y ver todos estos archivos ocultos, de los que hablamos en el capítulo anterior, incluido el archivo .command.sh. Este puede ver que es el mismo que los comandos que se ejecutaron aquí. + +Al mirar este archivo, podemos tener una idea de qué podría haber salido mal aquí en lugar de ejecutar una sola tarea para cada elemento en el array como lo hizo la última vez, simplemente proporcionó todo el array de una vez como una cadena. Entonces necesitamos desempaquetar ese array en valores individuales antes de pasarlo al channel. Volvamos y veamos si podemos hacer eso usando un operador. + +## 3.2. Usar un operador para transformar el contenido del channel + +En este caso, no vamos a cambiar el array antes de pasarlo al channel. Vamos a ajustar el channel para que se comporte de la manera que esperamos. Vamos a hacer eso usando el operador flatten puede hacer punto comenzar a escribir y podemos ver que la extensión de VS Code comienza a sugerir todos los diferentes operadores que tenemos disponibles. + +## 3.2.1. Agregar el operador flatten() + +Y voy a seleccionar flatten. Note que el espacio en blanco no importa en este contexto para Nextflow. Entonces puede poner estos operadores en una nueva línea si lo desea. Entonces puedo bajar esto aquí e indentarlo para que quede debajo de ".of" y verá que las personas a menudo encadenan muchos operadores como este en un channel e indentan de esta manera para que sea más fácil de leer. + +También puede ver, como antes, puedo pasar el cursor sobre esto y leer lo que está haciendo el operador flatten, y también seguir un enlace a la documentación si quiero. + +Entonces, este operador está tomando este channel, que tiene un solo array dentro de él, y separando los valores del array. + +## 3.2.2. Agregar view() para inspeccionar el contenido del channel + +Podemos echar un vistazo a los channels usando el operador especial view, y voy a agregar un par de ellos aquí. Esto es un poco como usar declaraciones de impresión en otros lenguajes. Entonces voy a hacer dot view y luego voy a usar estas llaves onduladas. + +Esto se llama un closure. Básicamente esto da código adicional al operador view, que ejecutará en cada elemento dentro del channel. En este caso, voy a decir greeting before flatten. Greeting. + +Estoy definiendo una variable aquí, que está solo dentro del alcance de este closure. Entonces esta variable solo se usa aquí y podría llamarla como quisiera. No importa realmente. Solo estoy usando greeting para que sea fácil de leer. + +En algunos pipelines de Nextflow, puede ver que las personas usan una variable implícita especial llamada "$it". Así. Esta es una variable especial dentro del código Nextflow, que es una forma abreviada para que no tenga que hacer la pequeña definición de una variable. Sin embargo, con el tiempo estamos pensando que esto no es muy claro para las personas que son nuevas en Nextflow, y desalentamos el uso de "$it" ahora. + +Entonces voy a mantenerme con el comportamiento anterior de greeting y usarlo así porque eso es más explícito y es más claro sobre lo que está sucediendo. + +Entonces voy a copiar esta línea y hacer exactamente lo mismo de nuevo después de los argumentos flatten. El operador view es un poco especial porque hace algo en los elementos, pero también simplemente continúa pasándolos al siguiente operador para que podamos encadenarlo en medio de una cadena de operaciones como esta, e imprimirá el estado allí y seguirá adelante. Entonces, con suerte, esto nos mostrará cómo se ve el channel antes y después del operador flatten. + +## 3.2.3. Ejecutar el workflow + +Probémoslo. Limpio. Limpio todo en el espacio de trabajo. Ejecuto el pipeline de nuevo. + +Está bien, entonces podemos ver que ejecutó nuestros cinco procesos. De nuevo, no se bloqueó con un error, así que eso es definitivamente bueno. Y ahora tenemos el before flatten y efectivamente tenemos nuestro array y tenemos after flatten, impreso cinco veces una vez para cada elemento del array. Eso es exactamente lo que esperábamos. Entonces esas son realmente buenas noticias. Y eso encaja exactamente con lo que esperaríamos del código. + +Ya no necesitamos estas declaraciones de depuración, así que puedo comentarlas o eliminarlas. Voy a eliminarlas solo para mantener mi código agradable y limpio. Está bien, genial. Este ejemplo ahora está funcionando bien y podemos comenzar a ver cómo los channels pueden hacer una lógica un poco más complicada. + +## 4. Usar un operador para analizar valores de entrada desde un archivo CSV + +Ahora vamos a intentar hacer esto usando un archivo con una serie de entradas en su lugar. Esta es una forma muy común de escribir pipelines de Nextflow usando una hoja de muestras o un CSV de metadatos. + +## 4.1. Modificar el script para esperar un archivo CSV como la fuente de saludos + +Si voy a la barra lateral, puede ver greetings.csv en el repositorio de ejemplo, y este es un archivo CSV muy, muy simple que solo contiene tres líneas con tres saludos diferentes. Veamos si podemos usar este archivo CSV dentro de nuestro workflow. + +Ahora voy a volver a usar params como lo hicimos en el capítulo uno, para que podamos tener una entrada de línea de comandos. + +Voy a eliminar este array greetings. + +## 4.1.1. Cambiar el parámetro de entrada para apuntar al archivo CSV + +Voy a establecer params greeting al nombre del archivo, que es greetings.csv, y voy a usar esta variable especial para generar el channel. Voy a poner eso ahí, y los errores desaparecen. Recuerde que esto está estableciendo esta variable por defecto ahora. Entonces, si ejecuto el pipeline sin ningún argumento, usará greetings.csv, pero podría hacer --greeting para sobrescribir esta variable si quisiera. + +## 4.1.2. Cambiar a un channel factory diseñado para manejar un archivo + +Está bien, estamos pasando un archivo ahora en lugar de una cadena o un array de cadenas, por lo que probablemente necesitamos un channel factory diferente. + +Nos vamos a deshacer de "of" que hemos estado usando hasta ahora, y en su lugar usar .fromPath. Esto hace exactamente lo que suena. Crea un channel con rutas en lugar de valores, usando un nombre de archivo de cadena o glob. También voy a eliminar el operador flatten ya que ya no necesitamos esto, ahora que estamos pasando un archivo. + +## 4.1.3. Ejecutar el workflow + +Voy a presionar guardar, abrir el terminal, ejecutar el workflow, y luego ver qué sucede. + +Está bien. Se bloqueó de nuevo. No se preocupe. También esperaba este. Echemos un vistazo al mensaje de error y veamos si podemos averiguar qué está saliendo mal. Aquí podemos ver el comando ejecutado, y un poco como antes donde teníamos todo el array impreso. Ahora tenemos la ruta del archivo siendo repetida en el comando, en lugar de recorrer el contenido del archivo. + +## 4.2. Usar el operador splitCsv() para analizar el archivo + +Entonces, para usar el contenido del archivo en su lugar, necesitamos otro operador. El operador que vamos a usar para este es llamado splitCsv. Tiene sentido, porque es un archivo CSV que estamos cargando. + +## 4.2.1. Aplicar splitCsv() al channel + +Ok, entonces splitCsv. Cerrar paréntesis. No necesitamos ningún argumento aquí. Y de nuevo, voy a usar algunos operadores view para dar una idea de lo que está pasando aquí. + +.view csv after splitCsv. Before split Cv.s + +## 4.2.2. Ejecutar el workflow nuevamente + +Está bien, intentemos ejecutar esto y ver qué sucede. + +Está bien, tenemos un poco más de salida esta vez, pero todavía falló. Podemos mirar las declaraciones view, y aquí puede ver before split CSV, y tenemos una ruta de archivo como vimos en el mensaje de error anterior. After split CSV, ahora tenemos tres valores correspondientes a las tres líneas en el archivo CSV. + +Sin embargo, puede ver que cada uno de estos valores está rodeado por corchetes. Entonces cada uno de esos era un array en sí mismo, y eso nos ha dado el mismo área que teníamos antes donde está intentando repetir un array en lugar de solo una cadena única. + +Si pensamos en un archivo CSV, esto tiene sentido. Típicamente, un archivo CSV tendrá filas y columnas, por lo que split CSV hace un array bidimensional. La primera dimensión del array es cada fila, y luego hay una segunda dimensión, que es cada columna para cada fila. + +Entonces aquí solo tenemos un solo valor en cada línea, por lo que tenemos una sola columna, por lo que tenemos un array de un elemento para cada línea del archivo. + +Está bien. Solo necesitamos otro operador para colapsar ese array para cada línea del archivo CSV analizado. Limpiemos esto. Deshagámonos de un terminal y veamos qué podemos hacer. + +## 4.3. Usar el operador map() para extraer los saludos + +Ahora podríamos usar el operador flatten de nuevo, que usamos antes. Hemos visto cómo puede colapsar un array en una serie de valores, lo que funcionaría muy bien aquí. Pero voy a usar la oportunidad para demostrar otro operador, que es muy común dentro de los flujos de trabajo llamado el operador map. + +## 4.3.1. Aplicar map() al channel + +Voy a hacer dot map y voy a hacer item item[0]. + +Si escribe mucho código en otros lenguajes, puede estar familiarizado con el operador map ya. Toma un iterable, como un array o un channel, y hace alguna operación en cada valor de eso. + +Aquí estamos diciendo que deberíamos definir una variable llamada item dentro del alcance de este closure, y luego queremos devolver, solo el primer valor en ese array. Entonces item índice cero. + +Esto está efectivamente aplanando el array. Puede ver cómo podríamos extender esto para ser más complejo, sin embargo: si nuestro archivo CSV tuviera seis columnas, pero solo estamos interesados en la cuarta columna, podríamos acceder a un índice específico aquí. O hacer cualquier otro tipo de operación en el valor antes de pasarlo al procesamiento posterior. + +Entonces el operador map es extremadamente flexible y muy poderoso para modificar channels en vuelo. Pongamos otra declaración view solo para que podamos ver lo que está haciendo en nuestra ejecución. Puedo adjudicar esa línea y moverla hacia abajo. Y after map. + +## 4.3.2. Ejecutar el workflow una vez más + +Abramos el terminal e intentemos ejecutar el workflow. + +Está bien, no hay errores esta vez. Esa es una buena señal. Ahora podemos revisar todas estas diferentes salidas de las declaraciones view. Before split CSV, teníamos una sola ruta. After split CSV, teníamos los arrays de un solo valor, y luego after map, tenemos solo los valores sin ninguna sintaxis de array. Vayamos al directorio results, y aquí están nuestros archivos de salida comportándose exactamente como queríamos. + +Hay un pequeño bonus aquí. Puede ver realmente que los operadores view están ligeramente mezclados en el orden en que han hecho la salida. Esto se debe a que Nextflow está haciendo la paralelización de estas diferentes tareas. Entonces, después de que dividió el CSV, hay tres elementos en este channel, y está manejando el procesamiento de esos tres elementos en paralelo automáticamente. Eso significa que el orden de las salidas es estocástico y puede variar. En este caso, simplemente sucedió que algunos de los operadores view regresaron después de que el paso subsiguiente se había completado, y por eso vino en este orden. + +Si ejecuto el mismo workflow de nuevo. Entonces, efectivamente, ha venido en un orden diferente y esta vez tenemos los split CSV y los maps en el orden que esperaríamos. + +Entonces solo tenga en cuenta, no puede confiar en el orden de salidas de una tarea de proceso porque Nextflow está manejando esta paralelización para usted automáticamente. Nextflow hace eso por usted con su lógica de flujo de datos, y ese es el verdadero poder de Nextflow. + +Está bien, este es probablemente uno de los capítulos más importantes de todo el entrenamiento. Una vez que comprenda los channels, los channel factories y los operadores, comenzará a entrar en la fortaleza de Nextflow y lo que lo hace único como lenguaje de programación. Esta funcionalidad permite a Nextflow paralelizar todos sus flujos de trabajo para usted y generar lógica de flujo de trabajo extremadamente compleja con una sintaxis muy limpia y un modelo de flujo de datos de empuje. Puede ser un concepto un poco extraño al principio, pero una vez que se acostumbre a escribir código como este, rápidamente se sentirá natural y antes de que se dé cuenta, estará escribiendo flujos de trabajo fantásticos. + +Tome un descanso, una taza de té, camine y pasemos al capítulo tres, donde comenzamos a extender estos conceptos a flujos de trabajo más complejos. Nos vemos en el próximo video. + +[Transcripción del siguiente video :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/es/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..83431f1c06 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Parte 3: Hola Workflow - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra únicamente la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../03_hello_workflow.md). + + Los números de sección mostrados en la transcripción se proporcionan solo con fines indicativos y pueden no incluir todos los números de sección de los materiales. + +## Bienvenida + +Hola, bienvenidos a la parte tres del curso de entrenamiento "Hola Nextflow". + +Este capítulo se llama "Hola Workflow". + +En el capítulo dos, construimos un flujo de trabajo simple de un proceso, pero en realidad, los pipelines son útiles porque pueden encadenar múltiples pasos de análisis juntos. + +En este capítulo, vamos a tomar ese ejemplo inicial y ampliarlo para que sea un poco más realista. + +Vamos a agregar algunos pasos adicionales y vamos a ver cómo usamos los canales para conectar esos pasos. + +Vamos a ver múltiples tareas, que pueden colapsar en un solo proceso y vamos a ver procesos que pueden tener múltiples entradas y múltiples salidas. + +Bien, comencemos. + +Así que empecemos. Igual que antes. Vamos a training.nextflow.io. Hola Nextflow, capítulo tres. Hola Workflow. Y abramos nuestro espacio de trabajo. He limpiado todos mis archivos de trabajo de mis capítulos anteriores y voy a abrir Hola Workflow. + +Ahora este es el mismo archivo en el que hemos estado trabajando hasta ahora, así que debería verse familiar. Tenemos nuestro proceso say hello. Tenemos nuestro params.greeting con su archivo greetings CSV, y tenemos nuestro workflow en la parte inferior, que carga ese archivo CSV, crea el canal y lo pasa a nuestro proceso. + +## 0. Calentamiento: Ejecutar hello-workflow.nf + +Si lo desea, podemos probar esto y verificar dos veces que esté funcionando como esperamos. Abra una terminal para nextflow run hello workflow nf y presione enter. + +Bien, genial. Nuestros tres procesos se ejecutan. Tenemos nuestro directorio de resultados con nuestras tres salidas. Bonjour. Hello. Holà. Así que cerremos esos archivos, cerremos la terminal, volvamos al script. + +## 1. Agregar un segundo paso al flujo de trabajo + +Bien. Para nuestro ejemplo, nos mantenemos básicos e intentamos mantenernos agnósticos del dominio. Así que nuestro segundo proceso solo va a manipular estas cadenas, estas palabras, de una manera simple. Vamos a usar el comando Unix translate para tomar estos archivos y ponerlos todos en mayúsculas. Lo hacemos con el comando "tr". + +## 1.1. Definir el comando de conversión a mayúsculas y probarlo en la terminal + +Podemos probar esto solo en la terminal bash, y ver si funciona. Así que haces echo, Hello World, y luego pasas eso con el carácter pipe a tr, y le damos un patrón de reconocimiento, a a z y a qué debería traducirse. A a Z en mayúsculas. + +Esto es muy simple porque está literalmente haciendo los caracteres de A a Z. Así que no funcionará con nada que tenga acentos o algo así. Pero para los propósitos del ejemplo, debería entender la idea. + +Voy a presionar enter y se imprime en una terminal, HELLO WORLD en mayúsculas. Y como antes, podríamos redirigir esto a un archivo si quisiéramos. Outfile. + +Bien. Limpiemos esto. + +## 1.1. Escribir el paso de conversión a mayúsculas como un proceso de Nextflow + +Volvamos a nuestro script y escribamos un nuevo proceso para manejar este comando bash. Voy a copiar el proceso anterior, pegarlo debajo, y llamarlo convert to upper. Para mayúsculas. Voy a usar el mismo publishDir results, pero voy a hacer algunos cambios aquí. En lugar de tomar un val, voy a tomar un path input file, y voy a tener un prefijo aquí upper, para que nuestros archivos de salida no sobrescriban la salida. Y voy a usar el nombre de variable de la entrada. Y luego voy a cambiar un script aquí abajo, y en su lugar voy a usar cat en el archivo de entrada y al igual que hicimos en Bash TR, a-z, upper input file .txt. Bien, hagamos clic en guardar. + +## 1.2. Agregar una llamada al nuevo proceso en el bloque workflow + +Ahora si me desplazo hacia abajo, necesitamos realmente llamar a este proceso. Solo agregar el proceso al script no es suficiente. Tenemos que decirle a Nextflow que necesitamos ejecutar este proceso y dónde hacerlo. + +Así que voy a hacer aquí, convert to upper y + +bien, estamos obteniendo un error aquí que dice que espera un argumento. Por supuesto, necesitamos pasar algo a este proceso para que realmente tenga algo que hacer. + +## 1.3. Pasar la salida del primer proceso al segundo proceso + +Lo que vamos a hacer es vamos a tomar la salida de este proceso. Así que tomo el nombre, say hello, y cuando hago dot out. + +Para un ejemplo simple como este, donde tenemos un proceso que tiene solo una salida y estamos pasando eso a un nuevo proceso, por lo que tiene una entrada, eso debería ser todo lo que necesitamos. Así que voy a hacer clic en guardar, abrir la terminal, y tratemos de ejecutar esto nuevamente. + +## 1.4. Ejecutar el flujo de trabajo nuevamente + +Ahora, no he limpiado mi directorio de trabajo de la última vez que ejecuté este flujo de trabajo. Voy a ejecutarlo nuevamente y voy a usar esto como una oportunidad para mostrar cómo funciona el almacenamiento en caché parcial. Así que si hago single dash resume. Con suerte debería reutilizar las salidas de ese primer proceso, que eran exactamente las mismas que la última vez que ejecuté. Pero ahora tenemos un nuevo proceso aquí que no se ha ejecutado antes, que se ejecuta desde cero. Y efectivamente, puede ver que el primer proceso usó las salidas de caché, y la segunda salida ejecutó tres de tres. También puede ver que tenemos ambos procesos aquí ahora, nuestro primer proceso, say hello, se ejecutó tres veces, y nuestro segundo proceso convert to upper se ejecutó tres veces. + +Si ejecuto esto nuevamente, como recordatorio, con -ansi-log false, deberíamos ver que se ejecutaron seis tareas de proceso diferentes, tres para cada una de ellas. Así que esto está haciendo exactamente lo que esperábamos. El primer proceso se está ejecutando tres veces, pasando esas salidas a un segundo proceso, que luego se está ejecutando tres veces. + +Así que echemos un vistazo dentro del directorio de trabajo y veamos cómo Nextflow está manejando estas entradas de archivos. Si tomo este directorio hash aquí del segundo proceso, podemos usar un comando tree nuevamente con -a solo para mirar estos archivos. Puede ver aquí que tenemos nuestro archivo de entrada, que es el archivo Bonjour-output.txt, y eso es en realidad un enlace simbólico. Eso es lo que nos muestra esta flecha, y está apuntando al archivo en el directorio de trabajo anterior. + +Esto tiene sentido. Nextflow maneja la ejecución de cada tarea en su propio directorio encapsulado, por lo que está completamente autocontenido. Sin embargo, necesita proporcionar los archivos de pasos anteriores como entrada. En lugar de salir fuera del directorio de trabajo para obtener esos archivos, Nextflow los prepara en el directorio de trabajo. + +Si tenemos un sistema de archivos compartido como aquí, hace eso usando un enlace simbólico para que no use ningún espacio de archivo adicional. Si usamos almacenamiento en la nube con buckets en diferentes ubicaciones, buscaría esos archivos y realmente los copiaría en el directorio de trabajo. + +Echemos un vistazo al archivo command sh. Si hago code work, command sh, puede ver, efectivamente, está accediendo a ese archivo desde el directorio local. Así que todo está muy autocontenido y limpio. + +También podemos verificar el directorio de resultados y asegurarnos de que estos archivos se hayan producido correctamente. Y efectivamente, en resultados, podemos ver todos los archivos de salida del primer proceso y todos los archivos de salida del segundo. Y todos están en mayúsculas como esperábamos. + +Aquí es donde el poder de Nextflow comienza a brillar. Con un código muy mínimo y Nextflow manejó la ejecución en paralelo de estas tareas con una encapsulación limpia dentro de directorios de trabajo separados y preparación de archivos de entrada y salida y publicación de archivos, todo automáticamente para nosotros, justo desde el principio. Así que puede ver cómo, a medida que escalamos esta complejidad de nuestros flujos de trabajo de análisis, esta funcionalidad es realmente, realmente valiosa. + +## 2. Agregar un tercer paso para recolectar todos los saludos + +Bien. Estos pasos fueron uno a uno. Tuvimos una salida del primer proceso yendo a una entrada para el segundo proceso. A continuación, vamos a hablar sobre cómo recolectar estas diferentes salidas en una sola tarea de proceso, lo cual es nuevamente algo muy común de hacer. Así que rápidamente abramos la terminal y hagamos una ejecución de prueba de esto. + +## 2.1. Definir el comando de recolección y probarlo en la terminal + +Voy a hacer trampa y copiar el código bash de ejemplo del material de entrenamiento y simplemente presionar enter. + +Lo que podemos ver aquí es que ejecutamos este comando echo tres veces en tres archivos de salida diferentes, que puedo ver aquí. Y luego usamos el comando cat para imprimir la salida de cada uno de estos tres archivos diferentes, y redirigir eso a un único archivo recolectado. + +Y si hago "cat COLLECTED-output", puede ver que tiene el contenido de esos tres archivos diferentes, ahora en un solo archivo. + +## 2.2. Crear un nuevo proceso para hacer el paso de recolección + +Así que veamos si podemos replicar lo mismo dentro de nuestro pipeline de Nextflow. + +Desplacémonos hacia arriba y creemos un tercer proceso. Voy a copiar este anterior, y esta vez lo voy a llamar Collect Greetings. + +En la terminal bash, lo llamamos collected output txt. Así que voy a decir lo mismo path output aquí. Y voy a hacer la redirección aquí, para que se guarde de la misma manera. + +Bien. Necesitamos cambiar lo que sucede al principio de ese comando, y necesitamos pensar en cuál es el archivo de entrada aquí. De hecho, este proceso va a tomar múltiples archivos de entrada. Voy a mantener path y voy a cambiar esto a una nueva variable llamada input files, en plural. + +Luego voy a nuevamente, hacer cat con ellos como hicimos en nuestro script bash. Y voy a usar la variable aquí. + +Ahora, podrías pensar que esto no funcionaría. Hemos visto fallas anteriormente donde se pasó un arreglo de cadenas o un arreglo de rutas a un proceso y eso causó un error. Pero de hecho, aquí Nextflow va a manejar esto automáticamente para nosotros de la manera correcta. Va a tomar varios archivos de entrada diferentes, y solo va a imprimir las diferentes rutas de archivos aquí. + +Por supuesto, ayuda que el comando cat pueda tomar una serie de nombres de archivos como este. Si estuviera usando un comando diferente que requiriera un argumento antes de cada ruta de archivo o algo así, tendríamos que tener un poco más de código aquí y lógica para poder manejar la iteración de estas rutas de archivo. Pero en este caso, debería funcionar simplemente. + +## 2.3. Agregar el paso de recolección al flujo de trabajo + +Bien, bajemos al workflow y agreguemos nuestro nuevo proceso. Collect greetings. Y nuevamente, tomemos la salida de convert to upper out. Guardemos esto. + +Démosle una oportunidad. nextflow run hello workflow. + +Bien, el flujo de trabajo se ejecutó, pero algo es un poco extraño aquí. Tenemos tres ejecuciones del primer paso, lo cual esperamos. Tres tareas para el segundo, pero también tenemos tres tareas al final cuando esperábamos tener solo una sola tarea aquí fusionando todas las salidas. + +Si vamos a nuestro directorio de resultados. También vemos que la salida recolectada solo tiene un valor único en lugar de los tres. Esto es porque ese archivo de salida fue sobrescrito tres veces con tres valores diferentes. + +Esto tiene sentido porque pasamos una salida a una entrada aquí de la misma manera que hicimos en el paso anterior. + +## 2.4. Usar un operador para recolectar los saludos en una sola entrada + +Así que necesitamos un operador aquí para tomar este canal con tres elementos y colapsarlos a un solo elemento, para que ese proceso final solo se ejecute una vez. + +Para hacer eso, vamos a usar el operador collect. Puedo hacer esto directamente dentro del workflow. Puedo hacer .out y encadenar un operador aquí al final .collect. + +Presionar guardar. Y luego para los propósitos de este entrenamiento, también voy a hacer algunos operadores view como hicimos antes, para que podamos echar un vistazo a este canal antes y después de usar el operador collect, para que podamos entender qué está sucediendo. + +Voy a tomar este canal, deshacerme del collect y dot view greetings, y luego voy a duplicar esta línea, agregar el operador collect. Y cambiar eso a after. + +Esto es separado de donde estamos llamando esto, pero eso está bien porque estamos usando las mismas llamadas de operador en el mismo canal de salida. + +Bien, guardemos y probémoslo en la terminal. Voy a ejecutar nextflow run. Hello, workflow. Volver a ejecutar nuestro script. + +Bien. Esto se ve mejor. Como antes, podemos ver que los dos primeros procesos se ejecutan tres veces y ahora nuestro proceso final solo se ejecutó una vez. + +Si miramos lo que fue impreso por el operador view, aquí abajo, dijimos before collect, que es esta salida aquí, y eso se imprimió tres veces. Y puede ver que hay una sola ruta para cada uno de esos. Y luego after collect, puede ver que tenemos este arreglo de tres rutas. Así que eso es como esperamos. + +Bien, revisemos el archivo de resultados y veamos si es lo que esperamos esta vez. Efectivamente, ahora hay tres líneas en el archivo - eso concatenó exitosamente estas tres salidas en un solo archivo de salida. Fantástico. + +Bien, voy a limpiar y pasemos al siguiente paso. Y voy a eliminar estas declaraciones view solo para mantener las cosas limpias. + +## 3. Pasar más de una entrada a un proceso para nombrar el archivo de salida final de forma única + +Bien. Hasta ahora, todos nuestros procesos solo han tomado una sola entrada. Ahora vamos a hacer un ejercicio donde agregamos más de una entrada a un proceso para ver cómo funciona esto. Para hacer esto, vamos a usar este ejemplo collect greetings. + +Cada vez que ejecuté el flujo de trabajo, sobrescribió ese archivo en el directorio de resultados, lo cual puede no ser lo que queremos. + +## 3.1. Modificar el proceso recolector para aceptar un nombre definido por el usuario para el archivo de salida + +Así que para este ejemplo, vamos a pasar un parámetro adicional para que podamos personalizar el nombre del archivo de salida. + +Agregar una segunda entrada a un proceso es muy simple. Solo agrego una segunda línea en el bloque input. Esta vez va a ser un valor, en lugar de una ruta, porque queremos pasar una cadena y voy a llamarlo batch underscore name. + +Ahora puedo usar esta variable en el bloque script, y voy a decir collected dash dollar batch name. + +Estoy usando llaves aquí alrededor del nombre de la variable. Eso es solo para mantenerlo separado del resto de una cadena, y probablemente no sea necesario en este caso, pero creo que hace que sea más fácil de leer. + +Bien. Finalmente, recuerde actualizar la ruta de salida porque ahora el nombre del archivo ha cambiado, así que voy a hacer lo mismo y poner el batch name en la salida de path como se esperaba. + +## 3.2. Agregar un parámetro batch de línea de comandos + +Ahora necesitamos pasar un nombre de lote desde algún lugar, y voy a crear un segundo parámetro para hacer esto para que podamos hacerlo en la línea de comandos cuando ejecutemos el flujo de trabajo. + +Así que voy a hacer params batch name, y por defecto, llamemos a esto test batch. Ahora puedo usar esta variable de parámetros especiales abajo, donde llamamos al proceso. + +Y efectivamente VS Code nos está diciendo que no hay suficientes argumentos para este proceso ahora, y que espera una segunda entrada. + +Simplemente hago coma y paso nuestra nueva variable y el error desaparece. + +Note que el orden de las entradas aquí es realmente importante. La primera entrada del proceso era la ruta, y la segunda entrada es el nombre. Si cambio el orden aquí, también debo cambiar el orden cuando llamo al proceso. De lo contrario. Siguiente, pasaremos el canal equivocado a la entrada equivocada. + +## 3.3. Ejecutar el flujo de trabajo + +Bien, probémoslo y veamos si funciona. Hagamos "nextflow run hello- workflow. Bien, se ejecutó como antes. Echemos un vistazo al directorio de resultados. + +Efectivamente, nuestro nombre de archivo aquí ahora se llama "collected test batch output txt". Fantástico. + +Y ahora veamos si podemos sobrescribir eso ejecutando nuevamente. Esta vez voy a hacer --batch_name para que coincida con ese nombre de variable de parámetro especial aquí. Y voy a llamarlo demo output. + +Ejecute el flujo de trabajo nuevamente y veremos si algo sucede. + +Bien, ahora tenemos un collected demo output .txt. Y debido a que este nombre de archivo es diferente a ese, no lo sobrescribió. Ambos están ahora presentes en el directorio de resultados. + +## 4. Agregar una salida al paso recolector + +Bien, así que ahí mostramos dar múltiples entradas a un proceso, pero ¿qué hay de múltiples salidas? Para este ejemplo, vamos a calcular el número de saludos que se procesan y producir eso como una salida secundaria para este paso collect greeting. + +## 4.1. Modificar el proceso para contar y producir el número de saludos + +Vamos a hacer un poco de truco aquí. Los procesos de Nextflow tienen este bloque script con una cadena multilínea, y eso se pasa como salida bash al dot comando dot sh. Pero en realidad podemos escribir cualquier código personalizado arriba de eso, y eso se ejecutará como parte de una tarea pero no se incluirá dentro del script bash. + +Una de las funciones incorporadas en la sintaxis de Nextflow se llama size. Así que voy a tomar la entrada de ruta, y voy a decir count underscore greetings, solo para definir un nombre de variable. Voy a tomar los archivos de entrada y voy a llamar "size" en él. + +Esta función contará el tamaño de este canal de entrada y lo asignará a una variable. + +Ahora podemos devolver esa variable como parte del bloque output. Así que decimos, val, porque es un valor, no un archivo. Y count greetings. + +Ahora esto es suficiente por sí mismo, y ahora podríamos acceder a estas diferentes salidas de este proceso. Sin embargo, tendríamos que acceder a ellas de manera posicional. Así que usando una clave de índice como cero y uno. + +Para que sea un poco más fácil obtener las salidas, podemos nombrarlas y hacemos eso usando una declaración emit. + +Así que hacemos coma emit out file o como quiera llamar a esto. Y hago aquí emit count. Esto es básicamente solo un decorador, que solo nos ayuda a escribir un código un poco más limpio para que podamos fácilmente referenciar las salidas específicas más adelante en el bloque workflow. + +## 4.2. Reportar la salida al final del flujo de trabajo + +Bien. Si me desplazo hacia abajo al bloque workflow, ahora puedo tomar las salidas de collect greetings, hacer collect greetings, dot out, y podemos ver nuestras dos salidas nombradas se sugieren aquí por la extensión de VS Code. Muy útil. + +Así que voy a hacer dot count para obtener el valor de conteo que acabamos de crear, y voy a hacer view, para que se imprima en la línea de comandos. Para que podamos verlo cuando ejecutemos el flujo de trabajo. + +Escribamos algo en el closure aquí solo para hacerlo un poco más agradable. num greetings, there were greetings greetings. + +Y en realidad no nos importa la otra salida porque no la estamos usando como entrada para ningún otro proceso. Pero puede ver cómo podríamos fácilmente pasar esto como entrada a otro proceso si quisiéramos, posteriormente. + +## 4.3. Ejecutar el flujo de trabajo + +Vamos a hacer clic en guardar. Echemos un vistazo a la terminal y probémoslo. + +Bien, fantástico. Aquí vamos. Hay tres saludos. Eso es exactamente correcto. + +Bien, gran trabajo. Ese es el final de este capítulo. Hemos terminado por llegar hasta aquí. Ahora está comenzando a construir un flujo de trabajo bastante realista, donde somos capaces de manejar entradas y salidas y lógica dentro de nuestro flujo de trabajo. + +A medida que estos archivos de flujo de trabajo se hacen más largos, comienzan a volverse un poco difíciles de manejar. Así que en el próximo capítulo, veremos cómo podemos modularizar el código de Nextflow en archivos separados para que sea más fácil encontrar y mantener el código dentro del flujo de trabajo. + +Únase a nosotros en el próximo video para el capítulo cuatro. Hola Modules. + +[Siguiente transcripción de video :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/es/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..6c2956122f --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Parte 4: Hola Módulos - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra solo la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../04_hello_modules.md). + + Los números de sección mostrados en la transcripción se proporcionan solo con fines indicativos y pueden no incluir todos los números de sección en los materiales. + +## Bienvenida + +Hola, bienvenido a la Parte Cuatro del curso de entrenamiento Hello Nextflow. + +Este capítulo se llama Hola Módulos, y hablaremos sobre cómo modularizar código Nextflow. Lo que vamos a hacer es tomar nuestro script de workflow y dividirlo en archivos separados. + +Esto hace que el código sea más fácil de navegar y mantener a medida que su workflow se hace más grande, y también hace posible compartir módulos entre pipelines para que si tiene múltiples pipelines usando la misma herramienta, solo necesite escribir ese process una vez. + +Un ejemplo clásico de esto es el repositorio de módulos nf-core, que tiene miles de herramientas diferentes en módulos listos para usar, los cuales puede instalar y utilizar en su workflow. + +Nextflow también puede trabajar con sub workflows, que son como módulos, pero tienen múltiples processes. Eso está fuera del alcance de este entrenamiento, pero funciona básicamente de la misma manera. + +Muy bien. Echemos un vistazo. + +Como siempre, comience yendo a training.nextflow.io. + +Vaya a "Hello Nextflow" en la barra lateral, y estamos en la parte cuatro: "Hello Modules". + +Ahora voy a saltar a mi entorno de GitHub Code Spaces y echar un vistazo al archivo "hello-modules". + +Como antes, estamos comenzando en el punto final del capítulo anterior, así que este script debería resultarle familiar. Tenemos nuestros tres processes, say hello, convert to upper y collect greetings, y en un simple workflow, que ejecuta estos tres comandos y emite un mensaje al final. Tenemos dos parámetros llamados greeting y batch, que especifica el nombre, que se utiliza para el archivo de salida recopilado al final. + +## 0. Calentamiento: Ejecutar hello-modules.nf + +Podemos verificar que este workflow todavía funciona como esperamos haciendo nextflow run hello, modules. + +Genial. Ejecutó tres tareas con cada uno de estos processes, una tarea recopilada, y nos dijo que hay tres saludos en este lote. Si entramos en results, tenemos nuestros diferentes archivos de salida aquí, incluida la salida recopilada test batch. + +## 1. Crear un directorio para almacenar módulos + +Bien. Hagamos algo de modularización. + +Generalmente es una buena idea poner los módulos en una subcarpeta en su repositorio de pipeline, solo para mantener las cosas ordenadas. Puede llamarla como quiera, pero por convención usualmente la llamamos modules. + +Así que vamos adelante, vaya a una terminal y haga make the modules. Puede verla aparecer en la barra lateral y VS Code aquí. + +## 2. Crear un módulo para sayHello() + +Entonces voy a crear un nuevo archivo para mi primer módulo. Puede hacer "touch" o "code" o puede hacerlo en la barra lateral, realmente no importa. Así que voy a hacer code modules y voy a nombrarlo según el process. Así que sayHello.nf. NF es una extensión de archivo tradicional para archivos Nextflow. + +Voy a presionar guardar aquí y podemos ver que aparece nuestro nuevo archivo de módulo. + +## 2.2. Mover el código del process sayHello al archivo del módulo + +Bien, a continuación voy a tomar el código del módulo del workflow. También voy a tomar el hash bang aquí y copiarlo primero para que sea claramente un archivo Nextflow. Y luego voy a tomar este process y voy a cortar. Así que voy a eliminarlo de mi script principal de workflow y voy a pegarlo en este nuevo módulo. + +Ese es todo el contenido que este archivo de módulo va a contener. Solo un process único, no workflow, no lógica, solo un process solo. + +Ahora puedo cerrar este archivo. + +## 2.3. Agregar una declaración de importación antes del bloque workflow + +Ahora mi workflow está faltando ese primer process, así que necesitamos traerlo de vuelta importándolo. La sintaxis para esto es muy similar a otros lenguajes de programación, así que puede sentirse familiar. Hacemos include llaves, el nombre del process, say hello, y luego from la ruta del archivo modules, say hello, nf. Fantástico. + +Un par de trucos aquí. La extensión de VS Code es inteligente con esto. Reconoce esta ruta de archivo y puede pasar el cursor sobre ella y hacer follow link. O estoy en Mac, puedo hacer option click y abre este archivo. Así que podemos saltar rápidamente a él. + +Este nombre de process ahora está siendo usado por el workflow aquí abajo, y podemos hacer lo mismo aquí. Nos muestra un poco de información sobre ese process, y nuevamente, puedo mantener presionado option, hacer clic en él, y lo abrirá en el editor. + +Así que es una forma realmente rápida cuando tiene muchos archivos para sus diferentes processes de navegar rápidamente por su base de código en VS Code. + +Bien. Eso es básicamente todo para este capítulo. Ahora solo hacemos lo mismo nuevamente para los otros processes. + +## 3. Modularizar el process convertToUpper() + +Así que vamos a crear un nuevo archivo aquí. Llamémoslo Convert to upper nf. Nuevamente, copie el hash bang. Y luego corte el process. + +Copie el nombre del process allí, incluya una nueva declaración include con el nuevo nombre de process. + +## 4. Modularizar el process collectGreetings() + +Y luego haga lo mismo para el tercer process. Nuevo archivo, connect. Greetings, + +haga el hash bang. Corte el process, pegue el process, y haga una nueva declaración include. + +Ahora puede ver aquí tengo un subrayado de error aquí diciendo invalid include source. Y este es en realidad un error genuino que cometí porque me estaba moviendo un poco demasiado rápido. Si mira de cerca, puede ver que me perdí la T en convert to upper + +Así que VS Code muy útilmente me ha dicho que cometí un error allí. Si corrijo ese nombre de archivo, el error desaparece. Es un buen ejemplo de por qué la verificación de errores dentro de VS Code es tan útil para escribir código Nextflow. De lo contrario no lo habría detectado y solo me habría dado cuenta mucho más tarde cuando intenté ejecutar el workflow. + +Nuestro script principal de pipeline ahora se ve mucho más simple. No tiene ningún process, solo tenemos tres declaraciones include y nuestro workflow. No hemos cambiado ninguna de la lógica del workflow. No hemos cambiado ningún código del process, así que con suerte debería funcionar exactamente de la misma manera. + +## 4.4. Ejecutar el workflow para verificar que hace lo mismo que antes + +Vamos a verificar. Voy a abrir una terminal y voy a ejecutar exactamente el mismo comando que antes. + +Efectivamente, ha ejecutado nuestros processes, say hello, convert to upper collect greetings, y nos dio tres saludos nuevamente. + +Así que hemos movido nuestro código, pero no hemos cambiado nada sobre cómo se ejecuta el workflow y está completamente sin cambios. La única diferencia es que ahora tenemos código más limpio, más fácil de mantener, y más fácil de compartir con otros. + +Y eso es todo. Fue un capítulo corto. Es un concepto simple, pero es muy poderoso y clave para cómo escribimos workflows Nextflow más complejos. Así que es importante que lo entienda y adquiera el hábito de usarlo. + +En el siguiente capítulo, vamos a tener un poco de cambio de ritmo y dejar de pensar tanto en la sintaxis de escribir código Nextflow, y pensar un poco sobre cómo usamos software en los processes mismos. Únase a nosotros en la parte cinco para Hola Contenedores. + +[Siguiente transcripción de video :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/es/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..1d712f84a6 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Parte 5: Hola Contenedores - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra únicamente la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../05_hello_containers.md). + + Los números de sección mostrados en la transcripción se proporcionan únicamente con fines indicativos y pueden no incluir todos los números de sección en los materiales. + +## Bienvenida + +Hola, bienvenido a la Parte Cinco del curso de entrenamiento Hello Nextflow. + +Este capítulo se llama Hola Contenedores. Vamos a hablar sobre cómo Nextflow se integra con herramientas como Docker y Singularity para usar contenedores de software para proporcionar software a los usuarios de su pipeline. + +Esto significa que cuando las personas ejecutan su pipeline, no tienen que ir e instalar todas las diferentes herramientas ellos mismos. Nextflow lo hará por ellos. + +Los contenedores son una tecnología extremadamente poderosa y crucial en reproducibilidad y facilidad de uso. Vamos a comenzar haciendo una breve introducción a los contenedores mismos, ejecutando algunos comandos de docker manualmente, y luego tomaremos esos mismos contenedores y los pondremos en nuestro pipeline de Nextflow. + +Muy bien. Empecemos. + +Entonces, como antes, comencemos cargando el material de entrenamiento. Vaya a training.nextflow.io. Hello Nextflow, Capítulo Cinco, Hola Contenedores. + +Voy a entrar en mi entorno de Codespaces y a la izquierda aquí vemos hello containers punto nf. + +Como antes, este es el mismo script con el que terminamos el capítulo cuatro anterior, así que debería verse familiar. + +Tenemos nuestros parámetros de línea de comandos para especificar el archivo de entrada y el nombre del lote. Estamos incluyendo nuestros tres módulos, y tenemos nuestro workflow donde ejecutamos los tres procesos. + +## 0. Calentamiento: Ejecute hello-containers.nf + +Siéntase libre de ejecutar este workflow nuevamente y verificar que está produciendo las salidas que espera. Por ahora, en realidad voy a cerrarlo y sumergirme en la terminal. + +## 1. Use un contenedor 'manualmente' + +Para comenzar este capítulo, vamos a hacer un poco de recapitulación sobre la tecnología de contenedores. Si está muy acostumbrado a docker o singularity u otras tecnologías de contenedores, entonces trate esto como un repaso, o siéntase libre de omitirlo completamente. + +Nextflow soporta muchos tipos diferentes de tecnologías de contenedores. Eso incluye Docker, Singularity, Podman, Shifter, Charliecloud, y más. + +En este entrenamiento, vamos a enfocarnos en Docker. Ese viene preinstalado en los code spaces y es una de las tecnologías de contenedores más populares, especialmente si está desarrollando en su propia computadora o en su propia laptop. + +Si está trabajando en un entorno académico en un HPC compartido, puede que encuentre que Singularity está disponible y no Docker. Está bien. Todos los conceptos son exactamente los mismos. Algunos de los comandos manuales son diferentes, pero si entiende Docker, también entenderá singularity. + +De hecho, Singularity también está instalado en el entorno de Code Spaces. Entonces si gusta, puede intentar hacer las mismas tareas usando Singularity en lugar de Docker. + +Bien, entonces ¿qué es la tecnología de contenedores? La idea detrás de Docker es que puede obtener una imagen de una fuente remota. Descargarla a su máquina local y luego crear un contenedor basado en esa imagen. + +Este contenedor en ejecución es un poco como una máquina virtual ejecutándose en su computadora. Está aislado de su entorno, y viene preempaquetado con un sistema operativo y un conjunto de software disponible. + +## 1.1. Descargue la imagen del contenedor + +La sintaxis que necesitamos para obtener una imagen preexistente es "docker pull". Entonces voy a escribir eso en mi terminal, pero ahora necesitamos una imagen con la cual jugar. + +Puede construir imágenes usted mismo. Puede encontrarlas en registros públicos como Docker Hub o quay.io. Pero una forma realmente buena de obtener imágenes rápidamente es usando Seqera Containers. + +Este es un servicio comunitario gratuito que hemos construido en 2024, que puede usar sin inicio de sesión ni nada. + +Si va a seqera.io/containers o hace clic en containers en la parte superior aquí, se le presenta una interfaz de búsqueda y puede escribir el nombre de cualquier herramienta disponible en Conda o en el Python package Index. + +Por defecto, busca en los canales de Bioconda y Conda Forge, pero puede prefijar cualquier canal de Conda. Estoy aquí si lo desea. + +Por diversión, usemos cowpy. Voy a escribir cowpy. Me da resultados de Python Package Index y Conda Forge. Voy a hacer clic en eso para agregarlo a mi contenedor. Podría agregar múltiples paquetes aquí si quisiera. Selecciono Docker, selecciono linux/amd64, y hago clic en Get Container. + +Esto construye la imagen para mí bajo demanda si no ha sido creada ya, y me da una URL que puedo copiar. + +Si está interesado, puede hacer clic en view Build Details, y eso lo lleva a una página que muestra el archivo de entorno conda que fue usado y el registro completo de construcción para la construcción, junto con los resultados del escaneo de seguridad. + +Si regreso a mis code spaces, ahora puedo pegar este nombre de contenedor y presionar enter. + +Docker ahora descarga todas las diferentes capas dentro de esta imagen de contenedor, y ahora nos dice que esta imagen está disponible para usar. + +## Descargando una imagen de Singularity + +Si está usando singularity, el proceso es básicamente el mismo. Seleccionamos nuestros paquetes de imagen, seleccionamos cowpy. Ahora elegimos Singularity en lugar de Docker y hacemos clic en Get Container. Eso nos da una URL de imagen usando oras://. O si prefiere, puede usar https:// marcando esa casilla. Copie esa URL. Ahora vaya a Code Spaces. En realidad tenemos Apptainer instalado en este espacio, que es lo mismo que Singularity, pero están aliados entre sí. Entonces voy a hacer apptainer pull y luego voy a llamarlo cowpy sif, pero puede llamarlo como quiera. Pegue la URL. Y eso va a descargar esa imagen para mí. + +Podría hacer ls -lh y ver cowpy.sif + +Singularity es diferente a Docker, en que singularity almacena todas las imágenes en archivos planos, mientras que Docker tiene un registro donde mantiene todas las capas por separado en su máquina host, y tiene un demonio ejecutándose para hacer seguimiento de todo eso. + +## 1.2. Use el contenedor para ejecutar cowpy como un comando único + +Bien, volvamos a Docker. Ahora podemos intentar ejecutar esta imagen que creamos haciendo docker run. + +Voy a hacer dash dash rm, que simplemente hace una ejecución única de la imagen. Y voy a pegar la URL de la imagen. Y luego finalmente, termina esto con un comando que desea ejecutar. + +La imagen que generamos tenía cowpy instalado, así que intentemos cowpy. + +Ahí está. Ejecutó nuestro comando. No tengo cowpy instalado localmente. Puede ver que si intento ejecutarlo, no existe. Sin embargo, en este comando, lo ejecuté usando Docker y correctamente generó esta salida. + +## 1.3. Use el contenedor para ejecutar cowpy interactivamente + +Podemos ir más allá de esto si queremos y activar un contenedor interactivamente y mirar alrededor adentro. Nuevamente, hago "docker run dash dash rm". Ahora voy a hacer dash it, que le dice a Docker que queremos una terminal interactiva. Hago la URL de la imagen nuevamente, y esta vez, en lugar de hacer cowpy, voy a hacer bin bash porque el comando que queremos ejecutar es bash. + +Esto nos lleva dentro de este contenedor en ejecución y puede ver que el prompt ha cambiado ahora. + +Si hago LS slash puede ver que los directorios aquí son diferentes. + +Si abro una segunda terminal aquí a la derecha, que simplemente está ejecutándose en GitHub Code Spaces y hago LS slash, ve que tenemos directorios como workspaces y temp, mientras que aquí en Docker es diferente. + +Entonces este entorno está completamente separado dentro de Docker y aislado de mi entorno host. Eso es algo bueno, porque eso aísla la ejecución de este comando en la imagen de Docker y lo mantiene reproducible entre diferentes personas en diferentes sistemas host. + +Si desea usar datos de su sistema host dentro de la imagen de Docker, tiene que montar eso explícitamente en el contenedor. + +Vamos a hacer eso en un segundo. + +## 1.3.2. Ejecute el(los) comando(s) de la herramienta deseada + +Primero, sin embargo, veamos si podemos ejecutar cowpy. Ahí nuevamente, el comando está disponible ahora directamente en la línea de comandos, y podemos comenzar a hacer cosas más complejas y pasar argumentos. Hello containers y en lugar de la vaca, hagamos el pingüino tux. Veamos qué más tenemos. + +Hagamos cheese. Maravilloso. ¿Qué tal Dragon y Cow? Bastante bien. + +## 1.3.3. Salga del contenedor + +Bien. No puedo hacer mucho más porque no tengo ningún dato en este contenedor. Así que salgamos de esta imagen en ejecución y veamos si podemos montar algunos datos en el contenedor. Puedo hacer eso haciendo control D o escribiendo exit. Bien, ahora estoy de vuelta en mi code space regular de GitHub. + +## 1.3.4. Monte datos en el contenedor + +Para montar algunos datos en el contenedor de Docker, necesito usar dash V. Entonces voy a tomar mi comando docker anterior, ir al inicio hacer dash v. Voy a hacer "." para el directorio de trabajo local actual, y luego dos puntos para decir dónde debería montarse eso en el directorio host y hacer slash data. Entonces eso está montando este directorio particular en el contenedor en slash data. + +Ahora si hago LS slash podemos ver que tenemos un nuevo directorio llamado data, y si hago LS data, puede ver todos los archivos que tenemos en la barra lateral aquí. Fantástico. + +## 1.3.5. Use los datos montados + +Ahora podemos comenzar a usar algunos de los archivos que están en el sistema host dentro de la imagen de Docker. Entonces puedo decir cat data greetings csv. Si recuerda, este es nuestro archivo CSV con nuestros diferentes saludos de antes, y puedo canalizarlo a cowpy. Fantástico. Ahora estamos llegando a algún lado. + +Bien. Eso es suficiente para ejecutar Docker interactivamente. Esperamos que ahora tenga una idea de aproximadamente qué es Docker y cómo usarlo tanto para ejecutar un comando de manera única, como también para usar una imagen interactivamente. Si está usando singularity. Los comandos son todos muy similares excepto que hace cosas como apptainer exec o apptainer run, o singularity exec o singularity run. + +## 2. Use contenedores en Nextflow + +A continuación vamos a volver a nuestro workflow de Nextflow y ver cómo usar esta tecnología dentro del pipeline de Nextflow. + +Cerremos la terminal y abramos Hello Containers nuevamente. + +## 2.1. Escriba un módulo cowpy + +Para continuar con nuestro ejemplo de cowpy, creemos un nuevo proceso en nuestro workflow, que use cowpy. Vayamos a modules, creemos un nuevo archivo y llamémoslo cowpy nf. Ahora voy a hacer trampa un poco y copiar el código del material de entrenamiento y presionar guardar. Y echemos un vistazo. + +Entonces este es un proceso simple. Esperamos que ahora entienda cómo lucen los bloques de construcción de un proceso. Tenemos nuestro publishDir nuevamente, yendo a results. Tenemos dos entradas, un archivo de entrada y un string llamado character. Tenemos una salida cowpy input file, y tenemos un script que se ve exactamente igual a lo que ejecutamos manualmente dentro de nuestra imagen de docker hace un segundo: cat para imprimir un archivo, canalizándolo a cowpy, diciendo qué tipo de carácter de cowpy queremos usar, y enviando eso al archivo de salida, que pasamos como la salida aquí. + +## 2.2. Agregue cowpy al workflow + +Bien, volvamos a nuestro workflow, importemos este nuevo proceso. Entonces cowpy from modules cowpy nf. Creemos un nuevo parámetro para que podamos especificar qué carácter queríamos. Digamos Turkey por defecto. Y luego llamemos a este nuevo proceso al final del workflow, + +cowpy. Y usemos la salida aquí de Collect Greetings. Entonces collect greetings out, out file aquí. Y luego necesitamos un segundo argumento, que es el nuevo params que acabamos de hacer. params dot character. + +## 2.2.4. Ejecute el workflow para verificar que funciona + +Bien, veamos si nuestro nuevo proceso funciona. Nextflow run hello containers. Esto debería ejecutar esos primeros tres procesos y luego intentar ejecutar cowpy al final. + +Tuvimos un error. Lo que está diciendo aquí, cowpy tuvo un error y tuvo un estado de salida 127 y efectivamente, comando sh cowpy comando no encontrado. + +No le dijimos a Nextflow que tenemos una imagen de Docker disponible para cowpy, así que intentó ejecutarlo en nuestro sistema host y no tenemos cowpy instalado en nuestro sistema host, así que desencadenó un error. + +## 2.3. Use un contenedor para ejecutarlo + +Entonces lo que necesitamos hacer es que necesitamos decirle a Nextflow que tenemos un contenedor disponible. Vayamos a nuestro proceso cowpy y vamos a agregar una nueva directiva en la parte superior del proceso llamada container. + +Luego encontramos nuestra imagen, copiamos la URL, y la ponemos en un string. + +Esto no es suficiente por sí mismo porque un pipeline de Nextflow puede tener varias formas de especificar software. También podría hacer conda conda-forge cowpy, por ejemplo. Y Nextflow necesita saber cuál de estas tecnologías desea usar. + +## 2.3.2. Habilite el uso de Docker a través del archivo nextflow.config + +Entonces para ejecutar con Docker habilitado, vamos a adelantarnos un poco y usar el archivo Nextflow config, que es algo que vamos a cubrir con más detalle en el próximo capítulo. Puede ver en este directorio que tenemos un archivo llamado Nextflow Config, y aquí ya tiene docker.enabled False. + +Vamos a cambiar eso a True para habilitar Docker, y luego podemos intentar ejecutar el workflow nuevamente. + +## 2.3.3. Ejecute el workflow con Docker habilitado + +Nextflow run hello containers nf y esta vez cowpy se ejecutó exitosamente. Miremos en Results. cowpy collected test y ahí está nuestro Turkey. Maravilloso. + +Entonces en segundo plano ahí, Nextflow sabía que tenía un contenedor disponible para ese proceso. + +Obtuvo la imagen y ejecutó los comandos por nosotros. + +## 2.3.4. Inspeccione cómo Nextflow lanzó la tarea contenerizada + +Si tiene curiosidad, en realidad podemos ver exactamente qué hizo mirando en el directorio de trabajo. Si hago code work, y luego el hash y luego command run, que si recuerda es el archivo real que se ejecuta para esa tarea, podemos entrar y podemos buscar una función llamada NXF launch. Y aquí puede ver el comando docker exacto que Nextflow usó, que se parece mucho a lo que estábamos haciendo manualmente en la terminal antes. Docker run. Vinculando este directorio host en el contenedor, y luego especificando la URL del contenedor. + +Entonces no hay magia aquí. Es solo que Nextflow está haciendo automáticamente el trabajo pesado por usted de una manera que significa que puede especificar fácilmente contenedores en su pipeline, que luego están fácilmente disponibles para cualquier otra persona que ejecute su workflow. Y esas personas ya no tienen que pensar en gestionar software para ejecutar su pipeline de análisis. + +Muy, muy simple, muy conveniente, y también realmente reproducible. Bueno en general. + +Bien, buen trabajo. Ese es el final del Capítulo Cinco. Únase a nosotros en el próximo video para la parte seis, que es la parte final de este entrenamiento Hello Nextflow, donde hablaremos sobre la configuración de Nextflow con más detalle. + +Nos vemos en el próximo video. + +[Transcripción del próximo video :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/es/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..d1ed95be7c --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Parte 6: Hola Config - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra solo la transcripción. Para instrucciones completas paso a paso, regrese al [material del curso](../06_hello_config.md). + + Los números de sección mostrados en la transcripción se proporcionan solo con fines indicativos y pueden no incluir todos los números de sección en los materiales. + +## Bienvenida + +Hola, bienvenido a la parte seis del curso de entrenamiento Hello Nextflow. + +Este capítulo se llama Hola Config, y es la parte final de nuestro curso de entrenamiento. + +En este capítulo, vamos a hablar sobre la configuración de Nextflow. La configuración de Nextflow es realmente poderosa. Nos permite ejecutar el mismo pipeline en múltiples infraestructuras de cómputo diferentes con diferente aprovisionamiento de software y diferentes opciones en el pipeline mismo. + +Esto significa que puede tomar pipelines de Nextflow construidos por otras personas y ejecutarlos en su sistema, aunque pueden haber sido construidos para una infraestructura completamente diferente. Esta capacidad de configurar Nextflow hace que los workflows sean verdaderamente portables y compartibles. + +En este capítulo, usaremos el workflow que hemos construido en partes anteriores, pero no vamos a editar el código del workflow en absoluto. Solo vamos a mirar nuestro archivo de configuración de Nextflow y ver cómo cambiar la configuración altera la forma en que Nextflow se ejecuta. + +Bien, comencemos. + +Como antes, comencemos yendo a training.nextflow.io. Vaya a la izquierda en Hello Nextflow y capítulo seis, Hola config. Ahora voy a entrar en mi entorno de GitHub Codespaces y verificar el script que usaremos. + +## 0. Calentamiento: Verificar que Docker esté habilitado y ejecutar el workflow Hello Config + +Este se llama Hello Config, y está comenzando desde donde estábamos antes. Entonces se ve exactamente igual con nuestros tres parámetros: greetings para el archivo CSV, batch para el nombre de lote de salida y character para el nombre de cowpy. Tenemos nuestras cuatro importaciones de los diferentes procesos, y luego tenemos un workflow donde los encadenamos. + +De hecho, voy a cerrar este archivo ahora porque no vamos a tocar el archivo de Nextflow en absoluto en este capítulo. Vamos a trabajar puramente dentro del archivo de configuración. Si miro el archivo nextflow.config que brevemente vimos en el capítulo cinco anterior, podemos ver que tenemos una sola declaración aquí: docker.enabled = true, que le está diciendo a Nextflow que use Docker cuando ejecute este workflow. + +Estoy usando nextflow.config en la raíz del pipeline aquí, que se carga automáticamente cuando ejecuto Nextflow. Pero recuerde, Nextflow puede cargar archivos de configuración desde múltiples lugares. + +Si verifico con la documentación de Nextflow, voy a Configuración, puede ver una lista de estos lugares y una prioridad en la que se cargan. + +Bien. Verifiquemos que nuestro workflow se está ejecutando como esperamos. Abro una terminal. Hago nextflow run hello-config y presiono enter. Deberíamos tener esos cuatro procesos ejecutándose, terminando con un comando cowpy. Efectivamente, esto funcionó correctamente. Tenía Docker habilitado, descargó Docker y ejecutó cowpy para mí, tal como lo hizo al final del capítulo cinco. + +## 1. Determinar qué tecnología de empaquetado de software usar + +Bien. Digamos que estoy ejecutando en un HPC y no tengo Docker instalado. Lo mejor que podría hacer en este escenario sería usar Singularity o Apptainer. Si fuera a hacer eso, iría al módulo cowpy y cambiaría este contenedor para usar la imagen de singularity como mostré en el capítulo anterior, con un oras://, que también puede obtener de Seqera Containers. + +Luego iría a nextflow.config, establecería docker.enabled en false y haría singularity.enabled = true. O, si uso Apptainer, apptainer.enabled = true y eso funcionaría. + +Nextflow también admite otras tecnologías además de contenedores, algo con lo que podría estar familiarizado es conda. Aquí podemos hacer conda.enabled = true y establecer Docker en false. conda no usa la misma directiva de contenedor. En su lugar, podemos agregar una nueva aquí llamada conda. Luego especificamos el paquete conda que queremos usar. Es una buena práctica ser lo más específico posible para tratar de hacer el pipeline lo más reproducible posible. Así que voy a especificar el canal conda, conda-forge, y luego cowpy, y la versión exacta, que fue 1.1.5. + +También podría simplemente escribir cowpy si quisiera, pero eso podría resolver a una versión diferente de cowpy en diferentes ejecuciones del pipeline. + +Lo bueno de esto es que no he tocado la directiva docker en absoluto. Esta imagen de Docker todavía está ahí. Solo estoy proporcionando dos alternativas ahora, y estas pueden activarse o desactivarse usando solo un archivo de configuración. + +## 1.3. Ejecutar el workflow para verificar que pueda usar Conda + +Conda ahora está habilitado, así que probémoslo. + +Genial. Se está ejecutando y puede ver que hay un mensaje de Nextflow aquí diciendo que Nextflow está creando un entorno conda para mí, y está usando esta ubicación de caché. + +En segundo plano, Nextflow está ejecutando comandos "conda create" para mí para crear un nuevo entorno conda aislado con solo los paquetes que quiero, y luego instalando y obteniendo esos paquetes conda para que pueda ejecutar el proceso. + +Puede ver que tomó un poco de tiempo allí porque estaba creando el entorno e instalando el software por primera vez. Sin embargo, ha almacenado en caché este entorno, así que si ejecuto el mismo comando de Nextflow nuevamente, debería ser mucho más rápido porque reutilizará el mismo entorno conda. + +Una de las cosas geniales de esto es que estas directivas pueden especificarse a nivel de proceso, no solo para todo el workflow. Entonces, si lo desea, puede mezclar y combinar qué tecnología se usa para diferentes procesos. + +## 2. Asignar recursos de cómputo con directivas de proceso + +El archivo de configuración de Nextflow puede hacer mucho más que solo empaquetado de software. También podemos decirle a Nextflow cómo ejecutar realmente los pasos en el pipeline. Un ejemplo es decirle al sistema host qué recursos deben estar disponibles para cada tarea en ejecución. + +Por defecto, Nextflow no proporciona mucho. Proporciona un solo CPU y solo dos gigabytes de memoria para cada proceso. + +Esto es probablemente algo que querríamos cambiar, para que los procesos que toman mucho tiempo para ejecutarse puedan tener más recursos y ejecutarse más rápidamente, pero puede ser difícil saber qué asignar a un proceso. Nextflow tiene algunos buenos trucos bajo la manga para ayudarlo con esto. + +## 2.1. Ejecutar el workflow para generar un reporte de utilización de recursos + +Ejecutemos el workflow nuevamente. Esta vez, voy a agregar un argumento adicional, que es -with-report. Es una opción central de Nextflow, así que es un solo guion. Y luego cualquier nombre de archivo que me guste. En este caso, voy a llamarlo report-config-1.html. + +Voy a ejecutar el workflow nuevamente. Va a ejecutarse exactamente como antes, pero me va a dar un reporte de ayuda adicional, que puede ver que ahora ha aparecido aquí en la barra lateral. + +Voy a hacer clic derecho en este archivo, hacer clic en descargar, que lo descarga de GitHub Codespaces a mi sistema local, para que pueda verlo fácilmente en el navegador web aquí arriba. + +Este reporte puede generarse para cualquier ejecución de Nextflow, y tiene mucha información. Comienza en la parte superior con algunos metadatos sobre qué comando se usó, cuándo se ejecutó el workflow, cuánto tiempo tomó, pero a medida que se desplaza hacia abajo, obtenemos información más detallada sobre los recursos que fueron utilizados por cada paso en el pipeline. + +Debido a que cada proceso se ejecuta múltiples veces para diferentes tareas, tenemos un diagrama de caja que muestra la variación de los recursos que usamos para cada proceso. + +Si me desplazo un poco más hacia abajo, veo información similar sobre la memoria utilizada y la duración del trabajo. También lectura y escritura de disco. + +Puede imaginar que para un pipeline grande con tareas de larga ejecución, esto puede ser muy informativo sobre cómo ajustar la configuración de los recursos que está solicitando para que no solicite de más, pero también para que pueda proporcionar suficiente para que se ejecute rápidamente. + +Si sigo desplazándome hacia abajo en el reporte, también vemos una tabla de tareas, que nos muestra información detallada sobre cada tarea individual que se ejecutó en el workflow. Esto incluye información como el script resuelto, que se ejecutó. + +Bien, volvamos a nuestro archivo de configuración. Vimos que realmente no necesitábamos mucho para nuestro workflow, así que digámosle a Nextflow que solo necesitamos un gigabyte de memoria para cada proceso en el workflow. + +Ahora cuando lo definimos así a nivel de proceso, esto se aplica a cada proceso individual en el pipeline. + +## 2.3. Establecer asignaciones de recursos para un proceso individual + +Por el bien del argumento, supongamos que cowpy está realmente haciendo mucho trabajo pesado y necesita más recursos que las otras tareas. Podemos definir un bloque adicional de configuración aquí, que se aplica solo a ese proceso usando withName: COWPY. + +Esto se llama un selector de configuración, y podemos definir diferentes patrones aquí para coincidir con diferentes procesos. Por ejemplo, podría hacer COW\*. Luego sigo eso con algunas llaves y démosle dos gigabytes de memoria en lugar de uno y digamos dos CPUs. + +Ahora Nextflow proporcionará a cada proceso en el workflow un gigabyte, aparte de esta solicitud, que es más específica. Así que la sobrescribe. Y solo para cualquier proceso que se llame COWPY, obtendrá dos gigabytes de memoria y dos CPUs. + +Tenga en cuenta que Nextflow es inteligente sobre la utilización de recursos. Entonces, si comienza a poner estos números en valores más altos, verá que Nextflow comienza a poner en cola los envíos de trabajos uno tras otro, en lugar de ejecutarlos todos en paralelo, para que no solicite en exceso los recursos que están disponibles. + +## 2.4. Ejecutar el workflow con la configuración modificada + +Intentemos ejecutar un workflow nuevamente y guardemos un nuevo reporte esta vez. + +Bien, podemos descargar este archivo y echarle un vistazo. + +Sí, como era de esperar, se ve básicamente exactamente igual porque este es un workflow ficticio, que no está haciendo nada real. Pero puede imaginar cómo este enfoque iterativo de definir límites y hacer workflows de la vida real con este tipo de reportes le permite hacer un enfoque basado en evidencia para establecer la configuración apropiada y realmente aprovechar al máximo los recursos computacionales que tiene disponibles. + +Puede comenzar a ser realmente inteligente sobre esto. Nextflow tiene una capacidad incorporada para reintentar fallas, y puede aprovecharla en su archivo de configuración usando un closure como este y estableciendo dinámicamente los recursos que se ponen a disposición. Entonces aquí le he dicho a Nextflow que multiplique esos dos gigabytes por el intento de reintento. Entonces, el segundo reintento obtendrá cuatro gigabytes, el tercer reintento obtendrá seis gigabytes y así sucesivamente. Esto está un poco más allá del alcance de este curso de entrenamiento, pero si está interesado, consulte la documentación de Nextflow, que tiene una buena sección sobre lógica de reintento dinámico. + +## 2.5. Agregar límites de recursos + +Ahora, una cosa que podría notar sobre esto es que este tipo de cosas puede hacer que sea bastante fácil ir accidentalmente más allá de los recursos disponibles en su sistema. Si solicita más recursos de los que están disponibles, Nextflow generará un error sobre su configuración y detendrá la ejecución. Para evitar eso, puede usar algo llamado límites de recursos. + +Bajo el ámbito process, en nuestro workflow, podemos definir límites de recursos como este, que toma un array, y podemos especificar la memoria máxima, CPUs y tiempo que están disponibles en este sistema. + +Establecer valores altos aquí no aumenta la cantidad de recursos que se solicitan. Todavía vamos a usar un gigabyte en nuestras solicitudes, pero significa que si alguna de estas solicitudes llega a 750, alcanzarán ese límite y no se solicitará más que eso, lo que significa que Nextflow continuará ejecutándose y no fallará debido a recursos no disponibles. + +Entonces, esta es una buena salvaguarda para usar, especialmente si está usando lógica dinámica con su asignación de recursos. + +La otra situación donde esto es realmente útil es si está usando pipelines que son públicos y no están controlados por usted. Pueden venir con valores predeterminados de configuración, y Nextflow automáticamente tomará el enfoque correcto de limitar cualquier solicitud de recursos para ejecutarse en su sistema. + +Bien, genial. Hemos hablado sobre software. Hemos hablado sobre la asignación de recursos, y hemos descrito diferentes ámbitos de configuración, tanto para todos los procesos como para procesos específicos. + +## 3. Usar un archivo de parámetros para almacenar parámetros del workflow + +Bien, a continuación vamos a dirigir nuestra atención a los parámetros. Podemos definir parámetros en el archivo de configuración tal como lo hicimos antes en el script de Nextflow. Entonces params.greeting = 'hello' o usar el ámbito params y establecer foo = 'bar'. + +Y eso es genial para establecer valores predeterminados para su workflow. Sin embargo, cuando está ejecutando pipelines, puede ser bueno especificar parámetros en un archivo JSON o YAML. + +Usar un archivo como este es mucho mejor que especificar opciones de línea de comandos con --. Como cuando ejecuta un workflow, podría tener que especificar muchos parámetros y puede ser tedioso escribirlos todos en una sola CLI y propenso a errores. Además, es poco probable que recuerde todos los parámetros que usó, así que si lo codifica en un archivo, es más fácil lanzar el workflow nuevamente, usando los mismos parámetros en el futuro. + +Tenemos un archivo de ejemplo aquí llamado test-params, y puede ver que esto especifica los tres parámetros que tenemos en nuestro workflow con tres valores diferentes. Personalmente, encuentro que YAML es más fácil de escribir que JSON. Entonces, solo para demostrar que funciona, voy a crear un nuevo archivo llamado test.yaml y copiar estos, deshacerme de las comillas. Y guardar. + +Estos archivos JSON y YAML pueden ser más fáciles de escribir ya que son sintaxis más familiar. Pero tenga en cuenta que estos son solo para parámetros y solo toman sintaxis de clave-valor como esta. + +## 3.1. Ejecutar el workflow usando un archivo de parámetros + +Probémoslo. Hago el mismo comando que antes. Me deshago del reporte y voy a hacer -params-file test-params.yaml. + +No, esta es una opción central de Nextflow, así que es un solo guion. + +Bien. Ejecutó el workflow y usó los parámetros en ese archivo YAML en lugar de que yo los especifique todos en la línea de comandos. Puede parecer exagerado solo para este ejemplo simple, pero puede imaginar si tiene 10 o 20 parámetros diferentes, puede ser una molestia escribirlos manualmente, y esto es simplemente mucho más fácil de editar en un editor de código y conservar para fines de reproducibilidad. + +## 3. Determinar qué executor(es) deben usarse para hacer el trabajo + +Bien. Hemos hablado sobre empaquetado de software con Docker y conda. Hemos hablado sobre requisitos de recursos de proceso con CPUs y memoria. Y hablamos un poco sobre cómo especificar parámetros al ejecutar workflows. + +Las partes finales de la configuración realmente son la ejecución, la infraestructura de cómputo subyacente misma, y esta es la verdadera joya de la corona de Nextflow: que podemos ejecutar estos mismos workflows a través de múltiples infraestructuras de cómputo diferentes. + +De hecho, voy a cambiar al material de entrenamiento escrito por un segundo. Bajo esta parte del entrenamiento, podemos ver algunos ejemplos diferentes de cómo diferentes executors, en este caso, planificadores HPC, definen los requisitos de recursos necesarios para enviar un trabajo. + +Entonces, para Slurm, tiene estos encabezados SBATCH, que definen --mem y el número de CPU. Si está usando PBS, tiene encabezados diferentes, y si usa Grid Engine, tiene encabezados diferentes nuevamente. + +Puede imaginar que es aún más diferente si quiere ejecutar en la nube, ya sea AWS Batch, Google Cloud, Azure o más. + +Cada una de estas infraestructuras de cómputo subyacentes se llama un executor y Nextflow sabe cómo hablar con todos estos diferentes executors para enviar trabajos con la sintaxis correcta. + +La buena noticia es que no tiene que saber sobre esto. Todo lo que tiene que hacer es decirle a Nextflow qué executor usar. + +## 3.1. Apuntar a un backend diferente + +Volvemos a nuestro archivo de configuración y en process hacemos executor, y voy a escribir 'local'. + +Local es en realidad el predeterminado, si no especifica ningún otro executor, local es lo que se usará, y eso simplemente significa su sistema host, donde sea que haya lanzado Nextflow. + +En su lugar, podría especificar slurm. Y eso enviaría trabajos de Slurm, o podría decir awsbatch, y eso enviaría trabajos a AWS Batch. + +Necesita alguna configuración adicional en algunos casos, por ejemplo, ejecutar en la nube necesitará ciertas credenciales, pero realmente este es el núcleo de ello, y puede ser tan simple como una o dos líneas de configuración para ejecutar su workflow en un entorno de cómputo completamente diferente. + +Aunque estamos ejecutando en un sistema simple dentro de Codespaces, todavía puedo jugar con esto un poco y pretender que estamos ejecutando en Slurm. Si luego lanzo el workflow nuevamente, nextflow run hello-config. Fallará porque no podrá enviar trabajos a Slurm. Pero aún podemos ir a los directorios de trabajo y ver qué hizo Nextflow. Entonces, si vamos a este directorio de trabajo y miramos .command.run. Puede ver en la parte superior de este archivo, ahora tenemos estas líneas de encabezado sbatch, que intentaron especificar los recursos necesarios para el trabajo de Slurm. + +## 4. Usar perfiles para seleccionar configuraciones preestablecidas + +Bien, ya casi llegamos. La parte final de este capítulo es hablar sobre perfiles de configuración. Si está ejecutando su pipeline en varios sistemas diferentes, podría ser molesto tener todos estos diferentes archivos de configuración de Nextflow, que necesita especificar cada vez. + +En su lugar, puede codificar agrupaciones de configuración dentro de su archivo nextflow.config, y activar y desactivar esos grupos usando una bandera de perfil. Veamos cómo se ve eso. + +## 4.1. Crear perfiles para cambiar entre desarrollo local y ejecución en HPC + +Vamos a crear dos perfiles en nuestro ejemplo aquí, uno para mi laptop y uno para un sistema HPC más pesado. Voy a hacer trampa un poco y simplemente copiar el código del material de entrenamiento y ponerlo aquí. + +Tenemos un nuevo ámbito llamado profiles, y luego tenemos un nombre para cada perfil, que puede ser cualquier cosa. Y dentro de eso tenemos configuración, que se ve exactamente igual que la configuración de nivel superior que ya escribimos. Entonces, nuevamente, tenemos ámbito process, ámbito docker. + +En el perfil llamado my_laptop, estoy diciendo que se ejecute usando el executor local, entonces en mi sistema host y que use Docker. + +En el perfil university_hpc aquí estoy diciendo que use Slurm para enviar trabajos, que use conda en lugar de Docker, y estoy especificando diferentes límites de recursos, que pueden coincidir con el tamaño del sistema de nodos en el HPC que estoy usando. + +Por defecto, ninguna de esta configuración se usará cuando ejecute Nextflow, tengo que especificar que quiero usar uno de estos perfiles. + +## 4.2. Ejecutar el workflow con un perfil + +Hagamos nextflow run hello-config. Y voy a hacer -profile, un solo guion porque es una opción central de Nextflow. Y luego el nombre que le di, que es my_laptop. Nextflow ahora debería usar el bloque de configuración que se especificó dentro de ese perfil de configuración, y aplicarlo cuando ejecute Nextflow. Si quisiera usar el otro bloque de configuración, solo tengo que cambiar ese nombre de perfil. Mucho más fácil de recordar. Mucho más fácil de usar. + +## 4.3. Crear un perfil de prueba + +Tenga en cuenta, los perfiles pueden tener cualquier tipo de configuración, así que no tiene que estar relacionado con su entorno de ejecución. Por ejemplo, creemos un nuevo perfil aquí, que tenga un conjunto de parámetros. Podemos cambiar esto a tux y cambiar a My Profile, y ahora cuando hagamos profile test, va a especificar estos parámetros, que sobrescribirán los parámetros que se especifican en el nivel superior del workflow. + +Cuando ejecute Nextflow, puede encadenar múltiples perfiles y se aplicarán en secuencia. + +## 4.4. Ejecutar el workflow localmente con el perfil de prueba + +Entonces puedo tomar el comando anterior y hacer coma test. Eso aplicará la configuración my_laptop primero, y luego aplicará la configuración test. Si hay alguna superposición, entonces el perfil a la derecha sobrescribirá cualquier configuración en perfiles anteriores. Si presiono enter, veamos qué pasa. + +Bien, tenemos un nuevo archivo de resultados aquí. Puede ver el My Profile, que especifiqué como una de las opciones. Y también podemos ver cowpy, my_profile, y efectivamente, ahí está tux. Entonces eso ha funcionado. + +## Conclusión + +¡Bien! Increíble. Eso es todo. Lo ha logrado hasta el final del curso. Obtiene un poco de confeti de celebración. Bien hecho por terminar este capítulo. + +[Siguiente transcripción de video :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/es/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/es/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..d66df28e71 --- /dev/null +++ b/docs/es/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Próximos Pasos - Transcripción + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página muestra únicamente la transcripción. Para instrucciones paso a paso completas, regrese al [material del curso](../05_hello_containers.md). + +## Bienvenida + +Felicidades, lo ha logrado. Ha completado el primer curso de entrenamiento de Nextflow, llamado Hello Nextflow. + +Bien hecho. Gracias por perseverar y realmente apreciamos el tiempo y esfuerzo que ha dedicado a aprender Nextflow, y esperamos sinceramente que sea útil para su trabajo. + +## Próximos Pasos + +Para los próximos pasos, esté atento al portal de entrenamiento: training.nextflow.io. Estamos subiendo nuevo material de curso todo el tiempo y también lo estamos actualizando. Así que podría encontrar entrenamiento más avanzado, o entrenamiento que sea específico para un campo de investigación que le interese. + +Específicamente, consulte la página de Nextflow for Science. Esta tiene una serie de cursos cortos que son independientes, y extienden lo que ha aprendido en Hello Nextflow a casos de uso específicos. + +Hay uno para Genómica y también uno para RNA-seq. Esperamos traer más pronto. + +## Side Quests + +Hay muchas cosas de las que podríamos haber hablado en Hello Nextflow, que habrían sido demasiado detalle. Algunas de estas cosas las estamos poniendo en Side Quests, que son cursos cortos sobre temas específicos. + +También están los cursos más grandes de entrenamiento fundamental y entrenamiento avanzado, que pueden incluir contenido que le resulte interesante. + +## nf-core + +Se ha mencionado una o dos veces en este curso, pero definitivamente consulte el proyecto nf-core. Hay más de cien pipelines allí para diferentes tipos de datos, así que es completamente posible que no necesite construir su propio pipeline. + +También hay casi mil quinientos módulos de procesos donde, si usa las herramientas de desarrollo de nf-core, puede crear un pipeline e importar esos módulos en cuestión de segundos. + +## Seqera Platform + +Por último, una rápida mención para Seqera Platform. Esta es sin duda la mejor manera de ejecutar Nextflow en la práctica, es una plataforma basada en la nube, pero usted conecta su propia infraestructura de cómputo, ya sea su propia cuenta en la nube en AWS, Google Batch, o Azure, o incluso su propio HPC. El nivel gratuito está disponible para todos, y si es académico, puede aplicar a nuestro programa académico para acceso gratuito a nivel profesional. + +Seqera Platform va más allá de ser solo una interfaz gráfica para lanzar y monitorear flujos de trabajo. También hay herramientas adicionales como Data Studios para ejecutar sesiones interactivas, y herramientas fundamentales como Fusion, que proporciona acceso más rápido y económico a datos en la nube. + +## Soporte y eventos + +Recuerde, si alguna vez tiene algún problema, simplemente vaya a community.seqera.io. Nuestro foro allí es realmente activo, la comunidad de Nextflow es súper fuerte y casi siempre hay personas disponibles listas para ayudar, ya sea para entrenamiento o cualquier cosa relacionada con su uso diario de Nextflow. + +Y por supuesto, un gran próximo paso es unirse a uno de nuestros eventos de la comunidad, ya sea un hackathon de nf-core o uno de los eventos de Nextflow Summit. Son muy divertidos, y sería muy agradable conocerle allí y conversar sobre para qué está usando Nextflow. + +## Agradecimientos + +Me gustaría dar un enorme agradecimiento a todos los que han estado involucrados en escribir este material de entrenamiento. Yo lo he estado presentando, pero realmente todo el trabajo duro lo ha hecho el equipo de entrenamiento en Seqera. Específicamente Geraldine, quien ha puesto una enorme cantidad de trabajo en reescribir este material. + +También, Marcel, Ken, Adam, John, otros del equipo de desarrollo científico y otros en la comunidad. + +## Encuesta de retroalimentación + +Ahora que ha terminado el curso, nos encantaría saber qué le pareció. En training.nextflow.io, encontrará una encuesta de retroalimentación debajo de la sección de Hello Nextflow. + +Solo hay cuatro preguntas pero es realmente importante para nosotros. Si nada más, nos dice aproximadamente cuántas personas están haciendo el entrenamiento. También nos dice si le gustó y si tiene alguna sugerencia, por favor déjela al final. Leemos cada envío. + +Si detecta algún error, todo es de código abierto en GitHub, así que puede crear un issue o hacer un pull request o dejarnos un mensaje en el foro. Nos encantaría saber qué le pareció y cómo podríamos mejorarlo. Gracias de nuevo. Esperamos verle pronto. diff --git a/docs/es/docs/hello_nf-core/00_orientation.md b/docs/es/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..7a5c5e75cf --- /dev/null +++ b/docs/es/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Primeros pasos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Iniciar un entorno de entrenamiento + +Para usar el entorno preconfigurado que proporcionamos en GitHub Codespaces, haga clic en el botón "Open in GitHub Codespaces" a continuación. Para otras opciones, consulte [Opciones de entorno](../envsetup/index.md). + +Recomendamos abrir el entorno de entrenamiento en una nueva pestaña o ventana del navegador (use clic derecho, ctrl-clic o cmd-clic según su equipo) para que pueda continuar leyendo mientras el entorno se carga. +Necesitará mantener estas instrucciones abiertas en paralelo para trabajar a través del curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Conceptos básicos del entorno + +Este entorno de entrenamiento contiene todo el software, código y datos necesarios para trabajar a través del curso de entrenamiento, por lo que no necesita instalar nada por su cuenta. + +El codespace está configurado con una interfaz VSCode, que incluye un explorador de sistema de archivos, un editor de código y un terminal shell. +Todas las instrucciones dadas durante el curso (por ejemplo, 'abrir el archivo', 'editar el código' o 'ejecutar este comando') se refieren a estas tres partes de la interfaz VSCode a menos que se especifique lo contrario. + +Si está trabajando en este curso por su cuenta, por favor familiarícese con los [conceptos básicos del entorno](../envsetup/01_setup.md) para más detalles. + +### Requisitos de versión + +Este entrenamiento está diseñado para **Nextflow 25.10.2** o posterior **con el analizador de sintaxis v2 DESHABILITADO**. + +#### Si está usando nuestro entorno de entrenamiento: + +DEBE ejecutar el siguiente comando antes de continuar: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Si está usando un entorno local o personalizado: + +Por favor asegúrese de estar usando la configuración correcta como se documenta [aquí](../info/nxf_versions.md). + +El entrenamiento además requiere **nf-core tools 3.4.1**. +Si usa una versión diferente de las herramientas nf-core, puede tener dificultades para seguir el curso. + +Puede verificar qué versión está instalada en su entorno usando el comando `nf-core --version`. + +## Prepararse para trabajar + +Una vez que su codespace esté funcionando, hay dos cosas que necesita hacer antes de sumergirse en el entrenamiento: establecer su directorio de trabajo para este curso específico y echar un vistazo a los materiales proporcionados. + +### Establecer el directorio de trabajo + +Por defecto, el codespace se abre con el directorio de trabajo establecido en la raíz de todos los cursos de entrenamiento, pero para este curso, trabajaremos en el directorio `hello-nf-core/`. + +Cambie de directorio ahora ejecutando este comando en el terminal: + +```bash +cd hello-nf-core/ +``` + +!!! tip "Consejo" + + Si por alguna razón sale de este directorio (por ejemplo, su codespace se suspende), siempre puede usar la ruta completa para volver a él, asumiendo que está ejecutando esto dentro del entorno de entrenamiento de Github Codespaces: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Ahora echemos un vistazo al contenido de este directorio. + +### Explorar los materiales proporcionados + +Puede explorar el contenido de este directorio usando el explorador de archivos en el lado izquierdo del espacio de trabajo de entrenamiento. +Alternativamente, puede usar el comando `tree`. + +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenidos del directorio en una forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 2 +``` + +??? abstract "Contenidos del directorio" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Haga clic en el cuadro de color para expandir la sección y ver su contenido. +Usamos secciones colapsables como esta para incluir la salida esperada de comandos de manera concisa. + +- **El archivo `greetings.csv`** es un CSV que contiene algunos datos columnares mínimos que usamos con fines de prueba. + +- **El directorio `original-hello`** contiene una copia del código fuente producido al trabajar a través de la serie completa de entrenamiento Hello Nextflow (con Docker habilitado). + +- **El directorio `solutions`** contiene los scripts de workflow completados que resultan de cada paso del curso. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + +## Lista de verificación de preparación + +¿Cree que está listo para sumergirse? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi entorno está funcionando +- [ ] Me he asegurado de que el analizador de sintaxis esté establecido en **v1** +- [ ] He establecido mi directorio de trabajo apropiadamente + +Si puede marcar todas las casillas, está listo para comenzar. + +**Para continuar a la Parte 1, haga clic en la flecha en la esquina inferior derecha de esta página.** diff --git a/docs/es/docs/hello_nf-core/01_run_demo.md b/docs/es/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..0f2037df81 --- /dev/null +++ b/docs/es/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# Parte 1: Ejecutar un pipeline de demostración + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta primera parte del curso de entrenamiento Hello nf-core, le mostramos cómo encontrar y probar un pipeline de nf-core, entender cómo está organizado el código y reconocer en qué se diferencia del código Nextflow básico como se muestra en [Hello Nextflow](../hello_nextflow/index.md). + +Vamos a utilizar un pipeline llamado nf-core/demo que es mantenido por el proyecto nf-core como parte de su inventario de pipelines para demostrar la estructura del código y las operaciones de las herramientas. + +Asegúrese de que su directorio de trabajo esté configurado en `hello-nf-core/` como se indica en la página [Primeros pasos](./00_orientation.md). + +--- + +## 1. Encontrar y obtener el pipeline nf-core/demo + +Comencemos localizando el pipeline nf-core/demo en el sitio web del proyecto en [nf-co.re](https://nf-co.re), que centraliza toda la información como: documentación general y artículos de ayuda, documentación para cada uno de los pipelines, publicaciones de blog, anuncios de eventos, etcétera. + +### 1.1. Encontrar el pipeline en el sitio web + +En su navegador web, vaya a [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) y escriba `demo` en la barra de búsqueda. + +![resultados de búsqueda](./img/search-results.png) + +Haga clic en el nombre del pipeline, `demo`, para acceder a la página de documentación del pipeline. + +Cada pipeline publicado tiene una página dedicada que incluye las siguientes secciones de documentación: + +- **Introduction:** Una introducción y descripción general del pipeline +- **Usage:** Descripciones de cómo ejecutar el pipeline +- **Parameters:** Parámetros del pipeline agrupados con descripciones +- **Output:** Descripciones y ejemplos de los archivos de salida esperados +- **Results:** Archivos de salida de ejemplo generados a partir del conjunto de datos de prueba completo +- **Releases & Statistics:** Historial de versiones del pipeline y estadísticas + +Siempre que esté considerando adoptar un nuevo pipeline, debe leer cuidadosamente la documentación del pipeline primero para entender qué hace y cómo debe configurarse antes de intentar ejecutarlo. + +Eche un vistazo ahora y vea si puede averiguar: + +- Qué herramientas ejecutará el pipeline (Consulte la pestaña: `Introduction`) +- Qué entradas y parámetros acepta o requiere el pipeline (Consulte la pestaña: `Parameters`) +- Cuáles son las salidas producidas por el pipeline (Consulte la pestaña: `Output`) + +#### 1.1.1. Descripción general del pipeline + +La pestaña `Introduction` proporciona una descripción general del pipeline, incluyendo una representación visual (llamada mapa de metro) y una lista de herramientas que se ejecutan como parte del pipeline. + +![mapa de metro del pipeline](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Ejemplo de línea de comando + +La documentación también proporciona un archivo de entrada de ejemplo (discutido más adelante) y un ejemplo de línea de comando. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Notará que el comando de ejemplo NO especifica un archivo de workflow, solo la referencia al repositorio del pipeline, `nf-core/demo`. + +Cuando se invoca de esta manera, Nextflow asumirá que el código está organizado de cierta manera. +Obtengamos el código para que podamos examinar esta estructura. + +### 1.2. Obtener el código del pipeline + +Una vez que hemos determinado que el pipeline parece ser adecuado para nuestros propósitos, probémoslo. +Afortunadamente, Nextflow facilita la obtención de pipelines desde repositorios correctamente formateados sin tener que descargar nada manualmente. + +Volvamos a la terminal y ejecutemos lo siguiente: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Salida del comando" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow hace un `pull` del código del pipeline, lo que significa que descarga el repositorio completo en su unidad local. + +Para ser claros, puede hacer esto con cualquier pipeline de Nextflow que esté configurado apropiadamente en GitHub, no solo con pipelines de nf-core. +Sin embargo, nf-core es la colección de código abierto más grande de pipelines de Nextflow. + +Puede hacer que Nextflow le proporcione una lista de qué pipelines ha obtenido de esta manera: + +```bash +nextflow list +``` + +??? success "Salida del comando" + + ```console + nf-core/demo + ``` + +Notará que los archivos no están en su directorio de trabajo actual. +Por defecto, Nextflow los guarda en `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Contenido del directorio" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note "Nota" + + La ruta completa puede diferir en su sistema si no está utilizando nuestro entorno de entrenamiento. + +Nextflow mantiene el código fuente descargado intencionalmente 'fuera del camino' bajo el principio de que estos pipelines deben usarse más como bibliotecas que como código con el que interactuaría directamente. + +Sin embargo, para los propósitos de este entrenamiento, queremos poder explorar y ver qué hay allí. +Entonces, para facilitar eso, creemos un enlace simbólico a esa ubicación desde nuestro directorio de trabajo actual. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Esto crea un acceso directo que facilita explorar el código que acabamos de descargar. + +```bash +tree -L 2 pipelines +``` + +```console title="Contenido del directorio" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Ahora podemos explorar más fácilmente el código fuente según sea necesario. + +Pero primero, ¡probemos ejecutar nuestro primer pipeline de nf-core! + +### Conclusión + +Ahora sabe cómo encontrar un pipeline a través del sitio web de nf-core y obtener una copia local del código fuente. + +### ¿Qué sigue? + +Aprenda cómo probar un pipeline de nf-core con mínimo esfuerzo. + +--- + +## 2. Probar el pipeline con su perfil de prueba + +Convenientemente, cada pipeline de nf-core viene con un perfil de prueba. +Este es un conjunto mínimo de configuraciones para que el pipeline se ejecute usando un conjunto de datos de prueba pequeño alojado en el repositorio [nf-core/test-datasets](https://github.com/nf-core/test-datasets). +Es una excelente manera de probar rápidamente un pipeline a pequeña escala. + +!!! note "Nota" + + El sistema de perfiles de configuración de Nextflow le permite cambiar fácilmente entre diferentes motores de contenedores o entornos de ejecución. + Para más detalles, consulte [Hello Nextflow Parte 6: Configuración](../hello_nextflow/06_hello_config.md). + +### 2.1. Examinar el perfil de prueba + +Es una buena práctica verificar qué especifica el perfil de prueba de un pipeline antes de ejecutarlo. +El perfil `test` para `nf-core/demo` se encuentra en el archivo de configuración `conf/test.config` y se muestra a continuación. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Datos de entrada + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Notará de inmediato que el bloque de comentarios en la parte superior incluye un ejemplo de uso que muestra cómo ejecutar el pipeline con este perfil de prueba. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Las únicas cosas que necesitamos proporcionar son lo que se muestra entre corchetes angulares en el comando de ejemplo: `<docker/singularity>` y `<OUTDIR>`. + +Como recordatorio, `<docker/singularity>` se refiere a la elección del sistema de contenedores. Todos los pipelines de nf-core están diseñados para ser utilizables con contenedores (Docker, Singularity, etc.) para garantizar la reproducibilidad y eliminar problemas de instalación de software. +Entonces necesitaremos especificar si queremos usar Docker o Singularity para probar el pipeline. + +La parte `--outdir <OUTDIR>` se refiere al directorio donde Nextflow escribirá las salidas del pipeline. +Necesitamos proporcionar un nombre para él, que simplemente podemos inventar. +Si aún no existe, Nextflow lo creará por nosotros en tiempo de ejecución. + +Pasando a la sección después del bloque de comentarios, el perfil de prueba nos muestra qué ha sido preconfigurado para las pruebas: más notablemente, el parámetro `input` ya está configurado para apuntar a un conjunto de datos de prueba, por lo que no necesitamos proporcionar nuestros propios datos. +Si sigue el enlace a la entrada preconfigurada, verá que es un archivo csv que contiene identificadores de muestra y rutas de archivo para varias muestras experimentales. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Esto se llama una hoja de muestras, y es la forma más común de entrada a los pipelines de nf-core. + +!!! note "Nota" + + No se preocupe si no está familiarizado con los formatos y tipos de datos, no es importante para lo que sigue. + +Entonces esto confirma que tenemos todo lo que necesitamos para probar el pipeline. + +### 2.2. Ejecutar el pipeline + +Decidamos usar Docker para el sistema de contenedores y `demo-results` como el directorio de salida, y estamos listos para ejecutar el comando de prueba: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Si su salida coincide con esa, ¡felicitaciones! Acaba de ejecutar su primer pipeline de nf-core. + +Notará que hay mucha más salida en la consola que cuando ejecuta un pipeline básico de Nextflow. +Hay un encabezado que incluye un resumen de la versión del pipeline, entradas y salidas, y algunos elementos de configuración. + +!!! note "Nota" + + Su salida mostrará diferentes marcas de tiempo, nombres de ejecución y rutas de archivo, pero la estructura general y la ejecución del proceso deben ser similares. + +Pasando a la salida de ejecución, echemos un vistazo a las líneas que nos dicen qué procesos se ejecutaron: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Esto nos dice que se ejecutaron tres procesos, correspondientes a las tres herramientas mostradas en la página de documentación del pipeline en el sitio web de nf-core: FASTQC, SEQTK_TRIM y MULTIQC. + +Los nombres completos de los procesos como se muestran aquí, como `NFCORE_DEMO:DEMO:MULTIQC`, son más largos que lo que puede haber visto en el material introductorio de Hello Nextflow. +Estos incluyen los nombres de sus workflows padre y reflejan la modularidad del código del pipeline. +Entraremos en más detalle sobre eso en un momento. + +### 2.3. Examinar las salidas del pipeline + +Finalmente, echemos un vistazo al directorio `demo-results` producido por el pipeline. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Contenido del directorio" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Eso puede parecer mucho. +Para obtener más información sobre las salidas del pipeline `nf-core/demo`, consulte su [página de documentación](https://nf-co.re/demo/1.0.2/docs/output/). + +En esta etapa, lo importante a observar es que los resultados están organizados por módulo, y además hay un directorio llamado `pipeline_info` que contiene varios informes con marcas de tiempo sobre la ejecución del pipeline. + +Por ejemplo, el archivo `execution_timeline_*` le muestra qué procesos se ejecutaron, en qué orden y cuánto tiempo tardaron en ejecutarse: + +![informe de línea de tiempo de ejecución](./img/execution_timeline.png) + +!!! note "Nota" + + Aquí las tareas no se ejecutaron en paralelo porque estamos ejecutando en una máquina minimalista en Github Codespaces. + Para ver que se ejecuten en paralelo, intente aumentar la asignación de CPU de su codespace y los límites de recursos en la configuración de prueba. + +Estos informes se generan automáticamente para todos los pipelines de nf-core. + +### Conclusión + +Sabe cómo ejecutar un pipeline de nf-core usando su perfil de prueba integrado y dónde encontrar sus salidas. + +### ¿Qué sigue? + +Aprenda cómo está organizado el código del pipeline. + +--- + +## 3. Examinar la estructura del código del pipeline + +Ahora que hemos ejecutado con éxito el pipeline como usuarios, cambiemos nuestra perspectiva para ver cómo están estructurados internamente los pipelines de nf-core. + +El proyecto nf-core aplica directrices estrictas sobre cómo se estructuran los pipelines, y sobre cómo se organiza, configura y documenta el código. +Entender cómo está todo organizado es el primer paso hacia el desarrollo de sus propios pipelines compatibles con nf-core, lo cual abordaremos en la Parte 2 de este curso. + +Echemos un vistazo a cómo está organizado el código del pipeline en el repositorio `nf-core/demo`, usando el enlace simbólico `pipelines` que creamos anteriormente. + +Puede usar `tree` o usar el explorador de archivos para encontrar y abrir el directorio `nf-core/demo`. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Contenido del directorio" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Hay mucho sucediendo allí, así que abordaremos esto paso a paso. + +Primero, notemos que en el nivel superior, puede encontrar un archivo README con información resumida, así como archivos accesorios que resumen información del proyecto como licencia, directrices de contribución, citas y código de conducta. +La documentación detallada del pipeline se encuentra en el directorio `docs`. +Todo este contenido se utiliza para generar las páginas web en el sitio web de nf-core programáticamente, por lo que siempre están actualizadas con el código. + +Ahora, para el resto, vamos a dividir nuestra exploración en tres etapas: + +1. Componentes del código del pipeline (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Configuración del pipeline +3. Entradas y validación + +Comencemos con los componentes del código del pipeline. +Nos vamos a enfocar en la jerarquía de archivos y la organización estructural, en lugar de profundizar en el código dentro de archivos individuales. + +### 3.1. Componentes del código del pipeline + +La organización estándar del código de pipeline de nf-core sigue una estructura modular que está diseñada para maximizar la reutilización de código, como se presentó en [Hello Modules](../hello_nextflow/04_hello_modules.md), Parte 4 del curso [Hello Nextflow](../hello_nextflow/index.md), aunque al verdadero estilo de nf-core, esto se implementa con un poco de complejidad adicional. +Específicamente, los pipelines de nf-core hacen uso abundante de subworkflows, es decir, scripts de workflow que son importados por un workflow padre. + +Eso puede sonar un poco abstracto, así que echemos un vistazo a cómo se usa esto en la práctica en el pipeline `nf-core/demo`. + +!!! note "Nota" + + No revisaremos el código real de _cómo_ estos componentes modulares están conectados, porque hay cierta complejidad adicional asociada con el uso de subworkflows que puede ser confusa, y entender eso no es necesario en esta etapa del entrenamiento. + Por ahora, nos vamos a enfocar en la organización general y la lógica. + +#### 3.1.1. Descripción general + +Así es como se ven las relaciones entre los componentes de código relevantes para el pipeline `nf-core/demo`: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +Hay un script llamado _punto de entrada_ llamado `main.nf`, que actúa como un contenedor para dos tipos de workflows anidados: el workflow que contiene la lógica de análisis real, ubicado en `workflows/` y llamado `demo.nf`, y un conjunto de workflows de mantenimiento ubicados en `subworkflows/`. +El workflow `demo.nf` llama a **módulos** ubicados en `modules/`; estos contienen los **procesos** que realizarán los pasos de análisis reales. + +!!! note "Nota" + + Los subworkflows no se limitan a funciones de mantenimiento, y pueden hacer uso de módulos de procesos. + + El pipeline `nf-core/demo` mostrado aquí resulta estar en el lado más simple del espectro, pero otros pipelines de nf-core (como `nf-core/rnaseq`) utilizan subworkflows que están involucrados en el análisis real. + +Ahora, revisemos estos componentes por turno. + +#### 3.1.2. El script de punto de entrada: `main.nf` + +El script `main.nf` es el punto de entrada desde donde Nextflow comienza cuando ejecutamos `nextflow run nf-core/demo`. +Eso significa que cuando ejecuta `nextflow run nf-core/demo` para ejecutar el pipeline, Nextflow encuentra y ejecuta automáticamente el script `main.nf`. +Esto funciona para cualquier pipeline de Nextflow que siga esta nomenclatura y estructura convencionales, no solo para pipelines de nf-core. + +Usar un script de punto de entrada facilita ejecutar subworkflows de 'mantenimiento' estandarizados antes y después de que se ejecute el script de análisis real. +Revisaremos esos después de haber revisado el workflow de análisis real y sus módulos. + +#### 3.1.3. El script de análisis: `workflows/demo.nf` + +El workflow `workflows/demo.nf` es donde se almacena la lógica central del pipeline. +Está estructurado de manera muy similar a un workflow normal de Nextflow, excepto que está diseñado para ser llamado desde un workflow padre, lo cual requiere algunas características adicionales. +Cubriremos las diferencias relevantes en la siguiente parte de este curso, cuando abordemos la conversión del pipeline simple Hello de Hello Nextflow en una forma compatible con nf-core. + +El workflow `demo.nf` llama a **módulos** ubicados en `modules/`, que revisaremos a continuación. + +!!! note "Nota" + + Algunos workflows de análisis de nf-core muestran niveles adicionales de anidamiento al llamar a subworkflows de nivel inferior. + Esto se usa principalmente para envolver dos o más módulos que se usan comúnmente juntos en segmentos de pipeline fácilmente reutilizables. + Puede ver algunos ejemplos navegando por los [subworkflows de nf-core](https://nf-co.re/subworkflows/) disponibles en el sitio web de nf-core. + + Cuando el script de análisis usa subworkflows, estos se almacenan en el directorio `subworkflows/`. + +#### 3.1.4. Los módulos + +Los módulos son donde vive el código del proceso, como se describe en la [Parte 4 del curso de entrenamiento Hello Nextflow](../hello_nextflow/04_hello_modules.md). + +En el proyecto nf-core, los módulos se organizan usando una estructura anidada multinivel que refleja tanto su origen como su contenido. +En el nivel superior, los módulos se diferencian como `nf-core` o `local` (no parte del proyecto nf-core), y luego se colocan en un directorio nombrado según la(s) herramienta(s) que envuelven. +Si la herramienta pertenece a un toolkit (es decir, un paquete que contiene múltiples herramientas) entonces hay un nivel de directorio intermedio nombrado según el toolkit. + +Puede ver esto aplicado en la práctica a los módulos del pipeline `nf-core/demo`: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Contenido del directorio" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Aquí ve que los módulos `fastqc` y `multiqc` se encuentran en el nivel superior dentro de los módulos `nf-core`, mientras que el módulo `trim` se encuentra bajo el toolkit al que pertenece, `seqtk`. +En este caso no hay módulos `local`. + +El archivo de código del módulo que describe el proceso siempre se llama `main.nf`, y está acompañado de pruebas y archivos `.yml` que ignoraremos por ahora. + +En conjunto, el workflow de punto de entrada, el workflow de análisis y los módulos son suficientes para ejecutar las partes 'interesantes' del pipeline. +Sin embargo, sabemos que también hay subworkflows de mantenimiento allí, así que veamos esos ahora. + +#### 3.1.5. Los subworkflows de mantenimiento + +Al igual que los módulos, los subworkflows se diferencian en directorios `local` y `nf-core`, y cada subworkflow tiene su propia estructura de directorio anidada con su propio script `main.nf`, pruebas y archivo `.yml`. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Contenido del directorio" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Como se señaló anteriormente, el pipeline `nf-core/demo` no incluye ningún subworkflow específico de análisis, por lo que todos los subworkflows que vemos aquí son los llamados workflows de 'mantenimiento' o 'utilidad', como se denota por el prefijo `utils_` en sus nombres. +Estos subworkflows son los que producen el elegante encabezado de nf-core en la salida de la consola, entre otras funciones accesorias. + +!!! tip "Consejo" + + Aparte de su patrón de nomenclatura, otra indicación de que estos subworkflows no realizan ninguna función verdaderamente relacionada con el análisis es que no llaman a ningún proceso en absoluto. + +Esto completa el resumen de los componentes de código principales que constituyen el pipeline `nf-core/demo`. +Ahora echemos un vistazo a los elementos restantes sobre los que debe saber un poco antes de sumergirse en el desarrollo: configuración del pipeline y validación de entrada. + +### 3.2. Configuración del pipeline + +Ha aprendido anteriormente que Nextflow ofrece muchas opciones para configurar la ejecución del pipeline, ya sea en términos de entradas y parámetros, recursos de computación y otros aspectos de la orquestación. +El proyecto nf-core aplica directrices altamente estandarizadas para la configuración del pipeline que tienen como objetivo basarse en las opciones de personalización flexibles de Nextflow de una manera que proporcione mayor consistencia y mantenibilidad entre pipelines. + +El archivo de configuración central `nextflow.config` se utiliza para establecer valores predeterminados para parámetros y otras opciones de configuración. +La mayoría de estas opciones de configuración se aplican por defecto, mientras que otras (por ejemplo, perfiles de dependencias de software) se incluyen como perfiles opcionales. + +Hay varios archivos de configuración adicionales que se almacenan en la carpeta `conf` y que pueden agregarse a la configuración por defecto u opcionalmente como perfiles: + +- `base.config`: Un archivo de configuración 'en blanco', apropiado para uso general en la mayoría de los entornos de computación de alto rendimiento. Esto define amplios contenedores de uso de recursos, por ejemplo, que son convenientes de aplicar a los módulos. +- `modules.config`: Directivas y argumentos adicionales de módulos. +- `test.config`: Un perfil para ejecutar el pipeline con datos de prueba mínimos, que usamos cuando ejecutamos el pipeline de demostración. +- `test_full.config`: Un perfil para ejecutar el pipeline con un conjunto de datos de prueba de tamaño completo. + +Tocaremos algunos de esos archivos más adelante en el curso. + +### 3.3. Entradas y validación + +Como notamos anteriormente, cuando examinamos el perfil de prueba del pipeline `nf-core/demo`, está diseñado para tomar como entrada una hoja de muestras que contiene rutas de archivo e identificadores de muestra. +Las rutas de archivo vinculadas a datos reales ubicados en el repositorio `nf-core/test-datasets`. + +También se proporciona una hoja de muestras de ejemplo en el directorio `assets`, aunque las rutas en esta no son reales. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Esta hoja de muestras en particular es bastante simple, pero algunos pipelines se ejecutan en hojas de muestras que son más complejas, con muchos más metadatos asociados con las entradas primarias. + +Desafortunadamente, debido a que estos archivos pueden ser difíciles de verificar a simple vista, el formato inadecuado de los datos de entrada es una fuente muy común de fallas del pipeline. +Un problema relacionado es cuando los parámetros se proporcionan incorrectamente. + +La solución a estos problemas es ejecutar verificaciones de validación automatizadas en todos los archivos de entrada para asegurar que contengan los tipos esperados de información, formateados correctamente, y en parámetros para asegurar que sean del tipo esperado. +Esto se llama validación de entrada, y idealmente debería hacerse _antes_ de intentar ejecutar un pipeline, en lugar de esperar a que el pipeline falle para descubrir que hubo un problema con las entradas. + +Al igual que con la configuración, el proyecto nf-core tiene opiniones muy firmes sobre la validación de entrada, y recomienda el uso del [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/), un plugin de Nextflow que proporciona capacidades de validación integrales para pipelines de Nextflow. + +Cubriremos este tema con más detalle en la Parte 5 de este curso. +Por ahora, solo tenga en cuenta que se proporcionan dos archivos JSON para ese propósito, `nextflow_schema.json` y `assets/schema_input.json`. + +El `nextflow_schema.json` es un archivo utilizado para almacenar información sobre los parámetros del pipeline incluyendo tipo, descripción y texto de ayuda en un formato legible por máquina. +Esto se utiliza para varios propósitos, incluyendo validación automatizada de parámetros, generación de texto de ayuda y renderizado de formularios de parámetros interactivos en interfaces de usuario. + +El `schema_input.json` es un archivo utilizado para definir la estructura de la hoja de muestras de entrada. +Cada columna puede tener un tipo, patrón, descripción y texto de ayuda en un formato legible por máquina. +El esquema se utiliza para varios propósitos, incluyendo validación automatizada y proporcionar mensajes de error útiles. + +### Conclusión + +Sabe cuáles son los componentes principales de un pipeline de nf-core y cómo está organizado el código; dónde están ubicados los elementos principales de configuración; y es consciente de para qué sirve la validación de entrada. + +### ¿Qué sigue? + +¡Tome un descanso! Eso fue mucho. Cuando se sienta renovado y listo, pase a la siguiente sección para aplicar lo que ha aprendido para escribir un pipeline compatible con nf-core. + +!!! tip "Consejo" + + Si desea aprender cómo componer workflows con subworkflows antes de pasar a la siguiente parte, consulte la [Misión Secundaria Workflows de Workflows](../side_quests/workflows_of_workflows.md). diff --git a/docs/es/docs/hello_nf-core/02_rewrite_hello.md b/docs/es/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..0c9f61ccf6 --- /dev/null +++ b/docs/es/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1434 @@ +# Parte 2: Reescribir Hello para nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta segunda parte del curso de entrenamiento Hello nf-core, te mostramos cómo crear una versión compatible con nf-core del pipeline producido por el curso para principiantes [Hello Nextflow](../hello_nextflow/index.md). + +Habrás notado en la primera sección del entrenamiento que los pipelines de nf-core siguen una estructura bastante elaborada con muchos archivos accesorios. +Crear todo eso desde cero sería muy tedioso, por lo que la comunidad nf-core ha desarrollado herramientas para hacerlo desde una plantilla, facilitando el proceso inicial. + +Vamos a mostrarte cómo usar estas herramientas para crear una estructura base de pipeline, y luego adaptar el código de pipeline 'regular' existente sobre esta estructura nf-core. + +Si no estás familiarizado con el pipeline Hello o necesitas un recordatorio, consulta [esta página de información](../info/hello_pipeline.md). + +--- + +## 1. Crear un nuevo proyecto de pipeline + +Primero, creamos la estructura base para el nuevo pipeline. + +!!! note "Nota" + + Asegúrate de estar en el directorio `hello-nf-core` en tu terminal. + +### 1.1. Ejecutar la herramienta de creación de pipeline basada en plantilla + +Comencemos creando un nuevo pipeline con el comando `nf-core pipelines create`. +Esto creará una estructura base de pipeline usando la plantilla base de nf-core, personalizada con un nombre de pipeline, descripción y autor. + +```bash +nf-core pipelines create +``` + +Ejecutar este comando abrirá una Interfaz de Usuario de Texto (TUI) para la creación del pipeline: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Esta TUI te pedirá que proporciones información básica sobre tu pipeline y te ofrecerá opciones de funcionalidades para incluir o excluir en tu estructura base. + +- En la pantalla de bienvenida, haz clic en **Let's go!**. +- En la pantalla `Choose pipeline type`, haz clic en **Custom**. +- Ingresa los detalles de tu pipeline como se indica a continuación (reemplazando `< TU NOMBRE >` con tu propio nombre), luego haz clic en **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < TU NOMBRE > +``` + +- En la pantalla Template features, establece `Toggle all features` en **off**, luego **habilita** selectivamente las siguientes opciones. Verifica tus selecciones y haz clic en **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- En la pantalla `Final details`, haz clic en **Finish**. Espera a que se cree el pipeline, luego haz clic en **Continue**. +- En la pantalla Create GitHub repository, haz clic en **Finish without creating a repo**. Esto mostrará instrucciones para crear un repositorio de GitHub más adelante. Ignóralas y haz clic en **Close**. + +Una vez que la TUI se cierre, deberías ver la siguiente salida en la consola. + +??? success "Salida del comando" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +No hay una confirmación explícita en la salida de consola de que la creación del pipeline funcionó, pero deberías ver un nuevo directorio llamado `core-hello`. + +Visualiza el contenido del nuevo directorio para ver cuánto trabajo te ahorraste usando la plantilla. + +```bash +tree core-hello +``` + +??? abstract "Contenido del directorio" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +¡Son muchos archivos! + +Con suerte reconocerás muchos de ellos como los mismos que encontramos cuando exploramos la estructura del pipeline `nf-core/demo`. +Pero no te preocupes si todavía te sientes un poco perdido; recorreremos juntos las partes importantes en el transcurso de este entrenamiento. + +!!! note "Nota" + + Una diferencia importante comparada con el pipeline `nf-core/demo` que examinamos en la primera parte de este entrenamiento es que no hay un directorio `modules`. + Esto es porque no elegimos incluir ninguno de los módulos predeterminados de nf-core. + +### 1.2. Probar que la estructura base es funcional + +Lo creas o no, aunque aún no has agregado módulos para que haga trabajo real, la estructura base del pipeline puede ejecutarse usando el perfil de prueba, de la misma manera que ejecutamos el pipeline `nf-core/demo`. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Esto te muestra que toda la estructura básica está en su lugar. +Entonces, ¿dónde están las salidas? ¿Hay alguna? + +De hecho, se creó un nuevo directorio de resultados llamado `core-hello-results` que contiene los reportes de ejecución estándar: + +```bash +tree core-hello-results +``` + +??? abstract "Contenido del directorio" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Puedes echar un vistazo a los reportes para ver qué se ejecutó, y la respuesta es: ¡nada en absoluto! + +![reporte de línea de tiempo de ejecución vacío](./img/execution_timeline_empty.png) + +Echemos un vistazo a lo que realmente hay en el código. + +### 1.3. Examinar el workflow placeholder + +Si miras dentro del archivo `main.nf`, verás que importa un workflow llamado `HELLO` desde `workflows/hello`. + +Esto es equivalente al workflow `workflows/demo.nf` que encontramos en la Parte 1, y sirve como workflow placeholder para nuestro workflow de interés, con algo de funcionalidad nf-core ya en su lugar. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // canal: samplesheet leído desde --input + main: + + ch_versions = channel.empty() + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // canal: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Comparado con un workflow básico de Nextflow como el desarrollado en [Hello Nextflow](../hello_nextflow/index.md), notarás algunas cosas que son nuevas aquí (líneas destacadas arriba): + +- El bloque workflow tiene un nombre +- Las entradas del workflow se declaran usando la palabra clave `take:` y la construcción del canal se mueve al workflow padre +- El contenido del workflow se coloca dentro de un bloque `main:` +- Las salidas se declaran usando la palabra clave `emit:` + +Estas son características opcionales de Nextflow que hacen que el workflow sea **componible**, lo que significa que puede ser llamado desde dentro de otro workflow. + +!!! note "Workflows componibles en profundidad" + + La [Side Quest Workflows de Workflows](../side_quests/workflows_of_workflows.md) explora la composición de workflows con mucha más profundidad, incluyendo cómo componer múltiples workflows juntos y gestionar flujos de datos complejos entre ellos. Estamos introduciendo la componibilidad aquí porque es un requisito fundamental de la arquitectura de plantilla nf-core, que utiliza workflows anidados para organizar la inicialización del pipeline, el workflow de análisis principal y las tareas de finalización en componentes separados y reutilizables. + +Vamos a necesitar conectar la lógica relevante de nuestro workflow de interés en esa estructura. +El primer paso para eso es hacer que nuestro workflow original sea componible. + +### Conclusión + +Ahora sabes cómo crear una estructura base de pipeline usando las herramientas nf-core. + +### ¿Qué sigue? + +Aprende cómo hacer que un workflow simple sea componible como preludio para hacerlo compatible con nf-core. + +--- + +## 2. Hacer el workflow original de Hello Nextflow componible + +Ahora es momento de trabajar integrando nuestro workflow en la estructura base nf-core. +Como recordatorio, estamos trabajando con el workflow presentado en nuestro curso de entrenamiento [Hello Nextflow](../hello_nextflow/index.md). + +!!! tip "Consejo" + + Si no estás familiarizado con ese pipeline o necesitas un recordatorio, consulta [El pipeline Hello](../info/hello_pipeline.md). + +Te proporcionamos una copia limpia y completamente funcional del workflow Hello Nextflow completado en el directorio `original-hello` junto con sus módulos y el archivo CSV predeterminado que espera usar como entrada. + +```bash +tree original-hello/ +``` + +??? abstract "Contenido del directorio" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Siéntete libre de ejecutarlo para verificar que funciona: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Abramos el archivo de workflow `hello.nf` para inspeccionar el código, que se muestra completo a continuación (sin contar los procesos, que están en módulos): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Incluir módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Como puedes ver, este workflow fue escrito como un workflow simple sin nombre que puede ejecutarse por sí solo. +Para hacerlo ejecutable desde dentro de un workflow padre como requiere la plantilla nf-core, necesitamos hacerlo **componible**. + +Recorramos los cambios necesarios uno por uno. + +### 2.1. Nombrar el workflow + +Primero, démosle un nombre al workflow para poder referirnos a él desde un workflow padre. + +=== "Después" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Las mismas convenciones se aplican a los nombres de workflow que a los nombres de módulos. + +### 2.2. Reemplazar la construcción de canal con `take` + +Ahora, reemplaza la construcción del canal con una simple declaración `take` que declare las entradas esperadas. + +=== "Después" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // channel of greetings + greeting_ch + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="18" + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Esto deja los detalles de cómo se proporcionan las entradas al workflow padre. + +Ya que estamos en eso, también podemos comentar la línea `params.greeting = 'greetings.csv'` + +=== "Después" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Nota" + + Si tienes instalada la extensión del servidor de lenguaje Nextflow, el verificador de sintaxis iluminará tu código con garabatos rojos. + Eso es porque si pones una declaración `take:`, también debes tener un `main:`. + + Agregaremos eso en el siguiente paso. + +### 2.3. Anteponer las operaciones del workflow con la declaración `main` + +A continuación, agrega una declaración `main` antes del resto de las operaciones llamadas en el cuerpo del workflow. + +=== "Después" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="21" + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Esto básicamente dice 'esto es lo que este workflow _hace_'. + +### 2.4. Agregar declaración `emit` + +Finalmente, agrega una declaración `emit` que declare cuáles son las salidas finales del workflow. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Esta es una adición completamente nueva al código comparado con el workflow original. + +### 2.5. Resumen de los cambios completados + +Si has hecho todos los cambios como se describe, tu workflow ahora debería verse así: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Incluir módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // channel of greetings + greeting_ch + + main: + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Esto describe todo lo que Nextflow necesita EXCEPTO qué alimentar en el canal de entrada. +Eso se va a definir en el workflow padre, también llamado workflow de **punto de entrada**. + +### 2.6. Hacer un workflow de punto de entrada ficticio + +Antes de integrar nuestro workflow componible en la compleja estructura base nf-core, verifiquemos que funcione correctamente. +Podemos hacer un workflow de punto de entrada ficticio simple para probar el workflow componible de forma aislada. + +Crea un archivo en blanco llamado `main.nf` en el mismo directorio `original-hello`. + +```bash +touch original-hello/main.nf +``` + +Copia el siguiente código en el archivo `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// importar el código del workflow desde el archivo hello.nf +include { HELLO } from './hello.nf' + +// declarar parámetro de entrada +params.greeting = 'greetings.csv' + +workflow { + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // llamar al workflow importado con el canal de saludos + HELLO(greeting_ch) + + // ver las salidas emitidas por el workflow + HELLO.out.view { output -> "Output: $output" } +} +``` + +Hay dos observaciones importantes que hacer aquí: + +- La sintaxis para llamar al workflow importado es esencialmente la misma que la sintaxis para llamar módulos. +- Todo lo que está relacionado con llevar las entradas al workflow (parámetro de entrada y construcción del canal) ahora se declara en este workflow padre. + +!!! note "Nota" + + Nombrar el archivo de workflow de punto de entrada `main.nf` es una convención, no un requisito. + + Si sigues esta convención, puedes omitir especificar el nombre del archivo del workflow en tu comando `nextflow run`. + Nextflow buscará automáticamente un archivo llamado `main.nf` en el directorio de ejecución. + + Sin embargo, puedes nombrar el archivo de workflow de punto de entrada de otra manera si lo prefieres. + En ese caso, asegúrate de especificar el nombre del archivo del workflow en tu comando `nextflow run`. + +### 2.7. Probar que el workflow se ejecuta + +Finalmente tenemos todas las piezas que necesitamos para verificar que el workflow componible funciona. +¡Ejecutémoslo! + +```bash +nextflow run ./original-hello +``` + +Aquí ves la ventaja de usar la convención de nomenclatura `main.nf`. +Si hubiéramos nombrado el workflow de punto de entrada `algo_mas.nf`, habríamos tenido que hacer `nextflow run original-hello/algo_mas.nf`. + +Si hiciste todos los cambios correctamente, esto debería ejecutarse hasta completarse. + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Esto significa que hemos actualizado exitosamente nuestro workflow HELLO para que sea componible. + +### Conclusión + +Sabes cómo hacer un workflow componible dándole un nombre y agregando declaraciones `take`, `main` y `emit`, y cómo llamarlo desde un workflow de punto de entrada. + +### ¿Qué sigue? + +Aprende cómo injertar un workflow componible básico en la estructura base nf-core. + +--- + +## 3. Ajustar la lógica del workflow actualizado en el workflow placeholder + +Ahora que hemos verificado que nuestro workflow componible funciona correctamente, volvamos a la estructura base del pipeline nf-core que creamos en la sección 1. +Queremos integrar el workflow componible que acabamos de desarrollar en la estructura de plantilla nf-core, para que el resultado final se vea algo así. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Entonces, ¿cómo hacemos que eso suceda? Echemos un vistazo al contenido actual del workflow `HELLO` en `core-hello/workflows/hello.nf` (la estructura base nf-core). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // canal: samplesheet leído desde --input + main: + + ch_versions = channel.empty() + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // canal: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +En general, este código hace muy poco aparte de algunas tareas de mantenimiento que tienen que ver con capturar la versión de cualquier herramienta de software que se ejecute en el pipeline. + +Necesitamos agregar el código relevante del workflow componible original que desarrollamos en la sección 2. + +Vamos a abordar esto en las siguientes etapas: + +1. Copiar los módulos y configurar las importaciones de módulos +2. Dejar la declaración `take` como está +3. Agregar la lógica del workflow al bloque `main` +4. Actualizar el bloque `emit` + +!!! note "Nota" + + Vamos a ignorar la captura de versión por este primer paso y veremos cómo conectar eso en una parte posterior de este entrenamiento. + +### 3.1. Copiar los módulos y configurar las importaciones de módulos + +Los cuatro procesos de nuestro workflow Hello Nextflow están almacenados como módulos en `original-hello/modules/`. +Necesitamos copiar esos módulos en la estructura del proyecto nf-core (bajo `core-hello/modules/local/`) y agregar declaraciones de importación al archivo de workflow nf-core. + +Primero copiemos los archivos de módulos de `original-hello/` a `core-hello/`: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Ahora deberías ver el directorio de módulos listado bajo `core-hello/`. + +```bash +tree core-hello/modules +``` + +??? abstract "Contenido del directorio" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Ahora configuremos las declaraciones de importación de módulos. + +Estas eran las declaraciones de importación en el workflow `original-hello/hello.nf`: + +```groovy title="original-hello/hello.nf" linenums="9" +// Incluir módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Abre el archivo `core-hello/workflows/hello.nf` y transpón esas declaraciones de importación en él como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Dos observaciones más interesantes aquí: + +- Hemos adaptado el formato de las declaraciones de importación para seguir la convención de estilo nf-core. +- Hemos actualizado las rutas relativas a los módulos para reflejar que ahora están almacenados en un nivel diferente de anidamiento. + +### 3.2. Dejar la declaración `take` como está + +El proyecto nf-core tiene mucha funcionalidad preconstruida alrededor del concepto de samplesheet, que típicamente es un archivo CSV que contiene datos en columnas. +Como eso es esencialmente lo que es nuestro archivo `greetings.csv`, mantendremos la declaración `take` actual como está, y simplemente actualizaremos el nombre del canal de entrada en el siguiente paso. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // canal: samplesheet leído desde --input +``` + +El manejo de entrada se hará antes de este workflow (no en este archivo de código). + +### 3.3. Agregar la lógica del workflow al bloque `main` + +Ahora que nuestros módulos están disponibles para el workflow, podemos conectar la lógica del workflow en el bloque `main`. + +Como recordatorio, este es el código relevante en el workflow original, que no cambió mucho cuando lo hicimos componible (solo agregamos la línea `main:`): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) +``` + +Necesitamos copiar el código que viene después de `main:` en la nueva versión del workflow. + +Ya hay algo de código allí que tiene que ver con capturar las versiones de las herramientas que ejecuta el workflow. Vamos a dejarlo solo por ahora (nos ocuparemos de las versiones de las herramientas más tarde). +Mantendremos la inicialización `ch_versions = channel.empty()` en la parte superior, luego insertaremos nuestra lógica de workflow, manteniendo el código de recopilación de versiones al final. +Este orden tiene sentido porque en un pipeline real, los procesos emitirían información de versión que se agregaría al canal `ch_versions` a medida que el workflow se ejecuta. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // canal: samplesheet leído desde --input + + main: + + ch_versions = Channel.empty() + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // canal: [ path(versions.yml) ] + + } + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // canal: samplesheet leído desde --input + main: + + ch_versions = Channel.empty() + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // canal: [ path(versions.yml) ] + + } + ``` + +Notarás que también agregamos una línea en blanco antes de `main:` para hacer el código más legible. + +Esto se ve bien, pero todavía necesitamos actualizar el nombre del canal que estamos pasando al proceso `sayHello()` de `greeting_ch` a `ch_samplesheet` como se muestra a continuación, para coincidir con lo que está escrito bajo la palabra clave `take:`. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir un saludo (updated to use the nf-core convention for samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir un saludo + sayHello(greeting_ch) + ``` + +Ahora la lógica del workflow está correctamente conectada. + +### 3.4. Actualizar el bloque `emit` + +Finalmente, necesitamos actualizar el bloque `emit` para incluir la declaración de las salidas finales del workflow. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // canal: [ path(versions.yml) ] + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // canal: [ path(versions.yml) ] + ``` + +Esto concluye las modificaciones que necesitamos hacer al workflow HELLO en sí mismo. +En este punto, hemos logrado la estructura general de código que nos propusimos implementar. + +### Conclusión + +Sabes cómo ajustar las piezas centrales de un workflow componible en un workflow placeholder nf-core. + +### ¿Qué sigue? + +Aprende cómo adaptar cómo se manejan las entradas en la estructura base del pipeline nf-core. + +--- + +## 4. Adaptar el manejo de entradas + +Ahora que hemos integrado exitosamente nuestra lógica de workflow en la estructura base nf-core, necesitamos abordar una pieza más crítica: asegurar que nuestros datos de entrada se procesen correctamente. +La plantilla nf-core viene con un manejo de entrada sofisticado diseñado para conjuntos de datos genómicos complejos, por lo que necesitamos adaptarlo para que funcione con nuestro archivo `greetings.csv` más simple. + +### 4.1. Identificar dónde se manejan las entradas + +El primer paso es averiguar dónde se realiza el manejo de entrada. + +Puede que recuerdes que cuando reescribimos el workflow Hello Nextflow para que fuera componible, movimos la declaración del parámetro de entrada un nivel arriba, en el workflow de punto de entrada `main.nf`. +Así que echemos un vistazo al workflow de punto de entrada `main.nf` de nivel superior que se creó como parte de la estructura base del pipeline: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Ejecutar el pipeline de análisis principal según el tipo de entrada +// +workflow CORE_HELLO { + + take: + samplesheet // canal: samplesheet leído desde --input + + main: + + // + // WORKFLOW: Ejecutar pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Ejecutar tareas de inicialización + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Ejecutar workflow principal + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Ejecutar tareas de finalización + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +El proyecto nf-core hace un uso intensivo de subworkflows anidados, por lo que esta parte puede ser un poco confusa al principio. + +Lo que importa aquí es que hay dos workflows definidos: + +- `CORE_HELLO` es un envoltorio delgado para ejecutar el workflow HELLO que acabamos de terminar de adaptar en `core-hello/workflows/hello.nf`. +- Un workflow sin nombre que llama a `CORE_HELLO` así como a otros dos subworkflows, `PIPELINE_INITIALISATION` y `PIPELINE_COMPLETION`. + +Aquí hay un diagrama de cómo se relacionan entre sí: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Importante, no podemos encontrar ningún código construyendo un canal de entrada en este nivel, solo referencias a un samplesheet proporcionado a través del parámetro `--input`. + +Un poco de investigación revela que el manejo de entrada lo realiza el subworkflow `PIPELINE_INITIALISATION`, apropiadamente, que se importa de `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`. + +Si abrimos ese archivo y nos desplazamos hacia abajo, llegamos a este fragmento de código: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +Esta es la fábrica de canales que analiza el samplesheet y lo pasa en una forma que está lista para ser consumida por el workflow HELLO. + +!!! note "Nota" + + La sintaxis anterior es un poco diferente de lo que hemos usado anteriormente, pero básicamente esto: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + es equivalente a esto: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Este código involucra algunos pasos de análisis y validación que son altamente específicos del samplesheet de ejemplo incluido con la plantilla del pipeline nf-core, que al momento de escribir esto es muy específico del dominio y no es adecuado para nuestro proyecto de pipeline simple. + +### 4.2. Reemplazar el código del canal de entrada de la plantilla + +La buena noticia es que las necesidades de nuestro pipeline son mucho más simples, por lo que podemos reemplazar todo eso por el código de construcción de canal que desarrollamos en el workflow Hello Nextflow original. + +Como recordatorio, así se veía la construcción del canal (como se ve en el directorio de soluciones): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Así que solo necesitamos conectar eso en el workflow de inicialización, con cambios menores: actualizamos el nombre del canal de `greeting_ch` a `ch_samplesheet`, y el nombre del parámetro de `params.greeting` a `params.input` (ver línea destacada). + +=== "Después" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Create channel from input file provided through params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Eso completa los cambios que necesitamos hacer para que el procesamiento de entrada funcione. + +En su forma actual, esto no nos permitirá aprovechar las capacidades integradas de nf-core para la validación de esquema, pero podemos agregar eso más tarde. +Por ahora, nos estamos enfocando en mantenerlo lo más simple posible para llegar a algo que podamos ejecutar exitosamente en datos de prueba. + +### 4.3. Actualizar el perfil de prueba + +Hablando de datos de prueba y parámetros, actualicemos el perfil de prueba para este pipeline para usar el mini-samplesheet `greetings.csv` en lugar del samplesheet de ejemplo proporcionado en la plantilla. + +Bajo `core-hello/conf`, encontramos dos perfiles de prueba de plantilla: `test.config` y `test_full.config`, que están destinados a probar una muestra pequeña de datos y una de tamaño completo. +Dado el propósito de nuestro pipeline, realmente no hay sentido en configurar un perfil de prueba de tamaño completo, así que siéntete libre de ignorar o eliminar `test_full.config`. +Nos vamos a enfocar en configurar `test.config` para que se ejecute en nuestro archivo `greetings.csv` con algunos parámetros predeterminados. + +#### 4.3.1. Copiar el archivo `greetings.csv` + +Primero necesitamos copiar el archivo `greetings.csv` a un lugar apropiado en nuestro proyecto de pipeline. +Típicamente los archivos de prueba pequeños se almacenan en el directorio `assets`, así que copiemos el archivo desde nuestro directorio de trabajo. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Ahora el archivo `greetings.csv` está listo para ser usado como entrada de prueba. + +#### 4.3.2. Actualizar el archivo `test.config` + +Ahora podemos actualizar el archivo `test.config` de la siguiente manera: + +=== "Después" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Datos de entrada + input = "${projectDir}/assets/greetings.csv" + + // Other parameters + batch = 'test' + character = 'tux' + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Datos de entrada + // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets + // TODO nf-core: Give any required params for the test so that command line flags are not needed + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Puntos clave: + +- **Usando `${projectDir}`**: Esta es una variable implícita de Nextflow que apunta al directorio donde se encuentra el script de workflow principal (la raíz del pipeline). Usarla asegura que la ruta funcione independientemente de dónde se ejecute el pipeline. +- **Rutas absolutas**: Al usar `${projectDir}`, creamos una ruta absoluta, lo cual es importante para datos de prueba que se envían con el pipeline. +- **Ubicación de datos de prueba**: Los pipelines nf-core típicamente almacenan datos de prueba en el directorio `assets/` dentro del repositorio del pipeline para archivos de prueba pequeños, o referencian conjuntos de datos de prueba externos para archivos más grandes. + +Y ya que estamos en eso, ajustemos los límites de recursos predeterminados para asegurar que esto se ejecutará en máquinas muy básicas (como las VMs mínimas en Github Codespaces): + +=== "Después" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Antes" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Esto completa las modificaciones de código que necesitamos hacer. + +### 4.4. Ejecutar el pipeline con el perfil de prueba + +Eso fue mucho, ¡pero finalmente podemos intentar ejecutar el pipeline! +Ten en cuenta que tenemos que agregar `--validate_params false` a la línea de comando porque no configuramos la validación todavía (eso vendrá más tarde). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Si has hecho todas las modificaciones correctamente, debería ejecutarse hasta completarse. + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Como puedes ver, esto produjo el resumen típico de nf-core al inicio gracias al subworkflow de inicialización, y las líneas para cada módulo ahora muestran los nombres completos PIPELINE:WORKFLOW:module. + +### 4.5. Encontrar las salidas del pipeline + +La pregunta ahora es: ¿dónde están las salidas del pipeline? +Y la respuesta es bastante interesante: ahora hay dos lugares diferentes donde buscar los resultados. + +Como puede que recuerdes de antes, nuestra primera ejecución del workflow recién creado produjo un directorio llamado `core-hello-results/` que contenía varios reportes de ejecución y metadatos. + +```bash +tree core-hello-results +``` + +??? abstract "Contenido del directorio" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_07-29-37.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── execution_trace_2025-11-21_07-29-37.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-13.json + ├── params_2025-11-21_07-29-41.json + └── pipeline_dag_2025-11-21_04-47-18.html + └── pipeline_dag_2025-11-21_07-29-37.html + + 1 directory, 12 files + ``` + +Ves que obtuvimos otro conjunto de reportes de ejecución además de los que obtuvimos de la primera ejecución, cuando el workflow era solo un placeholder. +Esta vez ves todas las tareas que se ejecutaron como se esperaba. + +![reporte de línea de tiempo de ejecución para el pipeline Hello](./img/execution_timeline_hello.png) + +!!! note "Nota" + + Una vez más, las tareas no se ejecutaron en paralelo porque estamos ejecutando en una máquina minimalista en Github Codespaces. + Para ver que se ejecuten en paralelo, intenta aumentar la asignación de CPU de tu codespace y los límites de recursos en la configuración de prueba. + +Eso es genial, ¡pero nuestros resultados reales del pipeline no están ahí! + +Aquí está lo que pasó: no cambiamos nada de los módulos en sí, por lo que las salidas manejadas por las directivas `publishDir` a nivel de módulo todavía van a un directorio `results` como se especificó en el pipeline original. + +```bash +tree results +``` + +??? abstract "Contenido del directorio" + + ```console + results + ├── Bonjour-output.txt + ├── COLLECTED-test-batch-output.txt + ├── COLLECTED-test-output.txt + ├── cowpy-COLLECTED-test-batch-output.txt + ├── cowpy-COLLECTED-test-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + 0 directories, 10 files + ``` + +Ah, ahí están, mezclados con las salidas de ejecuciones anteriores del pipeline Hello original. + +Si queremos que estén organizados ordenadamente como lo estaban las salidas del pipeline demo, necesitaremos cambiar cómo configuramos las salidas para ser publicadas. +Te mostraremos cómo hacer eso más adelante en este curso de entrenamiento. + +<!-- TODO: Update this once we've updated Hello Nextflow to use workflow-level outputs --> + +¡Y ahí lo tienes! Puede parecer mucho trabajo para lograr el mismo resultado que el pipeline original, pero obtienes todos esos reportes hermosos generados automáticamente, y ahora tienes una base sólida para aprovechar las características adicionales de nf-core, incluyendo la validación de entrada y algunas capacidades ingeniosas de manejo de metadatos que cubriremos en una sección posterior. + +--- + +### Conclusión + +Sabes cómo convertir un pipeline regular de Nextflow en un pipeline de estilo nf-core usando la plantilla nf-core. +Como parte de eso, aprendiste cómo hacer un workflow componible, y cómo identificar los elementos de la plantilla nf-core que más comúnmente necesitan ser adaptados al desarrollar un pipeline de estilo nf-core personalizado. + +### ¿Qué sigue? + +¡Toma un descanso, fue un trabajo duro! Cuando estés listo, continúa con [Parte 3: Usar un módulo nf-core](./03_use_module.md) para aprender cómo aprovechar módulos mantenidos por la comunidad del repositorio nf-core/modules. diff --git a/docs/es/docs/hello_nf-core/03_use_module.md b/docs/es/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..8a66647db5 --- /dev/null +++ b/docs/es/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Parte 3: Usar un módulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta tercera parte del curso de entrenamiento Hello nf-core, le mostramos cómo encontrar, instalar y usar un módulo nf-core existente en su pipeline. + +Uno de los grandes beneficios de trabajar con nf-core es la capacidad de aprovechar módulos preconstruidos y probados del repositorio [nf-core/modules](https://github.com/nf-core/modules). +En lugar de escribir cada proceso desde cero, puede instalar y usar módulos mantenidos por la comunidad que siguen las mejores prácticas. + +Para demostrar cómo funciona esto, reemplazaremos el módulo personalizado `collectGreetings` con el módulo `cat/cat` de nf-core/modules en el pipeline `core-hello`. + +??? info "Cómo comenzar desde esta sección" + + Esta sección del curso asume que ha completado la [Parte 2: Reescribir Hello para nf-core](./02_rewrite_hello.md) y tiene un pipeline `core-hello` funcional. + + Si no completó la Parte 2 o desea comenzar desde cero para esta parte, puede usar la solución `core-hello-part2` como punto de partida. + Ejecute este comando desde el directorio `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Esto le proporciona un pipeline nf-core completamente funcional listo para agregar módulos. + Puede probar que se ejecuta correctamente ejecutando el siguiente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Encontrar e instalar un módulo nf-core adecuado + +Primero, aprendamos cómo encontrar un módulo nf-core existente e instalarlo en nuestro pipeline. + +Nuestro objetivo será reemplazar el proceso `collectGreetings`, que utiliza el comando Unix `cat` para concatenar múltiples archivos de saludo en uno. +Concatenar archivos es una operación muy común, por lo que es razonable pensar que podría haber ya un módulo en nf-core diseñado para ese propósito. + +Comencemos. + +### 1.1. Explorar los módulos disponibles en el sitio web de nf-core + +El proyecto nf-core mantiene un catálogo centralizado de módulos en [https://nf-co.re/modules](https://nf-co.re/modules). + +Navegue a la página de módulos en su navegador web y use la barra de búsqueda para buscar 'concatenate'. + +![module search results](./img/module-search-results.png) + +Como puede ver, hay bastantes resultados, muchos de ellos módulos diseñados para concatenar tipos de archivos muy específicos. +Entre ellos, debería ver uno llamado `cat_cat` que es de propósito general. + +!!! note "Convención de nomenclatura de módulos" + + El guion bajo (`_`) se usa como sustituto del carácter de barra diagonal (`/`) en los nombres de los módulos. + + Los módulos nf-core siguen la convención de nomenclatura `software/comando` cuando una herramienta proporciona múltiples comandos, como `samtools/view` (paquete samtools, comando view) o `gatk/haplotypecaller` (paquete GATK, comando HaplotypeCaller). + Para herramientas que proporcionan solo un comando principal, los módulos usan un solo nivel como `fastqc` o `multiqc`. + +Haga clic en el recuadro del módulo `cat_cat` para ver la documentación del módulo. + +La página del módulo muestra: + +- Una breve descripción: "A module for concatenation of gzipped or uncompressed files" +- Comando de instalación: `nf-core modules install cat/cat` +- Estructura de canales de entrada y salida +- Parámetros disponibles + +### 1.2. Listar los módulos disponibles desde la línea de comandos + +Alternativamente, también puede buscar módulos directamente desde la línea de comandos usando las herramientas nf-core. + +```bash +nf-core modules list remote +``` + +Esto mostrará una lista de todos los módulos disponibles en el repositorio nf-core/modules, aunque es un poco menos conveniente si no conoce ya el nombre del módulo que está buscando. +Sin embargo, si lo conoce, puede canalizar la lista a `grep` para encontrar módulos específicos: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Salida del comando" + + ```console + │ cat/cat + ``` + +Tenga en cuenta que el enfoque de `grep` solo mostrará resultados con el término de búsqueda en su nombre, lo que no funcionaría para `cat_cat`. + +### 1.3. Obtener información detallada sobre el módulo + +Para ver información detallada sobre un módulo específico desde la línea de comandos, use el comando `info`: + +```bash +nf-core modules info cat/cat +``` + +Esto muestra documentación sobre el módulo, incluyendo sus entradas, salidas e información básica de uso. + +??? success "Salida del comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +Esta es exactamente la misma información que puede encontrar en el sitio web. + +### 1.4. Instalar el módulo cat/cat + +Ahora que hemos encontrado el módulo que queremos, necesitamos agregarlo al código fuente de nuestro pipeline. + +La buena noticia es que el proyecto nf-core incluye algunas herramientas para facilitar esta parte. +Específicamente, el comando `nf-core modules install` permite automatizar la recuperación del código y hacerlo disponible para su proyecto en un solo paso. + +Navegue al directorio de su pipeline y ejecute el comando de instalación: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +La herramienta puede primero solicitarle que especifique un tipo de repositorio. +(Si no lo hace, salte a "Finalmente, la herramienta procederá a instalar el módulo.") + +??? success "Salida del comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Si es así, presione enter para aceptar la respuesta predeterminada (`Pipeline`) y continuar. + +Luego, la herramienta ofrecerá modificar la configuración de su proyecto para evitar esta solicitud en el futuro. + +??? success "Salida del comando" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +¡Más vale aprovechar esta práctica herramienta! +Presione enter para aceptar la respuesta predeterminada (sí). + +Finalmente, la herramienta procederá a instalar el módulo. + +??? success "Salida del comando" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +El comando automáticamente: + +- Descarga los archivos del módulo a `modules/nf-core/cat/cat/` +- Actualiza `modules.json` para rastrear el módulo instalado +- Le proporciona la declaración `include` correcta para usar en su workflow + +!!! tip + + Asegúrese siempre de que su directorio de trabajo actual sea la raíz de su proyecto de pipeline antes de ejecutar el comando de instalación del módulo. + +Verifiquemos que el módulo se instaló correctamente: + +```bash +tree -L 4 modules +``` + +??? abstract "Contenidos del directorio" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +También puede verificar la instalación pidiendo a la utilidad nf-core que liste los módulos instalados localmente: + +```bash +nf-core modules list local +``` + +??? success "Salida del comando" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Esto confirma que el módulo `cat/cat` ahora es parte del código fuente de su proyecto. + +Sin embargo, para realmente usar el nuevo módulo, necesitamos importarlo en nuestro pipeline. + +### 1.5. Actualizar las importaciones de módulos + +Reemplacemos la declaración `include` para el módulo `collectGreetings` con la de `CAT_CAT` en la sección de importaciones del workflow `workflows/hello.nf`. + +Como recordatorio, la herramienta de instalación del módulo nos dio la declaración exacta a usar: + +```groovy title="Declaración de importación producida por el comando install" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Tenga en cuenta que la convención nf-core es usar mayúsculas para los nombres de los módulos al importarlos. + +Abra [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) y realice la siguiente sustitución: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Observe cómo la ruta para el módulo nf-core difiere de los módulos locales: + +- **Módulo nf-core**: `'../modules/nf-core/cat/cat/main'` (referencia a `main.nf`) +- **Módulo local**: `'../modules/local/collectGreetings.nf'` (referencia a archivo único) + +El módulo ahora está disponible para el workflow, así que todo lo que necesitamos hacer es intercambiar la llamada a `collectGreetings` para usar `CAT_CAT`. ¿Correcto? + +No tan rápido. + +En este punto, podría sentirse tentado a sumergirse y comenzar a editar código, pero vale la pena tomarse un momento para examinar cuidadosamente qué espera el nuevo módulo y qué produce. + +Vamos a abordar eso como una sección separada porque involucra un nuevo mecanismo que no hemos cubierto todavía: los mapas de metadatos. + +!!! note + + Opcionalmente puede eliminar el archivo `collectGreetings.nf`: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Sin embargo, podría querer mantenerlo como referencia para comprender las diferencias entre los módulos locales y los de nf-core. + +### Conclusión + +Sabe cómo encontrar un módulo nf-core y hacerlo disponible para su proyecto. + +### ¿Qué sigue? + +Evaluar qué requiere un nuevo módulo e identificar cualquier cambio importante necesario para integrarlo en un pipeline. + +--- + +## 2. Evaluar los requisitos del nuevo módulo + +Específicamente, necesitamos examinar la **interfaz** del módulo, es decir, sus definiciones de entrada y salida, y compararla con la interfaz del módulo que buscamos reemplazar. +Esto nos permitirá determinar si podemos simplemente tratar el nuevo módulo como un reemplazo directo o si necesitaremos adaptar parte del cableado. + +Idealmente, esto es algo que debería hacer _antes_ de instalar el módulo, pero bueno, más vale tarde que nunca. +(Para su información, existe un comando `uninstall` para deshacerse de los módulos que decide que ya no quiere.) + +!!! note + + El proceso CAT_CAT incluye un manejo bastante ingenioso de diferentes tipos de compresión, extensiones de archivo, etc., que no son estrictamente relevantes para lo que estamos tratando de mostrarle aquí, así que ignoraremos la mayor parte y nos enfocaremos solo en las partes que son importantes. + +### 2.1. Comparar las interfaces de los dos módulos + +Como recordatorio, esto es cómo se ve la interfaz de nuestro módulo `collectGreetings`: + +```groovy title="modules/local/collectGreetings.nf (extracto)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +El módulo `collectGreetings` toma dos entradas: + +- `input_files` contiene uno o más archivos de entrada para procesar; +- `batch_name` es un valor que usamos para asignar un nombre específico de ejecución al archivo de salida, que es una forma de metadatos. + +Al completarse, `collectGreetings` produce una sola ruta de archivo, emitida con la etiqueta `outfile`. + +En comparación, la interfaz del módulo `cat/cat` es más compleja: + +```groovy title="modules/nf-core/cat/cat/main.nf (extracto)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +El módulo CAT_CAT toma una sola entrada, pero esa entrada es una tupla que contiene dos cosas: + +- `meta` es una estructura que contiene metadatos, llamada metamapa; +- `files_in` contiene uno o más archivos de entrada para procesar, equivalente a `input_files` de `collectGreetings`. + +Al completarse, CAT_CAT entrega sus salidas en dos partes: + +- Otra tupla que contiene el metamapa y el archivo de salida concatenado, emitido con la etiqueta `file_out`; +- Un archivo `versions.yml` que captura información sobre la versión del software que se usó, emitido con la etiqueta `versions`. + +Observe también que, por defecto, el archivo de salida se nombrará en base a un identificador que es parte de los metadatos (código no mostrado aquí). + +Esto puede parecer mucho para llevar un registro solo mirando el código, así que aquí hay un diagrama para ayudarlo a visualizar cómo todo encaja. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Puede ver que los dos módulos tienen requisitos de entrada similares en términos de contenido (un conjunto de archivos de entrada más algunos metadatos) pero expectativas muy diferentes sobre cómo se empaqueta ese contenido. +Ignorando el archivo de versiones por ahora, su salida principal también es equivalente (un archivo concatenado), excepto que CAT_CAT también emite el metamapa junto con el archivo de salida. + +Las diferencias de empaquetado serán bastante fáciles de manejar, como verá en un momento. +Sin embargo, para entender la parte del metamapa, necesitamos presentarle algo de contexto adicional. + +### 2.2. Comprender los metamapas + +Acabamos de decirle que el módulo CAT_CAT espera un mapa de metadatos como parte de su tupla de entrada. +Tomemos unos minutos para examinar más de cerca qué es eso. + +El **mapa de metadatos**, a menudo referido como **metamapa** para abreviar, es un mapa estilo Groovy que contiene información sobre unidades de datos. +En el contexto de los pipelines Nextflow, las unidades de datos pueden ser lo que usted quiera: muestras individuales, lotes de muestras o conjuntos de datos completos. + +Por convención, un metamapa nf-core se llama `meta` y contiene el campo requerido `id`, que se usa para nombrar salidas y rastrear unidades de datos. + +Por ejemplo, un mapa de metadatos típico podría verse así: + +```groovy title="Ejemplo de metamapa a nivel de muestra" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +O en un caso donde los metadatos se adjuntan a nivel de lote: + +```groovy title="Ejemplo de metamapa a nivel de lote" +[id: 'batch1', date: '25.10.01'] +``` + +Ahora pongamos esto en el contexto del proceso `CAT_CAT`, que espera que los archivos de entrada se empaqueten en una tupla con un metamapa, y también produce el metamapa como parte de la tupla de salida. + +```groovy title="modules/nf-core/cat/cat/main.nf (extracto)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +Como resultado, cada unidad de datos viaja a través del pipeline con los metadatos relevantes adjuntos. +Los procesos subsecuentes pueden entonces acceder fácilmente a esos metadatos también. + +¿Recuerda cómo le dijimos que el archivo producido por `CAT_CAT` se nombrará en base a un identificador que es parte de los metadatos? +Este es el código relevante: + +```groovy title="modules/nf-core/cat/cat/main.nf (extracto)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Esto se traduce aproximadamente de la siguiente manera: si se proporciona un `prefix` a través del sistema de parámetros externos de tarea (`task.ext`), úselo para nombrar el archivo de salida; de lo contrario, cree uno usando `${meta.id}`, que corresponde al campo `id` en el metamapa. + +Puede imaginar el canal de entrada llegando a este módulo con contenidos como este: + +```groovy title="Ejemplo de contenidos del canal de entrada" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Luego, los contenidos del canal de salida saliendo así: + +```groovy title="Ejemplo de contenidos del canal de salida" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Como se mencionó anteriormente, la configuración de entrada `tuple val(meta), path(files_in)` es un patrón estándar usado en todos los módulos nf-core. + +Con suerte, puede comenzar a ver qué tan útil puede ser esto. +No solo le permite nombrar salidas basadas en metadatos, sino que también puede hacer cosas como usarlo para aplicar diferentes valores de parámetros, y en combinación con operadores específicos, incluso puede agrupar, ordenar o filtrar datos a medida que fluyen a través del pipeline. + +!!! note "Aprenda más sobre metadatos" + + Para una introducción completa sobre cómo trabajar con metadatos en workflows Nextflow, incluyendo cómo leer metadatos de hojas de muestras y usarlos para personalizar el procesamiento, consulte la [Metadatos en workflows](../side_quests/metadata) misión secundaria. + +### 2.3. Resumir los cambios a realizar + +Basándonos en lo que hemos revisado, estos son los cambios principales que necesitamos hacer a nuestro pipeline para utilizar el módulo `cat/cat`: + +- Crear un metamapa que contenga el nombre del lote; +- Empaquetar el metamapa en una tupla con el conjunto de archivos de entrada a concatenar (provenientes de `convertToUpper`); +- Cambiar la llamada de `collectGreetings()` a `CAT_CAT`; +- Extraer el archivo de salida de la tupla producida por el proceso `CAT_CAT` antes de pasarlo a `cowpy`. + +¡Eso debería funcionar! Ahora que tenemos un plan, estamos listos para sumergirnos. + +### Conclusión + +Sabe cómo evaluar la interfaz de entrada y salida de un nuevo módulo para identificar sus requisitos, y ha aprendido cómo los metamapas son usados por los pipelines nf-core para mantener los metadatos estrechamente asociados con los datos a medida que fluyen a través de un pipeline. + +### ¿Qué sigue? + +Integrar el nuevo módulo en un workflow. + +--- + +## 3. Integrar CAT_CAT en el workflow `hello.nf` + +Ahora que sabe todo sobre los metamapas (o suficiente para los propósitos de este curso, de todos modos), es hora de implementar realmente los cambios que describimos anteriormente. + +Por claridad, desglosaremos esto y cubriremos cada paso por separado. + +!!! note + + Todos los cambios mostrados a continuación se realizan en la lógica del workflow en el bloque `main` en el archivo de workflow `core-hello/workflows/hello.nf`. + +### 3.1. Crear un mapa de metadatos + +Primero, necesitamos crear un mapa de metadatos para `CAT_CAT`, teniendo en cuenta que los módulos nf-core requieren que el metamapa tenga al menos un campo `id`. + +Dado que no necesitamos otros metadatos, podemos mantenerlo simple y usar algo como esto: + +```groovy title="Ejemplo de sintaxis" +def cat_meta = [id: 'test'] +``` + +Excepto que no queremos codificar el valor de `id`; queremos usar el valor del parámetro `params.batch`. +Entonces el código se convierte en: + +```groovy title="Ejemplo de sintaxis" +def cat_meta = [id: params.batch] +``` + +Sí, es literalmente así de simple crear un metamapa básico. + +Agreguemos estas líneas después de la llamada a `convertToUpper`, eliminando la llamada a `collectGreetings`: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Esto crea un mapa de metadatos simple donde el `id` se establece en nuestro nombre de lote (que será `test` cuando se use el perfil de prueba). + +### 3.2. Crear un canal con tuplas de metadatos + +A continuación, transforme el canal de archivos en un canal de tuplas que contengan metadatos y archivos: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // crear un canal con metadatos y archivos en formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +La línea que hemos agregado logra dos cosas: + +- `.collect()` reúne todos los archivos de la salida de `convertToUpper` en una sola lista +- `.map { files -> tuple(cat_meta, files) }` crea una tupla de `[metadatos, archivos]` en el formato que `CAT_CAT` espera + +Eso es todo lo que necesitamos hacer para configurar la tupla de entrada para `CAT_CAT`. + +### 3.3. Llamar al módulo CAT_CAT + +Ahora llame a `CAT_CAT` en el canal recién creado: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // crear un canal con metadatos y archivos en formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar archivos usando el módulo nf-core cat/cat + CAT_CAT(ch_for_cat) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // crear un canal con metadatos y archivos en formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Esto completa la parte más complicada de esta sustitución, pero aún no hemos terminado: todavía necesitamos actualizar cómo pasamos la salida concatenada al proceso `cowpy`. + +### 3.4. Extraer el archivo de salida de la tupla para `cowpy` + +Anteriormente, el proceso `collectGreetings` simplemente producía un archivo que podíamos pasar a `cowpy` directamente. +Sin embargo, el proceso `CAT_CAT` produce una tupla que incluye el metamapa además del archivo de salida. + +Dado que `cowpy` aún no acepta tuplas de metadatos (arreglaremos esto en la siguiente parte del curso), necesitamos extraer el archivo de salida de la tupla producida por `CAT_CAT` antes de pasarlo a `cowpy`: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // crear un canal con metadatos y archivos en formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar los saludos + CAT_CAT(ch_for_cat) + + // extraer el archivo de la tupla ya que cowpy aún no usa metadatos + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // generar arte ASCII de los saludos con cowpy + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // emitir un saludo + sayHello(ch_samplesheet) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + + // crear mapa de metadatos con el nombre del lote como ID + def cat_meta = [ id: params.batch ] + + // crear un canal con metadatos y archivos en formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar los saludos + CAT_CAT(ch_for_cat) + + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +La operación `.map{ meta, file -> file }` extrae el archivo de la tupla `[metadatos, archivo]` producida por `CAT_CAT` en un nuevo canal, `ch_for_cowpy`. + +Luego, es solo cuestión de pasar `ch_for_cowpy` a `cowpy` en lugar de `collectGreetings.out.outfile` en esa última línea. + +!!! note + + En la siguiente parte del curso, actualizaremos `cowpy` para trabajar con tuplas de metadatos directamente, por lo que este paso de extracción ya no será necesario. + +### 3.5. Probar el workflow + +Probemos que el workflow funciona con el módulo `cat/cat` recién integrado: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Esto debería ejecutarse razonablemente rápido. + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Observe que `CAT_CAT` ahora aparece en la lista de ejecución de procesos en lugar de `collectGreetings`. + +¡Y eso es todo! Ahora estamos usando un módulo robusto mantenido por la comunidad en lugar de código personalizado de grado prototipo para ese paso en el pipeline. + +### Conclusión + +Ahora sabe cómo: + +- Encontrar e instalar módulos nf-core +- Evaluar los requisitos de un módulo nf-core +- Crear un mapa de metadatos simple para usar con un módulo nf-core +- Integrar un módulo nf-core en su workflow + +### ¿Qué sigue? + +Aprenda a adaptar sus módulos locales para seguir las convenciones nf-core. +También le mostraremos cómo crear nuevos módulos nf-core a partir de una plantilla usando las herramientas nf-core. diff --git a/docs/es/docs/hello_nf-core/04_make_module.md b/docs/es/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..d3aff8b6a1 --- /dev/null +++ b/docs/es/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1180 @@ +# Parte 4: Crear un módulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta cuarta parte del curso de entrenamiento Hello nf-core, le mostramos cómo crear un módulo nf-core aplicando las convenciones clave que hacen que los módulos sean portables y mantenibles. + +El proyecto nf-core proporciona un comando (`nf-core modules create`) que genera plantillas de módulos estructuradas correctamente de forma automática, similar a lo que usamos para el flujo de trabajo en la Parte 2. +Sin embargo, con fines didácticos, vamos a comenzar haciéndolo manualmente: transformando el módulo local `cowpy` en su pipeline `core-hello` en un módulo de estilo nf-core paso a paso. +Después de eso, le mostraremos cómo usar la creación de módulos basada en plantillas para trabajar de manera más eficiente en el futuro. + +??? info "Cómo comenzar desde esta sección" + + Esta sección asume que ha completado la [Parte 3: Usar un módulo nf-core](./03_use_module.md) e ha integrado el módulo `CAT_CAT` en su pipeline. + + Si no completó la Parte 3 o desea comenzar de nuevo para esta parte, puede usar la solución `core-hello-part3` como punto de partida. + Ejecute estos comandos desde dentro del directorio `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Esto le proporciona un pipeline con el módulo `CAT_CAT` ya integrado. + Puede probar que se ejecuta correctamente ejecutando el siguiente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Transformar `cowpy` en un módulo nf-core + +En esta sección, aplicaremos las convenciones de nf-core al módulo local `cowpy` en su pipeline `core-hello`, transformándolo en un módulo que sigue los estándares de la comunidad nf-core. + +Este es el código actual para el módulo de proceso `cowpy`: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Aplicaremos las siguientes convenciones de nf-core de forma incremental: + +1. **Cambiar el nombre del proceso a mayúsculas `COWPY`** para seguir la convención. +2. **Actualizar `COWPY` para usar tuplas de metadatos** para propagar los metadatos de muestra a través del flujo de trabajo. +3. **Centralizar la configuración de argumentos de la herramienta con `ext.args`** para aumentar la versatilidad del módulo mientras se mantiene la interfaz mínima. +4. **Estandarizar el nombre de salida con `ext.prefix`** para promover la consistencia. +5. **Centralizar la configuración de publicación** para promover la consistencia. + +Después de cada paso, ejecutaremos el pipeline para probar que todo funciona como se espera. + +!!! warning "Directorio de trabajo" + + Asegúrese de estar en el directorio `core-hello` (la raíz de su pipeline) para todas las ediciones de archivos y ejecuciones de comandos en esta sección. + + ```bash + cd core-hello + ``` + +### 1.1. Cambiar el nombre del proceso a mayúsculas + +Esta es puramente una convención estilística (no hay justificación técnica), pero dado que es la norma para los módulos nf-core, vamos a cumplirla. + +Necesitamos hacer tres conjuntos de cambios: + +1. Actualizar el nombre del proceso en el módulo +2. Actualizar la declaración de importación del módulo en el encabezado del flujo de trabajo +3. Actualizar la llamada al proceso y la declaración emit en el cuerpo del flujo de trabajo + +¡Comencemos! + +#### 1.1.1. Actualizar el nombre del proceso en el módulo + +Abra el archivo del módulo `cowpy.nf` (en `core-hello/modules/local/`) y modifique el nombre del proceso a mayúsculas: + +=== "Después" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +En este caso, el cambio a mayúsculas es completamente directo. + +Si el nombre del proceso estuviera compuesto por varias palabras, por ejemplo si tuviéramos un proceso llamado MyCowpyTool originalmente en camelCase, la convención de nf-core sería usar guiones bajos para separarlas, resultando en MY_COWPY_TOOL. + +#### 1.1.2. Actualizar la declaración de importación del módulo + +Los nombres de procesos distinguen entre mayúsculas y minúsculas, así que ahora que hemos cambiado el nombre del proceso, necesitamos actualizar la declaración de importación del módulo en consecuencia en el encabezado del flujo de trabajo de `hello.nf`: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Podríamos usar un alias en la declaración de importación para evitar tener que actualizar las llamadas al proceso, pero eso de alguna manera anularía el propósito de adoptar la convención de mayúsculas. + +#### 1.1.3. Actualizar la llamada al proceso y la declaración emit + +Así que ahora actualicemos las dos referencias al proceso en el bloque workflow de `hello.nf`: + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // generar arte ASCII de los saludos con cowpy + COWPY(CAT_CAT.out.file_out) + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // generar arte ASCII de los saludos con cowpy + cowpy(CAT_CAT.out.file_out) + + // + // Recopilar y guardar versiones de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Asegúrese de hacer **ambos** cambios, de lo contrario obtendrá un error cuando ejecute esto. + +#### 1.1.4. Ejecutar el pipeline para probarlo + +Ejecutemos el flujo de trabajo para probar que todo está funcionando correctamente después de estos cambios. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +¡Muy bien, esto funciona! Ahora pasemos a hacer cambios más sustanciales. + +### 1.2. Actualizar `COWPY` para usar tuplas de metadatos + +En la versión actual del pipeline `core-hello`, estamos extrayendo el archivo de la tupla de salida de `CAT_CAT` para pasarlo a `COWPY`, como se muestra en la mitad superior del diagrama a continuación. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Sería mejor que `COWPY` aceptara tuplas de metadatos directamente, permitiendo que los metadatos fluyan a través del flujo de trabajo, como se muestra en la mitad inferior del diagrama. + +Para lograrlo, necesitaremos hacer los siguientes cambios: + +1. Actualizar las definiciones de entrada y salida +2. Actualizar la llamada al proceso en el flujo de trabajo +3. Actualizar el bloque emit en el flujo de trabajo + +Una vez que hayamos hecho todo eso, ejecutaremos el pipeline para probar que todo sigue funcionando como antes. + +#### 1.2.1. Actualizar las definiciones de entrada y salida + +Regrese al archivo del módulo `cowpy.nf` y modifíquelo para aceptar tuplas de metadatos como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Como puede ver, cambiamos tanto la **entrada principal** como la **salida** a una tupla que sigue el patrón `tuple val(meta), path(input_file)` introducido en la Parte 3 de este entrenamiento. +Para la salida, también aprovechamos esta oportunidad para agregar `emit: cowpy_output` con el fin de dar al canal de salida un nombre descriptivo. + +Ahora que hemos cambiado lo que el proceso espera, necesitamos actualizar lo que le proporcionamos en la llamada al proceso. + +#### 1.2.2. Actualizar la llamada al proceso en el flujo de trabajo + +La buena noticia es que este cambio simplificará la llamada al proceso. +Ahora que la salida de `CAT_CAT` y la entrada de `COWPY` tienen la misma 'forma', es decir, ambas consisten en una estructura `tuple val(meta), path(input_file)`, simplemente podemos conectarlas directamente en lugar de tener que extraer el archivo explícitamente de la salida del proceso `CAT_CAT`. + +Abra el archivo de flujo de trabajo `hello.nf` (en `core-hello/workflows/`) y actualice la llamada a `COWPY` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // generar arte ASCII de los saludos con cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extract the file from the tuple since cowpy doesn't use metadata yet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // generar arte ASCII de los saludos con cowpy + COWPY(ch_for_cowpy, params.character) + ``` + +Ahora llamamos a `COWPY` directamente en `CAT_CAT.out.file_out`. + +Como resultado, ya no necesitamos construir el canal `ch_for_cowpy`, por lo que esa línea (y su línea de comentario) se pueden eliminar por completo. + +#### 1.2.3. Actualizar el bloque emit en el flujo de trabajo + +Dado que `COWPY` ahora emite una salida nombrada, `cowpy_output`, podemos actualizar el bloque `emit:` del flujo de trabajo `hello.nf` para usar eso. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Técnicamente esto no es requerido, pero es una buena práctica referirse a salidas nombradas siempre que sea posible. + +#### 1.2.4. Ejecutar el pipeline para probarlo + +Ejecutemos el flujo de trabajo para probar que todo está funcionando correctamente después de estos cambios. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +El pipeline debería ejecutarse exitosamente, con los metadatos ahora fluyendo desde `CAT_CAT` a través de `COWPY`. + +Eso completa lo que necesitábamos hacer para que `COWPY` maneje tuplas de metadatos. +Ahora, veamos qué más podemos hacer para aprovechar los patrones de módulos de nf-core. + +### 1.3. Centralizar la configuración de argumentos de herramientas con `ext.args` + +En su estado actual, el proceso `COWPY` espera recibir un valor para el parámetro `character`. +Como resultado, tenemos que proporcionar un valor cada vez que llamamos al proceso, incluso si estaríamos contentos con los valores predeterminados establecidos por la herramienta. +Para `COWPY` esto admitidamente no es un gran problema, pero para herramientas con muchos parámetros opcionales, puede volverse bastante engorroso. + +El proyecto nf-core recomienda usar una característica de Nextflow llamada [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) para gestionar los argumentos de herramientas de manera más conveniente a través de archivos de configuración. + +En lugar de declarar entradas de proceso para cada opción de herramienta, usted escribe el módulo para referenciar `ext.args` en la construcción de su línea de comandos. +Luego es solo cuestión de configurar la variable `ext.args` para contener los argumentos y valores que desea usar en el archivo `modules.config`, que consolida los detalles de configuración para todos los módulos. +Nextflow agregará esos argumentos con sus valores a la línea de comandos de la herramienta en tiempo de ejecución. + +Apliquemos este enfoque al módulo `COWPY`. +Vamos a necesitar hacer los siguientes cambios: + +1. Actualizar el módulo `COWPY` +2. Configurar `ext.args` en el archivo `modules.config` +3. Actualizar el flujo de trabajo `hello.nf` + +Una vez que hayamos hecho todo eso, ejecutaremos el pipeline para probar que todo sigue funcionando como antes. + +#### 1.3.1. Actualizar el módulo `COWPY` + +Hagámoslo. +Abra el archivo del módulo `cowpy.nf` (en `core-hello/modules/local/`) y modifíquelo para referenciar `ext.args` como se muestra a continuación. + +=== "Después" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Puede ver que hicimos tres cambios. + +1. **En el bloque `input:`, eliminamos la entrada `val character`.** + De ahora en adelante, proporcionaremos ese argumento a través de la configuración `ext.args` como se describe más adelante. + +2. **En el bloque `script:`, agregamos la línea `def args = task.ext.args ?: ''`.** + Esa línea usa el operador `?:` para determinar el valor de la variable `args`: el contenido de `task.ext.args` si no está vacío, o una cadena vacía si lo está. + Tenga en cuenta que aunque generalmente nos referimos a `ext.args`, este código debe referenciar `task.ext.args` para extraer la configuración de `ext.args` a nivel de módulo. + +3. **En la línea de comandos, reemplazamos `-c "$character"` con `$args`.** + Aquí es donde Nextflow inyectará cualquier argumento de herramienta configurado en `ext.args` en el archivo `modules.config`. + +Como resultado, la interfaz del módulo ahora es más simple: solo espera las entradas esenciales de metadatos y archivos. + +!!! note + + El operador `?:` a menudo se llama 'operador Elvis' porque parece una cara de Elvis Presley de lado, con el carácter `?` simbolizando la onda en su cabello. + +#### 1.3.2. Configurar `ext.args` en el archivo `modules.config` + +Ahora que hemos sacado la declaración de `character` del módulo, tenemos que agregarla a `ext.args` en el archivo de configuración `modules.config`. + +Específicamente, vamos a agregar este pequeño fragmento de código al bloque `process {}`: + +```groovy title="Código a agregar" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +La sintaxis `withName:` asigna esta configuración solo al proceso `COWPY`, y `ext.args = { "-c ${params.character}" }` simplemente compone una cadena que incluirá el valor del parámetro `character`. +Tenga en cuenta el uso de llaves, que le dicen a Nextflow que evalúe el valor del parámetro en tiempo de ejecución. + +¿Tiene sentido? Agreguémoslo. + +Abra `conf/modules.config` y agregue el código de configuración dentro del bloque `process {}` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Esperamos que pueda imaginar tener todos los módulos en un pipeline con sus `ext.args` especificados en este archivo, con los siguientes beneficios: + +- La **interfaz del módulo se mantiene simple** - Solo acepta las entradas esenciales de metadatos y archivos +- El **pipeline todavía expone `params.character`** - Los usuarios finales aún pueden configurarlo como antes +- El **módulo ahora es portable** - Puede reutilizarse en otros pipelines sin esperar un nombre de parámetro específico +- La configuración está **centralizada** en `modules.config`, manteniendo limpia la lógica del flujo de trabajo + +Al usar el archivo `modules.config` como el lugar donde todos los pipelines centralizan la configuración por módulo, hacemos que nuestros módulos sean más reutilizables en diferentes pipelines. + +#### 1.3.3. Actualizar el flujo de trabajo `hello.nf` + +Dado que el módulo `COWPY` ya no requiere el parámetro `character` como entrada, necesitamos actualizar la llamada del flujo de trabajo en consecuencia. + +Abra el archivo de flujo de trabajo `hello.nf` (en `core-hello/workflows/`) y actualice la llamada a `COWPY` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // generar arte ASCII de los saludos con cowpy + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // generar arte ASCII de los saludos con cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +El código del flujo de trabajo ahora es más limpio: no necesitamos pasar `params.character` directamente al proceso. +La interfaz del módulo se mantiene mínima, haciéndola más portable, mientras que el pipeline todavía proporciona la opción explícita a través de la configuración. + +#### 1.3.4. Ejecutar el pipeline para probarlo + +Probemos que el flujo de trabajo todavía funciona como se espera, especificando un personaje diferente para verificar que la configuración de `ext.args` está funcionando. + +Ejecute este comando usando `kosh`, una de las opciones más... enigmáticas: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Esto debería ejecutarse exitosamente como anteriormente. + +Verifiquemos que la configuración de `ext.args` funcionó verificando la salida. +Encuentre la salida en el navegador de archivos o use el hash de la tarea (la parte `38/eb29ea` en el ejemplo anterior) para ver el archivo de salida: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Salida del comando" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +¡Debería ver el arte ASCII mostrado con el personaje `kosh`, confirmando que la configuración de `ext.args` funcionó! + +??? info "(Opcional) Inspeccionar el archivo de comando" + + Si desea ver exactamente cómo se aplicó la configuración, puede inspeccionar el archivo `.command.sh`: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Verá el comando `cowpy` con el argumento `-c kosh`: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Esto muestra que el archivo `.command.sh` se generó correctamente basándose en la configuración de `ext.args`. + +Tómese un momento para pensar en lo que logramos aquí. +Este enfoque mantiene la interfaz del módulo enfocada en datos esenciales (archivos, metadatos y cualquier parámetro obligatorio por muestra), mientras que las opciones que controlan el comportamiento de la herramienta se manejan por separado a través de la configuración. + +Esto puede parecer innecesario para una herramienta simple como `cowpy`, pero puede marcar una gran diferencia para herramientas de análisis de datos que tienen muchos argumentos opcionales. + +Para resumir los beneficios de este enfoque: + +- **Interfaz limpia**: El módulo se centra en entradas de datos esenciales (metadatos y archivos) +- **Flexibilidad**: Los usuarios pueden especificar argumentos de herramientas a través de la configuración, incluyendo valores específicos por muestra +- **Consistencia**: Todos los módulos nf-core siguen este patrón +- **Portabilidad**: Los módulos pueden reutilizarse sin opciones de herramientas codificadas +- **Sin cambios en el flujo de trabajo**: Agregar o cambiar opciones de herramientas no requiere actualizar el código del flujo de trabajo + +!!! note + + El sistema `ext.args` tiene capacidades adicionales poderosas no cubiertas aquí, incluyendo el cambio de valores de argumentos dinámicamente basado en metadatos. Consulte las [especificaciones de módulos nf-core](https://nf-co.re/docs/guidelines/components/modules) para más detalles. + +### 1.4. Estandarizar el nombre de salida con `ext.prefix` + +Ahora que le hemos dado al proceso `COWPY` acceso al metamap, podemos comenzar a aprovechar otro patrón útil de nf-core: nombrar archivos de salida basándose en metadatos. + +Aquí vamos a usar una característica de Nextflow llamada `ext.prefix` que nos permitirá estandarizar el nombre de archivos de salida en todos los módulos usando `meta.id` (el identificador incluido en el metamap), mientras seguimos pudiendo configurar módulos individualmente si se desea. + +Esto será similar a lo que hicimos con `ext.args`, con algunas diferencias que detallaremos a medida que avancemos. + +Apliquemos este enfoque al módulo `COWPY`. +Vamos a necesitar hacer los siguientes cambios: + +1. Actualizar el módulo `COWPY` +2. Configurar `ext.prefix` en el archivo `modules.config` + +(No se necesitan cambios en el flujo de trabajo.) + +Una vez que hayamos hecho eso, ejecutaremos el pipeline para probar que todo sigue funcionando como antes. + +#### 1.4.1. Actualizar el módulo `COWPY` + +Abra el archivo del módulo `cowpy.nf` (en `core-hello/modules/local/`) y modifíquelo para referenciar `ext.prefix` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Puede ver que hicimos tres cambios. + +1. **En el bloque `script:`, agregamos la línea `prefix = task.ext.prefix ?: "${meta.id}"`.** + Esa línea usa el operador `?:` para determinar el valor de la variable `prefix`: el contenido de `task.ext.prefix` si no está vacío, o el identificador del metamap (`meta.id`) si lo está. + Tenga en cuenta que aunque generalmente nos referimos a `ext.prefix`, este código debe referenciar `task.ext.prefix` para extraer la configuración de `ext.prefix` a nivel de módulo. + +2. **En la línea de comandos, reemplazamos `cowpy-${input_file}` con `${prefix}.txt`.** + Aquí es donde Nextflow inyectará el valor de `prefix` determinado por la línea anterior. + +3. **En el bloque `output:`, reemplazamos `path("cowpy-${input_file}")` con `path("${prefix}.txt")`.** + Esto simplemente reitera cuál será la ruta del archivo según lo escrito en la línea de comandos. + +Como resultado, el nombre del archivo de salida ahora se construye usando un valor predeterminado sensato (el identificador del metamap) combinado con la extensión de formato de archivo apropiada. + +#### 1.4.2. Configurar `ext.prefix` en el archivo `modules.config` + +En este caso, el valor predeterminado sensato no es suficientemente expresivo para nuestro gusto; queremos usar un patrón de nomenclatura personalizado que incluya el nombre de la herramienta, `cowpy-<id>.txt`, como teníamos antes. + +Lo haremos configurando `ext.prefix` en `modules.config`, tal como lo hicimos para el parámetro `character` con `ext.args`, excepto que esta vez el bloque `withName: 'COWPY' {}` ya existe, y solo necesitamos agregar la siguiente línea: + +```groovy title="Código a agregar" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Esto compondrá la cadena que queremos. +Tenga en cuenta que una vez más usamos llaves, esta vez para decirle a Nextflow que evalúe el valor de `meta.id` en tiempo de ejecución. + +Agreguémoslo. + +Abra `conf/modules.config` y agregue el código de configuración dentro del bloque `process {}` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +En caso de que se esté preguntando, el closure `ext.prefix` tiene acceso a la pieza correcta de metadatos porque la configuración se evalúa en el contexto de la ejecución del proceso, donde los metadatos están disponibles. + +#### 1.4.3. Ejecutar el pipeline para probarlo + +Probemos que el flujo de trabajo todavía funciona como se espera. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Eche un vistazo a la salida en el directorio de resultados. +Debería ver el archivo de salida de cowpy con el mismo nombre que antes: `cowpy-test.txt`, basado en el nombre de lote predeterminado. + +??? abstract "Contenido del directorio" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Siéntase libre de cambiar la configuración de `ext.prefix` en `conf/modules.config` para satisfacerse de que puede cambiar el patrón de nomenclatura sin tener que hacer ningún cambio en el código del módulo o del flujo de trabajo. + +Alternativamente, también puede intentar ejecutar esto nuevamente con un parámetro `--batch` diferente especificado en la línea de comandos para satisfacerse de que esa parte todavía es personalizable sobre la marcha. + +Esto demuestra cómo `ext.prefix` le permite mantener su convención de nomenclatura preferida mientras mantiene flexible la interfaz del módulo. + +Para resumir los beneficios de este enfoque: + +- **Nomenclatura estandarizada**: Los archivos de salida se nombran típicamente usando IDs de muestra de metadatos +- **Configurable**: Los usuarios pueden sobrescribir la nomenclatura predeterminada si es necesario +- **Consistente**: Todos los módulos nf-core siguen este patrón +- **Predecible**: Es fácil saber cómo se llamarán los archivos de salida + +¿Bastante bien, verdad? +Bueno, hay un cambio más importante que necesitamos hacer para mejorar nuestro módulo para que se ajuste a las directrices de nf-core. + +### 1.5. Centralizar la configuración de publicación + +Puede haber notado que hemos estado publicando salidas en dos directorios diferentes: + +- **`results`** — El directorio de salida original que hemos estado usando desde el principio para nuestros módulos locales, establecido individualmente usando directivas `publishDir` por módulo; +- **`core-hello-results`** — El directorio de salida establecido con `--outdir` en la línea de comandos, que ha estado recibiendo los registros de nf-core y los resultados publicados por `CAT_CAT`. + +Esto es desordenado y subóptimo; sería mejor tener una ubicación para todo. +Por supuesto, podríamos ir a cada uno de nuestros módulos locales y actualizar la directiva `publishDir` manualmente para usar el directorio `core-hello-results`, pero ¿qué pasa la próxima vez que decidamos cambiar el directorio de salida? + +Tener módulos individuales tomando decisiones de publicación claramente no es el camino a seguir, especialmente en un mundo donde el mismo módulo podría usarse en muchos pipelines diferentes, por personas que tienen diferentes necesidades o preferencias. +Queremos poder controlar dónde se publican las salidas al nivel de la configuración del flujo de trabajo. + +"Oye", podría decir, "`CAT_CAT` está enviando sus salidas a `--outdir`. ¿Quizás deberíamos copiar su directiva `publishDir`?" + +Sí, esa es una gran idea. + +Excepto que no tiene una directiva `publishDir`. (Adelante, mire el código del módulo.) + +Eso es porque los pipelines nf-core centralizan el control al nivel del flujo de trabajo configurando `publishDir` en `conf/modules.config` en lugar de en módulos individuales. +Específicamente, la plantilla nf-core declara una directiva `publishDir` predeterminada (con una estructura de directorio predefinida) que se aplica a todos los módulos a menos que se proporcione una directiva de sobrescritura. + +¿No suena increíble? ¿Podría ser que para aprovechar esta directiva predeterminada, todo lo que necesitamos hacer es eliminar la directiva `publishDir` actual de nuestros módulos locales? + +Probemos eso en `COWPY` para ver qué sucede, luego veremos el código para la configuración predeterminada para entender cómo funciona. + +Finalmente, demostraremos cómo sobrescribir el comportamiento predeterminado si se desea. + +#### 1.5.1. Eliminar la directiva `publishDir` de `COWPY` + +Hagamos esto. +Abra el archivo del módulo `cowpy.nf` (en `core-hello/modules/local/`) y elimine la directiva `publishDir` como se muestra a continuación. + +=== "Después" + + ```groovy title="core-hello/modules/local/cowpy.nf (extracto)" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf (extracto)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +¡Eso es todo! + +#### 1.5.2. Ejecutar el pipeline para probarlo + +Echemos un vistazo a lo que sucede si ejecutamos el pipeline ahora. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Eche un vistazo a su directorio de trabajo actual. +Ahora el `core-hello-results` también contiene las salidas del módulo `COWPY`. + +??? abstract "Contenido del directorio" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Puede ver que Nextflow creó esta jerarquía de directorios basada en los nombres del flujo de trabajo y del módulo. + +El código responsable vive en el archivo `conf/modules.config`. +Esta es la configuración `publishDir` predeterminada que forma parte de la plantilla nf-core y se aplica a todos los procesos: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Esto puede parecer complicado, así que veamos cada uno de los tres componentes: + +- **`path:`** Determina el directorio de salida basado en el nombre del proceso. + El nombre completo de un proceso contenido en `task.process` incluye la jerarquía de importaciones de flujo de trabajo y módulo (como `CORE_HELLO:HELLO:CAT_CAT`). + Las operaciones `tokenize` eliminan esa jerarquía para obtener solo el nombre del proceso, luego toman la primera parte antes de cualquier guion bajo (si corresponde), y la convierten a minúsculas. + Esto es lo que determina que los resultados de `CAT_CAT` se publiquen en `${params.outdir}/cat/`. +- **`mode:`** Controla cómo se publican los archivos (copia, enlace simbólico, etc.). + Esto es configurable a través del parámetro `params.publish_dir_mode`. +- **`saveAs:`** Filtra qué archivos publicar. + Este ejemplo excluye archivos `versions.yml` devolviendo `null` para ellos, evitando que se publiquen. + +Esto proporciona una lógica consistente para organizar salidas. + +La salida se ve aún mejor cuando todos los módulos en un pipeline adoptan esta convención, así que siéntase libre de ir a eliminar las directivas `publishDir` de los otros módulos en su pipeline. +Este valor predeterminado se aplicará incluso a módulos que no modificamos explícitamente para seguir las directrices de nf-core. + +Dicho esto, puede decidir que desea organizar sus entradas de manera diferente, y la buena noticia es que es fácil hacerlo. + +#### 1.5.3. Sobrescribir el valor predeterminado + +Para sobrescribir la directiva `publishDir` predeterminada, simplemente puede agregar sus propias directivas al archivo `conf/modules.config`. + +Por ejemplo, podría sobrescribir el valor predeterminado para un solo proceso usando el selector `withName:`, como en este ejemplo donde agregamos una directiva `publishDir` personalizada para el proceso 'COWPY'. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +En realidad no vamos a hacer ese cambio, pero siéntase libre de jugar con esto y ver qué lógica puede implementar. + +El punto es que este sistema permite le da lo mejor de ambos mundos: consistencia por defecto y la flexibilidad para personalizar la configuración bajo demanda. + +Para resumir, obtiene: + +- **Fuente única de verdad**: Toda la configuración de publicación vive en `modules.config` +- **Valor predeterminado útil**: Los procesos funcionan de inmediato sin configuración por módulo +- **Personalización fácil**: Sobrescriba el comportamiento de publicación en configuración, no en código de módulo +- **Módulos portables**: Los módulos no codifican ubicaciones de salida + +Esto completa el conjunto de características de módulos nf-core que absolutamente debe aprender a usar, pero hay otras que puede leer en las [especificaciones de módulos nf-core](https://nf-co.re/docs/guidelines/components/modules). + +### Conclusión + +Ahora sabe cómo adaptar módulos locales para seguir las convenciones de nf-core: + +- Diseñe sus módulos para aceptar y propagar tuplas de metadatos; +- Use `ext.args` para mantener las interfaces de módulos mínimas y portables; +- Use `ext.prefix` para nombres de archivos de salida configurables y estandarizados; +- Adopte la directiva `publishDir` centralizada predeterminada para una estructura de directorio de resultados consistente. + +### ¿Qué sigue? + +Aprenda a usar las herramientas integradas basadas en plantillas de nf-core para crear módulos de la manera fácil. + +--- + +## 2. Crear un módulo con las herramientas nf-core + +Ahora que ha aprendido los patrones de módulos nf-core aplicándolos manualmente, veamos cómo crearía módulos en la práctica. + +### 2.1. Generar un esqueleto de módulo desde una plantilla + +Similar a lo que existe para crear pipelines, el proyecto nf-core proporciona herramientas para generar módulos estructurados correctamente basados en una plantilla, con todos estos patrones incorporados desde el principio. + +#### 2.1.1. Ejecutar el comando de creación de módulo + +El comando `nf-core modules create` genera una plantilla de módulo que ya sigue todas las convenciones que ha aprendido. + +Creemos una nueva versión del módulo `COWPY` con una plantilla mínima ejecutando este comando: + +```bash +nf-core modules create --empty-template COWPY +``` + +La bandera `--empty-template` crea una plantilla inicial limpia sin código extra, facilitando ver la estructura esencial. + +El comando se ejecuta de forma interactiva, guiándolo a través de la configuración. +Busca automáticamente información de herramientas de repositorios de paquetes como Bioconda y bio.tools para prepoblar metadatos. + +Se le solicitarán varias opciones de configuración: + +- **Información del autor**: Su nombre de usuario de GitHub para atribución +- **Etiqueta de recurso**: Un conjunto predefinido de requisitos computacionales. + El proyecto nf-core proporciona etiquetas estándar como `process_single` para herramientas ligeras y `process_high` para las exigentes. + Estas etiquetas ayudan a gestionar la asignación de recursos en diferentes entornos de ejecución. +- **Requisito de metadatos**: Si el módulo necesita información específica de muestra a través de un mapa `meta` (generalmente sí para módulos de procesamiento de datos). + +La herramienta maneja la complejidad de encontrar información de paquetes y configurar la estructura, permitiéndole concentrarse en implementar la lógica específica de la herramienta. + +#### 2.1.2. Examinar el esqueleto del módulo + +La herramienta crea una estructura de módulo completa en `modules/local/` (o `modules/nf-core/` si está en el repositorio nf-core/modules): + +??? abstract "Contenido del directorio" + + ```console + modules/local/cowpy + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + └── main.nf.test + ``` + +Cada archivo tiene un propósito específico: + +- **`main.nf`**: Definición de proceso con todos los patrones nf-core incorporados +- **`meta.yml`**: Documentación del módulo describiendo entradas, salidas y la herramienta +- **`environment.yml`**: Especificación de entorno Conda para dependencias +- **`tests/main.nf.test`**: Casos de prueba nf-test para validar que el módulo funciona + +!!! tip "Aprenda más sobre pruebas" + + El archivo de prueba generado usa nf-test, un framework de pruebas para pipelines y módulos de Nextflow. Para aprender cómo escribir y ejecutar estas pruebas, consulte la [misión secundaria nf-test](../side_quests/nf-test.md). + +El `main.nf` generado incluye todos los patrones que acaba de aprender, más algunas características adicionales: + +```groovy title="modules/local/cowpy/main.nf" hl_lines="11 21 22" +process COWPY { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/YOUR-TOOL-HERE': + 'biocontainers/ +``` diff --git a/docs/es/docs/hello_nf-core/05_input_validation.md b/docs/es/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..d7c7061326 --- /dev/null +++ b/docs/es/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Parte 5: Validación de entradas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta quinta parte del curso de entrenamiento Hello nf-core, le mostramos cómo usar el plugin nf-schema para validar las entradas y parámetros del pipeline. + +??? info "Cómo comenzar desde esta sección" + + Esta sección asume que ha completado la [Parte 4: Crear un módulo nf-core](./04_make_module.md) y ha actualizado el módulo de proceso `COWPY` a los estándares nf-core en su pipeline. + + Si no completó la Parte 4 o desea comenzar desde cero para esta parte, puede usar la solución `core-hello-part4` como punto de partida. + Ejecute estos comandos desde dentro del directorio `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Esto le proporciona un pipeline con el módulo `COWPY` ya actualizado para seguir los estándares nf-core. + Puede probar que se ejecuta correctamente ejecutando el siguiente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Calentamiento: Un poco de contexto + +### 0.1. Por qué es importante la validación + +Imagine ejecutar su pipeline durante dos horas, solo para que falle porque un usuario proporcionó un archivo con la extensión incorrecta. O pasar horas depurando errores crípticos, solo para descubrir que un parámetro estaba mal escrito. Sin validación de entradas, estos escenarios son comunes. + +Considere este ejemplo: + +```console title="Sin validación" +$ nextflow run my-pipeline --input data.txt --output results + +...2 horas después... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +El pipeline aceptó entradas inválidas y se ejecutó durante horas antes de fallar. Con validación adecuada: + +```console title="Con validación" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +El pipeline falla inmediatamente con mensajes de error claros y procesables. Esto ahorra tiempo, recursos computacionales y frustraciones. + +### 0.2. El plugin nf-schema + +El [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/) es un plugin de Nextflow que proporciona capacidades de validación completas para pipelines de Nextflow. +Aunque nf-schema funciona con cualquier workflow de Nextflow, es la solución de validación estándar para todos los pipelines nf-core. + +nf-schema proporciona varias funciones clave: + +- **Validación de parámetros**: Valida los parámetros del pipeline contra `nextflow_schema.json` +- **Validación de hojas de muestras**: Valida archivos de entrada contra `assets/schema_input.json` +- **Conversión de canales**: Convierte hojas de muestras validadas a canales de Nextflow +- **Generación de texto de ayuda**: Genera automáticamente la salida de `--help` a partir de las definiciones del schema +- **Resumen de parámetros**: Muestra qué parámetros difieren de los valores predeterminados + +nf-schema es el sucesor del plugin nf-validation obsoleto y utiliza el estándar [JSON Schema Draft 2020-12](https://json-schema.org/) para la validación. + +??? info "¿Qué son los plugins de Nextflow?" + + Los plugins son extensiones que agregan nueva funcionalidad al lenguaje Nextflow mismo. Se instalan mediante un bloque `plugins{}` en `nextflow.config` y pueden proporcionar: + + - Nuevas funciones y clases que se pueden importar (como `samplesheetToList`) + - Nuevas características DSL y operadores + - Integración con servicios externos + + El plugin nf-schema se especifica en `nextflow.config`: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Una vez instalado, puede importar funciones de plugins usando la sintaxis `include { functionName } from 'plugin/plugin-name'`. + +### 0.3. Dos archivos de schema para dos tipos de validación + +Un pipeline nf-core utilizará dos archivos de schema separados, que corresponden a dos tipos de validación: + +| Archivo de Schema | Propósito | Valida | +| -------------------------- | ------------------------------ | ------------------------------------------------------------ | +| `nextflow_schema.json` | Validación de parámetros | Flags de línea de comandos: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Validación de datos de entrada | Contenido de hojas de muestras y archivos de entrada | + +Ambos schemas usan el formato JSON Schema, un estándar ampliamente adoptado para describir y validar estructuras de datos. + +**La validación de parámetros** valida parámetros de línea de comandos (flags como `--outdir`, `--batch`, `--input`): + +- Verifica tipos de parámetros, rangos y formatos +- Asegura que se proporcionen los parámetros requeridos +- Valida que las rutas de archivos existan +- Definida en `nextflow_schema.json` + +**La validación de datos de entrada** valida la estructura de hojas de muestras y archivos de manifiesto (archivos CSV/TSV que describen sus datos): + +- Verifica la estructura de columnas y tipos de datos +- Valida que las rutas de archivos referenciadas en la hoja de muestras existan +- Asegura que los campos requeridos estén presentes +- Definida en `assets/schema_input.json` + +!!! warning "Lo que la validación de datos de entrada NO hace" + + La validación de datos de entrada verifica la estructura de *archivos de manifiesto* (hojas de muestras, archivos CSV), NO el contenido de sus archivos de datos reales (FASTQ, BAM, VCF, etc.). + + Para datos a gran escala, validar el contenido de los archivos (como verificar la integridad de BAM) debe ocurrir en los procesos del pipeline que se ejecutan en nodos de trabajo, no durante la etapa de validación en la máquina de orquestación. + +### 0.4. ¿Cuándo debe ocurrir la validación? + +```mermaid +graph LR + A[Usuario ejecuta pipeline] --> B[Validación de parámetros] + B -->|✓ Válido| C[Validación de datos de entrada] + B -->|✗ Inválido| D[Error: Corregir parámetros] + C -->|✓ Válido| E[Pipeline se ejecuta] + C -->|✗ Inválido| F[Error: Corregir datos de entrada] +``` + +La validación debe ocurrir **antes** de que se ejecuten los procesos del pipeline, para proporcionar retroalimentación rápida y prevenir el desperdicio de tiempo de cómputo. + +Ahora apliquemos estos principios en la práctica, comenzando con la validación de parámetros. + +--- + +## 1. Validación de parámetros (nextflow_schema.json) + +Comencemos agregando validación de parámetros a nuestro pipeline. Esto valida flags de línea de comandos como `--input`, `--outdir` y `--batch`. + +### 1.1. Configurar la validación para omitir la validación de archivos de entrada + +La plantilla de pipeline nf-core viene con nf-schema ya instalado y configurado: + +- El plugin nf-schema se instala mediante el bloque `plugins{}` en `nextflow.config` +- La validación de parámetros está habilitada por defecto mediante `params.validate_params = true` +- La validación se realiza mediante el subworkflow `UTILS_NFSCHEMA_PLUGIN` durante la inicialización del pipeline + +El comportamiento de validación se controla a través del alcance `validation{}` en `nextflow.config`. + +Dado que trabajaremos primero en la validación de parámetros (esta sección) y no configuraremos el schema de datos de entrada hasta la sección 2, necesitamos decirle temporalmente a nf-schema que omita la validación del contenido del archivo del parámetro `input`. + +Abra `nextflow.config` y encuentre el bloque `validation` (alrededor de la línea 246). Agregue `ignoreParams` para omitir la validación del archivo de entrada: + +=== "Después" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Esta configuración le dice a nf-schema que: + +- **`defaultIgnoreParams`**: Omita la validación de parámetros complejos como `genomes` (establecido por los desarrolladores de la plantilla) +- **`ignoreParams`**: Omita la validación del contenido del archivo del parámetro `input` (temporal; volveremos a habilitar esto en la sección 2) +- **`monochromeLogs`**: Deshabilite la salida coloreada en mensajes de validación cuando esté establecido en `true` (controlado por `params.monochrome_logs`) + +!!! note "¿Por qué ignorar el parámetro input?" + + El parámetro `input` en `nextflow_schema.json` tiene `"schema": "assets/schema_input.json"` que le dice a nf-schema que valide el *contenido* del archivo CSV de entrada contra ese schema. + Dado que aún no hemos configurado ese schema, omitimos temporalmente esta validación. + Eliminaremos esta configuración en la sección 2 después de configurar el schema de datos de entrada. + +### 1.2. Examinar el schema de parámetros + +Veamos una sección del archivo `nextflow_schema.json` que vino con nuestra plantilla de pipeline: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +El schema de parámetros está organizado en grupos. Aquí está el grupo `input_output_options`: + +```json title="core-hello/nextflow_schema.json (extracto)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Cada entrada descrita aquí tiene las siguientes propiedades clave que pueden ser validadas: + +- **`type`**: Tipo de datos (string, integer, boolean, number) +- **`format`**: Formatos especiales como `file-path` o `directory-path` +- **`exists`**: Para rutas de archivos, verificar si el archivo existe +- **`pattern`**: Expresión regular que el valor debe coincidir +- **`required`**: Array de nombres de parámetros que deben proporcionarse +- **`mimetype`**: Mimetype de archivo esperado para validación + +Si tiene buen ojo, podría notar que el parámetro de entrada `batch` que hemos estado usando aún no está definido en el schema. +Lo agregaremos en la siguiente sección. + +??? info "¿De dónde vienen los parámetros del schema?" + + La validación del schema usa `nextflow.config` como base para las definiciones de parámetros. + Los parámetros declarados en otros lugares de sus scripts de workflow (como en `main.nf` o archivos de módulos) **no** son automáticamente detectados por el validador de schema. + + Esto significa que siempre debe declarar sus parámetros de pipeline en `nextflow.config`, y luego definir sus reglas de validación en `nextflow_schema.json`. + +### 1.3. Agregar el parámetro batch + +Aunque el schema es un archivo JSON que puede editarse manualmente, **la edición manual es propensa a errores y no se recomienda**. +En su lugar, nf-core proporciona una herramienta GUI interactiva que maneja la sintaxis JSON Schema por usted y valida sus cambios: + +```bash +nf-core pipelines schema build +``` + +Debería ver algo como esto: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Escriba `y` y presione Enter para lanzar la interfaz web interactiva. + +Su navegador se abrirá mostrando el constructor de schema de parámetros: + +![Interfaz del constructor de schema](./img/schema_build.png) + +Para agregar el parámetro `batch`: + +1. Haga clic en el botón **"Add parameter"** en la parte superior +2. Use el controlador de arrastre (⋮⋮) para mover el nuevo parámetro hacia arriba en el grupo "Input/output options", debajo del parámetro `input` +3. Complete los detalles del parámetro: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: marque la casilla + - Opcionalmente, seleccione un icono del selector de iconos (por ejemplo, `fas fa-layer-group`) + +![Agregando el parámetro batch](./img/schema_add.png) + +Cuando termine, haga clic en el botón **"Finished"** en la parte superior derecha. + +De vuelta en su terminal, verá: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Presione `Ctrl+C` para salir del constructor de schema. + +La herramienta ahora ha actualizado su archivo `nextflow_schema.json` con el nuevo parámetro `batch`, manejando toda la sintaxis JSON Schema correctamente. + +### 1.4. Verificar los cambios + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (extracto)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Debería ver que el parámetro `batch` se ha agregado al schema con el campo "required" ahora mostrando `["input", "outdir", "batch"]`. + +### 1.5. Probar la validación de parámetros + +Ahora probemos que la validación de parámetros funciona correctamente. + +Primero, intente ejecutar sin el parámetro `input` requerido: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Salida del comando" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +¡Perfecto! La validación detecta el parámetro requerido faltante antes de que se ejecute el pipeline. + +Ahora intente con un conjunto válido de parámetros: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +El pipeline debería ejecutarse correctamente, y el parámetro `batch` ahora está validado. + +### Conclusión + +Ha aprendido cómo usar la herramienta interactiva `nf-core pipelines schema build` para agregar parámetros a `nextflow_schema.json` y ha visto la validación de parámetros en acción. +La interfaz web maneja toda la sintaxis JSON Schema por usted, facilitando la gestión de schemas de parámetros complejos sin edición manual de JSON propensa a errores. + +### ¿Qué sigue? + +Ahora que la validación de parámetros está funcionando, agreguemos validación para el contenido del archivo de datos de entrada. + +--- + +## 2. Validación de datos de entrada (schema_input.json) + +Vamos a agregar validación para el contenido de nuestro archivo CSV de entrada. +Mientras que la validación de parámetros verifica los flags de línea de comandos, la validación de datos de entrada asegura que los datos dentro del archivo CSV estén estructurados correctamente. + +### 2.1. Entender el formato de greetings.csv + +Recordemos cómo se ve nuestra entrada: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Este es un CSV simple con: + +- Tres columnas (sin encabezado) +- En cada línea: un saludo, un idioma y una puntuación +- Las dos primeras columnas son strings de texto sin requisitos de formato especial +- La tercera columna es un entero + +Para nuestro pipeline, solo se requiere la primera columna. + +### 2.2. Diseñar la estructura del schema + +Para nuestro caso de uso, queremos: + +1. Aceptar entrada CSV con al menos una columna +2. Tratar el primer elemento de cada fila como un string de saludo +3. Asegurar que los saludos no estén vacíos y no comiencen con espacios en blanco +4. Asegurar que el campo de idioma coincida con uno de los códigos de idioma compatibles (en, fr, es, it, de) +5. Asegurar que el campo de puntuación sea un entero con un valor entre 0 y 100 + +Estructuraremos esto como un array de objetos, donde cada objeto tiene al menos un campo `greeting`. + +### 2.3. Actualizar el archivo de schema + +La plantilla de pipeline nf-core incluye un `assets/schema_input.json` predeterminado diseñado para datos de secuenciación de extremos emparejados. +Necesitamos reemplazarlo con un schema más simple para nuestro caso de uso de saludos. + +Abra `assets/schema_input.json` y reemplace las secciones `properties` y `required`: + +=== "Después" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Antes" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Los cambios clave: + +- **`description`**: Actualizado para mencionar "greetings file" +- **`properties`**: Reemplazado `sample`, `fastq_1` y `fastq_2` con `greeting`, `language` y `score` + - **`type:`** Aplicar string (`greeting`, `language`) o entero (`score`) + - **`pattern: "^\\S.*$"`**: El saludo debe comenzar con un carácter que no sea espacio en blanco (pero puede contener espacios después de eso) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: El código de idioma debe estar en el conjunto compatible + - **`"minimum": 0` y `"maximum": 100`**: El valor de puntuación debe estar entre 0 y 100 + - **`errorMessage`**: Mensaje de error personalizado mostrado si falla la validación +- **`required`**: Cambiado de `["sample", "fastq_1"]` a `["greeting"]` + +### 2.4. Agregar un encabezado al archivo greetings.csv + +Cuando nf-schema lee un archivo CSV, espera que la primera fila contenga encabezados de columna que coincidan con los nombres de campo en el schema. + +Para nuestro caso simple, necesitamos agregar una línea de encabezado a nuestro archivo de saludos: + +=== "Después" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Antes" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Ahora el archivo CSV tiene una línea de encabezado que coincide con los nombres de campo en nuestro schema. + +El paso final es implementar la validación en el código del pipeline usando `samplesheetToList`. + +### 2.5. Implementar validación en el pipeline + +Ahora necesitamos reemplazar nuestro análisis simple de CSV con la función `samplesheetToList` de nf-schema, que validará y analizará la hoja de muestras. + +La función `samplesheetToList`: + +1. Lee la hoja de muestras de entrada (CSV, TSV, JSON o YAML) +2. La valida contra el schema JSON proporcionado +3. Devuelve una lista de Groovy donde cada entrada corresponde a una fila +4. Lanza mensajes de error útiles si la validación falla + +Actualicemos el código de manejo de entrada: + +Abra `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` y localice la sección donde creamos el canal de entrada (alrededor de la línea 80). + +Necesitamos: + +1. Usar la función `samplesheetToList` (ya importada en la plantilla) +2. Validar y analizar la entrada +3. Extraer solo los strings de saludo para nuestro workflow + +Primero, note que la función `samplesheetToList` ya está importada en la parte superior del archivo (la plantilla nf-core incluye esto por defecto): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subworkflow con funcionalidad específica del pipeline core/hello +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Ahora actualice el código de creación del canal: + +=== "Después" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Desglosemos lo que cambió: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Valida el archivo de entrada contra nuestro schema y devuelve una lista +2. **`Channel.fromList(...)`**: Convierte la lista en un canal de Nextflow + +Esto completa la implementación de validación de datos de entrada usando `samplesheetToList` y schemas JSON. + +Ahora que hemos configurado el schema de datos de entrada, podemos eliminar la configuración de ignorar temporal que agregamos anteriormente. + +### 2.6. Rehabilitar la validación de entrada + +Abra `nextflow.config` y elimine la línea `ignoreParams` del bloque `validation`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Ahora nf-schema validará tanto los tipos de parámetros COMO el contenido del archivo de entrada. + +### 2.7. Probar la validación de entrada + +Verifiquemos que nuestra validación funciona probando tanto entradas válidas como inválidas. + +#### 2.7.1. Probar con entrada válida + +Primero, confirme que el pipeline se ejecuta correctamente con entrada válida. +¡Note que ya no necesitamos `--validate_params false` ya que la validación está funcionando! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Salida del comando" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +¡Excelente! El pipeline se ejecuta correctamente y la validación pasa en silencio. +La advertencia sobre `--character` es solo informativa ya que no está definido en el schema. +Si lo desea, use lo que ha aprendido para agregar validación para ese parámetro también. + +#### 2.7.2. Probar con entrada inválida + +Pasar la validación siempre es una buena sensación, pero asegurémonos de que la validación realmente detectará errores. + +Para crear un archivo de prueba con un nombre de columna inválido, comience haciendo una copia del archivo `greetings.csv`: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Ahora abra el archivo y cambie el nombre de la primera columna, en la línea de encabezado, de `greeting` a `message`: + +=== "Después" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Antes" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Esto no coincide con nuestro schema, por lo que la validación debería lanzar un error. + +Intente ejecutar el pipeline con esta entrada inválida: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +¡Perfecto! La validación detectó el error y proporcionó un mensaje de error claro y útil que señala: + +- Qué archivo falló la validación +- Qué entrada (fila 1, la primera fila de datos) tiene el problema +- Cuál es el problema específico (falta el campo requerido `greeting`) + +La validación del schema asegura que los archivos de entrada tengan la estructura correcta antes de que se ejecute el pipeline, ahorrando tiempo y previniendo errores confusos más adelante en la ejecución. + +Si desea practicar esto, siéntase libre de crear otros archivos de entrada de saludos que violen el schema de otras maneras divertidas. + +### Conclusión + +Ha implementado y probado tanto la validación de parámetros como la validación de datos de entrada. Su pipeline ahora valida las entradas antes de la ejecución, proporcionando retroalimentación rápida y mensajes de error claros. + +!!! tip "Lectura adicional" + + Para aprender más sobre características y patrones de validación avanzados, consulte la [documentación de nf-schema](https://nextflow-io.github.io/nf-schema/latest/). El comando `nf-core pipelines schema build` proporciona una GUI interactiva para gestionar schemas complejos. + +### ¿Qué sigue? + +¡Ha completado las cinco partes del curso de entrenamiento Hello nf-core! + +Continúe al [Resumen](summary.md) para reflexionar sobre lo que ha construido y aprendido. diff --git a/docs/es/docs/hello_nf-core/index.md b/docs/es/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..87c41e52d5 --- /dev/null +++ b/docs/es/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Recuperar, ejecutar y gestionar la ejecución de pipelines de nf-core + - Describir la estructura del código y la organización del proyecto de pipelines de nf-core + - Crear un pipeline básico compatible con nf-core desde una plantilla + - Actualizar un workflow de Nextflow básico para cumplir con los estándares de nf-core + - Añadir módulos de nf-core a un pipeline compatible con nf-core + - Contribuir con sus propios módulos a nf-core + - Validar entradas y parámetros utilizando las herramientas de nf-core + audience_prerequisites: + - "**Audiencia:** Este curso está diseñado para estudiantes que ya están familiarizados con Nextflow básico y desean aprender a usar recursos y mejores prácticas de nf-core." + - "**Habilidades:** Se asume familiaridad con la línea de comandos, conceptos básicos de scripting y formatos de archivo comunes." + - "**Cursos:** Debe haber completado el curso [Hello Nextflow](../hello_nextflow/index.md) o equivalente." + - "**Dominio:** Los ejercicios son todos agnósticos al dominio, por lo que no se requiere conocimiento científico previo." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core es una introducción práctica al uso de recursos y mejores prácticas de nf-core.** + +![nf-core logo](./img/nf-core-logo.png) + +Trabajando a través de ejemplos prácticos y ejercicios guiados, aprenderá a usar y desarrollar módulos y pipelines compatibles con nf-core, y a utilizar las herramientas de nf-core de manera efectiva. + +Obtendrá las habilidades y la confianza para comenzar a desarrollar pipelines de acuerdo con las mejores prácticas de nf-core. + +<!-- additional_information --> + +## Descripción general del curso + +Este curso está diseñado para ser práctico, con ejercicios orientados a objetivos estructurados para introducir información gradualmente. + +Se le presentará [**nf-core**](https://nf-co.re/), un esfuerzo comunitario para desarrollar y mantener un conjunto curado de pipelines científicos construidos usando Nextflow, así como herramientas y directrices relevantes que promueven el desarrollo abierto, las pruebas y la revisión por pares ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +Los pipelines desarrollados por la comunidad nf-core están diseñados para ser modulares, escalables y portables, permitiendo a los investigadores adaptarlos y ejecutarlos fácilmente usando sus propios datos y recursos de cómputo. +Las directrices de mejores prácticas aplicadas por el proyecto aseguran además que los pipelines sean robustos, estén bien documentados y validados contra conjuntos de datos del mundo real. +Esto ayuda a aumentar la confiabilidad y reproducibilidad de los análisis científicos y, en última instancia, permite a los investigadores acelerar sus descubrimientos científicos. + +No cubriremos todo lo que hay que saber sobre pipelines de nf-core en este curso, porque nf-core abarca muchas características y convenciones desarrolladas por la comunidad a lo largo de años. +En su lugar, nos centraremos en los conceptos esenciales que le ayudarán a comenzar y entender cómo funciona nf-core. + +### Plan de lecciones + +Hemos dividido esto en cinco partes que se enfocarán cada una en aspectos específicos del uso de recursos de nf-core. + +| Capítulo del curso | Resumen | Duración estimada | +| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| [Parte 1: Ejecutar un pipeline de demostración](./01_run_demo.md) | Ejecutar un pipeline existente de nf-core y examinar su estructura de código para tener una idea de lo que hace diferentes a estos pipelines de los workflows básicos de Nextflow | 30 mins | +| [Parte 2: Reescribir Hello para nf-core](./02_rewrite_hello.md) | Adaptar un workflow existente a la estructura de plantilla de nf-core, comenzando desde el workflow simple producido en el curso [Hello Nextflow](../hello_nextflow/index.md) | 60 mins | +| [Parte 3: Usar un módulo de nf-core](./03_use_module.md) | Explorar la biblioteca de módulos de la comunidad y aprender a integrar módulos preconstruidos y probados que envuelven herramientas bioinformáticas comunes | 30 mins | +| [Parte 4: Crear un módulo de nf-core](./04_make_module.md) | Crear su propio módulo al estilo nf-core usando la estructura específica, convenciones de nomenclatura y requisitos de metadatos establecidos por nf-core | 30 mins | +| [Parte 5: Añadir validación de entrada](./05_input_validation.md) | Implementar validación de entrada tanto para parámetros de línea de comandos como para archivos de datos de entrada usando nf-schema | 30 mins | + +Al final de este curso, podrá aprovechar la enorme riqueza de recursos ofrecidos por el proyecto nf-core. + +¿Listo para tomar el curso? + +[Comenzar a aprender :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/es/docs/hello_nf-core/next_steps.md b/docs/es/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..4a137c959f --- /dev/null +++ b/docs/es/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Resumen del curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicitaciones por completar el curso de entrenamiento Hello nf-core! 🎉 + +<!-- placeholder for video --> + +## Tu recorrido + +Comenzaste aprendiendo a recuperar y ejecutar un pipeline de demostración, luego abordaste la conversión de un workflow simple de Nextflow en un pipeline de nf-core. +Aprendiste cómo crear una estructura de pipeline usando una plantilla e injertaste el pipeline existente en esa estructura. +Luego refinaste gradualmente el pipeline reemplazando uno de los módulos locales con un módulo de nf-core, transformaste otro de los módulos locales para ajustarse a los estándares de nf-core y agregaste validación de entrada. + +### Lo que construiste + +Tu pipeline final `core-hello` ahora tiene: + +- **Estructura estandarizada** usando la plantilla de nf-core con directorios organizados para workflows, subworkflows, módulos y configuración +- **Módulos de la comunidad** del repositorio de nf-core (`cat/cat`) junto con tus módulos personalizados +- **Validación integral** que verifica tanto los parámetros como los datos de entrada antes de que el pipeline se ejecute +- **Configuración profesional** con perfiles para diferentes entornos de ejecución +- **Documentación completa** y metadatos siguiendo las convenciones de nf-core + +### Habilidades clave adquiridas + +A través de este curso práctico, has aprendido a: + +1. **Navegar y comprender** la estructura de pipelines de nf-core explorando un pipeline existente +2. **Reestructurar workflows** para que sean componibles y se ajusten dentro de la plantilla de nf-core +3. **Encontrar e integrar** módulos preconstruidos del repositorio de la comunidad +4. **Crear módulos personalizados** siguiendo los estándares de nf-core para nomenclatura, estructura y metadatos +5. **Implementar validación** usando nf-schema para detectar errores temprano con retroalimentación clara + +Ahora estás equipado con el conocimiento fundamental para construir pipelines de nf-core listos para producción que siguen las mejores prácticas de la comunidad. + +## Próximos pasos para desarrollar tus habilidades + +Aquí están nuestras 3 principales sugerencias para lo que puedes hacer a continuación: + +- Aplica Nextflow a un caso de uso de análisis científico con [Nextflow para Ciencia](../nf4_science/index.md) +- Explora características más avanzadas de Nextflow con las [Misiones Secundarias](../side_quests/index.md) +- Involúcrate [uniéndote a la comunidad de nf-core](https://nf-co.re/join). + +Finalmente, te recomendamos que eches un vistazo a [**Seqera Platform**](https://seqera.io/), una plataforma basada en la nube desarrollada por los creadores de Nextflow que hace aún más fácil lanzar y gestionar tus workflows, así como administrar tus datos y ejecutar análisis de forma interactiva en cualquier entorno. + +## Encuesta de retroalimentación + +Antes de continuar, ¡por favor tómate un minuto para completar la encuesta del curso! Tu retroalimentación nos ayuda a mejorar nuestros materiales de entrenamiento para todos. + +[Realizar la encuesta :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/es/docs/hello_nf-core/survey.md b/docs/es/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..3e1c26e9cf --- /dev/null +++ b/docs/es/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Encuesta de retroalimentación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, por favor complete esta breve encuesta de 5 preguntas para calificar el entrenamiento, compartir cualquier comentario que pueda tener sobre su experiencia y hacernos saber qué más podríamos hacer para ayudarle en su trayectoria con Nextflow. + +Esto le tomará menos de un minuto completar. ¡Gracias por ayudarnos a mejorar nuestros materiales de entrenamiento para todos! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/es/docs/help.md b/docs/es/docs/help.md new file mode 100644 index 0000000000..62200973c1 --- /dev/null +++ b/docs/es/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Obtener ayuda +description: Recursos útiles cuando tiene un problema con el entrenamiento de Nextflow +hide: + - toc + - footer +--- + +# Obtener ayuda + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ya sea que tenga dificultades para comenzar, se quede atascado a mitad de camino o tenga preguntas de seguimiento, ¡no dude en comunicarse! Nuestro equipo de la comunidad está aquí para ayudar, y la comunidad de Nextflow en general es muy activa, inclusiva y dispuesta a ayudar. + +Aquí están las principales opciones disponibles según lo que esté buscando. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Foro de la comunidad__ + + --- + + Nuestro foro de la comunidad tiene una categoría dedicada al entrenamiento, que es un excelente lugar para publicar preguntas o reportar cualquier problema que pueda estar teniendo con el entrenamiento. ¡Incluso puede encontrar que su pregunta ya ha sido formulada y respondida! + + [Unirse al foro de entrenamiento:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Canal de Slack__ + + --- + + Si usa Slack, puede comunicarse con nosotros en el canal de entrenamiento en el espacio de trabajo de Slack de Nextflow. El Slack de Nextflow es un excelente lugar para chatear con otros desarrolladores e interactuar con la comunidad de Nextflow en general. + + [Unirse al Slack de Nextflow :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Issues de Github__ + + --- + + Si encuentra un error en los materiales de entrenamiento, por favor repórtelo abriendo un issue en el repositorio de Github. Ya sea un error tipográfico, un problema de formato o un error real que afecta el código, ¡háganos saber para que podamos solucionarlo! También damos la bienvenida a PRs directamente. + + [Reportar un issue:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Asistente de IA de Seqera__ + + --- + + Seqera AI es un asistente de IA entrenado con recursos de Nextflow y nf-core. Puede ayudarle a depurar su código, aclarar conceptos de Nextflow y buscar documentación más rápido. Piense en él como tener un tutor disponible 24/7 mientras trabaja en los cursos. + + [Preguntar a Seqera AI:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Documentación de Nextflow__ + + --- + + La documentación oficial es la guía definitiva para todas las características del lenguaje y opciones de configuración. Úsela junto con este entrenamiento para profundizar en temas específicos, explorar características avanzadas y encontrar referencias detalladas de sintaxis. + + [Explorar la documentación:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Soporte profesional__ + + --- + + Nextflow es un software gratuito y de código abierto desarrollado por [Seqera](https://seqera.io/), una empresa con sede en España con oficinas satélite en el Reino Unido y Estados Unidos. Ofrecemos servicios de soporte profesional para Nextflow, incluyendo entrenamiento personalizado. + + [Ponerse en contacto:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/es/docs/index.md b/docs/es/docs/index.md new file mode 100644 index 0000000000..83e3739b52 --- /dev/null +++ b/docs/es/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Inicio +description: ¡Bienvenido al portal de entrenamiento de la comunidad Nextflow! +hide: + - toc + - footer +--- + +# Entrenamiento de Nextflow + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Cursos de autoservicio__ + + --- + + **¡Bienvenido al portal de entrenamiento de la comunidad Nextflow!** + + Los cursos de entrenamiento listados a continuación están diseñados para ser utilizados como recurso de autoservicio. + Puede trabajar con ellos por su cuenta en cualquier momento, ya sea en el entorno web que proporcionamos a través de Github Codespaces o en su propio entorno. + + [Explorar los cursos :material-arrow-right:](#catalogo-de-cursos-de-entrenamiento-de-nextflow){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Información adicional__ + + --- + + ??? warning "Compatibilidad de versiones" + + <!-- Cualquier actualización de este contenido debe copiarse a la página de instalación local --> + **A partir de enero de 2026, todos nuestros cursos de entrenamiento de Nextflow requieren la versión 25.10.2 o posterior de Nextflow, con la sintaxis estricta activada, a menos que se indique lo contrario.** + + Para más información sobre los requisitos de versión y la sintaxis estricta, consulte la [guía de migración de la documentación de Nextflow](https://nextflow.io/docs/latest/strict-syntax.html). + + Las versiones anteriores del material de entrenamiento correspondientes a la sintaxis anterior están disponibles a través del selector de versiones en la barra de menú de esta página web. + + ??? terminal "Opciones de entorno" + + Proporcionamos un entorno de entrenamiento basado en web donde todo lo que necesita para realizar el entrenamiento está preinstalado, disponible a través de Github Codespaces (requiere una cuenta gratuita de GitHub). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Si esto no se adapta a sus necesidades, consulte las otras [Opciones de entorno](./envsetup/index.md). + + ??? learning "Eventos de entrenamiento" + + Si prefiere tomar el entrenamiento de Nextflow como parte de un evento estructurado, hay muchas oportunidades para hacerlo. Le recomendamos consultar las siguientes opciones: + + - **[Semanas de Entrenamiento]()** organizadas trimestralmente por el equipo de la Comunidad + - **[Eventos de Seqera](https://seqera.io/events/)** incluyen eventos de entrenamiento presencial organizados por Seqera (busque 'Seqera Sessions' y 'Nextflow Summit') + - **[Embajadores de Nextflow]()** organizan eventos para su comunidad local + - **[Eventos de nf-core](https://nf-co.re/events)** incluyen hackathons de la comunidad + + ??? people "Información para instructores" + + Si usted es un instructor que dirige sus propios entrenamientos, puede utilizar nuestros materiales directamente desde el portal de entrenamiento siempre que atribuya el crédito correspondiente. Consulte 'Créditos y contribuciones' a continuación para más detalles. + + Además, nos encantaría saber de usted cómo podríamos apoyar mejor sus esfuerzos de entrenamiento. Por favor contáctenos en [community@seqera.io](mailto:community@seqera.io) o en el foro de la comunidad (consulte la página de [Ayuda](help.md)). + + ??? licensing "Licencia de código abierto y política de contribuciones" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Este material de entrenamiento está desarrollado y mantenido por [Seqera](https://seqera.io) y publicado bajo una licencia de código abierto ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) para beneficio de la comunidad. Si desea utilizar este material de una manera que quede fuera del alcance de la licencia (tenga en cuenta las limitaciones sobre uso comercial y redistribución), por favor contáctenos en [community@seqera.io](mailto:community@seqera.io) para discutir su solicitud. + + Damos la bienvenida a mejoras, correcciones y reportes de errores de la comunidad. Cada página tiene un ícono :material-file-edit-outline: en la parte superior derecha de la página que enlaza al repositorio de código, donde puede reportar problemas o proponer cambios al material de entrenamiento fuente a través de un pull request. Consulte el `README.md` en el repositorio para más detalles. + +</div> + +!!! note "Traducción asistida por IA" + + Esta traducción fue creada utilizando inteligencia artificial y revisada por traductores humanos. + Agradecemos tus comentarios y sugerencias de mejora. + Consulta nuestra [guía de traducción](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) para más información. + +## Catálogo de cursos de entrenamiento de Nextflow + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Pista introductoria__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow para principiantes {.mt-1} + + Cursos independientes del dominio destinados a quienes son completamente nuevos en Nextflow. Cada curso consiste en una serie de módulos de entrenamiento diseñados para ayudar a los estudiantes a desarrollar sus habilidades progresivamente. + + ??? courses "**Hello Nextflow:** Aprenda a desarrollar sus propios pipelines" + + Este curso cubre los componentes principales del lenguaje Nextflow con suficiente detalle para permitir el desarrollo de pipelines simples pero completamente funcionales, además de elementos clave de diseño de pipelines, prácticas de desarrollo y configuración. + + [Comenzar el entrenamiento Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Aprenda a ejecutar pipelines existentes" + + Una introducción concisa a la ejecución y configuración de pipelines de Nextflow, basada en el curso de desarrolladores Hello Nextflow pero con menos enfoque en el código. Cubre la ejecución, salidas, estructura básica del código y configuración para diferentes entornos de cómputo. + + [Comenzar el entrenamiento Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow para Ciencia {.mt-1} + + Aprenda a aplicar los conceptos y componentes presentados en 'Hello Nextflow' a casos de uso científicos específicos. + + ??? courses "**Nextflow para Genómica** (llamado de variantes)" + + Para investigadores que desean aprender a desarrollar sus propios pipelines de genómica. El curso utiliza un caso de uso de llamado de variantes para demostrar cómo desarrollar un pipeline de genómica simple pero funcional. + + [Comenzar el entrenamiento Nextflow para Genómica :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow para RNAseq** (RNAseq bulk)" + + Para investigadores que desean aprender a desarrollar sus propios pipelines de RNAseq. El curso utiliza un caso de uso de procesamiento de RNAseq bulk para demostrar cómo desarrollar un pipeline de RNAseq simple pero funcional. + + [Comenzar el entrenamiento Nextflow para RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow para Imaging** (ómicas espaciales)" + + Para investigadores en imaging y ómicas espaciales que desean aprender a ejecutar y personalizar pipelines de análisis. El curso utiliza el pipeline nf-core/molkart para proporcionar un pipeline biológicamente relevante y demostrar cómo ejecutar, configurar y gestionar entradas para flujos de trabajo de Nextflow. + + [Comenzar el entrenamiento Nextflow para Imaging :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Pista avanzada__ + + --- + + ### :material-bridge:{.nextflow-primary} De Nextflow a nf-core {.mt-1} + + Aprenda a utilizar código y mejores prácticas del proyecto de comunidad [nf-core](https://nf-co.re/). + + Estos cursos le ayudan a pasar de los fundamentos de Nextflow a las mejores prácticas de nf-core. + Entienda cómo y por qué la comunidad nf-core construye pipelines, y cómo puede contribuir y reutilizar estas técnicas. + + ??? courses "**Hello nf-core:** Comience con nf-core" + + Para desarrolladores que desean aprender a ejecutar y desarrollar pipelines compatibles con [nf-core](https://nf-co.re/). El curso cubre la estructura de los pipelines nf-core con suficiente detalle para permitir el desarrollo de pipelines simples pero completamente funcionales que siguen la plantilla de nf-core y las mejores prácticas de desarrollo, así como el uso de módulos nf-core existentes. + + [Comenzar el entrenamiento Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Entrenamiento Avanzado de Nextflow {.mt-1} + + Aprenda conceptos y mecanismos avanzados para desarrollar e implementar pipelines de Nextflow para abordar casos de uso del mundo real. + + ??? courses "**Side Quests:** Profundizaciones en temas independientes" + + Mini-cursos independientes destinados a desarrolladores de Nextflow que desean ampliar su alcance y/o profundizar sus habilidades en temas particulares. Se presentan de forma lineal pero pueden tomarse en cualquier orden (consulte las dependencias en la descripción general de cada mini-curso). + + [Explorar los Side Quests :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Colecciones de Entrenamiento:** Rutas de aprendizaje recomendadas a través de los Side Quests" + + Las Colecciones de Entrenamiento combinan múltiples Side Quests para proporcionar una experiencia de aprendizaje integral en torno a un tema o caso de uso particular. + + [Explorar las Colecciones de Entrenamiento :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "¿Busca materiales de entrenamiento archivados?" + + Los materiales de entrenamiento más antiguos (Entrenamiento Fundamental, Entrenamiento Avanzado y otros cursos experimentales) han sido eliminados del portal de entrenamiento ya que son incompatibles con la sintaxis estricta de Nextflow 3.0. + Si necesita acceso a estos materiales, están disponibles en el [historial de git](https://github.com/nextflow-io/training) antes de enero de 2026. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/es/docs/info/conventions.md b/docs/es/docs/info/conventions.md new file mode 100644 index 0000000000..24602edf00 --- /dev/null +++ b/docs/es/docs/info/conventions.md @@ -0,0 +1 @@ +Se utiliza el prefijo `ch_` para todas las variables de canal para indicar claramente que son canales de Nextflow. diff --git a/docs/es/docs/info/hello_pipeline.md b/docs/es/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..aa8f87f929 --- /dev/null +++ b/docs/es/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: El pipeline Hello +description: Resumen de lo que hace el pipeline Hello y cómo está estructurado. +hide: + - toc + - footer +--- + +# El pipeline Hello + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +La mayoría de nuestros cursos de entrenamiento utilizan un pipeline simple e independiente del dominio para demostrar conceptos y mecanismos de Nextflow. +El curso Hello Nextflow muestra cómo desarrollar este pipeline paso a paso, explicando cada decisión de diseño e implementación. +Otros entrenamientos utilizan este pipeline, o partes de él, como punto de partida. + +Esta página resume el estado del pipeline tal como está al completar el curso Hello Nextflow. + +### Descripción resumida + +El workflow Hello toma un archivo CSV que contiene saludos, los escribe en archivos separados, convierte cada uno a mayúsculas, los recopila nuevamente y genera un único archivo de texto que contiene una imagen ASCII de un personaje divertido diciendo los saludos. + +### Pasos del workflow (procesos) + +Los cuatro pasos están implementados como processes de Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` y `cowpy`) almacenados en archivos de módulo separados. + +1. **`sayHello`:** Escribe cada saludo en su propio archivo de salida (por ejemplo, "Hello-output.txt") +2. **`convertToUpper`:** Convierte cada saludo a mayúsculas (por ejemplo, "HELLO") +3. **`collectGreetings`:** Recopila todos los saludos en mayúsculas en un único archivo de lote +4. **`cowpy`:** Genera arte ASCII usando la herramienta `cowpy` + +### Diagrama + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Resultados + +Los resultados se publican en un directorio llamado `results/`, y la salida final del pipeline (cuando se ejecuta con parámetros predeterminados) es un archivo de texto plano que contiene arte ASCII de un pavo diciendo los saludos en mayúsculas. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Puede encontrar algunas variaciones en los detalles específicos dependiendo del curso en el que se presenta el pipeline. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/es/docs/info/nxf_versions.md b/docs/es/docs/info/nxf_versions.md new file mode 100644 index 0000000000..26b2375cf2 --- /dev/null +++ b/docs/es/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Versiones de Nextflow +description: Comprensión y gestión de la evolución de las versiones de sintaxis de Nextflow +hide: + - toc + - footer +--- + +## Versión de sintaxis de Nextflow actualmente soportada y requisitos + +A partir de la versión 3.0 del portal de entrenamiento, todos nuestros cursos de entrenamiento se basan en la versión 25.10.2 de Nextflow, a menos que se especifique lo contrario en la página de índice del curso (excepto materiales obsoletos o archivados que pueden no incluir un aviso de versión). + +Debido a que los cursos ahora utilizan entradas tipadas a nivel de workflow así como directivas de salida a nivel de workflow, requieren el uso del parser de sintaxis V2. +Si planea utilizar el entorno que proporcionamos a través de [Github Codespaces](../envsetup/01_setup.md) o [devcontainers locales](../envsetup/03_devcontainer.md), no necesita hacer nada a menos que se indique específicamente en las instrucciones del curso. +Sin embargo, si planea trabajar en los entrenamientos en su propio entorno ([Instalación manual](../envsetup/02_local.md)), deberá asegurarse de usar Nextflow versión 25.10.2 o posterior con el parser de sintaxis v2 habilitado. + +## Versiones anteriores de los materiales de entrenamiento + +Nuestros materiales de entrenamiento han sido versionados desde febrero de 2025. + +Puede acceder a versiones anteriores de los materiales de entrenamiento que funcionan con versiones de Nextflow **anteriores a 25.10.2** a través del elemento del menú desplegable en la parte superior de cada página que muestra la versión numerada de los materiales de entrenamiento. +Cuando seleccione una versión anterior de los materiales de entrenamiento, los enlaces al entorno de entrenamiento especificarán automáticamente la versión correspondiente del entorno. + +## Otra información sobre las versiones de sintaxis de Nextflow + +Nextflow tiene dos conceptos de versionado distintos que a veces se confunden: **versiones DSL** y **versiones del parser de sintaxis**. + +**DSL1 vs DSL2** se refiere a formas fundamentalmente diferentes de escribir pipelines de Nextflow. +DSL1 era la sintaxis original donde los processes se conectaban implícitamente a través de channels. +DSL2, introducido en Nextflow 20.07, agregó características de modularidad: la capacidad de importar processes y workflows desde otros archivos, bloques `workflow` explícitos y salidas de process nombradas. +DSL1 fue declarado obsoleto en Nextflow 22.03 y eliminado en 22.12. +Todo el código moderno de Nextflow utiliza DSL2. + +**Parser de sintaxis v1 vs v2** se refiere a diferentes parsers que ambos funcionan con código DSL2. +El parser v1 es el original, más permisivo. +El parser v2 es más estricto y habilita nuevas características del lenguaje como tipado estático (entradas y salidas tipadas) y directivas de salida a nivel de workflow. +El parser v2 también proporciona mejores mensajes de error y detecta más errores en tiempo de análisis en lugar de en tiempo de ejecución. +El parser v2 se convertirá en el predeterminado en Nextflow 26.04. + +En resumen: DSL2 es el lenguaje que escribe; la versión del parser de sintaxis determina cuán estrictamente se interpreta ese lenguaje y qué características avanzadas están disponibles. + +### Verificar y establecer la versión de Nextflow + +Puede verificar qué versión de Nextflow está instalada en su sistema usando el comando `nextflow --version`. + +Para más información sobre cómo actualizar su versión de Nextflow, consulte la documentación de referencia sobre [Updating Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Habilitar el parser de sintaxis v2 + +Para **habilitar** el parser de sintaxis v2 para su sesión actual, ejecute el siguiente comando en su terminal: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Para hacer esto permanente (hasta que v2 se convierta en el predeterminado en Nextflow 26.04), agregue el comando export a su perfil de shell (`~/.bashrc`, `~/.zshrc`, etc.): + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Tenga en cuenta que la variable de entorno `NXF_SYNTAX_PARSER=v2` es un requisito temporal. +A partir de Nextflow 26.04, el parser v2 se convertirá en el predeterminado y esta configuración ya no será necesaria. + +### Deshabilitar el parser de sintaxis v2 + +Para **deshabilitar** el parser de sintaxis v2 para su sesión actual, ejecute el siguiente comando en su terminal: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migrar código existente + +Para obtener orientación sobre la migración de código existente para cumplir con versiones más recientes de Nextflow, consulte las [Migration Notes](https://www.nextflow.io/docs/latest/migrations/index.html) en la documentación de referencia. + +Estos dos artículos son particularmente útiles para migrar a la versión más reciente: + +- [Migrating to workflow outputs](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrating to static types](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Ambas características se cubren como parte del entrenamiento para principiantes a partir de la versión 3.0 de los materiales de entrenamiento. + +Dependiendo de la generación de código Nextflow que pretenda migrar, es posible que pueda realizar la mayor parte del trabajo con el linter de Nextflow usando el comando `nextflow lint -format`. +Consulte la referencia de CLI para [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) para más detalles. + +Esperamos que esto sea útil. +Si necesita ayuda, comuníquese en Slack o en el foro. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/es/docs/nextflow_run/00_orientation.md b/docs/es/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..c14d2f4c48 --- /dev/null +++ b/docs/es/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Primeros pasos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Iniciar un entorno de entrenamiento + +Para usar el entorno preconfigurado que proporcionamos en GitHub Codespaces, haga clic en el botón "Open in GitHub Codespaces" a continuación. Para otras opciones, consulte [Opciones de entorno](../envsetup/index.md). + +Recomendamos abrir el entorno de entrenamiento en una nueva pestaña o ventana del navegador (use clic derecho, ctrl-clic o cmd-clic dependiendo de su equipo) para que pueda seguir leyendo mientras se carga el entorno. +Necesitará mantener estas instrucciones abiertas en paralelo para trabajar a través del curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Conceptos básicos del entorno + +Este entorno de entrenamiento contiene todo el software, código y datos necesarios para trabajar a través del curso de entrenamiento, por lo que no necesita instalar nada usted mismo. + +El codespace está configurado con una interfaz VSCode, que incluye un explorador de archivos, un editor de código y una terminal. +Todas las instrucciones dadas durante el curso (por ejemplo, 'abrir el archivo', 'editar el código' o 'ejecutar este comando') se refieren a esas tres partes de la interfaz VSCode a menos que se especifique lo contrario. + +Si está trabajando en este curso por su cuenta, familiarícese con los [conceptos básicos del entorno](../envsetup/01_setup.md) para más detalles. + +### Requisitos de versión + +Este entrenamiento está diseñado para Nextflow 25.10.2 o posterior **con el analizador de sintaxis v2 HABILITADO**. +Si está usando un entorno local o personalizado, asegúrese de usar la configuración correcta como se documenta [aquí](../info/nxf_versions.md). + +## Prepararse para trabajar + +Una vez que su codespace esté ejecutándose, hay dos cosas que necesita hacer antes de sumergirse en el entrenamiento: establecer su directorio de trabajo para este curso específico y echar un vistazo a los materiales proporcionados. + +### Establecer el directorio de trabajo + +Por defecto, el codespace se abre con el directorio de trabajo establecido en la raíz de todos los cursos de entrenamiento, pero para este curso, trabajaremos en el directorio `nextflow-run/`. + +Cambie de directorio ahora ejecutando este comando en la terminal: + +```bash +cd nextflow-run/ +``` + +Puede configurar VSCode para enfocarse en este directorio, de modo que solo los archivos relevantes se muestren en la barra lateral del explorador de archivos: + +```bash +code . +``` + +!!! tip "Consejo" + + Si por cualquier razón sale de este directorio (por ejemplo, si su codespace entra en suspensión), siempre puede usar la ruta completa para volver a él, asumiendo que está ejecutando esto dentro del entorno de entrenamiento de GitHub Codespaces: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Ahora echemos un vistazo a los contenidos. + +### Explorar los materiales proporcionados + +Puede explorar los contenidos de este directorio usando el explorador de archivos en el lado izquierdo del espacio de trabajo de entrenamiento. +Alternativamente, puede usar el comando `tree`. + +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenidos del directorio de forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 2 +``` + +??? abstract "Contenidos del directorio" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Haga clic en el cuadro coloreado para expandir la sección y ver su contenido. +Usamos secciones colapsables como esta para mostrar la salida esperada de comandos así como contenidos de directorios y archivos de manera concisa. + +- **Los archivos `.nf`** son scripts de workflow que están numerados según la parte del curso en la que se usan. + +- **El archivo `nextflow.config`** es un archivo de configuración que establece propiedades mínimas del entorno. + Puede ignorarlo por ahora. + +- **El archivo `greetings.csv`** bajo `data/` contiene datos de entrada que usaremos en la mayor parte del curso. Se describe en la Parte 2 (Ejecutar pipelines), cuando lo introducimos por primera vez. + +- **Los archivos `test-params.*`** son archivos de configuración que usaremos en la Parte 3 (Configuración). Puede ignorarlos por ahora. + +- **El directorio `solutions`** contiene el estado final del workflow y sus archivos accesorios (config y modules) que resultan de completar el curso. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + +## Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi entorno está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente + +Si puede marcar todas las casillas, está listo para comenzar. + +**Para continuar a [Parte 1: Ejecutar operaciones básicas](./01_basics.md), haga clic en la flecha en la esquina inferior derecha de esta página.** diff --git a/docs/es/docs/nextflow_run/01_basics.md b/docs/es/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..82f481c9d9 --- /dev/null +++ b/docs/es/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Parte 1: Ejecutar operaciones básicas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta primera parte del curso de entrenamiento Nextflow Run, nos introducimos en el tema con un ejemplo muy básico de Hello World independiente del dominio, que usaremos para demostrar operaciones esenciales y señalar los componentes de código de Nextflow correspondientes. + +??? info "¿Qué es un ejemplo Hello World?" + + Un "Hello World!" es un ejemplo minimalista que pretende demostrar la sintaxis y estructura básica de un lenguaje de programación o framework de software. + El ejemplo típicamente consiste en imprimir la frase "Hello, World!" al dispositivo de salida, como la consola o terminal, o escribirla en un archivo. + +--- + +## 1. Ejecutar un Hello World directamente + +Demostremos este concepto con un comando simple que ejecutamos directamente en la terminal, para mostrar lo que hace antes de envolverlo en Nextflow. + +!!! tip "Consejo" + + Recuerde que ahora debería estar dentro del directorio `nextflow-run/` como se describe en la página de [Primeros pasos](00_orientation.md). + +### 1.1. Hacer que la terminal diga hola + +Ejecute el siguiente comando en su terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Salida del comando" + + ```console + Hello World! + ``` + +Esto muestra el texto 'Hello World' directamente en la terminal. + +### 1.2. Escribir la salida a un archivo + +Ejecutar pipelines principalmente implica leer datos de archivos y escribir resultados en otros archivos, así que modifiquemos el comando para escribir la salida de texto a un archivo para hacer el ejemplo un poco más relevante. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Salida del comando" + + ```console + + ``` + +Esto no muestra nada en la terminal. + +### 1.3. Encontrar la salida + +El texto 'Hello World' ahora debería estar en el archivo de salida que especificamos, llamado `output.txt`. +Puede abrirlo en el explorador de archivos o desde la línea de comandos usando la utilidad `cat`, por ejemplo. + +??? abstract "Contenido del archivo" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Esto es lo que vamos a intentar replicar con nuestro primer workflow de Nextflow. + +### Conclusión + +Ahora sabe cómo ejecutar un comando simple en la terminal que produce algún texto, y opcionalmente, cómo hacer que escriba la salida a un archivo. + +### ¿Qué sigue? + +Descubra qué se necesita para ejecutar un workflow de Nextflow que logre el mismo resultado. + +--- + +## 2. Ejecutar el workflow + +Le proporcionamos un script de workflow llamado `1-hello.nf` que toma un saludo de entrada a través de un argumento de línea de comandos llamado `--input` y produce un archivo de texto que contiene ese saludo. + +No vamos a mirar el código todavía; primero veamos cómo se ve ejecutarlo. + +### 2.1. Lanzar el workflow y monitorear la ejecución + +En la terminal, ejecute el siguiente comando: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Salida del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Si su salida de consola se ve algo así, ¡felicidades, acaba de ejecutar su primer workflow de Nextflow! + +La salida más importante aquí es la última línea, que está resaltada en la salida anterior: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Esto nos dice que el process `sayHello` fue ejecutado exitosamente una vez (`1 of 1 ✔`). + +Genial, pero puede estar preguntándose: ¿dónde está la salida? + +### 2.2. Encontrar el archivo de salida en el directorio `results` + +Este workflow está configurado para publicar su salida en un directorio de resultados. +Si mira su directorio actual, verá que cuando ejecutó el workflow, Nextflow creó un nuevo directorio llamado `results`, así como un subdirectorio llamado `1-hello` bajo él, que contiene un archivo llamado `output.txt`. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Abra el archivo; el contenido debería coincidir con la cadena que especificó en la línea de comandos. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +¡Genial, nuestro workflow hizo lo que se suponía que debía hacer! + +Sin embargo, tenga en cuenta que el resultado 'publicado' es una copia (o en algunos casos un enlace simbólico) de la salida real producida por Nextflow cuando ejecutó el workflow. + +Ahora vamos a echar un vistazo bajo el capó para ver dónde ejecutó Nextflow realmente el trabajo. + +!!! warning "Advertencia" + + No todos los workflows estarán configurados para publicar salidas en un directorio de resultados, y/o los nombres y estructura de directorios pueden ser diferentes. + Un poco más adelante en esta sección, le mostraremos cómo averiguar dónde se especifica este comportamiento. + +### 2.3. Encontrar la salida original y los registros en el directorio `work/` + +Cuando ejecuta un workflow, Nextflow crea un 'directorio de tarea' distinto para cada invocación individual de cada process en el workflow (=cada paso en el pipeline). +Para cada uno, preparará las entradas necesarias, ejecutará la(s) instrucción(es) relevante(s) y escribirá las salidas y archivos de registro dentro de ese único directorio, que se nombra automáticamente usando un hash para hacerlo único. + +Todos estos directorios de tareas vivirán bajo un directorio llamado `work` dentro de su directorio actual (donde está ejecutando el comando). + +Eso puede sonar confuso, así que veamos cómo se ve en la práctica. + +Volviendo a la salida de consola del workflow que ejecutamos antes, teníamos esta línea: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +¿Ve cómo la línea comienza con `[a3/7be2fa]`? +Esa es una forma truncada de la ruta del directorio de tarea para esa llamada de process, y le dice dónde encontrar la salida de la llamada del process `sayHello` dentro de la ruta del directorio `work/`. + +Puede encontrar la ruta completa escribiendo el siguiente comando (reemplazando `a3/7be2fa` con lo que ve en su propia terminal) y presionando la tecla tab para autocompletar la ruta o agregando un asterisco: + +```bash +ls work/a3/7be2fa* +``` + +Esto debería producir la ruta completa del directorio: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Veamos qué hay ahí. + +??? abstract "Contenidos del directorio" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "¿No ve lo mismo?" + + Los nombres exactos de los subdirectorios serán diferentes en su sistema. + + Si navega por los contenidos del subdirectorio de tarea en el explorador de archivos de VSCode, verá todos los archivos de inmediato. + Sin embargo, los archivos de registro están configurados para ser invisibles en la terminal, así que si quiere usar `ls` o `tree` para verlos, necesitará establecer la opción relevante para mostrar archivos invisibles. + + ```bash + tree -a work + ``` + +Debería reconocer inmediatamente el archivo `output.txt`, que es de hecho la salida original del process `sayHello` que se publicó en el directorio `results`. +Si lo abre, encontrará el saludo `Hello World!` nuevamente. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +¿Entonces qué pasa con todos esos otros archivos? + +Estos son los archivos auxiliares y de registro que Nextflow escribió como parte de la ejecución de la tarea: + +- **`.command.begin`**: Archivo centinela creado tan pronto como se lanza la tarea. +- **`.command.err`**: Mensajes de error (`stderr`) emitidos por la llamada del process +- **`.command.log`**: Salida de registro completa emitida por la llamada del process +- **`.command.out`**: Salida regular (`stdout`) por la llamada del process +- **`.command.run`**: Script completo ejecutado por Nextflow para ejecutar la llamada del process +- **`.command.sh`**: El comando que realmente ejecutó la llamada del process +- **`.exitcode`**: El código de salida resultante del comando + +El archivo `.command.sh` es especialmente útil porque le muestra el comando principal que Nextflow ejecutó, sin incluir toda la contabilidad y configuración de tarea/entorno. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Esto confirma que el workflow compuso el mismo comando que ejecutamos directamente en la línea de comandos anteriormente. + +Cuando algo sale mal y necesita solucionar lo que sucedió, puede ser útil mirar el script `command.sh` para verificar exactamente qué comando compuso Nextflow basándose en las instrucciones del workflow, interpolación de variables y demás. + +### 2.4. Re-ejecutar el workflow con diferentes saludos + +Intente re-ejecutar el workflow algunas veces con diferentes valores para el argumento `--input`, luego mire los directorios de tarea. + +??? abstract "Contenidos del directorio" + + ```console + 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 + ``` + +Puede ver que se ha creado un nuevo subdirectorio con un conjunto completo de archivos de salida y registro para cada ejecución. + +En contraste, si mira el directorio `results`, todavía hay solo un conjunto de resultados, y el contenido del archivo de salida corresponde a lo que ejecutó por última vez. + +??? abstract "Contenidos del directorio" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Esto le muestra que los resultados publicados serán sobrescritos por ejecuciones posteriores, mientras que los directorios de tarea bajo `work/` se preservan. + +### Conclusión + +Sabe cómo ejecutar un script simple de Nextflow, monitorear su ejecución y encontrar sus salidas. + +### ¿Qué sigue? + +Aprenda cómo leer un script básico de Nextflow e identificar cómo sus componentes se relacionan con su funcionalidad. + +--- + +## 3. Examinar el script inicial del workflow Hello World + +Lo que hicimos allí fue básicamente tratar el script del workflow como una caja negra. +Ahora que hemos visto lo que hace, abramos la caja y miremos adentro. + +Nuestro objetivo aquí no es memorizar la sintaxis del código de Nextflow, sino formar alguna intuición básica de cuáles son los componentes principales y cómo están organizados. + +### 3.1. Examinar la estructura general del código + +Encontrará el script `1-hello.nf` en su directorio actual, que debería ser `nextflow-run`. Ábralo en el panel del editor. + +??? full-code "Archivo de código completo" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usar echo para imprimir 'Hello World!' a un archivo + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parameters + */ + params { + input: String + } + + workflow { + + main: + // emitir un saludo + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Un script de workflow de Nextflow típicamente incluye una o más definiciones de **process**, el **workflow** en sí, y algunos bloques opcionales como **params** y **output**. + +Cada **process** describe qué operación(es) debería realizar el paso correspondiente en el pipeline, mientras que el **workflow** describe la lógica de flujo de datos que conecta los varios pasos. + +Echemos un vistazo más de cerca al bloque **process** primero, luego veremos el bloque **workflow**. + +### 3.2. La definición del `process` + +El primer bloque de código describe un **process**. +La definición del process comienza con la palabra clave `process`, seguida del nombre del process y finalmente el cuerpo del process delimitado por llaves. +El cuerpo del process debe contener un bloque script que especifica el comando a ejecutar, que puede ser cualquier cosa que pueda ejecutar en una terminal de línea de comandos. + +```groovy title="1-hello.nf" linenums="3" +/* +* Usar echo para imprimir un saludo a un archivo +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Aquí tenemos un **process** llamado `sayHello` que toma una variable de **entrada** llamada `greeting` y escribe su **salida** a un archivo llamado `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +Esta es una definición de process muy mínima que solo contiene una definición de `input`, una definición de `output` y el `script` a ejecutar. + +La definición de `input` incluye el calificador `val`, que le dice a Nextflow que espere un valor de algún tipo (puede ser una cadena, un número, lo que sea). + +La definición de `output` incluye el calificador `path`, que le dice a Nextflow que esto debe manejarse como una ruta (incluye tanto rutas de directorio como archivos). + +### 3.3. La definición del `workflow` + +El segundo bloque de código describe el **workflow** en sí. +La definición del workflow comienza con la palabra clave `workflow`, seguida de un nombre opcional, luego el cuerpo del workflow delimitado por llaves. + +Aquí tenemos un **workflow** que consiste en un bloque `main:` y un bloque `publish:`. +El bloque `main:` es el cuerpo principal del workflow y el bloque `publish:` lista las salidas que deben publicarse en el directorio `results`. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // emitir un saludo + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +En este caso el bloque `main:` contiene una llamada al process `sayHello` y le da una entrada llamada `params.input` para usar como el saludo. + +Como discutiremos con más detalle en un momento, `params.input` contiene el valor que dimos al parámetro `--input` en nuestra línea de comandos. + +El bloque `publish:` lista la salida de la llamada del process `sayHello()`, a la cual se refiere como `sayHello.out` y le da el nombre `first_output` (esto puede ser cualquier cosa que el autor del workflow quiera). + +Esta es una definición de **workflow** muy mínima. +En un pipeline del mundo real, el workflow típicamente contiene múltiples llamadas a **processes** conectados por **channels**, y puede haber valores predeterminados configurados para las entradas variables. + +Llegaremos a eso en la Parte 2 del curso. +Por ahora, echemos un vistazo más de cerca a cómo nuestro workflow está manejando entradas y salidas. + +### 3.4. El sistema `params` de parámetros de línea de comandos + +El `params.input` que proporcionamos a la llamada del process `sayHello()` es un código elegante de Nextflow y vale la pena dedicarle un minuto extra. + +Como se mencionó anteriormente, así es como pasamos el valor del parámetro de línea de comandos `--input` a la llamada del process `sayHello()`. +De hecho, simplemente declarar `params.someParameterName` es suficiente para dar al workflow un parámetro llamado `--someParameterName` desde la línea de comandos. + +Aquí hemos formalizado esa declaración de parámetro configurando un bloque `params` que especifica el tipo de entrada que espera el workflow (Nextflow 25.10.2 y posterior). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +Los tipos soportados incluyen `String`, `Integer`, `Float`, `Boolean` y `Path`. + +!!! tip "Consejo" + + Los parámetros de workflow declarados usando el sistema `params` siempre llevan dos guiones en la línea de comandos (`--`). + Esto los distingue de los parámetros a nivel de Nextflow, que solo llevan un guión (`-`). + +### 3.5. La directiva `publish` + +En el otro extremo del workflow, ya hemos echado un vistazo al bloque `publish:`. +Esa es una mitad del sistema de manejo de salidas; la otra mitad es el bloque `output` ubicado abajo. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Esto especifica que la salida `first_output` listada en el bloque `publish:` debe copiarse a un subdirectorio llamado `1-hello` bajo el directorio de salida `results` predeterminado. + +La línea `mode 'copy'` anula el comportamiento predeterminado del sistema, que es hacer un enlace simbólico (o symlink) al archivo original en el directorio `work/` en lugar de una copia propiamente dicha. + +Hay más opciones que las mostradas aquí para controlar el comportamiento de publicación; cubriremos algunas más adelante. +También verá que cuando un workflow genera múltiples salidas, cada una se lista de esta manera en el bloque `output`. + +??? info "Sintaxis antigua para publicar salidas usando `publishDir`" + + Hasta muy recientemente, la forma establecida de publicar salidas era hacerlo a nivel de cada process individual usando una directiva `publishDir`. + + Todavía encontrará este patrón de código en todas partes en pipelines de Nextflow más antiguos y módulos de process, por lo que es importante estar al tanto de ello. + + En lugar de tener un bloque `publish:` en el workflow y un bloque `output` en el nivel superior, vería una línea `publishDir` en la definición del process `sayHello`: + + ```groovy title="Ejemplo de sintaxis" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + Sin embargo, no recomendamos usar esto en ningún trabajo nuevo ya que eventualmente será prohibido en futuras versiones del lenguaje Nextflow. + +### Conclusión + +Ahora sabe cómo está estructurado un workflow simple de Nextflow, y cómo los componentes básicos se relacionan con su funcionalidad. + +### ¿Qué sigue? + +Aprenda a gestionar las ejecuciones de su workflow de manera conveniente. + +--- + +## 4. Gestionar ejecuciones de workflow + +Saber cómo lanzar workflows y recuperar salidas es genial, pero rápidamente encontrará que hay algunos otros aspectos de la gestión de workflows que harán su vida más fácil. + +Aquí le mostramos cómo aprovechar la función `resume` para cuando necesite re-lanzar el mismo workflow, cómo inspeccionar los registros de ejecución con `nextflow log`, y cómo eliminar directorios de trabajo antiguos con `nextflow clean`. + +### 4.1. Re-lanzar un workflow con `-resume` + +A veces, va a querer re-ejecutar un pipeline que ya lanzó anteriormente sin rehacer ningún trabajo que ya se completó exitosamente. + +Nextflow tiene una opción llamada `-resume` que le permite hacer esto. +Específicamente, en este modo, cualquier process que ya se haya ejecutado con exactamente el mismo código, configuración y entradas será omitido. +Esto significa que Nextflow solo ejecutará los processes que haya agregado o modificado desde la última ejecución, o a los que esté proporcionando nuevas configuraciones o entradas. + +Hay dos ventajas clave de hacer esto: + +- Si está en medio del desarrollo de un pipeline, puede iterar más rápidamente ya que solo tiene que ejecutar el o los process(es) en los que está trabajando activamente para probar sus cambios. +- Si está ejecutando un pipeline en producción y algo sale mal, en muchos casos puede arreglar el problema y relanzar el pipeline, y reanudará la ejecución desde el punto de falla, lo que puede ahorrarle mucho tiempo y cómputo. + +Para usarlo, simplemente agregue `-resume` a su comando y ejecútelo: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Salida del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +La salida de consola debería verse familiar, pero hay una cosa que es un poco diferente comparado con antes. + +Busque el bit `cached:` que se ha agregado en la línea de estado del process (línea 5), lo que significa que Nextflow ha reconocido que ya hizo este trabajo y simplemente reutilizó el resultado de la ejecución exitosa anterior. + +También puede ver que el hash del subdirectorio de trabajo es el mismo que en la ejecución anterior. +Nextflow está literalmente señalándole la ejecución anterior y diciendo "Ya hice eso ahí". + +!!! tip "Consejo" + + Cuando re-ejecuta un pipeline con `resume`, Nextflow no sobrescribe ningún archivo publicado fuera del directorio de trabajo por cualquier ejecución que se ejecutó exitosamente anteriormente. + +### 4.2. Inspeccionar el registro de ejecuciones pasadas + +Cada vez que lanza un workflow de Nextflow, se escribe una línea en un archivo de registro llamado `history`, bajo un directorio oculto llamado `.nextflow` en el directorio de trabajo actual. + +??? abstract "Contenido del archivo" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Este archivo le da la marca de tiempo, nombre de ejecución, estado, ID de revisión, ID de sesión y línea de comandos completa para cada ejecución de Nextflow que se ha lanzado desde el directorio de trabajo actual. + +Una forma más conveniente de acceder a esta información es usar el comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Salida del comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Esto mostrará el contenido del archivo de registro en la terminal, aumentado con una línea de encabezado. + +Notará que el ID de sesión cambia cada vez que ejecuta un nuevo comando `nextflow run`, EXCEPTO si está usando la opción `-resume`. +En ese caso, el ID de sesión permanece igual. + +Nextflow usa el ID de sesión para agrupar información de caché de ejecución bajo el directorio `cache`, también ubicado bajo `.nextflow`. + +### 4.3. Eliminar directorios de trabajo antiguos + +Si ejecuta muchos pipelines, puede terminar acumulando muchos archivos a través de muchos subdirectorios. +Dado que los subdirectorios se nombran aleatoriamente, es difícil saber por sus nombres cuáles son ejecuciones más antiguas vs. más recientes. + +Afortunadamente Nextflow incluye un subcomando útil `clean` que puede eliminar automáticamente los subdirectorios de trabajo de ejecuciones pasadas que ya no le importan. + +#### 4.3.1. Determinar criterios de eliminación + +Hay múltiples [opciones](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para determinar qué eliminar. + +Aquí le mostramos un ejemplo que elimina todos los subdirectorios de ejecuciones anteriores a una ejecución dada, especificada usando su nombre de ejecución. + +Busque la ejecución exitosa más reciente donde no usó `-resume`; en nuestro caso el nombre de ejecución fue `backstabbing_swartz`. + +El nombre de ejecución es la cadena de dos partes generada por la máquina mostrada entre corchetes en la línea de salida de consola `Launching (...)`. +También puede usar el registro de Nextflow para buscar una ejecución basándose en su marca de tiempo y/o línea de comandos. + +#### 4.3.2. Hacer una ejecución de prueba + +Primero usamos la bandera de ejecución de prueba `-n` para verificar qué se eliminará dado el comando: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Salida del comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Su salida tendrá diferentes nombres de directorio de tarea y puede tener un número diferente de líneas, pero debería verse similar al ejemplo. + +Si no ve ninguna línea de salida, ya sea que no proporcionó un nombre de ejecución válido o no hay ejecuciones pasadas para eliminar. Asegúrese de cambiar `backstabbing_swartz` en el comando de ejemplo a lo que sea el nombre de ejecución más reciente correspondiente en su registro. + +#### 4.3.3. Proceder con la eliminación + +Si la salida se ve como se esperaba y quiere proceder con la eliminación, re-ejecute el comando con la bandera `-f` en lugar de `-n`: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Salida del comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +La salida debería ser similar a antes, pero ahora diciendo 'Removed' en lugar de 'Would remove'. +Note que esto no elimina los subdirectorios de dos caracteres (como `eb/` arriba) pero sí vacía su contenido. + +!!! warning "Advertencia" + + Eliminar subdirectorios de trabajo de ejecuciones pasadas los elimina de la caché de Nextflow y elimina cualquier salida que se almacenó en esos directorios. + Eso significa que rompe la capacidad de Nextflow de reanudar la ejecución sin re-ejecutar los processes correspondientes. + + ¡Usted es responsable de guardar cualquier salida que le importe! Esa es la razón principal por la que preferimos usar el modo `copy` en lugar del modo `symlink` para la directiva `publish`. + +### Conclusión + +Sabe cómo relanzar un pipeline sin repetir pasos que ya se ejecutaron de manera idéntica, inspeccionar el registro de ejecución, y usar el comando `nextflow clean` para limpiar directorios de trabajo antiguos. + +### ¿Qué sigue? + +¡Tome un pequeño descanso! Acaba de absorber los bloques de construcción de la sintaxis de Nextflow e instrucciones básicas de uso. + +En la próxima sección de este entrenamiento, vamos a ver cuatro versiones sucesivamente más realistas del pipeline Hello World que demostrarán cómo Nextflow le permite procesar múltiples entradas eficientemente, ejecutar workflows compuestos de múltiples pasos conectados, aprovechar componentes de código modulares, y utilizar contenedores para mayor reproducibilidad y portabilidad. + +--- + +## Cuestionario + +<quiz> +En la línea de salida de consola `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`, ¿qué representa `[a3/7be2fa]`? +- [ ] El número de versión del process +- [ ] Un identificador único de ejecución +- [x] La ruta truncada al directorio de trabajo de la tarea +- [ ] La suma de verificación del archivo de salida + +Más información: [2.3. Encontrar la salida original y los registros en el directorio `work/`](#23-encontrar-la-salida-original-y-los-registros-en-el-directorio-work) +</quiz> + +<quiz> +¿Cuál es el propósito del archivo `.command.sh` en un directorio de tarea? +- [ ] Almacena la configuración de la tarea +- [x] Muestra el comando real que fue ejecutado por el process +- [ ] Contiene mensajes de error de tareas fallidas +- [ ] Lista los archivos de entrada preparados para la tarea + +Más información: [2.3. Encontrar la salida original y los registros en el directorio `work/`](#23-encontrar-la-salida-original-y-los-registros-en-el-directorio-work) +</quiz> + +<quiz> +¿Qué sucede con los resultados publicados cuando re-ejecuta un workflow sin `-resume`? +- [ ] Se preservan en directorios separados con marca de tiempo +- [x] Son sobrescritos por la nueva ejecución +- [ ] Nextflow previene la sobrescritura y falla +- [ ] Son respaldados automáticamente + +Más información: [2.4. Re-ejecutar el workflow con diferentes saludos](#24-re-ejecutar-el-workflow-con-diferentes-saludos) +</quiz> + +<quiz> +¿Qué indica esta salida de consola? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] La tarea falló y fue omitida +- [ ] La tarea está esperando en una cola +- [x] Nextflow reutilizó resultados de una ejecución idéntica anterior +- [ ] La tarea fue cancelada manualmente + +Más información: [4.1. Re-lanzar un workflow con `-resume`](#41-re-lanzar-un-workflow-con--resume) +</quiz> + +<quiz> +¿Dónde almacena Nextflow el historial de ejecución que muestra el comando `nextflow log`? +- [ ] En el directorio de resultados +- [ ] En el directorio de trabajo +- [x] En el archivo `.nextflow/history` +- [ ] En `nextflow.config` + +Más información: [4.2. Inspeccionar el registro de ejecuciones pasadas](#42-inspeccionar-el-registro-de-ejecuciones-pasadas) +</quiz> + +<quiz> +¿Cuál es el propósito del bloque `params` en un archivo de workflow? +- [ ] Definir los requisitos de recursos del process +- [ ] Configurar el executor +- [x] Declarar y tipificar los parámetros de entrada del workflow +- [ ] Especificar opciones de publicación de salida + +Más información: [3.4. El sistema params de parámetros de línea de comandos](#34-el-sistema-params-de-parámetros-de-línea-de-comandos) +</quiz> + +<quiz> +En el bloque `output` del workflow, ¿qué hace `mode 'copy'`? +- [ ] Crea un respaldo del directorio de trabajo +- [x] Hace una copia completa de archivos en lugar de enlaces simbólicos +- [ ] Copia el script del workflow a los resultados +- [ ] Habilita la copia incremental de archivos + +Más información: [3.5. La directiva publish](#35-la-directiva-publish) +</quiz> + +<quiz> +¿Cuál es la bandera recomendada para usar con el comando `nextflow clean` antes de realmente eliminar archivos? +- [x] `-n` (ejecución de prueba) para previsualizar lo que se eliminaría +- [ ] `-v` (verbose) para ver salida detallada +- [ ] `-a` (all) para seleccionar todos los directorios +- [ ] `-q` (quiet) para suprimir advertencias + +Más información: [4.3. Eliminar directorios de trabajo antiguos](#43-eliminar-directorios-de-trabajo-antiguos) +</quiz> diff --git a/docs/es/docs/nextflow_run/02_pipeline.md b/docs/es/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..d6d573d60c --- /dev/null +++ b/docs/es/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1509 @@ +# Parte 2: Ejecutar pipelines reales + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la Parte 1 de este curso (Ejecutar operaciones básicas), comenzamos con un workflow de ejemplo que solo tenía características mínimas para mantener baja la complejidad del código. +Por ejemplo, `1-hello.nf` usaba un parámetro de línea de comandos (`--input`) para proporcionar un único valor a la vez. + +Sin embargo, la mayoría de los pipelines del mundo real usan características más sofisticadas para permitir el procesamiento eficiente de grandes cantidades de datos a escala, y aplican múltiples pasos de procesamiento encadenados por una lógica a veces compleja. + +En esta parte del entrenamiento, demostramos características clave de pipelines del mundo real probando versiones expandidas del pipeline Hello World original. + +## 1. Procesar datos de entrada desde un archivo + +En un pipeline del mundo real, típicamente queremos procesar múltiples puntos de datos (o series de datos) contenidos en uno o más archivos de entrada. +Y siempre que sea posible, queremos ejecutar el procesamiento de datos independientes en paralelo, para acortar el tiempo de espera para el análisis. + +Para demostrar cómo hace esto Nextflow, hemos preparado un archivo CSV llamado `greetings.csv` que contiene varios saludos de entrada, imitando el tipo de datos columnares que podría querer procesar en un análisis de datos real. +Note que los números no tienen significado, están ahí solo con propósitos ilustrativos. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +También hemos escrito una versión mejorada del workflow original, ahora llamada `2a-inputs.nf`, que leerá el archivo CSV, extraerá los saludos y escribirá cada uno de ellos en un archivo separado. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Ejecutemos el workflow primero, y veremos el código de Nextflow relevante después. + +### 1.1. Ejecutar el workflow + +Ejecute el siguiente comando en su terminal. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Emocionantemente, esto parece indicar que se hicieron '3 of 3' llamadas para el process, lo cual es alentador, ya que había tres filas de datos en el CSV que proporcionamos como entrada. +Esto sugiere que el process `sayHello()` fue llamado tres veces, una vez en cada fila de entrada. + +### 1.2. Encontrar las salidas publicadas en el directorio `results` + +Veamos el directorio 'results' para ver si nuestro workflow todavía está escribiendo una copia de nuestras salidas allí. + +??? abstract "Contenidos del directorio" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +¡Sí! Vemos un nuevo directorio llamado `2a-inputs` con tres archivos de salida con diferentes nombres, convenientemente. + +Puede abrir cada uno de ellos para asegurarse de que contienen la cadena de saludo apropiada. + +??? abstract "Contenido de los archivos" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Esto confirma que cada saludo en el archivo de entrada ha sido procesado apropiadamente. + +### 1.3. Encontrar las salidas y registros originales + +Puede haber notado que la salida de consola anterior se refería a solo un directorio de tarea. +¿Significa eso que las tres llamadas a `sayHello()` fueron ejecutadas dentro de ese único directorio de tarea? + +#### 1.3.1. Examinar el directorio de tarea dado en la terminal + +Echemos un vistazo dentro de ese directorio de tarea `8e/0eb066`. + +??? abstract "Contenidos del directorio" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Solo encontramos la salida correspondiente a uno de los saludos (así como los archivos accesorios si habilitamos la visualización de archivos ocultos). + +Entonces, ¿qué está pasando aquí? + +Por defecto, el sistema de registro ANSI escribe la información de estado para todas las llamadas al mismo process en la misma línea. +Como resultado, solo nos mostró una de las tres rutas de directorio de tarea (`8e/0eb066`) en la salida de consola. +Hay otras dos que no están listadas allí. + +#### 1.3.2. Hacer que la terminal muestre más detalles + +Podemos modificar el comportamiento de registro para ver la lista completa de llamadas de process agregando `-ansi-log false` al comando de la siguiente manera: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Salida del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Esta vez vemos las tres ejecuciones de process y sus subdirectorios de trabajo asociados listados en la salida. +Deshabilitar el registro ANSI también evitó que Nextflow usara colores en la salida de terminal. + +Note que la forma en que se reporta el estado es un poco diferente entre los dos modos de registro. +En el modo condensado, Nextflow reporta si las llamadas se completaron exitosamente o no. +En este modo expandido, solo reporta que fueron enviadas. + +Esto confirma que el process `sayHello()` es llamado tres veces, y se crea un directorio de tarea separado para cada uno. + +Si miramos dentro de cada uno de los directorios de tarea listados allí, podemos verificar que cada uno corresponde a uno de los saludos. + +??? abstract "Contenidos del directorio" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Esto confirma que cada llamada de process se ejecuta aislada de todas las demás. +Eso tiene muchas ventajas, incluyendo evitar colisiones si el process produce algún archivo intermedio con nombres no únicos. + +!!! tip "Consejo" + + Para un workflow complejo, o un gran número de entradas, tener la lista completa en la terminal podría volverse un poco abrumador, así que las personas normalmente no usan `-ansi-log false` en uso rutinario. + +### 1.4. Examinar el código del workflow + +Así que esta versión del workflow es capaz de leer un archivo CSV de entradas, procesar las entradas por separado, y nombrar las salidas de manera única. + +Veamos qué hace posible eso en el código del workflow. + +??? full-code "Archivo de código completo" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Usar echo para imprimir 'Hello World!' a un archivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + } + + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Una vez más, no necesita memorizar la sintaxis del código, pero es bueno aprender a reconocer componentes clave del workflow que proporcionan funcionalidad importante. + +#### 1.4.1. Cargar los datos de entrada desde el CSV + +Esta es la parte más interesante: ¿cómo cambiamos de tomar un único valor desde la línea de comandos, a tomar un archivo CSV, analizarlo y procesar los saludos individuales que contiene? + +En Nextflow, hacemos eso con un **channel**: una estructura diseñada para manejar entradas eficientemente y transportarlas de un paso a otro en workflows de múltiples pasos, mientras proporciona paralelismo incorporado y muchos beneficios adicionales. + +Desglosémoslo. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) +``` + +Este código crea un channel llamado `greeting_ch` que lee el archivo CSV, lo analiza y extrae la primera columna de cada fila. +El resultado es un channel que contiene `Hello`, `Bonjour` y `Holà`. + +??? tip "¿Cómo funciona esto?" + + Esto es lo que significa esa línea en español sencillo: + + - `channel.fromPath` es una **fábrica de canales** que crea un channel a partir de ruta(s) de archivo + - `(params.input)` especifica que la ruta del archivo se proporciona mediante `--input` en la línea de comandos + + En otras palabras, esa línea le dice a Nextflow: toma la ruta del archivo dada con `--input` y prepárate para tratar su contenido como datos de entrada. + + Luego las siguientes dos líneas aplican **operadores** que hacen el análisis real del archivo y la carga de los datos en la estructura de datos apropiada: + + - `.splitCsv()` le dice a Nextflow que analice el archivo CSV en un array representando filas y columnas + - `.map { line -> line[0] }` le dice a Nextflow que tome solo el elemento en la primera columna de cada fila + + Así que en la práctica, comenzando desde el siguiente archivo CSV: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Hemos transformado eso en un array que se ve así: + + ```txt title="Contenido del array" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + Y luego hemos tomado el primer elemento de cada una de las tres filas y los hemos cargado en un channel de Nextflow que ahora contiene: `Hello`, `Bonjour` y `Holà`. + + Si quiere entender los channels y operadores en profundidad, incluyendo cómo escribirlos usted mismo, vea [Hello Nextflow Part 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Llamar al process en cada saludo + +Luego, en la última línea del bloque `main:` del workflow, proporcionamos el channel cargado `greeting_ch` como entrada al process `sayHello()`. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) +``` + +Esto le dice a Nextflow que ejecute el process individualmente en cada elemento del channel, _es decir_, en cada saludo. +Y como Nextflow es inteligente, ejecutará estas llamadas de process en paralelo si es posible, dependiendo de la infraestructura de computación disponible. + +Así es como puede lograr un procesamiento eficiente y escalable de muchos datos (muchas muestras, o puntos de datos, lo que sea su unidad de investigación) con comparativamente muy poco código. + +#### 1.4.3. Cómo se nombran las salidas + +Finalmente, vale la pena echar un vistazo rápido al código del process para ver cómo hacemos que los archivos de salida se nombren de manera única. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Puede ver que, comparado con la versión de este process en `1-hello.nf`, la declaración de salida y la parte relevante del comando han cambiado para incluir el valor del saludo en el nombre del archivo de salida. + +Esta es una forma de asegurar que los nombres de los archivos de salida no colisionen cuando se publican en el directorio de resultados común. + +¡Y ese es el único cambio que hemos tenido que hacer dentro de la declaración del process! + +### Conclusión + +Comprende a un nivel básico cómo los channels y operadores nos permiten procesar múltiples entradas eficientemente. + +### ¿Qué sigue? + +Descubra cómo se construyen los workflows de múltiples pasos y cómo operan. + +--- + +## 2. Ejecutar workflows de múltiples pasos + +La mayoría de los workflows del mundo real involucran más de un paso. +Construyamos sobre lo que acabamos de aprender sobre channels, y veamos cómo Nextflow usa channels y operadores para conectar processes juntos en un workflow de múltiples pasos. + +Para ese fin, le proporcionamos un workflow de ejemplo que encadena tres pasos separados y demuestra lo siguiente: + +1. Hacer que los datos fluyan de un process al siguiente +2. Recolectar salidas de múltiples llamadas de process en una sola llamada de process + +Específicamente, hicimos una versión expandida del workflow llamada `2b-multistep.nf` que toma cada saludo de entrada, lo convierte a mayúsculas, luego recolecta todos los saludos en mayúsculas en un único archivo de salida. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Como anteriormente, ejecutaremos el workflow primero y luego veremos el código para ver qué hay de nuevo. + +### 2.1. Ejecutar el workflow + +Ejecute el siguiente comando en su terminal: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Salida del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Puede ver que como se prometió, se ejecutaron múltiples pasos como parte del workflow; los primeros dos (`sayHello` y `convertToUpper`) presumiblemente se ejecutaron en cada saludo individual, y el tercero (`collectGreetings`) se habrá ejecutado solo una vez, en las salidas de las tres llamadas `convertToUpper`. + +### 2.2. Encontrar las salidas + +Verifiquemos que eso es de hecho lo que sucedió echando un vistazo en el directorio `results`. + +??? abstract "Contenidos del directorio" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Como puede ver, tenemos un nuevo directorio llamado `2b-multistep`, y contiene bastantes más archivos que antes. +Algunos de los archivos han sido agrupados en un subdirectorio llamado `intermediates`, mientras que dos archivos están ubicados en el nivel superior. + +Esos dos son los resultados finales del workflow de múltiples pasos. +Tómese un minuto para mirar los nombres de los archivos y verificar su contenido para confirmar que son lo que espera. + +??? abstract "Contenido de los archivos" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +El primero contiene nuestros tres saludos, en mayúsculas y recolectados de vuelta en un único archivo como se prometió. +El segundo es un archivo de informe que resume alguna información sobre la ejecución. + +### 2.3. Examinar el código + +Veamos el código e identifiquemos los patrones clave para workflows de múltiples pasos. + +??? full-code "Archivo de código completo" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Usar echo para imprimir 'Hello World!' a un archivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Usar una herramienta de reemplazo de texto para convertir el saludo a mayúsculas + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Hay mucho sucediendo allí, pero la diferencia más obvia comparada con la versión anterior del workflow es que ahora hay múltiples definiciones de process, y correspondientemente, varias llamadas de process en el bloque workflow. + +Echemos un vistazo más de cerca y veamos si podemos identificar las piezas más interesantes. + +#### 2.3.1. Visualizar la estructura del workflow + +Si está usando VSCode con la extensión de Nextflow, puede obtener un diagrama útil de cómo los processes están conectados haciendo clic en el pequeño enlace `DAG preview` que se muestra justo encima del bloque workflow en cualquier script de Nextflow. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Esto le da una buena visión general de cómo los processes están conectados y qué producen. + +Puede ver que además del process original `sayHello`, ahora también tenemos `convertToUpper` y `collectGreetings`, que coinciden con los nombres de los processes que vimos en la salida de consola. +Las dos nuevas definiciones de process están estructuradas de la misma manera que el process `sayHello`, excepto que `collectGreetings` toma un parámetro de entrada adicional llamado `batch` y produce dos salidas. + +No entraremos en el código para cada uno en detalle, pero si tiene curiosidad, puede buscar los detalles en [Part 2 of Hello Nextflow](../hello_nextflow/03_hello_workflow.md). + +Por ahora, profundicemos en cómo los processes están conectados entre sí. + +#### 2.3.2. Cómo los processes están conectados + +Lo realmente interesante de ver aquí es cómo las llamadas de process están encadenadas juntas en el bloque `main:` del workflow. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Puede ver que la primera llamada de process, `sayHello(greeting_ch)`, no ha cambiado. +Luego la siguiente llamada de process, a `convertToUpper`, se refiere a la salida de `sayHello` como `sayHello.out`. + +El patrón es simple: `processName.out` se refiere al channel de salida de un process, que puede pasarse directamente al siguiente process. +Así es como transportamos datos de un paso al siguiente en Nextflow. + +#### 2.3.3. Un process puede tomar múltiples entradas + +La tercera llamada de process, a `collectGreetings`, es un poco diferente. + +```groovy title="2b-multistep.nf" linenums="77" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Puede ver que esta llamada recibe dos entradas, `convertToUpper.out.collect()` y `params.batch`. +Ignorando la parte `.collect()` por ahora, podemos generalizar esto como `collectGreetings(input1, input2)`. + +Eso coincide con las dos declaraciones de entrada en el módulo del process: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Cuando Nextflow analiza esto, asignará la primera entrada en la llamada a `path input_files`, y la segunda a `val batch_name`. + +Así que ahora sabe que un process puede tomar múltiples entradas, y cómo se ve la llamada en el bloque workflow. + +Ahora echemos un vistazo más de cerca a esa primera entrada, `convertToUpper.out.collect()`. + +#### 2.3.4. Qué hace `collect()` en la llamada `collectGreetings` + +Para pasar la salida de `sayHello` a `convertToUpper`, simplemente nos referimos al channel de salida de `sayHello` como `sayHello.out`. Pero para el siguiente paso, estamos viendo una referencia a `convertToUpper.out.collect()`. + +¿Qué es esta parte de `collect()` y qué hace? + +Es un operador, por supuesto. Al igual que los operadores `splitCsv` y `map` que encontramos antes. +Esta vez el operador se llama `collect`, y se aplica al channel de salida producido por `convertToUpper`. + +El operador `collect` se usa para recolectar las salidas de múltiples llamadas al mismo process y empaquetarlas en un único elemento de channel. + +En el contexto de este workflow, está tomando los tres saludos en mayúsculas en el channel `convertToUpper.out` --que son tres elementos de channel separados, y normalmente serían manejados en llamadas separadas por el siguiente process-- y empaquetándolos en un único elemento. + +En términos más prácticos: si no aplicáramos `collect()` a la salida de `convertToUpper()` antes de alimentarla a `collectGreetings()`, Nextflow simplemente ejecutaría `collectGreetings()` independientemente en cada saludo, lo cual no lograría nuestro objetivo. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +En contraste, usar `collect()` nos permite tomar todos los saludos en mayúsculas separados producidos por el segundo paso del workflow y alimentarlos todos juntos a una única llamada en el tercer paso del pipeline. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +Así es como obtenemos todos los saludos de vuelta en el mismo archivo. + +Hay muchos otros [operadores](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) disponibles para aplicar transformaciones al contenido de los channels entre llamadas de process. + +Esto le da a los desarrolladores de pipelines mucha flexibilidad para personalizar la lógica de flujo de su pipeline. +La desventaja es que a veces puede hacer más difícil descifrar lo que está haciendo el pipeline. + +#### 2.3.5. Un parámetro de entrada puede tener un valor predeterminado + +Puede haber notado que `collectGreetings` toma una segunda entrada, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Esto pasa un parámetro CLI llamado `--batch` al workflow. +Sin embargo, cuando lanzamos el workflow antes, no especificamos un parámetro `--batch`. + +¿Qué está pasando ahí? +Eche un vistazo al bloque `params`: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Hay un valor predeterminado configurado en el workflow, así que no tenemos que proporcionarlo. +Pero si proporcionamos uno en la línea de comandos, el valor que especificamos se usará en lugar del predeterminado. + +Inténtelo: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Salida del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Debería ver nuevas salidas finales nombradas con su nombre de lote personalizado. + +??? abstract "Contenidos del directorio" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Este es un aspecto de la configuración de entrada, que cubriremos con más detalle en la Parte 3, pero por ahora lo importante es saber que los parámetros de entrada pueden tener valores predeterminados. + +#### 2.3.6. Un process puede producir múltiples salidas + +En la definición del process `collectGreetings`, vemos las siguientes declaraciones de salida: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Las cuales luego se refieren por el nombre dado con `emit:` en el bloque `publish:`: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Esto facilita pasar salidas específicas individualmente a otros processes en el workflow, en combinación con varios operadores. + +#### 2.3.7. Las salidas publicadas pueden organizarse + +En el bloque `output`, hemos usado rutas personalizadas para agrupar resultados intermedios para facilitar identificar solo las salidas finales del workflow. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Hay formas más sofisticadas de organizar las salidas publicadas; tocaremos algunas en la parte sobre configuración. + +!!! tip "¿Quiere aprender más sobre construir workflows?" + + Para cobertura detallada de la construcción de workflows de múltiples pasos, vea [Hello Nextflow Part 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Conclusión + +Comprende a un nivel básico cómo se construyen los workflows de múltiples pasos usando channels y operadores y cómo operan. +También ha visto que los processes pueden tomar múltiples entradas y producir múltiples salidas, y que estas pueden publicarse de manera estructurada. + +### ¿Qué sigue? + +Aprenda cómo los pipelines de Nextflow pueden modularizarse para promover la reutilización de código y la mantenibilidad. + +--- + +## 3. Ejecutar pipelines modularizados + +Hasta ahora, todos los workflows que hemos visto han consistido en un único archivo de workflow que contiene todo el código relevante. + +Sin embargo, los pipelines del mundo real típicamente se benefician de ser _modularizados_, lo que significa que el código se divide en diferentes archivos. +Esto puede hacer su desarrollo y mantenimiento más eficiente y sostenible. + +Aquí vamos a demostrar la forma más común de modularidad de código en Nextflow, que es el uso de **módulos**. + +En Nextflow, un **módulo** es una definición de process única que se encapsula por sí misma en un archivo de código independiente. +Para usar un módulo en un workflow, simplemente agrega una declaración de importación de una sola línea a su archivo de código de workflow; luego puede integrar el process en el workflow de la misma manera que normalmente lo haría. +Eso hace posible reutilizar definiciones de process en múltiples workflows sin producir múltiples copias del código. + +Hasta ahora hemos estado ejecutando workflows que tenían todos sus processes incluidos en un archivo de código monolítico. +Ahora vamos a ver cómo se ve cuando los processes se almacenan en módulos individuales. + +Por supuesto, hemos preparado nuevamente un workflow adecuado para propósitos de demostración, llamado `2c-modules.nf`, junto con un conjunto de módulos ubicados en el directorio `modules/`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Contenidos del directorio" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Puede ver que hay cuatro archivos de Nextflow, cada uno nombrado según uno de los processes. +Puede ignorar el archivo `cowpy.nf` por ahora; llegaremos a ese más tarde. + +### 3.1. Examinar el código + +Esta vez vamos a ver el código primero. +Comience abriendo el archivo de workflow `2c-modules.nf`. + +??? full-code "Archivo de código completo" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Puede ver que la lógica del workflow es exactamente la misma que en la versión anterior del workflow. +Sin embargo, el código del process ya no está en el archivo del workflow, y en su lugar hay declaraciones `include` que apuntan a archivos separados bajo `modules`. + +```groovy title="hello-modules.nf" linenums="3" +// Incluir módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Abra uno de esos archivos y encontrará el código para el process correspondiente. + +??? full-code "Archivo de código completo" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usar echo para imprimir 'Hello World!' a un archivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Como puede ver, el código del process no ha cambiado; simplemente se ha copiado en un archivo de módulo individual en lugar de estar en el archivo principal del workflow. +Lo mismo aplica a los otros dos processes. + +Así que veamos cómo se ve ejecutar esta nueva versión. + +### 3.2. Ejecutar el workflow + +Ejecute este comando en su terminal, con la bandera `-resume`: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Notará que las ejecuciones de process todas se almacenaron en caché exitosamente, lo que significa que Nextflow reconoció que ya ha hecho el trabajo solicitado, aunque el código se haya dividido y el archivo principal del workflow se haya renombrado. + +Nada de eso importa a Nextflow; lo que importa es el script de trabajo que se genera una vez que todo el código ha sido juntado y evaluado. + +!!! tip "Consejo" + + También es posible encapsular una sección de un workflow como un 'subworkflow' que puede importarse en un pipeline más grande, pero eso está fuera del alcance de este curso. + + Puede aprender más sobre desarrollar workflows componibles en el Side Quest sobre [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/). + +### Conclusión + +Sabe cómo los processes pueden almacenarse en módulos independientes para promover la reutilización de código y mejorar la mantenibilidad. + +### ¿Qué sigue? + +Aprenda a usar contenedores para gestionar dependencias de software. + +--- + +## 4. Usar software en contenedores + +Hasta ahora los workflows que hemos usado como ejemplos solo necesitaban ejecutar operaciones de procesamiento de texto muy básicas usando herramientas UNIX disponibles en nuestro entorno. + +Sin embargo, los pipelines del mundo real típicamente requieren herramientas y paquetes especializados que no están incluidos por defecto en la mayoría de los entornos. +Usualmente, necesitaría instalar estas herramientas, gestionar sus dependencias y resolver cualquier conflicto. + +Todo eso es muy tedioso y molesto. +Una manera mucho mejor de abordar este problema es usar **contenedores**. + +Un **contenedor** es una unidad de software ligera, independiente y ejecutable creada a partir de una **imagen** de contenedor que incluye todo lo necesario para ejecutar una aplicación incluyendo código, bibliotecas del sistema y configuraciones. + +!!! tip "Consejo" + + Enseñamos esto usando la tecnología [Docker](https://www.docker.com/get-started/), pero Nextflow soporta [varias otras tecnologías de contenedores](https://www.nextflow.io/docs/latest/container.html#) también. + +### 4.1. Usar un contenedor directamente + +Primero, intentemos interactuar con un contenedor directamente. +Esto ayudará a solidificar su comprensión de qué son los contenedores antes de que comencemos a usarlos en Nextflow. + +#### 4.1.1. Descargar la imagen del contenedor + +Para usar un contenedor, usualmente descarga o "pull" una imagen de contenedor de un registro de contenedores, y luego ejecuta la imagen del contenedor para crear una instancia de contenedor. + +La sintaxis general es la siguiente: + +```bash title="Sintaxis" +docker pull '<container>' +``` + +- `docker pull` es la instrucción al sistema de contenedores para descargar una imagen de contenedor de un repositorio. +- `'<container>'` es la dirección URI de la imagen del contenedor. + +Como ejemplo, descarguemos una imagen de contenedor que contiene [cowpy](https://github.com/jeffbuttars/cowpy), una implementación en python de una herramienta llamada `cowsay` que genera arte ASCII para mostrar entradas de texto arbitrarias de una manera divertida. + +Hay varios repositorios donde puede encontrar contenedores publicados. +Usamos el servicio [Seqera Containers](https://seqera.io/containers/) para generar esta imagen de contenedor Docker del paquete Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Ejecute el comando completo de descarga: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Salida del comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Esto le dice al sistema que descargue la imagen especificada. +Una vez que la descarga esté completa, tiene una copia local de la imagen del contenedor. + +#### 4.1.2. Iniciar el contenedor + +Los contenedores pueden ejecutarse como un comando único, pero también puede usarlos interactivamente, lo que le da un prompt de shell dentro del contenedor y le permite jugar con el comando. + +La sintaxis general es la siguiente: + +```bash title="Sintaxis" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'` es la instrucción al sistema de contenedores para iniciar una instancia de contenedor a partir de una imagen de contenedor y ejecutar un comando en él. +- `--rm` le dice al sistema que apague la instancia del contenedor después de que el comando se haya completado. + +Completamente ensamblado, el comando de ejecución del contenedor se ve así: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Ejecute ese comando, y debería ver que su prompt cambia a algo como `(base) root@b645838b3314:/tmp#`, lo que indica que ahora está dentro del contenedor. + +Puede verificar esto ejecutando `ls` para listar contenidos del directorio: + +```bash +ls / +``` + +??? success "Salida del comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Puede ver que el sistema de archivos dentro del contenedor es diferente del sistema de archivos en su sistema host. + +!!! tip "Consejo" + + Cuando ejecuta un contenedor, está aislado del sistema host por defecto. + Esto significa que el contenedor no puede acceder a ningún archivo en el sistema host a menos que explícitamente lo permita especificando que quiere montar un volumen como parte del comando `docker run` usando la siguiente sintaxis: + + ```bash title="Sintaxis" + -v <outside_path>:<inside_path> + ``` + + Esto efectivamente establece un túnel a través de la pared del contenedor que puede usar para acceder a esa parte de su sistema de archivos. + + Esto se cubre con más detalle en [Part 5 of Hello Nextflow](../hello_nextflow/05_hello_containers.md). + +#### 4.1.3. Ejecutar la herramienta `cowpy` + +Desde dentro del contenedor, puede ejecutar el comando `cowpy` directamente. + +```bash +cowpy "Hello Containers" +``` + +??? success "Salida del comando" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Esto produce arte ASCII del personaje de vaca predeterminado (o 'cowacter') con un globo de diálogo que contiene el texto que especificamos. + +Ahora que ha probado el uso básico, puede intentar darle algunos parámetros. +Por ejemplo, la documentación de la herramienta dice que podemos establecer el personaje con `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Salida del comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Esta vez la salida de arte ASCII muestra el pingüino de Linux, Tux, porque especificamos el parámetro `-c tux`. + +Ya que está dentro del contenedor, puede ejecutar el comando cowpy tantas veces como quiera, variando los parámetros de entrada, sin tener que preocuparse por instalar ninguna biblioteca en su sistema mismo. + +??? tip "Otros personajes disponibles" + + Use la bandera '-c' para elegir un personaje diferente, incluyendo: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Siéntase libre de jugar con esto. +Cuando haya terminado, salga del contenedor usando el comando `exit`: + +```bash +exit +``` + +Se encontrará de vuelta en su shell normal. + +### 4.2. Usar un contenedor en un workflow + +Cuando ejecutamos un pipeline, queremos poder decirle a Nextflow qué contenedor usar en cada paso, e importantemente, queremos que maneje todo ese trabajo que acabamos de hacer: descargar el contenedor, iniciarlo, ejecutar el comando y destruir el contenedor cuando haya terminado. + +Buenas noticias: eso es exactamente lo que Nextflow va a hacer por nosotros. +Solo necesitamos especificar un contenedor para cada process. + +Para demostrar cómo funciona esto, hicimos otra versión de nuestro workflow que ejecuta `cowpy` en el archivo de saludos recolectados producido en el tercer paso. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Esto debería producir un archivo que contiene el arte ASCII con los tres saludos en el globo de diálogo. + +#### 4.2.1. Examinar el código + +El workflow es muy similar al anterior, más el paso extra para ejecutar `cowpy`. + +??? full-code "Archivo de código completo" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Incluir módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emitir un saludo + sayHello(greeting_ch) + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + // recopilar todos los saludos en un archivo + collectGreetings(convertToUpper.out.collect(), params.batch) + // generar arte ASCII de los saludos con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Puede ver que este workflow importa un process `cowpy` de un archivo de módulo, y lo llama en la salida de la llamada `collectGreetings()`, más un parámetro de entrada llamado `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// generar arte ASCII con cowpy +cowpy(collectGreetings.out, params.character) +``` + +El process `cowpy`, que envuelve el comando cowpy para generar arte ASCII, está definido en el módulo `cowpy.nf`. + +??? full-code "Archivo de código completo" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +El process `cowpy` requiere dos entradas: la ruta a un archivo de entrada que contiene el texto para poner en el globo de diálogo (`input_file`), y un valor para la variable de personaje. + +Importantemente, también incluye la línea `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`, que apunta a la URI del contenedor que usamos antes. + +#### 4.2.2. Verificar que Docker esté habilitado en la configuración + +Vamos a anticipar ligeramente la Parte 3 de este curso de entrenamiento introduciendo el archivo de configuración `nextflow.config`, que es una de las principales formas que ofrece Nextflow para configurar la ejecución de workflows. +Cuando un archivo llamado `nextflow.config` está presente en el directorio actual, Nextflow lo cargará automáticamente y aplicará cualquier configuración que contenga. + +Para ese fin, incluimos un archivo `nextflow.config` con una sola línea de código que habilita Docker. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Esta configuración le dice a Nextflow que use Docker para cualquier process que especifique un contenedor compatible. + +!!! tip "Consejo" + + Es técnicamente posible habilitar la ejecución de Docker desde la línea de comandos, por ejecución, usando el parámetro `-with-docker <container>`. + Sin embargo, eso solo nos permite especificar un contenedor para todo el workflow, mientras que el enfoque que acabamos de mostrarle le permite especificar un contenedor diferente por process. + Este último es mucho mejor para modularidad, mantenimiento de código y reproducibilidad. + +#### 4.2.3. Ejecutar el workflow + +Solo para recapitular, esto es lo que estamos a punto de ejecutar: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +¿Cree que va a funcionar? + +Ejecutemos el workflow con la bandera `-resume`, y especifiquemos que queremos que el personaje sea el turkey. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +Los primeros tres pasos se almacenaron en caché ya que los hemos ejecutado antes, pero el process `cowpy` es nuevo así que realmente se ejecuta. + +Puede encontrar la salida del paso `cowpy` en el directorio `results`. + +??? abstract "Contenido del archivo" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Puede ver que el personaje está diciendo todos los saludos, ya que se ejecutó en el archivo de saludos recolectados en mayúsculas. + +Más al punto, pudimos ejecutar esto como parte de nuestro pipeline sin tener que hacer una instalación propiamente dicha de cowpy y todas sus dependencias. +Y ahora podemos compartir el pipeline con colaboradores y hacer que lo ejecuten en su infraestructura sin que ellos necesiten instalar nada tampoco, aparte de Docker o una de sus alternativas (como Singularity/Apptainer) como se mencionó anteriormente. + +#### 4.2.4. Inspeccionar cómo Nextflow lanzó la tarea en contenedor + +Como coda final a esta sección, echemos un vistazo al subdirectorio de trabajo para una de las llamadas del process `cowpy` para obtener un poco más de información sobre cómo trabaja Nextflow con contenedores bajo el capó. + +Verifique la salida de su comando `nextflow run` para encontrar la ruta al subdirectorio de trabajo para el process `cowpy`. +Mirando lo que obtuvimos para la ejecución mostrada arriba, la línea de registro de consola para el process `cowpy` comienza con `[7f/caf718]`. +Eso corresponde a la siguiente ruta de directorio truncada: `work/7f/caf718`. + +En ese directorio, encontrará el archivo `.command.run` que contiene todos los comandos que Nextflow ejecutó en su nombre en el curso de ejecutar el pipeline. + +??? abstract "Contenido del archivo" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + ... + ``` + +Si busca `nxf_launch` en este archivo, debería ver algo como esto: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh +} +``` + +Este comando de lanzamiento muestra que Nextflow está usando un comando `docker run` muy similar para lanzar la llamada del process como hicimos cuando lo ejecutamos manualmente. +También monta el subdirectorio de trabajo correspondiente en el contenedor, establece el directorio de trabajo dentro del contenedor en consecuencia, y ejecuta nuestro script bash con plantilla en el archivo `.command.sh`. + +¡Esto confirma que todo el trabajo duro que tuvimos que hacer manualmente en la sección anterior ahora lo hace Nextflow por nosotros! + +### Conclusión + +Comprende qué papel juegan los contenedores en la gestión de versiones de herramientas de software y asegurar la reproducibilidad. + +Más generalmente, tiene una comprensión básica de cuáles son los componentes principales de los pipelines de Nextflow del mundo real y cómo están organizados. +Conoce los fundamentos de cómo Nextflow puede procesar múltiples entradas eficientemente, ejecutar workflows compuestos de múltiples pasos conectados juntos, aprovechar componentes de código modulares, y utilizar contenedores para mayor reproducibilidad y portabilidad. + +### ¿Qué sigue? + +¡Tome otro descanso! Esa fue una gran cantidad de información sobre cómo funcionan los pipelines de Nextflow. + +En la última sección de este entrenamiento, vamos a profundizar más en el tema de la configuración. +Aprenderá cómo configurar la ejecución de su pipeline para adaptarlo a su infraestructura así como gestionar la configuración de entradas y parámetros. + +--- + +## Cuestionario + +<quiz> +¿Por qué Nextflow crea un directorio de tarea separado para cada llamada de process? +- [ ] Para mejorar la velocidad de ejecución +- [ ] Para reducir el uso de memoria +- [x] Para aislar ejecuciones y evitar colisiones entre salidas +- [ ] Para habilitar la compresión paralela de archivos + +Más información: [1.3. Encontrar las salidas y registros originales](#13-encontrar-las-salidas-y-registros-originales) +</quiz> + +<quiz> +¿Qué hace la opción `-ansi-log false` al ejecutar un workflow? +- [ ] Deshabilita toda la salida de consola +- [x] Elimina el color de la salida +- [x] Muestra todas las rutas de directorio de tarea en lugar de condensarlas en una línea +- [ ] Habilita el modo de depuración detallado + +Más información: [1.3.2. Hacer que la terminal muestre más detalles](#132-hacer-que-la-terminal-muestre-más-detalles) + +También puede usar cualquiera de las siguientes variables de entorno si prefiere este estilo: + +```bash +export NXF_ANSI_LOG=0 +# o +export NO_COLOR=1 +``` + +</quiz> + +<quiz> +En el código `#!groovy channel.fromPath(params.input).splitCsv().map { line -> line[0] }`, ¿qué hace `#!groovy .map { line -> line[0] }`? +- [ ] Filtra líneas vacías +- [ ] Ordena las líneas alfabéticamente +- [x] Extrae la primera columna de cada fila CSV +- [ ] Cuenta el número de líneas + +Más información: [1.4.1. Cargar los datos de entrada desde el CSV](#141-cargar-los-datos-de-entrada-desde-el-csv) +</quiz> + +<quiz> +¿Por qué es importante incluir el valor de entrada en los nombres de archivos de salida (por ejemplo, `#!groovy "${greeting}-output.txt"`)? +- [ ] Para mejorar la velocidad de procesamiento +- [ ] Para habilitar la funcionalidad resume +- [x] Para evitar que los archivos de salida se sobrescriban entre sí al procesar múltiples entradas +- [ ] Para facilitar la compresión de archivos + +Más información: [1.4.3. Cómo se nombran las salidas](#143-cómo-se-nombran-las-salidas) +</quiz> + +<quiz> +¿Cuál es el propósito de la declaración `include` en un workflow modularizado? +- [ ] Copiar código de process al archivo de workflow +- [x] Importar una definición de process de un archivo de módulo externo +- [ ] Incluir configuraciones +- [ ] Agregar comentarios de documentación + +Más información: [3. Ejecutar pipelines modularizados](#3-ejecutar-pipelines-modularizados) +</quiz> + +<quiz> +Cuando modulariza un workflow y lo ejecuta con `-resume`, ¿qué sucede? +- [ ] El almacenamiento en caché está deshabilitado para processes modulares +- [ ] Todas las tareas deben re-ejecutarse +- [x] El almacenamiento en caché funciona normalmente basándose en los scripts de trabajo generados +- [ ] Solo el archivo principal del workflow se almacena en caché + +Más información: [3.2. Ejecutar el workflow](#32-ejecutar-el-workflow) +</quiz> + +<quiz> +¿Qué especifica la directiva `container` en una definición de process? +- [ ] El directorio de trabajo para el process +- [ ] La asignación máxima de memoria +- [x] La URI de la imagen del contenedor a usar para ejecutar el process +- [ ] El formato del archivo de salida + +Más información: [4.2. Usar un contenedor en un workflow](#42-usar-un-contenedor-en-un-workflow) +</quiz> + +<quiz> +En el archivo `.command.run`, ¿qué contiene la función `nxf_launch`? +- [ ] La información de versión de Nextflow +- [ ] Los parámetros del workflow +- [x] El comando `docker run` con montajes de volumen y configuraciones de contenedor +- [ ] Las declaraciones de entrada del process + +Más información: [4.2.4. Inspeccionar cómo Nextflow lanzó la tarea en contenedor](#424-inspeccionar-cómo-nextflow-lanzó-la-tarea-en-contenedor) +</quiz> + +<quiz> +¿Qué maneja automáticamente Nextflow al ejecutar un process en contenedor? (Seleccione todas las que apliquen) +- [x] Descargar la imagen del contenedor si es necesario +- [x] Montar el directorio de trabajo en el contenedor +- [x] Ejecutar el script del process dentro del contenedor +- [x] Limpiar la instancia del contenedor después de la ejecución + +Más información: [4. Usar software en contenedores](#4-usar-software-en-contenedores) +</quiz> diff --git a/docs/es/docs/nextflow_run/03_config.md b/docs/es/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..6db5156393 --- /dev/null +++ b/docs/es/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Parte 3: Configuración de ejecución + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta sección explorará cómo gestionar la configuración de un pipeline de Nextflow para personalizar su comportamiento, adaptarlo a diferentes entornos y optimizar el uso de recursos _sin alterar una sola línea del código del workflow en sí_. + +Hay múltiples formas de hacer esto, que pueden usarse en combinación y se interpretan según el orden de precedencia descrito [aquí](https://www.nextflow.io/docs/latest/config.html). + +En esta parte del curso, le mostraremos el mecanismo de archivo de configuración más simple y común, el archivo `nextflow.config`, que ya encontró en la sección sobre contenedores en la Parte 2. + +Revisaremos componentes esenciales de la configuración de Nextflow como directivas de process, executors, perfiles y archivos de parámetros. +Al aprender a utilizar estas opciones de configuración efectivamente, puede aprovechar al máximo la flexibilidad, escalabilidad y rendimiento de los pipelines de Nextflow. + +Para ejercitar estos elementos de configuración, vamos a ejecutar una copia fresca del workflow que ejecutamos por última vez al final de la Parte 2 de este curso de entrenamiento, renombrado `3-main.nf`. + +Si no está familiarizado con el pipeline Hello o podría usar un recordatorio, vea [esta página de información](../info/hello_pipeline.md). + +--- + +## 1. Gestionar parámetros de entrada del workflow + +??? example "Escenario" + + Ha descargado un pipeline y quiere ejecutarlo repetidamente con los mismos archivos de entrada y configuraciones, pero no quiere escribir todos los parámetros cada vez. + O quizás está configurando el pipeline para un colega que no está cómodo con argumentos de línea de comandos. + +Vamos a comenzar con un aspecto de la configuración que es simplemente una extensión de lo que hemos estado trabajando hasta ahora: la gestión de parámetros de entrada. + +Actualmente, nuestro workflow está configurado para aceptar varios valores de parámetros a través de la línea de comandos, declarados en un bloque `params` en el script del workflow mismo. +Uno tiene un valor predeterminado establecido como parte de su declaración. + +Sin embargo, puede querer establecer valores predeterminados para todos ellos, o anular el predeterminado existente sin tener que especificar parámetros en la línea de comandos, o modificar el archivo de script original. + +Hay múltiples formas de hacer eso; le mostraremos tres formas básicas que son muy comúnmente usadas. + +### 1.1. Configurar valores en `nextflow.config` + +Este es el enfoque más simple, aunque es posiblemente el menos flexible ya que el archivo principal `nextflow.config` no es algo que quiera estar editando para cada ejecución. +Pero tiene la ventaja de separar las preocupaciones de _declarar_ los parámetros en el workflow (que definitivamente pertenece allí) versus suministrar _valores predeterminados_, que están más en casa en un archivo de configuración. + +Hagamos esto en dos pasos. + +#### 1.1.1. Crear un bloque `params` en el archivo de configuración + +Haga los siguientes cambios de código en el archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Note que no simplemente copiamos el bloque `params` del workflow al archivo de configuración. +Para el parámetro `batch` que ya tenía un valor predeterminado declarado, la sintaxis es un poco diferente. +En el archivo del workflow, esa es una declaración tipada. +En la configuración, esas son asignaciones de valores. + +Técnicamente, esto es suficiente para anular los valores predeterminados aún especificados en el archivo del workflow. +Podría modificar el valor predeterminado para `batch` y ejecutar el workflow para asegurarse de que el valor establecido en el archivo de configuración anula el establecido en el archivo del workflow. + +Pero en el espíritu de mover la configuración completamente al archivo de configuración, eliminemos ese valor predeterminado del archivo del workflow por completo. + +#### 1.1.2. Eliminar el valor predeterminado para `batch` en el archivo del workflow + +Haga el siguiente cambio de código en el archivo de workflow `3-main.nf`: + +=== "Después" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Ahora el archivo del workflow en sí no establece ningún valor predeterminado para estos parámetros. + +#### 1.1.3. Ejecutar el pipeline + +Probemos que funciona correctamente sin especificar ningún parámetro en la línea de comandos. + +```bash +nextflow run 3-main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente. + +La salida final de arte ASCII está en el directorio `results/3-main/`, bajo el nombre `cowpy-COLLECTED-batch-output.txt`, igual que antes. + +??? abstract "Contenido del archivo" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funcionalmente, este movimiento no ha cambiado nada, pero conceptualmente es un poco más limpio tener los valores predeterminados establecidos en el archivo de configuración. + +### 1.2. Usar un archivo de configuración específico para la ejecución + +??? example "Escenario" + + Quiere experimentar con diferentes configuraciones sin modificar su archivo de configuración principal. + +Puede hacer eso creando un nuevo archivo `nextflow.config` en un subdirectorio que usará como directorio de trabajo para sus experimentos. + +#### 1.2.1. Crear el directorio de trabajo con una configuración en blanco + +Comencemos creando un nuevo directorio y moviéndonos a él: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Luego, cree un archivo de configuración en blanco en ese directorio: + +```bash +touch nextflow.config +``` + +Esto produce un archivo vacío. + +#### 1.2.2. Configurar la configuración experimental + +Ahora abra el nuevo archivo y agregue los parámetros que quiere personalizar: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Note que la ruta al archivo de entrada debe reflejar la estructura del directorio. + +#### 1.2.3. Ejecutar el pipeline + +Ahora podemos ejecutar nuestro pipeline desde dentro de nuestro nuevo directorio de trabajo. +¡Asegúrese de adaptar la ruta en consecuencia! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Esto creará un nuevo conjunto de directorios bajo `tux-run/` incluyendo `tux-run/work/` y `tux-run/results/`. + +En esta ejecución, Nextflow combina el `nextflow.config` en nuestro directorio actual con el `nextflow.config` en el directorio raíz del pipeline, y por lo tanto anula el personaje predeterminado (turkey) con el personaje tux. + +El archivo de salida final debería contener el personaje tux diciendo los saludos. + +??? abstract "Contenido del archivo" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Eso es todo; ahora tiene un espacio para experimentar sin modificar su configuración 'normal'. + +!!! warning "Advertencia" + + ¡Asegúrese de volver al directorio anterior antes de pasar a la siguiente sección! + + ```bash + cd .. + ``` + +Ahora veamos otra forma útil de establecer valores de parámetros. + +### 1.3. Usar un archivo de parámetros + +??? example "Escenario" + + Necesita compartir parámetros de ejecución exactos con un colaborador, o registrarlos para una publicación. + +El enfoque de subdirectorio funciona muy bien para experimentar, pero implica un poco de configuración y requiere que adapte las rutas en consecuencia. +Hay un enfoque más simple para cuando quiere ejecutar su pipeline con un conjunto específico de valores, o permitir que alguien más lo haga con mínimo esfuerzo. + +Nextflow nos permite especificar parámetros a través de un archivo de parámetros en formato YAML o JSON, lo que hace muy conveniente gestionar y distribuir conjuntos alternativos de valores predeterminados, por ejemplo, así como valores de parámetros específicos de la ejecución. + +#### 1.3.1. Examinar el archivo de parámetros de ejemplo + +Para demostrar esto, proporcionamos un archivo de parámetros de ejemplo en el directorio actual, llamado `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Este archivo de parámetros contiene un par clave-valor para cada una de las entradas que queremos especificar. +Note el uso de dos puntos (`:`) en lugar de signos de igual (`=`) si compara la sintaxis con el archivo de configuración. +El archivo config está escrito en Groovy, mientras que el archivo de parámetros está escrito en YAML. + +!!! info "Información" + + También proporcionamos una versión JSON del archivo de parámetros como ejemplo pero no vamos a ejecutar con él aquí. + Siéntase libre de probar ese por su cuenta. + +#### 1.3.2. Ejecutar el pipeline + +Para ejecutar el workflow con este archivo de parámetros, simplemente agregue `-params-file <filename>` al comando base. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +El archivo de salida final debería contener el personaje stegosaurus diciendo los saludos. + +??? abstract "Contenido del archivo" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usar un archivo de parámetros puede parecer excesivo cuando solo tiene unos pocos parámetros para especificar, pero algunos pipelines esperan docenas de parámetros. +En esos casos, usar un archivo de parámetros nos permitirá proporcionar valores de parámetros en tiempo de ejecución sin tener que escribir líneas de comando masivas y sin modificar el script del workflow. + +También facilita distribuir conjuntos de parámetros a colaboradores, o como información de apoyo para una publicación, por ejemplo. +Esto hace su trabajo más reproducible por otros. + +### Conclusión + +Sabe cómo aprovechar las opciones de configuración clave para gestionar entradas del workflow. + +### ¿Qué sigue? + +Aprenda cómo gestionar dónde y cómo se publican las salidas de su workflow. + +--- + +## 2. Gestionar salidas del workflow + +??? example "Escenario" + + Su pipeline publica salidas en un directorio codificado, pero quiere organizar los resultados por proyecto o nombre de experimento sin editar el código del workflow cada vez. + +El workflow que heredamos usa rutas para declaraciones de salida a nivel de workflow, lo cual no es terriblemente flexible e implica mucha repetición. + +Veamos algunas formas comunes en que podría configurar esto para que sea más flexible. + +### 2.1. Personalizar el nombre del directorio `outputDir` + +Cada versión del workflow que hemos ejecutado hasta ahora ha publicado sus salidas en un subdirectorio diferente codificado en las definiciones de salida. + +Cambiemos eso para usar un parámetro configurable por el usuario. +Podríamos crear un parámetro completamente nuevo para esto, pero usemos el parámetro `batch` ya que está ahí mismo. + +#### 2.1.1. Establecer un valor para `outputDir` en el archivo de configuración + +La ruta que Nextflow usa para publicar salidas está controlada por la opción `outputDir`. +Para cambiar la ruta para todas las salidas, puede establecer un valor para esta opción en el archivo de configuración `nextflow.config`. + +Agregue el siguiente código al archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Esto reemplazará la ruta predeterminada incorporada, `results/`, con `results/` más el valor del parámetro `batch` como subdirectorio. +También podría cambiar la parte `results` si quisiera. + +Para un cambio temporal, podría establecer esta opción desde la línea de comandos usando el parámetro `-output-dir` en su comando (pero entonces no podría usar el valor del parámetro `batch`). + +#### 2.1.2. Eliminar la parte repetida de la ruta codificada + +Todavía tenemos un subdirectorio codificado en las opciones de salida, así que eliminémoslo ahora. + +Haga los siguientes cambios de código en el archivo del workflow: + +=== "Después" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +También podríamos haber simplemente agregado `${params.batch}` a cada ruta en lugar de modificar el `outputDir` predeterminado, pero esto es más conciso. + +#### 2.1.3. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `outdir` desde la línea de comandos. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/outdir/`. + +??? abstract "Contenidos del directorio" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Puede combinar este enfoque con definiciones de ruta personalizadas para construir cualquier jerarquía de directorios que desee. + +### 2.2. Organizar salidas por process + +Una forma popular de organizar las salidas más es hacerlo por process, _es decir_, crear subdirectorios para cada process ejecutado en el pipeline. + +#### 2.2.1. Reemplazar las rutas de salida por una referencia a los nombres de process + +Todo lo que necesita hacer es referenciar el nombre del process como `<task>.name` en la declaración de ruta de salida. + +Haga los siguientes cambios en el archivo del workflow: + +=== "Después" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Esto elimina los elementos codificados restantes de la configuración de ruta de salida. + +#### 2.2.2. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `pnames` desde la línea de comandos. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/pnames/`, y están agrupadas por process. + +??? abstract "Contenidos del directorio" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Note que aquí hemos borrado la distinción entre `intermediates` versus salidas finales estando en el nivel superior. +Por supuesto, podría mezclar y combinar estos enfoques, por ejemplo estableciendo la ruta de la primera salida como `intermediates/${sayHello.name}` + +### 2.3. Establecer el modo de publicación a nivel de workflow + +Finalmente, en el espíritu de reducir la cantidad de código repetitivo, podemos reemplazar las declaraciones `mode` por salida con una sola línea en la configuración. + +#### 2.3.1. Agregar `workflow.output.mode` al archivo de configuración + +Agregue el siguiente código al archivo `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Al igual que la opción `outputDir`, dar a `workflow.output.mode` un valor en el archivo de configuración sería suficiente para anular lo que está establecido en el archivo del workflow, pero eliminemos el código innecesario de todos modos. + +#### 2.3.2. Eliminar el modo de salida del archivo del workflow + +Haga los siguientes cambios en el archivo del workflow: + +=== "Después" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +¿Eso es más conciso, no? + +#### 2.3.3. Ejecutar el pipeline + +Probemos que funciona correctamente, estableciendo el nombre del lote a `outmode` desde la línea de comandos. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Esto todavía produce la misma salida que anteriormente, excepto que esta vez encontramos nuestras salidas bajo `results/outmode/`. +Todavía son todas copias propias, no symlinks. + +??? abstract "Contenidos del directorio" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +La razón principal por la que aún podría querer usar la forma de establecer el modo por salida es si quiere mezclar y combinar dentro del mismo workflow, _es decir_, tener algunas salidas copiadas y otras como symlinks. + +Hay muchas otras opciones que puede personalizar de esta manera, pero esperamos que esto le dé una idea del rango de opciones y cómo utilizarlas efectivamente para adaptarlas a sus preferencias. + +### Conclusión + +Sabe cómo controlar el nombre y estructura de los directorios donde se publican sus salidas, así como el modo de publicación de salidas del workflow. + +### ¿Qué sigue? + +Aprenda cómo adaptar la configuración de su workflow a su entorno de cómputo, comenzando con la tecnología de empaquetado de software. + +--- + +## 3. Seleccionar una tecnología de empaquetado de software + +Hasta ahora hemos estado viendo elementos de configuración que controlan cómo entran las entradas y dónde salen las salidas. Ahora es tiempo de enfocarnos más específicamente en adaptar la configuración de su workflow a su entorno de cómputo. + +El primer paso en ese camino es especificar de dónde van a venir los paquetes de software que se ejecutarán en cada paso. +¿Ya están instalados en el entorno de cómputo local? +¿Necesitamos recuperar imágenes y ejecutarlas a través de un sistema de contenedores? +¿O necesitamos recuperar paquetes de Conda y construir un entorno Conda local? + +En la primera parte de este curso de entrenamiento (Partes 1-4) solo usamos software instalado localmente en nuestro workflow. +Luego en la Parte 5, introdujimos contenedores Docker y el archivo `nextflow.config`, que usamos para habilitar el uso de contenedores Docker. + +Ahora veamos cómo podemos configurar una opción alternativa de empaquetado de software a través del archivo `nextflow.config`. + +### 3.1. Deshabilitar Docker y habilitar Conda en el archivo de configuración + +??? example "Escenario" + + Está moviendo su pipeline a un clúster HPC donde Docker no está permitido por razones de seguridad. + El clúster soporta Singularity y Conda, así que necesita cambiar su configuración en consecuencia. + +Nextflow soporta múltiples tecnologías de contenedores incluyendo Singularity (que se usa más ampliamente en HPC), así como gestores de paquetes de software como Conda. + +Podemos cambiar nuestro archivo de configuración para usar Conda en lugar de Docker. +Para hacerlo, cambiemos el valor de `docker.enabled` a `false`, y agreguemos una directiva habilitando el uso de Conda: + +=== "Después" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Esto permitirá a Nextflow crear y utilizar entornos Conda para processes que tengan paquetes Conda especificados. +Lo que significa que ahora necesitamos agregar uno de esos a nuestro process `cowpy`. + +### 3.2. Especificar un paquete Conda en la definición del process + +Ya hemos recuperado la URI para un paquete Conda que contiene la herramienta `cowpy`: `conda-forge::cowpy==1.1.5` + +Ahora agregamos la URI a la definición del process `cowpy` usando la directiva `conda`: + +=== "Después" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Para ser claros, no estamos _reemplazando_ la directiva `docker`, estamos _agregando_ una opción alternativa. + +!!! tip "Consejo" + + Hay algunas formas diferentes de obtener la URI para un paquete conda dado. + Recomendamos usar la consulta de búsqueda de [Seqera Containers](https://seqera.io/containers/), que le dará una URI que puede copiar y pegar, incluso si no planea crear un contenedor a partir de él. + +### 3.3. Ejecutar el workflow para verificar que puede usar Conda + +Probémoslo. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Salida del comando" + + ```console title="Salida" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Esto debería funcionar sin problemas y producir las mismas salidas que anteriormente bajo `results/conda`. + +Detrás de escena, Nextflow ha recuperado los paquetes Conda y creado el entorno, lo cual normalmente requiere un poco de trabajo; ¡así que es bueno que no tengamos que hacer nada de eso nosotros mismos! + +!!! info "Información" + + Esto se ejecuta rápidamente porque el paquete `cowpy` es bastante pequeño, pero si está trabajando con paquetes grandes, puede tomar un poco más de tiempo de lo usual la primera vez, y puede ver que la salida de la consola se queda 'atascada' por un minuto o más antes de completarse. + Esto es normal y se debe al trabajo extra que Nextflow hace la primera vez que usa un paquete nuevo. + +Desde nuestro punto de vista, parece que funciona exactamente igual que ejecutar con Docker, aunque en el backend la mecánica es un poco diferente. + +Esto significa que estamos listos para ejecutar con entornos Conda si es necesario. + +??? info "Mezclar y combinar Docker y Conda" + + Dado que estas directivas se asignan por process, es posible 'mezclar y combinar', _es decir_, configurar algunos de los processes en su workflow para ejecutarse con Docker y otros con Conda, por ejemplo, si la infraestructura de cómputo que está usando soporta ambos. + En ese caso, habilitaría tanto Docker como Conda en su archivo de configuración. + Si ambos están disponibles para un process dado, Nextflow priorizará los contenedores. + + Y como se señaló anteriormente, Nextflow soporta múltiples otras tecnologías de empaquetado de software y contenedores, así que no está limitado a solo esas dos. + +### Conclusión + +Sabe cómo configurar qué paquete de software debe usar cada process, y cómo cambiar entre tecnologías. + +### ¿Qué sigue? + +Aprenda cómo cambiar la plataforma de ejecución usada por Nextflow para hacer realmente el trabajo. + +--- + +## 4. Seleccionar una plataforma de ejecución + +??? example "Escenario" + + Ha estado desarrollando y probando su pipeline en su laptop, pero ahora necesita ejecutarlo en miles de muestras. + Su institución tiene un clúster HPC con un scheduler Slurm que le gustaría usar en su lugar. + +Hasta ahora, hemos estado ejecutando nuestro pipeline con el executor local. +Este ejecuta cada tarea en la máquina donde se está ejecutando Nextflow. +Cuando Nextflow comienza, mira los CPUs y memoria disponibles. +Si los recursos de las tareas listas para ejecutarse exceden los recursos disponibles, Nextflow retendrá las últimas tareas de la ejecución hasta que una o más de las tareas anteriores hayan terminado, liberando los recursos necesarios. + +El executor local es conveniente y eficiente, pero está limitado a esa única máquina. Para cargas de trabajo muy grandes, puede descubrir que su máquina local es un cuello de botella, ya sea porque tiene una sola tarea que requiere más recursos de los que tiene disponibles, o porque tiene tantas tareas que esperar a que una sola máquina las ejecute tomaría demasiado tiempo. + +Nextflow soporta [muchos backends de ejecución diferentes](https://www.nextflow.io/docs/latest/executor.html), incluyendo schedulers HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor y otros) así como backends de ejecución en la nube (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes y más). + +### 4.1. Apuntar a un backend diferente + +La elección del executor se establece mediante una directiva de process llamada `executor`. +Por defecto está establecido a `local`, así que la siguiente configuración está implícita: + +```groovy title="Configuración incorporada" +process { + executor = 'local' +} +``` + +Para establecer el executor para apuntar a un backend diferente, simplemente especificaría el executor que quiere usando una sintaxis similar a la descrita anteriormente para asignaciones de recursos (vea la [documentación](https://www.nextflow.io/docs/latest/executor.html) para todas las opciones). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Advertencia" + + No podemos realmente probar esto en el entorno de entrenamiento porque no está configurado para conectarse a un HPC. + +### 4.2. Lidiar con sintaxis específica del backend para parámetros de ejecución + +La mayoría de las plataformas de computación de alto rendimiento permiten (y a veces requieren) que especifique ciertos parámetros como solicitudes y limitaciones de asignación de recursos (por ejemplo, número de CPUs y memoria) y nombre de la cola de trabajos a usar. + +Desafortunadamente, cada uno de estos sistemas usa diferentes tecnologías, sintaxis y configuraciones para definir cómo un trabajo debe ser definido y enviado al scheduler relevante. + +??? abstract "Ejemplos" + + Por ejemplo, el mismo trabajo que requiere 8 CPUs y 4GB de RAM para ser ejecutado en la cola "my-science-work" necesita expresarse de diferentes maneras dependiendo del backend. + + ```bash title="Config para SLURM / enviar usando sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config para PBS / enviar usando qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config para SGE / enviar usando qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Afortunadamente, Nextflow simplifica todo esto. +Proporciona una sintaxis estandarizada para que pueda especificar las propiedades relevantes como `cpus`, `memory` y `queue` (vea la documentación para otras propiedades) solo una vez. +Luego, en tiempo de ejecución, Nextflow usará esas configuraciones para generar los scripts específicos del backend apropiados basados en la configuración del executor. + +Cubriremos esa sintaxis estandarizada en la siguiente sección. + +### Conclusión + +Ahora sabe cómo cambiar el executor para usar diferentes tipos de infraestructura de cómputo. + +### ¿Qué sigue? + +Aprenda cómo evaluar y expresar asignaciones y limitaciones de recursos en Nextflow. + +--- + +## 5. Controlar asignaciones de recursos de cómputo + +??? example "Escenario" + + Su pipeline sigue fallando en el clúster porque las tareas están siendo terminadas por exceder los límites de memoria. + O quizás le están cobrando por recursos que no está usando y quiere optimizar costos. + +La mayoría de las plataformas de computación de alto rendimiento permiten (y a veces requieren) que especifique ciertos parámetros de asignación de recursos como número de CPUs y memoria. + +Por defecto, Nextflow usará un solo CPU y 2GB de memoria para cada process. +Las directivas de process correspondientes se llaman `cpus` y `memory`, así que la siguiente configuración está implícita: + +```groovy title="Configuración incorporada" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Puede modificar estos valores, ya sea para todos los processes o para processes nombrados específicos, usando directivas de process adicionales en su archivo de configuración. +Nextflow las traducirá en las instrucciones apropiadas para el executor elegido. + +¿Pero cómo sabe qué valores usar? + +### 5.1. Ejecutar el workflow para generar un informe de utilización de recursos + +??? example "Escenario" + + No sabe cuánta memoria o CPU necesitan sus processes y quiere evitar desperdiciar recursos o que los trabajos sean terminados. + +Si no sabe de antemano cuánto CPU y memoria es probable que necesiten sus processes, puede hacer un perfilado de recursos, lo que significa que ejecuta el workflow con algunas asignaciones predeterminadas, registra cuánto usó cada process, y de ahí, estima cómo ajustar las asignaciones base. + +Convenientemente, Nextflow incluye herramientas incorporadas para hacer esto, y generará un informe para usted a petición. + +Para hacerlo, agregue `-with-report <filename>.html` a su línea de comandos. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +El informe es un archivo html, que puede descargar y abrir en su navegador. También puede hacer clic derecho en el explorador de archivos a la izquierda y hacer clic en `Show preview` para verlo en el entorno de entrenamiento. + +Tómese unos minutos para revisar el informe y ver si puede identificar algunas oportunidades para ajustar recursos. +Asegúrese de hacer clic en las pestañas que muestran los resultados de utilización como porcentaje de lo que fue asignado. +Hay [documentación](https://www.nextflow.io/docs/latest/reports.html) que describe todas las características disponibles. + +### 5.2. Establecer asignaciones de recursos para todos los processes + +El perfilado muestra que los processes en nuestro workflow de entrenamiento son muy ligeros, así que reduzcamos la asignación de memoria predeterminada a 1GB por process. + +Agregue lo siguiente a su archivo `nextflow.config`, antes de la sección de parámetros del pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Eso ayudará a reducir la cantidad de cómputo que consumimos. + +### 5.3. Establecer asignaciones de recursos para un process específico + +Al mismo tiempo, vamos a pretender que el process `cowpy` requiere más recursos que los otros, solo para poder demostrar cómo ajustar asignaciones para un process individual. + +=== "Después" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Con esta configuración, todos los processes solicitarán 1GB de memoria y un solo CPU (el predeterminado implícito), excepto el process `cowpy`, que solicitará 2GB y 2 CPUs. + +!!! info "Información" + + Si tiene una máquina con pocos CPUs y asigna un número alto por process, podría ver llamadas de process siendo encoladas detrás de otras. + Esto es porque Nextflow asegura que no solicitemos más CPUs de los que están disponibles. + +### 5.4. Ejecutar el workflow con la configuración actualizada + +Probemos eso, suministrando un nombre de archivo diferente para el informe de perfilado para que podamos comparar el rendimiento antes y después de los cambios de configuración. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Probablemente no notará ninguna diferencia real ya que esta es una carga de trabajo tan pequeña, pero este es el enfoque que usaría para analizar el rendimiento y los requisitos de recursos de un workflow del mundo real. + +Es muy útil cuando sus processes tienen diferentes requisitos de recursos. Le permite dimensionar correctamente las asignaciones de recursos que configura para cada process basándose en datos reales, no en conjeturas. + +!!! tip "Consejo" + + Esto es solo una pequeña muestra de lo que puede hacer para optimizar su uso de recursos. + Nextflow mismo tiene una [lógica de reintento dinámica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) muy elegante incorporada para reintentar trabajos que fallan debido a limitaciones de recursos. + Además, Seqera Platform ofrece herramientas impulsadas por IA para optimizar sus asignaciones de recursos automáticamente también. + +### 5.5. Agregar límites de recursos + +Dependiendo de qué executor de cómputo e infraestructura de cómputo esté usando, puede haber algunas restricciones sobre lo que puede (o debe) asignar. +Por ejemplo, su clúster puede requerir que permanezca dentro de ciertos límites. + +Puede usar la directiva `resourceLimits` para establecer las limitaciones relevantes. La sintaxis se ve así cuando está sola en un bloque process: + +```groovy title="Ejemplo de sintaxis" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow traducirá estos valores en las instrucciones apropiadas dependiendo del executor que especificó. + +No vamos a ejecutar esto, ya que no tenemos acceso a infraestructura relevante en el entorno de entrenamiento. +Sin embargo, si intentara ejecutar el workflow con asignaciones de recursos que excedan estos límites, luego busque el comando `sbatch` en el archivo de script `.command.run`, vería que las solicitudes que realmente se envían al executor están limitadas a los valores especificados por `resourceLimits`. + +??? info "Configuraciones de referencia institucionales" + + El proyecto nf-core ha compilado una [colección de archivos de configuración](https://nf-co.re/configs/) compartidos por varias instituciones alrededor del mundo, cubriendo una amplia gama de executors HPC y de nube. + + Esas configs compartidas son valiosas tanto para las personas que trabajan allí y por lo tanto pueden simplemente utilizar la configuración de su institución directamente, como también como modelo para personas que buscan desarrollar una configuración para su propia infraestructura. + +### Conclusión + +Sabe cómo generar un informe de perfilado para evaluar la utilización de recursos y cómo modificar las asignaciones de recursos para todos los processes y/o para processes individuales, así como establecer limitaciones de recursos para ejecutar en HPC. + +### ¿Qué sigue? + +Aprenda cómo configurar perfiles de configuración preestablecidos y cambiar entre ellos en tiempo de ejecución. + +--- + +## 6. Usar perfiles para cambiar entre configuraciones preestablecidas + +??? example "Escenario" + + Regularmente cambia entre ejecutar pipelines en su laptop para desarrollo y en el HPC de su institución para ejecuciones de producción. + Está cansado de cambiar manualmente las configuraciones cada vez que cambia de entorno. + +Le hemos mostrado varias formas en que puede personalizar la configuración de su pipeline dependiendo del proyecto en el que esté trabajando o el entorno de cómputo que esté usando. + +Puede querer cambiar entre configuraciones alternativas dependiendo de qué infraestructura de cómputo esté usando. Por ejemplo, puede querer desarrollar y ejecutar pruebas a pequeña escala localmente en su laptop, luego ejecutar cargas de trabajo a escala completa en HPC o en la nube. + +Nextflow le permite configurar cualquier número de perfiles que describen diferentes configuraciones, que luego puede seleccionar en tiempo de ejecución usando un argumento de línea de comandos, en lugar de tener que modificar el archivo de configuración mismo. + +### 6.1. Crear perfiles para cambiar entre desarrollo local y ejecución en HPC + +Configuremos dos perfiles alternativos; uno para ejecutar cargas pequeñas en una computadora regular, donde usaremos contenedores Docker, y uno para ejecutar en un HPC universitario con un scheduler Slurm, donde usaremos paquetes Conda. + +#### 6.1.1. Configurar los perfiles + +Agregue lo siguiente a su archivo `nextflow.config`, después de la sección de parámetros del pipeline pero antes de las configuraciones de salida: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Puede ver que para el HPC universitario, también estamos especificando limitaciones de recursos. + +#### 6.1.2. Ejecutar el workflow con un perfil + +Para especificar un perfil en nuestra línea de comandos de Nextflow, usamos el argumento `-profile`. + +Intentemos ejecutar el workflow con la configuración `my_laptop`. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Como puede ver, esto nos permite alternar entre configuraciones muy convenientemente en tiempo de ejecución. + +!!! warning "Advertencia" + + El perfil `univ_hpc` no se ejecutará correctamente en el entorno de entrenamiento ya que no tenemos acceso a un scheduler Slurm. + +Si en el futuro encontramos otros elementos de configuración que siempre co-ocurren con estos, simplemente podemos agregarlos al perfil o perfiles correspondientes. +También podemos crear perfiles adicionales si hay otros elementos de configuración que queremos agrupar juntos. + +### 6.2. Crear un perfil de parámetros de prueba + +??? example "Escenario" + + Quiere que otros puedan probar su pipeline rápidamente sin recopilar sus propios datos de entrada. + +Los perfiles no son solo para configuración de infraestructura. +También podemos usarlos para establecer valores predeterminados para parámetros del workflow, para facilitar que otros prueben el workflow sin tener que recopilar valores de entrada apropiados ellos mismos. +Puede considerar esto como una alternativa a usar un archivo de parámetros. + +#### 6.2.1. Configurar el perfil + +La sintaxis para expresar valores predeterminados en este contexto se ve así, para un perfil que nombramos `test`: + +```groovy title="Ejemplo de sintaxis" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Si agregamos un perfil de prueba para nuestro workflow, el bloque `profiles` se convierte en: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Al igual que para perfiles de configuración técnica, puede configurar múltiples perfiles diferentes especificando parámetros bajo cualquier nombre arbitrario que desee. + +#### 6.2.2. Ejecutar el workflow localmente con el perfil de prueba + +Convenientemente, los perfiles no son mutuamente excluyentes, así que podemos especificar múltiples perfiles en nuestra línea de comandos usando la siguiente sintaxis `-profile <profile1>,<profile2>` (para cualquier número de perfiles). + +Si combina perfiles que establecen valores para los mismos elementos de configuración y se describen en el mismo archivo de configuración, Nextflow resolverá el conflicto usando el valor que leyó en último lugar (_es decir_, lo que venga después en el archivo). +Si las configuraciones conflictivas se establecen en diferentes fuentes de configuración, se aplica el [orden de precedencia](https://www.nextflow.io/docs/latest/config.html) predeterminado. + +Intentemos agregar el perfil de prueba a nuestro comando anterior: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Esto usará Docker donde sea posible y producirá salidas bajo `results/test`, y esta vez el personaje es el dúo cómico `dragonandcow`. + +??? abstract "Contenido del archivo" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Esto significa que mientras distribuyamos cualquier archivo de datos de prueba con el código del workflow, cualquiera puede probar rápidamente el workflow sin tener que suministrar sus propias entradas a través de la línea de comandos o un archivo de parámetros. + +!!! tip "Consejo" + + Podemos apuntar a URLs para archivos más grandes que están almacenados externamente. + Nextflow los descargará automáticamente mientras haya una conexión abierta. + + Para más detalles, vea el Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Usar `nextflow config` para ver la configuración resuelta + +Como se señaló anteriormente, a veces el mismo parámetro puede establecerse a diferentes valores en perfiles que quiere combinar. +Y más generalmente, hay numerosos lugares donde los elementos de configuración pueden almacenarse, y a veces las mismas propiedades pueden establecerse a diferentes valores en diferentes lugares. + +Nextflow aplica un [orden de precedencia](https://www.nextflow.io/docs/latest/config.html) establecido para resolver cualquier conflicto, pero eso puede ser difícil de determinar usted mismo. +E incluso si nada está en conflicto, puede ser tedioso buscar todos los lugares posibles donde las cosas podrían estar configuradas. + +Afortunadamente, Nextflow incluye una herramienta de utilidad conveniente llamada `config` que puede automatizar todo ese proceso para usted. + +La herramienta `config` explorará todos los contenidos en su directorio de trabajo actual, aspirará cualquier archivo de configuración, y producirá la configuración completamente resuelta que Nextflow usaría para ejecutar el workflow. +Esto le permite averiguar qué configuraciones se usarán sin tener que lanzar nada. + +#### 6.3.1. Resolver la configuración predeterminada + +Ejecute este comando para resolver la configuración que se aplicaría por defecto. + +```bash +nextflow config +``` + +??? success "Salida del comando" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Esto le muestra la configuración base que obtiene si no especifica nada extra en la línea de comandos. + +#### 6.3.2. Resolver la configuración con configuraciones específicas activadas + +Si proporciona parámetros de línea de comandos, por ejemplo habilitando uno o más perfiles o cargando un archivo de parámetros, el comando también los tomará en cuenta. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Salida del comando" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Esto se vuelve especialmente útil para proyectos complejos que involucran múltiples capas de configuración. + +### Conclusión + +Sabe cómo usar perfiles para seleccionar una configuración preestablecida en tiempo de ejecución con mínima molestia. +Más generalmente, sabe cómo configurar las ejecuciones de su workflow para adaptarse a diferentes plataformas de cómputo y mejorar la reproducibilidad de sus análisis. + +### ¿Qué sigue? + +Aprenda cómo ejecutar pipelines directamente desde repositorios remotos como GitHub. + +--- + +## 7. Ejecutar pipelines desde repositorios remotos + +??? example "Escenario" + + Quiere ejecutar un pipeline bien establecido como los de nf-core sin tener que descargar y gestionar el código usted mismo. + +Hasta ahora hemos estado ejecutando scripts de workflow ubicados en el directorio actual. +En la práctica, a menudo querrá ejecutar pipelines almacenados en repositorios remotos, como GitHub. + +Nextflow hace esto sencillo: puede ejecutar cualquier pipeline directamente desde una URL de repositorio Git sin descargarlo manualmente primero. + +### 7.1. Ejecutar un pipeline desde GitHub + +La sintaxis básica para ejecutar un pipeline remoto es `nextflow run <repository>`, donde `<repository>` puede ser una ruta de repositorio GitHub como `nextflow-io/hello`, una URL completa, o una ruta a GitLab, Bitbucket, u otros servicios de alojamiento Git. + +Intente ejecutar el pipeline demo "hello" oficial de Nextflow: + +```bash +nextflow run nextflow-io/hello +``` + +La primera vez que ejecuta un pipeline remoto, Nextflow lo descarga y lo almacena en caché localmente. +Las ejecuciones posteriores usan la versión en caché a menos que solicite explícitamente una actualización. + +### 7.2. Especificar una versión para reproducibilidad + +Por defecto, Nextflow ejecuta la última versión de la rama predeterminada. +Puede especificar una versión particular, rama o commit usando la bandera `-r`: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Especificar versiones exactas es esencial para la reproducibilidad. + +### Conclusión + +Sabe cómo ejecutar pipelines directamente desde GitHub y otros repositorios remotos, y cómo especificar versiones para reproducibilidad. + +### ¿Qué sigue? + +¡Dése una gran palmadita en la espalda! +Sabe todo lo que necesita saber para comenzar a ejecutar y gestionar pipelines de Nextflow. + +Eso concluye este curso, pero si está ansioso por seguir aprendiendo, tenemos dos recomendaciones principales: + +- Si quiere profundizar más en desarrollar sus propios pipelines, eche un vistazo a [Hello Nextflow](../hello_nextflow/index.md), un curso para principiantes que cubre la misma progresión general que este pero entra en mucho más detalle sobre channels y operadores. +- Si le gustaría continuar aprendiendo cómo ejecutar pipelines de Nextflow sin profundizar más en el código, eche un vistazo a la primera parte de [Hello nf-core](../hello_nf-core/index.md), que introduce las herramientas para encontrar y ejecutar pipelines del proyecto [nf-core](https://nf-co.re/) muy popular. + +¡Diviértase! + +--- + +## Cuestionario + +<quiz> +Cuando los valores de parámetros se establecen tanto en el archivo del workflow como en `nextflow.config`, ¿cuál tiene precedencia? +- [ ] El valor del archivo del workflow +- [x] El valor del archivo de configuración +- [ ] El primer valor encontrado +- [ ] Causa un error + +Más información: [1.1. Configurar valores en `nextflow.config`](#11-configurar-valores-en-nextflowconfig) +</quiz> + +<quiz> +¿Cuál es la diferencia de sintaxis entre establecer un valor predeterminado de parámetro en un archivo de workflow vs. un archivo de configuración? +- [ ] Usan la misma sintaxis +- [x] El workflow usa declaración tipada (`#!groovy param: Type = value`), config usa asignación (`#!groovy param = value`) +- [ ] Config usa declaración tipada, workflow usa asignación +- [ ] Solo los archivos de configuración pueden establecer valores predeterminados + +Más información: [1.1. Configurar valores en `nextflow.config`](#11-configurar-valores-en-nextflowconfig) +</quiz> + +<quiz> +¿Cómo especifica un archivo de parámetros al ejecutar un workflow? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Más información: [1.3. Usar un archivo de parámetros](#13-usar-un-archivo-de-parámetros) +</quiz> + +<quiz> +¿Qué controla la opción de configuración `outputDir`? +- [ ] La ubicación del directorio de trabajo +- [x] La ruta base donde se publican las salidas del workflow +- [ ] El directorio para archivos de registro +- [ ] La ubicación de archivos de módulos + +Más información: [2.1. Personalizar el nombre del directorio outputDir](#21-personalizar-el-nombre-del-directorio-outputdir) +</quiz> + +<quiz> +¿Cómo referencia un nombre de process dinámicamente en la configuración de ruta de salida? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Más información: [2.2. Organizar salidas por process](#22-organizar-salidas-por-process) +</quiz> + +<quiz> +Si tanto Docker como Conda están habilitados y un process tiene ambas directivas, ¿cuál se prioriza? +- [x] Docker (contenedores) +- [ ] Conda +- [ ] El primero definido en el process +- [ ] Causa un error + +Más información: [3. Seleccionar una tecnología de empaquetado de software](#3-seleccionar-una-tecnología-de-empaquetado-de-software) +</quiz> + +<quiz> +¿Cuál es el executor predeterminado en Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Más información: [4. Seleccionar una plataforma de ejecución](#4-seleccionar-una-plataforma-de-ejecución) +</quiz> + +<quiz> +¿Qué comando genera un informe de utilización de recursos? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Más información: [5.1. Ejecutar el workflow para generar un informe de utilización de recursos](#51-ejecutar-el-workflow-para-generar-un-informe-de-utilización-de-recursos) +</quiz> + +<quiz> +¿Cómo establece requisitos de recursos para un process específico llamado `cowpy` en el archivo de configuración? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Más información: [5.3. Establecer asignaciones de recursos para un process específico](#53-establecer-asignaciones-de-recursos-para-un-process-específico) +</quiz> + +<quiz> +¿Qué hace la directiva `resourceLimits`? +- [ ] Establece requisitos mínimos de recursos +- [ ] Asigna recursos a processes +- [x] Limita los recursos máximos que pueden solicitarse +- [ ] Monitorea el uso de recursos en tiempo real + +Más información: [5.5. Agregar límites de recursos](#55-agregar-límites-de-recursos) +</quiz> + +<quiz> +¿Cómo especifica múltiples perfiles en un solo comando? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Más información: [6. Usar perfiles para cambiar entre configuraciones preestablecidas](#6-usar-perfiles-para-cambiar-entre-configuraciones-preestablecidas) +</quiz> + +<quiz> +¿Qué comando muestra la configuración completamente resuelta que Nextflow usaría? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Más información: [6.3. Usar `nextflow config` para ver la configuración resuelta](#63-usar-nextflow-config-para-ver-la-configuración-resuelta) +</quiz> + +<quiz> +¿Para qué se pueden usar los perfiles? (Seleccione todas las que apliquen) +- [x] Definir configuraciones específicas de infraestructura (executors, contenedores) +- [x] Establecer límites de recursos para diferentes entornos +- [x] Proporcionar parámetros de prueba para pruebas fáciles del workflow +- [ ] Definir nuevos processes + +Más información: [6. Usar perfiles para cambiar entre configuraciones preestablecidas](#6-usar-perfiles-para-cambiar-entre-configuraciones-preestablecidas) +</quiz> diff --git a/docs/es/docs/nextflow_run/index.md b/docs/es/docs/nextflow_run/index.md new file mode 100644 index 0000000000..3f817f0a5c --- /dev/null +++ b/docs/es/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Lanzar y gestionar la ejecución de workflows de Nextflow + - Encontrar e interpretar salidas (resultados) y archivos de registro + - Reconocer los componentes principales de Nextflow en un workflow simple de múltiples pasos + - Configurar la ejecución de pipelines para ejecutarse en plataformas de computación comunes, incluyendo HPC y nube + - Resumir las mejores prácticas para reproducibilidad, portabilidad y reutilización de código que hacen los pipelines FAIR, incluyendo modularidad de código y contenedores de software + audience_prerequisites: + - "**Audiencia:** Este curso está diseñado para quienes son completamente nuevos en Nextflow y desean ejecutar pipelines existentes." + - "**Habilidades:** Se asume cierta familiaridad con la línea de comandos, conceptos básicos de scripting y formatos de archivo comunes." + - "**Dominio:** Los ejercicios son independientes del dominio, por lo que no se requiere conocimiento científico previo." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run es una introducción práctica a la ejecución de workflows de análisis de datos reproducibles y escalables.** + +A través de ejemplos prácticos y ejercicios guiados, aprenderá los fundamentos del uso de Nextflow, incluyendo cómo ejecutar pipelines, gestionar archivos y dependencias de software, paralelizar la ejecución sin esfuerzo y ejecutar workflows en diferentes entornos de computación. + +Se llevará las habilidades y la confianza para comenzar a ejecutar workflows con Nextflow. + +<!-- additional_information --> + +## Descripción general del curso + +### Qué hará + +Este curso es práctico, con ejercicios orientados a objetivos estructurados para introducir información gradualmente. + +Ejecutará varias versiones de un pipeline de Nextflow que procesa entradas de texto. +Comenzará con una versión simple que consiste en un solo paso, y eventualmente progresará a una versión de múltiples pasos que toma un archivo CSV de entradas de texto tabulares, ejecuta algunos pasos de transformación y produce un único archivo de texto que contiene una imagen ASCII de un personaje diciendo el texto transformado. + +Este curso se enfoca en ejecutar pipelines (nombrado así por el comando principal `nextflow run`). +Si busca una introducción al desarrollo de pipelines de Nextflow, consulte [Hello Nextflow](../hello_nextflow/index.md). + +### Plan de lecciones + +Hemos dividido esto en tres partes que se enfocarán en aspectos específicos de la ejecución y gestión de pipelines escritos en Nextflow. + +| Capítulo del curso | Resumen | Duración estimada | +| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------- | +| [Parte 1: Ejecutar operaciones básicas](./01_basics.md) | Lanzar y gestionar la ejecución de un workflow simple | 30 mins | +| [Parte 2: Ejecutar pipelines reales](./02_pipeline.md) | Procesar entradas complejas, ejecutar workflows de múltiples pasos, usar contenedores y paralelizar la ejecución sin esfuerzo | 60 mins | +| [Parte 3: Configuración de ejecución](./03_config.md) | Personalizar el comportamiento del pipeline y optimizar el uso en diferentes entornos computacionales | 60 mins | + +Al final de este curso, estará bien preparado para abordar los próximos pasos en su camino para ejecutar workflows reproducibles para sus necesidades de computación científica. + +¿Listo para tomar el curso? + +[Comenzar a aprender :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/es/docs/nextflow_run/next_steps.md b/docs/es/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..64dace1dae --- /dev/null +++ b/docs/es/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Resumen del curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicidades por completar el curso de entrenamiento Nextflow Run! + +<!-- placeholder for video --> + +## Su recorrido + +Comenzó con un workflow muy básico, y aprendió a ejecutarlo, encontrar las salidas y gestionar su ejecución. +Luego, trabajó a través de versiones cada vez más complejas de ese workflow y aprendió a reconocer los conceptos y mecanismos esenciales que impulsan los pipelines de Nextflow, incluyendo channels y operadores, modularización de código y contenedores. +Finalmente, aprendió cómo personalizar la configuración de un pipeline para adaptarlo a sus preferencias y su infraestructura computacional. + +### Lo que aprendió + +Ahora puede gestionar la ejecución del pipeline Hello, describir cómo está estructurado e identificar las piezas principales de código involucradas. + +- La forma final del workflow Hello toma como entrada un archivo CSV que contiene saludos de texto. +- Los cuatro pasos están implementados como processes de Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` y `cowpy`) almacenados en archivos de módulos separados. +- Los resultados se publican en un directorio llamado `results/`. +- La salida final del pipeline es un archivo de texto plano que contiene arte ASCII de un personaje diciendo los saludos en mayúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Escribe cada saludo en su propio archivo de salida (_ej._ "Hello-output.txt") +2. **`convertToUpper`:** Convierte cada saludo a mayúsculas (_ej._ "HELLO") +3. **`collectGreetings`:** Recolecta todos los saludos en mayúsculas en un único archivo de lote +4. **`cowpy`:** Genera arte ASCII usando la herramienta `cowpy` + +La configuración del workflow soporta proporcionar entradas y parámetros de manera flexible y reproducible. + +### Habilidades adquiridas + +A través de este curso práctico, ha aprendido cómo: + +- Lanzar un workflow de Nextflow localmente +- Encontrar e interpretar salidas (resultados) y archivos de registro generados por Nextflow +- Reconocer los componentes principales de Nextflow que constituyen un workflow simple de múltiples pasos +- Describir conceptos del siguiente nivel como operadores y fábricas de channels +- Configurar pipelines para diferentes entornos de cómputo + +Ahora está equipado con el conocimiento fundamental para comenzar a integrar pipelines de Nextflow existentes en su propio trabajo. + +## Próximos pasos para desarrollar sus habilidades + +Aquí están nuestras principales sugerencias de qué hacer a continuación: + +- ¡No solo ejecute Nextflow, escríbalo! Conviértase en un desarrollador de Nextflow con [Hello Nextflow](../hello_nextflow/index.md) +- Aplique Nextflow a un caso de uso de análisis científico con [Nextflow for Science](../nf4_science/index.md) +- Comience con nf-core con [Hello nf-core](../hello_nf-core/index.md) +- Aprenda técnicas de solución de problemas con el [Debugging Side Quest](../side_quests/debugging.md) + +Finalmente, le recomendamos que eche un vistazo a [**Seqera Platform**](https://seqera.io/), una plataforma basada en la nube desarrollada por los creadores de Nextflow que hace aún más fácil lanzar y gestionar sus workflows, así como gestionar sus datos y ejecutar análisis interactivamente en cualquier entorno. + +## Obtener ayuda + +Para recursos de ayuda y soporte de la comunidad, vea la [página de Ayuda](../help.md). + +## Encuesta de retroalimentación + +Antes de continuar, ¡tómese un minuto para completar la encuesta del curso! Su retroalimentación nos ayuda a mejorar nuestros materiales de entrenamiento para todos. + +[Tomar la encuesta :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/es/docs/nextflow_run/survey.md b/docs/es/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..c8565649d2 --- /dev/null +++ b/docs/es/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Encuesta de retroalimentación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, complete esta breve encuesta de 5 preguntas para calificar el entrenamiento, compartir cualquier comentario que pueda tener sobre su experiencia, y hacernos saber qué más podríamos hacer para ayudarle en su viaje con Nextflow. + +Esto debería tomarle menos de un minuto para completar. ¡Gracias por ayudarnos a mejorar nuestros materiales de entrenamiento para todos! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/es/docs/nf4_science/genomics/00_orientation.md b/docs/es/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..29b9059d09 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +El entorno de entrenamiento contiene todo el software, código y datos necesarios para trabajar en este curso de entrenamiento, por lo que no necesita instalar nada por su cuenta. +Sin embargo, sí necesita una cuenta (gratuita) para iniciar sesión, y debería tomarse unos minutos para familiarizarse con la interfaz. + +Si aún no lo ha hecho, por favor siga [este enlace](../../../envsetup/) antes de continuar. + +## Materiales proporcionados + +A lo largo de este curso de entrenamiento, trabajaremos en el directorio `nf4-science/genomics/`, al cual debe moverse cuando abra el espacio de trabajo de entrenamiento. +Este directorio contiene todos los archivos de código, datos de prueba y archivos accesorios que necesitará. + +Siéntase libre de explorar el contenido de este directorio; la forma más fácil de hacerlo es usar el explorador de archivos en el lado izquierdo del espacio de trabajo de entrenamiento en la interfaz de VSCode. +Alternativamente, puede usar el comando `tree`. +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenido del directorio de una forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 2 +``` + +Si ejecuta esto dentro de `nf4-science/genomics`, debería ver la siguiente salida: + +```console title="Contenido del directorio" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Nota" + + No se preocupe si esto parece mucho; revisaremos las partes relevantes en cada paso del curso. + Esto está destinado solo a darle una visión general. + +**Aquí hay un resumen de lo que debe saber para comenzar:** + +- **Los archivos `.nf`** son scripts de workflow que se nombran según la parte del curso en la que se utilizan. + +- **El archivo `nextflow.config`** es un archivo de configuración que establece propiedades mínimas del entorno. + Puede ignorarlo por ahora. + +- **El directorio `data`** contiene datos de entrada y recursos relacionados, descritos más adelante en el curso. + +- **El directorio `solutions`** contiene archivos de módulo y configuraciones de prueba que resultan de las Partes 3 y 4 del curso. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + +!!!tip "Consejo" + + Si por cualquier razón sale de este directorio, siempre puede ejecutar este comando para regresar a él: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Ahora, para comenzar el curso, haga clic en la flecha en la esquina inferior derecha de esta página. diff --git a/docs/es/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/es/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..0e070e2f03 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1054 @@ +# Parte 1: Llamado de variantes por muestra + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la primera parte de este curso, le mostramos cómo construir un pipeline simple de llamado de variantes que aplica el llamado de variantes de GATK a muestras de secuenciación individuales. + +### Descripción general del método + +El llamado de variantes es un método de análisis genómico que tiene como objetivo identificar variaciones en una secuencia genómica en relación con un genoma de referencia. +Aquí vamos a utilizar herramientas y métodos diseñados para llamar variantes cortas, _es decir_, SNPs e indels. + +![Pipeline GATK](img/gatk-pipeline.png) + +Un pipeline completo de llamado de variantes típicamente involucra muchos pasos, incluyendo el mapeo a la referencia (a veces denominado alineamiento del genoma) y el filtrado y priorización de variantes. +Para simplificar, en esta parte del curso nos vamos a enfocar solo en la parte del llamado de variantes. + +### Conjunto de datos + +Proporcionamos los siguientes datos y recursos relacionados: + +- **Un genoma de referencia** que consiste en una pequeña región del cromosoma 20 humano (de hg19/b37) y sus archivos accesorios (índice y diccionario de secuencias). +- **Tres muestras de secuenciación de genoma completo** correspondientes a un trío familiar (madre, padre e hijo), que han sido reducidas a un pequeño fragmento de datos en el cromosoma 20 para mantener los tamaños de archivo pequeños. + Estos son datos de secuenciación Illumina de lecturas cortas que ya han sido mapeados al genoma de referencia, proporcionados en formato [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) (Binary Alignment Map, una versión comprimida de SAM, Sequence Alignment Map). +- **Una lista de intervalos genómicos**, es decir, coordenadas en el genoma donde nuestras muestras tienen datos adecuados para llamar variantes, proporcionados en formato BED. + +### Workflow + +En esta parte del curso, vamos a desarrollar un workflow que hace lo siguiente: + +1. Generar un archivo de índice para cada archivo BAM de entrada usando [Samtools](https://www.htslib.org/) +2. Ejecutar GATK HaplotypeCaller en cada archivo BAM de entrada para generar llamados de variantes por muestra en VCF (Variant Call Format) + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note + + Los archivos de índice son una característica común de los formatos de archivo bioinformáticos; contienen información sobre la estructura del archivo principal que permite a herramientas como GATK acceder a un subconjunto de los datos sin tener que leer todo el archivo. + Esto es importante debido a lo grandes que pueden llegar a ser estos archivos. + +--- + +## 0. Calentamiento: Probar los comandos de Samtools y GATK de forma interactiva + +Primero queremos probar los comandos manualmente antes de intentar envolverlos en un workflow. +Las herramientas que necesitamos (Samtools y GATK) no están instaladas en el entorno de GitHub Codespaces, así que las usaremos a través de contenedores (ver [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note + + Asegúrese de estar en el directorio `nf4-science/genomics` para que la última parte de la ruta mostrada cuando escribe `pwd` sea `genomics`. + +### 0.1. Indexar un archivo BAM de entrada con Samtools + +Vamos a descargar un contenedor de Samtools, iniciarlo de forma interactiva y ejecutar el comando `samtools index` en uno de los archivos BAM. + +#### 0.1.1. Descargar el contenedor de Samtools + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.1.2. Iniciar el contenedor de Samtools de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.1.3. Ejecutar el comando de indexación + +La [documentación de Samtools](https://www.htslib.org/doc/samtools-index.html) nos da la línea de comando para ejecutar para indexar un archivo BAM. + +Solo necesitamos proporcionar el archivo de entrada; la herramienta generará automáticamente un nombre para la salida agregando `.bai` al nombre del archivo de entrada. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Esto debería completarse de inmediato, y ahora debería ver un archivo llamado `reads_mother.bam.bai` en el mismo directorio que el archivo BAM de entrada original. + +??? abstract "Contenido del directorio" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Salir del contenedor de Samtools + +```bash +exit +``` + +### 0.2. Llamar variantes con GATK HaplotypeCaller + +Vamos a descargar un contenedor de GATK, iniciarlo de forma interactiva y ejecutar el comando `gatk HaplotypeCaller` en el archivo BAM que acabamos de indexar. + +#### 0.2.1. Descargar el contenedor de GATK + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.2.2. Iniciar el contenedor de GATK de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.2.3. Ejecutar el comando de llamado de variantes + +La [documentación de GATK](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) nos da la línea de comando para ejecutar para realizar el llamado de variantes en un archivo BAM. + +Necesitamos proporcionar el archivo BAM de entrada (`-I`) así como el genoma de referencia (`-R`), un nombre para el archivo de salida (`-O`) y una lista de intervalos genómicos a analizar (`-L`). + +Sin embargo, no necesitamos especificar la ruta al archivo de índice; la herramienta lo buscará automáticamente en el mismo directorio, basándose en la convención establecida de nomenclatura y co-ubicación. +Lo mismo se aplica a los archivos accesorios del genoma de referencia (archivos de índice y diccionario de secuencias, `*.fai` y `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +El archivo de salida `reads_mother.vcf` se crea dentro de su directorio de trabajo en el contenedor, por lo que no lo verá en el explorador de archivos de VS Code a menos que cambie la ruta del archivo de salida. +Sin embargo, es un archivo de prueba pequeño, así que puede usar `cat` para abrirlo y ver el contenido. +Si se desplaza hasta el inicio del archivo, encontrará un encabezado compuesto de muchas líneas de metadatos, seguido de una lista de llamados de variantes, uno por línea. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Cada línea describe una posible variante identificada en los datos de secuenciación de la muestra. Para orientación sobre cómo interpretar el formato VCF, vea [este artículo útil](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +El archivo VCF de salida está acompañado de un archivo de índice llamado `reads_mother.vcf.idx` que fue creado automáticamente por GATK. +Tiene la misma función que el archivo de índice BAM, permitir a las herramientas buscar y recuperar subconjuntos de datos sin cargar el archivo completo. + +#### 0.2.4. Salir del contenedor de GATK + +```bash +exit +``` + +### Conclusión + +Sabe cómo probar los comandos de indexación de Samtools y llamado de variantes de GATK en sus respectivos contenedores. + +### ¿Qué sigue? + +Aprenda cómo envolver esos mismos comandos en un workflow de dos pasos que usa contenedores para ejecutar el trabajo. + +--- + +## 1. Escribir un workflow de una etapa que ejecuta Samtools index en un archivo BAM + +Le proporcionamos un archivo de workflow, `genomics-1.nf`, que describe las partes principales del workflow. +No es funcional; su propósito es solo servir como un esqueleto que usará para escribir el workflow real. + +### 1.1. Definir el proceso de indexación + +Comencemos escribiendo un proceso, que llamaremos `SAMTOOLS_INDEX`, describiendo la operación de indexación. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Generar archivo de índice BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Debería reconocer todas las partes de lo que aprendió en la Parte 1 y Parte 2 de esta serie de entrenamiento. + +Este proceso va a requerir que pasemos una ruta de archivo a través de la entrada `input_bam`, así que configuremos eso a continuación. + +### 1.2. Agregar una declaración de parámetro de entrada + +En la parte superior del archivo, bajo la sección `Pipeline parameters`, declaramos un parámetro CLI llamado `reads_bam` y le damos un valor predeterminado. +De esa manera, podemos ser perezosos y no especificar la entrada cuando escribimos el comando para lanzar el pipeline (con fines de desarrollo). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Parámetros del pipeline + */ +params { + // Entrada principal + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Ahora tenemos un proceso listo, así como un parámetro para darle una entrada para ejecutar, así que conectemos esas cosas juntas. + +!!! note + + `${projectDir}` es una variable integrada de Nextflow que apunta al directorio donde se encuentra el script de workflow actual de Nextflow (`genomics-1.nf`). + + Esto facilita hacer referencia a archivos, directorios de datos y otros recursos incluidos en el repositorio del workflow sin codificar rutas absolutas. + +### 1.3. Agregar bloque workflow para ejecutar SAMTOOLS_INDEX + +En el bloque `workflow`, necesitamos configurar un **canal** para alimentar la entrada al proceso `SAMTOOLS_INDEX`; luego podemos llamar al proceso mismo para que se ejecute en el contenido de ese canal. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Crear canal de entrada (archivo único vía parámetro CLI) + reads_ch = channel.fromPath(params.reads_bam) + + // Crear archivo de índice para el archivo BAM de entrada + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +El bloque workflow tiene dos secciones: + +- `main:` contiene las operaciones de canal y llamadas a procesos +- `publish:` declara qué salidas deben publicarse, asignándolas a destinos con nombre + +Notará que estamos usando la misma channel factory `.fromPath` que usamos en [Hello Channels](../../hello_nextflow/02_hello_channels.md). +De hecho, estamos haciendo algo muy similar. +La diferencia es que le estamos diciendo a Nextflow que solo cargue la ruta del archivo en sí en el canal como un elemento de entrada, en lugar de leer su contenido. + +### 1.4. Agregar un bloque output para definir dónde se publican los resultados + +Después del bloque workflow, agregamos un bloque `output` que especifica dónde publicar las salidas del workflow. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Cada destino nombrado de la sección `publish:` (como `bam_index`) obtiene su propio bloque donde puede configurar la ruta de salida relativa al directorio de salida base. + +!!! note + + Aunque los archivos de datos que estamos usando aquí son muy pequeños, en genómica pueden llegar a ser muy grandes. + Por defecto, Nextflow crea enlaces simbólicos a los archivos de salida en el directorio de publicación, lo que evita copias de archivos innecesarias. + Puede cambiar este comportamiento usando la opción `mode` (por ejemplo, `mode 'copy'`) para crear copias reales en su lugar. + Tenga en cuenta que los enlaces simbólicos se romperán cuando limpie su directorio `work`, por lo que para workflows de producción es posible que desee usar `mode 'copy'`. + +### 1.5. Configurar el directorio de salida + +El directorio de salida base se establece mediante la opción de configuración `outputDir`. Agréguela a `nextflow.config`: + +=== "Después" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Ejecutar el workflow para verificar que el paso de indexación funciona + +¡Ejecutemos el workflow! Como recordatorio, no necesitamos especificar una entrada en la línea de comando porque establecimos un valor predeterminado para la entrada cuando declaramos el parámetro de entrada. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Puede verificar que el archivo de índice se ha generado correctamente mirando en el directorio de trabajo o en el directorio de resultados. + +??? abstract "Contenido del directorio de trabajo" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Contenido del directorio de resultados" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +¡Ahí está! + +### Conclusión + +Sabe cómo envolver una herramienta genómica en un workflow Nextflow de un solo paso y hacer que se ejecute usando un contenedor. + +### ¿Qué sigue? + +Agregar un segundo paso que consuma la salida del primero. + +--- + +## 2. Agregar un segundo proceso para ejecutar GATK HaplotypeCaller en el archivo BAM indexado + +Ahora que tenemos un índice para nuestro archivo de entrada, podemos pasar a configurar el paso de llamado de variantes, que es la parte interesante del workflow. + +### 2.1. Definir el proceso de llamado de variantes + +Escribamos un proceso, que llamaremos `GATK_HAPLOTYPECALLER`, describiendo la operación de llamado de variantes. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Llamar variantes con GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Notará que hemos introducido una nueva sintaxis aquí (`emit:`) para nombrar de forma única cada uno de nuestros canales de salida, y las razones para esto quedarán claras pronto. + +Este comando toma bastantes más entradas, porque GATK necesita más información para realizar el análisis en comparación con un simple trabajo de indexación. +Pero notará que hay incluso más entradas definidas en el bloque de entradas de las que se enumeran en el comando de GATK. ¿Por qué es eso? + +!!! note + + GATK sabe buscar el archivo de índice BAM y los archivos accesorios del genoma de referencia porque está al tanto de las convenciones que rodean esos archivos. + Sin embargo, Nextflow está diseñado para ser agnóstico del dominio y no sabe nada sobre los requisitos de formato de archivo bioinformático. + +Necesitamos decirle a Nextflow explícitamente que tiene que preparar esos archivos en el directorio de trabajo en tiempo de ejecución; de lo contrario no lo hará, y GATK (correctamente) lanzará un error sobre los archivos de índice que faltan. + +De manera similar, tenemos que listar el archivo de índice del VCF de salida (el archivo `"${input_bam}.vcf.idx"`) explícitamente para que Nextflow sepa hacer un seguimiento de ese archivo en caso de que sea necesario en pasos posteriores. + +### 2.2. Agregar definiciones para entradas accesorias + +Dado que nuestro nuevo proceso espera que se proporcionen un puñado de archivos adicionales, configuramos algunos parámetros CLI para ellos bajo la sección `Pipeline parameters`, junto con algunos valores predeterminados (por las mismas razones que antes). + +```groovy title="genomics-1.nf" linenums="8" + // Archivos accesorios + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Crear variables para contener las rutas de archivos accesorios + +Mientras que las entradas de datos principales se transmiten dinámicamente a través de canales, hay dos enfoques para manejar archivos accesorios. El enfoque recomendado es crear canales explícitos, lo que hace que el flujo de datos sea más claro y consistente. Alternativamente, se puede usar la función file() para crear variables en casos más simples, particularmente cuando necesita hacer referencia al mismo archivo en múltiples procesos, aunque tenga en cuenta que esto aún crea canales implícitamente. <!-- TODO: Aclarar: ¿esto sigue siendo necesario con entradas tipadas? --> + +Agregue esto al bloque workflow (después de la creación de `reads_ch`, dentro de la sección `main:`): + +```groovy title="genomics-1.nf" linenums="79" + // Cargar las rutas de archivo para los archivos accesorios (referencia e intervalos) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Esto hará que las rutas de archivos accesorios estén disponibles para proporcionar como entrada a cualquier proceso que las necesite. + +### 2.4. Agregar una llamada al bloque workflow para ejecutar GATK_HAPLOTYPECALLER + +Ahora que tenemos nuestro segundo proceso configurado y todas las entradas y archivos accesorios están listos y disponibles, podemos agregar una llamada al proceso `GATK_HAPLOTYPECALLER` en el cuerpo del workflow. + +```groovy title="genomics-1.nf" linenums="88" + // Llamar variantes del archivo BAM indexado + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Debería reconocer la sintaxis `*.out` de la Parte 1 de esta serie de entrenamiento; le estamos diciendo a Nextflow que tome la salida de canal de `SAMTOOLS_INDEX` y la conecte a la llamada del proceso `GATK_HAPLOTYPECALLER`. + +!!! note + + Notará que las entradas se proporcionan en el mismo orden exacto en la llamada al proceso que se enumeran en el bloque de entrada del proceso. + En Nextflow, las entradas son posicionales, lo que significa que _debe_ seguir el mismo orden; y por supuesto tiene que haber el mismo número de elementos. + +### 2.5. Actualizar la sección publish y el bloque output + +Necesitamos actualizar la sección `publish:` para incluir las salidas VCF, y agregar los destinos correspondientes en el bloque `output`. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Ejecutar el workflow para verificar que el paso de llamado de variantes funciona + +Ejecutemos el workflow expandido con `-resume` para que no tengamos que ejecutar el paso de indexación nuevamente. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Ahora si miramos la salida de la consola, vemos los dos procesos listados. + +El primer proceso fue omitido gracias al almacenamiento en caché, como se esperaba, mientras que el segundo proceso se ejecutó ya que es completamente nuevo. + +Encontrará los archivos de salida en el directorio de resultados (como enlaces simbólicos al directorio de trabajo). + +??? abstract "Contenido del directorio" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Si abre el archivo VCF, debería ver el mismo contenido que en el archivo que generó al ejecutar el comando GATK directamente en el contenedor. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Esta es la salida que nos interesa generar para cada muestra en nuestro estudio. + +### Conclusión + +Sabe cómo hacer un workflow muy básico de dos pasos que hace un trabajo de análisis real y es capaz de lidiar con las idiosincrasias del formato de archivo genómico como los archivos accesorios. + +### ¿Qué sigue? + +Hacer que el workflow maneje múltiples muestras en lote. + +--- + +## 3. Adaptar el workflow para ejecutarse en un lote de muestras + +Está muy bien tener un workflow que pueda automatizar el procesamiento en una sola muestra, pero ¿qué pasa si tiene 1000 muestras? +¿Necesita escribir un script bash que haga un bucle a través de todas sus muestras? + +¡No, gracias a Dios! Solo haga un pequeño ajuste al código y Nextflow también manejará eso por usted. + +### 3.1. Convertir la declaración de parámetro de entrada en un array que liste las tres muestras + +Convirtamos esa ruta de archivo predeterminada en la declaración del archivo BAM de entrada en un array que liste las rutas de archivo para nuestras tres muestras de prueba, arriba bajo la sección `Pipeline parameters`. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (array de tres muestras) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note + + Al usar declaraciones de parámetros tipadas (como `reads_bam: Path`), no puede asignar un valor de array. + Para arrays, omita la anotación de tipo. + +Y eso es realmente todo lo que necesitamos hacer, porque la channel factory que usamos en el cuerpo del workflow (`.fromPath`) está tan feliz de aceptar múltiples rutas de archivo para cargar en el canal de entrada como lo estaba para cargar una sola. + +!!! note + + Normalmente, no querría codificar la lista de muestras en su archivo de workflow, pero lo estamos haciendo aquí para mantener las cosas simples. + Presentaremos formas más elegantes de manejar entradas más adelante en esta serie de entrenamiento. + +### 3.2. Ejecutar el workflow para verificar que se ejecuta en las tres muestras + +Intentemos ejecutar el workflow ahora que la tubería está configurada para ejecutarse en las tres muestras de prueba. + +```bash +nextflow run genomics-1.nf -resume +``` + +Cosa graciosa: esto _podría funcionar_, O _podría fallar_. Por ejemplo, aquí hay una ejecución que tuvo éxito: + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Si su ejecución de workflow tuvo éxito, ejecútelo nuevamente hasta que obtenga un error como este: + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Si mira la salida de error del comando GATK, habrá una línea como esta: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Bueno, eso es extraño, considerando que indexamos explícitamente los archivos BAM en el primer paso del workflow. ¿Podría haber algo mal con la tubería? + +#### 3.2.1. Verificar los directorios de trabajo para las llamadas relevantes + +Echemos un vistazo dentro del directorio de trabajo para la llamada de proceso `GATK_HAPLOTYPECALLER` fallida listada en la salida de la consola. + +??? abstract "Contenido del directorio" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Preste especial atención a los nombres del archivo BAM y el índice BAM que se enumeran en este directorio: `reads_son.bam` y `reads_father.bam.bai`. + +¿Qué demonios? Nextflow ha preparado un archivo de índice en el directorio de trabajo de esta llamada de proceso, pero es el incorrecto. ¿Cómo pudo haber sucedido esto? + +#### 3.2.2. Usar el [operador view()](https://www.nextflow.io/docs/latest/reference/operator.html#view) para inspeccionar el contenido del canal + +Agregue estas dos líneas en el cuerpo del workflow antes de la llamada al proceso `GATK_HAPLOTYPER`: + +```groovy title="genomics-1.nf" linenums="84" + // diagnósticos temporales + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Luego ejecute el comando del workflow nuevamente. + +```bash +nextflow run genomics-1.nf +``` + +Una vez más, esto puede tener éxito o fallar. Aquí hay una ejecución exitosa: + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +Y aquí hay una fallida: + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Es posible que necesite ejecutarlo varias veces para que falle nuevamente. +Este error no se reproducirá de manera consistente porque depende de cierta variabilidad en los tiempos de ejecución de las llamadas de proceso individuales. + +Esto es lo que se ve la salida de las dos llamadas `.view()` que agregamos para una ejecución fallida: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +Las primeras tres líneas corresponden al canal de entrada y las segundas, al canal de salida. +¡Puede ver que los archivos BAM y los archivos de índice para las tres muestras no están listados en el mismo orden! + +!!! note + + Cuando llama a un proceso Nextflow en un canal que contiene múltiples elementos, Nextflow intentará paralelizar la ejecución tanto como sea posible, y recopilará salidas en el orden en que estén disponibles. + La consecuencia es que las salidas correspondientes pueden recopilarse en un orden diferente al que se alimentaron las entradas originales. + +Tal como está escrito actualmente, nuestro script de workflow asume que los archivos de índice saldrán del paso de indexación listados en el mismo orden madre/padre/hijo que se dieron las entradas. +Pero eso no está garantizado, razón por la cual a veces (aunque no siempre) los archivos incorrectos se emparejan en el segundo paso. + +Para solucionar esto, necesitamos asegurarnos de que los archivos BAM y sus archivos de índice viajen juntos a través de los canales. + +!!! tip + + Las declaraciones `view()` en el código del workflow no hacen nada, por lo que no es un problema dejarlas. + Sin embargo, desordenarán su salida de consola, por lo que recomendamos eliminarlas cuando termine de solucionar el problema. + +### 3.3. Cambiar la salida del proceso SAMTOOLS_INDEX en una tupla que mantenga el archivo de entrada y su índice juntos + +La forma más simple de asegurar que un archivo BAM y su índice permanezcan estrechamente asociados es empaquetarlos juntos en una tupla que salga de la tarea de índice. + +!!! note + + Una **tupla** es una lista ordenada y finita de elementos que se usa comúnmente para devolver múltiples valores de una función. Las tuplas son particularmente útiles para pasar múltiples entradas o salidas entre procesos mientras se preserva su asociación y orden. + +Primero, cambiemos la salida del proceso `SAMTOOLS_INDEX` para incluir el archivo BAM en su declaración de salida. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +De esta manera, cada archivo de índice estará estrechamente acoplado con su archivo BAM original, y la salida general del paso de indexación será un solo canal que contiene pares de archivos. + +### 3.4. Cambiar la entrada al proceso GATK_HAPLOTYPECALLER para que sea una tupla + +Dado que hemos cambiado la 'forma' de la salida del primer proceso en el workflow, necesitamos actualizar la definición de entrada del segundo proceso para que coincida. + +Específicamente, donde previamente declaramos dos rutas de entrada separadas en el bloque de entrada del proceso `GATK_HAPLOTYPECALLER`, ahora declaramos una sola entrada que coincide con la estructura de la tupla emitida por `SAMTOOLS_INDEX`. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Por supuesto, dado que ahora hemos cambiado la forma de las entradas que `GATK_HAPLOTYPECALLER` espera, necesitamos actualizar la llamada del proceso en consecuencia en el cuerpo del workflow. + +### 3.5. Actualizar la llamada a GATK_HAPLOTYPECALLER en el bloque workflow + +Ya no necesitamos proporcionar el `reads_ch` original al proceso `GATK_HAPLOTYPECALLER`, ya que el archivo BAM ahora está empaquetado en la salida del canal por `SAMTOOLS_INDEX`. + +Como resultado, simplemente podemos eliminar esa línea. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +Esa es toda la reconexión que es necesaria para resolver el problema de desajuste de índice. + +### 3.6. Actualizar la sección publish y el bloque output para la tupla + +Dado que `SAMTOOLS_INDEX.out` ahora es una tupla que contiene tanto el BAM como su índice, ambos archivos se publicarán juntos. +Renombramos el destino de `bam_index` a `indexed_bam` para reflejar que ahora contiene ambos archivos. + +=== "Después" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +También necesitamos actualizar el bloque output para usar el nuevo nombre de destino: + +=== "Después" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Ejecutar el workflow para verificar que funciona correctamente en las tres muestras cada vez + +Por supuesto, la prueba está en el resultado, así que ejecutemos el workflow nuevamente algunas veces para asegurarnos de que esto funcione de manera confiable en el futuro. + +```bash +nextflow run genomics-1.nf +``` + +Esta vez (y cada vez) todo debería ejecutarse correctamente: + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +El directorio de resultados ahora contiene archivos BAM y BAI para cada muestra (de la tupla), junto con las salidas VCF: + +??? abstract "Contenido del directorio de resultados" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Si lo desea, puede usar `.view()` nuevamente para ver cómo se ve el contenido del canal de salida de `SAMTOOLS_INDEX`: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Verá que el canal contiene las tres tuplas esperadas (rutas de archivo truncadas para legibilidad). + +```console title="Salida" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Eso será mucho más seguro, en adelante. + +### Conclusión + +Sabe cómo hacer que su workflow se ejecute en múltiples muestras (independientemente). + +### ¿Qué sigue? + +Facilitar el manejo de muestras en lote. + +--- + +## 4. Hacer que el workflow acepte un archivo de texto que contenga un lote de archivos de entrada + +Una forma muy común de proporcionar múltiples archivos de datos de entrada a un workflow es hacerlo con un archivo de texto que contenga las rutas de los archivos. +Puede ser tan simple como un archivo de texto que liste una ruta de archivo por línea y nada más, o el archivo puede contener metadatos adicionales, en cuyo caso a menudo se llama samplesheet. + +Aquí vamos a mostrarle cómo hacer el caso simple. + +### 4.1. Examinar el archivo de texto proporcionado que lista las rutas de los archivos de entrada + +Ya hicimos un archivo de texto que lista las rutas de los archivos de entrada, llamado `sample_bams.txt`, que puede encontrar en el directorio `data/`. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Como puede ver, listamos una ruta de archivo por línea, y son rutas absolutas. + +!!! note + + Los archivos que estamos usando aquí están simplemente en el sistema de archivos local de su GitHub Codespaces, pero también podríamos apuntar a archivos en almacenamiento en la nube. + +### 4.2. Actualizar el valor predeterminado del parámetro + +Cambiemos el valor predeterminado para nuestro parámetro de entrada `reads_bam` para que apunte al archivo `sample_bams.txt`. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (archivo de archivos de entrada, uno por línea) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (array de tres muestras) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +De esta manera podemos continuar siendo perezosos, pero la lista de archivos ya no vive en el código del workflow en sí, lo cual es un gran paso en la dirección correcta. + +### 4.3. Actualizar la channel factory para leer líneas de un archivo + +Actualmente, nuestra channel factory de entrada trata cualquier archivo que le demos como las entradas de datos que queremos alimentar al proceso de indexación. +Dado que ahora le estamos dando un archivo que lista las rutas de los archivos de entrada, necesitamos cambiar su comportamiento para analizar el archivo y tratar las rutas de archivo que contiene como las entradas de datos. + +Afortunadamente, podemos hacer eso muy simplemente, solo agregando el [operador `.splitText()`](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) al paso de construcción del canal. + +=== "Después" + + ```groovy title="genomics-1.nf" linenums="68" + // Crear canal de entrada desde un archivo de texto que lista rutas de archivos de entrada + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="68" + // Crear canal de entrada (archivo único vía parámetro CLI) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip + + Esta es otra gran oportunidad para usar el operador `.view()` para ver cómo se ve el contenido del canal antes y después de aplicar un operador. + +### 4.4. Ejecutar el workflow para verificar que funciona correctamente + +Ejecutemos el workflow una vez más. Esto debería producir el mismo resultado que antes, ¿verdad? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + ``` + +¡Sí! De hecho, Nextflow detecta correctamente que las llamadas de proceso son exactamente las mismas, y ni siquiera se molesta en volver a ejecutar todo, ya que estábamos ejecutando con `-resume`. + +¡Y eso es todo! Nuestro workflow simple de llamado de variantes tiene todas las características básicas que queríamos. + +### Conclusión + +Sabe cómo hacer un workflow lineal de múltiples pasos para indexar un archivo BAM y aplicar el llamado de variantes por muestra usando GATK. + +De manera más general, ha aprendido cómo usar componentes y lógica esenciales de Nextflow para construir un pipeline genómico simple que hace trabajo real, teniendo en cuenta las idiosincrasias de los formatos de archivo genómicos y los requisitos de las herramientas. + +### ¿Qué sigue? + +¡Celebre su éxito y tome un descanso extra largo! + +En la próxima parte de este curso, aprenderá cómo usar algunas características adicionales de Nextflow (incluyendo más operadores de canal) para aplicar el llamado de variantes conjunto a los datos. diff --git a/docs/es/docs/nf4_science/genomics/02_joint_calling.md b/docs/es/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..38389de104 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1026 @@ +# Parte 2: Llamado conjunto en una cohorte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la primera parte de este curso, construyó un pipeline de llamado de variantes que era completamente lineal y procesaba los datos de cada muestra independientemente de las demás. +Sin embargo, en un caso de uso genómico real, típicamente necesitará examinar los llamados de variantes de múltiples muestras juntas. + +En esta segunda parte, le mostramos cómo usar canales y operadores de canal para implementar el llamado conjunto de variantes con GATK, basándose en el pipeline de la Parte 1. + +### Descripción general del método + +El método de llamado de variantes de GATK que usamos en la primera parte de este curso simplemente generaba llamados de variantes por muestra. +Eso está bien si solo desea examinar las variantes de cada muestra en aislamiento, pero eso produce información limitada. +A menudo es más interesante observar cómo difieren los llamados de variantes entre múltiples muestras, y para hacerlo, GATK ofrece un método alternativo llamado llamado conjunto de variantes, que demostramos aquí. + +El llamado conjunto de variantes implica generar un tipo especial de salida de variantes llamado GVCF (por Genomic VCF) para cada muestra, luego combinar los datos GVCF de todas las muestras y finalmente, ejecutar un análisis estadístico de 'genotipado conjunto'. + +![Análisis conjunto](img/joint-calling.png) + +Lo especial del GVCF de una muestra es que contiene registros que resumen las estadísticas de datos de secuencia sobre todas las posiciones en el área objetivo del genoma, no solo las posiciones donde el programa encontró evidencia de variación. +Esto es crítico para el cálculo del genotipado conjunto ([lectura adicional](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +El GVCF es producido por GATK HaplotypeCaller, la misma herramienta que usamos en la Parte 1, con un parámetro adicional (`-ERC GVCF`). +La combinación de los GVCFs se realiza con GATK GenomicsDBImport, que combina los llamados por muestra en un almacén de datos (análogo a una base de datos), luego el análisis de 'genotipado conjunto' propiamente dicho se realiza con GATK GenotypeGVCFs. + +### Flujo de trabajo + +Entonces, para recapitular, en esta parte del curso, vamos a desarrollar un flujo de trabajo que hace lo siguiente: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Generar un archivo de índice para cada archivo BAM de entrada usando Samtools +2. Ejecutar GATK HaplotypeCaller en cada archivo BAM de entrada para generar un GVCF de llamados de variantes genómicas por muestra +3. Recopilar todos los GVCFs y combinarlos en un almacén de datos GenomicsDB +4. Ejecutar genotipado conjunto en el almacén de datos GVCF combinado para producir un VCF a nivel de cohorte + +Aplicaremos esto al mismo conjunto de datos que en la Parte 1. + +--- + +## 0. Calentamiento: Ejecutar Samtools y GATK directamente + +Al igual que anteriormente, queremos probar los comandos manualmente antes de intentar envolverlos en un flujo de trabajo. + +!!! note + + Asegúrese de estar en el directorio de trabajo correcto: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Indexar un archivo BAM de entrada con Samtools + +Este primer paso es el mismo que en la Parte 1, por lo que debería sentirse muy familiar, pero esta vez necesitamos hacerlo para las tres muestras. + +!!! note + + Técnicamente ya hemos generado archivos de índice para las tres muestras a través de nuestro pipeline, por lo que podríamos ir a buscarlos en el directorio de resultados. Sin embargo, es más limpio simplemente rehacerlo manualmente, y solo tomará un minuto. + +#### 0.1.1. Iniciar el contenedor de Samtools de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.1.2. Ejecutar el comando de indexación para las tres muestras + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Al igual que anteriormente, esto debería producir los archivos de índice en el mismo directorio que los archivos BAM correspondientes. + +??? abstract "Contenido del directorio" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Ahora que tenemos archivos de índice para las tres muestras, podemos proceder a generar los GVCFs para cada una de ellas. + +#### 0.1.3. Salir del contenedor de Samtools + +```bash +exit +``` + +### 0.2. Llamar variantes con GATK HaplotypeCaller en modo GVCF + +Este segundo paso es muy similar a lo que hicimos en la Parte 1: Hello Genomics, pero ahora vamos a ejecutar GATK en 'modo GVCF'. + +#### 0.2.1. Iniciar el contenedor de GATK de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +#### 0.2.2. Ejecutar el comando de llamado de variantes con la opción GVCF + +Para producir un VCF genómico (GVCF), agregamos la opción `-ERC GVCF` al comando base, que activa el modo GVCF de HaplotypeCaller. + +También cambiamos la extensión del archivo de salida de `.vcf` a `.g.vcf`. +Esto técnicamente no es un requisito, pero es una convención fuertemente recomendada. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +Esto crea el archivo de salida GVCF `reads_mother.g.vcf` en el directorio de trabajo actual en el contenedor. + +Si ejecuta `cat` para ver su contenido, verá que es mucho más largo que el VCF equivalente que generamos en la Parte 1. Ni siquiera puede desplazarse hacia arriba hasta el inicio del archivo, y la mayoría de las líneas se ven bastante diferentes de lo que vimos en el VCF en la Parte 1. + +```console title="Salida" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Estas representan regiones no variantes donde el llamador de variantes no encontró evidencia de variación, por lo que capturó algunas estadísticas que describen su nivel de confianza en la ausencia de variación. Esto hace posible distinguir entre dos casos muy diferentes: (1) hay datos de buena calidad que muestran que la muestra es homocigota-referencia, y (2) no hay suficientes datos buenos disponibles para hacer una determinación de cualquier manera. + +En un GVCF, típicamente hay muchas de estas líneas no variantes, con un número menor de registros de variantes intercalados entre ellas. Intente ejecutar `head -176` en el GVCF para cargar solo las primeras 176 líneas del archivo para encontrar un llamado de variante real. + +```console title="Salida" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +La segunda línea muestra el primer registro de variante en el archivo, que corresponde a la primera variante en el archivo VCF que examinamos en la Parte 1. + +Al igual que el VCF original, el archivo GVCF de salida también está acompañado por un archivo de índice, llamado `reads_mother.g.vcf.idx`. + +#### 0.2.3. Repetir el proceso en las otras dos muestras + +Para probar el paso de genotipado conjunto, necesitamos GVCFs para las tres muestras, así que generémoslos manualmente ahora. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +Una vez que esto se complete, debería tener tres archivos que terminan en `.g.vcf` en su directorio actual (uno por muestra) y sus respectivos archivos de índice que terminan en `.g.vcf.idx`. + +### 0.3. Ejecutar genotipado conjunto + +Ahora que tenemos todos los GVCFs, finalmente podemos probar el enfoque de genotipado conjunto para generar llamados de variantes para una cohorte de muestras. +Como recordatorio, es un método de dos pasos que consiste en combinar los datos de todos los GVCFs en un almacén de datos, luego ejecutar el análisis de genotipado conjunto propiamente dicho para generar el VCF final de variantes llamadas conjuntamente. + +#### 0.3.1. Combinar todos los GVCFs por muestra + +Este primer paso usa otra herramienta de GATK, llamada GenomicsDBImport, para combinar los datos de todos los GVCFs en un almacén de datos GenomicsDB. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +La salida de este paso es efectivamente un directorio que contiene un conjunto de directorios más anidados que contienen los datos de variantes combinados en forma de múltiples archivos diferentes. +Puede explorar dentro de él pero rápidamente verá que este formato de almacén de datos no está destinado a ser leído directamente por humanos. + +!!! note + + GATK incluye herramientas que hacen posible inspeccionar y extraer datos de llamados de variantes del almacén de datos según sea necesario. + +#### 0.3.2. Ejecutar el análisis de genotipado conjunto propiamente dicho + +Este segundo paso usa otra herramienta de GATK, llamada GenotypeGVCFs, para recalcular las estadísticas de variantes y los genotipos individuales a la luz de los datos disponibles en todas las muestras de la cohorte. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +Esto crea el archivo de salida VCF `family_trio.vcf` en el directorio de trabajo actual en el contenedor. +Es otro archivo razonablemente pequeño, por lo que puede ejecutar `cat` en este archivo para ver su contenido, y desplazarse hacia arriba para encontrar las primeras líneas de variantes. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Esto se parece más al VCF original que generamos en la Parte 1, excepto que esta vez tenemos información a nivel de genotipo para las tres muestras. +Las últimas tres columnas en el archivo son los bloques de genotipo para las muestras, listadas en orden alfabético. + +Si observamos los genotipos llamados para nuestro trío familiar de prueba para la primera variante, vemos que el padre es heterocigoto-variante (`0/1`), y la madre y el hijo son ambos homocigotos-variante (`1/1`). + +¡Esa es en última instancia la información que buscamos extraer del conjunto de datos! Así que envolvamos todo esto en un flujo de trabajo de Nextflow para poder hacerlo a escala. + +#### 0.3.3. Salir del contenedor de GATK + +```bash +exit +``` + +### Conclusión + +Sabe cómo ejecutar los comandos individuales involucrados en el llamado conjunto de variantes en la terminal para verificar que producirán la información que desea. + +### ¿Qué sigue? + +Envolver estos comandos en un pipeline real. + +--- + +## 1. Modificar el paso de llamado de variantes por muestra para producir un GVCF + +La buena noticia es que no necesitamos comenzar desde cero, ya que escribimos un flujo de trabajo que hace parte de este trabajo en la Parte 1. +Sin embargo, ese pipeline produce archivos VCF, mientras que ahora queremos archivos GVCF para hacer el genotipado conjunto. +Entonces necesitamos comenzar activando el modo de llamado de variantes GVCF y actualizando la extensión del archivo de salida. + +!!! note + + Por conveniencia, vamos a trabajar con una copia nueva del flujo de trabajo de GATK tal como está al final de la Parte 1, pero con un nombre diferente: `genomics-2.nf`. + +### 1.1. Indicar a HaplotypeCaller que emita un GVCF y actualizar la extensión de salida + +Abramos el archivo `genomics-2.nf` en el editor de código. +Debería verse muy familiar, pero siéntase libre de ejecutarlo si desea asegurarse de que funciona como se espera. + +Vamos a comenzar haciendo dos cambios: + +- Agregar el parámetro `-ERC GVCF` al comando GATK HaplotypeCaller; +- Actualizar la ruta del archivo de salida para usar la extensión `.g.vcf` correspondiente, según la convención de GATK. + +Asegúrese de agregar una barra invertida (`\`) al final de la línea anterior cuando agregue `-ERC GVCF`. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +Y eso es todo lo que se necesita para cambiar HaplotypeCaller a generar GVCFs en lugar de VCFs, ¿verdad? + +### 1.2. Ejecutar el pipeline para verificar que puede generar GVCFs + +El comando de ejecución de Nextflow es el mismo que antes, salvo por el nombre del archivo de flujo de trabajo en sí. +Asegúrese de actualizarlo apropiadamente. + +```bash +nextflow run genomics-2.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +Y la salida es... ¡todo rojo! Oh no. + +El comando que se ejecutó es correcto, así que teníamos razón en que eso era suficiente para cambiar el comportamiento de la herramienta GATK. +Pero observe esa línea sobre el archivo de salida faltante. ¿Nota algo? + +Así es, olvidamos decirle a Nextflow que espere un nuevo nombre de archivo. Ups. + +### 1.3. Actualizar la extensión del archivo de salida en el bloque de salidas del proceso también + +Porque no es suficiente solo cambiar la extensión del archivo en el comando de la herramienta en sí, también tiene que decirle a Nextflow que el nombre del archivo de salida esperado ha cambiado. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Actualizar los destinos de publicación para las nuevas salidas GVCF + +Ya que ahora estamos produciendo GVCFs en lugar de VCFs, deberíamos actualizar la sección `publish:` del flujo de trabajo para usar nombres más descriptivos. +También organizaremos los archivos GVCF en su propio subdirectorio para mayor claridad. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Actualizar el bloque de salida para la nueva estructura de directorios + +También necesitamos actualizar el bloque `output` para colocar los archivos GVCF en un subdirectorio `gvcf`. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Ejecutar el pipeline nuevamente + +Ejecutémoslo con `-resume` esta vez. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Esta vez funciona. + +La salida de Nextflow en sí no se ve diferente (comparada con una ejecución exitosa en modo VCF normal), pero ahora podemos encontrar los archivos `.g.vcf` y sus respectivos archivos de índice, para las tres muestras, organizados en subdirectorios. + +??? abstract "Contenido del directorio (symlinks acortados)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Si abre uno de los archivos GVCF y se desplaza a través de él, puede verificar que GATK HaplotypeCaller produjo archivos GVCF como se solicitó. + +### Conclusión + +Bien, este fue mínimo en términos de aprendizaje de Nextflow... +¡Pero fue una buena oportunidad para reiterar la importancia del bloque de salida del proceso! + +### ¿Qué sigue? + +Aprender a recopilar el contenido de un canal y pasarlos al siguiente proceso como una única entrada. + +--- + +## 2. Recopilar y combinar los datos GVCF de todas las muestras + +Ahora necesitamos combinar los datos de todos los GVCFs por muestra en una forma que soporte el análisis de genotipado conjunto que queremos hacer. + +### 2.1. Definir el proceso que combinará los GVCFs + +Como recordatorio de lo que hicimos anteriormente en la sección de calentamiento, combinar los GVCFs es un trabajo para la herramienta GATK GenomicsDBImport, que producirá un almacén de datos en el llamado formato GenomicsDB. + +Escribamos un nuevo proceso para definir cómo va a funcionar eso, basándonos en el comando que usamos anteriormente en la sección de calentamiento. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Combinar GVCFs en almacén de datos GenomicsDB + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +¿Qué piensa, se ve razonable? + +Conectémoslo y veamos qué sucede. + +### 2.2. Agregar un parámetro `cohort_name` con un valor predeterminado + +Necesitamos proporcionar un nombre arbitrario para la cohorte. +Más adelante en la serie de entrenamiento aprenderá cómo usar metadatos de muestras para este tipo de cosas, pero por ahora solo declaramos un parámetro CLI usando `params` y le damos un valor predeterminado por conveniencia. + +```groovy title="genomics-2.nf" linenums="16" + // Nombre base para el archivo de salida final + cohort_name: String = "family_trio" +``` + +### 2.3. Reunir las salidas de GATK_HAPLOTYPECALLER entre muestras + +Si simplemente conectáramos el canal de salida del proceso `GATK_HAPLOTYPECALLER` tal como está, Nextflow llamaría al proceso en cada GVCF de muestra por separado. +Sin embargo, queremos agrupar los tres GVCFs (y sus archivos de índice) de tal manera que Nextflow los entregue todos juntos a una sola llamada de proceso. + +Buenas noticias: podemos hacer eso usando el operador de canal `collect()`. Agreguemos las siguientes líneas al cuerpo del `workflow`, justo después de la llamada a GATK_HAPLOTYPECALLER: + +```groovy title="genomics-2.nf" linenums="118" +// Recopilar salidas de llamado de variantes entre muestras +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +¿Parece un poco complicado? Desglosemos esto y traduzcámoslo a lenguaje sencillo. + +1. Estamos tomando el canal de salida del proceso `GATK_HAPLOTYPECALLER`, referido usando la propiedad `.out`. +2. Cada 'elemento' que sale del canal es un par de archivos: el GVCF y su archivo de índice, en ese orden porque ese es el orden en que están listados en el bloque de salida del proceso. Convenientemente, debido a que en la última sesión nombramos las salidas de este proceso (usando `emit:`), podemos seleccionar los GVCFs por un lado agregando `.vcf` y los archivos de índice por otro agregando `.idx` después de la propiedad `.out`. Si no hubiéramos nombrado esas salidas, habríamos tenido que referirnos a ellas como `.out[0]` y `.out[1]`, respectivamente. +3. Agregamos el operador de canal `collect()` para agrupar todos los archivos GVCF juntos en un solo elemento en un nuevo canal llamado `all_gvcfs_ch`, y hacemos lo mismo con los archivos de índice para formar el nuevo canal llamado `all_idxs_ch`. + +!!! tip + + Si tiene dificultades para visualizar exactamente qué está sucediendo aquí, recuerde que puede usar el operador `view()` para inspeccionar el contenido de los canales antes y después de aplicar operadores de canal. + +Los canales `all_gvcfs_ch` y `all_idxs_ch` resultantes son lo que vamos a conectar en el proceso `GATK_GENOMICSDB` que acabamos de escribir. + +!!! note + + En caso de que se lo estuviera preguntando, recopilamos los GVCFs y sus archivos de índice por separado porque el comando GATK GenomicsDBImport solo quiere ver las rutas de los archivos GVCF. Afortunadamente, dado que Nextflow preparará todos los archivos juntos para la ejecución, no tenemos que preocuparnos por el orden de los archivos como lo hicimos para los BAMs y su índice en la Parte 1. + +### 2.4. Agregar una llamada al bloque de flujo de trabajo para ejecutar GATK_GENOMICSDB + +Tenemos un proceso y tenemos canales de entrada. Solo necesitamos agregar la llamada al proceso. + +```groovy title="genomics-2.nf" linenums="122" + // Combinar GVCFs en un almacén de datos GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, todo está conectado. + +### 2.5. Ejecutar el flujo de trabajo + +Veamos si esto funciona. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Se ejecuta bastante rápido, ya que estamos ejecutando con `-resume`, ¡pero falla! + +Ah. Por el lado positivo, vemos que Nextflow ha recogido el proceso `GATK_GENOMICSDB`, y específicamente lo llamó solo una vez. +Eso sugiere que el enfoque de `collect()` funcionó, hasta cierto punto. +Pero, y es grande, la llamada al proceso falló. + +Cuando profundizamos en la salida de la consola anterior, podemos ver que el comando ejecutado no es correcto. + +¿Puede detectar el error? +Observe este fragmento: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Le dimos a `gatk GenomicsDBImport` múltiples archivos GVCF para un solo argumento `-V`, pero la herramienta espera un argumento `-V` separado para cada archivo GVCF. + +Como recordatorio, este fue el comando que ejecutamos en el contenedor: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Entonces eso significa que necesitamos de alguna manera transformar nuestro paquete de archivos GVCF en una cadena de comando formateada correctamente. + +### 2.6. Construir una línea de comando con un argumento `-V` separado para cada GVCF de entrada + +Aquí es donde Nextflow estar basado en Groovy resulta útil, porque nos permitirá usar algunas manipulaciones de cadenas bastante directas para construir la cadena de comando necesaria. + +Específicamente, usando esta sintaxis: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Una vez más, desglosémoslo en sus componentes. + +1. Primero, tomamos el contenido del canal de entrada `all_gvcfs` y aplicamos `.collect()` en él (al igual que antes). +2. Eso nos permite pasar cada ruta de archivo GVCF individual en el paquete a la **closure**, `{ gvcf -> "-V ${gvcf}" }`, donde `gvcf` se refiere a esa ruta de archivo GVCF. + La closure es una mini-función que usamos para anteponer `-V ` a la ruta del archivo, en la forma de `"-V ${gvcf}"`. +3. Luego usamos `.join(' ')` para concatenar las tres cadenas con un solo espacio como separador. + +Con un ejemplo concreto, se ve así: + +1. Tenemos tres archivos: + + `[A.ext, B.ext, C.ext]` + +2. La closure modifica cada uno para crear las cadenas: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. La operación `.join(' ')` genera la cadena final: + + `"-V A.ext -V B.ext -V C.ext"` + +Una vez que tengamos esa cadena, podemos asignarla a una variable local, `gvcfs_line`, definida con la palabra clave `def`: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, entonces tenemos nuestra cosa de manipulación de cadenas. ¿Dónde la ponemos? + +Queremos que esto vaya dentro de la definición del proceso en alguna parte, porque queremos hacerlo _después_ de haber canalizado las rutas de archivos GVCF en el proceso. +Eso es porque Nextflow debe verlas como rutas de archivos para preparar los archivos en sí correctamente para la ejecución. + +¿Pero _dónde_ en el proceso podemos agregar esto? + +Dato curioso: ¡puede agregar código arbitrario después de `script:` y antes de las `"""`! + +Genial, agreguemos nuestra línea de manipulación de cadenas allí entonces, y actualicemos el comando `gatk GenomicsDBImport` para usar la cadena concatenada que produce. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Eso debería ser todo lo necesario para proporcionar las entradas a `gatk GenomicsDBImport` correctamente. + +!!! tip + + Cuando actualice el comando `gatk GenomicsDBImport`, asegúrese de eliminar el prefijo `-V ` cuando intercambie la variable `${gvcfs_line}`. + +### 2.7. Ejecutar el flujo de trabajo para verificar que genera la salida GenomicsDB como se esperaba + +Muy bien, veamos si eso abordó el problema. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +¡Ajá! Parece estar funcionando ahora. + +Los primeros dos pasos se omitieron exitosamente, y el tercer paso funcionó como un encanto esta vez. +El almacén de datos GenomicsDB se crea en el directorio de trabajo pero no se publica en los resultados, ya que es solo un formato intermedio que usaremos para el genotipado conjunto. + +Por cierto, no tuvimos que hacer nada especial para manejar que la salida sea un directorio en lugar de un solo archivo. + +### Conclusión + +Ahora sabe cómo recopilar salidas de un canal y agruparlas como una única entrada a otro proceso. +También sabe cómo construir una línea de comando para proporcionar entradas a una herramienta dada con la sintaxis apropiada. + +### ¿Qué sigue? + +Aprender cómo agregar un segundo comando al mismo proceso. + +--- + +## 3. Ejecutar el paso de genotipado conjunto como parte del mismo proceso + +Ahora que tenemos los llamados de variantes genómicas combinados, podemos ejecutar la herramienta de genotipado conjunto, que producirá la salida final que realmente nos interesa: el VCF de llamados de variantes a nivel de cohorte. + +Por razones logísticas, decidimos incluir el genotipado conjunto dentro del mismo proceso. + +### 3.1. Renombrar el proceso de GATK_GENOMICSDB a GATK_JOINTGENOTYPING + +Dado que el proceso ejecutará más de una herramienta, cambiamos su nombre para referirse a la operación general en lugar de un solo nombre de herramienta. + +=== "Después" + + ```groovy title="genomics-2.nf" + /* + * Combinar GVCFs en almacén de datos GenomicsDB y ejecutar genotipado conjunto para producir llamados a nivel de cohorte + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" + /* + * Combinar GVCFs en almacén de datos GenomicsDB + */ + process GATK_GENOMICSDB { + ``` + +¡Recuerde mantener sus nombres de procesos lo más descriptivos posible, para maximizar la legibilidad para sus colegas —y su yo futuro! + +### 3.2. Agregar el comando de genotipado conjunto al proceso GATK_JOINTGENOTYPING + +Simplemente agregue el segundo comando después del primero dentro de la sección de script. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Los dos comandos se ejecutarán en serie, de la misma manera que lo harían si los ejecutáramos manualmente en la terminal. + +### 3.3. Agregar los archivos del genoma de referencia a las definiciones de entrada del proceso GATK_JOINTGENOTYPING + +El segundo comando requiere los archivos del genoma de referencia, así que necesitamos agregarlos a las entradas del proceso. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Puede parecer molesto escribirlos, pero recuerde, solo los escribe una vez, y luego puede ejecutar el flujo de trabajo un millón de veces. ¿Vale la pena? + +### 3.4. Actualizar la definición de salida del proceso para emitir el VCF de llamados de variantes a nivel de cohorte + +Realmente no nos importa guardar el almacén de datos GenomicsDB, que es solo un formato intermedio que solo existe por razones logísticas, así que podemos simplemente eliminarlo del bloque de salida si queremos. + +La salida que realmente nos interesa es el VCF producido por el comando de genotipado conjunto. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +¡Casi terminamos! + +### 3.5. Actualizar la llamada al proceso de GATK_GENOMICSDB a GATK_JOINTGENOTYPING + +No olvidemos renombrar la llamada al proceso en el cuerpo del flujo de trabajo de GATK_GENOMICSDB a GATK_JOINTGENOTYPING. Y mientras estamos en eso, también deberíamos agregar los archivos del genoma de referencia como entradas, ya que necesitamos proporcionarlos a la herramienta de genotipado conjunto. + +=== "Después" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinar GVCFs en un almacén de datos GenomicsDB y aplicar genotipado conjunto + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinar GVCFs en un almacén de datos GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Ahora el proceso está completamente conectado. + +### 3.6. Agregar el VCF conjunto a la sección de publicación + +Necesitamos publicar las salidas del VCF conjunto del nuevo proceso. +Agregue estas líneas a la sección `publish:` del flujo de trabajo: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Agregar los destinos del VCF conjunto al bloque de salida + +Finalmente, agregue destinos de salida para los archivos VCF conjuntos. +Los colocaremos en la raíz del directorio de resultados ya que esta es la salida final. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Ahora todo debería estar completamente conectado. + +### 3.8. Ejecutar el flujo de trabajo + +Finalmente, podemos ejecutar el flujo de trabajo modificado... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +¡Y funciona! + +Encontrará el archivo de salida final, `family_trio.joint.vcf` (y su índice de archivo), en el directorio de resultados. + +??? abstract "Contenido del directorio (symlinks acortados)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Si es del tipo escéptico, puede hacer clic en el archivo VCF conjunto para abrirlo y verificar que el flujo de trabajo haya generado los mismos llamados de variantes que obtuvo al ejecutar las herramientas manualmente al comienzo de esta sección. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +¡Ahora tiene un flujo de trabajo de llamado conjunto de variantes automatizado y completamente reproducible! + +!!! note + + Tenga en cuenta que los archivos de datos que le dimos cubren solo una pequeña porción del cromosoma 20. + El tamaño real de un conjunto de llamados de variantes se contaría en millones de variantes. + ¡Por eso usamos solo subconjuntos pequeños de datos para propósitos de entrenamiento! + +### Conclusión + +Sabe cómo usar algunos operadores comunes así como closures de Groovy para controlar el flujo de datos en su flujo de trabajo. + +### ¿Qué sigue? + +Celebre su éxito y tome un merecido descanso. + +En la próxima parte de este curso, aprenderá cómo modularizar su flujo de trabajo extrayendo definiciones de procesos en módulos reutilizables. diff --git a/docs/es/docs/nf4_science/genomics/03_modules.md b/docs/es/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..78c0e09b78 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Parte 3: Mover código a módulos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la primera parte de este curso, construiste un pipeline de llamado de variantes que era completamente lineal y procesaba los datos de cada muestra independientemente de las demás. + +En la segunda parte, te mostramos cómo usar canales y operadores de canal para implementar el llamado conjunto de variantes con GATK, construyendo sobre el pipeline de la Parte 1. + +En esta parte, te mostraremos cómo convertir el código de ese workflow en módulos. Para seguir esta parte del entrenamiento, debes haber completado la Parte 1 y la Parte 2, así como [Hello Modules](../../../hello_nextflow/hello_modules.md), que cubre los conceptos básicos de los módulos. + +--- + +## 0. Calentamiento + +Cuando comenzamos a desarrollar nuestro workflow, pusimos todo en un único archivo de código. +Ahora es momento de abordar la **modularización** de nuestro código, _es decir_, extraer las definiciones de procesos en módulos. + +Vamos a comenzar con el mismo workflow que en la Parte 2, que hemos proporcionado en el archivo `genomics-3.nf`. + +!!! note "Nota" + + Asegúrate de estar en el directorio de trabajo correcto: + `cd /workspaces/training/nf4-science/genomics` + +Ejecuta el workflow para verificar el punto de partida: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Salida" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Ahora habrá un directorio `work` y un directorio `results_genomics` dentro de tu directorio del proyecto. + +### Conclusión + +Estás listo para comenzar a modularizar tu workflow. + +### ¿Qué sigue? + +Mover los procesos del workflow de Genómica a módulos. + +--- + +## 1. Mover procesos a módulos + +Como aprendiste en [Hello Modules](../../../hello_nextflow/hello_modules.md), puedes crear un módulo simplemente copiando la definición del proceso en su propio archivo, en cualquier directorio, y puedes nombrar ese archivo como quieras. + +Por razones que quedarán claras más adelante (en particular cuando lleguemos a las pruebas), en este entrenamiento seguiremos la convención de nombrar el archivo `main.nf`, y colocarlo en una estructura de directorios nombrada según el conjunto de herramientas y el comando. + +### 1.1. Crear un módulo para el proceso `SAMTOOLS_INDEX` + +En el caso del proceso `SAMTOOLS_INDEX`, 'samtools' es el conjunto de herramientas e 'index' es el comando. Entonces, crearemos una estructura de directorios `modules/samtools/index` y pondremos la definición del proceso `SAMTOOLS_INDEX` en el archivo `main.nf` dentro de ese directorio. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Abre el archivo `main.nf` y copia la definición del proceso `SAMTOOLS_INDEX` en él. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * Generar archivo de índice BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Luego, elimina la definición del proceso `SAMTOOLS_INDEX` de `genomics-3.nf`, y agrega una declaración de importación para el módulo antes de la siguiente definición de proceso, así: + +=== "Después" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Incluir módulos + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Llamar variantes con GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Antes" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Llamar variantes con GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +Ahora puedes ejecutar el workflow nuevamente, y debería funcionar de la misma manera que antes. Si proporcionas la bandera `-resume`, ni siquiera deberían ejecutarse nuevas tareas: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Crear módulos para los procesos `GATK_HAPLOTYPECALLER` y `GATK_JOINTGENOTYPING` + +Repite los mismos pasos para los procesos restantes. +Para cada proceso: + +1. Crea la estructura de directorios (`modules/gatk/haplotypecaller/` y `modules/gatk/jointgenotyping/`) +2. Crea un archivo `main.nf` que contenga la definición del proceso +3. Elimina la definición del proceso de `genomics-3.nf` +4. Agrega una declaración de importación para el módulo + +Una vez que hayas terminado, verifica que la estructura de directorios de tus módulos sea correcta ejecutando: + +```bash +tree modules/ +``` + +??? abstract "Contenidos del directorio" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +También deberías tener algo como esto en el archivo principal del workflow, después de la sección de parámetros: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Conclusión + +Has practicado la modularización de un workflow, con el workflow de genómica como ejemplo. + +### ¿Qué sigue? + +Probar el workflow modularizado. + +--- + +## 2. Probar el workflow modularizado + +Ejecuta el workflow modularizado para verificar que todo siga funcionando. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Salida" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Todo sigue funcionando, incluyendo la capacidad de reanudación del pipeline. +Los resultados continúan siendo publicados en el directorio `results_genomics`. + +```console title="Contenidos del directorio" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Conclusión + +Has modularizado un workflow y verificado que sigue funcionando de la misma manera que antes. + +### ¿Qué sigue? + +Revisar lo que has aprendido y mirar hacia adelante a las pruebas. + +--- + +## 3. Resumen + +Has modularizado el workflow, y nada ha cambiado en cómo funciona el pipeline. +Esto es intencional: has reestructurado el código sin impactar su función. + +Los módulos contienen solo la lógica del proceso, haciéndolos limpios y reutilizables. +El script principal controla qué se publica y dónde, mientras que los módulos permanecen enfocados en su tarea computacional. + +Has sentado las bases para cosas que harán tu código más fácil de mantener. +Por ejemplo, ahora puedes agregar pruebas a tu pipeline usando el framework nf-test. +Esto es lo que veremos en la siguiente parte de este curso. diff --git a/docs/es/docs/nf4_science/genomics/04_testing.md b/docs/es/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..9508297148 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Parte 4: Agregando pruebas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la primera parte de este curso, construiste un pipeline de llamado de variantes que fue completamente lineal y procesó los datos de cada muestra de forma independiente de las otras. + +En la segunda parte, te mostramos cómo usar canales y operadores de canal para implementar el llamado conjunto de variantes con GATK. + +En la tercera parte, modularizamos el pipeline. + +En esta parte del entrenamiento, vamos a mostrarte cómo usar [**nf-test**](https://www.nf-test.com/), un marco de pruebas que se integra bien con Nextflow y facilita agregar pruebas tanto a nivel de módulo como a nivel de flujo de trabajo a tu pipeline. Para seguir esta parte del entrenamiento, deberías haber completado la Parte 1, Parte 2 y Parte 3, así como la [misión secundaria de nf-test](../../side_quests/nf-test.md), que cubre los conceptos básicos de nf-test y por qué las pruebas son importantes. + +--- + +## 0. Calentamiento + +!!! note "Nota" + + Asegúrate de estar en el directorio de trabajo correcto: + `cd /workspaces/training/nf4-science/genomics` + +Si trabajaste en las partes anteriores de este curso de entrenamiento, deberías tener una versión funcional del pipeline de genómica con la estructura de directorios de módulos apropiada. + +??? abstract "Contenido del directorio" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Este directorio de módulos se puede encontrar en el directorio `solutions` si lo necesitas. + +Vamos a comenzar con el mismo flujo de trabajo que en la Parte 3, que hemos proporcionado en el archivo `genomics-4.nf`. Exactamente como en la [misión secundaria de nf-test](../../side_quests/nf-test.md), vamos a agregar algunos tipos diferentes de pruebas a los tres procesos en este pipeline, así como una prueba a nivel de flujo de trabajo. + +### 0.1. Verificar que el flujo de trabajo se ejecute + +Antes de comenzar a agregar pruebas, asegúrate de que el flujo de trabajo se ejecute como se espera. + +```bash +nextflow run genomics-4.nf -resume +``` + +Esto debería verse muy familiar a estas alturas si has estado trabajando en este curso de entrenamiento desde el principio. + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Como anteriormente, ahora habrá un directorio `work` y un directorio `results_genomics` dentro de tu directorio de proyecto. Realmente haremos uso de estos resultados más adelante en nuestras pruebas. Pero a partir de ahora vamos a usar el paquete `nf-test` para probar el pipeline. + +### 0.2. Inicializar `nf-test` + +Como en la [misión secundaria de nf-test](../../side_quests/nf-test.md), necesitamos inicializar el paquete `nf-test`. + +```bash +nf-test init +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "Contenido de nf-test.config" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +También crea un directorio `tests` que contiene un esqueleto de archivo de configuración. + +### Conclusión + +Ahora estamos listos para comenzar a escribir pruebas para nuestro pipeline de genómica. + +### ¿Qué sigue? + +Escribir pruebas básicas que evalúen si las llamadas a los procesos fueron exitosas y produjeron las salidas correctas. + +--- + +## 1. Probar un proceso para éxito y salidas coincidentes + +Comenzaremos probando el proceso `SAMTOOLS_INDEX`, que crea archivos de índice para archivos BAM para permitir un acceso aleatorio eficiente. Este es un buen primer caso de prueba porque: + +1. Tiene una única entrada bien definida (un archivo BAM) +2. Produce una salida predecible (un archivo de índice BAI) +3. La salida debería ser idéntica para entradas idénticas + +### 1.1. Generar un esqueleto de archivo de prueba + +Primero, genera un esqueleto de archivo de prueba: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Salida del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Esto crea un archivo en el mismo directorio que `main.nf`. +Puedes navegar al directorio en el explorador de archivos y abrir el archivo, que debería contener el siguiente código: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Las afirmaciones iniciales deberían ser familiares de la [misión secundaria de nf-test](../../side_quests/nf-test.md): + +- `assert process.success` establece que esperamos que el proceso se ejecute exitosamente y se complete sin fallas. +- `snapshot(process.out).match()` establece que esperamos que el resultado de la ejecución sea idéntico al resultado obtenido en una ejecución anterior (si aplica). + Discutimos esto con más detalle más adelante. + +Usando esto como punto de partida, necesitamos agregar las entradas de prueba correctas para el proceso de índice de samtools, y cualquier parámetro si aplica. + +### 1.2. Mover el archivo de prueba y actualizar la ruta del script + +Antes de comenzar a trabajar en completar la prueba, necesitamos mover el archivo a su ubicación definitiva. Parte de la razón por la que agregamos un directorio para cada módulo es que ahora podemos enviar pruebas en un directorio `tests` co-ubicado con el archivo `main.nf` de cada módulo. Crea ese directorio y mueve el archivo de prueba allí. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Ahora podemos simplificar la sección `script` del archivo de prueba a una ruta relativa: + +=== "Después" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Esto le dice a la prueba dónde encontrar el archivo `main.nf` del módulo, sin tener que especificar la ruta completa. + +### 1.3. Proporcionar entradas de prueba para SAMTOOLS_INDEX + +El archivo esqueleto incluye un marcador de posición que necesitamos reemplazar con una entrada de prueba real, apropiada para la entrada de `samtools index`. La entrada apropiada es un archivo BAM, que tenemos disponible en el directorio `data/bam`. + +=== "Después" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Nombrar la prueba basándose en la funcionalidad + +Como aprendimos antes, es una buena práctica renombrar la prueba a algo que tenga sentido en el contexto de la prueba. + +=== "Después" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Esto toma una cadena arbitraria, así que podríamos poner lo que queramos. + Aquí elegimos referirnos al nombre del archivo y su formato. + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Ejecutar la prueba y examinar la salida + +Ejecuta la prueba: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Como aprendimos anteriormente, esto verificó la afirmación básica sobre el éxito del proceso y creó un archivo de snapshot basado en la salida del proceso. Podemos ver el contenido del archivo snapshot en el archivo `tests/modules/samtools/index/tests/main.nf.test.snap`: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +También podemos ejecutar la prueba nuevamente y ver que pasa, porque la salida es idéntica al snapshot: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Agregar más pruebas a `SAMTOOLS_INDEX` + +A veces es útil probar un rango de diferentes archivos de entrada para asegurarnos de que estamos probando una variedad de problemas potenciales. Agrega pruebas para los archivos BAM de la madre y el padre en el trío de nuestros datos de prueba. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Luego puedes ejecutar la prueba nuevamente: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Observa la advertencia, refiriéndose al efecto del parámetro `--update-snapshot`. + +!!! note "Nota" + + Aquí estamos usando datos de prueba que usamos anteriormente para demostrar las salidas científicas del pipeline. + Si hubiéramos estado planeando operar estas pruebas en un entorno de producción, habríamos generado entradas más pequeñas para propósitos de prueba. + + En general es importante mantener las pruebas unitarias lo más ligeras posible usando las piezas de datos más pequeñas necesarias y suficientes para evaluar la funcionalidad del proceso, de lo contrario el tiempo de ejecución total puede acumularse bastante seriamente. + Una suite de pruebas que tarda demasiado en ejecutarse regularmente es una suite de pruebas que probablemente se omitirá en interés de la conveniencia. + +### Conclusión + +Has escrito tu primera prueba de módulo para un proceso de genómica, verificando que `SAMTOOLS_INDEX` crea correctamente archivos de índice para diferentes archivos BAM. La suite de pruebas asegura que: + +1. El proceso se ejecuta exitosamente +2. Se crean archivos de índice +3. Las salidas son consistentes a través de las ejecuciones +4. El proceso funciona para todos los archivos BAM de muestra + +### ¿Qué sigue? + +Aprender cómo escribir pruebas para otros procesos en nuestro flujo de trabajo de genómica, usando el método setup para manejar procesos encadenados. También evaluaremos si las salidas, específicamente nuestros archivos VCF, contienen las llamadas de variantes esperadas. + +--- + +## 2. Agregar pruebas a un proceso encadenado y probar contenido + +Para probar `GATK_HAPLOTYPECALLER`, necesitamos proporcionar al proceso la salida de `SAMTOOLS_INDEX` como entrada. Podríamos hacer eso ejecutando `SAMTOOLS_INDEX`, recuperando sus salidas, y almacenándolas con los datos de prueba para el flujo de trabajo. Ese es en realidad el enfoque recomendado para un pipeline pulido, pero nf-test proporciona un enfoque alternativo, usando el método `setup`. + +Con el método setup, podemos activar el proceso `SAMTOOLS_INDEX` como parte de la configuración de la prueba, y luego usar su salida como entrada para `GATK_HAPLOTYPECALLER`. Esto tiene un costo: vamos a tener que ejecutar el proceso `SAMTOOLS_INDEX` cada vez que ejecutemos la prueba para `GATK_HAPLOTYPECALLER`. Sin embargo, tal vez todavía estamos desarrollando el flujo de trabajo y no queremos pre-generar datos de prueba que podríamos tener que cambiar más tarde. El proceso `SAMTOOLS_INDEX` también es muy rápido, así que tal vez los beneficios de pre-generar y almacenar sus salidas son insignificantes. Así es como funciona el método setup. + +### 2.1. Generar y ubicar el archivo de prueba + +Como anteriormente, primero generamos el esqueleto de archivo: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Salida del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Esto produce el siguiente esqueleto de prueba: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Mover el archivo de prueba y actualizar la ruta del script + +Creamos un directorio para el archivo de prueba co-ubicado con el archivo `main.nf` del módulo: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +Y movemos el archivo esqueleto de prueba allí: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Finalmente, no olvides actualizar la ruta del script: + +=== "Después" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Proporcionar entradas usando el método setup + +Insertamos un bloque `setup` antes del bloque `when`, donde podemos activar una ejecución del proceso `SAMTOOLS_INDEX` en uno de nuestros archivos de entrada originales. Además, recuerda como antes cambiar el nombre de la prueba a algo significativo. + +=== "Después" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Luego podemos referirnos a la salida de ese proceso en el bloque `when` donde especificamos las entradas de prueba: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Realiza ese cambio y ejecuta la prueba nuevamente: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +También produce un archivo snapshot como anteriormente. + +### 2.4. Ejecutar nuevamente y observar falla + +Curiosamente, si ejecutas exactamente el mismo comando nuevamente, esta vez la prueba fallará. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +El mensaje de error te dice que hubo diferencias entre los snapshots para las dos ejecuciones; específicamente, los valores md5sum son diferentes para los archivos VCF. + +¿Por qué? Para hacer una larga historia corta, la herramienta HaplotypeCaller incluye una marca de tiempo en el encabezado del VCF que es diferente cada vez (por definición). +Como resultado, no podemos simplemente esperar que los archivos tengan md5sums idénticos incluso si tienen contenido idéntico en términos de las llamadas de variantes en sí. + +¿Cómo lidiamos con eso? + +### 2.5. Usar un método de afirmación de contenido para verificar una variante específica + +Una forma de resolver el problema es usar un [tipo diferente de afirmación](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions). +En este caso, vamos a verificar contenido específico en lugar de afirmar identidad. +Más exactamente, haremos que la herramienta lea las líneas del archivo VCF y verifique la existencia de líneas específicas. + +En la práctica, reemplazamos la segunda afirmación en el bloque `then` de la siguiente manera: + +=== "Después" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Aquí estamos leyendo el contenido completo del archivo de salida VCF y buscando una coincidencia de contenido, lo cual está bien hacer en un archivo de prueba pequeño, pero no querrías hacer eso en un archivo más grande. +En su lugar, podrías elegir leer líneas específicas. + +Este enfoque requiere elegir más cuidadosamente qué queremos usar como 'señal' para probar. +En el lado positivo, se puede usar para probar con gran precisión si una herramienta de análisis puede identificar consistentemente características 'difíciles' (como variantes raras) a medida que experimenta un mayor desarrollo. + +### 2.6. Ejecutar nuevamente y observar éxito + +Una vez que hemos modificado la prueba de esta manera, podemos ejecutar la prueba múltiples veces, y pasará consistentemente. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Agregar más pruebas + +Agrega pruebas similares para las muestras de la madre y el padre: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Ejecutar el comando de prueba + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Eso completa el plan de prueba básico para este segundo paso en el pipeline. ¡Hacia la tercera y última prueba a nivel de módulo! + +### Conclusión + +Has aprendido cómo: + +1. Probar procesos que dependen de salidas de otros procesos +2. Verificar variantes genómicas específicas en archivos de salida VCF +3. Manejar salidas no determinísticas verificando contenido específico +4. Probar llamado de variantes a través de múltiples muestras + +### ¿Qué sigue? + +Aprender cómo escribir pruebas que usen datos de prueba pre-generados para el paso de genotipado conjunto. + +--- + +## 3. Usar datos de prueba pre-generados + +Para el paso de genotipado conjunto, usaremos un enfoque diferente - usar datos de prueba pre-generados. Esto suele ser preferible para: + +1. Procesos complejos con múltiples dependencias +2. Procesos que toman mucho tiempo en ejecutarse +3. Procesos que son parte de un pipeline estable, de producción + +### 3.1. Generar datos de prueba + +Inspecciona los resultados que generamos al inicio de esta sección: + +```bash +tree results_genomics/ +``` + +```console title="Contenido del directorio de resultados" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +El paso de genotipado conjunto necesita los archivos VCF producidos por los pasos del llamador de haplotipo como entradas, junto con los índices. Así que copiemos los resultados que tenemos al directorio de prueba del módulo `jointgenotyping`. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Ahora podemos usar estos archivos como entradas a la prueba que vamos a escribir para el paso de genotipado conjunto. + +### 3.2. Generar el esqueleto de archivo de prueba + +Como anteriormente, primero generamos el esqueleto de archivo: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Salida del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Esto produce el siguiente esqueleto de prueba: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Mover el archivo de prueba y actualizar la ruta del script + +Esta vez ya tenemos un directorio para pruebas co-ubicado con el archivo `main.nf` del módulo, así que podemos mover el archivo esqueleto de prueba allí: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +Y no olvides actualizar la ruta del script: + +=== "Después" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Antes" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Proporcionar entradas + +Completa las entradas basándose en las definiciones de entrada del proceso y renombra la prueba en consecuencia: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Usar afirmaciones de contenido + +La salida del paso de genotipado conjunto es otro archivo VCF, así que vamos a usar una afirmación de contenido nuevamente. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Al verificar el contenido de una variante específica en el archivo de salida, esta prueba verifica que: + +1. El proceso de genotipado conjunto se ejecuta exitosamente +2. El VCF de salida contiene las tres muestras en el orden correcto +3. Una variante específica es llamada correctamente con: + - Genotipos precisos para cada muestra (0/1 para el padre, 1/1 para la madre y el hijo) + - Profundidades de lectura y calidades de genotipo correctas + - Estadísticas a nivel de población como la frecuencia alélica (AF=0.833) + +No hemos tomado un snapshot del archivo completo, pero al verificar una variante específica, podemos estar seguros de que el proceso de genotipado conjunto está funcionando como se espera. + +### 3.6. Ejecutar la prueba + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +La prueba pasa, verificando que nuestro proceso de genotipado conjunto correctamente: + +1. Combina VCFs de muestras individuales +2. Realiza llamado de variantes conjunto +3. Produce un VCF de múltiples muestras con llamados de genotipo consistentes a través de las ejecuciones + +### Conclusión + +Sabes cómo: + +- Usar resultados generados previamente como entradas para pruebas +- Escribir pruebas usando datos de prueba pre-generados + +### ¿Qué sigue? + +Agregar una prueba a nivel de flujo de trabajo para verificar que todo el pipeline de llamado de variantes funcione de principio a fin. + +--- + +## 4. Agregar una prueba a nivel de flujo de trabajo + +Ahora probaremos el pipeline completo de llamado de variantes, desde archivos BAM hasta genotipos conjuntos. Esto verifica que: + +1. Todos los procesos funcionan juntos correctamente +2. Los datos fluyen apropiadamente entre pasos +3. Las llamadas de variantes finales son consistentes + +### 4.1. Generar la prueba de flujo de trabajo + +Genera un archivo de prueba para el pipeline completo: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Salida del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Esto crea un esqueleto de prueba básico: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Solo corrige el nombre a algo significativo (verás por qué esto es útil en breve). + +=== "Después" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Antes" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "Nota" + + En este caso el archivo de prueba puede permanecer donde `nf-test` lo creó. + +### 4.2. Especificar parámetros de entrada + +Todavía necesitamos especificar entradas, lo cual se hace ligeramente diferente a nivel de flujo de trabajo comparado con las pruebas a nivel de módulo. +Hay varias formas de hacer esto, incluyendo especificando un perfil. +Sin embargo, una forma más simple es configurar un bloque `params {}` en el archivo `nextflow.config` que `nf-test init` creó originalmente en el directorio `tests`. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow config file for running tests +======================================================================================== +*/ + +// Directorio de salida para salidas del flujo de trabajo +outputDir = 'results_genomics' + +/* + * Parámetros del pipeline + */ + +params { + // Entrada primaria (archivo de archivos de entrada, uno por línea) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Archivos accesorios + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Nombre base para el archivo de salida final + cohort_name = "family_trio" +} +``` + +Cuando ejecutemos la prueba, `nf-test` recogerá este archivo de configuración y extraerá las entradas en consecuencia. + +### 4.3. Ejecutar la prueba de flujo de trabajo + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +La prueba pasa, confirmando que nuestro pipeline completo de llamado de variantes: + +1. Procesa exitosamente todas las muestras +2. Encadena correctamente todos los pasos + +### 4.4. Ejecutar TODAS las pruebas + +nf-test tiene un truco más bajo la manga. ¡Podemos ejecutar todas las pruebas a la vez! Modifica el archivo `nf-test.config` para que nf-test busque en cada directorio archivos de nf-test. Puedes hacer esto modificando el parámetro `testsDir`: + +=== "Después" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Antes" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Ahora, simplemente podemos ejecutar nf-test y ejecutará _cada prueba individual_ en nuestro repositorio: + +```bash +nf-test test +``` + +??? success "Salida del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +¡8 pruebas en 1 comando! Pasamos mucho tiempo configurando muchas pruebas, pero cuando llegó el momento de ejecutarlas fue muy rápido y fácil. Puedes ver lo útil que es esto cuando se mantiene un pipeline grande, que podría incluir cientos de elementos diferentes. Pasamos tiempo escribiendo pruebas una vez para poder ahorrar tiempo ejecutándolas muchas veces. + +Además, ¡podemos automatizar esto! Imagina pruebas ejecutándose cada vez que tú o un colega intenta agregar código nuevo. Así es como aseguramos que nuestros pipelines mantengan un alto estándar. + +## Conclusión + +Ahora sabes cómo escribir y ejecutar varios tipos de pruebas para tu pipeline de genómica usando nf-test. Este marco de pruebas ayuda a asegurar que tu flujo de trabajo de llamado de variantes produzca resultados consistentes y confiables en diferentes entornos y a medida que realizas cambios en el código. + +Has aprendido a probar componentes críticos como: + +- El proceso `SAMTOOLS_INDEX` que prepara archivos BAM para el llamado de variantes +- El proceso `GATK_HAPLOTYPECALLER` que identifica variantes en muestras individuales +- El proceso `GATK_JOINTGENOTYPING` que combina llamadas de variantes a través de una cohorte + +También has implementado diferentes estrategias de prueba específicas para datos genómicos: + +- Verificar que los archivos VCF contengan las llamadas de variantes esperadas a pesar de elementos no determinísticos como marcas de tiempo +- Probar con un conjunto de datos de trío familiar para asegurar la identificación apropiada de variantes a través de muestras relacionadas +- Verificar coordenadas genómicas específicas e información de variantes en tus archivos de salida + +Estas habilidades de prueba son esenciales para desarrollar pipelines bioinformáticos robustos que puedan procesar datos genómicos de manera confiable y producir llamadas de variantes precisas. A medida que continúes trabajando con Nextflow para análisis genómico, esta base de pruebas te ayudará a mantener código de alta calidad que produzca resultados científicos confiables. diff --git a/docs/es/docs/nf4_science/genomics/05_configuration.md b/docs/es/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..f776964062 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Parte 3: Perfilado y optimización de recursos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +ESTO ES UN MARCADOR DE POSICIÓN + +!!!note "Nota" + + Este módulo de entrenamiento está en proceso de rediseño. + +--- + +POR HACER + +### 1.1. Ejecutar el flujo de trabajo para generar un reporte de utilización de recursos + +Para que Nextflow genere el reporte automáticamente, simplemente agregue `-with-report <nombre_archivo>.html` a su línea de comando. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +El reporte es un archivo html, que puede descargar y abrir en su navegador. También puede hacer clic derecho sobre él en el explorador de archivos de la izquierda y hacer clic en `Show preview` para visualizarlo en VS Code. + +Tómese unos minutos para revisar el reporte y ver si puede identificar algunas oportunidades para ajustar los recursos. +Asegúrese de hacer clic en las pestañas que muestran los resultados de utilización como un porcentaje de lo que fue asignado. +Hay [documentación](https://www.nextflow.io/docs/latest/reports.html) disponible que describe todas las características. + +<!-- TODO: insert images --> + +Una observación es que `GATK_JOINTGENOTYPING` parece tener mucha demanda de CPU, lo cual tiene sentido ya que realiza muchos cálculos complejos. +Así que podríamos intentar aumentar eso y ver si reduce el tiempo de ejecución. + +Sin embargo, parece que nos hemos excedido con las asignaciones de memoria; todos los procesos solo están usando una fracción de lo que les estamos dando. +Deberíamos reducir eso y ahorrar algunos recursos. + +### 1.2. Ajustar las asignaciones de recursos para un proceso específico + +Podemos especificar asignaciones de recursos para un proceso dado usando el selector de proceso `withName`. +La sintaxis se ve así cuando está por sí sola en un bloque process: + +```groovy title="Sintaxis" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Agreguemos eso al bloque process existente en el archivo `nextflow.config`. + +```groovy title="nextflow.config" linenums="11" +process { + // valores predeterminados para todos los procesos + cpus = 2 + memory = 2.GB + // asignaciones para un proceso específico + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Con eso especificado, la configuración predeterminada se aplicará a todos los procesos **excepto** el proceso `GATK_JOINTGENOTYPING`, que es un caso especial que obtiene mucho más CPU. +Esperemos que eso tenga un efecto. + +### 1.3. Ejecutar nuevamente con la configuración modificada + +Ejecutemos el flujo de trabajo nuevamente con la configuración modificada y con la bandera de reporte activada, pero note que estamos dando al reporte un nombre diferente para poder diferenciarlos. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Una vez más, probablemente no notará una diferencia sustancial en el tiempo de ejecución, porque esta es una carga de trabajo tan pequeña y las herramientas pasan más tiempo en tareas auxiliares que en realizar el trabajo 'real'. + +Sin embargo, el segundo reporte muestra que nuestra utilización de recursos está más equilibrada ahora. + +<!-- **TODO: screenshots?** --> + +Como puede ver, este enfoque es útil cuando sus procesos tienen diferentes requisitos de recursos. Le permite dimensionar correctamente las asignaciones de recursos que configura para cada proceso basándose en datos reales, no en conjeturas. + +!!!note "Nota" + + Esto es solo una pequeña muestra de lo que puede hacer para optimizar su uso de recursos. + Nextflow tiene una [lógica de reintento dinámico](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) realmente útil incorporada para reintentar trabajos que fallan debido a limitaciones de recursos. + Además, Seqera Platform ofrece herramientas impulsadas por IA para optimizar sus asignaciones de recursos automáticamente también. + + Cubriremos ambos enfoques en una próxima parte de este curso de entrenamiento. + +Dicho esto, puede haber algunas restricciones sobre lo que puede (o debe) asignar dependiendo del ejecutor de cómputo y la infraestructura de cómputo que esté usando. Por ejemplo, su clúster puede requerir que se mantenga dentro de ciertos límites que no se aplican cuando está ejecutando en otro lugar. diff --git a/docs/es/docs/nf4_science/genomics/index.md b/docs/es/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..e53496ff7f --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/index.md @@ -0,0 +1,36 @@ +# Nextflow para Genómica + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de entrenamiento está dirigido a investigadores en genómica y campos relacionados que estén interesados en desarrollar o personalizar pipelines de análisis de datos. +Se basa en el entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/) y demuestra cómo usar Nextflow en el contexto específico del dominio de la genómica. + +Específicamente, este curso demuestra cómo implementar un pipeline simple de llamado de variantes con [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit), un paquete de software ampliamente utilizado para analizar datos de secuenciación de alto rendimiento. + +¡Comencemos! Haga clic en el botón "Open in GitHub Codespaces" a continuación para iniciar el entorno de entrenamiento (preferiblemente en una pestaña separada), luego continúe leyendo mientras se carga. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizaje + +Al completar este curso, aprenderá cómo aplicar conceptos y herramientas fundamentales de Nextflow a un caso de uso típico de genómica. + +Al final de este taller será capaz de: + +- Escribir un workflow lineal para aplicar llamado de variantes a una única muestra +- Manejar archivos accesorios como archivos de índice y recursos del genoma de referencia de manera apropiada +- Aprovechar el paradigma de flujo de datos de Nextflow para paralelizar el llamado de variantes por muestra +- Implementar llamado de variantes de múltiples muestras utilizando operadores de canal relevantes +- Implementar pruebas por paso y de extremo a extremo del pipeline que manejen idiosincrasias específicas de genómica de manera apropiada + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Requisitos previos + +El curso asume cierta familiaridad mínima con lo siguiente: + +- Herramientas y formatos de archivo comúnmente utilizados en este dominio científico +- Experiencia con la línea de comandos +- Conceptos fundamentales de Nextflow y herramientas cubiertas en el entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/) + +Para requisitos técnicos y configuración del entorno, consulte el mini-curso [Configuración del Entorno](../../envsetup/). diff --git a/docs/es/docs/nf4_science/genomics/next_steps.md b/docs/es/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..0466e3fbe0 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Próximos Pasos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicitaciones nuevamente por completar el curso de entrenamiento Nextflow para Genómica y gracias por completar nuestra encuesta! + +--- + +## 1. Las 3 mejores formas de mejorar sus habilidades en Nextflow + +Aquí están nuestras tres principales recomendaciones sobre qué hacer a continuación basadas en el curso que acaba de completar. + +### 1.1. Aplique Nextflow a otros casos de uso de análisis científico + +**Consulte la página [Nextflow para Ciencia](../index.md)** para ver una lista de otros cursos cortos independientes que demuestran cómo aplicar los conceptos básicos y mecanismos presentados en Hello Nextflow a casos de uso comunes de análisis científico. + +Si no ve su dominio representado por un caso de uso relacionado, háganoslo saber en el [foro de la Comunidad](https://community.seqera.io/) para que podamos agregarlo a nuestra lista de desarrollo. + +### 1.2. Comience con nf-core + +**[nf-core](https://nf-co.re/)** es un esfuerzo colaborativo mundial para desarrollar pipelines de código abierto estandarizados para una amplia gama de aplicaciones de investigación científica. +El proyecto incluye [más de 100 pipelines](https://nf-co.re/pipelines/) que están disponibles para usar de inmediato y [más de 1400 módulos de proceso](https://nf-co.re/modules/) que pueden integrarse en sus propios proyectos, así como un rico conjunto de herramientas para desarrolladores. + +El curso de entrenamiento **[Hello nf-core](../../hello_nf-core/index.md)** le presentará los pipelines curados por la comunidad nf-core y el marco de desarrollo, diseñados para ayudarle a escribir workflows reproducibles, escalables y estandarizados. Aprenderá cómo usar pipelines nf-core existentes, contribuir a su desarrollo e incluso comenzar a construir los suyos propios, respaldado por mejores prácticas y una comunidad vibrante. Si está listo para aplicar sus habilidades de Nextflow en proyectos del mundo real, este es el siguiente paso perfecto. + +### 1.3. Domine características más avanzadas de Nextflow + +En los cursos Hello, mantenemos el nivel de complejidad técnica bajo a propósito para evitar sobrecargarlo con información que no necesita para comenzar con Nextflow. +A medida que avance con su trabajo, querrá aprender cómo usar el conjunto completo de características y el poder de Nextflow. + +Con ese fin, actualmente estamos trabajando en una **colección de [Side Quests](../side_quests/index.md)**, que están destinados a ser cursos cortos independientes que profundizan en temas específicos como pruebas y manejo de metadatos. + +--- + +## 2. Consulte Seqera Platform + +**[Seqera Platform](https://seqera.io/) es la mejor manera de ejecutar Nextflow en la práctica.** + +Es una plataforma basada en la nube desarrollada por los creadores de Nextflow que puede conectar a su propia infraestructura de cómputo (ya sea local, HPC o nube) para facilitar mucho el lanzamiento y la gestión de sus workflows, así como gestionar sus datos y ejecutar análisis de forma interactiva en un entorno de nube. + +El nivel gratuito (Free Tier) está disponible para uso gratuito por parte de todos (con cuotas de uso). +Los académicos que califiquen pueden obtener acceso gratuito de nivel Pro (sin limitaciones de uso) a través del [Programa Académico](https://seqera.io/academic/program/). + +Eche un vistazo a los [tutoriales de Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) para ver si esto podría serle útil. + +--- + +### ¡Eso es todo por ahora! + +**Buena suerte en su viaje con Nextflow y no dude en hacernos saber en el [foro de la Comunidad](https://community.seqera.io/) qué más podríamos hacer para ayudar.** diff --git a/docs/es/docs/nf4_science/genomics/survey.md b/docs/es/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..b618c20249 --- /dev/null +++ b/docs/es/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Encuesta de retroalimentación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, por favor complete esta breve encuesta de 5 preguntas para calificar el entrenamiento, compartir cualquier comentario que pueda tener sobre su experiencia y hacernos saber qué más podríamos hacer para ayudarlo en su camino con Nextflow. + +Esto le tomará menos de un minuto completar. ¡Gracias por ayudarnos a mejorar nuestros materiales de entrenamiento para todos! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/es/docs/nf4_science/imaging/00_orientation.md b/docs/es/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..61368e69f6 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta orientación asume que ya ha abierto el entorno de entrenamiento haciendo clic en el botón "Open in GitHub Codespaces". +Si no lo ha hecho, hágalo ahora, idealmente en una segunda ventana o pestaña del navegador para poder consultar estas instrucciones. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Requisito de tamaño de máquina" + + Asegúrese de seleccionar una **máquina de 8 núcleos** al crear su Codespace para este curso de entrenamiento. Los flujos de trabajo de bioimagen requieren recursos computacionales adicionales. + +## GitHub Codespaces + +El entorno de GitHub Codespaces contiene todo el software, código y datos necesarios para trabajar en este curso de entrenamiento, por lo que no necesita instalar nada usted mismo. +Sin embargo, sí necesita una cuenta (gratuita) de GitHub para iniciar sesión, y si no está familiarizado con la interfaz, debería tomarse unos minutos para familiarizarse con ella completando el mini-curso [GitHub Codespaces Orientation](../../envsetup/index.md). + +## Pre-descargar imágenes de Docker + +Una vez que haya abierto su Codespace, pre-descarguemos todas las imágenes de Docker que necesitaremos para este curso de entrenamiento. +Esto ahorrará tiempo más adelante y asegurará una ejecución fluida de los flujos de trabajo. + +Abra una nueva pestaña de terminal y ejecute el siguiente comando: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Este comando descargará todas las imágenes de Docker necesarias en segundo plano. +Puede continuar con el resto de la orientación mientras esto se ejecuta. + +!!!tip "Consejo" + + La bandera `-stub` permite que el pipeline se ejecute rápidamente sin procesar datos reales, lo cual es perfecto para descargar imágenes. Puede monitorear el progreso en la pestaña de terminal. + +## Directorio de trabajo + +A lo largo de este curso de entrenamiento, trabajaremos en el directorio `nf4-science/imaging/`. + +Cambie de directorio ahora ejecutando este comando en la terminal: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "Consejo" + + Si por alguna razón se mueve fuera de este directorio, siempre puede usar la ruta completa para regresar a él, asumiendo que está ejecutando esto dentro del entorno de entrenamiento de GitHub Codespaces: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Ahora, para comenzar el curso, haga clic en la flecha en la esquina inferior derecha de esta página.** diff --git a/docs/es/docs/nf4_science/imaging/01_basics.md b/docs/es/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..978110a87a --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Parte 1: Ejecutar operaciones básicas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta primera parte del curso de entrenamiento de Nextflow para Bioimagen, utilizaremos un ejemplo muy básico de Hello World independiente del dominio para demostrar las operaciones esenciales y señalar los componentes de código de Nextflow correspondientes. + +## 1. Ejecutar el workflow + +Le proporcionamos un script de workflow llamado `hello-world.nf` que recibe una entrada mediante un argumento de línea de comandos llamado `--greeting` y produce un archivo de texto que contiene ese saludo. +Todavía no vamos a ver el código; primero veamos cómo se ve ejecutarlo. + +### 1.1. Lanzar el workflow y monitorear la ejecución + +En la terminal, ejecute el siguiente comando: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +La salida de su consola debería verse algo así: + +```console title="Output" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +¡Felicidades, acaba de ejecutar su primer workflow de Nextflow! + +La salida más importante aquí es la última línea (línea 6): + +```console title="Output" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Esto nos dice que el proceso `sayHello` fue ejecutado exitosamente una vez (`1 of 1 ✔`). + +Eso es genial, pero puede estar preguntándose: ¿dónde está la salida? + +### 1.2. Encontrar el archivo de salida en el directorio `results` + +Este workflow está configurado para publicar su salida en un directorio llamado `results`. +Si observa su directorio actual, verá que cuando ejecutó el workflow, Nextflow creó un nuevo directorio llamado `results`, que contiene un archivo llamado `output.txt`. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Abra el archivo; el contenido debería coincidir con el saludo que especificó en la línea de comandos. + +<details> + <summary>Contenido del archivo</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +¡Eso es genial, nuestro workflow hizo lo que se suponía que debía hacer! + +Sin embargo, tenga en cuenta que el resultado 'publicado' es una copia (o en algunos casos un enlace simbólico) de la salida real producida por Nextflow cuando ejecutó el workflow. + +Así que ahora, vamos a mirar bajo el capó para ver dónde Nextflow realmente ejecutó el trabajo. + +!!! warning "Advertencia" + + No todos los workflows estarán configurados para publicar las salidas en un directorio de resultados, y/o el nombre del directorio puede ser diferente. + Un poco más adelante en esta sección, le mostraremos cómo averiguar dónde se especifica este comportamiento. + +### 1.3. Encontrar la salida original y los logs en el directorio `work/` + +Cuando ejecuta un workflow, Nextflow crea un 'directorio de tarea' distinto para cada invocación de cada proceso en el workflow (=cada paso en el pipeline). +Para cada uno, preparará las entradas necesarias, ejecutará la(s) instrucción(es) relevante(s) y escribirá las salidas y archivos de log dentro de ese único directorio, que se nombra automáticamente usando un hash para hacerlo único. + +Todos estos directorios de tarea vivirán bajo un directorio llamado `work` dentro de su directorio actual (donde está ejecutando el comando). + +Eso puede sonar confuso, así que veamos cómo se ve eso en la práctica. + +Volviendo a la salida de la consola para el workflow que ejecutamos anteriormente, teníamos esta línea: + +```console title="Extracto de la salida del comando" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +¿Ve cómo la línea comienza con `[a3/7be2fa]`? +Esa es una forma truncada de la ruta del directorio de tarea para esa llamada de proceso, y le dice dónde encontrar la salida de la llamada al proceso `sayHello` dentro de la ruta del directorio `work/`. + +Puede encontrar la ruta completa escribiendo el siguiente comando (reemplazando `a3/7be2fa` con lo que ve en su propia terminal) y presionando la tecla tab para autocompletar la ruta o agregando un asterisco: + +```bash +tree work/a3/7be2fa* +``` + +Esto debería producir la ruta completa del directorio: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Echemos un vistazo a lo que hay ahí. + +!!! Tip "Consejo" + + Si navega por el contenido del subdirectorio de tarea en el explorador de archivos de VSCode, verá todos los archivos de inmediato. + Sin embargo, los archivos de log están configurados para ser invisibles en la terminal, así que si desea usar `ls` o `tree` para verlos, deberá establecer la opción relevante para mostrar archivos invisibles. + + ```bash + tree -a work + ``` + +Los nombres exactos de los subdirectorios serán diferentes en su sistema. + +<details> + <summary>Contenido del directorio</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Debería reconocer inmediatamente el archivo `output.txt`, que de hecho es la salida original del proceso `sayHello` que fue publicada en el directorio `results`. +Si lo abre, encontrará el saludo `Hello World!` nuevamente. + +<details> + <summary>Contenido del archivo output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +Entonces, ¿qué hay de todos esos otros archivos? + +Estos son los archivos auxiliares y de log que Nextflow escribió como parte de la ejecución de la tarea: + +- **`.command.begin`**: Archivo centinela creado tan pronto como se lanza la tarea. +- **`.command.err`**: Mensajes de error (`stderr`) emitidos por la llamada al proceso +- **`.command.log`**: Salida de log completa emitida por la llamada al proceso +- **`.command.out`**: Salida regular (`stdout`) de la llamada al proceso +- **`.command.run`**: Script completo ejecutado por Nextflow para ejecutar la llamada al proceso +- **`.command.sh`**: El comando que fue realmente ejecutado por la llamada al proceso +- **`.exitcode`**: El código de salida resultante del comando + +El archivo `.command.sh` es especialmente útil porque muestra el comando principal que Nextflow ejecutó sin incluir toda la contabilidad y configuración de tarea/entorno. + +<details> + <summary>Contenido del archivo</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Consejo" + + Cuando algo sale mal y necesita solucionar problemas sobre qué sucedió, puede ser útil mirar el script `command.sh` para verificar exactamente qué comando compuso Nextflow basándose en las instrucciones del workflow, interpolación de variables y demás. + +### 1.4. Ejercicio opcional: volver a ejecutar con diferentes saludos + +Intente volver a ejecutar el workflow varias veces con diferentes valores para el argumento `--greeting`, luego observe tanto el contenido del directorio `results/` como los directorios de tarea. + +Observe cómo se preservan las salidas y logs de los directorios de tarea aislados, mientras que el contenido del directorio `results` es sobrescrito por la salida de ejecuciones posteriores. + +### Conclusión + +Usted sabe cómo ejecutar un script simple de Nextflow, monitorear su ejecución y encontrar sus salidas. + +### ¿Qué sigue? + +Aprenda a leer un script básico de Nextflow e identificar cómo sus componentes se relacionan con su funcionalidad. + +--- + +## 2. Examinar el script inicial del workflow Hello World + +Lo que hicimos allí fue básicamente tratar el script del workflow como una caja negra. +Ahora que hemos visto qué hace, abramos la caja y miremos dentro. + +_El objetivo aquí no es memorizar la sintaxis del código de Nextflow, sino formar algo de intuición básica sobre cuáles son los componentes principales y cómo están organizados._ + +### 2.1. Examinar la estructura general del código + +Abramos el script `hello-world.nf` en el panel del editor. + +<details> + <summary>Código</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usar echo para imprimir un saludo a un archivo + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // emitir un saludo + sayHello(params.greeting) +} +``` + +</details> + +Un script de Nextflow involucra dos tipos principales de componentes centrales: uno o más **processes**, y el **workflow** en sí. +Cada **process** describe qué operación(es) debe realizar el paso correspondiente en el pipeline, mientras que el **workflow** describe la lógica de flujo de datos que conecta los diversos pasos. + +Veamos más de cerca el bloque **process** primero, luego veremos el bloque **workflow**. + +### 2.2. La definición del `process` + +El primer bloque de código describe un **process**. +La definición del proceso comienza con la palabra clave `process`, seguida del nombre del proceso y finalmente el cuerpo del proceso delimitado por llaves. +El cuerpo del proceso debe contener un bloque script que especifica el comando a ejecutar, que puede ser cualquier cosa que pueda ejecutar en una terminal de línea de comandos. + +Aquí tenemos un **process** llamado `sayHello` que toma una variable de **input** llamada `greeting` y escribe su **output** en un archivo llamado `output.txt`. + +<details> + <summary>Código</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Usar echo para imprimir un saludo a un archivo + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +Esta es una definición de proceso muy mínima que solo contiene una definición de `input`, una definición de `output` y el `script` a ejecutar. + +La definición de `input` incluye el calificador `val`, que le dice a Nextflow que espere un valor de algún tipo (puede ser una cadena, un número, lo que sea). + +La definición de `output` incluye el calificador `path`, que le dice a Nextflow que esto debe manejarse como una ruta (incluye tanto rutas de directorio como archivos). + +!!! Tip "Consejo" + + La definición de salida no _determina_ qué salida se creará. + Simplemente _declara_ dónde encontrar el(los) archivo(s) de salida esperado(s), para que Nextflow pueda buscarlo una vez que la ejecución esté completa. + + Esto es necesario para verificar que el comando se ejecutó exitosamente y para pasar la salida a los procesos posteriores si es necesario. + La salida producida que no coincida con lo declarado en el bloque de salida no se pasará a los procesos posteriores. + +En un pipeline del mundo real, un proceso generalmente contiene información adicional como directivas de proceso, que presentaremos en un momento. + +### 2.3. La definición del `workflow` + +El segundo bloque de código describe el **workflow** en sí. +La definición del workflow comienza con la palabra clave `workflow`, seguida de un nombre opcional, luego el cuerpo del workflow delimitado por llaves. + +Aquí tenemos un **workflow** que consiste en una llamada al proceso `sayHello`, que toma una entrada, `params.greeting`, que contiene el valor que dimos al parámetro `--greeting`. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // emitir un saludo + sayHello(params.greeting) +} +``` + +Esta es una definición de **workflow** muy mínima. +En un pipeline del mundo real, el workflow típicamente contiene múltiples llamadas a **processes** conectados por **channels**, y puede haber valores predeterminados configurados para las entradas de variables. + +Veremos esto en acción cuando ejecutemos nf-core/molkart en la Parte 2 del curso. + +### 2.4. El sistema `params` de parámetros de línea de comandos + +El `params.greeting` que proporcionamos a la llamada del proceso `sayHello()` es un fragmento ingenioso de código de Nextflow y vale la pena dedicarle un minuto extra. + +Como se mencionó anteriormente, así es como pasamos el valor del parámetro de línea de comandos `--greeting` a la llamada del proceso `sayHello()`. +De hecho, simplemente declarar `params.someParameterName` nos permitirá dar al workflow un parámetro llamado `--someParameterName` desde la línea de comandos. + +!!! Tip "Consejo" + + Estos parámetros de workflow declarados usando el sistema `params` siempre toman dos guiones (`--`). + Esto los distingue de los parámetros a nivel de Nextflow, que solo toman un guion (`-`). + +### Conclusión + +Ahora sabe cómo está estructurado un workflow simple de Nextflow, y cómo los componentes básicos se relacionan con su funcionalidad. + +### ¿Qué sigue? + +Aprenda a gestionar sus ejecuciones de workflow convenientemente. + +--- + +## 3. Gestionar ejecuciones de workflow + +Saber cómo lanzar workflows y recuperar salidas es genial, pero rápidamente encontrará que hay algunos otros aspectos de la gestión de workflows que harán su vida más fácil. + +Aquí le mostramos cómo aprovechar la función `resume` para cuando necesite relanzar el mismo workflow, cómo inspeccionar los logs de ejecución con `nextflow log`, y cómo eliminar directorios de trabajo más antiguos con `nextflow clean`. + +### 3.1. Relanzar un workflow con `-resume` + +A veces, va a querer volver a ejecutar un pipeline que ya lanzó previamente sin rehacer ningún trabajo que ya se haya completado exitosamente. + +Nextflow tiene una opción llamada `-resume` que le permite hacer esto. +Específicamente, en este modo, cualquier proceso que ya se haya ejecutado con exactamente el mismo código, configuraciones y entradas será omitido. +Esto significa que Nextflow solo ejecutará los procesos que haya agregado o modificado desde la última ejecución, o a los que esté proporcionando nuevas configuraciones o entradas. + +Hay dos ventajas clave al hacer esto: + +- Si está en medio del desarrollo de un pipeline, puede iterar más rápidamente ya que solo tiene que ejecutar el(los) proceso(s) en los que está trabajando activamente para probar sus cambios. +- Si está ejecutando un pipeline en producción y algo sale mal, en muchos casos puede corregir el problema y relanzar el pipeline, y se reanudará ejecutándose desde el punto de falla, lo que puede ahorrarle mucho tiempo y cómputo. + +Para usarlo, simplemente agregue `-resume` a su comando y ejecútelo: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Busque el bit `cached:` que se ha agregado en la línea de estado del proceso (línea 5), lo que significa que Nextflow ha reconocido que ya ha hecho este trabajo y simplemente reutilizó el resultado de la ejecución exitosa anterior. + +También puede ver que el hash del subdirectorio de trabajo es el mismo que en la ejecución anterior. +Nextflow literalmente le está señalando la ejecución anterior y diciendo "Ya hice eso allí". + +!!! Tip "Consejo" + + Cuando vuelve a ejecutar un pipeline con `resume`, Nextflow no sobrescribe ningún archivo escrito en un directorio `publishDir` por ninguna llamada de proceso que se haya ejecutado previamente de manera exitosa. + +### 3.2. Inspeccionar el log de ejecuciones pasadas + +Cada vez que lanza un workflow de nextflow, se escribe una línea en un archivo de log llamado `history`, bajo un directorio oculto llamado `.nextflow` en el directorio de trabajo actual. + +Una forma más conveniente de acceder a esta información es usar el comando `nextflow log`. + +```bash +nextflow log +``` + +Esto mostrará el contenido del archivo de log en la terminal, mostrándole la marca de tiempo, nombre de ejecución, estado y línea de comandos completa para cada ejecución de Nextflow que se haya lanzado desde dentro del directorio de trabajo actual. + +### 3.3. Eliminar directorios de trabajo más antiguos + +Durante el proceso de desarrollo, típicamente ejecutará sus pipelines en borrador un gran número de veces, lo que puede llevar a una acumulación de muchos archivos en muchos subdirectorios. +Dado que los subdirectorios se nombran aleatoriamente, es difícil distinguir por sus nombres cuáles son ejecuciones más antiguas vs. más recientes. + +Nextflow incluye un conveniente subcomando `clean` que puede eliminar automáticamente los subdirectorios de trabajo de ejecuciones pasadas que ya no le interesan, con varias [opciones](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para controlar qué se eliminará. + +Puede usar el log de Nextflow para buscar una ejecución basándose en su marca de tiempo y/o línea de comandos, luego usar `nextflow clean -before <run_name> -f` para eliminar directorios de trabajo de ejecuciones anteriores. + +!!! Warning "Advertencia" + + Eliminar subdirectorios de trabajo de ejecuciones pasadas los elimina del caché de Nextflow y elimina cualquier salida que se haya almacenado en esos directorios. + Esto significa que rompe la capacidad de Nextflow de reanudar la ejecución sin volver a ejecutar los procesos correspondientes. + + ¡Usted es responsable de guardar cualquier salida que le importe o en la que planee confiar! Si está usando la directiva `publishDir` para ese propósito, asegúrese de usar el modo `copy`, no el modo `symlink`. + +### Conclusión + +Usted sabe cómo relanzar un pipeline sin repetir pasos que ya se ejecutaron de manera idéntica, inspeccionar el log de ejecución, y usar el comando `nextflow clean` para limpiar directorios de trabajo antiguos. + +### ¿Qué sigue? + +Ahora que entiende las operaciones básicas de Nextflow, está listo para ejecutar un pipeline real de bioimagen con nf-core/molkart. diff --git a/docs/es/docs/nf4_science/imaging/02_run_molkart.md b/docs/es/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..2e71282750 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Parte 2: Ejecutar nf-core/molkart + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la Parte 1, ejecutamos un flujo de trabajo simple de Hello World para comprender los conceptos básicos de la ejecución de Nextflow. +Ahora vamos a ejecutar un pipeline de bioimagen del mundo real: **nf-core/molkart**. + +Este pipeline procesa datos de transcriptómica espacial de Molecular Cartography de Resolve Bioscience. +Sin embargo, los patrones de Nextflow que aprenderá aquí se aplican a cualquier pipeline de nf-core o flujo de trabajo de producción. + +## 1. Comprender los pipelines de nf-core + +Antes de ejecutar el pipeline, entendamos qué es nf-core y por qué es importante para ejecutar flujos de trabajo. + +### 1.1. ¿Qué es nf-core? + +[nf-core](https://nf-co.re/) es una colección impulsada por la comunidad de pipelines de Nextflow de alta calidad. +Todos los pipelines de nf-core siguen la misma estructura y convenciones, lo que significa que una vez que aprende a ejecutar uno, puede ejecutar cualquiera de ellos. + +Características clave de los pipelines de nf-core: + +- **Estructura estandarizada**: Todos los pipelines tienen nombres de parámetros y patrones de uso consistentes +- **Datos de prueba integrados**: Cada pipeline incluye perfiles de prueba para validación rápida +- **Documentación completa**: Instrucciones de uso detalladas y descripciones de parámetros +- **Control de calidad**: Informes de QC automatizados usando MultiQC +- **Soporte de contenedores**: Contenedores pre-construidos para reproducibilidad + +!!! tip "¿Quiere aprender más sobre nf-core?" + + Para una introducción detallada al desarrollo de pipelines de nf-core, consulte el curso de entrenamiento [Hello nf-core](../../hello_nf-core/index.md). + Cubre cómo crear y personalizar pipelines de nf-core desde cero. + +### 1.2. El pipeline molkart + +![Pipeline nf-core/molkart](img/molkart.png) + +El pipeline [nf-core/molkart](https://nf-co.re/molkart) procesa datos de imágenes de transcriptómica espacial a través de varias etapas: + +1. **Preprocesamiento de imágenes**: Relleno de patrón de cuadrícula y mejora de contraste opcional +2. **Segmentación celular**: Múltiples opciones de algoritmos (Cellpose, Mesmer, ilastik, Stardist) +3. **Asignación de puntos**: Asignar puntos de transcripción a células segmentadas +4. **Control de calidad**: Generar informes de QC completos + +Las salidas clave son: + +- Tablas de conteo de células por transcripción +- Máscaras de segmentación +- Informe de control de calidad MultiQC + +--- + +## 2. Ejecutar molkart con datos de prueba + +Antes de comenzar, clonemos el repositorio de molkart localmente para que podamos inspeccionar su código: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Esto crea un directorio `molkart/` que contiene el código fuente completo del pipeline. + +!!! note "¿Por qué estamos clonando localmente?" + + Típicamente, ejecutaría pipelines de nf-core directamente desde GitHub usando `nextflow run nf-core/molkart -r 1.2.0`. + Nextflow descarga automáticamente la versión del pipeline solicitada para usted en `$HOME/.nextflow/assets/nf-core/molkart` y lo ejecuta desde allí. + Sin embargo, para este entrenamiento, estamos clonando el pipeline a un directorio local diferente para que podamos inspeccionar el código más fácilmente. + +### 2.1. Comprender los requisitos de contenedores + +Antes de ejecutar el pipeline completo, aprendamos por qué los contenedores son esenciales para los pipelines de nf-core. + +Intentemos ejecutar el pipeline usando el conjunto de datos de prueba y los parámetros de la configuración de prueba de molkart: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Desglosemos estos parámetros: + +- `--input`: Ruta a la hoja de muestras que contiene metadatos de muestras +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Parámetros para el relleno de patrón de cuadrícula +- `--clahe_pyramid_tile`: Tamaño del kernel para mejora de contraste +- `--segmentation_method`: Qué algoritmo(s) usar para la segmentación celular +- `--outdir`: Dónde guardar los resultados + +!!! Warning "¡Este comando fallará - eso es intencional!" + + Estamos ejecutando esto deliberadamente sin contenedores para demostrar por qué son necesarios. + +Después de unos momentos, verá un error como este: + +??? failure "Salida del comando" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**¿Qué está sucediendo aquí?** + +El error `command not found` (estado de salida 127) significa que Nextflow intentó ejecutar `duplicate_finder.py` pero no pudo encontrarlo en su sistema. +Esto se debe a que: + +1. El pipeline espera que el software de bioinformática especializado esté instalado +2. Estas herramientas (como `duplicate_finder.py`, `apply_clahe.dask.py`, etc.) no son parte de las distribuciones estándar de Linux +3. Sin contenedores, Nextflow intenta ejecutar comandos directamente en su máquina local + +**¿De dónde se supone que vienen estas herramientas?** + +Inspeccionemos uno de los módulos de proceso para ver cómo declara sus requisitos de software. + +Abra el módulo de preprocesamiento CLAHE: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Mire la línea 5 - verá: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Esta línea le dice a Nextflow: "Para ejecutar este proceso, use la imagen de Docker `ghcr.io/schapirolabor/molkart-local:v0.0.4`, que contiene todo el software requerido." + +Cada proceso declara qué imagen de contenedor proporciona sus herramientas requeridas. +¡Sin embargo, Nextflow solo usa estos contenedores si usted se lo indica! + +**La solución: Habilitar Docker en la configuración** + +### 2.2. Configurar Docker e iniciar el pipeline + +Para habilitar Docker, necesitamos cambiar `docker.enabled` de `false` a `true` en el archivo `nextflow.config`. + +Abra el archivo de configuración: + +```bash +code nextflow.config +``` + +Cambie `docker.enabled = false` a `docker.enabled = true`: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Ahora ejecute el pipeline nuevamente con el mismo comando: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Esta vez, Nextflow: + +1. Leerá la configuración `docker.enabled = true` del config +2. Descargará las imágenes de Docker requeridas (solo la primera vez) +3. Ejecutará cada proceso dentro de su contenedor especificado +4. Se ejecutará exitosamente porque todas las herramientas están disponibles dentro de los contenedores + +!!! Tip "Por qué importan los contenedores" + + La mayoría de los pipelines de nf-core **requieren** contenedorización (Docker, Singularity, Podman, etc.) porque: + + - Utilizan software de bioinformática especializado no disponible en entornos estándar + - Los contenedores aseguran reproducibilidad - las mismas versiones exactas de software se ejecutan en todas partes + - No necesita instalar manualmente docenas de herramientas y sus dependencias + + Para más detalles sobre contenedores en Nextflow, consulte [Hello Containers](../../hello_nextflow/05_hello_containers.md) del entrenamiento Hello Nextflow. + +### 2.3. Monitorear la ejecución + +Mientras se ejecuta el pipeline, verá una salida similar a esta: + +??? success "Salida del comando" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Note cómo esta salida es más detallada que nuestro ejemplo de Hello World debido a las convenciones de nf-core que sigue el pipeline: + +- El pipeline muestra su versión y logo +- Se muestran los parámetros de configuración +- Múltiples procesos se ejecutan en paralelo (indicado por múltiples líneas de proceso) +- Los nombres de proceso incluyen la ruta completa del módulo (por ejemplo, `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Comprender la ejecución de procesos + +La línea del executor `executor > local (22)` le dice: + +- **executor**: Qué entorno de cómputo se está usando (`local` = su máquina) +- **(22)**: Número total de tareas lanzadas + +Cada línea de proceso muestra: + +- **Hash** (`[1a/2b3c4d]`): Identificador del directorio de trabajo (como antes) +- **Nombre del proceso**: Ruta completa del módulo y nombre del proceso +- **Identificador de entrada**: Nombre de muestra entre paréntesis +- **Progreso**: Porcentaje completo y conteo (por ejemplo, `1 of 1 ✔`) + +### Conclusión + +Sabe cómo lanzar un pipeline de nf-core con datos de prueba e interpretar su salida de ejecución. + +### ¿Qué sigue? + +Aprenda dónde encontrar los resultados y cómo interpretarlos. + +--- + +## 3. Encontrar y examinar las salidas + +Cuando el pipeline se complete exitosamente, verá un mensaje de finalización y un resumen de ejecución. + +### 3.1. Localizar el directorio de resultados + +Por defecto, los pipelines de nf-core escriben las salidas en un directorio especificado por el parámetro `outdir`, que establecimos en `results/`. + +Liste el contenido: + +```bash +tree results/ +``` + +Debería ver varios subdirectorios: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Cada subdirectorio contiene salidas de una etapa específica del pipeline: + +- **mindagap/**: Imágenes con cuadrícula rellenada del paso de preprocesamiento MindaGap +- **clahe/**: Imágenes con contraste mejorado del preprocesamiento CLAHE +- **stack/**: Pilas de imágenes multicanal creadas para segmentación +- **segmentation/**: Resultados de segmentación de diferentes algoritmos (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Tablas de conteo de células por transcripción +- **anndata/**: Objetos AnnData que contienen matrices de células por transcripción y coordenadas espaciales +- **molkartqc/**: Métricas de control de calidad para asignación de puntos +- **multiqc/**: Informe de control de calidad completo +- **pipeline_info/**: Informes de ejecución y logs + +### 3.2. Examinar el informe MultiQC + +El informe MultiQC es un archivo HTML completo que agrega métricas de calidad de todos los pasos del pipeline. + +Abra el informe en el explorador de archivos y luego haga clic en el botón "Show Preview" para verlo renderizado directamente en VS Code. + +El informe incluye: + +- Estadísticas generales para todas las muestras +- Métricas de preprocesamiento +- Métricas de calidad de segmentación +- Número de células y puntos detectados + +!!! Tip + + Los informes MultiQC se incluyen típicamente en todos los pipelines de nf-core. + Siempre proporcionan una visión general de alto nivel de la ejecución del pipeline y la calidad de los datos. + +### 3.3. Examinar las tablas de células por transcripción + +La salida científica más importante es la tabla de conteo de células por transcripción. +Esto le dice cuántos de cada transcripción se detectaron en cada célula. + +Navegue al directorio spot2cell: + +```bash +ls results/spot2cell/ +``` + +Encontrará archivos como: + +- `cellxgene_mem_only_cellpose.csv`: Tabla de células por transcripción usando segmentación Cellpose +- `cellxgene_mem_only_mesmer.csv`: Tabla de células por transcripción usando segmentación Mesmer +- `cellxgene_mem_only_stardist.csv`: Tabla de células por transcripción usando segmentación Stardist + +Solo ejecutamos 1 muestra en este conjunto de datos de prueba, pero en un experimento real tendríamos estas tablas para cada muestra. +Note cómo Nextflow puede procesar múltiples métodos de segmentación en paralelo, haciendo fácil comparar resultados. + +### 3.4. Ver informes de ejecución + +Nextflow genera varios informes de ejecución automáticamente. + +Verifique el directorio pipeline_info: + +```bash +ls results/pipeline_info/ +``` + +Archivos clave: + +- **execution_report.html**: Visualización de línea de tiempo y uso de recursos +- **execution_timeline.html**: Gráfico de Gantt de ejecución de procesos +- **execution_trace.txt**: Métricas detalladas de ejecución de tareas +- **pipeline_dag.html**: Grafo acíclico dirigido que muestra la estructura del flujo de trabajo + +Abra el informe de ejecución para ver el uso de recursos: + +```bash +code results/pipeline_info/execution_report.html +``` + +Esto muestra: + +- Cuánto tiempo tomó cada proceso +- Uso de CPU y memoria +- Qué tareas fueron cacheadas vs. ejecutadas + +!!! Tip + + Estos informes son increíblemente útiles para optimizar la asignación de recursos y solucionar problemas de rendimiento. + +### Conclusión + +Sabe cómo localizar las salidas del pipeline, examinar informes de control de calidad y acceder a métricas de ejecución. + +### ¿Qué sigue? + +Aprenda sobre el directorio de trabajo y cómo Nextflow gestiona los archivos intermedios. + +--- + +## 4. Explorar el directorio de trabajo + +Al igual que con nuestro ejemplo de Hello World, todo el trabajo real ocurre en el directorio `work/`. + +### 4.1. Comprender la estructura del directorio de trabajo + +El directorio de trabajo contiene un subdirectorio para cada tarea que fue ejecutada. +Para este pipeline con 12 tareas, habrá 12 subdirectorios de trabajo. + +Liste el directorio de trabajo: + +```bash +ls -d work/*/*/ | head -5 +``` + +Esto muestra los primeros 5 directorios de tareas. + +### 4.2. Inspeccionar un directorio de tareas + +Elija uno de los hashes de proceso de segmentación de la salida de consola (por ejemplo, `[3m/4n5o6p]`) y mire dentro: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Verá: + +- **Archivos .command.\***: Scripts de ejecución de Nextflow y logs (como antes) +- **Archivos de entrada preparados**: Enlaces simbólicos a los archivos de entrada reales +- **Archivos de salida**: Máscaras de segmentación, resultados intermedios, etc. + +La diferencia clave con Hello World: + +- Los pipelines reales preparan archivos de entrada grandes (imágenes, datos de referencia) +- Los archivos de salida pueden ser bastante grandes (máscaras de segmentación, imágenes procesadas) +- Múltiples archivos de entrada y salida por tarea + +!!! Tip + + Si un proceso falla, puede navegar a su directorio de trabajo, examinar `.command.err` para mensajes de error e incluso re-ejecutar `.command.sh` manualmente para depurar el problema. + +### 4.3. Limpieza del directorio de trabajo + +El directorio de trabajo puede volverse bastante grande con múltiples ejecuciones de pipeline. +Como aprendimos en la Parte 1, puede usar `nextflow clean` para eliminar directorios de trabajo de ejecuciones antiguas. + +Sin embargo, para pipelines de nf-core con archivos intermedios grandes, es especialmente importante limpiar regularmente. + +### Conclusión + +Comprende cómo los pipelines de nf-core organizan sus directorios de trabajo y cómo inspeccionar tareas individuales para depuración. + +### ¿Qué sigue? + +Aprenda sobre el caché de Nextflow y cómo reanudar ejecuciones de pipeline fallidas. + +--- + +## 5. Reanudar una ejecución de pipeline + +Una de las características más poderosas de Nextflow es la capacidad de reanudar un pipeline desde el punto de falla. + +### 5.1. El mecanismo de caché + +Cuando ejecuta un pipeline con `-resume`, Nextflow: + +1. Verifica el caché para cada tarea +2. Si las entradas, código y parámetros son idénticos, reutiliza el resultado cacheado +3. Solo re-ejecuta tareas que cambiaron o fallaron + +Esto es esencial para pipelines de larga ejecución donde las fallas pueden ocurrir tarde en la ejecución. + +### 5.2. Probar resume con molkart + +Ejecute el mismo comando nuevamente, pero agregue `-resume`: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Debería ver una salida como: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Note `cached: 2` o `cached: 1` para cada proceso - ¡nada fue re-ejecutado! + +### 5.3. Cuándo resume es útil + +Resume es particularmente valioso cuando: + +- Un pipeline falla debido a límites de recursos (memoria insuficiente, límite de tiempo excedido) +- Necesita modificar procesos posteriores sin re-ejecutar pasos anteriores +- Su conexión de red se interrumpe durante la descarga de datos +- Desea agregar salidas adicionales sin rehacer el cómputo + +!!! Warning + + Resume solo funciona si no ha cambiado los datos de entrada, el código del pipeline o los parámetros. + Si cambia cualquiera de estos, Nextflow correctamente re-ejecutará las tareas afectadas. + +### Conclusión + +Sabe cómo usar `-resume` para re-ejecutar pipelines eficientemente sin repetir tareas exitosas. + +### ¿Qué sigue? + +Ahora que puede ejecutar nf-core/molkart con datos de prueba, está listo para aprender cómo configurarlo para sus propios conjuntos de datos. diff --git a/docs/es/docs/nf4_science/imaging/03_inputs.md b/docs/es/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..d378af9bd7 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Parte 3: Organización de entradas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En la Parte 2, ejecutamos molkart con múltiples parámetros en la línea de comandos. +Ahora aprenderemos dos enfoques mejores para gestionar entradas: **archivos de parámetros** y **hojas de muestras**. + +## 1. Uso de archivos de parámetros + +### 1.1. El problema con líneas de comandos largas + +Recordemos nuestro comando de la Parte 2: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Esto funciona, pero es difícil de reproducir, compartir o modificar. +¿Qué pasa si necesita ejecutar el mismo análisis nuevamente el próximo mes? +¿Qué pasa si un colaborador quiere usar exactamente su configuración? + +### 1.2. Solución: Use un archivo de parámetros + +Cree un archivo llamado `params.yaml`: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Ahora su comando se convierte en: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +¡Eso es todo! El archivo de parámetros documenta su configuración exacta y facilita la reejecución o el compartir. + +### 1.3. Anulación de parámetros + +Todavía puede anular parámetros específicos desde la línea de comandos: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +La línea anterior cambia el `segmentation_method` a `stardist` y el nombre de `--outdir` a `stardist_results` en lugar de los parámetros en el archivo `params.yaml`. +Además, puede ver que la bandera `-resume` nos permitió reutilizar los resultados de preprocesamiento de la ejecución anterior, ahorrando tiempo. +Puede usar este patrón para probar rápidamente diferentes variaciones del pipeline. + +### Conclusión + +Los archivos de parámetros hacen que sus análisis sean reproducibles y fáciles de compartir. +Úselos para cualquier trabajo de análisis real. + +### ¿Qué sigue? + +Aprenda cómo las hojas de muestras organizan información sobre múltiples muestras. + +--- + +## 2. El patrón de hoja de muestras + +### 2.1. ¿Qué es una hoja de muestras? + +Una hoja de muestras es un archivo CSV que describe sus muestras de entrada. +Cada fila es una muestra, y las columnas especifican los archivos y metadatos para esa muestra. + +Veamos la hoja de muestras que hemos estado usando: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Las columnas son: + +- `sample`: Identificador único de la muestra +- `nuclear_image`: Imagen de tinción nuclear (TIFF) +- `spot_table`: Puntos de transcripción (TXT) +- `membrane_image`: Imagen de tinción de membrana (TIFF, opcional) + +### 2.2. Rutas de archivos + +Las hojas de muestras aceptan múltiples tipos de rutas: + +- **URLs**: Nextflow descarga automáticamente (como se muestra arriba) +- **Rutas locales**: `data/nuclear.tiff` o `/absolute/path/to/nuclear.tiff` +- **Almacenamiento en la nube**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Puede mezclar tipos de rutas en la misma hoja de muestras. + +### 2.3. Creación de su propia hoja de muestras + +Primero, descarguemos los archivos de datos de prueba localmente: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Ahora modifiquemos la hoja de muestras para hacer referencia a estos archivos locales: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Advertencia" + + Observe que las rutas en la hoja de muestras son relativas a donde **ejecuta** Nextflow, no a donde se encuentra la hoja de muestras. + +Finalmente, ejecutemos nf-core/molkart una vez más con la hoja de muestras con rutas de archivos locales: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Como puede ver, Nextflow ejecuta esta ejecución de manera similar a cuando los archivos se descargaron desde Github. Esta es una de las grandes características de Nextflow, organiza los datos adecuadamente para usted, independientemente de dónde se encuentren. + +### Conclusión + +Las hojas de muestras organizan conjuntos de datos con múltiples muestras de una manera que le permite definir explícitamente sus metadatos junto con las rutas de archivos. +La mayoría de los pipelines de nf-core usan este patrón. + +### ¿Qué sigue? + +Ahora que hemos cubierto las entradas, exploremos cómo configurar pipelines de Nextflow para diferentes entornos de cómputo. diff --git a/docs/es/docs/nf4_science/imaging/04_config.md b/docs/es/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..1147e8bca0 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Parte 4: Configuración + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En las Partes 1-3, aprendimos cómo ejecutar Nextflow, ejecutar un pipeline de nf-core y gestionar entradas con archivos de parámetros y samplesheets. +Ahora exploraremos cómo configurar pipelines para diferentes entornos computacionales usando **archivos de configuración** y **perfiles**. + +## Objetivos de aprendizaje + +Al finalizar esta parte, podrás: + +- Comprender cómo Nextflow resuelve la configuración desde múltiples fuentes +- Usar perfiles integrados de nf-core para contenedores y pruebas +- Crear perfiles personalizados para diferentes entornos computacionales +- Personalizar solicitudes de recursos usando etiquetas de proceso +- Gestionar límites de recursos en entornos restringidos +- Inspeccionar la configuración resuelta con `nextflow config` + +--- + +## 1. Comprender la configuración de Nextflow + +### 1.1. ¿Qué es un archivo de configuración? + +Nextflow usa archivos de configuración para separar la **lógica del workflow** (qué hacer) de las **configuraciones de ejecución** (cómo y dónde hacerlo). + +Los archivos de configuración controlan: + +- Motores de contenedores (Docker, Singularity, Conda) +- Recursos computacionales (CPUs, memoria, tiempo) +- Plataformas de ejecución (local, HPC, nube) +- Parámetros del pipeline + +### 1.2. Precedencia de la configuración + +Nextflow carga la configuración desde múltiples fuentes, donde las fuentes posteriores sobrescriben a las anteriores: + +1. **Configuración del pipeline**: `nextflow.config` en el repositorio del pipeline +2. **Configuración del directorio**: `nextflow.config` en tu directorio de trabajo actual +3. **Configuración de usuario**: `~/.nextflow/config` +4. **Línea de comandos**: Parámetros y opciones pasados directamente + +Este enfoque en capas te permite mantener valores predeterminados en el pipeline, sobrescribir con configuraciones específicas del usuario y hacer ajustes rápidos en la línea de comandos. + +### 1.3. Nuestra configuración actual + +Veamos la configuración que hemos estado usando: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Comentemos o cambiemos la línea `docker.enabled = true` de la Parte 2, y descubramos cómo podemos lograr el mismo resultado usando un perfil en molkart. + +--- + +## 2. Usar perfiles + +### 2.1. ¿Qué son los perfiles? + +Los perfiles son conjuntos nombrados de configuración que pueden activarse con la bandera `-profile` mediante el comando `nextflow run`. +Facilitan el cambio entre diferentes escenarios computacionales sin editar archivos de configuración. + +Todos los pipelines de nf-core vienen con varios perfiles predeterminados que podemos usar. + +### 2.2. Inspeccionar perfiles integrados + +Inspeccionémoslos en el archivo `molkart/nextflow.config` asociado con el código base del pipeline: + +```bash +code molkart/nextflow.config +``` + +Busca el bloque `profiles`: + +```groovy title="molkart/nextflow.config (extracto)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Perfiles de contenedores comunes: + +- `docker`: Usar contenedores Docker (más común para desarrollo local) +- `singularity`: Usar Singularity/Apptainer (común en HPC) +- `conda`: Usar entornos Conda +- `apptainer`: Usar contenedores Apptainer + +### 2.3. Re-ejecutar con perfiles en lugar de nextflow.config + +Ahora que hemos deshabilitado la configuración de docker en nuestro archivo `nextflow.config` local y entendemos los perfiles, volvamos a ejecutar el pipeline usando la bandera `-profile`. + +Anteriormente en la Parte 3, creamos un archivo `params.yaml` con nuestros parámetros personalizados. +Ahora podemos combinarlo con el perfil Docker integrado: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Desglosemos qué hace cada bandera: + +- `-profile docker`: Activa el perfil Docker del `nextflow.config` de molkart, que establece `docker.enabled = true` +- `-params-file params.yaml`: Carga todos los parámetros del pipeline desde nuestro archivo YAML +- `-resume`: Reutiliza resultados almacenados en caché de ejecuciones anteriores + +Como estamos usando `-resume`, Nextflow verificará si algo cambió desde la última ejecución. +Si los parámetros, entradas y código son los mismos, todas las tareas se recuperarán de la caché y el pipeline se completará casi instantáneamente. + +```console title="Salida (extracto)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +¡Observa que todos los procesos muestran `cached: 2` o `cached: 1` - nada fue re-ejecutado! + +### 2.4. Perfiles de prueba + +Los perfiles de prueba proporcionan formas rápidas de especificar parámetros de entrada predeterminados y archivos de datos para verificar que el pipeline funcione. +Los pipelines de nf-core siempre incluirán al menos dos perfiles de prueba: + +- `test`: Conjunto de datos pequeño con parámetros rápidos para pruebas rápidas +- `test_full`: Prueba más completa con datos más grandes + +Veamos más de cerca el perfil `test` en molkart que se incluye usando la directiva `includeConfig`: + +```groovy title="molkart/nextflow.config (extracto)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Esto significa que cada vez que ejecutemos el pipeline con `-profile test`, Nextflow cargará la configuración desde `conf/test.config`. + +```groovy title="molkart/conf/test.config (extracto)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Observa que este perfil contiene los mismos parámetros que usamos en nuestro archivo `params.yaml` anteriormente. + +Puedes activar múltiples perfiles separándolos con comas. +Usemos eso para probar nuestro pipeline sin necesitar nuestro archivo de parámetros: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Esto combina: + +- `docker`: Habilitar contenedores Docker +- `test`: Usar conjunto de datos y parámetros de prueba + +Los perfiles se aplican de izquierda a derecha, por lo que los perfiles posteriores sobrescriben a los anteriores si establecen los mismos valores. + +### Conclusión + +Los pipelines de nf-core vienen con perfiles integrados para contenedores, pruebas y entornos especiales. +Puedes combinar múltiples perfiles para construir la configuración que necesitas. + +### ¿Qué sigue? + +Aprende cómo crear tus propios perfiles personalizados para diferentes entornos computacionales. + +--- + +## 3. Crear perfiles personalizados + +### 3.1. Crear perfiles para cambiar entre desarrollo local y ejecución en HPC + +Creemos perfiles personalizados para dos escenarios: + +1. Desarrollo local con Docker +2. HPC universitario con planificador Slurm y Singularity + +Agrega lo siguiente a tu `nextflow.config`: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Ahora puedes cambiar entre entornos fácilmente: + +```bash +# Para desarrollo local +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Para HPC (cuando esté disponible) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "Nota" + + No podemos probar el perfil HPC en este entorno de entrenamiento ya que no tenemos acceso a un planificador Slurm. + Pero esto muestra cómo lo configurarías para uso en el mundo real. + +### 3.2. Usar `nextflow config` para inspeccionar la configuración + +El comando `nextflow config` muestra la configuración completamente resuelta sin ejecutar el pipeline. + +Ver la configuración predeterminada: + +```bash +nextflow config ./molkart +``` + +Ver la configuración con un perfil específico: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Esto es extremadamente útil para: + +- Depurar problemas de configuración +- Comprender qué valores se usarán realmente +- Verificar cómo interactúan múltiples perfiles + +### Conclusión + +Los perfiles personalizados te permiten cambiar entre diferentes entornos computacionales con una sola bandera de línea de comandos. +Usa `nextflow config` para inspeccionar la configuración resuelta antes de ejecutar. + +### ¿Qué sigue? + +Aprende cómo personalizar solicitudes de recursos para procesos individuales usando el sistema de etiquetas de proceso de nf-core. + +--- + +## 4. Personalizar solicitudes de recursos + +### 4.1. Comprender las etiquetas de proceso en pipelines de nf-core + +Para simplificar, los pipelines de nf-core usan [**etiquetas de proceso**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) para estandarizar la asignación de recursos en todos los pipelines. +Cada proceso está etiquetado con una etiqueta como `process_low`, `process_medium` o `process_high` para describir requisitos de recursos computacionales bajos, medios o altos, respectivamente. +Estas etiquetas se convierten en solicitudes de recursos específicas en uno de los archivos de configuración ubicados en el directorio `conf/` del pipeline. + +```groovy title="molkart/conf/base.config (extracto)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Observa el multiplicador `task.attempt` - esto permite que los reintentos subsiguientes de tareas soliciten más recursos, si el pipeline está configurado con `process.maxRetries > 1`. + +### 4.2. Sobrescribir recursos para procesos específicos + +Para control detallado, dirige procesos individuales por nombre: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Si intentamos ejecutar este pipeline con la sobrescritura anterior, el proceso `CELLPOSE` solicitará 16 CPUs y 32 GB de memoria en lugar del valor predeterminado definido por su etiqueta. +Esto causará que el pipeline falle en nuestro entorno actual ya que no tenemos tanta RAM disponible. +Aprenderemos cómo prevenir estos tipos de fallos en la siguiente sección. + +!!! tip "Consejo" + + Para encontrar nombres de procesos, revisa la salida de ejecución del pipeline o verifica `.nextflow.log`. + Los nombres de procesos siguen el patrón `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### Conclusión + +Los pipelines de nf-core usan etiquetas de proceso para estandarizar la asignación de recursos. +Puedes sobrescribir recursos por etiqueta (afecta múltiples procesos) o por nombre (afecta un proceso específico). + +### ¿Qué sigue? + +Aprende cómo gestionar límites de recursos en entornos restringidos como GitHub Codespaces. + +--- + +## 5. Gestionar recursos en entornos restringidos + +### 5.1. El problema de los límites de recursos + +Si intentáramos ejecutar molkart con un proceso solicitando 16 CPUs y 32 GB de memoria (como se mostró en la sección 4.2), fallaría en nuestro entorno actual porque no tenemos tantos recursos disponibles. +En un entorno de clúster con nodos más grandes, tales solicitudes se enviarían al planificador. + +En entornos restringidos como GitHub Codespaces, sin límites, Nextflow se negaría a ejecutar procesos que excedan los recursos disponibles. + +### 5.2. Establecer límites de recursos + +La directiva `resourceLimits` limita las solicitudes de recursos a valores especificados: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Esto le dice a Nextflow: "Si algún proceso solicita más de 2 CPUs o 7 GB de memoria, limítalo a estos valores en su lugar." + +### 5.3. Agregar límites de recursos a perfiles personalizados + +Actualiza tus perfiles personalizados para incluir límites apropiados: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "Advertencia" + + Establecer límites de recursos demasiado bajos puede causar que los procesos fallen o se ejecuten lentamente. + El pipeline puede necesitar usar algoritmos menos intensivos en memoria o procesar datos en fragmentos más pequeños. + +### Conclusión + +Usa `resourceLimits` para ejecutar pipelines en entornos con recursos restringidos limitando las solicitudes de recursos de procesos. +Diferentes perfiles pueden tener diferentes límites apropiados para su entorno. + +### ¿Qué sigue? + +¡Has completado el entrenamiento principal de Nextflow para Bioimagen! + +--- + +## Conclusión + +Ahora comprendes cómo configurar pipelines de Nextflow para diferentes entornos computacionales. + +Habilidades clave que has aprendido: + +- **Precedencia de configuración**: Cómo Nextflow resuelve configuraciones desde múltiples fuentes +- **Perfiles de nf-core**: Usar perfiles integrados para contenedores, pruebas y utilidades +- **Perfiles personalizados**: Crear tus propios perfiles para diferentes entornos +- **Etiquetas de proceso**: Comprender y sobrescribir solicitudes de recursos por etiqueta +- **Límites de recursos**: Gestionar entornos restringidos con `resourceLimits` +- **Inspección de configuración**: Usar `nextflow config` para depurar y verificar configuraciones + +Estas habilidades de configuración son transferibles a cualquier pipeline de Nextflow y te ayudarán a ejecutar workflows eficientemente en máquinas locales, clústeres HPC y plataformas en la nube. + +### ¿Qué sigue? + +¡Felicidades por completar el curso de Nextflow para Bioimagen! + +Próximos pasos: + +- Completa la encuesta del curso para proporcionar retroalimentación +- Revisa [Hello Nextflow](../hello_nextflow/index.md) para aprender más sobre el desarrollo de workflows +- Explora [Hello nf-core](../hello_nf-core/index.md) para profundizar en las herramientas de nf-core +- Navega otros cursos en las [colecciones de entrenamiento](../training_collections/index.md) diff --git a/docs/es/docs/nf4_science/imaging/index.md b/docs/es/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..8d2e484291 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/index.md @@ -0,0 +1,32 @@ +# Nextflow run for Imaging + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de entrenamiento está dirigido a investigadores en imagenología y biología espacial que estén interesados en ejecutar y personalizar pipelines de análisis de datos. +Enseña conceptos fundamentales de Nextflow relacionados con la ejecución, organización y configuración de workflows utilizando [nf-core/molkart](https://nf-co.re/molkart), un pipeline para procesar datos de transcriptómica espacial de Cartografía Molecular. +Las habilidades que aprenderá aquí son transferibles a cualquier pipeline de Nextflow o nf-core. + +¡Comencemos! Haga clic en el botón "Open in GitHub Codespaces" a continuación para iniciar el entorno de entrenamiento (preferiblemente en una pestaña separada), luego continúe leyendo mientras se carga. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizaje + +Al trabajar en este curso, aprenderá a aplicar conceptos y herramientas fundamentales de Nextflow para ejecutar pipelines de análisis de imágenes. + +Al final de este taller será capaz de: + +- Lanzar un workflow de Nextflow localmente y monitorear la ejecución +- Encontrar e interpretar salidas (resultados) y archivos de registro generados por Nextflow +- Ejecutar un pipeline de nf-core con datos de prueba y entradas personalizadas +- Configurar la ejecución del pipeline usando perfiles y archivos de parámetros +- Gestionar entradas utilizando hojas de muestras y parámetros de línea de comandos + +## Audiencia y requisitos previos + +Este curso asume cierta familiaridad mínima con lo siguiente: + +- Experiencia con la línea de comandos +- Familiaridad básica con formatos de archivos de imágenes (imágenes TIFF, datos tabulares) + +Para requisitos técnicos y configuración del entorno, consulte el mini-curso de [Configuración del Entorno](../../envsetup/). diff --git a/docs/es/docs/nf4_science/imaging/next_steps.md b/docs/es/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..c0db482eaa --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Próximos pasos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicitaciones por completar el entrenamiento de Nextflow para Bioimagen! + +Ahora tiene las habilidades fundamentales para ejecutar y configurar pipelines de Nextflow para el análisis de datos de imagen. + +## Continuar aprendiendo + +Aquí hay algunos pasos recomendados para profundizar su conocimiento de Nextflow: + +### Explorar más pipelines de nf-core + +- **Explorar todos los pipelines**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Desarrollar sus propios pipelines + +Si desea aprender cómo escribir pipelines de Nextflow: + +- **[Hello Nextflow](../../hello_nextflow/)**: Entrenamiento completo de desarrollo en Nextflow +- **[Side Quests](../../side_quests/)**: Temas avanzados para desarrolladores de pipelines + +### Unirse a la comunidad + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Obtenga ayuda y conéctese con otros usuarios +- **[nf-core Slack](https://nf-co.re/join)**: Únase a la comunidad de nf-core +- **[Seqera Community Forum](https://community.seqera.io)**: Haga preguntas y comparta experiencias + +### Recursos adicionales + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Documentación de referencia completa +- **[nf-core Documentation](https://nf-co.re/docs)**: Directrices y mejores prácticas + +## Involucrarse + +- **Contribuir a nf-core**: Ayude a mejorar pipelines o documentación +- **Compartir sus workflows**: Contribuya sus propios pipelines a la comunidad +- **Asistir a eventos**: Únase al Nextflow Summit y sesiones de entrenamiento de la comunidad + +¡Gracias por aprender con nosotros! diff --git a/docs/es/docs/nf4_science/imaging/survey.md b/docs/es/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..4da7563718 --- /dev/null +++ b/docs/es/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Encuesta + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Gracias por completar el entrenamiento de Nextflow para Bioimagen! + +Agradeceríamos mucho sus comentarios para ayudarnos a mejorar este material de entrenamiento. + +Por favor, tome unos minutos para completar nuestra breve encuesta: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Sus respuestas nos ayudarán a comprender qué funcionó bien y qué podemos mejorar para futuros estudiantes. + +¡Gracias por su tiempo y participación! diff --git a/docs/es/docs/nf4_science/index.md b/docs/es/docs/nf4_science/index.md new file mode 100644 index 0000000000..5c47df4100 --- /dev/null +++ b/docs/es/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow para Ciencia +hide: + - toc +--- + +# Nextflow para Ciencia + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Estos son cursos que demuestran cómo aplicar los conceptos y componentes presentados en el curso para principiantes [Hello Nextflow](../hello_nextflow/) a casos de uso científicos específicos. Cada curso consiste en una serie de módulos de entrenamiento diseñados para ayudar a los estudiantes a desarrollar sus habilidades de forma progresiva. + +!!! exercise "Ejercicio" + + !!! tip inline end "" + + :material-run-fast: Aprenda a desarrollar un pipeline para genómica en Nextflow. + + Este es un curso para investigadores que desean aprender a desarrollar sus propios pipelines de genómica. El curso utiliza un caso de uso de identificación de variantes para demostrar cómo desarrollar un pipeline de genómica simple pero funcional. + + [Comience el entrenamiento de Nextflow para Genómica :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Ejercicio" + + !!! tip inline end "" + + :material-run-fast: Aprenda a desarrollar un pipeline para procesamiento de datos RNAseq en Nextflow. + + Este es un curso para investigadores que desean aprender a desarrollar sus propios pipelines de RNAseq. El curso utiliza un caso de uso de procesamiento de RNAseq masivo para demostrar cómo desarrollar un pipeline de RNAseq simple pero funcional. + + [Comience el entrenamiento de Nextflow para RNAseq :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Ejercicio" + + !!! tip inline end "" + + :material-run-fast: Aprenda a ejecutar pipelines para datos de imágenes en Nextflow. + + Este es un curso para investigadores que desean aprender a ejecutar y configurar pipelines de bioimagen. El curso utiliza nf-core/molkart para demostrar patrones esenciales de uso de Nextflow aplicables a cualquier pipeline. + + [Comience el entrenamiento de Nextflow para Bioimagen :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Háganos saber qué otros dominios y casos de uso le gustaría ver cubiertos aquí publicando en la [sección de Entrenamiento](https://community.seqera.io/c/training/) del foro de la comunidad. diff --git a/docs/es/docs/nf4_science/rnaseq/00_orientation.md b/docs/es/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..00716953dd --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +El entorno de entrenamiento contiene todo el software, código y datos necesarios para trabajar en este curso de entrenamiento, por lo que no necesita instalar nada usted mismo. +Sin embargo, sí necesita una cuenta (gratuita) para iniciar sesión, y debe tomarse unos minutos para familiarizarse con la interfaz. + +Si aún no lo ha hecho, por favor complete el mini-curso de [Configuración del Entorno](../../envsetup/) antes de continuar. + +## Materiales proporcionados + +A lo largo de este curso de entrenamiento, trabajaremos en el directorio `nf4-science/rnaseq/`, al cual debe moverse cuando abra el espacio de trabajo de entrenamiento. +Este directorio contiene todos los archivos de código, datos de prueba y archivos accesorios que necesitará. + +Siéntase libre de explorar el contenido de este directorio; la forma más fácil de hacerlo es usar el explorador de archivos en el lado izquierdo del espacio de trabajo de entrenamiento en la interfaz de VSCode. +Alternativamente, puede usar el comando `tree`. +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenido del directorio en una forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 3 +``` + +??? success "Contenido del directorio" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + No se preocupe si esto parece mucho; revisaremos las partes relevantes en cada paso del curso. + Esto es solo para darle una visión general. + +**Aquí hay un resumen de lo que debe saber para comenzar:** + +- **El archivo `rnaseq.nf`** es el esquema del script de flujo de trabajo que desarrollaremos. + +- **El archivo `nextflow.config`** es un archivo de configuración que establece propiedades mínimas del entorno. Puede ignorarlo por ahora. + +- **El directorio `data`** contiene datos de entrada y recursos relacionados: + + - _Un genoma de referencia_ llamado `genome.fa` que consiste en una pequeña región del cromosoma 20 humano (de hg19/b37). + - _Datos de RNAseq_ que han sido reducidos a una pequeña región para mantener los tamaños de archivo pequeños, en el directorio `reads/`. + - _Archivos CSV_ que listan los IDs y rutas de los archivos de datos de ejemplo, para procesamiento en lotes. + +- **El directorio `solutions`** contiene los scripts de flujo de trabajo y módulos completados que resultan de cada paso del curso. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + El número en el nombre del archivo corresponde al paso de la parte relevante del curso. + +!!!tip + + Si por cualquier razón sale de este directorio, siempre puede ejecutar este comando para regresar: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Ahora, para comenzar el curso, haga clic en la flecha en la esquina inferior derecha de esta página. diff --git a/docs/es/docs/nf4_science/rnaseq/01_method.md b/docs/es/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..84d9bb6d6c --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Parte 1: Descripción general del método y pruebas manuales + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Existen múltiples métodos válidos para procesar y analizar datos de RNAseq en bulk. +Para este curso, seguimos el método descrito [aquí](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) por los Drs. Simon Andrews y Laura Biggins en el [Babraham Institute](https://www.babraham.ac.uk/). + +Nuestro objetivo es desarrollar un flujo de trabajo que implemente los siguientes pasos de procesamiento: ejecutar control de calidad inicial en las lecturas de una muestra de RNAseq en bulk, recortar secuencias de adaptadores de las lecturas, alinear las lecturas a un genoma de referencia y producir un informe completo de control de calidad (QC). + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** Realizar QC en los datos de lectura antes del recorte usando FastQC +- **TRIM_GALORE:** Recortar secuencias de adaptadores y realizar QC después del recorte usando Trim Galore (agrupa Cutadapt y FastQC) +- **HISAT2_ALIGN:** Alinear lecturas al genoma de referencia usando Hisat2 +- **MULTIQC:** Generar un informe QC completo usando MultiQC + +Sin embargo, antes de comenzar a escribir cualquier código de flujo de trabajo, vamos a probar los comandos manualmente con algunos datos de prueba. +Las herramientas que necesitamos no están instaladas en el entorno de GitHub Codespaces, por lo que las usaremos a través de contenedores (ver [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Nota" + + Asegúrese de estar en el directorio `nf4-science/rnaseq`. La última parte de la ruta que se muestra cuando escribe `pwd` debe ser `rnaseq`. + +--- + +## 1. QC inicial y recorte de adaptadores + +Vamos a descargar una imagen de contenedor que tiene instalados tanto `fastqc` como `trim_galore`, iniciarlo de forma interactiva y ejecutar los comandos de recorte y QC en uno de los archivos de datos de ejemplo. + +### 1.1. Descargar el contenedor + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Esto le proporciona la siguiente salida de consola mientras el sistema descarga la imagen: + +??? success "Salida del comando" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Iniciar el contenedor de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Salida del comando" + + ```console + + ``` +--> + +Su prompt cambiará a algo como `(base) root@b645838b3314:/tmp#`, lo que indica que ahora está dentro del contenedor. + +La parte `-v ./data:/data` del comando nos permitirá acceder al contenido del directorio `data/` desde dentro del contenedor. + +```bash +ls /data/reads +``` + +??? success "Salida del comando" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Ejecutar el primer comando `fastqc` + +Ejecutemos `fastqc` para recopilar métricas de control de calidad en los datos de lectura. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Salida del comando" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Esto debería ejecutarse muy rápidamente. +Puede encontrar los archivos de salida en el mismo directorio que los datos originales: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Salida" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Recortar secuencias de adaptadores con `trim_galore` + +Ahora ejecutemos `trim_galore`, que agrupa Cutadapt y FastQC, para recortar las secuencias de adaptadores y recopilar métricas QC posteriores al recorte. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +La opción `--fastqc` hace que el comando ejecute automáticamente un paso de recopilación de QC después de que se complete el recorte. + +_La salida es muy detallada, por lo que lo siguiente está abreviado._ + +??? success "Salida del comando" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Puede encontrar los archivos de salida en el directorio de trabajo: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Salida" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Mover los archivos de salida al sistema de archivos fuera del contenedor + +Cualquier cosa que permanezca dentro del contenedor será inaccesible para trabajo futuro, así que movamos estos archivos a un nuevo directorio. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Salir del contenedor + +```bash +exit +``` + +--- + +## 2. Alinear las lecturas al genoma de referencia + +Vamos a descargar una imagen de contenedor que tiene instalado `hisat2`, iniciarlo de forma interactiva y ejecutar el comando de alineamiento para alinear los datos de RNAseq a un genoma de referencia. + +### 2.1. Descargar el contenedor de `hisat2` + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Salida del comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. Iniciar el contenedor de `hisat2` de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +El comando es el mismo que antes, con el URI del contenedor correspondiente intercambiado. + +### 2.3. Crear los archivos de índice del genoma para Hisat2 + +Hisat2 requiere que la referencia del genoma se proporcione en un formato muy específico, y no puede simplemente consumir el archivo FASTA `genome.fa` que proporcionamos, por lo que vamos a aprovechar esta oportunidad para crear los recursos relevantes. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +La salida es muy detallada, por lo que lo siguiente está abreviado: + +<!-- TODO: switch to full output --> + +??? success "Salida del comando" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Esto crea múltiples archivos de índice del genoma, que puede encontrar en el directorio de trabajo. + +```bash +ls genome_index.* +``` + +```console title="Salida" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Los usaremos en un momento, pero primero generemos un archivo tar comprimido con estos archivos de índice del genoma; los necesitaremos más adelante y generar estos no es típicamente algo que queramos hacer como parte de un flujo de trabajo. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Esto almacena un archivo tar `genome_index.tar.gz` que contiene los archivos de índice del genoma en el directorio `data/` en nuestro sistema de archivos, lo cual será útil en la Parte 2 de este curso. + +### 2.4. Ejecutar el comando `hisat2` + +Ahora podemos ejecutar el comando de alineamiento, que realiza el paso de alineamiento con `hisat2` y luego dirige la salida a `samtools` para escribir la salida como un archivo BAM. + +La entrada de datos de lectura es el archivo `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` que generamos con `trim_galore` en el paso anterior. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Salida del comando" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Esto se ejecuta casi instantáneamente porque es un archivo de prueba muy pequeño. +A escala real, esto podría tardar mucho más. + +Una vez más, puede encontrar los archivos de salida en el directorio de trabajo: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Salida" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Mover los archivos de salida al sistema de archivos fuera del contenedor + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Salir del contenedor + +```bash +exit +``` + +--- + +## 3. Generar un informe QC completo + +Vamos a descargar una imagen de contenedor que tiene instalado `multiqc`, iniciarlo de forma interactiva y ejecutar un comando de generación de informes en los archivos de informe FastQC antes/después. + +### 3.1. Descargar el contenedor de `multiqc` + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Salida del comando" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. Iniciar el contenedor de `multiqc` de forma interactiva + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. Ejecutar el comando `multiqc` + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Salida del comando" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC puede buscar en directorios informes QC compatibles y agregará todo lo que encuentre. + +Aquí vemos que la herramienta encontró los tres informes QC que generamos: el QC inicial que hicimos con `fastqc`, el informe posterior al recorte de `cutadapt` (hecho a través de `trim_galore`) y el QC posterior al alineamiento producido por `hisat2`. + +Los archivos de salida están una vez más en el directorio de trabajo: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Salida" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Mover los archivos de salida al sistema de archivos fuera del contenedor + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Salir del contenedor + +```bash +exit +``` + +--- + +### Conclusión + +Ha probado todos los comandos individuales de forma interactiva en los contenedores correspondientes. + +### ¿Qué sigue? + +Aprenda a envolver esos mismos comandos en un flujo de trabajo de múltiples pasos que usa contenedores para ejecutar el trabajo. diff --git a/docs/es/docs/nf4_science/rnaseq/02_single-sample.md b/docs/es/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..a42085350c --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Parte 2: Implementación de muestra única + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta parte del curso, vamos a escribir el flujo de trabajo más simple posible que envuelva todos los comandos que ejecutamos en la Parte 1 para automatizar su ejecución, y nos enfocaremos en procesar una muestra a la vez. + +Haremos esto en tres etapas: + +1. Escribir un flujo de trabajo de una sola etapa que ejecute el paso inicial de control de calidad +2. Agregar el recorte de adaptadores y el control de calidad posterior al recorte +3. Agregar alineamiento al genoma de referencia + +!!! warning "Requisito previo" + + Debe completar la Parte 1 del curso antes de comenzar esta lección. + Específicamente, trabajar en las secciones 2.1-3 crea el archivo de índice del genoma (`data/genome_index.tar.gz`) requerido para el paso de alineamiento en esta lección. + +--- + +## 1. Escribir un flujo de trabajo de una sola etapa que ejecute el control de calidad inicial + +Comencemos escribiendo un flujo de trabajo simple que ejecute la herramienta FastQC en un archivo FASTQ que contenga lecturas de RNAseq de extremo simple. + +Le proporcionamos un archivo de flujo de trabajo, `rnaseq.nf`, que describe las partes principales del flujo de trabajo. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Declaraciones de inclusión de módulos + +/* + * Pipeline parameters + */ + +// Entrada principal + +workflow { + + // Crear canal de entrada + + // Llamar procesos + +} +``` + +Tenga en cuenta que este código de flujo de trabajo es correcto pero no es funcional; su propósito es solo servir como esqueleto que usará para escribir el flujo de trabajo real. + +### 1.1. Crear un directorio para almacenar módulos + +Crearemos módulos independientes para cada proceso para facilitar su gestión y reutilización, así que creemos un directorio para almacenarlos. + +```bash +mkdir modules +``` + +### 1.2. Crear un módulo para el proceso de recolección de métricas de control de calidad + +Creemos un archivo de módulo llamado `modules/fastqc.nf` para alojar el proceso `FASTQC`: + +```bash +touch modules/fastqc.nf +``` + +Abra el archivo en el editor de código y copie el siguiente código en él: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Debería reconocer todas las piezas de lo que aprendió en la Parte 1 y Parte 2 de esta serie de entrenamiento; el único cambio notable es que esta vez estamos usando `mode: symlink` para la directiva `publishDir`, y estamos usando un parámetro para definir el `publishDir`. + +!!! note "Nota" + + Aunque los archivos de datos que estamos usando aquí son muy pequeños, en genómica pueden volverse muy grandes. Para fines de demostración en el entorno de enseñanza, estamos usando el modo de publicación 'symlink' para evitar copias de archivos innecesarias. No debería hacer esto en sus flujos de trabajo finales, ya que perderá resultados cuando limpie su directorio `work`. + +### 1.3. Importar el módulo en el archivo de flujo de trabajo + +Agregue la declaración `include { FASTQC } from './modules/fastqc.nf'` al archivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declaraciones de inclusión de módulos +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Agregar una declaración de entrada + +Declare un parámetro de entrada con un valor predeterminado: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Entrada principal + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Crear un canal de entrada en el bloque workflow + +Use una fábrica de canal básica `.fromPath()` para crear el canal de entrada: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Crear canal de entrada from a file path + read_ch = channel.fromPath(params.reads) + + // Llamar procesos + +} +``` + +### 1.6. Llamar al proceso `FASTQC` en el canal de entrada + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Crear canal de entrada from a file path + read_ch = channel.fromPath(params.reads) + + // Initial quality control + FASTQC(read_ch) + +} +``` + +### 1.7. Ejecutar el flujo de trabajo para verificar que funciona + +Podríamos usar el parámetro `--reads` para especificar una entrada desde la línea de comandos, pero durante el desarrollo podemos ser perezosos y simplemente usar el valor predeterminado de prueba que configuramos. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Esto debería ejecutarse muy rápidamente si trabajó en la Parte 1 y ya ha descargado el contenedor. +Si la omitió, Nextflow descargará el contenedor por usted; no tiene que hacer nada para que suceda, pero es posible que deba esperar hasta un minuto. + +Puede encontrar las salidas bajo `results/fastqc` como se especifica en el proceso `FASTQC` por la directiva `publishDir`. + +```bash +ls results/fastqc +``` + +```console title="Salida" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Agregar recorte de adaptadores y control de calidad posterior al recorte + +Vamos a usar el envoltorio Trim_Galore, que incluye Cutadapt para el recorte en sí y FastQC para el control de calidad posterior al recorte. + +### 2.1. Crear un módulo para el proceso de recorte y control de calidad + +Creemos un archivo de módulo llamado `modules/trim_galore.nf` para alojar el proceso `TRIM_GALORE`: + +```bash +touch modules/trim_galore.nf +``` + +Abra el archivo en el editor de código y copie el siguiente código en él: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Importar el módulo en el archivo de flujo de trabajo + +Agregue la declaración `include { TRIM_GALORE } from './modules/trim_galore.nf'` al archivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declaraciones de inclusión de módulos +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Llamar al proceso en el canal de entrada + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Crear canal de entrada from a file path + read_ch = channel.fromPath(params.reads) + + // Initial quality control + FASTQC(read_ch) + + // Adapter trimming and post-trimming QC + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Ejecutar el flujo de trabajo para verificar que funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Esto también debería ejecutarse muy rápidamente, ya que estamos ejecutando en un archivo de entrada tan pequeño. + +Puede encontrar las salidas bajo `results/trimming` como se especifica en el proceso `TRIM_GALORE` por la directiva `publishDir`. + +```bash +ls results/trimming +``` + +```console title="Salida" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Alinear las lecturas al genoma de referencia + +Finalmente podemos ejecutar el paso de alineamiento del genoma usando Hisat2, que también emitirá métricas de control de calidad al estilo FastQC. + +### 3.1. Crear un módulo para el proceso HiSat2 + +Creemos un archivo de módulo llamado `modules/hisat2_align.nf` para alojar el proceso `HISAT2_ALIGN`: + +```bash +touch modules/hisat2_align.nf +``` + +Abra el archivo en el editor de código y copie el siguiente código en él: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Importar el módulo en el archivo de flujo de trabajo + +Agregue la declaración `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` al archivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declaraciones de inclusión de módulos +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Agregar una declaración de parámetro para proporcionar el índice del genoma + +Declare un parámetro de entrada con un valor predeterminado: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Entrada principal + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Llamar al proceso `HISAT2_ALIGN` en las lecturas recortadas de salida de `TRIM_GALORE` + +Las lecturas recortadas están en el canal `TRIM_GALORE.out.trimmed_reads` de salida del paso anterior. + +Además, usamos `file (params.hisat2_index_zip)` para proporcionar a la herramienta Hisat2 el archivo tarball comprimido del índice del genoma. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Crear canal de entrada from a file path + read_ch = channel.fromPath(params.reads) + + // Initial quality control + FASTQC(read_ch) + + // Adapter trimming and post-trimming QC + TRIM_GALORE(read_ch) + + // Alineamiento a un genoma de referencia + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Ejecutar el flujo de trabajo para verificar que funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Puede encontrar las salidas bajo `results/align` como se especifica en el proceso `HISAT2_ALIGN` por la directiva `publishDir`. + +```bash +ls results/align +``` + +```console title="Salida" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Esto completa el procesamiento básico que necesitamos aplicar a cada muestra. + +_Agregaremos la agregación de informes MultiQC en la Parte 2, después de que hayamos modificado el flujo de trabajo para aceptar múltiples muestras a la vez._ + +--- + +### Conclusión + +Sabe cómo envolver todos los pasos principales para procesar muestras de RNAseq de extremo simple individualmente. + +### ¿Qué sigue? + +Aprenda cómo modificar el flujo de trabajo para procesar múltiples muestras en paralelo, agregar informes de control de calidad en todos los pasos para todas las muestras, y habilitar la ejecución del flujo de trabajo en datos de RNAseq de extremo pareado. diff --git a/docs/es/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/es/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..93005950b8 --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Parte 3: Implementación con múltiples muestras de extremos pareados + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En esta parte final del curso, vamos a llevar nuestro flujo de trabajo simple al siguiente nivel convirtiéndolo en una poderosa herramienta de automatización por lotes para manejar números arbitrarios de muestras. +Y mientras lo hacemos, también vamos a cambiarlo para que espere datos de extremos pareados, que son más comunes en estudios más recientes. + +Lo haremos en tres etapas: + +1. Hacer que el flujo de trabajo acepte múltiples muestras de entrada y paralelice la ejecución +2. Agregar generación de reportes de control de calidad completos +3. Cambiar a datos de RNAseq de extremos pareados + +--- + +## 1. Hacer que el flujo de trabajo acepte múltiples muestras de entrada y paralelice la ejecución + +Vamos a necesitar cambiar cómo gestionamos la entrada. + +### 1.1. Cambiar la entrada principal para que sea un CSV de rutas de archivos en lugar de un solo archivo + +Proporcionamos un archivo CSV que contiene IDs de muestra y rutas de archivos FASTQ en el directorio `data/`. +Este archivo CSV incluye una línea de encabezado. +Observe que las rutas de archivos FASTQ son rutas absolutas. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Renombremos el parámetro de entrada principal a `input_csv` y cambiemos el valor predeterminado para que sea la ruta al archivo `single-end.csv`. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Entrada principal + input_csv: Path = "data/single-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Actualizar la fábrica de canales de entrada para manejar un CSV como entrada + +Vamos a querer cargar los contenidos del archivo en el canal en lugar de solo la ruta del archivo, así que usamos el operador `.splitCsv()` para analizar el formato CSV, luego el operador `.map()` para obtener la información específica que queremos (la ruta del archivo FASTQ). + +```groovy title="rnaseq.nf" linenums="16" + // Crear canal de entrada a partir del contenido de un archivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Ejecutar el flujo de trabajo para probar que funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Esta vez vemos que cada paso se ejecuta 6 veces, en cada uno de los 6 archivos de datos que proporcionamos. + +¡Eso es todo lo que se necesitó para que el flujo de trabajo se ejecute en múltiples archivos! +Nextflow maneja todo el paralelismo por nosotros. + +--- + +## 2. Agregar métricas de control de calidad de preprocesamiento en un solo reporte MultiQC + +Todo esto produce muchos reportes de control de calidad, y no queremos tener que revisar reportes individuales. +¡Este es el punto perfecto para poner un paso de agregación de reportes MultiQC! + +### 2.1. Crear un módulo para el proceso de agregación de control de calidad + +Creemos un archivo de módulo llamado `modules/multiqc.nf` para alojar el proceso `MULTIQC`: + +```bash +touch modules/multiqc.nf +``` + +Abra el archivo en el editor de código y copie el siguiente código en él: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Importar el módulo en el archivo del flujo de trabajo + +Agregue la declaración `include { MULTIQC } from './modules/multiqc.nf'` al archivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declaraciones de inclusión de módulos +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Agregar un parámetro `report_id` y darle un valor predeterminado sensato + +```groovy title="rnaseq.nf" linenums="9" +params { + // Entrada principal + input_csv: Path = "data/single-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_single-end" +} +``` + +### 2.4. Llamar al proceso con las salidas de los pasos anteriores + +Necesitamos darle al proceso `MULTIQC` todas las salidas relacionadas con control de calidad de los pasos anteriores. + +Para eso, vamos a usar el operador `.mix()`, que agrega múltiples canales en uno solo. + +Si tuviéramos cuatro procesos llamados A, B, C y D con un canal `.out` simple cada uno, la sintaxis se vería así: `A.out.mix( B.out, C.out, D.out )`. Como puede ver, se aplica al primero de los canales que desea combinar (no importa cuál) y simplemente agrega todos los demás, separados por comas, en el paréntesis que sigue. + +En el caso de nuestro flujo de trabajo, tenemos las siguientes salidas para agregar: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Así que el ejemplo de sintaxis se convierte en: + +```groovy title="Aplicando .mix() en la llamada a MULTIQC" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Eso recogerá reportes de control de calidad por muestra. +Pero como queremos agregarlos a través de todas las muestras, necesitamos agregar el operador `collect()` para reunir los reportes de todas las muestras en una sola llamada a `MULTIQC`. +Y también necesitamos darle el parámetro `report_id`. + +Esto nos da lo siguiente: + +```groovy title="La llamada completa a MULTIQC" linenums="33" + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +En el contexto del bloque de flujo de trabajo completo, termina viéndose así: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Crear canal de entrada a partir del contenido de un archivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// Initial quality control + FASTQC(read_ch) + + // Adapter trimming and post-trimming QC + TRIM_GALORE(read_ch) + + // Alineamiento a un genoma de referencia + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Ejecutar el flujo de trabajo para probar que funciona + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Esta vez vemos una sola llamada a MULTIQC agregada después de las llamadas a procesos en caché: + +Puede encontrar las salidas en `results/trimming` según lo especificado en el proceso `TRIM_GALORE` por la directiva `publishDir`. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Salida" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Ese último archivo `all_single-end.html` es el reporte agregado completo, convenientemente empaquetado en un archivo HTML fácil de navegar. + +--- + +## 3. Habilitar el procesamiento de datos de RNAseq de extremos pareados + +Actualmente nuestro flujo de trabajo solo puede manejar datos de RNAseq de un solo extremo. +Es cada vez más común ver datos de RNAseq de extremos pareados, así que queremos poder manejar eso. + +Hacer que el flujo de trabajo sea completamente agnóstico del tipo de datos requeriría usar características del lenguaje Nextflow un poco más avanzadas, así que no vamos a hacerlo aquí, pero podemos hacer una versión de procesamiento de extremos pareados para demostrar qué necesita ser adaptado. + +### 3.1. Hacer una copia del flujo de trabajo llamada `rnaseq_pe.nf` + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Modificar el `input_csv` predeterminado para que apunte a los datos de extremos pareados + +Proporcionamos un segundo archivo CSV que contiene IDs de muestra y rutas de archivos FASTQ pareados en el directorio `data/` + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Cambiemos el valor predeterminado de `input_csv` para que sea la ruta al archivo `paired-end.csv`. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Entrada principal + input_csv: Path = "data/paired-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_single-end" +} +``` + +### 3.3. Actualizar la fábrica de canales + +Necesitamos decirle al operador `.map()` que obtenga ambas rutas de archivos FASTQ ahora. + +Así que `row -> file(row.fastq_path)` se convierte en `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Crear canal de entrada a partir del contenido de un archivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Hacer una versión de extremos pareados del proceso FASTQC + +Hagamos una copia del módulo para que podamos tener ambas versiones a mano. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Abra el nuevo archivo de módulo `fastqc_pe.nf` en el editor de código y haga los siguientes cambios de código: + +- Cambie `fastqc $reads` a `fastqc ${reads}` en el bloque `script` (línea 17) para que la entrada `reads` se desempaquete, ya que ahora es una tupla de dos rutas en lugar de una sola ruta. +- Reemplace `${reads.simpleName}` con un comodín (`*`) para evitar tener que manejar los archivos de salida individualmente. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Técnicamente esto generaliza el proceso `FASTQC` de una manera que lo hace capaz de manejar datos de RNAseq de un solo extremo o de extremos pareados. + +Finalmente, actualice la declaración de importación del módulo para usar la versión de extremos pareados del módulo. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Hacer una versión de extremos pareados del proceso TRIM_GALORE + +Haga una copia del módulo para que podamos tener ambas versiones a mano. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Abra el nuevo archivo de módulo `trim_galore_pe.nf` en el editor de código y haga los siguientes cambios de código: + +- Cambie la declaración de entrada de `path reads` a `tuple path(read1), path(read2)` +- Actualice el comando en el bloque `script`, reemplazando `$reads` con `--paired ${read1} ${read2}` +- Actualice las declaraciones de salida para reflejar los archivos agregados y las convenciones de nomenclatura diferentes, usando comodines para evitar tener que listar todo. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Finalmente, actualice la declaración de importación del módulo para usar la versión de extremos pareados del módulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Actualizar la llamada al proceso MULTIQC para esperar dos reportes de TRIM_GALORE + +El proceso `TRIM_GALORE` ahora produce un canal de salida adicional, así que necesitamos alimentar eso a MultiQC. + +Reemplace `TRIM_GALORE.out.fastqc_reports,` con `TRIM_GALORE.out.fastqc_reports_1,` más `TRIM_GALORE.out.fastqc_reports_2,`: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Mientras estamos en MultiQC, actualicemos también el valor predeterminado del parámetro `report_id` de `"all_single-end"` a `"all_paired-end"`. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Entrada principal + input_csv: Path = "data/paired-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_paired-end" +} +``` + +### 3.7. Hacer una versión de extremos pareados del proceso HISAT2_ALIGN + +Haga una copia del módulo para que podamos tener ambas versiones a mano. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Abra el nuevo archivo de módulo `hisat2_align_pe.nf` en el editor de código y haga los siguientes cambios de código: + +- Cambie la declaración de entrada de `path reads` a `tuple path(read1), path(read2)` +- Actualice el comando en el bloque `script`, reemplazando `-U $reads` con `-1 ${read1} -2 ${read2}` +- Reemplace todas las instancias de `${reads.simpleName}` con `${read1.simpleName}` en el comando en el bloque `script` así como en las declaraciones de salida. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Finalmente, actualice la declaración de importación del módulo para usar la versión de extremos pareados del módulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Ejecutar el flujo de trabajo para probar que funciona + +No usamos `-resume` ya que esto no usaría la caché, y hay el doble de datos para procesar que antes, pero aún así debería completarse en menos de un minuto. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +¡Y eso es todo! Ahora tenemos dos versiones ligeramente divergentes de nuestro flujo de trabajo, una para datos de lecturas de un solo extremo y una para datos de extremos pareados. +El siguiente paso lógico sería hacer que el flujo de trabajo acepte cualquier tipo de datos sobre la marcha, lo cual está fuera del alcance de este curso, pero podríamos abordar eso en un seguimiento. + +--- + +### Conclusión + +Usted sabe cómo adaptar un flujo de trabajo de una sola muestra para paralelizar el procesamiento de múltiples muestras, generar un reporte de control de calidad completo y adaptar el flujo de trabajo para usar datos de lecturas de extremos pareados si es necesario. + +### ¿Qué sigue? + +¡Felicitaciones, ha completado el mini-curso de Nextflow para RNAseq! ¡Celebre su éxito y tome un merecido descanso! + +A continuación, le pedimos que complete una encuesta muy breve sobre su experiencia con este curso de entrenamiento, luego lo llevaremos a una página con enlaces a recursos de entrenamiento adicionales y enlaces útiles. diff --git a/docs/es/docs/nf4_science/rnaseq/index.md b/docs/es/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..99896f01e1 --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,40 @@ +# Nextflow para RNAseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de entrenamiento está dirigido a investigadores en transcriptómica y campos relacionados que estén interesados en desarrollar o personalizar pipelines de análisis de datos. +Se basa en el entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/) y demuestra cómo usar Nextflow en el contexto específico del análisis de RNAseq masivo. + +Específicamente, este curso demuestra cómo implementar un pipeline simple de procesamiento de RNAseq masivo para recortar secuencias adaptadoras, alinear las lecturas a un genoma de referencia y realizar control de calidad (QC) en varias etapas. + +¡Comencemos! Haga clic en el botón "Open in GitHub Codespaces" a continuación para iniciar el entorno de entrenamiento (preferiblemente en una pestaña separada), luego continúe leyendo mientras se carga. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizaje + +Al trabajar en este curso, aprenderá a aplicar conceptos fundamentales de Nextflow y herramientas a un caso de uso típico de RNAseq. + +Al finalizar este taller, usted será capaz de: + +- Escribir un workflow lineal para aplicar métodos básicos de procesamiento de RNAseq y QC +- Manejar apropiadamente archivos específicos del dominio como FASTQ y recursos de genoma de referencia +- Manejar datos de secuenciación de extremo simple y extremo pareado +- Aprovechar el paradigma de flujo de datos de Nextflow para paralelizar el procesamiento de RNAseq por muestra +- Agregar reportes de QC a través de múltiples pasos y muestras usando operadores de channel relevantes + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Requisitos previos + +El curso asume cierta familiaridad mínima con lo siguiente: + +- Herramientas y formatos de archivo comúnmente usados en este dominio científico +- Experiencia con la línea de comandos +- Conceptos fundamentales de Nextflow y herramientas cubiertas en el entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/). + +Para requisitos técnicos y configuración del entorno, consulte el mini-curso [Configuración del Entorno](../../envsetup/). diff --git a/docs/es/docs/nf4_science/rnaseq/next_steps.md b/docs/es/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..dc4798a892 --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Próximos Pasos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +¡Felicitaciones nuevamente por completar el curso de entrenamiento de Nextflow para RNAseq y gracias por completar nuestra encuesta! + +--- + +## 1. Las 3 mejores formas de mejorar sus habilidades en Nextflow + +Aquí están nuestras tres principales recomendaciones sobre qué hacer a continuación basadas en el curso que acaba de completar. + +### 1.1. Aplique Nextflow a otros casos de uso de análisis científico + +**Consulte la página [Nextflow para Ciencia](../nf4_science/index.md)** para obtener una lista de otros cursos cortos independientes que demuestran cómo aplicar los conceptos básicos y mecanismos presentados en Hello Nextflow a casos de uso comunes de análisis científico. + +Si no ve su dominio representado por un caso de uso relacionado, háganoslo saber en el [foro de la Comunidad](https://community.seqera.io/) para que podamos agregarlo a nuestra lista de desarrollo. + +### 1.2. Comience con nf-core + +**[nf-core](https://nf-co.re/)** es un esfuerzo colaborativo mundial para desarrollar pipelines estandarizados de código abierto para una amplia gama de aplicaciones de investigación científica. +El proyecto incluye [más de 100 pipelines](https://nf-co.re/pipelines/) que están disponibles para usar listos para usar y [más de 1400 módulos de procesos](https://nf-co.re/modules/) que pueden integrarse en sus propios proyectos, así como un rico conjunto de herramientas para desarrolladores. + +El curso de entrenamiento **[Hello nf-core](../../hello_nf-core/index.md)** le presentará los pipelines curados por la comunidad nf-core y el marco de desarrollo, diseñado para ayudarle a escribir flujos de trabajo reproducibles, escalables y estandarizados. Aprenderá cómo usar pipelines nf-core existentes, contribuir a su desarrollo e incluso comenzar a construir los suyos propios, respaldado por mejores prácticas y una comunidad vibrante. Si está listo para aplicar sus habilidades de Nextflow en proyectos del mundo real, este es el siguiente paso perfecto. + +### 1.3. Domine características más avanzadas de Nextflow + +En los cursos Hello, mantenemos el nivel de complejidad técnica bajo a propósito para evitar sobrecargarlo con información que no necesita para comenzar con Nextflow. +A medida que avance con su trabajo, querrá aprender cómo usar el conjunto completo de características y el poder de Nextflow. + +Con ese fin, actualmente estamos trabajando en una **colección de [Misiones Secundarias](../side_quests/index.md)**, que están diseñadas para ser cursos cortos independientes que profundizan en temas específicos como pruebas y manejo de metadatos. + +--- + +## 2. Consulte Seqera Platform + +**[Seqera Platform](https://seqera.io/) es la mejor manera de ejecutar Nextflow en la práctica.** + +Es una plataforma basada en la nube desarrollada por los creadores de Nextflow que puede conectar a su propia infraestructura de cómputo (ya sea local, HPC o nube) para facilitar mucho el lanzamiento y gestión de sus flujos de trabajo, así como gestionar sus datos y ejecutar análisis de forma interactiva en un entorno de nube. + +El nivel gratuito está disponible para uso gratuito por parte de todos (con cuotas de uso). +Los académicos calificados pueden obtener acceso gratuito de nivel Pro (sin limitaciones de uso) a través del [Programa Académico](https://seqera.io/academic/program/). + +Eche un vistazo a los [tutoriales de Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) para ver si esto podría ser útil para usted. + +--- + +### ¡Eso es todo por ahora! + +**Buena suerte en su viaje con Nextflow y no dude en hacérnoslo saber en el [foro de la Comunidad](https://community.seqera.io/) qué más podríamos hacer para ayudar.** diff --git a/docs/es/docs/nf4_science/rnaseq/survey.md b/docs/es/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..1fb5aff4e3 --- /dev/null +++ b/docs/es/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Encuesta de retroalimentación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, por favor complete esta breve encuesta de 5 preguntas para calificar el entrenamiento, compartir cualquier comentario que pueda tener sobre su experiencia, y hacernos saber qué más podríamos hacer para ayudarle en su camino con Nextflow. + +Esto debería tomarle menos de un minuto completar. ¡Gracias por ayudarnos a mejorar nuestros materiales de entrenamiento para todos! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/es/docs/side_quests/README.md b/docs/es/docs/side_quests/README.md new file mode 100644 index 0000000000..d046885904 --- /dev/null +++ b/docs/es/docs/side_quests/README.md @@ -0,0 +1 @@ +Este es un marcador de posición para las futuras Misiones Secundarias (entrenamientos profundos). Los documentos que se encuentran aquí actualmente son borradores basados en contenido reutilizado de otros lugares. diff --git a/docs/es/docs/side_quests/debugging.md b/docs/es/docs/side_quests/debugging.md new file mode 100644 index 0000000000..870ae4edc0 --- /dev/null +++ b/docs/es/docs/side_quests/debugging.md @@ -0,0 +1,1671 @@ +# Depuración de Flujos de Trabajo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +La depuración es una habilidad crítica que puede ahorrarle horas de frustración y ayudarle a convertirse en un desarrollador de Nextflow más eficaz. A lo largo de su carrera, especialmente cuando está comenzando, encontrará errores mientras construye y mantiene sus flujos de trabajo. Aprender enfoques sistemáticos de depuración le ayudará a identificar y resolver problemas rápidamente. + +### Objetivos de aprendizaje + +En esta misión secundaria, exploraremos **técnicas sistemáticas de depuración** para flujos de trabajo de Nextflow: + +- **Depuración de errores de sintaxis**: Uso efectivo de características del IDE y mensajes de error de Nextflow +- **Depuración de canales**: Diagnóstico de problemas de flujo de datos y problemas de estructura de canales +- **Depuración de procesos**: Investigación de fallas de ejecución y problemas de recursos +- **Herramientas de depuración integradas**: Aprovechamiento del modo preview, ejecución stub y directorios de trabajo de Nextflow +- **Enfoques sistemáticos**: Una metodología de cuatro fases para depuración eficiente + +Al final, tendrá una metodología robusta de depuración que transforma mensajes de error frustrantes en hojas de ruta claras hacia soluciones. + +### Requisitos previos + +Antes de emprender esta misión secundaria, debería: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso equivalente para principiantes. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores) + +**Opcional:** Recomendamos completar primero la misión secundaria [Características del IDE para Desarrollo con Nextflow](./ide_features.md). +Esa cubre características completas del IDE que apoyan la depuración (resaltado de sintaxis, detección de errores, etc.), que usaremos intensivamente aquí. + +--- + +## 0. Comenzar + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en [Configuración del Entorno](../envsetup/index.md). + +[![Abrir en GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/debugging +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un conjunto de flujos de trabajo de ejemplo con varios tipos de errores que usaremos para practicar: + +??? abstract "Contenido del directorio" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Estos archivos representan escenarios comunes de depuración que encontrará en el desarrollo del mundo real. + +#### Revisar la asignación + +Su desafío es ejecutar cada flujo de trabajo, identificar el(los) error(es) y corregirlos. + +Para cada flujo de trabajo con errores: + +1. **Ejecutar el flujo de trabajo** y observar el error +2. **Analizar el mensaje de error**: ¿qué le está diciendo Nextflow? +3. **Localizar el problema** en el código usando las pistas proporcionadas +4. **Corregir el error** y verificar que su solución funciona +5. **Restablecer el archivo** antes de pasar a la siguiente sección (use `git checkout <filename>`) + +Los ejercicios progresan desde errores de sintaxis simples hasta problemas de tiempo de ejecución más sutiles. +Las soluciones se discuten en línea, pero intente resolver cada uno usted mismo antes de leer más adelante. + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Errores de Sintaxis + +Los errores de sintaxis son el tipo más común de error que encontrará al escribir código Nextflow. Ocurren cuando el código no se ajusta a las reglas de sintaxis esperadas del DSL de Nextflow. Estos errores evitan que su flujo de trabajo se ejecute en absoluto, por lo que es importante aprender a identificarlos y corregirlos rápidamente. + +### 1.1. Llaves faltantes + +Uno de los errores de sintaxis más comunes, y a veces uno de los más complejos de depurar, son **corchetes faltantes o desemparejados**. + +Comencemos con un ejemplo práctico. + +#### Ejecutar el pipeline + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Elementos clave de los mensajes de error de sintaxis:** + +- **Archivo y ubicación**: Muestra qué archivo y línea/columna contienen el error (`bad_syntax.nf:24:1`) +- **Descripción del error**: Explica lo que el analizador encontró que no esperaba (`Unexpected input: '<EOF>'`) +- **Indicador EOF**: El mensaje `<EOF>` (End Of File - Fin de Archivo) indica que el analizador llegó al final del archivo mientras todavía esperaba más contenido - una señal clásica de llaves sin cerrar + +#### Verificar el código + +Ahora, examinemos `bad_syntax.nf` para entender qué está causando el error: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Falta la llave de cierre para el proceso + +workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) +} +``` + +Para el propósito de este ejemplo, hemos dejado un comentario para mostrarle dónde está el error. La extensión de Nextflow para VSCode también debería estar dándole algunas pistas sobre lo que podría estar mal, poniendo la llave desemparejada en rojo y resaltando el final prematuro del archivo: + +![Bad syntax](img/bad_syntax.png) + +**Estrategia de depuración para errores de corchetes:** + +1. Use el emparejamiento de corchetes de VS Code (coloque el cursor junto a un corchete) +2. Revise el panel de Problemas para mensajes relacionados con corchetes +3. Asegúrese de que cada `{` de apertura tenga su correspondiente `}` de cierre + +#### Corregir el código + +Reemplace el comentario con la llave de cierre faltante: + +=== "Después" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Agregar la llave de cierre faltante + + workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Falta la llave de cierre para el proceso + + workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +#### Ejecutar el pipeline + +Ahora ejecute el flujo de trabajo nuevamente para confirmar que funciona: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Uso de palabras clave o directivas de proceso incorrectas + +Otro error de sintaxis común es una **definición de proceso inválida**. Esto puede suceder si olvida definir bloques requeridos o usa directivas incorrectas en la definición del proceso. + +#### Ejecutar el pipeline + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verificar el código + +El error indica una "Definición de proceso inválida" y muestra el contexto alrededor del problema. Mirando las líneas 3-7, podemos ver `inputs:` en la línea 4, que es el problema. Examinemos `invalid_process.nf`: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // ERROR: Debería ser 'input' no 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) +} +``` + +Mirando la línea 4 en el contexto del error, podemos identificar el problema: estamos usando `inputs` en lugar de la directiva correcta `input`. La extensión de Nextflow para VSCode también marcará esto: + +![Invalid process message](img/invalid_process_message.png) + +#### Corregir el código + +Reemplace la palabra clave incorrecta con la correcta consultando [la documentación](https://www.nextflow.io/docs/latest/process.html#): + +=== "Después" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Corregido: Cambiado 'inputs' a 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // ERROR: Debería ser 'input' no 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crear canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Llamar al proceso con el canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +#### Ejecutar el pipeline + +Ahora ejecute el flujo de trabajo nuevamente para confirmar que funciona: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Uso de nombres de variable incorrectos + +Los nombres de variable que usa en sus bloques de script deben ser válidos, derivados ya sea de entradas o de código groovy insertado antes del script. Pero cuando está manejando complejidad al inicio del desarrollo del pipeline, es fácil cometer errores en el nombramiento de variables, y Nextflow se lo hará saber rápidamente. + +#### Ejecutar el pipeline + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +El error se detecta en tiempo de compilación y apunta directamente a la variable no definida en la línea 17, con un acento circunflejo indicando exactamente dónde está el problema. + +#### Verificar el código + +Examinemos `no_such_var.nf`: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var no definida + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +El mensaje de error indica que la variable no se reconoce en la plantilla del script, y ahí está: puede ver `${undefined_var}` usado en el bloque de script, pero no definido en otro lugar. + +#### Corregir el código + +Si obtiene un error de 'No existe tal variable', puede corregirlo definiendo la variable (corrigiendo nombres de variables de entrada o editando código groovy antes del script), o eliminándola del bloque de script si no es necesaria: + +=== "Después" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Eliminada la línea con undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var no definida + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Ejecutar el pipeline + +Ahora ejecute el flujo de trabajo nuevamente para confirmar que funciona: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Mal uso de variables de Bash + +Comenzando en Nextflow, puede ser difícil entender la diferencia entre variables de Nextflow (Groovy) y Bash. Esto puede generar otra forma del error de variable incorrecta que aparece al intentar usar variables en el contenido Bash del bloque de script. + +#### Ejecutar el pipeline + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verificar el código + +El error apunta a la línea 13 donde se usa `${prefix}`. Examinemos `bad_bash_var.nf` para ver qué está causando el problema: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} es sintaxis Groovy, no Bash + """ +} +``` + +En este ejemplo, estamos definiendo la variable `prefix` en Bash, pero en un proceso de Nextflow la sintaxis `$` que usamos para referirnos a ella (`${prefix}`) se interpreta como una variable Groovy, no Bash. La variable no existe en el contexto Groovy, por lo que obtenemos un error de 'no existe tal variable'. + +#### Corregir el código + +Si quiere usar una variable de Bash, debe escapar el signo de dólar así: + +=== "Después" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Corregido: Escapado el signo de dólar + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} es sintaxis Groovy, no Bash + """ + } + ``` + +Esto le dice a Nextflow que interprete esto como una variable de Bash. + +#### Ejecutar el pipeline + +Ahora ejecute el flujo de trabajo nuevamente para confirmar que funciona: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Variables Groovy vs Bash" + + Para manipulaciones de variables simples como concatenación de strings u operaciones de prefijo/sufijo, generalmente es más legible usar variables Groovy en la sección de script en lugar de variables Bash en el bloque de script: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Este enfoque evita la necesidad de escapar signos de dólar y hace que el código sea más fácil de leer y mantener. + +### 1.5. Declaraciones Fuera del Bloque Workflow + +La extensión de Nextflow para VSCode resalta problemas con la estructura del código que causarán errores. Un ejemplo común es definir canales fuera del bloque `workflow {}` - esto ahora se aplica como un error de sintaxis. + +#### Ejecutar el pipeline + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +El mensaje de error indica claramente el problema: las declaraciones (como definiciones de canales) no pueden mezclarse con declaraciones de script fuera de un bloque workflow o process. + +#### Verificar el código + +Examinemos `badpractice_syntax.nf` para ver qué está causando el error: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Canal definido fuera del workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +La extensión de VSCode también resaltará la variable `input_ch` como definida fuera del bloque workflow: + +![Non-lethal syntax error](img/nonlethal.png) + +#### Corregir el código + +Mueva la definición del canal dentro del bloque workflow: + +=== "Después" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Movido dentro del bloque workflow + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Canal definido fuera del workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Definir variables en código Groovy antes del script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Ejecutar el pipeline + +Ejecute el flujo de trabajo nuevamente para confirmar que la corrección funciona: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Mantenga sus canales de entrada definidos dentro del bloque workflow, y en general siga cualquier otra recomendación que haga la extensión. + +### Conclusión + +Puede identificar y corregir errores de sintaxis sistemáticamente usando mensajes de error de Nextflow e indicadores visuales del IDE. Los errores de sintaxis comunes incluyen llaves faltantes, palabras clave de proceso incorrectas, variables no definidas y uso inadecuado de variables de Bash vs. Nextflow. La extensión de VSCode ayuda a detectar muchos de estos antes del tiempo de ejecución. Con estas habilidades de depuración de sintaxis en su caja de herramientas, podrá resolver rápidamente los errores de sintaxis más comunes de Nextflow y pasar a abordar problemas de tiempo de ejecución más complejos. + +### ¿Qué sigue? + +Aprenda a depurar errores de estructura de canal más complejos que ocurren incluso cuando la sintaxis es correcta. + +--- + +## 2. Errores de Estructura de Canal + +Los errores de estructura de canal son más sutiles que los errores de sintaxis porque el código es sintácticamente correcto, pero las formas de los datos no coinciden con lo que los procesos esperan. Nextflow intentará ejecutar el pipeline, pero podría encontrar que el número de entradas no coincide con lo que espera y fallar. Estos errores típicamente solo aparecen en tiempo de ejecución y requieren una comprensión de los datos que fluyen a través de su flujo de trabajo. + +!!! tip "Depuración de Canales con `.view()`" + + A lo largo de esta sección, recuerde que puede usar el operador `.view()` para inspeccionar el contenido del canal en cualquier punto de su flujo de trabajo. Esta es una de las herramientas de depuración más poderosas para entender problemas de estructura de canal. Exploraremos esta técnica en detalle en la sección 2.4, pero siéntase libre de usarla mientras trabaja en los ejemplos. + + ```groovy + my_channel.view() // Muestra lo que está fluyendo a través del canal + ``` + +### 2.1. Número Incorrecto de Canales de Entrada + +Este error ocurre cuando pasa un número diferente de canales del que un proceso espera. + +#### Ejecutar el pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verificar el código + +El mensaje de error indica claramente que la llamada esperaba 1 argumento pero recibió 2, y apunta a la línea 23. Examinemos `bad_number_inputs.nf`: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // El proceso espera solo 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Crear dos canales separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Pasando 2 canales pero el proceso espera solo 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Debería ver la llamada desemparejada `PROCESS_FILES`, suministrando múltiples canales de entrada cuando el proceso solo define uno. La extensión de VSCode también subrayará la llamada al proceso en rojo y suministrará un mensaje de diagnóstico cuando pase el mouse: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Corregir el código + +Para este ejemplo específico, el proceso espera un solo canal y no requiere el segundo canal, por lo que podemos corregirlo pasando solo el canal `samples_ch`: + +=== "Después" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // El proceso espera solo 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crear dos canales separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Corregido: Pasar solo el canal que el proceso espera + PROCESS_FILES(samples_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // El proceso espera solo 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crear dos canales separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Pasando 2 canales pero el proceso espera solo 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Ejecutar el pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Más comúnmente que este ejemplo, podría agregar entradas adicionales a un proceso y olvidar actualizar la llamada del workflow en consecuencia, lo que puede conducir a este tipo de error. Afortunadamente, este es uno de los errores más fáciles de entender y corregir, ya que el mensaje de error es bastante claro sobre el desajuste. + +### 2.2. Agotamiento de Canal (El Proceso se Ejecuta Menos Veces de lo Esperado) + +Algunos errores de estructura de canal son mucho más sutiles y no producen errores en absoluto. Probablemente el más común de estos refleja un desafío que los nuevos usuarios de Nextflow enfrentan al entender que los canales de cola pueden agotarse y quedarse sin elementos, lo que significa que el flujo de trabajo termina prematuramente. + +#### Ejecutar el pipeline + +```bash +nextflow run exhausted.nf +``` + +??? success "Salida del comando" + +```console title="Salida de canal agotado" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +¡Este flujo de trabajo se completa sin errores, pero solo procesa una sola muestra! + +#### Verificar el código + +Examinemos `exhausted.nf` para ver si eso es correcto: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Definir variables en código Groovy antes del script + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +El proceso solo se ejecuta una vez en lugar de tres veces porque el canal `reference_ch` es un canal de cola que se agota después de la primera ejecución del proceso. Cuando un canal se agota, todo el proceso se detiene, incluso si otros canales todavía tienen elementos. + +Este es un patrón común donde tiene un archivo de referencia único que necesita ser reutilizado en múltiples muestras. La solución es convertir el canal de referencia en un canal de valor que puede ser reutilizado indefinidamente. + +#### Corregir el código + +Hay un par de formas de abordar esto dependiendo de cuántos archivos están afectados. + +**Opción 1**: Tiene un solo archivo de referencia que está reutilizando mucho. Puede simplemente crear un tipo de canal de valor, que puede usarse una y otra vez. Hay tres formas de hacer esto: + +**1a** Usar `channel.value()`: + +```groovy title="exhausted.nf (corregido - Opción 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // El canal de valor puede ser reutilizado + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Usar el [operador](https://www.nextflow.io/docs/latest/reference/operator.html#first) `first()`: + +```groovy title="exhausted.nf (corregido - Opción 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Convertir a canal de valor + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Usar el [operador](https://www.nextflow.io/docs/latest/reference/operator.html#collect) `collect()`: + +```groovy title="exhausted.nf (corregido - Opción 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Convertir a canal de valor + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Opción 2**: En escenarios más complejos, quizás donde tiene múltiples archivos de referencia para todas las muestras en el canal de muestras, puede usar el operador `combine` para crear un nuevo canal que combine los dos canales en tuplas: + +```groovy title="exhausted.nf (corregido - Opción 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Crea producto cartesiano + + PROCESS_FILES(combined_ch) +} +``` + +El operador `.combine()` genera un producto cartesiano de los dos canales, por lo que cada elemento en `reference_ch` se emparejará con cada elemento en `input_ch`. Esto permite que el proceso se ejecute para cada muestra mientras sigue usando la referencia. + +Esto requiere que la entrada del proceso sea ajustada. En nuestro ejemplo, el inicio de la definición del proceso necesitaría ser ajustado de la siguiente manera: + +```groovy title="exhausted.nf (corregido - Opción 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Este enfoque puede no ser adecuado en todas las situaciones. + +#### Ejecutar el pipeline + +Pruebe una de las correcciones anteriores y ejecute el flujo de trabajo nuevamente: + +```bash +nextflow run exhausted.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Ahora debería ver las tres muestras siendo procesadas en lugar de solo una. + +### 2.3. Estructura de Contenido de Canal Incorrecta + +Cuando los flujos de trabajo alcanzan un cierto nivel de complejidad, puede ser un poco difícil hacer un seguimiento de las estructuras internas de cada canal, y las personas comúnmente generan desajustes entre lo que el proceso espera y lo que el canal realmente contiene. Esto es más sutil que el problema que discutimos anteriormente, donde el número de canales era incorrecto. En este caso, puede tener el número correcto de canales de entrada, pero la estructura interna de uno o más de esos canales no coincide con lo que el proceso espera. + +#### Ejecutar el pipeline + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Salida del comando" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Verificar el código + +Los corchetes en el mensaje de error proporcionan la pista aquí - el proceso está tratando la tupla como un solo valor, lo cual no es lo que queremos. Examinemos `bad_channel_shape.nf`: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Espera un solo valor, obtiene una tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Puede ver que estamos generando un canal compuesto de tuplas: `['sample1', 'file1.txt']`, pero el proceso espera un solo valor, `val sample_name`. El comando ejecutado muestra que el proceso está intentando crear un archivo llamado `[sample3, file3.txt]_output.txt`, que no es la salida prevista. + +#### Corregir el código + +Para corregir esto, si el proceso requiere ambas entradas podríamos ajustar el proceso para aceptar una tupla: + +=== "Opción 1: Aceptar tupla en el proceso" + + === "Después" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Corregido: Aceptar tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Antes" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Espera un solo valor, obtiene una tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Opción 2: Extraer primer elemento" + + === "Después" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Corregido: Extraer primer elemento + } + ``` + + === "Antes" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Ejecutar el pipeline + +Elija una de las soluciones y vuelva a ejecutar el flujo de trabajo: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Técnicas de Depuración de Canales + +#### Uso de `.view()` para Inspección de Canales + +La herramienta de depuración más poderosa para canales es el operador `.view()`. Con `.view()`, puede entender la forma de sus canales en todas las etapas para ayudar con la depuración. + +#### Ejecutar el pipeline + +Ejecute `bad_channel_shape_viewed.nf` para ver esto en acción: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Verificar el código + +Examinemos `bad_channel_shape_viewed.nf` para ver cómo se usa `.view()`: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debug: Mostrar contenido original del canal + .map { tuple -> tuple[0] } // Transform: Extraer primer elemento + .view { "After mapping: $it" } // Debug: Mostrar contenido transformado del canal + + PROCESS_FILES(input_ch) +} +``` + +#### Corregir el código + +Para evitar usar operaciones `.view()` excesivamente en el futuro para entender el contenido del canal, es aconsejable agregar algunos comentarios para ayudar: + +```groovy title="bad_channel_shape_viewed.nf (con comentarios)" linenums="16" hl_lines="8 9" +workflow { + + // El canal emite tuplas, pero el proceso espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Esto se volverá más importante a medida que sus flujos de trabajo crezcan en complejidad y la estructura del canal se vuelva más opaca. + +#### Ejecutar el pipeline + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Conclusión + +Muchos errores de estructura de canal pueden crearse con sintaxis de Nextflow válida. Puede depurar errores de estructura de canal entendiendo el flujo de datos, usando operadores `.view()` para inspección y reconociendo patrones de mensajes de error como corchetes que indican estructuras de tupla inesperadas. + +### ¿Qué sigue? + +Aprenda sobre errores creados por definiciones de procesos. + +--- + +## 3. Errores de Estructura de Proceso + +La mayoría de los errores que encuentre relacionados con procesos estarán relacionados con errores que ha cometido al formar el comando, o con problemas relacionados con el software subyacente. Dicho esto, de manera similar a los problemas de canal anteriores, puede cometer errores en la definición del proceso que no califican como errores de sintaxis, pero que causarán errores en tiempo de ejecución. + +### 3.1. Archivos de Salida Faltantes + +Un error común al escribir procesos es hacer algo que genera un desajuste entre lo que el proceso espera y lo que se genera. + +#### Ejecutar el pipeline + +```bash +nextflow run missing_output.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Verificar el código + +El mensaje de error indica que el proceso esperaba producir un archivo de salida llamado `sample3.txt`, pero el script realmente crea `sample3_output.txt`. Examinemos la definición del proceso en `missing_output.nf`: + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Espera: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Crea: sample3_output.txt + """ +} +``` + +Debería ver que hay un desajuste entre el nombre del archivo de salida en el bloque `output:`, y el utilizado en el script. Este desajuste hace que el proceso falle. Si encuentra este tipo de error, revise que las salidas coincidan entre su definición de proceso y su bloque de salida. + +Si el problema aún no está claro, verifique el directorio de trabajo mismo para identificar los archivos de salida reales creados: + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Para este ejemplo, esto nos resaltaría que se está incorporando un sufijo `_output` en el nombre del archivo de salida, contrario a nuestra definición `output:`. + +#### Corregir el código + +Corrija el desajuste haciendo que el nombre del archivo de salida sea consistente: + +=== "Después" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Corregido: Coincidir con la salida del script + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Antes" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Espera: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Crea: sample3_output.txt + """ + } + ``` + +#### Ejecutar el pipeline + +```bash +nextflow run missing_output.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [elated_hamilton] DSL2 - revision: 961938ee2b + + executor > local (3) + [16/1c437c] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +### 3.2. Software faltante + +Otra clase de errores ocurre debido a errores en el aprovisionamiento de software. `missing_software.nf` es un flujo de trabajo sintácticamente válido, pero depende de algún software externo para proporcionar el comando `cowpy` que utiliza. + +#### Ejecutar el pipeline + +```bash +nextflow run missing_software.nf +``` + +??? failure "Salida del comando" + + ```console hl_lines="12 18" + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Process `PROCESS_FILES (3)` terminated with an error exit status (127) + + + Command executed: + + cowpy sample3 > sample3_output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/side-quests/debugging/work/82/42a5bfb60c9c6ee63ebdbc2d51aa6e + + Tip: you can try to figure out what's wrong by changing to the process work directory and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +El proceso no tiene acceso al comando que estamos especificando. A veces esto es porque un script está presente en el directorio `bin` del flujo de trabajo, pero no se ha hecho ejecutable. Otras veces es porque el software no está instalado en el contenedor o entorno donde se está ejecutando el flujo de trabajo. + +#### Verificar el código + +Esté atento a ese código de salida `127` - le dice exactamente el problema. Examinemos `missing_software.nf`: + +```groovy title="missing_software.nf" linenums="3" hl_lines="3" +process PROCESS_FILES { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + cowpy ${sample_name} > ${sample_name}_output.txt + """ +} +``` + +#### Corregir el código + +Hemos sido un poco engañosos aquí, y en realidad no hay nada malo con el código. Solo necesitamos especificar la configuración necesaria para ejecutar el proceso de tal manera que tenga acceso al comando en cuestión. En este caso, el proceso tiene una definición de contenedor, por lo que todo lo que necesitamos hacer es ejecutar el flujo de trabajo con Docker habilitado. + +#### Ejecutar el pipeline + +Hemos configurado un perfil de Docker para usted en `nextflow.config`, por lo que puede ejecutar el flujo de trabajo con: + +```bash +nextflow run missing_software.nf -profile docker +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_software.nf` [awesome_stonebraker] DSL2 - revision: 0296d12839 + + executor > local (3) + [38/ab20d1] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +!!! note + + Para aprender más sobre cómo Nextflow usa contenedores, vea [Hello Nextflow](../hello_nextflow/05_hello_containers.md) + +### 3.3. Mala configuración de recursos + +En uso de producción, estará configurando recursos en sus procesos. Por ejemplo, `memory` define la cantidad máxima de memoria disponible para su proceso, y si el proceso excede eso, su planificador típicamente matará el proceso y devolverá un código de salida de `137`. No podemos demostrar eso aquí porque estamos usando el executor `local`, pero podemos mostrar diff --git a/docs/es/docs/side_quests/dev_environment.md b/docs/es/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..a6cdb97db0 --- /dev/null +++ b/docs/es/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Entorno de Desarrollo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Los Entornos de Desarrollo Integrados (IDEs) modernos pueden transformar dramáticamente su experiencia de desarrollo con Nextflow. Esta misión secundaria se enfoca específicamente en aprovechar VS Code y su extensión de Nextflow para escribir código más rápido, detectar errores temprano y navegar workflows complejos de manera eficiente. + +!!! note "Este no es un tutorial tradicional" + + A diferencia de otros módulos de entrenamiento, esta guía está organizada como una colección de sugerencias rápidas, consejos y ejemplos prácticos en lugar de un tutorial paso a paso. Cada sección puede explorarse de forma independiente según sus intereses y necesidades actuales de desarrollo. Siéntase libre de moverse entre secciones y enfocarse en las características que serán más útiles inmediatamente para el desarrollo de su workflow. + +## Qué debería saber primero + +Esta guía asume que ha completado el curso de entrenamiento [Hello Nextflow](../hello_nextflow/) y se siente cómodo con conceptos fundamentales de Nextflow incluyendo: + +- **Estructura básica de workflow**: Comprensión de procesos, workflows y cómo se conectan entre sí +- **Operaciones de canal**: Creación de canales, paso de datos entre procesos y uso de operadores básicos +- **Módulos y organización**: Creación de módulos reutilizables y uso de declaraciones include +- **Conceptos básicos de configuración**: Uso de `nextflow.config` para parámetros, directivas de proceso y perfiles + +## Qué aprenderá aquí + +Esta guía se enfoca en **características de productividad del IDE** que lo convertirán en un desarrollador de Nextflow más eficiente: + +- **Resaltado de sintaxis avanzado**: Comprender qué está mostrando VS Code sobre la estructura de su código +- **Auto-completado inteligente**: Aprovechar sugerencias contextuales para escribir código más rápido +- **Detección de errores y diagnósticos**: Detectar errores de sintaxis antes de ejecutar su workflow +- **Navegación de código**: Moverse rápidamente entre procesos, módulos y definiciones +- **Formato y organización**: Mantener un estilo de código consistente y legible +- **Desarrollo asistido por IA** (opcional): Usar herramientas de IA modernas integradas con su IDE + +!!! info "¿Por qué características del IDE ahora?" + + Es probable que ya haya estado usando VS Code durante el curso [Hello Nextflow](../hello_nextflow/), pero mantuvimos el enfoque en aprender los fundamentos de Nextflow en lugar de características del IDE. Ahora que se siente cómodo con conceptos básicos de Nextflow como procesos, workflows, canales y módulos, está listo para aprovechar las características sofisticadas del IDE que lo harán un desarrollador más eficiente. + + Piense en esto como "subir de nivel" su entorno de desarrollo - el mismo editor que ha estado usando tiene capacidades mucho más poderosas que se vuelven verdaderamente valiosas una vez que comprende en qué lo están ayudando. + +--- + +## 0. Configuración y Preparación + +Configuremos un espacio de trabajo específicamente para explorar características del IDE: + +```bash title="Navegue al directorio de características del IDE" +cd side-quests/ide_features +``` + +Abra este directorio en VS Code: + +```bash title="Abra VS Code en el directorio actual" +code . +``` + +El directorio `ide_features` contiene workflows de ejemplo que demuestran varias características del IDE: + +```bash title="Mostrar estructura del directorio" +tree . +``` + +```console title="Estructura del proyecto" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "Acerca de los Archivos de Ejemplo" + + - `basic_workflow.nf` es un workflow básico funcional que puede ejecutar y modificar + - `complex_workflow.nf` está diseñado solo para ilustración para demostrar características de navegación - puede que no se ejecute exitosamente pero muestra una estructura de workflow multi-archivo realista + +### Atajos de Teclado + +Algunas de las características en esta guía usarán atajos de teclado opcionales. Es muy posible que esté accediendo a este material vía GitHub Codespaces en el navegador, y en este caso a veces los atajos no funcionarán como se espera porque se usan para otras cosas en su sistema. + +Si está ejecutando VS Code localmente, como probablemente lo hará cuando realmente esté escribiendo workflows, los atajos funcionarán como se describe. + +Si está usando Mac, algunos (no todos) atajos de teclado usarán "cmd" en lugar de "ctrl", y lo indicaremos en el texto como `Ctrl/Cmd`. + +### 0.1. Instalación de la Extensión de Nextflow + +!!! note "¿Ya Usa Devcontainers?" + + Si está trabajando en **GitHub Codespaces** o usando un **devcontainer local**, la extensión de Nextflow probablemente ya está instalada y configurada para usted. Puede omitir los pasos de instalación manual a continuación y proceder directamente a explorar las características de la extensión. + +Para instalar la extensión manualmente: + +1. Abra VS Code +2. Vaya a la vista de Extensiones haciendo clic en el ícono de extensiones a la izquierda: ![ícono de extensiones](img/extensions_icon.png) (atajo `Ctrl/Cmd+Shift+X` si está ejecutando VS Code localmente) +3. Busque "Nextflow" +4. Instale la extensión oficial de Nextflow + +![Instalar Extensión de Nextflow](img/install_extension.png) + +### 0.2. Diseño del Espacio de Trabajo + +Dado que ha estado usando VS Code durante Hello Nextflow, ya está familiarizado con lo básico. Aquí está cómo organizar su espacio de trabajo eficientemente para esta sesión: + +- **Área del Editor**: Para ver y editar archivos. Puede dividir esto en múltiples paneles para comparar archivos lado a lado. +- **Explorador de Archivos** haga clic (![ícono del explorador de archivos](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): Los archivos y carpetas locales en su sistema. Mantenga esto abierto a la izquierda para navegar entre archivos +- **Terminal Integrada** (`Ctrl+Shift+` backtick tanto para Windows como MacOS): Una terminal para interactuar con la computadora en la parte inferior. Use esto para ejecutar Nextflow u otros comandos. +- **Panel de Problemas** (`Ctrl+Shift+M`): VS Code mostrará cualquier error y problema que detecte aquí. Esto es útil para resaltar problemas de un vistazo. + +Puede arrastrar paneles o ocultarlos (`Ctrl/Cmd+B` para alternar la barra lateral) para personalizar su diseño mientras trabajamos con los ejemplos. + +### Conclusión + +Tiene VS Code configurado con la extensión de Nextflow y comprende el diseño del espacio de trabajo para desarrollo eficiente. + +### ¿Qué sigue? + +Aprenda cómo el resaltado de sintaxis le ayuda a comprender la estructura del código Nextflow de un vistazo. + +--- + +## 1. Resaltado de Sintaxis y Estructura del Código + +Ahora que su espacio de trabajo está configurado, exploremos cómo el resaltado de sintaxis de VS Code le ayuda a leer y escribir código Nextflow más efectivamente. + +### 1.1. Elementos de Sintaxis de Nextflow + +Abra `basic_workflow.nf` para ver el resaltado de sintaxis en acción: + +![Demostración de Sintaxis](img/syntax_showcase.png) + +Note cómo VS Code resalta: + +- **Palabras clave** (`process`, `workflow`, `input`, `output`, `script`) en colores distintos +- **Literales de cadena** y **parámetros** con estilo diferente +- **Comentarios** en un color atenuado +- **Variables** y **llamadas a funciones** con énfasis apropiado +- **Bloques de código** con guías de indentación apropiadas + +!!! note "Colores Dependientes del Tema" + + Los colores específicos que vea dependerán de su tema de VS Code (modo oscuro/claro), configuración de colores y cualquier personalización que haya hecho. Lo importante es que diferentes elementos de sintaxis se distingan visualmente entre sí, haciendo la estructura del código más fácil de entender independientemente de su esquema de color elegido. + +### 1.2. Comprensión de la Estructura del Código + +El resaltado de sintaxis le ayuda a identificar rápidamente: + +- **Límites de proceso**: Distinción clara entre diferentes procesos +- **Bloques de entrada/salida**: Fácil de identificar definiciones de flujo de datos +- **Bloques de script**: Los comandos reales que se están ejecutando +- **Operaciones de canal**: Pasos de transformación de datos +- **Directivas de configuración**: Configuraciones específicas del proceso + +Esta organización visual se vuelve invaluable cuando se trabaja con workflows complejos que contienen múltiples procesos y flujos de datos intrincados. + +### Conclusión + +Comprende cómo el resaltado de sintaxis de VS Code le ayuda a leer la estructura del código Nextflow e identificar diferentes elementos del lenguaje para un desarrollo más rápido. + +### ¿Qué sigue? + +Aprenda cómo el auto-completado inteligente acelera la escritura de código con sugerencias contextuales. + +--- + +## 2. Auto-completado Inteligente + +Las características de auto-completado de VS Code le ayudan a escribir código más rápido y con menos errores sugiriendo opciones apropiadas según el contexto. + +### 2.1. Sugerencias Contextuales + +Las opciones de auto-completado varían dependiendo de dónde esté en su código: + +#### Operaciones de Canal + +Abra `basic_workflow.nf` nuevamente e intente escribir `channel.` en el bloque workflow: + +![Auto-completado de canal](img/autocomplete_channel.png) + +Verá sugerencias para: + +- `fromPath()` - Crear canal desde rutas de archivo +- `fromFilePairs()` - Crear canal desde archivos emparejados +- `of()` - Crear canal desde valores +- `fromSRA()` - Crear canal desde accesos SRA +- Y muchos más... + +Esto le ayuda a encontrar rápidamente la fábrica de canal correcta sin necesidad de recordar nombres exactos de métodos. + +También puede descubrir los operadores disponibles para aplicar a canales. Por ejemplo, escriba `FASTQC.out.html.` para ver operaciones disponibles: + +![Auto-completado de operaciones de canal](img/autocomplete_operators.png) + +#### Directivas de Proceso + +Dentro de un bloque script de proceso, escriba `task.` para ver propiedades de tiempo de ejecución disponibles: + +![Auto-completado de propiedades de tarea](img/autocomplete_task.png) + +#### Configuración + +Abra nextflow.config y escriba `process.` en cualquier lugar para ver directivas de proceso disponibles: + +![Auto-completado de configuración](img/autocomplete_config.png) + +Verá sugerencias para: + +- `executor` +- `memory` +- `cpus` + +Esto ahorra tiempo al configurar procesos y funciona a través de diferentes ámbitos de configuración. Por ejemplo, intente escribir `docker.` para ver opciones de configuración específicas de Docker. + +### Conclusión + +Puede usar el auto-completado inteligente de VS Code para descubrir operaciones de canal disponibles, directivas de proceso y opciones de configuración sin memorizar la sintaxis. + +### ¿Qué sigue? + +Aprenda cómo la detección de errores en tiempo real le ayuda a detectar problemas antes de ejecutar su workflow, simplemente leyendo el código. + +## 3. Detección de Errores y Diagnósticos + +La detección de errores en tiempo real de VS Code le ayuda a detectar problemas antes de ejecutar su workflow. + +### 3.1. Detección de Errores de Sintaxis + +Creemos un error deliberado para ver la detección en acción. Abra `basic_workflow.nf` y cambie el nombre del proceso de `FASTQC` a `FASTQ` (o cualquier otro nombre inválido). VS Code inmediatamente resaltará el error en el bloque workflow con un subrayado ondulado rojo: + +![Subrayado de error](img/error_underline.png) + +### 3.2. Panel de Problemas + +Más allá del resaltado de errores individuales, VS Code proporciona un panel de Problemas centralizado que agrega todos los errores, advertencias y mensajes de información en su espacio de trabajo. Ábralo con `Ctrl/Cmd+Shift+M` y use el ícono de filtro para mostrar solo errores relevantes al archivo actual: + +![Filtrar el panel de problemas](img/active_file.png) + +Haga clic en cualquier problema para saltar directamente a la línea problemática + +![Panel de Problemas](img/problems_panel.png) + +Corrija el error cambiando el nombre del proceso de vuelta a `FASTQC`. + +### 3.3. Patrones Comunes de Error + +Los errores comunes en la sintaxis de Nextflow incluyen: + +- **Corchetes faltantes**: `{` o `}` sin coincidencia +- **Bloques incompletos**: Secciones requeridas faltantes en procesos +- **Sintaxis inválida**: DSL de Nextflow mal formado +- **Errores tipográficos en palabras clave**: Directivas de proceso mal escritas +- **Desajustes de canal**: Incompatibilidades de tipo + +El servidor de lenguaje de Nextflow resalta estos problemas en el panel de Problemas. Puede revisar estos temprano para evitar errores de sintaxis al ejecutar un pipeline. + +### Conclusión + +Puede usar la detección de errores de VS Code y el panel de Problemas para detectar errores de sintaxis y problemas antes de ejecutar su workflow, ahorrando tiempo y previniendo frustraciones. + +### ¿Qué sigue? + +Aprenda cómo navegar eficientemente entre procesos, módulos y definiciones en workflows complejos. + +--- + +## 4. Navegación de Código y Gestión de Símbolos + +La navegación eficiente es crucial cuando se trabaja con workflows complejos que abarcan múltiples archivos. Para entender esto, reemplace la definición del proceso en `basic_workflow.nf` con una importación para el módulo que le hemos proporcionado: + +=== "Después" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Antes" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Ir a Definición + +Si pasa el mouse sobre un nombre de proceso como `FASTQC`, verá una ventana emergente con la interfaz del módulo (entradas y salidas): + +![Ir a definición](img/syntax.png) + +Esta característica es particularmente valiosa cuando se crean workflows, ya que le permite comprender la interfaz del módulo sin abrir el archivo del módulo directamente. + +Puede navegar rápidamente a cualquier definición de proceso, módulo o variable usando **Ctrl/Cmd-clic**. Pase el mouse sobre el enlace al archivo del módulo en la parte superior del script y siga el enlace como se sugiere: + +![Seguir enlace](img/follow_link.png) + +Lo mismo funciona para nombres de proceso. Regrese a `basic_workflow.nf` e intente esto en el nombre del proceso `FASTQC` en el bloque workflow. Esto lo enlaza directamente al nombre del proceso (que es el mismo que el archivo del módulo en este ejemplo, pero podría estar a mitad de camino en un archivo mucho más grande). + +Para regresar a donde estaba, use **Alt+←** (o **Ctrl+-** en Mac). Esta es una forma poderosa de explorar código sin perder su lugar. + +Ahora exploremos la navegación en un workflow más complejo usando `complex_workflow.nf` (el archivo solo para ilustración mencionado anteriormente). Este workflow contiene múltiples procesos definidos en archivos de módulos separados, así como algunos en línea. Aunque las estructuras complejas multi-archivo pueden ser desafiantes de navegar manualmente, la capacidad de saltar a definiciones hace la exploración mucho más manejable. + +1. Abra `complex_workflow.nf` +2. Navegue a definiciones de módulos +3. Use **Alt+←** (o **Ctrl+-**) para navegar hacia atrás +4. Navegue al nombre del proceso `FASTQC` en el bloque workflow. Esto lo enlaza directamente al nombre del proceso (que es el mismo que el archivo del módulo en este ejemplo, pero podría estar a mitad de camino en un archivo mucho más grande). +5. Navegue hacia atrás nuevamente +6. Navegue al proceso `TRIM_GALORE` en el bloque workflow. Este está definido en línea, así que no lo llevará a un archivo separado, pero aún le mostrará la definición del proceso, y aún puede navegar de regreso a donde estaba. + +### 4.2. Navegación de Símbolos + +Con `complex_workflow.nf` aún abierto, puede obtener una visión general de todos los símbolos en el archivo escribiendo `@` en la barra de búsqueda en la parte superior de VS Code (el atajo de teclado es `Ctrl/Cmd+Shift+O`, pero puede no funcionar en Codespaces). Esto abre el panel de navegación de símbolos, que lista todos los símbolos en el archivo actual: + +![Navegación de símbolos](img/symbols.png) + +Esto muestra: + +- Todas las definiciones de proceso +- Definiciones de workflow (hay dos workflows definidos en este archivo) +- Definiciones de función + +Comience a escribir para filtrar resultados. + +### 4.3. Encontrar Todas las Referencias + +Comprender dónde se usa un proceso o variable en toda su base de código puede ser muy útil. Por ejemplo, si desea encontrar todas las referencias al proceso `FASTQC`, comience navegando a su definición. Puede hacer esto abriendo `modules/fastqc.nf` directamente, o usando la característica de navegación rápida de VS Code con `Ctrl/Cmd-clic` como hicimos arriba. Una vez en la definición del proceso, haga clic derecho en el nombre del proceso `FASTQC` y seleccione "Find All References" del menú contextual para ver todas las instancias donde se usa. + +![Encontrar referencias](img/references.png) + +Esta característica muestra todas las instancias donde se hace referencia a `FASTQC` dentro de su espacio de trabajo, incluyendo su uso en los dos workflows distintos. Esta visión es crucial para evaluar el impacto potencial de modificaciones al proceso `FASTQC`. + +### 4.4. Panel de Esquema + +El panel de Esquema, ubicado en la barra lateral del Explorador (haga clic en ![ícono del Explorador](img/files_icon.png)), proporciona una visión general conveniente de todos los símbolos en su archivo actual. Esta característica le permite navegar y gestionar rápidamente la estructura de su código mostrando funciones, variables y otros elementos clave en una vista jerárquica. + +![Panel de esquema](img/outline.png) + +Use el panel de Esquema para navegar rápidamente a diferentes partes de su código sin usar el navegador de archivos. + +### 4.5. Visualización DAG + +La extensión de Nextflow de VS Code puede visualizar su workflow como un Grafo Acíclico Dirigido (DAG). Esto le ayuda a comprender el flujo de datos y las dependencias entre procesos. Abra `complex_workflow.nf` y haga clic en el botón "Preview DAG" arriba de `workflow {` (el segundo bloque `workflow` en este archivo): + +![Vista previa DAG](img/dag_preview.png) + +Este es solo el workflow de 'entrada', pero también puede previsualizar el DAG para los workflows internos haciendo clic en el botón "Preview DAG" arriba del workflow `RNASEQ_PIPELINE {` más arriba: + +![Vista previa DAG workflow interno](img/dag_preview_inner.png) + +Para este workflow, puede usar los nodos en el DAG para navegar a las definiciones de proceso correspondientes en el código. Haga clic en un nodo y lo llevará a la definición de proceso relevante en el editor. Particularmente cuando un workflow crece a un tamaño grande, esto puede realmente ayudarlo a navegar por el código y comprender cómo los procesos están conectados. + +### Conclusión + +Puede navegar workflows complejos eficientemente usando ir a definición, búsqueda de símbolos, encontrar referencias y visualización DAG para comprender la estructura del código y las dependencias. + +### ¿Qué sigue? + +Aprenda cómo trabajar efectivamente a través de múltiples archivos interconectados en proyectos Nextflow más grandes. + +## 5. Trabajo a Través de Múltiples Archivos + +El desarrollo real de Nextflow implica trabajar con múltiples archivos interconectados. Exploremos cómo VS Code le ayuda a gestionar proyectos complejos eficientemente. + +### 5.1. Navegación Rápida de Archivos + +Con `complex_workflow.nf` abierto, notará que importa varios módulos. Practiquemos la navegación rápida entre ellos. + +Presione **Ctrl+P** (o **Cmd+P**) y comience a escribir "fast": + +VS Code le mostrará archivos coincidentes. Seleccione `modules/fastqc.nf` para saltar allí instantáneamente. Esto es mucho más rápido que hacer clic a través del explorador de archivos cuando sabe aproximadamente qué archivo está buscando. + +Intente esto con otros patrones: + +- Escriba "star" para encontrar el archivo del módulo de alineamiento STAR (`star.nf`) +- Escriba "utils" para encontrar el archivo de funciones de utilidad (`utils.nf`) +- Escriba "config" para saltar a archivos de configuración (`nextflow.config`) + +### 5.2. Editor Dividido para Desarrollo Multi-archivo + +Cuando trabaja con módulos, a menudo necesita ver tanto el workflow principal como las definiciones de módulos simultáneamente. Configuremos esto: + +1. Abra `complex_workflow.nf` +2. Abra `modules/fastqc.nf` en una nueva pestaña +3. Haga clic derecho en la pestaña `modules/fastqc.nf` y seleccione "Split Right" +4. Ahora puede ver ambos archivos lado a lado + +![Editor dividido](img/split_editor.png) + +Esto es invaluable cuando: + +- Verifica interfaces de módulos mientras escribe llamadas de workflow, y la vista previa no es suficiente +- Compara procesos similares a través de diferentes módulos +- Depura flujo de datos entre workflow y módulos + +### 5.3. Búsqueda en Todo el Proyecto + +A veces necesita encontrar dónde se usan patrones específicos en todo su proyecto. Presione `Ctrl/Cmd+Shift+F` para abrir el panel de búsqueda. + +Intente buscar `publishDir` en todo el espacio de trabajo: + +![Búsqueda de proyecto](img/project_search.png) + +Esto le muestra cada archivo que usa directorios de publicación, ayudándolo a: + +- Comprender patrones de organización de salida +- Encontrar ejemplos de directivas específicas +- Asegurar consistencia a través de módulos + +### Conclusión + +Puede gestionar proyectos complejos multi-archivo usando navegación rápida de archivos, editores divididos y búsqueda en todo el proyecto para trabajar eficientemente a través de workflows y módulos. + +### ¿Qué sigue? + +Aprenda cómo las características de formato de código y mantenimiento mantienen sus workflows organizados y legibles. + +--- + +## 6. Formato de Código y Mantenimiento + +El formato apropiado del código es esencial no solo para la estética sino también para mejorar la legibilidad, comprensión y la facilidad de actualizar workflows complejos. + +### 6.1. Formato Automático en Acción + +Abra `basic_workflow.nf` y desordene deliberadamente el formato: + +- Elimine algo de indentación: Resalte todo el documento y presione `shift+tab` muchas veces para eliminar tantas indentaciones como sea posible. +- Agregue espacios extra en lugares aleatorios: en la declaración `channel.fromPath`, agregue 30 espacios después del `(`. +- Rompa algunas líneas de manera incómoda: Agregue una nueva línea entre el operador `.view {` y la cadena `Processing sample:` pero no agregue una nueva línea correspondiente antes del paréntesis de cierre `}`. + +Ahora presione `Shift+Alt+F` (o `Shift+Option+F` en MacOS) para auto-formatear: + +VS Code inmediatamente: + +- Corrige la indentación para mostrar la estructura del proceso claramente +- Alinea elementos similares consistentemente +- Elimina espacios en blanco innecesarios +- Mantiene saltos de línea legibles + +Note que el formato automático puede no resolver todos los problemas de estilo de código. El servidor de lenguaje de Nextflow intenta mantener su código ordenado, pero también respeta sus preferencias personales en ciertas áreas. Por ejemplo, si elimina indentación dentro del bloque `script` de un proceso, el formateador lo dejará como está, ya que podría preferir intencionalmente ese estilo. + +Actualmente, no hay una aplicación de estilo estricta para Nextflow, así que el servidor de lenguaje ofrece cierta flexibilidad. Sin embargo, aplicará consistentemente reglas de formato alrededor de definiciones de métodos y funciones para mantener claridad. + +### 6.2. Características de Organización de Código + +#### Comentar Rápidamente + +Seleccione un bloque de código en su workflow y presione **Ctrl+/** (o **Cmd+/**) para comentarlo: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +Esto es perfecto para: + +- Deshabilitar temporalmente partes de workflows durante el desarrollo +- Agregar comentarios explicativos a operaciones de canal complejas +- Documentar secciones de workflow + +Use **Ctrl+/** (o **Cmd+/**) nuevamente para descomentar el código. + +#### Plegado de Código para Visión General + +En `complex_workflow.nf`, note las pequeñas flechas junto a las definiciones de proceso. Haga clic en ellas para plegar (colapsar) procesos: + +![Plegado de código](img/code_folding.png) + +Esto le da una visión general de alto nivel de su estructura de workflow sin perderse en detalles de implementación. + +#### Coincidencia de Corchetes + +Coloque su cursor junto a cualquier corchete `{` o `}` y VS Code resalta el corchete coincidente. Use **Ctrl+Shift+\\** (o **Cmd+Shift+\\**) para saltar entre corchetes coincidentes. + +Esto es crucial para: + +- Comprender límites de proceso +- Encontrar corchetes faltantes o extra +- Navegar estructuras de workflow anidadas + +#### Selección y Edición Multi-línea + +Para editar múltiples líneas simultáneamente, VS Code ofrece capacidades poderosas de multi-cursor: + +- **Selección multi-línea**: Mantenga **Ctrl+Alt** (o **Cmd+Option** para MacOS) y use las teclas de flecha para seleccionar múltiples líneas +- **Indentación multi-línea**: Seleccione múltiples líneas y use **Tab** para indentar o **Shift+Tab** para des-indentar bloques completos + +Esto es particularmente útil para: + +- Indentar bloques de proceso completos consistentemente +- Agregar comentarios a múltiples líneas a la vez +- Editar definiciones de parámetros similares a través de múltiples procesos + +### Conclusión + +Puede mantener código limpio y legible usando formato automático, características de comentarios, plegado de código, coincidencia de corchetes y edición multi-línea para organizar workflows complejos eficientemente. + +### ¿Qué sigue? + +Aprenda cómo VS Code se integra con su flujo de trabajo de desarrollo más amplio más allá de solo editar código. + +--- + +## 7. Integración del Flujo de Trabajo de Desarrollo + +VS Code se integra bien con su flujo de trabajo de desarrollo más allá de solo editar código. + +### 7.1. Integración de Control de Versiones + +!!! note "Codespaces e Integración Git" + + Si está trabajando en **GitHub Codespaces**, algunas características de integración Git pueden no funcionar como se espera, particularmente atajos de teclado para Control de Fuente. También pudo haber declinado abrir el directorio como un repositorio Git durante la configuración inicial, lo cual está bien para propósitos de entrenamiento. + +Si su proyecto es un repositorio git (como este lo es), VS Code muestra: + +- Archivos modificados con indicadores de color +- Estado de Git en la barra de estado +- Vistas de diferencias en línea +- Capacidades de commit y push + +Abra el panel de Control de Fuente usando el botón de control de fuente (![ícono de Control de fuente](img/source_control_icon.png)) (`Ctrl+Shift+G` o `Cmd+Shift+G` si está trabajando con VS Code localmente) para ver cambios de git y realizar commits directamente en el editor. + +![Panel de Control de Fuente](img/source_control.png) + +### 7.2. Ejecución e Inspección de Workflows + +Ejecutemos un workflow y luego inspeccionemos los resultados. En la terminal integrada (`Ctrl+Shift+` backtick tanto en Windows como MacOS), ejecute el workflow básico: + +```bash title="Ejecute el workflow básico" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Mientras el workflow se ejecuta, verá salida en tiempo real en la terminal. Después de completarse, puede usar VS Code para inspeccionar resultados sin salir de su editor: + +1. **Navegue a directorios de trabajo**: Use el explorador de archivos o terminal para navegar `.nextflow/work` +2. **Abra archivos de registro**: Haga clic en rutas de archivos de registro en la salida de la terminal para abrirlos directamente en VS Code +3. **Inspeccione salidas**: Navegue por directorios de resultados publicados en el explorador de archivos +4. **Vea reportes de ejecución**: Abra reportes HTML directamente en VS Code o su navegador + +Esto mantiene todo en un solo lugar en lugar de cambiar entre múltiples aplicaciones. + +### Conclusión + +Puede integrar VS Code con control de versiones y ejecución de workflow para gestionar todo su proceso de desarrollo desde una sola interfaz. + +### ¿Qué sigue? + +Vea cómo todas estas características del IDE funcionan juntas en su flujo de trabajo de desarrollo diario. + +--- + +## 8. Resumen y Notas Rápidas + +Aquí hay algunas notas rápidas sobre cada una de las características del IDE discutidas arriba: + +### 8.1. Iniciando una Nueva Característica + +1. **Apertura rápida de archivos** (`Ctrl+P` o `Cmd+P`) para encontrar módulos existentes relevantes +2. **Editor dividido** para ver procesos similares lado a lado +3. **Navegación de símbolos** (`Ctrl+Shift+O` o `Cmd+Shift+O`) para comprender estructura de archivo +4. **Auto-completado** para escribir nuevo código rápidamente + +### 8.2. Depuración de Problemas + +1. **Panel de problemas** (`Ctrl+Shift+M` o `Cmd+Shift+M`) para ver todos los errores a la vez +2. **Ir a definición** (`Ctrl-clic` o `Cmd-clic`) para comprender interfaces de proceso +3. **Encontrar todas las referencias** para ver cómo se usan los procesos +4. **Búsqueda en todo el proyecto** para encontrar patrones o problemas similares + +### 8.3. Refactorización y Mejora + +1. **Búsqueda en todo el proyecto** (`Ctrl+Shift+F` o `Cmd+Shift+F`) para encontrar patrones +2. **Auto-formato** (`Shift+Alt+F` o `Shift+Option+F`) para mantener consistencia +3. **Plegado de código** para enfocarse en estructura +4. **Integración Git** para rastrear cambios + +--- + +## Resumen + +Ahora ha tenido un recorrido rápido de las características del IDE de VS Code para desarrollo de Nextflow. Estas herramientas lo harán significativamente más productivo al: + +- **Reducir errores** a través de verificación de sintaxis en tiempo real +- **Acelerar el desarrollo** con auto-completado inteligente +- **Mejorar la navegación** en workflows complejos multi-archivo +- **Mantener calidad** a través de formato consistente +- **Mejorar la comprensión** a través de resaltado avanzado y visualización de estructura + +No esperamos que recuerde todo, pero ahora que sabe que estas características existen podrá encontrarlas cuando las necesite. A medida que continúe desarrollando workflows de Nextflow, estas características del IDE se volverán una segunda naturaleza, permitiéndole enfocarse en escribir código de alta calidad en lugar de luchar con sintaxis y estructura. + +### ¿Qué sigue? + +Aplique estas habilidades del IDE mientras trabaja en otros módulos de entrenamiento, por ejemplo: + +- **[nf-test](nf-test.md)**: Cree suites de pruebas completas para sus workflows +- **[Hello nf-core](../../hello_nf-core/)**: Construya pipelines de calidad de producción con estándares de la comunidad + +El verdadero poder de estas características del IDE emerge a medida que trabaja en proyectos más grandes y complejos. Comience a incorporarlas en su flujo de trabajo gradualmente—dentro de unas pocas sesiones, se volverán una segunda naturaleza y transformarán cómo aborda el desarrollo de Nextflow. + +Desde detectar errores antes de que lo retrasen hasta navegar bases de código complejas con facilidad, estas herramientas lo harán un desarrollador más confiado y eficiente. + +¡Feliz codificación! diff --git a/docs/es/docs/side_quests/essential_scripting_patterns.md b/docs/es/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..eeaad820f1 --- /dev/null +++ b/docs/es/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1184 @@ +# Patrones Esenciales de Scripting en Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow es un lenguaje de programación que se ejecuta en la Máquina Virtual de Java. Aunque Nextflow está construido sobre [Groovy](http://groovy-lang.org/) y comparte gran parte de su sintaxis, Nextflow es más que solo "Groovy con extensiones" -- es un lenguaje independiente con una [sintaxis](https://nextflow.io/docs/latest/reference/syntax.html) y [biblioteca estándar](https://nextflow.io/docs/latest/reference/stdlib.html) completamente especificadas. + +Se puede escribir mucho código en Nextflow sin aventurarse más allá de la sintaxis básica para variables, mapas y listas. La mayoría de los tutoriales de Nextflow se centran en la orquestación del flujo de trabajo (canales, procesos y flujo de datos), y se puede llegar sorprendentemente lejos con solo eso. + +Sin embargo, cuando se necesita manipular datos, analizar nombres de archivos complejos, implementar lógica condicional o construir flujos de trabajo de producción robustos, ayuda pensar en dos aspectos distintos de tu código: **flujo de datos** (canales, operadores, procesos y workflows) y **scripting** (el código dentro de closures, funciones y scripts de procesos). Aunque esta distinción es algo arbitraria—todo es código Nextflow—proporciona un modelo mental útil para entender cuándo estás orquestando tu pipeline versus cuándo estás manipulando datos. Dominar ambos aspectos mejora drásticamente tu capacidad de escribir flujos de trabajo claros y mantenibles. + +### Objetivos de aprendizaje + +Esta misión secundaria te lleva en un viaje práctico desde conceptos básicos hasta patrones listos para producción. +Transformaremos un flujo de trabajo simple de lectura de CSV en un pipeline de bioinformática sofisticado, evolucionándolo paso a paso a través de desafíos realistas: + +- **Comprender límites:** Distinguir entre operaciones de flujo de datos y scripting, y entender cómo trabajan juntos +- **Manipulación de datos:** Extraer, transformar y hacer subconjuntos de mapas y colecciones usando operadores poderosos +- **Procesamiento de cadenas:** Analizar esquemas complejos de nombres de archivos con patrones regex y dominar la interpolación de variables +- **Funciones reutilizables:** Extraer lógica compleja en funciones nombradas para flujos de trabajo más limpios y mantenibles +- **Lógica dinámica:** Construir procesos que se adapten a diferentes tipos de entrada y usar closures para asignación dinámica de recursos +- **Enrutamiento condicional:** Enrutar muestras inteligentemente a través de diferentes procesos según sus características de metadatos +- **Operaciones seguras:** Manejar datos faltantes con gracia usando operadores seguros ante null y validar entradas con mensajes de error claros +- **Manejadores basados en configuración:** Usar manejadores de eventos de flujo de trabajo para registro, notificaciones y gestión del ciclo de vida + +### Requisitos previos + +Antes de emprender esta misión secundaria, debes: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso equivalente para principiantes. +- Sentirte cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores, trabajo con archivos, metadatos) +- Tener familiaridad básica con construcciones comunes de programación (variables, mapas, listas) + +Este tutorial explicará conceptos de programación a medida que los encontremos, así que no necesitas experiencia extensa en programación. +Comenzaremos con conceptos fundamentales y construiremos hasta patrones avanzados. + +--- + +## 0. Comenzar + +#### Abrir el codespace de entrenamiento + +Si aún no lo has hecho, asegúrate de abrir el entorno de entrenamiento como se describe en la [Configuración del Entorno](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde están ubicados los archivos para este tutorial. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Revisar los materiales + +Encontrarás un archivo de flujo de trabajo principal y un directorio `data` que contiene archivos de datos de ejemplo. + +```console title="Contenido del directorio" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Nuestro CSV de muestra contiene información sobre muestras biológicas que necesitan diferentes procesamientos según sus características: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Usaremos este conjunto de datos realista para explorar técnicas prácticas de programación que encontrarás en flujos de trabajo reales de bioinformática. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### Lista de verificación de preparación + +¿Crees que estás listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente +<!-- - [ ] I understand the assignment --> + +Si puedes marcar todas las casillas, estás listo para continuar. + +--- + +## 1. Flujo de datos vs Scripting: Comprender los límites + +### 1.1. Identificar qué es qué + +Al escribir flujos de trabajo en Nextflow, es importante distinguir entre **flujo de datos** (cómo los datos se mueven a través de canales y procesos) y **scripting** (el código que manipula datos y toma decisiones). Construyamos un flujo de trabajo que demuestre cómo trabajan juntos. + +#### 1.1.1. Flujo de trabajo básico en Nextflow + +Comienza con un flujo de trabajo simple que solo lee el archivo CSV (ya lo hemos hecho por ti en `main.nf`): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +El bloque `workflow` define la estructura de nuestro pipeline, mientras que `channel.fromPath()` crea un canal desde una ruta de archivo. El operador `.splitCsv()` procesa el archivo CSV y convierte cada fila en una estructura de datos de tipo mapa. + +Ejecuta este flujo de trabajo para ver los datos CSV sin procesar: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Agregar el operador map + +Ahora vamos a agregar scripting para transformar los datos, usando el operador `.map()` que probablemente ya conoces. Este operador toma un 'closure' donde podemos escribir código para transformar cada elemento. + +!!! note + + Un **closure** es un bloque de código que puede pasarse y ejecutarse más tarde. Piénsalo como una función que defines en línea. Los closures se escriben con llaves `{ }` y pueden tomar parámetros. ¡Son fundamentales para cómo funcionan los operadores de Nextflow y si has estado escribiendo Nextflow por un tiempo, puede que ya los hayas estado usando sin darte cuenta! + +Así es como se ve esa operación map: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +Este es nuestro primer **closure** - una función anónima que puedes pasar como argumento (similar a lambdas en Python o arrow functions en JavaScript). Los closures son esenciales para trabajar con operadores de Nextflow. + +El closure `{ row -> return row }` toma un parámetro `row` (podría ser cualquier nombre: `item`, `sample`, etc.). + +Cuando el operador `.map()` procesa cada elemento del canal, pasa ese elemento a tu closure. Aquí, `row` contiene una fila del CSV a la vez. + +Aplica este cambio y ejecuta el flujo de trabajo: + +```bash +nextflow run main.nf +``` + +Verás la misma salida que antes, porque simplemente estamos devolviendo la entrada sin cambios. Esto confirma que el operador map está funcionando correctamente. Ahora comencemos a transformar los datos. + +#### 1.1.3. Crear una estructura de datos de tipo mapa + +Ahora vamos a escribir lógica de **scripting** dentro de nuestro closure para transformar cada fila de datos. Aquí es donde procesamos elementos de datos individuales en lugar de orquestar el flujo de datos. + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformación de datos + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +El mapa `sample_meta` es una estructura de datos clave-valor (como diccionarios en Python, objetos en JavaScript, o hashes en Ruby) que almacena información relacionada: ID de muestra, organismo, tipo de tejido, profundidad de secuenciación y puntuación de calidad. + +Usamos métodos de manipulación de cadenas como `.toLowerCase()` y `.replaceAll()` para limpiar nuestros datos, y métodos de conversión de tipo como `.toInteger()` y `.toDouble()` para convertir datos de cadena del CSV en los tipos numéricos apropiados. + +Aplica este cambio y ejecuta el flujo de trabajo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Agregar lógica condicional + +Ahora agreguemos más scripting - esta vez usando un operador ternario para tomar decisiones basadas en valores de datos. + +Realiza el siguiente cambio: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +El operador ternario es una forma abreviada de una declaración if/else que sigue el patrón `condición ? valor_si_verdadero : valor_si_falso`. Esta línea significa: "Si la calidad es mayor que 40, usa 'high', de lo contrario usa 'normal'". Su primo, el **operador Elvis** (`?:`), proporciona valores predeterminados cuando algo es null o está vacío - exploraremos ese patrón más adelante en este tutorial. + +El operador de adición de mapas `+` crea un **nuevo mapa** en lugar de modificar el existente. Esta línea crea un nuevo mapa que contiene todos los pares clave-valor de `sample_meta` más la nueva clave `priority`. + +!!! Note + + Nunca modifiques mapas pasados a closures - siempre crea nuevos usando `+` (por ejemplo). En Nextflow, los mismos datos a menudo fluyen a través de múltiples operaciones simultáneamente. Modificar un mapa in situ puede causar efectos secundarios impredecibles cuando otras operaciones hacen referencia a ese mismo objeto. Crear nuevos mapas asegura que cada operación tenga su propia copia limpia. + +Ejecuta el flujo de trabajo modificado: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Hemos agregado con éxito lógica condicional para enriquecer nuestros metadatos con un nivel de prioridad basado en puntuaciones de calidad. + +#### 1.1.5. Hacer subconjuntos de mapas con `.subMap()` + +Mientras que el operador `+` agrega claves a un mapa, a veces necesitas hacer lo contrario - extraer solo claves específicas. El método `.subMap()` es perfecto para esto. + +Agreguemos una línea para crear una versión simplificada de nuestros metadatos que solo contenga campos de identificación: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformación de datos + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Solo campos de ID: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformación de datos + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Ejecuta el flujo de trabajo modificado: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Solo campos de ID: [id:sample_001, organism:human, tissue:liver] + Solo campos de ID: [id:sample_002, organism:mouse, tissue:brain] + Solo campos de ID: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Esto muestra tanto los metadatos completos mostrados por la operación `view()` como el subconjunto extraído que imprimimos con `println`. + +El método `.subMap()` toma una lista de claves y devuelve un nuevo mapa que contiene solo esas claves. Si una clave no existe en el mapa original, simplemente no se incluye en el resultado. + +Esto es particularmente útil cuando necesitas crear diferentes versiones de metadatos para diferentes procesos - algunos podrían necesitar metadatos completos mientras que otros necesitan solo campos mínimos de identificación. + +Ahora elimina esas declaraciones println para restaurar tu flujo de trabajo a su estado anterior, ya que no las necesitamos en el futuro. + +!!! tip "Resumen de operaciones con mapas" + + - **Agregar claves**: `map1 + [new_key: value]` - Crea nuevo mapa con claves adicionales + - **Extraer claves**: `map1.subMap(['key1', 'key2'])` - Crea nuevo mapa con solo las claves especificadas + - **Ambas operaciones crean nuevos mapas** - Los mapas originales permanecen sin cambios + +#### 1.1.6. Combinar mapas y devolver resultados + +Hasta ahora, solo hemos estado devolviendo lo que la comunidad Nextflow llama el 'meta map', y hemos estado ignorando los archivos a los que esos metadatos se relacionan. Pero si estás escribiendo flujos de trabajo en Nextflow, probablemente quieras hacer algo con esos archivos. + +Generemos una estructura de canal que comprenda una tupla de 2 elementos: el mapa de metadatos enriquecido y la ruta de archivo correspondiente. Este es un patrón común en Nextflow para pasar datos a procesos. + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Aplica este cambio y ejecuta el flujo de trabajo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Esta estructura de tupla `[meta, file]` es un patrón común en Nextflow para pasar tanto metadatos como archivos asociados a procesos. + +!!! note + + **Mapas y metadatos**: Los mapas son fundamentales para trabajar con metadatos en Nextflow. Para una explicación más detallada de trabajo con mapas de metadatos, consulta la misión secundaria [Trabajar con metadatos](./metadata.md). + +Nuestro flujo de trabajo demuestra el patrón central: **operaciones de flujo de datos** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orquestan cómo los datos se mueven a través del pipeline, mientras que **scripting** (mapas `[key: value]`, métodos de cadenas, conversiones de tipo, operadores ternarios) dentro del closure `.map()` maneja la transformación de elementos de datos individuales. + +### 1.2. Comprender diferentes tipos: canal vs lista + +Hasta ahora todo bien, podemos distinguir entre operaciones de flujo de datos y scripting. Pero ¿qué pasa cuando el mismo nombre de método existe en ambos contextos? + +Un ejemplo perfecto es el método `collect`, que existe tanto para tipos de canal como para tipos List en la biblioteca estándar de Nextflow. El método `collect()` en una List transforma cada elemento, mientras que el operador `collect()` en un canal reúne todas las emisiones del canal en un canal de un solo elemento. + +Demostremos esto con algunos datos de muestra, comenzando por refrescar lo que hace el operador `collect()` del canal. Revisa `collect.nf`: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - agrupa múltiples emisiones de canal en una +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Elemento de canal individual: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} elementos agrupados en 1)" } +``` + +Pasos: + +- Define una List de IDs de muestra +- Crea un canal con `fromList()` que emite cada ID de muestra por separado +- Imprime cada elemento con `view()` a medida que fluye +- Reúne todos los elementos en una sola lista con el operador `collect()` del canal +- Imprime el resultado recopilado (un solo elemento que contiene todos los IDs de muestra) con un segundo `view()` + +Hemos cambiado la estructura del canal, pero no hemos cambiado los datos en sí. + +Ejecuta el flujo de trabajo para confirmar esto: + +```bash +nextflow run collect.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Elemento de canal individual: sample_001 + Elemento de canal individual: sample_002 + Elemento de canal individual: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 elementos agrupados en 1) + ``` + +`view()` devuelve una salida por cada emisión del canal, así que sabemos que esta única salida contiene los 3 elementos originales agrupados en una lista. + +Ahora veamos el método `collect` en una List en acción. Modifica `collect.nf` para aplicar el método `collect` de List a la lista original de IDs de muestra: + +=== "Después" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiples emisiones de canal en una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento de canal individual: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} elementos agrupados en 1)" } + + // List.collect() - transforma cada elemento, preserva estructura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} elementos transformados en ${formatted_ids.size()})" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiples emisiones de canal en una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento de canal individual: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} elementos agrupados en 1)" } + ``` + +En este nuevo fragmento: + +- Definimos una nueva variable `formatted_ids` que usa el método `collect` de List para transformar cada ID de muestra en la lista original +- Imprimimos el resultado usando `println` + +Ejecuta el flujo de trabajo modificado: + +```bash +nextflow run collect.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + Resultado de List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementos transformados en 3) + Elemento de canal individual: sample_001 + Elemento de canal individual: sample_002 + Elemento de canal individual: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 elementos agrupados en 1) + ``` + +Esta vez, NO hemos cambiado la estructura de los datos, todavía tenemos 3 elementos en la lista, pero SÍ hemos transformado cada elemento usando el método `collect` de List para producir una nueva lista con valores modificados. Esto es similar a usar el operador `map` en un canal, pero está operando en una estructura de datos List en lugar de un canal. + +`collect` es un caso extremo que estamos usando aquí para hacer un punto. La lección clave es que cuando estás escribiendo flujos de trabajo, siempre distingue entre **estructuras de datos** (Lists, Maps, etc.) y **canales** (construcciones de flujo de datos). Las operaciones pueden compartir nombres pero comportarse completamente diferente dependiendo del tipo sobre el que se llaman. + +### 1.3. El operador de propagación (`*.`) - Atajo para extracción de propiedades + +Relacionado con el método `collect` de List está el operador de propagación (`*.`), que proporciona una forma concisa de extraer propiedades de colecciones. Es esencialmente azúcar sintáctica para un patrón común de `collect`. + +Agreguemos una demostración a nuestro archivo `collect.nf`: + +=== "Después" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiples emisiones de canal en una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento de canal individual: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} elementos agrupados en 1)" } + + // List.collect() - transforma cada elemento, preserva estructura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} elementos transformados en ${formatted_ids.size()})" + + // Operador de propagación - acceso conciso a propiedades + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Resultado del operador de propagación: ${all_ids}" + ``` + +=== "Antes" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiples emisiones de canal en una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento de canal individual: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} elementos agrupados en 1)" } + + // List.collect() - transforma cada elemento, preserva estructura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} elementos transformados en ${formatted_ids.size()})" + ``` + +Ejecuta el flujo de trabajo actualizado: + +```bash title="Probar operador de propagación" +nextflow run collect.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + Resultado de List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementos transformados en 3) + Resultado del operador de propagación: [s1, s2, s3] + Elemento de canal individual: sample_001 + Elemento de canal individual: sample_002 + Elemento de canal individual: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 elementos agrupados en 1) + ``` + +El operador de propagación `*.` es una forma abreviada de un patrón común de collect: + +```groovy +// Estos son equivalentes: +def ids = samples*.id +def ids = samples.collect { it.id } + +// También funciona con llamadas a métodos: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +El operador de propagación es particularmente útil cuando necesitas extraer una sola propiedad de una lista de objetos - es más legible que escribir el closure completo de `collect`. + +!!! tip "Cuándo usar propagación vs collect" + + - **Usa propagación (`*.`)** para acceso simple a propiedades: `samples*.id`, `files*.name` + - **Usa collect** para transformaciones o lógica compleja: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Conclusión + +En esta sección, has aprendido: + +- **Flujo de datos vs scripting**: Los operadores de canal orquestan cómo los datos fluyen a través de tu pipeline, mientras que el scripting transforma elementos de datos individuales +- **Comprender tipos**: El mismo nombre de método (como `collect`) puede comportarse diferente dependiendo del tipo sobre el que se llama (Channel vs List) +- **El contexto importa**: Siempre sé consciente de si estás trabajando con canales (flujo de datos) o estructuras de datos (scripting) + +Comprender estos límites es esencial para depuración, documentación y escribir flujos de trabajo mantenibles. + +A continuación profundizaremos en capacidades de procesamiento de cadenas, que son esenciales para manejar datos del mundo real. + +--- + +## 2. Procesamiento de cadenas y generación dinámica de scripts + +Dominar el procesamiento de cadenas separa flujos de trabajo frágiles de pipelines robustos. Esta sección cubre análisis de nombres de archivos complejos, generación dinámica de scripts e interpolación de variables. + +### 2.1. Coincidencia de patrones y expresiones regulares + +Los archivos de bioinformática a menudo tienen convenciones de nomenclatura complejas que codifican metadatos. Extraigamos esto automáticamente usando coincidencia de patrones con expresiones regulares. + +Vamos a regresar a nuestro flujo de trabajo `main.nf` y agregar algo de lógica de coincidencia de patrones para extraer información adicional de muestra de los nombres de archivos. Los archivos FASTQ en nuestro conjunto de datos siguen convenciones de nomenclatura estilo Illumina con nombres como `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Estos pueden parecer crípticos, pero en realidad codifican metadatos útiles como ID de muestra, número de carril y dirección de lectura. Vamos a usar capacidades regex para analizar estos nombres. + +Realiza el siguiente cambio a tu flujo de trabajo existente `main.nf`: + +=== "Después" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Scripting para transformación de datos + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Scripting para transformación de datos + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Esto demuestra **conceptos clave de procesamiento de cadenas**: + +1. **Literales de expresión regular** usando sintaxis `~/patrón/` - esto crea un patrón regex sin necesidad de escapar barras invertidas +2. **Coincidencia de patrones** con el operador `=~` - esto intenta hacer coincidir una cadena con un patrón regex +3. **Objetos matcher** que capturan grupos con `[0][1]`, `[0][2]`, etc. - `[0]` se refiere a la coincidencia completa, `[1]`, `[2]`, etc. se refieren a grupos capturados en paréntesis + +Desglosemos el patrón regex `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$`: + +| Patrón | Coincide con | Captura | +| ------------------- | ------------------------------------------- | ---------------------------------- | +| `^(.+)` | Nombre de muestra desde el inicio | Grupo 1: nombre de muestra | +| `_S(\d+)` | Número de muestra `_S1`, `_S2`, etc. | Grupo 2: número de muestra | +| `_L(\d{3})` | Número de carril `_L001` | Grupo 3: carril (3 dígitos) | +| `_(R[12])` | Dirección de lectura `_R1` o `_R2` | Grupo 4: dirección de lectura | +| `_(\d{3})` | Número de fragmento `_001` | Grupo 5: fragmento (3 dígitos) | +| `\.fastq(?:\.gz)?$` | Extensión de archivo `.fastq` o `.fastq.gz` | No capturado (?: es no capturante) | + +Esto analiza convenciones de nomenclatura estilo Illumina para extraer metadatos automáticamente. + +Ejecuta el flujo de trabajo modificado: + +```bash title="Probar coincidencia de patrones" +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Esto muestra los metadatos enriquecidos desde los nombres de archivos. + +### 2.2. Generación dinámica de scripts en procesos + +Los bloques script de procesos son esencialmente cadenas multilínea que se pasan al shell. Puedes usar **lógica condicional** (if/else, operadores ternarios) para generar dinámicamente diferentes cadenas de script basadas en características de entrada. Esto es esencial para manejar tipos de entrada diversos—como lecturas single-end vs paired-end—sin duplicar definiciones de procesos. + +Agreguemos un proceso a nuestro flujo de trabajo que demuestre este patrón. Abre `modules/fastp.nf` y echa un vistazo: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +El proceso toma archivos FASTQ como entrada y ejecuta la herramienta `fastp` para recortar adaptadores y filtrar lecturas de baja calidad. Desafortunadamente, la persona que escribió este proceso no permitió las lecturas single-end que tenemos en nuestro conjunto de datos de ejemplo. Agreguémoslo a nuestro flujo de trabajo y veamos qué sucede: + +Primero, incluye el módulo en la primera línea de tu flujo de trabajo `main.nf`: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Luego modifica el bloque `workflow` para conectar el canal `ch_samples` al proceso `FASTP`: + +=== "Después" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Ejecuta este flujo de trabajo modificado: + +```bash +nextflow run main.nf +``` + +??? failure "Salida del comando" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Puedes ver que el proceso está intentando ejecutar `fastp` con un valor `null` para el segundo archivo de entrada, lo que está causando que falle. Esto es porque nuestro conjunto de datos contiene lecturas single-end, pero el proceso está codificado para esperar lecturas paired-end (dos archivos de entrada a la vez). + +Arregla esto agregando lógica condicional al bloque `script:` del proceso `FASTP`. Una declaración if/else verifica el conteo de archivos de lectura y ajusta el comando en consecuencia. + +=== "Después" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Detección simple de single-end vs paired-end + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Ahora el flujo de trabajo puede manejar tanto lecturas single-end como paired-end con gracia. La lógica condicional verifica el número de archivos de entrada y construye el comando apropiado para `fastp`. Veamos si funciona: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +¡Se ve bien! Si verificamos los comandos reales que se ejecutaron (personaliza para tu hash de tarea): + +```console title="Verificar comandos ejecutados" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Podemos ver que Nextflow correctamente eligió el comando correcto para lecturas single-end: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Otro uso común de lógica dinámica de script puede verse en [el módulo de Genómica de Nextflow para Ciencia](../../nf4science/genomics/02_joint_calling). En ese módulo, el proceso GATK que se está llamando puede tomar múltiples archivos de entrada, pero cada uno debe estar precedido por `-V` para formar una línea de comando correcta. El proceso usa scripting para transformar una colección de archivos de entrada (`all_gvcfs`) en los argumentos de comando correctos: + +```groovy title="manipulación de línea de comando para GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Estos patrones de usar scripting en bloques script de procesos son extremadamente poderosos y pueden aplicarse en muchos escenarios - desde manejar tipos de entrada variables hasta construir argumentos complejos de línea de comando desde colecciones de archivos, haciendo tus procesos verdaderamente adaptables a los diversos requisitos de datos del mundo real. + +### 2.3. Interpolación de variables: variables de Nextflow y Shell + +Los scripts de procesos mezclan variables de Nextflow, variables de shell y sustituciones de comandos, cada una con diferente sintaxis de interpolación. Usar la sintaxis incorrecta causa errores. Exploremos estos con un proceso que crea un reporte de procesamiento. + +Echa un vistazo al archivo de módulo `modules/generate_report.nf`: + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Procesando ${reads}" > ${meta.id}_report.txt + echo "Muestra: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Este proceso escribe un reporte simple con el ID de muestra y nombre de archivo. Ahora ejecutémoslo para ver qué sucede cuando necesitamos mezclar diferentes tipos de variables. + +Incluye el proceso en tu `main.nf` y agrégalo al flujo de trabajo: + +=== "Después" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +Ahora ejecuta el flujo de trabajo y verifica los reportes generados en `results/reports/`. Deberían contener información básica sobre cada muestra. + +<!-- TODO: add the run command --> + +??? success "Salida del comando" + + ```console + <!-- TODO: output --> + ``` + +Pero ¿qué pasa si queremos agregar información sobre cuándo y dónde ocurrió el procesamiento? Modifiquemos el proceso para usar variables **shell** y un poco de sustitución de comandos para incluir el usuario actual, nombre del host y fecha en el reporte: + +=== "Después" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Procesando ${reads}" > ${meta.id}_report.txt + echo "Muestra: ${meta.id}" >> ${meta.id}_report.txt + echo "Procesado por: ${USER}" >> ${meta.id}_report.txt + echo "Host: $(hostname)" >> ${meta.id}_report.txt + echo "Fecha: $(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Antes" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Procesando ${reads}" > ${meta.id}_report.txt + echo "Muestra: ${meta.id}" >> ${meta.id}_report.txt + """ + ``` + +Si ejecutas esto, notarás un error - Nextflow intenta interpretar `${USER}` como una variable de Nextflow que no existe. + +??? failure "Salida del comando" + + ```console + Error modules/generate_report.nf:15:27: `USER` is not defined + │ 15 | echo "Procesado por: ${USER}" >> ${meta.id}_report.txt + ╰ | ^^^^ + + ERROR ~ Script compilation failed + ``` + +Necesitamos escaparlo para que Bash pueda manejarlo en su lugar. + +Arregla esto escapando las variables de shell y sustituciones de comandos con una barra invertida (`\`): + +=== "Después" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Procesando ${reads}" > ${meta.id}_report.txt + echo "Muestra: ${meta.id}" >> ${meta.id}_report.txt + echo "Procesado por: \${USER}" >> ${meta.id}_report.txt + echo "Host: \$(hostname)" >> ${meta.id}_report.txt + echo "Fecha: \$(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Antes" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Procesando ${reads}" > ${meta.id}_report.txt + echo "Muestra: ${meta.id}" >> ${meta.id}_report.txt + echo "Procesado por: ${USER}" >> ${meta.id}_report.txt + echo "Host: $(hostname)" >> ${meta.id}_report.txt + echo "Fecha: $(date)" >> ${meta.id}_report.txt + """ + ``` + +¡Ahora funciona! La barra invertida (`\`) le dice a Nextflow "no interpretes esto, pásalo a Bash." + +### Conclusión + +En esta sección, has aprendido técnicas de **procesamiento de cadenas**: + +- **Expresiones regulares para análisis de archivos**: Usando el operador `=~` y patrones regex (`~/patrón/`) para extraer metadatos de convenciones de nomenclatura de archivos complejos +- **Generación dinámica de scripts**: Usando lógica condicional (if/else, operadores ternarios) para generar diferentes cadenas de script basadas en características de entrada +- **Interpolación de variables**: Entender cuándo Nextflow interpreta cadenas vs cuándo lo hace el shell + - `${var}` - Variables de Nextflow (interpoladas por Nextflow en tiempo de compilación del flujo de trabajo) + - `\${var}` - Variables de entorno de shell (escapadas, pasadas a bash en tiempo de ejecución) + - `\$(cmd)` - Sustitución de comandos de shell (escapada, ejecutada por bash diff --git a/docs/es/docs/side_quests/ideas/containers.md b/docs/es/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..a5e100f98c --- /dev/null +++ b/docs/es/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Parte 1: Más Contenedores + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Cómo encontrar o crear imágenes de contenedores + +Algunos desarrolladores de software proporcionan imágenes de contenedores para su software que están disponibles en registros de contenedores como Docker Hub, pero muchos no lo hacen. +En esta sección opcional, le mostraremos dos formas de obtener una imagen de contenedor para las herramientas que desea usar en sus pipelines de Nextflow: usando Seqera Containers y construyendo la imagen de contenedor usted mismo. + +Obtendrá/construirá una imagen de contenedor para el paquete pip `quote`, que se usará en el ejercicio al final de esta sección. + +### 1.1. Obtener una imagen de contenedor de Seqera Containers + +Seqera Containers es un servicio gratuito que construye imágenes de contenedores para herramientas instalables mediante pip y conda (incluido bioconda). +Navegue a [Seqera Containers](https://www.seqera.io/containers/) y busque el paquete pip `quote`. + +![Seqera Containers](img/seqera-containers-1.png) + +Haga clic en "+Add" y luego en "Get Container" para solicitar una imagen de contenedor para el paquete pip `quote`. + +![Seqera Containers](img/seqera-containers-2.png) + +Si esta es la primera vez que se construye un contenedor comunitario para esta versión del paquete, puede tomar unos minutos completarse. +Haga clic para copiar el URI (por ejemplo, `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) de la imagen de contenedor que se creó para usted. + +Ahora puede usar la imagen de contenedor para ejecutar el comando `quote` y obtener una frase aleatoria de Grace Hopper. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Salida: + +```console title="Salida" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Construir la imagen de contenedor usted mismo + +Usemos algunos detalles de construcción del sitio web de Seqera Containers para construir nosotros mismos la imagen de contenedor para el paquete pip `quote`. +Regrese al sitio web de Seqera Containers y haga clic en el botón "Build Details". + +El primer elemento que veremos es el `Dockerfile`, un tipo de archivo de script que contiene todos los comandos necesarios para construir la imagen de contenedor. +Hemos agregado algunos comentarios explicativos al Dockerfile a continuación para ayudarle a entender qué hace cada parte. + +```Dockerfile title="Dockerfile" +# Comenzar desde la imagen base de docker de micromamba +FROM mambaorg/micromamba:1.5.10-noble +# Copiar el archivo conda.yml dentro del contenedor +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Instalar varias utilidades para que Nextflow las use y los paquetes en el archivo conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Ejecutar el contenedor como el usuario root +USER root +# Establecer la variable de entorno PATH para incluir el directorio de instalación de micromamba +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +El segundo elemento que veremos es el archivo `conda.yml`, que contiene la lista de paquetes que deben instalarse en la imagen de contenedor. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Copie el contenido de estos archivos en los stubs ubicados en el directorio `containers/build`, luego ejecute el siguiente comando para construir la imagen de contenedor usted mismo. + +!!! note "Nota" + + Usamos la bandera `-t quote:latest` para etiquetar la imagen de contenedor con el nombre `quote` y la etiqueta `latest`. + Podremos usar esta etiqueta para referirnos a la imagen de contenedor al ejecutarla en este sistema. + +```bash +docker build -t quote:latest containers/build +``` + +Después de que haya terminado de construirse, puede ejecutar la imagen de contenedor que acaba de construir. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Conclusión + +Ha aprendido dos formas diferentes de obtener una imagen de contenedor para una herramienta que desea usar en sus pipelines de Nextflow: usando Seqera Containers y construyendo la imagen de contenedor usted mismo. + +### ¿Qué sigue? + +Tiene todo lo que necesita para continuar con el [siguiente capítulo](./04_hello_genomics.md) de esta serie de entrenamiento. +También puede continuar con un ejercicio opcional para obtener citas sobre pioneros de la computación/biología usando el contenedor `quote` y mostrarlas usando el contenedor `cowsay`. + +--- + +## 2. Hacer que la vaca cite científicos famosos + +Esta sección contiene algunos ejercicios adicionales, para practicar lo que ha aprendido hasta ahora. +Hacer estos ejercicios _no es obligatorio_ para comprender las partes posteriores del entrenamiento, pero proporcionan una forma divertida de reforzar su aprendizaje al descubrir cómo hacer que la vaca cite científicos famosos. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Modificar el script `hello-containers.nf` para usar un proceso getQuote + +Tenemos una lista de pioneros de la computación y la biología en el archivo `containers/data/pioneers.csv`. +A nivel general, para completar este ejercicio necesitará: + +- Modificar el `params.input_file` predeterminado para que apunte al archivo `pioneers.csv`. +- Crear un proceso `getQuote` que use el contenedor `quote` para obtener una cita para cada entrada. +- Conectar la salida del proceso `getQuote` al proceso `cowsay` para mostrar la cita. + +Para la imagen de contenedor `quote`, puede usar la que construyó usted mismo en el ejercicio adicional anterior o usar la que obtuvo de Seqera Containers. + +!!! tip "Consejo" + + Una buena elección para el bloque `script` de su proceso getQuote podría ser: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Puede encontrar una solución a este ejercicio en `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Modificar su pipeline de Nextflow para permitir que se ejecute en los modos `quote` y `sayHello`. + +Agregue algo de lógica de ramificación a su pipeline para permitir que acepte entradas destinadas tanto para `quote` como para `sayHello`. +Aquí hay un ejemplo de cómo usar una sentencia `if` en un workflow de Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "Consejo" + + Puede usar `new_ch = processName.out` para asignar un nombre al canal de salida de un proceso. + +Puede encontrar una solución a este ejercicio en `containers/solutions/hello-containers-4.2.nf`. + +### Conclusión + +¡Sabe cómo usar contenedores en Nextflow para ejecutar procesos y cómo construir algo de lógica de ramificación en sus pipelines! + +### ¿Qué sigue? + +¡Celebre, tome un descanso para estirarse y beba algo de agua! + +Cuando esté listo, continúe con la Parte 3 de esta serie de entrenamiento para aprender cómo aplicar lo que ha aprendido hasta ahora a un caso de uso de análisis de datos más realista. diff --git a/docs/es/docs/side_quests/ideas/if_else.md b/docs/es/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..b1828f780a --- /dev/null +++ b/docs/es/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Parte 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Hacer que la vaca cite científicos famosos + +Esta sección contiene algunos ejercicios adicionales para practicar lo que ha aprendido hasta ahora. +Realizar estos ejercicios _no es obligatorio_ para comprender las partes posteriores del entrenamiento, pero proporcionan una forma divertida de reforzar sus aprendizajes al descubrir cómo hacer que la vaca cite científicos famosos. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Modificar el script `hello-containers.nf` para usar un proceso getQuote + +Tenemos una lista de pioneros de la informática y la biología en el archivo `containers/data/pioneers.csv`. +A nivel general, para completar este ejercicio necesitará: + +- Modificar el `params.input_file` predeterminado para que apunte al archivo `pioneers.csv`. +- Crear un proceso `getQuote` que use el contenedor `quote` para obtener una cita para cada entrada. +- Conectar la salida del proceso `getQuote` al proceso `cowsay` para mostrar la cita. + +Para la imagen del contenedor `quote`, puede usar la que construyó usted mismo en el ejercicio adicional anterior o usar la que obtuvo de Seqera Containers. + +!!! Hint + + Una buena opción para el bloque `script` de su proceso getQuote podría ser: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Puede encontrar una solución a este ejercicio en `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Modificar su pipeline de Nextflow para permitir que se ejecute en los modos `quote` y `sayHello`. + +Agregue algo de lógica de ramificación a su pipeline para permitir que acepte entradas destinadas tanto a `quote` como a `sayHello`. +Aquí hay un ejemplo de cómo usar una sentencia `if` en un workflow de Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + Puede usar `new_ch = processName.out` para asignar un nombre al canal de salida de un proceso. + +Puede encontrar una solución a este ejercicio en `containers/solutions/hello-containers-4.2.nf`. + +### Conclusión + +¡Ahora sabe cómo usar contenedores en Nextflow para ejecutar procesos y cómo construir algo de lógica de ramificación en sus pipelines! + +### ¿Qué sigue? + +¡Celebre, tome un descanso para estirarse y beba algo de agua! + +Cuando esté listo, continúe con la Parte 3 de esta serie de entrenamiento para aprender cómo aplicar lo que ha aprendido hasta ahora a un caso de uso de análisis de datos más realista. diff --git a/docs/es/docs/side_quests/index.md b/docs/es/docs/side_quests/index.md new file mode 100644 index 0000000000..7da63d9677 --- /dev/null +++ b/docs/es/docs/side_quests/index.md @@ -0,0 +1,38 @@ +# Misiones Secundarias + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta es una colección de mini-cursos de entrenamiento independientes que profundizan en temas específicos. Puede completarlos en cualquier orden. + +¡Comencemos! Haga clic en el botón "Open in GitHub Codespaces" a continuación para iniciar el entorno de entrenamiento (preferiblemente en una pestaña separada), luego continúe leyendo mientras se carga. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Requisitos Previos + +Los requisitos previos específicos de cada mini-curso varían y están documentados en las páginas correspondientes. +Sin embargo, todos asumen cierta familiaridad mínima con lo siguiente: + +- Experiencia con la línea de comandos +- Conceptos y herramientas fundamentales de Nextflow cubiertos en el curso de entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/). + +Para requisitos técnicos y configuración del entorno, consulte el mini-curso [Configuración del Entorno](../../envsetup/). + +**Si esta es la primera vez que explora las Misiones Secundarias, ¡asegúrese de revisar primero la página de [Orientación](./orientation.md)!** + +De lo contrario, seleccione una misión secundaria de la tabla a continuación. + +## Misiones Secundarias + +| Misión Secundaria | Tiempo Estimado para Enseñanza | +| --------------------------------------------------------------------------------- | ------------------------------ | +| [Recorrido del entorno de desarrollo de Nextflow](./ide_features.md) | 45 mins | +| [Patrones Esenciales de Scripting en Nextflow](./essential_scripting_patterns.md) | 90 mins | +| [Metadatos en workflows](./metadata.md) | 45 mins | +| [División y Agrupación](./splitting_and_grouping.md) | 45 mins | +| [Pruebas con nf-test](./nf-test.md) | 1 hora | +| [Workflows de workflows](./workflows_of_workflows.md) | 30 mins | +| [Trabajar con archivos](./working_with_files.md) | 45 mins | +| [Depuración de workflows](./debugging.md) | 1 hora | + +Háganos saber qué otros dominios y casos de uso le gustaría ver cubiertos aquí publicando en la [sección de Training](https://community.seqera.io/c/training/) del foro de la comunidad. diff --git a/docs/es/docs/side_quests/metadata.md b/docs/es/docs/side_quests/metadata.md new file mode 100644 index 0000000000..08665134be --- /dev/null +++ b/docs/es/docs/side_quests/metadata.md @@ -0,0 +1,1282 @@ +# Metadatos y mapas de metadatos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +En cualquier análisis científico, rara vez trabajamos solo con los archivos de datos en bruto. +Cada archivo viene con su propia información adicional: qué es, de dónde proviene y qué lo hace especial. +Esta información extra es lo que llamamos metadatos. + +Los metadatos son datos que describen otros datos. +Los metadatos rastrean detalles importantes sobre archivos y condiciones experimentales, y ayudan a adaptar los análisis a las características únicas de cada conjunto de datos. + +Piense en ello como un catálogo de biblioteca: mientras que los libros contienen el contenido real (datos en bruto), las fichas del catálogo proporcionan información esencial sobre cada libro—cuándo fue publicado, quién lo escribió, dónde encontrarlo (metadatos). +En los pipelines de Nextflow, los metadatos se pueden usar para: + +- Rastrear información específica de archivos a lo largo del workflow +- Configurar procesos basándose en las características de los archivos +- Agrupar archivos relacionados para análisis conjunto + +### Objetivos de aprendizaje + +En esta misión secundaria, exploraremos cómo manejar metadatos en workflows. +Comenzando con una hoja de datos simple (a menudo llamada samplesheet en bioinformática) que contiene información básica de archivos, aprenderá a: + +- Leer y procesar metadatos de archivos desde archivos CSV +- Crear y manipular mapas de metadatos +- Agregar nuevos campos de metadatos durante la ejecución del workflow +- Usar metadatos para personalizar el comportamiento de los procesos + +Estas habilidades lo ayudarán a construir pipelines más robustos y flexibles que puedan manejar relaciones complejas de archivos y requisitos de procesamiento. + +### Requisitos previos + +Antes de embarcarse en esta misión secundaria, debería: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso para principiantes equivalente. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores) + +--- + +## 0. Primeros pasos + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en [Configuración del Entorno](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/metadata +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un archivo de workflow principal y un directorio `data` que contiene una hoja de datos y un puñado de archivos de datos. + +??? abstract "Contenido del directorio" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +El workflow en el archivo `main.nf` es un esqueleto que expandirá gradualmente en un workflow completamente funcional. + +La hoja de datos enumera las rutas a los archivos de datos y algunos metadatos asociados, organizados en 3 columnas: + +- `id`: autoexplicativo, un ID asignado al archivo +- `character`: un nombre de personaje, que usaremos más tarde para dibujar diferentes criaturas +- `data`: rutas a archivos `.txt` que contienen saludos en diferentes idiomas + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Cada archivo de datos contiene texto de saludo en uno de cinco idiomas (fr: francés, de: alemán, es: español, it: italiano, en: inglés). + +También le proporcionaremos una herramienta de análisis de lenguaje en contenedor llamada `langid`. + +#### Revisar la asignación + +Su desafío es escribir un workflow de Nextflow que: + +1. **Identifique** el idioma en cada archivo automáticamente +2. **Agrupe** archivos por familia de idiomas (idiomas germánicos vs románicos) +3. **Personalice** el procesamiento para cada archivo basándose en su idioma y metadatos +4. **Organice** las salidas por grupo de idiomas + +Esto representa un patrón típico de workflow donde los metadatos específicos de archivos impulsan las decisiones de procesamiento; exactamente el tipo de problema que los mapas de metadatos resuelven elegantemente. + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está en funcionamiento +- [ ] He configurado mi directorio de trabajo apropiadamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Cargar metadatos desde una hoja de datos + +Abra el archivo de workflow `main.nf` para examinar el esqueleto de workflow que le proporcionamos como punto de partida. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Puede ver que hemos configurado un factory de canal básico para cargar la hoja de datos de ejemplo como un archivo, pero eso aún no leerá el contenido del archivo. +Comencemos agregando eso. + +### 1.1. Leer el contenido con `splitCsv` + +Necesitamos elegir un operador que procese el contenido del archivo apropiadamente con el mínimo esfuerzo de nuestra parte. +Como nuestra hoja de datos está en formato CSV, este es un trabajo para el operador [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv), que carga cada fila en el archivo como un elemento en el canal. + +Realice los siguientes cambios para agregar una operación `splitCsv()` al código de construcción del canal, más una operación `view()` para verificar que el contenido del archivo se esté cargando en el canal correctamente. + +=== "Después" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Tenga en cuenta que estamos usando la opción `header: true` para indicarle a Nextflow que lea la primera fila del archivo CSV como la fila de encabezado. + +Veamos qué sale de eso, ¿de acuerdo? +Ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Podemos ver que el operador ha construido un mapa de pares clave-valor para cada fila en el archivo CSV, con los encabezados de columna como claves para los valores correspondientes. + +Cada entrada de mapa corresponde a una columna en nuestra hoja de datos: + +- `id` +- `character` +- `recording` + +¡Esto es genial! Facilita el acceso a campos específicos de cada archivo. +Por ejemplo, podríamos acceder al ID del archivo con `id` o a la ruta del archivo txt con `recording`. + +??? info "(Opcional) Más sobre mapas" + + En Groovy, el lenguaje de programación sobre el que se construye Nextflow, un mapa es una estructura de datos clave-valor similar a los diccionarios en Python, objetos en JavaScript o hashes en Ruby. + + Aquí hay un script ejecutable que muestra cómo puede definir un mapa y acceder a su contenido en la práctica: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Crear un mapa simple + def my_map = [id:'sampleA', character:'squirrel'] + + // Imprimir todo el mapa + println "map: ${my_map}" + + // Acceder a valores individuales usando notación de punto + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Aunque no tiene un bloque `workflow` apropiado, Nextflow puede ejecutar esto como si fuera un workflow: + + ```bash + nextflow run examples/map_demo.nf + ``` + + Y aquí está lo que puede esperar ver en la salida: + + ```console title="Salida" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Seleccionar campos específicos con `map` + +Digamos que queremos acceder a la columna `character` de la hoja de datos e imprimirla. +Podemos usar el operador `map` de Nextflow para iterar sobre cada elemento en nuestro canal y específicamente seleccionar la entrada `character` del objeto mapa. + +Realice las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Ahora ejecute el workflow nuevamente: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +¡Éxito! Hemos aprovechado la estructura de mapa derivada de nuestra hoja de datos para acceder a los valores de columnas individuales para cada fila. + +Ahora que hemos leído exitosamente la hoja de datos y tenemos acceso a los datos en cada fila, podemos comenzar a implementar nuestra lógica de pipeline. + +### 1.3. Organizar los metadatos en un 'mapa de metadatos' + +En el estado actual del workflow, los archivos de entrada (bajo la clave `recording`) y los metadatos asociados (`id`, `character`) están todos al mismo nivel, como si estuvieran todos en una gran bolsa. +La consecuencia práctica es que cada proceso que consuma este canal necesitaría configurarse con esta estructura en mente: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +Eso está bien siempre que el número de columnas en la hoja de datos no cambie. +Sin embargo, si agrega incluso solo una columna a la hoja de datos, la forma del canal ya no coincidirá con lo que el proceso espera, y el workflow producirá errores. +También hace que el proceso sea difícil de compartir con otros que podrían tener datos de entrada ligeramente diferentes, y podría terminar teniendo que codificar variables en el proceso que no son necesarias para el bloque de script. + +Para evitar este problema, necesitamos encontrar una forma de mantener la estructura del canal consistente independientemente de cuántas columnas contenga esa hoja de datos. + +Podemos hacer eso recopilando todos los metadatos en un elemento dentro de la tupla, que llamaremos el mapa de metadatos, o más simplemente 'mapa de metadatos'. + +Realice las siguientes ediciones a la operación `map`: + +=== "Después" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Hemos reestructurado nuestros elementos de canal en una tupla que consta de dos elementos, el mapa de metadatos y el objeto archivo correspondiente. + +Ejecutemos el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console title="Ver mapa de metadatos" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Ahora, cada elemento en el canal contiene primero el mapa de metadatos y segundo el objeto archivo correspondiente: + +```console title="Ejemplo de estructura de salida" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +Como resultado, agregar más columnas en la hoja de datos hará que más metadatos estén disponibles en el mapa `meta`, pero no cambiará la forma del canal. +Esto nos permite escribir procesos que consuman el canal sin tener que codificar los elementos de metadatos en la especificación de entrada: + +```groovy title="Ejemplo de sintaxis" + input: + tuple val(meta), file(recording) +``` + +Esta es una convención ampliamente utilizada para organizar metadatos en workflows de Nextflow. + +### Conclusión + +En esta sección, ha aprendido: + +- **Por qué los metadatos son importantes:** Mantener los metadatos con sus datos preserva información importante de archivos a lo largo del workflow. +- **Cómo leer hojas de datos:** Usar `splitCsv` para leer archivos CSV con información de encabezado y transformar filas en datos estructurados +- **Cómo crear un mapa de metadatos:** Separar metadatos de datos de archivos usando la estructura de tupla `[ [id:value, ...], file ]` + +--- + +## 2. Manipulando metadatos + +Ahora que tenemos nuestros metadatos cargados, ¡hagamos algo con ellos! + +Vamos a usar una herramienta llamada [`langid`](https://github.com/saffsd/langid.py) para identificar el idioma contenido en cada archivo de grabación de la criatura. +La herramienta viene pre-entrenada con un conjunto de idiomas, y dado un fragmento de texto, producirá una predicción de idioma y una puntuación de probabilidad asociada, ambas a `stdout`. + +### 2.1. Importar el proceso y examinar el código + +Le proporcionamos un módulo de proceso pre-escrito llamado `IDENTIFY_LANGUAGE` que envuelve la herramienta `langid`, por lo que solo necesita agregar una declaración de inclusión antes del bloque de workflow. + +Realice la siguiente edición al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Puede abrir el archivo del módulo para examinar su código: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Usar langid para predecir el idioma de cada archivo de entrada +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Como puede ver, la definición de entrada usa la misma estructura `tuple val(meta), path(file)` que acabamos de aplicar a nuestro canal de entrada. + +La definición de salida está estructurada como una tupla con una estructura similar a la entrada, excepto que también contiene `stdout` como tercer elemento. +Este patrón `tuple val(meta), path(file), <output>` mantiene los metadatos asociados tanto con los datos de entrada como con las salidas mientras fluye a través del pipeline. + +Tenga en cuenta que estamos usando el calificador de salida [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) de Nextflow aquí porque la herramienta imprime su salida directamente a la consola en lugar de escribir un archivo; y usamos `sed` en la línea de comando para eliminar la puntuación de probabilidad, limpiar la cadena eliminando caracteres de nueva línea y devolver solo la predicción de idioma. + +### 2.2. Agregar una llamada a `IDENTIFY_LANGUAGE` + +Ahora que el proceso está disponible para el workflow, podemos agregar una llamada al proceso `IDENTIFY_LANGUAGE` para ejecutarlo en el canal de datos. + +Realice las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Tenga en cuenta que hemos eliminado la operación `.view()` original en la construcción del canal. + +Ahora podemos ejecutar el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +¡Excelente! Ahora tenemos una predicción de qué idioma habla cada personaje. + +Y como se señaló anteriormente, también hemos incluido el archivo de entrada y el mapa de metadatos en la salida, lo que significa que ambos permanecen asociados con la nueva información que acabamos de producir. +Esto resultará útil en el siguiente paso. + +!!! note + + De manera más general, este patrón de mantener el mapa de metadatos asociado con los resultados facilita la asociación de resultados relacionados que comparten los mismos identificadores. + + Como ya habrá aprendido, no puede confiar en el orden de los elementos en los canales para emparejar resultados entre ellos. + En su lugar, debe usar claves para asociar datos correctamente, y los mapas de metadatos proporcionan una estructura ideal para este propósito. + + Exploramos este caso de uso en detalle en la misión secundaria [Dividir y Agrupar](./splitting_and_grouping.md). + +### 2.3. Aumentar metadatos con salidas de procesos + +Dado que los resultados que acabamos de producir son en sí mismos una forma de metadatos sobre el contenido de los archivos, sería útil agregarlos a nuestro mapa de metadatos. + +Sin embargo, no queremos modificar el mapa de metadatos existente en su lugar. +Desde un punto de vista técnico, es _posible_ hacer eso, pero no es seguro. + +Así que en su lugar, crearemos un nuevo mapa de metadatos que contenga el contenido del mapa de metadatos existente más un nuevo par clave-valor `lang: lang_id` que contenga la nueva información, usando el operador `+` (una característica de Groovy). +Y combinaremos esto con una operación [`map`](https://www.nextflow.io/docs/latest/operator.html#map) para reemplazar el mapa antiguo con el nuevo. + +Aquí están las ediciones que necesita hacer al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Si aún no está familiarizado con el operador `+`, o si esto parece confuso, tome unos minutos para revisar la explicación detallada a continuación. + +??? info "Creación del nuevo mapa de metadatos usando el operador `+`" + + **Primero, necesita saber que podemos fusionar el contenido de dos mapas usando el operador `+` de Groovy.** + + Digamos que tenemos los siguientes mapas: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Podemos fusionarlos así: + + ```groovy + new_map = map1 + map2 + ``` + + El contenido de `new_map` será: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + ¡Genial! + + **¿Pero qué pasa si necesita agregar un campo que aún no es parte de un mapa?** + + Digamos que comienza nuevamente desde `map1`, pero la predicción de idioma no está en su propio mapa (no hay `map2`). + En su lugar, se mantiene en una variable llamada `lang_id`, y sabe que quiere almacenar su valor (`'fr'`) con la clave `lang`. + + En realidad puede hacer lo siguiente: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Aquí, `[lang: new_info]` crea un nuevo mapa sin nombre sobre la marcha, y `map1 + ` fusiona `map1` con el nuevo mapa sin nombre, produciendo el mismo contenido `new_map` que antes. + + Ordenado, ¿verdad? + + **Ahora transpongamos eso al contexto de una operación `channel.map()` de Nextflow.** + + El código se convierte en: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Esto hace lo siguiente: + + - `map1, lang_id ->` toma los dos elementos en la tupla + - `[map1 + [lang: lang_id]]` crea el nuevo mapa como se detalló arriba + + La salida es un solo mapa sin nombre con el mismo contenido que `new_map` en nuestro ejemplo anterior. + Entonces efectivamente hemos transformado: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + en: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Con suerte puede ver que si cambiamos `map1` a `meta`, eso es básicamente todo lo que necesitamos para agregar la predicción de idioma a nuestro mapa de metadatos en nuestro workflow. + + ¡Excepto por una cosa! + + En el caso de nuestro workflow, **también necesitamos tener en cuenta la presencia del objeto `file` en la tupla**, que está compuesta de `meta, file, lang_id`. + + Entonces el código aquí se convertiría en: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Si está teniendo dificultades para entender por qué el `file` parece estar moviéndose en la operación `map`, imagine que en lugar de `[meta + [lang: lang_id], file]`, esa línea lee `[new_map, file]`. + Esto debería dejar más claro que simplemente estamos dejando el `file` en su lugar original en segunda posición en la tupla. Simplemente hemos tomado el valor `new_info` y lo hemos incorporado al mapa que está en primera posición. + + **¡Y esto nos lleva de vuelta a la estructura de canal `tuple val(meta), path(file)`!** + +Una vez que esté seguro de entender qué está haciendo este código, ejecute el workflow para ver si funcionó: + +```bash +nextflow run main.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Sí, ¡eso lo confirma! +Hemos reorganizado ordenadamente la salida del proceso de `meta, file, lang_id` para que `lang_id` sea ahora una de las claves en el mapa de metadatos, y las tuplas del canal se ajusten al modelo `meta, file` una vez más. + +### 2.4. Asignar un grupo de idiomas usando condicionales + +Ahora que tenemos nuestras predicciones de idioma, usemos la información para asignar algunas agrupaciones nuevas. + +En nuestros datos de ejemplo, los idiomas usados por nuestros personajes pueden agruparse en idiomas germánicos (inglés, alemán) e idiomas románicos (francés, español, italiano). +Podría ser útil tener esa clasificación fácilmente disponible en algún lugar más adelante en el pipeline, así que agreguemos esa información en el mapa de metadatos. + +Y, buenas noticias, ¡este es otro caso que se presta perfectamente para usar el operador `map`! + +Específicamente, vamos a definir una variable llamada `lang_group`, usar algo de lógica condicional simple para determinar qué valor asignar al `lang_group` para cada pieza de datos. + +La sintaxis general se verá así: + +```groovy +.map { meta, file -> + + // la lógica condicional que define lang_group va aquí + + [meta + [lang_group: lang_group], file] +} +``` + +Puede ver que esto es muy similar a la operación de fusión de mapa sobre la marcha que usamos en el paso anterior. +Solo necesitamos escribir las declaraciones condicionales. + +Aquí está la lógica condicional que queremos aplicar: + +- Definir una variable llamada `lang_group` con valor predeterminado `'unknown'`. +- Si `lang` es alemán (`'de'`) o inglés (`'en'`), cambiar `lang_group` a `germanic`. +- De lo contrario, si `lang` está incluido en una lista que contiene francés (`'fr'`), español (`'es'`) e italiano (`'it'`), cambiar `lang_group` a `romance`. + +Intente escribirlo usted mismo si ya sabe cómo escribir declaraciones condicionales en Nextflow. + +!!! tip + + Puede acceder al valor de `lang` dentro de la operación map con `meta.lang`. + +Debería terminar haciendo los siguientes cambios al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Aquí están los puntos clave: + +- Usamos `def lang_group = "unknown"` para crear la variable `lang_group` con valor predeterminado establecido en `unknown`. +- Usamos una estructura `if {} else if {}` para la lógica condicional, con pruebas alternativas `.equals()` para los dos idiomas germánicos, y una prueba de existencia en una lista para los tres idiomas románicos. +- Usamos la operación de fusión `meta + [lang_group:lang_group]` como anteriormente para generar el mapa de metadatos actualizado. + +Una vez que todo tenga sentido, ejecute el workflow nuevamente para ver el resultado: + +```bash +nextflow run main.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Como puede ver, los elementos del canal mantienen su estructura `[meta, file]`, pero el mapa de metadatos ahora incluye esta nueva clasificación. + +### Conclusión + +En esta sección, ha aprendido cómo: + +- **Aplicar metadatos de entrada a canales de salida**: Copiar metadatos de esta manera nos permite asociar resultados más adelante basándonos en el contenido de los metadatos. +- **Crear claves personalizadas**: Creó dos nuevas claves en su mapa de metadatos, fusionándolas con `meta + [new_key:value]` en el mapa de metadatos existente. Una basada en un valor calculado de un proceso, y una basada en una condición que estableció en el operador `map`. + +Estos le permiten asociar metadatos nuevos y existentes con archivos a medida que avanza a través de su pipeline. +Incluso si no está usando metadatos como parte de un proceso, mantener el mapa de metadatos asociado con los datos de esta manera facilita mantener toda la información relevante junta. + +--- + +## 3. Usando información del mapa de metadatos en un proceso + +Ahora que sabe cómo crear y actualizar el mapa de metadatos, podemos llegar a la parte realmente divertida: usar realmente los metadatos en un proceso. + +Más específicamente, vamos a agregar un segundo paso a nuestro workflow para dibujar cada animal como arte ASCII y hacer que diga el texto grabado en una burbuja de diálogo. +Vamos a hacer esto usando una herramienta llamada [`cowpy`](https://github.com/jeffbuttars/cowpy). + +??? info "¿Qué hace `cowpy`?" + + `cowpy` es una herramienta de línea de comandos que genera arte ASCII para mostrar entradas de texto arbitrarias de una manera divertida. + Es una implementación en Python de la herramienta clásica [cowsay](https://en.wikipedia.org/wiki/Cowsay) de Tony Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Opcionalmente, puede seleccionar un personaje (o 'cowacter') para usar en lugar de la vaca predeterminada. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Si trabajó en el curso Hello Nextflow, ya ha visto esta herramienta en acción. +Si no, no se preocupe; cubriremos todo lo que necesita saber a medida que avancemos. + +### 3.1. Importar el proceso y examinar el código + +Le proporcionamos un módulo de proceso pre-escrito llamado `COWPY` que envuelve la herramienta `cowpy`, por lo que solo necesita agregar una declaración de inclusión antes del bloque de workflow. + +Realice la siguiente edición al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Puede abrir el archivo del módulo para examinar su código: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generar arte ASCII con cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Como puede ver, este proceso está actualmente diseñado para tomar un archivo de entrada (que contiene el texto a mostrar) y un valor que especifica el personaje que debe dibujarse en arte ASCII, generalmente proporcionado a nivel de workflow por un parámetro de línea de comandos. + +### 3.2. Pasar un campo del mapa de metadatos como entrada + +Cuando usamos la herramienta `cowpy` en el curso Hello Nextflow, usamos un parámetro de línea de comandos para determinar qué personaje usar para dibujar la imagen final. +Eso tenía sentido, porque solo estábamos generando una imagen por ejecución del pipeline. + +Sin embargo, en este tutorial, queremos generar una imagen apropiada para cada sujeto que estamos procesando, por lo que usar un parámetro de línea de comandos sería demasiado limitante. + +Buenas noticias: tenemos una columna `character` en nuestra hoja de datos y por lo tanto, en nuestro mapa de metadatos. +Usemos eso para establecer el personaje que el proceso debería usar para cada entrada. + +Para ese fin, necesitaremos hacer tres cosas: + +1. Dar un nombre al canal de salida que sale del proceso anterior para que podamos operar en él más convenientemente. +2. Determinar cómo acceder a la información de interés +3. Agregar una llamada al segundo proceso y alimentar la información apropiadamente. + +Comencemos. + +#### 3.2.1. Nombrar el canal de salida anterior + +Aplicamos las manipulaciones anteriores directamente en el canal de salida del primer proceso, `IDENTIFY_LANGUAGE.out`. +Para alimentar el contenido de ese canal al siguiente proceso (y hacerlo de una manera que sea clara y fácil de leer) queremos darle su propio nombre, `ch_languages`. + +Podemos hacer eso usando el operador [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set). + +En el workflow principal, reemplace el operador `.view()` con `.set { ch_languages }`, y agregue una línea probando que podemos referirnos al canal por nombre. + +=== "Después" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Temporal: mirar dentro de ch_languages + ch_languages.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Ejecutar langid para identificar el idioma de cada saludo + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Ejecutemos esto: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Esto confirma que ahora podemos referirnos al canal por nombre. + +#### 3.2.2. Acceder al archivo y metadatos del personaje + +Sabemos por mirar el código del módulo que el proceso `COWPY` espera que se le proporcione un archivo de texto y un valor `character`. +Para escribir la llamada al proceso `COWPY`, solo necesitamos saber cómo extraer el objeto archivo correspondiente y los metadatos de cada elemento en el canal. + +Como suele ser el caso, la forma más simple de hacer eso es usar una operación `map`. + +Nuestro canal contiene tuplas estructuradas como `[meta, file]`, por lo que podemos acceder al objeto `file` directamente, y podemos acceder al valor `character` almacenado dentro del mapa de metadatos refiriéndonos a él como `meta.character`. + +En el workflow principal, realice los siguientes cambios de código: + +=== "Después" + + ```groovy title="main.nf" linenums="34" + // Temporal: acceder al archivo y personaje + ch_languages.map { meta, file -> file }.view { file -> "Archivo: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Personaje: " + character } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" + // Temporal: mirar dentro de ch_languages + ch_languages.view() + ``` + +Tenga en cuenta que estamos usando closures (como `{ file -> "Archivo: " + file }`) para hacer la salida de las operaciones `.view` más legible. + +Ejecutemos esto: + +```bash +nextflow run main.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Personaje: squirrel + Archivo: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + Archivo: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Personaje: tux + Personaje: turkey + Archivo: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + Archivo: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Personaje: sheep + Personaje: moose + Personaje: stegosaurus + Archivo: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + Archivo: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + Archivo: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Personaje: turtle + ``` + +_Las rutas de archivo y valores de personaje pueden aparecer en un orden diferente en su salida._ + +Esto confirma que podemos acceder al archivo y al personaje para cada elemento en el canal. + +#### 3.2.3. Llamar al proceso `COWPY` + +Ahora pongamos todo junto y llamemos realmente al proceso `COWPY` en el canal `ch_languages`. + +En el workflow principal, realice los siguientes cambios de código: + +=== "Después" + + ```groovy title="main.nf" linenums="34" + // Ejecutar cowpy para generar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" + // Temporal: acceder al archivo y personaje + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Ve que simplemente copiamos las dos operaciones map (menos las declaraciones `.view()`) como las entradas para la llamada al proceso. +¡Solo asegúrese de no olvidar la coma entre ellas! + +Es un poco torpe, pero veremos cómo mejorar eso en la siguiente sección. + +Ejecutemos esto: + +```bash +nextflow run main.nf -resume +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Si mira en el directorio de resultados, debería ver los archivos individuales que contienen el arte ASCII de cada saludo hablado por el personaje correspondiente. + +??? abstract "Directorio y contenido de archivo de ejemplo" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola.txt + └── cowpy-salut.txt + ``` + + ```text title="results/cowpy-bonjour.txt" + _________________ + / Bonjour \ + \ Salut, à demain / + ----------------- + \ + \ + _ _ + | \__/| .~ ~. + /oo `./ .' + {o__, \ { + / . . ) \ + `-` '-' \ } + .( _( )_.' + '---.~_ _ _| + ``` + +Esto muestra que pudimos usar la información en el mapa de metadatos para parametrizar el comando en el segundo paso del pipeline. + +Sin embargo, como se señaló anteriormente, parte del código involucrado fue un poco torpe, ya que tuvimos que desempaquetar metadatos mientras todavía estábamos en el contexto del cuerpo del workflow. +Ese enfoque funciona bien para usar un pequeño número de campos del mapa de metadatos, pero escalaría pobremente si quisiéramos usar muchos más. + +Hay otro operador llamado `multiMap()` que nos permite optimizar esto un poco, pero incluso entonces no es ideal. + +??? info "(Opcional) Versión alternativa con `multiMap()`" + + En caso de que se lo esté preguntando, no podíamos simplemente escribir una sola operación `map()` que produjera tanto el `file` como el `character`, porque eso los devolvería como una tupla. + Tuvimos que escribir dos operaciones `map()` separadas para alimentar los elementos `file` y `character` al proceso por separado. + + Técnicamente hay otra forma de hacer esto a través de una sola operación de mapeo, usando el operador `multiMap()`, que es capaz de emitir múltiples canales. + Por ejemplo, podría reemplazar la llamada a `COWPY` anterior con el siguiente código: + + === "Después" + + ```groovy title="main.nf" linenums="34" + // Ejecutar cowpy para generar arte ASCII + COWPY( + ch_languages.multiMap { meta, file -> + file: file + character: meta.character + } + ) + ``` + + === "Antes" + + ```groovy title="main.nf" linenums="34" + // Ejecutar cowpy para generar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + + Esto produce exactamente el mismo resultado. + +En cualquier caso, es incómodo que tengamos que hacer algo de desempaquetado a nivel de workflow. + +Sería mejor si pudiéramos alimentar todo el mapa de metadatos en el proceso y seleccionar lo que necesitamos una vez allí. + +### 3.3. Pasar y usar todo el mapa de metadatos + +El punto del mapa de metadatos es después de todo pasar todos los metadatos juntos como un paquete. +La única razón por la que no pudimos hacer eso anteriormente es que el proceso no está configurado para aceptar un mapa de metadatos. +Pero como controlamos el código del proceso, podemos cambiar eso. + +Modifiquemos el proceso `COWPY` para aceptar la estructura de tupla `[meta, file]` que usamos en el primer proceso para poder optimizar el workflow. + +Para ese fin, necesitaremos hacer tres cosas: + +1. Modificar las definiciones de entrada del módulo de proceso `COWPY` +2. Actualizar el comando del proceso para usar el mapa de metadatos +3. Actualizar la llamada al proceso en el cuerpo del workflow + +¿Listo? ¡Vamos! + +#### 3.3.1. Modificar la entrada del módulo `COWPY` + +Realice las siguientes ediciones al archivo de módulo `cowpy.nf`: + +=== "Después" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2" + input: + tuple val(meta), path(input_file) + ``` + +=== "Antes" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2-3" + input: + path(input_file) + val character + ``` + +Esto nos permite usar la estructura de tupla `[meta, file]` que cubrimos anteriormente en el tutorial. + +Tenga en cuenta que no actualizamos la definición de salida del proceso para producir el mapa de metadatos, con el fin de mantener el tutorial simplificado, pero siéntase libre de hacerlo usted mismo como ejercicio siguiendo el modelo del proceso `IDENTIFY_LANGUAGE`. + +#### 3.3.2. Actualizar el comando para usar el campo del mapa de metadatos + +Todo el mapa de metadatos ahora está disponible dentro del proceso, por lo que podemos referirnos a la información que contiene directamente desde dentro del bloque de comando. + +Realice las siguientes ediciones al archivo de módulo `cowpy.nf`: + +=== "Después" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${meta.character} > cowpy-${input_file} + """ + ``` + +=== "Antes" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ + ``` + +Hemos reemplazado la referencia al valor `character` previamente pasado como una entrada independiente con el valor contenido en el mapa de metadatos, al que nos referimos usando `meta.character`. + +Ahora actualicemos la llamada al proceso en consecuencia. + +#### 3.3.3. Actualizar la llamada al proceso y ejecutarlo + +El proceso ahora espera que su entrada use la estructura de tupla `[meta, file]`, que es lo que produce el proceso anterior, por lo que simplemente podemos pasar todo el canal `ch_languages` al proceso `COWPY`. + +Realice las siguientes ediciones al workflow principal: + +=== "Después" + + ```groovy title="main.nf" linenums="34" hl_lines="2" + // Ejecutar cowpy para generar arte ASCII + COWPY(ch_languages) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" hl_lines="3-4" + // Ejecutar cowpy para generar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) diff --git a/docs/es/docs/side_quests/nf-test.md b/docs/es/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..453fd9f212 --- /dev/null +++ b/docs/es/docs/side_quests/nf-test.md @@ -0,0 +1,1196 @@ +# Pruebas con nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Poder probar sistemáticamente que cada parte de su flujo de trabajo está haciendo lo que se supone que debe hacer es fundamental para la reproducibilidad y el mantenimiento a largo plazo, y puede ser de gran ayuda durante el proceso de desarrollo. + +Tomemos un minuto para hablar sobre por qué las pruebas son tan importantes. Si está desarrollando un flujo de trabajo, una de las primeras cosas que hará es tomar algunos datos de prueba que sabe que son válidos y que deberían producir un resultado. Agrega el primer proceso al pipeline y lo conecta a sus entradas para que funcione. Luego, para verificar que todo funciona, lo ejecuta con los datos de prueba. Suponiendo que funcione, pasa al siguiente proceso y ejecuta los datos de prueba nuevamente. Repite este proceso hasta que tiene un pipeline con el que está satisfecho. + +Luego, tal vez agregue un parámetro simple de verdadero o falso como `--skip_process`. Ahora debe ejecutar el pipeline dos veces, una con cada parámetro para asegurarse de que funcione como se espera. Pero espere, ¿cómo verificamos si `--skip_process` realmente omite el proceso? ¡Tenemos que revisar las salidas o verificar los archivos de registro! Esto es tedioso y propenso a errores. + +A medida que desarrolla su pipeline, rápidamente se volverá tan complejo que probar manualmente cada iteración es lento y propenso a errores. Además, si encuentra un error, será muy difícil identificar exactamente de dónde proviene el error en su pipeline. Aquí es donde entran las pruebas. + +Las pruebas le permiten verificar sistemáticamente que cada parte de su pipeline está funcionando como se espera. Los beneficios para un desarrollador de pruebas bien escritas son enormes: + +- **Confianza**: Debido a que las pruebas cubren todo el pipeline, puede estar seguro de que cambiar algo no afecta nada más +- **Confiabilidad**: Cuando múltiples desarrolladores trabajan en el pipeline, saben que los otros desarrolladores no han roto el pipeline ni ningún componente. +- **Transparencia**: Las pruebas muestran dónde está fallando un pipeline y facilitan el rastreo del problema. También funcionan como una forma de documentación, mostrando cómo ejecutar un proceso o flujo de trabajo. +- **Velocidad**: Debido a que las pruebas están automatizadas, pueden ejecutarse muy rápidamente y repetidamente. Puede iterar rápidamente con menos temor de introducir nuevos errores. + +Hay muchos tipos diferentes de pruebas que podemos escribir: + +1. **Pruebas a nivel de módulo**: Para procesos individuales +2. **Pruebas a nivel de flujo de trabajo**: Para un solo flujo de trabajo +3. **Pruebas a nivel de pipeline**: Para el pipeline en su conjunto +4. **Pruebas de rendimiento**: Para la velocidad y eficiencia del pipeline +5. **Pruebas de estrés**: Evaluar el rendimiento del pipeline bajo condiciones extremas para determinar sus límites + +Probar procesos individuales es análogo a las pruebas unitarias en otros lenguajes. Probar el flujo de trabajo o el pipeline completo es análogo a lo que se llama pruebas de integración en otros lenguajes, donde probamos las interacciones de los componentes. + +[**nf-test**](https://www.nf-test.com/) es una herramienta que le permite escribir pruebas a nivel de módulo, flujo de trabajo y pipeline. En resumen, le permite verificar sistemáticamente que cada parte individual del pipeline está funcionando como se espera, _de forma aislada_. + +### Objetivos de aprendizaje + +En esta misión secundaria, aprenderá a usar nf-test para escribir una prueba a nivel de flujo de trabajo para el pipeline, así como pruebas a nivel de módulo para los tres procesos que llama. + +Al final de esta misión secundaria, podrá usar las siguientes técnicas de manera efectiva: + +- Inicializar nf-test en su proyecto +- Generar pruebas a nivel de módulo y flujo de trabajo +- Agregar tipos comunes de aserciones +- Comprender cuándo usar instantáneas vs. aserciones de contenido +- Ejecutar pruebas para un proyecto completo + +Estas habilidades le ayudarán a implementar una estrategia de pruebas integral en sus proyectos de pipeline, asegurando que sean más robustos y mantenibles. + +### Requisitos previos + +Antes de emprender esta misión secundaria, debe: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso equivalente para principiantes. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores, trabajo con archivos, metadatos) + +--- + +## 0. Comenzar + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en la [Configuración del Entorno](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/nf-test +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un archivo de flujo de trabajo principal y un archivo CSV llamado `greetings.csv` que contiene la entrada al pipeline. + +```console title="Contenidos del directorio" +. +├── greetings.csv +└── main.nf +``` + +Para una descripción detallada de los archivos, consulte el [calentamiento de Hello Nextflow](../hello_nextflow/00_orientation.md). + +El flujo de trabajo que probaremos es un subconjunto del flujo de trabajo Hello construido en [Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +??? example "¿Qué hace el flujo de trabajo Hello Nextflow?" + + Si no ha realizado el entrenamiento de [Hello Nextflow](../hello_nextflow/index.md), aquí hay una descripción rápida de lo que hace este flujo de trabajo simple. + + El flujo de trabajo toma un archivo CSV que contiene saludos, ejecuta cuatro pasos de transformación consecutivos sobre ellos y produce un solo archivo de texto que contiene una imagen ASCII de un personaje divertido diciendo los saludos. + + Los cuatro pasos se implementan como procesos de Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` y `cowpy`) almacenados en archivos de módulos separados. + + 1. **`sayHello`:** Escribe cada saludo en su propio archivo de salida (por ejemplo, "Hello-output.txt") + 2. **`convertToUpper`:** Convierte cada saludo a mayúsculas (por ejemplo, "HELLO") + 3. **`collectGreetings`:** Recopila todos los saludos en mayúsculas en un solo archivo por lotes + 4. **`cowpy`:** Genera arte ASCII usando la herramienta `cowpy` + + Los resultados se publican en un directorio llamado `results/`, y la salida final del pipeline (cuando se ejecuta con parámetros predeterminados) es un archivo de texto plano que contiene arte ASCII de un personaje diciendo los saludos en mayúsculas. + + En esta misión secundaria, utilizamos una forma intermedia del flujo de trabajo Hello que solo contiene los primeros dos procesos. <!-- TODO: change this to use the full finished workflow as suggested in https://github.com/nextflow-io/training/issues/735 --> + +El subconjunto con el que trabajaremos está compuesto por dos procesos: `sayHello` y `convertToUpper`. +Puede ver el código completo del flujo de trabajo a continuación. + +??? example "Código del flujo de trabajo" + + ```groovy title="main.nf" + /* + * Pipeline parameters + */ + params.input_file = "greetings.csv" + + /* + * Usar echo para imprimir 'Hello World!' a la salida estándar + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Usar una utilidad de reemplazo de texto para convertir el saludo a mayúsculas + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // crear un canal para entradas desde un archivo CSV + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // emitir un saludo + sayHello(greeting_ch) + + // convertir el saludo a mayúsculas + convertToUpper(sayHello.out) + } + ``` + +#### Ejecutar el flujo de trabajo + +Ejecutemos el flujo de trabajo para asegurarnos de que funcione como se espera. + +```bash +nextflow run main.nf +``` + +```console title="Resultado de ejecutar el flujo de trabajo" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +¡FELICITACIONES! ¡Acaba de ejecutar una prueba! + +"Espere, ¿qué? ¡Solo ejecuté el flujo de trabajo y funcionó! ¿Cómo es eso una prueba?" + +¡Buena pregunta! + +Analicemos lo que acaba de suceder. + +Ejecutó el flujo de trabajo con los parámetros predeterminados, confirmó que funcionó y está satisfecho con los resultados. Esta es la esencia de las pruebas. Si trabajó en el curso de entrenamiento Hello Nextflow, habrá notado que siempre comenzamos cada sección ejecutando el flujo de trabajo que estábamos usando como punto de partida, para confirmar que todo está configurado correctamente. + +Las pruebas de software esencialmente hacen este proceso por nosotros. + +#### Revisar la asignación + +Su desafío es agregar pruebas estandarizadas a este flujo de trabajo usando nf-test, con el fin de facilitar la verificación de que cada parte continúa funcionando como se espera en caso de que se realicen cambios adicionales. + +<!-- TODO: give a bit more details, similar to how it's done in the Metadata side quest --> + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está en funcionamiento +- [ ] He configurado mi directorio de trabajo adecuadamente +- [ ] He ejecutado el flujo de trabajo exitosamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Inicializar `nf-test` + +El paquete `nf-test` proporciona un comando de inicialización que configura algunas cosas para que podamos comenzar a desarrollar pruebas para nuestro proyecto. + +```bash +nf-test init +``` + +Esto debería producir la siguiente salida: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +También crea un directorio `tests` que contiene un esquema de archivo de configuración. + +### 1.1. Generar un nf-test + +`nf-test` viene con un conjunto de herramientas para construir archivos nf-test, ahorrándonos la mayor parte del trabajo. Estos vienen bajo el subcomando `generate`. Generemos una prueba para el pipeline: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Salida" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Esto creará un archivo `main.nf.test` dentro del directorio `tests`. Este es nuestro archivo de prueba a nivel de pipeline. Si ejecuta `tree tests/` debería ver algo como esto: + +```console title="Contenidos del directorio de pruebas" +tests/ +├── main.nf.test +└── nextflow.config +``` + +El archivo `main.nf.test` es nuestro archivo de prueba a nivel de pipeline. Abramos y veamos el contenido. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Tomaremos un segundo para entender la estructura del archivo de prueba. + +El bloque `nextflow_pipeline` es el punto de entrada para todas las pruebas a nivel de pipeline. Contiene lo siguiente: + +- `name`: El nombre de la prueba. +- `script`: La ruta al script del pipeline. + +El bloque `test` es la prueba real. Contiene lo siguiente: + +- `when`: Las condiciones bajo las cuales se debe ejecutar la prueba. Esto incluye los parámetros que se utilizarán para ejecutar el pipeline. +- `then`: Las aserciones que se deben hacer. Esto incluye los resultados esperados del pipeline. + +En español claro, la lógica de la prueba se lee de la siguiente manera: +"**Cuando** se proporcionan estos _parámetros_ a este _pipeline_, **entonces** esperamos ver estos resultados." + +Esta no es una prueba funcional, demostraremos cómo convertirla en una en la siguiente sección. + +### Una nota sobre los nombres de las pruebas + +En el ejemplo anterior, utilizamos el nombre predeterminado "Should run without failures" (Debería ejecutarse sin fallos) que es apropiado para una prueba básica que solo verifica si el pipeline se ejecuta correctamente. Sin embargo, a medida que agregamos casos de prueba más específicos, debemos usar nombres más descriptivos que indiquen lo que realmente estamos probando. Por ejemplo: + +- "Should convert input to uppercase" - cuando se prueba funcionalidad específica +- "Should handle empty input gracefully" - cuando se prueban casos extremos +- "Should respect max memory parameter" - cuando se prueban restricciones de recursos +- "Should create expected output files" - cuando se prueba la generación de archivos + +Los buenos nombres de prueba deben: + +1. Comenzar con "Should" para dejar claro cuál es el comportamiento esperado +2. Describir la funcionalidad específica o el escenario que se está probando +3. Ser lo suficientemente claros como para que si la prueba falla, sepa qué funcionalidad está rota + +A medida que agreguemos más aserciones y casos de prueba específicos más adelante, usaremos estos nombres más descriptivos para dejar claro qué está verificando cada prueba. + +### 1.2. Ejecutar la prueba + +Ejecutemos la prueba para ver qué sucede. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="fallo de pipeline nf-test" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +¡La prueba falla! ¿Qué sucedió? + +1. nf-test intentó ejecutar el pipeline tal como está, usando la configuración en el bloque `when`: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test verificó el estado del pipeline y lo comparó con el bloque `when`: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Observe cómo nf-test ha reportado que el pipeline falló y proporcionó el mensaje de error de Nextflow: + +```console title="Error" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Entonces, ¿cuál fue el problema? Recuerde que el pipeline tiene un archivo greetings.csv en el directorio del proyecto. Cuando nf-test ejecuta el pipeline, buscará este archivo, pero no puede encontrarlo. El archivo está ahí, ¿qué está pasando? Bueno, si miramos la ruta, podemos ver que la prueba está ocurriendo en la ruta `./nf-test/tests/longHashString/`. Al igual que Nextflow, nf-test crea un nuevo directorio para cada prueba para mantener todo aislado. El archivo de datos no se encuentra allí, por lo que debemos corregir la ruta al archivo en la prueba original. + +Puede estar preguntándose cómo vamos a apuntar a la raíz del pipeline en la prueba. Dado que esta es una situación común, nf-test tiene una gama de variables globales que podemos usar para facilitarnos la vida. Puede encontrar la lista completa [aquí](https://www.nf-test.com/docs/testcases/global_variables/) pero mientras tanto usaremos la variable `projectDir`, que significa la raíz del proyecto del pipeline. + +_Antes:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Después:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Ejecutemos la prueba nuevamente para ver si funciona. + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="El pipeline pasa" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +¡Éxito! El pipeline se ejecuta correctamente y la prueba pasa. ¡Ejecútelo tantas veces como desee y siempre obtendrá el mismo resultado! + +Por defecto, la salida de Nextflow está oculta, pero para convencerse de que nf-test definitivamente está ejecutando el flujo de trabajo, puede usar la bandera `--verbose`: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="El pipeline ejecuta todos los procesos" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Agregar aserciones + +Una verificación simple es asegurarse de que nuestro pipeline esté ejecutando todos los procesos que esperamos y no omitiendo ninguno silenciosamente. Recuerde que nuestro pipeline ejecuta 6 procesos, uno llamado `sayHello` y uno llamado `convertToUpper` para cada uno de los 3 saludos. + +Agreguemos una aserción a nuestra prueba para verificar que el pipeline ejecute el número esperado de procesos. También actualizaremos el nombre de nuestra prueba para reflejar mejor lo que estamos probando. + +**Antes:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Después:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +El nombre de la prueba ahora refleja mejor lo que realmente estamos verificando: no solo que el pipeline se ejecute sin fallar, sino que ejecute el número esperado de procesos. + +Ejecutemos la prueba nuevamente para ver si funciona. + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="El pipeline pasa con aserciones" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +¡Éxito! El pipeline se ejecuta correctamente y la prueba pasa. Ahora hemos comenzado a probar los detalles del pipeline, así como el estado general. + +### 1.4. Probar la salida + +Agreguemos una aserción a nuestra prueba para verificar que se creó el archivo de salida. Lo agregaremos como una prueba separada, con un nombre informativo, para que los resultados sean más fáciles de interpretar. + +**Antes:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Después:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Ejecute la prueba nuevamente para ver si funciona. + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="El pipeline pasa con aserciones de archivos" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +¡Éxito! Las pruebas pasan porque el pipeline se completó correctamente, se ejecutó el número correcto de procesos y se crearon los archivos de salida. Esto también debería mostrarle lo útil que es proporcionar esos nombres informativos para sus pruebas. + +Esto es solo la superficie, podemos seguir escribiendo aserciones para verificar los detalles del pipeline, pero por ahora pasemos a probar los componentes internos del pipeline. + +### Conclusión + +Sabe cómo escribir un nf-test para un pipeline. + +### ¿Qué sigue? + +Aprenda cómo probar un proceso de Nextflow. + +--- + +## 2. Probar un proceso de Nextflow + +No tenemos que escribir pruebas para cada parte del pipeline, pero cuantas más pruebas tengamos, más integrales podemos ser sobre el pipeline y más confiados podemos estar de que está funcionando como se espera. En esta sección vamos a probar ambos procesos en el pipeline como unidades individuales. + +### 2.1. Probar el proceso `sayHello` + +Comencemos con el proceso `sayHello`. + +Usemos el comando `nf-test generate` nuevamente para generar pruebas para el proceso. + +```bash +nf-test generate process main.nf +``` + +```console title="Salida" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Centrémonos por ahora en el proceso `sayhello` en el archivo `main.sayhello.nf.test`. + +Abramos el archivo y veamos el contenido. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Como antes, comenzamos con los detalles de la prueba, seguidos de los bloques `when` y `then`. Sin embargo, también tenemos un bloque `process` adicional que nos permite definir las entradas al proceso. + +Ejecutemos la prueba para ver si funciona. + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Falla la prueba del proceso" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +La prueba falla porque el proceso `sayHello` declara 1 entrada pero fue llamado con 0 argumentos. Arreglemos eso agregando una entrada al proceso. Recuerde de [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (y la sección de calentamiento anterior) que nuestro proceso `sayHello` toma una sola entrada de valor, que necesitaremos proporcionar. También deberíamos corregir el nombre de la prueba para reflejar mejor lo que estamos probando. + +**Antes:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Después:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Ejecutemos la prueba nuevamente para ver si funciona. + +```console title="pasa pipeline nf-test" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +¡Éxito! La prueba pasa porque el proceso `sayHello` se ejecutó correctamente y se creó la salida. + +### 2.2. Revisar la instantánea creada por la prueba + +Si miramos el archivo `tests/main.sayhello.nf.test`, podemos ver que usa un método `snapshot()` en el bloque de aserción: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Esto le está diciendo a nf-test que cree una instantánea de la salida del proceso `sayHello`. Echemos un vistazo al contenido del archivo de instantánea. + +```console title="Contenido del archivo de instantánea" +code tests/main.sayhello.nf.test.snap +``` + +No lo imprimiremos aquí, pero debería ver un archivo JSON que contiene detalles del proceso y las salidas del proceso. En particular, podemos ver una línea que se ve así: + +```json title="Contenido del archivo de instantánea" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Esto representa las salidas creadas por el proceso `sayHello`, que estamos probando explícitamente. Si volvemos a ejecutar la prueba, el programa verificará que la nueva salida coincida con la salida que se registró originalmente. Esta es una forma rápida y simple de probar que las salidas del proceso no cambien, por lo que nf-test la proporciona como predeterminada. + +!!!warning + + ¡Eso significa que debemos estar seguros de que la salida que registramos en la ejecución original es correcta! + +Si, en el curso del desarrollo futuro, algo en el código cambia que hace que la salida sea diferente, la prueba fallará y tendremos que determinar si el cambio es esperado o no. + +- Si resulta que algo en el código se rompió, tendremos que arreglarlo, con la expectativa de que el código corregido pasará la prueba. +- Si es un cambio esperado (por ejemplo, la herramienta se ha mejorado y los resultados son mejores) entonces necesitaremos actualizar la instantánea para aceptar la nueva salida como referencia para coincidir. nf-test tiene un parámetro `--update-snapshot` para este propósito. + +Podemos ejecutar la prueba nuevamente y ver que la prueba debería pasar: + +```console title="pasa proceso nf-test con instantánea" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +¡Éxito! La prueba pasa porque el proceso `sayHello` se ejecutó correctamente y la salida coincidió con la instantánea. + +### 2.3. Alternativa a las instantáneas: aserciones de contenido directo + +Si bien las instantáneas son excelentes para detectar cualquier cambio en la salida, a veces desea verificar contenido específico sin ser tan estricto sobre que todo el archivo coincida. Por ejemplo: + +- Cuando partes de la salida pueden cambiar (marcas de tiempo, IDs aleatorios, etc.) pero cierto contenido clave debe estar presente +- Cuando desea verificar patrones o valores específicos en la salida +- Cuando desea hacer que la prueba sea más explícita sobre qué constituye el éxito + +Aquí está cómo podríamos modificar nuestra prueba para verificar contenido específico: + +**Antes:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Después:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Tenga en cuenta que nf-test ve las salidas del proceso como una lista de listas, por lo que `process.out[0][0]` está obteniendo la primera parte del primer elemento del canal (o 'emisión') de este proceso. + +Este enfoque: + +- Deja claro exactamente qué esperamos en la salida +- Es más resistente a cambios irrelevantes en la salida +- Proporciona mejores mensajes de error cuando las pruebas fallan +- Permite validaciones más complejas (patrones regex, comparaciones numéricas, etc.) + +Ejecutemos la prueba para ver si funciona. + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Falla la prueba del proceso" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Probar el proceso `convertToUpper` + +Abramos el archivo `tests/main.converttoupper.nf.test` y veamos el contenido: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Esta es una prueba similar al proceso `sayHello`, pero está probando el proceso `convertToUpper`. Sabemos que este fallará porque al igual que con `sayHello`, el proceso `convertToUpper` toma una sola entrada de ruta, pero no hemos especificado una. + +Ahora necesitamos proporcionar un solo archivo de entrada al proceso convertToUpper, que incluye algo de texto que queremos convertir a mayúsculas. Hay muchas formas en que podríamos hacer esto: + +- Podríamos crear un archivo dedicado para probar +- Podríamos reutilizar el archivo data/greetings.csv existente +- Podríamos crearlo sobre la marcha dentro de la prueba + +Por ahora, reutilicemos el archivo data/greetings.csv existente usando el ejemplo que usamos con la prueba a nivel de pipeline. Como antes, podemos nombrar la prueba para reflejar mejor lo que estamos probando, pero esta vez dejemos que tome una 'instantánea' del contenido en lugar de verificar cadenas específicas (como hicimos en el otro proceso). + +**Antes:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Después:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +¡Y ejecutar la prueba! + +```bash title="pasa pipeline nf-test" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="pasa proceso convertToUpper nf-test" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Tenga en cuenta que hemos creado un archivo de instantánea para el proceso `convertToUpper` en `tests/main.converttoupper.nf.test.snap`. Si ejecutamos la prueba nuevamente, deberíamos ver que nf-test pasa nuevamente. + +```bash title="pasa proceso convertToUpper nf-test" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="pasa proceso convertToUpper nf-test" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Conclusión + +Sabe cómo escribir pruebas para un proceso de Nextflow y ejecutarlas. + +### ¿Qué sigue? + +¡Aprenda cómo ejecutar pruebas para todo a la vez! + +## 3. Ejecutar pruebas para todo el repositorio + +Ejecutar nf-test en cada componente está bien, pero es laborioso y propenso a errores. ¿No podemos simplemente probar todo a la vez? + +¡Sí podemos! + +Ejecutemos nf-test en todo el repositorio. + +### 3.1. Ejecutar nf-test en todo el repositorio + +Podemos ejecutar nf-test en todo el repositorio ejecutando el comando `nf-test test`. + +```bash +nf-test test . +``` + +Tenga en cuenta que solo estamos usando el `.` para ejecutar todo desde nuestro directorio actual. ¡Esto incluirá cada prueba! + +```console title="pasa repositorio nf-test" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +¡Mire eso! Ejecutamos 4 pruebas, 1 para cada proceso y 2 para todo el pipeline con un solo comando. ¡Imagine lo poderoso que es esto en una base de código grande! + +--- + +## Resumen + +En esta misión secundaria, ha aprendido a aprovechar las características de nf-test para crear y ejecutar pruebas para procesos individuales, así como pruebas de extremo a extremo para todo el pipeline. +Ahora conoce los dos enfoques principales para la validación de salida, instantáneas y aserciones de contenido directo, y cuándo usar cada uno. +También sabe cómo ejecutar pruebas ya sea una por una o para un proyecto completo. + +Aplicar estas técnicas en su propio trabajo le permitirá asegurarse de que: + +- Su código funcione como se espera +- Los cambios no rompan la funcionalidad existente +- Otros desarrolladores puedan contribuir con confianza +- Los problemas puedan identificarse y solucionarse rápidamente +- El contenido de salida coincida con las expectativas + +### Patrones clave + +<!-- TODO: Can we add snippets of code below to illustrate? --> + +1. Pruebas a nivel de pipeline: + - Pruebas básicas de éxito + - Verificación del conteo de procesos + - Verificaciones de existencia de archivos de salida +2. Pruebas a nivel de proceso +3. Dos enfoques para la validación de salida: + - Usar instantáneas para verificación completa de salida + - Usar aserciones de contenido directo para verificaciones de contenido específico +4. Ejecutar todas las pruebas en un repositorio con un solo comando + +### Recursos adicionales + +Consulte la [documentación de nf-test](https://www.nf-test.com/) para características de prueba más avanzadas y mejores prácticas. Puede que desee: + +- Agregar aserciones más completas a sus pruebas +- Escribir pruebas para casos extremos y condiciones de error +- Configurar integración continua para ejecutar pruebas automáticamente +- Aprender sobre otros tipos de pruebas como pruebas de flujo de trabajo y módulo +- Explorar técnicas más avanzadas de validación de contenido + +**Recuerde:** Las pruebas son documentación viva de cómo debería comportarse su código. Cuantas más pruebas escriba, y cuanto más específicas sean sus aserciones, más confiado puede estar en la confiabilidad de su pipeline. + +--- + +## ¿Qué sigue? + +Regrese al [menú de Misiones Secundarias](./index.md) o haga clic en el botón en la parte inferior derecha de la página para pasar al siguiente tema de la lista. diff --git a/docs/es/docs/side_quests/orientation.md b/docs/es/docs/side_quests/orientation.md new file mode 100644 index 0000000000..bdcbf5c772 --- /dev/null +++ b/docs/es/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +El entorno de GitHub Codespaces contiene todo el software, código y datos necesarios para completar este curso de entrenamiento, por lo que no necesita instalar nada usted mismo. +Sin embargo, necesita una cuenta (gratuita) para iniciar sesión, y debería tomarse unos minutos para familiarizarse con la interfaz. + +Si aún no lo ha hecho, por favor siga [este enlace](../../envsetup/) antes de continuar. + +## Materiales proporcionados + +A lo largo de este curso de entrenamiento, trabajaremos en el directorio `side-quests/`. +Este directorio contiene todos los archivos de código, datos de prueba y archivos accesorios que necesitará. + +Siéntase libre de explorar los contenidos de este directorio; la forma más fácil de hacerlo es usar el explorador de archivos en el lado izquierdo del espacio de trabajo de GitHub Codespaces. +Alternativamente, puede usar el comando `tree`. +A lo largo del curso, usamos la salida de `tree` para representar la estructura y contenidos del directorio de forma legible, a veces con modificaciones menores para mayor claridad. + +Aquí generamos una tabla de contenidos hasta el segundo nivel: + +```bash +tree . -L 2 +``` + +Si ejecuta esto dentro de `side-quests`, debería ver la siguiente salida: + +```console title="Contenidos del directorio" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Esto es un resumen de lo que debería saber para comenzar:** + +- **Cada directorio corresponde a una misión secundaria individual.** + Sus contenidos se detallan en la página de la misión secundaria correspondiente. + +- **El directorio `solutions`** contiene los scripts de workflow y/o módulo completados que resultan de ejecutar varios pasos de cada misión secundaria. + Están destinados a ser usados como referencia para verificar su trabajo y solucionar cualquier problema. + +!!!tip "Consejo" + + Si por cualquier razón sale de este directorio, siempre puede ejecutar este comando para regresar a él: + + ```bash + cd /workspaces/training/side-quests + ``` + +Ahora, para comenzar el curso, haga clic en la flecha en la esquina inferior derecha de esta página. diff --git a/docs/es/docs/side_quests/splitting_and_grouping.md b/docs/es/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..59a47c4d8b --- /dev/null +++ b/docs/es/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,1069 @@ +# División y Agrupación + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow proporciona herramientas poderosas para trabajar con datos de manera flexible. Una capacidad clave es dividir datos en diferentes flujos y luego agrupar elementos relacionados. Esto es especialmente valioso en flujos de trabajo bioinformáticos donde necesita procesar diferentes tipos de muestras por separado antes de combinar resultados para el análisis. + +Piense en esto como clasificar correo: separa las cartas por destino, procesa cada pila de manera diferente, luego recombina los elementos que van a la misma persona. Nextflow usa operadores especiales para lograr esto con datos científicos. Este enfoque también se conoce comúnmente como el patrón **scatter/gather** en computación distribuida y flujos de trabajo bioinformáticos. + +El sistema de canales de Nextflow está en el corazón de esta flexibilidad. Los canales conectan diferentes partes de su flujo de trabajo, permitiendo que los datos fluyan a través de su análisis. Puede crear múltiples canales desde una única fuente de datos, procesar cada canal de manera diferente y luego fusionar canales cuando sea necesario. Este enfoque le permite diseñar flujos de trabajo que reflejan naturalmente las rutas ramificadas y convergentes de análisis bioinformáticos complejos. + +### Objetivos de aprendizaje + +En esta misión secundaria, aprenderá a dividir y agrupar datos usando los operadores de canal de Nextflow. +Comenzaremos con un archivo CSV que contiene información de muestras y archivos de datos asociados, luego manipularemos y reorganizaremos estos datos. + +Al final de esta misión secundaria, podrá separar y combinar flujos de datos de manera efectiva, utilizando las siguientes técnicas: + +- Leer datos de archivos usando `splitCsv` +- Filtrar y transformar datos con `filter` y `map` +- Combinar datos relacionados usando `join` y `groupTuple` +- Crear combinaciones de datos con `combine` para procesamiento paralelo +- Optimizar la estructura de datos usando `subMap` y estrategias de deduplicación +- Construir funciones reutilizables con closures nombrados para ayudarle a manipular estructuras de canal + +Estas habilidades le ayudarán a construir flujos de trabajo que pueden manejar múltiples archivos de entrada y diferentes tipos de datos de manera eficiente, mientras mantienen una estructura de código limpia y mantenible. + +### Requisitos previos + +Antes de asumir esta misión secundaria, debe: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso para principiantes equivalente. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores, trabajar con archivos, metadatos) + +**Opcional:** Recomendamos completar primero la misión secundaria [Metadatos en flujos de trabajo](./metadata.md). +Eso cubre los fundamentos de leer archivos CSV con `splitCsv` y crear mapas meta, que usaremos ampliamente aquí. + +--- + +## 0. Comenzar + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en [Configuración del Entorno](../envsetup/index.md). + +[![Abrir en GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/splitting_and_grouping +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un archivo de flujo de trabajo principal y un directorio `data` que contiene una hoja de muestras llamada `samplesheet.csv`. + +```console title="Contenido del directorio" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +La hoja de muestras contiene información sobre muestras de diferentes pacientes, incluyendo el ID del paciente, el número de repetición de la muestra, el tipo (normal o tumor) y rutas a archivos de datos hipotéticos (que en realidad no existen, pero pretenderemos que sí). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Esta hoja de muestras lista ocho muestras de tres pacientes (A, B, C). + +Para cada paciente, tenemos muestras que son de tipo `tumor` (típicamente originadas de biopsias de tumor) o `normal` (tomadas de tejido sano o sangre). +Si no está familiarizado con el análisis de cáncer, solo sepa que esto corresponde a un modelo experimental que usa muestras pareadas tumor/normal para realizar análisis contrastivos. + +Para el paciente A específicamente, tenemos dos conjuntos de réplicas técnicas (repeticiones). + +!!! note + + No se preocupe si no está familiarizado con este diseño experimental, no es crítico para entender este tutorial. + +#### Revisar la asignación + +Su desafío es escribir un flujo de trabajo de Nextflow que: + +1. **Lea** datos de muestras desde un archivo CSV y los estructure con mapas meta +2. **Separe** muestras en diferentes canales según el tipo (normal vs tumor) +3. **Una** pares coincidentes tumor/normal por ID de paciente y número de repetición +4. **Distribuya** muestras a través de intervalos genómicos para procesamiento paralelo +5. **Agrupe** muestras relacionadas para análisis posteriores + +Esto representa un patrón bioinformático común donde necesita dividir datos para procesamiento independiente, luego recombinar elementos relacionados para análisis comparativo. + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Leer datos de muestras + +### 1.1. Leer datos de muestras con `splitCsv` y crear mapas meta + +Comencemos leyendo los datos de muestras con `splitCsv` y organizándolos en el patrón de mapa meta. En el `main.nf`, verá que ya hemos comenzado el flujo de trabajo. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + A lo largo de este tutorial, usaremos el prefijo `ch_` para todas las variables de canal para indicar claramente que son canales de Nextflow. + +Si completó la misión secundaria [Metadatos en flujos de trabajo](./metadata.md), reconocerá este patrón. Usaremos `splitCsv` para leer el CSV y estructurar inmediatamente los datos con un mapa meta para separar metadatos de rutas de archivo. + +!!! info + + Encontraremos dos conceptos diferentes llamados `map` en este entrenamiento: + + - **Estructura de datos**: El map de Groovy (equivalente a diccionarios/hashes en otros lenguajes) que almacena pares clave-valor + - **Operador de canal**: El operador `.map()` que transforma elementos en un canal + + Aclararemos cuál queremos decir en contexto, pero esta distinción es importante para entender cuando se trabaja con Nextflow. + +Aplique estos cambios a `main.nf`: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Esto combina la operación `splitCsv` (leer el CSV con encabezados) y la operación `map` (estructurar datos como tuplas `[meta, file]`) en un solo paso. Aplique ese cambio y ejecute el pipeline: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Ahora tenemos un canal donde cada elemento es una tupla `[meta, file]` - metadatos separados de rutas de archivo. Esta estructura nos permite dividir y agrupar nuestra carga de trabajo según campos de metadatos. + +--- + +## 2. Filtrar y transformar datos + +### 2.1. Filtrar datos con `filter` + +Podemos usar el [operador `filter`](https://www.nextflow.io/docs/latest/operator.html#filter) para filtrar los datos según una condición. Digamos que solo queremos procesar muestras normales. Podemos hacer esto filtrando los datos según el campo `type`. Insertemos esto antes del operador `view`. + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Ejecute el flujo de trabajo nuevamente para ver el resultado filtrado: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Hemos filtrado exitosamente los datos para incluir solo muestras normales. Recapitulemos cómo funciona esto. + +El operador `filter` toma un closure que se aplica a cada elemento en el canal. Si el closure devuelve `true`, el elemento se incluye; si devuelve `false`, el elemento se excluye. + +En nuestro caso, queremos mantener solo las muestras donde `meta.type == 'normal'`. El closure usa la tupla `meta,file` para referirse a cada muestra, accede al tipo de muestra con `meta.type`, y verifica si es igual a `'normal'`. + +Esto se logra con el único closure que introducimos arriba: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Crear canales filtrados separados + +Actualmente estamos aplicando el filtro al canal creado directamente desde el CSV, pero queremos filtrar esto de más de una manera, así que reescribamos la lógica para crear un canal filtrado separado para muestras normales: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Ejecute el pipeline para ver los resultados: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Hemos filtrado exitosamente los datos y creado un canal separado para muestras normales. + +Creemos también un canal filtrado para las muestras de tumor: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Hemos separado las muestras normales y de tumor en dos canales diferentes, y usamos un closure proporcionado a `view()` para etiquetarlas de manera diferente en la salida: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Conclusión + +En esta sección, ha aprendido: + +- **Filtrar datos**: Cómo filtrar datos con `filter` +- **Dividir datos**: Cómo dividir datos en diferentes canales según una condición +- **Visualizar datos**: Cómo usar `view` para imprimir los datos y etiquetar salidas de diferentes canales + +Ahora hemos separado las muestras normales y de tumor en dos canales diferentes. A continuación, uniremos las muestras normales y de tumor en el campo `id`. + +--- + +## 3. Unir canales por identificadores + +En la sección anterior, separamos las muestras normales y de tumor en dos canales diferentes. Estos podrían procesarse independientemente usando procesos o flujos de trabajo específicos según su tipo. Pero, ¿qué sucede cuando queremos comparar las muestras normales y de tumor del mismo paciente? En este punto, necesitamos unirlas asegurándonos de emparejar las muestras según su campo `id`. + +Nextflow incluye muchos métodos para combinar canales, pero en este caso el operador más apropiado es [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Si está familiarizado con SQL, actúa como la operación `JOIN`, donde especificamos la clave para unir y el tipo de unión a realizar. + +### 3.1. Usar `map` y `join` para combinar según ID de paciente + +Si revisamos la documentación de [`join`](https://www.nextflow.io/docs/latest/operator.html#join), podemos ver que por defecto une dos canales según el primer elemento en cada tupla. + +#### 3.1.1. Verificar la estructura de datos + +Si no tiene la salida de consola todavía disponible, ejecutemos el pipeline para verificar nuestra estructura de datos y ver cómo necesitamos modificarla para unir en el campo `id`. + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Podemos ver que el campo `id` es el primer elemento en cada mapa meta. Para que `join` funcione, deberíamos aislar el campo `id` en cada tupla. Después de eso, simplemente podemos usar el operador `join` para combinar los dos canales. + +#### 3.1.2. Aislar el campo `id` + +Para aislar el campo `id`, podemos usar el [operador `map`](https://www.nextflow.io/docs/latest/operator.html#map) para crear una nueva tupla con el campo `id` como primer elemento. + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Puede ser sutil, pero debería poder ver que el primer elemento en cada tupla es el campo `id`. + +#### 3.1.3. Combinar los dos canales + +Ahora podemos usar el operador `join` para combinar los dos canales según el campo `id`. + +Una vez más, usaremos `view` para imprimir las salidas unidas. + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Es un poco difícil de ver porque es muy ancho, pero debería poder ver que las muestras se han unido por el campo `id`. Cada tupla ahora tiene el formato: + +- `id`: El ID de muestra +- `normal_meta_map`: Los metadatos de la muestra normal incluyendo tipo, réplica y ruta al archivo bam +- `normal_sample_file`: El archivo de muestra normal +- `tumor_meta_map`: Los metadatos de la muestra de tumor incluyendo tipo, réplica y ruta al archivo bam +- `tumor_sample`: La muestra de tumor incluyendo tipo, réplica y ruta al archivo bam + +!!! warning + + El operador `join` descartará cualquier tupla no emparejada. En este ejemplo, nos aseguramos de que todas las muestras estuvieran emparejadas para tumor y normal, pero si esto no es cierto debe usar el parámetro `remainder: true` para mantener las tuplas no emparejadas. Consulte la [documentación](https://www.nextflow.io/docs/latest/operator.html#join) para más detalles. + +Así que ahora sabe cómo usar `map` para aislar un campo en una tupla, y cómo usar `join` para combinar tuplas según el primer campo. +Con este conocimiento, podemos combinar exitosamente canales según un campo compartido. + +A continuación, consideraremos la situación donde desea unir en múltiples campos. + +### 3.2. Unir en múltiples campos + +Tenemos 2 réplicas para sampleA, pero solo 1 para sampleB y sampleC. En este caso pudimos unirlas efectivamente usando el campo `id`, pero ¿qué pasaría si estuvieran fuera de sincronización? ¡Podríamos mezclar las muestras normales y de tumor de diferentes réplicas! + +Para evitar esto, podemos unir en múltiples campos. Realmente hay múltiples formas de lograr esto, pero nos vamos a enfocar en crear una nueva clave de unión que incluya tanto el `id` de muestra como el número de `replicate`. + +Comencemos creando una nueva clave de unión. Podemos hacer esto de la misma manera que antes usando el [operador `map`](https://www.nextflow.io/docs/latest/operator.html#map) para crear una nueva tupla con los campos `id` y `repeat` como primer elemento. + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Ahora deberíamos ver que la unión está ocurriendo pero usando tanto los campos `id` como `repeat`. Ejecute el flujo de trabajo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Note cómo tenemos una tupla de dos elementos (campos `id` y `repeat`) como el primer elemento de cada resultado unido. Esto demuestra cómo elementos complejos pueden usarse como clave de unión, permitiendo emparejamientos bastante intrincados entre muestras de las mismas condiciones. + +Si desea explorar más formas de unir en diferentes claves, consulte la [documentación del operador join](https://www.nextflow.io/docs/latest/operator.html#join) para opciones y ejemplos adicionales. + +### 3.3. Usar `subMap` para crear una nueva clave de unión + +El enfoque anterior pierde los nombres de campo de nuestra clave de unión - los campos `id` y `repeat` se convierten solo en una lista de valores. Para retener los nombres de campo para acceso posterior, podemos usar el [método `subMap`](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>). + +El método `subMap` extrae solo los pares clave-valor especificados de un map. Aquí extraeremos solo los campos `id` y `repeat` para crear nuestra clave de unión. + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Ahora tenemos una nueva clave de unión que no solo incluye los campos `id` y `repeat` sino que también retiene los nombres de campo para que podamos accederlos más tarde por nombre, por ejemplo `meta.id` y `meta.repeat`. + +### 3.4. Usar un closure nombrado en map + +Para evitar duplicación y reducir errores, podemos usar un closure nombrado. Un closure nombrado nos permite crear una función reutilizable que podemos llamar en múltiples lugares. + +Para hacerlo, primero definimos el closure como una nueva variable: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Hemos definido la transformación map como una variable nombrada que podemos reutilizar. + +Note que también convertimos la ruta del archivo a un objeto Path usando `file()` para que cualquier proceso que reciba este canal pueda manejar el archivo correctamente (para más información vea [Trabajar con archivos](./working_with_files.md)). + +Implementemos el closure en nuestro flujo de trabajo: + +=== "Después" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + El operador `map` ha cambiado de usar `{ }` a usar `( )` para pasar el closure como argumento. Esto es porque el operador `map` espera un closure como argumento y `{ }` se usa para definir un closure anónimo. Al llamar un closure nombrado, use la sintaxis `( )`. + +Ejecute el flujo de trabajo una vez más para verificar que todo sigue funcionando: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Usar un closure nombrado nos permite reutilizar la misma transformación en múltiples lugares, reduciendo el riesgo de errores y haciendo el código más legible y mantenible. + +### 3.5. Reducir duplicación de datos + +Tenemos muchos datos duplicados en nuestro flujo de trabajo. Cada elemento en las muestras unidas repite los campos `id` y `repeat`. Dado que esta información ya está disponible en la clave de agrupación, podemos evitar esta redundancia. Como recordatorio, nuestra estructura de datos actual se ve así: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Dado que los campos `id` y `repeat` están disponibles en la clave de agrupación, eliminémoslos del resto de cada elemento del canal para evitar duplicación. Podemos hacer esto usando el método `subMap` para crear un nuevo map con solo el campo `type`. Este enfoque nos permite mantener toda la información necesaria mientras eliminamos la redundancia en nuestra estructura de datos. + +=== "Después" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Ahora el closure devuelve una tupla donde el primer elemento contiene los campos `id` y `repeat`, y el segundo elemento contiene solo el campo `type`. Esto elimina la redundancia almacenando la información de `id` y `repeat` una vez en la clave de agrupación, mientras mantiene toda la información necesaria. + +Ejecute el flujo de trabajo para ver cómo se ve esto: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Podemos ver que solo declaramos los campos `id` y `repeat` una vez en la clave de agrupación y tenemos el campo `type` en los datos de muestra. No hemos perdido ninguna información pero logramos hacer el contenido de nuestro canal más sucinto. + +### 3.6. Eliminar información redundante + +Eliminamos información duplicada arriba, pero todavía tenemos alguna otra información redundante en nuestros canales. + +Al principio, separamos las muestras normales y de tumor usando `filter`, luego las unimos según las claves `id` y `repeat`. El operador `join` preserva el orden en que se fusionan las tuplas, así que en nuestro caso, con muestras normales en el lado izquierdo y muestras de tumor en el derecho, el canal resultante mantiene esta estructura: `id, <elementos normales>, <elementos tumor>`. + +Dado que conocemos la posición de cada elemento en nuestro canal, podemos simplificar aún más la estructura eliminando los metadatos `[type:normal]` y `[type:tumor]`. + +=== "Después" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Ejecute nuevamente para ver el resultado: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Conclusión + +En esta sección, ha aprendido: + +- **Manipular Tuplas**: Cómo usar `map` para aislar un campo en una tupla +- **Unir Tuplas**: Cómo usar `join` para combinar tuplas según el primer campo +- **Crear Claves de Unión**: Cómo usar `subMap` para crear una nueva clave de unión +- **Closures Nombrados**: Cómo usar un closure nombrado en map +- **Unión de Múltiples Campos**: Cómo unir en múltiples campos para emparejamiento más preciso +- **Optimización de Estructura de Datos**: Cómo simplificar la estructura del canal eliminando información redundante + +Ahora tiene un flujo de trabajo que puede dividir una hoja de muestras, filtrar las muestras normales y de tumor, unirlas por ID de muestra y número de réplica, luego imprimir los resultados. + +Este es un patrón común en flujos de trabajo bioinformáticos donde necesita emparejar muestras u otros tipos de datos después de procesar independientemente, por lo que es una habilidad útil. A continuación, veremos cómo repetir una muestra múltiples veces. + +## 4. Distribuir muestras por intervalos + +Un patrón clave en flujos de trabajo bioinformáticos es distribuir análisis a través de regiones genómicas. Por ejemplo, el llamado de variantes puede paralelizarse dividiendo el genoma en intervalos (como cromosomas o regiones más pequeñas). Esta estrategia de paralelización mejora significativamente la eficiencia del pipeline al distribuir la carga computacional entre múltiples núcleos o nodos, reduciendo el tiempo total de ejecución. + +En la siguiente sección, demostraremos cómo distribuir nuestros datos de muestras a través de múltiples intervalos genómicos. Emparejaremos cada muestra con cada intervalo, permitiendo procesamiento paralelo de diferentes regiones genómicas. Esto multiplicará el tamaño de nuestro conjunto de datos por el número de intervalos, creando múltiples unidades de análisis independientes que pueden volver a reunirse más tarde. + +### 4.1. Distribuir muestras sobre intervalos usando `combine` + +Comencemos creando un canal de intervalos. Para mantener la vida simple, solo usaremos 3 intervalos que definiremos manualmente. En un flujo de trabajo real, podría leerlos desde una entrada de archivo o incluso crear un canal con muchos archivos de intervalo. + +=== "Después" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Ahora recuerde, queremos repetir cada muestra para cada intervalo. Esto a veces se denomina producto cartesiano de las muestras e intervalos. Podemos lograr esto usando el [operador `combine`](https://www.nextflow.io/docs/latest/operator.html#combine). Esto tomará cada elemento del canal 1 y lo repetirá para cada elemento en el canal 2. Agreguemos un operador combine a nuestro flujo de trabajo: + +=== "Después" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Ahora ejecutémoslo y veamos qué sucede: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +¡Éxito! Hemos repetido cada muestra para cada intervalo en nuestra lista de 3 intervalos. Efectivamente hemos triplicado el número de elementos en nuestro canal. + +Es un poco difícil de leer, así que en la siguiente sección lo ordenaremos. + +### 4.2. Organizar el canal + +Podemos usar el operador `map` para ordenar y refactorizar nuestros datos de muestra para que sea más fácil de entender. Movamos la cadena de intervalos al map de unión en el primer elemento. + +=== "Después" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Desglosemos qué hace esta operación map paso a paso. + +Primero, usamos parámetros nombrados para hacer el código más legible. Al usar los nombres `grouping_key`, `normal`, `tumor` e `interval`, podemos referirnos a los elementos en la tupla por nombre en lugar de por índice: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +A continuación, combinamos el `grouping_key` con el campo `interval`. El `grouping_key` es un map que contiene campos `id` y `repeat`. Creamos un nuevo map con el `interval` y los fusionamos usando la adición de map de Groovy (`+`): + +```groovy + grouping_key + [interval: interval], +``` + +Finalmente, devolvemos esto como una tupla con tres elementos: el map de metadatos combinado, el archivo de muestra normal y el archivo de muestra de tumor: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Ejecutémoslo nuevamente y verifiquemos el contenido del canal: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Usar `map` para coaccionar sus datos a la estructura correcta puede ser complicado, pero es crucial para la manipulación efectiva de datos. + +Ahora tenemos cada muestra repetida en todos los intervalos genómicos, creando múltiples unidades de análisis independientes que pueden procesarse en paralelo. ¿Pero qué pasa si queremos volver a reunir muestras relacionadas? En la siguiente sección, aprenderemos cómo agrupar muestras que comparten atributos comunes. + +### Conclusión + +En esta sección, ha aprendido: + +- **Distribuir muestras sobre intervalos**: Cómo usar `combine` para repetir muestras sobre intervalos +- **Crear productos cartesianos**: Cómo generar todas las combinaciones de muestras e intervalos +- **Organizar estructura de canal**: Cómo usar `map` para reestructurar datos para mejor legibilidad +- **Preparación para procesamiento paralelo**: Cómo configurar datos para análisis distribuido + +## 5. Agregar muestras usando `groupTuple` + +En las secciones anteriores, aprendimos cómo dividir datos de un archivo de entrada y filtrar por campos específicos (en nuestro caso muestras normales y de tumor). Pero esto solo cubre un tipo de unión. ¿Qué pasa si queremos agrupar muestras por un atributo específico? Por ejemplo, en lugar de unir pares coincidentes normal-tumor, podríamos querer procesar todas las muestras de "sampleA" juntas independientemente de su tipo. Este patrón es común en flujos de trabajo bioinformáticos donde puede querer procesar muestras relacionadas por separado por razones de eficiencia antes de comparar o combinar los resultados al final. + +Nextflow incluye métodos integrados para hacer esto, el principal que veremos es `groupTuple`. + +Comencemos agrupando todas nuestras muestras que tienen los mismos campos `id` e `interval`, esto sería típico de un análisis donde quisiéramos agrupar réplicas técnicas pero mantener muestras significativamente diferentes separadas. + +Para hacer esto, debemos separar nuestras variables de agrupación para que podamos usarlas en aislamiento. + +El primer paso es similar a lo que hicimos en la sección anterior. Debemos aislar nuestra variable de agrupación como el primer elemento de la tupla. Recuerde, nuestro primer elemento es actualmente un map de campos `id`, `repeat` e `interval`: + +```groovy title="main.nf" linenums="1" +{ + "id": "sampleA", + "repeat": "1", + "interval": "chr1" +} +``` + +Podemos reutilizar el método `subMap` de antes para aislar nuestros campos `id` e `interval` del map. Como antes, usaremos el operador `map` para aplicar el método `subMap` al primer elemento de la tupla para cada muestra. + +=== "Después" + + ```groovy title="main.nf" linenums="20" hl_lines="11-19" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="20" hl_lines="10" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +Ejecutémoslo nuevamente y verifiquemos el contenido del canal: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [hopeful_brenner] DSL2 - revision: 7f4f7fea76 + + [[id:patientA, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, interval:chr1], patientB_rep1_normal.bam, diff --git a/docs/es/docs/side_quests/workflows_of_workflows.md b/docs/es/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..42efba33ca --- /dev/null +++ b/docs/es/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Flujos de trabajo de flujos de trabajo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Cuando está desarrollando un pipeline, a menudo se encuentra creando secuencias similares de procesos para diferentes tipos de datos o pasos de análisis. Podría terminar copiando y pegando estas secuencias de procesos, lo que lleva a código duplicado que es difícil de mantener; o podría crear un flujo de trabajo masivo que es difícil de entender y modificar. + +Una de las características más poderosas de Nextflow es su capacidad para componer pipelines complejos a partir de módulos de flujos de trabajo más pequeños y reutilizables. Este enfoque modular hace que los pipelines sean más fáciles de desarrollar, probar y mantener. + +### Objetivos de aprendizaje + +En esta misión secundaria, exploraremos cómo desarrollar módulos de flujos de trabajo que se pueden probar y usar por separado, componer esos módulos en un pipeline más grande y gestionar el flujo de datos entre módulos. + +Al final de esta misión secundaria, usted podrá: + +- Dividir pipelines complejos en unidades lógicas y reutilizables +- Probar cada módulo de flujo de trabajo de forma independiente +- Mezclar y combinar flujos de trabajo para crear nuevos pipelines +- Compartir módulos de flujos de trabajo comunes entre diferentes pipelines +- Hacer su código más mantenible y más fácil de entender + +Estas habilidades le ayudarán a construir pipelines complejos mientras mantiene una estructura de código limpia y mantenible. + +### Requisitos previos + +Antes de asumir esta misión secundaria debería: + +- Haber completado el tutorial [Hello Nextflow](../hello_nextflow/README.md) o un curso equivalente para principiantes. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, canales, operadores, módulos) + +--- + +## 0. Comenzar + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en [Configuración del Entorno](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/workflows_of_workflows +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un directorio `modules` que contiene varias definiciones de procesos que se basan en lo que aprendió en 'Hello Nextflow': + +```console title="Contenido del directorio" +modules/ +├── say_hello.nf # Crea un saludo (de Hello Nextflow) +├── say_hello_upper.nf # Convierte a mayúsculas (de Hello Nextflow) +├── timestamp_greeting.nf # Agrega marcas de tiempo a los saludos +├── validate_name.nf # Valida nombres de entrada +└── reverse_text.nf # Invierte el contenido del texto +``` + +#### Revisar la asignación + +Su desafío es ensamblar estos módulos en dos flujos de trabajo separados que luego compondremos en un flujo de trabajo principal: + +- Un `GREETING_WORKFLOW` que valida nombres, crea saludos y agrega marcas de tiempo +- Un `TRANSFORM_WORKFLOW` que convierte texto a mayúsculas y lo invierte + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está funcionando +- [ ] He configurado mi directorio de trabajo apropiadamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Crear el flujo de trabajo de saludo + +Comencemos creando un flujo de trabajo que valide nombres y genere saludos con marcas de tiempo. + +### 1.1. Crear la estructura del flujo de trabajo + +```bash title="Crear directorio de flujo de trabajo y archivo" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Agregar el código del primer (sub)flujo de trabajo + +Agregue este código a `workflows/greeting.nf`: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Encadenar procesos: validar -> crear saludo -> agregar marca de tiempo + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Este es un flujo de trabajo completo, con una estructura similar a los que vio en el tutorial 'Hello Nextflow', que podemos probar de forma independiente. Probémoslo ahora: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Esto funciona como se esperaba, pero para hacerlo componible hay algunas cosas que necesitamos cambiar. + +### 1.3. Hacer el flujo de trabajo componible + +Los flujos de trabajo componibles tienen algunas diferencias con respecto a los que vio en el tutorial 'Hello Nextflow': + +- El bloque workflow necesita tener un nombre +- Las entradas se declaran usando la palabra clave `take:` +- El contenido del flujo de trabajo se coloca dentro del bloque `main:` +- Las salidas se declaran usando la palabra clave `emit:` + +Actualicemos el flujo de trabajo de saludo para que coincida con esta estructura. Cambie el código a lo siguiente: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Canal de entrada con nombres + + main: + // Encadenar procesos: validar -> crear saludo -> agregar marca de tiempo + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Saludos originales + timestamped = timestamped_ch // Saludos con marca de tiempo +} +``` + +Puede ver que el flujo de trabajo ahora tiene un nombre y tiene un bloque `take:` y `emit:`, y estas son las conexiones que usaremos para componer un flujo de trabajo de nivel superior. +El contenido del flujo de trabajo también se coloca dentro del bloque `main:`. Note también que hemos eliminado la declaración del canal de entrada `names_ch`, ya que ahora se pasa como argumento al flujo de trabajo. + +Probemos el flujo de trabajo nuevamente para ver si funciona como se esperaba: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Esto le informa sobre otro concepto nuevo, un 'flujo de trabajo de entrada'. El flujo de trabajo de entrada es el flujo de trabajo que se llama cuando ejecuta un script de Nextflow. Por defecto, Nextflow usará un flujo de trabajo sin nombre como flujo de trabajo de entrada, cuando esté presente, y eso es lo que ha estado haciendo hasta ahora, con bloques de flujo de trabajo que comienzan así: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Pero nuestro flujo de trabajo de saludo no tiene un flujo de trabajo sin nombre, sino que tenemos un flujo de trabajo con nombre: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +Por eso Nextflow arrojó un error y no hizo lo que queríamos. + +No agregamos la sintaxis `take:`/`emit:` para poder llamar al flujo de trabajo directamente - lo hicimos para poder componerlo con otros flujos de trabajo. La solución es crear un script principal con un flujo de trabajo de entrada sin nombre que importe y llame a nuestro flujo de trabajo con nombre. + +### 1.4. Crear y probar el flujo de trabajo principal + +Ahora crearemos un flujo de trabajo principal que importa y usa el flujo de trabajo de saludo. + +Crear `main.nf`: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Note que nuestra entrada de flujo de trabajo en este archivo no tiene nombre, y eso es porque vamos a usarla como un flujo de trabajo de entrada. + +Ejecute esto y vea la salida: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +¡Funciona! Hemos envuelto el flujo de trabajo de saludo con nombre en un flujo de trabajo principal con un bloque de entrada `workflow` sin nombre. El flujo de trabajo principal está usando el flujo de trabajo `GREETING_WORKFLOW` casi (no exactamente) como un proceso, y pasando el canal `names` como argumento. + +### Conclusión + +En esta sección, ha aprendido varios conceptos importantes: + +- **Flujos de trabajo con nombre**: Crear un flujo de trabajo con nombre (`GREETING_WORKFLOW`) que puede importarse y reutilizarse +- **Interfaces de flujo de trabajo**: Definir entradas claras con `take:` y salidas con `emit:` para crear un flujo de trabajo componible +- **Puntos de entrada**: Entender que Nextflow necesita un flujo de trabajo de entrada sin nombre para ejecutar un script +- **Composición de flujos de trabajo**: Importar y usar un flujo de trabajo con nombre dentro de otro flujo de trabajo +- **Espacios de nombres de flujo de trabajo**: Acceder a las salidas del flujo de trabajo usando el espacio de nombres `.out` (`GREETING_WORKFLOW.out.greetings`) + +Ahora tiene un flujo de trabajo de saludo funcional que: + +- Toma un canal de nombres como entrada +- Valida cada nombre +- Crea un saludo para cada nombre válido +- Agrega marcas de tiempo a los saludos +- Expone tanto los saludos originales como los que tienen marca de tiempo como salidas + +Este enfoque modular le permite probar el flujo de trabajo de saludo de forma independiente o usarlo como componente en pipelines más grandes. + +--- + +## 2. Agregar el flujo de trabajo de transformación + +Ahora creemos un flujo de trabajo que aplica transformaciones de texto a los saludos. + +### 2.1. Crear el archivo de flujo de trabajo + +```bash +touch workflows/transform.nf +``` + +### 2.2. Agregar el código del flujo de trabajo + +Agregue este código a `workflows/transform.nf`: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Canal de entrada con mensajes + + main: + // Aplicar transformaciones en secuencia + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Saludos en mayúsculas + reversed = reversed_ch // Saludos en mayúsculas invertidos +} +``` + +No repetiremos la explicación de la sintaxis componible aquí, pero note que el flujo de trabajo con nombre se declara nuevamente con un bloque `take:` y `emit:`, y el contenido del flujo de trabajo se coloca dentro del bloque `main:`. + +### 2.3. Actualizar el flujo de trabajo principal + +Actualice `main.nf` para usar ambos flujos de trabajo: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Ejecutar el flujo de trabajo de saludo + GREETING_WORKFLOW(names) + + // Ejecutar el flujo de trabajo de transformación + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Ver resultados + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Ejecute el pipeline completo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Si echa un vistazo a uno de esos archivos invertidos, verá que es la versión en mayúsculas del saludo invertido: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Contenido del archivo invertido" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Conclusión + +Ahora debería tener un pipeline completo que: + +- Procesa nombres a través del flujo de trabajo de saludo +- Alimenta los saludos con marca de tiempo al flujo de trabajo de transformación +- Produce versiones tanto en mayúsculas como invertidas de los saludos + +--- + +## Resumen + +En esta misión secundaria, hemos explorado el poderoso concepto de composición de flujos de trabajo en Nextflow, que nos permite construir pipelines complejos a partir de componentes más pequeños y reutilizables. + +Este enfoque modular ofrece varias ventajas sobre los pipelines monolíticos: + +- Cada flujo de trabajo puede desarrollarse, probarse y depurarse de forma independiente +- Los flujos de trabajo pueden reutilizarse en diferentes pipelines +- La estructura general del pipeline se vuelve más legible y mantenible +- Los cambios en un flujo de trabajo no necesariamente afectan a otros si las interfaces permanecen consistentes +- Los puntos de entrada pueden configurarse para ejecutar diferentes partes de su pipeline según sea necesario + +_Es importante notar sin embargo que aunque llamar flujos de trabajo es un poco como llamar procesos, en realidad no es lo mismo. No puede, por ejemplo, ejecutar un flujo de trabajo N veces llamándolo con un canal de tamaño N - necesitaría pasar un canal de tamaño N al flujo de trabajo e iterar internamente._ + +Aplicar estas técnicas en su propio trabajo le permitirá construir pipelines de Nextflow más sofisticados que puedan manejar tareas bioinformáticas complejas mientras permanecen mantenibles y escalables. + +### Patrones clave + +1. **Estructura de flujo de trabajo**: Definimos entradas y salidas claras para cada flujo de trabajo usando la sintaxis `take:` y `emit:`, creando interfaces bien definidas entre componentes, y envolvimos la lógica del flujo de trabajo dentro del bloque `main:`. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Los canales de entrada se declaran aquí + input_ch + + main: + // La lógica del flujo de trabajo va aquí + // Aquí es donde se llaman los procesos y se manipulan los canales + result_ch = SOME_PROCESS(input_ch) + + emit: + // Los canales de salida se declaran aquí + output_ch = result_ch + } + ``` + +2. **Importaciones de flujos de trabajo:** Construimos dos módulos de flujos de trabajo independientes y los importamos en un pipeline principal con declaraciones include. + + - Incluir un único flujo de trabajo + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Incluir múltiples flujos de trabajo + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Incluir con alias para evitar conflictos de nombres + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Puntos de entrada**: Nextflow requiere un flujo de trabajo de entrada sin nombre para saber dónde comenzar la ejecución. Este flujo de trabajo de entrada llama a sus flujos de trabajo con nombre. + + - Flujo de trabajo sin nombre (punto de entrada) + + ```groovy + workflow { + // Este es el punto de entrada cuando se ejecuta el script + NAMED_WORKFLOW(input_ch) + } + ``` + + - Flujo de trabajo con nombre (llamado desde el flujo de trabajo de entrada) + + ```groovy + workflow NAMED_WORKFLOW { + // Debe ser llamado desde el flujo de trabajo de entrada + } + ``` + +4. **Gestión del flujo de datos:** Aprendimos cómo acceder a las salidas del flujo de trabajo usando la notación de espacio de nombres (`WORKFLOW_NAME.out.channel_name`) y pasarlas a otros flujos de trabajo. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Recursos adicionales + +- [Documentación de Workflow de Nextflow](https://www.nextflow.io/docs/latest/workflow.html) +- [Referencia de Operadores de Canal](https://www.nextflow.io/docs/latest/operator.html) +- [Documentación de Error Strategy](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## ¿Qué sigue? + +Regrese al [menú de Misiones Secundarias](./index.md) o haga clic en el botón en la parte inferior derecha de la página para pasar al siguiente tema de la lista. diff --git a/docs/es/docs/side_quests/working_with_files.md b/docs/es/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..6b8d425cd7 --- /dev/null +++ b/docs/es/docs/side_quests/working_with_files.md @@ -0,0 +1,1307 @@ +# Procesamiento de archivos de entrada + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Los flujos de trabajo de análisis científico a menudo implican el procesamiento de grandes cantidades de archivos. +Nextflow proporciona herramientas poderosas para manejar archivos de manera eficiente, ayudándole a organizar y procesar sus datos con un código mínimo. + +### Objetivos de aprendizaje + +En esta misión secundaria, exploraremos cómo Nextflow maneja archivos, desde operaciones básicas hasta técnicas más avanzadas para trabajar con colecciones de archivos. +Aprenderá cómo extraer metadata de los nombres de archivos, que es un requisito común en los pipelines de análisis científico. + +Al final de esta misión secundaria, podrá: + +- Crear objetos Path a partir de cadenas de rutas de archivo usando el método `file()` de Nextflow +- Acceder a atributos de archivos como nombre, extensión y directorio padre +- Manejar tanto archivos locales como remotos de manera transparente usando URIs +- Usar channels para automatizar el manejo de archivos con `channel.fromPath()` y `channel.fromFilePairs()` +- Extraer y estructurar metadata de los nombres de archivos usando manipulación de cadenas +- Agrupar archivos relacionados usando coincidencia de patrones y expresiones glob +- Integrar operaciones de archivos en procesos de Nextflow con el manejo apropiado de entradas +- Organizar salidas de procesos usando estructuras de directorios basadas en metadata + +Estas habilidades le ayudarán a construir flujos de trabajo que puedan manejar diferentes tipos de entradas de archivos con gran flexibilidad. + +### Requisitos previos + +Antes de emprender esta misión secundaria, debería: + +- Haber completado el tutorial [Hello Nextflow](../../hello_nextflow/) o un curso equivalente para principiantes. +- Sentirse cómodo usando conceptos y mecanismos básicos de Nextflow (procesos, channels, operadores) + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. Primeros pasos + +#### Abrir el codespace de entrenamiento + +Si aún no lo ha hecho, asegúrese de abrir el entorno de entrenamiento como se describe en [Configuración del Entorno](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Moverse al directorio del proyecto + +Vamos a movernos al directorio donde se encuentran los archivos para este tutorial. + +```bash +cd side-quests/working_with_files +``` + +Puede configurar VSCode para enfocarse en este directorio: + +```bash +code . +``` + +#### Revisar los materiales + +Encontrará un archivo de workflow simple llamado `main.nf`, un directorio `modules` que contiene dos archivos de módulos, y un directorio `data` que contiene algunos archivos de datos de ejemplo. + +??? abstract "Contenido del directorio" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Este directorio contiene datos de secuenciación de extremos emparejados de tres pacientes (A, B, C). + +Para cada paciente, tenemos muestras que son de tipo `tumor` (típicamente originadas de biopsias de tumores) o `normal` (tomadas de tejido sano o sangre). +Si no está familiarizado con el análisis de cáncer, solo sepa que esto corresponde a un modelo experimental que usa muestras emparejadas tumor/normal para realizar análisis contrastivos. + +Para el paciente A específicamente, tenemos dos conjuntos de réplicas técnicas (repeticiones). + +Los archivos de datos de secuenciación se nombran con una convención típica `_R1_` y `_R2_` para lo que se conoce como 'lecturas forward' y 'lecturas reverse'. + +_No se preocupe si no está familiarizado con este diseño experimental, no es crítico para entender este tutorial._ + +#### Revisar la asignación + +Su desafío es escribir un workflow de Nextflow que: + +1. **Cargue** archivos de entrada usando los métodos de manejo de archivos de Nextflow +2. **Extraiga** metadata (ID del paciente, réplica, tipo de muestra) de la estructura del nombre de archivo +3. **Agrupe** archivos emparejados (R1/R2) juntos usando `channel.fromFilePairs()` +4. **Procese** los archivos con un módulo de análisis proporcionado +5. **Organice** las salidas en una estructura de directorios basada en la metadata extraída + +#### Lista de verificación de preparación + +¿Cree que está listo para comenzar? + +- [ ] Entiendo el objetivo de este curso y sus requisitos previos +- [ ] Mi codespace está funcionando +- [ ] He establecido mi directorio de trabajo apropiadamente +- [ ] Entiendo la asignación + +Si puede marcar todas las casillas, está listo para comenzar. + +--- + +## 1. Operaciones básicas de archivos + +### 1.1. Identificar el tipo de un objeto con `.class` + +Eche un vistazo al archivo de workflow `main.nf`: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Crear un objeto Path a partir de una ruta de texto + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +Este es un mini-workflow (sin procesos) que hace referencia a una única ruta de archivo en su workflow, luego la imprime en la consola, junto con su clase. + +??? info "¿Qué es `.class`?" + + En Nextflow, `.class` nos dice qué tipo de objeto estamos manejando. Es como preguntar "¿qué tipo de cosa es esto?" para averiguar si es una cadena, un número, un archivo o algo más. + Esto nos ayudará a ilustrar la diferencia entre una cadena simple y un objeto Path en las siguientes secciones. + +Ejecutemos el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Como puede ver, Nextflow imprimió la ruta de cadena exactamente como la escribimos. + +Esto es solo salida de texto; Nextflow aún no ha hecho nada especial con ella. +También hemos confirmado que, hasta donde Nextflow tiene conocimiento, esto es solo una cadena (de clase `java.lang.String`). +Eso tiene sentido, ya que aún no le hemos dicho a Nextflow que corresponde a un archivo. + +### 1.2. Crear un objeto Path con file() + +Podemos indicarle a Nextflow cómo manejar archivos creando [objetos Path](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) a partir de cadenas de rutas. + +En nuestro workflow, podemos convertir la cadena de ruta `data/patientA_rep1_normal_R1_001.fastq.gz` a un objeto Path usando el método `file()`, que proporciona acceso a propiedades y operaciones de archivos. + +Edite el `main.nf` para envolver la cadena con `file()` de la siguiente manera: + +=== "Después" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Crear un objeto Path a partir de una ruta de texto + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Ahora ejecute el workflow de nuevo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Esta vez, ve la ruta absoluta completa en lugar de la ruta relativa que proporcionamos como entrada. + +Nextflow ha convertido nuestra cadena en un objeto Path y la ha resuelto a la ubicación real del archivo en el sistema. +La ruta del archivo ahora será absoluta, como en `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Note también que la clase del objeto Path es `sun.nio.fs.UnixPath`: esta es la forma de Nextflow de representar archivos locales. +Como veremos más adelante, los archivos remotos tendrán nombres de clase diferentes (como `nextflow.file.http.XPath` para archivos HTTP), pero todos funcionan exactamente de la misma manera y pueden usarse de manera idéntica en sus flujos de trabajo. + +!!! tip + + **La diferencia clave:** + + - **Cadena de ruta**: Solo texto que Nextflow trata como caracteres + - **Objeto Path**: Una referencia de archivo inteligente con la que Nextflow puede trabajar + + Piénselo así: una cadena de ruta es como escribir una dirección en papel, mientras que un objeto Path es como tener la dirección cargada en un dispositivo GPS que sabe cómo navegar hasta allí y puede decirle detalles sobre el viaje. + +### 1.3. Acceder a atributos de archivo + +¿Por qué es esto útil? Bueno, ahora que Nextflow entiende que `myFile` es un objeto Path y no solo una cadena, podemos acceder a los diversos atributos del objeto Path. + +Actualicemos nuestro workflow para imprimir los atributos de archivo incorporados: + +=== "Después" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Ve los diversos atributos de archivo impresos en la consola arriba. + +### 1.4. Alimentar el archivo a un proceso + +La diferencia entre cadenas y objetos Path se vuelve crítica cuando comienza a construir workflows reales con procesos. +Hasta ahora hemos verificado que Nextflow ahora está tratando nuestro archivo de entrada como un archivo, pero veamos si podemos realmente ejecutar algo en ese archivo en un proceso. + +#### 1.4.1. Importar el proceso y examinar el código + +Le proporcionamos un módulo de proceso pre-escrito llamado `COUNT_LINES` que toma una entrada de archivo y cuenta cuántas líneas contiene. + +Para usar el proceso en el workflow, solo necesita agregar una declaración include antes del bloque workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Puede abrir el archivo de módulo para examinar su código: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Como puede ver, es un pequeño script bastante directo que descomprime el archivo y cuenta cuántas líneas contiene. + +??? info "¿Qué hace `debug true`?" + + La directiva `debug true` en la definición del proceso hace que Nextflow imprima la salida de su script (como el conteo de líneas "40") directamente en el registro de ejecución. + Sin esto, solo vería el estado de ejecución del proceso pero no la salida real de su script. + + Para más información sobre depuración de procesos de Nextflow, vea la misión secundaria [Debugging Nextflow Workflows](debugging.md). + +#### 1.4.2. Agregar una llamada a `COUNT_LINES` + +Ahora que el proceso está disponible para el workflow, podemos agregar una llamada al proceso `COUNT_LINES` para ejecutarlo en el archivo de entrada. + +Haga las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Contar las líneas del archivo + COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Y ahora ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Esto muestra que somos capaces de operar en el archivo apropiadamente dentro de un proceso. + +Específicamente, Nextflow llevó a cabo las siguientes operaciones exitosamente: + +- Organizó el archivo en el directorio de trabajo +- Descomprimió el archivo .gz +- Contó las líneas (40 líneas en este caso) +- Completó sin error + +La clave de esta operación fluida es que estamos diciéndole explícitamente a Nextflow que nuestra entrada es un archivo y debe ser tratada como tal. + +### 1.5. Solucionar errores básicos de entrada de archivo + +Esto a menudo confunde a los recién llegados a Nextflow, así que tomemos unos minutos para ver qué sucede cuando lo hace mal. + +Hay dos lugares principales donde puede manejar incorrectamente los archivos: al nivel del workflow y al nivel del proceso. + +#### 1.5.1. Error a nivel de workflow + +Veamos qué sucede si volvemos a tratar el archivo como una cadena cuando especificamos la entrada en el bloque workflow. + +Haga las siguientes ediciones al workflow, asegurándose de comentar las declaraciones print específicas de path: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Crear un objeto Path a partir de una ruta de texto + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Contar las líneas del archivo + COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Contar las líneas del archivo + COUNT_LINES(myFile) + ``` + +Y ahora ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Esta es la parte importante: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Cuando especifica una entrada `path`, Nextflow valida que esté pasando referencias de archivo reales, no solo cadenas. +Este error le está diciendo que `'data/patientA_rep1_normal_R1_001.fastq.gz'` no es un valor de ruta válido porque es una cadena, no un objeto Path. + +Nextflow detectó inmediatamente el problema y se detuvo antes de siquiera iniciar el proceso. + +#### 1.5.2. Error a nivel de proceso + +El otro lugar donde podríamos olvidar especificar que queremos que Nextflow trate la entrada como un archivo es en la definición del proceso. + +!!! warning "Mantenga el error del workflow de 1.5.1" + + Para que esta prueba funcione correctamente, mantenga el workflow en su estado roto (usando una cadena simple en lugar de `file()`). + Cuando se combina con `val` en el proceso, esto produce el error que se muestra a continuación. + +Haga la siguiente edición al módulo: + +=== "Después" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Antes" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +Y ahora ejecute el workflow de nuevo: + +```bash +nextflow run main.nf +``` + +??? failure "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Esto muestra muchos detalles sobre el error porque el proceso está configurado para generar información de depuración, como se señaló anteriormente. + +Estas son las secciones más relevantes: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Esto dice que el sistema no pudo encontrar el archivo; sin embargo, si busca la ruta, hay un archivo con ese nombre en esa ubicación. + +Cuando ejecutamos esto, Nextflow pasó el valor de cadena al script, pero no _organizó_ el archivo real en el directorio de trabajo. +Entonces el proceso intentó usar la cadena relativa, `data/patientA_rep1_normal_R1_001.fastq.gz`, pero ese archivo no existe dentro del directorio de trabajo del proceso. + +En conjunto, estos dos ejemplos le muestran cuán importante es decirle a Nextflow si una entrada debe ser manejada como un archivo. + +!!! note + + Asegúrese de volver atrás y corregir ambos errores intencionales antes de continuar a la siguiente sección. + +### Conclusión + +- Cadenas de ruta vs objetos Path: Las cadenas son solo texto, los objetos Path son referencias de archivo inteligentes +- El método `file()` convierte una cadena de ruta en un objeto Path con el que Nextflow puede trabajar +- Puede acceder a propiedades de archivo como `name`, `simpleName`, `extension` y `parent` [usando atributos de archivo](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) +- Usar objetos Path en lugar de cadenas permite a Nextflow gestionar apropiadamente los archivos en su workflow +- Resultados de Entrada de Proceso: El manejo apropiado de archivos requiere objetos Path, no cadenas, para asegurar que los archivos se organicen correctamente y sean accesibles para su uso por los procesos. + +--- + +## 2. Usar archivos remotos + +Una de las características clave de Nextflow es la capacidad de cambiar sin problemas entre archivos locales (en la misma máquina) y archivos remotos accesibles a través de internet. + +Si lo está haciendo correctamente, nunca debería necesitar cambiar la lógica de su workflow para acomodar archivos provenientes de diferentes ubicaciones. +Todo lo que necesita hacer para usar un archivo remoto es especificar el prefijo apropiado en la ruta del archivo cuando lo suministra al workflow. + +Por ejemplo, `/path/to/data` no tiene prefijo, indicando que es una ruta de archivo local 'normal', mientras que `s3://path/to/data` incluye el prefijo `s3://`, indicando que está ubicado en el almacenamiento de objetos S3 de Amazon. + +Muchos protocolos diferentes son soportados: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Para usar cualquiera de estos, simplemente especifique el prefijo relevante en la cadena, que entonces técnicamente se llama Identificador Uniforme de Recursos (URI) en lugar de ruta de archivo. +Nextflow manejará la autenticación y la organización de los archivos en el lugar correcto, descargando o subiendo y todas las demás operaciones de archivos que esperaría. + +La fortaleza clave de este sistema es que nos permite cambiar entre entornos sin cambiar ninguna lógica del pipeline. +Por ejemplo, puede desarrollar con un conjunto de prueba pequeño y local antes de cambiar a un conjunto de prueba a gran escala ubicado en almacenamiento remoto simplemente cambiando el URI. + +### 2.1. Usar un archivo de internet + +Probemos esto cambiando la ruta local que estamos proporcionando a nuestro workflow con una ruta HTTPS que apunta a una copia de los mismos datos que está almacenada en Github. + +!!! warning + + Esto solo funcionará si tiene una conexión a internet activa. + +Abra `main.nf` nuevamente y cambie la ruta de entrada de la siguiente manera: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Usar un archivo remoto de internet + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Ejecutemos el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +¡Funciona! Puede ver que muy poco ha cambiado. + +La única diferencia en la salida de la consola es que la clase del objeto path ahora es `nextflow.file.http.XPath`, mientras que para la ruta local la clase era `sun.nio.fs.UnixPath`. +No necesita recordar estas clases; solo mencionamos esto para demostrar que Nextflow identifica y maneja las diferentes ubicaciones apropiadamente. + +Entre bastidores, Nextflow descargó el archivo a un directorio de organización ubicado dentro del directorio de trabajo. +Ese archivo organizado puede entonces ser tratado como un archivo local y vinculado simbólicamente en el directorio del proceso relevante. + +Puede verificar que eso sucedió aquí mirando el contenido del directorio de trabajo ubicado en el valor hash del proceso. + +??? abstract "Contenido del directorio de trabajo" + + Si el hash del proceso fue `8a/2ab7ca`, podría explorar el directorio de trabajo: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + El enlace simbólico apunta a una copia organizada del archivo remoto que Nextflow descargó automáticamente. + +Note que para archivos más grandes, el paso de descarga tomará tiempo adicional en comparación con ejecutar en archivos locales. +Sin embargo, Nextflow verifica si ya tiene una copia organizada para evitar descargas innecesarias. +Entonces, si ejecuta nuevamente en el mismo archivo y no ha eliminado el archivo organizado, Nextflow usará la copia organizada. + +Esto muestra cuán fácil es cambiar entre datos locales y remotos usando Nextflow, que es una característica clave de Nextflow. + +!!! note + + La única excepción importante a este principio es que no puede usar patrones glob o rutas de directorio con HTTPS porque HTTPS no puede listar múltiples archivos, por lo que debe especificar URLs de archivos exactas. + Sin embargo, otros protocolos de almacenamiento como blob storage (`s3://`, `az://`, `gs://`) pueden usar tanto globs como rutas de directorio. + + Aquí está cómo podría usar patrones glob con almacenamiento en la nube: + + ```groovy title="Ejemplos de almacenamiento en la nube (no ejecutables en este entorno)" + // S3 con patrones glob - coincidiría con múltiples archivos + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage con patrones glob + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage con patrones glob + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Le mostraremos cómo trabajar con globs en la práctica en la siguiente sección. + +### 2.2. Volver al archivo local + +Vamos a volver a usar nuestros archivos de ejemplo locales para el resto de esta misión secundaria, así que cambiemos la entrada del workflow de vuelta al archivo original: + +=== "Después" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Conclusión + +- Los datos remotos se acceden usando un URI (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow descargará y organizará automáticamente los datos en el lugar correcto, siempre que estas rutas se alimenten a los procesos +- ¡No escriba lógica para descargar o subir archivos remotos! +- Los archivos locales y remotos producen diferentes tipos de objetos pero funcionan de manera idéntica +- **Importante**: HTTP/HTTPS solo funcionan con archivos individuales (sin patrones glob) +- El almacenamiento en la nube (S3, Azure, GCS) soporta tanto archivos individuales como patrones glob +- Puede cambiar sin problemas entre fuentes de datos locales y remotas sin cambiar la lógica del código (siempre que el protocolo soporte sus operaciones requeridas) + +--- + +## 3. Usar el channel factory `fromPath()` + +Hasta ahora hemos estado trabajando con un solo archivo a la vez, pero en Nextflow, típicamente vamos a querer crear un canal de entrada con múltiples archivos de entrada para procesar. + +Una forma ingenua de hacer eso sería combinar el método `file()` con [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) así: + +```groovy title="Ejemplo de sintaxis" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Eso funciona, pero es torpe. + +!!! tip "Cuándo usar `file()` vs `channel.fromPath()`" + + - Use `file()` cuando necesite un único objeto Path para manipulación directa (verificar si existe un archivo, leer sus atributos, o pasar a una única invocación de proceso) + - Use `channel.fromPath()` cuando necesite un canal que pueda contener múltiples archivos, especialmente con patrones glob, o cuando los archivos fluirán a través de múltiples procesos + +Aquí es donde entra [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath): un conveniente channel factory que agrupa toda la funcionalidad que necesitamos para generar un canal a partir de una o más cadenas de archivos estáticas así como patrones glob. + +### 3.1. Agregar el channel factory + +Actualicemos nuestro workflow para usar `channel.fromPath`. + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Imprimir atributos del archivo + /* Comentar esto por ahora, volveremos a ello más adelante! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Contar las líneas del archivo + // COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Crear un objeto Path a partir de una ruta de texto + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprimir atributos del archivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Contar las líneas del archivo + COUNT_LINES(myFile) + ``` + +También hemos comentado el código que imprime los atributos por ahora, y agregamos una declaración `.view` para imprimir solo el nombre del archivo en su lugar. + +Ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Como puede ver, la ruta del archivo se está cargando como un objeto de tipo `Path` en el canal. +Esto es similar a lo que `file()` habría hecho, excepto que ahora tenemos un canal en el que podemos cargar más archivos si queremos. + +Usar `channel.fromPath()` es una forma conveniente de crear un nuevo canal poblado por una lista de archivos. + +### 3.2. Ver atributos de archivos en el canal + +En nuestro primer intento de usar el channel factory, simplificamos el código y solo imprimimos el nombre del archivo. + +Volvamos a imprimir los atributos completos del archivo: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Contar las líneas del archivo + COUNT_LINES(ch_files) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Contar las líneas del archivo + // COUNT_LINES(ch_files) + ``` + +También estamos re-habilitando la llamada al proceso `COUNT_LINES` para verificar que el procesamiento de archivos todavía funciona correctamente con nuestro enfoque basado en canales. + +Ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Y ahí está, mismos resultados que antes pero ahora tenemos el archivo en un canal, así que podemos agregar más. + +### 3.3. Usar un glob para coincidir con múltiples archivos + +Hay varias formas en que podríamos cargar más archivos en el canal. +Aquí vamos a mostrarle cómo usar patrones glob, que son una forma conveniente de coincidir y recuperar nombres de archivos y directorios basados en caracteres comodín. +El proceso de coincidir estos patrones se llama "globbing" o "expansión de nombres de archivo". + +!!! note + + Como se señaló anteriormente, Nextflow soporta globbing para gestionar archivos de entrada y salida en la mayoría de los casos, excepto con rutas de archivo HTTPS porque HTTPS no puede listar múltiples archivos. + +Digamos que queremos recuperar ambos archivos en un par de archivos asociados con un paciente dado, `patientA`: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Ya que la única diferencia entre los nombres de archivos es el número de réplica, _es decir_, el número después de `R`, podemos usar el carácter comodín `*` para representar el número de la siguiente manera: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +Ese es el patrón glob que necesitamos. + +Ahora todo lo que necesitamos hacer es actualizar la ruta del archivo en el channel factory para usar ese patrón glob de la siguiente manera: + +=== "Después" + + ```groovy title="main.nf" linenums="7" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow reconocerá automáticamente que este es un patrón glob y lo manejará apropiadamente. + +Ejecute el workflow para probarlo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Como puede ver, ahora tenemos dos objetos Path en nuestro canal, lo que muestra que Nextflow ha hecho la expansión de nombres de archivo correctamente, y ha cargado y procesado ambos archivos como se esperaba. + +Usando este método, podemos recuperar tantos o tan pocos archivos como queramos simplemente cambiando el patrón glob. Si lo hiciéramos más generoso, por ejemplo reemplazando todas las partes variables de los nombres de archivo por `*` (_e.g._ `data/patient*_rep*_*_R*_001.fastq.gz`) podríamos tomar todos los archivos de ejemplo en el directorio `data`. + +### Conclusión + +- `channel.fromPath()` crea un canal con archivos que coinciden con un patrón +- Cada archivo se emite como un elemento separado en el canal +- Podemos usar un patrón glob para coincidir con múltiples archivos +- Los archivos se convierten automáticamente en objetos Path con atributos completos +- El método `.view()` permite inspección del contenido del canal + +--- + +## 4. Extraer metadata básica de nombres de archivos + +En la mayoría de dominios científicos, es muy común tener metadata codificada en los nombres de los archivos que contienen los datos. +Por ejemplo, en bioinformática, los archivos que contienen datos de secuenciación a menudo se nombran de una manera que codifica información sobre la muestra, condición, réplica y número de lectura. + +Si los nombres de archivos se construyen de acuerdo con una convención consistente, puede extraer esa metadata de manera estandarizada y usarla en el curso de su análisis. +Ese es un gran 'si', por supuesto, y debe ser muy cauteloso cada vez que confíe en la estructura del nombre de archivo; pero la realidad es que este enfoque es muy ampliamente utilizado, así que veamos cómo se hace en Nextflow. + +En el caso de nuestros datos de ejemplo, sabemos que los nombres de archivos incluyen metadata estructurada consistentemente. +Por ejemplo, el nombre de archivo `patientA_rep1_normal_R2_001` codifica lo siguiente: + +- ID del paciente: `patientA` +- ID de réplica: `rep1` +- tipo de muestra: `normal` (en oposición a `tumor`) +- conjunto de lectura: `R1` (en oposición a `R2`) + +Vamos a modificar nuestro workflow para recuperar esta información en tres pasos: + +1. Recuperar el `simpleName` del archivo, que incluye la metadata +2. Separar la metadata usando un método llamado `tokenize()` +3. Usar un map para organizar la metadata + +!!! warning + + Nunca debe codificar información sensible en nombres de archivos, como nombres de pacientes u otras características identificatorias, ya que eso puede comprometer la privacidad del paciente u otras restricciones de seguridad relevantes. + +### 4.1. Recuperar el `simpleName` + +El `simpleName` es un atributo de archivo que corresponde al nombre de archivo sin su ruta y extensión. + +Haga las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +Esto recupera el `simpleName` y lo asocia con el objeto de archivo completo usando una operación `map()`. + +Ejecute el workflow para probar que funciona: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Cada elemento en el canal ahora es una tupla que contiene el `simpleName` y el objeto de archivo original. + +### 4.2. Extraer la metadata del `simplename` + +En este punto, la metadata que queremos está incrustada en el `simplename`, pero no podemos acceder a elementos individuales directamente. +Entonces necesitamos dividir el `simplename` en sus componentes. +Afortunadamente, esos componentes están simplemente separados por guiones bajos en el nombre de archivo original, así que podemos aplicar un método común de Nextflow llamado `tokenize()` que es perfecto para esta tarea. + +Haga las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +El método `tokenize()` dividirá la cadena `simpleName` donde encuentre guiones bajos, y devolverá una lista que contiene las subcadenas. + +Ejecute el workflow: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ahora la tupla para cada elemento en nuestro canal contiene la lista de metadata (_e.g._ `[patientA, rep1, normal, R1, 001]`) y el objeto de archivo original. + +¡Eso es genial! +Hemos desglosado nuestra información de paciente de una sola cadena en una lista de cadenas. +Ahora podemos manejar cada parte de la información del paciente por separado. + +### 4.3. Usar un map para organizar la metadata + +Nuestra metadata es solo una lista plana en este momento. +Es suficientemente fácil de usar pero difícil de leer. + +```console +[patientA, rep1, normal, R1, 001] +``` + +¿Qué es el elemento en el índice 3? ¿Puede decirlo sin referirse a la explicación original de la estructura de metadata? + +Esta es una gran oportunidad para usar un almacén clave-valor, donde cada elemento tiene un conjunto de claves y sus valores asociados, para que pueda referirse fácilmente a cada clave para obtener el valor correspondiente. + +En nuestro ejemplo, eso significa ir de esta organización: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +A esta: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +En Nextflow, eso se llama un [map](https://nextflow.io/docs/latest/script.html#maps). + +Convirtamos nuestra lista plana en un map ahora. +Haga las siguientes ediciones al workflow: + +=== "Después" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Cargar archivos con channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +Los cambios clave aquí son: + +- **Asignación por desestructuración**: `def (patient, replicate, type, readNum) = ...` extrae los valores tokenizados en variables nombradas en una línea +- **Sintaxis literal de map**: `[id: patient, replicate: ...]` crea un map donde cada clave (como `id`) está asociada con un valor (como `patient`) +- **Estructura anidada**: La lista externa `[..., myFile]` empareja el map de metadata con el objeto de archivo original + +También simplificamos un par de cadenas de metadata usando un método de reemplazo de cadenas llamado `replace()` para eliminar algunos caracteres que son innecesarios (_e.g._ `replicate.replace('rep', '')` para mantener solo el número de los IDs de réplica). + +Ejecutemos el workflow de nuevo: + +```bash +nextflow run main.nf +``` + +??? success "Salida del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [infallible_swartz] DSL2 - revision: 7f4e68c0cb + + executor > local (2) + [1b/e7fb27] COUNT_LINES (1) [100%] 2 of 2 ✔ + [[id:patientA, replicate:1, type:normal, readNum:2], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[id:patientA, replicate:1, type:normal, readNum:1], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ahora la metadata está claramente etiquetada (_e.g._ `[id:patientA, replicate:1, type:normal, readNum:2]`) así que es mucho más fácil decir qué es qué. + +También será mucho más fácil hacer uso de elementos de metadata en el workflow, y hará nuestro código más fácil de leer y más mantenible. + +### Conclusión + +- Podemos manejar nombres de archivos en Nextflow con el poder de un lenguaje de programación completo +- Podemos tratar los nombres de archivos como cadenas para extraer información relevante +- El uso de métodos como `tokenize()` y `replace()` nos permite manipular cadenas en el nombre de archivo +- La operación `.map()` transforma elementos del canal mientras preserva la estructura +- La metadata estructurada (maps) hace el código más legible y mantenible que las listas posicionales + +A continuación, veremos cómo manejar archivos de datos emparejados. + +--- + +## 5. Manejar archivos de datos emparejados + +Muchos diseños experimentales producen archivos de datos emparejados que se benefician de ser manejados de una manera explícitamente emparejada. +Por ejemplo, en bioinformática, los datos de secuenciación a menudo se generan en forma de lecturas emparejadas, que significa cadenas de secuencia que se originan del mismo fragmento de ADN (a menudo llamadas 'forward' y 'reverse' porque se leen desde extremos opuestos). + +Ese es el caso de nuestros datos de ejemplo, donde R1 y R2 se refieren a los dos conjuntos de lecturas. + +```console +data/patientA_rep1_normal_R1_001.fastq.gz +data/patientA_rep1_normal_R2_001.fastq.gz +``` + +Nextflow proporciona un channel factory especializado para trabajar con archivos emparejados como este llamado `channel.fromFilePairs()`, que automáticamente agrupa archivos basándose en un patrón de nomenclatura compartido. Eso le permite asociar los archivos emparejados más estrechamente con menos esfuerzo. + +Vamos a modificar nuestro workflow para aprovechar esto. +Va a tomar dos pasos: + +1. Cambiar el channel factory a `channel.fromFilePairs()` +2. Extraer y mapear la metadata + +### 5.1. Cambiar el channel factory a `channel.fromFilePairs()` + +Para usar `channel.fromFilePairs diff --git a/docs/es/docs/training_collections/architects_toolkit_1.md b/docs/es/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..ba56252aec --- /dev/null +++ b/docs/es/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,63 @@ +```markdown +--- +title: Kit de Herramientas del Arquitecto I +hide: + - toc +--- + +# Kit de Herramientas del Arquitecto I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nuestras Colecciones de Entrenamiento proporcionan rutas de aprendizaje curadas a través de nuestros materiales de entrenamiento avanzado (llamados [Side Quests](../../side_quests)). Esta colección cubre cuatro temas esenciales que se usan frecuentemente en conjunto para construir workflows robustos y escalables. + +## Objetivos de aprendizaje + +Al final de esta colección, tendrá experiencia con: + +- **Arquitecturas de workflows modulares complejas** - Combinar múltiples workflows en pipelines cohesivos +- **Estrategias de testing integrales** - Asegurar que sus workflows sean confiables y mantenibles +- **Gestión de metadatos** - Manejar metadatos específicos de muestras a lo largo de sus workflows de manera efectiva +- **Procesamiento avanzado de datos** - Implementar patrones eficientes de división y agrupación de datos + +Estas habilidades le permitirán construir workflows de Nextflow robustos, escalables y mantenibles para aplicaciones del mundo real. + +## Audiencia y prerequisitos + +Esta colección está diseñada para usuarios que han completado el entrenamiento básico de Nextflow y quieren profundizar en patrones avanzados de workflows, estrategias de testing, y técnicas de manejo de datos y metadatos. + +**Prerequisitos** + +- Finalización del entrenamiento [Hello Nextflow](../../hello_nextflow/) o experiencia equivalente +- Familiaridad básica con la sintaxis y conceptos de Nextflow +- Comprensión de patrones básicos de desarrollo de workflows +- Experiencia con herramientas de línea de comandos + +## Contenido de la colección + +Esta colección consta de cuatro Side Quests que cubren temas complementarios de ingeniería de workflows: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - Arquitectura y composición de workflows complejos +2. **[Testing with nf-test](../../side_quests/nf-test)** - Estrategias de testing para workflows de Nextflow +3. **[Metadata](../../side_quests/metadata)** - Manejo de metadatos para elementos en canales de Nextflow +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - Patrones avanzados de procesamiento de datos + +Cada Side Quest es autocontenido y cubre conceptos independientes, pero recomendamos completarlos en el orden listado arriba para una progresión lógica a través de los temas. + +## Cómo usar esta colección + +Primero, haga clic con el comando en el botón "Open in GitHub Codespaces" a continuación para lanzar el entorno de entrenamiento en una pestaña separada, luego continúe leyendo mientras carga. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Una vez que su entorno esté en ejecución, trabaje a través de la colección de la siguiente manera: + +1. En esta pestaña: Navegue al primer Side Quest listado arriba, que describe ejercicios de desarrollo paso a paso. +2. En su pestaña de Codespaces: Trabaje a través de los ejercicios para el Side Quest. +3. Cuando complete un Side Quest, regrese a esta página y navegue al siguiente en la lista de arriba. +4. Cuando haya completado la colección, haga clic en el botón a continuación para completar una encuesta muy breve. Sus comentarios nos permiten continuar mejorando los materiales de entrenamiento para todos. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +¿Listo para comenzar? ¡Comience con el primer módulo arriba! +``` diff --git a/docs/es/docs/training_collections/index.md b/docs/es/docs/training_collections/index.md new file mode 100644 index 0000000000..f13d54c780 --- /dev/null +++ b/docs/es/docs/training_collections/index.md @@ -0,0 +1,31 @@ +```markdown +--- +title: Colecciones de Entrenamiento +hide: + - toc +--- + +# Colecciones de Entrenamiento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traducción asistida por IA - [más información y sugerencias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta sección contiene colecciones curadas de módulos de entrenamiento llamados [Side Quests](../side_quests/index.md) que tienen como objetivo proporcionar una experiencia de aprendizaje integral alrededor de un tema o caso de uso particular. + +## Requisitos Previos + +Cada colección tiene requisitos previos específicos documentados en su página índice. Sin embargo, la mayoría de las colecciones asumen: + +- Experiencia con la línea de comandos +- Conceptos fundamentales de Nextflow y herramientas cubiertas en el curso de entrenamiento para principiantes [Hello Nextflow](../../hello_nextflow/) + +Para los requisitos técnicos y la configuración del entorno, consulte el mini-curso de [Configuración del Entorno](../../envsetup/). + +## Colecciones disponibles + +- [El Kit de Herramientas del Arquitecto I](./architects_toolkit_1.md) - Una colección de cuatro Side Quests que cubren patrones de arquitectura de flujos de trabajo para ensamblar pipelines complejos, implementar estrategias de prueba, gestionar la administración de metadatos, y agrupar y dividir datos. _Duración estimada: 4 horas en entrenamiento grupal._ + +## Sugerir nuevas colecciones + +Estamos trabajando activamente en el desarrollo de Side Quests y Colecciones adicionales. +Siéntase libre de sugerir temas que considere que tendría sentido cubrir en una Colección publicando en la [sección de Training](https://community.seqera.io/c/training/) del foro de la comunidad. +``` diff --git a/docs/es/llm-prompt.md b/docs/es/llm-prompt.md new file mode 100644 index 0000000000..95a845b909 --- /dev/null +++ b/docs/es/llm-prompt.md @@ -0,0 +1,154 @@ +# Translation Rules for Spanish + +The target language for this translation is **Spanish** (`es`). + +## 1. Grammar & Tone + +- Use Latin American Spanish spelling conventions +- For instructions, use imperative forms that work with both tú and usted (e.g., "Ejecute", "Consulte") +- Use proper Spanish punctuation: ¡...! and ¿...? +- Prefer active voice when possible +- Consider gender-inclusive greetings: "¡Te damos la bienvenida!" or "¡Bienvenido/a!" rather than just "¡Bienvenido!" + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Spanish (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "El canal de entrada recibe los archivos..." (translate "channel" to "canal") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// emite un saludo` + +## 3. Code Comments + +**Always translate code comments to Spanish.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Spanish translation +params.greeting = "Hello" // define el saludo predeterminado +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Spanish: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Canal.fromPath('*.fastq') +proceso FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ versión 24.04.0 +executor > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Missing Spanish punctuation + +```markdown +// Wrong - missing opening punctuation marks +Que sigue? +Felicidades! + +// Correct - proper Spanish punctuation +¿Qué sigue? +¡Felicidades! +``` + +### ❌ Using Spain Spanish for Latin American audience + +```markdown +// Wrong - Spain Spanish vocabulary +El ordenador ejecuta el script... + +// Correct - Latin American Spanish +La computadora ejecuta el script... +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code): + +| English | Spanish | Notes | +| ----------- | -------------------- | ------------------------------ | +| channel | canal | In prose; keep English in code | +| process | proceso | In prose; keep English in code | +| workflow | workflow | Keep in English (common usage) | +| pipeline | pipeline | Keep in English (common usage) | +| directive | directiva | | +| container | contenedor | | +| input | entrada | | +| output | salida | | +| task | tarea | | +| tuple | tupla | | +| operator | operador | | +| parameter | parámetro | | +| environment | entorno | | +| directory | directorio | | +| file | archivo | | +| sample | muestra | | +| alignment | alineamiento | | +| reference | referencia | | +| training | capacitación | Latin American preference | +| workshop | taller | | +| module | módulo | | +| command | comando | | +| index | índice | | +| run | ejecutar / ejecución | | +| open source | código abierto | | +| community | comunidad | | + +## 6. Admonition Titles + +| English | Spanish | +| -------- | ----------- | +| Note | Nota | +| Tip | Consejo | +| Warning | Advertencia | +| Exercise | Ejercicio | +| Solution | Solución | +| Example | Ejemplo | + +## 7. Section Headers + +These recurring section headers should be translated consistently: + +| English | Spanish | +| ----------------- | ------------------------- | +| Takeaway | Conclusión | +| What's next? | ¿Qué sigue? | +| Warmup | Calentamiento | +| Environment Setup | Configuración del entorno | +| Getting Started | Primeros pasos | + +## 8. Tab Labels + +| English | Spanish | +| ------- | ------- | +| After | Después | +| Before | Antes | +| Gitpod | Gitpod | +| Local | Local | diff --git a/docs/es/mkdocs.yml b/docs/es/mkdocs.yml new file mode 100644 index 0000000000..9db86b9ae8 --- /dev/null +++ b/docs/es/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: es + custom_dir: ../en/overrides +extra: + consent: + title: "Consentimiento de cookies" + description: >- + Utilizamos cookies para reconocer tus visitas repetidas y preferencias, + así como para medir la efectividad de nuestra documentación y si los usuarios + encuentran lo que buscan. Con tu consentimiento, nos ayudas a mejorar + nuestros materiales de capacitación. + Obtén más información sobre + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">cómo usamos las cookies</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/es/ui-strings.yml b/docs/es/ui-strings.yml new file mode 100644 index 0000000000..37515ac8aa --- /dev/null +++ b/docs/es/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - Spanish (Español) +# Estas cadenas son utilizadas por index_page_hook.py para las páginas +# de inicio de cursos y en mkdocs.yml para el consentimiento de cookies. + +index_page: + course_summary: "Resumen del curso" + additional_information: "Información adicional" + technical_requirements: "Requisitos técnicos" + learning_objectives: "Objetivos de aprendizaje" + audience_prerequisites: "Audiencia y prerrequisitos" + course_videos: "Videos del curso" + +defaults: + technical_requirements: >- + Necesitarás una cuenta de GitHub O una instalación local de Nextflow. + Consulta [Opciones de entorno](../envsetup/index.md) para más detalles. + videos: >- + Hay videos disponibles para cada capítulo, con un instructor trabajando + a través de los ejercicios. El video de cada parte del curso está + incrustado en la parte superior de la página correspondiente. + view_playlist: "Ver la lista de reproducción en YouTube" diff --git a/docs/fr/docs/envsetup/01_setup.md b/docs/fr/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..0c24866acf --- /dev/null +++ b/docs/fr/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces est une plateforme web qui nous permet de fournir un environnement préconfiguré pour la formation, soutenu par des machines virtuelles dans le cloud. +La plateforme est exploitée par GitHub (qui appartient à Microsoft) et est accessible gratuitement (avec des quotas d'utilisation) à toute personne possédant un compte GitHub. + +!!! warning "Avertissement" + + Les comptes rattachés à des organisations peuvent être soumis à certaines restrictions supplémentaires. + Si c'est votre cas, vous devrez peut-être utiliser un compte personnel indépendant ou opter pour une installation locale. + +## Création d'un compte GitHub + +Vous pouvez créer un compte GitHub gratuit depuis la [page d'accueil de GitHub](https://github.com/). + +## Lancement de votre GitHub Codespace + +Une fois connecté à GitHub, ouvrez ce lien dans votre navigateur pour ouvrir l'environnement de formation Nextflow : <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Vous pouvez également cliquer sur le bouton ci-dessous, qui est répété dans chaque cours de formation (généralement sur la page d'orientation). + +[![Ouvrir dans GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Vous devriez voir une page où vous pouvez créer un nouveau GitHub Codespace : + +![Créer un GitHub Codespace](img/codespaces_create.png) + +### Configuration + +Pour une utilisation générale, vous ne devriez rien avoir à configurer. +Sauf indication contraire dans le cours que vous commencez, vous pouvez simplement cliquer sur le bouton principal pour continuer. + +Cependant, il est possible de personnaliser l'environnement en cliquant sur le bouton « Change options ». + +??? info "Options de configuration" + + Si vous cliquez sur le bouton « Change options », vous aurez la possibilité de personnaliser les éléments suivants : + + #### Branche + + Cela vous permet de sélectionner une version différente des supports de formation. + La branche `master` contient généralement des corrections de bogues et des supports récemment développés et approuvés mais pas encore publiés sur le site web. + Les autres branches contiennent des travaux en cours qui peuvent ne pas être entièrement fonctionnels. + + #### Type de machine + + Cela vous permet de personnaliser la machine virtuelle que vous utiliserez pour suivre la formation. + + Utiliser une machine avec plus de cœurs vous permet de mieux tirer parti de la capacité de Nextflow à paralléliser l'exécution des flux de travail. + Cependant, cela consommera plus rapidement votre quota gratuit, nous ne recommandons donc pas de modifier ce paramètre à moins que cela ne soit conseillé dans les instructions du cours que vous prévoyez de suivre. + + Voir « Quotas GitHub Codespaces » ci-dessous pour plus de détails sur les quotas. + +### Temps de démarrage + +L'ouverture d'un nouvel environnement GitHub Codespaces pour la première fois peut prendre plusieurs minutes, car le système doit configurer votre machine virtuelle, alors ne vous inquiétez pas s'il y a un temps d'attente. +Cependant, cela ne devrait pas prendre plus de cinq minutes. + +## Navigation dans l'interface de formation + +Une fois votre GitHub Codespaces chargé, vous devriez voir quelque chose de similaire à ce qui suit (qui peut s'ouvrir en mode clair selon les préférences de votre compte) : + +![Accueil GitHub Codespaces](img/codespaces_welcome.png) + +Ceci est l'interface de l'IDE VSCode, une application de développement de code populaire que nous recommandons d'utiliser pour le développement Nextflow. + +- **L'éditeur principal** est l'endroit où le code Nextflow et d'autres fichiers texte s'ouvriront. C'est ici que vous modifierez le code. Lorsque vous ouvrez le codespace, cela vous montrera un aperçu du fichier `README.md`. +- **Le terminal** sous l'éditeur principal vous permet d'exécuter des commandes. C'est ici que vous exécuterez toutes les lignes de commande données dans les instructions du cours. +- **La barre latérale** vous permet de personnaliser votre environnement et d'effectuer des tâches de base (copier, coller, ouvrir des fichiers, rechercher, git, etc.). Par défaut, elle est ouverte sur l'explorateur de fichiers, qui vous permet de parcourir le contenu du dépôt. Cliquer sur un fichier dans l'explorateur l'ouvrira dans la fenêtre de l'éditeur principal. + +Vous pouvez ajuster les proportions relatives des volets de la fenêtre comme vous le souhaitez. + +<!-- TODO (future) Link to development best practices side quest? --> + +## Autres notes sur l'utilisation de GitHub Codespaces + +### Reprendre une session + +Une fois que vous avez créé un environnement, vous pouvez facilement le reprendre ou le redémarrer et continuer là où vous vous étiez arrêté. +Votre environnement expirera après 30 minutes d'inactivité et sauvegardera vos modifications pendant 2 semaines maximum. + +Vous pouvez rouvrir un environnement depuis <https://github.com/codespaces/>. +Les environnements précédents seront listés. +Cliquez sur une session pour la reprendre. + +![Liste des sessions GitHub Codespace](img/codespaces_list.png) + +Si vous avez enregistré l'URL de votre environnement GitHub Codespaces précédent, vous pouvez simplement l'ouvrir dans votre navigateur. +Sinon, cliquez sur le même bouton que vous avez utilisé pour le créer initialement : + +[![Ouvrir dans GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Vous devriez voir la session précédente, l'option par défaut est de la reprendre : + +![Reprendre un GitHub Codespace](img/codespaces_resume.png) + +### Enregistrement de fichiers sur votre machine locale + +Pour enregistrer n'importe quel fichier depuis le panneau de l'explorateur, faites un clic droit sur le fichier et sélectionnez `Download`. + +### Gestion des quotas GitHub Codespaces + +GitHub Codespaces vous donne jusqu'à 15 Go-mois de stockage par mois et 120 heures-cœur par mois. +Cela équivaut à environ 60 heures d'exécution de l'environnement par défaut en utilisant l'espace de travail standard (2 cœurs, 8 Go de RAM et 32 Go de stockage). + +Vous pouvez les créer avec plus de ressources (voir l'explication ci-dessus), mais cela consommera plus rapidement votre utilisation gratuite et vous aurez moins d'heures d'accès à cet espace. +Par exemple, si vous sélectionnez une machine à 4 cœurs au lieu des 2 cœurs par défaut, votre quota s'épuisera deux fois plus vite. + +Vous pouvez optionnellement acheter l'accès à plus de ressources. + +Pour plus d'informations, consultez la documentation GitHub : +[À propos de la facturation pour GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/fr/docs/envsetup/02_local.md b/docs/fr/docs/envsetup/02_local.md new file mode 100644 index 0000000000..6a685710e4 --- /dev/null +++ b/docs/fr/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Installation manuelle + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Il est possible d'installer tout ce dont vous avez besoin pour suivre la formation dans votre propre environnement local manuellement. + +Nous avons documenté ici comment procéder sur les systèmes compatibles POSIX standard (en supposant une machine personnelle comme un ordinateur portable). +Gardez à l'esprit que certains détails peuvent différer selon votre système spécifique. + +!!! tip "Astuce" + + Avant de continuer, avez-vous envisagé d'utiliser l'[approche Devcontainers](03_devcontainer.md) ? + Elle fournit tous les outils et dépendances nécessaires sans nécessiter d'installation manuelle. + +## Exigences logicielles générales + +Nextflow peut être utilisé sur tout système compatible POSIX (Linux, macOS, Windows Subsystem for Linux, etc.) avec Java installé. +Nos cours de formation ont quelques exigences supplémentaires. + +Au total, vous devrez avoir les logiciels suivants installés : + +- Bash ou shell équivalent +- [Java 11 (ou plus récent, jusqu'à 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (ou plus récent) +- [VSCode](https://code.visualstudio.com) avec l'[extension Nextflow](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +L'application VSCode est techniquement optionnelle mais nous vous recommandons fortement de l'utiliser pour suivre les cours ainsi que pour votre travail de développement Nextflow en général. + +Le manuel de documentation Nextflow fournit des instructions pour installer ces dépendances sous [Configuration de l'environnement](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow et outils nf-core + +Vous devrez installer Nextflow lui-même, ainsi que les outils nf-core, comme détaillé dans les articles liés ci-dessous : + +- [Installation de Nextflow](https://www.nextflow.io/docs/latest/install.html) +- [Outils nf-core](https://nf-co.re/docs/nf-core-tools/installation) + +Nous recommandons d'utiliser l'option d'auto-installation pour Nextflow et l'option PyPI pour les outils nf-core. + +!!! warning "Compatibilité des versions" + + <!-- Any update to this content needs to be copied to the home page --> + **Depuis janvier 2026, tous nos cours de formation Nextflow nécessitent Nextflow version 25.10.2 ou ultérieure, avec la syntaxe stricte v2 activée, sauf indication contraire.** + + Pour plus d'informations sur les exigences de version et la syntaxe stricte v2, veuillez consulter le guide [Versions de Nextflow](../info/nxf_versions.md). + + Les anciennes versions du matériel de formation correspondant aux syntaxes antérieures sont disponibles via le sélecteur de version dans la barre de menu de cette page web. + +## Supports de formation + +Le moyen le plus simple de télécharger les supports de formation est de cloner l'intégralité du dépôt en utilisant cette commande : + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Chaque cours a son propre répertoire. +Pour suivre un cours, ouvrez une fenêtre de terminal (idéalement depuis l'application VSCode) et faites `cd` dans le répertoire approprié. + +Vous pouvez ensuite suivre les instructions du cours fournies sur le site web. diff --git a/docs/fr/docs/envsetup/03_devcontainer.md b/docs/fr/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..e1548fc379 --- /dev/null +++ b/docs/fr/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Devcontainers locaux + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Si vous avez une installation Docker locale ou êtes prêt à en installer une, le moyen le plus simple de travailler localement avec ces supports est d'utiliser la fonctionnalité devcontainer de Visual Studio Code. Cette approche fournit tous les outils et dépendances nécessaires sans nécessiter d'installation manuelle. + +## Exigences + +Pour utiliser la configuration devcontainer locale, vous aurez besoin de : + +- [Visual Studio Code](https://code.visualstudio.com/) +- Une installation Docker locale, par exemple : + - [Docker Desktop](https://docs.docker.com/get-docker/) (pour Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (pour Linux) + - [Colima](https://github.com/abiosoft/colima) (alternative pour macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (inclus dans Docker Desktop, mais peut nécessiter une installation séparée avec d'autres configurations Docker) +- [Extension Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) pour VS Code + +Votre installation Docker doit être en cours d'exécution avant de tenter d'ouvrir le devcontainer. + +Pour vérifier que Docker buildx est disponible, exécutez : + +```bash +docker buildx version +``` + +Si cette commande échoue, vous devrez installer l'extension buildx avant de continuer. + +## Instructions de configuration + +Suivez ces étapes pour configurer votre environnement local en utilisant les devcontainers VS Code : + +### Installer l'extension « Dev Containers » dans VS Code + +- Ouvrez VS Code +- Allez dans Extensions (Ctrl+Shift+X ou Cmd+Shift+X sur macOS) +- Recherchez « Dev Containers » +- Cliquez sur « Install » + +![Installation de l'extension Dev Containers dans VS Code](img/install_extension.png) + +### Cloner le dépôt : + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Ouvrir le dépôt dans VS Code : + +- Lancez VS Code +- Sélectionnez **Fichier -> Ouvrir le dossier** depuis le menu +- Naviguez jusqu'au dossier du dépôt de formation que vous venez de cloner et sélectionnez-le +- Cliquez sur **Ouvrir** + +### Rouvrir dans le conteneur + +Si VS Code vous invite à « Reopen in Container », cliquez dessus. Sinon : + +- Appuyez sur F1 (ou Ctrl+Shift+P / Cmd+Shift+P sur macOS) +- Tapez « Dev Containers: Reopen in Container » +- **Important** : Lorsque vous êtes invité à sélectionner une configuration, choisissez la configuration devcontainer **local-dev** + +![Invite Rouvrir dans le conteneur](img/reopen_prompt.png) + +![Sélection de la configuration locale](img/select_local_config.png) + +Attendez que le conteneur soit construit. Cela peut prendre quelques minutes la première fois car il télécharge et configure tous les composants nécessaires. + +Une fois le conteneur construit et en cours d'exécution, vous aurez un environnement entièrement configuré avec tous les outils nécessaires installés, notamment : + +- Java +- Nextflow +- Docker +- Git +- Et toutes les autres dépendances requises pour la formation + +![VS Code avec devcontainer en cours d'exécution](img/running_container.png) + +## Avantages de l'utilisation des Devcontainers + +L'utilisation de l'approche devcontainer offre plusieurs avantages : + +- **Cohérence** : Assure un environnement de développement cohérent sur différentes machines +- **Simplicité** : Toutes les dépendances sont préinstallées et configurées +- **Isolation** : L'environnement de développement est isolé de votre système local +- **Reproductibilité** : Tous ceux qui utilisent le devcontainer obtiennent la même configuration +- **Pas d'installation manuelle** : Pas besoin d'installer manuellement Java, Nextflow et d'autres outils + +## Vérification de votre environnement + +Une fois votre devcontainer en cours d'exécution, vous pouvez vérifier que tout est correctement configuré en exécutant : + +```bash +nextflow info +``` + +Cela devrait afficher la version de Nextflow et les informations d'exécution, confirmant que votre environnement est correctement configuré. + +## Dépannage + +Si vous rencontrez des problèmes avec la configuration du devcontainer : + +1. Assurez-vous que votre installation Docker (Docker Desktop, Colima, Docker Engine, etc.) est en cours d'exécution avant d'ouvrir le devcontainer +2. Vérifiez que vous avez sélectionné la configuration **local-dev** lorsque vous y êtes invité +3. Vérifiez que Docker buildx est installé et fonctionne en exécutant `docker buildx version` +4. Si le conteneur ne parvient pas à se construire, essayez de le reconstruire en exécutant la commande « Dev Containers: Rebuild Container » +5. Pour les problèmes persistants, consultez le [guide de dépannage Dev Containers de VS Code](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/fr/docs/envsetup/index.md b/docs/fr/docs/envsetup/index.md new file mode 100644 index 0000000000..6ade0e58a9 --- /dev/null +++ b/docs/fr/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Options d'environnement +description: Options pour configurer votre environnement pour les formations Nextflow +hide: + - toc + - footer +--- + +# Options d'environnement + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nous visons à fournir un environnement cohérent et minutieusement testé qui permet aux apprenants de se concentrer sur l'apprentissage de Nextflow sans avoir à consacrer du temps et des efforts à la gestion des logiciels. +À cette fin, nous avons développé un environnement conteneurisé qui contient tous les logiciels, fichiers de code et données d'exemple nécessaires pour suivre tous nos cours. + +Cet environnement conteneurisé peut être exécuté directement sur GitHub Codespaces ou localement dans VS Code avec l'extension Devcontainers. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **GitHub Codespaces** + + *** + + GitHub Codespaces est un service web qui nous permet de fournir un environnement pré-construit pour la formation, avec tous les outils et données inclus, soutenu par des machines virtuelles dans le cloud. Il est accessible gratuitement à toute personne possédant un compte GitHub. + + [Utiliser GitHub Codespaces :material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Devcontainers locaux** + + *** + + VS Code avec Devcontainers fournit un environnement de développement conteneurisé exécuté localement avec tous les outils de formation préconfigurés. Il offre le même environnement pré-construit que Codespaces mais s'exécute entièrement sur votre matériel local. + + [Utiliser Devcontainers localement :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Instructions pour l'installation manuelle + +Si aucune des options ci-dessus ne convient à vos besoins, vous pouvez reproduire cet environnement sur votre propre système local en installant manuellement les dépendances logicielles et en clonant le dépôt de formation. + +[Installation manuelle :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Dépréciation de Gitpod" + + La formation Nextflow utilisait [Gitpod](https://gitpod.io) jusqu'en février 2025. + Cependant, les créateurs de Gitpod ont décidé de retirer la fonctionnalité gratuite au profit du système [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex). + Pour cette raison, nous sommes passés à l'utilisation de GitHub Codespaces, qui offre également un environnement de développement en un clic sans configuration préalable. + + Selon le moment où vous vous êtes inscrit à Gitpod et le moment exact où ils retireront le service, vous pourriez encore être en mesure de lancer la formation dans leur ancien IDE cloud, bien que nous ne puissions pas garantir un accès fiable à l'avenir : + [Ouvrir dans Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/fr/docs/hello_nextflow/00_orientation.md b/docs/fr/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..3891c39955 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Premiers pas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/00_orientation.md). +/// + +!!! tip "Astuce" + + Les vidéos YouTube ont des super pouvoirs ! + + - :fontawesome-solid-closed-captioning: Sous-titres de haute qualité (révisés manuellement). Activez-les avec l'icône :material-subtitles: + - :material-bookmark: Chapitres vidéo dans la timeline qui correspondent aux titres de la page. + +## Démarrer un environnement de formation + +Pour utiliser l'environnement pré-construit que nous fournissons sur GitHub Codespaces, cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous. Pour d'autres options, voir [Options d'environnement](../envsetup/index.md). + +Nous vous recommandons d'ouvrir l'environnement de formation dans un nouvel onglet ou une nouvelle fenêtre de navigateur (utilisez le clic droit, ctrl-clic ou cmd-clic selon votre équipement) afin de pouvoir continuer à lire pendant le chargement de l'environnement. +Vous devrez garder ces instructions ouvertes en parallèle pour suivre le cours. + +[![Ouvrir dans GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Bases de l'environnement + +Cet environnement de formation contient tous les logiciels, le code et les données nécessaires pour suivre le cours de formation, vous n'avez donc rien à installer vous-même. + +Le codespace est configuré avec une interface VSCode, qui comprend un explorateur de système de fichiers, un éditeur de code et un terminal shell. +Toutes les instructions données pendant le cours (par exemple « ouvrir le fichier », « modifier le code » ou « exécuter cette commande ») font référence à ces trois parties de l'interface VSCode, sauf indication contraire. + +Si vous suivez ce cours par vous-même, veuillez vous familiariser avec les [bases de l'environnement](../envsetup/01_setup.md) pour plus de détails. + +### Exigences de version + +Cette formation est conçue pour Nextflow 25.10.2 ou ultérieur **avec le parseur de syntaxe v2 ACTIVÉ**. +Si vous utilisez un environnement local ou personnalisé, veuillez vous assurer que vous utilisez les bons paramètres comme documenté [ici](../info/nxf_versions.md). + +## Se préparer à travailler + +Une fois votre codespace en cours d'exécution, il y a deux choses que vous devez faire avant de plonger dans la formation : définir votre répertoire de travail pour ce cours spécifique et examiner les supports fournis. + +### Définir le répertoire de travail + +Par défaut, le codespace s'ouvre avec le répertoire de travail défini à la racine de tous les cours de formation, mais pour ce cours, nous travaillerons dans le répertoire `hello-nextflow/`. + +Changez de répertoire maintenant en exécutant cette commande dans le terminal : + +```bash +cd hello-nextflow/ +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire, de sorte que seuls les fichiers pertinents s'affichent dans la barre latérale de l'explorateur de fichiers : + +```bash +code . +``` + +!!! tip "Astuce" + + Si pour une raison quelconque vous sortez de ce répertoire (par exemple, votre codespace se met en veille), vous pouvez toujours utiliser le chemin complet pour y revenir, en supposant que vous l'exécutez dans l'environnement de formation GitHub Codespaces : + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Examinons maintenant le contenu. + +### Explorer les supports fournis + +Vous pouvez explorer le contenu de ce répertoire en utilisant l'explorateur de fichiers sur le côté gauche de l'espace de travail de formation. +Sinon, vous pouvez utiliser la commande `tree`. + +Tout au long du cours, nous utilisons la sortie de `tree` pour représenter la structure des répertoires et le contenu sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 2 +``` + +??? abstract "Contenu du répertoire" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Cliquez sur la boîte colorée pour développer la section et voir son contenu. +Nous utilisons des sections pliables comme celle-ci pour inclure la sortie de commande attendue de manière concise. + +- **Les fichiers `.nf`** sont des scripts de flux de travail nommés en fonction de la partie du cours où ils sont utilisés. + +- **Le fichier `nextflow.config`** est un fichier de configuration qui définit des propriétés d'environnement minimales. + Vous pouvez l'ignorer pour l'instant. + +- **Le fichier `greetings.csv`** sous `data/` contient les données d'entrée que nous utiliserons dans la majeure partie du cours. Il est décrit dans la Partie 2 (Channels), lorsque nous l'introduisons pour la première fois. + +- **Les fichiers `test-params.*`** sont des fichiers de configuration que nous utiliserons dans la Partie 6 (Configuration). Vous pouvez les ignorer pour l'instant. + +- **Le répertoire `solutions`** contient les scripts de flux de travail complétés qui résultent de chaque étape du cours. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre les éventuels problèmes. + +## Liste de vérification de préparation + +Vous pensez être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon environnement est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +**Pour continuer vers la [Partie 1 : Hello World](./01_hello_world.md), cliquez sur la flèche dans le coin inférieur droit de cette page.** diff --git a/docs/fr/docs/hello_nextflow/01_hello_world.md b/docs/fr/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..5f368c7eaa --- /dev/null +++ b/docs/fr/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Partie 1 : Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/01_hello_world.md). +/// + +Dans cette première partie du cours de formation Hello Nextflow, nous abordons le sujet avec un exemple Hello World très basique et indépendant du domaine, que nous allons progressivement enrichir pour démontrer l'utilisation de la logique et des composants fondamentaux de Nextflow. + +??? info "Qu'est-ce qu'un exemple Hello World ?" + + Un « Hello World ! » est un exemple minimaliste destiné à démontrer la syntaxe de base et la structure d'un langage de programmation ou d'un framework logiciel. + L'exemple consiste généralement à imprimer la phrase « Hello, World! » sur le périphérique de sortie, comme la console ou le terminal, ou à l'écrire dans un fichier. + +--- + +## 0. Échauffement : Exécuter un exemple Hello World directement + +Démontrons ceci avec une commande simple que nous exécutons directement dans le terminal, pour montrer ce qu'elle fait avant de l'encapsuler dans Nextflow. + +!!! tip "Astuce" + + N'oubliez pas que vous devriez maintenant être dans le répertoire `hello-nextflow/` comme décrit sur la page [Premiers pas](00_orientation.md). + +### 0.1. Faire dire bonjour au terminal + +Exécutez la commande suivante dans votre terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Sortie de la commande" + + ```console + Hello World! + ``` + +Cela affiche le texte « Hello World » directement dans le terminal. + +### 0.2. Écrire la sortie dans un fichier + +L'exécution de pipelines implique principalement la lecture de données à partir de fichiers et l'écriture de résultats dans d'autres fichiers, alors modifions la commande pour écrire la sortie texte dans un fichier afin de rendre l'exemple un peu plus pertinent. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Sortie de la commande" + + ```console + + ``` + +Cela n'affiche rien dans le terminal. + +### 0.3. Trouver la sortie + +Le texte « Hello World » devrait maintenant être dans le fichier de sortie que nous avons spécifié, nommé `output.txt`. +Vous pouvez l'ouvrir dans l'explorateur de fichiers ou depuis la ligne de commande en utilisant l'utilitaire `cat`, par exemple. + +??? abstract "Contenu du fichier" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +C'est ce que nous allons essayer de reproduire avec notre tout premier flux de travail Nextflow. + +### À retenir + +Vous savez maintenant comment exécuter une commande simple dans le terminal qui affiche du texte, et optionnellement, comment lui faire écrire la sortie dans un fichier. + +### Et ensuite ? + +Découvrez à quoi cela ressemblerait écrit comme un flux de travail Nextflow. + +--- + +## 1. Examiner le script et l'exécuter + +Nous vous fournissons un script de flux de travail pleinement fonctionnel, bien que minimaliste, nommé `hello-world.nf` qui fait la même chose qu'avant (écrire « Hello World! ») mais avec Nextflow. + +Pour commencer, ouvrons le script de flux de travail afin que vous puissiez avoir une idée de sa structure. +Ensuite, nous l'exécuterons et chercherons ses sorties. + +### 1.1. Examiner le code + +Vous trouverez le script `hello-world.nf` dans votre répertoire actuel, qui devrait être `hello-nextflow`. Ouvrez-le dans le panneau de l'éditeur. + +??? full-code "Fichier de code complet" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // émettre une salutation + sayHello() + } + ``` + +Un script de flux de travail Nextflow comprend généralement une ou plusieurs définitions de **processus** et le **flux de travail** lui-même, plus quelques blocs optionnels (non présents ici) que nous présenterons plus tard. + +Chaque **processus** décrit quelle(s) opération(s) l'étape correspondante dans le pipeline devrait accomplir, tandis que le **workflow** décrit la logique de flux de données qui connecte les différentes étapes. + +Nous allons d'abord examiner de plus près le bloc **process**, puis nous examinerons le bloc **workflow**. + +#### 1.1.1. La définition du `process` + +Le premier bloc de code décrit un **processus**. + +La définition du processus commence par le mot-clé `process`, suivi du nom du processus et enfin du corps du processus délimité par des accolades. +Le corps du processus doit contenir un bloc script qui spécifie la commande à exécuter, qui peut être n'importe quoi que vous pourriez exécuter dans un terminal de ligne de commande. + +```groovy title="hello-world.nf" linenums="3" +/* +* Utilise echo pour imprimer 'Hello World!' dans un fichier +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Ici, nous avons un **processus** appelé `sayHello` qui écrit sa **sortie** dans un fichier nommé `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +C'est une définition de processus très minimale qui contient juste une définition de `output` et le `script` à exécuter. + +La définition de `output` inclut le qualificateur `path`, qui indique à Nextflow que cela doit être traité comme un chemin (inclut à la fois les chemins de répertoires et les fichiers). +Un autre qualificateur courant est `val`. + +Il est important de noter que la définition de sortie ne _détermine_ pas quelle sortie sera créée. +Elle _déclare_ simplement quelle est la sortie attendue, afin que Nextflow puisse la rechercher une fois l'exécution terminée. +Ceci est nécessaire pour vérifier que la commande a été exécutée avec succès et pour transmettre la sortie aux processus en aval si nécessaire. Les sorties produites qui ne correspondent pas à ce qui est déclaré dans le bloc output ne seront pas transmises aux processus en aval. + +!!! warning "Avertissement" + + Cet exemple est fragile car nous avons codé en dur le nom du fichier de sortie à deux endroits séparés (les blocs script et output). + Si nous changeons l'un mais pas l'autre, le script ne fonctionnera plus. + Plus tard, vous apprendrez des moyens d'utiliser des variables pour atténuer ce problème. + +Dans un pipeline réel, un processus contient généralement des blocs supplémentaires tels que des directives et des entrées, que nous présenterons dans un instant. + +#### 1.1.2. La définition du `workflow` + +Le deuxième bloc de code décrit le **workflow** lui-même. +La définition du workflow commence par le mot-clé `workflow`, suivi d'un nom optionnel, puis du corps du workflow délimité par des accolades. + +Ici, nous avons un **workflow** qui consiste en un bloc `main:` (qui dit « ceci est le corps principal du workflow ») contenant un appel au processus `sayHello`. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // émettre une salutation + sayHello() +} +``` + +C'est une définition de **workflow** très minimale. +Dans un pipeline réel, le workflow contient généralement plusieurs appels à des **processus** connectés par des **canaux**, et les processus attendent une ou plusieurs **entrée(s)** variable(s). + +Vous apprendrez comment ajouter des entrées variables plus tard dans ce module de formation ; et vous apprendrez comment ajouter plus de processus et les connecter par des canaux dans la Partie 3 de ce cours. + +!!! tip "Astuce" + + Techniquement, la ligne `main:` n'est pas requise pour les workflows simples comme celui-ci, vous pouvez donc rencontrer des workflows qui ne l'ont pas. + Mais nous en aurons besoin pour profiter des sorties au niveau du workflow, donc autant l'inclure dès le départ. + +### 1.2. Exécuter le flux de travail + +Regarder du code n'est pas aussi amusant que de l'exécuter, alors essayons cela en pratique. + +#### 1.2.1. Lancer le flux de travail et surveiller l'exécution + +Dans le terminal, exécutez la commande suivante : + +```bash +nextflow run hello-world.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Si votre sortie console ressemble à cela, alors félicitations, vous venez d'exécuter votre premier flux de travail Nextflow ! + +La sortie la plus importante ici est la dernière ligne, qui est mise en évidence dans la sortie ci-dessus : + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Cela nous indique que le processus `sayHello` a été exécuté avec succès une fois (`1 of 1 ✔`). + +De manière importante, cette ligne vous indique également où trouver la sortie de l'appel au processus `sayHello`. +Examinons cela maintenant. + +#### 1.2.2. Trouver la sortie et les logs dans le répertoire `work` + +Lorsque vous exécutez Nextflow pour la première fois dans un répertoire donné, il crée un répertoire appelé `work` où il écrira tous les fichiers (et tous les liens symboliques) générés au cours de l'exécution. + +Dans le répertoire `work`, Nextflow organise les sorties et les logs par appel de processus. +Pour chaque appel de processus, Nextflow crée un sous-répertoire imbriqué, nommé avec un hash pour le rendre unique, où il préparera toutes les entrées nécessaires (en utilisant des liens symboliques par défaut), écrira les fichiers d'aide, et écrira les logs et toutes les sorties du processus. + +Le chemin vers ce sous-répertoire est affiché sous forme tronquée entre crochets dans la sortie console. +En regardant ce que nous avons obtenu pour l'exécution montrée ci-dessus, la ligne de log console pour le processus sayHello commence par `[65/7be2fa]`. Cela correspond au chemin de répertoire suivant : `work/65/7be2fad5e71e5f49998f795677fd68` + +Voyons ce qu'il y a dedans. + +??? abstract "Contenu du répertoire" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Vous ne voyez pas la même chose ?" + + Les noms exacts des sous-répertoires seront différents sur votre système. + + Si vous parcourez le contenu du sous-répertoire de tâche dans l'explorateur de fichiers VSCode, vous verrez tous les fichiers immédiatement. + Cependant, les fichiers de log sont configurés pour être invisibles dans le terminal, donc si vous voulez utiliser `ls` ou `tree` pour les voir, vous devrez définir l'option pertinente pour afficher les fichiers invisibles. + + ```bash + tree -a work + ``` + +La première chose que vous voulez regarder est la sortie réelle du flux de travail, c'est-à-dire le fichier `output.txt` produit par le processus `sayHello`. +Ouvrez-le et vous trouverez la salutation `Hello World!`, qui était le but de notre flux de travail minimaliste. + +??? abstract "Contenu du fichier" + + ```console title="output.txt" + Hello World! + ``` + +Ça a fonctionné ! + +Certes, cela peut sembler beaucoup de code d'enveloppe pour un si petit résultat, mais la valeur de tout ce code d'enveloppe deviendra plus évidente une fois que nous commencerons à lire des fichiers d'entrée et à enchaîner plusieurs étapes. + +Cela dit, examinons également les autres fichiers dans ce répertoire. Ce sont des fichiers d'aide et de log produits par Nextflow dans le cadre de l'exécution de la tâche. + +- **`.command.begin`** : Métadonnées liées au début de l'exécution de l'appel de processus +- **`.command.err`** : Messages d'erreur (`stderr`) émis par l'appel de processus +- **`.command.log`** : Sortie de log complète émise par l'appel de processus +- **`.command.out`** : Sortie régulière (`stdout`) de l'appel de processus +- **`.command.run`** : Script complet exécuté par Nextflow pour exécuter l'appel de processus +- **`.command.sh`** : La commande qui a été réellement exécutée par l'appel de processus +- **`.exitcode`** : Le code de sortie résultant de la commande + +Le fichier `.command.sh` est particulièrement utile car il vous indique la commande principale que Nextflow a exécutée, sans inclure toute la comptabilité et la configuration de la tâche/de l'environnement. + +??? abstract "Contenu du fichier" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Cela correspond à ce que nous avons exécuté manuellement plus tôt. + +Dans ce cas, c'est très simple car la commande du processus était codée en dur, mais plus tard dans le cours, vous verrez des commandes de processus qui impliquent une interpolation de variables. +Cela rend particulièrement précieux de pouvoir voir exactement comment Nextflow a interprété le code et quelle commande a été produite lorsque vous dépannez une exécution échouée. + +### 1.3. Exécuter à nouveau le flux de travail + +Essayez de ré-exécuter le flux de travail plusieurs fois, puis regardez les répertoires de tâches sous `work/`. + +??? abstract "Contenu du répertoire" + + ```console + 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 + ``` + +Vous voyez qu'un nouveau sous-répertoire avec un ensemble complet de fichiers de sortie et de log a été créé pour chaque exécution. +Cela vous montre que l'exécution du même flux de travail plusieurs fois n'écrasera pas les résultats des exécutions précédentes. + +### À retenir + +Vous savez comment déchiffrer un script Nextflow simple, l'exécuter et trouver la sortie et les fichiers de log pertinents dans le répertoire work. + +### Et ensuite ? + +Apprendre à publier les sorties du flux de travail dans un emplacement plus pratique. + +--- + +## 2. Publier les sorties + +Comme vous venez de l'apprendre, la sortie produite par notre pipeline est enfouie dans un répertoire de travail situé plusieurs niveaux plus bas. +Ceci est fait exprès ; Nextflow contrôle ce répertoire et nous ne sommes pas censés interagir avec lui. +Cependant, cela rend peu pratique la récupération des sorties qui nous importent. + +Heureusement, Nextflow fournit un moyen de publier les sorties dans un répertoire désigné en utilisant des [définitions de sortie au niveau du workflow](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs). + +### 2.1. Utilisation de base + +Cela va impliquer deux nouveaux morceaux de code : + +1. Un bloc `publish:` à l'intérieur du corps du `workflow`, déclarant les sorties de processus. +2. Un bloc `output` au script spécifiant les options de sortie telles que le mode et l'emplacement. + +#### 2.1.1. Déclarer la sortie du processus `sayHello` + +Nous devons ajouter un bloc `publish:` au corps du workflow (même type d'élément de code que le bloc `main:`) et lister la sortie du processus `sayHello()`. + +Dans le fichier de script de workflow `hello-world.nf`, ajoutez les lignes de code suivantes : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // émettre une salutation + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // émettre une salutation + sayHello() + } + ``` + +Vous voyez que nous pouvons faire référence à la sortie du processus simplement en faisant `sayHello().out`, et lui attribuer un nom arbitraire, `first_output`. + +#### 2.1.2. Ajouter un bloc `output:` au script + +Maintenant nous avons juste besoin d'ajouter le bloc `output:` où le chemin du répertoire de sortie sera spécifié. Notez que ce nouveau bloc se situe **en dehors** et **en dessous** du bloc `workflow` dans le script. + +Dans le fichier de script de workflow `hello-world.nf`, ajoutez les lignes de code suivantes : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // émettre une salutation + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // émettre une salutation + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Nous pouvons utiliser ceci pour attribuer des chemins spécifiques à toutes les sorties de processus déclarées dans le bloc `workflow`. +Plus tard, vous apprendrez des moyens de générer des structures de répertoires de sortie sophistiquées, mais pour l'instant, nous codons juste en dur un chemin minimal pour plus de simplicité. + +#### 2.1.3. Exécuter le flux de travail + +Maintenant exécutez le script de workflow modifié : + +```bash +nextflow run hello-world.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +La sortie du terminal devrait sembler familière. Extérieurement, rien n'a changé. + +Cependant, vérifiez votre explorateur de fichiers : cette fois, Nextflow a créé un nouveau répertoire appelé `results/`. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +À l'intérieur du répertoire `results`, nous trouvons un lien symbolique vers le `output.txt` produit dans le répertoire work par la commande que nous venons d'exécuter. + +Cela nous permet de récupérer facilement les fichiers de sortie sans avoir à fouiller dans le sous-répertoire work. + +### 2.2. Définir un emplacement personnalisé + +Avoir un emplacement par défaut est bien, mais vous pourriez vouloir personnaliser où les résultats sont enregistrés et comment ils sont organisés. + +Par exemple, vous pouvez vouloir organiser vos sorties dans des sous-répertoires. +La façon la plus simple de le faire est d'attribuer un chemin de sortie spécifique par sortie. + +#### 2.2.1. Modifier le chemin de sortie + +Encore une fois, modifier le comportement de publication pour une sortie spécifique est vraiment simple. +Pour définir un emplacement personnalisé, modifiez simplement le `path` en conséquence : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Puisque ceci est défini au niveau de la sortie individuelle, vous pouvez spécifier différents emplacements et sous-répertoires selon vos besoins. + +#### 2.2.2. Exécuter à nouveau le flux de travail + +Essayons-le. + +```bash +nextflow run hello-world.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Cette fois, le résultat est écrit sous le sous-répertoire spécifié. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Vous voyez que le résultat de l'exécution précédente est toujours là. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +Vous pouvez utiliser autant de niveaux d'imbrication que vous le souhaitez. +Il est également possible d'utiliser le nom du processus ou d'autres variables pour nommer les répertoires utilisés pour organiser les résultats, et il est possible de changer le nom par défaut du répertoire de sortie de niveau supérieur (qui est contrôlé par la variable spéciale `outputDir`). +Nous couvrirons ces options dans des formations ultérieures. + +### 2.3. Définir le mode de publication sur copy + +Par défaut, les sorties sont publiées comme des liens symboliques depuis le répertoire `work`. +Cela signifie qu'il n'y a qu'un seul fichier sur le système de fichiers. + +C'est très bien lorsque vous travaillez avec de très gros fichiers, pour lesquels vous ne voulez pas stocker plusieurs copies. +Cependant, si vous supprimez le répertoire work à un moment donné (nous couvrirons les opérations de nettoyage sous peu), vous perdrez l'accès au fichier. +Vous devez donc avoir un plan pour sauvegarder des copies de tous les fichiers importants dans un endroit sûr. + +Une option facile est de basculer le mode de publication sur copy pour les sorties qui vous importent. + +#### 2.3.1. Ajouter la directive mode + +Cette partie est vraiment simple. +Ajoutez simplement `mode 'copy'` à la définition de sortie au niveau du workflow concernée : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Cela définit le mode de publication pour cette sortie spécifique. + +#### 2.3.2. Exécuter à nouveau le flux de travail + +Essayons-le. + +```bash +nextflow run hello-world.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Cette fois, si vous regardez les résultats, le fichier est une vraie copie au lieu d'un simple lien symbolique. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Puisque ceci aussi est défini au niveau de la sortie individuelle, cela vous permet de définir le mode de publication de manière granulaire. +Cela sera particulièrement pratique plus tard lorsque nous passerons à des pipelines à plusieurs étapes, où vous pourriez vouloir copier uniquement les sorties finales et laisser les sorties intermédiaires comme liens symboliques, par exemple. + +Comme noté précédemment, il existe d'autres options plus sophistiquées pour contrôler comment les sorties sont publiées. +Nous vous montrerons comment les utiliser en temps voulu dans votre parcours Nextflow. + +### 2.4. Note sur les directives `publishDir` au niveau du processus + +Jusqu'à très récemment, la façon établie de publier les sorties était de le faire au niveau de chaque processus individuel en utilisant une directive `publishDir`. + +Pour obtenir ce que nous venons de faire pour les sorties du processus `sayHello`, nous aurions plutôt ajouté la ligne suivante à la définition du processus : + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Vous trouverez encore ce modèle de code partout dans les anciens pipelines Nextflow et modules de processus, il est donc important d'en être conscient. +Cependant, nous ne recommandons pas de l'utiliser dans tout nouveau travail car il sera éventuellement interdit dans les futures versions du langage Nextflow. + +### À retenir + +Vous savez comment publier les sorties du flux de travail dans un emplacement plus pratique. + +### Et ensuite ? + +Apprendre à fournir une entrée variable via un paramètre de ligne de commande et utiliser efficacement les valeurs par défaut. + +--- + +## 3. Utiliser une entrée variable passée en ligne de commande + +Dans son état actuel, notre flux de travail utilise une salutation codée en dur dans la commande du processus. +Nous voulons ajouter de la flexibilité en utilisant une variable d'entrée, afin de pouvoir plus facilement changer la salutation au moment de l'exécution. + +Cela nécessite que nous apportions trois ensembles de modifications à notre script : + +1. Modifier le processus pour attendre une entrée variable +2. Configurer un paramètre de ligne de commande pour capturer l'entrée utilisateur +3. Passer l'entrée au processus dans le corps du workflow + +Faisons ces modifications une à la fois. + +### 3.1. Modifier le processus `sayHello` pour attendre une entrée variable + +Nous devons modifier la définition du processus pour (1) accepter une variable d'entrée et (2) utiliser cette variable dans la ligne de commande. + +#### 3.1.1. Ajouter un bloc input à la définition du processus + +D'abord, adaptons la définition du processus pour accepter une entrée appelée `greeting`. + +Dans le bloc process, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +La variable `greeting` est préfixée par `val` pour indiquer à Nextflow que c'est une valeur (pas un chemin). + +#### 3.1.2. Modifier la commande du processus pour utiliser la variable d'entrée + +Maintenant nous échangeons la valeur originale codée en dur pour la valeur de la variable d'entrée que nous attendons de recevoir. + +Dans le bloc process, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +Le symbole `$` et les accolades (`{ }`) indiquent à Nextflow que c'est un nom de variable qui doit être remplacé par la valeur d'entrée réelle (=interpolé). + +!!! tip "Astuce" + + Les accolades (`{ }`) étaient techniquement optionnelles dans les versions précédentes de Nextflow, vous pourriez donc voir des anciens workflows où ceci est écrit comme `echo '$greeting' > output.txt`. + +Maintenant que le processus `sayHello()` est prêt à accepter une entrée variable, nous avons besoin d'un moyen de fournir une valeur d'entrée à l'appel du processus au niveau du workflow. + +### 3.2. Configurer un paramètre de ligne de commande pour capturer l'entrée utilisateur + +Nous pourrions simplement coder en dur une entrée directement en faisant l'appel de processus `sayHello('Hello World!')`. +Cependant, lorsque nous faisons un vrai travail avec notre flux de travail, nous allons vouloir pouvoir contrôler ses entrées depuis la ligne de commande. + +Bonne nouvelle : Nextflow dispose d'un système de paramètres de workflow intégré appelé `params`, qui facilite la déclaration et l'utilisation des paramètres CLI. + +La syntaxe générale est de déclarer `params.<nom_paramètre>` pour indiquer à Nextflow d'attendre un paramètre `--<nom_paramètre>` sur la ligne de commande. + +Ici, nous voulons créer un paramètre appelé `--input`, donc nous devons déclarer `params.input` quelque part dans le workflow. +En principe, nous pouvons l'écrire n'importe où ; mais puisque nous allons vouloir le donner à l'appel du processus `sayHello()`, nous pouvons le brancher directement là en écrivant `sayHello(params.input)`. + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // émettre une salutation + sayHello(params.input) + ``` + +=== "Avant" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // émettre une salutation + sayHello() + ``` + +Cela indique à Nextflow d'exécuter le processus `sayHello` sur la valeur fournie via le paramètre `--input`. + +En effet, nous avons accompli les étapes (2) et (3) décrites au début de la section en une seule fois. + +### 3.3. Exécuter la commande du flux de travail + +Exécutons-le ! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Si vous avez fait toutes ces modifications correctement, vous devriez obtenir une autre exécution réussie. + +Assurez-vous d'ouvrir le fichier de sortie pour vérifier que vous avez maintenant la nouvelle version de la salutation. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà ! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Notez comment la nouvelle exécution a écrasé le fichier de sortie publié dans le répertoire `results`. +Cependant, les résultats des exécutions précédentes sont toujours préservés dans les répertoires de tâches sous `work`. + +!!! tip "Astuce" + + Vous pouvez facilement distinguer les paramètres au niveau de Nextflow des paramètres au niveau du pipeline. + + - Les paramètres qui s'appliquent à un pipeline prennent toujours un double tiret (`--`). + - Les paramètres qui modifient un paramètre Nextflow, _par exemple_ la fonctionnalité `-resume` que nous avons utilisée précédemment, prennent un simple tiret (`-`). + +### 3.4. Utiliser des valeurs par défaut pour les paramètres de ligne de commande + +D'accord, c'était pratique, mais dans de nombreux cas, il est logique de fournir une valeur par défaut pour un paramètre donné afin de ne pas avoir à le spécifier à chaque exécution. + +#### 3.4.1. Définir une valeur par défaut pour le paramètre CLI + +Donnons au paramètre `input` une valeur par défaut en le déclarant avant la définition du workflow. + +```groovy title="hello-world.nf" linenums="20" +/* + * Paramètres du pipeline + */ +params { + input: String = 'Holà mundo!' +} +``` + +Comme vous pouvez le voir, nous pouvons spécifier le type d'entrée que le workflow attend (Nextflow 25.10.2 et ultérieur). +La syntaxe est `nom: Type = valeur_par_defaut`. +Les types supportés incluent `String`, `Integer`, `Float`, `Boolean` et `Path`. + +!!! info "Information" + + Dans les anciens workflows, vous pouvez voir que tout ce bloc `params` est écrit simplement comme `input = 'Holà mundo!'`. + +À mesure que vous ajoutez plus de paramètres à votre pipeline, vous devriez tous les ajouter à ce bloc, que vous ayez besoin de leur donner une valeur par défaut ou non. +Cela facilitera la recherche de tous les paramètres configurables en un coup d'œil. + +#### 3.4.2. Exécuter à nouveau le flux de travail sans spécifier le paramètre + +Maintenant que vous avez une valeur par défaut définie, vous pouvez exécuter à nouveau le flux de travail sans avoir à spécifier une valeur en ligne de commande. + +```bash +nextflow run hello-world.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +La sortie sera au même endroit que précédemment, mais le contenu devrait être mis à jour avec le nouveau texte. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow a utilisé la valeur par défaut du paramètre greeting pour créer la sortie. + +#### 3.4.3. Remplacer la valeur par défaut + +Si vous fournissez le paramètre en ligne de commande, la valeur CLI remplacera la valeur par défaut. + +Essayez-le : + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Encore une fois, vous devriez trouver la sortie mise à jour correspondante dans votre répertoire de résultats. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Note" + + Dans Nextflow, il y a plusieurs endroits où vous pouvez spécifier des valeurs pour les paramètres. + Si le même paramètre est défini à des valeurs différentes à plusieurs endroits, Nextflow déterminera quelle valeur utiliser en fonction de l'ordre de priorité qui est décrit [ici](https://www.nextflow.io/docs/latest/config.html). + + Nous couvrirons cela plus en détail dans la Partie 6 (Configuration). + +### À retenir + +Vous savez comment utiliser une simple entrée variable fournie au moment de l'exécution via un paramètre de ligne de commande, ainsi que comment configurer, utiliser et remplacer les valeurs par défaut. + +### Et ensuite ? + +Apprendre à gérer les exécutions de flux de travail de manière plus pratique. + +--- + +## 4. Gérer les exécutions de flux de travail + +Savoir comment lancer des flux de travail et récupérer les sorties est très bien, mais vous découvrirez rapidement qu'il y a quelques autres aspects de la gestion des flux de travail qui vous faciliteront la vie, surtout si vous développez vos propres flux de travail. + +Ici, nous vous montrons comment utiliser la fonctionnalité `resume` lorsque vous devez relancer le même flux de travail, comment inspecter le journal des exécutions passées avec `nextflow log`, et comment supprimer les anciens répertoires de travail avec `nextflow clean`. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. Relancer un flux de travail avec `-resume` + +Parfois, vous allez vouloir relancer un pipeline que vous avez déjà lancé précédemment sans refaire les étapes qui se sont déjà terminées avec succès. + +Nextflow a une option appelée `-resume` qui vous permet de faire cela. +Spécifiquement, dans ce mode, tous les processus qui ont déjà été exécutés avec exactement le même code, les mêmes paramètres et les mêmes entrées seront ignorés. +Cela signifie que Nextflow n'exécutera que les processus que vous avez ajoutés ou modifiés depuis la dernière exécution, ou ceux auxquels vous fournissez de nouveaux paramètres ou entrées. + +Il y a deux avantages clés à faire cela : + +- Si vous êtes en train de développer votre pipeline, vous pouvez itérer plus rapidement puisque vous n'avez qu'à exécuter le(s) processus sur le(s)quel(s) vous travaillez activement pour tester vos modifications. +- Si vous exécutez un pipeline en production et que quelque chose se passe mal, dans de nombreux cas vous pouvez corriger le problème et relancer le pipeline, et il reprendra l'exécution à partir du point d'échec, ce qui peut vous faire gagner beaucoup de temps et de calcul. + +Pour l'utiliser, ajoutez simplement `-resume` à votre commande et exécutez-la : + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Sortie de la commande" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +La sortie console devrait sembler familière, mais il y a une chose qui est un peu différente par rapport à avant. + +Cherchez la partie `cached:` qui a été ajoutée dans la ligne d'état du processus (ligne 5), ce qui signifie que Nextflow a reconnu qu'il a déjà fait ce travail et a simplement réutilisé le résultat de l'exécution réussie précédente. + +Vous pouvez également voir que le hash du sous-répertoire work est le même que lors de l'exécution précédente. +Nextflow vous indique littéralement l'exécution précédente et dit « J'ai déjà fait cela là-bas. » + +!!! tip "Astuce" + + Lorsque vous relancez un pipeline avec `resume`, Nextflow n'écrase pas les fichiers publiés en dehors du répertoire work par les exécutions qui se sont terminées avec succès précédemment. + +### 4.2. Inspecter le journal des exécutions passées + +Que vous développiez un nouveau pipeline ou que vous exécutiez des pipelines en production, à un moment donné vous aurez probablement besoin de rechercher des informations sur les exécutions passées. +Voici comment faire. + +Chaque fois que vous lancez un flux de travail Nextflow, une ligne est écrite dans un fichier journal appelé `history`, sous un répertoire caché appelé `.nextflow` dans le répertoire de travail actuel. + +??? abstract "Contenu du fichier" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Ce fichier vous donne l'horodatage, le nom d'exécution, le statut, l'ID de révision, l'ID de session et la ligne de commande complète pour chaque exécution Nextflow qui a été lancée depuis le répertoire de travail actuel. + +Une façon plus pratique d'accéder à ces informations est d'utiliser la commande `nextflow log`. + +```bash +nextflow log +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Cela affichera le contenu du fichier journal dans le terminal, augmenté d'une ligne d'en-tête. + +Vous remarquerez que l'ID de session change chaque fois que vous exécutez une nouvelle commande `nextflow run`, SAUF si vous utilisez l'option `-resume`. +Dans ce cas, l'ID de session reste le même. + +Nextflow utilise l'ID de session pour regrouper les informations de mise en cache d'exécution sous le répertoire `cache`, également situé sous `.nextflow`. + +### 4.3. Supprimer les anciens répertoires de travail + +Pendant le processus de développement, vous exécuterez généralement votre pipeline en cours d'élaboration un grand nombre de fois, ce qui peut conduire à une accumulation de nombreux fichiers dans de nombreux sous-répertoires. + +Heureusement, Nextflow inclut une sous-commande `clean` utile qui peut automatiquement supprimer les sous-répertoires de travail des exécutions passées dont vous ne vous souciez plus. + +#### 4.3.1. Déterminer les critères de suppression + +Il existe plusieurs [options](https://www.nextflow.io/docs/latest/reference/cli.html#clean) pour déterminer ce qu'il faut supprimer. + +Ici, nous vous montrons un exemple qui supprime tous les sous-répertoires des exécutions avant une exécution donnée, spécifiée en utilisant son nom d'exécution. + +Recherchez l'exécution réussie la plus récente où vous n'avez pas utilisé `-resume` ; dans notre cas, le nom d'exécution était `golden_cantor`. + +Le nom d'exécution est la chaîne en deux parties générée par la machine affichée entre crochets dans la ligne de sortie console `Launching (...)`. +Vous pouvez également utiliser le journal Nextflow pour rechercher une exécution en fonction de son horodatage et/ou de sa ligne de commande. + +#### 4.3.2. Faire un essai à blanc + +D'abord, nous utilisons le drapeau d'essai à blanc `-n` pour vérifier ce qui sera supprimé avec la commande : + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Sortie de la commande" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Votre sortie aura des noms de répertoires de tâches différents et peut avoir un nombre de lignes différent, mais elle devrait ressembler à l'exemple. + +Si vous ne voyez aucune ligne en sortie, soit vous n'avez pas fourni un nom d'exécution valide, soit il n'y a pas d'exécutions passées à supprimer. Assurez-vous de changer `golden_cantor` dans la commande d'exemple par le nom d'exécution le plus récent correspondant dans votre journal. + +#### 4.3.3. Procéder à la suppression + +Si la sortie semble comme prévu et que vous voulez procéder à la suppression, relancez la commande avec le drapeau `-f` au lieu de `-n` : + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Sortie de la commande" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +La sortie devrait être similaire à avant, mais disant maintenant « Removed » au lieu de « Would remove ». +Notez que cela ne supprime pas les sous-répertoires à deux caractères (comme `a3/` ci-dessus) mais vide leur contenu. + +!!! warning "Avertissement" + + La suppression des sous-répertoires de travail des exécutions passées les supprime du cache de Nextflow et supprime toutes les sorties qui étaient stockées dans ces répertoires. + Cela signifie que cela brise la capacité de Nextflow à reprendre l'exécution sans relancer les processus correspondants. + + Vous êtes responsable de sauvegarder toutes les sorties qui vous importent ou sur lesquelles vous prévoyez de compter ! C'est la principale raison pour laquelle nous préférons utiliser le mode `copy` plutôt que le mode `symlink` pour la directive `publish`. + +### À retenir + +Vous savez comment publier les sorties dans un répertoire spécifique, relancer un pipeline sans répéter les étapes qui ont déjà été exécutées de manière identique, et utiliser la commande `nextflow clean` pour nettoyer les anciens répertoires de travail. + +Plus généralement, vous savez comment interpréter un flux de travail Nextflow simple, gérer son exécution et récupérer les sorties. + +### Et ensuite ? + +Faites une petite pause, vous l'avez bien mérité ! + +Quand vous êtes prêt, passez à la [**Partie 2 : Hello Channels**](./02_hello_channels.md) pour apprendre comment utiliser les canaux pour alimenter les entrées dans votre flux de travail, ce qui vous permettra de profiter du parallélisme de flux de données intégré de Nextflow et d'autres fonctionnalités puissantes. + +--- + +## Quiz + +<quiz> +Quels sont les composants minimaux requis d'un processus Nextflow ? +- [ ] Blocs input et output uniquement +- [x] Blocs output et script +- [ ] Blocs input, output et script +- [ ] Uniquement un bloc script + +En savoir plus : [1.1.1. La définition du processus](#111-la-definition-du-process) +</quiz> + +<quiz> +Quel est le but du bloc output dans un processus ? +- [ ] Imprimer les résultats dans la console +- [ ] Enregistrer les fichiers dans le répertoire work +- [x] Déclarer les sorties attendues du processus +- [ ] Définir les variables d'environnement + +En savoir plus : [1.1.1. La définition du processus](#111-la-definition-du-process) +</quiz> + +<quiz> +Quelle commande est utilisée pour exécuter un flux de travail Nextflow ? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +En regardant le répertoire work d'une tâche, quel fichier contient la commande réellement exécutée ? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +En savoir plus : [1.2.2. Trouver la sortie et les logs dans le répertoire `work`](#122-trouver-la-sortie-et-les-logs-dans-le-repertoire-work) +</quiz> + +<quiz> +Que fait le drapeau `-resume` ? +- [ ] Redémarre le flux de travail depuis le début +- [ ] Met le flux de travail en pause +- [x] Ignore les processus qui se sont déjà terminés avec succès +- [ ] Crée une sauvegarde du flux de travail + +En savoir plus : [4.1. Relancer un flux de travail avec `-resume`](#41-relancer-un-flux-de-travail-avec--resume) +</quiz> + +<quiz> +Quel est le mode par défaut pour publier les sorties du flux de travail ? +- [ ] Copier les fichiers dans le répertoire de sortie +- [x] Créer des liens symboliques dans le répertoire de sortie +- [ ] Déplacer les fichiers dans le répertoire de sortie +- [ ] Compresser les fichiers dans le répertoire de sortie + +En savoir plus : [2.3. Définir le mode de publication sur copy](#23-definir-le-mode-de-publication-sur-copy) +</quiz> + +<quiz> +Comment passez-vous une valeur de paramètre à un flux de travail Nextflow depuis la ligne de commande ? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +En savoir plus : [3.2. Configurer un paramètre de ligne de commande pour capturer l'entrée utilisateur](#32-configurer-un-parametre-de-ligne-de-commande-pour-capturer-lentree-utilisateur) +</quiz> + +<quiz> +Comment référencez-vous une variable à l'intérieur d'un bloc script Nextflow ? +- [ ] Utiliser la syntaxe `%variable%` +- [x] Utiliser la syntaxe `#!groovy ${variable}` +- [ ] Utiliser la syntaxe `{{variable}}` +- [ ] Utiliser la syntaxe `[variable]` +</quiz> diff --git a/docs/fr/docs/hello_nextflow/02_hello_channels.md b/docs/fr/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..9d607347c1 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Partie 2 : Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/02_hello_channels.md). +/// + +Dans la Partie 1 de ce cours (Hello World), nous vous avons montré comment fournir une entrée variable à un processus en fournissant l'entrée directement dans l'appel du processus : `sayHello(params.input)`. +C'était une approche délibérément simplifiée. +En pratique, cette approche a des limitations majeures ; à savoir qu'elle ne fonctionne que pour des cas très simples où nous voulons seulement exécuter le processus une fois, sur une seule valeur. +Dans la plupart des cas d'utilisation de flux de travail réalistes, nous voulons traiter plusieurs valeurs (données expérimentales pour plusieurs échantillons, par exemple), nous avons donc besoin d'une façon plus sophistiquée de gérer les entrées. + +C'est à cela que servent les **canaux** Nextflow. +Les canaux sont des files d'attente conçues pour gérer les entrées efficacement et les faire passer d'une étape à l'autre dans des flux de travail à plusieurs étapes, tout en fournissant un parallélisme intégré et de nombreux autres avantages. + +Dans cette partie du cours, vous apprendrez à utiliser un canal pour gérer plusieurs entrées provenant de diverses sources différentes. +Vous apprendrez également à utiliser des **opérateurs** pour transformer le contenu des canaux selon les besoins. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez terminé la Partie 1 du cours [Hello Nextflow](./index.md), mais si vous êtes à l'aise avec les bases couvertes dans cette section, vous pouvez commencer ici sans rien faire de spécial. + +--- + +## 0. Échauffement : Exécuter `hello-channels.nf` + +Nous allons utiliser le script de flux de travail `hello-channels.nf` comme point de départ. +Il est équivalent au script produit en suivant la Partie 1 de ce cours de formation, sauf que nous avons changé la destination de sortie : + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'apporter des modifications : + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Comme précédemment, vous trouverez le fichier de sortie nommé `output.txt` dans le répertoire `results/hello_channels` (comme spécifié dans le bloc `output` du script de flux de travail, montré ci-dessus). + +??? abstract "Contenu du répertoire" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenu du fichier" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Si cela a fonctionné pour vous, vous êtes prêt à apprendre les canaux. + +--- + +## 1. Fournir des entrées variables via un canal explicitement + +Nous allons créer un **canal** pour passer l'entrée variable au processus `sayHello()` au lieu de compter sur la gestion implicite, qui a certaines limitations. + +### 1.1. Créer un canal d'entrée + +Il existe une variété de **fabriques de canaux** que nous pouvons utiliser pour configurer un canal. +Pour garder les choses simples pour l'instant, nous allons utiliser la fabrique de canaux la plus basique, appelée `channel.of`, qui créera un canal contenant une seule valeur. +Fonctionnellement, ce sera similaire à la configuration que nous avions avant, mais au lieu de laisser Nextflow créer un canal implicitement, nous le faisons explicitement maintenant. + +Voici la ligne de code que nous allons utiliser : + +```console title="Syntaxe" +greeting_ch = channel.of('Hello Channels!') +``` + +Cela crée un canal appelé `greeting_ch` en utilisant la fabrique de canaux `channel.of()`, qui configure un simple canal de file d'attente, et charge la chaîne `'Hello Channels!'` à utiliser comme valeur de salutation. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Note" + + Nous revenons temporairement aux chaînes codées en dur au lieu d'utiliser un paramètre CLI pour des raisons de lisibilité. Nous reviendrons à l'utilisation des paramètres CLI une fois que nous aurons couvert ce qui se passe au niveau du canal. + +Dans le bloc workflow, ajoutez le code de la fabrique de canaux : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels!') + // émettre une salutation + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // émettre une salutation + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Ce n'est pas encore fonctionnel puisque nous n'avons pas encore changé l'entrée vers l'appel du processus. + +### 1.2. Ajouter le canal comme entrée à l'appel du processus + +Maintenant nous devons effectivement brancher notre canal nouvellement créé dans l'appel du processus `sayHello()`, remplaçant le paramètre CLI que nous fournissions directement avant. + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels!') + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels!') + // émettre une salutation + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Cela indique à Nextflow d'exécuter le processus `sayHello` sur le contenu du canal `greeting_ch`. + +Maintenant notre flux de travail est correctement fonctionnel ; c'est l'équivalent explicite d'écrire `sayHello('Hello Channels!')`. + +### 1.3. Exécuter le flux de travail + +Exécutons-le ! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Si vous avez fait les deux modifications correctement, vous devriez obtenir une exécution réussie. +Vous pouvez vérifier le répertoire des résultats pour vous assurer que le résultat est toujours le même qu'avant. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Nous avons donc augmenté la flexibilité de notre flux de travail tout en obtenant le même résultat final. +Cela peut sembler que nous écrivons plus de code sans bénéfice tangible, mais la valeur deviendra claire dès que nous commencerons à gérer plus d'entrées. + +En avant-première, regardons une chose de plus avant de passer à la suite : un petit avantage pratique de l'utilisation d'un canal explicite pour gérer l'entrée de données. + +### 1.4. Utiliser `view()` pour inspecter le contenu du canal + +Les canaux Nextflow sont construits d'une manière qui nous permet d'opérer sur leur contenu en utilisant des opérateurs, que nous couvrirons en détail plus tard dans ce chapitre. + +Pour l'instant, nous allons juste vous montrer comment utiliser un opérateur super simple appelé [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) pour inspecter le contenu d'un canal. +Vous pouvez considérer `view()` comme un outil de débogage, comme une instruction `print()` en Python, ou son équivalent dans d'autres langages. + +Ajoutez cette petite ligne au bloc workflow : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels!') + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels!') + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +La quantité exacte d'espaces n'a pas d'importance tant que c'est un multiple de 4 ; nous visons juste à aligner le début de l'instruction `.view()` avec la partie `.of()` de la construction du canal. + +Maintenant exécutez à nouveau le flux de travail : + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Comme vous pouvez le voir, cela affiche le contenu du canal dans la console. +Ici, nous n'avons qu'un élément, mais quand nous commencerons à charger plusieurs valeurs dans le canal dans la section suivante, vous verrez que cela est configuré pour afficher un élément par ligne. + +### À retenir + +Vous savez comment utiliser une fabrique de canaux de base pour fournir une entrée à un processus. + +### Et ensuite ? + +Apprendre à utiliser les canaux pour faire itérer le flux de travail sur plusieurs valeurs d'entrée. + +--- + +## 2. Modifier le flux de travail pour s'exécuter sur plusieurs valeurs d'entrée + +Les flux de travail s'exécutent généralement sur des lots d'entrées destinés à être traités en masse, nous voulons donc améliorer le flux de travail pour accepter plusieurs valeurs d'entrée. + +### 2.1. Charger plusieurs salutations dans le canal d'entrée + +De façon pratique, la fabrique de canaux `channel.of()` que nous utilisons est tout à fait capable d'accepter plus d'une valeur, donc nous n'avons pas besoin de la modifier du tout. +Nous pouvons simplement charger plusieurs valeurs dans le canal. + +Mettons `'Hello'`, `'Bonjour'` et `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Dans le diagramme, le canal est représenté en vert, et l'ordre des éléments est représenté comme des billes dans un tuyau : le premier chargé est à droite, puis le deuxième au milieu, puis le troisième est à gauche._ + +#### 2.1.1. Ajouter plus de salutations + +Avant le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // créer un canal pour les entrées + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // créer un canal pour les entrées + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +La documentation nous dit que cela devrait fonctionner. Cela peut-il vraiment être aussi simple ? + +#### 2.1.2. Exécuter la commande et regarder la sortie du log + +Essayons. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Cela semble avoir bien fonctionné. +Le moniteur d'exécution montre que `3 of 3` appels ont été effectués pour le processus `sayHello`, et nous voyons les trois salutations énumérées par l'instruction `view()`, une par ligne comme promis. + +Cependant, il n'y a toujours qu'une seule sortie dans le répertoire des résultats : + +??? abstract "Contenu du répertoire" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenu du fichier" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Vous devriez voir l'une des trois salutations dedans, mais celle que vous avez obtenue pourrait être différente de ce qui est montré ici. +Pouvez-vous deviner pourquoi ? + +En regardant le moniteur d'exécution, il nous a donné seulement un chemin de sous-répertoire (`f4/c9962c`). +Jetons un coup d'œil dedans. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenu du fichier" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +Ce n'est même pas la même salutation que nous avons obtenue dans le répertoire des résultats ! Que se passe-t-il ? + +À ce stade, nous devons vous dire que par défaut, le système de journalisation ANSI écrit les logs de plusieurs appels au même processus sur la même ligne. +Donc le statut des trois appels au processus sayHello() atterrissent au même endroit. + +Heureusement, nous pouvons désactiver ce comportement pour voir la liste complète des appels de processus. + +#### 2.1.3. Exécuter à nouveau la commande avec l'option `-ansi-log false` + +Pour développer la journalisation afin d'afficher une ligne par appel de processus, ajoutez `-ansi-log false` à la commande. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Cette fois nous voyons les trois exécutions de processus et leurs sous-répertoires de travail associés listés dans la sortie. + +C'est beaucoup mieux, au moins pour un flux de travail simple. +Pour un flux de travail complexe, ou un grand nombre d'entrées, avoir la liste complète affichée dans le terminal deviendrait un peu accablant. +C'est pourquoi `-ansi-log false` n'est pas le comportement par défaut. + +!!! tip "Astuce" + + La façon dont le statut est rapporté est un peu différente entre les deux modes de journalisation. + Dans le mode condensé, Nextflow rapporte si les appels se sont terminés avec succès ou non. + Dans ce mode étendu, il rapporte seulement qu'ils ont été soumis. + +De toute façon, maintenant que nous avons les sous-répertoires de chaque appel de processus, nous pouvons chercher leurs logs et sorties. + +??? abstract "Contenu du répertoire" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenu des fichiers" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Cela montre que les trois processus se sont exécutés avec succès (youpi). + +Cela dit, nous avons toujours le problème qu'il n'y a qu'un seul fichier de sortie dans le répertoire des résultats. + +Vous vous souvenez peut-être que nous avions codé en dur le nom du fichier de sortie pour le processus `sayHello`, donc les trois appels ont produit un fichier appelé `output.txt`. + +Tant que les fichiers de sortie restent dans les sous-répertoires de travail, isolés des autres processus, c'est correct. +Mais quand ils sont publiés dans le même répertoire de résultats, celui qui a été copié là en premier est écrasé par le suivant, et ainsi de suite. + +### 2.2. S'assurer que les noms de fichiers de sortie seront uniques + +Nous pouvons continuer à publier toutes les sorties dans le même répertoire de résultats, mais nous devons nous assurer qu'elles auront des noms uniques. +Spécifiquement, nous devons modifier le premier processus pour générer un nom de fichier dynamiquement afin que les noms de fichiers finaux soient uniques. + +Alors comment rendre les noms de fichiers uniques ? +Une façon courante de le faire est d'utiliser une pièce unique de métadonnées des entrées (reçues du canal d'entrée) comme partie du nom du fichier de sortie. +Ici, pour plus de commodité, nous utiliserons simplement la salutation elle-même puisque c'est juste une courte chaîne, et la préfixerons au nom de fichier de sortie de base. + +#### 2.2.1. Construire un nom de fichier de sortie dynamique + +Dans le bloc process, faites les modifications de code suivantes : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Assurez-vous de remplacer `output.txt` à la fois dans la définition de sortie et dans le bloc de commande `script:`. + +!!! tip "Astuce" + + Dans la définition de sortie, vous DEVEZ utiliser des guillemets doubles autour de l'expression du nom de fichier de sortie (PAS des guillemets simples), sinon cela échouera. + +Cela devrait produire un nom de fichier de sortie unique chaque fois que le processus est appelé, afin qu'il puisse être distingué des sorties d'autres appels au même processus dans le répertoire de sortie. + +#### 2.2.2. Exécuter le flux de travail + +Exécutons-le. Notez que nous revenons à l'exécution avec les paramètres de log ANSI par défaut. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +En revenant à la vue résumée, la sortie est à nouveau résumée sur une ligne. +Jetez un œil au répertoire `results` pour voir si toutes les salutations de sortie y sont. + +??? abstract "Contenu du répertoire" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Oui ! Et chacune a le contenu attendu. + +??? abstract "Contenu des fichiers" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Succès ! Maintenant nous pouvons ajouter autant de salutations que nous voulons sans nous soucier de l'écrasement des fichiers de sortie. + +!!! tip "Astuce" + + En pratique, nommer les fichiers en fonction des données d'entrée elles-mêmes est presque toujours peu pratique. + La meilleure façon de générer des noms de fichiers dynamiques est de passer des métadonnées à un processus avec les fichiers d'entrée. + Les métadonnées sont généralement fournies via une « feuille d'échantillons » ou équivalents. + Vous apprendrez comment faire cela plus tard dans votre formation Nextflow (voir la [quête annexe sur les métadonnées](../side_quests/metadata.md)). + +### À retenir + +Vous savez comment alimenter plusieurs éléments d'entrée à travers un canal. + +### Et ensuite ? + +Apprendre à utiliser un opérateur pour transformer le contenu d'un canal. + +--- + +## 3. Fournir plusieurs entrées via un tableau + +Nous venons de vous montrer comment gérer plusieurs éléments d'entrée qui étaient codés en dur directement dans la fabrique de canaux. +Et si nous voulions fournir ces entrées multiples d'une manière différente ? + +Par exemple, imaginez que nous configurions une variable d'entrée contenant un tableau d'éléments comme ceci : + +`greetings_array = ['Hello','Bonjour','Holà']` + +Pouvons-nous charger cela dans notre canal de sortie et nous attendre à ce que ça fonctionne ? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Découvrons-le. + +### 3.1. Fournir un tableau de valeurs comme entrée au canal + +Le bon sens suggère que nous devrions pouvoir simplement passer un tableau de valeurs au lieu d'une seule valeur. +Essayons ; nous devrons configurer la variable d'entrée et la charger dans la fabrique de canaux. + +#### 3.1.1. Configurer la variable d'entrée + +Prenons la variable `greetings_array` que nous venons d'imaginer et rendons-la réelle en l'ajoutant au bloc workflow : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // créer un canal pour les entrées + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Ce n'est pas encore fonctionnel, nous avons juste ajouté une déclaration pour le tableau. + +#### 3.1.2. Définir le tableau de salutations comme entrée de la fabrique de canaux + +Maintenant nous allons remplacer les valeurs `'Hello','Bonjour','Holà'` actuellement codées en dur dans la fabrique de canaux par le `greetings_array` que nous venons de créer. + +Dans le bloc workflow, faites la modification suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Cela devrait être fonctionnel maintenant. + +#### 3.1.3. Exécuter le flux de travail + +Essayons de l'exécuter : + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Sortie de la commande" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +Oh non ! Il y a une erreur ! + +Regardez la sortie de `view()` et les messages d'erreur. + +On dirait que Nextflow a essayé d'exécuter un seul appel de processus, en utilisant `[Hello, Bonjour, Holà]` comme valeur de chaîne, au lieu d'utiliser les trois chaînes dans le tableau comme valeurs séparées. + +Donc c'est l'« emballage » qui cause le problème. +Comment faire pour que Nextflow déballe le tableau et charge les chaînes individuelles dans le canal ? + +### 3.2. Utiliser un opérateur pour transformer le contenu du canal + +C'est là que les **[opérateurs](https://www.nextflow.io/docs/latest/reference/operator.html)** entrent en jeu. +Vous avez déjà utilisé l'opérateur `.view()`, qui regarde juste ce qu'il y a à l'intérieur. +Maintenant nous allons regarder les opérateurs qui nous permettent d'agir sur le contenu d'un canal. + +Si vous parcourez la [liste des opérateurs](https://www.nextflow.io/docs/latest/reference/operator.html) dans la documentation Nextflow, vous trouverez [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), qui fait exactement ce dont nous avons besoin : déballer le contenu d'un tableau et les émettre comme éléments individuels. + +#### 3.2.1. Ajouter l'opérateur `flatten()` + +Pour appliquer l'opérateur `flatten()` à notre canal d'entrée, nous l'ajoutons à la déclaration de la fabrique de canaux. + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Ici nous avons ajouté l'opérateur sur la ligne suivante pour la lisibilité, mais vous pouvez ajouter des opérateurs sur la même ligne que la fabrique de canaux si vous préférez, comme ceci : +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Affiner les instructions `view()` + +Nous pourrions exécuter cela tout de suite pour tester si ça fonctionne, mais pendant qu'on y est, nous allons affiner la façon dont nous inspectons le contenu du canal. + +Nous voulons pouvoir contraster ce à quoi ressemble le contenu avant et après l'application de l'opérateur `flatten()`, donc nous allons en ajouter un second, ET nous allons ajouter un peu de code pour les étiqueter plus clairement dans la sortie. + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Vous voyez que nous avons ajouté une deuxième instruction `.view`, et pour chacune d'elles, nous avons remplacé les parenthèses vides (`()`) par des accolades contenant du code, tel que `{ greeting -> "Before flatten: $greeting" }`. + +Ce sont des _closures_. Le code qu'elles contiennent sera exécuté pour chaque élément dans le canal. +Nous définissons une variable temporaire pour la valeur interne, ici appelée `greeting` (mais ce pourrait être n'importe quel nom arbitraire), qui n'est utilisée que dans la portée de cette closure. + +Dans cet exemple, `$greeting` représente chaque élément individuel chargé dans le canal. +Cela donnera une sortie console bien étiquetée. + +!!! info "Information" + + Dans certains pipelines, vous pourriez voir une variable spéciale appelée `$it` utilisée à l'intérieur des closures d'opérateurs. + C'est une variable _implicite_ qui permet un accès raccourci à la variable interne, + sans avoir besoin de la définir avec un `->`. + + Nous préférons être explicites pour aider à la clarté du code, ainsi la syntaxe `$it` est découragée et sera progressivement supprimée du langage Nextflow. + +#### 3.2.3. Exécuter le flux de travail + +Finalement, vous pouvez essayer d'exécuter à nouveau le flux de travail ! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Cette fois ça fonctionne ET nous donne l'aperçu supplémentaire de ce à quoi ressemble le contenu du canal avant et après l'exécution de l'opérateur `flatten()`. + +- Vous voyez que nous obtenons une seule instruction `Before flatten:` parce qu'à ce moment le canal contient un élément, le tableau original. + Ensuite nous obtenons trois instructions `After flatten:` séparées, une pour chaque salutation, qui sont maintenant des éléments individuels dans le canal. + +De manière importante, cela signifie que chaque élément peut maintenant être traité séparément par le flux de travail. + +!!! tip "Astuce" + + Il est techniquement possible d'obtenir les mêmes résultats en utilisant une fabrique de canaux différente, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), qui inclut une étape de mapping implicite dans son fonctionnement. + Ici nous avons choisi de ne pas l'utiliser afin de démontrer l'utilisation d'un opérateur sur un cas d'utilisation simple. + +### À retenir + +Vous savez comment utiliser un opérateur comme `flatten()` pour transformer le contenu d'un canal, et comment utiliser l'opérateur `view()` pour inspecter le contenu du canal avant et après l'application d'un opérateur. + +### Et ensuite ? + +Apprendre à faire prendre au flux de travail un fichier comme source de valeurs d'entrée. + +--- + +## 4. Lire les valeurs d'entrée depuis un fichier CSV + +De façon réaliste, nous allons rarement, voire jamais, commencer à partir d'un tableau de valeurs. +Le plus probable est que nous aurons un ou plusieurs fichiers contenant les données qui doivent être traitées, dans un format structuré quelconque. + +Nous avons préparé un fichier CSV appelé `greetings.csv` qui contient plusieurs salutations d'entrée, imitant le type de données tabulaires que vous pourriez vouloir traiter dans une analyse de données réelle, stocké sous `data/`. +(Les nombres ne sont pas significatifs, ils sont juste là à des fins d'illustration.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Notre prochaine tâche est d'adapter notre flux de travail pour lire les valeurs de ce fichier. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Voyons comment nous pouvons faire cela. + +### 4.1. Modifier le script pour attendre un fichier CSV comme source de salutations + +Pour commencer, nous allons devoir faire deux changements clés au script : + +- Changer le paramètre d'entrée pour pointer vers le fichier CSV +- Changer la fabrique de canaux pour une conçue pour gérer un fichier + +#### 4.1.1. Changer le paramètre d'entrée pour pointer vers le fichier CSV + +Vous vous souvenez du paramètre `params.input` que nous avons configuré dans la Partie 1 ? +Nous allons le mettre à jour pour pointer vers le fichier CSV contenant nos salutations. + +Faites la modification suivante à la déclaration du paramètre : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Paramètres du pipeline + */ + input: String = 'Holà mundo!' + ``` + +Cela suppose que le fichier est co-localisé avec le code du flux de travail. +Vous apprendrez comment gérer d'autres emplacements de données plus tard dans votre parcours Nextflow. + +#### 4.1.2. Passer à une fabrique de canaux conçue pour gérer un fichier + +Puisque nous voulons maintenant utiliser un fichier au lieu de simples chaînes comme entrée, nous ne pouvons pas utiliser la fabrique de canaux `channel.of()` d'avant. +Nous devons passer à l'utilisation d'une nouvelle fabrique de canaux, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), qui a une fonctionnalité intégrée pour gérer les chemins de fichiers. + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // déclarer un tableau de salutations d'entrée + greetings_array = ['Hello','Bonjour','Holà'] + // créer un canal pour les entrées + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Vous remarquerez que nous avons rechangé l'entrée du canal en `param.input`, et supprimé la déclaration `greetings_array` puisque nous n'en aurons plus besoin. +Nous avons également commenté le `flatten()` et la deuxième instruction `view()`. + +#### 4.1.3. Exécuter le flux de travail + +Essayons d'exécuter le flux de travail avec la nouvelle fabrique de canaux et le fichier d'entrée. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Sortie de la commande" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Oh non, ça ne fonctionne pas. Regardez le début de la sortie console et le message d'erreur. +La partie `Command executed:` est particulièrement utile ici. + +Cela peut sembler un peu familier. +On dirait que Nextflow a essayé d'exécuter un seul appel de processus en utilisant le chemin du fichier lui-même comme valeur de chaîne. +Donc il a résolu le chemin du fichier correctement, mais il n'a pas réellement analysé son contenu, ce qui est ce que nous voulions. + +Comment faire pour que Nextflow ouvre le fichier et charge son contenu dans le canal ? + +On dirait qu'on a besoin d'un autre [opérateur](https://www.nextflow.io/docs/latest/reference/operator.html) ! + +### 4.2. Utiliser l'opérateur `splitCsv()` pour analyser le fichier + +En parcourant à nouveau la liste des opérateurs, nous trouvons [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), qui est conçu pour analyser et diviser le texte au format CSV. + +#### 4.2.1. Appliquer `splitCsv()` au canal + +Pour appliquer l'opérateur, nous l'ajoutons à la ligne de la fabrique de canaux comme précédemment. + +Dans le bloc workflow, faites la modification de code suivante pour remplacer `flatten()` par `splitcsv()` (décommenté) : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Comme vous pouvez le voir, nous avons également mis à jour les instructions `view()` avant/après. +Techniquement nous aurions pu utiliser le même nom de variable (`greeting`) mais nous l'avons mis à jour en quelque chose de plus approprié (`csv`) pour rendre le code plus lisible par les autres. + +#### 4.2.2. Exécuter à nouveau le flux de travail + +Essayons d'exécuter le flux de travail avec la logique d'analyse CSV ajoutée. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Sortie de la commande" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Intéressant, cela échoue aussi, mais avec une erreur différente. +Cette fois Nextflow a analysé le contenu du fichier (youpi !) mais il a chargé chaque ligne comme un tableau, et chaque tableau est un élément dans le canal. + +Nous devons lui dire de ne prendre que la première colonne de chaque ligne. +Alors comment déballer cela ? + +Nous avons précédemment utilisé `flatten()` pour déballer le contenu d'un canal, mais cela ne fonctionnerait pas ici parce que flatten déballe _tout_ (n'hésitez pas à l'essayer si vous voulez voir par vous-même). + +À la place, nous utiliserons un autre opérateur appelé `map()` qui est vraiment utile et apparaît beaucoup dans les pipelines Nextflow. + +### 4.3. Utiliser l'opérateur `map()` pour extraire les salutations + +L'opérateur [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) est un petit outil très pratique qui nous permet de faire toutes sortes de mappings sur le contenu d'un canal. + +Dans ce cas, nous allons l'utiliser pour extraire cet unique élément que nous voulons de chaque ligne dans notre fichier de données. +Voici à quoi ressemble la syntaxe : + +```groovy title="Syntaxe" +.map { row -> row[0] } +``` + +Cela signifie « pour chaque ligne dans le canal, prendre le 0ème (premier) élément qu'elle contient ». + +Appliquons donc cela à notre analyse CSV. + +#### 4.3.1. Appliquer `map()` au canal + +Dans le bloc workflow, faites la modification de code suivante : + +=== "Après" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Vous voyez que nous avons ajouté un autre appel `view()` pour confirmer que l'opérateur fait ce que nous attendons. + +#### 4.3.2. Exécuter le flux de travail + +Exécutons cela une fois de plus : + +```bash +nextflow run hello-channels.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Cette fois cela devrait s'exécuter sans erreur. + +En regardant la sortie des instructions `view()`, vous voyez ce qui suit : + +- Une seule instruction `Before splitCsv:` : à ce moment le canal contient un élément, le chemin du fichier original. +- Trois instructions `After splitCsv:` séparées : une pour chaque salutation, mais chacune est contenue dans un tableau qui correspond à cette ligne dans le fichier. +- Trois instructions `After map:` séparées : une pour chaque salutation, qui sont maintenant des éléments individuels dans le canal. + +Notez que les lignes peuvent apparaître dans un ordre différent dans votre sortie. + +Vous pouvez également regarder les fichiers de sortie pour vérifier que chaque salutation a été correctement extraite et traitée à travers le flux de travail. + +Nous avons obtenu le même résultat qu'avant, mais maintenant nous avons beaucoup plus de flexibilité pour ajouter plus d'éléments au canal de salutations que nous voulons traiter en modifiant un fichier d'entrée, sans modifier aucun code. +Vous apprendrez des approches plus sophistiquées pour gérer des entrées complexes dans une formation ultérieure. + +### À retenir + +Vous savez comment utiliser le constructeur de canal `.fromPath()` et les opérateurs `splitCsv()` et `map()` pour lire un fichier de valeurs d'entrée et les gérer de manière appropriée. + +Plus généralement, vous avez une compréhension de base de la façon dont Nextflow utilise les **canaux** pour gérer les entrées vers les processus et les **opérateurs** pour transformer leur contenu. + +### Et ensuite ? + +Prenez une grande pause, vous avez travaillé dur sur celui-ci ! + +Quand vous êtes prêt, passez à la [**Partie 3 : Hello Workflow**](./03_hello_workflow.md) pour apprendre comment ajouter plus d'étapes et les connecter ensemble dans un vrai flux de travail. + +--- + +## Quiz + +<quiz> +Qu'est-ce qu'un canal dans Nextflow ? +- [ ] Une spécification de chemin de fichier +- [ ] Une définition de processus +- [x] Une structure de type file d'attente pour passer des données entre processus +- [ ] Un paramètre de configuration + +En savoir plus : [1.1. Créer un canal d'entrée](#11-creer-un-canal-dentree) +</quiz> + +<quiz> +Que va produire ce code ? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (une seule liste) +- [x] Chaque élément sur une ligne séparée : `Hello`, `Bonjour`, `Hola` +- [ ] Rien (les canaux n'affichent pas par défaut) +- [ ] Une erreur (syntaxe invalide) + +En savoir plus : [1.1. Créer un canal d'entrée](#11-creer-un-canal-dentree) +</quiz> + +<quiz> +Quand un canal contient plusieurs valeurs, comment Nextflow gère-t-il l'exécution du processus ? +- [ ] Le processus s'exécute une fois avec toutes les valeurs +- [x] Le processus s'exécute une fois pour chaque valeur dans le canal +- [ ] Le processus s'exécute seulement avec la première valeur +- [ ] Le processus s'exécute seulement avec la dernière valeur + +En savoir plus : [2. Modifier le flux de travail pour s'exécuter sur plusieurs valeurs d'entrée](#2-modifier-le-flux-de-travail-pour-sexecuter-sur-plusieurs-valeurs-dentree) +</quiz> + +<quiz> +Que fait l'opérateur `flatten()` ? +- [ ] Combine plusieurs canaux en un seul +- [ ] Trie les éléments du canal +- [x] Déballe les tableaux en éléments individuels +- [ ] Supprime les éléments dupliqués + +En savoir plus : [3.2.1. Ajouter l'opérateur `flatten()`](#321-ajouter-loperateur-flatten) +</quiz> + +<quiz> +Quel est le but de l'opérateur `view()` ? +- [ ] Filtrer le contenu du canal +- [ ] Transformer les éléments du canal +- [x] Inspecter et déboguer le contenu du canal +- [ ] Sauvegarder le contenu du canal dans un fichier + +En savoir plus : [1.4. Utiliser `view()` pour inspecter le contenu du canal](#14-utiliser-view-pour-inspecter-le-contenu-du-canal) +</quiz> + +<quiz> +Que fait `splitCsv()` ? +- [ ] Crée un fichier CSV à partir du contenu du canal +- [ ] Divise une chaîne par des virgules +- [x] Analyse un fichier CSV en tableaux représentant chaque ligne +- [ ] Fusionne plusieurs fichiers CSV + +En savoir plus : [4.2. Utiliser l'opérateur `splitCsv()` pour analyser le fichier](#42-utiliser-loperateur-splitcsv-pour-analyser-le-fichier) +</quiz> + +<quiz> +Quel est le but de l'opérateur `map()` ? +- [ ] Filtrer les éléments d'un canal +- [ ] Combiner plusieurs canaux +- [x] Transformer chaque élément dans un canal +- [ ] Compter les éléments dans un canal + +En savoir plus : [4.3. Utiliser l'opérateur `map()` pour extraire les salutations](#43-utiliser-loperateur-map-pour-extraire-les-salutations) +</quiz> + +<quiz> +Pourquoi est-il important d'utiliser des noms de fichiers de sortie dynamiques lors du traitement de plusieurs entrées ? +- [ ] Pour améliorer les performances +- [ ] Pour réduire l'espace disque +- [x] Pour empêcher les fichiers de sortie de s'écraser mutuellement +- [ ] Pour activer la fonctionnalité de reprise + +En savoir plus : [2.2. S'assurer que les noms de fichiers de sortie seront uniques](#22-sassurer-que-les-noms-de-fichiers-de-sortie-seront-uniques) +</quiz> diff --git a/docs/fr/docs/hello_nextflow/03_hello_workflow.md b/docs/fr/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..5ee958e8f2 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Partie 3 : Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube de Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/03_hello_workflow.md). +/// + +La plupart des workflows réels impliquent plus d'une étape. +Dans ce module de formation, vous apprendrez à connecter des processus ensemble dans un workflow multi-étapes. + +Cela vous enseignera la méthode Nextflow pour accomplir les tâches suivantes : + +1. Faire circuler les données d'un processus à l'autre +2. Collecter les sorties de plusieurs appels de processus dans un seul appel de processus +3. Passer plus d'une entrée à un processus +4. Gérer plusieurs sorties provenant d'un processus + +Pour illustrer, nous continuerons à construire sur l'exemple Hello World indépendant du domaine des Parties 1 et 2. +Cette fois, nous allons apporter les modifications suivantes à notre workflow pour mieux refléter la façon dont les gens construisent de véritables workflows : + +1. Ajouter une deuxième étape qui convertit le message de bienvenue en majuscules. +2. Ajouter une troisième étape qui collecte tous les messages transformés et les écrit dans un seul fichier. +3. Ajouter un paramètre pour nommer le fichier de sortie final et le passer comme entrée secondaire à l'étape de collecte. +4. Faire en sorte que l'étape de collecte rapporte également une statistique simple sur ce qui a été traité. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez complété les Parties 1-2 du cours [Hello Nextflow](./index.md), mais si vous êtes à l'aise avec les bases couvertes dans ces sections, vous pouvez commencer ici sans rien faire de spécial. + +--- + +## 0. Échauffement : Exécuter `hello-workflow.nf` + +Nous allons utiliser le script de workflow `hello-workflow.nf` comme point de départ. +Il est équivalent au script produit en travaillant à travers la Partie 2 de ce cours de formation, sauf que nous avons supprimé les instructions `view()` et changé la destination de sortie : + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'effectuer des modifications : + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Comme précédemment, vous trouverez les fichiers de sortie à l'emplacement spécifié dans le bloc `output`. +Pour ce chapitre, c'est sous `results/hello_workflow/`. + +??? abstract "Contenu du répertoire" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Si cela a fonctionné pour vous, vous êtes prêt à apprendre comment assembler un workflow multi-étapes. + +--- + +## 1. Ajouter une deuxième étape au workflow + +Nous allons ajouter une étape pour convertir chaque message de bienvenue en majuscules. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +Pour ce faire, nous devons accomplir trois choses : + +- Définir la commande que nous allons utiliser pour effectuer la conversion en majuscules. +- Écrire un nouveau processus qui encapsule la commande de mise en majuscules. +- Appeler le nouveau processus dans le bloc workflow et le configurer pour prendre la sortie du processus `sayHello()` comme entrée. + +### 1.1. Définir la commande de mise en majuscules et la tester dans le terminal + +Pour effectuer la conversion des messages de bienvenue en majuscules, nous allons utiliser un outil UNIX classique appelé `tr` pour « remplacement de texte », avec la syntaxe suivante : + +```bash title="Syntaxe" +tr '[a-z]' '[A-Z]' +``` + +C'est un one-liner de remplacement de texte très naïf qui ne tient pas compte des lettres accentuées, donc par exemple « Holà » deviendra « HOLà », mais il fera un travail suffisant pour démontrer les concepts Nextflow et c'est ce qui compte. + +Pour le tester, nous pouvons exécuter la commande `echo 'Hello World'` et rediriger sa sortie vers la commande `tr` : + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +La sortie est un fichier texte appelé `UPPER-output.txt` qui contient la version en majuscules de la chaîne `Hello World`. + +??? abstract "Contenu du fichier" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +C'est essentiellement ce que nous allons essayer de faire avec notre workflow. + +### 1.2. Écrire l'étape de mise en majuscules comme un processus Nextflow + +Nous pouvons modeler notre nouveau processus sur le premier, puisque nous voulons utiliser tous les mêmes composants. + +Ajoutez la définition de processus suivante au script de workflow, juste en dessous de la première : + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Utilise un outil de remplacement de texte pour convertir la salutation en majuscules + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Dans celui-ci, nous composons le deuxième nom de fichier de sortie basé sur le nom du fichier d'entrée, de manière similaire à ce que nous avions fait initialement pour la sortie du premier processus. + +### 1.3. Ajouter un appel au nouveau processus dans le bloc workflow + +Maintenant, nous devons dire à Nextflow d'appeler effectivement le processus que nous venons de définir. + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Ceci n'est pas encore fonctionnel car nous n'avons pas spécifié ce qui doit être passé en entrée au processus `convertToUpper()`. + +### 1.4. Passer la sortie du premier processus au deuxième processus + +Maintenant, nous devons faire en sorte que la sortie du processus `sayHello()` circule vers le processus `convertToUpper()`. + +De manière pratique, Nextflow empaquette automatiquement la sortie d'un processus dans un canal appelé `<process>.out`. +Ainsi, la sortie du processus `sayHello` est un canal appelé `sayHello.out`, que nous pouvons brancher directement dans l'appel à `convertToUpper()`. + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // convertir la salutation en majuscules + convertToUpper() + ``` + +Pour un cas simple comme celui-ci (une sortie vers une entrée), c'est tout ce que nous devons faire pour connecter deux processus ! + +### 1.5. Configurer la publication des sorties du workflow + +Enfin, mettons à jour les sorties du workflow pour publier également les résultats du deuxième processus. + +#### 1.5.1. Mettre à jour la section `publish:` du bloc `workflow` + +Dans le bloc `workflow`, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +La logique est la même que précédemment. + +#### 1.5.2. Mettre à jour le bloc `output` + +Dans le bloc `output`, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Encore une fois, la logique est la même qu'avant. + +Cela vous montre que vous pouvez contrôler les paramètres de sortie à un niveau très granulaire, pour chaque sortie individuelle. +N'hésitez pas à essayer de changer les chemins ou le mode de publication pour l'un des processus pour voir ce qui se passe. + +Bien sûr, cela signifie que nous répétons certaines informations ici, ce qui pourrait devenir gênant si nous voulions mettre à jour l'emplacement pour toutes les sorties de la même manière. +Plus tard dans le cours, vous apprendrez comment configurer ces paramètres pour plusieurs sorties de manière structurée. + +### 1.6. Exécuter le workflow avec `-resume` + +Testons ceci en utilisant le flag `-resume`, puisque nous avons déjà exécuté la première étape du workflow avec succès. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Il y a maintenant une ligne supplémentaire dans la sortie de la console qui correspond au nouveau processus que nous venons d'ajouter. + +Vous trouverez les sorties dans le répertoire `results/hello_workflow` comme défini dans le bloc `output`. + +??? abstract "Contenu du répertoire" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +C'est pratique ! Mais cela vaut quand même la peine de jeter un œil à l'intérieur du répertoire de travail d'un des appels au deuxième processus. + +??? abstract "Contenu du répertoire" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Remarquez qu'il y a deux fichiers `*-output` : la sortie du premier processus ainsi que la sortie du deuxième. + +La sortie du premier processus est là parce que Nextflow l'a **stagée** là afin d'avoir tout ce qui est nécessaire pour l'exécution dans le même sous-répertoire. + +Cependant, c'est en fait un lien symbolique pointant vers le fichier original dans le sous-répertoire de l'appel du premier processus. +Par défaut, lors de l'exécution sur une seule machine comme nous le faisons ici, Nextflow utilise des liens symboliques plutôt que des copies pour stager les fichiers d'entrée et intermédiaires. + +Maintenant, avant de continuer, réfléchissez à comment tout ce que nous avons fait est de connecter la sortie de `sayHello` à l'entrée de `convertToUpper` et les deux processus ont pu être exécutés en série. +Nextflow a fait le travail difficile de gérer les fichiers d'entrée et de sortie individuels et de les passer entre les deux commandes pour nous. + +C'est l'une des raisons pour lesquelles les canaux Nextflow sont si puissants : ils s'occupent du travail fastidieux impliqué dans la connexion des étapes du workflow ensemble. + +### À retenir + +Vous savez comment enchaîner des processus ensemble en fournissant la sortie d'une étape comme entrée à l'étape suivante. + +### Et ensuite ? + +Apprenez à collecter les sorties des appels de processus par lots et à les alimenter dans un seul processus. + +--- + +## 2. Ajouter une troisième étape pour collecter tous les messages de bienvenue + +Lorsque nous utilisons un processus pour appliquer une transformation à chacun des éléments d'un canal, comme nous le faisons ici avec les multiples messages de bienvenue, nous voulons parfois collecter les éléments du canal de sortie de ce processus et les alimenter dans un autre processus qui effectue une sorte d'analyse ou de sommation. + +Pour illustrer, nous allons ajouter une nouvelle étape à notre pipeline qui collecte tous les messages de bienvenue en majuscules produits par le processus `convertToUpper` et les écrit dans un seul fichier. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Sans vouloir gâcher la surprise, cela va impliquer un opérateur très utile. + +### 2.1. Définir la commande de collecte et la tester dans le terminal + +L'étape de collecte que nous voulons ajouter à notre workflow utilisera la commande `cat` pour concaténer plusieurs messages de bienvenue en majuscules dans un seul fichier. + +Exécutons la commande seule dans le terminal pour vérifier qu'elle fonctionne comme prévu, comme nous l'avons fait précédemment. + +Exécutez ce qui suit dans votre terminal : + +```bash +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 +``` + +La sortie est un fichier texte appelé `COLLECTED-output.txt` qui contient les versions en majuscules des messages de bienvenue originaux. + +??? abstract "Contenu du fichier" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +C'est le résultat que nous voulons obtenir avec notre workflow. + +### 2.2. Créer un nouveau processus pour effectuer l'étape de collecte + +Créons un nouveau processus et appelons-le `collectGreetings()`. +Nous pouvons commencer à l'écrire en nous basant sur ce que nous avons vu auparavant. + +#### 2.2.1. Écrire les parties « évidentes » du processus + +Ajoutez la définition de processus suivante au script de workflow : + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Collecter les salutations en majuscules dans un seul fichier de sortie + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +C'est ce que nous pouvons écrire avec confiance en nous basant sur ce que vous avez appris jusqu'à présent. +Mais ce n'est pas fonctionnel ! +Cela omet la définition des entrées et la première moitié de la commande de script parce que nous devons déterminer comment les écrire. + +#### 2.2.2. Définir les entrées de `collectGreetings()` + +Nous devons collecter les messages de bienvenue de tous les appels au processus `convertToUpper()`. +Que savons-nous pouvoir obtenir de l'étape précédente du workflow ? + +Le canal sorti par `convertToUpper()` contiendra les chemins vers les fichiers individuels contenant les messages de bienvenue en majuscules. +Cela correspond à un emplacement d'entrée ; appelons-le `input_files` pour simplifier. + +Dans le bloc du processus, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Notez que nous utilisons le préfixe `path` même si nous nous attendons à ce que cela contienne plusieurs fichiers. + +#### 2.2.3. Composer la commande de concaténation + +C'est là que les choses pourraient devenir un peu délicates, car nous devons être capables de gérer un nombre arbitraire de fichiers d'entrée. +Plus précisément, nous ne pouvons pas écrire la commande à l'avance, nous devons donc dire à Nextflow comment la composer à l'exécution en fonction des entrées qui circulent dans le processus. + +En d'autres termes, si nous avons un canal d'entrée contenant l'élément `[file1.txt, file2.txt, file3.txt]`, nous avons besoin que Nextflow transforme cela en `cat file1.txt file2.txt file3.txt`. + +Heureusement, Nextflow est tout à fait capable de faire cela pour nous si nous écrivons simplement `cat ${input_files}` dans la commande de script. + +Dans le bloc du processus, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +En théorie, cela devrait gérer n'importe quel nombre arbitraire de fichiers d'entrée. + +!!! tip "Astuce" + + Certains outils en ligne de commande nécessitent de fournir un argument (comme `-input`) pour chaque fichier d'entrée. + Dans ce cas, nous devrions faire un peu de travail supplémentaire pour composer la commande. + Vous pouvez voir un exemple de ceci dans le cours de formation [Nextflow for Genomics](../../nf4_science/genomics/). + +### 2.3. Ajouter l'étape de collecte au workflow + +Maintenant, nous devrions juste avoir besoin d'appeler le processus de collecte sur la sortie de l'étape de mise en majuscules. + +#### 2.3.1. Connecter les appels de processus + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out) + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="75" + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + } + ``` + +Cela connecte la sortie de `convertToUpper()` à l'entrée de `collectGreetings()`. + +#### 2.3.2. Exécuter le workflow avec `-resume` + +Essayons. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Sortie de la commande" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Il s'exécute avec succès, y compris la troisième étape. + +Cependant, regardez le nombre d'appels pour `collectGreetings()` sur la dernière ligne. +Nous n'en attendions qu'un, mais il y en a trois. + +Maintenant, regardez le contenu du fichier de sortie final. + +??? abstract "Contenu du fichier" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Oh non. L'étape de collecte a été exécutée individuellement sur chaque message de bienvenue, ce qui N'EST PAS ce que nous voulions. + +Nous devons faire quelque chose pour dire explicitement à Nextflow que nous voulons que cette troisième étape s'exécute sur tous les éléments du canal sorti par `convertToUpper()`. + +### 2.4. Utiliser un opérateur pour collecter les messages de bienvenue dans une seule entrée + +Oui, encore une fois la réponse à notre problème est un opérateur. + +Plus précisément, nous allons utiliser l'opérateur bien nommé [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect). + +#### 2.4.1. Ajouter l'opérateur `collect()` + +Cette fois, cela va sembler un peu différent parce que nous n'ajoutons pas l'opérateur dans le contexte d'une channel factory ; nous l'ajoutons à un canal de sortie. + +Nous prenons le `convertToUpper.out` et ajoutons l'opérateur `collect()`, ce qui nous donne `convertToUpper.out.collect()`. +Nous pouvons brancher cela directement dans l'appel du processus `collectGreetings()`. + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Ajouter quelques instructions `view()` + +Incluons également quelques instructions `view()` pour visualiser les états avant et après du contenu du canal. + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="73" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + } + ``` + +Les instructions `view()` peuvent aller où vous voulez ; nous les avons mises juste après l'appel pour la lisibilité. + +#### 2.4.3. Exécuter à nouveau le workflow avec `-resume` + +Essayons : + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + 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] + ``` + +Il s'exécute avec succès, bien que la sortie du journal puisse sembler un peu plus désordonnée que ceci (nous l'avons nettoyée pour la lisibilité). + +Cette fois, la troisième étape n'a été appelée qu'une seule fois ! + +En regardant la sortie des instructions `view()`, nous voyons ce qui suit : + +- Trois instructions `Before collect:`, une pour chaque message de bienvenue : à ce stade, les chemins de fichiers sont des éléments individuels dans le canal. +- Une seule instruction `After collect:` : les trois chemins de fichiers sont maintenant empaquetés dans un seul élément. + +Regardez le contenu du fichier de sortie final. + +??? abstract "Contenu du fichier" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Cette fois, nous avons les trois messages de bienvenue dans le fichier de sortie final. Succès ! + +!!! note "Note" + + Si vous exécutez ceci plusieurs fois sans `-resume`, vous verrez que l'ordre des messages de bienvenue change d'une exécution à l'autre. + Cela vous montre que l'ordre dans lequel les éléments circulent à travers les appels de processus n'est pas garanti d'être cohérent. + +#### 2.4.4. Supprimer les instructions `view()` pour la lisibilité + +Avant de passer à la section suivante, nous vous recommandons de supprimer les instructions `view()` pour éviter d'encombrer la sortie de la console. + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="73" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +C'est essentiellement l'opération inverse du point 2.4.2. + +### À retenir + +Vous savez comment collecter les sorties d'un lot d'appels de processus et les alimenter dans une étape d'analyse ou de sommation conjointe. + +### Et ensuite ? + +Apprenez à passer plus d'une entrée à un processus. + +--- + +## 3. Passer plus d'une entrée à un processus + +Nous voulons pouvoir nommer le fichier de sortie final avec un nom spécifique afin de traiter des lots ultérieurs de messages de bienvenue sans écraser les résultats finaux. + +Pour ce faire, nous allons apporter les améliorations suivantes au workflow : + +- Modifier le processus collecteur pour accepter un nom défini par l'utilisateur pour le fichier de sortie +- Ajouter un paramètre de ligne de commande au workflow et le passer au processus collecteur + +### 3.1. Modifier le processus collecteur + +Nous allons devoir déclarer l'entrée supplémentaire et l'intégrer dans le nom du fichier de sortie. + +#### 3.1.1. Déclarer l'entrée supplémentaire + +Bonne nouvelle : nous pouvons déclarer autant de variables d'entrée que nous voulons dans la définition du processus. +Appelons celle-ci `batch_name`. + +Dans le bloc du processus, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Vous pouvez configurer vos processus pour attendre autant d'entrées que vous le souhaitez. +Pour le moment, ce sont toutes des entrées requises ; vous _devez_ fournir une valeur pour que le workflow fonctionne. + +Vous apprendrez comment gérer les entrées requises vs. optionnelles plus tard dans votre parcours Nextflow. + +#### 3.1.2. Utiliser la variable `batch_name` dans le nom du fichier de sortie + +Nous pouvons insérer la variable dans le nom du fichier de sortie de la même manière que nous avons composé des noms de fichiers dynamiques auparavant. + +Dans le bloc du processus, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Cela configure le processus pour utiliser la valeur `batch_name` afin de générer un nom de fichier spécifique pour la sortie finale du workflow. + +### 3.2. Ajouter un paramètre de ligne de commande `batch` + +Maintenant, nous avons besoin d'un moyen de fournir la valeur pour `batch_name` et de l'alimenter à l'appel du processus. + +#### 3.2.1. Utiliser `params` pour configurer le paramètre + +Vous savez déjà comment utiliser le système `params` pour déclarer des paramètres CLI. +Utilisons cela pour déclarer un paramètre `batch` (avec une valeur par défaut parce que nous sommes paresseux). + +Dans la section des paramètres du pipeline, effectuez les modifications de code suivantes : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Tout comme nous l'avons démontré pour `--input`, vous pouvez remplacer cette valeur par défaut en spécifiant une valeur avec `--batch` sur la ligne de commande. + +#### 3.2.2. Passer le paramètre `batch` au processus + +Pour fournir la valeur du paramètre au processus, nous devons l'ajouter dans l'appel du processus. + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect()) + ``` + +Vous voyez que pour fournir plusieurs entrées à un processus, vous les listez simplement dans les parenthèses de l'appel, séparées par des virgules. + +!!! warning "Avertissement" + + Vous DEVEZ fournir les entrées au processus dans le MÊME ORDRE EXACT qu'elles sont listées dans le bloc de définition des entrées du processus. + +### 3.3. Exécuter le workflow + +Essayons d'exécuter ceci avec un nom de lot sur la ligne de commande. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Il s'exécute avec succès et produit la sortie désirée : + +??? abstract "Contenu du fichier" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Maintenant, tant que nous spécifions le paramètre de manière appropriée, les exécutions ultérieures sur d'autres lots d'entrées n'écraseront pas les résultats précédents. + +### À retenir + +Vous savez comment passer plus d'une entrée à un processus. + +### Et ensuite ? + +Apprenez à émettre plusieurs sorties et à les gérer de manière pratique. + +--- + +## 4. Ajouter une sortie à l'étape collecteur + +Jusqu'à présent, nous avons utilisé des processus qui ne produisaient qu'une seule sortie chacun. +Nous avons pu accéder à leurs sorties respectives de manière très pratique en utilisant la syntaxe `<process>.out`, que nous avons utilisée à la fois dans le contexte du passage d'une sortie au processus suivant (par exemple `convertToUpper(sayHello.out)`) et dans le contexte de la section `publish:` (par exemple `first_output = sayHello.out`). + +Que se passe-t-il quand un processus en produit plus d'une ? +Comment gérons-nous les sorties multiples ? +Pouvons-nous sélectionner et utiliser une sortie spécifique ? + +Toutes d'excellentes questions, et la réponse courte est oui, nous le pouvons ! + +Les sorties multiples seront empaquetées dans des canaux séparés. +Nous pouvons soit choisir de donner des noms à ces canaux de sortie, ce qui facilite la référence individuelle plus tard, soit nous y référer par index. + +Explorons avec un exemple. + +À des fins de démonstration, disons que nous voulons compter le nombre de messages de bienvenue qui sont collectés pour un lot donné d'entrées et le rapporter dans un fichier. + +### 4.1. Modifier le processus pour compter et sortir le nombre de messages de bienvenue + +Cela nécessitera deux changements clés à la définition du processus : nous avons besoin d'un moyen de compter les messages de bienvenue et d'écrire un fichier de rapport, puis nous devons ajouter ce fichier de rapport au bloc `output` du processus. + +#### 4.1.1. Compter le nombre de messages de bienvenue collectés + +De manière pratique, Nextflow nous permet d'ajouter du code arbitraire dans le bloc `script:` de la définition du processus, ce qui s'avère vraiment pratique pour faire des choses comme ceci. + +Cela signifie que nous pouvons utiliser la fonction intégrée `size()` de Nextflow pour obtenir le nombre de fichiers dans le tableau `input_files`, et écrire le résultat dans un fichier avec une commande `echo`. + +Dans le bloc du processus `collectGreetings`, effectuez les modifications de code suivantes : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +La variable `count_greetings` sera calculée à l'exécution. + +#### 4.1.2. Émettre le fichier de rapport et nommer les sorties + +En principe, tout ce que nous devons faire est d'ajouter le fichier de rapport au bloc `output:`. + +Cependant, pendant que nous y sommes, nous allons également ajouter quelques balises `emit:` à nos déclarations de sortie. Celles-ci nous permettront de sélectionner les sorties par nom au lieu d'avoir à utiliser des indices positionnels. + +Dans le bloc du processus, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +Les balises `emit:` sont optionnelles, et nous aurions pu ajouter une balise à une seule des sorties. +Mais comme dit le dicton, pourquoi pas les deux ? + +!!! tip "Astuce" + + Si vous ne nommez pas les sorties d'un processus en utilisant `emit:`, vous pouvez toujours y accéder individuellement en utilisant leur index respectif (basé sur zéro). + Par exemple, vous utiliseriez `<process>.out[0]` pour obtenir la première sortie, `<process>.out[1]` pour obtenir la deuxième sortie, et ainsi de suite. + + Nous préférons nommer les sorties parce que sinon, il est trop facile de saisir le mauvais index par erreur, surtout quand le processus produit beaucoup de sorties. + +### 4.2. Mettre à jour les sorties du workflow + +Maintenant que nous avons deux sorties provenant du processus `collectGreetings`, la sortie `collectGreetings.out` contient deux canaux : + +- `collectGreetings.out.outfile` contient le fichier de sortie final +- `collectGreetings.out.report` contient le fichier de rapport + +Nous devons mettre à jour les sorties du workflow en conséquence. + +#### 4.2.1. Mettre à jour la section `publish:` + +Dans le bloc `workflow`, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Comme vous pouvez le voir, se référer à des sorties de processus spécifiques est maintenant trivial. +Quand nous ajouterons une étape de plus à notre pipeline dans la Partie 5 (Conteneurs), nous pourrons facilement nous référer à `collectGreetings.out.outfile` et le passer au nouveau processus (spoiler : le nouveau processus s'appelle `cowpy`). + +Mais pour l'instant, finissons de mettre à jour les sorties au niveau du workflow. + +#### 4.2.2. Mettre à jour le bloc `output` + +Dans le bloc `output`, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Nous n'avons pas besoin de mettre à jour la définition de sortie `collected` puisque ce nom n'a pas changé. +Nous devons juste ajouter la nouvelle sortie. + +### 4.3. Exécuter le workflow + +Essayons d'exécuter ceci avec le lot actuel de messages de bienvenue. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Si vous regardez dans le répertoire `results/hello_workflow/`, vous trouverez le nouveau fichier de rapport, `trio-report.txt`. +Ouvrez-le pour vérifier que le workflow a correctement rapporté le nombre de messages de bienvenue qui ont été traités. + +??? abstract "Contenu du fichier" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +N'hésitez pas à ajouter plus de messages de bienvenue au CSV et tester ce qui se passe. + +### À retenir + +Vous savez comment faire en sorte qu'un processus émette plusieurs sorties nommées et comment les gérer de manière appropriée au niveau du workflow. + +Plus généralement, vous comprenez les principes clés impliqués dans la connexion des processus ensemble de manières courantes. + +### Et ensuite ? + +Prenez une pause extra longue, vous l'avez bien méritée. + +Quand vous êtes prêt, passez à la [**Partie 4 : Hello Modules**](./04_hello_modules.md) pour apprendre comment modulariser votre code pour une meilleure maintenabilité et efficacité du code. + +--- + +## Quiz + +<quiz> +Comment accédez-vous à la sortie d'un processus dans le bloc workflow ? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +En savoir plus : [1.4. Passer la sortie du premier processus au deuxième processus](#14-passer-la-sortie-du-premier-processus-au-deuxieme-processus) +</quiz> + +<quiz> +Qu'est-ce qui détermine l'ordre d'exécution des processus dans Nextflow ? +- [ ] L'ordre dans lequel les processus sont écrits dans le bloc workflow +- [ ] L'ordre alphabétique par nom de processus +- [x] Les dépendances de données entre les processus +- [ ] Ordre aléatoire pour l'exécution parallèle + +En savoir plus : [1.4. Passer la sortie du premier processus au deuxième processus](#14-passer-la-sortie-du-premier-processus-au-deuxieme-processus) +</quiz> + +<quiz> +Quel opérateur doit remplacer `???` pour rassembler toutes les sorties dans une seule liste pour le processus en aval ? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +En savoir plus : [2.4. Utiliser un opérateur pour collecter les messages de bienvenue dans une seule entrée](#24-utiliser-un-operateur-pour-collecter-les-messages-de-bienvenue-dans-une-seule-entree) +</quiz> + +<quiz> +Quand devriez-vous utiliser l'opérateur `collect()` ? +- [ ] Quand vous voulez traiter les éléments en parallèle +- [ ] Quand vous devez filtrer le contenu d'un canal +- [x] Quand un processus en aval a besoin de tous les éléments d'un processus en amont +- [ ] Quand vous voulez diviser les données entre plusieurs processus + +En savoir plus : [2.4. Utiliser un opérateur pour collecter les messages de bienvenue dans une seule entrée](#24-utiliser-un-operateur-pour-collecter-les-messages-de-bienvenue-dans-une-seule-entree) +</quiz> + +<quiz> +Comment accédez-vous à une sortie nommée d'un processus ? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +En savoir plus : [4.1.2. Émettre le fichier de rapport et nommer les sorties](#412-emettre-le-fichier-de-rapport-et-nommer-les-sorties) +</quiz> + +<quiz> +Quelle est la syntaxe correcte pour nommer une sortie dans un processus ? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +En savoir plus : [4.1.2. Émettre le fichier de rapport et nommer les sorties](#412-emettre-le-fichier-de-rapport-et-nommer-les-sorties) +</quiz> + +<quiz> +Lors de la fourniture de plusieurs entrées à un processus, qu'est-ce qui doit être vrai ? +- [ ] Toutes les entrées doivent être du même type +- [ ] Les entrées doivent être fournies dans l'ordre alphabétique +- [x] L'ordre des entrées doit correspondre à l'ordre défini dans le bloc d'entrée +- [ ] Seules deux entrées peuvent être fournies à la fois + +En savoir plus : [3. Passer plus d'une entrée à un processus](#3-passer-plus-dune-entree-a-un-processus) +</quiz> diff --git a/docs/fr/docs/hello_nextflow/04_hello_modules.md b/docs/fr/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..3cd57aa5a5 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Partie 4 : Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube de Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/04_hello_modules.md). +/// + +Cette section couvre comment organiser votre code de workflow pour rendre le développement et la maintenance de votre pipeline plus efficaces et durables. +Plus précisément, nous allons démontrer comment utiliser des **modules**. + +Dans Nextflow, un **module** est une définition de processus unique qui est encapsulée par elle-même dans un fichier de code autonome. +Pour utiliser un module dans un workflow, vous ajoutez simplement une instruction d'importation sur une seule ligne à votre fichier de code de workflow ; ensuite vous pouvez intégrer le processus dans le workflow de la même manière que vous le feriez normalement. +Cela permet de réutiliser des définitions de processus dans plusieurs workflows sans produire plusieurs copies du code. + +Quand nous avons commencé à développer notre workflow, nous avons tout écrit dans un seul fichier de code. +Maintenant, nous allons déplacer les processus dans des modules individuels. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Cela rendra notre code plus partageable, flexible et maintenable. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez complété les Parties 1-3 du cours [Hello Nextflow](./index.md), mais si vous êtes à l'aise avec les bases couvertes dans ces sections, vous pouvez commencer ici sans rien faire de spécial. + +--- + +## 0. Échauffement : Exécuter `hello-modules.nf` + +Nous allons utiliser le script de workflow `hello-modules.nf` comme point de départ. +Il est équivalent au script produit en travaillant à travers la Partie 3 de ce cours de formation, sauf que nous avons changé les destinations de sortie : + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'effectuer des modifications : + +```bash +nextflow run hello-modules.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Comme précédemment, vous trouverez les fichiers de sortie dans le répertoire spécifié dans le bloc `output` (ici, `results/hello_modules/`). + +??? abstract "Contenu du répertoire" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Si cela a fonctionné pour vous, vous êtes prêt à apprendre comment modulariser votre code de workflow. + +--- + +## 1. Créer un répertoire pour stocker les modules + +Il est recommandé de stocker vos modules dans un répertoire spécifique. +Vous pouvez appeler ce répertoire comme vous le souhaitez, mais la convention est de l'appeler `modules/`. + +```bash +mkdir modules +``` + +!!! tip "Astuce" + + Ici, nous vous montrons comment utiliser des **modules locaux**, c'est-à-dire des modules stockés localement dans le même dépôt que le reste du code du workflow, par opposition aux modules distants, qui sont stockés dans d'autres dépôts (distants). + Pour plus d'informations sur les **modules distants**, consultez la [documentation](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Créer un module pour `sayHello()` + +Dans sa forme la plus simple, transformer un processus existant en module n'est guère plus qu'une opération de copier-coller. +Nous allons créer un fichier stub pour le module, copier le code pertinent puis le supprimer du fichier de workflow principal. + +Ensuite, tout ce que nous aurons à faire est d'ajouter une instruction d'importation pour que Nextflow sache récupérer le code pertinent à l'exécution. + +### 2.1. Créer un fichier stub pour le nouveau module + +Créons un fichier vide pour le module appelé `sayHello.nf`. + +```bash +touch modules/sayHello.nf +``` + +Cela nous donne un endroit pour mettre le code du processus. + +### 2.2. Déplacer le code du processus `sayHello` vers le fichier module + +Copiez l'ensemble de la définition du processus du fichier de workflow vers le fichier module, en vous assurant de copier également le shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Une fois cela fait, supprimez la définition du processus du fichier de workflow, mais assurez-vous de laisser le shebang en place. + +### 2.3. Ajouter une déclaration d'importation avant le bloc workflow + +La syntaxe pour importer un module local est assez simple : + +```groovy title="Syntaxe : Déclaration d'importation" +include { <NOM_DU_MODULE> } from '<chemin_vers_le_module>' +``` + +Insérons cela au-dessus du bloc `params` et remplissons-le de manière appropriée. + +=== "Après" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Avant" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Vous voyez que nous avons renseigné le nom du module, `sayHello`, et le chemin vers le fichier contenant le code du module, `./modules/sayHello.nf`. + +### 2.4. Exécuter le workflow + +Nous exécutons le workflow avec essentiellement le même code et les mêmes entrées qu'avant, donc exécutons avec le flag `-resume` et voyons ce qui se passe. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Cela devrait s'exécuter très rapidement car tout est en cache. +N'hésitez pas à vérifier les sorties publiées. + +Nextflow a reconnu que c'est toujours le même travail à faire, même si le code est divisé en plusieurs fichiers. + +### À retenir + +Vous savez comment extraire un processus dans un module local et vous savez que faire cela ne casse pas la reprise du workflow. + +### Et ensuite ? + +Pratiquez la création de plus de modules. +Une fois que vous en avez fait un, vous pouvez en faire un million de plus... +Mais faisons-en juste deux de plus pour l'instant. + +--- + +## 3. Modulariser le processus `convertToUpper()` + +### 3.1. Créer un fichier stub pour le nouveau module + +Créez un fichier vide pour le module appelé `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Déplacer le code du processus `convertToUpper` vers le fichier module + +Copiez l'ensemble de la définition du processus du fichier de workflow vers le fichier module, en vous assurant de copier également le shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Utilise un outil de remplacement de texte pour convertir la salutation en majuscules + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Une fois cela fait, supprimez la définition du processus du fichier de workflow, mais assurez-vous de laisser le shebang en place. + +### 3.3. Ajouter une déclaration d'importation avant le bloc `params` + +Insérez la déclaration d'importation au-dessus du bloc `params` et remplissez-la de manière appropriée. + +=== "Après" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Avant" + + ```groovy title="hello-modules.nf" linenums="23" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Cela devrait commencer à sembler très familier. + +### 3.4. Exécuter à nouveau le workflow + +Exécutez ceci avec le flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Cela devrait toujours produire la même sortie que précédemment. + +Deux de faits, plus qu'un ! + +--- + +## 4. Modulariser le processus `collectGreetings()` + +### 4.1. Créer un fichier stub pour le nouveau module + +Créez un fichier vide pour le module appelé `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Déplacer le code du processus `collectGreetings` vers le fichier module + +Copiez l'ensemble de la définition du processus du fichier de workflow vers le fichier module, en vous assurant de copier également le shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Collecter les salutations en majuscules dans un seul fichier de sortie + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Une fois cela fait, supprimez la définition du processus du fichier de workflow, mais assurez-vous de laisser le shebang en place. + +### 4.3. Ajouter une déclaration d'importation avant le bloc `params` + +Insérez la déclaration d'importation au-dessus du bloc `params` et remplissez-la de manière appropriée. + +=== "Après" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Avant" + + ```groovy title="hello-modules.nf" linenums="3" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Paramètres du pipeline + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Dernier ! + +### 4.4. Exécuter le workflow + +Exécutez ceci avec le flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Cela devrait toujours produire la même sortie que précédemment. + +### À retenir + +Vous savez comment modulariser plusieurs processus dans un workflow. + +Félicitations, vous avez fait tout ce travail et absolument rien n'a changé dans le fonctionnement du pipeline ! + +Blague à part, maintenant votre code est plus modulaire, et si vous décidez d'écrire un autre pipeline qui fait appel à l'un de ces processus, vous n'avez qu'à taper une courte instruction d'importation pour utiliser le module pertinent. +C'est mieux que de copier-coller le code, parce que si plus tard vous décidez d'améliorer le module, tous vos pipelines hériteront des améliorations. + +### Et ensuite ? + +Prenez une courte pause si vous le souhaitez. + +Quand vous êtes prêt, passez à la [**Partie 5 : Hello Containers**](./05_hello_containers.md) pour apprendre comment utiliser les conteneurs pour gérer les dépendances logicielles de manière plus pratique et reproductible. + +--- + +## Quiz + +<quiz> +Qu'est-ce qu'un module dans Nextflow ? +- [ ] Un fichier de configuration +- [x] Un fichier autonome contenant une définition de processus unique +- [ ] Une définition de workflow +- [ ] Un opérateur de canal + +En savoir plus : [2. Créer un module pour `sayHello()`](#2-creer-un-module-pour-sayhello) +</quiz> + +<quiz> +Quelle est la convention de nommage recommandée pour les fichiers de module ? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Où les fichiers de module doivent-ils être stockés ? +- [ ] Dans le même répertoire que le workflow +- [ ] Dans un répertoire `bin/` +- [x] Dans un répertoire `modules/` +- [ ] Dans un répertoire `lib/` + +En savoir plus : [1. Créer un répertoire pour stocker les modules](#1-creer-un-repertoire-pour-stocker-les-modules) +</quiz> + +<quiz> +Quelle est la syntaxe correcte pour importer un module ? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +En savoir plus : [2.3. Ajouter une déclaration d'importation](#23-ajouter-une-declaration-dimportation-avant-le-bloc-workflow) +</quiz> + +<quiz> +Que se passe-t-il avec la fonctionnalité `-resume` lors de l'utilisation de modules ? +- [ ] Elle ne fonctionne plus +- [ ] Elle nécessite une configuration supplémentaire +- [x] Elle fonctionne comme avant +- [ ] Elle ne fonctionne que pour les modules locaux +</quiz> + +<quiz> +Quels sont les avantages de l'utilisation de modules ? (Sélectionnez toutes les réponses applicables) +- [x] Réutilisabilité du code entre les workflows +- [x] Maintenance plus facile +- [x] Meilleure organisation du code du workflow +- [ ] Vitesse d'exécution plus rapide +</quiz> diff --git a/docs/fr/docs/hello_nextflow/05_hello_containers.md b/docs/fr/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..ee14b5ef81 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Partie 5 : Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube de Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/05_hello_containers.md). +/// + +Dans les Parties 1-4 de ce cours de formation, vous avez appris comment utiliser les blocs de construction de base de Nextflow pour assembler un workflow simple capable de traiter du texte, de paralléliser l'exécution s'il y avait plusieurs entrées, et de collecter les résultats pour un traitement ultérieur. + +Cependant, vous étiez limité aux outils UNIX de base disponibles dans votre environnement. +Les tâches du monde réel nécessitent souvent divers outils et paquets non inclus par défaut. +Typiquement, vous auriez besoin d'installer ces outils, de gérer leurs dépendances et de résoudre les conflits éventuels. + +Tout cela est très fastidieux et ennuyeux, donc nous allons vous montrer comment utiliser des **conteneurs** pour résoudre ce problème de manière beaucoup plus pratique. + +Un **conteneur** est une unité logicielle légère, autonome et exécutable créée à partir d'une **image** de conteneur qui inclut tout ce qui est nécessaire pour exécuter une application, y compris le code, les bibliothèques système et les paramètres. +Comme vous pouvez l'imaginer, cela va être très utile pour rendre vos pipelines plus reproductibles. + +Notez que nous enseignerons ceci en utilisant [Docker](https://www.docker.com/get-started/), mais gardez à l'esprit que Nextflow prend en charge [plusieurs autres technologies de conteneurs](https://www.nextflow.io/docs/latest/container.html#) également. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez complété les Parties 1-4 du cours [Hello Nextflow](./index.md) et que vous avez un pipeline fonctionnel complet. + + Si vous commencez le cours à partir de ce point, vous devrez copier le répertoire `modules` depuis les solutions : + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Échauffement : Exécuter `hello-containers.nf` + +Nous allons utiliser le script de workflow `hello-containers.nf` comme point de départ. +Il est équivalent au script produit en travaillant à travers la Partie 4 de ce cours de formation, sauf que nous avons changé les destinations de sortie : + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'effectuer des modifications : + +```bash +nextflow run hello-containers.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Comme précédemment, vous trouverez les fichiers de sortie dans le répertoire spécifié dans le bloc `output` (`results/hello_containers/`). + +??? abstract "Contenu du répertoire" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Si cela a fonctionné pour vous, vous êtes prêt à apprendre comment utiliser les conteneurs. + +--- + +## 1. Utiliser un conteneur « manuellement » + +Ce que nous voulons faire est d'ajouter une étape à notre workflow qui utilisera un conteneur pour l'exécution. + +Cependant, nous allons d'abord passer en revue quelques concepts et opérations de base pour solidifier votre compréhension de ce que sont les conteneurs avant de commencer à les utiliser dans Nextflow. + +### 1.1. Télécharger l'image de conteneur + +Pour utiliser un conteneur, vous téléchargez généralement ou _tirez_ une image de conteneur depuis un registre de conteneurs, puis exécutez l'image de conteneur pour créer une instance de conteneur. + +La syntaxe générale est la suivante : + +```bash title="Syntaxe" +docker pull '<container>' +``` + +La partie `docker pull` est l'instruction au système de conteneur pour tirer une image de conteneur depuis un dépôt. + +La partie `'<container>'` est l'adresse URI de l'image de conteneur. + +À titre d'exemple, tirons une image de conteneur qui contient [cowpy](https://github.com/jeffbuttars/cowpy), une implémentation Python d'un outil appelé `cowsay` qui génère de l'art ASCII pour afficher des entrées de texte arbitraires de manière amusante. + +```txt title="Exemple" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Il existe différents dépôts où vous pouvez trouver des conteneurs publiés. +Nous avons utilisé le service [Seqera Containers](https://seqera.io/containers/) pour générer cette image de conteneur Docker à partir du paquet Conda `cowpy` : `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Exécutez la commande pull complète : + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Sortie de la commande" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Si vous n'avez jamais téléchargé l'image auparavant, cela peut prendre une minute à compléter. +Une fois terminé, vous avez une copie locale de l'image de conteneur. + +### 1.2. Utiliser le conteneur pour exécuter `cowpy` comme une commande ponctuelle + +Une façon très courante d'utiliser les conteneurs est de les exécuter directement, _c.-à-d._ de manière non interactive. +C'est idéal pour exécuter des commandes ponctuelles. + +La syntaxe générale est la suivante : + +```bash title="Syntaxe" +docker run --rm '<container>' [commande de l'outil] +``` + +La partie `docker run --rm '<container>'` est l'instruction au système de conteneur pour démarrer une instance de conteneur à partir d'une image de conteneur et exécuter une commande à l'intérieur. +Le flag `--rm` indique au système d'arrêter l'instance du conteneur après que la commande soit terminée. + +La syntaxe `[commande de l'outil]` dépend de l'outil que vous utilisez et de la façon dont le conteneur est configuré. +Commençons simplement avec `cowpy`. + +Entièrement assemblée, la commande d'exécution du conteneur ressemble à ceci ; allez-y et exécutez-la. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Sortie de la commande" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Le système a démarré le conteneur, exécuté la commande `cowpy` avec ses paramètres, envoyé la sortie à la console et finalement, arrêté l'instance du conteneur. + +### 1.3. Utiliser le conteneur pour exécuter `cowpy` de manière interactive + +Vous pouvez également exécuter un conteneur de manière interactive, ce qui vous donne une invite shell à l'intérieur du conteneur et vous permet de jouer avec la commande. + +#### 1.3.1. Démarrer le conteneur + +Pour exécuter de manière interactive, nous ajoutons simplement `-it` à la commande `docker run`. +Optionnellement, nous pouvons spécifier le shell que nous voulons utiliser à l'intérieur du conteneur en ajoutant par exemple `/bin/bash` à la commande. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Remarquez que votre invite change en quelque chose comme `(base) root@b645838b3314:/tmp#`, ce qui indique que vous êtes maintenant à l'intérieur du conteneur. + +Vous pouvez le vérifier en exécutant `ls /` pour lister le contenu du répertoire depuis la racine du système de fichiers : + +```bash +ls / +``` + +??? abstract "Sortie de la commande" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Nous utilisons `ls` ici au lieu de `tree` parce que l'utilitaire `tree` n'est pas disponible dans ce conteneur. +Vous pouvez voir que le système de fichiers à l'intérieur du conteneur est différent du système de fichiers sur votre système hôte. + +Une limitation de ce que nous venons de faire est que le conteneur est complètement isolé du système hôte par défaut. +Cela signifie que le conteneur ne peut accéder à aucun fichier sur le système hôte à moins que vous ne l'autorisiez explicitement à le faire. + +Nous allons vous montrer comment faire cela dans une minute. + +#### 1.3.2. Exécuter la ou les commandes d'outil souhaitées + +Maintenant que vous êtes à l'intérieur du conteneur, vous pouvez exécuter la commande `cowpy` directement et lui donner quelques paramètres. +Par exemple, la documentation de l'outil dit que nous pouvons changer le personnage (« cowacter ») avec `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Sortie de la commande" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Maintenant, la sortie montre le pingouin Linux, Tux, au lieu de la vache par défaut, parce que nous avons spécifié le paramètre `-c tux`. + +Parce que vous êtes à l'intérieur du conteneur, vous pouvez exécuter la commande `cowpy` autant de fois que vous le souhaitez, en variant les paramètres d'entrée, sans avoir à vous soucier des commandes Docker. + +!!! tip "Astuce" + + Utilisez le flag '-c' pour choisir un personnage différent, y compris : + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +C'est chouette. Ce qui serait encore plus chouette, c'est si nous pouvions alimenter notre `greetings.csv` comme entrée dans ceci. +Mais puisque nous n'avons pas accès au système de fichiers, nous ne pouvons pas. + +Corrigeons cela. + +#### 1.3.3. Quitter le conteneur + +Pour quitter le conteneur, vous pouvez taper `exit` à l'invite ou utiliser le raccourci clavier ++ctrl+d++. + +```bash +exit +``` + +Votre invite devrait maintenant être revenue à ce qu'elle était avant de démarrer le conteneur. + +#### 1.3.4. Monter des données dans le conteneur + +Comme noté précédemment, le conteneur est isolé du système hôte par défaut. + +Pour permettre au conteneur d'accéder au système de fichiers hôte, vous pouvez **monter** un **volume** depuis le système hôte dans le conteneur en utilisant la syntaxe suivante : + +```bash title="Syntaxe" +-v <chemin_extérieur>:<chemin_intérieur> +``` + +Dans notre cas, `<chemin_extérieur>` sera le répertoire de travail actuel, donc nous pouvons simplement utiliser un point (`.`), et `<chemin_intérieur>` est juste un alias que nous inventons ; appelons-le `/my_project` (le chemin intérieur doit être absolu). + +Pour monter un volume, nous remplaçons les chemins et ajoutons l'argument de montage de volume à la commande docker run comme suit : + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Cela monte le répertoire de travail actuel comme un volume qui sera accessible sous `/my_project` à l'intérieur du conteneur. + +Vous pouvez vérifier que cela fonctionne en listant le contenu de `/my_project` : + +```bash +ls /my_project +``` + +??? success "Sortie de la commande" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Vous pouvez maintenant voir le contenu du répertoire de travail depuis l'intérieur du conteneur, y compris le fichier `greetings.csv` sous `data/`. + +Cela a effectivement établi un tunnel à travers la paroi du conteneur que vous pouvez utiliser pour accéder à cette partie de votre système de fichiers. + +#### 1.3.5. Utiliser les données montées + +Maintenant que nous avons monté le répertoire de travail dans le conteneur, nous pouvons utiliser la commande `cowpy` pour afficher le contenu du fichier `greetings.csv`. + +Pour ce faire, nous utiliserons `cat /my_project/data/greetings.csv | ` pour rediriger le contenu du fichier CSV vers la commande `cowpy`. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Sortie de la commande" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Cela produit l'art ASCII désiré d'une dinde débitant nos exemples de messages de bienvenue ! +Sauf qu'ici la dinde répète les lignes complètes au lieu de juste les messages de bienvenue. +Nous savons déjà que notre workflow Nextflow fera un meilleur travail ! + +N'hésitez pas à jouer avec cette commande. +Quand vous avez terminé, quittez le conteneur comme précédemment : + +```bash +exit +``` + +Vous vous retrouverez dans votre shell normal. + +### À retenir + +Vous savez comment télécharger un conteneur et l'exécuter soit de manière ponctuelle, soit de manière interactive. Vous savez également comment rendre vos données accessibles depuis l'intérieur de votre conteneur, ce qui vous permet d'essayer n'importe quel outil qui vous intéresse sur de vraies données sans avoir à installer de logiciel sur votre système. + +### Et ensuite ? + +Apprenez à utiliser les conteneurs pour l'exécution des processus Nextflow. + +--- + +## 2. Utiliser les conteneurs dans Nextflow + +Nextflow a un support intégré pour exécuter des processus à l'intérieur de conteneurs pour vous permettre d'exécuter des outils que vous n'avez pas installés dans votre environnement de calcul. +Cela signifie que vous pouvez utiliser n'importe quelle image de conteneur que vous aimez pour exécuter vos processus, et Nextflow s'occupera de télécharger l'image, de monter les données et d'exécuter le processus à l'intérieur. + +Pour démontrer ceci, nous allons ajouter une étape `cowpy` au pipeline que nous avons développé, après l'étape `collectGreetings`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Meuglez si vous êtes prêt à plonger ! + +### 2.1. Écrire un module `cowpy` + +D'abord, créons le module de processus `cowpy`. + +#### 2.1.1. Créer un fichier stub pour le nouveau module + +Créez un fichier vide pour le module appelé `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +Cela nous donne un endroit pour mettre le code du processus. + +#### 2.1.2. Copier le code du processus `cowpy` dans le fichier module + +Nous pouvons modeler notre processus `cowpy` sur les autres processus que nous avons écrits précédemment. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Générer de l'art ASCII avec cowpy +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Le processus attend un `input_file` contenant les messages de bienvenue ainsi qu'une valeur `character`. + +La sortie sera un nouveau fichier texte contenant l'art ASCII généré par l'outil `cowpy`. + +### 2.2. Ajouter cowpy au workflow + +Maintenant nous devons importer le module et appeler le processus. + +#### 2.2.1. Importer le processus `cowpy` dans `hello-containers.nf` + +Insérez la déclaration d'importation au-dessus du bloc workflow et remplissez-la de manière appropriée. + +=== "Après" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Avant" + + ```groovy title="hello-containers.nf" linenums="3" + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Maintenant le module `cowpy` est disponible pour être utilisé dans le workflow. + +#### 2.2.2. Ajouter un appel au processus `cowpy` dans le workflow + +Connectons le processus `cowpy()` à la sortie du processus `collectGreetings()`, qui comme vous vous en souvenez peut-être produit deux sorties : + +- `collectGreetings.out.outfile` contient le fichier de sortie <--_ce que nous voulons_ +- `collectGreetings.out.report` contient le fichier de rapport avec le nombre de messages de bienvenue par lot + +Dans le bloc workflow, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Avant" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Remarquez que nous avons déclaré un nouveau paramètre CLI, `params.character`, afin de spécifier quel personnage nous voulons faire dire les messages de bienvenue. + +#### 2.2.3. Ajouter le paramètre `character` au bloc `params` + +C'est techniquement optionnel mais c'est la pratique recommandée et c'est une opportunité de définir une valeur par défaut pour le personnage pendant que nous y sommes. + +=== "Après" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Avant" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Maintenant nous pouvons être paresseux et éviter de taper le paramètre character dans nos lignes de commande. + +#### 2.2.4. Mettre à jour les sorties du workflow + +Nous devons mettre à jour les sorties du workflow pour publier la sortie du processus `cowpy`. + +##### 2.2.4.1. Mettre à jour la section `publish:` + +Dans le bloc `workflow`, effectuez la modification de code suivante : + +=== "Après" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Avant" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +Le processus `cowpy` ne produit qu'une seule sortie donc nous pouvons nous y référer de la manière habituelle en ajoutant `.out`. + +Mais pour l'instant, finissons de mettre à jour les sorties au niveau du workflow. + +##### 2.2.4.2. Mettre à jour le bloc `output` + +Nous devons ajouter la sortie finale `cowpy_art` au bloc `output`. Pendant que nous y sommes, modifions également les destinations de publication puisque maintenant notre pipeline est complet et nous savons quelles sorties nous intéressent vraiment. + +Dans le bloc `output`, effectuez les modifications de code suivantes : + +=== "Après" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Maintenant les sorties publiées seront un peu mieux organisées. + +#### 2.2.5. Exécuter le workflow + +Juste pour récapituler, voici ce que nous visons : + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Pensez-vous que ça va fonctionner ? + +Supprimons les sorties publiées précédentes pour avoir une page blanche, et exécutons le workflow avec le flag `-resume`. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Sortie de la commande (éditée pour la clarté)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +Oh non, il y a une erreur ! +Le code d'erreur donné par `error exit status (127)` signifie que l'exécutable que nous avons demandé n'a pas été trouvé. + +Cela a du sens, puisque nous appelons l'outil `cowpy` mais nous n'avons pas encore spécifié de conteneur (oups). + +### 2.3. Utiliser un conteneur pour exécuter le processus `cowpy` + +Nous devons spécifier un conteneur et dire à Nextflow de l'utiliser pour le processus `cowpy()`. + +#### 2.3.1. Spécifier un conteneur pour `cowpy` + +Nous pouvons utiliser la même image que nous utilisions directement dans la première section de ce tutoriel. + +Modifiez le module `cowpy.nf` pour ajouter la directive `container` à la définition du processus comme suit : + +=== "Après" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Avant" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Cela indique à Nextflow que _si l'utilisation de Docker est activée_, il doit utiliser l'image de conteneur spécifiée ici pour exécuter le processus. + +#### 2.3.2. Activer l'utilisation de Docker via le fichier `nextflow.config` + +Remarquez que nous avons dit _« si l'utilisation de Docker est activée »_. Par défaut, elle ne l'est pas, donc nous devons dire à Nextflow qu'il est autorisé à utiliser Docker. +Pour ce faire, nous allons légèrement anticiper le sujet de la prochaine et dernière partie de ce cours (Partie 6), qui couvre la configuration. + +L'une des principales façons dont Nextflow offre pour configurer l'exécution du workflow est d'utiliser un fichier `nextflow.config`. +Lorsqu'un tel fichier est présent dans le répertoire actuel, Nextflow le chargera automatiquement et appliquera toute configuration qu'il contient. + +Nous avons fourni un fichier `nextflow.config` avec une seule ligne de code qui désactive explicitement Docker : `docker.enabled = false`. + +Maintenant, passons cela à `true` pour activer Docker : + +=== "Après" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Avant" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Astuce" + + Il est possible d'activer l'exécution Docker depuis la ligne de commande, sur une base par exécution, en utilisant le paramètre `-with-docker <container>`. + Cependant, cela ne nous permet de spécifier qu'un seul conteneur pour l'ensemble du workflow, alors que l'approche que nous venons de vous montrer nous permet de spécifier un conteneur différent par processus. + C'est mieux pour la modularité, la maintenance du code et la reproductibilité. + +#### 2.3.3. Exécuter le workflow avec Docker activé + +Exécutez le workflow avec le flag `-resume` : + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Cette fois, cela fonctionne effectivement ! +Comme d'habitude, vous pouvez trouver les sorties du workflow dans le répertoire de résultats correspondant, bien que cette fois elles soient un peu mieux organisées, avec seulement le rapport et la sortie finale au niveau supérieur, et tous les fichiers intermédiaires rangés dans un sous-répertoire. + +??? abstract "Contenu du répertoire" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +La sortie finale d'art ASCII est dans le répertoire `results/hello_containers/`, sous le nom `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Et voilà, notre belle dinde disant les messages de bienvenue comme souhaité. + +#### 2.3.4. Inspecter comment Nextflow a lancé la tâche conteneurisée + +Comme coda finale à cette section, jetons un coup d'œil au sous-répertoire de travail pour l'un des appels du processus `cowpy` pour avoir un peu plus d'aperçu sur la façon dont Nextflow fonctionne avec les conteneurs en coulisses. + +Vérifiez la sortie de votre commande `nextflow run` pour trouver le chemin vers le sous-répertoire de travail pour le processus `cowpy`. +En regardant ce que nous avons obtenu pour l'exécution montrée ci-dessus, la ligne de journal de la console pour le processus `cowpy` commence par `[98/656c6c]`. +Cela correspond au chemin de répertoire tronqué suivant : `work/98/656c6c`. + +Dans ce répertoire, vous trouverez le fichier `.command.run` qui contient toutes les commandes que Nextflow a exécutées en votre nom au cours de l'exécution du pipeline. + +??? abstract "Contenu du fichier" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Si vous cherchez `nxf_launch` dans ce fichier, vous devriez voir quelque chose comme ceci : + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Comme vous pouvez le voir, Nextflow utilise la commande `docker run` pour lancer l'appel du processus. +Il monte également le sous-répertoire de travail correspondant dans le conteneur, définit le répertoire de travail à l'intérieur du conteneur en conséquence, et exécute notre script bash modélisé dans le fichier `.command.sh`. + +Tout le travail difficile que nous avons dû faire manuellement dans la première section ? Nextflow le fait pour nous en coulisses ! + +```txt + _______________________ +< Hourra pour les robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### À retenir + +Vous savez comment utiliser les conteneurs dans Nextflow pour exécuter des processus. + +### Et ensuite ? + +Prenez une pause ! + +Quand vous êtes prêt, passez à la [**Partie 6 : Hello Config**](./06_hello_config.md) pour apprendre comment configurer l'exécution de votre pipeline pour s'adapter à votre infrastructure ainsi que gérer la configuration des entrées et des paramètres. + +C'est la toute dernière partie, et ensuite vous aurez terminé ce cours ! + +--- + +## Quiz + +<quiz> +Qu'est-ce qu'un conteneur ? +- [ ] Un type de machine virtuelle +- [ ] Un format de compression de fichiers +- [x] Une unité exécutable légère et autonome qui inclut tout ce qui est nécessaire pour exécuter une application +- [ ] Un protocole réseau +</quiz> + +<quiz> +Quelle est la différence entre une image de conteneur et une instance de conteneur ? +- [ ] C'est la même chose +- [x] Une image est un modèle ; une instance est un conteneur en cours d'exécution créé à partir de cette image +- [ ] Une instance est un modèle ; une image est un conteneur en cours d'exécution +- [ ] Les images sont pour Docker ; les instances sont pour Singularity +</quiz> + +<quiz> +Que fait le flag `-v` dans une commande `docker run` ? +- [ ] Active la sortie verbeuse +- [ ] Valide le conteneur +- [x] Monte un volume depuis le système hôte dans le conteneur +- [ ] Spécifie la version du conteneur + +En savoir plus : [1.3.4. Monter des données dans le conteneur](#134-monter-des-donnees-dans-le-conteneur) +</quiz> + +<quiz> +Pourquoi avez-vous besoin de monter des volumes lors de l'utilisation de conteneurs ? +- [ ] Pour améliorer les performances du conteneur +- [ ] Pour économiser de l'espace disque +- [x] Parce que les conteneurs sont isolés du système de fichiers hôte par défaut +- [ ] Pour activer le réseau + +En savoir plus : [1.3.4. Monter des données dans le conteneur](#134-monter-des-donnees-dans-le-conteneur) +</quiz> + +<quiz> +Comment spécifiez-vous un conteneur pour un processus Nextflow ? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +En savoir plus : [2.3.1. Spécifier un conteneur pour cowpy](#231-specifier-un-conteneur-pour-cowpy) +</quiz> + +<quiz> +Quel paramètre `nextflow.config` active Docker pour votre workflow ? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +En savoir plus : [2.3.2. Activer l'utilisation de Docker via le fichier `nextflow.config`](#232-activer-lutilisation-de-docker-via-le-fichier-nextflowconfig) +</quiz> + +<quiz> +Que gère automatiquement Nextflow lors de l'exécution d'un processus dans un conteneur ? (Sélectionnez toutes les réponses applicables) +- [x] Télécharger l'image du conteneur si nécessaire +- [x] Monter le répertoire de travail +- [x] Exécuter le script du processus à l'intérieur du conteneur +- [x] Nettoyer l'instance du conteneur après l'exécution + +En savoir plus : [2.3.4. Inspecter comment Nextflow a lancé la tâche conteneurisée](#234-inspecter-comment-nextflow-a-lance-la-tache-contenerisee) +</quiz> diff --git a/docs/fr/docs/hello_nextflow/06_hello_config.md b/docs/fr/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..7ebb460912 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# Partie 6 : Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir [la playlist complète](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sur la chaîne YouTube de Nextflow. + +:green_book: La transcription de la vidéo est disponible [ici](./transcripts/06_hello_config.md). +/// + +Cette section explorera comment configurer et gérer la configuration de votre pipeline Nextflow afin que vous puissiez personnaliser son comportement, l'adapter à différents environnements et optimiser l'utilisation des ressources _sans modifier une seule ligne du code du workflow lui-même_. + +Il existe plusieurs façons de le faire, qui peuvent être utilisées en combinaison et sont interprétées selon l'ordre de priorité décrit [ici](https://www.nextflow.io/docs/latest/config.html). + +Dans cette partie du cours, nous allons vous montrer le mécanisme de fichier de configuration le plus simple et le plus courant, le fichier `nextflow.config`, que vous avez déjà rencontré dans la Partie 5 : Hello Containers. + +Nous passerons en revue les composants essentiels de la configuration Nextflow tels que les directives de processus, les exécuteurs, les profils et les fichiers de paramètres. +En apprenant à utiliser efficacement ces options de configuration, vous pouvez améliorer la flexibilité, l'évolutivité et les performances de vos pipelines. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez complété les Parties 1-5 du cours [Hello Nextflow](./index.md) et que vous avez un pipeline fonctionnel complet. + + Si vous commencez le cours à partir de ce point, vous devrez copier le répertoire `modules` et le fichier `nextflow.config` depuis les solutions : + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + Le fichier `nextflow.config` contient la ligne `docker.enabled = true` qui active l'utilisation des conteneurs Docker. + + Si vous n'êtes pas familier avec le pipeline Hello ou si vous avez besoin d'un rappel, consultez [cette page d'information](../info/hello_pipeline.md). + +--- + +## 0. Échauffement : Exécuter `hello-config.nf` + +Nous allons utiliser le script de workflow `hello-config.nf` comme point de départ. +Il est équivalent au script produit en travaillant à travers la Partie 5 de ce cours de formation, sauf que nous avons changé les destinations de sortie : + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Juste pour s'assurer que tout fonctionne, exécutez le script une fois avant d'effectuer des modifications : + +```bash +nextflow run hello-config.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Comme précédemment, vous trouverez les fichiers de sortie dans le répertoire spécifié dans le bloc `output` (`results/hello_config/`). + +??? abstract "Contenu du répertoire" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +La sortie finale d'art ASCII est dans le répertoire `results/hello_config/`, sous le nom `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Si cela a fonctionné pour vous, vous êtes prêt à apprendre comment configurer vos pipelines. + +--- + +## 1. Gérer les paramètres d'entrée du workflow + +Nous allons commencer par un aspect de la configuration qui est simplement une extension de ce avec quoi nous avons travaillé jusqu'à présent : la gestion des paramètres d'entrée. + +Actuellement, notre workflow est configuré pour accepter plusieurs valeurs de paramètres via la ligne de commande, avec des valeurs par défaut définies dans un bloc `params` dans le script de workflow lui-même. +Cependant, vous pourriez vouloir remplacer ces valeurs par défaut sans avoir à spécifier les paramètres sur la ligne de commande ou à modifier le fichier de script original. + +Il existe plusieurs façons de le faire ; nous allons vous montrer trois façons de base qui sont très couramment utilisées. + +### 1.1. Déplacer les valeurs par défaut vers `nextflow.config` + +C'est l'approche la plus simple, bien qu'elle soit peut-être la moins flexible puisque le fichier `nextflow.config` principal n'est pas quelque chose que vous voulez éditer pour chaque exécution. +Mais elle a l'avantage de séparer les préoccupations de _déclarer_ les paramètres dans le workflow (ce qui appartient définitivement là) versus fournir des _valeurs par défaut_, qui sont plus à leur place dans un fichier de configuration. + +Faisons cela en deux étapes. + +#### 1.1.1. Créer un bloc `params` dans le fichier de configuration + +Effectuez les modifications de code suivantes dans le fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Notez que nous n'avons pas simplement copié le bloc `params` du workflow vers le fichier de configuration. +La syntaxe est un peu différente. +Dans le fichier de workflow, ce sont des déclarations typées. +Dans la configuration, ce sont des affectations de valeurs. + +Techniquement, cela suffit pour remplacer les valeurs par défaut encore spécifiées dans le fichier de workflow. +Vous pourriez modifier le personnage, par exemple, et exécuter le workflow pour vous assurer que la valeur définie dans le fichier de configuration remplace celle définie dans le fichier de workflow. + +Mais dans l'esprit de déplacer complètement la configuration vers le fichier de configuration, supprimons entièrement ces valeurs du fichier de workflow. + +#### 1.1.2. Supprimer les valeurs du bloc `params` dans le fichier de workflow + +Effectuez les modifications de code suivantes dans le fichier de workflow `hello-config.nf` : + +=== "Après" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Avant" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Paramètres du pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Maintenant, le fichier de workflow lui-même ne définit aucune valeur par défaut pour ces paramètres. + +#### 1.1.3. Exécuter le pipeline + +Testons que cela fonctionne correctement. + +```bash +nextflow run hello-config.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'avant. + +La sortie finale d'art ASCII est dans le répertoire `results/hello_config/`, sous le nom `cowpy-COLLECTED-batch-output.txt`, comme avant. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Fonctionnellement, ce déplacement n'a rien changé, mais conceptuellement c'est un peu plus propre d'avoir les valeurs par défaut définies dans le fichier de configuration. + +### 1.2. Utiliser un fichier de configuration spécifique à l'exécution + +C'est très bien, mais parfois vous pourriez vouloir exécuter des expériences temporaires avec différentes valeurs par défaut sans toucher au fichier de configuration principal. +Vous pouvez le faire en créant un nouveau fichier `nextflow.config` dans un sous-répertoire que vous utiliserez comme répertoire de travail pour vos expériences. + +#### 1.2.1. Créer le répertoire de travail avec une configuration vide + +Commençons par créer un nouveau répertoire et nous y déplacer : + +```bash +mkdir -p tux-run +cd tux-run +``` + +Ensuite, créez un fichier de configuration vide dans ce répertoire : + +```bash +touch nextflow.config +``` + +Cela produit un fichier vide. + +#### 1.2.2. Configurer la configuration expérimentale + +Maintenant, ouvrez le nouveau fichier et ajoutez les paramètres que vous voulez personnaliser : + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Notez que le chemin vers le fichier d'entrée doit refléter la structure du répertoire. + +#### 1.2.3. Exécuter le pipeline + +Nous pouvons maintenant exécuter notre pipeline depuis notre nouveau répertoire de travail. +Assurez-vous d'adapter le chemin en conséquence ! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Cela créera un nouvel ensemble de répertoires sous `tux-run/` incluant `tux-run/work/` et `tux-run/results/`. + +Dans cette exécution, Nextflow combine le `nextflow.config` dans notre répertoire actuel avec le `nextflow.config` dans le répertoire racine du pipeline, et remplace ainsi le personnage par défaut (turkey) par le personnage tux. + +Le fichier de sortie final devrait contenir le personnage tux disant les messages de bienvenue. + +??? abstract "Contenu du fichier" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Voilà ; maintenant vous avez un espace pour expérimenter sans modifier votre configuration « normale ». + +!!! warning "Avertissement" + + Assurez-vous de revenir au répertoire précédent avant de passer à la section suivante ! + + ```bash + cd .. + ``` + +Maintenant, regardons une autre façon utile de définir les valeurs des paramètres. + +### 1.3. Utiliser un fichier de paramètres + +L'approche du sous-répertoire fonctionne très bien pour l'expérimentation, mais elle implique un peu de configuration et nécessite que vous adaptiez les chemins en conséquence. +Il existe une approche plus simple lorsque vous voulez exécuter votre pipeline avec un ensemble spécifique de valeurs, ou permettre à quelqu'un d'autre de le faire avec un minimum d'effort. + +Nextflow nous permet de spécifier des paramètres via un fichier de paramètres au format YAML ou JSON, ce qui rend très pratique la gestion et la distribution d'ensembles alternatifs de valeurs par défaut, par exemple, ainsi que de valeurs de paramètres spécifiques à l'exécution. + +#### 1.3.1. Examiner le fichier de paramètres exemple + +Pour démontrer ceci, nous fournissons un fichier de paramètres exemple dans le répertoire actuel, appelé `test-params.yaml` : + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Ce fichier de paramètres contient une paire clé-valeur pour chacune des entrées que nous voulons spécifier. +Notez l'utilisation de deux-points (`:`) au lieu de signes égal (`=`) si vous comparez la syntaxe avec le fichier de configuration. +Le fichier de configuration est écrit en Groovy, tandis que le fichier de paramètres est écrit en YAML. + +!!! info "Info" + + Nous fournissons également une version JSON du fichier de paramètres comme exemple mais nous n'allons pas l'exécuter ici. + N'hésitez pas à essayer celui-là par vous-même. + +#### 1.3.2. Exécuter le pipeline + +Pour exécuter le workflow avec ce fichier de paramètres, ajoutez simplement `-params-file <nom_de_fichier>` à la commande de base. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Le fichier de sortie final devrait contenir le personnage stegosaurus disant les messages de bienvenue. + +??? abstract "Contenu du fichier" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Utiliser un fichier de paramètres peut sembler excessif lorsque vous n'avez que quelques paramètres à spécifier, mais certains pipelines attendent des dizaines de paramètres. +Dans ces cas, utiliser un fichier de paramètres nous permettra de fournir des valeurs de paramètres à l'exécution sans avoir à taper des lignes de commande massives et sans modifier le script de workflow. + +Cela facilite également la distribution d'ensembles de paramètres aux collaborateurs, ou comme information de support pour une publication, par exemple. +Cela rend votre travail plus reproductible par d'autres. + +### À retenir + +Vous savez comment tirer parti des options de configuration clés pour gérer les entrées du workflow. + +### Et ensuite ? + +Apprenez à gérer où et comment les sorties de votre workflow sont publiées. + +--- + +## 2. Gérer les sorties du workflow + +Jusqu'à présent, nous avons codé en dur tous les chemins pour les déclarations de sortie au niveau du workflow, et comme nous l'avons noté lorsque nous avons commencé à ajouter plusieurs sorties, il peut y avoir un peu de répétition impliquée. + +Regardons quelques façons courantes de configurer cela pour être plus flexible. + +### 2.1. Personnaliser le nom du répertoire `outputDir` + +Pour chaque chapitre de ce cours, nous avons publié les sorties dans un sous-répertoire différent codé en dur dans les définitions de sortie. + +Changeons cela pour utiliser un paramètre configurable par l'utilisateur. +Nous pourrions créer un tout nouveau paramètre pour cela, mais utilisons le paramètre `batch` puisqu'il est juste là. + +#### 2.1.1. Définir une valeur pour `outputDir` dans le fichier de configuration + +Le chemin que Nextflow utilise pour publier les sorties est contrôlé par l'option `outputDir`. +Pour changer le chemin pour toutes les sorties, vous pouvez définir une valeur pour cette option dans le fichier de configuration `nextflow.config`. + +Ajoutez le code suivant au fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="9" + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Cela remplacera le chemin par défaut intégré, `results/`, par `results/` plus la valeur du paramètre `batch` comme sous-répertoire. +Vous pourriez également changer la partie `results` si vous le souhaitez. + +Pour un changement temporaire, vous pourriez définir cette option depuis la ligne de commande en utilisant le paramètre `-output-dir` dans votre commande (mais alors vous ne pourriez pas utiliser la valeur du paramètre `batch`). + +#### 2.1.2. Supprimer la partie répétée du chemin codé en dur + +Nous avons toujours un sous-répertoire codé en dur dans les options de sortie, donc supprimons-le maintenant. + +Effectuez les modifications de code suivantes dans le fichier de workflow : + +=== "Après" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +Nous aurions aussi pu simplement ajouter `${params.batch}` à chaque chemin au lieu de modifier le `outputDir` par défaut, mais ceci est plus concis. + +#### 2.1.3. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot à `outdir` depuis la ligne de commande. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'avant, sauf que cette fois nous trouvons nos sorties sous `results/outdir/`. + +??? abstract "Contenu du répertoire" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Vous pouvez combiner cette approche avec des définitions de chemin personnalisées pour construire n'importe quelle hiérarchie de répertoires que vous aimez. + +### 2.2. Organiser les sorties par processus + +Une façon populaire d'organiser davantage les sorties est de le faire par processus, _c.-à-d._ créer des sous-répertoires pour chaque processus exécuté dans le pipeline. + +#### 2.2.1. Remplacer les chemins de sortie par une référence aux noms de processus + +Tout ce que vous devez faire est de référencer le nom du processus comme `<task>.name` dans la déclaration du chemin de sortie. + +Effectuez les modifications suivantes dans le fichier de workflow : + +=== "Après" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Cela supprime les éléments codés en dur restants de la configuration du chemin de sortie. + +#### 2.2.2. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot à `pnames` depuis la ligne de commande. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'avant, sauf que cette fois nous trouvons nos sorties sous `results/pnames/`, et elles sont groupées par processus. + +??? abstract "Contenu du répertoire" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Notez qu'ici nous avons effacé la distinction entre les `intermediates` versus les sorties finales étant au niveau supérieur. +Vous pourriez bien sûr mélanger et assortir ces approches, par exemple en définissant le chemin de la première sortie comme `intermediates/${sayHello.process}` + +### 2.3. Définir le mode de publication au niveau du workflow + +Enfin, dans l'esprit de réduire la quantité de code répétitif, nous pouvons remplacer les déclarations `mode` par sortie par une seule ligne dans la configuration. + +#### 2.3.1. Ajouter `workflow.output.mode` au fichier de configuration + +Ajoutez le code suivant au fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Tout comme l'option `outputDir`, donner une valeur à `workflow.output.mode` dans le fichier de configuration serait suffisant pour remplacer ce qui est défini dans le fichier de workflow, mais supprimons quand même le code inutile. + +#### 2.3.2. Supprimer le mode de sortie du fichier de workflow + +Effectuez les modifications suivantes dans le fichier de workflow : + +=== "Après" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Avant" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +C'est plus concis, n'est-ce pas ? + +#### 2.3.3. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot à `outmode` depuis la ligne de commande. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'avant, sauf que cette fois nous trouvons nos sorties sous `results/outmode/`. +Ce sont toujours de vraies copies, pas des liens symboliques. + +??? abstract "Contenu du répertoire" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +La principale raison pour laquelle vous pourriez encore vouloir utiliser la façon par sortie de définir le mode est si vous voulez mélanger et assortir au sein du même workflow, _c.-à-d._ avoir certaines sorties copiées et d'autres liées symboliquement. + +Il y a plein d'autres options que vous pouvez personnaliser de cette façon, mais espérons que cela vous donne une idée de l'éventail d'options et comment les utiliser efficacement selon vos préférences. + +### À retenir + +Vous savez comment contrôler le nommage et la structure des répertoires où vos sorties sont publiées, ainsi que le mode de publication des sorties du workflow. + +### Et ensuite ? + +Apprenez à adapter la configuration de votre workflow à votre environnement de calcul, en commençant par la technologie de packaging logiciel. + +--- + +## 3. Sélectionner une technologie de packaging logiciel + +Jusqu'à présent, nous avons examiné des éléments de configuration qui contrôlent comment les entrées entrent et où les sorties sortent. Maintenant, il est temps de nous concentrer plus spécifiquement sur l'adaptation de la configuration de votre workflow à votre environnement de calcul. + +La première étape sur ce chemin est de spécifier d'où proviendront les packages logiciels qui seront exécutés à chaque étape. +Sont-ils déjà installés dans l'environnement de calcul local ? +Devons-nous récupérer des images et les exécuter via un système de conteneurs ? +Ou devons-nous récupérer des packages Conda et construire un environnement Conda local ? + +Dans la toute première partie de ce cours de formation (Parties 1-4), nous avons simplement utilisé des logiciels installés localement dans notre workflow. +Puis dans la Partie 5, nous avons introduit les conteneurs Docker et le fichier `nextflow.config`, que nous avons utilisé pour activer l'utilisation des conteneurs Docker. + +Maintenant, voyons comment nous pouvons configurer une option de packaging logiciel alternative via le fichier `nextflow.config`. + +### 3.1. Désactiver Docker et activer Conda dans le fichier de configuration + +Prétendons que nous travaillons sur un cluster HPC et que l'administrateur n'autorise pas l'utilisation de Docker pour des raisons de sécurité. +Heureusement pour nous, Nextflow prend en charge plusieurs autres technologies de conteneurs comme Singularity (qui est plus largement utilisé sur HPC), et des gestionnaires de packages logiciels tels que Conda. + +Nous pouvons changer notre fichier de configuration pour utiliser Conda au lieu de Docker. +Pour ce faire, changeons la valeur de `docker.enabled` à `false`, et ajoutons une directive activant l'utilisation de Conda : + +=== "Après" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Cela permettra à Nextflow de créer et d'utiliser des environnements Conda pour les processus qui ont des packages Conda spécifiés. +Ce qui signifie que nous devons maintenant en ajouter un à notre processus `cowpy` ! + +### 3.2. Spécifier un package Conda dans la définition du processus + +Nous avons déjà récupéré l'URI pour un package Conda contenant l'outil `cowpy` : `conda-forge::cowpy==1.1.5` + +Maintenant nous ajoutons l'URI à la définition du processus `cowpy` en utilisant la directive `conda` : + +=== "Après" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Avant" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Pour être clair, nous ne _remplaçons_ pas la directive `docker`, nous _ajoutons_ une option alternative. + +!!! tip "Astuce" + + Il existe plusieurs façons d'obtenir l'URI pour un package conda donné. + Nous recommandons d'utiliser la requête de recherche [Seqera Containers](https://seqera.io/containers/), qui vous donnera un URI que vous pouvez copier et coller, même si vous ne prévoyez pas de créer un conteneur à partir de celui-ci. + +### 3.3. Exécuter le workflow pour vérifier qu'il peut utiliser Conda + +Essayons. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Sortie de la commande" + + ```console title="Sortie" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Cela devrait fonctionner sans problème et produire les mêmes sorties qu'avant sous `results/conda`. + +En coulisses, Nextflow a récupéré les packages Conda et créé l'environnement, ce qui prend normalement un peu de travail ; c'est donc agréable que nous n'ayons pas à faire tout cela nous-mêmes ! + +!!! note "Note" + + Cela s'exécute rapidement parce que le package `cowpy` est assez petit, mais si vous travaillez avec de gros packages, cela peut prendre un peu plus de temps que d'habitude la première fois, et vous pourriez voir la sortie de la console rester « coincée » pendant une minute environ avant de se terminer. + C'est normal et c'est dû au travail supplémentaire que fait Nextflow la première fois que vous utilisez un nouveau package. + +De notre point de vue, cela semble fonctionner exactement de la même manière qu'avec Docker, même si en coulisses la mécanique est un peu différente. + +Cela signifie que nous sommes prêts à exécuter avec des environnements Conda si nécessaire. + +??? info "Mélanger et assortir Docker et Conda" + + Puisque ces directives sont assignées par processus, il est possible de « mélanger et assortir », _c.-à-d._ configurer certains des processus de votre workflow pour s'exécuter avec Docker et d'autres avec Conda, par exemple, si l'infrastructure de calcul que vous utilisez prend en charge les deux. + Dans ce cas, vous activeriez à la fois Docker et Conda dans votre fichier de configuration. + Si les deux sont disponibles pour un processus donné, Nextflow priorisera les conteneurs. + + Et comme noté précédemment, Nextflow prend en charge plusieurs autres technologies de packaging logiciel et de conteneurs, donc vous n'êtes pas limité à ces deux-là. + +### À retenir + +Vous savez comment configurer quel package logiciel chaque processus doit utiliser, et comment basculer entre les technologies. + +### Et ensuite ? + +Apprenez à changer la plateforme d'exécution utilisée par Nextflow pour effectivement faire le travail. + +--- + +## 4. Sélectionner une plateforme d'exécution + +Jusqu'à présent, nous avons exécuté notre pipeline avec l'exécuteur local. +Celui-ci exécute chaque tâche sur la machine sur laquelle Nextflow s'exécute. +Quand Nextflow démarre, il regarde les CPU et la mémoire disponibles. +Si les ressources des tâches prêtes à s'exécuter dépassent les ressources disponibles, Nextflow retiendra les dernières tâches de l'exécution jusqu'à ce qu'une ou plusieurs des tâches précédentes soient terminées, libérant les ressources nécessaires. + +L'exécuteur local est pratique et efficace, mais il est limité à cette seule machine. Pour de très grandes charges de travail, vous pourriez découvrir que votre machine locale est un goulot d'étranglement, soit parce que vous avez une seule tâche qui nécessite plus de ressources que ce que vous avez disponible, soit parce que vous avez tellement de tâches qu'attendre qu'une seule machine les exécute prendrait trop de temps. + +Nextflow prend en charge [de nombreux backends d'exécution différents](https://www.nextflow.io/docs/latest/executor.html), y compris les ordonnanceurs HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor et autres) ainsi que les backends d'exécution cloud tels que (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes et plus). + +### 4.1. Cibler un backend différent + +Le choix de l'exécuteur est défini par une directive de processus appelée `executor`. +Par défaut, elle est définie sur `local`, donc la configuration suivante est implicite : + +```groovy title="Configuration intégrée" +process { + executor = 'local' +} +``` + +Pour définir l'exécuteur pour cibler un backend différent, vous spécifieriez simplement l'exécuteur que vous voulez en utilisant une syntaxe similaire à celle décrite ci-dessus pour les allocations de ressources (voir la [documentation](https://www.nextflow.io/docs/latest/executor.html) pour toutes les options). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Avertissement" + + Nous ne pouvons pas réellement tester ceci dans l'environnement de formation car il n'est pas configuré pour se connecter à un HPC. + +### 4.2. Gérer la syntaxe spécifique au backend pour les paramètres d'exécution + +La plupart des plateformes de calcul haute performance permettent (et parfois exigent) que vous spécifiiez certains paramètres tels que les demandes et limitations d'allocation de ressources (par exemple, nombre de CPU et mémoire) et le nom de la file d'attente de jobs à utiliser. + +Malheureusement, chacun de ces systèmes utilise des technologies, syntaxes et configurations différentes pour définir comment un job doit être défini et soumis à l'ordonnanceur correspondant. + +??? abstract "Exemples" + + Par exemple, le même job nécessitant 8 CPU et 4 Go de RAM à exécuter sur la file « my-science-work » doit être exprimé de différentes manières selon le backend. + + ```bash title="Config pour SLURM / soumettre avec sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config pour PBS / soumettre avec qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config pour SGE / soumettre avec qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Heureusement, Nextflow simplifie tout cela. +Il fournit une syntaxe standardisée pour que vous puissiez spécifier les propriétés pertinentes telles que `cpus`, `memory` et `queue` (voir la documentation pour d'autres propriétés) une seule fois. +Ensuite, à l'exécution, Nextflow utilisera ces paramètres pour générer les scripts appropriés spécifiques au backend en fonction du paramètre d'exécuteur. + +Nous couvrirons cette syntaxe standardisée dans la section suivante. + +### À retenir + +Vous savez maintenant comment changer l'exécuteur pour utiliser différents types d'infrastructure de calcul. + +### Et ensuite ? + +Apprenez à évaluer et exprimer les allocations et limitations de ressources dans Nextflow. + +--- + +## 5. Contrôler les allocations de ressources de calcul + +La plupart des plateformes de calcul haute performance permettent (et parfois exigent) que vous spécifiiez certains paramètres d'allocation de ressources tels que le nombre de CPU et la mémoire. + +Par défaut, Nextflow utilisera un seul CPU et 2 Go de mémoire pour chaque processus. +Les directives de processus correspondantes sont appelées `cpus` et `memory`, donc la configuration suivante est implicite : + +```groovy title="Configuration intégrée" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Vous pouvez modifier ces valeurs, soit pour tous les processus, soit pour des processus nommés spécifiques, en utilisant des directives de processus supplémentaires dans votre fichier de configuration. +Nextflow les traduira en instructions appropriées pour l'exécuteur choisi. + +Mais comment savez-vous quelles valeurs utiliser ? + +### 5.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources + +Si vous ne savez pas à l'avance combien de CPU et de mémoire vos processus sont susceptibles d'avoir besoin, vous pouvez faire du profilage de ressources, ce qui signifie que vous exécutez le workflow avec des allocations par défaut, enregistrez combien chaque processus a utilisé, et à partir de là, estimez comment ajuster les allocations de base. + +De manière pratique, Nextflow inclut des outils intégrés pour faire ceci, et générera volontiers un rapport pour vous sur demande. + +Pour ce faire, ajoutez `-with-report <nom_de_fichier>.html` à votre ligne de commande. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Le rapport est un fichier html, que vous pouvez télécharger et ouvrir dans votre navigateur. Vous pouvez également faire un clic droit dessus dans l'explorateur de fichiers à gauche et cliquer sur `Show preview` pour le visualiser dans l'environnement de formation. + +Prenez quelques minutes pour parcourir le rapport et voir si vous pouvez identifier des opportunités d'ajustement des ressources. +Assurez-vous de cliquer sur les onglets qui montrent les résultats d'utilisation en pourcentage de ce qui a été alloué. +Il y a de la [documentation](https://www.nextflow.io/docs/latest/reports.html) décrivant toutes les fonctionnalités disponibles. + +### 5.2. Définir les allocations de ressources pour tous les processus + +Le profilage montre que les processus de notre workflow de formation sont très légers, donc réduisons l'allocation de mémoire par défaut à 1 Go par processus. + +Ajoutez ce qui suit à votre fichier `nextflow.config`, avant la section des paramètres du pipeline : + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Cela aidera à réduire la quantité de calcul que nous consommons. + +### 5.3. Définir les allocations de ressources pour un processus spécifique + +En même temps, nous allons prétendre que le processus `cowpy` nécessite plus de ressources que les autres, juste pour pouvoir démontrer comment ajuster les allocations pour un processus individuel. + +=== "Après" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Avec cette configuration, tous les processus demanderont 1 Go de mémoire et un seul CPU (la valeur par défaut implicite), sauf le processus `cowpy`, qui demandera 2 Go et 2 CPU. + +!!! tip "Astuce" + + Si vous avez une machine avec peu de CPU et que vous en allouez un nombre élevé par processus, vous pourriez voir des appels de processus mis en file d'attente derrière d'autres. + C'est parce que Nextflow s'assure que nous ne demandons pas plus de CPU qu'il n'y en a de disponibles. + +### 5.4. Exécuter le workflow avec la configuration mise à jour + +Essayons cela, en fournissant un nom de fichier différent pour le rapport de profilage afin que nous puissions comparer les performances avant et après les changements de configuration. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Vous ne remarquerez probablement aucune différence réelle puisque c'est une si petite charge de travail, mais c'est l'approche que vous utiliseriez pour analyser les performances et les besoins en ressources d'un workflow du monde réel. + +C'est très utile lorsque vos processus ont des besoins en ressources différents. Cela vous permet de dimensionner correctement les allocations de ressources que vous configurez pour chaque processus en fonction de données réelles, pas de suppositions. + +!!! tip "Astuce" + + Ce n'est qu'un petit aperçu de ce que vous pouvez faire pour optimiser votre utilisation des ressources. + Nextflow lui-même a une [logique de réessai dynamique](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) vraiment chouette intégrée pour réessayer les jobs qui échouent en raison de limitations de ressources. + De plus, la Seqera Platform offre des outils pilotés par l'IA pour optimiser automatiquement vos allocations de ressources également. + +### 5.5. Ajouter des limites de ressources + +Selon l'exécuteur de calcul et l'infrastructure de calcul que vous utilisez, il peut y avoir des contraintes sur ce que vous pouvez (ou devez) allouer. +Par exemple, votre cluster peut exiger que vous restiez dans certaines limites. + +Vous pouvez utiliser la directive `resourceLimits` pour définir les limitations pertinentes. La syntaxe ressemble à ceci quand elle est seule dans un bloc process : + +```groovy title="Exemple de syntaxe" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow traduira ces valeurs en instructions appropriées selon l'exécuteur que vous avez spécifié. + +Nous n'allons pas exécuter ceci, puisque nous n'avons pas accès à l'infrastructure pertinente dans l'environnement de formation. +Cependant, si vous essayiez d'exécuter le workflow avec des allocations de ressources qui dépassent ces limites, puis que vous regardiez la commande `sbatch` dans le fichier de script `.command.run`, vous verriez que les demandes qui sont réellement envoyées à l'exécuteur sont plafonnées aux valeurs spécifiées par `resourceLimits`. + +??? info "Configurations de référence institutionnelles" + + Le projet nf-core a compilé une [collection de fichiers de configuration](https://nf-co.re/configs/) partagés par diverses institutions à travers le monde, couvrant un large éventail d'exécuteurs HPC et cloud. + + Ces configurations partagées sont précieuses à la fois pour les personnes qui travaillent là-bas et peuvent donc simplement utiliser la configuration de leur institution prête à l'emploi, et comme modèle pour les personnes qui cherchent à développer une configuration pour leur propre infrastructure. + +### À retenir + +Vous savez comment générer un rapport de profilage pour évaluer l'utilisation des ressources et comment modifier les allocations de ressources pour tous les processus et/ou pour des processus individuels, ainsi que définir des limitations de ressources pour l'exécution sur HPC. + +### Et ensuite ? + +Apprenez à configurer des profils de configuration prédéfinis et à basculer entre eux à l'exécution. + +--- + +## 6. Utiliser des profils pour basculer entre des configurations prédéfinies + +Nous vous avons montré plusieurs façons de personnaliser la configuration de votre pipeline selon le projet sur lequel vous travaillez ou l'environnement de calcul que vous utilisez. + +Vous pourriez vouloir basculer entre des paramètres alternatifs selon l'infrastructure de calcul que vous utilisez. Par exemple, vous pourriez vouloir développer et exécuter des tests à petite échelle localement sur votre ordinateur portable, puis exécuter des charges de travail à grande échelle sur HPC ou cloud. + +Nextflow vous permet de configurer n'importe quel nombre de profils qui décrivent différentes configurations, que vous pouvez ensuite sélectionner à l'exécution en utilisant un argument de ligne de commande, plutôt que d'avoir à modifier le fichier de configuration lui-même. + +### 6.1. Créer des profils pour basculer entre le développement local et l'exécution sur HPC + +Configurons deux profils alternatifs ; un pour exécuter de petites charges sur un ordinateur ordinaire, où nous utiliserons des conteneurs Docker, et un pour l'exécution sur un HPC universitaire avec un ordonnanceur Slurm, où nous utiliserons des packages Conda. + +#### 6.1.1. Configurer les profils + +Ajoutez ce qui suit à votre fichier `nextflow.config`, après la section des paramètres du pipeline mais avant les paramètres de sortie : + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Vous voyez que pour le HPC universitaire, nous spécifions également des limitations de ressources. + +#### 6.1.2. Exécuter le workflow avec un profil + +Pour spécifier un profil dans notre ligne de commande Nextflow, nous utilisons l'argument `-profile`. + +Essayons d'exécuter le workflow avec la configuration `my_laptop`. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Comme vous pouvez le voir, cela nous permet de basculer entre les configurations très facilement à l'exécution. + +!!! warning "Avertissement" + + Le profil `univ_hpc` ne fonctionnera pas correctement dans l'environnement de formation puisque nous n'avons pas accès à un ordonnanceur Slurm. + +Si à l'avenir nous trouvons d'autres éléments de configuration qui co-surviennent toujours avec ceux-ci, nous pouvons simplement les ajouter au(x) profil(s) correspondant(s). +Nous pouvons également créer des profils supplémentaires s'il y a d'autres éléments de configuration que nous voulons regrouper. + +### 6.2. Créer un profil de paramètres de test + +Les profils ne sont pas seulement pour la configuration de l'infrastructure. +Nous pouvons également les utiliser pour définir des valeurs par défaut pour les paramètres du workflow, pour faciliter à d'autres d'essayer le workflow sans avoir à rassembler eux-mêmes des valeurs d'entrée appropriées. +Vous pouvez considérer cela comme une alternative à l'utilisation d'un fichier de paramètres. + +#### 6.2.1. Configurer le profil + +La syntaxe pour exprimer les valeurs par défaut dans ce contexte ressemble à ceci, pour un profil que nous nommons `test` : + +```groovy title="Exemple de syntaxe" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Si nous ajoutons un profil de test pour notre workflow, le bloc `profiles` devient : + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Tout comme pour les profils de configuration technique, vous pouvez configurer plusieurs profils différents spécifiant des paramètres sous n'importe quel nom arbitraire que vous aimez. + +#### 6.2.2. Exécuter le workflow localement avec le profil de test + +De manière pratique, les profils ne sont pas mutuellement exclusifs, donc nous pouvons spécifier plusieurs profils dans notre ligne de commande en utilisant la syntaxe suivante `-profile <profile1>,<profile2>` (pour n'importe quel nombre de profils). + +Si vous combinez des profils qui définissent des valeurs pour les mêmes éléments de configuration et sont décrits dans le même fichier de configuration, Nextflow résoudra le conflit en utilisant la valeur qu'il a lue en dernier (_c.-à-d._ ce qui vient plus tard dans le fichier). +Si les paramètres conflictuels sont définis dans différentes sources de configuration, l'[ordre de priorité](https://www.nextflow.io/docs/latest/config.html) par défaut s'applique. + +Essayons d'ajouter le profil de test à notre commande précédente : + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Cela utilisera Docker quand c'est possible et produira des sorties sous `results/test`, et cette fois le personnage est le duo comique `dragonandcow`. + +??? abstract "Contenu du fichier" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Cela signifie que tant que nous distribuons tous les fichiers de données de test avec le code du workflow, n'importe qui peut rapidement essayer le workflow sans avoir à fournir ses propres entrées via la ligne de commande ou un fichier de paramètres. + +!!! tip "Astuce" + + Nous pouvons pointer vers des URLs pour des fichiers plus volumineux qui sont stockés à l'extérieur. + Nextflow les téléchargera automatiquement tant qu'il y a une connexion ouverte. + + Pour plus de détails, voir la Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Utiliser `nextflow config` pour voir la configuration résolue + +Comme noté ci-dessus, parfois le même paramètre peut être défini à des valeurs différentes dans des profils que vous voulez combiner. +Et plus généralement, il existe de nombreux endroits où des éléments de configuration peuvent être stockés, et parfois les mêmes propriétés peuvent être définies à des valeurs différentes à différents endroits. + +Nextflow applique un [ordre de priorité](https://www.nextflow.io/docs/latest/config.html) défini pour résoudre les conflits, mais cela peut être difficile à déterminer par vous-même. +Et même si rien n'est en conflit, il peut être fastidieux de chercher tous les endroits possibles où les choses pourraient être configurées. + +Heureusement, Nextflow inclut un outil utilitaire pratique appelé `config` qui peut automatiser tout ce processus pour vous. + +L'outil `config` explorera tout le contenu de votre répertoire de travail actuel, aspirera tous les fichiers de configuration, et produira la configuration entièrement résolue que Nextflow utiliserait pour exécuter le workflow. +Cela vous permet de savoir quels paramètres seront utilisés sans avoir à lancer quoi que ce soit. + +#### 6.3.1. Résoudre la configuration par défaut + +Exécutez cette commande pour résoudre la configuration qui serait appliquée par défaut. + +```bash +nextflow config +``` + +??? success "Sortie de la commande" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Cela vous montre la configuration de base que vous obtenez si vous ne spécifiez rien de plus dans la ligne de commande. + +#### 6.3.2. Résoudre la configuration avec des paramètres spécifiques activés + +Si vous fournissez des paramètres de ligne de commande, par exemple en activant un ou plusieurs profils ou en chargeant un fichier de paramètres, la commande les prendra également en compte. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Sortie de la commande" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Cela devient particulièrement utile pour des projets complexes qui impliquent plusieurs couches de configuration. + +### À retenir + +Vous savez comment utiliser des profils pour sélectionner une configuration prédéfinie à l'exécution avec un minimum de tracas. +Plus généralement, vous savez comment configurer les exécutions de votre workflow pour s'adapter à différentes plateformes de calcul et améliorer la reproductibilité de vos analyses. + +### Et ensuite ? + +Célébrez et donnez-vous une grande tape dans le dos ! Vous avez terminé votre tout premier cours de développeur Nextflow. + +Rendez-vous au [résumé final du cours](./next_steps.md) pour revoir ce que vous avez appris et découvrir ce qui vient ensuite. + +--- + +## Quiz + +<quiz> +Quel est le nom du fichier de configuration que Nextflow charge automatiquement ? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +Qu'est-ce qui a priorité lorsque le même paramètre est défini à la fois dans le fichier de configuration et sur la ligne de commande ? +- [ ] La valeur du fichier de configuration +- [x] La valeur de la ligne de commande +- [ ] La première valeur rencontrée +- [ ] Aucune ; cela provoque une erreur + +En savoir plus : [1.1. Déplacer les valeurs par défaut vers `nextflow.config`](#11-deplacer-les-valeurs-par-defaut-vers-nextflowconfig) +</quiz> + +<quiz> +Pouvez-vous avoir à la fois Docker et Conda activés dans la même configuration ? +- [x] Oui, Nextflow peut utiliser les deux selon les directives de processus +- [ ] Non, un seul peut être activé à la fois +- [ ] Oui, mais seulement dans les profils +- [ ] Non, ils sont mutuellement exclusifs +</quiz> + +<quiz> +Si Docker et Conda sont tous deux activés et qu'un processus a les deux directives, lequel est priorisé ? +- [x] Docker (conteneurs) +- [ ] Conda +- [ ] Le premier défini +- [ ] Cela provoque une erreur + +En savoir plus : [3. Sélectionner une technologie de packaging logiciel](#3-selectionner-une-technologie-de-packaging-logiciel) +</quiz> + +<quiz> +Quelle est l'allocation de mémoire par défaut pour les processus Nextflow ? +- [ ] 1 Go +- [x] 2 Go +- [ ] 4 Go +- [ ] Pas de limite +</quiz> + +<quiz> +Comment définissez-vous les besoins en ressources pour un processus spécifique dans le fichier de configuration ? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +En savoir plus : [5.3. Définir les allocations de ressources pour un processus spécifique](#53-definir-les-allocations-de-ressources-pour-un-processus-specifique) +</quiz> + +<quiz> +Quelle option de ligne de commande génère un rapport d'utilisation des ressources ? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +En savoir plus : [5.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources](#51-executer-le-workflow-pour-generer-un-rapport-dutilisation-des-ressources) +</quiz> + +<quiz> +Que fait la directive `resourceLimits` ? +- [ ] Définit les besoins minimaux en ressources +- [ ] Alloue des ressources aux processus +- [x] Plafonne le maximum de ressources qui peuvent être demandées +- [ ] Surveille l'utilisation des ressources + +En savoir plus : [5.5. Ajouter des limites de ressources](#55-ajouter-des-limites-de-ressources) +</quiz> + +<quiz> +Quel est l'exécuteur par défaut dans Nextflow ? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +En savoir plus : [4. Sélectionner une plateforme d'exécution](#4-selectionner-une-plateforme-dexecution) +</quiz> + +<quiz> +Comment spécifiez-vous un fichier de paramètres lors de l'exécution de Nextflow ? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +En savoir plus : [1.3. Utiliser un fichier de paramètres](#13-utiliser-un-fichier-de-parametres) +</quiz> + +<quiz> +À quoi peuvent servir les profils ? (Sélectionnez toutes les réponses applicables) +- [x] Définir des paramètres spécifiques à l'infrastructure +- [x] Définir des limites de ressources pour différents environnements +- [x] Fournir des paramètres de test +- [ ] Définir de nouveaux processus + +En savoir plus : [6. Utiliser des profils pour basculer entre des configurations prédéfinies](#6-utiliser-des-profils-pour-basculer-entre-des-configurations-predefinies) +</quiz> + +<quiz> +Comment spécifiez-vous plusieurs profils dans une seule commande ? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +En savoir plus : [6. Utiliser des profils pour basculer entre des configurations prédéfinies](#6-utiliser-des-profils-pour-basculer-entre-des-configurations-predefinies) +</quiz> diff --git a/docs/fr/docs/hello_nextflow/index.md b/docs/fr/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..b93bc35dd8 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Lancer et gérer l'exécution des flux de travail Nextflow + - Trouver et interpréter les sorties (résultats) et fichiers de log générés par Nextflow + - Résoudre les problèmes de base + - Construire un flux de travail simple à plusieurs étapes à partir des composants essentiels de Nextflow + - Distinguer les types essentiels de fabriques de canaux et d'opérateurs et les utiliser efficacement dans un flux de travail simple + - Configurer l'exécution du pipeline pour s'exécuter sur des plateformes de calcul courantes, y compris HPC et cloud + - Appliquer les bonnes pratiques de reproductibilité, portabilité et réutilisation du code qui rendent les pipelines FAIR, y compris la modularité du code et les conteneurs logiciels + audience_prerequisites: + - "**Public :** Ce cours est conçu pour les apprenants qui découvrent complètement Nextflow et souhaitent développer leurs propres pipelines." + - "**Compétences :** Une certaine familiarité avec la ligne de commande, les concepts de base des scripts et les formats de fichiers courants est supposée." + - "**Domaine :** Les exercices sont tous indépendants du domaine, aucune connaissance scientifique préalable n'est donc requise." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow est une introduction pratique à la construction de flux de travail d'analyse de données reproductibles et évolutifs.** + +En travaillant sur des exemples pratiques et des exercices guidés, vous apprendrez les fondamentaux du développement de pipelines avec Nextflow, notamment comment définir des processus, les connecter dans des pipelines, gérer les fichiers et les dépendances logicielles, paralléliser l'exécution sans effort et exécuter des flux de travail dans différents environnements de calcul. + +Vous repartirez avec les compétences et la confiance nécessaires pour commencer à développer et exécuter vos propres flux de travail avec Nextflow. + +<!-- additional_information --> + +## Aperçu du cours + +Ce cours est conçu pour être pratique, avec des exercices orientés vers des objectifs structurés pour introduire l'information progressivement. + +Vous développerez un pipeline Nextflow simple qui prend des entrées de texte, exécute quelques étapes de transformation et produit un fichier texte unique contenant une image ASCII d'un personnage prononçant le texte transformé. + +### Plan de cours + +Afin de ne pas vous submerger de concepts et de code, nous avons divisé cela en six parties qui se concentreront chacune sur des aspects spécifiques du développement de pipelines avec Nextflow. + +| Chapitre du cours | Résumé | Durée estimée | +| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------- | +| [Partie 1 : Hello World](./01_hello_world.md) | Composants de base et principes impliqués dans l'assemblage et l'exécution d'un flux de travail Nextflow | 30 min | +| [Partie 2 : Hello Channels](./02_hello_channels.md) | Utilisation des canaux et opérateurs pour traiter les entrées et paralléliser l'exécution sans effort | 45 min | +| [Partie 3 : Hello Workflow](./03_hello_workflow.md) | Utilisation des canaux pour enchaîner plusieurs étapes et gérer le transfert de données entre les étapes | 60 min | +| [Partie 4 : Hello Modules](./04_hello_modules.md) | Application des principes de modularité du code pour augmenter la réutilisabilité et diminuer la charge de maintenance | 20 min | +| [Partie 5 : Hello Containers](./05_hello_containers.md) | Utilisation des conteneurs comme mécanisme de gestion des dépendances logicielles et augmentation de la reproductibilité | 60 min | +| [Partie 6 : Hello Config](./06_hello_config.md) | Personnalisation du comportement du pipeline et optimisation de l'utilisation dans différents environnements de calcul | 60 min | + +À la fin de ce cours, vous serez bien préparé pour aborder les prochaines étapes de votre parcours pour développer des flux de travail reproductibles pour vos besoins de calcul scientifique. + +Prêt à suivre le cours ? + +[Commencer :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/fr/docs/hello_nextflow/next_steps.md b/docs/fr/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..5ae52d48c7 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Résumé du cours + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations pour avoir terminé le cours de formation Hello Nextflow ! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Voir la [playlist complète sur la chaîne YouTube Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Vous pouvez lire la [transcription de la vidéo](./transcripts/07_next_steps.md) en parallèle de la vidéo. +/// + +## Votre parcours + +Vous avez commencé avec un flux de travail très basique qui exécutait une commande codée en dur. +Au cours des six parties, vous avez transformé ce flux de travail basique en un pipeline modulaire à plusieurs étapes qui exploite les fonctionnalités clés de Nextflow, notamment les canaux, les opérateurs, le support intégré des conteneurs et les options de configuration. + +### Ce que vous avez construit + +- La forme finale du flux de travail Hello prend en entrée un fichier CSV contenant des salutations textuelles. +- Les quatre étapes sont implémentées comme des processus Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` et `cowpy`) stockés dans des fichiers de modules séparés. +- Les résultats sont publiés dans un répertoire appelé `results/`. +- La sortie finale du pipeline est un fichier texte brut contenant de l'art ASCII d'un personnage prononçant les salutations en majuscules. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello` :** Écrit chaque salutation dans son propre fichier de sortie (_par ex._ « Hello-output.txt ») +2. **`convertToUpper` :** Convertit chaque salutation en majuscules (_par ex._ « HELLO ») +3. **`collectGreetings` :** Collecte toutes les salutations en majuscules dans un seul fichier de lot +4. **`cowpy` :** Génère de l'art ASCII en utilisant l'outil `cowpy` + +La configuration du flux de travail permet de fournir des entrées et des paramètres de manière flexible et reproductible. + +### Compétences acquises + +Grâce à ce cours pratique, vous avez appris à : + +- Décrire et utiliser les composants essentiels de Nextflow suffisants pour construire un flux de travail simple à plusieurs étapes +- Décrire des concepts avancés tels que les opérateurs et les fabriques de canaux +- Lancer un flux de travail Nextflow localement +- Trouver et interpréter les sorties (résultats) et les fichiers de log générés par Nextflow +- Résoudre les problèmes de base + +Vous êtes maintenant équipé des connaissances fondamentales pour commencer à développer et exécuter vos propres flux de travail avec Nextflow. + +## Prochaines étapes pour développer vos compétences + +Voici nos 3 principales suggestions pour ce qu'il faut faire ensuite : + +- Appliquer Nextflow à un cas d'utilisation d'analyse scientifique avec [Nextflow pour la science](../nf4_science/index.md) +- Démarrer avec nf-core avec [Hello nf-core](../../hello_nf-core/index.md) +- Explorer des fonctionnalités Nextflow plus avancées avec les [Quêtes annexes](../side_quests/index.md) + +Enfin, nous vous recommandons de jeter un œil à la [**Plateforme Seqera**](https://seqera.io/), une plateforme basée sur le cloud développée par les créateurs de Nextflow qui facilite encore plus le lancement et la gestion de vos flux de travail, ainsi que la gestion de vos données et l'exécution d'analyses interactives dans n'importe quel environnement. + +## Enquête de satisfaction + +Avant de passer à la suite, veuillez prendre une minute pour remplir l'enquête du cours ! Vos commentaires nous aident à améliorer nos supports de formation pour tout le monde. + +[Répondre à l'enquête :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/fr/docs/hello_nextflow/survey.md b/docs/fr/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..aae20703f9 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Enquête de satisfaction + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Avant de passer à la suite, veuillez remplir cette courte enquête en 5 questions pour évaluer la formation, partager vos commentaires sur votre expérience et nous faire savoir ce que nous pourrions faire d'autre pour vous aider dans votre parcours Nextflow. + +Cela devrait vous prendre moins d'une minute à compléter. Merci de nous aider à améliorer nos supports de formation pour tout le monde ! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/fr/docs/hello_nextflow/transcripts/00_orientation.md b/docs/fr/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..a5277d8ab6 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Orientation - Transcription Vidéo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importante" + + Cette page ne présente que la transcription. Pour les instructions complètes étape par étape, retournez au [matériel de formation](../00_orientation.md). + +## Bienvenue + +Bonjour, bienvenue à Hello Nextflow. Je m'appelle Phil Ewels. Je suis Chef de Produit pour l'Open Source chez Seqera, et je suis ravi d'être ici aujourd'hui pour vous guider à travers ce premier cours de formation Nextflow. + +Nous allons passer en revue les bases de Nextflow, en expliquant comment écrire et exécuter des pipelines et les configurer. + +Et vous allez construire votre propre pipeline simple à plusieurs étapes. Nous couvrirons la terminologie comme les opérateurs et les fabriques de canaux, et à la fin du cours, vous serez prêt à commencer à construire vos propres pipelines bioinformatiques. + +Si vous avez des questions, n'hésitez pas à nous contacter sur community.seqera.io. Nous avons une communauté Nextflow très active, il y a une section dédiée à la formation, alors faites-nous savoir où vous êtes bloqué et quelqu'un pourra vous aider. + +Très bien. Commençons. + +## Site Web de Formation + +Tout le matériel de formation pour les cours Nextflow se trouve sur training.nextflow.io. Vous pouvez y accéder dans votre navigateur web. Alors lancez-le maintenant et nous pouvons y jeter un œil. + +Je vais utiliser la version 2.1.1. Nous publions de petites mises à jour et corrections de temps en temps, donc ne vous inquiétez pas si c'est légèrement différent, mais si le matériel a trop dérivé, vous pouvez toujours utiliser ce sélecteur de version en haut pour choisir la version exacte des matériaux que je vais présenter. + +Si vous préférez le mode clair, vous pouvez changer le thème du site web ici. + +Voyez les traductions ici, bien qu'au moment de l'enregistrement, c'est vraiment uniquement en anglais qui couvre ce nouveau matériel. + +Et voyez également tout le code source du site web de formation et tout ce avec quoi nous allons travailler sur GitHub. + +La page d'accueil ici liste tous les différents cours de matériel de formation que nous avons. Donc si je défile vers le bas, nous verrons Nextflow pour les nouveaux venus avec le cours Hello Nextflow que nous allons faire ici. Vous pouvez voir tous les autres cours que nous avons également, qui fonctionnent de manière similaire. + +## Configuration de l'Environnement + +Je vais en fait commencer par utiliser ce premier en haut, qui est commun à tous les cours de formation, et concerne spécifiquement la configuration de notre environnement. + +Je clique dessus, cela m'amène à cette section, et nous pouvons voir les instructions pour le développement en local. Si vous voulez utiliser votre propre ordinateur portable avec votre propre copie de VS Code et vos propres installations logicielles, ou ce que nous attendons de la plupart des gens, qui est d'utiliser quelque chose appelé GitHub Codespaces. + +Codespaces est un service fourni par GitHub où ils exécutent un serveur web dans le cloud, auquel vous pouvez vous connecter. Ce serveur a VS code installé, où vous pouvez l'exécuter dans votre navigateur web, ou si vous préférez, le connecter à votre installation locale de VS code. Tous les calculs, tous les fichiers, toutes les modifications se font à distance, ce qui signifie que tous les logiciels dont vous avez besoin sont pré-installés et sont les mêmes pour tout le monde. + +## Créer un GitHub Codespace + +Pour créer le codespace avec tout ce dont nous avons besoin, cherchez les boutons dans la documentation, qui disent "Open in GitHub Codespaces". Je vais cliquer dessus maintenant, l'ouvrir dans un nouvel onglet. Et je suis présenté avec cette page web. Maintenant vous pouvez voir que c'est pré-configuré avec nextflow-io training. + +Je peux simplement cliquer sur créer un nouveau codespace. Mais en fait nous recommandons d'utiliser une machine légèrement plus grande pour la formation Nextflow avec quatre CPUs au lieu de deux. Vous pouvez changer quelle version du matériel il utilise. Donc cela utilise par défaut 2.1.1 parce que c'est la version de la documentation d'où j'ai suivi le lien. Mais je pourrais aussi le définir à une branche spécifique du dépôt si je le veux. + +Maintenant je vais cliquer sur créer un codespace. Et il va commencer à configurer l'environnement pour moi. + +## Création du Codespace + +Maintenant, la première fois que vous faites cela, cela va prendre pas mal de temps, donc c'est le bon moment pour aller prendre une tasse de thé. Installez-vous confortablement, discutez avec la personne assise à côté de vous. + +Si vous êtes intéressé, vous pouvez cliquer sur building codespace ici en bas pour voir les logs de la configuration. Et vous pouvez voir ici qu'il télécharge une image Docker avec tout ce dont j'ai besoin et configure l'environnement. + +Maintenant, vous devez seulement attendre comme ça la première fois que vous créez un codespace. Si vous allez sur github.com/codespaces ici, vous verrez tous les différents Codespaces que vous avez ouverts. Voici celui que je viens de créer. La prochaine fois que vous faites cela, vous pouvez aller ici et vous pouvez sélectionner le codespace précédent et y revenir directement. Et c'est un processus beaucoup, beaucoup plus rapide pour réchauffer cet environnement existant. Cela conservera également toutes les modifications que vous avez apportées à VS Code et aux fichiers, donc vous ne perdrez pas votre progression si vous partez et revenez. + +Vous pouvez cliquer sur les trois points ici pour effectuer d'autres actions. Par exemple, si vous l'avez configuré avec deux CPUs et maintenant vous en voulez quatre, vous pouvez changer le type de machine. Ou si vous voulez recommencer à zéro et frais, vous pouvez supprimer le codespace. + +## Introduction à VS Code + +D'accord, Codespaces a fini de configurer mon environnement et je suis maintenant présenté avec VS Code dans le navigateur web. + +Si vous êtes habitué à VS code, cela vous semblera très familier. Si vous ne l'avez pas utilisé auparavant, c'est assez simple. Il y a quelques parties différentes de la page dont vous devez être conscient. + +Ici sur la gauche, nous avons la barre latérale. Vous pouvez voir l'Explorateur configuré avec tous les différents fichiers dans le dépôt GitHub du dépôt de formation. + +Sur ces boutons en bas à gauche, peuvent être différents outils. Dans la barre latérale. Je peux rechercher tous les fichiers dans tout le projet. Je peux travailler avec Git, je peux travailler avec GitHub, toutes sortes de choses comme ça. + +En haut ici se trouve le menu principal. L'explorateur de fichiers est celui que nous aurons le plus ici, et vous pouvez faire un clic droit sur n'importe lequel de ces fichiers et faire les choses normales auxquelles vous vous attendez. Vous devrez peut-être cliquer à travers quelques avertissements comme celui-ci où il coupe copie et vous pouvez télécharger sur votre machine locale également. + +Quand le codespace se charge, il nous donne un aperçu du fichier markdown dans cette zone principale ici. C'est exactement le même que celui qui s'affiche sur github.com. Je peux fermer ça et si je double-clique sur ce fichier Readme, vous verrez qu'il l'ouvre sous forme de code dans l'éditeur de code et tout comme avec n'importe quel autre fichier, nous pouvons éditer ce code directement. + +Enfin en bas ici, nous avons la fenêtre de terminal. Je regardais les logs pendant la construction, donc c'est ce qu'elle affiche actuellement. Je peux aussi appuyer sur ce bouton plus pour démarrer une nouvelle session de terminal. Cela ne s'exécute pas sur ma machine. Rappelez-vous, cela s'exécute dans le cloud, et si je fais tree trois à une profondeur de deux, vous verrez tous les mêmes fichiers ici, qui étaient sur la gauche. + +## Afficher uniquement les fichiers "hello-nextflow" + +Ce dépôt GitHub contient tous les différents ensembles de formation, pas seulement celui que nous faisons. Donc si vous voulez, vous pouvez vous concentrer uniquement sur le dossier Hello Nextflow. Une façon de nettoyer un peu cela est d'aller dans le menu fichier puis ajouter un dossier à l'espace de travail. + +Nous cliquons dessus, allons dans training. Hello nextflow, et cliquons sur ajouter. Cela actualisera votre écran. Et puis dans l'Explorateur, nous avons maintenant deux espaces de travail différents, celui que nous avions avant pour training et un avec juste Hello Nextflow. + +Si vous voulez, vous pouvez faire un clic droit sur training et cliquer sur supprimer le dossier de l'espace de travail pour le retirer complètement de la barre latérale. + +Maintenant nous avons juste les fichiers pour ce cours de formation particulier dans la barre latérale. Je peux masquer cet avertissement et maintenant je peux faire la même chose dans le terminal ici et faire CD pour changer de répertoire. Hello, Nextflow. Et encore, nous avons les mêmes fichiers ici, qui sont dans la barre latérale. + +## Hello Nextflow : fichiers + +En regardant ces fichiers pour le cours Hello Nextflow. + +Nous avons un ensemble de fichiers .nf, qui sont pour Nextflow, et il y a un de ces fichiers pour chacun des chapitres du cours de formation. Nous allons travailler à travers ces fichiers et les modifier dans les exercices. + +Nous avons également un fichier nextflow.config, qui a juste des paramètres de configuration de base pour exécuter Nextflow dans cet environnement, dont vous n'avez pas vraiment besoin de vous soucier à ce stade. Un fichier greetings.csv, que nous utiliserons pour traiter les données, qui sera introduit dans la prochaine partie de ce cours, et un fichier test-params.json, qui sera utilisé dans la partie six et que vous pouvez ignorer pour l'instant. + +Ces fichiers Nextflow sont juste le début de chaque exercice. Si vous voulez voir à quoi ils devraient ressembler une fois terminés, vous pouvez aller dans un répertoire solutions et il y a les réponses pour chaque partie du cours de formation, donc vous pouvez voir une version fonctionnelle de ce vers quoi vous visez. + +## Ouvrir un Terminal + +Si à un moment donné vous fermez le terminal et ne vous rappelez plus comment y revenir, ne vous inquiétez pas. Ces boutons en haut à droite ouvrent et ferment différents panneaux dans l'espace de travail. Donc cliquez sur celui-ci pour le panneau du bas et il réapparaîtra. Et assurez-vous simplement que vous avez sélectionné terminal ici. Vous pouvez également cliquer sur ce bouton ici, la flèche sur le côté droit d'un terminal pour le mettre en plein écran. + +Vous me verrez faire ça assez souvent parce que j'ai VS Code zoomé pour que vous puissiez lire le texte. Selon la taille de votre écran, vous pourriez avoir besoin ou non de faire cela. Il en va de même pour minimiser le panneau latéral. + +Très bien. C'est suffisant pour l'environnement. Je pense que nous sommes prêts à commencer. Rejoignez-moi dans la prochaine vidéo pour le chapitre un. + +[Transcription vidéo suivante :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/fr/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..0a70bfa764 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Partie 1 : Hello World - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page montre uniquement la transcription. Pour des instructions complètes étape par étape, retournez au [matériel de formation](../01_hello_world.md). + + Les numéros de section affichés dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section du matériel. + +## Bienvenue + +Bonjour, bienvenue dans le Chapitre Un de Hello Nextflow. + +Dans cette première partie d'un cours en six parties, nous allons voir les bases de Nextflow. Nous allons commencer par exécuter quelques commandes dans un terminal, puis nous prendrons ces commandes Bash et verrons comment les intégrer dans un script Nextflow. + +Nous essaierons d'exécuter ce premier pipeline Nextflow, verrons ce que Nextflow fait, où il s'exécute, quels fichiers il crée, et quel est le but de ces fichiers. + +Très bien, commençons. + +## training.nextflow.io + +Tout d'abord, allez sur training.nextflow.io. Comme précédemment, tout le matériel est écrit ici, et je vais le parcourir étape par étape. Je vais montrer mon écran pendant que je fais les étapes de la formation, mais tout ce que je dis se trouve dans le matériel de formation, donc vous pouvez le suivre à votre propre rythme, et vous pouvez tout trouver écrit là. + +Cette vidéo a également des sous-titres activés, alors n'hésitez pas à les afficher et à suivre exactement ce que je dis au fur et à mesure. + +D'accord, allons à Hello Nextflow. C'est le cours que nous allons faire aujourd'hui, et nous avons déjà fait l'orientation dans la première vidéo, donc nous allons directement passer à la partie un. Hello World. + +Très bien, je vais maintenant quitter ce matériel de formation et passer à mon environnement Code Spaces. C'est ce que nous avons configuré dans la première vidéo. J'espère que vous avez quelque chose de très similaire à cela dans votre propre système. J'utilise VS Code et je regarde le matériel de formation et j'ai changé de répertoire dans le répertoire hello Nextflow. + +## 0. Échauffement : Exécuter Hello World directement + +D'accord. Commençons par quelques bases, qui devraient être familières à tout le monde. Je vais commencer par écrire une commande très basique dans le terminal. Ici en bas, je vais dire 'echo Hello World!"' appuyer sur entrée et, sans surprise, le terminal fait ce que je lui demande et renvoie cette chaîne. Hello world. + +D'accord, ensuite je vais appuyer sur la flèche du haut pour récupérer cette commande et la modifier un peu. Cette fois, redirigeons cette sortie vers un fichier. Je vais plutôt l'écrire dans output.txt et appuyer sur entrée, rien dans le terminal cette fois parce que la sortie n'est pas allée au terminal. Elle est allée dans ce fichier. + +Je peux ensuite lire ce fichier en faisant 'cat output.txt', appuyez sur tab ici pour auto-compléter le nom du fichier et voilà. Le fichier est là. + +Je peux également voir ce fichier dans la barre latérale dans l'explorateur de fichiers dans VS Code. Je peux double-cliquer dessus et l'ouvrir ici. Si vous voulez l'ouvrir dans VS Code sans rien cliquer, vous pouvez également faire "code" puis "output.txt" et cela fait la même chose. + +Parfait. C'est la première étape. Très simple. + +## 1. Examiner le script de démarrage du workflow Hello World + +D'accord. Nous allons maintenant faire exactement la même chose, mais dans Nextflow, au lieu de directement dans le terminal. + +Nous allons utiliser le premier exemple de script pour commencer, ce fichier s'appelle Hello World. Je peux faire "ls" pour le voir dans un terminal, et je suis sur Mac, donc je peux faire commande + clic pour ouvrir ce fichier, ou j'aurais pu simplement double-cliquer dans la barre latérale ici. + +Il y a quelques choses que nous pouvons voir dans ce fichier. Tout en haut, il y a une déclaration avec un dièse disant que c'est un fichier Nextflow et qu'il peut être exécuté. Il y a quelques commentaires ici, juste des commentaires de code réguliers en gris clair, qui n'affectent pas l'exécution, et aident simplement à lire le script. + +Et ensuite il y a deux structures principales. Il y a un process ici et un workflow. + +Les processes dans Nextflow sont les étapes du pipeline. Ce sont les parties qui font réellement la logique et effectuent le traitement. + +Le workflow ensuite en bas relie ces processes ensemble et gouverne la logique du workflow, comment tout se connecte les uns aux autres. + +Nous allons commencer par regarder un process. Nous reviendrons au workflow dans un moment. + +## 1.2 La définition du process + +Donc chaque process commence par un mot-clé process. Il a un nom et puis il a des accolades et tout ce qui se trouve dans ces accolades est ce process unique. + +Un process doit avoir une section script, et contenu ici est un extrait bash dans une chaîne multi-lignes, qui est la partie du code qui est réellement exécutée dans l'environnement de calcul. + +Nous avons également une déclaration output ici, qui dit à Nextflow quels fichiers sont censés être créés par le script. Notez que l'output ici a un mot-clé path, qui dit à Nextflow que c'est un fichier, pas une valeur, ou une chaîne. + +Dans le bloc script, c'est juste une déclaration bash régulière, et c'est exactement la même que ce que nous avons écrit dans le terminal. Nous faisons echo de hello world vers un fichier appelé output.txt. Ce output.txt est ensuite récupéré par la définition output. La définition output ne fait rien en réalité. Elle dit juste à Nextflow quoi s'attendre, et si ce fichier n'était pas créé, Nextflow lancerait une erreur. + +Notez que cet exemple n'est pas excellent parce que nous avons codé en dur le nom du fichier ici, output.txt et output.txt. Si l'un de ceux-ci était changé, cela causerait une erreur dans notre workflow. + +Il y a une meilleure façon de faire cela avec des variables, que nous couvrirons dans une minute. + +## 1.3 La définition du workflow + +D'accord. En descendant au workflow, nous pouvons voir que nous avons un commentaire et ensuite nous exécutons le process appelé sayHello. C'est le même mot-clé qui est ici en haut. C'est à peu près aussi simple qu'un workflow peut être. Nous appelons juste un seul process sans entrée variable, donc nous ne le connectons à rien d'autre. Dans la partie suivante de ce cours, nous parlerons de comment rendre cela plus puissant en utilisant des entrées variables et en connectant des choses avec des channels. + +## 2. Exécuter le workflow + +D'accord, c'est tout ce dont nous avons besoin. Voyons si nous pouvons l'exécuter et voir ce qui se passe. Je vais juste effacer le terminal et ensuite je vais faire "nextflow run", et je vais appeler le nom du fichier, qui est hello-world.nf. C'est tout ce dont nous avons besoin pour exécuter un pipeline Nextflow. Ce pipeline ne prend pas d'entrée, donc nous n'avons pas besoin d'autres arguments. + +Appuyons sur entrée et voyons ce qui se passe. + +D'accord. J'espère que vous devriez avoir une sortie qui ressemble à ceci. Nous avons quelques informations nous disant que Nextflow s'est exécuté et quelle version il utilisait. Il nous dit quel script a été lancé et il nous donne un nom généré aléatoirement pour cette exécution de workflow particulière. Dans ce cas, le mien s'appelait "gloomy_crick". + +La partie la plus importante de ceci cependant, c'est qu'il nous dit quelles étapes se sont exécutées dans le pipeline. Vous pouvez voir que notre process appelé sayHello s'est exécuté, et il s'est exécuté une fois et il était complet à cent pour cent. + +Cette partie ici est le hash pour cette tâche de workflow particulière. Chaque process s'exécute une ou plusieurs fois, et chacune de ces exécutions est appelée une tâche. + +## 2.2. Trouver la sortie et les logs dans le répertoire work + +Chaque tâche obtient son propre répertoire isolé où elle s'exécute, donc elle est séparée du reste de l'exécution du workflow. Ce hash correspond à la structure de fichiers dans le répertoire work. Si je fais "tree work", nous pouvons voir a0, puis une version plus longue d'un hash court, puis notre fichier output.txt. Vous pouvez également le voir dans la barre latérale. + +Vous pouvez voir dans la barre latérale qu'il y a quelques fichiers supplémentaires ici. La raison pour laquelle ceux-ci n'apparaissent pas dans le terminal est qu'ils sont des fichiers cachés, ils commencent par un point. Et en effet, si je fais "tree -a" pour all, et "work", nous pouvons les voir ici. + +Ces fichiers dot sont présents dans chaque répertoire work que Nextflow crée, et chacun a une tâche légèrement différente. Premièrement .command.begin inclut juste quelques instructions pour Nextflow qui configure la tâche avant qu'elle ne s'exécute. .command.run sont les instructions réelles exécutées par Nextflow lui-même. Ensuite .command.sh est probablement le plus intéressant. C'est le script qui a été résolu à partir de notre bloc script du process. + +Si je l'ouvre, vous pouvez voir que nous avons notre "echo Hello World" vers le fichier output.txt. C'est exactement la même chose que notre process dans ce cas, mais si nous avons des variables dans notre code Nextflow, chaque tâche aura un .command.sh différent, et vous pouvez voir comment ces variables ont été résolues. + +Les autres fichiers ont à voir avec comment la tâche s'est exécutée. Donc .command.err, .log et .out sont l'erreur standard, la sortie standard et les deux combinés. Et .exitcode dit à Nextflow comment cette tâche s'est exécutée avec quel code de sortie, si elle a réussi ou non. + +Enfin, nous avons notre fichier output.txt et effectivement, "Hello World", c'est ce que nous attendions et c'est ce qui a été créé. + +D'accord, parfait. C'était votre toute première exécution Nextflow. Félicitations. C'est vraiment aussi simple que cela. + +Ensuite, nous allons voir comment faire cela un peu plus facilement pour ne pas avoir à éditer le code chaque fois que nous voulons faire un changement dans la façon dont le pipeline s'exécute. + +## 3. Gérer les exécutions de workflow + +Cette structure de répertoires est excellente pour garder toutes les tâches séparées et tout organisé, mais bien sûr, ce n'est pas très pratique pour trouver vos fichiers de sortie. Vous ne voulez pas fouiller dans des tas de répertoires imbriqués pour essayer de trouver les résultats de votre pipeline. + +## 3.1. Publier les sorties + +La bonne nouvelle est que vous n'êtes pas censé le faire. Les répertoires work sont vraiment juste pour que Nextflow les utilise lui-même. Donc ce que nous allons faire, c'est que nous allons utiliser une fonction de Nextflow appelée "publishDir". + +Nous retournons à notre workflow, allons au process. Nous pouvons ajouter une nouvelle déclaration ici appelée une directive. C'est ainsi que Nextflow appelle ces choses en haut des processes qui augmentent le fonctionnement, et celle que nous allons utiliser s'appelle publishDir. + +Vous pouvez voir que j'ai commencé à taper ici et l'extension Nextflow pour VS Code m'a suggéré la directive, donc je peux juste appuyer sur entrée. + +D'accord, je vais suivre cela avec un répertoire appelé "results" et nous allons lui dire de copier les fichiers de sortie là. Donc je vais dire mode copy. Parfait. Je vais sauvegarder et exécutons le workflow à nouveau. + +nextflow run hello-world.nf + +Il s'exécute exactement de la même manière. Bien que notez que nous avons un hash légèrement différent cette fois. Nextflow utilisera un hash différent à chaque fois que vous exécutez le workflow. Et nous avons un ensemble différent de répertoires work en conséquence. Les zones, l'une s'appelle EB à la place, mais vous pouvez voir que tous les fichiers sont les mêmes. Cependant, ce qui est nouveau cette fois, c'est que nous avons également un répertoire appelé "results". + +Dans "results" ici, nous avons notre fichier de sortie. C'est ce que nous avons dit à Nextflow de faire. Nous avons dit, enregistrez les fichiers de résultats dans un répertoire appelé "results" et copiez-les là. Et donc c'est maintenant beaucoup plus facile à trouver. C'est juste là à côté de l'endroit où nous avons lancé le workflow et tous les différents fichiers peuvent y être organisés comme nous le souhaitons, indépendamment de où ou comment Nextflow a exécuté l'exécution réelle. + +Notez que publishDir peut gérer les liens symboliques, ce qui est bien si vous travaillez sur un système de fichiers partagé et que vous voulez économiser de l'espace. Et aussi vous n'avez pas à définir tous les fichiers qui sont créés par un process comme une sortie. + +Nextflow copiera uniquement les choses qui sont définies dans ce bloc output. Donc si vous avez des fichiers intermédiaires créés par l'étape, qui ne sont pas nécessaires en aval de ce process, vous ne les définissez simplement pas dans output et ils n'apparaîtront pas dans le publishDir. Donc c'est une façon de garder vos fichiers de sortie d'un pipeline propres et de supprimer facilement les fichiers intermédiaires une fois le travail terminé. + +Une petite note ici. Il y a une nouvelle syntaxe Nextflow qui arrive appelée workflow output definitions, qui remplacera éventuellement publishDir. Cela nous donne un moyen de définir toutes les sorties d'un workflow au niveau du pipeline dans le bloc workflow. Ceci est décrit dans les docs Nextflow si vous voulez l'essayer. Mais pour l'instant, publishDir sera encore là pendant un moment, donc nous l'avons toujours dans la formation pour 2025. + +## 3.2. Relancer un workflow avec -resume + +D'accord. J'ai mentionné que le répertoire work ici a maintenant deux ensembles de résultats avec un hash différent de chaque fois que nous exécutons le workflow. C'est bien. Cependant, parfois nous ne voulons pas recalculer les étapes à chaque fois si nous n'en avons pas besoin. + +Peut-être que vous êtes en train de construire itérativement votre workflow et vous ajoutez des étapes et vous voulez que les premières étapes réutilisent simplement les versions mises en cache. Ou peut-être que quelque chose s'est mal passé sur votre système de calcul à mi-chemin de votre workflow et vous voulez qu'il continue à partir de là où il s'est arrêté, mais saute les étapes qu'il avait déjà terminées. + +Nextflow a une fonctionnalité intégrée pour cela appelée resume. Essayons-le. Donc tout d'abord, je vais juste regarder le répertoire work pour que nous puissions nous rappeler ce qui était là. + +Et ensuite je vais faire "nextflow run hello-world.nf" et je vais ajouter une seule commande ici, "-resume". + +Notez, un seul tiret, c'est vraiment important. Je vais l'exécuter et la sortie va ressembler essentiellement exactement à la même chose, avec quelques petites différences. + +Notez ici qu'il dit "cached" en gris. Cela signifie que Nextflow n'a pas exécuté la tâche. Cette fois, il a trouvé quelque chose qui correspondait à ce que nous demandions et il a réutilisé ces sorties directement plutôt que de réexécuter l'étape. + +Et effectivement, si vous regardez le hash ici, vous pouvez voir que cela correspond au hash existant que nous avions d'une exécution précédente. + +## 3.3. Supprimer les anciens répertoires work + +D'accord. Mais si vous développez de manière itérative, vous allez accumuler beaucoup de ces fichiers de workflow. Cela peut être un problème si vous manquez d'espace. + +Nextflow peut nous aider à nettoyer ces répertoires work avec quelques commandes d'aide. Si je fais "nextflow log". Cela me donnera une liste de toutes les différentes exécutions de workflow que j'ai faites dans ce répertoire, et elles ont les noms d'exécution ici. Vous pouvez voir le gloomy quick, qui était le premier que nous avons exécuté, puis ces deux nouveaux. + +Nous pouvons maintenant prendre ce nom et les utiliser avec la commande "nextflow clean". Je peux spécifier un seul nom d'exécution. Ou encore mieux, je peux dire à Nextflow de supprimer tout ce qui se trouve avant un seul nom de workflow avec "-before", et je vais mettre "stupefied_shaw". C'était ma dernière exécution, "-n". + +La commande "-n" a dit à Nextflow de le faire comme un dry run sans réellement supprimer quoi que ce soit pour de vrai, et il nous dit lesquels des répertoires hash auraient été supprimés. Effectivement, c'est juste celui de la première exécution. Les deux secondes exécutions utilisent le même répertoire hash. + +Je vais l'exécuter à nouveau, mais maintenant au lieu de "-n" pour dry run, je vais faire "-f" pour force et il a supprimé ce répertoire hash. Maintenant si je fais "tree work", nous pouvons voir, nous avons juste ce fichier de sortie restant. + +Parfait. Donc nous avons réussi à nettoyer beaucoup d'espace disque là. + +Quelques points à noter lors de la suppression de répertoires work, si vous faites des liens symboliques vers votre répertoire results, ces sources de liens symboliques seront maintenant supprimées et vos résultats seront perdus pour toujours. C'est pourquoi utiliser le mode copy est une chose plus sûre à faire, et généralement ce que nous recommandons. + +Deuxièmement, la fonctionnalité resume de Nextflow repose sur ces répertoires work. Donc si vous les supprimez et que vous exécutez Nextflow à nouveau, la fonctionnalité resume ne fonctionnera plus. Donc c'est à vous de garder une trace de quelles choses vous pourriez avoir besoin ou non, et de supprimer uniquement les choses lorsque vous êtes sûr qu'il est sûr de le faire. + +L'autre chose que nous pouvons faire est que nous pouvons simplement supprimer l'ensemble du répertoire work si nous avons terminé notre exécution de workflow et que nous sommes sûrs que nous n'en avons plus besoin. + +Donc je peux faire "rm -r work". Je sais qu'il n'y avait rien d'important là-dedans. J'ai mes résultats qui m'intéressent dans le répertoire results où nous les avons copiés. Et donc il était sûr de supprimer le répertoire work. C'est à vous de décider laquelle de ces approches vous utilisez. + +## 4. Utiliser une entrée variable passée sur la ligne de commande + +D'accord, et ensuite ? J'ai mentionné que nous avions codé en dur certaines des valeurs dans notre script de workflow ici, le fichier output.txt, et qu'il pourrait y avoir une meilleure façon de faire cela. + +Commençons par cela. Ce que nous allons faire, c'est trois choses. Nous allons ajouter une nouvelle entrée au process. Nous allons dire au script du process comment utiliser cette entrée, puis nous allons le câbler dans le workflow afin que nous puissions l'utiliser dynamiquement avec un flag de ligne de commande lors de l'exécution de Nextflow. + +Donc tout d'abord. Ajoutons un bloc input ici. Tout comme output. C'est une nouvelle section pour le process, et je vais dire, "val greeting". + +Notez ici, je dis "val", ce qui dit que c'est une variable, pas un path. + +Je peux ensuite descendre dans le script et ensuite je peux retirer ce texte codé en dur ici et faire $greeting. Cela fonctionne comme n'importe quel autre langage de programmation. Nous définissons une variable ici et nous la référençons dans ce bloc script. Lorsque Nextflow exécute ce process, la variable sera interpolée. Et lorsque nous irons regarder ce fichier .command.sh, nous verrons la chaîne réelle codée en dur ici à la place. + +## 4.1.3. Configurer un paramètre CLI et le fournir comme entrée à l'appel du process + +D'accord, mais où fournissons-nous la variable ? Ensuite, nous descendons à la section workflow, et vous pouvez voir que l'extension ici dit que nous attendons maintenant une entrée, et elle m'a donné un avertissement. + +Maintenant, la chose la plus simple que nous pourrions faire est simplement de la coder en dur. Je pourrais écrire "Hello World" et fournir cette entrée de chaîne au process. Mais encore une fois, cela ne résoudrait pas vraiment de problèmes. Nous devrions toujours retourner et éditer le code du pipeline chaque fois que nous voudrions changer quelque chose, ce qui n'est pas bon. + +La bonne nouvelle est que Nextflow a un système intégré pour gérer les arguments de ligne de commande appelé paramètres. Donc à la place, je peux utiliser l'une de ces variables spéciales appelées params et je peux l'appeler comme je veux, mais je vais dire greeting pour qu'elle corresponde à la logique du workflow. + +Sauvegardons et voyons ce que nous pouvons faire avec cela. + +Donc si je retourne au terminal. Donc nous faisons "nextflow run hello-world.nf". Juste comme avant, mais la différence clé est que nous faisons --greeting + +Notez, il y a deux tirets ici parce que c'est un paramètre. Quand nous avons repris le workflow avant, c'était un seul tiret. C'est parce que resume est une option Nextflow de base, et ceci est un paramètre qui est spécifique à notre pipeline. + +Ne confondez pas les deux. C'est facile de faire cela. Si vous faisiez --resume au lieu d'un seul tiret, alors ce serait "params.resume", ce qui ne ferait rien. De même, si vous faisiez un seul tiret ici, Nextflow ne le reconnaîtrait pas comme un argument clé. + +Donc c'est --greeting, qui correspond à params.greeting. + +Je peux maintenant suivre cela avec n'importe quel texte que je veux. Donc je suis en Suède en ce moment, donc je vais dire, "Hej världen". + +Donc exécutons-le, voyons ce qui se passe, moment de vérité. + +D'accord, donc vous pouvez voir que le process s'est à nouveau exécuté, juste comme avant, sayHello avec une seule exécution. + +Cela aura écrasé le fichier qui était dans le répertoire publishDir "results". Donc soyez prudent lorsque vous réexécutez les fichiers car les choses dans le répertoire publié seront écrasées. + +Je peux maintenant faire "code results/output.txt", et effectivement, notre sortie a été mise à jour et dit maintenant "Hej världen". + +## 4.2. Utiliser des valeurs par défaut pour les paramètres de ligne de commande + +D'accord, c'est super. Mais le problème maintenant est que notre workflow repose sur nous définissant toujours ce paramètre, et c'est bien d'avoir des valeurs par défaut sensées pour que les choses s'exécutent de manière sensée pour votre workflow à moins que vous ne remplaciez les valeurs par défaut. + +Donc la façon dont nous faisons cela est en définissant une valeur par défaut pour le paramètre dans notre script de workflow. + +Donc si je retourne à mon fichier hello-world.nf, je peux aller dans le script juste au-dessus du workflow, taper "params.greeting" et le définir comme n'importe quelle autre variable. Donc mettons une chaîne ici et disons "Holà mundo!" + +Maintenant ce paramètre a une valeur par défaut définie, qui sera utilisée ici, ou nous pouvons toujours la remplacer sur la ligne de commande avec --greeting, exactement comme nous l'avons fait avant. + +Donc vérifions que ça fonctionne. "nextflow run hello-world.nf" + +Pas d'arguments de ligne de commande cette fois, et vérifions si cela a fait la bonne chose. + +"code results/output.txt". Et voilà. Nous avons notre valeur par défaut. + +D'accord, essayons à nouveau, vérifions juste que je ne vous raconte pas de mensonges. Exécutons-le à nouveau, mais faisons --greeting, et utilisons l'exemple du matériel de formation, disons "Konnichiwa!" + +Réexécute le workflow, et effectivement, notre fichier de sortie en haut vient d'être mis à jour avec la nouvelle valeur que nous avons fournie sur la ligne de commande. + +Parfait. C'est un aspect vraiment central pour écrire n'importe quel workflow Nextflow. Définir des valeurs par défaut sensées dans votre code de pipeline, mais le rendre très facile à configurer pour l'utilisateur final en ayant des arguments de ligne de commande sur le terminal. + +Notez que l'utilisateur final peut remplacer la configuration à plusieurs endroits différents. Vous pouvez avoir un fichier de configuration dans votre répertoire personnel, qui est appliqué à chaque exécution Nextflow que vous faites. Vous pouvez avoir un fichier de configuration dans un répertoire de lancement. Vous pouvez avoir un fichier de configuration dans un répertoire de pipeline. Tous ces différents emplacements de configuration sont chargés dans un ordre spécifique, qui est décrit dans les docs Nextflow. + +D'accord, c'est la fin de la section un. Nous avons eu notre tout premier script de workflow dans Nextflow avec un process et un workflow. Nous avons examiné les entrées, les sorties, les scripts et la publication, et comment câbler les paramètres et un canal d'entrée dans notre process. + +Félicitations, votre premier pas vers l'écriture de code Nextflow est terminé. + +Faites une petite pause et je vous verrai de retour dans quelques minutes pour le chapitre deux. + +[Transcription de la vidéo suivante :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/fr/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..a0e7d413da --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Partie 2 : Hello Channels - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page affiche uniquement la transcription. Pour des instructions complètes étape par étape, retournez au [matériel de formation](../02_hello_channels.md). + + Les numéros de section affichés dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section dans les matériels. + +## Bienvenue + +Bonjour, bienvenue dans la partie deux de Hello Nextflow. + +Ce chapitre s'appelle Hello Channels. Nous allons parler de cette partie fondamentale de Nextflow. + +Les channels sont les éléments qui connectent les différentes étapes de votre pipeline, la façon dont vos données et votre logique circulent à travers votre workflow. + +D'accord, plongeons-nous dedans. + +Commençons par aller sur training.nextflow.io + +Hello Nextflow dans la barre latérale et cliquons sur la partie deux, Hello Channels. + +Tout le matériel est écrit ici, vous pouvez donc suivre à votre propre rythme et rattraper tout ce que vous auriez pu manquer. + +Une fois que vous avez ouvert le site web, vous pouvez charger Codespaces et nous continuerons là où nous en étions à la fin du dernier chapitre. + +## 0. Échauffement : Exécuter hello-channels.nf + +Pour ce chapitre, nous allons éditer un fichier différent. Celui-ci s'appelle Hello Channels, vous pouvez donc le trouver dans la barre latérale, double-cliquez dessus pour l'ouvrir. + +Maintenant, si vous venez juste du chapitre un, ce fichier vous semblera très familier. Le point de départ ici est essentiellement là où nous avons terminé le chapitre un, avec notre process appelé sayHello, notre entrée, sortie, notre publishDir et notre params.greeting, et notre workflow simple. + +Nous commençons avec un nouveau fichier, c'est donc un terrain de jeu équitable pour tout le monde, mais vous pouvez continuer avec votre fichier précédent si vous préférez. + +Notez que j'ai également supprimé tous les fichiers .nextflow\* et les répertoires work ici, juste pour avoir un point de départ propre. Peu importe si vous le faites ou non, c'est à vous de décider. + +D'accord. Commençons par vérifier que ce pipeline fonctionne toujours comme nous l'attendons. Je vais ouvrir le terminal ici. + +Faites "nextflow run hello-channels.nf" et appuyez sur entrée. + +Il va exécuter ce petit workflow, exécute notre étape sayHello, génère un répertoire work avec ce hash, et voici notre répertoire results et voilà notre fichier de sortie, exactement comme nous l'attendions de notre params.greeting par défaut. + +C'est donc excellent. Exactement pareil que le chapitre un, fonctionnant comme nous l'attendons. + +## 1. Fournir des entrées variables via un channel explicitement + +Dans le chapitre un, vous utilisiez déjà des channels, vous ne le réalisiez simplement pas. Lorsque nous avons spécifié une chaîne de caractères ici, Nextflow a automatiquement créé un channel autour de cette chaîne pour nous, simplement parce qu'il savait que nous appelions un process, donc nous avions besoin d'un channel d'entrée. + +La première chose que nous allons faire est de le rendre explicite en écrivant réellement le channel lui-même. + +## 1.1. Créer un channel d'entrée + +Je vais donc aller dans le workflow ici en bas du script, et je vais dire greeting_ch. C'est une convention que nous utilisons souvent dans le code Nextflow d'avoir un underscore ch à la fin d'un nom de variable lorsqu'il s'agit d'un channel, juste pour qu'il soit facile d'identifier que c'est un channel, mais vous n'êtes pas obligé de le faire. Égale channel of Hello Channels. + +Ce que nous venons d'utiliser s'appelle une "Channel Factory" dans le langage Nextflow. C'est cette chose ici, nous définissons cette variable à un nouveau channel, et cette channel factory ici crée un channel pour nous d'une manière particulière. + +Il existe une poignée de channel factories différentes que Nextflow possède, pour créer des channels à partir de différents types d'entrées. Dot of est la plus simple, et prend simplement toutes les chaînes de caractères que nous lui donnons. + +Notez que lorsque je survole ces mots dans VS Code, l'extension Nextflow me donne une fenêtre contextuelle expliquant ce que fait cette syntaxe, et il y a également un texte lire la suite en bas de cette fenêtre contextuelle. + +Si je clique dessus, cela ouvrira la documentation Nextflow dans un nouvel onglet et m'amènera directement à la documentation pour cette chose spécifique. Dans ce cas pour channel.of. + +## 1.2. Ajouter le channel comme entrée à l'appel du process + +Notez que l'extension nous donne également un avertissement, disant que nous avons créé un nouveau channel ici, mais qu'il n'est utilisé par rien. + +Alors, réglons ça. Je vais prendre le nouveau nom de channel et je vais remplacer ce params.greeting par notre nouveau channel. + +Notez que nous n'utilisons plus le drapeau de ligne de commande --greeting maintenant, params.greeting n'est plus utilisé, nous revenons à coder en dur cette chaîne. Ce n'est pas grave. J'essaie juste de garder les choses simples. Nous reviendrons plus tard et utiliserons les params à nouveau. + +## 1.3. Exécuter à nouveau la commande workflow + +D'accord, vérifions juste que cela fonctionne. Ouvrons le terminal et notons à nouveau. Nextflow run hello channels. Vérifiez output.txt, et le voilà. + +Excellent, un peu un exemple ennuyeux, faisant exactement la même chose que nous avons fait avant, mais maintenant au moins la logique est un peu plus claire. Nous sommes explicites sur l'écriture d'un nouveau channel. + +Nous avons effectivement juste écrit plus de code pour faire la même chose. Mais cela commencera à avoir plus de sens alors que nous devenons un peu plus compliqués avec la façon dont nous créons nos channels. + +## 2. Modifier le workflow pour s'exécuter sur plusieurs valeurs d'entrée + +D'accord, rendons cela un peu plus intéressant. Il est très rare que vous souhaitiez exécuter un pipeline Nextflow sur une seule entrée, alors donnons-lui plusieurs entrées. + +## 2.1. Charger plusieurs salutations dans le channel d'entrée + +Depuis la documentation ici, je vais copier ces différentes chaînes de caractères, trois d'entre elles. Hello, Bonjour, Olà. Oh, j'espère que Copilot en suggère quelques autres. Alors appuyons sur tab pour entrer celles-ci. + +La documentation Nextflow ici nous dit que nous pouvons donner plusieurs valeurs à cet opérateur, donc cela devrait fonctionner, mais essayons-le et voyons ce qui se passe. + +## 2.1.2. Exécuter la commande et regarder la sortie du journal + +Eh bien. Oui et non. Voyons voir. Il dit que cinq des cinq tâches ont été exécutées ici, mais il ne nous montre qu'un seul hash, ce qui est un peu étrange. Ce n'est pas grave. Tout est comme prévu ici. Par défaut, Nextflow utilise un type spécial de sortie vers le terminal appelé codes de contrôle ANSI, ce qui signifie qu'il écrase certaines lignes pour donner une vue compressée agréable de tous les différents processes qui sont exécutés. + +Cela a beaucoup plus de sens lorsque vous avez des workflows plus importants et exécutez des centaines ou des milliers d'échantillons différents. Vous pouvez simplement générer tellement de sortie sur le terminal, c'est impossible à regarder, alors que cette vue de mise à jour vous donne une progression en temps réel. + +## 2.1.3. Exécuter à nouveau la commande avec l'option -ansi-log false + +Si vous le souhaitez, vous pouvez l'exécuter à nouveau, et cette fois je vais utiliser un argument de base Nextflow supplémentaire avec un seul trait d'union disant, "-ansi-log false". Cela utilise la version précédente de la sortie du journal Nextflow. Et ici vous pouvez voir tous les processes individuels qui ont été lancés. + +C'est à vous de décider si vous faites cela ou non. La sortie de Nextflow est exactement la même dans les deux cas. + +## 2.2. Assurer que les noms de fichiers de sortie seront uniques + +D'accord, jetons un coup d'œil aux fichiers de sortie, puis nous irons dans results. Mais il n'y a qu'un seul fichier de sortie. Que s'est-il passé ? Nous avons vu que le process avait été exécuté plusieurs fois. Nous pouvons aller dans le répertoire work et voir tous les différents hashs, toutes les tâches ont été exécutées correctement. Mais si vous vous souvenez dans notre process ici, nous sauvegardons tout dans un fichier output.txt et ensuite nous publions cela dans ce répertoire. + +Donc le même fichier a été créé cinq fois, puis il a été écrasé cinq fois. Et nous avons juste quelle que soit la tâche qui s'est exécutée en dernier. + +## 2.2.1. Construire un nom de fichier de sortie dynamique + +La façon dont nous résolvons cela est d'utiliser un nom de fichier de sortie dynamique. Ici nous avons déjà une variable appelée greeting dans le process, nous pouvons donc l'utiliser dans le nom du fichier de sortie. Je copie cela et je fais $greeting-output.txt. + +Je vais entourer cela de guillemets, juste pour que bash ne soit pas confus par des espaces qui pourraient se glisser ici. Et ensuite je vais prendre le même nom de fichier et mettre à jour la sortie ici. + +C'est vraiment important que la sortie corresponde à cela, parce que sinon, ce fichier ne sera pas trouvé et Nextflow plantera. + +Je vais faire une autre modification vraiment importante, qui est que je vais changer ces guillemets simples pour des guillemets doubles. Notez que la couleur du code a changé lorsque j'ai fait cela. Cette variable n'est développée que si nous utilisons des guillemets doubles. Si j'utilise des guillemets simples ici, elle est utilisée comme valeur littérale, et j'obtiendrais un seul fichier appelé $greeting-output, ce qui n'est pas ce que je veux. + +## 2.2.2. Exécuter le workflow + +Alors remettons les guillemets doubles et essayons. + +Je vais juste nettoyer mon répertoire avant de commencer, pour qu'il soit facile de voir les nouveaux fichiers. Je vais supprimer tout ce qui s'appelle .nextflow, work, et results. + +Et je vais exécuter cette commande Nextflow à nouveau et voyons quels fichiers sont créés. Donc il exécute les cinq processes là. Si vous regardiez très attentivement, vous auriez pu voir cette ligne se mettre à jour pendant l'exécution. + +Et maintenant nous pouvons aller dans le répertoire results, et effectivement, nous avons cinq sorties différentes, et elles sont toutes préfixées avec la différente salutation. + +Si j'ouvre chacune d'elles, nous verrons qu'elles contiennent chacune la salutation correspondante. Fantastique. C'est ce que nous voulons. + +## 3. Utiliser un opérateur pour transformer le contenu d'un channel + +D'accord, donc maintenant nous savons ce que sont les channels et nous savons ce que sont les channel factories. Qu'en est-il des opérateurs ? C'est un autre terme pour une partie du langage Nextflow, qui est une série de fonctions qui nous permettent d'opérer sur les channels pour leur faire certaines choses. Nextflow, vient avec une suite d'opérateurs, qui nous permettent de manipuler les channels de diverses manières différentes. + +## 3.1. Fournir un tableau de valeurs comme entrée au channel + +Travaillons à travers ceci avec un exemple. Disons que nous voulons prendre ces chaînes d'entrée, mais au lieu de les mettre directement dans une channel factory, nous voulons les définir comme un tableau. + +## 3.1.1. Configurer la variable d'entrée + +Je vais donc prendre celles-ci et faire cela comme une nouvelle ligne au-dessus et dire, greetings, array. + +Voilà. Je vais prendre cette variable de tableau et la mettre dans le channel.of, et appuyer sur sauvegarder. + +## 3.1.3. Exécuter le workflow + +Maintenant, voyons ce qui se passe. Retournons à mon terminal. Je vais juste nettoyer tous ces fichiers temporaires à nouveau. Et exécutons le workflow. + +Pas bon. D'accord. Il a planté. Ce n'est pas grave. Je m'attendais à ce qu'il plante cette fois. Déboguer ce qui ne va pas lorsqu'un workflow Nextflow échoue est une partie clé d'être un développeur Nextflow. Cela arrivera beaucoup et il est important de comprendre ce que dit le message d'erreur et comment y faire face. + +Les messages d'erreur Nextflow sont en fait assez structurés. Il nous dit quel process s'est mal passé. Il nous donne un message d'erreur pour une raison. Il dit quelle était la commande qu'il a essayé d'exécuter dans cette tâche particulière, quel était le statut de sortie, quelle était la sortie et où était le répertoire work de cette tâche. + +Notez que je peux option-cliquer dessus dans VS Code et cela l'ouvre dans une barre latérale pour que je puisse y aller directement et voir tous ces fichiers cachés, dont nous avons parlé dans le chapitre précédent, y compris le fichier .command.sh. Vous pouvez voir que c'est le même que les commandes qui ont été exécutées ici. + +En regardant ce fichier, nous pouvons avoir une idée de ce qui aurait pu mal tourner ici au lieu d'exécuter une seule tâche pour chaque élément du tableau comme il l'a fait la dernière fois, il a juste fourni le tableau entier en une seule fois comme une chaîne. Nous devons donc déballer ce tableau en valeurs individuelles avant de le passer dans le channel. Retournons en arrière et voyons si nous pouvons faire cela en utilisant un opérateur. + +## 3.2. Utiliser un opérateur pour transformer le contenu du channel + +Dans ce cas, nous n'allons pas changer le tableau avant de le passer dans le channel. Nous allons ajuster le channel pour qu'il se comporte de la manière que nous attendons. Nous allons faire cela en utilisant l'opérateur flatten peut faire dot commencer à taper et nous pouvons voir que l'extension VS Code commence à suggérer tous les différents opérateurs que nous avons disponibles. + +## 3.2.1. Ajouter l'opérateur flatten() + +Et je vais sélectionner flatten. Notez que l'espace blanc n'a pas d'importance dans ce contexte pour Nextflow. Vous pouvez donc mettre ces opérateurs sur une nouvelle ligne si vous le souhaitez. Je peux donc faire descendre cela ici et l'indenter pour qu'il se situe sous ".of" et vous verrez que les gens enchaînent souvent beaucoup d'opérateurs comme ceci sur un channel et l'indentent de cette façon pour qu'il soit plus facile à lire. + +Vous pouvez également voir, comme avant, je peux survoler cela et lire ce que fait l'opérateur flatten, et aussi suivre un lien vers la documentation si je le souhaite. + +Donc cet opérateur prend ce channel, qui a un seul tableau dedans, et sépare les valeurs du tableau. + +## 3.2.2. Ajouter view() pour inspecter le contenu du channel + +Nous pouvons jeter un coup d'œil dans les channels en utilisant l'opérateur spécial view, et je vais en ajouter quelques-uns ici. C'est un peu comme utiliser des instructions print dans d'autres langages. Je vais donc faire dot view et ensuite je vais utiliser ces accolades. + +Ceci s'appelle une closure. Cela donne essentiellement du code supplémentaire à l'opérateur view, qu'il exécutera sur chaque élément dans le channel. Dans ce cas, je vais dire greeting before flatten. Greeting. + +Je définis une variable ici, qui n'est que dans la portée de cette closure. Donc cette variable n'est utilisée qu'ici et je pourrais l'appeler comme je le veux. Peu importe vraiment. J'utilise juste greeting pour le rendre facile à lire. + +Dans certains pipelines Nextflow, vous pourriez voir des gens utiliser une variable implicite spéciale appelée "$it". Comme ça. C'est une variable spéciale dans le code Nextflow, qui est un raccourci pour que vous n'ayez pas à faire la petite définition d'une variable. Cependant, au fil du temps, nous pensons que ce n'est pas très clair pour les personnes qui sont nouvelles à Nextflow, et nous décourageons l'utilisation de "$it" maintenant. + +Je vais donc m'en tenir au comportement précédent de greeting et l'utiliser comme ceci parce que c'est plus explicite et c'est plus clair sur ce qui se passe. + +Je vais ensuite copier cette ligne et faire exactement la même chose à nouveau après les arguments flatten. L'opérateur view est un peu spécial parce qu'il fait quelque chose sur les éléments, mais il continue également simplement à les passer au prochain opérateur pour que nous puissions l'enchaîner au milieu d'une chaîne d'opérations comme ceci, et il imprimera l'état là et continuera. J'espère donc que cela nous montrera à quoi ressemble le channel avant et après l'opérateur flatten. + +## 3.2.3. Exécuter le workflow + +Essayons-le. Nettoyer. Nettoyer tout dans l'espace de travail. Exécuter à nouveau le pipeline. + +D'accord, nous pouvons voir qu'il a exécuté nos cinq processes. Encore une fois, il n'a pas planté avec une erreur, c'est donc définitivement bon. Et maintenant nous avons le before flatten et effectivement nous avons notre tableau et nous avons after flatten, imprimé cinq fois une fois pour chaque élément du tableau. C'est exactement ce que nous espérions. C'est donc vraiment une bonne nouvelle. Et cela correspond exactement à ce que nous attendrions du code. + +Nous n'avons plus besoin de ces instructions de débogage, je peux donc soit les commenter soit les supprimer. Je vais les supprimer juste pour garder mon code propre et net. D'accord, super. Cet exemple fonctionne maintenant bien et nous pouvons commencer à voir comment les channels peuvent faire une logique un peu plus compliquée. + +## 4. Utiliser un opérateur pour analyser les valeurs d'entrée à partir d'un fichier CSV + +Maintenant nous allons essayer de faire cela en utilisant un fichier avec une série d'entrées à la place. C'est une façon très courante d'écrire des pipelines Nextflow en utilisant une feuille d'échantillons ou un CSV de métadonnées. + +## 4.1. Modifier le script pour attendre un fichier CSV comme source de salutations + +Si je vais dans la barre latérale, vous pouvez voir greetings.csv dans le dépôt d'exemples, et c'est un fichier CSV très, très simple qui contient juste trois lignes avec trois salutations différentes. Voyons si nous pouvons utiliser ce fichier CSV dans notre workflow. + +Je vais maintenant revenir à l'utilisation de params comme nous l'avons fait dans le chapitre un, pour que nous puissions avoir une entrée en ligne de commande. + +Je vais supprimer ce tableau greetings. + +## 4.1.1. Changer le paramètre d'entrée pour pointer vers le fichier CSV + +Je vais définir params greeting au nom de fichier, qui est greetings.csv, et je vais utiliser cette variable spéciale pour générer le channel. Je vais mettre ça là-dedans, et les erreurs disparaissent. Rappelez-vous que cela définit cette variable par défaut maintenant. Donc si j'exécute le pipeline sans aucun argument, il utilisera greetings.csv, mais je pourrais faire --greeting pour écraser cette variable si je le voulais. + +## 4.1.2. Changer pour une channel factory conçue pour gérer un fichier + +D'accord, nous passons maintenant un fichier plutôt qu'une chaîne ou un tableau de chaînes, nous avons donc probablement besoin d'une channel factory différente. + +Nous allons nous débarrasser de "of" que nous avons utilisé jusqu'à présent, et utiliser à la place .fromPath. Cela fait exactement ce que cela semble. Il crée un channel avec des chemins au lieu de valeurs, en utilisant un nom de fichier de chaîne ou un glob. Je vais également supprimer l'opérateur flatten car nous n'en avons plus besoin maintenant que nous passons un fichier. + +## 4.1.3. Exécuter le workflow + +Je vais appuyer sur sauvegarder, ouvrir le terminal, exécuter le workflow, et ensuite voir ce qui se passe. + +D'accord. Il a planté à nouveau. Ne vous inquiétez pas. Je m'attendais à celui-ci également. Jetons un coup d'œil au message d'erreur et voyons si nous pouvons comprendre ce qui ne va pas. Ici nous pouvons voir la commande exécutée, et un peu comme avant où nous avions tout le tableau imprimé. Maintenant nous avons le chemin de fichier qui est écho dans la commande, plutôt que de parcourir le contenu du fichier. + +## 4.2. Utiliser l'opérateur splitCsv() pour analyser le fichier + +Donc pour utiliser le contenu du fichier à la place, nous avons besoin d'un autre opérateur. L'opérateur que nous allons utiliser pour celui-ci s'appelle splitCsv. Cela a du sens, parce que c'est un fichier CSV que nous chargeons. + +## 4.2.1. Appliquer splitCsv() au channel + +Ok, donc splitCsv. Fermer la parenthèse. Nous n'avons besoin d'aucun argument ici. Et encore, je vais utiliser quelques opérateurs view pour donner un aperçu de ce qui se passe ici. + +.view csv after splitCsv. Before split Csv. + +## 4.2.2. Exécuter à nouveau le workflow + +D'accord, essayons d'exécuter cela et voyons ce qui se passe. + +D'accord, nous avons un peu plus de sortie cette fois, mais cela a quand même échoué. Nous pouvons regarder les instructions view, et ici vous pouvez voir before split CSV, et nous avons un chemin de fichier comme nous l'avons vu dans le message d'erreur précédent. After split CSV, nous avons maintenant trois valeurs correspondant aux trois lignes dans le fichier CSV. + +Cependant, vous pouvez voir que chacune de ces valeurs est entourée de crochets. Donc chacune d'elles était un tableau en soi, et cela nous a donné la même zone que nous avions avant où il essaie d'écho un tableau plutôt qu'une simple chaîne. + +Si nous pensons à un fichier CSV, cela a du sens. Typiquement, un fichier CSV aura des lignes et des colonnes, donc split CSV fait un tableau en deux dimensions. La première dimension du tableau est chaque ligne, et ensuite il y a une deuxième dimension, qui est chaque colonne pour chaque ligne. + +Donc ici nous n'avons qu'une seule valeur sur chaque ligne, donc nous avons une seule colonne, donc nous avons un tableau à un élément pour chaque ligne du fichier. + +Ce n'est pas grave. Nous avons juste besoin d'un autre opérateur pour effondrer ce tableau pour chaque ligne du fichier CSV analysé. Nettoyons ceci. Débarrassons-nous d'un terminal et voyons ce que nous pouvons faire. + +## 4.3. Utiliser l'opérateur map() pour extraire les salutations + +Maintenant nous pourrions utiliser l'opérateur flatten à nouveau, que nous avons utilisé avant. Nous avons vu comment cela peut effondrer un tableau en une série de valeurs, ce qui fonctionnerait très bien ici. Mais je vais utiliser l'opportunité pour démontrer un autre opérateur, qui est très courant dans les workflows appelé l'opérateur map. + +## 4.3.1. Appliquer map() au channel + +Je vais faire dot map et je vais faire item item[0]. + +Si vous écrivez beaucoup d'autres langages de code, vous pourriez déjà être familier avec l'opérateur map. Il prend un itérable, tel qu'un tableau ou un channel, et il fait une opération sur chaque valeur de celui-ci. + +Ici nous disons que nous devrions définir une variable appelée item dans la portée de cette closure, et ensuite nous voulons retourner, juste la première valeur dans ce tableau. Donc item index zéro. + +Cela aplatit effectivement le tableau. Vous pouvez voir comment nous pourrions étendre ceci pour être plus complexe, cependant : si notre fichier CSV avait six colonnes, mais nous ne sommes intéressés que par la quatrième colonne, nous pourrions accéder à un index spécifique ici. Ou faire tout autre type d'opération sur la valeur avant de la passer au traitement en aval. + +Donc l'opérateur map est extrêmement flexible et très puissant pour modifier les channels en vol. Mettons une autre instruction view juste pour que nous puissions voir ce qu'il fait dans notre exécution. Peut juger cette ligne et la déplacer vers le bas. Et after map. + +## 4.3.2. Exécuter le workflow une dernière fois + +Ouvrons le terminal et essayons d'exécuter le workflow. + +D'accord, pas d'erreurs cette fois. C'est bon signe. Nous pouvons maintenant parcourir toutes ces différentes sorties des instructions view. Before split CSV, nous avions un seul chemin. After split CSV, nous avions les tableaux à valeur unique, et ensuite after map, nous avons juste les valeurs sans aucune syntaxe de tableau. Allons dans le répertoire results, et voici nos fichiers de sortie se comportant exactement comme nous le voulions. + +Il y a un petit bonus ici. Vous pouvez réellement voir que les opérateurs view sont légèrement mélangés dans l'ordre dans lequel ils ont fait la sortie. C'est parce que Nextflow fait de la parallélisation de ces différentes tâches. Donc après avoir divisé le CSV, il y a trois éléments dans ce channel, et il gère le traitement de ces trois éléments en parallèle automatiquement. Cela signifie que l'ordre des sorties est stochastique et peut varier. Dans ce cas, il s'est simplement trouvé que certains des opérateurs view ont retourné après que l'étape suivante ait été terminée, et donc c'est venu dans cet ordre. + +Si j'exécute le même workflow à nouveau. Alors effectivement, c'est venu dans un ordre différent et cette fois nous avons les split CSVs et les maps dans l'ordre que nous attendrions. + +Alors gardez juste à l'esprit, vous ne pouvez pas compter sur l'ordre des sorties d'une tâche de process parce que Nextflow gère cette parallélisation pour vous automatiquement. Nextflow fait cela pour vous avec sa logique de flux de données, et c'est la vraie puissance de Nextflow. + +D'accord, c'est probablement l'un des chapitres les plus importants de toute la formation. Une fois que vous comprenez les channels, les channel factories et les opérateurs, vous commencez à exploiter la force de Nextflow et ce qui le rend unique en tant que langage de programmation. Cette fonctionnalité permet à Nextflow de paralléliser tous vos workflows pour vous et de générer une logique de workflow extrêmement complexe avec une syntaxe très propre et un modèle de flux de données push. Cela peut être un concept un peu étrange au début, mais une fois que vous vous habituez à écrire du code comme ceci, cela deviendra rapidement naturel et avant que vous le sachiez, vous écrirez des workflows fantastiques. + +Faites une pause, une tasse de thé, promenez-vous et passons au chapitre trois, où nous commençons à étendre ces concepts dans des workflows plus complexes. À la prochaine vidéo. + +[Transcription de la vidéo suivante :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/fr/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..5c05109983 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Partie 3 : Hello Workflow - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page présente uniquement la transcription. Pour les instructions complètes étape par étape, retournez au [matériel de formation](../03_hello_workflow.md). + + Les numéros de section indiqués dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section du matériel. + +## Bienvenue + +Bonjour, bienvenue dans la partie trois de la formation « Hello Nextflow ». + +Ce chapitre s'intitule « Hello Workflow ». + +Dans le chapitre deux, nous avons construit un workflow simple d'un seul process, mais en réalité, les pipelines sont utiles car ils peuvent enchaîner plusieurs étapes d'analyse ensemble. + +Dans ce chapitre, nous allons prendre cet exemple initial et l'étendre pour le rendre un peu plus réaliste. + +Nous allons ajouter quelques étapes supplémentaires et nous allons voir comment utiliser les channels pour connecter ces étapes. + +Nous allons examiner plusieurs tâches, qui peuvent se regrouper en un seul process, et nous allons examiner les processes qui peuvent avoir plusieurs entrées et plusieurs sorties. + +D'accord, commençons. + +Alors, commençons. Comme auparavant. Allons sur training.nextflow.io. Hello Nextflow, chapitre trois. Hello Workflow. Et ouvrons notre espace de travail. J'ai nettoyé tous mes fichiers de travail des chapitres précédents et je vais ouvrir Hello Workflow. + +Maintenant, c'est le même fichier sur lequel nous avons travaillé jusqu'à présent, donc cela devrait être familier. Nous avons notre process say hello. Nous avons notre params.greeting avec son fichier greetings CSV, et nous avons notre workflow en bas, qui charge ce fichier CSV, crée le channel et le transmet à notre process. + +## 0. Échauffement : Exécuter hello-workflow.nf + +Si vous voulez, nous pouvons essayer cela et vérifier qu'il fonctionne comme prévu. Ouvrez un terminal pour nextflow run hello workflow nf et appuyez sur entrée. + +D'accord, excellent. Nos trois processes s'exécutent. Nous avons notre répertoire results avec nos trois sorties. Bonjour. Hello. Holà. Alors fermons ces fichiers, fermons le terminal, revenons au script. + +## 1. Ajouter une deuxième étape au workflow + +D'accord. Pour notre exemple, nous restons basiques et nous essayons de rester indépendants du domaine. Notre deuxième process va donc simplement manipuler ces chaînes de caractères, ces mots, de manière simple. Nous allons utiliser la commande Unix translate pour prendre ces fichiers et les mettre tous en majuscules. Nous faisons cela avec la commande « tr ». + +## 1.1. Définir la commande de mise en majuscules et la tester dans le terminal + +Nous pouvons essayer cela simplement dans le terminal bash, et voir si cela fonctionne. Donc vous faites echo, Hello World, puis vous passez cela avec le caractère pipe à tr, et nous lui donnons un motif de reconnaissance, a à z et ce en quoi il doit traduire. A à Z en majuscules. + +C'est très simple car cela traite littéralement les caractères A à Z. Donc cela ne fonctionnera pas sur quoi que ce soit d'accentué ou similaire. Mais pour les besoins de l'exemple, vous devriez comprendre l'idée. + +Je vais appuyer sur entrée et cela affiche dans le terminal, HELLO WORLD en majuscules. Et tout comme avant, nous pourrions rediriger cela vers un fichier si nous le voulions. Outfile. + +D'accord. Nettoyons cela. + +## 1.1. Écrire l'étape de mise en majuscules en tant que process Nextflow + +Retournons à notre script et écrivons un nouveau process pour gérer cette commande bash. Je vais copier le process précédent, le coller en dessous, et l'appeler convert to upper. Pour majuscules. Je vais utiliser le même publishDir results, mais je vais faire quelques modifications ici. Au lieu de prendre un val, je vais prendre un path input file, et je vais avoir un préfixe ici upper, pour que nos fichiers de sortie n'écrasent pas la sortie. Et je vais utiliser le nom de variable de l'entrée. Et ensuite je vais modifier le script ici en bas, et à la place je vais utiliser cat sur le fichier d'entrée et tout comme nous l'avons fait dans Bash TR, a-z, upper input file .txt. D'accord, cliquons sur enregistrer. + +## 1.2. Ajouter un appel au nouveau process dans le bloc workflow + +Maintenant, si je descends, nous devons réellement appeler ce process. Ajouter simplement le process dans le script ne suffit pas. Nous devons indiquer à Nextflow que nous devons exécuter ce process et où le faire. + +Donc je vais écrire ici, convert to upper et + +d'accord, nous obtenons une erreur ici disant qu'il attend un argument. Effectivement, nous devons passer quelque chose à ce process pour qu'il ait effectivement quelque chose à faire. + +## 1.3. Passer la sortie du premier process au deuxième process + +Ce que nous allons faire, c'est prendre la sortie de ce process. Donc je prends le nom, say hello, et quand je fais dot out. + +Pour un exemple simple comme celui-ci, où nous avons un process qui n'a qu'une seule sortie et nous passons cela à un nouveau process, donc il a une entrée, cela devrait être tout ce dont nous avons besoin. Donc je vais cliquer sur enregistrer, ouvrir le terminal, et essayons d'exécuter cela à nouveau. + +## 1.4. Exécuter à nouveau le workflow + +Maintenant, je n'ai pas nettoyé mon répertoire work de la dernière fois que j'ai exécuté ce workflow. Je vais l'exécuter à nouveau et je vais utiliser cela comme une opportunité pour montrer comment fonctionne la mise en cache partielle. Donc si je fais simple tiret resume. Avec un peu de chance, il devrait réutiliser les sorties de ce premier process, qui étaient exactement les mêmes que la dernière fois que j'ai exécuté. Mais maintenant nous avons un nouveau process ici qui n'a jamais été exécuté auparavant, qui s'exécute à partir de zéro. Et effectivement, vous pouvez voir que le premier process a utilisé les sorties en cache, et la deuxième sortie a exécuté trois sur trois. Vous pouvez également voir que nous avons maintenant nos deux processes ici, notre premier process, say hello, exécuté trois fois, et notre deuxième process convert to upper exécuté trois fois. + +Si j'exécute cela à nouveau, pour rappel, avec -ansi-log false, nous devrions voir que six tâches de process différentes s'exécutent, trois pour chacune d'elles. Donc cela fait exactement ce que nous espérions. Le premier process s'exécute trois fois, passant ces sorties à un deuxième process, qui s'exécute ensuite trois fois. + +Alors jetons un coup d'œil dans le répertoire work et voyons comment Nextflow gère ces entrées de fichiers. Si je prends ce répertoire de hachage ici du deuxième process, nous pouvons utiliser à nouveau la commande tree avec -a juste pour regarder ces fichiers. Vous pouvez voir ici que nous avons notre fichier d'entrée, qui est le fichier Bonjour-output.txt, et c'est en fait un lien symbolique. C'est ce que cette flèche nous montre, et elle pointe vers le fichier dans le répertoire work précédent. + +Cela a du sens. Nextflow gère l'exécution de chaque tâche dans son propre répertoire encapsulé, donc il est complètement autonome. Cependant, il doit fournir les fichiers des étapes précédentes comme entrée. Plutôt que de sortir du répertoire work pour obtenir ces fichiers, Nextflow les organise dans le répertoire work. + +Si nous avons un système de fichiers partagé comme ici, il le fait en utilisant un lien symbolique pour ne pas utiliser d'espace de fichier supplémentaire. Si nous utilisons le stockage cloud avec des buckets dans différents emplacements, il récupérerait ces fichiers et les copierait réellement dans le répertoire work. + +Regardons le fichier command sh. Si je fais code work, command sh, vous pouvez voir, effectivement, il accède à ce fichier depuis le répertoire local. Donc tout est très autonome et propre. + +Nous pouvons également vérifier le répertoire results et nous assurer que ces fichiers ont été correctement sortis. Et effectivement, dans results, nous pouvons voir tous les fichiers de sortie du premier process et tous les fichiers de sortie du second. Et ils sont tous en majuscules comme nous l'espérions. + +C'est là que la puissance de Nextflow commence à briller. Avec un code très minimal, Nextflow a géré l'exécution en parallèle de ces tâches avec une encapsulation propre dans des répertoires work séparés et l'organisation des fichiers d'entrée et de sortie et la publication des fichiers, tout automatiquement pour nous, directement prêt à l'emploi. Donc vous pouvez voir comment, à mesure que nous augmentons la complexité de nos workflows d'analyse, cette fonctionnalité est vraiment, vraiment précieuse. + +## 2. Ajouter une troisième étape pour collecter toutes les salutations + +D'accord. Ces étapes étaient un pour un. Nous avions une sortie du premier process allant à une entrée pour le deuxième process. Ensuite, nous allons parler de la façon de collecter ces différentes sorties dans une seule tâche de process, ce qui est encore une fois, une chose très courante à faire. Alors ouvrons rapidement le terminal et faisons un test à sec de cela. + +## 2.1. Définir la commande de collecte et la tester dans le terminal + +Je vais tricher et copier l'exemple de code bash du matériel de formation et simplement appuyer sur entrée. + +Ce que nous pouvons voir ici, c'est que nous avons exécuté cette commande echo trois fois vers trois fichiers de sortie différents, que je peux voir ici. Et ensuite nous avons utilisé la commande cat pour afficher la sortie de chacun de ces trois fichiers différents, et rediriger cela vers un seul fichier collecté. + +Et si je fais « cat COLLECTED-output », vous pouvez voir qu'il contient le contenu de ces trois fichiers différents, maintenant dans un seul fichier. + +## 2.2. Créer un nouveau process pour effectuer l'étape de collecte + +Alors voyons si nous pouvons reproduire la même chose dans notre pipeline Nextflow. + +Remontons et créons un troisième process. Je vais copier celui précédent, et cette fois je vais l'appeler Collect Greetings. + +Dans le terminal bash, nous l'avons appelé collected output txt. Donc je vais dire le même path output ici. Et je vais faire la redirection ici, donc c'est sauvegardé de la même manière. + +D'accord. Nous devons changer ce qui se passe au début de cette commande, et nous devons réfléchir à ce qu'est le fichier d'entrée ici. En fait, ce process va prendre plusieurs fichiers d'entrée. Je vais garder path et je vais changer cela en une nouvelle variable appelée input files, au pluriel. + +Je vais ensuite à nouveau, les cat comme nous l'avons fait dans notre script bash. Et je vais utiliser la variable ici. + +Maintenant, vous pourriez penser que cela ne fonctionnerait pas. Nous avons vu précédemment des échecs où un tableau de chaînes ou un tableau de chemins a été passé à un process et cela a causé une erreur. Mais en fait, ici Nextflow va gérer cela automatiquement pour nous de la bonne manière. Il va prendre plusieurs fichiers d'entrée différents, et il va simplement afficher les différents chemins de fichiers ici. + +Bien sûr, cela aide que la commande cat puisse prendre une série de noms de fichiers comme cela. Si j'utilisais une commande différente qui nécessitait un argument avant chaque chemin de fichier ou quelque chose comme ça, nous devrions avoir un peu plus de code ici et de logique pour pouvoir gérer l'itération de ces chemins de fichiers. Mais dans ce cas, cela devrait simplement fonctionner. + +## 2.3. Ajouter l'étape de collecte au workflow + +D'accord, descendons au workflow et ajoutons notre nouveau process. Collect greetings. Et encore une fois, prenons la sortie de convert to upper out. Enregistrons cela. + +Essayons. nextflow run hello workflow. + +D'accord, le workflow s'est exécuté, mais quelque chose est un peu étrange ici. Nous avons trois exécutions de la première étape, ce que nous attendons. Trois tâches pour la deuxième, mais nous avons également trois tâches à la fin alors que nous nous attendions à n'avoir qu'une seule tâche ici fusionnant toutes les sorties. + +Si nous allons dans notre répertoire results. Nous voyons également que la sortie collectée n'a qu'une seule valeur plutôt que les trois. C'est parce que ce fichier de sortie a été écrasé trois fois avec trois valeurs différentes. + +Cela a du sens car nous avons passé une sortie à une entrée ici de la même manière que nous l'avons fait à l'étape précédente. + +## 2.4. Utiliser un opérateur pour collecter les salutations en une seule entrée + +Nous avons donc besoin d'un opérateur ici pour prendre ce channel avec trois éléments et les réduire à un seul élément, pour que ce process final ne s'exécute qu'une seule fois. + +Pour ce faire, nous allons utiliser l'opérateur collect. Je peux faire cela directement dans le workflow. Je peux faire .out et enchaîner un opérateur ici à la fin .collect. + +Cliquez sur enregistrer. Et puis pour les besoins de cette formation, je vais également faire quelques opérateurs view comme nous l'avons fait avant, pour que nous puissions jeter un œil à ce channel avant et après avoir utilisé l'opérateur collect, pour que nous puissions comprendre ce qui se passe. + +Je vais prendre ce channel, supprimer le collect et dot view greetings, puis je vais dupliquer cette ligne, ajouter l'opérateur collect. Et changer cela en after. + +C'est séparé de l'endroit où nous appelons cela, mais ce n'est pas grave car nous utilisons les mêmes appels d'opérateurs sur le même channel de sortie. + +D'accord, enregistrons et essayons-le dans le terminal. Je vais faire nextflow run. Hello, workflow. Réexécutons notre script. + +D'accord. Cela a l'air mieux. Comme avant, nous pouvons voir que les deux premiers processes s'exécutent trois fois et maintenant notre process final ne s'est exécuté qu'une seule fois. + +Si nous regardons ce qui a été affiché par l'opérateur view, ici en bas, nous avons dit before collect, qui est cette sortie ici, et c'est affiché trois fois. Et vous pouvez voir qu'il y a un seul chemin pour chacun d'eux. Et ensuite after collect, vous pouvez voir que nous avons ce tableau de trois chemins. Donc c'est comme prévu. + +D'accord, vérifions le fichier results et voyons si c'est ce que nous attendons cette fois. Effectivement, il y a maintenant trois lignes dans le fichier - cela a réussi à concaténer ces trois sorties en un seul fichier de sortie. Fantastique. + +D'accord, je vais nettoyer et passons à l'étape suivante. Et je vais supprimer ces instructions view juste pour garder les choses propres. + +## 3. Passer plus d'une entrée à un process afin de nommer le fichier de sortie final de manière unique + +D'accord. Jusqu'à présent, tous nos processes n'ont pris qu'une seule entrée. Nous allons maintenant faire un exercice où nous ajoutons plus d'une entrée à un process pour voir comment cela fonctionne. Pour ce faire, nous allons utiliser cet exemple collect greetings. + +Chaque fois que j'ai exécuté le workflow, il a écrasé ce fichier dans le répertoire results, ce qui peut ne pas être ce que nous voulons. + +## 3.1. Modifier le process de collecte pour accepter un nom défini par l'utilisateur pour le fichier de sortie + +Donc pour cet exemple, nous allons passer un paramètre supplémentaire pour pouvoir personnaliser le nom du fichier de sortie. + +Ajouter une deuxième entrée à un process est très simple. J'ajoute simplement une deuxième ligne dans le bloc input. Cette fois, ce sera une value, plutôt qu'un path, car nous voulons passer une chaîne et je vais l'appeler batch underscore name. + +Je peux maintenant utiliser cette variable dans le bloc script, et je vais dire collected dash dollar batch name. + +J'utilise des accolades ici autour du nom de la variable. C'est juste pour la séparer du reste de la chaîne, et ce n'est probablement pas nécessaire dans ce cas, mais je pense que cela rend la lecture plus facile. + +D'accord. Enfin, n'oubliez pas de mettre à jour le path de sortie car maintenant le nom du fichier a changé, donc je vais faire la même chose et mettre le batch name dans la sortie du path comme prévu. + +## 3.2. Ajouter un paramètre de ligne de commande batch + +Nous devons maintenant passer un batch name de quelque part, et je vais créer un deuxième paramètre pour ce faire afin que nous puissions le faire en ligne de commande lorsque nous exécutons le workflow. + +Donc je vais faire params batch name, et par défaut, appelons cela test batch. Maintenant je peux utiliser cette variable de paramètre spéciale en bas, là où nous appelons le process. + +Et effectivement VS Code nous dit qu'il n'y a pas assez d'arguments pour ce process maintenant, et qu'il attend une deuxième entrée. + +Simplement faire virgule et passer notre nouvelle variable et l'erreur disparaît. + +Notez que l'ordre des entrées ici est vraiment important. La première entrée du process était le path, et la deuxième entrée est le name. Si je change l'ordre ici, je dois également changer l'ordre lorsque j'appelle le process. Sinon. Nextflow passera le mauvais channel à la mauvaise entrée. + +## 3.3. Exécuter le workflow + +D'accord, essayons et voyons si cela fonctionne. Faisons « nextflow run hello- workflow ». D'accord, il s'est exécuté comme avant. Regardons dans le répertoire results. + +Effectivement, notre nom de fichier ici s'appelle maintenant « collected test batch output txt ». Fantastique. + +Et maintenant voyons si nous pouvons écraser cela en exécutant à nouveau. Cette fois, je vais faire --batch_name pour correspondre à ce nom de variable de paramètre spécial ici. Et je vais l'appeler demo output. + +Exécutons à nouveau le workflow et nous verrons si quelque chose se passe. + +D'accord, nous avons maintenant un collected demo output .txt. Et parce que ce nom de fichier est différent de celui-là, il ne l'a pas écrasé. Les deux sont maintenant présents dans le répertoire results. + +## 4. Ajouter une sortie à l'étape de collecte + +D'accord, donc là nous avons montré comment donner plusieurs entrées à un process, mais qu'en est-il de plusieurs sorties ? Pour cet exemple, nous allons calculer le nombre de salutations qui sont traitées et sortir cela comme une sortie secondaire pour cette étape collect greeting. + +## 4.1. Modifier le process pour compter et sortir le nombre de salutations + +Nous allons faire une petite astuce ici. Les processes Nextflow ont ce bloc script avec une chaîne multi-lignes, et cela est passé comme sortie bash au dot command dot sh. Mais nous pouvons en fait écrire n'importe quel code personnalisé au-dessus de cela, et cela sera exécuté dans le cadre d'une tâche mais pas inclus dans le script bash. + +Une des fonctions intégrées dans la syntaxe Nextflow s'appelle size. Donc je vais prendre l'entrée path, et je vais dire count underscore greetings, juste pour définir un nom de variable. Je vais prendre les input files et je vais appeler « size » dessus. + +Cette fonction comptera la taille de ce channel d'entrée et l'attribuera à une variable. + +Nous pouvons maintenant retourner cette variable dans le cadre du bloc output. Donc nous disons, val, car c'est une value, pas un fichier. Et count greetings. + +Maintenant cela suffit en soi, et nous pourrions maintenant accéder à ces différentes sorties de ce process. Cependant, nous devrions y accéder de manière positionnelle. Donc en utilisant une clé d'index comme zéro et un. + +Pour rendre un peu plus facile l'accès aux sorties, nous pouvons les nommer et nous faisons cela en utilisant une instruction emit. + +Donc nous faisons, virgule emit out file ou quel que soit le nom que je veux donner à cela. Et je fais ici emit count. C'est essentiellement juste un décorateur, qui nous aide à écrire un code légèrement plus propre pour que nous puissions facilement référencer les sorties spécifiques plus tard dans le bloc workflow. + +## 4.2. Rapporter la sortie à la fin du workflow + +D'accord. Si je descends au bloc workflow, je peux maintenant prendre les sorties de collect greetings, faire collect greetings, dot out, et nous pouvons voir que nos deux sorties nommées sont suggérées ici par l'extension VS Code. Très pratique. + +Donc je vais faire dot count pour obtenir la valeur count que nous venons de créer, et je vais faire view, pour qu'elle s'affiche dans la ligne de commande. Donc nous pouvons la voir lorsque nous exécutons le workflow. + +Écrivons quelque chose dans la closure ici juste pour que ce soit un peu plus joli. num greetings, there were greetings greetings. + +Et nous ne nous soucions pas vraiment de l'autre sortie car nous ne l'utilisons pas comme entrée pour d'autres processes. Mais vous pouvez voir comment nous pourrions facilement passer cela comme entrée à un autre process si nous le voulions, en aval. + +## 4.3. Exécuter le workflow + +Nous allons cliquer sur enregistrer. Jetons un coup d'œil au terminal et essayons-le. + +D'accord, fantastique. Nous y voilà. There are three greetings. C'est exactement ça. + +D'accord, excellent. C'est la fin de ce chapitre. Nous avons tout terminé pour être arrivés jusqu'ici. Vous commencez maintenant à construire un workflow assez réaliste, où nous sommes capables de gérer les entrées et les sorties et la logique dans notre workflow. + +À mesure que ces fichiers de workflow deviennent plus longs, ils commencent à devenir un peu lourds. Donc dans le prochain chapitre, nous examinerons comment nous pouvons modulariser le code Nextflow dans des fichiers séparés pour qu'il soit plus facile de trouver et de maintenir le code dans le workflow. + +Rejoignez-nous dans la prochaine vidéo pour le chapitre quatre. Hello Modules. + +[Transcription de la vidéo suivante :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/fr/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..1d7aed6307 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Partie 4 : Hello Modules - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page présente uniquement la transcription. Pour des instructions complètes étape par étape, retournez au [matériel de formation](../04_hello_modules.md). + + Les numéros de section affichés dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section du matériel. + +## Bienvenue + +Bonjour, bienvenue dans la Partie Quatre de la formation Hello Nextflow. + +Ce chapitre s'intitule Hello Modules, et nous allons parler de la façon de modulariser le code Nextflow. Ce que nous allons faire, c'est prendre notre script de workflow unique et le diviser en fichiers séparés. + +Cela rend le code plus facile à naviguer et à maintenir au fur et à mesure que votre workflow grandit, et permet également de partager des modules entre pipelines, de sorte que si vous avez plusieurs pipelines utilisant le même outil, vous n'avez besoin d'écrire ce process qu'une seule fois. + +Un exemple classique de ceci est le dépôt de modules nf-core, qui contient des milliers d'outils différents dans des modules prêts à l'emploi, que vous pouvez installer et utiliser dans votre workflow. + +Nextflow peut également fonctionner avec des sub workflows, qui sont comme des modules, mais ils ont plusieurs processes. Cela dépasse le cadre de cette formation, mais cela fonctionne essentiellement de la même manière. + +D'accord. Jetons un coup d'œil. + +Comme d'habitude, commencez par aller sur training.nextflow.io. + +Allez dans « Hello Nextflow » dans la barre latérale, et nous faisons la partie quatre : « Hello Modules ». + +Je vais maintenant passer à mon environnement GitHub Code Spaces et examiner le fichier « hello-modules ». + +Comme précédemment, nous commençons à partir du point final du chapitre précédent, donc ce script devrait vous sembler familier. Nous avons nos trois processes, say hello, convert to upper et collect greetings, et dans un workflow simple, qui exécute ces trois commandes et émet un message à la fin. Nous avons deux paramètres appelés greeting et batch, qui spécifie le nom utilisé pour le fichier de sortie collecté à la fin. + +## 0. Échauffement : Exécuter hello-modules.nf + +Nous pouvons vérifier que ce workflow fonctionne toujours comme prévu en faisant nextflow run hello, modules. + +Parfait. Il a exécuté trois tâches avec chacun de ces processes, une tâche collectée, et il nous a dit qu'il y a trois salutations dans ce lot. Si nous allons dans results, nous avons nos différents fichiers de sortie ici, y compris le test collecté, la sortie batch. + +## 1. Créer un répertoire pour stocker les modules + +Bien. Faisons un peu de modularisation. + +C'est généralement une bonne idée de mettre les modules dans un sous-répertoire de votre dépôt de pipeline, juste pour garder les choses organisées. Vous pouvez appeler cela comme vous voulez, mais par convention, nous l'appelons habituellement modules. + +Alors allons-y, ouvrons un terminal et faisons make the modules. Vous pouvez le voir apparaître dans la barre latérale et VS Code ici. + +## 2. Créer un module pour sayHello() + +Je vais ensuite créer un nouveau fichier pour mon premier module. Vous pouvez faire « touch » ou « code » ou vous pouvez le faire dans la barre latérale, cela n'a vraiment pas d'importance. Donc je vais faire code modules et je vais le nommer d'après le process. Donc sayHello.nf . NF est une extension de fichier traditionnelle pour les fichiers Nextflow. + +Je vais sauvegarder ici et nous pouvons voir notre nouveau fichier de module apparaître. + +## 2.2. Déplacer le code du process sayHello vers le fichier module + +Bien, ensuite je vais prendre le code du module depuis le workflow. Je vais aussi prendre le hash bang ici et le copier en premier pour qu'il soit clairement un fichier Nextflow. Et puis je vais prendre ce process et je vais le couper. Donc je vais le retirer de mon script de workflow principal et je vais le coller dans ce nouveau module. + +C'est tout le contenu que ce fichier module va contenir. Juste un seul process, pas de workflow, pas de logique, juste un process seul. + +Je peux maintenant fermer ce fichier. + +## 2.3. Ajouter une déclaration d'import avant le bloc workflow + +Maintenant mon workflow manque ce premier process, donc nous devons le ramener en l'important. La syntaxe pour cela est très similaire à d'autres langages de programmation, donc elle peut sembler familière. Nous faisons include accolades, le nom du process, say hello, puis from le chemin du fichier modules, say hello, nf. Fantastique. + +Quelques astuces ici. L'extension VS Code est intelligente à ce sujet. Elle reconnaît ce chemin de fichier et vous pouvez passer la souris dessus et faire follow link. Ou je suis sur Mac, je peux faire option click et cela ouvre ce fichier. Donc nous pouvons rapidement y accéder. + +Ce nom de process est maintenant utilisé par le workflow en bas ici, et nous pouvons faire la même chose ici. Il nous montre un peu d'information sur ce process, et encore une fois, je peux maintenir option, cliquer dessus, et cela l'ouvrira dans l'éditeur. + +C'est donc un moyen très rapide lorsque vous avez beaucoup de fichiers pour vos différents processes de naviguer rapidement dans votre base de code dans VS Code. + +D'accord. C'est essentiellement tout pour ce chapitre. Maintenant nous faisons juste la même chose à nouveau pour les autres processes. + +## 3. Modulariser le process convertToUpper() + +Donc créons un nouveau fichier ici. Appelons-le Convert to upper nf. Encore une fois, copions le hash bang. Et puis coupons le process. + +Copions le nom du process là, include une nouvelle instruction include avec le nouveau nom de process. + +## 4. Modulariser le process collectGreetings() + +Et puis faisons la même chose pour le troisième process. Nouveau fichier, connect. Greetings, + +faisons le hash bang. Coupons le process, collons le process, et faisons une nouvelle instruction include. + +Maintenant vous pouvez voir ici j'ai un soulignement d'erreur ici disant invalid include source. Et c'est en fait une véritable erreur que j'ai faite parce que j'allais un peu trop vite. Si vous regardez attentivement, vous pouvez voir que j'ai manqué le T dans convert to upper + +Donc VS Code m'a très utilement dit que j'avais fait une erreur là. Si je corrige ce nom de fichier, l'erreur disparaît. C'est un bon exemple de pourquoi la vérification des erreurs dans VS Code est si utile pour écrire du code Nextflow. Sinon je ne l'aurais pas remarqué et je ne l'aurais découvert que bien plus tard lorsque j'aurais essayé d'exécuter le workflow. + +Notre script de pipeline principal est maintenant beaucoup plus simple. Il n'a aucun process dedans, nous avons juste trois instructions include et notre workflow. Nous n'avons changé aucune logique du workflow. Nous n'avons changé aucun code de process, donc j'espère qu'il devrait fonctionner exactement de la même manière. + +## 4.4. Exécuter le workflow pour vérifier qu'il fait la même chose qu'avant + +Vérifions. Je vais ouvrir un terminal et je vais exécuter exactement la même commande qu'avant. + +Effectivement, il a exécuté nos processes, say hello, convert to upper collect greetings, et nous a donné trois salutations à nouveau. + +Donc nous avons déplacé notre code, mais nous n'avons rien changé à la façon dont le workflow s'exécute et il est complètement inchangé. La seule différence est que nous avons maintenant un code plus propre, plus facile à maintenir et plus facile à partager avec les autres. + +Et c'est tout. C'était un chapitre court. C'est un concept simple, mais il est très puissant et essentiel à la façon dont nous écrivons des workflows Nextflow plus complexes. Il est donc important que vous le compreniez et que vous preniez l'habitude de l'utiliser. + +Dans le chapitre suivant, nous allons changer un peu de rythme et arrêter de penser autant à la syntaxe d'écriture du code Nextflow, et réfléchir un peu à la façon dont nous utilisons les logiciels dans les processes eux-mêmes. Rejoignez-nous dans la partie cinq pour Hello Containers. + +[Transcription vidéo suivante :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/fr/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..e1d38e3e5a --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Partie 5 : Hello Containers - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page affiche uniquement la transcription. Pour les instructions détaillées étape par étape, retournez au [matériel de formation](../05_hello_containers.md). + + Les numéros de section affichés dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section des supports. + +## Bienvenue + +Bonjour, bienvenue dans la Partie Cinq de la formation Hello Nextflow. + +Ce chapitre s'intitule Hello Containers. Nous allons parler de la façon dont Nextflow s'intègre avec des outils tels que Docker et Singularity pour utiliser des conteneurs logiciels afin de fournir des logiciels aux utilisateurs de votre pipeline. + +Cela signifie que lorsque les personnes exécutent votre pipeline, elles n'ont pas besoin d'aller installer tous les différents outils elles-mêmes. Nextflow le fera pour elles. + +Les conteneurs sont une technologie extrêmement puissante et cruciale pour la reproductibilité et la facilité d'utilisation. Nous allons commencer par faire une brève introduction aux conteneurs eux-mêmes, exécuter quelques commandes docker manuellement, puis nous prendrons ces mêmes conteneurs et les intégrerons dans notre pipeline Nextflow. + +D'accord. Commençons. + +Comme précédemment, commençons par charger le matériel de formation. Allez sur training.nextflow.io. Hello Nextflow, Chapitre Cinq, Hello Containers. + +Je vais accéder à mon environnement Codespaces et sur la gauche nous voyons hello containers point nf. + +Comme avant, c'est le même script avec lequel nous avons terminé le chapitre quatre précédent, donc il devrait vous sembler familier. + +Nous avons nos paramètres de ligne de commande pour spécifier le fichier d'entrée et le nom du lot. Nous incluons nos trois modules, et nous avons notre workflow où nous exécutons les trois processus. + +## 0. Échauffement : Exécuter hello-containers.nf + +N'hésitez pas à exécuter ce workflow à nouveau et vérifiez qu'il produit les sorties que vous attendez. Pour l'instant, je vais en fait le fermer et plonger dans le terminal. + +## 1. Utiliser un conteneur 'manuellement' + +Pour commencer ce chapitre, nous allons faire un petit récapitulatif sur la technologie des conteneurs. Si vous êtes très habitué à docker ou singularity ou d'autres technologies de conteneurs, alors considérez ceci comme un rappel, ou n'hésitez pas à le sauter complètement. + +Nextflow supporte de nombreux types différents de technologies de conteneurs. Cela inclut Docker, Singularity, Podman, Shifter, Charliecloud, et plus encore. + +Dans cette formation, nous allons nous concentrer sur Docker. Il est pré-installé dans les code spaces et est l'une des technologies de conteneurs les plus populaires, en particulier si vous développez sur votre propre ordinateur ou votre propre portable. + +Si vous travaillez dans un environnement académique sur un HPC partagé, vous pourriez constater que Singularity est disponible et non Docker. Ce n'est pas grave. Tous les concepts sont exactement les mêmes. Quelques commandes manuelles sont différentes, mais si vous comprenez Docker, vous comprendrez aussi singularity. + +En fait, Singularity est également installé dans l'environnement Code Spaces. Donc si vous le souhaitez, vous pouvez essayer de faire les mêmes tâches en utilisant Singularity au lieu de Docker. + +D'accord, donc qu'est-ce que la technologie de conteneurs ? L'idée derrière Docker est qu'il peut récupérer une image depuis une source distante. La télécharger sur votre machine locale puis créer un conteneur basé sur cette image. + +Ce conteneur en cours d'exécution est un peu comme une machine virtuelle fonctionnant sur votre ordinateur. Il est isolé de votre environnement, et il vient préemballé avec un système d'exploitation et un ensemble de logiciels disponibles. + +## 1.1. Télécharger l'image du conteneur + +La syntaxe dont nous avons besoin pour récupérer une image préexistante est "docker pull". Donc je vais taper ça dans mon terminal, mais maintenant nous avons besoin d'une image avec laquelle jouer. + +Vous pouvez construire des images vous-même. Vous pouvez les trouver sur des registres publics comme Docker Hub ou quay.io. Mais une très bonne façon d'obtenir des images rapidement est d'utiliser Seqera Containers. + +C'est un service communautaire gratuit que nous avons construit en 2024, que vous pouvez utiliser sans connexion ni rien. + +Si vous allez sur seqera.io/containers ou cliquez sur containers en haut ici, vous êtes présenté avec une interface de recherche et vous pouvez taper le nom de n'importe quel outil disponible dans Conda ou sur le Python Package Index. + +Par défaut, il recherche dans les canaux Bioconda et Conda Forge, mais vous pouvez préfixer n'importe quel canal Conda. Je suis ici si vous voulez. + +Pour un peu de plaisir, utilisons cowpy. Je vais taper cowpy. Cela me donne des résultats de Python Package Index et Conda Forge. Je vais cliquer dessus pour l'ajouter à mon conteneur. Je pourrais ajouter plusieurs paquets ici si je le voulais. Sélectionner Docker, sélectionner linux/amd64, et cliquer sur Get Container. + +Cela construit l'image pour moi à la demande si elle n'a pas déjà été créée, et me donne une URL que je peux copier. + +Si vous êtes intéressé, vous pouvez cliquer sur view Build Details, et cela vous amène à une page qui montre le fichier d'environnement conda qui a été utilisé et le journal de construction complet pour la construction, ainsi que les résultats de l'analyse de sécurité. + +Si je retourne à mes code spaces, je peux maintenant coller ce nom de conteneur et appuyer sur entrée. + +Docker télécharge maintenant toutes les différentes couches dans cette image de conteneur, et nous dit maintenant que cette image est disponible à l'utilisation. + +## Télécharger une image Singularity + +Si vous utilisez singularity, le processus est fondamentalement le même. Nous sélectionnons nos paquets d'image, sélectionnons cowpy. Maintenant nous choisissons Singularity au lieu de Docker et cliquons sur Get Container. Cela nous donne une URL d'image utilisant oras://. Ou si vous préférez, vous pouvez utiliser https:// en cochant cette case. Copiez cette URL. Maintenant allez dans Code Spaces. Nous avons en fait Apptainer installé dans cet espace, qui est le même que Singularity, mais ils sont aliasés l'un à l'autre. Donc je vais faire apptainer pull et ensuite je vais l'appeler cowpy sif, mais vous pouvez l'appeler comme vous voulez. Collez l'URL. Et cela va télécharger cette image pour moi. + +Je pourrais faire ls -lh et voir cowpy.sif + +Singularity est différent de Docker, en ce que singularity stocke toutes les images dans des fichiers plats, alors que Docker a un registre où il conserve toutes les couches séparément sur votre machine hôte, et il a un démon en cours d'exécution pour garder trace de tout cela. + +## 1.2. Utiliser le conteneur pour exécuter cowpy en tant que commande unique + +D'accord, revenons à Docker. Nous pouvons maintenant essayer d'exécuter cette image que nous avons créée en faisant docker run. + +Je vais faire dash dash rm, qui fait simplement une exécution unique de l'image. Et je vais coller l'URL de l'image. Et puis finalement, vous terminez ceci avec une commande que vous voulez exécuter. + +L'image que nous avons générée avait cowpy installé, donc essayons cowpy. + +Voilà. Elle a exécuté notre commande. Je n'ai pas cowpy installé localement. Vous pouvez voir que si j'essaie de l'exécuter, ça n'existe pas. Cependant, dans cette commande, je l'ai exécuté en utilisant Docker et il a correctement généré cette sortie. + +## 1.3. Utiliser le conteneur pour exécuter cowpy de manière interactive + +Nous pouvons aller plus loin si nous le souhaitons et démarrer un conteneur de manière interactive et regarder à l'intérieur. Encore une fois, je fais "docker run dash dash rm". Maintenant je vais faire dash it, qui indique à Docker que nous voulons un terminal interactif. Je fais à nouveau l'URL de l'image, et cette fois, au lieu de faire cowpy, je vais faire bin bash parce que la commande que nous voulons exécuter est bash. + +Cela nous amène dans ce conteneur en cours d'exécution et vous pouvez voir que l'invite a changé maintenant. + +Si je fais LS slash vous pouvez voir que les répertoires ici sont différents. + +Si j'ouvre un deuxième terminal ici sur le côté droit, qui s'exécute simplement dans GitHub Code Spaces et je fais LS slash, vous voyez que nous avons des répertoires comme workspaces et temp, alors qu'ici dans Docker c'est différent. + +Donc cet environnement est complètement séparé dans Docker et isolé de mon environnement hôte. C'est une bonne chose, parce que cela isole l'exécution de cette commande dans l'image Docker et la garde reproductible entre différentes personnes sur différents systèmes hôtes. + +Si vous voulez utiliser des données de votre système hôte dans l'image Docker, vous devez explicitement monter cela dans le conteneur. + +Nous allons faire cela dans une seconde. + +## 1.3.2. Exécuter la ou les commandes de l'outil souhaité + +D'abord cependant, voyons si nous pouvons exécuter cowpy. Encore une fois, la commande est disponible maintenant directement sur la ligne de commande, et nous pouvons commencer à faire des choses plus complexes et passer des arguments. Hello containers et au lieu de la vache, faisons le pingouin tux. Voyons ce que nous avons d'autre. + +Faisons cheese. Merveilleux. Que diriez-vous de Dragon et Cow ? Plutôt bien. + +## 1.3.3. Quitter le conteneur + +D'accord. Je ne peux pas faire beaucoup plus parce que je n'ai pas de données dans ce conteneur. Donc sortons de cette image en cours d'exécution et voyons si nous pouvons monter des données dans le conteneur. Je peux faire ça en faisant control D ou en tapant exit. D'accord, je suis maintenant de retour dans mon GitHub code space régulier. + +## 1.3.4. Monter des données dans le conteneur + +Pour monter des données dans le conteneur Docker, je dois utiliser dash V. Donc je vais prendre ma commande docker précédente, retourner au début faire dash v. Je vais faire "." pour le répertoire de travail local actuel, puis deux points pour dire où cela devrait être monté dans le répertoire hôte et faire slash data. Donc cela monte ce répertoire particulier dans le conteneur à slash data. + +Maintenant si je fais LS slash nous pouvons voir que nous avons un nouveau répertoire appelé data, et si je fais LS data, vous pouvez voir tous les fichiers que nous avons dans la barre latérale ici. Fantastique. + +## 1.3.5. Utiliser les données montées + +Maintenant nous pouvons commencer à utiliser certains des fichiers qui sont sur le système hôte dans l'image Docker. Donc je peux dire cat data greetings csv. Si vous vous souvenez, c'est notre fichier CSV avec nos différentes salutations d'avant, et je peux le piper vers cowpy. Fantastique. Maintenant nous progressons. + +D'accord. C'est assez pour exécuter Docker de manière interactive. J'espère que vous avez maintenant une idée de ce qu'est Docker approximativement et comment l'utiliser à la fois pour exécuter une commande de manière unique, et aussi pour utiliser une image de manière interactive. Si vous utilisez singularity. Les commandes sont toutes très similaires sauf que vous faites des choses comme apptainer exec ou apptainer run, ou singularity exec ou singularity run. + +## 2. Utiliser des conteneurs dans Nextflow + +Ensuite, nous allons retourner à notre workflow Nextflow et voir comment utiliser cette technologie dans le pipeline Nextflow. + +Fermons le terminal et ouvrons à nouveau Hello Containers. + +## 2.1. Écrire un module cowpy + +Pour rester avec notre exemple cowpy, créons un nouveau processus dans notre workflow, qui utilise cowpy. Allons dans modules, créons un nouveau fichier et appelons-le cowpy nf. Je vais maintenant tricher un peu et copier le code du matériel de formation et appuyer sur sauvegarder. Et regardons. + +Donc c'est un processus simple. J'espère que maintenant vous comprenez à quoi ressemblent les éléments constitutifs d'un processus. Nous avons notre publishDir à nouveau, allant vers results. Nous avons deux entrées, un fichier d'entrée et une chaîne appelée character. Nous avons une sortie cowpy input file, et nous avons un script qui ressemble exactement à ce que nous avons exécuté manuellement dans notre image docker il y a une seconde : cat pour imprimer un fichier, le piper vers cowpy, dire quel type de caractère cowpy nous voulons utiliser, et sortir cela vers le fichier de sortie, que nous passons comme sortie ici. + +## 2.2. Ajouter cowpy au workflow + +D'accord, retournons à notre workflow, importons ce nouveau processus. Donc cowpy depuis modules cowpy nf. Créons un nouveau paramètre pour que nous puissions spécifier quel caractère nous voulions. Disons Turkey par défaut. Et puis appelons ce nouveau processus à la fin du workflow, + +cowpy. Et utilisons la sortie ici de Collect Greetings. Donc collect greetings out, out file ici. Et puis nous avons besoin d'un second argument, qui est le nouveau paramètre que nous venons de créer. params dot character. + +## 2.2.4. Exécuter le workflow pour vérifier qu'il fonctionne + +D'accord, voyons si notre nouveau processus fonctionne. Nextflow run hello containers. Cela devrait exécuter ces trois premiers processus puis essayer d'exécuter cowpy à la fin. + +Nous avons une erreur. Ce qu'il dit ici, cowpy a eu une erreur et il a eu un statut de sortie 127 et effectivement, commande sh cowpy commande non trouvée. + +Nous n'avons pas dit à Nextflow que nous avons une image Docker disponible pour cowpy, donc il a essayé de l'exécuter sur notre système hôte et nous n'avons pas cowpy installé sur notre système hôte, donc cela a déclenché une erreur. + +## 2.3. Utiliser un conteneur pour l'exécuter + +Donc ce que nous devons faire, c'est que nous devons dire à Nextflow que nous avons un conteneur disponible. Allons à notre processus cowpy et nous allons ajouter une nouvelle directive en haut du processus appelée container. + +Nous trouvons ensuite notre image, copions l'URL, et mettons cela dans une chaîne. + +Ceci n'est pas suffisant en soi parce qu'un pipeline Nextflow peut avoir plusieurs façons de spécifier des logiciels. Je pourrais aussi faire conda conda-forge cowpy, par exemple. Et Nextflow a besoin de savoir laquelle de ces technologies vous voulez utiliser. + +## 2.3.2. Activer l'utilisation de Docker via le fichier nextflow.config + +Donc afin d'exécuter avec Docker activé, nous allons prendre un peu d'avance et utiliser le fichier de configuration Nextflow, qui est quelque chose que nous allons couvrir plus en détail dans le prochain chapitre. Vous pouvez voir dans ce répertoire que nous avons un fichier appelé Nextflow Config, et ici vous avez déjà docker.enabled False. + +Nous allons changer cela en True pour activer Docker, et ensuite nous pouvons essayer d'exécuter le workflow à nouveau. + +## 2.3.3. Exécuter le workflow avec Docker activé + +Nextflow run hello containers nf et cette fois cowpy s'est exécuté avec succès. Regardons dans Results. cowpy collected test et voilà notre Turkey. Merveilleux. + +Donc en arrière-plan là, Nextflow savait qu'il avait un conteneur disponible pour ce processus. + +Il a récupéré l'image et il a exécuté les commandes pour nous. + +## 2.3.4. Inspecter comment Nextflow a lancé la tâche conteneurisée + +Si vous êtes curieux, nous pouvons en fait voir exactement ce qu'il a fait en regardant dans le répertoire work. Si je fais code work, puis le hash et ensuite command run, qui si vous vous souvenez est le fichier réel qui est exécuté pour cette tâche, nous pouvons entrer et nous pouvons chercher une fonction appelée NXF launch. Et ici vous pouvez voir la commande docker exacte que Nextflow a utilisée, qui ressemble beaucoup à ce que nous faisions manuellement dans le terminal plus tôt. Docker run. Lier ce répertoire hôte dans le conteneur, puis spécifier l'URL du conteneur. + +Donc il n'y a pas de magie ici. C'est juste que Nextflow fait automatiquement le gros du travail pour vous d'une manière qui signifie que vous pouvez facilement spécifier des conteneurs dans votre pipeline, qui sont ensuite facilement disponibles pour quiconque d'autre utilise qui exécute votre workflow. Et ces personnes n'ont plus à penser à gérer les logiciels pour exécuter votre pipeline d'analyse. + +Très, très simple, très pratique, et aussi vraiment reproductible. Bon dans l'ensemble. + +D'accord, excellent travail. C'est la fin du Chapitre Cinq. Rejoignez-nous dans la prochaine vidéo pour la partie six, qui est la dernière partie de cette formation Hello Nextflow, où nous parlerons de la configuration Nextflow plus en détail. + +À la prochaine vidéo. + +[Transcription de la vidéo suivante :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/fr/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..7078012b83 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Partie 6 : Hello Config - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page présente uniquement la transcription. Pour des instructions complètes étape par étape, retournez au [matériel de formation](../06_hello_config.md). + + Les numéros de section affichés dans la transcription sont fournis à titre indicatif uniquement et peuvent ne pas inclure tous les numéros de section dans les supports. + +## Bienvenue + +Bonjour, bienvenue dans la partie six de la formation Hello Nextflow. + +Ce chapitre s'intitule Hello Config, et c'est la dernière partie de notre formation. + +Dans ce chapitre, nous allons parler de la configuration Nextflow. La configuration Nextflow est vraiment puissante. Elle nous permet d'exécuter le même pipeline sur plusieurs infrastructures de calcul différentes avec différentes méthodes de provisionnement logiciel et différentes options dans le pipeline lui-même. + +Cela signifie que vous pouvez prendre des pipelines Nextflow construits par d'autres personnes et les exécuter sur votre système, même s'ils ont pu être conçus pour une infrastructure entièrement différente. Cette capacité à configurer Nextflow rend les workflows vraiment portables et partageables. + +Dans ce chapitre, nous utiliserons le workflow que nous avons construit dans les parties précédentes, mais nous n'allons pas du tout modifier le code du workflow. Nous allons simplement examiner notre fichier de configuration Nextflow et voir comment la modification de la configuration altère la façon dont Nextflow s'exécute. + +D'accord, commençons. + +Comme auparavant, commençons par aller sur training.nextflow.io. Allez à gauche sur Hello Nextflow et chapitre six, Hello config. Je vais maintenant aller dans mon environnement GitHub Codespaces et vérifier le script que nous allons utiliser. + +## 0. Échauffement : Vérifier que Docker est activé et exécuter le workflow Hello Config + +Celui-ci s'appelle Hello Config, et il repart d'où nous étions auparavant. Il ressemble donc exactement au même avec nos trois paramètres. Greetings pour le fichier CSV, batch pour le nom du lot de sortie et character pour le nom cowpy. Nous avons nos quatre imports des différents processus, puis nous avons un workflow où nous les enchaînons. + +Je vais effectivement fermer ce fichier maintenant car nous ne toucherons pas du tout au fichier Nextflow dans ce chapitre. Nous allons travailler uniquement dans le fichier de configuration. Si je regarde dans le fichier nextflow.config que nous avons brièvement examiné dans le chapitre cinq précédent, nous pouvons voir que nous avons une seule instruction ici : docker enabled equals true, qui indique à Nextflow d'utiliser Docker lorsqu'il exécute ce workflow. + +J'utilise nextflow.config à la racine du pipeline ici, qui est chargé automatiquement lorsque j'exécute Nextflow. Mais rappelez-vous, Nextflow peut charger des fichiers de configuration depuis plusieurs endroits. + +Si je vérifie avec la documentation Nextflow, je vais à Configuration, vous pouvez voir une liste de ces endroits et une priorité dans laquelle ils se chargent. + +D'accord. Vérifions que notre workflow s'exécute comme nous l'attendons. Je fais apparaître un terminal. Je fais nextflow run hello-config et j'appuie sur entrée. Nous devrions avoir ces quatre processus en cours d'exécution, se terminant par une commande cowpy. Effectivement, cela a bien fonctionné. Docker était activé, il a téléchargé Docker et a exécuté cowpy pour moi, comme à la fin du chapitre cinq. + +## 1. Déterminer quelle technologie d'empaquetage logiciel utiliser + +D'accord. Disons que je travaille sur un HPC et que je n'ai pas Docker installé. La meilleure chose à faire dans ce scénario serait d'utiliser Singularity ou Apptainer. Si je devais faire cela, j'irais dans le module cowpy et changerais ce conteneur pour utiliser l'image singularity comme je l'ai montré dans le chapitre précédent, avec un oras://, que vous pouvez également obtenir depuis Seqera Containers. + +J'irais ensuite dans nextflow.config, mettrais docker enabled à false et ferais singularity enabled equals true. Ou, si j'utilise Apptainer, apptainer enabled equals true et cela fonctionnerait. + +Nextflow prend également en charge d'autres technologies en plus des conteneurs, quelque chose que vous connaissez peut-être est conda. Ici, nous pouvons faire conda enabled equals true et mettre Docker à false. conda n'utilise pas la même directive container. Au lieu de cela, nous pouvons en ajouter une nouvelle ici appelée conda. Nous spécifions ensuite le paquet conda que nous voulons utiliser. C'est une bonne pratique d'être aussi spécifique que possible pour essayer de rendre le pipeline aussi reproductible que possible. Je vais donc spécifier le canal conda, conda-forge, puis cowpy, et la version exacte, qui était 1.1.5. + +Je pourrais aussi simplement écrire cowpy si je voulais, mais cela pourrait se résoudre en une version différente de cowpy lors de différentes exécutions du pipeline. + +La chose intéressante à ce sujet est que je n'ai pas du tout touché la directive docker. Cette image Docker est toujours là. Je fournis juste deux alternatives maintenant, et celles-ci peuvent être activées ou désactivées en utilisant uniquement un fichier de configuration. + +## 1.3. Exécuter le workflow pour vérifier qu'il peut utiliser Conda + +Conda est maintenant activé, alors essayons-le. + +Excellent. Il s'exécute et vous pouvez voir qu'il y a un message de Nextflow ici disant que Nextflow crée un environnement conda pour moi, et il utilise cet emplacement de cache. + +En arrière-plan, Nextflow exécute des commandes "conda create" pour moi pour créer un nouvel environnement conda isolé avec juste les paquets que je veux, puis installe et récupère ces paquets conda afin qu'il puisse exécuter le processus. + +Vous pouvez voir que cela a pris un peu de temps parce qu'il créait l'environnement et installait le logiciel pour la première fois. Cependant, il a mis en cache cet environnement, donc si j'exécute à nouveau la même commande Nextflow, cela devrait être beaucoup plus rapide car il réutilisera le même environnement conda. + +L'une des choses intéressantes à ce sujet est que ces directives peuvent être spécifiées au niveau du processus, pas seulement pour le workflow entier. Donc si vous le souhaitez, vous pouvez mélanger et assortir quelle technologie est utilisée pour différents processus. + +## 2. Allouer des ressources de calcul avec des directives de processus + +Le fichier de configuration Nextflow peut faire beaucoup plus que simplement l'empaquetage logiciel. Nous pouvons également indiquer à Nextflow comment exécuter réellement les étapes du pipeline. Un exemple est de dire à un système hôte quelles ressources doivent être mises à disposition pour chaque tâche en cours d'exécution. + +Par défaut, Nextflow ne donne pas grand-chose. Il donne un seul CPU et seulement deux gigaoctets de mémoire à chaque processus. + +C'est probablement quelque chose que nous voudrions changer, afin que les processus qui prennent beaucoup de temps à s'exécuter puissent avoir plus de ressources et s'exécuter plus rapidement, mais il peut être difficile de savoir quoi allouer à un processus. Nextflow a quelques astuces intéressantes pour vous aider avec cela. + +## 2.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources + +Exécutons à nouveau le workflow. Cette fois, je vais ajouter un argument supplémentaire, qui est -with-report. C'est une option Nextflow de base, donc c'est un seul trait d'union. Et puis le nom de fichier que je veux. Dans ce cas, je vais l'appeler report-config-one.html. + +Je vais exécuter à nouveau le workflow. Il va s'exécuter exactement comme avant, mais il va me donner un rapport d'aide supplémentaire, que vous pouvez voir apparaître maintenant ici dans la barre latérale. + +Je vais faire un clic droit sur ce fichier, cliquer sur télécharger, ce qui le télécharge de GitHub Codespaces vers mon système local, afin que je puisse facilement le visualiser dans le navigateur web ici. + +Ce rapport peut être généré pour n'importe quelle exécution Nextflow, et il contient beaucoup d'informations. Il commence en haut avec des métadonnées sur la commande utilisée, quand le workflow a été exécuté, combien de temps cela a pris, mais en faisant défiler vers le bas, nous obtenons des informations plus détaillées sur les ressources qui ont été utilisées par chaque étape du pipeline. + +Parce que chaque processus s'exécute plusieurs fois pour différentes tâches, nous avons une boîte à moustaches montrant la variation des ressources que nous avons utilisées pour chaque processus. + +Si je fais défiler un peu plus bas, je vois des informations similaires sur la mémoire utilisée et la durée des tâches. Également la lecture-écriture disque. + +Vous pouvez imaginer que pour un grand pipeline avec des tâches de longue durée, cela peut être très informatif sur la façon de peaufiner la configuration des ressources que vous demandez afin de ne pas en demander trop, mais aussi de fournir suffisamment pour qu'il s'exécute rapidement. + +Si je continue à faire défiler le rapport, nous voyons également un tableau de tâches, qui nous montre des informations détaillées sur chaque tâche unique qui a été exécutée dans le workflow. Cela inclut des informations telles que le script résolu qui a été exécuté. + +D'accord, revenons à notre fichier de configuration. Nous avons vu que nous n'avions vraiment pas besoin de beaucoup pour notre workflow, alors disons à Nextflow que nous n'avons besoin que d'un gigaoctet de mémoire pour chaque processus dans le workflow. + +Maintenant, lorsque nous le définissons ainsi au niveau du processus, cela s'applique à chaque processus du pipeline. + +## 2.3. Définir des allocations de ressources pour un processus individuel + +Pour les besoins de l'argument, supposons que cowpy fait vraiment beaucoup de calculs lourds et qu'il a besoin de plus de ressources que les autres tâches. Nous pouvons définir un bloc de configuration supplémentaire ici, qui s'applique uniquement à ce processus en utilisant withName cowpy. + +C'est ce qu'on appelle un sélecteur de configuration, et nous pouvons définir différents motifs ici pour correspondre à différents processus. Par exemple, je pourrais faire cow star. Je suis ensuite cela avec des accolades et donnons-lui deux gigaoctets de mémoire au lieu d'un et disons deux CPUs. + +Maintenant Nextflow donnera à chaque processus du workflow un gigaoctet à part cette requête, qui est plus spécifique. Donc elle l'écrase. Et juste pour les processus qui s'appellent cowpy, ils obtiendront deux gigs de mémoire et deux CPUs. + +Notez que Nextflow est intelligent concernant l'utilisation des ressources. Donc si vous commencez à mettre ces nombres à des valeurs plus élevées, vous verrez que Nextflow commence à mettre en file d'attente les soumissions de tâches l'une après l'autre, plutôt que de toutes les exécuter en parallèle, afin de ne pas sur-demander les ressources disponibles. + +## 2.4. Exécuter le workflow avec la configuration modifiée + +Essayons d'exécuter à nouveau un workflow et sauvegardons un nouveau rapport cette fois. + +D'accord, nous pouvons télécharger ce fichier et y jeter un œil. + +Oui, sans surprise, il ressemble exactement au même parce que c'est un workflow factice, qui ne fait rien de réel. Mais vous pouvez imaginer comment cette approche itérative de définition de limites et de réalisation de workflows réels avec ce type de rapports vous permet de faire une approche basée sur les preuves pour définir une configuration appropriée et vraiment tirer le meilleur parti des ressources de calcul dont vous disposez. + +Vous pouvez commencer à être vraiment intelligent à ce sujet. Nextflow a une capacité intégrée pour réessayer les échecs, et vous pouvez en profiter dans votre fichier de configuration en utilisant une closure comme ceci et en définissant dynamiquement les ressources qui sont mises à disposition. Donc ici, j'ai dit à Nextflow de multiplier ces deux gigaoctets par la tentative de réessai. Donc le deuxième réessai obtiendra quatre gigs, le troisième réessai obtiendra six gigs et ainsi de suite. Cela va un peu au-delà de la portée de cette formation, mais si vous êtes intéressé, consultez la documentation Nextflow, qui a une belle section sur la logique de réessai dynamique. + +## 2.5. Ajouter des limites de ressources + +Maintenant, une chose que vous pourriez remarquer à ce sujet est que ce genre de chose peut rendre assez facile de dépasser accidentellement les ressources disponibles sur votre système. Si vous demandez plus de ressources que disponibles, Nextflow lancera une erreur concernant votre configuration et arrêtera l'exécution. Pour éviter cela, vous pouvez utiliser quelque chose appelé limites de ressources. + +Sous la portée du processus, dans notre workflow, nous pouvons définir des limites de ressources comme ceci, qui prend un tableau, et nous pouvons spécifier la mémoire maximale, les CPUs et le temps qui sont disponibles sur ce système. + +Définir des valeurs élevées ici n'augmente pas la quantité de ressources demandées. Nous allons toujours utiliser un gigaoctet dans nos requêtes, mais cela signifie que si l'une de ces requêtes atteint 750, elle atteindra ce plafond et rien de plus ne sera demandé, ce qui signifie que Nextflow continuera à s'exécuter et ne plantera pas en raison de ressources indisponibles. + +C'est donc une bonne protection à utiliser, surtout si vous utilisez une logique dynamique avec votre allocation de ressources. + +L'autre situation où c'est vraiment utile est si vous utilisez des pipelines publics et non contrôlés par vous. Ils peuvent venir avec des valeurs par défaut de configuration, et Nextflow prendra automatiquement la bonne approche en plafonnant toutes les demandes de ressources pour s'exécuter sur votre système. + +D'accord, super. Nous avons parlé du logiciel. Nous avons parlé de l'allocation de ressources, et nous avons décrit différentes portées de configuration, à la fois pour tous les processus et pour des processus spécifiques. + +## 3. Utiliser un fichier de paramètres pour stocker les paramètres du workflow + +D'accord, ensuite nous allons tourner notre attention vers les paramètres. Nous pouvons définir des paramètres dans le fichier de configuration tout comme nous l'avons fait auparavant dans le script Nextflow. Donc params.greeting equals hello ou utiliser la portée params et définir foo equals bar. + +Et c'est génial pour définir des valeurs par défaut pour votre workflow. Cependant, lorsque vous exécutez des pipelines, il peut être agréable de spécifier les paramètres dans un fichier JSON ou YAML. + +Utiliser un fichier comme celui-ci est bien mieux que de spécifier des options en ligne de commande avec --. Car lorsque vous exécutez un workflow, vous devrez peut-être spécifier de nombreux paramètres et il peut être fastidieux de tous les écrire sur une seule CLI et sujet aux erreurs. De plus, il est peu probable que vous vous souveniez de tous les paramètres que vous avez utilisés, donc si vous les codez dans un fichier, il est plus facile de lancer à nouveau le workflow, en utilisant les mêmes paramètres à l'avenir. + +Nous avons un exemple de fichier ici appelé test-params, et vous pouvez voir que cela spécifie les trois paramètres que nous avons dans notre workflow avec trois valeurs différentes. Personnellement, je trouve YAML plus facile à écrire que JSON. Donc juste pour démontrer que cela fonctionne, je vais créer un nouveau fichier appelé test.yaml et copier ceux-ci, me débarrasser des guillemets et sauvegarder. + +Ces fichiers JSON et YAML peuvent être plus faciles à écrire car leur syntaxe est plus familière. Mais notez que ceux-ci sont uniquement pour les paramètres et ils ne prennent que la syntaxe clé-valeur comme ceci. + +## 3.1. Exécuter le workflow en utilisant un fichier de paramètres + +Essayons-le. Je fais la même commande qu'avant. Je me débarrasse du rapport et je vais faire -params-file test-params.yaml. + +Non, c'est une option Nextflow de base, donc c'est un seul trait d'union. + +D'accord. Il a exécuté le workflow et il a utilisé les paramètres dans ce fichier YAML au lieu que je les spécifie tous en ligne de commande. Cela peut sembler excessif juste pour cet exemple simple, mais vous pouvez imaginer que si vous avez 10 ou 20 paramètres différents, cela peut être pénible de les taper manuellement, et c'est juste beaucoup plus facile à éditer dans un éditeur de code et à conserver pour des raisons de reproductibilité. + +## 3. Déterminer quel(s) exécuteur(s) doit/doivent être utilisé(s) pour effectuer le travail + +D'accord. Nous avons parlé d'empaquetage logiciel avec Docker et conda. Nous avons parlé des exigences de ressources de processus avec les CPUs et la mémoire. Et nous avons parlé un peu de la façon de spécifier les paramètres lors de l'exécution des workflows. + +Les dernières parties de la configuration concernent vraiment l'exécution, l'infrastructure de calcul sous-jacente elle-même, et c'est le vrai joyau de la couronne de Nextflow : que nous pouvons exécuter ces mêmes workflows sur plusieurs infrastructures de calcul différentes. + +Je vais effectivement basculer vers le matériel de formation écrit pendant une seconde. Dans cette partie de la formation, nous pouvons voir quelques exemples différents de la façon dont différents exécuteurs, dans ce cas, des ordonnanceurs HPC, définissent les exigences de ressources nécessaires pour soumettre un travail. + +Donc pour Slurm, vous avez ces en-têtes SBATCH, qui définissent --mem et le nombre de CPU. Si vous utilisez PBS, vous avez des en-têtes différents, et si vous utilisez Grid Engine, vous avez des en-têtes différents encore. + +Vous pouvez imaginer que c'est encore plus différent si vous voulez exécuter sur le cloud, que ce soit AWS Batch, Google Cloud, Azure, ou plus. + +Chacune de ces infrastructures de calcul sous-jacentes est appelée un exécuteur et Nextflow sait comment parler à tous ces différents exécuteurs afin de soumettre des tâches avec la syntaxe correcte. + +La bonne nouvelle est que vous n'avez pas besoin de connaître cela. Tout ce que vous avez à faire est de dire à Nextflow quel exécuteur utiliser. + +## 3.1. Cibler un backend différent + +Nous retournons à notre fichier de configuration et au processus, nous faisons executor, et je vais taper local. + +Local est en fait la valeur par défaut, si vous ne spécifiez aucun autre exécuteur, local est ce qui sera utilisé, et cela signifie simplement votre système hôte, où que vous ayez lancé Nextflow. + +Je pourrais spécifier à la place, slurm. Et cela soumettrait des tâches Slurm, ou je pourrais dire awsbatch, et cela soumettrait des tâches à AWS Batch. + +Vous avez besoin de configuration supplémentaire dans certains cas, par exemple, l'exécution sur le cloud nécessitera certaines informations d'identification, mais vraiment c'est le cœur de cela, et cela peut être aussi simple qu'une ou deux lignes de configuration pour exécuter votre workflow dans un environnement de calcul complètement différent. + +Même si nous exécutons sur un système simple dans Codespaces, je peux toujours jouer avec cela un peu et prétendre que nous exécutons sur Slurm. Si je lance ensuite à nouveau le workflow, nextflow run hello-config, cela échouera car il ne pourra pas soumettre de tâches à Slurm. Mais nous pouvons toujours aller dans les répertoires de travail et voir ce que Nextflow a fait. Donc si nous allons dans ce répertoire de travail et regardons .command.run, vous pouvez voir en haut de ce fichier, nous avons maintenant ces lignes d'en-tête sbatch, qui ont essayé de spécifier les ressources nécessaires pour la tâche Slurm. + +## 4. Utiliser des profils pour sélectionner des configurations prédéfinies + +D'accord, nous y sommes presque. La dernière partie de ce chapitre concerne les profils de configuration. Si vous exécutez votre pipeline sur plusieurs systèmes différents, il pourrait être ennuyeux d'avoir tous ces fichiers de configuration Nextflow différents, que vous devez spécifier à chaque fois. + +Au lieu de cela, vous pouvez encoder des groupes de configuration dans votre fichier de configuration Nextflow, et activer ou désactiver ces groupes en utilisant un indicateur de profil. Voyons à quoi cela ressemble. + +## 4.1. Créer des profils pour basculer entre le développement local et l'exécution sur HPC + +Nous allons créer deux profils dans notre exemple ici, un pour mon ordinateur portable et un pour un système HPC plus lourd. Je vais tricher un peu et simplement copier le code du matériel de formation et le mettre ici. + +Nous avons une nouvelle portée appelée profiles, puis nous avons un nom pour chaque profil, qui peut être n'importe quoi. Et à l'intérieur de cela, nous avons une configuration, qui ressemble exactement à la configuration de niveau supérieur que nous avons déjà écrite. Donc encore, nous avons la portée process, la portée docker. + +Sur le profil appelé my_laptop, je dis d'exécuter en utilisant l'exécuteur local, donc sur mon système hôte et d'utiliser Docker. + +Sur le profil university_hpc ici, je dis d'utiliser Slurm pour soumettre des tâches, d'utiliser conda au lieu de Docker, et je spécifie différentes limites de ressources, qui peuvent correspondre à la taille du système de nœuds sur le HPC que j'utilise. + +Par défaut, aucune de cette configuration ne sera utilisée lorsque j'exécute Nextflow, je dois spécifier que je veux utiliser l'un de ces profils. + +## 4.2. Exécuter le workflow avec un profil + +Faisons nextflow run hello-config. Et je vais faire -profile, trait d'union simple parce que c'est une option Nextflow de base. Et puis le nom que je lui ai donné, qui est my_laptop. Nextflow devrait maintenant utiliser le bloc de configuration qui a été spécifié dans ce profil de configuration, et l'appliquer lorsqu'il exécute Nextflow. Si je voulais utiliser l'autre bloc de configuration, je n'ai qu'à changer ce nom de profil. Beaucoup plus facile à retenir. Beaucoup plus facile à utiliser. + +## 4.3. Créer un profil de test + +Notez, les profils peuvent avoir n'importe quel type de configuration, donc cela ne doit pas être lié à votre environnement d'exécution. Par exemple, créons un nouveau profil ici, qui a un ensemble de paramètres. Nous pouvons changer cela en tux et changer en my profile, et maintenant lorsque nous faisons profile test, cela va spécifier ces paramètres, qui écraseront les paramètres qui sont spécifiés au niveau supérieur du workflow. + +Lorsque vous exécutez Nextflow, vous pouvez enchaîner plusieurs profils et ils seront appliqués en séquence. + +## 4.4. Exécuter le workflow localement avec le profil de test + +Donc je peux prendre la commande précédente et faire virgule test. Cela appliquera d'abord la configuration my_laptop, puis il appliquera la configuration test. S'il y a un chevauchement, alors le profil à droite écrasera toute configuration dans les profils précédents. Si j'appuie sur entrée, voyons ce qui se passe. + +D'accord, nous avons un nouveau fichier de résultats ici. Vous pouvez voir le My Profile, que j'ai spécifié comme l'une des options. Et nous pouvons également voir cowpy, my profile, et effectivement, il y a tux. Donc cela a fonctionné. + +## Récapitulatif + +D'accord ! Incroyable. C'est tout. Vous avez réussi jusqu'à la fin du cours. Vous obtenez un peu de confettis de célébration. Bravo d'avoir terminé ce chapitre. + +[Transcription vidéo suivante :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/fr/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/fr/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..ba352561c8 --- /dev/null +++ b/docs/fr/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Prochaines Étapes - Transcription + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notes importantes" + + Cette page affiche uniquement la transcription. Pour les instructions détaillées étape par étape, retournez au [matériel de formation](../05_hello_containers.md). + +## Bienvenue + +Félicitations, vous l'avez fait. Vous avez terminé le premier cours de formation Nextflow, appelé Hello Nextflow. + +Bravo. Merci d'avoir persévéré et nous apprécions vraiment le temps et les efforts que vous avez consacrés à l'apprentissage de Nextflow, et nous espérons sincèrement que cela vous sera utile dans votre travail. + +## Prochaines Étapes + +Pour les prochaines étapes, gardez un œil sur le portail de formation : training.nextflow.io. Nous publions constamment de nouveaux contenus de formation et les actualisons également. Vous pourrez donc peut-être trouver des formations plus avancées, ou des formations spécifiques à un domaine de recherche qui vous intéresse. + +Plus particulièrement, consultez la page Nextflow for Science. Elle propose une série de cours courts qui sont autonomes et qui étendent ce que vous avez appris dans Hello Nextflow à des cas d'usage spécifiques. + +Il y en a un pour la génomique et également un pour le RNA-seq. Nous espérons en proposer d'autres prochainement. + +## Quêtes Secondaires + +Il y a beaucoup de sujets dont nous aurions pu parler dans Hello Nextflow, mais qui auraient été trop détaillés. Certains de ces sujets sont intégrés dans les Quêtes Secondaires, qui sont de courts cours sur des thématiques spécifiques. + +Il existe également les cours plus complets de formation fondamentale et de formation avancée, qui peuvent inclure du contenu qui vous intéresse. + +## nf-core + +Cela a été mentionné une ou deux fois dans ce cours, mais consultez définitivement le projet nf-core. Il existe plus d'une centaine de pipelines pour différents types de données, il est donc tout à fait possible que vous n'ayez pas besoin de construire votre propre pipeline. + +Il existe également près de mille cinq cents modules de processus où, si vous utilisez les outils de développement nf-core, vous pouvez créer un pipeline et importer ces modules en quelques secondes. + +## Seqera Platform + +Enfin, une petite promotion pour Seqera Platform. C'est sans aucun doute la meilleure façon d'exécuter Nextflow en pratique, c'est une plateforme basée sur le cloud, mais vous connectez votre propre infrastructure de calcul, que ce soit votre propre compte cloud sur AWS, Google Batch ou Azure, ou même votre propre HPC. Le niveau gratuit est disponible pour tout le monde, et si vous êtes universitaire, vous pouvez postuler à notre programme académique pour un accès gratuit de niveau professionnel. + +Seqera Platform va au-delà d'une simple interface graphique pour lancer et surveiller les workflows. Il existe également des outils supplémentaires tels que Data Studios pour exécuter des sessions interactives, et des outils fondamentaux tels que Fusion, qui offre un accès plus rapide et moins coûteux aux données dans le cloud. + +## Support et événements + +N'oubliez pas, si vous rencontrez des difficultés, rendez-vous simplement sur community.seqera.io. Notre forum y est très actif, la communauté Nextflow est extrêmement forte et il y a presque toujours des personnes disponibles prêtes à vous aider, que ce soit pour la formation ou pour tout ce qui concerne votre utilisation quotidienne de Nextflow. + +Et bien sûr, une excellente prochaine étape consiste à rejoindre l'un de nos événements communautaires, qu'il s'agisse d'un hackathon nf-core ou de l'un des événements Nextflow Summit. Ils sont très amusants, et ce serait vraiment agréable de vous y rencontrer et de discuter de votre utilisation de Nextflow. + +## Remerciements + +Je tiens à remercier chaleureusement tous ceux qui ont participé à la rédaction de ce matériel de formation. Je l'ai présenté, mais en réalité, tout le travail a été effectué par l'équipe de formation chez Seqera. Plus particulièrement Geraldine, qui a consacré énormément de travail à la réécriture de ce matériel. + +Également, Marcel, Ken, Adam, John, d'autres membres de l'équipe de développement scientifique et d'autres personnes de la communauté. + +## Questionnaire de satisfaction + +Maintenant que vous avez terminé le cours, nous aimerions savoir ce que vous en avez pensé. Sur training.nextflow.io, vous trouverez un questionnaire de satisfaction sous la section Hello Nextflow. + +Il ne comporte que quatre questions mais c'est vraiment important pour nous. Ne serait-ce que pour nous indiquer approximativement combien de personnes suivent la formation. Cela nous indique également si vous l'avez appréciée et si vous avez des suggestions, n'hésitez pas à les déposer à la fin. Nous lisons chaque soumission. + +Si vous repérez des erreurs, tout est open source sur GitHub, vous pouvez donc créer une issue ou faire une pull request ou nous laisser un message sur le forum. Nous aimerions beaucoup savoir ce que vous en avez pensé et comment nous pourrions l'améliorer. Merci encore. Au plaisir de vous revoir bientôt. diff --git a/docs/fr/docs/hello_nf-core/00_orientation.md b/docs/fr/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..89bc55b6da --- /dev/null +++ b/docs/fr/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Premiers pas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Démarrer un environnement de formation + +Pour utiliser l'environnement préconstruit que nous fournissons sur GitHub Codespaces, cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous. Pour d'autres options, consultez [Options d'environnement](../envsetup/index.md). + +Nous vous recommandons d'ouvrir l'environnement de formation dans un nouvel onglet ou une nouvelle fenêtre de navigateur (utilisez le clic droit, ctrl+clic ou cmd+clic selon votre équipement) afin de pouvoir continuer à lire pendant le chargement de l'environnement. +Vous devrez garder ces instructions ouvertes en parallèle pour suivre le cours. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Notions de base de l'environnement + +Cet environnement de formation contient tous les logiciels, le code et les données nécessaires pour suivre le cours de formation, vous n'avez donc rien à installer vous-même. + +Le codespace est configuré avec une interface VSCode, qui comprend un explorateur de système de fichiers, un éditeur de code et un terminal shell. +Toutes les instructions données pendant le cours (par exemple « ouvrir le fichier », « modifier le code » ou « exécuter cette commande ») font référence à ces trois parties de l'interface VSCode, sauf indication contraire. + +Si vous suivez ce cours par vous-même, veuillez vous familiariser avec les [notions de base de l'environnement](../envsetup/01_setup.md) pour plus de détails. + +### Exigences de version + +Cette formation est conçue pour **Nextflow 25.10.2** ou version ultérieure **avec l'analyseur de syntaxe v2 DÉSACTIVÉ**. + +#### Si vous utilisez notre environnement de formation : + +Vous DEVEZ exécuter la commande suivante avant d'aller plus loin : + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Si vous utilisez un environnement local ou personnalisé : + +Veuillez vous assurer d'utiliser les paramètres corrects comme documenté [ici](../info/nxf_versions.md). + +La formation nécessite en outre **nf-core tools 3.4.1**. +Si vous utilisez une version différente des outils nf-core, vous pourriez rencontrer des difficultés à suivre. + +Vous pouvez vérifier quelle version est installée dans votre environnement à l'aide de la commande `nf-core --version`. + +## Préparez-vous à travailler + +Une fois votre codespace en cours d'exécution, vous devez faire deux choses avant de vous plonger dans la formation : définir votre répertoire de travail pour ce cours spécifique et examiner les ressources fournies. + +### Définir le répertoire de travail + +Par défaut, le codespace s'ouvre avec le répertoire de travail défini à la racine de tous les cours de formation, mais pour ce cours, nous travaillerons dans le répertoire `hello-nf-core/`. + +Changez de répertoire maintenant en exécutant cette commande dans le terminal : + +```bash +cd hello-nf-core/ +``` + +!!! tip "Astuce" + + Si pour une raison quelconque vous sortez de ce répertoire (par exemple, votre codespace se met en veille), vous pouvez toujours utiliser le chemin complet pour y revenir, en supposant que vous exécutez ceci dans l'environnement de formation Github Codespaces : + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Maintenant, jetons un coup d'œil au contenu de ce répertoire. + +### Explorer les ressources fournies + +Vous pouvez explorer le contenu de ce répertoire en utilisant l'explorateur de fichiers sur le côté gauche de l'espace de travail de formation. +Alternativement, vous pouvez utiliser la commande `tree`. + +Tout au long du cours, nous utilisons la sortie de `tree` pour représenter la structure et le contenu des répertoires sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 2 +``` + +??? abstract "Contenu du répertoire" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Cliquez sur la case colorée pour développer la section et afficher son contenu. +Nous utilisons des sections repliables comme celle-ci pour inclure la sortie de commande attendue de manière concise. + +- **Le fichier `greetings.csv`** est un CSV contenant des données colonnes minimales que nous utilisons à des fins de test. + +- **Le répertoire `original-hello`** contient une copie du code source produit en suivant la série de formation complète Hello Nextflow (avec Docker activé). + +- **Le répertoire `solutions`** contient les scripts de workflow complétés qui résultent de chaque étape du cours. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre les problèmes éventuels. + +## Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon environnement est opérationnel +- [ ] Je me suis assuré que l'analyseur de syntaxe est défini sur **v1** +- [ ] J'ai défini mon répertoire de travail de manière appropriée + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +**Pour continuer vers la Partie 1, cliquez sur la flèche dans le coin inférieur droit de cette page.** diff --git a/docs/fr/docs/hello_nf-core/01_run_demo.md b/docs/fr/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..4d5488091d --- /dev/null +++ b/docs/fr/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# Partie 1 : Exécuter un pipeline de démonstration + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette première partie de la formation Hello nf-core, nous vous montrons comment trouver et essayer un pipeline nf-core, comprendre comment le code est organisé, et reconnaître en quoi il diffère du code Nextflow simple tel que présenté dans [Hello Nextflow](../hello_nextflow/index.md). + +Nous allons utiliser un pipeline appelé nf-core/demo qui est maintenu par le projet nf-core dans le cadre de son inventaire de pipelines pour démontrer la structure du code et le fonctionnement des outils. + +Assurez-vous que votre répertoire de travail est défini sur `hello-nf-core/` comme indiqué sur la page [Premiers pas](./00_orientation.md). + +--- + +## 1. Trouver et récupérer le pipeline nf-core/demo + +Commençons par localiser le pipeline nf-core/demo sur le site web du projet à l'adresse [nf-co.re](https://nf-co.re), qui centralise toutes les informations telles que : la documentation générale et les articles d'aide, la documentation pour chacun des pipelines, les articles de blog, les annonces d'événements, etc. + +### 1.1. Trouver le pipeline sur le site web + +Dans votre navigateur web, allez sur [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) et tapez `demo` dans la barre de recherche. + +![résultats de recherche](./img/search-results.png) + +Cliquez sur le nom du pipeline, `demo`, pour accéder à la page de documentation du pipeline. + +Chaque pipeline publié dispose d'une page dédiée qui comprend les sections de documentation suivantes : + +- **Introduction :** Une introduction et un aperçu du pipeline +- **Usage :** Descriptions de la manière d'exécuter le pipeline +- **Parameters :** Paramètres du pipeline regroupés avec descriptions +- **Output :** Descriptions et exemples des fichiers de sortie attendus +- **Results :** Exemples de fichiers de sortie générés à partir du jeu de données de test complet +- **Releases & Statistics :** Historique des versions du pipeline et statistiques + +Chaque fois que vous envisagez d'adopter un nouveau pipeline, vous devez d'abord lire attentivement la documentation du pipeline pour comprendre ce qu'il fait et comment il doit être configuré avant de tenter de l'exécuter. + +Jetez-y un coup d'œil maintenant et voyez si vous pouvez découvrir : + +- Quels outils le pipeline exécutera (Vérifiez l'onglet : `Introduction`) +- Quelles entrées et paramètres le pipeline accepte ou requiert (Vérifiez l'onglet : `Parameters`) +- Quelles sont les sorties produites par le pipeline (Vérifiez l'onglet : `Output`) + +#### 1.1.1. Aperçu du pipeline + +L'onglet `Introduction` fournit un aperçu du pipeline, incluant une représentation visuelle (appelée carte de métro) et une liste des outils qui sont exécutés dans le cadre du pipeline. + +![carte de métro du pipeline](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Exemple de ligne de commande + +La documentation fournit également un exemple de fichier d'entrée (discuté plus en détail ci-dessous) et un exemple de ligne de commande. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Vous remarquerez que l'exemple de commande ne spécifie PAS de fichier de workflow, juste la référence au dépôt du pipeline, `nf-core/demo`. + +Lorsqu'il est invoqué de cette manière, Nextflow supposera que le code est organisé d'une certaine manière. +Récupérons le code afin de pouvoir examiner cette structure. + +### 1.2. Récupérer le code du pipeline + +Une fois que nous avons déterminé que le pipeline semble convenir à nos besoins, essayons-le. +Heureusement, Nextflow facilite la récupération des pipelines à partir de dépôts correctement formatés sans avoir à télécharger quoi que ce soit manuellement. + +Retournons au terminal et exécutons ce qui suit : + +```bash +nextflow pull nf-core/demo +``` + +??? success "Sortie de la commande" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow effectue un `pull` du code du pipeline, c'est-à-dire qu'il télécharge le dépôt complet sur votre disque local. + +Pour être clair, vous pouvez faire cela avec n'importe quel pipeline Nextflow qui est correctement configuré dans GitHub, pas seulement les pipelines nf-core. +Cependant, nf-core est la plus grande collection open-source de pipelines Nextflow. + +Vous pouvez demander à Nextflow de vous fournir une liste des pipelines que vous avez récupérés de cette manière : + +```bash +nextflow list +``` + +??? success "Sortie de la commande" + + ```console + nf-core/demo + ``` + +Vous remarquerez que les fichiers ne se trouvent pas dans votre répertoire de travail actuel. +Par défaut, Nextflow les enregistre dans `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Contenu du répertoire" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + Le chemin complet peut différer sur votre système si vous n'utilisez pas notre environnement de formation. + +Nextflow garde intentionnellement le code source téléchargé 'à l'écart' sur le principe que ces pipelines doivent être utilisés davantage comme des bibliothèques que comme du code avec lequel vous interagiriez directement. + +Cependant, pour les besoins de cette formation, nous voulons pouvoir explorer et voir ce qu'il contient. +Donc, pour faciliter cela, créons un lien symbolique vers cet emplacement depuis notre répertoire de travail actuel. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Cela crée un raccourci qui facilite l'exploration du code que nous venons de télécharger. + +```bash +tree -L 2 pipelines +``` + +```console title="Contenu du répertoire" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Maintenant, nous pouvons plus facilement jeter un coup d'œil au code source si nécessaire. + +Mais d'abord, essayons d'exécuter notre premier pipeline nf-core ! + +### À retenir + +Vous savez maintenant comment trouver un pipeline via le site web nf-core et récupérer une copie locale du code source. + +### Et ensuite ? + +Apprenez comment essayer un pipeline nf-core avec un minimum d'effort. + +--- + +## 2. Essayer le pipeline avec son profil de test + +De manière pratique, chaque pipeline nf-core est fourni avec un profil de test. +Il s'agit d'un ensemble minimal de paramètres de configuration permettant au pipeline de s'exécuter en utilisant un petit jeu de données de test hébergé dans le dépôt [nf-core/test-datasets](https://github.com/nf-core/test-datasets). +C'est un excellent moyen d'essayer rapidement un pipeline à petite échelle. + +!!! note + + Le système de profils de configuration de Nextflow vous permet de basculer facilement entre différents moteurs de conteneurs ou environnements d'exécution. + Pour plus de détails, consultez [Hello Nextflow Partie 6 : Configuration](../hello_nextflow/06_hello_config.md). + +### 2.1. Examiner le profil de test + +C'est une bonne pratique de vérifier ce que spécifie le profil de test d'un pipeline avant de l'exécuter. +Le profil `test` pour `nf-core/demo` se trouve dans le fichier de configuration `conf/test.config` et est présenté ci-dessous. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Données d'entrée + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Vous remarquerez tout de suite que le bloc de commentaires en haut inclut un exemple d'utilisation montrant comment exécuter le pipeline avec ce profil de test. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Les seules choses que nous devons fournir sont ce qui est montré entre crochets dans l'exemple de commande : `<docker/singularity>` et `<OUTDIR>`. + +Pour rappel, `<docker/singularity>` fait référence au choix du système de conteneurs. Tous les pipelines nf-core sont conçus pour être utilisables avec des conteneurs (Docker, Singularity, etc.) afin de garantir la reproductibilité et d'éliminer les problèmes d'installation de logiciels. +Nous devrons donc spécifier si nous voulons utiliser Docker ou Singularity pour tester le pipeline. + +La partie `--outdir <OUTDIR>` fait référence au répertoire où Nextflow écrira les sorties du pipeline. +Nous devons lui fournir un nom, que nous pouvons simplement inventer. +S'il n'existe pas déjà, Nextflow le créera pour nous lors de l'exécution. + +Passant à la section après le bloc de commentaires, le profil de test nous montre ce qui a été préconfiguré pour les tests : plus particulièrement, le paramètre `input` est déjà défini pour pointer vers un jeu de données de test, nous n'avons donc pas besoin de fournir nos propres données. +Si vous suivez le lien vers l'entrée préconfigurée, vous verrez qu'il s'agit d'un fichier csv contenant des identifiants d'échantillons et des chemins de fichiers pour plusieurs échantillons expérimentaux. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +C'est ce qu'on appelle une feuille d'échantillons (samplesheet), et c'est la forme d'entrée la plus courante pour les pipelines nf-core. + +!!! note + + Ne vous inquiétez pas si vous n'êtes pas familier avec les formats et types de données, ce n'est pas important pour la suite. + +Cela confirme donc que nous avons tout ce dont nous avons besoin pour essayer le pipeline. + +### 2.2. Exécuter le pipeline + +Décidons d'utiliser Docker pour le système de conteneurs et `demo-results` comme répertoire de sortie, et nous sommes prêts à exécuter la commande de test : + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Si votre sortie correspond à celle-ci, félicitations ! Vous venez d'exécuter votre premier pipeline nf-core. + +Vous remarquerez qu'il y a beaucoup plus de sortie console que lorsque vous exécutez un pipeline Nextflow basique. +Il y a un en-tête qui inclut un résumé de la version du pipeline, des entrées et sorties, et quelques éléments de configuration. + +!!! note + + Votre sortie affichera des horodatages, des noms d'exécution et des chemins de fichiers différents, mais la structure globale et l'exécution des processus devraient être similaires. + +Passons maintenant à la sortie d'exécution, et jetons un coup d'œil aux lignes qui nous indiquent quels processus ont été exécutés : + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Cela nous indique que trois processus ont été exécutés, correspondant aux trois outils présentés dans la page de documentation du pipeline sur le site web nf-core : FASTQC, SEQTK_TRIM et MULTIQC. + +Les noms complets des processus tels qu'affichés ici, comme `NFCORE_DEMO:DEMO:MULTIQC`, sont plus longs que ce que vous avez pu voir dans le matériel d'introduction Hello Nextflow. +Ils incluent les noms de leurs workflows parents et reflètent la modularité du code du pipeline. +Nous entrerons plus en détail à ce sujet dans un instant. + +### 2.3. Examiner les sorties du pipeline + +Enfin, jetons un coup d'œil au répertoire `demo-results` produit par le pipeline. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Contenu du répertoire" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Cela peut sembler beaucoup. +Pour en savoir plus sur les sorties du pipeline `nf-core/demo`, consultez sa [page de documentation](https://nf-co.re/demo/1.0.2/docs/output/). + +À ce stade, ce qui est important d'observer est que les résultats sont organisés par module, et il y a en plus un répertoire appelé `pipeline_info` contenant divers rapports horodatés sur l'exécution du pipeline. + +Par exemple, le fichier `execution_timeline_*` vous montre quels processus ont été exécutés, dans quel ordre et combien de temps ils ont pris pour s'exécuter : + +![rapport de chronologie d'exécution](./img/execution_timeline.png) + +!!! note + + Ici, les tâches n'ont pas été exécutées en parallèle car nous fonctionnons sur une machine minimaliste dans Github Codespaces. + Pour voir ces tâches s'exécuter en parallèle, essayez d'augmenter l'allocation CPU de votre codespace et les limites de ressources dans la configuration de test. + +Ces rapports sont générés automatiquement pour tous les pipelines nf-core. + +### À retenir + +Vous savez comment exécuter un pipeline nf-core en utilisant son profil de test intégré et où trouver ses sorties. + +### Et ensuite ? + +Apprenez comment le code du pipeline est organisé. + +--- + +## 3. Examiner la structure du code du pipeline + +Maintenant que nous avons exécuté avec succès le pipeline en tant qu'utilisateurs, changeons de perspective pour voir comment les pipelines nf-core sont structurés en interne. + +Le projet nf-core applique des directives strictes sur la façon dont les pipelines sont structurés, et sur la façon dont le code est organisé, configuré et documenté. +Comprendre comment tout cela est organisé est la première étape vers le développement de vos propres pipelines compatibles nf-core, que nous aborderons dans la Partie 2 de ce cours. + +Jetons un coup d'œil à la façon dont le code du pipeline est organisé dans le dépôt `nf-core/demo`, en utilisant le lien symbolique `pipelines` que nous avons créé précédemment. + +Vous pouvez soit utiliser `tree` soit utiliser l'explorateur de fichiers pour trouver et ouvrir le répertoire `nf-core/demo`. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Contenu du répertoire" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Il se passe beaucoup de choses là-dedans, nous allons donc aborder cela étape par étape. + +Tout d'abord, notons qu'au niveau supérieur, vous pouvez trouver un fichier README avec des informations récapitulatives, ainsi que des fichiers accessoires qui résument les informations du projet telles que les licences, les directives de contribution, les citations et le code de conduite. +La documentation détaillée du pipeline se trouve dans le répertoire `docs`. +Tout ce contenu est utilisé pour générer les pages web sur le site web nf-core de manière programmatique, elles sont donc toujours à jour avec le code. + +Maintenant, pour le reste, nous allons diviser notre exploration en trois étapes : + +1. Composants du code du pipeline (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Configuration du pipeline +3. Entrées et validation + +Commençons par les composants du code du pipeline. +Nous allons nous concentrer sur la hiérarchie des fichiers et l'organisation structurelle, plutôt que de plonger dans le code à l'intérieur de fichiers individuels. + +### 3.1. Composants du code du pipeline + +L'organisation standard du code d'un pipeline nf-core suit une structure modulaire conçue pour maximiser la réutilisation du code, comme introduit dans [Hello Modules](../hello_nextflow/04_hello_modules.md), Partie 4 du cours [Hello Nextflow](../hello_nextflow/index.md), bien que dans le véritable style nf-core, cela soit implémenté avec un peu de complexité supplémentaire. +Plus précisément, les pipelines nf-core font un usage abondant des subworkflows, c'est-à-dire des scripts de workflow qui sont importés par un workflow parent. + +Cela peut sembler un peu abstrait, alors jetons un coup d'œil à la façon dont cela est utilisé en pratique dans le pipeline `nf-core/demo`. + +!!! note + + Nous ne passerons pas en revue le code réel de la _façon_ dont ces composants modulaires sont connectés, car il y a une complexité supplémentaire associée à l'utilisation des subworkflows qui peut être déroutante, et comprendre cela n'est pas nécessaire à ce stade de la formation. + Pour l'instant, nous allons nous concentrer sur l'organisation générale et la logique. + +#### 3.1.1. Vue d'ensemble générale + +Voici à quoi ressemblent les relations entre les composants de code pertinents pour le pipeline `nf-core/demo` : + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +Il y a un script dit _point d'entrée_ appelé `main.nf`, qui agit comme une enveloppe pour deux types de workflows imbriqués : le workflow contenant la logique d'analyse réelle, situé sous `workflows/` et appelé `demo.nf`, et un ensemble de workflows de gestion situés sous `subworkflows/`. +Le workflow `demo.nf` fait appel aux **modules** situés sous `modules/` ; ceux-ci contiennent les **processus** qui effectueront les étapes d'analyse réelles. + +!!! note + + Les subworkflows ne sont pas limités aux fonctions de gestion, et ils peuvent utiliser des modules de processus. + + Le pipeline `nf-core/demo` présenté ici se trouve être du côté le plus simple du spectre, mais d'autres pipelines nf-core (tels que `nf-core/rnaseq`) utilisent des subworkflows qui sont impliqués dans l'analyse réelle. + +Maintenant, passons en revue ces composants à tour de rôle. + +#### 3.1.2. Le script de point d'entrée : `main.nf` + +Le script `main.nf` est le point d'entrée à partir duquel Nextflow démarre lorsque nous exécutons `nextflow run nf-core/demo`. +Cela signifie que lorsque vous exécutez `nextflow run nf-core/demo` pour exécuter le pipeline, Nextflow trouve et exécute automatiquement le script `main.nf`. +Cela fonctionne pour tout pipeline Nextflow qui suit cette convention de nommage et cette structure, pas seulement les pipelines nf-core. + +L'utilisation d'un script de point d'entrée facilite l'exécution de subworkflows de 'gestion' standardisés avant et après l'exécution du script d'analyse réel. +Nous examinerons ceux-ci après avoir passé en revue le workflow d'analyse réel et ses modules. + +#### 3.1.3. Le script d'analyse : `workflows/demo.nf` + +Le workflow `workflows/demo.nf` est l'endroit où la logique centrale du pipeline est stockée. +Il est structuré de la même manière qu'un workflow Nextflow normal, sauf qu'il est conçu pour être appelé depuis un workflow parent, ce qui nécessite quelques fonctionnalités supplémentaires. +Nous couvrirons les différences pertinentes dans la partie suivante de ce cours, lorsque nous aborderons la conversion du simple pipeline Hello de Hello Nextflow en une forme compatible nf-core. + +Le workflow `demo.nf` fait appel aux **modules** situés sous `modules/`, que nous examinerons ensuite. + +!!! note + + Certains workflows d'analyse nf-core affichent des niveaux supplémentaires d'imbrication en appelant des subworkflows de niveau inférieur. + Ceci est principalement utilisé pour encapsuler deux modules ou plus qui sont couramment utilisés ensemble dans des segments de pipeline facilement réutilisables. + Vous pouvez voir quelques exemples en parcourant les [subworkflows nf-core](https://nf-co.re/subworkflows/) disponibles sur le site web nf-core. + + Lorsque le script d'analyse utilise des subworkflows, ceux-ci sont stockés sous le répertoire `subworkflows/`. + +#### 3.1.4. Les modules + +Les modules sont l'endroit où réside le code des processus, comme décrit dans la [Partie 4 du cours de formation Hello Nextflow](../hello_nextflow/04_hello_modules.md). + +Dans le projet nf-core, les modules sont organisés selon une structure imbriquée à plusieurs niveaux qui reflète à la fois leur origine et leur contenu. +Au niveau supérieur, les modules sont différenciés comme étant soit `nf-core` soit `local` (ne faisant pas partie du projet nf-core), puis placés dans un répertoire nommé d'après le(s) outil(s) qu'ils encapsulent. +Si l'outil appartient à une boîte à outils (c'est-à-dire un package contenant plusieurs outils), il y a un niveau de répertoire intermédiaire nommé d'après la boîte à outils. + +Vous pouvez voir cela appliqué en pratique aux modules du pipeline `nf-core/demo` : + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Contenu du répertoire" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Ici, vous voyez que les modules `fastqc` et `multiqc` se situent au niveau supérieur au sein des modules `nf-core`, alors que le module `trim` se trouve sous la boîte à outils à laquelle il appartient, `seqtk`. +Dans ce cas, il n'y a pas de modules `local`. + +Le fichier de code du module décrivant le processus s'appelle toujours `main.nf`, et est accompagné de tests et de fichiers `.yml` que nous ignorerons pour l'instant. + +Pris ensemble, le workflow de point d'entrée, le workflow d'analyse et les modules sont suffisants pour exécuter les parties 'intéressantes' du pipeline. +Cependant, nous savons qu'il y a aussi des subworkflows de gestion là-dedans, alors regardons-les maintenant. + +#### 3.1.5. Les subworkflows de gestion + +Comme les modules, les subworkflows sont différenciés en répertoires `local` et `nf-core`, et chaque subworkflow a sa propre structure de répertoire imbriquée avec son propre script `main.nf`, ses tests et son fichier `.yml`. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Contenu du répertoire" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Comme noté ci-dessus, le pipeline `nf-core/demo` n'inclut aucun subworkflow spécifique à l'analyse, donc tous les subworkflows que nous voyons ici sont des workflows dits de 'gestion' ou 'utilitaires', comme indiqué par le préfixe `utils_` dans leurs noms. +Ces subworkflows sont ce qui produit le joli en-tête nf-core dans la sortie console, parmi d'autres fonctions accessoires. + +!!! tip + + Mis à part leur modèle de nommage, une autre indication que ces subworkflows n'effectuent aucune fonction véritablement liée à l'analyse est qu'ils n'appellent aucun processus du tout. + +Ceci complète le tour d'horizon des composants de code de base qui constituent le pipeline `nf-core/demo`. +Maintenant, jetons un coup d'œil aux éléments restants que vous devriez connaître un peu avant de plonger dans le développement : la configuration du pipeline et la validation des entrées. + +### 3.2. Configuration du pipeline + +Vous avez appris précédemment que Nextflow offre de nombreuses options pour configurer l'exécution du pipeline, que ce soit en termes d'entrées et de paramètres, de ressources de calcul et d'autres aspects d'orchestration. +Le projet nf-core applique des directives hautement standardisées pour la configuration du pipeline qui visent à s'appuyer sur les options de personnalisation flexibles de Nextflow d'une manière qui offre une plus grande cohérence et maintenabilité entre les pipelines. + +Le fichier de configuration central `nextflow.config` est utilisé pour définir les valeurs par défaut des paramètres et d'autres options de configuration. +La majorité de ces options de configuration sont appliquées par défaut tandis que d'autres (par exemple, les profils de dépendances logicielles) sont incluses comme profils optionnels. + +Il existe plusieurs fichiers de configuration supplémentaires qui sont stockés dans le dossier `conf` et qui peuvent être ajoutés à la configuration par défaut ou optionnellement comme profils : + +- `base.config` : Un fichier de configuration 'de base', approprié pour une utilisation générale sur la plupart des environnements de calcul haute performance. Cela définit de larges catégories d'utilisation des ressources, par exemple, qui sont pratiques à appliquer aux modules. +- `modules.config` : Directives et arguments de modules supplémentaires. +- `test.config` : Un profil pour exécuter le pipeline avec des données de test minimales, que nous avons utilisé lorsque nous avons exécuté le pipeline de démonstration. +- `test_full.config` : Un profil pour exécuter le pipeline avec un jeu de données de test de taille complète. + +Nous toucherons quelques-uns de ces fichiers plus tard dans le cours. + +### 3.3. Entrées et validation + +Comme nous l'avons noté précédemment, lorsque nous avons examiné le profil de test du pipeline `nf-core/demo`, il est conçu pour prendre comme entrée une feuille d'échantillons contenant des chemins de fichiers et des identifiants d'échantillons. +Les chemins de fichiers sont liés à de vraies données situées dans le dépôt `nf-core/test-datasets`. + +Un exemple de feuille d'échantillons est également fourni dans le répertoire `assets`, bien que les chemins dans celui-ci ne soient pas réels. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Cette feuille d'échantillons particulière est assez simple, mais certains pipelines s'exécutent sur des feuilles d'échantillons plus complexes, avec beaucoup plus de métadonnées associées aux entrées principales. + +Malheureusement, parce que ces fichiers peuvent être difficiles à vérifier à l'œil, un formatage incorrect des données d'entrée est une source très courante d'échecs de pipeline. +Un problème connexe est lorsque les paramètres sont fournis de manière incorrecte. + +La solution à ces problèmes est d'exécuter des vérifications de validation automatisées sur tous les fichiers d'entrée pour s'assurer qu'ils contiennent les types d'informations attendus, correctement formatés, et sur les paramètres pour s'assurer qu'ils sont du type attendu. +C'est ce qu'on appelle la validation d'entrée, et devrait idéalement être effectuée _avant_ d'essayer d'exécuter un pipeline, plutôt que d'attendre que le pipeline échoue pour découvrir qu'il y avait un problème avec les entrées. + +Tout comme pour la configuration, le projet nf-core a des opinions très arrêtées sur la validation des entrées, et recommande l'utilisation du [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/), un plugin Nextflow qui fournit des capacités de validation complètes pour les pipelines Nextflow. + +Nous couvrirons ce sujet plus en détail dans la Partie 5 de ce cours. +Pour l'instant, soyez simplement conscient qu'il existe deux fichiers JSON fournis à cet effet, `nextflow_schema.json` et `assets/schema_input.json`. + +Le `nextflow_schema.json` est un fichier utilisé pour stocker des informations sur les paramètres du pipeline, y compris le type, la description et le texte d'aide dans un format lisible par machine. +Ceci est utilisé à diverses fins, notamment la validation automatisée des paramètres, la génération de texte d'aide et le rendu de formulaires de paramètres interactifs dans les interfaces utilisateur. + +Le `schema_input.json` est un fichier utilisé pour définir la structure de la feuille d'échantillons d'entrée. +Chaque colonne peut avoir un type, un modèle, une description et un texte d'aide dans un format lisible par machine. +Le schéma est utilisé à diverses fins, notamment la validation automatisée et la fourniture de messages d'erreur utiles. + +### À retenir + +Vous savez quels sont les principaux composants d'un pipeline nf-core et comment le code est organisé ; où se trouvent les principaux éléments de configuration ; et vous êtes conscient de l'utilité de la validation des entrées. + +### Et ensuite ? + +Faites une pause ! C'était beaucoup. Lorsque vous vous sentez rafraîchi et prêt, passez à la section suivante pour appliquer ce que vous avez appris afin d'écrire un pipeline compatible nf-core. + +!!! tip + + Si vous souhaitez apprendre à composer des workflows avec des subworkflows avant de passer à la partie suivante, consultez la [Quête Secondaire Workflows de Workflows](../side_quests/workflows_of_workflows.md). diff --git a/docs/fr/docs/hello_nf-core/02_rewrite_hello.md b/docs/fr/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..3553454be9 --- /dev/null +++ b/docs/fr/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1429 @@ +# Partie 2 : Réécrire Hello pour nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette deuxième partie du cours de formation Hello nf-core, nous vous montrons comment créer une version compatible nf-core du pipeline produit par le cours pour débutants [Hello Nextflow](../hello_nextflow/index.md). + +Vous aurez remarqué dans la première section de la formation que les pipelines nf-core suivent une structure assez élaborée avec de nombreux fichiers accessoires. +Créer tout cela à partir de zéro serait très fastidieux, donc la communauté nf-core a développé des outils pour le faire à partir d'un modèle à la place, afin d'amorcer le processus. + +Nous allons vous montrer comment utiliser ces outils pour créer une structure de pipeline, puis adapter le code du pipeline « régulier » existant sur la structure nf-core. + +Si vous n'êtes pas familier avec le pipeline Hello ou si vous avez besoin d'un rappel, consultez [cette page d'information](../info/hello_pipeline.md). + +--- + +## 1. Créer un nouveau projet de pipeline + +Tout d'abord, nous créons la structure pour le nouveau pipeline. + +!!! note "Note" + + Assurez-vous d'être dans le répertoire `hello-nf-core` dans votre terminal. + +### 1.1. Exécuter l'outil de création de pipeline basé sur un modèle + +Commençons par créer un nouveau pipeline avec la commande `nf-core pipelines create`. +Cela créera une nouvelle structure de pipeline en utilisant le modèle de base nf-core, personnalisé avec un nom de pipeline, une description et un auteur. + +```bash +nf-core pipelines create +``` + +L'exécution de cette commande ouvrira une Interface Utilisateur Texte (TUI) pour la création du pipeline : + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Cette TUI vous demandera de fournir des informations de base sur votre pipeline et vous offrira un choix de fonctionnalités à inclure ou exclure dans votre structure de pipeline. + +- Sur l'écran de bienvenue, cliquez sur **Let's go!**. +- Sur l'écran `Choose pipeline type`, cliquez sur **Custom**. +- Entrez les détails de votre pipeline comme suit (en remplaçant `< VOTRE NOM >` par votre propre nom), puis cliquez sur **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < VOTRE NOM > +``` + +- Sur l'écran Template features, réglez `Toggle all features` sur **off**, puis **activez** sélectivement les éléments suivants. Vérifiez vos sélections et cliquez sur **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- Sur l'écran `Final details`, cliquez sur **Finish**. Attendez que le pipeline soit créé, puis cliquez sur **Continue**. +- Sur l'écran Create GitHub repository, cliquez sur **Finish without creating a repo**. Cela affichera des instructions pour créer un dépôt GitHub ultérieurement. Ignorez-les et cliquez sur **Close**. + +Une fois que la TUI se ferme, vous devriez voir la sortie de console suivante. + +??? success "Sortie de la commande" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +Il n'y a pas de confirmation explicite dans la sortie de console que la création du pipeline a réussi, mais vous devriez voir un nouveau répertoire appelé `core-hello`. + +Visualisez le contenu du nouveau répertoire pour voir combien de travail vous vous êtes épargné en utilisant le modèle. + +```bash +tree core-hello +``` + +??? abstract "Contenu du répertoire" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +Cela fait beaucoup de fichiers ! + +Vous devriez en reconnaître beaucoup comme étant les mêmes que nous avons rencontrés lorsque nous avons exploré la structure du pipeline `nf-core/demo`. +Mais ne vous inquiétez pas si vous vous sentez encore un peu perdu ; nous parcourrons ensemble les parties importantes au cours de cette formation. + +!!! note "Note" + + Une différence importante par rapport au pipeline `nf-core/demo` que nous avons examiné dans la première partie de cette formation est qu'il n'y a pas de répertoire `modules`. + C'est parce que nous n'avons pas choisi d'inclure les modules nf-core par défaut. + +### 1.2. Tester que la structure est fonctionnelle + +Croyez-le ou non, même si vous n'avez pas encore ajouté de modules pour effectuer un vrai travail, la structure du pipeline peut en fait être exécutée en utilisant le profil de test, de la même manière que nous avons exécuté le pipeline `nf-core/demo`. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Cela vous montre que tout le câblage de base est en place. +Alors où sont les sorties ? Y en a-t-il ? + +En fait, un nouveau répertoire de résultats appelé `core-hello-results` a été créé contenant les rapports d'exécution standard : + +```bash +tree core-hello-results +``` + +??? abstract "Contenu du répertoire" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Vous pouvez jeter un œil aux rapports pour voir ce qui a été exécuté, et la réponse est : rien du tout ! + +![rapport de chronologie d'exécution vide](./img/execution_timeline_empty.png) + +Regardons ce qu'il y a réellement dans le code. + +### 1.3. Examiner le workflow de substitution + +Si vous regardez à l'intérieur du fichier `main.nf`, vous verrez qu'il importe un workflow appelé `HELLO` depuis `workflows/hello`. + +Ceci est équivalent au workflow `workflows/demo.nf` que nous avons rencontré dans la Partie 1, et sert de workflow de substitution pour notre workflow d'intérêt, avec certaines fonctionnalités nf-core déjà en place. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Par rapport à un workflow Nextflow basique comme celui développé dans [Hello Nextflow](../hello_nextflow/index.md), vous remarquerez quelques nouveautés ici (lignes surlignées ci-dessus) : + +- Le bloc workflow a un nom +- Les entrées du workflow sont déclarées en utilisant le mot-clé `take:` et la construction du canal est déplacée vers le workflow parent +- Le contenu du workflow est placé à l'intérieur d'un bloc `main:` +- Les sorties sont déclarées en utilisant le mot-clé `emit:` + +Ce sont des fonctionnalités optionnelles de Nextflow qui rendent le workflow **composable**, ce qui signifie qu'il peut être appelé depuis un autre workflow. + +!!! note "Workflows composables en profondeur" + + La [Side Quest Workflows of Workflows](../side_quests/workflows_of_workflows.md) explore la composition de workflows de manière beaucoup plus approfondie, y compris comment composer plusieurs workflows ensemble et gérer des flux de données complexes entre eux. Nous introduisons la composabilité ici car c'est une exigence fondamentale de l'architecture du modèle nf-core, qui utilise des workflows imbriqués pour organiser l'initialisation du pipeline, le workflow d'analyse principal et les tâches de finalisation en composants séparés et réutilisables. + +Nous allons devoir intégrer la logique pertinente de notre workflow d'intérêt dans cette structure. +La première étape pour cela est de rendre notre workflow original composable. + +### À retenir + +Vous savez maintenant comment créer une structure de pipeline en utilisant les outils nf-core. + +### Et ensuite ? + +Apprenez à rendre un workflow simple composable comme prélude à le rendre compatible nf-core. + +--- + +## 2. Rendre le workflow Hello Nextflow original composable + +Maintenant il est temps de se mettre au travail pour intégrer notre workflow dans la structure nf-core. +Pour rappel, nous travaillons avec le workflow présenté dans notre cours de formation [Hello Nextflow](../hello_nextflow/index.md). + +!!! tip "Astuce" + + Si vous n'êtes pas familier avec ce pipeline ou si vous avez besoin d'un rappel, consultez [Le pipeline Hello](../info/hello_pipeline.md). + +Nous vous fournissons une copie propre et entièrement fonctionnelle du workflow Hello Nextflow terminé dans le répertoire `original-hello` avec ses modules et le fichier CSV par défaut qu'il s'attend à utiliser comme entrée. + +```bash +tree original-hello/ +``` + +??? abstract "Contenu du répertoire" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +N'hésitez pas à l'exécuter pour vous assurer qu'il fonctionne : + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Ouvrons le fichier de workflow `hello.nf` pour inspecter le code, qui est montré en entier ci-dessous (sans compter les processus, qui sont dans les modules) : + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Paramètres du pipeline +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Inclure les modules +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Comme vous pouvez le voir, ce workflow a été écrit comme un workflow simple sans nom qui peut être exécuté seul. +Pour le rendre exécutable depuis un workflow parent comme l'exige le modèle nf-core, nous devons le rendre **composable**. + +Parcourons les modifications nécessaires une par une. + +### 2.1. Nommer le workflow + +Tout d'abord, donnons un nom au workflow afin de pouvoir y faire référence depuis un workflow parent. + +=== "Après" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Avant" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Les mêmes conventions s'appliquent aux noms de workflow qu'aux noms de modules. + +### 2.2. Remplacer la construction de canal par `take` + +Maintenant, remplacez la construction de canal par une simple déclaration `take` déclarant les entrées attendues. + +=== "Après" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // canal de salutations + greeting_ch + ``` + +=== "Avant" + + ```groovy title="original-hello/hello.nf" linenums="18" + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Cela laisse les détails de la façon dont les entrées sont fournies au workflow parent. + +Pendant que nous y sommes, nous pouvons également commenter la ligne `params.greeting = 'greetings.csv'` + +=== "Après" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Paramètres du pipeline + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Avant" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Paramètres du pipeline + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Note" + + Si vous avez l'extension du serveur de langage Nextflow installée, le vérificateur de syntaxe éclairera votre code avec des lignes ondulées rouges. + C'est parce que si vous mettez une déclaration `take:`, vous devez aussi avoir un `main:`. + + Nous ajouterons cela à l'étape suivante. + +### 2.3. Préfacer les opérations du workflow avec la déclaration `main` + +Ensuite, ajoutez une déclaration `main` avant le reste des opérations appelées dans le corps du workflow. + +=== "Après" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Avant" + + ```groovy title="original-hello/hello.nf" linenums="21" + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Cela dit essentiellement « voici ce que ce workflow _fait_ ». + +### 2.4. Ajouter la déclaration `emit` + +Enfin, ajoutez une déclaration `emit` déclarant quelles sont les sorties finales du workflow. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Il s'agit d'un ajout entièrement nouveau au code par rapport au workflow original. + +### 2.5. Récapitulatif des modifications complétées + +Si vous avez effectué toutes les modifications comme décrit, votre workflow devrait maintenant ressembler à ceci : + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Paramètres du pipeline +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Inclure les modules +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // canal de salutations + greeting_ch + + main: + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Cela décrit tout ce dont Nextflow a besoin SAUF ce qu'il faut alimenter dans le canal d'entrée. +Cela va être défini dans le workflow parent, également appelé workflow **d'entrée**. + +### 2.6. Créer un workflow d'entrée factice + +Avant d'intégrer notre workflow composable dans la structure nf-core complexe, vérifions qu'il fonctionne correctement. +Nous pouvons créer un simple workflow d'entrée factice pour tester le workflow composable de manière isolée. + +Créez un fichier vide nommé `main.nf` dans le même répertoire `original-hello`. + +```bash +touch original-hello/main.nf +``` + +Copiez le code suivant dans le fichier `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// importer le code du workflow depuis le fichier hello.nf +include { HELLO } from './hello.nf' + +// déclarer le paramètre d'entrée +params.greeting = 'greetings.csv' + +workflow { + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // appeler le workflow importé sur le canal de salutations + HELLO(greeting_ch) + + // visualiser les sorties émises par le workflow + HELLO.out.view { output -> "Output: $output" } +} +``` + +Il y a deux observations importantes à faire ici : + +- La syntaxe pour appeler le workflow importé est essentiellement la même que la syntaxe pour appeler des modules. +- Tout ce qui est lié à l'acheminement des entrées dans le workflow (paramètre d'entrée et construction de canal) est maintenant déclaré dans ce workflow parent. + +!!! note "Note" + + Nommer le fichier de workflow d'entrée `main.nf` est une convention, pas une exigence. + + Si vous suivez cette convention, vous pouvez omettre de spécifier le nom du fichier de workflow dans votre commande `nextflow run`. + Nextflow recherchera automatiquement un fichier nommé `main.nf` dans le répertoire d'exécution. + + Cependant, vous pouvez nommer le fichier de workflow d'entrée autrement si vous préférez. + Dans ce cas, assurez-vous de spécifier le nom du fichier de workflow dans votre commande `nextflow run`. + +### 2.7. Tester que le workflow s'exécute + +Nous avons enfin toutes les pièces dont nous avons besoin pour vérifier que le workflow composable fonctionne. +Exécutons-le ! + +```bash +nextflow run ./original-hello +``` + +Ici vous voyez l'avantage d'utiliser la convention de nommage `main.nf`. +Si nous avions nommé le workflow d'entrée `something_else.nf`, nous aurions dû faire `nextflow run original-hello/something_else.nf`. + +Si vous avez effectué toutes les modifications correctement, cela devrait s'exécuter jusqu'à la fin. + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Cela signifie que nous avons réussi à mettre à niveau notre workflow HELLO pour le rendre composable. + +### À retenir + +Vous savez comment rendre un workflow composable en lui donnant un nom et en ajoutant des déclarations `take`, `main` et `emit`, et comment l'appeler depuis un workflow d'entrée. + +### Et ensuite ? + +Apprenez à greffer un workflow composable basique sur la structure nf-core. + +--- + +## 3. Adapter la logique du workflow mis à jour dans le workflow de substitution + +Maintenant que nous avons vérifié que notre workflow composable fonctionne correctement, retournons à la structure du pipeline nf-core que nous avons créée dans la section 1. +Nous voulons intégrer le workflow composable que nous venons de développer dans la structure du modèle nf-core, donc le résultat final devrait ressembler à ceci. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Alors comment faisons-nous cela ? Jetons un œil au contenu actuel du workflow `HELLO` dans `core-hello/workflows/hello.nf` (la structure nf-core). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Dans l'ensemble, ce code fait très peu de choses en dehors de quelques tâches administratives liées à la capture de la version de tous les outils logiciels qui sont exécutés dans le pipeline. + +Nous devons ajouter le code pertinent de la version composable du workflow original que nous avons développée dans la section 2. + +Nous allons aborder cela dans les étapes suivantes : + +1. Copier les modules et configurer les imports de modules +2. Laisser la déclaration `take` telle quelle +3. Ajouter la logique du workflow au bloc `main` +4. Mettre à jour le bloc `emit` + +!!! note "Note" + + Nous allons ignorer la capture de version pour cette première passe et verrons comment la câbler dans une partie ultérieure de cette formation. + +### 3.1. Copier les modules et configurer les imports de modules + +Les quatre processus de notre workflow Hello Nextflow sont stockés comme modules dans `original-hello/modules/`. +Nous devons copier ces modules dans la structure du projet nf-core (sous `core-hello/modules/local/`) et ajouter des déclarations d'importation au fichier de workflow nf-core. + +Copions d'abord les fichiers de modules de `original-hello/` vers `core-hello/` : + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Vous devriez maintenant voir le répertoire des modules listé sous `core-hello/`. + +```bash +tree core-hello/modules +``` + +??? abstract "Contenu du répertoire" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Maintenant configurons les déclarations d'importation de modules. + +Voici les déclarations d'importation dans le workflow `original-hello/hello.nf` : + +```groovy title="original-hello/hello.nf" linenums="9" +// Inclure les modules +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Ouvrez le fichier `core-hello/workflows/hello.nf` et transposez ces déclarations d'importation dedans comme montré ci-dessous. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Deux autres observations intéressantes ici : + +- Nous avons adapté le formatage des déclarations d'importation pour suivre la convention de style nf-core. +- Nous avons mis à jour les chemins relatifs vers les modules pour refléter qu'ils sont maintenant stockés à un niveau d'imbrication différent. + +### 3.2. Laisser la déclaration `take` telle quelle + +Le projet nf-core a beaucoup de fonctionnalités préconçues autour du concept de samplesheet, qui est typiquement un fichier CSV contenant des données en colonnes. +Puisque c'est essentiellement ce qu'est notre fichier `greetings.csv`, nous garderons la déclaration `take` actuelle telle quelle, et mettrons simplement à jour le nom du canal d'entrée à l'étape suivante. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +La gestion des entrées sera effectuée en amont de ce workflow (pas dans ce fichier de code). + +### 3.3. Ajouter la logique du workflow au bloc `main` + +Maintenant que nos modules sont disponibles pour le workflow, nous pouvons intégrer la logique du workflow dans le bloc `main`. + +Pour rappel, voici le code pertinent dans le workflow original, qui n'a pas beaucoup changé lorsque nous l'avons rendu composable (nous avons juste ajouté la ligne `main:`) : + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) +``` + +Nous devons copier le code qui vient après `main:` dans la nouvelle version du workflow. + +Il y a déjà du code là-dedans qui a à voir avec la capture des versions des outils qui sont exécutés par le workflow. Nous allons laisser cela tranquille pour l'instant (nous traiterons les versions d'outils plus tard). +Nous garderons l'initialisation `ch_versions = channel.empty()` en haut, puis insérerons notre logique de workflow, en gardant le code de collecte des versions à la fin. +Cet ordonnancement a du sens car dans un vrai pipeline, les processus émettraient des informations de version qui seraient ajoutées au canal `ch_versions` pendant l'exécution du workflow. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +Vous remarquerez que nous avons également ajouté une ligne vide avant `main:` pour rendre le code plus lisible. + +Cela semble très bien, mais nous devons encore mettre à jour le nom du canal que nous passons au processus `sayHello()` de `greeting_ch` à `ch_samplesheet` comme montré ci-dessous, pour correspondre à ce qui est écrit sous le mot-clé `take:`. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // émettre une salutation (mis à jour pour utiliser la convention nf-core pour les samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // émettre une salutation + sayHello(greeting_ch) + ``` + +Maintenant la logique du workflow est correctement câblée. + +### 3.4. Mettre à jour le bloc `emit` + +Enfin, nous devons mettre à jour le bloc `emit` pour inclure la déclaration des sorties finales du workflow. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +Ceci conclut les modifications que nous devons apporter au workflow HELLO lui-même. +À ce stade, nous avons atteint la structure globale du code que nous nous étions fixés pour objectif. + +### À retenir + +Vous savez comment adapter les éléments principaux d'un workflow composable dans un workflow de substitution nf-core. + +### Et ensuite ? + +Apprenez à adapter la gestion des entrées dans la structure du pipeline nf-core. + +--- + +## 4. Adapter la gestion des entrées + +Maintenant que nous avons intégré avec succès notre logique de workflow dans la structure nf-core, nous devons aborder une dernière pièce critique : nous assurer que nos données d'entrée sont traitées correctement. +Le modèle nf-core est livré avec une gestion des entrées sophistiquée conçue pour des ensembles de données génomiques complexes, donc nous devons l'adapter pour qu'il fonctionne avec notre fichier `greetings.csv` plus simple. + +### 4.1. Identifier où les entrées sont gérées + +La première étape est de déterminer où la gestion des entrées est effectuée. + +Vous vous souvenez peut-être que lorsque nous avons réécrit le workflow Hello Nextflow pour le rendre composable, nous avons déplacé la déclaration du paramètre d'entrée d'un niveau vers le haut, dans le workflow d'entrée `main.nf`. +Jetons donc un œil au workflow d'entrée de niveau supérieur `main.nf` qui a été créé dans le cadre de la structure du pipeline : + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Run main analysis pipeline depending on type of input +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Run pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Run initialisation tasks + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Run main workflow + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Run completion tasks + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Le projet nf-core fait un usage intensif de sous-workflows imbriqués, donc cette partie peut être un peu déroutante à première approche. + +Ce qui compte ici, c'est qu'il y a deux workflows définis : + +- `CORE_HELLO` est une enveloppe mince pour exécuter le workflow HELLO que nous venons de finir d'adapter dans `core-hello/workflows/hello.nf`. +- Un workflow sans nom qui appelle `CORE_HELLO` ainsi que deux autres sous-workflows, `PIPELINE_INITIALISATION` et `PIPELINE_COMPLETION`. + +Voici un diagramme de la façon dont ils sont liés les uns aux autres : + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Fait important, nous ne pouvons trouver aucun code construisant un canal d'entrée à ce niveau, seulement des références à un samplesheet fourni via le paramètre `--input`. + +Un peu de fouille révèle que la gestion des entrées est effectuée par le sous-workflow `PIPELINE_INITIALISATION`, comme il se doit, qui est importé depuis `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`. + +Si nous ouvrons ce fichier et faisons défiler vers le bas, nous arrivons à ce bloc de code : + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Crée un canal à partir du fichier d'entrée fourni via params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +C'est la fabrique de canaux qui analyse le samplesheet et le transmet sous une forme prête à être consommée par le workflow HELLO. + +!!! note "Note" + + La syntaxe ci-dessus est un peu différente de ce que nous avons utilisé précédemment, mais fondamentalement ceci : + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + est équivalent à ceci : + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Ce code implique quelques étapes d'analyse et de validation qui sont très spécifiques à l'exemple de samplesheet inclus avec le modèle de pipeline nf-core, qui au moment de la rédaction est très spécifique au domaine et ne convient pas à notre simple projet de pipeline. + +### 4.2. Remplacer le code de canal d'entrée du modèle + +La bonne nouvelle est que les besoins de notre pipeline sont beaucoup plus simples, donc nous pouvons remplacer tout cela par le code de construction de canal que nous avons développé dans le workflow Hello Nextflow original. + +Pour rappel, voici à quoi ressemblait la construction du canal (comme vu dans le répertoire solutions) : + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Donc nous devons juste intégrer cela dans le workflow d'initialisation, avec des modifications mineures : nous mettons à jour le nom du canal de `greeting_ch` à `ch_samplesheet`, et le nom du paramètre de `params.greeting` à `params.input` (voir ligne surlignée). + +=== "Après" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Crée un canal à partir du fichier d'entrée fourni via params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Avant" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Crée un canal à partir du fichier d'entrée fourni via params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Cela termine les modifications que nous devons effectuer pour que le traitement des entrées fonctionne. + +Dans sa forme actuelle, cela ne nous permettra pas de profiter des capacités intégrées de nf-core pour la validation de schéma, mais nous pouvons ajouter cela plus tard. +Pour l'instant, nous nous concentrons sur le garder aussi simple que possible pour arriver à quelque chose que nous pouvons exécuter avec succès sur des données de test. + +### 4.3. Mettre à jour le profil de test + +En parlant de données de test et de paramètres, mettons à jour le profil de test pour ce pipeline afin d'utiliser le mini-samplesheet `greetings.csv` au lieu de l'exemple de samplesheet fourni dans le modèle. + +Sous `core-hello/conf`, nous trouvons deux profils de test basés sur le modèle : `test.config` et `test_full.config`, qui sont destinés à tester un petit échantillon de données et un échantillon de taille complète. +Étant donné l'objectif de notre pipeline, il n'y a pas vraiment d'intérêt à configurer un profil de test de taille complète, donc n'hésitez pas à ignorer ou supprimer `test_full.config`. +Nous allons nous concentrer sur la configuration de `test.config` pour s'exécuter sur notre fichier `greetings.csv` avec quelques paramètres par défaut. + +#### 4.3.1. Copier le fichier `greetings.csv` + +D'abord, nous devons copier le fichier `greetings.csv` dans un endroit approprié de notre projet de pipeline. +Généralement, les petits fichiers de test sont stockés dans le répertoire `assets`, donc copions le fichier depuis notre répertoire de travail. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Maintenant le fichier `greetings.csv` est prêt à être utilisé comme entrée de test. + +#### 4.3.2. Mettre à jour le fichier `test.config` + +Maintenant nous pouvons mettre à jour le fichier `test.config` comme suit : + +=== "Après" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Données d'entrée + input = "${projectDir}/assets/greetings.csv" + + // Autres paramètres + batch = 'test' + character = 'tux' + } + ``` + +=== "Avant" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Données d'entrée + // TODO nf-core: Spécifiez les chemins vers vos données de test sur nf-core/test-datasets + // TODO nf-core: Donnez tous les paramètres requis pour le test afin que les flags de ligne de commande ne soient pas nécessaires + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Points clés : + +- **Utilisation de `${projectDir}`** : C'est une variable implicite de Nextflow qui pointe vers le répertoire où se trouve le script de workflow principal (la racine du pipeline). Son utilisation garantit que le chemin fonctionne quel que soit l'endroit d'où le pipeline est exécuté. +- **Chemins absolus** : En utilisant `${projectDir}`, nous créons un chemin absolu, ce qui est important pour les données de test qui sont fournies avec le pipeline. +- **Emplacement des données de test** : les pipelines nf-core stockent généralement les données de test dans le répertoire `assets/` au sein du dépôt du pipeline pour les petits fichiers de test, ou référencent des ensembles de données de test externes pour les fichiers plus volumineux. + +Et pendant que nous y sommes, resserrons les limites de ressources par défaut pour garantir que cela s'exécutera sur des machines très basiques (comme les VM minimales dans Github Codespaces) : + +=== "Après" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Avant" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Cela termine les modifications de code que nous devons effectuer. + +### 4.4. Exécuter le pipeline avec le profil de test + +C'était beaucoup, mais nous pouvons enfin essayer d'exécuter le pipeline ! +Notez que nous devons ajouter `--validate_params false` à la ligne de commande car nous n'avons pas encore configuré la validation (cela viendra plus tard). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Si vous avez effectué toutes les modifications correctement, cela devrait s'exécuter jusqu'à la fin. + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Comme vous pouvez le voir, cela a produit le résumé typique nf-core au démarrage grâce au sous-workflow d'initialisation, et les lignes pour chaque module montrent maintenant les noms complets PIPELINE:WORKFLOW:module. + +### 4.5. Trouver les sorties du pipeline + +La question maintenant est : où sont les sorties du pipeline ? +Et la réponse est assez intéressante : il y a maintenant deux endroits différents où chercher les résultats. + +Comme vous vous en souvenez peut-être d'avant, notre première exécution du workflow nouvellement créé a produit un répertoire appelé `core-hello-results/` qui contenait divers rapports d'exécution et métadonnées. + +```bash +tree core-hello-results +``` + +??? abstract "Contenu du répertoire" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_07-29-37.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── execution_trace_2025-11-21_07-29-37.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-13.json + ├── params_2025-11-21_07-29-41.json + └── pipeline_dag_2025-11-21_04-47-18.html + └── pipeline_dag_2025-11-21_07-29-37.html + + 1 directory, 12 files + ``` + +Vous voyez que nous avons obtenu un autre ensemble de rapports d'exécution en plus de ceux que nous avons obtenus lors de la première exécution, lorsque le workflow n'était encore qu'un substitut. +Cette fois, vous voyez toutes les tâches qui ont été exécutées comme prévu. + +![rapport de chronologie d'exécution pour le pipeline Hello](./img/execution_timeline_hello.png) + +!!! note "Note" + + Une fois de plus, les tâches n'ont pas été exécutées en parallèle car nous exécutons sur une machine minimaliste dans Github Codespaces. + Pour voir celles-ci s'exécuter en parallèle, essayez d'augmenter l'allocation de CPU de votre codespace et les limites de ressources dans la configuration de test. + +C'est génial, mais nos résultats de pipeline réels ne sont pas là ! + +Voici ce qui s'est passé : nous n'avons rien changé aux modules eux-mêmes, donc les sorties gérées par les directives `publishDir` au niveau du module vont toujours dans un répertoire `results` tel que spécifié dans le pipeline original. + +```bash +tree results +``` + +??? abstract "Contenu du répertoire" + + ```console + results + ├── Bonjour-output.txt + ├── COLLECTED-test-batch-output.txt + ├── COLLECTED-test-output.txt + ├── cowpy-COLLECTED-test-batch-output.txt + ├── cowpy-COLLECTED-test-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + 0 directories, 10 files + ``` + +Ah, les voilà, mélangés avec les sorties des exécutions précédentes du pipeline Hello original. + +Si nous voulons qu'ils soient bien organisés comme les sorties du pipeline demo l'étaient, nous devrons changer la façon dont nous configurons la publication des sorties. +Nous vous montrerons comment faire cela plus tard dans ce cours de formation. + +<!-- TODO: Mettre à jour ceci une fois que nous aurons mis à jour Hello Nextflow pour utiliser des sorties au niveau workflow --> + +Et voilà ! Cela peut sembler beaucoup de travail pour accomplir le même résultat que le pipeline original, mais vous obtenez tous ces beaux rapports générés automatiquement, et vous avez maintenant une base solide pour profiter de fonctionnalités supplémentaires de nf-core, y compris la validation des entrées et certaines capacités de gestion des métadonnées intéressantes que nous couvrirons dans une section ultérieure. + +--- + +### À retenir + +Vous savez comment convertir un pipeline Nextflow ordinaire en un pipeline de style nf-core en utilisant le modèle nf diff --git a/docs/fr/docs/hello_nf-core/03_use_module.md b/docs/fr/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..39f456ab0c --- /dev/null +++ b/docs/fr/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Partie 3 : Utiliser un module nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette troisième partie du cours de formation Hello nf-core, nous vous montrons comment trouver, installer et utiliser un module nf-core existant dans votre pipeline. + +L'un des grands avantages de travailler avec nf-core est la possibilité de tirer parti de modules pré-construits et testés du dépôt [nf-core/modules](https://github.com/nf-core/modules). +Plutôt que d'écrire chaque processus à partir de zéro, vous pouvez installer et utiliser des modules maintenus par la communauté qui suivent les meilleures pratiques. + +Pour démontrer comment cela fonctionne, nous remplacerons le module personnalisé `collectGreetings` par le module `cat/cat` de nf-core/modules dans le pipeline `core-hello`. + +??? info "Comment commencer à partir de cette section" + + Cette section du cours suppose que vous avez terminé la [Partie 2 : Réécrire Hello pour nf-core](./02_rewrite_hello.md) et que vous disposez d'un pipeline `core-hello` fonctionnel. + + Si vous n'avez pas terminé la Partie 2 ou si vous souhaitez repartir de zéro pour cette partie, vous pouvez utiliser la solution `core-hello-part2` comme point de départ. + Exécutez cette commande depuis le répertoire `hello-nf-core/` : + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Cela vous donne un pipeline nf-core entièrement fonctionnel prêt pour l'ajout de modules. + Vous pouvez tester qu'il s'exécute avec succès en exécutant la commande suivante : + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Trouver et installer un module nf-core approprié + +Tout d'abord, apprenons comment trouver un module nf-core existant et l'installer dans notre pipeline. + +Nous allons chercher à remplacer le processus `collectGreetings`, qui utilise la commande Unix `cat` pour concaténer plusieurs fichiers de salutations en un seul. +La concaténation de fichiers est une opération très courante, il est donc raisonnable de penser qu'il pourrait déjà exister un module dans nf-core conçu à cet effet. + +Plongeons-nous dans le sujet. + +### 1.1. Parcourir les modules disponibles sur le site web nf-core + +Le projet nf-core maintient un catalogue centralisé de modules sur [https://nf-co.re/modules](https://nf-co.re/modules). + +Accédez à la page des modules dans votre navigateur web et utilisez la barre de recherche pour rechercher 'concatenate'. + +![résultats de recherche de module](./img/module-search-results.png) + +Comme vous pouvez le voir, il y a pas mal de résultats, dont beaucoup sont des modules conçus pour concaténer des types de fichiers très spécifiques. +Parmi eux, vous devriez voir un module appelé `cat_cat` qui est générique. + +!!! note "Convention de nommage des modules" + + Le caractère de soulignement (`_`) est utilisé comme substitut du caractère barre oblique (`/`) dans les noms de modules. + + Les modules nf-core suivent la convention de nommage `logiciel/commande` lorsqu'un outil fournit plusieurs commandes, comme `samtools/view` (package samtools, commande view) ou `gatk/haplotypecaller` (package GATK, commande HaplotypeCaller). + Pour les outils qui ne fournissent qu'une seule commande principale, les modules utilisent un seul niveau comme `fastqc` ou `multiqc`. + +Cliquez sur la boîte du module `cat_cat` pour voir la documentation du module. + +La page du module affiche : + +- Une brève description : "A module for concatenation of gzipped or uncompressed files" +- La commande d'installation : `nf-core modules install cat/cat` +- La structure des canaux d'entrée et de sortie +- Les paramètres disponibles + +### 1.2. Lister les modules disponibles depuis la ligne de commande + +Alternativement, vous pouvez également rechercher des modules directement depuis la ligne de commande en utilisant les outils nf-core. + +```bash +nf-core modules list remote +``` + +Cela affichera une liste de tous les modules disponibles dans le dépôt nf-core/modules, bien que ce soit un peu moins pratique si vous ne connaissez pas déjà le nom du module que vous recherchez. +Cependant, si vous le connaissez, vous pouvez rediriger la liste vers `grep` pour trouver des modules spécifiques : + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Sortie de la commande" + + ```console + │ cat/cat + ``` + +Gardez simplement à l'esprit que l'approche `grep` ne récupérera que les résultats avec le terme de recherche dans leur nom, ce qui ne fonctionnerait pas pour `cat_cat`. + +### 1.3. Obtenir des informations détaillées sur le module + +Pour voir des informations détaillées sur un module spécifique depuis la ligne de commande, utilisez la commande `info` : + +```bash +nf-core modules info cat/cat +``` + +Cela affiche la documentation sur le module, y compris ses entrées, ses sorties et des informations d'utilisation de base. + +??? success "Sortie de la commande" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +Ce sont exactement les mêmes informations que vous pouvez trouver sur le site web. + +### 1.4. Installer le module cat/cat + +Maintenant que nous avons trouvé le module que nous voulons, nous devons l'ajouter au code source de notre pipeline. + +La bonne nouvelle est que le projet nf-core inclut des outils pour faciliter cette partie. +Plus précisément, la commande `nf-core modules install` permet d'automatiser la récupération du code et de le rendre disponible à votre projet en une seule étape. + +Accédez au répertoire de votre pipeline et exécutez la commande d'installation : + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +L'outil peut d'abord vous demander de spécifier un type de dépôt. +(Sinon, passez directement à "Enfin, l'outil procédera à l'installation du module.") + +??? success "Sortie de la commande" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Si c'est le cas, appuyez sur Entrée pour accepter la réponse par défaut (`Pipeline`) et continuer. + +L'outil proposera ensuite de modifier la configuration de votre projet pour éviter cette invite à l'avenir. + +??? success "Sortie de la commande" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +Autant profiter de cet outil pratique ! +Appuyez sur Entrée pour accepter la réponse par défaut (oui). + +Enfin, l'outil procédera à l'installation du module. + +??? success "Sortie de la commande" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +La commande effectue automatiquement : + +- Le téléchargement des fichiers du module dans `modules/nf-core/cat/cat/` +- La mise à jour de `modules.json` pour suivre le module installé +- La fourniture de l'instruction `include` correcte à utiliser dans votre workflow + +!!! tip + + Assurez-vous toujours que votre répertoire de travail actuel est la racine de votre projet de pipeline avant d'exécuter la commande d'installation de module. + +Vérifions que le module a été installé correctement : + +```bash +tree -L 4 modules +``` + +??? abstract "Contenu du répertoire" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +Vous pouvez également vérifier l'installation en demandant à l'utilitaire nf-core de lister les modules installés localement : + +```bash +nf-core modules list local +``` + +??? success "Sortie de la commande" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Cela confirme que le module `cat/cat` fait maintenant partie du code source de votre projet. + +Cependant, pour utiliser réellement le nouveau module, nous devons l'importer dans notre pipeline. + +### 1.5. Mettre à jour les importations de module + +Remplaçons l'instruction `include` pour le module `collectGreetings` par celle pour `CAT_CAT` dans la section des importations du workflow `workflows/hello.nf`. + +Pour rappel, l'outil d'installation de module nous a donné l'instruction exacte à utiliser : + +```groovy title="Instruction d'importation produite par la commande d'installation" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Notez que la convention nf-core est d'utiliser des majuscules pour les noms de modules lors de leur importation. + +Ouvrez [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) et effectuez la substitution suivante : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Remarquez comment le chemin pour le module nf-core diffère des modules locaux : + +- **Module nf-core** : `'../modules/nf-core/cat/cat/main'` (référence à `main.nf`) +- **Module local** : `'../modules/local/collectGreetings.nf'` (référence à un fichier unique) + +Le module est maintenant disponible pour le workflow, donc tout ce que nous devons faire est de remplacer l'appel à `collectGreetings` pour utiliser `CAT_CAT`. N'est-ce pas ? + +Pas si vite. + +À ce stade, vous pourriez être tenté de vous lancer et de commencer à éditer le code, mais il vaut la peine de prendre un moment pour examiner attentivement ce que le nouveau module attend et ce qu'il produit. + +Nous allons traiter cela comme une section séparée car cela implique un nouveau mécanisme que nous n'avons pas encore couvert : les métadonnées sous forme de map. + +!!! note + + Vous pouvez éventuellement supprimer le fichier `collectGreetings.nf` : + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Cependant, vous pourriez vouloir le conserver comme référence pour comprendre les différences entre les modules locaux et nf-core. + +### À retenir + +Vous savez comment trouver un module nf-core et le rendre disponible pour votre projet. + +### Et ensuite ? + +Évaluer ce qu'un nouveau module requiert et identifier les changements importants nécessaires pour l'intégrer dans un pipeline. + +--- + +## 2. Évaluer les exigences du nouveau module + +Plus précisément, nous devons examiner l'**interface** du module, c'est-à-dire ses définitions d'entrée et de sortie, et la comparer à l'interface du module que nous cherchons à remplacer. +Cela nous permettra de déterminer si nous pouvons simplement traiter le nouveau module comme un remplacement direct ou si nous devrons adapter une partie du câblage. + +Idéalement, c'est quelque chose que vous devriez faire _avant_ même d'installer le module, mais bon, mieux vaut tard que jamais. +(Pour information, il existe une commande `uninstall` pour se débarrasser des modules que vous décidez de ne plus vouloir.) + +!!! note + + Le processus CAT_CAT inclut une gestion assez intelligente de différents types de compression, d'extensions de fichiers, etc. qui ne sont pas strictement pertinents pour ce que nous essayons de vous montrer ici, donc nous ignorerons la plupart de ces éléments et nous concentrerons uniquement sur les parties importantes. + +### 2.1. Comparer les interfaces des deux modules + +Pour rappel, voici à quoi ressemble l'interface de notre module `collectGreetings` : + +```groovy title="modules/local/collectGreetings.nf (extrait)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +Le module `collectGreetings` prend deux entrées : + +- `input_files` contient un ou plusieurs fichiers d'entrée à traiter ; +- `batch_name` est une valeur que nous utilisons pour attribuer un nom spécifique à l'exécution au fichier de sortie, qui est une forme de métadonnées. + +Une fois terminé, `collectGreetings` produit un seul chemin de fichier, émis avec l'étiquette `outfile`. + +En comparaison, l'interface du module `cat/cat` est plus complexe : + +```groovy title="modules/nf-core/cat/cat/main.nf (extrait)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +Le module CAT_CAT prend une seule entrée, mais cette entrée est un tuple contenant deux choses : + +- `meta` est une structure contenant des métadonnées, appelée metamap ; +- `files_in` contient un ou plusieurs fichiers d'entrée à traiter, équivalent à `input_files` de `collectGreetings`. + +Une fois terminé, CAT_CAT livre ses sorties en deux parties : + +- Un autre tuple contenant le metamap et le fichier de sortie concaténé, émis avec l'étiquette `file_out` ; +- Un fichier `versions.yml` qui capture des informations sur la version du logiciel qui a été utilisée, émis avec l'étiquette `versions`. + +Notez également que par défaut, le fichier de sortie sera nommé en fonction d'un identifiant qui fait partie des métadonnées (code non montré ici). + +Cela peut sembler beaucoup à retenir en regardant simplement le code, voici donc un diagramme pour vous aider à visualiser comment tout s'articule. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Vous pouvez voir que les deux modules ont des exigences d'entrée similaires en termes de contenu (un ensemble de fichiers d'entrée plus quelques métadonnées) mais des attentes très différentes quant à la façon dont ce contenu est empaqueté. +En ignorant le fichier versions pour l'instant, leur sortie principale est également équivalente (un fichier concaténé), sauf que CAT_CAT émet également le metamap conjointement avec le fichier de sortie. + +Les différences d'empaquetage seront assez faciles à gérer, comme vous le verrez dans un instant. +Cependant, pour comprendre la partie metamap, nous devons vous présenter un contexte supplémentaire. + +### 2.2. Comprendre les metamaps + +Nous venons de vous dire que le module CAT_CAT attend une map de métadonnées comme partie de son tuple d'entrée. +Prenons quelques minutes pour examiner de plus près ce que c'est. + +La **map de métadonnées**, souvent appelée **metamap** en abrégé, est une map de style Groovy contenant des informations sur des unités de données. +Dans le contexte des pipelines Nextflow, les unités de données peuvent être tout ce que vous voulez : des échantillons individuels, des lots d'échantillons ou des ensembles de données entiers. + +Par convention, un metamap nf-core est nommé `meta` et contient le champ requis `id`, qui est utilisé pour nommer les sorties et suivre les unités de données. + +Par exemple, une map de métadonnées typique pourrait ressembler à ceci : + +```groovy title="Exemple de metamap au niveau de l'échantillon" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +Ou dans un cas où les métadonnées sont attachées au niveau du lot : + +```groovy title="Exemple de metamap au niveau du lot" +[id: 'batch1', date: '25.10.01'] +``` + +Maintenant, plaçons cela dans le contexte du processus `CAT_CAT`, qui attend que les fichiers d'entrée soient empaquetés dans un tuple avec un metamap, et produit également le metamap comme partie du tuple de sortie. + +```groovy title="modules/nf-core/cat/cat/main.nf (extrait)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +En conséquence, chaque unité de données circule dans le pipeline avec les métadonnées pertinentes attachées. +Les processus suivants peuvent alors facilement accéder à ces métadonnées également. + +Vous vous souvenez que nous vous avons dit que le fichier produit par `CAT_CAT` sera nommé en fonction d'un identifiant qui fait partie des métadonnées ? +Voici le code pertinent : + +```groovy title="modules/nf-core/cat/cat/main.nf (extrait)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Cela se traduit approximativement comme suit : si un `prefix` est fourni via le système de paramètres de tâche externes (`task.ext`), utilisez-le pour nommer le fichier de sortie ; sinon créez-en un en utilisant `${meta.id}`, qui correspond au champ `id` dans le metamap. + +Vous pouvez imaginer le canal d'entrée entrant dans ce module avec un contenu comme ceci : + +```groovy title="Exemple de contenu de canal d'entrée" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Puis le contenu du canal de sortie sortant comme ceci : + +```groovy title="Exemple de contenu de canal de sortie" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Comme mentionné précédemment, la configuration d'entrée `tuple val(meta), path(files_in)` est un modèle standard utilisé dans tous les modules nf-core. + +Nous espérons que vous commencez à voir à quel point cela peut être utile. +Non seulement cela vous permet de nommer les sorties en fonction des métadonnées, mais vous pouvez également faire des choses comme l'utiliser pour appliquer différentes valeurs de paramètres, et en combinaison avec des opérateurs spécifiques, vous pouvez même regrouper, trier ou filtrer les données au fur et à mesure qu'elles circulent dans le pipeline. + +!!! note "En savoir plus sur les métadonnées" + + Pour une introduction complète au travail avec les métadonnées dans les workflows Nextflow, y compris comment lire les métadonnées à partir de samplesheets et les utiliser pour personnaliser le traitement, consultez la quête secondaire [Métadonnées dans les workflows](../side_quests/metadata). + +### 2.3. Résumer les changements à effectuer + +Sur la base de ce que nous avons examiné, voici les changements majeurs que nous devons apporter à notre pipeline pour utiliser le module `cat/cat` : + +- Créer un metamap contenant le nom du lot ; +- Empaqueter le metamap dans un tuple avec l'ensemble des fichiers d'entrée à concaténer (provenant de `convertToUpper`) ; +- Changer l'appel de `collectGreetings()` à `CAT_CAT` ; +- Extraire le fichier de sortie du tuple produit par le processus `CAT_CAT` avant de le passer à `cowpy`. + +Cela devrait faire l'affaire ! Maintenant que nous avons un plan, nous sommes prêts à nous lancer. + +### À retenir + +Vous savez comment évaluer l'interface d'entrée et de sortie d'un nouveau module pour identifier ses exigences, et vous avez appris comment les metamaps sont utilisés par les pipelines nf-core pour garder les métadonnées étroitement associées aux données au fur et à mesure qu'elles circulent dans un pipeline. + +### Et ensuite ? + +Intégrer le nouveau module dans un workflow. + +--- + +## 3. Intégrer CAT_CAT dans le workflow `hello.nf` + +Maintenant que vous savez tout sur les metamaps (ou suffisamment pour les besoins de ce cours, en tout cas), il est temps de réellement implémenter les changements que nous avons décrits ci-dessus. + +Par souci de clarté, nous allons décomposer cela et couvrir chaque étape séparément. + +!!! note + + Tous les changements montrés ci-dessous sont apportés à la logique du workflow dans le bloc `main` dans le fichier de workflow `core-hello/workflows/hello.nf`. + +### 3.1. Créer une map de métadonnées + +Tout d'abord, nous devons créer une map de métadonnées pour `CAT_CAT`, en gardant à l'esprit que les modules nf-core exigent que le metamap contienne au moins un champ `id`. + +Puisque nous n'avons besoin d'aucune autre métadonnée, nous pouvons rester simple et utiliser quelque chose comme ceci : + +```groovy title="Exemple de syntaxe" +def cat_meta = [id: 'test'] +``` + +Sauf que nous ne voulons pas coder en dur la valeur `id` ; nous voulons utiliser la valeur du paramètre `params.batch`. +Donc le code devient : + +```groovy title="Exemple de syntaxe" +def cat_meta = [id: params.batch] +``` + +Oui, c'est littéralement aussi simple que cela de créer un metamap de base. + +Ajoutons ces lignes après l'appel à `convertToUpper`, en supprimant l'appel à `collectGreetings` : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Cela crée une map de métadonnées simple où l'`id` est défini sur le nom de notre lot (qui sera `test` lors de l'utilisation du profil test). + +### 3.2. Créer un canal avec des tuples de métadonnées + +Ensuite, transformez le canal de fichiers en un canal de tuples contenant des métadonnées et des fichiers : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // créer un canal avec des métadonnées et des fichiers au format tuple + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +La ligne que nous avons ajoutée accomplit deux choses : + +- `.collect()` rassemble tous les fichiers de la sortie `convertToUpper` dans une seule liste +- `.map { files -> tuple(cat_meta, files) }` crée un tuple de `[métadonnées, fichiers]` dans le format attendu par `CAT_CAT` + +C'est tout ce que nous devons faire pour configurer le tuple d'entrée pour `CAT_CAT`. + +### 3.3. Appeler le module CAT_CAT + +Maintenant, appelez `CAT_CAT` sur le canal nouvellement créé : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // créer un canal avec des métadonnées et des fichiers au format tuple + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concaténer les fichiers en utilisant le module nf-core cat/cat + CAT_CAT(ch_for_cat) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // créer un canal avec des métadonnées et des fichiers au format tuple + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Cela complète la partie la plus délicate de cette substitution, mais nous n'avons pas tout à fait terminé : nous devons encore mettre à jour la façon dont nous passons la sortie concaténée au processus `cowpy`. + +### 3.4. Extraire le fichier de sortie du tuple pour `cowpy` + +Auparavant, le processus `collectGreetings` produisait simplement un fichier que nous pouvions passer directement à `cowpy`. +Cependant, le processus `CAT_CAT` produit un tuple qui inclut le metamap en plus du fichier de sortie. + +Puisque `cowpy` n'accepte pas encore les tuples de métadonnées (nous corrigerons cela dans la prochaine partie du cours), nous devons extraire le fichier de sortie du tuple produit par `CAT_CAT` avant de le transmettre à `cowpy` : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // créer un canal avec des métadonnées et des fichiers au format tuple + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concaténer les salutations + CAT_CAT(ch_for_cat) + + // extraire le fichier du tuple puisque cowpy n'utilise pas encore les métadonnées + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // générer de l'art ASCII des salutations avec cowpy + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // émettre une salutation + sayHello(ch_samplesheet) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + + // créer une map de métadonnées avec le nom du lot comme ID + def cat_meta = [ id: params.batch ] + + // créer un canal avec des métadonnées et des fichiers au format tuple + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concaténer les salutations + CAT_CAT(ch_for_cat) + + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +L'opération `.map{ meta, file -> file }` extrait le fichier du tuple `[métadonnées, fichier]` produit par `CAT_CAT` dans un nouveau canal, `ch_for_cowpy`. + +Ensuite, il suffit de passer `ch_for_cowpy` à `cowpy` au lieu de `collectGreetings.out.outfile` dans cette dernière ligne. + +!!! note + + Dans la prochaine partie du cours, nous mettrons à jour `cowpy` pour qu'il fonctionne directement avec les tuples de métadonnées, donc cette étape d'extraction ne sera plus nécessaire. + +### 3.5. Tester le workflow + +Testons que le workflow fonctionne avec le module `cat/cat` nouvellement intégré : + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Cela devrait s'exécuter assez rapidement. + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Remarquez que `CAT_CAT` apparaît maintenant dans la liste d'exécution des processus au lieu de `collectGreetings`. + +Et voilà ! Nous utilisons maintenant un module robuste et maintenu par la communauté au lieu d'un code personnalisé de qualité prototype pour cette étape du pipeline. + +### À retenir + +Vous savez maintenant comment : + +- Trouver et installer des modules nf-core +- Évaluer les exigences d'un module nf-core +- Créer une map de métadonnées simple pour l'utiliser avec un module nf-core +- Intégrer un module nf-core dans votre workflow + +### Et ensuite ? + +Apprendre à adapter vos modules locaux pour suivre les conventions nf-core. +Nous vous montrerons également comment créer de nouveaux modules nf-core à partir d'un modèle en utilisant les outils nf-core. diff --git a/docs/fr/docs/hello_nf-core/04_make_module.md b/docs/fr/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..7f6ae2a095 --- /dev/null +++ b/docs/fr/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1139 @@ +# Partie 4 : Créer un module nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette quatrième partie du cours de formation Hello nf-core, nous vous montrons comment créer un module nf-core en appliquant les conventions clés qui rendent les modules portables et maintenables. + +Le projet nf-core fournit une commande (`nf-core modules create`) qui génère automatiquement des modèles de modules correctement structurés, similaire à ce que nous avons utilisé pour le workflow dans la Partie 2. +Cependant, à des fins pédagogiques, nous allons commencer par le faire manuellement : transformer le module local `cowpy` dans votre pipeline `core-hello` en un module de style nf-core étape par étape. +Après cela, nous vous montrerons comment utiliser la création de modules basée sur des modèles pour travailler plus efficacement à l'avenir. + +??? info "Comment commencer à partir de cette section" + + Cette section suppose que vous avez terminé la [Partie 3 : Utiliser un module nf-core](./03_use_module.md) et que vous avez intégré le module `CAT_CAT` dans votre pipeline. + + Si vous n'avez pas terminé la Partie 3 ou souhaitez repartir de zéro pour cette partie, vous pouvez utiliser la solution `core-hello-part3` comme point de départ. + Exécutez ces commandes depuis l'intérieur du répertoire `hello-nf-core/` : + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Cela vous donne un pipeline avec le module `CAT_CAT` déjà intégré. + Vous pouvez tester qu'il s'exécute avec succès en exécutant la commande suivante : + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Transformer `cowpy` en un module nf-core + +Dans cette section, nous appliquerons les conventions nf-core au module local `cowpy` dans votre pipeline `core-hello`, le transformant en un module qui suit les normes de la communauté nf-core. + +Voici le code actuel du module de processus `cowpy` : + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Nous appliquerons les conventions nf-core suivantes de manière incrémentale : + +1. **Mettre le nom du processus en majuscules `COWPY`** pour suivre la convention. +2. **Mettre à jour `COWPY` pour utiliser des tuples de métadonnées** afin de propager les métadonnées d'échantillon à travers le workflow. +3. **Centraliser la configuration des arguments de l'outil avec `ext.args`** pour augmenter la polyvalence du module tout en gardant l'interface minimale. +4. **Standardiser la dénomination des sorties avec `ext.prefix`** pour promouvoir la cohérence. +5. **Centraliser la configuration de publication** pour promouvoir la cohérence. + +Après chaque étape, nous exécuterons le pipeline pour tester que tout fonctionne comme prévu. + +!!! warning "Répertoire de travail" + + Assurez-vous d'être dans le répertoire `core-hello` (la racine de votre pipeline) pour toutes les modifications de fichiers et l'exécution de commandes dans cette section. + + ```bash + cd core-hello + ``` + +### 1.1. Mettre le nom du processus en majuscules + +Il s'agit purement d'une convention stylistique (il n'y a pas de justification technique) mais comme c'est la norme pour les modules nf-core, conformons-nous. + +Nous devons effectuer trois séries de modifications : + +1. Mettre à jour le nom du processus dans le module +2. Mettre à jour l'instruction d'importation du module dans l'en-tête du workflow +3. Mettre à jour l'appel du processus et la déclaration emit dans le corps du workflow + +Commençons ! + +#### 1.1.1. Mettre à jour le nom du processus dans le module + +Ouvrez le fichier du module `cowpy.nf` (sous `core-hello/modules/local/`) et modifiez le nom du processus en majuscules : + +=== "Après" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Avant" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +Dans ce cas, la mise en majuscules est complètement directe. + +Si le nom du processus était composé de plusieurs mots, par exemple si nous avions un processus appelé MyCowpyTool à l'origine en camel case, la convention nf-core serait d'utiliser des underscores pour les séparer, donnant MY_COWPY_TOOL. + +#### 1.1.2. Mettre à jour l'instruction d'importation du module + +Les noms de processus sont sensibles à la casse, donc maintenant que nous avons changé le nom du processus, nous devons mettre à jour l'instruction d'importation du module en conséquence dans l'en-tête du workflow de `hello.nf` : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Nous pourrions utiliser un alias dans l'instruction d'importation pour éviter d'avoir à mettre à jour les appels au processus, mais cela irait quelque peu à l'encontre de l'objectif d'adopter la convention de mise en majuscules. + +#### 1.1.3. Mettre à jour l'appel du processus et la déclaration emit + +Maintenant, mettons à jour les deux références au processus dans le bloc workflow de `hello.nf` : + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // générer de l'art ASCII des salutations avec cowpy + COWPY(CAT_CAT.out.file_out) + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // générer de l'art ASCII des salutations avec cowpy + cowpy(CAT_CAT.out.file_out) + + // + // Rassembler et enregistrer les versions des logiciels + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Assurez-vous de faire les **deux** modifications, sinon vous obtiendrez une erreur lorsque vous exécuterez ceci. + +#### 1.1.4. Exécuter le pipeline pour le tester + +Exécutons le workflow pour tester que tout fonctionne correctement après ces modifications. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Très bien, cela fonctionne ! Maintenant, passons à des modifications plus substantielles. + +### 1.2. Mettre à jour `COWPY` pour utiliser des tuples de métadonnées + +Dans la version actuelle du pipeline `core-hello`, nous extrayons le fichier du tuple de sortie de `CAT_CAT` pour le passer à `COWPY`, comme indiqué dans la moitié supérieure du diagramme ci-dessous. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Il serait préférable que `COWPY` accepte directement des tuples de métadonnées, permettant aux métadonnées de circuler à travers le workflow, comme indiqué dans la moitié inférieure du diagramme. + +À cette fin, nous devrons effectuer les modifications suivantes : + +1. Mettre à jour les définitions d'entrée et de sortie +2. Mettre à jour l'appel du processus dans le workflow +3. Mettre à jour le bloc emit dans le workflow + +Une fois que nous aurons fait tout cela, nous exécuterons le pipeline pour tester que tout fonctionne encore comme avant. + +#### 1.2.1. Mettre à jour les définitions d'entrée et de sortie + +Revenez au fichier du module `cowpy.nf` et modifiez-le pour accepter des tuples de métadonnées comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Avant" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Comme vous pouvez le voir, nous avons modifié à la fois l'**entrée principale** et la **sortie** en un tuple qui suit le modèle `tuple val(meta), path(input_file)` introduit dans la Partie 3 de cette formation. +Pour la sortie, nous en avons également profité pour ajouter `emit: cowpy_output` afin de donner un nom descriptif au canal de sortie. + +Maintenant que nous avons modifié ce que le processus attend, nous devons mettre à jour ce que nous lui fournissons dans l'appel du processus. + +#### 1.2.2. Mettre à jour l'appel du processus dans le workflow + +La bonne nouvelle est que ce changement simplifiera l'appel du processus. +Maintenant que la sortie de `CAT_CAT` et l'entrée de `COWPY` ont la même 'forme', c'est-à-dire qu'elles consistent toutes deux en une structure `tuple val(meta), path(input_file)`, nous pouvons simplement les connecter directement au lieu d'avoir à extraire explicitement le fichier de la sortie du processus `CAT_CAT`. + +Ouvrez le fichier workflow `hello.nf` (sous `core-hello/workflows/`) et mettez à jour l'appel à `COWPY` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // générer de l'art ASCII des salutations avec cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extraire le fichier du tuple puisque cowpy n'utilise pas encore les métadonnées + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // générer de l'art ASCII des salutations avec cowpy + COWPY(ch_for_cowpy, params.character) + ``` + +Nous appelons maintenant `COWPY` directement sur `CAT_CAT.out.file_out`. + +Par conséquent, nous n'avons plus besoin de construire le canal `ch_for_cowpy`, donc cette ligne (et sa ligne de commentaire) peuvent être entièrement supprimées. + +#### 1.2.3. Mettre à jour le bloc emit dans le workflow + +Puisque `COWPY` émet maintenant une sortie nommée, `cowpy_output`, nous pouvons mettre à jour le bloc `emit:` du workflow `hello.nf` pour l'utiliser. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Ce n'est techniquement pas nécessaire, mais c'est une bonne pratique de faire référence aux sorties nommées chaque fois que possible. + +#### 1.2.4. Exécuter le pipeline pour le tester + +Exécutons le workflow pour tester que tout fonctionne correctement après ces modifications. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Le pipeline devrait s'exécuter avec succès, avec les métadonnées circulant maintenant de `CAT_CAT` à travers `COWPY`. + +Cela complète ce que nous devions faire pour que `COWPY` gère les tuples de métadonnées. +Maintenant, voyons ce que nous pouvons faire d'autre pour tirer parti des modèles de modules nf-core. + +### 1.3. Centraliser la configuration des arguments de l'outil avec `ext.args` + +Dans son état actuel, le processus `COWPY` s'attend à recevoir une valeur pour le paramètre `character`. +Par conséquent, nous devons fournir une valeur à chaque fois que nous appelons le processus, même si nous serions satisfaits des valeurs par défaut définies par l'outil. +Pour `COWPY`, ce n'est certes pas un gros problème, mais pour des outils avec de nombreux paramètres optionnels, cela peut devenir assez lourd. + +Le projet nf-core recommande d'utiliser une fonctionnalité de Nextflow appelée [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) pour gérer les arguments de l'outil plus commodément via des fichiers de configuration. + +Au lieu de déclarer des entrées de processus pour chaque option de l'outil, vous écrivez le module pour référencer `ext.args` dans la construction de sa ligne de commande. +Ensuite, il suffit de configurer la variable `ext.args` pour contenir les arguments et les valeurs que vous souhaitez utiliser dans le fichier `modules.config`, qui consolide les détails de configuration pour tous les modules. +Nextflow ajoutera ces arguments avec leurs valeurs dans la ligne de commande de l'outil au moment de l'exécution. + +Appliquons cette approche au module `COWPY`. +Nous allons devoir effectuer les modifications suivantes : + +1. Mettre à jour le module `COWPY` +2. Configurer `ext.args` dans le fichier `modules.config` +3. Mettre à jour le workflow `hello.nf` + +Une fois que nous aurons fait tout cela, nous exécuterons le pipeline pour tester que tout fonctionne encore comme avant. + +#### 1.3.1. Mettre à jour le module `COWPY` + +Faisons-le. +Ouvrez le fichier du module `cowpy.nf` (sous `core-hello/modules/local/`) et modifiez-le pour référencer `ext.args` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Avant" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Vous pouvez voir que nous avons fait trois modifications. + +1. **Dans le bloc `input:`, nous avons supprimé l'entrée `val character`.** + Dorénavant, nous fournirons cet argument via la configuration `ext.args` comme décrit ci-dessous. + +2. **Dans le bloc `script:`, nous avons ajouté la ligne `def args = task.ext.args ?: ''`.** + Cette ligne utilise l'opérateur `?:` pour déterminer la valeur de la variable `args` : le contenu de `task.ext.args` s'il n'est pas vide, ou une chaîne vide s'il l'est. + Notez que bien que nous fassions généralement référence à `ext.args`, ce code doit référencer `task.ext.args` pour extraire la configuration `ext.args` au niveau du module. + +3. **Dans la ligne de commande, nous avons remplacé `-c "$character"` par `$args`.** + C'est ici que Nextflow injectera tous les arguments de l'outil définis dans `ext.args` dans le fichier `modules.config`. + +Par conséquent, l'interface du module est maintenant plus simple : elle n'attend que les entrées essentielles de métadonnées et de fichiers. + +!!! note + + L'opérateur `?:` est souvent appelé 'opérateur Elvis' car il ressemble à un visage d'Elvis Presley de côté, avec le caractère `?` symbolisant la vague dans ses cheveux. + +#### 1.3.2. Configurer `ext.args` dans le fichier `modules.config` + +Maintenant que nous avons retiré la déclaration `character` du module, nous devons l'ajouter à `ext.args` dans le fichier de configuration `modules.config`. + +Plus précisément, nous allons ajouter ce petit morceau de code au bloc `process {}` : + +```groovy title="Code à ajouter" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +La syntaxe `withName:` assigne cette configuration uniquement au processus `COWPY`, et `ext.args = { "-c ${params.character}" }` compose simplement une chaîne qui inclura la valeur du paramètre `character`. +Notez l'utilisation des accolades, qui indiquent à Nextflow d'évaluer la valeur du paramètre au moment de l'exécution. + +C'est clair ? Ajoutons-le. + +Ouvrez `conf/modules.config` et ajoutez le code de configuration à l'intérieur du bloc `process {}` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Avant" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Vous pouvez probablement imaginer avoir tous les modules d'un pipeline avec leur `ext.args` spécifié dans ce fichier, avec les avantages suivants : + +- L'**interface du module reste simple** - Elle n'accepte que les entrées essentielles de métadonnées et de fichiers +- Le **pipeline expose toujours `params.character`** - Les utilisateurs finaux peuvent toujours le configurer comme avant +- Le **module est maintenant portable** - Il peut être réutilisé dans d'autres pipelines sans attendre un nom de paramètre spécifique +- La configuration est **centralisée** dans `modules.config`, gardant la logique du workflow propre + +En utilisant le fichier `modules.config` comme l'endroit où tous les pipelines centralisent la configuration par module, nous rendons nos modules plus réutilisables dans différents pipelines. + +#### 1.3.3. Mettre à jour le workflow `hello.nf` + +Puisque le module `COWPY` ne nécessite plus le paramètre `character` comme entrée, nous devons mettre à jour l'appel du workflow en conséquence. + +Ouvrez le fichier workflow `hello.nf` (sous `core-hello/workflows/`) et mettez à jour l'appel à `COWPY` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // générer de l'art ASCII des salutations avec cowpy + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Avant" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // générer de l'art ASCII des salutations avec cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +Le code du workflow est maintenant plus propre : nous n'avons pas besoin de passer `params.character` directement au processus. +L'interface du module est maintenue minimale, la rendant plus portable, tandis que le pipeline fournit toujours l'option explicite via la configuration. + +#### 1.3.4. Exécuter le pipeline pour le tester + +Testons que le workflow fonctionne toujours comme prévu, en spécifiant un caractère différent pour vérifier que la configuration `ext.args` fonctionne. + +Exécutez cette commande en utilisant `kosh`, l'une des options les plus... énigmatiques : + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Cela devrait s'exécuter avec succès comme précédemment. + +Vérifions que la configuration `ext.args` a fonctionné en vérifiant la sortie. +Trouvez la sortie dans le navigateur de fichiers ou utilisez le hash de tâche (la partie `38/eb29ea` dans l'exemple ci-dessus) pour regarder le fichier de sortie : + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Sortie de la commande" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +Vous devriez voir l'art ASCII affiché avec le caractère `kosh`, confirmant que la configuration `ext.args` a fonctionné ! + +??? info "(Optionnel) Inspecter le fichier de commande" + + Si vous voulez voir exactement comment la configuration a été appliquée, vous pouvez inspecter le fichier `.command.sh` : + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Vous verrez la commande `cowpy` avec l'argument `-c kosh` : + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Cela montre que le fichier `.command.sh` a été généré correctement en fonction de la configuration `ext.args`. + +Prenez un moment pour réfléchir à ce que nous avons accompli ici. +Cette approche maintient l'interface du module focalisée sur les données essentielles (fichiers, métadonnées et tous paramètres obligatoires par échantillon), tandis que les options qui contrôlent le comportement de l'outil sont gérées séparément via la configuration. + +Cela peut sembler inutile pour un outil simple comme `cowpy`, mais cela peut faire une grande différence pour les outils d'analyse de données qui ont beaucoup d'arguments optionnels. + +Pour résumer les avantages de cette approche : + +- **Interface propre** : Le module se concentre sur les entrées de données essentielles (métadonnées et fichiers) +- **Flexibilité** : Les utilisateurs peuvent spécifier les arguments de l'outil via la configuration, y compris des valeurs spécifiques aux échantillons +- **Cohérence** : Tous les modules nf-core suivent ce modèle +- **Portabilité** : Les modules peuvent être réutilisés sans options d'outils codées en dur +- **Pas de changements de workflow** : L'ajout ou la modification d'options d'outils ne nécessite pas de mise à jour du code du workflow + +!!! note + + Le système `ext.args` a des capacités supplémentaires puissantes non couvertes ici, y compris le changement dynamique des valeurs d'arguments en fonction des métadonnées. Consultez les [spécifications des modules nf-core](https://nf-co.re/docs/guidelines/components/modules) pour plus de détails. + +### 1.4. Standardiser la dénomination des sorties avec `ext.prefix` + +Maintenant que nous avons donné au processus `COWPY` accès au metamap, nous pouvons commencer à profiter d'un autre modèle utile de nf-core : nommer les fichiers de sortie en fonction des métadonnées. + +Ici, nous allons utiliser une fonctionnalité de Nextflow appelée `ext.prefix` qui nous permettra de standardiser la dénomination des fichiers de sortie dans tous les modules en utilisant `meta.id` (l'identifiant inclus dans le metamap), tout en étant capable de configurer les modules individuellement si désiré. + +Ce sera similaire à ce que nous avons fait avec `ext.args`, avec quelques différences que nous détaillerons au fur et à mesure. + +Appliquons cette approche au module `COWPY`. +Nous allons devoir effectuer les modifications suivantes : + +1. Mettre à jour le module `COWPY` +2. Configurer `ext.prefix` dans le fichier `modules.config` + +(Aucune modification nécessaire du workflow.) + +Une fois que nous aurons fait cela, nous exécuterons le pipeline pour tester que tout fonctionne encore comme avant. + +#### 1.4.1. Mettre à jour le module `COWPY` + +Ouvrez le fichier du module `cowpy.nf` (sous `core-hello/modules/local/`) et modifiez-le pour référencer `ext.prefix` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Avant" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Vous pouvez voir que nous avons fait trois modifications. + +1. **Dans le bloc `script:`, nous avons ajouté la ligne `prefix = task.ext.prefix ?: "${meta.id}"`.** + Cette ligne utilise l'opérateur `?:` pour déterminer la valeur de la variable `prefix` : le contenu de `task.ext.prefix` s'il n'est pas vide, ou l'identifiant du metamap (`meta.id`) s'il l'est. + Notez que bien que nous fassions généralement référence à `ext.prefix`, ce code doit référencer `task.ext.prefix` pour extraire la configuration `ext.prefix` au niveau du module. + +2. **Dans la ligne de commande, nous avons remplacé `cowpy-${input_file}` par `${prefix}.txt`.** + C'est ici que Nextflow injectera la valeur de `prefix` déterminée par la ligne ci-dessus. + +3. **Dans le bloc `output:`, nous avons remplacé `path("cowpy-${input_file}")` par `path("${prefix}.txt")`.** + Cela réitère simplement quel sera le chemin du fichier selon ce qui est écrit dans la ligne de commande. + +Par conséquent, le nom du fichier de sortie est maintenant construit en utilisant une valeur par défaut sensée (l'identifiant du metamap) combinée avec l'extension de format de fichier appropriée. + +#### 1.4.2. Configurer `ext.prefix` dans le fichier `modules.config` + +Dans ce cas, la valeur par défaut sensée n'est pas suffisamment expressive à notre goût ; nous voulons utiliser un modèle de dénomination personnalisé qui inclut le nom de l'outil, `cowpy-<id>.txt`, comme nous l'avions auparavant. + +Nous ferons cela en configurant `ext.prefix` dans `modules.config`, tout comme nous l'avons fait pour le paramètre `character` avec `ext.args`, sauf que cette fois le bloc `withName: 'COWPY' {}` existe déjà, et nous devons juste ajouter la ligne suivante : + +```groovy title="Code à ajouter" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Cela composera la chaîne que nous voulons. +Notez qu'une fois de plus nous utilisons des accolades, cette fois pour dire à Nextflow d'évaluer la valeur de `meta.id` au moment de l'exécution. + +Ajoutons-le. + +Ouvrez `conf/modules.config` et ajoutez le code de configuration à l'intérieur du bloc `process {}` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Avant" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Au cas où vous vous poseriez la question, la closure `ext.prefix` a accès à la bonne pièce de métadonnées car la configuration est évaluée dans le contexte de l'exécution du processus, où les métadonnées sont disponibles. + +#### 1.4.3. Exécuter le pipeline pour le tester + +Testons que le workflow fonctionne toujours comme prévu. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Regardez la sortie dans le répertoire des résultats. +Vous devriez voir le fichier de sortie cowpy avec la même dénomination qu'avant : `cowpy-test.txt`, basée sur le nom de lot par défaut. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +N'hésitez pas à modifier la configuration `ext.prefix` dans `conf/modules.config` pour vous assurer que vous pouvez changer le modèle de dénomination sans avoir à apporter de modifications au code du module ou du workflow. + +Alternativement, vous pouvez également essayer d'exécuter ceci à nouveau avec un paramètre `--batch` différent spécifié sur la ligne de commande pour vous assurer que cette partie est toujours personnalisable à la volée. + +Cela démontre comment `ext.prefix` vous permet de maintenir votre convention de dénomination préférée tout en gardant l'interface du module flexible. + +Pour résumer les avantages de cette approche : + +- **Dénomination standardisée** : Les fichiers de sortie sont généralement nommés en utilisant les identifiants d'échantillon des métadonnées +- **Configurable** : Les utilisateurs peuvent remplacer la dénomination par défaut si nécessaire +- **Cohérent** : Tous les modules nf-core suivent ce modèle +- **Prévisible** : Facile de savoir comment les fichiers de sortie seront appelés + +Plutôt bien, non ? +Eh bien, il y a encore une modification importante que nous devons faire pour améliorer notre module pour qu'il corresponde aux directives nf-core. + +### 1.5. Centraliser la configuration de publication + +Vous avez peut-être remarqué que nous avons publié des sorties dans deux répertoires différents : + +- **`results`** — Le répertoire de sortie original que nous utilisons depuis le début pour nos modules locaux, défini individuellement à l'aide de directives `publishDir` par module ; +- **`core-hello-results`** — Le répertoire de sortie défini avec `--outdir` sur la ligne de commande, qui a reçu les journaux nf-core et les résultats publiés par `CAT_CAT`. + +C'est désordonné et sous-optimal ; il serait préférable d'avoir un seul emplacement pour tout. +Bien sûr, nous pourrions aller dans chacun de nos modules locaux et mettre à jour la directive `publishDir` manuellement pour utiliser le répertoire `core-hello-results`, mais qu'en est-il la prochaine fois que nous décidons de changer le répertoire de sortie ? + +Avoir des modules individuels prendre des décisions de publication n'est clairement pas la voie à suivre, surtout dans un monde où le même module pourrait être utilisé dans beaucoup de pipelines différents, par des personnes qui ont des besoins ou des préférences différents. +Nous voulons pouvoir contrôler où les sorties sont publiées au niveau de la configuration du workflow. + +"Hé," pourriez-vous dire, "`CAT_CAT` envoie ses sorties au `--outdir`. Peut-être devrions-nous copier sa directive `publishDir` ?" + +Oui, c'est une excellente idée. + +Sauf qu'il n'a pas de directive `publishDir`. (Allez-y, regardez le code du module.) + +C'est parce que les pipelines nf-core centralisent le contrôle au niveau du workflow en configurant `publishDir` dans `conf/modules.config` plutôt que dans les modules individuels. +Plus précisément, le modèle nf-core déclare une directive `publishDir` par défaut (avec une structure de répertoire prédéfinie) qui s'applique à tous les modules sauf si une directive de remplacement est fournie. + +Cela ne semble-t-il pas génial ? Se pourrait-il que pour profiter de cette directive par défaut, tout ce que nous ayons à faire soit de supprimer la directive `publishDir` actuelle de nos modules locaux ? + +Essayons cela sur `COWPY` pour voir ce qui se passe, puis nous examinerons le code de la configuration par défaut pour comprendre comment cela fonctionne. + +Enfin, nous démontrerons comment remplacer le comportement par défaut si désiré. + +#### 1.5.1. Supprimer la directive `publishDir` de `COWPY` + +Faisons-le. +Ouvrez le fichier du module `cowpy.nf` (sous `core-hello/modules/local/`) et supprimez la directive `publishDir` comme indiqué ci-dessous. + +=== "Après" + + ```groovy title="core-hello/modules/local/cowpy.nf (extrait)" linenums="1" + #!/usr/bin/env nextflow + + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Avant" + + ```groovy title="core-hello/modules/local/cowpy.nf (extrait)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +C'est tout ! + +#### 1.5.2. Exécuter le pipeline pour le tester + +Voyons ce qui se passe si nous exécutons le pipeline maintenant. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Jetez un œil à votre répertoire de travail actuel. +Maintenant, `core-hello-results` contient également les sorties du module `COWPY`. + +??? abstract "Contenu du répertoire" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Vous pouvez voir que Nextflow a créé cette hiérarchie de répertoires basée sur les noms du workflow et du module. + +Le code responsable se trouve dans le fichier `conf/modules.config`. +Voici la configuration `publishDir` par défaut qui fait partie du modèle nf-core et s'applique à tous les processus : + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Cela peut paraître compliqué, alors regardons chacun des trois composants : + +- **`path:`** Détermine le répertoire de sortie en fonction du nom du processus. + Le nom complet d'un processus contenu dans `task.process` inclut la hiérarchie des importations de workflow et de modules (comme `CORE_HELLO:HELLO:CAT_CAT`). + Les opérations `tokenize` suppriment cette hiérarchie pour obtenir juste le nom du processus, puis prennent la première partie avant tout underscore (si applicable), et la convertissent en minuscules. + C'est ce qui détermine que les résultats de `CAT_CAT` sont publiés dans `${params.outdir}/cat/`. +- **`mode:`** Contrôle comment les fichiers sont publiés (copie, lien symbolique, etc.). + Ceci est configurable via le paramètre `params.publish_dir_mode`. +- **`saveAs:`** Filtre quels fichiers publier. + Cet exemple exclut les fichiers `versions.yml` en renvoyant `null` pour eux, les empêchant d'être publiés. + +Cela fournit une logique cohérente pour organiser les sorties. + +La sortie est encore meilleure lorsque tous les modules d'un pipeline adoptent cette convention, alors n'hésitez pas à supprimer les directives `publishDir` des autres modules de votre pipeline. +Cette valeur par défaut sera appliquée même aux modules que nous n'avons pas explicitement modifiés pour suivre les directives nf-core. + +Cela dit, vous pouvez décider que vous voulez organiser vos entrées différemment, et la bonne nouvelle est qu'il est facile de le faire. + +#### 1.5.3. Remplacer la valeur par défaut + +Pour remplacer la directive `publishDir` par défaut, vous pouvez simplement ajouter vos propres directives au fichier `conf/modules.config`. + +Par exemple, vous pourriez remplacer la valeur par défaut pour un seul processus en utilisant le sélecteur `withName:`, comme dans cet exemple où nous ajoutons une directive `publishDir` personnalisée pour le processus 'COWPY'. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +Nous n'allons pas réellement faire ce changement, mais n'hésitez pas à jouer avec cela et voir quelle logique vous pouvez implémenter. + +Le point est que ce système permet donne le meilleur des deux mondes : cohérence par défaut et flexibilité pour personnaliser la configuration à la demande. + +Pour résumer, vous obtenez : + +- **Source unique de vérité** : Toute la configuration de publication se trouve dans `modules.config` +- **Valeur par défaut utile** : Les processus fonctionnent prêts à l'emploi sans configuration par module +- **Personnalisation facile** : Remplacez le comportement de publication dans la configuration, pas dans le code du module +- **Modules portables** : Les modules ne codent pas en dur les emplacements de sortie + +Cela complète l'ensemble des fonctionnalités de modules nf-core que vous devriez absolument apprendre à utiliser, mais il en existe d'autres sur lesquelles vous pouvez lire dans les [spécifications des modules nf-core](https://nf-co.re/docs/guidelines/components/modules). + +### À retenir + +Vous savez maintenant comment adapter les modules locaux pour suivre les conventions nf-core : + +- Concevez vos modules pour accepter et propager des tuples de métadonnées ; +- Utilisez `ext.args` pour garder les interfaces de modules minimales et portables ; +- Utilisez `ext.prefix` pour une dénomination de fichiers de sortie standardisée et configurable ; +- Adoptez la directive `publishDir` centralisée par défaut pour une structure de répertoire de résultats cohérente. + +### Et ensuite ? + +Apprenez comment utiliser les outils intégrés de nf-core basés sur des modèles pour créer des modules de manière simple. + +--- + +## 2. Créer un module avec les outils nf-core + +Maintenant que vous avez appris les modèles de modules nf-core en les appliquant manuellement, voyons comment vous créeriez des modules en pratique. + +### 2.1. Générer un squelette de module à partir d'un modèle + +Similaire à ce qui existe pour créer des pipelines, le projet nf-core fournit des outils pour générer des modules correctement structurés basés sur un modèle, avec tous ces modèles intégrés dès le départ. + +#### 2.1.1. Exécuter la commande de création de module + +La commande `nf-core modules create` génère un modèle de module qui suit déjà toutes les conventions que vous avez apprises. + +Créons une nouvelle version du module `COWPY` avec un modèle minimal en exécutant cette commande : + +```bash +nf-core modules create --empty-template COWPY +``` + +Le drapeau `--empty-template` crée un modèle de démarrage propre sans code supplémentaire, facilitant la visualisation de la structure essentielle. + +La commande s'exécute de manière interactive, vous guidant à travers la configuration. +Elle recherche automatiquement les informations sur l'outil à partir de dépôts de paquets comme Bioconda et bio.tools pour pré-remplir les métadonnées. + +Vous serez invité à fournir plusieurs options de configuration : + +- **Informations sur l'auteur** : Votre nom d'utilisateur GitHub pour l'attribution +- **Étiquette de ressource** : Un ensemble prédéfini d'exigences de calcul. + Le projet nf-core fournit des étiquettes standard comme `process_single` pour les outils légers et `process_high` pour les outils exigeants. + Ces étiquettes aident à gérer l'allocation des ressources dans différents environnements d'exécution. +- **Exigence de métadonnées** : Si le module a besoin d'informations spécifiques aux échantillons via une map `meta` (généralement diff --git a/docs/fr/docs/hello_nf-core/05_input_validation.md b/docs/fr/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..33ffe4765c --- /dev/null +++ b/docs/fr/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Partie 5 : Validation des entrées + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette cinquième partie du cours de formation Hello nf-core, nous vous montrons comment utiliser le plugin nf-schema pour valider les entrées et les paramètres du pipeline. + +??? info "Comment commencer à partir de cette section" + + Cette section suppose que vous avez terminé la [Partie 4 : Créer un module nf-core](./04_make_module.md) et que vous avez mis à jour le module de processus `COWPY` aux standards nf-core dans votre pipeline. + + Si vous n'avez pas terminé la Partie 4 ou souhaitez repartir de zéro pour cette partie, vous pouvez utiliser la solution `core-hello-part4` comme point de départ. + Exécutez ces commandes depuis le répertoire `hello-nf-core/` : + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Cela vous donne un pipeline avec le module `COWPY` déjà mis à niveau pour suivre les standards nf-core. + Vous pouvez vérifier qu'il s'exécute avec succès en lançant la commande suivante : + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Échauffement : Un peu de contexte + +### 0.1. Pourquoi la validation est importante + +Imaginez exécuter votre pipeline pendant deux heures, pour qu'il plante parce qu'un utilisateur a fourni un fichier avec la mauvaise extension. Ou passer des heures à déboguer des erreurs cryptiques, pour découvrir qu'un paramètre était mal orthographié. Sans validation des entrées, ces scénarios sont courants. + +Considérez cet exemple : + +```console title="Sans validation" +$ nextflow run my-pipeline --input data.txt --output results + +...2 heures plus tard... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +Le pipeline a accepté des entrées invalides et s'est exécuté pendant des heures avant d'échouer. Avec une validation appropriée : + +```console title="Avec validation" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +Le pipeline échoue immédiatement avec des messages d'erreur clairs et exploitables. Cela économise du temps, des ressources de calcul et évite les frustrations. + +### 0.2. Le plugin nf-schema + +Le [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/) est un plugin Nextflow qui fournit des capacités de validation complètes pour les pipelines Nextflow. +Bien que nf-schema fonctionne avec n'importe quel workflow Nextflow, c'est la solution de validation standard pour tous les pipelines nf-core. + +nf-schema fournit plusieurs fonctions clés : + +- **Validation des paramètres** : Valide les paramètres du pipeline par rapport à `nextflow_schema.json` +- **Validation des feuilles d'échantillons** : Valide les fichiers d'entrée par rapport à `assets/schema_input.json` +- **Conversion de canaux** : Convertit les feuilles d'échantillons validées en canaux Nextflow +- **Génération de texte d'aide** : Génère automatiquement la sortie `--help` à partir des définitions de schéma +- **Résumé des paramètres** : Affiche les paramètres qui diffèrent des valeurs par défaut + +nf-schema est le successeur du plugin nf-validation (obsolète) et utilise le standard [JSON Schema Draft 2020-12](https://json-schema.org/) pour la validation. + +??? info "Qu'est-ce que les plugins Nextflow ?" + + Les plugins sont des extensions qui ajoutent de nouvelles fonctionnalités au langage Nextflow lui-même. Ils sont installés via un bloc `plugins{}` dans `nextflow.config` et peuvent fournir : + + - De nouvelles fonctions et classes qui peuvent être importées (comme `samplesheetToList`) + - De nouvelles fonctionnalités DSL et opérateurs + - Intégration avec des services externes + + Le plugin nf-schema est spécifié dans `nextflow.config` : + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Une fois installé, vous pouvez importer des fonctions depuis les plugins en utilisant la syntaxe `include { functionName } from 'plugin/plugin-name'`. + +### 0.3. Deux fichiers de schéma pour deux types de validation + +Un pipeline nf-core utilise deux fichiers de schéma distincts, qui correspondent à deux types de validation : + +| Fichier de schéma | Objectif | Valide | +| -------------------------- | ------------------------------- | --------------------------------------------------------------- | +| `nextflow_schema.json` | Validation des paramètres | Options en ligne de commande : `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Validation des données d'entrée | Contenu des feuilles d'échantillons et des fichiers d'entrée | + +Les deux schémas utilisent le format JSON Schema, un standard largement adopté pour décrire et valider les structures de données. + +**La validation des paramètres** valide les paramètres en ligne de commande (options comme `--outdir`, `--batch`, `--input`) : + +- Vérifie les types, plages et formats des paramètres +- S'assure que les paramètres requis sont fournis +- Valide que les chemins de fichiers existent +- Définie dans `nextflow_schema.json` + +**La validation des données d'entrée** valide la structure des feuilles d'échantillons et des fichiers de manifeste (fichiers CSV/TSV qui décrivent vos données) : + +- Vérifie la structure des colonnes et les types de données +- Valide que les chemins de fichiers référencés dans la feuille d'échantillons existent +- S'assure que les champs requis sont présents +- Définie dans `assets/schema_input.json` + +!!! warning "Ce que la validation des données d'entrée ne fait PAS" + + La validation des données d'entrée vérifie la structure des *fichiers de manifeste* (feuilles d'échantillons, fichiers CSV), PAS le contenu de vos fichiers de données réels (FASTQ, BAM, VCF, etc.). + + Pour des données à grande échelle, la validation du contenu des fichiers (comme la vérification de l'intégrité des BAM) devrait se faire dans les processus du pipeline exécutés sur les nœuds de travail, pas pendant l'étape de validation sur la machine d'orchestration. + +### 0.4. Quand la validation doit-elle se produire ? + +```mermaid +graph LR + A[L'utilisateur exécute le pipeline] --> B[Validation des paramètres] + B -->|✓ Valide| C[Validation des données d'entrée] + B -->|✗ Invalide| D[Erreur : Corrigez les paramètres] + C -->|✓ Valide| E[Le pipeline s'exécute] + C -->|✗ Invalide| F[Erreur : Corrigez les données d'entrée] +``` + +La validation devrait se produire **avant** l'exécution de tout processus du pipeline, pour fournir un retour rapide et éviter le gaspillage de temps de calcul. + +Appliquons maintenant ces principes en pratique, en commençant par la validation des paramètres. + +--- + +## 1. Validation des paramètres (nextflow_schema.json) + +Commençons par ajouter la validation des paramètres à notre pipeline. Cela valide les options en ligne de commande comme `--input`, `--outdir` et `--batch`. + +### 1.1. Configurer la validation pour ignorer la validation des fichiers d'entrée + +Le modèle de pipeline nf-core est livré avec nf-schema déjà installé et configuré : + +- Le plugin nf-schema est installé via le bloc `plugins{}` dans `nextflow.config` +- La validation des paramètres est activée par défaut via `params.validate_params = true` +- La validation est effectuée par le sous-workflow `UTILS_NFSCHEMA_PLUGIN` lors de l'initialisation du pipeline + +Le comportement de validation est contrôlé via la portée `validation{}` dans `nextflow.config`. + +Puisque nous allons d'abord travailler sur la validation des paramètres (cette section) et ne configurerons pas le schéma de données d'entrée avant la section 2, nous devons temporairement demander à nf-schema d'ignorer la validation du contenu du fichier du paramètre `input`. + +Ouvrez `nextflow.config` et trouvez le bloc `validation` (autour de la ligne 246). Ajoutez `ignoreParams` pour ignorer la validation des fichiers d'entrée : + +=== "Après" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Cette configuration indique à nf-schema de : + +- **`defaultIgnoreParams`** : Ignorer la validation des paramètres complexes comme `genomes` (défini par les développeurs du modèle) +- **`ignoreParams`** : Ignorer la validation du contenu du fichier du paramètre `input` (temporaire ; nous réactiverons cela dans la section 2) +- **`monochromeLogs`** : Désactiver la sortie colorée dans les messages de validation lorsque défini sur `true` (contrôlé par `params.monochrome_logs`) + +!!! note "Pourquoi ignorer le paramètre input ?" + + Le paramètre `input` dans `nextflow_schema.json` a `"schema": "assets/schema_input.json"` qui indique à nf-schema de valider le *contenu* du fichier CSV d'entrée par rapport à ce schéma. + Puisque nous n'avons pas encore configuré ce schéma, nous ignorons temporairement cette validation. + Nous supprimerons ce paramètre dans la section 2 après avoir configuré le schéma de données d'entrée. + +### 1.2. Examiner le schéma de paramètres + +Regardons une section du fichier `nextflow_schema.json` qui est fourni avec notre modèle de pipeline : + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +Le schéma de paramètres est organisé en groupes. Voici le groupe `input_output_options` : + +```json title="core-hello/nextflow_schema.json (extrait)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Chaque entrée décrite ici possède les propriétés clés suivantes qui peuvent être validées : + +- **`type`** : Type de données (string, integer, boolean, number) +- **`format`** : Formats spéciaux comme `file-path` ou `directory-path` +- **`exists`** : Pour les chemins de fichiers, vérifier si le fichier existe +- **`pattern`** : Expression régulière que la valeur doit respecter +- **`required`** : Tableau des noms de paramètres qui doivent être fournis +- **`mimetype`** : Type MIME attendu du fichier pour la validation + +Si vous avez l'œil aiguisé, vous remarquerez peut-être que le paramètre d'entrée `batch` que nous utilisons n'est pas encore défini dans le schéma. +Nous allons l'ajouter dans la section suivante. + +??? info "D'où viennent les paramètres du schéma ?" + + La validation du schéma utilise `nextflow.config` comme base pour les définitions de paramètres. + Les paramètres déclarés ailleurs dans vos scripts de workflow (comme dans `main.nf` ou les fichiers de modules) ne sont **pas** automatiquement récupérés par le validateur de schéma. + + Cela signifie que vous devez toujours déclarer vos paramètres de pipeline dans `nextflow.config`, puis définir leurs règles de validation dans `nextflow_schema.json`. + +### 1.3. Ajouter le paramètre batch + +Bien que le schéma soit un fichier JSON qui peut être édité manuellement, **l'édition manuelle est sujette aux erreurs et n'est pas recommandée**. +À la place, nf-core fournit un outil GUI interactif qui gère la syntaxe JSON Schema pour vous et valide vos modifications : + +```bash +nf-core pipelines schema build +``` + +Vous devriez voir quelque chose comme ceci : + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Tapez `y` et appuyez sur Entrée pour lancer l'interface web interactive. + +Votre navigateur s'ouvrira affichant le constructeur de schéma de paramètres : + +![Interface du constructeur de schéma](./img/schema_build.png) + +Pour ajouter le paramètre `batch` : + +1. Cliquez sur le bouton **"Add parameter"** en haut +2. Utilisez la poignée de glissement (⋮⋮) pour déplacer le nouveau paramètre vers le haut dans le groupe "Input/output options", sous le paramètre `input` +3. Remplissez les détails du paramètre : + - **ID** : `batch` + - **Description** : `Name for this batch of greetings` + - **Type** : `string` + - **Required** : cochez la case + - Optionnellement, sélectionnez une icône dans le sélecteur d'icônes (par ex., `fas fa-layer-group`) + +![Ajout du paramètre batch](./img/schema_add.png) + +Lorsque vous avez terminé, cliquez sur le bouton **"Finished"** en haut à droite. + +De retour dans votre terminal, vous verrez : + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Appuyez sur `Ctrl+C` pour quitter le constructeur de schéma. + +L'outil a maintenant mis à jour votre fichier `nextflow_schema.json` avec le nouveau paramètre `batch`, en gérant correctement toute la syntaxe JSON Schema. + +### 1.4. Vérifier les modifications + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (extrait)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Vous devriez voir que le paramètre `batch` a été ajouté au schéma avec le champ "required" affichant maintenant `["input", "outdir", "batch"]`. + +### 1.5. Tester la validation des paramètres + +Testons maintenant que la validation des paramètres fonctionne correctement. + +D'abord, essayez d'exécuter sans le paramètre requis `input` : + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Sortie de la commande" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Parfait ! La validation détecte le paramètre requis manquant avant l'exécution du pipeline. + +Maintenant essayez avec un ensemble de paramètres valides : + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Le pipeline devrait s'exécuter avec succès, et le paramètre `batch` est maintenant validé. + +### À retenir + +Vous avez appris à utiliser l'outil interactif `nf-core pipelines schema build` pour ajouter des paramètres à `nextflow_schema.json` et vous avez vu la validation des paramètres en action. +L'interface web gère toute la syntaxe JSON Schema pour vous, facilitant la gestion de schémas de paramètres complexes sans édition manuelle de JSON sujette aux erreurs. + +### Et ensuite ? + +Maintenant que la validation des paramètres fonctionne, ajoutons la validation du contenu des fichiers de données d'entrée. + +--- + +## 2. Validation des données d'entrée (schema_input.json) + +Nous allons ajouter la validation du contenu de notre fichier CSV d'entrée. +Alors que la validation des paramètres vérifie les options en ligne de commande, la validation des données d'entrée s'assure que les données à l'intérieur du fichier CSV sont structurées correctement. + +### 2.1. Comprendre le format de greetings.csv + +Rappelons-nous à quoi ressemble notre entrée : + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Il s'agit d'un simple CSV avec : + +- Trois colonnes (sans en-tête) +- Sur chaque ligne : une salutation, une langue et un score +- Les deux premières colonnes sont des chaînes de texte sans exigences de format particulières +- La troisième colonne est un entier + +Pour notre pipeline, seule la première colonne est requise. + +### 2.2. Concevoir la structure du schéma + +Pour notre cas d'usage, nous voulons : + +1. Accepter une entrée CSV avec au moins une colonne +2. Traiter le premier élément de chaque ligne comme une chaîne de salutation +3. S'assurer que les salutations ne sont pas vides et ne commencent pas par un espace +4. S'assurer que le champ de langue correspond à l'un des codes de langue pris en charge (en, fr, es, it, de) +5. S'assurer que le champ de score est un entier avec une valeur entre 0 et 100 + +Nous structurerons cela comme un tableau d'objets, où chaque objet a au moins un champ `greeting`. + +### 2.3. Mettre à jour le fichier de schéma + +Le modèle de pipeline nf-core inclut un fichier par défaut `assets/schema_input.json` conçu pour les données de séquençage en paired-end. +Nous devons le remplacer par un schéma plus simple pour notre cas d'usage de salutations. + +Ouvrez `assets/schema_input.json` et remplacez les sections `properties` et `required` : + +=== "Après" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Avant" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Les modifications clés : + +- **`description`** : Mise à jour pour mentionner "greetings file" +- **`properties`** : Remplacement de `sample`, `fastq_1`, et `fastq_2` par `greeting`, `language`, et `score` + - **`type:`** Imposer soit string (`greeting`, `language`) soit integer (`score`) + - **`pattern: "^\\S.*$"`** : La salutation doit commencer par un caractère non-espace (mais peut contenir des espaces après) + - **`"enum": ["en", "fr", "es", "it", "de"]`** : Le code de langue doit être dans l'ensemble supporté + - **`"minimum": 0` et `"maximum": 100`** : La valeur du score doit être entre 0 et 100 + - **`errorMessage`** : Message d'erreur personnalisé affiché si la validation échoue +- **`required`** : Changé de `["sample", "fastq_1"]` à `["greeting"]` + +### 2.4. Ajouter un en-tête au fichier greetings.csv + +Lorsque nf-schema lit un fichier CSV, il s'attend à ce que la première ligne contienne des en-têtes de colonnes qui correspondent aux noms de champs dans le schéma. + +Pour notre cas simple, nous devons ajouter une ligne d'en-tête à notre fichier de salutations : + +=== "Après" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Avant" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Maintenant le fichier CSV a une ligne d'en-tête qui correspond aux noms de champs dans notre schéma. + +L'étape finale consiste à implémenter la validation dans le code du pipeline en utilisant `samplesheetToList`. + +### 2.5. Implémenter la validation dans le pipeline + +Nous devons maintenant remplacer notre analyse CSV simple par la fonction `samplesheetToList` de nf-schema, qui validera et analysera la feuille d'échantillons. + +La fonction `samplesheetToList` : + +1. Lit la feuille d'échantillons d'entrée (CSV, TSV, JSON ou YAML) +2. La valide par rapport au schéma JSON fourni +3. Retourne une liste Groovy où chaque entrée correspond à une ligne +4. Génère des messages d'erreur utiles si la validation échoue + +Mettons à jour le code de gestion des entrées : + +Ouvrez `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` et localisez la section où nous créons le canal d'entrée (autour de la ligne 80). + +Nous devons : + +1. Utiliser la fonction `samplesheetToList` (déjà importée dans le modèle) +2. Valider et analyser l'entrée +3. Extraire uniquement les chaînes de salutation pour notre workflow + +D'abord, notez que la fonction `samplesheetToList` est déjà importée en haut du fichier (le modèle nf-core l'inclut par défaut) : + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Sous-workflow avec des fonctionnalités spécifiques au pipeline core/hello +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT DES FONCTIONS / MODULES / SOUS-WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Maintenant mettez à jour le code de création du canal : + +=== "Après" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Crée un canal à partir du fichier d'entrée fourni via params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Avant" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Crée un canal à partir du fichier d'entrée fourni via params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Décomposons ce qui a changé : + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`** : Valide le fichier d'entrée par rapport à notre schéma et retourne une liste +2. **`Channel.fromList(...)`** : Convertit la liste en un canal Nextflow + +Ceci complète l'implémentation de la validation des données d'entrée en utilisant `samplesheetToList` et les schémas JSON. + +Maintenant que nous avons configuré le schéma de données d'entrée, nous pouvons supprimer le paramètre d'ignore temporaire que nous avons ajouté plus tôt. + +### 2.6. Réactiver la validation des entrées + +Ouvrez `nextflow.config` et supprimez la ligne `ignoreParams` du bloc `validation` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Maintenant nf-schema validera à la fois les types de paramètres ET le contenu du fichier d'entrée. + +### 2.7. Tester la validation des entrées + +Vérifions que notre validation fonctionne en testant des entrées valides et invalides. + +#### 2.7.1. Tester avec une entrée valide + +D'abord, confirmez que le pipeline s'exécute avec succès avec une entrée valide. +Notez que nous n'avons plus besoin de `--validate_params false` puisque la validation fonctionne ! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Sortie de la commande" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Excellent ! Le pipeline s'exécute avec succès et la validation se passe silencieusement. +L'avertissement concernant `--character` est juste informatif puisqu'il n'est pas défini dans le schéma. +Si vous le souhaitez, utilisez ce que vous avez appris pour ajouter également la validation de ce paramètre ! + +#### 2.7.2. Tester avec une entrée invalide + +Réussir la validation est toujours une bonne sensation, mais assurons-nous que la validation détectera réellement les erreurs. + +Pour créer un fichier de test avec un nom de colonne invalide, commencez par faire une copie du fichier `greetings.csv` : + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Maintenant ouvrez le fichier et changez le nom de la première colonne, dans la ligne d'en-tête, de `greeting` à `message` : + +=== "Après" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Avant" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Cela ne correspond pas à notre schéma, donc la validation devrait générer une erreur. + +Essayez d'exécuter le pipeline avec cette entrée invalide : + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Parfait ! La validation a détecté l'erreur et fourni un message d'erreur clair et utile indiquant : + +- Quel fichier a échoué à la validation +- Quelle entrée (ligne 1, la première ligne de données) a le problème +- Quel est le problème spécifique (champ requis `greeting` manquant) + +La validation du schéma garantit que les fichiers d'entrée ont la structure correcte avant l'exécution du pipeline, économisant du temps et évitant des erreurs confuses plus tard dans l'exécution. + +Si vous souhaitez vous entraîner, n'hésitez pas à créer d'autres fichiers d'entrée de salutations qui violent le schéma d'autres manières amusantes. + +### À retenir + +Vous avez implémenté et testé à la fois la validation des paramètres et la validation des données d'entrée. Votre pipeline valide maintenant les entrées avant l'exécution, fournissant un retour rapide et des messages d'erreur clairs. + +!!! tip "Pour aller plus loin" + + Pour en savoir plus sur les fonctionnalités et modèles de validation avancés, consultez la [documentation nf-schema](https://nextflow-io.github.io/nf-schema/latest/). La commande `nf-core pipelines schema build` fournit une interface graphique interactive pour gérer des schémas complexes. + +### Et ensuite ? + +Vous avez terminé les cinq parties du cours de formation Hello nf-core ! + +Continuez vers le [Résumé](summary.md) pour réfléchir à ce que vous avez construit et appris. diff --git a/docs/fr/docs/hello_nf-core/index.md b/docs/fr/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..d1367095bc --- /dev/null +++ b/docs/fr/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Récupérer, lancer et gérer l'exécution de pipelines nf-core + - Décrire la structure du code et l'organisation de projet des pipelines nf-core + - Créer un pipeline compatible nf-core de base à partir d'un modèle + - Mettre à niveau un workflow Nextflow simple pour respecter les standards nf-core + - Ajouter des modules nf-core à un pipeline compatible nf-core + - Contribuer vos propres modules à nf-core + - Valider les entrées et les paramètres en utilisant les outils nf-core + audience_prerequisites: + - "**Public :** Ce cours est conçu pour les apprenants qui connaissent déjà les bases de Nextflow et souhaitent apprendre à utiliser les ressources et les bonnes pratiques nf-core." + - "**Compétences :** Une familiarité avec la ligne de commande, les concepts de base de script et les formats de fichiers courants est supposée." + - "**Cours :** Vous devez avoir terminé le cours [Hello Nextflow](../hello_nextflow/index.md) ou équivalent." + - "**Domaine :** Les exercices sont tous indépendants du domaine scientifique, donc aucune connaissance scientifique préalable n'est requise." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core est une introduction pratique à l'utilisation des ressources et des bonnes pratiques nf-core.** + +![logo nf-core](./img/nf-core-logo.png) + +En travaillant sur des exemples pratiques et des exercices guidés, vous apprendrez à utiliser et développer des modules et pipelines compatibles nf-core, et à utiliser efficacement les outils nf-core. + +Vous acquerrez les compétences et la confiance nécessaires pour commencer à développer des pipelines selon les bonnes pratiques nf-core. + +<!-- additional_information --> + +## Aperçu du cours + +Ce cours est conçu pour être pratique, avec des exercices orientés objectifs structurés pour introduire l'information progressivement. + +Vous serez initié à [**nf-core**](https://nf-co.re/), un effort communautaire pour développer et maintenir un ensemble organisé de pipelines scientifiques construits avec Nextflow, ainsi que les outils et directives pertinents qui favorisent le développement ouvert, les tests et l'évaluation par les pairs ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +Les pipelines développés par la communauté nf-core sont conçus pour être modulaires, évolutifs et portables, permettant aux chercheurs de les adapter et de les exécuter facilement avec leurs propres données et ressources de calcul. +Les directives de bonnes pratiques imposées par le projet garantissent en outre que les pipelines sont robustes, bien documentés et validés sur des ensembles de données réels. +Cela contribue à augmenter la fiabilité et la reproductibilité des analyses scientifiques et permet finalement aux chercheurs d'accélérer leurs découvertes scientifiques. + +Nous ne couvrirons pas tout ce qu'il y a à savoir sur les pipelines nf-core dans ce cours, car nf-core englobe de nombreuses fonctionnalités et conventions développées par la communauté au fil des années. +Au lieu de cela, nous nous concentrerons sur les concepts essentiels qui vous aideront à démarrer et à comprendre comment fonctionne nf-core. + +### Plan de cours + +Nous avons divisé cela en cinq parties qui se concentreront chacune sur des aspects spécifiques de l'utilisation des ressources nf-core. + +| Chapitre du cours | Résumé | Durée estimée | +| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| [Partie 1 : Exécuter un pipeline de démonstration](./01_run_demo.md) | Exécuter un pipeline nf-core existant et examiner sa structure de code pour avoir une idée de ce qui distingue ces pipelines des workflows Nextflow de base | 30 min | +| [Partie 2 : Réécrire Hello pour nf-core](./02_rewrite_hello.md) | Adapter un workflow existant à la structure du modèle nf-core, en partant du workflow simple produit dans le cours [Hello Nextflow](../hello_nextflow/index.md) | 60 min | +| [Partie 3 : Utiliser un module nf-core](./03_use_module.md) | Explorer la bibliothèque de modules de la communauté et apprendre à intégrer des modules pré-construits et testés qui encapsulent des outils bioinformatiques courants | 30 min | +| [Partie 4 : Créer un module nf-core](./04_make_module.md) | Créer votre propre module de style nf-core en utilisant la structure spécifique, les conventions de nommage et les exigences de métadonnées établies par nf-core | 30 min | +| [Partie 5 : Ajouter la validation des entrées](./05_input_validation.md) | Implémenter la validation des entrées pour les paramètres de ligne de commande et les fichiers de données d'entrée en utilisant nf-schema | 30 min | + +À la fin de ce cours, vous serez capable de tirer parti de l'énorme richesse de ressources offertes par le projet nf-core. + +Prêt à commencer le cours ? + +[Commencer l'apprentissage :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/fr/docs/hello_nf-core/next_steps.md b/docs/fr/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..68439059ed --- /dev/null +++ b/docs/fr/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Résumé du cours + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations pour avoir terminé le cours de formation Hello nf-core ! 🎉 + +<!-- placeholder for video --> + +## Votre parcours + +Vous avez commencé par apprendre à récupérer et exécuter un pipeline de démonstration, puis vous avez abordé la conversion d'un simple workflow Nextflow en pipeline nf-core. +Vous avez appris à créer une structure de pipeline à l'aide d'un modèle et à greffer le pipeline existant sur cette structure. +Ensuite, vous avez progressivement affiné le pipeline en remplaçant l'un des modules locaux par un module nf-core, transformé un autre module local pour qu'il respecte les normes nf-core, et ajouté la validation des entrées. + +### Ce que vous avez construit + +Votre pipeline final `core-hello` possède maintenant : + +- **Une structure standardisée** utilisant le modèle nf-core avec des répertoires organisés pour les workflows, les subworkflows, les modules et la configuration +- **Des modules communautaires** du dépôt nf-core (`cat/cat`) aux côtés de vos modules personnalisés +- **Une validation complète** qui vérifie à la fois les paramètres et les données d'entrée avant l'exécution du pipeline +- **Une configuration professionnelle** avec des profils pour différents environnements d'exécution +- **Une documentation complète** et des métadonnées suivant les conventions nf-core + +### Compétences clés acquises + +Grâce à ce cours pratique, vous avez appris à : + +1. **Naviguer et comprendre** la structure d'un pipeline nf-core en explorant un pipeline existant +2. **Restructurer les workflows** pour les rendre composables et les adapter au modèle nf-core +3. **Trouver et intégrer** des modules pré-construits du dépôt communautaire +4. **Créer des modules personnalisés** en suivant les normes nf-core pour le nommage, la structure et les métadonnées +5. **Mettre en œuvre la validation** en utilisant nf-schema pour détecter les erreurs tôt avec des retours clairs + +Vous êtes maintenant équipé des connaissances fondamentales pour construire des pipelines nf-core prêts pour la production qui suivent les meilleures pratiques de la communauté. + +## Prochaines étapes pour développer vos compétences + +Voici nos 3 principales suggestions pour la suite : + +- Appliquez Nextflow à un cas d'usage d'analyse scientifique avec [Nextflow for Science](../nf4_science/index.md) +- Explorez des fonctionnalités Nextflow plus avancées avec les [Side Quests](../side_quests/index.md) +- Impliquez-vous en [rejoignant la communauté nf-core](https://nf-co.re/join). + +Enfin, nous vous recommandons de jeter un œil à [**Seqera Platform**](https://seqera.io/), une plateforme cloud développée par les créateurs de Nextflow qui facilite encore davantage le lancement et la gestion de vos workflows, ainsi que la gestion de vos données et l'exécution d'analyses interactives dans n'importe quel environnement. + +## Questionnaire de satisfaction + +Avant de continuer, veuillez prendre une minute pour compléter le questionnaire du cours ! Vos retours nous aident à améliorer nos supports de formation pour tous. + +[Répondre au questionnaire :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/fr/docs/hello_nf-core/survey.md b/docs/fr/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..a5f1118d79 --- /dev/null +++ b/docs/fr/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Enquête de retour d'expérience + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Avant de poursuivre, veuillez compléter cette courte enquête de 5 questions pour évaluer la formation, partager vos commentaires sur votre expérience, et nous faire savoir ce que nous pourrions faire d'autre pour vous aider dans votre parcours avec Nextflow. + +Cela devrait vous prendre moins d'une minute. Merci de nous aider à améliorer nos supports de formation pour tous ! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/fr/docs/help.md b/docs/fr/docs/help.md new file mode 100644 index 0000000000..049eb55d34 --- /dev/null +++ b/docs/fr/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Obtenir de l'aide +description: Ressources utiles lorsque vous rencontrez un problème avec la formation Nextflow +hide: + - toc + - footer +--- + +# Obtenir de l'aide + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Que vous ayez des difficultés à démarrer, que vous soyez bloqué en cours de route ou que vous ayez des questions de suivi, n'hésitez pas à nous contacter ! Notre équipe communautaire est là pour vous aider, et la communauté Nextflow au sens large est très active, inclusive et désireuse d'aider. + +Voici les principales options disponibles selon ce que vous recherchez. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Forum communautaire__ + + --- + + Notre forum communautaire dispose d'une catégorie dédiée à la formation, qui est un excellent endroit pour poser des questions ou signaler tout problème que vous pourriez rencontrer avec la formation. Vous pourriez même constater que votre question a déjà été posée — et répondue ! + + [Rejoindre le forum de formation :material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Canal Slack__ + + --- + + Si vous êtes sur Slack, vous êtes invité à nous contacter dans le canal de formation de l'espace de travail Slack Nextflow. Le Slack Nextflow est un excellent endroit pour discuter avec d'autres développeurs et interagir avec la communauté Nextflow en général. + + [Rejoindre le Slack Nextflow :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Issues GitHub__ + + --- + + Si vous repérez une erreur dans les supports de formation, veuillez la signaler en ouvrant une issue dans le dépôt GitHub. Qu'il s'agisse d'une faute de frappe, d'un problème de mise en forme ou d'un véritable bogue affectant le code, faites-le nous savoir afin que nous puissions le corriger ! Nous acceptons également les PR directement. + + [Signaler un problème :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Assistant IA Seqera__ + + --- + + Seqera AI est un assistant IA formé sur les ressources Nextflow et nf-core. Il peut vous aider à déboguer votre code, clarifier les concepts Nextflow et rechercher de la documentation plus rapidement. Considérez-le comme un tuteur disponible 24h/24 et 7j/7 pendant que vous travaillez sur les cours. + + [Demander à Seqera AI :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Documentation Nextflow__ + + --- + + La documentation officielle est le guide ultime pour toutes les fonctionnalités du langage et les options de configuration. Utilisez-la en parallèle de cette formation pour approfondir des sujets spécifiques, explorer des fonctionnalités avancées et trouver des références de syntaxe détaillées. + + [Parcourir la documentation :material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Support professionnel__ + + --- + + Nextflow est un logiciel libre et gratuit développé par [Seqera](https://seqera.io/), une entreprise basée en Espagne avec des bureaux satellites au Royaume-Uni et aux États-Unis. Nous offrons des services de support professionnel pour Nextflow, y compris des formations personnalisées. + + [Nous contacter :material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/fr/docs/index.md b/docs/fr/docs/index.md new file mode 100644 index 0000000000..f455e3712b --- /dev/null +++ b/docs/fr/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Accueil +description: Bienvenue sur le portail de formation de la communauté Nextflow ! +hide: + - toc + - footer +--- + +# Formation Nextflow + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Cours en libre-service__ + + --- + + **Bienvenue sur le portail de formation de la communauté Nextflow !** + + Les cours de formation listés ci-dessous sont conçus pour être utilisés en libre-service. + Vous pouvez les suivre à votre rythme, à tout moment, soit dans l'environnement web que nous fournissons via GitHub Codespaces, soit dans votre propre environnement. + + [Explorer les cours :material-arrow-right:](#catalogue-des-cours-de-formation-nextflow){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Informations complémentaires__ + + --- + + ??? warning "Compatibilité des versions" + + <!-- Any update to this content needs to be copied to the local installation page --> + **Depuis janvier 2026, tous nos cours de formation Nextflow nécessitent Nextflow version 25.10.2 ou ultérieure, avec la syntaxe stricte activée, sauf indication contraire.** + + Pour plus d'informations sur les exigences de version et la syntaxe stricte, veuillez consulter le [guide de migration de la documentation Nextflow](https://nextflow.io/docs/latest/strict-syntax.html). + + Les anciennes versions du matériel de formation correspondant aux syntaxes antérieures sont disponibles via le sélecteur de version dans la barre de menu de cette page web. + + ??? terminal "Options d'environnement" + + Nous fournissons un environnement de formation web où tout ce dont vous avez besoin pour suivre la formation est préinstallé, accessible via GitHub Codespaces (nécessite un compte GitHub gratuit). + + [![Ouvrir dans GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Si cela ne convient pas à vos besoins, veuillez consulter les autres [options d'environnement](./envsetup/index.md). + + ??? learning "Événements de formation" + + Si vous préférez suivre une formation Nextflow dans le cadre d'un événement structuré, de nombreuses opportunités s'offrent à vous. Nous vous recommandons de consulter les options suivantes : + + - **[Semaines de formation]()** organisées trimestriellement par l'équipe communautaire + - **[Événements Seqera](https://seqera.io/events/)** incluant des événements de formation en personne organisés par Seqera (recherchez « Seqera Sessions » et « Nextflow Summit ») + - **[Ambassadeurs Nextflow]()** qui organisent des événements pour leur communauté locale + - **[Événements nf-core](https://nf-co.re/events)** incluant des hackathons communautaires + + ??? people "Informations pour les formateurs" + + Si vous êtes un formateur qui organise vos propres formations, vous êtes invité à utiliser nos supports directement depuis le portail de formation à condition d'attribuer les crédits appropriés. Voir « Crédits et contributions » ci-dessous pour plus de détails. + + De plus, nous aimerions avoir de vos nouvelles sur la façon dont nous pourrions mieux soutenir vos efforts de formation ! Veuillez nous contacter à [community@seqera.io](mailto:community@seqera.io) ou sur le forum communautaire (voir la page [Aide](help.md)). + + ??? licensing "Licence open-source et politique de contribution" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Ce matériel de formation est développé et maintenu par [Seqera](https://seqera.io) et publié sous licence open-source ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) au bénéfice de la communauté. Si vous souhaitez utiliser ce matériel d'une manière qui sort du cadre de la licence (notez les limitations sur l'utilisation commerciale et la redistribution), veuillez nous contacter à [community@seqera.io](mailto:community@seqera.io) pour discuter de votre demande. + + Nous accueillons les améliorations, corrections et rapports de bogues de la communauté. Chaque page possède une icône :material-file-edit-outline: en haut à droite qui renvoie au dépôt de code, où vous pouvez signaler des problèmes ou proposer des modifications au matériel source de formation via une pull request. Consultez le fichier `README.md` dans le dépôt pour plus de détails. + +</div> + +!!! note "Traduction assistée par IA" + + Cette traduction a été réalisée à l'aide de l'intelligence artificielle et révisée par des traducteurs humains. + Vos commentaires et suggestions d'amélioration sont les bienvenus. + Consultez notre [guide de traduction](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) pour plus d'informations. + +## Catalogue des cours de formation Nextflow + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Parcours d'introduction__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow pour les débutants {.mt-1} + + Cours indépendants du domaine destinés à ceux qui découvrent complètement Nextflow. Chaque cours se compose d'une série de modules de formation conçus pour aider les apprenants à développer progressivement leurs compétences. + + ??? courses "**Hello Nextflow :** Apprenez à développer vos propres pipelines" + + Ce cours couvre les composants essentiels du langage Nextflow avec suffisamment de détails pour permettre le développement de pipelines simples mais pleinement fonctionnels, ainsi que les éléments clés des pratiques de conception, de développement et de configuration de pipelines. + + [Commencer la formation Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run :** Apprenez à exécuter des pipelines existants" + + Une introduction concise à l'exécution et à la configuration des pipelines Nextflow, basée sur le cours Hello Nextflow pour développeurs mais avec moins d'accent sur le code. Couvre l'exécution, les sorties, la structure de base du code et la configuration pour différents environnements de calcul. + + [Commencer la formation Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow pour la science {.mt-1} + + Apprenez à appliquer les concepts et composants présentés dans « Hello Nextflow » à des cas d'utilisation scientifiques spécifiques. + + ??? courses "**Nextflow pour la génomique** (appel de variants)" + + Pour les chercheurs qui souhaitent apprendre à développer leurs propres pipelines génomiques. Ce cours utilise un cas d'utilisation d'appel de variants pour démontrer comment développer un pipeline génomique simple mais fonctionnel. + + [Commencer la formation Nextflow pour la génomique :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow pour RNAseq** (RNAseq en vrac)" + + Pour les chercheurs qui souhaitent apprendre à développer leurs propres pipelines RNAseq. Ce cours utilise un cas d'utilisation de traitement RNAseq en vrac pour démontrer comment développer un pipeline RNAseq simple mais fonctionnel. + + [Commencer la formation Nextflow pour RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow pour l'imagerie** (omiques spatiales)" + + Pour les chercheurs en imagerie et omiques spatiales qui souhaitent apprendre à exécuter et personnaliser des pipelines d'analyse. Ce cours utilise le pipeline nf-core/molkart pour fournir un pipeline biologiquement pertinent et démontrer comment exécuter, configurer et gérer les entrées pour les flux de travail Nextflow. + + [Commencer la formation Nextflow pour l'imagerie :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Parcours avancé__ + + --- + + ### :material-bridge:{.nextflow-primary} De Nextflow à nf-core {.mt-1} + + Apprenez à utiliser le code et les bonnes pratiques du projet communautaire [nf-core](https://nf-co.re/). + + Ces cours vous aident à passer des fondamentaux de Nextflow aux bonnes pratiques nf-core. + Comprenez comment et pourquoi la communauté nf-core construit des pipelines, et comment vous pouvez contribuer et réutiliser ces techniques. + + ??? courses "**Hello nf-core :** Démarrer avec nf-core" + + Pour les développeurs qui souhaitent apprendre à exécuter et développer des pipelines conformes à [nf-core](https://nf-co.re/). Ce cours couvre la structure des pipelines nf-core avec suffisamment de détails pour permettre le développement de pipelines simples mais pleinement fonctionnels qui suivent le modèle nf-core et les bonnes pratiques de développement, ainsi que l'utilisation des modules nf-core existants. + + [Commencer la formation Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Formation Nextflow avancée {.mt-1} + + Apprenez des concepts et mécanismes avancés pour développer et déployer des pipelines Nextflow afin de répondre à des cas d'utilisation réels. + + ??? courses "**Quêtes annexes :** Approfondissements sur des sujets autonomes" + + Mini-cours autonomes destinés aux développeurs Nextflow qui souhaitent élargir leur éventail de compétences et/ou approfondir leurs connaissances sur des sujets particuliers. Ils sont présentés de manière linéaire mais peuvent être suivis dans n'importe quel ordre (voir les dépendances dans chaque aperçu de mini-cours). + + [Parcourir les quêtes annexes :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Collections de formation :** Parcours d'apprentissage recommandés à travers les quêtes annexes" + + Les collections de formation combinent plusieurs quêtes annexes afin de fournir une expérience d'apprentissage complète autour d'un thème ou d'un cas d'utilisation particulier. + + [Parcourir les collections de formation :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Vous recherchez des supports de formation archivés ?" + + Les anciens supports de formation (Formation Fondamentale, Formation Avancée et autres cours expérimentaux) ont été retirés du portail de formation car ils sont incompatibles avec la syntaxe stricte de Nextflow 3.0. + Si vous avez besoin d'accéder à ces supports, ils sont disponibles dans l'[historique git](https://github.com/nextflow-io/training) avant janvier 2026. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/fr/docs/info/conventions.md b/docs/fr/docs/info/conventions.md new file mode 100644 index 0000000000..e0fe77d601 --- /dev/null +++ b/docs/fr/docs/info/conventions.md @@ -0,0 +1,3 @@ +<!-- Emplacement temporaire pour des notes spécifiques qui devraient être généralisées --> + +Nous utilisons le préfixe `ch_` pour toutes les variables de canaux afin d'indiquer clairement qu'il s'agit de canaux Nextflow. diff --git a/docs/fr/docs/info/hello_pipeline.md b/docs/fr/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..b7350a891b --- /dev/null +++ b/docs/fr/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Le pipeline Hello +description: Récapitulatif de ce que fait le pipeline Hello et comment il est structuré. +hide: + - toc + - footer +--- + +# Le pipeline Hello + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +La plupart de nos cours de formation utilisent un pipeline simple et indépendant du domaine pour démontrer les concepts et mécanismes de Nextflow. +Le cours Hello Nextflow montre comment développer ce pipeline étape par étape, en expliquant chaque décision de conception et d'implémentation. +D'autres formations utilisent ce pipeline, ou des parties de celui-ci, comme point de départ. + +Cette page résume l'état du pipeline tel qu'il se présente à la fin du cours Hello Nextflow. + +### Description sommaire + +Le workflow Hello prend un fichier CSV contenant des salutations, les écrit dans des fichiers séparés, convertit chacune en majuscules, les rassemble à nouveau et produit un seul fichier texte contenant une image ASCII d'un personnage amusant prononçant les salutations. + +### Étapes du workflow (processus) + +Les quatre étapes sont implémentées en tant que processes Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` et `cowpy`) stockés dans des fichiers de module séparés. + +1. **`sayHello` :** Écrit chaque salutation dans son propre fichier de sortie (par exemple, « Hello-output.txt ») +2. **`convertToUpper` :** Convertit chaque salutation en majuscules (par exemple, « HELLO ») +3. **`collectGreetings` :** Rassemble toutes les salutations en majuscules dans un seul fichier de lot +4. **`cowpy` :** Génère de l'art ASCII en utilisant l'outil `cowpy` + +### Diagramme + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Résultats + +Les résultats sont publiés dans un répertoire appelé `results/`, et la sortie finale du pipeline (lorsqu'il est exécuté avec les paramètres par défaut) est un fichier texte brut contenant de l'art ASCII d'une dinde prononçant les salutations en majuscules. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Vous pouvez rencontrer quelques variations dans les détails spécifiques selon le cours dans lequel le pipeline est présenté. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/fr/docs/info/nxf_versions.md b/docs/fr/docs/info/nxf_versions.md new file mode 100644 index 0000000000..6f16ae8a73 --- /dev/null +++ b/docs/fr/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Versions de Nextflow +description: Comprendre et gérer l'évolution des versions de syntaxe de Nextflow +hide: + - toc + - footer +--- + +## Version de syntaxe Nextflow actuellement supportée et exigences + +À partir de la version 3.0 du portail de formation, tous nos cours de formation sont basés sur la version 25.10.2 de Nextflow, sauf indication contraire sur la page d'index du cours (à l'exception des matériaux obsolètes ou archivés qui peuvent ne pas inclure d'avis de version). + +Étant donné que les cours utilisent maintenant des entrées typées au niveau du workflow ainsi que des directives de sortie au niveau du workflow, ils nécessitent l'utilisation du parser de syntaxe V2. +Si vous prévoyez d'utiliser l'environnement que nous fournissons via [Github Codespaces](../envsetup/01_setup.md) ou [devcontainers locaux](../envsetup/03_devcontainer.md), vous n'avez rien à faire sauf indication spécifique dans les instructions du cours. +Cependant, si vous prévoyez de travailler sur les formations dans votre propre environnement ([Installation manuelle](../envsetup/02_local.md)), vous devrez vous assurer d'utiliser Nextflow version 25.10.2 ou ultérieure avec le parser de syntaxe v2 activé. + +## Versions antérieures des matériaux de formation + +Nos matériaux de formation sont versionnés depuis février 2025. + +Vous pouvez accéder aux versions antérieures des matériaux de formation qui fonctionnent avec les versions de Nextflow **antérieures à 25.10.2** via l'élément de menu déroulant en haut de chaque page qui affiche la version numérotée des matériaux de formation. +Lorsque vous sélectionnez une version antérieure des matériaux de formation, les liens vers l'environnement de formation spécifieront automatiquement la version correspondante de l'environnement. + +## Autres informations sur les versions de syntaxe Nextflow + +Nextflow a deux concepts de versionnement distincts qui sont parfois confondus : **les versions DSL** et **les versions du parser de syntaxe**. + +**DSL1 vs DSL2** fait référence à des façons fondamentalement différentes d'écrire des pipelines Nextflow. +DSL1 était la syntaxe originale où les processes étaient implicitement connectés via des channels. +DSL2, introduit dans Nextflow 20.07, a ajouté des fonctionnalités de modularité : la possibilité d'importer des processes et des workflows depuis d'autres fichiers, des blocs `workflow` explicites et des sorties de process nommées. +DSL1 a été déprécié dans Nextflow 22.03 et supprimé dans 22.12. +Tout le code Nextflow moderne utilise DSL2. + +**Parser de syntaxe v1 vs v2** fait référence à différents parsers qui fonctionnent tous deux avec du code DSL2. +Le parser v1 est l'original, plus permissif. +Le parser v2 est plus strict et permet de nouvelles fonctionnalités du langage telles que le typage statique (entrées et sorties typées) et les directives de sortie au niveau du workflow. +Le parser v2 fournit également de meilleurs messages d'erreur et détecte plus d'erreurs au moment de l'analyse plutôt qu'à l'exécution. +Le parser v2 deviendra la valeur par défaut dans Nextflow 26.04. + +En résumé : DSL2 est le langage que vous écrivez ; la version du parser de syntaxe détermine à quel point ce langage est interprété strictement et quelles fonctionnalités avancées sont disponibles. + +### Vérifier et définir la version de Nextflow + +Vous pouvez vérifier quelle version de Nextflow est installée sur votre système en utilisant la commande `nextflow --version`. + +Pour plus d'informations sur la mise à jour de votre version de Nextflow, veuillez consulter la documentation de référence sur [Updating Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Activer le parser de syntaxe v2 + +Pour **activer** le parser de syntaxe v2 pour votre session actuelle, exécutez la commande suivante dans votre terminal : + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Pour rendre cela permanent (en attendant que v2 devienne la valeur par défaut dans Nextflow 26.04), ajoutez la commande export à votre profil shell (`~/.bashrc`, `~/.zshrc`, etc.) : + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Notez que la variable d'environnement `NXF_SYNTAX_PARSER=v2` est une exigence temporaire. +À partir de Nextflow 26.04, le parser v2 deviendra la valeur par défaut et ce paramètre ne sera plus nécessaire. + +### Désactiver le parser de syntaxe v2 + +Pour **désactiver** le parser de syntaxe v2 pour votre session actuelle, exécutez la commande suivante dans votre terminal : + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migrer du code existant + +Pour des conseils concernant la migration de code existant pour se conformer aux versions plus récentes de Nextflow, veuillez consulter les [Migration Notes](https://www.nextflow.io/docs/latest/migrations/index.html) dans la documentation de référence. + +Ces deux articles sont particulièrement utiles pour migrer vers la version la plus récente : + +- [Migrating to workflow outputs](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrating to static types](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Ces deux fonctionnalités sont couvertes dans le cadre de la formation pour débutants à partir de la version 3.0 des matériaux de formation. + +Selon la génération de code Nextflow que vous souhaitez migrer, vous pourrez peut-être effectuer la majeure partie du travail avec le linter Nextflow en utilisant la commande `nextflow lint -format`. +Consultez la référence CLI pour [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) pour plus de détails. + +Nous espérons que cela vous sera utile. +Si vous avez besoin d'aide, contactez-nous sur Slack ou sur le forum. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/fr/docs/nextflow_run/00_orientation.md b/docs/fr/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..de94fd08a4 --- /dev/null +++ b/docs/fr/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Démarrage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Lancer un environnement de formation + +Pour utiliser l'environnement pré-construit que nous fournissons sur GitHub Codespaces, cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous. Pour d'autres options, consultez [Options d'environnement](../envsetup/index.md). + +Nous vous recommandons d'ouvrir l'environnement de formation dans un nouvel onglet ou une nouvelle fenêtre de navigateur (utilisez le clic droit, ctrl-clic ou cmd-clic selon votre équipement) afin de pouvoir continuer à lire pendant que l'environnement se charge. +Vous devrez garder ces instructions ouvertes en parallèle pour suivre la formation. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Les bases de l'environnement + +Cet environnement de formation contient tous les logiciels, le code et les données nécessaires pour suivre la formation, vous n'avez donc pas besoin d'installer quoi que ce soit vous-même. + +Le codespace est configuré avec une interface VSCode, qui comprend un explorateur de fichiers, un éditeur de code et un terminal shell. +Toutes les instructions données pendant la formation (par exemple « ouvrir le fichier », « modifier le code » ou « exécuter cette commande ») se réfèrent à ces trois parties de l'interface VSCode, sauf indication contraire. + +Si vous suivez cette formation par vous-même, veuillez vous familiariser avec les [bases de l'environnement](../envsetup/01_setup.md) pour plus de détails. + +### Exigences de version + +Cette formation est conçue pour Nextflow 25.10.2 ou ultérieur **avec le parseur de syntaxe v2 ACTIVÉ**. +Si vous utilisez un environnement local ou personnalisé, veuillez vous assurer que vous utilisez les paramètres corrects comme documenté [ici](../info/nxf_versions.md). + +## Se préparer à travailler + +Une fois votre codespace en cours d'exécution, il y a deux choses que vous devez faire avant de plonger dans la formation : définir votre répertoire de travail pour cette formation spécifique, et examiner les matériaux fournis. + +### Définir le répertoire de travail + +Par défaut, le codespace s'ouvre avec le répertoire de travail défini à la racine de toutes les formations, mais pour cette formation, nous allons travailler dans le répertoire `nextflow-run/`. + +Changez de répertoire maintenant en exécutant cette commande dans le terminal : + +```bash +cd nextflow-run/ +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire, de sorte que seuls les fichiers pertinents apparaissent dans la barre latérale de l'explorateur de fichiers : + +```bash +code . +``` + +!!! tip "Astuce" + + Si pour une raison quelconque vous sortez de ce répertoire (par exemple, votre codespace s'endort), vous pouvez toujours utiliser le chemin complet pour y revenir, en supposant que vous exécutez cela dans l'environnement de formation GitHub Codespaces : + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Maintenant, examinons le contenu. + +### Explorer les matériaux fournis + +Vous pouvez explorer le contenu de ce répertoire en utilisant l'explorateur de fichiers sur le côté gauche de l'espace de travail de formation. +Alternativement, vous pouvez utiliser la commande `tree`. + +Tout au long de la formation, nous utilisons la sortie de `tree` pour représenter la structure et le contenu des répertoires sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 2 +``` + +??? abstract "Contenu du répertoire" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Cliquez sur la boîte colorée pour développer la section et voir son contenu. +Nous utilisons des sections repliables comme celle-ci pour afficher la sortie attendue des commandes ainsi que le contenu des répertoires et des fichiers de manière concise. + +- **Les fichiers `.nf`** sont des scripts de workflow numérotés en fonction de la partie de la formation où ils sont utilisés. + +- **Le fichier `nextflow.config`** est un fichier de configuration qui définit les propriétés minimales de l'environnement. + Vous pouvez l'ignorer pour l'instant. + +- **Le fichier `greetings.csv`** sous `data/` contient les données d'entrée que nous utiliserons dans la majeure partie de la formation. Il est décrit dans la Partie 2 (Exécuter des pipelines), lorsque nous l'introduisons pour la première fois. + +- **Les fichiers `test-params.*`** sont des fichiers de configuration que nous utiliserons dans la Partie 3 (Configuration). Vous pouvez les ignorer pour l'instant. + +- **Le répertoire `solutions`** contient l'état final du workflow et de ses fichiers accessoires (config et modules) qui résultent de l'achèvement de la formation. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre les problèmes. + +## Liste de vérification de préparation + +Vous pensez être prêt à plonger ? + +- [ ] Je comprends l'objectif de cette formation et ses prérequis +- [ ] Mon environnement est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +**Pour continuer vers [Partie 1 : Exécuter les opérations de base](./01_basics.md), cliquez sur la flèche en bas à droite de cette page.** diff --git a/docs/fr/docs/nextflow_run/01_basics.md b/docs/fr/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..80a6af987d --- /dev/null +++ b/docs/fr/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Partie 1 : Exécuter les opérations de base + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette première partie de la formation Nextflow Run, nous abordons le sujet avec un exemple Hello World très basique et indépendant du domaine, que nous utiliserons pour démontrer les opérations essentielles et pointer les composants de code Nextflow correspondants. + +??? info "Qu'est-ce qu'un exemple Hello World ?" + + Un « Hello World! » est un exemple minimaliste destiné à démontrer la syntaxe et la structure de base d'un langage de programmation ou d'un framework logiciel. + L'exemple consiste généralement à afficher la phrase « Hello, World! » sur le dispositif de sortie, comme la console ou le terminal, ou à l'écrire dans un fichier. + +--- + +## 1. Exécuter un Hello World directement + +Démontrons ce concept avec une commande simple que nous exécutons directement dans le terminal, pour montrer ce qu'elle fait avant de l'encapsuler dans Nextflow. + +!!! tip "Astuce" + + N'oubliez pas que vous devriez maintenant être dans le répertoire `nextflow-run/` comme décrit sur la page [Démarrage](00_orientation.md). + +### 1.1. Faire dire bonjour au terminal + +Exécutez la commande suivante dans votre terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Sortie de la commande" + + ```console + Hello World! + ``` + +Cela affiche le texte 'Hello World' directement dans le terminal. + +### 1.2. Écrire la sortie dans un fichier + +L'exécution de pipelines implique principalement la lecture de données depuis des fichiers et l'écriture de résultats dans d'autres fichiers, alors modifions la commande pour écrire la sortie texte dans un fichier afin de rendre l'exemple un peu plus pertinent. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Sortie de la commande" + + ```console + + ``` + +Cela n'affiche rien dans le terminal. + +### 1.3. Trouver la sortie + +Le texte 'Hello World' devrait maintenant être dans le fichier de sortie que nous avons spécifié, nommé `output.txt`. +Vous pouvez l'ouvrir dans l'explorateur de fichiers ou depuis la ligne de commande en utilisant l'utilitaire `cat`, par exemple. + +??? abstract "Contenu du fichier" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +C'est ce que nous allons essayer de reproduire avec notre tout premier workflow Nextflow. + +### Récapitulatif + +Vous savez maintenant comment exécuter une commande simple dans le terminal qui affiche du texte, et optionnellement, comment lui faire écrire la sortie dans un fichier. + +### Et ensuite ? + +Découvrez ce qu'il faut pour exécuter un workflow Nextflow qui atteint le même résultat. + +--- + +## 2. Exécuter le workflow + +Nous vous fournissons un script de workflow nommé `1-hello.nf` qui prend une salutation en entrée via un argument de ligne de commande nommé `--input` et produit un fichier texte contenant cette salutation. + +Nous n'allons pas regarder le code pour l'instant ; voyons d'abord à quoi ressemble son exécution. + +### 2.1. Lancer le workflow et surveiller l'exécution + +Dans le terminal, exécutez la commande suivante : + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Sortie de la commande" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Si votre sortie console ressemble à cela, alors félicitations, vous venez d'exécuter votre premier workflow Nextflow ! + +La sortie la plus importante ici est la dernière ligne, qui est mise en surbrillance dans la sortie ci-dessus : + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Cela nous indique que le process `sayHello` a été exécuté avec succès une fois (`1 of 1 ✔`). + +C'est bien, mais vous vous demandez peut-être : où est la sortie ? + +### 2.2. Trouver le fichier de sortie dans le répertoire `results` + +Ce workflow est configuré pour publier sa sortie dans un répertoire de résultats. +Si vous regardez votre répertoire actuel, vous verrez que lorsque vous avez exécuté le workflow, Nextflow a créé un nouveau répertoire appelé `results`, ainsi qu'un sous-répertoire appelé `1-hello` en dessous, contenant un fichier appelé `output.txt`. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Ouvrez le fichier ; le contenu devrait correspondre à la chaîne que vous avez spécifiée sur la ligne de commande. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +C'est bien, notre workflow a fait ce qu'il était censé faire ! + +Cependant, soyez conscient que le résultat « publié » est une copie (ou dans certains cas un lien symbolique) de la sortie réelle produite par Nextflow lors de l'exécution du workflow. + +Alors maintenant, nous allons jeter un coup d'œil sous le capot pour voir où Nextflow a réellement exécuté le travail. + +!!! Warning "Avertissement" + + Tous les workflows ne seront pas configurés pour publier les sorties dans un répertoire de résultats, et/ou les noms de répertoires et la structure peuvent être différents. + Un peu plus loin dans cette section, nous vous montrerons comment découvrir où ce comportement est spécifié. + +### 2.3. Trouver la sortie originale et les logs dans le répertoire `work/` + +Lorsque vous exécutez un workflow, Nextflow crée un « répertoire de tâche » distinct pour chaque invocation de chaque process dans le workflow (= chaque étape du pipeline). +Pour chacun, il va préparer les entrées nécessaires, exécuter l'instruction ou les instructions pertinentes et écrire les sorties et les fichiers de log dans ce seul répertoire, qui est nommé automatiquement en utilisant un hash afin de le rendre unique. + +Tous ces répertoires de tâches vivront sous un répertoire appelé `work` dans votre répertoire actuel (où vous exécutez la commande). + +Cela peut sembler confus, alors voyons à quoi cela ressemble en pratique. + +En revenant à la sortie console pour le workflow que nous avons exécuté plus tôt, nous avions cette ligne : + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Vous voyez comment la ligne commence par `[a3/7be2fa]` ? +C'est une forme tronquée du chemin du répertoire de tâche pour cet appel de process, et vous indique où trouver la sortie de l'appel au process `sayHello` dans le chemin du répertoire `work/`. + +Vous pouvez trouver le chemin complet en tapant la commande suivante (en remplaçant `a3/7be2fa` par ce que vous voyez dans votre propre terminal) et en appuyant sur la touche tab pour compléter automatiquement le chemin ou en ajoutant un astérisque : + +```bash +ls work/a3/7be2fa* +``` + +Cela devrait donner le chemin complet du répertoire : `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Jetons un coup d'œil à ce qu'il y a dedans. + +??? abstract "Contenu du répertoire" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Vous ne voyez pas la même chose ?" + + Les noms exacts des sous-répertoires seront différents sur votre système. + + Si vous parcourez le contenu du sous-répertoire de tâche dans l'explorateur de fichiers VSCode, vous verrez tous les fichiers immédiatement. + Cependant, les fichiers de log sont définis pour être invisibles dans le terminal, donc si vous voulez utiliser `ls` ou `tree` pour les voir, vous devrez définir l'option appropriée pour afficher les fichiers invisibles. + + ```bash + tree -a work + ``` + +Vous devriez immédiatement reconnaître le fichier `output.txt`, qui est en fait la sortie originale du process `sayHello` qui a été publiée dans le répertoire `results`. +Si vous l'ouvrez, vous retrouverez la salutation `Hello World!`. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +Alors qu'en est-il de tous ces autres fichiers ? + +Ce sont les fichiers auxiliaires et de log que Nextflow a écrits dans le cadre de l'exécution de la tâche : + +- **`.command.begin`** : Fichier sentinelle créé dès que la tâche est lancée. +- **`.command.err`** : Messages d'erreur (`stderr`) émis par l'appel du process +- **`.command.log`** : Sortie de log complète émise par l'appel du process +- **`.command.out`** : Sortie régulière (`stdout`) de l'appel du process +- **`.command.run`** : Script complet exécuté par Nextflow pour exécuter l'appel du process +- **`.command.sh`** : La commande qui a été réellement exécutée par l'appel du process +- **`.exitcode`** : Le code de sortie résultant de la commande + +Le fichier `.command.sh` est particulièrement utile car il vous montre la commande principale que Nextflow a exécutée, sans inclure toute la comptabilité et la configuration de la tâche/environnement. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Cela confirme donc que le workflow a composé la même commande que nous avons exécutée directement sur la ligne de commande plus tôt. + +Lorsque quelque chose ne va pas et que vous devez résoudre ce qui s'est passé, il peut être utile de regarder le script `command.sh` pour vérifier exactement quelle commande Nextflow a composée en fonction des instructions du workflow, de l'interpolation de variables, etc. + +### 2.4. Ré-exécuter le workflow avec différentes salutations + +Essayez de ré-exécuter le workflow quelques fois avec différentes valeurs pour l'argument `--input`, puis regardez les répertoires de tâches. + +??? abstract "Contenu du répertoire" + + ```console + 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 + ``` + +Vous voyez qu'un nouveau sous-répertoire avec un ensemble complet de fichiers de sortie et de log a été créé pour chaque exécution. + +En revanche, si vous regardez le répertoire `results`, il n'y a toujours qu'un seul ensemble de résultats, et le contenu du fichier de sortie correspond à ce que vous avez exécuté en dernier. + +??? abstract "Contenu du répertoire" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Cela vous montre que les résultats publiés seront écrasés par les exécutions suivantes, alors que les répertoires de tâches sous `work/` sont préservés. + +### Récapitulatif + +Vous savez comment exécuter un script Nextflow simple, surveiller son exécution et trouver ses sorties. + +### Et ensuite ? + +Apprenez à lire un script Nextflow basique et à identifier comment ses composants sont liés à sa fonctionnalité. + +--- + +## 3. Examiner le script de démarrage du workflow Hello World + +Ce que nous avons fait là-bas était essentiellement de traiter le script de workflow comme une boîte noire. +Maintenant que nous avons vu ce qu'il fait, ouvrons la boîte et regardons à l'intérieur. + +Notre objectif ici n'est pas de mémoriser la syntaxe du code Nextflow, mais de former une intuition de base sur les principaux composants et comment ils sont organisés. + +### 3.1. Examiner la structure globale du code + +Vous trouverez le script `1-hello.nf` dans votre répertoire actuel, qui devrait être `nextflow-run`. Ouvrez-le dans le panneau de l'éditeur. + +??? full-code "Fichier de code complet" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Paramètres du pipeline + */ + params { + input: String + } + + workflow { + + main: + // émettre une salutation + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Un script de workflow Nextflow inclut généralement une ou plusieurs définitions de **process**, le **workflow** lui-même, et quelques blocs optionnels tels que **params** et **output**. + +Chaque **process** décrit quelle(s) opération(s) l'étape correspondante dans le pipeline doit accomplir, tandis que le **workflow** décrit la logique de flux de données qui connecte les différentes étapes. + +Examinons de plus près le bloc **process** d'abord, puis nous regarderons le bloc **workflow**. + +### 3.2. La définition du `process` + +Le premier bloc de code décrit un **process**. +La définition du process commence par le mot-clé `process`, suivi du nom du process et enfin le corps du process délimité par des accolades. +Le corps du process doit contenir un bloc script qui spécifie la commande à exécuter, qui peut être n'importe quoi que vous pourriez exécuter dans un terminal de ligne de commande. + +```groovy title="1-hello.nf" linenums="3" +/* +* Utilise echo pour imprimer une salutation dans un fichier +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Ici, nous avons un **process** appelé `sayHello` qui prend une variable d'**entrée** appelée `greeting` et écrit sa **sortie** dans un fichier nommé `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +C'est une définition de process très minimale qui contient juste une définition d'`input`, une définition d'`output` et le `script` à exécuter. + +La définition d'`input` inclut le qualificateur `val`, qui indique à Nextflow d'attendre une valeur de quelque type que ce soit (peut être une chaîne, un nombre, peu importe). + +La définition d'`output` inclut le qualificateur `path`, qui indique à Nextflow que cela doit être traité comme un chemin (inclut à la fois les chemins de répertoires et les fichiers). + +### 3.3. La définition du `workflow` + +Le deuxième bloc de code décrit le **workflow** lui-même. +La définition du workflow commence par le mot-clé `workflow`, suivi d'un nom optionnel, puis le corps du workflow délimité par des accolades. + +Ici, nous avons un **workflow** qui consiste en un bloc `main:` et un bloc `publish:`. +Le bloc `main:` est le corps principal du workflow et le bloc `publish:` liste les sorties qui doivent être publiées dans le répertoire `results`. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // émettre une salutation + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +Dans ce cas, le bloc `main:` contient un appel au process `sayHello` et lui donne une entrée appelée `params.input` à utiliser comme salutation. + +Comme nous le discuterons plus en détail dans un moment, `params.input` contient la valeur que nous avons donnée au paramètre `--input` dans notre ligne de commande. + +Le bloc `publish:` liste la sortie de l'appel au process `sayHello()`, qu'il désigne comme `sayHello.out` et lui donne le nom `first_output` (cela peut être n'importe quoi que l'auteur du workflow souhaite). + +C'est une définition de **workflow** très minimale. +Dans un pipeline réel, le workflow contient généralement plusieurs appels à des **processes** connectés par des **channels**, et il peut y avoir des valeurs par défaut configurées pour les entrées variables. + +Nous aborderons cela dans la Partie 2 de la formation. +Pour l'instant, examinons de plus près comment notre workflow gère les entrées et les sorties. + +### 3.4. Le système `params` de paramètres de ligne de commande + +Le `params.input` que nous fournissons à l'appel du process `sayHello()` est un morceau de code Nextflow intéressant qui mérite qu'on s'y attarde une minute supplémentaire. + +Comme mentionné ci-dessus, c'est ainsi que nous passons la valeur du paramètre de ligne de commande `--input` à l'appel du process `sayHello()`. +En fait, simplement déclarer `params.someParameterName` est suffisant pour donner au workflow un paramètre nommé `--someParameterName` depuis la ligne de commande. + +Ici, nous avons formalisé cette déclaration de paramètre en configurant un bloc `params` qui spécifie le type d'entrée que le workflow attend (Nextflow 25.10.2 et ultérieur). + +```groovy title="1-hello.nf" linenums="20" +/* + * Paramètres du pipeline + */ +params { + input: String +} +``` + +Les types pris en charge incluent `String`, `Integer`, `Float`, `Boolean` et `Path`. + +!!! tip "Astuce" + + Les paramètres de workflow déclarés en utilisant le système `params` prennent toujours deux tirets sur la ligne de commande (`--`). + Cela les distingue des paramètres de niveau Nextflow, qui ne prennent qu'un seul tiret (`-`). + +### 3.5. La directive `publish` + +À l'autre extrémité du workflow, nous avons déjà jeté un coup d'œil au bloc `publish:`. +C'est une moitié du système de gestion des sorties ; l'autre moitié est le bloc `output` situé en dessous. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Cela spécifie que la sortie `first_output` listée dans le bloc `publish:` doit être copiée dans un sous-répertoire appelé `1-hello` sous le répertoire de sortie `results` par défaut. + +La ligne `mode 'copy'` remplace le comportement par défaut du système, qui est de faire un lien symbolique (ou symlink) vers le fichier original dans le répertoire `work/` au lieu d'une copie propre. + +Il y a plus d'options que celles affichées ici pour contrôler le comportement de publication ; nous en couvrirons quelques-unes plus tard. +Vous verrez également que lorsqu'un workflow génère plusieurs sorties, chacune est listée de cette façon dans le bloc `output`. + +??? info "Ancienne syntaxe pour publier les sorties en utilisant `publishDir`" + + Jusqu'à très récemment, la façon établie de publier les sorties était de le faire au niveau de chaque process individuel en utilisant une directive `publishDir`. + + Vous trouverez encore ce modèle de code partout dans les anciens pipelines Nextflow et les modules de process, il est donc important d'en être conscient. + + Au lieu d'avoir un bloc `publish:` dans le workflow et un bloc `output` au niveau supérieur, vous verriez une ligne `publishDir` dans la définition du process `sayHello` : + + ```groovy title="Exemple de syntaxe" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + Cependant, nous ne recommandons pas d'utiliser cela dans tout nouveau travail car cela sera éventuellement interdit dans les futures versions du langage Nextflow. + +### Récapitulatif + +Vous savez maintenant comment un workflow Nextflow simple est structuré, et comment les composants de base sont liés à sa fonctionnalité. + +### Et ensuite ? + +Apprenez à gérer vos exécutions de workflow de manière pratique. + +--- + +## 4. Gérer les exécutions de workflow + +Savoir comment lancer des workflows et récupérer les sorties est bien, mais vous trouverez rapidement qu'il y a quelques autres aspects de la gestion des workflows qui vous faciliteront la vie. + +Ici, nous vous montrons comment tirer parti de la fonctionnalité `resume` lorsque vous devez relancer le même workflow, comment inspecter les logs d'exécution avec `nextflow log`, et comment supprimer les anciens répertoires de travail avec `nextflow clean`. + +### 4.1. Relancer un workflow avec `-resume` + +Parfois, vous allez vouloir ré-exécuter un pipeline que vous avez déjà lancé précédemment sans refaire le travail qui a déjà été complété avec succès. + +Nextflow a une option appelée `-resume` qui vous permet de faire cela. +Plus précisément, dans ce mode, tout process qui a déjà été exécuté avec exactement le même code, les mêmes paramètres et les mêmes entrées sera ignoré. +Cela signifie que Nextflow n'exécutera que les processes que vous avez ajoutés ou modifiés depuis la dernière exécution, ou auxquels vous fournissez de nouveaux paramètres ou entrées. + +Il y a deux avantages clés à faire cela : + +- Si vous êtes en train de développer un pipeline, vous pouvez itérer plus rapidement puisque vous n'avez qu'à exécuter le(s) process(es) sur lesquels vous travaillez activement pour tester vos modifications. +- Si vous exécutez un pipeline en production et que quelque chose ne va pas, dans de nombreux cas, vous pouvez corriger le problème et relancer le pipeline, et il reprendra l'exécution à partir du point d'échec, ce qui peut vous faire gagner beaucoup de temps et de calcul. + +Pour l'utiliser, ajoutez simplement `-resume` à votre commande et exécutez-la : + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +La sortie console devrait sembler familière, mais il y a une chose qui est un peu différente par rapport à avant. + +Cherchez la partie `cached:` qui a été ajoutée dans la ligne de statut du process (ligne 5), ce qui signifie que Nextflow a reconnu qu'il a déjà fait ce travail et a simplement réutilisé le résultat de l'exécution réussie précédente. + +Vous pouvez également voir que le hash du sous-répertoire de travail est le même que dans l'exécution précédente. +Nextflow vous pointe littéralement vers l'exécution précédente et dit « J'ai déjà fait ça là-bas. » + +!!! tip "Astuce" + + Lorsque vous ré-exécutez un pipeline avec `resume`, Nextflow n'écrase pas les fichiers publiés en dehors du répertoire de travail par les exécutions qui ont été exécutées avec succès précédemment. + +### 4.2. Inspecter le log des exécutions passées + +Chaque fois que vous lancez un workflow Nextflow, une ligne est écrite dans un fichier de log appelé `history`, sous un répertoire caché appelé `.nextflow` dans le répertoire de travail actuel. + +??? abstract "Contenu du fichier" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Ce fichier vous donne l'horodatage, le nom d'exécution, le statut, l'ID de révision, l'ID de session et la ligne de commande complète pour chaque exécution Nextflow qui a été lancée depuis le répertoire de travail actuel. + +Une façon plus pratique d'accéder à ces informations est d'utiliser la commande `nextflow log`. + +```bash +nextflow log +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Cela affichera le contenu du fichier de log dans le terminal, augmenté d'une ligne d'en-tête. + +Vous remarquerez que l'ID de session change chaque fois que vous exécutez une nouvelle commande `nextflow run`, SAUF si vous utilisez l'option `-resume`. +Dans ce cas, l'ID de session reste le même. + +Nextflow utilise l'ID de session pour regrouper les informations de mise en cache d'exécution sous le répertoire `cache`, également situé sous `.nextflow`. + +### 4.3. Supprimer les anciens répertoires de travail + +Si vous exécutez beaucoup de pipelines, vous pourriez accumuler de très nombreux fichiers dans de nombreux sous-répertoires. +Puisque les sous-répertoires sont nommés de manière aléatoire, il est difficile de dire d'après leurs noms quelles sont les exécutions plus anciennes par rapport aux plus récentes. + +Heureusement, Nextflow inclut une sous-commande `clean` utile qui peut automatiquement supprimer les sous-répertoires de travail des exécutions passées dont vous ne vous souciez plus. + +#### 4.3.1. Déterminer les critères de suppression + +Il existe plusieurs [options](https://www.nextflow.io/docs/latest/reference/cli.html#clean) pour déterminer ce qui doit être supprimé. + +Ici, nous vous montrons un exemple qui supprime tous les sous-répertoires des exécutions avant une exécution donnée, spécifiée en utilisant son nom d'exécution. + +Recherchez l'exécution réussie la plus récente où vous n'avez pas utilisé `-resume` ; dans notre cas, le nom d'exécution était `backstabbing_swartz`. + +Le nom d'exécution est la chaîne en deux parties générée par la machine affichée entre crochets dans la ligne de sortie console `Launching (...)`. +Vous pouvez également utiliser le log Nextflow pour rechercher une exécution basée sur son horodatage et/ou sa ligne de commande. + +#### 4.3.2. Faire un test à blanc + +D'abord, nous utilisons le drapeau de test à blanc `-n` pour vérifier ce qui sera supprimé avec la commande : + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Sortie de la commande" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Votre sortie aura des noms de répertoires de tâches différents et peut avoir un nombre de lignes différent, mais elle devrait ressembler à l'exemple. + +Si vous ne voyez aucune ligne en sortie, vous n'avez soit pas fourni un nom d'exécution valide, soit il n'y a pas d'exécutions passées à supprimer. Assurez-vous de changer `backstabbing_swartz` dans la commande d'exemple par le nom d'exécution le plus récent correspondant dans votre log. + +#### 4.3.3. Procéder à la suppression + +Si la sortie semble comme attendu et que vous voulez procéder à la suppression, ré-exécutez la commande avec le drapeau `-f` au lieu de `-n` : + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Sortie de la commande" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +La sortie devrait être similaire à avant, mais maintenant disant 'Removed' au lieu de 'Would remove'. +Notez que cela ne supprime pas les sous-répertoires de deux caractères (comme `eb/` ci-dessus) mais vide leur contenu. + +!!! Warning "Avertissement" + + Supprimer les sous-répertoires de travail des exécutions passées les supprime du cache de Nextflow et supprime toutes les sorties qui étaient stockées dans ces répertoires. + Cela signifie que cela casse la capacité de Nextflow à reprendre l'exécution sans ré-exécuter les processes correspondants. + + Vous êtes responsable de sauvegarder toutes les sorties qui vous importent ! C'est la raison principale pour laquelle nous préférons utiliser le mode `copy` plutôt que le mode `symlink` pour la directive `publish`. + +### Récapitulatif + +Vous savez comment relancer un pipeline sans répéter les étapes qui ont déjà été exécutées de manière identique, inspecter le log d'exécution, et utiliser la commande `nextflow clean` pour nettoyer les anciens répertoires de travail. + +### Et ensuite ? + +Prenez une petite pause ! Vous venez d'absorber les éléments de base de la syntaxe Nextflow et les instructions d'utilisation de base. + +Dans la prochaine section de cette formation, nous allons examiner quatre versions successivement plus réalistes du pipeline Hello World qui démontreront comment Nextflow vous permet de traiter plusieurs entrées efficacement, d'exécuter des workflows composés de plusieurs étapes connectées ensemble, d'exploiter des composants de code modulaires, et d'utiliser des conteneurs pour une plus grande reproductibilité et portabilité. + +--- + +## Quiz + +<quiz> +Dans la ligne de sortie console `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`, que représente `[a3/7be2fa]` ? +- [ ] Le numéro de version du process +- [ ] Un identifiant d'exécution unique +- [x] Le chemin tronqué vers le répertoire de travail de la tâche +- [ ] La somme de contrôle du fichier de sortie + +En savoir plus : [2.3. Trouver la sortie originale et les logs dans le répertoire `work/`](#23-trouver-la-sortie-originale-et-les-logs-dans-le-repertoire-work) +</quiz> + +<quiz> +Quel est le but du fichier `.command.sh` dans un répertoire de tâche ? +- [ ] Il stocke les paramètres de configuration de la tâche +- [x] Il montre la commande réelle qui a été exécutée par le process +- [ ] Il contient les messages d'erreur des tâches échouées +- [ ] Il liste les fichiers d'entrée préparés pour la tâche + +En savoir plus : [2.3. Trouver la sortie originale et les logs dans le répertoire `work/`](#23-trouver-la-sortie-originale-et-les-logs-dans-le-repertoire-work) +</quiz> + +<quiz> +Qu'arrive-t-il aux résultats publiés lorsque vous ré-exécutez un workflow sans `-resume` ? +- [ ] Ils sont préservés dans des répertoires horodatés séparés +- [x] Ils sont écrasés par la nouvelle exécution +- [ ] Nextflow empêche l'écrasement et échoue +- [ ] Ils sont automatiquement sauvegardés + +En savoir plus : [2.4. Ré-exécuter le workflow avec différentes salutations](#24-re-executer-le-workflow-avec-differentes-salutations) +</quiz> + +<quiz> +Qu'indique cette sortie console ? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] La tâche a échoué et a été ignorée +- [ ] La tâche attend dans une file d'attente +- [x] Nextflow a réutilisé les résultats d'une exécution identique précédente +- [ ] La tâche a été annulée manuellement + +En savoir plus : [4.1. Relancer un workflow avec `-resume`](#41-relancer-un-workflow-avec--resume) +</quiz> + +<quiz> +Où Nextflow stocke-t-il l'historique d'exécution que la commande `nextflow log` affiche ? +- [ ] Dans le répertoire results +- [ ] Dans le répertoire work +- [x] Dans le fichier `.nextflow/history` +- [ ] Dans `nextflow.config` + +En savoir plus : [4.2. Inspecter le log des exécutions passées](#42-inspecter-le-log-des-executions-passees) +</quiz> + +<quiz> +Quel est le but du bloc `params` dans un fichier de workflow ? +- [ ] Définir les exigences de ressources du process +- [ ] Configurer l'executor +- [x] Déclarer et typer les paramètres d'entrée du workflow +- [ ] Spécifier les options de publication des sorties + +En savoir plus : [3.4. Le système params de paramètres de ligne de commande](#34-le-systeme-params-de-parametres-de-ligne-de-commande) +</quiz> + +<quiz> +Dans le bloc `output` du workflow, que fait `mode 'copy'` ? +- [ ] Crée une sauvegarde du répertoire de travail +- [x] Fait une copie complète des fichiers au lieu de liens symboliques +- [ ] Copie le script du workflow vers les résultats +- [ ] Active la copie incrémentielle des fichiers + +En savoir plus : [3.5. La directive publish](#35-la-directive-publish) +</quiz> + +<quiz> +Quel est le drapeau recommandé à utiliser avec la commande `nextflow clean` avant de supprimer réellement des fichiers ? +- [x] `-n` (test à blanc) pour prévisualiser ce qui serait supprimé +- [ ] `-v` (verbeux) pour voir une sortie détaillée +- [ ] `-a` (tous) pour sélectionner tous les répertoires +- [ ] `-q` (silencieux) pour supprimer les avertissements + +En savoir plus : [4.3. Supprimer les anciens répertoires de travail](#43-supprimer-les-anciens-repertoires-de-travail) +</quiz> diff --git a/docs/fr/docs/nextflow_run/02_pipeline.md b/docs/fr/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..b065e6555a --- /dev/null +++ b/docs/fr/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1509 @@ +# Partie 2 : Exécuter de vrais pipelines + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la Partie 1 de cette formation (Exécuter les opérations de base), nous avons commencé avec un workflow d'exemple qui n'avait que des fonctionnalités minimales afin de garder la complexité du code faible. +Par exemple, `1-hello.nf` utilisait un paramètre de ligne de commande (`--input`) pour fournir une seule valeur à la fois. + +Cependant, la plupart des pipelines du monde réel utilisent des fonctionnalités plus sophistiquées afin de permettre un traitement efficace de grandes quantités de données à grande échelle, et d'appliquer plusieurs étapes de traitement enchaînées par une logique parfois complexe. + +Dans cette partie de la formation, nous démontrons les fonctionnalités clés des pipelines réels en essayant des versions étendues du pipeline Hello World original. + +## 1. Traitement des données d'entrée depuis un fichier + +Dans un pipeline réel, nous voulons généralement traiter plusieurs points de données (ou séries de données) contenus dans un ou plusieurs fichiers d'entrée. +Et dans la mesure du possible, nous voulons exécuter le traitement de données indépendantes en parallèle, pour raccourcir le temps d'attente de l'analyse. + +Pour démontrer comment Nextflow fait cela, nous avons préparé un fichier CSV appelé `greetings.csv` qui contient plusieurs salutations d'entrée, imitant le type de données tabulaires que vous pourriez vouloir traiter dans une vraie analyse de données. +Notez que les nombres ne sont pas significatifs, ils sont juste là à des fins d'illustration. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Nous avons également écrit une version améliorée du workflow original, maintenant appelée `2a-inputs.nf`, qui lira le fichier CSV, extraira les salutations et écrira chacune d'elles dans un fichier séparé. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Exécutons d'abord le workflow, et nous examinerons le code Nextflow pertinent ensuite. + +### 1.1. Exécuter le workflow + +Exécutez la commande suivante dans votre terminal. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +De manière encourageante, cela semble indiquer que « 3 of 3 » appels ont été faits pour le process, ce qui est encourageant, puisqu'il y avait trois lignes de données dans le CSV que nous avons fourni en entrée. +Cela suggère que le process `sayHello()` a été appelé trois fois, une fois sur chaque ligne d'entrée. + +### 1.2. Trouver les sorties publiées dans le répertoire `results` + +Regardons le répertoire 'results' pour voir si notre workflow écrit toujours une copie de nos sorties là. + +??? abstract "Contenu du répertoire" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Oui ! Nous voyons un nouveau répertoire appelé `2a-inputs` avec trois fichiers de sortie avec des noms différents, très pratique. + +Vous pouvez ouvrir chacun d'eux pour vous assurer qu'ils contiennent la chaîne de salutation appropriée. + +??? abstract "Contenu des fichiers" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Cela confirme que chaque salutation dans le fichier d'entrée a été traitée de manière appropriée. + +### 1.3. Trouver les sorties et logs originaux + +Vous avez peut-être remarqué que la sortie console ci-dessus ne faisait référence qu'à un seul répertoire de tâche. +Cela signifie-t-il que les trois appels à `sayHello()` ont été exécutés dans ce seul répertoire de tâche ? + +#### 1.3.1. Examiner le répertoire de tâche donné dans le terminal + +Jetons un coup d'œil à l'intérieur de ce répertoire de tâche `8e/0eb066`. + +??? abstract "Contenu du répertoire" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Nous ne trouvons que la sortie correspondant à l'une des salutations (ainsi que les fichiers accessoires si nous activons l'affichage des fichiers cachés). + +Alors que se passe-t-il ? + +Par défaut, le système de journalisation ANSI écrit les informations de statut pour tous les appels au même process sur la même ligne. +En conséquence, il ne nous a montré qu'un seul des trois chemins de répertoire de tâche (`8e/0eb066`) dans la sortie console. +Il y en a deux autres qui ne sont pas listés là. + +#### 1.3.2. Faire afficher plus de détails par le terminal + +Nous pouvons modifier le comportement de journalisation pour voir la liste complète des appels de process en ajoutant `-ansi-log false` à la commande comme suit : + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Cette fois, nous voyons les trois exécutions de process et leurs sous-répertoires de travail associés listés dans la sortie. +Désactiver la journalisation ANSI a également empêché Nextflow d'utiliser des couleurs dans la sortie du terminal. + +Remarquez que la façon dont le statut est rapporté est un peu différente entre les deux modes de journalisation. +Dans le mode condensé, Nextflow rapporte si les appels ont été complétés avec succès ou non. +Dans ce mode étendu, il rapporte seulement qu'ils ont été soumis. + +Cela confirme que le process `sayHello()` est appelé trois fois, et un répertoire de tâche séparé est créé pour chacun. + +Si nous regardons à l'intérieur de chacun des répertoires de tâche listés là, nous pouvons vérifier que chacun correspond à l'une des salutations. + +??? abstract "Contenu du répertoire" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Cela confirme que chaque appel de process est exécuté isolément de tous les autres. +Cela a de nombreux avantages, y compris éviter les collisions si le process produit des fichiers intermédiaires avec des noms non uniques. + +!!! tip "Astuce" + + Pour un workflow complexe, ou un grand nombre d'entrées, avoir la liste complète affichée dans le terminal pourrait devenir un peu écrasant, donc les gens n'utilisent normalement pas `-ansi-log false` en utilisation courante. + +### 1.4. Examiner le code du workflow + +Cette version du workflow est donc capable de lire un fichier CSV d'entrées, de traiter les entrées séparément, et de nommer les sorties de manière unique. + +Jetons un coup d'œil à ce qui rend cela possible dans le code du workflow. + +??? full-code "Fichier de code complet" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Paramètres du pipeline + */ + params { + input: Path + } + + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Encore une fois, vous n'avez pas besoin de mémoriser la syntaxe du code, mais il est bon d'apprendre à reconnaître les composants clés du workflow qui fournissent des fonctionnalités importantes. + +#### 1.4.1. Chargement des données d'entrée depuis le CSV + +C'est la partie la plus intéressante : comment sommes-nous passés de la prise d'une seule valeur depuis la ligne de commande, à la prise d'un fichier CSV, son analyse et le traitement des salutations individuelles qu'il contient ? + +Dans Nextflow, nous faisons cela avec un **channel** : une construction conçue pour gérer les entrées efficacement et les faire passer d'une étape à l'autre dans les workflows multi-étapes, tout en fournissant un parallélisme intégré et de nombreux autres avantages. + +Décomposons cela. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) +``` + +Ce code crée un channel appelé `greeting_ch` qui lit le fichier CSV, l'analyse, et extrait la première colonne de chaque ligne. +Le résultat est un channel contenant `Hello`, `Bonjour`, et `Holà`. + +??? tip "Comment cela fonctionne-t-il ?" + + Voici ce que cette ligne signifie en langage courant : + + - `channel.fromPath` est une **fabrique de channel** qui crée un channel à partir de chemin(s) de fichier + - `(params.input)` spécifie que le chemin du fichier est fourni par `--input` sur la ligne de commande + + En d'autres termes, cette ligne dit à Nextflow : prends le chemin de fichier donné avec `--input` et prépare-toi à traiter son contenu comme des données d'entrée. + + Ensuite, les deux lignes suivantes appliquent des **opérateurs** qui font l'analyse réelle du fichier et le chargement des données dans la structure de données appropriée : + + - `.splitCsv()` dit à Nextflow d'analyser le fichier CSV en un tableau représentant les lignes et les colonnes + - `.map { line -> line[0] }` dit à Nextflow de prendre uniquement l'élément de la première colonne de chaque ligne + + Donc en pratique, en partant du fichier CSV suivant : + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Nous avons transformé cela en un tableau qui ressemble à ceci : + + ```txt title="Contenu du tableau" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + Et ensuite nous avons pris le premier élément de chacune des trois lignes et les avons chargés dans un channel Nextflow qui contient maintenant : `Hello`, `Bonjour`, et `Holà`. + + Si vous voulez comprendre les channels et les opérateurs en profondeur, y compris comment les écrire vous-même, consultez [Hello Nextflow Partie 2 : Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Appeler le process sur chaque salutation + +Ensuite, dans la dernière ligne du bloc `main:` du workflow, nous fournissons le channel `greeting_ch` chargé comme entrée au process `sayHello()`. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) +``` + +Cela dit à Nextflow d'exécuter le process individuellement sur chaque élément du channel, _c.-à-d._ sur chaque salutation. +Et parce que Nextflow est intelligent comme ça, il exécutera ces appels de process en parallèle si possible, en fonction de l'infrastructure de calcul disponible. + +C'est ainsi que vous pouvez réaliser un traitement efficace et évolutif d'une grande quantité de données (de nombreux échantillons, ou points de données, quel que soit votre unité de recherche) avec comparativement très peu de code. + +#### 1.4.3. Comment les sorties sont nommées + +Enfin, il vaut la peine de jeter un coup d'œil rapide au code du process pour voir comment nous obtenons des noms uniques pour les fichiers de sortie. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Vous voyez que, comparé à la version de ce process dans `1-hello.nf`, la déclaration de sortie et la partie pertinente de la commande ont changé pour inclure la valeur de la salutation dans le nom du fichier de sortie. + +C'est une façon de s'assurer que les noms de fichiers de sortie ne vont pas entrer en collision lorsqu'ils sont publiés dans le répertoire de résultats commun. + +Et c'est le seul changement que nous avons dû faire à l'intérieur de la déclaration du process ! + +### Récapitulatif + +Vous comprenez à un niveau basique comment les channels et les opérateurs nous permettent de traiter plusieurs entrées efficacement. + +### Et ensuite ? + +Découvrez comment les workflows multi-étapes sont construits et comment ils fonctionnent. + +--- + +## 2. Exécution de workflows multi-étapes + +La plupart des workflows du monde réel impliquent plus d'une étape. +Construisons sur ce que nous venons d'apprendre sur les channels, et regardons comment Nextflow utilise les channels et les opérateurs pour connecter les processes ensemble dans un workflow multi-étapes. + +À cette fin, nous vous fournissons un workflow d'exemple qui enchaîne trois étapes séparées et démontre ce qui suit : + +1. Faire passer les données d'un process au suivant +2. Collecter les sorties de plusieurs appels de process en un seul appel de process + +Plus précisément, nous avons fait une version étendue du workflow appelée `2b-multistep.nf` qui prend chaque salutation d'entrée, la convertit en majuscules, puis collecte toutes les salutations en majuscules dans un seul fichier de sortie. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Comme précédemment, nous exécuterons d'abord le workflow puis regarderons le code pour voir ce qui est nouveau. + +### 2.1. Exécuter le workflow + +Exécutez la commande suivante dans votre terminal : + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Vous voyez que comme promis, plusieurs étapes ont été exécutées dans le cadre du workflow ; les deux premières (`sayHello` et `convertToUpper`) ont vraisemblablement été exécutées sur chaque salutation individuelle, et la troisième (`collectGreetings`) aura été exécutée une seule fois, sur les sorties des trois appels `convertToUpper`. + +### 2.2. Trouver les sorties + +Vérifions que c'est bien ce qui s'est passé en jetant un coup d'œil dans le répertoire `results`. + +??? abstract "Contenu du répertoire" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Comme vous pouvez le voir, nous avons un nouveau répertoire appelé `2b-multistep`, et il contient bien plus de fichiers qu'avant. +Certains des fichiers ont été regroupés dans un sous-répertoire appelé `intermediates`, tandis que deux fichiers sont situés au niveau supérieur. + +Ces deux-là sont les résultats finaux du workflow multi-étapes. +Prenez une minute pour regarder les noms de fichiers et vérifier leur contenu pour confirmer qu'ils sont ce que vous attendez. + +??? abstract "Contenu des fichiers" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +Le premier contient nos trois salutations, en majuscules et collectées dans un seul fichier comme promis. +Le second est un fichier de rapport qui résume quelques informations sur l'exécution. + +### 2.3. Examiner le code + +Regardons le code et identifions les modèles clés pour les workflows multi-étapes. + +??? full-code "Fichier de code complet" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Utilise un outil de remplacement de texte pour convertir la salutation en majuscules + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Il se passe beaucoup de choses là-dedans, mais la différence la plus évidente par rapport à la version précédente du workflow est que maintenant il y a plusieurs définitions de process, et par conséquent, plusieurs appels de process dans le bloc workflow. + +Regardons de plus près et voyons si nous pouvons identifier les pièces les plus intéressantes. + +#### 2.3.1. Visualiser la structure du workflow + +Si vous utilisez VSCode avec l'extension Nextflow, vous pouvez obtenir un diagramme utile montrant comment les processes sont connectés en cliquant sur le petit lien `DAG preview` affiché juste au-dessus du bloc workflow dans n'importe quel script Nextflow. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Cela vous donne un bon aperçu de la façon dont les processes sont connectés et ce qu'ils produisent. + +Vous voyez qu'en plus du process `sayHello` original, nous avons maintenant aussi `convertToUpper` et `collectGreetings`, qui correspondent aux noms des processes que nous avons vus dans la sortie console. +Les deux nouvelles définitions de process sont structurées de la même manière que le process `sayHello`, sauf que `collectGreetings` prend un paramètre d'entrée supplémentaire appelé `batch` et produit deux sorties. + +Nous n'entrerons pas dans le code de chacun en détail, mais si vous êtes curieux, vous pouvez consulter les détails dans [Partie 2 de Hello Nextflow](../hello_nextflow/03_hello_workflow.md). + +Pour l'instant, creusons dans la façon dont les processes sont connectés les uns aux autres. + +#### 2.3.2. Comment les processes sont connectés + +La chose vraiment intéressante à regarder ici est comment les appels de process sont enchaînés dans le bloc `main:` du workflow. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Vous pouvez voir que le premier appel de process, `sayHello(greeting_ch)`, est inchangé. +Ensuite, l'appel de process suivant, à `convertToUpper`, fait référence à la sortie de `sayHello` comme `sayHello.out`. + +Le modèle est simple : `processName.out` fait référence au channel de sortie d'un process, qui peut être passé directement au process suivant. +C'est ainsi que nous faisons passer les données d'une étape à l'autre dans Nextflow. + +#### 2.3.3. Un process peut prendre plusieurs entrées + +Le troisième appel de process, à `collectGreetings`, est un peu différent. + +```groovy title="2b-multistep.nf" linenums="77" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Vous voyez que cet appel reçoit deux entrées, `convertToUpper.out.collect()` et `params.batch`. +En ignorant la partie `.collect()` pour l'instant, nous pouvons généraliser cela comme `collectGreetings(input1, input2)`. + +Cela correspond aux deux déclarations d'entrée dans le module du process : + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Lorsque Nextflow analyse ceci, il assignera la première entrée dans l'appel à `path input_files`, et la seconde à `val batch_name`. + +Maintenant vous savez qu'un process peut prendre plusieurs entrées, et à quoi ressemble l'appel dans le bloc workflow. + +Maintenant regardons de plus près cette première entrée, `convertToUpper.out.collect()`. + +#### 2.3.4. Ce que fait `collect()` dans l'appel `collectGreetings` + +Pour passer la sortie de `sayHello` à `convertToUpper`, nous avons simplement fait référence au channel de sortie de `sayHello` comme `sayHello.out`. Mais pour l'étape suivante, nous voyons une référence à `convertToUpper.out.collect()`. + +Qu'est-ce que cette partie `collect()` et que fait-elle ? + +C'est un opérateur, bien sûr. Tout comme les opérateurs `splitCsv` et `map` que nous avons rencontrés plus tôt. +Cette fois l'opérateur s'appelle `collect`, et est appliqué au channel de sortie produit par `convertToUpper`. + +L'opérateur `collect` est utilisé pour collecter les sorties de plusieurs appels au même process et les empaqueter en un seul élément de channel. + +Dans le contexte de ce workflow, il prend les trois salutations en majuscules dans le channel `convertToUpper.out` -- qui sont trois éléments de channel séparés, et seraient normalement traités dans des appels séparés par le process suivant -- et les empaquette en un seul élément. + +En termes plus pratiques : si nous n'appliquions pas `collect()` à la sortie de `convertToUpper()` avant de la passer à `collectGreetings()`, Nextflow exécuterait simplement `collectGreetings()` indépendamment sur chaque salutation, ce qui n'atteindrait pas notre objectif. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +En revanche, utiliser `collect()` nous permet de prendre toutes les salutations en majuscules séparées produites par la deuxième étape du workflow et de les passer toutes ensemble à un seul appel dans la troisième étape du pipeline. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +C'est ainsi que nous récupérons toutes les salutations dans le même fichier. + +Il existe de nombreux autres [opérateurs](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) disponibles pour appliquer des transformations au contenu des channels entre les appels de process. + +Cela donne aux développeurs de pipelines beaucoup de flexibilité pour personnaliser la logique de flux de leur pipeline. +L'inconvénient est que cela peut parfois rendre plus difficile le déchiffrage de ce que fait le pipeline. + +#### 2.3.5. Un paramètre d'entrée peut avoir une valeur par défaut + +Vous avez peut-être remarqué que `collectGreetings` prend une seconde entrée, `params.batch` : + +```groovy title="2b-multistep.nf" linenums="77" + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Cela passe un paramètre CLI nommé `--batch` au workflow. +Cependant, lorsque nous avons lancé le workflow plus tôt, nous n'avons pas spécifié de paramètre `--batch`. + +Que se passe-t-il là ? +Jetez un coup d'œil au bloc `params` : + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Il y a une valeur par défaut configurée dans le workflow, donc nous n'avons pas à la fournir. +Mais si nous en fournissons une sur la ligne de commande, la valeur que nous spécifions sera utilisée à la place de la valeur par défaut. + +Essayez : + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Sortie de la commande" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Vous devriez voir de nouvelles sorties finales nommées avec votre nom de lot personnalisé. + +??? abstract "Contenu du répertoire" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +C'est un aspect de la configuration des entrées, que nous couvrirons plus en détail dans la Partie 3, mais pour l'instant l'important est de savoir que les paramètres d'entrée peuvent recevoir des valeurs par défaut. + +#### 2.3.6. Un process peut produire plusieurs sorties + +Dans la définition du process `collectGreetings`, nous voyons les déclarations de sortie suivantes : + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Qui sont ensuite référencées par le nom donné avec `emit:` dans le bloc `publish:` : + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Cela facilite ensuite le passage de sorties spécifiques individuellement à d'autres processes dans le workflow, en combinaison avec divers opérateurs. + +#### 2.3.7. Les sorties publiées peuvent être organisées + +Dans le bloc `output`, nous avons utilisé des chemins personnalisés pour regrouper les résultats intermédiaires afin de faciliter l'identification des sorties finales du workflow. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Il existe des moyens plus sophistiqués d'organiser les sorties publiées ; nous en aborderons quelques-uns dans la partie sur la configuration. + +!!! tip "Vous voulez en savoir plus sur la construction de workflows ?" + + Pour une couverture détaillée de la construction de workflows multi-étapes, consultez [Hello Nextflow Partie 3 : Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Récapitulatif + +Vous comprenez à un niveau basique comment les workflows multi-étapes sont construits en utilisant des channels et des opérateurs et comment ils fonctionnent. +Vous avez également vu que les processes peuvent prendre plusieurs entrées et produire plusieurs sorties, et que celles-ci peuvent être publiées de manière structurée. + +### Et ensuite ? + +Apprenez comment les pipelines Nextflow peuvent être modularisés pour promouvoir la réutilisation du code et la maintenabilité. + +--- + +## 3. Exécution de pipelines modularisés + +Jusqu'à présent, tous les workflows que nous avons examinés consistaient en un seul fichier de workflow contenant tout le code pertinent. + +Cependant, les pipelines du monde réel bénéficient généralement d'être _modularisés_, ce qui signifie que le code est divisé en différents fichiers. +Cela peut rendre leur développement et leur maintenance plus efficaces et durables. + +Ici, nous allons démontrer la forme la plus courante de modularité du code dans Nextflow, qui est l'utilisation de **modules**. + +Dans Nextflow, un **module** est une définition de process unique qui est encapsulée par elle-même dans un fichier de code autonome. +Pour utiliser un module dans un workflow, vous ajoutez simplement une instruction d'importation d'une seule ligne à votre fichier de code de workflow ; ensuite vous pouvez intégrer le process dans le workflow de la même manière que vous le feriez normalement. +Cela permet de réutiliser les définitions de process dans plusieurs workflows sans produire plusieurs copies du code. + +Jusqu'à présent, nous avons exécuté des workflows qui avaient tous leurs processes inclus dans un fichier de code monolithique. +Maintenant, nous allons voir à quoi cela ressemble lorsque les processes sont stockés dans des modules individuels. + +Nous avons bien sûr encore une fois préparé un workflow approprié pour la démonstration, appelé `2c-modules.nf`, ainsi qu'un ensemble de modules situés dans le répertoire `modules/`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Contenu du répertoire" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Vous voyez qu'il y a quatre fichiers Nextflow, chacun nommé d'après l'un des processes. +Vous pouvez ignorer le fichier `cowpy.nf` pour l'instant ; nous y viendrons plus tard. + +### 3.1. Examiner le code + +Cette fois, nous allons regarder le code en premier. +Commencez par ouvrir le fichier de workflow `2c-modules.nf`. + +??? full-code "Fichier de code complet" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Vous voyez que la logique du workflow est exactement la même que dans la version précédente du workflow. +Cependant, le code du process a disparu du fichier du workflow, et à la place il y a des instructions `include` pointant vers des fichiers séparés sous `modules`. + +```groovy title="hello-modules.nf" linenums="3" +// Inclure les modules +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Ouvrez l'un de ces fichiers et vous trouverez le code du process correspondant. + +??? full-code "Fichier de code complet" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Utilise echo pour imprimer 'Hello World!' dans un fichier + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Comme vous pouvez le voir, le code du process n'a pas changé ; il a juste été copié dans un fichier de module individuel au lieu d'être dans le fichier de workflow principal. +La même chose s'applique aux deux autres processes. + +Voyons donc à quoi ressemble l'exécution de cette nouvelle version. + +### 3.2. Exécuter le workflow + +Exécutez cette commande dans votre terminal, avec le drapeau `-resume` : + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Vous remarquerez que les exécutions de process ont toutes été mises en cache avec succès, ce qui signifie que Nextflow a reconnu qu'il a déjà fait le travail demandé, même si le code a été divisé et le fichier de workflow principal a été renommé. + +Rien de tout cela n'a d'importance pour Nextflow ; ce qui compte est le script de job qui est généré une fois que tout le code a été rassemblé et évalué. + +!!! tip "Astuce" + + Il est également possible d'encapsuler une section d'un workflow comme un « subworkflow » qui peut être importé dans un pipeline plus grand, mais cela dépasse le cadre de cette formation. + + Vous pouvez en apprendre plus sur le développement de workflows composables dans le Side Quest sur [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/). + +### Récapitulatif + +Vous savez comment les processes peuvent être stockés dans des modules autonomes pour promouvoir la réutilisation du code et améliorer la maintenabilité. + +### Et ensuite ? + +Apprenez à utiliser des conteneurs pour gérer les dépendances logicielles. + +--- + +## 4. Utilisation de logiciels conteneurisés + +Jusqu'à présent, les workflows que nous avons utilisés comme exemples n'avaient besoin que d'exécuter des opérations de traitement de texte très basiques en utilisant des outils UNIX disponibles dans notre environnement. + +Cependant, les pipelines du monde réel nécessitent généralement des outils et des packages spécialisés qui ne sont pas inclus par défaut dans la plupart des environnements. +Normalement, vous devriez installer ces outils, gérer leurs dépendances et résoudre les conflits éventuels. + +Tout cela est très fastidieux et ennuyeux. +Une bien meilleure façon d'aborder ce problème est d'utiliser des **conteneurs**. + +Un **conteneur** est une unité logicielle légère, autonome et exécutable créée à partir d'une **image** de conteneur qui inclut tout ce qui est nécessaire pour exécuter une application, y compris le code, les bibliothèques système et les paramètres. + +!!! Tip "Astuce" + + Nous enseignons cela en utilisant la technologie [Docker](https://www.docker.com/get-started/), mais Nextflow prend en charge [plusieurs autres technologies de conteneurs](https://www.nextflow.io/docs/latest/container.html#) également. + +### 4.1. Utiliser un conteneur directement + +D'abord, essayons d'interagir directement avec un conteneur. +Cela aidera à solidifier votre compréhension de ce que sont les conteneurs avant que nous commencions à les utiliser dans Nextflow. + +#### 4.1.1. Télécharger l'image du conteneur + +Pour utiliser un conteneur, vous téléchargez généralement ou « tirez » une image de conteneur depuis un registre de conteneurs, puis exécutez l'image du conteneur pour créer une instance de conteneur. + +La syntaxe générale est la suivante : + +```bash title="Syntaxe" +docker pull '<container>' +``` + +- `docker pull` est l'instruction au système de conteneurs pour tirer une image de conteneur depuis un dépôt. +- `'<container>'` est l'adresse URI de l'image du conteneur. + +Comme exemple, tirons une image de conteneur qui contient [cowpy](https://github.com/jeffbuttars/cowpy), une implémentation Python d'un outil appelé `cowsay` qui génère de l'art ASCII pour afficher des entrées de texte arbitraires de manière amusante. + +Il existe divers dépôts où vous pouvez trouver des conteneurs publiés. +Nous avons utilisé le service [Seqera Containers](https://seqera.io/containers/) pour générer cette image de conteneur Docker à partir du package Conda `cowpy` : `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Exécutez la commande de téléchargement complète : + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Sortie de la commande" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Cela indique au système de télécharger l'image spécifiée. +Une fois le téléchargement terminé, vous avez une copie locale de l'image du conteneur. + +#### 4.1.2. Démarrer le conteneur + +Les conteneurs peuvent être exécutés comme une commande ponctuelle, mais vous pouvez aussi les utiliser de manière interactive, ce qui vous donne une invite shell à l'intérieur du conteneur et vous permet de jouer avec la commande. + +La syntaxe générale est la suivante : + +```bash title="Syntaxe" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'` est l'instruction au système de conteneurs pour démarrer une instance de conteneur à partir d'une image de conteneur et exécuter une commande dedans. +- `--rm` indique au système d'arrêter l'instance du conteneur une fois la commande terminée. + +Entièrement assemblée, la commande d'exécution du conteneur ressemble à ceci : + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Exécutez cette commande, et vous devriez voir votre invite changer en quelque chose comme `(base) root@b645838b3314:/tmp#`, ce qui indique que vous êtes maintenant à l'intérieur du conteneur. + +Vous pouvez vérifier cela en exécutant `ls` pour lister le contenu du répertoire : + +```bash +ls / +``` + +??? success "Sortie de la commande" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Vous voyez que le système de fichiers à l'intérieur du conteneur est différent du système de fichiers sur votre système hôte. + +!!! Tip "Astuce" + + Lorsque vous exécutez un conteneur, il est isolé du système hôte par défaut. + Cela signifie que le conteneur ne peut pas accéder aux fichiers du système hôte à moins que vous ne l'autorisiez explicitement en spécifiant que vous voulez monter un volume dans la commande `docker run` en utilisant la syntaxe suivante : + + ```bash title="Syntaxe" + -v <outside_path>:<inside_path> + ``` + + Cela établit effectivement un tunnel à travers la paroi du conteneur que vous pouvez utiliser pour accéder à cette partie de votre système de fichiers. + + Ceci est couvert plus en détail dans [Partie 5 de Hello Nextflow](../hello_nextflow/05_hello_containers.md). + +#### 4.1.3. Exécuter l'outil `cowpy` + +Depuis l'intérieur du conteneur, vous pouvez exécuter la commande `cowpy` directement. + +```bash +cowpy "Hello Containers" +``` + +??? success "Sortie de la commande" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Cela produit de l'art ASCII du personnage de vache par défaut (ou « cowacter ») avec une bulle de dialogue contenant le texte que nous avons spécifié. + +Maintenant que vous avez testé l'utilisation de base, vous pouvez essayer de lui donner quelques paramètres. +Par exemple, la documentation de l'outil dit que nous pouvons définir le personnage avec `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Sortie de la commande" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Cette fois, la sortie d'art ASCII montre le pingouin Linux, Tux, parce que nous avons spécifié le paramètre `-c tux`. + +Puisque vous êtes à l'intérieur du conteneur, vous pouvez exécuter la commande cowpy autant de fois que vous le souhaitez, en variant les paramètres d'entrée, sans avoir à vous soucier d'installer des bibliothèques sur votre système lui-même. + +??? tip "Autres personnages disponibles" + + Utilisez le drapeau '-c' pour choisir un personnage différent, y compris : + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +N'hésitez pas à jouer avec cela. +Quand vous avez terminé, quittez le conteneur en utilisant la commande `exit` : + +```bash +exit +``` + +Vous vous retrouverez dans votre shell normal. + +### 4.2. Utiliser un conteneur dans un workflow + +Lorsque nous exécutons un pipeline, nous voulons pouvoir dire à Nextflow quel conteneur utiliser à chaque étape, et surtout, nous voulons qu'il gère tout ce travail que nous venons de faire : tirer le conteneur, le démarrer, exécuter la commande et arrêter le conteneur quand c'est fait. + +Bonne nouvelle : c'est exactement ce que Nextflow va faire pour nous. +Nous avons juste besoin de spécifier un conteneur pour chaque process. + +Pour démontrer comment cela fonctionne, nous avons fait une autre version de notre workflow qui exécute `cowpy` sur le fichier de salutations collectées produit à la troisième étape. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Cela devrait produire un fichier contenant l'art ASCII avec les trois salutations dans la bulle de dialogue. + +#### 4.2.1. Examiner le code + +Le workflow est très similaire au précédent, plus l'étape supplémentaire pour exécuter `cowpy`. + +??? full-code "Fichier de code complet" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Inclure les modules + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // émettre une salutation + sayHello(greeting_ch) + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + // collecter toutes les salutations dans un seul fichier + collectGreetings(convertToUpper.out.collect(), params.batch) + // générer de l'art ASCII des salutations avec cowpy + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Vous voyez que ce workflow importe un process `cowpy` depuis un fichier de module, et l'appelle sur la sortie de l'appel `collectGreetings()`, plus un paramètre d'entrée appelé `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// générer de l'art ASCII avec cowpy +cowpy(collectGreetings.out, params.character) +``` + +Le process `cowpy`, qui encapsule la commande cowpy pour générer de l'art ASCII, est défini dans le module `cowpy.nf`. + +??? full-code "Fichier de code complet" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Générer de l'art ASCII avec cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Le process `cowpy` nécessite deux entrées : le chemin vers un fichier d'entrée contenant le texte à mettre dans la bulle de dialogue (`input_file`), et une valeur pour la variable de personnage. + +Surtout, il inclut également la ligne `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`, qui pointe vers l'URI du conteneur que nous avons utilisé plus tôt. + +#### 4.2.2. Vérifier que Docker est activé dans la configuration + +Nous allons légèrement anticiper la Partie 3 de cette formation en introduisant le fichier de configuration `nextflow.config`, qui est l'un des principaux moyens que Nextflow offre pour configurer l'exécution du workflow. +Lorsqu'un fichier nommé `nextflow.config` est présent dans le répertoire courant, Nextflow le chargera automatiquement et appliquera toute configuration qu'il contient. + +À cette fin, nous avons inclus un fichier `nextflow.config` avec une seule ligne de code qui active Docker. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Cette configuration indique à Nextflow d'utiliser Docker pour tout process qui spécifie un conteneur compatible. + +!!! tip "Astuce" + + Il est techniquement possible d'activer l'exécution Docker depuis la ligne de commande, sur une base par exécution, en utilisant le paramètre `-with-docker <container>`. + Cependant, cela ne nous permet de spécifier qu'un seul conteneur pour l'ensemble du workflow, alors que l'approche que nous venons de vous montrer nous permet de spécifier un conteneur différent par process. + Cette dernière est bien meilleure pour la modularité, la maintenance du code et la reproductibilité. + +#### 4.2.3. Exécuter le workflow + +Juste pour récapituler, voici ce que nous sommes sur le point d'exécuter : + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Pensez-vous que cela va fonctionner ? + +Exécutons le workflow avec le drapeau `-resume`, et spécifions que nous voulons que le personnage soit le turkey. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +Les trois premières étapes ont été mises en cache puisque nous les avons déjà exécutées auparavant, mais le process `cowpy` est nouveau donc il est effectivement exécuté. + +Vous pouvez trouver la sortie de l'étape `cowpy` dans le répertoire `results`. + +??? abstract "Contenu du fichier" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Vous voyez que le personnage dit toutes les salutations, puisqu'il a été exécuté sur le fichier de salutations collectées en majuscules. + +Plus important encore, nous avons pu exécuter cela dans le cadre de notre pipeline sans avoir à faire une installation correcte de cowpy et de toutes ses dépendances. +Et nous pouvons maintenant partager le pipeline avec des collaborateurs et les faire l'exécuter sur leur infrastructure sans qu'ils aient besoin d'installer quoi que ce soit non plus, à part Docker ou l'une de ses alternatives (comme Singularity/Apptainer) comme mentionné ci-dessus. + +#### 4.2.4. Inspecter comment Nextflow a lancé la tâche conteneurisée + +En guise de coda finale à cette section, jetons un coup d'œil au sous-répertoire de travail pour l'un des appels au process `cowpy` pour avoir un peu plus d'aperçu sur la façon dont Nextflow fonctionne avec les conteneurs sous le capot. + +Vérifiez la sortie de votre commande `nextflow run` pour trouver le chemin vers le sous-répertoire de travail pour le process `cowpy`. +En regardant ce que nous avons obtenu pour l'exécution montrée ci-dessus, la ligne de log console pour le process `cowpy` commence par `[7f/caf718]`. +Cela correspond au chemin de répertoire tronqué suivant : `work/7f/caf718`. + +Dans ce répertoire, vous trouverez le fichier `.command.run` qui contient toutes les commandes que Nextflow a exécutées en votre nom lors de l'exécution du pipeline. + +??? abstract "Contenu du fichier" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + ... + ``` + +Si vous cherchez `nxf_launch` dans ce fichier, vous devriez voir quelque chose comme ceci : + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh +} +``` + +Cette commande de lancement montre que Nextflow utilise une commande `docker run` très similaire pour lancer l'appel au process que lorsque nous l'avons exécuté manuellement. +Elle monte également le sous-répertoire de travail correspondant dans le conteneur, définit le répertoire de travail à l'intérieur du conteneur en conséquence, et exécute notre script bash modélisé dans le fichier `.command.sh`. + +Cela confirme que tout le travail difficile que nous avons dû faire manuellement dans la section précédente est maintenant fait pour nous par Nextflow ! + +### Récapitulatif + +Vous comprenez quel rôle jouent les conteneurs dans la gestion des versions des outils logiciels et la garantie de la reproductibilité. + +Plus généralement, vous avez une compréhension de base de ce que sont les composants principaux des pipelines Nextflow du monde réel et comment ils sont organisés. +Vous connaissez les fondamentaux de la façon dont Nextflow peut traiter plusieurs entrées efficacement, exécuter des workflows composés de plusieurs étapes connectées ensemble, exploiter des composants de code modulaires, et utiliser des conteneurs pour une plus grande reproductibilité et portabilité. + +### Et ensuite ? + +Prenez une autre pause ! C'était une grande quantité d'informations sur le fonctionnement des pipelines Nextflow. + +Dans la dernière section de cette formation, nous allons approfondir le sujet de la configuration. +Vous apprendrez comment configurer l'exécution de votre pipeline pour s'adapter à votre infrastructure ainsi que gérer la configuration des entrées et des paramètres. + +--- + +## Quiz + +<quiz> +Pourquoi Nextflow crée-t-il un répertoire de tâche séparé pour chaque appel de process ? +- [ ] Pour améliorer la vitesse d'exécution +- [ ] Pour réduire l'utilisation de la mémoire +- [x] Pour isoler les exécutions et éviter les collisions entre les sorties +- [ ] Pour permettre la compression parallèle des fichiers + +En savoir plus : [1.3. Trouver les sorties et logs originaux](#13-trouver-les-sorties-et-logs-originaux) +</quiz> + +<quiz> +Que fait l'option `-ansi-log false` lors de l'exécution d'un workflow ? +- [ ] Désactive toute sortie console +- [x] Supprime les couleurs de la sortie +- [x] Affiche tous les chemins de répertoires de tâches au lieu de les condenser sur une seule ligne +- [ ] Active le mode de débogage verbeux + +En savoir plus : [1.3.2. Faire afficher plus de détails par le terminal](#132-faire-afficher-plus-de-details-par-le-terminal) + +Vous pouvez également utiliser l'une des variables d'environnement suivantes si vous préférez ce style : + +```bash +export NXF_ANSI_LOG=0 +# ou +export NO_COLOR=1 +``` + +</quiz> + +<quiz> +Dans le code `#!groovy channel.fromPath(params.input).splitCsv().map { line -> line[0] }`, que fait `#!groovy .map { line -> line[0] }` ? +- [ ] Filtre les lignes vides +- [ ] Trie les lignes par ordre alphabétique +- [x] Extrait la première colonne de chaque ligne CSV +- [ ] Compte le nombre de lignes + +En savoir plus : [1.4.1. Chargement des données d'entrée depuis le CSV](#141-chargement-des-donnees-dentree-depuis-le-csv) +</quiz> + +<quiz> +Pourquoi est-il important d'inclure la valeur d'entrée dans les noms de fichiers de sortie (par exemple, `#!groovy "${greeting}-output.txt"`) ? +- [ ] Pour améliorer la vitesse de traitement +- [ ] Pour activer la fonctionnalité resume +- [x] Pour empêcher les fichiers de sortie de s'écraser mutuellement lors du traitement de plusieurs entrées +- [ ] Pour faciliter la compression des fichiers + +En savoir plus : [1.4.3. Comment les sorties sont nommées](#143-comment-les-sorties-sont-nommees) +</quiz> + +<quiz> +Quel est le but de l'instruction `include` dans un workflow modularisé ? +- [ ] Copier le code du process dans le fichier du workflow +- [x] Importer une définition de process depuis un fichier de module externe +- [ ] Inclure des paramètres de configuration +- [ ] Ajouter des commentaires de documentation + +En savoir plus : [3. Exécution de pipelines modularisés](#3-execution-de-pipelines-modularises) +</quiz> + +<quiz> +Lorsque vous modularisez un workflow et l'exécutez avec `-resume`, que se passe-t-il ? +- [ ] La mise en cache est désactivée pour les processes modulaires +- [ ] Toutes les tâches doivent être ré-exécutées +- [x] La mise en cache fonctionne normalement en fonction des scripts de job générés +- [ ] Seul le fichier de workflow principal est mis en cache + +En savoir plus : [3.2. Exécuter le workflow](#32-executer-le-workflow) +</quiz> + +<quiz> +Que spécifie la directive `container` dans une définition de process ? +- [ ] Le répertoire de travail pour le process +- [ ] L'allocation maximale de mémoire +- [x] L'URI de l'image de conteneur à utiliser pour exécuter le process +- [ ] Le format du fichier de sortie + +En savoir plus : [4.2. Utiliser un conteneur dans un workflow](#42-utiliser-un-conteneur-dans-un-workflow) +</quiz> + +<quiz> +Dans le fichier `.command.run`, que contient la fonction `nxf_launch` ? +- [ ] Les informations de version de Nextflow +- [ ] Les paramètres du workflow +- [x] La commande `docker run` avec les montages de volumes et les paramètres du conteneur +- [ ] Les déclarations d'entrée du process + +En savoir plus : [4.2.4. Inspecter comment Nextflow a lancé la tâche conteneurisée](#424-inspecter-comment-nextflow-a-lance-la-tache-conteneurisee) +</quiz> + +<quiz> +Que gère automatiquement Nextflow lors de l'exécution d'un process conteneurisé ? (Sélectionnez toutes les réponses applicables) +- [x] Télécharger l'image du conteneur si nécessaire +- [x] Monter le répertoire de travail dans le conteneur +- [x] Exécuter le script du process à l'intérieur du conteneur +- [x] Nettoyer l'instance du conteneur après l'exécution + +En savoir plus : [4. Utilisation de logiciels conteneurisés](#4-utilisation-de-logiciels-conteneurises) +</quiz> diff --git a/docs/fr/docs/nextflow_run/03_config.md b/docs/fr/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..40aaa9df61 --- /dev/null +++ b/docs/fr/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Partie 3 : Configuration d'exécution + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Cette section explorera comment gérer la configuration d'un pipeline Nextflow afin de personnaliser son comportement, l'adapter à différents environnements et optimiser l'utilisation des ressources _sans modifier une seule ligne du code du workflow lui-même_. + +Il existe plusieurs façons de le faire, qui peuvent être utilisées en combinaison et sont interprétées selon l'ordre de priorité décrit [ici](https://www.nextflow.io/docs/latest/config.html). + +Dans cette partie de la formation, nous allons vous montrer le mécanisme de fichier de configuration le plus simple et le plus courant, le fichier `nextflow.config`, que vous avez déjà rencontré dans la section sur les conteneurs de la Partie 2. + +Nous passerons en revue les composants essentiels de la configuration Nextflow tels que les directives de process, les executors, les profils et les fichiers de paramètres. +En apprenant à utiliser efficacement ces options de configuration, vous pourrez tirer pleinement parti de la flexibilité, de l'évolutivité et des performances des pipelines Nextflow. + +Pour exercer ces éléments de configuration, nous allons exécuter une nouvelle copie du workflow que nous avons exécuté à la fin de la Partie 2 de cette formation, renommé `3-main.nf`. + +Si vous n'êtes pas familier avec le pipeline Hello ou si vous avez besoin d'un rappel, consultez [cette page d'information](../info/hello_pipeline.md). + +--- + +## 1. Gérer les paramètres d'entrée du workflow + +??? example "Scénario" + + Vous avez téléchargé un pipeline et souhaitez l'exécuter de manière répétée avec les mêmes fichiers d'entrée et paramètres, mais vous ne voulez pas taper tous les paramètres à chaque fois. + Ou peut-être configurez-vous le pipeline pour un collègue qui n'est pas à l'aise avec les arguments en ligne de commande. + +Nous allons commencer par un aspect de la configuration qui est simplement une extension de ce avec quoi nous avons travaillé jusqu'à présent : la gestion des paramètres d'entrée. + +Actuellement, notre workflow est configuré pour accepter plusieurs valeurs de paramètres via la ligne de commande, déclarées dans un bloc `params` dans le script du workflow lui-même. +L'un a une valeur par défaut définie dans sa déclaration. + +Cependant, vous pourriez vouloir définir des valeurs par défaut pour tous, ou remplacer la valeur par défaut existante sans avoir à spécifier les paramètres sur la ligne de commande, ou modifier le fichier de script original. + +Il existe plusieurs façons de le faire ; nous allons vous montrer trois façons basiques qui sont très couramment utilisées. + +### 1.1. Configurer des valeurs dans `nextflow.config` + +C'est l'approche la plus simple, bien que ce soit peut-être la moins flexible puisque le fichier `nextflow.config` principal n'est pas quelque chose que vous voulez modifier pour chaque exécution. +Mais cela a l'avantage de séparer les préoccupations de _déclarer_ les paramètres dans le workflow (ce qui y a définitivement sa place) versus fournir des _valeurs par défaut_, qui sont plus à leur place dans un fichier de configuration. + +Faisons cela en deux étapes. + +#### 1.1.1. Créer un bloc `params` dans le fichier de configuration + +Effectuez les modifications de code suivantes dans le fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Notez que nous n'avons pas simplement copié le bloc `params` du workflow vers le fichier de configuration. +Pour le paramètre `batch` qui avait déjà une valeur par défaut déclarée, la syntaxe est un peu différente. +Dans le fichier du workflow, c'est une déclaration typée. +Dans la configuration, ce sont des affectations de valeurs. + +Techniquement, cela suffit pour remplacer les valeurs par défaut toujours spécifiées dans le fichier du workflow. +Vous pourriez modifier la valeur par défaut pour `batch` et exécuter le workflow pour vous assurer que la valeur définie dans le fichier de configuration remplace celle définie dans le fichier du workflow. + +Mais dans l'esprit de déplacer complètement la configuration vers le fichier de configuration, supprimons entièrement cette valeur par défaut du fichier du workflow. + +#### 1.1.2. Supprimer la valeur par défaut pour `batch` dans le fichier du workflow + +Effectuez la modification de code suivante dans le fichier du workflow `3-main.nf` : + +=== "Après" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Avant" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Paramètres du pipeline + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Maintenant, le fichier du workflow lui-même ne définit aucune valeur par défaut pour ces paramètres. + +#### 1.1.3. Exécuter le pipeline + +Testons que cela fonctionne correctement sans spécifier de paramètres dans la ligne de commande. + +```bash +nextflow run 3-main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'auparavant. + +La sortie finale d'art ASCII est dans le répertoire `results/3-main/`, sous le nom `cowpy-COLLECTED-batch-output.txt`, comme avant. + +??? abstract "Contenu du fichier" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Fonctionnellement, ce déplacement n'a rien changé, mais conceptuellement c'est un peu plus propre d'avoir les valeurs par défaut définies dans le fichier de configuration. + +### 1.2. Utiliser un fichier de configuration spécifique à l'exécution + +??? example "Scénario" + + Vous voulez expérimenter avec différents paramètres sans modifier votre fichier de configuration principal. + +Vous pouvez le faire en créant un nouveau fichier `nextflow.config` dans un sous-répertoire que vous utiliserez comme répertoire de travail pour vos expériences. + +#### 1.2.1. Créer le répertoire de travail avec une configuration vierge + +Commençons par créer un nouveau répertoire et nous y déplacer : + +```bash +mkdir -p tux-run +cd tux-run +``` + +Ensuite, créez un fichier de configuration vierge dans ce répertoire : + +```bash +touch nextflow.config +``` + +Cela produit un fichier vide. + +#### 1.2.2. Configurer la configuration expérimentale + +Ouvrez maintenant le nouveau fichier et ajoutez les paramètres que vous souhaitez personnaliser : + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Notez que le chemin vers le fichier d'entrée doit refléter la structure des répertoires. + +#### 1.2.3. Exécuter le pipeline + +Nous pouvons maintenant exécuter notre pipeline depuis notre nouveau répertoire de travail. +Assurez-vous d'adapter le chemin en conséquence ! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Cela créera un nouvel ensemble de répertoires sous `tux-run/` incluant `tux-run/work/` et `tux-run/results/`. + +Dans cette exécution, Nextflow combine le `nextflow.config` dans notre répertoire actuel avec le `nextflow.config` dans le répertoire racine du pipeline, et remplace ainsi le personnage par défaut (turkey) par le personnage tux. + +Le fichier de sortie final devrait contenir le personnage tux disant les salutations. + +??? abstract "Contenu du fichier" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Voilà ; maintenant vous avez un espace pour expérimenter sans modifier votre configuration « normale ». + +!!! warning "Avertissement" + + Assurez-vous de revenir au répertoire précédent avant de passer à la section suivante ! + + ```bash + cd .. + ``` + +Maintenant regardons une autre façon utile de définir des valeurs de paramètres. + +### 1.3. Utiliser un fichier de paramètres + +??? example "Scénario" + + Vous devez partager les paramètres exacts d'exécution avec un collaborateur, ou les enregistrer pour une publication. + +L'approche du sous-répertoire fonctionne très bien pour expérimenter, mais elle implique un peu de configuration et nécessite que vous adaptiez les chemins en conséquence. +Il existe une approche plus simple pour quand vous voulez exécuter votre pipeline avec un ensemble spécifique de valeurs, ou permettre à quelqu'un d'autre de le faire avec un effort minimal. + +Nextflow nous permet de spécifier des paramètres via un fichier de paramètres au format YAML ou JSON, ce qui rend très pratique la gestion et la distribution d'ensembles alternatifs de valeurs par défaut, par exemple, ainsi que de valeurs de paramètres spécifiques à l'exécution. + +#### 1.3.1. Examiner le fichier de paramètres d'exemple + +Pour démontrer cela, nous fournissons un fichier de paramètres d'exemple dans le répertoire actuel, appelé `test-params.yaml` : + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Ce fichier de paramètres contient une paire clé-valeur pour chacune des entrées que nous voulons spécifier. +Notez l'utilisation de deux-points (`:`) au lieu de signes égal (`=`) si vous comparez la syntaxe au fichier de configuration. +Le fichier de config est écrit en Groovy, tandis que le fichier de paramètres est écrit en YAML. + +!!! info "Information" + + Nous fournissons également une version JSON du fichier de paramètres comme exemple mais nous n'allons pas l'exécuter ici. + N'hésitez pas à essayer celui-là par vous-même. + +#### 1.3.2. Exécuter le pipeline + +Pour exécuter le workflow avec ce fichier de paramètres, ajoutez simplement `-params-file <filename>` à la commande de base. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Le fichier de sortie final devrait contenir le personnage stegosaurus disant les salutations. + +??? abstract "Contenu du fichier" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Utiliser un fichier de paramètres peut sembler excessif quand vous n'avez que quelques paramètres à spécifier, mais certains pipelines attendent des dizaines de paramètres. +Dans ces cas, utiliser un fichier de paramètres nous permettra de fournir des valeurs de paramètres au moment de l'exécution sans avoir à taper des lignes de commande massives et sans modifier le script du workflow. + +Cela facilite également la distribution d'ensembles de paramètres à des collaborateurs, ou comme information supplémentaire pour une publication, par exemple. +Cela rend votre travail plus reproductible par d'autres. + +### Récapitulatif + +Vous savez comment tirer parti des options de configuration clés pour gérer les entrées du workflow. + +### Et ensuite ? + +Apprenez à gérer où et comment les sorties de votre workflow sont publiées. + +--- + +## 2. Gérer les sorties du workflow + +??? example "Scénario" + + Votre pipeline publie les sorties dans un répertoire codé en dur, mais vous voulez organiser les résultats par projet ou nom d'expérience sans modifier le code du workflow à chaque fois. + +Le workflow que nous avons hérité utilise des chemins pour les déclarations de sortie au niveau du workflow, ce qui n'est pas terriblement flexible et implique beaucoup de répétition. + +Regardons quelques façons courantes de configurer cela pour être plus flexible. + +### 2.1. Personnaliser le nom du répertoire `outputDir` + +Chaque version du workflow que nous avons exécutée jusqu'à présent a publié ses sorties dans un sous-répertoire différent codé en dur dans les définitions de sortie. + +Changeons cela pour utiliser un paramètre configurable par l'utilisateur. +Nous pourrions créer un tout nouveau paramètre pour cela, mais utilisons le paramètre `batch` puisqu'il est juste là. + +#### 2.1.1. Définir une valeur pour `outputDir` dans le fichier de configuration + +Le chemin que Nextflow utilise pour publier les sorties est contrôlé par l'option `outputDir`. +Pour changer le chemin pour toutes les sorties, vous pouvez définir une valeur pour cette option dans le fichier de configuration `nextflow.config`. + +Ajoutez le code suivant au fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="9" + /* + * Paramètres du pipeline + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Cela remplacera le chemin par défaut intégré, `results/`, par `results/` plus la valeur du paramètre `batch` comme sous-répertoire. +Vous pourriez également changer la partie `results` si vous le souhaitiez. + +Pour un changement temporaire, vous pourriez définir cette option depuis la ligne de commande en utilisant le paramètre `-output-dir` dans votre commande (mais alors vous ne pourriez pas utiliser la valeur du paramètre `batch`). + +#### 2.1.2. Supprimer la partie répétée du chemin codé en dur + +Nous avons encore un sous-répertoire codé en dur dans les options de sortie, alors débarrassons-nous de cela maintenant. + +Effectuez les modifications de code suivantes dans le fichier du workflow : + +=== "Après" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +Nous aurions également pu simplement ajouter `${params.batch}` à chaque chemin au lieu de modifier la valeur par défaut de `outputDir`, mais c'est plus concis. + +#### 2.1.3. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot sur `outdir` depuis la ligne de commande. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'auparavant, sauf que cette fois nous trouvons nos sorties sous `results/outdir/`. + +??? abstract "Contenu du répertoire" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Vous pouvez combiner cette approche avec des définitions de chemins personnalisés pour construire n'importe quelle hiérarchie de répertoires que vous souhaitez. + +### 2.2. Organiser les sorties par process + +Une façon populaire d'organiser davantage les sorties est de le faire par process, _c.-à-d._ créer des sous-répertoires pour chaque process exécuté dans le pipeline. + +#### 2.2.1. Remplacer les chemins de sortie par une référence aux noms de process + +Tout ce que vous avez à faire est de référencer le nom du process comme `<task>.name` dans la déclaration du chemin de sortie. + +Effectuez les modifications suivantes dans le fichier du workflow : + +=== "Après" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Avant" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Cela supprime les éléments codés en dur restants de la configuration du chemin de sortie. + +#### 2.2.2. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot sur `pnames` depuis la ligne de commande. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'auparavant, sauf que cette fois nous trouvons nos sorties sous `results/pnames/`, et elles sont groupées par process. + +??? abstract "Contenu du répertoire" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Notez qu'ici nous avons effacé la distinction entre `intermediates` versus les sorties finales au niveau supérieur. +Vous pourriez bien sûr mélanger ces approches, par exemple en définissant le chemin de la première sortie comme `intermediates/${sayHello.name}` + +### 2.3. Définir le mode de publication au niveau du workflow + +Enfin, dans l'esprit de réduire la quantité de code répétitif, nous pouvons remplacer les déclarations `mode` par sortie par une seule ligne dans la configuration. + +#### 2.3.1. Ajouter `workflow.output.mode` au fichier de configuration + +Ajoutez le code suivant au fichier `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Tout comme l'option `outputDir`, donner une valeur à `workflow.output.mode` dans le fichier de configuration serait suffisant pour remplacer ce qui est défini dans le fichier du workflow, mais supprimons quand même le code inutile. + +#### 2.3.2. Supprimer le mode de sortie du fichier du workflow + +Effectuez les modifications suivantes dans le fichier du workflow : + +=== "Après" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Avant" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +C'est plus concis, n'est-ce pas ? + +#### 2.3.3. Exécuter le pipeline + +Testons que cela fonctionne correctement, en définissant le nom du lot sur `outmode` depuis la ligne de commande. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Cela produit toujours la même sortie qu'auparavant, sauf que cette fois nous trouvons nos sorties sous `results/outmode/`. +Ce sont toujours toutes des copies propres, pas des liens symboliques. + +??? abstract "Contenu du répertoire" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +La principale raison pour laquelle vous pourriez encore vouloir utiliser la façon par sortie de définir le mode est si vous voulez mélanger dans le même workflow, _c.-à-d._ avoir certaines sorties copiées et d'autres liées symboliquement. + +Il y a beaucoup d'autres options que vous pouvez personnaliser de cette façon, mais nous espérons que cela vous donne une idée de la gamme d'options et comment les utiliser efficacement selon vos préférences. + +### Récapitulatif + +Vous savez comment contrôler le nommage et la structure des répertoires où vos sorties sont publiées, ainsi que le mode de publication des sorties du workflow. + +### Et ensuite ? + +Apprenez à adapter la configuration de votre workflow à votre environnement de calcul, en commençant par la technologie d'empaquetage logiciel. + +--- + +## 3. Sélectionner une technologie d'empaquetage logiciel + +Jusqu'à présent, nous avons examiné les éléments de configuration qui contrôlent comment les entrées vont et d'où les sorties sortent. Maintenant il est temps de se concentrer plus spécifiquement sur l'adaptation de la configuration de votre workflow à votre environnement de calcul. + +La première étape sur ce chemin est de spécifier d'où vont venir les packages logiciels qui seront exécutés à chaque étape. +Sont-ils déjà installés dans l'environnement de calcul local ? +Devons-nous récupérer des images et les exécuter via un système de conteneurs ? +Ou devons-nous récupérer des packages Conda et construire un environnement Conda local ? + +Dans la toute première partie de cette formation (Parties 1-4) nous avons juste utilisé des logiciels installés localement dans notre workflow. +Ensuite dans la Partie 5, nous avons introduit les conteneurs Docker et le fichier `nextflow.config`, que nous avons utilisé pour activer l'utilisation des conteneurs Docker. + +Maintenant voyons comment nous pouvons configurer une option d'empaquetage logiciel alternative via le fichier `nextflow.config`. + +### 3.1. Désactiver Docker et activer Conda dans le fichier de config + +??? example "Scénario" + + Vous déplacez votre pipeline vers un cluster HPC où Docker n'est pas autorisé pour des raisons de sécurité. + Le cluster prend en charge Singularity et Conda, donc vous devez changer votre configuration en conséquence. + +Nextflow prend en charge plusieurs technologies de conteneurs, y compris Singularity (qui est plus largement utilisé sur HPC), ainsi que des gestionnaires de packages logiciels tels que Conda. + +Nous pouvons changer notre fichier de configuration pour utiliser Conda au lieu de Docker. +Pour ce faire, changeons la valeur de `docker.enabled` à `false`, et ajoutons une directive activant l'utilisation de Conda : + +=== "Après" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Cela permettra à Nextflow de créer et d'utiliser des environnements Conda pour les processes qui ont des packages Conda spécifiés. +Ce qui signifie que nous devons maintenant en ajouter un à notre process `cowpy` ! + +### 3.2. Spécifier un package Conda dans la définition du process + +Nous avons déjà récupéré l'URI pour un package Conda contenant l'outil `cowpy` : `conda-forge::cowpy==1.1.5` + +Maintenant nous ajoutons l'URI à la définition du process `cowpy` en utilisant la directive `conda` : + +=== "Après" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Avant" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Pour être clair, nous ne _remplaçons_ pas la directive `docker`, nous _ajoutons_ une option alternative. + +!!! tip "Astuce" + + Il existe plusieurs façons d'obtenir l'URI pour un package conda donné. + Nous recommandons d'utiliser la requête de recherche [Seqera Containers](https://seqera.io/containers/), qui vous donnera un URI que vous pouvez copier et coller, même si vous ne prévoyez pas de créer un conteneur à partir de celui-ci. + +### 3.3. Exécuter le workflow pour vérifier qu'il peut utiliser Conda + +Essayons cela. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Sortie de la commande" + + ```console title="Sortie" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Cela devrait fonctionner sans problème et produire les mêmes sorties qu'auparavant sous `results/conda`. + +En coulisses, Nextflow a récupéré les packages Conda et créé l'environnement, ce qui prend normalement un peu de travail ; donc c'est agréable de ne pas avoir à faire tout cela nous-mêmes ! + +!!! info "Information" + + Cela s'exécute rapidement car le package `cowpy` est assez petit, mais si vous travaillez avec de gros packages, cela peut prendre un peu plus de temps que d'habitude la première fois, et vous pourriez voir la sortie console rester « bloquée » pendant une minute ou plus avant de se terminer. + C'est normal et est dû au travail supplémentaire que Nextflow fait la première fois que vous utilisez un nouveau package. + +De notre point de vue, cela semble fonctionner exactement de la même manière que l'exécution avec Docker, même si en arrière-plan les mécanismes sont un peu différents. + +Cela signifie que nous sommes prêts à exécuter avec des environnements Conda si nécessaire. + +??? info "Mélanger Docker et Conda" + + Puisque ces directives sont assignées par process, il est possible de « mélanger », _c.-à-d._ de configurer certains des processes de votre workflow pour s'exécuter avec Docker et d'autres avec Conda, par exemple, si l'infrastructure de calcul que vous utilisez prend en charge les deux. + Dans ce cas, vous activeriez à la fois Docker et Conda dans votre fichier de configuration. + Si les deux sont disponibles pour un process donné, Nextflow priorisera les conteneurs. + + Et comme noté précédemment, Nextflow prend en charge plusieurs autres technologies d'empaquetage logiciel et de conteneurs, donc vous n'êtes pas limité à ces deux-là. + +### Récapitulatif + +Vous savez comment configurer quel package logiciel chaque process doit utiliser, et comment basculer entre les technologies. + +### Et ensuite ? + +Apprenez à changer la plateforme d'exécution utilisée par Nextflow pour faire réellement le travail. + +--- + +## 4. Sélectionner une plateforme d'exécution + +??? example "Scénario" + + Vous avez développé et testé votre pipeline sur votre ordinateur portable, mais maintenant vous devez l'exécuter sur des milliers d'échantillons. + Votre institution a un cluster HPC avec un ordonnanceur Slurm que vous aimeriez utiliser à la place. + +Jusqu'à présent, nous avons exécuté notre pipeline avec l'executor local. +Cela exécute chaque tâche sur la machine sur laquelle Nextflow s'exécute. +Quand Nextflow démarre, il examine les CPU et la mémoire disponibles. +Si les ressources des tâches prêtes à s'exécuter dépassent les ressources disponibles, Nextflow retiendra les dernières tâches de l'exécution jusqu'à ce qu'une ou plusieurs des tâches précédentes soient terminées, libérant les ressources nécessaires. + +L'executor local est pratique et efficace, mais il est limité à cette seule machine. Pour de très grandes charges de travail, vous pourriez découvrir que votre machine locale est un goulot d'étranglement, soit parce que vous avez une seule tâche qui nécessite plus de ressources que vous n'en avez disponibles, soit parce que vous avez tellement de tâches qu'attendre qu'une seule machine les exécute prendrait trop de temps. + +Nextflow prend en charge [de nombreux backends d'exécution différents](https://www.nextflow.io/docs/latest/executor.html), y compris les ordonnanceurs HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor et d'autres) ainsi que les backends d'exécution cloud (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes et plus). + +### 4.1. Cibler un backend différent + +Le choix de l'executor est défini par une directive de process appelée `executor`. +Par défaut, elle est définie sur `local`, donc la configuration suivante est implicite : + +```groovy title="Configuration intégrée" +process { + executor = 'local' +} +``` + +Pour définir l'executor pour cibler un backend différent, vous spécifieriez simplement l'executor que vous voulez en utilisant une syntaxe similaire à celle décrite ci-dessus pour les allocations de ressources (voir la [documentation](https://www.nextflow.io/docs/latest/executor.html) pour toutes les options). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Avertissement" + + Nous ne pouvons pas réellement tester cela dans l'environnement de formation car il n'est pas configuré pour se connecter à un HPC. + +### 4.2. Gérer la syntaxe spécifique au backend pour les paramètres d'exécution + +La plupart des plateformes de calcul haute performance permettent (et parfois exigent) que vous spécifiiez certains paramètres tels que les demandes et limitations d'allocation de ressources (par exemple le nombre de CPU et la mémoire) et le nom de la file d'attente des jobs à utiliser. + +Malheureusement, chacun de ces systèmes utilise différentes technologies, syntaxes et configurations pour définir comment un job doit être défini et soumis à l'ordonnanceur concerné. + +??? abstract "Exemples" + + Par exemple, le même job nécessitant 8 CPU et 4 Go de RAM à exécuter sur la file « my-science-work » doit être exprimé de différentes manières selon le backend. + + ```bash title="Config pour SLURM / soumettre avec sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config pour PBS / soumettre avec qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config pour SGE / soumettre avec qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Heureusement, Nextflow simplifie tout cela. +Il fournit une syntaxe standardisée pour que vous puissiez spécifier les propriétés pertinentes telles que `cpus`, `memory` et `queue` (voir la documentation pour d'autres propriétés) une seule fois. +Ensuite, au moment de l'exécution, Nextflow utilisera ces paramètres pour générer les scripts spécifiques au backend appropriés en fonction du paramètre d'executor. + +Nous couvrirons cette syntaxe standardisée dans la section suivante. + +### Récapitulatif + +Vous savez maintenant comment changer l'executor pour utiliser différents types d'infrastructure de calcul. + +### Et ensuite ? + +Apprenez à évaluer et exprimer les allocations et limitations de ressources dans Nextflow. + +--- + +## 5. Contrôler les allocations de ressources de calcul + +??? example "Scénario" + + Votre pipeline continue d'échouer sur le cluster parce que les tâches sont tuées pour avoir dépassé les limites de mémoire. + Ou peut-être êtes-vous facturé pour des ressources que vous n'utilisez pas et souhaitez-vous optimiser les coûts. + +La plupart des plateformes de calcul haute performance permettent (et parfois exigent) que vous spécifiiez certains paramètres d'allocation de ressources tels que le nombre de CPU et la mémoire. + +Par défaut, Nextflow utilisera un seul CPU et 2 Go de mémoire pour chaque process. +Les directives de process correspondantes sont appelées `cpus` et `memory`, donc la configuration suivante est implicite : + +```groovy title="Configuration intégrée" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Vous pouvez modifier ces valeurs, soit pour tous les processes, soit pour des processes nommés spécifiques, en utilisant des directives de process supplémentaires dans votre fichier de configuration. +Nextflow les traduira en instructions appropriées pour l'executor choisi. + +Mais comment savez-vous quelles valeurs utiliser ? + +### 5.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources + +??? example "Scénario" + + Vous ne savez pas combien de mémoire ou de CPU vos processes ont besoin et voulez éviter de gaspiller des ressources ou d'avoir des jobs tués. + +Si vous ne savez pas à l'avance combien de CPU et de mémoire vos processes sont susceptibles d'avoir besoin, vous pouvez faire du profilage de ressources, ce qui signifie que vous exécutez le workflow avec quelques allocations par défaut, enregistrez combien chaque process a utilisé, et à partir de là, estimez comment ajuster les allocations de base. + +Commodément, Nextflow inclut des outils intégrés pour faire cela, et générera volontiers un rapport pour vous sur demande. + +Pour ce faire, ajoutez `-with-report <filename>.html` à votre ligne de commande. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Le rapport est un fichier html, que vous pouvez télécharger et ouvrir dans votre navigateur. Vous pouvez également faire un clic droit dessus dans l'explorateur de fichiers à gauche et cliquer sur `Show preview` pour le voir dans l'environnement de formation. + +Prenez quelques minutes pour parcourir le rapport et voir si vous pouvez identifier des opportunités d'ajustement des ressources. +Assurez-vous de cliquer sur les onglets qui montrent les résultats d'utilisation en pourcentage de ce qui a été alloué. +Il y a de la [documentation](https://www.nextflow.io/docs/latest/reports.html) décrivant toutes les fonctionnalités disponibles. + +### 5.2. Définir les allocations de ressources pour tous les processes + +Le profilage montre que les processes de notre workflow de formation sont très légers, alors réduisons l'allocation de mémoire par défaut à 1 Go par process. + +Ajoutez ce qui suit à votre fichier `nextflow.config`, avant la section des paramètres du pipeline : + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Cela aidera à réduire la quantité de calcul que nous consommons. + +### 5.3. Définir les allocations de ressources pour un process spécifique + +En même temps, nous allons prétendre que le process `cowpy` nécessite plus de ressources que les autres, juste pour que nous puissions démontrer comment ajuster les allocations pour un process individuel. + +=== "Après" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Avant" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Avec cette configuration, tous les processes demanderont 1 Go de mémoire et un seul CPU (la valeur par défaut implicite), sauf le process `cowpy`, qui demandera 2 Go et 2 CPU. + +!!! info "Information" + + Si vous avez une machine avec peu de CPU et que vous en allouez un grand nombre par process, vous pourriez voir des appels de process mis en file d'attente les uns derrière les autres. + C'est parce que Nextflow s'assure que nous ne demandons pas plus de CPU qu'il n'y en a de disponibles. + +### 5.4. Exécuter le workflow avec la configuration mise à jour + +Essayons cela, en fournissant un nom de fichier différent pour le rapport de profilage afin de pouvoir comparer les performances avant et après les modifications de configuration. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Vous ne remarquerez probablement pas de différence réelle puisque c'est une charge de travail si petite, mais c'est l'approche que vous utiliseriez pour analyser les performances et les besoins en ressources d'un workflow du monde réel. + +C'est très utile lorsque vos processes ont des besoins en ressources différents. Cela vous permet de dimensionner correctement les allocations de ressources que vous définissez pour chaque process en fonction de données réelles, pas de suppositions. + +!!! tip "Astuce" + + Ceci n'est qu'un petit aperçu de ce que vous pouvez faire pour optimiser votre utilisation des ressources. + Nextflow lui-même a une [logique de réessai dynamique](https://training.nextflow.io/basic_training/debugging/#dynamic-resources-allocation) vraiment intéressante intégrée pour réessayer les jobs qui échouent en raison de limitations de ressources. + De plus, la plateforme Seqera offre des outils pilotés par l'IA pour optimiser vos allocations de ressources automatiquement également. + +### 5.5. Ajouter des limites de ressources + +Selon l'executor de calcul et l'infrastructure de calcul que vous utilisez, il peut y avoir des contraintes sur ce que vous pouvez (ou devez) allouer. +Par exemple, votre cluster peut exiger que vous restiez dans certaines limites. + +Vous pouvez utiliser la directive `resourceLimits` pour définir les limitations pertinentes. La syntaxe ressemble à ceci quand elle est seule dans un bloc process : + +```groovy title="Exemple de syntaxe" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow traduira ces valeurs en instructions appropriées selon l'executor que vous avez spécifié. + +Nous n'allons pas exécuter cela, puisque nous n'avons pas accès à l'infrastructure pertinente dans l'environnement de formation. +Cependant, si vous deviez essayer d'exécuter le workflow avec des allocations de ressources qui dépassent ces limites, puis rechercher la commande `sbatch` dans le fichier de script `.command.run`, vous verriez que les demandes qui sont réellement envoyées à l'executor sont plafonnées aux valeurs spécifiées par `resourceLimits`. + +??? info "Configurations de référence institutionnelles" + + Le projet nf-core a compilé une [collection de fichiers de configuration](https://nf-co.re/configs/) partagés par diverses institutions à travers le monde, couvrant une large gamme d'executors HPC et cloud. + + Ces configurations partagées sont précieuses à la fois pour les personnes qui y travaillent et peuvent donc simplement utiliser la configuration de leur institution immédiatement, et comme modèle pour les personnes qui cherchent à développer une configuration pour leur propre infrastructure. + +### Récapitulatif + +Vous savez comment générer un rapport de profilage pour évaluer l'utilisation des ressources et comment modifier les allocations de ressources pour tous les processes et/ou pour des processes individuels, ainsi que définir des limitations de ressources pour l'exécution sur HPC. + +### Et ensuite ? + +Apprenez à configurer des profils de configuration prédéfinis et à basculer entre eux au moment de l'exécution. + +--- + +## 6. Utiliser des profils pour basculer entre des configurations prédéfinies + +??? example "Scénario" + + Vous basculez régulièrement entre l'exécution de pipelines sur votre ordinateur portable pour le développement et sur le HPC de votre institution pour les exécutions de production. + Vous en avez assez de changer manuellement les paramètres de configuration chaque fois que vous changez d'environnement. + +Nous vous avons montré un certain nombre de façons de personnaliser la configuration de votre pipeline selon le projet sur lequel vous travaillez ou l'environnement de calcul que vous utilisez. + +Vous pourriez vouloir basculer entre des paramètres alternatifs selon l'infrastructure de calcul que vous utilisez. Par exemple, vous pourriez vouloir développer et exécuter des tests à petite échelle localement sur votre ordinateur portable, puis exécuter des charges de travail à grande échelle sur HPC ou cloud. + +Nextflow vous permet de configurer n'importe quel nombre de profils qui décrivent différentes configurations, que vous pouvez ensuite sélectionner au moment de l'exécution en utilisant un argument de ligne de commande, plutôt que d'avoir à modifier le fichier de configuration lui-même. + +### 6.1. Créer des profils pour basculer entre le développement local et l'exécution sur HPC + +Configurons deux profils alternatifs ; un pour exécuter des charges à petite échelle sur un ordinateur ordinaire, où nous utiliserons des conteneurs Docker, et un pour exécuter sur un HPC universitaire avec un ordonnanceur Slurm, où nous utiliserons des packages Conda. + +#### 6.1.1. Configurer les profils + +Ajoutez ce qui suit à votre fichier `nextflow.config`, après la section des paramètres du pipeline mais avant les paramètres de sortie : + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Vous voyez que pour le HPC universitaire, nous spécifions également des limitations de ressources. + +#### 6.1.2. Exécuter le workflow avec un profil + +Pour spécifier un profil dans notre ligne de commande Nextflow, nous utilisons l'argument `-profile`. + +Essayons d'exécuter le workflow avec la configuration `my_laptop`. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Comme vous pouvez le voir, cela nous permet de basculer entre les configurations très commodément au moment de l'exécution. + +!!! warning "Avertissement" + + Le profil `univ_hpc` ne fonctionnera pas correctement dans l'environnement de formation puisque nous n'avons pas accès à un ordonnanceur Slurm. + +Si à l'avenir nous trouvons d'autres éléments de configuration qui sont toujours co-occurrents avec ceux-ci, nous pouvons simplement les ajouter au(x) profil(s) correspondant(s). +Nous pouvons également créer des profils supplémentaires s'il y a d'autres éléments de configuration que nous voulons regrouper. + +### 6.2. Créer un profil de paramètres de test + +??? example "Scénario" + + Vous voulez que d'autres puissent essayer rapidement votre pipeline sans avoir à rassembler leurs propres données d'entrée. + +Les profils ne sont pas seulement pour la configuration d'infrastructure. +Nous pouvons également les utiliser pour définir des valeurs par défaut pour les paramètres du workflow, pour faciliter aux autres l'essai du workflow sans avoir à rassembler eux-mêmes des valeurs d'entrée appropriées. +Vous pouvez considérer cela comme une alternative à l'utilisation d'un fichier de paramètres. + +#### 6.2.1. Configurer le profil + +La syntaxe pour exprimer les valeurs par défaut dans ce contexte ressemble à ceci, pour un profil que nous nommons `test` : + +```groovy title="Exemple de syntaxe" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Si nous ajoutons un profil de test pour notre workflow, le bloc `profiles` devient : + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Tout comme pour les profils de configuration technique, vous pouvez configurer plusieurs profils différents spécifiant des paramètres sous n'importe quel nom arbitraire que vous aimez. + +#### 6.2.2. Exécuter le workflow localement avec le profil de test + +Commodément, les profils ne sont pas mutuellement exclusifs, donc nous pouvons spécifier plusieurs profils dans notre ligne de commande en utilisant la syntaxe suivante `-profile <profile1>,<profile2>` (pour n'importe quel nombre de profils). + +Si vous combinez des profils qui définissent des valeurs pour les mêmes éléments de configuration et sont décrits dans le même fichier de configuration, Nextflow résoudra le conflit en utilisant la valeur qu'il a lue en dernier (_c.-à-d._ ce qui vient plus tard dans le fichier). +Si les paramètres en conflit sont définis dans différentes sources de configuration, l'[ordre de priorité](https://www.nextflow.io/docs/latest/config.html) par défaut s'applique. + +Essayons d'ajouter le profil de test à notre commande précédente : + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Cela utilisera Docker où possible et produira des sorties sous `results/test`, et cette fois le personnage est le duo comique `dragonandcow`. + +??? abstract "Contenu du fichier" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Cela signifie que tant que nous distribuons tous les fichiers de données de test avec le code du workflow, n'importe qui peut rapidement essayer le workflow sans avoir à fournir ses propres entrées via la ligne de commande ou un fichier de paramètres. + +!!! tip "Astuce" + + Nous pouvons pointer vers des URL pour des fichiers plus grands qui sont stockés en externe. + Nextflow les téléchargera automatiquement tant qu'il y a une connexion ouverte. + + Pour plus de détails, consultez le Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Utiliser `nextflow config` pour voir la configuration résolue + +Comme noté ci-dessus, parfois le même paramètre peut être défini sur différentes valeurs dans des profils que vous voulez combiner. +Et plus généralement, il y a de nombreux endroits où des éléments de configuration peuvent être stockés, et parfois les mêmes propriétés peuvent être définies sur différentes valeurs à différents endroits. + +Nextflow applique un [ordre de priorité](https://www.nextflow.io/docs/latest/config.html) défini pour résoudre les conflits, mais cela peut être difficile à déterminer vous-même. +Et même si rien n'est en conflit, il peut être fastidieux de rechercher tous les endroits possibles où les choses pourraient être configurées. + +Heureusement, Nextflow inclut un outil utilitaire pratique appelé `config` qui peut automatiser tout ce processus pour vous. + +L'outil `config` explorera tout le contenu de votre répertoire de travail actuel, aspirera tous les fichiers de configuration, et produira la configuration entièrement résolue que Nextflow utiliserait pour exécuter le workflow. +Cela vous permet de découvrir quels paramètres seront utilisés sans avoir à lancer quoi que ce soit. + +#### 6.3.1. Résoudre la configuration par défaut + +Exécutez cette commande pour résoudre la configuration qui serait appliquée par défaut. + +```bash +nextflow config +``` + +??? success "Sortie de la commande" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Cela vous montre la configuration de base que vous obtenez si vous ne spécifiez rien de supplémentaire dans la ligne de commande. + +#### 6.3.2. Résoudre la configuration avec des paramètres spécifiques activés + +Si vous fournissez des paramètres de ligne de commande, par exemple en activant un ou plusieurs profils ou en chargeant un fichier de paramètres, la commande les prendra également en compte. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Sortie de la commande" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'data/greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Cela devient particulièrement utile pour les projets complexes qui impliquent plusieurs couches de configuration. + +### Récapitulatif + +Vous savez comment utiliser les profils pour sélectionner une configuration prédéfinie au moment de l'exécution avec un minimum de tracas. +Plus généralement, vous savez comment configurer vos exécutions de workflow pour convenir à différentes plateformes de calcul et améliorer la reproductibilité de vos analyses. + +### Et ensuite ? + +Apprenez à exécuter des pipelines directement depuis des dépôts distants comme GitHub. + +--- + +## 7. Exécuter des pipelines depuis des dépôts distants + +??? example "Scénario" + + Vous voulez exécuter un pipeline bien établi comme ceux de nf-core sans avoir à télécharger et gérer le code vous-même. + +Jusqu'à présent, nous avons exécuté des scripts de workflow situés dans le répertoire actuel. +En pratique, vous voudrez souvent exécuter des pipelines stockés dans des dépôts distants, tels que GitHub. + +Nextflow rend cela simple : vous pouvez exécuter n'importe quel pipeline directement depuis une URL de dépôt Git sans avoir à le télécharger manuellement d'abord. + +### 7.1. Exécuter un pipeline depuis GitHub + +La syntaxe de base pour exécuter un pipeline distant est `nextflow run <repository>`, où `<repository>` peut être un chemin de dépôt GitHub comme `nextflow-io/hello`, une URL complète, ou un chemin vers GitLab, Bitbucket, ou d'autres services d'hébergement Git. + +Essayez d'exécuter le pipeline de démonstration officiel Nextflow « hello » : + +```bash +nextflow run nextflow-io/hello +``` + +La première fois que vous exécutez un pipeline distant, Nextflow le télécharge et le met en cache localement. +Les exécutions suivantes utilisent la version mise en cache à moins que vous ne demandiez explicitement une mise à jour. + +### 7.2. Spécifier une version pour la reproductibilité + +Par défaut, Nextflow exécute la dernière version de la branche par défaut. +Vous pouvez spécifier une version particulière, une branche ou un commit en utilisant le drapeau `-r` : + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Spécifier des versions exactes est essentiel pour la reproductibilité. + +### Récapitulatif + +Vous savez comment exécuter des pipelines directement depuis GitHub et d'autres dépôts distants, et comment spécifier des versions pour la reproductibilité. + +### Et ensuite ? + +Félicitez-vous bien ! +Vous savez tout ce que vous devez savoir pour commencer à exécuter et gérer des pipelines Nextflow. + +Cela conclut cette formation, mais si vous êtes impatient de continuer à apprendre, nous avons deux recommandations principales : + +- Si vous voulez approfondir le développement de vos propres pipelines, consultez [Hello Nextflow](../hello_nextflow/index.md), une formation pour débutants qui couvre la même progression générale que celle-ci mais va beaucoup plus en détail sur les channels et les opérateurs. +- Si vous souhaitez continuer à apprendre comment exécuter des pipelines Nextflow sans aller plus profondément dans le code, consultez la première partie de [Hello nf-core](../hello_nf-core/index.md), qui introduit les outils pour trouver et exécuter des pipelines du projet très populaire [nf-core](https://nf-co.re/). + +Amusez-vous bien ! + +--- + +## Quiz + +<quiz> +Lorsque des valeurs de paramètres sont définies à la fois dans le fichier du workflow et dans `nextflow.config`, laquelle prévaut ? +- [ ] La valeur du fichier du workflow +- [x] La valeur du fichier de configuration +- [ ] La première valeur rencontrée +- [ ] Cela provoque une erreur + +En savoir plus : [1.1. Configurer des valeurs dans `nextflow.config`](#11-configurer-des-valeurs-dans-nextflowconfig) +</quiz> + +<quiz> +Quelle est la différence de syntaxe entre définir une valeur par défaut de paramètre dans un fichier de workflow vs. un fichier de config ? +- [ ] Ils utilisent la même syntaxe +- [x] Le workflow utilise une déclaration typée (`#!groovy param: Type = value`), la config utilise une affectation (`#!groovy param = value`) +- [ ] La config utilise une déclaration typée, le workflow utilise une affectation +- [ ] Seuls les fichiers de config peuvent définir des valeurs par défaut + +En savoir plus : [1.1. Configurer des valeurs dans `nextflow.config`](#11-configurer-des-valeurs-dans-nextflowconfig) +</quiz> + +<quiz> +Comment spécifiez-vous un fichier de paramètres lors de l'exécution d'un workflow ? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +En savoir plus : [1.3. Utiliser un fichier de paramètres](#13-utiliser-un-fichier-de-parametres) +</quiz> + +<quiz> +Que contrôle l'option de configuration `outputDir` ? +- [ ] L'emplacement du répertoire de travail +- [x] Le chemin de base où les sorties du workflow sont publiées +- [ ] Le répertoire pour les fichiers de log +- [ ] L'emplacement des fichiers de module + +En savoir plus : [2.1. Personnaliser le nom du répertoire outputDir](#21-personnaliser-le-nom-du-repertoire-outputdir) +</quiz> + +<quiz> +Comment référencez-vous dynamiquement un nom de process dans la configuration du chemin de sortie ? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +En savoir plus : [2.2. Organiser les sorties par process](#22-organiser-les-sorties-par-process) +</quiz> + +<quiz> +Si Docker et Conda sont tous deux activés et qu'un process a les deux directives, lequel est priorisé ? +- [x] Docker (conteneurs) +- [ ] Conda +- [ ] Le premier défini dans le process +- [ ] Cela provoque une erreur + +En savoir plus : [3. Sélectionner une technologie d'empaquetage logiciel](#3-selectionner-une-technologie-dempaquetage-logiciel) +</quiz> + +<quiz> +Quel est l'executor par défaut dans Nextflow ? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +En savoir plus : [4. Sélectionner une plateforme d'exécution](#4-selectionner-une-plateforme-dexecution) +</quiz> + +<quiz> +Quelle commande génère un rapport d'utilisation des ressources ? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +En savoir plus : [5.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources](#51-executer-le-workflow-pour-generer-un-rapport-dutilisation-des-ressources) +</quiz> + +<quiz> +Comment définissez-vous les exigences de ressources pour un process spécifique nommé `cowpy` dans le fichier de config ? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +En savoir plus : [5.3. Définir les allocations de ressources pour un process spécifique](#53-definir-les-allocations-de-ressources-pour-un-process-specifique) +</quiz> + +<quiz> +Que fait la directive `resourceLimits` ? +- [ ] Définit les exigences minimales de ressources +- [ ] Alloue des ressources aux processes +- [x] Plafonne les ressources maximales qui peuvent être demandées +- [ ] Surveille l'utilisation des ressources en temps réel + +En savoir plus : [5.5. Ajouter des limites de ressources](#55-ajouter-des-limites-de-ressources) +</quiz> + +<quiz> +Comment spécifiez-vous plusieurs profils dans une seule commande ? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +En savoir plus : [6. Utiliser des profils pour basculer entre des configurations prédéfinies](#6-utiliser-des-profils-pour-basculer-entre-des-configurations-predefinies) +</quiz> + +<quiz> +Quelle commande affiche la configuration entièrement résolue que Nextflow utiliserait ? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +En savoir plus : [6.3. Utiliser `nextflow config` pour voir la configuration résolue](#63-utiliser-nextflow-config-pour-voir-la-configuration-resolue) +</quiz> + +<quiz> +À quoi peuvent servir les profils ? (Sélectionnez toutes les réponses applicables) +- [x] Définir des paramètres spécifiques à l'infrastructure (executors, conteneurs) +- [x] Définir des limites de ressources pour différents environnements +- [x] Fournir des paramètres de test pour faciliter le test du workflow +- [ ] Définir de nouveaux processes + +En savoir plus : [6. Utiliser des profils pour basculer entre des configurations prédéfinies](#6-utiliser-des-profils-pour-basculer-entre-des-configurations-predefinies) +</quiz> diff --git a/docs/fr/docs/nextflow_run/index.md b/docs/fr/docs/nextflow_run/index.md new file mode 100644 index 0000000000..671ca62a06 --- /dev/null +++ b/docs/fr/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Lancer et gérer l'exécution de workflows Nextflow + - Trouver et interpréter les sorties (résultats) et les fichiers de log + - Reconnaître les composants principaux de Nextflow dans un workflow multi-étapes simple + - Configurer l'exécution d'un pipeline pour fonctionner sur des plateformes de calcul courantes, y compris HPC et cloud + - Résumer les bonnes pratiques pour la reproductibilité, la portabilité et la réutilisation du code qui rendent les pipelines FAIR, y compris la modularité du code et les conteneurs logiciels + audience_prerequisites: + - "**Public :** Cette formation est conçue pour les apprenants qui sont complètement nouveaux avec Nextflow et souhaitent exécuter des pipelines existants." + - "**Compétences :** Une certaine familiarité avec la ligne de commande, les concepts de base du scripting et les formats de fichiers courants est supposée." + - "**Domaine :** Les exercices sont tous indépendants du domaine, donc aucune connaissance scientifique préalable n'est requise." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run est une introduction pratique à l'exécution de workflows d'analyse de données reproductibles et évolutifs.** + +En travaillant sur des exemples pratiques et des exercices guidés, vous apprendrez les fondamentaux de l'utilisation de Nextflow, notamment comment exécuter des pipelines, gérer les fichiers et les dépendances logicielles, paralléliser l'exécution sans effort, et exécuter des workflows dans différents environnements de calcul. + +Vous en retirerez les compétences et la confiance pour commencer à exécuter des workflows avec Nextflow. + +<!-- additional_information --> + +## Aperçu de la formation + +### Ce que vous allez faire + +Cette formation est pratique, avec des exercices orientés vers des objectifs structurés pour introduire les informations progressivement. + +Vous exécuterez plusieurs versions d'un pipeline Nextflow qui traite des entrées de texte. +Vous commencerez par une version simple constituée d'une seule étape, et progresserez éventuellement vers une version multi-étapes qui prend un fichier CSV de données textuelles tabulaires, exécute quelques étapes de transformation, et produit un seul fichier texte contenant une image ASCII d'un personnage disant le texte transformé. + +Cette formation se concentre sur l'exécution de pipelines (nommée d'après la commande principale `nextflow run`). +Si vous cherchez une introduction au développement de pipelines Nextflow, consultez [Hello Nextflow](../hello_nextflow/index.md). + +### Plan de la formation + +Nous avons divisé cela en trois parties qui se concentreront chacune sur des aspects spécifiques de l'exécution et de la gestion des pipelines écrits en Nextflow. + +| Chapitre de la formation | Résumé | Durée estimée | +| ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| [Partie 1 : Exécuter les opérations de base](./01_basics.md) | Lancer et gérer l'exécution d'un workflow simple | 30 mins | +| [Partie 2 : Exécuter de vrais pipelines](./02_pipeline.md) | Traiter des entrées complexes, exécuter des workflows multi-étapes, utiliser des conteneurs et paralléliser l'exécution sans effort | 60 mins | +| [Partie 3 : Configuration d'exécution](./03_config.md) | Personnaliser le comportement du pipeline et optimiser l'utilisation dans différents environnements de calcul | 60 mins | + +À la fin de cette formation, vous serez bien préparé pour aborder les prochaines étapes de votre parcours pour exécuter des workflows reproductibles pour vos besoins de calcul scientifique. + +Prêt à suivre la formation ? + +[Commencer l'apprentissage :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/fr/docs/nextflow_run/next_steps.md b/docs/fr/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..aa4bdaa875 --- /dev/null +++ b/docs/fr/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Résumé de la formation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations pour avoir terminé la formation Nextflow Run ! + +<!-- placeholder for video --> + +## Votre parcours + +Vous avez commencé avec un workflow très basique, et avez appris à l'exécuter, trouver les sorties, et gérer son exécution. +Ensuite, vous avez travaillé à travers des versions de plus en plus complexes de ce workflow et avez appris à reconnaître les concepts et mécanismes essentiels qui alimentent les pipelines Nextflow, y compris les channels et les opérateurs, la modularisation du code, et les conteneurs. +Enfin, vous avez appris à personnaliser la configuration d'un pipeline pour s'adapter à vos préférences et à votre infrastructure de calcul. + +### Ce que vous avez appris + +Vous êtes maintenant capable de gérer l'exécution du pipeline Hello, de décrire comment il est structuré, et d'identifier les principales parties du code impliquées. + +- La forme finale du workflow Hello prend en entrée un fichier CSV contenant des salutations textuelles. +- Les quatre étapes sont implémentées comme des processes Nextflow (`sayHello`, `convertToUpper`, `collectGreetings`, et `cowpy`) stockés dans des fichiers de module séparés. +- Les résultats sont publiés dans un répertoire appelé `results/`. +- La sortie finale du pipeline est un fichier texte brut contenant de l'art ASCII d'un personnage disant les salutations en majuscules. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello` :** Écrit chaque salutation dans son propre fichier de sortie (par exemple « Hello-output.txt ») +2. **`convertToUpper` :** Convertit chaque salutation en majuscules (par exemple « HELLO ») +3. **`collectGreetings` :** Collecte toutes les salutations en majuscules dans un seul fichier de lot +4. **`cowpy` :** Génère de l'art ASCII en utilisant l'outil `cowpy` + +La configuration du workflow prend en charge la fourniture d'entrées et de paramètres de manière flexible et reproductible. + +### Compétences acquises + +À travers cette formation pratique, vous avez appris à : + +- Lancer un workflow Nextflow localement +- Trouver et interpréter les sorties (résultats) et les fichiers de log générés par Nextflow +- Reconnaître les composants principaux de Nextflow qui constituent un workflow multi-étapes simple +- Décrire des concepts avancés tels que les opérateurs et les fabriques de channel +- Configurer des pipelines pour différents environnements de calcul + +Vous êtes maintenant équipé des connaissances fondamentales pour commencer à intégrer des pipelines Nextflow existants dans votre propre travail. + +## Prochaines étapes pour développer vos compétences + +Voici nos principales suggestions pour la suite : + +- Ne vous contentez pas d'exécuter Nextflow, écrivez-le ! Devenez un développeur Nextflow avec [Hello Nextflow](../hello_nextflow/index.md) +- Appliquez Nextflow à un cas d'utilisation d'analyse scientifique avec [Nextflow for Science](../nf4_science/index.md) +- Commencez avec nf-core avec [Hello nf-core](../hello_nf-core/index.md) +- Apprenez les techniques de dépannage avec le [Debugging Side Quest](../side_quests/debugging.md) + +Enfin, nous vous recommandons de jeter un œil à [**Seqera Platform**](https://seqera.io/), une plateforme basée sur le cloud développée par les créateurs de Nextflow qui facilite encore plus le lancement et la gestion de vos workflows, ainsi que la gestion de vos données et l'exécution d'analyses de manière interactive dans n'importe quel environnement. + +## Obtenir de l'aide + +Pour les ressources d'aide et le support communautaire, consultez la [page d'aide](../help.md). + +## Enquête de satisfaction + +Avant de passer à autre chose, veuillez prendre une minute pour compléter l'enquête de la formation ! Vos retours nous aident à améliorer nos supports de formation pour tout le monde. + +[Répondre à l'enquête :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/fr/docs/nextflow_run/survey.md b/docs/fr/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..cebbb2a93f --- /dev/null +++ b/docs/fr/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Enquête de satisfaction + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Avant de passer à autre chose, veuillez compléter cette courte enquête de 5 questions pour évaluer la formation, partager vos retours sur votre expérience, et nous faire savoir ce que nous pourrions faire d'autre pour vous aider dans votre parcours Nextflow. + +Cela devrait vous prendre moins d'une minute à compléter. Merci de nous aider à améliorer nos supports de formation pour tout le monde ! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/fr/docs/nf4_science/genomics/00_orientation.md b/docs/fr/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..d1fc3633ea --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'environnement de formation contient tous les logiciels, le code et les données nécessaires pour suivre cette formation, vous n'avez donc rien à installer vous-même. +Cependant, vous avez besoin d'un compte (gratuit) pour vous connecter, et vous devriez prendre quelques minutes pour vous familiariser avec l'interface. + +Si vous ne l'avez pas encore fait, veuillez suivre [ce lien](../../../envsetup/) avant de continuer. + +## Matériel fourni + +Tout au long de cette formation, nous travaillerons dans le répertoire `nf4-science/genomics/`, dans lequel vous devez vous déplacer lorsque vous ouvrez l'espace de travail de formation. +Ce répertoire contient tous les fichiers de code, les données de test et les fichiers accessoires dont vous aurez besoin. + +N'hésitez pas à explorer le contenu de ce répertoire ; le moyen le plus simple est d'utiliser l'explorateur de fichiers sur le côté gauche de l'espace de travail de formation dans l'interface VSCode. +Vous pouvez également utiliser la commande `tree`. +Tout au long de la formation, nous utilisons la sortie de `tree` pour représenter la structure et le contenu des répertoires sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 2 +``` + +Si vous exécutez cette commande à l'intérieur de `nf4-science/genomics`, vous devriez voir la sortie suivante : + +```console title="Contenu du répertoire" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note + + Ne vous inquiétez pas si cela semble beaucoup ; nous passerons en revue les éléments pertinents à chaque étape de la formation. + Ceci est juste destiné à vous donner un aperçu. + +**Voici un résumé de ce que vous devez savoir pour commencer :** + +- **Les fichiers `.nf`** sont des scripts de workflow nommés en fonction de la partie de la formation dans laquelle ils sont utilisés. + +- **Le fichier `nextflow.config`** est un fichier de configuration qui définit des propriétés minimales de l'environnement. + Vous pouvez l'ignorer pour l'instant. + +- **Le répertoire `data`** contient les données d'entrée et les ressources associées, décrites plus tard dans la formation. + +- **Le répertoire `solutions`** contient les fichiers de modules et les configurations de tests qui résultent des parties 3 et 4 de la formation. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre tout problème. + +!!!tip + + Si pour une raison quelconque vous sortez de ce répertoire, vous pouvez toujours exécuter cette commande pour y revenir : + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Maintenant, pour commencer la formation, cliquez sur la flèche dans le coin inférieur droit de cette page. diff --git a/docs/fr/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/fr/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..ecbc9e98e4 --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1054 @@ +# Partie 1 : Appel de variants par échantillon + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la première partie de ce cours, nous vous montrons comment construire un pipeline simple d'appel de variants qui applique l'appel de variants GATK à des échantillons de séquençage individuels. + +### Vue d'ensemble de la méthode + +L'appel de variants est une méthode d'analyse génomique qui vise à identifier les variations dans une séquence génomique par rapport à un génome de référence. +Ici, nous allons utiliser des outils et des méthodes conçus pour appeler les variants courts, _c'est-à-dire_ les SNP et les indels. + +![Pipeline GATK](img/gatk-pipeline.png) + +Un pipeline complet d'appel de variants implique généralement de nombreuses étapes, y compris le mapping sur la référence (parfois appelé alignement du génome) et le filtrage et la priorisation des variants. +Pour simplifier, dans cette partie du cours, nous allons nous concentrer uniquement sur la partie appel de variants. + +### Jeu de données + +Nous fournissons les données et ressources suivantes : + +- **Un génome de référence** constitué d'une petite région du chromosome 20 humain (de hg19/b37) et ses fichiers accessoires (index et dictionnaire de séquence). +- **Trois échantillons de séquençage du génome entier** correspondant à un trio familial (mère, père et fils), qui ont été réduits à une petite tranche de données sur le chromosome 20 pour maintenir la taille des fichiers petite. + Il s'agit de données de séquençage Illumina à lectures courtes qui ont déjà été mappées sur le génome de référence, fournies au format [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) (Binary Alignment Map, une version compressée de SAM, Sequence Alignment Map). +- **Une liste d'intervalles génomiques**, c'est-à-dire des coordonnées sur le génome où nos échantillons ont des données appropriées pour appeler des variants, fournie au format BED. + +### Workflow + +Dans cette partie du cours, nous allons développer un workflow qui effectue les opérations suivantes : + +1. Générer un fichier d'index pour chaque fichier BAM d'entrée en utilisant [Samtools](https://www.htslib.org/) +2. Exécuter GATK HaplotypeCaller sur chaque fichier BAM d'entrée pour générer des appels de variants par échantillon au format VCF (Variant Call Format) + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note + + Les fichiers d'index sont une caractéristique courante des formats de fichiers bioinformatiques ; ils contiennent des informations sur la structure du fichier principal qui permettent à des outils comme GATK d'accéder à un sous-ensemble des données sans avoir à lire l'intégralité du fichier. + C'est important en raison de la taille que peuvent atteindre ces fichiers. + +--- + +## 0. Échauffement : Tester les commandes Samtools et GATK de manière interactive + +Nous voulons d'abord essayer les commandes manuellement avant de tenter de les intégrer dans un workflow. +Les outils dont nous avons besoin (Samtools et GATK) ne sont pas installés dans l'environnement GitHub Codespaces, nous allons donc les utiliser via des conteneurs (voir [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note + + Assurez-vous d'être dans le répertoire `nf4-science/genomics` de sorte que la dernière partie du chemin affiché lorsque vous tapez `pwd` soit `genomics`. + +### 0.1. Indexer un fichier BAM d'entrée avec Samtools + +Nous allons télécharger un conteneur Samtools, le démarrer de manière interactive et exécuter la commande `samtools index` sur l'un des fichiers BAM. + +#### 0.1.1. Télécharger le conteneur Samtools + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.1.2. Démarrer le conteneur Samtools de manière interactive + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.1.3. Exécuter la commande d'indexation + +La [documentation Samtools](https://www.htslib.org/doc/samtools-index.html) nous donne la ligne de commande à exécuter pour indexer un fichier BAM. + +Nous devons seulement fournir le fichier d'entrée ; l'outil générera automatiquement un nom pour la sortie en ajoutant `.bai` au nom du fichier d'entrée. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Cela devrait se terminer immédiatement, et vous devriez maintenant voir un fichier appelé `reads_mother.bam.bai` dans le même répertoire que le fichier BAM d'entrée original. + +??? abstract "Contenu du répertoire" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Quitter le conteneur Samtools + +```bash +exit +``` + +### 0.2. Appeler des variants avec GATK HaplotypeCaller + +Nous allons télécharger un conteneur GATK, le démarrer de manière interactive et exécuter la commande `gatk HaplotypeCaller` sur le fichier BAM que nous venons d'indexer. + +#### 0.2.1. Télécharger le conteneur GATK + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.2.2. Démarrer le conteneur GATK de manière interactive + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.2.3. Exécuter la commande d'appel de variants + +La [documentation GATK](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) nous donne la ligne de commande à exécuter pour effectuer l'appel de variants sur un fichier BAM. + +Nous devons fournir le fichier BAM d'entrée (`-I`) ainsi que le génome de référence (`-R`), un nom pour le fichier de sortie (`-O`) et une liste d'intervalles génomiques à analyser (`-L`). + +Cependant, nous n'avons pas besoin de spécifier le chemin vers le fichier d'index ; l'outil le recherchera automatiquement dans le même répertoire, en se basant sur la convention établie de nommage et de co-localisation. +Il en va de même pour les fichiers accessoires du génome de référence (fichiers d'index et de dictionnaire de séquence, `*.fai` et `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +Le fichier de sortie `reads_mother.vcf` est créé dans votre répertoire de travail dans le conteneur, vous ne le verrez donc pas dans l'explorateur de fichiers de VS Code à moins que vous ne changiez le chemin du fichier de sortie. +Cependant, c'est un petit fichier de test, vous pouvez donc utiliser `cat` pour l'ouvrir et afficher son contenu. +Si vous faites défiler jusqu'au début du fichier, vous trouverez un en-tête composé de nombreuses lignes de métadonnées, suivi d'une liste d'appels de variants, un par ligne. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Chaque ligne décrit un variant possible identifié dans les données de séquençage de l'échantillon. Pour obtenir des conseils sur l'interprétation du format VCF, consultez [cet article utile](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +Le fichier VCF de sortie est accompagné d'un fichier d'index appelé `reads_mother.vcf.idx` qui a été automatiquement créé par GATK. +Il a la même fonction que le fichier d'index BAM, permettre aux outils de rechercher et récupérer des sous-ensembles de données sans charger l'intégralité du fichier. + +#### 0.2.4. Quitter le conteneur GATK + +```bash +exit +``` + +### À retenir + +Vous savez comment tester les commandes d'indexation Samtools et d'appel de variants GATK dans leurs conteneurs respectifs. + +### Et ensuite ? + +Apprenez à intégrer ces mêmes commandes dans un workflow en deux étapes qui utilise des conteneurs pour exécuter le travail. + +--- + +## 1. Écrire un workflow à une seule étape qui exécute Samtools index sur un fichier BAM + +Nous vous fournissons un fichier de workflow, `genomics-1.nf`, qui décrit les parties principales du workflow. +Il n'est pas fonctionnel ; son objectif est simplement de servir de squelette que vous utiliserez pour écrire le workflow réel. + +### 1.1. Définir le processus d'indexation + +Commençons par écrire un processus, que nous appellerons `SAMTOOLS_INDEX`, décrivant l'opération d'indexation. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Générer le fichier d'index BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Vous devriez reconnaître tous les éléments de ce que vous avez appris dans la Partie 1 et la Partie 2 de cette série de formation. + +Ce processus va nécessiter que nous lui passions un chemin de fichier via l'entrée `input_bam`, configurons donc cela ensuite. + +### 1.2. Ajouter une déclaration de paramètre d'entrée + +En haut du fichier, sous la section `Pipeline parameters`, nous déclarons un paramètre CLI appelé `reads_bam` et lui donnons une valeur par défaut. +De cette façon, nous pouvons être paresseux et ne pas spécifier l'entrée lorsque nous tapons la commande pour lancer le pipeline (à des fins de développement). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Paramètres du pipeline + */ +params { + // Entrée principale + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Maintenant nous avons un processus prêt, ainsi qu'un paramètre pour lui donner une entrée sur laquelle s'exécuter, câblons donc ces éléments ensemble. + +!!! note + + `${projectDir}` est une variable Nextflow intégrée qui pointe vers le répertoire où se trouve le script de workflow Nextflow actuel (`genomics-1.nf`). + + Cela facilite le référencement des fichiers, des répertoires de données et d'autres ressources inclus dans le dépôt du workflow sans coder en dur des chemins absolus. + +### 1.3. Ajouter un bloc workflow pour exécuter SAMTOOLS_INDEX + +Dans le bloc `workflow`, nous devons configurer un **canal** pour alimenter l'entrée du processus `SAMTOOLS_INDEX` ; ensuite nous pouvons appeler le processus lui-même pour qu'il s'exécute sur le contenu de ce canal. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Créer le canal d'entrée (fichier unique via paramètre CLI) + reads_ch = channel.fromPath(params.reads_bam) + + // Créer le fichier d'index pour le fichier BAM d'entrée + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +Le bloc workflow a deux sections : + +- `main:` contient les opérations de canal et les appels de processus +- `publish:` déclare quelles sorties doivent être publiées, en les assignant à des cibles nommées + +Vous remarquerez que nous utilisons le même factory de canal `.fromPath` que nous avons utilisé dans [Hello Channels](../../hello_nextflow/02_hello_channels.md). +En effet, nous faisons quelque chose de très similaire. +La différence est que nous disons à Nextflow de simplement charger le chemin du fichier lui-même dans le canal en tant qu'élément d'entrée, plutôt que de lire son contenu. + +### 1.4. Ajouter un bloc output pour définir où les résultats sont publiés + +Après le bloc workflow, nous ajoutons un bloc `output` qui spécifie où publier les sorties du workflow. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Chaque cible nommée de la section `publish:` (comme `bam_index`) obtient son propre bloc où vous pouvez configurer le chemin de sortie relatif au répertoire de sortie de base. + +!!! note + + Même si les fichiers de données que nous utilisons ici sont très petits, en génomique ils peuvent devenir très volumineux. + Par défaut, Nextflow crée des liens symboliques vers les fichiers de sortie dans le répertoire de publication, ce qui évite les copies de fichiers inutiles. + Vous pouvez modifier ce comportement en utilisant l'option `mode` (par exemple, `mode 'copy'`) pour créer des copies réelles à la place. + Sachez que les liens symboliques seront rompus lorsque vous nettoierez votre répertoire `work`, donc pour les workflows de production vous voudrez peut-être utiliser `mode 'copy'`. + +### 1.5. Configurer le répertoire de sortie + +Le répertoire de sortie de base est défini via l'option de configuration `outputDir`. Ajoutez-la à `nextflow.config` : + +=== "Après" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Avant" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Exécuter le workflow pour vérifier que l'étape d'indexation fonctionne + +Exécutons le workflow ! Pour rappel, nous n'avons pas besoin de spécifier une entrée dans la ligne de commande car nous avons configuré une valeur par défaut pour l'entrée lors de la déclaration du paramètre d'entrée. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Vous pouvez vérifier que le fichier d'index a été généré correctement en regardant dans le répertoire de travail ou dans le répertoire des résultats. + +??? abstract "Contenu du répertoire de travail" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Contenu du répertoire des résultats" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +Le voilà ! + +### À retenir + +Vous savez comment intégrer un outil de génomique dans un workflow Nextflow à une seule étape et le faire fonctionner en utilisant un conteneur. + +### Et ensuite ? + +Ajouter une deuxième étape qui consomme la sortie de la première. + +--- + +## 2. Ajouter un deuxième processus pour exécuter GATK HaplotypeCaller sur le fichier BAM indexé + +Maintenant que nous avons un index pour notre fichier d'entrée, nous pouvons passer à la configuration de l'étape d'appel de variants, qui est la partie intéressante du workflow. + +### 2.1. Définir le processus d'appel de variants + +Écrivons un processus, que nous appellerons `GATK_HAPLOTYPECALLER`, décrivant l'opération d'appel de variants. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Appeler des variants avec GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Vous remarquerez que nous avons introduit une nouvelle syntaxe ici (`emit:`) pour nommer de manière unique chacun de nos canaux de sortie, et les raisons de cela deviendront claires bientôt. + +Cette commande prend pas mal plus d'entrées, car GATK a besoin de plus d'informations pour effectuer l'analyse par rapport à un simple travail d'indexation. +Mais vous noterez qu'il y a encore plus d'entrées définies dans le bloc d'entrées qu'il n'y en a listées dans la commande GATK. Pourquoi donc ? + +!!! note + + GATK sait rechercher le fichier d'index BAM et les fichiers accessoires du génome de référence car il connaît les conventions entourant ces fichiers. + Cependant, Nextflow est conçu pour être indépendant du domaine et ne sait rien des exigences des formats de fichiers bioinformatiques. + +Nous devons dire explicitement à Nextflow qu'il doit placer ces fichiers dans le répertoire de travail au moment de l'exécution ; sinon il ne le fera pas, et GATK lancera (à juste titre) une erreur concernant les fichiers d'index manquants. + +De même, nous devons lister explicitement le fichier d'index du VCF de sortie (le fichier `"${input_bam}.vcf.idx"`) pour que Nextflow sache garder la trace de ce fichier au cas où il serait nécessaire dans les étapes suivantes. + +### 2.2. Ajouter des définitions pour les entrées accessoires + +Puisque notre nouveau processus attend qu'un certain nombre de fichiers supplémentaires soient fournis, nous configurons des paramètres CLI pour eux sous la section `Pipeline parameters`, ainsi que quelques valeurs par défaut (pour les mêmes raisons qu'avant). + +```groovy title="genomics-1.nf" linenums="8" + // Fichiers accessoires + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Créer des variables pour contenir les chemins des fichiers accessoires + +Bien que les entrées de données principales soient diffusées dynamiquement à travers les canaux, il existe deux approches pour gérer les fichiers accessoires. L'approche recommandée consiste à créer des canaux explicites, ce qui rend le flux de données plus clair et plus cohérent. Alternativement, la fonction file() pour créer des variables peut être utilisée pour les cas plus simples, en particulier lorsque vous devez référencer le même fichier dans plusieurs processus - bien que sachez que cela crée toujours des canaux implicitement. <!-- TODO: Clarify: is this still necessary with typed inputs? --> + +Ajoutez ceci au bloc workflow (après la création de `reads_ch`, à l'intérieur de la section `main:`) : + +```groovy title="genomics-1.nf" linenums="79" + // Charger les chemins de fichiers pour les fichiers accessoires (référence et intervalles) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Cela rendra les chemins des fichiers accessoires disponibles pour être fournis en entrée à tous les processus qui en ont besoin. + +### 2.4. Ajouter un appel au bloc workflow pour exécuter GATK_HAPLOTYPECALLER + +Maintenant que nous avons configuré notre deuxième processus et que toutes les entrées et fichiers accessoires sont prêts et disponibles, nous pouvons ajouter un appel au processus `GATK_HAPLOTYPECALLER` dans le corps du workflow. + +```groovy title="genomics-1.nf" linenums="88" + // Appeler les variants depuis le fichier BAM indexé + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Vous devriez reconnaître la syntaxe `*.out` de la Partie 1 de cette série de formation ; nous disons à Nextflow de prendre le canal de sortie de `SAMTOOLS_INDEX` et de le brancher dans l'appel du processus `GATK_HAPLOTYPECALLER`. + +!!! note + + Vous remarquerez que les entrées sont fournies dans le même ordre exact dans l'appel au processus que celui dans lequel elles sont listées dans le bloc d'entrée du processus. + Dans Nextflow, les entrées sont positionnelles, ce qui signifie que vous _devez_ suivre le même ordre ; et bien sûr il doit y avoir le même nombre d'éléments. + +### 2.5. Mettre à jour la section publish et le bloc output + +Nous devons mettre à jour la section `publish:` pour inclure les sorties VCF, et ajouter les cibles correspondantes dans le bloc `output`. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Exécuter le workflow pour vérifier que l'étape d'appel de variants fonctionne + +Exécutons le workflow étendu avec `-resume` pour ne pas avoir à exécuter à nouveau l'étape d'indexation. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Maintenant si nous regardons la sortie de la console, nous voyons les deux processus listés. + +Le premier processus a été ignoré grâce à la mise en cache, comme prévu, tandis que le deuxième processus a été exécuté puisqu'il est tout nouveau. + +Vous trouverez les fichiers de sortie dans le répertoire des résultats (sous forme de liens symboliques vers le répertoire de travail). + +??? abstract "Contenu du répertoire" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Si vous ouvrez le fichier VCF, vous devriez voir le même contenu que dans le fichier que vous avez généré en exécutant la commande GATK directement dans le conteneur. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +C'est la sortie que nous voulons générer pour chaque échantillon dans notre étude. + +### À retenir + +Vous savez comment créer un workflow très basique à deux étapes qui effectue un véritable travail d'analyse et est capable de gérer les idiosyncrasies des formats de fichiers génomiques comme les fichiers accessoires. + +### Et ensuite ? + +Faire en sorte que le workflow gère plusieurs échantillons en masse. + +--- + +## 3. Adapter le workflow pour qu'il s'exécute sur un lot d'échantillons + +C'est bien d'avoir un workflow qui peut automatiser le traitement d'un seul échantillon, mais que se passe-t-il si vous avez 1000 échantillons ? +Devez-vous écrire un script bash qui boucle sur tous vos échantillons ? + +Non, Dieu merci ! Il suffit de faire une petite modification du code et Nextflow gérera cela pour vous aussi. + +### 3.1. Transformer la déclaration du paramètre d'entrée en un tableau listant les trois échantillons + +Transformons ce chemin de fichier par défaut dans la déclaration du fichier BAM d'entrée en un tableau listant les chemins de fichiers pour nos trois échantillons de test, sous la section `Pipeline parameters`. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrée principale (tableau de trois échantillons) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrée principale + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note + + Lors de l'utilisation de déclarations de paramètres typés (comme `reads_bam: Path`), vous ne pouvez pas assigner une valeur de tableau. + Pour les tableaux, omettez l'annotation de type. + +Et c'est en fait tout ce que nous devons faire, car le factory de canal que nous utilisons dans le corps du workflow (`.fromPath`) est tout aussi heureux d'accepter plusieurs chemins de fichiers à charger dans le canal d'entrée qu'il l'était d'en charger un seul. + +!!! note + + Normalement, vous ne voudriez pas coder en dur la liste des échantillons dans votre fichier de workflow, mais nous le faisons ici pour garder les choses simples. + Nous présenterons des façons plus élégantes de gérer les entrées plus tard dans cette série de formation. + +### 3.2. Exécuter le workflow pour vérifier qu'il s'exécute sur les trois échantillons + +Essayons maintenant d'exécuter le workflow maintenant que la plomberie est configurée pour s'exécuter sur les trois échantillons de test. + +```bash +nextflow run genomics-1.nf -resume +``` + +Chose amusante : cela _pourrait fonctionner_, OU cela _pourrait échouer_. Par exemple, voici une exécution qui a réussi : + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Si votre exécution de workflow a réussi, exécutez-la à nouveau jusqu'à ce que vous obteniez une erreur comme celle-ci : + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Si vous regardez la sortie d'erreur de la commande GATK, il y aura une ligne comme celle-ci : + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Eh bien, c'est étrange, considérant que nous avons explicitement indexé les fichiers BAM dans la première étape du workflow. Pourrait-il y avoir un problème avec la plomberie ? + +#### 3.2.1. Vérifier les répertoires de travail pour les appels pertinents + +Jetons un coup d'œil à l'intérieur du répertoire de travail pour l'appel de processus `GATK_HAPLOTYPECALLER` échoué listé dans la sortie de la console. + +??? abstract "Contenu du répertoire" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Portez une attention particulière aux noms du fichier BAM et de l'index BAM qui sont listés dans ce répertoire : `reads_son.bam` et `reads_father.bam.bai`. + +Qu'est-ce que c'est que ça ? Nextflow a placé un fichier d'index dans le répertoire de travail de cet appel de processus, mais c'est le mauvais. Comment cela a-t-il pu se produire ? + +#### 3.2.2. Utiliser l'opérateur [view()](https://www.nextflow.io/docs/latest/reference/operator.html#view) pour inspecter le contenu des canaux + +Ajoutez ces deux lignes dans le corps du workflow avant l'appel du processus `GATK_HAPLOTYPER` : + +```groovy title="genomics-1.nf" linenums="84" + // diagnostics temporaires + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Puis exécutez à nouveau la commande du workflow. + +```bash +nextflow run genomics-1.nf +``` + +Une fois encore, cela peut réussir ou échouer. Voici une exécution réussie : + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +Et voici une échouée : + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Vous devrez peut-être l'exécuter plusieurs fois pour qu'elle échoue à nouveau. +Cette erreur ne se reproduira pas systématiquement car elle dépend d'une certaine variabilité dans les temps d'exécution des appels de processus individuels. + +Voici à quoi ressemble la sortie des deux appels `.view()` que nous avons ajoutés pour une exécution échouée : + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +Les trois premières lignes correspondent au canal d'entrée et les secondes, au canal de sortie. +Vous pouvez voir que les fichiers BAM et les fichiers d'index pour les trois échantillons ne sont pas listés dans le même ordre ! + +!!! note + + Lorsque vous appelez un processus Nextflow sur un canal contenant plusieurs éléments, Nextflow essaiera de paralléliser l'exécution autant que possible, et collectera les sorties dans l'ordre dans lequel elles deviennent disponibles. + La conséquence est que les sorties correspondantes peuvent être collectées dans un ordre différent de celui dans lequel les entrées originales ont été fournies. + +Tel qu'il est écrit actuellement, notre script de workflow suppose que les fichiers d'index sortiront de l'étape d'indexation listés dans le même ordre mère/père/fils que les entrées ont été données. +Mais ce n'est pas garanti d'être le cas, c'est pourquoi parfois (mais pas toujours) les mauvais fichiers sont appariés dans la deuxième étape. + +Pour corriger cela, nous devons nous assurer que les fichiers BAM et leurs fichiers d'index voyagent ensemble à travers les canaux. + +!!! tip + + Les instructions `view()` dans le code du workflow ne font rien, donc ce n'est pas un problème de les laisser. + Cependant, elles encombrent votre sortie de console, nous recommandons donc de les supprimer lorsque vous avez fini de déboguer le problème. + +### 3.3. Changer la sortie du processus SAMTOOLS_INDEX en un tuple qui garde le fichier d'entrée et son index ensemble + +La façon la plus simple d'assurer qu'un fichier BAM et son index restent étroitement associés est de les emballer ensemble dans un tuple sortant de la tâche d'index. + +!!! note + + Un **tuple** est une liste ordonnée finie d'éléments qui est couramment utilisée pour retourner plusieurs valeurs d'une fonction. Les tuples sont particulièrement utiles pour passer plusieurs entrées ou sorties entre des processus tout en préservant leur association et leur ordre. + +Tout d'abord, changeons la sortie du processus `SAMTOOLS_INDEX` pour inclure le fichier BAM dans sa déclaration de sortie. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +De cette façon, chaque fichier d'index sera étroitement couplé avec son fichier BAM original, et la sortie globale de l'étape d'indexation sera un seul canal contenant des paires de fichiers. + +### 3.4. Changer l'entrée du processus GATK_HAPLOTYPECALLER en un tuple + +Puisque nous avons changé la « forme » de la sortie du premier processus dans le workflow, nous devons mettre à jour la définition d'entrée du deuxième processus pour correspondre. + +Spécifiquement, là où nous déclarions auparavant deux chemins d'entrée séparés dans le bloc d'entrée du processus `GATK_HAPLOTYPECALLER`, nous déclarons maintenant une seule entrée correspondant à la structure du tuple émis par `SAMTOOLS_INDEX`. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Bien sûr, puisque nous avons maintenant changé la forme des entrées que `GATK_HAPLOTYPECALLER` attend, nous devons mettre à jour l'appel du processus en conséquence dans le corps du workflow. + +### 3.5. Mettre à jour l'appel à GATK_HAPLOTYPECALLER dans le bloc workflow + +Nous n'avons plus besoin de fournir le `reads_ch` original au processus `GATK_HAPLOTYPECALLER`, puisque le fichier BAM est maintenant empaqueté dans le canal de sortie par `SAMTOOLS_INDEX`. + +En conséquence, nous pouvons simplement supprimer cette ligne. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +C'est tout le recâblage nécessaire pour résoudre le problème de non-correspondance des index. + +### 3.6. Mettre à jour la section publish et le bloc output pour le tuple + +Puisque `SAMTOOLS_INDEX.out` est maintenant un tuple contenant à la fois le BAM et son index, les deux fichiers seront publiés ensemble. +Nous renommons la cible de `bam_index` à `indexed_bam` pour refléter qu'elle contient maintenant les deux fichiers. + +=== "Après" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Nous devons également mettre à jour le bloc output pour utiliser le nouveau nom de cible : + +=== "Après" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Exécuter le workflow pour vérifier qu'il fonctionne correctement sur les trois échantillons à chaque fois + +Bien sûr, la preuve est dans le pudding, exécutons donc le workflow à nouveau quelques fois pour nous assurer que cela fonctionnera de manière fiable à l'avenir. + +```bash +nextflow run genomics-1.nf +``` + +Cette fois (et à chaque fois) tout devrait fonctionner correctement : + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Le répertoire des résultats contient maintenant à la fois les fichiers BAM et BAI pour chaque échantillon (du tuple), ainsi que les sorties VCF : + +??? abstract "Contenu du répertoire des résultats" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Si vous le souhaitez, vous pouvez utiliser `.view()` à nouveau pour jeter un coup d'œil au contenu du canal de sortie de `SAMTOOLS_INDEX` : + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Vous verrez que le canal contient les trois tuples attendus (chemins de fichiers tronqués pour la lisibilité). + +```console title="Sortie" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Ce sera beaucoup plus sûr, à l'avenir. + +### À retenir + +Vous savez comment faire en sorte que votre workflow s'exécute sur plusieurs échantillons (de manière indépendante). + +### Et ensuite ? + +Faciliter la gestion des échantillons en masse. + +--- + +## 4. Faire en sorte que le workflow accepte un fichier texte contenant un lot de fichiers d'entrée + +Une façon très courante de fournir plusieurs fichiers de données d'entrée à un workflow est de le faire avec un fichier texte contenant les chemins de fichiers. +Il peut être aussi simple qu'un fichier texte listant un chemin de fichier par ligne et rien d'autre, ou le fichier peut contenir des métadonnées supplémentaires, auquel cas il est souvent appelé samplesheet. + +Ici, nous allons vous montrer comment faire le cas simple. + +### 4.1. Examiner le fichier texte fourni listant les chemins de fichiers d'entrée + +Nous avons déjà créé un fichier texte listant les chemins de fichiers d'entrée, appelé `sample_bams.txt`, que vous pouvez trouver dans le répertoire `data/`. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Comme vous pouvez le voir, nous avons listé un chemin de fichier par ligne, et ce sont des chemins absolus. + +!!! note + + Les fichiers que nous utilisons ici sont simplement sur le système de fichiers local de votre GitHub Codespaces, mais nous pourrions également pointer vers des fichiers dans le stockage cloud. + +### 4.2. Mettre à jour la valeur par défaut du paramètre + +Changeons la valeur par défaut de notre paramètre d'entrée `reads_bam` pour pointer vers le fichier `sample_bams.txt`. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrée principale (fichier de fichiers d'entrée, un par ligne) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrée principale (tableau de trois échantillons) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +De cette façon, nous pouvons continuer à être paresseux, mais la liste des fichiers ne vit plus dans le code du workflow lui-même, ce qui est un grand pas dans la bonne direction. + +### 4.3. Mettre à jour le factory de canal pour lire les lignes d'un fichier + +Actuellement, notre factory de canal d'entrée traite tous les fichiers que nous lui donnons comme les entrées de données que nous voulons alimenter au processus d'indexation. +Puisque nous lui donnons maintenant un fichier qui liste les chemins de fichiers d'entrée, nous devons changer son comportement pour analyser le fichier et traiter les chemins de fichiers qu'il contient comme les entrées de données. + +Heureusement, nous pouvons faire cela très simplement, juste en ajoutant l'opérateur [`.splitText()`](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) à l'étape de construction du canal. + +=== "Après" + + ```groovy title="genomics-1.nf" linenums="68" + // Créer le canal d'entrée à partir d'un fichier texte listant les chemins de fichiers d'entrée + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Avant" + + ```groovy title="genomics-1.nf" linenums="68" + // Créer le canal d'entrée (fichier unique via paramètre CLI) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip + + C'est une autre excellente opportunité d'utiliser l'opérateur `.view()` pour regarder à quoi ressemble le contenu du canal avant et après l'application d'un opérateur. + +### 4.4. Exécuter le workflow pour vérifier qu'il fonctionne correctement + +Exécutons le workflow une dernière fois. Cela devrait produire le même résultat qu'avant, n'est-ce pas ? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + ``` + +Oui ! En fait, Nextflow détecte correctement que les appels de processus sont exactement les mêmes, et ne se donne même pas la peine de tout ré-exécuter, puisque nous exécutions avec `-resume`. + +Et c'est tout ! Notre simple workflow d'appel de variants a toutes les fonctionnalités de base que nous voulions. + +### À retenir + +Vous savez comment créer un workflow linéaire multi-étapes pour indexer un fichier BAM et appliquer l'appel de variants par échantillon en utilisant GATK. + +Plus généralement, vous avez appris à utiliser des composants et une logique Nextflow essentiels pour construire un pipeline de génomique simple qui fait du véritable travail, en tenant compte des idiosyncrasies des formats de fichiers génomiques et des exigences des outils. + +### Et ensuite ? + +Célébrez votre succès et prenez une pause extra longue ! + +Dans la prochaine partie de ce cours, vous apprendrez à utiliser quelques fonctionnalités Nextflow supplémentaires (y compris plus d'opérateurs de canal) pour appliquer l'appel de variants conjoint aux données. diff --git a/docs/fr/docs/nf4_science/genomics/02_joint_calling.md b/docs/fr/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..2a3af8141d --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1026 @@ +# Partie 2 : Appel conjoint de variants sur une cohorte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la première partie de ce cours, vous avez construit un pipeline d'appel de variants complètement linéaire qui traitait les données de chaque échantillon indépendamment des autres. +Cependant, dans un cas d'usage génomique réel, vous aurez généralement besoin d'examiner les appels de variants de plusieurs échantillons ensemble. + +Dans cette deuxième partie, nous vous montrons comment utiliser les canaux et les opérateurs de canaux pour implémenter l'appel conjoint de variants avec GATK, en nous basant sur le pipeline de la Partie 1. + +### Aperçu de la méthode + +La méthode d'appel de variants GATK que nous avons utilisée dans la première partie de ce cours générait simplement des appels de variants par échantillon. +C'est bien si vous voulez seulement examiner les variants de chaque échantillon isolément, mais cela fournit des informations limitées. +Il est souvent plus intéressant d'examiner comment les appels de variants diffèrent entre plusieurs échantillons, et pour ce faire, GATK offre une méthode alternative appelée appel conjoint de variants, que nous démontrons ici. + +L'appel conjoint de variants consiste à générer un type spécial de sortie de variants appelée GVCF (pour Genomic VCF) pour chaque échantillon, puis à combiner les données GVCF de tous les échantillons et enfin, à exécuter une analyse statistique de « génotypage conjoint ». + +![Analyse conjointe](img/joint-calling.png) + +Ce qui est spécial avec le GVCF d'un échantillon, c'est qu'il contient des enregistrements résumant les statistiques de données de séquence sur toutes les positions dans la zone ciblée du génome, et pas seulement les positions où le programme a trouvé des preuves de variation. +Ceci est essentiel pour le calcul du génotypage conjoint ([lecture complémentaire](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +Le GVCF est produit par GATK HaplotypeCaller, le même outil que nous avons utilisé dans la Partie 1, avec un paramètre supplémentaire (`-ERC GVCF`). +La combinaison des GVCFs est effectuée avec GATK GenomicsDBImport, qui combine les appels par échantillon dans un magasin de données (analogue à une base de données), puis l'analyse de « génotypage conjoint » proprement dite est effectuée avec GATK GenotypeGVCFs. + +### Workflow + +Donc, pour récapituler, dans cette partie du cours, nous allons développer un workflow qui fait ce qui suit : + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Générer un fichier d'index pour chaque fichier BAM d'entrée en utilisant Samtools +2. Exécuter GATK HaplotypeCaller sur chaque fichier BAM d'entrée pour générer un GVCF d'appels de variants génomiques par échantillon +3. Collecter tous les GVCFs et les combiner dans un magasin de données GenomicsDB +4. Exécuter le génotypage conjoint sur le magasin de données GVCF combiné pour produire un VCF au niveau de la cohorte + +Nous appliquerons ceci au même jeu de données que dans la Partie 1. + +--- + +## 0. Échauffement : Exécuter Samtools et GATK directement + +Tout comme précédemment, nous voulons essayer les commandes manuellement avant de tenter de les encapsuler dans un workflow. + +!!! note + + Assurez-vous d'être dans le bon répertoire de travail : + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Indexer un fichier BAM d'entrée avec Samtools + +Cette première étape est la même que dans la Partie 1, donc elle devrait être très familière, mais cette fois nous devons le faire pour les trois échantillons. + +!!! note + + Nous avons techniquement déjà généré des fichiers d'index pour les trois échantillons via notre pipeline, nous pourrions donc aller les récupérer dans le répertoire de résultats. Cependant, il est plus propre de simplement refaire cela manuellement, et cela ne prendra qu'une minute. + +#### 0.1.1. Démarrer le conteneur Samtools en mode interactif + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.1.2. Exécuter la commande d'indexation pour les trois échantillons + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Tout comme précédemment, cela devrait produire les fichiers d'index dans le même répertoire que les fichiers BAM correspondants. + +??? abstract "Contenu du répertoire" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Maintenant que nous avons des fichiers d'index pour les trois échantillons, nous pouvons procéder à la génération des GVCFs pour chacun d'eux. + +#### 0.1.3. Quitter le conteneur Samtools + +```bash +exit +``` + +### 0.2. Appeler les variants avec GATK HaplotypeCaller en mode GVCF + +Cette deuxième étape est très similaire à ce que nous avons fait dans la Partie 1 : Hello Genomics, mais nous allons maintenant exécuter GATK en « mode GVCF ». + +#### 0.2.1. Démarrer le conteneur GATK en mode interactif + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +#### 0.2.2. Exécuter la commande d'appel de variants avec l'option GVCF + +Afin de produire un VCF génomique (GVCF), nous ajoutons l'option `-ERC GVCF` à la commande de base, ce qui active le mode GVCF de HaplotypeCaller. + +Nous modifions également l'extension du fichier de sortie de `.vcf` à `.g.vcf`. +Ce n'est techniquement pas une exigence, mais c'est une convention fortement recommandée. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +Ceci crée le fichier de sortie GVCF `reads_mother.g.vcf` dans le répertoire de travail actuel dans le conteneur. + +Si vous utilisez `cat` pour visualiser le contenu, vous verrez qu'il est beaucoup plus long que le VCF équivalent que nous avons généré dans la Partie 1. Vous ne pouvez même pas faire défiler jusqu'au début du fichier, et la plupart des lignes semblent assez différentes de ce que nous avons vu dans le VCF de la Partie 1. + +```console title="Sortie" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Celles-ci représentent des régions non-variantes où l'appeleur de variants n'a trouvé aucune preuve de variation, il a donc capturé certaines statistiques décrivant son niveau de confiance dans l'absence de variation. Cela permet de distinguer deux cas très différents : (1) il y a des données de bonne qualité montrant que l'échantillon est homozygote-référence, et (2) il n'y a pas assez de bonnes données disponibles pour faire une détermination dans un sens ou dans l'autre. + +Dans un GVCF, il y a généralement beaucoup de telles lignes non-variantes, avec un plus petit nombre d'enregistrements de variants parsemés parmi elles. Essayez d'exécuter `head -176` sur le GVCF pour charger seulement les 176 premières lignes du fichier et trouver un appel de variant réel. + +```console title="Sortie" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +La deuxième ligne montre le premier enregistrement de variant dans le fichier, qui correspond au premier variant dans le fichier VCF que nous avons examiné dans la Partie 1. + +Tout comme le VCF original, le fichier de sortie GVCF est également accompagné d'un fichier d'index, appelé `reads_mother.g.vcf.idx`. + +#### 0.2.3. Répéter le processus sur les deux autres échantillons + +Afin de tester l'étape de génotypage conjoint, nous avons besoin de GVCFs pour les trois échantillons, générons-les donc manuellement maintenant. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +Une fois terminé, vous devriez avoir trois fichiers se terminant par `.g.vcf` dans votre répertoire actuel (un par échantillon) et leurs fichiers d'index respectifs se terminant par `.g.vcf.idx`. + +### 0.3. Exécuter le génotypage conjoint + +Maintenant que nous avons tous les GVCFs, nous pouvons enfin essayer l'approche de génotypage conjoint pour générer des appels de variants pour une cohorte d'échantillons. +Pour rappel, c'est une méthode en deux étapes qui consiste à combiner les données de tous les GVCFs dans un magasin de données, puis à exécuter l'analyse de génotypage conjoint proprement dite pour générer le VCF final d'appels de variants conjoints. + +#### 0.3.1. Combiner tous les GVCFs par échantillon + +Cette première étape utilise un autre outil GATK, appelé GenomicsDBImport, pour combiner les données de tous les GVCFs dans un magasin de données GenomicsDB. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +La sortie de cette étape est effectivement un répertoire contenant un ensemble de répertoires supplémentaires imbriqués contenant les données de variants combinées sous la forme de plusieurs fichiers différents. +Vous pouvez explorer mais vous verrez rapidement que ce format de magasin de données n'est pas destiné à être lu directement par des humains. + +!!! note + + GATK inclut des outils qui permettent d'inspecter et d'extraire les données d'appel de variants du magasin de données selon les besoins. + +#### 0.3.2. Exécuter l'analyse de génotypage conjoint proprement dite + +Cette deuxième étape utilise encore un autre outil GATK, appelé GenotypeGVCFs, pour recalculer les statistiques de variants et les génotypes individuels à la lumière des données disponibles sur tous les échantillons de la cohorte. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +Ceci crée le fichier de sortie VCF `family_trio.vcf` dans le répertoire de travail actuel dans le conteneur. +C'est un autre fichier raisonnablement petit, vous pouvez donc utiliser `cat` pour visualiser son contenu et faire défiler pour trouver les premières lignes de variants. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Cela ressemble plus au VCF original que nous avons généré dans la Partie 1, sauf que cette fois nous avons des informations au niveau du génotype pour les trois échantillons. +Les trois dernières colonnes du fichier sont les blocs de génotypes pour les échantillons, listés par ordre alphabétique. + +Si nous examinons les génotypes appelés pour notre trio familial de test pour le tout premier variant, nous voyons que le père est hétérozygote-variant (`0/1`), et la mère et le fils sont tous deux homozygotes-variants (`1/1`). + +C'est finalement l'information que nous cherchons à extraire du jeu de données ! Alors encapsulons tout cela dans un workflow Nextflow afin de pouvoir le faire à grande échelle. + +#### 0.3.3. Quitter le conteneur GATK + +```bash +exit +``` + +### À retenir + +Vous savez comment exécuter les commandes individuelles impliquées dans l'appel conjoint de variants dans le terminal pour vérifier qu'elles produiront les informations souhaitées. + +### Et ensuite ? + +Encapsuler ces commandes dans un pipeline réel. + +--- + +## 1. Modifier l'étape d'appel de variants par échantillon pour produire un GVCF + +La bonne nouvelle est que nous n'avons pas besoin de tout recommencer, puisque nous avons déjà écrit un workflow qui fait une partie de ce travail dans la Partie 1. +Cependant, ce pipeline produit des fichiers VCF, alors que maintenant nous voulons des fichiers GVCF afin de faire le génotypage conjoint. +Nous devons donc commencer par activer le mode d'appel de variants GVCF et mettre à jour l'extension du fichier de sortie. + +!!! note + + Pour plus de commodité, nous allons travailler avec une nouvelle copie du workflow GATK tel qu'il se présente à la fin de la Partie 1, mais sous un nom différent : `genomics-2.nf`. + +### 1.1. Indiquer à HaplotypeCaller d'émettre un GVCF et mettre à jour l'extension de sortie + +Ouvrons le fichier `genomics-2.nf` dans l'éditeur de code. +Il devrait être très familier, mais n'hésitez pas à l'exécuter si vous voulez vous assurer qu'il fonctionne comme prévu. + +Nous allons commencer par apporter deux modifications : + +- Ajouter le paramètre `-ERC GVCF` à la commande GATK HaplotypeCaller ; +- Mettre à jour le chemin du fichier de sortie pour utiliser l'extension `.g.vcf` correspondante, selon la convention GATK. + +Assurez-vous d'ajouter une barre oblique inverse (`\`) à la fin de la ligne précédente lorsque vous ajoutez `-ERC GVCF`. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +Et c'est tout ce qu'il faut pour faire passer HaplotypeCaller à la génération de GVCFs au lieu de VCFs, n'est-ce pas ? + +### 1.2. Exécuter le pipeline pour vérifier que vous pouvez générer des GVCFs + +La commande d'exécution Nextflow est la même qu'avant, sauf pour le nom du fichier de workflow lui-même. +Assurez-vous de le mettre à jour de manière appropriée. + +```bash +nextflow run genomics-2.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +Et la sortie est... toute rouge ! Oh non. + +La commande qui a été exécutée est correcte, nous avions donc raison de penser que c'était suffisant pour changer le comportement de l'outil GATK. +Mais regardez cette ligne sur le fichier de sortie manquant. Remarquez-vous quelque chose ? + +C'est exact, nous avons oublié de dire à Nextflow d'attendre un nouveau nom de fichier. Oups. + +### 1.3. Mettre à jour l'extension du fichier de sortie dans le bloc de sorties du processus également + +Parce qu'il ne suffit pas de simplement changer l'extension du fichier dans la commande de l'outil elle-même, vous devez également dire à Nextflow que le nom du fichier de sortie attendu a changé. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Mettre à jour les cibles de publication pour les nouvelles sorties GVCF + +Puisque nous produisons maintenant des GVCFs au lieu de VCFs, nous devrions mettre à jour la section `publish:` du workflow pour utiliser des noms plus descriptifs. +Nous organiserons également les fichiers GVCF dans leur propre sous-répertoire pour plus de clarté. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Mettre à jour le bloc output pour la nouvelle structure de répertoires + +Nous devons également mettre à jour le bloc `output` pour placer les fichiers GVCF dans un sous-répertoire `gvcf`. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Exécuter à nouveau le pipeline + +Exécutons-le avec `-resume` cette fois. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Cette fois, cela fonctionne. + +La sortie Nextflow elle-même ne semble pas différente (comparée à une exécution réussie en mode VCF normal), mais maintenant nous pouvons trouver les fichiers `.g.vcf` et leurs fichiers d'index respectifs, pour les trois échantillons, organisés dans des sous-répertoires. + +??? abstract "Contenu du répertoire (liens symboliques raccourcis)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Si vous ouvrez l'un des fichiers GVCF et le parcourez, vous pouvez vérifier que GATK HaplotypeCaller a produit des fichiers GVCF comme demandé. + +### À retenir + +Bon, celle-ci était minime en termes d'apprentissage Nextflow... +Mais c'était une belle occasion de réitérer l'importance du bloc de sortie du processus ! + +### Et ensuite ? + +Apprendre à collecter le contenu d'un canal et à le transmettre au processus suivant comme une entrée unique. + +--- + +## 2. Collecter et combiner les données GVCF de tous les échantillons + +Nous devons maintenant combiner les données de tous les GVCFs par échantillon dans une forme qui supporte l'analyse de génotypage conjoint que nous voulons faire. + +### 2.1. Définir le processus qui combinera les GVCFs + +Pour rappel de ce que nous avons fait plus tôt dans la section d'échauffement, combiner les GVCFs est un travail pour l'outil GATK GenomicsDBImport, qui produira un magasin de données dans le format dit GenomicsDB. + +Écrivons un nouveau processus pour définir comment cela va fonctionner, basé sur la commande que nous avons utilisée plus tôt dans la section d'échauffement. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Combiner les GVCFs dans un magasin de données GenomicsDB + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +Qu'en pensez-vous, cela semble-t-il raisonnable ? + +Branchons-le et voyons ce qui se passe. + +### 2.2. Ajouter un paramètre `cohort_name` avec une valeur par défaut + +Nous devons fournir un nom arbitraire pour la cohorte. +Plus tard dans la série de formations, vous apprendrez comment utiliser les métadonnées d'échantillons pour ce genre de choses, mais pour l'instant, nous déclarons simplement un paramètre CLI en utilisant `params` et lui donnons une valeur par défaut pour plus de commodité. + +```groovy title="genomics-2.nf" linenums="16" + // Nom de base pour le fichier de sortie final + cohort_name: String = "family_trio" +``` + +### 2.3. Rassembler les sorties de GATK_HAPLOTYPECALLER pour tous les échantillons + +Si nous devions simplement brancher le canal de sortie du processus `GATK_HAPLOTYPECALLER` tel quel, Nextflow appellerait le processus sur chaque GVCF d'échantillon séparément. +Cependant, nous voulons regrouper les trois GVCFs (et leurs fichiers d'index) de telle manière que Nextflow les transmette tous ensemble à un seul appel de processus. + +Bonne nouvelle : nous pouvons le faire en utilisant l'opérateur de canal `collect()`. Ajoutons les lignes suivantes au corps du `workflow`, juste après l'appel à GATK_HAPLOTYPECALLER : + +```groovy title="genomics-2.nf" linenums="118" +// Collecter les sorties d'appel de variants pour tous les échantillons +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Cela semble-t-il un peu compliqué ? Décomposons cela et traduisons-le en langage clair. + +1. Nous prenons le canal de sortie du processus `GATK_HAPLOTYPECALLER`, référencé en utilisant la propriété `.out`. +2. Chaque « élément » sortant du canal est une paire de fichiers : le GVCF et son fichier d'index, dans cet ordre parce que c'est l'ordre dans lequel ils sont listés dans le bloc de sortie du processus. Heureusement, parce que dans la dernière session nous avons nommé les sorties de ce processus (en utilisant `emit:`), nous pouvons sélectionner les GVCFs d'un côté en ajoutant `.vcf` et les fichiers d'index de l'autre en ajoutant `.idx` après la propriété `.out`. Si nous n'avions pas nommé ces sorties, nous aurions dû y faire référence par `.out[0]` et `.out[1]`, respectivement. +3. Nous ajoutons l'opérateur de canal `collect()` pour regrouper tous les fichiers GVCF ensemble dans un seul élément d'un nouveau canal appelé `all_gvcfs_ch`, et faisons de même avec les fichiers d'index pour former le nouveau canal appelé `all_idxs_ch`. + +!!! tip + + Si vous avez du mal à visualiser exactement ce qui se passe ici, rappelez-vous que vous pouvez utiliser l'opérateur `view()` pour inspecter le contenu des canaux avant et après l'application des opérateurs de canaux. + +Les canaux `all_gvcfs_ch` et `all_idxs_ch` résultants sont ce que nous allons brancher dans le processus `GATK_GENOMICSDB` que nous venons d'écrire. + +!!! note + + Au cas où vous vous poseriez la question, nous collectons les GVCFs et leurs fichiers d'index séparément parce que la commande GATK GenomicsDBImport ne veut voir que les chemins des fichiers GVCF. Heureusement, puisque Nextflow préparera tous les fichiers ensemble pour l'exécution, nous n'avons pas à nous soucier de l'ordre des fichiers comme nous l'avons fait pour les BAMs et leur index dans la Partie 1. + +### 2.4. Ajouter un appel au bloc workflow pour exécuter GATK_GENOMICSDB + +Nous avons un processus, et nous avons des canaux d'entrée. Nous devons juste ajouter l'appel de processus. + +```groovy title="genomics-2.nf" linenums="122" + // Combiner les GVCFs dans un magasin de données GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, tout est branché. + +### 2.5. Exécuter le workflow + +Voyons si cela fonctionne. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Il s'exécute assez rapidement, puisque nous exécutons avec `-resume`, mais il échoue ! + +Ah. Du côté positif, nous voyons que Nextflow a récupéré le processus `GATK_GENOMICSDB`, et l'a spécifiquement appelé une seule fois. +Cela suggère que l'approche `collect()` a fonctionné, dans une certaine mesure. +Mais, et c'est un gros mais, l'appel de processus a échoué. + +Lorsque nous fouillons dans la sortie de la console ci-dessus, nous pouvons voir que la commande exécutée n'est pas correcte. + +Pouvez-vous repérer l'erreur ? +Regardez cette partie : `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Nous avons donné à `gatk GenomicsDBImport` plusieurs fichiers GVCF pour un seul argument `-V`, mais l'outil attend un argument `-V` séparé pour chaque fichier GVCF. + +Pour rappel, voici la commande que nous avons exécutée dans le conteneur : + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Cela signifie donc que nous devons d'une manière ou d'une autre transformer notre ensemble de fichiers GVCF en une chaîne de commande correctement formatée. + +### 2.6. Construire une ligne de commande avec un argument `-V` séparé pour chaque GVCF d'entrée + +C'est là que le fait que Nextflow soit basé sur Groovy s'avère pratique, car cela va nous permettre d'utiliser des manipulations de chaînes assez simples pour construire la chaîne de commande nécessaire. + +Spécifiquement, en utilisant cette syntaxe : `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Encore une fois, décomposons cela en ses composants. + +1. D'abord, nous prenons le contenu du canal d'entrée `all_gvcfs` et appliquons `.collect()` dessus (tout comme précédemment). +2. Cela nous permet de passer chaque chemin de fichier GVCF individuel dans l'ensemble à la **closure**, `{ gvcf -> "-V ${gvcf}" }`, où `gvcf` fait référence à ce chemin de fichier GVCF. + La closure est une mini-fonction que nous utilisons pour préfixer `-V ` au chemin de fichier, sous la forme de `"-V ${gvcf}"`. +3. Ensuite, nous utilisons `.join(' ')` pour concaténer les trois chaînes avec un seul espace comme séparateur. + +Avec un exemple concret, cela ressemble à ceci : + +1. Nous avons trois fichiers : + + `[A.ext, B.ext, C.ext]` + +2. La closure modifie chacun pour créer les chaînes : + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. L'opération `.join(' ')` génère la chaîne finale : + + `"-V A.ext -V B.ext -V C.ext"` + +Une fois que nous avons cette chaîne, nous pouvons l'assigner à une variable locale, `gvcfs_line`, définie avec le mot-clé `def` : + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, nous avons donc notre manipulation de chaîne. Où la mettons-nous ? + +Nous voulons que cela aille quelque part dans la définition du processus, car nous voulons le faire _après_ avoir canalisé les chemins de fichiers GVCF dans le processus. +C'est parce que Nextflow doit les voir comme des chemins de fichiers afin de préparer les fichiers eux-mêmes correctement pour l'exécution. + +Mais _où_ dans le processus pouvons-nous ajouter cela ? + +Fait amusant : vous pouvez ajouter du code arbitraire après `script:` et avant les `"""` ! + +Parfait, ajoutons notre ligne de manipulation de chaîne là alors, et mettons à jour la commande `gatk GenomicsDBImport` pour utiliser la chaîne concaténée qu'elle produit. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Cela devrait être tout ce qui est nécessaire pour fournir les entrées à `gatk GenomicsDBImport` correctement. + +!!! tip + + Lorsque vous mettez à jour la commande `gatk GenomicsDBImport`, assurez-vous de supprimer le préfixe `-V ` lorsque vous remplacez par la variable `${gvcfs_line}`. + +### 2.7. Exécuter le workflow pour vérifier qu'il génère la sortie GenomicsDB comme prévu + +D'accord, voyons si cela a résolu le problème. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha ! Il semble que cela fonctionne maintenant. + +Les deux premières étapes ont été ignorées avec succès, et la troisième étape a fonctionné comme un charme cette fois. +Le magasin de données GenomicsDB est créé dans le répertoire de travail mais n'est pas publié dans les résultats, puisque c'est juste un format intermédiaire que nous utiliserons pour le génotypage conjoint. + +Au fait, nous n'avons rien eu à faire de spécial pour gérer le fait que la sortie soit un répertoire au lieu d'un seul fichier. + +### À retenir + +Vous savez maintenant comment collecter les sorties d'un canal et les regrouper comme une entrée unique pour un autre processus. +Vous savez également comment construire une ligne de commande pour fournir des entrées à un outil donné avec la syntaxe appropriée. + +### Et ensuite ? + +Apprendre à ajouter une deuxième commande au même processus. + +--- + +## 3. Exécuter l'étape de génotypage conjoint dans le même processus + +Maintenant que nous avons les appels de variants génomiques combinés, nous pouvons exécuter l'outil de génotypage conjoint, qui produira la sortie finale qui nous intéresse vraiment : le VCF d'appels de variants au niveau de la cohorte. + +Pour des raisons logistiques, nous décidons d'inclure le génotypage conjoint dans le même processus. + +### 3.1. Renommer le processus de GATK_GENOMICSDB à GATK_JOINTGENOTYPING + +Puisque le processus exécutera plus d'un outil, nous changeons son nom pour faire référence à l'opération globale plutôt qu'à un seul nom d'outil. + +=== "Après" + + ```groovy title="genomics-2.nf" + /* + * Combiner les GVCFs dans un magasin de données GenomicsDB et exécuter le génotypage conjoint pour produire des appels au niveau de la cohorte + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" + /* + * Combiner les GVCFs dans un magasin de données GenomicsDB + */ + process GATK_GENOMICSDB { + ``` + +N'oubliez pas de garder vos noms de processus aussi descriptifs que possible, pour maximiser la lisibilité pour vos collègues — et votre futur vous ! + +### 3.2. Ajouter la commande de génotypage conjoint au processus GATK_JOINTGENOTYPING + +Ajoutez simplement la deuxième commande après la première dans la section script. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Les deux commandes seront exécutées en série, de la même manière qu'elles le seraient si nous les exécutions manuellement dans le terminal. + +### 3.3. Ajouter les fichiers du génome de référence aux définitions d'entrée du processus GATK_JOINTGENOTYPING + +La deuxième commande nécessite les fichiers du génome de référence, nous devons donc les ajouter aux entrées du processus. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Il peut sembler ennuyeux de taper tout cela, mais rappelez-vous, vous ne les tapez qu'une fois, et ensuite vous pouvez exécuter le workflow un million de fois. Ça en vaut la peine ? + +### 3.4. Mettre à jour la définition de sortie du processus pour émettre le VCF d'appels de variants au niveau de la cohorte + +Nous ne nous soucions pas vraiment de sauvegarder le magasin de données GenomicsDB, qui n'est qu'un format intermédiaire qui existe seulement pour des raisons logistiques, nous pouvons donc simplement le supprimer du bloc de sortie si nous le souhaitons. + +La sortie qui nous intéresse vraiment est le VCF produit par la commande de génotypage conjoint. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Nous avons presque fini ! + +### 3.5. Mettre à jour l'appel de processus de GATK_GENOMICSDB à GATK_JOINTGENOTYPING + +N'oublions pas de renommer l'appel de processus dans le corps du workflow de GATK_GENOMICSDB à GATK_JOINTGENOTYPING. Et pendant que nous y sommes, nous devrions également ajouter les fichiers du génome de référence comme entrées, puisque nous devons les fournir à l'outil de génotypage conjoint. + +=== "Après" + + ```groovy title="genomics-2.nf" linenums="126" + // Combiner les GVCFs dans un magasin de données GenomicsDB et appliquer le génotypage conjoint + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Avant" + + ```groovy title="genomics-2.nf" linenums="126" + // Combiner les GVCFs dans un magasin de données GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Maintenant le processus est complètement branché. + +### 3.6. Ajouter le VCF conjoint à la section publish + +Nous devons publier les sorties VCF conjointes du nouveau processus. +Ajoutez ces lignes à la section `publish:` du workflow : + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Ajouter les cibles VCF conjointes au bloc output + +Enfin, ajoutez des cibles de sortie pour les fichiers VCF conjoints. +Nous les placerons à la racine du répertoire de résultats puisque c'est la sortie finale. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Maintenant tout devrait être complètement branché. + +### 3.8. Exécuter le workflow + +Enfin, nous pouvons exécuter le workflow modifié... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Et ça fonctionne ! + +Vous trouverez le fichier de sortie final, `family_trio.joint.vcf` (et son index de fichier), dans le répertoire de résultats. + +??? abstract "Contenu du répertoire (liens symboliques raccourcis)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Si vous êtes du genre sceptique, vous pouvez cliquer sur le fichier VCF conjoint pour l'ouvrir et vérifier que le workflow a généré les mêmes appels de variants que vous avez obtenus en exécutant les outils manuellement au début de cette section. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Vous avez maintenant un workflow d'appel conjoint de variants automatisé et entièrement reproductible ! + +!!! note + + Gardez à l'esprit que les fichiers de données que nous vous avons fournis ne couvrent qu'une toute petite portion du chromosome 20. + La taille réelle d'un ensemble d'appels de variants se compterait en millions de variants. + C'est pourquoi nous n'utilisons que de minuscules sous-ensembles de données à des fins de formation ! + +### À retenir + +Vous savez comment utiliser certains opérateurs courants ainsi que des closures Groovy pour contrôler le flux de données dans votre workflow. + +### Et ensuite ? + +Célébrez votre succès et prenez une pause bien méritée. + +Dans la prochaine partie de ce cours, vous apprendrez à modulariser votre workflow en extrayant les définitions de processus dans des modules réutilisables. diff --git a/docs/fr/docs/nf4_science/genomics/03_modules.md b/docs/fr/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..5ac6031a7f --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Partie 3 : Déplacer le code dans des modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la première partie de cette formation, vous avez construit un pipeline d'appel de variants complètement linéaire qui traitait les données de chaque échantillon indépendamment des autres. + +Dans la deuxième partie, nous vous avons montré comment utiliser les canaux et les opérateurs de canaux pour implémenter l'appel de variants joint avec GATK, en vous appuyant sur le pipeline de la Partie 1. + +Dans cette partie, nous allons vous montrer comment convertir le code de ce workflow en modules. Pour suivre cette partie de la formation, vous devriez avoir terminé la Partie 1 et la Partie 2, ainsi que [Hello Modules](../../../hello_nextflow/hello_modules.md), qui couvre les bases des modules. + +--- + +## 0. Échauffement + +Lorsque nous avons commencé à développer notre workflow, nous avons tout mis dans un seul fichier de code. +Il est maintenant temps de s'attaquer à la **modularisation** de notre code, _c'est-à-dire_ extraire les définitions de processus dans des modules. + +Nous allons commencer avec le même workflow que dans la Partie 2, que nous vous avons fourni dans le fichier `genomics-3.nf`. + +!!! note "Note" + + Assurez-vous d'être dans le bon répertoire de travail : + `cd /workspaces/training/nf4-science/genomics` + +Exécutez le workflow pour vérifier le point de départ : + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Sortie" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Il y aura maintenant un répertoire `work` et un répertoire `results_genomics` à l'intérieur de votre répertoire de projet. + +### À retenir + +Vous êtes prêt à commencer la modularisation de votre workflow. + +### Et ensuite ? + +Déplacer les processus du workflow Genomics dans des modules. + +--- + +## 1. Déplacer les processus dans des modules + +Comme vous l'avez appris dans [Hello Modules](../../../hello_nextflow/hello_modules.md), vous pouvez créer un module simplement en copiant la définition du processus dans son propre fichier, dans n'importe quel répertoire, et vous pouvez nommer ce fichier comme vous le souhaitez. + +Pour des raisons qui deviendront claires plus tard (en particulier lorsque nous aborderons les tests), dans cette formation nous suivrons la convention de nommer le fichier `main.nf`, et de le placer dans une structure de répertoires nommée d'après la boîte à outils et la commande. + +### 1.1. Créer un module pour le processus `SAMTOOLS_INDEX` + +Dans le cas du processus `SAMTOOLS_INDEX`, 'samtools' est la boîte à outils et 'index' est la commande. Nous allons donc créer une structure de répertoires `modules/samtools/index` et placer la définition du processus `SAMTOOLS_INDEX` dans le fichier `main.nf` à l'intérieur de ce répertoire. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Ouvrez le fichier `main.nf` et copiez-y la définition du processus `SAMTOOLS_INDEX`. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * Générer le fichier d'index BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Ensuite, supprimez la définition du processus `SAMTOOLS_INDEX` de `genomics-3.nf`, et ajoutez une déclaration d'import pour le module avant la définition du processus suivant, comme ceci : + +=== "Après" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Inclure les modules + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Appeler les variants avec GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Avant" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Appeler les variants avec GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +Vous pouvez maintenant exécuter à nouveau le workflow, et il devrait fonctionner de la même manière qu'auparavant. Si vous fournissez l'option `-resume`, aucune nouvelle tâche ne devrait même avoir besoin d'être exécutée : + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Créer des modules pour les processus `GATK_HAPLOTYPECALLER` et `GATK_JOINTGENOTYPING` + +Répétez les mêmes étapes pour les processus restants. +Pour chaque processus : + +1. Créez la structure de répertoires (`modules/gatk/haplotypecaller/` et `modules/gatk/jointgenotyping/`) +2. Créez un fichier `main.nf` contenant la définition du processus +3. Supprimez la définition du processus de `genomics-3.nf` +4. Ajoutez une déclaration d'import pour le module + +Une fois terminé, vérifiez que la structure de votre répertoire modules est correcte en exécutant : + +```bash +tree modules/ +``` + +??? abstract "Contenu du répertoire" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Vous devriez également avoir quelque chose comme ceci dans le fichier workflow principal, après la section des paramètres : + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### À retenir + +Vous vous êtes exercé à modulariser un workflow, avec le workflow génomique comme exemple. + +### Et ensuite ? + +Tester le workflow modularisé. + +--- + +## 2. Tester le workflow modularisé + +Exécutez le workflow modularisé pour vérifier que tout fonctionne toujours. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Sortie" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Tout fonctionne toujours, y compris la capacité de reprise du pipeline. +Les résultats continuent d'être publiés dans le répertoire `results_genomics`. + +```console title="Contenu du répertoire" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### À retenir + +Vous avez modularisé un workflow et vérifié qu'il fonctionne toujours de la même manière qu'auparavant. + +### Et ensuite ? + +Examiner ce que vous avez appris et anticiper les tests. + +--- + +## 3. Résumé + +Vous avez modularisé le workflow, et rien n'a changé dans le fonctionnement du pipeline. +C'est intentionnel : vous avez restructuré le code sans impacter sa fonction. + +Les modules contiennent uniquement la logique des processus, les rendant propres et réutilisables. +Le script principal contrôle ce qui est publié et où, tandis que les modules restent concentrés sur leur tâche de calcul. + +Vous avez posé les bases de choses qui rendront votre code plus facile à maintenir. +Par exemple, vous pouvez maintenant ajouter des tests à votre pipeline en utilisant le framework nf-test. +C'est ce que nous examinerons dans la prochaine partie de cette formation. diff --git a/docs/fr/docs/nf4_science/genomics/04_testing.md b/docs/fr/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..e21362d086 --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Partie 4 : Ajout de tests + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la première partie de ce cours, vous avez construit un pipeline d'appel de variants complètement linéaire qui traitait les données de chaque échantillon indépendamment des autres. + +Dans la deuxième partie, nous vous avons montré comment utiliser les canaux et les opérateurs de canaux pour implémenter l'appel de variants conjoint avec GATK. + +Dans la troisième partie, nous avons modularisé le pipeline. + +Dans cette partie de la formation, nous allons vous montrer comment utiliser [**nf-test**](https://www.nf-test.com/), un framework de test qui s'intègre bien avec Nextflow et facilite l'ajout de tests au niveau des modules et au niveau du workflow à votre pipeline. Pour suivre cette partie de la formation, vous devriez avoir complété la Partie 1, la Partie 2 et la Partie 3, ainsi que la [quête annexe nf-test](../../side_quests/nf-test.md), qui couvre les bases de nf-test et pourquoi les tests sont importants. + +--- + +## 0. Échauffement + +!!! note + + Assurez-vous d'être dans le répertoire de travail correct : + `cd /workspaces/training/nf4-science/genomics` + +Si vous avez suivi les parties précédentes de ce cours de formation, vous devriez avoir une version fonctionnelle du pipeline de génomique avec la structure de répertoires de modules appropriée. + +??? abstract "Contenu du répertoire" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Ce répertoire modules se trouve dans le répertoire `solutions` si vous en avez besoin. + +Nous allons commencer avec le même workflow que dans la Partie 3, que nous vous avons fourni dans le fichier `genomics-4.nf`. Exactement comme pour la [quête annexe nf-test](../../side_quests/nf-test.md), nous allons ajouter plusieurs types de tests différents aux trois processus de ce pipeline, ainsi qu'un test au niveau du workflow. + +### 0.1. Vérifier que le workflow s'exécute + +Avant de commencer à ajouter des tests, assurez-vous que le workflow s'exécute comme prévu. + +```bash +nextflow run genomics-4.nf -resume +``` + +Cela devrait vous sembler très familier maintenant si vous avez suivi ce cours de formation depuis le début. + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Comme précédemment, il y aura maintenant un répertoire `work` et un répertoire `results_genomics` dans votre répertoire de projet. Nous utiliserons en fait ces résultats plus tard dans nos tests. Mais à partir de maintenant, nous allons utiliser le package `nf-test` pour tester le pipeline. + +### 0.2. Initialiser `nf-test` + +Comme pour la [quête annexe nf-test](../../side_quests/nf-test.md), nous devons initialiser le package `nf-test`. + +```bash +nf-test init +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "Contenu de nf-test.config" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Cela crée également un répertoire `tests` contenant une ébauche de fichier de configuration. + +### À retenir + +Nous sommes maintenant prêts à commencer à écrire des tests pour notre pipeline de génomique. + +### Et maintenant ? + +Écrire des tests de base qui évaluent si les appels de processus ont réussi et produit les sorties correctes. + +--- + +## 1. Tester un processus pour le succès et la correspondance des sorties + +Nous commencerons par tester le processus `SAMTOOLS_INDEX`, qui crée des fichiers d'index pour les fichiers BAM afin de permettre un accès aléatoire efficace. C'est un bon premier cas de test car : + +1. Il a une seule entrée bien définie (un fichier BAM) +2. Il produit une sortie prévisible (un fichier d'index BAI) +3. La sortie devrait être identique pour des entrées identiques + +### 1.1. Générer une ébauche de fichier de test + +Tout d'abord, générez une ébauche de fichier de test : + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Sortie de la commande" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Cela crée un fichier dans le même répertoire que `main.nf`. +Vous pouvez naviguer vers le répertoire dans l'explorateur de fichiers et ouvrir le fichier, qui devrait contenir le code suivant : + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Les assertions de départ devraient être familières de la [quête annexe nf-test](../../side_quests/nf-test.md) : + +- `assert process.success` indique que nous attendons que le processus s'exécute avec succès et se termine sans échec. +- `snapshot(process.out).match()` indique que nous attendons que le résultat de l'exécution soit identique au résultat obtenu lors d'une exécution précédente (le cas échéant). + Nous en discutons plus en détail plus tard. + +En utilisant ceci comme point de départ, nous devons ajouter les bonnes entrées de test pour le processus samtools index, et tous les paramètres le cas échéant. + +### 1.2. Déplacer le fichier de test et mettre à jour le chemin du script + +Avant de commencer à remplir le test, nous devons déplacer le fichier vers son emplacement définitif. Une partie de la raison pour laquelle nous avons ajouté un répertoire pour chaque module est que nous pouvons maintenant inclure les tests dans un répertoire `tests` colocalisé avec le fichier `main.nf` de chaque module. Créez ce répertoire et déplacez le fichier de test là-bas. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Nous pouvons maintenant simplifier la section `script` du fichier de test en un chemin relatif : + +=== "Après" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Avant" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Cela indique au test où trouver le fichier `main.nf` du module, sans avoir à spécifier le chemin complet. + +### 1.3. Fournir des entrées de test pour SAMTOOLS_INDEX + +Le fichier d'ébauche inclut un espace réservé que nous devons remplacer par une entrée de test réelle, appropriée à l'entrée de `samtools index`. L'entrée appropriée est un fichier BAM, que nous avons disponible dans le répertoire `data/bam`. + +=== "Après" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Avant" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Nommer le test en fonction de la fonctionnalité + +Comme nous l'avons appris précédemment, c'est une bonne pratique de renommer le test avec quelque chose qui a du sens dans le contexte du test. + +=== "Après" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Cela prend une chaîne arbitraire, nous pourrions donc y mettre ce que nous voulons. + Ici, nous choisissons de faire référence au nom du fichier et à son format. + +=== "Avant" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Exécuter le test et examiner la sortie + +Exécutez le test : + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Comme nous l'avons appris précédemment, cela a vérifié l'assertion de base sur le succès du processus et créé un fichier snapshot basé sur la sortie du processus. Nous pouvons voir le contenu du fichier snapshot dans le fichier `tests/modules/samtools/index/tests/main.nf.test.snap` : + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Nous pouvons également exécuter à nouveau le test et voir qu'il réussit, car la sortie est identique au snapshot : + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Ajouter plus de tests à `SAMTOOLS_INDEX` + +Parfois, il est utile de tester une gamme de différents fichiers d'entrée pour s'assurer que nous testons une variété de problèmes potentiels. Ajoutez des tests pour les fichiers BAM de la mère et du père dans le trio de nos données de test. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Ensuite, vous pouvez exécuter à nouveau le test : + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Notez l'avertissement, faisant référence à l'effet du paramètre `--update-snapshot`. + +!!! note + + Ici, nous utilisons des données de test que nous avons utilisées précédemment pour démontrer les sorties scientifiques du pipeline. + Si nous avions prévu d'utiliser ces tests dans un environnement de production, nous aurions généré des entrées plus petites à des fins de test. + + En général, il est important de garder les tests unitaires aussi légers que possible en utilisant les plus petits morceaux de données nécessaires et suffisants pour évaluer la fonctionnalité du processus, sinon le temps d'exécution total peut s'additionner de manière assez sérieuse. + Une suite de tests qui prend trop de temps à s'exécuter régulièrement est une suite de tests susceptible d'être ignorée dans l'intérêt de l'opportunité. + +### À retenir + +Vous avez écrit votre premier test de module pour un processus de génomique, vérifiant que `SAMTOOLS_INDEX` crée correctement des fichiers d'index pour différents fichiers BAM. La suite de tests garantit que : + +1. Le processus s'exécute avec succès +2. Les fichiers d'index sont créés +3. Les sorties sont cohérentes entre les exécutions +4. Le processus fonctionne pour tous les fichiers BAM d'échantillons + +### Et maintenant ? + +Apprendre à écrire des tests pour d'autres processus dans notre workflow de génomique, en utilisant la méthode setup pour gérer les processus chaînés. Nous évaluerons également si les sorties, en particulier nos fichiers VCF, contiennent les appels de variants attendus. + +--- + +## 2. Ajouter des tests à un processus chaîné et tester le contenu + +Pour tester `GATK_HAPLOTYPECALLER`, nous devons fournir au processus la sortie de `SAMTOOLS_INDEX` comme entrée. Nous pourrions le faire en exécutant `SAMTOOLS_INDEX`, en récupérant ses sorties et en les stockant avec les données de test pour le workflow. C'est en fait l'approche recommandée pour un pipeline soigné, mais nf-test fournit une approche alternative, utilisant la méthode `setup`. + +Avec la méthode setup, nous pouvons déclencher le processus `SAMTOOLS_INDEX` dans le cadre de la configuration du test, puis utiliser sa sortie comme entrée pour `GATK_HAPLOTYPECALLER`. Cela a un coût : nous allons devoir exécuter le processus `SAMTOOLS_INDEX` à chaque fois que nous exécutons le test pour `GATK_HAPLOTYPECALLER`. Cependant, peut-être que nous développons encore le workflow et ne voulons pas pré-générer des données de test que nous pourrions devoir modifier plus tard. Le processus `SAMTOOLS_INDEX` est également très rapide, donc peut-être que les avantages de pré-générer et de stocker ses sorties sont négligeables. Voici comment fonctionne la méthode setup. + +### 2.1. Générer et placer le fichier de test + +Comme précédemment, nous générons d'abord l'ébauche du fichier : + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Sortie de la commande" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Cela produit l'ébauche de test suivante : + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Déplacer le fichier de test et mettre à jour le chemin du script + +Nous créons un répertoire pour le fichier de test colocalisé avec le fichier `main.nf` du module : + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +Et nous déplaçons le fichier d'ébauche de test là-bas : + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Enfin, n'oubliez pas de mettre à jour le chemin du script : + +=== "Après" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Avant" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Fournir des entrées en utilisant la méthode setup + +Nous insérons un bloc `setup` avant le bloc `when`, où nous pouvons déclencher une exécution du processus `SAMTOOLS_INDEX` sur l'un de nos fichiers d'entrée d'origine. N'oubliez pas non plus de changer le nom du test en quelque chose de significatif. + +=== "Après" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Avant" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Ensuite, nous pouvons faire référence à la sortie de ce processus dans le bloc `when` où nous spécifions les entrées de test : + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Effectuez cette modification et exécutez à nouveau le test : + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Cela produit également un fichier snapshot comme précédemment. + +### 2.4. Exécuter à nouveau et observer l'échec + +Fait intéressant, si vous exécutez exactement la même commande à nouveau, cette fois le test échouera. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +Le message d'erreur vous indique qu'il y avait des différences entre les snapshots pour les deux exécutions ; plus précisément, les valeurs md5sum sont différentes pour les fichiers VCF. + +Pourquoi ? Pour faire court, l'outil HaplotypeCaller inclut un horodatage dans l'en-tête VCF qui est différent à chaque fois (par définition). +En conséquence, nous ne pouvons pas simplement nous attendre à ce que les fichiers aient des md5sum identiques même s'ils ont un contenu identique en termes d'appels de variants eux-mêmes. + +Comment gérons-nous cela ? + +### 2.5. Utiliser une méthode d'assertion de contenu pour vérifier un variant spécifique + +Une façon de résoudre le problème est d'utiliser un [type d'assertion différent](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions). +Dans ce cas, nous allons vérifier un contenu spécifique au lieu d'affirmer l'identité. +Plus exactement, nous allons faire lire les lignes du fichier VCF par l'outil et vérifier l'existence de lignes spécifiques. + +En pratique, nous remplaçons la deuxième assertion dans le bloc `then` comme suit : + +=== "Après" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Avant" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Ici, nous lisons le contenu complet du fichier de sortie VCF et recherchons une correspondance de contenu, ce qui est acceptable sur un petit fichier de test, mais vous ne voudriez pas faire cela sur un fichier plus volumineux. +Vous pourriez plutôt choisir de lire des lignes spécifiques. + +Cette approche nécessite de choisir plus soigneusement ce que nous voulons utiliser comme « signal » à tester. +Le bon côté, c'est qu'elle peut être utilisée pour tester avec une grande précision si un outil d'analyse peut systématiquement identifier des caractéristiques « difficiles » (comme des variants rares) au fur et à mesure de son développement. + +### 2.6. Exécuter à nouveau et observer le succès + +Une fois que nous avons modifié le test de cette façon, nous pouvons exécuter le test plusieurs fois, et il réussira systématiquement. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Ajouter plus de tests + +Ajoutez des tests similaires pour les échantillons de la mère et du père : + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Exécuter la commande de test + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Cela complète le plan de test de base pour cette deuxième étape dans le pipeline. Passons au troisième et dernier test au niveau du module ! + +### À retenir + +Vous avez appris comment : + +1. Tester des processus qui dépendent des sorties d'autres processus +2. Vérifier des variants génomiques spécifiques dans les fichiers de sortie VCF +3. Gérer les sorties non déterministes en vérifiant un contenu spécifique +4. Tester l'appel de variants sur plusieurs échantillons + +### Et maintenant ? + +Apprendre à écrire des tests qui utilisent des données de test pré-générées pour l'étape de génotypage conjoint. + +--- + +## 3. Utiliser des données de test pré-générées + +Pour l'étape de génotypage conjoint, nous utiliserons une approche différente - l'utilisation de données de test pré-générées. Ceci est souvent préférable pour : + +1. Les processus complexes avec plusieurs dépendances +2. Les processus qui prennent beaucoup de temps à s'exécuter +3. Les processus qui font partie d'un pipeline stable de production + +### 3.1. Générer des données de test + +Inspectez les résultats que nous avons générés au début de cette section : + +```bash +tree results_genomics/ +``` + +```console title="Contenu du répertoire de résultats" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +L'étape de génotypage conjoint nécessite les fichiers VCF produits par les étapes de l'appeleur d'haplotypes comme entrées, ainsi que les indices. Copions donc les résultats que nous avons dans le répertoire de tests du module `jointgenotyping`. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Nous pouvons maintenant utiliser ces fichiers comme entrées pour le test que nous allons écrire pour l'étape de génotypage conjoint. + +### 3.2. Générer l'ébauche du fichier de test + +Comme précédemment, nous générons d'abord l'ébauche du fichier : + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Sortie de la commande" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Cela produit l'ébauche de test suivante : + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Déplacer le fichier de test et mettre à jour le chemin du script + +Cette fois, nous avons déjà un répertoire pour les tests colocalisé avec le fichier `main.nf` du module, nous pouvons donc déplacer le fichier d'ébauche de test là-bas : + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +Et n'oubliez pas de mettre à jour le chemin du script : + +=== "Après" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Avant" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Fournir les entrées + +Remplissez les entrées en fonction des définitions d'entrée du processus et renommez le test en conséquence : + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Utiliser des assertions de contenu + +La sortie de l'étape de génotypage conjoint est un autre fichier VCF, nous allons donc utiliser à nouveau une assertion de contenu. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +En vérifiant le contenu d'un variant spécifique dans le fichier de sortie, ce test vérifie que : + +1. Le processus de génotypage conjoint s'exécute avec succès +2. Le VCF de sortie contient les trois échantillons dans le bon ordre +3. Un variant spécifique est appelé correctement avec : + - Des génotypes précis pour chaque échantillon (0/1 pour le père, 1/1 pour la mère et le fils) + - Des profondeurs de lecture et des qualités de génotype correctes + - Des statistiques au niveau de la population comme la fréquence allélique (AF=0.833) + +Nous n'avons pas fait de snapshot du fichier entier, mais en vérifiant un variant spécifique, nous pouvons être confiants que le processus de génotypage conjoint fonctionne comme prévu. + +### 3.6. Exécuter le test + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +Le test réussit, vérifiant que notre processus de génotypage conjoint : + +1. Combine correctement les VCF d'échantillons individuels +2. Effectue l'appel de variants conjoint +3. Produit un VCF multi-échantillons avec des appels de génotype cohérents entre les exécutions + +### À retenir + +Vous savez comment : + +- Utiliser des résultats précédemment générés comme entrées pour les tests +- Écrire des tests en utilisant des données de test pré-générées + +### Et maintenant ? + +Ajouter un test au niveau du workflow pour vérifier que l'ensemble du pipeline d'appel de variants fonctionne de bout en bout. + +--- + +## 4. Ajouter un test au niveau du workflow + +Nous allons maintenant tester le pipeline complet d'appel de variants, des fichiers BAM aux génotypes conjoints. Cela vérifie que : + +1. Tous les processus fonctionnent correctement ensemble +2. Les données circulent correctement entre les étapes +3. Les appels de variants finaux sont cohérents + +### 4.1. Générer le test de workflow + +Générez un fichier de test pour le pipeline complet : + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Sortie de la commande" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Cela crée une ébauche de test de base : + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Corrigez simplement le nom en quelque chose de significatif (vous verrez pourquoi c'est utile sous peu). + +=== "Après" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Avant" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note + + Dans ce cas, le fichier de test peut rester là où `nf-test` l'a créé. + +### 4.2. Spécifier les paramètres d'entrée + +Nous devons encore spécifier les entrées, ce qui se fait de manière légèrement différente au niveau du workflow par rapport aux tests au niveau du module. +Il existe plusieurs façons de le faire, notamment en spécifiant un profil. +Cependant, une façon plus simple est de configurer un bloc `params {}` dans le fichier `nextflow.config` que `nf-test init` a créé à l'origine dans le répertoire `tests`. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Fichier de configuration Nextflow pour l'exécution des tests +======================================================================================== +*/ + +// Répertoire de sortie pour les sorties du workflow +outputDir = 'results_genomics' + +/* + * Paramètres du pipeline + */ + +params { + // Entrée principale (fichier de fichiers d'entrée, un par ligne) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Fichiers accessoires + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Nom de base pour le fichier de sortie final + cohort_name = "family_trio" +} +``` + +Lorsque nous exécuterons le test, `nf-test` récupérera ce fichier de configuration et importera les entrées en conséquence. + +### 4.3. Exécuter le test de workflow + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +Le test réussit, confirmant que notre pipeline complet d'appel de variants : + +1. Traite avec succès tous les échantillons +2. Enchaîne correctement toutes les étapes + +### 4.4. Exécuter TOUS les tests + +nf-test a encore un tour dans son sac. Nous pouvons exécuter tous les tests en une seule fois ! Modifiez le fichier `nf-test.config` pour que nf-test recherche dans tous les répertoires les fichiers nf-test. Vous pouvez le faire en modifiant le paramètre `testsDir` : + +=== "Après" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Avant" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Maintenant, nous pouvons simplement exécuter nf-test et il exécutera _chaque test unique_ dans notre dépôt : + +```bash +nf-test test +``` + +??? success "Sortie de la commande" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +8 tests en 1 commande ! Nous avons passé beaucoup de temps à configurer de nombreux tests, mais quand il s'agit de les exécuter, c'était très rapide et facile. Vous pouvez voir à quel point c'est utile lors de la maintenance d'un grand pipeline, qui pourrait inclure des centaines d'éléments différents. Nous passons du temps à écrire des tests une fois pour pouvoir gagner du temps en les exécutant plusieurs fois. + +De plus, nous pouvons automatiser cela ! Imaginez que des tests s'exécutent à chaque fois que vous ou un collègue essayez d'ajouter du nouveau code. C'est ainsi que nous nous assurons que nos pipelines maintiennent un niveau de qualité élevé. + +## À retenir + +Vous savez maintenant comment écrire et exécuter plusieurs types de tests pour votre pipeline de génomique en utilisant nf-test. Ce framework de test aide à garantir que votre workflow d'appel de variants produit des résultats cohérents et fiables dans différents environnements et au fur et à mesure que vous apportez des modifications au code. + +Vous avez appris à tester des composants critiques tels que : + +- Le processus `SAMTOOLS_INDEX` qui prépare les fichiers BAM pour l'appel de variants +- Le processus `GATK_HAPLOTYPECALLER` qui identifie les variants dans des échantillons individuels +- Le processus `GATK_JOINTGENOTYPING` qui combine les appels de variants à travers une cohorte + +Vous avez également mis en œuvre différentes stratégies de test spécifiques aux données de génomique : + +- Vérifier que les fichiers VCF contiennent les appels de variants attendus malgré des éléments non déterministes comme les horodatages +- Tester avec un jeu de données de trio familial pour assurer une identification appropriée des variants à travers des échantillons apparentés +- Vérifier des coordonnées génomiques spécifiques et des informations de variants dans vos fichiers de sortie + +Ces compétences en tests sont essentielles pour développer des pipelines de bioinformatique robustes qui peuvent traiter de manière fiable des données génomiques et produire des appels de variants précis. Au fur et à mesure que vous continuez à travailler avec Nextflow pour l'analyse génomique, cette base de tests vous aidera à maintenir un code de haute qualité qui produit des résultats scientifiques dignes de confiance. diff --git a/docs/fr/docs/nf4_science/genomics/05_configuration.md b/docs/fr/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..706c8987ab --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Partie 3 : Profilage et optimisation des ressources + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +CECI EST UN ESPACE RÉSERVÉ + +!!!note "Note" + + Ce module de formation est en cours de refonte. + +--- + +TODO + +### 1.1. Exécuter le workflow pour générer un rapport d'utilisation des ressources + +Pour que Nextflow génère le rapport automatiquement, ajoutez simplement `-with-report <nom_fichier>.html` à votre ligne de commande. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +Le rapport est un fichier html, que vous pouvez télécharger et ouvrir dans votre navigateur. Vous pouvez également faire un clic droit dessus dans l'explorateur de fichiers à gauche et cliquer sur `Show preview` afin de le visualiser dans VS Code. + +Prenez quelques minutes pour parcourir le rapport et voir si vous pouvez identifier des opportunités d'ajustement des ressources. +Assurez-vous de cliquer sur les onglets qui montrent les résultats d'utilisation en pourcentage de ce qui a été alloué. +Il existe une [documentation](https://www.nextflow.io/docs/latest/reports.html) décrivant toutes les fonctionnalités disponibles. + +<!-- TODO: insert images --> + +Une observation est que le processus `GATK_JOINTGENOTYPING` semble être très gourmand en CPU, ce qui est logique puisqu'il effectue de nombreux calculs complexes. +Nous pourrions donc essayer d'augmenter cette allocation et voir si cela réduit le temps d'exécution. + +Cependant, nous semblons avoir surestimé les allocations de mémoire ; tous les processus n'utilisent qu'une fraction de ce que nous leur donnons. +Nous devrions réduire cela et économiser des ressources. + +### 1.2. Ajuster les allocations de ressources pour un processus spécifique + +Nous pouvons spécifier les allocations de ressources pour un processus donné en utilisant le sélecteur de processus `withName`. +La syntaxe ressemble à ceci lorsqu'elle est seule dans un bloc process : + +```groovy title="Syntaxe" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Ajoutons cela au bloc process existant dans le fichier `nextflow.config`. + +```groovy title="nextflow.config" linenums="11" +process { + // valeurs par défaut pour tous les processus + cpus = 2 + memory = 2.GB + // allocations pour un processus spécifique + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Avec cette spécification, les paramètres par défaut s'appliqueront à tous les processus **sauf** au processus `GATK_JOINTGENOTYPING`, qui est un cas particulier recevant beaucoup plus de CPU. +Espérons que cela aura un effet. + +### 1.3. Exécuter à nouveau avec la configuration modifiée + +Exécutons à nouveau le workflow avec la configuration modifiée et avec l'indicateur de rapport activé, mais notez que nous donnons un nom différent au rapport afin de pouvoir les différencier. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Une fois de plus, vous ne remarquerez probablement pas de différence substantielle dans le temps d'exécution, car il s'agit d'une charge de travail si petite et les outils passent plus de temps dans des tâches auxiliaires que dans l'exécution du « vrai » travail. + +Cependant, le deuxième rapport montre que notre utilisation des ressources est maintenant plus équilibrée. + +<!-- **TODO: screenshots?** --> + +Comme vous pouvez le voir, cette approche est utile lorsque vos processus ont des besoins en ressources différents. Elle vous permet d'ajuster précisément les allocations de ressources que vous configurez pour chaque processus en fonction de données réelles, et non de suppositions. + +!!!note "Note" + + Ceci n'est qu'un petit aperçu de ce que vous pouvez faire pour optimiser votre utilisation des ressources. + Nextflow lui-même dispose d'une [logique de nouvelle tentative dynamique](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) vraiment intéressante intégrée pour réessayer les tâches qui échouent en raison de limitations de ressources. + De plus, Seqera Platform offre des outils pilotés par l'IA pour optimiser automatiquement vos allocations de ressources également. + + Nous aborderons ces deux approches dans une prochaine partie de ce cours de formation. + +Cela étant dit, il peut y avoir certaines contraintes sur ce que vous pouvez (ou devez) allouer selon l'exécuteur de calcul et l'infrastructure de calcul que vous utilisez. Par exemple, votre cluster peut vous obliger à rester dans certaines limites qui ne s'appliquent pas lorsque vous exécutez ailleurs. diff --git a/docs/fr/docs/nf4_science/genomics/index.md b/docs/fr/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..6a961ebc61 --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/index.md @@ -0,0 +1,36 @@ +# Nextflow pour la Génomique + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Cette formation est destinée aux chercheurs en génomique et domaines connexes qui souhaitent développer ou personnaliser des pipelines d'analyse de données. +Elle s'appuie sur la formation pour débutants [Hello Nextflow](../../hello_nextflow/) et démontre comment utiliser Nextflow dans le contexte spécifique du domaine de la génomique. + +Plus précisément, ce cours démontre comment implémenter un pipeline simple d'appel de variants avec [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit), un ensemble logiciel largement utilisé pour l'analyse de données de séquençage à haut débit. + +Commençons ! Cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous pour lancer l'environnement de formation (de préférence dans un onglet séparé), puis poursuivez la lecture pendant le chargement. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objectifs pédagogiques + +En suivant ce cours, vous apprendrez comment appliquer les concepts et outils fondamentaux de Nextflow à un cas d'usage typique en génomique. + +À la fin de cet atelier, vous serez capable de : + +- Écrire un workflow linéaire pour appliquer l'appel de variants à un seul échantillon +- Gérer correctement les fichiers accessoires tels que les fichiers d'index et les ressources du génome de référence +- Exploiter le paradigme de flux de données de Nextflow pour paralléliser l'appel de variants par échantillon +- Implémenter l'appel de variants multi-échantillons en utilisant les opérateurs de canaux appropriés +- Implémenter des tests par étape et de bout en bout qui gèrent correctement les particularités spécifiques à la génomique + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Prérequis + +Le cours suppose une familiarité minimale avec les éléments suivants : + +- Outils et formats de fichiers couramment utilisés dans ce domaine scientifique +- Expérience avec la ligne de commande +- Concepts et outils fondamentaux de Nextflow couverts dans la formation pour débutants [Hello Nextflow](../../hello_nextflow/) + +Pour les exigences techniques et la configuration de l'environnement, consultez le mini-cours [Configuration de l'Environnement](../../envsetup/). diff --git a/docs/fr/docs/nf4_science/genomics/next_steps.md b/docs/fr/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..b7c8f329ea --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Prochaines Étapes + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations encore pour avoir terminé la formation Nextflow pour la Génomique et merci d'avoir répondu à notre enquête ! + +--- + +## 1. Top 3 des moyens d'améliorer vos compétences Nextflow + +Voici nos trois principales recommandations pour la suite, basées sur le cours que vous venez de terminer. + +### 1.1. Appliquer Nextflow à d'autres cas d'usage d'analyse scientifique + +**Consultez la page [Nextflow for Science](../index.md)** pour une liste d'autres cours courts et autonomes qui démontrent comment appliquer les concepts de base et les mécanismes présentés dans Hello Nextflow à des cas d'usage courants d'analyse scientifique. + +Si vous ne voyez pas votre domaine représenté par un cas d'usage pertinent, faites-le nous savoir sur le [forum communautaire](https://community.seqera.io/) afin que nous puissions l'ajouter à notre liste de développement. + +### 1.2. Commencer avec nf-core + +**[nf-core](https://nf-co.re/)** est un effort collaboratif mondial visant à développer des pipelines open-source standardisés pour un large éventail d'applications de recherche scientifique. +Le projet comprend [plus de 100 pipelines](https://nf-co.re/pipelines/) disponibles prêts à l'emploi et [bien plus de 1400 modules de processus](https://nf-co.re/modules/) qui peuvent être intégrés dans vos propres projets, ainsi qu'un riche ensemble d'outils de développement. + +Le cours de formation **[Hello nf-core](../../hello_nf-core/index.md)** vous présentera les pipelines organisés par la communauté nf-core et le framework de développement, conçu pour vous aider à écrire des workflows reproductibles, évolutifs et standardisés. Vous apprendrez à utiliser les pipelines nf-core existants, à contribuer à leur développement, et même à commencer à construire les vôtres, soutenus par les meilleures pratiques et une communauté dynamique. Si vous êtes prêt à appliquer vos compétences Nextflow dans des projets concrets, c'est l'étape suivante idéale. + +### 1.3. Maîtriser les fonctionnalités avancées de Nextflow + +Dans les cours Hello, nous maintenons intentionnellement un niveau de complexité technique bas pour éviter de vous surcharger d'informations dont vous n'avez pas besoin pour débuter avec Nextflow. +Au fur et à mesure que vous progresserez dans votre travail, vous voudrez apprendre à utiliser l'ensemble complet des fonctionnalités et la puissance de Nextflow. + +À cette fin, nous travaillons actuellement sur une **collection de [Side Quests](../side_quests/index.md)**, qui sont des cours courts et autonomes approfondissant des sujets spécifiques comme les tests et la gestion des métadonnées. + +--- + +## 2. Découvrez Seqera Platform + +**[Seqera Platform](https://seqera.io/) est la meilleure façon d'exécuter Nextflow en pratique.** + +Il s'agit d'une plateforme cloud développée par les créateurs de Nextflow que vous pouvez connecter à votre propre infrastructure de calcul (qu'elle soit locale, HPC ou cloud) pour faciliter grandement le lancement et la gestion de vos workflows, ainsi que la gestion de vos données et l'exécution d'analyses de manière interactive dans un environnement cloud. + +Le niveau gratuit (Free Tier) est disponible gratuitement pour tous (avec des quotas d'utilisation). +Les universitaires éligibles peuvent obtenir un accès gratuit au niveau Pro (sans limitations d'utilisation) via le [Programme Académique](https://seqera.io/academic/program/). + +Consultez les [tutoriels Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) pour voir si cela pourrait vous être utile. + +--- + +### C'est tout pour le moment ! + +**Bonne chance dans votre parcours Nextflow et n'hésitez pas à nous faire savoir sur le [forum communautaire](https://community.seqera.io/) ce que nous pourrions faire d'autre pour vous aider.** diff --git a/docs/fr/docs/nf4_science/genomics/survey.md b/docs/fr/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..35fb57ac96 --- /dev/null +++ b/docs/fr/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Questionnaire de retour d'expérience + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Avant de continuer, veuillez compléter ce court questionnaire de 5 questions pour évaluer la formation, partager vos commentaires sur votre expérience et nous faire savoir ce que nous pourrions faire d'autre pour vous aider dans votre parcours Nextflow. + +Cela devrait vous prendre moins d'une minute. Merci de nous aider à améliorer nos supports de formation pour tous ! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/fr/docs/nf4_science/imaging/00_orientation.md b/docs/fr/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..f087e1d546 --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Cette orientation suppose que vous avez déjà ouvert l'environnement de formation en cliquant sur le bouton "Open in GitHub Codespaces". +Si ce n'est pas le cas, veuillez le faire maintenant, idéalement dans une seconde fenêtre ou un second onglet de navigateur afin de pouvoir vous référer à ces instructions. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Exigence de taille de machine" + + Assurez-vous de sélectionner une **machine à 8 cœurs** lors de la création de votre Codespace pour cette formation. Les workflows de bio-imagerie nécessitent des ressources de calcul supplémentaires. + +## GitHub Codespaces + +L'environnement GitHub Codespaces contient tous les logiciels, le code et les données nécessaires pour suivre cette formation, vous n'avez donc rien à installer vous-même. +Cependant, vous avez besoin d'un compte GitHub (gratuit) pour vous connecter, et si vous n'êtes pas familier avec l'interface, vous devriez prendre quelques minutes pour vous familiariser en complétant le mini-cours [Orientation GitHub Codespaces](../../envsetup/index.md). + +## Pré-téléchargement des images Docker + +Une fois que vous avez ouvert votre Codespace, pré-téléchargeons toutes les images Docker dont nous aurons besoin pour cette formation. +Cela fera gagner du temps plus tard et garantira une exécution fluide des workflows. + +Ouvrez un nouvel onglet de terminal et exécutez la commande suivante : + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Cette commande téléchargera toutes les images Docker nécessaires en arrière-plan. +Vous pouvez continuer avec le reste de l'orientation pendant que cela s'exécute. + +!!!tip "Astuce" + + Le flag `-stub` permet au pipeline de s'exécuter rapidement sans traiter de vraies données, ce qui est parfait pour télécharger les images. Vous pouvez surveiller la progression dans l'onglet du terminal. + +## Répertoire de travail + +Tout au long de cette formation, nous travaillerons dans le répertoire `nf4-science/imaging/`. + +Changez de répertoire maintenant en exécutant cette commande dans le terminal : + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "Astuce" + + Si pour une raison quelconque vous sortez de ce répertoire, vous pouvez toujours utiliser le chemin complet pour y revenir, en supposant que vous travaillez dans l'environnement de formation GitHub Codespaces : + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Maintenant, pour commencer la formation, cliquez sur la flèche dans le coin inférieur droit de cette page.** diff --git a/docs/fr/docs/nf4_science/imaging/01_basics.md b/docs/fr/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..2100cd77ff --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Partie 1 : Exécuter des opérations de base + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette première partie du cours de formation Nextflow pour la bio-imagerie, nous allons utiliser un exemple Hello World très basique et indépendant du domaine pour démontrer les opérations essentielles et identifier les composants de code Nextflow correspondants. + +## 1. Exécuter le workflow + +Nous vous fournissons un script de workflow nommé `hello-world.nf` qui prend une entrée via un argument de ligne de commande nommé `--greeting` et produit un fichier texte contenant ce message de salutation. +Nous n'allons pas encore examiner le code ; voyons d'abord à quoi ressemble son exécution. + +### 1.1. Lancer le workflow et surveiller l'exécution + +Dans le terminal, exécutez la commande suivante : + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +La sortie de votre console devrait ressembler à ceci : + +```console title="Sortie" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Félicitations, vous venez d'exécuter votre premier workflow Nextflow ! + +La sortie la plus importante ici est la dernière ligne (ligne 6) : + +```console title="Sortie" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Cela nous indique que le processus `sayHello` a été exécuté avec succès une fois (`1 of 1 ✔`). + +C'est parfait, mais vous vous demandez peut-être : où se trouve la sortie ? + +### 1.2. Trouver le fichier de sortie dans le répertoire `results` + +Ce workflow est configuré pour publier sa sortie dans un répertoire appelé `results`. +Si vous regardez votre répertoire actuel, vous verrez que lorsque vous avez exécuté le workflow, Nextflow a créé un nouveau répertoire appelé `results`, qui contient un fichier appelé `output.txt`. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Ouvrez le fichier ; le contenu devrait correspondre au message de salutation que vous avez spécifié sur la ligne de commande. + +<details> + <summary>Contenu du fichier</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +C'est parfait, notre workflow a fait ce qu'il était censé faire ! + +Cependant, sachez que le résultat 'publié' est une copie (ou dans certains cas un lien symbolique) de la sortie réelle produite par Nextflow lors de l'exécution du workflow. + +Maintenant, nous allons regarder sous le capot pour voir où Nextflow a réellement effectué le travail. + +!!! warning "Avertissement" + + Tous les workflows ne seront pas configurés pour publier les sorties dans un répertoire results, et/ou le nom du répertoire peut être différent. + Un peu plus loin dans cette section, nous vous montrerons comment découvrir où ce comportement est spécifié. + +### 1.3. Trouver la sortie originale et les logs dans le répertoire `work/` + +Lorsque vous exécutez un workflow, Nextflow crée un 'répertoire de tâche' distinct pour chaque invocation de chaque processus dans le workflow (=chaque étape du pipeline). +Pour chacun, il va préparer les entrées nécessaires, exécuter la ou les instruction(s) pertinente(s) et écrire les sorties et les fichiers de log dans ce répertoire unique, qui est nommé automatiquement à l'aide d'un hash afin de le rendre unique. + +Tous ces répertoires de tâches se trouveront dans un répertoire appelé `work` dans votre répertoire actuel (où vous exécutez la commande). + +Cela peut sembler déroutant, alors voyons à quoi cela ressemble en pratique. + +En revenant à la sortie console du workflow que nous avons exécuté précédemment, nous avions cette ligne : + +```console title="Extrait de la sortie de la commande" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Voyez comment la ligne commence par `[a3/7be2fa]` ? +C'est une forme tronquée du chemin du répertoire de tâche pour cet appel de processus particulier, et vous indique où trouver la sortie de l'appel du processus `sayHello` dans le chemin du répertoire `work/`. + +Vous pouvez trouver le chemin complet en tapant la commande suivante (en remplaçant `a3/7be2fa` par ce que vous voyez dans votre propre terminal) et en appuyant sur la touche tab pour compléter automatiquement le chemin ou en ajoutant un astérisque : + +```bash +tree work/a3/7be2fa* +``` + +Cela devrait donner le chemin complet du répertoire : `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Voyons ce qu'il y a dedans. + +!!! Tip "Astuce" + + Si vous parcourez le contenu du sous-répertoire de tâche dans l'explorateur de fichiers de VSCode, vous verrez tous les fichiers immédiatement. + Cependant, les fichiers de log sont configurés pour être invisibles dans le terminal, donc si vous voulez utiliser `ls` ou `tree` pour les voir, vous devrez définir l'option pertinente pour afficher les fichiers invisibles. + + ```bash + tree -a work + ``` + +Les noms exacts des sous-répertoires seront différents sur votre système. + +<details> + <summary>Contenu du répertoire</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Vous devriez immédiatement reconnaître le fichier `output.txt`, qui est en fait la sortie originale du processus `sayHello` qui a été publiée dans le répertoire `results`. +Si vous l'ouvrez, vous retrouverez le message de salutation `Hello World!`. + +<details> + <summary>Contenu du fichier output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +Alors, qu'en est-il de tous ces autres fichiers ? + +Ce sont les fichiers d'aide et de log que Nextflow a écrits dans le cadre de l'exécution de la tâche : + +- **`.command.begin`** : Fichier sentinelle créé dès que la tâche est lancée. +- **`.command.err`** : Messages d'erreur (`stderr`) émis par l'appel du processus +- **`.command.log`** : Sortie de log complète émise par l'appel du processus +- **`.command.out`** : Sortie normale (`stdout`) par l'appel du processus +- **`.command.run`** : Script complet exécuté par Nextflow pour exécuter l'appel du processus +- **`.command.sh`** : La commande qui a réellement été exécutée par l'appel du processus +- **`.exitcode`** : Le code de sortie résultant de la commande + +Le fichier `.command.sh` est particulièrement utile car il vous montre la commande principale que Nextflow a exécutée, sans inclure toute la gestion administrative et la configuration de la tâche/environnement. + +<details> + <summary>Contenu du fichier</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Astuce" + + Lorsque quelque chose ne va pas et que vous devez résoudre le problème, il peut être utile de regarder le script `command.sh` pour vérifier exactement quelle commande Nextflow a composée en fonction des instructions du workflow, de l'interpolation des variables, etc. + +### 1.4. Exercice optionnel : ré-exécuter avec différents messages de salutation + +Essayez de ré-exécuter le workflow plusieurs fois avec différentes valeurs pour l'argument `--greeting`, puis regardez à la fois le contenu du répertoire `results/` et les répertoires de tâches. + +Observez comment les sorties et les logs des répertoires de tâches isolés sont préservés, alors que le contenu du répertoire `results` est écrasé par la sortie des exécutions suivantes. + +### À retenir + +Vous savez comment exécuter un script Nextflow simple, surveiller son exécution et trouver ses sorties. + +### Et ensuite ? + +Apprenez à lire un script Nextflow de base et à identifier comment ses composants sont liés à ses fonctionnalités. + +--- + +## 2. Examiner le script de démarrage du workflow Hello World + +Ce que nous avons fait là, c'était essentiellement traiter le script de workflow comme une boîte noire. +Maintenant que nous avons vu ce qu'il fait, ouvrons la boîte et regardons à l'intérieur. + +_L'objectif ici n'est pas de mémoriser la syntaxe du code Nextflow, mais de former une intuition de base de quels sont les composants principaux et comment ils sont organisés._ + +### 2.1. Examiner la structure générale du code + +Ouvrons le script `hello-world.nf` dans le volet de l'éditeur. + +<details> + <summary>Code</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Utilise echo pour imprimer une salutation dans un fichier + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // émettre une salutation + sayHello(params.greeting) +} +``` + +</details> + +Un script Nextflow implique deux types principaux de composants de base : un ou plusieurs **processus**, et le **workflow** lui-même. +Chaque **processus** décrit quelle(s) opération(s) l'étape correspondante du pipeline doit accomplir, tandis que le **workflow** décrit la logique de flux de données qui connecte les différentes étapes. + +Examinons d'abord de plus près le bloc **process**, puis nous examinerons le bloc **workflow**. + +### 2.2. La définition du `process` + +Le premier bloc de code décrit un **processus**. +La définition du processus commence par le mot-clé `process`, suivi du nom du processus et enfin du corps du processus délimité par des accolades. +Le corps du processus doit contenir un bloc script qui spécifie la commande à exécuter, qui peut être n'importe quoi que vous seriez capable d'exécuter dans un terminal de ligne de commande. + +Ici, nous avons un **processus** appelé `sayHello` qui prend une variable d'**entrée** appelée `greeting` et écrit sa **sortie** dans un fichier nommé `output.txt`. + +<details> + <summary>Code</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Utilise echo pour imprimer une salutation dans un fichier + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +C'est une définition de processus très minimale qui contient juste une définition d'`input`, une définition d'`output` et le `script` à exécuter. + +La définition d'`input` inclut le qualificateur `val`, qui indique à Nextflow de s'attendre à une valeur d'un certain type (peut être une chaîne, un nombre, peu importe). + +La définition d'`output` inclut le qualificateur `path`, qui indique à Nextflow que cela doit être traité comme un chemin (inclut à la fois les chemins de répertoires et les fichiers). + +!!! Tip "Astuce" + + La définition de sortie ne _détermine_ pas quelle sortie sera créée. + Elle _déclare_ simplement où trouver le(s) fichier(s) de sortie attendu(s), afin que Nextflow puisse le chercher une fois l'exécution terminée. + + Ceci est nécessaire pour vérifier que la commande a été exécutée avec succès et pour transmettre la sortie aux processus en aval si nécessaire. + Les sorties produites qui ne correspondent pas à ce qui est déclaré dans le bloc de sortie ne seront pas transmises aux processus en aval. + +Dans un pipeline réel, un processus contient généralement des informations supplémentaires telles que des directives de processus, que nous présenterons dans un instant. + +### 2.3. La définition du `workflow` + +Le deuxième bloc de code décrit le **workflow** lui-même. +La définition du workflow commence par le mot-clé `workflow`, suivi d'un nom optionnel, puis du corps du workflow délimité par des accolades. + +Ici, nous avons un **workflow** qui consiste en un appel au processus `sayHello`, qui prend une entrée, `params.greeting`, qui contient la valeur que nous avons donnée au paramètre `--greeting`. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // émettre une salutation + sayHello(params.greeting) +} +``` + +C'est une définition de **workflow** très minimale. +Dans un pipeline réel, le workflow contient généralement plusieurs appels à des **processus** connectés par des **canaux**, et il peut y avoir des valeurs par défaut configurées pour les entrées variables. + +Nous verrons cela en action lorsque nous exécuterons nf-core/molkart dans la Partie 2 du cours. + +### 2.4. Le système `params` de paramètres de ligne de commande + +Le `params.greeting` que nous fournissons à l'appel du processus `sayHello()` est un élément intéressant du code Nextflow et mérite qu'on y consacre une minute supplémentaire. + +Comme mentionné ci-dessus, c'est ainsi que nous transmettons la valeur du paramètre de ligne de commande `--greeting` à l'appel du processus `sayHello()`. +En fait, le simple fait de déclarer `params.someParameterName` nous permettra de donner au workflow un paramètre nommé `--someParameterName` depuis la ligne de commande. + +!!! Tip "Astuce" + + Ces paramètres de workflow déclarés à l'aide du système `params` prennent toujours deux tirets (`--`). + Cela les distingue des paramètres au niveau de Nextflow, qui ne prennent qu'un seul tiret (`-`). + +### À retenir + +Vous savez maintenant comment un workflow Nextflow simple est structuré, et comment les composants de base sont liés à ses fonctionnalités. + +### Et ensuite ? + +Apprenez à gérer vos exécutions de workflow de manière pratique. + +--- + +## 3. Gérer les exécutions de workflow + +Savoir comment lancer des workflows et récupérer les sorties est excellent, mais vous découvrirez rapidement qu'il existe quelques autres aspects de la gestion des workflows qui vous faciliteront la vie. + +Nous vous montrons ici comment profiter de la fonctionnalité `resume` lorsque vous devez relancer le même workflow, comment inspecter les logs d'exécution avec `nextflow log`, et comment supprimer les anciens répertoires work avec `nextflow clean`. + +### 3.1. Relancer un workflow avec `-resume` + +Parfois, vous voudrez ré-exécuter un pipeline que vous avez déjà lancé précédemment sans refaire le travail qui a déjà été effectué avec succès. + +Nextflow a une option appelée `-resume` qui vous permet de faire cela. +Plus précisément, dans ce mode, tous les processus qui ont déjà été exécutés avec exactement le même code, les mêmes paramètres et les mêmes entrées seront ignorés. +Cela signifie que Nextflow n'exécutera que les processus que vous avez ajoutés ou modifiés depuis la dernière exécution, ou auxquels vous fournissez de nouveaux paramètres ou entrées. + +Il y a deux avantages clés à faire cela : + +- Si vous êtes en train de développer un pipeline, vous pouvez itérer plus rapidement puisque vous n'avez qu'à exécuter le(s) processus sur le(s)quel(s) vous travaillez activement pour tester vos modifications. +- Si vous exécutez un pipeline en production et que quelque chose ne va pas, dans de nombreux cas vous pouvez corriger le problème et relancer le pipeline, et il reprendra l'exécution à partir du point de défaillance, ce qui peut vous faire gagner beaucoup de temps et de calcul. + +Pour l'utiliser, ajoutez simplement `-resume` à votre commande et exécutez-la : + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Recherchez le bit `cached:` qui a été ajouté dans la ligne de statut du processus (ligne 5), ce qui signifie que Nextflow a reconnu qu'il a déjà fait ce travail et a simplement réutilisé le résultat de l'exécution précédente réussie. + +Vous pouvez également voir que le hash du sous-répertoire work est le même que lors de l'exécution précédente. +Nextflow vous indique littéralement l'exécution précédente et dit « J'ai déjà fait ça là-bas. » + +!!! Tip "Astuce" + + Lorsque vous ré-exécutez un pipeline avec `resume`, Nextflow n'écrase aucun fichier écrit dans un répertoire `publishDir` par un appel de processus qui a été précédemment exécuté avec succès. + +### 3.2. Inspecter le log des exécutions passées + +Chaque fois que vous lancez un workflow nextflow, une ligne est écrite dans un fichier de log appelé `history`, dans un répertoire caché appelé `.nextflow` dans le répertoire de travail actuel. + +Une façon plus pratique d'accéder à cette information est d'utiliser la commande `nextflow log`. + +```bash +nextflow log +``` + +Cela affichera le contenu du fichier de log dans le terminal, vous montrant l'horodatage, le nom de l'exécution, le statut et la ligne de commande complète pour chaque exécution Nextflow qui a été lancée depuis le répertoire de travail actuel. + +### 3.3. Supprimer les anciens répertoires work + +Pendant le processus de développement, vous exécuterez généralement vos projets de pipelines un grand nombre de fois, ce qui peut conduire à une accumulation de très nombreux fichiers dans de nombreux sous-répertoires. +Comme les sous-répertoires sont nommés aléatoirement, il est difficile de dire d'après leurs noms lesquels sont des exécutions plus anciennes ou plus récentes. + +Nextflow inclut une sous-commande `clean` pratique qui peut automatiquement supprimer les sous-répertoires work pour les exécutions passées qui ne vous intéressent plus, avec plusieurs [options](https://www.nextflow.io/docs/latest/reference/cli.html#clean) pour contrôler ce qui sera supprimé. + +Vous pouvez utiliser le log Nextflow pour rechercher une exécution en fonction de son horodatage et/ou de sa ligne de commande, puis utiliser `nextflow clean -before <run_name> -f` pour supprimer les répertoires work des exécutions antérieures. + +!!! Warning "Avertissement" + + La suppression des sous-répertoires work des exécutions passées les supprime du cache de Nextflow et supprime toutes les sorties qui étaient stockées dans ces répertoires. + Cela signifie que cela brise la capacité de Nextflow à reprendre l'exécution sans ré-exécuter les processus correspondants. + + Vous êtes responsable de la sauvegarde de toutes les sorties qui vous intéressent ou sur lesquelles vous prévoyez de vous appuyer ! Si vous utilisez la directive `publishDir` à cette fin, assurez-vous d'utiliser le mode `copy`, pas le mode `symlink`. + +### À retenir + +Vous savez comment relancer un pipeline sans répéter les étapes qui ont déjà été exécutées de manière identique, inspecter le log d'exécution, et utiliser la commande `nextflow clean` pour nettoyer les anciens répertoires work. + +### Et ensuite ? + +Maintenant que vous comprenez les opérations de base de Nextflow, vous êtes prêt à exécuter un véritable pipeline de bio-imagerie avec nf-core/molkart. diff --git a/docs/fr/docs/nf4_science/imaging/02_run_molkart.md b/docs/fr/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..77044a6684 --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Partie 2 : Exécuter nf-core/molkart + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la Partie 1, nous avons exécuté un workflow simple Hello World pour comprendre les bases de l'exécution de Nextflow. +Nous allons maintenant exécuter un véritable pipeline de bio-imagerie : **nf-core/molkart**. + +Ce pipeline traite les données de transcriptomique spatiale Molecular Cartography de Resolve Bioscience. +Cependant, les modèles Nextflow que vous apprendrez ici s'appliquent à n'importe quel pipeline nf-core ou workflow de production. + +## 1. Comprendre les pipelines nf-core + +Avant d'exécuter le pipeline, comprenons ce qu'est nf-core et pourquoi c'est important pour l'exécution de workflows. + +### 1.1. Qu'est-ce que nf-core ? + +[nf-core](https://nf-co.re/) est une collection pilotée par la communauté de pipelines Nextflow de haute qualité. +Tous les pipelines nf-core suivent la même structure et les mêmes conventions, ce qui signifie qu'une fois que vous avez appris à en exécuter un, vous pouvez tous les exécuter. + +Caractéristiques clés des pipelines nf-core : + +- **Structure standardisée** : Tous les pipelines ont des noms de paramètres et des modèles d'utilisation cohérents +- **Données de test intégrées** : Chaque pipeline inclut des profils de test pour une validation rapide +- **Documentation complète** : Instructions d'utilisation détaillées et descriptions des paramètres +- **Contrôle qualité** : Rapports de QC automatisés utilisant MultiQC +- **Support des conteneurs** : Conteneurs pré-construits pour la reproductibilité + +!!! tip "Vous voulez en savoir plus sur nf-core ?" + + Pour une introduction approfondie au développement de pipelines nf-core, consultez le cours de formation [Hello nf-core](../../hello_nf-core/index.md). + Il couvre comment créer et personnaliser des pipelines nf-core à partir de zéro. + +### 1.2. Le pipeline molkart + +![Pipeline nf-core/molkart](img/molkart.png) + +Le pipeline [nf-core/molkart](https://nf-co.re/molkart) traite les données d'imagerie de transcriptomique spatiale à travers plusieurs étapes : + +1. **Prétraitement d'image** : Remplissage de motif de grille et amélioration optionnelle du contraste +2. **Segmentation cellulaire** : Plusieurs options d'algorithmes (Cellpose, Mesmer, ilastik, Stardist) +3. **Attribution de spots** : Attribuer les spots de transcrit aux cellules segmentées +4. **Contrôle qualité** : Générer des rapports de QC complets + +Les sorties clés sont : + +- Tables de comptage cellule par transcrit +- Masques de segmentation +- Rapport de contrôle qualité MultiQC + +--- + +## 2. Exécuter molkart avec des données de test + +Avant de commencer, clonons le dépôt molkart localement afin de pouvoir inspecter son code : + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Cela crée un répertoire `molkart/` contenant le code source complet du pipeline. + +!!! note "Pourquoi clonons-nous localement ?" + + Typiquement, vous exécuteriez les pipelines nf-core directement depuis GitHub en utilisant `nextflow run nf-core/molkart -r 1.2.0`. + Nextflow télécharge automatiquement la version du pipeline demandée pour vous dans `$HOME/.nextflow/assets/nf-core/molkart` et l'exécute à partir de là. + Cependant, pour cette formation, nous clonons le pipeline dans un répertoire local différent afin de pouvoir inspecter plus facilement le code. + +### 2.1. Comprendre les exigences en matière de conteneurs + +Avant d'exécuter le pipeline complet, apprenons pourquoi les conteneurs sont essentiels pour les pipelines nf-core. + +Essayons d'exécuter le pipeline en utilisant l'ensemble de données de test et les paramètres de la configuration de test molkart : + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Décomposons ces paramètres : + +- `--input` : Chemin vers la feuille d'échantillons contenant les métadonnées des échantillons +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum` : Paramètres pour le remplissage de motif de grille +- `--clahe_pyramid_tile` : Taille du noyau pour l'amélioration du contraste +- `--segmentation_method` : Quel(s) algorithme(s) utiliser pour la segmentation cellulaire +- `--outdir` : Où enregistrer les résultats + +!!! Warning "Cette commande échouera - c'est intentionnel !" + + Nous exécutons délibérément cela sans conteneurs pour démontrer pourquoi ils sont nécessaires. + +Après quelques instants, vous verrez une erreur comme celle-ci : + +??? failure "Sortie de la commande" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**Que se passe-t-il ici ?** + +L'erreur `command not found` (statut de sortie 127) signifie que Nextflow a essayé d'exécuter `duplicate_finder.py` mais n'a pas pu le trouver sur votre système. +C'est parce que : + +1. Le pipeline attend que des logiciels bioinformatiques spécialisés soient installés +2. Ces outils (comme `duplicate_finder.py`, `apply_clahe.dask.py`, etc.) ne font pas partie des distributions Linux standard +3. Sans conteneurs, Nextflow essaie d'exécuter les commandes directement sur votre machine locale + +**D'où ces outils sont-ils censés provenir ?** + +Inspectons l'un des modules de processus pour voir comment il déclare ses exigences logicielles. + +Ouvrez le module de prétraitement CLAHE : + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Regardez la ligne 5 - vous verrez : + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Cette ligne indique à Nextflow : « Pour exécuter ce processus, utilisez l'image Docker `ghcr.io/schapirolabor/molkart-local:v0.0.4`, qui contient tous les logiciels requis. » + +Chaque processus déclare quelle image de conteneur fournit ses outils requis. +Cependant, Nextflow n'utilise ces conteneurs que si vous lui dites de le faire ! + +**La solution : Activer Docker dans la configuration** + +### 2.2. Configurer Docker et lancer le pipeline + +Pour activer Docker, nous devons changer `docker.enabled` de `false` à `true` dans le fichier `nextflow.config`. + +Ouvrez le fichier de configuration : + +```bash +code nextflow.config +``` + +Changez `docker.enabled = false` en `docker.enabled = true` : + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Maintenant, exécutez à nouveau le pipeline avec la même commande : + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Cette fois, Nextflow va : + +1. Lire le paramètre `docker.enabled = true` de la configuration +2. Récupérer les images Docker requises (première fois seulement) +3. Exécuter chaque processus à l'intérieur de son conteneur spécifié +4. S'exécuter avec succès car tous les outils sont disponibles à l'intérieur des conteneurs + +!!! Tip "Pourquoi les conteneurs sont importants" + + La plupart des pipelines nf-core **nécessitent** la conteneurisation (Docker, Singularity, Podman, etc.) car : + + - Ils utilisent des logiciels bioinformatiques spécialisés non disponibles dans les environnements standard + - Les conteneurs garantissent la reproductibilité - exactement les mêmes versions de logiciels s'exécutent partout + - Vous n'avez pas besoin d'installer manuellement des dizaines d'outils et leurs dépendances + + Pour plus de détails sur les conteneurs dans Nextflow, consultez [Hello Containers](../../hello_nextflow/05_hello_containers.md) de la formation Hello Nextflow. + +### 2.3. Surveiller l'exécution + +Pendant l'exécution du pipeline, vous verrez une sortie similaire à ceci : + +??? success "Sortie de la commande" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Remarquez comment cette sortie est plus détaillée que notre exemple Hello World en raison des conventions nf-core que le pipeline suit : + +- Le pipeline affiche sa version et son logo +- Les paramètres de configuration sont affichés +- Plusieurs processus s'exécutent en parallèle (indiqué par plusieurs lignes de processus) +- Les noms de processus incluent le chemin complet du module (par ex., `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Comprendre l'exécution des processus + +La ligne executor `executor > local (22)` vous indique : + +- **executor** : Quel environnement de calcul est utilisé (`local` = votre machine) +- **(22)** : Nombre total de tâches lancées + +Chaque ligne de processus montre : + +- **Hash** (`[1a/2b3c4d]`) : Identifiant du répertoire de travail (comme avant) +- **Nom du processus** : Chemin complet du module et nom du processus +- **Identifiant d'entrée** : Nom de l'échantillon entre parenthèses +- **Progression** : Pourcentage terminé et comptage (par ex., `1 of 1 ✔`) + +### À retenir + +Vous savez comment lancer un pipeline nf-core avec des données de test et interpréter sa sortie d'exécution. + +### Et maintenant ? + +Apprenez où trouver les résultats et comment les interpréter. + +--- + +## 3. Trouver et examiner les sorties + +Lorsque le pipeline se termine avec succès, vous verrez un message de complétion et un résumé d'exécution. + +### 3.1. Localiser le répertoire des résultats + +Par défaut, les pipelines nf-core écrivent les sorties dans un répertoire spécifié par le paramètre `outdir`, que nous avons défini sur `results/`. + +Listez le contenu : + +```bash +tree results/ +``` + +Vous devriez voir plusieurs sous-répertoires : + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Chaque sous-répertoire contient des sorties d'une étape spécifique du pipeline : + +- **mindagap/** : Images remplies par grille de l'étape de prétraitement MindaGap +- **clahe/** : Images avec contraste amélioré du prétraitement CLAHE +- **stack/** : Piles d'images multi-canaux créées pour la segmentation +- **segmentation/** : Résultats de segmentation de différents algorithmes (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/** : Tables de comptage cellule par transcrit +- **anndata/** : Objets AnnData contenant des matrices cellule par transcrit et des coordonnées spatiales +- **molkartqc/** : Métriques de contrôle qualité pour l'attribution de spots +- **multiqc/** : Rapport complet de contrôle qualité +- **pipeline_info/** : Rapports d'exécution et journaux + +### 3.2. Examiner le rapport MultiQC + +Le rapport MultiQC est un fichier HTML complet qui agrège les métriques de qualité de toutes les étapes du pipeline. + +Ouvrez le rapport dans l'explorateur de fichiers puis cliquez sur le bouton « Show Preview » pour le voir rendu directement dans VS Code. + +Le rapport inclut : + +- Statistiques générales pour tous les échantillons +- Métriques de prétraitement +- Métriques de qualité de segmentation +- Nombre de cellules et de spots détectés + +!!! Tip + + Les rapports MultiQC sont généralement inclus dans tous les pipelines nf-core. + Ils fournissent toujours un aperçu de haut niveau de l'exécution du pipeline et de la qualité des données. + +### 3.3. Examiner les tables cellule par transcrit + +La sortie scientifique la plus importante est la table de comptage cellule par transcrit. +Cela vous indique combien de chaque transcrit a été détecté dans chaque cellule. + +Naviguez vers le répertoire spot2cell : + +```bash +ls results/spot2cell/ +``` + +Vous trouverez des fichiers comme : + +- `cellxgene_mem_only_cellpose.csv` : Table cellule par transcrit utilisant la segmentation Cellpose +- `cellxgene_mem_only_mesmer.csv` : Table cellule par transcrit utilisant la segmentation Mesmer +- `cellxgene_mem_only_stardist.csv` : Table cellule par transcrit utilisant la segmentation Stardist + +Nous n'avons exécuté qu'un seul échantillon dans cet ensemble de données de test, mais dans une expérience réelle, nous aurions ces tables pour chaque échantillon. +Remarquez comment Nextflow est capable de traiter plusieurs méthodes de segmentation en parallèle, facilitant la comparaison des résultats. + +### 3.4. Voir les rapports d'exécution + +Nextflow génère automatiquement plusieurs rapports d'exécution. + +Vérifiez le répertoire pipeline_info : + +```bash +ls results/pipeline_info/ +``` + +Fichiers clés : + +- **execution_report.html** : Chronologie et visualisation de l'utilisation des ressources +- **execution_timeline.html** : Diagramme de Gantt de l'exécution des processus +- **execution_trace.txt** : Métriques détaillées d'exécution des tâches +- **pipeline_dag.html** : Graphe acyclique dirigé montrant la structure du workflow + +Ouvrez le rapport d'exécution pour voir l'utilisation des ressources : + +```bash +code results/pipeline_info/execution_report.html +``` + +Cela montre : + +- Combien de temps chaque processus a pris +- Utilisation du CPU et de la mémoire +- Quelles tâches ont été mises en cache ou exécutées + +!!! Tip + + Ces rapports sont incroyablement utiles pour optimiser l'allocation des ressources et dépanner les problèmes de performance. + +### À retenir + +Vous savez comment localiser les sorties du pipeline, examiner les rapports de contrôle qualité et accéder aux métriques d'exécution. + +### Et maintenant ? + +Apprenez le répertoire de travail et comment Nextflow gère les fichiers intermédiaires. + +--- + +## 4. Explorer le répertoire de travail + +Tout comme avec notre exemple Hello World, tout le travail réel se passe dans le répertoire `work/`. + +### 4.1. Comprendre la structure du répertoire de travail + +Le répertoire de travail contient un sous-répertoire pour chaque tâche qui a été exécutée. +Pour ce pipeline avec 12 tâches, il y aura 12 sous-répertoires de travail. + +Listez le répertoire de travail : + +```bash +ls -d work/*/*/ | head -5 +``` + +Cela montre les 5 premiers répertoires de tâches. + +### 4.2. Inspecter un répertoire de tâche + +Prenez l'un des hashs de processus de segmentation de la sortie console (par ex., `[3m/4n5o6p]`) et regardez à l'intérieur : + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Vous verrez : + +- **Fichiers .command.\*** : Scripts et journaux d'exécution Nextflow (comme avant) +- **Fichiers d'entrée préparés** : Liens symboliques vers les fichiers d'entrée réels +- **Fichiers de sortie** : Masques de segmentation, résultats intermédiaires, etc. + +La différence clé par rapport à Hello World : + +- Les pipelines réels préparent de gros fichiers d'entrée (images, données de référence) +- Les fichiers de sortie peuvent être assez volumineux (masques de segmentation, images traitées) +- Plusieurs fichiers d'entrée et de sortie par tâche + +!!! Tip + + Si un processus échoue, vous pouvez naviguer vers son répertoire de travail, examiner `.command.err` pour les messages d'erreur, et même réexécuter `.command.sh` manuellement pour déboguer le problème. + +### 4.3. Nettoyage du répertoire de travail + +Le répertoire de travail peut devenir assez volumineux sur plusieurs exécutions de pipeline. +Comme nous l'avons appris dans la Partie 1, vous pouvez utiliser `nextflow clean` pour supprimer les répertoires de travail des anciennes exécutions. + +Cependant, pour les pipelines nf-core avec de gros fichiers intermédiaires, il est particulièrement important de nettoyer régulièrement. + +### À retenir + +Vous comprenez comment les pipelines nf-core organisent leurs répertoires de travail et comment inspecter des tâches individuelles pour le débogage. + +### Et maintenant ? + +Apprenez le cache Nextflow et comment reprendre les exécutions de pipeline échouées. + +--- + +## 5. Reprendre une exécution de pipeline + +L'une des fonctionnalités les plus puissantes de Nextflow est la capacité de reprendre un pipeline à partir du point d'échec. + +### 5.1. Le mécanisme de cache + +Lorsque vous exécutez un pipeline avec `-resume`, Nextflow : + +1. Vérifie le cache pour chaque tâche +2. Si les entrées, le code et les paramètres sont identiques, réutilise le résultat en cache +3. Réexécute uniquement les tâches qui ont changé ou échoué + +Ceci est essentiel pour les pipelines de longue durée où des échecs peuvent survenir tard dans l'exécution. + +### 5.2. Essayer resume avec molkart + +Exécutez à nouveau la même commande, mais ajoutez `-resume` : + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Vous devriez voir une sortie comme : <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Remarquez `cached: 2` ou `cached: 1` pour chaque processus - rien n'a été réexécuté ! + +### 5.3. Quand resume est utile + +Resume est particulièrement utile quand : + +- Un pipeline échoue en raison de limites de ressources (mémoire insuffisante, limite de temps dépassée) +- Vous devez modifier des processus en aval sans réexécuter les étapes en amont +- Votre connexion réseau tombe pendant le téléchargement de données +- Vous voulez ajouter des sorties supplémentaires sans refaire le calcul + +!!! Warning + + Resume ne fonctionne que si vous n'avez pas modifié les données d'entrée, le code du pipeline ou les paramètres. + Si vous modifiez l'un de ces éléments, Nextflow réexécutera correctement les tâches affectées. + +### À retenir + +Vous savez comment utiliser `-resume` pour réexécuter efficacement les pipelines sans répéter les tâches réussies. + +### Et maintenant ? + +Maintenant que vous pouvez exécuter nf-core/molkart avec des données de test, vous êtes prêt à apprendre comment le configurer pour vos propres ensembles de données. diff --git a/docs/fr/docs/nf4_science/imaging/03_inputs.md b/docs/fr/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..9cc9943c41 --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Partie 3 : Organisation des entrées + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans la Partie 2, nous avons exécuté molkart avec plusieurs paramètres sur la ligne de commande. +Nous allons maintenant apprendre deux meilleures approches pour gérer les entrées : les **fichiers de paramètres** et les **feuilles d'échantillons**. + +## 1. Utilisation des fichiers de paramètres + +### 1.1. Le problème des longues lignes de commande + +Rappelons notre commande de la Partie 2 : + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Cela fonctionne, mais c'est difficile à reproduire, partager ou modifier. +Que faire si vous devez exécuter la même analyse le mois prochain ? +Que faire si un collaborateur souhaite utiliser exactement vos paramètres ? + +### 1.2. Solution : Utiliser un fichier de paramètres + +Créez un fichier appelé `params.yaml` : + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Maintenant votre commande devient : + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +C'est tout ! Le fichier de paramètres documente votre configuration exacte et facilite la réexécution ou le partage. + +### 1.3. Remplacement des paramètres + +Vous pouvez toujours remplacer des paramètres spécifiques depuis la ligne de commande : + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +La ligne ci-dessus change le `segmentation_method` en `stardist` et le nom du `--outdir` en `stardist_results` au lieu des paramètres dans le fichier `params.yaml`. +De plus, vous pouvez voir que le flag `-resume` nous a permis de réutiliser les résultats de prétraitement de l'exécution précédente, ce qui économise du temps. +Vous pouvez utiliser ce modèle pour tester rapidement différentes variations du pipeline. + +### Point clé + +Les fichiers de paramètres rendent vos analyses reproductibles et faciles à partager. +Utilisez-les pour tout travail d'analyse réel. + +### Et ensuite ? + +Apprenez comment les feuilles d'échantillons organisent les informations sur plusieurs échantillons. + +--- + +## 2. Le modèle de feuille d'échantillons + +### 2.1. Qu'est-ce qu'une feuille d'échantillons ? + +Une feuille d'échantillons est un fichier CSV qui décrit vos échantillons d'entrée. +Chaque ligne est un échantillon, et les colonnes spécifient les fichiers et les métadonnées pour cet échantillon. + +Regardons la feuille d'échantillons que nous avons utilisée : + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Les colonnes sont : + +- `sample` : Identifiant unique de l'échantillon +- `nuclear_image` : Image de coloration nucléaire (TIFF) +- `spot_table` : Points de transcription (TXT) +- `membrane_image` : Image de coloration membranaire (TIFF, optionnel) + +### 2.2. Chemins de fichiers + +Les feuilles d'échantillons acceptent plusieurs types de chemins : + +- **URLs** : Nextflow télécharge automatiquement (comme montré ci-dessus) +- **Chemins locaux** : `data/nuclear.tiff` ou `/absolute/path/to/nuclear.tiff` +- **Stockage cloud** : `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Vous pouvez mélanger les types de chemins dans la même feuille d'échantillons. + +### 2.3. Création de votre propre feuille d'échantillons + +Tout d'abord, téléchargeons les fichiers de données de test localement : + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Maintenant, modifions la feuille d'échantillons pour référencer ces fichiers locaux : + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Avertissement" + + Notez que les chemins dans la feuille d'échantillons sont relatifs à l'endroit où vous **exécutez** Nextflow, pas à l'endroit où se trouve la feuille d'échantillons. + +Enfin, exécutons nf-core/molkart une fois de plus avec la feuille d'échantillons contenant des chemins de fichiers locaux : + +`nextflow run ./molkart -params-file params.yaml -resume` + +Comme vous pouvez le voir, Nextflow exécute cette exécution de manière similaire à lorsque les fichiers étaient téléchargés depuis Github. C'est l'une des grandes fonctionnalités de Nextflow : il organise les données correctement pour vous, quel que soit l'endroit où elles se trouvent. + +### Point clé + +Les feuilles d'échantillons organisent les ensembles de données multi-échantillons d'une manière qui vous permet de définir explicitement vos métadonnées avec les chemins de fichiers. +La plupart des pipelines nf-core utilisent ce modèle. + +### Et ensuite ? + +Maintenant que nous avons couvert les entrées, explorons comment configurer les pipelines Nextflow pour différents environnements informatiques. diff --git a/docs/fr/docs/nf4_science/imaging/04_config.md b/docs/fr/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..96841b89aa --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Partie 4 : Configuration + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans les Parties 1-3, nous avons appris à exécuter Nextflow, à lancer un pipeline nf-core et à gérer les entrées avec des fichiers de paramètres et des samplesheets. +Nous allons maintenant explorer comment configurer les pipelines pour différents environnements informatiques en utilisant des **fichiers de configuration** et des **profils**. + +## Objectifs d'apprentissage + +À la fin de cette partie, vous serez capable de : + +- Comprendre comment Nextflow résout la configuration à partir de plusieurs sources +- Utiliser les profils intégrés nf-core pour les conteneurs et les tests +- Créer des profils personnalisés pour différents environnements informatiques +- Personnaliser les demandes de ressources en utilisant les étiquettes de processus +- Gérer les limites de ressources dans des environnements contraints +- Inspecter la configuration résolue avec `nextflow config` + +--- + +## 1. Comprendre la configuration Nextflow + +### 1.1. Qu'est-ce qu'un fichier de configuration ? + +Nextflow utilise des fichiers de configuration pour séparer la **logique du workflow** (quoi faire) des **paramètres d'exécution** (comment et où le faire). + +Les fichiers de configuration contrôlent : + +- Les moteurs de conteneurs (Docker, Singularity, Conda) +- Les ressources de calcul (CPUs, mémoire, temps) +- Les plateformes d'exécution (local, HPC, cloud) +- Les paramètres du pipeline + +### 1.2. Priorité de configuration + +Nextflow charge la configuration à partir de plusieurs sources, les sources ultérieures remplaçant les précédentes : + +1. **Configuration du pipeline** : `nextflow.config` dans le dépôt du pipeline +2. **Configuration du répertoire** : `nextflow.config` dans votre répertoire de travail actuel +3. **Configuration utilisateur** : `~/.nextflow/config` +4. **Ligne de commande** : Paramètres et options passés directement + +Cette approche en couches vous permet de conserver les valeurs par défaut dans le pipeline, de les remplacer par des paramètres spécifiques à l'utilisateur et d'effectuer des ajustements rapides en ligne de commande. + +### 1.3. Notre configuration actuelle + +Examinons la configuration que nous avons utilisée : + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Commentons ou modifions la ligne `docker.enabled = true` de la Partie 2, et voyons comment nous pouvons obtenir le même résultat en utilisant un profil dans molkart à la place. + +--- + +## 2. Utilisation des profils + +### 2.1. Qu'est-ce que les profils ? + +Les profils sont des ensembles nommés de configuration qui peuvent être activés avec le drapeau `-profile` via la commande `nextflow run`. +Ils facilitent le passage d'un scénario de calcul à l'autre sans modifier les fichiers de configuration. + +Tous les pipelines nf-core sont fournis avec plusieurs profils par défaut que nous pouvons utiliser. + +### 2.2. Inspection des profils intégrés + +Inspectons-les dans le fichier `molkart/nextflow.config` associé au code du pipeline : + +```bash +code molkart/nextflow.config +``` + +Recherchez le bloc `profiles` : + +```groovy title="molkart/nextflow.config (extrait)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Profils de conteneurs courants : + +- `docker` : Utilise des conteneurs Docker (le plus courant pour le développement local) +- `singularity` : Utilise Singularity/Apptainer (courant sur HPC) +- `conda` : Utilise des environnements Conda +- `apptainer` : Utilise des conteneurs Apptainer + +### 2.3. Ré-exécution avec des profils au lieu de nextflow.config + +Maintenant que nous avons désactivé la configuration docker dans notre fichier `nextflow.config` local et que nous comprenons les profils, ré-exécutons le pipeline en utilisant le drapeau `-profile`. + +Précédemment dans la Partie 3, nous avons créé un fichier `params.yaml` avec nos paramètres personnalisés. +Nous pouvons maintenant le combiner avec le profil Docker intégré : + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Décomposons ce que fait chaque drapeau : + +- `-profile docker` : Active le profil Docker du fichier `nextflow.config` de molkart, qui définit `docker.enabled = true` +- `-params-file params.yaml` : Charge tous les paramètres du pipeline à partir de notre fichier YAML +- `-resume` : Réutilise les résultats en cache des exécutions précédentes + +Comme nous utilisons `-resume`, Nextflow vérifiera si quelque chose a changé depuis la dernière exécution. +Si les paramètres, les entrées et le code sont identiques, toutes les tâches seront récupérées du cache et le pipeline se terminera presque instantanément. + +```console title="Sortie (extrait)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Remarquez que tous les processus affichent `cached: 2` ou `cached: 1` - rien n'a été ré-exécuté ! + +### 2.4. Profils de test + +Les profils de test fournissent des moyens rapides de spécifier des paramètres d'entrée et des fichiers de données par défaut pour vous permettre de vérifier que le pipeline fonctionne. +Les pipelines nf-core incluront toujours au moins deux profils de test : + +- `test` : Petit jeu de données avec des paramètres rapides pour des tests rapides +- `test_full` : Test plus complet avec des données plus volumineuses + +Examinons de plus près le profil `test` dans molkart qui est inclus à l'aide de la directive `includeConfig` : + +```groovy title="molkart/nextflow.config (extrait)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Cela signifie que chaque fois que nous exécutons le pipeline avec `-profile test`, Nextflow chargera la configuration depuis `conf/test.config`. + +```groovy title="molkart/conf/test.config (extrait)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Remarquez que ce profil contient les mêmes paramètres que ceux que nous avons utilisés dans notre fichier `params.yaml` précédemment. + +Vous pouvez activer plusieurs profils en les séparant par des virgules. +Utilisons cela pour tester notre pipeline sans avoir besoin de notre fichier de paramètres : + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Cela combine : + +- `docker` : Active les conteneurs Docker +- `test` : Utilise le jeu de données et les paramètres de test + +Les profils sont appliqués de gauche à droite, donc les profils ultérieurs remplacent les précédents s'ils définissent les mêmes valeurs. + +### À retenir + +Les pipelines nf-core sont fournis avec des profils intégrés pour les conteneurs, les tests et les environnements spéciaux. +Vous pouvez combiner plusieurs profils pour construire la configuration dont vous avez besoin. + +### Et ensuite ? + +Apprenez à créer vos propres profils personnalisés pour différents environnements informatiques. + +--- + +## 3. Création de profils personnalisés + +### 3.1. Créer des profils pour basculer entre le développement local et l'exécution sur HPC + +Créons des profils personnalisés pour deux scénarios : + +1. Développement local avec Docker +2. HPC universitaire avec planificateur Slurm et Singularity + +Ajoutez ce qui suit à votre `nextflow.config` : + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Vous pouvez maintenant basculer facilement entre les environnements : + +```bash +# Pour le développement local +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Pour HPC (lorsque disponible) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! Note + + Nous ne pouvons pas tester le profil HPC dans cet environnement de formation car nous n'avons pas accès à un planificateur Slurm. + Mais cela montre comment vous le configureriez pour une utilisation réelle. + +### 3.2. Utiliser `nextflow config` pour inspecter la configuration + +La commande `nextflow config` affiche la configuration entièrement résolue sans exécuter le pipeline. + +Afficher la configuration par défaut : + +```bash +nextflow config ./molkart +``` + +Afficher la configuration avec un profil spécifique : + +```bash +nextflow config -profile local_dev ./molkart +``` + +Ceci est extrêmement utile pour : + +- Déboguer les problèmes de configuration +- Comprendre quelles valeurs seront réellement utilisées +- Vérifier comment plusieurs profils interagissent + +### À retenir + +Les profils personnalisés vous permettent de basculer entre différents environnements informatiques avec un seul drapeau en ligne de commande. +Utilisez `nextflow config` pour inspecter la configuration résolue avant l'exécution. + +### Et ensuite ? + +Apprenez à personnaliser les demandes de ressources pour des processus individuels en utilisant le système d'étiquettes de processus de nf-core. + +--- + +## 4. Personnalisation des demandes de ressources + +### 4.1. Comprendre les étiquettes de processus dans les pipelines nf-core + +Pour plus de simplicité, les pipelines nf-core utilisent des [**étiquettes de processus**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) pour standardiser l'allocation de ressources dans tous les pipelines. +Chaque processus est étiqueté avec une étiquette comme `process_low`, `process_medium` ou `process_high` pour décrire respectivement des besoins en ressources de calcul faibles, moyens ou élevés. +Ces étiquettes sont converties en demandes de ressources spécifiques dans l'un des fichiers de configuration situés dans le répertoire `conf/` du pipeline. + +```groovy title="molkart/conf/base.config (extrait)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Remarquez le multiplicateur `task.attempt` - cela permet aux nouvelles tentatives de tâches ultérieures de demander plus de ressources, si le pipeline est configuré avec `process.maxRetries > 1`. + +### 4.2. Remplacement des ressources pour des processus spécifiques + +Pour un contrôle précis, ciblez des processus individuels par nom : + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Si nous essayons d'exécuter ce pipeline avec le remplacement ci-dessus, le processus `CELLPOSE` demandera 16 CPUs et 32 GB de mémoire au lieu des valeurs par défaut définies par son étiquette. +Cela provoquera l'échec du pipeline dans notre environnement actuel car nous n'avons pas autant de RAM disponible. +Nous apprendrons comment prévenir ces types d'échecs dans la section suivante. + +!!! Tip "Astuce" + + Pour trouver les noms de processus, consultez la sortie d'exécution du pipeline ou vérifiez `.nextflow.log`. + Les noms de processus suivent le modèle `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### À retenir + +Les pipelines nf-core utilisent des étiquettes de processus pour standardiser l'allocation de ressources. +Vous pouvez remplacer les ressources par étiquette (affecte plusieurs processus) ou par nom (affecte un processus spécifique). + +### Et ensuite ? + +Apprenez à gérer les limites de ressources dans des environnements contraints comme GitHub Codespaces. + +--- + +## 5. Gestion des ressources dans des environnements contraints + +### 5.1. Le problème des limites de ressources + +Si nous essayions d'exécuter molkart avec un processus demandant 16 CPUs et 32 GB de mémoire (comme montré dans la section 4.2), cela échouerait dans notre environnement actuel car nous n'avons pas autant de ressources disponibles. +Dans un environnement de cluster avec des nœuds plus grands, de telles demandes seraient soumises au planificateur. + +Dans des environnements contraints comme GitHub Codespaces, sans limites, Nextflow refuserait d'exécuter des processus qui dépassent les ressources disponibles. + +### 5.2. Définition des limites de ressources + +La directive `resourceLimits` plafonne les demandes de ressources aux valeurs spécifiées : + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Cela indique à Nextflow : « Si un processus demande plus de 2 CPUs ou 7 GB de mémoire, limitez-le plutôt à ces limites. » + +### 5.3. Ajout de limites de ressources aux profils personnalisés + +Mettez à jour vos profils personnalisés pour inclure des limites appropriées : + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! Warning "Avertissement" + + Définir des limites de ressources trop basses peut entraîner l'échec ou le ralentissement des processus. + Le pipeline peut avoir besoin d'utiliser des algorithmes moins gourmands en mémoire ou de traiter les données par plus petits morceaux. + +### À retenir + +Utilisez `resourceLimits` pour exécuter des pipelines dans des environnements à ressources limitées en plafonnant les demandes de ressources des processus. +Différents profils peuvent avoir des limites différentes adaptées à leur environnement. + +### Et ensuite ? + +Vous avez terminé la formation de base Nextflow pour la bio-imagerie ! + +--- + +## Conclusion + +Vous comprenez maintenant comment configurer les pipelines Nextflow pour différents environnements informatiques. + +Compétences clés que vous avez acquises : + +- **Priorité de configuration** : Comment Nextflow résout les paramètres à partir de plusieurs sources +- **Profils nf-core** : Utilisation des profils intégrés pour les conteneurs, les tests et les utilitaires +- **Profils personnalisés** : Création de vos propres profils pour différents environnements +- **Étiquettes de processus** : Compréhension et remplacement des demandes de ressources par étiquette +- **Limites de ressources** : Gestion d'environnements contraints avec `resourceLimits` +- **Inspection de configuration** : Utilisation de `nextflow config` pour déboguer et vérifier les paramètres + +Ces compétences de configuration sont transférables à tout pipeline Nextflow et vous aideront à exécuter des workflows efficacement sur des machines locales, des clusters HPC et des plateformes cloud. + +### Et ensuite ? + +Félicitations pour avoir terminé le cours Nextflow pour la bio-imagerie ! + +Prochaines étapes : + +- Remplissez le questionnaire du cours pour fournir des commentaires +- Consultez [Hello Nextflow](../hello_nextflow/index.md) pour en savoir plus sur le développement de workflows +- Explorez [Hello nf-core](../hello_nf-core/index.md) pour approfondir les outils nf-core +- Parcourez d'autres cours dans les [collections de formation](../training_collections/index.md) diff --git a/docs/fr/docs/nf4_science/imaging/index.md b/docs/fr/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..de8222f8bf --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/index.md @@ -0,0 +1,32 @@ +# Nextflow run pour l'imagerie + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ce cours de formation s'adresse aux chercheurs en imagerie et biologie spatiale qui souhaitent exécuter et personnaliser des pipelines d'analyse de données. +Il enseigne les concepts fondamentaux de Nextflow liés à l'exécution, à l'organisation et à la configuration de workflows en utilisant [nf-core/molkart](https://nf-co.re/molkart), un pipeline pour le traitement de données de transcriptomique spatiale Molecular Cartography. +Les compétences que vous apprendrez ici sont transférables à n'importe quel pipeline Nextflow ou nf-core. + +Commençons ! Cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous pour lancer l'environnement de formation (de préférence dans un onglet séparé), puis continuez votre lecture pendant qu'il se charge. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objectifs d'apprentissage + +En suivant ce cours, vous apprendrez à appliquer les concepts et outils fondamentaux de Nextflow à l'exécution de pipelines d'analyse d'imagerie. + +À la fin de cet atelier, vous serez capable de : + +- Lancer un workflow Nextflow localement et surveiller son exécution +- Trouver et interpréter les sorties (résultats) et fichiers de log générés par Nextflow +- Exécuter un pipeline nf-core avec des données de test et des entrées personnalisées +- Configurer l'exécution du pipeline en utilisant des profils et des fichiers de paramètres +- Gérer les entrées en utilisant des samplesheets et des paramètres en ligne de commande + +## Public et prérequis + +Ce cours suppose une familiarité minimale avec les éléments suivants : + +- Expérience avec la ligne de commande +- Familiarité de base avec les formats de fichiers d'imagerie (images TIFF, données tabulaires) + +Pour les exigences techniques et la configuration de l'environnement, consultez le mini-cours [Configuration de l'environnement](../../envsetup/). diff --git a/docs/fr/docs/nf4_science/imaging/next_steps.md b/docs/fr/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..d88c5b1235 --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Prochaines étapes + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations pour avoir terminé la formation Nextflow pour la bio-imagerie ! + +Vous possédez maintenant les compétences fondamentales pour exécuter et configurer des pipelines Nextflow pour l'analyse de données d'imagerie. + +## Continuer l'apprentissage + +Voici quelques prochaines étapes recommandées pour approfondir vos connaissances de Nextflow : + +### Explorer davantage de pipelines nf-core + +- **Parcourir tous les pipelines** : [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Développer vos propres pipelines + +Si vous souhaitez apprendre à écrire des pipelines Nextflow : + +- **[Hello Nextflow](../../hello_nextflow/)** : Formation complète au développement Nextflow +- **[Side Quests](../../side_quests/)** : Sujets avancés pour les développeurs de pipelines + +### Rejoindre la communauté + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)** : Obtenez de l'aide et connectez-vous avec d'autres utilisateurs +- **[nf-core Slack](https://nf-co.re/join)** : Rejoignez la communauté nf-core +- **[Seqera Community Forum](https://community.seqera.io)** : Posez des questions et partagez vos expériences + +### Ressources supplémentaires + +- **[Documentation Nextflow](https://www.nextflow.io/docs/latest/)** : Documentation de référence complète +- **[Documentation nf-core](https://nf-co.re/docs)** : Lignes directrices et bonnes pratiques + +## S'impliquer + +- **Contribuer à nf-core** : Aidez à améliorer les pipelines ou la documentation +- **Partager vos workflows** : Contribuez vos propres pipelines à la communauté +- **Assister aux événements** : Participez au Nextflow Summit et aux sessions de formation communautaires + +Merci d'avoir appris avec nous ! diff --git a/docs/fr/docs/nf4_science/imaging/survey.md b/docs/fr/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..73682728ed --- /dev/null +++ b/docs/fr/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Sondage + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Merci d'avoir suivi la formation Nextflow pour la bio-imagerie ! + +Nous apprécierions grandement vos commentaires pour nous aider à améliorer ce matériel de formation. + +Veuillez prendre quelques minutes pour remplir notre court sondage : + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Vos réponses nous aideront à comprendre ce qui a bien fonctionné et ce que nous pouvons améliorer pour les futurs apprenants. + +Merci pour votre temps et votre participation ! diff --git a/docs/fr/docs/nf4_science/index.md b/docs/fr/docs/nf4_science/index.md new file mode 100644 index 0000000000..59b89d29f6 --- /dev/null +++ b/docs/fr/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow pour la Science +hide: + - toc +--- + +# Nextflow pour la Science + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Il s'agit de cours qui démontrent comment appliquer les concepts et composants présentés dans le cours débutant [Hello Nextflow](../hello_nextflow/) à des cas d'usage scientifiques spécifiques. Chaque cours consiste en une série de modules de formation conçus pour aider les apprenants à développer progressivement leurs compétences. + +!!! exercise "Nextflow pour la Génomique" + + !!! tip inline end "" + + :material-run-fast: Apprenez à développer un pipeline de génomique avec Nextflow. + + Il s'agit d'un cours destiné aux chercheurs qui souhaitent apprendre à développer leurs propres pipelines de génomique. Le cours utilise un cas d'usage d'appel de variants pour démontrer comment développer un pipeline de génomique simple mais fonctionnel. + + [Commencer la formation Nextflow pour la Génomique :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Nextflow pour le RNAseq" + + !!! tip inline end "" + + :material-run-fast: Apprenez à développer un pipeline pour le traitement de données RNAseq avec Nextflow. + + Il s'agit d'un cours destiné aux chercheurs qui souhaitent apprendre à développer leurs propres pipelines RNAseq. Le cours utilise un cas d'usage de traitement de RNAseq en masse pour démontrer comment développer un pipeline RNAseq simple mais fonctionnel. + + [Commencer la formation Nextflow pour le RNAseq :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Nextflow pour la Bio-imagerie" + + !!! tip inline end "" + + :material-run-fast: Apprenez à exécuter des pipelines pour des données d'imagerie avec Nextflow. + + Il s'agit d'un cours destiné aux chercheurs qui souhaitent apprendre à exécuter et configurer des pipelines de bio-imagerie. Le cours utilise nf-core/molkart pour démontrer les modèles d'utilisation essentiels de Nextflow applicables à tout pipeline. + + [Commencer la formation Nextflow pour la Bio-imagerie :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Faites-nous savoir quels autres domaines et cas d'usage vous aimeriez voir couverts ici en publiant dans la [section Formation](https://community.seqera.io/c/training/) du forum communautaire. diff --git a/docs/fr/docs/nf4_science/rnaseq/00_orientation.md b/docs/fr/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..1199afc3cc --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'environnement de formation contient tous les logiciels, le code et les données nécessaires pour suivre ce cours de formation, vous n'avez donc rien à installer vous-même. +Cependant, vous avez besoin d'un compte (gratuit) pour vous connecter, et vous devriez prendre quelques minutes pour vous familiariser avec l'interface. + +Si vous ne l'avez pas encore fait, veuillez suivre le mini-cours [Configuration de l'environnement](../../envsetup/) avant d'aller plus loin. + +## Matériel fourni + +Tout au long de ce cours de formation, nous travaillerons dans le répertoire `nf4-science/rnaseq/`, dans lequel vous devez vous placer lorsque vous ouvrez l'espace de travail de formation. +Ce répertoire contient tous les fichiers de code, les données de test et les fichiers accessoires dont vous aurez besoin. + +N'hésitez pas à explorer le contenu de ce répertoire ; la façon la plus simple de le faire est d'utiliser l'explorateur de fichiers sur le côté gauche de l'espace de travail de formation dans l'interface VSCode. +Alternativement, vous pouvez utiliser la commande `tree`. +Tout au long du cours, nous utilisons la sortie de `tree` pour représenter la structure et le contenu des répertoires sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 3 +``` + +??? success "Contenu du répertoire" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + Ne vous inquiétez pas si cela semble beaucoup ; nous passerons en revue les éléments pertinents à chaque étape du cours. + Ceci est simplement destiné à vous donner un aperçu. + +**Voici un résumé de ce que vous devez savoir pour commencer :** + +- **Le fichier `rnaseq.nf`** est l'ébauche du script de workflow que nous allons développer. + +- **Le fichier `nextflow.config`** est un fichier de configuration qui définit les propriétés minimales de l'environnement. Vous pouvez l'ignorer pour le moment. + +- **Le répertoire `data`** contient les données d'entrée et les ressources associées : + + - _Un génome de référence_ appelé `genome.fa` constitué d'une petite région du chromosome 20 humain (de hg19/b37). + - _Des données RNAseq_ qui ont été extraites d'une petite région pour réduire la taille des fichiers, dans le répertoire `reads/`. + - _Des fichiers CSV_ listant les identifiants et les chemins des fichiers de données d'exemple, pour un traitement par lots. + +- **Le répertoire `solutions`** contient les scripts de workflow et les modules complets qui résultent de chaque étape du cours. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre tout problème. + Le numéro dans le nom du fichier correspond à l'étape de la partie pertinente du cours. + +!!!tip + + Si pour une raison quelconque vous sortez de ce répertoire, vous pouvez toujours exécuter cette commande pour y retourner : + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Maintenant, pour commencer le cours, cliquez sur la flèche dans le coin inférieur droit de cette page. diff --git a/docs/fr/docs/nf4_science/rnaseq/01_method.md b/docs/fr/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..7eb51a2c24 --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Partie 1 : Aperçu de la méthode et tests manuels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Il existe plusieurs méthodes valides pour traiter et analyser les données RNAseq en vrac. +Pour cette formation, nous suivons la méthode décrite [ici](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) par les Drs. Simon Andrews et Laura Biggins au [Babraham Institute](https://www.babraham.ac.uk/). + +Notre objectif est de développer un workflow qui implémente les étapes de traitement suivantes : exécuter un contrôle qualité initial sur les lectures dans un échantillon RNAseq en vrac, couper les séquences d'adaptateurs des lectures, aligner les lectures sur un génome de référence et produire un rapport de contrôle qualité (QC) complet. + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC :** Effectuer le QC sur les données de lecture avant la coupe en utilisant FastQC +- **TRIM_GALORE :** Couper les séquences d'adaptateurs et effectuer le QC après la coupe en utilisant Trim Galore (regroupe Cutadapt et FastQC) +- **HISAT2_ALIGN :** Aligner les lectures sur le génome de référence en utilisant Hisat2 +- **MULTIQC :** Générer un rapport QC complet en utilisant MultiQC + +Cependant, avant de nous lancer dans l'écriture de code de workflow, nous allons tester les commandes manuellement sur des données de test. +Les outils dont nous avons besoin ne sont pas installés dans l'environnement GitHub Codespaces, nous allons donc les utiliser via des conteneurs (voir [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Note" + + Assurez-vous d'être dans le répertoire `nf4-science/rnaseq`. La dernière partie du chemin affichée lorsque vous tapez `pwd` devrait être `rnaseq`. + +--- + +## 1. QC initial et coupe des adaptateurs + +Nous allons récupérer une image de conteneur qui a à la fois `fastqc` et `trim_galore` installés, la lancer en mode interactif et exécuter les commandes de coupe et de QC sur l'un des fichiers de données d'exemple. + +### 1.1. Récupérer le conteneur + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Cela vous donne la sortie console suivante pendant que le système télécharge l'image : + +??? success "Sortie de la commande" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Lancer le conteneur en mode interactif + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Sortie de la commande" + + ```console + + ``` +--> + +Votre invite changera pour quelque chose comme `(base) root@b645838b3314:/tmp#`, ce qui indique que vous êtes maintenant à l'intérieur du conteneur. + +La partie `-v ./data:/data` de la commande nous permettra d'accéder au contenu du répertoire `data/` depuis l'intérieur du conteneur. + +```bash +ls /data/reads +``` + +??? success "Sortie de la commande" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Exécuter la première commande `fastqc` + +Exécutons `fastqc` pour collecter les métriques de contrôle qualité sur les données de lecture. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Sortie de la commande" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Cela devrait s'exécuter très rapidement. +Vous pouvez trouver les fichiers de sortie dans le même répertoire que les données originales : + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Sortie" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Couper les séquences d'adaptateurs avec `trim_galore` + +Maintenant, exécutons `trim_galore`, qui regroupe Cutadapt et FastQC, pour couper les séquences d'adaptateurs et collecter les métriques QC après la coupe. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +Le flag `--fastqc` fait en sorte que la commande exécute automatiquement une étape de collecte QC une fois la coupe terminée. + +_La sortie est très verbeuse, ce qui suit est donc abrégé._ + +??? success "Sortie de la commande" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Vous pouvez trouver les fichiers de sortie dans le répertoire de travail : + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Sortie" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Déplacer les fichiers de sortie vers le système de fichiers en dehors du conteneur + +Tout ce qui reste à l'intérieur du conteneur sera inaccessible pour les travaux futurs, déplaçons donc ces fichiers vers un nouveau répertoire. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Quitter le conteneur + +```bash +exit +``` + +--- + +## 2. Aligner les lectures sur le génome de référence + +Nous allons récupérer une image de conteneur qui a `hisat2` installé, la lancer en mode interactif et exécuter la commande d'alignement pour aligner les données RNAseq sur un génome de référence. + +### 2.1. Récupérer le conteneur `hisat2` + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Sortie de la commande" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. Lancer le conteneur `hisat2` en mode interactif + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +La commande est la même qu'avant, avec l'URI du conteneur pertinent échangée. + +### 2.3. Créer les fichiers d'index du génome Hisat2 + +Hisat2 nécessite que la référence du génome soit fournie dans un format très spécifique, et ne peut pas simplement consommer le fichier FASTA `genome.fa` que nous fournissons, nous allons donc profiter de cette occasion pour créer les ressources pertinentes. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +La sortie est très verbeuse, ce qui suit est donc abrégé : + +<!-- TODO: switch to full output --> + +??? success "Sortie de la commande" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Cela crée plusieurs fichiers d'index du génome, que vous pouvez trouver dans le répertoire de travail. + +```bash +ls genome_index.* +``` + +```console title="Sortie" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Nous les utiliserons dans un instant, mais générons d'abord une archive tar compressée avec ces fichiers d'index du génome ; nous en aurons besoin plus tard et générer ces fichiers n'est généralement pas quelque chose que nous voulons faire dans le cadre d'un workflow. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Cela stocke une archive tar `genome_index.tar.gz` contenant les fichiers d'index du génome dans le répertoire `data/` de notre système de fichiers, ce qui sera utile dans la Partie 2 de cette formation. + +### 2.4. Exécuter la commande `hisat2` + +Maintenant nous pouvons exécuter la commande d'alignement, qui effectue l'étape d'alignement avec `hisat2` puis redirige la sortie vers `samtools` pour écrire la sortie sous forme de fichier BAM. + +L'entrée de données de lecture est le fichier `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` que nous avons généré avec `trim_galore` dans l'étape précédente. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Sortie de la commande" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Cela s'exécute presque instantanément car c'est un fichier de test très petit. +À l'échelle réelle, cela pourrait prendre beaucoup plus de temps. + +Une fois de plus, vous pouvez trouver les fichiers de sortie dans le répertoire de travail : + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Sortie" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Déplacer les fichiers de sortie vers le système de fichiers en dehors du conteneur + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Quitter le conteneur + +```bash +exit +``` + +--- + +## 3. Générer un rapport QC complet + +Nous allons récupérer une image de conteneur qui a `multiqc` installé, la lancer en mode interactif et exécuter une commande de génération de rapport sur les fichiers de rapport FastQC avant/après. + +### 3.1. Récupérer le conteneur `multiqc` + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Sortie de la commande" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. Lancer le conteneur `multiqc` en mode interactif + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. Exécuter la commande `multiqc` + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Sortie de la commande" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC est capable de rechercher dans les répertoires des rapports QC compatibles et agrégera tout ce qu'il trouve. + +Ici, nous voyons que l'outil a trouvé les trois rapports QC que nous avons générés : le QC initial que nous avons fait avec `fastqc`, le rapport après coupe de `cutadapt` (fait via `trim_galore`) et le QC après alignement produit par `hisat2`. + +Les fichiers de sortie sont une fois de plus dans le répertoire de travail : + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Sortie" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Déplacer les fichiers de sortie vers le système de fichiers en dehors du conteneur + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Quitter le conteneur + +```bash +exit +``` + +--- + +### À retenir + +Vous avez testé toutes les commandes individuelles de manière interactive dans les conteneurs pertinents. + +### Et ensuite ? + +Apprenez à encapsuler ces mêmes commandes dans un workflow multi-étapes qui utilise des conteneurs pour exécuter le travail. diff --git a/docs/fr/docs/nf4_science/rnaseq/02_single-sample.md b/docs/fr/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..64cdd72f73 --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Partie 2 : Implémentation pour un seul échantillon + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette partie du cours, nous allons écrire le workflow le plus simple possible qui encapsule toutes les commandes que nous avons exécutées dans la Partie 1 pour automatiser leur exécution, et nous viserons simplement à traiter un échantillon à la fois. + +Nous le ferons en trois étapes : + +1. Écrire un workflow à une seule étape qui exécute l'étape initiale de QC +2. Ajouter le nettoyage des adaptateurs et le QC post-nettoyage +3. Ajouter l'alignement sur le génome de référence + +!!! warning "Prérequis" + + Vous devez travailler la Partie 1 du cours avant de commencer cette leçon. + Plus précisément, travailler les sections 2.1-3 crée le fichier d'index du génome (`data/genome_index.tar.gz`) requis pour l'étape d'alignement dans cette leçon. + +--- + +## 1. Écrire un workflow à une seule étape qui exécute le QC initial + +Commençons par écrire un workflow simple qui exécute l'outil FastQC sur un fichier FASTQ contenant des lectures RNAseq single-end. + +Nous vous fournissons un fichier de workflow, `rnaseq.nf`, qui décrit les parties principales du workflow. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Instructions INCLUDE de modules + +/* + * Paramètres du pipeline + */ + +// Entrée principale + +workflow { + + // Créer le canal d'entrée + + // Appeler les processus + +} +``` + +Gardez à l'esprit que ce code de workflow est correct mais il n'est pas fonctionnel ; son but est juste de servir de squelette que vous utiliserez pour écrire le workflow réel. + +### 1.1. Créer un répertoire pour stocker les modules + +Nous allons créer des modules autonomes pour chaque processus afin de faciliter leur gestion et leur réutilisation, créons donc un répertoire pour les stocker. + +```bash +mkdir modules +``` + +### 1.2. Créer un module pour le processus de collecte des métriques QC + +Créons un fichier de module appelé `modules/fastqc.nf` pour héberger le processus `FASTQC` : + +```bash +touch modules/fastqc.nf +``` + +Ouvrez le fichier dans l'éditeur de code et copiez-y le code suivant : + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Vous devriez reconnaître tous les éléments de ce que vous avez appris dans les Parties 1 et 2 de cette série de formation ; le seul changement notable est que cette fois nous utilisons `mode: symlink` pour la directive `publishDir`, et nous utilisons un paramètre pour définir le `publishDir`. + +!!! note + + Même si les fichiers de données que nous utilisons ici sont très petits, en génomique ils peuvent devenir très volumineux. À des fins de démonstration dans l'environnement d'enseignement, nous utilisons le mode de publication 'symlink' pour éviter des copies de fichiers inutiles. Vous ne devriez pas faire cela dans vos workflows finaux, car vous perdrez les résultats lorsque vous nettoierez votre répertoire `work`. + +### 1.3. Importer le module dans le fichier de workflow + +Ajoutez l'instruction `include { FASTQC } from './modules/fastqc.nf'` au fichier `rnaseq.nf` : + +```groovy title="rnaseq.nf" linenums="3" +// Instructions INCLUDE de modules +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Ajouter une déclaration d'entrée + +Déclarez un paramètre d'entrée avec une valeur par défaut : + +```groovy title="rnaseq.nf" linenums="10" +params { + // Entrée principale + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Créer un canal d'entrée dans le bloc workflow + +Utilisez une fabrique de canaux basique `.fromPath()` pour créer le canal d'entrée : + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Créer le canal d'entrée à partir d'un chemin de fichier + read_ch = channel.fromPath(params.reads) + + // Appeler les processus + +} +``` + +### 1.6. Appeler le processus `FASTQC` sur le canal d'entrée + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Créer le canal d'entrée à partir d'un chemin de fichier + read_ch = channel.fromPath(params.reads) + + // Contrôle qualité initial + FASTQC(read_ch) + +} +``` + +### 1.7. Exécuter le workflow pour tester qu'il fonctionne + +Nous pourrions utiliser le paramètre `--reads` pour spécifier une entrée depuis la ligne de commande, mais pendant le développement nous pouvons être paresseux et simplement utiliser le test par défaut que nous avons configuré. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Cela devrait s'exécuter très rapidement si vous avez travaillé la Partie 1 et avez déjà téléchargé le conteneur. +Si vous l'avez sautée, Nextflow téléchargera le conteneur pour vous ; vous n'avez rien à faire pour que cela se produise, mais vous devrez peut-être attendre jusqu'à une minute. + +Vous pouvez trouver les sorties sous `results/fastqc` comme spécifié dans le processus `FASTQC` par la directive `publishDir`. + +```bash +ls results/fastqc +``` + +```console title="Sortie" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Ajouter le nettoyage des adaptateurs et le contrôle qualité post-nettoyage + +Nous allons utiliser le wrapper Trim_Galore, qui intègre Cutadapt pour le nettoyage lui-même et FastQC pour le contrôle qualité post-nettoyage. + +### 2.1. Créer un module pour le processus de nettoyage et QC + +Créons un fichier de module appelé `modules/trim_galore.nf` pour héberger le processus `TRIM_GALORE` : + +```bash +touch modules/trim_galore.nf +``` + +Ouvrez le fichier dans l'éditeur de code et copiez-y le code suivant : + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Importer le module dans le fichier de workflow + +Ajoutez l'instruction `include { TRIM_GALORE } from './modules/trim_galore.nf'` au fichier `rnaseq.nf` : + +```groovy title="rnaseq.nf" linenums="3" +// Instructions INCLUDE de modules +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Appeler le processus sur le canal d'entrée + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Créer le canal d'entrée à partir d'un chemin de fichier + read_ch = channel.fromPath(params.reads) + + // Contrôle qualité initial + FASTQC(read_ch) + + // Nettoyage des adaptateurs et QC post-nettoyage + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Exécuter le workflow pour tester qu'il fonctionne + +```bash +nextflow run rnaseq.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Cela devrait également s'exécuter très rapidement, car nous travaillons sur un fichier d'entrée si petit. + +Vous pouvez trouver les sorties sous `results/trimming` comme spécifié dans le processus `TRIM_GALORE` par la directive `publishDir`. + +```bash +ls results/trimming +``` + +```console title="Sortie" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Aligner les lectures sur le génome de référence + +Finalement, nous pouvons exécuter l'étape d'alignement du génome en utilisant Hisat2, qui émettra également des métriques de contrôle qualité de type FastQC. + +### 3.1. Créer un module pour le processus HiSat2 + +Créons un fichier de module appelé `modules/hisat2_align.nf` pour héberger le processus `HISAT2_ALIGN` : + +```bash +touch modules/hisat2_align.nf +``` + +Ouvrez le fichier dans l'éditeur de code et copiez-y le code suivant : + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Importer le module dans le fichier de workflow + +Ajoutez l'instruction `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` au fichier `rnaseq.nf` : + +```groovy title="rnaseq.nf" linenums="3" +// Instructions INCLUDE de modules +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Ajouter une déclaration de paramètre pour fournir l'index du génome + +Déclarez un paramètre d'entrée avec une valeur par défaut : + +```groovy title="rnaseq.nf" linenums="8" +params { + // Entrée principale + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Archive du génome de référence + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Appeler le processus `HISAT2_ALIGN` sur les lectures nettoyées produites par `TRIM_GALORE` + +Les lectures nettoyées sont dans le canal de sortie `TRIM_GALORE.out.trimmed_reads` produit par l'étape précédente. + +De plus, nous utilisons `file (params.hisat2_index_zip)` pour fournir à l'outil Hisat2 l'archive tar compressée de l'index du génome. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Créer le canal d'entrée à partir d'un chemin de fichier + read_ch = channel.fromPath(params.reads) + + // Contrôle qualité initial + FASTQC(read_ch) + + // Nettoyage des adaptateurs et QC post-nettoyage + TRIM_GALORE(read_ch) + + // Alignement sur un génome de référence + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Exécuter le workflow pour tester qu'il fonctionne + +```bash +nextflow run rnaseq.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Vous pouvez trouver les sorties sous `results/align` comme spécifié dans le processus `HISAT2_ALIGN` par la directive `publishDir`. + +```bash +ls results/align +``` + +```console title="Sortie" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Cela complète le traitement de base que nous devons appliquer à chaque échantillon. + +_Nous ajouterons l'agrégation de rapports MultiQC dans la Partie 2, après avoir fait en sorte que le workflow accepte plusieurs échantillons à la fois._ + +--- + +### À retenir + +Vous savez comment encapsuler toutes les étapes principales pour traiter des échantillons RNAseq single-end individuellement. + +### Et ensuite ? + +Apprenez comment modifier le workflow pour traiter plusieurs échantillons en parallèle, agréger les rapports QC sur toutes les étapes pour tous les échantillons, et permettre l'exécution du workflow sur des données RNAseq paired-end. diff --git a/docs/fr/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/fr/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..1db7bce893 --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Partie 3 : Implémentation multi-échantillons en lecture appariée + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans cette dernière partie du cours, nous allons faire passer notre simple workflow au niveau supérieur en le transformant en un puissant outil d'automatisation par lots capable de traiter un nombre arbitraire d'échantillons. +Et pendant que nous y sommes, nous allons également le modifier pour qu'il accepte des données en lecture appariée, ce qui est plus courant dans les études récentes. + +Nous procéderons en trois étapes : + +1. Faire accepter au workflow plusieurs échantillons en entrée et paralléliser l'exécution +2. Ajouter la génération de rapport QC complet +3. Passer aux données RNAseq en lecture appariée + +--- + +## 1. Faire accepter au workflow plusieurs échantillons en entrée et paralléliser l'exécution + +Nous allons devoir modifier la façon dont nous gérons l'entrée. + +### 1.1. Changer l'entrée principale pour qu'elle soit un CSV de chemins de fichiers au lieu d'un seul fichier + +Nous fournissons un fichier CSV contenant les identifiants d'échantillons et les chemins de fichiers FASTQ dans le répertoire `data/`. +Ce fichier CSV inclut une ligne d'en-tête. +Notez que les chemins de fichiers FASTQ sont des chemins absolus. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Renommons le paramètre d'entrée principal en `input_csv` et changeons la valeur par défaut pour qu'elle soit le chemin vers le fichier `single-end.csv`. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Entrée principale + input_csv: Path = "data/single-end.csv" + + // Archive de l'index du génome de référence + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Mettre à jour la fabrique de canal d'entrée pour gérer un CSV en entrée + +Nous allons vouloir charger le contenu du fichier dans le canal plutôt que simplement le chemin du fichier lui-même, donc nous utilisons l'opérateur `.splitCsv()` pour analyser le format CSV, puis l'opérateur `.map()` pour récupérer l'information spécifique que nous voulons (le chemin du fichier FASTQ). + +```groovy title="rnaseq.nf" linenums="16" + // Créer le canal d'entrée à partir du contenu d'un fichier CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Exécuter le workflow pour vérifier qu'il fonctionne + +```bash +nextflow run rnaseq.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Cette fois, nous voyons que chaque étape est exécutée 6 fois, sur chacun des 6 fichiers de données que nous avons fournis. + +C'est tout ce qu'il a fallu pour que le workflow s'exécute sur plusieurs fichiers ! +Nextflow gère tout le parallélisme pour nous. + +--- + +## 2. Agréger les métriques QC de pré-traitement dans un seul rapport MultiQC + +Tout cela produit beaucoup de rapports QC, et nous ne voulons pas avoir à fouiller dans les rapports individuels. +C'est le moment idéal pour ajouter une étape d'agrégation de rapport MultiQC ! + +### 2.1. Créer un module pour le processus d'agrégation QC + +Créons un fichier module appelé `modules/multiqc.nf` pour héberger le processus `MULTIQC` : + +```bash +touch modules/multiqc.nf +``` + +Ouvrez le fichier dans l'éditeur de code et copiez-y le code suivant : + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Importer le module dans le fichier de workflow + +Ajoutez l'instruction `include { MULTIQC } from './modules/multiqc.nf'` au fichier `rnaseq.nf` : + +```groovy title="rnaseq.nf" linenums="3" +// Instructions INCLUDE de modules +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Ajouter un paramètre `report_id` et lui donner une valeur par défaut appropriée + +```groovy title="rnaseq.nf" linenums="9" +params { + // Entrée principale + input_csv: Path = "data/single-end.csv" + + // Archive de l'index du génome de référence + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID de rapport + report_id: String = "all_single-end" +} +``` + +### 2.4. Appeler le processus sur les sorties des étapes précédentes + +Nous devons donner au processus `MULTIQC` toutes les sorties liées au QC des étapes précédentes. + +Pour cela, nous allons utiliser l'opérateur `.mix()`, qui agrège plusieurs canaux en un seul. + +Si nous avions quatre processus appelés A, B, C et D avec chacun un simple canal `.out`, la syntaxe ressemblerait à ceci : `A.out.mix( B.out, C.out, D.out )`. Comme vous pouvez le voir, vous l'appliquez au premier des canaux que vous voulez combiner (peu importe lequel) et vous ajoutez simplement tous les autres, séparés par des virgules, dans les parenthèses qui suivent. + +Dans le cas de notre workflow, nous avons les sorties suivantes à agréger : + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +L'exemple de syntaxe devient donc : + +```groovy title="Application de .mix() dans l'appel MULTIQC" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Cela collectera les rapports QC par échantillon. +Mais puisque nous voulons les agréger pour tous les échantillons, nous devons ajouter l'opérateur `collect()` afin de rassembler les rapports de tous les échantillons en un seul appel à `MULTIQC`. +Et nous devons également lui donner le paramètre `report_id`. + +Cela nous donne ce qui suit : + +```groovy title="L'appel MULTIQC complet" linenums="33" + // Génération de rapport QC complet + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Dans le contexte du bloc de workflow complet, cela finit par ressembler à ceci : + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Créer le canal d'entrée à partir du contenu d'un fichier CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// Contrôle qualité initial + FASTQC(read_ch) + + // Coupe des adaptateurs et QC post-coupe + TRIM_GALORE(read_ch) + + // Alignement sur un génome de référence + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Génération de rapport QC complet + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Exécuter le workflow pour vérifier qu'il fonctionne + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Cette fois, nous voyons un seul appel à MULTIQC ajouté après les appels de processus mis en cache : + +Vous pouvez trouver les sorties sous `results/trimming` comme spécifié dans le processus `TRIM_GALORE` par la directive `publishDir`. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Sortie" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Ce dernier fichier `all_single-end.html` est le rapport agrégé complet, commodément emballé dans un seul fichier HTML facile à consulter. + +--- + +## 3. Activer le traitement de données RNAseq en lecture appariée + +Actuellement, notre workflow ne peut gérer que des données RNAseq en lecture simple. +Il est de plus en plus courant de voir des données RNAseq en lecture appariée, donc nous voulons pouvoir les gérer. + +Rendre le workflow complètement agnostique du type de données nécessiterait d'utiliser des fonctionnalités légèrement plus avancées du langage Nextflow, donc nous n'allons pas le faire ici, mais nous pouvons créer une version de traitement en lecture appariée pour démontrer ce qui doit être adapté. + +### 3.1. Créer une copie du workflow appelée `rnaseq_pe.nf` + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Modifier le `input_csv` par défaut pour pointer vers les données en lecture appariée + +Nous fournissons un deuxième fichier CSV contenant les identifiants d'échantillons et les chemins de fichiers FASTQ appariés dans le répertoire `data/` + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Changeons la valeur par défaut de `input_csv` pour qu'elle soit le chemin vers le fichier `paired-end.csv`. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Entrée principale + input_csv: Path = "data/paired-end.csv" + + // Archive de l'index du génome de référence + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID de rapport + report_id: String = "all_single-end" +} +``` + +### 3.3. Mettre à jour la fabrique de canal + +Nous devons indiquer à l'opérateur `.map()` de récupérer maintenant les deux chemins de fichiers FASTQ. + +Donc `row -> file(row.fastq_path)` devient `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Créer le canal d'entrée à partir du contenu d'un fichier CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Créer une version en lecture appariée du processus FASTQC + +Créons une copie du module pour que nous puissions avoir les deux versions à portée de main. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Ouvrez le nouveau fichier module `fastqc_pe.nf` dans l'éditeur de code et effectuez les modifications de code suivantes : + +- Changez `fastqc $reads` en `fastqc ${reads}` dans le bloc `script` (ligne 17) pour que l'entrée `reads` soit déballée, puisqu'elle est maintenant un tuple de deux chemins au lieu d'un seul chemin. +- Remplacez `${reads.simpleName}` par un joker (`*`) pour éviter d'avoir à gérer les fichiers de sortie individuellement. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Techniquement, cela généralise le processus `FASTQC` d'une manière qui le rend capable de gérer des données RNAseq en lecture simple ou appariée. + +Enfin, mettez à jour l'instruction d'importation de module pour utiliser la version en lecture appariée du module. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Créer une version en lecture appariée du processus TRIM_GALORE + +Créez une copie du module pour que nous puissions avoir les deux versions à portée de main. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Ouvrez le nouveau fichier module `trim_galore_pe.nf` dans l'éditeur de code et effectuez les modifications de code suivantes : + +- Changez la déclaration d'entrée de `path reads` en `tuple path(read1), path(read2)` +- Mettez à jour la commande dans le bloc `script`, en remplaçant `$reads` par `--paired ${read1} ${read2}` +- Mettez à jour les déclarations de sortie pour refléter les fichiers ajoutés et les différentes conventions de nommage, en utilisant des jokers pour éviter d'avoir à tout lister. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Enfin, mettez à jour l'instruction d'importation de module pour utiliser la version en lecture appariée du module. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Mettre à jour l'appel au processus MULTIQC pour attendre deux rapports de TRIM_GALORE + +Le processus `TRIM_GALORE` produit maintenant un canal de sortie supplémentaire, donc nous devons le fournir à MultiQC. + +Remplacez `TRIM_GALORE.out.fastqc_reports,` par `TRIM_GALORE.out.fastqc_reports_1,` plus `TRIM_GALORE.out.fastqc_reports_2,` : + +```groovy title="rnaseq_pe.nf" linenums="33" + // Génération de rapport QC complet + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Pendant que nous sommes sur MultiQC, mettons également à jour la valeur par défaut du paramètre `report_id` de `"all_single-end"` à `"all_paired-end"`. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Entrée principale + input_csv: Path = "data/paired-end.csv" + + // Archive de l'index du génome de référence + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID de rapport + report_id: String = "all_paired-end" +} +``` + +### 3.7. Créer une version en lecture appariée du processus HISAT2_ALIGN + +Créez une copie du module pour que nous puissions avoir les deux versions à portée de main. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Ouvrez le nouveau fichier module `hisat2_align_pe.nf` dans l'éditeur de code et effectuez les modifications de code suivantes : + +- Changez la déclaration d'entrée de `path reads` en `tuple path(read1), path(read2)` +- Mettez à jour la commande dans le bloc `script`, en remplaçant `-U $reads` par `-1 ${read1} -2 ${read2}` +- Remplacez toutes les instances de `${reads.simpleName}` par `${read1.simpleName}` dans la commande du bloc `script` ainsi que dans les déclarations de sortie. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Enfin, mettez à jour l'instruction d'importation de module pour utiliser la version en lecture appariée du module. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Exécuter le workflow pour vérifier qu'il fonctionne + +Nous n'utilisons pas `-resume` car cela ne serait pas mis en cache, et il y a deux fois plus de données à traiter qu'avant, mais cela devrait quand même se terminer en moins d'une minute. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +Et voilà ! Maintenant nous avons deux versions légèrement divergentes de notre workflow, une pour les données de lecture simple et une pour les données de lecture appariée. +L'étape logique suivante serait de faire en sorte que le workflow accepte l'un ou l'autre type de données à la volée, ce qui est hors du cadre de ce cours, mais nous pourrions aborder cela dans une suite. + +--- + +### À retenir + +Vous savez comment adapter un workflow mono-échantillon pour paralléliser le traitement de plusieurs échantillons, générer un rapport QC complet et adapter le workflow pour utiliser des données de lecture appariée si nécessaire. + +### Et maintenant ? + +Félicitations, vous avez terminé le mini-cours Nextflow pour RNAseq ! Célébrez votre succès et prenez une pause bien méritée ! + +Ensuite, nous vous demandons de compléter une très courte enquête sur votre expérience avec ce cours de formation, puis nous vous emmènerons vers une page avec des liens vers d'autres ressources de formation et des liens utiles. diff --git a/docs/fr/docs/nf4_science/rnaseq/index.md b/docs/fr/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..9336382833 --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: Nextflow pour l'ARNseq +hide: + - toc +--- + +# Nextflow pour l'ARNseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ce cours de formation est destiné aux chercheurs en transcriptomique et dans les domaines connexes qui souhaitent développer ou personnaliser des pipelines d'analyse de données. +Il s'appuie sur la formation débutant [Hello Nextflow](../../hello_nextflow/) et démontre comment utiliser Nextflow dans le contexte spécifique de l'analyse d'ARNseq en bulk. + +Plus précisément, ce cours démontre comment implémenter un pipeline simple de traitement d'ARNseq en bulk pour éliminer les séquences adaptatrices, aligner les lectures sur un génome de référence et effectuer un contrôle qualité (QC) à plusieurs étapes. + +Commençons ! Cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous pour lancer l'environnement de formation (de préférence dans un onglet séparé), puis poursuivez la lecture pendant le chargement. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objectifs d'apprentissage + +En suivant ce cours, vous apprendrez à appliquer les concepts et outils fondamentaux de Nextflow à un cas d'usage typique d'ARNseq. + +À la fin de cet atelier, vous serez capable de : + +- Écrire un workflow linéaire pour appliquer des méthodes de base de traitement et de QC d'ARNseq +- Gérer de manière appropriée les fichiers spécifiques au domaine tels que les FASTQ et les ressources de génome de référence +- Gérer les données de séquençage single-end et paired-end +- Exploiter le paradigme de flux de données de Nextflow pour paralléliser le traitement d'ARNseq par échantillon +- Agréger les rapports de QC à travers plusieurs étapes et échantillons en utilisant les opérateurs de canal pertinents + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Prérequis + +Ce cours suppose une familiarité minimale avec les éléments suivants : + +- Outils et formats de fichiers couramment utilisés dans ce domaine scientifique +- Expérience avec la ligne de commande +- Concepts et outils fondamentaux de Nextflow couverts dans la formation débutant [Hello Nextflow](../../hello_nextflow/). + +Pour les exigences techniques et la configuration de l'environnement, consultez le mini-cours [Configuration de l'environnement](../../envsetup/). diff --git a/docs/fr/docs/nf4_science/rnaseq/next_steps.md b/docs/fr/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..9ae2d9872a --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Prochaines Étapes + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Félicitations encore pour avoir terminé la formation Nextflow For RNAseq et merci d'avoir répondu à notre enquête ! + +--- + +## 1. Top 3 des moyens d'améliorer vos compétences Nextflow + +Voici nos trois principales recommandations pour ce qu'il faut faire ensuite, basées sur le cours que vous venez de terminer. + +### 1.1. Appliquer Nextflow à d'autres cas d'usage d'analyse scientifique + +**Consultez la page [Nextflow for Science](../nf4_science/index.md)** pour une liste d'autres cours courts autonomes qui démontrent comment appliquer les concepts de base et les mécanismes présentés dans Hello Nextflow à des cas d'usage courants d'analyse scientifique. + +Si vous ne voyez pas votre domaine représenté par un cas d'usage pertinent, faites-le nous savoir sur le [forum de la communauté](https://community.seqera.io/) afin que nous puissions l'ajouter à notre liste de développement. + +### 1.2. Démarrer avec nf-core + +**[nf-core](https://nf-co.re/)** est un effort collaboratif mondial visant à développer des pipelines open-source standardisés pour un large éventail d'applications de recherche scientifique. +Le projet comprend [plus de 100 pipelines](https://nf-co.re/pipelines/) disponibles à l'utilisation immédiatement et [bien plus de 1400 modules de processus](https://nf-co.re/modules/) qui peuvent être intégrés dans vos propres projets, ainsi qu'un ensemble riche d'outils de développement. + +Le cours de formation **[Hello nf-core](../../hello_nf-core/index.md)** vous présentera les pipelines organisés par la communauté nf-core et le framework de développement, conçu pour vous aider à écrire des workflows reproductibles, évolutifs et standardisés. Vous apprendrez à utiliser les pipelines nf-core existants, à contribuer à leur développement, et même à commencer à construire les vôtres, soutenus par les meilleures pratiques et une communauté dynamique. Si vous êtes prêt à appliquer vos compétences Nextflow dans des projets concrets, c'est l'étape suivante parfaite. + +### 1.3. Maîtriser des fonctionnalités Nextflow plus avancées + +Dans les cours Hello, nous maintenons volontairement un niveau de complexité technique faible pour éviter de vous surcharger avec des informations dont vous n'avez pas besoin pour débuter avec Nextflow. +Au fur et à mesure que vous progresserez dans votre travail, vous voudrez apprendre à utiliser l'ensemble complet des fonctionnalités et la puissance de Nextflow. + +À cette fin, nous travaillons actuellement sur une **collection de [Side Quests](../side_quests/index.md)**, qui sont conçus pour être des cours courts autonomes approfondissant des sujets spécifiques comme les tests et la gestion des métadonnées. + +--- + +## 2. Découvrez Seqera Platform + +**[Seqera Platform](https://seqera.io/) est la meilleure façon d'exécuter Nextflow en pratique.** + +Il s'agit d'une plateforme cloud développée par les créateurs de Nextflow que vous pouvez connecter à votre propre infrastructure de calcul (qu'elle soit locale, HPC ou cloud) pour faciliter grandement le lancement et la gestion de vos workflows, ainsi que la gestion de vos données et l'exécution d'analyses de manière interactive dans un environnement cloud. + +Le niveau gratuit (Free Tier) est disponible gratuitement pour tous (avec des quotas d'utilisation). +Les universitaires éligibles peuvent obtenir un accès gratuit de niveau Pro (sans limitation d'utilisation) via le [Programme Académique](https://seqera.io/academic/program/). + +Consultez les [tutoriels Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) pour voir si cela pourrait vous être utile. + +--- + +### C'est tout pour l'instant ! + +**Bonne chance dans votre parcours Nextflow et n'hésitez pas à nous faire savoir sur le [forum de la communauté](https://community.seqera.io/) ce que nous pourrions faire d'autre pour vous aider.** diff --git a/docs/fr/docs/nf4_science/rnaseq/survey.md b/docs/fr/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..fbebe00391 --- /dev/null +++ b/docs/fr/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Questionnaire de retour d'expérience + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Avant de continuer, veuillez compléter ce court questionnaire de 5 questions pour évaluer la formation, partager vos commentaires sur votre expérience, et nous faire savoir comment nous pourrions mieux vous accompagner dans votre parcours Nextflow. + +Cela devrait vous prendre moins d'une minute. Merci de nous aider à améliorer nos supports de formation pour tous ! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/fr/docs/side_quests/README.md b/docs/fr/docs/side_quests/README.md new file mode 100644 index 0000000000..0cae561957 --- /dev/null +++ b/docs/fr/docs/side_quests/README.md @@ -0,0 +1 @@ +Ceci est un espace réservé pour les futurs Side Quests (formations approfondies). Les documents actuellement présents ici sont des ébauches basées sur du contenu recyclé provenant d'ailleurs. diff --git a/docs/fr/docs/side_quests/debugging.md b/docs/fr/docs/side_quests/debugging.md new file mode 100644 index 0000000000..8fb73a65ac --- /dev/null +++ b/docs/fr/docs/side_quests/debugging.md @@ -0,0 +1,1630 @@ +# Débogage des Workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Le débogage est une compétence essentielle qui peut vous faire gagner des heures de frustration et vous aider à devenir un développeur Nextflow plus efficace. Tout au long de votre carrière, en particulier lorsque vous débutez, vous rencontrerez des bugs lors de la construction et de la maintenance de vos workflows. L'apprentissage d'approches de débogage systématiques vous aidera à identifier et à résoudre les problèmes rapidement. + +### Objectifs d'apprentissage + +Dans cette quête annexe, nous explorerons les **techniques de débogage systématiques** pour les workflows Nextflow : + +- **Débogage des erreurs de syntaxe** : Utilisation efficace des fonctionnalités de l'IDE et des messages d'erreur de Nextflow +- **Débogage des canaux** : Diagnostic des problèmes de flux de données et de structure des canaux +- **Débogage des processus** : Investigation des échecs d'exécution et des problèmes de ressources +- **Outils de débogage intégrés** : Exploitation du mode preview, de l'exécution stub et des répertoires de travail de Nextflow +- **Approches systématiques** : Une méthodologie en quatre phases pour un débogage efficace + +À la fin, vous disposerez d'une méthodologie de débogage robuste qui transforme les messages d'erreur frustrants en feuilles de route claires vers les solutions. + +### Prérequis + +Avant d'entreprendre cette quête annexe, vous devez : + +- Avoir terminé le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants. +- Être à l'aise avec les concepts et mécanismes de base de Nextflow (processus, canaux, opérateurs) + +**Optionnel :** Nous recommandons de terminer d'abord la quête annexe [Fonctionnalités IDE pour le Développement Nextflow](./ide_features.md). +Celle-ci couvre de manière exhaustive les fonctionnalités de l'IDE qui supportent le débogage (coloration syntaxique, détection d'erreurs, etc.), que nous utiliserons intensivement ici. + +--- + +## 0. Commencer + +#### Ouvrir l'espace de code de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'Environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/debugging +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner le matériel + +Vous trouverez un ensemble d'exemples de workflows avec divers types de bugs que nous utiliserons pour la pratique : + +??? abstract "Contenu du répertoire" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Ces fichiers représentent des scénarios de débogage courants que vous rencontrerez dans le développement en conditions réelles. + +#### Examiner l'exercice + +Votre défi est d'exécuter chaque workflow, d'identifier la ou les erreurs, et de les corriger. + +Pour chaque workflow bugué : + +1. **Exécuter le workflow** et observer l'erreur +2. **Analyser le message d'erreur** : que vous dit Nextflow ? +3. **Localiser le problème** dans le code en utilisant les indices fournis +4. **Corriger le bug** et vérifier que votre solution fonctionne +5. **Réinitialiser le fichier** avant de passer à la section suivante (utilisez `git checkout <filename>`) + +Les exercices progressent des erreurs de syntaxe simples vers des problèmes d'exécution plus subtils. +Les solutions sont discutées en ligne, mais essayez de résoudre chaque problème vous-même avant de lire la suite. + +#### Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon espace de code est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +- [ ] Je comprends l'exercice + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +--- + +## 1. Erreurs de Syntaxe + +Les erreurs de syntaxe sont le type d'erreur le plus courant que vous rencontrerez lors de l'écriture de code Nextflow. Elles se produisent lorsque le code ne se conforme pas aux règles de syntaxe attendues du DSL Nextflow. Ces erreurs empêchent votre workflow de s'exécuter du tout, il est donc important d'apprendre à les identifier et à les corriger rapidement. + +### 1.1. Accolades manquantes + +L'une des erreurs de syntaxe les plus courantes, et parfois l'une des plus complexes à déboguer, est **les crochets manquants ou mal appariés**. + +Commençons par un exemple pratique. + +#### Exécuter le pipeline + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Éléments clés des messages d'erreur de syntaxe :** + +- **Fichier et emplacement** : Indique quel fichier et quelle ligne/colonne contiennent l'erreur (`bad_syntax.nf:24:1`) +- **Description de l'erreur** : Explique ce que l'analyseur a trouvé qu'il n'attendait pas (`Unexpected input: '<EOF>'`) +- **Indicateur EOF** : Le message `<EOF>` (End Of File) indique que l'analyseur a atteint la fin du fichier en attendant toujours plus de contenu - un signe classique d'accolades non fermées + +#### Vérifier le code + +Maintenant, examinons `bad_syntax.nf` pour comprendre ce qui cause l'erreur : + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Accolade fermante manquante pour le processus + +workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) +} +``` + +Pour les besoins de cet exemple, nous avons laissé un commentaire pour vous montrer où se trouve l'erreur. L'extension VSCode Nextflow devrait également vous donner quelques indices sur ce qui pourrait ne pas aller, en mettant l'accolade mal appariée en rouge et en soulignant la fin prématurée du fichier : + +![Bad syntax](img/bad_syntax.png) + +**Stratégie de débogage pour les erreurs d'accolades :** + +1. Utilisez la correspondance d'accolades de VS Code (placez le curseur à côté d'une accolade) +2. Vérifiez le panneau Problèmes pour les messages liés aux accolades +3. Assurez-vous que chaque `{` d'ouverture a un `}` de fermeture correspondant + +#### Corriger le code + +Remplacez le commentaire par l'accolade fermante manquante : + +=== "Après" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Ajoute l'accolade fermante manquante + + workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) + } + ``` + +=== "Avant" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Accolade fermante manquante pour le processus + + workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) + } + ``` + +#### Exécuter le pipeline + +Maintenant, exécutez à nouveau le workflow pour confirmer qu'il fonctionne : + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Utilisation de mots-clés ou directives de processus incorrects + +Une autre erreur de syntaxe courante est une **définition de processus invalide**. Cela peut se produire si vous oubliez de définir des blocs requis ou si vous utilisez des directives incorrectes dans la définition du processus. + +#### Exécuter le pipeline + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Vérifier le code + +L'erreur indique une "Définition de processus invalide" et montre le contexte autour du problème. En regardant les lignes 3-7, nous pouvons voir `inputs:` à la ligne 4, qui est le problème. Examinons `invalid_process.nf` : + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // ERREUR : Devrait être 'input' et non 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) +} +``` + +En regardant la ligne 4 dans le contexte de l'erreur, nous pouvons repérer le problème : nous utilisons `inputs` au lieu de la directive correcte `input`. L'extension VSCode Nextflow signalera également ceci : + +![Invalid process message](img/invalid_process_message.png) + +#### Corriger le code + +Remplacez le mot-clé incorrect par le bon en consultant [la documentation](https://www.nextflow.io/docs/latest/process.html#) : + +=== "Après" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Corrigé : Changé 'inputs' en 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) + } + ``` + +=== "Avant" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // ERREUR : Devrait être 'input' et non 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crée un canal d'entrée + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Appelle le processus avec le canal d'entrée + PROCESS_FILES(input_ch) + } + ``` + +#### Exécuter le pipeline + +Maintenant, exécutez à nouveau le workflow pour confirmer qu'il fonctionne : + +```bash +nextflow run invalid_process.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Utilisation de mauvais noms de variables + +Les noms de variables que vous utilisez dans vos blocs de script doivent être valides, dérivés soit des entrées, soit du code groovy inséré avant le script. Mais lorsque vous gérez la complexité au début du développement de pipeline, il est facile de faire des erreurs dans la dénomination des variables, et Nextflow vous le fera savoir rapidement. + +#### Exécuter le pipeline + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +L'erreur est détectée au moment de la compilation et pointe directement vers la variable non définie à la ligne 17, avec un caret indiquant exactement où se trouve le problème. + +#### Vérifier le code + +Examinons `no_such_var.nf` : + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERREUR : undefined_var non définie + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +Le message d'erreur indique que la variable n'est pas reconnue dans le template de script, et vous devriez pouvoir voir `${undefined_var}` utilisé dans le bloc script, mais non défini ailleurs. + +#### Corriger le code + +Si vous obtenez une erreur 'No such variable', vous pouvez la corriger soit en définissant la variable (en corrigeant les noms de variables d'entrée ou en modifiant le code groovy avant le script), soit en la supprimant du bloc script si elle n'est pas nécessaire : + +=== "Après" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Supprime la ligne avec undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Avant" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERREUR : undefined_var non définie + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Exécuter le pipeline + +Maintenant, exécutez à nouveau le workflow pour confirmer qu'il fonctionne : + +```bash +nextflow run no_such_var.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Mauvaise utilisation des variables Bash + +En débutant avec Nextflow, il peut être difficile de comprendre la différence entre les variables Nextflow (Groovy) et Bash. Cela peut générer une autre forme d'erreur de variable incorrecte qui apparaît lors de la tentative d'utilisation de variables dans le contenu Bash du bloc script. + +#### Exécuter le pipeline + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Vérifier le code + +L'erreur pointe vers la ligne 13 où `${prefix}` est utilisé. Examinons `bad_bash_var.nf` pour voir ce qui cause le problème : + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +Dans cet exemple, nous définissons la variable `prefix` en Bash, mais dans un processus Nextflow, la syntaxe `$` que nous avons utilisée pour y faire référence (`${prefix}`) est interprétée comme une variable Groovy, pas Bash. La variable n'existe pas dans le contexte Groovy, donc nous obtenons une erreur 'no such variable'. + +#### Corriger le code + +Si vous voulez utiliser une variable Bash, vous devez échapper le signe dollar comme ceci : + +=== "Après" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Avant" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +Cela indique à Nextflow d'interpréter ceci comme une variable Bash. + +#### Exécuter le pipeline + +Maintenant, exécutez à nouveau le workflow pour confirmer qu'il fonctionne : + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Variables Groovy vs Variables Bash" + + Pour les manipulations de variables simples comme la concaténation de chaînes ou les opérations de préfixe/suffixe, il est généralement plus lisible d'utiliser des variables Groovy dans la section script plutôt que des variables Bash dans le bloc script : + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Cette approche évite le besoin d'échapper les signes dollar et rend le code plus facile à lire et à maintenir. + +### 1.5. Instructions en Dehors du Bloc Workflow + +L'extension VSCode Nextflow met en évidence les problèmes de structure de code qui causeront des erreurs. Un exemple courant est la définition de canaux en dehors du bloc `workflow {}` - ceci est maintenant imposé comme une erreur de syntaxe. + +#### Exécuter le pipeline + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Le message d'erreur indique clairement le problème : les instructions (comme les définitions de canaux) ne peuvent pas être mélangées avec les déclarations de script en dehors d'un bloc workflow ou process. + +#### Vérifier le code + +Examinons `badpractice_syntax.nf` pour voir ce qui cause l'erreur : + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // ERREUR : Canal défini en dehors du workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +L'extension VSCode soulignera également la variable `input_ch` comme étant définie en dehors du bloc workflow : + +![Non-lethal syntax error](img/nonlethal.png) + +#### Corriger le code + +Déplacez la définition du canal à l'intérieur du bloc workflow : + +=== "Après" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Déplacé à l'intérieur du bloc workflow + PROCESS_FILES(input_ch) + } + ``` + +=== "Avant" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // ERREUR : Canal défini en dehors du workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Définit les variables dans le code Groovy avant le script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Exécuter le pipeline + +Exécutez à nouveau le workflow pour confirmer que la correction fonctionne : + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Gardez vos canaux d'entrée définis dans le bloc workflow, et en général suivez toutes les autres recommandations faites par l'extension. + +### À retenir + +Vous pouvez identifier et corriger systématiquement les erreurs de syntaxe en utilisant les messages d'erreur de Nextflow et les indicateurs visuels de l'IDE. Les erreurs de syntaxe courantes incluent les accolades manquantes, les mots-clés de processus incorrects, les variables non définies et l'utilisation inappropriée des variables Bash vs Nextflow. L'extension VSCode aide à détecter bon nombre de ces erreurs avant l'exécution. Avec ces compétences de débogage de syntaxe dans votre boîte à outils, vous serez capable de résoudre rapidement les erreurs de syntaxe Nextflow les plus courantes et de passer à la résolution de problèmes d'exécution plus complexes. + +### Et ensuite ? + +Apprenez à déboguer des erreurs de structure de canal plus complexes qui se produisent même lorsque la syntaxe est correcte. + +--- + +## 2. Erreurs de Structure des Canaux + +Les erreurs de structure des canaux sont plus subtiles que les erreurs de syntaxe car le code est syntaxiquement correct, mais les formes de données ne correspondent pas à ce que les processus attendent. Nextflow tentera d'exécuter le pipeline, mais pourrait constater que le nombre d'entrées ne correspond pas à ce qu'il attend et échouer. Ces erreurs n'apparaissent généralement qu'à l'exécution et nécessitent une compréhension des données circulant dans votre workflow. + +!!! tip "Débogage des Canaux avec `.view()`" + + Tout au long de cette section, rappelez-vous que vous pouvez utiliser l'opérateur `.view()` pour inspecter le contenu des canaux à n'importe quel point de votre workflow. C'est l'un des outils de débogage les plus puissants pour comprendre les problèmes de structure des canaux. Nous explorerons cette technique en détail dans la section 2.4, mais n'hésitez pas à l'utiliser pendant que vous travaillez sur les exemples. + + ```groovy + my_channel.view() // Affiche ce qui circule dans le canal + ``` + +### 2.1. Mauvais Nombre de Canaux d'Entrée + +Cette erreur se produit lorsque vous passez un nombre différent de canaux que ce qu'un processus attend. + +#### Exécuter le pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Vérifier le code + +Le message d'erreur indique clairement que l'appel attendait 1 argument mais en a reçu 2, et pointe vers la ligne 23. Examinons `bad_number_inputs.nf` : + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Le processus n'attend qu'une seule entrée + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Crée deux canaux séparés + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERREUR : Passe 2 canaux mais le processus n'en attend qu'un seul + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Vous devriez voir l'appel `PROCESS_FILES` mal apparié, fournissant plusieurs canaux d'entrée alors que le processus n'en définit qu'un. L'extension VSCode soulignera également l'appel du processus en rouge, et fournira un message de diagnostic au survol : + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Corriger le code + +Pour cet exemple spécifique, le processus attend un seul canal et ne nécessite pas le second canal, nous pouvons donc le corriger en passant uniquement le canal `samples_ch` : + +=== "Après" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Le processus n'attend qu'une seule entrée + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crée deux canaux séparés + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Corrigé : Passe uniquement le canal que le processus attend + PROCESS_FILES(samples_ch) + } + ``` + +=== "Avant" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Le processus n'attend qu'une seule entrée + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crée deux canaux séparés + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERREUR : Passe 2 canaux mais le processus n'en attend qu'un seul + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Exécuter le pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Plus couramment que dans cet exemple, vous pourriez ajouter des entrées supplémentaires à un processus et oublier de mettre à jour l'appel du workflow en conséquence, ce qui peut conduire à ce type d'erreur. Heureusement, c'est l'une des erreurs les plus faciles à comprendre et à corriger, car le message d'erreur est assez clair sur le décalage. + +### 2.2. Épuisement des Canaux (Le Processus S'Exécute Moins de Fois Que Prévu) + +Certaines erreurs de structure de canal sont beaucoup plus subtiles et ne produisent aucune erreur du tout. Probablement la plus courante de celles-ci reflète un défi auquel les nouveaux utilisateurs de Nextflow sont confrontés en comprenant que les canaux de file peuvent être épuisés et manquer d'éléments, ce qui signifie que le workflow se termine prématurément. + +#### Exécuter le pipeline + +```bash +nextflow run exhausted.nf +``` + +??? success "Sortie de la commande" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Ce workflow se termine sans erreur, mais il ne traite qu'un seul échantillon ! + +#### Vérifier le code + +Examinons `exhausted.nf` pour voir si c'est correct : + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Définit les variables dans le code Groovy avant le script + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Le processus ne s'exécute qu'une seule fois au lieu de trois fois car le canal `reference_ch` est un canal de file qui s'épuise après la première exécution du processus. Lorsqu'un canal est épuisé, l'ensemble du processus s'arrête, même si d'autres canaux ont encore des éléments. + +C'est un modèle courant où vous avez un seul fichier de référence qui doit être réutilisé sur plusieurs échantillons. La solution consiste à convertir le canal de référence en canal de valeur qui peut être réutilisé indéfiniment. + +#### Corriger le code + +Il existe plusieurs façons de résoudre ce problème selon le nombre de fichiers affectés. + +**Option 1** : Vous avez un seul fichier de référence que vous réutilisez beaucoup. Vous pouvez simplement créer un type de canal de valeur, qui peut être utilisé encore et encore. Il y a trois façons de faire cela : + +**1a** Utilisez `channel.value()` : + +```groovy title="exhausted.nf (corrigé - Option 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Le canal de valeur peut être réutilisé + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Utilisez l'[opérateur](https://www.nextflow.io/docs/latest/reference/operator.html#first) `first()` : + +```groovy title="exhausted.nf (corrigé - Option 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Convertit en canal de valeur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Utilisez l'[opérateur](https://www.nextflow.io/docs/latest/reference/operator.html#collect) `collect()` : + +```groovy title="exhausted.nf (corrigé - Option 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Convertit en canal de valeur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Option 2** : Dans des scénarios plus complexes, peut-être où vous avez plusieurs fichiers de référence pour tous les échantillons dans le canal d'échantillons, vous pouvez utiliser l'opérateur `combine` pour créer un nouveau canal qui combine les deux canaux en tuples : + +```groovy title="exhausted.nf (corrigé - Option 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Crée un produit cartésien + + PROCESS_FILES(combined_ch) +} +``` + +L'opérateur `.combine()` génère un produit cartésien des deux canaux, donc chaque élément dans `reference_ch` sera apparié avec chaque élément dans `input_ch`. Cela permet au processus de s'exécuter pour chaque échantillon tout en utilisant la référence. + +Cela nécessite d'ajuster l'entrée du processus. Dans notre exemple, le début de la définition du processus devrait être ajusté comme suit : + +```groovy title="exhausted.nf (corrigé - Option 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Cette approche peut ne pas convenir dans toutes les situations. + +#### Exécuter le pipeline + +Essayez l'une des corrections ci-dessus et exécutez à nouveau le workflow : + +```bash +nextflow run exhausted.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Vous devriez maintenant voir tous les trois échantillons être traités au lieu d'un seul. + +### 2.3. Mauvaise Structure du Contenu des Canaux + +Lorsque les workflows atteignent un certain niveau de complexité, il peut être un peu difficile de suivre les structures internes de chaque canal, et les gens génèrent couramment des décalages entre ce que le processus attend et ce que le canal contient réellement. C'est plus subtil que le problème dont nous avons discuté plus tôt, où le nombre de canaux était incorrect. Dans ce cas, vous pouvez avoir le bon nombre de canaux d'entrée, mais la structure interne d'un ou plusieurs de ces canaux ne correspond pas à ce que le processus attend. + +#### Exécuter le pipeline + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Sortie de la commande" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Vérifier le code + +Les crochets dans le message d'erreur fournissent l'indice ici - le processus traite le tuple comme une valeur unique, ce qui n'est pas ce que nous voulons. Examinons `bad_channel_shape.nf` : + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Attend une valeur unique, reçoit un tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Vous pouvez voir que nous générons un canal composé de tuples : `['sample1', 'file1.txt']`, mais le processus attend une valeur unique, `val sample_name`. La commande exécutée montre que le processus essaie de créer un fichier nommé `[sample3, file3.txt]_output.txt`, ce qui n'est pas la sortie prévue. + +#### Corriger le code + +Pour corriger cela, si le processus nécessite les deux entrées, nous pourrions ajuster le processus pour accepter un tuple : + +=== "Option 1: Accepter un tuple dans le processus" + + === "Après" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Corrigé : Accepte le tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Avant" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Attend une valeur unique, reçoit un tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Option 2: Extraire le premier élément" + + === "Après" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Corrigé : Extrait le premier élément + } + ``` + + === "Avant" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Exécuter le pipeline + +Choisissez l'une des solutions et réexécutez le workflow : + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Techniques de Débogage des Canaux + +#### Utilisation de `.view()` pour l'Inspection des Canaux + +L'outil de débogage le plus puissant pour les canaux est l'opérateur `.view()`. Avec `.view()`, vous pouvez comprendre la forme de vos canaux à toutes les étapes pour aider au débogage. + +#### Exécuter le pipeline + +Exécutez `bad_channel_shape_viewed.nf` pour voir cela en action : + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Vérifier le code + +Examinons `bad_channel_shape_viewed.nf` pour voir comment `.view()` est utilisé : + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Débogage : Affiche le contenu original du canal + .map { tuple -> tuple[0] } // Transformation : Extrait le premier élément + .view { "After mapping: $it" } // Débogage : Affiche le contenu transformé du canal + + PROCESS_FILES(input_ch) +} +``` + +#### Corriger le code + +Pour vous éviter d'utiliser excessivement les opérations `.view()` à l'avenir pour comprendre le contenu des canaux, il est conseillé d'ajouter quelques commentaires pour aider : + +```groovy title="bad_channel_shape_viewed.nf (avec commentaires)" linenums="16" hl_lines="8 9" +workflow { + + // Le canal émet des tuples, mais le processus attend des valeurs uniques + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Cela deviendra plus important à mesure que vos workflows gagneront en complexité et que la structure des canaux deviendra plus opaque. + +#### Exécuter le pipeline + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### À retenir + +De nombreuses erreurs de structure de canal peuvent être créées avec une syntaxe Nextflow valide. Vous pouvez déboguer les erreurs de structure de canal en comprenant le flux de données, en utilisant des opérateurs `.view()` pour l'inspection, et en reconnaissant les modèles d'erreur comme les crochets indiquant des structures de tuple inattendues. + +### Et ensuite ? + +Apprenez les erreurs créées par les définitions de processus. + +--- + +## 3. Erreurs de Structure des Processus + +La plupart des erreurs que vous rencontrerez liées aux processus seront liées à des erreurs que vous avez faites dans la formation de la commande, ou à des problèmes liés au logiciel sous-jacent. Cela dit, de manière similaire aux problèmes de canal ci-dessus, vous pouvez faire des erreurs dans la définition du processus qui ne sont pas des erreurs de syntaxe, mais qui causeront des erreurs à l'exécution. + +### 3.1. Fichiers de Sortie Manquants + +Une erreur courante lors de l'écriture de processus est de faire quelque chose qui génère un décalage entre ce que le processus attend et ce qui est généré. + +#### Exécuter le pipeline + +```bash +nextflow run missing_output.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Vérifier le code + +Le message d'erreur indique que le processus s'attendait à produire un fichier de sortie nommé `sample3.txt`, mais le script crée en réalité `sample3_output.txt`. Examinons la définition du processus dans `missing_output.nf` : + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Attend : sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Crée : sample3_output.txt + """ +} +``` + +Vous devriez voir qu'il y a un décalage entre le nom du fichier de sortie dans le bloc `output:`, et celui utilisé dans le script. Ce décalage cause l'échec du processus. Si vous rencontrez ce type d'erreur, retournez vérifier que les sorties correspondent entre votre définition de processus et votre bloc de sortie. + +Si le problème n'est toujours pas clair, vérifiez le répertoire de travail lui-même pour identifier les fichiers de sortie réels créés : + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Pour cet exemple, cela nous mettrait en évidence qu'un suffixe `_output` est incorporé dans le nom du fichier de sortie, contrairement à notre définition `output:`. + +#### Corriger le code + +Corrigez le décalage en rendant le nom de fichier de sortie cohérent : + +=== "Après" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Corrigé : Correspond à la sortie du script + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Avant" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Attend : sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Crée : sample3_output.txt + """ + } + ``` + +#### Exécuter le pipeline + +```bash +nextflow run missing_output.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [elated_hamilton] DSL2 - revision: 961938ee2b + + executor > local (3) + [16/1c437c] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +### 3.2. Logiciel manquant + +Une autre classe d'erreurs se produit en raison d'erreurs dans la fourniture de logiciels. `missing_software.nf` est un workflow syntaxiquement valide, mais il dépend d'un logiciel externe pour fournir la commande `cowpy` qu'il utilise. + +#### Exécuter le pipeline + +```bash +nextflow run missing_software.nf +``` + +??? failure "Sortie de la commande" + + ```console hl_lines="12 18" + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Process `PROCESS_FILES (3)` terminated with an error exit status (127) + + + Command executed: + + cowpy sample3 > sample3_output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/side-quests/debugging/work/82/42a5bfb60c9c6ee63ebdbc2d51aa6e + + Tip: you can try to figure out what's wrong by changing to the process work directory and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Le processus n'a pas accès à la commande que nous spécifions. Parfois, c'est parce qu'un script est présent dans le répertoire `bin` du workflow, mais n'a pas été rendu exécutable. D'autres fois, c'est parce que le logiciel n'est pas installé dans le conteneur ou l'environnement où le workflow s'exécute. + +#### Vérifier le code + +Attention à ce code de sortie `127` - il vous dit exactement le problème. Examinons `missing_software.nf` : + +```groovy title="missing_software.nf" linenums="3" hl_lines="3" +process PROCESS_FILES { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input +``` diff --git a/docs/fr/docs/side_quests/dev_environment.md b/docs/fr/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..1033c3dcb1 --- /dev/null +++ b/docs/fr/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Environnement de Développement + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Les environnements de développement intégrés (IDE) modernes peuvent transformer radicalement votre expérience de développement Nextflow. Cette quête secondaire se concentre spécifiquement sur l'exploitation de VS Code et de son extension Nextflow pour écrire du code plus rapidement, détecter les erreurs tôt et naviguer efficacement dans des workflows complexes. + +!!! note "Ce n'est pas un tutoriel traditionnel" + + Contrairement aux autres modules de formation, ce guide est organisé comme une collection de conseils rapides, d'astuces et d'exemples pratiques plutôt qu'un tutoriel étape par étape. Chaque section peut être explorée indépendamment en fonction de vos intérêts et de vos besoins actuels de développement. N'hésitez pas à naviguer librement et à vous concentrer sur les fonctionnalités qui seront les plus immédiatement utiles pour le développement de votre workflow. + +## Ce que vous devriez savoir d'abord + +Ce guide suppose que vous avez terminé le cours de formation [Hello Nextflow](../hello_nextflow/) et que vous êtes à l'aise avec les concepts fondamentaux de Nextflow, notamment : + +- **Structure de workflow de base** : Comprendre les processus, les workflows et comment ils se connectent ensemble +- **Opérations sur les canaux** : Créer des canaux, transmettre des données entre processus et utiliser les opérateurs de base +- **Modules et organisation** : Créer des modules réutilisables et utiliser les instructions include +- **Bases de la configuration** : Utiliser `nextflow.config` pour les paramètres, les directives de processus et les profils + +## Ce que vous apprendrez ici + +Ce guide se concentre sur les **fonctionnalités de productivité de l'IDE** qui feront de vous un développeur Nextflow plus efficace : + +- **Coloration syntaxique avancée** : Comprendre ce que VS Code vous montre sur la structure de votre code +- **Auto-complétion intelligente** : Exploiter les suggestions contextuelles pour écrire du code plus rapidement +- **Détection d'erreurs et diagnostics** : Détecter les erreurs de syntaxe avant d'exécuter votre workflow +- **Navigation dans le code** : Se déplacer rapidement entre processus, modules et définitions +- **Formatage et organisation** : Maintenir un style de code cohérent et lisible +- **Développement assisté par IA** (optionnel) : Utiliser des outils IA modernes intégrés à votre IDE + +!!! info "Pourquoi les fonctionnalités IDE maintenant ?" + + Vous avez probablement déjà utilisé VS Code pendant le cours [Hello Nextflow](../hello_nextflow/), mais nous avons maintenu l'accent sur l'apprentissage des fondamentaux de Nextflow plutôt que sur les fonctionnalités de l'IDE. Maintenant que vous êtes à l'aise avec les concepts de base de Nextflow comme les processus, workflows, canaux et modules, vous êtes prêt à exploiter les fonctionnalités sophistiquées de l'IDE qui feront de vous un développeur plus efficace. + + Considérez cela comme une « montée en compétence » de votre environnement de développement - l'éditeur que vous utilisez déjà possède des capacités bien plus puissantes qui deviennent vraiment précieuses une fois que vous comprenez ce qu'elles vous apportent. + +--- + +## 0. Configuration et Préparation + +Configurons un espace de travail spécifiquement pour explorer les fonctionnalités de l'IDE : + +```bash title="Naviguer vers le répertoire des fonctionnalités IDE" +cd side-quests/ide_features +``` + +Ouvrez ce répertoire dans VS Code : + +```bash title="Ouvrir VS Code dans le répertoire courant" +code . +``` + +Le répertoire `ide_features` contient des exemples de workflows qui démontrent diverses fonctionnalités de l'IDE : + +```bash title="Afficher la structure du répertoire" +tree . +``` + +```console title="Structure du projet" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "À propos des fichiers d'exemple" + + - `basic_workflow.nf` est un workflow de base fonctionnel que vous pouvez exécuter et modifier + - `complex_workflow.nf` est conçu uniquement à titre d'illustration pour démontrer les fonctionnalités de navigation - il peut ne pas s'exécuter correctement mais montre une structure de workflow multi-fichiers réaliste + +### Raccourcis Clavier + +Certaines des fonctionnalités de ce guide utiliseront des raccourcis clavier optionnels. Vous accédez peut-être à ce matériel via GitHub Codespaces dans un navigateur, et dans ce cas, les raccourcis ne fonctionneront parfois pas comme prévu car ils sont utilisés pour d'autres fonctions dans votre système. + +Si vous exécutez VS Code localement, comme vous le ferez probablement lorsque vous écrirez réellement des workflows, les raccourcis fonctionneront comme décrit. + +Si vous utilisez un Mac, certains (pas tous) raccourcis clavier utiliseront « cmd » au lieu de « ctrl », et nous l'indiquerons dans le texte comme `Ctrl/Cmd`. + +### 0.1. Installation de l'Extension Nextflow + +!!! note "Vous utilisez déjà des Devcontainers ?" + + Si vous travaillez dans **GitHub Codespaces** ou utilisez un **devcontainer local**, l'extension Nextflow est probablement déjà installée et configurée pour vous. Vous pouvez ignorer les étapes d'installation manuelle ci-dessous et passer directement à l'exploration des fonctionnalités de l'extension. + +Pour installer l'extension manuellement : + +1. Ouvrez VS Code +2. Accédez à la vue Extensions en cliquant sur l'icône des extensions à gauche : ![icône des extensions](img/extensions_icon.png) (raccourci `Ctrl/Cmd+Shift+X` si vous exécutez VSCode localement) +3. Recherchez « Nextflow » +4. Installez l'extension officielle Nextflow + +![Installer l'extension Nextflow](img/install_extension.png) + +### 0.2. Disposition de l'Espace de Travail + +Puisque vous avez utilisé VS Code tout au long de Hello Nextflow, vous connaissez déjà les bases. Voici comment organiser efficacement votre espace de travail pour cette session : + +- **Zone d'Édition** : Pour visualiser et éditer les fichiers. Vous pouvez diviser cette zone en plusieurs panneaux pour comparer des fichiers côte à côte. +- **Explorateur de Fichiers** cliquez (![icône de l'explorateur de fichiers](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`) : Les fichiers et dossiers locaux sur votre système. Gardez-le ouvert à gauche pour naviguer entre les fichiers +- **Terminal Intégré** (`Ctrl+Shift+` backtick pour Windows et MacOS) : Un terminal pour interagir avec l'ordinateur en bas. Utilisez-le pour exécuter Nextflow ou d'autres commandes. +- **Panneau Problèmes** (`Ctrl+Shift+M`) : VS Code affichera ici toutes les erreurs et problèmes qu'il détecte. Ceci est utile pour mettre en évidence les problèmes d'un coup d'œil. + +Vous pouvez faire glisser les panneaux ou les masquer (`Ctrl/Cmd+B` pour basculer la barre latérale) afin de personnaliser votre disposition pendant que nous travaillons sur les exemples. + +### Points Clés + +Vous avez VS Code configuré avec l'extension Nextflow et comprenez la disposition de l'espace de travail pour un développement efficace. + +### Et Ensuite ? + +Découvrez comment la coloration syntaxique vous aide à comprendre la structure du code Nextflow d'un seul coup d'œil. + +--- + +## 1. Coloration Syntaxique et Structure du Code + +Maintenant que votre espace de travail est configuré, explorons comment la coloration syntaxique de VS Code vous aide à lire et écrire du code Nextflow plus efficacement. + +### 1.1. Éléments de Syntaxe Nextflow + +Ouvrez `basic_workflow.nf` pour voir la coloration syntaxique en action : + +![Présentation de la syntaxe](img/syntax_showcase.png) + +Remarquez comment VS Code met en évidence : + +- **Les mots-clés** (`process`, `workflow`, `input`, `output`, `script`) dans des couleurs distinctes +- **Les chaînes littérales** et **les paramètres** avec un style différent +- **Les commentaires** dans une couleur atténuée +- **Les variables** et **les appels de fonction** avec l'emphase appropriée +- **Les blocs de code** avec des guides d'indentation appropriés + +!!! note "Couleurs Dépendantes du Thème" + + Les couleurs spécifiques que vous voyez dépendront de votre thème VS Code (mode sombre/clair), des paramètres de couleur et de toute personnalisation que vous avez effectuée. L'important est que les différents éléments de syntaxe soient visuellement distingués les uns des autres, rendant la structure du code plus facile à comprendre quel que soit le schéma de couleurs choisi. + +### 1.2. Comprendre la Structure du Code + +La coloration syntaxique vous aide à identifier rapidement : + +- **Les limites des processus** : Distinction claire entre différents processus +- **Les blocs d'entrée/sortie** : Facile à repérer les définitions de flux de données +- **Les blocs script** : Les commandes réellement exécutées +- **Les opérations sur les canaux** : Les étapes de transformation de données +- **Les directives de configuration** : Les paramètres spécifiques aux processus + +Cette organisation visuelle devient inestimable lorsque vous travaillez avec des workflows complexes contenant plusieurs processus et des flux de données complexes. + +### Points Clés + +Vous comprenez comment la coloration syntaxique de VS Code vous aide à lire la structure du code Nextflow et à identifier différents éléments du langage pour un développement plus rapide. + +### Et Ensuite ? + +Découvrez comment l'auto-complétion intelligente accélère l'écriture de code avec des suggestions contextuelles. + +--- + +## 2. Auto-complétion Intelligente + +Les fonctionnalités d'auto-complétion de VS Code vous aident à écrire du code plus rapidement et avec moins d'erreurs en suggérant des options appropriées en fonction du contexte. + +### 2.1. Suggestions Contextuelles + +Les options d'auto-complétion varient en fonction de l'endroit où vous vous trouvez dans votre code : + +#### Opérations sur les Canaux + +Ouvrez à nouveau `basic_workflow.nf` et essayez de taper `channel.` dans le bloc workflow : + +![Auto-complétion des canaux](img/autocomplete_channel.png) + +Vous verrez des suggestions pour : + +- `fromPath()` - Créer un canal à partir de chemins de fichiers +- `fromFilePairs()` - Créer un canal à partir de fichiers appariés +- `of()` - Créer un canal à partir de valeurs +- `fromSRA()` - Créer un canal à partir d'accessions SRA +- Et bien d'autres... + +Cela vous aide à trouver rapidement la bonne fabrique de canaux à utiliser sans avoir besoin de mémoriser les noms exacts des méthodes. + +Vous pouvez également découvrir les opérateurs disponibles à appliquer aux canaux. Par exemple, tapez `FASTQC.out.html.` pour voir les opérations disponibles : + +![Auto-complétion des opérateurs de canaux](img/autocomplete_operators.png) + +#### Directives de Processus + +À l'intérieur d'un bloc script de processus, tapez `task.` pour voir les propriétés d'exécution disponibles : + +![Auto-complétion des propriétés task](img/autocomplete_task.png) + +#### Configuration + +Ouvrez nextflow.config et tapez `process.` n'importe où pour voir les directives de processus disponibles : + +![Auto-complétion de configuration](img/autocomplete_config.png) + +Vous verrez des suggestions pour : + +- `executor` +- `memory` +- `cpus` + +Cela fait gagner du temps lors de la configuration des processus et fonctionne dans différents contextes de configuration. Par exemple, essayez de taper `docker.` pour voir les options de configuration spécifiques à Docker. + +### Points Clés + +Vous pouvez utiliser l'auto-complétion intelligente de VS Code pour découvrir les opérations de canaux disponibles, les directives de processus et les options de configuration sans mémoriser la syntaxe. + +### Et Ensuite ? + +Découvrez comment la détection d'erreurs en temps réel vous aide à détecter les problèmes avant d'exécuter votre workflow, simplement en lisant le code. + +## 3. Détection d'Erreurs et Diagnostics + +La détection d'erreurs en temps réel de VS Code vous aide à détecter les problèmes avant d'exécuter votre workflow. + +### 3.1. Détection d'Erreurs de Syntaxe + +Créons une erreur délibérée pour voir la détection en action. Ouvrez `basic_workflow.nf` et changez le nom du processus de `FASTQC` à `FASTQ` (ou tout autre nom invalide). VS Code mettra immédiatement en évidence l'erreur dans le bloc workflow avec un soulignement ondulé rouge : + +![Soulignement d'erreur](img/error_underline.png) + +### 3.2. Panneau Problèmes + +Au-delà de la mise en évidence individuelle des erreurs, VS Code fournit un panneau Problèmes centralisé qui agrège toutes les erreurs, avertissements et messages d'information dans votre espace de travail. Ouvrez-le avec `Ctrl/Cmd+Shift+M` et utilisez l'icône de filtre pour afficher uniquement les erreurs pertinentes pour le fichier actuel : + +![Filtrer le panneau problèmes](img/active_file.png) + +Cliquez sur n'importe quel problème pour accéder directement à la ligne problématique + +![Panneau Problèmes](img/problems_panel.png) + +Corrigez l'erreur en changeant le nom du processus pour revenir à `FASTQC`. + +### 3.3. Modèles d'Erreurs Courants + +Les erreurs courantes dans la syntaxe Nextflow incluent : + +- **Parenthèses manquantes** : `{` ou `}` non appariés +- **Blocs incomplets** : Sections requises manquantes dans les processus +- **Syntaxe invalide** : DSL Nextflow mal formé +- **Fautes de frappe dans les mots-clés** : Directives de processus mal orthographiées +- **Incompatibilités de canaux** : Incompatibilités de types + +Le serveur de langage Nextflow met en évidence ces problèmes dans le panneau Problèmes. Vous pouvez les vérifier tôt pour éviter les erreurs de syntaxe lors de l'exécution d'un pipeline. + +### Points Clés + +Vous pouvez utiliser la détection d'erreurs de VS Code et le panneau Problèmes pour détecter les erreurs de syntaxe et les problèmes avant d'exécuter votre workflow, économisant du temps et évitant la frustration. + +### Et Ensuite ? + +Découvrez comment naviguer efficacement entre processus, modules et définitions dans des workflows complexes. + +--- + +## 4. Navigation dans le Code et Gestion des Symboles + +Une navigation efficace est cruciale lorsque vous travaillez avec des workflows complexes répartis sur plusieurs fichiers. Pour comprendre cela, remplacez la définition du processus dans `basic_workflow.nf` par une importation du module que nous vous avons fourni : + +=== "Après" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Avant" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Aller à la Définition + +Si vous passez la souris sur un nom de processus comme `FASTQC`, vous verrez une fenêtre contextuelle avec l'interface du module (entrées et sorties) : + +![Aller à la définition](img/syntax.png) + +Cette fonctionnalité est particulièrement précieuse lors de la création de workflows, car elle vous permet de comprendre l'interface du module sans ouvrir directement le fichier du module. + +Vous pouvez naviguer rapidement vers n'importe quelle définition de processus, module ou variable en utilisant **Ctrl/Cmd-clic**. Passez la souris sur le lien vers le fichier du module en haut du script, et suivez le lien comme suggéré : + +![Suivre le lien](img/follow_link.png) + +La même chose fonctionne pour les noms de processus. Retournez à `basic_workflow.nf` et essayez ceci sur le nom du processus `FASTQC` dans le bloc workflow. Cela vous lie directement au nom du processus (qui est le même que le fichier du module dans cet exemple, mais pourrait être à mi-chemin d'un fichier beaucoup plus grand). + +Pour revenir à l'endroit où vous étiez, utilisez **Alt+←** (ou **Ctrl+-** sur Mac). C'est une façon puissante d'explorer le code sans perdre votre position. + +Explorons maintenant la navigation dans un workflow plus complexe en utilisant `complex_workflow.nf` (le fichier d'illustration uniquement mentionné précédemment). Ce workflow contient plusieurs processus définis dans des fichiers de module séparés, ainsi que certains en ligne. Bien que les structures multi-fichiers complexes puissent être difficiles à naviguer manuellement, la capacité à accéder aux définitions rend l'exploration beaucoup plus gérable. + +1. Ouvrez `complex_workflow.nf` +2. Naviguez vers les définitions de modules +3. Utilisez **Alt+←** (ou **Ctrl+-**) pour revenir en arrière +4. Naviguez vers le nom du processus `FASTQC` dans le bloc workflow. Cela vous lie directement au nom du processus (qui est le même que le fichier du module dans cet exemple, mais pourrait être à mi-chemin d'un fichier beaucoup plus grand). +5. Naviguez à nouveau en arrière +6. Naviguez vers le processus `TRIM_GALORE` dans le bloc workflow. Celui-ci est défini en ligne, il ne vous mènera donc pas vers un fichier séparé, mais il vous montrera quand même la définition du processus, et vous pourrez toujours revenir à l'endroit où vous étiez. + +### 4.2. Navigation par Symboles + +Avec `complex_workflow.nf` toujours ouvert, vous pouvez obtenir un aperçu de tous les symboles du fichier en tapant `@` dans la barre de recherche en haut de VSCode (le raccourci clavier est `Ctrl/Cmd+Shift+O`, mais peut ne pas fonctionner dans Codespaces). Cela ouvre le panneau de navigation par symboles, qui liste tous les symboles du fichier actuel : + +![Navigation par symboles](img/symbols.png) + +Cela affiche : + +- Toutes les définitions de processus +- Les définitions de workflow (il y a deux workflows définis dans ce fichier) +- Les définitions de fonctions + +Commencez à taper pour filtrer les résultats. + +### 4.3. Rechercher Toutes les Références + +Comprendre où un processus ou une variable est utilisé dans votre base de code peut être très utile. Par exemple, si vous voulez trouver toutes les références au processus `FASTQC`, commencez par naviguer vers sa définition. Vous pouvez le faire en ouvrant `modules/fastqc.nf` directement, ou en utilisant la fonctionnalité de navigation rapide de VS Code avec `Ctrl/Cmd-clic` comme nous l'avons fait ci-dessus. Une fois à la définition du processus, faites un clic droit sur le nom du processus `FASTQC` et sélectionnez « Find All References » dans le menu contextuel pour voir toutes les instances où il est utilisé. + +![Rechercher les références](img/references.png) + +Cette fonctionnalité affiche toutes les instances où `FASTQC` est référencé dans votre espace de travail, y compris son utilisation dans les deux workflows distincts. Cette information est cruciale pour évaluer l'impact potentiel des modifications du processus `FASTQC`. + +### 4.4. Panneau Plan + +Le panneau Plan, situé dans la barre latérale de l'Explorateur (cliquez ![Icône Explorateur](img/files_icon.png)), fournit un aperçu pratique de tous les symboles de votre fichier actuel. Cette fonctionnalité vous permet de naviguer rapidement et de gérer la structure de votre code en affichant les fonctions, variables et autres éléments clés dans une vue hiérarchique. + +![Panneau Plan](img/outline.png) + +Utilisez le panneau Plan pour naviguer rapidement vers différentes parties de votre code sans utiliser l'explorateur de fichiers. + +### 4.5. Visualisation DAG + +L'extension Nextflow de VS Code peut visualiser votre workflow sous forme de graphe acyclique dirigé (DAG). Cela vous aide à comprendre le flux de données et les dépendances entre processus. Ouvrez `complex_workflow.nf` et cliquez sur le bouton « Preview DAG » au-dessus de `workflow {` (le deuxième bloc `workflow` dans ce fichier) : + +![Aperçu DAG](img/dag_preview.png) + +Il ne s'agit que du workflow « d'entrée », mais vous pouvez également prévisualiser le DAG pour les workflows internes en cliquant sur le bouton « Preview DAG » au-dessus du workflow `RNASEQ_PIPELINE {` plus haut : + +![Aperçu DAG workflow interne](img/dag_preview_inner.png) + +Pour ce workflow, vous pouvez utiliser les nœuds du DAG pour naviguer vers les définitions de processus correspondantes dans le code. Cliquez sur un nœud, et il vous mènera à la définition de processus pertinente dans l'éditeur. Particulièrement lorsqu'un workflow atteint une grande taille, cela peut vraiment vous aider à naviguer dans le code et à comprendre comment les processus sont connectés. + +### Points Clés + +Vous pouvez naviguer efficacement dans des workflows complexes en utilisant l'aller-à-la-définition, la recherche de symboles, la recherche de références et la visualisation DAG pour comprendre la structure du code et les dépendances. + +### Et Ensuite ? + +Découvrez comment travailler efficacement sur plusieurs fichiers interconnectés dans de plus grands projets Nextflow. + +## 5. Travailler sur Plusieurs Fichiers + +Le développement réel de Nextflow implique de travailler avec plusieurs fichiers interconnectés. Explorons comment VS Code vous aide à gérer efficacement des projets complexes. + +### 5.1. Navigation Rapide entre Fichiers + +Avec `complex_workflow.nf` ouvert, vous remarquerez qu'il importe plusieurs modules. Pratiquons la navigation rapide entre eux. + +Appuyez sur **Ctrl+P** (ou **Cmd+P**) et commencez à taper « fast » : + +VS Code vous montrera les fichiers correspondants. Sélectionnez `modules/fastqc.nf` pour y accéder instantanément. C'est beaucoup plus rapide que de cliquer dans l'explorateur de fichiers lorsque vous savez à peu près quel fichier vous recherchez. + +Essayez ceci avec d'autres modèles : + +- Tapez « star » pour trouver le fichier du module d'alignement STAR (`star.nf`) +- Tapez « utils » pour trouver le fichier des fonctions utilitaires (`utils.nf`) +- Tapez « config » pour accéder aux fichiers de configuration (`nextflow.config`) + +### 5.2. Éditeur Divisé pour le Développement Multi-fichiers + +Lorsque vous travaillez avec des modules, vous devez souvent voir à la fois le workflow principal et les définitions de modules simultanément. Configurons cela : + +1. Ouvrez `complex_workflow.nf` +2. Ouvrez `modules/fastqc.nf` dans un nouvel onglet +3. Faites un clic droit sur l'onglet `modules/fastqc.nf` et sélectionnez « Split Right » +4. Maintenant vous pouvez voir les deux fichiers côte à côte + +![Éditeur divisé](img/split_editor.png) + +Ceci est inestimable lorsque : + +- Vous vérifiez les interfaces de modules pendant l'écriture d'appels de workflow, et l'aperçu ne suffit pas +- Vous comparez des processus similaires dans différents modules +- Vous déboguez le flux de données entre workflow et modules + +### 5.3. Recherche à l'Échelle du Projet + +Parfois, vous devez trouver où des modèles spécifiques sont utilisés dans l'ensemble de votre projet. Appuyez sur `Ctrl/Cmd+Shift+F` pour ouvrir le panneau de recherche. + +Essayez de rechercher `publishDir` dans l'espace de travail : + +![Recherche de projet](img/project_search.png) + +Cela vous montre tous les fichiers qui utilisent des répertoires de publication, vous aidant à : + +- Comprendre les modèles d'organisation de sortie +- Trouver des exemples de directives spécifiques +- Assurer la cohérence entre les modules + +### Points Clés + +Vous pouvez gérer des projets multi-fichiers complexes en utilisant la navigation rapide entre fichiers, les éditeurs divisés et la recherche à l'échelle du projet pour travailler efficacement sur les workflows et les modules. + +### Et Ensuite ? + +Découvrez comment les fonctionnalités de formatage et de maintenance du code maintiennent vos workflows organisés et lisibles. + +--- + +## 6. Formatage et Maintenance du Code + +Un formatage correct du code est essentiel non seulement pour l'esthétique mais aussi pour améliorer la lisibilité, la compréhension et la facilité de mise à jour de workflows complexes. + +### 6.1. Formatage Automatique en Action + +Ouvrez `basic_workflow.nf` et dérangez délibérément le formatage : + +- Supprimez quelques indentations : Mettez en surbrillance l'ensemble du document et appuyez plusieurs fois sur `shift+tab` pour supprimer autant d'indentations que possible. +- Ajoutez des espaces supplémentaires à des endroits aléatoires : dans l'instruction `channel.fromPath`, ajoutez 30 espaces après le `(`. +- Cassez maladroitement certaines lignes : Ajoutez une nouvelle ligne entre l'opérateur `.view {` et la chaîne `Processing sample:` mais n'ajoutez pas de nouvelle ligne correspondante avant la parenthèse fermante `}`. + +Maintenant, appuyez sur `Shift+Alt+F` (ou `Shift+Option+F` sur MacOS) pour auto-formater : + +VS Code immédiatement : + +- Corrige l'indentation pour montrer clairement la structure du processus +- Aligne les éléments similaires de manière cohérente +- Supprime les espaces inutiles +- Maintient des sauts de ligne lisibles + +Notez que le formatage automatique peut ne pas résoudre tous les problèmes de style de code. Le serveur de langage Nextflow vise à garder votre code propre, mais il respecte également vos préférences personnelles dans certains domaines. Par exemple, si vous supprimez l'indentation à l'intérieur du bloc `script` d'un processus, le formateur la laissera telle quelle, car vous pourriez intentionnellement préférer ce style. + +Actuellement, il n'y a pas d'application stricte de style pour Nextflow, donc le serveur de langage offre une certaine flexibilité. Cependant, il appliquera systématiquement les règles de formatage autour des définitions de méthodes et de fonctions pour maintenir la clarté. + +### 6.2. Fonctionnalités d'Organisation du Code + +#### Commentaires Rapides + +Sélectionnez un bloc de code dans votre workflow et appuyez sur **Ctrl+/** (ou **Cmd+/**) pour le commenter : + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +C'est parfait pour : + +- Désactiver temporairement des parties de workflows pendant le développement +- Ajouter des commentaires explicatifs à des opérations de canaux complexes +- Documenter des sections de workflow + +Utilisez à nouveau **Ctrl+/** (ou **Cmd+/**) pour décommenter le code. + +#### Pliage de Code pour Aperçu + +Dans `complex_workflow.nf`, remarquez les petites flèches à côté des définitions de processus. Cliquez dessus pour plier (réduire) les processus : + +![Pliage de code](img/code_folding.png) + +Cela vous donne un aperçu de haut niveau de la structure de votre workflow sans vous perdre dans les détails d'implémentation. + +#### Correspondance des Parenthèses + +Placez votre curseur à côté de n'importe quelle parenthèse `{` ou `}` et VS Code met en évidence la parenthèse correspondante. Utilisez **Ctrl+Shift+\\** (ou **Cmd+Shift+\\**) pour sauter entre parenthèses correspondantes. + +Ceci est crucial pour : + +- Comprendre les limites des processus +- Trouver les parenthèses manquantes ou supplémentaires +- Naviguer dans les structures de workflow imbriquées + +#### Sélection et Édition Multi-lignes + +Pour éditer plusieurs lignes simultanément, VS Code offre de puissantes capacités multi-curseurs : + +- **Sélection multi-lignes** : Maintenez **Ctrl+Alt** (ou **Cmd+Option** pour MacOS) et utilisez les touches fléchées pour sélectionner plusieurs lignes +- **Indentation multi-lignes** : Sélectionnez plusieurs lignes et utilisez **Tab** pour indenter ou **Shift+Tab** pour désindenter des blocs entiers + +Ceci est particulièrement utile pour : + +- Indenter des blocs de processus entiers de manière cohérente +- Ajouter des commentaires à plusieurs lignes à la fois +- Éditer des définitions de paramètres similaires dans plusieurs processus + +### Points Clés + +Vous pouvez maintenir un code propre et lisible en utilisant le formatage automatique, les fonctionnalités de commentaires, le pliage de code, la correspondance des parenthèses et l'édition multi-lignes pour organiser efficacement des workflows complexes. + +### Et Ensuite ? + +Découvrez comment VS Code s'intègre à votre workflow de développement plus large au-delà de la simple édition de code. + +--- + +## 7. Intégration du Workflow de Développement + +VS Code s'intègre bien avec votre workflow de développement au-delà de la simple édition de code. + +### 7.1. Intégration du Contrôle de Version + +!!! note "Codespaces et Intégration Git" + + Si vous travaillez dans **GitHub Codespaces**, certaines fonctionnalités d'intégration Git peuvent ne pas fonctionner comme prévu, en particulier les raccourcis clavier pour le contrôle de source. Vous avez peut-être également refusé d'ouvrir le répertoire en tant que dépôt Git lors de la configuration initiale, ce qui est acceptable à des fins de formation. + +Si votre projet est un dépôt git (comme c'est le cas), VS Code affiche : + +- Les fichiers modifiés avec des indicateurs colorés +- Le statut Git dans la barre d'état +- Des vues de différences en ligne +- Des capacités de commit et de push + +Ouvrez le panneau Contrôle de Source en utilisant le bouton de contrôle de source (![Icône de contrôle de source](img/source_control_icon.png)) (`Ctrl+Shift+G` ou `Cmd+Shift+G` si vous travaillez avec VSCode localement) pour voir les modifications git et valider les commits directement dans l'éditeur. + +![Panneau Contrôle de Source](img/source_control.png) + +### 7.2. Exécution et Inspection des Workflows + +Exécutons un workflow puis inspectons les résultats. Dans le terminal intégré (`Ctrl+Shift+` backtick sous Windows et MacOS), exécutez le workflow de base : + +```bash title="Exécuter le workflow de base" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Pendant l'exécution du workflow, vous verrez la sortie en temps réel dans le terminal. Après l'achèvement, vous pouvez utiliser VS Code pour inspecter les résultats sans quitter votre éditeur : + +1. **Naviguer vers les répertoires de travail** : Utilisez l'explorateur de fichiers ou le terminal pour parcourir `.nextflow/work` +2. **Ouvrir les fichiers journaux** : Cliquez sur les chemins de fichiers journaux dans la sortie du terminal pour les ouvrir directement dans VS Code +3. **Inspecter les sorties** : Parcourez les répertoires de résultats publiés dans l'explorateur de fichiers +4. **Voir les rapports d'exécution** : Ouvrez les rapports HTML directement dans VS Code ou votre navigateur + +Cela garde tout au même endroit plutôt que de basculer entre plusieurs applications. + +### Points Clés + +Vous pouvez intégrer VS Code avec le contrôle de version et l'exécution de workflow pour gérer l'ensemble de votre processus de développement depuis une interface unique. + +### Et Ensuite ? + +Voyez comment toutes ces fonctionnalités IDE fonctionnent ensemble dans votre workflow de développement quotidien. + +--- + +## 8. Récapitulatif et Notes Rapides + +Voici quelques notes rapides sur chacune des fonctionnalités IDE discutées ci-dessus : + +### 8.1. Commencer une Nouvelle Fonctionnalité + +1. **Ouverture rapide de fichier** (`Ctrl+P` ou `Cmd+P`) pour trouver les modules existants pertinents +2. **Éditeur divisé** pour voir des processus similaires côte à côte +3. **Navigation par symboles** (`Ctrl+Shift+O` ou `Cmd+Shift+O`) pour comprendre la structure du fichier +4. **Auto-complétion** pour écrire rapidement du nouveau code + +### 8.2. Débogage des Problèmes + +1. **Panneau Problèmes** (`Ctrl+Shift+M` ou `Cmd+Shift+M`) pour voir toutes les erreurs en une fois +2. **Aller à la définition** (`Ctrl-clic` ou `Cmd-clic`) pour comprendre les interfaces de processus +3. **Rechercher toutes les références** pour voir comment les processus sont utilisés +4. **Recherche à l'échelle du projet** pour trouver des modèles ou des problèmes similaires + +### 8.3. Refactorisation et Amélioration + +1. **Recherche à l'échelle du projet** (`Ctrl+Shift+F` ou `Cmd+Shift+F`) pour trouver des modèles +2. **Auto-formatage** (`Shift+Alt+F` ou `Shift+Option+F`) pour maintenir la cohérence +3. **Pliage de code** pour se concentrer sur la structure +4. **Intégration Git** pour suivre les modifications + +--- + +## Résumé + +Vous avez maintenant eu un tour d'horizon rapide des fonctionnalités IDE de VS Code pour le développement Nextflow. Ces outils vous rendront nettement plus productif en : + +- **Réduisant les erreurs** grâce à la vérification syntaxique en temps réel +- **Accélérant le développement** avec l'auto-complétion intelligente +- **Améliorant la navigation** dans des workflows multi-fichiers complexes +- **Maintenant la qualité** grâce à un formatage cohérent +- **Améliorant la compréhension** grâce à la coloration avancée et à la visualisation de structure + +Nous ne nous attendons pas à ce que vous vous souveniez de tout, mais maintenant que vous savez que ces fonctionnalités existent, vous pourrez les trouver quand vous en aurez besoin. À mesure que vous continuerez à développer des workflows Nextflow, ces fonctionnalités IDE deviendront une seconde nature, vous permettant de vous concentrer sur l'écriture de code de haute qualité plutôt que de vous battre avec la syntaxe et la structure. + +### Et Ensuite ? + +Appliquez ces compétences IDE en travaillant sur d'autres modules de formation, par exemple : + +- **[nf-test](nf-test.md)** : Créez des suites de tests complètes pour vos workflows +- **[Hello nf-core](../../hello_nf-core/)** : Construisez des pipelines de qualité production avec les standards de la communauté + +Le véritable pouvoir de ces fonctionnalités IDE émerge à mesure que vous travaillez sur des projets plus grands et plus complexes. Commencez à les incorporer progressivement dans votre workflow - en quelques sessions, elles deviendront une seconde nature et transformeront votre approche du développement Nextflow. + +De la détection d'erreurs avant qu'elles ne vous ralentissent à la navigation dans des bases de code complexes avec facilité, ces outils feront de vous un développeur plus confiant et efficace. + +Bon codage ! diff --git a/docs/fr/docs/side_quests/essential_scripting_patterns.md b/docs/fr/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..5c71a12ee2 --- /dev/null +++ b/docs/fr/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1141 @@ +# Modèles de Script Nextflow Essentiels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow est un langage de programmation qui s'exécute sur la Java Virtual Machine. Bien que Nextflow soit construit sur [Groovy](http://groovy-lang.org/) et partage une grande partie de sa syntaxe, Nextflow est plus qu'un simple "Groovy avec des extensions" -- c'est un langage autonome avec une [syntaxe](https://nextflow.io/docs/latest/reference/syntax.html) et une [bibliothèque standard](https://nextflow.io/docs/latest/reference/stdlib.html) entièrement spécifiées. + +Vous pouvez écrire beaucoup de code Nextflow sans aller au-delà de la syntaxe de base pour les variables, les maps et les listes. La plupart des tutoriels Nextflow se concentrent sur l'orchestration des workflows (channels, processes et flux de données), et vous pouvez aller étonnamment loin avec seulement cela. + +Cependant, lorsque vous devez manipuler des données, analyser des noms de fichiers complexes, implémenter une logique conditionnelle ou construire des workflows de production robustes, il est utile de penser à deux aspects distincts de votre code : le **dataflow** (channels, opérateurs, processes et workflows) et le **scripting** (le code à l'intérieur des closures, des fonctions et des scripts de process). Bien que cette distinction soit quelque peu arbitraire—c'est tout du code Nextflow—elle fournit un modèle mental utile pour comprendre quand vous orchestrez votre pipeline par rapport à quand vous manipulez des données. Maîtriser les deux améliore considérablement votre capacité à écrire des workflows clairs et maintenables. + +### Objectifs d'apprentissage + +Cette quête secondaire vous emmène dans un voyage pratique des concepts de base aux modèles prêts pour la production. +Nous allons transformer un workflow simple de lecture CSV en un pipeline bioinformatique sophistiqué, en le faisant évoluer étape par étape à travers des défis réalistes : + +- **Comprendre les frontières :** Distinguer entre les opérations de dataflow et le scripting, et comprendre comment ils fonctionnent ensemble +- **Manipulation de données :** Extraire, transformer et sélectionner des maps et des collections en utilisant des opérateurs puissants +- **Traitement de chaînes :** Analyser des schémas de nommage de fichiers complexes avec des motifs regex et maîtriser l'interpolation de variables +- **Fonctions réutilisables :** Extraire une logique complexe dans des fonctions nommées pour des workflows plus propres et plus maintenables +- **Logique dynamique :** Construire des processes qui s'adaptent à différents types d'entrées et utiliser des closures pour l'allocation dynamique de ressources +- **Routage conditionnel :** Router intelligemment les échantillons à travers différents processes en fonction de leurs caractéristiques de métadonnées +- **Opérations sûres :** Gérer les données manquantes avec élégance grâce aux opérateurs null-safe et valider les entrées avec des messages d'erreur clairs +- **Gestionnaires basés sur la configuration :** Utiliser les gestionnaires d'événements de workflow pour la journalisation, les notifications et la gestion du cycle de vie + +### Prérequis + +Avant d'entreprendre cette quête secondaire, vous devriez : + +- Avoir complété le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants. +- Être à l'aise avec l'utilisation des concepts et mécanismes de base de Nextflow (processes, channels, opérateurs, travail avec des fichiers, métadonnées) +- Avoir une familiarité de base avec les constructions de programmation courantes (variables, maps, listes) + +Ce tutoriel expliquera les concepts de programmation au fur et à mesure que nous les rencontrerons, vous n'avez donc pas besoin d'une vaste expérience en programmation. +Nous commencerons par des concepts fondamentaux et construirons jusqu'aux modèles avancés. + +--- + +## 0. Commencer + +#### Ouvrir le codespace de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans [Configuration de l'environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Examiner les matériaux + +Vous trouverez un fichier de workflow principal et un répertoire `data` contenant des exemples de fichiers de données. + +```console title="Contenu du répertoire" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Notre exemple de CSV contient des informations sur des échantillons biologiques qui nécessitent un traitement différent en fonction de leurs caractéristiques : + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Nous utiliserons cet ensemble de données réaliste pour explorer des techniques de programmation pratiques que vous rencontrerez dans des workflows bioinformatiques réels. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Examiner l'assignation --> + +#### Liste de vérification de la préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon codespace est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +<!-- - [ ] Je comprends l'assignation --> + +Si vous pouvez cocher toutes les cases, vous êtes prêt. + +--- + +## 1. Dataflow vs Scripting : Comprendre les Frontières + +### 1.1. Identifier Ce Qui Est Quoi + +Lors de l'écriture de workflows Nextflow, il est important de distinguer entre le **dataflow** (comment les données se déplacent à travers les channels et les processes) et le **scripting** (le code qui manipule les données et prend des décisions). Construisons un workflow démontrant comment ils fonctionnent ensemble. + +#### 1.1.1. Workflow Nextflow de Base + +Commencez par un workflow simple qui lit simplement le fichier CSV (nous l'avons déjà fait pour vous dans `main.nf`) : + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +Le bloc `workflow` définit la structure de notre pipeline, tandis que `channel.fromPath()` crée un channel à partir d'un chemin de fichier. L'opérateur `.splitCsv()` traite le fichier CSV et convertit chaque ligne en une structure de données map. + +Exécutez ce workflow pour voir les données CSV brutes : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Ajout de l'Opérateur Map + +Maintenant, nous allons ajouter du scripting pour transformer les données, en utilisant l'opérateur `.map()` que vous connaissez probablement déjà. Cet opérateur prend une 'closure' où nous pouvons écrire du code pour transformer chaque élément. + +!!! note + + Une **closure** est un bloc de code qui peut être passé et exécuté plus tard. Considérez-la comme une fonction que vous définissez en ligne. Les closures sont écrites avec des accolades `{ }` et peuvent prendre des paramètres. Elles sont fondamentales pour le fonctionnement des opérateurs Nextflow et si vous écrivez du Nextflow depuis un moment, vous les utilisez peut-être déjà sans vous en rendre compte ! + +Voici à quoi ressemble cette opération map : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +C'est notre première **closure** - une fonction anonyme que vous pouvez passer comme argument (similaire aux lambdas en Python ou aux fonctions fléchées en JavaScript). Les closures sont essentielles pour travailler avec les opérateurs Nextflow. + +La closure `{ row -> return row }` prend un paramètre `row` (qui pourrait avoir n'importe quel nom : `item`, `sample`, etc.). + +Lorsque l'opérateur `.map()` traite chaque élément du channel, il passe cet élément à votre closure. Ici, `row` contient une ligne CSV à la fois. + +Appliquez ce changement et exécutez le workflow : + +```bash +nextflow run main.nf +``` + +Vous verrez la même sortie qu'avant, car nous retournons simplement l'entrée sans modification. Cela confirme que l'opérateur map fonctionne correctement. Maintenant, commençons à transformer les données. + +#### 1.1.3. Création d'une Structure de Données Map + +Maintenant, nous allons écrire une logique de **scripting** à l'intérieur de notre closure pour transformer chaque ligne de données. C'est ici que nous traitons des éléments de données individuels plutôt que d'orchestrer le flux de données. + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting pour la transformation de données + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +La map `sample_meta` est une structure de données clé-valeur (comme les dictionnaires en Python, les objets en JavaScript ou les hashes en Ruby) stockant des informations liées : ID d'échantillon, organisme, type de tissu, profondeur de séquençage et score de qualité. + +Nous utilisons des méthodes de manipulation de chaînes comme `.toLowerCase()` et `.replaceAll()` pour nettoyer nos données, et des méthodes de conversion de type comme `.toInteger()` et `.toDouble()` pour convertir les données de chaîne du CSV en types numériques appropriés. + +Appliquez ce changement et exécutez le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Ajout de Logique Conditionnelle + +Maintenant, ajoutons plus de scripting - cette fois en utilisant un opérateur ternaire pour prendre des décisions basées sur les valeurs des données. + +Effectuez le changement suivant : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +L'opérateur ternaire est un raccourci pour une instruction if/else qui suit le modèle `condition ? valeur_si_vrai : valeur_si_faux`. Cette ligne signifie : "Si la qualité est supérieure à 40, utiliser 'high', sinon utiliser 'normal'". Son cousin, l'**opérateur Elvis** (`?:`), fournit des valeurs par défaut lorsque quelque chose est null ou vide - nous explorerons ce modèle plus tard dans ce tutoriel. + +L'opérateur d'addition de map `+` crée une **nouvelle map** plutôt que de modifier celle existante. Cette ligne crée une nouvelle map qui contient toutes les paires clé-valeur de `sample_meta` plus la nouvelle clé `priority`. + +!!! Note + + Ne modifiez jamais les maps passées dans les closures - créez-en toujours de nouvelles en utilisant `+` (par exemple). Dans Nextflow, les mêmes données transitent souvent simultanément par plusieurs opérations. Modifier une map sur place peut provoquer des effets secondaires imprévisibles lorsque d'autres opérations référencent ce même objet. La création de nouvelles maps garantit que chaque opération dispose de sa propre copie propre. + +Exécutez le workflow modifié : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Nous avons ajouté avec succès une logique conditionnelle pour enrichir nos métadonnées avec un niveau de priorité basé sur les scores de qualité. + +#### 1.1.5. Sélection de Maps avec `.subMap()` + +Alors que l'opérateur `+` ajoute des clés à une map, vous devez parfois faire l'inverse - extraire uniquement des clés spécifiques. La méthode `.subMap()` est parfaite pour cela. + +Ajoutons une ligne pour créer une version simplifiée de nos métadonnées qui ne contient que les champs d'identification : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting pour la transformation de données + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "ID fields only: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting pour la transformation de données + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Exécutez le workflow modifié : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + ID fields only: [id:sample_001, organism:human, tissue:liver] + ID fields only: [id:sample_002, organism:mouse, tissue:brain] + ID fields only: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Cela montre à la fois les métadonnées complètes affichées par l'opération `view()` et le sous-ensemble extrait que nous avons imprimé avec `println`. + +La méthode `.subMap()` prend une liste de clés et retourne une nouvelle map contenant uniquement ces clés. Si une clé n'existe pas dans la map d'origine, elle n'est tout simplement pas incluse dans le résultat. + +Ceci est particulièrement utile lorsque vous devez créer différentes versions de métadonnées pour différents processes - certains peuvent avoir besoin de métadonnées complètes tandis que d'autres n'ont besoin que de champs d'identification minimaux. + +Maintenant, supprimez ces instructions println pour restaurer votre workflow à son état précédent, car nous n'en avons pas besoin pour la suite. + +!!! tip "Résumé des Opérations sur les Maps" + + - **Ajouter des clés** : `map1 + [new_key: value]` - Crée une nouvelle map avec des clés supplémentaires + - **Extraire des clés** : `map1.subMap(['key1', 'key2'])` - Crée une nouvelle map avec uniquement les clés spécifiées + - **Les deux opérations créent de nouvelles maps** - Les maps originales restent inchangées + +#### 1.1.6. Combiner des Maps et Retourner des Résultats + +Jusqu'à présent, nous n'avons retourné que ce que la communauté Nextflow appelle la 'meta map', et nous avons ignoré les fichiers auxquels ces métadonnées se rapportent. Mais si vous écrivez des workflows Nextflow, vous voulez probablement faire quelque chose avec ces fichiers. + +Produisons une structure de channel comprenant un tuple de 2 éléments : la map de métadonnées enrichie et le chemin de fichier correspondant. C'est un modèle courant dans Nextflow pour passer des données aux processes. + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Appliquez ce changement et exécutez le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Cette structure de tuple `[meta, file]` est un modèle courant dans Nextflow pour passer à la fois des métadonnées et des fichiers associés aux processes. + +!!! note + + **Maps et Métadonnées** : Les maps sont fondamentales pour travailler avec les métadonnées dans Nextflow. Pour une explication plus détaillée du travail avec les maps de métadonnées, consultez la quête secondaire [Travailler avec les métadonnées](./metadata.md). + +Notre workflow démontre le modèle de base : les **opérations de dataflow** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orchestrent comment les données se déplacent à travers le pipeline, tandis que le **scripting** (maps `[key: value]`, méthodes de chaînes, conversions de type, opérateurs ternaires) à l'intérieur de la closure `.map()` gère la transformation des éléments de données individuels. + +### 1.2. Comprendre les Différents Types : Channel vs List + +Jusqu'à présent, nous avons pu distinguer entre les opérations de dataflow et le scripting. Mais qu'en est-il lorsque le même nom de méthode existe dans les deux contextes ? + +Un exemple parfait est la méthode `collect`, qui existe à la fois pour les types de channel et les types List dans la bibliothèque standard Nextflow. La méthode `collect()` sur une List transforme chaque élément, tandis que l'opérateur `collect()` sur un channel rassemble toutes les émissions du channel en un channel à élément unique. + +Démontrons cela avec quelques données d'exemple, en commençant par nous rappeler ce que fait l'opérateur `collect()` de channel. Consultez `collect.nf` : + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - regroupe plusieurs émissions de channel en une seule +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Individual channel item: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } +``` + +Étapes : + +- Définir une List d'ID d'échantillons +- Créer un channel avec `fromList()` qui émet chaque ID d'échantillon séparément +- Imprimer chaque élément avec `view()` au fur et à mesure qu'il transite +- Rassembler tous les éléments en une seule liste avec l'opérateur `collect()` du channel +- Imprimer le résultat collecté (élément unique contenant tous les ID d'échantillons) avec un deuxième `view()` + +Nous avons modifié la structure du channel, mais nous n'avons pas modifié les données elles-mêmes. + +Exécutez le workflow pour confirmer cela : + +```bash +nextflow run collect.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +`view()` retourne une sortie pour chaque émission de channel, nous savons donc que cette sortie unique contient tous les 3 éléments originaux regroupés en une seule liste. + +Maintenant, voyons la méthode `collect` sur une List en action. Modifiez `collect.nf` pour appliquer la méthode `collect` de la List à la liste originale d'ID d'échantillons : + +=== "Après" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - regroupe plusieurs émissions de channel en une seule + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - transforme chaque élément, préserve la structure + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - regroupe plusieurs émissions de channel en une seule + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + ``` + +Dans ce nouvel extrait, nous : + +- Définissons une nouvelle variable `formatted_ids` qui utilise la méthode `collect` de la List pour transformer chaque ID d'échantillon dans la liste originale +- Imprimons le résultat en utilisant `println` + +Exécutez le workflow modifié : + +```bash +nextflow run collect.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +Cette fois, nous n'avons PAS modifié la structure des données, nous avons toujours 3 éléments dans la liste, mais nous AVONS transformé chaque élément en utilisant la méthode `collect` de la List pour produire une nouvelle liste avec des valeurs modifiées. Ceci est similaire à l'utilisation de l'opérateur `map` sur un channel, mais il opère sur une structure de données List plutôt que sur un channel. + +`collect` est un cas extrême que nous utilisons ici pour faire valoir un point. La leçon clé est que lorsque vous écrivez des workflows, distinguez toujours entre les **structures de données** (Lists, Maps, etc.) et les **channels** (constructions de dataflow). Les opérations peuvent partager des noms mais se comportent complètement différemment selon le type sur lequel elles sont appelées. + +### 1.3. L'Opérateur Spread (`*.`) - Raccourci pour l'Extraction de Propriétés + +Liée à la méthode `collect` de List est l'opérateur spread (`*.`), qui fournit un moyen concis d'extraire des propriétés de collections. C'est essentiellement du sucre syntaxique pour un modèle `collect` courant. + +Ajoutons une démonstration à notre fichier `collect.nf` : + +=== "Après" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - regroupe plusieurs émissions de channel en une seule + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - transforme chaque élément, préserve la structure + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + + // Opérateur Spread - accès concis aux propriétés + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Spread operator result: ${all_ids}" + ``` + +=== "Avant" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - regroupe plusieurs émissions de channel en une seule + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - transforme chaque élément, préserve la structure + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +Exécutez le workflow mis à jour : + +```bash title="Tester l'opérateur spread" +nextflow run collect.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Spread operator result: [s1, s2, s3] + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +L'opérateur spread `*.` est un raccourci pour un modèle collect courant : + +```groovy +// Ceux-ci sont équivalents : +def ids = samples*.id +def ids = samples.collect { it.id } + +// Fonctionne également avec les appels de méthodes : +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +L'opérateur spread est particulièrement utile lorsque vous devez extraire une seule propriété d'une liste d'objets - c'est plus lisible que d'écrire la closure `collect` complète. + +!!! tip "Quand Utiliser Spread vs Collect" + + - **Utilisez spread (`*.`)** pour un accès simple aux propriétés : `samples*.id`, `files*.name` + - **Utilisez collect** pour des transformations ou une logique complexe : `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Récapitulatif + +Dans cette section, vous avez appris : + +- **Dataflow vs scripting** : Les opérateurs de channel orchestrent la façon dont les données transitent par votre pipeline, tandis que le scripting transforme les éléments de données individuels +- **Comprendre les types** : La même méthode (comme `collect`) peut se comporter différemment selon le type sur lequel elle est appelée (Channel vs List) +- **Le contexte compte** : Soyez toujours conscient de savoir si vous travaillez avec des channels (dataflow) ou des structures de données (scripting) + +Comprendre ces frontières est essentiel pour le débogage, la documentation et l'écriture de workflows maintenables. + +Ensuite, nous plongerons plus profondément dans les capacités de traitement de chaînes, qui sont essentielles pour gérer des données du monde réel. + +--- + +## 2. Traitement de Chaînes et Génération Dynamique de Scripts + +Maîtriser le traitement de chaînes distingue les workflows fragiles des pipelines robustes. Cette section couvre l'analyse de noms de fichiers complexes, la génération dynamique de scripts et l'interpolation de variables. + +### 2.1. Correspondance de Motifs et Expressions Régulières + +Les fichiers bioinformatiques ont souvent des conventions de nommage complexes encodant des métadonnées. Extrayons cela automatiquement en utilisant la correspondance de motifs avec des expressions régulières. + +Nous allons retourner à notre workflow `main.nf` et ajouter une logique de correspondance de motifs pour extraire des informations d'échantillon supplémentaires des noms de fichiers. Les fichiers FASTQ de notre ensemble de données suivent les conventions de nommage de style Illumina avec des noms comme `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Ceux-ci peuvent sembler cryptiques, mais ils encodent en fait des métadonnées utiles comme l'ID d'échantillon, le numéro de voie et la direction de lecture. Nous allons utiliser les capacités regex pour analyser ces noms. + +Effectuez le changement suivant à votre workflow `main.nf` existant : + +=== "Après" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Scripting pour la transformation de données + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Scripting pour la transformation de données + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Cela démontre les **concepts clés de traitement de chaînes** : + +1. **Littéraux d'expressions régulières** utilisant la syntaxe `~/pattern/` - cela crée un motif regex sans avoir besoin d'échapper les barres obliques inverses +2. **Correspondance de motifs** avec l'opérateur `=~` - cela tente de faire correspondre une chaîne avec un motif regex +3. **Objets Matcher** qui capturent des groupes avec `[0][1]`, `[0][2]`, etc. - `[0]` fait référence à la correspondance entière, `[1]`, `[2]`, etc. font référence aux groupes capturés entre parenthèses + +Décomposons le motif regex `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$` : + +| Motif | Correspond à | Capture | +| ------------------- | -------------------------------------------- | ---------------------------------- | +| `^(.+)` | Nom d'échantillon depuis le début | Groupe 1 : nom d'échantillon | +| `_S(\d+)` | Numéro d'échantillon `_S1`, `_S2`, etc. | Groupe 2 : numéro d'échantillon | +| `_L(\d{3})` | Numéro de voie `_L001` | Groupe 3 : voie (3 chiffres) | +| `_(R[12])` | Direction de lecture `_R1` ou `_R2` | Groupe 4 : direction de lecture | +| `_(\d{3})` | Numéro de fragment `_001` | Groupe 5 : fragment (3 chiffres) | +| `\.fastq(?:\.gz)?$` | Extension de fichier `.fastq` ou `.fastq.gz` | Non capturé (?: est non-capturant) | + +Cela analyse les conventions de nommage de style Illumina pour extraire automatiquement les métadonnées. + +Exécutez le workflow modifié : + +```bash title="Tester la correspondance de motifs" +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Cela montre les métadonnées enrichies à partir des noms de fichiers. + +### 2.2. Génération Dynamique de Scripts dans les Processes + +Les blocs script de process sont essentiellement des chaînes multi-lignes qui sont passées au shell. Vous pouvez utiliser une **logique conditionnelle** (if/else, opérateurs ternaires) pour générer dynamiquement différentes chaînes de script en fonction des caractéristiques d'entrée. Ceci est essentiel pour gérer des types d'entrée divers—comme les lectures single-end vs paired-end—sans dupliquer les définitions de process. + +Ajoutons un process à notre workflow qui démontre ce modèle. Ouvrez `modules/fastp.nf` et jetez un œil : + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Le process prend des fichiers FASTQ en entrée et exécute l'outil `fastp` pour rogner les adaptateurs et filtrer les lectures de faible qualité. Malheureusement, la personne qui a écrit ce process n'a pas prévu les lectures single-end que nous avons dans notre ensemble de données d'exemple. Ajoutons-le à notre workflow et voyons ce qui se passe : + +Tout d'abord, incluez le module à la toute première ligne de votre workflow `main.nf` : + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Ensuite, modifiez le bloc `workflow` pour connecter le channel `ch_samples` au process `FASTP` : + +=== "Après" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Exécutez ce workflow modifié : + +```bash +nextflow run main.nf +``` + +??? failure "Sortie de la commande" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Vous pouvez voir que le process essaie d'exécuter `fastp` avec une valeur `null` pour le deuxième fichier d'entrée, ce qui provoque son échec. C'est parce que notre ensemble de données contient des lectures single-end, mais le process est codé en dur pour attendre des lectures paired-end (deux fichiers d'entrée à la fois). + +Corrigez cela en ajoutant une logique conditionnelle au bloc `script:` du process `FASTP`. Une instruction if/else vérifie le nombre de fichiers de lecture et ajuste la commande en conséquence. + +=== "Après" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Détection simple single-end vs paired-end + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Maintenant, le workflow peut gérer gracieusement les lectures single-end et paired-end. La logique conditionnelle vérifie le nombre de fichiers d'entrée et construit la commande appropriée pour `fastp`. Voyons si cela fonctionne : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +Ça a l'air bon ! Si nous vérifions les commandes réelles qui ont été exécutées (personnalisez pour votre hash de tâche) : + +```console title="Vérifier les commandes exécutées" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Nous pouvons voir que Nextflow a correctement choisi la bonne commande pour les lectures single-end : + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Un autre usage courant de la logique de script dynamique peut être vu dans [le module Génomique de Nextflow pour la Science](../../nf4science/genomics/02_joint_calling). Dans ce module, le process GATK appelé peut prendre plusieurs fichiers d'entrée, mais chacun doit être préfixé par `-V` pour former une ligne de commande correcte. Le process utilise du scripting pour transformer une collection de fichiers d'entrée (`all_gvcfs`) en arguments de commande corrects : + +```groovy title="manipulation de ligne de commande pour GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Ces modèles d'utilisation du scripting dans les blocs script de process sont extrêmement puissants et peuvent être appliqués dans de nombreux scénarios - de la gestion de types d'entrée variables à la construction d'arguments de ligne de commande complexes à partir de collections de fichiers, rendant vos processes vraiment adaptables aux exigences diverses des données du monde réel. + +### 2.3. Interpolation de Variables : Variables Nextflow et Shell + +Les scripts de process mélangent des variables Nextflow, des variables shell et des substitutions de commandes, chacune avec une syntaxe d'interpolation différente. L'utilisation de la mauvaise syntaxe provoque des erreurs. Explorons-les avec un process qui crée un rapport de traitement. + +Jetez un œil au fichier de module `modules/generate_report.nf` : + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Ce process écrit un rapport simple avec l'ID d'échantillon et le nom de fichier. Maintenant, exécutons-le pour voir ce qui se passe lorsque nous devons mélanger différents types de variables. + +Incluez le process dans votre `main.nf` et ajoutez-le au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +Maintenant, exécutez le workflow et vérifiez les rapports générés dans `results/reports/`. Ils devraient contenir des informations de base sur chaque échantillon. + +<!-- TODO: add the run command --> + +??? success "Sortie de la commande" + + ```console + <!-- TODO: output --> + ``` + +Mais que se passe-t-il si nous voulons ajouter des informations sur quand et où le traitement a eu lieu ? Modifions le process pour utiliser des variables **shell** et un peu de substitution de commande pour inclure l'utilisateur actuel, le nom d'hôte et la date dans le rapport : + +=== "Après" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + echo "Processed by: ${USER}" >> ${meta.id}_report.txt + echo "Hostname: $(hostname)" >> ${meta.id}_report.txt + echo "Date: $(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Avant" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + """ + ``` + +Si vous exécutez cela, vous remarquerez une erreur - Nextflow essaie d'interpréter `${USER}` comme une variable Nextflow qui n'existe pas. + +??? failure "Sortie de la commande" + + ```console + Error modules/generate_report.nf:15:27: `USER` is not defined + │ 15 | echo "Processed by: ${USER}" >> ${meta.id}_report.txt + ╰ | ^^^^ + + ERROR ~ Script compilation failed + ``` diff --git a/docs/fr/docs/side_quests/ideas/containers.md b/docs/fr/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..f626b8c267 --- /dev/null +++ b/docs/fr/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Partie 1 : Approfondissement des Conteneurs + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Comment trouver ou créer des images de conteneurs + +Certains développeurs de logiciels fournissent des images de conteneurs pour leurs logiciels disponibles sur des registres de conteneurs comme Docker Hub, mais beaucoup ne le font pas. +Dans cette section optionnelle, nous vous montrerons deux façons d'obtenir une image de conteneur pour les outils que vous souhaitez utiliser dans vos pipelines Nextflow : en utilisant Seqera Containers et en construisant vous-même l'image de conteneur. + +Vous allez obtenir/construire une image de conteneur pour le package pip `quote`, qui sera utilisé dans l'exercice à la fin de cette section. + +### 1.1. Obtenir une image de conteneur depuis Seqera Containers + +Seqera Containers est un service gratuit qui construit des images de conteneurs pour les outils installables via pip et conda (y compris bioconda). +Accédez à [Seqera Containers](https://www.seqera.io/containers/) et recherchez le package pip `quote`. + +![Seqera Containers](img/seqera-containers-1.png) + +Cliquez sur "+Add" puis "Get Container" pour demander une image de conteneur pour le package pip `quote`. + +![Seqera Containers](img/seqera-containers-2.png) + +Si c'est la première fois qu'un conteneur communautaire est construit pour cette version du package, cela peut prendre quelques minutes. +Cliquez pour copier l'URI (par exemple `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) de l'image de conteneur qui a été créée pour vous. + +Vous pouvez maintenant utiliser l'image de conteneur pour exécuter la commande `quote` et obtenir une citation aléatoire de Grace Hopper. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Sortie : + +```console title="Sortie" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Construire l'image de conteneur vous-même + +Utilisons quelques détails de construction du site web Seqera Containers pour construire nous-mêmes l'image de conteneur pour le package pip `quote`. +Retournez sur le site web Seqera Containers et cliquez sur le bouton "Build Details". + +Le premier élément que nous allons examiner est le `Dockerfile`, un type de fichier script qui contient toutes les commandes nécessaires pour construire l'image de conteneur. +Nous avons ajouté quelques commentaires explicatifs au Dockerfile ci-dessous pour vous aider à comprendre ce que fait chaque partie. + +```Dockerfile title="Dockerfile" +# Partir de l'image docker de base micromamba +FROM mambaorg/micromamba:1.5.10-noble +# Copier le fichier conda.yml dans le conteneur +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Installer divers utilitaires pour que Nextflow les utilise et les packages dans le fichier conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Exécuter le conteneur en tant qu'utilisateur root +USER root +# Définir la variable d'environnement PATH pour inclure le répertoire d'installation de micromamba +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +Le deuxième élément que nous allons examiner est le fichier `conda.yml`, qui contient la liste des packages qui doivent être installés dans l'image de conteneur. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Copiez le contenu de ces fichiers dans les emplacements situés dans le répertoire `containers/build`, puis exécutez la commande suivante pour construire l'image de conteneur vous-même. + +!!! Note + + Nous utilisons l'option `-t quote:latest` pour étiqueter l'image de conteneur avec le nom `quote` et l'étiquette `latest`. + Nous pourrons utiliser cette étiquette pour faire référence à l'image de conteneur lors de son exécution sur ce système. + +```bash +docker build -t quote:latest containers/build +``` + +Une fois la construction terminée, vous pouvez exécuter l'image de conteneur que vous venez de construire. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### À retenir + +Vous avez appris deux façons différentes d'obtenir une image de conteneur pour un outil que vous souhaitez utiliser dans vos pipelines Nextflow : en utilisant Seqera Containers et en construisant l'image de conteneur vous-même. + +### Et ensuite ? + +Vous avez tout ce dont vous avez besoin pour continuer au [chapitre suivant](./04_hello_genomics.md) de cette série de formation. +Vous pouvez également poursuivre avec un exercice optionnel pour récupérer des citations sur les pionniers de l'informatique/biologie en utilisant le conteneur `quote` et les afficher en utilisant le conteneur `cowsay`. + +--- + +## 2. Faire dire des citations de scientifiques célèbres à la vache + +Cette section contient quelques exercices avancés, pour pratiquer ce que vous avez appris jusqu'à présent. +Faire ces exercices n'est _pas requis_ pour comprendre les parties suivantes de la formation, mais ils offrent une façon amusante de renforcer vos acquis en déterminant comment faire dire des citations de scientifiques célèbres à la vache. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Modifier le script `hello-containers.nf` pour utiliser un processus getQuote + +Nous avons une liste de pionniers de l'informatique et de la biologie dans le fichier `containers/data/pioneers.csv`. +À un niveau élevé, pour compléter cet exercice vous devrez : + +- Modifier le `params.input_file` par défaut pour pointer vers le fichier `pioneers.csv`. +- Créer un processus `getQuote` qui utilise le conteneur `quote` pour récupérer une citation pour chaque entrée. +- Connecter la sortie du processus `getQuote` au processus `cowsay` pour afficher la citation. + +Pour l'image de conteneur `quote`, vous pouvez soit utiliser celle que vous avez construite vous-même dans l'exercice avancé précédent, soit utiliser celle que vous avez obtenue depuis Seqera Containers. + +!!! Hint "Indice" + + Un bon choix pour le bloc `script` de votre processus getQuote pourrait être : + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Vous pouvez trouver une solution à cet exercice dans `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Modifier votre pipeline Nextflow pour lui permettre de s'exécuter en modes `quote` et `sayHello`. + +Ajoutez une logique de branchement à votre pipeline pour lui permettre d'accepter des entrées destinées à la fois à `quote` et `sayHello`. +Voici un exemple de la façon d'utiliser une instruction `if` dans un workflow Nextflow : + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint "Indice" + + Vous pouvez utiliser `new_ch = processName.out` pour assigner un nom au canal de sortie d'un processus. + +Vous pouvez trouver une solution à cet exercice dans `containers/solutions/hello-containers-4.2.nf`. + +### À retenir + +Vous savez comment utiliser les conteneurs dans Nextflow pour exécuter des processus, et comment construire une logique de branchement dans vos pipelines ! + +### Et ensuite ? + +Félicitations, prenez une pause et buvez de l'eau ! + +Lorsque vous êtes prêt, passez à la Partie 3 de cette série de formation pour apprendre comment appliquer ce que vous avez appris jusqu'à présent à un cas d'utilisation d'analyse de données plus réaliste. diff --git a/docs/fr/docs/side_quests/ideas/if_else.md b/docs/fr/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..f0c50440a1 --- /dev/null +++ b/docs/fr/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Partie 2 : If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Faire citer des scientifiques célèbres à la vache + +Cette section contient quelques exercices supplémentaires pour pratiquer ce que vous avez appris jusqu'à présent. +Réaliser ces exercices n'est _pas obligatoire_ pour comprendre les parties suivantes de la formation, mais ils constituent une façon amusante de renforcer vos apprentissages en découvrant comment faire citer des scientifiques célèbres à la vache. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Modifier le script `hello-containers.nf` pour utiliser un processus getQuote + +Nous avons une liste de pionniers de l'informatique et de la biologie dans le fichier `containers/data/pioneers.csv`. +De manière générale, pour compléter cet exercice, vous devrez : + +- Modifier le paramètre par défaut `params.input_file` pour qu'il pointe vers le fichier `pioneers.csv`. +- Créer un processus `getQuote` qui utilise le conteneur `quote` pour récupérer une citation pour chaque entrée. +- Connecter la sortie du processus `getQuote` au processus `cowsay` pour afficher la citation. + +Pour l'image de conteneur `quote`, vous pouvez soit utiliser celle que vous avez construite vous-même dans l'exercice supplémentaire précédent, soit utiliser celle que vous avez obtenue depuis Seqera Containers. + +!!! Hint + + Un bon choix pour le bloc `script` de votre processus getQuote pourrait être : + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Vous pouvez trouver une solution à cet exercice dans `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Modifier votre pipeline Nextflow pour lui permettre de s'exécuter en modes `quote` et `sayHello`. + +Ajoutez une logique de branchement à votre pipeline pour lui permettre d'accepter des entrées destinées à la fois à `quote` et `sayHello`. +Voici un exemple d'utilisation d'une instruction `if` dans un workflow Nextflow : + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + Vous pouvez utiliser `new_ch = processName.out` pour attribuer un nom au canal de sortie d'un processus. + +Vous pouvez trouver une solution à cet exercice dans `containers/solutions/hello-containers-4.2.nf`. + +### À retenir + +Vous savez comment utiliser des conteneurs dans Nextflow pour exécuter des processus, et comment construire une logique de branchement dans vos pipelines ! + +### Et ensuite ? + +Félicitations, prenez une pause pour vous étirer et boire de l'eau ! + +Lorsque vous êtes prêt, passez à la Partie 3 de cette série de formation pour apprendre à appliquer ce que vous avez appris jusqu'à présent à un cas d'usage d'analyse de données plus réaliste. diff --git a/docs/fr/docs/side_quests/index.md b/docs/fr/docs/side_quests/index.md new file mode 100644 index 0000000000..5e70ed3b2f --- /dev/null +++ b/docs/fr/docs/side_quests/index.md @@ -0,0 +1,38 @@ +# Quêtes secondaires + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ceci est une collection de mini-cours de formation autonomes qui approfondissent des sujets spécifiques. Vous pouvez les suivre dans n'importe quel ordre. + +Commençons ! Cliquez sur le bouton « Open in GitHub Codespaces » ci-dessous pour lancer l'environnement de formation (de préférence dans un onglet séparé), puis continuez votre lecture pendant le chargement. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Prérequis + +Les prérequis spécifiques de chaque mini-cours varient et sont documentés dans les pages correspondantes. +Néanmoins, tous supposent une familiarité minimale avec les éléments suivants : + +- Expérience avec la ligne de commande +- Concepts et outils fondamentaux de Nextflow couverts dans le cours de formation pour débutants [Hello Nextflow](../../hello_nextflow/). + +Pour les exigences techniques et la configuration de l'environnement, consultez le mini-cours [Configuration de l'environnement](../../envsetup/). + +**Si c'est la première fois que vous explorez les Quêtes secondaires, assurez-vous de consulter d'abord la page [Orientation](./orientation.md) !** + +Sinon, sélectionnez une quête secondaire dans le tableau ci-dessous. + +## Quêtes secondaires + +| Quête secondaire | Durée estimée pour l'enseignement | +| ------------------------------------------------------------------------------ | --------------------------------- | +| [Présentation de l'environnement de développement Nextflow](./ide_features.md) | 45 min | +| [Modèles de script Nextflow essentiels](./essential_scripting_patterns.md) | 90 min | +| [Métadonnées dans les workflows](./metadata.md) | 45 min | +| [Division et regroupement](./splitting_and_grouping.md) | 45 min | +| [Tests avec nf-test](./nf-test.md) | 1 heure | +| [Workflows de workflows](./workflows_of_workflows.md) | 30 min | +| [Travailler avec les fichiers](./working_with_files.md) | 45 min | +| [Débogage des workflows](./debugging.md) | 1 heure | + +Faites-nous savoir quels autres domaines et cas d'usage vous aimeriez voir couverts ici en publiant dans la [section Formation](https://community.seqera.io/c/training/) du forum communautaire. diff --git a/docs/fr/docs/side_quests/metadata.md b/docs/fr/docs/side_quests/metadata.md new file mode 100644 index 0000000000..7c065a56b7 --- /dev/null +++ b/docs/fr/docs/side_quests/metadata.md @@ -0,0 +1,1211 @@ +# Métadonnées et meta maps + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dans toute analyse scientifique, nous travaillons rarement uniquement avec les fichiers de données brutes. +Chaque fichier s'accompagne de ses propres informations supplémentaires : ce qu'il est, d'où il vient et ce qui le rend spécial. +Ces informations supplémentaires sont ce que nous appelons les métadonnées. + +Les métadonnées sont des données décrivant d'autres données. +Les métadonnées permettent de suivre les détails importants concernant les fichiers et les conditions expérimentales, et aident à adapter les analyses aux caractéristiques uniques de chaque ensemble de données. + +Imaginez cela comme un catalogue de bibliothèque : alors que les livres contiennent le contenu réel (données brutes), les fiches du catalogue fournissent des informations essentielles sur chaque livre—quand il a été publié, qui l'a écrit, où le trouver (métadonnées). +Dans les pipelines Nextflow, les métadonnées peuvent être utilisées pour : + +- Suivre les informations spécifiques aux fichiers tout au long du workflow +- Configurer les processus en fonction des caractéristiques des fichiers +- Regrouper les fichiers liés pour une analyse conjointe + +### Objectifs d'apprentissage + +Dans cette quête secondaire, nous explorerons comment gérer les métadonnées dans les workflows. +En partant d'une simple feuille de données (souvent appelée samplesheet en bioinformatique) contenant des informations de base sur les fichiers, vous apprendrez à : + +- Lire et analyser les métadonnées de fichiers à partir de fichiers CSV +- Créer et manipuler des maps de métadonnées +- Ajouter de nouveaux champs de métadonnées pendant l'exécution du workflow +- Utiliser les métadonnées pour personnaliser le comportement des processus + +Ces compétences vous aideront à construire des pipelines plus robustes et flexibles qui peuvent gérer des relations de fichiers et des exigences de traitement complexes. + +### Prérequis + +Avant d'entreprendre cette quête secondaire, vous devriez : + +- Avoir complété le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants. +- Être à l'aise avec l'utilisation des concepts et mécanismes de base de Nextflow (processus, canaux, opérateurs) + +--- + +## 0. Pour commencer + +#### Ouvrir le codespace de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/metadata +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner les ressources + +Vous trouverez un fichier de workflow principal et un répertoire `data` contenant une feuille de données et quelques fichiers de données. + +??? abstract "Contenu du répertoire" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +Le workflow dans le fichier `main.nf` est une ébauche que vous développerez progressivement en un workflow pleinement fonctionnel. + +La feuille de données répertorie les chemins vers les fichiers de données et certaines métadonnées associées, organisées en 3 colonnes : + +- `id` : auto-explicatif, un identifiant attribué au fichier +- `character` : un nom de personnage, que nous utiliserons plus tard pour dessiner différentes créatures +- `data` : chemins vers les fichiers `.txt` qui contiennent des salutations dans différentes langues + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Chaque fichier de données contient du texte de salutation dans l'une des cinq langues (fr : français, de : allemand, es : espagnol, it : italien, en : anglais). + +Nous vous fournirons également un outil d'analyse de langue conteneurisé appelé `langid`. + +#### Examiner l'assignation + +Votre défi est d'écrire un workflow Nextflow qui va : + +1. **Identifier** automatiquement la langue dans chaque fichier +2. **Regrouper** les fichiers par famille de langues (langues germaniques vs langues romanes) +3. **Personnaliser** le traitement de chaque fichier en fonction de sa langue et de ses métadonnées +4. **Organiser** les sorties par groupe de langues + +Cela représente un modèle de workflow typique où les métadonnées spécifiques aux fichiers guident les décisions de traitement ; exactement le type de problème que les meta maps résolvent élégamment. + +#### Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon codespace est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +- [ ] Je comprends l'assignation + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +--- + +## 1. Charger les métadonnées depuis une feuille de données + +Ouvrez le fichier de workflow `main.nf` pour examiner l'ébauche de workflow que nous vous donnons comme point de départ. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Vous pouvez voir que nous avons configuré une factory de canal de base pour charger l'exemple de feuille de données en tant que fichier, mais cela ne lira pas encore le contenu du fichier. +Commençons par ajouter cela. + +### 1.1. Lire le contenu avec `splitCsv` + +Nous devons choisir un opérateur qui analysera le contenu du fichier de manière appropriée avec un effort minimal de notre part. +Puisque notre feuille de données est au format CSV, c'est un travail pour l'opérateur [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv), qui charge chaque ligne du fichier comme un élément dans le canal. + +Effectuez les modifications suivantes pour ajouter une opération `splitCsv()` au code de construction du canal, plus une opération `view()` pour vérifier que le contenu du fichier est correctement chargé dans le canal. + +=== "Après" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Notez que nous utilisons l'option `header: true` pour indiquer à Nextflow de lire la première ligne du fichier CSV comme ligne d'en-tête. + +Voyons ce qui en ressort, d'accord ? +Exécutez le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Nous pouvons voir que l'opérateur a construit une map de paires clé-valeur pour chaque ligne du fichier CSV, avec les en-têtes de colonnes comme clés pour les valeurs correspondantes. + +Chaque entrée de map correspond à une colonne dans notre feuille de données : + +- `id` +- `character` +- `recording` + +C'est excellent ! Cela facilite l'accès à des champs spécifiques de chaque fichier. +Par exemple, nous pourrions accéder à l'identifiant du fichier avec `id` ou au chemin du fichier txt avec `recording`. + +??? info "(Optionnel) En savoir plus sur les maps" + + Dans Groovy, le langage de programmation sur lequel Nextflow est construit, une map est une structure de données clé-valeur similaire aux dictionnaires en Python, aux objets en JavaScript ou aux hashes en Ruby. + + Voici un script exécutable qui montre comment vous pouvez définir une map et accéder à son contenu en pratique : + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Créer une map simple + def my_map = [id:'sampleA', character:'squirrel'] + + // Afficher toute la map + println "map: ${my_map}" + + // Accéder aux valeurs individuelles en utilisant la notation par point + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Même s'il n'a pas de bloc `workflow` approprié, Nextflow peut exécuter cela comme s'il s'agissait d'un workflow : + + ```bash + nextflow run examples/map_demo.nf + ``` + + Et voici ce que vous pouvez vous attendre à voir dans la sortie : + + ```console title="Sortie" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Sélectionner des champs spécifiques avec `map` + +Disons que nous voulons accéder à la colonne `character` de la feuille de données et l'afficher. +Nous pouvons utiliser l'opérateur Nextflow `map` pour itérer sur chaque élément dans notre canal et sélectionner spécifiquement l'entrée `character` de l'objet map. + +Effectuez les modifications suivantes au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Maintenant, exécutez à nouveau le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Succès ! Nous avons tiré parti de la structure de map dérivée de notre feuille de données pour accéder aux valeurs de colonnes individuelles pour chaque ligne. + +Maintenant que nous avons lu avec succès la feuille de données et que nous avons accès aux données de chaque ligne, nous pouvons commencer à implémenter la logique de notre pipeline. + +### 1.3. Organiser les métadonnées dans une 'meta map' + +Dans l'état actuel du workflow, les fichiers d'entrée (sous la clé `recording`) et les métadonnées associées (`id`, `character`) sont tous sur le même pied, comme s'ils étaient tous dans un grand sac. +La conséquence pratique est que chaque processus qui consomme ce canal devrait être configuré avec cette structure à l'esprit : + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +C'est bien tant que le nombre de colonnes dans la feuille de données ne change pas. +Cependant, si vous ajoutez ne serait-ce qu'une seule colonne à la feuille de données, la forme du canal ne correspondra plus à ce que le processus attend, et le workflow produira des erreurs. +Cela rend également le processus difficile à partager avec d'autres qui pourraient avoir des données d'entrée légèrement différentes, et vous pourriez finir par devoir coder en dur des variables dans le processus qui ne sont pas nécessaires au bloc script. + +Pour éviter ce problème, nous devons trouver un moyen de maintenir la structure du canal cohérente quel que soit le nombre de colonnes que contient la feuille de données. + +Nous pouvons le faire en collectant toutes les métadonnées dans un élément au sein du tuple, que nous appellerons la map de métadonnées, ou plus simplement 'meta map'. + +Effectuez les modifications suivantes à l'opération `map` : + +=== "Après" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Nous avons restructuré nos éléments de canal en un tuple composé de deux éléments, la meta map et l'objet fichier correspondant. + +Exécutons le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console title="Afficher la meta map" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Maintenant, chaque élément dans le canal contient la meta map en premier et l'objet fichier correspondant en second : + +```console title="Exemple de structure de sortie" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +En conséquence, l'ajout de plus de colonnes dans la feuille de données rendra plus de métadonnées disponibles dans la map `meta`, mais ne changera pas la forme du canal. +Cela nous permet d'écrire des processus qui consomment le canal sans avoir à coder en dur les éléments de métadonnées dans la spécification d'entrée : + +```groovy title="Exemple de syntaxe" + input: + tuple val(meta), file(recording) +``` + +C'est une convention largement utilisée pour organiser les métadonnées dans les workflows Nextflow. + +### À retenir + +Dans cette section, vous avez appris : + +- **Pourquoi les métadonnées sont importantes :** Garder les métadonnées avec vos données préserve les informations importantes sur les fichiers tout au long du workflow. +- **Comment lire des feuilles de données :** Utiliser `splitCsv` pour lire les fichiers CSV avec des informations d'en-tête et transformer les lignes en données structurées +- **Comment créer une meta map :** Séparer les métadonnées des données de fichiers en utilisant la structure de tuple `[ [id:value, ...], file ]` + +--- + +## 2. Manipuler les métadonnées + +Maintenant que nous avons chargé nos métadonnées, faisons quelque chose avec ! + +Nous allons utiliser un outil appelé [`langid`](https://github.com/saffsd/langid.py) pour identifier la langue contenue dans le fichier d'enregistrement de chaque créature. +L'outil est pré-entraîné sur un ensemble de langues, et étant donné un extrait de texte, il produira une prédiction de langue et un score de probabilité associé, tous deux vers `stdout`. + +### 2.1. Importer le processus et examiner le code + +Nous vous fournissons un module de processus pré-écrit appelé `IDENTIFY_LANGUAGE` qui encapsule l'outil `langid`, vous devez donc simplement ajouter une instruction include avant le bloc workflow. + +Effectuez la modification suivante au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Vous pouvez ouvrir le fichier de module pour examiner son code : + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Utiliser langid pour prédire la langue de chaque fichier d'entrée +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Comme vous pouvez le voir, la définition d'entrée utilise la même structure `tuple val(meta), path(file)` que nous venons d'appliquer à notre canal d'entrée. + +La définition de sortie est structurée comme un tuple avec une structure similaire à celle de l'entrée, sauf qu'elle contient également `stdout` comme troisième élément. +Ce modèle `tuple val(meta), path(file), <sortie>` maintient les métadonnées associées à la fois aux données d'entrée et aux sorties alors qu'elles circulent dans le pipeline. + +Notez que nous utilisons le qualificateur de sortie [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) de Nextflow ici parce que l'outil affiche sa sortie directement sur la console plutôt que d'écrire un fichier ; et nous utilisons `sed` dans la ligne de commande pour supprimer le score de probabilité, nettoyer la chaîne en supprimant les caractères de nouvelle ligne, et ne retourner que la prédiction de langue. + +### 2.2. Ajouter un appel à `IDENTIFY_LANGUAGE` + +Maintenant que le processus est disponible pour le workflow, nous pouvons ajouter un appel au processus `IDENTIFY_LANGUAGE` pour l'exécuter sur le canal de données. + +Effectuez les modifications suivantes au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Notez que nous avons supprimé l'opération `.view()` originale dans la construction du canal. + +Nous pouvons maintenant exécuter le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Excellent ! Nous avons maintenant une prédiction de la langue parlée par chaque personnage. + +Et comme noté précédemment, nous avons également inclus le fichier d'entrée et la meta map dans la sortie, ce qui signifie que les deux restent associés aux nouvelles informations que nous venons de produire. +Cela s'avérera utile dans l'étape suivante. + +!!! note + + Plus généralement, ce modèle consistant à garder la meta map associée aux résultats facilite l'association de résultats liés qui partagent les mêmes identifiants. + + Comme vous l'aurez déjà appris, vous ne pouvez pas compter sur l'ordre des éléments dans les canaux pour faire correspondre les résultats entre eux. + Au lieu de cela, vous devez utiliser des clés pour associer correctement les données, et les meta maps fournissent une structure idéale à cette fin. + + Nous explorons ce cas d'usage en détail dans la quête secondaire [Splitting & Grouping](./splitting_and_grouping.md). + +### 2.3. Augmenter les métadonnées avec les sorties de processus + +Étant donné que les résultats que nous venons de produire sont en eux-mêmes une forme de métadonnées sur le contenu des fichiers, il serait utile de les ajouter à notre meta map. + +Cependant, nous ne voulons pas modifier la meta map existante sur place. +D'un point de vue technique, il est _possible_ de le faire, mais c'est risqué. + +Donc à la place, nous allons créer une nouvelle meta map contenant le contenu de la meta map existante plus une nouvelle paire clé-valeur `lang: lang_id` contenant les nouvelles informations, en utilisant l'opérateur `+` (une fonctionnalité Groovy). +Et nous combinerons cela avec une opération [`map`](https://www.nextflow.io/docs/latest/operator.html#map) pour remplacer l'ancienne map par la nouvelle. + +Voici les modifications que vous devez apporter au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Si vous n'êtes pas encore familier avec l'opérateur `+`, ou si cela semble déroutant, prenez quelques minutes pour parcourir l'explication détaillée ci-dessous. + +??? info "Création de la nouvelle meta map en utilisant l'opérateur `+`" + + **D'abord, vous devez savoir que nous pouvons fusionner le contenu de deux maps en utilisant l'opérateur Groovy `+`.** + + Disons que nous avons les maps suivantes : + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Nous pouvons les fusionner ainsi : + + ```groovy + new_map = map1 + map2 + ``` + + Le contenu de `new_map` sera : + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Parfait ! + + **Mais que faire si vous devez ajouter un champ qui ne fait pas déjà partie d'une map ?** + + Disons que vous repartez de `map1`, mais la prédiction de langue n'est pas dans sa propre map (il n'y a pas de `map2`). + Au lieu de cela, elle est contenue dans une variable appelée `lang_id`, et vous savez que vous voulez stocker sa valeur (`'fr'`) avec la clé `lang`. + + Vous pouvez en fait faire ce qui suit : + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Ici, `[lang: new_info]` crée une nouvelle map sans nom à la volée, et `map1 + ` fusionne `map1` avec la nouvelle map sans nom, produisant le même contenu `new_map` qu'auparavant. + + Élégant, n'est-ce pas ? + + **Maintenant transposons cela dans le contexte d'une opération Nextflow `channel.map()`.** + + Le code devient : + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Cela fait ce qui suit : + + - `map1, lang_id ->` prend les deux éléments du tuple + - `[map1 + [lang: lang_id]]` crée la nouvelle map comme détaillé ci-dessus + + La sortie est une seule map sans nom avec le même contenu que `new_map` dans notre exemple ci-dessus. + Donc nous avons effectivement transformé : + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + en : + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Espérons que vous pouvez voir que si nous changeons `map1` en `meta`, c'est essentiellement tout ce dont nous avons besoin pour ajouter la prédiction de langue à notre meta map dans notre workflow. + + Sauf pour une chose ! + + Dans le cas de notre workflow, **nous devons également tenir compte de la présence de l'objet `file` dans le tuple**, qui est composé de `meta, file, lang_id`. + + Donc le code ici deviendrait : + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Si vous avez du mal à comprendre pourquoi le `file` semble se déplacer dans l'opération `map`, imaginez qu'au lieu de `[meta + [lang: lang_id], file]`, cette ligne lise `[new_map, file]`. + Cela devrait rendre plus clair que nous laissons simplement le `file` à sa place d'origine en deuxième position dans le tuple. Nous avons juste pris la valeur `new_info` et l'avons intégrée dans la map qui est en première position. + + **Et cela nous ramène à la structure de canal `tuple val(meta), path(file)` !** + +Une fois que vous êtes sûr de comprendre ce que fait ce code, exécutez le workflow pour voir si cela a fonctionné : + +```bash +nextflow run main.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Oui, ça fonctionne ! +Nous avons soigneusement réorganisé la sortie du processus de `meta, file, lang_id` pour que `lang_id` soit maintenant l'une des clés dans la meta map, et les tuples du canal correspondent à nouveau au modèle `meta, file`. + +### 2.4. Attribuer un groupe de langue en utilisant des conditions + +Maintenant que nous avons nos prédictions de langue, utilisons les informations pour attribuer de nouveaux regroupements. + +Dans nos données d'exemple, les langues utilisées par nos personnages peuvent être regroupées en langues germaniques (anglais, allemand) et langues romanes (français, espagnol, italien). +Il pourrait être utile d'avoir cette classification facilement disponible quelque part plus tard dans le pipeline, alors ajoutons cette information dans la meta map. + +Et, bonne nouvelle, c'est encore un autre cas qui se prête parfaitement à l'utilisation de l'opérateur `map` ! + +Spécifiquement, nous allons définir une variable appelée `lang_group`, utiliser une logique conditionnelle simple pour déterminer quelle valeur attribuer au `lang_group` pour chaque donnée. + +La syntaxe générale va ressembler à ceci : + +```groovy +.map { meta, file -> + + // la logique conditionnelle définissant lang_group va ici + + [meta + [lang_group: lang_group], file] +} +``` + +Vous pouvez voir que c'est très similaire à l'opération de fusion de map à la volée que nous avons utilisée à l'étape précédente. +Nous devons juste écrire les instructions conditionnelles. + +Voici la logique conditionnelle que nous voulons appliquer : + +- Définir une variable appelée `lang_group` avec la valeur par défaut `'unknown'`. +- Si `lang` est soit allemand (`'de'`) soit anglais (`'en'`), changer `lang_group` en `germanic`. +- Sinon si `lang` est inclus dans une liste contenant français (`'fr'`), espagnol (`'es'`) et italien (`'it'`), changer `lang_group` en `romance`. + +Essayez de l'écrire vous-même si vous savez déjà comment écrire des instructions conditionnelles dans Nextflow. + +!!! tip + + Vous pouvez accéder à la valeur de `lang` dans l'opération map avec `meta.lang`. + +Vous devriez finir par apporter les modifications suivantes au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Voici les points clés : + +- Nous utilisons `def lang_group = "unknown"` pour créer la variable `lang_group` avec une valeur par défaut définie sur `unknown`. +- Nous utilisons une structure `if {} else if {}` pour la logique conditionnelle, avec des tests `.equals()` alternatifs pour les deux langues germaniques, et un test d'existence dans une liste pour les trois langues romanes. +- Nous utilisons l'opération de fusion `meta + [lang_group:lang_group]` comme précédemment pour générer la meta map mise à jour. + +Une fois que tout cela a du sens, exécutez à nouveau le workflow pour voir le résultat : + +```bash +nextflow run main.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Comme vous pouvez le voir, les éléments du canal maintiennent leur structure `[meta, file]`, mais la meta map inclut maintenant cette nouvelle classification. + +### À retenir + +Dans cette section, vous avez appris comment : + +- **Appliquer les métadonnées d'entrée aux canaux de sortie** : Copier les métadonnées de cette manière nous permet d'associer les résultats ultérieurement en fonction du contenu des métadonnées. +- **Créer des clés personnalisées** : Vous avez créé deux nouvelles clés dans votre meta map, les fusionnant avec `meta + [new_key:value]` dans la meta map existante. L'une basée sur une valeur calculée à partir d'un processus, et une basée sur une condition que vous avez définie dans l'opérateur `map`. + +Celles-ci vous permettent d'associer des métadonnées nouvelles et existantes avec des fichiers au fur et à mesure que vous progressez dans votre pipeline. +Même si vous n'utilisez pas les métadonnées dans le cadre d'un processus, garder la meta map associée aux données comme ceci facilite le maintien de toutes les informations pertinentes ensemble. + +--- + +## 3. Utiliser les informations de la meta map dans un processus + +Maintenant que vous savez comment créer et mettre à jour la meta map, nous pouvons passer à la partie vraiment amusante : utiliser réellement les métadonnées dans un processus. + +Plus spécifiquement, nous allons ajouter une deuxième étape à notre workflow pour dessiner chaque animal en art ASCII et le faire dire le texte enregistré dans une bulle de dialogue. +Nous allons faire cela en utilisant un outil appelé [`cowpy`](https://github.com/jeffbuttars/cowpy). + +??? info "Que fait `cowpy` ?" + + `cowpy` est un outil en ligne de commande qui génère de l'art ASCII pour afficher des entrées de texte arbitraires de manière amusante. + C'est une implémentation python du classique outil [cowsay](https://en.wikipedia.org/wiki/Cowsay) par Tony Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Optionnellement, vous pouvez sélectionner un personnage (ou 'cowacter') à utiliser au lieu de la vache par défaut. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Si vous avez suivi le cours Hello Nextflow, vous avez déjà vu cet outil en action. +Sinon, ne vous inquiétez pas ; nous couvrirons tout ce que vous devez savoir au fur et à mesure. + +### 3.1. Importer le processus et examiner le code + +Nous vous fournissons un module de processus pré-écrit appelé `COWPY` qui encapsule l'outil `cowpy`, vous devez donc simplement ajouter une instruction include avant le bloc workflow. + +Effectuez la modification suivante au workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Vous pouvez ouvrir le fichier de module pour examiner son code : + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Générer de l'art ASCII avec cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Comme vous pouvez le voir, ce processus est actuellement conçu pour prendre un fichier d'entrée (contenant le texte à afficher) et une valeur spécifiant le personnage qui doit être dessiné en art ASCII, généralement fournie au niveau du workflow par un paramètre de ligne de commande. + +### 3.2. Passer un champ de meta map comme entrée + +Lorsque nous avons utilisé l'outil `cowpy` dans le cours Hello Nextflow, nous avons utilisé un paramètre de ligne de commande pour déterminer quel personnage utiliser pour dessiner l'image finale. +Cela avait du sens, car nous ne générions qu'une seule image par exécution du pipeline. + +Cependant, dans ce tutoriel, nous voulons générer une image appropriée pour chaque sujet que nous traitons, donc utiliser un paramètre de ligne de commande serait trop limitant. + +Bonne nouvelle : nous avons une colonne `character` dans notre feuille de données et donc, dans notre meta map. +Utilisons cela pour définir le personnage que le processus doit utiliser pour chaque entrée. + +À cette fin, nous devrons faire trois choses : + +1. Donner un nom au canal de sortie provenant du processus précédent afin de pouvoir l'utiliser plus commodément. +2. Déterminer comment accéder aux informations qui nous intéressent +3. Ajouter un appel au deuxième processus et fournir les informations de manière appropriée. + +Commençons. + +#### 3.2.1. Nommer le canal de sortie précédent + +Nous avons appliqué les manipulations précédentes directement sur le canal de sortie du premier processus, `IDENTIFY_LANGUAGE.out`. +Afin de fournir le contenu de ce canal au processus suivant (et de le faire d'une manière claire et facile à lire) nous voulons lui donner son propre nom, `ch_languages`. + +Nous pouvons le faire en utilisant l'opérateur [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set). + +Dans le workflow principal, remplacez l'opérateur `.view()` par `.set { ch_languages }`, et ajoutez une ligne testant que nous pouvons référer au canal par nom. + +=== "Après" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Temporaire : jeter un œil dans ch_languages + ch_languages.view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Exécuter langid pour identifier la langue de chaque salutation + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Exécutons ceci : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Cela confirme que nous pouvons maintenant référer au canal par nom. + +#### 3.2.2. Accéder au fichier et aux métadonnées de personnage + +Nous savons en regardant le code du module que le processus `COWPY` s'attend à recevoir un fichier texte et une valeur `character`. +Pour écrire l'appel au processus `COWPY`, nous devons simplement savoir comment extraire l'objet fichier correspondant et les métadonnées de chaque élément du canal. + +Comme c'est souvent le cas, la façon la plus simple de le faire est d'utiliser une opération `map`. + +Notre canal contient des tuples structurés comme `[meta, file]`, donc nous pouvons accéder à l'objet `file` directement, et nous pouvons accéder à la valeur `character` stockée à l'intérieur de la meta map en y faisant référence comme `meta.character`. + +Dans le workflow principal, effectuez les modifications de code suivantes : + +=== "Après" + + ```groovy title="main.nf" linenums="34" + // Temporaire : accéder au fichier et au personnage + ch_languages.map { meta, file -> file }.view { file -> "Fichier : " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Personnage : " + character } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="34" + // Temporaire : jeter un œil dans ch_languages + ch_languages.view() + ``` + +Notez que nous utilisons des closures (telles que `{ file -> "Fichier : " + file }`) pour rendre la sortie des opérations `.view` plus lisible. + +Exécutons ceci : + +```bash +nextflow run main.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Personnage : squirrel + Fichier : /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + Fichier : /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Personnage : tux + Personnage : turkey + Fichier : /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + Fichier : /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Personnage : sheep + Personnage : moose + Personnage : stegosaurus + Fichier : /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + Fichier : /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + Fichier : /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Personnage : turtle + ``` + +_Les chemins de fichiers et les valeurs de personnages peuvent sortir dans un ordre différent dans votre sortie._ + +Cela confirme que nous sommes capables d'accéder au fichier et au personnage pour chaque élément du canal. + +#### 3.2.3. Appeler le processus `COWPY` + +Maintenant, assemblons tout et appelons réellement le processus `COWPY` sur le canal `ch_languages`. + +Dans le workflow principal, effectuez les modifications de code suivantes : + +=== "Après" + + ```groovy title="main.nf" linenums="34" + // Exécuter cowpy pour générer de l'art ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="34" + // Temporaire : accéder au fichier et au personnage + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Vous voyez que nous copions simplement les deux opérations map (moins les instructions `.view()`) comme entrées de l'appel de processus. +Assurez-vous simplement de ne pas oublier la virgule entre elles ! + +C'est un peu maladroit, mais nous verrons comment améliorer cela dans la section suivante. + +Exécutons ceci : + +```bash +nextflow run main.nf -resume +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Si vous regardez dans le répertoire results, vous devriez voir les fichiers individuels contenant l'art ASCII de chaque salutation prononcée par le personnage correspondant. + +??? abstract "Répertoire et exemple de contenu de fichier" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola.txt + └── cowpy-salut.txt + ``` + + ```text title="results/cowpy-bonjour.txt" + _________________ + / Bonjour \ + \ Salut, à demain / + ----------------- + \ + \ + _ _ + | \__/| .~ ~. + /oo `./ .' + {o__, \ { + / . . ) \ + `-` '-' \ } + .( _( )_.' + '---.~_ _ _| + ``` + +Cela montre que nous avons pu utiliser les informations dans la meta map pour paramétrer la commande dans la deuxième étape du pipeline. + +Cependant, comme noté ci-dessus, une partie du code impliqué était un peu maladroite, puisque nous avons dû déballer les métadonnées tout en étant encore dans le contexte du corps du workflow. +Cette approche fonctionne bien pour utiliser un petit nombre de champs de la meta map, mais évoluerait mal si nous voulions en utiliser beaucoup plus. + +Il existe un autre opérateur appelé `multiMap()` qui nous permet de rationaliser cela un peu, mais même alors ce n'est pas idéal. + +??? info "(Optionnel) Version alternative avec `multiMap()`" + + Au cas où vous vous poseriez la question, nous ne pouvions pas simplement écrire une seule opération `map()` qui sort à la fois le `file` et le `character`, parce que cela les retournerait comme un tuple. + Nous avons dû écrire deux opérations `map()` séparées afin de fournir les éléments `file` et `character` au processus séparément. + + Techniquement, il existe une autre façon de le faire à travers une seule opération de mapping, en utilisant l'opérateur `multiMap()`, qui est capable d'émettre plusieurs canaux. + Par exemple, vous pourriez remplacer l'appel à `COWPY` ci-dessus par le code suivant : + + === "Après" + + ```groovy title="main.nf" linenums="34" + // Exécuter cowpy pour générer de l'art ASCII + COWPY( + ch_languages.multiMap { meta, file -> + file: file + character: meta.character + } + ) + ``` + + === "Avant" + + ```groovy title="main.nf" linenums="34" + // Exécuter cowpy pour générer de l'art ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + + Cela produit exactement le même résultat. + +Dans les deux cas, il est gênant de devoir faire un peu de déballage au niveau du workflow. + +Il serait préférable de pouvoir fournir la meta map entière au processus et choisir ce dont nous avons besoin une fois là-bas. + +### 3.3. Passer et utiliser la meta map entière + +Le but de la meta map est après tout de passer toutes les métadonnées ensemble comme un ensemble. +La seule raison pour laquelle nous ne pouvions pas le faire ci-dessus est que le processus n'est pas configuré pour accepter une meta map. +Mais puisque nous contrôlons le code du processus, nous pouvons changer cela. + +Modifions le processus `COWPY` pour accepter la structure de tuple `[meta, file]` que nous avons utilisée dans le premier processus afin de pouvoir rationaliser le workflow. + +À cette fin, nous devrons faire trois choses : + +1. Modifier les définitions d'entrée du module de processus `COWPY` +2. Mettre à jour la commande du processus pour utiliser la meta map +3. Mettre à jour l'appel de processus dans le corps du workflow + +Prêt ? Allons-y ! + +#### 3.3.1. Modifier l'entrée du module `COWPY` diff --git a/docs/fr/docs/side_quests/nf-test.md b/docs/fr/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..aaaed41883 --- /dev/null +++ b/docs/fr/docs/side_quests/nf-test.md @@ -0,0 +1,1194 @@ +# Tests avec nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Pouvoir tester systématiquement que chaque partie de votre workflow fait ce qu'elle est censée faire est essentiel pour la reproductibilité et la maintenance à long terme, et peut être d'une grande aide durant le processus de développement. + +Prenons un moment pour parler de l'importance des tests. Si vous développez un workflow, l'une des premières choses que vous ferez sera de prendre des données de test dont vous savez qu'elles sont valides et devraient produire un résultat. Vous ajoutez le premier processus au pipeline et le connectez à vos entrées pour le faire fonctionner. Ensuite, pour vérifier que tout fonctionne, vous l'exécutez sur les données de test. En supposant que cela fonctionne, vous passez au processus suivant et exécutez à nouveau les données de test. Vous répétez ce processus jusqu'à obtenir un pipeline qui vous satisfait. + +Ensuite, vous ajoutez peut-être un simple paramètre vrai ou faux comme `--skip_process`. Maintenant vous devez exécuter le pipeline deux fois, une fois avec chaque paramètre pour vous assurer qu'il fonctionne comme prévu. Mais attendez, comment vérifier si `--skip_process` saute réellement le processus ? Nous devons fouiller dans les sorties ou vérifier les fichiers de log ! C'est pénible et sujet aux erreurs. + +Au fur et à mesure que vous développez votre pipeline, il deviendra rapidement si complexe que tester manuellement chaque itération sera lent et sujet aux erreurs. De plus, si vous trouvez une erreur, il sera très difficile de déterminer exactement d'où provient l'erreur dans votre pipeline. C'est là que les tests interviennent. + +Les tests permettent de vérifier systématiquement que chaque partie de votre pipeline fonctionne comme prévu. Les avantages pour un développeur de tests bien écrits sont énormes : + +- **Confiance** : Parce que les tests couvrent l'ensemble du pipeline, vous pouvez être sûr que modifier quelque chose n'affecte rien d'autre +- **Fiabilité** : Lorsque plusieurs développeurs travaillent sur le pipeline, ils savent que les autres développeurs n'ont pas cassé le pipeline et chaque composant. +- **Transparence** : Les tests montrent où un pipeline échoue et facilitent le suivi du problème. Ils fonctionnent également comme une forme de documentation, montrant comment exécuter un processus ou un workflow. +- **Rapidité** : Parce que les tests sont automatisés, ils peuvent être exécutés très rapidement et de manière répétée. Vous pouvez itérer rapidement avec moins de crainte d'introduire de nouveaux bugs. + +Il existe de nombreux types de tests différents que nous pouvons écrire : + +1. **Tests au niveau module** : Pour les processus individuels +2. **Tests au niveau workflow** : Pour un seul workflow +3. **Tests au niveau pipeline** : Pour le pipeline dans son ensemble +4. **Tests de performance** : Pour la vitesse et l'efficacité du pipeline +5. **Tests de stress** : Évaluation de la performance du pipeline dans des conditions extrêmes pour déterminer ses limites + +Tester des processus individuels est analogue aux tests unitaires dans d'autres langages. Tester le workflow ou l'ensemble du pipeline est analogue à ce qu'on appelle les tests d'intégration dans d'autres langages, où nous testons les interactions des composants. + +[**nf-test**](https://www.nf-test.com/) est un outil qui vous permet d'écrire des tests au niveau module, workflow et pipeline. En bref, il vous permet de vérifier systématiquement que chaque partie individuelle du pipeline fonctionne comme prévu, _de manière isolée_. + +### Objectifs d'apprentissage + +Dans cette quête secondaire, vous apprendrez à utiliser nf-test pour écrire un test au niveau workflow pour le pipeline ainsi que des tests au niveau module pour les trois processus qu'il appelle. + +À la fin de cette quête secondaire, vous serez capable d'utiliser efficacement les techniques suivantes : + +- Initialiser nf-test dans votre projet +- Générer des tests au niveau module et workflow +- Ajouter des types courants d'assertions +- Comprendre quand utiliser les snapshots vs. les assertions de contenu +- Exécuter des tests pour un projet entier + +Ces compétences vous aideront à mettre en œuvre une stratégie de test complète dans vos projets de pipeline, garantissant qu'ils sont plus robustes et maintenables. + +### Prérequis + +Avant de vous lancer dans cette quête secondaire, vous devriez : + +- Avoir terminé le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants. +- Être à l'aise avec les concepts et mécanismes de base de Nextflow (processus, canaux, opérateurs, manipulation de fichiers, métadonnées) + +--- + +## 0. Mise en route + +#### Ouvrir l'environnement de formation dans Codespaces + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Aller dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/nf-test +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner le matériel + +Vous trouverez un fichier de workflow principal et un fichier CSV appelé `greetings.csv` qui contient l'entrée du pipeline. + +```console title="Contenu du répertoire" +. +├── greetings.csv +└── main.nf +``` + +Pour une description détaillée des fichiers, consultez la [mise en route de Hello Nextflow](../hello_nextflow/00_orientation.md). + +Le workflow que nous allons tester est un sous-ensemble du workflow Hello construit dans [Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +??? example "Que fait le workflow Hello Nextflow ?" + + Si vous n'avez pas suivi la formation [Hello Nextflow](../hello_nextflow/index.md), voici un aperçu rapide de ce que fait ce workflow simple. + + Le workflow prend un fichier CSV contenant des salutations, exécute quatre étapes de transformation consécutives sur elles, et produit un seul fichier texte contenant une image ASCII d'un personnage amusant disant les salutations. + + Les quatre étapes sont implémentées comme des processus Nextflow (`sayHello`, `convertToUpper`, `collectGreetings`, et `cowpy`) stockés dans des fichiers de module séparés. + + 1. **`sayHello`:** Écrit chaque salutation dans son propre fichier de sortie (par exemple, "Hello-output.txt") + 2. **`convertToUpper`:** Convertit chaque salutation en majuscules (par exemple, "HELLO") + 3. **`collectGreetings`:** Collecte toutes les salutations en majuscules dans un seul fichier batch + 4. **`cowpy`:** Génère de l'art ASCII en utilisant l'outil `cowpy` + + Les résultats sont publiés dans un répertoire appelé `results/`, et la sortie finale du pipeline (lorsqu'il est exécuté avec les paramètres par défaut) est un fichier texte contenant de l'art ASCII d'un personnage disant les salutations en majuscules. + + Dans cette quête secondaire, nous utilisons une forme intermédiaire du workflow Hello qui ne contient que les deux premiers processus. + +Le sous-ensemble avec lequel nous allons travailler est composé de deux processus : `sayHello` et `convertToUpper`. +Vous pouvez voir le code complet du workflow ci-dessous. + +??? example "Code du workflow" + + ```groovy title="main.nf" + /* + * Paramètres du pipeline + */ + params.input_file = "greetings.csv" + + /* + * Utilise echo pour imprimer 'Hello World!' sur la sortie standard + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Utilise un utilitaire de remplacement de texte pour convertir la salutation en majuscules + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // créer un canal pour les entrées depuis un fichier CSV + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // émettre une salutation + sayHello(greeting_ch) + + // convertir la salutation en majuscules + convertToUpper(sayHello.out) + } + ``` + +#### Exécuter le workflow + +Exécutons le workflow pour nous assurer qu'il fonctionne comme prévu. + +```bash +nextflow run main.nf +``` + +```console title="Résultat de l'exécution du workflow" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +FÉLICITATIONS ! Vous venez d'exécuter un test ! + +"Attendez, quoi ? Je viens juste d'exécuter le workflow et ça a fonctionné ! Comment est-ce un test ?" + +Bonne question ! + +Décomposons ce qui vient de se passer. + +Vous avez exécuté le workflow avec les paramètres par défaut, vous avez confirmé qu'il fonctionnait et vous êtes satisfait des résultats. C'est l'essence même des tests. Si vous avez suivi le cours de formation Hello Nextflow, vous aurez remarqué que nous avons toujours commencé chaque section en exécutant le workflow que nous utilisions comme point de départ, pour confirmer que tout était correctement configuré. + +Tester un logiciel fait essentiellement ce processus pour nous. + +#### Examiner l'exercice + +Votre défi est d'ajouter des tests standardisés à ce workflow en utilisant nf-test, afin de faciliter la vérification que chaque partie continue de fonctionner comme prévu en cas de modifications ultérieures. + +#### Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon codespace est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +- [ ] J'ai exécuté le workflow avec succès +- [ ] Je comprends l'exercice + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +--- + +## 1. Initialiser `nf-test` + +Le package `nf-test` fournit une commande d'initialisation qui configure quelques éléments afin que nous puissions commencer à développer des tests pour notre projet. + +```bash +nf-test init +``` + +Cela devrait produire la sortie suivante : + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Cela crée également un répertoire `tests` contenant une ébauche de fichier de configuration. + +### 1.1. Générer un nf-test + +`nf-test` est fourni avec un ensemble d'outils pour construire des fichiers nf-test, nous épargnant la majeure partie du travail. Ceux-ci se trouvent sous la sous-commande `generate`. Générons un test pour le pipeline : + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Sortie" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Cela créera un fichier `main.nf.test` dans le répertoire `tests`. C'est notre fichier de test au niveau pipeline. Si vous exécutez `tree tests/`, vous devriez voir quelque chose comme ceci : + +```console title="Contenu du répertoire tests" +tests/ +├── main.nf.test +└── nextflow.config +``` + +Le fichier `main.nf.test` est notre fichier de test au niveau pipeline. Ouvrons-le et examinons son contenu. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Prenons un moment pour comprendre la structure du fichier de test. + +Le bloc `nextflow_pipeline` est le point d'entrée pour tous les tests au niveau pipeline. Il contient : + +- `name` : Le nom du test. +- `script` : Le chemin vers le script du pipeline. + +Le bloc `test` est le test proprement dit. Il contient : + +- `when` : Les conditions dans lesquelles le test doit être exécuté. Cela inclut les paramètres qui seront utilisés pour exécuter le pipeline. +- `then` : Les assertions qui doivent être faites. Cela inclut les résultats attendus du pipeline. + +En français clair, la logique du test se lit comme suit : +"**Quand** ces _paramètres_ sont fournis à ce _pipeline_, **alors** nous nous attendons à voir ces résultats." + +Ce n'est pas un test fonctionnel, nous démontrerons comment le transformer en un dans la section suivante. + +### Une note sur les noms de tests + +Dans l'exemple ci-dessus, nous avons utilisé le nom par défaut "Should run without failures" qui est approprié pour un test de base qui vérifie simplement si le pipeline s'exécute avec succès. Cependant, au fur et à mesure que nous ajoutons des cas de test plus spécifiques, nous devrions utiliser des noms plus descriptifs qui indiquent ce que nous testons réellement. Par exemple : + +- "Should convert input to uppercase" - lors du test de fonctionnalités spécifiques +- "Should handle empty input gracefully" - lors du test de cas limites +- "Should respect max memory parameter" - lors du test de contraintes de ressources +- "Should create expected output files" - lors du test de génération de fichiers + +Les bons noms de tests devraient : + +1. Commencer par "Should" pour clarifier quel est le comportement attendu +2. Décrire la fonctionnalité ou le scénario spécifique testé +3. Être suffisamment clairs pour que si le test échoue, vous sachiez quelle fonctionnalité est cassée + +À mesure que nous ajouterons plus d'assertions et de cas de test spécifiques plus tard, nous utiliserons ces noms plus descriptifs pour clarifier ce que chaque test vérifie. + +### 1.2. Exécuter le test + +Exécutons le test pour voir ce qui se passe. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="Échec du test pipeline nf-test" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Le test échoue ! Que s'est-il passé ? + +1. nf-test a essayé d'exécuter le pipeline tel quel, en utilisant les paramètres du bloc `when` : + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test a vérifié le statut du pipeline et l'a comparé au bloc `when` : + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Notez comment nf-test a signalé l'échec du pipeline et fourni le message d'erreur de Nextflow : + +```console title="Erreur" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Alors quel était le problème ? Rappelez-vous que le pipeline a un fichier greetings.csv dans le répertoire du projet. Lorsque nf-test exécute le pipeline, il cherchera ce fichier, mais ne peut pas le trouver. Le fichier est bien là, que se passe-t-il ? Eh bien, si nous regardons le chemin, nous pouvons voir que le test se déroule dans le chemin `./nf-test/tests/longHashString/`. Tout comme Nextflow, nf-test crée un nouveau répertoire pour chaque test afin de garder tout isolé. Le fichier de données ne se trouve pas là, nous devons donc corriger le chemin vers le fichier dans le test original. + +Revenons au fichier de test et modifions le chemin vers le fichier dans le bloc `when`. + +Vous vous demandez peut-être comment nous allons pointer vers la racine du pipeline dans le test. Puisque c'est une situation courante, nf-test dispose d'une gamme de variables globales que nous pouvons utiliser pour nous faciliter la vie. Vous pouvez trouver la liste complète [ici](https://www.nf-test.com/docs/testcases/global_variables/) mais en attendant, nous utiliserons la variable `projectDir`, qui désigne la racine du projet de pipeline. + +_Avant :_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Après :_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Exécutons à nouveau le test pour voir s'il fonctionne. + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="Le pipeline réussit" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Succès ! Le pipeline s'exécute avec succès et le test réussit. Exécutez-le autant de fois que vous le souhaitez et vous obtiendrez toujours le même résultat ! + +Par défaut, la sortie de Nextflow est masquée, mais pour vous convaincre que nf-test exécute définitivement le workflow, vous pouvez utiliser le flag `--verbose` : + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Le pipeline exécute tous les processus" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Ajouter des assertions + +Une vérification simple consiste à s'assurer que notre pipeline exécute tous les processus attendus et n'en saute aucun silencieusement. Rappelez-vous que notre pipeline exécute 6 processus, un appelé `sayHello` et un appelé `convertToUpper` pour chacune des 3 salutations. + +Ajoutons une assertion à notre test pour vérifier que le pipeline exécute le nombre attendu de processus. Nous mettrons également à jour le nom de notre test pour mieux refléter ce que nous testons. + +**Avant :** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Après :** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Le nom du test reflète maintenant mieux ce que nous vérifions réellement - non seulement que le pipeline s'exécute sans échec, mais qu'il exécute le nombre attendu de processus. + +Exécutons à nouveau le test pour voir s'il fonctionne. + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="Le pipeline réussit avec les assertions" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Succès ! Le pipeline s'exécute avec succès et le test réussit. Nous avons maintenant commencé à tester les détails du pipeline, ainsi que le statut global. + +### 1.4. Tester la sortie + +Ajoutons une assertion à notre test pour vérifier que le fichier de sortie a été créé. Nous l'ajouterons comme un test séparé, avec un nom informatif, pour faciliter l'interprétation des résultats. + +**Avant :** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Après :** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Exécutez à nouveau le test pour voir s'il fonctionne. + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.nf.test +``` + +```console title="Le pipeline réussit avec les assertions de fichiers" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Succès ! Les tests réussissent parce que le pipeline s'est terminé avec succès, le nombre correct de processus a été exécuté et les fichiers de sortie ont été créés. Cela devrait également vous montrer à quel point il est utile de fournir ces noms informatifs pour vos tests. + +Ce n'est que la surface, nous pouvons continuer à écrire des assertions pour vérifier les détails du pipeline, mais pour l'instant passons au test des composants internes du pipeline. + +### À retenir + +Vous savez comment écrire un nf-test pour un pipeline. + +### Et ensuite ? + +Apprenez à tester un processus Nextflow. + +--- + +## 2. Tester un processus Nextflow + +Nous n'avons pas besoin d'écrire des tests pour chaque partie du pipeline, mais plus nous avons de tests, plus nous pouvons être complets sur le pipeline et plus nous pouvons être confiants qu'il fonctionne comme prévu. Dans cette section, nous allons tester les deux processus du pipeline en tant qu'unités individuelles. + +### 2.1. Tester le processus `sayHello` + +Commençons par le processus `sayHello`. + +Utilisons à nouveau la commande `nf-test generate` pour générer des tests pour le processus. + +```bash +nf-test generate process main.nf +``` + +```console title="Sortie" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Concentrons-nous pour l'instant sur le processus `sayhello` dans le fichier `main.sayhello.nf.test`. + +Ouvrons le fichier et examinons son contenu. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Comme précédemment, nous commençons par les détails du test, suivis des blocs `when` et `then`. Cependant, nous avons également un bloc `process` supplémentaire qui nous permet de définir les entrées du processus. + +Exécutons le test pour voir s'il fonctionne. + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Le test du processus échoue" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Le test échoue parce que le processus `sayHello` déclare 1 entrée mais a été appelé avec 0 arguments. Corrigeons cela en ajoutant une entrée au processus. Rappelez-vous de [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (et de la section de mise en route ci-dessus) que notre processus `sayHello` prend une seule entrée de valeur, que nous devrons fournir. Nous devrions également corriger le nom du test pour mieux refléter ce que nous testons. + +**Avant :** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Après :** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Exécutons à nouveau le test pour voir s'il fonctionne. + +```console title="Réussite du test pipeline nf-test" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Succès ! Le test réussit parce que le processus `sayHello` s'est exécuté avec succès et la sortie a été créée. + +### 2.2. Examiner le snapshot créé par le test + +Si nous regardons le fichier `tests/main.sayhello.nf.test`, nous pouvons voir qu'il utilise une méthode `snapshot()` dans le bloc d'assertion : + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Cela indique à nf-test de créer un snapshot de la sortie du processus `sayHello`. Jetons un coup d'œil au contenu du fichier de snapshot. + +```console title="Contenu du fichier snapshot" +code tests/main.sayhello.nf.test.snap +``` + +Nous ne l'imprimerons pas ici, mais vous devriez voir un fichier JSON contenant des détails sur le processus et les sorties du processus. En particulier, nous pouvons voir une ligne qui ressemble à ceci : + +```json title="Contenu du fichier snapshot" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Cela représente les sorties créées par le processus `sayHello`, que nous testons explicitement. Si nous réexécutons le test, le programme vérifiera que la nouvelle sortie correspond à la sortie qui a été enregistrée à l'origine. C'est une façon rapide et simple de tester que les sorties du processus ne changent pas, c'est pourquoi nf-test le fournit par défaut. + +!!!warning + + Cela signifie que nous devons être sûrs que la sortie que nous enregistrons lors de l'exécution d'origine est correcte ! + +Si, au cours du développement futur, quelque chose dans le code change et provoque une sortie différente, le test échouera et nous devrons déterminer si le changement est attendu ou non. + +- S'il s'avère que quelque chose dans le code s'est cassé, nous devrons le corriger, en s'attendant à ce que le code corrigé passe le test. +- Si c'est un changement attendu (par exemple, l'outil a été amélioré et les résultats sont meilleurs) alors nous devrons mettre à jour le snapshot pour accepter la nouvelle sortie comme référence à faire correspondre. nf-test a un paramètre `--update-snapshot` à cet effet. + +Nous pouvons réexécuter le test et voir que le test devrait réussir : + +```console title="Réussite du test du processus nf-test avec snapshot" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Succès ! Le test réussit parce que le processus `sayHello` s'est exécuté avec succès et la sortie correspondait au snapshot. + +### 2.3. Alternative aux snapshots : Assertions de contenu directes + +Bien que les snapshots soient excellents pour détecter tout changement dans la sortie, parfois vous voulez vérifier un contenu spécifique sans être aussi strict sur la correspondance complète du fichier. Par exemple : + +- Lorsque des parties de la sortie peuvent changer (horodatages, identifiants aléatoires, etc.) mais que certains contenus clés doivent être présents +- Lorsque vous voulez vérifier des motifs ou valeurs spécifiques dans la sortie +- Lorsque vous voulez rendre le test plus explicite sur ce qui constitue un succès + +Voici comment nous pourrions modifier notre test pour vérifier un contenu spécifique : + +**Avant :** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Après :** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Notez que nf-test voit les sorties du processus comme une liste de listes, donc `process.out[0][0]` récupère la première partie du premier élément du canal (ou 'émission') de ce processus. + +Cette approche : + +- Rend clair exactement ce que nous attendons dans la sortie +- Est plus résiliente aux changements non pertinents dans la sortie +- Fournit de meilleurs messages d'erreur lorsque les tests échouent +- Permet des validations plus complexes (motifs regex, comparaisons numériques, etc.) + +Exécutons le test pour voir s'il fonctionne. + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Le test du processus échoue" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Tester le processus `convertToUpper` + +Ouvrons le fichier `tests/main.converttoupper.nf.test` et examinons son contenu : + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +C'est un test similaire au processus `sayHello`, mais il teste le processus `convertToUpper`. Nous savons que celui-ci échouera car tout comme avec `sayHello`, le processus `convertToUpper` prend une seule entrée de chemin, mais nous n'en avons pas spécifié. + +Nous devons maintenant fournir un seul fichier d'entrée au processus convertToUpper, qui contient du texte que nous voulons convertir en majuscules. Il existe de nombreuses façons de faire cela : + +- Nous pourrions créer un fichier dédié pour tester +- Nous pourrions réutiliser le fichier existant data/greetings.csv +- Nous pourrions le créer à la volée dans le test + +Pour l'instant, réutilisons le fichier existant data/greetings.csv en utilisant l'exemple que nous avons utilisé avec le test au niveau pipeline. Comme précédemment, nous pouvons nommer le test pour mieux refléter ce que nous testons, mais cette fois laissons-le "snapshoter" le contenu plutôt que de vérifier des chaînes spécifiques (comme nous l'avons fait dans l'autre processus). + +**Avant :** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Après :** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Et exécutons le test ! + +```bash title="Réussite du test pipeline nf-test" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="Réussite du test du processus convertToUpper nf-test" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Notez que nous avons créé un fichier snapshot pour le processus `convertToUpper` à `tests/main.converttoupper.nf.test.snap`. Si nous exécutons le test à nouveau, nous devrions voir que nf-test réussit à nouveau. + +```bash title="Réussite du test du processus convertToUpper nf-test" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="Réussite du test du processus convertToUpper nf-test" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### À retenir + +Vous savez comment écrire des tests pour un processus Nextflow et les exécuter. + +### Et ensuite ? + +Apprenez à exécuter des tests pour tout en une seule fois ! + +## 3. Exécuter des tests pour l'ensemble du dépôt + +Exécuter nf-test sur chaque composant est correct, mais laborieux et sujet aux erreurs. Ne peut-on pas simplement tout tester en une seule fois ? + +Oui, nous le pouvons ! + +Exécutons nf-test sur l'ensemble du dépôt. + +### 3.1. Exécuter nf-test sur l'ensemble du dépôt + +Nous pouvons exécuter nf-test sur l'ensemble du dépôt en exécutant la commande `nf-test test`. + +```bash +nf-test test . +``` + +Notez que nous utilisons simplement le `.` pour exécuter tout depuis notre répertoire actuel. Cela inclura tous les tests ! + +```console title="Réussite du test du dépôt nf-test" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Regardez ça ! Nous avons exécuté 4 tests, 1 pour chaque processus et 2 pour l'ensemble du pipeline avec une seule commande. Imaginez à quel point c'est puissant sur une grande base de code ! + +--- + +## Résumé + +Dans cette quête secondaire, vous avez appris à exploiter les fonctionnalités de nf-test pour créer et exécuter des tests pour des processus individuels ainsi que des tests de bout en bout pour l'ensemble du pipeline. +Vous êtes maintenant conscient des deux principales approches de validation de sortie, les snapshots et les assertions de contenu directes, et savez quand utiliser l'une ou l'autre. +Vous savez également comment exécuter des tests un par un ou pour un projet entier. + +L'application de ces techniques dans votre propre travail vous permettra de vous assurer que : + +- Votre code fonctionne comme prévu +- Les modifications ne cassent pas les fonctionnalités existantes +- D'autres développeurs peuvent contribuer en toute confiance +- Les problèmes peuvent être identifiés et corrigés rapidement +- Le contenu de sortie correspond aux attentes + +### Motifs clés + +1. Tests au niveau pipeline : + - Test de succès de base + - Vérification du nombre de processus + - Vérifications d'existence de fichiers de sortie +2. Tests au niveau processus +3. Deux approches de validation de sortie : + - Utilisation de snapshots pour une vérification complète de la sortie + - Utilisation d'assertions de contenu directes pour des vérifications de contenu spécifique +4. Exécution de tous les tests dans un dépôt avec une seule commande + +### Ressources supplémentaires + +Consultez la [documentation nf-test](https://www.nf-test.com/) pour plus de fonctionnalités de test avancées et de meilleures pratiques. Vous pourriez vouloir : + +- Ajouter des assertions plus complètes à vos tests +- Écrire des tests pour les cas limites et les conditions d'erreur +- Configurer l'intégration continue pour exécuter les tests automatiquement +- En savoir plus sur d'autres types de tests comme les tests de workflow et de module +- Explorer des techniques de validation de contenu plus avancées + +**Rappelez-vous :** Les tests sont une documentation vivante de la façon dont votre code devrait se comporter. Plus vous écrivez de tests, et plus vos assertions sont spécifiques, plus vous pouvez avoir confiance en la fiabilité de votre pipeline. + +--- + +## Et ensuite ? + +Retournez au [menu des Quêtes Secondaires](./index.md) ou cliquez sur le bouton en bas à droite de la page pour passer au prochain sujet de la liste. diff --git a/docs/fr/docs/side_quests/orientation.md b/docs/fr/docs/side_quests/orientation.md new file mode 100644 index 0000000000..ed7ae20710 --- /dev/null +++ b/docs/fr/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'environnement GitHub Codespaces contient tous les logiciels, le code et les données nécessaires pour suivre cette formation, vous n'avez donc rien à installer vous-même. +Cependant, vous avez besoin d'un compte (gratuit) pour vous connecter, et vous devriez prendre quelques minutes pour vous familiariser avec l'interface. + +Si vous ne l'avez pas encore fait, veuillez suivre [ce lien](../../envsetup/) avant d'aller plus loin. + +## Matériel fourni + +Tout au long de cette formation, nous travaillerons dans le répertoire `side-quests/`. +Ce répertoire contient tous les fichiers de code, les données de test et les fichiers accessoires dont vous aurez besoin. + +N'hésitez pas à explorer le contenu de ce répertoire ; la façon la plus simple de le faire est d'utiliser l'explorateur de fichiers sur le côté gauche de l'espace de travail GitHub Codespaces. +Alternativement, vous pouvez utiliser la commande `tree`. +Tout au long de la formation, nous utilisons la sortie de `tree` pour représenter la structure et le contenu des répertoires sous une forme lisible, parfois avec des modifications mineures pour plus de clarté. + +Ici, nous générons une table des matières jusqu'au deuxième niveau : + +```bash +tree . -L 2 +``` + +Si vous exécutez ceci dans `side-quests`, vous devriez voir la sortie suivante : + +```console title="Contenu du répertoire" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Voici un résumé de ce que vous devez savoir pour commencer :** + +- **Chaque répertoire correspond à une quête secondaire individuelle.** + Leur contenu est détaillé sur la page de la quête secondaire correspondante. + +- **Le répertoire `solutions`** contient les scripts de workflow et/ou de module complétés qui résultent de l'exécution des différentes étapes de chaque quête secondaire. + Ils sont destinés à être utilisés comme référence pour vérifier votre travail et résoudre tout problème. + +!!!tip "Astuce" + + Si pour une raison quelconque vous sortez de ce répertoire, vous pouvez toujours exécuter cette commande pour y revenir : + + ```bash + cd /workspaces/training/side-quests + ``` + +Maintenant, pour commencer la formation, cliquez sur la flèche dans le coin inférieur droit de cette page. diff --git a/docs/fr/docs/side_quests/splitting_and_grouping.md b/docs/fr/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..2fac680587 --- /dev/null +++ b/docs/fr/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,991 @@ +# Division et regroupement + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow fournit des outils puissants pour travailler avec les données de manière flexible. Une capacité clé est la division des données en différents flux, puis le regroupement d'éléments connexes. Ceci est particulièrement précieux dans les workflows de bioinformatique où vous devez traiter différents types d'échantillons séparément avant de combiner les résultats pour l'analyse. + +Imaginez cela comme le tri du courrier : vous séparez les lettres par destination, traitez chaque pile différemment, puis recombinez les éléments allant à la même personne. Nextflow utilise des opérateurs spéciaux pour accomplir cela avec des données scientifiques. Cette approche est également communément appelée le modèle **scatter/gather** dans l'informatique distribuée et les workflows de bioinformatique. + +Le système de canaux de Nextflow est au cœur de cette flexibilité. Les canaux connectent différentes parties de votre workflow, permettant aux données de circuler à travers votre analyse. Vous pouvez créer plusieurs canaux à partir d'une seule source de données, traiter chaque canal différemment, puis fusionner les canaux lorsque nécessaire. Cette approche vous permet de concevoir des workflows qui reflètent naturellement les chemins de branchement et de convergence d'analyses bioinformatiques complexes. + +### Objectifs d'apprentissage + +Dans cette quête annexe, vous apprendrez à diviser et regrouper des données en utilisant les opérateurs de canaux de Nextflow. +Nous commencerons avec un fichier CSV contenant des informations sur les échantillons et les fichiers de données associés, puis manipulerons et réorganiserons ces données. + +À la fin de cette quête annexe, vous serez capable de séparer et combiner efficacement des flux de données, en utilisant les techniques suivantes : + +- Lire des données à partir de fichiers en utilisant `splitCsv` +- Filtrer et transformer des données avec `filter` et `map` +- Combiner des données connexes en utilisant `join` et `groupTuple` +- Créer des combinaisons de données avec `combine` pour un traitement parallèle +- Optimiser la structure des données en utilisant `subMap` et des stratégies de déduplication +- Construire des fonctions réutilisables avec des closures nommées pour vous aider à manipuler les structures de canaux + +Ces compétences vous aideront à construire des workflows capables de gérer efficacement plusieurs fichiers d'entrée et différents types de données, tout en maintenant une structure de code propre et maintenable. + +### Prérequis + +Avant d'entreprendre cette quête annexe, vous devez : + +- Avoir terminé le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants. +- Être à l'aise avec les concepts et mécanismes de base de Nextflow (processes, channels, operators, travailler avec des fichiers, méta données) + +**Optionnel :** Nous recommandons de compléter d'abord la quête annexe [Metadata in workflows](./metadata.md). +Elle couvre les fondamentaux de la lecture de fichiers CSV avec `splitCsv` et de la création de meta maps, que nous utiliserons beaucoup ici. + +--- + +## 0. Commencer + +#### Ouvrir le codespace de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/splitting_and_grouping +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner les matériaux + +Vous trouverez un fichier de workflow principal et un répertoire `data` contenant une feuille d'échantillons nommée `samplesheet.csv`. + +```console title="Contenu du répertoire" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +La feuille d'échantillons contient des informations sur des échantillons de différents patients, incluant l'identifiant du patient, le numéro de répétition de l'échantillon, le type (normal ou tumeur), et les chemins vers des fichiers de données hypothétiques (qui n'existent pas réellement, mais nous ferons comme s'ils existaient). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Cette feuille d'échantillons répertorie huit échantillons provenant de trois patients (A, B, C). + +Pour chaque patient, nous avons des échantillons de type `tumor` (provenant généralement de biopsies tumorales) ou `normal` (prélevés sur du tissu sain ou du sang). +Si vous n'êtes pas familier avec l'analyse du cancer, sachez simplement que cela correspond à un modèle expérimental qui utilise des échantillons appariés tumeur/normal pour effectuer des analyses contrastives. + +Pour le patient A spécifiquement, nous avons deux ensembles de réplicats techniques (répétitions). + +!!! note + + Ne vous inquiétez pas si vous n'êtes pas familier avec cette conception expérimentale, ce n'est pas critique pour comprendre ce tutoriel. + +#### Examiner l'assignation + +Votre défi est d'écrire un workflow Nextflow qui va : + +1. **Lire** les données d'échantillons à partir d'un fichier CSV et les structurer avec des meta maps +2. **Séparer** les échantillons dans différents canaux en fonction du type (normal vs tumeur) +3. **Joindre** les paires appariées tumeur/normal par identifiant de patient et numéro de réplicat +4. **Distribuer** les échantillons sur des intervalles génomiques pour un traitement parallèle +5. **Regrouper** les échantillons connexes pour une analyse en aval + +Ceci représente un modèle bioinformatique courant où vous devez diviser les données pour un traitement indépendant, puis recombiner les éléments connexes pour une analyse comparative. + +#### Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon codespace est opérationnel +- [ ] J'ai configuré mon répertoire de travail de manière appropriée +- [ ] Je comprends l'assignation + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +--- + +## 1. Lire les données d'échantillons + +### 1.1. Lire les données d'échantillons avec `splitCsv` et créer des meta maps + +Commençons par lire les données d'échantillons avec `splitCsv` et les organiser selon le modèle de meta map. Dans le fichier `main.nf`, vous verrez que nous avons déjà commencé le workflow. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + Tout au long de ce tutoriel, nous utiliserons le préfixe `ch_` pour toutes les variables de canaux afin d'indiquer clairement qu'il s'agit de canaux Nextflow. + +Si vous avez complété la quête annexe [Metadata in workflows](./metadata.md), vous reconnaîtrez ce modèle. Nous utiliserons `splitCsv` pour lire le CSV et structurer immédiatement les données avec une meta map pour séparer les métadonnées des chemins de fichiers. + +!!! info + + Nous rencontrerons deux concepts différents appelés `map` dans cette formation : + + - **Structure de données** : La map Groovy (équivalente aux dictionnaires/hashes dans d'autres langages) qui stocke des paires clé-valeur + - **Opérateur de canal** : L'opérateur `.map()` qui transforme les éléments dans un canal + + Nous clarifierons de quel type nous parlons dans le contexte, mais cette distinction est importante à comprendre lors du travail avec Nextflow. + +Appliquez ces modifications à `main.nf` : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Cela combine l'opération `splitCsv` (lecture du CSV avec en-têtes) et l'opération `map` (structuration des données en tuples `[meta, file]`) en une seule étape. Appliquez cette modification et exécutez le pipeline : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Nous avons maintenant un canal où chaque élément est un tuple `[meta, file]` - métadonnées séparées des chemins de fichiers. Cette structure nous permet de diviser et regrouper notre charge de travail en fonction des champs de métadonnées. + +--- + +## 2. Filtrer et transformer les données + +### 2.1. Filtrer les données avec `filter` + +Nous pouvons utiliser l'[opérateur `filter`](https://www.nextflow.io/docs/latest/operator.html#filter) pour filtrer les données en fonction d'une condition. Disons que nous voulons traiter uniquement les échantillons normaux. Nous pouvons le faire en filtrant les données en fonction du champ `type`. Insérons cela avant l'opérateur `view`. + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Exécutez à nouveau le workflow pour voir le résultat filtré : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Nous avons réussi à filtrer les données pour inclure uniquement les échantillons normaux. Récapitulons comment cela fonctionne. + +L'opérateur `filter` prend une closure qui est appliquée à chaque élément du canal. Si la closure renvoie `true`, l'élément est inclus ; si elle renvoie `false`, l'élément est exclu. + +Dans notre cas, nous voulons conserver uniquement les échantillons où `meta.type == 'normal'`. La closure utilise le tuple `meta,file` pour faire référence à chaque échantillon, accède au type d'échantillon avec `meta.type`, et vérifie s'il est égal à `'normal'`. + +Ceci est accompli avec la closure unique que nous avons introduite ci-dessus : + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Créer des canaux filtrés séparés + +Actuellement, nous appliquons le filtre au canal créé directement à partir du CSV, mais nous voulons le filtrer de plusieurs façons, réécrivons donc la logique pour créer un canal filtré séparé pour les échantillons normaux : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Exécutez le pipeline pour voir les résultats : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Nous avons réussi à filtrer les données et créé un canal séparé pour les échantillons normaux. + +Créons également un canal filtré pour les échantillons tumoraux : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Nous avons séparé les échantillons normaux et tumoraux dans deux canaux différents, et utilisé une closure fournie à `view()` pour les étiqueter différemment dans la sortie : `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Point clé + +Dans cette section, vous avez appris : + +- **Filtrer les données** : Comment filtrer les données avec `filter` +- **Diviser les données** : Comment diviser les données en différents canaux en fonction d'une condition +- **Visualiser les données** : Comment utiliser `view` pour afficher les données et étiqueter la sortie de différents canaux + +Nous avons maintenant séparé les échantillons normaux et tumoraux dans deux canaux différents. Ensuite, nous joindrons les échantillons normaux et tumoraux sur le champ `id`. + +--- + +## 3. Joindre des canaux par identifiants + +Dans la section précédente, nous avons séparé les échantillons normaux et tumoraux dans deux canaux différents. Ceux-ci pourraient être traités indépendamment en utilisant des processes ou workflows spécifiques en fonction de leur type. Mais que se passe-t-il lorsque nous voulons comparer les échantillons normaux et tumoraux du même patient ? À ce stade, nous devons les joindre à nouveau en nous assurant de faire correspondre les échantillons en fonction de leur champ `id`. + +Nextflow inclut de nombreuses méthodes pour combiner des canaux, mais dans ce cas, l'opérateur le plus approprié est [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Si vous êtes familier avec SQL, il agit comme l'opération `JOIN`, où nous spécifions la clé sur laquelle joindre et le type de jointure à effectuer. + +### 3.1. Utiliser `map` et `join` pour combiner en fonction de l'identifiant patient + +Si nous consultons la documentation de [`join`](https://www.nextflow.io/docs/latest/operator.html#join), nous pouvons voir que par défaut, elle joint deux canaux en fonction du premier élément de chaque tuple. + +#### 3.1.1. Vérifier la structure des données + +Si vous n'avez plus la sortie console disponible, exécutons le pipeline pour vérifier notre structure de données et voir comment nous devons la modifier pour joindre sur le champ `id`. + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Nous pouvons voir que le champ `id` est le premier élément dans chaque meta map. Pour que `join` fonctionne, nous devons isoler le champ `id` dans chaque tuple. Après cela, nous pouvons simplement utiliser l'opérateur `join` pour combiner les deux canaux. + +#### 3.1.2. Isoler le champ `id` + +Pour isoler le champ `id`, nous pouvons utiliser l'[opérateur `map`](https://www.nextflow.io/docs/latest/operator.html#map) pour créer un nouveau tuple avec le champ `id` comme premier élément. + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +C'est peut-être subtil, mais vous devriez pouvoir voir que le premier élément de chaque tuple est le champ `id`. + +#### 3.1.3. Combiner les deux canaux + +Maintenant, nous pouvons utiliser l'opérateur `join` pour combiner les deux canaux en fonction du champ `id`. + +Une fois de plus, nous utiliserons `view` pour afficher les sorties jointes. + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +C'est un peu difficile à dire parce que c'est très large, mais vous devriez pouvoir voir que les échantillons ont été joints par le champ `id`. Chaque tuple a maintenant le format : + +- `id` : L'identifiant de l'échantillon +- `normal_meta_map` : Les métadonnées de l'échantillon normal incluant le type, le réplicat et le chemin vers le fichier bam +- `normal_sample_file` : Le fichier de l'échantillon normal +- `tumor_meta_map` : Les métadonnées de l'échantillon tumoral incluant le type, le réplicat et le chemin vers le fichier bam +- `tumor_sample` : L'échantillon tumoral incluant le type, le réplicat et le chemin vers le fichier bam + +!!! warning + + L'opérateur `join` éliminera tous les tuples non appariés. Dans cet exemple, nous nous sommes assurés que tous les échantillons étaient appariés pour tumeur et normal, mais si ce n'est pas le cas, vous devez utiliser le paramètre `remainder: true` pour conserver les tuples non appariés. Consultez la [documentation](https://www.nextflow.io/docs/latest/operator.html#join) pour plus de détails. + +Maintenant vous savez comment utiliser `map` pour isoler un champ dans un tuple, et comment utiliser `join` pour combiner des tuples en fonction du premier champ. +Avec ces connaissances, nous pouvons combiner avec succès des canaux en fonction d'un champ partagé. + +Ensuite, nous examinerons la situation où vous voulez joindre sur plusieurs champs. + +### 3.2. Joindre sur plusieurs champs + +Nous avons 2 réplicats pour l'échantillon A, mais seulement 1 pour les échantillons B et C. Dans ce cas, nous avons pu les joindre efficacement en utilisant le champ `id`, mais que se passerait-il s'ils n'étaient pas synchronisés ? Nous pourrions mélanger les échantillons normaux et tumoraux de différents réplicats ! + +Pour éviter cela, nous pouvons joindre sur plusieurs champs. Il existe en fait plusieurs façons d'y parvenir, mais nous allons nous concentrer sur la création d'une nouvelle clé de jointure qui inclut à la fois l'`id` de l'échantillon et le numéro de `replicate`. + +Commençons par créer une nouvelle clé de jointure. Nous pouvons le faire de la même manière qu'avant en utilisant l'[opérateur `map`](https://www.nextflow.io/docs/latest/operator.html#map) pour créer un nouveau tuple avec les champs `id` et `repeat` comme premier élément. + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Maintenant, nous devrions voir que la jointure s'effectue en utilisant à la fois les champs `id` et `repeat`. Exécutez le workflow : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Notez comment nous avons un tuple de deux éléments (champs `id` et `repeat`) comme premier élément de chaque résultat joint. Cela démontre comment des éléments complexes peuvent être utilisés comme clé de jointure, permettant un appariement assez complexe entre les échantillons des mêmes conditions. + +Si vous souhaitez explorer d'autres façons de joindre sur différentes clés, consultez la [documentation de l'opérateur join](https://www.nextflow.io/docs/latest/operator.html#join) pour des options et exemples supplémentaires. + +### 3.3. Utiliser `subMap` pour créer une nouvelle clé de jointure + +L'approche précédente perd les noms de champs de notre clé de jointure - les champs `id` et `repeat` deviennent simplement une liste de valeurs. Pour conserver les noms de champs pour un accès ultérieur, nous pouvons utiliser la [méthode `subMap`](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>). + +La méthode `subMap` extrait uniquement les paires clé-valeur spécifiées d'une map. Ici, nous extrairons uniquement les champs `id` et `repeat` pour créer notre clé de jointure. + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Maintenant, nous avons une nouvelle clé de jointure qui inclut non seulement les champs `id` et `repeat` mais conserve également les noms de champs afin que nous puissions y accéder ultérieurement par nom, par exemple `meta.id` et `meta.repeat`. + +### 3.4. Utiliser une closure nommée dans map + +Pour éviter la duplication et réduire les erreurs, nous pouvons utiliser une closure nommée. Une closure nommée nous permet de créer une fonction réutilisable que nous pouvons appeler à plusieurs endroits. + +Pour ce faire, nous définissons d'abord la closure comme une nouvelle variable : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Nous avons défini la transformation map comme une variable nommée que nous pouvons réutiliser. + +Notez que nous convertissons également le chemin du fichier en objet Path en utilisant `file()` afin que tout process recevant ce canal puisse gérer le fichier correctement (pour plus d'informations, voir [Working with files](./working_with_files.md)). + +Implémentons la closure dans notre workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + L'opérateur `map` est passé de l'utilisation de `{ }` à l'utilisation de `( )` pour passer la closure comme argument. C'est parce que l'opérateur `map` attend une closure comme argument et `{ }` est utilisé pour définir une closure anonyme. Lors de l'appel d'une closure nommée, utilisez la syntaxe `( )`. + +Exécutez le workflow une fois de plus pour vérifier que tout fonctionne toujours : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +L'utilisation d'une closure nommée nous permet de réutiliser la même transformation à plusieurs endroits, réduisant le risque d'erreurs et rendant le code plus lisible et maintenable. + +### 3.5. Réduire la duplication des données + +Nous avons beaucoup de données dupliquées dans notre workflow. Chaque élément des échantillons joints répète les champs `id` et `repeat`. Puisque ces informations sont déjà disponibles dans la clé de regroupement, nous pouvons éviter cette redondance. Pour rappel, notre structure de données actuelle ressemble à ceci : + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Puisque les champs `id` et `repeat` sont disponibles dans la clé de regroupement, supprimons-les du reste de chaque élément de canal pour éviter la duplication. Nous pouvons le faire en utilisant la méthode `subMap` pour créer une nouvelle map avec uniquement le champ `type`. Cette approche nous permet de maintenir toutes les informations nécessaires tout en éliminant la redondance dans notre structure de données. + +=== "Après" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Maintenant, la closure renvoie un tuple où le premier élément contient les champs `id` et `repeat`, et le deuxième élément contient uniquement le champ `type`. Cela élimine la redondance en stockant les informations `id` et `repeat` une seule fois dans la clé de regroupement, tout en maintenant toutes les informations nécessaires. + +Exécutez le workflow pour voir à quoi cela ressemble : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Nous pouvons voir que nous ne déclarons les champs `id` et `repeat` qu'une seule fois dans la clé de regroupement et que nous avons le champ `type` dans les données d'échantillon. Nous n'avons perdu aucune information mais nous avons réussi à rendre le contenu de notre canal plus succinct. + +### 3.6. Supprimer les informations redondantes + +Nous avons supprimé les informations dupliquées ci-dessus, mais nous avons encore d'autres informations redondantes dans nos canaux. + +Au début, nous avons séparé les échantillons normaux et tumoraux en utilisant `filter`, puis nous les avons joints en fonction des clés `id` et `repeat`. L'opérateur `join` préserve l'ordre dans lequel les tuples sont fusionnés, donc dans notre cas, avec les échantillons normaux du côté gauche et les échantillons tumoraux du côté droit, le canal résultant maintient cette structure : `id, <éléments normaux>, <éléments tumoraux>`. + +Puisque nous connaissons la position de chaque élément dans notre canal, nous pouvons simplifier davantage la structure en supprimant les métadonnées `[type:normal]` et `[type:tumor]`. + +=== "Après" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Exécutez à nouveau pour voir le résultat : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Point clé + +Dans cette section, vous avez appris : + +- **Manipuler les tuples** : Comment utiliser `map` pour isoler un champ dans un tuple +- **Joindre les tuples** : Comment utiliser `join` pour combiner des tuples en fonction du premier champ +- **Créer des clés de jointure** : Comment utiliser `subMap` pour créer une nouvelle clé de jointure +- **Closures nommées** : Comment utiliser une closure nommée dans map +- **Jointure sur plusieurs champs** : Comment joindre sur plusieurs champs pour un appariement plus précis +- **Optimisation de la structure de données** : Comment rationaliser la structure du canal en supprimant les informations redondantes + +Vous disposez maintenant d'un workflow capable de diviser une feuille d'échantillons, filtrer les échantillons normaux et tumoraux, les joindre par identifiant d'échantillon et numéro de réplicat, puis afficher les résultats. + +Il s'agit d'un modèle courant dans les workflows de bioinformatique où vous devez apparier des échantillons ou d'autres types de données après un traitement indépendant, c'est donc une compétence utile. Ensuite, nous examinerons la répétition d'un échantillon plusieurs fois. + +## 4. Distribuer les échantillons sur des intervalles + +Un modèle clé dans les workflows de bioinformatique est la distribution de l'analyse sur des régions génomiques. Par exemple, l'appel de variants peut être parallélisé en divisant le génome en intervalles (comme des chromosomes ou des régions plus petites). Cette stratégie de parallélisation améliore considérablement l'efficacité du pipeline en distribuant la charge de calcul sur plusieurs cœurs ou nœuds, réduisant ainsi le temps d'exécution global. + +Dans la section suivante, nous démontrerons comment distribuer nos données d'échantillons sur plusieurs intervalles génomiques. Nous associerons chaque échantillon à chaque intervalle, permettant le traitement parallèle de différentes régions génomiques. Cela multipliera la taille de notre ensemble de données par le nombre d'intervalles, créant plusieurs unités d'analyse indépendantes qui pourront être rassemblées ultérieurement. + +### 4.1. Distribuer les échantillons sur des intervalles en utilisant `combine` + +Commençons par créer un canal d'intervalles. Pour simplifier les choses, nous utiliserons simplement 3 intervalles que nous définirons manuellement. Dans un vrai workflow, vous pourriez les lire à partir d'un fichier d'entrée ou même créer un canal avec de nombreux fichiers d'intervalles. + +=== "Après" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Maintenant, souvenez-vous, nous voulons répéter chaque échantillon pour chaque intervalle. Ceci est parfois appelé le produit cartésien des échantillons et des intervalles. Nous pouvons y parvenir en utilisant l'[opérateur `combine`](https://www.nextflow.io/docs/latest/operator.html#combine). Cela prendra chaque élément du canal 1 et le répétera pour chaque élément du canal 2. Ajoutons un opérateur combine à notre workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Maintenant, exécutons-le et voyons ce qui se passe : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Succès ! Nous avons répété chaque échantillon pour chaque intervalle de notre liste de 3 intervalles. Nous avons effectivement triplé le nombre d'éléments dans notre canal. + +C'est un peu difficile à lire cependant, donc dans la section suivante, nous allons le rendre plus clair. + +### 4.2. Organiser le canal + +Nous pouvons utiliser l'opérateur `map` pour ranger et refactoriser nos données d'échantillons afin qu'elles soient plus faciles à comprendre. Déplaçons la chaîne d'intervalles vers la map de jointure au premier élément. + +=== "Après" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Décomposons ce que fait cette opération map étape par étape. + +Tout d'abord, nous utilisons des paramètres nommés pour rendre le code plus lisible. En utilisant les noms `grouping_key`, `normal`, `tumor` et `interval`, nous pouvons faire référence aux éléments du tuple par nom au lieu de par index : + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Ensuite, nous combinons la `grouping_key` avec le champ `interval`. La `grouping_key` est une map contenant les champs `id` et `repeat`. Nous créons une nouvelle map avec l'`interval` et les fusionnons en utilisant l'addition de maps de Groovy (`+`) : + +```groovy + grouping_key + [interval: interval], +``` + +Enfin, nous retournons cela comme un tuple avec trois éléments : la map de métadonnées combinée, le fichier d'échantillon normal et le fichier d'échantillon tumoral : + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Exécutons-le à nouveau et vérifions le contenu du canal : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Utiliser `map` pour contraindre vos données dans la structure correcte peut être délicat, mais c'est crucial pour une manipulation efficace des données. + +Nous avons maintenant chaque échantillon répété sur tous les intervalles génomiques, créant plusieurs unités d'analyse indépendantes qui peuvent être traitées en parallèle. Mais que se passe-t-il si nous voulons rassembler des échantillons connexes ? Dans la section suivante, nous apprendrons comment regrouper des échantillons qui partagent des attributs communs. + +### Point clé + +Dans cette section, vous avez appris : + +- **Distribuer les échantillons sur des intervalles** : Comment utiliser `combine` pour répéter les échantillons sur des intervalles +- **Créer des produits cartésiens** : Comment générer toutes les combinaisons d'échantillons et d'intervalles +- **Organiser la structure du canal** : Comment utiliser `map` pour restructurer les données pour une meilleure lisibilité +- **Préparation au traitement parallèle** : Comment préparer les données pour une analyse distribuée + +## 5. Agréger des échantillons en utilisant `groupTuple` + +Dans les sections précédentes, nous avons appris comment diviser les données d'un fichier d'entrée et filtrer par des champs spécifiques (dans notre cas, les échantillons normaux et tumoraux). Mais cela ne couvre qu'un seul type de jointure. Et si nous voulons regrouper les échantillons par un attribut spécifique ? Par exemple, au lieu de joindre des paires appariées normal-tumeur, nous pourrions vouloir traiter tous les échantillons de "sampleA" ensemble indépendamment de leur type. Ce modèle est courant dans les workflows de bioin diff --git a/docs/fr/docs/side_quests/workflows_of_workflows.md b/docs/fr/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..9fd5b97ff0 --- /dev/null +++ b/docs/fr/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Workflows de workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Lorsque vous développez un pipeline, vous vous retrouvez souvent à créer des séquences similaires de processus pour différents types de données ou étapes d'analyse. Vous pourriez finir par copier et coller ces séquences de processus, ce qui conduit à du code dupliqué difficile à maintenir ; ou vous pourriez créer un workflow massif qui est difficile à comprendre et à modifier. + +L'une des fonctionnalités les plus puissantes de Nextflow est sa capacité à composer des pipelines complexes à partir de modules de workflow plus petits et réutilisables. Cette approche modulaire rend les pipelines plus faciles à développer, tester et maintenir. + +### Objectifs d'apprentissage + +Dans cette quête secondaire, nous explorerons comment développer des modules de workflow qui peuvent être testés et utilisés séparément, composer ces modules dans un pipeline plus large, et gérer le flux de données entre les modules. + +À la fin de cette quête secondaire, vous serez capable de : + +- Décomposer des pipelines complexes en unités logiques et réutilisables +- Tester chaque module de workflow indépendamment +- Mélanger et associer des workflows pour créer de nouveaux pipelines +- Partager des modules de workflow communs entre différents pipelines +- Rendre votre code plus maintenable et plus facile à comprendre + +Ces compétences vous aideront à construire des pipelines complexes tout en maintenant une structure de code claire et maintenable. + +### Prérequis + +Avant d'entreprendre cette quête secondaire, vous devriez : + +- Avoir complété le tutoriel [Hello Nextflow](../hello_nextflow/README.md) ou un cours équivalent pour débutants +- Être à l'aise avec l'utilisation des concepts et mécanismes de base de Nextflow (processus, canaux, opérateurs, modules) + +--- + +## 0. Pour commencer + +#### Ouvrir le codespace de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/workflows_of_workflows +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner le matériel + +Vous trouverez un répertoire `modules` contenant plusieurs définitions de processus qui s'appuient sur ce que vous avez appris dans 'Hello Nextflow' : + +```console title="Contenu du répertoire" +modules/ +├── say_hello.nf # Crée un message de bienvenue (de Hello Nextflow) +├── say_hello_upper.nf # Convertit en majuscules (de Hello Nextflow) +├── timestamp_greeting.nf # Ajoute des horodatages aux messages +├── validate_name.nf # Valide les noms en entrée +└── reverse_text.nf # Inverse le contenu du texte +``` + +#### Examiner l'exercice + +Votre défi est d'assembler ces modules en deux workflows séparés que nous composerons ensuite dans un workflow principal : + +- Un `GREETING_WORKFLOW` qui valide les noms, crée des messages de bienvenue et ajoute des horodatages +- Un `TRANSFORM_WORKFLOW` qui convertit le texte en majuscules et l'inverse + +#### Liste de vérification de préparation + +Pensez-vous être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon codespace est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +- [ ] Je comprends l'exercice + +Si vous pouvez cocher toutes les cases, vous êtes prêt à commencer. + +--- + +## 1. Créer le workflow de bienvenue + +Commençons par créer un workflow qui valide les noms et génère des messages de bienvenue horodatés. + +### 1.1. Créer la structure du workflow + +```bash title="Créer le répertoire et le fichier du workflow" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Ajouter le code du premier (sous-)workflow + +Ajoutez ce code à `workflows/greeting.nf` : + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Enchaîner les processus : valider -> créer message -> ajouter horodatage + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Il s'agit d'un workflow complet, avec une structure similaire à ceux que vous avez vus dans le tutoriel 'Hello Nextflow', que nous pouvons tester indépendamment. Essayons cela maintenant : + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Cela fonctionne comme prévu, mais pour le rendre composable, il y a quelques modifications à apporter. + +### 1.3. Rendre le workflow composable + +Les workflows composables présentent quelques différences par rapport à ceux que vous avez vus dans le tutoriel 'Hello Nextflow' : + +- Le bloc workflow doit être nommé +- Les entrées sont déclarées en utilisant le mot-clé `take:` +- Le contenu du workflow est placé à l'intérieur du bloc `main:` +- Les sorties sont déclarées en utilisant le mot-clé `emit:` + +Mettons à jour le workflow de bienvenue pour correspondre à cette structure. Modifiez le code comme suit : + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Canal d'entrée avec les noms + + main: + // Enchaîner les processus : valider -> créer message -> ajouter horodatage + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Messages originaux + timestamped = timestamped_ch // Messages horodatés +} +``` + +Vous pouvez voir que le workflow est maintenant nommé et possède un bloc `take:` et `emit:`, et ce sont les connexions que nous utiliserons pour composer un workflow de niveau supérieur. +Le contenu du workflow est également placé à l'intérieur du bloc `main:`. Notez également que nous avons supprimé la déclaration du canal d'entrée `names_ch`, car il est maintenant passé en argument au workflow. + +Testons à nouveau le workflow pour voir s'il fonctionne comme prévu : + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Cela vous informe d'un autre nouveau concept, un 'workflow d'entrée'. Le workflow d'entrée est le workflow qui est appelé lorsque vous exécutez un script Nextflow. Par défaut, Nextflow utilisera un workflow sans nom comme workflow d'entrée, lorsqu'il est présent, et c'est ce que vous avez fait jusqu'à présent, avec des blocs workflow commençant comme ceci : + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Mais notre workflow de bienvenue n'a pas de workflow sans nom, nous avons plutôt un workflow nommé : + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +C'est pourquoi Nextflow a généré une erreur et n'a pas fait ce que nous voulions. + +Nous n'avons pas ajouté la syntaxe `take:`/`emit:` pour pouvoir appeler le workflow directement - nous l'avons fait pour pouvoir le composer avec d'autres workflows. La solution est de créer un script principal avec un workflow d'entrée sans nom qui importe et appelle notre workflow nommé. + +### 1.4. Créer et tester le workflow principal + +Nous allons maintenant créer un workflow principal qui importe et utilise le workflow `greeting`. + +Créez `main.nf` : + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Notez que notre entrée de workflow dans ce fichier est sans nom, et c'est parce que nous allons l'utiliser comme workflow d'entrée. + +Exécutez ceci et observez la sortie : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Ça fonctionne ! Nous avons enveloppé le workflow de bienvenue nommé dans un workflow principal avec un bloc `workflow` d'entrée sans nom. Le workflow principal utilise le workflow `GREETING_WORKFLOW` presque (mais pas tout à fait) comme un processus, et passe le canal `names` en argument. + +### À retenir + +Dans cette section, vous avez appris plusieurs concepts importants : + +- **Workflows nommés** : Créer un workflow nommé (`GREETING_WORKFLOW`) qui peut être importé et réutilisé +- **Interfaces de workflow** : Définir des entrées claires avec `take:` et des sorties avec `emit:` pour créer un workflow composable +- **Points d'entrée** : Comprendre que Nextflow a besoin d'un workflow d'entrée sans nom pour exécuter un script +- **Composition de workflows** : Importer et utiliser un workflow nommé dans un autre workflow +- **Espaces de noms de workflow** : Accéder aux sorties de workflow en utilisant l'espace de noms `.out` (`GREETING_WORKFLOW.out.greetings`) + +Vous avez maintenant un workflow de bienvenue fonctionnel qui : + +- Prend un canal de noms en entrée +- Valide chaque nom +- Crée un message de bienvenue pour chaque nom valide +- Ajoute des horodatages aux messages +- Expose à la fois les messages originaux et horodatés comme sorties + +Cette approche modulaire vous permet de tester le workflow de bienvenue indépendamment ou de l'utiliser comme composant dans des pipelines plus grands. + +--- + +## 2. Ajouter le workflow de transformation + +Créons maintenant un workflow qui applique des transformations de texte aux messages de bienvenue. + +### 2.1. Créer le fichier du workflow + +```bash +touch workflows/transform.nf +``` + +### 2.2. Ajouter le code du workflow + +Ajoutez ce code à `workflows/transform.nf` : + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Canal d'entrée avec les messages + + main: + // Appliquer les transformations en séquence + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Messages en majuscules + reversed = reversed_ch // Messages en majuscules inversés +} +``` + +Nous ne répéterons pas l'explication de la syntaxe composable ici, mais notez que le workflow nommé est à nouveau déclaré avec un bloc `take:` et `emit:`, et le contenu du workflow est placé à l'intérieur du bloc `main:`. + +### 2.3. Mettre à jour le workflow principal + +Mettez à jour `main.nf` pour utiliser les deux workflows : + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Exécuter le workflow de bienvenue + GREETING_WORKFLOW(names) + + // Exécuter le workflow de transformation + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Afficher les résultats + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Exécutez le pipeline complet : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Si vous examinez l'un de ces fichiers inversés, vous verrez qu'il s'agit de la version en majuscules du message inversé : + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Contenu du fichier inversé" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### À retenir + +Vous devriez maintenant avoir un pipeline complet qui : + +- Traite les noms à travers le workflow de bienvenue +- Alimente les messages horodatés dans le workflow de transformation +- Produit à la fois les versions en majuscules et inversées des messages + +--- + +## Résumé + +Dans cette quête secondaire, nous avons exploré le concept puissant de composition de workflows dans Nextflow, qui nous permet de construire des pipelines complexes à partir de composants plus petits et réutilisables. + +Cette approche modulaire offre plusieurs avantages par rapport aux pipelines monolithiques : + +- Chaque workflow peut être développé, testé et débogué indépendamment +- Les workflows peuvent être réutilisés dans différents pipelines +- La structure globale du pipeline devient plus lisible et maintenable +- Les modifications apportées à un workflow n'affectent pas nécessairement les autres si les interfaces restent cohérentes +- Les points d'entrée peuvent être configurés pour exécuter différentes parties de votre pipeline selon les besoins + +_Il est important de noter cependant que, bien que l'appel de workflows ressemble un peu à l'appel de processus, ce n'est pas réellement la même chose. Vous ne pouvez pas, par exemple, exécuter un workflow N fois en l'appelant avec un canal de taille N - vous devriez passer un canal de taille N au workflow et itérer en interne._ + +L'application de ces techniques dans votre propre travail vous permettra de construire des pipelines Nextflow plus sophistiqués capables de gérer des tâches bioinformatiques complexes tout en restant maintenables et évolutifs. + +### Modèles clés + +1. **Structure de workflow** : Nous avons défini des entrées et sorties claires pour chaque workflow en utilisant la syntaxe `take:` et `emit:`, créant des interfaces bien définies entre les composants, et enveloppé la logique du workflow dans le bloc `main:`. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Les canaux d'entrée sont déclarés ici + input_ch + + main: + // La logique du workflow va ici + // C'est ici que les processus sont appelés et les canaux manipulés + result_ch = SOME_PROCESS(input_ch) + + emit: + // Les canaux de sortie sont déclarés ici + output_ch = result_ch + } + ``` + +2. **Imports de workflow :** Nous avons construit deux modules de workflow indépendants et les avons importés dans un pipeline principal avec des instructions include. + + - Inclure un seul workflow + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Inclure plusieurs workflows + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Inclure avec un alias pour éviter les conflits de noms + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Points d'entrée** : Nextflow nécessite un workflow d'entrée sans nom pour savoir où commencer l'exécution. Ce workflow d'entrée appelle vos workflows nommés. + + - Workflow sans nom (point d'entrée) + + ```groovy + workflow { + // Ceci est le point d'entrée lorsque le script est exécuté + NAMED_WORKFLOW(input_ch) + } + ``` + + - Workflow nommé (appelé depuis le workflow d'entrée) + + ```groovy + workflow NAMED_WORKFLOW { + // Doit être appelé depuis le workflow d'entrée + } + ``` + +4. **Gestion du flux de données :** Nous avons appris comment accéder aux sorties de workflow en utilisant la notation d'espace de noms (`WORKFLOW_NAME.out.channel_name`) et les passer à d'autres workflows. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Ressources supplémentaires + +- [Documentation Nextflow sur les workflows](https://www.nextflow.io/docs/latest/workflow.html) +- [Référence des opérateurs de canaux](https://www.nextflow.io/docs/latest/operator.html) +- [Documentation sur la stratégie d'erreur](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## Et ensuite ? + +Retournez au [menu des Quêtes secondaires](./index.md) ou cliquez sur le bouton en bas à droite de la page pour passer au sujet suivant dans la liste. diff --git a/docs/fr/docs/side_quests/working_with_files.md b/docs/fr/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..e572a24192 --- /dev/null +++ b/docs/fr/docs/side_quests/working_with_files.md @@ -0,0 +1,1227 @@ +# Traitement des fichiers en entrée + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Les flux de travail d'analyse scientifique impliquent souvent le traitement d'un grand nombre de fichiers. +Nextflow fournit des outils puissants pour gérer les fichiers efficacement, vous aidant à organiser et traiter vos données avec un minimum de code. + +### Objectifs d'apprentissage + +Dans cette quête secondaire, nous allons explorer comment Nextflow gère les fichiers, des opérations de base aux techniques plus avancées pour travailler avec des collections de fichiers. +Vous apprendrez à extraire des métadonnées à partir de noms de fichiers, ce qui est une exigence courante dans les pipelines d'analyse scientifique. + +À la fin de cette quête secondaire, vous serez capable de : + +- Créer des objets Path à partir de chaînes de caractères représentant des chemins de fichiers en utilisant la méthode `file()` de Nextflow +- Accéder aux attributs de fichiers tels que le nom, l'extension et le répertoire parent +- Gérer de manière transparente les fichiers locaux et distants en utilisant des URI +- Utiliser les canaux pour automatiser la gestion des fichiers avec `channel.fromPath()` et `channel.fromFilePairs()` +- Extraire et structurer les métadonnées à partir de noms de fichiers en utilisant la manipulation de chaînes +- Grouper les fichiers associés en utilisant la correspondance de motifs et les expressions glob +- Intégrer les opérations sur fichiers dans les processus Nextflow avec une gestion appropriée des entrées +- Organiser les sorties de processus en utilisant des structures de répertoires pilotées par les métadonnées + +Ces compétences vous aideront à construire des flux de travail capables de gérer différents types d'entrées de fichiers avec une grande flexibilité. + +### Prérequis + +Avant d'entreprendre cette quête secondaire, vous devriez : + +- Avoir terminé le tutoriel [Hello Nextflow](../../hello_nextflow/) ou un cours équivalent pour débutants. +- Être à l'aise avec l'utilisation des concepts et mécanismes de base de Nextflow (processus, canaux, opérateurs) + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. Démarrage + +#### Ouvrir l'espace de code de formation + +Si vous ne l'avez pas encore fait, assurez-vous d'ouvrir l'environnement de formation comme décrit dans la [Configuration de l'Environnement](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Se déplacer dans le répertoire du projet + +Déplaçons-nous dans le répertoire où se trouvent les fichiers pour ce tutoriel. + +```bash +cd side-quests/working_with_files +``` + +Vous pouvez configurer VSCode pour se concentrer sur ce répertoire : + +```bash +code . +``` + +#### Examiner les matériaux + +Vous trouverez un fichier de flux de travail simple appelé `main.nf`, un répertoire `modules` contenant deux fichiers de modules, et un répertoire `data` contenant quelques fichiers de données d'exemple. + +??? abstract "Contenu du répertoire" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Ce répertoire contient des données de séquençage en paires provenant de trois patients (A, B, C). + +Pour chaque patient, nous avons des échantillons de type `tumor` (provenant généralement de biopsies tumorales) ou `normal` (prélevés sur des tissus sains ou du sang). +Si vous n'êtes pas familier avec l'analyse du cancer, sachez simplement que cela correspond à un modèle expérimental qui utilise des échantillons appariés tumeur/normal pour effectuer des analyses contrastives. + +Pour le patient A spécifiquement, nous avons deux ensembles de réplicats techniques (répétitions). + +Les fichiers de données de séquençage sont nommés avec une convention typique `_R1_` et `_R2_` pour ce qu'on appelle les 'lectures avant' et 'lectures arrière'. + +_Ne vous inquiétez pas si vous n'êtes pas familier avec ce plan expérimental, ce n'est pas critique pour comprendre ce tutoriel._ + +#### Examiner l'exercice + +Votre défi est d'écrire un flux de travail Nextflow qui va : + +1. **Charger** les fichiers d'entrée en utilisant les méthodes de gestion de fichiers de Nextflow +2. **Extraire** les métadonnées (ID patient, réplicat, type d'échantillon) de la structure du nom de fichier +3. **Grouper** les fichiers appariés (R1/R2) ensemble en utilisant `channel.fromFilePairs()` +4. **Traiter** les fichiers avec un module d'analyse fourni +5. **Organiser** les sorties dans une structure de répertoires basée sur les métadonnées extraites + +#### Liste de vérification de préparation + +Vous pensez être prêt à vous lancer ? + +- [ ] Je comprends l'objectif de ce cours et ses prérequis +- [ ] Mon espace de code est opérationnel +- [ ] J'ai défini mon répertoire de travail de manière appropriée +- [ ] Je comprends l'exercice + +Si vous pouvez cocher toutes les cases, vous êtes prêt. + +--- + +## 1. Opérations de base sur les fichiers + +### 1.1. Identifier le type d'un objet avec `.class` + +Regardez le fichier de flux de travail `main.nf` : + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Crée un objet Path à partir d'une chaîne de chemin + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +Il s'agit d'un mini-flux de travail (sans processus) qui fait référence à un seul chemin de fichier dans son workflow, puis l'imprime dans la console, avec sa classe. + +??? info "Qu'est-ce que `.class` ?" + + Dans Nextflow, `.class` nous indique quel type d'objet nous manipulons. C'est comme demander "quel genre de chose est-ce ?" pour savoir s'il s'agit d'une chaîne de caractères, d'un nombre, d'un fichier ou d'autre chose. + Cela nous aidera à illustrer la différence entre une simple chaîne de caractères et un objet Path dans les sections suivantes. + +Exécutons le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Comme vous pouvez le voir, Nextflow a imprimé le chemin sous forme de chaîne exactement comme nous l'avons écrit. + +Il s'agit simplement d'une sortie texte ; Nextflow n'a encore rien fait de spécial avec. +Nous avons également confirmé qu'en ce qui concerne Nextflow, il s'agit seulement d'une chaîne (de classe `java.lang.String`). +Cela a du sens, puisque nous n'avons pas encore indiqué à Nextflow qu'il correspond à un fichier. + +### 1.2. Créer un objet Path avec file() + +Nous pouvons indiquer à Nextflow comment gérer les fichiers en créant des [objets Path](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) à partir de chaînes de chemins. + +Dans notre flux de travail, nous pouvons convertir le chemin sous forme de chaîne `data/patientA_rep1_normal_R1_001.fastq.gz` en objet Path en utilisant la méthode `file()`, qui donne accès aux propriétés et opérations sur les fichiers. + +Modifiez le fichier `main.nf` pour envelopper la chaîne avec `file()` comme suit : + +=== "Après" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Maintenant, exécutez à nouveau le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Cette fois, vous voyez le chemin absolu complet au lieu du chemin relatif que nous avons fourni en entrée. + +Nextflow a converti notre chaîne en objet Path et l'a résolu vers l'emplacement réel du fichier sur le système. +Le chemin du fichier sera maintenant absolu, comme dans `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Notez également que la classe de l'objet Path est `sun.nio.fs.UnixPath` : c'est la façon dont Nextflow représente les fichiers locaux. +Comme nous le verrons plus tard, les fichiers distants auront des noms de classe différents (comme `nextflow.file.http.XPath` pour les fichiers HTTP), mais ils fonctionnent tous exactement de la même manière et peuvent être utilisés de manière identique dans vos flux de travail. + +!!! tip + + **La différence clé :** + + - **Chaîne de chemin** : Juste du texte que Nextflow traite comme des caractères + - **Objet Path** : Une référence de fichier intelligente avec laquelle Nextflow peut travailler + + Pensez-y ainsi : une chaîne de chemin est comme écrire une adresse sur papier, tandis qu'un objet Path est comme avoir l'adresse chargée dans un appareil GPS qui sait comment naviguer jusqu'à là et peut vous donner des détails sur le trajet. + +### 1.3. Accéder aux attributs de fichier + +Pourquoi est-ce utile ? Eh bien, maintenant que Nextflow comprend que `myFile` est un objet Path et pas seulement une chaîne, nous pouvons accéder aux différents attributs de l'objet Path. + +Mettons à jour notre flux de travail pour imprimer les attributs de fichier intégrés : + +=== "Après" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Vous voyez les différents attributs de fichier imprimés dans la console ci-dessus. + +### 1.4. Fournir le fichier à un processus + +La différence entre les chaînes et les objets Path devient critique lorsque vous commencez à construire des flux de travail réels avec des processus. +Jusqu'à présent, nous avons vérifié que Nextflow traite maintenant notre fichier d'entrée comme un fichier, mais voyons si nous pouvons réellement exécuter quelque chose sur ce fichier dans un processus. + +#### 1.4.1. Importer le processus et examiner le code + +Nous vous fournissons un module de processus pré-écrit appelé `COUNT_LINES` qui prend un fichier en entrée et compte combien de lignes il contient. + +Pour utiliser le processus dans le flux de travail, vous devez simplement ajouter une instruction include avant le bloc workflow : + +=== "Après" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Vous pouvez ouvrir le fichier de module pour examiner son code : + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Comme vous pouvez le voir, c'est un petit script assez simple qui décompresse le fichier et compte combien de lignes il contient. + +??? info "Que fait `debug true` ?" + + La directive `debug true` dans la définition du processus fait en sorte que Nextflow imprime la sortie de votre script (comme le nombre de lignes "40") directement dans le journal d'exécution. + Sans cela, vous ne verriez que le statut d'exécution du processus mais pas la sortie réelle de votre script. + + Pour plus d'informations sur le débogage des flux de travail Nextflow, consultez la quête secondaire [Débogage des Flux de Travail Nextflow](debugging.md). + +#### 1.4.2. Ajouter un appel à `COUNT_LINES` + +Maintenant que le processus est disponible pour le flux de travail, nous pouvons ajouter un appel au processus `COUNT_LINES` pour l'exécuter sur le fichier d'entrée. + +Effectuez les modifications suivantes dans le flux de travail : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Compte les lignes dans le fichier + COUNT_LINES(myFile) + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Et maintenant exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Cela montre que nous sommes capables d'opérer sur le fichier de manière appropriée à l'intérieur d'un processus. + +Plus précisément, Nextflow a effectué avec succès les opérations suivantes : + +- Mis en place le fichier dans le répertoire de travail +- Décompressé le fichier .gz +- Compté les lignes (40 lignes dans ce cas) +- Terminé sans erreur + +La clé de cette opération fluide est que nous indiquons explicitement à Nextflow que notre entrée est un fichier et doit être traitée comme telle. + +### 1.5. Dépanner les erreurs de base sur les entrées de fichiers + +Cela déroute souvent les nouveaux venus à Nextflow, alors prenons quelques minutes pour examiner ce qui se passe lorsque vous le faites mal. + +Il y a deux endroits principaux où vous pouvez vous tromper dans la gestion des fichiers : au niveau du flux de travail et au niveau du processus. + +#### 1.5.1. Erreur au niveau du flux de travail + +Voyons ce qui se passe si nous revenons à traiter le fichier comme une chaîne lorsque nous spécifions l'entrée dans le bloc workflow. + +Effectuez les modifications suivantes dans le flux de travail, en veillant à commenter les instructions d'impression spécifiques aux chemins : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Compte les lignes dans le fichier + COUNT_LINES(myFile) + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Compte les lignes dans le fichier + COUNT_LINES(myFile) + ``` + +Et maintenant exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Voici la partie importante : + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Lorsque vous spécifiez une entrée `path`, Nextflow valide que vous passez des références de fichiers réelles, pas seulement des chaînes. +Cette erreur vous indique que `'data/patientA_rep1_normal_R1_001.fastq.gz'` n'est pas une valeur de chemin valide car c'est une chaîne, pas un objet Path. + +Nextflow a immédiatement détecté le problème et s'est arrêté avant même de démarrer le processus. + +#### 1.5.2. Erreur au niveau du processus + +L'autre endroit où nous pourrions oublier de spécifier que nous voulons que Nextflow traite l'entrée comme un fichier est dans la définition du processus. + +!!! warning "Conservez l'erreur du flux de travail de 1.5.1" + + Pour que ce test fonctionne correctement, conservez le flux de travail dans son état défaillant (utilisant une simple chaîne au lieu de `file()`). + Lorsqu'il est combiné avec `val` dans le processus, cela produit l'erreur montrée ci-dessous. + +Effectuez la modification suivante dans le module : + +=== "Après" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Avant" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +Et maintenant exécutez à nouveau le flux de travail : + +```bash +nextflow run main.nf +``` + +??? failure "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Cela montre beaucoup de détails sur l'erreur car le processus est configuré pour afficher des informations de débogage, comme indiqué précédemment. + +Voici les sections les plus pertinentes : + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Cela indique que le système n'a pas pu trouver le fichier ; cependant, si vous regardez le chemin, il y a bien un fichier avec ce nom à cet emplacement. + +Lorsque nous avons exécuté cela, Nextflow a transmis la valeur de chaîne au script, mais il n'a pas _mis en place_ le fichier réel dans le répertoire de travail. +Ainsi, le processus a essayé d'utiliser la chaîne relative, `data/patientA_rep1_normal_R1_001.fastq.gz`, mais ce fichier n'existe pas dans le répertoire de travail du processus. + +Pris ensemble, ces deux exemples vous montrent à quel point il est important d'indiquer à Nextflow si une entrée doit être gérée comme un fichier. + +!!! note + + Assurez-vous de revenir en arrière et de corriger les deux erreurs intentionnelles avant de continuer à la section suivante. + +### Enseignements clés + +- Chaînes de chemin vs objets Path : Les chaînes sont juste du texte, les objets Path sont des références de fichiers intelligentes +- La méthode `file()` convertit un chemin sous forme de chaîne en objet Path avec lequel Nextflow peut travailler +- Vous pouvez accéder aux propriétés de fichier comme `name`, `simpleName`, `extension` et `parent` [en utilisant les attributs de fichier](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) +- L'utilisation d'objets Path au lieu de chaînes permet à Nextflow de gérer correctement les fichiers dans votre flux de travail +- Résultats des entrées de processus : Une gestion appropriée des fichiers nécessite des objets Path, et non des chaînes, pour garantir que les fichiers sont correctement mis en place et accessibles pour être utilisés par les processus. + +--- + +## 2. Utilisation de fichiers distants + +L'une des fonctionnalités clés de Nextflow est la capacité de basculer de manière transparente entre les fichiers locaux (sur la même machine) et les fichiers distants accessibles via Internet. + +Si vous le faites correctement, vous ne devriez jamais avoir besoin de modifier la logique de votre flux de travail pour accommoder des fichiers provenant de différents emplacements. +Tout ce que vous devez faire pour utiliser un fichier distant est de spécifier le préfixe approprié dans le chemin du fichier lorsque vous le fournissez au flux de travail. + +Par exemple, `/path/to/data` n'a pas de préfixe, indiquant qu'il s'agit d'un chemin de fichier local 'normal', alors que `s3://path/to/data` inclut le préfixe `s3://`, indiquant qu'il est situé dans le stockage d'objets S3 d'Amazon. + +De nombreux protocoles différents sont pris en charge : + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Pour utiliser l'un de ces protocoles, spécifiez simplement le préfixe pertinent dans la chaîne, qui est alors techniquement appelée Uniform Resource Identifier (URI) au lieu de chemin de fichier. +Nextflow gérera l'authentification et la mise en place des fichiers au bon endroit, le téléchargement ou le chargement et toutes les autres opérations sur fichiers auxquelles vous vous attendez. + +La force principale de ce système est qu'il nous permet de basculer entre les environnements sans modifier aucune logique de pipeline. +Par exemple, vous pouvez développer avec un petit ensemble de tests local avant de passer à un ensemble de tests à grande échelle situé dans un stockage distant simplement en changeant l'URI. + +### 2.1. Utiliser un fichier depuis Internet + +Testons cela en remplaçant le chemin local que nous fournissons à notre flux de travail par un chemin HTTPS pointant vers une copie des mêmes données stockées dans Github. + +!!! warning + + Cela ne fonctionnera que si vous avez une connexion Internet active. + +Ouvrez à nouveau `main.nf` et modifiez le chemin d'entrée comme suit : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Utilise un fichier distant depuis Internet + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Exécutons le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ça marche ! Vous pouvez voir que très peu de choses ont changé. + +La seule différence dans la sortie de la console est que la classe de l'objet path est maintenant `nextflow.file.http.XPath`, alors que pour le chemin local la classe était `sun.nio.fs.UnixPath`. +Vous n'avez pas besoin de mémoriser ces classes ; nous mentionnons simplement cela pour démontrer que Nextflow identifie et gère les différents emplacements de manière appropriée. + +En coulisses, Nextflow a téléchargé le fichier dans un répertoire de mise en place situé dans le répertoire de travail. +Ce fichier mis en place peut ensuite être traité comme un fichier local et créé en lien symbolique dans le répertoire de processus pertinent. + +Vous pouvez vérifier que cela s'est produit ici en regardant le contenu du répertoire de travail situé à la valeur de hachage du processus. + +??? abstract "Contenu du répertoire de travail" + + Si le hachage du processus était `8a/2ab7ca`, vous pourriez explorer le répertoire de travail : + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Le lien symbolique pointe vers une copie mise en place du fichier distant que Nextflow a téléchargé automatiquement. + +Notez que pour les fichiers plus volumineux, l'étape de téléchargement prendra du temps supplémentaire par rapport à l'exécution sur des fichiers locaux. +Cependant, Nextflow vérifie s'il a déjà une copie mise en place pour éviter les téléchargements inutiles. +Donc, si vous réexécutez sur le même fichier et que vous n'avez pas supprimé le fichier mis en place, Nextflow utilisera la copie mise en place. + +Cela montre à quel point il est facile de basculer entre les données locales et distantes en utilisant Nextflow, ce qui est une fonctionnalité clé de Nextflow. + +!!! note + + La seule exception importante à ce principe est que vous ne pouvez pas utiliser de motifs glob ou de chemins de répertoires avec HTTPS car HTTPS ne peut pas lister plusieurs fichiers, vous devez donc spécifier des URL de fichiers exactes. + Cependant, d'autres protocoles de stockage tels que le stockage blob (`s3://`, `az://`, `gs://`) peuvent utiliser à la fois des globs et des chemins de répertoires. + + Voici comment vous pourriez utiliser des motifs glob avec le stockage cloud : + + ```groovy title="Exemples de stockage cloud (non exécutables dans cet environnement)" + // S3 avec motifs glob - correspondrait à plusieurs fichiers + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage avec motifs glob + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage avec motifs glob + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Nous vous montrerons comment travailler avec des globs dans la pratique dans la section suivante. + +### 2.2. Revenir au fichier local + +Nous allons revenir à l'utilisation de nos fichiers d'exemple locaux pour le reste de cette quête secondaire, alors remettons l'entrée du flux de travail sur le fichier d'origine : + +=== "Après" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Enseignements clés + +- Les données distantes sont accessibles en utilisant un URI (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow téléchargera et mettra en place automatiquement les données au bon endroit, tant que ces chemins sont fournis aux processus +- N'écrivez pas de logique pour télécharger ou charger des fichiers distants ! +- Les fichiers locaux et distants produisent différents types d'objets mais fonctionnent de manière identique +- **Important** : HTTP/HTTPS fonctionne uniquement avec des fichiers uniques (pas de motifs glob) +- Le stockage cloud (S3, Azure, GCS) prend en charge à la fois les fichiers uniques et les motifs glob +- Vous pouvez basculer de manière transparente entre les sources de données locales et distantes sans modifier la logique du code (tant que le protocole prend en charge vos opérations requises) + +--- + +## 3. Utilisation de la fabrique de canal `fromPath()` + +Jusqu'à présent, nous avons travaillé avec un seul fichier à la fois, mais dans Nextflow, nous allons généralement vouloir créer un canal d'entrée avec plusieurs fichiers d'entrée à traiter. + +Une façon naïve de le faire serait de combiner la méthode `file()` avec [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) comme ceci : + +```groovy title="Exemple de syntaxe" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Cela fonctionne, mais c'est maladroit. + +!!! tip "Quand utiliser `file()` vs `channel.fromPath()`" + + - Utilisez `file()` lorsque vous avez besoin d'un seul objet Path pour une manipulation directe (vérifier si un fichier existe, lire ses attributs, ou le passer à un seul appel de processus) + - Utilisez `channel.fromPath()` lorsque vous avez besoin d'un canal pouvant contenir plusieurs fichiers, surtout avec des motifs glob, ou lorsque les fichiers vont circuler à travers plusieurs processus + +C'est là qu'intervient [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) : une fabrique de canal pratique qui regroupe toutes les fonctionnalités dont nous avons besoin pour générer un canal à partir d'une ou plusieurs chaînes de fichiers statiques ainsi que de motifs glob. + +### 3.1. Ajouter la fabrique de canal + +Mettons à jour notre flux de travail pour utiliser `channel.fromPath`. + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Affiche les attributs du fichier + /* Comment these out for now, we'll come back to them! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Compte les lignes dans le fichier + // COUNT_LINES(myFile) + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Crée un objet Path à partir d'une chaîne de chemin + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Affiche les attributs du fichier + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Compte les lignes dans le fichier + COUNT_LINES(myFile) + ``` + +Nous avons également commenté le code qui imprime les attributs pour le moment, et ajouté une instruction `.view` pour imprimer juste le nom de fichier à la place. + +Exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Comme vous pouvez le voir, le chemin du fichier est chargé en tant qu'objet de type `Path` dans le canal. +C'est similaire à ce qu'aurait fait `file()`, sauf que maintenant nous avons un canal dans lequel nous pouvons charger plus de fichiers si nous le souhaitons. + +L'utilisation de `channel.fromPath()` est un moyen pratique de créer un nouveau canal peuplé par une liste de fichiers. + +### 3.2. Voir les attributs des fichiers dans le canal + +Dans notre première utilisation de la fabrique de canal, nous avons simplifié le code et imprimé simplement le nom de fichier. + +Revenons à l'impression des attributs de fichier complets : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Compte les lignes dans le fichier + COUNT_LINES(ch_files) + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Compte les lignes dans le fichier + // COUNT_LINES(ch_files) + ``` + +Nous réactivons également l'appel au processus `COUNT_LINES` pour vérifier que le traitement des fichiers fonctionne toujours correctement avec notre approche basée sur les canaux. + +Exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Et voilà, mêmes résultats qu'avant mais maintenant nous avons le fichier dans un canal, donc nous pouvons en ajouter plus. + +### 3.3. Utiliser un glob pour correspondre à plusieurs fichiers + +Il y a plusieurs façons de charger plus de fichiers dans le canal. +Ici, nous allons vous montrer comment utiliser des motifs glob, qui sont un moyen pratique de faire correspondre et récupérer des noms de fichiers et de répertoires basés sur des caractères génériques. +Le processus de correspondance de ces motifs est appelé "globbing" ou "expansion de nom de fichier". + +!!! note + + Comme indiqué précédemment, Nextflow prend en charge le globbing pour gérer les fichiers d'entrée et de sortie dans la majorité des cas, sauf avec les chemins de fichiers HTTPS car HTTPS ne peut pas lister plusieurs fichiers. + +Disons que nous voulons récupérer les deux fichiers d'une paire de fichiers associés à un patient donné, `patientA` : + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Puisque la seule différence entre les noms de fichiers est le numéro de réplicat, _c'est-à-dire_ le numéro après `R`, nous pouvons utiliser le caractère générique `*` pour représenter le numéro comme suit : + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +C'est le motif glob dont nous avons besoin. + +Maintenant, tout ce que nous devons faire est de mettre à jour le chemin de fichier dans la fabrique de canal pour utiliser ce motif glob comme suit : + +=== "Après" + + ```groovy title="main.nf" linenums="7" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow reconnaîtra automatiquement qu'il s'agit d'un motif glob et le gérera de manière appropriée. + +Exécutez le flux de travail pour tester cela : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Comme vous pouvez le voir, nous avons maintenant deux objets Path dans notre canal, ce qui montre que Nextflow a effectué l'expansion de nom de fichier correctement et a chargé et traité les deux fichiers comme prévu. + +En utilisant cette méthode, nous pouvons récupérer autant ou aussi peu de fichiers que nous le souhaitons simplement en changeant le motif glob. Si nous le rendions plus généreux, par exemple en remplaçant toutes les parties variables des noms de fichiers par `*` (_par exemple_ `data/patient*_rep*_*_R*_001.fastq.gz`), nous pourrions récupérer tous les fichiers d'exemple dans le répertoire `data`. + +### Enseignements clés + +- `channel.fromPath()` crée un canal avec des fichiers correspondant à un motif +- Chaque fichier est émis en tant qu'élément séparé dans le canal +- Nous pouvons utiliser un motif glob pour correspondre à plusieurs fichiers +- Les fichiers sont automatiquement convertis en objets Path avec des attributs complets +- La méthode `.view()` permet l'inspection du contenu du canal + +--- + +## 4. Extraction de métadonnées de base à partir de noms de fichiers + +Dans la plupart des domaines scientifiques, il est très courant d'avoir des métadonnées encodées dans les noms des fichiers qui contiennent les données. +Par exemple, en bio-informatique, les fichiers contenant des données de séquençage sont souvent nommés de manière à encoder des informations sur l'échantillon, la condition, le réplicat et le numéro de lecture. + +Si les noms de fichiers sont construits selon une convention cohérente, vous pouvez extraire ces métadonnées de manière standardisée et les utiliser dans le cours de votre analyse. +C'est un grand 'si', bien sûr, et vous devriez être très prudent chaque fois que vous vous fiez à la structure des noms de fichiers ; mais la réalité est que cette approche est très largement utilisée, alors jetons un œil à comment cela se fait dans Nextflow. + +Dans le cas de nos données d'exemple, nous savons que les noms de fichiers incluent des métadonnées structurées de manière cohérente. +Par exemple, le nom de fichier `patientA_rep1_normal_R2_001` encode ce qui suit : + +- ID patient : `patientA` +- ID réplicat : `rep1` +- type d'échantillon : `normal` (par opposition à `tumor`) +- ensemble de lectures : `R1` (par opposition à `R2`) + +Nous allons modifier notre flux de travail pour récupérer ces informations en trois étapes : + +1. Récupérer le `simpleName` du fichier, qui inclut les métadonnées +2. Séparer les métadonnées en utilisant une méthode appelée `tokenize()` +3. Utiliser une map pour organiser les métadonnées + +!!! warning + + Vous ne devriez jamais encoder d'informations sensibles dans les noms de fichiers, telles que les noms de patients ou d'autres caractéristiques d'identification, car cela peut compromettre la confidentialité des patients ou d'autres restrictions de sécurité pertinentes. + +### 4.1. Récupérer le `simpleName` + +Le `simpleName` est un attribut de fichier qui correspond au nom de fichier dépouillé de son chemin et de son extension. + +Effectuez les modifications suivantes dans le flux de travail : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +Cela récupère le `simpleName` et l'associe à l'objet fichier complet en utilisant une opération `map()`. + +Exécutez le flux de travail pour tester qu'il fonctionne : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Chaque élément dans le canal est maintenant un tuple contenant le `simpleName` et l'objet fichier d'origine. + +### 4.2. Extraire les métadonnées du `simplename` + +À ce stade, les métadonnées que nous voulons sont intégrées dans le `simplename`, mais nous ne pouvons pas accéder directement aux éléments individuels. +Nous devons donc diviser le `simplename` en ses composants. +Heureusement, ces composants sont simplement séparés par des traits de soulignement dans le nom de fichier d'origine, nous pouvons donc appliquer une méthode Nextflow courante appelée `tokenize()` qui est parfaite pour cette tâche. + +Effectuez les modifications suivantes dans le flux de travail : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Avant" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +La méthode `tokenize()` divisera la chaîne `simpleName` partout où elle trouve des traits de soulignement, et retournera une liste contenant les sous-chaînes. + +Exécutez le flux de travail : + +```bash +nextflow run main.nf +``` + +??? success "Sortie de la commande" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Maintenant le tuple pour chaque élément dans notre canal contient la liste de métadonnées (_par exemple_ `[patientA, rep1, normal, R1, 001]`) et l'objet fichier d'origine. + +C'est génial ! +Nous avons décomposé les informations de notre patient d'une seule chaîne en une liste de chaînes. +Nous pouvons maintenant gérer chaque partie de l'information du patient séparément. + +### 4.3. Utiliser une map pour organiser les métadonnées + +Nos métadonnées ne sont qu'une liste plate pour le moment. +Elle est assez facile à utiliser mais difficile à lire. + +```console +[patientA, rep1, normal, R1, 001] +``` + +Quel est l'élément à l'index 3 ? Pouvez-vous le dire sans vous référer à l'explication originale de la structure des métadonnées ? + +C'est une excellente opportunité d'utiliser un stockage clé-valeur, où chaque élément a un ensemble de clés et leurs valeurs associées, vous pouvez donc facilement vous référer à chaque clé pour obtenir la valeur correspondante. + +Dans notre exemple, cela signifie passer de cette organisation : + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +À celle-ci : + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +Dans Nextflow, cela s'appelle une [map](https://nextflow.io/docs/latest/script.html#maps). + +Convertissons maintenant notre liste plate en map. +Effectuez les modifications suivantes dans le flux de travail : + +=== "Après" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // Charge les fichiers avec channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== diff --git a/docs/fr/docs/training_collections/architects_toolkit_1.md b/docs/fr/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..83c4727da9 --- /dev/null +++ b/docs/fr/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: La Boîte à Outils de l'Architecte I +hide: + - toc +--- + +# La Boîte à Outils de l'Architecte I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nos Collections de Formation proposent des parcours d'apprentissage organisés à travers nos supports de formation avancés (appelés [Side Quests](../../side_quests)). Cette collection couvre quatre sujets essentiels qui sont fréquemment utilisés ensemble pour construire des workflows robustes et évolutifs. + +## Objectifs pédagogiques + +À la fin de cette collection, vous aurez acquis de l'expérience avec : + +- **Les architectures de workflows modulaires complexes** - Combiner plusieurs workflows en pipelines cohérents +- **Les stratégies de test complètes** - Garantir que vos workflows sont fiables et maintenables +- **La gestion des métadonnées** - Gérer efficacement les métadonnées spécifiques aux échantillons tout au long de vos workflows +- **Le traitement avancé des données** - Implémenter des modèles efficaces de division et de regroupement des données + +Ces compétences vous permettront de construire des workflows Nextflow robustes, évolutifs et maintenables pour des applications réelles. + +## Public et prérequis + +Cette collection est conçue pour les utilisateurs qui ont terminé la formation Nextflow de base et souhaitent approfondir les modèles de workflows avancés, les stratégies de test, et les techniques de gestion des données et métadonnées. + +**Prérequis** + +- Avoir terminé la formation [Hello Nextflow](../../hello_nextflow/) ou posséder une expérience équivalente +- Connaissance de base de la syntaxe et des concepts Nextflow +- Compréhension des modèles de développement de workflows de base +- Expérience avec les outils en ligne de commande + +## Contenu de la collection + +Cette collection se compose de quatre Side Quests qui couvrent des sujets complémentaires d'ingénierie de workflows : + +1. **[Workflows de Workflows](../../side_quests/workflows_of_workflows)** - Architecture et composition de workflows complexes +2. **[Tests avec nf-test](../../side_quests/nf-test)** - Stratégies de test pour les workflows Nextflow +3. **[Métadonnées](../../side_quests/metadata)** - Gestion des métadonnées pour les éléments dans les canaux Nextflow +4. **[Division et Regroupement](../../side_quests/splitting_and_grouping)** - Modèles avancés de traitement des données + +Chaque Side Quest est autonome et couvre des concepts indépendants, mais nous recommandons de les compléter dans l'ordre listé ci-dessus pour une progression logique à travers les sujets. + +## Comment utiliser cette collection + +D'abord, faites Ctrl+clic (ou Cmd+clic) sur le bouton « Open in GitHub Codespaces » ci-dessous pour lancer l'environnement de formation dans un onglet séparé, puis continuez à lire pendant son chargement. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Une fois votre environnement en cours d'exécution, parcourez la collection comme suit : + +1. Dans cet onglet : Naviguez vers le premier Side Quest listé ci-dessus, qui décrit des exercices de développement étape par étape. +2. Dans votre onglet Codespaces : Réalisez les exercices du Side Quest. +3. Lorsque vous terminez un Side Quest, revenez sur cette page et naviguez vers le suivant dans la liste ci-dessus. +4. Lorsque vous avez terminé la collection, cliquez sur le bouton ci-dessous pour remplir un très court questionnaire. Vos retours nous permettent de continuer à améliorer les supports de formation pour tous. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Prêt à commencer ? Démarrez avec le premier module ci-dessus ! diff --git a/docs/fr/docs/training_collections/index.md b/docs/fr/docs/training_collections/index.md new file mode 100644 index 0000000000..a4905f20a1 --- /dev/null +++ b/docs/fr/docs/training_collections/index.md @@ -0,0 +1,23 @@ +# Collections de Formation + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduction assistée par IA - [en savoir plus et suggérer des améliorations](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Cette section contient des collections organisées de modules de formation appelés [Side Quests](../side_quests/index.md) qui visent à fournir une expérience d'apprentissage complète autour d'un thème ou d'un cas d'usage particulier. + +## Prérequis + +Chaque collection a des prérequis spécifiques documentés sur sa page d'index. Cependant, la plupart des collections supposent : + +- Une expérience avec la ligne de commande +- Les concepts fondamentaux de Nextflow et les outils couverts dans le cours de formation pour débutants [Hello Nextflow](../../hello_nextflow/) + +Pour les exigences techniques et la configuration de l'environnement, consultez le mini-cours [Configuration de l'Environnement](../../envsetup/). + +## Collections disponibles + +- [The Architect's Toolkit I](./architects_toolkit_1.md) - Une collection de quatre Side Quests couvrant les modèles d'architecture de workflow pour assembler des pipelines complexes, mettre en œuvre des stratégies de test, gérer les métadonnées et regrouper et diviser les données. _Durée estimée : 4 heures en formation de groupe._ + +## Suggérer de nouvelles collections + +Nous travaillons activement au développement de Side Quests et Collections supplémentaires. +N'hésitez pas à suggérer des sujets qui, selon vous, mériteraient d'être couverts dans une Collection en publiant dans la [section Formation](https://community.seqera.io/c/training/) du forum communautaire. diff --git a/docs/fr/llm-prompt.md b/docs/fr/llm-prompt.md new file mode 100644 index 0000000000..379ea7ae8a --- /dev/null +++ b/docs/fr/llm-prompt.md @@ -0,0 +1,170 @@ +# Translation Rules for French + +The target language for this translation is **French** (`fr`). + +## 1. Grammar & Tone + +- Use formal tone (vous instead of tu) +- Follow standard French spelling conventions +- Prefer active voice when possible +- Standard quotation marks ("") are acceptable; French quotation marks (« ») are optional + +### Inclusive Writing (Écriture Inclusive) + +Consider using inclusive writing with middle dots for gender-neutral terms: + +- "débutant·es" (beginners, both genders) +- "prêt·e" (ready, both genders) +- "chercheur·euses" (researchers, both genders) +- "formateur·trice" (trainer, both genders) + +This is optional but aligns with modern French writing practices. + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to French (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "Le canal d'entrée reçoit les fichiers..." (translate "channel" to "canal") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// émet un message de bienvenue` + +## 3. Code Comments + +**Always translate code comments to French.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// French translation +params.greeting = "Hello" // définit le message d'accueil par défaut +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to French: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Canal.fromPath('*.fastq') +processus FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ version 24.04.0 +exécuteur > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Translating terms commonly kept in English + +French tech writing commonly keeps these terms in English: + +```markdown +// Acceptable - these terms are standard in French tech docs +Le workflow utilise plusieurs pipelines... +Configurez le container Docker... + +// Also acceptable if translating +Le flux de travail utilise plusieurs pipelines... +Configurez le conteneur Docker... +``` + +### ❌ Missing spaces before punctuation + +French requires a non-breaking space before `:`, `;`, `!`, and `?`: + +```markdown +// Wrong +Attention: ceci est important! + +// Correct (with non-breaking space) +Attention : ceci est important ! +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code). + +Note: French technical writing commonly keeps "workflow" and "pipeline" in English. + +| English | French | Notes | +| --------------- | -------------------- | ---------------------------------- | +| channel | canal | In prose; keep English in code | +| process | processus | In prose; keep English in code | +| workflow | workflow | Keep in English (common in French) | +| pipeline | pipeline | Keep in English (common in French) | +| directive | directive | | +| container | conteneur | | +| input | entrée | | +| output | sortie | | +| task | tâche | | +| tuple | tuple | | +| operator | opérateur | | +| parameter | paramètre | | +| environment | environnement | | +| directory | répertoire | | +| file | fichier | | +| sample | échantillon | | +| alignment | alignement | | +| reference | référence | | +| training | formation | | +| workshop | atelier | | +| module | module | | +| command | commande | | +| index | index | | +| run | exécuter / exécution | | +| Side Quests | Quêtes secondaires | Creative translation, keep theme | +| quick reference | référence rapide | | + +## 6. Admonition Titles + +| English | French | +| -------- | ------------- | +| Note | Note | +| Tip | Astuce | +| Warning | Avertissement | +| Exercise | Exercice | +| Solution | Solution | +| Example | Exemple | + +## 7. Section Headers + +These recurring section headers should be translated consistently: + +| English | French | +| ----------------- | -------------------------------- | +| Takeaway | À retenir | +| What's next? | Et ensuite ? | +| Warmup | Échauffement | +| Environment Setup | Configuration de l'environnement | +| Getting Started | Premiers pas | + +## 8. Tab Labels + +| English | French | +| ------- | ------ | +| After | Après | +| Before | Avant | +| Gitpod | Gitpod | +| Local | Local | diff --git a/docs/fr/mkdocs.yml b/docs/fr/mkdocs.yml new file mode 100644 index 0000000000..36b505dcb9 --- /dev/null +++ b/docs/fr/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: fr + custom_dir: ../en/overrides +extra: + consent: + title: "Consentement aux cookies" + description: >- + Nous utilisons des cookies pour reconnaître vos visites répétées et vos préférences, + ainsi que pour mesurer l'efficacité de notre documentation et déterminer si les + utilisateur·rice·s trouvent ce qu'ils recherchent. Avec votre consentement, vous nous + aidez à améliorer nos supports de formation. + En savoir plus sur + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">notre utilisation des cookies</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/fr/ui-strings.yml b/docs/fr/ui-strings.yml new file mode 100644 index 0000000000..1325a75a9f --- /dev/null +++ b/docs/fr/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - French (Français) +# Ces chaînes sont utilisées par index_page_hook.py pour les pages +# d'accueil des cours et dans mkdocs.yml pour le consentement aux cookies. + +index_page: + course_summary: "Résumé du cours" + additional_information: "Informations complémentaires" + technical_requirements: "Prérequis techniques" + learning_objectives: "Objectifs d'apprentissage" + audience_prerequisites: "Public et prérequis" + course_videos: "Vidéos du cours" + +defaults: + technical_requirements: >- + Vous aurez besoin d'un compte GitHub OU d'une installation locale de Nextflow. + Consultez [Options d'environnement](../envsetup/index.md) pour plus de détails. + videos: >- + Des vidéos sont disponibles pour chaque chapitre, présentant un·e formateur·rice + qui travaille sur les exercices. La vidéo de chaque partie du cours est + intégrée en haut de la page correspondante. + view_playlist: "Voir la playlist sur YouTube" diff --git a/docs/hello_nextflow/00_orientation.it.md b/docs/hello_nextflow/00_orientation.it.md deleted file mode 100644 index c5dfb3bd5b..0000000000 --- a/docs/hello_nextflow/00_orientation.it.md +++ /dev/null @@ -1,93 +0,0 @@ -# Orientation - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/00_orientation.md). -/// - -## GitHub Codespaces - -L'ambiente GitHub Codespaces contiene tutto il software, il codice e i dati necessari per lavorare attraverso questo corso di formazione, quindi non devi installare nulla da solo. -Tuttavia, hai bisogno di un account GitHub (gratuito) per effettuare l'accesso e dovresti prenderti qualche minuto per familiarizzare con l'interfaccia. - -Se non l'hai ancora fatto, segui il mini-corso [Environment Setup](../../envsetup/) prima di proseguire. - -## Working directory - -Durante questo corso di formazione, lavoreremo nella directory `hello-nextflow/`. - -Cambia directory ora eseguendo questo comando nel terminale: - -```bash -cd hello-nextflow/ -``` - -!!!tip - - Se per qualsiasi motivo esci da questa directory, puoi sempre utilizzare il percorso completo per tornarci, supponendo che tu stia eseguendo questo comando nell'ambiente di formazione Github Codespaces: - - ```bash - cd /workspaces/training/hello-nextflow - ``` - -Diamo ora un'occhiata al contenuto di questa directory. - -## Materiali forniti - -Puoi esplorare il contenuto di questa directory utilizzando l'esploratore di file sul lato sinistro dell'area di lavoro di training. -In alternativa, puoi utilizzare il comando `tree`. - -Durante il corso, utilizziamo l'output `tree` per rappresentare la struttura e il contenuto delle directory in un formato leggibile, a volte con piccole modifiche per chiarezza. - -Qui generiamo un indice fino al secondo livello in basso: - -```bash -tree . -L 2 -``` - -Se esegui questo comando all'interno di `hello-nextflow`, dovresti vedere il seguente output: - -```console title="Directory contents" -. -├── greetings.csv -├── hello-channels.nf -├── hello-config.nf -├── hello-containers.nf -├── hello-modules.nf -├── hello-workflow.nf -├── hello-world.nf -├── nextflow.config -├── solutions -│ ├── 1-hello-world -│ ├── 2-hello-channels -│ ├── 3-hello-workflow -│ ├── 4-hello-modules -│ ├── 5-hello-containers -│ └── 6-hello-config -└── test-params.json - -7 directories, 9 files -``` - -**Ecco un riepilogo di ciò che dovresti sapere per iniziare:** - -- **I file `.nf`** sono script di workflow denominati in base alla parte del corso in cui vengono utilizzati. - -- **Il file `nextflow.config`** è un file di configurazione che imposta le proprietà minime dell'ambiente. - Per ora puoi ignorarlo. - -- **Il file `greetings.csv`** contiene i dati di input che utilizzeremo nella maggior parte del corso. È descritto nella Parte 1, quando lo introduciamo per la prima volta. - -- **Il file `test-params.json`** è un file che utilizzeremo nella Parte 6. Per ora puoi ignorarlo. - -- **La directory `solutions`** contiene gli script del workflow completati che risultano da ogni passaggio del corso. - Sono pensati per essere utilizzati come riferimento per controllare il tuo lavoro e risolvere eventuali problemi. - Il nome e il numero nel nome del file corrispondono al passaggio della parte pertinente del corso. - Ad esempio, il file `hello-world-4.nf` è il risultato previsto del completamento dei passaggi da 1 a 4 della Parte 1: Hello World. - -**Ora, per iniziare il corso, clicca sulla freccia nell'angolo in basso a destra di questa pagina.** diff --git a/docs/hello_nextflow/00_orientation.pt.md b/docs/hello_nextflow/00_orientation.pt.md deleted file mode 100644 index 60bc2e971e..0000000000 --- a/docs/hello_nextflow/00_orientation.pt.md +++ /dev/null @@ -1,77 +0,0 @@ -# Orientação - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Veja a [playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal de YouTube do Nextflow. - -:green_book: A transcrição desse vídeo está disponível [aqui](./transcripts/00_orientation.md). -/// - -O ambiente GitHub Codespaces contém todo o software, código e dados necessários para este curso. Você não precisa instalar nada por conta própria. No entanto, é necessária uma conta (gratuita) para logar - e recomendamos que você reserve alguns minutos para se familiarizar com a interface. - -Caso ainda não tenha feito isso, siga [este link](../../envsetup/) antes de prosseguir. - -## Materiais fornecidos - -Ao longo deste curso, trabalharemos no diretório `hello-nextflow/`, que é carregado por padrão quando você abre o ambiente de trabalho do Gitpod. Este diretório contém todos os arquivos de código, dados de teste e arquivos auxiliares que você precisará. - -Sinta-se à vontade para explorar o conteúdo deste diretório; a maneira mais fácil de fazer isso é usando o explorador de arquivos no lado esquerdo do ambiente de trabalho do Gitpod. Alternativamente, você pode usar o comando `tree`. Ao longo do curso, usamos a saída do `tree` para representar a estrutura e o conteúdo do diretório de forma legível - às vezes com pequenas modificações para maior clareza. - -Aqui, geramos um índice até o segundo nível: - -```bash -tree . -L 2 -``` - -Se você executar isso dentro do diretório `hello-nextflow`, verá a seguinte saída: - -```console title="Directory contents" -. -├── greetings.csv -├── hello-channels.nf -├── hello-config.nf -├── hello-containers.nf -├── hello-modules.nf -├── hello-workflow.nf -├── hello-world.nf -├── nextflow.config -├── solutions -│ ├── 1-hello-world -│ ├── 2-hello-channels -│ ├── 3-hello-workflow -│ ├── 4-hello-modules -│ ├── 5-hello-containers -│ └── 6-hello-config -└── test-params.json - -7 directories, 9 files -``` - -!!!nota - - Não se preocupe se isso parecer muita informação até o momento. Nós passaremos pelas partes relevantes ao longo das etapas do curso. Isso é apenas para te dar uma visão geral. - -**Aqui está um resumo do que você deveria saber para começar:** - -- **Os arquivos `.nf`** são _scripts_ de fluxo de trabalho nomeados com base na parte do curso em que são utilizados. - -- **O arquivo `nextflow.config`** é um arquivo de configuração que define propriedades mínimas do ambiente. Você pode ignorá-lo por enquanto. - -- **The file `greetings.csv`** contains input data we'll use in most of the course. It is described in Part 1, when we introduce it for the first time. - -- **The file `test-params.json`** is a file we'll use in Part 6. You can ignore it for now. - -- **O diretório `solutions`** contém os _scripts_ de fluxo de trabalho completos resultantes de cada etapa do curso. Eles servem como referência para verificar seu trabalho e solucionar quaisquer problemas. As informações de nome e o número presentes no nome do arquivo correspondem à etapa da parte relevante do curso. Por exemplo, o arquivo `hello-world-4.nf` é o resultado esperado ao completar as etapas 1 a 4 da Parte 1: Hello World. - -!!!dica - - Se, por algum motivo, você sair deste diretório, sempre poderá executar este comando para retornar: - - ```bash - cd /workspaces/training/hello-nextflow - ``` - -Agora, para iniciar o curso, clique na seta no canto inferior direito desta página. diff --git a/docs/hello_nextflow/01_hello_world.it.md b/docs/hello_nextflow/01_hello_world.it.md deleted file mode 100644 index c416238ba6..0000000000 --- a/docs/hello_nextflow/01_hello_world.it.md +++ /dev/null @@ -1,698 +0,0 @@ -# Parte 1: Hello World - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/01_hello_world.md). -/// - -In questa prima parte del corso di formazione Hello Nextflow, ci addentriamo nell'argomento con un esempio di Hello World molto elementare e indipendente dal dominio, che svilupperemo progressivamente per dimostrare l'uso della logica e dei componenti fondamentali di Nextflow. - -!!! note - - Un “Hello World!” è un esempio minimalista che ha lo scopo di dimostrare la sintassi e la struttura di base di un linguaggio di programmazione o di un framework software. L'esempio consiste tipicamente nello stampare la frase “Hello, World!” su un dispositivo di output, come la console o il terminale, o nello scriverla su un file. - ---- - -## 0. Riscaldamento: Eseguire direttamente Hello World - -Possiamo farlo con un semplice comando eseguito direttamente nel terminale, per mostrare cosa fa prima di adentrarci in Nextflow. - -!!! tip - - Ricordate che ora dovreste trovarvi all'interno della cartella `hello-nextflow/`, come descritto nella sezione Orientamento. - -### 0.1. Facciamo dire al terminale "Hello" - -```bash -echo 'Hello World!' -``` - -Questo testo viene inviato al terminale con la scritta 'Hello World'. - -```console title="Output" -Hello World! -``` - -### 0.2. Ora fate in modo che scriva il testo output in un file - -```bash -echo 'Hello World!' > output.txt -``` - -Questo non produce alcun output nel terminale. - -```console title="Output" - -``` - -### 0.3. Mostra il contenuto del file - -```bash -cat output.txt -``` - -Adesso, il testo 'Hello World' si trova nel file output che abbiamo specificato. - -```console title="output.txt" linenums="1" -Hello World! -``` - -!!! tip - - Nell'ambiente di addestramento, è possibile trovare il file di output nell'esploratore di file e visualizzarne il contenuto facendo clic su di esso. In alternativa, si può usare il comando `code` per aprire il file per visualizzarlo - - ```bash - code output.txt - ``` - -### Takeaway - -Ora sapete come eseguire un semplice comando nel terminale che produce un testo e, facoltativamente, come far scrivere l'output in un file. - -### Cosa c'è dopo? - -Scoprire come potrebbe essere scritto un flusso di lavoro Nextflow. - ---- - -## 1. Esaminare lo script di avvio del flusso di lavoro Hello World - -Come accennato nella guida, vi forniamo uno script di flusso di lavoro completamente funzionale, anche se minimalista, chiamato `hello-world.nf` che fa la stessa cosa di prima (scrivere “Hello World!”) ma con Nextflow. - -Per iniziare, apriremo prima lo script del flusso di lavoro, in modo da avere un'idea di come è strutturato. - -### 1.1. Esaminare la struttura complessiva del codice - -Apriamo lo script `hello-world.nf` nel pannello dell'editor. - -!!! note - - Il file si trova nella cartella `hello-nextflow`, che dovrebbe essere la cartella di lavoro corrente. - È possibile fare clic sul file nell'esploratore di file, oppure digitare `ls` nel terminale e fare Cmd+clic (MacOS) o Ctrl+clic (PC) sul file per aprirlo. - -```groovy title="hello-world.nf" linenums="1" -#!/usr/bin/env nextflow - -/* - * Usa echo per stampare 'Hello World!' in un file - */ -process sayHello { - - output: - path 'output.txt' - - script: - """ - echo 'Hello World!' > output.txt - """ -} - -workflow { - - // emette un saluto - sayHello() -} -``` - -Come si può vedere, uno script Nextflow comprende due tipi principali di componenti fondamentali: uno o più **process** e il **workflow** stesso. -Ogni **process** descrive le operazioni che il passo corrispondente della pipeline deve compiere, mentre il **workflow** descrive la logica del flusso di dati che collega i vari passi. - -Vediamo prima il blocco **process** e poi il blocco **workflow**. - -### 1.2. Definzione di `process` - -Il primo blocco di codice descrive un **process**. -La definizione del process inizia con la parola chiave `process`, seguita dal nome del processo e infine dal corpo del processo delimitato da parentesi graffe. -Il corpo del processo deve contenere un blocco di script che specifica il comando da eseguire, che può essere qualsiasi cosa si possa eseguire in un terminale a riga di comando. -Qui abbiamo un **process** chiamato `sayHello` che produce un **output** in un file chiamato `output.txt`. - -```groovy title="hello-world.nf" linenums="3" -/* - * Usa echo per stampare 'Hello World!' in un file - */ -process sayHello { - - output: - path 'output.txt' - - script: - """ - echo 'Hello World!' > output.txt - """ -} -``` - -Si tratta di una definizione di processo molto minimale, che contiene solo una definizione di `output' e lo `script' da eseguire - -La definizione `output` include il qualificatore `path`, che indica a Nextflow che questo deve essere gestito come un percorso (include sia percorsi di directory che di file). -Un altro qualificatore comune è `val`. - -!!! note - - La definzione dell'output non _determina_ quale output verrà creato. - Semplicemente _dichiara_ qual è l'output atteso, in modo che Nextflow possa cercarlo al termine dell'esecuzione. - Questo è necessario per verificare che il comando sia stato eseguito correttamente e per passare l'output ai processi a valle, se necessario. L'output prodotto che non corrisponde a quanto dichiarato nel blocco di output non verrà passato ai processi a valle. - -!!! warning - - Questo esempio è fragile perché abbiamo codificato il nome del file di output in due punti separati (lo script e i blocchi di output). - Se ne cambiamo uno ma non l'altro, lo script si rompe. - Più avanti, si imparerà a usare le variabili per evitare questo problema. - -In una pipeline reale, un processo di solito contiene blocchi aggiuntivi come le direttive e gli input, che introdurremo tra poco. - -### 1.3. La definizione di `workflow` - -Il secondo blocco di codice descrive il **workflow** stesso. -La definizione di workflow comincia con la parola chiabe `workflow`, seguita da un nome opzionale, e dal corpo del workflow delimitato da parentesi graffe. - -Qui abbiamo un **workflow** che consiste in una chiamata al processo `sayHello`. - -```groovy title="hello-world.nf" linenums="17" -workflow { - - // emette un saluto - sayHello() -} -``` - -Questa è definizione minimale del **workflow**. -In una pipeline reale, the workflow contiene tipicamente chiamate multiple a **processes** connesse da **channels**, e i processi prevedono una o più variabili in **input(s)**. - -Si apprenderà come aggiungere ingressi variabili più avanti in questo modulo di formazione; e si apprenderà come aggiungere altri processi e collegarli tramite canali nella Parte 3 di questo corso. - -### Takeaway - -Adesso sai com'è strutturato un semplice worflow di Nextflow. - -### Cosa c'è dopo? - -Impara come lanciare un workflow e a monitorare l'esecuzione e a trovare i vostri output. - ---- - -## 2. Esecuzione del workflow - -Guarda il codice non è così divertente come eseguirlo, quindi proviamao a metterlo in pratica. - -### 2.1. Lancio del workflow e monitorare l'esecuzione - -Nel terminale, esegui i seguenti comandi: - -```bash -nextflow run hello-world.nf -``` - -L'output della console dovrebbe apparire simile a questo: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 - -executor > local (1) -[a3/7be2fa] sayHello | 1 of 1 ✔ -``` - -Congratulazione, hai appena eseguito il tuo primo workflow i Nextflow. - -L'output più importante è l'ultima riga (riga 6): - -```console title="Output" linenums="6" -[a3/7be2fa] sayHello | 1 of 1 ✔ -``` - -Questo ci dice che il processo `sayHello' è stato eseguito con successo una volta (`1 di 1 ✔`). - -È importante che questa riga indichi anche dove trovare l'output della chiamata al processo `sayHello`. -Vediamolo ora. - -### 2.2. Trovare l'output e i registri nella directory `work` - -Quando si esegue Nextflow per la prima volta in una determinata directory, viene creata una directory chiamata `work` in cui verranno scritti tutti i file (e gli eventuali symlinks) generati nel corso dell'esecuzione. - -All'interno della directory `work`, Nextflow organizza gli output e i registri per ogni chiamata di processo. -Per ogni chiamata di processo, Nextflow crea una sottodirectory nidificata, denominata con un hash per renderla unica, in cui inserisce tutti gli input necessari (usando i symlinks per impostazione predefinita), scrive i file di aiuto e scrive i log e gli output del processo. - -Il percorso della subdirectory viene mostrato in forma tronca tra parentesi quadre nell'output della console. -Osservando i risultati dell'esecuzione mostrata sopra, la riga di log della console per il processo sayHello inizia con `[a3/7be2fa]`. Ciò corrisponde al seguente percorso di directory: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` - -Diamo un occhiata a cosa c'è dentro. - -!!! tip - - Se si sfoglia il contenuto della subdirectory task nel file explorer di VSCode, si vedranno subito tutti i file. - Tuttavia, i file di log sono impostati per essere invisibili nel terminale, quindi se si vuole usare `ls` o `tree` per visualizzarli, è necessario impostare l'opzione corrispondente per la visualizzazione dei file invisibili. - - ```bash - tree -a work - ``` - -Si dovrebbe vedere qualcosa di simile, anche se i nomi esatti delle subdirectory saranno diversi sul vostro sistema: - -```console title="Directory contents" -work -└── a3 - └── 7be2fad5e71e5f49998f795677fd68 - ├── .command.begin - ├── .command.err - ├── .command.log - ├── .command.out - ├── .command.run - ├── .command.sh - ├── .exitcode - └── output.txt -``` - -Questi sono i file di aiuto e di registro: - -- **`.command.begin`**: Metadati relativi all'inizio dell'esecuzione della chiamata di processo. -- **`.command.err`**: Messaggi di errore (`stderr`) emessi dalla chiamata al processo. -- **`.command.log`**: Output di log completo emesso dalla chiamata al processo -- **`.command.out`**: Output regolare (`stdout`) emesso dalla chiamata al processo -- **`.command.run`**: Script completo eseguito da Nextflow per eseguire la chiamata al processo -- **`.command.sh`**: Il comando che è stato effettivamente eseguito dalla chiamata di processo -- **`.exitcode`**: Il codice di uscita risultante dal comando - -Il file `.command.sh` è particolarmente utile perché dice quale comando Nextflow ha effettivamente eseguito. -In questo caso è molto semplice, ma più avanti nel corso si vedranno comandi che comportano un'interpolazione di variabili. -Quando si ha a che fare con questi comandi, è necessario essere in grado di controllare esattamente cosa è stato eseguito, soprattutto quando si risolve un problema. - -L'output effettivo del processo `sayHello` è `output.txt`. -Aprendola, troverete il saluto `Hello World!`, che era il risultato atteso del nostro flusso di lavoro minimalista. - -```console title="output.txt" linenums="1" -Hello World! -``` - -### Takeaway - -Sapete come decifrare un semplice script di Nextflow, eseguirlo e trovare l'output e i relativi file di log nella directory di lavoro. - -### Cosa c'è dopo? - -Imparate a gestire comodamente le esecuzioni dei vostri workflow. - ---- - -## 3. Gestire le esecuzioni dei workflow - -Sapere come lanciare workflow e recuperarne i risultati è ottimo, ma scoprirete subito che ci sono altri aspetti della gestione dei workflow che vi renderanno la vita più facile, soprattutto se ne state sviluppando uno di personale. - -Qui mostriamo come usare la direttiva `publishDir` per memorizzare in una cartella di output tutti i risultati principali dell'esecuzione della pipeline, la funzione `resume` per quando è necessario rilanciare lo stesso workflow e come cancellare le vecchie directory di lavoro con `nextflow clean`. - -### 3.1. Pubblicare i risultati - -Come si è appena appreso, l'output prodotto dalla nostra pipeline è sepolto in una directory di lavoro a diversi livelli di profondità. -Questo è stato fatto di proposito; Nextflow ha il controllo di questa directory e noi non dobbiamo interagire con essa. - -Tuttavia, questo rende scomodo recuperare gli output che ci interessano. - -Fortunatamente, Nextflow offre un modo per gestire più comodamente questo aspetto, chiamato direttiva `publishDir`, che agisce a livello di processo. -Questa direttiva indica a Nextflow di pubblicare gli output del processo in una directory di output designata. Per impostazione predefinita, gli output sono pubblicati come collegamenti simbolici dalla directory `work`. -Permette di recuperare il file di output desiderato senza dover scavare nella directory di lavoro. - -#### 3.1.1. Aggiungere una direttiva `publishDir` al processo `sayHello` - -Nel file di script del flusso di lavoro `hello-world.nf`, apportare la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-world.nf" linenums="6" hl_lines="3" - process sayHello { - - publishDir 'results', mode: 'copy' - - output: - path 'output.txt' - ``` - -=== "Prima" - - ```groovy title="hello-world.nf" linenums="6" - process sayHello { - - output: - path 'output.txt' - ``` - -#### 3.1.2. Eseguire nuovamente il workflow - -Eseguite ora lo script del workflow modificato: - -```bash -nextflow run hello-world.nf -``` - -L'output del log dovrebbe essere molto familiare - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 - -executor > local (1) -[62/49a1f8] sayHello | 1 of 1 ✔ -``` - -Questa volta, Nextflow ha creato una nuova directory chiamata `results/`. -Il nostro file `output.txt` si trova in questa directory. -Se si controlla il contenuto, dovrebbe corrispondere all'output della sottodirectory di lavoro. -In questo modo si pubblicano i file dei risultati al di fuori delle directory di lavoro. - -Quando si ha a che fare con file molto grandi che non devono essere conservati a lungo, si può preferire impostare la direttiva `publishDir` per creare un collegamento simbolico al file invece di copiarlo. -Tuttavia, se si elimina la directory di lavoro come parte di un'operazione di pulizia, si perderà l'accesso al file, quindi assicuratevi sempre di avere copie effettive di tutto ciò che vi interessa prima di eliminare qualcosa. - -!!! note - - È stata proposta una nuova opzione di sintassi documentata [qui](https://www.nextflow.io/docs/latest/workflow.html#publishing-outputs) per rendere possibile la dichiarazione e la pubblicazione di output a livello di flusso di lavoro. - Questo renderà l'uso di `publishDir`, a livello del processo, ridondante per le pipeline completate. - Tuttavia, ci aspettiamo che `publishDir` rimanga molto utile durante lo sviluppo della pipeline. - -### 3.2. Rilanciare un workflow con `-resume` - -A volte si desidera rieseguire una pipeline già avviata in precedenza, senza ripetere le fasi già completate con successo. - -Nextflow ha un'opzione chiamata `resume` che permette di farlo. -In particolare, in questa modalità vengono saltati tutti i processi già eseguiti con lo stesso codice, le stesse impostazioni e gli stessi input. -Ciò significa che Nextflow eseguirà solo i processi aggiunti o modificati dall'ultima volta che sono stati eseguiti o per i quali sono state fornite nuove impostazioni o input. - -Ci sono due vantaggi principali nel fare ciò: - -- Se siete nel bel mezzo dello sviluppo della vostra pipeline, potete iterare più rapidamente, poiché dovete eseguire solo i processi su cui state lavorando attivamente per testare le vostre modifiche. -- Se si sta eseguendo una pipeline in produzione e qualcosa va storto, in molti casi è possibile risolvere il problema e rilanciare la pipeline, che riprenderà a funzionare dal punto di guasto, con un notevole risparmio di tempo e di calcolo. - -Per usarlo, aggiungete semplicemente `-resume` al vostro comando ed eseguitelo: - -```bash -nextflow run hello-world.nf -resume -``` - -L'output della console dovresse essere simile. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 - -[62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ -``` - -Cercate il bit `cached:` che è stato aggiunto nella riga di stato del processo (riga 5), il che significa che Nextflow ha riconosciuto di aver già svolto questo lavoro e ha semplicemente riutilizzato il risultato della precedente esecuzione andata a buon fine. - -Si può anche notare che l'hash della sottodirectory di lavoro è lo stesso dell'esecuzione precedente. -Nextflow indica letteralmente l'esecuzione precedente e dice: “L'ho già fatto lì”. - -!!! note - - Quando si riesegue una pipeline con `resume`, Nextflow non sovrascrive alcun file scritto in una directory `publishDir` da qualsiasi chiamata di processo precedentemente eseguita con successo. - -### 3.3. Eliminare vecchie work directories - -Durante il processo di sviluppo, di solito si eseguono le pipeline in bozza un gran numero di volte, il che può portare all'accumulo di moltissimi file in molte sottodirectory. -Poiché le sottodirectory sono denominate in modo casuale, è difficile capire dai loro nomi quali sono le esecuzioni più vecchie e quali quelle più recenti. - -Nextflow include un utile sottocomando `clean` che può cancellare automaticamente le sottodirectory di lavoro per le esecuzioni passate che non interessano più, con diverse [opzioni](https://www.nextflow.io/docs/latest/reference/cli.html#clean) per controllare cosa verrà cancellato. - -Qui viene mostrato un esempio che cancella tutte le sottodirectory delle esecuzioni precedenti a una determinata esecuzione, specificata con il suo nome di esecuzione. -Il nome dell'esecuzione è la stringa in due parti generata dalla macchina e mostrata tra parentesi quadre nella riga di output della console `Launching (...)`. - -Per prima cosa usiamo il flag `-n` per verificare cosa verrà cancellato con il comando: - -```bash -nextflow clean -before golden_cantor -n -``` - -L'output dovrebbe risultare il seguente: - -```console title="Output" -Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 -``` - -Se non viene visualizzata alcuna riga, significa che non è stato fornito un nome di sessione valido o che non ci sono sessioni precedenti da eliminare. - -Se l'output appare come previsto e si vuole procedere con la cancellazione, rieseguire il comando con il flag `-f` invece di `-n`: - -```bash -nextflow clean -before golden_cantor -f -``` - -A questo punto si dovrebbe vedere quanto segue: - -```console title="Output" -Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 -``` - -!!! Warning - - L'eliminazione delle sottodirectory di lavoro delle esecuzioni precedenti le rimuove dalla cache di Nextflow e cancella tutti gli output memorizzati in tali directory. - Ciò significa che interrompe la capacità di Nextflow di riprendere l'esecuzione senza rieseguire i processi corrispondenti. - - L'utente è responsabile del salvataggio di tutti gli output a cui tiene o su cui intende fare affidamento! Se si usa la direttiva `publishDir` a tale scopo, assicurarsi di usare la modalità `copy`, non la modalità `symlink`. - -### Takeaway - -Sapete come pubblicare gli output in una directory specifica, rilanciare una pipeline senza ripetere i passaggi già eseguiti in modo identico e usare il comando `nextflow clean` per ripulire le vecchie directory di lavoro. - -### Cosa c'è dopo? - -Imparare a fornire una variabile in ingresso tramite un parametro della riga di comando e a utilizzare efficacemente i valori predefiniti. - ---- - -## 4. Usare una variabile di input passata alla riga di comando - -Nel suo stato attuale, il nostro flusso di lavoro utilizza un saluto codificato nel comando di processo. -Vogliamo aggiungere un po' di flessibilità utilizzando una variabile di input, in modo da poter cambiare più facilmente il saluto in fase di esecuzione. - -### 4.1. Modificare il flusso di lavoro per accettare e utilizzare un input variabile - -Ciò richiede di apportare tre modifiche al nostro script: - -1. Indicare al processo di aspettarsi un input variabile aggiungendo un blocco `input:` -2. Modificare il processo per utilizzare l'input -3. Impostare un parametro della riga di comando e fornire il suo valore come input alla chiamata al processo - -Apportiamo queste modifiche una alla volta. - -#### 4.1.1. Aggiungere un blocco di input alla definizione del processo - -Per prima cosa dobbiamo adattare la definizione del processo in modo che accetti un input chiamato `greeting`. - -Nel blocco del processo, apportare la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-world.nf" linenums="6" hl_lines="5 6" - process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path 'output.txt' - ``` - -=== "Prima" - - ```groovy title="hello-world.nf" linenums="6" - process sayHello { - - publishDir 'results', mode: 'copy' - - output: - path 'output.txt' - ``` - -La variabile `greeting` è preceduta da `val` per indicare a Nextflow che si tratta di un valore (non di un percorso). - -#### 4.1.2. Modificare il comando di processo per utilizzare la variabile di input - -Ora scambiamo il valore originale codificato con il valore della variabile di ingresso che ci aspettiamo di ricevere. - -Nel blocco del processo, apportare la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="16" hl_lines="3" - script: - """ - echo '$greeting' > output.txt - """ - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="16" - script: - """ - echo 'Hello World!' > output.txt - """ - ``` - -Assicuratevi di aggiungere il simbolo `$` per indicare a Nextflow che si tratta di un nome di variabile che deve essere sostituito con il valore effettivo (=interpolato). - -#### 4.1.3. Impostare un parametro CLI e fornirlo come input alla chiamata al processo - -Ora dobbiamo impostare un modo per fornire un valore di input alla chiamata di processo `sayHello()`. - -Si potrebbe semplicemente codificare direttamente scrivendo `sayHello('Hello World!')`. -Tuttavia, quando si lavora davvero con il flusso di lavoro, spesso si desidera poter controllare gli input dalla riga di comando. - -Buone notizie: Nextflow ha un sistema di parametri incorporato nel flusso di lavoro chiamato `params`, che rende facile dichiarare e utilizzare i parametri della CLI. La sintassi generale è dichiarare `params.<nome_parametro>` per dire a Nextflow di aspettarsi un parametro `--<nome_parametro>` sulla riga di comando. - -In questo caso, vogliamo creare un parametro chiamato `--greeting`, quindi dobbiamo dichiarare `params.greeting` da qualche parte nel flusso di lavoro. -In linea di principio, possiamo scriverla ovunque; ma poiché vogliamo darla alla chiamata di processo `sayHello()`, possiamo inserirla direttamente scrivendo `sayHello(params.greeting)`. - -!!! note - - Il nome del parametro (a livello di flusso di lavoro) non deve necessariamente corrispondere al nome della variabile di input (a livello di processo). - Usiamo la stessa parola perché è quella che ha senso e mantiene il codice leggibile. - -Nel blocco del flusso di lavoro, apportare la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-world.nf" linenums="24" hl_lines="2" - // emit a greeting - sayHello(params.greeting) - ``` - -=== "Prima" - - ```groovy title="hello-world.nf" linenums="24" - // emit a greeting - sayHello() - ``` - -Indica a Nextflow di eseguire il processo `sayHello` sul valore fornito attraverso il parametro `--greeting`. - -#### 4.1.4. Eseguite nuovamente il comando del flusso di lavoro - -Eseguiamolo! - -```bash -nextflow run hello-world.nf --greeting 'Bonjour le monde!' -``` - -Se tutte e tre le modifiche sono state eseguite correttamente, si dovrebbe ottenere un'altra esecuzione di successo: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Avvio di `hello-world.nf` [elated_lavoisier] DSL2 - revisione: 7c031b42ea - -executor > local (1) -[4b/654319] sayHello | 1 of 1 ✔ -``` - -Assicurarsi di aprire il file di output per verificare che sia disponibile la nuova versione del saluto. - -```console title="results/output.txt" linenums="1" -Bonjour le monde! -``` - -Voilà! - -!!! tip - - È possibile distinguere facilmente i parametri a livello di Nextflow da quelli a livello di pipeline. - - - I parametri che si applicano a una pipeline hanno sempre un doppio trattino (`--`). - - I parametri che modificano un'impostazione di Nextflow, ad esempio la funzione `riprendi' usata in precedenza, sono caratterizzati da un singolo trattino (`-`). - -### 4.2. Utilizzare i valori predefiniti per i parametri della riga di comando - -In molti casi, ha senso fornire un valore predefinito per un determinato parametro, in modo da non doverlo specificare per ogni esecuzione. - -#### 4.2.1. Impostare un valore predefinito per il parametro CLI - -Diamo al parametro `greeting` un valore predefinito, dichiarandolo prima della definizione del flusso di lavoro. - -```groovy title="hello-world.nf" linenums="22" -/* - * Pipeline parameters - */ -params.greeting = 'Holà mundo!' -``` - -!!! tip - - Se si preferisce, si può inserire la dichiarazione dei parametri all'interno del blocco del flusso di lavoro. Qualunque sia la scelta, si cerchi di raggruppare le cose simili nello stesso posto, in modo da non ritrovarsi con dichiarazioni sparse ovunque. - -#### 4.2.2. Eseguire nuovamente il flusso di lavoro senza specificare il parametro - -Ora che è stato impostato un valore predefinito, è possibile eseguire nuovamente il flusso di lavoro senza dover specificare un valore nella riga di comando. - -```bash -nextflow run hello-world.nf -``` - -L'output della console dovrebbe essere lo stesso. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 - -executor > local (1) -[72/394147] sayHello | 1 of 1 ✔ -``` - -Controllare l'output nella directory dei risultati: - -```console title="results/output.txt" linenums="1" -Holà mundo! -``` - -Nextflow ha utilizzato il valore predefinito per assegnare un nome all'output - -#### 4.2.3. Eseguire nuovamente il flusso di lavoro con il parametro per sovrascrivere il valore predefinito - -Se si fornisce il parametro sulla riga di comando, il valore della CLI sovrascrive il valore predefinito. - -Provate: - -```bash -nextflow run hello-world.nf --greeting 'Konnichiwa!' -``` - -L'output della console dovrebbe essere lo stesso. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 - -executor > local (1) -[6f/a12a91] sayHello | 1 of 1 ✔ -``` - -Ora si avrà il nuovo output corrispondente nella cartella dei risultati. - -```console title="results/output.txt" linenums="1" -Konnichiwa! -``` - -!!! note - - In Nextflow sono presenti più punti in cui è possibile specificare i valori dei parametri. - Se lo stesso parametro è impostato su valori diversi in più punti, Nexflow determinerà quale valore utilizzare in base all'ordine di precedenza descritto [qui](https://www.nextflow.io/docs/latest/config.html). - -### Takeaway - -Sapete come utilizzare una semplice variabile di input fornita in fase di esecuzione tramite un parametro della riga di comando, nonché come impostare, utilizzare e sovrascrivere i valori predefiniti. - -Più in generale, sapete come interpretare un semplice flusso di lavoro Nextflow, gestirne l'esecuzione e recuperare i risultati. - -### Cosa c'è dopo? - -Prendetevi una piccola pausa, ve la siete meritata!! -Quando siete pronti, passate alla Parte 2 per imparare a usare i canali per alimentare gli input nel vostro flusso di lavoro, il che vi permetterà di sfruttare il parallelismo dataflow integrato di Nextflow e altre potenti funzioni. diff --git a/docs/hello_nextflow/01_hello_world.pt.md b/docs/hello_nextflow/01_hello_world.pt.md deleted file mode 100644 index 75db66ac09..0000000000 --- a/docs/hello_nextflow/01_hello_world.pt.md +++ /dev/null @@ -1,1139 +0,0 @@ -# Part 1: Hello World - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Veja a [playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal de YouTube do Nextflow. - -:green_book: A transcrição desse vídeo está disponível [aqui](./transcripts/01_hello_world.md). -/// - -Um exemplo "Hello World!" é um modelo minimalista projetado para demonstrar a sintaxe básica e a estrutura de uma linguagem de programação ou framework de software. Esse exemplo normalmente consiste em exibir a frase "Hello, World!" no dispositivo de saída, como o console ou terminal, ou gravá-la em um arquivo. - -Nesta primeira parte do curso de treinamento Hello Nextflow, introduzimos o tópico com um exemplo Hello World muito simples e independente de domínio, que será gradualmente expandido para demonstrar o uso dos componentes e da lógica fundamental do Nextflow. - ---- - -## 0. Aquecimento: Execute Hello World diretamente - -Vamos demonstrar isso com um comando simples executado diretamente no terminal, para entender seu funcionamento antes de encapsulá-lo no Nextflow. - -### 0.1. Faça o terminal dizer hello - -```bash -echo 'Hello World!' -``` - -### 0.2. Agora faça-o escrever a saída em um arquivo - -```bash -echo 'Hello World!' > output.txt -``` - -### 0.3. Verifique se o arquivo de saída está presente usando o comando `ls` - -```bash -ls -``` - -### 0.4. Exiba o conteúdo do arquivo - -```bash -cat output.txt -``` - -!!! dica - - No ambiente Gitpod, você também pode encontrar o arquivo de saída no explorador de arquivos e visualizar seu conteúdo clicando nele. Alternativamente, pode usar o comando `code` para abrir o arquivo para visualização. - - - ```bash - code output.txt - ``` - -### Conclusão - -Agora você sabe como executar um comando simples no terminal que exibe um texto e, opcionalmente, como gravar essa saída em um arquivo. - -### O que vem a seguir? - -Descubra como isso seria estruturado em um fluxo de trabalho do Nextflow. - ---- - -## 1. Experimente o script inicial do workflow Hello World - -Conforme mencionado na introdução, fornecemos um script de workflow funcional, embora minimalista, chamado hello-world.nf. Ele realiza a mesma tarefa de antes (escrever "Hello World!"), mas utilizando o Nextflow. - -Para começar, primeiro abriremos o script do workflow para entender sua estrutura, e só depois o executaremos (antes de tentar qualquer modificação) para verificar se ele se comporta conforme esperado. - -### 1.1. Decifrando a estrutura do código - -Let's open the `hello-world.nf` script in the editor pane. - -!!! nota - - O arquivo está no diretório hello-nextflow, que deve ser seu diretório de trabalho atual. Você pode abrir o arquivo clicando no mesmo no explorador de arquivo ou digitar `ls` no terminal e Cmd+Click (MacOS) ou Ctrl+Click (PC). - -```groovy title="hello-world.nf" linenums="1" -#!/usr/bin/env nextflow - -/* - * Use echo para exibir 'Hello World!' - */ -process sayHello { - - output: - stdout - - script: - """ - echo 'Hello World!' - """ -} - -workflow { - - // emita uma saudação - sayHello() -} -``` - -Como você pode ver, um script Nextflow envolve dois tipos de componentes principais: um ou mais **processos** e o **fluxo de trabalho** propriamente dito. -Cada **processo** descreve a(s) operação(ões) que a etapa correspondente no pipeline deve realizar, enquanto o **fluxo de trabalho** descreve a lógica do fluxo de dados que conecta as várias etapas. -Vamos dar uma olhada mais de perto no bloco **process** primeiro e, depois, no bloco **workflow**. - -#### 1.1.1. A definição `process` - -O primeiro bloco de código descreve um **processo**. A definição do processo começa com a palavra-chave `process`, seguida do nome do processo e, finalmente, do corpo do processo delimitado por chaves. -O corpo do processo deve conter um bloco de script que especifica o comando a ser executado, que pode ser qualquer coisa que você executaria em um terminal de linha de comando. - -Aqui temos um **processo** chamado `sayHello` que grava sua **saída** em `stdout`. - -```groovy title="hello-world.nf" linenums="3" -/* - * Use echo para imprimir "Hello World!" na saída padrão - */ -processo sayHello { - output: - stdout - script: - """ - echo 'Hello World!' - """ -} -``` - -Essa é uma definição mínima de processo que contém apenas uma definição de saída e o próprio script. -Em um pipeline do mundo real, um processo geralmente contém blocos adicionais, como diretivas, entradas e cláusulas condicionais, que apresentaremos mais adiante neste curso de treinamento. - -!!! nota -A definição de saída não _determina_ qual saída será criada. -Ela simplesmente _declara_ qual é a saída esperada, de modo que o Nextflow possa procurá-la quando a execução estiver concluída. -Isso é necessário para verificar se o comando foi executado com êxito e para passar a saída para processos posteriores, se necessário. - -#### 1.1.2. A definição `workflow` - -O segundo bloco de código descreve o **fluxo de trabalho** em si. -A definição do fluxo de trabalho começa com a palavra-chave `workflow`, seguida de um nome opcional e, em seguida, o corpo do fluxo de trabalho delimitado por chaves. -Aqui temos um **fluxo de trabalho** que consiste em uma chamada para o processo `sayHello`. - -```groovy title="hello-world.nf" linenums="16" -workflow { - // emite uma saudação - sayHello() -} -``` - -Essa é uma definição mínima de **fluxo de trabalho**. -Em um pipeline do mundo real, o fluxo de trabalho normalmente contém várias chamadas para **processos** conectados por **canais**. -Você aprenderá como adicionar mais processos e conectá-los por canais daqui a pouco. - -### 1.2. Executando o fluxo de trabalho - -Olhar para o código não é tão divertido quanto executá-lo, portanto, vamos testar isso na prática. - -```bash -nextflow run hello-world.nf -``` - -A saída do console deve ser semelhante a esta: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [reverent_carson] DSL2 - revision: 463b611a35 - -executor > local (1) -[1c/7d08e6] sayHello [100%] 1 of 1 ✔ -``` - -Parabéns, você acabou de executar seu primeiro fluxo de trabalho Nextflow! - -O resultado mais importante aqui é a última linha (linha 6), que informa que o processo `sayHello` foi executado com sucesso uma vez. - -Ok, isso é ótimo, mas onde podemos encontrar o resultado? -A definição do processo `sayHello` dizia que a saída seria enviada para a saída padrão, mas nada foi impresso no console, não é mesmo? - -### 1.3. Localizando a saída e os logs no diretório `work` - -Quando você executa o Nextflow pela primeira vez em um determinado diretório, ele cria um diretório chamado `work` no qual gravará todos os arquivos (e links simbólicos) gerados durante a execução. - -Dê uma olhada lá dentro; você encontrará um subdiretório nomeado com um hash (para torná-lo exclusivo; discutiremos o motivo daqui a pouco), aninhado em dois níveis de profundidade e contendo alguns arquivos de log. - -!!! dica -Se você procurar o conteúdo do subdiretório de tarefas no explorador de arquivos VSCode do Gitpod, verá todos esses arquivos imediatamente. -No entanto, esses arquivos estão configurados para serem ocultados no terminal. Portanto, se quiser usar o `ls` ou o `tree` para visualizá-los, será necessário definir a opção relevante para exibir arquivos ocultados. - - ```bash - tree -a work - ``` - - Você deverá ver algo parecido com isto, embora os nomes exatos dos subdiretórios sejam diferentes em seu sistema. - - ```console title="Directory contents" - work - └── 1c - └── 7d08e685a7aa7060b9c21667924824 - ├── .command.begin - ├── .command.err - ├── .command.log - ├── .command.out - ├── .command.run - ├── .command.sh - └── .exitcode - ``` - -Você deve ter notado que os nomes dos subdiretórios apareceram (de forma truncada) na saída da execução do fluxo de trabalho, na linha que diz: - -```console title="Output" -[1c/7d08e6] sayHello [100%] 1 of 1 ✔ -``` - -Isso informa qual é o caminho do subdiretório para essa chamada de processo específica (às vezes chamada de tarefa). - -!!! nota -O Nextflow cria um subdiretório exclusivo e separado para cada chamada de processo. -Ele prepara os arquivos de entrada relevantes, o script e outros arquivos auxiliares lá, e grava todos os arquivos de saída e registros lá também. - -Se olharmos dentro do subdiretório, encontraremos os seguintes arquivos de log: - -- **`.command.begin`**: Metadados relacionados ao início da execução da tarefa do processo. -- **`.command.err`**: Mensagens de erro (stderr) emitidas pela tarefa de processo. -- **`.command.log`**: Saída de registro completa emitida pela tarefa de processo. -- **`.command.out`**: Saída regular (stdout) pela tarefa de processo. -- **`.command.sh`**: O comando que foi executado pela chamada da tarefa de processo -- **`.exitcode`**: O código de saída resultante do comando. - -Nesse caso, você pode procurar sua saída no arquivo `.command.out`, pois é nele que a saída stdout é capturada. -Se você abri-lo, encontrará a saudação `Hello World!`, que era o resultado esperado de nosso fluxo de trabalho minimalista. - -Também vale a pena dar uma olhada no arquivo `.command.sh`, que informa qual comando o Nextflow realmente executou. Nesse caso, é muito simples, mas mais adiante no curso você verá comandos que envolvem alguma interpolação de variáveis. Quando estiver lidando com isso, você precisará ser capaz de verificar exatamente o que foi executado, especialmente ao solucionar um problema. - -### Conclusão - -Você agora sabe como decifrar um script simples do Nextflow, executá-lo e encontrar a saída e os logs no diretório de trabalho. - -### O que vem a seguir? - -Saiba como fazer com que o script produza um arquivo nomeado. - ---- - -## 2. Enviando a saída para um arquivo - -Em vez de imprimir "Hello World!" na saída padrão, seria melhor salvar essa saída em um arquivo específico, exatamente como fizemos ao executar no terminal anteriormente. -É assim que a maioria das ferramentas que você executará como parte dos pipelines do mundo real normalmente se comporta; veremos exemplos disso mais tarde. -Para obter esse resultado, o script e os blocos de definição de saída precisam ser atualizados. - -### 2.1. Alterando o comando `process` para gerar um arquivo nomeado - -Essa é a mesma alteração que fizemos quando executamos o comando diretamente no terminal anteriormente. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="11" -''' -echo 'Hello World!' -''' -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="11" -''' -echo 'Hello World!' > output.txt -''' -``` - -### 2.2. Alterando a declaração de saída no processo `sayHello` - -Precisamos informar ao Nextflow que agora ele deve procurar um arquivo específico a ser produzido pela execução do processo. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="8" -output: - stdout -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="8" -output: - path 'output.txt' -``` - -!!! nota -As entradas e saídas nos blocos de processo normalmente exigem um qualificador e um nome de variável: - - ``` - <qualificador de entrada/saída> <nome da entrada/saída> - ``` - - O qualificador define o tipo de dados a serem recebidos. - Essas informações são usadas pelo Nextflow para aplicar as regras semânticas associadas a cada qualificador e tratá-las adequadamente. - - Os qualificadores comuns incluem `val` e `path`. - - No exemplo acima, `stdout` é uma exceção, pois não está associado a um nome. - -### 2.3. Executando o fluxo de trabalho novamente - -```bash -nextflow run hello-world.nf -``` - -A saída do log deve ser muito semelhante à primeira vez que você executou o fluxo de trabalho: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [cranky_sinoussi] DSL2 - revision: 30b437bb96 - -executor > local (1) -[7a/6bd54c] sayHello [100%] 1 of 1 ✔ -``` - -Como fez anteriormente, localize o diretório `work` no explorador de arquivos. -Lá, localize o arquivo de saída `output.txt`, clique nele para abri-lo e verifique se ele contém a saudação conforme esperado. - -!!! aviso -Este exemplo é frágil porque codificamos o nome do arquivo de saída em dois lugares diferentes (nos blocos `script` e `output`). -Se alterarmos um, mas não o outro, o script será interrompido. -Mais tarde, você aprenderá a usar variáveis para evitar esse problema. - -### 2.4. Adicionando uma diretiva `publishDir` ao processo - -Você deve ter notado que a saída está enterrada em um diretório de trabalho com várias camadas de profundidade. -O Nextflow está no controle desse diretório e não devemos interagir com ele. -Para tornar o arquivo de saída mais acessível, podemos utilizar a diretiva `publishDir`. - -Ao especificar essa diretiva, estamos dizendo ao Nextflow para copiar automaticamente o arquivo de saída para um diretório de saída designado. -Isso nos permite deixar o diretório de trabalho sozinho e, ao mesmo tempo, ter acesso fácil ao arquivo de saída desejado. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="6" -process sayHello { - - output: - path 'output.txt' -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="6" -process sayHello { - - publishDir 'results', mode: 'copy' - - output: - path 'output.txt' -``` - -!!! nota -Há uma nova opção de sintaxe que possibilita declarar e publicar saídas no nível do fluxo de trabalho, documentada [aqui] (https://www.nextflow.io/docs/latest/workflow.html#publishing-outputs), o que torna redundante o uso do `publishDir` no nível do processo quando o pipeline estiver totalmente operacional. -No entanto, o `publishDir` ainda é muito útil durante o desenvolvimento do pipeline; é por isso que o incluímos nesta série de treinamento. -Isso também garantirá que você possa ler e entender o grande número de pipelines que já foram escritos com o `publishDir`. -Você aprenderá a usar a sintaxe de saídas em nível de fluxo de trabalho mais adiante nesta série de treinamento. - -### 2.5. Executando o fluxo de trabalho novamente - -```bash -nextflow run hello-world.nf -``` - -A saída do log deve começar a parecer muito familiar: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [mighty_lovelace] DSL2 - revision: 6654bc1327 - -executor > local (1) -[10/15498d] sayHello [100%] 1 of 1 ✔ -``` - -Desta vez, o Nextflow terá criado um novo diretório chamado `results/`. -Nesse diretório, está o nosso arquivo `output.txt`. -Se você verificar o conteúdo, ele deverá corresponder à saída em nosso diretório work/task. -É assim que movemos os arquivos de resultados para fora dos diretórios de trabalho. - -### Conclusão - -Você agora já sabe como enviar resultados para um arquivo nomeado específico e usar a diretiva `publishDir` para mover arquivos para fora do diretório de trabalho do Nextflow. - -### O que vem a seguir? - -Saiba como fazer com que o Nextflow retome a execução de um pipeline usando resultados em cache de uma execução anterior para ignorar quaisquer etapas que já tenham sido concluídas com êxito. - ---- - -## 3. Usando o recurso `resume` do Nextflow - -O Nextflow tem uma opção chamada `resume`, que permite que você execute novamente um pipeline que já tenha sido iniciado anteriormente. -Quando iniciado com `-resume`, qualquer processo que já tenha sido executado exatamente com o mesmo código, configurações e entradas será ignorado. -Usar esse modo significa que o Nextflow só executará processos novos, que tenham sido modificados ou que estejam recebendo novas configurações ou entradas. - -Há duas vantagens principais em fazer isso: - -- Se você estiver no meio do desenvolvimento do pipeline, poderá iterar mais rapidamente, pois só precisará executar efetivamente o(s) processo(s) em que estiver trabalhando ativamente para testar as alterações. - -- Se estiver executando um pipeline em produção e algo der errado, em muitos casos, você poderá corrigir o problema e reiniciar o pipeline, e ele voltará a ser executado a partir do ponto de falha, o que pode economizar muito tempo e computação. - -### 3.1. Executando o fluxo de trabalho novamente com `-resume` - -```bash -nextflow run hello-world.nf -resume -``` - -A saída do console deve ser semelhante. - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [thirsty_gautier] DSL2 - revision: 6654bc1327 - -[10/15498d] sayHello [100%] 1 of 1, cached: 1 ✔ -``` - -Observe o bit adicional `cached:` na linha de status do processo, o que significa que o Nextflow reconheceu que já havia feito esse trabalho e simplesmente reutilizou o resultado da última execução. - -!!! nota -Quando você executa novamente um pipeline com `resume`, o Nextflow não sobrescreve nenhum arquivo gravado em um diretório publishDir por qualquer chamada de processo que tenha sido executada com sucesso anteriormente. - -### Conclusão - -Agora você sabe como reiniciar um pipeline sem repetir etapas que já foram executadas de maneira idêntica. - -### O que vem a seguir? - -Saiba como adicionar entradas variáveis. - ---- - -## 4. Adicionando entradas variáveis usando um canal - -Até agora, estamos emitindo uma saudação codificada no comando `process`. -Agora, vamos adicionar alguma flexibilidade usando uma variável de entrada, para que possamos alterar facilmente a saudação. - -Para isso, precisamos fazer uma série de alterações inter-relacionadas: - -1. Informar o processo sobre as entradas de variáveis esperadas usando o bloco `input:` -2. Editar o processo para usar a entrada -3. Criar um **canal** para passar a entrada para o processo (falaremos mais sobre isso em um minuto) -4. Adicionar o canal como entrada à chamada do processo - -### 4.1. Adicionando uma definição de `input` ao bloco do processo - -Primeiro, precisamos adaptar a definição do processo para aceitar uma entrada. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="6" -process sayHello { - - publishDir 'results', mode: 'copy' - - output: - path "output.txt" -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="6" -process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path "output.txt" -``` - -### 4.2. Editando o comando do processo para usar a variável de entrada - -Agora, trocamos o valor original codificado para a variável de entrada. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="16" -""" -echo 'Hello World!' > output.txt -""" -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="16" -""" -echo '$greeting' > output.txt -""" -``` - -### 4.3. Criando um canal de entrada - -Agora que o nosso processo espera uma entrada, precisamos configurar essa entrada no corpo do fluxo de trabalho. - -É aqui que entram os canais: o Nextflow usa canais para alimentar as entradas dos processos e transportar dados entre os processos que estão conectados entre si. -Há várias maneiras de fazer isso, mas, por enquanto, usaremos apenas o canal mais simples possível, contendo um único valor. - -Vamos criar o canal usando a fábrica `channel.of()`, que configura um canal de valor simples, e fornecer a ele uma string codificada para ser usada como saudação, declarando `greeting_ch = channel.of('Hello world!')`. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="21" -workflow { - - // emite uma saudação - sayHello() -} -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="21" -workflow { - - // cria um canal para os inputs - greeting_ch = channel.of('Hello world!') - - // emite uma saudação - sayHello() -} -``` - -### 4.4. Adicionando o canal como entrada à chamada de processo - -Agora precisamos realmente conectar nosso canal recém-criado à chamada de processo `sayHello()`. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="26" -// emit a greeting -sayHello() -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="26" -// emit a greeting -sayHello(greeting_ch) -``` - -### 4.5. Executando o comando do fluxo de trabalho novamente - -Vamos executá-lo! - -```bash -nextflow run hello-world.nf -``` - -Se você fez todas as quatro edições corretamente, deverá obter outra execução bem-sucedida: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [prickly_avogadro] DSL2 - revision: b58b6ab94b - -executor > local (1) -[1f/50efd5] sayHello (1) [100%] 1 of 1 ✔ -``` - -Sinta-se à vontade para verificar o diretório de resultados para se certificar de que o resultado ainda é o mesmo de antes; até agora, estamos apenas ajustando progressivamente o encanamento interno para aumentar a flexibilidade do nosso fluxo de trabalho e, ao mesmo tempo, obter o mesmo resultado final. - -### Conclusão - -Você agora sabe como usar um canal simples para fornecer uma entrada a um processo. - -### O que vem a seguir? - -Saiba como passar entradas da linha de comando. - ---- - -## 5. Usando parâmetros da CLI para entradas - -Queremos poder especificar a entrada da linha de comando, pois essa é a parte que quase sempre será diferente nas execuções subsequentes do fluxo de trabalho. - -Boas notícias: O Nextflow tem um sistema de parâmetros de fluxo de trabalho integrado chamado `params`, que facilita a declaração e o uso de parâmetros da CLI. - -### 5.1. Editando a declaração do canal de entrada para usar um parâmetro - -Aqui, trocamos a string codificada por `params.greeting` na linha de criação do canal. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="23" -// criar um canal para os inputs -greeting_ch = channel.of('Hello world!') -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="23" -// criar um canal para os inputs -greeting_ch = channel.of(params.greeting) -``` - -Isso cria automaticamente um parâmetro chamado `greeting` que você pode usar para fornecer um valor na linha de comando. - -### 5.2. Executar o fluxo de trabalho novamente com o parâmetro `--greeting` - -Para fornecer um valor para esse parâmetro, basta adicionar `--greeting <value>` à sua linha de comando. - -```bash -nextflow run hello-world.nf --greeting 'Bonjour le monde!' -``` - -A execução desse comando já deve lhe parecer extremamente familiar. - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [cheesy_engelbart] DSL2 - revision: b58b6ab94b - -executor > local (1) -[1c/9b6dc9] sayHello (1) [100%] 1 of 1 ✔ -``` - -Não se esqueça de abrir o arquivo de saída para verificar se agora você tem a nova versão da saudação. Pronto! - -!!! dica -É útil distinguir os parâmetros em nível de Nextflow dos parâmetros em nível de pipeline. -Para parâmetros que se aplicam a um pipeline, usamos um hífen duplo (`--`), enquanto usamos um único hífen (`-`) para parâmetros que modificam uma configuração específica do Nextflow, por exemplo, o recurso `-resume` que usamos anteriormente. - -### 5.3. Definindo um valor padrão para um parâmetro de linha de comando - -Em muitos casos, faz sentido fornecer um valor padrão para um determinado parâmetro para que você não precise especificá-lo em cada execução. -Vamos inicializar o parâmetro `greeting` com um valor padrão, adicionando a declaração do parâmetro na parte superior do script (com um bloco de comentários como bônus gratuito). - -```groovy title="hello-world.nf" linenums="3" -/* - * Parâmetros do Pipeline - */ -params.greeting = "Olá mundo!" -``` - -### 5.4. Executando o fluxo de trabalho novamente sem especificar o parâmetro - -Agora que você tem um valor padrão definido, pode executar o fluxo de trabalho novamente sem precisar especificar um valor na linha de comando. - -```bash -nextflow run hello-world.nf -``` - -A saída deve ser a mesma. - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [wise_waddington] DSL2 - revision: 988fc779cf - -executor > local (1) -[c0/8b8332] sayHello (1) [100%] 1 of 1 ✔ -``` - -Verifique a saída no diretório de resultados e... Tcharam! Funciona! O Nextflow usou o valor padrão para nomear a saída. Mas espere aí, o que acontece agora se fornecermos o parâmetro na linha de comando? - -### 5.5. Executando o fluxo de trabalho novamente com o parâmetro `--greeting` na linha de comando usando uma saudação diferente - -```bash -nextflow run hello-world.nf --greeting 'Hola Mundo!' -``` - -O Nextflow não está reclamando, o que é um bom sinal: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [prickly_miescher] DSL2 - revision: 988fc779cf - -executor > local (1) -[56/f88a56] sayHello (1) [100%] 1 of 1 ✔ -``` - -Verifique o diretório de resultados e veja o conteúdo de `output.txt`. Tcharam novamente! -O valor do parâmetro que passamos na linha de comando substituiu o valor que demos à variável no script. De fato, os parâmetros podem ser definidos de várias maneiras diferentes; se o mesmo parâmetro for definido em vários locais, seu valor será determinado com base na ordem de precedência descrita [aqui](https://www.nextflow.io/docs/latest/config.html). - -!!! dica -Você pode colocar a declaração do parâmetro dentro do bloco de fluxo de trabalho, se preferir. Seja qual for a sua escolha, tente agrupar coisas semelhantes no mesmo lugar para não acabar com declarações espalhadas por toda parte. - -### Conclusão - -Até agora você já sabe como configurar uma variável de entrada para um processo e fornecer um valor na linha de comando. - -### O que vem a seguir? - -Saiba como adicionar um segundo processo e encadeá-los. - ---- - -## 6. Adicionando uma segunda etapa ao fluxo de trabalho - -A maioria dos fluxos de trabalho do mundo real envolve mais de uma etapa. Aqui apresentamos um segundo processo que converte o texto em maiúsculas (all-caps), usando o clássico UNIX one-liner: - -```bash -tr '[a-z]' '[A-Z]' -``` - -Primeiro, vamos executar o comando sozinho no terminal para verificar se ele funciona conforme o esperado, sem que nenhum código de fluxo de trabalho atrapalhe a clareza, assim como fizemos no início com `echo 'Hello World'`. Em seguida, escreveremos um processo que faz a mesma coisa e, finalmente, conectaremos os dois processos para que a saída do primeiro sirva de entrada para o segundo. - -### 6.1. Executando o comando no terminal por si só - -```bash -echo 'Hello World' | tr '[a-z]' '[A-Z]' -``` - -A saída é simplesmente a versão em maiúsculas da string de texto: - -```console title="Output" -HELLO WORLD -``` - -!!! nota -Esse é um one-liner de substituição de texto muito ingênuo que não leva em conta as letras acentuadas, portanto, por exemplo, 'olá' se tornará 'OLà'. Isso é esperado. - -### 6.2. Fazendo com que o comando receba um arquivo como entrada e grave a saída em um arquivo - -Como anteriormente, queremos enviar os resultados para um arquivo dedicado, que nomeamos prefixando o nome do arquivo original com `UPPER-`. - -```bash -cat output.txt | tr '[a-z]' '[A-Z]' > UPPER-output.txt -``` - -Agora, a saída do `HELLO WORLD` está no novo arquivo de saída, `UPPER-output.txt`. - -### 6.3. Envolvendo o comando em uma nova definição de processo do Nextflow - -Podemos modelar nosso novo processo com base no primeiro, já que queremos usar todos os mesmos componentes. - -```groovy title="hello-world.nf" linenums="26" -/* - * Use um utilitário de substituição de texto para converter a saudação em maiúsculas - */ -process convertToUpper { - - publishDir 'results', mode: 'copy' - - input: - path input_file - - output: - path "UPPER-${input_file}" - - script: - """ - cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} - """ -} -``` - -Como um pequeno bônus, aqui compomos o segundo nome de arquivo de saída com base no primeiro. - -!!! dica -É muito importante lembrar: é necessário usar aspas duplas ao redor da expressão do nome do arquivo de saída (NÃO aspas simples) ou haverá falha. - -### 6.4. Adicionando uma chamada ao novo processo no corpo do fluxo de trabalho - -Não se esqueça de que precisamos dizer ao Nextflow para realmente chamar o processo que acabamos de criar! Para fazer isso, nós o adicionamos ao corpo do fluxo de trabalho. - -```groovy title="hello-world.nf" linenums="44" -workflow { - // criar um canal para entradas - greeting_ch = channel.of(params.greeting) - // emite uma saudação - sayHello(greeting_ch) - // converter a saudação em maiúsculas - convertToUpper() -} -``` - -Parece bom! Mas ainda precisamos conectar a chamada do processo `convertToUpper` para ser executada na saída do `sayHello`. - -### 6.5. Passando a saída do primeiro processo para o segundo processo - -A saída do processo `sayHello` é automaticamente empacotada como um canal chamado `sayHello.out`, portanto, tudo o que precisamos fazer é passá-la como entrada para o processo `convertToUpper`. - -```groovy title="hello-world.nf" linenums="52" -// converter a saudação em letras maiúsculas -convertToUpper(sayHello.out) -``` - -Para um caso simples como esse, isso é tudo o que precisamos fazer para conectar dois processos! - -### 6.6. Executar o mesmo comando de fluxo de trabalho anterior - -Vamos nos certificar de que isso funcione: - -```bash -nextflow run hello-world.nf --greeting 'Hello World!' -``` - -Que emocionante! Agora há uma linha extra na saída de registro, que corresponde ao novo processo que acabamos de adicionar: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [magical_brenner] DSL2 - revision: 0e18f34798 - -executor > local (2) -[57/3836c0] sayHello (1) [100%] 1 of 1 ✔ -[ee/bb3cc8] convertToUpper (1) [100%] 1 of 1 ✔ -``` - -Você notará que, desta vez, o fluxo de trabalho produziu dois novos subdiretórios de trabalho, um por chamada de processo. -Verifique o diretório de trabalho da chamada para o segundo processo, onde você deve encontrar dois arquivos de saída diferentes listados. Se olhar com atenção, você notará que um deles (a saída do primeiro processo) tem um pequeno ícone de seta à direita, o que significa que é um link simbólico. -Ele aponta para o local onde esse arquivo está no diretório de trabalho do primeiro processo. -Por padrão, o Nextflow usa links simbólicos para encenar arquivos de entrada sempre que possível, para evitar fazer cópias duplicadas. - -!!! nota -Tudo o que fizemos foi conectar a saída do `sayHello` à entrada do `convertToUpper` e os dois processos puderam ser executados em série. -O Nextflow fez o trabalho pesado de manipular os arquivos de entrada e saída e passá-los entre os dois comandos para nós. -Esse é o poder dos canais no Nextflow, fazendo o trabalho pesado de conectar as etapas do nosso pipeline. -Além disso, o Nextflow determinará automaticamente qual chamada precisa ser executada primeiro com base em como elas estão conectadas, de modo que a ordem em que estão escritas no corpo do fluxo de trabalho não importa. -No entanto, recomendamos que você seja gentil com seus colaboradores e com seu futuro eu, e tente escrevê-las em uma ordem lógica! - -### Conclusão - -Você já sabe como adicionar uma segunda etapa que usa a saída da primeira etapa como entrada. - -### O que vem a seguir? - -Saiba como fazer com que o fluxo de trabalho seja executado em um lote de valores de entrada. - ---- - -## 7. Modificando o fluxo de trabalho para ser executado em um lote de valores de entrada - -Os fluxos de trabalho normalmente são executados em lotes de entradas que devem ser processados em massa, portanto, queremos atualizar o fluxo de trabalho para aceitar vários valores de entrada. - -Convenientemente, a fábrica `channel.of()` que estamos usando aceita de bom grado mais de um valor, portanto, não precisamos modificá-la; basta carregar mais valores no canal. - -### 7.1. Carregando várias saudações no canal de entrada - -Para manter as coisas simples, voltamos a codificar as saudações na fábrica do canal em vez de usar um parâmetro para a entrada, mas melhoraremos isso em breve. -_Antes:_ - -```groovy title="hello-world.nf" linenums="46" -// criar um canal para entradas -greeting_ch = channel.of(params.greeting) -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="46" -// criar um canal para entradas -greeting_ch = channel.of('Hello','Bonjour','Holà') -``` - -A documentação nos diz que isso deve funcionar. Será que realmente pode ser tão simples? - -### 7.2. Executando o comando e vendo a saída do registro - -Vamos tentar. - -```bash -nextflow run hello-world.nf -``` - -Bem, ele parece estar funcionando bem. - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [lonely_pare] DSL2 - revision: b9f1d96905 - -executor > local (6) -[3d/1fe62c] sayHello (2) [100%] 3 of 3 ✔ -[86/695813] convertToUpper (3) [100%] 3 of 3 ✔ -``` - -No entanto... Isso parece indicar que foram feitas “3 de 3” chamadas para cada processo, o que é animador, mas isso nos dá apenas um caminho de subdiretório para cada um. O que está acontecendo? - -Por padrão, o sistema de registro ANSI grava o registro de várias chamadas para o mesmo processo na mesma linha. Felizmente, podemos desativar esse comportamento. - -### 7.3. Execute o comando novamente com a opção `-ansi-log false` - -Para expandir o registro em log para exibir uma linha por chamada de processo, basta adicionar `-ansi-log false` ao comando. - -```bash -nextflow run hello-world.nf -ansi-log false -``` - -Desta vez, vemos todos os seis subdiretórios de trabalho listados na saída: - -```console title="Output" -N E X T F L O W ~ version 24.02.0-edge -Launching `hello-world.nf` [big_woese] DSL2 - revision: 53f20aeb70 -[62/d81e63] Submitted process > sayHello (1) -[19/507af3] Submitted process > sayHello (2) -[8a/3126e6] Submitted process > sayHello (3) -[12/48a5c6] Submitted process > convertToUpper (1) -[73/e6e746] Submitted process > convertToUpper (2) -[c5/4fedda] Submitted process > convertToUpper (3) -``` - -Isso é muito melhor, pelo menos para esse número de processos. -No caso de um fluxo de trabalho complexo ou de um grande número de entradas, ter a lista completa de saída para o terminal pode ser um pouco cansativo. - -Dito isso, temos outro problema. Se você olhar o diretório `results`, há apenas dois arquivos: `output.txt` e `UPPER-output.txt`! - -```console title="Conteúdo do diretório” -resultados -├── output.txt -└── UPPER-output.txt -``` - -O que está acontecendo com isso? Não deveríamos estar esperando dois arquivos por saudação de entrada, ou seja, seis arquivos no total? -Você deve se lembrar que codificamos o nome do arquivo de saída para o primeiro processo. -Isso foi bom desde que houvesse apenas uma única chamada feita por processo, mas quando começamos a processar vários valores de entrada e a publicar as saídas no mesmo diretório de resultados, isso se torna um problema. -Para um determinado processo, cada chamada produz uma saída com o mesmo nome de arquivo, portanto, o Nextflow simplesmente substitui o arquivo de saída anterior sempre que um novo é produzido. - -### 7.4. Certifique-se de que os nomes dos arquivos de saída sejam exclusivos - -Como publicaremos todos os resultados no mesmo diretório de resultados, precisamos garantir que eles tenham nomes exclusivos. -Especificamente, precisamos modificar o primeiro processo para gerar um nome de arquivo dinamicamente, de modo que os nomes dos arquivos finais sejam exclusivos. -Então, como tornar os nomes dos arquivos exclusivos? Uma maneira comum de fazer isso é usar alguma parte exclusiva de metadados como parte do nome do arquivo. -Aqui, por conveniência, usaremos apenas a saudação em si. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="11" -process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path "output.txt" - - script: - """ - echo '$greeting' > "output.txt" - """ -} -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="11" -process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path "${greeting}-output.txt" - - script: - """ - echo '$greeting' > '$greeting-output.txt' - """ -} -``` - -Isso deve produzir um nome de arquivo de saída exclusivo para cada chamada de cada processo. - -### 7.5. Execute o fluxo de trabalho e veja o diretório de resultados - -Vamos executá-lo e verificar se ele funciona. - -```bash -nextflow run hello-world.nf -``` - -Ao voltar para a visualização de resumo, a saída tem a seguinte aparência novamente: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [jovial_mccarthy] DSL2 - revision: 53f20aeb70 - -executor > local (6) -[03/f007f2] sayHello (1) [100%] 3 of 3 ✔ -[e5/dd2890] convertToUpper (3) [100%] 3 of 3 ✔ -``` - -Mas o mais importante é que agora temos seis novos arquivos, além dos dois que já tínhamos no diretório `results`: - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── Hello-output.txt -├── Holà-output.txt -├── output.txt -├── UPPER-Bonjour-output.txt -├── UPPER-Hello-output.txt -├── UPPER-Holà-output.txt -└── UPPER-output.txt -``` - -Sucesso! Agora podemos adicionar quantas saudações quisermos sem nos preocuparmos com o fato de os arquivos de saída serem sobrescritos. - -!!! nota -Na prática, nomear arquivos com base nos próprios dados de entrada é quase sempre impraticável. A melhor maneira de gerar nomes de arquivos dinâmicos é usar uma planilha de amostras que contenha metadados relevantes (como IDs de amostra exclusivos) e criar uma estrutura de dados chamada “mapa”, que passamos para os processos e da qual podemos obter um identificador apropriado para gerar os nomes de arquivos. -Mostraremos a você como fazer isso mais adiante neste curso de treinamento. - -### Conclusão - -Você já sabe como alimentar um lote de vários elementos de entrada por meio de um canal. - -### O que vem a seguir? - -Saiba como fazer com que o fluxo de trabalho use um arquivo como sua fonte de valores de entrada. - ---- - -## 8. Modificando o fluxo de trabalho para usar um arquivo como fonte de valores de entrada - -Muitas vezes, quando queremos executar um lote de vários elementos de entrada, os valores de entrada podem estar contidos em um arquivo. - -Como exemplo, fornecemos a você um arquivo CSV chamado `greetings.csv` no diretório `data/`, contendo várias saudações separadas por vírgulas. - -```csv title="greetings.csv" -Hello,Bonjour,Holà -``` - -Portanto, só precisamos modificar nosso fluxo de trabalho para ler os valores de um arquivo como esse. - -### 8.1. Configurando um parâmetro da CLI com um valor padrão apontando para um arquivo de entrada - -Primeiro, vamos usar o argumento `params` para configurar um novo parâmetro chamado `input_file`, substituindo o parâmetro `greeting`, agora inútil, com um valor padrão que aponta para o arquivo `greetings.csv`. - -_Antes:_ - -```groovy title="hello-world.nf" linenums="6" -/* - * Parâmetros do pipeline - */ -params.greeting = "Bonjour le monde!" -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="6" -/* - * Parâmetros do pipeline - */ -params.input_file = "data/greetings.csv" -``` - -### 8.2. Atualizando a declaração do canal para lidar com o arquivo de entrada - -Neste ponto, apresentamos uma nova fábrica de canais, `channel.fromPath()`, que tem algumas funcionalidades integradas para lidar com caminhos de arquivos. - -Vamos usá-la em vez da fábrica `channel.of()` que usamos anteriormente; a sintaxe básica é a seguinte: - -```groovy title="channel construction syntax" -channel.fromPath(input_file) -``` - -Agora, vamos implantar um novo conceito, um “operador” para transformar esse arquivo CSV em conteúdo de canal. Você aprenderá mais sobre operadores mais tarde, mas, por enquanto, basta entendê-los como formas de transformar canais de várias maneiras. - -Como nosso objetivo é ler o conteúdo de um arquivo `.csv`, adicionaremos o operador `.splitCsv()` para fazer com que o Nextflow analise o conteúdo do arquivo adequadamente, bem como o operador `.flatten()` para transformar o elemento de matriz produzido por `.splitCsv()` em um canal de elementos individuais. -Portanto, a instrução de construção do canal passa a ser: - -```groovy title="channel construction syntax" -channel.fromPath(input_file) - .splitCsv() - .flatten() -``` - -E aqui está ele no contexto do corpo do fluxo de trabalho: - -_Antes:_ - -```groovy title="hello-world.nf" linenums="46" -// criar um canal para entradas -greeting_ch = channel.of('Hello','Bonjour','Holà') -``` - -_Depois:_ - -```groovy title="hello-world.nf" linenums="46" -// criar um canal para entradas de um arquivo CSV -greeting_ch = channel.fromPath(params.input_file) - .splitCsv() - .flatten() -``` - -### 8.3. Executando o fluxo de trabalho (uma última vez!) - -```bash -nextflow run hello-world.nf -``` - -Mais uma vez, vemos que cada processo é executado três vezes: - -```console title="Output" - N E X T F L O W ~ version 24.02.0-edge - - ┃ Launching `hello-world.nf` [angry_spence] DSL2 - revision: d171cc0193 - -executor > local (6) -[0e/ceb175] sayHello (2) [100%] 3 of 3 ✔ -[01/046714] convertToUpper (3) [100%] 3 of 3 ✔ -``` - -Observando os resultados, vemos que cada saudação foi extraída e processada corretamente pelo fluxo de trabalho. Obtivemos o mesmo resultado da etapa anterior, mas agora temos muito mais flexibilidade para adicionar mais elementos ao canal de saudações que queremos processar. - -!!! dica -Durante o desenvolvimento do pipeline, você pode inspecionar o conteúdo de qualquer canal adicionando o operador `.view()` ao nome do canal. -Por exemplo, se você adicionar `greeting_ch.view()` em qualquer lugar do corpo do fluxo de trabalho, ao executar o script, o Nextflow imprimirá o conteúdo do canal na saída padrão. -Você também pode usar isso para inspecionar o efeito dos operadores. - - Por exemplo, a saída de `channel.fromPath(params.input_file).splitCsv().view()` terá a seguinte aparência: - - ```console title="Output" - [Hello, Bonjour, Holà] - ``` - - Enquanto a saída de `channel.fromPath(params.input_file).splitCsv().flatten().view()` terá a seguinte aparência: - - ```console title="Output” - Olá - Bom dia - Olá - ``` - -### Conclusão - -Você agora sabe como fornecer os valores de entrada para o fluxo de trabalho por meio de um arquivo. -De modo mais geral, você aprendeu a usar os componentes essenciais do Nextflow e tem uma compreensão básica da lógica de como criar um fluxo de trabalho e gerenciar entradas e saídas. - -### O que vem a seguir? - -Comemore seu sucesso e faça uma pausa! -Não se preocupe se os tipos de canais e operadores parecerem muito difíceis de lidar na primeira vez que você os encontrar. -Você terá mais oportunidades de praticar o uso desses componentes em várias configurações ao longo deste curso de treinamento. -Quando estiver pronto, vá para a Parte 2 para aprender sobre outro conceito importante: o provisionamento do software necessário para cada processo. diff --git a/docs/hello_nextflow/02_hello_channels.it.md b/docs/hello_nextflow/02_hello_channels.it.md deleted file mode 100644 index 1a67e2e045..0000000000 --- a/docs/hello_nextflow/02_hello_channels.it.md +++ /dev/null @@ -1,908 +0,0 @@ -# Parte 2: Hello Channels - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/02_hello_channels.md). -/// - -Nella parte 1 di questo corso (Hello World), ti abbiamo mostrato come fornire un input variabile a un processo fornendo direttamente l'input nella chiamata di processo: `sayHello(params.greet)`. -Era un approccio volutamente semplificato. -In pratica, questo approccio ha grandi limitazioni; vale a dire che funziona solo per casi molto semplici in cui vogliamo eseguire il processo solo una volta, su un singolo valore. -Nella maggior parte dei casi d'uso del workflow realistici, vogliamo elaborare più valori (dati sperimentali per più campioni, ad esempio), quindi abbiamo bisogno di un modo più sofisticato per gestire gli input. - -Ecco a cosa servono i **canali** di Nextflow. -I canali sono code progettate per gestire gli input in modo efficiente e spostarli da un passaggio all'altro in workflows in più fasi, fornendo parallelismo integrato e molti vantaggi aggiuntivi. - -In questa parte del corso, imparerai come utilizzare un canale per gestire più input da una varietà di fonti diverse. -Imparerai anche a usare **operatori** per trasformare i contenuti del canale secondo necessità. - -_Per la formazione sull'uso dei canali per collegare i passaggi in un workflow multi-step, vedere la parte 3 di questo corso. _ - ---- - -## 0. Riscaldamento: esegui `hello-channels.nf` - -Useremo lo script del workflow `hello-channels.nf` come punto di partenza. -È equivalente allo script prodotto lavorando attraverso la Parte 1 di questo corso di formazione. - -Solo per assicurarti che tutto funzioni, esegui lo script una volta prima di apportare qualsiasi modifica: - -```bash -nextflow run hello-channels.nf --greeting 'Hello Channels!' -``` - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [insane_lichterman] DSL2 - revision: c33d41f479 - -executor > local (1) -[86/9efa08] sayHello | 1 of 1 ✔ -``` - -Come in precedenza, troverai il file di output denominato `output.txt` nella directory `results` (specificata dalla direttiva `publishDir`). - -```console title="results/output.txt" linenums="1" -Hello Channels! -``` - -Se ha funzionato per te, sei pronto a conoscere i canali. - ---- - -## 1. Fornire input variabili tramite un canale esplicitamente - -Creeremo un **canale** per passare l'input variabile al processo `sayHello()` invece di fare affidamento sulla gestione implicita, che ha alcune limitazioni. - -### 1.1. Crea un canale di input - -Ci sono una varietà di **fabbriche di canali** che possiamo utilizzare per creare un canale. -Per mantenere le cose semplici per ora, useremo la fabbrica di canale più semplice, chiamata `channel.of`, che creerà un canale contenente un singolo valore. -Funzionalmente questo sarà simile a come lo avevamo impostato prima, ma invece di avere Nextflow a creare implicitamente un canale, lo stiamo facendo esplicitamente ora. - -Questa è la riga di codice che useremo: - -```console title="Syntax" -greeting_ch = channel.of('Hello Channels!') -``` - -Questo crea un canale chiamato `greeting_ch` usando la fabbrica del canale `channel.of()`, che imposta un semplice canale di coda e carica la stringa `'Hello Channels!' ` da usare come valore di saluto. - -!!! note - - Stiamo temporaneamente tornando alle stringhe codificate invece di utilizzare un parametro CLI per motivi di leggibilità. Torneremo a utilizzare i parametri CLI una volta che avremo coperto ciò che sta accadendo a livello del canale. - -Nel blocco del workflow, aggiungi il codice di fabbrica del canale: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="27" hl_lines="3 4" - workflow { - - // create a channel for inputs - greeting_ch = channel.of('Hello Channels!') - - // emit a greeting - sayHello(params.greeting) - } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="27" - workflow { - - // emit a greeting - sayHello(params.greeting) - } - ``` - -Questo non è ancora funzionale poiché non abbiamo ancora cambiato l'input alla chiamata di processo. - -### 1.2. Aggiungi il canale come input alla chiamata di processo - -Ora dobbiamo effettivamente collegare il nostro canale appena creato alla chiamata di processo `sayHello()`, sostituendo il parametro CLI che stavamo fornendo direttamente prima. - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" - workflow { - - // create a channel for inputs - greeting_ch = channel.of('Hello Channels!') - - // emit a greeting - sayHello(greeting_ch) - } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="27" - workflow { - - // create a channel for inputs - greeting_ch = channel.of('Hello Channels!') - - // emit a greeting - sayHello(params.greeting) - } - ``` - -Questo dice a Nextflow di eseguire il processo `sayHello` sui contenuti del canale `greeting_ch`. - -Ora il nostro workflow è correttamente funzionale; è l'equivalente esplicito di scrivere `sayHello('Hello Channels!') `. - -### 1.3. Esegui di nuovo il comando del workflow - -Eseguiamolo! - -```bash -nextflow run hello-channels.nf -``` - -Se hai apportato entrambe le modifiche correttamente, dovresti ottenere un'altra esecuzione riuscita: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [nice_heisenberg] DSL2 - revision: 41b4aeb7e9 - -executor > local (1) -[3b/f2b109] sayHello (1) | 1 of 1 ✔ -``` - -Puoi controllare la directory dei risultati per assicurarti che il risultato sia ancora lo stesso di prima. - -```console title="results/output.txt" linenums="1" -Hello Channels! -``` - -Finora stiamo solo modificando progressivamente il codice per aumentare la flessibilità del nostro workflow ottenendo allo stesso tempo lo stesso risultato finale. - -!!! note - - Può sembrare che stiamo scrivendo più codice senza alcun beneficio tangibile, ma il valore diventerà chiaro non appena inizieremo a gestire più input. - -### Conclusioni - -Sai come utilizzare una fabbrica di canale di base per fornire un input a un processo. - -### Cosa c'è dopo? - -Scopri come utilizzare i canali per far in modo che il workflow iteri su più valori di input. - ---- - -## 2. Modifica il workflow per eseguire su più valori di input - -I workflows in genere vengono eseguiti su lotti di input che devono essere elaborati in blocco, quindi vogliamo aggiornare il workflow per accettare più valori di input. - -### 2.1. Carica più saluti nel canale di input - -Convenientemente, la fabbrica di canali `channel.of()` che abbiamo utilizzato è abbastanza felice di accettare più di un valore, quindi non abbiamo affatto bisogno di modificarlo. - -Dobbiamo solo caricare più valori nel canale. - -#### 2.1.1. Aggiungi altri saluti - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="29" hl_lines="2" - // create a channel for inputs - greeting_ch = channel.of('Hello','Bonjour','Holà') - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="29" - // create a channel for inputs - greeting_ch = channel.of('Hello Channels') - ``` - -La documentazione ci dice che questo dovrebbe funzionare. Può davvero essere così semplice? - -#### 2.1.2. Esegui il comando e guarda l'output del registro - -Proviamolo. - -```bash -nextflow run hello-channels.nf -``` - -Certamente sembra funzionare bene: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [suspicious_lamport] DSL2 - revision: 778deadaea - -executor > local (3) -[cd/77a81f] sayHello (3) | 3 of 3 ✔ -``` - -Tuttavia... Questo sembra indicare che sono state effettuate chiamate "3 di 3" per il processo, il che è incoraggiante, ma questo ci mostra solo una singola esecuzione del processo, con un percorso di sottodirectory (`cd/77a81f`). -Cosa sta succedendo? - -Per impostazione predefinita, il sistema di registrazione ANSI scrive la registrazione da più chiamate allo stesso processo sulla stessa linea. -Fortunatamente, possiamo disabilitare quel comportamento per vedere l'elenco completo delle chiamate di processo. - -#### 2.1.3. Esegui di nuovo il comando con l'opzione `-ansi-log false` - -Per espandere la registrazione per visualizzare una riga per chiamata di processo, aggiungi `-ansi-log false` al comando. - -```bash -nextflow run hello-channels.nf -ansi-log false -``` - -Questa volta vediamo tutte e tre le esecuzioni di processo e le loro sottodirectory di lavoro associate elencate nell'output: - -```console title="Output" linenums="1" -N E X T F L O W ~ version 24.10.0 -Launching `hello-channels.nf` [pensive_poitras] DSL2 - revision: 778deadaea -[76/f61695] Submitted process > sayHello (1) -[6e/d12e35] Submitted process > sayHello (3) -[c1/097679] Submitted process > sayHello (2) -``` - -È molto meglio; almeno per un semplice workflow. -Per un workflow complesso o un gran numero di input, avere l'output completo dell'elenco sul terminale potrebbe diventare un po' travolgente, quindi potresti non scegliere di usare `-ansi-log false` in quei casi. - -!!! note - - Il modo in cui viene riportato lo stato è un po' diverso tra le due modalità di registrazione. - In modalità condensata, Nextflow segnala se le chiamate sono state completate con successo o meno. - In questa modalità espansa, riporta solo che sono stati inviati. - -Detto questo, abbiamo un altro problema. Se guardi nella directory `results`, c'è solo un file: `output.txt`! - -```console title="Directory contents" -results -└── output.txt -``` - -Che succede? Non dovremmo aspettarci un file separato per saluto di input, quindi tre file in tutto? -Tutti e tre i saluti sono andati in un unico file? - -Puoi controllare il contenuto di `output.txt`; troverai solo uno dei tre, contenente uno dei tre saluti che abbiamo fornito. - -```console title="output.txt" linenums="1" -Bonjour -``` - -Potresti ricordare che abbiamo codificato il nome del file di output per il processo `sayHello`, quindi tutte e tre le chiamate hanno prodotto un file chiamato `output.txt`. -Puoi controllare le sottodirectory di lavoro per ciascuno dei tre processi; ognuno di essi contiene un file chiamato `output.txt` come previsto. - -Finché i file di output rimangono lì, isolati dagli altri processi, va bene. -Ma quando la direttiva `publishDir` copia ciascuno di essi nella stessa directory `results`, qualunque sia stato copiato lì per primo viene sovrascritto da quello successivo, e così via. - -### 2.2. Assicurati che i nomi dei file di output siano univoci - -Possiamo continuare a pubblicare tutti gli output nella stessa directory dei risultati, ma dobbiamo assicurarci che abbiano nomi univoci. -In particolare, dobbiamo modificare il primo processo per generare un nome di file in modo dinamico in modo che i nomi dei file finali siano unici. - -Quindi, come facciamo a rendere unici i nomi dei file? -Un modo comune per farlo è utilizzare un pezzo unico di metadati dagli input (ricevuti dal canale di input) come parte del nome del file di output. -Qui, per comodità, useremo solo il saluto stesso poiché è solo una stringa breve e lo antemeremo al nome del file di output di base. - -#### 2.2.1. Costruisci un nome di file di output dinamico - -Nel blocco di processo, apporta le seguenti modifiche al codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="6" hl_lines="9 13" - process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path "${greeting}-output.txt" - - script: - """ - echo '$greeting' > '$greeting-output.txt' - """ - } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="6" - process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path 'output.txt' - - script: - """ - echo '$greeting' > output.txt - """ - } - ``` - -Assicurati di sostituire `output.txt` sia nella definizione di output che nel blocco di comando `script:`. - -!!! tip - - Nella definizione di output, DEVI usare virgolette doppie attorno all'espressione del nome del file di output (NON virgolette singole), altrimenti fallirà. - -Questo dovrebbe produrre un nome di file di output univoco ogni volta che viene chiamato il processo, in modo che possa essere distinto dagli output di altre iterazioni dello stesso processo nella directory di output. - -#### 2.2.2. Esegui il workflow - -Eseguiamolo: - -```bash -nextflow run hello-channels.nf -``` - -Tornando alla vista di riepilogo, l'output ha di nuovo questo aspetto: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [astonishing_bell] DSL2 - revision: f57ff44a69 - -executor > local (3) -[2d/90a2e2] sayHello (1) | 3 of 3 ✔ -``` - -È importante sottolineare che ora abbiamo tre nuovi file oltre a quello che avevamo già nella directory `risultati`: - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── Hello-output.txt -├── Holà-output.txt -└── output.txt -``` - -Ognuno di loro ha i contenuti previsti: - -```console title="Bonjour-output.txt" linenums="1" -Bonjour -``` - -```console title="Hello-output.txt" linenums="1" -Hello -``` - -```console title="Holà-output.txt" linenums="1" -Holà -``` - -Successo! Ora possiamo aggiungere tutti i saluti che vorremmo senza preoccuparci che i file di output vengano sovrascritti. - -!!! note - - In pratica, nominare i file in base ai dati di input stessi è quasi sempre impraticabile. - Il modo migliore per generare nomi di file dinamici è passare i metadati a un processo insieme ai file di input. - I metadati sono in genere forniti tramite un "foglio campione" o equivalenti. - Imparerai come farlo più avanti nel tuo corso di formazione Nextflow. - -### Conclusioni - -Sai come alimentare più elementi di input attraverso un canale. - -### Cosa c'è dopo? - -Impara a usare un operatore per trasformare i contenuti di un canale. - ---- - -## 3. Usa un operatore per trasformare il contenuto di un canale - -In Nextflow, [operatori](https://www.nextflow.io/docs/latest/reference/operator.html) ci consentono di trasformare il contenuto di un canale. - -Ti abbiamo appena mostrato come gestire più elementi di input che sono stati codificati direttamente nella fabbrica del canale. -E se volessimo fornire quegli input multipli in una forma diversa? - -Ad esempio, immagina di impostare una variabile di input contenente una serie di elementi come questa: - -`greetings_array = ['Ciao','Bonjour','Holà']` - -Possiamo caricarlo nel nostro canale di output e aspettarci che funzioni? Scopriamolo. - -### 3.1. Fornire una serie di valori come input al canale - -Il buon senso suggerisce che dovremmo essere in grado di passare semplicemente una serie di valori invece di un singolo valore. Giusto? - -#### 3.1.1. Imposta la variabile di input - -Prendiamo la variabile `greetings_array` che abbiamo appena immaginato e rendiamola una realtà aggiungendola al blocco del workflow: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="27" hl_lines="3 4" - workflow { - - // declare an array of input greetings - greetings_array = ['Hello','Bonjour','Holà'] - - // create a channel for inputs - greeting_ch = channel.of('Hello','Bonjour','Holà') - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="27" - workflow { - - // create a channel for inputs - greeting_ch = channel.of('Hello','Bonjour','Holà') - ``` - -#### 3.1.2. Imposta l'array di saluti come input alla fabbrica del canale - -Sostituiremo i valori `'Hello','Bonjour', 'Holà'` attualmente codificati nella fabbrica del canale con il `greetings_array` che abbiamo appena creato. - -Nel blocco del workflow, apportare la seguente modifica: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="32" hl_lines="2" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="32" - // create a channel for inputs - greeting_ch = channel.of('Hello','Bonjour','Holà') - ``` - -#### 3.1.3. Esegui il workflow - -Proviamo a eseguire questo: - -```bash -nextflow run hello-channels.nf -``` - -Oh no! Nextflow genera un errore che inizia così: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 - -executor > local (1) -[22/57e015] sayHello (1) | 0 of 1 -ERROR ~ Error executing process > 'sayHello (1)' - -Caused by: - Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` -``` - -Sembra che Nextflow abbia tentato di eseguire una singola chiamata di processo, usando `[Hello, Bonjour, Holà]` come valore di stringa, invece di utilizzare le tre stringhe nell'array come valori separati. - -Come facciamo a ottenere Nextflow per decomprimere l'array e caricare le singole stringhe nel canale? - -### 3.2. Usa un operatore per trasformare i contenuti del canale - -È qui che entrano in gioco gli **operatori**. - -Se sfogli [elenco di operatori](https://www.nextflow.io/docs/latest/reference/operator.html) nella documentazione di Nextflow, troverai [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), che fa esattamente ciò di cui abbiamo bisogno: decomprimere il contenuto di un array e li emette come singoli elementi. - -!!! note - - È tecnicamente possibile ottenere gli stessi risultati utilizzando una fabbrica di canali diversa, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), che include una fase di mappatura implicita nella sua operazione. - Qui abbiamo scelto di non usarlo per dimostrare l'uso di un operatore su un caso d'uso abbastanza semplice. - -#### 3.2.1. Aggiungi l'operatore `flatten()` - -Per applicare l'operatore `flatten()` al nostro canale di input, lo apponiamo alla dichiarazione di fabbrica del canale. - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="31" hl_lines="3" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - .flatten() - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="31" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - - ``` - -Qui abbiamo aggiunto l'operatore sulla riga successiva per la leggibilità, ma puoi aggiungere operatori sulla stessa riga della fabbrica del canale se preferisci, come questo: `greeting_ch = channel.of(greetings_array).flatten()` - -#### 3.2.2. Aggiungi `view()` per ispezionare i contenuti del canale - -Potremmo eseguirlo subito per verificare se funziona, ma già che ci siamo, aggiungeremo anche un paio di operatori [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view), che ci consentono di ispezionare il contenuto di un canale. -Puoi pensare a `view()` come a uno strumento di debug, come un'istruzione `print()` in Python, o il suo equivalente in altre lingue. - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="31" hl_lines="3-5" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - .view { greeting -> "Before flatten: $greeting" } - .flatten() - .view { greeting -> "After flatten: $greeting" } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="31" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - .flatten() - ``` - -Stiamo usando un operatore _closure_ qui - le parentesi graffe. -Questo codice viene eseguito per ogni elemento nel canale. -Definiamo una variabile temporanea per il valore interno, qui chiamata `salunto` (potrebbe essere qualsiasi cosa). -Questa variabile viene utilizzata solo nell'ambito di tale chiusura. - -In questo esempio, `$greeting` rappresenta ogni singolo elemento caricato in un canale. - -!!! note "Nota su `$it`" - - In alcune pipeline potresti vedere una variabile speciale chiamata `$it` utilizzata all'interno delle chiusure dell'operatore. - Questa è una variabile _implicita_ che consente un accesso abbreviato alla variabile interna, - Senza bisogno di definirlo con un `->`. - - Preferiamo essere espliciti per aiutare la chiarezza del codice, in quanto tale la sintassi `$it` è scoraggiata e verrà lentamente eliminata dal linguaggio Nextflow. - -#### 3.2.3. Esegui il workflow - -Infine, puoi provare a eseguire di nuovo il workflow! - -```bash -nextflow run hello-channels.nf -``` - -Questa volta funziona E ci dà una visione aggiuntiva di come appaiono i contenuti del canale prima e dopo aver eseguito l'operatore `flatten()`: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [tiny_elion] DSL2 - revision: 1d834f23d2 - -executor > local (3) -[8e/bb08f3] sayHello (2) | 3 of 3 ✔ -Before flatten: [Hello, Bonjour, Holà] -After flatten: Hello -After flatten: Bonjour -After flatten: Holà -``` - -Vedi che otteniamo una singola istruzione `Before flatten:` perché a quel punto il canale contiene un elemento, l'array originale. -Quindi otteniamo tre istruzioni separate `Dopo appiattire:`, una per ogni saluto, che ora sono singoli elementi nel canale. - -È importante sottolineare che questo significa che ogni elemento può ora essere elaborato separatamente dal workflow. - -!!! tip - - Dovresti eliminare o commentare le istruzioni `view()` prima di andare avanti. - - ```groovy title="hello-channels.nf" linenums="31" - // crea un canale per gli input - greeting_ch = channel.of(greetings_array) - .flatten() - ``` - - Li abbiamo lasciati nel file di soluzione `hello-channels-3.nf` a scopo di riferimento. - -### Conclusioni - -Sai come usare un operatore come `flatten()` per trasformare il contenuto di un canale e come usare l'operatore `view()` per ispezionare il contenuto del canale prima e dopo aver applicato un operatore. - -### Cosa c'è dopo? - -Scopri come fare in modo che il workflow prenda un file come fonte di valori di input. - ---- - -## 4. Usa un operatore per analizzare i valori di input da un file CSV - -Spesso accade che, quando vogliamo eseguire su più ingressi, i valori di input sono contenuti in un file. -Ad esempio, abbiamo preparato un file CSV chiamato `greetings.csv` contenente diversi saluti, uno su ogni riga (come una colonna di dati). - -```csv title="greetings.csv" linenums="1" -Hello -Bonjour -Holà -``` - -Quindi ora dobbiamo modificare il nostro workflow per leggere i valori di un file del genere. - -### 4.1. Modifica lo script per aspettarti un file CSV come fonte di saluti - -Per iniziare, dovremo apportare due modifiche chiave allo script: - -- Cambia il parametro di input per puntare al file CSV -- Passa a una fabbrica di canali progettata per gestire un file - -#### 4.1.1. Cambia il parametro di input per puntare al file CSV - -Ricordi il parametro `params.greeting` che abbiamo impostato nella parte 1? -Lo aggiorneremo per puntare al file CSV contenente i nostri saluti. - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="25" hl_lines="4" - /* - * Pipeline parameters - */ - params.greeting = 'greetings.csv' - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="25" - /* - * Pipeline parameters - */ - params.greeting = ['Hello','Bonjour','Holà'] - ``` - -#### 4.1.2. Passa a una fabbrica di canali progettata per gestire un file - -Dal momento che ora vogliamo usare un file invece di semplici stringhe come input, non possiamo usare la fabbrica di canali `channel.of()` di prima. -Dobbiamo passare all'utilizzo di una nuova fabbrica di canali, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), che ha alcune funzionalità integrate per la gestione dei percorsi dei file. - -Nel blocco del flusso di lavoro, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="31" hl_lines="1 2" - // create a channel for inputs from a CSV file - greeting_ch = channel.fromPath(params.greeting) - - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="31" - // create a channel for inputs - greeting_ch = channel.of(greetings_array) - .flatten() - ``` - -#### 4.1.3. Esegui il workflow - -Proviamo a eseguire il workflow con la nuova fabbrica di canali e il file di input. - -```bash -nextflow run hello-channels.nf -``` - -Oh no, non funziona. Ecco l'inizio dell'output della console e il messaggio di errore: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [adoring_bhabha] DSL2 - revision: 8ce25edc39 - -[- ] sayHello | 0 of 1 -ERROR ~ Error executing process > 'sayHello (1)' - -Caused by: - File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/e3/c459b3c8f4029094cc778c89a4393d - - -Command executed: - - echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings. -``` - -The `Command executed:` bit (lines 13-15) is especially helpful here. - -Questo può sembrare un po' familiare. -Sembra che Nextflow abbia tentato di eseguire una singola chiamata di processo utilizzando il percorso del file stesso come valore stringa. -Quindi ha risolto correttamente il percorso del file, ma in realtà non ha analizzato il suo contenuto, che è quello che volevamo. - -Come facciamo a fare in modo che Nextflow apra il file e carichi i suoi contenuti nel canale? - -Sembra che abbiamo bisogno di un altro [operatore](https://www.nextflow.io/docs/latest/reference/operator.html)! - -### 4.2. Usa l'operatore `splitCsv()` per analizzare il file - -Guardando di nuovo l'elenco degli operatori, troviamo [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), che è progettato per analizzare e dividere il testo in formato CSV. - -#### 4.2.1. Applica `splitCsv()` al canale - -Per applicare l'operatore, lo assediamo alla linea di fabbrica del canale come in precedenza. - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="31" hl_lines="3-5" - // create a channel for inputs from a CSV file - greeting_ch = channel.fromPath(params.greeting) - .view { csv -> "Before splitCsv: $csv" } - .splitCsv() - .view { csv -> "After splitCsv: $csv" } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="31" - // create a channel for inputs from a CSV file - greeting_ch = channel.fromPath(params.greeting) - - ``` - -Come puoi vedere, includiamo anche le dichiarazioni prima/dopo la vista mentre ci siamo. - -#### 4.2.2. Esegui di nuovo il workflow - -Proviamo a eseguire il workflow con la logica di parsing CSV aggiunta. - -```bash -nextflow run hello-channels.nf -``` - -È interessante notare che anche questo fallisce, ma con un errore diverso. L'output e l'errore della console iniziano così: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [stoic_ride] DSL2 - revision: a0e5de507e - -executor > local (3) -[42/8fea64] sayHello (1) | 0 of 3 -Before splitCsv: /workspaces/training/hello-nextflow/greetings.csv -After splitCsv: [Hello] -After splitCsv: [Bonjour] -After splitCsv: [Holà] -ERROR ~ Error executing process > 'sayHello (2)' - -Caused by: - Missing output file(s) `[Bonjour]-output.txt` expected by process `sayHello (2)` - - -Command executed: - - echo '[Bonjour]' > '[Bonjour]-output.txt' -``` - -Questa volta Nextflow ha analizzato il contenuto del file (eviva!) Ma sono state aggiunte parentesi intorno ai saluti. - -Per farla breve, `splitCsv()` legge ogni riga in un array e ogni valore separato da virgole nella riga diventa un elemento nell'array. -Quindi qui ci dà tre array contenenti un elemento ciascuno. - -!!! note - - Anche se questo comportamento sembra scomodo in questo momento, sarà estremamente utile in seguito quando ci occuperemo di file di input con più colonne di dati. - -We could solve this by using `flatten()`, which you already know. -However, there's another operator called `map()` that's more appropriate to use here and is really useful to know; it pops up a lot in Nextflow pipelines. - -### 4.3. Usa l'operatore `map()` per estrarre i saluti - -L'operatore `map()` è un piccolo strumento molto pratico che ci consente di fare tutti i tipi di mappature ai contenuti di un canale. - -In questo caso, lo useremo per estrarre quell'elemento che vogliamo da ogni riga del nostro file. -Ecco come appare la sintassi: - -```groovy title="Syntax" -.map { item -> item[0] } -``` - -Ciò significa "per ogni elemento nel canale, prendi il primo di qualsiasi elemento che contiene". - -Quindi applichiamolo al nostro parsing CSV. - -#### 4.3.1. Applica `map()` al canale - -Nel blocco del workflow, apportare la seguente modifica del codice: - -=== "Dopo" - - ```groovy title="hello-channels.nf" linenums="31" hl_lines="6-8" - // create a channel for inputs from a CSV file - greeting_ch = channel.fromPath(params.greeting) - .view { csv -> "Before splitCsv: $csv" } - .splitCsv() - .view { csv -> "After splitCsv: $csv" } - .map { item -> item[0] } - .view { csv -> "After map: $csv" } - ``` - -=== "Prima" - - ```groovy title="hello-channels.nf" linenums="31" - // create a channel for inputs from a CSV file - greeting_ch = channel.fromPath(params.greeting) - .view { csv -> "Before splitCsv: $csv" } - .splitCsv() - .view { csv -> "After splitCsv: $csv" } - - ``` - -Ancora una volta includiamo un'altra chiamata `view()` per confermare che l'operatore fa ciò che ci aspettiamo. - -#### 4.3.2. Esegui il workflow ancora una volta - -Eseguiamolo ancora una volta: - -```bash -nextflow run hello-channels.nf -``` - -Questa volta dovrebbe funzionare senza errori. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-channels.nf` [tiny_heisenberg] DSL2 - revision: 845b471427 - -executor > local (3) -[1a/1d19ab] sayHello (2) | 3 of 3 ✔ -Before splitCsv: /workspaces/training/hello-nextflow/greetings.csv -After splitCsv: [Hello] -After splitCsv: [Bonjour] -After splitCsv: [Holà] -After map: Hello -After map: Bonjour -After map: Holà -``` - -Guardando l'output delle istruzioni `view()`, vediamo quanto segue: - -- Una singola istruzione `Before splitCsv:`: a quel punto il canale contiene un elemento, il percorso del file originale. -- Tre istruzioni separate `After splitCsv:`: una per ogni saluto, ma ognuna è contenuta all'interno di un array che corrisponde a quella riga nel file. -- Tre istruzioni separate `After map:`: una per ogni saluto, che ora sono elementi individuali nel canale. - -Puoi anche guardare i file di output per verificare che ogni saluto sia stato correttamente estratto ed elaborato attraverso il workflow. - -Abbiamo ottenuto lo stesso risultato di prima, ma ora abbiamo molta più flessibilità per aggiungere più elementi al canale di saluti che vogliamo elaborare modificando un file di input, senza modificare alcun codice. - -!!! note - - Qui abbiamo avuto tutti i saluti su una riga nel file CSV. - Puoi provare ad aggiungere più colonne al file CSV e vedere cosa succede; ad esempio, prova quanto segue: - - ```csv title="greetings.csv" - Hello,English - Bonjour,French - Holà,Spanish - ``` - - Puoi anche provare a sostituire `.map { item -> item[0] }` con `.flatten()` e vedere cosa succede a seconda di quante righe e colonne hai nel file di input. - - Imparerai approcci più avanzati per gestire input complessi in una formazione successiva. - -### Conclusioni - -Sai come usare gli operatori `splitCsv()` e `map()` per leggere in un file di valori di input e gestirli in modo appropriato. - -Più in generale, hai una comprensione di base di come Nextflow utilizza **canali** per gestire gli input dei processi e **operatori** per trasformare i loro contenuti. - -### Cosa c'è dopo? - -Fai una grande pausa, hai lavorato sodo in questo! -Quando sei pronto, passa alla parte 3 per imparare come aggiungere altri passaggi e collegarli insieme in un workflow corretto. diff --git a/docs/hello_nextflow/03_hello_workflow.it.md b/docs/hello_nextflow/03_hello_workflow.it.md deleted file mode 100644 index d1e18ad39e..0000000000 --- a/docs/hello_nextflow/03_hello_workflow.it.md +++ /dev/null @@ -1,868 +0,0 @@ -# Parte 3: Hello Workflow - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/02_hello_channels.md). -/// - -La maggior parte dei workflow nel mondo reale coinvolge più di un passaggio. -In questo modulo di formazione, imparerai come connettere i processi insieme in un workflow a più fasi. - -Questo ti insegnerà il modo Nextflow per ottenere i seguenti obiettivi: - -1. Far fluire i dati da un processo al successivo -2. Raccogliere gli output da più chiamate di processo in una singola chiamata -3. Passare più di un input a un processo -4. Gestire più output provenienti da un processo - -Per dimostrare ciò, continueremo a costruire sull'esempio del dominio indipendente Hello World delle Parti 1 e 2. -Questa volta, apporteremo le seguenti modifiche al nostro workflow per riflettere meglio su come le persone costruiscono flussi di lavoro reali: - -1. Aggiungere un secondo passaggio che converte il saluto in maiuscolo. -2. Aggiungere un terzo passaggio che raccoglie tutti i saluti trasformati e li scrive in un unico file. -3. Aggiungere un parametro per nominare il file di output finale e passarlo come input secondario al passaggio di raccolta. -4. Far sì che il passaggio di raccolta produca anche una statistica semplice su ciò che è stato elaborato. - ---- - -## 0. Warmup: Run `hello-workflow.nf` - -Useremo lo script del workflow `hello-workflow.nf` come punto di partenza. -Esso è equivalente allo script prodotto lavorando attraverso la Parte 2 di questo corso di formazione. - -Per essere sicuri che tutto funzioni, esegui lo script una volta prima di apportare qualsiasi modifica - -```bash -nextflow run hello-workflow.nf -``` - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-workflow.nf` [stupefied_sammet] DSL2 - revision: b9e466930b - -executor > local (3) -[2a/324ce6] sayHello (3) | 3 of 3 ✔ -``` - -Come in precedenza, troverai i file di output nella directory `results` (specificata dalla direttiva `publishDir`). - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── Hello-output.txt -└── Holà-output.txt -``` - -!!! note - - Potrebbe esserci anche un file chiamato `output.txt` se hai lavorato attraverso la Parte 2 nello stesso ambiente. - -Se tutto ha funzionato, sei pronto per imparare come assemblare un workflow a più fasi. - ---- - -## 1. Aggiungi un secondo step al workflow - -Aggiungeremo un passaggio per convertire il saluto in maiuscolo. -A tal fine, dobbiamo fare tre cose: - -- Definire il comando che useremo per eseguire la conversione in maiuscolo. -- Scrivere un nuovo processo che racchiuda il comando per la conversione in maiuscolo. -- Chiamare il nuovo processo nel blocco del workflow e configurarlo per prendere l'output del processo `sayHello()` come input. - -### 1.1. Definire il comando per la conversione in maiuscolo e testarlo nel terminale - -Per eseguire la conversione dei saluti in maiuscolo, useremo uno strumento UNIX classico chiamato `tr` per 'text replacement' (sostituzione del testo), con la seguente sintassi: - -```bash title="Syntax" -tr '[a-z]' '[A-Z]' -``` - -Questa è una sostituzione di testo molto semplice che non tiene conto delle lettere accentate, quindi ad esempio 'Holà' diventerà 'HOLà', ma andrà bene lo stesso per dimostrare i concetti di Nextflow, e questo è ciò che conta. - -Per testarlo, possiamo eseguire il comando `echo 'Hello World'` e passare il suo output al comando `tr`: - -```bash -echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt -``` - -Il risultato è un file di testo chiamato `UPPER-output.txt` che contiene la versione in maiuscolo della stringa `Hello World`: - -```console title="UPPER-output.txt" -HELLO WORLD -``` - -Questo è ciò che proveremo a fare con il nostro workflow. - -### 1.2. Scrivere il passaggio di conversione in maiuscolo come un processo Nextflow - -Possiamo modellare il nostro nuovo processo sul primo, poiché vogliamo usare gli stessi componenti. - -Aggiungi la seguente definizione del processo allo script del workflow: - -```groovy title="hello-workflow.nf" linenums="22" -/* - * Usa uno strumento di sostituzione del testo per convertire il saluto in maiuscolo. - */ -process convertToUpper { - - publishDir 'results', mode: 'copy' - - input: - path input_file - - output: - path "UPPER-${input_file}" - - script: - """ - cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' - """ -} -``` - -Qui, componiamo il secondo nome del file di output in base al nome del file di input, in modo simile a quanto abbiamo fatto inizialmente per l'output del primo processo. - -!!! note - - Nextflow determinerà l'ordine delle operazioni in base alla concatenazione degli input e degli output, quindi l'ordine delle definizioni dei processi nello script del flusso di lavoro non è importante. Tuttavia, ti consigliamo di essere gentile con i tuoi collaboratori e con il futuro te stesso, e cercare di scriverle in un ordine logico per motivi di leggibilità." - -### 1.3. Aggiungi una chiamata al nuovo processo nel blocco del workflow - -Ora dobbiamo dire a Nextflow di chiamare effettivamente il processo che abbiamo appena definito. - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="53" hl_lines="4 5" - // emit a greeting - sayHello(greeting_ch) - - // convert the greeting to uppercase - convertToUpper() - } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="53" - // emit a greeting - sayHello(greeting_ch) - } - ``` - -Questo non è ancora funzionante perché non abbiamo specificato cosa deve essere l'input per il processo `convertToUpper()`. - -### 1.4. Passare l'output del primo processo al secondo processo - -Ora dobbiamo fare in modo che l'output del processo `sayHello()` fluisca nel processo `convertToUpper()`. - -Comodamente, Nextflow impacchetta automaticamente l'output di un processo in un canale chiamato `<process>.out`. -Quindi, l'output del processo `sayHello` è un canale chiamato `sayHello.out`, che possiamo collegare direttamente alla chiamata a `convertToUpper()`. - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="56" hl_lines="2" - // convert the greeting to uppercase - convertToUpper(sayHello.out) - } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="56" - // convert the greeting to uppercase - convertToUpper() - } - ``` - -Per un caso semplice come questo (un output a un input), è tutto ciò che dobbiamo fare per connettere due processi! - -### 1.5. Esegui di nuovo il flusso di lavoro con `-resume` - -Eseguiamo di nuovo il flusso di lavoro utilizzando il flag `-resume`, poiché abbiamo già eseguito con successo il primo passaggio del workflow. - -```bash -nextflow run hello-workflow.nf -resume -``` - -Dovresti vedere il seguete output: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-workflow.nf` [disturbed_darwin] DSL2 - revision: 4e252c048f - -executor > local (3) -[79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ -[b3/d52708] convertToUpper (3) | 3 of 3 ✔ -``` - -Ora c'è una riga extra nell'output della console (riga 7), che corrisponde al nuovo processo che abbiamo appena aggiunto. - -Diamo un'occhiata all'interno della directory di lavoro di una delle chiamate al secondo processo. - -```console title="Directory contents" -work/b3/d52708edba8b864024589285cb3445/ -├── Bonjour-output.txt -> /workspaces/training/hello-nextflow/work/79/33b2f0af8438486258d200045bd9e8/Bonjour-output.txt -└── UPPER-Bonjour-output.txt -``` - -Troviamo due file di output: l'output del primo processo e l'output del secondo. - -L'output del primo processo è lì perché Nextflow lo ha messo in quella directory per avere tutto il necessario per l'esecuzione all'interno della stessa sottodirectory. -Tuttavia, in realtà si tratta di un collegamento simbolico che punta al file originale nella sottodirectory della prima chiamata al processo. -Per impostazione predefinita, quando si esegue su una singola macchina, come stiamo facendo qui, Nextflow utilizza collegamenti simbolici anziché copie per mettere in scena i file di input e i file intermedi. - -Troverai anche i file di output finali nella directory `results`, poiché abbiamo usato la direttiva `publishDir` anche nel secondo processo. - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── Hello-output.txt -├── Holà-output.txt -├── UPPER-Bonjour-output.txt -├── UPPER-Hello-output.txt -└── UPPER-Holà-output.txt -``` - -Pensiamo a come tutto ciò che abbiamo fatto è stato connettere l'output di `sayHello` all'input di `convertToUpper` e i due processi potrebbero essere eseguiti in serie. -Nextflow ha fatto il lavoro difficile di gestire i singoli file di input e output e passarli tra i due comandi per noi. - -Questa è una delle ragioni per cui i canali di Nextflow sono così potenti: si occupano del lavoro noioso coinvolto nel connettere i passaggi del workflow. - -### Conclusioni - -Ora sai come aggiungere un secondo passaggio che prende l'output del primo passaggio come input. - -### Cosa c'è dopo? - -Impara come raccogliere gli output da chiamate di processo in batch e passarli a un singolo processo. - ---- - -## 2. Aggiungi un terzo passo per raccogliere tutti i saluti - -Quando utilizziamo un processo per applicare una trasformazione a ciascuno degli elementi di un canale, come stiamo facendo qui con i saluti multipli, a volte vogliamo raccogliere gli elementi dal canale di output di quel processo e passarli a un altro processo che esegue una sorta di analisi o somma. - -Nel prossimo passo scriveremo semplicemente tutti gli elementi di un canale in un singolo file, utilizzando il comando UNIX `cat`. - -### 2.1. Definisci il comando di raccolta e testalo nel terminale - -Il passo di raccolta che vogliamo aggiungere al nostro flusso di lavoro utilizzerà il comando `cat` per concatenare i saluti in maiuscolo in un unico file. - -Eseguiamo il comando da solo nel terminale per verificare che funzioni come previsto, proprio come abbiamo fatto in precedenza. - -Esegui il seguente comando nel tuo terminale: - -```bash -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 -``` - -L'output è un file di testo chiamato `COLLECTED-output.txt` che contiene le versioni in maiuscolo dei saluti originali. - -```console title="COLLECTED-output.txt" -HELLO -BONJOUR -HOLà -``` - -Questo è il risultato che vogliamo ottenere con il nostro workflow. - -### 2.2. Crea un nuovo processo per eseguire il passo di raccolta - -Creiamo un nuovo processo e chiamamolo `collectGreetings()`. -Possiamo iniziare a scriverlo basandoci su quello precedente. - -#### 2.2.1. Scrivi le parti 'ovvie' del processo - -Aggiungi la seguente definizione del processo allo script del workflow: - -```groovy title="hello-workflow.nf" linenums="41" -/* - * Raccogli i saluti in maiuscolo in un unico file di output. - */ -process collectGreetings { - - publishDir 'results', mode: 'copy' - - input: - ??? - - output: - path "COLLECTED-output.txt" - - script: - """ - ??? > 'COLLECTED-output.txt' - """ -} -``` - -Questo è ciò che possiamo scrivere con sicurezza in base a quanto appreso finora. -Ma non è funzionale! -Manca la definizione dell'input e la prima metà del comando dello script perché dobbiamo capire come scrivere quella parte. - -#### 2.2.2. Definire gli input per `collectGreetings()` - -Dobbiamo raccogliere i saluti da tutte le chiamate al processo `convertToUpper()`. -Cosa sappiamo che possiamo ottenere dal passo precedente nel workflow? - -Il canale di output di `convertToUpper()` conterrà i percorsi dei singoli file che contengono i saluti in maiuscolo. -Questo corrisponde a uno slot di input; chiamiamolo `input_files` per semplicità. - -Nel blocco del processo, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="48" hl_lines="2" - input: - path input_files - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="48" - input: - ??? - ``` - -Nota che usiamo il prefisso `path` anche se ci aspettiamo che questo contenga più file. -Nextflow non ha problemi con questo, quindi non importa. - -#### 2.2.3. Comporre il comando di concatenazione - -Qui le cose potrebbero diventare un po' complicate, perché dobbiamo essere in grado di gestire un numero arbitrario di file di input. -In particolare, non possiamo scrivere il comando in anticipo, quindi dobbiamo dire a Nextflow come comporlo in fase di esecuzione in base agli input che fluiscono nel processo. - -In altre parole, se abbiamo un canale di input che contiene l'elemento `[file1.txt, file2.txt, file3.txt]`, dobbiamo fare in modo che Nextflow lo trasformi in `cat file1.txt file2.txt file3.txt`. - -Fortunatamente, Nextflow è abbastanza felice di farlo per noi se scriviamo semplicemente `cat ${input_files}` nel comando dello script. - -Nel blocco del processo, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" - script: - """ - cat ${input_files} > 'COLLECTED-output.txt' - """ - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="54" - script: - """ - ??? > 'COLLECTED-output.txt' - """ - ``` - -In teoria, questo dovrebbe gestire qualsiasi numero arbitrario di file di input. - -!!! tip - - Alcuni strumenti da riga di comando richiedono di fornire un argomento (come `-input`) per ogni file di input. - In tal caso, dovremmo fare un po' di lavoro extra per comporre il comando. - Puoi vedere un esempio di questo nel corso di formazione [Nextflow for Genomics](../../nf4_science/genomics/). - -<!--[AGGIUNGI LINK alla nota sopra] --> - -### 2.3. Aggiungi il passo di raccolta al workflow - -Ora dovremmo semplicemente chiamare il processo di raccolta sull'output del passo di trasformazione in maiuscolo. - -#### 2.3.1. Collega le chiamate ai processi - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" - // convert the greeting to uppercase - convertToUpper(sayHello.out) - - // collect all the greetings into one file - collectGreetings(convertToUpper.out) - } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="75" - // convert the greeting to uppercase - convertToUpper(sayHello.out) - } - ``` - -Questo collega l'output di `convertToUpper()` all'input di `collectGreetings()`. - -#### 2.3.2. Esegui il workflow con `-resume` - -Proviamolo. - -```bash -nextflow run hello-workflow.nf -resume -``` - -Viene eseguito con successo, compreso il terzo passo: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d - -executor > local (3) -[79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ -[99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ -[47/50fe4a] collectGreetings (1) | 3 of 3 ✔ -``` - -Tuttavia, guarda il numero di chiamate per collectGreetings() alla riga 8. -Ce ne aspettavamo solo una, ma ce ne sono tre. - -E dai un'occhiata anche ai contenuti del file di output finale: - -```console title="results/COLLECTED-output.txt" -Holà -``` - -Oh no. Il passo di raccolta è stato eseguito singolarmente su ogni saluto, il che NON è quello che volevamo. - -Dobbiamo fare qualcosa per dire esplicitamente a Nextflow che vogliamo che quel terzo passo venga eseguito su tutti gli elementi nel canale di output di `convertToUpper()`. - -### 2.4. Usa un operatore per raccogliere i saluti in un unico input - -Sì, ancora una volta la risposta al nostro problema è un operatore. - -In particolare, utilizzeremo l'operatore opportunamente chiamato [`collect()`] (https://www.nextflow.io/docs/latest/reference/operator.html#collect). - -#### 2.4.1. Aggiungi l'operatore `collect()` - -Questa volta sarà un po' diverso perché non stiamo aggiungendo l'operatore nel contesto di una fabbrica di canali, ma a un canale di output. - -Prendiamo `convertToUpper.out` e aggiungiamo l'operatore `collect()`, che diventa `convertToUpper.out.collect()`. -Possiamo collegarlo direttamente alla chiamata del processo `collectGreetings()`. - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="78" hl_lines="2" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect()) - } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="78" - // collect all the greetings into one file - collectGreetings(convertToUpper.out) - } - ``` - -#### 2.4.2. Aggiungi alcune dichiarazioni `view()` - -Includiamo anche un paio di dichiarazioni `view()` per visualizzare lo stato prima e dopo dei contenuti del canale. - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="78" hl_lines="4 6" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect()) - - // optional view statements - convertToUpper.out.view { greeting -> "Before collect: $greeting" } - convertToUpper.out.collect().view { greeting -> "After collect: $greeting" } - } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="78" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect()) - } - ``` - -Le dichiarazioni `view()` possono essere posizionate dove vuoi; noi le abbiamo messe dopo la chiamata per migliorare la leggibilità. - -#### 2.4.3. Esegui di nuovo il workflow con `-resume` - -Proviamolo: - -```bash -nextflow run hello-workflow.nf -resume -``` - -Viene eseguito con successo, anche se l'output del log potrebbe sembrare un po' più disordinato di così (l'abbiamo ripulito per migliorare la leggibilità). - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -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] -``` - -Questa volta il terzo passo è stato chiamato solo una volta! - -Guardando l'output delle dichiarazioni `view()`, vediamo quanto segue: - -- Tre dichiarazioni `Before collect:`, una per ciascun saluto: a quel punto i percorsi dei file sono elementi individuali nel canale. -- Una sola dichiarazione `After collect:`: i tre percorsi dei file sono ora raggruppati in un singolo elemento. - -Dai un'occhiata anche ai contenuti del file di output finale: - -```console title="results/COLLECTED-output.txt" -BONJOUR -HELLO -HOLà -``` - -Questa volta abbiamo tutti e tre i saluti nel file di output finale. Successo! Rimuovi le chiamate `view` opzionali per rendere gli output successivi meno verbosi. - -!!! note - - Se esegui questo processo più volte senza `-resume`, vedrai che l'ordine dei saluti cambia da un'esecuzione all'altra. - Questo ti mostra che l'ordine in cui gli elementi fluiscono attraverso le chiamate ai processi non è garantito essere consistente. - -### Conclusione - -Ora sai come raccogliere gli output da un gruppo di chiamate ai processi e passarli a un passo di analisi o somma congiunta. - -### Cosa c'è dopo? - -Impara come passare più di un input a un processo. - ---- - -## 3. Passare più di un input a un processo per nominare in modo univoco il file di output finale - -Vogliamo essere in grado di dare al file di output finale un nome specifico, in modo da poter elaborare successivi lotti di saluti senza sovrascrivere i risultati finali. - -A tal fine, apporteremo le seguenti modifiche al workflow: - -- Modificare il processo di raccolta per accettare un nome definito dall'utente per il file di output -- Aggiungere un parametro da riga di comando al workflow e passarne il valore al processo di raccolta - -### 3.1. Modificare il processo di raccolta per accettare un nome definito dall'utente per il file di output - -Dobbiamo dichiarare l'input aggiuntivo e integrarlo nel nome del file di output. - -#### 3.1.1. Dichiarare l'input aggiuntivo nella definizione del processo - -Buone notizie: possiamo dichiarare tutte le variabili di input che vogliamo. -Chiamiamo questa `batch_name`. - -Nel blocco del processo, apportiamo la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="48" hl_lines="3" - input: - path input_files - val batch_name - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="48" - input: - path input_files - ``` - -Puoi configurare i tuoi processi per aspettarsi quanti input desideri. -Più avanti, imparerai come gestire gli input obbligatori e opzionali. - -#### 3.1.2. Utilizzare la variabile `batch_name` nel nome del file di output - -Nel blocco del processo, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="52" hl_lines="2 6" - output: - path "COLLECTED-${batch_name}-output.txt" - - script: - """ - cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' - """ - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="52" - output: - path "COLLECTED-output.txt" - - script: - """ - cat ${input_files} > 'COLLECTED-output.txt' - """ - ``` - -Questo configura il processo per utilizzare il valore di `batch_name` per generare un nome file specifico per il file di output finale del workflow. - -### 3.2. Aggiungere un parametro `batch` da riga di comando - -Ora abbiamo bisogno di un modo per fornire il valore di `batch_name` e passarne il valore alla chiamata del processo. - -#### 3.2.1. Utilizzare `params` per configurare il parametro - -Sai già come utilizzare il sistema `params` per dichiarare i parametri CLI. -Usiamo questo sistema per dichiarare un parametro `batch` (con un valore predefinito, perché siamo pigri). - -Nella sezione dei parametri della pipeline, apporta le seguenti modifiche al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="61" hl_lines="5" - /* - * Pipeline parameters - */ - params.greeting = 'greetings.csv' - params.batch = 'test-batch' - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="61" - /* - * Pipeline parameters - */ - params.greeting = 'greetings.csv' - ``` - -Ricorda che puoi sovrascrivere il valore predefinito specificando un valore con `--batch` sulla riga di comando. - -#### 3.2.2. Passare il parametro `batch` al processo - -Per fornire il valore del parametro al processo, dobbiamo aggiungerlo nella chiamata del processo. - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="80" hl_lines="2" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect(), params.batch) - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="80" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect()) - ``` - -!!! warning - - Devi fornire gli input a un processo NELLO STESSO ORDINE ESATTO in cui sono elencati nel blocco di definizione degli input del processo. - -### 3.3. Eseguire il workflow - -Proviamo a eseguire questo con un nome di batch sulla riga di comando. - -```bash -nextflow run hello-workflow.nf -resume --batch trio -``` - -Viene eseguito con successo: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c - -executor > local (1) -[79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ -[99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ -[b5/f19efe] collectGreetings | 1 of 1 ✔ -``` - -E produce l'output desiderato: - -```console title="bash" -cat results/COLLECTED-trio-output.txt -``` - -```console title="Output" -HELLO -BONJOUR -HOLà -``` - -Ora, le esecuzioni successive su altri lotti di input non sovrascriveranno i risultati precedenti (purché specifichiamo correttamente il parametro). - -### Cosa devi ricordare - -Ora sai come passare più di un input a un processo. - -### Cosa succede dopo? - -Impara come emettere più output e gestirli comodamente. - ---- - -## 4. Aggiungere un output al passo di raccolta - -Quando un processo produce un solo output, è facile accedervi (nel blocco del workflow) utilizzando la sintassi `<process>.out`. -Quando ci sono due o più output, il metodo predefinito per selezionare un output specifico è usare l'indice corrispondente (basato su zero); per esempio, useresti `<process>.out[0]` per ottenere il primo output. -Questo però non è particolarmente comodo, perché è facile selezionare l'indice sbagliato. - -Vediamo come possiamo selezionare e utilizzare un output specifico di un processo quando ce ne sono più di uno. - -Per scopi dimostrativi, supponiamo che vogliamo contare e segnalare il numero di saluti che vengono raccolti per un dato lotto di input. - -A tal fine, apporteremo le seguenti modifiche al workflow: - -- Modificare il processo per contare e produrre il numero di saluti -- Una volta che il processo è stato eseguito, selezionare il conteggio e riportarlo utilizzando `view` (nel blocco del workflow) - -### 4.1. Modificare il processo per contare e produrre il numero di saluti - -Questo richiederà due modifiche principali alla definizione del processo: dobbiamo trovare un modo per contare i saluti, poi dobbiamo aggiungere quel conteggio al blocco `output` del processo. - -#### 4.1.1. Contare il numero di saluti raccolti - -Fortunatamente, Nextflow ci consente di aggiungere codice arbitrario nel blocco `script:` della definizione del processo, che risulta molto utile per fare cose come questa. - -Ciò significa che possiamo utilizzare la funzione incorporata `size()` per ottenere il numero di file nell'array `input_files`. - -Nel blocco del processo `collectGreetings`, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2" - script: - count_greetings = input_files.size() - """ - cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' - """ - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="55" - script: - """ - cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' - """ - ``` - -La variabile `count_greetings` verrà calcolata durante l'esecuzione. - -#### 4.1.2. Emissione del conteggio come output con nome - -In linea di principio, tutto ciò che dobbiamo fare è aggiungere la variabile `count_greetings` al blocco `output:`. - -Tuttavia, mentre ci siamo, aggiungeremo anche alcune etichette `emit:` alle nostre dichiarazioni di output. Queste ci permetteranno di selezionare gli output per nome, invece di dover usare indici posizionali. - -Nel blocco del processo, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="52" hl_lines="2 3" - output: - path "COLLECTED-${batch_name}-output.txt" , emit: outfile - val count_greetings , emit: count - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="52" - output: - path "COLLECTED-${batch_name}-output.txt" - ``` - -Le etichette `emit:` sono opzionali, e avremmo potuto aggiungere un'etichetta solo a uno degli output. -Ma, come si suol dire, perché non entrambi? - -### 4.2. Segnalare l'output alla fine del workflow - -Ora che abbiamo due output provenienti dal processo `collectGreetings`, l'output `collectGreetings.out` contiene due canali: - -- `collectGreetings.out.outfile` contiene il file di output finale -- `collectGreetings.out.count` contiene il conteggio dei saluti - -Potremmo inviare uno o entrambi questi output a un altro processo per ulteriori elaborazioni. Tuttavia, per concludere il lavoro, useremo semplicemente `view()` per dimostrare che possiamo accedere e segnalare il conteggio dei saluti. - -Nel blocco del workflow, apporta la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-workflow.nf" linenums="82" hl_lines="4 5" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect(), params.batch) - - // emit a message about the size of the batch - collectGreetings.out.count.view { num_greetings -> "There were $num_greetings greetings in this batch" } - ``` - -=== "Prima" - - ```groovy title="hello-workflow.nf" linenums="82" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect(), params.batch) - ``` - -!!! note - - Esistono altri modi per ottenere un risultato simile, inclusi alcuni più eleganti, come l'operatore `count()`, ma questo ci permette di mostrare come gestire più output, che è ciò che ci interessa. - -### 4.3. Eseguire il workflow - -Proviamo a eseguire questo con l'attuale lotto di saluti. - -```bash -nextflow run hello-workflow.nf -resume --batch trio -``` - -Viene eseguito con successo: - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-workflow.nf` [evil_sinoussi] DSL2 - revision: eeca64cdb1 - -[d6/cdf466] sayHello (1) | 3 of 3, cached: 3 ✔ -[99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ -[9e/1dfda7] collectGreetings | 1 of 1, cached: 1 ✔ -There were 3 greetings in this batch -``` - -L'ultima riga (riga 8) mostra che abbiamo correttamente recuperato il conteggio dei saluti elaborati. -Sentiti libero di aggiungere più saluti al CSV e vedere cosa succede. - -### Cosa devi ricordare - -Ora sai come far emettere a un processo un output con nome e come accedervi dal blocco del workflow. - -Più in generale, comprendi i principi chiave per connettere i processi in modi comuni. - -### Cosa succede dopo? - -Fai una lunga pausa, te la sei guadagnata. -Quando sei pronto, passa alla Parte 4 per imparare a modularizzare il tuo codice per una migliore manutenibilità e efficienza del codice. diff --git a/docs/hello_nextflow/04_hello_modules.it.md b/docs/hello_nextflow/04_hello_modules.it.md deleted file mode 100644 index 7587bfd569..0000000000 --- a/docs/hello_nextflow/04_hello_modules.it.md +++ /dev/null @@ -1,384 +0,0 @@ -# Parte 4: Hello Modules - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/03_hello_workflow.md). -/// - -Questa sezione spiega come organizzare il codice del workflow per rendere più efficiente e sostenibile lo sviluppo e la manutenzione della pipeline. -In particolare, dimostreremo come utilizzare i **moduli**. - -In Nextflow, un **modulo** è una singola definizione di processo incapsulata in un file di codice indipendente. -Per utilizzare un modulo in un workflow, basta aggiungere una singola riga di dichiarazione di importazione al file di codice del workflow; quindi è possibile integrare il processo nel workflow come si farebbe normalmente. - -Quando abbiamo iniziato a sviluppare il nostro workflow, abbiamo inserito tutto in un unico file di codice. - -La suddivisione dei processi in singoli moduli consente di riutilizzare le definizioni dei processi in più workflow senza produrre più copie del codice. -Questo rende il codice più condivisibile, flessibile e manutenibile. - -!!! note - - È anche possibile incapsulare una sezione di un workflow come un "sottoflusso" che può essere importato in una pipeline più ampia, ma ciò esula dallo scopo di questo corso. - ---- - -## 0. Riscaldamento: Eseguire `hello-modules.nf` - -Utilizzeremo lo script del workflow `hello-modules.nf` come punto di partenza. -È equivalente allo script prodotto lavorando alla Parte 3 di questo corso di formazione. - -Per assicurarsi che tutto funzioni, eseguire lo script una volta prima di apportare qualsiasi modifica: - -```bash -nextflow run hello-modules.nf -``` - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-modules.nf` [festering_nobel] DSL2 - revision: eeca64cdb1 - -executor > local (7) -[25/648bdd] sayHello (2) | 3 of 3 ✔ -[60/bc6831] convertToUpper (1) | 3 of 3 ✔ -[1a/bc5901] collectGreetings | 1 of 1 ✔ -there were 3 greetings in this batch -``` - -Come in precedenza, i file di output si trovano nella directory `results` (specificata dalla direttiva `publishDir`). - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── COLLECTED-output.txt -├── COLLECTED-test-batch-output.txt -├── COLLECTED-trio-output.txt -├── Hello-output.txt -├── Holà-output.txt -├── UPPER-Bonjour-output.txt -├── UPPER-Hello-output.txt -└── UPPER-Holà-output.txt -``` - -!!! note - - Potrebbe anche essere rimasto un file chiamato `output.txt` se si è lavorato alla Parte 2 nello stesso ambiente. - -Se questo ha funzionato, siete pronti per imparare a modularizzare il codice del workflow. - ---- - -## 1. Creare una cartella per memorizzare i moduli - -È buona norma memorizzare i moduli in una directory specifica. -Si può chiamare questa cartella come si vuole, ma la convenzione è di chiamarla `modules/`. - -```bash -mkdir modules -``` - -!!! note - - Qui mostriamo come usare i moduli locali, cioè i moduli memorizzati localmente nello stesso repository del resto del codice del workflow, in contrasto con i moduli remoti, che sono memorizzati in altri repository (remoti). Per maggiori informazioni sui moduli remoti, si veda la [documentazione](https://www.nextflow.io/docs/latest/module.html). - ---- - -## 2. Creare un modulo per `sayHello()` - -Nella sua forma più semplice, trasformare un processo esistente in un modulo è poco più di un'operazione di copia-incolla. -Creeremo un file stub per il modulo, copieremo il codice pertinente e lo cancelleremo dal file principale del workflow. - -A questo punto, basterà aggiungere una dichiarazione di importazione, in modo che Nextflow sappia che deve inserire il codice in questione in fase di esecuzione. - -### 2.1. Creare un file stub per il nuovo modulo - -Creiamo un file vuoto per il modulo, chiamato `sayHello.nf`. - -```bash -touch modules/sayHello.nf -``` - -Questo ci dà un posto dove mettere il codice del processo. - -### 2.2. Spostare il codice del processo `sayHello' nel file del modulo - -Copiare l'intera definizione del processo dal file del workflow al file del modulo, assicurandosi di copiare anche lo shebang `#!/usr/bin/env nextflow`. - -```groovy title="modules/sayHello.nf" linenums="1" -#!/usr/bin/env nextflow - -/* - * Usa echo per stampare 'Hello World!' A un file. - */ -process sayHello { - - publishDir 'results', mode: 'copy' - - input: - val greeting - - output: - path "${greeting}-output.txt" - - script: - """ - echo '$greeting' > '$greeting-output.txt' - """ -} -``` - -Una volta fatto ciò, eliminate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. - -### 2.3. Aggiungere una dichiarazione di importazione prima del blocco del workflow - -La sintassi per importare un modulo locale è abbastanza semplice: - -```groovy title="Syntax: Import declaration" -include { <MODULE_NAME> } from '<path_to_module>' -``` - -Inseriamo questo blocco sopra il blocco del workflow e compiliamolo in modo appropriato. - -=== "Dopo" - - ```groovy title="hello-modules.nf" linenums="50" hl_lines="1 2" - // Include modules - include { sayHello } from './modules/sayHello.nf' - - workflow { - ``` - -=== "Prima" - - ```groovy title="hello-modules.nf" linenums="50" - workflow { - ``` - -### 2.4. Eseguite il workflow per verificare che faccia la stessa cosa di prima - -Stiamo eseguendo il workflow essenzialmente con lo stesso codice e gli stessi input di prima, quindi eseguiamolo con il flag `resume` e vediamo cosa succede. - -```bash -nextflow run hello-modules.nf -resume -``` - -L'esecuzione è molto rapida perché tutto viene memorizzato nella cache. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 - -[f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ -[3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ -[1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ -there were 3 greetings in this batch -``` - -Nextflow ha riconosciuto che il lavoro da fare è sempre lo stesso, anche se il codice è suddiviso in più file. - -### Conclusione - -Sapete come estrarre un processo in un modulo locale e sapete che questo non rompe la riprendibilità del workflow. - -### Cosa c'è dopo? - -Esercitatevi a creare altri moduli. -Una volta che ne avete fatto uno, potete farne un milione... -Ma per ora facciamone solo altri due. - ---- - -## 3. Modularizzare il processo `convertToUpper()` - -### 3.1. Creare un file stub per il nuovo modulo - -Creare un file vuoto per il modulo, chiamato `convertToUpper.nf`. - -```bash -touch modules/convertToUpper.nf -``` - -### 3.2. Spostare il codice del processo `convertToUpper` nel file del modulo - -Copiare l'intera definizione del processo dal file del workflow al file del modulo, assicurandosi di copiare anche lo shebang `#!/usr/bin/env nextflow`. - -```groovy title="modules/convertToUpper.nf" linenums="1" -#!/usr/bin/env nextflow - -/* - * Utilizzare uno strumento di sostituzione del testo per convertire il saluto in maiuscolo. - */ -process convertToUpper { - - publishDir 'results', mode: 'copy' - - input: - path input_file - - output: - path "UPPER-${input_file}" - - script: - """ - cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' - """ -} -``` - -Una volta fatto ciò, eliminate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. - -### 3.3. Aggiungere una dichiarazione di importazione prima del blocco del workflow - -Inserite la dichiarazione di importazione sopra il blocco del workflow e compilatela in modo appropriato. - -=== "Dopo" - - ```groovy title="hello-modules.nf" linenums="31" hl_lines="3" - // Include modules - include { sayHello } from './modules/sayHello.nf' - include { convertToUpper } from './modules/convertToUpper.nf' - - workflow { - ``` - -=== "Prima" - - ```groovy title="hello-modules.nf" linenums="31" - // Include modules - include { sayHello } from './modules/sayHello.nf' - - workflow { - ``` - -### 3.4. Eseguite il workflow per verificare che faccia la stessa cosa di prima - -Eseguire questa operazione con il flag `-resume`. - -```bash -nextflow run hello-modules.nf -resume -``` - -Il risultato dovrebbe essere lo stesso di quello precedente. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 - -[c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ -[60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ -[1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ -There were 3 greetings in this batch -``` - -Due fatti, uno ancora da fare! - ---- - -## 4. Modularizzare il processo `collectGreetings()` - -### 4.1. Creare un file stub per il nuovo modulo - -Creare un file vuoto per il modulo, chiamato `collectGreetings.nf`. - -```bash -touch modules/collectGreetings.nf -``` - -### 4.2. Spostare il codice del processo `collectGreetings` nel file del modulo### - -Copiare l'intera definizione del processo dal file del workflow al file del modulo, assicurandosi di copiare anche lo shebang `#!/usr/bin/env nextflow`. - -```groovy title="modules/collectGreetings.nf" linenums="1" -#!/usr/bin/env nextflow - -/* - * Raccogli i saluti maiuscoli in un singolo file di output - */ -process collectGreetings { - - publishDir 'results', mode: 'copy' - - input: - path input_files - val batch_name - - output: - path "COLLECTED-${batch_name}-output.txt" , emit: outfile - val count_greetings , emit: count - - script: - count_greetings = input_files.size() - """ - cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' - """ -} -``` - -Una volta fatto ciò, eliminate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. - -### 4.3. Aggiungere una dichiarazione di importazione prima del blocco del workflow### - -Inserite la dichiarazione di importazione sopra il blocco del workflow e compilatela in modo appropriato. - -=== "Dopo" - - ```groovy title="hello-modules.nf" linenums="9" hl_lines="4" - // Include modules - include { sayHello } from './modules/sayHello.nf' - include { convertToUpper } from './modules/convertToUpper.nf' - include { collectGreetings } from './modules/collectGreetings.nf' - - workflow { - ``` - -=== "Prima" - - ```groovy title="hello-modules.nf" linenums="9" - // Include modules - include { sayHello } from './modules/sayHello.nf' - include { convertToUpper } from './modules/convertToUpper.nf' - - workflow { - ``` - -### 4.4. Eseguite il workflow per verificare che faccia la stessa cosa di prima - -Eseguire questa operazione con il flag `-resume`. - -```bash -nextflow run hello-modules.nf -resume -``` - -Il risultato dovrebbe essere lo stesso di quello precedente. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f - -[f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ -[3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ -[1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ -There were 3 greetings in this batch -``` - -### Conclusione - -Sapete come modulare più processi in un workflow. - -Congratulazioni, avete fatto tutto questo lavoro e non è cambiato assolutamente nulla nel funzionamento della pipeline! - -A parte gli scherzi, ora il codice è più modulare e se si decide di scrivere un'altra pipeline che richiama uno di questi processi, è sufficiente digitare una breve dichiarazione di importazione per utilizzare il modulo corrispondente. -È meglio che copiare il codice, perché se in seguito si decide di migliorare il modulo, tutte le pipeline erediteranno i miglioramenti. - -### Cosa c'è dopo? - -Fate una breve pausa se ne avete voglia. -Quando siete pronti, passate alla Parte 5 per imparare a usare i container per gestire le dipendenze del software in modo più pratico e riproducibile. diff --git a/docs/hello_nextflow/05_hello_containers.it.md b/docs/hello_nextflow/05_hello_containers.it.md deleted file mode 100644 index 6e5e232046..0000000000 --- a/docs/hello_nextflow/05_hello_containers.it.md +++ /dev/null @@ -1,677 +0,0 @@ -# Parte 5: Hello Containers - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/04_hello_modules.md). -/// - -Nella parte 1-4 del corso di training, hai imparato come usare gli elementi di base di Nextflow per assemblare un semplice workflow capace di processare alcuni testi, a fare esecuzioni parallele se ci sono più input e collezionare i risultati per esecuzioni future. - -Tuttavia, si era limitati agli strumenti unix di base disponibili nel proprio ambiente. -Le attività del mondo reale spesso richiedono vari strumenti e pacchetti non inclusi default. -In genere, è necessario installare questi strumenti, gestire le loro dipendenze e risolvere eventuali conflitti. - -Tutto ciò è molto noiso e fastidioso, quindi vi mostreremo come usare i container per risolvere questo problema in modo molto più comodo. - -Un container è un'unità di software leggera, autonoma ed eseguibile creata da un'immagine di container che incluede tutto ciò che serve per eseguitre un'applicazione, compresi codici librerie di sistema e impostazioni. - -!!! note - - We'll be teaching this using the technology [Docker](https://www.docker.com/get-started/), but Nextflow supports [several other container technologies](https://www.nextflow.io/docs/latest/container.html#) as well. - ---- - -## 0. Warmup: Eseguire `hello-containers.nf` - -Utilizzeremo lo script del workflow hello-containers.nf come punto di paretnza per la seconda sezione. - -Just to make sure everything is working, run the script once before making any changes: -È equivalente allo script prodotto lavorando alla Parte 4 di questo corso di formazione. - -```bash -nextflow run hello-containers.nf -``` - -Questo dovrebbe produrre il seguente risultato: - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-containers.nf` [tender_becquerel] DSL2 - revision: f7cat8e223 - -executor > local (7) -[bd/4bb541] sayHello (1) [100%] 3 of 3 ✔ -[85/b627e8] convertToUpper (3) [100%] 3 of 3 ✔ -[7d/f7961c] collectGreetings [100%] 1 of 1 ✔ -``` - -Come in precendenza, i file output si trovano nella directory `results` (specificata dalla direttiva `publishDir`). - -```console title="Directory contents" -results -├── Bonjour-output.txt -├── COLLECTED-output.txt -├── COLLECTED-test-batch-output.txt -├── COLLECTED-trio-output.txt -├── Hello-output.txt -├── Holà-output.txt -├── UPPER-Bonjour-output.txt -├── UPPER-Hello-output.txt -└── UPPER-Holà-output.txt -``` - -!!! note - - There may also be a file named `output.txt` left over if you worked through Part 2 in the same environment. - -Se questo ha funzionato, siete pronti per imparare a usare i container. - ---- - -## 1. Utilizzare un container 'manualmente' - -Quello che vogliamo fare è aggiungere un passo al nostro workflow che utilizzerà un container per l'esecuzione. - -Tuttavia, prima di iniziare a usarli in Nextflow, esamineremo alcuni concetti e operazioni di base, per consolidare la comprensione di cosa sono i container. - -### 1.1. Estrarre l'immagine del container - -Per utilizzare un container, di solito si scarica o si 'pull' un'immagine del container da un reggistro dei container e poi si eseguel'immagien del container per creare un'istanza del container. - -La sintassi generale è la seguente: - -```bash title="Syntax" -docker pull '<container>' -``` - -La parte `docker pull` è l'istruzione al sistema di container di prelevare un'immagine di container da un repository. - -La parte `'<container>'` è l'indirizzo URI dell'imagine del conatiner. - -a titolo d'esempio estraiamo un'immagine ocntainer che contenga [cowpy](https://github.com/jeffbuttars/cowpy), un'implementazione di Python di uno strumento chiamato cowsay che genera arte ASCII per visualizzare in modo divertente input di testo arbitrari. - -Esistono vari repository dove è possibile trovare i container pubblicati. -Noi abbiamo utilizzato il servizio di [Seqera Containers](https://seqera.io/containers/) per generare quest'immagine Docker container dal pacchetto cowpy Conda: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. - -Eseguire il comando di pull richiesto: - -```bash -docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' -``` - -In questo modo si ottiene il seguente output di console mebntro il sistema scarica le immagini: - -```console title="Output" -Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally -131d6a1b707a8e65: Pulling from library/cowpy -dafa2b0c44d2: Pull complete -dec6b097362e: Pull complete -f88da01cff0b: Pull complete -4f4fb700ef54: Pull complete -92dc97a3ef36: Pull complete -403f74b0f85e: Pull complete -10b8c00c10a5: Pull complete -17dc7ea432cc: Pull complete -bb36d6c3110d: Pull complete -0ea1a16bbe82: Pull complete -030a47592a0a: Pull complete -622dd7f15040: Pull complete -895fb5d0f4df: Pull complete -Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 -Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 -community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 -``` - -Una volta completato il download, si ha una copia locale dell'immagine del container. - -### 1.2. Utilizzare il container per eseguire cowpy come comando singolo - -Un modo molto comune di utilizzare i container è quello di eseguirli direttamente, cioè in modo non interattivo. -Questo è ottimo per eseguire comandi una tantum. - -La sintassi generale è la seguente: - -```bash title="Syntax" -docker run --rm '<container>' [tool command] -``` - -La parte `docker run --rm '<container>'` è l'istruzione al sistema di container di creare un'istanza da un'immagine di container ed eseguire un comando in essa. -Il flag `--rm` indica al sistema di chiudere l'istanza del container al termine del comando. - -La sintassi di `[tool command]` dipende dallo strumento che si sta usando e da come è impostato il conatiner. -Cominciamo con `cowpy`. - -Completamente assemblato, il comadno di esecuzione del container si presenta come segue: - -```bash -docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy -``` - -Esegui per produrre il seguente output: - -```console title="Output" - ______________________________________________________ -< Cowacter, eyes:default, tongue:False, thoughts:False > - ------------------------------------------------------ - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || -``` - -Il sistema avvia il container, esegue il comando cowpy con i suoi parametri, invia l'output alla console e infine chiude l'istanza del container. - -### 1.3. Ustilizzare il container per eseguire cowpy in modo interattivo - -E anche possibile eseguire un conatiner in modo interattivo, in modo da avere un prompt di shell all'interno del container e poter giocare con i comandi. - -#### 1.3.1. Avviare il container - -Per eseguire il container in modo interattivo, basta aggiungere `-it` al comando `docker run'. -Facoltativamente, possiamo specificare la shell che vogliamo usare all'inetrno del conatiner, aggiungendo ad esempio `/bin/bash` al comando. - -```bash -docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash -``` - -Notate che il prompt cambia in qualcosa di simile a`(base) root@b645838b3314:/tmp#`, che indica che ora siete all'interno del conatienr. - -E' possibile verificarlo eseguendo 'ls'per elencare il contenuto della directory: - -```bash -ls / -``` - -```console title="Output" -bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var -``` - -Si può notare che il filesystem all'interno del conatiner è diverso da quello del sistema host. . - -!!! note - - Quando esegui un container, questo è isolato dal sistema host per impostazione predefinita. - Ciò significa che il container non può accedere ad alcun file sul sistema host a meno che tu non glielo consenta esplicitamente. - - - Imparerai come farlo in un minuto. - -#### 1.3.2. Eseguire i comandi dello strumento desiderato - -Ora che sei all'interno del container, puoi eseguire direttamente il comando `cowpy` e fornirgli alcuni parametri. -Ad esempio, la documentazione dello strumento afferma che possiamo modificare il carattere ('cowacter') con `-c`. - -```bash -cowpy "Hello Containers" -c tux -``` - -Ora l'output mostra il pinguino di Linux, Tux, invece della mucca predefinita, perché abbiamo specificato il parametro `-c tux`. - -```console title="Output" - __________________ -< Hello Containers > - ------------------ - \ - \ - .--. - |o_o | - |:_/ | - // \ \ - (| | ) - /'\_ _/`\ - \___)=(___/ -``` - -Poiché ti trovi all'interno del container, puoi eseguire il comando cowpy tutte le volte che vuoi, variando i parametri di input, senza dover utilizzare i comandi Docker. - -!!! Tip - - Utilizzare il flag '-c' per selezionare un carattere diverso, incluso: - `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` - -Questo è carino. Sarebbe ancora più carino se potessimo alimentare il nostro `greetings.csv` come input in questo. -Ma poiché non abbiamo accesso al file system, non possiamo farlo. - -Risolviamolo. - -#### 1.3.3. Uscire dal container - -Per uscire dal container, puoi digitare `exit` al prompt oppure usare la scorciatoia da tastiera ++ctrl+d++. - -```bash -exit -``` - -Il prompt dovrebbe ora tornare a essere quello che era prima dell'avvio del container. - -#### 1.3.4. Montare i dati nel container - -Quando si esegue un container, questo è isolato dal sistema host per impostazione predefinita. -Ciò significa che il container non può accedere ad alcun file sul sistema host a meno che non gli venga esplicitamente consentito di farlo. - -Un modo per farlo è **montare** un **volume** dal sistema host nel container utilizzando la seguente sintassi: - -```bash title="Syntax" --v <outside_path>:<inside_path> -``` - -Nel nostro caso `<outside_path>` sarà la directory di lavoro corrente, quindi possiamo semplicemente usare un punto (`.`), e `<inside_path>` è solo un nome che inventiamo; Chiamiamolo `/data`. - -Per montare un volume, sostituiamo i percorsi e aggiungiamo l'argomento di montaggio del volume al comando docker run come segue: - -```bash -docker run --rm -it -v .:/data 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash -``` - -Questo monta la directory di lavoro corrente come un volume che sarà accessibile sotto `/data` all'interno del container. - -Puoi verificare che funzioni elencando il contenuto di `/data`: - -```bash -ls /data -``` - -A seconda della parte di questa formazione che hai già svolto in precedenza, il risultato riportato di seguito potrebbe essere leggermente diverso. - -```console title="Output" -demo-params.json hello-channels.nf hello-workflow.nf modules results -greetings.csv hello-modules.nf hello-world.nf nextflow.config work -``` - -<!-- ls output may need to be updated --> - -Ora puoi vedere il contenuto della directory `data` dall'interno del container, incluso il file `greetings.csv`. - -Questo ha effettivamente creato un tunnel attraverso il muro del container che puoi usare per accedere a quella parte del tuo file system. - -#### 1.3.5. Utilizza i dati montati - -Ora che abbiamo montato la directory `data` nel container, possiamo usare il comando `cowpy` per visualizzare il contenuto del file `greetings.csv`. - -Per fare questo, useremo`cat /data/greetings.csv | ` per inviare il contenuto del file CSV al comando `cowpy`. - -```bash -cat /data/greetings.csv | cowpy -c turkey -``` - -Questo produce l'ASCII art desiderata di un tacchino che snocciola i nostri saluti di esempio: - -```console title="Output" - _________ -/ Hello \ -| Bonjour | -\ Holà / - --------- - \ ,+*^^*+___+++_ - \ ,*^^^^ ) - \ _+* ^**+_ - \ +^ _ _++*+_+++_, ) - _+^^*+_ ( ,+*^ ^ \+_ ) - { ) ( ,( ,_+--+--, ^) ^\ - { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) - {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / - ( / ( ( ,___ ^*+_+* ) < < \ - U _/ ) *--< ) ^\-----++__) ) ) ) - ( ) _(^)^^)) ) )\^^^^^))^*+/ / / - ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ - ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) - *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ - \ \_)^)_)) ))^^^^^^^^^^))^^^^) - (_ ^\__^^^^^^^^^^^^))^^^^^^^) - ^\___ ^\__^^^^^^))^^^^^^^^)\\ - ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ - ___) >____) >___ ^\_\_\_\_\_\_\) - ^^^//\\_^^//\\_^ ^(\_\_\_\) - ^^^ ^^ ^^^ ^ -``` - -Sentiti libero di giocare con questo comando. -Quando hai finito, esci dal container come in precedenza: - -```bash -exit -``` - -Ti ritroverai nel tuo guscio normale. - -### Takeaway - -Sai come estrarre uncontainer ed eseguirlo singolarmente o in modo interattivo. Sai anche come rendere accessibili i tuoi dati dall'interno del container, il che ti consente di provare qualsiasi strumento a cui sei interessato su dati reali senza dover installare alcun software sul tuo sistema. - -### Prossimo passo? - -Scopri come utilizzare i contenitori per l'esecuzione dei processi Nextflow. - ---- - -## 2. Utilizzare i container in Nextflow - -Nextflow ha un supporto integrato per l'esecuzione di processi all'interno di contenitori per consentirti di eseguire strumenti che non hai installato nel tuo ambiente di elaborazione. -Ciò significa che puoi utilizzare qualsiasi immagine di container desideri per eseguire i tuoi processi e Nextflow si occuperà di estrarre l'immagine, montare i dati ed eseguire il processo al suo interno. - -Per dimostrarlo, aggiungeremo un passaggio `cowpy` alla pipeline che stiamo sviluppando, dopo il passaggio `collectGreetings`. - -### 2.1. Scrivi un modulo `cowpy` - -#### 2.1.1. Crea uno stub di file per il nuovo modulo - -Crea un file vuoto per il modulo chiamato `cowpy.nf`. - -```bash -touch modules/cowpy.nf -``` - -Questo ci fornisce un posto dove mettere il codice del processo. - -#### 2.1.2. Copia il codice del processo `cowpy` nel file del modulo - -Possiamo modellare il nostro processo `cowpy` sugli altri processi che abbiamo scritto in precedenza. - -```groovy title="modules/cowpy.nf" linenums="1" -#!/usr/bin/env nextflow - -// Generate ASCII art with cowpy -process cowpy { - - publishDir 'results', mode: 'copy' - - input: - path input_file - val character - - output: - path "cowpy-${input_file}" - - script: - """ - cat $input_file | cowpy -c "$character" > cowpy-${input_file} - """ - -} -``` - -L'output sarà un nuovo file di testo contenente l'ASCII art generata dallo strumento `cowpy`. - -### 2.2. Aggiungi cowpy al flusso di lavoro - -Ora dobbiamo importare il modulo e chiamare il processo. - -#### 2.2.1. Importa il processo `cowpy` in `hello-containers.nf` - -Inserire la dichiarazione di importazione sopra il blocco del workflow e compilarla in modo appropriato. - -=== "Dopo" - - ```groovy title="hello-containers.nf" linenums="9" hl_lines="5" - // Include modules - include { sayHello } from './modules/sayHello.nf' - include { convertToUpper } from './modules/convertToUpper.nf' - include { collectGreetings } from './modules/collectGreetings.nf' - include { cowpy } from './modules/cowpy.nf' - - workflow { - ``` - -=== "Prima" - - ```groovy title="hello-containers.nf" linenums="9" - // Include modules - include { sayHello } from './modules/sayHello.nf' - include { convertToUpper } from './modules/convertToUpper.nf' - include { collectGreetings } from './modules/collectGreetings.nf' - - workflow { - ``` - -#### 2.2.2. Aggiungere una chiamata al processo `cowpy` nel flusso di lavoro - -Colleghiamo il processo `cowpy()` all'output del processo `collectGreetings()`, che come ricorderai produce due output: - -- `collectGreetings.out.outfile` contiene gli otput dei file -- `collectGreetings.out.count`contiene il conteggio dei saluti per batch - -Nel blocco del flusso di lavoro, apportare la seguente modifica al codice: - -=== "Dopo" - - ```groovy title="hello-containers.nf" linenums="28" hl_lines="7 8" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect(), params.batch) - - // emit a message about the size of the batch - collectGreetings.out.count.view{ num_greetings -> "There were $num_greetings greetings in this batch" } - - // generate ASCII art of the greetings with cowpy - cowpy(collectGreetings.out.outfile, params.character) - ``` - -=== "Prima" - - ```groovy title="hello-containers.nf" linenums="28" - // collect all the greetings into one file - collectGreetings(convertToUpper.out.collect(), params.batch) - - // emit a message about the size of the batch - collectGreetings.out.count.view{ num_greetings -> "There were $num_greetings greetings in this batch" } - ``` - -Si noti che includiamo un nuovo parametro CLI, `params.character`, per specificare quale carattere vogliamo che dica i saluti. - -#### 2.2.3. Imposta un valore predefinito per `params.character` - -Ci piace essere pigri e saltare la digitazione dei parametri nelle nostre righe di comando. - -=== "Dopo" - - ```groovy title="hello-containers.nf" linenums="3" hl_lines="6" - /* - * Pipeline parameters - */ - params.greeting = 'greetings.csv' - params.batch = 'test-batch' - params.character = 'turkey' - ``` - -=== "Prima" - - ```groovy title="hello-containers.nf" linenums="3" - /* - * Pipeline parameters - */ - params.greeting = 'greetings.csv' - params.batch = 'test-batch' - ``` - -Dovrebbe essere tutto ciò di cui abbiamo bisogno per far funzionare tutto. - -#### 2.2.4. Eseguite il workflow per verificarne il funzionamento - -Eseguire questa operazione con il flag `-resume`. - -```bash -nextflow run hello-containers.nf -resume -``` - -Oh no, c'è un errore! - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-containers.nf` [special_lovelace] DSL2 - revision: 028a841db1 - -executor > local (1) -[f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ -[2c/67a06b] convertToUpper (3) | 3 of 3, cached: 3 ✔ -[1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ -[b2/488871] cowpy | 0 of 1 -There were 3 greetings in this batch -ERROR ~ Error executing process > 'cowpy' - -Caused by: - Process `cowpy` terminated with an error exit status (127) - -Command executed: - - cat COLLECTED-test-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-test-batch-output.txt - -Command exit status: - 127 - -Command output: - (empty) - -Command error: - .command.sh: line 2: cowpy: command not found - -(trimmed output) -``` - -Questo codice di errore, `error exit status (127)`, significa che l'eseguibile richiesto non è stato trovato. -Naturalmente, dato che stiamo chiamando lo strumento `cowpy` ma non abbiamo ancora specificato un container. - -### 2.3. Utilizzare un container per l'esecuzione - -Dobbiamo specificare un container e dire a Nextflow di usarlo per il processo `cowpy()`. - -#### 2.3.1. Specificare un container per il processo `cowpy` da utilizzare - -Modificare il modulo `cowpy.nf` per aggiungere la direttiva `container` alla definizione del processo come segue: - -=== "Dopo" - - ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" - process cowpy { - - publishDir 'containers/results', mode: 'copy' - container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' - ``` - -=== "Prima" - - ```groovy title="modules/cowpy.nf" linenums="4" - process cowpy { - - publishDir 'containers/results', mode: 'copy' - ``` - -indica a Nextflow che, se l'uso di Docker è abilitato, deve usare l'immagine del container specificata qui per eseguire il processo. - -#### 2.3.2. Abilitare l'uso di Docker tramite il file `nextflow.config - -Qui anticipiamo leggermente l'argomento della prossima e ultima parte di questo corso (Parte 6), che riguarda la configurazione. - -Uno dei modi principali che Nextflow offre per configurare l'esecuzione del workflow è l'uso di un file `nextflow.config`. Quando un file di questo tipo è presente nella directory corrente, Nextflow lo caricherà automaticamente e applicherà la configurazione in esso contenuta. -Abbiamo fornito un file `nextflow.config` con una singola riga di codice che disabilita Docker: `docker.enabled = false`. - -Ora, passiamo a `true` per abilitare Docker: - -=== "Dopo" - - ```console title="nextflow.config" linenums="1" hl_lines="1" - docker.enabled = true - ``` - -=== "Prima" - - ```console title="nextflow.config" linenums="1" - docker.enabled = false - ``` - -!!! note - - It is possible to enable Docker execution from the command-line, on a per-run basis, using the `-with-docker <container>` parameter. - However, that only allows us to specify one container for the entire workflow, whereas the approach we just showed you allows us to specify a different container per process. - This is better for modularity, code maintenance and reproducibility. - -#### 2.3.3. Eseguire il workflow con Docker abilitato - -Eseguire il workflow con il flag `resume`: - -```bash -nextflow run hello-containers.nf -resume -``` - -Questa volta funziona davvero. - -```console title="Output" linenums="1" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-containers.nf` [elegant_brattain] DSL2 - revision: 028a841db1 - -executor > local (1) -[95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ -[92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ -[aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ -[7f/caf718] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -È possibile trovare l'output di cowpy nella directory `results`. - -```console title="results/cowpy-COLLECTED-test-batch-output.txt" - _________ -/ HOLà \ -| HELLO | -\ BONJOUR / - --------- - \ ,+*^^*+___+++_ - \ ,*^^^^ ) - \ _+* ^**+_ - \ +^ _ _++*+_+++_, ) - _+^^*+_ ( ,+*^ ^ \+_ ) - { ) ( ,( ,_+--+--, ^) ^\ - { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) - {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / - ( / ( ( ,___ ^*+_+* ) < < \ - U _/ ) *--< ) ^\-----++__) ) ) ) - ( ) _(^)^^)) ) )\^^^^^))^*+/ / / - ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ - ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) - *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ - \ \_)^)_)) ))^^^^^^^^^^))^^^^) - (_ ^\__^^^^^^^^^^^^))^^^^^^^) - ^\___ ^\__^^^^^^))^^^^^^^^)\\ - ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ - ___) >____) >___ ^\_\_\_\_\_\_\) - ^^^//\\_^^//\\_^ ^(\_\_\_\) - ^^^ ^^ ^^^ ^ -``` - -Si vede che il personaggio sta pronunciando tutti i saluti, proprio come ha fatto quando abbiamo eseguito il comando `cowpy` sul file `greetings.csv` dall'interno del container. - -<!-- considering a side quest where we show how to use a conditional to skip the collect step if we want to emit the cowpy'ed greetings individually, and how to use metadata management to assign a specific character to each greeting, maybe do some cross products etc --> - -#### 2.3.4. Controllare come Nextflow ha lanciato il task containerizzato - -Diamo un'occhiata alla sottodirectory di lavoro di una delle chiamate al processo cowpy per capire meglio come Nextflow lavora con i container. - -Controllare l'output del comando nextflow run per trovare l'ID della chiamata al processo cowpy. -Quindi navigare nella sottodirectory work. -Al suo interno si trova il file .command.run che contiene tutti i comandi eseguiti da Nextflow per conto dell'utente durante l'esecuzione della pipeline. -Aprite il file .command.run e cercate nxf_launch; dovreste vedere qualcosa di simile: - -```bash -nxf_launch() { - docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/hello-nextflow/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh -} -``` - -Come si può vedere, Nextflow utilizza il comando docker run per lanciare la chiamata di processo. -Inoltre, monta la corrispondente sottodirectory di lavoro nel container, imposta di conseguenza la directory di lavoro all'interno del container ed esegue il nostro script bash templato nel file .command.sh. -Tutto il duro lavoro che abbiamo dovuto fare manualmente nella sezione precedente viene svolto da Nextflow! - -### Takeaway - -Sapete come usare i container in Nextflow per eseguire i processi. - -### E ora? - -Fate una pausa! -Quando sarete pronti, passate alla Parte 6 per imparare a configurare l'esecuzione della pipeline in base alla vostra infrastruttura e a gestire la configurazione di input e parametri. -È l'ultima parte e il gioco è fatto! diff --git a/docs/hello_nextflow/06_hello_config.it.md b/docs/hello_nextflow/06_hello_config.it.md deleted file mode 100644 index 2481cebc31..0000000000 --- a/docs/hello_nextflow/06_hello_config.it.md +++ /dev/null @@ -1,625 +0,0 @@ -# Parte 6: Hello Config - -<div class="video-wrapper"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> -</div> - -/// caption -:fontawesome-brands-youtube:{ .youtube } Guarda [tutta la playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale Youtube Nextflow. - -:green_book: La trascrizione di questo video è disponibile [qui](./transcripts/05_hello_containers.md). -/// - -Questa sezione esplorerà come impostare e gestire la configurazione della pipeline Nextflow in modo da poterne personalizzare il comportamento, adattarla a diversi ambienti e ottimizzare l'utilizzo delle risorse _senza modificare una sola riga del codice del flusso di lavoro stesso_. - -Ci sono diversi modi per farlo; qui useremo il meccanismo di file di configurazione più semplice e comune, il file `nextflow.config`. -Ogni volta che c'è un file chiamato `nextflow.config` nella directory corrente, Nextflow caricherà automaticamente la configurazione da esso. - -!!! note - - Tutto ciò che inserisci in `nextflow.config` può essere sovrascritto in fase di esecuzione fornendo le direttive di processo o i parametri e i valori pertinenti sulla riga di comando, oppure importando un altro file di configurazione, secondo l'ordine di precedenza descritto [qui](https://www.nextflow.io/docs/latest/config.html). - -In questa parte della formazione, utilizzeremo il file `nextflow.config` per illustrare i componenti essenziali della configurazione di Nextflow, quali direttive di processo, esecutori, profili e file di parametri. - -Imparando a utilizzare efficacemente queste opzioni di configurazione, puoi migliorare la flessibilità, la scalabilità e le prestazioni delle tue pipeline. - ---- - -## 0. Warmup: verifica che Docker sia abilitato ed esegui il Hello Config workflow - -Innanzitutto, un rapido controllo. C'è un file `nextflow.config` nella directory corrente che contiene la riga `docker.enabled = <setting>`, dove `<setting>` è `true` o `false` a seconda che tu abbia lavorato o meno alla Parte 5 di questo corso nello stesso ambiente. - -Se è impostato su `true`, non è necessario fare nulla. - -Se è impostato su `false`, impostalo ora su `true`. - -```console title="nextflow.config" linenums="1" -docker.enabled = true -``` - -Una volta fatto questo, verifica che il workflow iniziale funzioni correttamente: - -```bash -nextflow run hello-config.nf -``` - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-config.nf` [reverent_heisenberg] DSL2 - revision: 028a841db1 - -executor > local (8) -[7f/0da515] sayHello (1) | 3 of 3 ✔ -[f3/42f5a5] convertToUpper (3) | 3 of 3 ✔ -[04/fe90e4] collectGreetings | 1 of 1 ✔ -[81/4f5fa9] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -Se tutto funziona, sei pronto per imparare come modificare le proprietà di configurazione di base per adattarle ai requisiti del tuo ambiente di elaborazione. - ---- - -## 1. Determinare quale tecnologia di confezionamento software utilizzare - -Il primo passo per adattare la configurazione del workflow al tuo ambiente di calcolo è specificare da dove proverranno i pacchetti software che verranno eseguiti in ogni fase. -Sono già installati nell'ambiente di calcolo locale? Dobbiamo recuperare le immagini ed eseguirle tramite un sistema a container? Oppure dobbiamo recuperare i pacchetti Conda e creare un ambiente Conda locale? - -Nella primissima parte di questo corso di formazione (Parti 1-4) abbiamo utilizzato solo il software installato localmente nel nostro workflow. -Nella Parte 5 abbiamo poi introdotto i container Docker e il file `nextflow.config`, che abbiamo utilizzato per abilitare l'uso dei container Docker. - -Nel warmup di questa sezione, hai verificato che Docker fosse abilitato nel file `nextflow.config` ed eseguito il workflow, che ha utilizzato un container Docker per eseguire il processo `cowpy()`. - -!!! note - - Se questo non ti suona familiare, probabilmente dovresti tornare indietro e completare la Parte 5 prima di continuare. - -Vediamo ora come possiamo configurare un'opzione alternativa di software packaging tramite il file `nextflow.config`. - -### 1.1. Disabilitare Docker e abilitare Conda nel file di configurazione - -Supponiamo di lavorare su un cluster HPC e che l'amministratore non consenta l'uso di Docker per motivi di sicurezza. - -Fortunatamente per noi, Nextflow supporta molte altre tecnologie di container, tra cui Singularity (più ampiamente utilizzata su HPC) e gestori di pacchetti software come Conda. - -Possiamo modificare il nostro file di configurazione per usare Conda invece di Docker. -Per farlo, cambiamo il valore di `docker.enabled` in `false` e ​​aggiungiamo una direttiva che abilita l'uso di Conda: - -=== "Dopo" - - ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" - docker.enabled = false - conda.enabled = true - ``` - -=== "Prima" - - ```groovy title="nextflow.config" linenums="1" - - docker.enabled = true - ``` - -Ciò consentirà a Nextflow di creare e utilizzare ambienti Conda per i processi che hanno pacchetti Conda specificati. -Ciò significa che ora dobbiamo aggiungerne uno al nostro processo `cowpy`! - -### 1.2. Specificare un pacchetto Conda nella definizione del processo - -Abbiamo già recuperato l'URI per un pacchetto Conda contenente lo strumento `cowpy`: `conda-forge::cowpy==1.1.5` - -!!! note - - Esistono diversi modi per ottenere l'URI per un determinato pacchetto conda. - Consigliamo di usare la ricerca su [Seqera Containers](https://seqera.io/containers/), che ti fornirà un URI che puoi copiare e incollare, anche se non hai intenzione di creare un container da esso. - -Ora aggiungiamo l'URI alla definizione del processo `cowpy` utilizzando la direttiva `conda`: - -=== "Dopo" - - ```console title="modules/cowpy.nf" linenums="4" hl_lines="4" - process cowpy { - - container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' - conda 'conda-forge::cowpy==1.1.5' - - publishDir 'results', mode: 'copy' - ``` - -=== "Prima" - - ```console title="modules/cowpy.nf" linenums="4" - process cowpy { - - container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' - - publishDir 'results', mode: 'copy' - ``` - -Per essere chiari, non stiamo _sostituendo_ la direttiva `docker`, stiamo _aggiungendo_ un'opzione alternativa. - -### 1.3. Eseguire il workflow per verificare l'uso di Conda - -Proviamolo. - -```bash -nextflow run hello-config.nf -``` - -Dovrebbe funzionare senza problemi. - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 - -executor > local (8) -[ee/4ca1f2] sayHello (3) | 3 of 3 ✔ -[20/2596a7] convertToUpper (1) | 3 of 3 ✔ -[b3/e15de5] collectGreetings | 1 of 1 ✔ -[c5/af5f88] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -Dietro le quinte, Nextflow ha recuperato i pacchetti Conda e creato l'ambiente, il che normalmente richiede un po' di lavoro; è bello quindi che non dobbiamo farlo manualmente! - -!!! note - - Questa operazione è veloce perchè il pacchetto `cowpy` è piuttosto piccolo. Tuttavia,se si lavora con pacchetti di grandi dimensioni, il processo potrebbe richiedere più tempo al primo utilizzo, perchè si potrebbe vedere l'output della console rimanere "bloccato" per circa un minuto prima di completarsi. - Ciò è normale ed è dovuto al lavoro extra che Nextflow esegue la prima volta che si utilizza un nuovo pacchetto. - -Dal nostro punto di vista, sembra che funzioni esattamente come con Docker, anche se nel backend i meccanismi sono leggermente diversi. - -Ciò significa che siamo pronti per l'esecuzione con gli ambienti Conda, se necessario. - -!!!note - - Poiché queste direttive vengono assegnate per processo, è possibile "mescolare e abbinare", ovvero configurare alcuni processi nel workflow in modo che vengano eseguiti con Docker e altri con Conda, ad esempio se l'infrastruttura di elaborazione utilizzata supporta entrambi. - In tal caso, dovresti abilitare sia Docker che Conda nel tuo file di configurazione. - Se entrambi sono disponibili per un dato processo, Nextflow darà priorità ai container. - - Come accennato in precedenza, Nextflow supporta molte altre tecnologie di packaging e container software, quindi non sei limitato solo a queste due. - -### Conclusione - -Sai come configurare quale pacchetto software deve utilizzare ogni processo e come passare da una tecnologia all'altra. - -### Prossimi passi - -Scopri come modificare l'esecutore utilizzato da Nextflow per eseguire il lavoro. - ---- - -## 2. Assegnare risorse di elaborazione con direttive di processo - -La maggior parte delle piattaforme di elaborazione ad alte prestazioni consente (e talvolta richiede) di specificare determinati parametri di allocazione delle risorse, come il numero di CPU e la memoria. - -Di default, Nextflow utilizzerà una singola CPU e 2 GB di memoria per ogni processo. -Le direttive di processo corrispondenti sono chiamate `cpus` e `memory`, quindi è implicita la seguente configurazione: - -```groovy title="Built-in configuration" linenums="1" -process { - cpus = 1 - memory = 2.GB -} -``` - -Puoi modificare questi valori, sia per tutti i processi che per specifici processi denominati, utilizzando direttive di processo aggiuntive nel tuo file di configurazione. -Nextflow le tradurrà nelle istruzioni appropriate per l'esecutore scelto. - -Ma come fai a sapere quali valori utilizzare? - -### 2.1. Eseguire il workflow per generare un report sull'utilizzo delle risorse - -Se non si sa in anticipo quanta CPU e memoria saranno probabilmente necessarie ai propri processi, è possibile effettuare una profilazione delle risorse, ovvero eseguire il workflow con alcune allocazioni predefinite, registrare la quantità utilizzata da ciascun processo e, da lì, stimare come modificare le allocazioni di base. - -Nextflow include strumenti integrati per fare questo e sarà felice di generare un report per te su richiesta. - -Per farlo, aggiungi `-with-report <nomefile>.html` alla riga di comando. - -```bash -nextflow run hello-config.nf -with-report report-config-1.html -``` - -Il report è un file html, che puoi scaricare e aprire nel tuo browser. Puoi anche fare clic destro su di esso nell'esploratore file a sinistra e cliccare su `Mostra anteprima` per visualizzarlo nell'ambiente di training. - -Prenditi qualche minuto per esaminare il report e vedere se riesci a identificare alcune opportunità per regolare le risorse. -Assicurati di cliccare sulle schede che mostrano i risultati di utilizzo come percentuale di quanto è stato assegnato. -C'è della [documentazione](https://www.nextflow.io/docs/latest/reports.html) che descrive tutte le funzionalità disponibili. - -<!-- TODO: insert images --> - -### 2.2. Imposta le allocazioni delle risorse per tutti i processi - -La profilazione mostra che i processi nel nostro workflow di formazione sono molto leggeri, quindi riduciamo l'allocazione di memoria predefinita a 1 GB per processo. - -Aggiungere quanto segue al file `nextflow.config`: - -```groovy title="nextflow.config" linenums="4" -process { - memory = 1.GB -} -``` - -### 2.3. Imposta le allocazioni delle risorse per un singolo processo - -Allo stesso tempo, faremo finta che il processo `cowpy` richieda più risorse degli altri, così da poter dimostrare come adattare le allocazioni per un singolo processo. - -=== "Dopo" - - ```groovy title="nextflow.config" linenums="4" hl_lines="3-6" - process { - memory = 1.GB - withName: 'cowpy' { - memory = 2.GB - cpus = 2 - } - } - ``` - -=== "Prima" - - ```groovy title="nextflow.config" linenums="14" - process { - memory = 1.GB - } - ``` - -Con questa configurazione, tutti i processi richiederanno 1 GB di memoria e una singola CPU (impostazione predefinita), tranne il processo `cowpy`, che richiederà 2 GB e 2 CPU. - -!!! note - - Se hai una macchina con poche CPU e ne assegni un numero elevato per processo, potresti vedere le chiamate di processo accodarsi una dietro l'altra. - Questo perché Nextflow assicura che non richiediamo più CPU di quelle disponibili. - -### 2.4. Esegui il workflow con la configurazione modificata - -Proviamo a fare una prova specificando un nome file diverso per il report di profilazione, in modo da poter confrontare le prestazioni prima e dopo le modifiche alla configurazione. - -```bash -nextflow run hello-config.nf -with-report report-config-2.html -``` - -Probabilmente non noterai alcuna differenza reale, poiché si tratta di un carico di lavoro molto ridotto, ma questo è l'approccio che utilizzeresti per analizzare i requisiti di prestazioni e risorse di un workflow reale. - -È molto utile quando i tuoi processi hanno requisiti di risorse diversi. Ti consente di dimensionare correttamente le allocazioni di risorse che imposti per ogni processo in base a dati effettivi, non a supposizioni. - -!!!note - - Questo è solo un piccolo assaggio di ciò che puoi fare per ottimizzare l'uso delle risorse. - Nextflow stesso ha una [logica di retry dinamica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) davvero interessante, utilizzata per riprovare i lavori che falliscono a causa di limitazioni di risorse. - Inoltre, la piattaforma Seqera offre anche strumenti basati sull'intelligenza artificiale per ottimizzare automaticamente le allocazioni delle risorse. - - Parleremo di entrambi gli approcci in una prossima parte di questo corso di formazione. - -### 2.5. Aggiungere limiti alle risorse - -A seconda dell'esecutore di elaborazione e dell'infrastruttura di elaborazione che stai utilizzando, potrebbero esserci dei vincoli su ciò che puoi (o devi) allocare. -Ad esempio, il tuo cluster potrebbe richiedere di rimanere entro determinati limiti. - -Puoi utilizzare la direttiva `resourceLimits` per impostare le limitazioni pertinenti. La sintassi appare così quando è da sola in un blocco di processo: - -```groovy title="Syntax example" -process { - resourceLimits = [ - memory: 750.GB, - cpus: 200, - time: 30.d - ] -} -``` - -Nextflow tradurrà questi valori nelle istruzioni appropriate a seconda dell'esecutore specificato. - -Non lo eseguiremo, poiché non abbiamo accesso all'infrastruttura pertinente nell'ambiente di formazione. -Tuttavia, se provassi a eseguire il workflow con allocazioni di risorse che superano questi limiti, quindi cercassi il comando `sbatch` nel file di script `.command.run`, vedresti che le richieste che vengono effettivamente inviate all'esecutore sono limitate ai valori specificati da `resourceLimits`. - -!!!note - - Il progetto nf-core ha compilato una [raccolta di file di configurazione](https://nf-co.re/configs/) condivisa da varie istituzioni in tutto il mondo, che copre un'ampia gamma di esecutori HPC e cloud. - - Tali configurazioni condivise sono preziose sia per le persone che lavorano lì e che possono quindi utilizzare la configurazione della propria istituzione così com'è, sia come modello per coloro che desiderano sviluppare una configurazione per la propria infrastruttura. - -### Conclusione - -Sai come generare un report di profilazione per valutare l'utilizzo delle risorse e come modificare le allocazioni delle risorse per tutti i processi e/o per singoli processi, nonché come impostare limitazioni delle risorse per l'esecuzione su HPC. - -### Prossimi passi - -Impara a usare un file di parametri per memorizzare i parametri del workflow. - ---- - -## 3. Utilizzare un file di parametri per memorizzare i parametri del workflow - -Finora abbiamo esaminato la configurazione dal punto di vista tecnico dell'infrastruttura di elaborazione. -Ora prendiamo in considerazione un altro aspetto della configurazione del workflow che è molto importante per la riproducibilità: la configurazione dei parametri del workflow. - -Attualmente, il nostro workflow è impostato per accettare diversi valori di parametri tramite la riga di comando, con valori predefiniti impostati nello script del workflow stesso. -Questo va bene per un semplice workflow con pochissimi parametri che devono essere impostati per una determinata esecuzione. -Tuttavia, molti workflows del mondo reale avranno molti più parametri che potrebbero essere specifici dell'esecuzione e inserirli tutti nella riga di comando sarebbe noioso e soggetto a errori. - -Nextflow ci consente di specificare i parametri tramite un file di parametri in formato JSON, il che rende molto comodo gestire e distribuire set alternativi di valori predefiniti, ad esempio, nonché valori di parametri specifici dell'esecuzione. - -Forniamo un file di parametri di esempio nella directory corrente, denominato `test-params.json`: - -```json title="test-params.json" linenums="1" -{ - "greeting": "greetings.csv", - "batch": "Trio", - "character": "turkey" -} -``` - -Questo file di parametri contiene una coppia chiave-valore per ciascuno degli input previsti dal nostro workflow. - -### 3.1. Eseguire il workflow utilizzando un file di parametri - -Per eseguire il workflow con questo file di parametri, è sufficiente aggiungere `-params-file <nomefile>` al comando di base. - -```bash -nextflow run hello-config.nf -params-file test-params.json -``` - -Funziona! E come previsto, produce gli stessi output di prima. - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 - -executor > local (8) -[f0/35723c] sayHello (2) | 3 of 3 ✔ -[40/3efd1a] convertToUpper (3) | 3 of 3 ✔ -[17/e97d32] collectGreetings | 1 of 1 ✔ -[98/c6b57b] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -Questo potrebbe sembrare eccessivo quando hai solo pochi parametri da specificare, ma alcune pipeline si aspettano decine di parametri. -In quei casi, usare un file di parametri ci consentirà di fornire valori di parametri in fase di esecuzione senza dover digitare lunghe righe di comando e senza modificare lo script del workflow. - -### Conclusione - -Sai come gestire i parametri predefiniti e sovrascriverli in fase di esecuzione utilizzando un file di parametri. - -### Prossimi passi - -Scopri come utilizzare i profili per passare comodamente da una configurazione alternativa all'altra. - ---- - -## 4. Determinare quale esecutore dovrebbe essere utilizzato per svolgere il lavoro - -Finora abbiamo eseguito la nostra pipeline con l'esecutore locale. -Questo esegue ogni task sulla macchina su cui è in esecuzione Nextflow. -Quando Nextflow inizia, esamina le CPU e la memoria disponibili. -Se le risorse dei task pronti per l'esecuzione superano le risorse disponibili, Nextflow tratterrà gli ultimi task dall'esecuzione fino al completamento di uno o più task precedenti, liberando le risorse necessarie. - -Per carichi di lavoro molto grandi, potresti scoprire che la tua macchina locale è un collo di bottiglia, sia perché hai un singolo task che richiede più risorse di quelle disponibili, sia perché hai così tanti task che aspettare che un singolo computer li esegua richiederebbe troppo tempo. -L'esecutore locale è comodo ed efficiente, ma è limitato a quel singolo computer. -Nextflow supporta [molti backend di esecuzione diversi](https://www.nextflow.io/docs/latest/executor.html), inclusi gli scheduler HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor e altri) così come i backend di esecuzione cloud come (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes e altri). - -Ognuno di questi sistemi utilizza tecnologie, sintassi e configurazioni diverse per definire come dovrebbe essere definito un job. Ad esempio, /se non avessimo Nextflow/, un job che richiede 8 CPU e 4 GB di RAM per essere eseguito sulla coda "my-science-work" dovrebbe includere la seguente configurazione su SLURM e inviare il job tramite `sbatch`: - -```bash -#SBATCH -o /path/to/my/task/directory/my-task-1.log -#SBATCH --no-requeue -#SBATCH -c 8 -#SBATCH --mem 4096M -#SBATCH -p my-science-work -``` - -Se volessi rendere il workflow disponibile a un collega che utilizza PBS, dovrei ricordarmi di utilizzare un programma di invio diverso, `qsub`, e dovrei modificare i miei script per utilizzare una nuova sintassi per le risorse: - -```bash -#PBS -o /path/to/my/task/directory/my-task-1.log -#PBS -j oe -#PBS -q my-science-work -#PBS -l nodes=1:ppn=5 -#PBS -l mem=4gb -``` - -Se volessi usare SGE, la configurazione sarebbe leggermente diversa: - -```bash -#$ -o /path/to/my/task/directory/my-task-1.log -#$ -j y -#$ -terse -#$ -notify -#$ -q my-science-work -#$ -l slots=5 -#$ -l h_rss=4096M,mem_free=4096M -``` - -L'esecuzione su un singolo motore di esecuzione cloud richiederebbe di nuovo un nuovo approccio, probabilmente utilizzando un SDK che utilizza le API della piattaforma cloud. - -Nextflow semplifica la scrittura di un singolo flusso di lavoro che può essere eseguito su ciascuna di queste diverse infrastrutture e sistemi, senza dover modificare il workflow -L'esecutore è soggetto a una direttiva di processo denominata `executor`. -Per impostazione predefinita è impostato su `local`, quindi è implicita la seguente configurazione: - -```groovy title="Built-in configuration" -process { - executor = 'local' -} -``` - -### 4.1. Targeting di un backend diverso - -Per impostazione predefinita, questo ambiente di formazione non include uno scheduler HPC in esecuzione, ma se si esegue su un sistema con SLURM installato, ad esempio, è possibile far sì che Nextflow converta `cpus`, `memory`, `queue` e altre direttive di processo nella sintassi corretta in fase di esecuzione aggiungendo le seguenti righe al file `nextflow.config`: - -```groovy title="nextflow.config" -process { - executor = 'slurm' -} -``` - -E... questo è tutto! Come detto prima, questo presuppone che Slurm stesso sia già impostato per te, ma questo è tutto ciò che Nextflow stesso deve sapere. - -In pratica stiamo dicendo a Nextflow di generare uno script di invio Slurm e di inviarlo usando un comando `sbatch`. - -### Conclusione - -Ora sai come modificare l'esecutore per utilizzare diversi tipi di infrastrutture informatiche. - -### Prossimi passi? - -Scopri come controllare le risorse assegnate per l'esecuzione dei processi. - ---- - -## 5. Utilizza i profili per selezionare configurazioni preimpostate - -Potresti voler passare da un'impostazione alternativa all'altra a seconda dell'infrastruttura informatica che stai utilizzando. Ad esempio, potresti voler sviluppare ed eseguire test su piccola scala localmente sul tuo laptop, quindi eseguire carichi di lavoro su larga scala su HPC o cloud. - -Nextflow ti consente di impostare profili che descrivono diverse configurazioni, che puoi quindi selezionare in fase di esecuzione utilizzando un argomento della riga di comando, anziché dover modificare il file di configurazione stesso. - -### 5.1. Creare profili per passare dallo sviluppo locale all'esecuzione su HPC - -Impostiamo due profili alternativi: uno per l'esecuzione di carichi su piccola scala su un computer normale, dove utilizzeremo contenitori Docker, e uno per l'esecuzione su un HPC universitario con uno scheduler Slurm, dove utilizzeremo pacchetti Conda. - -Aggiungere quanto segue al file `nextflow.config`: - -```groovy title="nextflow.config" linenums="3" -profiles { - my_laptop { - process.executor = 'local' - docker.enabled = true - } - univ_hpc { - process.executor = 'slurm' - conda.enabled = true - process.resourceLimits = [ - memory: 750.GB, - cpus: 200, - time: 30.d - ] - } -} -``` - -Come puoi vedere, per l'HPC universitario stiamo anche specificando le limitazioni delle risorse. - -### 5.2. Esegui workflow con un profilo. - -Per specificare un profilo nella nostra riga di comando Nextflow, utilizziamo l'argomento `-profile`. - -Proviamo a eseguire il workflow con la configurazione `my_laptop`. - -```bash -nextflow run hello-config.nf -profile my_laptop -``` - -Questo produce ancora il seguente output: - -``` - N E X T F L O W ~ version 24.10.0 - -Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 - -executor > local (8) -[58/da9437] sayHello (3) | 3 of 3 ✔ -[35/9cbe77] convertToUpper (2) | 3 of 3 ✔ -[67/857d05] collectGreetings | 1 of 1 ✔ -[37/7b51b5] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -Come potete vedere, questo ci consente di passare da una configurazione all'altra in modo molto pratico durante l'esecuzione. - -!!! warning - - Il profilo `univ_hpc` non verrà eseguito correttamente nell'ambiente di training poiché non abbiamo accesso a uno scheduler Slurm. - -Se in futuro dovessimo trovare altri elementi di configurazione che si verificano sempre contemporaneamente a questi, potremmo semplicemente aggiungerli al profilo/i corrispondente/i. -Possiamo anche creare profili aggiuntivi se ci sono altri elementi di configurazione che vogliamo raggruppare. - -### 5.3. Crea un profilo di prova - -I profili non servono solo per la configurazione dell'infrastruttura. -Possiamo anche usarli per impostare valori predefiniti per i parametri del workflow, per rendere più facile per altri provare il workflow senza dover raccogliere autonomamente i valori di input appropriati. -Questo è inteso come alternativa all'uso di un file di parametri. - -La sintassi per esprimere i valori predefiniti è la stessa di quando li scriviamo nel file del workflow stesso, tranne per il fatto che li racchiudiamo in un blocco denominato `test`: - -```groovy title="Syntax example" - test { - params.<parameter1> - params.<parameter2> - ... - } -``` - -Se aggiungiamo un profilo di prova per il nostro workflow, il blocco `profili` diventa: - -```groovy title="nextflow.config" linenums="4" -profiles { - my_laptop { - process.executor = 'local' - docker.enabled = true - } - univ_hpc { - process.executor = 'slurm' - conda.enabled = true - process.resourceLimits = [ - memory: 750.GB, - cpus: 200, - time: 30.d - ] - } - test { - params.greeting = 'greetings.csv' - params.batch = 'test-batch' - params.character = 'turkey' - } -} -``` - -Proprio come per i profili di configurazione tecnica, è possibile impostare più profili diversi specificando i parametri con qualsiasi nome arbitrario si desideri. - -### 5.4. Esegui il workflow localmente con il profilo di prova - -Per comodità, i profili non si escludono a vicenda, quindi possiamo specificare più profili nella nostra riga di comando utilizzando la seguente sintassi `-profile <profile1>,<profile2>` (per qualsiasi numero di profili). - -!!! note - - Se si combinano profili che impostano valori per gli stessi elementi di configurazione e sono descritti nello stesso file di configurazione, Nextflow risolverà il conflitto utilizzando il valore letto per ultimo (ovvero, qualsiasi cosa si trovi dopo nel file). - Se le impostazioni in conflitto sono impostate in diverse origini di configurazione, si applica l'[ordine di precedenza](https://www.nextflow.io/docs/latest/config.html) predefinito. - -Proviamo ad aggiungere il profilo di prova al nostro comando precedente: - -```bash -nextflow run hello-config.nf -profile my_laptop,test -``` - -Ciò dovrebbe produrre quanto segue: - -```console title="Output" - N E X T F L O W ~ version 24.10.0 - -Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 - -executor > local (8) -[58/da9437] sayHello (3) | 3 of 3 ✔ -[35/9cbe77] convertToUpper (2) | 3 of 3 ✔ -[67/857d05] collectGreetings | 1 of 1 ✔ -[37/7b51b5] cowpy | 1 of 1 ✔ -There were 3 greetings in this batch -``` - -<!-- migliorare mostrando e variando gli output per tutti questi forse --> - -Ciò significa che finché distribuiamo file di dati di prova con il codice del workflow, chiunque può provare rapidamente il workflow senza dover fornire i propri input tramite la riga di comando o un file di parametri. - -!!! note - - Possiamo anche puntare agli URL per file più grandi che sono archiviati esternamente. - Nextflow li scaricherà automaticamente finché c'è una connessione aperta. - -### Conclusione - -Sai come usare i profili per selezionare una configurazione preimpostata in fase di esecuzione con il minimo sforzo. Più in generale, sai come configurare le esecuzioni del tuo workflow per adattarle a diverse piattaforme di elaborazione e migliorare la riproducibilità delle tue analisi. - -### Prossimi passi - -Festeggia e datti una bella pacca sulla spalla! Hai completato il tuo primo corso per sviluppatori Nextflow. - -Successivamente, ti chiederemo di compilare un brevissimo sondaggio sulla tua esperienza con questo corso di formazione, dopodiché ti indirizzeremo a una pagina con link ad ulteriori risorse di formazione e link utili. diff --git a/docs/hello_nextflow/index.it.md b/docs/hello_nextflow/index.it.md deleted file mode 100644 index 6c6c72e509..0000000000 --- a/docs/hello_nextflow/index.it.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Hello Nextflow -hide: - - toc ---- - -# Hello Nextflow - -Ciao! Ora sei sulla buona strada per scrivere flussi di lavoro scientifici riproducibili e scalabili utilizzando Nextflow. - -L'ascesa dei big data ha reso sempre più necessaria la capacità di analizzare ed eseguire esperimenti su grandi set di dati in modo portabile e riproducibile. Parallelizzazione e calcolo distribuito sono le soluzioni migliori per affrontare questa sfida, ma gli strumenti comunemente disponibili per gli scienziati computazionali spesso non supportano adeguatamente queste tecniche o forniscono un modello che non soddisfa appieno le loro esigenze. Nextflow è stato creato appositamente per affrontare queste sfide. - -Durante questa formazione, ti verrà presentato Nextflow attraverso una serie di workshop pratici complementari. - -Iniziamo! Fai clic sul pulsante "Apri in GitHub Codespaces" qui sotto per avviare l'ambiente di training (preferibilmente in una scheda separata), quindi continua a leggere mentre si carica. - -[![Apri in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -<h2> - <div style="float:right;"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=9bz6-59u_0XFmHB0&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - </div> - -Segui i video - -</h2> - -La formazione Hello Nextflow contiene un video per ogni capitolo, incorporato nella parte superiore di ogni pagina. - -Puoi trovare [l'intera playlist anche sul canale YouTube di Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). - -<!-- Clearfix for float --> -<div style="content: ''; clear: both; display: table;"></div> - -## Obiettivi di apprendimento - -In questo workshop apprenderai i concetti fondamentali per la creazione di pipeline. - -Alla fine di questo workshop sarai in grado di: - -- Descrivere e utilizzare i componenti principali di Nextflow sufficienti per creare un semplice flusso di lavoro multi-step -- Descrivere i concetti del passaggio successivo come operatori e fabbriche di canali -- Avvia un flusso di lavoro Nextflow in locale -- Trova e interpreta gli output (risultati) e i file di registro generati da Nextflow -- Risolvere i problemi di base - -## Pubblico e prerequisiti - -Questo workshop è rivolto a chi non ha mai usato Nextflow. Si presuppone una certa familiarità con la riga di comando e con i formati di file più comuni. - -**Prerequisiti** - -- Un account GitHub OPPURE un'installazione locale come descritto [qui](../envsetup/02_local). -- Esperienza con la riga di comando e la scrittura di script di base diff --git a/docs/hello_nextflow/index.pt.md b/docs/hello_nextflow/index.pt.md deleted file mode 100644 index 4865d2cc14..0000000000 --- a/docs/hello_nextflow/index.pt.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: Hello Nextflow -hide: - - toc ---- - -# Hello Nextflow - -Olá! Agora você está no caminho para escrever fluxos de trabalho científicos que são reproduzíveis e escaláveis ​​usando o Nextflow. - -O surgimento do big data tornou cada vez mais necessário ser capaz de analisar e executar experimentos em grandes conjuntos de dados de forma portável e reproduzível. Paralelização e computação distribuída são as melhores maneiras de lidar com esse desafio, mas as ferramentas comumente disponíveis para cientistas computacionais geralmente não têm um bom suporte para essas técnicas ou fornecem um modelo que se encaixa mal com as necessidades dos cientistas computacionais. O Nextflow foi criado especialmente para lidar com esses desafios. - -Durante este treinamento, você será apresentado ao Nextflow em uma série de workshops práticos complementares. - -Vamos começar! - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -<h2> - <div style="float:right;"> - <iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=9bz6-59u_0XFmHB0&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> - </div> - -Siga os vídeos - -</h2> - -A formação Hello Nextflow tem um vídeo para cada capítulo, incorporado no topo de cada página. - -Pode também encontrar [a playlist completa no canal de YouTube do Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). - -<!-- Clearfix for float --> -<div style="content: ''; clear: both; display: table;"></div> - -## Objetivos de aprendizagem - -Neste workshop, você aprenderá conceitos fundamentais para a construção de pipelines. - -Ao final deste workshop você será capaz de: - -- Descrever e utilizar os principais componentes do Nextflow o suficiente para criar um fluxo de trabalho simples de várias etapas -- Descrever conceitos como operadores e fábricas de canal -- Lançar um fluxo de trabalho localmente com Nextflow -- Encontrar e interpretar saídas (resultados) e arquivos de log gerados pelo Nextflow -- Solucionar problemas básicos - -## Público e pré-requisitos - -Este é um workshop para aqueles que são completamente novos no Nextflow. Alguma familiaridade básica com a linha de comando e formatos de arquivo comuns é assumida. - -**Pré-requisitos** - -- Uma conta GitHub -- Experiência com linha de comando diff --git a/docs/help.fr.md b/docs/help.fr.md deleted file mode 100644 index 9846f3b83d..0000000000 --- a/docs/help.fr.md +++ /dev/null @@ -1,19 +0,0 @@ -# Obtenir de l'aide - -## Documentation Nextflow - -Nextflow dispose d'une excellente [documentation](https://nextflow.io/docs/latest/), qui constitue votre première ressource dès que vous rencontrez quelque chose que vous ne comprenez pas ou si vous souhaitez en savoir plus. Vous pouvez parcourir les différents sujets ou rechercher des termes spécifiques. - -## Forum communautaire - -Si vous éprouvez des difficultés, n’hésitez pas à demander de l’aide. Notre formidable communauté est l’un des grands atouts de Nextflow ! - -Le [forum communautaire de Seqera](https://community.seqera.io) est un excellent endroit pour poser des questions sur Nextflow. C’est aussi une très bonne ressource pour trouver des réponses à des questions qui ont déjà été posées ! - -Si vous ne trouvez pas de solution à votre problème, connectez-vous simplement et cliquez sur le bouton « Nouveau sujet » pour publier votre question dans la catégorie [Ask for Help](https://community.seqera.io/c/help/37). N’hésitez pas à ajouter des tags que vous jugez pertinents, car ils peuvent aider notre équipe et vos pairs à repérer et à répondre plus facilement à votre question. - -## Support professionnel - -Nextflow est un logiciel libre et open source développé par [Seqera](https://seqera.io/), une entreprise dont le siège est en Espagne et qui possède des bureaux secondaires au Royaume-Uni et aux États-Unis. - -Seqera propose des services de support professionnel pour Nextflow et les produits associés, y compris des sessions de formation sur mesure. Si cela vous intéresse, n’hésitez pas à [nous contacter](https://seqera.io/demo/). diff --git a/docs/help.pt.md b/docs/help.pt.md deleted file mode 100644 index 25d4343de9..0000000000 --- a/docs/help.pt.md +++ /dev/null @@ -1,34 +0,0 @@ -# Conseguindo ajuda - -!!! warning - - Some of the translations on the training portal are out of date. - The translated material may be incomplete or incorrect. - We plan to update the translations later this year. - In the meantime, please try to work through the English-language material if you can. - -## Documentação do Nextflow - -Mesmo os desenvolvedores mais proficientes precisam de documentação. -Com o Nextflow não funciona diferente, e ele possui uma excelente documentação. -Você pode encontrar a documentação do Nextflow em <https://nextflow.io/docs/latest/> - recomendamos mantê-la aberta em uma aba enquanto você segue o treinamento! - -## Slack - -Se você está tendo dificuldades com o treinamento, não hesite em pedir ajuda. -Nossa incrível comunidade é um dos grandes pontos fortes do Nextflow! - -Existem duas instâncias relevantes do Slack: - -- Nextflow ([inscreva-se aqui](https://www.nextflow.io/slack-invite.html)) -- nf-core ([inscreva-se aqui](https://nf-co.re/join/slack)) - -Geralmente, o Slack do Nextflow é melhor, pois atende a toda a comunidade. -A exceção é se você estiver seguindo o treinamento através de um workshop organizado pelo projeto nf-core. Nesse caso, você deve ter sido informado sobre onde fazer perguntas. - -## Pergunte aos profissionais - -O Nextflow é um software gratuito e de código aberto, desenvolvido pela [Seqera](https://seqera.io/). -A Seqera oferece um serviço de suporte profissional para o Nextflow e produtos associados, além de realizar sessões de treinamento sob medida. - -Se isso soa como algo que pode ser do seu interesse, por favor [entre em contato conosco](https://seqera.io/demo/). diff --git a/docs/hi/docs/envsetup/01_setup.md b/docs/hi/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..b4a2e94e53 --- /dev/null +++ b/docs/hi/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces एक web-आधारित platform है जो हमें प्रशिक्षण के लिए पूर्व-configured वातावरण प्रदान करने की अनुमति देता है, जो cloud में virtual machines द्वारा समर्थित है। +यह platform Github (जो Microsoft के स्वामित्व में है) द्वारा संचालित है, और Github account वाले किसी भी व्यक्ति के लिए मुफ्त में (उपयोग quotas के साथ) उपलब्ध है। + +!!! warning "चेतावनी" + + संगठनों से जुड़े accounts कुछ अतिरिक्त प्रतिबंधों के अधीन हो सकते हैं। + अगर तुम्हारी स्थिति ऐसी है, तो तुम्हें एक स्वतंत्र व्यक्तिगत account का उपयोग करना पड़ सकता है, या इसके बजाय स्थानीय installation का उपयोग करना पड़ सकता है। + +## GitHub account बनाना + +तुम [GitHub home page](https://github.com/) से एक मुफ्त GitHub account बना सकते हो। + +## अपना GitHub Codespace शुरू करना + +एक बार जब तुम GitHub में logged in हो, Nextflow प्रशिक्षण वातावरण खोलने के लिए इस link को अपने browser में खोलो: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +वैकल्पिक रूप से, तुम नीचे दिखाए गए button पर click कर सकते हो, जो प्रत्येक प्रशिक्षण course में दोहराया गया है (आमतौर पर Orientation page पर)। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +तुम्हें एक page दिखाई देना चाहिए जहाँ तुम एक नया GitHub Codespace बना सकते हो: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Configuration + +सामान्य उपयोग के लिए, तुम्हें कुछ भी configure करने की ज़रूरत नहीं होनी चाहिए। +जब तक course में अन्यथा निर्दिष्ट न हो जो तुम शुरू कर रहे हो, तुम बस मुख्य button पर click करके आगे बढ़ सकते हो। + +हालाँकि, "Change options" button पर click करके वातावरण को customize करना संभव है। + +??? info "Configuration विकल्प" + + अगर तुम "Change options" button पर click करते हो, तो तुम्हें निम्नलिखित को customize करने का विकल्प दिया जाएगा: + + #### Branch + + यह तुम्हें प्रशिक्षण सामग्री का एक अलग version चुनने की अनुमति देता है। + `master` branch में आम तौर पर bug fixes और सामग्री होती है जो हाल ही में विकसित और approved हुई है लेकिन अभी तक website पर release नहीं हुई है। + अन्य branches में work in progress होता है जो पूर्णतः functional नहीं हो सकता। + + #### Machine type + + यह तुम्हें प्रशिक्षण में काम करने के लिए उपयोग की जाने वाली virtual machine को customize करने की अनुमति देता है। + + अधिक cores वाली machine का उपयोग करने से तुम Nextflow की workflow execution को parallelize करने की क्षमता का अधिक लाभ उठा सकते हो। + हालाँकि, यह तुम्हारे मुफ्त quota allocation को तेज़ी से consume करेगा, इसलिए हम इस setting को बदलने की अनुशंसा नहीं करते जब तक कि course के instructions में ऐसा करने की सलाह न दी गई हो जो तुम लेने की योजना बना रहे हो। + + Quotas के बारे में अधिक जानकारी के लिए नीचे 'GitHub Codespaces quotas' देखो। + +### Startup समय + +पहली बार एक नया GitHub Codespaces वातावरण खोलने में कई मिनट लग सकते हैं, क्योंकि system को तुम्हारी virtual machine सेट करनी होती है, इसलिए अगर कुछ देर लगे तो चिंता मत करो। +हालाँकि, इसमें पाँच मिनट से अधिक नहीं लगना चाहिए। + +## प्रशिक्षण interface में navigate करना + +एक बार तुम्हारा GitHub Codespaces load हो जाए, तुम्हें कुछ इस तरह दिखना चाहिए (जो तुम्हारी account preferences के आधार पर light mode में खुल सकता है): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +यह VSCode IDE का interface है, एक लोकप्रिय code development application जिसे हम Nextflow development के लिए उपयोग करने की अनुशंसा करते हैं। + +- **Main editor** वह जगह है जहाँ Nextflow code और अन्य text files खुलेंगी। यहाँ तुम code edit करोगे। जब तुम codespace खोलते हो, यह तुम्हें `README.md` file का preview दिखाएगा। +- Main editor के नीचे **terminal** तुम्हें commands चलाने की अनुमति देता है। यहाँ तुम course instructions में दी गई सभी command lines चलाओगे। +- **Sidebar** तुम्हें अपना वातावरण customize करने और बुनियादी कार्य करने की अनुमति देता है (copy, paste, files खोलना, search, git, आदि)। डिफ़ॉल्ट रूप से यह file explorer पर खुला होता है, जो तुम्हें repository की सामग्री browse करने की अनुमति देता है। Explorer में किसी file पर click करने से वह main editor window में खुलेगी। + +तुम window panes के सापेक्ष अनुपात को अपनी पसंद के अनुसार adjust कर सकते हो। + +<!-- TODO (future) Link to development best practices side quest? --> + +## GitHub Codespaces के उपयोग के बारे में अन्य नोट्स + +### Session फिर से शुरू करना + +एक बार जब तुमने वातावरण बना लिया, तुम आसानी से इसे फिर से शुरू या restart कर सकते हो और जहाँ छोड़ा था वहाँ से जारी रख सकते हो। +तुम्हारा वातावरण 30 मिनट की निष्क्रियता के बाद timeout हो जाएगा और तुम्हारे बदलावों को 2 सप्ताह तक save करेगा। + +तुम <https://github.com/codespaces/> से वातावरण फिर से खोल सकते हो। +पिछले वातावरण सूचीबद्ध होंगे। +इसे फिर से शुरू करने के लिए किसी session पर click करो। + +![List GitHub Codespace sessions](img/codespaces_list.png) + +अगर तुमने अपने पिछले GitHub Codespaces वातावरण का URL save किया है, तो तुम बस इसे अपने browser में खोल सकते हो। +वैकल्पिक रूप से, उसी button पर click करो जिसका उपयोग तुमने पहली बार इसे बनाने के लिए किया था: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +तुम्हें पिछला session दिखना चाहिए, डिफ़ॉल्ट विकल्प इसे फिर से शुरू करना है: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Files को अपनी स्थानीय machine पर save करना + +Explorer panel से कोई भी file save करने के लिए, file पर right-click करो और `Download` चुनो। + +### GitHub Codespaces quotas का प्रबंधन + +GitHub Codespaces तुम्हें प्रति माह 15 GB-month storage और 120 core-hours प्रति माह देता है। +यह standard workspace (2 cores, 8 GB RAM, और 32 GB storage) का उपयोग करके लगभग 60 घंटे के डिफ़ॉल्ट वातावरण runtime के बराबर है। + +तुम उन्हें अधिक resources के साथ बना सकते हो (ऊपर explanation देखो), लेकिन यह तुम्हारा मुफ्त उपयोग तेज़ी से consume करेगा और तुम्हारे पास इस space तक पहुँच के कम घंटे होंगे। +उदाहरण के लिए, अगर तुम 2-core डिफ़ॉल्ट के बजाय 4-core machine चुनते हो, तो तुम्हारा quota आधे समय में समाप्त हो जाएगा। + +वैकल्पिक रूप से, तुम अधिक resources तक पहुँच खरीद सकते हो। + +अधिक जानकारी के लिए, GitHub documentation देखो: +[About billing for GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/hi/docs/envsetup/02_local.md b/docs/hi/docs/envsetup/02_local.md new file mode 100644 index 0000000000..c5a5b757cc --- /dev/null +++ b/docs/hi/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# मैन्युअल इंस्टॉलेशन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +प्रशिक्षण चलाने के लिए आवश्यक सब कुछ अपने स्थानीय वातावरण में मैन्युअल रूप से install करना संभव है। + +यहाँ हमने standard POSIX-compatible systems (व्यक्तिगत machine जैसे laptop मानते हुए) पर यह कैसे करना है इसका documentation किया है। +ध्यान रखो कि कुछ विवरण तुम्हारे विशिष्ट system के आधार पर अलग हो सकते हैं। + +!!! tip "सुझाव" + + आगे बढ़ने से पहले, क्या तुमने [Devcontainers approach](03_devcontainer.md) पर विचार किया है? + यह मैन्युअल installation की आवश्यकता के बिना सभी आवश्यक tools और dependencies प्रदान करता है। + +## सामान्य software आवश्यकताएँ + +Nextflow किसी भी POSIX-compatible system (Linux, macOS, Windows Subsystem for Linux, आदि) पर Java installed के साथ उपयोग किया जा सकता है। +हमारे प्रशिक्षण courses में कुछ अतिरिक्त आवश्यकताएँ हैं। + +कुल मिलाकर, तुम्हें निम्नलिखित software installed होना चाहिए: + +- Bash या समकक्ष shell +- [Java 11 (या बाद का, 21 तक)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (या बाद का) +- [VSCode](https://code.visualstudio.com) [Nextflow extension](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) के साथ + +VSCode application तकनीकी रूप से वैकल्पिक है लेकिन हम दृढ़ता से अनुशंसा करते हैं कि तुम इसे courses में काम करने के साथ-साथ सामान्य रूप से अपने Nextflow development कार्य के लिए उपयोग करो। + +Nextflow documentation manual [Environment setup](https://www.nextflow.io/docs/latest/developer-env.html) के तहत इन dependencies को install करने के निर्देश प्रदान करता है। + +## Nextflow और nf-core tools + +तुम्हें Nextflow खुद install करना होगा, साथ ही nf-core tools, जैसा कि नीचे linked articles में विस्तृत है: + +- [Nextflow installation](https://www.nextflow.io/docs/latest/install.html) +- [nf-core tools](https://nf-co.re/docs/nf-core-tools/installation) + +हम Nextflow के लिए self-install विकल्प और nf-core tools के लिए PyPI विकल्प का उपयोग करने की अनुशंसा करते हैं। + +!!! warning "Version compatibility" + + <!-- इस content में कोई भी update home page पर copy करना होगा --> + **जनवरी 2026 के अनुसार, हमारे सभी Nextflow प्रशिक्षण courses के लिए Nextflow version 25.10.2 या बाद का आवश्यक है, strict v2 syntax सक्रिय के साथ, जब तक अन्यथा उल्लेख न हो।** + + Version आवश्यकताओं और strict v2 syntax के बारे में अधिक जानकारी के लिए, कृपया [Nextflow versions](../info/nxf_versions.md) guide देखो। + + पूर्व syntax के अनुरूप प्रशिक्षण सामग्री के पुराने versions इस webpage के menu bar में version selector के माध्यम से उपलब्ध हैं। + +## प्रशिक्षण सामग्री + +प्रशिक्षण सामग्री download करने का सबसे आसान तरीका इस command का उपयोग करके पूरी repository को clone करना है: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +प्रत्येक course की अपनी डायरेक्टरी है। +किसी course में काम करने के लिए, एक terminal window खोलो (आदर्श रूप से, VSCode application के अंदर से) और संबंधित डायरेक्टरी में `cd` करो। + +फिर तुम website पर दिए गए course instructions का पालन कर सकते हो। diff --git a/docs/hi/docs/envsetup/03_devcontainer.md b/docs/hi/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..fc4510457b --- /dev/null +++ b/docs/hi/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Local Devcontainers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +अगर तुम्हारे पास local Docker installation है या install करने के लिए तैयार हो, तो इन materials के साथ स्थानीय रूप से काम करने का सबसे आसान तरीका Visual Studio Code की devcontainer feature का उपयोग करना है। यह approach मैन्युअल installation की आवश्यकता के बिना सभी आवश्यक tools और dependencies प्रदान करता है। + +## आवश्यकताएँ + +Local devcontainer setup का उपयोग करने के लिए, तुम्हें चाहिए: + +- [Visual Studio Code](https://code.visualstudio.com/) +- एक local Docker installation, उदाहरण के लिए: + - [Docker Desktop](https://docs.docker.com/get-docker/) (Windows/macOS के लिए) + - [Docker Engine](https://docs.docker.com/engine/install/) (Linux के लिए) + - [Colima](https://github.com/abiosoft/colima) (macOS के लिए वैकल्पिक) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (Docker Desktop में शामिल, लेकिन अन्य Docker setups के साथ अलग installation की आवश्यकता हो सकती है) +- VS Code के लिए [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +Devcontainer खोलने का प्रयास करने से पहले तुम्हारी Docker installation चल रही होनी चाहिए। + +यह verify करने के लिए कि Docker buildx उपलब्ध है, चलाओ: + +```bash +docker buildx version +``` + +अगर यह command fail होता है, तो आगे बढ़ने से पहले तुम्हें buildx extension install करना होगा। + +## Setup निर्देश + +VS Code devcontainers का उपयोग करके अपना local वातावरण सेट करने के लिए इन steps का पालन करो: + +### VS Code में "Dev Containers" extension install करो + +- VS Code खोलो +- Extensions पर जाओ (Ctrl+Shift+X या macOS पर Cmd+Shift+X) +- "Dev Containers" search करो +- "Install" पर click करो + +![Installing Dev Containers extension in VS Code](img/install_extension.png) + +### Repository clone करो: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### VS Code में repository खोलो: + +- VS Code launch करो +- Menu से **File -> Open Folder** चुनो +- तुमने अभी clone की training repository folder पर navigate करो और उसे चुनो +- **Open** पर click करो + +### Container में फिर से खोलो + +अगर VS Code "Reopen in Container" के लिए prompt करे, तो उस पर click करो। वैकल्पिक रूप से: + +- F1 (या Ctrl+Shift+P / macOS पर Cmd+Shift+P) दबाओ +- "Dev Containers: Reopen in Container" type करो +- **महत्वपूर्ण**: जब configuration चुनने के लिए prompt हो, **local-dev** devcontainer configuration चुनो + +![Reopen in Container prompt](img/reopen_prompt.png) + +![Selecting local configuration](img/select_local_config.png) + +Container build होने का इंतज़ार करो। पहली बार इसमें कुछ मिनट लग सकते हैं क्योंकि यह सभी आवश्यक components download और सेट करता है। + +एक बार container build और run हो जाए, तुम्हारे पास सभी आवश्यक tools installed के साथ पूर्णतः configured वातावरण होगा, जिसमें शामिल हैं: + +- Java +- Nextflow +- Docker +- Git +- और प्रशिक्षण के लिए आवश्यक अन्य सभी dependencies + +![VS Code with devcontainer running](img/running_container.png) + +## Devcontainers के उपयोग के लाभ + +Devcontainer approach का उपयोग करने के कई फायदे हैं: + +- **सुसंगतता**: विभिन्न machines पर एक सुसंगत development वातावरण सुनिश्चित करता है +- **सरलता**: सभी dependencies पूर्व-installed और configured हैं +- **अलगाव**: Development वातावरण तुम्हारे local system से अलग है +- **पुनरुत्पादनीयता**: Devcontainer का उपयोग करने वाले सभी को समान setup मिलता है +- **कोई मैन्युअल installation नहीं**: Java, Nextflow और अन्य tools मैन्युअल रूप से install करने की आवश्यकता नहीं + +## अपने वातावरण की जाँच करना + +एक बार तुम्हारा devcontainer चल रहा हो, तुम verify कर सकते हो कि सब कुछ सही ढंग से सेट है: + +```bash +nextflow info +``` + +यह Nextflow version और runtime जानकारी दिखाएगा, जो confirm करेगा कि तुम्हारा वातावरण ठीक से configured है। + +## समस्या निवारण + +अगर तुम्हें devcontainer setup में समस्याएँ आती हैं: + +1. Devcontainer खोलने से पहले सुनिश्चित करो कि तुम्हारी Docker installation (Docker Desktop, Colima, Docker Engine, आदि) चल रही है +2. जाँचो कि prompt होने पर तुमने **local-dev** configuration चुना है +3. `docker buildx version` चलाकर verify करो कि Docker buildx installed और काम कर रहा है +4. अगर container build fail हो जाए, तो "Dev Containers: Rebuild Container" command चलाकर इसे फिर से build करने का प्रयास करो +5. लगातार समस्याओं के लिए, [VS Code Dev Containers troubleshooting guide](https://code.visualstudio.com/docs/devcontainers/troubleshooting) देखो diff --git a/docs/hi/docs/envsetup/index.md b/docs/hi/docs/envsetup/index.md new file mode 100644 index 0000000000..f95e2c8f83 --- /dev/null +++ b/docs/hi/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: वातावरण विकल्प +description: Nextflow प्रशिक्षणों के लिए अपना वातावरण सेट करने के विकल्प +hide: + - toc + - footer +--- + +# वातावरण विकल्प + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +हमारा लक्ष्य एक सुसंगत और पूर्णतः परीक्षित वातावरण प्रदान करना है जो शिक्षार्थियों को software प्रबंधन पर समय और प्रयास खर्च किए बिना Nextflow सीखने पर ध्यान केंद्रित करने की अनुमति देता है। +इसके लिए, हमने एक containerized वातावरण विकसित किया है जिसमें हमारे सभी courses में काम करने के लिए सभी आवश्यक software, code files और उदाहरण data शामिल हैं। + +यह containerized वातावरण Github Codespaces पर या VS Code में Devcontainers extension के साथ स्थानीय रूप से बॉक्स से बाहर चलाया जा सकता है। + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **Github Codespaces** + + *** + + GitHub Codespaces एक web-आधारित सेवा है जो हमें प्रशिक्षण के लिए पूर्व-निर्मित वातावरण प्रदान करने की अनुमति देती है, जिसमें सभी tools और data शामिल हैं, cloud में virtual machines द्वारा समर्थित। यह Github account वाले किसी भी व्यक्ति के लिए मुफ्त में उपलब्ध है। + + [Github Codespaces का उपयोग करें:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Local Devcontainers** + + *** + + Devcontainers के साथ VS Code स्थानीय रूप से चलने वाला containerized development वातावरण प्रदान करता है जिसमें सभी प्रशिक्षण tools पूर्व-configured हैं। यह Codespaces के समान पूर्व-निर्मित वातावरण प्रदान करता है लेकिन पूरी तरह से तुम्हारे स्थानीय hardware पर चलता है। + + [स्थानीय रूप से Devcontainers का उपयोग करें :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## मैन्युअल इंस्टॉलेशन के लिए निर्देश + +अगर ऊपर दिए गए विकल्पों में से कोई भी तुम्हारी ज़रूरतों के अनुकूल नहीं है, तो तुम software dependencies को मैन्युअल रूप से install करके और training repository को clone करके अपने स्थानीय system पर इस वातावरण की प्रतिकृति बना सकते हो। + +[मैन्युअल इंस्टॉलेशन :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Gitpod का बहिष्करण" + + Nextflow Training फरवरी 2025 तक [Gitpod](https://gitpod.io) का उपयोग करता था। + हालाँकि, Gitpod के निर्माताओं ने [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex) system के पक्ष में मुफ्त कार्यक्षमता को retire करने का निर्णय लिया। + इसी कारण से, हमने GitHub Codespaces का उपयोग करना शुरू किया, जो बिना किसी पूर्व setup के one-click developer वातावरण भी प्रदान करता है। + + तुम्हारे Gitpod में साइन अप करने के समय और उनके सेवा को retire करने के समय के आधार पर, तुम अभी भी उनके पुराने cloud IDE में प्रशिक्षण शुरू करने में सक्षम हो सकते हो, हालाँकि हम आगे विश्वसनीय पहुँच की गारंटी नहीं दे सकते: + [Gitpod में खोलें](https://gitpod.io/#https://github.com/nextflow-io/training)। diff --git a/docs/hi/docs/hello_nextflow/00_orientation.md b/docs/hi/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..3ae6acd879 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# शुरुआत करना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/00_orientation.md) उपलब्ध है। +/// + +!!! tip "सुझाव" + + YouTube वीडियो में कुछ super powers हैं! + + - :fontawesome-solid-closed-captioning: उच्च गुणवत्ता (manually curated) captions / subtitles। इन्हें :material-subtitles: icon से चालू करो + - :material-bookmark: Timeline में video chapters जो page headings से मेल खाते हैं। + +## Training environment शुरू करें + +GitHub Codespaces पर हमारे द्वारा प्रदान किए गए pre-built environment का उपयोग करने के लिए, नीचे "Open in GitHub Codespaces" button पर क्लिक करो। अन्य विकल्पों के लिए, [Environment options](../envsetup/index.md) देखें। + +हम training environment को एक नए browser tab या window में खोलने की सलाह देते हैं (अपने equipment के आधार पर right-click, ctrl-click या cmd-click का उपयोग करो) ताकि तुम environment लोड होने के दौरान पढ़ना जारी रख सको। +कोर्स के माध्यम से काम करने के लिए तुम्हें इन instructions को parallel में खुला रखना होगा। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Environment की मूल बातें + +इस training environment में training course के माध्यम से काम करने के लिए आवश्यक सभी software, code और data शामिल हैं, इसलिए तुम्हें खुद कुछ भी install करने की आवश्यकता नहीं है। + +Codespace एक VSCode interface के साथ सेट किया गया है, जिसमें एक filesystem explorer, एक code editor और एक terminal shell शामिल है। +कोर्स के दौरान दिए गए सभी instructions (जैसे 'file खोलो', 'code edit करो' या 'यह command चलाओ') VSCode interface के उन तीन भागों को संदर्भित करते हैं जब तक अन्यथा निर्दिष्ट न हो। + +यदि तुम इस कोर्स को स्वयं कर रहे हो, तो कृपया अधिक विवरण के लिए [environment basics](../envsetup/01_setup.md) से परिचित हो जाओ। + +### Version requirements + +यह training Nextflow 25.10.2 या बाद के version के लिए डिज़ाइन की गई है **v2 syntax parser ENABLED के साथ**। +यदि तुम local या custom environment का उपयोग कर रहे हो, तो कृपया सुनिश्चित करो कि तुम [यहाँ](../info/nxf_versions.md) documented सही settings का उपयोग कर रहे हो। + +## काम करने के लिए तैयार हो जाओ + +एक बार जब तुम्हारा codespace चल रहा हो, तो training में dive करने से पहले तुम्हें दो चीजें करनी होंगी: इस specific course के लिए अपनी working directory सेट करो, और प्रदान की गई materials पर एक नज़र डालो। + +### Working directory सेट करें + +डिफ़ॉल्ट रूप से, codespace सभी training courses के root पर work directory सेट के साथ खुलता है, लेकिन इस course के लिए, हम `hello-nextflow/` directory में काम करेंगे। + +Terminal में यह command चलाकर अभी directory बदलो: + +```bash +cd hello-nextflow/ +``` + +तुम VSCode को इस directory पर focus करने के लिए सेट कर सकते हो, ताकि file explorer sidebar में केवल relevant files दिखें: + +```bash +code . +``` + +!!! tip "सुझाव" + + यदि किसी भी कारण से तुम इस directory से बाहर चले जाते हो (जैसे तुम्हारा codespace sleep हो जाए), तो तुम हमेशा full path का उपयोग करके इसमें वापस आ सकते हो, यह मानते हुए कि तुम इसे Github Codespaces training environment में चला रहे हो: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +अब चलो contents पर एक नज़र डालते हैं। + +### प्रदान की गई materials को explore करें + +तुम training workspace के बाईं ओर file explorer का उपयोग करके इस directory की contents को explore कर सकते हो। +वैकल्पिक रूप से, तुम `tree` command का उपयोग कर सकते हो। + +पूरे course में, हम directory structure और contents को readable form में represent करने के लिए `tree` के output का उपयोग करते हैं, कभी-कभी clarity के लिए minor modifications के साथ। + +यहाँ हम दूसरे level तक table of contents generate करते हैं: + +```bash +tree . -L 2 +``` + +??? abstract "Directory contents" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Section को expand करने और इसकी contents देखने के लिए colored box पर क्लिक करो। +हम expected command output को concise तरीके से शामिल करने के लिए इस तरह के collapsible sections का उपयोग करते हैं। + +- **`.nf` files** workflow scripts हैं जिनके नाम इस आधार पर हैं कि वे course के किस भाग में उपयोग किए जाते हैं। + +- **`nextflow.config` file** एक configuration file है जो minimal environment properties सेट करती है। + तुम इसे अभी के लिए ignore कर सकते हो। + +- **`data/` के तहत `greetings.csv` file** में input data है जिसे हम course के अधिकांश भाग में उपयोग करेंगे। इसे Part 2 (Channels) में describe किया गया है, जब हम इसे पहली बार introduce करते हैं। + +- **`test-params.*` files** configuration files हैं जिनका उपयोग हम Part 6 (Configuration) में करेंगे। तुम इन्हें अभी के लिए ignore कर सकते हो। + +- **`solutions` directory** में completed workflow scripts हैं जो course के प्रत्येक step से result होती हैं। + ये तुम्हारे काम की जाँच करने और किसी भी issue को troubleshoot करने के लिए reference के रूप में उपयोग की जानी हैं। + +## तैयारी checklist + +सोचते हो कि तुम dive करने के लिए तैयार हो? + +- [ ] मैं इस course का goal और इसकी prerequisites समझता/समझती हूँ +- [ ] मेरा environment up और running है +- [ ] मैंने अपनी working directory appropriately सेट की है + +यदि तुम सभी boxes check कर सकते हो, तो तुम जाने के लिए तैयार हो। + +**[Part 1: Hello World](./01_hello_world.md) पर जारी रखने के लिए, इस page के नीचे दाएँ कोने में arrow पर क्लिक करो।** diff --git a/docs/hi/docs/hello_nextflow/01_hello_world.md b/docs/hi/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..da15080907 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1224 @@ +# भाग 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/01_hello_world.md) उपलब्ध है। +/// + +Hello Nextflow training course के इस पहले भाग में, हम एक बहुत ही बुनियादी domain-agnostic Hello World उदाहरण के साथ topic में आसानी से प्रवेश करते हैं, जिसे हम foundational Nextflow logic और components के उपयोग को demonstrate करने के लिए progressively build up करेंगे। + +??? info "Hello World उदाहरण क्या है?" + + एक "Hello World!" एक minimalist उदाहरण है जो programming language या software framework की basic syntax और structure को demonstrate करने के लिए है। + उदाहरण में आमतौर पर output device, जैसे console या terminal, पर "Hello, World!" phrase print करना, या इसे एक file में लिखना शामिल है। + +--- + +## 0. Warmup: Hello World उदाहरण को सीधे चलाएं + +चलो इसे एक simple command के साथ demonstrate करते हैं जिसे हम सीधे terminal में चलाते हैं, यह दिखाने के लिए कि यह क्या करता है इससे पहले कि हम इसे Nextflow में wrap करें। + +!!! tip "सुझाव" + + याद रखो कि तुम्हें अब `hello-nextflow/` directory के अंदर होना चाहिए जैसा कि [Getting Started](00_orientation.md) page पर describe किया गया है। + +### 0.1. Terminal को hello कहलवाएं + +अपने terminal में निम्नलिखित command चलाओ। + +```bash +echo 'Hello World!' +``` + +??? success "Command output" + + ```console + Hello World! + ``` + +यह terminal में 'Hello World' text output करता है। + +### 0.2. Output को एक file में लिखें + +Pipelines चलाने में ज्यादातर files से data पढ़ना और results को अन्य files में लिखना शामिल है, तो चलो command को modify करते हैं ताकि text output को एक file में लिखें ताकि उदाहरण थोड़ा अधिक relevant हो। + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Command output" + + ```console + + ``` + +यह terminal में कुछ भी output नहीं करता। + +### 0.3. Output खोजें + +'Hello World' text अब उस output file में होना चाहिए जो हमने specify की थी, जिसका नाम `output.txt` है। +तुम इसे file explorer में या command line से `cat` utility का उपयोग करके खोल सकते हो, उदाहरण के लिए। + +??? abstract "File contents" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +यही वह है जिसे हम अपने पहले Nextflow workflow के साथ replicate करने की कोशिश करेंगे। + +### सीख + +तुम अब जानते हो कि terminal में एक simple command कैसे चलाया जाए जो कुछ text output करता है, और optionally, इसे एक file में output कैसे लिखवाया जाए। + +### आगे क्या? + +पता लगाओ कि यह Nextflow workflow के रूप में कैसा दिखेगा। + +--- + +## 1. Script को examine करें और चलाएं + +हम तुम्हें `hello-world.nf` नामक एक fully functional अगर minimalist workflow script प्रदान करते हैं जो पहले जैसा ही काम करता है ('Hello World!' लिखता है) लेकिन Nextflow के साथ। + +शुरू करने के लिए, चलो workflow script खोलते हैं ताकि तुम समझ सको कि यह कैसे structured है। +फिर हम इसे चलाएंगे और इसके outputs खोजेंगे। + +### 1.1. Code को examine करें + +तुम `hello-world.nf` script अपनी current directory में पाओगे, जो `hello-nextflow` होनी चाहिए। इसे editor pane में खोलो। + +??? full-code "पूरी code file" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // एक अभिवादन emit करें + sayHello() + } + ``` + +एक Nextflow workflow script में आमतौर पर एक या अधिक **process** definitions और **workflow** itself शामिल होते हैं, साथ ही कुछ optional blocks (यहाँ मौजूद नहीं) जिन्हें हम बाद में introduce करेंगे। + +प्रत्येक **process** describe करता है कि pipeline में corresponding step को क्या operation(s) accomplish करने चाहिए, जबकि **workflow** dataflow logic describe करता है जो विभिन्न steps को connect करता है। + +हम पहले **process** block पर एक closer look लेंगे, फिर हम **workflow** block को देखेंगे। + +#### 1.1.1. `process` definition + +Code का पहला block एक **process** describe करता है। + +Process definition keyword `process` से शुरू होती है, उसके बाद process name और अंत में curly braces द्वारा delimited process body। +Process body में एक script block होना चाहिए जो चलाने के लिए command specify करता है, जो कुछ भी हो सकता है जो तुम command line terminal में चला सकते हो। + +```groovy title="hello-world.nf" linenums="3" +/* +* 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +यहाँ हमारे पास `sayHello` नामक एक **process** है जो अपना **output** `output.txt` नामक एक file में लिखता है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +यह एक बहुत ही minimal process definition है जिसमें बस एक `output` definition और execute करने के लिए `script` है। + +`output` definition में `path` qualifier शामिल है, जो Nextflow को बताता है कि इसे एक path के रूप में handle किया जाना चाहिए (जिसमें directory paths और files दोनों शामिल हैं)। +एक अन्य common qualifier `val` है। + +महत्वपूर्ण रूप से, output definition यह _determine_ नहीं करती कि क्या output बनाया जाएगा। +यह बस _declare_ करती है कि expected output क्या है, ताकि Nextflow execution complete होने के बाद इसे खोज सके। +यह verify करने के लिए आवश्यक है कि command successfully execute हुई और यदि आवश्यक हो तो output को downstream processes को pass करने के लिए। जो output produce होता है जो output block में declare किए गए से match नहीं करता वह downstream processes को pass नहीं किया जाएगा। + +!!! warning "चेतावनी" + + यह उदाहरण brittle है क्योंकि हमने output filename को दो अलग-अलग जगहों (script और output blocks) में hardcode किया है। + यदि हम एक को बदलते हैं लेकिन दूसरे को नहीं, तो script break हो जाएगी। + बाद में, तुम इस problem को mitigate करने के लिए variables का उपयोग करने के तरीके सीखोगे। + +एक real-world pipeline में, एक process में आमतौर पर additional blocks जैसे directives और inputs होते हैं, जिन्हें हम थोड़ी देर में introduce करेंगे। + +#### 1.1.2. `workflow` definition + +Code का दूसरा block **workflow** itself describe करता है। +Workflow definition keyword `workflow` से शुरू होती है, उसके बाद एक optional name, फिर curly braces द्वारा delimited workflow body। + +यहाँ हमारे पास एक **workflow** है जिसमें एक `main:` block है (जो कहता है 'यह workflow का main body है') जिसमें `sayHello` process का call है। + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // एक अभिवादन emit करें + sayHello() +} +``` + +यह एक बहुत ही minimal **workflow** definition है। +एक real-world pipeline में, workflow में आमतौर पर **channels** द्वारा connected **processes** के multiple calls होते हैं, और processes एक या अधिक variable **input(s)** expect करते हैं। + +तुम इस training module में बाद में variable inputs जोड़ना सीखोगे; और तुम इस course के Part 3 में more processes जोड़ना और उन्हें channels द्वारा connect करना सीखोगे। + +!!! tip "सुझाव" + + तकनीकी रूप से `main:` line इस तरह के simple workflows के लिए आवश्यक नहीं है, इसलिए तुम ऐसे workflows देख सकते हो जिनमें यह नहीं है। + लेकिन workflow-level outputs का लाभ उठाने के लिए हमें इसकी आवश्यकता होगी, इसलिए हम इसे शुरू से ही शामिल कर सकते हैं। + +### 1.2. Workflow चलाएं + +Code देखना इसे चलाने जितना fun नहीं है, तो चलो इसे practice में try करते हैं। + +#### 1.2.1. Workflow launch करें और execution monitor करें + +Terminal में, निम्नलिखित command चलाओ: + +```bash +nextflow run hello-world.nf +``` + +??? success "Command output" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +यदि तुम्हारा console output ऐसा कुछ दिखता है, तो बधाई हो, तुमने अभी अपना पहला Nextflow workflow चलाया! + +यहाँ सबसे महत्वपूर्ण output अंतिम line है, जो ऊपर के output में highlighted है: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +यह हमें बताता है कि `sayHello` process successfully एक बार execute हुआ (`1 of 1 ✔`)। + +महत्वपूर्ण रूप से, यह line तुम्हें यह भी बताती है कि `sayHello` process call का output कहाँ मिलेगा। +चलो अब उसे देखते हैं। + +#### 1.2.2. `work` directory में output और logs खोजें + +जब तुम किसी दी गई directory में पहली बार Nextflow चलाते हो, तो यह `work` नामक एक directory बनाता है जहाँ यह execution के दौरान generate की गई सभी files (और कोई भी symlinks) लिखेगा। + +`work` directory के भीतर, Nextflow outputs और logs को प्रति process call organize करता है। +प्रत्येक process call के लिए, Nextflow एक nested subdirectory बनाता है, जिसे unique बनाने के लिए hash के साथ named किया जाता है, जहाँ यह सभी आवश्यक inputs को stage करेगा (default रूप से symlinks का उपयोग करके), helper files लिखेगा, और logs और process के किसी भी outputs को लिखेगा। + +उस subdirectory का path console output में square brackets में truncated form में दिखाया जाता है। +ऊपर दिखाए गए run के लिए हमें जो मिला उसे देखते हुए, sayHello process के लिए console log line `[65/7be2fa]` से शुरू होती है। यह निम्नलिखित directory path से correspond करता है: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +चलो देखते हैं कि वहाँ क्या है। + +??? abstract "Directory contents" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "वही चीज़ नहीं दिख रही?" + + तुम्हारे system पर exact subdirectory names अलग होंगे। + + यदि तुम VSCode file explorer में task subdirectory की contents browse करते हो, तो तुम सभी files तुरंत देखोगे। + हालाँकि, log files terminal में invisible होने के लिए set हैं, इसलिए यदि तुम उन्हें देखने के लिए `ls` या `tree` का उपयोग करना चाहते हो, तो तुम्हें invisible files display करने के लिए relevant option set करना होगा। + + ```bash + tree -a work + ``` + +पहली चीज़ जो तुम देखना चाहते हो वह है workflow का actual output, यानी `sayHello` process द्वारा produce की गई `output.txt` file। +इसे खोलो और तुम `Hello World!` greeting पाओगे, जो हमारे minimalist workflow का point था। + +??? abstract "File contents" + + ```console title="output.txt" + Hello World! + ``` + +यह काम किया! + +माना, इतने छोटे result के लिए यह बहुत सारा wrapper code लग सकता है, लेकिन उस सारे wrapper code का value अधिक obvious हो जाएगा जब हम input files पढ़ना और multiple steps को string together करना शुरू करेंगे। + +उस ने कहा, चलो उस directory में अन्य files को भी देखते हैं। ये task execution के भाग के रूप में Nextflow द्वारा produce की गई helper और log files हैं। + +- **`.command.begin`**: Process call के execution की शुरुआत से संबंधित Metadata +- **`.command.err`**: Process call द्वारा emit किए गए Error messages (`stderr`) +- **`.command.log`**: Process call द्वारा emit किया गया Complete log output +- **`.command.out`**: Process call द्वारा Regular output (`stdout`) +- **`.command.run`**: Process call को execute करने के लिए Nextflow द्वारा चलाई गई Full script +- **`.command.sh`**: वह command जो वास्तव में process call द्वारा चलाई गई +- **`.exitcode`**: Command से resulting exit code + +`.command.sh` file विशेष रूप से useful है क्योंकि यह तुम्हें बताती है कि Nextflow ने main command क्या execute की, सभी bookkeeping और task/environment setup को शामिल नहीं करते हुए। + +??? abstract "File contents" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +यह उससे match करता है जो हमने पहले manually चलाया था। + +इस case में यह बहुत straightforward है क्योंकि process command hardcoded थी, लेकिन बाद में course में तुम process commands देखोगे जिनमें variables का कुछ interpolation शामिल है। +यह विशेष रूप से valuable बनाता है कि तुम exactly देख सको कि Nextflow ने code को कैसे interpret किया और जब तुम failed run को troubleshoot कर रहे हो तो क्या command produce हुई। + +### 1.3. Workflow फिर से चलाएं + +Workflow को कुछ बार फिर से चलाने का try करो, फिर `work/` के तहत task directories देखो। + +??? abstract "Directory contents" + + ```console + 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 + ``` + +तुम देखोगे कि प्रत्येक run के लिए output और log files के complete set के साथ एक new subdirectory बनाई गई है। +यह तुम्हें दिखाता है कि same workflow को कई बार चलाने से previous runs के results overwrite नहीं होंगे। + +### सीख + +तुम जानते हो कि एक simple Nextflow script को कैसे decipher करना है, इसे कैसे चलाना है और work directory में output और relevant log files कैसे खोजनी हैं। + +### आगे क्या? + +सीखो कि workflow outputs को एक अधिक convenient location पर कैसे publish करें। + +--- + +## 2. Outputs publish करें + +जैसा कि तुमने अभी सीखा, हमारे pipeline द्वारा produce किया गया output कई layers deep एक working directory में buried है। +यह जानबूझकर किया गया है; Nextflow इस directory का control में है और हमें इसके साथ interact नहीं करना चाहिए। +हालाँकि, यह उन outputs को retrieve करने में असुविधाजनक बनाता है जिनकी हमें care है। + +सौभाग्य से, Nextflow [workflow-level output definitions](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs) का उपयोग करके outputs को एक designated directory में publish करने का एक तरीका प्रदान करता है। + +### 2.1. Basic usage + +इसमें code के दो नए pieces शामिल होंगे: + +1. `workflow` body के अंदर एक `publish:` block, जो process outputs declare करता है। +2. Script में एक `output` block जो output options जैसे mode और location specify करता है। + +#### 2.1.1. `sayHello` process का output declare करें + +हमें workflow body में एक `publish:` block जोड़ना होगा (उसी प्रकार का code element जैसा `main:` block) और `sayHello()` process का output list करना होगा। + +Workflow script file `hello-world.nf` में, code की निम्नलिखित lines जोड़ो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // एक अभिवादन emit करें + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // एक अभिवादन emit करें + sayHello() + } + ``` + +तुम देखोगे कि हम process के output को simply `sayHello().out` करके refer कर सकते हैं, और इसे एक arbitrary name, `first_output` assign कर सकते हैं। + +#### 2.1.2. Script में एक `output:` block जोड़ें + +अब हमें बस वह `output:` block जोड़ना है जहाँ output directory path specify किया जाएगा। Note करो कि यह new block script के भीतर `workflow` block के **बाहर** और **नीचे** बैठता है। + +Workflow script file `hello-world.nf` में, code की निम्नलिखित lines जोड़ो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // एक अभिवादन emit करें + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // एक अभिवादन emit करें + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +हम इसका उपयोग `workflow` block में declare किए गए किसी भी process outputs को specific paths assign करने के लिए कर सकते हैं। +बाद में, तुम sophisticated output directory structures generate करने के तरीके सीखोगे, लेकिन अभी के लिए, हम simplicity के लिए एक minimal path hardcode कर रहे हैं। + +#### 2.1.3. Workflow चलाएं + +अब modified workflow script चलाओ: + +```bash +nextflow run hello-world.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +Terminal output परिचित दिखना चाहिए। बाहरी रूप से, कुछ भी नहीं बदला है। + +हालाँकि, अपना file explorer check करो: इस बार, Nextflow ने `results/` नामक एक new directory बनाई है। + +??? abstract "Directory contents" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +`results` directory के अंदर, हमें work directory में command द्वारा produce की गई `output.txt` का एक symbolic link मिलता है जो हमने अभी चलाई। + +यह हमें work subdirectory में खोदे बिना आसानी से output files retrieve करने की अनुमति देता है। + +### 2.2. Custom location सेट करें + +Default location होना great है, लेकिन तुम customize करना चाह सकते हो कि results कहाँ save होते हैं और वे कैसे organized होते हैं। + +उदाहरण के लिए, तुम अपने outputs को subdirectories में organize करना चाह सकते हो। +ऐसा करने का सबसे simple तरीका प्रति output specific output path assign करना है। + +#### 2.2.1. Output path modify करें + +एक बार फिर, specific output के लिए publish behavior modify करना वास्तव में straightforward है। +Custom location set करने के लिए, बस `path` को accordingly edit करो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +चूंकि यह individual output के level पर set है, तुम अपनी needs के अनुसार different locations और subdirectories specify कर सकते हो। + +#### 2.2.2. Workflow फिर से चलाएं + +चलो try करते हैं। + +```bash +nextflow run hello-world.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +इस बार result specified subdirectory के तहत लिखा जाता है। + +??? abstract "Directory contents" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +तुम देखोगे कि previous execution का result अभी भी वहाँ है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +तुम जितने चाहो उतने levels of nesting का उपयोग कर सकते हो। +Process name या अन्य variables का उपयोग करके results को organize करने के लिए उपयोग की जाने वाली directories को name करना भी संभव है, और top-level output directory का default name बदलना संभव है (जो special variable `outputDir` द्वारा controlled है)। +हम इन options को later trainings में cover करेंगे। + +### 2.3. Publish mode को copy पर सेट करें + +Default रूप से, outputs `work` directory से symbolic links के रूप में publish होते हैं। +इसका मतलब है कि filesystem पर केवल एक single file है। + +यह great है जब तुम बहुत large files के साथ deal कर रहे हो, जिनकी तुम multiple copies store नहीं करना चाहते। +हालाँकि, यदि तुम किसी भी समय work directory delete करते हो (हम cleanup operations को shortly cover करेंगे), तो तुम file तक access खो दोगे। +इसलिए तुम्हें किसी भी important files की copies को एक secure place पर save करने की plan होनी चाहिए। + +एक easy option उन outputs के लिए publish mode को copy में switch करना है जिनकी तुम care करते हो। + +#### 2.3.1. Mode directive जोड़ें + +यह bit वास्तव में straightforward है। +बस relevant workflow-level output definition में `mode 'copy'` जोड़ो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +यह उस specific output के लिए publish mode set करता है। + +#### 2.3.2. Workflow फिर से चलाएं + +चलो try करते हैं। + +```bash +nextflow run hello-world.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +इस बार, यदि तुम results देखो, तो file एक proper copy है बजाय सिर्फ एक symlink के। + +??? abstract "Directory contents" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +चूंकि यह भी individual output के level पर set है, यह तुम्हें publish mode को एक granular way में set करने की अनुमति देता है। +यह विशेष रूप से बाद में handy होगा जब हम multi-step pipelines पर move करेंगे, जहाँ तुम शायद केवल final outputs को copy करना और intermediate outputs को symlinks के रूप में छोड़ना चाहो, उदाहरण के लिए। + +जैसा कि पहले noted किया गया, outputs कैसे publish होते हैं इसे control करने के लिए अन्य, अधिक sophisticated options हैं। +हम तुम्हें तुम्हारी Nextflow journey में due time में उनका उपयोग करना दिखाएंगे। + +### 2.4. Process-level `publishDir` directives पर note + +बहुत हाल तक, outputs publish करने का established तरीका प्रत्येक individual process के level पर `publishDir` directive का उपयोग करके करना था। + +जो हमने अभी `sayHello` process के outputs के लिए किया, उसे achieve करने के लिए, हमने इसके बजाय process definition में निम्नलिखित line जोड़ी होती: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +तुम अभी भी इस code pattern को पुराने Nextflow pipelines और process modules में हर जगह पाओगे, इसलिए इसके बारे में aware होना important है। +हालाँकि, हम किसी भी new work में इसका उपयोग करने की recommend नहीं करते क्योंकि यह eventually Nextflow language के future versions में disallow हो जाएगा। + +### सीख + +तुम जानते हो कि workflow outputs को एक अधिक convenient location पर कैसे publish करें। + +### आगे क्या? + +सीखो कि command-line parameter के माध्यम से variable input कैसे provide करें और default values को effectively कैसे utilize करें। + +--- + +## 3. Command line पर passed variable input का उपयोग करें + +अपनी current state में, हमारा workflow process command में hardcoded greeting का उपयोग करता है। +हम एक input variable का उपयोग करके कुछ flexibility add करना चाहते हैं, ताकि हम runtime पर greeting को अधिक आसानी से बदल सकें। + +इसके लिए हमें अपनी script में तीन sets of changes करने होंगे: + +1. Process को variable input expect करने के लिए change करें +2. User input capture करने के लिए एक command-line parameter set up करें +3. Workflow body में process को input pass करें + +चलो ये changes एक-एक करके करते हैं। + +### 3.1. `sayHello` process को variable input expect करने के लिए change करें + +हमें process definition को edit करना होगा (1) एक input variable accept करने के लिए और (2) उस variable को command line में use करने के लिए। + +#### 3.1.1. Process definition में एक input block जोड़ें + +पहले, चलो process definition को `greeting` नामक एक input accept करने के लिए adapt करते हैं। + +Process block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +`greeting` variable `val` से prefixed है Nextflow को बताने के लिए कि यह एक value है (न कि एक path)। + +#### 3.1.2. Input variable use करने के लिए process command edit करें + +अब हम original hardcoded value को उस input variable की value से swap करते हैं जो हम receive करने की expect करते हैं। + +Process block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +`$` symbol और curly braces (`{ }`) Nextflow को बताते हैं कि यह एक variable name है जिसे actual input value से replace किया जाना चाहिए (=interpolated)। + +!!! tip "सुझाव" + + Nextflow के previous versions में curly braces (`{ }`) technically optional थे, इसलिए तुम पुराने workflows देख सकते हो जहाँ यह `echo '$greeting' > output.txt` के रूप में लिखा गया है। + +अब जबकि `sayHello()` process variable input accept करने के लिए ready है, हमें workflow level पर process call को input value provide करने का एक तरीका चाहिए। + +### 3.2. User input capture करने के लिए command-line parameter set up करें + +हम simply एक input को directly hardcode कर सकते हैं process call `sayHello('Hello World!')` बनाकर। +हालाँकि, जब हम अपने workflow के साथ real work कर रहे होते हैं, तो हम command line से इसके inputs को control करने में सक्षम होना चाहेंगे। + +अच्छी खबर: Nextflow में `params` नामक एक built-in workflow parameter system है, जो CLI parameters को declare और use करना आसान बनाता है। + +General syntax है `params.<parameter_name>` declare करना Nextflow को बताने के लिए कि command line पर एक `--<parameter_name>` parameter expect करें। + +यहाँ, हम `--input` नामक एक parameter बनाना चाहते हैं, इसलिए हमें workflow में कहीं `params.input` declare करना होगा। +सिद्धांत रूप में हम इसे कहीं भी लिख सकते हैं; लेकिन चूंकि हम इसे `sayHello()` process call को देना चाहते हैं, हम इसे सीधे वहाँ plug कर सकते हैं `sayHello(params.input)` लिखकर। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // एक अभिवादन emit करें + sayHello(params.input) + ``` + +=== "Before" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // एक अभिवादन emit करें + sayHello() + ``` + +यह Nextflow को बताता है कि `--input` parameter के माध्यम से provide की गई value पर `sayHello` process चलाएं। + +Effect में, हमने section की शुरुआत में outlined steps (2) और (3) एक ही बार में accomplish कर लिए हैं। + +### 3.3. Workflow command चलाएं + +चलो इसे चलाते हैं! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +यदि तुमने ये सभी edits correctly किए, तो तुम्हें एक और successful execution मिलनी चाहिए। + +यह check करने के लिए output file खोलना sure करो कि तुम्हारे पास अब greeting का new version है। + +??? abstract "File contents" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Note करो कि new execution ने `results` directory में publish की गई output file को overwrite कर दिया है। +हालाँकि, previous runs के results अभी भी `work` के तहत task directories में preserved हैं। + +!!! tip "सुझाव" + + तुम Nextflow-level parameters को pipeline-level parameters से readily distinguish कर सकते हो। + + - Pipeline पर apply होने वाले Parameters हमेशा double hyphen (`--`) लेते हैं। + - Nextflow setting को modify करने वाले Parameters, _जैसे_ `-resume` feature जो हमने पहले use किया, single hyphen (`-`) लेते हैं। + +### 3.4. Command line parameters के लिए default values use करें + +ठीक है, यह convenient था, लेकिन कई cases में, दिए गए parameter के लिए default value supply करना sense बनाता है ताकि तुम्हें हर run के लिए इसे specify न करना पड़े। + +#### 3.4.1. CLI parameter के लिए default value set करें + +चलो workflow definition से पहले declare करके `input` parameter को एक default value देते हैं। + +```groovy title="hello-world.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String = 'Holà mundo!' +} +``` + +जैसा कि तुम देखते हो, हम specify कर सकते हैं कि workflow किस type के input की expect करता है (Nextflow 25.10.2 और बाद में)। +Syntax है `name: Type = default_value`। +Supported types में `String`, `Integer`, `Float`, `Boolean`, और `Path` शामिल हैं। + +!!! info "जानकारी" + + पुराने workflows में, तुम देख सकते हो कि पूरा `params` block सिर्फ `input = 'Holà mundo!'` के रूप में लिखा गया है। + +जैसे-जैसे तुम अपने pipeline में more parameters add करते हो, तुम्हें उन सभी को इस block में add करना चाहिए, चाहे तुम्हें उन्हें default value देने की need हो या नहीं। +यह एक glance में सभी configurable parameters खोजना आसान बना देगा। + +#### 3.4.2. Parameter specify किए बिना workflow फिर से चलाएं + +अब जबकि तुम्हारे पास एक default value set है, तुम command line में value specify किए बिना workflow को फिर से चला सकते हो। + +```bash +nextflow run hello-world.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +Output पहले जैसी same place में होगा, लेकिन contents new text के साथ updated होनी चाहिए। + +??? abstract "File contents" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow ने output बनाने के लिए greeting parameter की default value use की। + +#### 3.4.3. Default value override करें + +यदि तुम command line पर parameter provide करते हो, तो CLI value default value को override करेगी। + +Try करो: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +एक बार फिर, तुम्हें अपनी results directory में corresponding updated output मिलनी चाहिए। + +??? abstract "File contents" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "नोट" + + Nextflow में, ऐसी कई places हैं जहाँ तुम parameters के लिए values specify कर सकते हो। + यदि same parameter multiple places में different values पर set है, तो Nextflow [यहाँ](https://www.nextflow.io/docs/latest/config.html) described precedence के order के आधार पर determine करेगा कि कौन सी value use करनी है। + + हम इसे Part 6 (Configuration) में अधिक detail में cover करेंगे। + +### सीख + +तुम जानते हो कि command-line parameter के माध्यम से runtime पर provide किए गए simple variable input का उपयोग कैसे करें, साथ ही default values को set up, use और override कैसे करें। + +### आगे क्या? + +सीखो कि executions को अधिक conveniently कैसे manage करें। + +--- + +## 4. Workflow executions manage करें + +Workflows launch करना और outputs retrieve करना जानना great है, लेकिन तुम जल्दी ही पाओगे कि workflow management के कुछ अन्य aspects हैं जो तुम्हारी life आसान बना देंगे, खासकर यदि तुम अपने खुद के workflows develop कर रहे हो। + +यहाँ हम तुम्हें दिखाते हैं कि जब तुम्हें same workflow re-launch करना हो तो `resume` feature कैसे use करें, `nextflow log` के साथ past executions का log कैसे inspect करें, और `nextflow clean` के साथ older work directories कैसे delete करें। + +### 4.1. `-resume` के साथ workflow re-launch करें + +कभी-कभी, तुम एक pipeline को re-run करना चाहोगे जो तुम पहले launch कर चुके हो बिना उन steps को redo किए जो पहले से successfully complete हो चुके हैं। + +Nextflow में `-resume` नामक एक option है जो तुम्हें ऐसा करने की अनुमति देता है। +Specifically, इस mode में, कोई भी processes जो पहले से exact same code, settings और inputs के साथ run हो चुके हैं, skip हो जाएंगे। +इसका मतलब है Nextflow केवल वे processes run करेगा जो तुमने last run के बाद से add या modify किए हैं, या जिन्हें तुम new settings या inputs provide कर रहे हो। + +ऐसा करने के दो key advantages हैं: + +- यदि तुम अपने pipeline develop करने के middle में हो, तो तुम अधिक rapidly iterate कर सकते हो क्योंकि तुम्हें अपने changes test करने के लिए केवल वह process(es) run करने होंगे जिन पर तुम actively काम कर रहे हो। +- यदि तुम production में pipeline run कर रहे हो और कुछ wrong हो जाता है, तो कई cases में तुम issue fix कर सकते हो और pipeline relaunch कर सकते हो, और यह failure के point से running resume करेगा, जो तुम्हें बहुत time और compute बचा सकता है। + +इसे use करने के लिए, simply अपने command में `-resume` add करो और इसे run करो: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Command output" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Console output परिचित दिखना चाहिए, लेकिन एक चीज़ है जो पहले की तुलना में थोड़ी different है। + +Process status line (line 5) में add हुए `cached:` bit को देखो, जिसका मतलब है कि Nextflow ने recognize किया है कि यह पहले से यह work कर चुका है और simply previous successful run के result को re-use किया है। + +तुम यह भी देख सकते हो कि work subdirectory hash previous run जैसा ही है। +Nextflow literally तुम्हें previous execution की ओर point कर रहा है और कह रहा है "मैंने पहले से वह वहाँ कर लिया था।" + +!!! tip "सुझाव" + + जब तुम `resume` के साथ pipeline re-run करते हो, Nextflow work directory के बाहर publish की गई किसी भी files को overwrite नहीं करता जो पहले successfully run हुई executions द्वारा publish की गई थीं। + +### 4.2. Past executions का log inspect करें + +चाहे तुम new pipeline develop कर रहे हो या production में pipelines run कर रहे हो, किसी point पर तुम्हें शायद past runs के बारे में information देखनी होगी। +यहाँ बताया गया है कि ऐसा कैसे करें। + +जब भी तुम nextflow workflow launch करते हो, current working directory में `.nextflow` नामक एक hidden directory के तहत `history` नामक एक log file में एक line लिखी जाती है। + +??? abstract "File contents" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +यह file तुम्हें current working directory के भीतर से launch की गई हर Nextflow run के लिए timestamp, run name, status, revision ID, session ID और full command line देती है। + +इस information को access करने का एक अधिक convenient तरीका `nextflow log` command use करना है। + +```bash +nextflow log +``` + +??? success "Command output" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +यह log file की contents को terminal में output करेगा, एक header line के साथ augmented। + +तुम notice करोगे कि session ID तब बदलती है जब तुम एक new `nextflow run` command run करते हो, EXCEPT यदि तुम `-resume` option use कर रहे हो। +उस case में, session ID same रहती है। + +Nextflow session ID का उपयोग `.nextflow` के तहत स्थित `cache` directory के तहत run caching information को group करने के लिए करता है। + +### 4.3. Older work directories delete करें + +Development process के दौरान, तुम typically अपनी draft pipeline को बड़ी संख्या में बार run करोगे, जो कई subdirectories में कई files के accumulation का कारण बन सकता है। + +सौभाग्य से Nextflow में एक helpful `clean` subcommand शामिल है जो past runs की work subdirectories को automatically delete कर सकता है जिनकी तुम्हें अब care नहीं है। + +#### 4.3.1. Deletion criteria determine करें + +यह determine करने के लिए कई [options](https://www.nextflow.io/docs/latest/reference/cli.html#clean) हैं कि क्या delete करना है। + +यहाँ हम तुम्हें एक example दिखाते हैं जो given run से पहले के runs की सभी subdirectories delete करता है, इसके run name का उपयोग करके specified। + +Most recent successful run देखो जहाँ तुमने `-resume` use नहीं किया; हमारे case में run name `golden_cantor` था। + +Run name machine-generated two-part string है जो `Launching (...)` console output line में square brackets में दिखाया जाता है। +तुम Nextflow log का उपयोग करके इसके timestamp और/या command line के आधार पर run look up भी कर सकते हो। + +#### 4.3.2. Dry run करें + +पहले हम dry run flag `-n` use करते हैं यह check करने के लिए कि command दिए जाने पर क्या delete होगा: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Command output" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +तुम्हारे output में different task directory names होंगे और lines की different number हो सकती है, लेकिन यह example के समान दिखना चाहिए। + +यदि तुम कोई lines output नहीं देखते, तो या तो तुमने valid run name provide नहीं किया या delete करने के लिए कोई past runs नहीं हैं। Example command में `golden_cantor` को तुम्हारे log में जो भी corresponding latest run name है उसमें change करना sure करो। + +#### 4.3.3. Deletion के साथ proceed करें + +यदि output expected दिखता है और तुम deletion के साथ proceed करना चाहते हो, तो `-n` के बजाय `-f` flag के साथ command re-run करो: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Command output" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Output पहले जैसा similar होना चाहिए, लेकिन अब 'Would remove' के बजाय 'Removed' कह रहा है। +Note करो कि यह two-character subdirectories (जैसे ऊपर `a3/`) को remove नहीं करता लेकिन यह उनकी contents को empty कर देता है। + +!!! warning "चेतावनी" + + Past runs की work subdirectories delete करना उन्हें Nextflow के cache से remove करता है और उन directories में stored किसी भी outputs को delete करता है। + इसका मतलब है कि यह corresponding processes को re-run किए बिना execution resume करने की Nextflow की ability break करता है। + + तुम किसी भी outputs को save करने के लिए responsible हो जिनकी तुम care करते हो या जिन पर rely करने की plan है! यही main reason है कि हम `publish` directive के लिए `symlink` mode के बजाय `copy` mode use करना prefer करते हैं। + +### सीख + +तुम जानते हो कि outputs को एक specific directory में कैसे publish करें, पहले से identical way में run हो चुके steps को repeat किए बिना pipeline कैसे relaunch करें, और old work directories को clean up करने के लिए `nextflow clean` command कैसे use करें। + +अधिक generally, तुम जानते हो कि एक simple Nextflow workflow को कैसे interpret करें, इसके execution को manage करें, और outputs retrieve करें। + +### आगे क्या? + +थोड़ा break लो, तुमने इसे earn किया है! + +जब तुम ready हो, तो [**Part 2: Hello Channels**](./02_hello_channels.md) पर move करो यह सीखने के लिए कि अपने workflow में inputs feed करने के लिए channels कैसे use करें, जो तुम्हें Nextflow के built-in dataflow parallelism और अन्य powerful features का लाभ उठाने की अनुमति देगा। + +--- + +## Quiz + +<quiz> +Nextflow process के minimum required components क्या हैं? +- [ ] केवल Input और output blocks +- [x] Output और script blocks +- [ ] Input, output, और script blocks +- [ ] केवल एक script block + +और जानें: [1.1.1. The process definition](#111-the-process-definition) +</quiz> + +<quiz> +Process में output block का purpose क्या है? +- [ ] Console पर results print करना +- [ ] Files को work directory में save करना +- [x] Process से expected outputs declare करना +- [ ] Environment variables define करना + +और जानें: [1.1.1. The process definition](#111-the-process-definition) +</quiz> + +<quiz> +Nextflow workflow run करने के लिए कौन सा command use होता है? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Task की work directory देखते हुए, कौन सी file वह actual command contain करती है जो execute हुई थी? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +और जानें: [1.2.2. Find the output and logs in the `work` directory](#122-find-the-output-and-logs-in-the-work-directory) +</quiz> + +<quiz> +`-resume` flag क्या करता है? +- [ ] Workflow को beginning से restart करता है +- [ ] Workflow को pause करता है +- [x] उन processes को skip करता है जो पहले से successfully complete हो चुके हैं +- [ ] Workflow का backup बनाता है + +और जानें: [4.1. Re-launch a workflow with `-resume`](#41-re-launch-a-workflow-with--resume) +</quiz> + +<quiz> +Workflow outputs publish करने के लिए default mode क्या है? +- [ ] Files को output directory में copy करना +- [x] Output directory में symbolic links बनाना +- [ ] Files को output directory में move करना +- [ ] Output directory में files compress करना + +और जानें: [2.3. Set the publish mode to copy](#23-set-the-publish-mode-to-copy) +</quiz> + +<quiz> +Command line से Nextflow workflow को parameter value कैसे pass करते हो? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +और जानें: [3.2. Set up a command-line parameter to capture user input](#32-set-up-a-command-line-parameter-to-capture-user-input) +</quiz> + +<quiz> +Nextflow script block के अंदर variable कैसे reference करते हो? +- [ ] `%variable%` syntax use करें +- [x] `#!groovy ${variable}` syntax use करें +- [ ] `{{variable}}` syntax use करें +- [ ] `[variable]` syntax use करें +</quiz> diff --git a/docs/hi/docs/hello_nextflow/02_hello_channels.md b/docs/hi/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..3a9d2e9292 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# भाग 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/02_hello_channels.md) उपलब्ध है। +/// + +इस course के Part 1 (Hello World) में, हमने तुम्हें दिखाया कि process call में directly input provide करके process को variable input कैसे provide करें: `sayHello(params.input)`। +यह जानबूझकर simplified approach था। +Practice में, उस approach की major limitations हैं; namely कि यह केवल बहुत simple cases के लिए काम करता है जहाँ हम process को केवल एक बार, single value पर run करना चाहते हैं। +अधिकांश realistic workflow use cases में, हम multiple values (उदाहरण के लिए, multiple samples के लिए experimental data) process करना चाहते हैं, इसलिए हमें inputs handle करने का एक अधिक sophisticated तरीका चाहिए। + +इसके लिए Nextflow **channels** हैं। +Channels ऐसी queues हैं जो inputs को efficiently handle करने और उन्हें multi-step workflows में एक step से दूसरे में shuttle करने के लिए designed हैं, जबकि built-in parallelism और कई additional benefits provide करते हैं। + +इस course के इस भाग में, तुम सीखोगे कि विभिन्न स्रोतों से multiple inputs handle करने के लिए channel कैसे use करें। +तुम channel contents को आवश्यकतानुसार transform करने के लिए **operators** use करना भी सीखोगे। + +??? info "इस section से कैसे शुरू करें" + + Course का यह section मानता है कि तुमने [Hello Nextflow](./index.md) course का Part 1 complete कर लिया है, लेकिन यदि तुम उस section में covered basics से comfortable हो, तो तुम बिना कुछ special किए यहाँ से शुरू कर सकते हो। + +--- + +## 0. Warmup: `hello-channels.nf` चलाएं + +हम starting point के रूप में workflow script `hello-channels.nf` use करेंगे। +यह इस training course के Part 1 में काम करके produce की गई script के equivalent है, सिवाय इसके कि हमने output destination बदल दी है: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +यह sure करने के लिए कि सब कुछ काम कर रहा है, कोई भी changes करने से पहले script को एक बार run करो: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +पहले की तरह, तुम `results/hello_channels` directory में `output.txt` नामक output file पाओगे (जैसा कि workflow script के `output` block में specify किया गया है, ऊपर दिखाया गया है)। + +??? abstract "Directory contents" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "File contents" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +यदि यह तुम्हारे लिए काम किया, तो तुम channels के बारे में सीखने के लिए ready हो। + +--- + +## 1. Channel के माध्यम से explicitly variable inputs provide करें + +हम implicit handling पर rely करने के बजाय `sayHello()` process को variable input pass करने के लिए एक **channel** बनाएंगे, जिसकी certain limitations हैं। + +### 1.1. Input channel बनाएं + +Channel set up करने के लिए हम विभिन्न प्रकार के **channel factories** use कर सकते हैं। +अभी के लिए चीजों को simple रखने के लिए, हम सबसे basic channel factory use करेंगे, जिसे `channel.of` कहते हैं, जो single value वाला channel बनाएगा। +Functionally यह पहले जैसे set up के similar होगा, लेकिन Nextflow को implicitly channel बनाने देने के बजाय, अब हम यह explicitly कर रहे हैं। + +यह code की वह line है जिसे हम use करेंगे: + +```console title="Syntax" +greeting_ch = channel.of('Hello Channels!') +``` + +यह `channel.of()` channel factory का उपयोग करके `greeting_ch` नामक एक channel बनाता है, जो एक simple queue channel set up करता है, और greeting value के रूप में use करने के लिए string `'Hello Channels!'` load करता है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "नोट" + + हम readability के लिए temporarily CLI parameter use करने के बजाय hardcoded strings पर वापस switch कर रहे हैं। Channel के level पर जो हो रहा है उसे cover करने के बाद हम CLI parameters use करने पर वापस जाएंगे। + +Workflow block में, channel factory code add करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels!') + // एक अभिवादन emit करें + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // एक अभिवादन emit करें + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +यह अभी functional नहीं है क्योंकि हमने अभी तक process call को input switch नहीं किया है। + +### 1.2. Process call में input के रूप में channel add करें + +अब हमें अपने newly created channel को `sayHello()` process call में plug करना होगा, जिस CLI parameter को हम पहले directly provide कर रहे थे उसे replace करते हुए। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels!') + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels!') + // एक अभिवादन emit करें + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +यह Nextflow को बताता है कि `greeting_ch` channel की contents पर `sayHello` process run करे। + +अब हमारा workflow properly functional है; यह `sayHello('Hello Channels!')` लिखने का explicit equivalent है। + +### 1.3. Workflow चलाएं + +चलो इसे चलाते हैं! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +यदि तुमने दोनों edits correctly किए, तो तुम्हें एक successful execution मिलनी चाहिए। +तुम results directory check कर सकते हो यह satisfy करने के लिए कि outcome अभी भी पहले जैसा ही है। + +??? abstract "File contents" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +तो हमने same end result achieve करते हुए अपने workflow की flexibility बढ़ा दी है। +यह ऐसा लग सकता है कि हम बिना किसी tangible benefit के more code लिख रहे हैं, लेकिन जैसे ही हम more inputs handle करना शुरू करेंगे value clear हो जाएगी। + +उसके preview के रूप में, move on करने से पहले एक और चीज़ देखते हैं: data input manage करने के लिए explicit channel use करने का एक छोटा लेकिन convenient benefit। + +### 1.4. Channel contents inspect करने के लिए `view()` use करें + +Nextflow channels इस तरह built हैं कि हम operators का उपयोग करके उनकी contents पर operate कर सकते हैं, जिसे हम इस chapter में बाद में detail में cover करेंगे। + +अभी के लिए, हम तुम्हें बस दिखाएंगे कि channel की contents inspect करने के लिए [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) नामक एक super simple operator कैसे use करें। +तुम `view()` को एक debugging tool के रूप में सोच सकते हो, जैसे Python में `print()` statement, या अन्य languages में इसके equivalent। + +Workflow block में यह tiny line add करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels!') + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels!') + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Exact spaces की amount matter नहीं करती जब तक यह 4 का multiple है; हम बस `.view()` statement की start को channel construction के `.of()` part से align करने का aim कर रहे हैं। + +अब workflow फिर से run करो: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +जैसा कि तुम देख सकते हो, यह channel contents को console पर output करता है। +यहाँ हमारे पास केवल एक element है, लेकिन जब हम next section में channel में multiple values load करना शुरू करेंगे, तुम देखोगे कि यह एक element per line output करने के लिए set है। + +### सीख + +तुम जानते हो कि process को input provide करने के लिए basic channel factory कैसे use करें। + +### आगे क्या? + +सीखो कि workflow को multiple input values पर iterate करने के लिए channels कैसे use करें। + +--- + +## 2. Multiple input values पर run करने के लिए workflow modify करें + +Workflows typically inputs के batches पर run होते हैं जो bulk में process होने के लिए meant हैं, इसलिए हम workflow को upgrade करना चाहते हैं ताकि multiple input values accept कर सके। + +### 2.1. Input channel में multiple greetings load करें + +Conveniently, `channel.of()` channel factory जो हम use कर रहे हैं वह एक से अधिक value accept करने में काफी खुश है, इसलिए हमें उसे modify करने की need नहीं है। +हम बस channel में multiple values load कर सकते हैं। + +चलो उन्हें `'Hello'`, `'Bonjour'` और `'Holà'` बनाते हैं। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Diagram में, channel को green में represent किया गया है, और elements का order pipe में marbles की तरह represent किया गया है: पहले load किया गया right पर है, फिर दूसरा middle में है, फिर तीसरा left पर है।_ + +#### 2.1.1. More greetings add करें + +Workflow block से पहले, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +Documentation हमें बताती है कि यह काम करना चाहिए। क्या यह सच में इतना simple हो सकता है? + +#### 2.1.2. Command run करें और log output देखें + +चलो try करते हैं। + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +यह certainly ठीक से run हुआ लगता है। +Execution monitor दिखाता है कि `sayHello` process के लिए `3 of 3` calls किए गए, और हम `view()` statement द्वारा enumerate किए गए तीन greetings देखते हैं, जैसा promised एक per line। + +हालाँकि, results directory में अभी भी केवल एक output है: + +??? abstract "Directory contents" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "File contents" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +तुम्हें वहाँ तीन greetings में से एक दिखनी चाहिए, लेकिन जो तुम्हें मिली वह यहाँ दिखाई गई से different हो सकती है। +क्या तुम सोच सकते हो कि ऐसा क्यों हो सकता है? + +Execution monitor को वापस देखते हुए, इसने हमें केवल एक subdirectory path (`f4/c9962c`) दी। +चलो वहाँ देखते हैं। + +??? abstract "Directory contents" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "File contents" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +यह तो वह greeting भी नहीं है जो हमें results directory में मिली! क्या हो रहा है? + +इस point पर, हमें तुम्हें बताना होगा कि default रूप से, ANSI logging system same process के multiple calls से logging को same line पर लिखता है। +तो sayHello() process के तीनों calls से status same spot पर land कर रही है। + +सौभाग्य से, हम process calls की full list देखने के लिए उस behavior को disable कर सकते हैं। + +#### 2.1.3. `-ansi-log false` option के साथ command फिर से run करें + +Logging को expand करके per process call एक line display करने के लिए, command में `-ansi-log false` add करो। + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +इस बार हम output में listed तीनों process runs और उनके associated work subdirectories देखते हैं। + +यह बहुत better है, कम से कम एक simple workflow के लिए। +एक complex workflow, या बड़ी संख्या में inputs के लिए, terminal पर full list output होने से थोड़ा overwhelming हो जाएगा। +इसीलिए `-ansi-log false` default behavior नहीं है। + +!!! tip "सुझाव" + + Status report करने का तरीका दो logging modes के बीच थोड़ा different है। + Condensed mode में, Nextflow report करता है कि calls successfully complete हुईं या नहीं। + इस expanded mode में, यह केवल report करता है कि वे submitted की गईं। + +Anyway, अब जबकि हमारे पास प्रत्येक process call की subdirectories हैं, हम उनके logs और outputs खोज सकते हैं। + +??? abstract "Directory contents" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "File contents" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +यह दिखाता है कि तीनों processes successfully run हुईं (yay)। + +उस ने कहा, हमारे पास अभी भी problem है कि results directory में केवल एक output file है। + +तुम्हें याद होगा कि हमने `sayHello` process के लिए output file name hardcode किया था, इसलिए तीनों calls ने `output.txt` नामक file produce की। + +जब तक output files work subdirectories में रहती हैं, अन्य processes से isolated, तब तक यह okay है। +लेकिन जब वे same results directory में publish होती हैं, जो भी पहले वहाँ copy की गई वह अगली द्वारा overwrite हो जाती है, और इसी तरह। + +### 2.2. सुनिश्चित करें कि output file names unique होंगे + +हम सभी outputs को same results directory में publish करना जारी रख सकते हैं, लेकिन हमें ensure करना होगा कि उनके unique names होंगे। +Specifically, हमें first process को dynamically file name generate करने के लिए modify करना होगा ताकि final file names unique हों। + +तो हम file names को unique कैसे बनाएं? +ऐसा करने का एक common तरीका output file name के भाग के रूप में inputs (input channel से received) से कुछ unique metadata use करना है। +यहाँ, convenience के लिए, हम greeting itself use करेंगे क्योंकि यह बस एक short string है, और इसे base output filename से पहले prepend करेंगे। + +#### 2.2.1. Dynamic output file name construct करें + +Process block में, निम्नलिखित code changes करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Output definition और `script:` command block दोनों में `output.txt` replace करना sure करो। + +!!! tip "सुझाव" + + Output definition में, तुम्हें output filename expression के आसपास double quotes use करना MUST है (single quotes नहीं), otherwise यह fail होगा। + +यह हर बार process call होने पर एक unique output file name produce करेगा, ताकि इसे output directory में same process के अन्य calls के outputs से distinguish किया जा सके। + +#### 2.2.2. Workflow चलाएं + +चलो इसे run करते हैं। Note करो कि हम default ANSI log settings के साथ वापस running पर हैं। + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Summary view पर वापस आते हुए, output फिर से एक line पर summarize हो गया है। +यह देखने के लिए `results` directory पर नज़र डालो कि क्या सभी output greetings वहाँ हैं। + +??? abstract "Directory contents" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +हाँ! और प्रत्येक में expected contents हैं। + +??? abstract "File contents" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Success! अब हम जितनी चाहें उतनी greetings add कर सकते हैं बिना output files के overwrite होने की चिंता किए। + +!!! tip "सुझाव" + + Practice में, input data itself के आधार पर files name करना almost हमेशा impractical है। + Dynamic filenames generate करने का better तरीका input files के साथ metadata को process में pass करना है। + Metadata typically 'sample sheet' या equivalents के माध्यम से provide किया जाता है। + तुम यह बाद में अपने Nextflow training में सीखोगे ([Metadata side quest](../side_quests/metadata.md) देखें)। + +### सीख + +तुम जानते हो कि channel के माध्यम से multiple input elements कैसे feed करें। + +### आगे क्या? + +सीखो कि channel की contents transform करने के लिए operator कैसे use करें। + +--- + +## 3. Array के माध्यम से multiple inputs provide करें + +हमने अभी तुम्हें दिखाया कि multiple input elements कैसे handle करें जो directly channel factory में hardcoded थे। +क्या होगा यदि हम उन multiple inputs को different way में provide करना चाहते? + +उदाहरण के लिए, imagine करो कि हम इस तरह elements का array वाला एक input variable set up करते हैं: + +`greetings_array = ['Hello','Bonjour','Holà']` + +क्या हम उसे अपने output channel में load कर सकते हैं और expect कर सकते हैं कि यह काम करे? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +चलो पता लगाते हैं। + +### 3.1. Channel को input के रूप में values का array provide करें + +Common sense suggest करता है कि हमें single value के बजाय simply values का array pass करने में सक्षम होना चाहिए। +चलो try करते हैं; हमें input variable set up करना होगा और इसे channel factory में load करना होगा। + +#### 3.1.1. Input variable set up करें + +चलो `greetings_array` variable जो हमने अभी imagine किया उसे workflow block में add करके reality बनाते हैं: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +यह अभी functional नहीं है, हमने बस array के लिए declaration add किया है। + +#### 3.1.2. Channel factory को input के रूप में greetings का array set करें + +अब हम channel factory में currently hardcoded values `'Hello','Bonjour','Holà'` को अभी बनाए गए `greetings_array` से replace करेंगे। + +Workflow block में, निम्नलिखित change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +यह अब functional होना चाहिए। + +#### 3.1.3. Workflow चलाएं + +चलो इसे running try करते हैं: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Command output" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +अरे नहीं! Error है! + +`view()` का output और error messages देखो। + +ऐसा लगता है Nextflow ने single process call run करने की कोशिश की, `[Hello, Bonjour, Holà]` को string value के रूप में use करते हुए, array में तीन strings को separate values के रूप में use करने के बजाय। + +तो यह 'packaging' है जो problem cause कर रही है। +हम Nextflow को array unpack करवाकर individual strings को channel में load कैसे करवाएं? + +### 3.2. Channel contents transform करने के लिए operator use करें + +यहीं **[operators](https://www.nextflow.io/docs/latest/reference/operator.html)** play में आते हैं। +तुम पहले से `.view()` operator use कर चुके हो, जो बस देखता है कि वहाँ क्या है। +अब हम उन operators को देखेंगे जो हमें channel की contents पर act करने की अनुमति देते हैं। + +यदि तुम Nextflow documentation में [operators की list](https://www.nextflow.io/docs/latest/reference/operator.html) skim through करते हो, तो तुम [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten) पाओगे, जो exactly वही करता है जो हमें चाहिए: array की contents unpack करना और उन्हें individual items के रूप में emit करना। + +#### 3.2.1. `flatten()` operator add करें + +हमारे input channel पर `flatten()` operator apply करने के लिए, हम इसे channel factory declaration में append करते हैं। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +यहाँ हमने readability के लिए operator को next line पर add किया, लेकिन तुम prefer करो तो operators को channel factory के same line पर add कर सकते हो, इस तरह: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. `view()` statement(s) refine करें + +हम इसे test करने के लिए तुरंत run कर सकते हैं, लेकिन जब हम इस पर हैं, हम channel contents को inspect करने के तरीके को refine करेंगे। + +हम यह contrast करने में सक्षम होना चाहते हैं कि `flatten()` operator apply होने से पहले और बाद में contents कैसी दिखती हैं, इसलिए हम दूसरा add करेंगे, AND हम उन्हें output में अधिक clearly labeled करने के लिए थोड़ा code add करेंगे। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +तुम देखोगे कि हमने दूसरा `.view` statement add किया है, और प्रत्येक के लिए, हमने empty parentheses (`()`) को curly braces से replace किया है जिसमें कुछ code है, जैसे `{ greeting -> "Before flatten: $greeting" }`। + +इन्हें _closures_ कहते हैं। इनमें contained code channel में प्रत्येक item के लिए execute होगा। +हम inner value के लिए एक temporary variable define करते हैं, यहाँ `greeting` कहलाता है (लेकिन यह कोई भी arbitrary name हो सकता है), जो केवल उस closure के scope के भीतर use होता है। + +इस example में, `$greeting` channel में load किए गए प्रत्येक individual item को represent करता है। +इसका result neatly labeled console output होगा। + +!!! info "जानकारी" + + कुछ pipelines में तुम operator closures के अंदर `$it` नामक एक special variable देख सकते हो। + यह एक _implicit_ variable है जो inner variable तक short-hand access की अनुमति देती है, + बिना इसे `->` के साथ define करने की need के। + + हम clarity में मदद के लिए explicit होना prefer करते हैं, इसलिए `$it` syntax discouraged है और slowly Nextflow language से phase out हो जाएगी। + +#### 3.2.3. Workflow चलाएं + +Finally, तुम workflow को फिर से running try कर सकते हो! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +इस बार यह काम करता है AND हमें `flatten()` operator run करने से पहले और बाद में channel की contents कैसी दिखती हैं इसकी additional insight देता है। + +- तुम देखोगे कि हमें एक single `Before flatten:` statement मिलता है क्योंकि उस point पर channel में एक item है, original array। + फिर हमें तीन separate `After flatten:` statements मिलते हैं, प्रत्येक greeting के लिए एक, जो अब channel में individual items हैं। + +महत्वपूर्ण रूप से, इसका मतलब है कि प्रत्येक item अब workflow द्वारा separately process किया जा सकता है। + +!!! tip "सुझाव" + + एक different channel factory, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist) use करके technically same results achieve करना संभव है, जिसमें इसके operation में एक implicit mapping step शामिल है। + यहाँ हमने वह use न करने का choice किया ताकि एक simple use case पर operator के use को demonstrate किया जा सके। + +### सीख + +तुम जानते हो कि channel की contents transform करने के लिए `flatten()` जैसे operator कैसे use करें, और operator apply करने से पहले और बाद में channel contents inspect करने के लिए `view()` operator कैसे use करें। + +### आगे क्या? + +सीखो कि workflow को input values के source के रूप में file कैसे लेने दें। + +--- + +## 4. CSV file से input values पढ़ें + +Realistically, हम शायद ही कभी values के array से शुरू करेंगे। +Most likely, हमारे पास एक या अधिक files होंगी जिनमें वह data है जिसे process करना है, किसी प्रकार के structured format में। + +हमने `greetings.csv` नामक एक CSV file prepare की है जिसमें कई input greetings हैं, उस तरह के columnar data को mimic करते हुए जो तुम real data analysis में process करना चाह सकते हो, `data/` के तहत stored। +(Numbers meaningful नहीं हैं, वे बस illustrative purposes के लिए हैं।) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +हमारा next task अपने workflow को इस file से values पढ़ने के लिए adapt करना है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +चलो देखते हैं कि हम यह कैसे कर सकते हैं। + +### 4.1. Greetings के source के रूप में CSV file expect करने के लिए script modify करें + +शुरू करने के लिए, हमें script में दो key changes करने होंगे: + +- Input parameter को CSV file point करने के लिए switch करें +- Channel factory को file handle करने के लिए designed किसी में switch करें + +#### 4.1.1. Input parameter को CSV file point करने के लिए switch करें + +Part 1 में हमने जो `params.input` parameter set up किया था याद है? +हम इसे update करेंगे ताकि हमारी greetings वाली CSV file point करे। + +Parameter declaration में निम्नलिखित edit करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline पैरामीटर + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + input: String = 'Holà mundo!' + ``` + +यह मानता है कि file workflow code के साथ co-located है। +तुम बाद में अपनी Nextflow journey में अन्य data locations के साथ deal करना सीखोगे। + +#### 4.1.2. File handle करने के लिए designed channel factory में switch करें + +चूंकि अब हम simple strings के बजाय file को input के रूप में use करना चाहते हैं, हम पहले वाली `channel.of()` channel factory use नहीं कर सकते। +हमें एक new channel factory, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path) use करने में switch करना होगा, जिसमें file paths handle करने के लिए कुछ built-in functionality है। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() को uncomment करें + // .view { greeting -> "Flatten के बाद: $greeting" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // इनपुट अभिवादनों की एक array declare करें + greetings_array = ['Hello','Bonjour','Holà'] + // इनपुट के लिए एक channel बनाएं + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +तुम notice करोगे कि हमने channel input को `param.input` पर वापस switch किया, और `greetings_array` declaration delete कर दी क्योंकि अब हमें इसकी need नहीं होगी। +हमने `flatten()` और दूसरे `view()` statement को भी comment out कर दिया है। + +#### 4.1.3. Workflow चलाएं + +चलो new channel factory और input file के साथ workflow running try करते हैं। + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Command output" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +अरे नहीं, यह काम नहीं करता। Console output और error message की start देखो। +`Command executed:` bit यहाँ विशेष रूप से helpful है। + +यह थोड़ा familiar लग सकता है। +ऐसा लगता है Nextflow ने file path itself को string value के रूप में use करके single process call run करने की कोशिश की। +तो इसने file path correctly resolve किया है, लेकिन इसने actually इसकी contents parse नहीं की, जो हम चाहते थे। + +हम Nextflow को file open करवाकर इसकी contents को channel में load कैसे करवाएं? + +Sounds like हमें एक और [operator](https://www.nextflow.io/docs/latest/reference/operator.html) चाहिए! + +### 4.2. File parse करने के लिए `splitCsv()` operator use करें + +Operators की list को फिर से देखते हुए, हमें [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv) मिलता है, जो CSV-formatted text को parse और split करने के लिए designed है। + +#### 4.2.1. Channel पर `splitCsv()` apply करें + +Operator apply करने के लिए, हम इसे पहले की तरह channel factory line में append करते हैं। + +Workflow block में, `flatten()` को `splitcsv()` (uncommented) से replace करने के लिए निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() को uncomment करें + // .view { greeting -> "Flatten के बाद: $greeting" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +जैसा तुम देख सकते हो, हमने before/after `view()` statements भी update किए हैं। +Technically हम same variable name (`greeting`) use कर सकते थे लेकिन हमने इसे कुछ अधिक appropriate (`csv`) में update किया ताकि code दूसरों द्वारा अधिक readable हो। + +#### 4.2.2. Workflow फिर से चलाएं + +चलो added CSV-parsing logic के साथ workflow running try करते हैं। + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Command output" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Interestingly, यह भी fail होता है, लेकिन एक different error के साथ। +इस बार Nextflow ने file की contents parse की हैं (yay!) लेकिन इसने प्रत्येक row को एक array के रूप में load किया है, और प्रत्येक array channel में एक element है। + +हमें इसे बताना होगा कि प्रत्येक row में केवल first column ले। +तो हम इसे कैसे unpack करें? + +हमने पहले channel की contents unpack करने के लिए `flatten()` use किया है, लेकिन यह यहाँ काम नहीं करेगा क्योंकि flatten _everything_ unpack करता है (यदि तुम खुद देखना चाहते हो तो try करो)। + +इसके बजाय, हम `map()` नामक एक और operator use करेंगे जो वास्तव में useful है और Nextflow pipelines में बहुत pop up होता है। + +### 4.3. Greetings extract करने के लिए `map()` operator use करें + +[`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) operator एक बहुत handy little tool है जो हमें channel की contents पर सभी प्रकार की mappings करने की अनुमति देता है। + +इस case में, हम इसे अपनी data file में प्रत्येक row से उस एक element को extract करने के लिए use करेंगे जो हम चाहते हैं। +Syntax ऐसा दिखता है: + +```groovy title="Syntax" +.map { row -> row[0] } +``` + +इसका मतलब है 'channel में प्रत्येक row के लिए, उसमें contained 0th (first) item लो'। + +तो चलो इसे अपने CSV parsing पर apply करते हैं। + +#### 4.3.1. Channel पर `map()` apply करें + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +तुम देखोगे कि हमने confirm करने के लिए एक और `view()` call add किया कि operator वही करता है जो हम expect करते हैं। + +#### 4.3.2. Workflow चलाएं + +चलो इसे एक बार और run करते हैं: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +इस बार यह बिना error के run होना चाहिए। + +`view()` statements के output को देखते हुए, तुम निम्नलिखित देखोगे: + +- एक single `Before splitCsv:` statement: उस point पर channel में एक item है, original file path। +- तीन separate `After splitCsv:` statements: प्रत्येक greeting के लिए एक, लेकिन प्रत्येक एक array के भीतर contained है जो file में उस line से correspond करता है। +- तीन separate `After map:` statements: प्रत्येक greeting के लिए एक, जो अब channel में individual elements हैं। + +Note करो कि lines तुम्हारे output में different order में appear हो सकती हैं। + +तुम यह verify करने के लिए output files भी देख सकते हो कि प्रत्येक greeting correctly extract और workflow के माध्यम से process हुई। + +हमने पहले जैसा same result achieve किया है, लेकिन अब हमारे पास process करने के लिए greetings के channel में more elements add करने की बहुत अधिक flexibility है एक input file modify करके, बिना कोई code modify किए। +तुम बाद की training में complex inputs handle करने के लिए more sophisticated approaches सीखोगे। + +### सीख + +तुम जानते हो कि `.fromPath()` channel constructor और operators `splitCsv()` और `map()` का उपयोग करके input values की file पढ़ना और उन्हें appropriately handle करना। + +अधिक generally, तुम्हारे पास basic understanding है कि Nextflow कैसे processes को inputs manage करने के लिए **channels** और उनकी contents transform करने के लिए **operators** use करता है। + +### आगे क्या? + +एक big break लो, तुमने इसमें hard work किया! + +जब तुम ready हो, तो [**Part 3: Hello Workflow**](./03_hello_workflow.md) पर move करो यह सीखने के लिए कि more steps कैसे add करें और उन्हें एक proper workflow में कैसे connect करें। + +--- + +## Quiz + +<quiz> +Nextflow में channel क्या है? +- [ ] एक file path specification +- [ ] एक process definition +- [x] Processes के बीच data pass करने के लिए एक queue-जैसी structure +- [ ] एक configuration setting + +और जानें: [1.1. Create an input channel](#11-create-an-input-channel) +</quiz> + +<quiz> +यह code क्या output करेगा? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (एक single list) +- [x] प्रत्येक element separate line पर: `Hello`, `Bonjour`, `Hola` +- [ ] कुछ नहीं (channels default रूप से print नहीं करते) +- [ ] एक error (invalid syntax) + +और जानें: [1.1. Create an input channel](#11-create-an-input-channel) +</quiz> + +<quiz> +जब channel में multiple values होती हैं, Nextflow process execution कैसे handle करता है? +- [ ] Process सभी values के साथ एक बार run होता है +- [x] Process channel में प्रत्येक value के लिए एक बार run होता है +- [ ] Process केवल first value के साथ run होता है +- [ ] Process केवल last value के साथ run होता है + +और जानें: [2. Modify the workflow to run on multiple input values](#2-modify-the-workflow-to-run-on-multiple-input-values) +</quiz> + +<quiz> +`flatten()` operator क्या करता है? +- [ ] Multiple channels को एक में combine करता है +- [ ] Channel elements को sort करता है +- [x] Arrays को individual elements में unpack करता है +- [ ] Duplicate elements remove करता है + +और जानें: [3.2.1. Add the `flatten()` operator](#321-add-the-flatten-operator) +</quiz> + +<quiz> +`view()` operator का purpose क्या है? +- [ ] Channel contents filter करना +- [ ] Channel elements transform करना +- [x] Channel contents inspect और debug करना +- [ ] Channel contents को file में save करना + +और जानें: [1.4. Use `view()` to inspect the channel contents](#14-use-view-to-inspect-the-channel-contents) +</quiz> + +<quiz> +`splitCsv()` क्या करता है? +- [ ] Channel contents से CSV file बनाता है +- [ ] String को commas से split करता है +- [x] CSV file को प्रत्येक row represent करने वाले arrays में parse करता है +- [ ] Multiple CSV files merge करता है + +और जानें: [4.2. Use the `splitCsv()` operator to parse the file](#42-use-the-splitcsv-operator-to-parse-the-file) +</quiz> + +<quiz> +`map()` operator का purpose क्या है? +- [ ] Channel से elements filter करना +- [ ] Multiple channels combine करना +- [x] Channel में प्रत्येक element को transform करना +- [ ] Channel में elements count करना + +और जानें: [4.3. Use the `map()` operator to extract the greetings](#43-use-the-map-operator-to-extract-the-greetings) +</quiz> + +<quiz> +Multiple inputs process करते समय dynamic output filenames use करना क्यों important है? +- [ ] Performance improve करने के लिए +- [ ] Disk space reduce करने के लिए +- [x] Output files को एक दूसरे को overwrite करने से रोकने के लिए +- [ ] Resume functionality enable करने के लिए + +और जानें: [2.2. Ensure the output file names will be unique](#22-ensure-the-output-file-names-will-be-unique) +</quiz> diff --git a/docs/hi/docs/hello_nextflow/03_hello_workflow.md b/docs/hi/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..122a35caff --- /dev/null +++ b/docs/hi/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,602 @@ +# भाग 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/03_hello_workflow.md) उपलब्ध है। +/// + +अधिकांश real-world workflows में एक से अधिक step शामिल होते हैं। +इस training module में, तुम सीखोगे कि multi-step workflow में processes को एक साथ कैसे connect करें। + +यह तुम्हें निम्नलिखित achieve करने का Nextflow तरीका सिखाएगा: + +1. एक process से दूसरे में data flow करवाना +2. Multiple process calls से outputs को एक single process call में collect करना +3. एक process को एक से अधिक input pass करना +4. एक process से आने वाले multiple outputs handle करना + +Demonstrate करने के लिए, हम Parts 1 और 2 के domain-agnostic Hello World example पर build करना जारी रखेंगे। +इस बार, हम अपने workflow में निम्नलिखित changes करेंगे जो बेहतर reflect करते हैं कि लोग actual workflows कैसे बनाते हैं: + +1. Greeting को uppercase में convert करने वाला एक second step add करें। +2. सभी transformed greetings collect करने और उन्हें एक single file में लिखने वाला एक third step add करें। +3. Final output file को name करने के लिए एक parameter add करें और उसे collection step को secondary input के रूप में pass करें। +4. Collection step को process किए गए के बारे में एक simple statistic भी report करवाएं। + +??? info "इस section से कैसे शुरू करें" + + Course का यह section मानता है कि तुमने [Hello Nextflow](./index.md) course के Parts 1-2 complete कर लिए हैं, लेकिन यदि तुम उन sections में covered basics से comfortable हो, तो तुम बिना कुछ special किए यहाँ से शुरू कर सकते हो। + +--- + +## 0. Warmup: `hello-workflow.nf` चलाएं + +हम starting point के रूप में workflow script `hello-workflow.nf` use करेंगे। +यह इस training course के Part 2 में काम करके produce की गई script के equivalent है, सिवाय इसके कि हमने `view()` statements remove कर दिए हैं और output destination बदल दी है: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +यह sure करने के लिए कि सब कुछ काम कर रहा है, कोई भी changes करने से पहले script को एक बार run करो: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +पहले की तरह, तुम `output` block में specified location पर output files पाओगे। +इस chapter के लिए, यह `results/hello_workflow/` के तहत है। + +??? abstract "Directory contents" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +यदि यह तुम्हारे लिए काम किया, तो तुम multi-step workflow assemble करना सीखने के लिए ready हो। + +--- + +## 1. Workflow में एक second step add करें + +हम प्रत्येक greeting को uppercase में convert करने के लिए एक step add करेंगे। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +इसके लिए, हमें तीन चीजें करनी होंगी: + +- Uppercase conversion करने के लिए जो command use करेंगे उसे define करें। +- Uppercasing command wrap करने वाला एक new process लिखें। +- Workflow block में new process call करें और इसे `sayHello()` process के output को input के रूप में लेने के लिए set up करें। + +### 1.1. Uppercasing command define करें और terminal में test करें + +Greetings को uppercase में conversion करने के लिए, हम `tr` नामक एक classic UNIX tool use करेंगे 'text replacement' के लिए, निम्नलिखित syntax के साथ: + +```bash title="Syntax" +tr '[a-z]' '[A-Z]' +``` + +यह एक बहुत naive text replacement one-liner है जो accented letters के लिए account नहीं करती, इसलिए उदाहरण के लिए 'Holà' 'HOLà' बन जाएगा, लेकिन यह Nextflow concepts demonstrate करने के लिए काफी अच्छा job करेगी और यही matter करता है। + +इसे test करने के लिए, हम `echo 'Hello World'` command run कर सकते हैं और इसका output `tr` command को pipe कर सकते हैं: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +Output `UPPER-output.txt` नामक एक text file है जिसमें `Hello World` string का uppercase version है। + +??? abstract "File contents" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +यही basically हम अपने workflow के साथ करने की कोशिश करेंगे। + +### 1.2. Uppercasing step को Nextflow process के रूप में लिखें + +हम अपने new process को पहले वाले पर model कर सकते हैं, क्योंकि हम सभी same components use करना चाहते हैं। + +Workflow script में, पहले वाले के ठीक नीचे निम्नलिखित process definition add करो: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * अभिवादन को uppercase में बदलने के लिए text replacement tool का उपयोग करें + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +इसमें, हम input filename के आधार पर second output filename compose करते हैं, जैसा हमने originally first process के output के लिए किया था। + +### 1.3. Workflow block में new process का call add करें + +अब हमें Nextflow को बताना होगा कि actually हमने जो process define किया उसे call करे। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + // अभिवादन को uppercase में बदलें + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +यह अभी functional नहीं है क्योंकि हमने specify नहीं किया कि `convertToUpper()` process को क्या input होना चाहिए। + +### 1.4. First process का output second process को pass करें + +अब हमें `sayHello()` process का output `convertToUpper()` process में flow करवाना होगा। + +Conveniently, Nextflow automatically process का output `<process>.out` नामक channel में package करता है। +तो `sayHello` process का output `sayHello.out` नामक channel है, जिसे हम सीधे `convertToUpper()` के call में plug कर सकते हैं। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // अभिवादन को uppercase में बदलें + convertToUpper() + ``` + +इस तरह के simple case (एक output से एक input) के लिए, दो processes connect करने के लिए बस इतना करना होगा! + +### 1.5. Workflow output publishing set up करें + +Finally, चलो workflow outputs update करते हैं ताकि second process के results भी publish हों। + +#### 1.5.1. `workflow` block का `publish:` section update करें + +`workflow` block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +Logic पहले जैसा ही है। + +#### 1.5.2. `output` block update करें + +`output` block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +एक बार फिर, logic पहले जैसा ही है। + +### 1.6. `-resume` के साथ workflow चलाएं + +चलो `-resume` flag का उपयोग करके इसे test करते हैं, क्योंकि हम पहले से workflow का first step successfully run कर चुके हैं। + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Console output में अब एक extra line है जो हमने अभी add किए new process से correspond करती है। + +तुम `results/hello_workflow` directory में outputs पाओगे जैसा `output` block में set है। + +??? abstract "Directory contents" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +### सीख + +तुम जानते हो कि एक step का output अगले step को input के रूप में provide करके processes को chain कैसे करें। + +### आगे क्या? + +सीखो कि batched process calls से outputs collect करके एक single process में कैसे feed करें। + +--- + +## 2. सभी greetings collect करने के लिए third step add करें + +जब हम यहाँ कर रहे हैं उस तरह channel में प्रत्येक element पर transformation apply करने के लिए process use करते हैं, तो कभी-कभी हम उस process के output channel से elements collect करना और उन्हें किसी प्रकार का analysis या summation perform करने वाले दूसरे process में feed करना चाहते हैं। + +Demonstrate करने के लिए, हम अपनी pipeline में एक new step add करेंगे जो `convertToUpper` process द्वारा produce किए गए सभी uppercase greetings collect करता है और उन्हें एक single file में लिखता है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Surprise spoil नहीं करना, लेकिन इसमें एक बहुत useful operator शामिल होगा। + +### 2.1. Collection command define करें और terminal में test करें + +जो collection step हम अपने workflow में add करना चाहते हैं वह `cat` command use करेगा multiple uppercased greetings को एक single file में concatenate करने के लिए। + +Terminal में command by itself run करो यह verify करने के लिए कि यह expected तरीके से काम करता है, जैसा हमने पहले किया था। + +अपने terminal में निम्नलिखित run करो: + +```bash +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 +``` + +Output `COLLECTED-output.txt` नामक एक text file है जिसमें original greetings के uppercase versions हैं। + +??? abstract "File contents" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +यही result है जो हम अपने workflow से achieve करना चाहते हैं। + +### 2.2. Collection step करने के लिए new process बनाएं + +चलो एक new process बनाते हैं और इसे `collectGreetings()` call करते हैं। + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Uppercase अभिवादनों को एक single output फ़ाइल में collect करें + */ +process collectGreetings { + + input: + path input_files + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ +} +``` + +### 2.3. Workflow में collection step add करें + +अब हमें बस uppercasing step के output पर collection process call करना चाहिए। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out) + } + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="75" + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + } + ``` + +### 2.4. Greetings को single input में collect करने के लिए operator use करें + +हमें aptly-named [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect) operator use करना होगा। + +Workflow block में, निम्नलिखित code change करो: + +=== "After" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Before" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out) + } + ``` + +### सीख + +तुम जानते हो कि batch of process calls से outputs collect करके joint analysis या summation step में कैसे feed करें। + +### आगे क्या? + +सीखो कि process को एक से अधिक input कैसे pass करें। + +--- + +## 3. Process को एक से अधिक input pass करें + +हम final output file को कुछ specific name देने में सक्षम होना चाहते हैं ताकि greetings के subsequent batches को previous results overwrite किए बिना process किया जा सके। + +### 3.1. Collector process modify करें + +हमें additional input declare करना होगा और इसे output file name में integrate करना होगा। + +```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name +``` + +### 3.2. `batch` command-line parameter add करें + +```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" +/* + * Pipeline पैरामीटर + */ +params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' +} +``` + +### 3.3. Workflow चलाएं + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +### सीख + +तुम जानते हो कि process को एक से अधिक input कैसे pass करें। + +### आगे क्या? + +सीखो कि multiple outputs emit और conveniently handle कैसे करें। + +--- + +## 4. Collector step में output add करें + +Multiple outputs separate channels में package होंगे। +हम या तो उन output channels को names दे सकते हैं, जो बाद में उन्हें individually refer करना आसान बनाता है, या हम उन्हें index द्वारा refer कर सकते हैं। + +### 4.1. Greetings count और output करने के लिए process modify करें + +```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +### 4.2. Workflow outputs update करें + +```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +### 4.3. Workflow चलाएं + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +### सीख + +तुम जानते हो कि process को multiple named outputs emit करवाना और उन्हें workflow level पर appropriately handle करना। + +अधिक generally, तुम common ways में processes को एक साथ connect करने में involved key principles समझते हो। + +### आगे क्या? + +Extra long break लो, तुमने इसे earn किया है। + +जब तुम ready हो, तो [**Part 4: Hello Modules**](./04_hello_modules.md) पर move करो यह सीखने के लिए कि better maintainability और code efficiency के लिए अपने code को कैसे modularize करें। + +--- + +## Quiz + +<quiz> +Workflow block में process का output कैसे access करते हो? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +और जानें: [1.4. Pass the output of the first process to the second process](#14-pass-the-output-of-the-first-process-to-the-second-process) +</quiz> + +<quiz> +Nextflow में process execution का order क्या determine करता है? +- [ ] Workflow block में processes लिखे जाने का order +- [ ] Process name द्वारा alphabetical order +- [x] Processes के बीच data dependencies +- [ ] Parallel execution के लिए random order + +और जानें: [1.4. Pass the output of the first process to the second process](#14-pass-the-output-of-the-first-process-to-the-second-process) +</quiz> + +<quiz> +Downstream process के लिए सभी outputs को single list में gather करने के लिए `???` को कौन सा operator replace करना चाहिए? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +और जानें: [2.4. Use an operator to collect the greetings into a single input](#24-use-an-operator-to-collect-the-greetings-into-a-single-input) +</quiz> + +<quiz> +Process से named output कैसे access करते हो? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +और जानें: [4.1.2. Emit the report file and name outputs](#412-emit-the-report-file-and-name-outputs) +</quiz> + +<quiz> +Process में output name करने के लिए correct syntax क्या है? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +और जानें: [4.1.2. Emit the report file and name outputs](#412-emit-the-report-file-and-name-outputs) +</quiz> + +<quiz> +Process को multiple inputs provide करते समय क्या true होना चाहिए? +- [ ] सभी inputs same type के होने चाहिए +- [ ] Inputs alphabetical order में provide होने चाहिए +- [x] Inputs का order input block में defined order से match होना चाहिए +- [ ] एक बार में केवल दो inputs provide किए जा सकते हैं + +और जानें: [3. Pass more than one input to a process](#3-pass-more-than-one-input-to-a-process) +</quiz> diff --git a/docs/hi/docs/hello_nextflow/04_hello_modules.md b/docs/hi/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..3a06a03834 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,360 @@ +# भाग 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/04_hello_modules.md) उपलब्ध है। +/// + +यह section cover करता है कि अपने pipeline की development और maintenance को अधिक efficient और sustainable बनाने के लिए अपने workflow code को कैसे organize करें। +Specifically, हम demonstrate करेंगे कि **modules** कैसे use करें। + +Nextflow में, एक **module** एक single process definition है जो एक standalone code file में खुद से encapsulated है। +Workflow में module use करने के लिए, तुम बस अपनी workflow code file में एक single-line import statement add करते हो; फिर तुम process को उसी तरह workflow में integrate कर सकते हो जैसे normally करते। +यह multiple workflows में process definitions को reuse करना possible बनाता है बिना code की multiple copies produce किए। + +जब हमने अपना workflow develop करना शुरू किया, हमने सब कुछ एक single code file में लिखा। +अब हम processes को individual modules में move करेंगे। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +यह हमारे code को अधिक shareable, flexible और maintainable बनाएगा। + +??? info "इस section से कैसे शुरू करें" + + Course का यह section मानता है कि तुमने [Hello Nextflow](./index.md) course के Parts 1-3 complete कर लिए हैं, लेकिन यदि तुम उन sections में covered basics से comfortable हो, तो तुम बिना कुछ special किए यहाँ से शुरू कर सकते हो। + +--- + +## 0. Warmup: `hello-modules.nf` चलाएं + +हम starting point के रूप में workflow script `hello-modules.nf` use करेंगे। +यह इस training course के Part 3 में काम करके produce की गई script के equivalent है, सिवाय इसके कि हमने output destinations बदल दी हैं। + +यह sure करने के लिए कि सब कुछ काम कर रहा है, कोई भी changes करने से पहले script को एक बार run करो: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +यदि यह तुम्हारे लिए काम किया, तो तुम अपने workflow code को modularize करना सीखने के लिए ready हो। + +--- + +## 1. Modules store करने के लिए directory बनाएं + +अपने modules को specific directory में store करना best practice है। +तुम उस directory को कुछ भी कह सकते हो, लेकिन convention इसे `modules/` कहना है। + +```bash +mkdir modules +``` + +!!! tip "सुझाव" + + यहाँ हम तुम्हें दिखा रहे हैं कि **local modules** कैसे use करें, meaning modules जो workflow code के बाकी हिस्से के same repository में locally stored हैं, remote modules के contrast में, जो अन्य (remote) repositories में stored हैं। + **Remote modules** के बारे में अधिक जानकारी के लिए, [documentation](https://www.nextflow.io/docs/latest/module.html) देखें। + +--- + +## 2. `sayHello()` के लिए module बनाएं + +इसके simplest form में, existing process को module में turn करना little more than copy-paste operation है। +हम module के लिए एक file stub बनाएंगे, relevant code copy करेंगे फिर इसे main workflow file से delete करेंगे। + +फिर हमें बस एक import statement add करना होगा ताकि Nextflow जान सके कि runtime पर relevant code pull करना है। + +### 2.1. New module के लिए file stub बनाएं + +चलो `sayHello.nf` नामक module के लिए एक empty file बनाते हैं। + +```bash +touch modules/sayHello.nf +``` + +### 2.2. `sayHello` process code को module file में move करें + +Workflow file से पूरी process definition को module file में copy करो, `#!/usr/bin/env nextflow` shebang भी copy करना sure करो। + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +एक बार यह हो जाए, workflow file से process definition delete करो, लेकिन shebang को जगह पर छोड़ना sure करो। + +### 2.3. Workflow block से पहले import declaration add करें + +Local module import करने के लिए syntax काफी straightforward है: + +```groovy title="Syntax: Import declaration" +include { <MODULE_NAME> } from '<path_to_module>' +``` + +चलो इसे `params` block के ऊपर insert करते हैं और इसे appropriately fill out करते हैं। + +=== "After" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Modules को include करें + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline पैरामीटर + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Before" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline पैरामीटर + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +### 2.4. Workflow चलाएं + +हम पहले जैसे essentially same code और inputs के साथ workflow run कर रहे हैं, तो चलो `-resume` flag के साथ run करते हैं और देखते हैं क्या होता है। + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Command output" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +यह बहुत जल्दी run होना चाहिए क्योंकि सब कुछ cached है। + +Nextflow ने recognize किया कि यह अभी भी same work है, भले ही code multiple files में split हो। + +### सीख + +तुम जानते हो कि process को local module में extract कैसे करें और तुम जानते हो कि ऐसा करना workflow की resumability break नहीं करता। + +### आगे क्या? + +More modules बनाने की practice करो। + +--- + +## 3. `convertToUpper()` process को modularize करें + +### 3.1. New module के लिए file stub बनाएं + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. `convertToUpper` process code को module file में move करें + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * अभिवादन को uppercase में बदलने के लिए text replacement tool का उपयोग करें + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +### 3.3. `params` block से पहले import declaration add करें + +```groovy title="hello-modules.nf" linenums="23" hl_lines="3" +// Modules को include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +``` + +### 3.4. Workflow फिर से चलाएं + +```bash +nextflow run hello-modules.nf -resume +``` + +--- + +## 4. `collectGreetings()` process को modularize करें + +### 4.1. New module के लिए file stub बनाएं + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. `collectGreetings` process code को module file में move करें + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Uppercase अभिवादनों को एक single output फ़ाइल में collect करें + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +### 4.3. `params` block से पहले import declaration add करें + +```groovy title="hello-modules.nf" linenums="3" hl_lines="4" +// Modules को include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +### 4.4. Workflow चलाएं + +```bash +nextflow run hello-modules.nf -resume +``` + +### सीख + +तुम जानते हो कि workflow में multiple processes को modularize कैसे करें। + +बधाई हो, तुमने यह सारा काम किया और pipeline कैसे काम करती है उसमें absolutely कुछ भी नहीं बदला! + +Jokes aside, अब तुम्हारा code अधिक modular है, और यदि तुम एक और pipeline लिखने का decide करते हो जो उन processes में से किसी को call करती है, तुम्हें relevant module use करने के लिए बस एक short import statement type करना होगा। + +### आगे क्या? + +जब तुम ready हो, तो [**Part 5: Hello Containers**](./05_hello_containers.md) पर move करो यह सीखने के लिए कि software dependencies को अधिक conveniently और reproducibly manage करने के लिए containers कैसे use करें। + +--- + +## Quiz + +<quiz> +Nextflow में module क्या है? +- [ ] एक configuration file +- [x] Single process definition वाली एक standalone file +- [ ] एक workflow definition +- [ ] एक channel operator + +और जानें: [2. Create a module for `sayHello()`](#2-create-a-module-for-sayhello) +</quiz> + +<quiz> +Module files के लिए recommended naming convention क्या है? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Module files कहाँ store होनी चाहिए? +- [ ] Workflow के same directory में +- [ ] `bin/` directory में +- [x] `modules/` directory में +- [ ] `lib/` directory में + +और जानें: [1. Create a directory to store modules](#1-create-a-directory-to-store-modules) +</quiz> + +<quiz> +Module import करने के लिए correct syntax क्या है? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +और जानें: [2.3. Add an import declaration](#23-add-an-import-declaration-before-the-workflow-block) +</quiz> + +<quiz> +Modules use करने पर `-resume` functionality का क्या होता है? +- [ ] यह अब काम नहीं करती +- [ ] इसे additional configuration की need होती है +- [x] यह पहले जैसी ही काम करती है +- [ ] यह केवल local modules के लिए काम करती है +</quiz> + +<quiz> +Modules use करने के benefits क्या हैं? (सभी लागू select करें) +- [x] Workflows में code reusability +- [x] आसान maintenance +- [x] Workflow code का बेहतर organization +- [ ] तेज़ execution speed +</quiz> diff --git a/docs/hi/docs/hello_nextflow/05_hello_containers.md b/docs/hi/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..c7bf188efc --- /dev/null +++ b/docs/hi/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,275 @@ +# भाग 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/05_hello_containers.md) उपलब्ध है। +/// + +इस training course के Parts 1-4 में, तुमने सीखा कि कुछ text process करने, multiple inputs होने पर execution parallelize करने, और further processing के लिए results collect करने में सक्षम simple workflow assemble करने के लिए Nextflow के basic building blocks कैसे use करें। + +हालाँकि, तुम अपने environment में available basic UNIX tools तक limited थे। +Real-world tasks को अक्सर विभिन्न tools और packages की need होती है जो default रूप से included नहीं हैं। +Typically, तुम्हें इन tools को install करना होगा, उनकी dependencies manage करनी होंगी, और किसी भी conflicts को resolve करना होगा। + +यह सब बहुत tedious और annoying है, इसलिए हम तुम्हें दिखाएंगे कि इस problem को बहुत अधिक conveniently solve करने के लिए **containers** कैसे use करें। + +एक **container** एक lightweight, standalone, executable unit of software है जो container **image** से बनाई जाती है जिसमें application run करने के लिए आवश्यक सब कुछ शामिल है जिसमें code, system libraries और settings शामिल हैं। +जैसा तुम imagine कर सकते हो, यह तुम्हारी pipelines को अधिक reproducible बनाने में बहुत helpful होगा। + +Note करो कि हम यह [Docker](https://www.docker.com/get-started/) का उपयोग करके teach करेंगे, लेकिन ध्यान रखो कि Nextflow [कई अन्य container technologies](https://www.nextflow.io/docs/latest/container.html#) को भी support करता है। + +??? info "इस section से कैसे शुरू करें" + + Course का यह section मानता है कि तुमने [Hello Nextflow](./index.md) course के Parts 1-4 complete कर लिए हैं और एक complete working pipeline है। + + यदि तुम इस point से course शुरू कर रहे हो, तो तुम्हें solutions से `modules` directory copy करनी होगी: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Warmup: `hello-containers.nf` चलाएं + +हम starting point के रूप में workflow script `hello-containers.nf` use करेंगे। + +यह sure करने के लिए कि सब कुछ काम कर रहा है, कोई भी changes करने से पहले script को एक बार run करो: + +```bash +nextflow run hello-containers.nf +``` + +यदि यह तुम्हारे लिए काम किया, तो तुम containers use करना सीखने के लिए ready हो। + +--- + +## 1. Container 'manually' use करें + +हम क्या करना चाहते हैं अपने workflow में एक step add करना जो execution के लिए container use करेगा। + +हालाँकि, हम पहले कुछ basic concepts और operations cover करेंगे ताकि Nextflow में use करने से पहले containers क्या हैं इसकी तुम्हारी understanding solidify हो। + +### 1.1. Container image pull करें + +Container use करने के लिए, तुम आमतौर पर container registry से container image download या _pull_ करते हो, और फिर container instance बनाने के लिए container image run करते हो। + +General syntax इस प्रकार है: + +```bash title="Syntax" +docker pull '<container>' +``` + +एक example के रूप में, चलो एक container image pull करते हैं जिसमें [cowpy](https://github.com/jeffbuttars/cowpy) है, `cowsay` नामक tool का python implementation जो arbitrary text inputs को fun तरीके से display करने के लिए ASCII art generate करता है। + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +### 1.2. One-off command के रूप में `cowpy` run करने के लिए container use करें + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +### 1.3. `cowpy` interactively run करने के लिए container use करें + +#### 1.3.1. Container spin up करें + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +#### 1.3.2. Desired tool command(s) run करें + +```bash +cowpy "Hello Containers" -c tux +``` + +#### 1.3.3. Container से exit करें + +```bash +exit +``` + +#### 1.3.4. Container में data mount करें + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +#### 1.3.5. Mounted data use करें + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +### सीख + +तुम जानते हो कि container pull करना और इसे one-off या interactively run करना। तुम यह भी जानते हो कि अपने data को अपने container के भीतर से accessible कैसे बनाना। + +### आगे क्या? + +सीखो कि Nextflow processes के execution के लिए containers कैसे use करें। + +--- + +## 2. Nextflow में containers use करें + +Nextflow में processes को containers के अंदर run करने के लिए built-in support है। + +### 2.1. `cowpy` module लिखें + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy के साथ ASCII art generate करें +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +### 2.2. Workflow में cowpy add करें + +#### 2.2.1. `hello-containers.nf` में `cowpy` process import करें + +```groovy title="hello-containers.nf" linenums="3" hl_lines="5" +// Modules को include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +#### 2.2.2. Workflow में `cowpy` process का call add करें + +```groovy title="hello-containers.nf" linenums="31" hl_lines="2" + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy के साथ अभिवादनों का ASCII art generate करें + cowpy(collectGreetings.out.outfile, params.character) +``` + +### 2.3. `cowpy` process run करने के लिए container use करें + +#### 2.3.1. `cowpy` के लिए container specify करें + +```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" +process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: +``` + +#### 2.3.2. `nextflow.config` file के माध्यम से Docker use enable करें + +```console title="nextflow.config" linenums="1" hl_lines="1" +docker.enabled = true +``` + +#### 2.3.3. Docker enabled के साथ workflow run करें + +```bash +nextflow run hello-containers.nf -resume +``` + +### सीख + +तुम जानते हो कि Nextflow में processes run करने के लिए containers कैसे use करें। + +### आगे क्या? + +Break लो! + +जब तुम ready हो, तो [**Part 6: Hello Config**](./06_hello_config.md) पर move करो यह सीखने के लिए कि अपने infrastructure fit करने के लिए अपने pipeline के execution को configure कैसे करें साथ ही inputs और parameters के configuration को manage करें। + +यह बिल्कुल last part है, और फिर तुम इस course से done हो जाओगे! + +--- + +## Quiz + +<quiz> +Container क्या है? +- [ ] एक type की virtual machine +- [ ] एक file compression format +- [x] एक lightweight, standalone executable unit जिसमें application run करने के लिए आवश्यक सब कुछ शामिल है +- [ ] एक network protocol +</quiz> + +<quiz> +Container image और container instance में क्या difference है? +- [ ] वे same thing हैं +- [x] एक image एक template है; एक instance उस image से बनाया गया running container है +- [ ] एक instance एक template है; एक image एक running container है +- [ ] Images Docker के लिए हैं; instances Singularity के लिए हैं +</quiz> + +<quiz> +`docker run` command में `-v` flag क्या करता है? +- [ ] Verbose output enable करता है +- [ ] Container validate करता है +- [x] Host system से container में volume mount करता है +- [ ] Container का version specify करता है + +और जानें: [1.3.4. Mount data into the container](#134-mount-data-into-the-container) +</quiz> + +<quiz> +Containers use करते समय volumes mount करने की need क्यों होती है? +- [ ] Container performance improve करने के लिए +- [ ] Disk space save करने के लिए +- [x] क्योंकि containers default रूप से host filesystem से isolated हैं +- [ ] Networking enable करने के लिए + +और जानें: [1.3.4. Mount data into the container](#134-mount-data-into-the-container) +</quiz> + +<quiz> +Nextflow process के लिए container कैसे specify करते हो? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +और जानें: [2.3.1. Specify a container for cowpy](#231-specify-a-container-for-cowpy) +</quiz> + +<quiz> +कौन सी `nextflow.config` setting तुम्हारे workflow के लिए Docker enable करती है? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +और जानें: [2.3.2. Enable use of Docker via the `nextflow.config` file](#232-enable-use-of-docker-via-the-nextflowconfig-file) +</quiz> + +<quiz> +Container में process run करते समय Nextflow automatically क्या handle करता है? (सभी लागू select करें) +- [x] यदि needed हो तो container image pull करना +- [x] Work directory mount करना +- [x] Container के अंदर process script run करना +- [x] Execution के बाद container instance clean up करना + +और जानें: [2.3.4. Inspect how Nextflow launched the containerized task](#234-inspect-how-nextflow-launched-the-containerized-task) +</quiz> diff --git a/docs/hi/docs/hello_nextflow/06_hello_config.md b/docs/hi/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..0fcdc73321 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1072 @@ +# भाग 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube channel पर [पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: वीडियो transcript [यहाँ](./transcripts/06_hello_config.md) उपलब्ध है। +/// + +यह section explore करेगा कि अपनी Nextflow pipeline का configuration कैसे set up और manage करें ताकि तुम इसके behavior को customize कर सको, इसे different environments में adapt कर सको, और resource usage optimize कर सको _बिना workflow code की single line को alter किए_। + +ऐसा करने के multiple ways हैं, जो combination में use किए जा सकते हैं और [यहाँ](https://www.nextflow.io/docs/latest/config.html) described order of precedence के अनुसार interpret किए जाते हैं। + +इस course के part में, हम तुम्हें सबसे simple और common configuration file mechanism, `nextflow.config` file दिखाएंगे, जो तुमने Part 5: Hello Containers में पहले ही encounter किया था। + +हम Nextflow configuration के essential components जैसे process directives, executors, profiles, और parameter files को cover करेंगे। +इन configuration options को effectively utilize करना सीखकर, तुम अपनी pipelines की flexibility, scalability, और performance enhance कर सकते हो। + +??? info "इस section से कैसे शुरू करें" + + Course का यह section मानता है कि तुमने [Hello Nextflow](./index.md) course के Parts 1-5 complete कर लिए हैं और एक complete working pipeline है। + + यदि तुम इस point से course शुरू कर रहे हो, तो तुम्हें solutions से `modules` directory और `nextflow.config` file copy करनी होगी: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + `nextflow.config` file में line `docker.enabled = true` है जो Docker containers का use enable करती है। + + यदि तुम Hello pipeline से familiar नहीं हो या तुम्हें reminder चाहिए, तो [यह info page](../info/hello_pipeline.md) देखो। + +--- + +## 0. Warmup: `hello-config.nf` चलाएं + +हम starting point के रूप में workflow script `hello-config.nf` use करेंगे। +यह इस training course के Part 5 में produce की गई script के equivalent है, except हमने output destinations change कर दिए हैं: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +यह sure करने के लिए कि सब कुछ काम कर रहा है, कोई भी changes करने से पहले script को एक बार run करो: + +```bash +nextflow run hello-config.nf +``` + +यदि यह तुम्हारे लिए काम किया, तो तुम अपनी pipelines configure करना सीखने के लिए ready हो। + +--- + +## 1. Workflow input parameters manage करें + +हम configuration के एक aspect से शुरू करेंगे जो हम अब तक काम कर रहे थे उसका simply extension है: input parameters का management। + +Currently, हमारा workflow command-line के through कई parameter values accept करने के लिए set up है, जिनकी default values workflow script में `params` block में set हैं। +हालाँकि, तुम उन defaults को override करना चाहते हो बिना parameters को command line पर specify करने या original script file modify करने के। + +ऐसा करने के multiple ways हैं; हम तुम्हें तीन basic ways दिखाएंगे जो बहुत commonly use होते हैं। + +### 1.1. Default values को `nextflow.config` में move करें + +यह सबसे simple approach है, हालाँकि यह possibly सबसे least flexible है क्योंकि main `nextflow.config` file कुछ ऐसा नहीं है जिसे तुम हर run के लिए edit करना चाहोगे। +लेकिन इसका advantage है कि यह parameters _declare_ करने (जो definitely workflow में belong करता है) versus _default values_ supply करने की concerns को separate करता है, जो configuration file में अधिक at home हैं। + +#### 1.1.1. Configuration file में `params` block create करें + +`nextflow.config` file में following code changes करो: + +=== "After" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline पैरामीटर + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Before" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Note करो कि हमने simply workflow से configuration file में `params` block copy नहीं किया। +Syntax थोड़ा different है। +Workflow file में, वे typed declarations हैं। +Configuration में, वे value assignments हैं। + +#### 1.1.2. Workflow file में `params` block से values remove करें + +`hello-config.nf` workflow file में following code changes करो: + +=== "After" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline पैरामीटर + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Before" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline पैरामीटर + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +अब workflow file itself इन parameters के लिए कोई default values set नहीं करती। + +#### 1.1.3. Pipeline run करें + +```bash +nextflow run hello-config.nf +``` + +यह अभी भी पहले जैसा same output produce करता है। + +### 1.2. Run-specific configuration file use करें + +यह great है, लेकिन sometimes तुम main configuration file के साथ mess किए बिना different default values के साथ कुछ temporary experiments run करना चाहते हो। +तुम ऐसा एक subdirectory में new `nextflow.config` file create करके कर सकते हो जिसे तुम अपने experiments के लिए working directory के रूप में use करोगे। + +#### 1.2.1. Blank configuration के साथ working directory create करें + +एक new directory create करके उसमें move करो: + +```bash +mkdir -p tux-run +cd tux-run +``` + +फिर, उस directory में blank configuration file create करो: + +```bash +touch nextflow.config +``` + +#### 1.2.2. Experimental configuration set up करें + +अब new file open करो और जो parameters customize करना चाहते हो वो add करो: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Note करो कि input file का path directory structure reflect करना चाहिए। + +#### 1.2.3. Pipeline run करें + +```bash +nextflow run ../hello-config.nf +``` + +इस run में, Nextflow हमारी current directory में `nextflow.config` को pipeline की root directory में `nextflow.config` के साथ combine करता है, और thereby default character (turkey) को tux character के साथ override करता है। + +!!! warning "चेतावनी" + + Next section पर move करने से पहले previous directory में वापस change करना sure करो! + + ```bash + cd .. + ``` + +### 1.3. Parameter file use करें + +Subdirectory approach experimenting के लिए great काम करता है, लेकिन इसमें थोड़ी setup involve होती है और require होता है कि तुम paths accordingly adapt करो। +एक simpler approach है जब तुम अपनी pipeline को specific set of values के साथ run करना चाहते हो, या किसी और को minimal effort के साथ ऐसा करने enable करना चाहते हो। + +Nextflow हमें YAML या JSON format में parameter file के through parameters specify करने allow करता है। + +#### 1.3.1. Example parameter file examine करें + +इसे demonstrate करने के लिए, हम current directory में एक example parameter file provide करते हैं, जिसका नाम `test-params.yaml` है: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Note करो कि यदि तुम syntax को configuration file से compare करो तो equal signs (`=`) के बजाय colons (`:`) का use है। +Config file Groovy में लिखी है, जबकि parameter file YAML में लिखी है। + +#### 1.3.2. Pipeline run करें + +इस parameter file के साथ workflow run करने के लिए, simply base command में `-params-file <filename>` add करो। + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +Parameter file use करना overkill लग सकता है जब तुम्हारे पास specify करने के लिए only कुछ parameters हों, लेकिन कुछ pipelines दर्जनों parameters expect करती हैं। +उन cases में, parameter file use करना हमें massive command lines type किए बिना और workflow script modify किए बिना runtime पर parameter values provide करने allow करेगा। + +### सीख + +तुम जानते हो कि workflow inputs manage करने के लिए key configuration options का advantage कैसे लें। + +### आगे क्या? + +सीखो कि where और how तुम्हारे workflow outputs publish होते हैं यह कैसे manage करें। + +--- + +## 2. Workflow outputs manage करें + +अब तक हम workflow-level output declarations के लिए सभी paths hardcode कर रहे थे, और जैसा हमने note किया जब हमने multiple outputs add करना शुरू किया, इसमें थोड़ी repetition involve हो सकती है। + +कुछ common ways देखते हैं जिनसे तुम इसे अधिक flexible बनाने के लिए configure कर सकते हो। + +### 2.1. `outputDir` directory name customize करें + +इस course के हर chapter के लिए, हम outputs को एक different hardcoded subdirectory में publish कर रहे थे। + +इसे user-configurable parameter use करने के लिए change करते हैं। +हम इसके लिए एक whole new parameter create कर सकते हैं, लेकिन `batch` parameter use करते हैं क्योंकि वह right there है। + +#### 2.1.1. Configuration file में `outputDir` के लिए value set करें + +Nextflow जो path outputs publish करने के लिए use करता है वह `outputDir` option द्वारा controlled है। + +`nextflow.config` file में following code add करो: + +=== "After" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline पैरामीटर + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output सेटिंग्स + */ + outputDir = "results/${params.batch}" + ``` + +=== "Before" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline पैरामीटर + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +यह built-in default path, `results/`, को `results/` plus `batch` parameter की value as subdirectory के साथ replace करेगा। + +#### 2.1.2. Hardcoded path का repeated part remove करें + +हमारे पास अभी भी output options में hardcoded subdirectory है, तो इसे अब remove करते हैं। + +Workflow file में following code changes करो: + +=== "After" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Before" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +#### 2.1.3. Pipeline run करें + +```bash +nextflow run hello-config.nf --batch outdir +``` + +यह अभी भी पहले जैसा same output produce करता है, except इस बार हम अपने outputs `results/outdir/` के under पाते हैं। + +### 2.2. Process के अनुसार outputs organize करें + +Outputs को further organize करने का एक popular way है इसे process के अनुसार करना, _i.e._ pipeline में run होने वाले प्रत्येक process के लिए subdirectories create करना। + +#### 2.2.1. Output paths को process names के reference से replace करें + +तुम्हें बस output path declaration में process का name `<task>.name` के रूप में reference करना है। + +Workflow file में following changes करो: + +=== "After" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Before" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +#### 2.2.2. Pipeline run करें + +```bash +nextflow run hello-config.nf --batch pnames +``` + +इस बार हम अपने outputs `results/pnames/` के under पाते हैं, और वे process के अनुसार grouped हैं। + +### 2.3. Workflow level पर publish mode set करें + +Finally, repetitive code की amount reduce करने की spirit में, हम per-output `mode` declarations को configuration में single line से replace कर सकते हैं। + +#### 2.3.1. Configuration file में `workflow.output.mode` add करें + +`nextflow.config` file में following code add करो: + +=== "After" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output सेटिंग्स + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Before" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output सेटिंग्स + */ + outputDir = "results/${params.batch}" + ``` + +#### 2.3.2. Workflow file से output mode remove करें + +Workflow file में following changes करो: + +=== "After" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Before" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +यह अधिक concise है। + +#### 2.3.3. Pipeline run करें + +```bash +nextflow run hello-config.nf --batch outmode +``` + +यह अभी भी पहले जैसा same output produce करता है, except इस बार हम अपने outputs `results/outmode/` के under पाते हैं। +वे सभी अभी भी proper copies हैं, symlinks नहीं। + +### सीख + +तुम जानते हो कि directories का naming और structure जहाँ तुम्हारे outputs publish होते हैं, साथ ही workflow output publishing mode कैसे control करें। + +### आगे क्या? + +सीखो कि अपने workflow configuration को अपने compute environment में कैसे adapt करें, software packaging technology से शुरू करके। + +--- + +## 3. Software packaging technology select करें + +अब तक हम configuration elements देख रहे थे जो control करते हैं कि inputs कैसे जाते हैं और outputs कहाँ से आते हैं। +अब specifically अपने workflow configuration को अपने compute environment में adapt करने पर focus करने का time है। + +उस path पर पहला step है यह specify करना कि software packages जो प्रत्येक step में run होंगे वे कहाँ से आएंगे। +क्या वे पहले से local compute environment में installed हैं? +क्या हमें images retrieve करनी और उन्हें container system के through run करना है? +या हमें Conda packages retrieve करने और local Conda environment build करना है? + +इस training course के बहुत पहले part में (Parts 1-4) हमने अपने workflow में बस locally installed software use किया। +फिर Part 5 में, हमने Docker containers और `nextflow.config` file introduce की, जिसे हमने Docker containers का use enable करने के लिए use किया। + +अब देखते हैं कि हम `nextflow.config` file के through एक alternative software packaging option कैसे configure कर सकते हैं। + +### 3.1. Config file में Docker disable और Conda enable करें + +मान लो हम एक HPC cluster पर काम कर रहे हैं और admin security reasons के लिए Docker का use allow नहीं करता। +Fortunately हमारे लिए, Nextflow कई अन्य container technologies support करता है जिसमें Singularity (जो HPC पर अधिक widely use होती है) शामिल है, और software package managers जैसे Conda। + +हम अपनी configuration file को Docker के बजाय Conda use करने के लिए change कर सकते हैं। + +=== "After" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Before" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +यह Nextflow को उन processes के लिए Conda environments create और utilize करने allow करेगा जिनके पास Conda packages specified हैं। + +### 3.2. Process definition में Conda package specify करें + +हम पहले से ही `cowpy` tool contain करने वाले Conda package के लिए URI retrieve कर चुके हैं: `conda-forge::cowpy==1.1.5` + +अब हम `conda` directive का use करके URI को `cowpy` process definition में add करते हैं: + +=== "After" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Before" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Clear करने के लिए, हम `docker` directive _replace_ नहीं कर रहे, हम एक alternative option _add_ कर रहे हैं। + +### 3.3. Workflow run करें verify करने के लिए कि यह Conda use कर सकता है + +```bash +nextflow run hello-config.nf --batch conda +``` + +यह बिना issue के काम करना चाहिए और पहले जैसे same outputs `results/conda` के under produce करना चाहिए। + +Behind the scenes, Nextflow ने Conda packages retrieve किए और environment create किया। + +??? info "Docker और Conda mix और match करना" + + चूंकि ये directives per process assign किए जाते हैं, 'mix और match' करना possible है, _i.e._ अपने workflow में कुछ processes को Docker के साथ और अन्य को Conda के साथ run करने के लिए configure करना, example के लिए, यदि तुम जो compute infrastructure use कर रहे हो वह दोनों support करता है। + उस case में, तुम अपनी configuration file में Docker और Conda दोनों enable करोगे। + यदि किसी given process के लिए दोनों available हैं, Nextflow containers को prioritize करेगा। + +### सीख + +तुम जानते हो कि प्रत्येक process को कौन सा software package use करना चाहिए यह कैसे configure करें, और technologies के बीच switch कैसे करें। + +### आगे क्या? + +सीखो कि Nextflow द्वारा actually work करने के लिए use किए जाने वाले execution platform को कैसे change करें। + +--- + +## 4. Execution platform select करें + +अब तक, हम अपनी pipeline को local executor के साथ run कर रहे थे। +यह प्रत्येक task को उस machine पर execute करता है जिस पर Nextflow run हो रहा है। + +Local executor convenient और efficient है, लेकिन यह उस single machine तक limited है। +बहुत large workloads के लिए, तुम discover कर सकते हो कि तुम्हारी local machine bottleneck है। + +Nextflow [कई different execution backends](https://www.nextflow.io/docs/latest/executor.html) support करता है, जिसमें HPC schedulers (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor और अन्य) साथ ही cloud execution backends जैसे (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes और अधिक) शामिल हैं। + +### 4.1. Different backend target करना + +Executor की choice एक process directive द्वारा set होती है जिसे `executor` कहते हैं। +By default यह `local` पर set है, तो following configuration implied है: + +```groovy title="Built-in configuration" +process { + executor = 'local' +} +``` + +Different backend target करने के लिए executor set करने के लिए, तुम simply वह executor specify करोगे जो तुम चाहते हो। + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "चेतावनी" + + हम actually training environment में इसे test नहीं कर सकते क्योंकि यह HPC से connect करने के लिए set up नहीं है। + +### 4.2. Execution parameters के लिए backend-specific syntax deal करना + +Most high-performance computing platforms allow (और sometimes require) करते हैं कि तुम certain parameters specify करो जैसे resource allocation requests और limitations (e.g. number of CPUs और memory) और use करने के लिए job queue का name। + +Unfortunately, इनमें से प्रत्येक system different technologies, syntaxes और configurations use करता है यह define करने के लिए कि job कैसे define और relevant scheduler को submit किया जाना चाहिए। + +Fortunately, Nextflow यह सब simplify करता है। +यह एक standardized syntax provide करता है ताकि तुम relevant properties जैसे `cpus`, `memory` और `queue` सिर्फ एक बार specify कर सको। +फिर, runtime पर, Nextflow उन settings को executor setting के based पर appropriate backend-specific scripts generate करने के लिए use करेगा। + +### सीख + +अब तुम जानते हो कि different kinds of computing infrastructure use करने के लिए executor कैसे change करें। + +### आगे क्या? + +सीखो कि Nextflow में resource allocations और limitations कैसे evaluate और express करें। + +--- + +## 5. Compute resource allocations control करें + +Most high-performance computing platforms allow (और sometimes require) करते हैं कि तुम certain resource allocation parameters specify करो जैसे number of CPUs और memory। + +By default, Nextflow प्रत्येक process के लिए single CPU और 2GB memory use करेगा। +Corresponding process directives को `cpus` और `memory` कहा जाता है, तो following configuration implied है: + +```groovy title="Built-in configuration" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +तुम इन values को modify कर सकते हो, either सभी processes के लिए या specific named processes के लिए, अपनी configuration file में additional process directives use करके। + +लेकिन तुम कैसे जानते हो कि कौन सी values use करनी हैं? + +### 5.1. Resource utilization report generate करने के लिए workflow run करें + +यदि तुम up front नहीं जानते कि तुम्हारे processes को कितनी CPU और memory की likely need होगी, तुम कुछ resource profiling कर सकते हो। + +Conveniently, Nextflow में इसके लिए built-in tools included हैं, और request पर तुम्हारे लिए report happily generate करेगा। + +ऐसा करने के लिए, अपनी command line में `-with-report <filename>.html` add करो। + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Report एक html file है, जिसे तुम download करके अपने browser में open कर सकते हो। + +Report को देखने के लिए कुछ minutes लो और identify करो कि resources adjust करने के लिए कुछ opportunities हैं या नहीं। + +### 5.2. सभी processes के लिए resource allocations set करें + +Profiling show करती है कि हमारी training workflow में processes बहुत lightweight हैं, तो default memory allocation को 1GB per process तक reduce करते हैं। + +अपनी `nextflow.config` file में following add करो: + +```groovy title="nextflow.config" linenums="4" +/* +* Process सेटिंग्स +*/ +process { + memory = 1.GB +} +``` + +### 5.3. Specific process के लिए resource allocations set करें + +साथ ही, हम pretend करेंगे कि `cowpy` process को दूसरों से अधिक resources require होती हैं, बस demonstrate करने के लिए कि individual process के लिए allocations कैसे adjust करें। + +=== "After" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Before" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +इस configuration के साथ, सभी processes 1GB memory और single CPU (implied default) request करेंगे, except `cowpy` process, जो 2GB और 2 CPUs request करेगा। + +### 5.4. Updated configuration के साथ workflow run करें + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +तुम probably कोई real difference notice नहीं करोगे चूंकि यह इतना small workload है, लेकिन यह approach है जो तुम real-world workflow की performance और resource requirements analyze करने के लिए use करोगे। + +### 5.5. Resource limits add करें + +Depending on तुम कौन सा computing executor और compute infrastructure use कर रहे हो, कुछ constraints हो सकते हैं कि तुम क्या allocate कर सकते हो (या must)। + +तुम `resourceLimits` directive use कर सकते हो relevant limitations set करने के लिए: + +```groovy title="Syntax example" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow इन values को उस executor के depending appropriate instructions में translate करेगा जो तुमने specify किया। + +### सीख + +तुम जानते हो कि resource utilization assess करने के लिए profiling report कैसे generate करें और सभी processes के लिए और/या individual processes के लिए resource allocations कैसे modify करें, साथ ही HPC पर running के लिए resource limitations set करें। + +### आगे क्या? + +सीखो कि preset configuration profiles कैसे set up करें और runtime पर उनके बीच switch करें। + +--- + +## 6. Preset configurations के बीच switch करने के लिए profiles use करें + +हमने तुम्हें कई ways दिखाए हैं जिनसे तुम अपनी pipeline configuration customize कर सकते हो depending on तुम किस project पर काम कर रहे हो या तुम कौन सा compute environment use कर रहे हो। + +तुम alternative settings के बीच switch करना चाहते हो depending on तुम कौन सी computing infrastructure use कर रहे हो। +Example के लिए, तुम अपने laptop पर locally develop और small-scale tests run करना चाहते हो, फिर HPC या cloud पर full-scale workloads run करना चाहते हो। + +Nextflow तुम्हें कितनी भी profiles set up करने देता है जो different configurations describe करती हैं, जिन्हें तुम फिर runtime पर command-line argument use करके select कर सकते हो, बजाय configuration file itself modify करने के। + +### 6.1. Local development और HPC पर execution के बीच switch करने के लिए profiles create करें + +दो alternative profiles set up करते हैं; एक regular computer पर small scale loads run करने के लिए, जहाँ हम Docker containers use करेंगे, और एक Slurm scheduler के साथ university HPC पर running के लिए, जहाँ हम Conda packages use करेंगे। + +#### 6.1.1. Profiles set up करें + +अपनी `nextflow.config` file में following add करो: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +तुम देखते हो कि university HPC के लिए, हम resource limitations भी specify कर रहे हैं। + +#### 6.1.2. Profile के साथ workflow run करें + +अपनी Nextflow command line में profile specify करने के लिए, हम `-profile` argument use करते हैं। + +`my_laptop` configuration के साथ workflow run करने की try करते हैं। + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +जैसा तुम देख सकते हो, यह हमें runtime पर configurations के बीच बहुत conveniently toggle करने allow करता है। + +!!! warning "चेतावनी" + + `univ_hpc` profile training environment में properly run नहीं होगी चूंकि हमारे पास Slurm scheduler तक access नहीं है। + +### 6.2. Test parameters की profile create करें + +Profiles सिर्फ infrastructure configuration के लिए नहीं हैं। +हम उन्हें workflow parameters के लिए default values set करने के लिए भी use कर सकते हैं, ताकि दूसरों के लिए workflow को try out करना easier हो बिना appropriate input values खुद gather किए। + +#### 6.2.1. Profile set up करें + +यदि हम अपने workflow के लिए test profile add करें, तो `profiles` block बन जाता है: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +#### 6.2.2. Test profile के साथ workflow locally run करें + +Conveniently, profiles mutually exclusive नहीं हैं, तो हम following syntax `-profile <profile1>,<profile2>` use करके अपनी command line में multiple profiles specify कर सकते हैं। + +अपने previous command में test profile add करने की try करते हैं: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +यह Docker use करेगा जहाँ possible हो और `results/test` के under outputs produce करेगा, और इस बार character comedic duo `dragonandcow` है। + +### 6.3. Resolved configuration देखने के लिए `nextflow config` use करें + +जैसा ऊपर noted है, sometimes same parameter profiles में different values पर set हो सकता है जिन्हें तुम combine करना चाहते हो। +और more generally, कई places हैं जहाँ configuration के elements stored हो सकते हैं, और sometimes same properties different places में different values पर set हो सकती हैं। + +Nextflow किसी भी conflicts को resolve करने के लिए set [order of precedence](https://www.nextflow.io/docs/latest/config.html) apply करता है। + +Fortunately, Nextflow में एक convenient utility tool included है जिसे `config` कहते हैं जो तुम्हारे लिए वह whole process automate कर सकता है। + +#### 6.3.1. Default configuration resolve करें + +यह command run करो default द्वारा apply होने वाली configuration resolve करने के लिए। + +```bash +nextflow config +``` + +यह तुम्हें base configuration show करता है जो तुम्हें मिलती है यदि तुम command line में कुछ extra specify नहीं करते। + +#### 6.3.2. Specific settings activated के साथ configuration resolve करें + +यदि तुम command-line parameters provide करते हो, e.g. एक या अधिक profiles enable करना या parameter file load करना, command additionally उन्हें account में लेगा। + +```bash +nextflow config -profile my_laptop,test +``` + +यह complex projects के लिए especially useful हो जाता है जिनमें configuration की multiple layers involve होती हैं। + +### सीख + +तुम जानते हो कि minimal hassle के साथ runtime पर preset configuration select करने के लिए profiles कैसे use करें। +More generally, तुम जानते हो कि अपने workflow executions को different compute platforms suit करने के लिए कैसे configure करें और अपनी analyses की reproducibility enhance करें। + +### आगे क्या? + +Celebrate करो और खुद को एक big pat on the back दो! तुमने अपना बहुत पहला Nextflow developer course complete कर लिया है। + +Final [course summary](./next_steps.md) पर जाओ review करने के लिए कि तुमने क्या सीखा और पता लगाओ कि आगे क्या आता है। + +--- + +## Quiz + +<quiz> +उस configuration file का क्या नाम है जो Nextflow automatically load करता है? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +जब same parameter config file और command line दोनों में set हो तो क्या precedence लेता है? +- [ ] Config file value +- [x] Command line value +- [ ] पहली encountered value +- [ ] Neither; यह error cause करता है + +और जानें: [1.1. Default values को `nextflow.config` में move करें](#11-default-values-को-nextflowconfig-में-move-करें) +</quiz> + +<quiz> +क्या same configuration में Docker और Conda दोनों enabled हो सकते हैं? +- [x] हाँ, Nextflow process directives के depending दोनों use कर सकता है +- [ ] नहीं, एक time पर सिर्फ एक enabled हो सकता है +- [ ] हाँ, लेकिन सिर्फ profiles में +- [ ] नहीं, वे mutually exclusive हैं +</quiz> + +<quiz> +यदि Docker और Conda दोनों enabled हैं और process के पास दोनों directives हैं, तो कौन prioritized होता है? +- [x] Docker (containers) +- [ ] Conda +- [ ] पहला defined +- [ ] यह error cause करता है + +और जानें: [3. Software packaging technology select करें](#3-software-packaging-technology-select-करें) +</quiz> + +<quiz> +Nextflow processes के लिए default memory allocation क्या है? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] No limit +</quiz> + +<quiz> +Config file में specific process के लिए resource requirements कैसे set करते हो? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +और जानें: [5.3. Specific process के लिए resource allocations set करें](#53-specific-process-के-लिए-resource-allocations-set-करें) +</quiz> + +<quiz> +कौन सा command line option resource utilization report generate करता है? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +और जानें: [5.1. Resource utilization report generate करने के लिए workflow run करें](#51-resource-utilization-report-generate-करने-के-लिए-workflow-run-करें) +</quiz> + +<quiz> +`resourceLimits` directive क्या करता है? +- [ ] Minimum resource requirements set करता है +- [ ] Processes को resources allocate करता है +- [x] Maximum resources को cap करता है जो request किए जा सकते हैं +- [ ] Resource usage monitor करता है + +और जानें: [5.5. Resource limits add करें](#55-resource-limits-add-करें) +</quiz> + +<quiz> +Nextflow में default executor क्या है? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +और जानें: [4. Execution platform select करें](#4-execution-platform-select-करें) +</quiz> + +<quiz> +Nextflow run करते समय parameter file कैसे specify करते हो? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +और जानें: [1.3. Parameter file use करें](#13-parameter-file-use-करें) +</quiz> + +<quiz> +Profiles किसके लिए use की जा सकती हैं? (सभी लागू select करें) +- [x] Infrastructure-specific settings define करने के लिए +- [x] Different environments के लिए resource limits set करने के लिए +- [x] Test parameters provide करने के लिए +- [ ] New processes define करने के लिए + +और जानें: [6. Preset configurations के बीच switch करने के लिए profiles use करें](#6-preset-configurations-के-बीच-switch-करने-के-लिए-profiles-use-करें) +</quiz> + +<quiz> +Single command में multiple profiles कैसे specify करते हो? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +और जानें: [6. Preset configurations के बीच switch करने के लिए profiles use करें](#6-preset-configurations-के-बीच-switch-करने-के-लिए-profiles-use-करें) +</quiz> diff --git a/docs/hi/docs/hello_nextflow/index.md b/docs/hi/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..0cfa732a23 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow workflows को लॉन्च और मैनेज करना + - Nextflow द्वारा जनरेट किए गए आउटपुट (परिणाम) और लॉग फ़ाइलों को खोजना और समझना + - बुनियादी समस्याओं का समाधान करना + - मुख्य Nextflow कंपोनेंट्स से एक सरल मल्टी-स्टेप workflow बनाना + - आवश्यक प्रकार के channel factories और operators को पहचानना और उन्हें एक सरल workflow में प्रभावी ढंग से उपयोग करना + - HPC और cloud सहित सामान्य कंप्यूटिंग प्लेटफॉर्म पर चलाने के लिए pipeline execution को कॉन्फ़िगर करना + - Reproducibility, portability और code re-use के लिए best practices लागू करना जो pipelines को FAIR बनाते हैं, जिसमें code modularity और software containers शामिल हैं + audience_prerequisites: + - "**दर्शक:** यह कोर्स उन learners के लिए डिज़ाइन किया गया है जो Nextflow में बिल्कुल नए हैं और अपने खुद के pipelines विकसित करना चाहते हैं।" + - "**कौशल:** command line, बुनियादी scripting concepts और सामान्य file formats से कुछ परिचितता मानी गई है।" + - "**डोमेन:** सभी exercises डोमेन-अज्ञेयवादी हैं, इसलिए कोई पूर्व वैज्ञानिक ज्ञान आवश्यक नहीं है।" + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow reproducible और scalable data analysis workflows बनाने का एक hands-on परिचय है।** + +व्यावहारिक उदाहरणों और guided exercises के माध्यम से काम करते हुए, तुम Nextflow के साथ pipelines विकसित करने की मूल बातें सीखोगे, जिसमें processes को परिभाषित करना, उन्हें pipelines में जोड़ना, files और software dependencies को मैनेज करना, execution को आसानी से parallelize करना, और विभिन्न computing environments में workflows चलाना शामिल है। + +तुम Nextflow के साथ अपने खुद के workflows विकसित करने और चलाने के कौशल और आत्मविश्वास लेकर जाओगे। + +<!-- additional_information --> + +## कोर्स अवलोकन + +यह कोर्स hands-on होने के लिए डिज़ाइन किया गया है, जिसमें goal-oriented exercises को धीरे-धीरे जानकारी पेश करने के लिए संरचित किया गया है। + +तुम एक सरल Nextflow pipeline विकसित करोगे जो कुछ text inputs लेता है, कुछ transformation steps चलाता है, और एक single text file आउटपुट करता है जिसमें एक character का ASCII picture है जो transformed text बोल रहा है। + +### पाठ योजना + +तुम्हें concepts और code से अभिभूत होने से बचाने के लिए, हमने इसे छह भागों में विभाजित किया है जो प्रत्येक Nextflow के साथ pipelines विकसित करने के विशिष्ट पहलुओं पर ध्यान केंद्रित करेंगे। + +| कोर्स अध्याय | सारांश | अनुमानित अवधि | +| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------- | +| [भाग 1: Hello World](./01_hello_world.md) | Nextflow workflow को assemble और run करने में शामिल बुनियादी components और principles | 30 मिनट | +| [भाग 2: Hello Channels](./02_hello_channels.md) | Inputs को process करने और execution को आसानी से parallelize करने के लिए channels और operators का उपयोग | 45 मिनट | +| [भाग 3: Hello Workflow](./03_hello_workflow.md) | Multiple steps को एक साथ chain करने और steps के बीच data transfer को handle करने के लिए channels का उपयोग | 60 मिनट | +| [भाग 4: Hello Modules](./04_hello_modules.md) | Reusability बढ़ाने और maintenance burden कम करने के लिए code modularity principles लागू करना | 20 मिनट | +| [भाग 5: Hello Containers](./05_hello_containers.md) | Software dependencies को मैनेज करने और reproducibility बढ़ाने के लिए containers का उपयोग करना | 60 मिनट | +| [भाग 6: Hello Config](./06_hello_config.md) | Pipeline behavior को customize करना और विभिन्न computational environments में usage को optimize करना | 60 मिनट | + +इस कोर्स के अंत तक, तुम अपनी scientific computing आवश्यकताओं के लिए reproducible workflows विकसित करने की अपनी यात्रा में अगले कदमों से निपटने के लिए अच्छी तरह से तैयार होगे। + +कोर्स लेने के लिए तैयार हो? + +[शुरू करें :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/hi/docs/hello_nextflow/next_steps.md b/docs/hi/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..ec38b078a7 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# कोर्स सारांश + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello Nextflow training course complete करने पर बधाई! + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } [Nextflow YouTube channel पर पूरी playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) देखें। + +:green_book: तुम video के साथ [video transcript](./transcripts/07_next_steps.md) पढ़ सकते हो। +/// + +## तुम्हारी यात्रा + +तुमने एक बहुत ही basic workflow से शुरू किया जो hardcoded command run करता था। +छह parts के दौरान, तुमने उस basic workflow को एक modular multi-step pipeline में transform किया जो Nextflow की key features exercise करता है जिसमें channels, operators, containers के लिए built-in support, और configuration options शामिल हैं। + +### तुमने क्या बनाया + +- Hello workflow का final form input के रूप में text greetings वाली CSV file लेता है। +- चार steps Nextflow processes (`sayHello`, `convertToUpper`, `collectGreetings`, और `cowpy`) के रूप में implement किए गए हैं जो separate module files में stored हैं। +- Results `results/` नामक directory में publish होते हैं। +- Pipeline का final output एक plain text file है जिसमें uppercased greetings बोलने वाले character की ASCII art है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** प्रत्येक greeting को उसकी अपनी output file में लिखता है (_जैसे_ "Hello-output.txt") +2. **`convertToUpper`:** प्रत्येक greeting को uppercase में convert करता है (_जैसे_ "HELLO") +3. **`collectGreetings`:** सभी uppercase greetings को एक single batch file में collect करता है +4. **`cowpy`:** `cowpy` tool का उपयोग करके ASCII art generate करता है + +Workflow configuration flexible, reproducible तरीके से inputs और parameters provide करने को support करता है। + +### प्राप्त कौशल + +इस hands-on course के माध्यम से, तुमने सीखा कि कैसे: + +- एक simple multi-step workflow बनाने के लिए पर्याप्त core Nextflow components describe और utilize करें +- Next-step concepts जैसे operators और channel factories describe करें +- Locally Nextflow workflow launch करें +- Nextflow द्वारा generate किए गए outputs (results) और log files खोजें और interpret करें +- Basic issues troubleshoot करें + +तुम अब Nextflow में अपने खुद के pipelines develop करना शुरू करने के foundational knowledge से equipped हो। + +## अपने skills बनाने के लिए next steps + +यहाँ आगे क्या करना है इसके लिए हमारे top 3 suggestions हैं: + +- [Nextflow for Science](../nf4_science/index.md) के साथ scientific analysis use case पर Nextflow apply करें +- [Hello nf-core](../../hello_nf-core/index.md) के साथ nf-core शुरू करें +- [Side Quests](../side_quests/index.md) के साथ more advanced Nextflow features explore करें + +Finally, हम recommend करते हैं कि तुम [**Seqera Platform**](https://seqera.io/) पर नज़र डालो, Nextflow के creators द्वारा develop किया गया एक cloud-based platform जो तुम्हारे workflows launch और manage करना, साथ ही तुम्हारा data manage करना और किसी भी environment में interactively analyses run करना और भी आसान बनाता है। + +## Feedback survey + +Move on करने से पहले, कृपया course survey complete करने के लिए एक minute लो! तुम्हारी feedback हमें सभी के लिए हमारी training materials improve करने में मदद करती है। + +[Survey लें :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/hi/docs/hello_nextflow/survey.md b/docs/hi/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..a9a9068c13 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Feedback survey + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आगे बढ़ने से पहले, कृपया training को rate करने, अपने experience के बारे में कोई भी feedback share करने, और हमें बताने के लिए यह छोटा 5-question survey complete करें कि तुम्हारी Nextflow journey में मदद करने के लिए हम और क्या कर सकते हैं। + +इसे complete करने में तुम्हें एक minute से भी कम समय लगना चाहिए। सभी के लिए हमारी training materials improve करने में मदद करने के लिए धन्यवाद! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/hi/docs/hello_nextflow/transcripts/00_orientation.md b/docs/hi/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..5b8f0dda84 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# ओरिएंटेशन - वीडियो ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स मटेरियल](../00_orientation.md) पर वापस जाएं। + +## स्वागत + +नमस्ते, Hello Nextflow में आपका स्वागत है। मेरा नाम Phil Ewels है। मैं Seqera में Open Source के लिए Product Manager हूं, और मुझे आज आपको इस पहले Nextflow प्रशिक्षण कोर्स में ले जाने में खुशी हो रहा है। + +हम Nextflow की बेसिक्स के बारे में जानेंगे, यह समझाएंगे कि pipelines को कैसे लिखा और चलाया जाता है और उन्हें कैसे कॉन्फ़िगर किया जाता है। + +और आप अपनी खुद की सरल मल्टी-स्टेप pipeline बनाएंगे। हम operators और channel factories जैसी शब्दावली को कवर करेंगे, और कोर्स के अंत तक, आप अपनी खुद की bioinformatics pipelines बनाना शुरू करने के लिए तैयार होंगे। + +अगर आपके कोई सवाल हैं, तो कृपया community.seqera.io पर संपर्क करें। हमारे पास वहां एक बहुत सक्रिय Nextflow कम्युनिटी है, प्रशिक्षण के लिए समर्पित एक सेक्शन है, तो बस हमें बताएं कि आप कहां अटके हैं और कोई न कोई मदद करने में सक्षम होगा। + +ठीक है। चलिए शुरू करते हैं। + +## ट्रेनिंग वेबसाइट + +Nextflow कोर्सों के लिए सभी प्रशिक्षण मटेरियल training.nextflow.io पर हैं। आप इसे अपने वेब ब्राउज़र में खोल सकते हैं। तो अभी इसे खोलें और हम एक नज़र डाल सकते हैं। + +मैं इसे वर्जन 2.1.1 के साथ चला रहा हूं। हम यहां-वहां छोटे अपडेट और फिक्स पुश करते हैं, तो चिंता न करें अगर यह थोड़ा अलग है, लेकिन अगर मटेरियल बहुत ज्यादा बदल गया है, तो आप हमेशा मटेरियल के उस सटीक वर्जन को चुनने के लिए शीर्ष पर इस वर्जन पिकर का उपयोग कर सकते हैं जिसके बारे में मैं बात करने जा रहा हूं। + +अगर आप लाइट मोड पसंद करते हैं, तो आप यहां वेबसाइट की थीम बदल सकते हैं। + +यहां अनुवाद देखें, हालांकि रिकॉर्डिंग के समय, यह वास्तव में केवल अंग्रेजी है, जो इस नए मटेरियल को कवर करती है। + +और प्रशिक्षण वेबसाइट के लिए सभी सोर्स कोड और वह सब कुछ जिसके साथ हम काम करेंगे, GitHub पर देखें। + +यहां होमपेज हमारे पास सभी विभिन्न प्रशिक्षण मटेरियल कोर्सों को सूचीबद्ध करता है। तो मैं नीचे स्क्रॉल करता हूं, हम Nextflow for newcomers के साथ Hello Nextflow कोर्स देखेंगे जो हम यहां करेंगे। आप अन्य सभी कोर्स भी देख सकते हैं जो हमारे पास हैं, जो इसी तरह काम करते हैं। + +## एनवायरनमेंट सेटअप + +मैं वास्तव में शीर्ष पर इस पहले वाले का उपयोग करके शुरू करने जा रहा हूं, जो सभी प्रशिक्षण कोर्सों के लिए सामान्य है, और यह विशेष रूप से हमारे वातावरण को सेट करने के बारे में है। + +मैं क्लिक करता हूं, यह मुझे इस सेक्शन में ले जाता है, और हम स्थानीय रूप से विकसित करने के लिए निर्देश देख सकते हैं। अगर आप अपने खुद के लैपटॉप के साथ VS Code की अपनी प्रति और अपने खुद के सॉफ़्टवेयर इंस्टॉलेशन का उपयोग करना चाहते हैं, या जो हम उम्मीद करते हैं कि अधिकांश लोग करेंगे, वह है GitHub Codespaces नामक किसी चीज़ का उपयोग करना। + +Codespaces GitHub द्वारा प्रदान की गई एक सेवा है जहां वे क्लाउड में एक वेब सर्वर चलाते हैं, जिससे आप कनेक्ट कर सकते हैं। उस सर्वर पर VS code इंस्टॉल है, जहां आप इसे अपने वेब ब्राउज़र में चला सकते हैं, या यदि आप चाहें, तो इसे अपने VS code के लोकल इंस्टॉलेशन से कनेक्ट कर सकते हैं। सभी गणना, सभी फ़ाइलें, सभी संपादन दूर से होता है, जिसका मतलब है कि आपको जो भी सॉफ़्टवेयर चाहिए वह पहले से इंस्टॉल आता है और सभी के लिए समान है। + +## GitHub Codespace बनाना + +सब कुछ के साथ codespace बनाने के लिए, डॉक्स मटेरियल में बटन खोजें, जो कहते हैं "Open in GitHub Codespaces"। मैं अभी उस पर क्लिक करने जा रहा हूं, इसे एक नए टैब में खोलूंगा। और मैं इस वेबपेज के साथ प्रस्तुत किया गया हूं। अब आप देख सकते हैं कि यह nextflow-io training के साथ पहले से कॉन्फ़िगर किया गया है। + +मैं बस create new codespace पर क्लिक कर सकता हूं। लेकिन वास्तव में हम अनुशंसा करते हैं कि हम दो के बजाय चार CPUs के साथ Nextflow प्रशिक्षण के लिए थोड़ी बड़ी मशीन का उपयोग करें। आप बदल सकते हैं कि मटेरियल का कौन सा वर्जन उपयोग करता है। तो यह 2.1.1 पर डिफ़ॉल्ट हो रहा है क्योंकि यह उस डॉक्स का वर्जन है जिसका मैंने लिंक फॉलो किया था। लेकिन मैं इसे रिपॉजिटरी की एक विशिष्ट ब्रांच पर भी सेट कर सकता हूं अगर मैं चाहूं। + +अब मैं create codespace पर क्लिक करने जा रहा हूं। और यह मेरे लिए वातावरण सेट अप करना शुरू करने जा रहा है। + +## Codespace निर्माण + +अब, पहली बार जब आप ऐसा करते हैं, तो इसमें काफी समय लगने वाला है, तो अब चाय का एक कप लेने का अच्छा समय है। खुद को आरामदायक बनाएं, अपने बगल में बैठे व्यक्ति से चैट करें। + +यदि आप रुचि रखते हैं, तो आप सेटअप के लॉग देखने के लिए यहां building codespace पर क्लिक कर सकते हैं। और आप यहां देख सकते हैं कि यह एक Docker इमेज को पुल कर रहा है जिसमें मुझे वह सब कुछ चाहिए जो मुझे चाहिए और वातावरण को कॉन्फ़िगर कर रहा है। + +अब, आपको पहली बार codespace बनाते समय ही इस तरह इंतजार करना होगा। यदि आप github.com/codespaces यहां जाते हैं, तो आप सभी विभिन्न Codespaces देखेंगे जो आपके पास खुले हैं। यहाँ वह है जो मैंने अभी बनाया है। अगली बार जब आप ऐसा करते हैं, तो आप यहां जा सकते हैं और आप पिछले codespace का चयन कर सकते हैं और सीधे वापस उसमें कूद सकते हैं। और उस मौजूदा वातावरण को गर्म करने के लिए यह बहुत, बहुत तेज़ प्रक्रिया है। यह VS Code और फ़ाइलों में किए गए सभी परिवर्तनों को भी रखेगा, इसलिए यदि आप छोड़ते हैं और वापस आते हैं तो आप अपनी प्रगति नहीं खोएंगे। + +आप अन्य एक्शन करने के लिए यहां तीन डॉट्स पर क्लिक कर सकते हैं। उदाहरण के लिए, यदि आपने इसे दो CPUs के साथ कॉन्फ़िगर किया है और अब आप चार चाहते हैं, तो आप मशीन टाइप बदल सकते हैं। या यदि आप स्क्रैच और फ्रेश से शुरू करना चाहते हैं, तो आप codespace को डिलीट कर सकते हैं। + +## VS Code का परिचय + +ठीक है, Codespaces ने मेरा वातावरण सेट करना समाप्त कर दिया है और अब वेब ब्राउज़र में VS Code के साथ प्रस्तुत किया गया है। + +यदि आप VS code के आदी हैं। यह बहुत परिचित महसूस होगा यदि आपने इसे पहले उपयोग नहीं किया है, तो यह बहुत सरल है। पेज के कुछ अलग-अलग हिस्से हैं जिनके बारे में आपको जागरूक होना चाहिए। + +यहां बाईं ओर, हमारे पास साइडबार है। आप प्रशिक्षण रिपो से GitHub रिपॉजिटरी में सभी विभिन्न फ़ाइलों के साथ Explorer सेट देख सकते हैं। + +बाईं ओर इन बटनों पर, साइडबार में विभिन्न टूलिंग हो सकते हैं। मैं प्रोजेक्ट की सभी फ़ाइलों को खोज सकता हूं। मैं Git के साथ काम कर सकता हूं, GitHub के साथ काम कर सकता हूं, इस तरह की सभी अलग-अलग चीजें। + +यहां शीर्ष पर मुख्य मेनू है। फ़ाइल एक्सप्लोरर वह है जो हम यहां सबसे अधिक रखेंगे, और आप इनमें से किसी भी फ़ाइल पर राइट क्लिक कर सकते हैं और सामान्य चीजें कर सकते हैं जिनकी आप अपेक्षा करेंगे। आपको इस तरह की कुछ चेतावनियों पर क्लिक करना पड़ सकता है जहां यह कट कॉपी जैसी है और आप अपनी लोकल मशीन पर भी डाउनलोड कर सकते हैं। + +जब codespace लोड होता है, तो यह हमें यहां इस मुख्य क्षेत्र में markdown फ़ाइल का पूर्वावलोकन देता है। यह github.com पर रेंडर होने वाले के समान ही है। मैं इसे बंद कर सकता हूं और अगर मैं उस Readme फ़ाइल पर डबल क्लिक करता हूं, तो आप देखेंगे कि यह इसे कोड एडिटर में कोड के रूप में खोलता है और किसी अन्य फ़ाइल की तरह, हम इस कोड को सीधे संपादित कर सकते हैं। + +अंत में यहां नीचे, हमारे पास टर्मिनल विंडो है। मैं लॉग देख रहा था जब यह बनाया गया था, तो यह वर्तमान चीज है जो यह दिखा रहा है। मैं एक नया टर्मिनल सत्र शुरू करने के लिए इस प्लस बटन को भी दबा सकता हूं। यह मेरी मशीन पर नहीं चल रहा है। याद रखें, यह क्लाउड में चल रहा है, और अगर मैं दो की गहराई तक tree करता हूं, तो आप वही सभी फ़ाइलें यहां देखेंगे, जो बाईं ओर थीं। + +## केवल "hello-nextflow" फ़ाइलें दिखाना + +इस GitHub रिपॉजिटरी में सभी विभिन्न प्रशिक्षण सेट होते हैं, न कि केवल वह जो हम कर रहे हैं। तो यदि आप चाहें, तो आप केवल Hello Nextflow फ़ोल्डर पर ध्यान केंद्रित कर सकते हैं। इसे थोड़ा साफ करने का एक तरीका मेनू फ़ाइल में जाना है और फिर add folder to workspace। + +हम उस पर क्लिक करते हैं training जाते हैं। Hello nextflow, और Add पर क्लिक करें। यह आपकी स्क्रीन को रिफ्रेश करेगा। और फिर Explorer में, अब हमारे पास दो अलग-अलग workspaces हैं, एक जो हमारे पास training के लिए पहले था और एक सिर्फ Hello Nextflow के साथ। + +यदि आप चाहें, तो आप training पर राइट क्लिक कर सकते हैं और साइडबार से इसे पूरी तरह से हटाने के लिए remove folder from workspace पर क्लिक कर सकते हैं। + +अब हमारे पास साइड में इस विशेष प्रशिक्षण कोर्स के लिए बस फ़ाइलें हैं। मैं उस चेतावनी को छिपा सकता हूं और अब मैं यहां टर्मिनल में भी ऐसा ही कर सकता हूं और डायरेक्टरी बदलने के लिए CD करता हूं। Hello, Nextflow। और फिर, हमारे पास वही फ़ाइलें यहां हैं, जो साइडबार पर हैं। + +## Hello Nextflow: फ़ाइलें + +Hello Nextflow कोर्स के लिए इन फ़ाइलों को देखते हुए। + +हमारे पास Nextflow के लिए `.nf` फ़ाइलों का एक समूह है, और प्रशिक्षण कोर्स के प्रत्येक अध्याय के लिए इनमें से एक फ़ाइल है। हम इन फ़ाइलों के माध्यम से काम करेंगे और अभ्यासों में उन्हें संशोधित करेंगे। + +हमारे पास एक `nextflow.config` फ़ाइल भी है, जिसमें इस वातावरण में Nextflow चलाने के लिए बुनियादी कॉन्फ़िग सेटिंग्स हैं, जिनके बारे में आपको इस बिंदु पर वास्तव में चिंता करने की आवश्यकता नहीं है। एक `greetings.csv` फ़ाइल, जिसका उपयोग हम डेटा प्रोसेसिंग के लिए करेंगे, जो इस कोर्स के अगले भाग में पेश की जाएगी, और एक `test-params.json` फ़ाइल, जिसका उपयोग भाग छह में किया जाएगा और आप अभी के लिए अनदेखा कर सकते हैं। + +ये Nextflow फ़ाइलें प्रत्येक अभ्यास की शुरुआत हैं। यदि आप देखना चाहते हैं कि वे कैसे दिखनी चाहिए जब वे समाप्त हो जाएं, तो आप `solutions` डायरेक्टरी में जा सकते हैं और प्रशिक्षण कोर्स के प्रत्येक भाग के लिए उत्तर हैं, ताकि आप जिस ओर लक्ष्य रखते हैं उसका एक काम करने वाला वर्जन देख सकें। + +## टर्मिनल खोलना + +यदि किसी भी समय आप टर्मिनल बंद करते हैं और याद नहीं रख सकते कि वापस कैसे जाना है, तो इसके बारे में चिंता न करें। workspace में विभिन्न पैनल खोलने और बंद करने के लिए शीर्ष पर ये बटन हैं। तो bottom panel के लिए इस पर क्लिक करें और यह फिर से प्रकट होगा। और बस सुनिश्चित करें कि आपने यहां terminal चुना है। आप इसे फुल स्क्रीन बनाने के लिए यहां इस बटन पर भी क्लिक कर सकते हैं, टर्मिनल के दाईं ओर तीर। + +आप मुझे ऐसा बहुत करते देखेंगे क्योंकि मैंने VS Code को ज़ूम इन किया है ताकि आप टेक्स्ट पढ़ सकें। आपकी स्क्रीन के आकार के आधार पर, आपको यह करने की आवश्यकता हो सकती है या नहीं। यही बात साइड पैनल को minimize करने के लिए भी जाती है। + +ठीक है। वातावरण के लिए यह काफी है। मुझे लगता है कि हम शुरू करने के लिए तैयार हैं। अध्याय एक के लिए अगले वीडियो में मेरे साथ जुड़ें। + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/hi/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..0fe6f0af21 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# भाग 1: Hello World - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स सामग्री](../01_hello_world.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए सेक्शन नंबर केवल संकेत के उद्देश्य से दिए गए हैं और हो सकता है कि सामग्री में सभी सेक्शन नंबर शामिल न हों। + +## स्वागत + +नमस्ते, Hello Nextflow के पहले अध्याय में आपका स्वागत है। + +छह भागों के इस कोर्स के पहले भाग में, हम Nextflow की बिल्कुल बुनियादी बातों में जाने वाले हैं। हम टर्मिनल में कुछ कमांड चलाकर शुरुआत करेंगे, और फिर हम उन Bash कमांड को लेंगे और देखेंगे कि उन्हें Nextflow स्क्रिप्ट में कैसे बनाया जाता है। + +हम उस पहले Nextflow pipeline को चलाने की कोशिश करेंगे, देखेंगे कि Nextflow क्या करता है, यह कहाँ चलता है, यह कौन सी फ़ाइलें बनाता है, और उन फ़ाइलों का उद्देश्य क्या है। + +ठीक है, चलिए शुरू करते हैं। + +## training.nextflow.io + +सबसे पहले, training.nextflow.io पर जाएं। बिल्कुल पहले की तरह, सारी सामग्री यहाँ लिखी गई है, और मैं इसे चरण-दर-चरण करूँगा। मैं प्रशिक्षण के चरणों को करते समय अपनी स्क्रीन दिखाऊंगा, लेकिन जो कुछ भी मैं कह रहा हूँ वह सब प्रशिक्षण सामग्री में है, इसलिए आप इसे अपनी गति से फॉलो कर सकते हैं, और आप सब कुछ वहाँ लिखा हुआ पा सकते हैं। + +इस वीडियो में वीडियो सबटाइटल भी सक्षम हैं, इसलिए बेझिझक उन्हें देखें और मैं जो कह रहा हूँ उसे सटीक रूप से ट्रैक करें। + +ठीक है, चलिए Hello Nextflow पर जाते हैं। यह वह कोर्स है जिसे हम आज करने जा रहे हैं, और हमने पहले वीडियो में पहले ही ओरिएंटेशन कर लिया है, इसलिए हम सीधे भाग एक में जाएंगे। Hello World. + +ठीक है, मैं अब इस प्रशिक्षण सामग्री को छोड़ रहा हूँ और अपने Code Spaces वातावरण में जा रहा हूँ। यह वही है जो हमने पहले वीडियो में सेटअप किया था। उम्मीद है कि आपके अपने सिस्टम में भी कुछ ऐसा ही दिखता होगा। मैं VS Code का उपयोग कर रहा हूँ और मैं प्रशिक्षण सामग्री को देख रहा हूँ और मैंने hello Nextflow डायरेक्टरी में डायरेक्टरी बदल दी है। + +## 0. Warmup: Hello World सीधे चलाएं + +ठीक है। चलिए कुछ बुनियादी बातों से शुरुआत करते हैं, जो उम्मीद है कि सभी को परिचित लगेंगी। मैं टर्मिनल में बहुत ही बुनियादी कमांड लिखकर शुरुआत करने जा रहा हूँ। यहाँ नीचे मैं 'echo Hello World!"' लिखने जा रहा हूँ, एंटर दबाएं और कोई आश्चर्य नहीं, टर्मिनल वही करता है जो मैं इसे करने के लिए कहता हूँ और वह स्ट्रिंग रिटर्न करता है। Hello world. + +ठीक है, फिर मैं उस कमांड को पाने के लिए ऊपर दबाने जा रहा हूँ और इसे थोड़ा और संपादित करूँगा। चलिए इस बार उस आउटपुट को एक फ़ाइल में रीडायरेक्ट करते हैं। मैं इसे output.txt में लिखने जा रहा हूँ और एंटर दबाता हूँ, इस बार टर्मिनल पर कुछ नहीं क्योंकि आउटपुट टर्मिनल पर नहीं आया। यह उस फ़ाइल में चला गया। + +फिर मैं 'cat output.txt' करके उस फ़ाइल को पढ़ सकता हूँ, फ़ाइल नाम को ऑटो विस्तारित करने के लिए वहाँ टैब दबाएं और वह रहा। फ़ाइल वहाँ है। + +मैं उस फ़ाइल को साइडबार में VS Code के फ़ाइल एक्सप्लोरर में भी देख सकता हूँ। मैं इसे डबल क्लिक कर सकता हूँ और इसे यहाँ खोल सकता हूँ। यदि आप किसी भी चीज़ को क्लिक किए बिना इसे VS Code में खोलना चाहते हैं, तो आप "code" और फिर "output.txt" भी कर सकते हैं और यह वही काम करता है। + +बढ़िया। यह पहला चरण है। बहुत सरल। + +## 1. Hello World workflow स्टार्टर स्क्रिप्ट की जांच करें + +ठीक है। अब हम बिल्कुल वही काम करने जा रहे हैं, लेकिन सीधे टर्मिनल में करने के बजाय Nextflow में। + +हम शुरुआत करने के लिए पहली उदाहरण स्क्रिप्ट का उपयोग करने जा रहे हैं, इस फ़ाइल को Hello World कहा जाता है। मैं टर्मिनल में इसे देखने के लिए "ls" कर सकता हूँ, और मैं Mac पर हूँ, इसलिए मैं उस फ़ाइल को खोलने के लिए command क्लिक कर सकता हूँ, या मैं साइडबार में यहाँ डबल क्लिक कर सकता था। + +इस फ़ाइल में हम कुछ चीजें देख सकते हैं। बिल्कुल ऊपर, एक हैश स्टेटमेंट है जो कहता है कि यह एक Nextflow फ़ाइल है और इसे इस तरह निष्पादित किया जा सकता है। हल्के भूरे रंग में यहाँ कुछ कमेंट हैं, जो केवल नियमित कोड कमेंट हैं, जो निष्पादन को प्रभावित नहीं करते हैं, और बस हमें स्क्रिप्ट पढ़ने में मदद करते हैं। + +और फिर दो मुख्य संरचनाएं हैं। यहाँ एक process है और एक workflow। + +Nextflow में processes pipeline के चरण हैं। वे वे भाग हैं जो वास्तव में तर्क करते हैं और प्रोसेसिंग करते हैं। + +फिर नीचे workflow इन processes को एक साथ जोड़ता है और workflow के तर्क को नियंत्रित करता है, कि सब कुछ एक दूसरे से कैसे जुड़ता है। + +हम एक process को देखकर शुरुआत करने जा रहे हैं। हम एक पल में workflow पर वापस आएंगे। + +## 1.2 process की परिभाषा + +तो हर process एक कीवर्ड process से शुरू होता है। एक नाम होता है और फिर कुछ कर्ली ब्रैकेट होते हैं और उन कर्ली ब्रैकेट के भीतर सब कुछ उस एकल process का है। + +एक process में एक script सेक्शन होना चाहिए, और यहाँ एक मल्टी-लाइन स्ट्रिंग में एक bash स्निपेट होता है, जो कोड का वह हिस्सा है जो वास्तव में कंप्यूट वातावरण में निष्पादित होता है। + +हमारे यहाँ एक output स्टेटमेंट भी है, जो Nextflow को बताता है कि script द्वारा कौन सी फ़ाइलें बनने की उम्मीद है। ध्यान दें कि यहाँ output में एक कीवर्ड path है, जो Nextflow को बताता है कि यह एक फ़ाइल है, न कि एक value या स्ट्रिंग। + +script ब्लॉक के भीतर, यह केवल एक नियमित bash स्टेटमेंट है, और यह बिल्कुल वैसा ही है जैसा हमने टर्मिनल में लिखा था। हम output.txt नामक फ़ाइल में hello world को echo कर रहे हैं। यह output.txt फिर output परिभाषा द्वारा उठाया जाता है। output परिभाषा वास्तव में कुछ नहीं कर रही है। यह बस Nextflow को बता रही है कि क्या उम्मीद करनी है, और अगर यह फ़ाइल नहीं बनाई गई, तो Nextflow एक एरर थ्रो करेगा। + +ध्यान दें कि यह उदाहरण बहुत अच्छा नहीं है क्योंकि हमने यहाँ फ़ाइल नाम हार्डकोड किया है, output.txt और output.txt। अगर इनमें से कोई भी बदला गया, तो यह हमारे workflow में एरर का कारण बनेगा। + +इसे variables के साथ करने का एक बेहतर तरीका है, जिसे हम एक मिनट में कवर करेंगे। + +## 1.3 workflow की परिभाषा + +ठीक है। workflow की ओर बढ़ते हुए, हम देख सकते हैं कि हमारे पास एक कमेंट है और फिर हम sayHello नामक process को चलाते हैं। यह वही कीवर्ड है जो यहाँ ऊपर है। यह जितना सरल हो सकता है एक workflow के बारे में है। हम बस एक single process को बिना किसी variable input के कॉल कर रहे हैं, इसलिए हम इसे किसी और चीज़ से कनेक्ट नहीं कर रहे हैं। इस कोर्स के बाद के भाग में, हम बात करेंगे कि variable inputs का उपयोग करके और channels के साथ चीजों को जोड़कर इसे और अधिक शक्तिशाली कैसे बनाया जाए। + +## 2. workflow चलाएं + +ठीक है, यह सब कुछ है जो हमें चाहिए। चलिए देखते हैं कि क्या हम इसे चला सकते हैं और देखते हैं कि क्या होता है। मैं बस टर्मिनल को साफ़ करने जा रहा हूँ और फिर मैं "nextflow run" करने जा रहा हूँ, और मैं फ़ाइल नाम कॉल करने जा रहा हूँ, जो hello-world.nf है। एक Nextflow pipeline चलाने के लिए बस इतना ही चाहिए। यह pipeline कोई input नहीं लेता है, इसलिए हमें किसी अन्य arguments की आवश्यकता नहीं है। + +चलिए एंटर दबाते हैं और देखते हैं कि क्या होता है। + +ठीक है। उम्मीद है कि आपके पास कुछ आउटपुट होना चाहिए, जो इस तरह दिखता है। हमारे पास कुछ जानकारी है जो हमें बताती है कि Nextflow चला और यह किस संस्करण का उपयोग कर रहा था। हमें बताता है कि कौन सी स्क्रिप्ट लॉन्च की गई थी और यह हमें इस विशेष workflow निष्पादन के लिए एक यादृच्छिक रूप से उत्पन्न नाम देता है। इस मामले में, मेरा "gloomy_crick" कहलाया। + +हालांकि, इसका सबसे महत्वपूर्ण हिस्सा यह है कि यह हमें बताता है कि pipeline में कौन से चरण चले। आप देख सकते हैं कि हमारा sayHello नामक process चला, और यह एक बार चला और यह सौ प्रतिशत पूर्ण था। + +यहाँ यह हिस्सा उस विशेष workflow task के लिए hash है। प्रत्येक process एक या अधिक बार चलता है, और उन निष्पादनों में से प्रत्येक को एक task कहा जाता है। + +## 2.2. work डायरेक्टरी में आउटपुट और लॉग खोजें + +प्रत्येक task को अपनी अलग डायरेक्टरी मिलती है जहाँ यह चलता है, इसलिए यह workflow के बाकी निष्पादन से अलग है। यह hash work डायरेक्टरी के भीतर फ़ाइल संरचना से मेल खाता है। अगर मैं "tree work" करता हूँ, तो हम a0 देख सकते हैं, और फिर एक छोटे hash का एक लंबा संस्करण, और फिर हमारी output.txt फ़ाइल। आप इसे साइडबार में भी देख सकते हैं। + +आप साइडबार में देख सकते हैं कि यहाँ कुछ अतिरिक्त फ़ाइलें हैं। इनके टर्मिनल में न दिखने का कारण यह है कि ये हिडन फ़ाइलें हैं, वे एक डॉट से शुरू होती हैं। और वास्तव में, अगर मैं "tree -a" सभी के लिए और "work" करता हूँ, तो हम उन्हें यहाँ देख सकते हैं। + +ये डॉट फ़ाइलें हर एक work डायरेक्टरी में मौजूद होती हैं जो Nextflow बनाता है, और प्रत्येक का थोड़ा अलग कार्य होता है। सबसे पहले .command.begin में Nextflow के लिए कुछ निर्देश शामिल हैं जो task को चलने से पहले सेटअप करते हैं। .command.run वे वास्तविक निर्देश हैं जो Nextflow द्वारा स्वयं निष्पादित किए जाते हैं। फिर .command.sh शायद सबसे दिलचस्प है। यह वह स्क्रिप्ट है जो हमारे process ब्लॉक script से resolve की गई थी। + +अगर मैं इसे खोलता हूँ, तो आप देख सकते हैं कि हमारे पास output.txt फ़ाइल में हमारा "echo Hello World" है। यह इस मामले में हमारे process के बिल्कुल समान है, लेकिन अगर हमारे Nextflow कोड के भीतर कोई variables हैं, तो प्रत्येक task का एक अलग .command.sh होगा, और आप देख सकते हैं कि उन variables को कैसे resolve किया गया। + +अन्य फ़ाइलें इस बारे में हैं कि task कैसे निष्पादित हुआ। तो .command.err, .log और .out स्टैंडर्ड एरर, स्टैंडर्ड आउटपुट और दोनों संयुक्त हैं। और .exitcode Nextflow को बताता है कि यह task किस exit code के साथ निष्पादित हुआ, चाहे वह सफल हो या नहीं। + +अंत में, हमारी output.txt फ़ाइल है और निश्चित रूप से, "Hello World" यह वही है जिसकी हम उम्मीद कर रहे थे और यह वही है जो बनाया गया था। + +ठीक है, बढ़िया। यह आपका पहला Nextflow रन था। बधाई हो। यह वास्तव में उतना ही सरल है। + +इसके बाद, हम इस बारे में जाएंगे कि इसे थोड़ा और सुविधाजनक तरीके से कैसे किया जाए ताकि हमें हर बार pipeline को चलाने के तरीके में बदलाव करने के लिए कोड को संपादित न करना पड़े। + +## 3. workflow निष्पादन प्रबंधित करें + +यह डायरेक्टरी संरचना सभी कार्यों को अलग रखने और सब कुछ व्यवस्थित रखने के लिए बहुत अच्छी है, लेकिन निश्चित रूप से, आपकी आउटपुट फ़ाइलों को खोजना बहुत सुविधाजनक नहीं है। आप अपने pipeline के परिणामों को खोजने की कोशिश करते हुए बहुत सारी नेस्टेड डायरेक्टरी के माध्यम से खोदना नहीं चाहते। + +## 3.1. आउटपुट प्रकाशित करें + +अच्छी खबर यह है कि आपको ऐसा करना नहीं है। work डायरेक्टरी वास्तव में सिर्फ Nextflow के उपयोग के लिए हैं। तो हम जो करने जा रहे हैं वह है Nextflow के लिए publishDir नामक एक फ़ंक्शन का उपयोग करना। + +हम अपने workflow पर वापस जाते हैं, process पर जाते हैं। हम यहाँ एक नया स्टेटमेंट जोड़ सकते हैं जिसे एक directive कहा जाता है। यह वह है जो Nextflow इन चीजों को processes के शीर्ष पर कहता है जो यह बढ़ाती हैं कि कार्यक्षमता कैसे काम करती है, और हम जिसका उपयोग करने जा रहे हैं उसे publishDir कहा जाता है। + +आप देख सकते हैं कि मैंने यहाँ टाइप करना शुरू किया है और VS Code के लिए Nextflow एक्सटेंशन ने मेरे लिए directive सुझाया है, इसलिए मैं बस एंटर दबा सकता हूँ। + +ठीक है। मैं इसके बाद "results" नामक एक डायरेक्टरी बनाने जा रहा हूँ और हम इसे आउटपुट फ़ाइलों को वहाँ कॉपी करने के लिए कहेंगे। तो मैं mode copy कहने जा रहा हूँ। बढ़िया। सेव करने जा रहा हूँ और चलिए workflow को फिर से चलाते हैं। + +nextflow run hello-world.nf + +यह बिल्कुल उसी तरह चलता है। हालांकि ध्यान दें कि इस बार हमारे पास थोड़ा अलग hash है। हर बार जब आप workflow चलाते हैं तो Nextflow एक अलग hash का उपयोग करेगा। और परिणामस्वरूप हमारे पास work डायरेक्टरी का एक अलग सेट है। क्षेत्र, एक eb कहा जाता है, लेकिन आप देख सकते हैं कि सभी फ़ाइलें समान हैं। हालाँकि, इस बार जो नया है वह यह है कि हमारे पास "results" नामक एक डायरेक्टरी भी है। + +यहाँ "results" के भीतर हमारी output फ़ाइल है। यही हमने Nextflow से करने के लिए कहा था। हमने कहा, results फ़ाइलों को "results" नामक डायरेक्टरी में सेव करें और उन्हें वहाँ कॉपी करें। और इसलिए अब यह खोजना बहुत आसान है। यह बस वहाँ है जहाँ हमने workflow लॉन्च किया था और सभी अलग-अलग फ़ाइलों को वहाँ व्यवस्थित किया जा सकता है, हालांकि हम चाहें, इस बात की परवाह किए बिना कि Nextflow ने वास्तविक निष्पादन कहाँ या कैसे चलाया। + +ध्यान दें कि publishDir symlinks को संभाल सकता है, जो अच्छा है यदि आप एक shared file system पर काम कर रहे हैं और आप स्पेस बचाना चाहते हैं। और साथ ही आपको एक process द्वारा बनाई गई सभी फ़ाइलों को एक output के रूप में परिभाषित करने की आवश्यकता नहीं है। + +Nextflow केवल उन चीजों को कॉपी करेगा जो इस output ब्लॉक में परिभाषित हैं। इसलिए यदि आपके पास चरण द्वारा बनाई गई मध्यवर्ती फ़ाइलें हैं, जो इस process के downstream की आवश्यकता नहीं हैं, तो आप उन्हें output में परिभाषित नहीं करते हैं और वे publishDir में नहीं दिखाई देंगी। तो यह एक pipeline से आपकी आउटपुट फ़ाइलों को साफ़ रखने और कार्यस्थल समाप्त होने के बाद मध्यवर्ती फ़ाइलों को आसानी से हटाने का एक तरीका है। + +एक त्वरित नोट यहाँ। कुछ नया Nextflow syntax आ रहा है जिसे workflow output definitions कहा जाता है, जो अंततः publishDir को बदल देगा। यह हमें workflow level पर workflow ब्लॉक में नीचे workflow से सभी आउटपुट परिभाषित करने का एक तरीका देता है। यह Nextflow docs में वर्णित है यदि आप इसे आज़माना चाहते हैं। लेकिन अभी के लिए, publishDir कुछ समय के लिए रहेगा, इसलिए 2025 के लिए अभी भी प्रशिक्षण में है। + +## 3.2. -resume के साथ एक workflow को फिर से लॉन्च करें + +ठीक है। मैंने उल्लेख किया कि work डायरेक्टरी में अब हर बार जब हम workflow चलाते हैं तो एक अलग hash के साथ दो सेट परिणाम हैं। यह अच्छा है। हालाँकि, कभी-कभी हम हर बार चरणों को फिर से गणना नहीं करना चाहते हैं यदि हमें इसकी आवश्यकता नहीं है। + +शायद आप अपने workflow को पुनरावृत्त रूप से बना रहे हैं और आप चरणों को जोड़ रहे हैं और आप चाहते हैं कि पहले चरण केवल cached versions का पुन: उपयोग करें। या शायद आपके कंप्यूट सिस्टम पर आपके workflow के बीच में कुछ गलत हो गया और आप चाहते हैं कि यह वहीं से आगे बढ़े जहाँ यह छूट गया था, लेकिन उन चरणों को छोड़ दें जो इसने पहले ही पूरा कर लिए थे। + +Nextflow में इसके लिए अंतर्निहित कार्यक्षमता है जिसे resume कहा जाता है। चलिए इसे आज़माते हैं। तो सबसे पहले, मैं बस work डायरेक्टरी पर एक नज़र डालने जा रहा हूँ ताकि हम याद रख सकें कि वहाँ क्या था। + +और फिर मैं "nextflow run hello-world.nf" करने जा रहा हूँ और मैं यहाँ एक single कमांड जोड़ने जा रहा हूँ, "-resume"। + +ध्यान दें, single dash, यह वास्तव में महत्वपूर्ण है। मैं इसे चलाने जा रहा हूँ और आउटपुट मूल रूप से बिल्कुल समान दिखने वाला है, कुछ छोटे अंतरों के साथ। + +ध्यान दें यहाँ यह भूरे रंग में "cached" कहता है। इसका मतलब है कि Nextflow ने task नहीं चलाया। इस बार इसे कुछ ऐसा मिला जो आवश्यकताओं से मेल खाता था और इसने चरण को फिर से चलाने के बजाय सीधे उन आउटपुट का पुन: उपयोग किया। + +और निश्चित रूप से, यदि आप यहाँ hash को देखते हैं, तो आप देख सकते हैं कि यह मौजूदा hash से मेल खाता है जो हमारे पास पिछले रन से था। + +## 3.3. पुरानी work डायरेक्टरी हटाएं + +ठीक है। लेकिन यदि आप पुनरावृत्त रूप से विकसित कर रहे हैं, तो आप इन workflow फ़ाइलों में से बहुत सारे बनाने जा रहे हैं। यह एक समस्या हो सकती है यदि आपकी स्पेस कम हो सकती है। + +Nextflow कुछ सहायक कमांड के साथ इन work डायरेक्टरी को साफ़ करने में हमारी मदद कर सकता है। अगर मैं "nextflow log" करता हूँ। यह मुझे इस डायरेक्टरी में किए गए सभी विभिन्न workflow runs की एक सूची देगा, और उनके रन नाम यहाँ हैं। आप gloomy quick देख सकते हैं, जो पहला था जो हमने चलाया, और फिर ये दो नए। + +अब हम उस नाम को ले सकते हैं और "nextflow clean" कमांड के साथ उनका उपयोग कर सकते हैं। मैं एक single रन नाम निर्दिष्ट कर सकता हूँ। या इससे भी बेहतर, मैं Nextflow को "-before" के साथ एकल workflow नाम से पहले की हर चीज़ को हटाने के लिए कह सकता हूँ, और मैं "stupefied_shaw" में डालने जा रहा हूँ। यह मेरा सबसे हालिया रन था, "-n"। + +"-n" कमांड ने Nextflow को वास्तव में कुछ भी हटाए बिना इसे dry run के रूप में करने के लिए कहा, और यह हमें बताता है कि कौन सी hash डायरेक्टरी हटा दी गई होंगी। निश्चित रूप से, यह पहले निष्पादन से बस वही है। दोनों दूसरे निष्पादन एक ही hash डायरेक्टरी का उपयोग करते हैं। + +मैं इसे फिर से चलाने जा रहा हूँ, लेकिन अब dry run के लिए "-n" के बजाय, मैं force के लिए "-f" करने जा रहा हूँ और इसने उस hash डायरेक्टरी को हटा दिया है। अब अगर मैं "tree work" करता हूँ, तो हम देख सकते हैं, हमारे पास बस यह आउटपुट फ़ाइल बची है। + +बढ़िया। तो हमने वहाँ बहुत सारी डिस्क स्पेस साफ़ की है। + +work डायरेक्टरी हटाते समय ध्यान देने योग्य कुछ बातें, यदि आप अपनी results डायरेक्टरी में सामान को symlink करते हैं, तो उन symlink स्रोतों को अब हटा दिया जाएगा और आपके परिणाम हमेशा के लिए चले जाएंगे। इसलिए copy mode का उपयोग करना एक सुरक्षित काम है, और आम तौर पर हम जो अनुशंसा करते हैं। + +दूसरे, Nextflow की resume कार्यक्षमता इन work डायरेक्टरी पर निर्भर करती है। इसलिए यदि आप उन्हें हटाते हैं और आप Nextflow को फिर से चलाते हैं, तो resume कार्यक्षमता अब काम नहीं करेगी। इसलिए यह आप पर निर्भर है कि आप ट्रैक करें कि आपको किन चीजों की आवश्यकता हो सकती है या नहीं, और केवल तभी चीजों को हटाएं जब आप सुनिश्चित हों कि ऐसा करना सुरक्षित है। + +दूसरी चीज़ जो हम कर सकते हैं वह है कि हम पूरी work डायरेक्टरी को हटा सकते हैं यदि हमने अपना workflow रन समाप्त कर लिया है और हम सुनिश्चित हैं कि हमें इसकी अब आवश्यकता नहीं है। + +तो मैं "rm -r work" कर सकता हूँ। मुझे पता है कि वहाँ कुछ भी महत्वपूर्ण नहीं था। मेरे पास मेरे परिणाम हैं जिनकी मुझे results डायरेक्टरी में परवाह है जहाँ हमने उन्हें कॉपी किया। और इसलिए work डायरेक्टरी को हटाना सुरक्षित था। यह आप पर निर्भर है कि आप इनमें से किस दृष्टिकोण का उपयोग करते हैं। + +## 4. command line पर पास किए गए variable input का उपयोग करें + +ठीक है, आगे क्या है? मैंने उल्लेख किया कि हमने अपने workflow स्क्रिप्ट में यहाँ कुछ मूल्यों को हार्डकोड किया था, output.txt फ़ाइल, और कि इसे करने का एक बेहतर तरीका हो सकता है। + +चलिए इस पर शुरुआत करते हैं। हम जो करने जा रहे हैं वह तीन चीजें हैं। हम process में एक नया input जोड़ने जा रहे हैं। हम process script को बताने जा रहे हैं कि उस input का उपयोग कैसे करें, और फिर हम इसे workflow में वायर करने जा रहे हैं ताकि हम इसे Nextflow चलाते समय command line flag के साथ गतिशील रूप से उपयोग कर सकें। + +तो सबसे पहले। चलिए यहाँ एक input ब्लॉक जोड़ते हैं। output की तरह ही। यह process के लिए एक नया सेक्शन है, और मैं कहने जा रहा हूँ, "val greeting"। + +यहाँ ध्यान दें, मैं "val" कह रहा हूँ, जो कहता है कि यह एक variable है, न कि path। + +फिर मैं script में नीचे जा सकता हूँ और फिर मैं इस हार्डकोड किए गए टेक्स्ट को यहाँ निकाल सकता हूँ और $greeting कर सकता हूँ। यह किसी भी अन्य प्रोग्रामिंग भाषा की तरह काम करता है। हम यहाँ एक variable को परिभाषित कर रहे हैं और हम इसे इस script ब्लॉक के भीतर संदर्भित कर रहे हैं। जब Nextflow इस process को चलाता है, तो variable को interpolate किया जाएगा। और जब हम उस .command.sh फ़ाइल को देखने जाते हैं, तो हम वहाँ वास्तविक हार्ड कोडेड स्ट्रिंग देखेंगे। + +## 4.1.3. एक CLI पैरामीटर सेटअप करें और इसे process कॉल में input के रूप में प्रदान करें + +ठीक है, लेकिन हम variable कहाँ प्रदान करते हैं? इसके बाद हम workflow सेक्शन में जाते हैं, और आप देख सकते हैं कि यहाँ एक्सटेंशन कह रहा है, हम अब एक input की उम्मीद करते हैं, और इसने मुझे एक चेतावनी दी है। + +अब, सबसे सरल चीज़ जो हम कर सकते हैं वह है इसे हार्डकोड करना। मैं "Hello World" लिख सकता था और process को वह स्ट्रिंग input प्रदान कर सकता था। लेकिन फिर से, यह वास्तव में किसी भी समस्या का समाधान नहीं करेगा। हमें अभी भी हर बार कुछ बदलना चाहते हैं तो pipeline कोड को वापस जाना और संपादित करना होगा, जो अच्छा नहीं है। + +अच्छी खबर यह है कि Nextflow में command line arguments को संभालने के लिए एक अंतर्निहित सिस्टम है जिसे parameters कहा जाता है। तो इसके बजाय, मैं इन विशेष variables में से एक का उपयोग कर सकता हूँ जिसे params कहा जाता है और मैं इसे जो चाहूं कह सकता हूँ, लेकिन मैं greeting कहने जा रहा हूँ ताकि यह workflow logic से मेल खाए। + +सेव करें और चलिए देखते हैं कि हम इसके साथ क्या कर सकते हैं। + +तो अगर मैं टर्मिनल पर वापस जाता हूँ। तो हम "nextflow run hello-world.nf" करते हैं। बिल्कुल पहले की तरह, लेकिन मुख्य अंतर यह है कि हम --greeting करते हैं + +ध्यान दें, यहाँ दो dashes हैं क्योंकि यह एक पैरामीटर है। जब हमने पहले workflow को resume किया, तो वह एक single dash था। ऐसा इसलिए है क्योंकि resume एक कोर Nextflow विकल्प है, और यह एक पैरामीटर है जो हमारे pipeline के लिए विशिष्ट है। + +दोनों को मिक्स न करें। ऐसा करना आसान है। यदि आपने --resume के बजाय सिर्फ एक dash किया, तो वह "params.resume" होगा, जो कुछ नहीं करेगा। इसी तरह, यदि आपने यहाँ एक single dash किया, तो Nextflow इसे एक key argument के रूप में नहीं पहचानेगा। + +तो यह --greeting है, जो parameters greeting से मेल खाता है। + +अब मैं जो चाहूं टेक्स्ट का अनुसरण कर सकता हूँ। तो मैं इस समय स्वीडन में हूँ, इसलिए मैं कहने जा रहा हूँ, "Hej världen"। + +तो चलिए इसे चलाते हैं, देखते हैं कि क्या होता है, सच्चाई का क्षण। + +ठीक है, तो आप देख सकते हैं कि process फिर से चला, बिल्कुल पहले की तरह, एक single निष्पादन के साथ sayHello। + +यह publishDir "results" डायरेक्टरी में फ़ाइल को अधिलेखित कर देगा। और इसलिए फ़ाइलों को फिर से चलाते समय सावधान रहें क्योंकि published air में चीजें अधिलेखित हो जाएंगी। + +अब मैं "code results/output.txt" कर सकता हूँ, और निश्चित रूप से, हमारा आउटपुट अपडेट हो गया है और अब "Hej världen" कहता है। + +## 4.2. command line पैरामीटर के लिए डिफ़ॉल्ट मान का उपयोग करें + +ठीक है, यह बढ़िया है। लेकिन अब समस्या यह है कि हमारा workflow हमेशा इस पैरामीटर को परिभाषित करने पर निर्भर करता है, और समझदार डिफ़ॉल्ट होना अच्छा है ताकि चीजें आपके workflow के लिए समझदार तरीके से चलें जब तक कि आप डिफ़ॉल्ट को ओवरराइड न करें। + +तो हम ऐसा करने का तरीका यह है कि हम अपने workflow स्क्रिप्ट में पैरामीटर के लिए एक डिफ़ॉल्ट मान सेट करें। + +तो अगर मैं अपनी hello-world.nf फ़ाइल पर वापस जाता हूँ, तो मैं workflow के ठीक ऊपर स्क्रिप्ट में जा सकता हूँ, "params.greeting" टाइप कर सकता हूँ और इसे किसी अन्य variable की तरह परिभाषित कर सकता हूँ। तो चलिए यहाँ एक स्ट्रिंग डालते हैं और चलिए कहते हैं "Holà mundo!" + +अब इस पैरामीटर को एक डिफ़ॉल्ट परिभाषित किया गया है, जिसका उपयोग यहाँ किया जाएगा, या हम अभी भी इसे command line पर --greeting के साथ ओवरराइड कर सकते हैं, बिल्कुल पहले की तरह। + +तो चलिए देखते हैं कि यह काम करता है। "nextflow run hello-world.nf" + +इस बार कोई command-line arguments नहीं, और जाँचें कि क्या इसने सही काम किया। + +"code results/output.txt"। और यह रहा। हमें अपना डिफ़ॉल्ट मिला। + +ठीक है, चलिए फिर से कोशिश करते हैं, बस जाँचें कि मैं आपको कोई झूठ नहीं बता रहा हूँ। चलिए इसे फिर से चलाते हैं, लेकिन --greeting करते हैं, और प्रशिक्षण सामग्री से उदाहरण का उपयोग करते हैं, चलिए कहते हैं "Konnichiwa!" + +workflow को फिर से चलाता है, और निश्चित रूप से, शीर्ष पर हमारी आउटपुट फ़ाइल बस नए मान के साथ अपडेट की गई है जो हमने command line पर प्रदान किया था। + +बढ़िया। किसी भी Nextflow workflow को लिखने के लिए यह एक वास्तविक केंद्रीय पहलू है। अपने pipeline कोड में समझदार डिफ़ॉल्ट परिभाषित करना, लेकिन टर्मिनल पर command line arguments रखकर अंतिम उपयोगकर्ता के लिए कॉन्फ़िगर करना बहुत आसान बनाना। + +ध्यान दें कि अंतिम उपयोगकर्ता कई अलग-अलग स्थानों पर config को अधिलेखित कर सकता है। आपके होम डायरेक्टरी में एक config फ़ाइल हो सकती है, जो आपके द्वारा किए गए हर एक Nextflow रन पर लागू होती है। आपके लॉन्च डायरेक्टरी में एक config फ़ाइल हो सकती है। आपके pipeline डायरेक्टरी में एक config फ़ाइल हो सकती है। ये सभी विभिन्न config स्थान एक विशिष्ट क्रम में लोड किए जाते हैं, जो Nextflow docs में वर्णित है। + +ठीक है, यह सेक्शन एक का अंत है। हमारे पास एक process और एक workflow के साथ Nextflow में हमारी पहली workflow स्क्रिप्ट थी। हमने inputs, outputs, scripts और publishing को देखा है, और यह कि कैसे पैरामीटर और एक input channel को हमारे process में वायर करें। + +बधाई हो, Nextflow कोड लिखने की ओर आपका पहला कदम पूरा हो गया है। + +थोड़ा ब्रेक लें और मैं आपको कुछ मिनटों में अध्याय दो के लिए वापस मिलूंगा। + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/hi/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..09bae7da96 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# भाग 2: Hello Channels - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पृष्ठ केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स सामग्री](../02_hello_channels.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए सेक्शन नंबर केवल संकेत के लिए प्रदान किए गए हैं और सामग्री में सभी सेक्शन नंबर शामिल नहीं हो सकते हैं। + +## स्वागत + +नमस्ते, Hello Nextflow के भाग दो में आपका स्वागत है। + +इस अध्याय को Hello Channels कहा जाता है। हम Nextflow के इस मौलिक हिस्से के बारे में बात करने वाले हैं। + +Channels वे चीजें हैं जो आपकी pipeline में विभिन्न चरणों को जोड़ती हैं, जिस तरह से आपका डेटा और लॉजिक आपके workflow के माध्यम से प्रवाहित होता है। + +ठीक है, चलिए शुरू करते हैं। + +चलिए training.nextflow.io पर जाकर शुरू करते हैं + +साइडबार में Hello Nextflow और भाग दो पर क्लिक करें। Hello Channels. + +सभी सामग्री यहां लिखी हुई है ताकि आप अपनी गति से अनुसरण कर सकें और जो कुछ भी आपसे छूट गया हो उसे पकड़ सकें। + +एक बार जब आप वेबसाइट खोल लें, तो आप Codespaces लोड कर सकते हैं और हम पिछले अध्याय के अंत से जारी रखेंगे। + +## 0. वार्म-अप: hello-channels.nf चलाएं + +इस अध्याय के लिए, हम एक अलग फ़ाइल को संपादित करने जा रहे हैं। इसे Hello Channels कहा जाता है, तो आप इसे साइडबार में पा सकते हैं, इसे खोलने के लिए डबल क्लिक करें। + +अब यदि आप अभी-अभी अध्याय एक से आए हैं, तो यह फ़ाइल आपको बहुत परिचित लगेगी। यहां शुरुआती बिंदु मूल रूप से वह है जहां हम अध्याय एक समाप्त करते हैं, हमारे process sayHello के साथ, हमारे input, output, हमारे publishDir और हमारे params.greeting, और हमारे सरल workflow के साथ। + +हम एक नई फ़ाइल से शुरू कर रहे हैं, इसलिए यह सभी के लिए समान स्तर है, लेकिन यदि आप चाहें तो अपनी पिछली फ़ाइल के साथ जारी रख सकते हैं। + +ध्यान दें, मैंने यहां सभी .nextflow\* फ़ाइलें और work डायरेक्टरी भी हटा दी हैं, बस ताकि यह एक स्वच्छ शुरुआती बिंदु हो। यह महत्वपूर्ण नहीं है कि आप ऐसा करें या नहीं, यह आप पर निर्भर है। + +ठीक है। चलिए यह जांच कर शुरू करते हैं कि यह pipeline अभी भी उम्मीद के अनुसार काम करती है। मैं यहां terminal लाने जा रहा हूं। + +"nextflow run hello-channels.nf" करें और enter दबाएं। + +यह उस छोटे workflow को चलाने वाला है, हमारे sayHello चरण को चलाता है, उस hash के साथ एक work डायरेक्टरी उत्पन्न करता है, और यहां हमारा results फ़ोल्डर है और हमारी आउटपुट फ़ाइल है, बिल्कुल जैसा कि हमने अपने डिफ़ॉल्ट params.greeting से उम्मीद की थी। + +तो यह बढ़िया है। अध्याय एक के बिल्कुल समान, जैसी उम्मीद थी वैसे काम कर रहा है। + +## 1. channel के माध्यम से स्पष्ट रूप से variable inputs प्रदान करें + +अध्याय एक में, आप वास्तव में पहले से ही channels का उपयोग कर रहे थे, आपको बस यह एहसास नहीं था। जब हमने यहां एक string निर्दिष्ट की, तो Nextflow ने स्वचालित रूप से हमारे लिए उस string के चारों ओर एक channel बना दिया, सिर्फ इसलिए क्योंकि यह जानता था कि हम एक process कॉल कर रहे थे, इसलिए हमें एक input channel की आवश्यकता थी। + +सबसे पहले हम जो करने जा रहे हैं वह यह है कि वास्तव में channel को स्वयं टाइप करके इसे स्पष्ट बनाएं। + +## 1.1. एक input channel बनाएं + +तो मैं स्क्रिप्ट के नीचे workflow में जाने वाला हूं, और मैं कहने वाला हूं greeting_ch। यह एक परंपरा है जिसका हम अक्सर Nextflow कोड में उपयोग करते हैं, जब यह एक channel हो तो variable नाम के अंत में अंडरस्कोर ch रखने की, बस ताकि यह पहचानना आसान हो कि यह एक channel है, लेकिन आपको ऐसा करने की आवश्यकता नहीं है। Channel.of Hello Channels के बराबर। + +हमने अभी जो उपयोग किया है उसे Nextflow भाषा में "Channel Factory" कहा जाता है। यह यहां यह चीज है, हम इस variable को एक नए channel पर सेट कर रहे हैं, और यहां यह channel factory हमारे लिए एक विशेष तरीके से एक channel बना रही है। + +Nextflow में कुछ अलग-अलग channel factories हैं, विभिन्न प्रकार के inputs से channels बनाने के लिए। Dot of सबसे सरल है, और बस हम जो भी strings देते हैं उसे लेता है। + +ध्यान दें कि जब मैं VS Code में इन शब्दों पर होवर करता हूं, तो Nextflow extension मुझे एक पॉपअप दे रहा है जो समझाता है कि यह syntax क्या करता है, और उस पॉपअप विंडो के नीचे एक और पढ़ें टेक्स्ट भी है। + +यदि मैं उस पर क्लिक करता हूं, तो यह Nextflow docs खोल देगा। एक नए टैब में और मुझे सीधे इस विशिष्ट चीज़ के लिए documentation पर ले जाएगा। इस मामले में channel.of के लिए। + +## 1.2. process कॉल में input के रूप में channel जोड़ें + +ध्यान दें कि extension हमें एक चेतावनी भी दे रहा है, कह रहा है कि हमने यहां एक नया channel बनाया है, लेकिन इसे किसी भी चीज़ द्वारा उपयोग नहीं किया जा रहा है। + +तो, चलिए इसे ठीक करते हैं। मैं नए channel का नाम लेने जा रहा हूं और मैं इस params.greeting को हमारे नए channel से बदलने जा रहा हूं। + +ध्यान दें कि हम अब command line flag --greeting का उपयोग नहीं कर रहे हैं, params.greeting का उपयोग नहीं किया जा रहा है, हम इस string को hard code करने के लिए वापस जा रहे हैं। कोई बात नहीं। मैं बस चीजों को सरल रखने की कोशिश कर रहा हूं। हम बाद में वापस आएंगे और फिर से params का उपयोग करेंगे। + +## 1.3. workflow कमांड फिर से चलाएं + +ठीक है, चलिए बस दोबारा जांच करते हैं कि यह काम करता है। terminal लाएं और फिर से ध्यान दें। Nextflow run hello channels. output.txt की जांच करें, और वहां यह है। + +बढ़िया थोड़ा उबाऊ उदाहरण, बिल्कुल वही करना जो हमने पहले किया था, लेकिन अब कम से कम तर्क थोड़ा स्पष्ट है। हम एक नए channel को लिखने के बारे में स्पष्ट हो रहे हैं। + +हमने वही काम करने के लिए प्रभावी रूप से अधिक कोड लिखा है। लेकिन यह तब समझ में आने लगेगा जब हम अपने channels को बनाने के तरीके में थोड़ा अधिक जटिल हो जाएंगे। + +## 2. कई input values पर चलाने के लिए workflow को संशोधित करें + +ठीक है, चलिए इसे थोड़ा और दिलचस्प बनाते हैं। यह बहुत दुर्लभ है कि आप एक ही input पर Nextflow pipeline चलाना चाहें, तो चलिए इसे कई inputs देते हैं। + +## 2.1. input channel में कई greetings लोड करें + +यहां docs से। मैं इन विभिन्न strings को कॉपी करने जा रहा हूं, उनमें से तीन। Hello, Bonjour, Olà. ओह, Hope प्राप्त करें। Copilot कुछ अन्य सुझाव दे रहा है। तो चलिए उन्हें tab enter करते हैं। + +यहां Nextflow docs हमें बताता है कि हम इस operator को कई values दे सकते हैं, इसलिए इसे काम करना चाहिए, लेकिन चलिए इसे आजमाते हैं और देखते हैं कि क्या होता है। + +## 2.1.2. कमांड चलाएं और log output देखें + +खैर। हां और नहीं। चलिए देखते हैं। यह कहता है कि पांच में से पांच कार्य यहां चल चुके हैं, लेकिन यह हमें केवल एक hash दिखाता है, जो थोड़ा अजीब है। कोई बात नहीं। सब कुछ उम्मीद के मुताबिक है। डिफ़ॉल्ट रूप से। Nextflow terminal पर आउटपुट के एक विशेष प्रकार का उपयोग करता है जिसे ANSI control codes कहा जाता है, जिसका मतलब है कि यह उन सभी विभिन्न processes का एक अच्छा संकुचित दृश्य देने के लिए कुछ पंक्तियों को अधिलेखित करता है जो चल रही हैं। + +यह तब बहुत अधिक समझ में आता है जब आपके पास बड़े workflows हैं और सैकड़ों या हजारों विभिन्न नमूने चला रहे हैं। आप terminal पर इतना आउटपुट उत्पन्न कर सकते हैं, इसे देखना असंभव है, जबकि यह अपडेट होने वाला दृश्य आपको वास्तविक समय की प्रगति देता है। + +## 2.1.3. -ansi-log false विकल्प के साथ कमांड फिर से चलाएं + +यदि आप चाहें, तो आप इसे फिर से चला सकते हैं, और इस बार मैं एक अतिरिक्त Nextflow core तर्क का उपयोग करने जा रहा हूं जिसमें एक hyphen है, "-ansi-log false"। यह Nextflow log आउटपुट के पिछले संस्करण का उपयोग करता है। और यहां आप सभी व्यक्तिगत processes देख सकते हैं जो लॉन्च की गई हैं। + +यह आप पर निर्भर है कि आप ऐसा करते हैं या नहीं। Nextflow से आउटपुट दोनों मामलों में बिल्कुल समान है। + +## 2.2. सुनिश्चित करें कि आउटपुट फ़ाइल के नाम अद्वितीय होंगे + +ठीक है, चलिए आउटपुट फ़ाइलों पर एक नज़र डालते हैं, फिर हम results पर जाएंगे। लेकिन केवल एक ही आउटपुट फ़ाइल है। क्या हुआ? हमने देखा कि process कई बार चली थी। हम work डायरेक्टरी में जा सकते हैं और सभी अलग-अलग hashes देख सकते हैं, सभी कार्य ठीक से निष्पादित किए गए थे। लेकिन यदि आपको याद है कि हमारे process में, हम सब कुछ एक output.txt फ़ाइल में सहेज रहे हैं और फिर उसे इस डायरेक्टरी में publish कर रहे हैं। + +तो एक ही फ़ाइल पांच बार बनाई गई, और फिर इसे पांच बार अधिलेखित किया गया। और हमारे पास वह है जो कोई भी कार्य अंतिम रूप से निष्पादित हुआ। + +## 2.2.1. एक dynamic आउटपुट फ़ाइल नाम बनाएं + +जिस तरह से हम इसे ठीक करते हैं वह एक dynamic आउटपुट फ़ाइल नाम का उपयोग करके है। यहां हमारे पास पहले से ही process के भीतर greeting नामक एक variable है, इसलिए हम उसे आउटपुट फ़ाइल नाम में उपयोग कर सकते हैं। मैं उसे कॉपी करता हूं और मैं $greeting-output.txt करता हूं। + +मैं इसे quotes में घेरने जा रहा हूं, बस ताकि bash किसी भी spaces से भ्रमित न हो जो यहां आ सकती हैं। और फिर मैं वही फ़ाइल नाम लेने जा रहा हूं और यहां आउटपुट को अपडेट करूंगा। + +यह वास्तव में महत्वपूर्ण है कि आउटपुट इससे मेल खाए, क्योंकि अन्यथा, यह फ़ाइल नहीं मिलेगी और Nextflow क्रैश हो जाएगा। + +मैं एक और वास्तव में महत्वपूर्ण संपादन करने जा रहा हूं, जो है कि मैं इन single quotes को double quotes में बदलने जा रहा हूं। ध्यान दें कि जब मैंने ऐसा किया तो कोड का रंग बदल गया। यह variable केवल तभी विस्तारित होता है जब हम double quotes का उपयोग करते हैं। यदि मैं यहां single quotes का उपयोग करता हूं, तो इसे एक literal value के रूप में उपयोग किया जाता है, और मुझे $greeting-output नामक एक ही फ़ाइल मिलेगी, जो मैं नहीं चाहता। + +## 2.2.2. workflow चलाएं + +तो चलिए double quotes वापस रखते हैं और इसे आजमाते हैं। + +मैं शुरू करने से पहले अपनी डायरेक्टरी को साफ करने जा रहा हूं, ताकि नई फ़ाइलों को देखना आसान हो। मैं .nextflow, work, और results नामक किसी भी चीज़ को हटाने जा रहा हूं। + +और मैं उस Nextflow कमांड को फिर से चलाने जा रहा हूं और देखते हैं कि कौन सी फ़ाइलें बनाई जाती हैं। तो यह वहां पांच processes चलाता है। यदि आप बहुत करीब से देख रहे थे, तो आपने देखा होगा कि वह line चलते समय अपडेट हो रही थी। + +और अब हम results डायरेक्टरी में जा सकते हैं, और निश्चित रूप से, हमारे पास पांच अलग-अलग आउटपुट हैं, और वे सभी विभिन्न greeting के साथ prefixed हैं। + +यदि मैं इनमें से प्रत्येक को खोलूं, तो हम देखेंगे कि उनमें से प्रत्येक में संबंधित greeting है। शानदार। यही हम चाहते हैं। + +## 3. channel की सामग्री को transform करने के लिए एक operator का उपयोग करें + +ठीक है, तो अब हम जानते हैं कि channels क्या हैं और हम जानते हैं कि channel factories क्या हैं। operators के बारे में क्या? यह Nextflow भाषा के एक हिस्से के लिए एक और शब्द है, जो functions की एक श्रृंखला है जो हमें channels पर संचालन करने की अनुमति देता है, उन पर कुछ चीजें करने के लिए। Nextflow, operators के एक suite के साथ आता है, जो हमें विभिन्न तरीकों से channels में हेरफेर करने की अनुमति देता है। + +## 3.1. channel में input के रूप में values का एक array प्रदान करें + +चलिए एक उदाहरण के साथ इसके माध्यम से काम करते हैं। मान लीजिए कि हम इन input strings को लेना चाहते हैं, लेकिन उन्हें सीधे channel factory में डालने के बजाय, हम उन्हें एक array के रूप में परिभाषित करना चाहते हैं। + +## 3.1.1. input variable सेट करें + +तो मैं इन्हें लेने जा रहा हूं और इसे ऊपर एक नई line के रूप में करूंगा और कहूंगा, greetings, array। + +वहां हम जाते हैं। मैं उस array variable को लेने जा रहा हूं और इसे channel.of में डालूंगा, और save करूंगा। + +## 3.1.3. workflow चलाएं + +अब, देखते हैं क्या होता है। मेरे terminal पर वापस जाएं। मैं बस उन सभी अस्थायी फ़ाइलों को फिर से साफ करने जा रहा हूं। और चलिए workflow चलाते हैं। + +अच्छा नहीं है। ठीक है। यह टूट गया। कोई बात नहीं। मुझे इस बार इसके टूटने की उम्मीद थी। जब कोई Nextflow workflow विफल हो जाता है तो क्या गलत होता है, इसे debug करना Nextflow developer होने का एक प्रमुख हिस्सा है। यह बहुत होगा और यह समझना महत्वपूर्ण है कि error message क्या कहता है और इससे कैसे निपटना है। + +Nextflow, error messages वास्तव में काफी संरचित हैं। यह हमें बताता है कि कौन सी process गलत हुई। यह हमें एक कारण के लिए एक error message देता है। यह कहता है कि उस विशेष कार्य के भीतर चलाने की कोशिश की गई कमांड क्या थी, exit status क्या थी, आउटपुट क्या था जहां वह कार्य work डायरेक्टरी थी। + +ध्यान दें कि मैं VS Code में इसे option, click कर सकता हूं और यह इसे एक साइडबार में खोलता है ताकि मैं सीधे वहां जा सकूं और इन सभी छिपी हुई फ़ाइलों को देख सकूं, जिनके बारे में हमने पिछले अध्याय में बात की थी, जिसमें .command.sh फ़ाइल भी शामिल है। यह आप देख सकते हैं कि वही है जो यहां निष्पादित की गई commands के समान है। + +इस फ़ाइल को देखकर, हम यह समझ सकते हैं कि यहां क्या गलत हुआ होगा, array में प्रत्येक तत्व के लिए एक ही कार्य चलाने के बजाय, पिछली बार जैसा किया था, इसने बस पूरे array को एक बार में string के रूप में प्रदान किया। इसलिए हमें channel में पास करने से पहले उस array को अलग-अलग values में unpack करने की आवश्यकता है। चलिए वापस जाते हैं और देखते हैं कि क्या हम एक operator का उपयोग करके ऐसा कर सकते हैं। + +## 3.2. channel की सामग्री को transform करने के लिए एक operator का उपयोग करें + +इस मामले में, हम array को channel में पास करने से पहले बदलने नहीं जा रहे हैं। हम channel को समायोजित करने जा रहे हैं ताकि यह उस तरह से व्यवहार करे जिसकी हम उम्मीद करते हैं। हम ऐसा flatten operator का उपयोग करके करने जा रहे हैं, dot टाइप करना शुरू कर सकते हैं और हम देख सकते हैं कि VS Code extension उन सभी विभिन्न operators का सुझाव देना शुरू कर देता है जो हमारे पास उपलब्ध हैं। + +## 3.2.1. flatten() operator जोड़ें + +और मैं flatten का चयन करने जा रहा हूं। ध्यान दें कि white space इस संदर्भ में Nextflow के लिए मायने नहीं रखता है। इसलिए यदि आप चाहें तो आप इन operators को एक नई line पर रख सकते हैं। इसलिए मैं इसे यहां नीचे छोड़ सकता हूं और इसे indent कर सकता हूं ताकि यह ".of" के नीचे बैठे और आप देखेंगे कि लोग अक्सर इस तरह के बहुत सारे operators को एक channel पर chain करते हैं और इसे इस तरह indent करते हैं ताकि यह पढ़ने में आसान हो। + +आप यह भी देख सकते हैं, पहले की तरह मैं इस पर hover कर सकता हूं और पढ़ सकता हूं कि flatten operator क्या कर रहा है, और यदि मैं चाहूं तो documentation के लिए एक link का पालन भी कर सकता हूं। + +तो यह operator इस channel को ले रहा है, जिसके भीतर एक एकल array है, और array values को अलग कर रहा है। + +## 3.2.2. channel की सामग्री का निरीक्षण करने के लिए view() जोड़ें + +हम विशेष view operator का उपयोग करके channels के अंदर झांक सकते हैं, और मैं उनमें से कुछ को यहां जोड़ने जा रहा हूं। यह अन्य भाषाओं में print statements का उपयोग करने जैसा है। इसलिए मैं dot view करने जा रहा हूं और फिर मैं इन squiggly brackets का उपयोग करूंगा। + +इसे closure कहा जाता है। यह मूल रूप से view operator को अतिरिक्त कोड देता है, जिसे यह channel के भीतर प्रत्येक item पर निष्पादित करेगा। इस मामले में, मैं कहने जा रहा हूं greeting before flatten। Greeting. + +मैं यहां एक variable परिभाषित कर रहा हूं, जो केवल इस closure के दायरे में है। तो यह variable केवल यहां उपयोग किया जाता है और मैं इसे जो भी चाहता था कह सकता था। यह वास्तव में मायने नहीं रखता। मैं बस इसे पढ़ने में आसान बनाने के लिए greeting का उपयोग कर रहा हूं। + +कुछ Nextflow pipelines में, आप लोगों को "$it" नामक एक विशेष implicit variable का उपयोग करते हुए देख सकते हैं। ऐसा। यह Nextflow कोड के भीतर एक विशेष variable है, जो एक shorthand है ताकि आपको variable की थोड़ी परिभाषा नहीं करनी पड़े। हालांकि, समय के साथ हम सोच रहे हैं, यह उन लोगों के लिए बहुत स्पष्ट नहीं है जो Nextflow में नए हैं, और हम अब "$it" के उपयोग को हतोत्साहित करते हैं। + +इसलिए मैं greeting के पिछले व्यवहार के साथ बने रहने जा रहा हूं और इसे इस तरह उपयोग करने जा रहा हूं क्योंकि यह अधिक स्पष्ट है और यह स्पष्ट है कि क्या हो रहा है। + +फिर मैं इस line को कॉपी करूंगा और flatten तर्कों के बाद बिल्कुल वही फिर से करूंगा। view operator थोड़ा विशेष है क्योंकि यह elements पर कुछ करता है, लेकिन यह उन्हें अगले operator को पास करना जारी रखता है ताकि हम इसे इस तरह के operations की chain के बीच में chain कर सकें, और यह वहां status प्रिंट करेगा और आगे बढ़ता रहेगा। तो उम्मीद है कि यह हमें दिखाएगा कि flatten operator से पहले और बाद में channel कैसा दिखता है। + +## 3.2.3. workflow चलाएं + +चलिए इसे आजमाते हैं। साफ़ करें। workspace में सब कुछ साफ़ करें। pipeline फिर से चलाएं। + +ठीक है, तो हम देख सकते हैं कि इसने हमारी पांच processes फिर से चलाई। फिर, यह एक error के साथ क्रैश नहीं हुआ, इसलिए यह निश्चित रूप से अच्छा है। और अब हमारे पास before flatten है और यह निश्चित है कि हमारे पास हमारा array है और हमारे पास after flatten है, पांच बार प्रिंट किया गया array के प्रत्येक तत्व के लिए एक बार। यही हम आशा कर रहे थे। तो यह वास्तव में अच्छी खबर है। और यह कोड से हम जो उम्मीद करते हैं उसके अनुरूप है। + +हमें अब इन debug statements की आवश्यकता नहीं है, इसलिए मैं या तो उन्हें comment कर सकता हूं या हटा सकता हूं। मैं अपने कोड को अच्छा और साफ रखने के लिए उन्हें हटाने जा रहा हूं। ठीक है, बढ़िया। यह उदाहरण अब अच्छी तरह से काम कर रहा है और हम देखना शुरू कर सकते हैं कि channels थोड़ी अधिक जटिल logic कैसे कर सकते हैं। + +## 4. CSV फ़ाइल से input values को parse करने के लिए एक operator का उपयोग करें + +अब हम इसके बजाय inputs की एक श्रृंखला के साथ एक फ़ाइल का उपयोग करके ऐसा करने की कोशिश करने जा रहे हैं। यह metadata के sample sheet या CSV का उपयोग करके Nextflow pipelines लिखने का एक बहुत ही सामान्य तरीका है। + +## 4.1. greetings के स्रोत के रूप में एक CSV फ़ाइल की अपेक्षा करने के लिए स्क्रिप्ट को संशोधित करें + +यदि मैं साइडबार पर जाता हूं, तो आप उदाहरण repository में greetings.csv देख सकते हैं, और यह एक बहुत ही, बहुत ही सरल CSV फ़ाइल है जिसमें तीन अलग-अलग greetings के साथ केवल तीन lines हैं। देखते हैं कि क्या हम इस CSV फ़ाइल का उपयोग अपने workflow के भीतर कर सकते हैं। + +अब मैं params का उपयोग करने के लिए वापस जा रहा हूं जैसा कि हमने अध्याय एक में किया था, ताकि हम एक command line input प्राप्त कर सकें। + +मैं इस greetings array को हटाने जा रहा हूं। + +## 4.1.1. CSV फ़ाइल को इंगित करने के लिए input पैरामीटर को स्विच करें + +मैं params greeting को फ़ाइल नाम पर सेट करने जा रहा हूं, जो greetings.csv है, और मैं channel उत्पन्न करने के लिए इस विशेष variable का उपयोग करने जा रहा हूं। मैं उसे वहां डालने जा रहा हूं, और errors चली जाती हैं। याद रखें कि यह अब इस variable को डिफ़ॉल्ट रूप से सेट कर रहा है। इसलिए यदि मैं किसी तर्क के बिना pipeline चलाता हूं, तो यह greetings.csv का उपयोग करेगा, लेकिन यदि मैं चाहूं तो इस variable को अधिलेखित करने के लिए मैं --greeting कर सकता था। + +## 4.1.2. एक फ़ाइल को संभालने के लिए डिज़ाइन किए गए channel factory पर स्विच करें + +ठीक है, हम अब एक string या strings के एक array के बजाय एक फ़ाइल पास कर रहे हैं, इसलिए हमें शायद एक अलग channel factory की आवश्यकता है। + +हम "of" से छुटकारा पाने जा रहे हैं जिसे हम अब तक उपयोग कर रहे हैं, और इसके बजाय .fromPath का उपयोग करें। यह बिल्कुल वही करता है जो यह लगता है। यह एक string फ़ाइल नाम या glob का उपयोग करके values के बजाय paths के साथ एक channel बनाता है। मैं flatten operator को भी हटाने जा रहा हूं क्योंकि अब हमें इसकी आवश्यकता नहीं है, अब जब हम एक फ़ाइल पास कर रहे हैं। + +## 4.1.3. workflow चलाएं + +मैं save करने जा रहा हूं, terminal खोलूंगा, workflow चलाऊंगा, और फिर देखूंगा कि क्या होता है। + +ठीक है। यह फिर से क्रैश हो गया। चिंता मत करो। मुझे इसकी भी उम्मीद थी। आइए error message पर एक नज़र डालें और देखें कि क्या हम यह पता लगा सकते हैं कि क्या गलत हो रहा है। यहां हम निष्पादित कमांड देख सकते हैं, और पहले की तरह थोड़ा जहां हमारे पास पूरा array प्रिंट था। अब हमारे पास फ़ाइल path है जिसे कमांड में echoed किया जा रहा है, फ़ाइल की सामग्री के माध्यम से जाने के बजाय। + +## 4.2. फ़ाइल को parse करने के लिए splitCsv() operator का उपयोग करें + +तो फ़ाइल की सामग्री का उपयोग करने के लिए, हमें एक और operator की आवश्यकता है। इसके लिए जो operator हम उपयोग करने जा रहे हैं उसे splitCsv कहा जाता है। समझ में आता है, क्योंकि यह एक CSV फ़ाइल है जिसे हम लोड कर रहे हैं। + +## 4.2.1. channel पर splitCsv() लागू करें + +ठीक है, तो splitCsv। Close bracket। हमें यहां किसी तर्क की आवश्यकता नहीं है। और फिर, मैं यह समझने के लिए कुछ view operators का उपयोग करने जा रहा हूं कि यहां क्या हो रहा है। + +.view csv after splitCsv। Before split Csv.s + +## 4.2.2. workflow फिर से चलाएं + +ठीक है, चलिए इसे चलाने और देखने की कोशिश करते हैं कि क्या होता है। + +ठीक है, इस बार हमें थोड़ा अधिक आउटपुट मिला है, लेकिन यह अभी भी विफल रहा। हम view statements को देख सकते हैं, और यहां आप before split CSV देख सकते हैं, और हमारे पास एक फ़ाइल path है जैसा कि हमने पिछले error message में देखा था। After split CSV, अब हमारे पास तीन values हैं जो CSV फ़ाइल में तीन lines के अनुरूप हैं। + +हालांकि, आप देख सकते हैं कि इनमें से प्रत्येक value square brackets से घिरी हुई है। तो उनमें से प्रत्येक अपने आप में एक array था, और इसने हमें वही area दिया है जो हमारे पास पहले था जहां यह एक ही string के बजाय एक array को echo करने की कोशिश कर रहा है। + +यदि हम एक CSV फ़ाइल के बारे में सोचते हैं, तो यह एक प्रकार से समझ में आता है। आमतौर पर, एक CSV फ़ाइल में rows और columns होंगे, इसलिए split CSV दो आयामी array करता है। array का पहला आयाम प्रत्येक row है, और फिर एक दूसरा आयाम है, जो प्रत्येक row के लिए प्रत्येक column है। + +तो यहां हमारे पास प्रत्येक line पर केवल एक ही value है, इसलिए हमारे पास एक ही column है, इसलिए हमारे पास फ़ाइल की प्रत्येक line के लिए एक one element array है। + +कोई बात नहीं। हमें बस parsed CSV फ़ाइल की प्रत्येक line के लिए उस array को collapse करने के लिए एक और operator की आवश्यकता है। चलिए इसे साफ करते हैं। terminal से छुटकारा पाएं और देखें कि हम क्या कर सकते हैं। + +## 4.3. greetings निकालने के लिए map() operator का उपयोग करें + +अब हम flatten operator का फिर से उपयोग कर सकते हैं, जिसे हमने पहले उपयोग किया था। हमने देखा है कि यह कैसे एक array को values की एक श्रृंखला में collapse कर सकता है, जो यहां बहुत अच्छी तरह से काम करेगा। लेकिन मैं map operator नामक एक और operator को प्रदर्शित करने के अवसर का उपयोग करने जा रहा हूं, जो workflows के भीतर बहुत आम है। + +## 4.3.1. channel पर map() लागू करें + +मैं dot map करने जा रहा हूं और मैं item item[0] करने जा रहा हूं। + +यदि आप अन्य कोड भाषाओं का बहुत सारा कोड लिखते हैं, तो आप map operator से पहले से ही परिचित हो सकते हैं। यह एक iterable, जैसे कि एक array या एक channel लेता है, और यह उसके प्रत्येक value पर कुछ operation करता है। + +यहां हम कह रहे हैं कि हमें इस closure के दायरे में item नामक एक variable को परिभाषित करना चाहिए, और फिर हम चाहते हैं कि बस, उस array में पहला value return करें। तो item index zero। + +यह प्रभावी रूप से array को flatten कर रहा है। आप देख सकते हैं कि हम इसे कैसे और अधिक जटिल होने के लिए बढ़ा सकते हैं, हालांकि: यदि हमारी CSV फ़ाइल में छह columns थे, लेकिन हम केवल चौथे column में रुचि रखते हैं, तो हम यहां एक विशिष्ट index तक पहुंच सकते हैं। या downstream processing को पास करने से पहले value पर किसी भी अन्य प्रकार का operation कर सकते हैं। + +तो map operator बेहद लचीला है और flight में channels को संशोधित करने के लिए बहुत शक्तिशाली है। आइए एक और view statement डालें बस ताकि हम देख सकें कि यह हमारे execution में क्या कर रहा है। उस line को adjudicate कर सकते हैं और इसे नीचे ले जा सकते हैं। और after map। + +## 4.3.2. workflow एक बार फिर चलाएं + +आइए terminal लाएं और workflow चलाने की कोशिश करें। + +ठीक है, इस बार कोई errors नहीं। यह एक अच्छा संकेत है। अब हम view statements से इन सभी विभिन्न आउटपुट के माध्यम से जा सकते हैं। Before split CSV, हमारे पास एक एकल path था। After split CSV, हमारे पास single value arrays थे, और फिर after map, हमारे पास बिना किसी array syntax के बस values हैं। चलिए results डायरेक्टरी में जाते हैं, और यहां हमारी आउटपुट फ़ाइलें बिल्कुल वैसे ही व्यवहार कर रही हैं जैसे हम चाहते थे। + +यहां थोड़ा बोनस है। आप वास्तव में देख सकते हैं कि view operators उस क्रम में थोड़े मिश्रित हैं जिसमें उन्होंने आउटपुट किया है। ऐसा इसलिए है क्योंकि Nextflow इन विभिन्न कार्यों के parallelization कर रहा है। तो इसने CSV को विभाजित करने के बाद, इस channel में तीन elements हैं, और यह उन तीन elements के processing को स्वचालित रूप से parallel में संभाल रहा है। इसका मतलब है कि आउटपुट का क्रम stochastic है और भिन्न हो सकता है। इस मामले में, ऐसा हुआ कि कुछ view operators बाद के चरण के पूरा होने के बाद return हुए, और इसलिए यह इस क्रम में आया। + +यदि मैं फिर से वही workflow चलाता हूं। तब निश्चित रूप से, यह एक अलग क्रम में आया है और इस बार हमें split CSVs और maps उस क्रम में मिले हैं जिसकी हम उम्मीद करते हैं। + +तो बस ध्यान रखें, आप एक process कार्य से आउटपुट के क्रम पर भरोसा नहीं कर सकते क्योंकि Nextflow आपके लिए स्वचालित रूप से इस parallelization को संभाल रहा है। Nextflow अपने data flow logic के साथ आपके लिए ऐसा करता है, और यही Nextflow की वास्तविक शक्ति है। + +ठीक है, यह शायद पूरे प्रशिक्षण के सबसे महत्वपूर्ण अध्यायों में से एक है। एक बार जब आप channels, channel factories और operators को समझ जाते हैं, तो आप Nextflow की ताकत और इसे एक प्रोग्रामिंग भाषा के रूप में अद्वितीय बनाने वाली चीज़ में प्रवेश करना शुरू कर देते हैं। यह functionality Nextflow को आपके लिए आपके सभी workflows को parallelize करने और एक बहुत ही स्वच्छ syntax और एक push data flow model के साथ अत्यंत जटिल workflow logic उत्पन्न करने की अनुमति देती है। यह पहली बार में थोड़ा अजीब concept हो सकता है, लेकिन एक बार जब आप इस तरह कोड लिखने के आदी हो जाते हैं, तो यह जल्दी से स्वाभाविक महसूस होगा और इससे पहले कि आप इसे जानें, आप शानदार workflows लिख रहे होंगे। + +ब्रेक लें, चाय का एक कप, घूमें और चलिए अध्याय तीन की ओर बढ़ते हैं, जहां हम इन अवधारणाओं को अधिक जटिल workflows में विस्तारित करना शुरू करते हैं। अगले वीडियो में मिलते हैं। + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/hi/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..93fbd2a43b --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# भाग 3: Hello Workflow - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [पाठ्यक्रम सामग्री](../03_hello_workflow.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए अनुभाग नंबर केवल संकेत के लिए प्रदान किए गए हैं और सामग्री में सभी अनुभाग नंबर शामिल नहीं हो सकते हैं। + +## स्वागत + +नमस्ते, "Hello Nextflow" प्रशिक्षण पाठ्यक्रम के भाग तीन में आपका स्वागत है। + +इस अध्याय को "Hello Workflow" कहा जाता है। + +अध्याय दो में, हमने एक process की एक सरल workflow बनाई थी, लेकिन वास्तविकता में, pipelines उपयोगी होती हैं क्योंकि वे विश्लेषण के कई चरणों को एक साथ जोड़ सकती हैं। + +इस अध्याय में, हम उस प्रारंभिक उदाहरण को लेने जा रहे हैं और इसे थोड़ा और यथार्थवादी बनाने के लिए विस्तारित करेंगे। + +हम कुछ अतिरिक्त चरण जोड़ने जा रहे हैं और हम देखेंगे कि उन चरणों को जोड़ने के लिए हम channels का उपयोग कैसे करते हैं। + +हम कई tasks को देखने जा रहे हैं, जो एक single process में समा सकते हैं और हम processes को देखने जा रहे हैं जिनमें कई inputs और कई outputs हो सकते हैं। + +ठीक है, चलिए शुरू करते हैं। + +तो चलिए शुरू करते हैं। पहले की तरह ही। चलिए training.nextflow.io पर जाते हैं। Hello Nextflow, अध्याय तीन। Hello Workflow। और चलिए अपना workspace खोलें। मैंने अपने पिछले अध्यायों से अपनी सभी work files को साफ कर दिया है और मैं Hello Workflow को खोलने जा रहा हूं। + +अब यह वही फ़ाइल है जिस पर हम अब तक काम कर रहे थे इसलिए यह परिचित लगनी चाहिए। हमारे पास हमारी say hello process है। हमारे पास हमारी params.greeting अपनी greetings CSV फ़ाइल के साथ है, और हमारे पास नीचे हमारी workflow है, जो उस CSV फ़ाइल को लोड करती है, channel बनाती है और इसे हमारी process में पास करती है। + +## 0. वार्म-अप: hello-workflow.nf चलाएं + +यदि आप चाहें, तो हम इसे आज़मा सकते हैं और दोबारा जांच सकते हैं कि यह हमारी उम्मीद के अनुसार काम कर रहा है। nextflow run hello workflow nf के लिए एक terminal लोड करें और enter पर क्लिक करें। + +ठीक है, बढ़िया। हमारी तीन processes रन हुईं। हमारे पास अपनी तीन outputs के साथ हमारी results डायरेक्टरी है। Bonjour. Hello. Holà. तो चलिए उन files को बंद करें, terminal को बंद करें, script पर वापस जाएं। + +## 1. workflow में दूसरा चरण जोड़ें + +ठीक है। हमारे उदाहरण के लिए, हम बुनियादी बने रहेंगे और हम domain agnostic रहने की कोशिश कर रहे हैं। तो हमारी दूसरी process बस इन strings, इन शब्दों को एक सरल तरीके से manipulate करने जा रही है। हम इन files को लेने और उन्हें सभी uppercase बनाने के लिए translate Unix कमांड का उपयोग करने जा रहे हैं। हम "tr" कमांड के साथ ऐसा करते हैं। + +## 1.1. uppercasing कमांड परिभाषित करें और इसे terminal में टेस्ट करें + +हम इसे बस bash terminal में आज़मा सकते हैं, और देख सकते हैं कि क्या यह काम करता है। तो आप echo करें, Hello World, और फिर इसे pipe character के साथ tr पर पास करें, और हम इसे एक recognition pattern देते हैं, a से z और इसे क्या translate करना चाहिए। A से Z uppercase में। + +यह बहुत सरल है क्योंकि यह शाब्दिक रूप से A से Z characters कर रहा है। तो यह किसी भी चीज़ पर काम नहीं करेगा जो accented है या ऐसा कुछ भी है। लेकिन उदाहरण के उद्देश्यों के लिए, आपको तस्वीर मिल जानी चाहिए। + +enter दबाने जा रहा हूं और यह terminal पर प्रिंट करता है, HELLO WORLD capitals में। और बस पहले की तरह, हम चाहें तो इसे एक फ़ाइल में redirect कर सकते हैं। Outfile. + +ठीक है। चलिए इसे साफ करें। + +## 1.1. uppercasing step को Nextflow process के रूप में लिखें + +चलिए अपनी script पर वापस जाएं और इस bash कमांड को handle करने के लिए एक नई process लिखें। मैं पिछली process को copy करने जा रहा हूं, इसे नीचे paste करूंगा, और इसे convert to upper कहूंगा। Uppercase के लिए। मैं वही publishDir results का उपयोग करने जा रहा हूं, लेकिन मैं यहां कुछ बदलाव करने जा रहा हूं। val लेने के बजाय, मैं एक path input फ़ाइल लेने जा रहा हूं, और मेरे पास यहां एक prefix upper होगा, ताकि हमारी output files आउटपुट को clobber न करें। और मैं input से variable name का उपयोग करने जा रहा हूं। और फिर मैं यहां नीचे एक script बदलने जा रहा हूं, और इसके बजाय मैं input फ़ाइल पर cat का उपयोग करने जा रहा हूं और जैसे हमने Bash TR में किया था, a-z, upper input file .txt। ठीक है, चलिए save पर क्लिक करें। + +## 1.2. workflow block में नई process को कॉल जोड़ें + +अब यदि मैं नीचे scroll करूं, तो हमें वास्तव में इस process को call करने की आवश्यकता है। बस script में process जोड़ना पर्याप्त नहीं है। हमें Nextflow को बताना होगा कि हमें इस process को चलाने की आवश्यकता है और इसे कहां करना है। + +तो मैं यहीं जा रहा हूं, convert to upper और + +ठीक है, हमें यहां एक error मिल रही है जो कहती है कि यह एक argument की उम्मीद करती है। निश्चित रूप से, हमें इस process को कुछ पास करने की आवश्यकता है ताकि इसके पास वास्तव में कुछ करने के लिए हो। + +## 1.3. पहली process के output को दूसरी process में पास करें + +हम जो करने जा रहे हैं वह है हम इस process से output लेने जा रहे हैं। तो मैं name लेता हूं, say hello, और जब मैं dot out करता हूं। + +इस तरह के एक सरल उदाहरण के लिए, जहां हमारे पास एक process है जिसमें बस एक output है और हम इसे एक नई process में पास कर रहे हैं, तो इसमें एक input है जो हमें चाहिए होना चाहिए। तो मैं save पर क्लिक करने जा रहा हूं, terminal लाऊंगा, और चलिए इसे फिर से चलाने की कोशिश करते हैं। + +## 1.4. workflow को फिर से चलाएं + +अब, मैंने पिछली बार जब मैंने यह workflow चलाई थी तब से अपनी work डायरेक्टरी को साफ नहीं किया है। मैं इसे फिर से चलाने जा रहा हूं और मैं इसे एक अवसर के रूप में उपयोग करने जा रहा हूं यह दिखाने के लिए कि partial caching कैसे काम करती है। तो यदि मैं single dash resume करता हूं। उम्मीद है कि यह उस पहली process से outputs का पुन: उपयोग करना चाहिए, जो पिछली बार मैंने चलाए के बिल्कुल समान थे। लेकिन अब हमारे पास यहां एक नई process है जो पहले नहीं चली है, जो scratch से चलती है। और निश्चित रूप से, आप देख सकते हैं कि पहली process ने cache outputs का उपयोग किया, और दूसरे output ने तीन में से तीन चलाए। आप यह भी देख सकते हैं कि हमारे पास अब अपनी दोनों processes हैं, हमारी पहली process, say hello, तीन बार चली, और हमारी दूसरी process convert to upper तीन बार चली। + +यदि मैं इसे फिर से चलाता हूं, एक reminder के रूप में, -ansi-log false के साथ, हमें देखना चाहिए कि छह अलग-अलग process tasks चलीं उनमें से प्रत्येक के लिए तीन। तो यह बिल्कुल वही कर रहा है जो हमने उम्मीद की थी। पहली process तीन बार चल रही है, उन outputs को दूसरी process पर पास कर रही है, जो फिर तीन बार चल रही है। + +तो चलिए work डायरेक्टरी के अंदर देखते हैं और देखते हैं कि Nextflow इन file inputs को कैसे handle कर रहा है। यदि मैं दूसरी process से इस hash डायरेक्टरी को यहां लेता हूं तो हम इन files को देखने के लिए फिर से -a के साथ tree कमांड का उपयोग कर सकते हैं। आप यहां देख सकते हैं कि हमारे पास हमारी input फ़ाइल है, जो Bonjour-output.txt फ़ाइल है, और वह वास्तव में एक symlink है। यही वह है जो यह arrow हमें दिखा रहा है, और यह पिछली work डायरेक्टरी में फ़ाइल की ओर इशारा कर रहा है। + +यह समझ में आता है। Nextflow अपनी स्वयं की encapsulated डायरेक्टरी में प्रत्येक कार्य के execution को handle करता है, इसलिए यह पूरी तरह से self enclosed है। हालांकि, इसे input के रूप में पिछले चरणों से files प्रदान करने की आवश्यकता है। उन files को प्राप्त करने के लिए work डायरेक्टरी के बाहर पहुंचने के बजाय, Nextflow उन्हें work डायरेक्टरी में stages करता है। + +यदि हमारे पास यहां जैसी shared file system है, तो यह एक symlink का उपयोग करके ऐसा करता है ताकि यह किसी अतिरिक्त file space का उपयोग न करे। यदि हम विभिन्न स्थानों में buckets के साथ cloud storage का उपयोग करते हैं, तो यह उन files को fetch करेगा और वास्तव में उन्हें work डायरेक्टरी में copy करेगा। + +चलिए command sh फ़ाइल पर एक नज़र डालते हैं। यदि मैं code work, command sh करता हूं, तो आप देख सकते हैं, निश्चित रूप से, यह local डायरेक्टरी से उस फ़ाइल तक पहुंच रहा है। तो सब कुछ बहुत self-contained और clean है। + +हम results डायरेक्टरी की भी जांच कर सकते हैं और सुनिश्चित कर सकते हैं कि ये files ठीक से output हुईं। और निश्चित रूप से, results में, हम पहली process से सभी output files और दूसरी से सभी output files देख सकते हैं। और वे सभी uppercase में हैं जैसा हमने उम्मीद की थी। + +यहीं पर Nextflow की शक्ति चमकने लगती है। कुछ बहुत न्यूनतम code के साथ और Nextflow ने इन tasks के parallel में execution को clean encapsulation के साथ अलग work directories के भीतर और input और output files की staging और file publishing सभी स्वचालित रूप से हमारे लिए बस out of the box में handle किया। तो आप देख सकते हैं कि जैसे-जैसे हम अपनी analysis workflows की जटिलता को scale करते हैं, यह functionality वास्तव में, वास्तव में मूल्यवान है। + +## 2. सभी greetings को collect करने के लिए तीसरा चरण जोड़ें + +ठीक है। ये steps one-to-one थे। हमारे पास पहली process से एक output था जो दूसरी process के लिए एक input में जा रहा था। इसके बाद, हम बात करने जा रहे हैं कि इन विभिन्न outputs को एक single process कार्य में कैसे collect किया जाए, जो फिर से, करने के लिए एक बहुत ही सामान्य बात है। तो चलिए जल्दी से terminal लाते हैं और इसका एक dry run करते हैं। + +## 2.1. collection कमांड परिभाषित करें और इसे terminal में टेस्ट करें + +मैं cheat करने जा रहा हूं और प्रशिक्षण सामग्री से example bash code को copy करूंगा और बस enter दबाऊंगा। + +हम यहां देख सकते हैं कि हमने इस echo कमांड को तीन अलग-अलग output files के लिए तीन बार चलाया, जिसे मैं यहां देख सकता हूं। और फिर इन तीन अलग-अलग files में से प्रत्येक के output को print करने के लिए cat कमांड का उपयोग किया, और उसे एक single collected फ़ाइल में redirect किया। + +और यदि मैं "cat COLLECTED-output" करता हूं, तो आप देख सकते हैं कि इसमें उन तीन अलग-अलग files की contents हैं, अब एक single फ़ाइल में। + +## 2.2. collection step करने के लिए एक नई process बनाएं + +तो चलिए देखते हैं कि क्या हम अपनी Nextflow pipeline के भीतर वही चीज़ replicate कर सकते हैं। + +चलिए ऊपर scroll करें और एक तीसरी process बनाएं। मैं इस पिछले वाले को copy करने जा रहा हूं, और इस बार मैं इसे Collect Greetings कहने जा रहा हूं। + +bash terminal में, हमने इसे collected output txt कहा था। तो मैं यहां same path output कहने जा रहा हूं। और मैं यहां redirection करने जा रहा हूं, इसलिए यह उसी तरह से save हो जाती है। + +ठीक है। हमें उस कमांड की शुरुआत में जो होता है उसे बदलने की आवश्यकता है, और हमें सोचना होगा कि यहां input फ़ाइल क्या है। वास्तव में, यह process कई input files लेने जा रही है। मैं path रखने जा रहा हूं और मैं इसे एक नए variable input files में बदलने जा रहा हूं, plural। + +फिर मैं फिर से, उन्हें cat करूंगा जैसे हमने अपनी bash script में किया था। और मैं यहां variable का उपयोग करने जा रहा हूं। + +अब, आप सोच सकते हैं कि यह काम नहीं करेगा। हमने पहले failures देखी हैं जहां strings की एक array या paths की एक array को एक process में पास किया गया था और इससे error हुई थी। लेकिन वास्तव में, यहां Nextflow इसे स्वचालित रूप से सही तरीके से हमारे लिए handle करने जा रहा है। यह कई अलग-अलग input files लेने जा रहा है, और यह बस यहां विभिन्न file paths को print करने जा रहा है। + +बेशक यह मदद करता है कि cat कमांड इस तरह file names की एक series ले सकती है। यदि मैं एक अलग कमांड का उपयोग कर रहा था जिसे प्रत्येक file path से पहले एक argument की आवश्यकता थी या कुछ और, तो हमें यहां थोड़ा और अधिक code और logic रखना होगा ताकि इन file paths की iteration को handle करने में सक्षम हो सकें। लेकिन इस मामले में, यह बस काम करना चाहिए। + +## 2.3. workflow में collection step जोड़ें + +ठीक है, चलिए workflow पर नीचे जाएं और अपनी नई process जोड़ें। Collect greetings। और फिर से, चलिए convert to upper out से output लेते हैं। चलिए इसे save करें। + +इसे एक try दें। nextflow run hello workflow. + +ठीक है, workflow चली, लेकिन कुछ अजीब है यहां। हमें पहले चरण के तीन executions मिले हैं, जिसकी हम उम्मीद करते हैं। दूसरे के लिए तीन tasks, लेकिन हमारे पास अंत में तीन tasks भी हैं जब हम यहां केवल एक single कार्य की उम्मीद करते थे जो सभी outputs को merge कर रहा था। + +यदि हम अपनी results डायरेक्टरी में जाते हैं। हम यह भी देखते हैं कि collected output में तीनों के बजाय केवल एक single value है। ऐसा इसलिए है क्योंकि वह output फ़ाइल तीन अलग-अलग values के साथ तीन बार overwrite की गई थी। + +यह समझ में आता है क्योंकि हमने यहां एक output को एक input में उसी तरह पास किया जैसे हमने पिछले चरण में किया था। + +## 2.4. greetings को एक single input में collect करने के लिए एक operator का उपयोग करें + +तो हमें यहां एक operator की आवश्यकता है जो इस channel को तीन elements के साथ लेगा और उन्हें एक single element में collapse करेगा, ताकि वह final process केवल एक बार चले। + +ऐसा करने के लिए, हम collect operator का उपयोग करने जा रहे हैं। मैं workflow के भीतर सीधे ऐसा कर सकता हूं। मैं .out कर सकता हूं और यहां अंत में एक operator पर chain कर सकता हूं .collect. + +save दबाएं। और फिर इस प्रशिक्षण के उद्देश्यों के लिए, मैं कुछ view operators भी करने जा रहा हूं जैसे हमने पहले किया था, ताकि हम collect operator का उपयोग करने से पहले और बाद में इस channel पर एक नज़र डाल सकें, ताकि हम समझ सकें कि क्या हो रहा है। + +मैं इस channel को लेने जा रहा हूं, collect से छुटकारा पाऊंगा और dot view greetings करूंगा, और फिर मैं इस line को duplicate करूंगा, collect operator जोड़ूंगा। और उसे after में बदलूंगा। + +यह अलग है जहां हम इसे call कर रहे हैं, लेकिन यह ठीक है क्योंकि हम same output channel पर same operator calls का उपयोग कर रहे हैं। + +ठीक है, चलिए save दबाएं और चलिए इसे terminal में आज़माएं। lgoing nextflow run करने जा रहा हूं। Hello, workflow। हमारी script फिर से चलाएं। + +ठीक है। यह बेहतर लग रहा है। पहले की तरह हम देख सकते हैं कि पहली दो processes तीन बार चलीं और अब हमारी final process केवल एक बार चली। + +यदि हम देखें कि view operator द्वारा क्या print किया गया था, यहां नीचे, हमने collect से पहले कहा, जो यहां यह output है, और वह तीन बार print हुआ है। और आप देख सकते हैं कि उनमें से प्रत्येक के लिए एक single path है। और फिर collect के बाद, आप देख सकते हैं कि हमारे पास तीन paths की यह array है। तो यह जैसी हमने उम्मीद की थी वैसी है। + +ठीक है, चलिए results फ़ाइल की जांच करें और देखें कि क्या यह इस बार हमारी उम्मीद के अनुसार है। निश्चित रूप से, अब फ़ाइल में तीन lines हैं - वह सफलतापूर्वक इन तीन outputs को एक single output फ़ाइल में concatenate कर दी। शानदार। + +ठीक है, मैं clean up करने जा रहा हूं और चलिए अगले चरण पर जाते हैं। और मैं इन view statements को हटाने जा रहा हूं बस चीजों को clean रखने के लिए। + +## 3. final output फ़ाइल को uniquely नाम देने के लिए एक process को एक से अधिक input पास करें + +ठीक है। अब तक, हमारी सभी processes ने केवल एक single input लिया है। अब हम एक अभ्यास करने जा रहे हैं जहां हम एक process में एक से अधिक input जोड़ते हैं यह देखने के लिए कि यह कैसे काम करता है। ऐसा करने के लिए, हम इस collect greetings example का उपयोग करने जा रहे हैं। + +हर बार जब मैंने workflow चलाई, तो यह results डायरेक्टरी में उस फ़ाइल को overwrite कर दी, जो शायद हम नहीं चाहते हैं। + +## 3.1. output फ़ाइल के लिए user-defined name स्वीकार करने के लिए collector process को संशोधित करें + +तो इस उदाहरण के लिए, हम एक अतिरिक्त पैरामीटर पास करने जा रहे हैं ताकि हम output फ़ाइल के name को customize कर सकें। + +एक process में दूसरा input जोड़ना बहुत सरल है। मैं बस input block में दूसरी line जोड़ता हूं। इस बार यह एक value होने जा रहा है, path के बजाय, क्योंकि हम एक string पास करना चाहते हैं और मैं इसे batch underscore name कहने जा रहा हूं। + +अब मैं इस variable का उपयोग script block में कर सकता हूं, और मैं collected dash dollar batch name कहने जा रहा हूं। + +मैं यहां variable name के आसपास squiggly brackets का उपयोग कर रहा हूं। यह बस इसे string के बाकी हिस्सों से अलग रखने के लिए है, और शायद इस मामले में इसकी आवश्यकता नहीं है, लेकिन मुझे लगता है कि यह इसे पढ़ना आसान बनाता है। + +ठीक है। अंत में, output path को update करना याद रखें क्योंकि अब फ़ाइल का name बदल गया है, तो मैं वही चीज़ करने जा रहा हूं और batch name को output of path में उम्मीद के अनुसार रखूंगा। + +## 3.2. batch command-line पैरामीटर जोड़ें + +अब हमें कहीं से एक batch name पास करने की आवश्यकता है, और मैं ऐसा करने के लिए एक दूसरा पैरामीटर बनाने जा रहा हूं ताकि हम इसे command line पर कर सकें जब हम workflow चलाएं। + +तो मैं params batch name करने जा रहा हूं, और by default, चलिए इसे test batch कहते हैं। अब मैं इस special parameters variable को नीचे उपयोग कर सकता हूं, जहां हम process को call करते हैं। + +और निश्चित रूप से VS Code हमें बता रहा है कि अब इस process के लिए पर्याप्त arguments नहीं हैं, और यह दूसरे input की उम्मीद करती है। + +बस comma करें और हमारे नए variable को पास करें और error चली जाती है। + +ध्यान दें कि यहां inputs का क्रम वास्तव में महत्वपूर्ण है। पहला process input path था, और दूसरा input name है। यदि मैं यहां क्रम बदलता हूं, तो मुझे भी क्रम बदलना होगा जब मैं process को call करूं। अन्यथा। इसके बाद, हम गलत input के लिए गलत channel पास करेंगे। + +## 3.3. workflow चलाएं + +ठीक है, चलिए इसे आज़माते हैं और देखते हैं कि क्या यह काम करता है। चलिए "nextflow run hello- workflow करते हैं। ठीक है, यह पहले की तरह चली। चलिए results डायरेक्टरी में देखते हैं। + +निश्चित रूप से, हमारी फ़ाइल का name अब "collected test batch output txt" है। शानदार। + +और अब देखते हैं कि क्या हम फिर से चलाकर उसे overwrite कर सकते हैं। इस बार मैं --batch_name करने जा रहा हूं ताकि यहां उस special parameter variable name से match हो। और मैं इसे demo output कहने जा रहा हूं। + +workflow को फिर से चलाएं और हम देखेंगे कि क्या कुछ होता है। + +ठीक है, अब हमारे पास एक collected demo output .txt है। और क्योंकि यह फ़ाइल का name उस एक से अलग है, इसने इसे overwrite नहीं किया है। दोनों अब results डायरेक्टरी में मौजूद हैं। + +## 4. collector step में एक output जोड़ें + +ठीक है, तो वहां हमने एक process को कई inputs देना दिखाया, लेकिन कई outputs के बारे में क्या? इस उदाहरण के लिए, हम greetings की संख्या की गणना करने जा रहे हैं जो processed हैं और इसे इस collect greeting step के लिए एक secondary output के रूप में output करें। + +## 4.1. greetings की संख्या को count और output करने के लिए process को संशोधित करें + +हम यहां थोड़ी trick करने जा रहे हैं। Nextflow processes में यह script block होता है एक multi-line string के साथ, और वह bash output के रूप में dot कमांड dot sh में पास किया जाता है। लेकिन हम वास्तव में उस से ऊपर कोई भी custom code लिख सकते हैं, और वह एक कार्य के हिस्से के रूप में execute होगा लेकिन bash script के भीतर शामिल नहीं होगा। + +Nextflow syntax में built-in functions में से एक को size कहा जाता है। तो मैं path input लेने जा रहा हूं, और मैं count underscore greetings कहने जा रहा हूं, बस एक variable name define करने के लिए। मैं input files लेने जा रहा हूं और मैं इस पर "size" call करने जा रहा हूं। + +यह function इस input channel के size को count करेगा और इसे एक variable को assign करेगा। + +अब हम उस variable को output block के हिस्से के रूप में return कर सकते हैं। तो हम कहते हैं, val, क्योंकि यह value है, फ़ाइल नहीं। और count greetings. + +अब यह अपने आप में पर्याप्त है, और हम अब इस process से इन विभिन्न outputs तक पहुंच सकते हैं। हालांकि, हमें उन्हें positional तरीके से access करना होगा। तो zero और one जैसी index key का उपयोग करके। + +outputs तक पहुंचना थोड़ा आसान बनाने के लिए, हम उन्हें नाम दे सकते हैं और हम एक emit statement का उपयोग करके ऐसा करते हैं। + +तो हम comma emit out file या जो कुछ भी मैं इसे call करना चाहता हूं करते हैं। और मैं यहां emit count करता हूं। यह मूल रूप से बस एक decorator है, जो हमें थोड़ा cleaner code लिखने में मदद करता है ताकि हम बाद में workflow block में specific outputs को आसानी से reference कर सकें। + +## 4.2. workflow के अंत में output की रिपोर्ट करें + +ठीक है। यदि मैं workflow block पर नीचे scroll करूं, तो अब मैं collect greetings के outputs ले सकता हूं, collect greetings, dot out कर सकता हूं, और हम देख सकते हैं कि हमारे दो named outputs यहां VS Code extension द्वारा सुझाए गए हैं। बहुत उपयोगी। + +तो मैं dot count करने जा रहा हूं जो हमने अभी बनाया count value प्राप्त करने के लिए, और मैं view करने जा रहा हूं, ताकि यह command line में print हो। ताकि हम इसे देख सकें जब हम workflow चलाएं। + +चलिए closure में यहां कुछ लिखते हैं बस इसे थोड़ा अच्छा बनाने के लिए। num greetings, there were greetings greetings. + +और हम वास्तव में दूसरे output के बारे में परवाह नहीं करते क्योंकि हम इसे किसी अन्य processes के लिए input के रूप में उपयोग नहीं कर रहे हैं। लेकिन आप देख सकते हैं कि यदि हम चाहें तो इसे एक और process के लिए input के रूप में आसानी से कैसे पास कर सकते हैं, downstream। + +## 4.3. workflow चलाएं + +हम save पर क्लिक करने जा रहे हैं। चलिए terminal पर एक नज़र डालते हैं और इसे आज़माते हैं। + +ठीक है, शानदार। यहां हम जाते हैं। तीन greetings हैं। यह बिल्कुल सही है। + +ठीक है, बढ़िया सामान। यह इस अध्याय का अंत है। अब तक बनाने के लिए हम सब पूरा कर चुके हैं। अब आप काफी realistic workflow बनाना शुरू कर रहे हैं, जहां हम अपनी workflow के भीतर inputs और outputs और logic को handle करने में सक्षम हैं। + +जैसे-जैसे ये workflow files लंबी होती जाती हैं, वे थोड़ी unwieldy होने लगती हैं। तो अगले अध्याय में, हम देखेंगे कि कैसे हम Nextflow code को अलग files में modularize कर सकते हैं ताकि workflow के भीतर code को ढूंढना और बनाए रखना आसान हो। + +अध्याय चार के लिए अगले वीडियो में हमारे साथ शामिल हों। Hello Modules. + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/hi/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..1ddb2914be --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# भाग 4: Hello Modules - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [पाठ्यक्रम सामग्री](../04_hello_modules.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए अनुभाग क्रमांक केवल संकेत के उद्देश्य से प्रदान किए गए हैं और सामग्री में सभी अनुभाग क्रमांक शामिल नहीं हो सकते हैं। + +## स्वागत + +नमस्ते, Hello Nextflow प्रशिक्षण पाठ्यक्रम के भाग चार में आपका स्वागत है। + +इस अध्याय को Hello Modules कहा जाता है, और हम Nextflow कोड को modularize करने के बारे में बात करेंगे। हम जो करने जा रहे हैं वह है अपनी एक workflow स्क्रिप्ट को लेकर उसे अलग-अलग फ़ाइलों में विभाजित करना। + +यह कोड को navigate और maintain करना आसान बनाता है जैसे-जैसे आपका workflow बड़ा होता जाता है, और pipelines के बीच modules को साझा करना भी संभव बनाता है ताकि यदि आपके पास एक ही टूल का उपयोग करने वाले कई pipelines हैं, तो आपको उस process को केवल एक बार लिखने की आवश्यकता हो। + +इसका एक क्लासिक उदाहरण nf-core modules रिपॉजिटरी है, जिसमें हजारों विभिन्न टूल्स ready to go modules में हैं, जिन्हें आप अपने workflow में install और उपयोग कर सकते हैं। + +Nextflow sub workflows के साथ भी काम कर सकता है, जो modules की तरह हैं, लेकिन उनमें कई processes होते हैं। यह इस प्रशिक्षण के दायरे से बाहर है, लेकिन यह मूल रूप से उसी तरह काम करता है। + +ठीक है। चलिए देखते हैं। + +हमेशा की तरह, training.nextflow.io पर जाकर शुरू करें। + +साइडबार में "Hello Nextflow" पर जाएं, और हम भाग चार कर रहे हैं: "Hello Modules"। + +मैं अब अपने GitHub Code Spaces वातावरण में जाऊंगा और "hello-modules" फ़ाइल को देखूंगा। + +पहले की तरह, हम पिछले अध्याय के अंतिम बिंदु से शुरू कर रहे हैं, इसलिए यह स्क्रिप्ट परिचित होनी चाहिए। हमारे पास तीन processes हैं, say hello, convert to upper और collect greetings, और एक सरल workflow में, जो इन तीन commands को चलाता है और अंत में एक message emit करता है। हमारे पास greeting और batch नामक दो parameters हैं, जो नाम निर्दिष्ट करता है, जिसका उपयोग अंत में collected आउटपुट फ़ाइल के लिए किया जाता है। + +## 0. Warmup: hello-modules.nf रन करें + +हम यह सत्यापित कर सकते हैं कि यह workflow अभी भी हमारी अपेक्षा के अनुसार काम करता है nextflow run hello, modules करके। + +बढ़िया। इसने इस process के साथ तीन कार्य रन किए, एक collected कार्य, और यह हमें बताया कि इस batch में तीन greetings हैं। अगर हम results में जाते हैं, तो हमारे पास यहां हमारी विभिन्न आउटपुट फ़ाइलें हैं, जिसमें collected test, batch आउटपुट भी शामिल है। + +## 1. modules संग्रहीत करने के लिए एक डायरेक्टरी बनाएं + +ठीक है। चलिए कुछ modularization करते हैं। + +आम तौर पर अपनी pipeline रिपॉजिटरी में modules को एक subfolder में रखना एक अच्छा विचार है, सिर्फ चीजों को व्यवस्थित रखने के लिए। आप इसे जो चाहें कह सकते हैं, लेकिन परंपरागत रूप से हम इसे modules कहते हैं। + +तो चलिए आगे बढ़ते हैं, एक टर्मिनल में जाएं और make the modules करें। आप इसे VS Code में साइडबार में पॉप अप होते देख सकते हैं। + +## 2. sayHello() के लिए एक module बनाएं + +मैं फिर अपने पहले module के लिए एक नई फ़ाइल बनाने जा रहा हूं। आप "touch" या "code" कर सकते हैं या आप इसे साइडबार में कर सकते हैं, वास्तव में कोई फर्क नहीं पड़ता। तो मैं code modules करने जा रहा हूं और मैं इसे process के नाम पर रखूंगा। तो sayHello.nf। NF, Nextflow फ़ाइलों के लिए एक पारंपरिक फ़ाइल एक्सटेंशन है। + +यहां save दबाने जा रहा हूं और हम अपनी नई module फ़ाइल को दिखाई देते देख सकते हैं। + +## 2.2. sayHello process कोड को module फ़ाइल में ले जाएं + +ठीक है, अगला मैं workflow से module कोड लेने जा रहा हूं। मैं यहां hash bang भी लेने जा रहा हूं और पहले उसे कॉपी करूंगा ताकि यह स्पष्ट रूप से एक Nextflow फ़ाइल हो। और फिर मैं इस process को लेने जा रहा हूं और मैं cut करूंगा। तो मैं इसे अपनी मुख्य workflow स्क्रिप्ट से हटा दूंगा और मैं इसे इस नए module में paste करूंगा। + +बस इतनी ही सामग्री इस module फ़ाइल में होगी। सिर्फ एक single process, कोई workflow नहीं, कोई logic नहीं, सिर्फ अकेली process। + +मैं अब इस फ़ाइल को बंद कर सकता हूं। + +## 2.3. workflow ब्लॉक से पहले एक import घोषणा जोड़ें + +अब मेरे workflow में वह पहली process गायब है, इसलिए हमें इसे import करके वापस लाने की आवश्यकता है। इसके लिए syntax अन्य प्रोग्रामिंग भाषाओं के समान है, इसलिए यह परिचित लग सकता है। हम include घुंघराले ब्रैकेट्स करते हैं, process का नाम, say hello, और फिर फ़ाइल पथ modules से, say hello, nf। शानदार। + +यहां कुछ tricks हैं। VS Code एक्सटेंशन इस बारे में चतुर है। यह इस फ़ाइल पथ को पहचानता है और आप इस पर hover कर सकते हैं और follow link कर सकते हैं। या मैं Mac पर हूं, मैं option click कर सकता हूं और यह इस फ़ाइल को खोलता है। इसलिए हम जल्दी से इस पर जा सकते हैं। + +यह process नाम अब यहां नीचे workflow द्वारा उपयोग किया जा रहा है, और हम यहां भी वही काम कर सकते हैं। यह हमें उस process के बारे में थोड़ी जानकारी दिखाता है, और फिर से, मैं option hold कर सकता हूं, इस पर click कर सकता हूं, और यह इसे editor में खोल देगा। + +तो यह VS Code में आपके विभिन्न processes के लिए जब आपके पास बहुत सारी फ़ाइलें हों तो अपने code base में जल्दी से navigate करने का वास्तव में तेज तरीका है। + +ठीक है। इस अध्याय के लिए मूल रूप से बस इतना ही। अब हम बाकी processes के लिए फिर से वही काम करते हैं। + +## 3. convertToUpper() process को modularize करें + +तो चलिए यहां एक नई फ़ाइल बनाते हैं। इसे Convert to upper nf कहें। फिर से, hash bang कॉपी करें। और फिर process को cut करें। + +वहां process का नाम कॉपी करें, नए process नाम के साथ एक नया include statement शामिल करें। + +## 4. collectGreetings() process को modularize करें + +और फिर तीसरी process के लिए भी वही करें। नई फ़ाइल, connect। Greetings, + +hash bang करें। Process को cut करें, process को paste करें, और एक नया include statement करें। + +अब आप यहां देख सकते हैं कि मुझे यहां एक error underline मिली है जो invalid include source कह रही है। और यह वास्तव में एक वास्तविक error है जो मैंने की क्योंकि मैं बहुत तेजी से आगे बढ़ रहा था। अगर आप ध्यान से देखें, तो आप देख सकते हैं कि मैंने T miss किया और convert to upper में + +तो VS Code ने बहुत उपयोगी रूप से मुझे बताया है कि मैंने वहां गलती की है। अगर मैं उस फ़ाइल का नाम ठीक करता हूं, तो error दूर हो जाती है। यह एक अच्छा उदाहरण है कि Nextflow कोड लिखने के लिए VS Code के भीतर error checking इतना उपयोगी क्यों है। अन्यथा मैंने इसे नहीं पकड़ा होता और मुझे बहुत बाद में पता चलता जब मैं workflow को चलाने की कोशिश करता। + +हमारी मुख्य pipeline स्क्रिप्ट अब बहुत सरल दिख रही है। इसमें कोई processes नहीं हैं, हमारे पास सिर्फ तीन include statements और हमारा workflow है। हमने workflow के logic में कोई बदलाव नहीं किया है। हमने process कोड में कोई बदलाव नहीं किया है, इसलिए उम्मीद है कि यह बिल्कुल उसी तरह काम करना चाहिए। + +## 4.4. सत्यापित करने के लिए workflow चलाएं कि यह पहले की तरह ही काम करता है + +चलिए जांच करते हैं। मैं एक टर्मिनल खोलने जा रहा हूं और मैं पहले की तरह बिल्कुल वही कमांड चलाने जा रहा हूं। + +निश्चित रूप से, इसने हमारी processes चलाई है, say hello, convert to upper collect greetings, और हमें फिर से तीन greetings दी हैं। + +तो हमने अपने कोड को इधर-उधर किया है, लेकिन हमने workflow के execute होने के तरीके के बारे में कुछ भी नहीं बदला है और यह पूरी तरह से अपरिवर्तित है। केवल अंतर यह है कि अब हमारे पास cleaner कोड है, maintain करना आसान है, और दूसरों के साथ साझा करना आसान है। + +और बस इतना ही। यह एक छोटा अध्याय था। यह एक सरल अवधारणा है, लेकिन यह बहुत शक्तिशाली है और अधिक जटिल Nextflow workflows लिखने के तरीके की कुंजी है। इसलिए यह महत्वपूर्ण है कि आप इसे समझें और इसका उपयोग करने की आदत डालें। + +अगले अध्याय में, हम गति में थोड़ा बदलाव करने जा रहे हैं और Nextflow कोड लिखने के syntax के बारे में इतना सोचना बंद करेंगे, और processes में खुद software का उपयोग कैसे करें इसके बारे में थोड़ा सोचेंगे। भाग पांच के लिए हमसे जुड़ें Hello Containers में। + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/hi/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..82d60e7003 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# भाग 5: हैलो कंटेनर्स - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स सामग्री](../05_hello_containers.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए सेक्शन नंबर केवल संकेत के उद्देश्य से दिए गए हैं और हो सकता है कि सामग्री में सभी सेक्शन नंबर शामिल न हों। + +## स्वागत + +नमस्कार, Hello Nextflow प्रशिक्षण कोर्स के भाग पाँच में आपका स्वागत है। + +इस अध्याय का नाम है Hello Containers। हम बात करने वाले हैं कि कैसे Nextflow, Docker और Singularity जैसे टूल्स के साथ एकीकृत होता है ताकि software containers का उपयोग करके आपकी pipeline के उपयोगकर्ताओं को software प्रदान किया जा सके। + +इसका मतलब है कि जब लोग आपकी pipeline चलाते हैं, तो उन्हें सभी अलग-अलग टूल्स खुद इंस्टॉल करने की आवश्यकता नहीं होती। Nextflow उनके लिए यह कर देगा। + +कंटेनर्स एक बेहद शक्तिशाली तकनीक हैं और reproducibility और उपयोग में आसानी के लिए महत्वपूर्ण हैं। हम कंटेनर्स का एक संक्षिप्त परिचय देकर शुरुआत करेंगे, कुछ docker कमांड मैन्युअली रन करेंगे, और फिर हम उन्हीं कंटेनर्स को अपनी Nextflow pipeline में डालेंगे। + +ठीक है। चलिए शुरू करते हैं। + +तो पहले की तरह, आइए प्रशिक्षण सामग्री को लोड करके शुरुआत करें। training.nextflow.io पर जाएं। Hello Nextflow, अध्याय पाँच, Hello Containers। + +मैं अपने Codespaces वातावरण में जाने वाला हूँ और यहाँ बाईं ओर हम hello containers dot nf देखते हैं। + +पहले की तरह, यह वही स्क्रिप्ट है जो हमने पिछले अध्याय चार में समाप्त की थी, इसलिए यह परिचित दिखनी चाहिए। + +हमारे पास इनपुट फ़ाइल और batch name निर्दिष्ट करने के लिए हमारे command line पैरामीटर हैं। हम अपने तीन मॉड्यूल्स को include कर रहे हैं, और हमारे पास हमारा workflow है जहाँ हम तीन processes चलाते हैं। + +## 0. वार्मअप: hello-containers.nf चलाएं + +बेझिझक इस workflow को फिर से चलाएं और दोबारा जांचें कि यह वे आउटपुट उत्पन्न कर रहा है जिनकी आप अपेक्षा करते हैं। अभी के लिए, मैं वास्तव में इसे बंद करने वाला हूँ और टर्मिनल में जाने वाला हूँ। + +## 1. 'मैन्युअली' एक कंटेनर का उपयोग करें + +इस अध्याय की शुरुआत करने के लिए, हम container तकनीक पर थोड़ा recap करने जा रहे हैं। यदि आप docker या singularity या अन्य container तकनीकों के बहुत आदी हैं, तो इसे एक refresher के रूप में लें, या बेझिझक इसे पूरी तरह से छोड़ दें। + +Nextflow कई अलग-अलग प्रकार की container तकनीकों का समर्थन करता है। इसमें Docker, Singularity, Podman, Shifter, Charliecloud और अधिक शामिल हैं। + +इस प्रशिक्षण में, हम Docker पर ध्यान केंद्रित करने जा रहे हैं। यह code spaces में पहले से इंस्टॉल होता है और सबसे लोकप्रिय container तकनीकों में से एक है, खासकर यदि आप अपने खुद के कंप्यूटर या अपने खुद के लैपटॉप पर विकास कर रहे हैं। + +यदि आप किसी शैक्षणिक वातावरण में shared HPC पर काम कर रहे हैं, तो आपको पता चल सकता है कि Singularity उपलब्ध है और Docker नहीं। यह ठीक है। सभी अवधारणाएं बिल्कुल समान हैं। कुछ मैन्युअल कमांड अलग हैं, लेकिन यदि आप Docker को समझते हैं, तो आप singularity को भी समझेंगे। + +वास्तव में, Singularity भी Code Spaces वातावरण में इंस्टॉल है। इसलिए यदि आप चाहें, तो आप Docker के बजाय Singularity का उपयोग करके समान कार्य करने का प्रयास कर सकते हैं। + +ठीक है, तो container तकनीक क्या है? Docker के पीछे का विचार यह है कि यह एक remote स्रोत से एक image fetch कर सकता है। इसे अपनी local मशीन पर pull कर सकता है और फिर उस image के आधार पर एक कंटेनर बना सकता है। + +यह चलने वाला कंटेनर आपके कंप्यूटर पर चलने वाली virtual machine की तरह थोड़ा है। यह आपके वातावरण से अलग है, और यह एक operating system और उपलब्ध software के एक सेट के साथ पहले से पैकेज होता है। + +## 1.1. कंटेनर image को pull करें + +हमें एक पहले से मौजूद image fetch करने के लिए जिस syntax की आवश्यकता है वह है "docker pull"। इसलिए मैं इसे अपने टर्मिनल में टाइप करने जा रहा हूँ, लेकिन अब हमें खेलने के लिए एक image की आवश्यकता है। + +आप खुद images बना सकते हैं। आप उन्हें Docker Hub या quay.io जैसी public registries पर पा सकते हैं। लेकिन images जल्दी प्राप्त करने का एक बहुत अच्छा तरीका है Seqera Containers का उपयोग करना। + +यह एक मुफ्त community service है जिसे हमने 2024 में बनाया है, जिसका उपयोग आप बिना login या कुछ भी किए कर सकते हैं। + +यदि आप seqera.io/containers पर जाते हैं या यहाँ शीर्ष पर containers पर क्लिक करते हैं, तो आपको एक search interface मिलता है और आप Conda या Python Package Index पर उपलब्ध किसी भी टूल का नाम टाइप कर सकते हैं। + +डिफ़ॉल्ट रूप से, यह Bioconda और Conda Forge channels को खोजता है, लेकिन यदि आप चाहें तो किसी भी Conda channel को prefix कर सकते हैं। + +थोड़ी मज़े के लिए, आइए cowpy का उपयोग करें। मैं cowpy टाइप करने जा रहा हूँ। यह मुझे Python Package Index और Conda Forge से परिणाम देता है। मैं इसे अपने कंटेनर में जोड़ने के लिए उस पर क्लिक करने जा रहा हूँ। यदि मैं चाहता तो यहाँ कई packages जोड़ सकता था। Docker चुनें, linux/amd64 चुनें, और Get Container पर क्लिक करें। + +यह मांग पर मेरे लिए image बनाता है यदि यह पहले से नहीं बनाई गई है, और मुझे एक URL देता है जिसे मैं कॉपी कर सकता हूँ। + +यदि आप रुचि रखते हैं, तो आप view Build Details पर क्लिक कर सकते हैं, और यह आपको एक पेज पर ले जाता है, जो conda environment फ़ाइल दिखाता है जिसका उपयोग किया गया था और build के लिए पूर्ण build log, security scan परिणामों के साथ। + +यदि मैं अपने code spaces पर वापस जाता हूँ, तो मैं अब इस container name को paste कर सकता हूँ और enter दबा सकता हूँ। + +Docker अब इस container image के भीतर सभी विभिन्न layers को डाउनलोड करता है, और अब हमें बताता है कि यह image उपयोग करने के लिए उपलब्ध है। + +## एक Singularity image को pull करना + +यदि आप singularity का उपयोग कर रहे हैं, तो प्रक्रिया मूल रूप से समान है। हम अपने image packages चुनते हैं, cowpy चुनते हैं। अब हम Docker के बजाय Singularity चुनते हैं और Get Container पर क्लिक करते हैं। यह हमें oras:// का उपयोग करके एक image URL देता है। या यदि आप पसंद करते हैं, तो आप उस box को check करके https:// का उपयोग कर सकते हैं। उस URL को कॉपी करें। अब Code Spaces पर जाएं। हमारे पास वास्तव में इस space में Apptainer इंस्टॉल है, जो Singularity के समान है, लेकिन वे एक दूसरे के लिए aliased हैं। इसलिए मैं apptainer pull करने जा रहा हूँ और फिर मैं इसे cowpy sif कहने जा रहा हूँ, लेकिन आप इसे जो चाहें कह सकते हैं। URL paste करें। और यह मेरे लिए उस image को डाउनलोड करने जा रहा है। + +मैं ls -lh कर सकता था और cowpy.sif देख सकता था + +Singularity, Docker से अलग है, कि singularity सभी images को flat files में store करता है, जबकि Docker की एक registry होती है जहाँ यह आपकी host मशीन पर सभी layers को अलग-अलग रखता है, और इन सब पर नज़र रखने के लिए उसके पास एक चलता हुआ demon है। + +## 1.2. एक one-off कमांड के रूप में cowpy चलाने के लिए कंटेनर का उपयोग करें + +ठीक है, चलिए Docker पर वापस जाएं। अब हम इस image को चलाने की कोशिश कर सकते हैं जिसे हमने docker run करके बनाया है। + +मैं dash dash rm करने जा रहा हूँ, जो केवल image का one-off execution करता है। और मैं image URL paste करने जा रहा हूँ। और फिर अंत में, आप इसे एक कमांड के साथ समाप्त करते हैं जिसे आप चलाना चाहते हैं। + +हमने जो image generate की थी उसमें cowpy इंस्टॉल था, तो चलिए cowpy को try करते हैं। + +वहाँ। इसने हमारी कमांड चलाई। मेरे पास locally cowpy इंस्टॉल नहीं है। आप देख सकते हैं कि अगर मैं इसे चलाने की कोशिश करता हूँ, तो यह मौजूद नहीं है। हालाँकि, इस कमांड में, मैंने इसे Docker का उपयोग करके चलाया और इसने सही तरीके से यह आउटपुट generate किया। + +## 1.3. cowpy को interactively चलाने के लिए कंटेनर का उपयोग करें + +हम चाहें तो इससे आगे जा सकते हैं और interactively एक कंटेनर spin up कर सकते हैं और अंदर देख सकते हैं। फिर से, मैं "docker run dash dash rm" करता हूँ। अब मैं dash it करने जा रहा हूँ, जो Docker को बताता है कि हम एक interactive terminal चाहते हैं। मैं फिर से image URL करता हूँ, और इस बार, cowpy करने के बजाय, मैं bin bash करने जा रहा हूँ क्योंकि जो कमांड हम चलाना चाहते हैं वह bash है। + +यह हमें इस चल रहे कंटेनर में ले जाता है और आप देख सकते हैं कि prompt अब बदल गया है। + +यदि मैं LS slash करता हूँ तो आप देख सकते हैं कि यहाँ की डायरेक्टरीज अलग हैं। + +यदि मैं यहाँ दाईं ओर एक दूसरा टर्मिनल खोलता हूँ, जो केवल GitHub Code Spaces में चल रहा है और LS slash करता हूँ, तो आप देखते हैं कि हमारे पास workspaces और temp जैसी डायरेक्टरीज हैं, जबकि यहाँ Docker में यह अलग है। + +तो यह वातावरण Docker के भीतर पूरी तरह से अलग है और मेरे host वातावरण से अलग है। यह एक अच्छी बात है, क्योंकि यह इस कमांड के execution को Docker image में isolate करता है और इसे विभिन्न host systems पर विभिन्न लोगों के बीच reproducible बनाए रखता है। + +यदि आप Docker image के भीतर अपने host system से data का उपयोग करना चाहते हैं, तो आपको कंटेनर में स्पष्ट रूप से उसे mount करना होगा। + +हम एक सेकंड में ऐसा करने जा रहे हैं। + +## 1.3.2. वांछित टूल कमांड(s) चलाएं + +हालांकि पहले, आइए देखें कि क्या हम cowpy चला सकते हैं। वहाँ फिर से, कमांड अब सीधे command line पर उपलब्ध है, और हम अधिक जटिल चीजें करना और arguments pass करना शुरू कर सकते हैं। Hello containers और cow के बजाय, चलिए tux penguin करते हैं। आइए देखें हमारे पास और क्या है। + +चलिए cheese करते हैं। शानदार। Dragon और Cow कैसा रहेगा? बहुत अच्छा। + +## 1.3.3. कंटेनर से बाहर निकलें + +ठीक है। मैं ज्यादा नहीं कर सकता क्योंकि मेरे पास इस कंटेनर में कोई data नहीं है। तो चलिए इस चल रही image से बाहर निकलें और देखें कि क्या हम कंटेनर में कुछ data mount कर सकते हैं। मैं control D करके या exit टाइप करके ऐसा कर सकता हूँ। ठीक है, मैं अब अपने regular GitHub code space में वापस आ गया हूँ। + +## 1.3.4. कंटेनर में data mount करें + +Docker कंटेनर में कुछ data mount करने के लिए, मुझे dash V का उपयोग करना होगा। तो मैं अपनी पिछली docker कमांड लेने जा रहा हूँ, शुरुआत में वापस जाऊंगा और dash v करूंगा। मैं वर्तमान local working डायरेक्टरी के लिए "." करने जा रहा हूँ, और फिर एक colon यह कहने के लिए कि host डायरेक्टरी में इसे कहाँ mount किया जाना चाहिए और slash data करूंगा। तो यह इस विशेष डायरेक्टरी को slash data पर कंटेनर में mount कर रहा है। + +अब यदि मैं LS slash करता हूँ तो हम देख सकते हैं कि हमारे पास data नाम की एक नई डायरेक्टरी है, और यदि मैं LS data करता हूँ, तो आप सभी फ़ाइलें देख सकते हैं जो हमारे पास यहाँ sidebar में हैं। शानदार। + +## 1.3.5. mounted data का उपयोग करें + +अब हम host system पर मौजूद कुछ फ़ाइलों का उपयोग Docker image के भीतर करना शुरू कर सकते हैं। तो मैं कह सकता हूँ cat data greetings csv। यदि आपको याद है, यह पहले से हमारे विभिन्न greetings के साथ हमारी CSV फ़ाइल है, और मैं इसे cowpy में pipe कर सकता हूँ। शानदार। अब हम कहीं पहुँच रहे हैं। + +ठीक है। Docker को interactively चलाने के लिए यह काफी है। उम्मीद है कि अब आपको मोटे तौर पर Docker क्या है और इसे one-off तरीके से कमांड चलाने और interactively एक image का उपयोग करने दोनों के लिए कैसे उपयोग करना है, इसका अंदाजा हो गया है। यदि आप singularity का उपयोग कर रहे हैं। सभी कमांड बहुत समान हैं सिवाय इसके कि आप apptainer exec या apptainer run, या singularity exec या singularity run जैसी चीजें करते हैं। + +## 2. Nextflow में कंटेनर्स का उपयोग करें + +आगे हम अपने Nextflow workflow में वापस जाने वाले हैं और देखने वाले हैं कि Nextflow pipeline के भीतर इस तकनीक का उपयोग कैसे करें। + +चलिए टर्मिनल बंद करें और Hello Containers को फिर से खोलें। + +## 2.1. एक cowpy मॉड्यूल लिखें + +अपने cowpy उदाहरण के साथ बने रहने के लिए, चलिए अपने workflow में एक नया process बनाएं, जो cowpy का उपयोग करता है। चलिए modules पर जाएं, एक नई फ़ाइल बनाएं और इसे cowpy nf कहें। मैं अब थोड़ा धोखा देने वाला हूँ और प्रशिक्षण सामग्री से code को कॉपी करने जा रहा हूँ और save दबाऊंगा। और चलिए एक नज़र डालते हैं। + +तो यह एक सरल process है। उम्मीद है कि अब आप समझ गए हैं कि एक process के building blocks कैसे दिखते हैं। हमारा publishDir फिर से है, results में जा रहा है। हमारे पास दो inputs हैं, एक input फ़ाइल और character नाम की एक string। हमारे पास एक आउटपुट cowpy input फ़ाइल है, और हमारे पास एक script है जो बिल्कुल वैसी ही दिखती है जैसी हमने एक सेकंड पहले अपनी docker image के अंदर मैन्युअली चलाई थी: एक फ़ाइल को print करने के लिए cat, इसे cowpy पर pipe करना, यह बताना कि हम किस प्रकार का cowpy character उपयोग करना चाहते हैं, और उसे output फ़ाइल में आउटपुट करना, जिसे हम यहाँ आउटपुट के रूप में pass करते हैं। + +## 2.2. workflow में cowpy जोड़ें + +ठीक है, चलिए अपने workflow में वापस जाएं, इस नए process को import करें। तो cowpy, modules cowpy nf से। चलिए एक नया पैरामीटर बनाएं ताकि हम निर्दिष्ट कर सकें कि हम कौन सा character चाहते थे। चलिए डिफ़ॉल्ट रूप से Turkey कहें। और फिर चलिए workflow के अंत में इस नए process को call करें, + +cowpy। और चलिए यहाँ Collect Greetings के आउटपुट का उपयोग करें। तो collect greetings out, यहाँ out file। और फिर हमें एक दूसरे argument की आवश्यकता है, जो हमने अभी बनाया नया params है। params dot character। + +## 2.2.4. यह सत्यापित करने के लिए workflow चलाएं कि यह काम करता है + +ठीक है, आइए देखें कि हमारा नया process काम करता है या नहीं। Nextflow run hello containers। इसे उन पहली तीन processes को चलाना चाहिए और फिर अंत में cowpy चलाने की कोशिश करनी चाहिए। + +हमें एक error मिली है। यहाँ जो कह रहा है, cowpy में एक error थी और इसमें exit status 127 था और निश्चित रूप से, कमांड sh cowpy command not found। + +हमने Nextflow को नहीं बताया कि हमारे पास cowpy के लिए एक Docker image उपलब्ध है, इसलिए इसने इसे हमारे host system पर चलाने की कोशिश की और हमारे host system पर cowpy इंस्टॉल नहीं है, इसलिए इसने एक error ट्रिगर की। + +## 2.3. इसे चलाने के लिए एक कंटेनर का उपयोग करें + +तो हमें जो करना है वह यह है कि हमें Nextflow को बताना है कि हमारे पास एक कंटेनर उपलब्ध है। चलिए अपने cowpy process में जाएं और हम process के शीर्ष पर container नामक एक नया निर्देश जोड़ने जा रहे हैं। + +फिर हम अपनी image ढूंढते हैं, URL कॉपी करते हैं, और उसे एक string में डालते हैं। + +यह अपने आप में पर्याप्त नहीं है क्योंकि एक X Flow pipeline में software निर्दिष्ट करने के कई तरीके हो सकते हैं। मैं conda conda-forge cowpy भी कर सकता था, उदाहरण के लिए। और Nextflow को यह जानना होगा कि आप इनमें से कौन सी तकनीक का उपयोग करना चाहते हैं। + +## 2.3.2. nextflow.config फ़ाइल के माध्यम से Docker के उपयोग को सक्षम करें + +इसलिए Docker सक्षम के साथ चलाने के लिए, हम खुद से थोड़ा आगे जाने वाले हैं और Nextflow config फ़ाइल का उपयोग करने जा रहे हैं, जो कुछ ऐसा है जिसे हम अगले अध्याय में अधिक विस्तार से कवर करने जा रहे हैं। आप इस डायरेक्टरी में देख सकते हैं कि हमारे पास Nextflow Config नाम की एक फ़ाइल है, और यहाँ आपके पास पहले से docker.enabled False है। + +हम इसे True में बदलने जा रहे हैं ताकि Docker सक्षम हो, और फिर हम workflow को फिर से चलाने की कोशिश कर सकते हैं। + +## 2.3.3. Docker सक्षम के साथ workflow चलाएं + +Nextflow run hello containers nf और इस बार cowpy सफलतापूर्वक चली। चलिए Results में देखें। cowpy collected test और वहाँ हमारा Turkey है। शानदार। + +तो पृष्ठभूमि में वहाँ, Nextflow जानता था कि उसके पास उस process के लिए एक कंटेनर उपलब्ध है। + +इसने image को fetch किया और इसने हमारे लिए कमांड्स चलाईं। + +## 2.3.4. निरीक्षण करें कि Nextflow ने containerized कार्य को कैसे launch किया + +यदि आप उत्सुक हैं, तो हम वास्तव में देख सकते हैं कि इसने वास्तव में क्या किया work डायरेक्टरी में देखकर। यदि मैं code work करता हूँ, और फिर hash और फिर command run, जो यदि आपको याद है तो वह actual फ़ाइल है जो उस कार्य के लिए execute की जाती है, हम अंदर जा सकते हैं और हम NXF launch नामक एक function की तलाश कर सकते हैं। और यहाँ आप exact docker कमांड देख सकते हैं जिसका Nextflow ने उपयोग किया, जो बहुत कुछ उस तरह दिखता है जो हम पहले टर्मिनल में मैन्युअली कर रहे थे। Docker run। इस host डायरेक्टरी को कंटेनर में bind करना, और फिर container URL निर्दिष्ट करना। + +तो यहाँ कोई जादू नहीं है। यह सिर्फ इतना है कि Nextflow स्वचालित रूप से आपके लिए भारी उठाने का काम कर रहा है इस तरह से कि आप आसानी से अपनी pipeline में कंटेनर्स निर्दिष्ट कर सकते हैं, जो फिर किसी और के लिए उपयोग करने के लिए आसानी से उपलब्ध हैं जो आपके workflow को चलाता है। और उन लोगों को अब आपकी analysis pipeline चलाने के लिए software प्रबंधित करने के बारे में सोचने की आवश्यकता नहीं है। + +बहुत, बहुत सरल, बहुत सुविधाजनक, और वास्तव में reproducible भी। चारों ओर अच्छा। + +ठीक है, बहुत अच्छा काम। यह अध्याय पाँच का अंत है। अगले वीडियो में हमसे जुड़ें भाग छह के लिए, जो इस Hello Nextflow प्रशिक्षण का अंतिम भाग है, जहाँ हम Nextflow configuration के बारे में अधिक विस्तार से बात करेंगे। + +अगले वीडियो में मिलते हैं। + +[अगला वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/hi/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..55c8ebda5e --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# भाग 6: Hello Config - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट्स" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स सामग्री](../06_hello_config.md) पर वापस जाएं। + + ट्रांसक्रिप्ट में दिखाए गए सेक्शन नंबर केवल संकेत के उद्देश्य से प्रदान किए गए हैं और सामग्री में सभी सेक्शन नंबर शामिल नहीं हो सकते हैं। + +## स्वागत + +नमस्ते, Hello Nextflow प्रशिक्षण कोर्स के भाग छह में आपका स्वागत है। + +इस अध्याय को Hello Config कहा जाता है, और यह हमारे प्रशिक्षण कोर्स का अंतिम भाग है। + +इस अध्याय में, हम Nextflow configuration के बारे में बात करने जा रहे हैं। Nextflow configuration वास्तव में शक्तिशाली है। यह हमें एक ही pipeline को कई विभिन्न compute infrastructures पर विभिन्न software provisioning के साथ चलाने की अनुमति देता है। और pipeline में विभिन्न options के साथ। + +इसका मतलब है कि आप अन्य लोगों द्वारा बनाए गए Nextflow pipelines ले सकते हैं और उन्हें अपने system पर चला सकते हैं, भले ही वे पूरी तरह से अलग infrastructure के लिए बनाए गए हों। Nextflow को configure करने की यह क्षमता workflows को वास्तव में portable और shareable बनाती है। + +इस अध्याय में, हम पिछले भागों में बनाए गए workflow का उपयोग करेंगे, लेकिन हम workflow code को बिल्कुल भी edit नहीं करेंगे। हम सिर्फ अपनी Nextflow config फ़ाइल को देखेंगे और देखेंगे कि config बदलने से Nextflow के चलने का तरीका कैसे बदलता है। + +ठीक है, चलिए शुरू करते हैं। + +पहले की तरह, चलिए training.nextflow.io पर जाकर शुरू करते हैं। बाईं ओर Hello Nextflow और अध्याय छह पर जाएं। Hello config। अब मैं अपने GitHub code Spaces environment में जा रहा हूं और उस script को दोबारा जांचूंगा जिसका हम उपयोग करेंगे। + +## 0. Warmup: जांचें कि Docker सक्षम है और Hello Config workflow चलाएं + +इसे Hello Config कहा जाता है, और यह वहीं से शुरू हो रहा है जहां हम पहले थे। तो हमारे तीन parameters के साथ बिल्कुल वैसा ही दिख रहा है। CSV फ़ाइल के लिए Greetings, आउटपुट batch name के लिए batch और cowpy name के लिए character। हमारे पास विभिन्न processes के चार imports हैं, और फिर हमारे पास एक workflow है जहां हम उन्हें एक साथ chain करते हैं। + +मैं वास्तव में अब इस फ़ाइल को बंद करने जा रहा हूं क्योंकि हम इस अध्याय में Nextflow फ़ाइल को बिल्कुल भी touch नहीं करेंगे। हम पूरी तरह से configuration फ़ाइल के भीतर काम करेंगे। अगर मैं Nextflow dot config फ़ाइल में देखूं जिसे हमने पिछले अध्याय पांच में संक्षेप में देखा था, तो हम देख सकते हैं कि यहां हमारे पास एक single statement है: Docker enabled equals true, जो Nextflow को बता रहा है कि इस workflow को execute करते समय Docker का उपयोग करें। + +मैं यहां pipeline root में Nextflow dot config का उपयोग कर रहा हूं, जो मेरे Nextflow चलाने पर automatically load हो जाता है। लेकिन याद रखें, Nextflow कई जगहों से config फ़ाइलें load कर सकता है। + +अगर मैं Nextflow docs के साथ जांच करूं और Configuration पर जाऊं, तो आप इन जगहों की एक list और एक priority देख सकते हैं जिसमें वे load होते हैं। + +ठीक है। चलिए जांचते हैं कि हमारा workflow हमारी अपेक्षा के अनुसार execute हो रहा है। एक terminal खोलें। Nextflow करें। Run। Hello, config। और enter दबाएं। हमारे पास वे चार processes चल रही होनी चाहिए, एक cowpy कमांड के साथ समाप्त होनी चाहिए। निश्चित रूप से, यह ठीक से काम किया। Docker enabled था, Docker को pull किया और मेरे लिए cowpy चलाया, बिल्कुल वैसे ही जैसे अध्याय पांच के अंत में किया था। + +## 1. निर्धारित करें कि किस software packaging technology का उपयोग करना है + +ठीक है। मान लीजिए मैं एक HPC पर चल रहा हूं और मेरे पास Docker installed नहीं है। इस परिदृश्य में करने के लिए सबसे अच्छी बात Singularity या Apptainer का उपयोग करना होगी। अगर मैं ऐसा करने जा रहा था, तो मैं module cowpy में जाऊंगा और इस container को singularity image का उपयोग करने के लिए बदलूंगा जैसा कि मैंने पिछले अध्याय में दिखाया था, एक oras:// के साथ, जो आप Seqera Containers से भी प्राप्त कर सकते हैं। + +फिर मैं Nextflow dot config में जाकर Docker enabled को false पर सेट करूंगा और singularity enabled equals true करूंगा। या, अगर Apptainer का उपयोग कर रहे हैं, तो apptainer enabled equals true और यह काम करेगा। + +Nextflow, यह containers के अलावा अन्य technologies को भी support करता है, जिससे आप परिचित हो सकते हैं वह है conda। यहां हम conda enabled equals true कर सकते हैं और Docker को false पर सेट कर सकते हैं। conda वही container directive का उपयोग नहीं करता है। इसके बजाय, हम यहां एक नया जोड़ सकते हैं जिसे conda कहा जाता है। फिर हम उस conda package को specify करते हैं जिसका हम उपयोग करना चाहते हैं। pipeline को यथासंभव reproducible बनाने की कोशिश करने के लिए जितना संभव हो उतना specific होना अच्छा अभ्यास है। तो मैं conda channel, conda-forge, और फिर cowpy, और exact version को specify करने जा रहा हूं, जो 1.1.5 था। + +मैं सिर्फ cowpy भी लिख सकता था अगर मैं चाहता, लेकिन यह pipeline के विभिन्न executions पर cowpy के एक अलग version में resolve हो सकता है। + +इसके बारे में अच्छी बात यह है कि मैंने docker directive को बिल्कुल भी touch नहीं किया है। यह Docker image अभी भी वहां है। मैं अब सिर्फ दो alternatives प्रदान कर रहा हूं, और इन्हें केवल एक config फ़ाइल का उपयोग करके on या off किया जा सकता है। + +## 1.3. यह verify करने के लिए workflow चलाएं कि यह Conda का उपयोग कर सकता है + +Conda अब enabled है, तो चलिए इसे आज़माते हैं। + +बढ़िया। यह चल रहा है और आप देख सकते हैं कि यहां Nextflow से एक message है जो कह रहा है कि Nextflow मेरे लिए एक conda environment बना रहा है, और यह इस cache location का उपयोग कर रहा है। + +Background में, Nextflow मेरे लिए "conda create" कमांड चला रहा है ताकि सिर्फ उन packages के साथ एक नया isolated conda environment बना सके जो मुझे चाहिए, और फिर उन conda packages को install और fetch कर रहा है ताकि यह process चला सके। + +आप देख सकते हैं कि वहां थोड़ा समय लगा क्योंकि यह पहली बार environment बना रहा था और software install कर रहा था। हालांकि, इसने इस environment को cache किया है, इसलिए अगर मैं फिर से वही Nextflow कमांड चलाता हूं, तो यह बहुत जल्दी होना चाहिए क्योंकि यह उसी conda environment का पुन: उपयोग करेगा। + +इसके बारे में अच्छी बातों में से एक यह है कि इन directives को process level पर specify किया जा सकता है, न कि सिर्फ पूरे workflow के लिए। इसलिए यदि आप चाहें, तो आप विभिन्न processes के लिए किस technology का उपयोग किया जाता है, इसे mix और match कर सकते हैं। + +## 2. Process directives के साथ compute resources आवंटित करें + +Nextflow configuration फ़ाइल सिर्फ software packaging से कहीं अधिक कर सकती है। हम Nextflow को यह भी बता सकते हैं कि वास्तव में pipeline में steps को कैसे चलाना है। एक उदाहरण host system को बताना है कि प्रत्येक executing task के लिए कौन से resources उपलब्ध कराए जाने चाहिए। + +By default, Nextflow बहुत ज्यादा नहीं देता है। यह प्रत्येक process को एक single CPU और केवल दो gigabytes की memory देता है। + +यह शायद कुछ ऐसा है जिसे हम बदलना चाहेंगे, ताकि जो processes चलने में लंबा समय लेती हैं वे अधिक resources प्राप्त कर सकें और अधिक तेज़ी से चल सकें, लेकिन यह जानना मुश्किल हो सकता है कि एक process को क्या allocate करना है। Nextflow के पास इसमें आपकी मदद करने के लिए कुछ अच्छी tricks हैं। + +## 2.1. Resource utilization report generate करने के लिए workflow चलाएं + +चलिए फिर से workflow चलाते हैं। इस बार, मैं एक अतिरिक्त argument जोड़ने जा रहा हूं, जो है dash with reports। यह एक core Nextflow option है, इसलिए यह एक single hyphen है। और फिर जो भी फ़ाइल name मुझे पसंद है। इस मामले में, मैं इसे report config one html कहने जा रहा हूं। + +मैं फिर से workflow चलाने जा रहा हूं। यह बिल्कुल पहले की तरह चलने वाला है, लेकिन यह मुझे एक अतिरिक्त helper report देगा, जो आप देख सकते हैं कि अब sidebar में pop up हो गया है। + +मैं इस फ़ाइल पर right click करने जा रहा हूं, download पर click करूंगा, जो इसे GitHub code Spaces से मेरे local system में download करता है, ताकि मैं आसानी से इसे यहां web browser में देख सकूं। + +यह report किसी भी Nextflow run के लिए generate किया जा सकता है, और इसमें बहुत सारी information होती है। यह top पर कुछ metadata के साथ शुरू होता है कि कौन सी कमांड उपयोग की गई थी, workflow कब चला, इसमें कितना समय लगा, लेकिन जैसे-जैसे आप नीचे scroll करते हैं, हमें resources के बारे में अधिक detailed information मिलती है, जो pipeline में प्रत्येक step द्वारा उपयोग किए गए थे। + +क्योंकि प्रत्येक process विभिन्न tasks के लिए कई बार चलता है। हमारे पास एक box plot है जो प्रत्येक process के लिए उपयोग किए गए resources की variation दिखा रहा है। + +अगर मैं थोड़ा और नीचे scroll करूं, तो मुझे memory used और job duration के बारे में समान information दिखाई देती है। साथ ही disk read write। + +आप कल्पना कर सकते हैं कि long running tasks के साथ एक बड़े pipeline के लिए, यह resources के configuration को fine tune करने के बारे में बहुत informative हो सकता है जो आप request कर रहे हैं ताकि आप over request न करें, बल्कि इतना प्रदान कर सकें कि यह जल्दी चले। + +अगर मैं report को नीचे scroll करता रहूं, तो हम एक task table भी देखते हैं, जो हमें workflow में चलाए गए हर एक task के बारे में detailed information दिखाता है। इसमें resolved script जैसी information शामिल है, जो चलाई गई थी। + +ठीक है, चलिए अपनी config फ़ाइल पर वापस जाते हैं। हमने देखा कि हमें वास्तव में अपने workflow के लिए बहुत ज्यादा की आवश्यकता नहीं है, तो चलिए Nextflow को बताते हैं कि हमें workflow में प्रत्येक process के लिए केवल एक gigabyte की memory की आवश्यकता है। + +अब जब हम इसे इस तरह process level पर define करते हैं, तो यह pipeline में प्रत्येक single process पर apply होता है। + +## 2.3. एक individual process के लिए resource allocations सेट करें + +तर्क के लिए, चलिए मान लेते हैं कि cowpy वास्तव में बहुत heavy lifting कर रहा है और इसे अन्य tasks की तुलना में अधिक resources की आवश्यकता है। हम यहां config का एक extra block define कर सकते हैं, जो सिर्फ उस process पर apply होता है, with name cowpy का उपयोग करके। + +इसे config selector कहा जाता है, और हम यहां विभिन्न processes को match करने के लिए अलग-अलग patterns define कर सकते हैं। उदाहरण के लिए, मैं cow star कर सकता हूं। फिर मैं उसके बाद कुछ curly brackets डालता हूं और चलिए इसे एक के बजाय दो gigabytes की memory दें और चलिए कहें दो CPUs। + +अब Nextflow workflow में प्रत्येक process को एक gigabyte दे रहा होगा इस request के अलावा, जो अधिक specific है। तो यह इसे override कर देता है। और सिर्फ किसी भी processes के लिए जिन्हें cowpy कहा जाता है, दो gigs की memory और दो CPUs मिलेंगे। + +ध्यान दें कि Nextflow resource utilization के बारे में clever है। इसलिए यदि आप इन संख्याओं को उच्च values पर रखना शुरू करते हैं, तो आप देखेंगे कि Nextflow job submissions को एक के बाद एक queue करना शुरू कर देता है, बजाय उन सभी को parallel में चलाने के, ताकि यह उपलब्ध resources को over request न करे। + +## 2.4. Modified configuration के साथ workflow चलाएं + +चलिए फिर से workflow चलाने की कोशिश करते हैं और चलिए इस बार एक नई report save करें। + +ठीक है, हम इस फ़ाइल को download कर सकते हैं और एक नज़र डाल सकते हैं। + +हां, आश्चर्यजनक रूप से नहीं, यह मूल रूप से बिल्कुल वैसा ही दिखता है क्योंकि यह एक dummy workflow है, जो कुछ भी real नहीं कर रहा है। लेकिन आप कल्पना कर सकते हैं कि इस तरह के reporting के साथ limits को define करने और real life workflows करने का यह iterative approach आपको appropriate configuration सेट करने के लिए एक evidence-based approach करने की अनुमति कैसे देता है और वास्तव में आपके लिए उपलब्ध computational resources का अधिकतम लाभ उठाता है। + +आप इसके बारे में वास्तव में clever होना शुरू कर सकते हैं। Nextflow में failures को retry करने की built-in क्षमता है, और आप अपनी config फ़ाइल में इस तरह एक closure का उपयोग करके और dynamically उपलब्ध resources को सेट करके इसका लाभ उठा सकते हैं। तो यहां मैंने Nextflow को उस दो gigabyte को retry attempt से multiply करने के लिए कहा है। तो दूसरी retry को चार gigs मिलेंगे, तीसरी retry को छह gigs मिलेंगे और इसी तरह। यह इस प्रशिक्षण कोर्स के दायरे से थोड़ा बाहर है, लेकिन अगर आप रुचि रखते हैं, तो Nextflow docs को check करें, जिसमें dynamic retry logic के बारे में एक अच्छा section है। + +## 2.5. Resource limits जोड़ें + +अब, एक चीज जो आपको इसके बारे में पता चल सकती है वह यह है कि इस तरह की चीज़ से गलती से आपके system पर उपलब्ध resources से परे जाना काफी आसान हो सकता है। यदि आप उपलब्ध resources से अधिक resources की request करते हैं तो Nextflow आपके configuration के बारे में एक error throw करेगा और run को halt कर देगा। इससे बचने के लिए, आप resource limits नामक किसी चीज़ का उपयोग कर सकते हैं। + +हमारे workflow में process scope के तहत, हम इस तरह resource limits define कर सकते हैं, जो एक array लेता है, और हम इस system पर उपलब्ध maximum memory CPUs और time specify कर सकते हैं। + +यहां high values सेट करना उन resources की मात्रा को नहीं बढ़ाता है जिनकी request की जाती है। हम अभी भी अपनी requests में एक gigabyte का उपयोग करने जा रहे हैं, लेकिन इसका मतलब है कि यदि इनमें से कोई भी request 750 तक पहुंच जाती है, तो वे उस ceiling से टकराएंगी और उससे अधिक कुछ भी request नहीं किया जाएगा, जिसका अर्थ है कि Nextflow चलना जारी रखेगा और unavailable resources के कारण crash नहीं करेगा। + +तो यह उपयोग करने के लिए एक अच्छा safeguard है, खासकर यदि आप अपने resource allocation के साथ dynamic logic का उपयोग कर रहे हैं। + +दूसरी स्थिति जहां यह वास्तव में उपयोगी है वह यह है कि यदि आप public pipelines का उपयोग कर रहे हैं जो आपके द्वारा नियंत्रित नहीं हैं। वे configuration defaults के साथ आ सकते हैं, और Nextflow automatically आपके system पर चलाने के लिए किसी भी resource requests को thresholding करने का सही approach लेगा। + +ठीक है, बढ़िया। हमने software के बारे में बात की है। हमने resource allocation के बारे में बात की है, और हमने सभी processes और specific processes दोनों के लिए config के विभिन्न scopes का वर्णन किया है। + +## 3. Workflow parameters store करने के लिए एक parameter फ़ाइल का उपयोग करें + +ठीक है, अब हम अपना ध्यान parameters की ओर मोड़ने जा रहे हैं। हम config फ़ाइल में parameters को define कर सकते हैं जैसा कि हमने पहले Nextflow script में किया था। तो params dot greeting equals hello या params scope का उपयोग करें और foo equals bar सेट करें। + +और यह आपके workflow के लिए defaults सेट करने के लिए बहुत अच्छा है। हालांकि, जब आप pipelines चला रहे हैं, तो JSON या YAML फ़ाइल में parameters specify करना अच्छा हो सकता है। + +इस तरह की फ़ाइल का उपयोग करना dash dash के साथ command line options specify करने से बेहतर है। जब आप एक workflow चलाते हैं, तो आपको कई parameters specify करने पड़ सकते हैं और उन सभी को एक single CLI पर लिखना tedious और error prone हो सकता है। साथ ही, यह संभावना नहीं है कि आप उन सभी parameters को याद रखेंगे जिनका आपने उपयोग किया था, इसलिए यदि आप उसे एक फ़ाइल में code करते हैं, तो भविष्य में समान parameters का उपयोग करके workflow को फिर से launch करना आसान है। + +हमारे पास यहां test params नामक एक example फ़ाइल है और आप देख सकते हैं कि यह हमारे workflow में तीन अलग-अलग values के साथ तीन parameters specify करती है। व्यक्तिगत रूप से, मुझे YAML को JSON की तुलना में लिखना आसान लगता है। तो सिर्फ यह demonstrate करने के लिए कि यह काम करता है, मैं Test yaml नामक एक नई फ़ाइल बनाने जा रहा हूं और इन्हें copy करूंगा, quotes से छुटकारा पाऊंगा। और save दबाऊंगा। + +ये JSON और YAML फ़ाइलें लिखने में आसान हो सकती हैं क्योंकि ये अधिक परिचित syntax हैं। लेकिन ध्यान दें कि ये केवल parameters के लिए हैं और वे केवल इस तरह key value syntax लेते हैं। + +## 3.1. Parameter फ़ाइल का उपयोग करके workflow चलाएं + +चलिए इसे आज़माते हैं। पहले जैसी ही कमांड करें। report से छुटकारा पाएं और मैं dash params file test params yaml करने जा रहा हूं। + +नहीं, यह एक core Nextflow option है, इसलिए यह एक single hyphen है। + +ठीक है। इसने workflow चलाया और इसने उस YAML फ़ाइल में parameters का उपयोग किया बजाय मैं उन सभी को command line पर specify करूं। सिर्फ इस simple example के लिए overkill लग सकता है, लेकिन आप कल्पना कर सकते हैं कि यदि आपके पास 10 या 20 विभिन्न parameters हैं, तो manually type करना एक pain हो सकता है, और यह code editor में edit करना और reproducibility के लिए पकड़े रखना बहुत आसान है। + +## 3. निर्धारित करें कि काम करने के लिए किस executor(s) का उपयोग किया जाना चाहिए + +ठीक है। हमने Docker और conda के साथ software packaging के बारे में बात की है। हमने CPUs और memory के साथ process resource requirements के बारे में बात की है। और हमने workflows चलाते समय parameters को specify करने के तरीके के बारे में थोड़ी बात की। + +Configuration के अंतिम भाग वास्तव में execution हैं, underlying compute infrastructure ही, और यह Nextflow का real jewel in the crown है: कि हम इन same workflow को कई विभिन्न compute infrastructures में चला सकते हैं। + +मैं वास्तव में एक second के लिए written training material पर switch करने जा रहा हूं। प्रशिक्षण के इस भाग के तहत, हम कुछ अलग-अलग examples देख सकते हैं कि विभिन्न executors, इस मामले में, HPC schedulers, एक job submit करने के लिए आवश्यक resource requirements को कैसे define करते हैं। + +तो Slurm के लिए, आपके पास ये SBATCH headers हैं, जो dash dash mem और CPU number को define करते हैं। यदि आप PBS का उपयोग कर रहे हैं, तो आपके पास अलग headers हैं, और यदि आप Grid Engine का उपयोग करते हैं, तो आपके पास फिर से अलग headers हैं। + +आप कल्पना कर सकते हैं कि यदि आप cloud पर चलाना चाहते हैं, तो यह और भी अलग है, चाहे वह AWS batch हो, Google Cloud, Azure, या अधिक। + +इन underlying compute infrastructures में से प्रत्येक को executor कहा जाता है और Nextflow जानता है कि correct syntax के साथ jobs submit करने के लिए इन सभी विभिन्न executors से कैसे बात करनी है। + +अच्छी खबर यह है कि आपको इसके बारे में जानने की ज़रूरत नहीं है। आपको बस Nextflow को बताना है कि किस executor का उपयोग करना है। + +## 3.1. एक अलग backend को लक्षित करना + +हम अपनी config फ़ाइल में वापस जाते हैं और process हम executor करते हैं, और मैं local type करने जा रहा हूं। + +Local वास्तव में default है, यदि आप कोई अन्य executor specify नहीं करते हैं, तो local का उपयोग किया जाएगा, और इसका मतलब सिर्फ आपका host system है, जहां भी आपने Nextflow launch किया, + +मैं इसके बजाय, Slurm specify कर सकता था। और वह Slurm jobs submit करेगा, या मैं AWS batch कह सकता था, और वह AWS batch को jobs submit करेगा। + +कुछ मामलों में आपको कुछ अतिरिक्त configuration की आवश्यकता होती है, उदाहरण के लिए, cloud पर चलाने के लिए कुछ credentials की आवश्यकता होगी, लेकिन वास्तव में यह इसका core है, और पूरी तरह से अलग compute environment में अपना workflow चलाने के लिए यह config की एक या दो lines जितना सरल हो सकता है। + +भले ही हम code spaces के भीतर एक simple system पर चल रहे हैं, मैं अभी भी इसके साथ थोड़ा खेल सकता हूं और दिखावा कर सकता हूं कि हम Slurm पर चल रहे हैं। अगर मैं फिर workflow launch करता हूं, Nextflow run, hello config। यह fail हो जाएगा क्योंकि यह Slurm को jobs submit करने में सक्षम नहीं होगा। लेकिन हम अभी भी work directories में जा सकते हैं और देख सकते हैं कि Nextflow ने क्या किया। तो अगर हम इस work directory में जाएं और Command Run को देखें। आप फ़ाइल के top पर देख सकते हैं, हमारे पास अब ये sbatch header lines हैं, जिन्होंने Slurm job के लिए आवश्यक resources को specify करने की कोशिश की। + +## 4. Preset configurations select करने के लिए profiles का उपयोग करें + +ठीक है, हम लगभग वहां हैं। इस अध्याय का अंतिम भाग configuration profiles के बारे में बात कर रहा है। यदि आप कई विभिन्न systems पर अपना pipeline चला रहे हैं, तो ये सभी विभिन्न Nextflow config फ़ाइलें होना annoying हो सकता है, जिन्हें आपको हर बार specify करने की आवश्यकता होती है। + +इसके बजाय, आप अपनी Nextflow config फ़ाइल के भीतर configuration की groupings को encode कर सकते हैं, और उन groups को एक profile flag का उपयोग करके on और off switch कर सकते हैं। चलिए देखते हैं कि वह कैसा दिखता है। + +## 4.1. Local development और HPC पर execution के बीच switching के लिए profiles बनाएं + +हम यहां अपने example में दो profiles बनाने जा रहे हैं, एक मेरे laptop के लिए और एक भारी HPC system के लिए। मैं थोड़ा cheat करने जा रहा हूं और बस training material से code को copy करूंगा और इसे यहां रखूंगा। + +हमारे पास profiles नामक एक नया scope है, और फिर हमारे पास प्रत्येक profile के लिए एक name है, जो कुछ भी हो सकता है। और उसके भीतर हमारे पास configuration है, जो बिल्कुल top level config की तरह दिखता है जो हमने पहले ही लिखा था। तो फिर से, हमारे पास process scope है। Docker scope। + +My laptop नामक profile पर। मैं कह रहा हूं कि local executor का उपयोग करके चलाएं, तो मेरे host system पर और Docker का उपयोग करें। + +यहां university HPC profile पर मैं कह रहा हूं कि jobs submit करने के लिए Slurm का उपयोग करें, Docker के बजाय conda का उपयोग करें, और मैं विभिन्न resource limits specify कर रहा हूं, जो मेरे द्वारा उपयोग किए जा रहे HPC पर nodes के system size से match हो सकते हैं। + +By default, जब मैं Nextflow चलाता हूं तो इस configuration में से कोई भी उपयोग नहीं किया जाएगा, मुझे specify करना होगा कि मैं इनमें से किसी एक profile का उपयोग करना चाहता हूं। + +## 4.2. एक profile के साथ workflow चलाएं + +चलिए nextflow run hello config करते हैं। और मैं dash profile करने जा रहा हूं, single hyphen क्योंकि यह एक core Nextflow option है। और फिर जो name मैंने दिया, जो है my laptop। Nextflow को अब उस configuration profile के भीतर specify किए गए config के block का उपयोग करना चाहिए, और इसे apply करना चाहिए जब यह Nextflow चलाता है। यदि मैं दूसरे config block का उपयोग करना चाहता था, तो मुझे बस उस profile name को switch करना होगा। याद रखना बहुत आसान। उपयोग करना बहुत आसान। + +## 4.3. एक test profile बनाएं + +ध्यान दें, profiles में किसी भी तरह का configuration हो सकता है, इसलिए इसे आपके execution environment से संबंधित होना जरूरी नहीं है। उदाहरण के लिए, चलिए यहां एक नया profile बनाते हैं, जिसमें parameters का एक set है। हम इसे tux में बदल सकते हैं और my profile में बदल सकते हैं, और अब जब हम profile test करते हैं, तो यह इन parameters को specify करने जा रहा है, जो workflow के top level पर specify किए गए parameters को overwrite करेगा। + +जब आप Nextflow चलाते हैं, तो आप कई profiles को chain कर सकते हैं और वे क्रम में apply होंगे। + +## 4.4. Test profile के साथ locally workflow चलाएं + +तो मैं पिछली कमांड ले सकता हूं और comma test कर सकता हूं। वह पहले my laptop config apply करेगा, और फिर यह test config apply करेगा। यदि कोई overlap है, तो right पर profile किसी भी पिछले profiles में configuration को overwrite कर देगा। अगर मैं enter दबाता हूं, तो देखते हैं क्या होता है। + +ठीक है, हमें यहां एक नई results फ़ाइल मिली है। आप My Profile देख सकते हैं, जिसे मैंने options में से एक के रूप में specify किया था। और हम cowpy, my profile भी देख सकते हैं, और निश्चित रूप से, वहां tux है। तो यह काम किया। + +## समापन + +ठीक है! अद्भुत। बस इतना ही। आपने कोर्स के अंत तक पहुंच गए हैं। आपको थोड़ी celebration confetti मिलती है। इस अध्याय को समाप्त करने के लिए बधाई। + +[अगली वीडियो ट्रांसक्रिप्ट :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/hi/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/hi/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..01c75e08c5 --- /dev/null +++ b/docs/hi/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# अगले कदम - ट्रांसक्रिप्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "महत्वपूर्ण नोट" + + यह पेज केवल ट्रांसक्रिप्ट दिखाता है। पूर्ण चरण-दर-चरण निर्देशों के लिए, [कोर्स सामग्री](../05_hello_containers.md) पर वापस जाएं। + +## स्वागत + +बधाई हो, आपने कर दिखाया। आपने पहला Nextflow प्रशिक्षण कोर्स पूरा कर लिया है, जिसे Hello Nextflow कहा जाता है + +बहुत बढ़िया। इसे पूरा करने के लिए धन्यवाद और हम वाकई में उस समय और मेहनत की सराहना करते हैं जो आपने Nextflow सीखने में लगाई है, और हमें उम्मीद है कि यह आपके काम के लिए उपयोगी होगा। + +## अगले कदम + +अगले कदमों के लिए, प्रशिक्षण पोर्टल पर नज़र रखें: training.nextflow.io। हम वहां हर समय नई कोर्स सामग्री डाल रहे हैं और इसे रिफ्रेश भी कर रहे हैं। तो आप अधिक उन्नत प्रशिक्षण, या ऐसा प्रशिक्षण पा सकते हैं जो अनुसंधान के उस क्षेत्र के लिए विशिष्ट है जिसमें आप रुचि रखते हैं। + +विशेष रूप से, Nextflow for Science पेज देखें। इसमें छोटे कोर्स की एक श्रृंखला है जो स्वतंत्र हैं, और वे विशिष्ट उपयोग के मामलों के लिए Hello Nextflow में आपने जो सीखा है उसे विस्तारित करते हैं। + +Genomics के लिए एक है और RNA-seq के लिए भी एक है। हमें जल्द ही और अधिक लाने की उम्मीद है। + +## साइड क्वेस्ट्स + +बहुत सारी चीजें हैं जिनके बारे में हम Hello Nextflow में बात कर सकते थे, जो बहुत अधिक विस्तार में होतीं। इनमें से कुछ चीजों को हम साइड क्वेस्ट्स में डाल रहे हैं, जो विशिष्ट विषयों पर छोटे कोर्स हैं। + +बड़े फंडामेंटल्स प्रशिक्षण और उन्नत प्रशिक्षण कोर्स भी हैं, जिनमें ऐसी सामग्री शामिल हो सकती है जो आपको दिलचस्प लगे। + +## nf-core + +इस कोर्स में इसका एक या दो बार उल्लेख किया गया है, लेकिन निश्चित रूप से nf-core प्रोजेक्ट देखें। विभिन्न प्रकार के डेटा के लिए वहां सौ से अधिक pipeline हैं, तो यह पूरी तरह से संभव है कि आपको अपनी खुद की pipeline बनाने की आवश्यकता न हो। + +लगभग डेढ़ हजार process मॉड्यूल भी हैं जहां यदि आप nf-core डेवलपर टूलिंग का उपयोग करते हैं, तो आप एक pipeline बना सकते हैं और उन मॉड्यूल को कुछ ही सेकंड में इम्पोर्ट कर सकते हैं। + +## Seqera Platform + +अंत में, Seqera Platform के लिए एक त्वरित प्लग। व्यवहार में Nextflow चलाने का यह निस्संदेह सबसे अच्छा तरीका है, यह एक क्लाउड-आधारित प्लेटफॉर्म है, लेकिन आप अपना खुद का कंप्यूट इंफ्रास्ट्रक्चर संलग्न करते हैं, चाहे वह AWS, Google Batch, या Azure पर आपका अपना क्लाउड अकाउंट हो, या यहां तक कि आपका अपना HPC हो। फ्री टियर सभी के लिए उपलब्ध है, और यदि आप एक शैक्षणिक हैं, तो आप मुफ्त, प्रो-स्तरीय एक्सेस के लिए हमारे शैक्षणिक कार्यक्रम में आवेदन कर सकते हैं। + +Seqera Platform workflow लॉन्च करने और मॉनिटर करने के लिए केवल एक ग्राफिकल इंटरफेस से परे जाता है। अतिरिक्त टूलिंग भी है जैसे कि Data Studios इंटरैक्टिव सत्र चलाने के लिए, और फंडामेंटल टूलिंग जैसे कि Fusion, जो क्लाउड पर डेटा तक तेज और सस्ती पहुंच देता है। + +## सहायता और इवेंट्स + +याद रखें, यदि आपको कभी कोई परेशानी होती है, तो बस community.seqera.io पर जाएं। वहां हमारा फोरम वास्तव में सक्रिय है, Nextflow समुदाय बहुत मजबूत है और लगभग हमेशा लोग मदद करने के लिए तैयार रहते हैं, चाहे वह प्रशिक्षण के लिए हो या Nextflow के आपके दिन-प्रतिदिन के उपयोग से संबंधित कुछ भी हो। + +और निश्चित रूप से, एक महान अगला कदम हमारे समुदाय इवेंट्स में से किसी एक में शामिल होना है, चाहे वह nf-core हैकथॉन हो या Nextflow Summit इवेंट्स में से एक हो। वे बहुत मजेदार होते हैं, और वहां आपसे मिलना और आप Nextflow को किस लिए उपयोग कर रहे हैं, इसके बारे में बात करना वाकई अच्छा होगा। + +## धन्यवाद + +मैं उन सभी को बहुत धन्यवाद देना चाहूंगा जो इस प्रशिक्षण सामग्री को लिखने में शामिल रहे हैं। मैं इसे प्रस्तुत कर रहा हूं, लेकिन वास्तव में सारी मेहनत Seqera की प्रशिक्षण टीम द्वारा की गई है। विशेष रूप से Geraldine, जिन्होंने इस सामग्री को फिर से लिखने में बहुत अधिक काम किया है। + +साथ ही, Marcel, Ken, Adam, John, वैज्ञानिक विकास टीम के अन्य लोग और समुदाय के अन्य लोग। + +## फीडबैक सर्वेक्षण + +अब जब आपने कोर्स पूरा कर लिया है, तो हम जानना चाहेंगे कि आपको यह कैसा लगा। training.nextflow.io पर, आपको Hello Nextflow सेक्शन के नीचे एक फीडबैक सर्वेक्षण मिलेगा। + +केवल चार प्रश्न हैं लेकिन यह हमारे लिए वास्तव में महत्वपूर्ण है। यदि कुछ नहीं तो, यह हमें मोटे तौर पर बताता है कि कितने लोग प्रशिक्षण कर रहे हैं। यह हमें यह भी बताता है कि क्या आपको यह पसंद आया और यदि आपके पास कोई सुझाव हैं, तो कृपया उन्हें अंत में डालें। हम हर एक सबमिशन पढ़ते हैं। + +यदि आपको कोई त्रुटि दिखाई देती है तो सब कुछ GitHub पर ओपन सोर्स है, इसलिए आप एक issue बना सकते हैं या pull request बना सकते हैं या फोरम में हमें मेसेज भेज सकते हैं। हम यह सुनना पसंद करेंगे कि आपको यह कैसा लगा और हम इसे कैसे सुधार सकते हैं। फिर से धन्यवाद। उम्मीद है जल्द ही मिलेंगे। diff --git a/docs/hi/docs/hello_nf-core/00_orientation.md b/docs/hi/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..00a8715509 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# शुरुआत करना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## प्रशिक्षण वातावरण शुरू करें + +GitHub Codespaces पर हमारे द्वारा प्रदान किए गए पूर्व-निर्मित वातावरण का उपयोग करने के लिए, नीचे दिए गए "Open in GitHub Codespaces" बटन पर क्लिक करें। अन्य विकल्पों के लिए, [वातावरण विकल्प](../envsetup/index.md) देखें। + +हम अनुशंसा करते हैं कि प्रशिक्षण वातावरण को एक नए ब्राउज़र टैब या विंडो में खोलें (अपने उपकरण के अनुसार राइट-क्लिक, ctrl-क्लिक या cmd-क्लिक का उपयोग करें) ताकि वातावरण लोड होते समय आप पढ़ सकें। +पाठ्यक्रम में काम करने के लिए आपको इन निर्देशों को समानांतर में खुला रखना होगा। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### वातावरण की मूल बातें + +इस प्रशिक्षण वातावरण में प्रशिक्षण पाठ्यक्रम के माध्यम से काम करने के लिए आवश्यक सभी सॉफ़्टवेयर, कोड और डेटा शामिल हैं, इसलिए आपको स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। + +codespace VSCode इंटरफ़ेस के साथ सेट अप किया गया है, जिसमें एक फ़ाइलसिस्टम एक्सप्लोरर, एक कोड एडिटर और एक टर्मिनल शेल शामिल है। +पाठ्यक्रम के दौरान दिए गए सभी निर्देश (जैसे 'फ़ाइल खोलें', 'कोड संपादित करें' या 'यह कमांड चलाएं') VScode इंटरफ़ेस के उन तीन भागों को संदर्भित करते हैं जब तक कि अन्यथा निर्दिष्ट न किया गया हो। + +यदि आप इस पाठ्यक्रम को स्वयं कर रहे हैं, तो कृपया अधिक विवरण के लिए [वातावरण की मूल बातें](../envsetup/01_setup.md) से परिचित हों। + +### संस्करण आवश्यकताएं + +यह प्रशिक्षण **Nextflow 25.10.2** या उसके बाद के संस्करण के लिए डिज़ाइन किया गया है **v2 syntax parser DISABLED के साथ**। + +#### यदि आप हमारे प्रशिक्षण वातावरण का उपयोग कर रहे हैं: + +आगे बढ़ने से पहले आपको निम्नलिखित कमांड चलानी होगी: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### यदि आप स्थानीय या कस्टम वातावरण का उपयोग कर रहे हैं: + +कृपया सुनिश्चित करें कि आप सही सेटिंग्स का उपयोग कर रहे हैं जैसा कि [यहां](../info/nxf_versions.md) दस्तावेज़ीकृत है। + +प्रशिक्षण के लिए अतिरिक्त रूप से **nf-core tools 3.4.1** की आवश्यकता है। +यदि आप nf-core टूलिंग के एक अलग संस्करण का उपयोग करते हैं, तो आपको अनुसरण करने में कठिनाई हो सकती है। + +आप `nf-core --version` कमांड का उपयोग करके जांच सकते हैं कि आपके वातावरण में कौन सा संस्करण इंस्टॉल है। + +## काम के लिए तैयार हो जाएं + +एक बार आपका codespace चल रहा हो, तो प्रशिक्षण में गोता लगाने से पहले आपको दो काम करने हैं: इस विशिष्ट पाठ्यक्रम के लिए अपनी कार्य डायरेक्टरी सेट करें, और प्रदान की गई सामग्री पर एक नज़र डालें। + +### कार्य डायरेक्टरी सेट करें + +डिफ़ॉल्ट रूप से, codespace सभी प्रशिक्षण पाठ्यक्रमों की रूट पर सेट कार्य डायरेक्टरी के साथ खुलता है, लेकिन इस पाठ्यक्रम के लिए, हम `hello-nf-core/` डायरेक्टरी में काम करेंगे। + +टर्मिनल में यह कमांड चलाकर अभी डायरेक्टरी बदलें: + +```bash +cd hello-nf-core/ +``` + +!!! tip "सुझाव" + + यदि किसी भी कारण से आप इस डायरेक्टरी से बाहर चले जाते हैं (जैसे आपका codespace स्लीप मोड में चला जाता है), तो आप हमेशा इसमें वापस आने के लिए पूर्ण path का उपयोग कर सकते हैं, यह मानते हुए कि आप Github Codespaces प्रशिक्षण वातावरण के भीतर इसे चला रहे हैं: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +अब आइए इस डायरेक्टरी की सामग्री पर एक नज़र डालें। + +### प्रदान की गई सामग्री का पता लगाएं + +आप प्रशिक्षण कार्यक्षेत्र के बाईं ओर फ़ाइल एक्सप्लोरर का उपयोग करके इस डायरेक्टरी की सामग्री का पता लगा सकते हैं। +वैकल्पिक रूप से, आप `tree` कमांड का उपयोग कर सकते हैं। + +पाठ्यक्रम के दौरान, हम डायरेक्टरी संरचना और सामग्री को पठनीय रूप में प्रस्तुत करने के लिए `tree` के आउटपुट का उपयोग करते हैं, कभी-कभी स्पष्टता के लिए मामूली संशोधनों के साथ। + +यहां हम दूसरे स्तर तक सामग्री की तालिका बनाते हैं: + +```bash +tree . -L 2 +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +अनुभाग का विस्तार करने और इसकी सामग्री देखने के लिए रंगीन बॉक्स पर क्लिक करें। +हम संक्षिप्त तरीके से अपेक्षित कमांड आउटपुट शामिल करने के लिए इस तरह के संक्षिप्त अनुभागों का उपयोग करते हैं। + +- **`greetings.csv` फ़ाइल** एक CSV है जिसमें कुछ न्यूनतम स्तंभीय डेटा है जिसका उपयोग हम परीक्षण उद्देश्यों के लिए करते हैं। + +- **`original-hello` डायरेक्टरी** में संपूर्ण Hello Nextflow प्रशिक्षण श्रृंखला के माध्यम से काम करके उत्पादित स्रोत कोड की एक प्रति शामिल है (Docker सक्षम के साथ)। + +- **`solutions` डायरेक्टरी** में पाठ्यक्रम के प्रत्येक चरण से प्राप्त पूर्ण workflow scripts शामिल हैं। + उनका उद्देश्य आपके काम की जांच करने और किसी भी समस्या का निवारण करने के लिए एक संदर्भ के रूप में उपयोग किया जाना है। + +## तैयारी चेकलिस्ट + +क्या आपको लगता है कि आप गोता लगाने के लिए तैयार हैं? + +- [ ] मैं इस पाठ्यक्रम के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता हूं +- [ ] मेरा वातावरण चालू और चल रहा है +- [ ] मैंने सुनिश्चित किया है कि syntax parser **v1** पर सेट है +- [ ] मैंने अपनी कार्य डायरेक्टरी को उचित रूप से सेट किया है + +यदि आप सभी बॉक्स चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +**भाग 1 को जारी रखने के लिए, इस पृष्ठ के निचले दाएं कोने में तीर पर क्लिक करें।** diff --git a/docs/hi/docs/hello_nf-core/01_run_demo.md b/docs/hi/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..1207a0739d --- /dev/null +++ b/docs/hi/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# भाग 1: एक डेमो पाइपलाइन चलाएं + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण पाठ्यक्रम के इस पहले भाग में, हम आपको दिखाएंगे कि एक nf-core pipeline कैसे खोजें और आज़माएं, कोड कैसे व्यवस्थित है यह कैसे समझें, और यह पहचानें कि यह plain Nextflow कोड से कैसे अलग है जैसा कि [Hello Nextflow](../hello_nextflow/index.md) में दिखाया गया है। + +हम nf-core/demo नामक एक pipeline का उपयोग करने जा रहे हैं जिसे nf-core प्रोजेक्ट अपने pipelines की सूची के हिस्से के रूप में कोड संरचना और टूल संचालन के प्रदर्शन के लिए बनाए रखता है। + +सुनिश्चित करें कि आपकी वर्किंग डायरेक्टरी `hello-nf-core/` पर सेट है जैसा कि [Getting started](./00_orientation.md) पेज पर निर्देश दिया गया है। + +--- + +## 1. nf-core/demo pipeline खोजें और प्राप्त करें + +आइए [nf-co.re](https://nf-co.re) पर प्रोजेक्ट वेबसाइट पर nf-core/demo pipeline को खोजने से शुरू करें, जो सभी जानकारी को केंद्रीकृत करती है जैसे: सामान्य दस्तावेज़ीकरण और सहायता लेख, प्रत्येक pipeline के लिए दस्तावेज़ीकरण, ब्लॉग पोस्ट, इवेंट की घोषणाएं इत्यादि। + +### 1.1. वेबसाइट पर pipeline खोजें + +अपने वेब ब्राउज़र में, [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) पर जाएं और सर्च बार में `demo` टाइप करें। + +![search results](./img/search-results.png) + +Pipeline दस्तावेज़ीकरण पेज तक पहुँचने के लिए pipeline के नाम, `demo`, पर क्लिक करें। + +प्रत्येक रिलीज़ की गई pipeline का एक समर्पित पेज होता है जिसमें निम्नलिखित दस्तावेज़ीकरण अनुभाग शामिल होते हैं: + +- **Introduction:** Pipeline का परिचय और अवलोकन +- **Usage:** Pipeline को execute करने के तरीके का विवरण +- **Parameters:** विवरण के साथ समूहीकृत pipeline पैरामीटर +- **Output:** अपेक्षित आउटपुट फ़ाइलों का विवरण और उदाहरण +- **Results:** पूर्ण test dataset से उत्पन्न उदाहरण आउटपुट फ़ाइलें +- **Releases & Statistics:** Pipeline संस्करण इतिहास और आंकड़े + +जब भी आप एक नई pipeline को अपनाने पर विचार कर रहे हों, तो आपको पहले pipeline दस्तावेज़ीकरण को ध्यान से पढ़ना चाहिए ताकि यह समझ सकें कि यह क्या करती है और इसे चलाने का प्रयास करने से पहले इसे कैसे कॉन्फ़िगर किया जाना चाहिए। + +अभी देखें और पता लगाएं: + +- Pipeline कौन से टूल चलाएगी (टैब देखें: `Introduction`) +- Pipeline कौन से इनपुट और पैरामीटर स्वीकार करती है या आवश्यक है (टैब देखें: `Parameters`) +- Pipeline द्वारा उत्पादित आउटपुट क्या हैं (टैब देखें: `Output`) + +#### 1.1.1. Pipeline अवलोकन + +`Introduction` टैब pipeline का एक अवलोकन प्रदान करता है, जिसमें एक दृश्य प्रतिनिधित्व (जिसे subway map कहा जाता है) और pipeline के हिस्से के रूप में चलाए जाने वाले टूल की एक सूची शामिल है। + +![pipeline subway map](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. उदाहरण कमांड लाइन + +दस्तावेज़ीकरण एक उदाहरण इनपुट फ़ाइल (जिसकी आगे चर्चा की जाएगी) और एक उदाहरण कमांड लाइन भी प्रदान करता है। + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +आप देखेंगे कि उदाहरण कमांड एक workflow फ़ाइल निर्दिष्ट नहीं करती है, केवल pipeline रिपॉज़िटरी का संदर्भ, `nf-core/demo`। + +इस तरह से शुरू करने पर, Nextflow मान लेगा कि कोड एक निश्चित तरीके से व्यवस्थित है। +आइए कोड प्राप्त करें ताकि हम इस संरचना की जांच कर सकें। + +### 1.2. Pipeline कोड प्राप्त करें + +एक बार जब हम यह निर्धारित कर लेते हैं कि pipeline हमारे उद्देश्यों के लिए उपयुक्त प्रतीत होती है, तो आइए इसे आज़माएं। +सौभाग्य से Nextflow सही ढंग से प्रारूपित रिपॉज़िटरी से pipelines को मैन्युअल रूप से कुछ भी डाउनलोड किए बिना प्राप्त करना आसान बनाता है। + +आइए टर्मिनल पर वापस जाएं और निम्नलिखित चलाएं: + +```bash +nextflow pull nf-core/demo +``` + +??? success "कमांड आउटपुट" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow pipeline कोड का एक `pull` करता है, मतलब यह पूरी रिपॉज़िटरी को आपकी लोकल ड्राइव पर डाउनलोड करता है। + +स्पष्ट करने के लिए, आप GitHub में उचित रूप से सेट की गई किसी भी Nextflow pipeline के साथ ऐसा कर सकते हैं, न केवल nf-core pipelines के साथ। +हालाँकि nf-core Nextflow pipelines का सबसे बड़ा ओपन-सोर्स संग्रह है। + +आप Nextflow से इस तरह से प्राप्त की गई pipelines की सूची दे सकते हैं: + +```bash +nextflow list +``` + +??? success "कमांड आउटपुट" + + ```console + nf-core/demo + ``` + +आप देखेंगे कि फ़ाइलें आपकी वर्तमान कार्य डायरेक्टरी में नहीं हैं। +डिफ़ॉल्ट रूप से, Nextflow उन्हें `$NXF_HOME/assets` में सहेजता है। + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="डायरेक्टरी सामग्री" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + यदि आप हमारे प्रशिक्षण वातावरण का उपयोग नहीं कर रहे हैं तो आपके सिस्टम पर पूर्ण पथ भिन्न हो सकता है। + +Nextflow डाउनलोड किए गए स्रोत कोड को जानबूझकर 'बाहर' रखता है इस सिद्धांत पर कि इन pipelines का उपयोग उस कोड की तुलना में अधिक लाइब्रेरी की तरह किया जाना चाहिए जिसके साथ आप सीधे इंटरैक्ट करेंगे। + +हालांकि, इस प्रशिक्षण के उद्देश्यों के लिए, हम इधर-उधर देखना और देखना चाहते हैं कि वहाँ क्या है। +तो इसे आसान बनाने के लिए, आइए अपनी वर्तमान कार्य डायरेक्टरी से उस स्थान पर एक symbolic link बनाएं। + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +यह एक शॉर्टकट बनाता है जो हमने अभी डाउनलोड किए गए कोड को एक्सप्लोर करना आसान बनाता है। + +```bash +tree -L 2 pipelines +``` + +```console title="डायरेक्टरी सामग्री" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +अब हम आवश्यकतानुसार स्रोत कोड में अधिक आसानी से झाँक सकते हैं। + +लेकिन पहले, आइए अपनी पहली nf-core pipeline चलाने का प्रयास करें! + +### मुख्य बात + +अब आप जानते हैं कि nf-core वेबसाइट के माध्यम से एक pipeline कैसे खोजें और स्रोत कोड की एक स्थानीय प्रति कैसे प्राप्त करें। + +### आगे क्या है? + +सीखें कि न्यूनतम प्रयास के साथ एक nf-core pipeline कैसे आज़माएं। + +--- + +## 2. अपने test profile के साथ pipeline आज़माएं + +सुविधाजनक रूप से, प्रत्येक nf-core pipeline एक test profile के साथ आती है। +यह [nf-core/test-datasets](https://github.com/nf-core/test-datasets) रिपॉज़िटरी में होस्ट किए गए एक छोटे test dataset का उपयोग करके चलने के लिए pipeline के लिए कॉन्फ़िगरेशन सेटिंग्स का एक न्यूनतम सेट है। +यह छोटे पैमाने पर एक pipeline को जल्दी से आज़माने का एक शानदार तरीका है। + +!!! note + + Nextflow का configuration profile सिस्टम आपको विभिन्न कंटेनर इंजन या execution वातावरण के बीच आसानी से स्विच करने की अनुमति देता है। + अधिक विवरण के लिए, [Hello Nextflow भाग 6: Configuration](../hello_nextflow/06_hello_config.md) देखें। + +### 2.1. test profile की जांच करें + +Pipeline के test profile को चलाने से पहले यह जांचना अच्छा अभ्यास है कि यह क्या निर्दिष्ट करता है। +`nf-core/demo` के लिए `test` profile कॉन्फ़िगरेशन फ़ाइल `conf/test.config` में रहता है और नीचे दिखाया गया है। + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // इनपुट डेटा + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +आप तुरंत देखेंगे कि शीर्ष पर कमेंट ब्लॉक में एक उपयोग उदाहरण शामिल है जो दिखाता है कि इस test profile के साथ pipeline को कैसे चलाना है। + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +हमें केवल वही प्रदान करने की आवश्यकता है जो उदाहरण कमांड में कैरेट के बीच दिखाया गया है: `<docker/singularity>` और `<OUTDIR>`। + +याद दिलाने के लिए, `<docker/singularity>` कंटेनर सिस्टम की पसंद को संदर्भित करता है। सभी nf-core pipelines को reproducibility सुनिश्चित करने और सॉफ़्टवेयर इंस्टॉलेशन समस्याओं को खत्म करने के लिए कंटेनर (Docker, Singularity, आदि) के साथ उपयोग करने योग्य होने के लिए डिज़ाइन किया गया है। +इसलिए हमें यह निर्दिष्ट करने की आवश्यकता होगी कि हम pipeline का परीक्षण करने के लिए Docker या Singularity का उपयोग करना चाहते हैं या नहीं। + +`--outdir <OUTDIR>` भाग उस डायरेक्टरी को संदर्भित करता है जहाँ Nextflow pipeline के आउटपुट लिखेगा। +हमें इसके लिए एक नाम प्रदान करने की आवश्यकता है, जिसे हम बस बना सकते हैं। +यदि यह पहले से मौजूद नहीं है, तो Nextflow इसे runtime पर हमारे लिए बना देगा। + +कमेंट ब्लॉक के बाद के अनुभाग की ओर बढ़ते हुए, test profile हमें दिखाता है कि परीक्षण के लिए क्या पूर्व-कॉन्फ़िगर किया गया है: सबसे विशेष रूप से, `input` पैरामीटर पहले से ही एक test dataset की ओर इशारा करने के लिए सेट है, इसलिए हमें अपना डेटा प्रदान करने की आवश्यकता नहीं है। +यदि आप पूर्व-कॉन्फ़िगर किए गए इनपुट के लिंक का अनुसरण करते हैं, तो आप देखेंगे कि यह एक csv फ़ाइल है जिसमें कई प्रायोगिक नमूनों के लिए नमूना पहचानकर्ता और फ़ाइल पथ हैं। + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +इसे samplesheet कहा जाता है, और यह nf-core pipelines के लिए इनपुट का सबसे आम रूप है। + +!!! note + + यदि आप डेटा प्रारूप और प्रकारों से परिचित नहीं हैं तो चिंता न करें, यह आगे के लिए महत्वपूर्ण नहीं है। + +तो यह पुष्टि करता है कि हमारे पास pipeline को आज़माने के लिए आवश्यक सब कुछ है। + +### 2.2. Pipeline चलाएं + +आइए कंटेनर सिस्टम के लिए Docker का उपयोग करने और आउटपुट डायरेक्टरी के रूप में `demo-results` का निर्णय लें, और हम test कमांड चलाने के लिए तैयार हैं: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +यदि आपका आउटपुट उससे मेल खाता है, तो बधाई हो! आपने अभी अपनी पहली nf-core pipeline चलाई है। + +आप देखेंगे कि जब आप एक बुनियादी Nextflow pipeline चलाते हैं तो कंसोल आउटपुट बहुत अधिक है। +एक हेडर है जिसमें pipeline के संस्करण, इनपुट और आउटपुट, और कॉन्फ़िगरेशन के कुछ तत्वों का सारांश शामिल है। + +!!! note + + आपका आउटपुट अलग-अलग timestamps, execution नाम और फ़ाइल पथ दिखाएगा, लेकिन समग्र संरचना और process execution समान होनी चाहिए। + +Execution आउटपुट की ओर बढ़ते हुए, आइए उन लाइनों पर एक नज़र डालें जो हमें बताती हैं कि कौन से processes चलाए गए थे: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +यह हमें बताता है कि तीन processes चलाई गईं, जो nf-core वेबसाइट पर pipeline दस्तावेज़ीकरण पेज में दिखाए गए तीन टूल से संबंधित हैं: FASTQC, SEQTK_TRIM और MULTIQC। + +पूर्ण process नाम जैसा कि यहाँ दिखाया गया है, जैसे `NFCORE_DEMO:DEMO:MULTIQC`, परिचयात्मक Hello Nextflow सामग्री में आपने जो देखा होगा उससे लंबे हैं। +इनमें उनके parent workflows के नाम शामिल हैं और pipeline कोड की modularity को दर्शाते हैं। +हम इसके बारे में थोड़ी देर में अधिक विस्तार से बात करेंगे। + +### 2.3. Pipeline के आउटपुट की जांच करें + +अंत में, आइए pipeline द्वारा उत्पादित `demo-results` डायरेक्टरी पर एक नज़र डालें। + +```bash +tree -L 2 demo-results +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +यह बहुत अधिक लग सकता है। +`nf-core/demo` pipeline के आउटपुट के बारे में अधिक जानने के लिए, इसका [दस्तावेज़ीकरण पेज](https://nf-co.re/demo/1.0.2/docs/output/) देखें। + +इस स्तर पर, यह देखना महत्वपूर्ण है कि परिणाम module द्वारा व्यवस्थित हैं, और इसके अतिरिक्त `pipeline_info` नामक एक डायरेक्टरी है जिसमें pipeline execution के बारे में विभिन्न timestamped रिपोर्ट हैं। + +उदाहरण के लिए, `execution_timeline_*` फ़ाइल आपको दिखाती है कि कौन से processes चलाए गए, किस क्रम में और उन्हें चलाने में कितना समय लगा: + +![execution timeline report](./img/execution_timeline.png) + +!!! note + + यहाँ कार्य समानांतर में नहीं चलाए गए क्योंकि हम Github Codespaces में एक minimalist मशीन पर चल रहे हैं। + इन्हें समानांतर में चलते हुए देखने के लिए, अपने codespace के CPU allocation और test configuration में resource limits को बढ़ाने का प्रयास करें। + +ये रिपोर्ट सभी nf-core pipelines के लिए स्वचालित रूप से उत्पन्न होती हैं। + +### मुख्य बात + +आप जानते हैं कि अपने अंतर्निहित test profile का उपयोग करके एक nf-core pipeline कैसे चलाएं और इसके आउटपुट कहाँ खोजें। + +### आगे क्या है? + +जानें कि pipeline कोड कैसे व्यवस्थित है। + +--- + +## 3. Pipeline कोड संरचना की जांच करें + +अब जब हमने उपयोगकर्ताओं के रूप में pipeline को सफलतापूर्वक चलाया है, तो आइए अपने दृष्टिकोण को बदलकर देखें कि nf-core pipelines आंतरिक रूप से कैसे संरचित हैं। + +nf-core प्रोजेक्ट pipelines के संरचित होने के तरीके, और कोड को कैसे व्यवस्थित, कॉन्फ़िगर और दस्तावेज़ित किया जाता है, के लिए मजबूत दिशानिर्देश लागू करता है। +यह सब कैसे व्यवस्थित है यह समझना अपने स्वयं के nf-core-compatible pipelines विकसित करने की दिशा में पहला कदम है, जिसे हम इस पाठ्यक्रम के भाग 2 में निपटाएंगे। + +आइए `pipelines` symlink का उपयोग करके `nf-core/demo` रिपॉज़िटरी में pipeline कोड कैसे व्यवस्थित है, इस पर एक नज़र डालें जिसे हमने पहले बनाया था। + +आप या तो `tree` का उपयोग कर सकते हैं या `nf-core/demo` डायरेक्टरी को खोजने और खोलने के लिए फ़ाइल एक्सप्लोरर का उपयोग कर सकते हैं। + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +वहाँ बहुत कुछ चल रहा है, इसलिए हम इसे चरण दर चरण निपटाएंगे। + +सबसे पहले, आइए ध्यान दें कि शीर्ष स्तर पर, आप सारांश जानकारी के साथ एक README फ़ाइल पा सकते हैं, साथ ही साथ सहायक फ़ाइलें जो प्रोजेक्ट की जानकारी जैसे लाइसेंसिंग, योगदान दिशानिर्देश, उद्धरण और आचार संहिता को सारांशित करती हैं। +विस्तृत pipeline दस्तावेज़ीकरण `docs` डायरेक्टरी में स्थित है। +यह सभी सामग्री nf-core वेबसाइट पर वेब पेज उत्पन्न करने के लिए प्रोग्रामेटिक रूप से उपयोग की जाती है, इसलिए वे हमेशा कोड के साथ अद्यतित रहते हैं। + +अब, बाकी के लिए, हम अपने अन्वेषण को तीन चरणों में विभाजित करने जा रहे हैं: + +1. Pipeline कोड घटक (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Pipeline कॉन्फ़िगरेशन +3. इनपुट और सत्यापन + +आइए pipeline कोड घटकों से शुरू करें। +हम फ़ाइल पदानुक्रम और संरचनात्मक संगठन पर ध्यान केंद्रित करने जा रहे हैं, बजाय व्यक्तिगत फ़ाइलों के भीतर कोड में गोता लगाने के। + +### 3.1. Pipeline कोड घटक + +मानक nf-core pipeline कोड संगठन एक modular संरचना का अनुसरण करता है जो कोड पुन: उपयोग को अधिकतम करने के लिए डिज़ाइन किया गया है, जैसा कि [Hello Modules](../hello_nextflow/04_hello_modules.md), [Hello Nextflow](../hello_nextflow/index.md) पाठ्यक्रम के भाग 4 में पेश किया गया है, हालांकि सच्चे nf-core फैशन में, यह थोड़ी अतिरिक्त जटिलता के साथ लागू किया गया है। +विशेष रूप से, nf-core pipelines subworkflows का प्रचुर उपयोग करते हैं, अर्थात् workflow scripts जो एक parent workflow द्वारा import की जाती हैं। + +यह थोड़ा अमूर्त लग सकता है, तो आइए देखें कि `nf-core/demo` pipeline में इसका व्यवहार में कैसे उपयोग किया जाता है। + +!!! note + + हम इन modular घटकों को कैसे जोड़ा जाता है इसके लिए वास्तविक कोड पर नहीं जाएंगे, क्योंकि subworkflows के उपयोग से जुड़ी कुछ अतिरिक्त जटिलता है जो भ्रमित करने वाली हो सकती है, और उसे समझना प्रशिक्षण के इस चरण में आवश्यक नहीं है। + फिलहाल, हम समग्र संगठन और तर्क पर ध्यान केंद्रित करने जा रहे हैं। + +#### 3.1.1. सामान्य अवलोकन + +यहाँ `nf-core/demo` pipeline के लिए प्रासंगिक कोड घटकों के बीच संबंध कैसा दिखता है: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +एक तथाकथित _entrypoint_ स्क्रिप्ट है जिसे `main.nf` कहा जाता है, जो दो प्रकार के nested workflows के लिए एक wrapper के रूप में कार्य करता है: वास्तविक विश्लेषण तर्क वाली workflow, जो `workflows/` के तहत स्थित है और `demo.nf` कहलाती है, और housekeeping workflows का एक सेट `subworkflows/` के तहत स्थित है। +`demo.nf` workflow `modules/` के तहत स्थित **modules** को कॉल करती है; इनमें **processes** हैं जो वास्तविक विश्लेषण चरण करेंगी। + +!!! note + + Subworkflows housekeeping कार्यों तक सीमित नहीं हैं, और वे process modules का उपयोग कर सकते हैं। + + यहाँ दिखाई गई `nf-core/demo` pipeline spectrum पर सरल पक्ष पर होती है, लेकिन अन्य nf-core pipelines (जैसे `nf-core/rnaseq`) subworkflows का उपयोग करती हैं जो वास्तविक विश्लेषण में शामिल हैं। + +अब, आइए इन घटकों की बारी-बारी से समीक्षा करें। + +#### 3.1.2. Entrypoint स्क्रिप्ट: `main.nf` + +`main.nf` स्क्रिप्ट वह entrypoint है जहाँ से Nextflow शुरू होता है जब हम `nextflow run nf-core/demo` execute करते हैं। +इसका मतलब है कि जब आप pipeline चलाने के लिए `nextflow run nf-core/demo` चलाते हैं, तो Nextflow स्वचालित रूप से `main.nf` स्क्रिप्ट ढूंढता है और execute करता है। +यह इस पारंपरिक नामकरण और संरचना का पालन करने वाली किसी भी Nextflow pipeline के लिए काम करता है, न केवल nf-core pipelines के लिए। + +एक entrypoint स्क्रिप्ट का उपयोग करने से वास्तविक विश्लेषण स्क्रिप्ट के चलने से पहले और बाद में मानकीकृत 'housekeeping' subworkflows को चलाना आसान हो जाता है। +हम वास्तविक विश्लेषण workflow और इसके modules की समीक्षा करने के बाद उन पर जाएंगे। + +#### 3.1.3. विश्लेषण स्क्रिप्ट: `workflows/demo.nf` + +`workflows/demo.nf` workflow वह जगह है जहाँ pipeline का केंद्रीय तर्क संग्रहीत है। +यह सामान्य Nextflow workflow की तरह संरचित है, सिवाय इसके कि इसे एक parent workflow से कॉल करने के लिए डिज़ाइन किया गया है, जिसके लिए कुछ अतिरिक्त सुविधाओं की आवश्यकता होती है। +हम इस पाठ्यक्रम के अगले भाग में प्रासंगिक अंतरों को कवर करेंगे, जब हम Hello Nextflow से साधारण Hello pipeline को nf-core-compatible रूप में परिवर्तित करने का सामना करेंगे। + +`demo.nf` workflow `modules/` के तहत स्थित **modules** को कॉल करती है, जिसकी हम अगली बार समीक्षा करेंगे। + +!!! note + + कुछ nf-core विश्लेषण workflows निम्न-स्तरीय subworkflows को कॉल करके nesting के अतिरिक्त स्तर प्रदर्शित करती हैं। + यह ज्यादातर दो या अधिक modules को wrap करने के लिए उपयोग किया जाता है जो आमतौर पर एक साथ आसानी से पुन: उपयोग योग्य pipeline segments में उपयोग किए जाते हैं। + आप nf-core वेबसाइट पर उपलब्ध [nf-core subworkflows](https://nf-co.re/subworkflows/) ब्राउज़ करके कुछ उदाहरण देख सकते हैं। + + जब विश्लेषण स्क्रिप्ट subworkflows का उपयोग करती है, तो वे `subworkflows/` डायरेक्टरी के तहत संग्रहीत होती हैं। + +#### 3.1.4. Modules + +Modules वह जगह हैं जहाँ process कोड रहता है, जैसा कि [Hello Nextflow प्रशिक्षण पाठ्यक्रम के भाग 4](../hello_nextflow/04_hello_modules.md) में वर्णित है। + +nf-core प्रोजेक्ट में, modules को एक बहु-स्तरीय nested संरचना का उपयोग करके व्यवस्थित किया जाता है जो उनके मूल और उनकी सामग्री दोनों को दर्शाता है। +शीर्ष स्तर पर, modules को या तो `nf-core` या `local` (nf-core प्रोजेक्ट का हिस्सा नहीं) के रूप में विभेदित किया जाता है, और फिर उन टूल के नाम पर एक डायरेक्टरी में रखा जाता है जिन्हें वे wrap करते हैं। +यदि टूल एक toolkit से संबंधित है (अर्थात् एक पैकेज जिसमें कई टूल हैं) तो toolkit के नाम पर एक intermediate डायरेक्टरी स्तर है। + +आप इसे `nf-core/demo` pipeline modules में व्यवहार में लागू देख सकते हैं: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +यहाँ आप देखते हैं कि `fastqc` और `multiqc` modules `nf-core` modules के भीतर शीर्ष स्तर पर बैठते हैं, जबकि `trim` module उस toolkit के तहत बैठता है जिससे यह संबंधित है, `seqtk`। +इस मामले में कोई `local` modules नहीं हैं। + +Process का वर्णन करने वाली module कोड फ़ाइल हमेशा `main.nf` कहलाती है, और tests और `.yml` फ़ाइलों के साथ होती है जिन्हें हम अभी के लिए अनदेखा करेंगे। + +एक साथ लिया जाए तो, entrypoint workflow, विश्लेषण workflow और modules pipeline के 'दिलचस्प' भागों को चलाने के लिए पर्याप्त हैं। +हालाँकि, हम जानते हैं कि वहाँ housekeeping subworkflows भी हैं, तो आइए अब उन्हें देखें। + +#### 3.1.5. Housekeeping subworkflows + +Modules की तरह, subworkflows को `local` और `nf-core` डायरेक्टरी में विभेदित किया जाता है, और प्रत्येक subworkflow की अपनी nested डायरेक्टरी संरचना है जिसमें अपनी `main.nf` स्क्रिप्ट, tests और `.yml` फ़ाइल है। + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +जैसा कि ऊपर बताया गया है, `nf-core/demo` pipeline में कोई विश्लेषण-विशिष्ट subworkflows शामिल नहीं हैं, इसलिए यहाँ हम जो सभी subworkflows देखते हैं वे तथाकथित 'housekeeping' या 'utility' workflows हैं, जैसा कि उनके नामों में `utils_` prefix द्वारा दर्शाया गया है। +ये subworkflows वे हैं जो कंसोल आउटपुट में fancy nf-core header उत्पन्न करती हैं, अन्य सहायक कार्यों के बीच। + +!!! tip + + उनके नामकरण पैटर्न के अलावा, एक और संकेत है कि ये subworkflows कोई वास्तव में विश्लेषण-संबंधित कार्य नहीं करती हैं वह यह है कि वे किसी भी processes को बिल्कुल नहीं कॉल करती हैं। + +यह `nf-core/demo` pipeline का गठन करने वाले मुख्य कोड घटकों के राउंड-अप को पूरा करता है। +अब आइए शेष तत्वों पर एक नज़र डालें जिनके बारे में आपको development में गोता लगाने से पहले थोड़ा पता होना चाहिए: pipeline कॉन्फ़िगरेशन और इनपुट सत्यापन। + +### 3.2. Pipeline कॉन्फ़िगरेशन + +आपने पहले सीखा है कि Nextflow pipeline execution को कॉन्फ़िगर करने के लिए कई विकल्प प्रदान करता है, चाहे वह इनपुट और पैरामीटर के संदर्भ में हो, कंप्यूटिंग संसाधन हों, और orchestration के अन्य पहलू हों। +nf-core प्रोजेक्ट pipeline कॉन्फ़िगरेशन के लिए अत्यधिक मानकीकृत दिशानिर्देश लागू करता है जो Nextflow के लचीले customization विकल्पों पर एक ऐसे तरीके से निर्माण करने का लक्ष्य रखते हैं जो pipelines में अधिक consistency और maintainability प्रदान करता है। + +केंद्रीय कॉन्फ़िगरेशन फ़ाइल `nextflow.config` का उपयोग पैरामीटर और अन्य कॉन्फ़िगरेशन विकल्पों के लिए डिफ़ॉल्ट मान सेट करने के लिए किया जाता है। +इनमें से अधिकांश कॉन्फ़िगरेशन विकल्प डिफ़ॉल्ट रूप से लागू होते हैं जबकि अन्य (उदाहरण के लिए, सॉफ़्टवेयर dependency profiles) वैकल्पिक profiles के रूप में शामिल हैं। + +कई अतिरिक्त कॉन्फ़िगरेशन फ़ाइलें हैं जो `conf` फ़ोल्डर में संग्रहीत हैं और जिन्हें डिफ़ॉल्ट रूप से या वैकल्पिक रूप से profiles के रूप में कॉन्फ़िगरेशन में जोड़ा जा सकता है: + +- `base.config`: एक 'blank slate' config फ़ाइल, अधिकांश high-performance computing वातावरण पर सामान्य उपयोग के लिए उपयुक्त। यह संसाधन उपयोग के व्यापक bins को परिभाषित करती है, उदाहरण के लिए, जो modules पर लागू करने के लिए सुविधाजनक हैं। +- `modules.config`: अतिरिक्त module निर्देश और arguments। +- `test.config`: न्यूनतम test डेटा के साथ pipeline चलाने के लिए एक profile, जिसका उपयोग हमने demo pipeline चलाते समय किया था। +- `test_full.config`: पूर्ण आकार के test dataset के साथ pipeline चलाने के लिए एक profile। + +हम पाठ्यक्रम में बाद में इनमें से कुछ फ़ाइलों को छुएंगे। + +### 3.3. इनपुट और सत्यापन + +जैसा कि हमने पहले बताया, जब हमने `nf-core/demo` pipeline के test profile की जांच की, यह इनपुट के रूप में एक samplesheet लेने के लिए डिज़ाइन की गई है जिसमें फ़ाइल पथ और नमूना पहचानकर्ता होते हैं। +फ़ाइल पथ `nf-core/test-datasets` रिपॉज़िटरी में स्थित वास्तविक डेटा से जुड़े थे। + +एक उदाहरण samplesheet `assets` डायरेक्टरी के तहत भी प्रदान की गई है, हालांकि इसमें पथ वास्तविक नहीं हैं। + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +यह विशेष samplesheet काफी सरल है, लेकिन कुछ pipelines samplesheets पर चलती हैं जो अधिक जटिल हैं, प्राथमिक इनपुट से जुड़े बहुत अधिक metadata के साथ। + +दुर्भाग्य से, क्योंकि इन फ़ाइलों को आंख से जांचना मुश्किल हो सकता है, इनपुट डेटा की अनुचित formatting pipeline विफलताओं का एक बहुत ही सामान्य स्रोत है। +एक संबंधित समस्या तब होती है जब पैरामीटर गलत तरीके से प्रदान किए जाते हैं। + +इन समस्याओं का समाधान सभी इनपुट फ़ाइलों पर स्वचालित सत्यापन जांच चलाना है ताकि यह सुनिश्चित किया जा सके कि उनमें अपेक्षित प्रकार की जानकारी है, सही ढंग से प्रारूपित है, और पैरामीटर पर यह सुनिश्चित करने के लिए कि वे अपेक्षित प्रकार के हैं। +इसे इनपुट सत्यापन कहा जाता है, और आदर्श रूप से pipeline चलाने की कोशिश करने से _पहले_ किया जाना चाहिए, बजाय यह पता लगाने के लिए pipeline के विफल होने की प्रतीक्षा करने के कि इनपुट के साथ कोई समस्या थी। + +कॉन्फ़िगरेशन की तरह, nf-core प्रोजेक्ट इनपुट सत्यापन के बारे में बहुत opinionated है, और [nf-schema plugin](https://nextflow-io.github.io/nf-schema/latest/) के उपयोग की सिफारिश करता है, एक Nextflow plugin जो Nextflow pipelines के लिए व्यापक सत्यापन क्षमताएं प्रदान करता है। + +हम इस पाठ्यक्रम के भाग 5 में इस विषय को अधिक विस्तार से कवर करेंगे। +अभी के लिए, बस जागरूक रहें कि उस उद्देश्य के लिए दो JSON फ़ाइलें प्रदान की गई हैं, `nextflow_schema.json` और `assets/schema_input.json`। + +`nextflow_schema.json` एक फ़ाइल है जिसका उपयोग pipeline पैरामीटर के बारे में जानकारी संग्रहीत करने के लिए किया जाता है जिसमें प्रकार, विवरण और machine readable format में सहायता text शामिल है। +इसका उपयोग विभिन्न उद्देश्यों के लिए किया जाता है, जिसमें स्वचालित पैरामीटर सत्यापन, सहायता text generation, और UI इंटरफेस में interactive पैरामीटर फॉर्म rendering शामिल है। + +`schema_input.json` एक फ़ाइल है जिसका उपयोग इनपुट samplesheet संरचना को परिभाषित करने के लिए किया जाता है। +प्रत्येक column का एक प्रकार, पैटर्न, विवरण और machine readable format में सहायता text हो सकता है। +स्कीमा का उपयोग विभिन्न उद्देश्यों के लिए किया जाता है, जिसमें स्वचालित सत्यापन और सहायक त्रुटि संदेश प्रदान करना शामिल है। + +### मुख्य बात + +आप जानते हैं कि nf-core pipeline के मुख्य घटक क्या हैं और कोड कैसे व्यवस्थित है; कॉन्फ़िगरेशन के मुख्य तत्व कहाँ स्थित हैं; और आप जागरूक हैं कि इनपुट सत्यापन किसके लिए है। + +### आगे क्या है? + +एक ब्रेक लें! वह बहुत कुछ था। जब आप तरोताज़ा महसूस करें और तैयार हों, तो एक nf-core compatible pipeline लिखने के लिए जो आपने सीखा है उसे लागू करने के लिए अगले अनुभाग पर जाएं। + +!!! tip + + यदि आप अगले भाग पर जाने से पहले subworkflows के साथ workflows बनाने का तरीका सीखना चाहते हैं, तो [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest देखें। diff --git a/docs/hi/docs/hello_nf-core/02_rewrite_hello.md b/docs/hi/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..6e225ea5e4 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1207 @@ +# भाग 2: nf-core के लिए Hello को फिर से लिखना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण पाठ्यक्रम के इस दूसरे भाग में, हम आपको दिखाते हैं कि [Hello Nextflow](../hello_nextflow/index.md) शुरुआती पाठ्यक्रम द्वारा तैयार की गई pipeline का nf-core संगत संस्करण कैसे बनाया जाए। + +आपने प्रशिक्षण के पहले भाग में देखा होगा कि nf-core pipelines काफी विस्तृत संरचना का पालन करते हैं जिसमें बहुत सारी सहायक फ़ाइलें होती हैं। +यह सब शुरू से बनाना बहुत थकाऊ होगा, इसलिए nf-core समुदाय ने इस प्रक्रिया को bootstrap करने के लिए एक template से यह करने के लिए tooling विकसित की है। + +हम आपको दिखाएंगे कि इस tooling का उपयोग करके pipeline scaffold कैसे बनाया जाए, फिर मौजूदा 'नियमित' pipeline कोड को nf-core scaffold पर कैसे अनुकूलित किया जाए। + +यदि आप Hello pipeline से परिचित नहीं हैं या आपको याद दिलाने की आवश्यकता है, तो [यह जानकारी पेज](../info/hello_pipeline.md) देखें। + +--- + +## 1. एक नया pipeline प्रोजेक्ट बनाएं + +सबसे पहले, हम नए pipeline के लिए scaffold बनाते हैं। + +!!! note "नोट" + + सुनिश्चित करें कि आप अपने terminal में `hello-nf-core` डायरेक्टरी में हैं। + +### 1.1. template-आधारित pipeline निर्माण tool चलाएं + +आइए `nf-core pipelines create` कमांड के साथ एक नया pipeline बनाकर शुरू करें। +यह nf-core base template का उपयोग करके एक नया pipeline scaffold बनाएगा, जिसे pipeline नाम, विवरण और लेखक के साथ अनुकूलित किया गया है। + +```bash +nf-core pipelines create +``` + +इस कमांड को चलाने से pipeline निर्माण के लिए एक Text User Interface (TUI) खुलेगा: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +यह TUI आपसे आपके pipeline के बारे में बुनियादी जानकारी प्रदान करने के लिए कहेगा और आपको अपने pipeline scaffold में शामिल करने या बाहर करने के लिए सुविधाओं का विकल्प प्रदान करेगा। + +- स्वागत स्क्रीन पर, **Let's go!** पर क्लिक करें। +- `Choose pipeline type` स्क्रीन पर, **Custom** पर क्लिक करें। +- अपनी pipeline का विवरण निम्नानुसार दर्ज करें (`< YOUR NAME >` को अपने नाम से बदलें), फिर **Next** पर क्लिक करें। + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < YOUR NAME > +``` + +- Template features स्क्रीन पर, `Toggle all features` को **off** पर सेट करें, फिर निम्नलिखित को चुनिंदा रूप से **enable** करें। अपने चयनों की जांच करें और **Continue** पर क्लिक करें। + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- `Final details` स्क्रीन पर, **Finish** पर क्लिक करें। Pipeline बनने तक प्रतीक्षा करें, फिर **Continue** पर क्लिक करें। +- Create GitHub repository स्क्रीन पर, **Finish without creating a repo** पर क्लिक करें। यह बाद में GitHub repository बनाने के निर्देश प्रदर्शित करेगा। इन्हें अनदेखा करें और **Close** पर क्लिक करें। + +एक बार TUI बंद हो जाने के बाद, आपको निम्नलिखित console output दिखाई देना चाहिए। + +??? success "कमांड आउटपुट" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +console output में कोई स्पष्ट पुष्टि नहीं है कि pipeline निर्माण सफल रहा, लेकिन आपको `core-hello` नाम की एक नई डायरेक्टरी दिखाई देनी चाहिए। + +नई डायरेक्टरी की सामग्री देखें कि template का उपयोग करके आपने अपने आप को कितना काम बचाया। + +```bash +tree core-hello +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +यह बहुत सारी फ़ाइलें हैं! + +उम्मीद है कि आप इनमें से बहुत सी को पहचान लेंगे क्योंकि हमने `nf-core/demo` pipeline संरचना की खोज करते समय इनका सामना किया था। +लेकिन चिंता न करें यदि आप अभी भी थोड़ा खोया हुआ महसूस कर रहे हैं; हम इस प्रशिक्षण के दौरान महत्वपूर्ण भागों के माध्यम से एक साथ चलेंगे। + +!!! note "नोट" + + `nf-core/demo` pipeline की तुलना में एक महत्वपूर्ण अंतर जिसे हमने इस प्रशिक्षण के पहले भाग में देखा था, यह है कि कोई `modules` डायरेक्टरी नहीं है। + ऐसा इसलिए है क्योंकि हमने डिफ़ॉल्ट nf-core modules में से किसी को भी शामिल करने का विकल्प नहीं चुना। + +### 1.2. जांचें कि scaffold कार्यात्मक है + +विश्वास करें या न करें, भले ही आपने अभी तक वास्तविक कार्य करने के लिए कोई modules नहीं जोड़े हैं, pipeline scaffold को वास्तव में test profile का उपयोग करके चलाया जा सकता है, उसी तरह जैसे हमने `nf-core/demo` pipeline चलाई थी। + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +यह आपको दिखाता है कि सभी बुनियादी wiring जगह पर है। +तो outputs कहाँ हैं? क्या कोई हैं? + +वास्तव में, `core-hello-results` नाम की परिणामों की एक नई डायरेक्टरी बनाई गई थी जिसमें मानक execution reports हैं: + +```bash +tree core-hello-results +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +आप देख सकते हैं कि क्या चलाया गया था, और जवाब है: बिल्कुल कुछ भी नहीं! + +![empty execution timeline report](./img/execution_timeline_empty.png) + +आइए देखें कि कोड में वास्तव में क्या है। + +### 1.3. placeholder workflow की जांच करें + +यदि आप `main.nf` फ़ाइल के अंदर देखें, तो आप देखेंगे कि यह `workflows/hello` से `HELLO` नाम की एक workflow को import करती है। + +यह भाग 1 में हमारे द्वारा आई `workflows/demo.nf` workflow के बराबर है, और हमारी रुचि की workflow के लिए एक placeholder के रूप में कार्य करती है, जिसमें कुछ nf-core कार्यक्षमता पहले से ही मौजूद है। + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Software versions को collate और save करें + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +[Hello Nextflow](../hello_nextflow/index.md) में विकसित की गई बुनियादी Nextflow workflow की तुलना में, आप कुछ चीजें देखेंगे जो यहाँ नई हैं (ऊपर highlighted पंक्तियाँ): + +- workflow block का एक नाम है +- Workflow inputs को `take:` keyword का उपयोग करके घोषित किया जाता है और channel निर्माण को parent workflow में ऊपर ले जाया जाता है +- Workflow सामग्री को `main:` block के अंदर रखा गया है +- Outputs को `emit:` keyword का उपयोग करके घोषित किया जाता है + +ये Nextflow की वैकल्पिक विशेषताएं हैं जो workflow को **composable** बनाती हैं, जिसका अर्थ है कि इसे किसी अन्य workflow के भीतर से बुलाया जा सकता है। + +!!! note "गहराई से Composable workflows" + + [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest workflow composition को बहुत अधिक गहराई से explore करता है, जिसमें कई workflows को एक साथ कैसे compose करें और उनके बीच जटिल डेटा flows को कैसे प्रबंधित करें शामिल है। हम यहां composability पेश कर रहे हैं क्योंकि यह nf-core template architecture की एक मौलिक आवश्यकता है, जो pipeline initialization, मुख्य analysis workflow, और completion tasks को अलग, पुन: प्रयोज्य components में व्यवस्थित करने के लिए nested workflows का उपयोग करती है। + +हमें अपनी रुचि की workflow से प्रासंगिक logic को उस संरचना में plug करने की आवश्यकता है। +इसके लिए पहला कदम हमारे मूल workflow को composable बनाना है। + +### निष्कर्ष + +अब आप जानते हैं कि nf-core tools का उपयोग करके pipeline scaffold कैसे बनाया जाए। + +### आगे क्या है? + +एक सरल workflow को composable बनाने का तरीका सीखें जो इसे nf-core संगत बनाने के लिए एक प्रस्तावना के रूप में है। + +--- + +## 2. मूल Hello Nextflow workflow को composable बनाएं + +अब अपने workflow को nf-core scaffold में integrate करने का समय आ गया है। +याद रखें, हम [Hello Nextflow](../hello_nextflow/index.md) प्रशिक्षण पाठ्यक्रम में दिखाई गई workflow के साथ काम कर रहे हैं। + +!!! tip "सुझाव" + + यदि आप उस pipeline से परिचित नहीं हैं या आपको याद दिलाने की आवश्यकता है, तो [The Hello pipeline](../info/hello_pipeline.md) देखें। + +हम आपको `original-hello` डायरेक्टरी में पूर्ण Hello Nextflow workflow की एक साफ, पूरी तरह से कार्यात्मक प्रति प्रदान करते हैं, इसके modules और डिफ़ॉल्ट CSV फ़ाइल के साथ जिसे यह इनपुट के रूप में उपयोग करने की अपेक्षा करती है। + +```bash +tree original-hello/ +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +अपने आप को संतुष्ट करने के लिए कि यह काम करता है, इसे चलाने के लिए स्वतंत्र महसूस करें: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +आइए कोड का निरीक्षण करने के लिए `hello.nf` workflow फ़ाइल खोलें, जो नीचे पूर्ण रूप से दिखाया गया है (processes को छोड़कर, जो modules में हैं): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Modules include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +जैसा कि आप देख सकते हैं, यह workflow एक साधारण unnamed workflow के रूप में लिखी गई थी जिसे अपने आप चलाया जा सकता है। +इसे parent workflow के भीतर से runnable बनाने के लिए जैसा कि nf-core template की आवश्यकता है, हमें इसे **composable** बनाने की आवश्यकता है। + +आइए आवश्यक बदलावों के माध्यम से एक-एक करके चलें। + +### 2.1. Workflow को नाम दें + +सबसे पहले, आइए workflow को एक नाम दें ताकि हम इसे parent workflow से संदर्भित कर सकें। + +=== "बाद में" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "पहले" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +वही conventions workflow नामों पर लागू होते हैं जो module नामों पर लागू होते हैं। + +### 2.2. Channel निर्माण को `take` से बदलें + +अब, channel निर्माण को एक साधारण `take` statement से बदलें जो अपेक्षित inputs घोषित करता है। + +=== "बाद में" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // अभिवादनों का channel + greeting_ch + ``` + +=== "पहले" + + ```groovy title="original-hello/hello.nf" linenums="18" + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +यह inputs कैसे प्रदान किए जाते हैं इसके विवरण को parent workflow पर छोड़ देता है। + +जब हम इस पर हैं, तो हम `params.greeting = 'greetings.csv'` लाइन को भी comment out कर सकते हैं + +=== "बाद में" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "पहले" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "नोट" + + यदि आपके पास Nextflow language server extension इंस्टॉल है, तो syntax checker आपके कोड को लाल squiggles के साथ light up करेगा। + ऐसा इसलिए है क्योंकि यदि आप `take:` statement डालते हैं, तो आपके पास `main:` भी होना चाहिए। + + हम इसे अगले चरण में जोड़ेंगे। + +### 2.3. Workflow operations से पहले `main` statement जोड़ें + +इसके बाद, workflow के body में बुलाए गए बाकी operations से पहले एक `main` statement जोड़ें। + +=== "बाद में" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art generate करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "पहले" + + ```groovy title="original-hello/hello.nf" linenums="21" + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art generate करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +यह मूल रूप से कहता है 'यह वह है जो यह workflow _करता है_'। + +### 2.4. `emit` statement जोड़ें + +अंत में, एक `emit` statement जोड़ें जो घोषित करता है कि workflow के अंतिम outputs क्या हैं। + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +यह मूल workflow की तुलना में कोड में एक नया जोड़ है। + +### 2.5. पूर्ण किए गए बदलावों का सारांश + +यदि आपने सभी बदलाव वर्णित के अनुसार किए हैं, तो आपकी workflow अब इस तरह दिखनी चाहिए: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' (comment out किया गया) +params.batch = 'test-batch' +params.character = 'turkey' + +// Modules include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // channel of greetings + greeting_ch + + main: + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +यह Nextflow को वह सब कुछ बताता है जो चाहिए सिवाय इनपुट channel में क्या feed करना है। +यह parent workflow में परिभाषित किया जाएगा, जिसे **entrypoint** workflow भी कहा जाता है। + +### 2.6. एक dummy entrypoint workflow बनाएं + +अपने composable workflow को जटिल nf-core scaffold में integrate करने से पहले, आइए सत्यापित करें कि यह सही तरीके से काम करता है। +हम isolation में composable workflow का परीक्षण करने के लिए एक साधारण dummy entrypoint workflow बना सकते हैं। + +उसी `original-hello` डायरेक्टरी में `main.nf` नाम की एक blank फ़ाइल बनाएं। + +```bash +touch original-hello/main.nf +``` + +निम्नलिखित कोड को `main.nf` फ़ाइल में copy करें। + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// hello.nf फ़ाइल से workflow code import करें +include { HELLO } from './hello.nf' + +// इनपुट पैरामीटर घोषित करें +params.greeting = 'greetings.csv' + +workflow { + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // अभिवादनों के channel पर imported workflow को call करें + HELLO(greeting_ch) + + // workflow द्वारा emit किए गए outputs देखें + HELLO.out.view { output -> "Output: $output" } +} +``` + +यहां दो महत्वपूर्ण अवलोकन हैं: + +- Imported workflow को बुलाने के लिए syntax मूल रूप से modules को बुलाने के लिए syntax के समान है। +- वह सब कुछ जो inputs को workflow में खींचने से संबंधित है (इनपुट पैरामीटर और channel निर्माण) अब इस parent workflow में घोषित किया गया है। + +!!! note "नोट" + + Entrypoint workflow फ़ाइल का नाम `main.nf` रखना एक convention है, आवश्यकता नहीं। + + यदि आप इस convention का पालन करते हैं, तो आप अपने `nextflow run` कमांड में workflow फ़ाइल का नाम निर्दिष्ट करना छोड़ सकते हैं। + Nextflow स्वचालित रूप से execution डायरेक्टरी में `main.nf` नाम की फ़ाइल की तलाश करेगा। + + हालाँकि, यदि आप चाहें तो entrypoint workflow फ़ाइल को कुछ और नाम दे सकते हैं। + उस स्थिति में, अपने `nextflow run` कमांड में workflow फ़ाइल का नाम निर्दिष्ट करना सुनिश्चित करें। + +### 2.7. जांचें कि workflow चलता है + +अंत में हमारे पास वह सभी टुकड़े हैं जो हमें यह सत्यापित करने के लिए चाहिए कि composable workflow काम करता है। +आइए इसे चलाएं! + +```bash +nextflow run ./original-hello +``` + +यहां आप `main.nf` naming convention का उपयोग करने का लाभ देखते हैं। +यदि हमने entrypoint workflow को `something_else.nf` नाम दिया होता, तो हमें `nextflow run original-hello/something_else.nf` करना पड़ता। + +यदि आपने सभी बदलाव सही तरीके से किए हैं, तो यह पूरा होने तक चलना चाहिए। + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +इसका मतलब है कि हमने सफलतापूर्वक अपने HELLO workflow को composable बनाने के लिए upgrade किया है। + +### निष्कर्ष + +आप जानते हैं कि इसे एक नाम देकर और `take`, `main` और `emit` statements जोड़कर एक workflow को composable कैसे बनाया जाए, और इसे entrypoint workflow से कैसे बुलाया जाए। + +### आगे क्या है? + +जानें कि एक बुनियादी composable workflow को nf-core scaffold पर कैसे graft किया जाए। + +--- + +## 3. Updated workflow logic को placeholder workflow में fit करें + +अब जब हमने सत्यापित कर लिया है कि हमारी composable workflow सही तरीके से काम करती है, तो आइए section 1 में बनाए गए nf-core pipeline scaffold पर लौटें। +हम अभी विकसित की गई composable workflow को nf-core template संरचना में integrate करना चाहते हैं, इसलिए अंतिम परिणाम कुछ इस तरह दिखना चाहिए। + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +तो हम इसे कैसे होने देते हैं? आइए `core-hello/workflows/hello.nf` (nf-core scaffold) में `HELLO` workflow की वर्तमान सामग्री देखें। + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Software versions को collate और save करें + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +कुल मिलाकर यह कोड बहुत कम करता है, कुछ housekeeping के अलावा जो pipeline में चलने वाले किसी भी software tools के version को capture करने से संबंधित है। + +हमें section 2 में विकसित मूल workflow के composable संस्करण से प्रासंगिक कोड जोड़ने की आवश्यकता है। + +हम इसे निम्नलिखित चरणों में निपटाने जा रहे हैं: + +1. Modules को copy करें और module imports सेट अप करें +2. `take` घोषणा को जैसा है वैसा छोड़ दें +3. `main` block में workflow logic जोड़ें +4. `emit` block को अपडेट करें + +!!! note "नोट" + + हम इस पहले pass के लिए version capture को ignore करने जा रहे हैं और बाद में इस प्रशिक्षण के एक भाग में देखेंगे कि इसे कैसे wire up किया जाए। + +### 3.1. Modules को copy करें और module imports सेट अप करें + +हमारी Hello Nextflow workflow के चार processes `original-hello/modules/` में modules के रूप में संग्रहीत हैं। +हमें उन modules को nf-core project संरचना (`core-hello/modules/local/` के तहत) में copy करने और nf-core workflow फ़ाइल में import statements जोड़ने की आवश्यकता है। + +पहले आइए module फ़ाइलों को `original-hello/` से `core-hello/` में copy करें: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +अब आपको `core-hello/` के तहत modules की डायरेक्टरी सूचीबद्ध दिखाई देनी चाहिए। + +```bash +tree core-hello/modules +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +अब आइए module import statements सेट अप करें। + +ये `original-hello/hello.nf` workflow में import statements थे: + +```groovy title="original-hello/hello.nf" linenums="9" +// Modules include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +`core-hello/workflows/hello.nf` फ़ाइल खोलें और उन import statements को नीचे दिखाए अनुसार इसमें transpose करें। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +यहां दो और दिलचस्प अवलोकन हैं: + +- हमने nf-core style convention का पालन करने के लिए import statements की formatting को अनुकूलित किया है। +- हमने modules के relative paths को यह reflect करने के लिए अपडेट किया है कि वे अब nesting के एक अलग स्तर पर संग्रहीत हैं। + +### 3.2. `take` घोषणा को जैसा है वैसा छोड़ दें + +nf-core project में samplesheet की अवधारणा के आसपास बहुत सारी पूर्व-निर्मित कार्यक्षमता है, जो आमतौर पर columnar डेटा वाली एक CSV फ़ाइल है। +चूंकि यह मूल रूप से वही है जो हमारी `greetings.csv` फ़ाइल है, हम वर्तमान `take` घोषणा को जैसा है वैसा रखेंगे, और अगले चरण में बस इनपुट channel के नाम को अपडेट करेंगे। + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +इनपुट handling इस workflow के upstream में की जाएगी (इस कोड फ़ाइल में नहीं)। + +### 3.3. `main` block में workflow logic जोड़ें + +अब जब हमारे modules workflow के लिए उपलब्ध हैं, तो हम workflow logic को `main` block में plug कर सकते हैं। + +एक reminder के रूप में, यह मूल workflow में प्रासंगिक कोड है, जो जब हमने इसे composable बनाया तो बहुत अधिक नहीं बदला (हमने बस `main:` लाइन जोड़ी): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) +``` + +हमें `main:` के बाद आने वाले कोड को workflow के नए संस्करण में copy करने की आवश्यकता है। + +इसमें पहले से ही कुछ कोड है जो workflow द्वारा चलाए जाने वाले tools के versions को capture करने से संबंधित है। हम अभी के लिए इसे अकेला छोड़ने जा रहे हैं (हम बाद में tool versions से निपटेंगे)। +हम शीर्ष पर `ch_versions = channel.empty()` initialization रखेंगे, फिर अपना workflow logic insert करेंगे, अंत में version collation कोड रखेंगे। +यह ordering समझ में आता है क्योंकि एक वास्तविक pipeline में, processes version information emit करेंगे जो workflow चलने के दौरान `ch_versions` channel में जोड़ी जाएगी। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art generate करें + cowpy(collectGreetings.out.outfile, params.character) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +आप ध्यान देंगे कि हमने कोड को अधिक readable बनाने के लिए `main:` से पहले एक blank लाइन भी जोड़ी। + +यह बहुत अच्छा लगता है, लेकिन हमें अभी भी `sayHello()` process को pass किए जाने वाले channel के नाम को `greeting_ch` से `ch_samplesheet` में अपडेट करने की आवश्यकता है जैसा कि नीचे दिखाया गया है, `take:` keyword के तहत लिखे गए से match करने के लिए। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // एक अभिवादन emit करें (nf-core samplesheet convention का उपयोग करने के लिए अपडेट किया गया) + sayHello(ch_samplesheet) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // एक अभिवादन emit करें + sayHello(greeting_ch) + ``` + +अब workflow logic सही तरीके से wired up है। + +### 3.4. `emit` block को अपडेट करें + +अंत में, हमें workflow के अंतिम outputs की घोषणा शामिल करने के लिए `emit` block को अपडेट करने की आवश्यकता है। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +यह उन संशोधनों को पूरा करता है जो हमें HELLO workflow के लिए करने की आवश्यकता है। +इस बिंदु पर, हमने उस समग्र कोड संरचना को प्राप्त कर लिया है जिसे हमने लागू करने के लिए निर्धारित किया था। + +### निष्कर्ष + +आप जानते हैं कि एक composable workflow के मुख्य टुकड़ों को nf-core placeholder workflow में कैसे fit किया जाए। + +### आगे क्या है? + +जानें कि nf-core pipeline scaffold में inputs को कैसे handle किया जाता है, इसे कैसे अनुकूलित करें। + +--- + +## 4. इनपुट handling को अनुकूलित करें + +अब जब हमने सफलतापूर्वक अपने workflow logic को nf-core scaffold में integrate कर लिया है, तो हमें एक और महत्वपूर्ण टुकड़े को संबोधित करने की आवश्यकता है: यह सुनिश्चित करना कि हमारा इनपुट डेटा सही तरीके से processed हो। +nf-core template जटिल genomics datasets के लिए डिज़ाइन की गई परिष्कृत इनपुट handling के साथ आता है, इसलिए हमें इसे अपनी सरल `greetings.csv` फ़ाइल के साथ काम करने के लिए अनुकूलित करने की आवश्यकता है। + +### 4.1. पहचानें कि inputs कहाँ handle किए जाते हैं + +पहला कदम यह पता लगाना है कि इनपुट handling कहाँ की जाती है। + +आपको याद होगा कि जब हमने Hello Nextflow workflow को composable बनाने के लिए फिर से लिखा था, तो हमने इनपुट पैरामीटर घोषणा को एक स्तर ऊपर, `main.nf` entrypoint workflow में ले जाया था। +तो आइए pipeline scaffold के हिस्से के रूप में बनाई गई शीर्ष स्तर `main.nf` entrypoint workflow देखें: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: इनपुट के प्रकार के आधार पर मुख्य analysis pipeline चलाएं +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Pipeline चलाएं + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Initialisation tasks चलाएं + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: मुख्य workflow चलाएं + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Completion tasks चलाएं + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +nf-core project nested subworkflows का भारी उपयोग करता है, इसलिए यह bit पहले approach पर थोड़ा confusing हो सकता है। + +यहाँ जो मायने रखता है वह यह है कि दो workflows परिभाषित हैं: + +- `CORE_HELLO` `core-hello/workflows/hello.nf` में HELLO workflow को चलाने के लिए एक thin wrapper है जिसे हमने अभी अनुकूलित करना समाप्त किया। +- एक unnamed workflow जो `CORE_HELLO` के साथ-साथ दो अन्य subworkflows, `PIPELINE_INITIALISATION` और `PIPELINE_COMPLETION` को call करता है। + +यहां एक diagram है कि वे एक दूसरे से कैसे संबंधित हैं: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +महत्वपूर्ण रूप से, हम इस स्तर पर कोई इनपुट channel construct करने वाला कोड नहीं पा सकते हैं, केवल `--input` पैरामीटर के माध्यम से प्रदान की गई samplesheet के संदर्भ। + +थोड़ा poke around करने से पता चलता है कि इनपुट handling `PIPELINE_INITIALISATION` subworkflow द्वारा की जाती है, उपयुक्त रूप से, जिसे `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf` से import किया जाता है। + +यदि हम उस फ़ाइल को खोलें और नीचे scroll करें, तो हम कोड के इस chunk पर आते हैं: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // params.input के माध्यम से प्रदान की गई इनपुट फ़ाइल से channel बनाएं + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +यह channel factory है जो samplesheet को parse करती है और इसे उस रूप में pass करती है जो HELLO workflow द्वारा consume करने के लिए तैयार है। + +!!! note "नोट" + + ऊपर दिया गया syntax हमने पहले उपयोग किए गए से थोड़ा अलग है, लेकिन मूल रूप से यह: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + इसके बराबर है: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +इस कोड में कुछ parsing और validation चरण शामिल हैं जो nf-core pipeline template के साथ शामिल उदाहरण samplesheet के लिए अत्यधिक specific हैं, जो लेखन के समय बहुत domain-specific है और हमारे सरल pipeline project के लिए उपयुक्त नहीं है। + +### 4.2. Templated इनपुट channel कोड को बदलें + +अच्छी खबर यह है कि हमारी pipeline की ज़रूरतें बहुत सरल हैं, इसलिए हम उस सभी को channel निर्माण कोड से बदल सकते हैं जो हमने मूल Hello Nextflow workflow में विकसित किया था। + +एक reminder के रूप में, यह channel निर्माण कैसा दिखता था (जैसा कि solutions डायरेक्टरी में देखा गया है): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +तो हमें बस इसे initialisation workflow में plug करने की आवश्यकता है, मामूली बदलावों के साथ: हम channel का नाम `greeting_ch` से `ch_samplesheet` में अपडेट करते हैं, और पैरामीटर नाम `params.greeting` से `params.input` में (highlighted लाइन देखें)। + +=== "बाद में" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // params.input के माध्यम से प्रदान की गई इनपुट फ़ाइल से channel बनाएं + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "पहले" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // params.input के माध्यम से प्रदान की गई इनपुट फ़ाइल से channel बनाएं + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +यह उन बदलावों को पूरा करता है जो हमें इनपुट processing को काम करने के लिए करने की आवश्यकता है। + +इसके वर्तमान रू diff --git a/docs/hi/docs/hello_nf-core/03_use_module.md b/docs/hi/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..6009de90f8 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# भाग 3: एक nf-core मॉड्यूल का उपयोग करें + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण पाठ्यक्रम के इस तीसरे भाग में, हम आपको दिखाते हैं कि अपनी pipeline में मौजूदा nf-core मॉड्यूल को कैसे खोजें, इंस्टॉल करें, और उपयोग करें। + +nf-core के साथ काम करने के महान लाभों में से एक [nf-core/modules](https://github.com/nf-core/modules) रिपॉजिटरी से पूर्व-निर्मित, परीक्षित मॉड्यूल का लाभ उठाने की क्षमता है। +हर process को शुरू से लिखने के बजाय, आप community द्वारा maintain किए गए मॉड्यूल इंस्टॉल और उपयोग कर सकते हैं जो सर्वोत्तम प्रथाओं का पालन करते हैं। + +यह कैसे काम करता है यह दिखाने के लिए, हम `core-hello` pipeline में nf-core/modules से `cat/cat` मॉड्यूल के साथ कस्टम `collectGreetings` मॉड्यूल को बदलेंगे। + +??? info "इस सेक्शन से कैसे शुरू करें" + + पाठ्यक्रम का यह सेक्शन मानता है कि आपने [भाग 2: nf-core के लिए Hello को फिर से लिखें](./02_rewrite_hello.md) पूरा कर लिया है और आपके पास एक कार्यशील `core-hello` pipeline है। + + यदि आपने भाग 2 पूरा नहीं किया है या इस भाग के लिए नए सिरे से शुरू करना चाहते हैं, तो आप अपने शुरुआती बिंदु के रूप में `core-hello-part2` समाधान का उपयोग कर सकते हैं। + `hello-nf-core/` डायरेक्टरी के अंदर से यह कमांड चलाएं: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + यह आपको मॉड्यूल जोड़ने के लिए तैयार एक पूरी तरह से कार्यात्मक nf-core pipeline देता है। + आप निम्नलिखित कमांड चलाकर परीक्षण कर सकते हैं कि यह सफलतापूर्वक चलता है: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. एक उपयुक्त nf-core मॉड्यूल खोजें और इंस्टॉल करें + +सबसे पहले, आइए सीखें कि मौजूदा nf-core मॉड्यूल कैसे खोजें और इसे अपनी pipeline में इंस्टॉल करें। + +हम `collectGreetings` process को बदलने का लक्ष्य रखेंगे, जो एक फ़ाइल में कई greeting फ़ाइलों को जोड़ने के लिए Unix `cat` कमांड का उपयोग करता है। +फ़ाइलों को जोड़ना एक बहुत ही सामान्य ऑपरेशन है, इसलिए यह तर्कसंगत है कि nf-core में पहले से ही उस उद्देश्य के लिए डिज़ाइन किया गया एक मॉड्यूल हो सकता है। + +आइए शुरू करें। + +### 1.1. nf-core वेबसाइट पर उपलब्ध मॉड्यूल ब्राउज़ करें + +nf-core प्रोजेक्ट [https://nf-co.re/modules](https://nf-co.re/modules) पर मॉड्यूल की एक केंद्रीकृत सूची maintain करता है। + +अपने web browser में मॉड्यूल पेज पर जाएं और 'concatenate' खोजने के लिए search bar का उपयोग करें। + +![module search results](./img/module-search-results.png) + +जैसा कि आप देख सकते हैं, काफी कुछ परिणाम हैं, उनमें से कई बहुत विशिष्ट प्रकार की फ़ाइलों को जोड़ने के लिए डिज़ाइन किए गए मॉड्यूल हैं। +उनमें से, आपको `cat_cat` नामक एक सामान्य-उद्देश्य मॉड्यूल दिखाई देना चाहिए। + +!!! note "मॉड्यूल नामकरण परंपरा" + + underscore (`_`) का उपयोग मॉड्यूल नामों में slash (`/`) वर्ण के स्थान पर किया जाता है। + + nf-core मॉड्यूल `software/command` नामकरण परंपरा का पालन करते हैं जब कोई tool कई कमांड प्रदान करता है, जैसे `samtools/view` (samtools पैकेज, view कमांड) या `gatk/haplotypecaller` (GATK पैकेज, HaplotypeCaller कमांड)। + उन tools के लिए जो केवल एक मुख्य कमांड प्रदान करते हैं, मॉड्यूल `fastqc` या `multiqc` जैसे एकल स्तर का उपयोग करते हैं। + +मॉड्यूल दस्तावेज़ देखने के लिए `cat_cat` मॉड्यूल बॉक्स पर क्लिक करें। + +मॉड्यूल पेज दिखाता है: + +- एक संक्षिप्त विवरण: "A module for concatenation of gzipped or uncompressed files" +- इंस्टॉलेशन कमांड: `nf-core modules install cat/cat` +- Input और output channel संरचना +- उपलब्ध पैरामीटर + +### 1.2. कमांड लाइन से उपलब्ध मॉड्यूल की सूची बनाएं + +वैकल्पिक रूप से, आप nf-core tools का उपयोग करके सीधे कमांड लाइन से भी मॉड्यूल खोज सकते हैं। + +```bash +nf-core modules list remote +``` + +यह nf-core/modules रिपॉजिटरी में सभी उपलब्ध मॉड्यूल की एक सूची प्रदर्शित करेगा, हालांकि यह थोड़ा कम सुविधाजनक है यदि आप पहले से उस मॉड्यूल का नाम नहीं जानते हैं जिसे आप खोज रहे हैं। +हालाँकि, यदि आप जानते हैं, तो आप विशिष्ट मॉड्यूल खोजने के लिए सूची को `grep` में pipe कर सकते हैं: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "कमांड आउटपुट" + + ```console + │ cat/cat + ``` + +बस ध्यान रखें कि `grep` दृष्टिकोण केवल उन परिणामों को निकालेगा जिनके नाम में खोज शब्द है, जो `cat_cat` के लिए काम नहीं करेगा। + +### 1.3. मॉड्यूल के बारे में विस्तृत जानकारी प्राप्त करें + +कमांड लाइन से किसी विशिष्ट मॉड्यूल के बारे में विस्तृत जानकारी देखने के लिए, `info` कमांड का उपयोग करें: + +```bash +nf-core modules info cat/cat +``` + +यह मॉड्यूल के बारे में दस्तावेज़ प्रदर्शित करता है, जिसमें इसके inputs, outputs, और बुनियादी उपयोग जानकारी शामिल है। + +??? success "कमांड आउटपुट" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +यह वही जानकारी है जो आप वेबसाइट पर पा सकते हैं। + +### 1.4. cat/cat मॉड्यूल इंस्टॉल करें + +अब जब हमें वह मॉड्यूल मिल गया है जो हम चाहते हैं, तो हमें इसे अपनी pipeline के source code में जोड़ना होगा। + +अच्छी खबर यह है कि nf-core प्रोजेक्ट में कुछ tooling शामिल है जो इस भाग को आसान बनाती है। +विशेष रूप से, `nf-core modules install` कमांड code को retrieve करने और इसे एक ही चरण में आपके प्रोजेक्ट के लिए उपलब्ध कराने को automate करना संभव बनाता है। + +अपनी pipeline डायरेक्टरी में जाएं और इंस्टॉलेशन कमांड चलाएं: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +tool पहले आपको repository प्रकार निर्दिष्ट करने के लिए कह सकता है। +(यदि नहीं, तो "अंत में, tool मॉड्यूल इंस्टॉल करने के लिए आगे बढ़ेगा।" पर नीचे जाएं।) + +??? success "कमांड आउटपुट" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +यदि ऐसा है, तो default प्रतिक्रिया (`Pipeline`) स्वीकार करने के लिए enter दबाएं और जारी रखें। + +tool तब भविष्य में इस prompt से बचने के लिए आपके प्रोजेक्ट के configuration में संशोधन करने की पेशकश करेगा। + +??? success "कमांड आउटपुट" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +इस सुविधाजनक tooling का लाभ उठाना भी उचित है! +default प्रतिक्रिया (हाँ) स्वीकार करने के लिए enter दबाएं। + +अंत में, tool मॉड्यूल इंस्टॉल करने के लिए आगे बढ़ेगा। + +??? success "कमांड आउटपुट" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +कमांड स्वचालित रूप से: + +- मॉड्यूल फ़ाइलों को `modules/nf-core/cat/cat/` में डाउनलोड करता है +- इंस्टॉल किए गए मॉड्यूल को ट्रैक करने के लिए `modules.json` को अपडेट करता है +- आपको अपने workflow में उपयोग करने के लिए सही `include` statement प्रदान करता है + +!!! tip + + मॉड्यूल इंस्टॉलेशन कमांड चलाने से पहले हमेशा सुनिश्चित करें कि आपकी वर्तमान working डायरेक्टरी आपके pipeline प्रोजेक्ट की root है। + +आइए जांचें कि मॉड्यूल सही तरीके से इंस्टॉल किया गया था: + +```bash +tree -L 4 modules +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +आप स्थानीय रूप से इंस्टॉल किए गए मॉड्यूल को सूचीबद्ध करने के लिए nf-core utility से पूछकर भी इंस्टॉलेशन को सत्यापित कर सकते हैं: + +```bash +nf-core modules list local +``` + +??? success "कमांड आउटपुट" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +यह पुष्टि करता है कि `cat/cat` मॉड्यूल अब आपके प्रोजेक्ट के source code का हिस्सा है। + +हालाँकि, वास्तव में नए मॉड्यूल का उपयोग करने के लिए, हमें इसे अपनी pipeline में import करना होगा। + +### 1.5. मॉड्यूल imports को अपडेट करें + +आइए `workflows/hello.nf` workflow के imports सेक्शन में `collectGreetings` मॉड्यूल के लिए `include` statement को `CAT_CAT` के लिए वाले से बदलें। + +याद दिलाने के लिए, मॉड्यूल install tool ने हमें उपयोग करने के लिए सटीक statement दिया: + +```groovy title="install कमांड द्वारा निर्मित Import statement" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +ध्यान दें कि nf-core परंपरा मॉड्यूल को import करते समय मॉड्यूल नामों के लिए uppercase का उपयोग करना है। + +[core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) खोलें और निम्नलिखित प्रतिस्थापन करें: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +ध्यान दें कि nf-core मॉड्यूल के लिए path local मॉड्यूल से कैसे भिन्न है: + +- **nf-core मॉड्यूल**: `'../modules/nf-core/cat/cat/main'` (`main.nf` को संदर्भित करता है) +- **Local मॉड्यूल**: `'../modules/local/collectGreetings.nf'` (एकल फ़ाइल संदर्भ) + +मॉड्यूल अब workflow के लिए उपलब्ध है, इसलिए हमें बस `collectGreetings` की call को `CAT_CAT` का उपयोग करने के लिए swap करना है। सही? + +इतनी जल्दी नहीं। + +इस बिंदु पर, आप कूदने और code संपादित करना शुरू करने के लिए प्रेरित हो सकते हैं, लेकिन यह ध्यान से जांचने के लिए एक पल लेने लायक है कि नया मॉड्यूल क्या अपेक्षा करता है और यह क्या उत्पन्न करता है। + +हम इसे एक अलग सेक्शन के रूप में निपटाने जा रहे हैं क्योंकि इसमें एक नया तंत्र शामिल है जिसे हमने अभी तक कवर नहीं किया है: metadata maps। + +!!! note + + आप वैकल्पिक रूप से `collectGreetings.nf` फ़ाइल को हटा सकते हैं: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + हालाँकि, आप इसे local और nf-core मॉड्यूल के बीच अंतर को समझने के लिए एक संदर्भ के रूप में रखना चाह सकते हैं। + +### निष्कर्ष + +आप जानते हैं कि nf-core मॉड्यूल कैसे खोजें और इसे अपने प्रोजेक्ट के लिए उपलब्ध कैसे कराएं। + +### आगे क्या है? + +आकलन करें कि एक नया मॉड्यूल क्या आवश्यक है और इसे pipeline में integrate करने के लिए किसी भी महत्वपूर्ण परिवर्तन की पहचान करें। + +--- + +## 2. नए मॉड्यूल की आवश्यकताओं का आकलन करें + +विशेष रूप से, हमें मॉड्यूल के **interface** की जांच करने की आवश्यकता है, अर्थात इसकी input और output definitions, और इसकी तुलना उस मॉड्यूल के interface से करनी होगी जिसे हम बदलना चाह रहे हैं। +यह हमें यह निर्धारित करने की अनुमति देगा कि क्या हम नए मॉड्यूल को केवल एक drop-in replacement के रूप में treat कर सकते हैं या क्या हमें wiring के कुछ हिस्सों को adapt करने की आवश्यकता होगी। + +आदर्श रूप से यह कुछ ऐसा है जो आपको मॉड्यूल इंस्टॉल करने से _पहले_ भी करना चाहिए, लेकिन अरे, देर से बेहतर कभी नहीं। +(क्या यह मायने रखता है, उन मॉड्यूल से छुटकारा पाने के लिए एक `uninstall` कमांड है जिन्हें आप तय करते हैं कि आप अब नहीं चाहते हैं।) + +!!! note + + CAT_CAT process में विभिन्न compression प्रकारों, फ़ाइल extensions इत्यादि की कुछ चतुर handling शामिल है जो सख्ती से हम आपको यहां दिखाने की कोशिश कर रहे हैं उससे संबंधित नहीं हैं, इसलिए हम इसमें से अधिकांश को ignore करेंगे और केवल उन हिस्सों पर ध्यान केंद्रित करेंगे जो महत्वपूर्ण हैं। + +### 2.1. दोनों मॉड्यूल के interfaces की तुलना करें + +याद दिलाने के लिए, यह है कि हमारे `collectGreetings` मॉड्यूल का interface कैसा दिखता है: + +```groovy title="modules/local/collectGreetings.nf (अंश)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +`collectGreetings` मॉड्यूल दो inputs लेता है: + +- `input_files` में process करने के लिए एक या अधिक input फ़ाइलें होती हैं; +- `batch_name` एक value है जिसका उपयोग हम output फ़ाइल को एक run-specific नाम देने के लिए करते हैं, जो metadata का एक रूप है। + +पूर्ण होने पर, `collectGreetings` एकल file path आउटपुट करता है, जो `outfile` tag के साथ emit किया जाता है। + +तुलना में, `cat/cat` मॉड्यूल का interface अधिक जटिल है: + +```groovy title="modules/nf-core/cat/cat/main.nf (अंश)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +CAT_CAT मॉड्यूल एक एकल input लेता है, लेकिन वह input एक tuple है जिसमें दो चीजें हैं: + +- `meta` एक संरचना है जिसमें metadata होता है, जिसे metamap कहा जाता है; +- `files_in` में process करने के लिए एक या अधिक input फ़ाइलें होती हैं, जो `collectGreetings` के `input_files` के बराबर हैं। + +पूर्ण होने पर, CAT_CAT अपने outputs दो भागों में देता है: + +- एक और tuple जिसमें metamap और concatenated output फ़ाइल होती है, `file_out` tag के साथ emit की गई; +- एक `versions.yml` फ़ाइल जो उपयोग किए गए software version के बारे में जानकारी capture करती है, `versions` tag के साथ emit की गई। + +यह भी ध्यान दें कि default रूप से, output फ़ाइल का नाम metadata का हिस्सा है एक identifier के आधार पर होगा (code यहाँ नहीं दिखाया गया है)। + +केवल code को देखते हुए यह बहुत कुछ ट्रैक करने के लिए लग सकता है, इसलिए यहां एक diagram है जो आपको सब कुछ एक साथ कैसे फिट होता है यह visualize करने में मदद करने के लिए है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +आप देख सकते हैं कि दोनों मॉड्यूल की सामग्री के संदर्भ में समान input आवश्यकताएं हैं (input फ़ाइलों का एक सेट प्लस कुछ metadata) लेकिन उस सामग्री को कैसे package किया जाता है, इसके लिए बहुत अलग अपेक्षाएं हैं। +अभी के लिए versions फ़ाइल को ignore करते हुए, उनका मुख्य output भी समतुल्य है (एक concatenated फ़ाइल), सिवाय CAT_CAT output फ़ाइल के संयोजन में metamap को भी emit करता है। + +packaging के अंतर को संभालना काफी आसान होगा, जैसा कि आप थोड़ी देर में देखेंगे। +हालाँकि, metamap भाग को समझने के लिए, हमें आपको कुछ अतिरिक्त संदर्भ से परिचित कराने की आवश्यकता है। + +### 2.2. Metamaps को समझना + +हमने अभी आपको बताया कि CAT_CAT मॉड्यूल अपने input tuple के हिस्से के रूप में एक metadata map की अपेक्षा करता है। +आइए कुछ मिनट लें और गहराई से देखें कि वह क्या है। + +**metadata map**, जिसे अक्सर संक्षेप में **metamap** कहा जाता है, data की units के बारे में जानकारी वाला एक Groovy-style map है। +Nextflow pipelines के संदर्भ में, data की units कुछ भी हो सकती हैं जो आप चाहते हैं: व्यक्तिगत नमूने, नमूनों के batches, या संपूर्ण datasets। + +परंपरा के अनुसार, एक nf-core metamap का नाम `meta` है और इसमें आवश्यक field `id` होता है, जिसका उपयोग outputs का नामकरण और data की units को ट्रैक करने के लिए किया जाता है। + +उदाहरण के लिए, एक विशिष्ट metadata map इस तरह दिख सकता है: + +```groovy title="sample-level metamap का उदाहरण" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +या एक मामले में जहां metadata batch स्तर पर attached है: + +```groovy title="batch-level metamap का उदाहरण" +[id: 'batch1', date: '25.10.01'] +``` + +अब आइए इसे `CAT_CAT` process के संदर्भ में रखें, जो input फ़ाइलों को metamap के साथ tuple में package किए जाने की अपेक्षा करता है, और output tuple के हिस्से के रूप में metamap को भी आउटपुट करता है। + +```groovy title="modules/nf-core/cat/cat/main.nf (अंश)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +परिणामस्वरूप, data की प्रत्येक unit संबंधित metadata के साथ जुड़ी हुई pipeline के माध्यम से यात्रा करती है। +बाद की processes तब उस metadata को भी आसानी से access कर सकती हैं। + +याद है कि कैसे हमने आपको बताया कि `CAT_CAT` द्वारा आउटपुट की गई फ़ाइल का नाम metadata का हिस्सा है एक identifier के आधार पर होगा? +यह संबंधित code है: + +```groovy title="modules/nf-core/cat/cat/main.nf (अंश)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +यह मोटे तौर पर इस प्रकार अनुवादित होता है: यदि external task पैरामीटर प्रणाली (`task.ext`) के माध्यम से एक `prefix` प्रदान किया जाता है, तो output फ़ाइल का नाम रखने के लिए उसका उपयोग करें; अन्यथा `${meta.id}` का उपयोग करके एक बनाएं, जो metamap में `id` field से मेल खाता है। + +आप इस तरह की सामग्री के साथ इस मॉड्यूल में आने वाली input channel की कल्पना कर सकते हैं: + +```groovy title="उदाहरण input channel सामग्री" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +फिर output channel सामग्री इस तरह बाहर आती है: + +```groovy title="उदाहरण output channel सामग्री" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +जैसा कि पहले उल्लेख किया गया है, `tuple val(meta), path(files_in)` input setup सभी nf-core मॉड्यूल में उपयोग किया जाने वाला एक मानक pattern है। + +उम्मीद है कि आप यह देखना शुरू कर सकते हैं कि यह कितना उपयोगी हो सकता है। +न केवल यह आपको metadata के आधार पर outputs का नाम रखने की अनुमति देता है, बल्कि आप विभिन्न पैरामीटर values लागू करने जैसी चीजें भी कर सकते हैं, और specific operators के संयोजन में, आप data को group, sort या filter भी कर सकते हैं क्योंकि यह pipeline के माध्यम से flows करता है। + +!!! note "Metadata के बारे में अधिक जानें" + + Nextflow workflows में metadata के साथ काम करने के लिए एक व्यापक परिचय के लिए, जिसमें samplesheets से metadata को कैसे पढ़ें और processing को customize करने के लिए इसका उपयोग कैसे करें, [workflows में Metadata](../side_quests/metadata) side quest देखें। + +### 2.3. किए जाने वाले परिवर्तनों का सारांश दें + +जो हमने समीक्षा की है उसके आधार पर, ये वे प्रमुख परिवर्तन हैं जो हमें `cat/cat` मॉड्यूल का उपयोग करने के लिए अपनी pipeline में करने की आवश्यकता है: + +- Batch name वाला एक metamap बनाएं; +- Concatenate करने के लिए input फ़ाइलों के सेट (convertToUpper से आ रही) के साथ metamap को एक tuple में package करें; +- `collectGreetings()` से `CAT_CAT` में call switch करें; +- `CAT_CAT` process द्वारा निर्मित tuple से output फ़ाइल को `cowpy` में पास करने से पहले extract करें। + +बस इतना ही काफी होना चाहिए! अब जब हमारे पास एक योजना है, तो हम गोता लगाने के लिए तैयार हैं। + +### निष्कर्ष + +आप जानते हैं कि एक नए मॉड्यूल के input और output interface का आकलन कैसे करें ताकि इसकी आवश्यकताओं की पहचान की जा सके, और आपने सीखा है कि nf-core pipelines द्वारा metamaps का उपयोग कैसे किया जाता है ताकि metadata को data के साथ निकटता से जुड़ा रखा जा सके क्योंकि यह एक pipeline के माध्यम से flows करता है। + +### आगे क्या है? + +नए मॉड्यूल को workflow में integrate करें। + +--- + +## 3. `hello.nf` workflow में CAT_CAT को integrate करें + +अब जब आप metamaps के बारे में सब कुछ जानते हैं (या इस पाठ्यक्रम के उद्देश्यों के लिए पर्याप्त, वैसे भी), तो वास्तव में उन परिवर्तनों को लागू करने का समय आ गया है जिन्हें हमने ऊपर रेखांकित किया है। + +स्पष्टता के लिए, हम इसे तोड़ेंगे और प्रत्येक चरण को अलग से कवर करेंगे। + +!!! note + + नीचे दिखाए गए सभी परिवर्तन `core-hello/workflows/hello.nf` workflow फ़ाइल में `main` ब्लॉक में workflow logic में किए गए हैं। + +### 3.1. एक metadata map बनाएं + +सबसे पहले, हमें `CAT_CAT` के लिए एक metadata map बनाने की आवश्यकता है, यह ध्यान में रखते हुए कि nf-core मॉड्यूल को metamap में कम से कम एक `id` field की आवश्यकता होती है। + +चूंकि हमें किसी अन्य metadata की आवश्यकता नहीं है, हम इसे सरल रख सकते हैं और इस तरह कुछ उपयोग कर सकते हैं: + +```groovy title="Syntax उदाहरण" +def cat_meta = [id: 'test'] +``` + +सिवाय हम `id` value को hardcode नहीं करना चाहते हैं; हम `params.batch` पैरामीटर की value का उपयोग करना चाहते हैं। +तो code बन जाता है: + +```groovy title="Syntax उदाहरण" +def cat_meta = [id: params.batch] +``` + +हाँ, एक बुनियादी metamap बनाना वास्तव में इतना सरल है। + +आइए इन पंक्तियों को `convertToUpper` call के बाद जोड़ें, `collectGreetings` call को हटाते हुए: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +यह एक सरल metadata map बनाता है जहां `id` हमारे batch नाम पर सेट है (जो test profile का उपयोग करते समय `test` होगा)। + +### 3.2. Metadata tuples के साथ एक channel बनाएं + +अगला, फ़ाइलों की channel को metadata और फ़ाइलें युक्त tuples की channel में transform करें: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // tuple format में metadata और files के साथ एक channel बनाएं + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +हमने जो पंक्ति जोड़ी है वह दो चीजें प्राप्त करती है: + +- `.collect()` `convertToUpper` output से सभी फ़ाइलों को एक एकल list में gather करता है +- `.map { files -> tuple(cat_meta, files) }` `[metadata, files]` के format में एक tuple बनाता है जो `CAT_CAT` अपेक्षा करता है + +यह सब कुछ है जो हमें `CAT_CAT` के लिए input tuple को सेट अप करने के लिए करने की आवश्यकता है। + +### 3.3. CAT_CAT मॉड्यूल को call करें + +अब नए बनाए गए channel पर `CAT_CAT` को call करें: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // tuple format में metadata और files के साथ एक channel बनाएं + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // nf-core cat/cat मॉड्यूल का उपयोग करके फ़ाइलों को concatenate करें + CAT_CAT(ch_for_cat) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // tuple format में metadata और files के साथ एक channel बनाएं + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +यह इस प्रतिस्थापन का सबसे मुश्किल हिस्सा पूरा करता है, लेकिन हम अभी तक पूरी तरह से नहीं हुए हैं: हमें अभी भी अपडेट करने की आवश्यकता है कि हम concatenated output को `cowpy` process में कैसे पास करते हैं। + +### 3.4. `cowpy` के लिए tuple से output file को extract करें + +पहले, `collectGreetings` process ने बस एक फ़ाइल उत्पन्न की जिसे हम सीधे `cowpy` में पास कर सकते थे। +हालाँकि, `CAT_CAT` process एक tuple उत्पन्न करता है जिसमें output फ़ाइल के अलावा metamap शामिल है। + +चूंकि `cowpy` अभी तक metadata tuples स्वीकार नहीं करता है (हम इसे पाठ्यक्रम के अगले भाग में ठीक करेंगे), हमें `cowpy` को सौंपने से पहले `CAT_CAT` द्वारा निर्मित tuple से output फ़ाइल को extract करने की आवश्यकता है: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // tuple format में metadata और files के साथ एक channel बनाएं + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenate the greetings + CAT_CAT(ch_for_cat) + + // tuple से file को extract करें क्योंकि cowpy अभी तक metadata का उपयोग नहीं करता है + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy के साथ अभिवादनों का ASCII art generate करें + cowpy(ch_for_cowpy, params.character) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // एक अभिवादन emit करें + sayHello(ch_samplesheet) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + + // batch name के साथ ID के रूप में metadata map बनाएं + def cat_meta = [ id: params.batch ] + + // tuple format में metadata और files के साथ एक channel बनाएं + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenate the greetings + CAT_CAT(ch_for_cat) + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + ``` + +`.map{ meta, file -> file }` operation `CAT_CAT` द्वारा निर्मित `[metadata, file]` tuple से file को एक नए channel, `ch_for_cowpy`, में extract करता है। + +फिर यह बस उस अंतिम पंक्ति में `collectGreetings.out.outfile` के बजाय `cowpy` को `ch_for_cowpy` पास करने की बात है। + +!!! note + + पाठ्यक्रम के अगले भाग में, हम `cowpy` को सीधे metadata tuples के साथ काम करने के लिए अपडेट करेंगे, इसलिए यह extraction चरण आवश्यक नहीं रहेगा। + +### 3.5. Workflow का परीक्षण करें + +आइए परीक्षण करें कि workflow नए integrated `cat/cat` मॉड्यूल के साथ काम करता है: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +यह यथोचित रूप से जल्दी चलना चाहिए। + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +ध्यान दें कि `collectGreetings` के बजाय अब process execution list में `CAT_CAT` दिखाई देता है। + +और बस! हम अब pipeline में उस चरण के लिए custom prototype-grade code के बजाय एक मजबूत community-curated मॉड्यूल का उपयोग कर रहे हैं। + +### निष्कर्ष + +अब आप जानते हैं कि कैसे: + +- nf-core मॉड्यूल खोजें और इंस्टॉल करें +- एक nf-core मॉड्यूल की आवश्यकताओं का आकलन करें +- nf-core मॉड्यूल के साथ उपयोग के लिए एक सरल metadata map बनाएं +- अपने workflow में एक nf-core मॉड्यूल को integrate करें + +### आगे क्या है? + +अपने local मॉड्यूल को nf-core परंपराओं का पालन करने के लिए adapt करना सीखें। +हम आपको यह भी दिखाएंगे कि nf-core tooling का उपयोग करके template से नए nf-core मॉड्यूल कैसे बनाएं। diff --git a/docs/hi/docs/hello_nf-core/04_make_module.md b/docs/hi/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..aff2d98363 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,801 @@ +# भाग 4: nf-core मॉड्यूल बनाएं + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण पाठ्यक्रम के इस चौथे भाग में, हम आपको दिखाएंगे कि मुख्य परंपराओं को लागू करके एक nf-core मॉड्यूल कैसे बनाया जाए जो मॉड्यूल को पोर्टेबल और मेंटेनेबल बनाती हैं। + +nf-core प्रोजेक्ट एक कमांड (`nf-core modules create`) प्रदान करता है जो स्वचालित रूप से उचित रूप से संरचित मॉड्यूल टेम्पलेट जेनरेट करता है, जैसा कि हमने भाग 2 में workflow के लिए उपयोग किया था। +हालाँकि, शिक्षण उद्देश्यों के लिए, हम मैन्युअल रूप से शुरू करने जा रहे हैं: आपके `core-hello` पाइपलाइन में स्थानीय `cowpy` मॉड्यूल को चरण-दर-चरण nf-core-शैली के मॉड्यूल में बदलना। +इसके बाद, हम आपको दिखाएंगे कि भविष्य में अधिक कुशलता से काम करने के लिए टेम्पलेट-आधारित मॉड्यूल निर्माण का उपयोग कैसे करें। + +??? info "इस सेक्शन से कैसे शुरू करें" + + यह सेक्शन मानता है कि आपने [भाग 3: nf-core मॉड्यूल का उपयोग करें](./03_use_module.md) पूरा कर लिया है और अपनी पाइपलाइन में `CAT_CAT` मॉड्यूल को एकीकृत कर लिया है। + + यदि आपने भाग 3 पूरा नहीं किया है या इस भाग के लिए नया शुरू करना चाहते हैं, तो आप अपने शुरुआती बिंदु के रूप में `core-hello-part3` समाधान का उपयोग कर सकते हैं। + `hello-nf-core/` डायरेक्टरी के अंदर से ये कमांड चलाएं: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + यह आपको एक पाइपलाइन देता है जिसमें `CAT_CAT` मॉड्यूल पहले से एकीकृत है। + आप निम्नलिखित कमांड चलाकर परीक्षण कर सकते हैं कि यह सफलतापूर्वक चलता है: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. `cowpy` को nf-core मॉड्यूल में बदलें + +इस सेक्शन में, हम आपकी `core-hello` पाइपलाइन में स्थानीय `cowpy` मॉड्यूल पर nf-core परंपराओं को लागू करेंगे, इसे एक ऐसे मॉड्यूल में बदलेंगे जो nf-core समुदाय के मानकों का पालन करता है। + +यह `cowpy` प्रोसेस मॉड्यूल के लिए वर्तमान कोड है: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy के साथ ASCII art जनरेट करें (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +हम निम्नलिखित nf-core परंपराओं को क्रमिक रूप से लागू करेंगे: + +1. **प्रोसेस नाम को `COWPY` में अपरकेस करें** ताकि परंपरा का पालन हो सके। +2. **`COWPY` को मेटाडेटा टपल का उपयोग करने के लिए अपडेट करें** ताकि workflow के माध्यम से नमूना मेटाडेटा प्रसारित हो सके। +3. **`ext.args` के साथ टूल आर्गुमेंट कॉन्फ़िगरेशन को केंद्रीकृत करें** ताकि मॉड्यूल की बहुमुखी प्रतिभा बढ़े जबकि इंटरफ़ेस न्यूनतम रहे। +4. **`ext.prefix` के साथ आउटपुट नामकरण को मानकीकृत करें** ताकि स्थिरता को बढ़ावा मिले। +5. **प्रकाशन कॉन्फ़िगरेशन को केंद्रीकृत करें** ताकि स्थिरता को बढ़ावा मिले। + +प्रत्येक चरण के बाद, हम यह परीक्षण करने के लिए पाइपलाइन चलाएंगे कि सब कुछ अपेक्षित रूप से काम कर रहा है। + +!!! warning "वर्किंग डायरेक्टरी" + + सुनिश्चित करें कि आप इस सेक्शन में सभी फ़ाइल संपादनों और कमांड निष्पादन के लिए `core-hello` डायरेक्टरी (आपकी पाइपलाइन रूट) में हैं। + + ```bash + cd core-hello + ``` + +### 1.1. प्रोसेस नाम को अपरकेस करें + +यह पूरी तरह से एक शैलीगत परंपरा है (कोई तकनीकी औचित्य नहीं है) लेकिन चूंकि यह nf-core मॉड्यूल के लिए मानक है, तो चलिए इसका पालन करते हैं। + +हमें तीन सेट परिवर्तन करने की आवश्यकता है: + +1. मॉड्यूल में प्रोसेस नाम अपडेट करें +2. workflow हेडर में मॉड्यूल इम्पोर्ट स्टेटमेंट अपडेट करें +3. workflow बॉडी में प्रोसेस कॉल और emit घोषणा अपडेट करें + +चलिए शुरू करते हैं! + +#### 1.1.1. मॉड्यूल में प्रोसेस नाम अपडेट करें + +`cowpy.nf` मॉड्यूल फ़ाइल (`core-hello/modules/local/` के अंतर्गत) खोलें और प्रोसेस नाम को अपरकेस में संशोधित करें: + +=== "बाद में" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // cowpy के साथ ASCII art जनरेट करें (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "पहले" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // cowpy के साथ ASCII art जेनरेट करें (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +इस मामले में अपरकेसिंग पूरी तरह से सीधी है। + +यदि प्रोसेस नाम कई शब्दों से बना होता, उदाहरण के लिए यदि हमारे पास मूल रूप से camel case में MyCowpyTool नामक एक प्रोसेस होता, तो nf-core परंपरा उन्हें अलग करने के लिए अंडरस्कोर का उपयोग करना होगी, जिससे MY_COWPY_TOOL मिलेगा। + +#### 1.1.2. मॉड्यूल इम्पोर्ट स्टेटमेंट अपडेट करें + +प्रोसेस नाम केस-सेंसिटिव हैं, इसलिए अब जब हमने प्रोसेस नाम बदल दिया है, हमें `hello.nf` के workflow हेडर में मॉड्यूल इम्पोर्ट स्टेटमेंट को तदनुसार अपडेट करने की आवश्यकता है: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +हम प्रोसेस कॉल को अपडेट करने से बचने के लिए इम्पोर्ट स्टेटमेंट में एक उपनाम का उपयोग कर सकते हैं, लेकिन इससे अपरकेसिंग परंपरा को अपनाने का उद्देश्य कुछ हद तक विफल हो जाएगा। + +#### 1.1.3. प्रोसेस कॉल और emit घोषणा अपडेट करें + +तो अब चलिए `hello.nf` के workflow ब्लॉक में प्रोसेस के दोनों संदर्भों को अपडेट करते हैं: + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + COWPY(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +**दोनों** परिवर्तन करना सुनिश्चित करें, अन्यथा जब आप इसे चलाएंगे तो आपको एक त्रुटि मिलेगी। + +#### 1.1.4. इसे परीक्षण करने के लिए पाइपलाइन चलाएं + +चलिए इन परिवर्तनों के बाद यह परीक्षण करने के लिए workflow चलाते हैं कि सब कुछ सही तरीके से काम कर रहा है। + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +बढ़िया, यह काम करता है! अब चलिए अधिक महत्वपूर्ण परिवर्तन करने की ओर बढ़ते हैं। + +### 1.2. `COWPY` को मेटाडेटा टपल का उपयोग करने के लिए अपडेट करें + +`core-hello` पाइपलाइन के वर्तमान संस्करण में, हम `COWPY` को पास करने के लिए `CAT_CAT` के आउटपुट टपल से फ़ाइल निकाल रहे हैं, जैसा कि नीचे दिए गए आरेख के ऊपरी भाग में दिखाया गया है। + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +यह बेहतर होगा कि `COWPY` सीधे मेटाडेटा टपल स्वीकार करे, जिससे मेटाडेटा workflow के माध्यम से प्रवाहित हो सके, जैसा कि आरेख के निचले भाग में दिखाया गया है। + +इसके लिए, हमें निम्नलिखित परिवर्तन करने की आवश्यकता होगी: + +1. इनपुट और आउटपुट परिभाषाओं को अपडेट करें +2. workflow में प्रोसेस कॉल को अपडेट करें +3. workflow में emit ब्लॉक को अपडेट करें + +एक बार जब हम यह सब कर लेते हैं, तो हम यह परीक्षण करने के लिए पाइपलाइन चलाएंगे कि सब कुछ अभी भी पहले की तरह काम करता है। + +#### 1.2.1. इनपुट और आउटपुट परिभाषाओं को अपडेट करें + +`cowpy.nf` मॉड्यूल फ़ाइल पर वापस जाएं और इसे नीचे दिखाए अनुसार मेटाडेटा टपल स्वीकार करने के लिए संशोधित करें। + +=== "बाद में" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "पहले" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +जैसा कि आप देख सकते हैं, हमने **मुख्य इनपुट** और **आउटपुट** दोनों को एक टपल में बदल दिया जो भाग 3 में प्रस्तुत `tuple val(meta), path(input_file)` पैटर्न का पालन करता है। +आउटपुट के लिए, हमने आउटपुट चैनल को एक वर्णनात्मक नाम देने के लिए `emit: cowpy_output` जोड़ने का अवसर भी लिया। + +अब जब हमने प्रोसेस की अपेक्षा बदल दी है, हमें प्रोसेस कॉल में जो हम प्रदान करते हैं उसे तदनुसार अपडेट करने की आवश्यकता है। + +#### 1.2.2. workflow में प्रोसेस कॉल को अपडेट करें + +अच्छी खबर यह है कि यह परिवर्तन प्रोसेस कॉल को सरल बना देगा। +अब जब `CAT_CAT` का आउटपुट और `COWPY` का इनपुट एक ही 'आकार' के हैं, यानी दोनों में `tuple val(meta), path(input_file)` संरचना है, तो हम उन्हें सीधे कनेक्ट कर सकते हैं बजाय `CAT_CAT` प्रोसेस के आउटपुट से फ़ाइल को स्पष्ट रूप से निकालने के। + +`hello.nf` workflow फ़ाइल (`core-hello/workflows/` के अंतर्गत) खोलें और नीचे दिखाए अनुसार `COWPY` के कॉल को अपडेट करें। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // cowpy के साथ अभिवादनों का ASCII art generate करें + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // tuple से file extract करें क्योंकि cowpy अभी metadata का उपयोग नहीं करता + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + COWPY(ch_for_cowpy, params.character) + ``` + +अब हम `CAT_CAT.out.file_out` पर सीधे `COWPY` को कॉल करते हैं। + +परिणामस्वरूप, हमें अब `ch_for_cowpy` चैनल बनाने की आवश्यकता नहीं है, इसलिए उस लाइन (और इसकी टिप्पणी लाइन) को पूरी तरह से हटाया जा सकता है। + +#### 1.2.3. workflow में emit ब्लॉक को अपडेट करें + +चूंकि `COWPY` अब एक नामांकित आउटपुट, `cowpy_output`, उत्सर्जित करता है, हम `hello.nf` workflow के `emit:` ब्लॉक को उसका उपयोग करने के लिए अपडेट कर सकते हैं। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +तकनीकी रूप से यह आवश्यक नहीं है, लेकिन जब भी संभव हो नामांकित आउटपुट का संदर्भ देना अच्छा अभ्यास है। + +#### 1.2.4. इसे परीक्षण करने के लिए पाइपलाइन चलाएं + +चलिए इन परिवर्तनों के बाद यह परीक्षण करने के लिए workflow चलाते हैं कि सब कुछ सही तरीके से काम कर रहा है। + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +पाइपलाइन सफलतापूर्वक चलनी चाहिए, मेटाडेटा अब `CAT_CAT` से `COWPY` के माध्यम से प्रवाहित हो रहा है। + +यह पूरा करता है कि हमें `COWPY` को मेटाडेटा टपल संभालने के लिए क्या करने की आवश्यकता थी। +अब, चलिए देखते हैं कि हम nf-core मॉड्यूल पैटर्न का लाभ उठाने के लिए और क्या कर सकते हैं। + +### 1.3. `ext.args` के साथ टूल आर्गुमेंट कॉन्फ़िगरेशन को केंद्रीकृत करें + +अपनी वर्तमान स्थिति में, `COWPY` प्रोसेस `character` पैरामीटर के लिए एक मान प्राप्त करने की अपेक्षा करता है। +परिणामस्वरूप, हमें हर बार प्रोसेस को कॉल करते समय एक मान प्रदान करना होगा, भले ही हम टूल द्वारा सेट किए गए डिफ़ॉल्ट से खुश हों। +`COWPY` के लिए यह स्वीकार्य रूप से एक बड़ी समस्या नहीं है, लेकिन कई वैकल्पिक पैरामीटर वाले टूल के लिए, यह काफी बोझिल हो सकता है। + +nf-core प्रोजेक्ट [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) नामक एक Nextflow फीचर का उपयोग करने की सिफारिश करता है ताकि कॉन्फ़िगरेशन फ़ाइलों के माध्यम से टूल आर्गुमेंट को अधिक सुविधाजनक रूप से प्रबंधित किया जा सके। + +हर टूल विकल्प के लिए प्रोसेस इनपुट घोषित करने के बजाय, आप मॉड्यूल को अपनी कमांड लाइन के निर्माण में `ext.args` का संदर्भ देने के लिए लिखते हैं। +फिर यह केवल `modules.config` फ़ाइल में `ext.args` वेरिएबल को सेट करने की बात है, जो सभी मॉड्यूल के लिए कॉन्फ़िगरेशन विवरण को समेकित करती है, जिसमें आप उपयोग करना चाहते हैं आर्गुमेंट और मान रखते हैं। +Nextflow रनटाइम पर उन आर्गुमेंट को उनके मानों के साथ टूल कमांड लाइन में जोड़ देगा। + +चलिए इस दृष्टिकोण को `COWPY` मॉड्यूल पर लागू करते हैं। +हमें निम्नलिखित परिवर्तन करने की आवश्यकता होगी: + +1. `COWPY` मॉड्यूल को अपडेट करें +2. `modules.config` फ़ाइल में `ext.args` को कॉन्फ़िगर करें +3. `hello.nf` workflow को अपडेट करें + +एक बार जब हम यह सब कर लेते हैं, तो हम यह परीक्षण करने के लिए पाइपलाइन चलाएंगे कि सब कुछ अभी भी पहले की तरह काम करता है। + +#### 1.3.1. `COWPY` मॉड्यूल को अपडेट करें + +चलिए इसे करते हैं। +`cowpy.nf` मॉड्यूल फ़ाइल (`core-hello/modules/local/` के अंतर्गत) खोलें और इसे नीचे दिखाए अनुसार `ext.args` का संदर्भ देने के लिए संशोधित करें। + +=== "बाद में" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // cowpy के साथ ASCII art जनरेट करें (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "पहले" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // cowpy के साथ ASCII art जनरेट करें (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +आप देख सकते हैं कि हमने तीन परिवर्तन किए। + +1. **`input:` ब्लॉक में, हमने `val character` इनपुट को हटा दिया।** + आगे बढ़ते हुए, हम नीचे वर्णित `ext.args` कॉन्फ़िगरेशन के माध्यम से उस आर्गुमेंट को प्रदान करेंगे। + +2. **`script:` ब्लॉक में, हमने लाइन `def args = task.ext.args ?: ''` जोड़ी।** + वह लाइन `args` वेरिएबल का मान निर्धारित करने के लिए `?:` ऑपरेटर का उपयोग करती है: यदि यह खाली नहीं है तो `task.ext.args` की सामग्री, या यदि यह है तो एक खाली स्ट्रिंग। + ध्यान दें कि जबकि हम आम तौर पर `ext.args` का संदर्भ देते हैं, इस कोड को मॉड्यूल-स्तरीय `ext.args` कॉन्फ़िगरेशन को बाहर निकालने के लिए `task.ext.args` का संदर्भ देना होगा। + +3. **कमांड लाइन में, हमने `-c "$character"` को `$args` से बदल दिया।** + यह वह जगह है जहाँ Nextflow `modules.config` फ़ाइल में `ext.args` में सेट किए गए किसी भी टूल आर्गुमेंट को इंजेक्ट करेगा। + +परिणामस्वरूप, मॉड्यूल इंटरफ़ेस अब सरल है: यह केवल आवश्यक मेटाडेटा और फ़ाइल इनपुट की अपेक्षा करता है। + +!!! note + + `?:` ऑपरेटर को अक्सर 'Elvis ऑपरेटर' कहा जाता है क्योंकि यह बगल से Elvis Presley के चेहरे की तरह दिखता है, `?` कैरेक्टर उनके बालों में लहर का प्रतीक है। + +#### 1.3.2. `modules.config` फ़ाइल में `ext.args` को कॉन्फ़िगर करें + +अब जब हमने मॉड्यूल से `character` घोषणा निकाल दी है, तो हमें इसे `modules.config` कॉन्फ़िगरेशन फ़ाइल में `ext.args` में जोड़ना होगा। + +विशेष रूप से, हम `process {}` ब्लॉक में कोड का यह छोटा हिस्सा जोड़ने जा रहे हैं: + +```groovy title="जोड़ने के लिए कोड" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +`withName:` सिंटैक्स इस कॉन्फ़िगरेशन को केवल `COWPY` प्रोसेस को असाइन करता है, और `ext.args = { "-c ${params.character}" }` बस एक स्ट्रिंग बनाता है जिसमें `character` पैरामीटर का मान शामिल होगा। +घुंघराले ब्रेसिज़ के उपयोग पर ध्यान दें, जो Nextflow को रनटाइम पर पैरामीटर का मान मूल्यांकन करने के लिए कहते हैं। + +समझ में आया? चलिए इसे जोड़ते हैं। + +`conf/modules.config` खोलें और नीचे दिखाए अनुसार `process {}` ब्लॉक के अंदर कॉन्फ़िगरेशन कोड जोड़ें। + +=== "बाद में" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "पहले" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +उम्मीद है कि आप कल्पना कर सकते हैं कि एक पाइपलाइन में सभी मॉड्यूल की अपनी `ext.args` इस फ़ाइल में निर्दिष्ट हों, निम्नलिखित लाभों के साथ: + +- **मॉड्यूल इंटरफ़ेस सरल रहता है** - यह केवल आवश्यक मेटाडेटा और फ़ाइल इनपुट स्वीकार करता है +- **पाइपलाइन अभी भी `params.character` को उजागर करती है** - अंतिम उपयोगकर्ता अभी भी इसे पहले की तरह कॉन्फ़िगर कर सकते हैं +- **मॉड्यूल अब पोर्टेबल है** - इसे किसी विशिष्ट पैरामीटर नाम की अपेक्षा के बिना अन्य पाइपलाइनों में पुन: उपयोग किया जा सकता है +- कॉन्फ़िगरेशन `modules.config` में **केंद्रीकृत** है, workflow लॉजिक को साफ रखते हुए + +`modules.config` फ़ाइल का उपयोग उस स्थान के रूप में करके जहाँ सभी पाइपलाइनें प्रति-मॉड्यूल कॉन्फ़िगरेशन को केंद्रीकृत करती हैं, हम अपने मॉड्यूल को विभिन्न पाइपलाइनों में अधिक पुन: उपयोग करने योग्य बनाते हैं। + +#### 1.3.3. `hello.nf` workflow को अपडेट करें + +चूंकि `COWPY` मॉड्यूल को अब इनपुट के रूप में `character` पैरामीटर की आवश्यकता नहीं है, हमें तदनुसार workflow कॉल को अपडेट करने की आवश्यकता है। + +`hello.nf` workflow फ़ाइल (`core-hello/workflows/` के अंतर्गत) खोलें और नीचे दिखाए अनुसार `COWPY` के कॉल को अपडेट करें। + +=== "बाद में" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy के साथ अभिवादनों का ASCII art generate करें + COWPY(CAT_CAT.out.file_out) + ``` + +=== "पहले" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy के साथ अभिवादनों का ASCII art generate करें + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +workflow कोड अब साफ है: हमें प्रोसेस को सीधे `params.character` पास करने की आवश्यकता नहीं है। +मॉड्यूल इंटरफ़ेस को न्यूनतम रखा गया है, जिससे यह अधिक पोर्टेबल हो जाता है, जबकि पाइपलाइन अभी भी कॉन्फ़िगरेशन के माध्यम से स्पष्ट विकल्प प्रदान करती है। + +#### 1.3.4. इसे परीक्षण करने के लिए पाइपलाइन चलाएं + +चलिए परीक्षण करते हैं कि workflow अभी भी अपेक्षित रूप से काम करता है, एक अलग कैरेक्टर निर्दिष्ट करके यह सत्यापित करें कि `ext.args` कॉन्फ़िगरेशन काम कर रहा है। + +`kosh` का उपयोग करके यह कमांड चलाएं, जो अधिक... रहस्यमय विकल्पों में से एक है: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +यह पहले की तरह सफलतापूर्वक चलना चाहिए। + +चलिए सत्यापित करें कि `ext.args` कॉन्फ़िगरेशन ने काम किया आउटपुट की जाँच करके। +फ़ाइल ब्राउज़र में आउटपुट खोजें या आउटपुट फ़ाइल को देखने के लिए task hash (ऊपर के उदाहरण में `38/eb29ea` भाग) का उपयोग करें: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "कमांड आउटपुट" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +आपको `kosh` कैरेक्टर के साथ ASCII art प्रदर्शित दिखनी चाहिए, जो पुष्टि करती है कि `ext.args` कॉन्फ़िगरेशन ने काम किया! + +??? info "(वैकल्पिक) कमांड फ़ाइल का निरीक्षण करें" + + यदि आप यह देखना चाहते हैं कि कॉन्फ़िगरेशन को वास्तव में कैसे लागू किया गया था, तो आप `.command.sh` फ़ाइल का निरीक्षण कर सकते हैं: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + आप `-c kosh` आर्गुमेंट के साथ `cowpy` कमांड देखेंगे: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + यह दर्शाता है कि `.command.sh` फ़ाइल `ext.args` कॉन्फ़िगरेशन के आधार पर सही ढंग से जेनरेट की गई थी। + +सोचने के लिए एक क्षण लें कि हमने यहाँ क्या हासिल किया। +यह दृष्टिकोण मॉड्यूल इंटरफ़ेस को आवश्यक डेटा (फ़ाइलें, मेटाडेटा, और कोई भी अनिवार्य प्रति-नमूना पैरामीटर) पर केंद्रित रखता है, जबकि टूल के व्यवहार को नियंत्रित करने वाले विकल्पों को कॉन्फ़िगरेशन के माध्यम से अलग से संभाला जाता है। + +यह `cowpy` जैसे सरल टूल के लिए अनावश्यक लग सकता है, लेकिन यह डेटा विश्लेषण टूल के लिए बड़ा अंतर ला सकता है जिनमें बहुत सारे वैकल्पिक आर्गुमेंट हैं। + +इस दृष्टिकोण के लाभों को सारांशित करने के लिए: + +- **साफ इंटरफ़ेस**: मॉड्यूल आवश्यक डेटा इनपुट (मेटाडेटा और फ़ाइलें) पर केंद्रित है +- **लचीलापन**: उपयोगकर्ता कॉन्फ़िगरेशन के माध्यम से टूल आर्गुमेंट निर्दिष्ट कर सकते हैं, नमूना-विशिष्ट मानों सहित +- **स्थिरता**: सभी nf-core मॉड्यूल इस पैटर्न का पालन करते हैं +- **पोर्टेबिलिटी**: मॉड्यूल को हार्डकोडेड टूल विकल्पों के बिना पुन: उपयोग किया जा सकता है +- **कोई workflow परिवर्तन नहीं**: टूल विकल्पों को जोड़ने या बदलने के लिए workflow कोड को अपडेट करने की आवश्यकता नहीं है + +!!! note + + `ext.args` सिस्टम में शक्तिशाली अतिरिक्त क्षमताएँ हैं जो यहाँ कवर नहीं की गई हैं, जिसमें मेटाडेटा के आधार पर आर्गुमेंट मानों को गतिशील रूप से स्विच करना शामिल है। अधिक विवरण के लिए [nf-core मॉड्यूल विशिष्टताएँ](https://nf-co.re/docs/guidelines/components/modules) देखें। + +### 1.4. `ext.prefix` के साथ आउटपुट नामकरण को मानकीकृत करें + +अब जब हमने `COWPY` प्रोसेस को metamap तक पहुँच दी है, तो हम एक और उपयोगी nf-core पैटर्न का लाभ उठाना शुरू कर सकते हैं: मेटाडेटा के आधार पर आउटपुट फ़ाइलों का नामकरण। + +यहाँ हम `ext.prefix` नामक एक Nextflow फीचर का उपयोग करने जा रहे हैं जो हमें `meta.id` (metamap में शामिल पहचानकर्ता) का उपयोग करके मॉड्यूलों में आउटपुट फ़ाइल नामकरण को मानकीकृत करने की अनुमति देगा, जबकि अभी भी वांछित होने पर मॉड्यूल को व्यक्तिगत रूप से कॉन्फ़िगर करने में सक्षम होंगे। + +यह `ext.args` के साथ हमने जो किया उसके समान होगा, कुछ अंतरों के साथ जिन्हें हम आगे बढ़ते हुए विस्तार से बताएंगे। + +चलिए इस दृष्टिकोण को `COWPY` मॉड्यूल पर लागू करते हैं। +हमें निम्नलिखित परिवर्तन करने की आवश्यकता होगी: + +1. `COWPY` मॉड्यूल को अपडेट करें +2. `modules.config` फ़ाइल में `ext.prefix` को कॉन्फ़िगर करें + +(workflow में कोई परिवर्तन आवश्यक नहीं।) + +एक बार जब हम यह कर लेते हैं, तो हम यह परीक्षण करने के लिए पाइपलाइन चलाएंगे कि सब कुछ अभी भी पहले की तरह काम करता है। + +#### 1.4.1. `COWPY` मॉड्यूल को अपडेट करें + +`cowpy.nf` मॉड्यूल फ़ाइल (`core-hello/modules/local/` के अंतर्गत) खोलें और इसे नीचे दिखाए अनुसार `ext.prefix` का संदर्भ देने के लिए संशोधित करें। + +=== "बाद में" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "पहले" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +आप देख सकते हैं कि हमने तीन परिवर्तन किए। + +1. **`script:` ब्लॉक में, हमने लाइन `prefix = task.ext.prefix ?: "${meta.id}"` जोड़ी।** + वह लाइन `prefix` वेरिएबल का मान निर्धारित करने के लिए `?:` ऑपरेटर का उपयोग करती है: यदि यह खाली नहीं है तो `task.ext.prefix` की सामग्री, या यदि यह है तो metamap से पहचानकर्ता (`meta.id`)। + ध्यान दें कि जबकि हम आम तौर पर `ext.prefix` का संदर्भ देते हैं, इस कोड को मॉड्यूल-स्तरीय `ext.prefix` कॉन्फ़िगरेशन को बाहर निकालने के लिए `task.ext.prefix` का संदर्भ देना होगा। + +2. **कमांड लाइन में, हमने `cowpy-${input_file}` को `${prefix}.txt` से बदल दिया।** + यह वह जगह है जहाँ Nextflow ऊपर की लाइन द्वारा निर्धारित `prefix` का मान इंजेक्ट करेगा। + +3. **`output:` ब्लॉक में, हमने `path("cowpy-${input_file}")` को `path("${prefix}.txt")` से बदल दिया।** + यह केवल यह दोहराता है कि कमांड लाइन में लिखे अनुसार फ़ाइल पथ क्या होगा। + +परिणामस्वरूप, आउटपुट फ़ाइल नाम अब उचित फ़ाइल फ़ॉर्मेट एक्सटेंशन के साथ संयुक्त समझदार डिफ़ॉल्ट (metamap से पहचानकर्ता) का उपयोग करके बनाया गया है। + +#### 1.4.2. `modules.config` फ़ाइल में `ext.prefix` को कॉन्फ़िगर करें + +इस मामले में समझदार डिफ़ॉल्ट हमारे स्वाद के लिए पर्याप्त रूप से अभिव्यंजक नहीं है; हम एक कस्टम नामकरण पैटर्न का उपयोग करना चाहते हैं जिसमें टूल नाम शामिल हो, `cowpy-<id>.txt`, जैसा कि हमारे पास पहले था। + +हम `modules.config` में `ext.prefix` को कॉन्फ़िगर करके ऐसा करेंगे, जैसा कि हमने `ext.args` के साथ `character` पैरामीटर के लिए किया था, सिवाय इस बार `withName: 'COWPY' {}` ब्लॉक पहले से मौजूद है, और हमें बस निम्नलिखित लाइन जोड़ने की आवश्यकता है: + +```groovy title="जोड़ने के लिए कोड" +ext.prefix = { "cowpy-${meta.id}" } +``` + +यह वह स्ट्रिंग तैयार करेगा जो हम चाहते हैं। +ध्यान दें कि एक बार फिर हम घुंघराले ब्रेसिज़ का उपयोग करते हैं, इस बार Nextflow को रनटाइम पर `meta.id` के मान का मूल्यांकन करने के लिए कहने के लिए। + +चलिए इसे जोड़ते हैं। + +`conf/modules.config` खोलें और नीचे दिखाए अनुसार `process {}` ब्लॉक के अंदर कॉन्फ़िगरेशन कोड जोड़ें। + +=== "बाद में" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "पहले" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +यद diff --git a/docs/hi/docs/hello_nf-core/05_input_validation.md b/docs/hi/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..dfe2c63870 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# भाग 5: इनपुट सत्यापन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण कोर्स के इस पांचवें भाग में, हम आपको दिखाते हैं कि pipeline इनपुट और पैरामीटर को सत्यापित करने के लिए nf-schema plugin का उपयोग कैसे करें। + +??? info "इस खंड से कैसे शुरू करें" + + यह खंड मानता है कि आपने [भाग 4: nf-core मॉड्यूल बनाएं](./04_make_module.md) पूरा कर लिया है और अपने pipeline में `COWPY` प्रोसेस मॉड्यूल को nf-core मानकों के अनुसार अपडेट कर दिया है। + + यदि आपने भाग 4 पूरा नहीं किया है या इस भाग के लिए नई शुरुआत करना चाहते हैं, तो आप अपने प्रारंभिक बिंदु के रूप में `core-hello-part4` समाधान का उपयोग कर सकते हैं। + `hello-nf-core/` डायरेक्टरी के अंदर से ये कमांड चलाएं: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + यह आपको एक pipeline देता है जिसमें `COWPY` मॉड्यूल पहले से nf-core मानकों का पालन करने के लिए अपग्रेड किया गया है। + आप निम्नलिखित कमांड चलाकर परीक्षण कर सकते हैं कि यह सफलतापूर्वक चलता है: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. वार्मअप: थोड़ी पृष्ठभूमि + +### 0.1. सत्यापन क्यों महत्वपूर्ण है + +कल्पना कीजिए कि आपका pipeline दो घंटे तक चल रहा है, केवल इसलिए क्रैश हो जाता है क्योंकि किसी उपयोगकर्ता ने गलत एक्सटेंशन वाली फ़ाइल प्रदान की थी। या घंटों तक रहस्यमय त्रुटियों को डीबग करने में बिताते हैं, केवल यह पता लगाने के लिए कि किसी पैरामीटर की स्पेलिंग गलत थी। इनपुट सत्यापन के बिना, ये परिदृश्य आम हैं। + +इस उदाहरण पर विचार करें: + +```console title="सत्यापन के बिना" +$ nextflow run my-pipeline --input data.txt --output results + +...2 घंटे बाद... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +Pipeline ने अमान्य इनपुट स्वीकार किए और विफल होने से पहले घंटों चला। उचित सत्यापन के साथ: + +```console title="सत्यापन के साथ" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +Pipeline स्पष्ट, कार्रवाई योग्य त्रुटि संदेशों के साथ तुरंत विफल हो जाता है। यह समय, कंप्यूट संसाधन और निराशा बचाता है। + +### 0.2. nf-schema plugin + +[nf-schema plugin](https://nextflow-io.github.io/nf-schema/latest/) एक Nextflow plugin है जो Nextflow pipelines के लिए व्यापक सत्यापन क्षमताएं प्रदान करता है। +जबकि nf-schema किसी भी Nextflow workflow के साथ काम करता है, यह सभी nf-core pipelines के लिए मानक सत्यापन समाधान है। + +nf-schema कई मुख्य कार्य प्रदान करता है: + +- **पैरामीटर सत्यापन**: `nextflow_schema.json` के विरुद्ध pipeline पैरामीटर को सत्यापित करता है +- **नमूना शीट सत्यापन**: `assets/schema_input.json` के विरुद्ध इनपुट फ़ाइलों को सत्यापित करता है +- **चैनल रूपांतरण**: सत्यापित नमूना शीट को Nextflow channels में परिवर्तित करता है +- **सहायता टेक्स्ट जनरेशन**: स्कीमा परिभाषाओं से स्वचालित रूप से `--help` आउटपुट उत्पन्न करता है +- **पैरामीटर सारांश**: प्रदर्शित करता है कि कौन से पैरामीटर डिफ़ॉल्ट से भिन्न हैं + +nf-schema deprecated nf-validation plugin का उत्तराधिकारी है और सत्यापन के लिए मानक [JSON Schema Draft 2020-12](https://json-schema.org/) का उपयोग करता है। + +??? info "Nextflow plugins क्या हैं?" + + Plugins एक्सटेंशन हैं जो Nextflow भाषा में ही नई कार्यक्षमता जोड़ते हैं। वे `nextflow.config` में `plugins{}` ब्लॉक के माध्यम से इंस्टॉल किए जाते हैं और प्रदान कर सकते हैं: + + - नए फ़ंक्शन और क्लास जिन्हें इम्पोर्ट किया जा सकता है (जैसे `samplesheetToList`) + - नई DSL सुविधाएं और ऑपरेटर + - बाहरी सेवाओं के साथ एकीकरण + + nf-schema plugin `nextflow.config` में निर्दिष्ट किया गया है: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + एक बार इंस्टॉल होने के बाद, आप `include { functionName } from 'plugin/plugin-name'` सिंटैक्स का उपयोग करके plugins से फ़ंक्शन इम्पोर्ट कर सकते हैं। + +### 0.3. दो प्रकार के सत्यापन के लिए दो स्कीमा फ़ाइलें + +एक nf-core pipeline दो अलग स्कीमा फ़ाइलों का उपयोग करेगा, जो दो प्रकार के सत्यापन से संबंधित हैं: + +| स्कीमा फ़ाइल | उद्देश्य | सत्यापित करता है | +| -------------------------- | ------------------ | -------------------------------------------------- | +| `nextflow_schema.json` | पैरामीटर सत्यापन | कमांड-लाइन फ्लैग: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | इनपुट डेटा सत्यापन | नमूना शीट और इनपुट फ़ाइलों की सामग्री | + +दोनों स्कीमा JSON Schema फॉर्मेट का उपयोग करते हैं, जो डेटा संरचनाओं का वर्णन और सत्यापन करने के लिए व्यापक रूप से अपनाया गया मानक है। + +**पैरामीटर सत्यापन** कमांड-लाइन पैरामीटर (जैसे `--outdir`, `--batch`, `--input` जैसे फ्लैग) को सत्यापित करता है: + +- पैरामीटर प्रकार, रेंज और फॉर्मेट की जांच करता है +- सुनिश्चित करता है कि आवश्यक पैरामीटर प्रदान किए गए हैं +- सत्यापित करता है कि फ़ाइल पथ मौजूद हैं +- `nextflow_schema.json` में परिभाषित + +**इनपुट डेटा सत्यापन** नमूना शीट और मेनिफेस्ट फ़ाइलों की संरचना को सत्यापित करता है (CSV/TSV फ़ाइलें जो आपके डेटा का वर्णन करती हैं): + +- कॉलम संरचना और डेटा प्रकारों की जांच करता है +- सत्यापित करता है कि नमूना शीट में संदर्भित फ़ाइल पथ मौजूद हैं +- सुनिश्चित करता है कि आवश्यक फ़ील्ड मौजूद हैं +- `assets/schema_input.json` में परिभाषित + +!!! warning "इनपुट डेटा सत्यापन क्या नहीं करता" + + इनपुट डेटा सत्यापन *मेनिफेस्ट फ़ाइलों* (नमूना शीट, CSV फ़ाइलें) की संरचना की जांच करता है, आपकी वास्तविक डेटा फ़ाइलों (FASTQ, BAM, VCF, आदि) की सामग्री की नहीं। + + बड़े पैमाने के डेटा के लिए, फ़ाइल सामग्री को सत्यापित करना (जैसे BAM अखंडता की जांच) ऑर्केस्ट्रेटिंग मशीन पर सत्यापन चरण के दौरान नहीं, बल्कि worker nodes पर चल रहे pipeline processes में होना चाहिए। + +### 0.4. सत्यापन कब होना चाहिए? + +```mermaid +graph LR + A[उपयोगकर्ता pipeline चलाता है] --> B[पैरामीटर सत्यापन] + B -->|✓ मान्य| C[इनपुट डेटा सत्यापन] + B -->|✗ अमान्य| D[त्रुटि: पैरामीटर ठीक करें] + C -->|✓ मान्य| E[Pipeline निष्पादित होता है] + C -->|✗ अमान्य| F[त्रुटि: इनपुट डेटा ठीक करें] +``` + +किसी भी pipeline processes के चलने से **पहले** सत्यापन होना चाहिए, ताकि तेज़ फीडबैक मिल सके और कंप्यूट समय की बर्बादी से बचा जा सके। + +अब आइए इन सिद्धांतों को व्यावहारिक रूप से लागू करें, पैरामीटर सत्यापन से शुरू करते हुए। + +--- + +## 1. पैरामीटर सत्यापन (nextflow_schema.json) + +आइए अपने pipeline में पैरामीटर सत्यापन जोड़कर शुरू करें। यह `--input`, `--outdir`, और `--batch` जैसे कमांड-लाइन फ्लैग को सत्यापित करता है। + +### 1.1. इनपुट फ़ाइल सत्यापन को छोड़ने के लिए सत्यापन कॉन्फ़िगर करें + +nf-core pipeline टेम्पलेट nf-schema के साथ पहले से इंस्टॉल और कॉन्फ़िगर होता है: + +- nf-schema plugin `nextflow.config` में `plugins{}` ब्लॉक के माध्यम से इंस्टॉल किया गया है +- पैरामीटर सत्यापन `params.validate_params = true` के माध्यम से डिफ़ॉल्ट रूप से सक्षम है +- सत्यापन pipeline इनिशियलाइज़ेशन के दौरान `UTILS_NFSCHEMA_PLUGIN` subworkflow द्वारा किया जाता है + +सत्यापन व्यवहार `nextflow.config` में `validation{}` स्कोप के माध्यम से नियंत्रित किया जाता है। + +चूंकि हम पहले पैरामीटर सत्यापन पर काम करेंगे (यह खंड) और खंड 2 तक इनपुट डेटा स्कीमा कॉन्फ़िगर नहीं करेंगे, हमें अस्थायी रूप से nf-schema को `input` पैरामीटर की फ़ाइल सामग्री को सत्यापित करने से छोड़ने के लिए कहना होगा। + +`nextflow.config` खोलें और `validation` ब्लॉक खोजें (लगभग लाइन 246)। इनपुट फ़ाइल सत्यापन को छोड़ने के लिए `ignoreParams` जोड़ें: + +=== "बाद में" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +यह कॉन्फ़िगरेशन nf-schema को बताती है: + +- **`defaultIgnoreParams`**: `genomes` जैसे जटिल पैरामीटर के सत्यापन को छोड़ें (टेम्पलेट डेवलपर्स द्वारा सेट) +- **`ignoreParams`**: `input` पैरामीटर की फ़ाइल सामग्री के सत्यापन को छोड़ें (अस्थायी; हम खंड 2 में इसे फिर से सक्षम करेंगे) +- **`monochromeLogs`**: `true` पर सेट होने पर सत्यापन संदेशों में रंगीन आउटपुट अक्षम करें (`params.monochrome_logs` द्वारा नियंत्रित) + +!!! note "input पैरामीटर को क्यों अनदेखा करें?" + + `nextflow_schema.json` में `input` पैरामीटर में `"schema": "assets/schema_input.json"` है जो nf-schema को उस स्कीमा के विरुद्ध इनपुट CSV फ़ाइल की *सामग्री* को सत्यापित करने के लिए कहता है। + चूंकि हमने अभी तक उस स्कीमा को कॉन्फ़िगर नहीं किया है, हम अस्थायी रूप से इस सत्यापन को अनदेखा करते हैं। + हम इनपुट डेटा स्कीमा को कॉन्फ़िगर करने के बाद खंड 2 में इस सेटिंग को हटा देंगे। + +### 1.2. पैरामीटर स्कीमा की जांच करें + +आइए `nextflow_schema.json` फ़ाइल के एक खंड को देखें जो हमारे pipeline टेम्पलेट के साथ आया था: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +पैरामीटर स्कीमा समूहों में व्यवस्थित है। यहां `input_output_options` समूह है: + +```json title="core-hello/nextflow_schema.json (अंश)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +यहां वर्णित प्रत्येक इनपुट में निम्नलिखित मुख्य गुण हैं जिन्हें सत्यापित किया जा सकता है: + +- **`type`**: डेटा प्रकार (string, integer, boolean, number) +- **`format`**: विशेष फॉर्मेट जैसे `file-path` या `directory-path` +- **`exists`**: फ़ाइल पथों के लिए, जांचें कि फ़ाइल मौजूद है या नहीं +- **`pattern`**: नियमित अभिव्यक्ति जिससे मान मेल खाना चाहिए +- **`required`**: पैरामीटर नामों की सरणी जो प्रदान की जानी चाहिए +- **`mimetype`**: सत्यापन के लिए अपेक्षित फ़ाइल mimetype + +यदि आपकी नज़र तेज़ है, तो आप देख सकते हैं कि जिस `batch` इनपुट पैरामीटर का हम उपयोग कर रहे हैं वह अभी तक स्कीमा में परिभाषित नहीं है। +हम इसे अगले खंड में जोड़ने वाले हैं। + +??? info "स्कीमा पैरामीटर कहां से आते हैं?" + + स्कीमा सत्यापन पैरामीटर परिभाषाओं के लिए आधार के रूप में `nextflow.config` का उपयोग करता है। + आपकी workflow स्क्रिप्ट में कहीं और घोषित पैरामीटर (जैसे `main.nf` या मॉड्यूल फ़ाइलों में) स्कीमा validator द्वारा स्वचालित रूप से **नहीं** उठाए जाते हैं। + + इसका मतलब है कि आपको हमेशा अपने pipeline पैरामीटर `nextflow.config` में घोषित करने चाहिए, और फिर उनके सत्यापन नियम `nextflow_schema.json` में परिभाषित करने चाहिए। + +### 1.3. batch पैरामीटर जोड़ें + +जबकि स्कीमा एक JSON फ़ाइल है जिसे मैन्युअल रूप से संपादित किया जा सकता है, **मैन्युअल संपादन त्रुटि-प्रवण है और अनुशंसित नहीं है**। +इसके बजाय, nf-core एक इंटरैक्टिव GUI टूल प्रदान करता है जो आपके लिए JSON Schema सिंटैक्स को संभालता है और आपके परिवर्तनों को सत्यापित करता है: + +```bash +nf-core pipelines schema build +``` + +आपको कुछ इस तरह दिखना चाहिए: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +`y` टाइप करें और Enter दबाएं ताकि इंटरैक्टिव वेब इंटरफ़ेस लॉन्च हो सके। + +आपका ब्राउज़र Parameter schema builder दिखाते हुए खुलेगा: + +![Schema builder इंटरफ़ेस](./img/schema_build.png) + +`batch` पैरामीटर जोड़ने के लिए: + +1. शीर्ष पर **"Add parameter"** बटन पर क्लिक करें +2. drag handle (⋮⋮) का उपयोग करके नए पैरामीटर को "Input/output options" समूह में, `input` पैरामीटर के नीचे ले जाएं +3. पैरामीटर विवरण भरें: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: चेकबॉक्स टिक करें + - वैकल्पिक रूप से, icon picker से एक आइकन चुनें (जैसे, `fas fa-layer-group`) + +![batch पैरामीटर जोड़ना](./img/schema_add.png) + +जब आप समाप्त कर लें, तो शीर्ष दाएं कोने में **"Finished"** बटन पर क्लिक करें। + +अपने टर्मिनल में वापस, आप देखेंगे: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +schema builder से बाहर निकलने के लिए `Ctrl+C` दबाएं। + +टूल ने अब आपकी `nextflow_schema.json` फ़ाइल को नए `batch` पैरामीटर के साथ अपडेट कर दिया है, सभी JSON Schema सिंटैक्स को सही तरीके से संभालते हुए। + +### 1.4. परिवर्तनों की पुष्टि करें + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (अंश)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +आपको दिखना चाहिए कि `batch` पैरामीटर स्कीमा में जोड़ा गया है, "required" फ़ील्ड अब `["input", "outdir", "batch"]` दिखा रहा है। + +### 1.5. पैरामीटर सत्यापन का परीक्षण करें + +अब आइए परीक्षण करें कि पैरामीटर सत्यापन सही तरीके से काम करता है। + +सबसे पहले, आवश्यक `input` पैरामीटर के बिना चलाने का प्रयास करें: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "कमांड आउटपुट" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +बिल्कुल सही! सत्यापन pipeline चलने से पहले लापता आवश्यक पैरामीटर को पकड़ता है। + +अब मान्य पैरामीटर के एक सेट के साथ प्रयास करें: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Pipeline सफलतापूर्वक चलना चाहिए, और `batch` पैरामीटर अब सत्यापित है। + +### निष्कर्ष + +आपने सीखा है कि `nextflow_schema.json` में पैरामीटर जोड़ने के लिए इंटरैक्टिव `nf-core pipelines schema build` टूल का उपयोग कैसे करें और पैरामीटर सत्यापन को क्रिया में देखा है। +वेब इंटरफ़ेस आपके लिए सभी JSON Schema सिंटैक्स को संभालता है, जिससे त्रुटि-प्रवण मैन्युअल JSON संपादन के बिना जटिल पैरामीटर स्कीमा को प्रबंधित करना आसान हो जाता है। + +### आगे क्या? + +अब जब पैरामीटर सत्यापन काम कर रहा है, आइए इनपुट डेटा फ़ाइल सामग्री के लिए सत्यापन जोड़ें। + +--- + +## 2. इनपुट डेटा सत्यापन (schema_input.json) + +हम अपनी इनपुट CSV फ़ाइल की सामग्री के लिए सत्यापन जोड़ने जा रहे हैं। +जबकि पैरामीटर सत्यापन कमांड-लाइन फ्लैग की जांच करता है, इनपुट डेटा सत्यापन यह सुनिश्चित करता है कि CSV फ़ाइल के अंदर डेटा सही तरीके से संरचित है। + +### 2.1. greetings.csv फॉर्मेट को समझें + +आइए खुद को याद दिलाएं कि हमारा इनपुट कैसा दिखता है: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +यह एक सरल CSV है जिसमें: + +- तीन कॉलम (कोई हेडर नहीं) +- प्रत्येक लाइन पर: एक अभिवादन, एक भाषा, और एक स्कोर +- पहले दो कॉलम टेक्स्ट स्ट्रिंग हैं जिनकी कोई विशेष फॉर्मेट आवश्यकताएं नहीं हैं +- तीसरा कॉलम एक integer है + +हमारे pipeline के लिए, केवल पहला कॉलम आवश्यक है। + +### 2.2. स्कीमा संरचना डिज़ाइन करें + +हमारे उपयोग के मामले के लिए, हम चाहते हैं: + +1. कम से कम एक कॉलम के साथ CSV इनपुट स्वीकार करें +2. प्रत्येक पंक्ति के पहले तत्व को अभिवादन स्ट्रिंग के रूप में मानें +3. सुनिश्चित करें कि अभिवादन खाली नहीं हैं और व्हाइटस्पेस से शुरू नहीं होते हैं +4. सुनिश्चित करें कि भाषा फ़ील्ड समर्थित भाषा कोड (en, fr, es, it, de) में से एक से मेल खाता है +5. सुनिश्चित करें कि स्कोर फ़ील्ड 0 और 100 के बीच मान वाला एक integer है + +हम इसे ऑब्जेक्ट की एक सरणी के रूप में संरचित करेंगे, जहां प्रत्येक ऑब्जेक्ट में कम से कम एक `greeting` फ़ील्ड है। + +### 2.3. स्कीमा फ़ाइल अपडेट करें + +nf-core pipeline टेम्पलेट में एक डिफ़ॉल्ट `assets/schema_input.json` शामिल है जो paired-end sequencing डेटा के लिए डिज़ाइन किया गया है। +हमें इसे अपने greetings उपयोग मामले के लिए एक सरल स्कीमा से बदलने की आवश्यकता है। + +`assets/schema_input.json` खोलें और `properties` और `required` अनुभागों को बदलें: + +=== "बाद में" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "पहले" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +मुख्य परिवर्तन: + +- **`description`**: "greetings file" का उल्लेख करने के लिए अपडेट किया गया +- **`properties`**: `sample`, `fastq_1`, और `fastq_2` को `greeting`, `language`, और `score` से बदल दिया गया + - **`type:`** या तो string (`greeting`, `language`) या integer (`score`) को लागू करें + - **`pattern: "^\\S.*$"`**: अभिवादन गैर-व्हाइटस्पेस वर्ण से शुरू होना चाहिए (लेकिन उसके बाद स्पेस हो सकते हैं) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: भाषा कोड समर्थित सेट में होना चाहिए + - **`"minimum": 0` और `"maximum": 100`**: स्कोर मान 0 और 100 के बीच होना चाहिए + - **`errorMessage`**: यदि सत्यापन विफल होता है तो दिखाया गया कस्टम त्रुटि संदेश +- **`required`**: `["sample", "fastq_1"]` से `["greeting"]` में बदल गया + +### 2.4. greetings.csv फ़ाइल में हेडर जोड़ें + +जब nf-schema एक CSV फ़ाइल पढ़ता है, तो यह अपेक्षा करता है कि पहली पंक्ति में कॉलम हेडर हों जो स्कीमा में फ़ील्ड नामों से मेल खाते हों। + +हमारे सरल मामले के लिए, हमें अपनी greetings फ़ाइल में एक हेडर लाइन जोड़नी होगी: + +=== "बाद में" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "पहले" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +अब CSV फ़ाइल में एक हेडर लाइन है जो हमारी स्कीमा में फ़ील्ड नामों से मेल खाती है। + +अंतिम चरण `samplesheetToList` का उपयोग करके pipeline कोड में सत्यापन को लागू करना है। + +### 2.5. pipeline में सत्यापन लागू करें + +अब हमें अपनी सरल CSV पार्सिंग को nf-schema के `samplesheetToList` फ़ंक्शन से बदलना होगा, जो नमूना शीट को सत्यापित और पार्स करेगा। + +`samplesheetToList` फ़ंक्शन: + +1. इनपुट नमूना शीट (CSV, TSV, JSON, या YAML) पढ़ता है +2. प्रदान की गई JSON स्कीमा के विरुद्ध इसे सत्यापित करता है +3. एक Groovy list लौटाता है जहां प्रत्येक प्रविष्टि एक पंक्ति से संबंधित है +4. यदि सत्यापन विफल होता है तो सहायक त्रुटि संदेश फेंकता है + +आइए इनपुट हैंडलिंग कोड अपडेट करें: + +`subworkflows/local/utils_nfcore_hello_pipeline/main.nf` खोलें और उस अनुभाग का पता लगाएं जहां हम इनपुट चैनल बनाते हैं (लगभग लाइन 80)। + +हमें करना होगा: + +1. `samplesheetToList` फ़ंक्शन का उपयोग करें (टेम्पलेट में पहले से इम्पोर्ट किया गया है) +2. इनपुट को सत्यापित और पार्स करें +3. हमारे workflow के लिए केवल अभिवादन स्ट्रिंग निकालें + +सबसे पहले, ध्यान दें कि `samplesheetToList` फ़ंक्शन पहले से फ़ाइल के शीर्ष पर इम्पोर्ट किया गया है (nf-core टेम्पलेट इसे डिफ़ॉल्ट रूप से शामिल करता है): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// core/hello pipeline के लिए विशिष्ट कार्यक्षमता के साथ Subworkflow +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +अब चैनल निर्माण कोड अपडेट करें: + +=== "बाद में" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // params.input के माध्यम से प्रदान की गई इनपुट फ़ाइल से channel बनाएं + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "पहले" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // params.input के माध्यम से प्रदान की गई इनपुट फ़ाइल से channel बनाएं + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +आइए जानें कि क्या बदला: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: इनपुट फ़ाइल को हमारी स्कीमा के विरुद्ध सत्यापित करता है और एक list लौटाता है +2. **`Channel.fromList(...)`**: list को Nextflow चैनल में परिवर्तित करता है + +यह `samplesheetToList` और JSON schemas का उपयोग करके इनपुट डेटा सत्यापन के कार्यान्वयन को पूरा करता है। + +अब जब हमने इनपुट डेटा स्कीमा को कॉन्फ़िगर कर लिया है, तो हम पहले जोड़ी गई अस्थायी ignore सेटिंग को हटा सकते हैं। + +### 2.6. इनपुट सत्यापन को फिर से सक्षम करें + +`nextflow.config` खोलें और `validation` ब्लॉक से `ignoreParams` लाइन हटाएं: + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "पहले" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +अब nf-schema पैरामीटर प्रकार और इनपुट फ़ाइल सामग्री दोनों को सत्यापित करेगा। + +### 2.7. इनपुट सत्यापन का परीक्षण करें + +आइए मान्य और अमान्य दोनों इनपुट का परीक्षण करके सत्यापित करें कि हमारा सत्यापन काम करता है। + +#### 2.7.1. मान्य इनपुट के साथ परीक्षण करें + +सबसे पहले, पुष्टि करें कि pipeline मान्य इनपुट के साथ सफलतापूर्वक चलता है। +ध्यान दें कि हमें अब `--validate_params false` की आवश्यकता नहीं है क्योंकि सत्यापन काम कर रहा है! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "कमांड आउटपुट" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +बढ़िया! Pipeline सफलतापूर्वक चलता है और सत्यापन चुपचाप पास हो जाता है। +`--character` के बारे में चेतावनी केवल सूचनात्मक है क्योंकि यह स्कीमा में परिभाषित नहीं है। +यदि आप चाहें, तो उस पैरामीटर के लिए भी सत्यापन जोड़ने के लिए जो आपने सीखा है उसका उपयोग करें! + +#### 2.7.2. अमान्य इनपुट के साथ परीक्षण करें + +सत्यापन पास करना हमेशा अच्छा लगता है, लेकिन आइए सुनिश्चित करें कि सत्यापन वास्तव में त्रुटियों को पकड़ेगा। + +अमान्य कॉलम नाम के साथ एक परीक्षण फ़ाइल बनाने के लिए, `greetings.csv` फ़ाइल की एक कॉपी बनाकर शुरू करें: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +अब फ़ाइल खोलें और हेडर लाइन में पहले कॉलम का नाम `greeting` से `message` में बदलें: + +=== "बाद में" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "पहले" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +यह हमारी स्कीमा से मेल नहीं खाता, इसलिए सत्यापन को एक त्रुटि फेंकनी चाहिए। + +इस अमान्य इनपुट के साथ pipeline चलाने का प्रयास करें: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +बिल्कुल सही! सत्यापन ने त्रुटि को पकड़ लिया और एक स्पष्ट, सहायक त्रुटि संदेश प्रदान किया: + +- कौन सी फ़ाइल सत्यापन विफल हुई +- कौन सी प्रविष्टि (पंक्ति 1, पहली डेटा पंक्ति) में समस्या है +- विशिष्ट समस्या क्या है (आवश्यक फ़ील्ड `greeting` लापता) + +स्कीमा सत्यापन यह सुनिश्चित करता है कि pipeline चलने से पहले इनपुट फ़ाइलों में सही संरचना हो, समय की बचत होती है और निष्पादन में बाद में भ्रमित करने वाली त्रुटियों को रोकता है। + +यदि आप इसका अभ्यास करना चाहते हैं, तो अन्य greetings इनपुट फ़ाइलें बनाने के लिए स्वतंत्र महसूस करें जो स्कीमा का अन्य मज़ेदार तरीकों से उल्लंघन करती हैं। + +### निष्कर्ष + +आपने पैरामीटर सत्यापन और इनपुट डेटा सत्यापन दोनों को लागू और परीक्षण किया है। आपका pipeline अब निष्पादन से पहले इनपुट को सत्यापित करता है, त्वरित फीडबैक और स्पष्ट त्रुटि संदेश प्रदान करता है। + +!!! tip "आगे पढ़ना" + + उन्नत सत्यापन सुविधाओं और पैटर्न के बारे में अधिक जानने के लिए, [nf-schema दस्तावेज़ीकरण](https://nextflow-io.github.io/nf-schema/latest/) देखें। `nf-core pipelines schema build` कमांड जटिल schemas को प्रबंधित करने के लिए एक इंटरैक्टिव GUI प्रदान करता है। + +### आगे क्या? + +आपने Hello nf-core प्रशिक्षण कोर्स के सभी पांच भाग पूरे कर लिए हैं! + +आपने क्या बनाया है और सीखा है, इस पर विचार करने के लिए [सारांश](summary.md) पर जारी रखें। diff --git a/docs/hi/docs/hello_nf-core/index.md b/docs/hi/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..c440e66de3 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - nf-core पाइपलाइनों को प्राप्त करना, लॉन्च करना और निष्पादन का प्रबंधन करना + - nf-core पाइपलाइनों की कोड संरचना और प्रोजेक्ट संगठन का वर्णन करना + - टेम्पलेट से एक बुनियादी nf-core संगत pipeline बनाना + - एक साधारण Nextflow workflow को nf-core मानकों के अनुरूप अपग्रेड करना + - nf-core संगत pipeline में nf-core modules जोड़ना + - nf-core में अपने स्वयं के modules का योगदान देना + - nf-core टूलिंग का उपयोग करके इनपुट और पैरामीटर को मान्य करना + audience_prerequisites: + - "**दर्शक:** यह कोर्स उन शिक्षार्थियों के लिए डिज़ाइन किया गया है जो पहले से बुनियादी Nextflow से परिचित हैं और nf-core संसाधनों और सर्वोत्तम प्रथाओं का उपयोग करना सीखना चाहते हैं।" + - "**कौशल:** कमांड लाइन, बुनियादी स्क्रिप्टिंग अवधारणाओं और सामान्य फ़ाइल प्रारूपों से परिचितता मानी गई है।" + - "**कोर्स:** [Hello Nextflow](../hello_nextflow/index.md) कोर्स या समकक्ष पूरा किया होना चाहिए।" + - "**डोमेन:** सभी अभ्यास डोमेन-अज्ञेयवादी हैं, इसलिए किसी पूर्व वैज्ञानिक ज्ञान की आवश्यकता नहीं है।" +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core, nf-core संसाधनों और सर्वोत्तम प्रथाओं का उपयोग करने के लिए एक व्यावहारिक परिचय है।** + +![nf-core logo](./img/nf-core-logo.png) + +व्यावहारिक उदाहरणों और निर्देशित अभ्यासों के माध्यम से काम करते हुए, आप nf-core संगत modules और pipelines का उपयोग और विकास करना सीखेंगे, और nf-core टूलिंग का प्रभावी ढंग से उपयोग करना सीखेंगे। + +आप nf-core सर्वोत्तम प्रथाओं के अनुसार pipelines विकसित करना शुरू करने के लिए कौशल और आत्मविश्वास प्राप्त करेंगे। + +<!-- additional_information --> + +## कोर्स अवलोकन + +यह कोर्स व्यावहारिक होने के लिए डिज़ाइन किया गया है, जिसमें लक्ष्य-उन्मुख अभ्यास हैं जो क्रमिक रूप से जानकारी प्रस्तुत करने के लिए संरचित हैं। + +आपको [**nf-core**](https://nf-co.re/) से परिचित कराया जाएगा, जो Nextflow का उपयोग करके निर्मित वैज्ञानिक pipelines के क्यूरेटेड सेट को विकसित और बनाए रखने के लिए एक सामुदायिक प्रयास है, साथ ही प्रासंगिक टूलिंग और दिशानिर्देश जो खुले विकास, परीक्षण और सहकर्मी समीक्षा को बढ़ावा देते हैं ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9))। + +nf-core समुदाय द्वारा विकसित pipelines मॉड्यूलर, स्केलेबल और पोर्टेबल होने के लिए डिज़ाइन किए गए हैं, जिससे शोधकर्ता आसानी से उन्हें अपने डेटा और कंप्यूट संसाधनों का उपयोग करके अनुकूलित और निष्पादित कर सकते हैं। +प्रोजेक्ट द्वारा लागू सर्वोत्तम प्रथाओं के दिशानिर्देश यह सुनिश्चित करते हैं कि pipelines मजबूत, अच्छी तरह से प्रलेखित और वास्तविक दुनिया के डेटासेट के खिलाफ मान्य हैं। +यह वैज्ञानिक विश्लेषणों की विश्वसनीयता और पुनरुत्पादकता बढ़ाने में मदद करता है और अंततः शोधकर्ताओं को अपनी वैज्ञानिक खोजों को तेज करने में सक्षम बनाता है। + +हम इस कोर्स में nf-core pipelines के बारे में जानने के लिए सब कुछ कवर नहीं करेंगे, क्योंकि nf-core में समुदाय द्वारा वर्षों में विकसित कई सुविधाएँ और परंपराएँ शामिल हैं। +इसके बजाय, हम उन आवश्यक अवधारणाओं पर ध्यान केंद्रित करेंगे जो आपको शुरू करने और यह समझने में मदद करेंगी कि nf-core कैसे काम करता है। + +### पाठ योजना + +हमने इसे पांच भागों में विभाजित किया है जो प्रत्येक nf-core संसाधनों का उपयोग करने के विशिष्ट पहलुओं पर ध्यान केंद्रित करेंगे। + +| कोर्स अध्याय | सारांश | अनुमानित अवधि | +| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| [भाग 1: Run a demo pipeline](./01_run_demo.md) | एक मौजूदा nf-core pipeline चलाएँ और इसकी कोड संरचना की जांच करें ताकि यह समझ सकें कि ये pipelines बुनियादी Nextflow workflows से कैसे अलग हैं | 30 मिनट | +| [भाग 2: Rewrite Hello for nf-core](./02_rewrite_hello.md) | एक मौजूदा workflow को nf-core टेम्पलेट स्कैफोल्ड में अनुकूलित करें, [Hello Nextflow](../hello_nextflow/index.md) कोर्स में तैयार सरल workflow से शुरू करते हुए | 60 मिनट | +| [भाग 3: Use an nf-core module](./03_use_module.md) | समुदाय modules लाइब्रेरी का अन्वेषण करें और पूर्व-निर्मित, परीक्षित modules को एकीकृत करना सीखें जो सामान्य बायोइंफॉर्मेटिक्स टूल को रैप करते हैं | 30 मिनट | +| [भाग 4: Make an nf-core module](./04_make_module.md) | nf-core द्वारा स्थापित विशिष्ट संरचना, नामकरण परंपराओं और मेटाडेटा आवश्यकताओं का उपयोग करके अपना स्वयं का nf-core-शैली का module बनाएँ | 30 मिनट | +| [भाग 5: Add input validation](./05_input_validation.md) | nf-schema का उपयोग करके कमांड-लाइन पैरामीटर और इनपुट डेटा फ़ाइलों दोनों के लिए इनपुट मान्यता लागू करें | 30 मिनट | + +इस कोर्स के अंत तक, आप nf-core प्रोजेक्ट द्वारा प्रदान किए गए संसाधनों के विशाल धन का लाभ उठाने में सक्षम होंगे। + +कोर्स लेने के लिए तैयार हैं? + +[सीखना शुरू करें :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/hi/docs/hello_nf-core/next_steps.md b/docs/hi/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..dc05808f23 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# पाठ्यक्रम सारांश + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core प्रशिक्षण पाठ्यक्रम पूरा करने पर बधाई! 🎉 + +<!-- placeholder for video --> + +## आपकी यात्रा + +आपने एक डेमो pipeline को retrieve और run करना सीखकर शुरुआत की, फिर एक सरल Nextflow workflow को nf-core pipeline में बदलने का कार्य किया। +आपने सीखा कि कैसे template का उपयोग करके pipeline scaffold बनाया जाए और मौजूदा pipeline को उस scaffold पर लगाया जाए। +फिर आपने धीरे-धीरे pipeline को परिष्कृत किया - एक local मॉड्यूल को nf-core मॉड्यूल से बदला, एक और local मॉड्यूल को nf-core मानकों के अनुरूप बनाया, और इनपुट validation जोड़ा। + +### आपने क्या बनाया + +आपकी अंतिम `core-hello` pipeline में अब है: + +- **मानकीकृत संरचना** nf-core template का उपयोग करते हुए workflows, subworkflows, modules, और configuration के लिए व्यवस्थित डायरेक्टरी के साथ +- **कम्युनिटी मॉड्यूल** nf-core repository से (`cat/cat`) आपके custom modules के साथ +- **व्यापक validation** जो pipeline के चलने से पहले पैरामीटर और इनपुट डेटा दोनों की जांच करता है +- **व्यावसायिक configuration** विभिन्न execution वातावरण के लिए profiles के साथ +- **पूर्ण documentation** और metadata nf-core conventions का पालन करते हुए + +### प्रमुख कौशल अर्जित किए + +इस hands-on पाठ्यक्रम के माध्यम से, आपने सीखा है: + +1. मौजूदा pipeline का पता लगाकर nf-core pipeline संरचना को **समझना और नेविगेट करना** +2. Workflows को nf-core template के भीतर **पुनर्संरचित करना** और composable बनाना +3. कम्युनिटी repository से पहले से बने modules को **खोजना और integrate करना** +4. Naming, संरचना और metadata के लिए nf-core मानकों का पालन करते हुए **custom modules बनाना** +5. स्पष्ट feedback के साथ त्रुटियों को जल्दी पकड़ने के लिए nf-schema का उपयोग करके **validation लागू करना** + +अब आप कम्युनिटी best practices का पालन करने वाली production-ready nf-core pipelines बनाने के लिए आवश्यक ज्ञान से सुसज्जित हैं। + +## अपने कौशल बढ़ाने के अगले कदम + +यहाँ हमारे शीर्ष 3 सुझाव हैं कि आगे क्या करें: + +- [Nextflow for Science](../nf4_science/index.md) के साथ एक वैज्ञानिक विश्लेषण use case में Nextflow को लागू करें +- [Side Quests](../side_quests/index.md) के साथ अधिक उन्नत Nextflow features देखें +- [nf-core कम्युनिटी में शामिल होकर](https://nf-co.re/join) सक्रिय भागीदार बनें। + +अंत में, हम अनुशंसा करते हैं कि आप [**Seqera Platform**](https://seqera.io/) पर एक नज़र डालें, एक cloud-based platform जो Nextflow के निर्माताओं द्वारा विकसित किया गया है जो आपके workflows को launch और manage करना और भी आसान बनाता है, साथ ही आपके डेटा को manage करना और किसी भी वातावरण में interactively विश्लेषण चलाना संभव बनाता है। + +## प्रतिक्रिया सर्वेक्षण + +आगे बढ़ने से पहले, कृपया पाठ्यक्रम सर्वेक्षण पूरा करने में एक मिनट का समय दें! आपकी प्रतिक्रिया हमें सभी के लिए अपनी प्रशिक्षण सामग्री को बेहतर बनाने में मदद करती है। + +[सर्वेक्षण लें :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/hi/docs/hello_nf-core/survey.md b/docs/hi/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..327f784535 --- /dev/null +++ b/docs/hi/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# फीडबैक सर्वेक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आगे बढ़ने से पहले, कृपया इस छोटे 5-प्रश्न सर्वेक्षण को पूरा करें ताकि आप प्रशिक्षण को रेट कर सकें, अपने अनुभव के बारे में कोई भी फीडबैक साझा कर सकें, और हमें बता सकें कि हम आपकी Nextflow यात्रा में आपकी मदद के लिए और क्या कर सकते हैं। + +इसे पूरा करने में आपको एक मिनट से भी कम समय लगेगा। सभी के लिए हमारी प्रशिक्षण सामग्री को बेहतर बनाने में मदद करने के लिए धन्यवाद! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/hi/docs/help.md b/docs/hi/docs/help.md new file mode 100644 index 0000000000..990f7ce91d --- /dev/null +++ b/docs/hi/docs/help.md @@ -0,0 +1,77 @@ +--- +title: सहायता प्राप्त करना +description: Nextflow प्रशिक्षण में समस्या होने पर उपयोगी संसाधन +hide: + - toc + - footer +--- + +# सहायता प्राप्त करना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +चाहे तुम्हें शुरू करने में कठिनाई हो रही हो, बीच में अटक गए हो या कोई अनुवर्ती प्रश्न हो, संपर्क करने में संकोच मत करो! हमारी समुदाय टीम मदद के लिए यहाँ है, और Nextflow समुदाय बहुत सक्रिय, समावेशी और मदद के लिए उत्सुक है। + +तुम जो खोज रहे हो उसके आधार पर यहाँ मुख्य विकल्प उपलब्ध हैं। + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __समुदाय फोरम__ + + --- + + हमारे समुदाय फोरम में प्रशिक्षण के लिए एक समर्पित श्रेणी है, जो प्रश्न पोस्ट करने या प्रशिक्षण में किसी भी समस्या की रिपोर्ट करने के लिए एक बेहतरीन जगह है। तुम्हें शायद पता चले कि तुम्हारा प्रश्न पहले ही पूछा जा चुका है--और उत्तर भी दिया जा चुका है! + + [प्रशिक्षण फोरम में शामिल हों:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Slack channel__ + + --- + + अगर तुम Slack पर हो, तो Nextflow Slack workspace में प्रशिक्षण channel में हमसे संपर्क कर सकते हो। Nextflow Slack साथी developers के साथ बातचीत करने और सामान्य रूप से Nextflow समुदाय के साथ जुड़ने के लिए एक बेहतरीन जगह है। + + [Nextflow Slack में शामिल हों :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Github issues__ + + --- + + अगर तुम्हें प्रशिक्षण सामग्री में कोई त्रुटि दिखे, तो कृपया Github repository में एक issue खोलकर इसकी रिपोर्ट करो। चाहे यह टाइपो हो, formatting की समस्या हो या कोई वास्तविक bug हो जो code को प्रभावित करता है, हमें बताओ ताकि हम इसे ठीक कर सकें! हम सीधे PRs का भी स्वागत करते हैं। + + [Issue रिपोर्ट करें:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Seqera AI assistant__ + + --- + + Seqera AI एक AI assistant है जो Nextflow और nf-core संसाधनों पर प्रशिक्षित है। यह तुम्हारे code को debug करने, Nextflow concepts को स्पष्ट करने और documentation को तेज़ी से खोजने में मदद कर सकता है। इसे courses के माध्यम से काम करते समय 24/7 उपलब्ध एक tutor की तरह समझो। + + [Seqera AI से पूछो:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Nextflow documentation__ + + --- + + आधिकारिक documentation सभी language features और configuration विकल्पों के लिए अंतिम मार्गदर्शक है। इसे इस प्रशिक्षण के साथ उपयोग करो ताकि विशिष्ट विषयों में गहराई से जा सको, उन्नत features का पता लगा सको और विस्तृत syntax references पा सको। + + [Docs ब्राउज़ करें:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __व्यावसायिक सहायता__ + + --- + + Nextflow एक मुफ्त, open-source software है जिसे [Seqera](https://seqera.io/) द्वारा विकसित किया गया है, जो Spain में मुख्यालय वाली एक कंपनी है जिसके UK और US में satellite offices हैं। हम Nextflow के लिए व्यावसायिक सहायता सेवाएँ प्रदान करते हैं, जिसमें custom प्रशिक्षण शामिल है। + + [संपर्क करें:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/hi/docs/index.md b/docs/hi/docs/index.md new file mode 100644 index 0000000000..a3f9093c49 --- /dev/null +++ b/docs/hi/docs/index.md @@ -0,0 +1,174 @@ +--- +title: होम +description: Nextflow समुदाय प्रशिक्षण पोर्टल में आपका स्वागत है! +hide: + - toc + - footer +--- + +# Nextflow प्रशिक्षण + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __स्व-सेवा पाठ्यक्रम__ + + --- + + **Nextflow समुदाय प्रशिक्षण पोर्टल में आपका स्वागत है!** + + नीचे सूचीबद्ध प्रशिक्षण पाठ्यक्रम स्व-सेवा संसाधन के रूप में उपयोग के लिए डिज़ाइन किए गए हैं। + तुम किसी भी समय इन पर अकेले काम कर सकते हो, चाहे Github Codespaces के माध्यम से हमारे द्वारा प्रदान किए गए वेब-आधारित वातावरण में हो या अपने स्वयं के वातावरण में। + + [पाठ्यक्रम देखें :material-arrow-right:](#catalog-of-nextflow-training-courses){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __अतिरिक्त जानकारी__ + + --- + + ??? warning "संस्करण संगतता" + + <!-- Any update to this content needs to be copied to the local installation page --> + **जनवरी 2026 से, हमारे सभी Nextflow प्रशिक्षण पाठ्यक्रमों के लिए Nextflow संस्करण 25.10.2 या बाद का संस्करण आवश्यक है, जब तक अन्यथा न कहा गया हो, strict syntax सक्रिय होना चाहिए।** + + संस्करण आवश्यकताओं और strict syntax के बारे में अधिक जानकारी के लिए, कृपया [Nextflow docs migration guide](https://nextflow.io/docs/latest/strict-syntax.html) देखें। + + पिछले syntax से संबंधित प्रशिक्षण सामग्री के पुराने संस्करण इस वेबपेज के मेनू बार में संस्करण चयनकर्ता के माध्यम से उपलब्ध हैं। + + ??? terminal "वातावरण विकल्प" + + हम एक वेब-आधारित प्रशिक्षण वातावरण प्रदान करते हैं जहाँ प्रशिक्षण लेने के लिए आवश्यक सब कुछ पहले से इंस्टॉल है, जो Github Codespaces के माध्यम से उपलब्ध है (मुफ्त GitHub खाते की आवश्यकता है)। + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + यदि यह तुम्हारी आवश्यकताओं के अनुरूप नहीं है, तो कृपया अन्य [वातावरण विकल्प](./envsetup/index.md) देखें। + + ??? learning "प्रशिक्षण कार्यक्रम" + + यदि तुम संरचित कार्यक्रम के भाग के रूप में Nextflow प्रशिक्षण लेना पसंद करते हो, तो ऐसा करने के कई अवसर हैं। हम निम्नलिखित विकल्पों की सिफारिश करते हैं: + + - **[Training Weeks]()** समुदाय टीम द्वारा त्रैमासिक आयोजित + - **[Seqera Events](https://seqera.io/events/)** में Seqera द्वारा आयोजित व्यक्तिगत प्रशिक्षण कार्यक्रम शामिल हैं ('Seqera Sessions' और 'Nextflow Summit' खोजें) + - **[Nextflow Ambassadors]()** अपने स्थानीय समुदाय के लिए कार्यक्रम आयोजित करते हैं + - **[nf-core events](https://nf-co.re/events)** में समुदाय hackathons शामिल हैं + + ??? people "प्रशिक्षकों के लिए जानकारी" + + यदि तुम एक प्रशिक्षक हो जो अपने स्वयं के प्रशिक्षण चला रहे हो, तो तुम हमारी सामग्री का सीधे प्रशिक्षण पोर्टल से उपयोग कर सकते हो जब तक तुम उचित श्रेय देते हो। विवरण के लिए नीचे 'Credits and contributions' देखें। + + इसके अलावा, हम तुमसे सुनना चाहेंगे कि हम तुम्हारे प्रशिक्षण प्रयासों का बेहतर समर्थन कैसे कर सकते हैं! कृपया [community@seqera.io](mailto:community@seqera.io) पर या समुदाय फोरम पर हमसे संपर्क करें ([सहायता](help.md) पृष्ठ देखें)। + + ??? licensing "ओपन-सोर्स लाइसेंस और योगदान नीति" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + यह प्रशिक्षण सामग्री [Seqera](https://seqera.io) द्वारा विकसित और रखरखाव की जाती है और समुदाय के लाभ के लिए ओपन-सोर्स लाइसेंस ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) के तहत जारी की गई है। यदि तुम इस सामग्री का उपयोग ऐसे तरीके से करना चाहते हो जो लाइसेंस के दायरे से बाहर है (व्यावसायिक उपयोग और पुनर्वितरण पर सीमाओं को ध्यान में रखें), तो कृपया अपने अनुरोध पर चर्चा करने के लिए [community@seqera.io](mailto:community@seqera.io) पर हमसे संपर्क करें। + + हम समुदाय से सुधार, fixes और bug reports का स्वागत करते हैं। प्रत्येक पृष्ठ के ऊपरी दाएं कोने में :material-file-edit-outline: आइकन है जो कोड रिपॉजिटरी से लिंक करता है, जहाँ तुम issues की रिपोर्ट कर सकते हो या pull request के माध्यम से प्रशिक्षण स्रोत सामग्री में परिवर्तन प्रस्तावित कर सकते हो। अधिक विवरण के लिए रिपॉजिटरी में `README.md` देखें। + +</div> + +!!! note "AI-सहायता प्राप्त अनुवाद" + + यह अनुवाद कृत्रिम बुद्धिमत्ता का उपयोग करके बनाया गया था और मानव अनुवादकों द्वारा समीक्षा की गई है। + हम आपकी प्रतिक्रिया और सुधार के सुझावों का स्वागत करते हैं। + अधिक जानकारी के लिए हमारी [अनुवाद मार्गदर्शिका](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) देखें। + +## Nextflow प्रशिक्षण पाठ्यक्रमों की सूची + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __परिचयात्मक ट्रैक__ + + --- + + ### :material-compass:{.nextflow-primary} नए लोगों के लिए Nextflow {.mt-1} + + डोमेन-अज्ञेयवादी पाठ्यक्रम जो Nextflow के लिए पूरी तरह से नए लोगों के लिए हैं। प्रत्येक पाठ्यक्रम में प्रशिक्षण मॉड्यूल की एक श्रृंखला होती है जो शिक्षार्थियों को उनके कौशल को क्रमिक रूप से बनाने में मदद करने के लिए डिज़ाइन की गई है। + + ??? courses "**Hello Nextflow:** अपनी खुद की pipelines विकसित करना सीखें" + + यह पाठ्यक्रम Nextflow भाषा के मुख्य घटकों को पर्याप्त विस्तार से कवर करता है ताकि सरल लेकिन पूरी तरह से कार्यात्मक pipelines विकसित की जा सकें, साथ ही pipeline डिज़ाइन, विकास और कॉन्फ़िगरेशन प्रथाओं के प्रमुख तत्व। + + [Hello Nextflow प्रशिक्षण शुरू करें :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** मौजूदा pipelines चलाना सीखें" + + Nextflow pipelines चलाने और कॉन्फ़िगर करने का संक्षिप्त परिचय, Hello Nextflow डेवलपर्स पाठ्यक्रम पर आधारित लेकिन कोड पर कम फोकस के साथ। execution, outputs, बुनियादी कोड संरचना, और विभिन्न compute वातावरणों के लिए कॉन्फ़िगरेशन को कवर करता है। + + [Nextflow Run प्रशिक्षण शुरू करें :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} विज्ञान के लिए Nextflow {.mt-1} + + 'Hello Nextflow' में प्रस्तुत अवधारणाओं और घटकों को विशिष्ट वैज्ञानिक उपयोग मामलों में लागू करना सीखें। + + ??? courses "**Nextflow for Genomics** (variant calling)" + + उन शोधकर्ताओं के लिए जो अपनी स्वयं की genomics pipelines विकसित करना सीखना चाहते हैं। यह पाठ्यक्रम एक variant calling उपयोग मामले का उपयोग करता है यह प्रदर्शित करने के लिए कि एक सरल लेकिन कार्यात्मक genomics pipeline कैसे विकसित की जाए। + + [Nextflow for Genomics प्रशिक्षण शुरू करें :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow for RNAseq** (bulk RNAseq)" + + उन शोधकर्ताओं के लिए जो अपनी स्वयं की RNAseq pipelines विकसित करना सीखना चाहते हैं। यह पाठ्यक्रम एक bulk RNAseq processing उपयोग मामले का उपयोग करता है यह प्रदर्शित करने के लिए कि एक सरल लेकिन कार्यात्मक RNAseq pipeline कैसे विकसित की जाए। + + [Nextflow for RNAseq प्रशिक्षण शुरू करें :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow for Imaging** (spatial omics)" + + imaging और spatial omics के शोधकर्ताओं के लिए जो analysis pipelines चलाना और customize करना सीखना चाहते हैं। यह पाठ्यक्रम nf-core/molkart pipeline का उपयोग करता है एक जैविक रूप से प्रासंगिक pipeline प्रदान करने के लिए यह प्रदर्शित करने के लिए कि Nextflow pipelines workflows को कैसे चलाएं, कॉन्फ़िगर करें और inputs को प्रबंधित करें। + + [Nextflow for Imaging प्रशिक्षण शुरू करें :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __उन्नत ट्रैक__ + + --- + + ### :material-bridge:{.nextflow-primary} Nextflow से nf-core तक {.mt-1} + + [nf-core](https://nf-co.re/) समुदाय परियोजना से कोड और सर्वोत्तम प्रथाओं का उपयोग करना सीखें। + + ये पाठ्यक्रम तुम्हें Nextflow fundamentals से nf-core सर्वोत्तम प्रथाओं तक ले जाने में मदद करते हैं। + समझें कि nf-core समुदाय कैसे और क्यों pipelines बनाता है, और तुम कैसे योगदान कर सकते हो और इन तकनीकों का पुन: उपयोग कर सकते हो। + + ??? courses "**Hello nf-core:** nf-core के साथ शुरुआत करें" + + उन डेवलपर्स के लिए जो [nf-core](https://nf-co.re/) compliant pipelines चलाना और विकसित करना सीखना चाहते हैं। यह पाठ्यक्रम nf-core pipelines की संरचना को पर्याप्त विस्तार से कवर करता है ताकि सरल लेकिन पूरी तरह से कार्यात्मक pipelines विकसित की जा सकें जो nf-core template और विकास सर्वोत्तम प्रथाओं का पालन करती हैं, साथ ही मौजूदा nf-core modules का उपयोग करती हैं। + + [Hello nf-core प्रशिक्षण शुरू करें :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} उन्नत Nextflow प्रशिक्षण {.mt-1} + + वास्तविक-दुनिया के उपयोग मामलों को संबोधित करने के लिए Nextflow pipelines विकसित और deploy करने के लिए उन्नत अवधारणाएं और तंत्र सीखें। + + ??? courses "**Side Quests:** स्टैंडअलोन विषयों में गहरी डुबकी" + + Nextflow डेवलपर्स के लिए स्टैंडअलोन मिनी-पाठ्यक्रम जो विशेष विषयों पर अपनी range बढ़ाना और/या अपने कौशल को गहरा करना चाहते हैं। ये रैखिक रूप से प्रस्तुत किए गए हैं लेकिन किसी भी क्रम में लिए जा सकते हैं (प्रत्येक मिनी-पाठ्यक्रम अवलोकन में निर्भरताएं देखें)। + + [Side Quests ब्राउज़ करें :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Training Collections:** Side Quests के माध्यम से अनुशंसित सीखने के मार्ग" + + Training Collections किसी विशेष थीम या उपयोग मामले के आसपास व्यापक सीखने का अनुभव प्रदान करने के लिए कई Side Quests को जोड़ती हैं। + + [Training Collections ब्राउज़ करें :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "संग्रहीत प्रशिक्षण सामग्री खोज रहे हो?" + + पुरानी प्रशिक्षण सामग्री (Fundamentals Training, Advanced Training, और अन्य प्रयोगात्मक पाठ्यक्रम) को प्रशिक्षण पोर्टल से हटा दिया गया है क्योंकि वे Nextflow 3.0 strict syntax के साथ असंगत हैं। + यदि तुम्हें इन सामग्रियों तक पहुंच की आवश्यकता है, तो वे जनवरी 2026 से पहले [git history](https://github.com/nextflow-io/training) में उपलब्ध हैं। + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/hi/docs/info/conventions.md b/docs/hi/docs/info/conventions.md new file mode 100644 index 0000000000..c389479dde --- /dev/null +++ b/docs/hi/docs/info/conventions.md @@ -0,0 +1 @@ +चैनल वेरिएबल्स के लिए हम `ch_` प्रीफ़िक्स का उपयोग करते हैं ताकि यह स्पष्ट रूप से इंगित किया जा सके कि वे Nextflow channels हैं। diff --git a/docs/hi/docs/info/hello_pipeline.md b/docs/hi/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..99e8f02d48 --- /dev/null +++ b/docs/hi/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Hello pipeline +description: Hello pipeline क्या करती है और यह कैसे संरचित है, इसका पुनरावलोकन। +hide: + - toc + - footer +--- + +# Hello pipeline + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +हमारे अधिकांश प्रशिक्षण पाठ्यक्रम Nextflow अवधारणाओं और तंत्रों को प्रदर्शित करने के लिए एक सरल डोमेन-अज्ञेयवादी pipeline का उपयोग करते हैं। +Hello Nextflow पाठ्यक्रम दिखाता है कि इस pipeline को चरण-दर-चरण तरीके से कैसे विकसित किया जाए जो प्रत्येक डिज़ाइन और कार्यान्वयन निर्णय को समझाता है। +अन्य प्रशिक्षण इस pipeline, या इसके भागों को, प्रारंभिक बिंदु के रूप में उपयोग करते हैं। + +यह पृष्ठ Hello Nextflow पाठ्यक्रम के पूरा होने पर pipeline की स्थिति का सारांश देता है। + +### सारांश विवरण + +Hello workflow एक CSV फ़ाइल लेता है जिसमें अभिवादन होते हैं, उन्हें अलग-अलग फ़ाइलों में लिखता है, प्रत्येक को uppercase में परिवर्तित करता है, उन्हें वापस एकत्र करता है और अभिवादन कहते हुए एक मज़ेदार चरित्र की ASCII तस्वीर वाली एक टेक्स्ट फ़ाइल आउटपुट करता है। + +### Workflow चरण (processes) + +चार चरणों को Nextflow processes (`sayHello`, `convertToUpper`, `collectGreetings`, और `cowpy`) के रूप में लागू किया गया है जो अलग मॉड्यूल फ़ाइलों में संग्रहीत हैं। + +1. **`sayHello`:** प्रत्येक अभिवादन को उसकी अपनी आउटपुट फ़ाइल में लिखता है (जैसे, "Hello-output.txt") +2. **`convertToUpper`:** प्रत्येक अभिवादन को uppercase में परिवर्तित करता है (जैसे, "HELLO") +3. **`collectGreetings`:** सभी uppercase अभिवादनों को एक एकल batch फ़ाइल में एकत्र करता है +4. **`cowpy`:** `cowpy` टूल का उपयोग करके ASCII art उत्पन्न करता है + +### आरेख + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### परिणाम + +परिणाम `results/` नामक डायरेक्टरी में प्रकाशित किए जाते हैं, और pipeline का अंतिम आउटपुट (जब डिफ़ॉल्ट पैरामीटर के साथ चलाया जाता है) एक plain text फ़ाइल है जिसमें uppercase अभिवादन कहते हुए एक turkey की ASCII art है। + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +पाठ्यक्रम के आधार पर जिसमें pipeline प्रदर्शित है, तुम्हें विशिष्टताओं में कुछ भिन्नताएँ मिल सकती हैं। + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/hi/docs/info/nxf_versions.md b/docs/hi/docs/info/nxf_versions.md new file mode 100644 index 0000000000..a21c1e177b --- /dev/null +++ b/docs/hi/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Nextflow संस्करण +description: Nextflow के syntax संस्करणों के विकास को समझना और प्रबंधित करना +hide: + - toc + - footer +--- + +## वर्तमान समर्थित Nextflow syntax संस्करण और आवश्यकताएँ + +प्रशिक्षण पोर्टल के संस्करण 3.0 के अनुसार, हमारे सभी प्रशिक्षण पाठ्यक्रम Nextflow के 25.10.2 संस्करण रिलीज़ पर आधारित हैं, जब तक कि पाठ्यक्रम इंडेक्स पेज पर अन्यथा निर्दिष्ट न हो (पुराने या संग्रहीत सामग्री को छोड़कर जिसमें संस्करण सूचना शामिल नहीं हो सकती)। + +क्योंकि पाठ्यक्रम अब workflow स्तर पर typed inputs के साथ-साथ workflow-level output directives का उपयोग करते हैं, इसलिए V2 syntax parser का उपयोग आवश्यक है। +यदि तुम [Github Codespaces](../envsetup/01_setup.md) या [local devcontainers](../envsetup/03_devcontainer.md) के माध्यम से हमारे द्वारा प्रदान किए गए वातावरण का उपयोग करने की योजना बना रहे हो, तो तुम्हें कुछ करने की आवश्यकता नहीं है जब तक कि पाठ्यक्रम निर्देशों में विशेष रूप से नोट न किया गया हो। +हालाँकि, यदि तुम अपने स्वयं के वातावरण में प्रशिक्षण के माध्यम से काम करने की योजना बना रहे हो ([Manual install](../envsetup/02_local.md)), तो तुम्हें v2 syntax parser सक्षम करके Nextflow संस्करण 25.10.2 या बाद के संस्करण का उपयोग करना सुनिश्चित करना होगा। + +## प्रशिक्षण सामग्री के पुराने संस्करण + +हमारी प्रशिक्षण सामग्री फ़रवरी 2025 से संस्करणित की गई है। + +तुम प्रत्येक पृष्ठ के शीर्ष पर ड्रॉपडाउन मेनू आइटम के माध्यम से **25.10.2 से पहले** के Nextflow संस्करणों के साथ काम करने वाली प्रशिक्षण सामग्री के पुराने संस्करण तक पहुँच सकते हो जो प्रशिक्षण सामग्री का क्रमांकित संस्करण दिखाता है। +जब तुम प्रशिक्षण सामग्री का पुराना संस्करण चुनते हो, तो प्रशिक्षण वातावरण के लिंक स्वचालित रूप से वातावरण के संबंधित संस्करण को निर्दिष्ट करेंगे। + +## Nextflow syntax संस्करणों के बारे में अन्य जानकारी + +Nextflow में दो अलग-अलग versioning अवधारणाएँ हैं जो कभी-कभी भ्रमित होती हैं: **DSL संस्करण** और **syntax parser संस्करण**। + +**DSL1 बनाम DSL2** Nextflow pipelines लिखने के मूल रूप से भिन्न तरीकों को संदर्भित करता है। +DSL1 मूल syntax था जहाँ processes channels के माध्यम से अंतर्निहित रूप से जुड़े थे। +DSL2, जो Nextflow 20.07 में पेश किया गया था, ने modularity सुविधाएँ जोड़ीं: अन्य फ़ाइलों से processes और workflows आयात करने की क्षमता, स्पष्ट `workflow` ब्लॉक, और named process outputs। +DSL1 को Nextflow 22.03 में deprecated किया गया और 22.12 में हटा दिया गया। +सभी आधुनिक Nextflow कोड DSL2 का उपयोग करते हैं। + +**Syntax parser v1 बनाम v2** अलग-अलग parsers को संदर्भित करता है जो दोनों DSL2 कोड के साथ काम करते हैं। +v1 parser मूल, अधिक अनुमोदक parser है। +v2 parser सख्त है और नई भाषा सुविधाओं को सक्षम करता है जैसे static typing (typed inputs और outputs) और workflow-level output directives। +v2 parser बेहतर त्रुटि संदेश भी प्रदान करता है और runtime के बजाय parse समय पर अधिक त्रुटियों को पकड़ता है। +v2 parser Nextflow 26.04 में डिफ़ॉल्ट बन जाएगा। + +संक्षेप में: DSL2 वह भाषा है जो तुम लिखते हो; syntax parser संस्करण यह निर्धारित करता है कि उस भाषा की कितनी सख्ती से व्याख्या की जाती है और कौन सी उन्नत सुविधाएँ उपलब्ध हैं। + +### Nextflow संस्करण की जाँच और सेटिंग + +तुम `nextflow --version` कमांड का उपयोग करके जाँच सकते हो कि तुम्हारे सिस्टम पर Nextflow का कौन सा संस्करण स्थापित है। + +Nextflow के संस्करण को अपडेट करने के बारे में अधिक जानकारी के लिए, कृपया [Updating Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html) पर संदर्भ दस्तावेज़ देखें। + +### v2 syntax parser सक्षम करना + +अपने वर्तमान सत्र के लिए v2 syntax parser को **सक्षम** करने के लिए, अपने टर्मिनल में निम्न कमांड चलाओ: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +इसे स्थायी बनाने के लिए (Nextflow 26.04 में v2 के डिफ़ॉल्ट बनने तक), export कमांड को अपने shell profile (`~/.bashrc`, `~/.zshrc`, आदि) में जोड़ो: + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +ध्यान दो कि `NXF_SYNTAX_PARSER=v2` environment variable एक अस्थायी आवश्यकता है। +Nextflow 26.04 से आगे, v2 parser डिफ़ॉल्ट बन जाएगा और इस सेटिंग की आवश्यकता नहीं होगी। + +### v2 syntax parser अक्षम करना + +अपने वर्तमान सत्र के लिए v2 syntax parser को **अक्षम** करने के लिए, अपने टर्मिनल में निम्न कमांड चलाओ: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### मौजूदा कोड का migration + +Nextflow के हाल के संस्करणों के अनुरूप मौजूदा कोड के migration के लिए मार्गदर्शन हेतु, कृपया संदर्भ दस्तावेज़ में [Migration Notes](https://www.nextflow.io/docs/latest/migrations/index.html) देखें। + +सबसे हाल के रिलीज़ में migrate करने के लिए ये दो लेख विशेष रूप से सहायक हैं: + +- [Migrating to workflow outputs](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrating to static types](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +इन दोनों सुविधाओं को प्रशिक्षण सामग्री के संस्करण 3.0 से शुरू होने वाले beginner training के हिस्से के रूप में कवर किया गया है। + +तुम जिस Nextflow कोड को migrate करना चाहते हो उसकी पीढ़ी के आधार पर, तुम `nextflow lint -format` कमांड का उपयोग करके Nextflow linter द्वारा इसका अधिकांश भाग पूरा करने में सक्षम हो सकते हो। +अधिक विवरण के लिए [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) के लिए CLI reference देखें। + +हम आशा करते हैं कि यह सहायक होगा। +यदि तुम्हें सहायता की आवश्यकता है, तो Slack या forum पर संपर्क करो। + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/hi/docs/nextflow_run/00_orientation.md b/docs/hi/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..f6dce0976c --- /dev/null +++ b/docs/hi/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# शुरू करना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## एक प्रशिक्षण वातावरण शुरू करें + +GitHub Codespaces पर हमारे द्वारा प्रदान किए गए पूर्व-निर्मित वातावरण का उपयोग करने के लिए, नीचे "Open in GitHub Codespaces" बटन पर क्लिक करो। अन्य विकल्पों के लिए, [वातावरण विकल्प](../envsetup/index.md) देखो। + +हम अनुशंसा करते हैं कि प्रशिक्षण वातावरण को एक नए ब्राउज़र टैब या विंडो में खोलो (अपने उपकरण के आधार पर राइट-क्लिक, ctrl-क्लिक या cmd-क्लिक का उपयोग करो) ताकि वातावरण लोड होने के दौरान तुम पढ़ते रह सको। +कोर्स के माध्यम से काम करने के लिए तुम्हें इन निर्देशों को समानांतर में खुला रखना होगा। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### वातावरण की मूल बातें + +इस प्रशिक्षण वातावरण में प्रशिक्षण कोर्स के माध्यम से काम करने के लिए आवश्यक सभी software, कोड और डेटा शामिल है, इसलिए तुम्हें स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। + +Codespace एक VSCode इंटरफ़ेस के साथ सेट अप है, जिसमें एक filesystem explorer, एक code editor और एक terminal shell शामिल है। +कोर्स के दौरान दिए गए सभी निर्देश (जैसे 'फ़ाइल खोलो', 'कोड एडिट करो' या 'यह कमांड चलाओ') अन्यथा निर्दिष्ट न होने पर VSCode इंटरफ़ेस के उन तीन भागों को संदर्भित करते हैं। + +यदि तुम इस कोर्स को स्वयं कर रहे हो, तो कृपया अधिक विवरण के लिए [वातावरण की मूल बातें](../envsetup/01_setup.md) से परिचित हो जाओ। + +### संस्करण आवश्यकताएं + +यह प्रशिक्षण Nextflow 25.10.2 या बाद के संस्करण के लिए डिज़ाइन किया गया है **v2 syntax parser सक्षम के साथ**। +यदि तुम एक स्थानीय या कस्टम वातावरण का उपयोग कर रहे हो, तो कृपया सुनिश्चित करो कि तुम [यहां](../info/nxf_versions.md) documented सही सेटिंग्स का उपयोग कर रहे हो। + +## काम करने के लिए तैयार हो जाओ + +एक बार तुम्हारा codespace चल रहा हो, तो प्रशिक्षण में गोता लगाने से पहले तुम्हें दो काम करने होंगे: इस विशिष्ट कोर्स के लिए अपनी working directory सेट करो, और प्रदान की गई सामग्री पर एक नज़र डालो। + +### Working directory सेट करो + +डिफ़ॉल्ट रूप से, codespace work directory को सभी प्रशिक्षण कोर्सों की root पर सेट करके खुलता है, लेकिन इस कोर्स के लिए, हम `nextflow-run/` डायरेक्टरी में काम करेंगे। + +अब terminal में यह कमांड चलाकर डायरेक्टरी बदलो: + +```bash +cd nextflow-run/ +``` + +तुम VSCode को इस डायरेक्टरी पर फोकस करने के लिए सेट कर सकते हो, ताकि file explorer sidebar में केवल प्रासंगिक फ़ाइलें दिखें: + +```bash +code . +``` + +!!! tip "सुझाव" + + यदि किसी भी कारण से तुम इस डायरेक्टरी से बाहर निकल जाते हो (जैसे तुम्हारा codespace स्लीप हो जाता है), तो तुम हमेशा इसमें वापस आने के लिए पूर्ण पथ का उपयोग कर सकते हो, यह मानते हुए कि तुम इसे Github Codespaces प्रशिक्षण वातावरण के भीतर चला रहे हो: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +अब आइए सामग्री पर एक नज़र डालें। + +### प्रदान की गई सामग्री का अन्वेषण करो + +तुम प्रशिक्षण workspace के बाईं ओर file explorer का उपयोग करके इस डायरेक्टरी की सामग्री का अन्वेषण कर सकते हो। +वैकल्पिक रूप से, तुम `tree` कमांड का उपयोग कर सकते हो। + +पूरे कोर्स में, हम डायरेक्टरी संरचना और सामग्री को पठनीय रूप में प्रस्तुत करने के लिए `tree` के आउटपुट का उपयोग करते हैं, कभी-कभी स्पष्टता के लिए मामूली संशोधनों के साथ। + +यहां हम दूसरे स्तर तक सामग्री की तालिका बनाते हैं: + +```bash +tree . -L 2 +``` + +??? abstract "डायरेक्टरी सामग्री" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +सेक्शन को विस्तारित करने और इसकी सामग्री देखने के लिए रंगीन बॉक्स पर क्लिक करो। +हम अपेक्षित कमांड आउटपुट के साथ-साथ डायरेक्टरी और फ़ाइल सामग्री को संक्षिप्त तरीके से प्रदर्शित करने के लिए इस तरह के collapsible sections का उपयोग करते हैं। + +- **`.nf` फ़ाइलें** workflow scripts हैं जो कोर्स के किस भाग में उपयोग की जाती हैं उसके आधार पर क्रमांकित हैं। + +- **`nextflow.config` फ़ाइल** एक configuration फ़ाइल है जो न्यूनतम वातावरण गुण सेट करती है। + तुम अभी के लिए इसे अनदेखा कर सकते हो। + +- **`data/` के अंतर्गत `greetings.csv` फ़ाइल** में इनपुट डेटा है जिसका उपयोग हम कोर्स के अधिकांश भाग में करेंगे। इसका वर्णन भाग 2 (Run pipelines) में किया गया है, जब हम इसे पहली बार पेश करते हैं। + +- **`test-params.*` फ़ाइलें** configuration फ़ाइलें हैं जिनका उपयोग हम भाग 3 (Configuration) में करेंगे। तुम अभी के लिए उन्हें अनदेखा कर सकते हो। + +- **`solutions` डायरेक्टरी** में workflow और इसकी सहायक फ़ाइलों (config और modules) की अंतिम स्थिति है जो कोर्स पूरा करने के परिणामस्वरूप बनती है। + ये तुम्हारे काम की जांच करने और किसी भी समस्या का निवारण करने के लिए एक संदर्भ के रूप में उपयोग किए जाने के लिए हैं। + +## तैयारी चेकलिस्ट + +क्या तुम सोचते हो कि तुम गोता लगाने के लिए तैयार हो? + +- [ ] मैं इस कोर्स के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता/समझती हूं +- [ ] मेरा वातावरण चालू और चल रहा है +- [ ] मैंने अपनी working directory उचित रूप से सेट कर ली है + +यदि तुम सभी बॉक्स चेक कर सकते हो, तो तुम जाने के लिए तैयार हो। + +**[भाग 1: बुनियादी संचालन चलाएं](./01_basics.md) पर जारी रखने के लिए, इस पृष्ठ के निचले दाएं कोने में तीर पर क्लिक करो।** diff --git a/docs/hi/docs/nextflow_run/01_basics.md b/docs/hi/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..e11c6abe20 --- /dev/null +++ b/docs/hi/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# भाग 1: बुनियादी संचालन चलाएं + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run प्रशिक्षण कोर्स के इस पहले भाग में, हम एक बहुत ही बुनियादी डोमेन-अज्ञेयवादी Hello World उदाहरण के साथ विषय में आसानी से प्रवेश करते हैं, जिसका उपयोग हम आवश्यक संचालन प्रदर्शित करने और संबंधित Nextflow कोड कॉम्पोनेंट्स को इंगित करने के लिए करेंगे। + +??? info "Hello World उदाहरण क्या है?" + + "Hello World!" एक न्यूनतम उदाहरण है जिसका उद्देश्य प्रोग्रामिंग भाषा या software framework के बुनियादी syntax और संरचना को प्रदर्शित करना है। + उदाहरण में आमतौर पर "Hello, World!" वाक्यांश को आउटपुट डिवाइस, जैसे console या terminal, पर प्रिंट करना, या इसे एक फ़ाइल में लिखना शामिल होता है। + +--- + +## 1. Hello World सीधे चलाएं + +आइए इस अवधारणा को एक सरल कमांड के साथ प्रदर्शित करें जिसे हम सीधे terminal में चलाते हैं, यह दिखाने के लिए कि यह क्या करता है इससे पहले कि हम इसे Nextflow में wrap करें। + +!!! tip "सुझाव" + + याद रखो कि तुम अब `nextflow-run/` डायरेक्टरी के अंदर होने चाहिए जैसा कि [शुरू करना](00_orientation.md) पृष्ठ पर वर्णित है। + +### 1.1. Terminal को hello कहलवाओ + +अपने terminal में निम्नलिखित कमांड चलाओ। + +```bash +echo 'Hello World!' +``` + +??? success "कमांड आउटपुट" + + ```console + Hello World! + ``` + +यह terminal में सीधे 'Hello World' टेक्स्ट आउटपुट करता है। + +### 1.2. आउटपुट को एक फ़ाइल में लिखो + +Pipelines चलाने में ज्यादातर फ़ाइलों से डेटा पढ़ना और परिणामों को अन्य फ़ाइलों में लिखना शामिल है, तो आइए उदाहरण को थोड़ा और प्रासंगिक बनाने के लिए कमांड को टेक्स्ट आउटपुट को एक फ़ाइल में लिखने के लिए संशोधित करें। + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "कमांड आउटपुट" + + ```console + + ``` + +यह terminal में कुछ भी आउटपुट नहीं करता है। + +### 1.3. आउटपुट खोजो + +'Hello World' टेक्स्ट अब हमारे द्वारा निर्दिष्ट आउटपुट फ़ाइल में होना चाहिए, जिसका नाम `output.txt` है। +तुम इसे file explorer में खोल सकते हो या कमांड लाइन से `cat` utility का उपयोग करके, उदाहरण के लिए। + +??? abstract "फ़ाइल सामग्री" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +यह वही है जो हम अपने पहले Nextflow workflow के साथ replicate करने की कोशिश करने जा रहे हैं। + +### सीख + +अब तुम जानते हो कि terminal में एक सरल कमांड कैसे चलाया जाए जो कुछ टेक्स्ट आउटपुट करता है, और वैकल्पिक रूप से, इसे एक फ़ाइल में आउटपुट कैसे लिखवाया जाए। + +### आगे क्या? + +जानो कि एक Nextflow workflow चलाने में क्या लगता है जो समान परिणाम प्राप्त करता है। + +--- + +## 2. Workflow चलाओ + +हम तुम्हें `1-hello.nf` नाम की एक workflow script प्रदान करते हैं जो `--input` नाम के कमांड-लाइन आर्गुमेंट के माध्यम से एक इनपुट greeting लेती है और उस greeting को शामिल करते हुए एक टेक्स्ट फ़ाइल उत्पन्न करती है। + +हम अभी कोड नहीं देखने जा रहे हैं; पहले आइए देखें कि इसे चलाना कैसा दिखता है। + +### 2.1. Workflow लॉन्च करो और execution मॉनिटर करो + +Terminal में, निम्नलिखित कमांड चलाओ: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +यदि तुम्हारा console आउटपुट कुछ इस तरह दिखता है, तो बधाई हो, तुमने अभी-अभी अपना पहला Nextflow workflow चलाया है! + +यहां सबसे महत्वपूर्ण आउटपुट अंतिम पंक्ति है, जो ऊपर के आउटपुट में हाइलाइट किया गया है: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +यह हमें बताता है कि `sayHello` process एक बार सफलतापूर्वक execute हुआ (`1 of 1 ✔`)। + +यह बढ़िया है, लेकिन तुम सोच रहे होगे: आउटपुट कहां है? + +### 2.2. `results` डायरेक्टरी में आउटपुट फ़ाइल खोजो + +यह workflow अपने आउटपुट को results डायरेक्टरी में publish करने के लिए कॉन्फ़िगर की गई है। +यदि तुम अपनी current डायरेक्टरी देखो, तुम देखोगे कि जब तुमने workflow चलाया, Nextflow ने `results` नाम की एक नई डायरेक्टरी बनाई, साथ ही उसके अंदर `1-hello` नाम की एक subdirectory, जिसमें `output.txt` नाम की एक फ़ाइल है। + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +फ़ाइल खोलो; सामग्री उस string से मेल खानी चाहिए जो तुमने कमांड लाइन पर निर्दिष्ट की थी। + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +बढ़िया, हमारे workflow ने वह किया जो उसे करना चाहिए था! + +हालांकि, ध्यान रखो कि 'published' परिणाम वास्तव में उस आउटपुट की एक प्रति (या कुछ मामलों में एक symbolic link) है जो Nextflow ने workflow execute करते समय उत्पन्न किया था। + +तो अब, हम hood के नीचे झांकने जा रहे हैं यह देखने के लिए कि Nextflow ने वास्तव में कहां काम execute किया। + +!!! warning "चेतावनी" + + सभी workflows results डायरेक्टरी में outputs publish करने के लिए सेट अप नहीं होंगी, और/या डायरेक्टरी के नाम और संरचना भिन्न हो सकती है। + इस सेक्शन में थोड़ा आगे, हम तुम्हें दिखाएंगे कि यह व्यवहार कहां निर्दिष्ट है यह कैसे पता करें। + +### 2.3. `work/` डायरेक्टरी में मूल आउटपुट और लॉग खोजो + +जब तुम एक workflow चलाते हो, Nextflow workflow में प्रत्येक process के हर एक invocation के लिए एक अलग 'task directory' बनाता है (=pipeline में प्रत्येक step)। +प्रत्येक के लिए, यह आवश्यक inputs को stage करेगा, प्रासंगिक instruction(s) execute करेगा और outputs और log फ़ाइलें उस एक डायरेक्टरी के भीतर लिखेगा, जिसे इसे unique बनाने के लिए hash का उपयोग करके स्वचालित रूप से नाम दिया जाता है। + +ये सभी task directories तुम्हारी current डायरेक्टरी (जहां से तुम कमांड चला रहे हो) के भीतर `work` नाम की एक डायरेक्टरी के अंतर्गत रहेंगी। + +यह भ्रमित करने वाला लग सकता है, तो आइए देखें कि व्यवहार में यह कैसा दिखता है। + +पहले चलाए गए workflow के console आउटपुट पर वापस जाते हुए, हमारे पास यह पंक्ति थी: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +देखो कि पंक्ति `[a3/7be2fa]` से कैसे शुरू होती है? +यह उस एक process call के लिए task directory path का एक छोटा रूप है, और तुम्हें बताता है कि `sayHello` process call का आउटपुट `work/` directory path के भीतर कहां खोजना है। + +तुम निम्नलिखित कमांड टाइप करके पूर्ण path पा सकते हो (`a3/7be2fa` को अपने terminal में जो दिखता है उससे बदलो) और path को autocomplete करने के लिए tab key दबाओ या asterisk जोड़ो: + +```bash +ls work/a3/7be2fa* +``` + +यह पूर्ण path directory path देना चाहिए: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +आइए देखें कि वहां क्या है। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "वही चीज़ नहीं दिख रही?" + + सटीक subdirectory नाम तुम्हारे system पर अलग होंगे। + + यदि तुम VSCode file explorer में task subdirectory की सामग्री browse करो, तुम्हें सभी फ़ाइलें तुरंत दिखेंगी। + हालांकि, log फ़ाइलें terminal में invisible होने के लिए सेट हैं, इसलिए यदि तुम उन्हें देखने के लिए `ls` या `tree` का उपयोग करना चाहते हो, तुम्हें invisible फ़ाइलें प्रदर्शित करने के लिए प्रासंगिक विकल्प सेट करना होगा। + + ```bash + tree -a work + ``` + +तुम्हें तुरंत `output.txt` फ़ाइल पहचानना चाहिए, जो वास्तव में `sayHello` process का मूल आउटपुट है जो `results` डायरेक्टरी में publish हुआ था। +यदि तुम इसे खोलो, तुम्हें फिर से `Hello World!` greeting मिलेगी। + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +तो उन सभी अन्य फ़ाइलों के बारे में क्या? + +ये helper और log फ़ाइलें हैं जो Nextflow ने task execution के भाग के रूप में लिखीं: + +- **`.command.begin`**: Sentinel फ़ाइल जो task लॉन्च होते ही बनाई जाती है। +- **`.command.err`**: Process call द्वारा emit किए गए Error संदेश (`stderr`) +- **`.command.log`**: Process call द्वारा emit किया गया पूर्ण log आउटपुट +- **`.command.out`**: Process call द्वारा Regular आउटपुट (`stdout`) +- **`.command.run`**: Process call को execute करने के लिए Nextflow द्वारा चलाई गई पूर्ण script +- **`.command.sh`**: वह कमांड जो वास्तव में process call द्वारा चलाया गया +- **`.exitcode`**: कमांड से resulting exit code + +`.command.sh` फ़ाइल विशेष रूप से उपयोगी है क्योंकि यह तुम्हें मुख्य कमांड दिखाती है जो Nextflow ने execute किया, सभी bookkeeping और task/environment setup को शामिल किए बिना। + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +तो यह पुष्टि करता है कि workflow ने वही कमांड compose किया जो हमने पहले सीधे कमांड-लाइन पर चलाया था। + +जब कुछ गलत हो जाता है और तुम्हें troubleshoot करने की आवश्यकता होती है कि क्या हुआ, `command.sh` script को देखना उपयोगी हो सकता है ताकि यह जांचा जा सके कि Nextflow ने workflow instructions, variable interpolation आदि के आधार पर कौन सा कमांड compose किया। + +### 2.4. अलग-अलग greetings के साथ workflow फिर से चलाओ + +`--input` आर्गुमेंट के लिए अलग-अलग values के साथ workflow को कुछ बार फिर से चलाने की कोशिश करो, फिर task directories देखो। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + 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 + ``` + +तुम देखते हो कि प्रत्येक run के लिए output और log फ़ाइलों के पूर्ण सेट के साथ एक नई subdirectory बनाई गई है। + +इसके विपरीत, यदि तुम `results` डायरेक्टरी देखो, वहां अभी भी केवल एक सेट परिणाम है, और output फ़ाइल की सामग्री जो तुमने आखिरी में चलाया उससे मेल खाती है। + +??? abstract "डायरेक्टरी सामग्री" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +यह तुम्हें दिखाता है कि published results बाद के executions द्वारा overwrite हो जाएंगे, जबकि `work/` के अंतर्गत task directories संरक्षित रहती हैं। + +### सीख + +तुम जानते हो कि एक सरल Nextflow script कैसे चलाएं, इसके execution को कैसे monitor करें और इसके outputs कैसे खोजें। + +### आगे क्या? + +सीखो कि एक बुनियादी Nextflow script कैसे पढ़ें और पहचानें कि इसके components इसकी functionality से कैसे संबंधित हैं। + +--- + +## 3. Hello World workflow starter script की जांच करो + +जो हमने वहां किया वह मूल रूप से workflow script को एक black box की तरह treat करना था। +अब जब हमने देख लिया कि यह क्या करता है, आइए box खोलें और अंदर देखें। + +यहां हमारा लक्ष्य Nextflow code का syntax याद करना नहीं है, बल्कि कुछ बुनियादी अंतर्ज्ञान बनाना है कि मुख्य components क्या हैं और वे कैसे organized हैं। + +### 3.1. समग्र code संरचना की जांच करो + +तुम्हें `1-hello.nf` script अपनी current डायरेक्टरी में मिलेगी, जो `nextflow-run` होनी चाहिए। इसे editor pane में खोलो। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parameters + */ + params { + input: String + } + + workflow { + + main: + // एक अभिवादन emit करें + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +एक Nextflow workflow script में आमतौर पर एक या अधिक **process** definitions, **workflow** स्वयं, और कुछ वैकल्पिक blocks जैसे **params** और **output** शामिल होते हैं। + +प्रत्येक **process** वर्णन करता है कि pipeline में संबंधित step को क्या operation(s) पूरा करना चाहिए, जबकि **workflow** dataflow logic का वर्णन करता है जो विभिन्न steps को जोड़ता है। + +आइए पहले **process** block पर करीब से नज़र डालें, फिर हम **workflow** block देखेंगे। + +### 3.2. `process` definition + +Code का पहला block एक **process** का वर्णन करता है। +Process definition `process` keyword से शुरू होती है, उसके बाद process का नाम और अंत में curly braces द्वारा delimit किया गया process body। +Process body में एक script block होना चाहिए जो चलाने के लिए कमांड निर्दिष्ट करता है, जो कुछ भी हो सकता है जो तुम कमांड लाइन terminal में चला सको। + +```groovy title="1-hello.nf" linenums="3" +/* +* Use echo to print a greeting to a file +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +यहां हमारे पास `sayHello` नाम का एक **process** है जो `greeting` नाम का एक **input** variable लेता है और अपना **output** `output.txt` नाम की फ़ाइल में लिखता है। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +यह एक बहुत ही न्यूनतम process definition है जिसमें बस एक `input` definition, एक `output` definition और execute करने के लिए `script` है। + +`input` definition में `val` qualifier शामिल है, जो Nextflow को बताता है कि किसी प्रकार का value expect करें (string, number, जो भी हो सकता है)। + +`output` definition में `path` qualifier शामिल है, जो Nextflow को बताता है कि इसे path के रूप में handle किया जाना चाहिए (इसमें directory paths और files दोनों शामिल हैं)। + +### 3.3. `workflow` definition + +Code का दूसरा block **workflow** स्वयं का वर्णन करता है। +Workflow definition `workflow` keyword से शुरू होती है, उसके बाद एक वैकल्पिक नाम, फिर curly braces द्वारा delimit किया गया workflow body। + +यहां हमारे पास एक **workflow** है जिसमें एक `main:` block और एक `publish:` block है। +`main:` block workflow का मुख्य body है और `publish:` block उन outputs को सूचीबद्ध करता है जो `results` डायरेक्टरी में publish होने चाहिए। + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // एक अभिवादन emit करें + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +इस मामले में `main:` block में `sayHello` process का एक call है और इसे greeting के रूप में उपयोग करने के लिए `params.input` नाम का एक input देता है। + +जैसा कि हम थोड़ी देर में और विस्तार से चर्चा करेंगे, `params.input` वह value रखता है जो हमने अपनी कमांड लाइन में `--input` parameter को दी थी। + +`publish:` block `sayHello()` process call के output को सूचीबद्ध करता है, जिसे यह `sayHello.out` के रूप में संदर्भित करता है और `first_output` नाम देता है (यह कुछ भी हो सकता है जो workflow author चाहे)। + +यह एक बहुत ही न्यूनतम **workflow** definition है। +एक real-world pipeline में, workflow में आमतौर पर **channels** द्वारा जुड़े **processes** के कई calls होते हैं, और variable inputs के लिए default values सेट अप हो सकते हैं। + +हम कोर्स के भाग 2 में इसमें जाएंगे। +अभी के लिए, आइए इस पर करीब से नज़र डालें कि हमारा workflow inputs और outputs को कैसे handle कर रहा है। + +### 3.4. कमांड-लाइन parameters की `params` system + +`params.input` जो हम `sayHello()` process call को प्रदान करते हैं वह Nextflow code का एक अच्छा टुकड़ा है और इस पर एक अतिरिक्त मिनट खर्च करने लायक है। + +जैसा कि ऊपर बताया गया है, इस तरह हम `--input` कमांड-लाइन parameter की value को `sayHello()` process call को pass करते हैं। +वास्तव में, बस `params.someParameterName` declare करना workflow को कमांड-लाइन से `--someParameterName` नाम का parameter देने के लिए पर्याप्त है। + +यहां हमने उस parameter declaration को एक `params` block सेट अप करके formalize किया है जो उस प्रकार के input को निर्दिष्ट करता है जिसकी workflow expect करती है (Nextflow 25.10.2 और बाद में)। + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +समर्थित types में `String`, `Integer`, `Float`, `Boolean`, और `Path` शामिल हैं। + +!!! tip "सुझाव" + + `params` system का उपयोग करके declare किए गए Workflow parameters कमांड लाइन पर हमेशा दो dashes (`--`) लेते हैं। + यह उन्हें Nextflow-level parameters से अलग करता है, जो केवल एक dash (`-`) लेते हैं। + +### 3.5. `publish` directive + +Workflow के दूसरे छोर पर, हमने पहले ही `publish:` block पर एक नज़र डाली है। +यह output handling system का एक आधा है; दूसरा आधा नीचे स्थित `output` block है। + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +यह निर्दिष्ट करता है कि `publish:` block में सूचीबद्ध `first_output` output को default `results` output डायरेक्टरी के अंतर्गत `1-hello` नाम की subdirectory में copy किया जाना चाहिए। + +`mode 'copy'` पंक्ति system के default व्यवहार को override करती है, जो proper copy के बजाय `work/` डायरेक्टरी में मूल फ़ाइल का symbolic link (या symlink) बनाना है। + +publishing व्यवहार को control करने के लिए यहां प्रदर्शित की तुलना में अधिक विकल्प हैं; हम बाद में कुछ cover करेंगे। +तुम यह भी देखोगे कि जब एक workflow कई outputs generate करता है, तो प्रत्येक को `output` block में इस तरह सूचीबद्ध किया जाता है। + +??? info "`publishDir` का उपयोग करके outputs publish करने का पुराना syntax" + + हाल ही तक, outputs publish करने का स्थापित तरीका प्रत्येक individual process के स्तर पर `publishDir` directive का उपयोग करके करना था। + + तुम अभी भी पुरानी Nextflow pipelines और process modules में हर जगह यह code pattern पाओगे, इसलिए इसके बारे में जागरूक होना महत्वपूर्ण है। + + Workflow में `publish:` block और top level पर `output` block होने के बजाय, तुम `sayHello` process definition में एक `publishDir` पंक्ति देखोगे: + + ```groovy title="Syntax example" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + हालांकि, हम किसी भी नए काम में इसका उपयोग करने की अनुशंसा नहीं करते क्योंकि यह अंततः Nextflow भाषा के भविष्य के versions में disallowed हो जाएगा। + +### सीख + +अब तुम जानते हो कि एक सरल Nextflow workflow कैसे structured है, और बुनियादी components इसकी functionality से कैसे संबंधित हैं। + +### आगे क्या? + +सीखो कि अपने workflow executions को सुविधाजनक तरीके से कैसे manage करें। + +--- + +## 4. Workflow executions manage करो + +Workflows लॉन्च करना और outputs प्राप्त करना जानना बढ़िया है, लेकिन तुम जल्दी पाओगे कि workflow management के कुछ अन्य पहलू हैं जो तुम्हारी ज़िंदगी आसान बना देंगे। + +यहां हम तुम्हें दिखाते हैं कि `resume` feature का लाभ कैसे उठाएं जब तुम्हें वही workflow फिर से लॉन्च करना हो, `nextflow log` के साथ execution logs का निरीक्षण कैसे करें, और `nextflow clean` के साथ पुरानी work directories कैसे delete करें। + +### 4.1. `-resume` के साथ workflow फिर से लॉन्च करो + +कभी-कभी, तुम एक pipeline फिर से चलाना चाहोगे जिसे तुमने पहले लॉन्च किया था बिना उस काम को दोहराए जो पहले ही सफलतापूर्वक पूरा हो चुका है। + +Nextflow में `-resume` नाम का एक विकल्प है जो तुम्हें ऐसा करने की अनुमति देता है। +विशेष रूप से, इस mode में, कोई भी processes जो पहले से ही exact same code, settings और inputs के साथ run हो चुके हैं, skip कर दिए जाएंगे। +इसका मतलब है कि Nextflow केवल वे processes run करेगा जो तुमने पिछले run के बाद से add या modify किए हैं, या जिन्हें तुम नई settings या inputs प्रदान कर रहे हो। + +ऐसा करने के दो मुख्य फायदे हैं: + +- यदि तुम एक pipeline develop करने के बीच में हो, तुम अधिक तेज़ी से iterate कर सकते हो क्योंकि तुम्हें अपने changes test करने के लिए केवल वह process(es) run करने होंगे जिन पर तुम सक्रिय रूप से काम कर रहे हो। +- यदि तुम production में एक pipeline चला रहे हो और कुछ गलत हो जाता है, कई मामलों में तुम समस्या ठीक कर सकते हो और pipeline फिर से लॉन्च कर सकते हो, और यह failure के point से running resume करेगी, जो तुम्हारा बहुत समय और compute बचा सकती है। + +इसका उपयोग करने के लिए, बस अपने कमांड में `-resume` जोड़ो और इसे run करो: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "कमांड आउटपुट" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Console आउटपुट परिचित दिखना चाहिए, लेकिन पहले की तुलना में एक चीज़ थोड़ी अलग है। + +`cached:` bit देखो जो process status पंक्ति (पंक्ति 5) में जोड़ी गई है, जिसका मतलब है कि Nextflow ने पहचान लिया है कि यह काम पहले ही कर चुका है और बस पिछले सफल run से परिणाम का पुन: उपयोग कर रहा है। + +तुम यह भी देख सकते हो कि work subdirectory hash पिछले run जैसा ही है। +Nextflow literally तुम्हें पिछले execution की ओर इंगित कर रहा है और कह रहा है "मैंने वह वहां पहले ही कर दिया था।" + +!!! tip "सुझाव" + + जब तुम `resume` के साथ pipeline फिर से चलाते हो, Nextflow पहले सफलतापूर्वक run हुए किसी भी executions द्वारा work directory के बाहर publish की गई किसी भी फ़ाइल को overwrite नहीं करता। + +### 4.2. पिछले executions के log का निरीक्षण करो + +जब भी तुम एक nextflow workflow लॉन्च करते हो, `history` नाम की एक log फ़ाइल में एक पंक्ति लिखी जाती है, जो current working directory में `.nextflow` नाम की एक hidden डायरेक्टरी के अंतर्गत होती है। + +??? abstract "फ़ाइल सामग्री" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +यह फ़ाइल तुम्हें current working directory के भीतर से लॉन्च किए गए हर Nextflow run के लिए timestamp, run name, status, revision ID, session ID और पूर्ण कमांड लाइन देती है। + +इस जानकारी तक पहुंचने का अधिक सुविधाजनक तरीका `nextflow log` कमांड का उपयोग करना है। + +```bash +nextflow log +``` + +??? success "कमांड आउटपुट" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +यह log फ़ाइल की सामग्री को terminal में आउटपुट करेगा, एक header पंक्ति के साथ augmented। + +तुम देखोगे कि session ID जब भी तुम एक नया `nextflow run` कमांड चलाते हो तब बदलता है, सिवाय इसके कि यदि तुम `-resume` विकल्प का उपयोग कर रहे हो। +उस मामले में, session ID वही रहता है। + +Nextflow session ID का उपयोग `cache` डायरेक्टरी के अंतर्गत run caching जानकारी group करने के लिए करता है, जो `.nextflow` के अंतर्गत भी स्थित है। + +### 4.3. पुरानी work directories delete करो + +यदि तुम बहुत सारी pipelines चलाते हो, तुम कई subdirectories में बहुत सारी फ़ाइलें accumulate कर सकते हो। +चूंकि subdirectories randomly नाम दी जाती हैं, उनके नामों से यह बताना मुश्किल है कि कौन से पुराने हैं बनाम अधिक हाल के runs। + +सौभाग्य से Nextflow में एक helpful `clean` subcommand शामिल है जो स्वचालित रूप से पिछले runs के लिए work subdirectories delete कर सकता है जिनकी तुम्हें अब परवाह नहीं है। + +#### 4.3.1. Deletion criteria निर्धारित करो + +यह निर्धारित करने के लिए कि क्या delete करना है, कई [विकल्प](https://www.nextflow.io/docs/latest/reference/cli.html#clean) हैं। + +यहां हम तुम्हें एक उदाहरण दिखाते हैं जो एक दिए गए run से पहले के सभी runs की subdirectories delete करता है, जो इसके run name का उपयोग करके निर्दिष्ट किया गया है। + +सबसे हाल का सफल run देखो जहां तुमने `-resume` का उपयोग नहीं किया; हमारे मामले में run name `backstabbing_swartz` था। + +Run name machine-generated two-part string है जो `Launching (...)` console आउटपुट पंक्ति में square brackets में दिखाया जाता है। +तुम run को उसके timestamp और/या कमांड लाइन के आधार पर देखने के लिए Nextflow log का भी उपयोग कर सकते हो। + +#### 4.3.2. Dry run करो + +पहले हम dry run flag `-n` का उपयोग यह जांचने के लिए करते हैं कि कमांड को देखते हुए क्या delete होगा: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "कमांड आउटपुट" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +तुम्हारे आउटपुट में अलग task directory नाम होंगे और पंक्तियों की संख्या अलग हो सकती है, लेकिन यह उदाहरण के समान दिखना चाहिए। + +यदि तुम कोई पंक्तियां आउटपुट नहीं देखते हो, तो या तो तुमने एक valid run name प्रदान नहीं किया या delete करने के लिए कोई पिछले runs नहीं हैं। उदाहरण कमांड में `backstabbing_swartz` को अपने log में जो भी संबंधित latest run name है उसमें बदलना सुनिश्चित करो। + +#### 4.3.3. Deletion के साथ आगे बढ़ो + +यदि आउटपुट अपेक्षित दिखता है और तुम deletion के साथ आगे बढ़ना चाहते हो, `-n` के बजाय `-f` flag के साथ कमांड फिर से चलाओ: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "कमांड आउटपुट" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +आउटपुट पहले जैसा ही होना चाहिए, लेकिन अब 'Would remove' के बजाय 'Removed' कह रहा है। +ध्यान दो कि यह two-character subdirectories (जैसे ऊपर `eb/`) को नहीं हटाता लेकिन यह उनकी सामग्री खाली कर देता है। + +!!! warning "चेतावनी" + + पिछले runs की work subdirectories delete करने से उन्हें Nextflow के cache से हटा दिया जाता है और उन directories में stored कोई भी outputs delete हो जाते हैं। + इसका मतलब है कि यह संबंधित processes को फिर से चलाए बिना execution resume करने की Nextflow की क्षमता को तोड़ देता है। + + तुम किसी भी outputs को save करने के लिए जिम्मेदार हो जिनकी तुम्हें परवाह है! यही मुख्य कारण है कि हम `publish` directive के लिए `symlink` mode के बजाय `copy` mode का उपयोग करना पसंद करते हैं। + +### सीख + +तुम जानते हो कि पहले से identical तरीके से run हुए steps को दोहराए बिना pipeline कैसे फिर से लॉन्च करें, execution log का निरीक्षण कैसे करें, और पुरानी work directories को साफ करने के लिए `nextflow clean` कमांड का उपयोग कैसे करें। + +### आगे क्या? + +थोड़ा ब्रेक लो! तुमने अभी-अभी Nextflow syntax और बुनियादी उपयोग निर्देशों के building blocks को absorb किया है। + +इस प्रशिक्षण के अगले section में, हम Hello World pipeline के चार क्रमिक रूप से अधिक realistic versions देखने जा रहे हैं जो प्रदर्शित करेंगे कि Nextflow तुम्हें कई inputs को कुशलता से process करने, एक साथ जुड़े कई steps से बनी workflows चलाने, modular code components का लाभ उठाने, और अधिक reproducibility और portability के लिए containers का उपयोग करने की अनुमति कैसे देता है। + +--- + +## Quiz + +<quiz> +Console आउटपुट पंक्ति `[a3/7be2fa] SAYHELLO | 1 of 1 ✔` में, `[a3/7be2fa]` क्या दर्शाता है? +- [ ] Process version number +- [ ] एक unique run identifier +- [x] Task की work directory का truncated path +- [ ] Output फ़ाइल का checksum + +और जानें: [2.3. `work/` डायरेक्टरी में मूल आउटपुट और लॉग खोजो](#23-work-directory-में-मूल-आउटपुट-और-लॉग-खोजो) +</quiz> + +<quiz> +Task directory में `.command.sh` फ़ाइल का उद्देश्य क्या है? +- [ ] यह task की configuration settings store करती है +- [x] यह process द्वारा execute किया गया actual कमांड दिखाती है +- [ ] इसमें failed tasks से error messages होते हैं +- [ ] यह task के लिए staged input फ़ाइलों को सूचीबद्ध करती है + +और जानें: [2.3. `work/` डायरेक्टरी में मूल आउटपुट और लॉग खोजो](#23-work-directory-में-मूल-आउटपुट-और-लॉग-खोजो) +</quiz> + +<quiz> +जब तुम `-resume` के बिना workflow फिर से चलाते हो तो published results का क्या होता है? +- [ ] वे अलग timestamped directories में preserve होते हैं +- [x] वे नए execution द्वारा overwrite हो जाते हैं +- [ ] Nextflow overwriting रोकता है और fail होता है +- [ ] वे automatically backup हो जाते हैं + +और जानें: [2.4. अलग-अलग greetings के साथ workflow फिर से चलाओ](#24-अलग-अलग-greetings-के-साथ-workflow-फिर-से-चलाओ) +</quiz> + +<quiz> +यह console आउटपुट क्या indicate करता है? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] Task fail हुआ और skip किया गया +- [ ] Task queue में wait कर रहा है +- [x] Nextflow ने पिछले identical execution से results का पुन: उपयोग किया +- [ ] Task manually cancel किया गया + +और जानें: [4.1. `-resume` के साथ workflow फिर से लॉन्च करो](#41--resume-के-साथ-workflow-फिर-से-लॉन्च-करो) +</quiz> + +<quiz> +Nextflow `nextflow log` कमांड जो execution history प्रदर्शित करता है उसे कहां store करता है? +- [ ] results डायरेक्टरी में +- [ ] work डायरेक्टरी में +- [x] `.nextflow/history` फ़ाइल में +- [ ] `nextflow.config` में + +और जानें: [4.2. पिछले executions के log का निरीक्षण करो](#42-पिछले-executions-के-log-का-निरीक्षण-करो) +</quiz> + +<quiz> +Workflow फ़ाइल में `params` block का उद्देश्य क्या है? +- [ ] Process resource requirements define करना +- [ ] Executor configure करना +- [x] Workflow input parameters declare और type करना +- [ ] Output publishing options specify करना + +और जानें: [3.4. कमांड-लाइन parameters की params system](#34-कमांड-लाइन-parameters-की-params-system) +</quiz> + +<quiz> +Workflow के `output` block में, `mode 'copy'` क्या करता है? +- [ ] Work directory का backup बनाता है +- [x] Symbolic links के बजाय फ़ाइलों की पूर्ण copy बनाता है +- [ ] Workflow script को results में copy करता है +- [ ] Incremental file copying enable करता है + +और जानें: [3.5. publish directive](#35-publish-directive) +</quiz> + +<quiz> +वास्तव में फ़ाइलें delete करने से पहले `nextflow clean` कमांड के साथ कौन सा flag उपयोग करने की अनुशंसा की जाती है? +- [x] `-n` (dry run) यह preview करने के लिए कि क्या delete होगा +- [ ] `-v` (verbose) detailed आउटपुट देखने के लिए +- [ ] `-a` (all) सभी directories select करने के लिए +- [ ] `-q` (quiet) warnings suppress करने के लिए + +और जानें: [4.3. पुरानी work directories delete करो](#43-पुरानी-work-directories-delete-करो) +</quiz> diff --git a/docs/hi/docs/nextflow_run/02_pipeline.md b/docs/hi/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..8605f18025 --- /dev/null +++ b/docs/hi/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1394 @@ +# भाग 2: असली pipelines चलाएं + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस कोर्स के भाग 1 (बुनियादी संचालन चलाएं) में, हमने एक उदाहरण workflow से शुरुआत की थी जिसमें code complexity को कम रखने के लिए केवल न्यूनतम features थीं। +उदाहरण के लिए, `1-hello.nf` ने एक समय में एक single value प्रदान करने के लिए एक कमांड-लाइन parameter (`--input`) का उपयोग किया। + +हालांकि, अधिकांश real-world pipelines scale पर बड़ी मात्रा में डेटा की कुशल processing enable करने के लिए अधिक sophisticated features का उपयोग करती हैं, और कभी-कभी complex logic द्वारा एक साथ जुड़े कई processing steps apply करती हैं। + +प्रशिक्षण के इस भाग में, हम मूल Hello World pipeline के expanded versions आज़माकर real-world pipelines की मुख्य features प्रदर्शित करते हैं। + +## 1. एक फ़ाइल से इनपुट डेटा प्रोसेस करना + +एक real-world pipeline में, हम आमतौर पर एक या अधिक इनपुट फ़ाइलों में contained कई data points (या data series) को process करना चाहते हैं। +और जहां संभव हो, हम independent data की processing को parallel में चलाना चाहते हैं, ताकि analysis के लिए wait करने में लगने वाले समय को कम किया जा सके। + +यह प्रदर्शित करने के लिए कि Nextflow यह कैसे करता है, हमने `greetings.csv` नाम की एक CSV फ़ाइल तैयार की है जिसमें कई इनपुट greetings हैं, जो उस प्रकार के columnar data की नकल करती है जिसे तुम एक real data analysis में process करना चाहोगे। +ध्यान दो कि numbers meaningful नहीं हैं, वे सिर्फ illustrative purposes के लिए हैं। + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +हमने मूल workflow का एक improved version भी लिखा है, जिसे अब `2a-inputs.nf` कहा जाता है, जो CSV फ़ाइल में पढ़ेगा, greetings extract करेगा और उनमें से प्रत्येक को एक अलग फ़ाइल में लिखेगा। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +आइए पहले workflow चलाएं, और बाद में हम relevant Nextflow code पर नज़र डालेंगे। + +### 1.1. Workflow चलाओ + +अपने terminal में निम्नलिखित कमांड चलाओ। + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +रोमांचक रूप से, यह indicate करता है कि process के लिए '3 of 3' calls किए गए, जो encouraging है, क्योंकि हमने जो CSV इनपुट के रूप में प्रदान किया उसमें तीन rows of data थीं। +यह suggest करता है कि `sayHello()` process को तीन बार call किया गया, प्रत्येक इनपुट row पर एक बार। + +### 1.2. `results` डायरेक्टरी में published outputs खोजो + +आइए 'results' डायरेक्टरी देखें यह देखने के लिए कि क्या हमारा workflow अभी भी वहां हमारे outputs की एक copy लिख रहा है। + +??? abstract "डायरेक्टरी सामग्री" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +हां! हम `2a-inputs` नाम की एक नई डायरेक्टरी देखते हैं जिसमें अलग-अलग नामों वाली तीन output फ़ाइलें हैं, सुविधाजनक रूप से। + +तुम उनमें से प्रत्येक को खोल कर satisfy हो सकते हो कि उनमें appropriate greeting string है। + +??? abstract "फ़ाइल सामग्री" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +यह confirm करता है कि इनपुट फ़ाइल में प्रत्येक greeting को appropriately process किया गया है। + +### 1.3. Original outputs और logs खोजो + +तुमने शायद देखा होगा कि ऊपर के console आउटपुट में केवल एक task directory का reference था। +क्या इसका मतलब है कि `sayHello()` के सभी तीन calls उस एक task directory में execute किए गए? + +#### 1.3.1. Terminal में दी गई task directory की जांच करो + +आइए उस `8e/0eb066` task directory के अंदर देखें। + +??? abstract "डायरेक्टरी सामग्री" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +हमें केवल एक greeting के corresponding आउटपुट मिलता है (साथ ही accessory फ़ाइलें यदि हम hidden फ़ाइलों का display enable करें)। + +तो यहां क्या हो रहा है? + +Default रूप से, ANSI logging system एक ही process के सभी calls के लिए status information एक ही पंक्ति पर लिखती है। +परिणामस्वरूप, इसने हमें console आउटपुट में तीन task directory paths (`8e/0eb066`) में से केवल एक दिखाया। +दो अन्य हैं जो वहां listed नहीं हैं। + +#### 1.3.2. Terminal को अधिक details दिखाने दो + +हम logging behavior को modify करके process calls की पूरी list देख सकते हैं जैसा कि follows कमांड में `-ansi-log false` जोड़कर: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "कमांड आउटपुट" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +इस बार हम सभी तीन process runs और उनकी associated work subdirectories आउटपुट में listed देखते हैं। +ANSI logging disable करने से Nextflow को terminal आउटपुट में colours का उपयोग करने से भी रोका गया। + +ध्यान दो कि दो logging modes के बीच status report करने का तरीका थोड़ा अलग है। +Condensed mode में, Nextflow report करता है कि calls सफलतापूर्वक पूरी हुईं या नहीं। +इस expanded mode में, यह केवल report करता है कि वे submitted हुईं। + +यह confirm करता है कि `sayHello()` process को तीन बार call किया जाता है, और प्रत्येक के लिए एक अलग task directory बनाई जाती है। + +यदि हम वहां listed प्रत्येक task directory के अंदर देखें, हम verify कर सकते हैं कि प्रत्येक एक greeting से correspond करती है। + +??? abstract "डायरेक्टरी सामग्री" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +यह confirm करता है कि प्रत्येक process call को अन्य सभी से isolation में execute किया जाता है। +इसके कई फायदे हैं, जिसमें collisions से बचना शामिल है यदि process कोई intermediate files produce करता है जिनके नाम unique नहीं हैं। + +!!! tip "सुझाव" + + एक complex workflow, या बड़ी संख्या में inputs के लिए, terminal में पूरी list आउटपुट होना थोड़ा overwhelming हो सकता है, इसलिए लोग सामान्य तौर पर routine usage में `-ansi-log false` का उपयोग नहीं करते। + +### 1.4. Workflow code की जांच करो + +तो workflow का यह version एक CSV फ़ाइल of inputs को पढ़ने, inputs को separately process करने, और outputs को uniquely नाम देने में सक्षम है। + +आइए देखें कि workflow code में यह क्या संभव बनाता है। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline पैरामीटर + */ + params { + input: Path + } + + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +एक बार फिर, तुम्हें code syntax याद करने की जरूरत नहीं है, लेकिन workflow के key components को पहचानना सीखना अच्छा है जो important functionality प्रदान करते हैं। + +#### 1.4.1. CSV से इनपुट डेटा load करना + +यह सबसे interesting भाग है: हमने कमांड-लाइन से single value लेने से, CSV फ़ाइल लेने, इसे parse करने और इसमें contained individual greetings को process करने में कैसे switch किया? + +Nextflow में, हम यह एक **channel** के साथ करते हैं: inputs को कुशलता से handle करने और उन्हें multi-step workflows में एक step से दूसरे में shuttle करने के लिए डिज़ाइन किया गया एक construct, जो built-in parallelism और कई अतिरिक्त benefits प्रदान करता है। + +आइए इसे break down करें। + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) +``` + +यह code `greeting_ch` नाम का एक channel बनाता है जो CSV फ़ाइल पढ़ता है, इसे parse करता है, और प्रत्येक row से पहला column extract करता है। +परिणाम एक channel है जिसमें `Hello`, `Bonjour`, और `Holà` हैं। + +??? tip "यह कैसे काम करता है?" + + यहां बताया गया है कि उस पंक्ति का plain English में क्या मतलब है: + + - `channel.fromPath` एक **channel factory** है जो file path(s) से एक channel बनाता है + - `(params.input)` specifies करता है कि filepath कमांड लाइन पर `--input` द्वारा प्रदान किया गया है + + दूसरे शब्दों में, वह पंक्ति Nextflow को बताती है: `--input` के साथ दिए गए filepath को लो और इसकी contents को इनपुट डेटा के रूप में treat करने के लिए तैयार हो जाओ। + + फिर अगली दो पंक्तियां **operators** apply करती हैं जो फ़ाइल की actual parsing और appropriate data structure में data की loading करती हैं: + + - `.splitCsv()` Nextflow को बताता है कि CSV फ़ाइल को rows और columns को represent करने वाले array में parse करें + - `.map { line -> line[0] }` Nextflow को बताता है कि प्रत्येक row से केवल पहले column में element लें + + तो व्यवहार में, निम्नलिखित CSV फ़ाइल से शुरू करते हुए: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + हमने उसे एक array में transform किया है जो इस तरह दिखता है: + + ```txt title="Array contents" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + और फिर हमने तीन rows में से प्रत्येक से पहला element लिया है और उन्हें एक Nextflow channel में load किया है जिसमें अब `Hello`, `Bonjour`, और `Holà` हैं। + + यदि तुम channels और operators को गहराई से समझना चाहते हो, जिसमें उन्हें खुद कैसे लिखना है, [Hello Nextflow Part 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file) देखो। + +#### 1.4.2. प्रत्येक greeting पर process call करो + +अगला, workflow के `main:` block की अंतिम पंक्ति में, हम loaded `greeting_ch` channel को `sayHello()` process को इनपुट के रूप में प्रदान करते हैं। + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) +``` + +यह Nextflow को बताता है कि channel में प्रत्येक element पर, _i.e._ प्रत्येक greeting पर individually process run करे। +और क्योंकि Nextflow इस तरह से smart है, यह इन process calls को संभव होने पर parallel में run करेगा, available computing infrastructure पर निर्भर करते हुए। + +इस तरह तुम comparatively बहुत कम code के साथ बहुत सारे डेटा (कई samples, या data points, जो भी तुम्हारी research की unit है) की कुशल और scalable processing achieve कर सकते हो। + +#### 1.4.3. Outputs को कैसे नाम दिया जाता है + +अंत में, यह देखने के लिए process code पर एक quick look लेने लायक है कि हम output फ़ाइलों को uniquely नाम कैसे देते हैं। + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +तुम देखते हो कि, `1-hello.nf` में इस process के version की तुलना में, output declaration और command का relevant bit output फ़ाइल नाम में greeting value शामिल करने के लिए बदल गए हैं। + +यह ensure करने का एक तरीका है कि output फ़ाइल नाम common results डायरेक्टरी में publish होने पर collide नहीं होंगे। + +और यही एकमात्र change है जो हमें process declaration के अंदर करना पड़ा! + +### सीख + +तुम basic level पर समझते हो कि channels और operators हमें कई inputs को कुशलता से process करने में कैसे enable करते हैं। + +### आगे क्या? + +जानो कि multi-step workflows कैसे constructed होते हैं और वे कैसे operate करते हैं। + +--- + +## 2. Multi-step workflows चलाना + +अधिकांश real-world workflows में एक से अधिक step होते हैं। +आइए जो हमने अभी channels के बारे में सीखा उस पर build करें, और देखें कि Nextflow multi-step workflow में processes को एक साथ जोड़ने के लिए channels और operators का उपयोग कैसे करता है। + +उस end के लिए, हम तुम्हें एक example workflow प्रदान करते हैं जो तीन अलग-अलग steps को एक साथ chain करता है और निम्नलिखित demonstrate करता है: + +1. एक process से अगले में data flow कराना +2. कई process calls से outputs को एक single process call में collect करना + +Specifically, हमने workflow का एक expanded version बनाया है जिसे `2b-multistep.nf` कहा जाता है जो प्रत्येक इनपुट greeting लेता है, इसे uppercase में convert करता है, फिर सभी uppercased greetings को एक single output फ़ाइल में collect करता है। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +पहले की तरह, हम पहले workflow चलाएंगे फिर code देखेंगे कि क्या नया है। + +### 2.1. Workflow चलाओ + +अपने terminal में निम्नलिखित कमांड चलाओ: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "कमांड आउटपुट" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +तुम देखते हो कि जैसा कि promised था, workflow के भाग के रूप में कई steps run किए गए; पहले दो (`sayHello` और `convertToUpper`) presumably प्रत्येक individual greeting पर run किए गए, और तीसरा (`collectGreetings`) सभी तीन `convertToUpper` calls के outputs पर केवल एक बार run किया गया होगा। + +### 2.2. Outputs खोजो + +आइए `results` डायरेक्टरी पर एक नज़र डालकर verify करें कि वास्तव में यही हुआ। + +??? abstract "डायरेक्टरी सामग्री" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +जैसा कि तुम देख सकते हो, हमारे पास `2b-multistep` नाम की एक नई डायरेक्टरी है, और इसमें पहले की तुलना में काफी अधिक फ़ाइलें हैं। +कुछ फ़ाइलों को `intermediates` नाम की एक subdirectory में group किया गया है, जबकि दो फ़ाइलें top level पर स्थित हैं। + +वे दो multi-step workflow के final results हैं। +फ़ाइल नाम देखने और उनकी contents check करने के लिए एक मिनट लो ताकि confirm हो सके कि वे वही हैं जो तुम expect करते हो। + +??? abstract "फ़ाइल सामग्री" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +पहली में हमारी तीन greetings हैं, जैसा कि promised था uppercased और एक single फ़ाइल में वापस collect की गई। +दूसरी एक report फ़ाइल है जो run के बारे में कुछ information summarize करती है। + +### 2.3. Code की जांच करो + +आइए code देखें और multi-step workflows के लिए key patterns identify करें। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Use a text replacement tool to convert the greeting to uppercase + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline पैरामीटर + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +वहां बहुत कुछ हो रहा है, लेकिन workflow के पिछले version की तुलना में सबसे obvious difference यह है कि अब कई process definitions हैं, और correspondingly, workflow block में कई process calls हैं। + +आइए करीब से देखें और देखें कि क्या हम सबसे interesting pieces identify कर सकते हैं। + +#### 2.3.1. Workflow structure को visualize करना + +यदि तुम Nextflow extension के साथ VSCode का उपयोग कर रहे हो, तो किसी भी Nextflow script में workflow block के ठीक ऊपर displayed छोटे `DAG preview` link पर click करके तुम processes कैसे connected हैं इसका एक helpful diagram प्राप्त कर सकते हो। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +यह तुम्हें एक अच्छा overview देता है कि processes कैसे connected हैं और वे क्या produce करते हैं। + +तुम देखते हो कि original `sayHello` process के अलावा, अब हमारे पास `convertToUpper` और `collectGreetings` भी हैं, जो उन processes के नामों से match करते हैं जो हमने console आउटपुट में देखे। +दो नई process definitions `sayHello` process के समान तरीके से structured हैं, सिवाय इसके कि `collectGreetings` एक अतिरिक्त input parameter `batch` लेता है और दो outputs produce करता है। + +हम प्रत्येक के लिए code में detail में नहीं जाएंगे, लेकिन यदि तुम curious हो, तो तुम [Hello Nextflow के Part 2](../hello_nextflow/03_hello_workflow.md) में details देख सकते हो। + +अभी के लिए, आइए dig करें कि processes एक दूसरे से कैसे connected हैं। + +#### 2.3.2. Processes कैसे connected हैं + +यहां देखने की वास्तव में interesting बात यह है कि workflow के `main:` block में process calls कैसे एक साथ chained हैं। + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +तुम देख सकते हो कि पहला process call, `sayHello(greeting_ch)`, unchanged है। +फिर अगला process call, `convertToUpper` को, `sayHello` के output को `sayHello.out` के रूप में refer करता है। + +Pattern सरल है: `processName.out` एक process के output channel को refer करता है, जिसे सीधे अगले process को pass किया जा सकता है। +इस तरह हम Nextflow में एक step से दूसरे में data shuttle करते हैं। + +#### 2.3.3. एक process कई inputs ले सकता है + +तीसरा process call, `collectGreetings` को, थोड़ा अलग है। + +```groovy title="2b-multistep.nf" linenums="77" + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +तुम देखते हो कि इस call को दो inputs दिए गए हैं, `convertToUpper.out.collect()` और `params.batch`। +अभी के लिए `.collect()` bit को ignore करते हुए, हम इसे `collectGreetings(input1, input2)` के रूप में generalize कर सकते हैं। + +यह process module में दो input declarations से match करता है: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +जब Nextflow इसे parse करता है, यह call में पहले input को `path input_files` को assign करेगा, और दूसरे को `val batch_name` को। + +तो अब तुम जानते हो कि एक process कई inputs ले सकता है, और workflow block में call कैसी दिखती है। + +अब आइए उस पहले input, `convertToUpper.out.collect()` पर करीब से नज़र डालें। + +#### 2.3.4. `collectGreetings` call में `collect()` क्या करता है + +`sayHello` के output को `convertToUpper` को pass करने के लिए, हमने simply `sayHello` के output channel को `sayHello.out` के रूप में refer किया। लेकिन अगले step के लिए, हम `convertToUpper.out.collect()` का reference देख रहे हैं। + +यह `collect()` bit क्या है और यह क्या करता है? + +यह एक operator है, बिल्कुल। जैसे `splitCsv` और `map` operators जो हमने पहले encounter किए थे। +इस बार operator को `collect` कहा जाता है, और यह `convertToUpper` द्वारा produced output channel पर apply होता है। + +`collect` operator का उपयोग एक ही process के कई calls से outputs को collect करने और उन्हें एक single channel element में package करने के लिए किया जाता है। + +इस workflow के context में, यह `convertToUpper.out` channel में तीन uppercased greetings ले रहा है --जो तीन अलग-अलग channel items हैं, और normally अगले process द्वारा अलग-अलग calls में handle की जाएंगी-- और उन्हें एक single item में package कर रहा है। + +अधिक practical terms में: यदि हम `collectGreetings()` को feed करने से पहले `convertToUpper()` के output पर `collect()` apply नहीं करते, Nextflow simply प्रत्येक greeting पर independently `collectGreetings()` run करेगा, जो हमारे goal को achieve नहीं करेगा। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +इसके विपरीत, `collect()` का उपयोग करना हमें workflow के दूसरे step द्वारा produced सभी अलग-अलग uppercased greetings लेने और उन्हें सब एक साथ pipeline के तीसरे step में एक single call को feed करने की अनुमति देता है। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +इस तरह हम सभी greetings को वापस एक ही फ़ाइल में लाते हैं। + +Process calls के बीच channels की contents पर transformations apply करने के लिए कई अन्य [operators](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) उपलब्ध हैं। + +यह pipeline developers को उनकी pipeline की flow logic customize करने में बहुत flexibility देता है। +Downside यह है कि यह कभी-कभी pipeline क्या कर रही है यह decipher करना कठिन बना सकता है। + +#### 2.3.5. एक input parameter का default value हो सकता है + +तुमने शायद देखा होगा कि `collectGreetings` एक दूसरा input लेता है, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +यह workflow को `--batch` नाम का एक CLI parameter pass करता है। +हालांकि, जब हमने पहले workflow launch किया, हमने `--batch` parameter specify नहीं किया। + +वहां क्या हो रहा है? +`params` block पर एक नज़र डालो: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Workflow में एक default value configured है, इसलिए हमें इसे provide करने की जरूरत नहीं है। +लेकिन यदि हम कमांड लाइन पर एक provide करते हैं, तो default के बजाय जो value हम specify करते हैं वह use होगी। + +इसे try करो: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "कमांड आउटपुट" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +तुम्हें अपने custom batch name के साथ named नए final outputs देखने चाहिए। + +??? abstract "डायरेक्टरी सामग्री" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +यह input configuration का एक aspect है, जिसे हम Part 3 में अधिक detail में cover करेंगे, लेकिन अभी के लिए important बात यह जानना है कि input parameters को default values दी जा सकती हैं। + +#### 2.3.6. एक process कई outputs produce कर सकता है + +`collectGreetings` process definition में, हम निम्नलिखित output declarations देखते हैं: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +जिन्हें फिर `publish:` block में `emit:` के साथ दिए गए name से refer किया जाता है: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +यह specific outputs को workflow में अन्य processes को individually pass करना आसान बनाता है, विभिन्न operators के combination में। + +#### 2.3.7. Published outputs को organize किया जा सकता है + +`output` block में, हमने intermediate results को group करने के लिए custom paths का उपयोग किया है ताकि workflow के सिर्फ final outputs को pick out करना आसान हो। + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Published outputs को organize करने के और भी sophisticated तरीके हैं; हम configuration पर part में कुछ touch करेंगे। + +!!! tip "Workflows build करने के बारे में अधिक जानना चाहते हो?" + + Multi-step workflows build करने की detailed coverage के लिए, [Hello Nextflow Part 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md) देखो। + +### सीख + +तुम basic level पर समझते हो कि channels और operators का उपयोग करके multi-step workflows कैसे constructed होते हैं और वे कैसे operate करते हैं। +तुमने यह भी देखा है कि processes कई inputs ले सकते हैं और कई outputs produce कर सकते हैं, और इन्हें structured तरीके से publish किया जा सकता है। + +### आगे क्या? + +जानो कि code reuse और maintainability को promote करने के लिए Nextflow pipelines को कैसे modularize किया जा सकता है। + +--- + +## 3. Modularized pipelines चलाना + +अब तक, हमने जो सभी workflows देखे हैं उनमें एक single workflow फ़ाइल थी जिसमें सभी relevant code था। + +हालांकि, real-world pipelines आमतौर पर _modularized_ होने से benefit करती हैं, मतलब code अलग-अलग फ़ाइलों में split है। +यह उनके development और maintenance को अधिक efficient और sustainable बना सकता है। + +यहां हम Nextflow में code modularity के सबसे common form को demonstrate करने जा रहे हैं, जो **modules** का उपयोग है। + +Nextflow में, एक **module** एक single process definition है जो एक standalone code फ़ाइल में अपने आप में encapsulated है। +Workflow में module use करने के लिए, तुम बस अपनी workflow code फ़ाइल में एक single-line import statement जोड़ते हो; फिर तुम process को workflow में normally integrate कर सकते हो। +यह workflow code की multiple copies produce किए बिना process definitions को multiple workflows में reuse करना possible बनाता है। + +अब तक हम ऐसे workflows चला रहे थे जिनके सभी processes एक monolithic code फ़ाइल में included थे। +अब हम देखने जा रहे हैं कि जब processes individual modules में stored होते हैं तो यह कैसा दिखता है। + +हमने बेशक demonstration purposes के लिए एक suitable workflow फिर से तैयार की है, जिसे `2c-modules.nf` कहा जाता है, साथ ही `modules/` डायरेक्टरी में located modules का एक set। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "डायरेक्टरी सामग्री" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +तुम देखते हो कि चार Nextflow फ़ाइलें हैं, प्रत्येक processes में से एक के नाम पर। +तुम अभी के लिए `cowpy.nf` फ़ाइल को ignore कर सकते हो; हम बाद में उस पर आएंगे। + +### 3.1. Code की जांच करो + +इस बार हम पहले code देखने जा रहे हैं। +`2c-modules.nf` workflow फ़ाइल open करके शुरू करो। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Modules को include करें + +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline पैरामीटर + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +तुम देखते हो कि workflow logic पिछले workflow version के exactly same है। +हालांकि, process code workflow फ़ाइल से गायब है, और इसके बजाय `modules` के अंतर्गत अलग फ़ाइलों की ओर point करने वाले `include` statements हैं। + +```groovy title="hello-modules.nf" linenums="3" +// Modules को include करें +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +उन फ़ाइलों में से एक open करो और तुम्हें corresponding process का code मिलेगा। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' को एक फ़ाइल में प्रिंट करने के लिए echo का उपयोग करें + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +जैसा कि तुम देख सकते हो, process code change नहीं हुआ है; इसे बस main workflow फ़ाइल में होने के बजाय एक individual module फ़ाइल में copy किया गया है। +वही अन्य दो processes पर भी लागू होता है। + +तो आइए देखें कि इस नए version को run करना कैसा दिखता है। + +### 3.2. Workflow चलाओ + +अपने terminal में यह कमांड चलाओ, `-resume` flag के साथ: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +तुम देखोगे कि सभी process executions successfully cached हुए, मतलब Nextflow ने recognize किया कि यह requested work पहले ही कर चुका है, भले ही code split हो गया है और main workflow फ़ाइल का नाम बदल गया है। + +इसमें से कुछ भी Nextflow को matter नहीं करता; जो matter करता है वह job script है जो सभी code को एक साथ pull और evaluate करने के बाद generate होती है। + +!!! tip "सुझाव" + + Workflow के एक section को 'subworkflow' के रूप में encapsulate करना भी possible है जिसे एक larger pipeline में import किया जा सकता है, लेकिन यह इस course के scope के बाहर है। + + तुम [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/) पर Side Quest में composable workflows develop करने के बारे में अधिक जान सकते हो। + +### सीख + +तुम जानते हो कि code reuse को promote करने और maintainability improve करने के लिए processes को standalone modules में कैसे store किया जा सकता है। + +### आगे क्या? + +Software dependencies manage करने के लिए containers का उपयोग करना सीखो। + +--- + +## 4. Containerized software का उपयोग करना + +अब तक जो workflows हम examples के रूप में use कर रहे थे उन्हें बस हमारे environment में उपलब्ध UNIX tools का उपयोग करके बहुत basic text processing operations run करने की जरूरत थी। + +हालांकि, real-world pipelines को आमतौर पर specialized tools और packages की आवश्यकता होती है जो अधिकांश environments में default रूप से included नहीं होते। +आमतौर पर, तुम्हें इन tools को install करना होगा, उनकी dependencies manage करनी होंगी, और किसी भी conflicts को resolve करना होगा। + +यह सब बहुत tedious और annoying है। +इस समस्या को address करने का एक बेहतर तरीका **containers** का उपयोग करना है। + +एक **container** एक lightweight, standalone, executable unit of software है जो container **image** से बनाई जाती है जिसमें code, system libraries और settings सहित application run करने के लिए आवश्यक सब कुछ शामिल होता है। + +!!! tip "सुझाव" + + हम यह [Docker](https://www.docker.com/get-started/) technology का उपयोग करके सिखाते हैं, लेकिन Nextflow [कई अन्य container technologies](https://www.nextflow.io/docs/latest/container.html#) को भी support करता है। + +### 4.1. Container को directly use करो + +पहले, आइए एक container के साथ directly interact करने की कोशिश करें। +यह तुम्हारी understanding को solidify करने में मदद करेगा कि containers क्या हैं इससे पहले कि हम उन्हें Nextflow में use करना शुरू करें। + +#### 4.1.1. Container image pull करो + +Container use करने के लिए, तुम आमतौर पर container registry से container image download या "pull" करते हो, और फिर container instance create करने के लिए container image run करते हो। + +General syntax इस प्रकार है: + +```bash title="Syntax" +docker pull '<container>' +``` + +- `docker pull` container system को container repository से container image pull करने का instruction है। +- `'<container>'` container image का URI address है। + +एक example के रूप में, आइए एक container image pull करें जिसमें [cowpy](https://github.com/jeffbuttars/cowpy) है, `cowsay` नाम के tool का एक python implementation जो मज़ेदार तरीके से arbitrary text inputs display करने के लिए ASCII art generate करता है। + +विभिन्न repositories हैं जहां तुम published containers पा सकते हो। +हमने इस Docker container image को `cowpy` Conda package से generate करने के लिए [Seqera Containers](https://seqera.io/containers/) service का उपयोग किया: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`। + +Complete pull कमांड चलाओ: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "कमांड आउटपुट" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +यह system को specified image download करने के लिए कहता है। +Download complete होने के बाद, तुम्हारे पास container image की एक local copy है। + +#### 4.1.2. Container spin up करो + +Containers को one-off कमांड के रूप में run किया जा सकता है, लेकिन तुम उन्हें interactively भी use कर सकते हो, जो तुम्हें container के अंदर एक shell prompt देता है और तुम्हें command के साथ play करने की अनुमति देता है। + +General syntax इस प्रकार है: + +```bash title="Syntax" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'` container system को container image से container instance spin up करने और उसमें एक कमांड execute करने का instruction है। +- `--rm` system को कमांड complete होने के बाद container instance shut down करने के लिए कहता है। + +Fully assembled, container execution कमांड इस तरह दिखता है: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +वह कमांड चलाओ, और तुम्हें अपना prompt कुछ इस तरह बदलता देखना चाहिए `(base) root@b645838b3314:/tmp#`, जो indicate करता है कि तुम अब container के अंदर हो। + +तुम directory contents list करने के लिए `ls` चलाकर इसे verify कर सकते हो: + +```bash +ls / +``` + +??? success "कमांड आउटपुट" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +तुम देखते हो कि container के अंदर filesystem तुम्हारे host system पर filesystem से अलग है। + +!!! tip "सुझाव" + + जब तुम एक container run करते हो, यह default रूप से host system से isolated होता है। + इसका मतलब है कि container host system पर किसी भी files को access नहीं कर सकता जब तक तुम explicitly इसे ऐसा करने की अनुमति नहीं देते यह specify करके कि तुम `docker run` कमांड के भाग के रूप में following syntax का उपयोग करके एक volume mount करना चाहते हो: + + ```bash title="Syntax" + -v <outside_path>:<inside_path> + ``` + + यह effectively container wall के through एक tunnel establish करता है जिसका उपयोग तुम अपने filesystem के उस part को access करने के लिए कर सकते हो। + + यह [Hello Nextflow के Part 5](../hello_nextflow/05_hello_containers.md) में अधिक detail में cover किया गया है। + +#### 4.1.3. `cowpy` tool चलाओ + +Container के अंदर से, तुम `cowpy` कमांड directly run कर सकते हो। + +```bash +cowpy "Hello Containers" +``` + +??? success "कमांड आउटपुट" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +यह default cow character (या 'cowacter') की ASCII art produce करता है जिसमें हमारे द्वारा specified text वाला speech bubble है। + +अब जब तुमने basic usage test कर लिया है, तुम इसे कुछ parameters देने की कोशिश कर सकते हो। +उदाहरण के लिए, tool documentation कहता है कि हम `-c` के साथ character set कर सकते हैं। + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "कमांड आउटपुट" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +इस बार ASCII art आउटपुट Linux penguin, Tux, दिखाता है, क्योंकि हमने `-c tux` parameter specify किया। + +चूंकि तुम container के अंदर हो, तुम input parameters vary करते हुए cowpy कमांड जितनी बार चाहो run कर सकते हो, अपने system पर किसी भी libraries को install करने की चिंता किए बिना। + +??? tip "अन्य उपलब्ध characters" + + एक अलग character pick करने के लिए '-c' flag use करो, जिसमें शामिल हैं: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +इसके साथ free feel करके play करो। +जब तुम done हो जाओ, `exit` कमांड का उपयोग करके container exit करो: + +```bash +exit +``` + +तुम अपने normal shell में वापस पाओगे। + +### 4.2. Workflow में container use करो + +जब हम एक pipeline run करते हैं, हम Nextflow को बताना चाहते हैं कि प्रत्येक step पर कौन सा container use करना है, और importantly, हम चाहते हैं कि यह वह सारा काम handle करे जो हमने अभी किया: container pull करो, इसे spin up करो, कमांड run करो और जब यह done हो जाए तो container tear down करो। + +अच्छी खबर: यही exactly है जो Nextflow हमारे लिए करने जा रहा है। +हमें बस प्रत्येक process के लिए एक container specify करना है। + +यह काम कैसे करता है demonstrate करने के लिए, हमने अपनी workflow का एक और version बनाया है जो तीसरे step में produced collected greetings की फ़ाइल पर `cowpy` run करता है। + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +इसे speech bubble में तीन greetings के साथ ASCII art containing एक फ़ाइल output करनी चाहिए। + +#### 4.2.1. Code की जांच करो + +Workflow पिछले वाले के बहुत similar है, plus `cowpy` run करने का extra step। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Modules को include करें + +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline पैरामीटर + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // एक अभिवादन emit करें + sayHello(greeting_ch) + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + // सभी अभिवादनों को एक फ़ाइल में collect करें + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy के साथ अभिवादनों का ASCII art जनरेट करें + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +तुम देखते हो कि यह workflow एक module फ़ाइल से `cowpy` process import करती है, और इसे `collectGreetings()` call के output पर call करती है, plus `params.character` नाम का एक input parameter। + +```groovy title="2d-container.nf" linenums="25" +// cowpy के साथ ASCII art जनरेट करें +cowpy(collectGreetings.out, params.character) +``` + +`cowpy` process, जो ASCII art generate करने के लिए cowpy कमांड wrap करता है, `cowpy.nf` module में defined है। + +??? full-code "पूर्ण code फ़ाइल" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // cowpy के साथ ASCII art जनरेट करें (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +`cowpy` process को दो inputs चाहिए: speech bubble में डालने के लिए text containing input फ़ाइल का path (`input_file`), और character variable के लिए एक value। + +Importantly, इसमें `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'` पंक्ति भी शामिल है, जो उस container URI की ओर point करती है जिसका हमने पहले use किया था। + +#### 4.2.2. Check करो कि Docker configuration में enabled है + +हम इस प्रशिक्षण course के Part 3 को slightly anticipate करने जा रहे हैं `nextflow.config` configuration फ़ाइल introduce करके, जो Nextflow workflow execution configure करने के लिए offer करता है main ways में से एक है। +जब `nextflow.config` नाम की एक फ़ाइल current डायरेक्टरी में present होती है, Nextflow automatically इसे load करेगा और इसमें contained किसी भी configuration को apply करेगा। + +उस end के लिए, हमने एक `nextflow.config` फ़ाइल include की है जिसमें Docker enable करने वाली code की एक single पंक्ति है। + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +यह configuration Nextflow को किसी भी process के लिए Docker use करने के लिए कहती है जो एक compatible container specify करता है। + +!!! tip "सुझाव" + + `-with-docker <container>` parameter का उपयोग करके कमांड-लाइन से, per-run basis पर Docker execution enable करना technically possible है। + हालांकि, यह हमें केवल entire workflow के लिए एक container specify करने की अनुमति देता है, जबकि जो approach हमने तुम्हें अभी दिखाया वह हमें प्रति process एक अलग container specify करने की अनुमति देता है। + बाद वाला modularity, code maintenance और reproducibility के लिए बहुत बेहतर है। + +#### 4.2.3. Workflow चलाओ + +Recap करने के लिए, यह वह है जो हम run करने वाले हैं: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +क्या तुम्हें लगता है यह काम करेगा? + +आइए `-resume` flag के साथ workflow run करें, और specify करें कि हम character को turkey चाहते हैं। + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +पहले तीन steps cached हुए क्योंकि हमने उन्हें पहले run कर लिया था, लेकिन `cowpy` process नया है इसलिए वह actually run होता है। + +तुम `results` डायरेक्टरी में `cowpy` step का output पा सकते हो। + +??? abstract "फ़ाइल सामग्री" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +तुम देखते हो कि character सभी greetings बोल रहा है, क्योंकि यह collected uppercased greetings की फ़ाइल पर run किया गया। + +अधिक महत्वपूर्ण बात, हम इसे cowpy और इसकी सभी dependencies का proper installation किए बिना अपनी pipeline के भाग के रूप में run करने में सक्षम थे। +और अब हम pipeline को collaborators के साथ share कर सकते हैं और उन्हें इसे उनके infrastructure पर run करवा सकते हैं बिना उन्हें Docker या इसके alternatives में से किसी एक (जैसे Singularity/Apptainer) के अलावा कुछ भी install करने की जरूरत के, जैसा कि ऊपर mentioned है। + +#### 4.2.4. Inspect करो कि Nextflow ने containerized task कैसे launch किया + +इस section के एक final coda के रूप में, आइए `cowpy` process calls में से एक के लिए work subdirectory पर एक नज़र डालें ताकि यह थोड़ा और insight मिले कि Nextflow hood के नीचे containers के साथ कैसे काम करता है। + +`cowpy` process के लिए work subdirectory का path खोजने के लिए अपने `nextflow run` कमांड का output check करो। +ऊपर दिखाए गए run के लिए जो हमें मिला उसे देखते हुए, `cowpy` process के लिए console log पंक्ति `[7f/caf718]` से शुरू होती है। +यह निम्नलिखित truncated डायरेक्टरी path से correspond करता है: `work/7f/caf718`। + +उस डायरेक्टरी में, तुम्हें `.command.run` फ़ाइल मिलेगी जिसमें वे सभी commands हैं जो Nextflow ने pipeline execute करते समय तुम्हारी ओर से run किए। + +??? abstract "फ़ाइल सामग्री" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + ... + ``` + +तुम देख सकते हो कि इसमें container को pull और mount करने के लिए setup instructions शामिल हैं, साथ ही script अंदर चलाने के instructions। + +### सीख + +तुम जानते हो कि Nextflow processes को container images specify करके software dependencies provide करना कैसे संभव बनाता है। + +### आगे क्या? + +यह Part 2 के अंत को mark करता है। +अगले part में, तुम workflow execution को configure करना सीखोगे जैसे inputs और outputs manage करना, software packaging technologies के बीच switch करना, और HPC या cloud जैसे different execution platforms पर run करना। + +[Part 3: Run configuration](./03_config.md) पर जारी रखो। diff --git a/docs/hi/docs/nextflow_run/03_config.md b/docs/hi/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..bdb3933148 --- /dev/null +++ b/docs/hi/docs/nextflow_run/03_config.md @@ -0,0 +1,1443 @@ +# भाग 3: Run configuration + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह section explore करेगा कि pipeline के व्यवहार को customize करने, इसे different environments में adapt करने, और resource usage को optimize करने के लिए Nextflow pipeline की configuration कैसे manage करें _workflow code की एक भी पंक्ति बदले बिना_। + +ऐसा करने के कई तरीके हैं, जिन्हें combination में use किया जा सकता है और [यहां](https://www.nextflow.io/docs/latest/config.html) described precedence के order के अनुसार interpret किया जाता है। + +इस course के इस part में, हम तुम्हें सबसे simple और सबसे common configuration फ़ाइल mechanism, `nextflow.config` फ़ाइल, दिखाने जा रहे हैं, जिसे तुमने Part 2 में containers पर section में पहले ही encounter किया था। + +हम Nextflow configuration के essential components जैसे process directives, executors, profiles, और parameter files पर जाएंगे। +इन configuration options को effectively utilize करना सीखकर, तुम Nextflow pipelines की flexibility, scalability, और performance का पूरा लाभ उठा सकते हो। + +इन configuration elements को exercise करने के लिए, हम इस प्रशिक्षण course के Part 2 के अंत में जो workflow आखिरी बार चलाया था उसकी एक fresh copy चलाने जा रहे हैं, जिसका नाम `3-main.nf` रखा गया है। + +यदि तुम Hello pipeline से familiar नहीं हो या तुम्हें reminder की जरूरत हो, [यह info page](../info/hello_pipeline.md) देखो। + +--- + +## 1. Workflow input parameters manage करें + +??? example "परिदृश्य" + + तुमने एक pipeline download की है और इसे बार-बार same input files और settings के साथ run करना चाहते हो, लेकिन तुम हर बार सभी parameters type नहीं करना चाहते। + या शायद तुम pipeline को एक colleague के लिए set up कर रहे हो जो command-line arguments के साथ comfortable नहीं है। + +हम configuration के एक aspect से शुरू करने जा रहे हैं जो simply अब तक हम जो कर रहे थे उसका एक extension है: input parameters का management। + +Currently, हमारी workflow कई parameter values command-line के माध्यम से accept करने के लिए set up है, जो workflow script में ही एक `params` block में declared हैं। +एक की default value उसकी declaration के भाग के रूप में set है। + +हालांकि, तुम सभी के लिए defaults set करना चाह सकते हो, या existing default को override करना चाह सकते हो बिना कमांड लाइन पर parameters specify किए, या original script फ़ाइल modify किए। + +ऐसा करने के कई तरीके हैं; हम तुम्हें तीन basic तरीके दिखाने जा रहे हैं जो बहुत commonly use होते हैं। + +### 1.1. `nextflow.config` में values set up करें + +यह सबसे simple approach है, हालांकि यह possibly least flexible है क्योंकि main `nextflow.config` फ़ाइल कुछ ऐसी नहीं है जिसे तुम हर run के लिए edit करना चाहते हो। +लेकिन इसका advantage है कि यह workflow में parameters _declare_ करने (जो definitely वहां belong करता है) बनाम _default values_ supply करने की concerns को separate करता है, जो configuration फ़ाइल में अधिक home पर हैं। + +आइए इसे दो steps में करें। + +#### 1.1.1. Configuration फ़ाइल में एक `params` block बनाओ + +`nextflow.config` फ़ाइल में निम्नलिखित code changes करो: + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +ध्यान दो कि हमने simply workflow से `params` block को configuration फ़ाइल में copy नहीं किया। +`batch` parameter जिसकी default value पहले से declared थी, उसके लिए syntax थोड़ा different है। +Workflow फ़ाइल में, वह एक typed declaration है। +Configuration में, वे value assignments हैं। + +Technically, यह workflow फ़ाइल में still specified default values को override करने के लिए sufficient है। +तुम `batch` के लिए default value modify कर सकते हो और workflow run करके satisfy हो सकते हो कि configuration फ़ाइल में set value workflow फ़ाइल में set को override करती है। + +लेकिन configuration को पूरी तरह से configuration फ़ाइल में move करने की spirit में, आइए उस default value को workflow फ़ाइल से entirely remove करें। + +#### 1.1.2. Workflow फ़ाइल में `batch` के लिए default value remove करो + +`3-main.nf` workflow फ़ाइल में निम्नलिखित code change करो: + +=== "बाद में" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "पहले" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +अब workflow फ़ाइल itself इन parameters के लिए कोई default values set नहीं करती। + +#### 1.1.3. Pipeline चलाओ + +आइए test करें कि यह command line में कोई parameters specify किए बिना correctly काम करता है। + +```bash +nextflow run 3-main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +यह अभी भी पहले जैसा ही output produce करता है। + +Final ASCII art output `results/3-main/` डायरेक्टरी में है, `cowpy-COLLECTED-batch-output.txt` नाम के अंतर्गत, पहले जैसा ही। + +??? abstract "फ़ाइल सामग्री" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Functionally, इस move ने कुछ नहीं बदला, लेकिन conceptually configuration फ़ाइल में default values set होना थोड़ा cleaner है। + +### 1.2. Run-specific configuration फ़ाइल use करें + +??? example "परिदृश्य" + + तुम अपनी main configuration फ़ाइल modify किए बिना different settings के साथ experiment करना चाहते हो। + +तुम ऐसा एक subdirectory में एक नई `nextflow.config` फ़ाइल बनाकर कर सकते हो जिसे तुम अपने experiments के लिए working directory के रूप में use करोगे। + +#### 1.2.1. Blank configuration के साथ working directory बनाओ + +आइए एक नई डायरेक्टरी बनाकर और उसमें move करके शुरू करें: + +```bash +mkdir -p tux-run +cd tux-run +``` + +फिर, उस डायरेक्टरी में एक blank configuration फ़ाइल बनाओ: + +```bash +touch nextflow.config +``` + +यह एक empty फ़ाइल produce करती है। + +#### 1.2.2. Experimental configuration set up करो + +अब नई फ़ाइल open करो और जो parameters तुम customize करना चाहते हो वे add करो: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +ध्यान दो कि input फ़ाइल का path directory structure को reflect करना चाहिए। + +#### 1.2.3. Pipeline चलाओ + +अब हम अपनी नई working directory के भीतर से pipeline run कर सकते हैं। +Path को accordingly adapt करना सुनिश्चित करो! + +```bash +nextflow run ../3-main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +यह `tux-run/` के अंतर्गत directories का एक नया set create करेगा जिसमें `tux-run/work/` और `tux-run/results/` शामिल हैं। + +इस run में, Nextflow हमारी current डायरेक्टरी में `nextflow.config` को pipeline की root डायरेक्टरी में `nextflow.config` के साथ combine करता है, और इस तरह default character (turkey) को tux character से override करता है। + +Final output फ़ाइल में greetings बोलते हुए tux character होना चाहिए। + +??? abstract "फ़ाइल सामग्री" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +बस इतना ही; अब तुम्हारे पास अपनी 'normal' configuration modify किए बिना experimenting के लिए एक space है। + +!!! warning "चेतावनी" + + अगले section में जाने से पहले पिछली डायरेक्टरी में वापस change करना सुनिश्चित करो! + + ```bash + cd .. + ``` + +अब आइए parameter values set करने का एक और useful तरीका देखें। + +### 1.3. Parameter फ़ाइल use करें + +??? example "परिदृश्य" + + तुम्हें exact run parameters किसी collaborator के साथ share करने होंगे, या उन्हें publication के लिए record करना होगा। + +Subdirectory approach experimenting के लिए बढ़िया काम करता है, लेकिन इसमें थोड़ा setup involve है और requires कि तुम paths को accordingly adapt करो। +जब तुम अपनी pipeline को values के specific set के साथ run करना चाहते हो, या किसी और को minimal effort के साथ ऐसा करने में enable करना चाहते हो, तो एक simpler approach है। + +Nextflow हमें YAML या JSON format में parameter फ़ाइल के माध्यम से parameters specify करने की अनुमति देता है, जो default values के alternative sets manage और distribute करना बहुत convenient बनाता है, साथ ही run-specific parameter values भी। + +#### 1.3.1. Example parameter फ़ाइल की जांच करो + +इसे demonstrate करने के लिए, हम current डायरेक्टरी में एक example parameter फ़ाइल provide करते हैं, जिसे `test-params.yaml` कहा जाता है: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +इस parameter फ़ाइल में प्रत्येक input के लिए एक key-value pair है जिसे हम specify करना चाहते हैं। +ध्यान दो कि यदि तुम configuration फ़ाइल से syntax compare करो तो equal signs (`=`) के बजाय colons (`:`) का use है। +Config फ़ाइल Groovy में लिखी है, जबकि parameter फ़ाइल YAML में लिखी है। + +!!! info "जानकारी" + + हम एक example के रूप में parameter फ़ाइल का JSON version भी provide करते हैं लेकिन हम यहां इसके साथ run नहीं करने जा रहे। + उसे अपने आप try करने के लिए free feel करो। + +#### 1.3.2. Pipeline चलाओ + +इस parameter फ़ाइल के साथ workflow run करने के लिए, simply base कमांड में `-params-file <filename>` add करो। + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Final output फ़ाइल में greetings बोलते हुए stegosaurus character होना चाहिए। + +??? abstract "फ़ाइल सामग्री" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Parameter फ़ाइल use करना overkill लग सकता है जब तुम्हारे पास specify करने के लिए केवल कुछ parameters हों, लेकिन कुछ pipelines दर्जनों parameters expect करती हैं। +उन cases में, parameter फ़ाइल use करना हमें massive command lines type किए बिना और workflow script modify किए बिना runtime पर parameter values provide करने की अनुमति देगा। + +यह collaborators को parameters के sets distribute करना भी आसान बनाता है, या publication के लिए supporting information के रूप में, उदाहरण के लिए। +यह तुम्हारे काम को दूसरों द्वारा अधिक reproducible बनाता है। + +### सीख + +तुम जानते हो कि workflow inputs manage करने के लिए key configuration options का लाभ कैसे उठाएं। + +### आगे क्या? + +सीखो कि तुम्हारे workflow outputs कहां और कैसे publish होते हैं इसे कैसे manage करें। + +--- + +## 2. Workflow outputs manage करें + +??? example "परिदृश्य" + + तुम्हारी pipeline outputs को एक hardcoded डायरेक्टरी में publish करती है, लेकिन तुम हर बार workflow code edit किए बिना project या experiment name से results organize करना चाहते हो। + +हमें जो workflow मिली है वह workflow-level output declarations के लिए paths use करती है, जो terribly flexible नहीं है और इसमें बहुत repetition involve है। + +आइए कुछ common तरीके देखें जिनसे तुम इसे अधिक flexible होने के लिए configure कर सकते हो। + +### 2.1. `outputDir` directory name customize करो + +अब तक हमने जो workflow का प्रत्येक version run किया है उसने अपने outputs को output definitions में hardcoded एक different subdirectory में publish किया है। + +आइए इसे एक user-configurable parameter use करने के लिए change करें। +हम इसके लिए एक whole new parameter create कर सकते थे, लेकिन आइए `batch` parameter use करें क्योंकि यह right there है। + +#### 2.1.1. Configuration फ़ाइल में `outputDir` के लिए एक value set करो + +Nextflow outputs publish करने के लिए जो path use करता है वह `outputDir` option द्वारा controlled है। +सभी outputs के लिए path change करने के लिए, तुम `nextflow.config` configuration फ़ाइल में इस option के लिए एक value set कर सकते हो। + +`nextflow.config` फ़ाइल में निम्नलिखित code add करो: + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +यह built-in default path, `results/`, को `results/` plus subdirectory के रूप में `batch` parameter की value से replace करेगा। +तुम चाहो तो `results` part भी change कर सकते हो। + +Temporary change के लिए, तुम अपने command में `-output-dir` parameter use करके command-line से यह option set कर सकते हो (लेकिन फिर तुम `batch` parameter value use नहीं कर पाओगे)। + +#### 2.1.2. Hardcoded path का repeated part remove करो + +हमारे पास output options में अभी भी एक subdirectory hardcoded है, तो आइए अब उससे छुटकारा पाएं। + +Workflow फ़ाइल में निम्नलिखित code changes करो: + +=== "बाद में" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "पहले" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +हम `outputDir` default modify करने के बजाय प्रत्येक path में बस `${params.batch}` भी add कर सकते थे, लेकिन यह अधिक concise है। + +#### 2.1.3. Pipeline चलाओ + +आइए test करें कि यह correctly काम करता है, command line से batch name को `outdir` set करते हुए। + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +यह अभी भी पहले जैसा ही output produce करता है, सिवाय इसके कि इस बार हम अपने outputs `results/outdir/` के अंतर्गत पाते हैं। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +तुम जो भी directory hierarchy चाहो उसे construct करने के लिए इस approach को custom path definitions के साथ combine कर सकते हो। + +### 2.2. Process के अनुसार outputs organize करो + +Outputs को और organize करने का एक popular तरीका है इसे process के अनुसार करना, _i.e._ pipeline में run होने वाले प्रत्येक process के लिए subdirectories create करना। + +#### 2.2.1. Output paths को process names के reference से replace करो + +तुम्हें बस output path declaration में process के name को `<task>.name` के रूप में reference करना है। + +Workflow फ़ाइल में निम्नलिखित changes करो: + +=== "बाद में" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "पहले" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +यह output path configuration से remaining hardcoded elements remove करता है। + +#### 2.2.2. Pipeline चलाओ + +आइए test करें कि यह correctly काम करता है, command line से batch name को `pnames` set करते हुए। + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +यह अभी भी पहले जैसा ही output produce करता है, सिवाय इसके कि इस बार हम अपने outputs `results/pnames/` के अंतर्गत पाते हैं, और वे process के अनुसार grouped हैं। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +ध्यान दो कि यहां हमने `intermediates` बनाम top level पर final outputs के बीच distinction erase कर दिया है। +तुम बेशक इन approaches को mix और match कर सकते हो, उदाहरण के लिए पहले output का path `intermediates/${sayHello.name}` set करके। + +### 2.3. Workflow level पर publish mode set करो + +अंत में, repetitive code की मात्रा reduce करने की spirit में, हम per-output `mode` declarations को configuration में एक single पंक्ति से replace कर सकते हैं। + +#### 2.3.1. Configuration फ़ाइल में `workflow.output.mode` add करो + +`nextflow.config` फ़ाइल में निम्नलिखित code add करो: + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +`outputDir` option की तरह ही, configuration फ़ाइल में `workflow.output.mode` को एक value देना workflow फ़ाइल में जो set है उसे override करने के लिए sufficient होगा, लेकिन आइए unnecessary code anyway remove करें। + +#### 2.3.2. Workflow फ़ाइल से output mode remove करो + +Workflow फ़ाइल में निम्नलिखित changes करो: + +=== "बाद में" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "पहले" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +यह अधिक concise है, है ना? + +#### 2.3.3. Pipeline चलाओ + +आइए test करें कि यह correctly काम करता है, command line से batch name को `outmode` set करते हुए। + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +यह अभी भी पहले जैसा ही output produce करता है, सिवाय इसके कि इस बार हम अपने outputs `results/outmode/` के अंतर्गत पाते हैं। +वे अभी भी सब proper copies हैं, symlinks नहीं। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Per-output तरीके से mode set करने का मुख्य कारण जो तुम अभी भी चाह सकते हो वह है यदि तुम same workflow के भीतर mix और match करना चाहते हो, _i.e._ कुछ outputs copied हों और कुछ symlinked। + +बहुत सारे अन्य options हैं जिन्हें तुम इस तरह customize कर सकते हो, लेकिन hopefully यह तुम्हें options की range और उन्हें अपनी preferences के अनुसार effectively utilize करने का sense देता है। + +### सीख + +तुम जानते हो कि तुम्हारे outputs कहां publish होते हैं उन directories की naming और structure को कैसे control करें, साथ ही workflow output publishing mode। + +### आगे क्या? + +सीखो कि अपनी workflow configuration को अपने compute environment में कैसे adapt करें, software packaging technology से शुरू करते हुए। + +--- + +## 3. Software packaging technology select करें + +अब तक हम configuration elements देख रहे थे जो control करते हैं कि inputs कैसे जाते हैं और outputs कहां आते हैं। अब अपनी workflow configuration को अपने compute environment में adapt करने पर अधिक specifically focus करने का समय है। + +उस path पर पहला step यह specify करना है कि प्रत्येक step में run होने वाले software packages कहां से आने वाले हैं। +क्या वे local compute environment में पहले से installed हैं? +क्या हमें images retrieve करके उन्हें container system के माध्यम से run करने की जरूरत है? +या क्या हमें Conda packages retrieve करके एक local Conda environment build करने की जरूरत है? + +इस प्रशिक्षण course के पहले part (Parts 1-4) में हमने बस अपनी workflow में locally installed software use किया। +फिर Part 5 में, हमने Docker containers और `nextflow.config` फ़ाइल introduce की, जिसे हमने Docker containers का use enable करने के लिए use किया। + +अब आइए देखें कि हम `nextflow.config` फ़ाइल के माध्यम से एक alternative software packaging option कैसे configure कर सकते हैं। + +### 3.1. Config फ़ाइल में Docker disable करो और Conda enable करो + +??? example "परिदृश्य" + + तुम अपनी pipeline को एक HPC cluster पर move कर रहे हो जहां security reasons के लिए Docker allowed नहीं है। + Cluster Singularity और Conda support करता है, इसलिए तुम्हें अपनी configuration accordingly switch करनी होगी। + +Nextflow Singularity (जो HPC पर अधिक widely use होता है) सहित multiple container technologies support करता है, साथ ही software package managers जैसे Conda भी। + +हम Docker के बजाय Conda use करने के लिए अपनी configuration फ़ाइल change कर सकते हैं। +ऐसा करने के लिए, आइए `docker.enabled` की value को `false` में switch करें, और Conda का use enable करने वाला एक directive add करें: + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +यह Nextflow को उन processes के लिए Conda environments create और utilize करने की अनुमति देगा जिनके पास Conda packages specified हैं। +जिसका मतलब है कि अब हमें अपने `cowpy` process में उनमें से एक add करना होगा! + +### 3.2. Process definition में एक Conda package specify करो + +हमने `cowpy` tool containing Conda package के लिए URI पहले ही retrieve कर लिया है: `conda-forge::cowpy==1.1.5` + +अब हम `conda` directive use करके `cowpy` process definition में URI add करते हैं: + +=== "बाद में" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "पहले" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Clear करने के लिए, हम `docker` directive को _replace_ नहीं कर रहे, हम एक alternative option _add_ कर रहे हैं। + +!!! tip "सुझाव" + + किसी given conda package के लिए URI प्राप्त करने के कुछ different तरीके हैं। + हम [Seqera Containers](https://seqera.io/containers/) search query use करने की recommend करते हैं, जो तुम्हें एक URI देगा जिसे तुम copy और paste कर सकते हो, भले ही तुम इससे container create करने का plan नहीं कर रहे हो। + +### 3.3. Verify करने के लिए workflow run करो कि यह Conda use कर सकता है + +आइए try करें। + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "कमांड आउटपुट" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +यह बिना किसी issue के काम करना चाहिए और `results/conda` के अंतर्गत पहले जैसे ही outputs produce करना चाहिए। + +Behind the scenes, Nextflow ने Conda packages retrieve किए हैं और environment create किया है, जिसमें normally थोड़ा काम लगता है; तो यह अच्छा है कि हमें वह सब खुद नहीं करना पड़ा! + +!!! info "जानकारी" + + यह quickly run होता है क्योंकि `cowpy` package quite small है, लेकिन यदि तुम large packages के साथ काम कर रहे हो, पहली बार इसमें usual से थोड़ा अधिक समय लग सकता है, और तुम complete होने से पहले console output को एक मिनट या उससे अधिक के लिए 'stuck' देख सकते हो। + यह normal है और पहली बार नया package use करने पर Nextflow जो extra काम करता है उसके कारण है। + +हमारे standpoint से, यह exactly same दिखता है जैसे Docker के साथ run करना, भले ही backend पर mechanics थोड़ी different हैं। + +इसका मतलब है कि हम जरूरत पड़ने पर Conda environments के साथ run करने के लिए all set हैं। + +??? info "Docker और Conda को mix और match करना" + + चूंकि ये directives प्रति process assign की जाती हैं, 'mix और match' करना possible है, _i.e._ अपनी workflow में कुछ processes को Docker के साथ और अन्य को Conda के साथ run करने के लिए configure करना, उदाहरण के लिए, यदि तुम जो compute infrastructure use कर रहे हो वह दोनों support करती है। + उस case में, तुम अपनी configuration फ़ाइल में Docker और Conda दोनों enable करोगे। + यदि किसी given process के लिए दोनों available हैं, Nextflow containers को prioritize करेगा। + + और जैसा कि पहले noted था, Nextflow multiple other software packaging और container technologies support करता है, इसलिए तुम just उन दो तक limited नहीं हो। + +### सीख + +तुम जानते हो कि प्रत्येक process को कौन सा software package use करना चाहिए configure कैसे करें, और technologies के बीच switch कैसे करें। + +### आगे क्या? + +सीखो कि Nextflow द्वारा actually काम करने के लिए use किया जाने वाला execution platform कैसे change करें। + +--- + +## 4. Execution platform select करें + +??? example "परिदृश्य" + + तुम अपने laptop पर अपनी pipeline develop और test कर रहे थे, लेकिन अब तुम्हें इसे हजारों samples पर run करना है। + तुम्हारी institution के पास एक Slurm scheduler वाला HPC cluster है जिसे तुम इसके बजाय use करना चाहोगे। + +अब तक, हम अपनी pipeline local executor के साथ run कर रहे थे। +यह प्रत्येक task को उस machine पर execute करता है जिस पर Nextflow run हो रहा है। +जब Nextflow begin होता है, यह available CPUs और memory देखता है। +यदि run करने के लिए ready tasks के resources available resources से exceed करते हैं, Nextflow last tasks को execution से hold back रखेगा जब तक कि एक या अधिक earlier tasks finish नहीं हो जाते, necessary resources free करते हुए। + +Local executor convenient और efficient है, लेकिन यह उस single machine तक limited है। बहुत large workloads के लिए, तुम discover कर सकते हो कि तुम्हारी local machine एक bottleneck है, या तो इसलिए कि तुम्हारे पास एक single task है जिसे तुम्हारे पास available से अधिक resources चाहिए, या इसलिए कि तुम्हारे पास इतने सारे tasks हैं कि single machine के उन्हें run करने का wait करना बहुत long लेगा। + +Nextflow [कई different execution backends](https://www.nextflow.io/docs/latest/executor.html) support करता है, जिसमें HPC schedulers (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor और अन्य) के साथ-साथ cloud execution backends जैसे (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes और अधिक) शामिल हैं। + +### 4.1. Different backend target करना + +Executor का choice `executor` नाम की एक process directive द्वारा set होता है। +Default रूप से यह `local` पर set है, इसलिए following configuration implied है: + +```groovy title="Built-in configuration" +process { + executor = 'local' +} +``` + +Different backend target करने के लिए executor set करने के लिए, तुम simply वह executor specify करोगे जो तुम चाहते हो resource allocations के लिए ऊपर described similar syntax use करके (सभी options के लिए [documentation](https://www.nextflow.io/docs/latest/executor.html) देखो)। + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "चेतावनी" + + हम actually training environment में इसे test नहीं कर सकते क्योंकि यह HPC से connect करने के लिए set up नहीं है। + +### 4.2. Execution parameters के लिए backend-specific syntax से deal करना + +अधिकांश high-performance computing platforms allow करते हैं (और कभी-कभी require करते हैं) कि तुम resource allocation requests और limitations (जैसे number of CPUs और memory) और use करने के लिए job queue का name जैसे certain parameters specify करो। + +दुर्भाग्य से, इनमें से प्रत्येक system different technologies, syntaxes और configurations use करती है यह define करने के लिए कि job को कैसे define और relevant scheduler को submit किया जाना चाहिए। + +??? abstract "उदाहरण" + + उदाहरण के लिए, same job जिसे 8 CPUs और 4GB RAM की आवश्यकता है "my-science-work" queue पर execute होने के लिए backend के आधार पर following different तरीकों से express करने की जरूरत है। + + ```bash title="Config for SLURM / submit using sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config for PBS / submit using qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config for SGE / submit using qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Fortunately, Nextflow यह सब simplify करता है। +यह एक standardized syntax provide करता है ताकि तुम `cpus`, `memory` और `queue` (अन्य properties के लिए documentation देखो) जैसी relevant properties बस एक बार specify कर सको। +फिर, runtime पर, Nextflow executor setting के आधार पर appropriate backend-specific scripts generate करने के लिए उन settings use करेगा। + +हम अगले section में उस standardized syntax को cover करेंगे। + +### सीख + +तुम अब जानते हो कि different kinds की computing infrastructure use करने के लिए executor कैसे change करें। + +### आगे क्या? + +सीखो कि Nextflow में resource allocations और limitations कैसे evaluate और express करें। + +--- + +## 5. Compute resource allocations control करें + +??? example "परिदृश्य" + + तुम्हारी pipeline cluster पर keep failing हो रही है क्योंकि tasks memory limits exceed करने के लिए kill हो रहे हैं। + या शायद तुम्हें ऐसे resources के लिए charge किया जा रहा है जिनका तुम use नहीं कर रहे और costs optimize करना चाहते हो। + +अधिकांश high-performance computing platforms allow करते हैं (और कभी-कभी require करते हैं) कि तुम certain resource allocation parameters जैसे number of CPUs और memory specify करो। + +Default रूप से, Nextflow प्रत्येक process के लिए single CPU और 2GB memory use करेगा। +Corresponding process directives `cpus` और `memory` कहलाती हैं, इसलिए following configuration implied है: + +```groovy title="Built-in configuration" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +तुम इन values को modify कर सकते हो, या तो सभी processes के लिए या specific named processes के लिए, अपनी configuration फ़ाइल में additional process directives use करके। +Nextflow उन्हें chosen executor के लिए appropriate instructions में translate करेगा। + +लेकिन तुम कैसे जानोगे कि कौन सी values use करनी हैं? + +### 5.1. Resource utilization report generate करने के लिए workflow run करो + +??? example "परिदृश्य" + + तुम नहीं जानते कि तुम्हारे processes को कितनी memory या CPU चाहिए और resources waste करने या jobs kill होने से बचना चाहते हो। + +यदि तुम up front नहीं जानते कि तुम्हारे processes को कितनी CPU और memory likely चाहिए होगी, तुम कुछ resource profiling कर सकते हो, meaning तुम workflow को कुछ default allocations के साथ run करते हो, record करते हो कि प्रत्येक process ने कितना use किया, और वहां से, estimate करते हो कि base allocations कैसे adjust करनी हैं। + +Conveniently, Nextflow में ऐसा करने के लिए built-in tools शामिल हैं, और request पर तुम्हारे लिए happily एक report generate करेगा। + +ऐसा करने के लिए, अपनी command line में `-with-report <filename>.html` add करो। + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Report एक html फ़ाइल है, जिसे तुम download करके अपने browser में open कर सकते हो। तुम training environment में इसे view करने के लिए left पर file explorer में इस पर right click करके `Show preview` पर click भी कर सकते हो। + +Report को देखने में कुछ minutes लो और देखो कि क्या तुम resources adjust करने के लिए कुछ opportunities identify कर सकते हो। +जो tabs utilization results को allocated के percentage के रूप में show करते हैं उन पर click करना सुनिश्चित करो। +सभी available features describe करने वाला कुछ [documentation](https://www.nextflow.io/docs/latest/reports.html) है। + +### 5.2. सभी processes के लिए resource allocations set करो + +Profiling show करती है कि हमारी training workflow में processes बहुत lightweight हैं, इसलिए आइए default memory allocation को प्रति process 1GB तक reduce करें। + +अपनी `nextflow.config` फ़ाइल में, pipeline parameters section से पहले, निम्नलिखित add करो: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +यह हमारे द्वारा consume किए जाने वाले compute की मात्रा reduce करने में help करेगा। + +### 5.3. Specific process के लिए resource allocations set करो + +साथ ही, हम pretend करने जा रहे हैं कि `cowpy` process को others से अधिक resources चाहिए, बस इसलिए कि हम demonstrate कर सकें कि individual process के लिए allocations कैसे adjust करें। + +=== "बाद में" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "पहले" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +इस configuration के साथ, सभी processes 1GB memory और single CPU (implied default) request करेंगे, सिवाय `cowpy` process के, जो 2GB और 2 CPUs request करेगा। + +!!! info "जानकारी" + + यदि तुम्हारे पास कम CPUs वाली machine है और तुम प्रति process high number allocate करते हो, तुम process calls को एक दूसरे के पीछे queue होते देख सकते हो। + ऐसा इसलिए है क्योंकि Nextflow ensure करता है कि हम available से अधिक CPUs request न करें। + +### 5.4. Updated configuration के साथ workflow run करो + +आइए try करें, profiling report के लिए एक different filename supply करते हुए ताकि हम configuration changes से पहले और बाद की performance compare कर सकें। + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +तुम शायद कोई real difference notice नहीं करोगे क्योंकि यह इतना small workload है, लेकिन यह वह approach है जिसे तुम real-world workflow की performance और resource requirements analyze करने के लिए use करोगे। + +यह बहुत useful है जब तुम्हारे processes की different resource requirements हैं। यह तुम्हें guesswork नहीं, actual data के आधार पर प्रत्येक process के लिए सेट की गई resource allocations को right-size करने का power देता है। + +!!! tip "सुझाव" + + यह सिर्फ एक tiny taster है जो तुम resources के अपने use को optimize करने के लिए कर सकते हो। + Nextflow में itself कुछ really neat [dynamic retry logic](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) built in है जो resource limitations के कारण fail होने वाले jobs को retry करता है। + Additionally, Seqera Platform आपकी resource allocations को automatically optimize करने के लिए AI-driven tooling भी offer करता है। + +### 5.5. Resource limits add करो + +तुम जो computing executor और compute infrastructure use कर रहे हो उसके आधार पर, कुछ constraints हो सकती हैं कि तुम क्या (या must) allocate कर सकते हो। +उदाहरण के लिए, तुम्हारे cluster को require हो सकता है कि तुम certain limits के भीतर रहो। + +तुम `resourceLimits` directive use करके relevant limitations set कर सकते हो। Syntax इस तरह दिखता है जब यह process block में अकेला है: + +```groovy title="Syntax example" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow तुम्हारे द्वारा specified executor के आधार पर इन values को appropriate instructions में translate करेगा। + +हम इसे run नहीं करने जा रहे, क्योंकि training environment में हमारे पास relevant infrastructure तक access नहीं है। +हालांकि, यदि तुम resource allocations के साथ workflow run करने की try करते जो इन limits से exceed करती हैं, फिर `.command.run` script फ़ाइल में `sbatch` command look up करते, तुम देखोगे कि executor को actually भेजे जाने वाले requests `resourceLimits` द्वारा specified values पर capped हैं। + +??? info "Institutional reference configurations" + + nf-core project ने world भर में various institutions द्वारा shared [configuration files का collection](https://nf-co.re/configs/) compile किया है, जो HPC और cloud executors की एक wide range cover करती है। + + वे shared configs दोनों के लिए valuable हैं जो लोग वहां काम करते हैं और इसलिए बस अपनी institution की configuration out of the box utilize कर सकते हैं, और एक model के रूप में उन लोगों के लिए जो अपनी own infrastructure के लिए configuration develop करना चाहते हैं। + +### सीख + +तुम जानते हो कि resource utilization assess करने के लिए profiling report कैसे generate करें और सभी processes और/या individual processes के लिए resource allocations कैसे modify करें, साथ ही HPC पर run करने के लिए resource limitations set करें। + +### आगे क्या? + +सीखो कि preset configuration profiles कैसे set up करें और runtime पर उनके बीच switch करें। + +--- + +## 6. Preset configurations के बीच switch करने के लिए profiles use करें + +??? example "परिदृश्य" + + तुम regularly अपने laptop पर development के लिए और अपनी institution के HPC पर production runs के लिए pipelines run करने के बीच switch करते हो। + तुम हर बार environments switch करने पर manually configuration settings change करने से थक गए हो। + +हमने तुम्हें कई तरीके दिखाए हैं जिनसे तुम अपनी pipeline configuration को उस project के आधार पर customize कर सकते हो जिस पर तुम काम कर रहे हो या जो compute environment तुम use कर रहे हो। + +तुम शायद जो computing infrastructure use कर रहे हो उसके आधार पर alternative settings के बीच switch करना चाहो। उदाहरण के लिए, तुम अपने laptop पर locally develop और small-scale tests run करना चाहोगे, फिर HPC या cloud पर full-scale workloads run करना। + +Nextflow तुम्हें any number of profiles set up करने देता है जो different configurations describe करते हैं, जिन्हें तुम फिर configuration फ़ाइल itself modify करने के बजाय एक command-line argument use करके runtime पर select कर सकते हो। + +### 6.1. Local development और HPC पर execution के बीच switch करने के लिए profiles create करो + +आइए दो alternative profiles set up करें; एक regular computer पर small scale loads run करने के लिए, जहां हम Docker containers use करेंगे, और एक Slurm scheduler वाले university HPC पर run करने के लिए, जहां हम Conda packages use करेंगे। + +#### 6.1.1. Profiles set up करो + +अपनी `nextflow.config` फ़ाइल में, pipeline parameters section के बाद लेकिन output settings से पहले, निम्नलिखित add करो: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +तुम देखते हो कि university HPC के लिए, हम resource limitations भी specify कर रहे हैं। + +#### 6.1.2. Profile के साथ workflow run करो + +अपनी Nextflow command line में profile specify करने के लिए, हम `-profile` argument use करते हैं। + +आइए `my_laptop` configuration के साथ workflow run करने की try करें। + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +जैसा कि तुम देख सकते हो, यह हमें runtime पर configurations के बीच बहुत conveniently toggle करने की अनुमति देता है। + +!!! warning "चेतावनी" + + `univ_hpc` profile training environment में properly run नहीं होगी क्योंकि हमारे पास Slurm scheduler तक access नहीं है। + +यदि future में हम configuration के अन्य elements पाते हैं जो always इनके साथ co-occurring हैं, हम simply उन्हें corresponding profile(s) में add कर सकते हैं। +हम additional profiles भी create कर सकते हैं यदि configuration के अन्य elements हैं जिन्हें हम एक साथ group करना चाहते हैं। + +### 6.2. Test parameters का एक profile create करो + +??? example "परिदृश्य" + + तुम चाहते हो कि others अपना own input data gather किए बिना quickly तुम्हारी pipeline try कर सकें। + +Profiles सिर्फ infrastructure configuration के लिए नहीं हैं। +हम उन्हें workflow parameters के लिए default values set करने के लिए भी use कर सकते हैं, ताकि others के लिए workflow try करना आसान हो बिना उन्हें appropriate input values खुद gather करने के। +तुम इसे parameter फ़ाइल use करने का एक alternative consider कर सकते हो। + +#### 6.2.1. Profile set up करो + +इस context में default values express करने का syntax इस तरह दिखता है, एक profile के लिए जिसे हम `test` name देते हैं: + +```groovy title="Syntax example" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +यदि हम अपनी workflow के लिए एक test profile add करते हैं, `profiles` block इस तरह बन जाता है: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Technical configuration profiles की तरह ही, तुम जो भी arbitrary name चाहो उसके अंतर्गत parameters specify करने वाले multiple different profiles set up कर सकते हो। + +#### 6.2.2. Test profile के साथ locally workflow run करो + +Conveniently, profiles mutually exclusive नहीं हैं, इसलिए हम अपनी command line में following syntax `-profile <profile1>,<profile2>` (any number of profiles के लिए) use करके multiple profiles specify कर सकते हैं। + +यदि तुम ऐसे profiles combine करते हो जो configuration के same elements के लिए values set करते हैं और same configuration फ़ाइल में described हैं, Nextflow conflict resolve करेगा जो भी value उसने last में read की (_i.e._ जो भी फ़ाइल में बाद में आती है) उसे use करके। +यदि conflicting settings different configuration sources में set हैं, default [order of precedence](https://www.nextflow.io/docs/latest/config.html) apply होता है। + +आइए अपने previous command में test profile add करने की try करें: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +यह जहां possible हो Docker use करेगा और `results/test` के अंतर्गत outputs produce करेगा, और इस बार character comedic duo `dragonandcow` है। + +??? abstract "फ़ाइल सामग्री" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +इसका मतलब है कि जब तक हम workflow code के साथ कोई test data files distribute करते हैं, कोई भी command line या parameter फ़ाइल के माध्यम से अपने own inputs supply किए बिना quickly workflow try कर सकता है। + +!!! tip "सुझाव" + + हम externally stored larger files के लिए URLs point कर सकते हैं। + Nextflow उन्हें automatically download करेगा जब तक open connection है। + + अधिक details के लिए, Side Quest [Working with Files](../side_quests/working_with_files.md) देखो। + +### 6.3. Resolved configuration देखने के लिए `nextflow config` use करो + +जैसा कि ऊपर noted था, कभी-कभी same parameter को different values पर profiles में set किया जा सकता है जिन्हें तुम combine करना चाहते हो। +और अधिक generally, numerous places हैं जहां configuration के elements stored हो सकते हैं, और कभी-कभी same properties को different places में different values पर set किया जा सकता है। + +Nextflow किसी भी conflicts को resolve करने के लिए set [order of precedence](https://www.nextflow.io/docs/latest/config.html) apply करता है, लेकिन यह खुद determine करना tricky हो सकता है। +और भले ही कुछ भी conflicting न हो, सभी possible places look up करना tedious हो सकता है जहां चीजें configured हो सकती हैं। + +Fortunately, Nextflow में `config` नाम का एक convenient utility tool शामिल है जो तुम्हारे लिए उस whole process को automate कर सकता है। + +`config` tool तुम्हारी current working directory में सभी contents explore करेगा, किसी भी configuration files को hoover up करेगा, और fully resolved configuration produce करेगा जो Nextflow workflow run करने के लिए use करेगा। +यह तुम्हें कुछ भी launch किए बिना find out करने की अनुमति देता है कि कौन सी settings use होंगी। + +#### 6.3.1. Default configuration resolve करो + +Default रूप से apply होने वाली configuration resolve करने के लिए यह कमांड run करो। + +```bash +nextflow config +``` + +??? success "कमांड आउटपुट" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +यह तुम्हें base configuration दिखाता है जो तुम्हें मिलती है यदि तुम command line में कुछ भी extra specify नहीं करते। + +#### 6.3.2. Specific settings activated के साथ configuration resolve करो + +यदि तुम command-line parameters provide करते हो, जैसे एक या अधिक profiles enable करना या parameter फ़ाइल load करना, command additionally उन्हें account में लेगा। + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "कमांड आउटपुट" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'data/greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +यह तुम्हें दिखाता है कि profiles से configuration जोड़ने पर क्या मिलता है। + +### सीख + +तुम जानते हो कि how to create profiles to bundle configuration presets और runtime पर उनके बीच toggle कैसे करें। +तुम यह भी जानते हो कि `nextflow config` utility का use कैसे करें जो set होगा उसे resolve और view करने के लिए। + +### आगे क्या? + +Part 3 complete करने पर congratulations! अगले page पर proceed करो course summary देखने के लिए और अपनी Nextflow journey में next steps के बारे में जानने के लिए। diff --git a/docs/hi/docs/nextflow_run/index.md b/docs/hi/docs/nextflow_run/index.md new file mode 100644 index 0000000000..eea324eb76 --- /dev/null +++ b/docs/hi/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow workflows को लॉन्च और मैनेज करना + - आउटपुट (परिणाम) और लॉग फ़ाइलों को खोजना और समझना + - एक साधारण मल्टी-स्टेप workflow में मुख्य Nextflow कॉम्पोनेंट्स को पहचानना + - HPC और cloud सहित सामान्य कंप्यूटिंग प्लेटफॉर्म पर pipeline execution को कॉन्फ़िगर करना + - reproducibility, portability और कोड पुन: उपयोग के लिए सर्वोत्तम प्रथाओं को समझना जो pipelines को FAIR बनाती हैं, जिसमें कोड modularity और software containers शामिल हैं + audience_prerequisites: + - "**दर्शक:** यह कोर्स उन शिक्षार्थियों के लिए डिज़ाइन किया गया है जो Nextflow में बिल्कुल नए हैं और मौजूदा pipelines चलाना चाहते हैं।" + - "**कौशल:** कमांड लाइन, बुनियादी scripting अवधारणाओं और सामान्य फ़ाइल फॉर्मेट्स से कुछ परिचितता अपेक्षित है।" + - "**डोमेन:** सभी अभ्यास डोमेन-अज्ञेयवादी हैं, इसलिए किसी पूर्व वैज्ञानिक ज्ञान की आवश्यकता नहीं है।" +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run reproducible और scalable डेटा विश्लेषण workflows चलाने का एक हैंड्स-ऑन परिचय है।** + +व्यावहारिक उदाहरणों और निर्देशित अभ्यासों के माध्यम से, तुम Nextflow का उपयोग करने के मूल सिद्धांतों को सीखोगे, जिसमें pipelines कैसे execute करें, फ़ाइलों और software dependencies को कैसे मैनेज करें, execution को सहजता से parallelize कैसे करें, और विभिन्न कंप्यूटिंग वातावरणों में workflows कैसे चलाएं। + +तुम Nextflow के साथ workflows चलाने के लिए कौशल और आत्मविश्वास प्राप्त करोगे। + +<!-- additional_information --> + +## कोर्स अवलोकन + +### तुम क्या करोगे + +यह कोर्स हैंड्स-ऑन है, जिसमें लक्ष्य-उन्मुख अभ्यास हैं जो धीरे-धीरे जानकारी प्रस्तुत करने के लिए संरचित हैं। + +तुम एक Nextflow pipeline के कई संस्करण execute करोगे जो टेक्स्ट इनपुट को प्रोसेस करती है। +तुम एक साधारण संस्करण से शुरू करोगे जिसमें एक ही स्टेप है, और अंततः एक मल्टी-स्टेप संस्करण तक पहुंचोगे जो टेबुलर टेक्स्ट इनपुट की एक CSV फ़ाइल लेता है, कुछ transformation स्टेप्स चलाता है, और एक टेक्स्ट फ़ाइल आउटपुट करता है जिसमें transformed टेक्स्ट बोलते हुए एक character की ASCII तस्वीर होती है। + +यह कोर्स pipelines चलाने पर केंद्रित है (कोर `nextflow run` कमांड के नाम पर)। +यदि तुम Nextflow pipelines विकसित करने का परिचय खोज रहे हो, तो [Hello Nextflow](../hello_nextflow/index.md) देखो। + +### पाठ योजना + +हमने इसे तीन भागों में विभाजित किया है जो प्रत्येक Nextflow में लिखी गई pipelines को चलाने और मैनेज करने के विशिष्ट पहलुओं पर ध्यान केंद्रित करेंगे। + +| कोर्स अध्याय | सारांश | अनुमानित अवधि | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------- | +| [भाग 1: बुनियादी संचालन चलाएं](./01_basics.md) | एक साधारण workflow को लॉन्च और मैनेज करना | 30 मिनट | +| [भाग 2: असली pipelines चलाएं](./02_pipeline.md) | जटिल इनपुट प्रोसेस करना, मल्टी-स्टेप workflows चलाना, containers का उपयोग करना और execution को सहजता से parallelize करना | 60 मिनट | +| [भाग 3: Run configuration](./03_config.md) | pipeline व्यवहार को कस्टमाइज़ करना और विभिन्न कम्प्यूटेशनल वातावरणों में उपयोग को optimize करना | 60 मिनट | + +इस कोर्स के अंत तक, तुम अपनी वैज्ञानिक कंप्यूटिंग आवश्यकताओं के लिए reproducible workflows चलाने की अपनी यात्रा में अगले कदम उठाने के लिए अच्छी तरह तैयार होगे। + +कोर्स लेने के लिए तैयार हो? + +[सीखना शुरू करें :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/hi/docs/nextflow_run/next_steps.md b/docs/hi/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..4d234c558e --- /dev/null +++ b/docs/hi/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# कोर्स सारांश + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run प्रशिक्षण कोर्स पूरा करने पर बधाई हो! 🎉 + +<!-- placeholder for video --> + +## तुम्हारी यात्रा + +तुमने एक बहुत ही basic workflow से शुरू किया, और इसे run करना, outputs खोजना, और इसके execution को manage करना सीखा। +फिर, तुमने उस workflow के increasingly अधिक complex versions के माध्यम से काम किया और essential concepts और mechanisms को पहचानना सीखा जो Nextflow pipelines को power करते हैं, जिसमें channels और operators, code modularization, और containers शामिल हैं। +अंत में, तुमने सीखा कि अपनी preferences और अपने computational infrastructure में fit करने के लिए pipeline की configuration को कैसे customize करें। + +### तुमने क्या सीखा + +तुम अब Hello pipeline के execution को manage करने, describe करने कि यह कैसे structured है, और involved code के main pieces identify करने में सक्षम हो। + +- Hello workflow का final form input के रूप में text greetings containing एक CSV फ़ाइल लेता है। +- चार steps Nextflow processes (`sayHello`, `convertToUpper`, `collectGreetings`, और `cowpy`) के रूप में implemented हैं जो अलग module files में stored हैं। +- Results `results/` नाम की डायरेक्टरी में publish होते हैं। +- Pipeline का final output एक plain text फ़ाइल है जिसमें uppercased greetings बोलते हुए character की ASCII art है। + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** प्रत्येक greeting को अपनी own output फ़ाइल में लिखता है (_e.g._ "Hello-output.txt") +2. **`convertToUpper`:** प्रत्येक greeting को uppercase में convert करता है (_e.g._ "HELLO") +3. **`collectGreetings`:** सभी uppercase greetings को एक single batch फ़ाइल में collect करता है +4. **`cowpy`:** `cowpy` tool का उपयोग करके ASCII art generate करता है + +Workflow configuration flexible, reproducible तरीके से inputs और parameters provide करने का support करती है। + +### अर्जित कौशल + +इस hands-on course के माध्यम से, तुमने सीखा कि कैसे: + +- Locally Nextflow workflow launch करें +- Nextflow द्वारा generated outputs (results) और log files खोजें और interpret करें +- एक simple multi-step workflow बनाने वाले core Nextflow components recognize करें +- Operators और channel factories जैसे next-step concepts describe करें +- Different computing environments के लिए pipelines configure करें + +तुम अब अपने own work में existing Nextflow pipelines integrate करना शुरू करने के लिए foundational knowledge से equipped हो। + +## अपने skills build करने के लिए next steps + +यहां आगे क्या करना है इसके लिए हमारे top suggestions हैं: + +- बस Nextflow run मत करो, इसे लिखो! [Hello Nextflow](../hello_nextflow/index.md) के साथ Nextflow developer बनो +- [Nextflow for Science](../nf4_science/index.md) के साथ scientific analysis use case पर Nextflow apply करो +- [Hello nf-core](../hello_nf-core/index.md) के साथ nf-core के साथ शुरू करो +- [Debugging Side Quest](../side_quests/debugging.md) के साथ troubleshooting techniques सीखो + +अंत में, हम recommend करते हैं कि तुम [**Seqera Platform**](https://seqera.io/) पर एक नज़र डालो, Nextflow के creators द्वारा developed एक cloud-based platform जो तुम्हारी workflows launch और manage करना और भी आसान बनाता है, साथ ही तुम्हारे data manage करना और किसी भी environment में interactively analyses run करना। + +## Help प्राप्त करना + +Help resources और community support के लिए, [Help page](../help.md) देखो। + +## Feedback survey + +आगे बढ़ने से पहले, कृपया course survey complete करने के लिए एक मिनट लो! तुम्हारी feedback हमें सभी के लिए हमारी training materials improve करने में help करती है। + +[Survey लें :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/hi/docs/nextflow_run/survey.md b/docs/hi/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..33eb9e1f8d --- /dev/null +++ b/docs/hi/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Feedback survey + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आगे बढ़ने से पहले, कृपया training को rate करने, अपने experience के बारे में कोई भी feedback share करने, और हमें बताने के लिए कि हम तुम्हारी Nextflow journey में और क्या help कर सकते हैं, यह short 5-question survey complete करो। + +इसे complete करने में तुम्हें एक मिनट से भी कम समय लगना चाहिए। सभी के लिए हमारी training materials improve करने में help करने के लिए धन्यवाद! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/hi/docs/nf4_science/genomics/00_orientation.md b/docs/hi/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..374b0d9240 --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# अभिविन्यास + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +प्रशिक्षण वातावरण में सभी सॉफ़्टवेयर, कोड और डेटा मौजूद हैं जो इस प्रशिक्षण पाठ्यक्रम को पूरा करने के लिए आवश्यक हैं, इसलिए आपको स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। +हालांकि, लॉग इन करने के लिए आपको एक (मुफ़्त) अकाउंट की आवश्यकता होगी, और आपको इंटरफ़ेस से परिचित होने के लिए कुछ मिनट देने चाहिए। + +यदि आपने अभी तक ऐसा नहीं किया है, तो कृपया आगे बढ़ने से पहले [इस लिंक](../../../envsetup/) पर जाएँ। + +## उपलब्ध सामग्री + +इस प्रशिक्षण पाठ्यक्रम के दौरान, हम `nf4-science/genomics/` डायरेक्टरी में काम करेंगे, जिसमें आपको प्रशिक्षण workspace खोलने पर जाना होगा। +इस डायरेक्टरी में वे सभी कोड फ़ाइलें, परीक्षण डेटा और सहायक फ़ाइलें हैं जिनकी आपको आवश्यकता होगी। + +इस डायरेक्टरी की सामग्री को देखने के लिए स्वतंत्र महसूस करें; ऐसा करने का सबसे आसान तरीका VSCode इंटरफ़ेस में प्रशिक्षण workspace के बाईं ओर file explorer का उपयोग करना है। +वैकल्पिक रूप से, आप `tree` कमांड का उपयोग कर सकते हैं। +पूरे पाठ्यक्रम में, हम डायरेक्टरी संरचना और सामग्री को पठनीय रूप में प्रस्तुत करने के लिए `tree` के आउटपुट का उपयोग करते हैं, कभी-कभी स्पष्टता के लिए मामूली संशोधनों के साथ। + +यहाँ हम दूसरे स्तर तक सामग्री की तालिका बनाते हैं: + +```bash +tree . -L 2 +``` + +यदि आप इसे `nf4-science/genomics` के अंदर चलाते हैं, तो आपको निम्नलिखित आउटपुट दिखाई देना चाहिए: + +```console title="Directory contents" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "नोट" + + चिंता न करें यदि यह बहुत अधिक लगता है; हम पाठ्यक्रम के प्रत्येक चरण में प्रासंगिक भागों पर विचार करेंगे। + यह केवल आपको एक सामान्य अवलोकन देने के लिए है। + +**यहाँ एक सारांश है कि शुरू करने के लिए आपको क्या जानना चाहिए:** + +- **`.nf` फ़ाइलें** workflow scripts हैं जिनका नाम इस आधार पर रखा गया है कि वे पाठ्यक्रम के किस भाग में उपयोग की जाती हैं। + +- **फ़ाइल `nextflow.config`** एक configuration फ़ाइल है जो न्यूनतम वातावरण गुणों को सेट करती है। + आप अभी इसे अनदेखा कर सकते हैं। + +- **`data` डायरेक्टरी** में इनपुट डेटा और संबंधित संसाधन हैं, जिनका वर्णन पाठ्यक्रम में बाद में किया गया है। + +- **`solutions` डायरेक्टरी** में module फ़ाइलें और test configurations हैं जो पाठ्यक्रम के भाग 3 और 4 से परिणामित होती हैं। + इनका उद्देश्य आपके काम की जाँच करने और किसी भी समस्या का निवारण करने के लिए संदर्भ के रूप में उपयोग किया जाना है। + +!!!tip "सुझाव" + + यदि किसी कारण से आप इस डायरेक्टरी से बाहर चले जाते हैं, तो आप हमेशा इसमें वापस आने के लिए यह कमांड चला सकते हैं: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +अब, पाठ्यक्रम शुरू करने के लिए, इस पृष्ठ के निचले दाएँ कोने में तीर पर क्लिक करें। diff --git a/docs/hi/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/hi/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..3b4ace263b --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,721 @@ +# भाग 1: प्रति-नमूना वेरिएंट कॉलिंग + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस कोर्स के पहले भाग में, हम आपको एक सरल वेरिएंट कॉलिंग पाइपलाइन बनाना सिखाएंगे जो व्यक्तिगत सीक्वेंसिंग नमूनों पर GATK वेरिएंट कॉलिंग लागू करती है। + +### विधि का अवलोकन + +वेरिएंट कॉलिंग एक जीनोमिक विश्लेषण विधि है जिसका उद्देश्य एक संदर्भ जीनोम के सापेक्ष एक जीनोम अनुक्रम में भिन्नताओं की पहचान करना है। +यहाँ हम छोटे वेरिएंट कॉल करने के लिए डिज़ाइन किए गए टूल और विधियों का उपयोग करने जा रहे हैं, _यानी_ SNPs और indels। + +![GATK pipeline](img/gatk-pipeline.png) + +एक पूर्ण वेरिएंट कॉलिंग पाइपलाइन में आम तौर पर कई चरण शामिल होते हैं, जिनमें संदर्भ के साथ मैपिंग (कभी-कभी जीनोम संरेखण के रूप में संदर्भित) और वेरिएंट फ़िल्टरिंग और प्राथमिकता शामिल है। +सरलता के लिए, इस कोर्स के इस भाग में हम केवल वेरिएंट कॉलिंग भाग पर ध्यान केंद्रित करने जा रहे हैं। + +### डेटासेट + +हम निम्नलिखित डेटा और संबंधित संसाधन प्रदान करते हैं: + +- **एक संदर्भ जीनोम** जिसमें मानव क्रोमोसोम 20 (hg19/b37 से) का एक छोटा क्षेत्र और इसकी सहायक फ़ाइलें (इंडेक्स और अनुक्रम शब्दकोश) शामिल हैं। +- **तीन संपूर्ण जीनोम सीक्वेंसिंग नमूने** जो एक परिवार के तीन सदस्यों (माँ, पिता और बेटा) से संबंधित हैं, जिन्हें फ़ाइल आकार को छोटा रखने के लिए क्रोमोसोम 20 पर डेटा के एक छोटे से हिस्से तक सीमित किया गया है। + यह Illumina शॉर्ट-रीड सीक्वेंसिंग डेटा है जो पहले ही संदर्भ जीनोम से मैप किया जा चुका है, [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) प्रारूप (Binary Alignment Map, SAM का एक संपीड़ित संस्करण, Sequence Alignment Map) में प्रदान किया गया है। +- **जीनोमिक अंतरालों की एक सूची**, यानी जीनोम पर निर्देशांक जहाँ हमारे नमूनों में वेरिएंट कॉल करने के लिए उपयुक्त डेटा है, BED प्रारूप में प्रदान किया गया है। + +### वर्कफ़्लो + +इस कोर्स के इस भाग में, हम एक वर्कफ़्लो विकसित करने जा रहे हैं जो निम्नलिखित करती है: + +1. [Samtools](https://www.htslib.org/) का उपयोग करके प्रत्येक BAM इनपुट फ़ाइल के लिए एक इंडेक्स फ़ाइल बनाएं +2. प्रत्येक BAM इनपुट फ़ाइल पर GATK HaplotypeCaller चलाएं ताकि VCF (Variant Call Format) में प्रति-नमूना वेरिएंट कॉल उत्पन्न हो सकें + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note + + इंडेक्स फ़ाइलें बायोइन्फॉर्मेटिक्स फ़ाइल प्रारूपों की एक सामान्य विशेषता हैं; उनमें मुख्य फ़ाइल की संरचना के बारे में जानकारी होती है जो GATK जैसे टूल को पूरी फ़ाइल को पढ़े बिना डेटा के एक सबसेट तक पहुँचने की अनुमति देती है। + यह महत्वपूर्ण है क्योंकि ये फ़ाइलें कितनी बड़ी हो सकती हैं। + +--- + +## 0. वार्मअप: Samtools और GATK कमांड को इंटरैक्टिव रूप से टेस्ट करें + +पहले हम कमांड को मैन्युअल रूप से आज़माना चाहते हैं इससे पहले कि हम उन्हें वर्कफ़्लो में लपेटने का प्रयास करें। +हमें जिन टूल की आवश्यकता है (Samtools और GATK) GitHub Codespaces वातावरण में इंस्टॉल नहीं हैं, इसलिए हम उन्हें कंटेनर के माध्यम से उपयोग करेंगे ([Hello Containers](../../hello_nextflow/05_hello_containers.md) देखें)। + +!!! note + + सुनिश्चित करें कि आप `nf4-science/genomics` डायरेक्टरी में हैं ताकि जब आप `pwd` टाइप करें तो दिखाए गए पथ का अंतिम भाग `genomics` हो। + +### 0.1. Samtools के साथ BAM इनपुट फ़ाइल को इंडेक्स करें + +हम एक Samtools कंटेनर को पुल करने जा रहे हैं, इसे इंटरैक्टिव रूप से स्पिन करें और BAM फ़ाइलों में से एक पर `samtools index` कमांड चलाएं। + +#### 0.1.1. Samtools कंटेनर को पुल करें + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.1.2. Samtools कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.1.3. इंडेक्सिंग कमांड चलाएं + +[Samtools डॉक्यूमेंटेशन](https://www.htslib.org/doc/samtools-index.html) हमें BAM फ़ाइल को इंडेक्स करने के लिए चलाने के लिए कमांड लाइन देता है। + +हमें केवल इनपुट फ़ाइल प्रदान करनी होगी; टूल स्वचालित रूप से इनपुट फ़ाइलनाम में `.bai` जोड़कर आउटपुट के लिए एक नाम उत्पन्न करेगा। + +```bash +samtools index /data/bam/reads_mother.bam +``` + +यह तुरंत पूरा होना चाहिए, और अब आपको मूल BAM इनपुट फ़ाइल के समान डायरेक्टरी में `reads_mother.bam.bai` नामक एक फ़ाइल दिखनी चाहिए। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Samtools कंटेनर से बाहर निकलें + +```bash +exit +``` + +### 0.2. GATK HaplotypeCaller के साथ वेरिएंट कॉल करें + +हम एक GATK कंटेनर को पुल करने जा रहे हैं, इसे इंटरैक्टिव रूप से स्पिन करें और BAM फ़ाइल पर `gatk HaplotypeCaller` कमांड चलाएं जिसे हमने अभी इंडेक्स किया है। + +#### 0.2.1. GATK कंटेनर को पुल करें + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.2.2. GATK कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.2.3. वेरिएंट कॉलिंग कमांड चलाएं + +[GATK डॉक्यूमेंटेशन](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) हमें BAM फ़ाइल पर वेरिएंट कॉलिंग करने के लिए चलाने के लिए कमांड लाइन देता है। + +हमें BAM इनपुट फ़ाइल (`-I`) के साथ-साथ संदर्भ जीनोम (`-R`), आउटपुट फ़ाइल के लिए एक नाम (`-O`) और विश्लेषण करने के लिए जीनोमिक अंतरालों की एक सूची (`-L`) प्रदान करनी होगी। + +हालाँकि, हमें इंडेक्स फ़ाइल के पथ को निर्दिष्ट करने की आवश्यकता नहीं है; टूल स्वचालित रूप से इसे समान डायरेक्टरी में ढूंढेगा, स्थापित नामकरण और सह-स्थान सम्मेलन के आधार पर। +यही बात संदर्भ जीनोम की सहायक फ़ाइलों (इंडेक्स और अनुक्रम शब्दकोश फ़ाइलें, `*.fai` और `*.dict`) पर भी लागू होती है। + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +आउटपुट फ़ाइल `reads_mother.vcf` कंटेनर में आपकी वर्किंग डायरेक्टरी के अंदर बनाई गई है, इसलिए आप इसे VS Code फ़ाइल एक्सप्लोरर में तब तक नहीं देखेंगे जब तक आप आउटपुट फ़ाइल पथ नहीं बदलते। +हालाँकि, यह एक छोटी परीक्षण फ़ाइल है, इसलिए आप इसे खोलने और सामग्री देखने के लिए `cat` कर सकते हैं। +यदि आप फ़ाइल की शुरुआत तक स्क्रॉल करते हैं, तो आपको मेटाडेटा की कई पंक्तियों से बना एक हेडर मिलेगा, जिसके बाद वेरिएंट कॉल की एक सूची होगी, प्रति पंक्ति एक। + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +प्रत्येक पंक्ति नमूने के सीक्वेंसिंग डेटा में पहचाने गए संभावित वेरिएंट का वर्णन करती है। VCF प्रारूप की व्याख्या करने के लिए मार्गदर्शन के लिए, [यह उपयोगी लेख](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/) देखें। + +आउटपुट VCF फ़ाइल के साथ `reads_mother.vcf.idx` नामक एक इंडेक्स फ़ाइल है जो स्वचालित रूप से GATK द्वारा बनाई गई थी। +इसका वही कार्य है जो BAM इंडेक्स फ़ाइल का है, टूल को पूरी फ़ाइल लोड किए बिना डेटा के सबसेट को खोजने और पुनर्प्राप्त करने की अनुमति देना। + +#### 0.2.4. GATK कंटेनर से बाहर निकलें + +```bash +exit +``` + +### निष्कर्ष + +आप जानते हैं कि Samtools इंडेक्सिंग और GATK वेरिएंट कॉलिंग कमांड को उनके संबंधित कंटेनर में कैसे टेस्ट करें। + +### आगे क्या है? + +सीखें कि उन्हीं कमांड को दो-चरणीय वर्कफ़्लो में कैसे लपेटें जो कार्य निष्पादित करने के लिए कंटेनर का उपयोग करती है। + +--- + +## 1. एक सिंगल-स्टेज वर्कफ़्लो लिखें जो BAM फ़ाइल पर Samtools index चलाती है + +हम आपको एक वर्कफ़्लो फ़ाइल प्रदान करते हैं, `genomics-1.nf`, जो वर्कफ़्लो के मुख्य भागों की रूपरेखा देती है। +यह कार्यात्मक नहीं है; इसका उद्देश्य केवल एक कंकाल के रूप में काम करना है जिसका उपयोग आप वास्तविक वर्कफ़्लो लिखने के लिए करेंगे। + +### 1.1. इंडेक्सिंग प्रोसेस को परिभाषित करें + +आइए एक प्रोसेस लिखें, जिसे हम `SAMTOOLS_INDEX` कहेंगे, जो इंडेक्सिंग ऑपरेशन का वर्णन करती है। + +```groovy title="genomics-1.nf" linenums="9" +/* + * BAM इंडेक्स फ़ाइल जेनरेट करें + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +आपको इस प्रशिक्षण श्रृंखला के भाग 1 और भाग 2 में जो कुछ सीखा है, उससे सभी टुकड़ों को पहचानना चाहिए। + +यह प्रोसेस हमें `input_bam` इनपुट के माध्यम से एक फ़ाइल पथ पास करने की आवश्यकता होगी, तो आइए इसे अगले सेट करें। + +### 1.2. एक इनपुट पैरामीटर घोषणा जोड़ें + +फ़ाइल के शीर्ष पर, `Pipeline parameters` सेक्शन के तहत, हम `reads_bam` नामक एक CLI पैरामीटर घोषित करते हैं और इसे एक डिफ़ॉल्ट मान देते हैं। +इस तरह, हम आलसी हो सकते हैं और पाइपलाइन को लॉन्च करने के लिए कमांड टाइप करते समय इनपुट निर्दिष्ट नहीं करते (विकास उद्देश्यों के लिए)। + +```groovy title="genomics-1.nf" linenums="3" +/* + * Pipeline पैरामीटर + */ +params { + // प्राथमिक इनपुट + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +अब हमारे पास एक प्रोसेस तैयार है, साथ ही इसे चलाने के लिए एक इनपुट देने के लिए एक पैरामीटर है, तो आइए उन चीजों को एक साथ जोड़ें। + +!!! note + + `${projectDir}` एक बिल्ट-इन Nextflow वेरिएबल है जो उस डायरेक्टरी की ओर इशारा करता है जहाँ वर्तमान Nextflow वर्कफ़्लो स्क्रिप्ट (`genomics-1.nf`) स्थित है। + + यह वर्कफ़्लो रिपॉजिटरी में शामिल फ़ाइलों, डेटा डायरेक्टरी और अन्य संसाधनों को संदर्भित करना आसान बनाता है बिना पूर्ण पथों को हार्डकोड किए। + +### 1.3. SAMTOOLS_INDEX चलाने के लिए वर्कफ़्लो ब्लॉक जोड़ें + +`workflow` ब्लॉक में, हमें `SAMTOOLS_INDEX` प्रोसेस को इनपुट देने के लिए एक **channel** सेट करना होगा; फिर हम उस चैनल की सामग्री पर चलाने के लिए प्रोसेस को स्वयं कॉल कर सकते हैं। + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // इनपुट चैनल बनाएं (CLI पैरामीटर के माध्यम से एकल फ़ाइल) + reads_ch = channel.fromPath(params.reads_bam) + + // इनपुट BAM फ़ाइल के लिए इंडेक्स फ़ाइल बनाएं + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +वर्कफ़्लो ब्लॉक में दो सेक्शन हैं: + +- `main:` में चैनल ऑपरेशन और प्रोसेस कॉल शामिल हैं +- `publish:` घोषित करता है कि कौन से आउटपुट प्रकाशित किए जाने चाहिए, उन्हें नामित लक्ष्यों को सौंपते हुए + +आप देखेंगे कि हम वही `.fromPath` चैनल फैक्ट्री का उपयोग कर रहे हैं जो हमने [Hello Channels](../../hello_nextflow/02_hello_channels.md) में उपयोग किया था। +वास्तव में, हम कुछ बहुत समान कर रहे हैं। +अंतर यह है कि हम Nextflow को बता रहे हैं कि फ़ाइल पथ को ही चैनल में इनपुट तत्व के रूप में लोड करें, इसकी सामग्री को पढ़ने के बजाय। + +### 1.4. यह परिभाषित करने के लिए एक आउटपुट ब्लॉक जोड़ें कि परिणाम कहाँ प्रकाशित किए जाते हैं + +वर्कफ़्लो ब्लॉक के बाद, हम एक `output` ब्लॉक जोड़ते हैं जो निर्दिष्ट करता है कि वर्कफ़्लो आउटपुट कहाँ प्रकाशित करें। + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +`publish:` सेक्शन से प्रत्येक नामित लक्ष्य (जैसे `bam_index`) को अपना ब्लॉक मिलता है जहाँ आप बेस आउटपुट डायरेक्टरी के सापेक्ष आउटपुट पथ को कॉन्फ़िगर कर सकते हैं। + +!!! note + + भले ही हम यहाँ जिन डेटा फ़ाइलों का उपयोग कर रहे हैं वे बहुत छोटी हैं, जीनोमिक्स में वे बहुत बड़ी हो सकती हैं। + डिफ़ॉल्ट रूप से, Nextflow प्रकाशन डायरेक्टरी में आउटपुट फ़ाइलों के लिए सिम्बोलिक लिंक बनाता है, जो अनावश्यक फ़ाइल प्रतियों से बचता है। + आप `mode` विकल्प का उपयोग करके इस व्यवहार को बदल सकते हैं (जैसे, `mode 'copy'`) वास्तविक प्रतियाँ बनाने के लिए। + ध्यान रखें कि जब आप अपनी `work` डायरेक्टरी को साफ़ करते हैं तो सिमलिंक टूट जाएंगे, इसलिए प्रोडक्शन वर्कफ़्लो के लिए आप `mode 'copy'` का उपयोग करना चाह सकते हैं। + +### 1.5. आउटपुट डायरेक्टरी को कॉन्फ़िगर करें + +बेस आउटपुट डायरेक्टरी `outputDir` कॉन्फ़िग विकल्प के माध्यम से सेट की जाती है। इसे `nextflow.config` में जोड़ें: + +=== "बाद में" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "पहले" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. वर्कफ़्लो चलाएं यह सत्यापित करने के लिए कि इंडेक्सिंग चरण काम करता है + +चलो वर्कफ़्लो चलाएं! एक अनुस्मारक के रूप में, हमें कमांड लाइन में इनपुट निर्दिष्ट करने की आवश्यकता नहीं है क्योंकि हमने इनपुट पैरामीटर घोषित करते समय इनपुट के लिए एक डिफ़ॉल्ट मान सेट किया था। + +```bash +nextflow run genomics-1.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +आप वर्क डायरेक्टरी या परिणाम डायरेक्टरी में देखकर जाँच सकते हैं कि इंडेक्स फ़ाइल सही ढंग से जेनरेट की गई है। + +??? abstract "वर्क डायरेक्टरी सामग्री" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "परिणाम डायरेक्टरी सामग्री" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +यह रहा! + +### निष्कर्ष + +आप जानते हैं कि एक जीनोमिक्स टूल को सिंगल-स्टेप Nextflow वर्कफ़्लो में कैसे लपेटें और इसे कंटेनर का उपयोग करके चलाएं। + +### आगे क्या है? + +एक दूसरा चरण जोड़ें जो पहले के आउटपुट का उपभोग करता है। + +--- + +## 2. इंडेक्स की गई BAM फ़ाइल पर GATK HaplotypeCaller चलाने के लिए दूसरा प्रोसेस जोड़ें + +अब जब हमारे पास हमारी इनपुट फ़ाइल के लिए एक इंडेक्स है, तो हम वेरिएंट कॉलिंग चरण को सेट करने के लिए आगे बढ़ सकते हैं, जो वर्कफ़्लो का दिलचस्प हिस्सा है। + +### 2.1. वेरिएंट कॉलिंग प्रोसेस को परिभाषित करें + +आइए एक प्रोसेस लिखें, जिसे हम `GATK_HAPLOTYPECALLER` कहेंगे, जो वेरिएंट कॉलिंग ऑपरेशन का वर्णन करती है। + +```groovy title="genomics-1.nf" linenums="44" +/* + * GATK HaplotypeCaller के साथ वेरिएंट कॉल करें + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +आप देखेंगे कि हमने यहाँ कुछ नया सिंटैक्स पेश किया है (`emit:`) हमारे प्रत्येक आउटपुट चैनल को विशिष्ट रूप से नाम देने के लिए, और इसके कारण जल्द ही स्पष्ट हो जाएंगे। + +यह कमांड काफी अधिक इनपुट लेता है, क्योंकि GATK को एक सरल इंडेक्सिंग कार्य की तुलना में विश्लेषण करने के लिए अधिक जानकारी की आवश्यकता होती है। +लेकिन आप ध्यान देंगे कि GATK कमांड में सूचीबद्ध की तुलना में इनपुट ब्लॉक में और भी अधिक इनपुट परिभाषित हैं। ऐसा क्यों है? + +!!! note + + GATK BAM इंडेक्स फ़ाइल और संदर्भ जीनोम की सहायक फ़ाइलों को देखना जानता है क्योंकि यह उन फ़ाइलों के आसपास के सम्मेलनों के बारे में जानता है। + हालाँकि, Nextflow को डोमेन-अज्ञेयवादी होने के लिए डिज़ाइन किया गया है और यह बायोइन्फॉर्मेटिक्स फ़ाइल प्रारूप आवश्यकताओं के बारे में कुछ नहीं जानता है। + +हमें Nextflow को स्पष्ट रूप से बताना होगा कि उसे रनटाइम पर वर्किंग डायरेक्टरी में उन फ़ाइलों को स्टेज करना होगा; अन्यथा यह ऐसा नहीं करेगा, और GATK (सही ढंग से) इंडेक्स फ़ाइलों के गायब होने के बारे में एक त्रुटि फेंकेगा। + +इसी तरह, हमें आउटपुट VCF की इंडेक्स फ़ाइल (`"${input_bam}.vcf.idx"` फ़ाइल) को स्पष्ट रूप से सूचीबद्ध करना होगा ताकि Nextflow को पता चले कि यदि बाद के चरणों में इसकी आवश्यकता हो तो उस फ़ाइल का ट्रैक रखना होगा। + +### 2.2. सहायक इनपुट के लिए परिभाषाएं जोड़ें + +चूंकि हमारी नई प्रोसेस को कुछ अतिरिक्त फ़ाइलें प्रदान करने की अपेक्षा है, हम `Pipeline parameters` सेक्शन के तहत उनके लिए कुछ CLI पैरामीटर सेट करते हैं, कुछ डिफ़ॉल्ट मानों के साथ (पहले जैसे ही कारण)। + +```groovy title="genomics-1.nf" linenums="8" + // सहायक फ़ाइलें + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. सहायक फ़ाइल पथों को रखने के लिए वेरिएबल बनाएं + +जबकि मुख्य डेटा इनपुट चैनलों के माध्यम से गतिशील रूप से स्ट्रीम किए जाते हैं, सहायक फ़ाइलों को संभालने के लिए दो दृष्टिकोण हैं। अनुशंसित दृष्टिकोण स्पष्ट चैनल बनाना है, जो डेटा प्रवाह को स्पष्ट और अधिक सुसंगत बनाता है। वैकल्पिक रूप से, सरल मामलों के लिए वेरिएबल बनाने के लिए file() फ़ंक्शन का उपयोग किया जा सकता है, विशेष रूप से जब आपको कई प्रोसेस में एक ही फ़ाइल को संदर्भित करने की आवश्यकता हो - हालाँकि ध्यान रखें कि यह अभी भी चैनल बनाता है अस्पष्ट रूप से। <!-- TODO: स्पष्ट करें: क्या यह अभी भी टाइप किए गए इनपुट के साथ आवश्यक है? --> + +इसे वर्कफ़्लो ब्लॉक में जोड़ें (`reads_ch` निर्माण के बाद, `main:` सेक्शन के अंदर): + +```groovy title="genomics-1.nf" linenums="79" + // सहायक फ़ाइलों (संदर्भ और अंतराल) के लिए फ़ाइल पथ लोड करें + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +यह सहायक फ़ाइल पथों को किसी भी प्रोसेस को इनपुट के रूप में प्रदान करने के लिए उपलब्ध कराएगा जिन्हें उनकी आवश्यकता है। + +### 2.4. GATK_HAPLOTYPECALLER चलाने के लिए वर्कफ़्लो ब्लॉक में एक कॉल जोड़ें + +अब जब हमने अपनी दूसरी प्रोसेस सेट कर ली है और सभी इनपुट और सहायक फ़ाइलें तैयार और उपलब्ध हैं, तो हम वर्कफ़्लो बॉडी में `GATK_HAPLOTYPECALLER` प्रोसेस में एक कॉल जोड़ सकते हैं। + +```groovy title="genomics-1.nf" linenums="88" + // इंडेक्स की गई BAM फ़ाइल से वेरिएंट कॉल करें + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +आपको इस प्रशिक्षण श्रृंखला के भाग 1 से `*.out` सिंटैक्स को पहचानना चाहिए; हम Nextflow को बता रहे हैं कि `SAMTOOLS_INDEX` द्वारा आउटपुट किए गए चैनल को लें और उसे `GATK_HAPLOTYPECALLER` प्रोसेस कॉल में प्लग करें। + +!!! note + + आप देखेंगे कि इनपुट प्रोसेस की कॉल में उसी क्रम में प्रदान किए जाते हैं जैसे वे प्रोसेस के इनपुट ब्लॉक में सूचीबद्ध हैं। + Nextflow में, इनपुट स्थितीय हैं, जिसका अर्थ है कि आपको _उसी क्रम का पालन करना होगा_; और बेशक तत्वों की संख्या समान होनी चाहिए। + +### 2.5. प्रकाशन सेक्शन और आउटपुट ब्लॉक को अपडेट करें + +हमें VCF आउटपुट को शामिल करने के लिए `publish:` सेक्शन को अपडेट करने की आवश्यकता है, और `output` ब्लॉक में संबंधित लक्ष्य जोड़ने की आवश्यकता है। + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. वर्कफ़्लो चलाएं यह सत्यापित करने के लिए कि वेरिएंट कॉलिंग चरण काम करता है + +चलो विस्तारित वर्कफ़्लो को `-resume` के साथ चलाएं ताकि हमें इंडेक्सिंग चरण को फिर से चलाने की आवश्यकता न हो। + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +अब यदि हम कंसोल आउटपुट को देखते हैं, तो हम दो प्रोसेस सूचीबद्ध देखते हैं। + +पहली प्रोसेस को कैशिंग के कारण छोड़ दिया गया था, जैसा कि अपेक्षित था, जबकि दूसरी प्रोसेस चलाई गई क्योंकि यह बिल्कुल नई है। + +आप परिणाम डायरेक्टरी में आउटपुट फ़ाइलें पाएंगे (वर्क डायरेक्टरी के सिम्बोलिक लिंक के रूप में)। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +यदि आप VCF फ़ाइल खोलते हैं, तो आपको उसी सामग्री को देखना चाहिए जो आपने GATK कमांड को सीधे कंटेनर में चलाकर जेनरेट की गई फ़ाइल में की थी। + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +यह वह आउटपुट है जिसे हम अपने अध्ययन में प्रत्येक नमूने के लिए उत्पन्न करने की परवाह करते हैं। + +### निष्कर्ष + +आप जानते हैं कि एक बहुत ही बुनियादी दो-चरणीय वर्कफ़्लो कैसे बनाएं जो वास्तविक विश्लेषण कार्य करती है और जीनोमिक्स फ़ाइल प्रारूप की विशिष्टताओं जैसे सहायक फ़ाइलों से निपटने में सक्षम है। + +### आगे क्या है? + +वर्कफ़्लो को नमूनों के एक बैच को थोक में संभालने के लिए अनुकूलित करें। + +--- + +## 3. वर्कफ़्लो को नमूनों के बैच पर चलाने के लिए अनुकूलित करें + +यह सब ठीक है कि एक वर्कफ़्लो है जो एक एकल नमूने पर प्रसंस्करण को स्वचालित कर सकती है, लेकिन यदि आपके पास 1000 नमूने हैं तो क्या होगा? +क्या आपको एक bash स्क्रिप्ट लिखने की आवश्यकता है जो आपके सभी नमूनों के माध्यम से लूप करती है? + +नहीं, भगवान का शुक्र है! बस कोड में एक मामूली बदलाव करें और Nextflow आपके लिए भी इसे संभाल लेगा। + +### 3.1. इनपुट पैरामीटर घोषणा को तीन नमूनों को सूचीबद्ध करने वाली एक सरणी में बदलें + +आइए इनपुट BAM फ़ाइल घोषणा में उस डिफ़ॉल्ट फ़ाइल पथ को हमारे तीन परीक्षण नमूनों के लिए फ़ाइल पथों को सूचीबद्ध करने वाली एक सरणी में बदलें, `Pipeline parameters` सेक्शन के तहत। + +=== "बाद में" + + ```groovy title="genomics-1.nf" linenums="7" + // प्राथमिक इनपुट (तीन नमूनों की सरणी) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "पहले" + + ```groovy title="genomics-1.nf" linenums="7" + // प्राथमिक इनपुट + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note + + टाइप किए गए पैरामीटर घोषणाओं (जैसे `reads_bam: Path`) का उपयोग करते समय, आप एक सरणी मान नहीं सौंप सकते। + सरणियों के लिए, प्रकार एनोटेशन को छोड़ दें। + +और वास्तव में यह सब हमें करने की आवश्यकता है, क्योंकि चैनल फैक्ट्री जो हम वर्कफ़्लो बॉडी में उपयोग करते हैं (`.fromPath`) इनपुट चैनल में लोड करने के लिए कई फ़ाइल पथों को स्वीकार करने में उतना ही खुश है जितना यह एक को लोड करने में था। + +!!! note + + सामान्य रूप से, आप नमूनों की सूची को अपनी वर्कफ़्लो फ़ाइल में हार्डकोड नहीं करना चाहेंगे, लेकिन हम यहां चीजों को सरल रखने के लिए ऐसा कर रहे हैं। + हम इस प्रशिक्षण श्रृंखला में बाद में इनपुट को संभालने के लिए अधिक सुरुचिपूर्ण तरीके प्रस्तुत करेंगे। + +### 3.2. वर्कफ़्लो चलाएं यह सत्यापित करने के लिए कि यह सभी तीन नमूनों पर चलती है + +आइए अब वर्कफ़्लो चलाने का प्रयास करें जब प्लंबिंग सभी तीन परीक्षण नमूनों पर चलाने के लिए सेट की गई है। + +```bash +nextflow run genomics-1.nf -resume +``` + +मज़ेदार बात: यह _काम कर सकता है_, OR यह _विफल हो सकता है_। उदाहरण के लिए, यहाँ एक रन है जो सफल हुआ: + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +यदि आपका वर्कफ़्लो रन सफल रहा, तो इसे तब तक फिर से चलाएं जब तक आपको इस तरह की त्रुटि न मिले: + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +यदि आप GATK कमांड त्रुटि आउटपुट को देखते हैं, तो इस तरह की एक पंक्ति होगी: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +खैर, यह अजीब है, यह देखते हुए कि हमने वर्कफ़्लो के पहले चरण में BAM फ़ाइलों को स्पष्ट रूप से इंडेक्स किया था। क्या प्लंबिंग में कुछ गलत हो सकता है? + +#### 3.2.1. प्रासंगिक कॉल के लिए वर्क डायरेक्टरी की जाँच करें + +आइए कंसोल आउटपुट में सूचीबद्ध विफल `GATK_HAPLOTYPECALLER` प्रोसेस कॉल के लिए वर्क डायरेक्टरी के अंदर देखें। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +इस डायरेक्टरी में सूचीबद्ध BAM फ़ाइल और BAM इंडेक्स के नामों पर विशेष ध्यान दें: `reads_son.bam` और `reads_father.bam.bai`। + +यह क्या है? Nextflow ने इस प्रोसेस कॉल की वर्क डायरेक्टरी में एक इंडेक्स फ़ाइल स्टेज की है, लेकिन यह गलत है। यह कैसे हुआ? + +#### 3.2.2. चैनल सामग्री का निरीक्षण करने के लिए [view() ऑपरेटर](https://www.nextflow.io/docs/latest/reference/operator.html#view) का उपयोग करें + +`GATK_HAPLOTYPER` प्रोसेस कॉल से पहले वर्कफ़्लो बॉडी में ये दो पंक्तियाँ जोड़ें: + +```groovy title="genomics-1.nf" linenums="84" + // अस्थायी निदान + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +फिर वर्कफ़्लो कमांड को फिर से चलाएं। + +```bash +nextflow run genomics-1.nf +``` + +एक बार फिर, यह सफल हो सकता है या विफल हो सकता है। यहाँ एक सफल रन है: + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +और यहाँ एक विफल है: + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 diff --git a/docs/hi/docs/nf4_science/genomics/02_joint_calling.md b/docs/hi/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..bc7b6218fd --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,703 @@ +# भाग 2: कोहोर्ट पर संयुक्त कॉलिंग + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस कोर्स के पहले भाग में, आपने एक वेरिएंट कॉलिंग पाइपलाइन बनाई जो पूरी तरह से रेखीय थी और प्रत्येक नमूने के डेटा को दूसरों से स्वतंत्र रूप से प्रोसेस करती थी। +हालाँकि, वास्तविक जीनोमिक्स उपयोग में, आपको आमतौर पर एक साथ कई नमूनों के वेरिएंट कॉल देखने की आवश्यकता होगी। + +इस दूसरे भाग में, हम आपको दिखाते हैं कि भाग 1 की पाइपलाइन पर आधारित, GATK के साथ संयुक्त वेरिएंट कॉलिंग को लागू करने के लिए channels और channel operators का उपयोग कैसे करें। + +### विधि अवलोकन + +GATK वेरिएंट कॉलिंग विधि जिसका हमने इस कोर्स के पहले भाग में उपयोग किया था, केवल प्रति नमूना वेरिएंट कॉल उत्पन्न करती थी। +यदि आप केवल प्रत्येक नमूने से वेरिएंट को अलगाव में देखना चाहते हैं तो यह ठीक है, लेकिन यह सीमित जानकारी देता है। +कई नमूनों में वेरिएंट कॉल कैसे भिन्न होते हैं यह देखना अक्सर अधिक दिलचस्प होता है, और ऐसा करने के लिए, GATK एक वैकल्पिक विधि प्रदान करता है जिसे संयुक्त वेरिएंट कॉलिंग कहा जाता है, जिसे हम यहाँ प्रदर्शित करते हैं। + +संयुक्त वेरिएंट कॉलिंग में प्रत्येक नमूने के लिए एक विशेष प्रकार का वेरिएंट आउटपुट उत्पन्न करना शामिल है जिसे GVCF (Genomic VCF के लिए) कहा जाता है, फिर सभी नमूनों से GVCF डेटा को जोड़ना और अंत में, 'संयुक्त जीनोटाइपिंग' सांख्यिकीय विश्लेषण चलाना। + +![संयुक्त विश्लेषण](img/joint-calling.png) + +नमूने के GVCF में विशेष यह है कि इसमें जीनोम के लक्षित क्षेत्र में सभी स्थितियों के बारे में अनुक्रम डेटा सांख्यिकी का सारांश देने वाले रिकॉर्ड होते हैं, न कि केवल उन स्थितियों के जहाँ प्रोग्राम को भिन्नता के साक्ष्य मिले। +यह संयुक्त जीनोटाइपिंग गणना के लिए महत्वपूर्ण है ([अधिक पढ़ें](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants))। + +GVCF को GATK HaplotypeCaller द्वारा उत्पन्न किया जाता है, वही टूल जिसका हमने भाग 1 में उपयोग किया था, एक अतिरिक्त पैरामीटर (`-ERC GVCF`) के साथ। +GVCFs को जोड़ना GATK GenomicsDBImport के साथ किया जाता है, जो प्रति-नमूना कॉल को एक डेटा स्टोर (डेटाबेस के समान) में जोड़ता है, फिर वास्तविक 'संयुक्त जीनोटाइपिंग' विश्लेषण GATK GenotypeGVCFs के साथ किया जाता है। + +### वर्कफ़्लो + +तो संक्षेप में, कोर्स के इस भाग में, हम एक वर्कफ़्लो विकसित करने जा रहे हैं जो निम्नलिखित करता है: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Samtools का उपयोग करके प्रत्येक BAM इनपुट फ़ाइल के लिए एक इंडेक्स फ़ाइल उत्पन्न करें +2. प्रति-नमूना जीनोमिक वेरिएंट कॉल का GVCF उत्पन्न करने के लिए प्रत्येक BAM इनपुट फ़ाइल पर GATK HaplotypeCaller चलाएँ +3. सभी GVCFs एकत्र करें और उन्हें GenomicsDB डेटा स्टोर में जोड़ें +4. कोहोर्ट-स्तरीय VCF उत्पन्न करने के लिए संयुक्त GVCF डेटा स्टोर पर संयुक्त जीनोटाइपिंग चलाएँ + +हम इसे भाग 1 के समान डेटासेट पर लागू करेंगे। + +--- + +## 0. वार्मअप: Samtools और GATK को सीधे चलाएँ + +पहले की तरह, हम उन्हें वर्कफ़्लो में लपेटने का प्रयास करने से पहले कमांड को मैन्युअल रूप से आज़माना चाहते हैं। + +!!! note + + सुनिश्चित करें कि आप सही कार्य डायरेक्टरी में हैं: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Samtools के साथ BAM इनपुट फ़ाइल को इंडेक्स करें + +यह पहला चरण भाग 1 के समान है, इसलिए यह बहुत परिचित लगना चाहिए, लेकिन इस बार हमें तीनों नमूनों के लिए ऐसा करना होगा। + +!!! note + + हमने तकनीकी रूप से अपनी पाइपलाइन के माध्यम से तीनों नमूनों के लिए पहले से ही इंडेक्स फ़ाइलें उत्पन्न की हैं, इसलिए हम उन्हें results डायरेक्टरी से निकाल सकते हैं। हालाँकि, इसे मैन्युअल रूप से फिर से करना साफ़-सुथरा है, और इसमें केवल एक मिनट लगेगा। + +#### 0.1.1. Samtools कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +#### 0.1.2. तीनों नमूनों के लिए इंडेक्सिंग कमांड चलाएँ + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +पहले की तरह, यह संबंधित BAM फ़ाइलों के समान डायरेक्टरी में इंडेक्स फ़ाइलें उत्पन्न करनी चाहिए। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +अब जब हमारे पास तीनों नमूनों के लिए इंडेक्स फ़ाइलें हैं, तो हम उनमें से प्रत्येक के लिए GVCFs उत्पन्न करने के लिए आगे बढ़ सकते हैं। + +#### 0.1.3. Samtools कंटेनर से बाहर निकलें + +```bash +exit +``` + +### 0.2. GVCF मोड में GATK HaplotypeCaller के साथ वेरिएंट कॉल करें + +यह दूसरा चरण उस चीज़ के समान है जो हमने भाग 1: Hello Genomics में किया था, लेकिन हम अब GATK को 'GVCF मोड' में चलाने जा रहे हैं। + +#### 0.2.1. GATK कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +#### 0.2.2. GVCF विकल्प के साथ वेरिएंट कॉलिंग कमांड चलाएँ + +एक जीनोमिक VCF (GVCF) उत्पन्न करने के लिए, हम बेस कमांड में `-ERC GVCF` विकल्प जोड़ते हैं, जो HaplotypeCaller के GVCF मोड को चालू करता है। + +हम आउटपुट फ़ाइल के लिए फ़ाइल एक्सटेंशन को `.vcf` से `.g.vcf` में भी बदलते हैं। +यह तकनीकी रूप से आवश्यकता नहीं है, लेकिन यह एक दृढ़ता से अनुशंसित परंपरा है। + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +यह कंटेनर में वर्तमान कार्य डायरेक्टरी में GVCF आउटपुट फ़ाइल `reads_mother.g.vcf` बनाता है। + +यदि आप सामग्री देखने के लिए इसे `cat` करते हैं, तो आप देखेंगे कि यह भाग 1 में हमारे द्वारा उत्पन्न समतुल्य VCF की तुलना में बहुत लंबा है। आप फ़ाइल की शुरुआत तक भी स्क्रॉल नहीं कर सकते, और अधिकांश पंक्तियाँ भाग 1 में VCF में हमने जो देखा था उससे काफी अलग दिखती हैं। + +```console title="Output" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +ये गैर-वेरिएंट क्षेत्रों का प्रतिनिधित्व करते हैं जहाँ वेरिएंट कॉलर को भिन्नता का कोई साक्ष्य नहीं मिला, इसलिए इसने भिन्नता की अनुपस्थिति में अपने विश्वास के स्तर का वर्णन करने वाली कुछ सांख्यिकी कैप्चर कीं। यह दो बहुत अलग केस आंकड़ों के बीच अंतर करना संभव बनाता है: (1) अच्छी गुणवत्ता का डेटा है जो दर्शाता है कि नमूना homozygous-reference है, और (2) किसी भी तरह से निर्धारण करने के लिए पर्याप्त अच्छा डेटा उपलब्ध नहीं है। + +GVCF में, आमतौर पर इस तरह की बहुत सारी गैर-वेरिएंट लाइनें होती हैं, जिनके बीच कम संख्या में वेरिएंट रिकॉर्ड बिखरे होते हैं। वास्तविक वेरिएंट कॉल खोजने के लिए फ़ाइल की केवल पहली 176 लाइनों को लोड करने के लिए GVCF पर `head -176` चलाने का प्रयास करें। + +```console title="Output" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +दूसरी लाइन फ़ाइल में पहला वेरिएंट रिकॉर्ड दिखाती है, जो भाग 1 में हमने देखी VCF फ़ाइल में पहले वेरिएंट से मेल खाती है। + +मूल VCF की तरह, आउटपुट GVCF फ़ाइल भी एक इंडेक्स फ़ाइल के साथ आती है, जिसे `reads_mother.g.vcf.idx` कहा जाता है। + +#### 0.2.3. अन्य दो नमूनों पर प्रक्रिया दोहराएँ + +संयुक्त जीनोटाइपिंग चरण का परीक्षण करने के लिए, हमें तीनों नमूनों के लिए GVCFs की आवश्यकता है, तो आइए अभी मैन्युअल रूप से उन्हें उत्पन्न करें। + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +एक बार यह पूरा हो जाने पर, आपके वर्तमान डायरेक्टरी में `.g.vcf` में समाप्त होने वाली तीन फ़ाइलें (प्रति नमूना एक) और `.g.vcf.idx` में समाप्त होने वाली उनकी संबंधित इंडेक्स फ़ाइलें होनी चाहिए। + +### 0.3. संयुक्त जीनोटाइपिंग चलाएँ + +अब जब हमारे पास सभी GVCFs हैं, तो हम अंततः नमूनों के कोहोर्ट के लिए वेरिएंट कॉल उत्पन्न करने के लिए संयुक्त जीनोटाइपिंग दृष्टिकोण को आज़मा सकते हैं। +एक अनुस्मारक के रूप में, यह एक दो-चरण विधि है जिसमें सभी GVCFs से डेटा को डेटा स्टोर में जोड़ना, फिर संयुक्त-कॉल किए गए वेरिएंट के अंतिम VCF को उत्पन्न करने के लिए संयुक्त जीनोटाइपिंग विश्लेषण उचित रूप से चलाना शामिल है। + +#### 0.3.1. सभी प्रति-नमूना GVCFs को जोड़ें + +यह पहला चरण एक अन्य GATK टूल का उपयोग करता है, जिसे GenomicsDBImport कहा जाता है, सभी GVCFs से डेटा को GenomicsDB डेटा स्टोर में जोड़ने के लिए। + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +इस चरण का आउटपुट प्रभावी रूप से एक डायरेक्टरी है जिसमें कई अलग-अलग फ़ाइलों के रूप में संयुक्त वेरिएंट डेटा रखने वाली आगे नेस्टेड डायरेक्टरियों का एक सेट होता है। +आप इसके चारों ओर देख सकते हैं लेकिन आप जल्दी देखेंगे कि इस डेटा स्टोर प्रारूप को मनुष्यों द्वारा सीधे पढ़ने के लिए नहीं बनाया गया है। + +!!! note + + GATK में ऐसे टूल शामिल हैं जो आवश्यकतानुसार डेटा स्टोर से वेरिएंट कॉल डेटा का निरीक्षण और निष्कर्षण करना संभव बनाते हैं। + +#### 0.3.2. संयुक्त जीनोटाइपिंग विश्लेषण उचित रूप से चलाएँ + +यह दूसरा चरण एक और GATK टूल का उपयोग करता है, जिसे GenotypeGVCFs कहा जाता है, कोहोर्ट में सभी नमूनों में उपलब्ध डेटा के आलोक में वेरिएंट सांख्यिकी और व्यक्तिगत जीनोटाइप की पुनर्गणना करने के लिए। + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +यह कंटेनर में वर्तमान कार्य डायरेक्टरी में VCF आउटपुट फ़ाइल `family_trio.vcf` बनाता है। +यह एक और उचित रूप से छोटी फ़ाइल है इसलिए आप इसकी सामग्री देखने के लिए इस फ़ाइल को `cat` कर सकते हैं, और पहली कुछ वेरिएंट लाइनों को खोजने के लिए ऊपर स्क्रॉल कर सकते हैं। + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +यह भाग 1 में हमारे द्वारा उत्पन्न मूल VCF की तरह अधिक दिखता है, सिवाय इसके कि इस बार हमारे पास तीनों नमूनों के लिए जीनोटाइप-स्तरीय जानकारी है। +फ़ाइल में अंतिम तीन कॉलम नमूनों के लिए जीनोटाइप ब्लॉक हैं, जो वर्णानुक्रम में सूचीबद्ध हैं। + +यदि हम अपने परीक्षण परिवार ट्रायो के लिए पहले वेरिएंट के लिए कॉल किए गए जीनोटाइप देखते हैं, तो हम देखते हैं कि पिता heterozygous-variant (`0/1`) हैं, और माँ और बेटा दोनों homozygous-variant (`1/1`) हैं। + +यह अंततः वह जानकारी है जिसे हम डेटासेट से निकालने की कोशिश कर रहे हैं! तो आइए इन सभी को Nextflow वर्कफ़्लो में लपेटें ताकि हम इसे बड़े पैमाने पर कर सकें। + +#### 0.3.3. GATK कंटेनर से बाहर निकलें + +```bash +exit +``` + +### निष्कर्ष + +आप जानते हैं कि टर्मिनल में संयुक्त वेरिएंट कॉलिंग से जुड़े व्यक्तिगत कमांड को कैसे चलाना है ताकि यह सत्यापित किया जा सके कि वे आपकी इच्छित जानकारी उत्पन्न करेंगे। + +### आगे क्या है? + +इन कमांड को वास्तविक पाइपलाइन में लपेटें। + +--- + +## 1. GVCF उत्पन्न करने के लिए प्रति-नमूना वेरिएंट कॉलिंग चरण को संशोधित करें + +अच्छी खबर यह है कि हमें सब कुछ फिर से शुरू करने की आवश्यकता नहीं है, क्योंकि हमने पहले से ही भाग 1 में एक वर्कफ़्लो लिखा है जो इस काम का कुछ हिस्सा करता है। +हालाँकि, वह पाइपलाइन VCF फ़ाइलें उत्पन्न करती है, जबकि अब हम संयुक्त जीनोटाइपिंग करने के लिए GVCF फ़ाइलें चाहते हैं। +इसलिए हमें GVCF वेरिएंट कॉलिंग मोड को चालू करके और आउटपुट फ़ाइल एक्सटेंशन को अपडेट करके शुरू करने की आवश्यकता है। + +!!! note + + सुविधा के लिए, हम GATK वर्कफ़्लो की एक नई प्रतिलिपि के साथ काम करने जा रहे हैं जैसा कि यह भाग 1 के अंत में खड़ा है, लेकिन एक अलग नाम के तहत: `genomics-2.nf`। + +### 1.1. HaplotypeCaller को GVCF उत्सर्जित करने के लिए कहें और आउटपुट एक्सटेंशन अपडेट करें + +आइए कोड एडिटर में `genomics-2.nf` फ़ाइल खोलें। +यह बहुत परिचित लगनी चाहिए, लेकिन यदि आप खुद को संतुष्ट करना चाहते हैं कि यह अपेक्षित रूप से चलती है तो इसे चलाने के लिए स्वतंत्र महसूस करें। + +हम दो परिवर्तन करके शुरू करने जा रहे हैं: + +- GATK HaplotypeCaller कमांड में `-ERC GVCF` पैरामीटर जोड़ें; +- GATK परंपरा के अनुसार, संबंधित `.g.vcf` एक्सटेंशन का उपयोग करने के लिए आउटपुट फ़ाइल पथ अपडेट करें। + +जब आप `-ERC GVCF` जोड़ें तो सुनिश्चित करें कि आप पिछली लाइन के अंत में बैकस्लैश (`\`) जोड़ें। + +=== "बाद में" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "पहले" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +और VCFs के बजाय GVCFs उत्पन्न करने के लिए HaplotypeCaller को स्विच करने के लिए बस इतना ही है, है ना? + +### 1.2. सत्यापित करने के लिए पाइपलाइन चलाएँ कि आप GVCFs उत्पन्न कर सकते हैं + +Nextflow निष्पादन कमांड पहले की तरह ही है, वर्कफ़्लो फ़ाइल नाम को छोड़कर। +सुनिश्चित करें कि आप इसे उचित रूप से अपडेट करें। + +```bash +nextflow run genomics-2.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +और आउटपुट है... सब लाल! ओह नहीं। + +जो कमांड निष्पादित की गई थी वह सही है, इसलिए हम सही थे कि GATK टूल के व्यवहार को बदलने के लिए यह पर्याप्त था। +लेकिन लापता आउटपुट फ़ाइल के बारे में उस लाइन को देखें। कुछ भी नोटिस करें? + +यह सही है, हम Nextflow को बताना भूल गए कि अपेक्षित आउटपुट फ़ाइल नाम बदल गया है। उफ़्फ़। + +### 1.3. process outputs ब्लॉक में भी आउटपुट फ़ाइल एक्सटेंशन अपडेट करें + +क्योंकि टूल कमांड में ही फ़ाइल एक्सटेंशन बदलना पर्याप्त नहीं है, आपको Nextflow को यह भी बताना होगा कि अपेक्षित आउटपुट फ़ाइल नाम बदल गया है। + +=== "बाद में" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "पहले" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. नए GVCF आउटपुट के लिए प्रकाशन लक्ष्य अपडेट करें + +चूँकि हम अब VCFs के बजाय GVCFs उत्पन्न कर रहे हैं, हमें अधिक वर्णनात्मक नामों का उपयोग करने के लिए वर्कफ़्लो के `publish:` अनुभाग को अपडेट करना चाहिए। +हम स्पष्टता के लिए GVCF फ़ाइलों को उनकी अपनी उपनिर्देशिका में भी व्यवस्थित करेंगे। + +=== "बाद में" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "पहले" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. नई डायरेक्टरी संरचना के लिए आउटपुट ब्लॉक अपडेट करें + +हमें GVCF फ़ाइलों को `gvcf` उपनिर्देशिका में रखने के लिए `output` ब्लॉक को भी अपडेट करने की आवश्यकता है। + +=== "बाद में" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "पहले" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. पाइपलाइन फिर से चलाएँ + +आइए इस बार इसे `-resume` के साथ चलाएँ। + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +इस बार यह काम करता है। + +Nextflow आउटपुट स्वयं (सामान्य VCF मोड में सफल रन की तुलना में) कोई अलग नहीं दिखता है, लेकिन अब हम `.g.vcf` फ़ाइलें और उनकी संबंधित इंडेक्स फ़ाइलें, तीनों नमूनों के लिए, उपनिर्देशिकाओं में व्यवस्थित पा सकते हैं। + +??? abstract "डायरेक्टरी सामग्री (symlinks छोटी की गई)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +यदि आप GVCF फ़ाइलों में से एक को खोलते हैं और इसके माध्यम से स्क्रॉल करते हैं, तो आप सत्यापित कर सकते हैं कि GATK HaplotypeCaller ने अनुरोध के अनुसार GVCF फ़ाइलें उत्पन्न कीं। + +### निष्कर्ष + +ठीक है, यह Nextflow सीखने के मामले में न्यूनतम था... +लेकिन process output ब्लॉक के महत्व को दोहराने का यह एक अच्छा अवसर था! + +### आगे क्या है? + +सभी नमूनों में GVCF डेटा एकत्र करना और जोड़ना सीखें। + +--- + +## 2. सभी नमूनों में GVCF डेटा एकत्र करें और जोड़ें + +अब हमें सभी प्रति-नमूना GVCFs से डेटा को एक ऐसे रूप में जोड़ने की आवश्यकता है जो हम जो संयुक्त जीनोटाइपिंग विश्लेषण करना चाहते हैं उसका समर्थन करता है। + +### 2.1. उस process को परिभाषित करें जो GVCFs को जोड़ेगा + +वार्मअप अनुभाग में हमने पहले जो किया था उसकी याद दिलाने के लिए, GVCFs को जोड़ना GATK टूल GenomicsDBImport के लिए एक काम है, जो तथाकथित GenomicsDB प्रारूप में एक डेटा स्टोर उत्पन्न करेगा। + +आइए वार्मअप अनुभाग में पहले उपयोग की गई कमांड के आधार पर यह परिभाषित करने के लिए एक नई प्रक्रिया लिखें कि यह कैसे काम करने वाला है। + +```groovy title="genomics-2.nf" linenums="66" +/* + * GVCFs को GenomicsDB datastore में जोड़ें + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +आपको क्या लगता है, उचित लग रहा है? + +आइए इसे वायर करें और देखें कि क्या होता है। + +### 2.2. डिफ़ॉल्ट मान के साथ `cohort_name` पैरामीटर जोड़ें + +हमें कोहोर्ट के लिए एक मनमाना नाम प्रदान करने की आवश्यकता है। +प्रशिक्षण श्रृंखला में बाद में आप इस तरह की चीज़ के लिए नमूना मेटाडेटा का उपयोग करना सीखेंगे, लेकिन अभी के लिए हम सुविधा के लिए `params` का उपयोग करके एक CLI पैरामीटर घोषित करते हैं और इसे एक डिफ़ॉल्ट मान देते हैं। + +```groovy title="genomics-2.nf" linenums="16" + // अंतिम आउटपुट फ़ाइल के लिए आधार नाम + cohort_name: String = "family_trio" +``` + +### 2.3. नमूनों में GATK_HAPLOTYPECALLER के आउटपुट एकत्र करें + +यदि हम `GATK_HAPLOTYPECALLER` process के आउटपुट channel को जैसा है वैसा ही प्लग करते हैं, तो Nextflow प्रत्येक नमूना GVCF पर अलग से process को कॉल करेगा। +हालाँकि, हम सभी तीन GVCFs (और उनकी इंडेक्स फ़ाइलों) को इस तरह से बंडल करना चाहते हैं कि Nextflow उन सभी को एक साथ एक process कॉल को सौंपे। + +अच्छी खबर: हम `collect()` channel operator का उपयोग करके ऐसा कर सकते हैं। आइए GATK_HAPLOTYPECALLER की कॉल के ठीक बाद, `workflow` बॉडी में निम्नलिखित लाइनें जोड़ें: + +```groovy title="genomics-2.nf" linenums="118" +// नमूनों में वेरिएंट कॉलिंग आउटपुट एकत्र करें +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +क्या यह थोड़ा जटिल लगता है? आइए इसे तोड़ें और इसे सादी भाषा में अनुवादित करें। + +1. हम `GATK_HAPLOTYPECALLER` process से आउटपुट channel ले रहे हैं, जिसे `.out` गुण का उपयोग करके संदर्भित किया गया है। +2. channel से निकलने वाला प्रत्येक 'तत्व' फ़ाइलों की एक जोड़ी है: GVCF और उसकी इंडेक्स फ़ाइल, उस क्रम में क्योंकि वह क्रम है जिसमें वे process output ब्लॉक में सूचीबद्ध हैं। सुविधाजनक रूप से, क्योंकि पिछले सत्र में हमने इस process के आउटपुट का नाम दिया था (`emit:` का उपयोग करके), हम एक हाथ में `.out` गुण के बाद `.vcf` जोड़कर GVCFs को चुन सकते हैं और दूसरी ओर `.idx` जोड़कर इंडेक्स फ़ाइलों को। यदि हमने उन आउटपुट का नाम नहीं दिया होता, तो हमें उन्हें क्रमशः `.out[0]` और `.out[1]` द्वारा संदर्भित करना होता। +3. हम सभी GVCF फ़ाइलों को `all_gvcfs_ch` नामक एक नए channel में एक एकल तत्व में बंडल करने के लिए `collect()` channel operator जोड़ते हैं, और `all_idxs_ch` नामक नया channel बनाने के लिए इंडेक्स फ़ाइलों के साथ भी ऐसा ही करते हैं। + +!!! tip + + यदि आपको यह कल्पना करना कठिन हो रहा है कि यहाँ वास्तव में क्या हो रहा है, तो याद रखें कि आप channel operators को लागू करने से पहले और बाद में channels की सामग्री का निरीक्षण करने के लिए `view()` operator का उपयोग कर सकते हैं। + +परिणामी `all_gvcfs_ch` और `all_idxs_ch` channels वे हैं जिन्हें हम अभी लिखे गए `GATK_GENOMICSDB` process में प्लग करने जा रहे हैं। + +!!! note + + यदि आप सोच रहे थे, तो हम GVCFs और उनकी इंडेक्स फ़ाइलों को अलग से एकत्र करते हैं क्योंकि GATK GenomicsDBImport कमांड केवल GVCF फ़ाइल पथ देखना चाहता है। सौभाग्य से, चूँकि Nextflow निष्पादन के लिए सभी फ़ाइलों को एक साथ मंचित करेगा, इसलिए हमें भाग 1 में BAMs और उनके इंडेक्स के लिए जैसी फ़ाइलों के क्रम के बारे में चिंता करने की आवश्यकता नहीं है। + +### 2.4. GATK_GENOMICSDB चलाने के लिए वर्कफ़्लो ब्लॉक में एक कॉल जोड़ें + +हमारे पास एक process है, और हमारे पास इनपुट channels हैं। हमें बस process कॉल जोड़ने की आवश्यकता है। + +```groovy title="genomics-2.nf" linenums="122" + // GVCFs को GenomicsDB डेटा स्टोर में जोड़ें + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +ठीक है, सब कुछ वायर किया गया है। + +### 2.5. वर्कफ़्लो चलाएँ + +आइए देखें कि क्या यह काम करता है। + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +यह काफी तेज़ी से चलता है, क्योंकि हम `-resume` के साथ चल रहे हैं, लेकिन यह विफल हो जाता है! + +आह। सकारात्मक पक्ष पर, हम देखते हैं कि Nextflow ने `GATK_GENOMICSDB` process को उठाया है, और विशेष रूप से इसे केवल एक बार कॉल किया है। +यह सुझाव देता है कि `collect()` दृष्टिकोण काम किया, एक सीमा तक। +लेकिन, और यह एक बड़ा है, process कॉल विफल रहा। + +जब हम ऊपर कंसोल आउटपुट में खोदते हैं, तो हम देख सकते हैं कि निष्पादित कमांड सही नहीं है। + +क्या आप त्रुटि देख सकते हैं? +इस बिट को देखें: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +हमने `gatk GenomicsDBImport` को एकल `-V` तर्क के लिए कई GVCF फ़ाइलें दीं, लेकिन टूल प्रत्येक GVCF फ़ाइल के लिए एक अलग `-V` तर्क की अपेक्षा करता है। + +एक अनुस्मारक के रूप में, यह वह कमांड थी जो हमने कंटेनर में चलाई थी: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +तो इसका मतलब है कि हमें किसी तरह GVCF फ़ाइलों के अपने बंडल को उचित रूप से स्वरूपित कमांड स्ट्रिंग में बदलने की आवश्यकता है। + +### 2.6. प्रत्येक इनपुट GVCF के लिए एक अलग `-V` तर्क के साथ एक कमांड लाइन बनाएँ + +यह वह जगह है जहाँ Groovy पर आधारित Nextflow होना काम आता है, क्योंकि यह हमें आवश्यक कमांड स्ट्रिंग बनाने के लिए कुछ काफी सीधे स्ट्रिंग हेरफेर का उपयोग करने की अनुमति देने वाला है। + +विशेष रूप से, इस सिंटैक्स का उपयोग करते हुए: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +एक बार फिर, आइए इसे इसके घटकों में तोड़ें। + +1. सबसे पहले, हम `all_gvcfs` input channel की सामग्री लेते हैं और उस पर `.collect()` लागू करते हैं (पहले की तरह)। +2. यह हमें बंडल में प्रत्येक व्यक्तिगत GVCF फ़ाइल पथ को **closure** में पास करने की अनुमति देता है, `{ gvcf -> "-V ${gvcf}" }`, जहाँ `gvcf` उस GVCF फ़ाइल पथ को संदर्भित करता है। + closure एक मिनी-फ़ंक्शन है जिसका उपयोग हम फ़ाइल पथ में `-V ` जोड़ने के लिए करते हैं, `"-V ${gvcf}"` के रूप में। +3. फिर हम सभी तीन स्ट्रिंग्स को विभाजक के रूप में एकल स्थान के साथ संयोजित करने के लिए `.join(' ')` का उपयोग करते हैं। + +एक ठोस उदाहरण के साथ, यह इस तरह दिखता है: + +1. हमारे पास तीन फ़ाइलें हैं: + + `[A.ext, B.ext, C.ext]` + +2. closure प्रत्येक को स्ट्रिंग्स बनाने के लिए संशोधित करता है: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. `.join(' ')` ऑपरेशन अंतिम स्ट्रिंग उत्पन्न करता है: + + `"-V A.ext -V B.ext -V C.ext"` + +एक बार जब हमारे पास वह स्ट्रिंग हो, तो हम इसे एक स्थानीय वेरिएबल, `gvcfs_line` को असाइन कर सकते हैं, जिसे `def` कीवर्ड के साथ परिभाषित किया गया है: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +ठीक है, तो हमारे पास हमारी स्ट्रिंग हेरफेर चीज़ है। हम इसे कहाँ रखते हैं? + +हम चाहते हैं कि यह process परिभाषा में कहीं जाए, क्योंकि हम चाहते हैं कि यह _बाद में_ करें जब हमने GVCF फ़ाइल पथों को process में channeled किया हो। +ऐसा इसलिए है क्योंकि Nextflow को उन्हें फ़ाइल पथों के रूप में देखना चाहिए ताकि निष्पादन के लिए फ़ाइलों को स्वयं सही ढंग से मंचित किया जा सके। + +लेकिन process में _कहाँ_ diff --git a/docs/hi/docs/nf4_science/genomics/03_modules.md b/docs/hi/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..48f6f2520b --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# भाग 3: कोड को मॉड्यूल में ले जाना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस कोर्स के पहले भाग में, आपने एक variant calling पाइपलाइन बनाई जो पूरी तरह से linear थी और प्रत्येक sample के डेटा को दूसरों से स्वतंत्र रूप से प्रोसेस करती थी। + +दूसरे भाग में, हमने आपको दिखाया कि GATK के साथ joint variant calling को implement करने के लिए channels और channel ऑपरेटर का उपयोग कैसे करें, जो भाग 1 की पाइपलाइन पर आधारित था। + +इस भाग में, हम आपको दिखाएंगे कि उस workflow के कोड को मॉड्यूल में कैसे convert करें। इस प्रशिक्षण के इस भाग को फॉलो करने के लिए, आपको भाग 1 और भाग 2 के साथ-साथ [Hello Modules](../../../hello_nextflow/hello_modules.md) को पूरा करना चाहिए, जो मॉड्यूल की मूल बातें कवर करता है। + +--- + +## 0. Warmup + +जब हमने अपने workflow को develop करना शुरू किया, तो हमने सब कुछ एक ही कोड फ़ाइल में रखा। +अब हमारे कोड को **modularize** करने का समय आ गया है, _यानी_ process definitions को मॉड्यूल में extract करना। + +हम भाग 2 के समान workflow से शुरू करने जा रहे हैं, जिसे हमने आपके लिए `genomics-3.nf` फ़ाइल में प्रदान किया है। + +!!! note "नोट" + + सुनिश्चित करें कि आप सही working डायरेक्टरी में हैं: + `cd /workspaces/training/nf4-science/genomics` + +शुरुआती बिंदु को verify करने के लिए workflow को चलाएं: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="आउटपुट" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +अब आपकी project डायरेक्टरी के अंदर एक `work` डायरेक्टरी और एक `results_genomics` डायरेक्टरी होगी। + +### सारांश + +आप अपने workflow को modularize करना शुरू करने के लिए तैयार हैं। + +### आगे क्या है? + +Genomics workflow की processes को मॉड्यूल में ले जाएं। + +--- + +## 1. Processes को मॉड्यूल में ले जाएं + +जैसा कि आपने [Hello Modules](../../../hello_nextflow/hello_modules.md) में सीखा, आप केवल process definition को अपनी खुद की फ़ाइल में copy करके, किसी भी डायरेक्टरी में, एक मॉड्यूल बना सकते हैं, और आप उस फ़ाइल को कुछ भी नाम दे सकते हैं। + +उन कारणों से जो बाद में स्पष्ट हो जाएंगे (विशेष रूप से जब हम testing पर आएंगे), इस प्रशिक्षण में हम फ़ाइल को `main.nf` नाम देने की convention का पालन करेंगे, और इसे tool kit और कमांड के नाम पर आधारित डायरेक्टरी structure में रखेंगे। + +### 1.1. `SAMTOOLS_INDEX` process के लिए एक मॉड्यूल बनाएं + +`SAMTOOLS_INDEX` process के मामले में, 'samtools' toolkit है और 'index' कमांड है। इसलिए, हम एक डायरेक्टरी structure `modules/samtools/index` बनाएंगे और उस डायरेक्टरी के अंदर `main.nf` फ़ाइल में `SAMTOOLS_INDEX` process definition रखेंगे। + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +`main.nf` फ़ाइल खोलें और इसमें `SAMTOOLS_INDEX` process definition को copy करें। + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * BAM इंडेक्स फ़ाइल बनाएं + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +फिर, `genomics-3.nf` से `SAMTOOLS_INDEX` process definition को हटाएं, और अगली process definition से पहले मॉड्यूल के लिए एक import declaration जोड़ें, इस तरह: + +=== "बाद में" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // मॉड्यूल include करें + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * GATK HaplotypeCaller के साथ variants को call करें + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "पहले" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * GATK HaplotypeCaller के साथ variants को call करें + */ + process GATK_HAPLOTYPECALLER { + ``` + +अब आप workflow को फिर से चला सकते हैं, और यह पहले की तरह ही काम करना चाहिए। यदि आप `-resume` flag प्रदान करते हैं, तो कोई नया कार्य भी चलाने की आवश्यकता नहीं होनी चाहिए: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. `GATK_HAPLOTYPECALLER` और `GATK_JOINTGENOTYPING` processes के लिए मॉड्यूल बनाएं + +शेष processes के लिए वही steps दोहराएं। +प्रत्येक process के लिए: + +1. डायरेक्टरी structure बनाएं (`modules/gatk/haplotypecaller/` और `modules/gatk/jointgenotyping/`) +2. Process definition वाली एक `main.nf` फ़ाइल बनाएं +3. `genomics-3.nf` से process definition हटाएं +4. मॉड्यूल के लिए एक import declaration जोड़ें + +एक बार जब आप काम कर लें, तो यह चलाकर जांचें कि आपकी modules डायरेक्टरी structure सही है: + +```bash +tree modules/ +``` + +??? abstract "डायरेक्टरी की सामग्री" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +पैरामीटर section के बाद, main workflow फ़ाइल में आपके पास इस तरह कुछ होना चाहिए: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### सारांश + +आपने genomics workflow को उदाहरण के रूप में लेकर एक workflow को modularize करने का अभ्यास किया है। + +### आगे क्या है? + +Modularized workflow को test करें। + +--- + +## 2. Modularized workflow को test करें + +सब कुछ अभी भी काम करता है यह verify करने के लिए modularized workflow को चलाएं। + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="आउटपुट" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +सब कुछ अभी भी काम करता है, जिसमें पाइपलाइन की resumability भी शामिल है। +परिणाम `results_genomics` डायरेक्टरी में publish होते रहते हैं। + +```console title="डायरेक्टरी की सामग्री" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### सारांश + +आपने एक workflow को modularize किया है और verify किया है कि यह अभी भी पहले की तरह ही काम करता है। + +### आगे क्या है? + +आपने जो सीखा है उसकी समीक्षा करें और testing की ओर देखें। + +--- + +## 3. सारांश + +आपने workflow को modularize किया है, और पाइपलाइन के काम करने के तरीके में कुछ भी नहीं बदला है। +यह जानबूझकर किया गया है: आपने कोड को restructure किया है बिना इसके function को प्रभावित किए। + +मॉड्यूल में केवल process logic होता है, जो उन्हें साफ और reusable बनाता है। +main script नियंत्रित करती है कि क्या publish होता है और कहां, जबकि मॉड्यूल अपने computational कार्य पर केंद्रित रहते हैं। + +आपने उन चीजों के लिए एक नींव रखी है जो आपके कोड को maintain करना आसान बना देंगी। +उदाहरण के लिए, अब आप nf-test framework का उपयोग करके अपनी पाइपलाइन में tests जोड़ सकते हैं। +यही वह है जो हम इस कोर्स के अगले भाग में देखेंगे। diff --git a/docs/hi/docs/nf4_science/genomics/04_testing.md b/docs/hi/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..2239c1a032 --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1055 @@ +# भाग 4: टेस्ट जोड़ना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस कोर्स के पहले भाग में, आपने एक variant calling pipeline बनाई जो पूरी तरह से linear थी और प्रत्येक नमूने के डेटा को दूसरों से स्वतंत्र रूप से प्रोसेस करती थी। + +दूसरे भाग में, हमने आपको दिखाया कि GATK के साथ joint variant calling को लागू करने के लिए channels और channel operators का उपयोग कैसे करें। + +तीसरे भाग में, हमने pipeline को modularize किया। + +प्रशिक्षण के इस भाग में, हम आपको दिखाने जा रहे हैं कि [**nf-test**](https://www.nf-test.com/) का उपयोग कैसे करें, एक testing framework जो Nextflow के साथ अच्छी तरह integrate होता है और आपकी pipeline में module-level और workflow-level दोनों प्रकार के टेस्ट जोड़ना सरल बनाता है। प्रशिक्षण के इस भाग का पालन करने के लिए, आपको भाग 1, भाग 2, और भाग 3 के साथ-साथ [nf-test side quest](../../side_quests/nf-test.md) पूरा करना चाहिए, जो nf-test की मूल बातें और testing क्यों महत्वपूर्ण है, इस पर आधारित है। + +--- + +## 0. Warmup + +!!! note + + सुनिश्चित करें कि आप सही working डायरेक्टरी में हैं: + `cd /workspaces/training/nf4-science/genomics` + +यदि आपने इस प्रशिक्षण कोर्स के पिछले भागों को पूरा किया है, तो आपके पास उचित modules डायरेक्टरी संरचना के साथ genomics pipeline का एक working संस्करण होना चाहिए। + +??? abstract "डायरेक्टरी की सामग्री" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +यह modules डायरेक्टरी `solutions` डायरेक्टरी में पाई जा सकती है यदि आपको इसकी आवश्यकता हो। + +हम भाग 3 में जैसी ही workflow के साथ शुरू करने जा रहे हैं, जिसे हमने आपके लिए `genomics-4.nf` फ़ाइल में प्रदान किया है। [nf-test side quest](../../side_quests/nf-test.md) की तरह ही, हम इस pipeline में तीन processes के लिए कुछ अलग-अलग प्रकार के टेस्ट जोड़ने जा रहे हैं, साथ ही एक workflow-level टेस्ट भी। + +### 0.1. जांचें कि workflow चलती है + +टेस्ट जोड़ना शुरू करने से पहले, सुनिश्चित करें कि workflow अपेक्षा के अनुसार चलती है। + +```bash +nextflow run genomics-4.nf -resume +``` + +यदि आप इस प्रशिक्षण कोर्स को शुरू से कर रहे हैं तो यह अब तक बहुत परिचित होना चाहिए। + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +पहले की तरह, अब आपकी project डायरेक्टरी के अंदर एक `work` डायरेक्टरी और एक `results_genomics` डायरेक्टरी होगी। हम वास्तव में इन परिणामों का उपयोग बाद में अपनी testing में करेंगे। लेकिन अब से हम pipeline को टेस्ट करने के लिए `nf-test` package का उपयोग करने जा रहे हैं। + +### 0.2. `nf-test` को initialize करें + +[nf-test side quest](../../side_quests/nf-test.md) की तरह, हमें `nf-test` package को initialize करना होगा। + +```bash +nf-test init +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "nf-test.config की सामग्री" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +यह एक configuration फ़ाइल stub युक्त `tests` डायरेक्टरी भी बनाता है। + +### निष्कर्ष + +अब हम अपनी genomics pipeline के लिए टेस्ट लिखने के लिए तैयार हैं। + +### आगे क्या है? + +मूल टेस्ट लिखें जो मूल्यांकन करते हैं कि process calls सफल रहे और सही आउटपुट उत्पन्न हुए। + +--- + +## 1. सफलता और मिलान करते आउटपुट के लिए एक process को टेस्ट करें + +हम `SAMTOOLS_INDEX` process को टेस्ट करके शुरू करेंगे, जो कुशल random access को सक्षम करने के लिए BAM फ़ाइलों के लिए इंडेक्स फ़ाइलें बनाती है। यह एक अच्छा पहला टेस्ट केस है क्योंकि: + +1. इसमें एक एकल, सुपरिभाषित इनपुट (एक BAM फ़ाइल) है +2. यह एक अनुमानित आउटपुट (एक BAI इंडेक्स फ़ाइल) उत्पन्न करता है +3. समान इनपुट के लिए आउटपुट समान होना चाहिए + +### 1.1. एक टेस्ट फ़ाइल stub उत्पन्न करें + +सबसे पहले, एक टेस्ट फ़ाइल stub उत्पन्न करें: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +यह `main.nf` के समान डायरेक्टरी में एक फ़ाइल बनाता है। +आप file explorer में डायरेक्टरी पर जा सकते हैं और फ़ाइल खोल सकते हैं, जिसमें निम्नलिखित कोड होना चाहिए: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +शुरुआती assertions [nf-test side quest](../../side_quests/nf-test.md) से परिचित होने चाहिए: + +- `assert process.success` कहता है कि हम उम्मीद करते हैं कि process सफलतापूर्वक चले और बिना किसी विफलता के पूरा हो। +- `snapshot(process.out).match()` कहता है कि हम उम्मीद करते हैं कि रन का परिणाम पिछले रन में प्राप्त परिणाम (यदि लागू हो) के समान हो। + हम इस पर बाद में अधिक विस्तार से चर्चा करते हैं। + +इसे एक शुरुआती बिंदु के रूप में उपयोग करते हुए, हमें samtools index process के लिए सही टेस्ट इनपुट जोड़ने होंगे, और यदि लागू हो तो कोई भी पैरामीटर। + +### 1.2. टेस्ट फ़ाइल को स्थानांतरित करें और script path को अपडेट करें + +टेस्ट को भरने के लिए काम करने से पहले, हमें फ़ाइल को उसके निश्चित स्थान पर ले जाना होगा। हमने प्रत्येक मॉड्यूल के लिए एक डायरेक्टरी जोड़ने का एक कारण यह है कि अब हम प्रत्येक मॉड्यूल की `main.nf` फ़ाइल के साथ co-located `tests` डायरेक्टरी में टेस्ट ship कर सकते हैं। वह डायरेक्टरी बनाएं और टेस्ट फ़ाइल को वहाँ ले जाएं। + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +अब हम टेस्ट फ़ाइल के `script` सेक्शन को एक relative path में सरल बना सकते हैं: + +=== "बाद में" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "पहले" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +यह टेस्ट को बताता है कि मॉड्यूल की `main.nf` फ़ाइल कहाँ खोजनी है, पूरा path निर्दिष्ट किए बिना। + +### 1.3. SAMTOOLS_INDEX के लिए टेस्ट इनपुट प्रदान करें + +stub फ़ाइल में एक placeholder शामिल है जिसे हमें `samtools index` के इनपुट के लिए उपयुक्त वास्तविक टेस्ट इनपुट से बदलना होगा। उपयुक्त इनपुट एक BAM फ़ाइल है, जो हमारे पास `data/bam` डायरेक्टरी में उपलब्ध है। + +=== "बाद में" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "पहले" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. कार्यक्षमता के आधार पर टेस्ट का नाम दें + +जैसा कि हमने पहले सीखा, टेस्ट का नाम बदलना अच्छा अभ्यास है ताकि यह टेस्ट के संदर्भ में समझ में आए। + +=== "बाद में" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + यह एक arbitrary string लेता है, इसलिए हम जो चाहें डाल सकते हैं। + यहां हम फ़ाइल नाम और उसके प्रारूप को संदर्भित करना चुनते हैं। + +=== "पहले" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. टेस्ट चलाएं और आउटपुट की जांच करें + +टेस्ट चलाएं: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +जैसा कि हमने पहले सीखा, इसने process की सफलता के बारे में मूल assertion को सत्यापित किया और process के आउटपुट के आधार पर एक snapshot फ़ाइल बनाई। हम `tests/modules/samtools/index/tests/main.nf.test.snap` फ़ाइल में snapshot फ़ाइल की सामग्री देख सकते हैं: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +हम टेस्ट को फिर से चला सकते हैं और देख सकते हैं कि यह पास हो जाता है, क्योंकि आउटपुट snapshot के समान है: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. `SAMTOOLS_INDEX` में अधिक टेस्ट जोड़ें + +कभी-कभी यह सुनिश्चित करने के लिए कि हम विभिन्न संभावित मुद्दों के लिए टेस्ट कर रहे हैं, विभिन्न इनपुट फ़ाइलों की एक श्रृंखला को टेस्ट करना उपयोगी होता है। हमारे टेस्ट डेटा से trio में mother और father की BAM फ़ाइलों के लिए टेस्ट जोड़ें। + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +फिर आप टेस्ट को फिर से चला सकते हैं: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +चेतावनी पर ध्यान दें, जो `--update-snapshot` पैरामीटर के प्रभाव को संदर्भित करती है। + +!!! note + + यहां हम टेस्ट डेटा का उपयोग कर रहे हैं जिसे हमने पहले pipeline के वैज्ञानिक आउटपुट का प्रदर्शन करने के लिए उपयोग किया था। + यदि हम इन टेस्टों को production वातावरण में संचालित करने की योजना बना रहे होते, तो हमने testing उद्देश्यों के लिए छोटे इनपुट उत्पन्न किए होते। + + सामान्य तौर पर, process functionality का मूल्यांकन करने के लिए आवश्यक और पर्याप्त डेटा के सबसे छोटे टुकड़ों का उपयोग करके unit tests को यथासंभव हल्का रखना महत्वपूर्ण है, अन्यथा कुल runtime गंभीरता से जोड़ सकता है। + एक टेस्ट suite जो नियमित रूप से चलने में बहुत लंबा समय लेता है, एक ऐसा टेस्ट suite है जिसे सुविधा के हित में छोड़े जाने की संभावना है। + +### निष्कर्ष + +आपने एक genomics process के लिए अपना पहला मॉड्यूल टेस्ट लिखा है, यह सत्यापित करते हुए कि `SAMTOOLS_INDEX` विभिन्न BAM फ़ाइलों के लिए सही तरीके से इंडेक्स फ़ाइलें बनाता है। टेस्ट suite सुनिश्चित करता है कि: + +1. Process सफलतापूर्वक चलता है +2. इंडेक्स फ़ाइलें बनाई गई हैं +3. आउटपुट runs में consistent हैं +4. Process सभी नमूना BAM फ़ाइलों के लिए काम करता है + +### आगे क्या है? + +हमारी genomics workflow में अन्य processes के लिए टेस्ट लिखना सीखें, chained processes को संभालने के लिए setup method का उपयोग करते हुए। हम यह भी मूल्यांकन करेंगे कि आउटपुट, विशेष रूप से हमारी VCF फ़ाइलें, अपेक्षित variant calls शामिल हैं या नहीं। + +--- + +## 2. एक chained process में टेस्ट जोड़ें और सामग्री के लिए टेस्ट करें + +`GATK_HAPLOTYPECALLER` को टेस्ट करने के लिए, हमें process को इनपुट के रूप में `SAMTOOLS_INDEX` आउटपुट प्रदान करना होगा। हम `SAMTOOLS_INDEX` को चलाकर, इसके आउटपुट को पुनर्प्राप्त करके, और उन्हें workflow के लिए टेस्ट डेटा के साथ संग्रहीत करके ऐसा कर सकते हैं। वास्तव में यह एक polished pipeline के लिए अनुशंसित दृष्टिकोण है, लेकिन nf-test `setup` method का उपयोग करके एक वैकल्पिक दृष्टिकोण प्रदान करता है। + +setup method के साथ, हम टेस्ट setup के हिस्से के रूप में `SAMTOOLS_INDEX` process को ट्रिगर कर सकते हैं, और फिर इसके आउटपुट को `GATK_HAPLOTYPECALLER` के लिए इनपुट के रूप में उपयोग कर सकते हैं। इसकी एक लागत है: हमें हर बार `GATK_HAPLOTYPECALLER` के लिए टेस्ट चलाते समय `SAMTOOLS_INDEX` process चलानी होगी। हालांकि, शायद हम अभी भी workflow विकसित कर रहे हैं और टेस्ट डेटा pre-generate नहीं करना चाहते जिसे हमें बाद में बदलना पड़ सकता है। `SAMTOOLS_INDEX` process भी बहुत तेज़ है, इसलिए शायद इसके आउटपुट को pre-generate और स्टोर करने के लाभ नगण्य हैं। यहां बताया गया है कि setup method कैसे काम करता है। + +### 2.1. टेस्ट फ़ाइल उत्पन्न करें और रखें + +पहले की तरह, सबसे पहले हम फ़ाइल stub उत्पन्न करते हैं: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +यह निम्नलिखित टेस्ट stub उत्पन्न करता है: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. टेस्ट फ़ाइल को स्थानांतरित करें और script path को अपडेट करें + +हम मॉड्यूल की `main.nf` फ़ाइल के साथ co-located टेस्ट फ़ाइल के लिए एक डायरेक्टरी बनाते हैं: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +और टेस्ट stub फ़ाइल को वहाँ स्थानांतरित करें: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +अंत में, script path को अपडेट करना न भूलें: + +=== "बाद में" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "पहले" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. setup method का उपयोग करके इनपुट प्रदान करें + +हम `when` block से पहले एक `setup` block डालते हैं, जहां हम हमारी मूल इनपुट फ़ाइलों में से एक पर `SAMTOOLS_INDEX` process का एक रन ट्रिगर कर सकते हैं। साथ ही, पहले की तरह टेस्ट के नाम को कुछ सार्थक में बदलना याद रखें। + +=== "बाद में" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "पहले" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +फिर हम उस process के आउटपुट को `when` block में संदर्भित कर सकते हैं जहां हम टेस्ट इनपुट निर्दिष्ट करते हैं: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +वह परिवर्तन करें और टेस्ट को फिर से चलाएं: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +यह पहले की तरह एक snapshot फ़ाइल भी उत्पन्न करता है। + +### 2.4. फिर से चलाएं और विफलता देखें + +दिलचस्प बात यह है कि यदि आप बिल्कुल वही कमांड फिर से चलाते हैं, तो इस बार टेस्ट विफल हो जाएगा। + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +त्रुटि संदेश आपको बताता है कि दो runs के लिए snapshots के बीच अंतर थे; विशेष रूप से, VCF फ़ाइलों के लिए md5sum values अलग हैं। + +क्यों? एक लंबी कहानी को छोटा करने के लिए, HaplotypeCaller tool में VCF header में एक timestamp शामिल है जो हर बार अलग है (परिभाषा के अनुसार)। +परिणामस्वरूप, हम केवल यह उम्मीद नहीं कर सकते कि फ़ाइलों में समान md5sums होंगे भले ही उनमें variant calls के संदर्भ में समान सामग्री हो। + +हम इससे कैसे निपटते हैं? + +### 2.5. एक विशिष्ट variant की जांच करने के लिए content assertion method का उपयोग करें + +समस्या को हल करने का एक तरीका [एक अलग प्रकार के assertion](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions) का उपयोग करना है। +इस मामले में, हम identity को assert करने के बजाय विशिष्ट सामग्री की जांच करने जा रहे हैं। +अधिक सटीक रूप से, हम tool को VCF फ़ाइल की lines पढ़ने और विशिष्ट lines के अस्तित्व की जांच करने देंगे। + +व्यवहार में, हम `then` block में दूसरे assertion को निम्नानुसार बदल देते हैं: + +=== "बाद में" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "पहले" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +यहां हम VCF आउटपुट फ़ाइल की पूरी सामग्री को पढ़ रहे हैं और content match की खोज कर रहे हैं, जो एक छोटी टेस्ट फ़ाइल पर करना ठीक है, लेकिन आप किसी बड़ी फ़ाइल पर ऐसा नहीं करना चाहेंगे। +आप इसके बजाय विशिष्ट lines पढ़ना चुन सकते हैं। + +इस दृष्टिकोण के लिए अधिक सावधानी से चुनने की आवश्यकता है कि हम 'signal' के रूप में किसका उपयोग करना चाहते हैं। +सकारात्मक पक्ष में, इसका उपयोग बड़ी सटीकता के साथ यह टेस्ट करने के लिए किया जा सकता है कि क्या एक analysis tool लगातार 'कठिन' सुविधाओं (जैसे rare variants) की पहचान कर सकता है क्योंकि यह आगे के विकास से गुजरता है। + +### 2.6. फिर से चलाएं और सफलता देखें + +एक बार जब हमने इस तरह से टेस्ट को संशोधित कर लिया है, तो हम टेस्ट को कई बार चला सकते हैं, और यह लगातार पास होगा। + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. अधिक टेस्ट जोड़ें + +mother और father नमूनों के लिए समान टेस्ट जोड़ें: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. टेस्ट कमांड चलाएं + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +यह pipeline में इस दूसरे चरण के लिए मूल टेस्ट योजना को पूरा करता है। तीसरे और अंतिम module-level टेस्ट पर आगे बढ़ें! + +### निष्कर्ष + +आपने सीखा कि कैसे: + +1. उन processes को टेस्ट करें जो अन्य processes के आउटपुट पर निर्भर हैं +2. VCF आउटपुट फ़ाइलों में विशिष्ट genomic variants सत्यापित करें +3. विशिष्ट सामग्री की जांच करके non-deterministic आउटपुट को संभालें +4. कई नमूनों में variant calling टेस्ट करें + +### आगे क्या है? + +joint genotyping चरण के लिए pre-generated टेस्ट डेटा का उपयोग करने वाले टेस्ट लिखना सीखें। + +--- + +## 3. Pre-generated टेस्ट डेटा का उपयोग करें + +joint genotyping चरण के लिए, हम एक अलग दृष्टिकोण का उपयोग करेंगे - pre-generated टेस्ट डेटा का उपयोग करना। यह अक्सर इसके लिए बेहतर होता है: + +1. कई dependencies के साथ जटिल processes +2. Processes जो चलने में लंबा समय लेती हैं +3. Processes जो एक स्थिर, production pipeline का हिस्सा हैं + +### 3.1. टेस्ट डेटा उत्पन्न करें + +इस खंड की शुरुआत में हमने जो परिणाम उत्पन्न किए थे, उनका निरीक्षण करें: + +```bash +tree results_genomics/ +``` + +```console title="परिणाम डायरेक्टरी की सामग्री" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +joint genotyping चरण को haplotype caller चरणों द्वारा उत्पादित VCF फ़ाइलों को indices के साथ इनपुट के रूप में चाहिए। तो चलिए हमारे पास जो परिणाम हैं उन्हें `jointgenotyping` मॉड्यूल की टेस्ट डायरेक्टरी में कॉपी करें। + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +अब हम इन फ़ाइलों को joint genotyping चरण के लिए हम जो टेस्ट लिखने जा रहे हैं उसके इनपुट के रूप में उपयोग कर सकते हैं। + +### 3.2. टेस्ट फ़ाइल stub उत्पन्न करें + +पहले की तरह, सबसे पहले हम फ़ाइल stub उत्पन्न करते हैं: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +यह निम्नलिखित टेस्ट stub उत्पन्न करता है: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. टेस्ट फ़ाइल को स्थानांतरित करें और script path को अपडेट करें + +इस बार हमारे पास पहले से ही मॉड्यूल की `main.nf` फ़ाइल के साथ co-located टेस्ट के लिए एक डायरेक्टरी है, इसलिए हम टेस्ट stub फ़ाइल को वहाँ स्थानांतरित कर सकते हैं: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +और script path को अपडेट करना न भूलें: + +=== "बाद में" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "पहले" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. इनपुट प्रदान करें + +process input definitions के आधार पर इनपुट भरें और टेस्ट का नाम तदनुसार बदलें: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Content assertions का उपयोग करें + +joint genotyping चरण का आउटपुट एक और VCF फ़ाइल है, इसलिए हम फिर से content assertion का उपयोग करने जा रहे हैं। + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +आउटपुट फ़ाइल में एक विशिष्ट variant की सामग्री की जांच करके, यह टेस्ट सत्यापित करता है कि: + +1. joint genotyping process सफलतापूर्वक चलता है +2. आउटपुट VCF में सही क्रम में सभी तीन नमूने शामिल हैं +3. एक विशिष्ट variant को सही तरीके से call किया गया है: + - प्रत्येक नमूने के लिए सटीक genotypes (father के लिए 0/1, mother और son के लिए 1/1) + - सही read depths और genotype qualities + - Population-level आंकड़े जैसे allele frequency (AF=0.833) + +हमने पूरी फ़ाइल को snapshot नहीं किया है, लेकिन एक विशिष्ट variant की जांच करके, हम आश्वस्त हो सकते हैं कि joint genotyping process अपेक्षा के अनुसार काम कर रही है। + +### 3.6. टेस्ट चलाएं + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "कमांड आउटपुट" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +टेस्ट पास हो जाता है, यह सत्यापित करते हुए कि हमारी joint genotyping process सही तरीके से: + +1. व्यक्तिगत नमूना VCFs को जोड़ती है +2. joint variant calling करती है +3. runs में consistent genotype calls के साथ एक multi-sample VCF उत्पन्न करती है + +### निष्कर्ष + +आप जानते हैं कि कैसे: + +- टेस्ट के लिए इनपुट के रूप में पहले से उत्पन्न परिणामों का उपयोग करें +- Pre-generated टेस्ट डेटा का उपयोग करके टेस्ट लिखें + +### आगे क्या है? + +पूरी variant calling pipeline end-to-end सही तरीके से काम करती है यह सत्यापित करने के लिए एक workflow-level टेस्ट जोड़ें। + +--- + +## 4. एक workflow-level टेस्ट जोड़ें + +अब हम पूरी variant calling pipeline को टेस्ट करेंगे, BAM फ़ाइलों से लेकर joint genotypes तक। यह सत्यापित करता है कि: + +1. सभी processes एक साथ सही तरीके से काम करती हैं +2. डेटा चरणों के बीच उचित रूप से flow करता है +3. अंतिम variant calls consistent हैं + +### 4.1. workflow टेस्ट उत्पन्न करें + +पूरी pipeline के लिए एक टेस्ट फ़ाइल उत् diff --git a/docs/hi/docs/nf4_science/genomics/05_configuration.md b/docs/hi/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..614cd6434f --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# भाग 3: संसाधन प्रोफाइलिंग और अनुकूलन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह एक प्लेसहोल्डर है + +!!!note "नोट" + + यह प्रशिक्षण मॉड्यूल पुनर्विकास के अधीन है। + +--- + +TODO + +### 1.1. संसाधन उपयोग रिपोर्ट उत्पन्न करने के लिए workflow चलाएं + +Nextflow से रिपोर्ट स्वचालित रूप से उत्पन्न करवाने के लिए, बस अपनी command line में `-with-report <filename>.html` जोड़ें। + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +यह रिपोर्ट एक html फ़ाइल है, जिसे आप डाउनलोड करके अपने ब्राउज़र में खोल सकते हैं। आप बाईं ओर फ़ाइल explorer में इस पर right click भी कर सकते हैं और इसे VS Code में देखने के लिए `Show preview` पर क्लिक कर सकते हैं। + +रिपोर्ट को देखने में कुछ मिनट लें और देखें कि क्या आप संसाधनों को समायोजित करने के कुछ अवसरों की पहचान कर सकते हैं। +उन tabs पर क्लिक करना सुनिश्चित करें जो आवंटित की गई राशि के प्रतिशत के रूप में उपयोग के परिणाम दिखाते हैं। +सभी उपलब्ध सुविधाओं का वर्णन करने वाला कुछ [documentation](https://www.nextflow.io/docs/latest/reports.html) है। + +<!-- TODO: insert images --> + +एक अवलोकन यह है कि `GATK_JOINTGENOTYPING` CPU के लिए बहुत भूखा लगता है, जो समझ में आता है क्योंकि यह बहुत सारी जटिल गणनाएं करता है। +तो हम इसे बढ़ाने का प्रयास कर सकते हैं और देख सकते हैं कि क्या यह runtime को कम करता है। + +हालांकि, ऐसा लगता है कि हमने memory आवंटन के साथ निशाने से आगे निकल गए हैं; सभी processes केवल उस अंश का उपयोग कर रही हैं जो हम उन्हें दे रहे हैं। +हमें इसे वापस कम करना चाहिए और कुछ संसाधन बचाने चाहिए। + +### 1.2. किसी विशिष्ट process के लिए संसाधन आवंटन समायोजित करें + +हम `withName` process selector का उपयोग करके किसी दिए गए process के लिए संसाधन आवंटन निर्दिष्ट कर सकते हैं। +जब यह process block में अकेला हो तो syntax इस तरह दिखता है: + +```groovy title="Syntax" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +आइए इसे `nextflow.config` फ़ाइल में मौजूदा process block में जोड़ें। + +```groovy title="nextflow.config" linenums="11" +process { + // सभी processes के लिए defaults + cpus = 2 + memory = 2.GB + // एक विशिष्ट process के लिए आवंटन + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +इसके निर्दिष्ट होने के साथ, default सेटिंग्स सभी processes पर लागू होंगी **सिवाय** `GATK_JOINTGENOTYPING` process के, जो एक विशेष snowflake है जिसे बहुत अधिक CPU मिलता है। +उम्मीद है कि इसका प्रभाव होना चाहिए। + +### 1.3. संशोधित configuration के साथ फिर से चलाएं + +आइए संशोधित configuration के साथ workflow को फिर से चलाएं और reporting flag को चालू रखें, लेकिन ध्यान दें कि हम रिपोर्ट को एक अलग नाम दे रहे हैं ताकि हम उन्हें अलग कर सकें। + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +एक बार फिर, आप शायद runtime में कोई महत्वपूर्ण अंतर नहीं देखेंगे, क्योंकि यह इतना छोटा workload है और tools 'वास्तविक' काम करने की तुलना में सहायक कार्यों में अधिक समय बिताते हैं। + +हालांकि, दूसरी रिपोर्ट दिखाती है कि अब हमारा संसाधन उपयोग अधिक संतुलित है। + +<!-- **TODO: screenshots?** --> + +जैसा कि आप देख सकते हैं, यह दृष्टिकोण तब उपयोगी है जब आपकी processes की अलग-अलग संसाधन आवश्यकताएं हों। यह आपको वास्तविक डेटा के आधार पर प्रत्येक process के लिए सेट किए गए संसाधन आवंटन को सही आकार देने में सक्षम बनाता है, अनुमान लगाने पर नहीं। + +!!!note "नोट" + + यह सिर्फ एक छोटा सा स्वाद है कि आप संसाधनों के उपयोग को अनुकूलित करने के लिए क्या कर सकते हैं। + Nextflow में स्वयं कुछ वास्तव में बढ़िया [dynamic retry logic](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) अंतर्निहित है जो संसाधन सीमाओं के कारण विफल होने वाली jobs को पुनः प्रयास करता है। + इसके अतिरिक्त, Seqera Platform आपके संसाधन आवंटन को स्वचालित रूप से अनुकूलित करने के लिए AI-संचालित टूलिंग भी प्रदान करता है। + + हम इस प्रशिक्षण पाठ्यक्रम के आने वाले भाग में इन दोनों दृष्टिकोणों को कवर करेंगे। + +उस ने कहा, आप किस computing executor और compute infrastructure का उपयोग कर रहे हैं, इसके आधार पर आप क्या आवंटित कर सकते हैं (या करना चाहिए) इस पर कुछ बाधाएं हो सकती हैं। उदाहरण के लिए, आपके cluster को आपको कुछ सीमाओं के भीतर रहने की आवश्यकता हो सकती है जो तब लागू नहीं होती जब आप कहीं और चला रहे हों। diff --git a/docs/hi/docs/nf4_science/genomics/index.md b/docs/hi/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..0de9d664a5 --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/index.md @@ -0,0 +1,36 @@ +# जीनोमिक्स के लिए Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह प्रशिक्षण पाठ्यक्रम जीनोमिक्स और संबंधित क्षेत्रों के शोधकर्ताओं के लिए है जो डेटा विश्लेषण pipelines विकसित करने या उन्हें अनुकूलित करने में रुचि रखते हैं। +यह [Hello Nextflow](../../hello_nextflow/) शुरुआती प्रशिक्षण पर आधारित है और यह प्रदर्शित करता है कि जीनोमिक्स डोमेन के विशिष्ट संदर्भ में Nextflow का उपयोग कैसे करें। + +विशेष रूप से, यह पाठ्यक्रम [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit) के साथ एक साधारण variant calling pipeline को लागू करने का तरीका प्रदर्शित करता है, जो high-throughput sequencing डेटा के विश्लेषण के लिए व्यापक रूप से उपयोग किया जाने वाला software package है। + +आइए शुरू करें! प्रशिक्षण वातावरण लॉन्च करने के लिए नीचे "Open in GitHub Codespaces" बटन पर क्लिक करें (अधिमानतः एक अलग टैब में), फिर जब वह लोड हो रहा हो तब आगे पढ़ें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## सीखने के उद्देश्य + +इस पाठ्यक्रम के माध्यम से काम करके, आप सीखेंगे कि एक विशिष्ट जीनोमिक्स उपयोग के मामले में बुनियादी Nextflow अवधारणाओं और टूलिंग को कैसे लागू करें। + +इस workshop के अंत तक आप सक्षम होंगे: + +- एक single नमूने पर variant calling लागू करने के लिए एक linear workflow लिखना +- index फ़ाइलें और reference genome संसाधनों जैसी सहायक फ़ाइलों को उचित रूप से संभालना +- per-sample variant calling को समानांतर करने के लिए Nextflow के dataflow paradigm का लाभ उठाना +- प्रासंगिक channel operators का उपयोग करके multi-sample variant calling को लागू करना +- per-step और end-to-end pipeline tests को लागू करना जो जीनोमिक्स-विशिष्ट विशेषताओं को उचित रूप से संभालते हैं + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## पूर्वापेक्षाएँ + +पाठ्यक्रम निम्नलिखित के साथ न्यूनतम परिचय मानता है: + +- इस वैज्ञानिक डोमेन में सामान्यतः उपयोग किए जाने वाले tools और file formats +- command line के साथ अनुभव +- [Hello Nextflow](../../hello_nextflow/) शुरुआती प्रशिक्षण में शामिल बुनियादी Nextflow अवधारणाओं और टूलिंग + +तकनीकी आवश्यकताओं और वातावरण सेटअप के लिए, [Environment Setup](../../envsetup/) mini-course देखें। diff --git a/docs/hi/docs/nf4_science/genomics/next_steps.md b/docs/hi/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..8589dd9584 --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# अगले कदम + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For Genomics प्रशिक्षण कोर्स पूरा करने पर फिर से बधाई और हमारे सर्वेक्षण को पूरा करने के लिए धन्यवाद! + +--- + +## 1. अपने Nextflow कौशल को बढ़ाने के शीर्ष 3 तरीके + +आपके द्वारा अभी पूरे किए गए कोर्स के आधार पर आगे क्या करना है, इसके लिए यहाँ हमारी शीर्ष तीन सिफारिशें हैं। + +### 1.1. Nextflow को अन्य वैज्ञानिक विश्लेषण उपयोग के मामलों में लागू करें + +सामान्य वैज्ञानिक विश्लेषण उपयोग के मामलों में Hello Nextflow में प्रस्तुत बुनियादी अवधारणाओं और तंत्रों को कैसे लागू किया जाए, यह प्रदर्शित करने वाले अन्य छोटे स्वतंत्र कोर्स की सूची के लिए **[Nextflow for Science](../index.md) पेज देखें**। + +यदि आपको अपने डोमेन को किसी संबंधित उपयोग के मामले द्वारा प्रस्तुत नहीं दिखता है, तो हमें [Community forum](https://community.seqera.io/) में बताएं ताकि हम इसे अपनी विकास सूची में जोड़ सकें। + +### 1.2. nf-core के साथ शुरुआत करें + +**[nf-core](https://nf-co.re/)** वैज्ञानिक अनुसंधान अनुप्रयोगों की एक विस्तृत श्रृंखला के लिए मानकीकृत ओपन-सोर्स पाइपलाइनों को विकसित करने के लिए एक विश्वव्यापी सहयोगात्मक प्रयास है। +इस परियोजना में [100 से अधिक पाइपलाइनें](https://nf-co.re/pipelines/) शामिल हैं जो तुरंत उपयोग के लिए उपलब्ध हैं और [1400 से अधिक प्रोसेस मॉड्यूल](https://nf-co.re/modules/) हैं जिन्हें आपकी अपनी परियोजनाओं में एकीकृत किया जा सकता है, साथ ही डेवलपर टूल का एक समृद्ध सेट भी। + +**[Hello nf-core](../../hello_nf-core/index.md)** प्रशिक्षण कोर्स आपको nf-core समुदाय-क्यूरेटेड पाइपलाइनों और विकास फ्रेमवर्क से परिचित कराएगा, जो आपको पुनरुत्पादनीय, स्केलेबल और मानकीकृत वर्कफ़्लो लिखने में मदद करने के लिए डिज़ाइन किया गया है। आप सीखेंगे कि मौजूदा nf-core पाइपलाइनों का उपयोग कैसे करें, उनके विकास में योगदान कैसे दें, और यहां तक कि अपनी खुद की पाइपलाइनें बनाना शुरू करें, जो सर्वोत्तम प्रथाओं और एक जीवंत समुदाय द्वारा समर्थित हैं। यदि आप वास्तविक दुनिया की परियोजनाओं में अपने Nextflow कौशल को लागू करने के लिए तैयार हैं, तो यह सही अगला कदम है। + +### 1.3. अधिक उन्नत Nextflow सुविधाओं में महारत हासिल करें + +Hello कोर्स में, हम तकनीकी जटिलता के स्तर को जानबूझकर कम रखते हैं ताकि आपको उस जानकारी से अभिभूत न किया जाए जो आपको Nextflow के साथ शुरुआत करने के लिए आवश्यक नहीं है। +जैसे-जैसे आप अपने काम के साथ आगे बढ़ते हैं, आप Nextflow की पूर्ण सुविधा सेट और शक्ति का उपयोग करना सीखना चाहेंगे। + +इस उद्देश्य के लिए, हम वर्तमान में **[Side Quests](../side_quests/index.md) का एक संग्रह** पर काम कर रहे हैं, जो छोटे स्वतंत्र कोर्स हैं जो परीक्षण और मेटाडेटा हैंडलिंग जैसे विशिष्ट विषयों में गहराई से जाते हैं। + +--- + +## 2. Seqera Platform देखें + +**[Seqera Platform](https://seqera.io/) व्यवहार में Nextflow चलाने का सबसे अच्छा तरीका है।** + +यह Nextflow के निर्माताओं द्वारा विकसित एक क्लाउड-आधारित प्लेटफ़ॉर्म है जिसे आप अपने स्वयं के कंप्यूट इंफ्रास्ट्रक्चर (चाहे स्थानीय, HPC या क्लाउड) से कनेक्ट कर सकते हैं ताकि आपके वर्कफ़्लो को लॉन्च और प्रबंधित करना, साथ ही अपने डेटा को प्रबंधित करना और क्लाउड वातावरण में इंटरैक्टिव रूप से विश्लेषण चलाना बहुत आसान हो जाए। + +Free Tier सभी के लिए मुफ्त उपयोग के लिए उपलब्ध है (उपयोग कोटा के साथ)। +योग्य शिक्षाविद [Academic Program](https://seqera.io/academic/program/) के माध्यम से मुफ्त Pro-स्तर की पहुंच (कोई उपयोग सीमा नहीं) प्राप्त कर सकते हैं। + +यह देखने के लिए [Seqera Platform tutorials](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) पर एक नज़र डालें कि यह आपके लिए उपयोगी हो सकता है या नहीं। + +--- + +### अभी के लिए बस इतना ही! + +**अपनी Nextflow यात्रा में शुभकामनाएं और हमें [Community forum](https://community.seqera.io/) में बताने में संकोच न करें कि हम आपकी मदद के लिए और क्या कर सकते हैं।** diff --git a/docs/hi/docs/nf4_science/genomics/survey.md b/docs/hi/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..e32cc580d6 --- /dev/null +++ b/docs/hi/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# फीडबैक सर्वेक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आगे बढ़ने से पहले, कृपया इस छोटे 5-प्रश्न सर्वेक्षण को पूरा करें ताकि आप प्रशिक्षण को रेट कर सकें, अपने अनुभव के बारे में कोई फीडबैक साझा कर सकें, और हमें बता सकें कि हम आपकी Nextflow यात्रा में आपकी मदद के लिए और क्या कर सकते हैं। + +इसे पूरा करने में आपको एक मिनट से भी कम समय लगेगा। हमारी प्रशिक्षण सामग्री को सभी के लिए बेहतर बनाने में मदद करने के लिए धन्यवाद! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/hi/docs/nf4_science/imaging/00_orientation.md b/docs/hi/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..490470a630 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# ओरिएंटेशन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह ओरिएंटेशन मानता है कि आपने पहले से ही "Open in GitHub Codespaces" बटन पर क्लिक करके प्रशिक्षण वातावरण खोल लिया है। +यदि नहीं, तो कृपया अभी ऐसा करें, आदर्श रूप से दूसरे ब्राउज़र विंडो या टैब में ताकि आप इन निर्देशों को वापस देख सकें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "मशीन साइज़ की आवश्यकता" + + इस प्रशिक्षण कोर्स के लिए अपना Codespace बनाते समय **8-core मशीन** चुनना सुनिश्चित करें। bioimaging workflows के लिए अतिरिक्त कंप्यूट संसाधनों की आवश्यकता होती है। + +## GitHub Codespaces + +GitHub Codespaces वातावरण में इस प्रशिक्षण कोर्स के माध्यम से काम करने के लिए आवश्यक सभी सॉफ़्टवेयर, कोड और डेटा शामिल हैं, इसलिए आपको स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। +हालांकि, लॉग इन करने के लिए आपको एक (मुफ्त) GitHub अकाउंट की आवश्यकता है, और यदि आप इंटरफ़ेस से अपरिचित हैं तो आपको [GitHub Codespaces Orientation](../../envsetup/index.md) मिनी-कोर्स पूरा करके इसे जानने में कुछ मिनट देने चाहिए। + +## Docker images को पहले से डाउनलोड करें + +एक बार जब आप अपना Codespace खोल लें, तो आइए इस प्रशिक्षण कोर्स के लिए आवश्यक सभी Docker images को पहले से डाउनलोड करें। +यह बाद में समय बचाएगा और workflows के सुचारू निष्पादन को सुनिश्चित करेगा। + +एक नया टर्मिनल टैब खोलें और निम्नलिखित कमांड चलाएं: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +यह कमांड पृष्ठभूमि में सभी आवश्यक Docker images डाउनलोड करेगा। +जब यह चल रहा हो तब आप ओरिएंटेशन के बाकी हिस्से को जारी रख सकते हैं। + +!!!tip "सुझाव" + + `-stub` फ्लैग pipeline को वास्तविक डेटा को प्रोसेस किए बिना तेज़ी से चलाने की अनुमति देता है, जो images डाउनलोड करने के लिए बिल्कुल सही है। आप टर्मिनल टैब में प्रगति की निगरानी कर सकते हैं। + +## वर्किंग डायरेक्टरी + +इस प्रशिक्षण कोर्स के दौरान, हम `nf4-science/imaging/` डायरेक्टरी में काम करेंगे। + +टर्मिनल में यह कमांड चलाकर अभी डायरेक्टरी बदलें: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "सुझाव" + + यदि किसी कारणवश आप इस डायरेक्टरी से बाहर चले जाते हैं, तो आप हमेशा इसमें वापस आने के लिए पूरा path उपयोग कर सकते हैं, यह मानते हुए कि आप इसे GitHub Codespaces प्रशिक्षण वातावरण के भीतर चला रहे हैं: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**अब, कोर्स शुरू करने के लिए, इस पेज के नीचे दाएं कोने में तीर पर क्लिक करें।** diff --git a/docs/hi/docs/nf4_science/imaging/01_basics.md b/docs/hi/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..a0c18a5ab6 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# भाग 1: बुनियादी ऑपरेशन चलाएं + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging प्रशिक्षण पाठ्यक्रम के इस पहले भाग में, हम एक बहुत ही बुनियादी domain-agnostic Hello World उदाहरण का उपयोग करेंगे ताकि आवश्यक ऑपरेशन प्रदर्शित कर सकें और संबंधित Nextflow कोड घटकों को इंगित कर सकें। + +## 1. workflow चलाएं + +हम आपको `hello-world.nf` नाम की एक workflow स्क्रिप्ट प्रदान करते हैं जो `--greeting` नाम के command-line argument के माध्यम से इनपुट लेती है और उस greeting वाली एक text फ़ाइल बनाती है। +हम अभी कोड को नहीं देखेंगे; पहले देखते हैं कि इसे चलाना कैसा लगता है। + +### 1.1. workflow लॉन्च करें और execution की निगरानी करें + +टर्मिनल में, निम्नलिखित कमांड चलाएं: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +आपका console आउटपुट कुछ इस तरह दिखना चाहिए: + +```console title="Output" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +बधाई हो, आपने अभी-अभी अपना पहला Nextflow workflow चलाया! + +यहाँ सबसे महत्वपूर्ण आउटपुट आखिरी लाइन है (line 6): + +```console title="Output" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +यह हमें बताता है कि `sayHello` process एक बार सफलतापूर्वक executed हुआ (`1 of 1 ✔`)। + +यह बढ़िया है, लेकिन आप सोच रहे होंगे: आउटपुट कहाँ है? + +### 1.2. `results` डायरेक्टरी में आउटपुट फ़ाइल खोजें + +यह workflow अपने आउटपुट को `results` नाम की डायरेक्टरी में publish करने के लिए configured है। +यदि आप अपनी वर्तमान डायरेक्टरी को देखें, तो आप देखेंगे कि जब आपने workflow चलाई, तो Nextflow ने `results` नाम की एक नई डायरेक्टरी बनाई, जिसमें `output.txt` नाम की एक फ़ाइल है। + +```console title="results/" linenums="1" +results +└── output.txt +``` + +फ़ाइल खोलें; सामग्री आपके द्वारा command line पर दी गई greeting से मेल खानी चाहिए। + +<details> + <summary>फ़ाइल सामग्री</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +यह बढ़िया है, हमारी workflow ने वह किया जो उसे करना था! + +हालांकि, ध्यान रखें कि 'published' परिणाम वास्तविक आउटपुट की एक copy (या कुछ मामलों में symlink) है जो Nextflow ने तब उत्पन्न किया जब उसने workflow को execute किया। + +तो अब, हम यह देखने के लिए अंदर झांकेंगे कि Nextflow ने वास्तव में कार्य कहाँ execute किया। + +!!! warning "चेतावनी" + + सभी workflows अपने आउटपुट को results डायरेक्टरी में publish करने के लिए set up नहीं होंगे, और/या डायरेक्टरी का नाम अलग हो सकता है। + इस section में थोड़ा आगे, हम आपको दिखाएंगे कि यह व्यवहार कहाँ निर्दिष्ट है। + +### 1.3. `work/` डायरेक्टरी में मूल आउटपुट और logs खोजें + +जब आप एक workflow चलाते हैं, तो Nextflow workflow में प्रत्येक process के हर एक invocation के लिए एक अलग 'task directory' बनाता है (=pipeline में प्रत्येक चरण)। +प्रत्येक के लिए, यह आवश्यक inputs को stage करेगा, संबंधित instruction(s) को execute करेगा और उस एक डायरेक्टरी के भीतर आउटपुट और log फ़ाइलें लिखेगा, जिसका नाम automatically hash का उपयोग करके दिया जाता है ताकि इसे unique बनाया जा सके। + +ये सभी task directories आपकी वर्तमान डायरेक्टरी (जहाँ आप कमांड चला रहे हैं) के अंदर `work` नाम की डायरेक्टरी के अंतर्गत रहेंगी। + +यह भ्रमित करने वाला लग सकता है, तो देखते हैं कि यह व्यवहार में कैसा दिखता है। + +पहले चलाई गई workflow के console आउटपुट पर वापस जाते हुए, हमारे पास यह लाइन थी: + +```console title="Excerpt of command output" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +देखें कि लाइन `[a3/7be2fa]` से कैसे शुरू होती है? +यह उस एक process call के लिए task directory path का एक संक्षिप्त रूप है, और आपको बताता है कि `work/` डायरेक्टरी path के भीतर `sayHello` process call का आउटपुट कहाँ मिलेगा। + +आप निम्नलिखित कमांड टाइप करके (अपने terminal में दिखाई देने वाले `a3/7be2fa` के साथ बदलते हुए) और path को autocomplete करने के लिए tab key दबाकर या asterisk जोड़कर पूरा path पा सकते हैं: + +```bash +tree work/a3/7be2fa* +``` + +यह पूरा path directory path देना चाहिए: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +देखते हैं कि वहाँ क्या है। + +!!! Tip "सुझाव" + + यदि आप VSCode file explorer में task subdirectory की सामग्री ब्राउज़ करते हैं, तो आप सभी फ़ाइलें तुरंत देखेंगे। + हालांकि, log फ़ाइलें terminal में invisible होने के लिए set हैं, इसलिए यदि आप उन्हें देखने के लिए `ls` या `tree` का उपयोग करना चाहते हैं, तो आपको invisible फ़ाइलें प्रदर्शित करने के लिए संबंधित विकल्प set करना होगा। + + ```bash + tree -a work + ``` + +आपके सिस्टम पर सटीक subdirectory नाम अलग होंगे। + +<details> + <summary>डायरेक्टरी सामग्री</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +आपको तुरंत `output.txt` फ़ाइल पहचाननी चाहिए, जो वास्तव में `sayHello` process का मूल आउटपुट है जो `results` डायरेक्टरी में published हुआ। +यदि आप इसे खोलते हैं, तो आपको फिर से `Hello World!` greeting मिलेगी। + +<details> + <summary>output.txt की फ़ाइल सामग्री</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +तो उन अन्य सभी फ़ाइलों का क्या? + +ये helper और log फ़ाइलें हैं जो Nextflow ने task execution के हिस्से के रूप में लिखीं: + +- **`.command.begin`**: Sentinel फ़ाइल जो task launch होते ही बन जाती है। +- **`.command.err`**: Process call द्वारा उत्सर्जित error संदेश (`stderr`) +- **`.command.log`**: Process call द्वारा उत्सर्जित पूर्ण log आउटपुट +- **`.command.out`**: Process call द्वारा नियमित आउटपुट (`stdout`) +- **`.command.run`**: Nextflow द्वारा process call को execute करने के लिए चलाई गई पूर्ण स्क्रिप्ट +- **`.command.sh`**: वह कमांड जो वास्तव में process call द्वारा चलाई गई थी +- **`.exitcode`**: कमांड से परिणामी exit code + +`.command.sh` फ़ाइल विशेष रूप से उपयोगी है क्योंकि यह आपको मुख्य कमांड दिखाती है जो Nextflow ने execute किया, सभी bookkeeping और task/environment setup को शामिल नहीं करते हुए। + +<details> + <summary>फ़ाइल सामग्री</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "सुझाव" + + जब कुछ गलत हो जाता है और आपको troubleshoot करने की आवश्यकता होती है कि क्या हुआ, तो यह देखने के लिए `command.sh` स्क्रिप्ट को देखना उपयोगी हो सकता है कि Nextflow ने workflow instructions, variable interpolation आदि के आधार पर बिल्कुल कौन सी कमांड बनाई। + +### 1.4. वैकल्पिक अभ्यास: अलग-अलग greetings के साथ फिर से चलाएं + +`--greeting` argument के लिए अलग-अलग मानों के साथ workflow को कुछ बार फिर से चलाने की कोशिश करें, फिर `results/` डायरेक्टरी और task directories दोनों की सामग्री देखें। + +देखें कि कैसे isolated task directories के आउटपुट और logs संरक्षित हैं, जबकि `results` डायरेक्टरी की सामग्री बाद के executions के आउटपुट द्वारा overwrite हो जाती है। + +### निष्कर्ष + +आप जानते हैं कि एक साधारण Nextflow स्क्रिप्ट कैसे चलाएं, इसके execution की निगरानी कैसे करें और इसके आउटपुट कैसे खोजें। + +### आगे क्या है? + +सीखें कि बुनियादी Nextflow स्क्रिप्ट कैसे पढ़ें और पहचानें कि इसके घटक इसकी functionality से कैसे संबंधित हैं। + +--- + +## 2. Hello World workflow starter स्क्रिप्ट की जांच करें + +हमने वहाँ मूल रूप से workflow स्क्रिप्ट को एक black box की तरह treat किया। +अब जब हमने देख लिया है कि यह क्या करती है, तो चलिए box खोलते हैं और अंदर देखते हैं। + +_यहाँ लक्ष्य Nextflow कोड की syntax को याद रखना नहीं है, बल्कि यह समझना है कि मुख्य घटक क्या हैं और वे कैसे organized हैं।_ + +### 2.1. समग्र कोड संरचना की जांच करें + +चलिए editor pane में `hello-world.nf` स्क्रिप्ट खोलते हैं। + +<details> + <summary>कोड</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // एक अभिवादन emit करें + sayHello(params.greeting) +} +``` + +</details> + +एक Nextflow स्क्रिप्ट में दो मुख्य प्रकार के core घटक शामिल होते हैं: एक या अधिक **processes**, और **workflow** स्वयं। +प्रत्येक **process** वर्णन करता है कि pipeline में संबंधित step को क्या operation(s) पूरा करना चाहिए, जबकि **workflow** dataflow logic का वर्णन करता है जो विभिन्न steps को जोड़ता है। + +आइए पहले **process** block को करीब से देखें, फिर हम **workflow** block को देखेंगे। + +### 2.2. `process` परिभाषा + +कोड का पहला block एक **process** का वर्णन करता है। +Process परिभाषा keyword `process` से शुरू होती है, इसके बाद process name और अंत में curly braces द्वारा सीमांकित process body आती है। +Process body में एक script block होना चाहिए जो चलाने के लिए कमांड निर्दिष्ट करता है, जो कुछ भी हो सकता है जिसे आप command line terminal में चला सकते हैं। + +यहाँ हमारे पास `sayHello` नाम का एक **process** है जो `greeting` नामक एक **input** variable लेता है और अपने **output** को `output.txt` नामक फ़ाइल में लिखता है। + +<details> + <summary>कोड</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +यह एक बहुत ही minimal process परिभाषा है जिसमें केवल एक `input` परिभाषा, एक `output` परिभाषा और execute करने के लिए `script` है। + +`input` परिभाषा में `val` qualifier शामिल है, जो Nextflow को किसी प्रकार का मान (string, number, जो भी हो) अपेक्षित करने के लिए कहता है। + +`output` परिभाषा में `path` qualifier शामिल है, जो Nextflow को बताता है कि इसे path के रूप में संभाला जाना चाहिए (directory paths और files दोनों शामिल हैं)। + +!!! Tip "सुझाव" + + Output परिभाषा _निर्धारित नहीं करती_ कि क्या आउटपुट बनाया जाएगा। + यह केवल _घोषित करती है_ कि अपेक्षित आउटपुट फ़ाइल(ओं) को कहाँ खोजना है, ताकि execution पूर्ण होने के बाद Nextflow इसे देख सके। + + यह सफलतापूर्वक execute की गई कमांड को verify करने और यदि आवश्यक हो तो downstream processes को आउटपुट पास करने के लिए आवश्यक है। + उत्पादित आउटपुट जो output block में घोषित के साथ मेल नहीं खाता, downstream processes को पास नहीं किया जाएगा। + +वास्तविक दुनिया की pipeline में, एक process में आमतौर पर अतिरिक्त जानकारी होती है जैसे process directives, जिन्हें हम थोड़ी देर में पेश करेंगे। + +### 2.3. `workflow` परिभाषा + +कोड का दूसरा block **workflow** स्वयं का वर्णन करता है। +Workflow परिभाषा keyword `workflow` से शुरू होती है, इसके बाद एक वैकल्पिक नाम, फिर curly braces द्वारा सीमांकित workflow body आती है। + +यहाँ हमारे पास एक **workflow** है जो `sayHello` process की एक call से बना है, जो एक इनपुट लेता है, `params.greeting`, जो उस मान को रखता है जो हमने `--greeting` पैरामीटर को दिया। + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // एक अभिवादन emit करें + sayHello(params.greeting) +} +``` + +यह एक बहुत ही minimal **workflow** परिभाषा है। +वास्तविक दुनिया की pipeline में, workflow में आमतौर पर **channels** द्वारा जुड़े **processes** की कई calls होती हैं, और variable inputs के लिए default मान set up हो सकते हैं। + +हम इसे action में देखेंगे जब हम पाठ्यक्रम के भाग 2 में nf-core/molkart चलाएंगे। + +### 2.4. command-line parameters की `params` प्रणाली + +`params.greeting` जो हम `sayHello()` process call को प्रदान करते हैं, Nextflow कोड का एक सुव्यवस्थित हिस्सा है और इस पर एक अतिरिक्त मिनट बिताने योग्य है। + +जैसा कि ऊपर उल्लेख किया गया है, यही तरीका है जिससे हम `--greeting` command-line पैरामीटर के मान को `sayHello()` process call को पास करते हैं। +वास्तव में, केवल `params.someParameterName` घोषित करने से हम workflow को command-line से `--someParameterName` नामक पैरामीटर दे सकेंगे। + +!!! Tip "सुझाव" + + `params` प्रणाली का उपयोग करके घोषित ये workflow parameters हमेशा दो dashes (`--`) लेते हैं। + यह उन्हें Nextflow-level parameters से अलग करता है, जो केवल एक dash (`-`) लेते हैं। + +### निष्कर्ष + +अब आप जानते हैं कि एक साधारण Nextflow workflow कैसे structured है, और बुनियादी घटक इसकी functionality से कैसे संबंधित हैं। + +### आगे क्या है? + +अपने workflow executions को सुविधाजनक रूप से प्रबंधित करना सीखें। + +--- + +## 3. workflow executions प्रबंधित करें + +Workflows लॉन्च करना और आउटपुट प्राप्त करना जानना बढ़िया है, लेकिन आप जल्दी पाएंगे कि workflow management के कुछ अन्य पहलू हैं जो आपके जीवन को आसान बना देंगे। + +यहाँ हम आपको दिखाते हैं कि जब आपको उसी workflow को फिर से लॉन्च करना हो तो `resume` feature का लाभ कैसे उठाएं, `nextflow log` के साथ execution logs की जांच कैसे करें, और `nextflow clean` के साथ पुरानी work directories को कैसे delete करें। + +### 3.1. `-resume` के साथ workflow को फिर से लॉन्च करें + +कभी-कभी, आप एक pipeline को फिर से चलाना चाहेंगे जिसे आपने पहले लॉन्च किया था, बिना उस काम को फिर से किए जो पहले ही सफलतापूर्वक पूरा हो चुका है। + +Nextflow में `-resume` नामक एक विकल्प है जो आपको ऐसा करने की अनुमति देता है। +विशेष रूप से, इस mode में, कोई भी processes जो पहले से ही बिल्कुल वही कोड, settings और inputs के साथ चलाई जा चुकी हैं, skip की जाएंगी। +इसका मतलब है कि Nextflow केवल उन processes को चलाएगा जिन्हें आपने पिछली बार से जोड़ा या संशोधित किया है, या जिन्हें आप नई settings या inputs प्रदान कर रहे हैं। + +ऐसा करने के दो मुख्य फायदे हैं: + +- यदि आप एक pipeline विकसित करने के बीच में हैं, तो आप अधिक तेजी से iterate कर सकते हैं क्योंकि आपको अपने परिवर्तनों का परीक्षण करने के लिए केवल उस process(es) को चलाना होगा जिस पर आप सक्रिय रूप से काम कर रहे हैं। +- यदि आप production में एक pipeline चला रहे हैं और कुछ गलत हो जाता है, तो कई मामलों में आप समस्या को ठीक कर सकते हैं और pipeline को फिर से लॉन्च कर सकते हैं, और यह failure के बिंदु से चलना resume करेगा, जो आपका बहुत समय और compute बचा सकता है। + +इसका उपयोग करने के लिए, बस अपनी कमांड में `-resume` जोड़ें और इसे चलाएं: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Process status line (line 5) में जोड़े गए `cached:` bit को देखें, जिसका अर्थ है कि Nextflow ने पहचान लिया है कि उसने यह काम पहले ही कर लिया है और बस पिछले सफल run के परिणाम का पुन: उपयोग किया। + +आप यह भी देख सकते हैं कि work subdirectory hash पिछले run के समान है। +Nextflow सचमुच आपको पिछले execution की ओर इशारा कर रहा है और कह रहा है "मैंने वह पहले ही वहाँ कर दिया।" + +!!! Tip "सुझाव" + + जब आप `resume` के साथ pipeline को फिर से चलाते हैं, तो Nextflow किसी भी process call द्वारा `publishDir` डायरेक्टरी में लिखी गई किसी भी फ़ाइल को overwrite नहीं करता है जो पहले सफलतापूर्वक चलाई गई थी। + +### 3.2. पिछले executions के log की जांच करें + +जब भी आप nextflow workflow लॉन्च करते हैं, तो वर्तमान working डायरेक्टरी में `.nextflow` नामक एक hidden डायरेक्टरी के अंतर्गत `history` नामक log फ़ाइल में एक line लिखी जाती है। + +इस जानकारी तक पहुँचने का एक अधिक सुविधाजनक तरीका `nextflow log` कमांड का उपयोग करना है। + +```bash +nextflow log +``` + +यह log फ़ाइल की सामग्री को terminal में आउटपुट करेगा, आपको timestamp, run name, status, और वर्तमान working डायरेक्टरी के भीतर से लॉन्च किए गए हर Nextflow run के लिए पूरी command line दिखाएगा। + +### 3.3. पुरानी work directories delete करें + +विकास प्रक्रिया के दौरान, आप आमतौर पर अपनी draft pipelines को बड़ी संख्या में चलाएंगे, जो कई subdirectories में बहुत सारी फ़ाइलों के संचय का कारण बन सकता है। +चूंकि subdirectories का नाम randomly दिया जाता है, इसलिए उनके नामों से यह बताना मुश्किल है कि पुरानी बनाम अधिक हाल की runs क्या हैं। + +Nextflow में एक सुविधाजनक `clean` subcommand शामिल है जो automatically पिछली runs के लिए work subdirectories को delete कर सकता है जिनकी आपको अब परवाह नहीं है, कई [options](https://www.nextflow.io/docs/latest/reference/cli.html#clean) के साथ यह नियंत्रित करने के लिए कि क्या deleted किया जाएगा। + +आप Nextflow log का उपयोग करके timestamp और/या command line के आधार पर एक run को देख सकते हैं, फिर पहले की runs से work directories को delete करने के लिए `nextflow clean -before <run_name> -f` का उपयोग कर सकते हैं। + +!!! Warning "चेतावनी" + + पिछली runs से work subdirectories को delete करना उन्हें Nextflow के cache से हटा देता है और उन directories में संग्रहीत किसी भी आउटपुट को delete कर देता है। + इसका मतलब है कि यह संबंधित processes को फिर से चलाए बिना execution को resume करने की Nextflow की क्षमता को तोड़ देता है। + + किसी भी आउटपुट को सहेजना आपकी जिम्मेदारी है जिसकी आपको परवाह है या जिस पर आप निर्भर रहने की योजना बनाते हैं! यदि आप इस उद्देश्य के लिए `publishDir` directive का उपयोग कर रहे हैं, तो सुनिश्चित करें कि `copy` mode का उपयोग करें, `symlink` mode का नहीं। + +### निष्कर्ष + +आप जानते हैं कि pipeline को उन steps को दोहराए बिना कैसे फिर से लॉन्च करें जो पहले ही identical तरीके से चलाए गए थे, execution log की जांच करें, और पुरानी work directories को साफ करने के लिए `nextflow clean` कमांड का उपयोग करें। + +### आगे क्या है? + +अब जब आप बुनियादी Nextflow operations समझते हैं, तो आप nf-core/molkart के साथ एक वास्तविक bioimaging pipeline चलाने के लिए तैयार हैं। diff --git a/docs/hi/docs/nf4_science/imaging/02_run_molkart.md b/docs/hi/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..af443f7f50 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# भाग 2: nf-core/molkart चलाना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +भाग 1 में, हमने Nextflow निष्पादन की मूल बातें समझने के लिए एक सरल Hello World वर्कफ़्लो चलाया। +अब हम एक वास्तविक बायोइमेजिंग पाइपलाइन चलाने जा रहे हैं: **nf-core/molkart**। + +यह पाइपलाइन Resolve Bioscience से Molecular Cartography spatial transcriptomics डेटा को प्रोसेस करती है। +हालांकि, यहां आप जो Nextflow पैटर्न सीखेंगे वे किसी भी nf-core पाइपलाइन या प्रोडक्शन वर्कफ़्लो पर लागू होते हैं। + +## 1. nf-core पाइपलाइनों को समझना + +पाइपलाइन चलाने से पहले, आइए समझें कि nf-core क्या है और वर्कफ़्लो चलाने के लिए यह क्यों महत्वपूर्ण है। + +### 1.1. nf-core क्या है? + +[nf-core](https://nf-co.re/) उच्च-गुणवत्ता वाली Nextflow पाइपलाइनों का एक समुदाय-संचालित संग्रह है। +सभी nf-core पाइपलाइनें समान संरचना और परंपराओं का पालन करती हैं, जिसका मतलब है कि एक बार जब आप एक को चलाना सीख लेते हैं, तो आप उनमें से किसी को भी चला सकते हैं। + +nf-core पाइपलाइनों की मुख्य विशेषताएं: + +- **मानकीकृत संरचना**: सभी पाइपलाइनों में सुसंगत पैरामीटर नाम और उपयोग पैटर्न हैं +- **अंतर्निहित टेस्ट डेटा**: प्रत्येक पाइपलाइन में त्वरित सत्यापन के लिए टेस्ट प्रोफाइल शामिल हैं +- **व्यापक दस्तावेज़ीकरण**: विस्तृत उपयोग निर्देश और पैरामीटर विवरण +- **गुणवत्ता नियंत्रण**: MultiQC का उपयोग करके स्वचालित QC रिपोर्ट +- **कंटेनर समर्थन**: पुनरुत्पादकता के लिए पूर्व-निर्मित कंटेनर + +!!! tip "nf-core के बारे में अधिक जानना चाहते हैं?" + + nf-core पाइपलाइन विकास के गहन परिचय के लिए, [Hello nf-core](../../hello_nf-core/index.md) प्रशिक्षण पाठ्यक्रम देखें। + यह शुरुआत से nf-core पाइपलाइनों को बनाने और कस्टमाइज़ करने को कवर करता है। + +### 1.2. molkart पाइपलाइन + +![nf-core/molkart पाइपलाइन](img/molkart.png) + +[nf-core/molkart](https://nf-co.re/molkart) पाइपलाइन कई चरणों में spatial transcriptomics इमेजिंग डेटा को प्रोसेस करती है: + +1. **इमेज प्रीप्रोसेसिंग**: ग्रिड पैटर्न फिलिंग और वैकल्पिक कंट्रास्ट एन्हांसमेंट +2. **सेल सेगमेंटेशन**: कई एल्गोरिदम विकल्प (Cellpose, Mesmer, ilastik, Stardist) +3. **स्पॉट असाइनमेंट**: सेगमेंटेड सेल्स को ट्रांसक्रिप्ट स्पॉट असाइन करना +4. **गुणवत्ता नियंत्रण**: व्यापक QC रिपोर्ट जेनरेट करना + +मुख्य आउटपुट हैं: + +- सेल-बाय-ट्रांसक्रिप्ट काउंट टेबल +- सेगमेंटेशन मास्क +- MultiQC गुणवत्ता नियंत्रण रिपोर्ट + +--- + +## 2. टेस्ट डेटा के साथ molkart चलाना + +शुरू करने से पहले, आइए molkart रिपॉजिटरी को स्थानीय रूप से क्लोन करें ताकि हम इसके कोड का निरीक्षण कर सकें: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +यह एक `molkart/` डायरेक्टरी बनाता है जिसमें संपूर्ण पाइपलाइन सोर्स कोड होता है। + +!!! note "हम स्थानीय रूप से क्यों क्लोन कर रहे हैं?" + + आमतौर पर, आप nf-core पाइपलाइनों को सीधे GitHub से `nextflow run nf-core/molkart -r 1.2.0` का उपयोग करके चलाते हैं। + Nextflow आपके लिए स्वचालित रूप से अनुरोधित पाइपलाइन संस्करण को `$HOME/.nextflow/assets/nf-core/molkart` पर डाउनलोड करता है और वहां से चलाता है। + हालांकि, इस प्रशिक्षण के लिए, हम पाइपलाइन को एक अलग स्थानीय डायरेक्टरी में क्लोन कर रहे हैं ताकि हम कोड का अधिक आसानी से निरीक्षण कर सकें। + +### 2.1. कंटेनर आवश्यकताओं को समझना + +पूर्ण पाइपलाइन चलाने से पहले, आइए जानें कि nf-core पाइपलाइनों के लिए कंटेनर क्यों आवश्यक हैं। + +आइए molkart टेस्ट कॉन्फ़िगरेशन से टेस्ट डेटासेट और पैरामीटर का उपयोग करके पाइपलाइन चलाने का प्रयास करें: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +आइए इन पैरामीटर्स को समझें: + +- `--input`: नमूना मेटाडेटा युक्त samplesheet का पथ +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: ग्रिड पैटर्न फिलिंग के लिए पैरामीटर +- `--clahe_pyramid_tile`: कंट्रास्ट एन्हांसमेंट के लिए कर्नेल साइज़ +- `--segmentation_method`: सेल सेगमेंटेशन के लिए कौन सा एल्गोरिदम उपयोग करना है +- `--outdir`: परिणाम कहां सेव करने हैं + +!!! Warning "यह कमांड विफल होगी - यह जानबूझकर है!" + + हम जानबूझकर इसे कंटेनर के बिना चला रहे हैं ताकि यह प्रदर्शित कर सकें कि उनकी आवश्यकता क्यों है। + +कुछ क्षणों के बाद, आपको इस तरह की एक एरर दिखेगी: + +??? failure "कमांड आउटपुट" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**यहां क्या हो रहा है?** + +एरर `command not found` (exit status 127) का मतलब है कि Nextflow ने `duplicate_finder.py` चलाने का प्रयास किया लेकिन इसे आपके सिस्टम पर नहीं मिला। +ऐसा इसलिए है क्योंकि: + +1. पाइपलाइन को विशेष बायोइंफॉर्मेटिक्स सॉफ़्टवेयर इंस्टॉल होने की उम्मीद है +2. ये टूल (जैसे `duplicate_finder.py`, `apply_clahe.dask.py`, आदि) मानक Linux वितरणों का हिस्सा नहीं हैं +3. कंटेनर के बिना, Nextflow आपकी स्थानीय मशीन पर सीधे कमांड चलाने का प्रयास करता है + +**इन टूल्स को कहां से आना चाहिए?** + +आइए एक प्रोसेस मॉड्यूल का निरीक्षण करें यह देखने के लिए कि यह अपनी सॉफ़्टवेयर आवश्यकताओं को कैसे घोषित करता है। + +CLAHE प्रीप्रोसेसिंग मॉड्यूल खोलें: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +लाइन 5 को देखें - आपको दिखेगा: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +यह लाइन Nextflow को बताती है: "इस प्रोसेस को चलाने के लिए, Docker इमेज `ghcr.io/schapirolabor/molkart-local:v0.0.4` का उपयोग करें, जिसमें सभी आवश्यक सॉफ़्टवेयर हैं।" + +प्रत्येक प्रोसेस घोषित करता है कि कौन सी कंटेनर इमेज अपने आवश्यक टूल प्रदान करती है। +हालांकि, Nextflow इन कंटेनरों का उपयोग तभी करता है जब आप इसे बताते हैं! + +**समाधान: कॉन्फ़िगरेशन में Docker सक्षम करें** + +### 2.2. Docker कॉन्फ़िगर करें और पाइपलाइन लॉन्च करें + +Docker सक्षम करने के लिए, हमें `nextflow.config` फ़ाइल में `docker.enabled` को `false` से `true` में बदलना होगा। + +कॉन्फ़िग फ़ाइल खोलें: + +```bash +code nextflow.config +``` + +`docker.enabled = false` को `docker.enabled = true` में बदलें: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +अब समान कमांड के साथ पाइपलाइन फिर से चलाएं: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +इस बार, Nextflow: + +1. कॉन्फ़िग से `docker.enabled = true` सेटिंग पढ़ेगा +2. आवश्यक Docker इमेज पुल करेगा (केवल पहली बार) +3. प्रत्येक प्रोसेस को उसकी निर्दिष्ट कंटेनर के अंदर चलाएगा +4. सफलतापूर्वक निष्पादित होगा क्योंकि सभी टूल कंटेनरों के अंदर उपलब्ध हैं + +!!! Tip "कंटेनर क्यों महत्वपूर्ण हैं" + + अधिकांश nf-core पाइपलाइनों को कंटेनराइज़ेशन (Docker, Singularity, Podman, आदि) की **आवश्यकता** होती है क्योंकि: + + - वे विशेष बायोइंफॉर्मेटिक्स सॉफ़्टवेयर का उपयोग करते हैं जो मानक वातावरणों में उपलब्ध नहीं होते + - कंटेनर पुनरुत्पादकता सुनिश्चित करते हैं - बिल्कुल समान सॉफ़्टवेयर संस्करण हर जगह चलते हैं + - आपको दर्जनों टूल और उनकी निर्भरताओं को मैन्युअल रूप से इंस्टॉल करने की आवश्यकता नहीं है + + Nextflow में कंटेनरों के बारे में अधिक विवरण के लिए, Hello Nextflow प्रशिक्षण से [Hello Containers](../../hello_nextflow/05_hello_containers.md) देखें। + +### 2.3. निष्पादन की निगरानी करें + +जैसे-जैसे पाइपलाइन चलती है, आपको इस तरह का आउटपुट दिखेगा: + +??? success "कमांड आउटपुट" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +ध्यान दें कि यह आउटपुट हमारे Hello World उदाहरण से अधिक विस्तृत है क्योंकि पाइपलाइन द्वारा अपनाई गई nf-core परंपराओं के कारण: + +- पाइपलाइन अपना संस्करण और लोगो दिखाती है +- कॉन्फ़िगरेशन पैरामीटर प्रदर्शित किए जाते हैं +- कई प्रोसेस समानांतर में चलते हैं (कई प्रोसेस लाइनों द्वारा संकेत किया गया) +- प्रोसेस नामों में पूर्ण मॉड्यूल पथ शामिल है (जैसे, `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. प्रोसेस निष्पादन को समझना + +executor लाइन `executor > local (22)` आपको बताती है: + +- **executor**: किस कंप्यूट वातावरण का उपयोग किया जा रहा है (`local` = आपकी मशीन) +- **(22)**: लॉन्च किए गए कुल कार्यों की संख्या + +प्रत्येक प्रोसेस लाइन दिखाती है: + +- **Hash** (`[1a/2b3c4d]`): work डायरेक्टरी आइडेंटिफ़ायर (पहले की तरह) +- **Process name**: पूर्ण मॉड्यूल पथ और प्रोसेस नाम +- **Input identifier**: कोष्ठक में नमूना नाम +- **Progress**: पूर्णता का प्रतिशत और गिनती (जैसे, `1 of 1 ✔`) + +### निष्कर्ष + +आप जानते हैं कि टेस्ट डेटा के साथ nf-core पाइपलाइन कैसे लॉन्च करें और इसके निष्पादन आउटपुट की व्याख्या कैसे करें। + +### आगे क्या है? + +जानें कि परिणाम कहां मिलेंगे और उनकी व्याख्या कैसे करें। + +--- + +## 3. आउटपुट ढूंढें और जांचें + +जब पाइपलाइन सफलतापूर्वक पूर्ण होती है, तो आपको एक पूर्णता संदेश और निष्पादन सारांश दिखेगा। + +### 3.1. परिणाम डायरेक्टरी का पता लगाएं + +डिफ़ॉल्ट रूप से, nf-core पाइपलाइनें `outdir` पैरामीटर द्वारा निर्दिष्ट डायरेक्टरी में आउटपुट लिखती हैं, जिसे हमने `results/` पर सेट किया था। + +सामग्री की सूची बनाएं: + +```bash +tree results/ +``` + +आपको कई subdirectories दिखनी चाहिए: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +प्रत्येक subdirectory में पाइपलाइन के एक विशिष्ट चरण से आउटपुट होता है: + +- **mindagap/**: MindaGap प्रीप्रोसेसिंग स्टेप से ग्रिड-फिल्ड इमेज +- **clahe/**: CLAHE प्रीप्रोसेसिंग से कंट्रास्ट-एन्हांस्ड इमेज +- **stack/**: सेगमेंटेशन के लिए बनाए गए मल्टी-चैनल इमेज स्टैक +- **segmentation/**: विभिन्न एल्गोरिदम से सेगमेंटेशन परिणाम (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: सेल-बाय-ट्रांसक्रिप्ट काउंट टेबल +- **anndata/**: सेल-बाय-ट्रांसक्रिप्ट मैट्रिसेस और स्थानिक निर्देशांक युक्त AnnData ऑब्जेक्ट +- **molkartqc/**: स्पॉट असाइनमेंट के लिए गुणवत्ता नियंत्रण मेट्रिक्स +- **multiqc/**: व्यापक गुणवत्ता नियंत्रण रिपोर्ट +- **pipeline_info/**: निष्पादन रिपोर्ट और लॉग + +### 3.2. MultiQC रिपोर्ट जांचें + +MultiQC रिपोर्ट एक व्यापक HTML फ़ाइल है जो सभी पाइपलाइन स्टेप्स से गुणवत्ता मेट्रिक्स एकत्रित करती है। + +फ़ाइल ब्राउज़र में रिपोर्ट खोलें और फिर VS Code में सीधे इसे रेंडर देखने के लिए "Show Preview" बटन पर क्लिक करें। + +रिपोर्ट में शामिल है: + +- सभी नमूनों के लिए सामान्य सांख्यिकी +- प्रीप्रोसेसिंग मेट्रिक्स +- सेगमेंटेशन गुणवत्ता मेट्रिक्स +- पाई गई सेल्स और स्पॉट्स की संख्या + +!!! Tip + + MultiQC रिपोर्ट आमतौर पर सभी nf-core पाइपलाइनों में शामिल होती हैं। + वे हमेशा पाइपलाइन निष्पादन और डेटा गुणवत्ता का उच्च-स्तरीय अवलोकन प्रदान करती हैं। + +### 3.3. सेल-बाय-ट्रांसक्रिप्ट टेबल जांचें + +सबसे महत्वपूर्ण वैज्ञानिक आउटपुट सेल-बाय-ट्रांसक्रिप्ट काउंट टेबल है। +यह आपको बताता है कि प्रत्येक सेल में प्रत्येक ट्रांसक्रिप्ट कितने पाए गए। + +spot2cell डायरेक्टरी पर नेविगेट करें: + +```bash +ls results/spot2cell/ +``` + +आपको इस तरह की फ़ाइलें मिलेंगी: + +- `cellxgene_mem_only_cellpose.csv`: Cellpose सेगमेंटेशन का उपयोग करके सेल-बाय-ट्रांसक्रिप्ट टेबल +- `cellxgene_mem_only_mesmer.csv`: Mesmer सेगमेंटेशन का उपयोग करके सेल-बाय-ट्रांसक्रिप्ट टेबल +- `cellxgene_mem_only_stardist.csv`: Stardist सेगमेंटेशन का उपयोग करके सेल-बाय-ट्रांसक्रिप्ट टेबल + +हमने इस टेस्ट डेटासेट में केवल 1 नमूना चलाया, लेकिन एक वास्तविक प्रयोग में हमारे पास प्रत्येक नमूने के लिए ये टेबल होंगी। +ध्यान दें कि Nextflow कैसे समानांतर में कई सेगमेंटेशन विधियों को प्रोसेस कर सकता है, जिससे परिणामों की तुलना करना आसान हो जाता है। + +### 3.4. निष्पादन रिपोर्ट देखें + +Nextflow स्वचालित रूप से कई निष्पादन रिपोर्ट जेनरेट करता है। + +pipeline_info डायरेक्टरी जांचें: + +```bash +ls results/pipeline_info/ +``` + +मुख्य फ़ाइलें: + +- **execution_report.html**: टाइमलाइन और संसाधन उपयोग विज़ुअलाइज़ेशन +- **execution_timeline.html**: प्रोसेस निष्पादन का Gantt चार्ट +- **execution_trace.txt**: विस्तृत कार्य निष्पादन मेट्रिक्स +- **pipeline_dag.html**: वर्कफ़्लो संरचना दिखाने वाला निर्देशित एसाइक्लिक ग्राफ़ + +संसाधन उपयोग देखने के लिए निष्पादन रिपोर्ट खोलें: + +```bash +code results/pipeline_info/execution_report.html +``` + +यह दिखाता है: + +- प्रत्येक प्रोसेस को कितना समय लगा +- CPU और मेमोरी उपयोग +- कौन से कार्य कैश्ड थे बनाम निष्पादित + +!!! Tip + + ये रिपोर्ट संसाधन आवंटन को अनुकूलित करने और प्रदर्शन समस्याओं को ट्रबलशूट करने के लिए अविश्वसनीय रूप से उपयोगी हैं। + +### निष्कर्ष + +आप जानते हैं कि पाइपलाइन आउटपुट कैसे खोजें, गुणवत्ता नियंत्रण रिपोर्ट की जांच करें, और निष्पादन मेट्रिक्स तक पहुंचें। + +### आगे क्या है? + +work डायरेक्टरी के बारे में जानें और Nextflow intermediate फ़ाइलों को कैसे प्रबंधित करता है। + +--- + +## 4. work डायरेक्टरी का अन्वेषण करें + +हमारे Hello World उदाहरण की तरह, सभी वास्तविक कार्य `work/` डायरेक्टरी में होता है। + +### 4.1. work डायरेक्टरी संरचना को समझना + +work डायरेक्टरी में निष्पादित प्रत्येक कार्य के लिए एक subdirectory होती है। +22 कार्यों वाली इस पाइपलाइन के लिए, 22 work subdirectories होंगी। + +work डायरेक्टरी की सूची बनाएं: + +```bash +ls -d work/*/*/ | head -5 +``` + +यह पहली 5 कार्य डायरेक्टरियां दिखाता है। + +### 4.2. एक कार्य डायरेक्टरी का निरीक्षण करें + +console आउटपुट से एक सेगमेंटेशन प्रोसेस हैश (जैसे, `[3m/4n5o6p]`) चुनें और अंदर देखें: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +आपको दिखेगा: + +- **.command.\* फ़ाइलें**: Nextflow निष्पादन स्क्रिप्ट और लॉग (पहले की तरह) +- **Staged इनपुट फ़ाइलें**: वास्तविक इनपुट फ़ाइलों के symlinks +- **आउटपुट फ़ाइलें**: सेगमेंटेशन मास्क, intermediate परिणाम, आदि। + +Hello World से मुख्य अंतर: + +- वास्तविक पाइपलाइनें बड़ी इनपुट फ़ाइलों को stage करती हैं (इमेज, संदर्भ डेटा) +- आउटपुट फ़ाइलें काफी बड़ी हो सकती हैं (सेगमेंटेशन मास्क, प्रोसेस्ड इमेज) +- प्रति कार्य कई इनपुट और आउटपुट फ़ाइलें + +!!! Tip + + यदि कोई प्रोसेस विफल होती है, तो आप उसकी work डायरेक्टरी पर नेविगेट कर सकते हैं, एरर संदेशों के लिए `.command.err` की जांच कर सकते हैं, और समस्या को debug करने के लिए `.command.sh` को मैन्युअली फिर से चला भी सकते हैं। + +### 4.3. work डायरेक्टरी की सफाई + +कई पाइपलाइन रन पर work डायरेक्टरी काफी बड़ी हो सकती है। +जैसा कि हमने भाग 1 में सीखा, आप पुराने रन से work डायरेक्टरियों को हटाने के लिए `nextflow clean` का उपयोग कर सकते हैं। + +हालांकि, बड़ी intermediate फ़ाइलों वाली nf-core पाइपलाइनों के लिए, नियमित रूप से साफ करना विशेष रूप से महत्वपूर्ण है। + +### निष्कर्ष + +आप समझते हैं कि nf-core पाइपलाइनें अपनी work डायरेक्टरियों को कैसे व्यवस्थित करती हैं और debugging के लिए व्यक्तिगत कार्यों का निरीक्षण कैसे करें। + +### आगे क्या है? + +Nextflow cache के बारे में जानें और विफल पाइपलाइन रन को कैसे resume करें। + +--- + +## 5. पाइपलाइन रन को resume करें + +Nextflow की सबसे शक्तिशाली विशेषताओं में से एक विफलता के बिंदु से पाइपलाइन को resume करने की क्षमता है। + +### 5.1. cache तंत्र + +जब आप `-resume` के साथ पाइपलाइन चलाते हैं, तो Nextflow: + +1. प्रत्येक कार्य के लिए cache की जांच करता है +2. यदि इनपुट, कोड, और पैरामीटर समान हैं, तो cached परिणाम का पुन: उपयोग करता है +3. केवल उन कार्यों को फिर से चलाता है जो बदल गए या विफल हुए + +यह लंबे समय तक चलने वाली पाइपलाइनों के लिए आवश्यक है जहां निष्पादन के अंत में विफलताएं हो सकती हैं। + +### 5.2. molkart के साथ resume का प्रयास करें + +समान कमांड फिर से चलाएं, लेकिन `-resume` जोड़ें: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +आपको इस तरह का आउटपुट दिखना चाहिए: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +ध्यान दें प्रत्येक प्रोसेस के लिए `cached: 2` या `cached: 1` - कुछ भी फिर से निष्पादित नहीं किया गया! + +### 5.3. resume कब उपयोगी है + +Resume विशेष रूप से मूल्यवान है जब: + +- संसाधन सीमाओं के कारण पाइपलाइन विफल हो जाती है (मेमोरी समाप्त, समय सीमा पार) +- आपको upstream स्टेप्स को फिर से चलाए बिना downstream प्रोसेस को संशोधित करने की आवश्यकता है +- डेटा डाउनलोड के दौरान आपका नेटवर्क कनेक्शन टूट जाता है +- आप गणना को फिर से किए बिना अतिरिक्त आउटपुट जोड़ना चाहते हैं + +!!! Warning + + Resume केवल तभी काम करता है जब आपने इनपुट डेटा, पाइपलाइन कोड, या पैरामीटर को नहीं बदला हो। + यदि आप इनमें से किसी को भी बदलते हैं, तो Nextflow सही ढंग से प्रभावित कार्यों को फिर से चलाएगा। + +### निष्कर्ष + +आप जानते हैं कि सफल कार्यों को दोहराए बिना पाइपलाइनों को कुशलतापूर्वक फिर से चलाने के लिए `-resume` का उपयोग कैसे करें। + +### आगे क्या है? + +अब जब आप टेस्ट डेटा के साथ nf-core/molkart चला सकते हैं, तो आप अपने स्वयं के डेटासेट के लिए इसे कॉन्फ़िगर करना सीखने के लिए तैयार हैं। diff --git a/docs/hi/docs/nf4_science/imaging/03_inputs.md b/docs/hi/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..cb77bf5d37 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# भाग 3: इनपुट को व्यवस्थित करना + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +भाग 2 में, हमने कमांड लाइन पर कई पैरामीटर के साथ molkart चलाया। +अब हम इनपुट को प्रबंधित करने के दो बेहतर तरीके सीखेंगे: **पैरामीटर फ़ाइलें** और **samplesheets**। + +## 1. पैरामीटर फ़ाइलों का उपयोग + +### 1.1. लंबी कमांड लाइनों की समस्या + +भाग 2 से हमारी कमांड याद करें: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +यह काम करता है, लेकिन इसे पुनः उत्पन्न करना, साझा करना या संशोधित करना कठिन है। +यदि आपको अगले महीने फिर से वही विश्लेषण चलाने की आवश्यकता हो तो क्या होगा? +यदि कोई सहयोगी आपकी सटीक सेटिंग्स का उपयोग करना चाहता है तो क्या होगा? + +### 1.2. समाधान: पैरामीटर फ़ाइल का उपयोग करें + +`params.yaml` नाम की एक फ़ाइल बनाएं: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +अब आपकी कमांड बन जाती है: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +बस इतना ही! पैरामीटर फ़ाइल आपके सटीक कॉन्फ़िगरेशन को दस्तावेज़ित करती है और इसे फिर से चलाना या साझा करना आसान बनाती है। + +### 1.3. पैरामीटर को ओवरराइड करना + +आप अभी भी कमांड लाइन से विशिष्ट पैरामीटर को ओवरराइड कर सकते हैं: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +उपरोक्त लाइन `segmentation_method` को `stardist` में बदल देती है और `--outdir` नाम को `params.yaml` फ़ाइल में दिए गए पैरामीटर के बजाय `stardist_results` में बदल देती है। +इसके अतिरिक्त, आप देख सकते हैं कि `-resume` फ़्लैग ने हमें पिछले रन से प्री-प्रोसेसिंग परिणामों का पुन: उपयोग करने की अनुमति दी, जिससे समय की बचत हुई। +आप इस पैटर्न का उपयोग pipeline के विभिन्न विविधताओं का शीघ्रता से परीक्षण करने के लिए कर सकते हैं। + +### मुख्य बात + +पैरामीटर फ़ाइलें आपके विश्लेषण को पुनरुत्पादनीय और साझा करने में आसान बनाती हैं। +किसी भी वास्तविक विश्लेषण कार्य के लिए इनका उपयोग करें। + +### आगे क्या? + +जानें कि samplesheets कैसे कई नमूनों के बारे में जानकारी को व्यवस्थित करती हैं। + +--- + +## 2. Samplesheet पैटर्न + +### 2.1. Samplesheet क्या है? + +Samplesheet एक CSV फ़ाइल है जो आपके इनपुट नमूनों का वर्णन करती है। +प्रत्येक पंक्ति एक नमूना है, और कॉलम उस नमूने के लिए फ़ाइलों और मेटाडेटा को निर्दिष्ट करते हैं। + +आइए देखें कि हम किस samplesheet का उपयोग कर रहे हैं: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +कॉलम हैं: + +- `sample`: अद्वितीय नमूना पहचानकर्ता +- `nuclear_image`: परमाणु स्टेनिंग इमेज (TIFF) +- `spot_table`: ट्रांसक्रिप्ट स्पॉट्स (TXT) +- `membrane_image`: मेम्ब्रेन स्टेनिंग इमेज (TIFF, वैकल्पिक) + +### 2.2. फ़ाइल पथ + +Samplesheets कई पथ प्रकारों को स्वीकार करती हैं: + +- **URLs**: Nextflow स्वचालित रूप से डाउनलोड करता है (जैसा कि ऊपर दिखाया गया है) +- **स्थानीय पथ**: `data/nuclear.tiff` या `/absolute/path/to/nuclear.tiff` +- **Cloud storage**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +आप एक ही samplesheet में पथ प्रकारों को मिक्स कर सकते हैं। + +### 2.3. अपनी खुद की samplesheet बनाना + +सबसे पहले, आइए परीक्षण डेटा फ़ाइलों को स्थानीय रूप से डाउनलोड करें: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +अब आइए इन स्थानीय फ़ाइलों का संदर्भ देने के लिए samplesheet को संशोधित करें: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "चेतावनी" + + ध्यान दें कि samplesheet में पथ वहाँ से सापेक्ष हैं जहाँ आप Nextflow **चलाते** हैं, न कि जहाँ samplesheet स्थित है। + +अंत में, आइए स्थानीय फ़ाइल पथों के साथ samplesheet के साथ nf-core/molkart को एक बार फिर से निष्पादित करें: + +`nextflow run ./molkart -params-file params.yaml -resume` + +जैसा कि आप देख सकते हैं, Nextflow इस रन को उसी तरह निष्पादित करता है जैसे कि फ़ाइलें Github से डाउनलोड की गई थीं। यह Nextflow की महान विशेषताओं में से एक है, यह आपके लिए डेटा को ठीक से व्यवस्थित करता है, चाहे वह कहीं भी स्थित हो। + +### मुख्य बात + +Samplesheets बहु-नमूना डेटासेट को इस तरह व्यवस्थित करती हैं जो आपको फ़ाइल पथों के साथ अपने मेटाडेटा को स्पष्ट रूप से परिभाषित करने की अनुमति देती हैं। +अधिकांश nf-core pipelines इस पैटर्न का उपयोग करती हैं। + +### आगे क्या? + +अब जब हमने इनपुट को कवर कर लिया है, तो आइए जानें कि विभिन्न कंप्यूटिंग वातावरण के लिए Nextflow pipelines को कैसे कॉन्फ़िगर किया जाए। diff --git a/docs/hi/docs/nf4_science/imaging/04_config.md b/docs/hi/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..eed1a7401a --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# भाग 4: कॉन्फ़िगरेशन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +भाग 1-3 में, हमने सीखा कि Nextflow को कैसे चलाएं, एक nf-core pipeline को कैसे चलाएं, और parameter files और samplesheets के साथ inputs को कैसे मैनेज करें। +अब हम **configuration files** और **profiles** का उपयोग करके विभिन्न computing environments के लिए pipelines को configure करने का तरीका जानेंगे। + +## सीखने के उद्देश्य + +इस भाग के अंत तक, आप सक्षम होंगे: + +- समझना कि Nextflow कई स्रोतों से configuration को कैसे resolve करता है +- containers और testing के लिए nf-core built-in profiles का उपयोग करना +- विभिन्न computing environments के लिए custom profiles बनाना +- process labels का उपयोग करके resource requests को customize करना +- सीमित environments में resource limits को मैनेज करना +- `nextflow config` के साथ resolved configuration को inspect करना + +--- + +## 1. Nextflow configuration को समझना + +### 1.1. configuration file क्या है? + +Nextflow configuration files का उपयोग **workflow logic** (क्या करना है) को **execution settings** (कैसे और कहाँ करना है) से अलग करने के लिए करता है। + +Configuration files निम्नलिखित को नियंत्रित करती हैं: + +- Container engines (Docker, Singularity, Conda) +- Compute resources (CPUs, memory, time) +- Execution platforms (local, HPC, cloud) +- Pipeline parameters + +### 1.2. Configuration precedence + +Nextflow कई स्रोतों से configuration लोड करता है, बाद के स्रोत पहले वाले को override करते हैं: + +1. **Pipeline config**: pipeline repository में `nextflow.config` +2. **Directory config**: आपकी वर्तमान working directory में `nextflow.config` +3. **User config**: `~/.nextflow/config` +4. **Command-line**: सीधे पास किए गए parameters और options + +यह layered approach आपको pipeline में defaults रखने, user-specific settings के साथ override करने, और command line पर त्वरित समायोजन करने देता है। + +### 1.3. हमारा वर्तमान configuration + +आइए उस configuration को देखें जिसका हम उपयोग कर रहे हैं: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +आइए भाग 2 से `docker.enabled = true` लाइन को comment out करें या वापस बदलें, और पता लगाएं कि molkart में एक profile का उपयोग करके हम इसी परिणाम को कैसे प्राप्त कर सकते हैं। + +--- + +## 2. Profiles का उपयोग करना + +### 2.1. Profiles क्या हैं? + +Profiles configuration के नामित सेट हैं जिन्हें `nextflow run` कमांड के माध्यम से `-profile` flag के साथ सक्रिय किया जा सकता है। +ये config files को edit किए बिना विभिन्न compute scenarios के बीच स्विच करना आसान बनाते हैं। + +सभी nf-core pipelines कई default profiles के साथ आते हैं जिनका हम उपयोग कर सकते हैं। + +### 2.2. Built-in profiles को inspect करना + +आइए उन्हें pipeline codebase से जुड़ी `molkart/nextflow.config` फ़ाइल में inspect करें: + +```bash +code molkart/nextflow.config +``` + +`profiles` block को खोजें: + +```groovy title="molkart/nextflow.config (excerpt)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +सामान्य container profiles: + +- `docker`: Docker containers का उपयोग करें (local development के लिए सबसे आम) +- `singularity`: Singularity/Apptainer का उपयोग करें (HPC पर आम) +- `conda`: Conda environments का उपयोग करें +- `apptainer`: Apptainer containers का उपयोग करें + +### 2.3. nextflow.config के बजाय profiles के साथ फिर से चलाना + +अब जब हमने अपनी local `nextflow.config` फ़ाइल में docker configuration को disable कर दिया है और profiles को समझ गए हैं, तो आइए `-profile` flag का उपयोग करके pipeline को फिर से चलाएं। + +पहले भाग 3 में, हमने अपने custom parameters के साथ एक `params.yaml` फ़ाइल बनाई थी। +अब हम इसे built-in Docker profile के साथ combine कर सकते हैं: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +आइए समझें कि प्रत्येक flag क्या करता है: + +- `-profile docker`: molkart के `nextflow.config` से Docker profile को सक्रिय करता है, जो `docker.enabled = true` set करता है +- `-params-file params.yaml`: हमारी YAML फ़ाइल से सभी pipeline parameters लोड करता है +- `-resume`: पिछले runs से cached results का पुनः उपयोग करता है + +क्योंकि हम `-resume` का उपयोग कर रहे हैं, Nextflow जांच करेगा कि पिछली बार से कुछ बदला है या नहीं। +यदि parameters, inputs, और code समान हैं, तो सभी tasks cache से पुनर्प्राप्त किए जाएंगे और pipeline लगभग तुरंत पूरा हो जाएगा। + +```console title="Output (excerpt)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +ध्यान दें कि सभी processes `cached: 2` या `cached: 1` दिखाते हैं - कुछ भी फिर से execute नहीं किया गया! + +### 2.4. Test profiles + +Test profiles default input parameters और datafiles को निर्दिष्ट करने के त्वरित तरीके प्रदान करते हैं ताकि आप सत्यापित कर सकें कि pipeline काम करता है। +nf-core pipelines में हमेशा कम से कम दो test profiles शामिल होंगे: + +- `test`: त्वरित testing के लिए छोटा dataset और fast parameters +- `test_full`: बड़े data के साथ अधिक व्यापक test + +आइए molkart में `test` profile पर करीब से नज़र डालें जो `includeConfig` निर्देश का उपयोग करके शामिल किया गया है: + +```groovy title="molkart/nextflow.config (excerpt)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +इसका मतलब है कि जब भी हम `-profile test` के साथ pipeline चलाते हैं, Nextflow `conf/test.config` से configuration लोड करेगा। + +```groovy title="molkart/conf/test.config (excerpt)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +ध्यान दें कि इस profile में वही parameters हैं जो हमने पहले अपनी `params.yaml` फ़ाइल में उपयोग किए थे। + +आप कॉमा से अलग करके कई profiles को सक्रिय कर सकते हैं। +आइए इसका उपयोग करके अपनी params फ़ाइल की आवश्यकता के बिना अपने pipeline को test करें: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +यह निम्नलिखित को combine करता है: + +- `docker`: Docker containers को enable करें +- `test`: Test dataset और parameters का उपयोग करें + +Profiles बाएं से दाएं applied होते हैं, इसलिए बाद के profiles पहले वाले को override करते हैं यदि वे समान values set करते हैं। + +### निष्कर्ष + +nf-core pipelines containers, testing, और विशेष environments के लिए built-in profiles के साथ आते हैं। +आप अपनी आवश्यकता के अनुसार configuration बनाने के लिए कई profiles को combine कर सकते हैं। + +### आगे क्या है? + +विभिन्न computing environments के लिए अपने custom profiles बनाना सीखें। + +--- + +## 3. Custom profiles बनाना + +### 3.1. Local development और HPC पर execution के बीच switching के लिए profiles बनाएं + +आइए दो scenarios के लिए custom profiles बनाएं: + +1. Docker के साथ local development +2. Slurm scheduler और Singularity के साथ University HPC + +अपने `nextflow.config` में निम्नलिखित जोड़ें: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +अब आप environments के बीच आसानी से switch कर सकते हैं: + +```bash +# Local development के लिए +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# HPC के लिए (जब उपलब्ध हो) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "नोट" + + हम इस training environment में HPC profile का test नहीं कर सकते क्योंकि हमारे पास Slurm scheduler तक पहुंच नहीं है। + लेकिन यह दिखाता है कि आप वास्तविक उपयोग के लिए इसे कैसे configure करेंगे। + +### 3.2. Configuration को inspect करने के लिए `nextflow config` का उपयोग करें + +`nextflow config` कमांड pipeline को चलाए बिना पूरी तरह से resolved configuration दिखाता है। + +Default configuration देखें: + +```bash +nextflow config ./molkart +``` + +किसी विशिष्ट profile के साथ configuration देखें: + +```bash +nextflow config -profile local_dev ./molkart +``` + +यह निम्नलिखित के लिए अत्यंत उपयोगी है: + +- Configuration issues को debug करना +- समझना कि वास्तव में कौन सी values का उपयोग किया जाएगा +- जांचना कि कई profiles कैसे interact करते हैं + +### निष्कर्ष + +Custom profiles आपको एक single command-line flag के साथ विभिन्न computing environments के बीच switch करने देते हैं। +चलाने से पहले resolved configuration को inspect करने के लिए `nextflow config` का उपयोग करें। + +### आगे क्या है? + +nf-core की process label system का उपयोग करके व्यक्तिगत processes के लिए resource requests को customize करना सीखें। + +--- + +## 4. Resource requests को customize करना + +### 4.1. nf-core pipelines में process labels को समझना + +सरलता के लिए, nf-core pipelines सभी pipelines में resource allocation को standardize करने के लिए [**process labels**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) का उपयोग करते हैं। +प्रत्येक process को low, medium, या high compute resource आवश्यकताओं का वर्णन करने के लिए `process_low`, `process_medium`, या `process_high` जैसे label के साथ tag किया जाता है। +ये labels pipeline की `conf/` directory में स्थित configuration files में से एक में विशिष्ट resource requests में परिवर्तित हो जाते हैं। + +```groovy title="molkart/conf/base.config (excerpt)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +`task.attempt` multiplier पर ध्यान दें - यह subsequent task retries को अधिक resources request करने की अनुमति देता है, यदि pipeline `process.maxRetries > 1` के साथ set है। + +### 4.2. विशिष्ट processes के लिए resources को override करना + +fine-grained नियंत्रण के लिए, व्यक्तिगत processes को नाम से target करें: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +यदि हम उपरोक्त override के साथ इस pipeline को चलाने का प्रयास करें, तो `CELLPOSE` process अपने label द्वारा परिभाषित default के बजाय 16 CPUs और 32 GB memory का request करेगा। +यह हमारे वर्तमान environment में pipeline को fail कर देगा क्योंकि हमारे पास इतना RAM उपलब्ध नहीं है। +हम अगले section में इस प्रकार की failures को रोकने का तरीका सीखेंगे। + +!!! tip "सुझाव" + + Process names खोजने के लिए, pipeline execution output देखें या `.nextflow.log` की जांच करें। + Process names `WORKFLOW:SUBWORKFLOW:PROCESS` pattern का पालन करते हैं। + +### निष्कर्ष + +nf-core pipelines resource allocation को standardize करने के लिए process labels का उपयोग करते हैं। +आप label के द्वारा (कई processes को प्रभावित करता है) या नाम से (एक विशिष्ट process को प्रभावित करता है) resources को override कर सकते हैं। + +### आगे क्या है? + +GitHub Codespaces जैसे सीमित environments में resource limits को मैनेज करना सीखें। + +--- + +## 5. सीमित environments में resources को मैनेज करना + +### 5.1. Resource limits की समस्या + +यदि हमने 16 CPUs और 32 GB memory का request करने वाली process के साथ molkart को चलाने का प्रयास किया (जैसा कि section 4.2 में दिखाया गया है), तो यह हमारे वर्तमान environment में fail हो जाएगा क्योंकि हमारे पास इतने resources उपलब्ध नहीं हैं। +बड़े nodes के साथ cluster environment में, ऐसे requests scheduler को submit किए जाएंगे। + +GitHub Codespaces जैसे सीमित environments में, limits के बिना, Nextflow उन processes को चलाने से इनकार कर देगा जो उपलब्ध resources से अधिक हैं। + +### 5.2. Resource limits सेट करना + +`resourceLimits` निर्देश निर्दिष्ट values पर resource requests को cap करता है: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +यह Nextflow को बताता है: "यदि कोई process 2 CPUs या 7 GB memory से अधिक का request करता है, तो इसे इन limits पर cap करें।" + +### 5.3. Custom profiles में resource limits जोड़ना + +उपयुक्त limits शामिल करने के लिए अपने custom profiles को update करें: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "चेतावनी" + + Resource limits को बहुत कम सेट करने से processes fail हो सकते हैं या धीरे चल सकते हैं। + Pipeline को कम memory-intensive algorithms का उपयोग करने या छोटे chunks में data को process करने की आवश्यकता हो सकती है। + +### निष्कर्ष + +Process resource requests को cap करके resource-constrained environments में pipelines चलाने के लिए `resourceLimits` का उपयोग करें। +विभिन्न profiles में उनके environment के लिए उपयुक्त अलग-अलग limits हो सकते हैं। + +### आगे क्या है? + +आपने core Nextflow for Bioimaging training पूरा कर लिया है! + +--- + +## निष्कर्ष + +अब आप समझते हैं कि विभिन्न computing environments के लिए Nextflow pipelines को कैसे configure करें। + +आपने जो मुख्य कौशल सीखे हैं: + +- **Configuration precedence**: Nextflow कई स्रोतों से settings को कैसे resolve करता है +- **nf-core profiles**: Containers, testing, और utilities के लिए built-in profiles का उपयोग करना +- **Custom profiles**: विभिन्न environments के लिए अपने profiles बनाना +- **Process labels**: Label के द्वारा resource requests को समझना और override करना +- **Resource limits**: `resourceLimits` के साथ सीमित environments को मैनेज करना +- **Configuration inspection**: Settings को debug और verify करने के लिए `nextflow config` का उपयोग करना + +ये configuration skills किसी भी Nextflow pipeline में transferable हैं और local machines, HPC clusters, और cloud platforms पर workflows को efficiently चलाने में आपकी मदद करेंगी। + +### आगे क्या है? + +Nextflow for Bioimaging course पूरा करने के लिए बधाई! + +अगले कदम: + +- Feedback प्रदान करने के लिए course survey भरें +- Workflows develop करने के बारे में अधिक जानने के लिए [Hello Nextflow](../hello_nextflow/index.md) देखें +- nf-core tooling में गहराई से जाने के लिए [Hello nf-core](../hello_nf-core/index.md) explore करें +- [Training collections](../training_collections/index.md) में अन्य courses देखें diff --git a/docs/hi/docs/nf4_science/imaging/index.md b/docs/hi/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..92dd1cbda9 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/index.md @@ -0,0 +1,40 @@ +```markdown +--- +title: इमेजिंग के लिए Nextflow run +hide: + - toc +--- + +# इमेजिंग के लिए Nextflow run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह प्रशिक्षण पाठ्यक्रम इमेजिंग और स्थानिक जीवविज्ञान के शोधकर्ताओं के लिए है जो डेटा विश्लेषण pipelines को चलाने और अनुकूलित करने में रुचि रखते हैं। +यह [nf-core/molkart](https://nf-co.re/molkart) का उपयोग करके workflows को चलाने, व्यवस्थित करने और कॉन्फ़िगर करने से संबंधित बुनियादी Nextflow अवधारणाएँ सिखाता है, जो Molecular Cartography स्थानिक transcriptomics डेटा को प्रोसेस करने के लिए एक pipeline है। +यहाँ आप जो कौशल सीखते हैं वे किसी भी Nextflow या nf-core pipeline में लागू होते हैं। + +चलिए शुरू करते हैं! प्रशिक्षण वातावरण लॉन्च करने के लिए नीचे दिए गए "Open in GitHub Codespaces" बटन पर क्लिक करें (अधिमानतः एक अलग टैब में), फिर जब यह लोड हो रहा हो तो आगे पढ़ें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## सीखने के उद्देश्य + +इस पाठ्यक्रम के माध्यम से काम करके, आप सीखेंगे कि इमेजिंग विश्लेषण pipelines को चलाने के लिए बुनियादी Nextflow अवधारणाओं और टूलिंग को कैसे लागू किया जाए। + +इस कार्यशाला के अंत तक आप सक्षम होंगे: + +- Nextflow workflow को स्थानीय रूप से लॉन्च करना और निष्पादन की निगरानी करना +- Nextflow द्वारा उत्पन्न outputs (परिणाम) और log फ़ाइलों को ढूंढना और समझना +- test डेटा और custom inputs के साथ nf-core pipeline चलाना +- profiles और parameter फ़ाइलों का उपयोग करके pipeline निष्पादन को कॉन्फ़िगर करना +- samplesheets और command-line parameters का उपयोग करके inputs को प्रबंधित करना + +## दर्शक और पूर्वापेक्षाएँ + +यह पाठ्यक्रम निम्नलिखित से कुछ न्यूनतम परिचितता मानता है: + +- command line के साथ अनुभव +- इमेजिंग फ़ाइल formats (TIFF images, tabular data) से बुनियादी परिचितता + +तकनीकी आवश्यकताओं और वातावरण सेटअप के लिए, [Environment Setup](../../envsetup/) मिनी-पाठ्यक्रम देखें। +``` diff --git a/docs/hi/docs/nf4_science/imaging/next_steps.md b/docs/hi/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..68603218eb --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# अगले कदम + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging प्रशिक्षण पूरा करने के लिए बधाई! + +अब आपके पास इमेजिंग डेटा विश्लेषण के लिए Nextflow pipelines को चलाने और कॉन्फ़िगर करने के बुनियादी कौशल हैं। + +## सीखना जारी रखें + +अपने Nextflow ज्ञान को गहरा करने के लिए यहाँ कुछ अनुशंसित अगले कदम हैं: + +### अधिक nf-core pipelines का अन्वेषण करें + +- **सभी pipelines ब्राउज़ करें**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### अपने खुद के pipelines विकसित करें + +यदि आप Nextflow pipelines लिखना सीखना चाहते हैं: + +- **[Hello Nextflow](../../hello_nextflow/)**: व्यापक Nextflow विकास प्रशिक्षण +- **[Side Quests](../../side_quests/)**: pipeline डेवलपर्स के लिए उन्नत विषय + +### समुदाय से जुड़ें + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: सहायता प्राप्त करें और अन्य उपयोगकर्ताओं से जुड़ें +- **[nf-core Slack](https://nf-co.re/join)**: nf-core समुदाय में शामिल हों +- **[Seqera Community Forum](https://community.seqera.io)**: प्रश्न पूछें और अनुभव साझा करें + +### अतिरिक्त संसाधन + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: पूर्ण संदर्भ दस्तावेज़ीकरण +- **[nf-core Documentation](https://nf-co.re/docs)**: दिशानिर्देश और सर्वोत्तम प्रथाएं + +## शामिल हों + +- **nf-core में योगदान करें**: pipelines या दस्तावेज़ीकरण को बेहतर बनाने में मदद करें +- **अपने workflows साझा करें**: समुदाय के लिए अपने खुद के pipelines का योगदान करें +- **इवेंट्स में भाग लें**: Nextflow Summit और समुदाय प्रशिक्षण सत्रों में शामिल हों + +हमारे साथ सीखने के लिए धन्यवाद! diff --git a/docs/hi/docs/nf4_science/imaging/survey.md b/docs/hi/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..7869d2de66 --- /dev/null +++ b/docs/hi/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# सर्वेक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging प्रशिक्षण पूरा करने के लिए धन्यवाद! + +हम इस प्रशिक्षण सामग्री को बेहतर बनाने में मदद के लिए आपकी प्रतिक्रिया की बहुत सराहना करेंगे। + +कृपया हमारे संक्षिप्त सर्वेक्षण को पूरा करने के लिए कुछ मिनट निकालें: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +आपकी प्रतिक्रियाएं हमें यह समझने में मदद करेंगी कि क्या अच्छा रहा और भविष्य के शिक्षार्थियों के लिए हम क्या सुधार कर सकते हैं। + +आपके समय और भागीदारी के लिए धन्यवाद! diff --git a/docs/hi/docs/nf4_science/index.md b/docs/hi/docs/nf4_science/index.md new file mode 100644 index 0000000000..8e9edbe794 --- /dev/null +++ b/docs/hi/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: विज्ञान के लिए Nextflow +hide: + - toc +--- + +# विज्ञान के लिए Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +ये पाठ्यक्रम दर्शाते हैं कि [Hello Nextflow](../hello_nextflow/) शुरुआती पाठ्यक्रम में प्रस्तुत अवधारणाओं और घटकों को विशिष्ट वैज्ञानिक उपयोग के मामलों में कैसे लागू करें। प्रत्येक पाठ्यक्रम में प्रशिक्षण मॉड्यूल की एक श्रृंखला शामिल है जो शिक्षार्थियों को क्रमिक रूप से अपने कौशल विकसित करने में मदद करने के लिए डिज़ाइन की गई है। + +!!! exercise "जीनोमिक्स के लिए Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow में जीनोमिक्स के लिए pipeline विकसित करना सीखें। + + यह पाठ्यक्रम उन शोधकर्ताओं के लिए है जो अपनी जीनोमिक्स pipelines विकसित करना सीखना चाहते हैं। पाठ्यक्रम एक सरल लेकिन कार्यात्मक जीनोमिक्स pipeline विकसित करने का तरीका प्रदर्शित करने के लिए variant calling उपयोग के मामले का उपयोग करता है। + + [Nextflow for Genomics प्रशिक्षण शुरू करें :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "RNAseq के लिए Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow में RNAseq डेटा प्रोसेसिंग के लिए pipeline विकसित करना सीखें। + + यह पाठ्यक्रम उन शोधकर्ताओं के लिए है जो अपनी RNAseq pipelines विकसित करना सीखना चाहते हैं। पाठ्यक्रम एक सरल लेकिन कार्यात्मक RNAseq pipeline विकसित करने का तरीका प्रदर्शित करने के लिए bulk RNAseq प्रोसेसिंग उपयोग के मामले का उपयोग करता है। + + [Nextflow for RNAseq प्रशिक्षण शुरू करें :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "बायोइमेजिंग के लिए Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow में इमेजिंग डेटा के लिए pipelines चलाना सीखें। + + यह पाठ्यक्रम उन शोधकर्ताओं के लिए है जो बायोइमेजिंग pipelines को चलाना और कॉन्फ़िगर करना सीखना चाहते हैं। पाठ्यक्रम किसी भी pipeline पर लागू होने वाले आवश्यक Nextflow उपयोग पैटर्न को प्रदर्शित करने के लिए nf-core/molkart का उपयोग करता है। + + [Nextflow for Bioimaging प्रशिक्षण शुरू करें :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +हमें बताएं कि आप यहां किन अन्य डोमेन और उपयोग के मामलों को कवर करना चाहेंगे, community forum के [Training अनुभाग](https://community.seqera.io/c/training/) में पोस्ट करके। diff --git a/docs/hi/docs/nf4_science/rnaseq/00_orientation.md b/docs/hi/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..84ca4b683d --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# परिचय + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +प्रशिक्षण वातावरण में इस प्रशिक्षण कोर्स को पूरा करने के लिए आवश्यक सभी सॉफ़्टवेयर, कोड और डेटा शामिल हैं, इसलिए आपको स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। +हालांकि, लॉग इन करने के लिए आपको एक (मुफ़्त) खाता चाहिए, और आपको इंटरफ़ेस से परिचित होने के लिए कुछ मिनट लेने चाहिए। + +यदि आपने अभी तक ऐसा नहीं किया है, तो कृपया आगे बढ़ने से पहले [वातावरण सेटअप](../../envsetup/) मिनी-कोर्स देखें। + +## उपलब्ध सामग्री + +इस प्रशिक्षण कोर्स के दौरान, हम `nf4-science/rnaseq/` डायरेक्टरी में काम करेंगे, जिसमें आपको प्रशिक्षण workspace खोलने पर जाना होगा। +इस डायरेक्टरी में सभी कोड फ़ाइलें, टेस्ट डेटा और सहायक फ़ाइलें शामिल हैं जिनकी आपको आवश्यकता होगी। + +इस डायरेक्टरी की सामग्री को एक्सप्लोर करने के लिए स्वतंत्र महसूस करें; ऐसा करने का सबसे आसान तरीका VSCode इंटरफ़ेस में प्रशिक्षण workspace के बाईं ओर फ़ाइल एक्सप्लोरर का उपयोग करना है। +वैकल्पिक रूप से, आप `tree` कमांड का उपयोग कर सकते हैं। +पूरे कोर्स में, हम डायरेक्टरी संरचना और सामग्री को पठनीय रूप में प्रस्तुत करने के लिए `tree` के आउटपुट का उपयोग करते हैं, कभी-कभी स्पष्टता के लिए मामूली संशोधनों के साथ। + +यहां हम दूसरे स्तर तक सामग्री की तालिका बनाते हैं: + +```bash +tree . -L 3 +``` + +??? success "डायरेक्टरी सामग्री" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + चिंता न करें अगर यह बहुत कुछ लगता है; हम कोर्स के प्रत्येक चरण में प्रासंगिक हिस्सों को देखेंगे। + यह केवल आपको एक सामान्य अवलोकन देने के लिए है। + +**शुरुआत करने के लिए आपको यह जानना चाहिए:** + +- **`rnaseq.nf` फ़ाइल** workflow स्क्रिप्ट की रूपरेखा है जिसे हम विकसित करने के लिए काम करेंगे। + +- **फ़ाइल `nextflow.config`** एक कॉन्फ़िगरेशन फ़ाइल है जो न्यूनतम वातावरण गुण सेट करती है। आप इसे अभी के लिए अनदेखा कर सकते हैं। + +- **`data` डायरेक्टरी** में इनपुट डेटा और संबंधित संसाधन शामिल हैं: + + - _एक संदर्भ जीनोम_ जिसे `genome.fa` कहा जाता है, जिसमें मानव क्रोमोसोम 20 (hg19/b37 से) का एक छोटा क्षेत्र शामिल है। + - _RNAseq डेटा_ जिसे फ़ाइल आकार कम रखने के लिए एक छोटे क्षेत्र में विभाजित किया गया है, `reads/` डायरेक्टरी में। + - _CSV फ़ाइलें_ जो बैच प्रोसेसिंग के लिए उदाहरण डेटा फ़ाइलों की ID और पथ को सूचीबद्ध करती हैं। + +- **`solutions` डायरेक्टरी** में कोर्स के प्रत्येक चरण से प्राप्त पूर्ण workflow स्क्रिप्ट और modules शामिल हैं। + वे आपके काम की जांच करने और किसी भी समस्या का निवारण करने के लिए संदर्भ के रूप में उपयोग किए जाने के लिए हैं। + फ़ाइल नाम में संख्या कोर्स के संबंधित भाग के चरण से मेल खाती है। + +!!!tip + + यदि किसी कारण से आप इस डायरेक्टरी से बाहर चले जाते हैं, तो आप इसमें वापस लौटने के लिए हमेशा यह कमांड चला सकते हैं: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +अब, कोर्स शुरू करने के लिए, इस पृष्ठ के निचले दाएं कोने में तीर पर क्लिक करें। diff --git a/docs/hi/docs/nf4_science/rnaseq/01_method.md b/docs/hi/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..3d171651db --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# भाग 1: विधि का अवलोकन और मैनुअल परीक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +बल्क RNAseq डेटा को प्रोसेस और विश्लेषण करने के लिए कई वैध विधियाँ हैं। +इस कोर्स के लिए, हम [Babraham Institute](https://www.babraham.ac.uk/) में डॉ. साइमन एंड्रूज और लौरा बिगिंस द्वारा [यहाँ](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) वर्णित विधि का अनुसरण कर रहे हैं। + +हमारा लक्ष्य एक workflow विकसित करना है जो निम्नलिखित प्रोसेसिंग चरणों को लागू करता है: बल्क RNAseq नमूने में reads पर प्रारंभिक गुणवत्ता नियंत्रण चलाना, reads से adapter अनुक्रम ट्रिम करना, reads को reference genome के साथ संरेखित करना, और एक व्यापक गुणवत्ता नियंत्रण (QC) रिपोर्ट तैयार करना। + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** ट्रिमिंग से पहले FastQC का उपयोग करके read डेटा पर QC करें +- **TRIM_GALORE:** Trim Galore (Cutadapt और FastQC को बंडल करता है) का उपयोग करके adapter अनुक्रम ट्रिम करें और ट्रिमिंग के बाद QC करें +- **HISAT2_ALIGN:** Hisat2 का उपयोग करके reads को reference genome के साथ संरेखित करें +- **MULTIQC:** MultiQC का उपयोग करके एक व्यापक QC रिपोर्ट तैयार करें + +हालांकि, इससे पहले कि हम कोई भी workflow कोड लिखना शुरू करें, हम कुछ टेस्ट डेटा पर commands को मैनुअल रूप से आज़माने जा रहे हैं। +हमें जिन tools की आवश्यकता है वे GitHub Codespaces वातावरण में इंस्टॉल नहीं हैं, इसलिए हम उन्हें containers के माध्यम से उपयोग करेंगे ([Hello Containers](../../hello_nextflow/05_hello_containers.md) देखें)। + +!!! note "नोट" + + सुनिश्चित करें कि आप `nf4-science/rnaseq` डायरेक्टरी में हैं। जब आप `pwd` टाइप करते हैं तो दिखाए गए path का अंतिम भाग `rnaseq` होना चाहिए। + +--- + +## 1. प्रारंभिक QC और adapter ट्रिमिंग + +हम एक container image पुल करने जा रहे हैं जिसमें `fastqc` और `trim_galore` दोनों इंस्टॉल हैं, इसे इंटरैक्टिव रूप से स्पिन करेंगे और उदाहरण डेटा फ़ाइलों में से एक पर ट्रिमिंग और QC commands चलाएंगे। + +### 1.1. कंटेनर पुल करें + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +यह आपको निम्नलिखित console आउटपुट देता है क्योंकि सिस्टम image डाउनलोड करता है: + +??? success "कमांड आउटपुट" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "कमांड आउटपुट" + + ```console + + ``` +--> + +आपका prompt कुछ इस तरह `(base) root@b645838b3314:/tmp#` में बदल जाएगा, जो इंगित करता है कि आप अब कंटेनर के अंदर हैं। + +कमांड का `-v ./data:/data` भाग हमें कंटेनर के अंदर से `data/` डायरेक्टरी की सामग्री तक पहुँचने में सक्षम बनाएगा। + +```bash +ls /data/reads +``` + +??? success "कमांड आउटपुट" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. पहली `fastqc` कमांड चलाएं + +आइए read डेटा पर गुणवत्ता नियंत्रण मैट्रिक्स एकत्र करने के लिए `fastqc` चलाएं। + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "कमांड आउटपुट" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +यह बहुत जल्दी चलना चाहिए। +आप मूल डेटा के समान डायरेक्टरी में आउटपुट फ़ाइलें पा सकते हैं: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="आउटपुट" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. `trim_galore` के साथ adapter अनुक्रम ट्रिम करें + +अब आइए `trim_galore` चलाएं, जो Cutadapt और FastQC को बंडल करता है, adapter अनुक्रमों को ट्रिम करने और पोस्ट-ट्रिमिंग QC मैट्रिक्स एकत्र करने के लिए। + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +`--fastqc` flag कमांड को ट्रिमिंग पूर्ण होने के बाद स्वचालित रूप से एक QC संग्रह चरण चलाने का कारण बनता है। + +_आउटपुट बहुत verbose है इसलिए निम्नलिखित संक्षिप्त है।_ + +??? success "कमांड आउटपुट" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +आप working डायरेक्टरी में आउटपुट फ़ाइलें पा सकते हैं: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="आउटपुट" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. आउटपुट फ़ाइलों को कंटेनर के बाहर फाइलसिस्टम में ले जाएं + +कंटेनर के अंदर जो कुछ भी रहता है वह भविष्य के काम के लिए दुर्गम होगा इसलिए आइए इन्हें एक नई डायरेक्टरी में ले जाएं। + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. कंटेनर से बाहर निकलें + +```bash +exit +``` + +--- + +## 2. reads को reference genome के साथ संरेखित करें + +हम एक container image पुल करने जा रहे हैं जिसमें `hisat2` इंस्टॉल है, इसे इंटरैक्टिव रूप से स्पिन करेंगे और RNAseq डेटा को reference genome के साथ संरेखित करने के लिए संरेखण कमांड चलाएंगे। + +### 2.1. `hisat2` कंटेनर पुल करें + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "कमांड आउटपुट" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. `hisat2` कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +कमांड पहले के समान है, संबंधित container URI को स्वैप कर दिया गया है। + +### 2.3. Hisat2 genome index फ़ाइलें बनाएं + +Hisat2 को genome संदर्भ को बहुत विशिष्ट प्रारूप में प्रदान किए जाने की आवश्यकता होती है, और यह सिर्फ हमारे द्वारा प्रदान की गई `genome.fa` FASTA फ़ाइल का उपभोग नहीं कर सकता है, इसलिए हम प्रासंगिक संसाधन बनाने के लिए इस अवसर का लाभ उठाने जा रहे हैं। + +```bash +hisat2-build /data/genome.fa genome_index +``` + +आउटपुट बहुत verbose है इसलिए निम्नलिखित संक्षिप्त है: + +<!-- TODO: switch to full output --> + +??? success "कमांड आउटपुट" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +यह कई genome index फ़ाइलें बनाता है, जिन्हें आप working डायरेक्टरी में पा सकते हैं। + +```bash +ls genome_index.* +``` + +```console title="आउटपुट" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +हम इनका उपयोग एक क्षण में करेंगे, लेकिन पहले आइए इन genome index फ़ाइलों के साथ एक gzipped tarball बनाएं; हमें बाद में इनकी आवश्यकता होगी और इन्हें generate करना आम तौर पर कुछ ऐसा नहीं है जो हम workflow के हिस्से के रूप में करना चाहते हैं। + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +यह genome index फ़ाइलों वाला एक `genome_index.tar.gz` tarball हमारे फ़ाइल सिस्टम पर `data/` डायरेक्टरी में स्टोर करता है, जो इस कोर्स के भाग 2 में काम आएगा। + +### 2.4. `hisat2` कमांड चलाएं + +अब हम संरेखण कमांड चला सकते हैं, जो `hisat2` के साथ संरेखण चरण करता है फिर आउटपुट को BAM फ़ाइल के रूप में लिखने के लिए `samtools` को पाइप करता है। + +read डेटा इनपुट `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` फ़ाइल है जिसे हमने पिछले चरण में `trim_galore` के साथ उत्पन्न किया था। + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "कमांड आउटपुट" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +यह लगभग तुरंत चलता है क्योंकि यह एक बहुत छोटी टेस्ट फ़ाइल है। +वास्तविक स्केल पर यह बहुत अधिक समय ले सकता है। + +एक बार फिर आप working डायरेक्टरी में आउटपुट फ़ाइलें पा सकते हैं: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="आउटपुट" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. आउटपुट फ़ाइलों को कंटेनर के बाहर फाइलसिस्टम में ले जाएं + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. कंटेनर से बाहर निकलें + +```bash +exit +``` + +--- + +## 3. एक व्यापक QC रिपोर्ट तैयार करें + +हम एक container image पुल करने जा रहे हैं जिसमें `multiqc` इंस्टॉल है, इसे इंटरैक्टिव रूप से स्पिन करेंगे और before/after FastQC रिपोर्ट फ़ाइलों पर एक रिपोर्ट generation कमांड चलाएंगे। + +### 3.1. `multiqc` कंटेनर पुल करें + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "कमांड आउटपुट" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. `multiqc` कंटेनर को इंटरैक्टिव रूप से स्पिन करें + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. `multiqc` कमांड चलाएं + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "कमांड आउटपुट" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC संगत QC रिपोर्ट के लिए डायरेक्टरी में खोज करने में सक्षम है और जो कुछ भी मिलता है उसे एकत्र करेगा। + +यहाँ हम देखते हैं कि टूल ने हमारे द्वारा उत्पन्न तीनों QC रिपोर्ट पाईं: प्रारंभिक QC जो हमने `fastqc` के साथ की, पोस्ट-ट्रिमिंग रिपोर्ट `cutadapt` से (`trim_galore` के माध्यम से बनाई गई) और `hisat2` द्वारा उत्पादित पोस्ट-संरेखण QC। + +आउटपुट फ़ाइलें एक बार फिर working डायरेक्टरी में हैं: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="आउटपुट" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. आउटपुट फ़ाइलों को कंटेनर के बाहर फाइलसिस्टम में ले जाएं + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. कंटेनर से बाहर निकलें + +```bash +exit +``` + +--- + +### निष्कर्ष + +आपने संबंधित containers में सभी व्यक्तिगत commands को इंटरैक्टिव रूप से परीक्षण किया है। + +### आगे क्या है? + +सीखें कि उन्हीं commands को एक बहु-चरणीय workflow में कैसे लपेटा जाए जो काम को निष्पादित करने के लिए containers का उपयोग करता है। diff --git a/docs/hi/docs/nf4_science/rnaseq/02_single-sample.md b/docs/hi/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..28d7df2b41 --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# भाग 2: एकल-नमूना कार्यान्वयन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +कोर्स के इस भाग में, हम सबसे सरल संभव workflow लिखने जा रहे हैं जो भाग 1 में चलाए गए सभी commands को wrap करता है ताकि उन्हें चलाना automate हो सके, और हम एक बार में सिर्फ एक नमूना प्रोसेस करने का लक्ष्य रखेंगे। + +हम यह तीन चरणों में करेंगे: + +1. एक single-stage workflow लिखें जो शुरुआती QC step चलाता है +2. Adapter trimming और post-trimming QC जोड़ें +3. Reference genome के लिए alignment जोड़ें + +!!! warning "पूर्वापेक्षा" + + इस पाठ को शुरू करने से पहले आपको कोर्स के भाग 1 को पूरा करना होगा। + विशेष रूप से, sections 2.1-3 पर काम करने से genome index फ़ाइल (`data/genome_index.tar.gz`) बनती है जो इस पाठ में alignment step के लिए आवश्यक है। + +--- + +## 1. एक single-stage workflow लिखें जो शुरुआती QC चलाता है + +आइए एक सरल workflow लिखकर शुरू करें जो single-end RNAseq reads वाली FASTQ फ़ाइल पर FastQC tool चलाता है। + +हम आपको एक workflow फ़ाइल, `rnaseq.nf`, प्रदान करते हैं, जो workflow के मुख्य भागों की रूपरेखा देती है। + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Module INCLUDE statements + +/* + * Pipeline parameters + */ + +// प्राथमिक इनपुट + +workflow { + + // इनपुट channel बनाएं + + // Processes को call करें + +} +``` + +ध्यान रखें यह workflow code सही है लेकिन यह functional नहीं है; इसका उद्देश्य सिर्फ एक skeleton के रूप में काम करना है जिसका उपयोग आप वास्तविक workflow लिखने के लिए करेंगे। + +### 1.1. Modules स्टोर करने के लिए एक डायरेक्टरी बनाएं + +हम प्रत्येक process के लिए standalone modules बनाएंगे ताकि उन्हें manage करना और reuse करना आसान हो, तो चलिए उन्हें स्टोर करने के लिए एक डायरेक्टरी बनाते हैं। + +```bash +mkdir modules +``` + +### 1.2. QC metrics collection process के लिए एक मॉड्यूल बनाएं + +आइए `FASTQC` process को रखने के लिए `modules/fastqc.nf` नाम की एक मॉड्यूल फ़ाइल बनाएं: + +```bash +touch modules/fastqc.nf +``` + +फ़ाइल को code editor में खोलें और निम्नलिखित code को इसमें कॉपी करें: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +आपको इस training series के भाग 1 और भाग 2 में जो सीखा है उससे सभी टुकड़े पहचानने चाहिए; एकमात्र उल्लेखनीय बदलाव यह है कि इस बार हम `publishDir` directive के लिए `mode: symlink` का उपयोग कर रहे हैं, और हम `publishDir` को define करने के लिए एक पैरामीटर का उपयोग कर रहे हैं। + +!!! note + + भले ही हम यहां जो data फ़ाइलें उपयोग कर रहे हैं वे बहुत छोटी हैं, genomics में वे बहुत बड़ी हो सकती हैं। teaching वातावरण में प्रदर्शन के उद्देश्य से, हम अनावश्यक फ़ाइल copies से बचने के लिए 'symlink' publishing mode का उपयोग कर रहे हैं। आपको अपने final workflows में ऐसा नहीं करना चाहिए, क्योंकि जब आप अपनी `work` डायरेक्टरी को साफ करेंगे तो आप results खो देंगे। + +### 1.3. Workflow फ़ाइल में मॉड्यूल को import करें + +`rnaseq.nf` फ़ाइल में statement `include { FASTQC } from './modules/fastqc.nf'` जोड़ें: + +```groovy title="rnaseq.nf" linenums="3" +// Module INCLUDE statements +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. एक इनपुट declaration जोड़ें + +एक default value के साथ एक इनपुट पैरामीटर declare करें: + +```groovy title="rnaseq.nf" linenums="10" +params { + // प्राथमिक इनपुट + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Workflow block में एक इनपुट channel बनाएं + +इनपुट channel बनाने के लिए एक basic `.fromPath()` channel factory का उपयोग करें: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // एक फ़ाइल path से इनपुट channel बनाएं + read_ch = channel.fromPath(params.reads) + + // Processes को call करें + +} +``` + +### 1.6. इनपुट channel पर `FASTQC` process को call करें + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // एक फ़ाइल path से इनपुट channel बनाएं + read_ch = channel.fromPath(params.reads) + + // प्रारंभिक quality control + FASTQC(read_ch) + +} +``` + +### 1.7. Workflow को चलाएं यह जांचने के लिए कि यह काम करता है + +हम command line से इनपुट specify करने के लिए `--reads` पैरामीटर का उपयोग कर सकते हैं, लेकिन development के दौरान हम lazy हो सकते हैं और बस हमारे द्वारा set किए गए test default का उपयोग कर सकते हैं। + +```bash +nextflow run rnaseq.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +यह बहुत जल्दी चलना चाहिए अगर आपने भाग 1 पर काम किया है और पहले से ही कंटेनर को pull कर लिया है। +यदि आपने इसे छोड़ दिया है, तो Nextflow आपके लिए कंटेनर को pull करेगा; इसके होने के लिए आपको कुछ भी करने की आवश्यकता नहीं है, लेकिन आपको एक मिनट तक प्रतीक्षा करने की आवश्यकता हो सकती है। + +आप `FASTQC` process द्वारा `publishDir` directive द्वारा निर्दिष्ट के अनुसार `results/fastqc` के तहत आउटपुट पा सकते हैं। + +```bash +ls results/fastqc +``` + +```console title="आउटपुट" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Adapter trimming और post-trimming quality control जोड़ें + +हम Trim_Galore wrapper का उपयोग करने जा रहे हैं, जो trimming के लिए Cutadapt और post-trimming quality control के लिए FastQC को bundle करता है। + +### 2.1. Trimming और QC process के लिए एक मॉड्यूल बनाएं + +आइए `TRIM_GALORE` process को रखने के लिए `modules/trim_galore.nf` नाम की एक मॉड्यूल फ़ाइल बनाएं: + +```bash +touch modules/trim_galore.nf +``` + +फ़ाइल को code editor में खोलें और निम्नलिखित code को इसमें कॉपी करें: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Workflow फ़ाइल में मॉड्यूल को import करें + +`rnaseq.nf` फ़ाइल में statement `include { TRIM_GALORE } from './modules/trim_galore.nf'` जोड़ें: + +```groovy title="rnaseq.nf" linenums="3" +// Module INCLUDE statements +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. इनपुट channel पर process को call करें + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // एक फ़ाइल path से इनपुट channel बनाएं + read_ch = channel.fromPath(params.reads) + + // प्रारंभिक quality control + FASTQC(read_ch) + + // Adapter trimming और post-trimming QC + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Workflow को चलाएं यह जांचने के लिए कि यह काम करता है + +```bash +nextflow run rnaseq.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +यह भी बहुत जल्दी चलना चाहिए, क्योंकि हम इतनी छोटी इनपुट फ़ाइल पर चला रहे हैं। + +आप `TRIM_GALORE` process द्वारा `publishDir` directive द्वारा निर्दिष्ट के अनुसार `results/trimming` के तहत आउटपुट पा सकते हैं। + +```bash +ls results/trimming +``` + +```console title="आउटपुट" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Reads को reference genome से align करें + +अंत में हम Hisat2 का उपयोग करके genome alignment step चला सकते हैं, जो FastQC-style quality control metrics भी emit करेगा। + +### 3.1. HiSat2 process के लिए एक मॉड्यूल बनाएं + +आइए `HISAT2_ALIGN` process को रखने के लिए `modules/hisat2_align.nf` नाम की एक मॉड्यूल फ़ाइल बनाएं: + +```bash +touch modules/hisat2_align.nf +``` + +फ़ाइल को code editor में खोलें और निम्नलिखित code को इसमें कॉपी करें: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Workflow फ़ाइल में मॉड्यूल को import करें + +`rnaseq.nf` फ़ाइल में statement `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` जोड़ें: + +```groovy title="rnaseq.nf" linenums="3" +// Module INCLUDE statements +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Genome index प्रदान करने के लिए एक पैरामीटर declaration जोड़ें + +एक default value के साथ एक इनपुट पैरामीटर declare करें: + +```groovy title="rnaseq.nf" linenums="8" +params { + // प्राथमिक इनपुट + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Reference genome archive (संदर्भ जीनोम आर्काइव) + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. `TRIM_GALORE` द्वारा आउटपुट किए गए trimmed reads पर `HISAT2_ALIGN` process को call करें + +Trimmed reads पिछले step द्वारा आउटपुट किए गए `TRIM_GALORE.out.trimmed_reads` channel में हैं। + +इसके अलावा, हम Hisat2 tool को gzipped genome index tarball प्रदान करने के लिए `file (params.hisat2_index_zip)` का उपयोग करते हैं। + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // एक फ़ाइल path से इनपुट channel बनाएं + read_ch = channel.fromPath(params.reads) + + // प्रारंभिक quality control + FASTQC(read_ch) + + // Adapter trimming और post-trimming QC + TRIM_GALORE(read_ch) + + // Reference genome के साथ alignment + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Workflow को चलाएं यह जांचने के लिए कि यह काम करता है + +```bash +nextflow run rnaseq.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +आप `HISAT2_ALIGN` process द्वारा `publishDir` directive द्वारा निर्दिष्ट के अनुसार `results/align` के तहत आउटपुट पा सकते हैं। + +```bash +ls results/align +``` + +```console title="आउटपुट" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +यह प्रत्येक नमूने पर लागू करने के लिए आवश्यक basic processing को पूरा करता है। + +_हम भाग 2 में MultiQC report aggregation जोड़ेंगे, जब हम workflow को एक बार में कई नमूने स्वीकार करने योग्य बना लेंगे।_ + +--- + +### सारांश + +आप जानते हैं कि single-end RNAseq नमूनों को व्यक्तिगत रूप से प्रोसेस करने के लिए सभी मुख्य steps को कैसे wrap करें। + +### आगे क्या है? + +जानें कि कैसे workflow को कई नमूनों को parallel में प्रोसेस करने के लिए modify करें, सभी नमूनों के लिए सभी steps में QC reports को aggregate करें, और paired-end RNAseq data पर workflow चलाना enable करें। diff --git a/docs/hi/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/hi/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..385858ee34 --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# भाग 3: बहु-नमूना युग्मित-अंत कार्यान्वयन + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस पाठ्यक्रम के इस अंतिम भाग में, हम अपने सरल workflow को अगले स्तर पर ले जाने वाले हैं और इसे एक शक्तिशाली बैच ऑटोमेशन टूल में बदलने वाले हैं ताकि यह मनमाने संख्या के नमूनों को संभाल सके। +और जब हम यह कर रहे हैं, हम इसे युग्मित-अंत डेटा की अपेक्षा करने के लिए भी स्विच करने वाले हैं, जो नए अध्ययनों में अधिक सामान्य है। + +हम यह तीन चरणों में करेंगे: + +1. workflow को कई इनपुट नमूने स्वीकार करने योग्य बनाएं और निष्पादन को समानांतरित करें +2. व्यापक QC रिपोर्ट जनरेशन जोड़ें +3. युग्मित-अंत RNAseq डेटा पर स्विच करें + +--- + +## 1. workflow को कई इनपुट नमूने स्वीकार करने योग्य बनाएं और निष्पादन को समानांतरित करें + +हमें इनपुट को प्रबंधित करने के तरीके को बदलना होगा। + +### 1.1. प्राथमिक इनपुट को एकल फ़ाइल के बजाय फ़ाइल पथों के CSV में बदलें + +हम `data/` डायरेक्टरी में नमूना IDs और FASTQ फ़ाइल पथों वाली एक CSV फ़ाइल प्रदान करते हैं। +यह CSV फ़ाइल एक हेडर लाइन शामिल करती है। +ध्यान दें कि FASTQ फ़ाइल पथ पूर्ण पथ हैं। + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +आइए प्राथमिक इनपुट पैरामीटर का नाम बदलकर `input_csv` करें और डिफ़ॉल्ट को `single-end.csv` फ़ाइल के पथ में बदलें। + +```groovy title="rnaseq.nf" linenums="13" +params { + // प्राथमिक इनपुट + input_csv: Path = "data/single-end.csv" + + // संदर्भ जीनोम आर्काइव + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. इनपुट channel फ़ैक्टरी को CSV को इनपुट के रूप में संभालने के लिए अपडेट करें + +हम फ़ाइल के सामग्री को केवल फ़ाइल पथ के बजाय channel में लोड करना चाहते हैं, इसलिए हम CSV प्रारूप को पार्स करने के लिए `.splitCsv()` ऑपरेटर का उपयोग करते हैं, फिर जानकारी के विशिष्ट टुकड़े को पकड़ने के लिए `.map()` ऑपरेटर का उपयोग करते हैं (FASTQ फ़ाइल पथ)। + +```groovy title="rnaseq.nf" linenums="16" + // CSV फ़ाइल की सामग्री से इनपुट channel बनाएं + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. workflow को चलाएं और परीक्षण करें कि यह काम करता है + +```bash +nextflow run rnaseq.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +इस बार हम देखते हैं कि हर चरण 6 बार चलता है, हर उस 6 डेटा फ़ाइलों पर जो हमने प्रदान की थीं। + +बस इतना ही काफी था workflow को कई फ़ाइलों पर चलाने के लिए! +Nextflow हमारे लिए सभी समानांतरता को संभालता है। + +--- + +## 2. प्री-प्रोसेसिंग QC मेट्रिक्स को एकल MultiQC रिपोर्ट में एकत्रित करें + +यह सब बहुत सारी QC रिपोर्ट उत्पन्न करता है, और हम व्यक्तिगत रिपोर्टों को खोदना नहीं चाहते। +यह MultiQC रिपोर्ट एकत्रीकरण चरण लगाने के लिए एकदम सही बिंदु है! + +### 2.1. QC एकत्रीकरण process के लिए एक मॉड्यूल बनाएं + +आइए `MULTIQC` process को रखने के लिए `modules/multiqc.nf` नामक एक मॉड्यूल फ़ाइल बनाएं: + +```bash +touch modules/multiqc.nf +``` + +कोड एडिटर में फ़ाइल खोलें और निम्नलिखित कोड को इसमें कॉपी करें: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. मॉड्यूल को workflow फ़ाइल में आयात करें + +`rnaseq.nf` फ़ाइल में स्टेटमेंट `include { MULTIQC } from './modules/multiqc.nf'` जोड़ें: + +```groovy title="rnaseq.nf" linenums="3" +// मॉड्यूल INCLUDE स्टेटमेंट +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. एक `report_id` पैरामीटर जोड़ें और इसे एक उचित डिफ़ॉल्ट दें + +```groovy title="rnaseq.nf" linenums="9" +params { + // प्राथमिक इनपुट + input_csv: Path = "data/single-end.csv" + + // संदर्भ जीनोम आर्काइव + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // रिपोर्ट ID + report_id: String = "all_single-end" +} +``` + +### 2.4. पिछले चरणों के आउटपुट पर process को कॉल करें + +हमें `MULTIQC` process को पिछले चरणों से सभी QC-संबंधित आउटपुट देने की आवश्यकता है। + +इसके लिए, हम `.mix()` ऑपरेटर का उपयोग करने वाले हैं, जो कई channels को एक में एकत्रित करता है। + +यदि हमारे पास A, B, C और D नामक चार processes थे जिनमें प्रत्येक में एक सरल `.out` channel था, तो सिंटैक्स कुछ इस तरह दिखेगा: `A.out.mix( B.out, C.out, D.out )`। जैसा कि आप देख सकते हैं, आप इसे पहले channel पर लागू करते हैं जिसे आप संयोजित करना चाहते हैं (कोई फर्क नहीं पड़ता कि कौन सा) और बाकी सभी को, कॉमा से अलग करके, कोष्ठक में जोड़ते हैं। + +हमारे workflow के मामले में, हमारे पास एकत्रित करने के लिए निम्नलिखित आउटपुट हैं: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +तो सिंटैक्स उदाहरण बन जाता है: + +```groovy title="MULTIQC कॉल में .mix() लागू करना" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +यह प्रति नमूना QC रिपोर्ट एकत्र करेगा। +लेकिन चूंकि हम उन्हें सभी नमूनों में एकत्रित करना चाहते हैं, हमें सभी नमूनों के लिए रिपोर्ट को `MULTIQC` के एक कॉल में खींचने के लिए `collect()` ऑपरेटर जोड़ना होगा। +और हमें इसे `report_id` पैरामीटर भी देना होगा। + +यह हमें निम्नलिखित देता है: + +```groovy title="पूर्ण MULTIQC कॉल" linenums="33" + // व्यापक QC रिपोर्ट जनरेशन + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +पूर्ण workflow ब्लॉक के संदर्भ में, यह इस तरह दिखता है: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // CSV फ़ाइल की सामग्री से इनपुट channel बनाएं + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// प्रारंभिक गुणवत्ता नियंत्रण + FASTQC(read_ch) + + // एडॉप्टर ट्रिमिंग और पोस्ट-ट्रिमिंग QC + TRIM_GALORE(read_ch) + + // संदर्भ जीनोम के साथ संरेखण + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // व्यापक QC रिपोर्ट जनरेशन + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. workflow को चलाएं और परीक्षण करें कि यह काम करता है + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +इस बार हम कैश किए गए process कॉलों के बाद MULTIQC के लिए एक एकल कॉल देखते हैं: + +आप `TRIM_GALORE` process में `publishDir` निर्देश द्वारा निर्दिष्ट `results/trimming` के अंतर्गत आउटपुट पा सकते हैं। + +```bash +tree -L 2 results/multiqc +``` + +```console title="आउटपुट" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +वह अंतिम `all_single-end.html` फ़ाइल पूर्ण एकत्रित रिपोर्ट है, जो एक आसान ब्राउज़ करने योग्य HTML फ़ाइल में सुविधाजनक रूप से पैक की गई है। + +--- + +## 3. युग्मित-अंत RNAseq डेटा प्रोसेसिंग सक्षम करें + +अभी हमारा workflow केवल single-end RNAseq डेटा को संभाल सकता है। +युग्मित-अंत RNAseq डेटा देखना तेजी से सामान्य हो रहा है, इसलिए हम इसे संभालने में सक्षम होना चाहते हैं। + +workflow को डेटा प्रकार से पूरी तरह अज्ञेयवादी बनाने के लिए थोड़ा अधिक उन्नत Nextflow भाषा सुविधाओं का उपयोग करने की आवश्यकता होगी, इसलिए हम यहां ऐसा नहीं करने वाले हैं, लेकिन हम यह प्रदर्शित करने के लिए एक युग्मित-अंत प्रोसेसिंग संस्करण बना सकते हैं कि क्या अनुकूलित करने की आवश्यकता है। + +### 3.1. workflow की एक प्रति बनाएं जिसे `rnaseq_pe.nf` कहा जाता है + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. डिफ़ॉल्ट `input_csv` को युग्मित-अंत डेटा की ओर इंगित करने के लिए संशोधित करें + +हम `data/` डायरेक्टरी में नमूना IDs और युग्मित FASTQ फ़ाइल पथों वाली दूसरी CSV फ़ाइल प्रदान करते हैं + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +आइए `input_csv` डिफ़ॉल्ट को `paired-end.csv` फ़ाइल का पथ बनाएं। + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // प्राथमिक इनपुट + input_csv: Path = "data/paired-end.csv" + + // संदर्भ जीनोम आर्काइव + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // रिपोर्ट ID + report_id: String = "all_single-end" +} +``` + +### 3.3. channel फ़ैक्टरी को अपडेट करें + +हमें `.map()` ऑपरेटर को दोनों FASTQ फ़ाइल पथ अब पकड़ने के लिए बताना होगा। + +तो `row -> file(row.fastq_path)` बन जाता है `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // CSV फ़ाइल की सामग्री से इनपुट channel बनाएं + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. FASTQC process का एक युग्मित-अंत संस्करण बनाएं + +आइए मॉड्यूल की एक प्रति बनाएं ताकि हम दोनों संस्करणों को हाथ में रख सकें। + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +कोड एडिटर में नई `fastqc_pe.nf` मॉड्यूल फ़ाइल खोलें और निम्नलिखित कोड परिवर्तन करें: + +- `script` ब्लॉक (पंक्ति 17) में `fastqc $reads` को `fastqc ${reads}` में बदलें ताकि `reads` इनपुट अनपैक हो जाए, क्योंकि यह अब एकल पथ के बजाय दो पथों का एक टपल है। +- आउटपुट फ़ाइलों को व्यक्तिगत रूप से संभालने से बचने के लिए `${reads.simpleName}` को वाइल्डकार्ड (`*`) से बदलें। + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +तकनीकी रूप से यह `FASTQC` process को इस तरह से सामान्यीकृत करता है कि यह single-end या युग्मित-अंत RNAseq डेटा को संभालने में सक्षम हो जाता है। + +अंत में, मॉड्यूल के युग्मित-अंत संस्करण का उपयोग करने के लिए मॉड्यूल आयात स्टेटमेंट को अपडेट करें। + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. TRIM_GALORE process का एक युग्मित-अंत संस्करण बनाएं + +मॉड्यूल की एक प्रति बनाएं ताकि हम दोनों संस्करणों को हाथ में रख सकें। + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +कोड एडिटर में नई `trim_galore_pe.nf` मॉड्यूल फ़ाइल खोलें और निम्नलिखित कोड परिवर्तन करें: + +- इनपुट घोषणा को `path reads` से `tuple path(read1), path(read2)` में बदलें +- `script` ब्लॉक में कमांड को अपडेट करें, `$reads` को `--paired ${read1} ${read2}` से बदलें +- जोड़ी गई फ़ाइलों और विभिन्न नामकरण परंपराओं को प्रतिबिंबित करने के लिए आउटपुट घोषणाओं को अपडेट करें, सब कुछ सूचीबद्ध करने से बचने के लिए वाइल्डकार्ड का उपयोग करें। + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +अंत में, मॉड्यूल के युग्मित-अंत संस्करण का उपयोग करने के लिए मॉड्यूल आयात स्टेटमेंट को अपडेट करें। + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. MULTIQC process के कॉल को TRIM_GALORE से दो रिपोर्ट अपेक्षित करने के लिए अपडेट करें + +`TRIM_GALORE` process अब एक अतिरिक्त आउटपुट channel उत्पन्न करती है, इसलिए हमें इसे MultiQC को फीड करना होगा। + +`TRIM_GALORE.out.fastqc_reports,` को `TRIM_GALORE.out.fastqc_reports_1,` और `TRIM_GALORE.out.fastqc_reports_2,` से बदलें: + +```groovy title="rnaseq_pe.nf" linenums="33" + // व्यापक QC रिपोर्ट जनरेशन + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +जब हम MultiQC पर हैं, तो आइए `report_id` पैरामीटर डिफ़ॉल्ट को `"all_single-end"` से `"all_paired-end"` में भी अपडेट करें। + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // प्राथमिक इनपुट + input_csv: Path = "data/paired-end.csv" + + // संदर्भ जीनोम आर्काइव + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // रिपोर्ट ID + report_id: String = "all_paired-end" +} +``` + +### 3.7. HISAT2_ALIGN process का एक युग्मित-अंत संस्करण बनाएं + +मॉड्यूल की एक प्रति बनाएं ताकि हम दोनों संस्करणों को हाथ में रख सकें। + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +कोड एडिटर में नई `hisat2_align_pe.nf` मॉड्यूल फ़ाइल खोलें और निम्नलिखित कोड परिवर्तन करें: + +- इनपुट घोषणा को `path reads` से `tuple path(read1), path(read2)` में बदलें +- `script` ब्लॉक में कमांड को अपडेट करें, `-U $reads` को `-1 ${read1} -2 ${read2}` से बदलें +- `script` ब्लॉक में कमांड के साथ-साथ आउटपुट घोषणाओं में `${reads.simpleName}` के सभी उदाहरणों को `${read1.simpleName}` से बदलें। + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +अंत में, मॉड्यूल के युग्मित-अंत संस्करण का उपयोग करने के लिए मॉड्यूल आयात स्टेटमेंट को अपडेट करें। + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. workflow को चलाएं और परीक्षण करें कि यह काम करता है + +हम `-resume` का उपयोग नहीं करते क्योंकि यह कैश नहीं होगा, और पहले की तुलना में दोगुना डेटा प्रोसेस करना है, लेकिन फिर भी यह एक मिनट से कम में पूरा होना चाहिए। + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +और बस इतना ही! अब हमारे पास हमारे workflow के दो थोड़े भिन्न संस्करण हैं, एक single-end रीड डेटा के लिए और एक युग्मित-अंत डेटा के लिए। +अगला तार्किक कदम workflow को किसी भी डेटा प्रकार को तुरंत स्वीकार करने योग्य बनाना होगा, जो इस पाठ्यक्रम के दायरे से बाहर है, लेकिन हम इसे एक फॉलो-अप में संभाल सकते हैं। + +--- + +### मुख्य बातें + +आप जानते हैं कि एकल-नमूना workflow को कई नमूनों की प्रोसेसिंग को समानांतरित करने के लिए कैसे अनुकूलित करें, एक व्यापक QC रिपोर्ट उत्पन्न करें और यदि आवश्यक हो तो युग्मित-अंत रीड डेटा का उपयोग करने के लिए workflow को अनुकूलित करें। + +### आगे क्या है? + +बधाई हो, आपने Nextflow For RNAseq मिनी-पाठ्यक्रम पूरा कर लिया है! अपनी सफलता का जश्न मनाएं और एक अच्छा आराम लें! + +इसके बाद, हम आपसे इस प्रशिक्षण पाठ्यक्रम के साथ अपने अनुभव के बारे में एक बहुत छोटा सर्वेक्षण पूरा करने के लिए कहते हैं, फिर हम आपको आगे के प्रशिक्षण संसाधनों और सहायक लिंक के साथ एक पेज पर ले जाएंगे। diff --git a/docs/hi/docs/nf4_science/rnaseq/index.md b/docs/hi/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..665f6c5249 --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: RNAseq के लिए Nextflow +hide: + - toc +--- + +# RNAseq के लिए Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह प्रशिक्षण कोर्स ट्रांसक्रिप्टोमिक्स और संबंधित क्षेत्रों के शोधकर्ताओं के लिए है जो डेटा विश्लेषण पाइपलाइन विकसित करने या कस्टमाइज़ करने में रुचि रखते हैं। +यह [Hello Nextflow](../../hello_nextflow/) शुरुआती प्रशिक्षण पर आधारित है और दर्शाता है कि बल्क RNAseq विश्लेषण के विशिष्ट संदर्भ में Nextflow का उपयोग कैसे करें। + +विशेष रूप से, यह कोर्स दिखाता है कि एडॉप्टर अनुक्रमों को ट्रिम करने, रीड्स को जीनोम संदर्भ के साथ संरेखित करने और कई चरणों में गुणवत्ता नियंत्रण (QC) करने के लिए एक सरल बल्क RNAseq प्रोसेसिंग पाइपलाइन कैसे लागू करें। + +चलिए शुरू करते हैं! प्रशिक्षण वातावरण लॉन्च करने के लिए नीचे दिए गए "Open in GitHub Codespaces" बटन पर क्लिक करें (अधिमानतः एक अलग टैब में), फिर लोड होने के दौरान आगे पढ़ें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## सीखने के उद्देश्य + +इस कोर्स के माध्यम से काम करके, आप सीखेंगे कि एक विशिष्ट RNAseq उपयोग के मामले में बुनियादी Nextflow अवधारणाओं और टूलिंग को कैसे लागू करें। + +इस वर्कशॉप के अंत तक आप सक्षम होंगे: + +- बुनियादी RNAseq प्रोसेसिंग और QC विधियों को लागू करने के लिए एक रैखिक वर्कफ़्लो लिखना +- FASTQ जैसी डोमेन-विशिष्ट फ़ाइलों और जीनोम संदर्भ संसाधनों को उचित रूप से संभालना +- सिंगल-एंड और पेयर्ड-एंड सीक्वेंसिंग डेटा को संभालना +- प्रति-नमूना RNAseq प्रोसेसिंग को समानांतरित करने के लिए Nextflow के डेटाफ़्लो प्रतिमान का लाभ उठाना +- प्रासंगिक channel ऑपरेटरों का उपयोग करके कई चरणों और नमूनों में QC रिपोर्ट एकत्रित करना + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## पूर्वापेक्षाएँ + +कोर्स निम्नलिखित के साथ न्यूनतम परिचितता मानता है: + +- इस वैज्ञानिक डोमेन में आमतौर पर उपयोग किए जाने वाले टूल और फ़ाइल फॉर्मेट +- कमांड लाइन के साथ अनुभव +- [Hello Nextflow](../../hello_nextflow/) शुरुआती प्रशिक्षण में कवर की गई बुनियादी Nextflow अवधारणाएँ और टूलिंग + +तकनीकी आवश्यकताओं और वातावरण सेटअप के लिए, [Environment Setup](../../envsetup/) मिनी-कोर्स देखें। diff --git a/docs/hi/docs/nf4_science/rnaseq/next_steps.md b/docs/hi/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..641c787a1b --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# अगले कदम + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For RNAseq प्रशिक्षण कोर्स पूरा करने पर फिर से बधाई और हमारे सर्वेक्षण को पूरा करने के लिए धन्यवाद! + +--- + +## 1. अपने Nextflow कौशल को बढ़ाने के शीर्ष 3 तरीके + +आपके द्वारा अभी पूरा किए गए कोर्स के आधार पर आगे क्या करना है, इसके लिए यहां हमारी शीर्ष तीन सिफारिशें हैं। + +### 1.1. अन्य वैज्ञानिक विश्लेषण उपयोग मामलों में Nextflow लागू करें + +**[Nextflow for Science](../nf4_science/index.md) पेज देखें** अन्य छोटे स्टैंडअलोन कोर्स की सूची के लिए जो दिखाते हैं कि कैसे Hello Nextflow में प्रस्तुत बुनियादी अवधारणाओं और तंत्रों को सामान्य वैज्ञानिक विश्लेषण उपयोग मामलों में लागू किया जाए। + +यदि आपको अपने डोमेन को किसी संबंधित उपयोग मामले द्वारा प्रदर्शित नहीं दिखाई देता है, तो हमें [Community forum](https://community.seqera.io/) में बताएं ताकि हम इसे अपनी विकास सूची में जोड़ सकें। + +### 1.2. nf-core के साथ शुरुआत करें + +**[nf-core](https://nf-co.re/)** वैज्ञानिक अनुसंधान अनुप्रयोगों की एक विस्तृत श्रृंखला के लिए मानकीकृत ओपन-सोर्स pipelines विकसित करने का एक विश्वव्यापी सहयोगात्मक प्रयास है। +परियोजना में [100 से अधिक pipelines](https://nf-co.re/pipelines/) शामिल हैं जो तुरंत उपयोग के लिए उपलब्ध हैं और [1400 से अधिक process modules](https://nf-co.re/modules/) हैं जिन्हें आपके अपने प्रोजेक्ट्स में एकीकृत किया जा सकता है, साथ ही डेवलपर टूल्स का एक समृद्ध सेट। + +**[Hello nf-core](../../hello_nf-core/index.md)** प्रशिक्षण कोर्स आपको nf-core समुदाय-क्यूरेटेड pipelines और विकास framework से परिचित कराएगा, जो आपको पुनरुत्पादनीय, स्केलेबल और मानकीकृत workflows लिखने में मदद करने के लिए डिज़ाइन किया गया है। आप सीखेंगे कि मौजूदा nf-core pipelines का उपयोग कैसे करें, उनके विकास में योगदान कैसे करें, और यहां तक कि अपना खुद का निर्माण कैसे शुरू करें, जो सर्वोत्तम प्रथाओं और एक जीवंत समुदाय द्वारा समर्थित है। यदि आप वास्तविक दुनिया के प्रोजेक्ट्स में अपने Nextflow कौशल को लागू करने के लिए तैयार हैं, तो यह सही अगला कदम है। + +### 1.3. अधिक उन्नत Nextflow सुविधाओं में महारत हासिल करें + +Hello कोर्स में, हम तकनीकी जटिलता के स्तर को जानबूझकर कम रखते हैं ताकि आपको उस जानकारी से अधिभारित न किया जाए जिसकी आपको Nextflow के साथ शुरुआत करने के लिए आवश्यकता नहीं है। +जैसे-जैसे आप अपने काम के साथ आगे बढ़ते हैं, आप Nextflow की पूर्ण सुविधा सेट और शक्ति का उपयोग करना सीखना चाहेंगे। + +इस उद्देश्य के लिए, हम वर्तमान में **[Side Quests](../side_quests/index.md) के संग्रह** पर काम कर रहे हैं, जो छोटे स्टैंडअलोन कोर्स होने के लिए हैं जो परीक्षण और मेटाडेटा हैंडलिंग जैसे विशिष्ट विषयों में गहराई से जाते हैं। + +--- + +## 2. Seqera Platform देखें + +**[Seqera Platform](https://seqera.io/) व्यवहार में Nextflow चलाने का सबसे अच्छा तरीका है।** + +यह Nextflow के निर्माताओं द्वारा विकसित एक क्लाउड-आधारित प्लेटफ़ॉर्म है जिसे आप अपने स्वयं के कंप्यूट इंफ्रास्ट्रक्चर (चाहे लोकल, HPC या क्लाउड) से कनेक्ट कर सकते हैं ताकि अपने workflows को लॉन्च और प्रबंधित करना, साथ ही अपने डेटा को प्रबंधित करना और क्लाउड वातावरण में इंटरैक्टिव रूप से विश्लेषण चलाना बहुत आसान हो सके। + +Free Tier सभी के लिए निःशुल्क उपयोग के लिए उपलब्ध है (उपयोग कोटा के साथ)। +योग्य शिक्षाविद [Academic Program](https://seqera.io/academic/program/) के माध्यम से निःशुल्क Pro-स्तर की पहुंच (कोई उपयोग सीमा नहीं) प्राप्त कर सकते हैं। + +यह देखने के लिए कि क्या यह आपके लिए उपयोगी हो सकता है, [Seqera Platform tutorials](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) पर एक नज़र डालें। + +--- + +### अभी के लिए बस इतना ही! + +**अपनी Nextflow यात्रा में शुभकामनाएं और [Community forum](https://community.seqera.io/) में हमें बताने में संकोच न करें कि हम आपकी मदद के लिए और क्या कर सकते हैं।** diff --git a/docs/hi/docs/nf4_science/rnaseq/survey.md b/docs/hi/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..996d83f0af --- /dev/null +++ b/docs/hi/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# फीडबैक सर्वेक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आगे बढ़ने से पहले, कृपया इस छोटे 5-प्रश्नों के सर्वेक्षण को पूरा करें ताकि आप प्रशिक्षण को रेट कर सकें, अपने अनुभव के बारे में कोई फीडबैक साझा कर सकें, और हमें बता सकें कि हम आपकी Nextflow यात्रा में आपकी मदद के लिए और क्या कर सकते हैं। + +इसे पूरा करने में आपको एक मिनट से भी कम समय लगेगा। हर किसी के लिए हमारी प्रशिक्षण सामग्री को बेहतर बनाने में मदद करने के लिए धन्यवाद! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/hi/docs/side_quests/README.md b/docs/hi/docs/side_quests/README.md new file mode 100644 index 0000000000..9995e825c9 --- /dev/null +++ b/docs/hi/docs/side_quests/README.md @@ -0,0 +1 @@ +यह भविष्य के साइड क्वेस्ट (गहन प्रशिक्षण) के लिए एक प्लेसहोल्डर है। वर्तमान में यहाँ जो दस्तावेज़ हैं वे अन्य स्रोतों से पुनर्चक्रित सामग्री पर आधारित स्टब हैं। diff --git a/docs/hi/docs/side_quests/debugging.md b/docs/hi/docs/side_quests/debugging.md new file mode 100644 index 0000000000..c05d63c144 --- /dev/null +++ b/docs/hi/docs/side_quests/debugging.md @@ -0,0 +1,1185 @@ +# वर्कफ़्लो की डिबगिंग + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +डिबगिंग एक महत्वपूर्ण कौशल है जो आपको घंटों की निराशा से बचा सकता है और आपको एक अधिक प्रभावी Nextflow डेवलपर बनने में मदद कर सकता है। अपने करियर के दौरान, खासकर जब आप शुरुआत कर रहे हों, आपको अपने वर्कफ़्लो को बनाते और बनाए रखते समय बग्स का सामना करना पड़ेगा। व्यवस्थित डिबगिंग दृष्टिकोण सीखने से आपको समस्याओं की पहचान करने और उन्हें जल्दी हल करने में मदद मिलेगी। + +### सीखने के लक्ष्य + +इस साइड क्वेस्ट में, हम Nextflow वर्कफ़्लो के लिए **व्यवस्थित डिबगिंग तकनीकों** का अन्वेषण करेंगे: + +- **सिंटैक्स एरर डिबगिंग**: IDE फीचर्स और Nextflow एरर मैसेज का प्रभावी ढंग से उपयोग करना +- **Channel डिबगिंग**: डेटा फ़्लो समस्याओं और channel संरचना समस्याओं का निदान करना +- **Process डिबगिंग**: निष्पादन विफलताओं और संसाधन समस्याओं की जांच करना +- **बिल्ट-इन डिबगिंग टूल्स**: Nextflow के preview mode, stub running, और work directories का लाभ उठाना +- **व्यवस्थित दृष्टिकोण**: कुशल डिबगिंग के लिए चार-चरण पद्धति + +अंत तक, आपके पास एक मजबूत डिबगिंग पद्धति होगी जो निराशाजनक एरर मैसेज को समाधान के लिए स्पष्ट रोडमैप में बदल देती है। + +### पूर्वापेक्षाएँ + +इस साइड क्वेस्ट को शुरू करने से पहले, आपको: + +- [Hello Nextflow](../hello_nextflow/README.md) ट्यूटोरियल या समकक्ष शुरुआती पाठ्यक्रम पूरा किया होना चाहिए। +- बुनियादी Nextflow अवधारणाओं और तंत्र (processes, channels, operators) का उपयोग करने में सहज होना चाहिए + +**वैकल्पिक:** हम अनुशंसा करते हैं कि पहले [IDE Features for Nextflow Development](./ide_features.md) साइड क्वेस्ट को पूरा करें। +यह IDE फीचर्स की व्यापक कवरेज प्रदान करता है जो डिबगिंग का समर्थन करते हैं (सिंटैक्स हाइलाइटिंग, एरर डिटेक्शन, आदि), जिन्हें हम यहाँ भारी मात्रा में उपयोग करेंगे। + +--- + +## 0. शुरुआत करें + +#### प्रशिक्षण codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार प्रशिक्षण वातावरण खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएं + +आइए उस डायरेक्टरी में चलें जहाँ इस ट्यूटोरियल के लिए फ़ाइलें स्थित हैं। + +```bash +cd side-quests/debugging +``` + +आप VSCode को इस डायरेक्टरी पर फोकस करने के लिए सेट कर सकते हैं: + +```bash +code . +``` + +#### सामग्री की समीक्षा करें + +आपको विभिन्न प्रकार के बग्स के साथ उदाहरण वर्कफ़्लो का एक सेट मिलेगा जिन्हें हम अभ्यास के लिए उपयोग करेंगे: + +??? abstract "डायरेक्टरी सामग्री" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +ये फ़ाइलें सामान्य डिबगिंग परिदृश्यों का प्रतिनिधित्व करती हैं जिनका सामना आप वास्तविक दुनिया के विकास में करेंगे। + +#### असाइनमेंट की समीक्षा करें + +आपकी चुनौती प्रत्येक वर्कफ़्लो को चलाना, एरर(एरर्स) की पहचान करना और उन्हें ठीक करना है। + +प्रत्येक बगी वर्कफ़्लो के लिए: + +1. **वर्कफ़्लो चलाएं** और एरर का अवलोकन करें +2. **एरर मैसेज का विश्लेषण करें**: Nextflow आपको क्या बता रहा है? +3. **कोड में समस्या का पता लगाएं** प्रदान किए गए सुरागों का उपयोग करके +4. **बग को ठीक करें** और सत्यापित करें कि आपका समाधान काम करता है +5. अगले अनुभाग पर जाने से पहले **फ़ाइल को रीसेट करें** (`git checkout <filename>` का उपयोग करें) + +अभ्यास सरल सिंटैक्स एरर से अधिक सूक्ष्म रनटाइम समस्याओं तक प्रगति करते हैं। +समाधान इनलाइन चर्चा किए गए हैं, लेकिन आगे पढ़ने से पहले प्रत्येक को स्वयं हल करने का प्रयास करें। + +#### तैयारी चेकलिस्ट + +क्या आपको लगता है कि आप शुरू करने के लिए तैयार हैं? + +- [ ] मैं इस पाठ्यक्रम के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता हूं +- [ ] मेरा codespace चल रहा है +- [ ] मैंने अपनी वर्किंग डायरेक्टरी उचित रूप से सेट की है +- [ ] मैं असाइनमेंट को समझता हूं + +यदि आप सभी बॉक्स को चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. सिंटैक्स एरर + +सिंटैक्स एरर सबसे सामान्य प्रकार के एरर हैं जिनका सामना आप Nextflow कोड लिखते समय करेंगे। ये तब होते हैं जब कोड Nextflow DSL के अपेक्षित सिंटैक्स नियमों के अनुरूप नहीं होता है। ये एरर आपके वर्कफ़्लो को बिल्कुल चलने से रोकते हैं, इसलिए उन्हें जल्दी पहचानना और ठीक करना सीखना महत्वपूर्ण है। + +### 1.1. गुम ब्रेसिज़ + +सबसे सामान्य सिंटैक्स एरर में से एक, और कभी-कभी डिबग करने के लिए अधिक जटिल में से एक **गुम या बेमेल ब्रैकेट** है। + +आइए एक व्यावहारिक उदाहरण से शुरू करें। + +#### पाइपलाइन चलाएं + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**सिंटैक्स एरर मैसेज के मुख्य तत्व:** + +- **फ़ाइल और स्थान**: दिखाता है कि किस फ़ाइल और लाइन/कॉलम में एरर है (`bad_syntax.nf:24:1`) +- **एरर विवरण**: बताता है कि पार्सर को क्या मिला जो उसे उम्मीद नहीं थी (`Unexpected input: '<EOF>'`) +- **EOF संकेतक**: `<EOF>` (End Of File) मैसेज इंगित करता है कि पार्सर अभी भी अधिक सामग्री की अपेक्षा करते हुए फ़ाइल के अंत तक पहुंच गया - बंद न हुए ब्रेसिज़ का एक क्लासिक संकेत + +#### कोड की जांच करें + +अब, आइए `bad_syntax.nf` की जांच करें यह समझने के लिए कि एरर का कारण क्या है: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// process के लिए closing brace गुम है + +workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) +} +``` + +इस उदाहरण के उद्देश्य के लिए हमने आपको दिखाने के लिए एक टिप्पणी छोड़ी है कि एरर कहाँ है। Nextflow VSCode एक्सटेंशन को भी आपको कुछ संकेत देना चाहिए कि क्या गलत हो सकता है, बेमेल ब्रेस को लाल रंग में रखते हुए और फ़ाइल के समय से पहले अंत को हाइलाइट करते हुए: + +![Bad syntax](img/bad_syntax.png) + +**ब्रैकेट एरर के लिए डिबगिंग रणनीति:** + +1. VS Code की ब्रैकेट मैचिंग का उपयोग करें (कर्सर को ब्रैकेट के बगल में रखें) +2. ब्रैकेट-संबंधित मैसेज के लिए Problems पैनल की जांच करें +3. सुनिश्चित करें कि प्रत्येक opening `{` में एक संबंधित closing `}` है + +#### कोड को ठीक करें + +गुम closing brace के साथ टिप्पणी को बदलें: + +=== "बाद में" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // गुम closing brace जोड़ें + + workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) + } + ``` + +=== "पहले" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // process के लिए closing brace गुम है + + workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) + } + ``` + +#### पाइपलाइन चलाएं + +अब वर्कफ़्लो को फिर से चलाएं यह पुष्टि करने के लिए कि यह काम करता है: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. गलत process कीवर्ड या निर्देशों का उपयोग करना + +एक अन्य सामान्य सिंटैक्स एरर एक **अमान्य process परिभाषा** है। यह तब हो सकता है जब आप आवश्यक ब्लॉक परिभाषित करना भूल जाते हैं या process परिभाषा में गलत निर्देशों का उपयोग करते हैं। + +#### पाइपलाइन चलाएं + +```bash +nextflow run invalid_process.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### कोड की जांच करें + +एरर एक "Invalid process definition" को इंगित करता है और समस्या के आसपास संदर्भ दिखाता है। लाइन 3-7 को देखते हुए, हम लाइन 4 पर `inputs:` देख सकते हैं, जो समस्या है। आइए `invalid_process.nf` की जांच करें: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // एरर: 'inputs' नहीं, 'input' होना चाहिए + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) +} +``` + +एरर संदर्भ में लाइन 4 को देखते हुए, हम समस्या को देख सकते हैं: हम सही `input` निर्देश के बजाय `inputs` का उपयोग कर रहे हैं। Nextflow VSCode एक्सटेंशन भी इसे फ्लैग करेगा: + +![Invalid process message](img/invalid_process_message.png) + +#### कोड को ठीक करें + +[डॉक्यूमेंटेशन](https://www.nextflow.io/docs/latest/process.html#) का संदर्भ देकर गलत कीवर्ड को सही के साथ बदलें: + +=== "बाद में" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // ठीक किया: 'inputs' को 'input' में बदला + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) + } + ``` + +=== "पहले" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // एरर: 'inputs' नहीं, 'input' होना चाहिए + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // इनपुट channel बनाएं + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // इनपुट channel के साथ process को call करें + PROCESS_FILES(input_ch) + } + ``` + +#### पाइपलाइन चलाएं + +अब वर्कफ़्लो को फिर से चलाएं यह पुष्टि करने के लिए कि यह काम करता है: + +```bash +nextflow run invalid_process.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. खराब वेरिएबल नामों का उपयोग करना + +आपके स्क्रिप्ट ब्लॉक में उपयोग किए जाने वाले वेरिएबल नाम मान्य होने चाहिए, या तो इनपुट से या स्क्रिप्ट से पहले डाले गए groovy कोड से प्राप्त होने चाहिए। लेकिन जब आप पाइपलाइन विकास की शुरुआत में जटिलता से जूझ रहे हों, तो वेरिएबल नामकरण में गलतियां करना आसान है, और Nextflow आपको जल्दी से बता देगा। + +#### पाइपलाइन चलाएं + +```bash +nextflow run no_such_var.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +एरर को कंपाइल समय पर पकड़ा जाता है और सीधे लाइन 17 पर अपरिभाषित वेरिएबल की ओर इशारा करता है, जिसमें एक कैरेट समस्या कहाँ है यह बिल्कुल इंगित करता है। + +#### कोड की जांच करें + +आइए `no_such_var.nf` की जांच करें: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // एरर: undefined_var परिभाषित नहीं है + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +एरर मैसेज इंगित करता है कि वेरिएबल को स्क्रिप्ट टेम्पलेट में पहचाना नहीं गया है, और वहाँ आप जाते हैं- आपको स्क्रिप्ट ब्लॉक में उपयोग किया गया `${undefined_var}` देखने में सक्षम होना चाहिए, लेकिन कहीं और परिभाषित नहीं किया गया है। + +#### कोड को ठीक करें + +यदि आपको 'No such variable' एरर मिलती है, तो आप वेरिएबल को परिभाषित करके (इनपुट वेरिएबल नामों को सही करके या स्क्रिप्ट से पहले groovy कोड को संपादित करके), या यदि इसकी आवश्यकता नहीं है तो इसे स्क्रिप्ट ब्लॉक से हटाकर इसे ठीक कर सकते हैं: + +=== "बाद में" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // undefined_var वाली लाइन हटाई गई + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "पहले" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // एरर: undefined_var परिभाषित नहीं है + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### पाइपलाइन चलाएं + +अब वर्कफ़्लो को फिर से चलाएं यह पुष्टि करने के लिए कि यह काम करता है: + +```bash +nextflow run no_such_var.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Bash वेरिएबल का खराब उपयोग + +Nextflow में शुरुआत करते समय, Nextflow (Groovy) और Bash वेरिएबल के बीच अंतर को समझना मुश्किल हो सकता है। यह एक अन्य रूप की खराब वेरिएबल एरर उत्पन्न कर सकता है जो स्क्रिप्ट ब्लॉक की Bash सामग्री में वेरिएबल का उपयोग करने का प्रयास करते समय दिखाई देती है। + +#### पाइपलाइन चलाएं + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### कोड की जांच करें + +एरर लाइन 13 की ओर इशारा करता है जहाँ `${prefix}` का उपयोग किया गया है। आइए `bad_bash_var.nf` की जांच करें यह देखने के लिए कि समस्या का कारण क्या है: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +इस उदाहरण में, हम Bash में `prefix` वेरिएबल को परिभाषित कर रहे हैं, लेकिन एक Nextflow process में हमने इसे संदर्भित करने के लिए उपयोग किया गया `$` सिंटैक्स (`${prefix}`) को Groovy वेरिएबल के रूप में व्याख्या किया जाता है, न कि Bash। वेरिएबल Groovy संदर्भ में मौजूद नहीं है, इसलिए हमें 'no such variable' एरर मिलता है। + +#### कोड को ठीक करें + +यदि आप एक Bash वेरिएबल का उपयोग करना चाहते हैं, तो आपको डॉलर चिह्न को इस तरह एस्केप करना होगा: + +=== "बाद में" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "पहले" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +यह Nextflow को बताता है कि इसे Bash वेरिएबल के रूप में व्याख्या करें। + +#### पाइपलाइन चलाएं + +अब वर्कफ़्लो को फिर से चलाएं यह पुष्टि करने के लिए कि यह काम करता है: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Groovy बनाम Bash वेरिएबल" + + स्ट्रिंग संयोजन या prefix/suffix ऑपरेशन जैसे सरल वेरिएबल मैनिपुलेशन के लिए, स्क्रिप्ट ब्लॉक में Bash वेरिएबल के बजाय script सेक्शन में Groovy वेरिएबल का उपयोग करना आमतौर पर अधिक पठनीय होता है: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + यह दृष्टिकोण डॉलर चिह्न को एस्केप करने की आवश्यकता से बचता है और कोड को पढ़ने और बनाए रखने में आसान बनाता है। + +### 1.5. Workflow ब्लॉक के बाहर स्टेटमेंट + +Nextflow VSCode एक्सटेंशन कोड संरचना के साथ समस्याओं को हाइलाइट करता है जो एरर का कारण बनेंगे। एक सामान्य उदाहरण `workflow {}` ब्लॉक के बाहर channels को परिभाषित करना है - यह अब एक सिंटैक्स एरर के रूप में लागू किया गया है। + +#### पाइपलाइन चलाएं + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +एरर मैसेज स्पष्ट रूप से समस्या को इंगित करता है: स्टेटमेंट (जैसे channel परिभाषाएं) को workflow या process ब्लॉक के बाहर स्क्रिप्ट घोषणाओं के साथ मिश्रित नहीं किया जा सकता है। + +#### कोड की जांच करें + +आइए `badpractice_syntax.nf` की जांच करें यह देखने के लिए कि एरर का कारण क्या है: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // एरर: Channel workflow के बाहर परिभाषित है + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +VSCode एक्सटेंशन `input_ch` वेरिएबल को workflow ब्लॉक के बाहर परिभाषित होने के रूप में भी हाइलाइट करेगा: + +![Non-lethal syntax error](img/nonlethal.png) + +#### कोड को ठीक करें + +channel परिभाषा को workflow ब्लॉक के अंदर ले जाएं: + +=== "बाद में" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // workflow ब्लॉक के अंदर ले जाया गया + PROCESS_FILES(input_ch) + } + ``` + +=== "पहले" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr्bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // एरर: Channel workflow के बाहर परिभाषित है + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### पाइपलाइन चलाएं + +फिक्स काम करती है यह पुष्टि करने के लिए वर्कफ़्लो को फिर से चलाएं: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +अपने इनपुट channels को workflow ब्लॉक के भीतर परिभाषित रखें, और सामान्य रूप से एक्सटेंशन द्वारा की गई किसी भी अन्य सिफारिश का पालन करें। + +### निष्कर्ष + +आप Nextflow एरर मैसेज और IDE दृश्य संकेतकों का उपयोग करके सिंटैक्स एरर को व्यवस्थित रूप से पहचान और ठीक कर सकते हैं। सामान्य सिंटैक्स एरर में गुम ब्रेसिज़, गलत process कीवर्ड, अपरिभाषित वेरिएबल, और Bash बनाम Nextflow वेरिएबल का अनुचित उपयोग शामिल हैं। VSCode एक्सटेंशन रनटाइम से पहले इनमें से कई को पकड़ने में मदद करता है। आपके टूलकिट में इन सिंटैक्स डिबगिंग कौशल के साथ, आप सबसे सामान्य Nextflow सिंटैक्स एरर को जल्दी हल करने में सक्षम होंगे और अधिक जटिल रनटाइम समस्याओं से निपटने के लिए आगे बढ़ेंगे। + +### आगे क्या है? + +अधिक जटिल channel संरचना एरर को डिबग करना सीखें जो तब भी होते हैं जब सिंटैक्स सही है। + +--- + +## 2. Channel संरचना एरर + +Channel संरचना एरर सिंटैक्स एरर से अधिक सूक्ष्म हैं क्योंकि कोड सिंटैक्टिकली सही है, लेकिन डेटा आकार उस से मेल नहीं खाते जो processes अपेक्षा करते हैं। Nextflow पाइपलाइन चलाने का प्रयास करेगा, लेकिन यह पा सकता है कि इनपुट की संख्या उसकी अपेक्षा से मेल नहीं खाती और विफल हो जाती है। ये एरर आम तौर पर केवल रनटाइम पर दिखाई देते हैं और आपके वर्कफ़्लो के माध्यम से प्रवाहित होने वाले डेटा की समझ की आवश्यकता होती है। + +!!! tip "`.view()` के साथ Channels की डिबगिंग" + + इस सेक्शन के दौरान, याद रखें कि आप अपने वर्कफ़्लो में किसी भी बिंदु पर channel सामग्री का निरीक्षण करने के लिए `.view()` operator का उपयोग कर सकते हैं। यह channel संरचना समस्याओं को समझने के लिए सबसे शक्तिशाली डिबगिंग टूल में से एक है। हम सेक्शन 2.4 में इस तकनीक का विस्तार से पता लगाएंगे, लेकिन उदाहरणों के माध्यम से काम करते समय इसका उपयोग करने के लिए स्वतंत्र महसूस करें। + + ```groovy + my_channel.view() // channel में क्या बह रहा है दिखाता है + ``` + +### 2.1. गलत संख्या में इनपुट Channels + +यह एरर तब होती है जब आप एक process की अपेक्षा से अलग संख्या में channels पास करते हैं। + +#### पाइपलाइन चलाएं + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### कोड की जांच करें + +एरर मैसेज स्पष्ट रूप से कहता है कि कॉल को 1 argument की उम्मीद थी लेकिन 2 प्राप्त हुए, और लाइन 23 की ओर इशारा करता है। आइए `bad_number_inputs.nf` की जांच करें: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Process केवल 1 इनपुट की अपेक्षा करती है + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // दो अलग-अलग channels बनाएं + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: 2 channels पास कर रहे हैं लेकिन process केवल 1 की अपेक्षा करता है + PROCESS_FILES(samples_ch, files_ch) +} +``` + +आपको बेमेल `PROCESS_FILES` कॉल देखनी चाहिए, जब process केवल एक को परिभाषित करती है तो कई इनपुट channels की आपूर्ति करना। VSCode एक्सटेंशन भी process कॉल को लाल रंग में रेखांकित करेगा, और जब आप माउस ओवर करते हैं तो एक diagnostic मैसेज प्रदान करेगा: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### कोड को ठीक करें + +इस विशिष्ट उदाहरण के लिए, process एक single channel की उम्मीद करती है और दूसरे channel की आवश्यकता नहीं है, इसलिए हम केवल `samples_ch` channel को पास करके इसे ठीक कर सकते हैं: + +=== "बाद में" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process केवल 1 इनपुट की अपेक्षा करती है + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // दो अलग-अलग channels बनाएं + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ठीक किया: केवल वह channel पास करें जो process अपेक्षा करता है + PROCESS_FILES(samples_ch) + } + ``` + +=== "पहले" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process केवल 1 इनपुट की अपेक्षा करती है + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // दो अलग-अलग channels बनाएं + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: 2 channels पास कर रहे हैं लेकिन process केवल 1 की अपेक्षा करता है + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### पाइपलाइन चलाएं + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +इस उदाहरण की तुलना में अधिक सामान्यतः, आप एक process में अतिरिक्त इनपुट जोड़ सकते हैं और तदनुसार workflow कॉल को अपडेट करना भूल सकते हैं, जो इस प्रकार की एरर का कारण बन सकता है। सौभाग्य से, यह समझने और ठीक करने में आसान एरर में से एक है, क्योंकि एरर मैसेज बेमेल के बारे में काफी स्पष्ट है। + +### 2.2. Channel समाप्ति (Process अपेक्षा से कम बार चलती है) + +कुछ channel संरचना एरर बहुत अधिक सूक्ष्म हैं और बिल्कुल भी एरर उत्पन्न नहीं करते हैं। शायद इनमें से सबसे सामान्य एक चुनौती को दर्शाता है जिसका सामना नए Nextflow उपयोगकर्ताओं को यह समझने में करना पड़ता है कि queue channels समाप्त हो सकते हैं और आइटम खत्म हो सकते हैं, जिसका अर्थ है कि वर्कफ़्लो समय से पहले समाप्त हो जाता है। + +#### पाइपलाइन चलाएं + +```bash +nextflow run exhausted.nf +``` + +??? success "कमांड आउटपुट" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +यह वर्कफ़्लो बिना एरर के पूरा होता है, लेकिन यह केवल एक single नमूने को प्रोसेस करता है! + +#### कोड की जांच करें + +आइए `exhausted.nf` की जांच करें यह देखने के लिए कि क्या यह सही है: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // script से पहले Groovy code में variables परिभाषित करें + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Process केवल एक बार चलती है तीन बार के बजाय क्योंकि `reference_ch` channel एक queue channel है जो पहले process निष्पादन के बाद समाप्त हो जाती है। जब एक channel समाप्त हो जाती है, तो पूरी process रुक जाती है, भले ही अन्य channels में अभी भी आइटम हों। + +यह एक सामान्य पैटर्न है जहां आपके पास एक single संदर्भ फ़ाइल है जिसे कई नमूनों में पुन: उपयोग करने की आवश्यकता है। समाधान संदर्भ channel को एक value channel में परिवर्तित करना है जिसे अनिश्चित काल तक पुन: उपयोग किया जा सकता है। + +#### कोड को ठीक करें + +इसे संबोधित करने के कुछ तरीके हैं जो इस बात पर निर्भर करते हैं कि कितनी फ़ाइलें प्रभावित हैं। + +**विकल्प 1**: आपके पास एक single संदर्भ फ़ाइल है जिसे आप बहुत पुन: उपयोग कर रहे हैं। आप बस एक value channel प्रकार बना सकते हैं, जिसका उपयोग बार-बार किया जा सकता है। ऐसा करने के तीन तरीके हैं: + +**1a** `channel.value()` का उपयोग करें: + +```groovy title="exhausted.nf (fixed - Option 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Value channel को पुन: उपयोग किया जा सकता है + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** `first()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#first) का उपयोग करें: + +```groovy title="exhausted.nf (fixed - Option 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Value channel में बदलें + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** `collect()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#collect) का उपयोग करें: + +```groovy title="exhausted.nf (fixed - Option 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Value channel में बदलें + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**विकल्प 2**: अधिक जटिल परिदृश्यों में, शायद जहां आपके पास sample channel में सभी नमूनों के लिए कई संदर्भ फ़ाइलें हैं, आप `combine` operator का उपयोग कर सकते हैं एक नया channel बनाने के लिए जो दोनों channels को tuples में संयोजित करता है: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // कार्टेशियन उत्पाद बनाता है + + PROCESS_FILES(combined_ch) +} +``` + +`.combine()` operator दोनों channels का एक कार्टेशियन उत्पाद उत्पन्न करता है, इसलिए `reference_ch` में प्रत्येक आइटम को `input_ch` में प्रत्येक आइटम के साथ जोड़ा जाएगा। यह process को संदर्भ का उपयोग करते हुए प्रत्येक नमूने के लिए चलाने की अनुमति देता है। + +इसके लिए process इनपुट को समायोजित करने की आवश्यकता है। हमारे उदाहरण में, process परिभाषा की शुरुआत को निम्नानुसार समायोजित करने की आवश्यकता होगी: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +यह दृष्टिकोण सभी स्थितियों में उपयुक्त नहीं हो सकता है। + +#### पाइपलाइन चलाएं + +ऊपर दिए गए फिक्स में से एक को आजमाएं और वर्कफ़्लो को फिर से चलाएं: + +```bash +nextflow run exhausted.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +आपको अब केवल एक के बजाय तीनों नमूनों को प्रोसेस किए जाते हुए देखना चाहिए। + +### 2.3. गलत Channel सामग्री संरचना + +जब वर्कफ़्लो जटिलता के एक निश्चित स्तर तक पहुंचते हैं, तो प्रत्येक channel की आंतरिक संरचनाओं पर नज़र रखना थोड़ा मुश्किल हो सकता है, और लोग आमतौर पर process की अपेक्षा और channel में वास्तव में क्या है के बीच बेमेल उत्पन्न करते हैं। यह उस समस्या से अधिक सूक्ष्म है जिस पर हमने पहले चर्चा की, जहां channels की संख्या गलत थी। इस मामले में, आपके पास सही संख्या में इनपुट channels हो सकते हैं, लेकिन उन channels में से एक या अधिक की आंतरिक संरचना उस से मेल नहीं खाती जो process अपेक्षा करती है। + +#### पाइपलाइन चलाएं + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for diff --git a/docs/hi/docs/side_quests/dev_environment.md b/docs/hi/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..5e6abad887 --- /dev/null +++ b/docs/hi/docs/side_quests/dev_environment.md @@ -0,0 +1,628 @@ +# विकास वातावरण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +आधुनिक इंटीग्रेटेड डेवलपमेंट एनवायरनमेंट (IDE) आपके Nextflow विकास अनुभव को पूरी तरह बदल सकते हैं। यह साइड क्वेस्ट विशेष रूप से VS Code और उसकी Nextflow एक्सटेंशन का उपयोग करके तेज़ी से कोड लिखने, गलतियों को जल्दी पकड़ने और जटिल workflows को कुशलता से नेविगेट करने पर केंद्रित है। + +!!! note "यह एक पारंपरिक ट्यूटोरियल नहीं है" + + अन्य प्रशिक्षण मॉड्यूल के विपरीत, यह गाइड स्टेप-बाय-स्टेप ट्यूटोरियल के बजाय त्वरित संकेतों, सुझावों और व्यावहारिक उदाहरणों के संग्रह के रूप में व्यवस्थित है। प्रत्येक अनुभाग को आपकी रुचियों और वर्तमान विकास आवश्यकताओं के आधार पर स्वतंत्र रूप से खोजा जा सकता है। बेझिझक इधर-उधर जाएं और उन सुविधाओं पर ध्यान केंद्रित करें जो आपके workflow विकास के लिए सबसे तुरंत उपयोगी होंगी। + +## पहले आपको क्या जानना चाहिए + +यह गाइड मानती है कि आपने [Hello Nextflow](../hello_nextflow/) प्रशिक्षण कोर्स पूरा कर लिया है और आप बुनियादी Nextflow अवधारणाओं के साथ सहज हैं, जिनमें शामिल हैं: + +- **बुनियादी workflow संरचना**: processes, workflows को समझना और वे एक साथ कैसे जुड़ते हैं +- **Channel ऑपरेशन**: channels बनाना, processes के बीच डेटा पास करना और बुनियादी ऑपरेटर का उपयोग करना +- **Modules और संगठन**: पुन: उपयोग योग्य modules बनाना और include स्टेटमेंट का उपयोग करना +- **Configuration मूल बातें**: पैरामीटर, process निर्देशों और profiles के लिए `nextflow.config` का उपयोग करना + +## आप यहां क्या सीखेंगे + +यह गाइड **IDE उत्पादकता सुविधाओं** पर केंद्रित है जो आपको एक अधिक कुशल Nextflow डेवलपर बनाएंगी: + +- **उन्नत syntax highlighting**: समझना कि VS Code आपके कोड संरचना के बारे में आपको क्या दिखा रहा है +- **बुद्धिमान auto-completion**: तेज़ कोड लिखने के लिए context-aware सुझावों का लाभ उठाना +- **त्रुटि पहचान और diagnostics**: अपने workflow को चलाने से पहले syntax त्रुटियों को पकड़ना +- **कोड नेविगेशन**: processes, modules और परिभाषाओं के बीच तेज़ी से जाना +- **फ़ॉर्मेटिंग और संगठन**: सुसंगत, पठनीय कोड शैली बनाए रखना +- **AI-सहायता प्राप्त विकास** (वैकल्पिक): अपने IDE के साथ एकीकृत आधुनिक AI टूल का उपयोग करना + +!!! info "अब IDE सुविधाएं क्यों?" + + आप संभवतः पहले से ही [Hello Nextflow](../hello_nextflow/) कोर्स के दौरान VS Code का उपयोग कर रहे हैं, लेकिन हमने IDE सुविधाओं के बजाय Nextflow बुनियादी बातों को सीखने पर ध्यान केंद्रित रखा। अब जब आप processes, workflows, channels और modules जैसी बुनियादी Nextflow अवधारणाओं के साथ सहज हैं, तो आप परिष्कृत IDE सुविधाओं का लाभ उठाने के लिए तैयार हैं जो आपको एक अधिक कुशल डेवलपर बनाएंगी। + + इसे अपने विकास वातावरण को "लेवल अप" करने के रूप में सोचें - जिस एडिटर का आप उपयोग कर रहे हैं उसमें बहुत अधिक शक्तिशाली क्षमताएं हैं जो वास्तव में मूल्यवान हो जाती हैं जब आप समझते हैं कि वे आपकी मदद किस चीज़ में कर रही हैं। + +--- + +## 0. सेटअप और वार्मअप + +चलिए IDE सुविधाओं की खोज के लिए विशेष रूप से एक workspace सेट अप करते हैं: + +```bash title="IDE सुविधाओं की डायरेक्टरी में जाएं" +cd side-quests/ide_features +``` + +इस डायरेक्टरी को VS Code में खोलें: + +```bash title="वर्तमान डायरेक्टरी में VS Code खोलें" +code . +``` + +`ide_features` डायरेक्टरी में उदाहरण workflows हैं जो विभिन्न IDE सुविधाओं को प्रदर्शित करते हैं: + +```bash title="डायरेक्टरी संरचना दिखाएं" +tree . +``` + +```console title="प्रोजेक्ट संरचना" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "उदाहरण फ़ाइलों के बारे में" + + - `basic_workflow.nf` एक कार्यशील बुनियादी workflow है जिसे आप चला सकते हैं और संशोधित कर सकते हैं + - `complex_workflow.nf` केवल नेविगेशन सुविधाओं को प्रदर्शित करने के लिए चित्रण के लिए डिज़ाइन किया गया है - यह सफलतापूर्वक नहीं चल सकता है लेकिन यथार्थवादी मल्टी-फ़ाइल workflow संरचना दिखाता है + +### कीबोर्ड शॉर्टकट + +इस गाइड में कुछ सुविधाएं वैकल्पिक कीबोर्ड शॉर्टकट का उपयोग करेंगी। हो सकता है कि आप ब्राउज़र में GitHub Codespaces के माध्यम से इस सामग्री तक पहुंच रहे हों, और इस मामले में कभी-कभी शॉर्टकट अपेक्षित रूप से काम नहीं करेंगे क्योंकि वे आपके सिस्टम में अन्य चीज़ों के लिए उपयोग किए जाते हैं। + +यदि आप VS Code को लोकल रूप से चला रहे हैं, जैसा कि आप शायद करेंगे जब आप वास्तव में workflows लिख रहे होंगे, तो शॉर्टकट वर्णित रूप में काम करेंगे। + +यदि आप Mac का उपयोग कर रहे हैं, तो कुछ (सभी नहीं) कीबोर्ड शॉर्टकट "ctrl" के बजाय "cmd" का उपयोग करेंगे, और हम इसे टेक्स्ट में `Ctrl/Cmd` की तरह इंगित करेंगे। + +### 0.1. Nextflow Extension इंस्टॉल करना + +!!! note "पहले से Devcontainers का उपयोग कर रहे हैं?" + + यदि आप **GitHub Codespaces** में काम कर रहे हैं या **लोकल devcontainer** का उपयोग कर रहे हैं, तो Nextflow extension संभवतः पहले से ही आपके लिए इंस्टॉल और कॉन्फ़िगर किया गया है। आप नीचे दिए गए मैनुअल इंस्टॉलेशन स्टेप्स को छोड़ सकते हैं और सीधे extension सुविधाओं की खोज के लिए आगे बढ़ सकते हैं। + +extension को मैनुअल रूप से इंस्टॉल करने के लिए: + +1. VS Code खोलें +2. बाईं ओर extensions आइकन पर क्लिक करके Extensions व्यू पर जाएं: ![extensions आइकन](img/extensions_icon.png) (यदि आप VSCode को लोकल रूप से चला रहे हैं तो शॉर्टकट `Ctrl/Cmd+Shift+X`) +3. "Nextflow" खोजें +4. आधिकारिक Nextflow extension इंस्टॉल करें + +![Nextflow Extension इंस्टॉल करें](img/install_extension.png) + +### 0.2. Workspace लेआउट + +चूंकि आप Hello Nextflow के दौरान VS Code का उपयोग कर रहे हैं, इसलिए आप पहले से ही बुनियादी बातों से परिचित हैं। इस सत्र के लिए अपने workspace को कुशलता से व्यवस्थित करने का तरीका यहां दिया गया है: + +- **Editor Area**: फ़ाइलों को देखने और संपादित करने के लिए। आप फ़ाइलों की साथ-साथ तुलना करने के लिए इसे कई panes में विभाजित कर सकते हैं। +- **File Explorer** क्लिक करें (![file explorer आइकन](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): आपके सिस्टम पर लोकल फ़ाइलें और फ़ोल्डर। फ़ाइलों के बीच नेविगेट करने के लिए इसे बाईं ओर खुला रखें +- **Integrated Terminal** (Windows और MacOS दोनों के लिए `Ctrl+Shift+` backtick): नीचे कंप्यूटर के साथ इंटरैक्ट करने के लिए एक टर्मिनल। Nextflow या अन्य कमांड चलाने के लिए इसका उपयोग करें। +- **Problems Panel** (`Ctrl+Shift+M`): VS Code यहां किसी भी त्रुटि और समस्या को दिखाएगा जिसे वह पहचानता है। यह एक नज़र में मुद्दों को हाइलाइट करने के लिए उपयोगी है। + +आप अपने लेआउट को कस्टमाइज़ करने के लिए panels को इधर-उधर खींच सकते हैं या उन्हें छिपा सकते हैं (`Ctrl/Cmd+B` साइडबार को टॉगल करने के लिए) जैसे हम उदाहरणों के माध्यम से काम करते हैं। + +### निष्कर्ष + +आपके पास Nextflow extension के साथ VS Code सेट अप है और आप कुशल विकास के लिए workspace लेआउट को समझते हैं। + +### आगे क्या है? + +जानें कि syntax highlighting आपको एक नज़र में Nextflow कोड संरचना को समझने में कैसे मदद करती है। + +--- + +## 1. Syntax Highlighting और कोड संरचना + +अब जब आपका workspace सेट अप हो गया है, तो आइए जानें कि VS Code की syntax highlighting आपको Nextflow कोड को अधिक प्रभावी ढंग से पढ़ने और लिखने में कैसे मदद करती है। + +### 1.1. Nextflow Syntax तत्व + +`basic_workflow.nf` खोलें और syntax highlighting को क्रियान्वित होते देखें: + +![Syntax Showcase](img/syntax_showcase.png) + +ध्यान दें कि VS Code कैसे हाइलाइट करता है: + +- **Keywords** (`process`, `workflow`, `input`, `output`, `script`) विशिष्ट रंगों में +- **String literals** और **पैरामीटर** विभिन्न स्टाइलिंग के साथ +- **Comments** एक मौन रंग में +- **Variables** और **function calls** उपयुक्त जोर के साथ +- **Code blocks** उचित indentation guides के साथ + +!!! note "थीम-आश्रित रंग" + + आप जो विशिष्ट रंग देखते हैं वे आपकी VS Code थीम (dark/light मोड), रंग सेटिंग्स और आपके द्वारा किए गए किसी भी कस्टमाइज़ेशन पर निर्भर करेंगे। महत्वपूर्ण बात यह है कि विभिन्न syntax तत्व एक दूसरे से दृश्य रूप से अलग हैं, जिससे आपकी चुनी हुई रंग योजना की परवाह किए बिना कोड संरचना को समझना आसान हो जाता है। + +### 1.2. कोड संरचना को समझना + +syntax highlighting आपको जल्दी से पहचानने में मदद करती है: + +- **Process सीमाएं**: विभिन्न processes के बीच स्पष्ट अंतर +- **Input/output ब्लॉक**: डेटा प्रवाह परिभाषाओं को आसानी से पहचानना +- **Script ब्लॉक**: वास्तविक कमांड जो निष्पादित की जा रही हैं +- **Channel ऑपरेशन**: डेटा परिवर्तन चरण +- **Configuration निर्देश**: Process-विशिष्ट सेटिंग्स + +यह दृश्य संगठन कई processes और जटिल डेटा प्रवाह वाले जटिल workflows के साथ काम करते समय अमूल्य हो जाता है। + +### निष्कर्ष + +आप समझते हैं कि VS Code की syntax highlighting आपको Nextflow कोड संरचना पढ़ने और तेज़ विकास के लिए विभिन्न भाषा तत्वों की पहचान करने में कैसे मदद करती है। + +### आगे क्या है? + +जानें कि बुद्धिमान auto-completion context-aware सुझावों के साथ कोड लिखने को कैसे तेज़ करता है। + +--- + +## 2. बुद्धिमान Auto-completion + +VS Code की auto-completion सुविधाएं आपको संदर्भ के आधार पर उपयुक्त विकल्पों का सुझाव देकर तेज़ और कम त्रुटियों के साथ कोड लिखने में मदद करती हैं। + +### 2.1. Context-Aware सुझाव + +auto-completion विकल्प आपके कोड में आपके स्थान के आधार पर भिन्न होते हैं: + +#### Channel ऑपरेशन + +फिर से `basic_workflow.nf` खोलें और workflow ब्लॉक में `channel.` टाइप करने का प्रयास करें: + +![Channel auto-completion](img/autocomplete_channel.png) + +आपको इनके लिए सुझाव दिखाई देंगे: + +- `fromPath()` - फ़ाइल पथों से channel बनाएं +- `fromFilePairs()` - युग्मित फ़ाइलों से channel बनाएं +- `of()` - मानों से channel बनाएं +- `fromSRA()` - SRA accessions से channel बनाएं +- और बहुत कुछ... + +यह आपको सटीक मेथड नाम याद रखने की आवश्यकता के बिना उपयोग करने के लिए सही channel factory को जल्दी से खोजने में मदद करता है। + +आप channels पर लागू करने के लिए उपलब्ध ऑपरेटर भी खोज सकते हैं। उदाहरण के लिए, उपलब्ध ऑपरेशन देखने के लिए `FASTQC.out.html.` टाइप करें: + +![Channel ऑपरेशन auto-completion](img/autocomplete_operators.png) + +#### Process निर्देश + +process script ब्लॉक के अंदर, उपलब्ध runtime properties देखने के लिए `task.` टाइप करें: + +![Task properties auto-completion](img/autocomplete_task.png) + +#### Configuration + +nextflow.config खोलें और उपलब्ध process निर्देश देखने के लिए कहीं भी `process.` टाइप करें: + +![Config auto-completion](img/autocomplete_config.png) + +आपको इनके लिए सुझाव दिखाई देंगे: + +- `executor` +- `memory` +- `cpus` + +यह processes को कॉन्फ़िगर करते समय समय बचाता है और विभिन्न configuration scopes में काम करता है। उदाहरण के लिए, Docker-विशिष्ट configuration विकल्प देखने के लिए `docker.` टाइप करने का प्रयास करें। + +### निष्कर्ष + +आप syntax को याद किए बिना उपलब्ध channel ऑपरेशन, process निर्देशों और configuration विकल्पों को खोजने के लिए VS Code की बुद्धिमान auto-completion का उपयोग कर सकते हैं। + +### आगे क्या है? + +जानें कि real-time त्रुटि पहचान आपको अपने workflow को चलाने से पहले मुद्दों को पकड़ने में कैसे मदद करती है, बस कोड पढ़कर। + +## 3. त्रुटि पहचान और Diagnostics + +VS Code की real-time त्रुटि पहचान आपको अपने workflow को चलाने से पहले मुद्दों को पकड़ने में मदद करती है। + +### 3.1. Syntax त्रुटि पहचान + +चलिए पहचान को क्रियान्वित होते देखने के लिए एक जानबूझकर त्रुटि बनाते हैं। `basic_workflow.nf` खोलें और process नाम को `FASTQC` से `FASTQ` (या किसी अन्य अमान्य नाम) में बदलें। VS Code तुरंत workflow ब्लॉक में लाल squiggly underline के साथ त्रुटि को हाइलाइट करेगा: + +![Error underline](img/error_underline.png) + +### 3.2. Problems Panel + +व्यक्तिगत त्रुटि हाइलाइटिंग से परे, VS Code एक केंद्रीकृत Problems panel प्रदान करता है जो आपके workspace में सभी त्रुटियों, चेतावनियों और info संदेशों को एकत्रित करता है। इसे `Ctrl/Cmd+Shift+M` के साथ खोलें और वर्तमान फ़ाइल के लिए प्रासंगिक केवल त्रुटियां दिखाने के लिए filter आइकन का उपयोग करें: + +![Problems panel फ़िल्टर करें](img/active_file.png) + +समस्याग्रस्त लाइन पर सीधे जाने के लिए किसी भी मुद्दे पर क्लिक करें + +![Problems Panel](img/problems_panel.png) + +process नाम को वापस `FASTQC` में बदलकर त्रुटि को ठीक करें। + +### 3.3. सामान्य त्रुटि पैटर्न + +Nextflow syntax में सामान्य त्रुटियों में शामिल हैं: + +- **गुम ब्रैकेट**: बेमेल `{` या `}` +- **अधूरे ब्लॉक**: processes में आवश्यक अनुभागों का गुम होना +- **अमान्य syntax**: विकृत Nextflow DSL +- **Keywords में टाइपो**: गलत वर्तनी वाले process निर्देश +- **Channel बेमेल**: प्रकार असंगतताएं + +Nextflow language server इन मुद्दों को Problems panel में हाइलाइट करता है। आप pipeline चलाते समय syntax त्रुटियों से बचने के लिए इन्हें जल्दी जांच सकते हैं। + +### निष्कर्ष + +आप अपने workflow को चलाने से पहले syntax त्रुटियों और मुद्दों को पकड़ने के लिए VS Code की त्रुटि पहचान और Problems panel का उपयोग कर सकते हैं, जिससे समय बचता है और निराशा रोकी जा सकती है। + +### आगे क्या है? + +जानें कि जटिल workflows में processes, modules और परिभाषाओं के बीच कुशलता से कैसे नेविगेट करें। + +--- + +## 4. कोड नेविगेशन और Symbol प्रबंधन + +कई फ़ाइलों में फैले जटिल workflows के साथ काम करते समय कुशल नेविगेशन महत्वपूर्ण है। इसे समझने के लिए, `basic_workflow.nf` में process परिभाषा को हमारे द्वारा आपको प्रदान किए गए मॉड्यूल के लिए import से बदलें: + +=== "बाद में" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "पहले" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. परिभाषा पर जाएं + +यदि आप `FASTQC` जैसे process नाम पर माउस घुमाते हैं, तो आपको मॉड्यूल इंटरफ़ेस (inputs और outputs) के साथ एक popup दिखाई देगा: + +![परिभाषा पर जाएं](img/syntax.png) + +यह सुविधा workflows लिखते समय विशेष रूप से मूल्यवान है, क्योंकि यह आपको सीधे मॉड्यूल फ़ाइल खोले बिना मॉड्यूल इंटरफ़ेस को समझने की अनुमति देती है। + +आप **Ctrl/Cmd-click** का उपयोग करके किसी भी process, मॉड्यूल या variable परिभाषा पर जल्दी से नेविगेट कर सकते हैं। script के शीर्ष पर मॉड्यूल फ़ाइल के लिंक पर माउस घुमाएं, और सुझाए अनुसार लिंक का अनुसरण करें: + +![लिंक का अनुसरण करें](img/follow_link.png) + +यही बात process नामों के लिए भी काम करती है। `basic_workflow.nf` पर वापस जाएं और workflow ब्लॉक में `FASTQC` process नाम पर इसे आज़माएं। यह आपको सीधे process नाम से जोड़ता है (जो इस उदाहरण में मॉड्यूल फ़ाइल के समान है, लेकिन बहुत बड़ी फ़ाइल के आधे रास्ते में हो सकता है)। + +वापस जाने के लिए जहां आप थे, **Alt+←** (या Mac पर **Ctrl+-**) का उपयोग करें। यह अपनी जगह खोए बिना कोड का पता लगाने का एक शक्तिशाली तरीका है। + +अब आइए `complex_workflow.nf` (पहले उल्लिखित केवल चित्रण के लिए फ़ाइल) का उपयोग करके अधिक जटिल workflow में नेविगेशन का पता लगाएं। इस workflow में अलग मॉड्यूल फ़ाइलों में परिभाषित कई processes के साथ-साथ कुछ inline processes भी हैं। जबकि जटिल मल्टी-फ़ाइल संरचनाओं को मैनुअल रूप से नेविगेट करना चुनौतीपूर्ण हो सकता है, परिभाषाओं पर जाने की क्षमता अन्वेषण को बहुत अधिक प्रबंधनीय बनाती है। + +1. `complex_workflow.nf` खोलें +2. मॉड्यूल परिभाषाओं पर नेविगेट करें +3. वापस नेविगेट करने के लिए **Alt+←** (या **Ctrl+-**) का उपयोग करें +4. workflow ब्लॉक में `FASTQC` process नाम पर नेविगेट करें। यह आपको सीधे process नाम से जोड़ता है (जो इस उदाहरण में मॉड्यूल फ़ाइल के समान है, लेकिन बहुत बड़ी फ़ाइल के आधे रास्ते में हो सकता है)। +5. फिर से वापस नेविगेट करें +6. workflow ब्लॉक में `TRIM_GALORE` process पर नेविगेट करें। यह inline परिभाषित है, इसलिए यह आपको अलग फ़ाइल में नहीं ले जाएगा, लेकिन यह अभी भी आपको process परिभाषा दिखाएगा, और आप अभी भी वापस नेविगेट कर सकते हैं जहां आप थे। + +### 4.2. Symbol नेविगेशन + +`complex_workflow.nf` अभी भी खुला होने के साथ, आप VSCode के शीर्ष पर सर्च बार में `@` टाइप करके फ़ाइल में सभी symbols का अवलोकन प्राप्त कर सकते हैं (कीबोर्ड शॉर्टकट `Ctrl/Cmd+Shift+O` है, लेकिन Codespaces में काम नहीं कर सकता है)। यह symbol नेविगेशन panel खोलता है, जो वर्तमान फ़ाइल में सभी symbols को सूचीबद्ध करता है: + +![Symbol नेविगेशन](img/symbols.png) + +यह दिखाता है: + +- सभी process परिभाषाएं +- Workflow परिभाषाएं (इस फ़ाइल में दो workflows परिभाषित हैं) +- Function परिभाषाएं + +परिणामों को फ़िल्टर करने के लिए टाइप करना शुरू करें। + +### 4.3. सभी संदर्भ खोजें + +समझना कि आपके codebase में एक process या variable का उपयोग कहाँ किया जाता है, बहुत सहायक हो सकता है। उदाहरण के लिए, यदि आप `FASTQC` process के सभी संदर्भों को खोजना चाहते हैं, तो इसकी परिभाषा पर नेविगेट करके शुरू करें। आप सीधे `modules/fastqc.nf` खोलकर, या जैसा हमने ऊपर किया था `Ctrl/Cmd-click` के साथ VS Code की त्वरित नेविगेशन सुविधा का उपयोग करके ऐसा कर सकते हैं। process परिभाषा पर पहुंचने के बाद, `FASTQC` process नाम पर राइट-क्लिक करें और संदर्भ मेनू से "Find All References" चुनें ताकि सभी उदाहरण देखे जा सकें जहां इसका उपयोग किया गया है। + +![संदर्भ खोजें](img/references.png) + +यह सुविधा सभी उदाहरणों को प्रदर्शित करती है जहां आपके workspace के भीतर `FASTQC` का संदर्भ दिया गया है, जिसमें दो अलग-अलग workflows में इसका उपयोग शामिल है। यह अंतर्दृष्टि `FASTQC` process में संशोधनों के संभावित प्रभाव का आकलन करने के लिए महत्वपूर्ण है। + +### 4.4. Outline Panel + +Outline panel, Explorer साइडबार में स्थित (![Explorer आइकन](img/files_icon.png) पर क्लिक करें), आपकी वर्तमान फ़ाइल में सभी symbols का एक सुविधाजनक अवलोकन प्रदान करता है। यह सुविधा आपको functions, variables और अन्य प्रमुख तत्वों को पदानुक्रमित दृश्य में प्रदर्शित करके अपने कोड की संरचना को जल्दी से नेविगेट करने और प्रबंधित करने की अनुमति देती है। + +![Outline panel](img/outline.png) + +फ़ाइल ब्राउज़र का उपयोग किए बिना अपने कोड के विभिन्न भागों में तेज़ी से नेविगेट करने के लिए Outline panel का उपयोग करें। + +### 4.5. DAG दृश्यीकरण + +VS Code की Nextflow extension आपके workflow को Directed Acyclic Graph (DAG) के रूप में दृश्यमान कर सकती है। यह आपको processes के बीच डेटा प्रवाह और निर्भरता को समझने में मदद करता है। `complex_workflow.nf` खोलें और `workflow {` के ऊपर "Preview DAG" बटन पर क्लिक करें (इस फ़ाइल में दूसरा `workflow` ब्लॉक): + +![DAG preview](img/dag_preview.png) + +यह सिर्फ 'entry' workflow है, लेकिन आप आगे workflow `RNASEQ_PIPELINE {` के ऊपर "Preview DAG" बटन पर क्लिक करके भीतरी workflows के लिए भी DAG का preview कर सकते हैं: + +![DAG preview भीतरी workflow](img/dag_preview_inner.png) + +इस workflow के लिए, आप कोड में संबंधित process परिभाषाओं पर नेविगेट करने के लिए DAG में nodes का उपयोग कर सकते हैं। किसी node पर क्लिक करें, और यह आपको editor में प्रासंगिक process परिभाषा पर ले जाएगा। विशेष रूप से जब एक workflow बड़े आकार में बढ़ता है, तो यह वास्तव में आपको कोड में नेविगेट करने और यह समझने में मदद कर सकता है कि processes कैसे जुड़ी हुई हैं। + +### निष्कर्ष + +आप कोड संरचना और निर्भरता को समझने के लिए go-to-definition, symbol खोज, संदर्भ खोजें और DAG दृश्यीकरण का उपयोग करके जटिल workflows को कुशलता से नेविगेट कर सकते हैं। + +### आगे क्या है? + +जानें कि बड़े Nextflow प्रोजेक्ट्स में कई परस्पर जुड़ी फ़ाइलों में प्रभावी ढंग से कैसे काम करें। + +## 5. कई फ़ाइलों में काम करना + +वास्तविक Nextflow विकास में कई परस्पर जुड़ी फ़ाइलों के साथ काम करना शामिल है। आइए जानें कि VS Code आपको जटिल प्रोजेक्ट्स को कुशलता से प्रबंधित करने में कैसे मदद करता है। + +### 5.1. त्वरित फ़ाइल नेविगेशन + +`complex_workflow.nf` खुला होने के साथ, आप देखेंगे कि यह कई modules को import करता है। आइए उनके बीच त्वरित नेविगेशन का अभ्यास करें। + +**Ctrl+P** (या **Cmd+P**) दबाएं और "fast" टाइप करना शुरू करें: + +VS Code आपको मेल खाने वाली फ़ाइलें दिखाएगा। तुरंत वहां जाने के लिए `modules/fastqc.nf` का चयन करें। जब आप मोटे तौर पर जानते हैं कि आप किस फ़ाइल की तलाश कर रहे हैं तो यह file explorer के माध्यम से क्लिक करने की तुलना में बहुत तेज़ है। + +अन्य पैटर्न के साथ इसे आज़माएं: + +- STAR alignment मॉड्यूल फ़ाइल (`star.nf`) खोजने के लिए "star" टाइप करें +- utility functions फ़ाइल (`utils.nf`) खोजने के लिए "utils" टाइप करें +- configuration फ़ाइलों (`nextflow.config`) पर जाने के लिए "config" टाइप करें + +### 5.2. मल्टी-फ़ाइल विकास के लिए Split Editor + +modules के साथ काम करते समय, आपको अक्सर मुख्य workflow और मॉड्यूल परिभाषाओं दोनों को एक साथ देखने की आवश्यकता होती है। चलिए इसे सेट अप करते हैं: + +1. `complex_workflow.nf` खोलें +2. नए टैब में `modules/fastqc.nf` खोलें +3. `modules/fastqc.nf` टैब पर राइट-क्लिक करें और "Split Right" चुनें +4. अब आप दोनों फ़ाइलों को साथ-साथ देख सकते हैं + +![Split editor](img/split_editor.png) + +यह अमूल्य है जब: + +- workflow calls लिखते समय मॉड्यूल इंटरफ़ेस की जांच कर रहे हों, और preview पर्याप्त नहीं है +- विभिन्न modules में समान processes की तुलना कर रहे हों +- workflow और modules के बीच डेटा प्रवाह को डीबग कर रहे हों + +### 5.3. प्रोजेक्ट-व्यापी खोज + +कभी-कभी आपको यह खोजने की आवश्यकता होती है कि आपके पूरे प्रोजेक्ट में विशिष्ट पैटर्न का उपयोग कहाँ किया जाता है। खोज panel खोलने के लिए `Ctrl/Cmd+Shift+F` दबाएं। + +workspace में `publishDir` खोजने का प्रयास करें: + +![प्रोजेक्ट खोज](img/project_search.png) + +यह आपको प्रत्येक फ़ाइल दिखाता है जो publish directories का उपयोग करती है, जिससे आपको मदद मिलती है: + +- आउटपुट संगठन पैटर्न को समझना +- विशिष्ट निर्देशों के उदाहरण खोजना +- modules में निरंतरता सुनिश्चित करना + +### निष्कर्ष + +आप workflows और modules में कुशलता से काम करने के लिए त्वरित फ़ाइल नेविगेशन, split editors और प्रोजेक्ट-व्यापी खोज का उपयोग करके जटिल मल्टी-फ़ाइल प्रोजेक्ट्स का प्रबंधन कर सकते हैं। + +### आगे क्या है? + +जानें कि कोड फ़ॉर्मेटिंग और रखरखाव सुविधाएं आपके workflows को व्यवस्थित और पठनीय कैसे रखती हैं। + +--- + +## 6. कोड फ़ॉर्मेटिंग और रखरखाव + +उचित कोड फ़ॉर्मेटिंग न केवल सौंदर्यशास्त्र के लिए बल्कि पठनीयता, समझ और जटिल workflows को अपडेट करने में आसानी बढ़ाने के लिए भी आवश्यक है। + +### 6.1. क्रियान्वित होती Automatic फ़ॉर्मेटिंग + +`basic_workflow.nf` खोलें और जानबूझकर फ़ॉर्मेटिंग को गड़बड़ा दें: + +- कुछ indentation हटाएं: पूरे दस्तावेज़ को हाइलाइट करें और जितना संभव हो उतने indentations हटाने के लिए `shift+tab` कई बार दबाएं। +- यादृच्छिक स्थानों में अतिरिक्त स्थान जोड़ें: `channel.fromPath` स्टेटमेंट में, `(` के बाद 30 स्थान जोड़ें। +- कुछ लाइनों को अजीब तरह से तोड़ें: `.view {` ऑपरेटर और `Processing sample:` string के बीच एक नई लाइन जोड़ें लेकिन closing parenthesis `}` से पहले संबंधित newline न जोड़ें। + +अब auto-format करने के लिए `Shift+Alt+F` (या MacOS पर `Shift+Option+F`) दबाएं: + +VS Code तुरंत: + +- process संरचना को स्पष्ट रूप से दिखाने के लिए indentation को ठीक करता है +- समान तत्वों को लगातार संरेखित करता है +- अनावश्यक whitespace को हटाता है +- पठनीय line breaks बनाए रखता है + +ध्यान दें कि automatic फ़ॉर्मेटिंग प्रत्येक कोड शैली समस्या को हल नहीं कर सकती है। Nextflow language server आपके कोड को साफ-सुथरा रखने का लक्ष्य रखता है, लेकिन यह कुछ क्षेत्रों में आपकी व्यक्तिगत प्राथमिकताओं का भी सम्मान करता है। उदाहरण के लिए, यदि आप process के `script` ब्लॉक के अंदर indentation हटाते हैं, तो formatter इसे जैसा है वैसा ही छोड़ देगा, क्योंकि आप जानबूझकर उस शैली को पसंद कर सकते हैं। + +वर्तमान में, Nextflow के लिए कोई सख्त शैली प्रवर्तन नहीं है, इसलिए language server कुछ लचीलापन प्रदान करता है। हालांकि, यह स्पष्टता बनाए रखने के लिए मेथड और function परिभाषाओं के आसपास लगातार फ़ॉर्मेटिंग नियमों को लागू करेगा। + +### 6.2. कोड संगठन सुविधाएं + +#### त्वरित Commenting + +अपने workflow में कोड का एक ब्लॉक चुनें और इसे comment out करने के लिए **Ctrl+/** (या **Cmd+/**) दबाएं: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +यह इनके लिए उत्तम है: + +- विकास के दौरान workflows के भागों को अस्थायी रूप से अक्षम करना +- जटिल channel ऑपरेशन में व्याख्यात्मक comments जोड़ना +- workflow अनुभागों का दस्तावेज़ीकरण करना + +कोड को uncomment करने के लिए फिर से **Ctrl+/** (या **Cmd+/**) का उपयोग करें। + +#### अवलोकन के लिए Code Folding + +`complex_workflow.nf` में, process परिभाषाओं के बगल में छोटे तीर देखें। processes को fold (collapse) करने के लिए उन पर क्लिक करें: + +![Code folding](img/code_folding.png) + +यह आपको कार्यान्वयन विवरण में खोए बिना आपके workflow संरचना का उच्च-स्तरीय अवलोकन देता है। + +#### Bracket मिलान + +किसी भी `{` या `}` bracket के बगल में अपना कर्सर रखें और VS Code मिलान करने वाले bracket को हाइलाइट करता है। मिलान करने वाले brackets के बीच जाने के लिए **Ctrl+Shift+\\** (या **Cmd+Shift+\\**) का उपयोग करें। + +यह इनके लिए महत्वपूर्ण है: + +- Process सीमाओं को समझना +- गुम या अतिरिक्त brackets को खोजना +- नेस्टेड workflow संरचनाओं को नेविगेट करना + +#### Multi-line चयन और संपादन + +एक साथ कई लाइनों को संपादित करने के लिए, VS Code शक्तिशाली multi-cursor क्षमताएं प्रदान करता है: + +- **Multi-line चयन**: कई लाइनों का चयन करने के लिए **Ctrl+Alt** (या MacOS के लिए **Cmd+Option**) को पकड़ें और arrow keys का उपयोग करें +- **Multi-line indenting**: कई लाइनों का चयन करें और पूरे ब्लॉक को indent करने के लिए **Tab** का उपयोग करें या outdent करने के लिए **Shift+Tab** का उपयोग करें + +यह विशेष रूप से इनके लिए उपयोगी है: + +- पूरे process ब्लॉक को लगातार indent करना +- एक साथ कई लाइनों में comments जोड़ना +- कई processes में समान पैरामीटर परिभाषाओं को संपादित करना + +### निष्कर्ष + +आप जटिल workflows को कुशलता से व्यवस्थित करने के लिए automatic फ़ॉर्मेटिंग, commenting सुविधाओं, code folding, bracket मिलान और multi-line संपादन का उपयोग करके स्वच्छ, पठनीय कोड बनाए रख सकते हैं। + +### आगे क्या है? + +जानें कि VS Code केवल कोड संपादन से परे आपके व्यापक विकास workflow के साथ कैसे एकीकृत होता है। + +--- + +## 7. विकास Workflow एकीकरण + +VS Code केवल कोड संपादन से परे आपके विकास workflow के साथ अच्छी तरह से एकीकृत होता है। + +### 7.1. Version Control एकीकरण + +!!! note "Codespaces और Git एकीकरण" + + यदि आप **GitHub Codespaces** में काम कर रहे हैं, तो कुछ Git एकीकरण सुविधाएं अपेक्षित रूप से काम नहीं कर सकती हैं, विशेष रूप से Source Control के लिए कीबोर्ड शॉर्टकट। हो सकता है कि आपने प्रारंभिक सेटअप के दौरान डायरेक्टरी को Git repository के रूप में खोलने से इनकार कर दिया हो, जो प्रशिक्षण उद्देश्यों के लिए ठीक है। + +यदि आपका प्रोजेक्ट एक git repository है (जैसा कि यह है), VS Code दिखाता है: + +- रंगीन संकेतकों के साथ संशोधित फ़ाइलें +- status bar में Git स्थिति +- Inline diff दृश्य +- Commit और push क्षमताएं + +git परिवर्तनों को देखने और editor में सीधे commits को stage करने के लिए source control बटन (![Source control आइकन](img/source_control_icon.png)) (`Ctrl+Shift+G` या `Cmd+Shift+G` यदि आप VSCode के साथ locally काम कर रहे हैं) का उपयोग करके Source Control panel खोलें। + +![Source Control Panel](img/source_control.png) + +### 7.2. Workflows को चलाना और निरीक्षण करना + +चलिए एक workflow चलाते हैं और फिर परिणामों का निरीक्षण करते हैं। integrated terminal (Windows और MacOS दोनों में `Ctrl+Shift+` backtick) में, basic workflow चलाएं: + +```bash title="basic workflow चलाएं" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +जबकि workflow चल रहा है, आप terminal में real-time आउटपुट देखेंगे। पूर्ण होने के बाद, आप अपने editor को छोड़े बिना परिणामों का निरीक्षण करने के लिए VS Code का उपयोग कर सकते हैं: + +1. **work directories पर नेविगेट करें**: `.nextflow/work` को browse करने के लिए file explorer या terminal का उपयोग करें +2. **log फ़ाइलें खोलें**: उन्हें सीधे VS Code में खोलने के लिए terminal आउटपुट में log फ़ाइल पथों पर क्लिक करें +3. **आउटपुट का निरीक्षण करें**: file explorer में प्रकाशित results directories को browse करें +4. **execution रिपोर्ट देखें**: HTML रिपोर्ट को सीधे VS Code या अपने ब्राउज़र में खोलें + +यह कई एप्लिकेशन के बीच स्विच करने के बजाय सब कुछ एक ही जगह रखता है। + +### निष्कर्ष + +आप एक ही इंटरफ़ेस से अपनी संपूर्ण विकास प्रक्रिया को प्रबंधित करने के लिए VS Code को version control और workflow execution के साथ एकीकृत कर सकते हैं। + +### आगे क्या है? + +देखें कि ये सभी IDE सुविधाएं आपके दैनिक विकास workflow में एक साथ कैसे काम करती हैं। + +--- + +## 8. सारांश और त्वरित नोट्स + +ऊपर चर्चा की गई प्रत्येक IDE सुविधा पर कुछ त्वरित नोट्स यहां दिए गए हैं: + +### 8.1. नई सुविधा शुरू करना + +1. प्रासंगिक मौजूदा modules को खोजने के लिए **त्वरित फ़ाइल open** (`Ctrl+P` या `Cmd+P`) +2. समान processes को साथ-साथ देखने के लिए **Split editor** +3. फ़ाइल संरचना को समझने के लिए **Symbol नेविगेशन** (`Ctrl+Shift+O` या `Cmd+Shift+O`) +4. नया कोड जल्दी लिखने के लिए **Auto-completion** + +### 8.2. मुद्दों को डीबग करना + +1. एक साथ सभी त्रुटियों को देखने के लिए **Problems panel** (`Ctrl+Shift+M` या `Cmd+Shift+M`) +2. Process इंटरफ़ेस को समझने के लिए **परिभाषा पर जाएं** (`Ctrl-click` या `Cmd-click`) +3. देखने के लिए कि processes का उपयोग कैसे किया जाता है **सभी संदर्भ खोजें** +4. समान पैटर्न या मुद्दों को खोजने के लिए **प्रोजेक्ट-व्यापी खोज** + +### 8.3. Refactoring और सुधार + +1. पैटर्न खोजने के लिए **प्रोजेक्ट-व्यापी खोज** (`Ctrl+Shift+F` या `Cmd+Shift+F`) +2. निरंतरता बनाए रखने के लिए **Auto-formatting** (`Shift+Alt+F` या `Shift+Option+F`) +3. संरचना पर ध्यान केंद्रित करने के लिए **Code folding** +4. परिवर्तनों को ट्रैक करने के लिए **Git एकीकरण** + +--- + +## सारांश + +अब आपने Nextflow विकास के लिए VS Code की IDE सुविधाओं का एक त्वरित दौरा किया है। ये टूल आपको इनके माध्यम से काफी अधिक उत्पादक बनाएंगे: + +- **त्रुटियों को कम करना** real-time syntax जांच के माध्यम से +- **विकास को तेज़ करना** बुद्धिमान auto-completion के साथ +- **नेविगेशन में सुधार** जटिल मल्टी-फ़ाइल workflows में +- **गुणवत्ता बनाए रखना** सुसंगत फ़ॉर्मेटिंग के माध्यम से +- **समझ को बढ़ाना** उन्नत highlighting और संरचना दृश्यीकरण के माध्यम से + +हम उम्मीद नहीं करते कि आप सब कुछ याद रखेंगे, लेकिन अब आप जानते हैं कि ये सुविधाएं मौजूद हैं और जब आपको उनकी आवश्यकता होगी तो आप उन्हें ढूंढ पाएंगे। जैसे ही आप Nextflow workflows को विकसित करना जारी रखते हैं, ये IDE सुविधाएं स्वाभाविक हो जाएंगी, जिससे आप syntax और संरचना से जूझने के बजाय उच्च-गुणवत्ता वाले कोड लिखने पर ध्यान केंद्रित कर सकेंगे। + +### आगे क्या है? + +अन्य प्रशिक्षण modules के माध्यम से काम करते समय इन IDE कौशल को लागू करें, उदाहरण के लिए: + +- **[nf-test](nf-test.md)**: अपने workflows के लिए व्यापक test suites बनाएं +- **[Hello nf-core](../../hello_nf-core/)**: community मानकों के साथ उत्पादन-गुणवत्ता वाले pipelines बनाएं + +इन IDE सुविधाओं की वास्तविक शक्ति तब उभरती है जब आप बड़े, अधिक जटिल प्रोजेक्ट्स पर काम करते हैं। उन्हें धीरे-धीरे अपने workflow में शामिल करना शुरू करें—कुछ सत्रों के भीतर, वे स्वाभाविक हो जाएंगी और परिवर्तित कर देंगी कि आप Nextflow विकास को कैसे देखते हैं। + +त्रुटियों को आपको धीमा करने से पहले पकड़ने से लेकर आसानी के साथ जटिल codebases को नेविगेट करने तक, ये टूल आपको अधिक आत्मविश्वासी और कुशल डे diff --git a/docs/hi/docs/side_quests/essential_scripting_patterns.md b/docs/hi/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..2bbd44d5b3 --- /dev/null +++ b/docs/hi/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,847 @@ +# आवश्यक Nextflow स्क्रिप्टिंग पैटर्न + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow एक प्रोग्रामिंग भाषा है जो Java Virtual Machine पर चलती है। जबकि Nextflow [Groovy](http://groovy-lang.org/) पर बनाई गई है और इसके अधिकांश सिंटैक्स को साझा करती है, Nextflow सिर्फ "एक्सटेंशन के साथ Groovy" नहीं है -- यह पूर्णतः निर्दिष्ट [सिंटैक्स](https://nextflow.io/docs/latest/reference/syntax.html) और [standard library](https://nextflow.io/docs/latest/reference/stdlib.html) के साथ एक स्वतंत्र भाषा है। + +आप वेरिएबल, maps, और lists के लिए बुनियादी सिंटैक्स से आगे बढ़े बिना बहुत सारी Nextflow लिख सकते हैं। अधिकांश Nextflow ट्यूटोरियल workflow orchestration (channels, processes, और data flow) पर केंद्रित होते हैं, और आप सिर्फ इतने से ही आश्चर्यजनक रूप से बहुत आगे जा सकते हैं। + +हालांकि, जब आपको डेटा में हेरफेर करने, जटिल फ़ाइल नामों को parse करने, conditional logic को लागू करने, या मजबूत production workflows बनाने की आवश्यकता होती है, तो यह आपके कोड के दो अलग पहलुओं के बारे में सोचने में मदद करता है: **dataflow** (channels, operators, processes, और workflows) और **scripting** (closures, functions, और process scripts के अंदर का कोड)। जबकि यह भेद कुछ हद तक मनमाना है—यह सब Nextflow कोड है—यह यह समझने के लिए एक उपयोगी मानसिक मॉडल प्रदान करता है कि आप कब अपनी pipeline को orchestrate कर रहे हैं बनाम कब आप डेटा में हेरफेर कर रहे हैं। दोनों में महारत हासिल करने से स्पष्ट, maintainable workflows लिखने की आपकी क्षमता में नाटकीय रूप से सुधार होता है। + +### सीखने के लक्ष्य + +यह side quest आपको बुनियादी अवधारणाओं से लेकर production-ready पैटर्न तक एक व्यावहारिक यात्रा पर ले जाता है। +हम एक साधारण CSV-reading workflow को एक sophisticated bioinformatics pipeline में बदल देंगे, इसे realistic चुनौतियों के माध्यम से चरण-दर-चरण विकसित करते हुए: + +- **सीमाओं को समझना:** Dataflow operations और scripting के बीच अंतर करें, और समझें कि वे एक साथ कैसे काम करते हैं +- **डेटा में हेरफेर:** शक्तिशाली ऑपरेटर्स का उपयोग करके maps और collections को extract, transform, और subset करें +- **स्ट्रिंग प्रोसेसिंग:** Regex पैटर्न के साथ जटिल फ़ाइल नामकरण योजनाओं को parse करें और वेरिएबल interpolation में महारत हासिल करें +- **पुन: प्रयोज्य फ़ंक्शन:** साफ़, अधिक maintainable workflows के लिए जटिल logic को named functions में extract करें +- **Dynamic logic:** ऐसे processes बनाएं जो विभिन्न इनपुट प्रकारों के अनुकूल हों और dynamic resource allocation के लिए closures का उपयोग करें +- **Conditional routing:** उनकी metadata विशेषताओं के आधार पर विभिन्न processes के माध्यम से बुद्धिमानी से नमूनों को route करें +- **सुरक्षित operations:** Null-safe operators के साथ लापता डेटा को gracefully handle करें और स्पष्ट त्रुटि संदेशों के साथ inputs को validate करें +- **Configuration-based handlers:** Logging, notifications, और lifecycle management के लिए workflow event handlers का उपयोग करें + +### पूर्वापेक्षाएँ + +इस side quest को लेने से पहले, आपको चाहिए: + +- [Hello Nextflow](../hello_nextflow/README.md) ट्यूटोरियल या समकक्ष beginner's कोर्स पूरा किया हो। +- बुनियादी Nextflow अवधारणाओं और mechanisms (processes, channels, operators, फ़ाइलों के साथ काम करना, meta data) के साथ सहज हों +- सामान्य प्रोग्रामिंग constructs (वेरिएबल, maps, lists) के साथ बुनियादी परिचय हो + +यह ट्यूटोरियल प्रोग्रामिंग अवधारणाओं को समझाएगा जैसे हम उनका सामना करते हैं, इसलिए आपको व्यापक प्रोग्रामिंग अनुभव की आवश्यकता नहीं है। +हम मौलिक अवधारणाओं से शुरू करेंगे और उन्नत पैटर्न तक बनाएंगे। + +--- + +## 0. शुरू करें + +#### ट्रेनिंग codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार ट्रेनिंग वातावरण को खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएँ + +आइए उस डायरेक्टरी में जाएँ जहाँ इस ट्यूटोरियल के लिए फ़ाइलें स्थित हैं। + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### सामग्री की समीक्षा करें + +आपको एक मुख्य workflow फ़ाइल और एक `data` डायरेक्टरी मिलेगी जिसमें उदाहरण डेटा फ़ाइलें हैं। + +```console title="डायरेक्टरी सामग्री" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +हमारे नमूना CSV में जैविक नमूनों के बारे में जानकारी है जिन्हें उनकी विशेषताओं के आधार पर विभिन्न प्रसंस्करण की आवश्यकता है: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +हम इस realistic डेटासेट का उपयोग व्यावहारिक प्रोग्रामिंग तकनीकों का पता लगाने के लिए करेंगे जो आप वास्तविक bioinformatics workflows में सामना करेंगे। + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### तैयारी चेकलिस्ट + +लगता है कि आप शुरू करने के लिए तैयार हैं? + +- [ ] मैं इस कोर्स के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता/समझती हूँ +- [ ] मेरा codespace चालू है और चल रहा है +- [ ] मैंने अपनी कार्य डायरेक्टरी को उचित रूप से सेट कर लिया है +<!-- - [ ] मैं असाइनमेंट को समझता/समझती हूँ --> + +यदि आप सभी बॉक्स को चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. Dataflow बनाम Scripting: सीमाओं को समझना + +### 1.1. क्या क्या है इसकी पहचान करना + +Nextflow workflows लिखते समय, **dataflow** (channels और processes के माध्यम से डेटा कैसे चलता है) और **scripting** (वह कोड जो डेटा में हेरफेर करता है और निर्णय लेता है) के बीच अंतर करना महत्वपूर्ण है। आइए एक workflow बनाएं जो दर्शाता है कि वे एक साथ कैसे काम करते हैं। + +#### 1.1.1. बुनियादी Nextflow Workflow + +एक साधारण workflow से शुरू करें जो सिर्फ CSV फ़ाइल को पढ़ता है (हमने पहले से ही यह आपके लिए `main.nf` में किया है): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +`workflow` ब्लॉक हमारी pipeline संरचना को परिभाषित करता है, जबकि `channel.fromPath()` एक फ़ाइल पथ से एक channel बनाता है। `.splitCsv()` ऑपरेटर CSV फ़ाइल को प्रोसेस करता है और प्रत्येक पंक्ति को एक map डेटा संरचना में परिवर्तित करता है। + +कच्चे CSV डेटा को देखने के लिए इस workflow को चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Map Operator जोड़ना + +अब हम डेटा को transform करने के लिए scripting जोड़ने जा रहे हैं, `.map()` ऑपरेटर का उपयोग करते हुए जिससे आप शायद पहले से परिचित हैं। यह ऑपरेटर एक 'closure' लेता है जहाँ हम प्रत्येक आइटम को transform करने के लिए कोड लिख सकते हैं। + +!!! note + + एक **closure** कोड का एक ब्लॉक है जिसे पास किया जा सकता है और बाद में निष्पादित किया जा सकता है। इसे एक ऐसे फ़ंक्शन के रूप में सोचें जिसे आप inline परिभाषित करते हैं। Closures को curly braces `{ }` के साथ लिखा जाता है और पैरामीटर ले सकते हैं। वे Nextflow operators के काम करने के तरीके के लिए मौलिक हैं और यदि आप कुछ समय से Nextflow लिख रहे हैं, तो आप शायद पहले से ही उनका उपयोग कर रहे हैं बिना यह महसूस किए! + +यहाँ वह map operation कैसा दिखता है: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +यह हमारा पहला **closure** है - एक anonymous फ़ंक्शन जिसे आप argument के रूप में पास कर सकते हैं (Python में lambdas या JavaScript में arrow functions के समान)। Closures Nextflow operators के साथ काम करने के लिए आवश्यक हैं। + +Closure `{ row -> return row }` एक पैरामीटर `row` लेता है (कोई भी नाम हो सकता है: `item`, `sample`, आदि)। + +जब `.map()` ऑपरेटर प्रत्येक channel आइटम को प्रोसेस करता है, तो यह उस आइटम को आपके closure को पास करता है। यहाँ, `row` एक बार में एक CSV पंक्ति रखता है। + +यह परिवर्तन लागू करें और workflow चलाएं: + +```bash +nextflow run main.nf +``` + +आप पहले जैसा ही आउटपुट देखेंगे, क्योंकि हम बस इनपुट को अपरिवर्तित रूप से वापस कर रहे हैं। यह पुष्टि करता है कि map ऑपरेटर सही ढंग से काम कर रहा है। अब आइए डेटा को transform करना शुरू करें। + +#### 1.1.3. एक Map डेटा संरचना बनाना + +अब हम डेटा की प्रत्येक पंक्ति को transform करने के लिए अपने closure के अंदर **scripting** logic लिखने जा रहे हैं। यह वह जगह है जहाँ हम data flow को orchestrate करने के बजाय व्यक्तिगत डेटा आइटम को प्रोसेस करते हैं। + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // डेटा transformation के लिए Scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +`sample_meta` map एक key-value डेटा संरचना है (Python में dictionaries, JavaScript में objects, या Ruby में hashes की तरह) जो संबंधित जानकारी संग्रहीत करती है: sample ID, organism, tissue type, sequencing depth, और quality score। + +हम अपने डेटा को साफ़ करने के लिए string manipulation methods जैसे `.toLowerCase()` और `.replaceAll()` का उपयोग करते हैं, और CSV से string डेटा को उपयुक्त numeric types में परिवर्तित करने के लिए type conversion methods जैसे `.toInteger()` और `.toDouble()` का उपयोग करते हैं। + +यह परिवर्तन लागू करें और workflow चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Conditional Logic जोड़ना + +अब आइए और scripting जोड़ें - इस बार डेटा मानों के आधार पर निर्णय लेने के लिए एक ternary ऑपरेटर का उपयोग करते हुए। + +निम्नलिखित परिवर्तन करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +Ternary ऑपरेटर एक if/else statement के लिए एक shorthand है जो पैटर्न `condition ? value_if_true : value_if_false` का अनुसरण करता है। इस पंक्ति का अर्थ है: "यदि quality 40 से अधिक है, तो 'high' का उपयोग करें, अन्यथा 'normal' का उपयोग करें"। इसका cousin, **Elvis operator** (`?:`), null या empty होने पर default values प्रदान करता है - हम इस ट्यूटोरियल में बाद में उस पैटर्न का पता लगाएंगे। + +Map addition ऑपरेटर `+` मौजूदा को संशोधित करने के बजाय एक **नया map** बनाता है। यह पंक्ति एक नया map बनाती है जिसमें `sample_meta` के सभी key-value pairs प्लस नई `priority` key होती है। + +!!! Note + + Closures में पास किए गए maps को कभी भी संशोधित न करें - हमेशा `+` (उदाहरण के लिए) का उपयोग करके नए बनाएं। Nextflow में, एक ही डेटा अक्सर एक साथ कई operations के माध्यम से बहता है। In-place में एक map को संशोधित करने से अप्रत्याशित side effects हो सकते हैं जब अन्य operations उसी object को reference करते हैं। नए maps बनाना सुनिश्चित करता है कि प्रत्येक operation की अपनी साफ़ copy है। + +संशोधित workflow चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +हमने quality scores के आधार पर एक priority level के साथ हमारे metadata को enrich करने के लिए conditional logic को सफलतापूर्वक जोड़ा है। + +#### 1.1.5. `.subMap()` के साथ Maps को Subset करना + +जबकि `+` ऑपरेटर एक map में keys जोड़ता है, कभी-कभी आपको विपरीत करने की आवश्यकता होती है - केवल विशिष्ट keys को extract करें। `.subMap()` method इसके लिए बिल्कुल सही है। + +आइए हमारे metadata का एक सरलीकृत संस्करण बनाने के लिए एक पंक्ति जोड़ें जिसमें केवल पहचान फ़ील्ड हों: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // डेटा transformation के लिए Scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "केवल ID फ़ील्ड: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // डेटा transformation के लिए Scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +संशोधित workflow चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + केवल ID फ़ील्ड: [id:sample_001, organism:human, tissue:liver] + केवल ID फ़ील्ड: [id:sample_002, organism:mouse, tissue:brain] + केवल ID फ़ील्ड: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +यह `view()` operation द्वारा प्रदर्शित पूर्ण metadata और extracted subset दोनों को दिखाता है जिसे हमने `println` के साथ प्रिंट किया। + +`.subMap()` method keys की एक सूची लेता है और केवल उन keys वाला एक नया map लौटाता है। यदि मूल map में कोई key मौजूद नहीं है, तो यह बस परिणाम में शामिल नहीं है। + +यह विशेष रूप से उपयोगी है जब आपको विभिन्न processes के लिए विभिन्न metadata versions बनाने की आवश्यकता है - कुछ को पूर्ण metadata की आवश्यकता हो सकती है जबकि अन्य को केवल न्यूनतम पहचान फ़ील्ड की आवश्यकता है। + +अब उन println statements को हटा दें ताकि आपका workflow अपनी पिछली स्थिति में वापस आ जाए, क्योंकि हमें उन्हें आगे बढ़ने की आवश्यकता नहीं है। + +!!! tip "Map Operations सारांश" + + - **Keys जोड़ें**: `map1 + [new_key: value]` - अतिरिक्त keys के साथ नया map बनाता है + - **Keys extract करें**: `map1.subMap(['key1', 'key2'])` - केवल निर्दिष्ट keys के साथ नया map बनाता है + - **दोनों operations नए maps बनाते हैं** - मूल maps अपरिवर्तित रहते हैं + +#### 1.1.6. Maps को संयोजित करना और परिणाम लौटाना + +अब तक, हम केवल वही लौटा रहे थे जिसे Nextflow community 'meta map' कहती है, और हम उन फ़ाइलों को नज़रअंदाज कर रहे थे जिनसे वह metadata संबंधित है। लेकिन यदि आप Nextflow workflows लिख रहे हैं, तो आप शायद उन फ़ाइलों के साथ कुछ करना चाहते हैं। + +आइए 2 तत्वों के एक tuple वाली एक channel संरचना आउटपुट करें: enriched metadata map और संबंधित फ़ाइल पथ। यह processes को डेटा पास करने के लिए Nextflow में एक सामान्य पैटर्न है। + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +यह परिवर्तन लागू करें और workflow चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +यह `[meta, file]` tuple संरचना processes को metadata और संबंधित फ़ाइलों दोनों को पास करने के लिए Nextflow में एक सामान्य पैटर्न है। + +!!! note + + **Maps और Metadata**: Maps Nextflow में metadata के साथ काम करने के लिए मौलिक हैं। Metadata maps के साथ काम करने के अधिक विस्तृत स्पष्टीकरण के लिए, [Working with metadata](./metadata.md) side quest देखें। + +हमारा workflow मुख्य पैटर्न को प्रदर्शित करता है: **dataflow operations** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) यह orchestrate करते हैं कि पाइपलाइन के माध्यम से डेटा कैसे चलता है, जबकि **scripting** (maps `[key: value]`, string methods, type conversions, ternary operators) `.map()` closure के अंदर व्यक्तिगत डेटा आइटम के transformation को संभालता है। + +### 1.2. विभिन्न प्रकारों को समझना: Channel बनाम List + +अब तक, बहुत अच्छा, हम dataflow operations और scripting के बीच अंतर कर सकते हैं। लेकिन क्या होगा जब Nextflow standard library में दोनों संदर्भों में एक ही method का नाम मौजूद हो? + +एक बिल्कुल सही उदाहरण `collect` method है, जो channel types और List types दोनों के लिए मौजूद है। List पर `collect()` method प्रत्येक तत्व को transform करती है, जबकि channel पर `collect()` ऑपरेटर सभी channel emissions को एक single-item channel में इकट्ठा करता है। + +आइए कुछ नमूना डेटा के साथ इसे प्रदर्शित करें, यह देखने के लिए कि channel `collect()` ऑपरेटर क्या करता है। `collect.nf` देखें: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - कई channel emissions को एक में group करता है +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Individual channel item: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } +``` + +चरण: + +- Sample IDs की एक List परिभाषित करें +- `fromList()` के साथ एक channel बनाएं जो प्रत्येक sample ID को अलग से emit करता है +- जैसे यह बहता है, `view()` के साथ प्रत्येक आइटम को प्रिंट करें +- Channel के `collect()` ऑपरेटर के साथ सभी आइटम को एक single list में इकट्ठा करें +- Collected result (सभी sample IDs वाला single आइटम) को एक दूसरे `view()` के साथ प्रिंट करें + +हमने channel की संरचना को बदल दिया है, लेकिन हमने डेटा को स्वयं नहीं बदला है। + +इसकी पुष्टि करने के लिए workflow चलाएं: + +```bash +nextflow run collect.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +`view()` हर channel emission के लिए एक आउटपुट लौटाता है, इसलिए हम जानते हैं कि यह single आउटपुट एक list में grouped सभी 3 मूल आइटम शामिल हैं। + +अब आइए List पर `collect` method को action में देखें। मूल sample IDs की सूची में List के `collect` method को लागू करने के लिए `collect.nf` को संशोधित करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - कई channel emissions को एक में group करता है + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - प्रत्येक तत्व को transform करता है, संरचना को preserve करता है + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - कई channel emissions को एक में group करता है + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + ``` + +इस नए snippet में हम: + +- एक नया वेरिएबल `formatted_ids` परिभाषित करते हैं जो मूल list में प्रत्येक sample ID को transform करने के लिए List के `collect` method का उपयोग करता है +- `println` का उपयोग करके परिणाम को प्रिंट करते हैं + +संशोधित workflow चलाएं: + +```bash +nextflow run collect.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +इस बार, हमने डेटा की संरचना को नहीं बदला है, list में अभी भी 3 आइटम हैं, लेकिन हमने संशोधित मानों के साथ एक नई list बनाने के लिए List के `collect` method का उपयोग करके प्रत्येक आइटम को transform किया है। यह एक channel पर `map` ऑपरेटर का उपयोग करने के समान है, लेकिन यह channel के बजाय एक List डेटा संरचना पर काम कर रहा है। + +`collect` एक चरम मामला है जिसका हम यहाँ एक बिंदु बनाने के लिए उपयोग कर रहे हैं। मुख्य सबक यह है कि जब आप workflows लिख रहे हों, तो हमेशा **डेटा संरचनाओं** (Lists, Maps, आदि) और **channels** (dataflow constructs) के बीच अंतर करें। Operations नाम साझा कर सकते हैं लेकिन जिस type पर उन्हें बुलाया जाता है, उसके आधार पर पूरी तरह से अलग तरीके से व्यवहार कर सकते हैं। + +### 1.3. Spread Operator (`*.`) - प्रॉपर्टी निष्कर्षण के लिए Shorthand + +List के `collect` method से संबंधित spread ऑपरेटर (`*.`) है, जो collections से properties निकालने का एक संक्षिप्त तरीका प्रदान करता है। यह अनिवार्य रूप से एक सामान्य `collect` पैटर्न के लिए syntactic sugar है। + +आइए अपनी `collect.nf` फ़ाइल में एक प्रदर्शन जोड़ें: + +=== "बाद" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - कई channel emissions को एक में group करता है + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - प्रत्येक तत्व को transform करता है, संरचना को preserve करता है + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + + // Spread operator - संक्षिप्त प्रॉपर्टी access + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Spread operator result: ${all_ids}" + ``` + +=== "पहले" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - कई channel emissions को एक में group करता है + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - प्रत्येक तत्व को transform करता है, संरचना को preserve करता है + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +अपडेट किया गया workflow चलाएं: + +```bash title="spread ऑपरेटर को test करें" +nextflow run collect.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Spread operator result: [s1, s2, s3] + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +Spread ऑपरेटर `*.` एक सामान्य collect पैटर्न के लिए एक shorthand है: + +```groovy +// ये समकक्ष हैं: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Method calls के साथ भी काम करता है: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +Spread ऑपरेटर विशेष रूप से उपयोगी है जब आपको objects की एक list से एक single प्रॉपर्टी extract करनी हो - यह पूर्ण `collect` closure लिखने की तुलना में अधिक पठनीय है। + +!!! tip "Spread बनाम Collect का उपयोग कब करें" + + - **Spread (`*.`) का उपयोग करें** साधारण प्रॉपर्टी access के लिए: `samples*.id`, `files*.name` + - **Collect का उपयोग करें** transformations या complex logic के लिए: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### निष्कर्ष + +इस खंड में, आपने सीखा: + +- **Dataflow बनाम scripting**: Channel operators यह orchestrate करते हैं कि आपकी pipeline के माध्यम से डेटा कैसे बहता है, जबकि scripting व्यक्तिगत डेटा आइटम को transform करता है +- **प्रकारों को समझना**: एक ही method का नाम (जैसे `collect`) जिस type पर इसे बुलाया जाता है (Channel बनाम List) के आधार पर अलग तरह से व्यवहार कर सकता है +- **संदर्भ महत्वपूर्ण है**: हमेशा जागरूक रहें कि आप channels (dataflow) या डेटा संरचनाओं (scripting) के साथ काम कर रहे हैं या नहीं + +इन सीमाओं को समझना debugging, documentation, और maintainable workflows लिखने के लिए आवश्यक है। + +अगला हम string processing क्षमताओं में गहराई से जाएंगे, जो वास्तविक दुनिया के डेटा को संभालने के लिए आवश्यक हैं। + +--- + +## 2. स्ट्रिंग प्रोसेसिंग और Dynamic Script Generation + +String processing में महारत हासिल करना नाजुक workflows को मजबूत pipelines से अलग करता है। यह खंड जटिल फ़ाइल नामों को parsing करने, dynamic script generation, और वेरिएबल interpolation को कवर करता है। + +### 2.1. Pattern Matching और Regular Expressions + +Bioinformatics फ़ाइलों में अक्सर जटिल नामकरण सम्मेलन होते हैं जो metadata को encode करते हैं। आइए pattern matching का उपयोग करके regular expressions के साथ इसे automatically extract करें। + +हम अपने `main.nf` workflow में वापस जाने वाले हैं और फ़ाइल नामों से अतिरिक्त नमूना जानकारी extract करने के लिए कुछ pattern matching logic जोड़ने जा रहे हैं। हमारे डेटासेट में FASTQ फ़ाइलें Illumina-style नामकरण सम्मेलनों का पालन करती हैं जिनके नाम `SAMPLE_001_S1_L001_R1_001.fastq.gz` जैसे हैं। ये रहस्यमय लग सकते हैं, लेकिन वे वास्तव में sample ID, lane number, और read direction जैसी उपयोगी metadata को encode करते हैं। हम इन नामों को parse करने के लिए regex क्षमताओं का उपयोग करने जा रहे हैं। + +अपने मौजूदा `main.nf` workflow में निम्नलिखित परिवर्तन करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // डेटा transformation के लिए Scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // डेटा transformation के लिए Scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +यह महत्वपूर्ण **string processing अवधारणाओं** को प्रदर्शित करता है: + +1. `~/pattern/` सिंटैक्स का उपयोग करके **Regular expression literals** - यह backslashes को escape करने की आवश्यकता के बिना एक regex पैटर्न बनाता है +2. `=~` ऑपरेटर के साथ **Pattern matching** - यह एक regex पैटर्न के विरुद्ध एक string को match करने का प्रयास करता है +3. **Matcher objects** जो `[0][1]`, `[0][2]`, आदि के साथ groups को capture करते हैं - `[0]` पूरे match को संदर्भित करता है, `[1]`, `[2]`, आदि parentheses में captured groups को संदर्भित करते हैं + +आइए regex पैटर्न `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$` को break down करें: + +| पैटर्न | Matches | Captures | +| ------------------- | --------------------------------------- | ----------------------------------- | +| `^(.+)` | शुरुआत से sample नाम | Group 1: sample name | +| `_S(\d+)` | Sample number `_S1`, `_S2`, आदि | Group 2: sample number | +| `_L(\d{3})` | Lane number `_L001` | Group 3: lane (3 digits) | +| `_(R[12])` | Read direction `_R1` या `_R2` | Group 4: read direction | +| `_(\d{3})` | Chunk number `_001` | Group 5: chunk (3 digits) | +| `\.fastq(?:\.gz)?$` | फ़ाइल extension `.fastq` या `.fastq.gz` | Captured नहीं (?: non-capturing है) | + +यह metadata को automatically extract करने के लिए Illumina-style नामकरण सम्मेलनों को parse करता है। + +संशोधित workflow चलाएं: + +```bash title="pattern matching को test करें" +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +यह फ़ाइल नामों से enriched metadata को दिखाता है। + +### 2.2. Processes में Dynamic Script Generation + +Process script blocks अनिवार्य रूप से multi-line strings हैं जो shell को pass हो जाते हैं। आप इनपुट विशेषताओं के आधार पर dynamically विभिन्न script strings generate करने के लिए **conditional logic** (if/else, ternary operators) का उपयोग कर सकते हैं। यह विभिन्न इनपुट प्रकारों—जैसे single-end बनाम paired-end sequencing reads—को process definitions को duplicate किए बिना संभालने के लिए आवश्यक है। + +आइए अपने workflow में एक process जोड़ें जो इस पैटर्न को प्रदर्शित करता है। `modules/fastp.nf` खोलें और देखें: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Process इनपुट के रूप में FASTQ फ़ाइलें लेता है और adapters को trim करने और low-quality reads को filter करने के लिए `fastp` tool चलाता है। दुर्भाग्य से, जिस व्यक्ति ने इस process को लिखा, उसने हमारे उदाहरण डेटासेट में single-end reads की अनुमति नहीं दी। आइए इसे अपने workflow में जोड़ें और देखें कि क्या होता है: + +सबसे पहले, अपने `main.nf` workflow की पहली पंक्ति में module को include करें: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +फिर `ch_samples` channel को `FASTP` process से connect करने के लिए `workflow` ब्लॉक को संशोधित करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(. diff --git a/docs/hi/docs/side_quests/ideas/containers.md b/docs/hi/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..2132c578ea --- /dev/null +++ b/docs/hi/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# भाग 1: अधिक कंटेनर + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. कंटेनर इमेज कैसे खोजें या बनाएं + +कुछ सॉफ़्टवेयर डेवलपर्स अपने सॉफ़्टवेयर के लिए कंटेनर इमेज प्रदान करते हैं जो Docker Hub जैसे कंटेनर रजिस्ट्री पर उपलब्ध होते हैं, लेकिन कई नहीं करते। +इस वैकल्पिक अनुभाग में, हम आपको उन टूल्स के लिए कंटेनर इमेज प्राप्त करने के दो तरीके दिखाएंगे जिन्हें आप अपने Nextflow pipelines में उपयोग करना चाहते हैं: Seqera Containers का उपयोग करके और कंटेनर इमेज को स्वयं बनाकर। + +आप `quote` pip पैकेज के लिए कंटेनर इमेज प्राप्त/निर्माण करेंगे, जिसका उपयोग इस अनुभाग के अंत में अभ्यास में किया जाएगा। + +### 1.1. Seqera Containers से कंटेनर इमेज प्राप्त करें + +Seqera Containers एक मुफ्त सेवा है जो pip और conda (bioconda सहित) इंस्टॉल करने योग्य टूल्स के लिए कंटेनर इमेज बनाती है। +[Seqera Containers](https://www.seqera.io/containers/) पर जाएं और `quote` pip पैकेज को खोजें। + +![Seqera Containers](img/seqera-containers-1.png) + +`quote` pip पैकेज के लिए कंटेनर इमेज का अनुरोध करने के लिए "+Add" और फिर "Get Container" पर क्लिक करें। + +![Seqera Containers](img/seqera-containers-2.png) + +यदि यह पहली बार इस पैकेज के इस संस्करण के लिए community कंटेनर बनाया जा रहा है, तो इसे पूरा होने में कुछ मिनट लग सकते हैं। +आपके लिए बनाई गई कंटेनर इमेज के URI (जैसे `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) को कॉपी करने के लिए क्लिक करें। + +अब आप Grace Hopper से एक यादृच्छिक कथन प्राप्त करने के लिए `quote` कमांड चलाने हेतु कंटेनर इमेज का उपयोग कर सकते हैं। + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +आउटपुट: + +```console title="Output" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. कंटेनर इमेज को स्वयं बनाएं + +चलिए `quote` pip पैकेज के लिए कंटेनर इमेज को स्वयं बनाने के लिए Seqera Containers वेबसाइट से कुछ बिल्ड विवरण का उपयोग करें। +Seqera Containers वेबसाइट पर वापस जाएं और "Build Details" बटन पर क्लिक करें। + +पहला आइटम जिसे हम देखेंगे वह `Dockerfile` है, एक प्रकार की स्क्रिप्ट फ़ाइल जिसमें कंटेनर इमेज बनाने के लिए आवश्यक सभी कमांड होते हैं। +हमने नीचे दिए गए Dockerfile में कुछ व्याख्यात्मक टिप्पणियां जोड़ी हैं ताकि आप समझ सकें कि प्रत्येक भाग क्या करता है। + +```Dockerfile title="Dockerfile" +# micromamba बेस docker इमेज से शुरू करें +FROM mambaorg/micromamba:1.5.10-noble +# conda.yml फ़ाइल को कंटेनर में कॉपी करें +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Nextflow के उपयोग के लिए विभिन्न यूटिलिटीज और conda.yml फ़ाइल में पैकेज इंस्टॉल करें +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# कंटेनर को root उपयोगकर्ता के रूप में चलाएं +USER root +# PATH वातावरण वेरिएबल को micromamba इंस्टॉलेशन डायरेक्टरी को शामिल करने के लिए सेट करें +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +दूसरा आइटम जिसे हम देखेंगे वह `conda.yml` फ़ाइल है, जिसमें कंटेनर इमेज में इंस्टॉल किए जाने वाले पैकेजों की सूची होती है। + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +इन फ़ाइलों की सामग्री को `containers/build` डायरेक्टरी में स्थित स्टब्स में कॉपी करें, फिर कंटेनर इमेज को स्वयं बनाने के लिए निम्नलिखित कमांड चलाएं। + +!!! note "नोट" + + हम कंटेनर इमेज को `quote` नाम और `latest` टैग के साथ टैग करने के लिए `-t quote:latest` फ्लैग का उपयोग करते हैं। + हम इस सिस्टम पर इसे चलाते समय कंटेनर इमेज को संदर्भित करने के लिए इस टैग का उपयोग कर सकेंगे। + +```bash +docker build -t quote:latest containers/build +``` + +बनने के बाद, आप अभी बनाई गई कंटेनर इमेज को चला सकते हैं। + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### निष्कर्ष + +आपने अपने Nextflow pipelines में उपयोग करने के लिए किसी टूल के लिए कंटेनर इमेज प्राप्त करने के दो अलग-अलग तरीके सीखे हैं: Seqera Containers का उपयोग करके और कंटेनर इमेज को स्वयं बनाकर। + +### आगे क्या है? + +इस प्रशिक्षण श्रृंखला के [अगले अध्याय](./04_hello_genomics.md) में जारी रखने के लिए आपके पास सब कुछ है। +आप `quote` कंटेनर का उपयोग करके कंप्यूटर/जीवविज्ञान के अग्रदूतों पर उद्धरण प्राप्त करने और `cowsay` कंटेनर का उपयोग करके उन्हें आउटपुट करने के लिए एक वैकल्पिक अभ्यास के साथ भी जारी रख सकते हैं। + +--- + +## 2. गाय को प्रसिद्ध वैज्ञानिकों का उद्धरण बोलवाएं + +इस अनुभाग में कुछ stretch अभ्यास हैं, जो आपने अब तक सीखा है उसका अभ्यास करने के लिए। +इन अभ्यासों को करना प्रशिक्षण के बाद के भागों को समझने के लिए _आवश्यक नहीं_ है, लेकिन यह पता लगाकर कि गाय को प्रसिद्ध वैज्ञानिकों का उद्धरण कैसे बोलवाया जाए, आपकी सीख को मजबूत करने का एक मजेदार तरीका प्रदान करते हैं। + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. getQuote process का उपयोग करने के लिए `hello-containers.nf` स्क्रिप्ट को संशोधित करें + +हमारे पास `containers/data/pioneers.csv` फ़ाइल में कंप्यूटर और जीवविज्ञान के अग्रदूतों की एक सूची है। +उच्च स्तर पर, इस अभ्यास को पूरा करने के लिए आपको यह करना होगा: + +- डिफ़ॉल्ट `params.input_file` को `pioneers.csv` फ़ाइल की ओर इंगित करने के लिए संशोधित करें। +- एक `getQuote` process बनाएं जो प्रत्येक इनपुट के लिए उद्धरण प्राप्त करने के लिए `quote` कंटेनर का उपयोग करता है। +- उद्धरण प्रदर्शित करने के लिए `getQuote` process के आउटपुट को `cowsay` process से कनेक्ट करें। + +`quote` कंटेनर इमेज के लिए, आप या तो पिछले stretch अभ्यास में स्वयं बनाई गई इमेज का उपयोग कर सकते हैं या Seqera Containers से प्राप्त की गई इमेज का उपयोग कर सकते हैं। + +!!! tip "सुझाव" + + आपके getQuote process के `script` ब्लॉक के लिए एक अच्छा विकल्प हो सकता है: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +आप इस अभ्यास का समाधान `containers/solutions/hello-containers-4.1.nf` में पा सकते हैं। + +### 2.2. अपने Nextflow pipeline को `quote` और `sayHello` मोड में निष्पादित होने की अनुमति देने के लिए संशोधित करें। + +अपने pipeline में कुछ branching तर्क जोड़ें ताकि यह `quote` और `sayHello` दोनों के लिए इच्छित इनपुट स्वीकार कर सके। +यहां Nextflow workflow में `if` स्टेटमेंट का उपयोग कैसे करें इसका एक उदाहरण है: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "सुझाव" + + आप किसी process के आउटपुट channel को एक नाम असाइन करने के लिए `new_ch = processName.out` का उपयोग कर सकते हैं। + +आप इस अभ्यास का समाधान `containers/solutions/hello-containers-4.2.nf` में पा सकते हैं। + +### निष्कर्ष + +आप जानते हैं कि processes चलाने के लिए Nextflow में कंटेनर का उपयोग कैसे करें, और अपने pipelines में कुछ branching तर्क कैसे बनाएं! + +### आगे क्या है? + +जश्न मनाएं, एक stretch ब्रेक लें और कुछ पानी पिएं! + +जब आप तैयार हों, तो इस प्रशिक्षण श्रृंखला के भाग 3 पर जाएं ताकि आप सीख सकें कि अब तक आपने जो सीखा है उसे अधिक यथार्थवादी डेटा विश्लेषण उपयोग मामले पर कैसे लागू करें। diff --git a/docs/hi/docs/side_quests/ideas/if_else.md b/docs/hi/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..88a964c8a1 --- /dev/null +++ b/docs/hi/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# भाग 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. गाय को प्रसिद्ध वैज्ञानिकों के उद्धरण बुलवाएं + +इस खंड में कुछ अतिरिक्त अभ्यास हैं, जो आपने अब तक जो सीखा है उसका अभ्यास करने के लिए। +इन अभ्यासों को करना प्रशिक्षण के बाद के भागों को समझने के लिए _आवश्यक नहीं_ है, लेकिन यह गाय को प्रसिद्ध वैज्ञानिकों के उद्धरण बुलवाने का तरीका सीखकर अपनी शिक्षा को मजबूत करने का एक मजेदार तरीका प्रदान करता है। + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. `hello-containers.nf` स्क्रिप्ट को getQuote प्रोसेस का उपयोग करने के लिए संशोधित करें + +हमारे पास `containers/data/pioneers.csv` फ़ाइल में कंप्यूटर और जीव विज्ञान के अग्रदूतों की एक सूची है। +उच्च स्तर पर, इस अभ्यास को पूरा करने के लिए आपको निम्नलिखित करना होगा: + +- डिफ़ॉल्ट `params.input_file` को `pioneers.csv` फ़ाइल की ओर इंगित करने के लिए संशोधित करें। +- एक `getQuote` process बनाएं जो प्रत्येक इनपुट के लिए उद्धरण लाने के लिए `quote` कंटेनर का उपयोग करे। +- `getQuote` process के आउटपुट को `cowsay` process से कनेक्ट करें ताकि उद्धरण प्रदर्शित हो सके। + +`quote` कंटेनर इमेज के लिए, आप या तो पिछले अतिरिक्त अभ्यास में स्वयं बनाई गई इमेज का उपयोग कर सकते हैं या Seqera Containers से प्राप्त की गई इमेज का उपयोग कर सकते हैं। + +!!! Hint + + आपके getQuote process के `script` ब्लॉक के लिए एक अच्छा विकल्प हो सकता है: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +आप इस अभ्यास का समाधान `containers/solutions/hello-containers-4.1.nf` में पा सकते हैं। + +### 1.2. अपनी Nextflow पाइपलाइन को `quote` और `sayHello` मोड में निष्पादित करने की अनुमति देने के लिए संशोधित करें। + +अपनी पाइपलाइन में शाखा तर्क जोड़ें ताकि यह `quote` और `sayHello` दोनों के लिए इच्छित इनपुट स्वीकार कर सके। +यहाँ Nextflow workflow में `if` स्टेटमेंट का उपयोग करने का एक उदाहरण है: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + आप किसी process के आउटपुट channel को नाम देने के लिए `new_ch = processName.out` का उपयोग कर सकते हैं। + +आप इस अभ्यास का समाधान `containers/solutions/hello-containers-4.2.nf` में पा सकते हैं। + +### निष्कर्ष + +आप जानते हैं कि प्रोसेस चलाने के लिए Nextflow में कंटेनर का उपयोग कैसे करें, और अपनी पाइपलाइन में कुछ शाखा तर्क कैसे बनाएं! + +### आगे क्या? + +जश्न मनाएं, थोड़ा ब्रेक लें और पानी पिएं! + +जब आप तैयार हों, तो इस प्रशिक्षण श्रृंखला के भाग 3 पर जाएं और सीखें कि आपने अब तक जो सीखा है उसे अधिक यथार्थवादी डेटा विश्लेषण उपयोग के मामले में कैसे लागू करें। diff --git a/docs/hi/docs/side_quests/index.md b/docs/hi/docs/side_quests/index.md new file mode 100644 index 0000000000..a0c4ed5543 --- /dev/null +++ b/docs/hi/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: साइड क्वेस्ट +hide: + - toc +--- + +# साइड क्वेस्ट + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह स्वतंत्र प्रशिक्षण मिनी-कोर्स का संग्रह है जो विशिष्ट विषयों में गहराई से जाते हैं। आप इन्हें किसी भी क्रम में पूरा कर सकते हैं। + +आइए शुरू करें! प्रशिक्षण वातावरण लॉन्च करने के लिए नीचे "Open in GitHub Codespaces" बटन पर क्लिक करें (अधिमानतः एक अलग टैब में), फिर इसके लोड होने के दौरान पढ़ें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## पूर्वापेक्षाएँ + +प्रत्येक मिनी-कोर्स की विशिष्ट पूर्वापेक्षाएँ अलग-अलग हैं और संबंधित पेजों में प्रलेखित हैं। +फिर भी, वे सभी निम्नलिखित के साथ कुछ न्यूनतम परिचितता मानते हैं: + +- कमांड लाइन के साथ अनुभव +- [Hello Nextflow](../../hello_nextflow/) शुरुआती प्रशिक्षण कोर्स में शामिल बुनियादी Nextflow अवधारणाएँ और टूलिंग। + +तकनीकी आवश्यकताओं और वातावरण सेटअप के लिए, [Environment Setup](../../envsetup/) मिनी-कोर्स देखें। + +**यदि आप पहली बार साइड क्वेस्ट में प्रवेश कर रहे हैं, तो पहले [Orientation](./orientation.md) पेज अवश्य देखें!** + +अन्यथा, नीचे दी गई तालिका से एक साइड क्वेस्ट चुनें। + +## साइड क्वेस्ट + +| साइड क्वेस्ट | शिक्षण के लिए अनुमानित समय | +| -------------------------------------------------------------------------- | -------------------------- | +| [Nextflow development environment walkthrough](./ide_features.md) | 45 मिनट | +| [Essential Nextflow Scripting Patterns](./essential_scripting_patterns.md) | 90 मिनट | +| [Metadata in workflows](./metadata.md) | 45 मिनट | +| [Splitting and Grouping](./splitting_and_grouping.md) | 45 मिनट | +| [Testing with nf-test](./nf-test.md) | 1 घंटा | +| [Workflows of workflows](./workflows_of_workflows.md) | 30 मिनट | +| [Working with files](./working_with_files.md) | 45 मिनट | +| [Debugging workflows](./debugging.md) | 1 घंटा | + +हमें बताएं कि आप यहाँ किन अन्य डोमेन और उपयोग के मामलों को शामिल देखना चाहेंगे, कम्युनिटी फोरम के [Training section](https://community.seqera.io/c/training/) में पोस्ट करके। diff --git a/docs/hi/docs/side_quests/metadata.md b/docs/hi/docs/side_quests/metadata.md new file mode 100644 index 0000000000..f3851bd9ab --- /dev/null +++ b/docs/hi/docs/side_quests/metadata.md @@ -0,0 +1,888 @@ +# मेटाडेटा और मेटा मैप्स + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +किसी भी वैज्ञानिक विश्लेषण में, हम शायद ही कभी केवल कच्ची डेटा फ़ाइलों के साथ काम करते हैं। +प्रत्येक फ़ाइल अपनी अतिरिक्त जानकारी के साथ आती है: यह क्या है, यह कहाँ से आई, और इसे क्या खास बनाता है। +इस अतिरिक्त जानकारी को हम मेटाडेटा कहते हैं। + +मेटाडेटा अन्य डेटा का वर्णन करने वाला डेटा है। +मेटाडेटा फ़ाइलों और प्रयोगात्मक स्थितियों के बारे में महत्वपूर्ण विवरण ट्रैक करता है, और प्रत्येक डेटासेट की अनूठी विशेषताओं के अनुसार विश्लेषण को तैयार करने में मदद करता है। + +इसे एक लाइब्रेरी कैटलॉग की तरह समझें: जबकि पुस्तकों में वास्तविक सामग्री (कच्चा डेटा) होती है, कैटलॉग कार्ड प्रत्येक पुस्तक के बारे में आवश्यक जानकारी प्रदान करते हैं—यह कब प्रकाशित हुई थी, इसे किसने लिखा, इसे कहाँ खोजें (मेटाडेटा)। +Nextflow pipelines में, मेटाडेटा का उपयोग निम्न के लिए किया जा सकता है: + +- पूरे workflow में फ़ाइल-विशिष्ट जानकारी को ट्रैक करना +- फ़ाइल विशेषताओं के आधार पर processes को कॉन्फ़िगर करना +- संयुक्त विश्लेषण के लिए संबंधित फ़ाइलों को समूहित करना + +### सीखने के लक्ष्य + +इस side quest में, हम workflows में मेटाडेटा को संभालने का तरीका जानेंगे। +बुनियादी फ़ाइल जानकारी वाली एक साधारण datasheet (जिसे अक्सर bioinformatics में samplesheet कहा जाता है) से शुरू करते हुए, आप सीखेंगे कि कैसे: + +- CSV फ़ाइलों से फ़ाइल मेटाडेटा पढ़ें और पार्स करें +- मेटाडेटा मैप्स बनाएं और उनमें परिवर्तन करें +- workflow निष्पादन के दौरान नए मेटाडेटा फ़ील्ड जोड़ें +- process व्यवहार को अनुकूलित करने के लिए मेटाडेटा का उपयोग करें + +ये कौशल आपको अधिक मजबूत और लचीली pipelines बनाने में मदद करेंगे जो जटिल फ़ाइल संबंधों और प्रोसेसिंग आवश्यकताओं को संभाल सकते हैं। + +### पूर्वापेक्षाएँ + +इस side quest को शुरू करने से पहले, आपको: + +- [Hello Nextflow](../hello_nextflow/README.md) tutorial या समकक्ष beginner's course पूरा किया होना चाहिए। +- बुनियादी Nextflow अवधारणाओं और तंत्रों (processes, channels, operators) का उपयोग करने में सहज होना चाहिए + +--- + +## 0. शुरुआत करें + +#### प्रशिक्षण codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित प्रशिक्षण वातावरण को खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएं + +आइए उस डायरेक्टरी में चलें जहाँ इस tutorial के लिए फ़ाइलें स्थित हैं। + +```bash +cd side-quests/metadata +``` + +आप VSCode को इस डायरेक्टरी पर फ़ोकस करने के लिए सेट कर सकते हैं: + +```bash +code . +``` + +#### सामग्री की समीक्षा करें + +आपको एक मुख्य workflow फ़ाइल और एक `data` डायरेक्टरी मिलेगी जिसमें एक datasheet और कुछ डेटा फ़ाइलें हैं। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +`main.nf` फ़ाइल में workflow एक stub है जिसे आप धीरे-धीरे एक पूर्ण रूप से कार्यशील workflow में विस्तारित करेंगे। + +datasheet डेटा फ़ाइलों के paths और कुछ संबंधित मेटाडेटा को सूचीबद्ध करती है, जो 3 columns में व्यवस्थित हैं: + +- `id`: स्व-व्याख्यात्मक, फ़ाइल को दी गई एक ID +- `character`: एक character नाम, जिसका उपयोग हम बाद में विभिन्न creatures बनाने के लिए करेंगे +- `data`: `.txt` फ़ाइलों के paths जिनमें विभिन्न भाषाओं में अभिवादन शामिल हैं + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +प्रत्येक डेटा फ़ाइल में पाँच भाषाओं (fr: French, de: German, es: Spanish, it: Italian, en: English) में से एक में कुछ अभिवादन text शामिल है। + +हम आपको `langid` नामक एक containerized भाषा विश्लेषण tool भी प्रदान करेंगे। + +#### असाइनमेंट की समीक्षा करें + +आपकी चुनौती एक Nextflow workflow लिखना है जो: + +1. प्रत्येक फ़ाइल में भाषा को स्वचालित रूप से **पहचानेगा** +2. फ़ाइलों को भाषा परिवार (Germanic बनाम Romance languages) द्वारा **समूहित** करेगा +3. प्रत्येक फ़ाइल के लिए उसकी भाषा और मेटाडेटा के आधार पर processing को **अनुकूलित** करेगा +4. outputs को भाषा समूह द्वारा **व्यवस्थित** करेगा + +यह एक विशिष्ट workflow pattern का प्रतिनिधित्व करता है जहाँ फ़ाइल-विशिष्ट मेटाडेटा processing निर्णयों को संचालित करता है; बिल्कुल वैसी ही समस्या जिसे मेटाडेटा मैप्स सुंदरता से हल करते हैं। + +#### तैयारी checklist + +क्या आपको लगता है कि आप शुरू करने के लिए तैयार हैं? + +- [ ] मैं इस course के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता हूँ +- [ ] मेरा codespace चालू है और चल रहा है +- [ ] मैंने अपनी working डायरेक्टरी को उचित रूप से सेट कर लिया है +- [ ] मैं असाइनमेंट को समझता हूँ + +यदि आप सभी boxes को चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. datasheet से मेटाडेटा लोड करें + +`main.nf` workflow फ़ाइल खोलें और workflow stub की जाँच करें जो हम आपको शुरुआती बिंदु के रूप में दे रहे हैं। + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +आप देख सकते हैं कि हमने उदाहरण datasheet को फ़ाइल के रूप में लोड करने के लिए एक बुनियादी channel factory सेट अप किया है, लेकिन यह अभी तक फ़ाइल की सामग्री नहीं पढ़ेगा। +आइए इसे जोड़कर शुरू करें। + +### 1.1. `splitCsv` के साथ सामग्री पढ़ें + +हमें एक ऑपरेटर चुनने की आवश्यकता है जो हमारी ओर से न्यूनतम प्रयास के साथ फ़ाइल सामग्री को उचित रूप से पार्स करे। +चूंकि हमारी datasheet CSV format में है, यह [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv) ऑपरेटर के लिए एक काम है, जो फ़ाइल में प्रत्येक पंक्ति को channel में एक तत्व के रूप में लोड करता है। + +channel निर्माण कोड में `splitCsv()` operation जोड़ने के लिए निम्नलिखित परिवर्तन करें, साथ ही यह जांचने के लिए `view()` operation भी कि फ़ाइल की सामग्री channel में सही ढंग से लोड हो रही है। + +=== "बाद में" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +ध्यान दें कि हम Nextflow को CSV फ़ाइल की पहली पंक्ति को header पंक्ति के रूप में पढ़ने के लिए `header: true` option का उपयोग कर रहे हैं। + +आइए देखें कि इससे क्या निकलता है, ठीक है? +workflow चलाएँ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +हम देख सकते हैं कि ऑपरेटर ने CSV फ़ाइल में प्रत्येक पंक्ति के लिए key-value pairs का एक map बनाया है, जिसमें संबंधित values के लिए keys के रूप में column headers हैं। + +प्रत्येक map entry हमारी datasheet में एक column से मेल खाती है: + +- `id` +- `character` +- `recording` + +यह बहुत बढ़िया है! यह प्रत्येक फ़ाइल से विशिष्ट फ़ील्ड्स तक पहुँचना आसान बनाता है। +उदाहरण के लिए, हम `id` के साथ फ़ाइल ID या `recording` के साथ txt फ़ाइल path तक पहुँच सकते हैं। + +??? info "(वैकल्पिक) मैप्स के बारे में अधिक" + + Groovy में, प्रोग्रामिंग भाषा जिस पर Nextflow बना है, एक map एक key-value डेटा structure है जो Python में dictionaries, JavaScript में objects, या Ruby में hashes के समान है। + + यहाँ एक runnable script है जो दिखाता है कि आप व्यवहार में एक map कैसे परिभाषित कर सकते हैं और इसकी सामग्री तक कैसे पहुँच सकते हैं: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // एक साधारण map बनाएं + def my_map = [id:'sampleA', character:'squirrel'] + + // पूरा map प्रिंट करें + println "map: ${my_map}" + + // dot notation का उपयोग करके व्यक्तिगत values तक पहुँचें + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + भले ही इसमें एक उचित `workflow` block नहीं है, Nextflow इसे workflow के रूप में चला सकता है: + + ```bash + nextflow run examples/map_demo.nf + ``` + + और यहाँ आउटपुट में आप क्या देखने की उम्मीद कर सकते हैं: + + ```console title="आउटपुट" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. `map` के साथ विशिष्ट फ़ील्ड्स चुनें + +मान लीजिए हम datasheet से `character` column तक पहुँचना और इसे प्रिंट करना चाहते हैं। +हम अपने channel में प्रत्येक item पर iterate करने और विशेष रूप से map object से `character` entry चुनने के लिए Nextflow `map` ऑपरेटर का उपयोग कर सकते हैं। + +workflow में निम्नलिखित संपादन करें: + +=== "बाद में" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +अब फिर से workflow चलाएँ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +सफलता! हमने प्रत्येक पंक्ति के लिए व्यक्तिगत columns से values तक पहुँचने के लिए अपनी datasheet से प्राप्त map structure का लाभ उठाया है। + +अब जब हमने सफलतापूर्वक datasheet पढ़ ली है और प्रत्येक पंक्ति में डेटा तक पहुँच है, तो हम अपनी pipeline logic को लागू करना शुरू कर सकते हैं। + +### 1.3. मेटाडेटा को 'meta map' में व्यवस्थित करें + +workflow की वर्तमान स्थिति में, इनपुट फ़ाइलें (`recording` key के तहत) और संबंधित मेटाडेटा (`id`, `character`) सभी एक ही स्तर पर हैं, जैसे वे सभी एक बड़े bag में हैं। +व्यावहारिक परिणाम यह है कि इस channel का उपभोग करने वाले प्रत्येक process को इस structure को ध्यान में रखते हुए configure करने की आवश्यकता होगी: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +यह ठीक है जब तक datasheet में columns की संख्या नहीं बदलती। +हालांकि, यदि आप datasheet में केवल एक column जोड़ते हैं, तो channel का आकार उस से मेल नहीं खाएगा जो process उम्मीद करता है, और workflow त्रुटियाँ उत्पन्न करेगा। +यह process को दूसरों के साथ साझा करना भी मुश्किल बनाता है जिनके पास थोड़ा अलग इनपुट डेटा हो सकता है, और आपको variables को process में hard-code करना पड़ सकता है जो script block द्वारा आवश्यक नहीं हैं। + +इस समस्या से बचने के लिए, हमें channel structure को consistent रखने का एक तरीका खोजने की आवश्यकता है, भले ही उस datasheet में कितने columns हों। + +हम सभी मेटाडेटा को tuple के भीतर एक item में एकत्र करके ऐसा कर सकते हैं, जिसे हम मेटाडेटा map, या अधिक सरलता से 'meta map' कहेंगे। + +`map` operation में निम्नलिखित संपादन करें: + +=== "बाद में" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +हमने अपने channel elements को दो तत्वों, meta map और संबंधित फ़ाइल object से मिलकर बने tuple में पुनर्गठित किया है। + +आइए workflow चलाएँ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console title="meta map देखें" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +अब, channel में प्रत्येक तत्व में मेटाडेटा map पहले और संबंधित फ़ाइल object दूसरे स्थान पर है: + +```console title="उदाहरण आउटपुट structure" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +परिणामस्वरूप, datasheet में अधिक columns जोड़ने से `meta` map में अधिक मेटाडेटा उपलब्ध होगा, लेकिन channel का आकार नहीं बदलेगा। +यह हमें ऐसी processes लिखने में सक्षम बनाता है जो channel का उपभोग करते हैं बिना मेटाडेटा items को इनपुट specification में hard-code किए: + +```groovy title="Syntax उदाहरण" + input: + tuple val(meta), file(recording) +``` + +यह Nextflow workflows में मेटाडेटा को व्यवस्थित करने के लिए व्यापक रूप से उपयोग किया जाने वाला convention है। + +### मुख्य बातें + +इस खंड में, आपने सीखा: + +- **मेटाडेटा क्यों महत्वपूर्ण है:** अपने डेटा के साथ मेटाडेटा रखने से पूरे workflow में महत्वपूर्ण फ़ाइल जानकारी संरक्षित होती है। +- **datasheets को कैसे पढ़ें:** header जानकारी के साथ CSV फ़ाइलों को पढ़ने और पंक्तियों को structured डेटा में transform करने के लिए `splitCsv` का उपयोग करना +- **meta map कैसे बनाएं:** tuple structure `[ [id:value, ...], file ]` का उपयोग करके फ़ाइल डेटा से मेटाडेटा को अलग करना + +--- + +## 2. मेटाडेटा में परिवर्तन करना + +अब जब हमारा मेटाडेटा लोड हो गया है, तो आइए इसके साथ कुछ करें! + +हम प्रत्येक creature की recording फ़ाइल में निहित भाषा की पहचान करने के लिए [`langid`](https://github.com/saffsd/langid.py) नामक एक tool का उपयोग करने जा रहे हैं। +यह tool भाषाओं के एक सेट पर पूर्व-प्रशिक्षित आता है, और text का एक snippet दिए जाने पर, यह एक भाषा prediction और एक संबंधित probability score दोनों को `stdout` में आउटपुट करेगा। + +### 2.1. process को import करें और कोड की जाँच करें + +हम आपको `IDENTIFY_LANGUAGE` नामक एक पूर्व-लिखित process मॉड्यूल प्रदान करते हैं जो `langid` tool को wrap करता है, इसलिए आपको workflow block से पहले केवल एक include statement जोड़ने की आवश्यकता है। + +workflow में निम्नलिखित संपादन करें: + +=== "बाद में" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +आप इसके कोड की जाँच करने के लिए मॉड्यूल फ़ाइल खोल सकते हैं: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// प्रत्येक इनपुट फ़ाइल की भाषा की भविष्यवाणी करने के लिए langid का उपयोग करें +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +जैसा कि आप देख सकते हैं, इनपुट definition उसी `tuple val(meta), path(file)` structure का उपयोग करता है जिसे हमने अभी अपने इनपुट channel पर लागू किया था। + +आउटपुट definition एक tuple के रूप में structured है जिसमें इनपुट के समान structure है, सिवाय इसके कि इसमें तीसरे तत्व के रूप में `stdout` भी है। +यह `tuple val(meta), path(file), <output>` pattern मेटाडेटा को इनपुट डेटा और outputs दोनों से जुड़ा रखता है क्योंकि यह pipeline के माध्यम से प्रवाहित होता है। + +ध्यान दें कि हम यहाँ Nextflow के [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) आउटपुट qualifier का उपयोग कर रहे हैं क्योंकि tool अपने आउटपुट को फ़ाइल लिखने के बजाय सीधे console पर print करता है; और हम probability score को हटाने, newline characters को हटाकर string को साफ करने, और केवल भाषा prediction वापस करने के लिए कमांड लाइन में `sed` का उपयोग करते हैं। + +### 2.2. `IDENTIFY_LANGUAGE` की call जोड़ें + +अब जब process workflow के लिए उपलब्ध है, तो हम डेटा channel पर इसे चलाने के लिए `IDENTIFY_LANGUAGE` process में एक call जोड़ सकते हैं। + +workflow में निम्नलिखित संपादन करें: + +=== "बाद में" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // प्रत्येक अभिवादन की भाषा पहचानने के लिए langid चलाएँ + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +ध्यान दें कि हमने channel निर्माण में मूल `.view()` operation हटा दिया है। + +अब हम workflow चला सकते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +उत्कृष्ट! अब हमारे पास इस बात की prediction है कि प्रत्येक character कौन सी भाषा बोलता है। + +और जैसा कि पहले उल्लेख किया गया है, हमने आउटपुट में इनपुट फ़ाइल और meta map भी शामिल किया है, जिसका अर्थ है कि दोनों नई जानकारी के साथ जुड़े रहते हैं जो हमने अभी उत्पन्न की है। +यह अगले चरण में उपयोगी साबित होगा। + +!!! note + + अधिक सामान्यतः, meta map को results से जुड़ा रखने का यह pattern संबंधित results को जोड़ना आसान बनाता है जो समान identifiers साझा करते हैं। + + जैसा कि आप पहले ही सीख चुके होंगे, आप results को उनके बीच match करने के लिए channels में items के क्रम पर भरोसा नहीं कर सकते। + इसके बजाय, आपको डेटा को सही ढंग से जोड़ने के लिए keys का उपयोग करना चाहिए, और meta maps इस उद्देश्य के लिए एक आदर्श structure प्रदान करते हैं। + + हम [Splitting & Grouping](./splitting_and_grouping.md) side quest में इस use case का विस्तार से पता लगाते हैं। + +### 2.3. process outputs के साथ मेटाडेटा बढ़ाएं + +यह देखते हुए कि हमने अभी जो परिणाम उत्पन्न किए हैं वे स्वयं फ़ाइलों की सामग्री के बारे में मेटाडेटा का एक रूप हैं, उन्हें हमारे meta map में जोड़ना उपयोगी होगा। + +हालाँकि, हम मौजूदा meta map को स्थान पर संशोधित नहीं करना चाहते। +तकनीकी दृष्टिकोण से, ऐसा करना _संभव_ है, लेकिन यह असुरक्षित है। + +इसलिए इसके बजाय, हम एक नया meta map बनाएंगे जिसमें मौजूदा meta map की सामग्री और एक नई `lang: lang_id` key-value pair होगी जो नई जानकारी रखेगी, `+` ऑपरेटर (एक Groovy feature) का उपयोग करते हुए। +और हम इसे एक [`map`](https://www.nextflow.io/docs/latest/operator.html#map) operation के साथ जोड़ेंगे ताकि पुराने map को नए से बदल सकें। + +यहाँ वे संपादन हैं जो आपको workflow में करने की आवश्यकता है: + +=== "बाद में" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // प्रत्येक अभिवादन की भाषा पहचानने के लिए langid चलाएँ + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // प्रत्येक अभिवादन की भाषा पहचानने के लिए langid चलाएँ + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +यदि आप अभी तक `+` ऑपरेटर से परिचित नहीं हैं, या यदि यह भ्रमित लगता है, तो नीचे दिए गए विस्तृत स्पष्टीकरण को पढ़ने में कुछ मिनट लगाएं। + +??? info "`+` ऑपरेटर का उपयोग करके नए meta map का निर्माण" + + **सबसे पहले, आपको जानना होगा कि हम Groovy ऑपरेटर `+` का उपयोग करके दो maps की सामग्री को merge कर सकते हैं।** + + मान लीजिए हमारे पास निम्नलिखित maps हैं: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + हम उन्हें इस तरह merge कर सकते हैं: + + ```groovy + new_map = map1 + map2 + ``` + + `new_map` की सामग्री होगी: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + बढ़िया! + + **लेकिन अगर आपको एक ऐसा फ़ील्ड जोड़ने की आवश्यकता है जो पहले से ही map का हिस्सा नहीं है तो क्या होगा?** + + मान लीजिए आप फिर से `map1` से शुरू करते हैं, लेकिन भाषा prediction अपने map में नहीं है (कोई `map2` नहीं है)। + इसके बजाय, यह `lang_id` नामक एक variable में है, और आप जानते हैं कि आप इसके value (`'fr'`) को key `lang` के साथ store करना चाहते हैं। + + आप वास्तव में निम्नलिखित कर सकते हैं: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + यहाँ, `[lang: new_info]` तुरंत एक नया unnamed map बनाता है, और `map1 + ` `map1` को नए unnamed map के साथ merge करता है, जो पहले की तरह समान `new_map` सामग्री उत्पन्न करता है। + + साफ़, है ना? + + **अब आइए इसे Nextflow `channel.map()` operation के संदर्भ में transpose करें।** + + कोड बन जाता है: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + यह निम्नलिखित करता है: + + - `map1, lang_id ->` tuple में दो items लेता है + - `[map1 + [lang: lang_id]]` ऊपर विस्तृत रूप से नया map बनाता है + + आउटपुट एक single unnamed map है जिसकी सामग्री हमारे ऊपर के उदाहरण में `new_map` के समान है। + इसलिए हमने प्रभावी रूप से परिवर्तित किया है: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + में: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + उम्मीद है कि आप देख सकते हैं कि यदि हम `map1` को `meta` में बदलते हैं, तो मूल रूप से हमारे workflow में हमारे meta map में भाषा predication जोड़ने के लिए यही सब हमें चाहिए। + + एक चीज़ के अलावा! + + हमारे workflow के मामले में, **हमें tuple में `file` object की उपस्थिति के लिए भी account करने की आवश्यकता है**, जो `meta, file, lang_id` से बना है। + + तो यहाँ कोड बन जाएगा: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + यदि आपको यह समझने में कठिनाई हो रही है कि `file` `map` operation में क्यों घूम रहा है, तो कल्पना करें कि `[meta + [lang: lang_id], file]` के बजाय, वह लाइन `[new_map, file]` पढ़ती है। + इससे यह अधिक स्पष्ट होना चाहिए कि हम केवल `file` को tuple में दूसरी position में अपनी मूल जगह पर छोड़ रहे हैं। हमने बस `new_info` value लिया है और इसे map में fold कर दिया है जो पहली position में है। + + **और यह हमें वापस `tuple val(meta), path(file)` channel structure पर लाता है!** + +एक बार जब आपको विश्वास हो जाए कि आप समझ गए हैं कि यह कोड क्या कर रहा है, तो यह देखने के लिए workflow चलाएं कि यह काम किया या नहीं: + +```bash +nextflow run main.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +हाँ, यह सही है! +हमने process के आउटपुट को `meta, file, lang_id` से साफ़ तरीके से पुनर्गठित कर दिया है ताकि `lang_id` अब meta map में keys में से एक हो, और channel के tuples फिर से `meta, file` model के अनुरूप हों। + +<!-- TODO (future) क्या हमें यह भी दिखाना चाहिए कि subMap का उपयोग करके key कैसे हटाएं?! या नोट करें कि यह कहाँ मिलेगा। --> + +### 2.4. conditionals का उपयोग करके भाषा समूह असाइन करें + +अब जब हमारे पास हमारी भाषा predictions हैं, तो आइए कुछ नए groupings असाइन करने के लिए जानकारी का उपयोग करें। + +हमारे उदाहरण डेटा में, हमारे characters द्वारा उपयोग की जाने वाली भाषाओं को germanic languages (English, German) और romance language (French, Spanish, Italian) में समूहीकृत किया जा सकता है। +यह classification बाद में pipeline में कहीं आसानी से उपलब्ध होना उपयोगी हो सकता है, तो आइए उस जानकारी को meta map में जोड़ें। + +और, अच्छी खबर है, यह एक और मामला है जो `map` ऑपरेटर का उपयोग करने के लिए पूरी तरह से उपयुक्त है! + +विशेष रूप से, हम `lang_group` नामक एक variable परिभाषित करने जा रहे हैं, डेटा के प्रत्येक टुकड़े के लिए `lang_group` को क्या value असाइन करनी है यह निर्धारित करने के लिए कुछ साधारण conditional logic का उपयोग करेंगे। + +सामान्य syntax इस तरह दिखने वाली है: + +```groovy +.map { meta, file -> + + // यहाँ lang_group को परिभाषित करने वाली conditional logic जाती है + + [meta + [lang_group: lang_group], file] +} +``` + +आप देख सकते हैं कि यह पिछले चरण में हमने उपयोग किए गए on-the-fly map merging operation के समान है। +हमें बस conditional statements लिखने की आवश्यकता है। + +यहाँ conditional logic है जो हम लागू करना चाहते हैं: + +- default value `'unknown'` के साथ `lang_group` नामक एक variable परिभाषित करें। +- यदि `lang` German (`'de'`) या English (`'en'`) है, तो `lang_group` को `germanic` में बदलें। +- अन्यथा यदि `lang` French (`'fr'`), Spanish (`'es'`) और Italian (`'it'`) युक्त सूची में शामिल है, तो `lang_group` को `romance` में बदलें। + +यदि आप पहले से ही जानते हैं कि Nextflow में conditional statements कैसे लिखें तो इसे स्वयं लिखने का प्रयास करें। + +!!! tip + + आप map operation के भीतर `meta.lang` के साथ `lang` के value तक पहुँच सकते हैं। + +आपको workflow में निम्नलिखित परिवर्तन करने चाहिए: + +=== "बाद में" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // प्रत्येक अभिवादन की भाषा पहचानने के लिए langid चलाएँ + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // प्रत्येक अभिवादन की भाषा पहचानने के लिए langid चलाएँ + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +यहाँ मुख्य बिंदु हैं: + +- हम `lang_group` variable बनाने के लिए `def lang_group = "unknown"` का उपयोग करते हैं जिसकी default value `unknown` पर सेट है। +- हम conditional logic के लिए `if {} else if {}` structure का उपयोग करते हैं, दो germanic भाषाओं के लिए वैकल्पिक `.equals()` tests के साथ, और तीन romance भाषाओं के लिए सूची में अस्तित्व के लिए एक test के साथ। +- हम updated meta map generate करने के लिए पहले की तरह `meta + [lang_group:lang_group]` merge operation का उपयोग करते हैं। + +<!-- TODO (future) अतिरिक्त संसाधन अनुभाग में संबंधित docs के लिए नोट/लिंक जोड़ें --> + +एक बार जब यह सब समझ में आ जाए, तो परिणाम देखने के लिए फिर से workflow चलाएँ: + +```bash +nextflow run main.nf -resume +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +जैसा कि आप देख सकते हैं, channel elements अपनी `[meta, file]` structure बनाए रखते हैं, लेकिन meta map में अब यह नया classification शामिल है। + +### मुख्य बातें + +इस खंड में, आपने सीखा कि कैसे: + +- **आउटपुट channels में इनपुट मेटाडेटा लागू करें**: इस तरह से मेटाडेटा कॉपी करने से हम बाद में मेटाडेटा सामग्री के आधार पर results को जोड़ सकते हैं। +- **कस्टम keys बनाएँ**: आपने अपने meta map में दो नई keys बनाईं, उन्हें `meta + [new_key:value]` के साथ मौजूदा meta map में merge करते हुए। एक process से computed value के आधार पर, और एक आपके द्वारा `map` ऑपरेटर में सेट की गई condition के आधार पर। + +ये आपको अपनी pipeline में आगे बढ़ते समय फ़ाइलों के साथ नए और मौजूदा मेटाडेटा को जोड़ने की अनुमति देते हैं। +भले ही आप process के हिस्से के रूप में मेटाडेटा का उपयोग नहीं कर रहे हों, इस तरह से meta map को डेटा से जुड़ा रखने से सभी प्रासंगिक जानकारी को एक साथ रखना आसान हो जाता है। + +--- + +## 3. process में meta map जानकारी का उपयोग करना + +अब जब आप जानते हैं कि meta map कैसे बनाएं और update करें, तो हम वास्तव में मज़ेदार बिट पर आ सकते हैं: वास्तव में process में मेटाडेटा का उपयोग करना। + +अधिक विशेष रूप से, हम अपने workflow में एक दूसरा चरण जोड़ने जा रहे हैं ताकि प्रत्येक animal को ASCII art के रूप में draw किया जा सके और उसे speech bubble में recorded text बोलने के लिए कहा जा सके। +हम [`cowpy`](https://github.com/jeffbuttars/cowpy) नामक एक tool का उपयोग करके ऐसा करने जा रहे हैं। + +??? info "`cowpy` क्या करता है?" + + `cowpy` एक command-line tool है जो मनमाना text inputs को एक मज़ेदार तरीके से प्रदर्शित करने के लिए ASCII art generate करता है। + यह Tony Monroe के classic [cowsay](https://en.wikipedia.org/wiki/Cowsay) tool का python implementation है। + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + वैकल्पिक रूप से, आप default cow के बजाय उपयोग करने के लिए एक character (या 'cowacter') चुन सकते हैं। + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +यदि आपने Hello Nextflow course किया है, तो आप पहले ही इस tool को action में देख चुके हैं। +यदि नहीं, तो चिंता न करें; हम सब कुछ कवर करेंगे जो आपको जानने की आवश्यकता है। + +### 3.1. process को import करें और कोड की जाँच करें + +हम आपको `COWPY` नामक एक पूर्व-लिखित process मॉड्यूल प्रदान करते हैं जो `cowpy` tool को wrap करता है, इसलिए आपको workflow block से पहले केवल एक include statement जोड़ने की आवश्यकता है। + +workflow में निम्नलिखित संपादन करें: + +=== "बाद में" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +आप इसके कोड की जाँच करने के लिए मॉड्यूल फ़ाइल खोल सकते हैं: + +```groovy title="modules/cowpy.nf" linen + +``` diff --git a/docs/hi/docs/side_quests/nf-test.md b/docs/hi/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..f8ee046eba --- /dev/null +++ b/docs/hi/docs/side_quests/nf-test.md @@ -0,0 +1,1194 @@ +# nf-test के साथ परीक्षण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +यह सुनिश्चित करने के लिए कि आपके workflow का हर भाग वही कर रहा है जो उसे करना चाहिए, व्यवस्थित रूप से परीक्षण करना reproducibility और दीर्घकालिक रखरखाव के लिए महत्वपूर्ण है, और development process के दौरान एक बड़ी मदद हो सकती है। + +आइए एक मिनट के लिए बात करें कि परीक्षण इतना महत्वपूर्ण क्यों है। यदि आप एक workflow develop कर रहे हैं, तो आप सबसे पहले कुछ test data लेंगे जो आपको पता है कि valid है और result produce करना चाहिए। आप pipeline में पहली process जोड़ते हैं और इसे काम करने के लिए अपने inputs के साथ wire करते हैं। फिर, यह जांचने के लिए कि सब कुछ काम कर रहा है, आप इसे test data पर run करते हैं। यह मानते हुए कि यह काम करता है, आप अगली process पर जाते हैं और फिर से test data run करते हैं। आप इस process को तब तक दोहराते हैं जब तक आपके पास एक pipeline न हो जिससे आप संतुष्ट हों। + +फिर, शायद आप एक सरल true या false parameter जैसे `--skip_process` जोड़ते हैं। अब आपको pipeline को दो बार run करना होगा, एक बार प्रत्येक parameter के साथ यह सुनिश्चित करने के लिए कि यह अपेक्षा के अनुसार काम करता है। लेकिन रुकिए, हम यह कैसे जांचें कि `--skip_process` वास्तव में process को skip करता है? हमें outputs में जाना होगा या log files check करनी होंगी! यह एक परेशानी है और error-prone है। + +जैसे-जैसे आप अपनी pipeline develop करते हैं, यह जल्दी ही इतनी complex हो जाएगी कि manually हर iteration को test करना slow और error-prone होगा। इसके अलावा, यदि आपको error मिलती है तो यह पता लगाना बहुत मुश्किल होगा कि आपकी pipeline में error कहां से आ रही है। यहीं पर testing काम आती है। + +Testing आपको systematically check करने की अनुमति देती है कि आपकी pipeline का हर भाग अपेक्षा के अनुसार काम कर रहा है। developer के लिए अच्छी तरह से लिखे गए tests के फायदे बहुत बड़े हैं: + +- **Confidence**: क्योंकि tests पूरी pipeline को cover करते हैं, आप confident रह सकते हैं कि कुछ बदलने से कुछ और प्रभावित नहीं होता है +- **Trust**: जब कई developers pipeline पर काम करते हैं, तो वे जानते हैं कि दूसरे developers ने pipeline और हर component को break नहीं किया है +- **Transparency**: Tests दिखाते हैं कि pipeline कहां fail हो रही है और problem को track करना आसान बनाते हैं। वे documentation के एक रूप के रूप में भी काम करते हैं, दिखाते हैं कि process या workflow कैसे run करें +- **Speed**: क्योंकि tests automated हैं, वे बहुत जल्दी और बार-बार run किए जा सकते हैं। आप नए bugs introduce करने के कम डर के साथ जल्दी iterate कर सकते हैं + +हम कई अलग-अलग प्रकार के tests लिख सकते हैं: + +1. **Module-level tests**: व्यक्तिगत processes के लिए +2. **Workflow-level tests**: एकल workflow के लिए +3. **Pipeline-level tests**: पूरी pipeline के लिए +4. **Performance tests**: Pipeline की speed और efficiency के लिए +5. **Stress tests**: extreme conditions में pipeline के performance का आकलन उसकी सीमाओं को निर्धारित करने के लिए + +व्यक्तिगत processes का परीक्षण अन्य languages में unit tests के समान है। Workflow या पूरी pipeline का परीक्षण अन्य languages में integration tests कहलाता है, जहां हम components के interactions का परीक्षण करते हैं। + +[**nf-test**](https://www.nf-test.com/) एक tool है जो आपको module, workflow और pipeline level tests लिखने की अनुमति देता है। संक्षेप में, यह आपको systematically check करने की अनुमति देता है कि pipeline का हर व्यक्तिगत भाग अपेक्षा के अनुसार काम कर रहा है, _isolation में_। + +### सीखने के लक्ष्य + +इस side quest में, आप pipeline के लिए workflow-level test के साथ-साथ तीन processes के लिए module-level tests लिखने के लिए nf-test का उपयोग करना सीखेंगे। + +इस side quest के अंत तक, आप निम्नलिखित techniques को effectively उपयोग करने में सक्षम होंगे: + +- अपने project में nf-test initialize करना +- Module-level और workflow-level tests generate करना +- Assertions के सामान्य प्रकार जोड़ना +- समझना कि snapshots vs. content assertions कब उपयोग करें +- पूरे project के लिए tests run करना + +ये skills आपको अपने pipeline projects में एक comprehensive testing strategy implement करने में मदद करेंगी, यह सुनिश्चित करते हुए कि वे अधिक robust और maintainable हैं। + +### पूर्वापेक्षाएँ + +इस side quest को लेने से पहले, आपको: + +- [Hello Nextflow](../hello_nextflow/README.md) tutorial या equivalent beginner's course पूरा किया हो +- Basic Nextflow concepts और mechanisms (processes, channels, operators, files के साथ काम करना, meta data) के साथ comfortable होना चाहिए + +--- + +## 0. शुरू करें + +#### Training codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार training environment खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Project directory में जाएं + +आइए उस directory में चलें जहां इस tutorial के लिए files स्थित हैं। + +```bash +cd side-quests/nf-test +``` + +आप VSCode को इस directory पर focus करने के लिए set कर सकते हैं: + +```bash +code . +``` + +#### Materials की समीक्षा करें + +आपको एक main workflow file और `greetings.csv` नामक एक CSV file मिलेगी जिसमें pipeline का input होगा। + +```console title="Directory contents" +. +├── greetings.csv +└── main.nf +``` + +Files के विस्तृत description के लिए, [Hello Nextflow से warmup](../hello_nextflow/00_orientation.md) देखें। + +जिस workflow का हम परीक्षण करेंगे वह [Hello Workflow](../hello_nextflow/03_hello_workflow.md) में बनाए गए Hello workflow का एक subset है। + +??? example "Hello Nextflow workflow क्या करता है?" + + यदि आपने [Hello Nextflow](../hello_nextflow/index.md) training नहीं की है, तो यहां एक quick overview है कि यह simple workflow क्या करता है। + + Workflow एक CSV file लेता है जिसमें greetings होते हैं, उन पर चार consecutive transformation steps run करता है, और एक single text file output करता है जिसमें एक fun character की ASCII picture होती है जो greetings कह रहा है। + + चार steps को Nextflow processes (`sayHello`, `convertToUpper`, `collectGreetings`, और `cowpy`) के रूप में implement किया गया है जो अलग-अलग module files में stored हैं। + + 1. **`sayHello`:** प्रत्येक greeting को अपनी output file में लिखता है (जैसे, "Hello-output.txt") + 2. **`convertToUpper`:** प्रत्येक greeting को uppercase में convert करता है (जैसे, "HELLO") + 3. **`collectGreetings`:** सभी uppercase greetings को एक single batch file में collect करता है + 4. **`cowpy`:** `cowpy` tool का उपयोग करके ASCII art generate करता है + + Results `results/` नामक directory में publish किए जाते हैं, और pipeline का final output (जब default parameters के साथ run किया जाता है) एक plain text file होती है जिसमें एक character का ASCII art होता है जो uppercased greetings कह रहा है। + + इस side quest में, हम Hello workflow के एक intermediate form का उपयोग करते हैं जिसमें केवल पहली दो processes होती हैं। + +जिस subset के साथ हम काम करेंगे वह दो processes से बना है: `sayHello` और `convertToUpper`। +आप नीचे पूरा workflow code देख सकते हैं। + +??? example "Workflow code" + + ```groovy title="main.nf" + /* + * Pipeline parameters + */ + params.input_file = "greetings.csv" + + /* + * Use echo to print 'Hello World!' to standard out + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Use a text replace utility to convert the greeting to uppercase + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // CSV फ़ाइल से इनपुट के लिए एक channel बनाएं + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // एक अभिवादन emit करें + sayHello(greeting_ch) + + // अभिवादन को uppercase में बदलें + convertToUpper(sayHello.out) + } + ``` + +#### Workflow चलाएं + +आइए workflow को run करें यह सुनिश्चित करने के लिए कि यह अपेक्षा के अनुसार काम कर रहा है। + +```bash +nextflow run main.nf +``` + +```console title="Workflow run करने का परिणाम" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +बधाई हो! आपने अभी-अभी एक test run किया! + +"रुकिए, क्या? मैंने अभी workflow run किया और यह काम किया! यह test कैसे है?" + +अच्छा सवाल! + +आइए समझें कि अभी क्या हुआ। + +आपने default parameters के साथ workflow run किया, आपने confirm किया कि यह काम किया और आप results से खुश हैं। यह testing का सार है। यदि आपने Hello Nextflow training course में काम किया है, तो आपने देखा होगा कि हमने हमेशा हर section की शुरुआत उस workflow को run करके की जिसे हम शुरुआती बिंदु के रूप में उपयोग कर रहे थे, यह confirm करने के लिए कि सब कुछ सही तरीके से set up है। + +Software का परीक्षण अनिवार्य रूप से हमारे लिए यह process करता है। + +#### Assignment की समीक्षा करें + +आपकी चुनौती इस workflow में nf-test का उपयोग करके standardized tests जोड़ना है, ताकि यह verify करना आसान हो जाए कि हर भाग अपेक्षा के अनुसार काम करना जारी रखता है यदि कोई और changes किए जाते हैं। + +#### Readiness checklist + +क्या आपको लगता है कि आप dive in करने के लिए तैयार हैं? + +- [ ] मैं इस course के goal और इसकी prerequisites को समझता हूं +- [ ] मेरा codespace up और running है +- [ ] मैंने अपनी working directory को appropriately set कर लिया है +- [ ] मैंने workflow को successfully run किया है +- [ ] मैं assignment को समझता हूं + +यदि आप सभी boxes check कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. `nf-test` Initialize करें + +`nf-test` package एक initialization command provide करता है जो हमारे लिए अपने project के लिए tests develop करना शुरू करने के लिए कुछ चीजें set up करता है। + +```bash +nf-test init +``` + +यह निम्नलिखित output produce करना चाहिए: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +यह एक configuration file stub युक्त `tests` directory भी बनाता है। + +### 1.1. nf-test generate करें + +`nf-test` nf-test files बनाने के लिए tools के एक set के साथ आता है, जो हमें अधिकांश काम बचाता है। ये `generate` subcommand के अंतर्गत आते हैं। आइए pipeline के लिए एक test generate करें: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Output" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +यह `tests` directory के भीतर एक `main.nf.test` file बनाएगा। यह हमारी pipeline level test file है। यदि आप `tree tests/` run करते हैं तो आपको कुछ ऐसा दिखना चाहिए: + +```console title="Test directory contents" +tests/ +├── main.nf.test +└── nextflow.config +``` + +`main.nf.test` file हमारी pipeline level test file है। आइए इसे खोलें और contents को देखें। + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + } + + then { + assert workflow.success + } + + } + +} +``` + +हम test file की structure को समझने के लिए एक second लेंगे। + +`nextflow_pipeline` block सभी pipeline level tests के लिए entry point है। इसमें निम्नलिखित होते हैं: + +- `name`: Test का नाम +- `script`: Pipeline script का path + +`test` block actual test है। इसमें निम्नलिखित होते हैं: + +- `when`: वे conditions जिनके तहत test run होना चाहिए। इसमें वे parameters शामिल हैं जो pipeline को run करने के लिए उपयोग किए जाएंगे +- `then`: वे assertions जो बनाए जाने चाहिए। इसमें pipeline के expected outcomes शामिल हैं + +Plain English में, test का logic निम्नानुसार पढ़ा जाता है: +"**जब** ये _parameters_ इस _pipeline_ को provide किए जाते हैं, **तो** हम इन results को देखने की उम्मीद करते हैं।" + +यह एक functional test नहीं है, हम अगले section में demonstrate करेंगे कि इसे कैसे बनाया जाए। + +### Test Names पर एक नोट + +ऊपर दिए गए उदाहरण में, हमने default name "Should run without failures" का उपयोग किया जो एक basic test के लिए उपयुक्त है जो सिर्फ यह check करता है कि pipeline successfully runs होता है। हालांकि, जैसे ही हम अधिक specific test cases जोड़ते हैं, हमें अधिक descriptive names का उपयोग करना चाहिए जो indicate करते हैं कि हम वास्तव में क्या test कर रहे हैं। उदाहरण के लिए: + +- "Should convert input to uppercase" - जब specific functionality test कर रहे हों +- "Should handle empty input gracefully" - जब edge cases test कर रहे हों +- "Should respect max memory parameter" - जब resource constraints test कर रहे हों +- "Should create expected output files" - जब file generation test कर रहे हों + +अच्छे test names को: + +1. "Should" से शुरू होना चाहिए यह clear करने के लिए कि expected behavior क्या है +2. उस specific functionality या scenario का describe करना चाहिए जो test किया जा रहा है +3. इतना clear होना चाहिए कि यदि test fail होता है, तो आपको पता चल जाए कि कौन सी functionality broken है + +जैसे-जैसे हम बाद में अधिक assertions और specific test cases जोड़ते हैं, हम इन अधिक descriptive names का उपयोग करेंगे यह clear करने के लिए कि प्रत्येक test क्या verify कर रहा है। + +### 1.2. Test run करें + +आइए test run करें यह देखने के लिए कि क्या होता है। + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test pipeline fail" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Test fail हो जाता है! क्या हुआ? + +1. nf-test ने pipeline को as is run करने की कोशिश की, `when` block में settings का उपयोग करते हुए: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test ने pipeline की status check की और इसे `when` block से compare किया: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +ध्यान दें कि कैसे nf-test ने report किया कि pipeline fail हो गई और Nextflow से error message provide किया: + +```console title="Error" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +तो issue क्या था? याद रखें कि pipeline में project directory में एक greetings.csv file है। जब nf-test pipeline run करता है, तो यह इस file को look करेगा, लेकिन यह इसे नहीं ढूंढ सकता। File वहां है, क्या हो रहा है? खैर, यदि हम path को देखें तो हम देख सकते हैं कि test path `./nf-test/tests/longHashString/` में हो रहा है। Nextflow की तरह, nf-test हर test के लिए एक नई directory बनाता है सब कुछ isolated रखने के लिए। Data file वहां स्थित नहीं है इसलिए हमें original test में file का path correct करना होगा। + +आइए test file पर वापस जाएं और `when` block में file का path change करें। + +आप सोच सकते हैं कि हम test में pipeline के root को कैसे point करने जा रहे हैं। चूंकि यह एक common situation है, nf-test के पास global variables की एक range है जिसे हम अपने जीवन को आसान बनाने के लिए उपयोग कर सकते हैं। आप पूरी list [यहां](https://www.nf-test.com/docs/testcases/global_variables/) पा सकते हैं लेकिन इस बीच हम `projectDir` variable का उपयोग करेंगे, जिसका अर्थ है pipeline project का root। + +_पहले:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_बाद में:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +आइए test को फिर से run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline passes" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +सफलता! Pipeline successfully runs होती है और test pass हो जाता है। इसे जितनी बार चाहें run करें और आपको हमेशा same result मिलेगा! + +Default रूप से, Nextflow output hidden है, लेकिन खुद को convince करने के लिए कि nf-test definitely workflow run कर रहा है, आप `--verbose` flag का उपयोग कर सकते हैं: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Pipeline सभी processes चलाती है" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Assertions जोड़ें + +एक simple check यह सुनिश्चित करना है कि हमारी pipeline उन सभी processes को run कर रही है जिनकी हम उम्मीद करते हैं और कोई भी silently skip नहीं कर रही है। याद रखें हमारी pipeline 6 processes run करती है, एक `sayHello` और एक `convertToUpper` 3 greetings में से प्रत्येक के लिए। + +आइए अपने test में एक assertion जोड़ें यह check करने के लिए कि pipeline expected number of processes run करती है। हम अपने test name को भी update करेंगे ताकि यह better reflect करे कि हम क्या test कर रहे हैं। + +**पहले:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**बाद में:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Test name अब better reflect करता है कि हम वास्तव में क्या verify कर रहे हैं - न केवल यह कि pipeline failing के बिना runs होती है, बल्कि यह कि यह expected number of processes run करती है। + +आइए test को फिर से run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline assertions के साथ passes होती है" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +सफलता! Pipeline successfully runs होती है और test pass हो जाता है। अब हमने pipeline के details का परीक्षण करना शुरू कर दिया है, साथ ही overall status का भी। + +### 1.4. Output का परीक्षण करें + +आइए अपने test में एक assertion जोड़ें यह check करने के लिए कि output file बनाई गई थी। हम इसे एक अलग test के रूप में जोड़ेंगे, एक informative name के साथ, ताकि results को interpret करना आसान हो जाए। + +**पहले:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**बाद में:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Test को फिर से run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline file assertions के साथ passes होती है" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +सफलता! Tests pass होते हैं क्योंकि pipeline successfully complete हुई, correct number of processes run हुईं और output files बनाई गईं। यह आपको यह भी दिखाना चाहिए कि अपने tests के लिए वे informative names provide करना कितना useful है। + +यह सिर्फ surface है, हम pipeline के details को check करने के लिए assertions लिखना जारी रख सकते हैं, लेकिन अभी के लिए आइए pipeline के internals को test करने की ओर बढ़ें। + +### निष्कर्ष + +आप जानते हैं कि pipeline के लिए nf-test कैसे लिखें। + +### आगे क्या है? + +Nextflow process को test करना सीखें। + +--- + +## 2. Nextflow process का परीक्षण करें + +हमें pipeline के हर भाग के लिए tests लिखने की जरूरत नहीं है, लेकिन हमारे पास जितने अधिक tests हैं हम pipeline के बारे में उतने ही comprehensive हो सकते हैं और उतने ही confident हो सकते हैं कि यह अपेक्षा के अनुसार काम कर रहा है। इस section में हम pipeline में दोनों processes को individual units के रूप में test करने जा रहे हैं। + +### 2.1. `sayHello` process का परीक्षण करें + +आइए `sayHello` process से शुरू करें। + +आइए process के लिए tests generate करने के लिए फिर से `nf-test generate` command का उपयोग करें। + +```bash +nf-test generate process main.nf +``` + +```console title="Output" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +आइए अभी के लिए `main.sayhello.nf.test` file में `sayhello` process पर focus करें। + +आइए file खोलें और contents को देखें। + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +पहले की तरह, हम test details से शुरू करते हैं, इसके बाद `when` और `then` blocks। हालांकि, हमारे पास एक अतिरिक्त `process` block भी है जो हमें process के inputs define करने की अनुमति देता है। + +आइए test run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Process test fails" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Test fail होता है क्योंकि `sayHello` process 1 input declare करती है लेकिन 0 arguments के साथ call की गई थी। आइए process में एक input जोड़कर इसे ठीक करें। [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (और ऊपर warmup section) से याद रखें कि हमारी `sayHello` process एक single value input लेती है, जिसे हमें provide करने की आवश्यकता होगी। हमें test name को भी ठीक करना चाहिए ताकि यह better reflect करे कि हम क्या test कर रहे हैं। + +**पहले:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**बाद में:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +आइए test को फिर से run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```console title="nf-test pipeline pass" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +सफलता! Test pass होता है क्योंकि `sayHello` process successfully run हुई और output बनाया गया। + +### 2.2. Test द्वारा बनाए गए snapshot को देखें + +यदि हम `tests/main.sayhello.nf.test` file को देखें, तो हम देख सकते हैं कि यह assertion block में एक method `snapshot()` का उपयोग करता है: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +यह nf-test को बता रहा है कि `sayHello` process के output का एक snapshot बनाए। आइए snapshot file के contents को देखें। + +```console title="Snapshot file contents" +code tests/main.sayhello.nf.test.snap +``` + +हम इसे यहां print नहीं करेंगे, लेकिन आपको process और process outputs के details युक्त एक JSON file दिखनी चाहिए। विशेष रूप से, हम एक line देख सकते हैं जो इस तरह दिखती है: + +```json title="Snapshot file contents" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +यह `sayHello` process द्वारा बनाए गए outputs को represent करता है, जिसे हम explicitly test कर रहे हैं। यदि हम test को फिर से run करते हैं, तो program check करेगा कि नया output उस output से match करता है जो originally record किया गया था। यह test करने का एक quick, simple तरीका है कि process outputs change नहीं होते हैं, यही कारण है कि nf-test इसे default के रूप में provide करता है। + +!!!warning + + इसका मतलब है कि हमें यह सुनिश्चित करना होगा कि जो output हम original run में record करते हैं वह सही है! + +यदि, future development के दौरान, code में कुछ बदलता है जो output को different बनाता है, तो test fail हो जाएगा और हमें यह निर्धारित करना होगा कि change expected है या नहीं। + +- यदि यह पता चलता है कि code में कुछ टूट गया है, तो हमें इसे ठीक करना होगा, इस expectation के साथ कि fixed code test pass करेगा +- यदि यह एक expected change है (जैसे, tool को improve किया गया है और results बेहतर हैं) तो हमें new output को reference के रूप में match करने के लिए snapshot को update करने की आवश्यकता होगी। nf-test के पास इस purpose के लिए एक parameter `--update-snapshot` है + +हम test को फिर से run कर सकते हैं और देख सकते हैं कि test pass होना चाहिए: + +```console title="nf-test process snapshot के साथ pass" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +सफलता! Test pass होता है क्योंकि `sayHello` process successfully run हुई और output snapshot से match हो गया। + +### 2.3. Snapshots का विकल्प: Direct Content Assertions + +जबकि snapshots output में किसी भी changes को catch करने के लिए बहुत अच्छे हैं, कभी-कभी आप specific content को verify करना चाहते हैं बिना entire file के matching के बारे में इतने strict होने के। उदाहरण के लिए: + +- जब output के parts change हो सकते हैं (timestamps, random IDs, आदि) लेकिन कुछ key content present होना चाहिए +- जब आप output में specific patterns या values check करना चाहते हैं +- जब आप test को इस बारे में अधिक explicit बनाना चाहते हैं कि success क्या है + +यहां बताया गया है कि हम specific content को check करने के लिए अपने test को कैसे modify कर सकते हैं: + +**पहले:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**बाद में:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +ध्यान दें कि nf-test process outputs को lists की lists के रूप में देखता है, इसलिए `process.out[0][0]` इस process से पहले channel item (या 'emission') के पहले भाग को fetch कर रहा है। + +यह approach: + +- यह clear करता है कि हम output में exactly क्या expect करते हैं +- Output में irrelevant changes के लिए अधिक resilient है +- जब tests fail होते हैं तो बेहतर error messages provide करता है +- अधिक complex validations (regex patterns, numerical comparisons, आदि) की अनुमति देता है + +आइए test run करें यह देखने के लिए कि यह काम करता है या नहीं। + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Process test fails" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. `convertToUpper` process का परीक्षण करें + +आइए `tests/main.converttoupper.nf.test` file खोलें और contents को देखें: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +यह `sayHello` process के समान test है, लेकिन यह `convertToUpper` process को test कर रहा है। हम जानते हैं कि यह fail हो जाएगा क्योंकि `sayHello` की तरह, `convertToUpper` process एक single path input लेती है, लेकिन हमने एक specify नहीं की है। + +अब हमें convertToUpper process को एक single input file supply करने की आवश्यकता है, जिसमें कुछ text शामिल है जिसे हम uppercase में convert करना चाहते हैं। हम ऐसा करने के कई तरीके हैं: + +- हम test करने के लिए एक dedicated file बना सकते हैं +- हम existing data/greetings.csv file को फिर से उपयोग कर सकते हैं +- हम इसे test के भीतर on the fly बना सकते हैं + +अभी के लिए, आइए pipeline level test के साथ उपयोग किए गए example का उपयोग करते हुए existing data/greetings.csv file को फिर से उपयोग करें। पहले की तरह, हम test का नाम बेहतर reflect करने के लिए name दे सकते हैं कि हम क्या test कर रहे हैं, लेकिन इस बार आइए इसे content को 'snapshot' करने दें बजाय specific strings check करने के (जैसा कि हमने दूसरी process में किया था)। + +**पहले:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**बाद में:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // यहाँ parameters define करें। उदाहरण: + // outdir = "tests/results" (output directory) + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +और test run करें! + +```bash title="nf-test pipeline pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +ध्यान दें, हमने `tests/main.converttoupper.nf.test.snap` पर `convertToUpper` process के लिए एक snapshot file बनाई है। यदि हम test को फिर से run करते हैं, तो हमें nf-test फिर से pass होता देखना चाहिए। + +```bash title="nf-test process convertToUpper pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### निष्कर्ष + +आप जानते हैं कि Nextflow process के लिए tests कैसे लिखें और उन्हें कैसे run करें। + +### आगे क्या है? + +सभी चीजों के लिए एक साथ tests run करना सीखें! + +## 3. पूरे repository के लिए tests run करें + +प्रत्येक component पर nf-test run करना ठीक है, लेकिन laborious और error prone है। क्या हम एक साथ सब कुछ test नहीं कर सकते? + +हां हम कर सकते हैं! + +आइए पूरे repo पर nf-test run करें। + +### 3.1. पूरे repo पर nf-test run करें + +हम `nf-test test` command run करके पूरे repo पर nf-test run कर सकते हैं। + +```bash +nf-test test . +``` + +ध्यान दें, हम अपनी current directory से सब कुछ run करने के लिए केवल `.` का उपयोग कर रहे हैं। इसमें हर test शामिल होगा! + +```console title="nf-test repo pass" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +यह देखिए! हमने 4 tests run किए, प्रत्येक process के लिए 1 और एक single command के साथ पूरी pipeline के लिए 2। कल्पना करें कि एक बड़े codebase पर यह कितना powerful है! + +--- + +## सारांश + +इस side quest में, आपने व्यक्तिगत processes के साथ-साथ पूरी pipeline के लिए end-to-end tests बनाने और run करने के लिए nf-test की features का leverage करना सीखा है। +अब आप output validation के मुख्य दो approaches, snapshots और direct content assertions से अवगत हैं, और कब किसका उपयोग करना है। +आप यह भी जानते हैं कि tests को एक-एक करके या पूरे project के लिए कैसे run करें। + +अपने स्वयं के काम में इन techniques को apply करना आपको यह सुनिश्चित करने में सक्षम बनाएगा कि: + +- आपका code अपेक्षा के अनुसार काम करता है +- Changes existing functionality को break नहीं करते हैं +- अन्य developers confidence के साथ contribute कर सकते हैं +- Problems को जल्दी identify और fix किया जा सकता है +- Output content expectations से match करता है + +### प्रमुख patterns + +1. Pipeline-level tests: + - Basic success testing + - Process count verification + - Output file existence checks +2. Process-level tests +3. Output validation के दो approaches: + - Complete output verification के लिए snapshots का उपयोग करना + - Specific content checks के लिए direct content assertions का उपयोग करना +4. एक single command के साथ repository में सभी tests run करना + +### अतिरिक्त संसाधन + +अधिक advanced testing features और best practices के लिए [nf-test documentation](https://www.nf-test.com/) देखें। आप चाह सकते हैं: + +- अपने tests में अधिक comprehensive assertions जोड़ें +- Edge cases और error conditions के लिए tests लिखें +- Tests को automatically run करने के लिए continuous integration set up करें +- Workflow और module tests जैसे अन्य प्रकार के tests के बारे में जानें +- अधिक advanced content validation techniques का पता लगाएं + +**याद रखें:** Tests आपके code के व्यवहार का living documentation हैं। आप जितने अधिक tests लिखते हैं, और आपके assertions जितने अधिक specific हैं, आप अपनी pipeline की reliability में उतने ही confident हो सकते हैं। + +--- + +## आगे क्या है? + +[Side Quests के menu](./index.md) पर वापस लौटें या list में अगले topic पर जाने के लिए page के निचले दाईं ओर button पर click करें। diff --git a/docs/hi/docs/side_quests/orientation.md b/docs/hi/docs/side_quests/orientation.md new file mode 100644 index 0000000000..e5fbc4e972 --- /dev/null +++ b/docs/hi/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# अभिविन्यास + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces वातावरण में इस प्रशिक्षण पाठ्यक्रम को पूरा करने के लिए आवश्यक सभी सॉफ़्टवेयर, कोड और डेटा शामिल हैं, इसलिए आपको स्वयं कुछ भी इंस्टॉल करने की आवश्यकता नहीं है। +हालांकि, लॉग इन करने के लिए आपको एक (निःशुल्क) खाते की आवश्यकता है, और आपको इंटरफ़ेस से परिचित होने के लिए कुछ मिनट देने चाहिए। + +यदि आपने अभी तक ऐसा नहीं किया है, तो कृपया आगे बढ़ने से पहले [इस लिंक](../../envsetup/) का अनुसरण करें। + +## प्रदान की गई सामग्री + +इस प्रशिक्षण पाठ्यक्रम के दौरान, हम `side-quests/` डायरेक्टरी में काम करेंगे। +इस डायरेक्टरी में सभी कोड फ़ाइलें, परीक्षण डेटा और सहायक फ़ाइलें शामिल हैं जिनकी आपको आवश्यकता होगी। + +इस डायरेक्टरी की सामग्री का पता लगाने के लिए स्वतंत्र महसूस करें; ऐसा करने का सबसे आसान तरीका GitHub Codespaces कार्यक्षेत्र के बाईं ओर फ़ाइल एक्सप्लोरर का उपयोग करना है। +वैकल्पिक रूप से, आप `tree` कमांड का उपयोग कर सकते हैं। +पाठ्यक्रम के दौरान, हम डायरेक्टरी संरचना और सामग्री को पठनीय रूप में प्रस्तुत करने के लिए `tree` के आउटपुट का उपयोग करते हैं, कभी-कभी स्पष्टता के लिए मामूली संशोधनों के साथ। + +यहाँ हम दूसरे स्तर तक विषय-सूची उत्पन्न करते हैं: + +```bash +tree . -L 2 +``` + +यदि आप इसे `side-quests` के अंदर चलाते हैं, तो आपको निम्नलिखित आउटपुट दिखाई देना चाहिए: + +```console title="Directory contents" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**शुरू करने के लिए आपको जो जानना चाहिए उसका सारांश यहां दिया गया है:** + +- **प्रत्येक डायरेक्टरी एक व्यक्तिगत साइड क्वेस्ट से संबंधित है।** + उनकी सामग्री संबंधित साइड क्वेस्ट के पेज पर विस्तृत है। + +- **`solutions` डायरेक्टरी** में पूर्ण workflow और/या module स्क्रिप्ट शामिल हैं जो प्रत्येक साइड क्वेस्ट के विभिन्न चरणों को चलाने से प्राप्त होती हैं। + इनका उपयोग आपके काम की जांच करने और किसी भी समस्या का निवारण करने के लिए संदर्भ के रूप में करने का इरादा है। + +!!!tip "सुझाव" + + यदि किसी भी कारण से आप इस डायरेक्टरी से बाहर चले जाते हैं, तो आप इस कमांड को चलाकर हमेशा इसमें वापस आ सकते हैं: + + ```bash + cd /workspaces/training/side-quests + ``` + +अब, पाठ्यक्रम शुरू करने के लिए, इस पेज के निचले दाएं कोने में तीर पर क्लिक करें। diff --git a/docs/hi/docs/side_quests/splitting_and_grouping.md b/docs/hi/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..ce3f9c9acf --- /dev/null +++ b/docs/hi/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,752 @@ +# विभाजन और समूहीकरण + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow डेटा के साथ लचीले ढंग से काम करने के लिए शक्तिशाली उपकरण प्रदान करता है। एक प्रमुख क्षमता है डेटा को विभिन्न स्ट्रीम में विभाजित करना और फिर संबंधित आइटम को वापस एक साथ समूहित करना। यह बायोइन्फॉर्मेटिक्स वर्कफ़्लो में विशेष रूप से मूल्यवान है जहाँ आपको विश्लेषण के लिए परिणामों को संयोजित करने से पहले विभिन्न प्रकार के नमूनों को अलग-अलग प्रोसेस करने की आवश्यकता होती है। + +इसे मेल को सॉर्ट करने की तरह समझें: आप गंतव्य के आधार पर पत्रों को अलग करते हैं, प्रत्येक ढेर को अलग तरीके से प्रोसेस करते हैं, फिर एक ही व्यक्ति के पास जाने वाली वस्तुओं को फिर से जोड़ते हैं। Nextflow वैज्ञानिक डेटा के साथ ऐसा करने के लिए विशेष ऑपरेटर का उपयोग करता है। इस दृष्टिकोण को डिस्ट्रिब्यूटेड कंप्यूटिंग और बायोइन्फॉर्मेटिक्स वर्कफ़्लो में **scatter/gather** पैटर्न के रूप में भी जाना जाता है। + +Nextflow का channel सिस्टम इस लचीलेपन का केंद्र है। Channel आपके वर्कफ़्लो के विभिन्न भागों को जोड़ते हैं, जिससे डेटा आपके विश्लेषण के माध्यम से प्रवाहित हो सकता है। आप एक ही डेटा स्रोत से कई channel बना सकते हैं, प्रत्येक channel को अलग तरीके से प्रोसेस कर सकते हैं, और फिर आवश्यकता पड़ने पर channel को वापस एक साथ मर्ज कर सकते हैं। यह दृष्टिकोण आपको ऐसे वर्कफ़्लो डिज़ाइन करने देता है जो स्वाभाविक रूप से जटिल बायोइन्फॉर्मेटिक्स विश्लेषणों के शाखाओं और अभिसरण पथों को दर्शाते हैं। + +### सीखने के लक्ष्य + +इस side quest में, आप Nextflow के channel ऑपरेटर का उपयोग करके डेटा को विभाजित और समूहित करना सीखेंगे। +हम एक CSV फ़ाइल से शुरू करेंगे जिसमें नमूना जानकारी और संबंधित डेटा फ़ाइलें होंगी, फिर इस डेटा को मैनिपुलेट और पुनर्गठित करेंगे। + +इस side quest के अंत तक, आप निम्नलिखित तकनीकों का उपयोग करके डेटा स्ट्रीम को प्रभावी ढंग से अलग और संयोजित करने में सक्षम होंगे: + +- `splitCsv` का उपयोग करके फ़ाइलों से डेटा पढ़ना +- `filter` और `map` के साथ डेटा को फ़िल्टर और ट्रांसफ़ॉर्म करना +- `join` और `groupTuple` का उपयोग करके संबंधित डेटा को संयोजित करना +- समानांतर प्रोसेसिंग के लिए `combine` के साथ डेटा संयोजन बनाना +- `subMap` और डुप्लीकेशन रणनीतियों का उपयोग करके डेटा संरचना को अनुकूलित करना +- channel संरचनाओं को मैनिपुलेट करने में मदद करने के लिए named closures के साथ पुन: प्रयोज्य फ़ंक्शन बनाना + +ये कौशल आपको ऐसे वर्कफ़्लो बनाने में मदद करेंगे जो कई इनपुट फ़ाइलों और विभिन्न प्रकार के डेटा को कुशलता से संभाल सकते हैं, जबकि स्वच्छ, रखरखाव योग्य कोड संरचना बनाए रखते हैं। + +### पूर्वापेक्षाएँ + +इस side quest को शुरू करने से पहले, आपको चाहिए: + +- [Hello Nextflow](../hello_nextflow/README.md) ट्यूटोरियल या समकक्ष शुरुआती पाठ्यक्रम पूरा किया हो। +- बुनियादी Nextflow अवधारणाओं और तंत्रों (processes, channels, operators, फ़ाइलों के साथ काम करना, meta data) का उपयोग करने में सहज हों + +**वैकल्पिक:** हम पहले [Metadata in workflows](./metadata.md) side quest पूरा करने की सलाह देते हैं। +यह `splitCsv` के साथ CSV फ़ाइलों को पढ़ने और meta maps बनाने की बुनियादी बातों को कवर करता है, जिसका हम यहाँ भारी उपयोग करेंगे। + +--- + +## 0. शुरुआत करें + +#### प्रशिक्षण codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार प्रशिक्षण वातावरण खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएं + +चलिए उस डायरेक्टरी में चलते हैं जहाँ इस ट्यूटोरियल के लिए फ़ाइलें स्थित हैं। + +```bash +cd side-quests/splitting_and_grouping +``` + +आप VSCode को इस डायरेक्टरी पर फ़ोकस करने के लिए सेट कर सकते हैं: + +```bash +code . +``` + +#### सामग्री की समीक्षा करें + +आपको एक मुख्य वर्कफ़्लो फ़ाइल और एक `data` डायरेक्टरी मिलेगी जिसमें `samplesheet.csv` नाम की एक samplesheet है। + +```console title="डायरेक्टरी सामग्री" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +Samplesheet में विभिन्न रोगियों के नमूनों के बारे में जानकारी होती है, जिसमें patient ID, sample repeat number, type (normal या tumor), और काल्पनिक डेटा फ़ाइलों के पथ शामिल हैं (जो वास्तव में मौजूद नहीं हैं, लेकिन हम मान लेंगे कि वे हैं)। + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +यह samplesheet तीन रोगियों (A, B, C) से आठ नमूनों की सूची बनाती है। + +प्रत्येक रोगी के लिए, हमारे पास ऐसे नमूने हैं जो `tumor` प्रकार के हैं (आमतौर पर ट्यूमर बायोप्सी से उत्पन्न) या `normal` (स्वस्थ ऊतक या रक्त से लिए गए)। +यदि आप कैंसर विश्लेषण से परिचित नहीं हैं, तो बस जान लें कि यह एक प्रायोगिक मॉडल से मेल खाता है जो विपरीत विश्लेषण करने के लिए युग्मित tumor/normal नमूनों का उपयोग करता है। + +विशेष रूप से रोगी A के लिए, हमारे पास तकनीकी प्रतिकृतियों (repeats) के दो सेट हैं। + +!!! note + + यदि आप इस प्रायोगिक डिज़ाइन से परिचित नहीं हैं तो चिंता न करें, यह इस ट्यूटोरियल को समझने के लिए महत्वपूर्ण नहीं है। + +#### असाइनमेंट की समीक्षा करें + +आपकी चुनौती एक Nextflow वर्कफ़्लो लिखना है जो: + +1. CSV फ़ाइल से नमूना डेटा **पढ़ेगा** और इसे meta maps के साथ संरचित करेगा +2. प्रकार (normal बनाम tumor) के आधार पर नमूनों को विभिन्न channel में **अलग** करेगा +3. patient ID और replicate number द्वारा मिलान किए गए tumor/normal जोड़ों को **जोड़ेगा** +4. समानांतर प्रोसेसिंग के लिए genomic intervals में नमूनों को **वितरित** करेगा +5. डाउनस्ट्रीम विश्लेषण के लिए संबंधित नमूनों को वापस एक साथ **समूहित** करेगा + +यह एक सामान्य बायोइन्फॉर्मेटिक्स पैटर्न का प्रतिनिधित्व करता है जहाँ आपको स्वतंत्र प्रोसेसिंग के लिए डेटा को विभाजित करने की आवश्यकता होती है, फिर तुलनात्मक विश्लेषण के लिए संबंधित आइटम को फिर से संयोजित करना होता है। + +#### तैयारी चेकलिस्ट + +क्या आप गोता लगाने के लिए तैयार हैं? + +- [ ] मैं इस पाठ्यक्रम के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता हूँ +- [ ] मेरा codespace चालू है +- [ ] मैंने अपनी कार्य डायरेक्टरी उचित रूप से सेट कर ली है +- [ ] मैं असाइनमेंट को समझता हूँ + +यदि आप सभी बॉक्स को चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. नमूना डेटा पढ़ें + +### 1.1. `splitCsv` के साथ नमूना डेटा पढ़ें और meta maps बनाएं + +चलिए `splitCsv` के साथ नमूना डेटा को पढ़कर और इसे meta map पैटर्न में व्यवस्थित करके शुरुआत करते हैं। `main.nf` में, आप देखेंगे कि हमने पहले से ही वर्कफ़्लो शुरू किया है। + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + इस ट्यूटोरियल के दौरान, हम सभी channel वेरिएबल के लिए `ch_` prefix का उपयोग करेंगे ताकि स्पष्ट रूप से संकेत दिया जा सके कि वे Nextflow channels हैं। + +यदि आपने [Metadata in workflows](./metadata.md) side quest पूरा किया है, तो आप इस पैटर्न को पहचानेंगे। हम CSV को पढ़ने के लिए `splitCsv` का उपयोग करेंगे और तुरंत डेटा को meta map के साथ संरचित करेंगे ताकि मेटाडेटा को फ़ाइल पथों से अलग किया जा सके। + +!!! info + + इस प्रशिक्षण में हम दो अलग-अलग अवधारणाओं का सामना करेंगे जिन्हें `map` कहा जाता है: + + - **डेटा संरचना**: Groovy map (अन्य भाषाओं में dictionaries/hashes के बराबर) जो key-value pairs को स्टोर करता है + - **Channel ऑपरेटर**: `.map()` ऑपरेटर जो channel में आइटम को ट्रांसफ़ॉर्म करता है + + हम संदर्भ में स्पष्ट करेंगे कि हमारा क्या मतलब है, लेकिन Nextflow के साथ काम करते समय यह भेद समझना महत्वपूर्ण है। + +`main.nf` में ये परिवर्तन लागू करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +यह `splitCsv` ऑपरेशन (headers के साथ CSV पढ़ना) और `map` ऑपरेशन (डेटा को `[meta, file]` tuples के रूप में संरचित करना) को एक चरण में जोड़ता है। उस परिवर्तन को लागू करें और pipeline चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +अब हमारे पास एक channel है जहाँ प्रत्येक आइटम एक `[meta, file]` tuple है - मेटाडेटा फ़ाइल पथों से अलग है। यह संरचना हमें मेटाडेटा फ़ील्ड के आधार पर अपने workload को विभाजित और समूहित करने की अनुमति देती है। + +--- + +## 2. डेटा को फ़िल्टर और ट्रांसफ़ॉर्म करें + +### 2.1. `filter` के साथ डेटा को फ़िल्टर करें + +हम एक शर्त के आधार पर डेटा को फ़िल्टर करने के लिए [`filter` ऑपरेटर](https://www.nextflow.io/docs/latest/operator.html#filter) का उपयोग कर सकते हैं। मान लें कि हम केवल normal नमूनों को प्रोसेस करना चाहते हैं। हम `type` फ़ील्ड के आधार पर डेटा को फ़िल्टर करके ऐसा कर सकते हैं। चलिए इसे `view` ऑपरेटर से पहले डालते हैं। + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +फ़िल्टर किए गए परिणाम देखने के लिए वर्कफ़्लो को फिर से चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +हमने सफलतापूर्वक डेटा को केवल normal नमूनों को शामिल करने के लिए फ़िल्टर किया है। चलिए संक्षेप में देखें कि यह कैसे काम करता है। + +`filter` ऑपरेटर एक closure लेता है जो channel में प्रत्येक तत्व पर लागू होता है। यदि closure `true` लौटाता है, तो तत्व शामिल है; यदि यह `false` लौटाता है, तो तत्व बाहर रखा जाता है। + +हमारे मामले में, हम केवल उन नमूनों को रखना चाहते हैं जहाँ `meta.type == 'normal'` है। Closure tuple `meta,file` का उपयोग प्रत्येक नमूने को संदर्भित करने के लिए करता है, `meta.type` के साथ नमूना प्रकार को एक्सेस करता है, और जांचता है कि यह `'normal'` के बराबर है या नहीं। + +यह ऊपर प्रस्तुत single closure के साथ पूरा होता है: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. अलग फ़िल्टर किए गए channel बनाएं + +वर्तमान में हम CSV से सीधे बनाए गए channel पर फ़िल्टर लागू कर रहे हैं, लेकिन हम इसे एक से अधिक तरीकों से फ़िल्टर करना चाहते हैं, तो चलिए normal नमूनों के लिए एक अलग फ़िल्टर किया गया channel बनाने के लिए तर्क को फिर से लिखते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +परिणाम देखने के लिए pipeline चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +हमने सफलतापूर्वक डेटा को फ़िल्टर किया है और normal नमूनों के लिए एक अलग channel बनाया है। + +चलिए tumor नमूनों के लिए भी एक फ़िल्टर किया गया channel बनाते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +हमने normal और tumor नमूनों को दो अलग-अलग channel में अलग कर दिया है, और आउटपुट में उन्हें अलग तरह से लेबल करने के लिए `view()` को प्रदान किए गए एक closure का उपयोग किया है: `ch_tumor_samples.view{'Tumor sample: ' + it}`। + +### निष्कर्ष + +इस खंड में, आपने सीखा: + +- **डेटा फ़िल्टर करना**: `filter` के साथ डेटा को कैसे फ़िल्टर करें +- **डेटा विभाजित करना**: किसी शर्त के आधार पर डेटा को विभिन्न channel में कैसे विभाजित करें +- **डेटा देखना**: डेटा प्रिंट करने और विभिन्न channel से आउटपुट को लेबल करने के लिए `view` का उपयोग कैसे करें + +हमने अब normal और tumor नमूनों को दो अलग-अलग channel में अलग कर दिया है। अगला, हम `id` फ़ील्ड पर normal और tumor नमूनों को जोड़ेंगे। + +--- + +## 3. पहचानकर्ताओं द्वारा channel जोड़ना + +पिछले खंड में, हमने normal और tumor नमूनों को दो अलग-अलग channel में अलग किया। इन्हें उनके प्रकार के आधार पर विशिष्ट processes या workflows का उपयोग करके स्वतंत्र रूप से प्रोसेस किया जा सकता है। लेकिन क्या होता है जब हम एक ही रोगी से normal और tumor नमूनों की तुलना करना चाहते हैं? इस बिंदु पर, हमें उन्हें वापस एक साथ जोड़ने की आवश्यकता है, यह सुनिश्चित करते हुए कि नमूनों को उनके `id` फ़ील्ड के आधार पर मैच किया जाए। + +Nextflow में channel को संयोजित करने के कई तरीके शामिल हैं, लेकिन इस मामले में सबसे उपयुक्त ऑपरेटर [`join`](https://www.nextflow.io/docs/latest/operator.html#join) है। यदि आप SQL से परिचित हैं, तो यह `JOIN` ऑपरेशन की तरह कार्य करता है, जहाँ हम join करने के लिए key और join के प्रकार को निर्दिष्ट करते हैं। + +### 3.1. patient ID के आधार पर संयोजित करने के लिए `map` और `join` का उपयोग करें + +यदि हम [`join`](https://www.nextflow.io/docs/latest/operator.html#join) दस्तावेज़ीकरण की जांच करते हैं, तो हम देख सकते हैं कि डिफ़ॉल्ट रूप से यह प्रत्येक tuple के पहले आइटम के आधार पर दो channel को join करता है। + +#### 3.1.1. डेटा संरचना की जांच करें + +यदि आपके पास अभी भी console आउटपुट उपलब्ध नहीं है, तो चलिए हमारी डेटा संरचना की जांच करने और देखने के लिए pipeline चलाते हैं कि हमें `id` फ़ील्ड पर join करने के लिए इसे कैसे संशोधित करने की आवश्यकता है। + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +हम देख सकते हैं कि `id` फ़ील्ड प्रत्येक meta map में पहला तत्व है। `join` के काम करने के लिए, हमें प्रत्येक tuple में `id` फ़ील्ड को अलग करना चाहिए। उसके बाद, हम दोनों channel को संयोजित करने के लिए बस `join` ऑपरेटर का उपयोग कर सकते हैं। + +#### 3.1.2. `id` फ़ील्ड को अलग करें + +`id` फ़ील्ड को अलग करने के लिए, हम [`map` ऑपरेटर](https://www.nextflow.io/docs/latest/operator.html#map) का उपयोग करके एक नया tuple बना सकते हैं जिसमें `id` फ़ील्ड पहले तत्व के रूप में है। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +यह सूक्ष्म हो सकता है, लेकिन आपको प्रत्येक tuple में पहला तत्व `id` फ़ील्ड होना चाहिए। + +#### 3.1.3. दोनों channel को संयोजित करें + +अब हम `id` फ़ील्ड के आधार पर दोनों channel को संयोजित करने के लिए `join` ऑपरेटर का उपयोग कर सकते हैं। + +एक बार फिर, हम joined आउटपुट प्रिंट करने के लिए `view` का उपयोग करेंगे। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +यह बताना थोड़ा मुश्किल है क्योंकि यह इतना चौड़ा है, लेकिन आपको देखने में सक्षम होना चाहिए कि नमूनों को `id` फ़ील्ड द्वारा joined किया गया है। प्रत्येक tuple में अब यह प्रारूप है: + +- `id`: नमूना ID +- `normal_meta_map`: normal नमूना मेटा डेटा जिसमें type, replicate और bam फ़ाइल का पथ शामिल है +- `normal_sample_file`: normal नमूना फ़ाइल +- `tumor_meta_map`: tumor नमूना मेटा डेटा जिसमें type, replicate और bam फ़ाइल का पथ शामिल है +- `tumor_sample`: tumor नमूना जिसमें type, replicate और bam फ़ाइल का पथ शामिल है + +!!! warning + + `join` ऑपरेटर किसी भी बेमेल tuple को त्याग देगा। इस उदाहरण में, हमने यह सुनिश्चित किया कि सभी नमूने tumor और normal के लिए मेल खाते थे, लेकिन यदि यह सच नहीं है तो आपको बेमेल tuple रखने के लिए पैरामीटर `remainder: true` का उपयोग करना होगा। अधिक विवरण के लिए [दस्तावेज़ीकरण](https://www.nextflow.io/docs/latest/operator.html#join) देखें। + +तो अब आप जानते हैं कि tuple में किसी फ़ील्ड को अलग करने के लिए `map` का उपयोग कैसे करें, और पहले फ़ील्ड के आधार पर tuple को संयोजित करने के लिए `join` का उपयोग कैसे करें। +इस ज्ञान के साथ, हम साझा फ़ील्ड के आधार पर channel को सफलतापूर्वक संयोजित कर सकते हैं। + +अगला, हम उस स्थिति पर विचार करेंगे जहाँ आप कई फ़ील्ड पर join करना चाहते हैं। + +### 3.2. कई फ़ील्ड पर join करें + +हमारे पास sampleA के लिए 2 replicates हैं, लेकिन sampleB और sampleC के लिए केवल 1। इस मामले में हम `id` फ़ील्ड का उपयोग करके उन्हें प्रभावी ढंग से join करने में सक्षम थे, लेकिन क्या होगा यदि वे sync से बाहर हों? हम विभिन्न replicates से normal और tumor नमूनों को मिला सकते हैं! + +इससे बचने के लिए, हम कई फ़ील्ड पर join कर सकते हैं। वास्तव में इसे प्राप्त करने के कई तरीके हैं लेकिन हम एक नई joining key बनाने पर ध्यान केंद्रित करने जा रहे हैं जिसमें नमूना `id` और `replicate` number दोनों शामिल हैं। + +चलिए एक नई joining key बनाने से शुरू करते हैं। हम पहले की तरह [`map` ऑपरेटर](https://www.nextflow.io/docs/latest/operator.html#map) का उपयोग करके ऐसा कर सकते हैं ताकि एक नया tuple बनाया जा सके जिसमें `id` और `repeat` फ़ील्ड पहले तत्व के रूप में हों। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +अब हमें join होता दिखना चाहिए लेकिन `id` और `repeat` दोनों फ़ील्ड का उपयोग करते हुए। वर्कफ़्लो चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +ध्यान दें कि हमारे पास प्रत्येक joined परिणाम के पहले तत्व के रूप में दो तत्वों (`id` और `repeat` फ़ील्ड) का एक tuple है। यह दर्शाता है कि जटिल आइटम को joining key के रूप में कैसे उपयोग किया जा सकता है, जो एक ही स्थितियों से नमूनों के बीच काफी जटिल मिलान को सक्षम बनाता है। + +यदि आप विभिन्न keys पर join करने के अधिक तरीकों का पता लगाना चाहते हैं, तो अतिरिक्त विकल्पों और उदाहरणों के लिए [join ऑपरेटर दस्तावेज़ीकरण](https://www.nextflow.io/docs/latest/operator.html#join) देखें। + +### 3.3. नई joining key बनाने के लिए `subMap` का उपयोग करें + +पिछला दृष्टिकोण हमारी joining key से फ़ील्ड नामों को खो देता है - `id` और `repeat` फ़ील्ड केवल मूल्यों की एक list बन जाते हैं। बाद में पहुँच के लिए फ़ील्ड नामों को बनाए रखने के लिए, हम [`subMap` method](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>) का उपयोग कर सकते हैं। + +`subMap` method एक map से केवल निर्दिष्ट key-value pairs को extract करता है। यहाँ हम अपनी joining key बनाने के लिए केवल `id` और `repeat` फ़ील्ड को extract करेंगे। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +अब हमारे पास एक नई joining key है जो न केवल `id` और `repeat` फ़ील्ड शामिल करती है, बल्कि फ़ील्ड नामों को भी बनाए रखती है ताकि हम उन्हें बाद में नाम से एक्सेस कर सकें, जैसे `meta.id` और `meta.repeat`। + +### 3.4. map में named closure का उपयोग करें + +डुप्लीकेशन से बचने और त्रुटियों को कम करने के लिए, हम एक named closure का उपयोग कर सकते हैं। एक named closure हमें एक पुन: प्रयोज्य फ़ंक्शन बनाने की अनुमति देता है जिसे हम कई स्थानों पर call कर सकते हैं। + +ऐसा करने के लिए, पहले हम closure को एक नए वेरिएबल के रूप में परिभाषित करते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +हमने map transformation को एक named वेरिएबल के रूप में परिभाषित किया है जिसे हम पुन: उपयोग कर सकते हैं। + +ध्यान दें कि हम फ़ाइल पथ को `file()` का उपयोग करके एक Path object में भी convert करते हैं ताकि इस channel को प्राप्त करने वाली कोई भी process फ़ाइल को सही ढंग से handle कर सके (अधिक जानकारी के लिए [Working with files](./working_with_files.md) देखें)। + +चलिए अपने वर्कफ़्लो में closure को implement करते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + `map` ऑपरेटर closure को एक argument के रूप में पास करने के लिए `{ }` के बजाय `( )` का उपयोग करने के लिए स्विच हो गया है। ऐसा इसलिए है क्योंकि `map` ऑपरेटर एक closure को argument के रूप में अपेक्षा करता है और `{ }` का उपयोग anonymous closure को परिभाषित करने के लिए किया जाता है। named closure को call करते समय, `( )` syntax का उपयोग करें। + +यह जांचने के लिए कि सबकुछ अभी भी काम कर रहा है, वर्कफ़्लो को एक बार और चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +named closure का उपयोग करने से हम कई स्थानों पर एक ही transformation को पुन: उपयोग कर सकते हैं, जिससे त्रुटियों का जोखिम कम होता है और कोड अधिक पठनीय और रखरखाव योग्य बनता है। + +### 3.5. डेटा के डुप्लीकेशन को कम करें + +हमारे वर्कफ़्लो में बहुत सारा डुप्लिकेट डेटा है। joined नमूनों में प्रत्येक आइटम `id` और `repeat` फ़ील्ड को दोहराता है। चूँकि यह जानकारी पहले से grouping key में उपलब्ध है, इसलिए हम इस अतिरेक से बच सकते हैं। एक reminder के रूप में, हमारी वर्तमान डेटा संरचना इस तरह दिखती है: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +चूँकि `id` और `repeat` फ़ील्ड grouping key में उपलब्ध हैं, चलिए डुप्लीकेशन से बचने के लिए प्रत्येक channel आइटम के बाकी हिस्सों से उन्हें हटाते हैं। हम केवल `type` फ़ील्ड के साथ एक नया map बनाने के लिए `subMap` method का उपयोग कर सकते हैं। यह दृष्टिकोण हमें हमारे डेटा संरचना में अतिरेक को समाप्त करते हुए सभी आवश्यक जानकारी बनाए रखने की अनुमति देता है। + +=== "बाद" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +अब closure एक tuple लौटाता है जहाँ पहले तत्व में `id` और `repeat` फ़ील्ड हैं, और दूसरे तत्व में केवल `type` फ़ील्ड है। यह grouping key diff --git a/docs/hi/docs/side_quests/workflows_of_workflows.md b/docs/hi/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..bd33fb6b8d --- /dev/null +++ b/docs/hi/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# वर्कफ़्लो के वर्कफ़्लो + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +जब आप एक pipeline विकसित कर रहे होते हैं, तो आप अक्सर खुद को विभिन्न डेटा प्रकारों या विश्लेषण चरणों के लिए समान प्रक्रियाओं के अनुक्रम बनाते हुए पाते हैं। आप इन process अनुक्रमों को कॉपी और पेस्ट करते हुए समाप्त हो सकते हैं, जिससे डुप्लिकेट कोड बनता है जिसे बनाए रखना कठिन होता है; या आप एक विशाल workflow बना सकते हैं जो समझना और संशोधित करना मुश्किल है। + +Nextflow की सबसे शक्तिशाली विशेषताओं में से एक छोटे, पुन: प्रयोज्य workflow मॉड्यूल से जटिल pipelines बनाने की इसकी क्षमता है। यह modular दृष्टिकोण pipelines को विकसित करना, परीक्षण करना और बनाए रखना आसान बनाता है। + +### सीखने के लक्ष्य + +इस side quest में, हम ऐसे workflow मॉड्यूल विकसित करने का पता लगाएंगे जिन्हें अलग से परीक्षण और उपयोग किया जा सकता है, उन मॉड्यूल को एक बड़े pipeline में संयोजित करेंगे, और मॉड्यूल के बीच डेटा प्रवाह का प्रबंधन करेंगे। + +इस side quest के अंत तक, आप निम्न करने में सक्षम होंगे: + +- जटिल pipelines को तार्किक, पुन: प्रयोज्य इकाइयों में विभाजित करना +- प्रत्येक workflow मॉड्यूल का स्वतंत्र रूप से परीक्षण करना +- नए pipelines बनाने के लिए workflows को मिलाना और मिलान करना +- विभिन्न pipelines में सामान्य workflow मॉड्यूल साझा करना +- अपने कोड को अधिक maintainable और समझने में आसान बनाना + +ये कौशल आपको स्वच्छ, maintainable कोड संरचना बनाए रखते हुए जटिल pipelines बनाने में मदद करेंगे। + +### पूर्वापेक्षाएँ + +इस side quest को शुरू करने से पहले आपको: + +- [Hello Nextflow](../hello_nextflow/README.md) ट्यूटोरियल या समकक्ष शुरुआती पाठ्यक्रम पूरा किया होना चाहिए। +- बुनियादी Nextflow अवधारणाओं और तंत्रों (processes, channels, operators, modules) का उपयोग करने में सहज होना चाहिए + +--- + +## 0. शुरुआत करें + +#### प्रशिक्षण codespace खोलें + +यदि आपने अभी तक ऐसा नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार प्रशिक्षण वातावरण खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएं + +चलिए उस डायरेक्टरी में चलते हैं जहां इस ट्यूटोरियल के लिए फ़ाइलें स्थित हैं। + +```bash +cd side-quests/workflows_of_workflows +``` + +आप VSCode को इस डायरेक्टरी पर ध्यान केंद्रित करने के लिए सेट कर सकते हैं: + +```bash +code . +``` + +#### सामग्री की समीक्षा करें + +आपको एक `modules` डायरेक्टरी मिलेगी जिसमें कई process परिभाषाएं हैं जो 'Hello Nextflow' में आपने जो सीखा था उस पर आधारित हैं: + +```console title="डायरेक्टरी सामग्री" +modules/ +├── say_hello.nf # एक अभिवादन बनाता है (Hello Nextflow से) +├── say_hello_upper.nf # uppercase में परिवर्तित करता है (Hello Nextflow से) +├── timestamp_greeting.nf # अभिवादन में timestamps जोड़ता है +├── validate_name.nf # इनपुट नामों को validate करता है +└── reverse_text.nf # टेक्स्ट सामग्री को उलट देता है +``` + +#### असाइनमेंट की समीक्षा करें + +आपकी चुनौती इन मॉड्यूल को दो अलग workflows में असेंबल करना है जिन्हें हम फिर एक मुख्य workflow में संयोजित करेंगे: + +- एक `GREETING_WORKFLOW` जो नामों को validate करता है, अभिवादन बनाता है, और timestamps जोड़ता है +- एक `TRANSFORM_WORKFLOW` जो टेक्स्ट को uppercase में परिवर्तित करता है और इसे उलट देता है + +#### तैयारी चेकलिस्ट + +लगता है कि आप शुरू करने के लिए तैयार हैं? + +- [ ] मैं इस पाठ्यक्रम के लक्ष्य और इसकी पूर्वापेक्षाओं को समझता/समझती हूं +- [ ] मेरा codespace चल रहा है +- [ ] मैंने अपनी working डायरेक्टरी उचित रूप से सेट की है +- [ ] मैं असाइनमेंट को समझता/समझती हूं + +यदि आप सभी बॉक्स को चेक कर सकते हैं, तो आप जाने के लिए तैयार हैं। + +--- + +## 1. Greeting Workflow बनाएं + +चलिए एक workflow बनाकर शुरू करते हैं जो नामों को validate करता है और timestamped अभिवादन उत्पन्न करता है। + +### 1.1. workflow संरचना बनाएं + +```bash title="workflow डायरेक्टरी और फ़ाइल बनाएं" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. पहले (sub)workflow कोड जोड़ें + +यह कोड `workflows/greeting.nf` में जोड़ें: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Processes की chain: validate -> greeting बनाएं -> timestamp जोड़ें + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +यह एक पूर्ण workflow है, जिसकी संरचना 'Hello Nextflow' ट्यूटोरियल में आपने देखे गए workflows के समान है, जिसे हम स्वतंत्र रूप से परीक्षण कर सकते हैं। चलिए अब इसे आज़माते हैं: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +यह अपेक्षा के अनुसार काम करता है, लेकिन इसे composable बनाने के लिए हमें कुछ चीजें बदलने की आवश्यकता है। + +### 1.3. workflow को composable बनाएं + +Composable workflows में 'Hello Nextflow' ट्यूटोरियल में आपने देखे गए workflows से कुछ अंतर हैं: + +- workflow block को नाम दिए जाने की आवश्यकता है +- इनपुट `take:` keyword का उपयोग करके घोषित किए जाते हैं +- Workflow सामग्री `main:` block के अंदर रखी जाती है +- आउटपुट `emit:` keyword का उपयोग करके घोषित किए जाते हैं + +चलिए greeting workflow को इस संरचना से मेल खाने के लिए अपडेट करते हैं। कोड को निम्नलिखित में बदलें: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // इनपुट channel नामों के साथ + + main: + // Processes की chain: validate -> greeting बनाएं -> timestamp जोड़ें + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // मूल अभिवादन + timestamped = timestamped_ch // Timestamped अभिवादन +} +``` + +आप देख सकते हैं कि workflow को अब नाम दिया गया है और इसमें `take:` और `emit:` block है, और ये वे कनेक्शन हैं जिनका उपयोग हम उच्च स्तर के workflow को संयोजित करने के लिए करेंगे। +Workflow सामग्री भी `main:` block के अंदर रखी गई है। यह भी नोट करें कि हमने `names_ch` इनपुट channel घोषणा को हटा दिया है, क्योंकि इसे अब workflow को एक argument के रूप में पास किया जाता है। + +चलिए यह देखने के लिए workflow को फिर से परीक्षण करते हैं कि क्या यह अपेक्षा के अनुसार काम करता है: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +यह आपको एक अन्य नई अवधारणा के बारे में बताता है, एक 'entry workflow'। Entry workflow वह workflow है जो तब कॉल किया जाता है जब आप एक Nextflow script चलाते हैं। डिफ़ॉल्ट रूप से, Nextflow एक unnamed workflow को entry workflow के रूप में उपयोग करेगा, जब मौजूद हो, और यह वही है जो आप अब तक कर रहे थे, workflow blocks इस तरह शुरू करते हुए: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +लेकिन हमारे greeting workflow में un-named workflow नहीं है, बल्कि हमारे पास एक named workflow है: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +इसलिए Nextflow ने एक error फेंकी और वह नहीं किया जो हम चाहते थे। + +हमने `take:`/`emit:` सिंटैक्स इसलिए नहीं जोड़ा कि हम workflow को सीधे कॉल कर सकें - हमने इसे इसलिए किया कि हम इसे अन्य workflows के साथ संयोजित कर सकें। समाधान एक मुख्य script बनाना है जिसमें एक unnamed entry workflow हो जो हमारे named workflow को import और कॉल करे। + +### 1.4. मुख्य workflow बनाएं और परीक्षण करें + +अब हम एक मुख्य workflow बनाएंगे जो `greeting` workflow को import और उपयोग करता है। + +`main.nf` बनाएं: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +नोट करें कि इस फ़ाइल में हमारी workflow entry un-named है, और ऐसा इसलिए है क्योंकि हम इसे entry workflow के रूप में उपयोग करने जा रहे हैं। + +इसे चलाएं और आउटपुट देखें: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +यह काम करता है! हमने named greeting workflow को एक मुख्य workflow में लपेटा है जिसमें un-named entry `workflow` block है। मुख्य workflow `GREETING_WORKFLOW` workflow का उपयोग लगभग (बिल्कुल नहीं) एक process की तरह कर रहा है, और `names` channel को एक argument के रूप में पास कर रहा है। + +### मुख्य बात + +इस खंड में, आपने कई महत्वपूर्ण अवधारणाएं सीखी हैं: + +- **Named Workflows**: एक named workflow (`GREETING_WORKFLOW`) बनाना जिसे import और पुन: उपयोग किया जा सकता है +- **Workflow Interfaces**: एक composable workflow बनाने के लिए `take:` के साथ स्पष्ट इनपुट और `emit:` के साथ आउटपुट परिभाषित करना +- **Entry Points**: यह समझना कि Nextflow को एक script चलाने के लिए एक unnamed entry workflow की आवश्यकता होती है +- **Workflow Composition**: एक अन्य workflow के भीतर named workflow को import और उपयोग करना +- **Workflow Namespaces**: `.out` namespace का उपयोग करके workflow आउटपुट तक पहुंचना (`GREETING_WORKFLOW.out.greetings`) + +अब आपके पास एक काम करने वाला greeting workflow है जो: + +- इनपुट के रूप में नामों के channel लेता है +- प्रत्येक नाम को validate करता है +- प्रत्येक valid नाम के लिए एक अभिवादन बनाता है +- अभिवादन में timestamps जोड़ता है +- मूल और timestamped दोनों अभिवादन को आउटपुट के रूप में expose करता है + +यह modular दृष्टिकोण आपको greeting workflow को स्वतंत्र रूप से परीक्षण करने या बड़े pipelines में एक component के रूप में उपयोग करने की अनुमति देता है। + +--- + +## 2. Transform Workflow जोड़ें + +अब चलिए एक workflow बनाते हैं जो अभिवादन पर text transformations लागू करता है। + +### 2.1. workflow फ़ाइल बनाएं + +```bash +touch workflows/transform.nf +``` + +### 2.2. workflow कोड जोड़ें + +यह कोड `workflows/transform.nf` में जोड़ें: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // संदेशों के साथ इनपुट channel + + main: + // क्रम में transformations लागू करें + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Uppercase अभिवादन + reversed = reversed_ch // Reversed uppercase अभिवादन +} +``` + +हम यहां composable सिंटैक्स की व्याख्या नहीं दोहराएंगे, लेकिन ध्यान दें कि named workflow फिर से `take:` और `emit:` block के साथ घोषित किया गया है, और workflow सामग्री `main:` block के अंदर रखी गई है। + +### 2.3. मुख्य workflow को अपडेट करें + +दोनों workflows का उपयोग करने के लिए `main.nf` को अपडेट करें: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // greeting workflow चलाएं + GREETING_WORKFLOW(names) + + // transform workflow चलाएं + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // परिणाम देखें + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +पूर्ण pipeline चलाएं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +यदि आप उन reversed फ़ाइलों में से एक पर नज़र डालते हैं, तो आप देखेंगे कि यह अभिवादन का uppercase संस्करण उलटा है: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Reversed फ़ाइल सामग्री" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### मुख्य बात + +अब आपके पास एक पूर्ण pipeline होना चाहिए जो: + +- greeting workflow के माध्यम से नामों को प्रोसेस करता है +- timestamped अभिवादन को transform workflow में भेजता है +- अभिवादन के uppercase और reversed दोनों संस्करण उत्पन्न करता है + +--- + +## सारांश + +इस side quest में, हमने Nextflow में workflow composition की शक्तिशाली अवधारणा का पता लगाया है, जो हमें छोटे, पुन: प्रयोज्य components से जटिल pipelines बनाने की अनुमति देती है। + +यह modular दृष्टिकोण monolithic pipelines की तुलना में कई लाभ प्रदान करता है: + +- प्रत्येक workflow को स्वतंत्र रूप से विकसित, परीक्षण और debug किया जा सकता है +- Workflows को विभिन्न pipelines में पुन: उपयोग किया जा सकता है +- समग्र pipeline संरचना अधिक पठनीय और maintainable बन जाती है +- एक workflow में परिवर्तन अन्य को जरूरी नहीं प्रभावित करते हैं यदि interfaces सुसंगत रहें +- Entry points को आपके pipeline के विभिन्न भागों को आवश्यकतानुसार चलाने के लिए कॉन्फ़िगर किया जा सकता है + +_यह ध्यान रखना महत्वपूर्ण है कि workflows को कॉल करना थोड़ा processes को कॉल करने जैसा है, लेकिन यह वास्तव में एक ही चीज नहीं है। उदाहरण के लिए, आप N आकार के channel के साथ इसे कॉल करके एक workflow को N बार नहीं चला सकते - आपको workflow को N आकार के channel को पास करने और आंतरिक रूप से iterate करने की आवश्यकता होगी।_ + +अपने स्वयं के काम में इन तकनीकों को लागू करने से आप अधिक परिष्कृत Nextflow pipelines बनाने में सक्षम होंगे जो maintainable और scalable रहते हुए जटिल bioinformatics कार्यों को संभाल सकते हैं। + +### मुख्य पैटर्न + +1. **Workflow संरचना**: हमने `take:` और `emit:` सिंटैक्स का उपयोग करके प्रत्येक workflow के लिए स्पष्ट इनपुट और आउटपुट परिभाषित किए, components के बीच अच्छी तरह से परिभाषित interfaces बनाए, और `main:` block के भीतर workflow तर्क को लपेटा। + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // इनपुट channels यहां घोषित किए जाते हैं + input_ch + + main: + // Workflow logic यहां जाता है + // यह वह जगह है जहां processes को कॉल किया जाता है और channels को manipulate किया जाता है + result_ch = SOME_PROCESS(input_ch) + + emit: + // आउटपुट channels यहां घोषित किए जाते हैं + output_ch = result_ch + } + ``` + +2. **Workflow imports:** हमने दो स्वतंत्र workflow मॉड्यूल बनाए और उन्हें include statements के साथ एक मुख्य pipeline में import किया। + + - एकल workflow include करें + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - एकाधिक workflows include करें + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - नाम संघर्षों से बचने के लिए alias के साथ include करें + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Entry points**: Nextflow को यह जानने के लिए एक unnamed entry workflow की आवश्यकता होती है कि निष्पादन कहां से शुरू करना है। यह entry workflow आपके named workflows को कॉल करता है। + + - Unnamed workflow (entry point) + + ```groovy + workflow { + // यह entry point है जब script को चलाया जाता है + NAMED_WORKFLOW(input_ch) + } + ``` + + - Named workflow (entry workflow से कॉल किया जाता है) + + ```groovy + workflow NAMED_WORKFLOW { + // entry workflow से कॉल किया जाना चाहिए + } + ``` + +4. **डेटा प्रवाह का प्रबंधन:** हमने सीखा कि namespace notation (`WORKFLOW_NAME.out.channel_name`) का उपयोग करके workflow आउटपुट तक कैसे पहुंचें और उन्हें अन्य workflows को पास करें। + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### अतिरिक्त संसाधन + +- [Nextflow Workflow Documentation](https://www.nextflow.io/docs/latest/workflow.html) +- [Channel Operators Reference](https://www.nextflow.io/docs/latest/operator.html) +- [Error Strategy Documentation](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## आगे क्या है? + +[Side Quests के मेनू](./index.md) पर वापस जाएं या सूची में अगले विषय पर जाने के लिए पृष्ठ के निचले दाहिने कोने में बटन पर क्लिक करें। diff --git a/docs/hi/docs/side_quests/working_with_files.md b/docs/hi/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..560d3b2eac --- /dev/null +++ b/docs/hi/docs/side_quests/working_with_files.md @@ -0,0 +1,2040 @@ +# फ़ाइल इनपुट प्रोसेसिंग + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +वैज्ञानिक विश्लेषण workflows में अक्सर बड़ी संख्या में फ़ाइलों को प्रोसेस करना शामिल होता है। +Nextflow फ़ाइलों को कुशलता से संभालने के लिए शक्तिशाली टूल प्रदान करता है, जो तुम्हें न्यूनतम कोड के साथ अपने डेटा को व्यवस्थित और प्रोसेस करने में मदद करता है। + +### सीखने के लक्ष्य + +इस side quest में, हम जानेंगे कि Nextflow फ़ाइलों को कैसे संभालता है, बुनियादी फ़ाइल ऑपरेशंस से लेकर फ़ाइल संग्रहों के साथ काम करने की अधिक उन्नत तकनीकों तक। +तुम सीखोगे कि फ़ाइलनामों से मेटाडेटा कैसे निकालना है, जो वैज्ञानिक विश्लेषण pipelines में एक सामान्य आवश्यकता है। + +इस side quest के अंत तक, तुम निम्नलिखित करने में सक्षम होंगे: + +- Nextflow की `file()` मेथड का उपयोग करके फ़ाइल path strings से Path ऑब्जेक्ट्स बनाना +- फ़ाइल विशेषताओं जैसे name, extension, और parent डायरेक्टरी तक पहुँचना +- URIs का उपयोग करके लोकल और रिमोट फ़ाइलों को पारदर्शी रूप से संभालना +- `channel.fromPath()` और `channel.fromFilePairs()` के साथ फ़ाइल हैंडलिंग को स्वचालित करने के लिए channels का उपयोग करना +- string manipulation का उपयोग करके फ़ाइलनामों से मेटाडेटा निकालना और संरचित करना +- पैटर्न मैचिंग और glob expressions का उपयोग करके संबंधित फ़ाइलों को ग्रुप करना +- उचित इनपुट हैंडलिंग के साथ फ़ाइल ऑपरेशंस को Nextflow processes में इंटीग्रेट करना +- मेटाडेटा-संचालित डायरेक्टरी संरचनाओं का उपयोग करके process आउटपुट को व्यवस्थित करना + +ये कौशल तुम्हें ऐसे workflows बनाने में मदद करेंगे जो विभिन्न प्रकार के फ़ाइल इनपुट को बहुत लचीलेपन के साथ संभाल सकते हैं। + +### पूर्वापेक्षाएँ + +इस side quest को शुरू करने से पहले, तुम्हें: + +- [Hello Nextflow](../../hello_nextflow/) ट्यूटोरियल या समकक्ष बिगिनर कोर्स पूरा कर लेना चाहिए। +- बुनियादी Nextflow अवधारणाओं और मैकेनिज्म (processes, channels, operators) का उपयोग करने में सहज होना चाहिए + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. शुरू करें + +#### प्रशिक्षण codespace खोलें + +यदि तुमने अभी तक नहीं किया है, तो [Environment Setup](../envsetup/index.md) में वर्णित अनुसार प्रशिक्षण वातावरण खोलना सुनिश्चित करें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### प्रोजेक्ट डायरेक्टरी में जाएं + +चलो उस डायरेक्टरी में जाते हैं जहाँ इस ट्यूटोरियल की फ़ाइलें स्थित हैं। + +```bash +cd side-quests/working_with_files +``` + +तुम VSCode को इस डायरेक्टरी पर फोकस करने के लिए सेट कर सकते हो: + +```bash +code . +``` + +#### सामग्री की समीक्षा करें + +तुम्हें `main.nf` नामक एक सरल workflow फ़ाइल, दो मॉड्यूल फ़ाइलों वाली `modules` डायरेक्टरी, और कुछ उदाहरण डेटा फ़ाइलों वाली `data` डायरेक्टरी मिलेगी। + +??? abstract "डायरेक्टरी सामग्री" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +इस डायरेक्टरी में तीन मरीजों (A, B, C) से paired-end सीक्वेंसिंग डेटा है। + +प्रत्येक मरीज के लिए, हमारे पास नमूने हैं जो `tumor` प्रकार के हैं (आमतौर पर ट्यूमर बायोप्सी से उत्पन्न) या `normal` (स्वस्थ ऊतक या रक्त से लिए गए)। +यदि तुम कैंसर विश्लेषण से परिचित नहीं हो, बस जान लो कि यह एक प्रयोगात्मक मॉडल से मेल खाता है जो कंट्रास्टिव विश्लेषण करने के लिए paired tumor/normal नमूनों का उपयोग करता है। + +विशेष रूप से मरीज A के लिए, हमारे पास तकनीकी प्रतिकृतियों (दोहराव) के दो सेट हैं। + +सीक्वेंसिंग डेटा फ़ाइलों को एक सामान्य `_R1_` और `_R2_` कन्वेंशन के साथ नामित किया गया है जो 'forward reads' और 'reverse reads' के रूप में जानी जाती हैं। + +_अगर तुम इस प्रयोगात्मक डिज़ाइन से परिचित नहीं हो तो चिंता मत करो, यह इस ट्यूटोरियल को समझने के लिए महत्वपूर्ण नहीं है।_ + +#### असाइनमेंट की समीक्षा करें + +तुम्हारी चुनौती एक Nextflow workflow लिखना है जो: + +1. Nextflow की फ़ाइल हैंडलिंग मेथड्स का उपयोग करके इनपुट फ़ाइलों को **लोड** करेगा +2. फ़ाइलनाम संरचना से मेटाडेटा (patient ID, replicate, sample type) **निकालेगा** +3. `channel.fromFilePairs()` का उपयोग करके paired फ़ाइलों (R1/R2) को एक साथ **ग्रुप** करेगा +4. प्रदान किए गए विश्लेषण मॉड्यूल के साथ फ़ाइलों को **प्रोसेस** करेगा +5. निकाले गए मेटाडेटा के आधार पर आउटपुट को डायरेक्टरी संरचना में **व्यवस्थित** करेगा + +#### तैयारी चेकलिस्ट + +क्या तुम शुरू करने के लिए तैयार हो? + +- [ ] मैं इस कोर्स का लक्ष्य और इसकी पूर्वापेक्षाएँ समझता/समझती हूँ +- [ ] मेरा codespace चल रहा है +- [ ] मैंने अपनी working डायरेक्टरी उचित रूप से सेट कर ली है +- [ ] मैं असाइनमेंट समझता/समझती हूँ + +यदि तुम सभी बॉक्स चेक कर सकते हो, तो तुम जाने के लिए तैयार हो। + +--- + +## 1. बुनियादी फ़ाइल ऑपरेशंस + +### 1.1. `.class` के साथ ऑब्जेक्ट के प्रकार की पहचान करें + +workflow फ़ाइल `main.nf` पर एक नज़र डालो: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +यह एक मिनी-workflow है (बिना किसी processes के) जो अपने workflow में एकल फ़ाइल path को संदर्भित करता है, फिर इसे कंसोल पर प्रिंट करता है, इसकी class के साथ। + +??? info "`.class` क्या है?" + + Nextflow में, `.class` हमें बताता है कि हम किस प्रकार के ऑब्जेक्ट के साथ काम कर रहे हैं। यह पूछने जैसा है "यह किस तरह की चीज़ है?" यह पता लगाने के लिए कि यह एक string है, एक number है, एक फ़ाइल है, या कुछ और। + यह हमें अगले अनुभागों में एक plain string और एक Path ऑब्जेक्ट के बीच अंतर को स्पष्ट करने में मदद करेगा। + +चलो workflow चलाते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +जैसा कि तुम देख सकते हो, Nextflow ने string path को ठीक वैसे ही प्रिंट किया जैसा हमने लिखा था। + +यह सिर्फ टेक्स्ट आउटपुट है; Nextflow ने अभी तक इसके साथ कुछ विशेष नहीं किया है। +हमने यह भी पुष्टि कर ली है कि जहाँ तक Nextflow का संबंध है, यह केवल एक string है (class `java.lang.String` की)। +यह समझ में आता है, क्योंकि हमने अभी तक Nextflow को नहीं बताया है कि यह एक फ़ाइल से मेल खाती है। + +### 1.2. file() के साथ Path ऑब्जेक्ट बनाएं + +हम path strings से [Path ऑब्जेक्ट्स](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) बनाकर Nextflow को बता सकते हैं कि फ़ाइलों को कैसे संभालना है। + +हमारे workflow में, हम `file()` मेथड का उपयोग करके string path `data/patientA_rep1_normal_R1_001.fastq.gz` को Path ऑब्जेक्ट में बदल सकते हैं, जो फ़ाइल प्रॉपर्टीज़ और ऑपरेशंस तक पहुँच प्रदान करती है। + +`main.nf` को एडिट करें और string को `file()` के साथ wrap करें जैसा कि नीचे दिखाया गया है: + +=== "बाद" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +अब workflow फिर से चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +इस बार, तुम देखते हो कि हमारे द्वारा इनपुट के रूप में प्रदान किए गए relative path के बजाय full absolute path दिख रहा है। + +Nextflow ने हमारी string को Path ऑब्जेक्ट में बदल दिया है और इसे सिस्टम पर वास्तविक फ़ाइल स्थान पर resolve कर दिया है। +फ़ाइल path अब absolute होगा, जैसे `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`। + +यह भी ध्यान दो कि Path ऑब्जेक्ट class `sun.nio.fs.UnixPath` है: यह Nextflow का लोकल फ़ाइलों का प्रतिनिधित्व करने का तरीका है। +जैसा कि हम बाद में देखेंगे, रिमोट फ़ाइलों की अलग-अलग class names होंगी (जैसे HTTP फ़ाइलों के लिए `nextflow.file.http.XPath`), लेकिन वे सभी ठीक उसी तरह काम करती हैं और तुम्हारे workflows में समान रूप से उपयोग की जा सकती हैं। + +!!! tip "सुझाव" + + **मुख्य अंतर:** + + - **Path string**: बस टेक्स्ट जिसे Nextflow अक्षरों के रूप में मानता है + - **Path ऑब्जेक्ट**: एक स्मार्ट फ़ाइल रेफरेंस जिसके साथ Nextflow काम कर सकता है + + इसे इस तरह सोचो: एक path string कागज पर पता लिखने जैसा है, जबकि Path ऑब्जेक्ट GPS डिवाइस में लोड किए गए पते जैसा है जो जानता है कि वहाँ कैसे नेविगेट करना है और यात्रा के बारे में विवरण बता सकता है। + +### 1.3. फ़ाइल विशेषताओं तक पहुँचें + +यह क्यों सहायक है? खैर, अब जब Nextflow समझ गया है कि `myFile` एक Path ऑब्जेक्ट है न कि सिर्फ एक string, हम Path ऑब्जेक्ट की विभिन्न विशेषताओं तक पहुँच सकते हैं। + +चलो अपने workflow को अपडेट करते हैं ताकि built-in फ़ाइल विशेषताएँ प्रिंट हों: + +=== "बाद" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +तुम ऊपर कंसोल पर प्रिंट की गई विभिन्न फ़ाइल विशेषताएँ देख सकते हो। + +### 1.4. फ़ाइल को process में फीड करें + +strings और Path ऑब्जेक्ट्स के बीच का अंतर तब महत्वपूर्ण हो जाता है जब तुम processes के साथ वास्तविक workflows बनाना शुरू करते हो। +अब तक हमने सत्यापित किया है कि Nextflow अब हमारी इनपुट फ़ाइल को फ़ाइल के रूप में मान रहा है, लेकिन देखते हैं कि क्या हम वास्तव में उस फ़ाइल पर एक process में कुछ चला सकते हैं। + +#### 1.4.1. process को import करें और कोड की जाँच करें + +हम तुम्हें `COUNT_LINES` नामक एक पूर्व-लिखित process मॉड्यूल प्रदान करते हैं जो एक फ़ाइल इनपुट लेता है और गिनता है कि इसमें कितनी लाइनें हैं। + +workflow में process का उपयोग करने के लिए, तुम्हें workflow block से पहले एक include स्टेटमेंट जोड़ना होगा: + +=== "बाद" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +तुम मॉड्यूल फ़ाइल को खोलकर इसके कोड की जाँच कर सकते हो: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +जैसा कि तुम देख सकते हो, यह एक काफी सीधी छोटी script है जो फ़ाइल को unzip करती है और गिनती करती है कि इसमें कितनी लाइनें हैं। + +??? info "`debug true` क्या करता है?" + + process definition में `debug true` निर्देश Nextflow को तुम्हारी script से आउटपुट (जैसे line count "40") सीधे execution log में प्रिंट करने का कारण बनता है। + इसके बिना, तुम केवल process execution status देखोगे लेकिन तुम्हारी script से वास्तविक आउटपुट नहीं। + + Nextflow processes को debug करने के बारे में अधिक जानकारी के लिए, [Debugging Nextflow Workflows](debugging.md) side quest देखें। + +#### 1.4.2. `COUNT_LINES` को कॉल जोड़ें + +अब जब process workflow के लिए उपलब्ध है, हम इनपुट फ़ाइल पर इसे चलाने के लिए `COUNT_LINES` process को कॉल जोड़ सकते हैं। + +workflow में निम्नलिखित एडिट करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // फ़ाइल में लाइनें गिनें + COUNT_LINES(myFile) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +और अब workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +यह दिखाता है कि हम एक process के अंदर फ़ाइल पर उचित रूप से ऑपरेट करने में सक्षम हैं। + +विशेष रूप से, Nextflow ने निम्नलिखित ऑपरेशंस सफलतापूर्वक किए: + +- फ़ाइल को working डायरेक्टरी में stage किया +- .gz फ़ाइल को decompress किया +- लाइनें गिनीं (इस मामले में 40 लाइनें) +- बिना error के पूरा हुआ + +इस सुगम ऑपरेशन की कुंजी यह है कि हम Nextflow को स्पष्ट रूप से बता रहे हैं कि हमारा इनपुट एक फ़ाइल है और इसे इस प्रकार माना जाना चाहिए। + +### 1.5. बुनियादी फ़ाइल इनपुट errors का समस्या निवारण + +यह अक्सर Nextflow के नए उपयोगकर्ताओं को परेशान करता है, तो चलो कुछ मिनट लेते हैं यह देखने के लिए कि जब तुम इसे गलत करते हो तो क्या होता है। + +दो मुख्य स्थान हैं जहाँ तुम फ़ाइल हैंडलिंग गलत कर सकते हो: workflow के स्तर पर, और process के स्तर पर। + +#### 1.5.1. Workflow-स्तर error + +देखते हैं क्या होता है अगर हम workflow block में इनपुट निर्दिष्ट करते समय फ़ाइल को string के रूप में मानते हैं। + +workflow में निम्नलिखित एडिट करें, path-विशिष्ट print statements को comment out करना सुनिश्चित करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // फ़ाइल में लाइनें गिनें + COUNT_LINES(myFile) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // फ़ाइल में लाइनें गिनें + COUNT_LINES(myFile) + ``` + +और अब workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +यह महत्वपूर्ण हिस्सा है: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +जब तुम `path` इनपुट निर्दिष्ट करते हो, Nextflow सत्यापित करता है कि तुम वास्तविक फ़ाइल references पास कर रहे हो, न कि सिर्फ strings। +यह error तुम्हें बता रहा है कि `'data/patientA_rep1_normal_R1_001.fastq.gz'` एक valid path value नहीं है क्योंकि यह एक string है, Path ऑब्जेक्ट नहीं। + +Nextflow ने तुरंत समस्या का पता लगाया और process शुरू करने से पहले ही रुक गया। + +#### 1.5.2. Process-स्तर error + +दूसरी जगह जहाँ हम निर्दिष्ट करना भूल सकते हैं कि हम चाहते हैं कि Nextflow इनपुट को फ़ाइल के रूप में माने, वह process definition में है। + +!!! warning "चेतावनी" + + इस टेस्ट के सही ढंग से काम करने के लिए, workflow को उसकी टूटी हुई अवस्था में रखो (`file()` के बजाय plain string का उपयोग करके)। + जब process में `val` के साथ जोड़ा जाता है, तो यह नीचे दिखाया गया error उत्पन्न करता है। + +मॉड्यूल में निम्नलिखित एडिट करें: + +=== "बाद" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "पहले" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +और अब workflow फिर से चलाओ: + +```bash +nextflow run main.nf +``` + +??? failure "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +यह error के बारे में बहुत सारे विवरण दिखाता है क्योंकि process debugging जानकारी आउटपुट करने के लिए सेट है, जैसा कि ऊपर नोट किया गया है। + +ये सबसे प्रासंगिक अनुभाग हैं: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +यह कहता है कि सिस्टम फ़ाइल नहीं ढूंढ सका; हालाँकि अगर तुम path देखो, उस नाम की एक फ़ाइल उस स्थान पर है। + +जब हमने यह चलाया, Nextflow ने string value को script में pass किया, लेकिन इसने वास्तविक फ़ाइल को working डायरेक्टरी में _stage_ नहीं किया। +इसलिए process ने relative string, `data/patientA_rep1_normal_R1_001.fastq.gz` का उपयोग करने की कोशिश की, लेकिन वह फ़ाइल process working डायरेक्टरी के भीतर मौजूद नहीं है। + +इन दोनों उदाहरणों को मिलाकर, तुम देख सकते हो कि Nextflow को बताना कितना महत्वपूर्ण है कि क्या किसी इनपुट को फ़ाइल के रूप में संभाला जाना चाहिए। + +!!! note "नोट" + + अगले अनुभाग पर जाने से पहले दोनों जानबूझकर errors को ठीक करना सुनिश्चित करो। + +### सीख + +- Path strings बनाम Path ऑब्जेक्ट्स: Strings बस टेक्स्ट हैं, Path ऑब्जेक्ट्स स्मार्ट फ़ाइल references हैं +- `file()` मेथड एक string path को Path ऑब्जेक्ट में बदलती है जिसके साथ Nextflow काम कर सकता है +- तुम [file attributes का उपयोग करके](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) फ़ाइल प्रॉपर्टीज़ जैसे `name`, `simpleName`, `extension`, और `parent` तक पहुँच सकते हो +- strings के बजाय Path ऑब्जेक्ट्स का उपयोग Nextflow को तुम्हारे workflow में फ़ाइलों को ठीक से प्रबंधित करने की अनुमति देता है +- Process इनपुट परिणाम: उचित फ़ाइल हैंडलिंग के लिए strings नहीं, Path ऑब्जेक्ट्स की आवश्यकता होती है, यह सुनिश्चित करने के लिए कि फ़ाइलें processes द्वारा उपयोग के लिए सही ढंग से staged और accessible हैं। + +--- + +## 2. रिमोट फ़ाइलों का उपयोग + +Nextflow की प्रमुख विशेषताओं में से एक लोकल फ़ाइलों (उसी मशीन पर) से इंटरनेट पर accessible रिमोट फ़ाइलों पर seamlessly switch करने की क्षमता है। + +यदि तुम इसे सही ढंग से कर रहे हो, तो विभिन्न स्थानों से आने वाली फ़ाइलों को accommodate करने के लिए तुम्हें अपने workflow के लॉजिक को कभी बदलने की आवश्यकता नहीं होनी चाहिए। +रिमोट फ़ाइल का उपयोग करने के लिए तुम्हें बस इतना करना है कि फ़ाइल path में उचित prefix निर्दिष्ट करो जब तुम इसे workflow को supply कर रहे हो। + +उदाहरण के लिए, `/path/to/data` में कोई prefix नहीं है, जो दर्शाता है कि यह एक 'normal' लोकल फ़ाइल path है, जबकि `s3://path/to/data` में `s3://` prefix शामिल है, जो दर्शाता है कि यह Amazon के S3 ऑब्जेक्ट स्टोरेज में स्थित है। + +कई अलग-अलग protocols समर्थित हैं: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +इनमें से किसी का भी उपयोग करने के लिए, बस string में relevant prefix निर्दिष्ट करो, जिसे तकनीकी रूप से फ़ाइल path के बजाय Uniform Resource Identifier (URI) कहा जाता है। +Nextflow authentication और फ़ाइलों को सही जगह पर staging को संभालेगा, downloading या uploading और अन्य सभी फ़ाइल ऑपरेशंस जो तुम expect करोगे। + +इस सिस्टम की मुख्य ताकत यह है कि यह हमें किसी भी pipeline लॉजिक को बदले बिना environments के बीच switch करने में सक्षम बनाता है। +उदाहरण के लिए, तुम एक छोटे, लोकल टेस्ट सेट के साथ develop कर सकते हो और फिर बस URI बदलकर रिमोट स्टोरेज में स्थित full-scale टेस्ट सेट पर switch कर सकते हो। + +### 2.1. इंटरनेट से फ़ाइल का उपयोग करें + +चलो इसे टेस्ट करते हैं अपने workflow को दिए जा रहे लोकल path को एक HTTPS path से बदलकर जो Github में stored उसी डेटा की एक कॉपी को point करता है। + +!!! warning "चेतावनी" + + यह तभी काम करेगा जब तुम्हारे पास active इंटरनेट कनेक्शन है। + +`main.nf` फिर से खोलो और इनपुट path को निम्नानुसार बदलो: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // इंटरनेट से रिमोट फ़ाइल का उपयोग + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +चलो workflow चलाते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +यह काम करता है! तुम देख सकते हो कि बहुत कम बदला है। + +कंसोल आउटपुट में एक अंतर यह है कि path object class अब `nextflow.file.http.XPath` है, जबकि लोकल path के लिए class `sun.nio.fs.UnixPath` थी। +तुम्हें इन classes को याद रखने की आवश्यकता नहीं है; हम इसका उल्लेख बस यह प्रदर्शित करने के लिए करते हैं कि Nextflow विभिन्न स्थानों को उचित रूप से पहचानता और संभालता है। + +पर्दे के पीछे, Nextflow ने फ़ाइल को work डायरेक्टरी के भीतर स्थित staging डायरेक्टरी में download किया। +उस staged फ़ाइल को फिर लोकल फ़ाइल के रूप में माना जा सकता है और relevant process डायरेक्टरी में symlinked किया जा सकता है। + +तुम process के hash value पर स्थित working डायरेक्टरी की सामग्री देखकर यह सत्यापित कर सकते हो कि ऐसा हुआ। + +??? abstract "Work डायरेक्टरी सामग्री" + + यदि process hash `8a/2ab7ca` था, तुम work डायरेक्टरी explore कर सकते हो: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Symlink रिमोट फ़ाइल की staged copy को point करता है जिसे Nextflow ने automatically download किया। + +ध्यान दो कि बड़ी फ़ाइलों के लिए, downloading step लोकल फ़ाइलों पर चलने की तुलना में कुछ अतिरिक्त समय लेगा। +हालाँकि, Nextflow check करता है कि क्या उसके पास पहले से staged copy है ताकि अनावश्यक downloads से बचा जा सके। +इसलिए यदि तुम उसी फ़ाइल पर फिर से run करते हो और staged फ़ाइल को delete नहीं किया है, Nextflow staged copy का उपयोग करेगा। + +यह दिखाता है कि Nextflow का उपयोग करके लोकल और रिमोट डेटा के बीच switch करना कितना आसान है, जो Nextflow की एक प्रमुख विशेषता है। + +!!! note "नोट" + + इस सिद्धांत का एक महत्वपूर्ण अपवाद यह है कि तुम HTTPS के साथ glob patterns या डायरेक्टरी paths का उपयोग नहीं कर सकते क्योंकि HTTPS multiple फ़ाइलों को list नहीं कर सकता, इसलिए तुम्हें exact फ़ाइल URLs निर्दिष्ट करने होंगे। + हालाँकि, अन्य storage protocols जैसे blob storage (`s3://`, `az://`, `gs://`) globs और डायरेक्टरी paths दोनों का उपयोग कर सकते हैं। + + यहाँ बताया गया है कि तुम cloud storage के साथ glob patterns कैसे उपयोग कर सकते हो: + + ```groovy title="Cloud storage examples (इस वातावरण में runnable नहीं)" + // S3 with glob patterns - multiple फ़ाइलों को match करेगा + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage with glob patterns + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage with glob patterns + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + हम तुम्हें अगले अनुभाग में practice में globs के साथ काम करना दिखाएंगे। + +### 2.2. लोकल फ़ाइल पर वापस switch करें + +हम इस side quest के बाकी हिस्से के लिए अपनी लोकल example फ़ाइलों का उपयोग करने जा रहे हैं, तो चलो workflow इनपुट को वापस original फ़ाइल पर switch करते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### सीख + +- रिमोट डेटा को URI (HTTP, FTP, S3, Azure, Google Cloud) का उपयोग करके access किया जाता है +- Nextflow automatically डेटा को download और सही जगह पर stage करेगा, जब तक ये paths processes को feed किए जा रहे हैं +- रिमोट फ़ाइलों को download या upload करने के लिए लॉजिक मत लिखो! +- लोकल और रिमोट फ़ाइलें अलग-अलग object types produce करती हैं लेकिन समान रूप से काम करती हैं +- **महत्वपूर्ण**: HTTP/HTTPS केवल single फ़ाइलों के साथ काम करते हैं (glob patterns नहीं) +- Cloud storage (S3, Azure, GCS) single फ़ाइलों और glob patterns दोनों को support करता है +- तुम code लॉजिक बदले बिना लोकल और रिमोट डेटा sources के बीच seamlessly switch कर सकते हो (जब तक protocol तुम्हारे required ऑपरेशंस को support करता है) + +--- + +## 3. `fromPath()` channel factory का उपयोग + +अब तक हम एक समय में एक फ़ाइल के साथ काम कर रहे थे, लेकिन Nextflow में, हम आमतौर पर प्रोसेस करने के लिए multiple इनपुट फ़ाइलों के साथ एक इनपुट channel बनाना चाहेंगे। + +ऐसा करने का एक naive तरीका `file()` मेथड को [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) के साथ combine करना होगा जैसे: + +```groovy title="Syntax example" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +यह काम करता है, लेकिन यह अजीब है। + +!!! tip "सुझाव" + + कब `file()` बनाम `channel.fromPath()` का उपयोग करें + + - `file()` का उपयोग करो जब तुम्हें direct manipulation के लिए single Path ऑब्जेक्ट की आवश्यकता हो (check करना कि फ़ाइल exists है, इसकी attributes पढ़ना, या single process invocation को pass करना) + - `channel.fromPath()` का उपयोग करो जब तुम्हें ऐसा channel चाहिए जो multiple फ़ाइलें hold कर सके, विशेष रूप से glob patterns के साथ, या जब फ़ाइलें multiple processes से flow करेंगी + +यहाँ [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) आता है: एक सुविधाजनक channel factory जो एक या अधिक static फ़ाइल strings के साथ-साथ glob patterns से channel generate करने के लिए हमें आवश्यक सभी functionality bundle करती है। + +### 3.1. channel factory जोड़ें + +चलो अपने workflow को अपडेट करते हैं `channel.fromPath` का उपयोग करने के लिए। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // फ़ाइल विशेषताएँ प्रिंट करें + /* इन्हें अभी comment out करो, हम इन पर वापस आएंगे! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // फ़ाइल में लाइनें गिनें + // COUNT_LINES(myFile) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // एक string path से Path ऑब्जेक्ट बनाएं + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // फ़ाइल विशेषताएँ प्रिंट करें + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // फ़ाइल में लाइनें गिनें + COUNT_LINES(myFile) + ``` + +हमने अभी के लिए attributes print करने वाले code को भी comment out कर दिया है, और इसके बजाय बस filename print करने के लिए `.view` statement जोड़ा है। + +workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +जैसा कि तुम देख सकते हो, फ़ाइल path channel में `Path` type ऑब्जेक्ट के रूप में load हो रहा है। +यह उसी के समान है जो `file()` ने किया होता, सिवाय इसके कि अब हमारे पास एक channel है जिसमें हम चाहें तो और फ़ाइलें load कर सकते हैं। + +`channel.fromPath()` का उपयोग फ़ाइलों की सूची द्वारा populated नया channel बनाने का एक सुविधाजनक तरीका है। + +### 3.2. channel में फ़ाइलों की attributes देखें + +Channel factory का उपयोग करने के हमारे पहले प्रयास में, हमने code को सरल बनाया और बस फ़ाइल का नाम print किया। + +चलो पूर्ण फ़ाइल attributes print करने पर वापस जाते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // फ़ाइल में लाइनें गिनें + COUNT_LINES(ch_files) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // फ़ाइल में लाइनें गिनें + // COUNT_LINES(ch_files) + ``` + +हम `COUNT_LINES` process call को भी re-enable कर रहे हैं यह verify करने के लिए कि फ़ाइल processing अभी भी हमारे channel-based approach के साथ सही ढंग से काम करती है। + +workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +और वहाँ तुम हो, पहले जैसे ही परिणाम लेकिन अब हमारे पास फ़ाइल एक channel में है, इसलिए हम और जोड़ सकते हैं। + +### 3.3. multiple फ़ाइलों को match करने के लिए glob का उपयोग + +channel में और फ़ाइलें load करने के कई तरीके हैं। +यहाँ हम तुम्हें glob patterns का उपयोग करना दिखाने जा रहे हैं, जो wildcard characters के आधार पर फ़ाइल और डायरेक्टरी names को match और retrieve करने का एक सुविधाजनक तरीका है। +इन patterns को match करने की प्रक्रिया को "globbing" या "filename expansion" कहा जाता है। + +!!! note "नोट" + + जैसा कि पहले noted किया गया था, Nextflow अधिकांश मामलों में इनपुट और आउटपुट फ़ाइलों को manage करने के लिए globbing को support करता है, HTTPS filepaths के साथ छोड़कर क्योंकि HTTPS multiple फ़ाइलों को list नहीं कर सकता। + +मान लो हम किसी दिए गए patient, `patientA` से जुड़ी फ़ाइलों की pair में दोनों फ़ाइलें retrieve करना चाहते हैं: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +चूँकि filenames के बीच एकमात्र अंतर replicate number है, _यानी_ `R` के बाद का number, हम wildcard character `*` का उपयोग number के स्थान पर निम्नानुसार कर सकते हैं: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +यह वह glob pattern है जिसकी हमें आवश्यकता है। + +अब हमें बस channel factory में फ़ाइल path को उस glob pattern का उपयोग करने के लिए update करना है जैसा कि निम्नानुसार है: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow automatically पहचान लेगा कि यह एक glob pattern है और इसे appropriately handle करेगा। + +इसे test करने के लिए workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +जैसा कि तुम देख सकते हो, अब हमारे channel में दो Path ऑब्जेक्ट्स हैं, जो दिखाता है कि Nextflow ने filename expansion सही ढंग से की है, और दोनों फ़ाइलों को expected के अनुसार load और process किया है। + +इस मेथड का उपयोग करके, हम बस glob pattern बदलकर जितनी चाहें उतनी या कम फ़ाइलें retrieve कर सकते हैं। यदि हम इसे अधिक generous बनाते हैं, उदाहरण के लिए filenames के सभी variable parts को `*` से replace करके (_जैसे_ `data/patient*_rep*_*_R*_001.fastq.gz`) हम `data` डायरेक्टरी में सभी example फ़ाइलें grab कर सकते हैं। + +### सीख + +- `channel.fromPath()` एक pattern से match करने वाली फ़ाइलों के साथ channel बनाता है +- प्रत्येक फ़ाइल channel में एक separate element के रूप में emit होती है +- हम multiple फ़ाइलों को match करने के लिए glob pattern का उपयोग कर सकते हैं +- फ़ाइलें automatically full attributes के साथ Path ऑब्जेक्ट्स में convert हो जाती हैं +- `.view()` मेथड channel contents का inspection करने की अनुमति देती है + +--- + +## 4. फ़ाइलनामों से बुनियादी मेटाडेटा निकालना + +अधिकांश वैज्ञानिक domains में, डेटा वाली फ़ाइलों के नामों में मेटाडेटा encoded होना बहुत आम है। +उदाहरण के लिए, bioinformatics में, सीक्वेंसिंग डेटा वाली फ़ाइलों को अक्सर इस तरह नाम दिया जाता है जो नमूने, condition, replicate, और read number के बारे में जानकारी encode करता है। + +यदि filenames एक consistent convention के अनुसार constructed हैं, तो तुम उस मेटाडेटा को standardized manner में extract कर सकते हो और अपने विश्लेषण के दौरान इसका उपयोग कर सकते हो। +यह एक बड़ा 'अगर' है, बेशक, और जब भी तुम filename structure पर rely करते हो तो तुम्हें बहुत सावधान रहना चाहिए; लेकिन वास्तविकता यह है कि यह approach बहुत व्यापक रूप से उपयोग किया जाता है, तो चलो देखते हैं कि Nextflow में यह कैसे किया जाता है। + +हमारे example डेटा के मामले में, हम जानते हैं कि filenames में consistently structured मेटाडेटा शामिल है। +उदाहरण के लिए, filename `patientA_rep1_normal_R2_001` निम्नलिखित encode करता है: + +- patient ID: `patientA` +- replicate ID: `rep1` +- sample type: `normal` (`tumor` के विपरीत) +- read set: `R1` (`R2` के विपरीत) + +हम अपने workflow को तीन चरणों में इस जानकारी को retrieve करने के लिए modify करने जा रहे हैं: + +1. फ़ाइल का `simpleName` retrieve करें, जिसमें मेटाडेटा शामिल है +2. `tokenize()` नामक मेथड का उपयोग करके मेटाडेटा को separate करें +3. मेटाडेटा को organize करने के लिए map का उपयोग करें + +!!! warning "चेतावनी" + + तुम्हें कभी भी filenames में sensitive जानकारी encode नहीं करनी चाहिए, जैसे patient names या अन्य identifying characteristics, क्योंकि यह patient privacy या अन्य relevant security restrictions को compromise कर सकता है। + +### 4.1. `simpleName` retrieve करें + +`simpleName` एक फ़ाइल attribute है जो path और extension से stripped filename से correspond करता है। + +workflow में निम्नलिखित edits करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +यह `simpleName` retrieve करता है और इसे `map()` ऑपरेशन का उपयोग करके full file ऑब्जेक्ट के साथ associate करता है। + +यह काम करता है इसे test करने के लिए workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +channel में प्रत्येक element अब एक tuple है जिसमें `simpleName` और original file ऑब्जेक्ट है। + +### 4.2. `simplename` से मेटाडेटा extract करें + +इस point पर, हमें जो मेटाडेटा चाहिए वह `simplename` में embedded है, लेकिन हम individual items को directly access नहीं कर सकते। +इसलिए हमें `simplename` को इसके components में split करना होगा। +सौभाग्य से, वे components original filename में बस underscores द्वारा separated हैं, इसलिए हम `tokenize()` नामक एक common Nextflow मेथड apply कर सकते हैं जो इस कार्य के लिए perfect है। + +workflow में निम्नलिखित edits करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +`tokenize()` मेथड `simpleName` string को जहाँ भी underscores पाती है वहाँ split करेगी, और substrings वाली list return करेगी। + +workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +अब हमारे channel में प्रत्येक element के लिए tuple में मेटाडेटा की list (_जैसे_ `[patientA, rep1, normal, R1, 001]`) और original file ऑब्जेक्ट है। + +बहुत बढ़िया! +हमने अपनी patient जानकारी को single string से strings की list में break down किया है। +अब हम patient जानकारी के प्रत्येक भाग को separately handle कर सकते हैं। + +### 4.3. मेटाडेटा को organize करने के लिए map का उपयोग करें + +हमारा मेटाडेटा इस समय बस एक flat list है। +इसे use करना आसान है लेकिन पढ़ना मुश्किल है। + +```console +[patientA, rep1, normal, R1, 001] +``` + +index 3 पर item क्या है? क्या तुम मेटाडेटा structure की original explanation को refer किए बिना बता सकते हो? + +यह एक key-value store का उपयोग करने का एक बढ़िया अवसर है, जहाँ प्रत्येक item में keys और उनके associated values का set होता है, इसलिए तुम corresponding value प्राप्त करने के लिए आसानी से प्रत्येक key को refer कर सकते हो। + +हमारे example में, इसका मतलब है इस organization से जाना: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +इस तक: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +Nextflow में, इसे [map](https://nextflow.io/docs/latest/script.html#maps) कहा जाता है। + +चलो अब अपनी flat list को map में convert करते हैं। +workflow में निम्नलिखित edits करें: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +यहाँ मुख्य changes हैं: + +- **Destructuring assignment**: `def (patient, replicate, type, readNum) = ...` tokenized values को एक line में named variables में extract करता है +- **Map literal syntax**: `[id: patient, replicate: ...]` एक map बनाता है जहाँ प्रत्येक key (जैसे `id`) एक value (जैसे `patient`) से associated है +- **Nested structure**: Outer list `[..., myFile]` मेटाडेटा map को original file ऑब्जेक्ट के साथ pair करती है + +हमने `replace()` नामक string replacement मेथड का उपयोग करके कुछ मेटाडेटा strings को भी simplify किया ताकि कुछ unnecessary characters remove हों (_जैसे_ `replicate.replace('rep', '')` replicate IDs से केवल number रखने के लिए)। + +चलो workflow फिर से चलाते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [infallible_swartz] DSL2 - revision: 7f4e68c0cb + + executor > local (2) + [1b/e7fb27] COUNT_LINES (1) [100%] 2 of 2 ✔ + [[id:patientA, replicate:1, type:normal, readNum:2], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[id:patientA, replicate:1, type:normal, readNum:1], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +अब मेटाडेटा neatly labeled है (_जैसे_ `[id:patientA, replicate:1, type:normal, readNum:2]`) इसलिए यह बताना बहुत आसान है कि क्या है। + +workflow में मेटाडेटा के elements का actually उपयोग करना भी बहुत आसान होगा, और हमारे code को पढ़ने में आसान और अधिक maintainable बनाएगा। + +### सीख + +- हम Nextflow में filenames को एक full programming language की power के साथ handle कर सकते हैं +- हम relevant जानकारी extract करने के लिए filenames को strings के रूप में treat कर सकते हैं +- `tokenize()` और `replace()` जैसी मेथड्स का उपयोग हमें filename में strings को manipulate करने की अनुमति देता है +- `.map()` ऑपरेशन structure को preserve करते हुए channel elements को transform करता है +- Structured मेटाडेटा (maps) positional lists की तुलना में code को अधिक readable और maintainable बनाता है + +अगला, हम देखेंगे कि paired डेटा फ़ाइलों को कैसे handle करना है। + +--- + +## 5. paired डेटा फ़ाइलों को handle करना + +कई experimental designs paired डेटा फ़ाइलें produce करते हैं जो explicitly paired तरीके से handle किए जाने से लाभान्वित होती हैं। +उदाहरण के लिए, bioinformatics में, सीक्वेंसिंग डेटा अक्सर paired reads के रूप में generate होता है, जिसका मतलब sequence strings जो DNA के same fragment से originate होती हैं (अक्सर 'forward' और 'reverse' कहा जाता है क्योंकि वे opposite ends से read की जाती हैं)। + +यही हमारे example डेटा का मामला है, जहाँ R1 और R2 reads के दो sets को refer करते हैं। + +```console +data/patientA_rep1_normal_R1_001.fastq.gz +data/patientA_rep1_normal_R2_001.fastq.gz +``` + +Nextflow इस तरह की paired फ़ाइलों के साथ काम करने के लिए एक specialized channel factory प्रदान करता है जिसे `channel.fromFilePairs()` कहा जाता है, जो automatically shared naming pattern के आधार पर फ़ाइलों को group करती है। यह तुम्हें कम प्रयास के साथ paired फ़ाइलों को अधिक tightly associate करने की अनुमति देता है। + +हम इसका लाभ उठाने के लिए अपने workflow को modify करने जा रहे हैं। +इसमें दो steps लगेंगे: + +1. channel factory को `channel.fromFilePairs()` में switch करें +2. मेटाडेटा extract और map करें + +### 5.1. channel factory को `channel.fromFilePairs()` में switch करें + +`channel.fromFilePairs` का उपयोग करने के लिए, हमें वह pattern specify करना होगा जिसका Nextflow को pair में दो members identify करने के लिए उपयोग करना चाहिए। + +हमारे example डेटा पर वापस जाते हुए, हम naming pattern को निम्नानुसार formalize कर सकते हैं: + +```console +data/patientA_rep1_normal_R{1,2}_001.fastq.gz +``` + +यह उस glob pattern के समान है जो हमने पहले उपयोग किया था, सिवाय इसके कि यह specifically उन substrings को enumerate करता है (या तो `1` या `2` R के ठीक बाद आ रहा है) जो pair के दो members को identify करते हैं। + +चलो `main.nf` workflow को accordingly update करते हैं: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + /* अभी के लिए mapping comment out करो, हम इस पर वापस आएंगे! + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + */ + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + .view() + ``` + +हमने channel factory switch की है और file matching pattern adapt किया है, और जब हम इस पर थे, हमने map ऑपरेशन को comment out कर दिया। +हम इसे बाद में वापस add करेंगे, कुछ modifications के साथ। + +इसे test करने के लिए workflow चलाओ: + +```bash +nextflow run main.nf +``` + +??? failure "कमांड आउटपुट" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_koch] DSL2 - revision: 44fdf66105 + + [- ] COUNT_LINES - + [patientA_rep1_normal_R, [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ERROR ~ Error executing process > 'COUNT_LINES (1)' + + Caused by: + Not a valid path value: 'patientA_rep1_normal_R' + + + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +अरे, इस बार run fail हो गया! + +error message का relevant हिस्सा यहाँ है: + +```console +Not a valid path value: 'patientA_rep1_normal_R' +``` + +ऐसा इसलिए है क्योंकि हमने channel factory बदल दी है। +अब तक, original input channel में केवल file paths थे। +हम जो सभी मेटाडेटा manipulation कर रहे थे उसने actually channel contents को affect नहीं किया। + +अब जब हम `.fromFilePairs` channel factory का उपयोग कर रहे हैं, resulting channel की contents different हैं। +हम केवल एक channel element देखते हैं, जो दो items वाले tuple से composed है: दो फ़ाइलों द्वारा shared `simpleName` का हिस्सा, जो एक identifier के रूप में serve करता है, और दो file ऑब्जेक्ट्स वाला tuple, format `id, [ file1, file2 ]` में। + +यह बढ़िया है, क्योंकि Nextflow ने shared prefix examine करके और इसे patient identifier के रूप में उपयोग करके patient name extract करने का कठिन काम किया है। + +हालाँकि, यह हमारे current workflow को break करता है। +यदि हम अभी भी `COUNT_LINES` को process बदले बिना same तरीके से run करना चाहते थे, तो हमें file paths extract करने के लिए mapping ऑपरेशन apply करना होगा। +लेकिन हम ऐसा नहीं करने जा रहे हैं, क्योंकि हमारा ultimate goal एक different process, `ANALYZE_READS` का उपयोग करना है, जो file pairs को appropriately handle करता है। + +तो चलो बस `COUNT_LINES` की call को comment out (या delete) करते हैं और आगे बढ़ते हैं। + +=== "बाद" + + ```groovy title="main.nf" linenums="26" hl_lines="2" + // फ़ाइल में लाइनें गिनें + // COUNT_LINES(ch_files) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="26" hl_lines="2" + // फ़ाइल में लाइनें गिनें + COUNT_LINES(ch_files) + ``` + +तुम `COUNT_LINES` include statement को भी comment out या delete कर सकते हो, लेकिन उसका कोई functional effect नहीं होगा। + +अब चलो workflow फिर से चलाते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [fabulous_davinci] DSL2 - revision: 22b53268dc + + [patientA_rep1_normal_R, [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +इस बार workflow succeed होता है! + +हालाँकि, हमें अभी भी `id` field से बाकी मेटाडेटा निकालना है। + +### 5.2. file pairs से मेटाडेटा extract और organize करें + +पहले का हमारा `map` ऑपरेशन काम नहीं करेगा क्योंकि यह data structure से match नहीं करता, लेकिन हम इसे काम करने के लिए modify कर सकते हैं। + +हमारे पास पहले से ही actual patient identifier का access उस string में है जो `fromFilePairs()` ने identifier के रूप में उपयोग किया, इसलिए हम इसका उपयोग मेटाडेटा extract करने के लिए कर सकते हैं बिना Path ऑब्जेक्ट से `simpleName` प्राप्त किए जैसा हमने पहले किया था। + +workflow में map ऑपरेशन को uncomment करो और निम्नलिखित edits करो: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="3-4 9 11 13" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="3-5 11 13" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + /* अभी के लिए mapping comment out करो, हम इस पर वापस आएंगे! + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + */ + .view() + ``` + +इस बार map बस `myFile` के बजाय `id, files` से शुरू होता है, और `tokenize()` `myFile.simpleName` के बजाय `id` पर apply होता है। + +यह भी notice करो कि हमने `tokenize()` line से `readNum` हटा दिया है; कोई भी substrings जिन्हें हम specifically name नहीं करते (left से शुरू करके) silently drop हो जाएंगी। +हम यह इसलिए कर सकते हैं क्योंकि paired फ़ाइलें अब tightly associated हैं, इसलिए हमें metadata map में `readNum` की अब आवश्यकता नहीं है। + +चलो workflow चलाते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_stonebraker] DSL2 - revision: f62ab10a3f + + [[id:patientA, replicate:1, type:normal], [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +और वहाँ है: हमारे पास metadata map (`[id:patientA, replicate:1, type:normal]`) output tuple की first position में है, इसके बाद paired फ़ाइलों का tuple है, जैसा intended था। + +बेशक, यह केवल उस specific pair of फ़ाइलों को pick up और process करेगा। +यदि तुम multiple pairs को process करने के साथ experiment करना चाहते हो, तुम input pattern में wildcards add करने की कोशिश कर सकते हो और देख सकते हो क्या होता है। +उदाहरण के लिए, `data/patientA_rep1_*_R{1,2}_001.fastq.gz` try करो। + +### सीख + +- [`channel.fromFilePairs()` automatically related फ़ाइलों को find और pair करती है](https://www.nextflow.io/docs/latest/reference/channel.html#fromfilepairs) +- यह तुम्हारी pipeline में paired-end reads को handle करना simplify करता है +- Paired फ़ाइलों को `[id, [file1, file2]]` tuples के रूप में group किया जा सकता है +- मेटाडेटा extraction individual फ़ाइलों के बजाय paired file ID से की जा सकती है + +--- + +## 6. processes में file ऑपरेशंस का उपयोग + +अब चलो यह सब एक simple process में एक साथ रखते हैं यह reinforce करने के लिए कि Nextflow process के अंदर file ऑपरेशंस कैसे उपयोग करें। + +हम तुम्हें `ANALYZE_READS` नामक एक pre-written process मॉड्यूल प्रदान करते हैं जो मेटाडेटा और इनपुट फ़ाइलों की pair का tuple लेता है और उनका analyze करता है। +हम imagine कर सकते हैं कि यह sequence alignment, या variant calling या कोई अन्य step कर रहा है जो इस data type के लिए sense बनाता है। + +चलो शुरू करते हैं। + +### 6.1. process को import करें और code examine करें + +workflow में इस process का उपयोग करने के लिए, हमें बस workflow block से पहले एक module include statement add करना होगा। + +workflow में निम्नलिखित edit करो: + +=== "बाद" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { ANALYZE_READS } from './modules/analyze_reads.nf' + + workflow { + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +तुम मॉड्यूल फ़ाइल को खोलकर इसके code examine कर सकते हो: + +```groovy title="modules/analyze_reads.nf - process example" linenums="1" +#!/usr/bin/env nextflow + +process ANALYZE_READS { + tag { meta.id } + + publishDir { "results/${meta.id}" }, mode: 'copy' + + input: + tuple val(meta), path(files) + + output: + tuple val(meta.id), path("${meta.id}_stats.txt") + + script: + """ + echo "Sample metadata: ${meta.id}" > ${meta.id}_stats.txt + echo "Replicate: ${meta.replicate}" >> ${meta.id}_stats.txt + echo "Type: ${meta.type}" >> ${meta.id}_stats.txt + echo "Read 1: ${files[0]}" >> ${meta.id}_stats.txt + echo "Read 2: ${files[1]}" >> ${meta.id}_stats.txt + echo "Read 1 size: \$(gunzip -dc ${files[0]} | wc -l | awk '{print \$1/4}') reads" >> ${meta.id}_stats.txt + echo "Read 2 size: \$(gunzip -dc ${files[1]} | wc -l | awk '{print \$1/4}') reads" >> ${meta.id}_stats.txt + """ +} +``` + +!!! note "नोट" + + `tag` और `publishDir` निर्देश string interpolation (`"${...}"`) के बजाय closure syntax (`{ ... }`) का उपयोग करते हैं। + ऐसा इसलिए है क्योंकि ये निर्देश input variables (`meta`) को reference करते हैं जो runtime तक available नहीं हैं। + Closure syntax evaluation को तब तक defer करता है जब तक process actually run नहीं होता। + +!!! note "नोट" + + हम अपने metadata map को convention से `meta` कह रहे हैं। + Meta maps में deeper dive के लिए, [Metadata and meta maps](./metadata.md) side quest देखें। + +### 6.2. workflow में process को call करें + +अब जब process workflow के लिए available है, हम इसे run करने के लिए `ANALYZE_READS` process को call add कर सकते हैं। + +इसे हमारे example डेटा पर run करने के लिए, हमें दो चीजें करनी होंगी: + +1. Remapped channel को name दें +2. Process को call add करें + +#### 6.2.1. Remapped input channel को name दें + +हमने पहले mapping manipulations को directly input channel पर apply किया था। +Remapped contents को `ANALYZE_READS` process को feed करने के लिए (और इसे इस तरह से करने के लिए जो clear और पढ़ने में easy हो) हम `ch_samples` नाम का एक नया channel बनाना चाहते हैं। + +हम यह [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set) ऑपरेटर का उपयोग करके कर सकते हैं। + +Main workflow में, `.view()` ऑपरेटर को `.set { ch_samples }` से replace करो, और एक line add करो testing कि हम channel को name से refer कर सकते हैं। + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="14 16-17" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .set { ch_samples } + + // Temporary: ch_samples में peek करें + ch_samples.view() + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="14" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .view() + } + ``` + +चलो यह run करते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [goofy_kirch] DSL2 - revision: 3313283e42 + + [[id:patientA, replicate:1, type:normal], [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +यह confirm करता है कि हम अब channel को name से refer कर सकते हैं। + +#### 6.2.2. data पर process call करें + +अब चलो actually `ch_samples` channel पर `ANALYZE_READS` process call करते हैं। + +Main workflow में, निम्नलिखित code changes करो: + +=== "बाद" + + ```groovy title="main.nf" linenums="23" + // analysis चलाएं + ANALYZE_READS(ch_samples) + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="23" + // Temporary: ch_samples में peek करें + ch_samples.view() + ``` + +चलो यह run करते हैं: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [shrivelled_cori] DSL2 - revision: b546a31769 + + executor > local (1) + [b5/110360] process > ANALYZE_READS (patientA) [100%] 1 of 1 ✔ + ``` + +यह process अपने outputs को `results` डायरेक्टरी में publish करने के लिए set up है, तो वहाँ एक नज़र डालो। + +??? abstract "डायरेक्टरी और फ़ाइल contents" + + ```console + results + └── patientA + └── patientA_stats.txt + ``` + + ```txt title="patientA_stats.txt" + Sample metadata: patientA + Replicate: 1 + Type: normal + Read 1: patientA_rep1_normal_R1_001.fastq.gz + Read 2: patientA_rep1_normal_R2_001.fastq.gz + Read 1 size: 10 reads + Read 2 size: 10 reads + ``` + +Process ने हमारे inputs लिए और patient metadata वाली एक new फ़ाइल बनाई, जैसा designed था। +शानदार! + +### 6.3. कई और patients include करें + +बेशक, यह single patient के लिए बस single pair of फ़ाइलों को process कर रहा है, जो exactly उस तरह का high throughput नहीं है जिसकी तुम Nextflow के साथ उम्मीद कर रहे हो। +तुम शायद एक समय में बहुत अधिक डेटा process करना चाहोगे। + +याद रखो `channel.fromPath()` input के रूप में एक _glob_ accept करता है, जिसका मतलब है कि यह pattern से match करने वाली किसी भी संख्या में फ़ाइलें accept कर सकता है। +इसलिए यदि हम सभी patients को include करना चाहते हैं, हम बस अधिक patients include करने के लिए input string modify कर सकते हैं, जैसा कि पहले passing में note किया गया था। + +मान लो हम जितना possible हो उतना greedy होना चाहते हैं। +workflow में निम्नलिखित edits करो: + +=== "बाद" + + ```groovy title="main.nf" linenums="7" hl_lines="2" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/*_R{1,2}_001.fastq.gz') + ``` + +=== "पहले" + + ```groovy title="main.nf" linenums="7" hl_lines="2" + // channel.fromFilePairs के साथ फ़ाइलें लोड करें + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ``` + +Pipeline फिर से run करो: + +```bash +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [big_stonebraker] DSL2 - revision: f7f9b8a76c + + executor > local (8) + [d5/441891] process > ANALYZE_READS (patientC) [100%] 8 of 8 ✔ + ``` + +Results डायरेक्टरी में अब सभी available डेटा के लिए results होने चाहिए। + +??? abstract "डायरेक्टरी contents" + + ```console + results + ├── patientA + │ └── patientA_stats.txt + ├── patientB + │ └── patientB_stats.txt + └── patientC + └── patientC_stats.txt + ``` + +सफलता! हमने सभी patients को एक बार में analyze कर दिया! सही? + +शायद नहीं। +यदि तुम अधिक closely देखो, हमारे पास एक problem है: patientA के लिए हमारे पास दो replicates हैं, लेकिन केवल एक output फ़ाइल! +हम हर बार output फ़ाइल को overwrite कर रहे हैं। + +### 6.4. published फ़ाइलों को unique बनाएं + +चूँकि हमारे पास patient metadata तक access है, हम इसका उपयोग published फ़ाइलों को unique बनाने के लिए कर सकते हैं differentiating metadata को include करके, या तो directory structure में या filenames में ही। + +workflow में निम्नलिखित change करो: + +=== "बाद" + + ```groovy title="modules/analyze_reads.nf" linenums="6" + publishDir { "results/${meta.type}/${meta.id}/${meta.replicate}" }, mode: 'copy' + ``` + +=== "पहले" + + ```groovy title="modules/analyze_reads.nf" linenums="6" + publishDir { "results/${meta.id}" }, mode: 'copy' + ``` + +यहाँ हम sample types और replicates के account के लिए additional directory levels उपयोग करने का option दिखाते हैं, लेकिन तुम filename level पर भी इसे करने के साथ experiment कर सकते हो। + +अब pipeline एक और बार run करो, लेकिन पहले results डायरेक्टरी remove करना सुनिश्चित करो ताकि तुम्हें clean workspace मिले: + +```bash +rm -r results +nextflow run main.nf +``` + +??? success "कमांड आउटपुट" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + executor > local (8) + [e3/449081] process > ANALYZE_READS (patientC) [100%] 8 of 8 ✔ + ``` + +अब results डायरेक्टरी check करो: + +??? abstract "डायरेक्टरी contents" + + ```console + results/ + ├── normal + │ ├── patientA + │ │ ├── 1 + │ │ │ └── patientA_stats.txt + │ │ └── 2 + │ │ └── patientA_stats.txt + │ ├── patientB + │ │ └── 1 + │ │ └── patientB_stats.txt + │ └── patientC + │ └── 1 + │ └── patientC_stats.txt + └── tumor + ├── patientA + │ ├── 1 + │ │ └── patientA_stats.txt + │ └── 2 + │ └── patientA_stats.txt + ├── patientB + │ └── 1 + │ └── patientB_stats.txt + └── patientC + └── 1 + └── patientC_stats.txt + ``` + +और वहाँ है, हमारा सारा मेटाडेटा, neatly organized। यह सफलता है! + +एक बार जब तुम्हारा मेटाडेटा इस तरह map में loaded है तो और भी बहुत कुछ कर सकते हो: + +1. Patient attributes के आधार पर organized output directories बनाना +2. Patient properties के आधार पर processes में decisions लेना +3. Metadata values के आधार पर data को split, join, और recombine करना + +मेटाडेटा को explicit और data से attached रखने का यह pattern (filenames में encoded करने के बजाय) Nextflow में एक core best practice है जो robust, maintainable analysis workflows बनाने में enable करता है। +तुम इसके बारे में [Metadata and meta maps](./metadata.md) side quest में और जान सकते हो। + +### सीख + +- `publishDir` निर्देश metadata values के आधार पर outputs organize कर सकता है +- Tuples में metadata results का structured organization enable करता है +- यह approach clear data provenance के साथ maintainable workflows बनाता है +- Processes मेटाडेटा और फ़ाइलों के tuples को input के रूप में ले सकते हैं +- `tag` निर्देश execution logs में process identification प्रदान करता है +- Workflow structure channel creation को process execution से separate करती है + +--- + +## सारांश + +इस side quest में, तुमने सीखा कि Nextflow में फ़ाइलों के साथ कैसे काम करना है, basic ऑपरेशंस से लेकर फ़ाइलों के collections को handle करने की अधिक advanced techniques तक। + +अपने own काम में इन techniques को apply करना तुम्हें अधिक efficient और maintainable workflows बनाने में enable करेगा, खासकर जब complex naming conventions के साथ बड़ी संख्या में फ़ाइलों के साथ काम कर रहे हो। + +### मुख्य पैटर्न + +1. **Basic File ऑपरेशंस:** हमने `file()` के साथ Path ऑब्जेक्ट्स बनाए और name, extension, और parent directory जैसी फ़ाइल attributes access कीं, strings और Path ऑब्जेक्ट्स के बीच अंतर सीखा। + + - `file()` के साथ Path ऑब्जेक्ट बनाएं + + ```groovy + myFile = file('path/to/file.txt') + ``` + + - फ़ाइल attributes प्राप्त करें + + ```groovy + println myFile.name // file.txt + println myFile.baseName // file + println myFile.extension // txt + println myFile.parent // path/to + ``` + +2. **Remote Files का उपयोग**: हमने सीखा कि URIs का उपयोग करके local और remote फ़ाइलों के बीच transparently switch कैसे करना है, Nextflow की विभिन्न sources से फ़ाइलों को workflow logic बदले बिना handle करने की क्षमता demonstrate करते हुए। + + - Local फ़ाइल + + ```groovy + myFile = file('path/to/file.txt') + ``` + + - FTP + + ```groovy + myFile = file('ftp://path/to/file.txt') + ``` + + - HTTPS + + ```groovy + myFile = file('https://path/to/file.txt') + ``` + + - Amazon S3 + + ```groovy + myFile = file('s3://path/to/file.txt') + ``` + + - Azure Blob Storage + + ```groovy + myFile = file('az://path/to/file.txt') + ``` + + - Google Cloud Storage + + ```groovy + myFile = file('gs://path/to/file.txt') + ``` + +3. **`fromPath()` channel factory का उपयोग करके फ़ाइलें load करना:** हमने `channel.fromPath()` के साथ file patterns से channels बनाए और object types सहित उनकी file attributes देखीं। + + - File pattern से channel बनाएं + + ```groovy + ch_files = channel.fromPath('data/*.fastq.gz') + ``` + + - फ़ाइल attributes प्राप्त करें + + ```groovy + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +4. **Filenames से Patient Metadata Extract करना:** हमने filenames से metadata extract और structure करने के लिए `tokenize()` और `replace()` का उपयोग किया, उन्हें organized maps में convert करते हुए। + + ```groovy + def name = file.name.tokenize('_') + def patientId = name[0] + def replicate = name[1].replace('rep', '') + def type = name[2] + def readNum = name[3].replace('R', '') + ``` + +5. **channel.fromFilePairs के साथ Simplify करना:** हमने related फ़ाइलों को automatically pair करने और paired file IDs से metadata extract करने के लिए `channel.fromFilePairs()` का उपयोग किया। + + ```groovy + ch_pairs = channel.fromFilePairs('data/*_R{1,2}_001.fastq.gz') + ``` + +6. **Processes में File ऑपरेशंस का उपयोग:** हमने proper input handling के साथ file ऑपरेशंस को Nextflow processes में integrate किया, metadata के आधार पर outputs organize करने के लिए `publishDir` का उपयोग करते हुए। + + - Process inputs के साथ meta map associate करें + + ```groovy + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .set { ch_samples } + + ANALYZE_READS(ch_samples) + ``` + + - Metadata के आधार पर outputs organize करें + + ```groovy + publishDir { "results/${meta.type}/${meta.id}/${meta.replicate}" }, mode: 'copy' + ``` + +### अतिरिक्त संसाधन + +- [Nextflow Documentation: Working with Files](https://www.nextflow.io/docs/latest/working-with-files.html) +- [channel.fromPath](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) +- [channel.fromFilePairs](https://www.nextflow.io/docs/latest/reference/channel.html#fromfilepairs) + +--- + +## आगे क्या? + +[Side Quests के menu](./index.md) पर वापस जाओ या सूची में अगले topic पर जाने के लिए page के bottom right में button पर click करो। diff --git a/docs/hi/docs/training_collections/architects_toolkit_1.md b/docs/hi/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..d4849a0dae --- /dev/null +++ b/docs/hi/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: The Architect's Toolkit I +hide: + - toc +--- + +# The Architect's Toolkit I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +हमारे प्रशिक्षण संग्रह हमारी उन्नत प्रशिक्षण सामग्री (जिसे [Side Quests](../../side_quests) कहा जाता है) के माध्यम से क्यूरेटेड लर्निंग पाथ प्रदान करते हैं। यह संग्रह चार आवश्यक विषयों को कवर करता है जो मजबूत और स्केलेबल workflows बनाने के लिए अक्सर एक साथ उपयोग किए जाते हैं। + +## सीखने के उद्देश्य + +इस संग्रह के अंत तक, तुम्हें निम्नलिखित का अनुभव होगा: + +- **जटिल मॉड्यूलर workflow आर्किटेक्चर** - कई workflows को सुसंगत pipelines में जोड़ना +- **व्यापक टेस्टिंग रणनीतियाँ** - यह सुनिश्चित करना कि तुम्हारे workflows विश्वसनीय और रखरखाव योग्य हैं +- **मेटाडेटा प्रबंधन** - तुम्हारे workflows में नमूना-विशिष्ट मेटाडेटा को प्रभावी ढंग से संभालना +- **उन्नत डेटा प्रोसेसिंग** - कुशल डेटा स्प्लिटिंग और ग्रुपिंग पैटर्न लागू करना + +ये कौशल तुम्हें वास्तविक-दुनिया के अनुप्रयोगों के लिए मजबूत, स्केलेबल, और रखरखाव योग्य Nextflow workflows बनाने में सक्षम बनाएंगे। + +## दर्शक और पूर्वापेक्षाएँ + +यह संग्रह उन उपयोगकर्ताओं के लिए डिज़ाइन किया गया है जिन्होंने बेसिक Nextflow प्रशिक्षण पूरा कर लिया है और उन्नत workflow पैटर्न, टेस्टिंग रणनीतियों, और डेटा और मेटाडेटा हैंडलिंग तकनीकों में गहराई से जाना चाहते हैं। + +**पूर्वापेक्षाएँ** + +- [Hello Nextflow](../../hello_nextflow/) प्रशिक्षण या समकक्ष अनुभव का पूरा होना +- Nextflow सिंटैक्स और अवधारणाओं से बुनियादी परिचित +- बुनियादी workflow विकास पैटर्न की समझ +- कमांड-लाइन टूल्स के साथ अनुभव + +## संग्रह सामग्री + +इस संग्रह में चार Side Quests हैं जो पूरक workflow इंजीनियरिंग विषयों को कवर करते हैं: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - जटिल workflow आर्किटेक्चर और कंपोजिशन +2. **[Testing with nf-test](../../side_quests/nf-test)** - Nextflow workflows के लिए टेस्टिंग रणनीतियाँ +3. **[Metadata](../../side_quests/metadata)** - Nextflow channels में आइटम्स के लिए मेटाडेटा हैंडलिंग +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - उन्नत डेटा प्रोसेसिंग पैटर्न + +प्रत्येक Side Quest स्व-निहित है और स्वतंत्र अवधारणाओं को कवर करता है, लेकिन हम विषयों के माध्यम से तार्किक प्रगति के लिए उन्हें ऊपर सूचीबद्ध क्रम में पूरा करने की सलाह देते हैं। + +## इस संग्रह का उपयोग कैसे करें + +पहले, प्रशिक्षण वातावरण को एक अलग टैब में लॉन्च करने के लिए नीचे "Open in GitHub Codespaces" बटन पर कमांड-क्लिक करें, फिर लोड होते समय आगे पढ़ें। + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +एक बार तुम्हारा वातावरण चल रहा हो, निम्नानुसार संग्रह के माध्यम से काम करें: + +1. इस टैब में: ऊपर सूचीबद्ध पहले Side Quest पर नेविगेट करें, जो स्टेप-बाय-स्टेप विकास अभ्यासों का वर्णन करता है। +2. तुम्हारे Codespaces टैब में: Side Quest के लिए अभ्यासों के माध्यम से काम करें। +3. जब तुम एक Side Quest पूरा करो, इस पृष्ठ पर वापस आओ और ऊपर की सूची में अगले पर नेविगेट करें। +4. जब तुम संग्रह पूरा कर लो, एक बहुत छोटा सर्वे भरने के लिए नीचे बटन पर क्लिक करें। तुम्हारी प्रतिक्रिया हमें सभी के लिए प्रशिक्षण सामग्री में सुधार जारी रखने की अनुमति देती है। + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +शुरू करने के लिए तैयार हो? ऊपर पहले मॉड्यूल से शुरू करो! diff --git a/docs/hi/docs/training_collections/index.md b/docs/hi/docs/training_collections/index.md new file mode 100644 index 0000000000..8ac9ecca89 --- /dev/null +++ b/docs/hi/docs/training_collections/index.md @@ -0,0 +1,29 @@ +--- +title: प्रशिक्षण संग्रह +hide: + - toc +--- + +# प्रशिक्षण संग्रह + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI-सहायता प्राप्त अनुवाद - [अधिक जानें और सुधार सुझाएं](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +इस अनुभाग में [Side Quests](../side_quests/index.md) नामक प्रशिक्षण मॉड्यूल के क्यूरेटेड संग्रह हैं जो किसी विशेष विषय या उपयोग के मामले के आसपास एक व्यापक सीखने का अनुभव प्रदान करने का लक्ष्य रखते हैं। + +## पूर्वापेक्षाएँ + +प्रत्येक संग्रह की विशिष्ट पूर्वापेक्षाएँ उसके इंडेक्स पृष्ठ पर प्रलेखित हैं। हालांकि, अधिकांश संग्रह यह मानते हैं: + +- कमांड लाइन के साथ अनुभव +- [Hello Nextflow](../../hello_nextflow/) बिगिनर प्रशिक्षण कोर्स में शामिल मूलभूत Nextflow अवधारणाएँ और टूलिंग + +तकनीकी आवश्यकताओं और वातावरण सेटअप के लिए, [Environment Setup](../../envsetup/) मिनी-कोर्स देखें। + +## उपलब्ध संग्रह + +- [The Architect's Toolkit I](./architects_toolkit_1.md) - चार Side Quests का एक संग्रह जो जटिल pipelines को असेंबल करने के लिए workflow आर्किटेक्चर पैटर्न, टेस्टिंग रणनीतियों को लागू करना, मेटाडेटा प्रबंधन, और डेटा को ग्रुप और स्प्लिट करना कवर करता है। _अनुमानित अवधि: ग्रुप प्रशिक्षण में 4 घंटे।_ + +## नए संग्रहों का सुझाव देना + +हम अतिरिक्त Side Quests और संग्रह विकसित करने पर सक्रिय रूप से काम कर रहे हैं। +कृपया उन विषयों का सुझाव देने के लिए स्वतंत्र महसूस करें जो आपको लगता है कि किसी संग्रह में कवर करने के लिए समझ में आएंगे, कम्युनिटी फोरम के [Training section](https://community.seqera.io/c/training/) में पोस्ट करके। diff --git a/docs/hi/llm-prompt.md b/docs/hi/llm-prompt.md new file mode 100644 index 0000000000..0a858ed1a3 --- /dev/null +++ b/docs/hi/llm-prompt.md @@ -0,0 +1,153 @@ +# Translation Rules for Hindi + +The target language for this translation is **Hindi** (`hi`). + +## 1. Grammar & Tone + +- Use informal tone (तुम instead of आप where appropriate for technical tutorials) +- Use standard Devanagari script +- Prefer active voice when possible +- Use Hindi numerals or Arabic numerals as appropriate for context +- Maintain a conversational yet professional tone + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Hindi (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "इनपुट चैनल फ़ाइलें प्राप्त करता है..." (translate "channel" to "चैनल" or keep in English with Hindi text) +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// एक अभिवादन emit करें` + +## 3. Code Comments + +**Always translate code comments to Hindi.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Hindi translation +params.greeting = "Hello" // डिफ़ॉल्ट अभिवादन सेट करें +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Hindi: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +चैनल.fromPath('*.fastq') +प्रोसेस FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ संस्करण 24.04.0 +निष्पादक > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Using overly formal आप when तुम is more appropriate + +```markdown +// Wrong - too formal for tutorial +आपको workflow चलाना होगा... +आप परिणाम देखेंगे... + +// Correct - appropriate informal tone +तुम्हें workflow चलाना होगा... +तुम परिणाम देखोगे... +``` + +### ❌ Mixing scripts inconsistently + +```markdown +// Wrong - inconsistent script usage +यह workflow बहुत powerful है और तुम इसे आसानी से use कर सकते हो। + +// Correct - consistent approach (either keep English terms or transliterate consistently) +यह workflow बहुत शक्तिशाली है और तुम इसे आसानी से उपयोग कर सकते हो। +// or +यह वर्कफ़्लो बहुत पावरफुल है और तुम इसे आसानी से यूज़ कर सकते हो। +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code). + +Note: Hindi tech writing often keeps English terms with Devanagari transliteration. Both approaches are acceptable - be consistent within a document. + +| English | Hindi | Notes | +| ----------- | ---------- | ------------------ | +| channel | चैनल | Transliteration | +| process | प्रोसेस | Transliteration | +| workflow | वर्कफ़्लो | Transliteration | +| pipeline | पाइपलाइन | Transliteration | +| directive | निर्देश | Actual translation | +| container | कंटेनर | Transliteration | +| input | इनपुट | Transliteration | +| output | आउटपुट | Transliteration | +| task | कार्य | Actual translation | +| tuple | टपल | Transliteration | +| operator | ऑपरेटर | Transliteration | +| parameter | पैरामीटर | Transliteration | +| environment | वातावरण | Actual translation | +| directory | डायरेक्टरी | Transliteration | +| file | फ़ाइल | Transliteration | +| sample | नमूना | Actual translation | +| alignment | संरेखण | Actual translation | +| reference | संदर्भ | Actual translation | +| training | प्रशिक्षण | Actual translation | +| module | मॉड्यूल | Transliteration | +| command | कमांड | Transliteration | +| index | इंडेक्स | Transliteration | +| run | चलाना / रन | Both acceptable | + +## 6. Admonition Titles + +| English | Hindi | +| -------- | ------- | +| Note | नोट | +| Tip | सुझाव | +| Warning | चेतावनी | +| Exercise | अभ्यास | +| Solution | समाधान | +| Example | उदाहरण | + +## 7. Section Headers + +| English | Hindi | +| ----------------- | -------------- | +| Takeaway | सारांश | +| What's next? | आगे क्या है? | +| Warmup | वार्मअप | +| Environment Setup | पर्यावरण सेटअप | +| Getting Started | शुरू करना | + +## 8. Tab Labels + +| English | Hindi | +| ------- | ------- | +| After | बाद में | +| Before | पहले | +| Gitpod | Gitpod | +| Local | लोकल | diff --git a/docs/hi/mkdocs.yml b/docs/hi/mkdocs.yml new file mode 100644 index 0000000000..684e235833 --- /dev/null +++ b/docs/hi/mkdocs.yml @@ -0,0 +1,15 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: hi + custom_dir: ../en/overrides +extra: + consent: + title: "कुकी सहमति" + description: >- + हम आपकी बार-बार की विज़िट और प्राथमिकताओं को पहचानने के लिए, साथ ही + हमारे दस्तावेज़ों की प्रभावशीलता और उपयोगकर्ताओं को उनकी खोज में मदद + मिल रही है या नहीं, यह मापने के लिए कुकीज़ का उपयोग करते हैं। आपकी + सहमति से, आप हमारी प्रशिक्षण सामग्री को बेहतर बनाने में मदद कर रहे हैं। + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">हम कुकीज़ का उपयोग कैसे करते हैं</a> इसके बारे में अधिक जानें। + cookies: + posthog: "PostHog Analytics" diff --git a/docs/hi/ui-strings.yml b/docs/hi/ui-strings.yml new file mode 100644 index 0000000000..913bdc8534 --- /dev/null +++ b/docs/hi/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - Hindi (हिन्दी) +# ये strings index_page_hook.py द्वारा कोर्स लैंडिंग पेज के लिए +# और mkdocs.yml में कुकी सहमति के लिए उपयोग की जाती हैं। + +index_page: + course_summary: "कोर्स सारांश" + additional_information: "अतिरिक्त जानकारी" + technical_requirements: "तकनीकी आवश्यकताएँ" + learning_objectives: "सीखने के उद्देश्य" + audience_prerequisites: "लक्षित दर्शक और पूर्वापेक्षाएँ" + course_videos: "कोर्स वीडियो" + +defaults: + technical_requirements: >- + आपको एक GitHub खाता या Nextflow का लोकल इंस्टॉलेशन चाहिए होगा। + अधिक जानकारी के लिए [वातावरण विकल्प](../envsetup/index.md) देखें। + videos: >- + प्रत्येक अध्याय के लिए वीडियो उपलब्ध हैं, जिसमें एक प्रशिक्षक + अभ्यासों को करके दिखाता है। कोर्स के प्रत्येक भाग का वीडियो + संबंधित पेज के शीर्ष पर एम्बेड किया गया है। + view_playlist: "YouTube पर प्लेलिस्ट देखें" diff --git a/docs/index.es.md b/docs/index.es.md deleted file mode 100644 index 711b11a98a..0000000000 --- a/docs/index.es.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Nextflow Training -description: ¡Bienvenido al portal de capacitación de la comunidad Nextflow! -hide: - - toc - - footer ---- - -# Capacitación en Nextflow - -¡Bienvenido al portal de capacitación de la comunidad Nextflow! - -Estos materiales de capacitación son de código abierto y de uso gratuito para cualquier persona. -Están alojados en un [repositorio de GitHub](https://github.com/nextflow-io/training) junto con scripts de ejemplo y configuración de desarrollo. - -Si bien puedes aprender con estos materiales en cualquier momento, probablemente los aproveches al máximo al participar en una sesión de entrenamiento. -La comunidad de nf-core organiza regularmente eventos online gratuitos; consulta la [página de eventos de nf-core](https://nf-co.re/events) para obtener más información. - -[![Abrir en GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -!!! warning - - Some of the translations on the training portal are out of date. - The translated material may be incomplete or incorrect. - We plan to update the translations later this year. - In the meantime, please try to work through the English-language material if you can. - -## Talleres disponibles - -Tenemos varios talleres disponibles en este sitio web. -Encuentra el adecuado para ti: - -!!! exercise "Taller de Entrenamiento Básico de Nextflow" - - !!! tip inline end "" - - :material-lightbulb: Este es el principal material de capacitación de Nextflow utilizado en la mayoría de los eventos de capacitación de Nextflow y nf-core. - - Entrenamiento básico para todo lo relacionado con Nextflow. Perfecto para cualquiera que busque familiarizarse con el uso de Nextflow para ejecutar análisis y construir pipelines. - - [Comienza ahora el entrenamiento de Nextflow :material-arrow-right:](basic_training/index.md){ .md-button .md-button--primary } - -!!! exercise "Entrenamiento práctico" - - !!! quote inline end "" - - :material-run-fast: Este material es bastante corto y práctico, excelente si desea practicar sus habilidades de Nextflow. - - Un tutorial para "aprender haciendo" con menos enfoque en la teoría, guiándote hacia ejercicios que aumentan en complejidad. - - [Comienza el entrenamiento práctico :material-arrow-right:](hands_on/index.md){ .md-button } - -## Recursos - -Referencia rápida a algunos enlaces útiles: - -| Referencias | Comunidad | -| ----------------------------------------------------------------------- | -------------------------------------------------------------- | -| [Documentación de Nextflow](https://nextflow.io/docs/latest/index.html) | [Slack de Nextflow](https://www.nextflow.io/slack-invite.html) | -| [Página principal de Nextflow](https://nextflow.io/) | [nf-core](https://nf-co.re/) | -| [Seqera](https://seqera.io/) | [Seqera Community](https://community.seqera.io) | - -¿No estás seguro por dónde comenzar? Consulta la página de [ayuda](help.md). - -## Créditos y contribuciones - -[![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) - -Todo el material de capacitación fue escrito originalmente por [Seqera](https://seqera.io) pero se ha hecho de código abierto ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) para la comunidad. - -Damos la bienvenida a las correcciones y mejoras de la comunidad. -Cada página tiene un ícono :material-file-edit-outline: en la parte superior derecha de la página, que te llevará a GitHub, donde puedes editar el material a través de un Pull Request. - -<div markdown class="homepage_logos"> - -![Seqera](assets/img/seqera_logo.png#only-light) - -![Seqera](assets/img/seqera_logo_dark.png#only-dark) - -</div> diff --git a/docs/index.fr.md b/docs/index.fr.md deleted file mode 100644 index 8dfdb12606..0000000000 --- a/docs/index.fr.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: Formation Nextflow -description: Bienvenue sur le portail de formation de la communauté Nextflow! -hide: - - toc - - footer ---- - -# Formation Nextflow - -Bienvenue sur le portail de formation de la communauté Nextflow ! - -Nous proposons plusieurs formations distinctes sur ce site. Faites défiler vers le bas pour trouver celle qui vous convient! - -Les formations listées ci-dessous sont conçues comme des ressources en libre-service ; vous pouvez les suivre à votre rythme (voir la section "Configuration de l’environnement" pour les détails pratiques). Vous pouvez toutefois en tirer encore plus profit en participant à une session de formation en groupe. - -- Des événements en ligne gratuits sont régulièrement organisés par la communauté nf-core. Consultez la [page des événements nf-core](https://nf-co.re/events) pour en savoir plus. -- Seqera (l'entreprise qui développe Nextflow) propose divers événements de formation. Consultez la page [Événements Seqera](https://seqera.io/events/) pour trouver les "Seqera Sessions" et les "Nextflow Summit". -- Notre équipe communautaire organise également régulièrement des formations via des organisations partenaires ; les annonces et inscriptions sont généralement gérées par ces dernières. - -Quand vous êtes prêt·e à commencer, cliquez sur le bouton "Open in GitHub Codespaces" (présent sur cette page ou sur la page d’accueil de la formation choisie) pour ouvrir un environnement de formation en ligne (nécessite un compte GitHub gratuit). - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -## Configuration de l’environnement de formation - -!!! exercise "Environment Setup" - - !!! tip inline end "" - - :material-laptop:{.nextflow-primary} Configurez votre environnement pour la première fois. - - Instructions pour configurer votre environnement afin de suivre les formations (tous les cours). Introduction à GitHub Codespaces et alternatives pour une installation locale. - - [Commencer la formation sur la configuration de l’environnement :material-arrow-right:](envsetup/index.md){ .md-button .md-button--primary } - -## Nextflow pour les débutant·es - -Ces cours de base, indépendants du domaine, s’adressent à celles et ceux qui découvrent totalement Nextflow. Chaque cours est constitué de modules conçus pour développer les compétences progressivement. - -!!! exercise "Hello Nextflow" - - !!! tip inline end "" - - :material-run-fast:{.nextflow-primary} Apprenez à développer des pipelines avec Nextflow. - - :fontawesome-brands-youtube:{.youtube} Matériel vidéo disponible. - - Ce cours s’adresse aux débutant·es qui souhaitent apprendre à développer leurs propres pipelines. Il couvre les composants essentiels du langage Nextflow afin de permettre la création de pipelines simples mais fonctionnels. Il inclut également des éléments clés de conception, développement et configuration. - - [Commencer la formation Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--primary } - -!!! exercise "Hello nf-core" - - !!! tip inline end "" - - :material-run-fast:{.nextflow-primary} Apprenez à développer des pipelines compatibles nf-core. - - Ce cours s’adresse aux débutant·es souhaitant apprendre à utiliser et développer des pipelines conformes à [nf-core](https://nf-co.re/). Il présente la structure des pipelines nf-core et les bonnes pratiques de développement. - - [Commencer la formation Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--primary } - -!!! info "" - - **À venir :** "Nextflow Run" — Apprenez à exécuter des pipelines Nextflow (exécution uniquement, sans développement) - -<!-- COMMENTÉ EN ATTENTE DE DISPONIBILITÉ -!!! exercise "Nextflow Run" - - !!! tip inline end "" - - :material-run-fast:{.nextflow-primary} Apprenez à exécuter des pipelines Nextflow. - - Ce cours s’adresse aux débutant·es qui souhaitent apprendre à exécuter des pipelines existants. Il couvre les bases du langage Nextflow, la configuration et l’exécution depuis le terminal. Il présente également des éléments de l’écosystème Nextflow, y compris le projet nf-core et la plateforme Seqera. - - [Commencer la formation Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--primary } ---> - -## Nextflow pour la science - -Ces cours montrent comment appliquer les concepts du cours "Hello Nextflow" à des cas d’usage scientifiques spécifiques. - -!!! exercise "Nextflow for Genomics" - - !!! tip inline end "" - - :material-dna:{.nextflow-primary} Apprenez à développer un pipeline de génomique avec Nextflow. - - Ce cours s’adresse aux chercheur·euses souhaitant créer leurs propres pipelines de génomique. Il utilise un exemple d’appel de variants pour illustrer la création d’un pipeline simple mais fonctionnel. - - [Commencer la formation pour la génomique :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--primary } - -!!! exercise "Nextflow for RNAseq" - - !!! tip inline end "" - - :material-flask:{.nextflow-primary} Apprenez à développer un pipeline RNAseq avec Nextflow. - - Ce cours s’adresse aux chercheur·euses souhaitant créer des pipelines RNAseq. Il utilise un cas d’analyse de bulk RNAseq pour démontrer le développement d’un pipeline fonctionnel. - - [Commencer la formation RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--primary } - -Faites-nous savoir quels autres domaines ou cas d’usage vous aimeriez voir couverts en postant sur la [section Formation](https://community.seqera.io/c/training/) du forum de la communauté. - -## Formation approfondie Nextflow - -Ces cours montrent comment utiliser les fonctionnalités de Nextflow de manière plus détaillée ou à un niveau plus avancé. Chaque cours est composé d’un ou plusieurs modules conçus pour aider les apprenant·es à perfectionner leurs compétences sur les sujets correspondants. - -!!! exercise "Quêtes secondaires" - - !!! tip inline end "" - - :material-compass:{.nextflow-primary} Modules de formation sur divers sujets d’intérêt. - - Ce cours s’adresse aux développeur·euses Nextflow souhaitant élargir leur champ de compétences et/ou approfondir leurs connaissances. Bien que les modules soient présentés de manière linéaire, les apprenant·es peuvent les suivre dans n’importe quel ordre. Toute dépendance à des composants ou compétences dépassant le cadre du cours "Hello Nextflow" est indiquée dans l’introduction du module concerné. - - [Commencer la formation Quêtes secondaires :material-arrow-right:](side_quests/){ .md-button .md-button--primary } - -!!! exercise "Formation Fondamentaux" - - !!! quote inline end "" - - :octicons-mortar-board-16:{.nextflow-primary} Matériel de formation complet pour explorer l’ensemble des fonctionnalités de Nextflow. - - Le cours sur les fondamentaux couvre tous les aspects de Nextflow. Il est conçu comme une ressource de référence pour toute personne souhaitant construire des workflows complexes avec Nextflow. - - [Commencer la formation Fondamentaux :material-arrow-right:](basic_training/index.md){ .md-button .md-button--primary } - -!!! exercise "Formation Avancée" - - !!! quote inline end "" - - :fontawesome-solid-hat-wizard:{.nextflow-primary} Matériel de formation avancé pour maîtriser Nextflow. - - Ce cours approfondit les fonctionnalités les plus avancées du langage et de l’environnement d’exécution Nextflow, et explique comment les utiliser pour créer des workflows efficaces, évolutifs et adaptés aux traitements intensifs de données. - - [Commencer la formation Avancée :material-arrow-right:](advanced/index.md){ .md-button .md-button--primary } - -## Autres / Expérimental - -Ce sont des formations qui ne sont plus activement dispensées ou maintenues et que nous pourrions réutiliser ailleurs ou supprimer dans un avenir proche. -Les supports correspondants ne sont pas disponibles dans l’environnement de formation. -Vous pouvez toutefois les retrouver dans le dépôt GitHub et les télécharger pour une utilisation locale. - -- **nf-customize** — Configuration des pipelines nf-core ([docs](other/nf_customize) / [code](https://github.com/nextflow-io/training/tree/master/other/nf-customize)) - -- **troubleshoot** — Exercices de dépannage ([docs](other/troubleshoot) / [code](https://github.com/nextflow-io/training/tree/master/other/troubleshoot)) - -- **hands-on (rnaseq)** — Développement d’un pipeline pour l’analyse bulk RNAseq (obsolète) ([docs](other/hands_on) / [code](https://github.com/nextflow-io/training/tree/master/other/hands-on)) - -## Resources - -Référence rapide de quelques liens utiles: - -| Référence |  Communauté | -| ----------------------------------------------------------- | ------------------------------------------------------------ | -| [Nextflow Docs](https://nextflow.io/docs/latest/index.html) | [Nextflow Slack](https://www.nextflow.io/slack-invite.html)  | -| [Nextflow Homepage](https://nextflow.io/) | [nf-core](https://nf-co.re/) | -| [Seqera](https://seqera.io/) | [Seqera Community Forum](https://community.seqera.io) | - -Vous ne savez pas où aller ? Consultez la page [Obtenir de l'aide](help.fr.md). - -## Crédits et contributions - -[![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) - -Ce matériel de formation est développé et maintenu par [Seqera](https://seqera.io) et publié sous une licence open source ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) au bénéfice de la communauté. Vous êtes libre de réutiliser ces ressources conformément aux conditions de la licence. Si vous êtes formateur·trice et que vous organisez vos propres sessions, nous serions ravis d’avoir votre retour sur votre expérience et de savoir ce que nous pourrions faire pour vous faciliter la tâche. - -Nous accueillons avec plaisir les corrections et améliorations proposées par la communauté. Chaque page comporte une icône :material-file-edit-outline: en haut à droite qui vous redirige vers GitHub, où vous pouvez proposer des modifications du contenu via une pull request. - -<div markdown class="homepage_logos"> - -![Seqera](assets/img/seqera_logo.png#only-light) - -![Seqera](assets/img/seqera_logo_dark.png#only-dark) - -</div> diff --git a/docs/index.ko.md b/docs/index.ko.md deleted file mode 100644 index be820f9b67..0000000000 --- a/docs/index.ko.md +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: Nextflow Training -description: Welcome to the Nextflow community training portal! -hide: - - toc - - footer ---- - -# Nextflow Training - -Nextflow 커뮤니티 교육 포털에 오신 것을 환영합니다! - -이 웹사이트에는 여러 가지 다양한 교육 과정이 준비되어 있습니다. 아래로 스크롤하여 여러분에게 맞는 과정을 찾아보세요! - -아래 나열된 교육 과정들은 셀프 서비스 리소스로 활용할 수 있도록 설계되었으며, 언제든지 혼자서 학습을 진행할 수 있습니다 (자세한 내용은 Environment Setup을 참고하세요). 하지만 그룹 교육 행사에 참여하면 더욱 효과적으로 학습할 수 있습니다. - -- nf-core 커뮤니티에서 정기적으로 무료 온라인 행사를 진행합니다. 자세한 내용은 [nf-core 행사 페이지](https://nf-co.re/events)를 확인하세요. -- Nextflow를 개발한 회사인 Seqera에서는 다양한 교육 행사를 운영하고 있습니다. [Seqera 행사 페이지](https://seqera.io/events/)를 방문하여 'Seqera Sessions' 및 'Nextflow Summit'을 확인해보세요. -- 저희 커뮤니티 팀은 제3자 기관이 주최하는 교육도 정기적으로 진행하고 있습니다. 해당 교육은 일반적으로 주최 측에서 공지 및 신청을 관리합니다. - -준비가 되셨다면, 이 페이지나 선택한 과정의 인덱스 페이지에서 'Open in GitHub Codespaces' 버튼을 클릭하세요. 웹 기반의 교육 환경이 열립니다 (GitHub 무료 계정 필요). - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -## 교육 환경 설정 - -!!! exercise "환경 설정" - - !!! tip inline end "" - - :material-laptop:{.nextflow-primary} 처음 환경을 설정해보세요. - - 모든 교육 과정에서 사용할 수 있도록 학습 환경을 설정하는 방법에 대한 안내입니다. GitHub Codespaces에 대한 기본 소개와 로컬 컴퓨터에서 직접 작업할 수 있는 대체 설치 방법도 포함되어 있습니다. - - [환경 설정 교육 시작하기 :material-arrow-right:](envsetup/index.md){ .md-button .md-button--primary } - -## Nextflow 입문자를 위한 과정 - -이 과정들은 Nextflow를 완전히 처음 접하는 분들을 위한 기초 수업으로, 특정 분야의 전문 지식 없이도 학습할 수 있도록 구성되어 있습니다. 각 과정은 단계별로 실력을 쌓을 수 있도록 여러 개의 교육 모듈로 이루어져 있습니다. - -!!! exercise "Hello Nextflow" - - !!! tip inline end "" - - :material-run-fast:{.nextflow-primary} Nextflow로 파이프라인 개발 배우기 - - :fontawesome-brands-youtube:{.youtube} 동영상 자료 제공 - - 이 과정은 자신만의 파이프라인을 개발하고자 하는 입문자를 위한 교육입니다. Nextflow 언어의 핵심 구성 요소들을 충분히 상세하게 다루며, 단순하지만 완전한 기능을 갖춘 파이프라인을 개발할 수 있도록 도와줍니다. 또한 파이프라인 설계, 개발, 설정에 필요한 주요 개념들도 함께 다룹니다. - - [Hello Nextflow 교육 시작하기 :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--primary } - -!!! info "" - - **곧 출시 예정:** "Nextflow Run" — Nextflow 파이프라인 실행 배우기 (코드 개발 없이 실행만 다룸) - -<!-- COMMENTED OUT UNTIL THIS IS READY -!!! exercise "Nextflow Run" - - !!! tip inline end "" - - :material-run-fast:{.nextflow-primary} Nextflow 파이프라인 실행 방법 배우기 - - 이 과정은 기존 파이프라인을 실행하는 방법을 배우고자 하는 입문자를 위한 교육입니다. 기존 파이프라인을 이해하고 실행할 수 있도록 Nextflow 언어의 필수 개념만을 간단히 다루며, 명령줄 환경에서 Nextflow 파이프라인을 설정하고 실행하는 방법을 설명합니다. 또한, 커뮤니티에서 큐레이션한 다양한 파이프라인을 제공하는 nf-core 프로젝트와, 대규모 파이프라인 실행을 관리할 수 있도록 Seqera(Nextflow 개발사)에서 운영하는 플랫폼 등 Nextflow 생태계의 중요한 구성 요소들도 함께 소개합니다. - - [Nextflow Run 교육 시작하기 :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--primary } ---> - -## 과학 분야를 위한 Nextflow - -이 과정들은 위의 'Hello Nextflow'에서 소개한 개념과 구성 요소들을 실제 과학 분야의 활용 사례에 적용하는 방법을 보여줍니다. 각 과정은 단계적으로 실력을 쌓아갈 수 있도록 여러 개의 교육 모듈로 구성되어 있습니다. - -!!! exercise "유전체학을 위한 Nextflow" - - !!! tip inline end "" - - :material-dna:{.nextflow-primary} Nextflow로 유전체학 파이프라인 개발 배우기 - - 이 과정은 자신만의 유전체학 파이프라인을 개발하고자 하는 연구자를 위한 교육입니다. 변이 분석(variant calling) 사례를 통해 간단하면서도 기능적인 유전체학 파이프라인을 개발하는 방법을 보여줍니다. - - [유전체학 교육 시작하기 :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--primary } - -!!! exercise "RNAseq를 위한 Nextflow" - - !!! tip inline end "" - - :material-flask:{.nextflow-primary} Nextflow로 RNAseq 데이터 처리 파이프라인 개발 배우기 - - 이 과정은 자신만의 RNAseq 파이프라인을 개발하고자 하는 연구자를 위한 교육입니다. 벌크 RNAseq 처리 사례를 통해 간단하면서도 기능적인 RNAseq 파이프라인을 개발하는 방법을 소개합니다. - - [RNAseq 교육 시작하기 :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--primary } - -어떤 분야나 사용 사례가 추가되었으면 하는지 [커뮤니티 포럼의 교육 섹션](https://community.seqera.io/c/training/)에 글을 남겨 알려주세요. - -## Nextflow 심화 교육 - -이 과정들은 Nextflow의 기능을 더 자세히, 또는 더 고급 수준에서 활용하는 방법을 보여줍니다. 각 과정은 관련 주제에 대한 실력을 더욱 깊이 있게 다듬을 수 있도록 하나 이상의 교육 모듈로 구성되어 있습니다 - -!!! exercise "사이드 퀘스트" - - !!! tip inline end "" - - :material-compass:{.nextflow-primary} 다양한 주제를 다루는 교육 모듈 - - 이 과정은 Nextflow 개발자가 기술의 폭을 넓히거나 깊이를 더하고자 할 때 적합합니다. 모듈은 순서대로 제공되지만, 학습자는 자유롭게 원하는 주제부터 선택하여 학습할 수 있습니다. ‘Hello Nextflow’ 과정을 넘어서는 내용이 필요한 경우, 각 모듈 개요에 그에 대한 의존성이 명시되어 있습니다. - - [사이드 퀘스트 교육 시작하기 :material-arrow-right:](side_quests/){ .md-button .md-button--primary } - -!!! exercise "기초 교육" - - !!! quote inline end "" - - :octicons-mortar-board-16:{.nextflow-primary} Nextflow의 모든 기능을 아우르는 포괄적인 교육 자료 - - 이 기초 교육 자료는 Nextflow의 전반적인 내용을 다루며, 복잡한 워크플로우를 구축하려는 분들을 위한 참고 자료로 활용될 수 있습니다. - - [기초 교육 시작하기 :material-arrow-right:](basic_training/index.md){ .md-button .md-button--primary } - -!!! exercise "고급 교육" - - !!! quote inline end "" - - :fontawesome-solid-hat-wizard:{.nextflow-primary} Nextflow 마스터를 위한 고급 교육 자료 - - Nextflow 언어와 런타임의 고급 기능을 탐색하며, 이를 통해 데이터 집약적인 워크플로우를 효율적이고 확장 가능하게 작성하는 방법을 배울 수 있습니다. - - [고급 교육 시작하기 :material-arrow-right:](advanced/index.md){ .md-button .md-button--primary } - -## 기타 / 실험적 과정 - -이 교육 과정들은 현재 적극적으로 유지되거나 진행되지 않고 있으며, 향후 다른 용도로 재구성되거나 삭제될 수 있습니다. 해당 자료들은 교육 환경에서는 제공되지 않으며, GitHub 저장소에서 직접 다운로드하여 로컬에서 사용할 수 있습니다. - -- **nf-customize** — nf-core 파이프라인 설정 ([문서](other/nf_customize) / [코드](https://github.com/nextflow-io/training/tree/master/other/nf-customize)) -- **troubleshoot** — 문제 해결 연습 ([문서](other/troubleshoot) / [코드](https://github.com/nextflow-io/training/tree/master/other/troubleshoot)) -- **hands-on (rnaseq)** — 벌크 RNAseq 파이프라인 개발 (사용 중단됨) ([문서](other/hands_on) / [코드](https://github.com/nextflow-io/training/tree/master/other/hands-on)) - -## 자료 모음 - -유용한 참고 링크들을 빠르게 확인해보세요: - -| 참고 자료 | 커뮤니티 | -| ----------------------------------------------------------- | ------------------------------------------------------------ | -| [Nextflow 문서](https://nextflow.io/docs/latest/index.html) | [Nextflow Slack](https://www.nextflow.io/slack-invite.html)  | -| [Nextflow 홈페이지](https://nextflow.io/) | [nf-core](https://nf-co.re/) | -| [Seqera](https://seqera.io/) | [Seqera 커뮤니티 포럼](https://community.seqera.io) | - -어디서부터 시작할지 모르겠다면 [도움 받기](help.md) 페이지를 참고하세요. - -## 크레딧 및 기여 - -[![크리에이티브 커먼즈 라이선스: CC BY-NC-SA 4.0](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) - -이 교육 자료는 [Seqera](https://seqera.io)에서 개발 및 유지 관리하고 있으며, 커뮤니티의 이익을 위해 오픈소스 라이선스([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) 하에 배포됩니다. 라이선스 조건에 따라 자유롭게 재사용하실 수 있습니다. 교육을 진행하는 강사분이라면, 사용 경험과 개선점을 저희에게 알려주시면 감사하겠습니다. - -커뮤니티의 수정 및 개선 제안을 언제든지 환영합니다. 각 페이지 오른쪽 상단의 :material-file-edit-outline: 아이콘을 클릭하면 GitHub에서 Pull Request를 통해 제안할 수 있습니다. - -<div markdown class="homepage_logos"> - -![Seqera](assets/img/seqera_logo.png#only-light) - -![Seqera](assets/img/seqera_logo_dark.png#only-dark) - -</div> diff --git a/docs/index.pt.md b/docs/index.pt.md deleted file mode 100644 index e682941c4f..0000000000 --- a/docs/index.pt.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Portal de Treinamento Nextflow -description: Seja bem vindo ao portal de treinamento da comunidade do Nextflow! -hide: - - toc - - footer ---- - -# Treinamentos Nextflow - -Seja bem vindo ao portal de treinamentos da comunidade do Nextflow! - -Temos vários treinamentos distintos disponíveis neste site. Role para baixo para encontrar o que se adequa a suas necessidades. - -Os treinamentos listados abaixo foram construídos de modo que você possa fazê-los de forma independente; você pode trabalhar neles sozinho a qualquer momento (veja Configuração do Ambiente para detalhes práticos). No entanto, você pode usufruir ainda mais desses materiais ao participar de um evento de treinamento em grupo. - -- Eventos online gratuitos são realizados regularmente pela comunidade nf-core, veja a [página de eventos nf-core](https://nf-co.re/events) para mais informações. -- A Seqera (a empresa que desenvolve o Nextflow) realiza uma variedade de eventos de treinamento. Veja a página [Seqera Events](https://seqera.io/events/) e procure por 'Seqera Sessions' e 'Nextflow Summit'. -- Nosso time de Comunidade também ministra regularmente treinamentos hospedados por outras organizações; anúncios e inscrições para eles são normalmente gerenciados por essas organizações. - -Quando decidir começar o treinamento, clique no botão 'Open in GitHub Codespaces', nesta página ou na página de índice do treinamento escolhido, para abrir um ambiente de treinamento dentro do seu próporio navegador (requer uma conta gratuita no GitHub). - -[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) - -!!! warning - - Some of the translations on the training portal are out of date. - The translated material may be incomplete or incorrect. - We plan to update the translations later this year. - In the meantime, please try to work through the English-language material if you can. - -## Configuração do Ambiente - -!!! exercise "Configuração do Ambiente" - - !!! quote inline end "" - - :material-lightbulb: Essencial para configurar seu ambiente pela primeira vez. - - Instruções para configurar seu ambiente para trabalhar por meio dos materiais de treinamento desse portal. Fornece uma orientação para o Gitpod, bem como instruções de instalação alternativas para trabalhar em sua própria máquina local. - - [Inicie o treinamento de Configuração do Ambiente :material-arrow-right:](envsetup/index.md){ .md-button .md-button--primary } - -## Nextflow para iniciantes - -!!! exercise "Hello Nextflow" - - !!! quote inline end "" - - :material-run-fast: Uma série de treinamento modular para começar a usar o Nextflow. - - Este é um treinamento básico para aqueles que são completamente novos no Nextflow. Ele consiste em uma série de módulos de treinamento que são projetados para ajudar os alunos a desenvolver suas habilidades progressivamente. A série abrange os principais componentes da linguagem Nextflow, bem como práticas essenciais de design e desenvolvimento de pipeline e uso eficaz de recursos de terceiros. - - [Inicie o treinamento Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button } - -## Treinamento aprofundado em Nextflow - -!!! exercise "Fundamentals Training" - - !!! tip inline end "" - - :material-lightbulb: Material de treinamento abrangente para explorar todo o escopo dos recursos do Nextflow. - - O treinamento Fundamentals Training abrange tudo sobre o Nextflow. Excelente material de referência para qualquer um que queira construir fluxos de trabalho complexos com o Nextflow. - - [Inicie o Fundamentals Training :material-arrow-right:](basic_training/index.md){ .md-button .md-button--primary } - -!!! exercise "Advanced Training" - - !!! quote inline end "" - - :material-lightbulb: Material de treinamento avançado para dominar o Nextflow. - - Material avançado explorando os recursos mais avançados da linguagem e da ferramenta Nextflow e como usá-los para escrever fluxos de trabalho intensivos em dados, eficientes e escaláveis. - - [Inicie o Advanced Training :material-arrow-right:](advanced/index.md){ .md-button .md-button--primary } - -## Outros/Em desenvolvimento - -!!! exercise "Configure a execução de um pipeline nf-core" - - !!! quote inline end "" - - :material-run-fast: Este treinamento ajudará você a entender como personalizar a execução de um pipeline nf-core. - - Um tutorial "aprenda fazendo" com foco na configuração de pipelines nf-core. - - [Inicie o treinamento de configuração do nf-core :material-arrow-right:](nf_customize/index.md){ .md-button } - -!!! exercise "Desenvolva um pipeline com o modelo nf-core" - - !!! quote inline end "" - - :material-run-fast: Este treinamento ajudará você a entender a estrutura do modelo de pipeline nf-core. - - Um tutorial de desenvolvimento de pipeline "aprenda fazendo" com foco no desenvolvimento de um pipeline com o modelo nf-core. - - [Inicie o treinamento de desenvolvimento com nf-core :material-arrow-right:](nf_develop/index.md){ .md-button } - -!!! exercise "Troubleshooting exercises" - - !!! quote inline end "" - - :material-run-fast: Este treinamento ajudará você a solucionar erros comuns em pipeline. - - Um tutorial de solução de problemas "aprenda fazendo" para desenvolvedores e usuários de pipeline. - - [Inicie o treinamento de solucionamento de problemas :material-arrow-right:](troubleshoot/index.md){ .md-button } - -## Obsoleto - -!!! exercise "Simple RNA-seq variant calling" - - !!! quote inline end "" - - :material-run-fast: Um breve tutorial prático focado em um exemplo concreto de pipeline de análise. - - Este curso foi desenvolvido como um tutorial "aprender fazendo", com a intenção de ser uma maneira rápida e prática de entender o Nextflow usando um exemplo de pipeline de análise muito concreto. Você ainda pode encontrar os materiais no repositório do GitHub, mas ele não está mais sendo mantido e não pode mais ser iniciado no Gitpod ou no portal de treinamento. - -## Recursos - -Referência rápida para alguns links úteis: - -| Reference |  Community | -| ---------------------------------------------------------------------- | --------------------------------------------------------------- | -| [Documentação do Nextflow](https://nextflow.io/docs/latest/index.html) | [Slack do Nextflow](https://www.nextflow.io/slack-invite.html)  | -| [Página do Nextflow](https://nextflow.io/) | [Página do nf-core](https://nf-co.re/) | -| [Página da Seqera](https://seqera.io/) | [Seqera Community Forum](https://community.seqera.io) | - -Não sabe para onde ir? Confira a página [Obtendo ajuda](help.md). - -## Créditos e contribuições - -[![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) - -Este material de treinamento é desenvolvido e mantido pela [Seqera](https://seqera.io) e lançado sob uma licença de código aberto ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) para o benefício da comunidade. Sinta-se à vontade para reutilizar esses materiais de acordo com os termos da licença. Se você administra seus próprios treinamentos, ensinando terceiros, adoraríamos saber como está indo e o que poderíamos fazer para facilitar. - -Aceitamos correções e melhorias da comunidade. Cada página tem um ícone :material-file-edit-outline: no canto superior direito da página, que te levará ao GitHub, onde você pode propor alterações no material de treinamento por meio de uma solicitação de _pull_. - -<div markdown class="homepage_logos"> - -![Seqera](assets/img/seqera_logo.png#only-light) - -![Seqera](assets/img/seqera_logo_dark.png#only-dark) - -</div> diff --git a/docs/it/docs/envsetup/01_setup.md b/docs/it/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..6eef7b696b --- /dev/null +++ b/docs/it/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces è una piattaforma basata sul web che ci permette di fornire un ambiente preconfigurato per la formazione, supportato da macchine virtuali nel cloud. +La piattaforma è gestita da Github (di proprietà di Microsoft) ed è accessibile gratuitamente (con quote di utilizzo) a chiunque abbia un account Github. + +!!! warning "Avviso" + + Gli account associati a organizzazioni possono essere soggetti a determinate restrizioni aggiuntive. + Se questo è il vostro caso, potrebbe dover utilizzare un account personale indipendente, oppure optare per un'installazione locale. + +## Creare un account GitHub + +È possibile creare un account GitHub gratuito dalla [home page di GitHub](https://github.com/). + +## Avviare il vostro GitHub Codespace + +Una volta effettuato l'accesso a GitHub, apra questo link nel browser per aprire l'ambiente di formazione Nextflow: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +In alternativa, potete cliccare sul pulsante mostrato di seguito, che viene ripetuto in ogni corso di formazione (tipicamente nella pagina Orientamento). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Dovreste visualizzare una pagina dove potete creare un nuovo GitHub Codespace: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Configurazione + +Per l'uso generale, non dovrebbe essere necessario configurare nulla. +Salvo diversa indicazione nel corso che state iniziando, potete semplicemente cliccare sul pulsante principale per continuare. + +Tuttavia, è possibile personalizzare l'ambiente cliccando sul pulsante "Change options". + +??? info "Opzioni di configurazione" + + Se clicca sul pulsante "Change options", avrà la possibilità di personalizzare quanto segue: + + #### Branch + + Questo permette di selezionare una versione diversa dei materiali formativi. + Il branch `master` generalmente contiene correzioni di bug e materiali che sono stati recentemente sviluppati e approvati ma non ancora rilasciati sul sito web. + Altri branch contengono lavori in corso che potrebbero non essere completamente funzionanti. + + #### Tipo di macchina + + Questo permette di personalizzare la macchina virtuale che utilizzerà per lavorare attraverso la formazione. + + Utilizzare una macchina con più core permette di sfruttare maggiormente la capacità di Nextflow di parallelizzare l'esecuzione del workflow. + Tuttavia, consumerà la vostra quota gratuita più velocemente, quindi non raccomandiamo di modificare questa impostazione a meno che non sia consigliato nelle istruzioni del corso che sta pianificando di seguire. + + Vedere 'Quote di GitHub Codespaces' di seguito per maggiori dettagli sulle quote. + +### Tempo di avvio + +Aprire un nuovo ambiente GitHub Codespaces per la prima volta può richiedere diversi minuti, perché il sistema deve configurare la vostra macchina virtuale, quindi non preoccupatevi se c'è un tempo di attesa. +Tuttavia, non dovrebbe richiedere più di cinque minuti. + +## Navigare nell'interfaccia di formazione + +Una volta caricato il vostro GitHub Codespaces, dovrebbe vedere qualcosa di simile al seguente (che potrebbe aprirsi in modalità chiara a seconda delle preferenze del vostro account): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +Questa è l'interfaccia dell'IDE VSCode, un'applicazione popolare per lo sviluppo del codice che raccomandiamo di utilizzare per lo sviluppo Nextflow. + +- **L'editor principale** è dove il codice Nextflow e altri file di testo verranno aperti. Qui è dove modificherà il codice. Quando apre il codespace, questo mostrerà un'anteprima del file `README.md`. +- **Il terminale** sotto l'editor principale permette di eseguire comandi. Qui è dove eseguirà tutte le righe di comando fornite nelle istruzioni del corso. +- **La barra laterale** permette di personalizzare l'ambiente ed eseguire attività di base (copia, incolla, apertura file, ricerca, git, ecc.). Per impostazione predefinita è aperta sull'esplora file, che permette di navigare nei contenuti del repository. Cliccando su un file nell'esplora lo aprirà nella finestra dell'editor principale. + +È possibile regolare le proporzioni relative dei riquadri della finestra come preferisce. + +<!-- TODO (future) Link to development best practices side quest? --> + +## Altre note sull'uso di GitHub Codespaces + +### Riprendere una sessione + +Una volta creato un ambiente, è possibile riprenderlo o riavviarlo facilmente e continuare da dove si era lasciato. +L'ambiente andrà in timeout dopo 30 minuti di inattività e salverà le modifiche per un massimo di 2 settimane. + +È possibile riaprire un ambiente da <https://github.com/codespaces/>. +Gli ambienti precedenti saranno elencati. +Clicchi su una sessione per riprenderla. + +![List GitHub Codespace sessions](img/codespaces_list.png) + +Se avete salvato l'URL del vostro ambiente GitHub Codespaces precedente, potete semplicemente aprirlo nel browser. +In alternativa, cliccate sullo stesso pulsante che avete usato per crearlo inizialmente: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Dovrebbe vedere la sessione precedente, l'opzione predefinita è di riprenderla: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Salvare file sulla macchina locale + +Per salvare qualsiasi file dal pannello esplora, cliccate con il tasto destro sul file e selezionate `Download`. + +### Gestire le quote di GitHub Codespaces + +GitHub Codespaces offre fino a 15 GB-mese di spazio di archiviazione al mese, e 120 ore-core al mese. +Questo equivale a circa 60 ore di runtime dell'ambiente predefinito utilizzando il workspace standard (2 core, 8 GB RAM e 32 GB di archiviazione). + +È possibile crearli con più risorse (vedere la spiegazione sopra), ma questo consumerà il vostro utilizzo gratuito più velocemente e avrà meno ore di accesso a questo spazio. +Per esempio, se seleziona una macchina a 4 core invece della predefinita a 2 core, la vostra quota si esaurirà in metà tempo. + +Opzionalmente, è possibile acquistare l'accesso a più risorse. + +Per maggiori informazioni, vedere la documentazione GitHub: +[Informazioni sulla fatturazione per GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/it/docs/envsetup/02_local.md b/docs/it/docs/envsetup/02_local.md new file mode 100644 index 0000000000..8e811c0434 --- /dev/null +++ b/docs/it/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Installazione manuale + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +È possibile installare tutto il necessario per eseguire la formazione nel proprio ambiente locale manualmente. + +Qui abbiamo documentato come farlo su sistemi standard compatibili con POSIX (assumendo un computer personale come un laptop). +Tenga presente che alcuni dettagli potrebbero essere diversi a seconda del vostro sistema specifico. + +!!! tip "Suggerimento" + + Prima di procedere, ha considerato l'utilizzo dell'[approccio Devcontainers](03_devcontainer.md)? + Fornisce tutti gli strumenti e le dipendenze necessarie senza richiedere l'installazione manuale. + +## Requisiti software generali + +Nextflow può essere utilizzato su qualsiasi sistema compatibile con POSIX (Linux, macOS, Windows Subsystem for Linux, ecc.) con Java installato. +I nostri corsi di formazione hanno alcuni requisiti aggiuntivi. + +In totale, dovrà avere installato il seguente software: + +- Bash o shell equivalente +- [Java 11 (o successivo, fino a 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (o successivo) +- [VSCode](https://code.visualstudio.com) con l'[estensione Nextflow](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +L'applicazione VSCode è tecnicamente opzionale ma raccomandiamo fortemente di utilizzarla per lavorare attraverso i corsi così come per il vostro lavoro di sviluppo Nextflow in generale. + +Il manuale della documentazione Nextflow fornisce istruzioni per l'installazione di queste dipendenze in [Configurazione dell'ambiente](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow e strumenti nf-core + +Dovrà installare Nextflow stesso, oltre agli strumenti nf-core, come descritto negli articoli collegati di seguito: + +- [Installazione Nextflow](https://www.nextflow.io/docs/latest/install.html) +- [Strumenti nf-core](https://nf-co.re/docs/nf-core-tools/installation) + +Raccomandiamo di utilizzare l'opzione di auto-installazione per Nextflow e l'opzione PyPI per gli strumenti nf-core. + +!!! warning "Compatibilità delle versioni" + + <!-- Any update to this content needs to be copied to the home page --> + **A partire da gennaio 2026, tutti i nostri corsi di formazione Nextflow richiedono Nextflow versione 25.10.2 o successiva, con la sintassi strict v2 attivata, salvo diversa indicazione.** + + Per maggiori informazioni sui requisiti di versione e sulla sintassi strict v2, consultare la guida [Versioni di Nextflow](../info/nxf_versions.md). + + Le versioni precedenti del materiale formativo corrispondenti alla sintassi precedente sono disponibili tramite il selettore di versione nella barra del menu di questa pagina web. + +## Materiali formativi + +Il modo più semplice per scaricare i materiali formativi è clonare l'intero repository utilizzando questo comando: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Ogni corso ha la propria directory. +Per lavorare attraverso un corso, apra una finestra del terminale (idealmente, dall'interno dell'applicazione VSCode) e faccia `cd` nella directory pertinente. + +Può quindi seguire le istruzioni del corso fornite sul sito web. diff --git a/docs/it/docs/envsetup/03_devcontainer.md b/docs/it/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..f6fac61f62 --- /dev/null +++ b/docs/it/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Devcontainers Locali + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Se ha un'installazione Docker locale o è disposto a installarne una, il modo più semplice per lavorare localmente con questi materiali è utilizzare la funzionalità devcontainer di Visual Studio Code. Questo approccio fornisce tutti gli strumenti e le dipendenze necessarie senza richiedere l'installazione manuale. + +## Requisiti + +Per utilizzare la configurazione devcontainer locale, avrà bisogno di: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Un'installazione Docker locale, per esempio: + - [Docker Desktop](https://docs.docker.com/get-docker/) (per Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (per Linux) + - [Colima](https://github.com/abiosoft/colima) (alternativa per macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (incluso in Docker Desktop, ma potrebbe richiedere un'installazione separata con altre configurazioni Docker) +- [Estensione Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) per VS Code + +La vostra installazione Docker deve essere in esecuzione prima di tentare di aprire il devcontainer. + +Per verificare che Docker buildx sia disponibile, eseguite: + +```bash +docker buildx version +``` + +Se questo comando fallisce, dovrà installare l'estensione buildx prima di procedere. + +## Istruzioni di configurazione + +Segua questi passaggi per configurare il vostro ambiente locale utilizzando i devcontainer di VS Code: + +### Installare l'estensione "Dev Containers" in VS Code + +- Apra VS Code +- Vada su Extensions (Ctrl+Shift+X o Cmd+Shift+X su macOS) +- Cerchi "Dev Containers" +- Clicchi su "Install" + +![Installing Dev Containers extension in VS Code](img/install_extension.png) + +### Clonare il repository: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Aprire il repository in VS Code: + +- Avvii VS Code +- Selezioni **File -> Open Folder** dal menu +- Navighi e selezioni la cartella del repository training appena clonata +- Clicchi su **Open** + +### Riaprire nel Container + +Se VS Code vi chiede di "Reopen in Container", cliccate su di esso. In alternativa: + +- Prema F1 (o Ctrl+Shift+P / Cmd+Shift+P su macOS) +- Digiti "Dev Containers: Reopen in Container" +- **Importante**: Quando Le viene chiesto di selezionare una configurazione, scelga la configurazione devcontainer **local-dev** + +![Reopen in Container prompt](img/reopen_prompt.png) + +![Selecting local configuration](img/select_local_config.png) + +Attenda che il container venga costruito. Questo potrebbe richiedere alcuni minuti la prima volta poiché scarica e configura tutti i componenti necessari. + +Una volta che il container è costruito e in esecuzione, avrà un ambiente completamente configurato con tutti gli strumenti necessari installati, inclusi: + +- Java +- Nextflow +- Docker +- Git +- E tutte le altre dipendenze richieste per la formazione + +![VS Code with devcontainer running](img/running_container.png) + +## Vantaggi dell'utilizzo dei Devcontainers + +L'utilizzo dell'approccio devcontainer offre diversi vantaggi: + +- **Coerenza**: Garantisce un ambiente di sviluppo coerente su macchine diverse +- **Semplicità**: Tutte le dipendenze sono preinstallate e configurate +- **Isolamento**: L'ambiente di sviluppo è isolato dal vostro sistema locale +- **Riproducibilità**: Tutti coloro che utilizzano il devcontainer ottengono la stessa configurazione +- **Nessuna installazione manuale**: Non è necessario installare manualmente Java, Nextflow e altri strumenti + +## Verificare il vostro ambiente + +Una volta che il devcontainer è in esecuzione, potete verificare che tutto sia configurato correttamente eseguendo: + +```bash +nextflow info +``` + +Questo dovrebbe visualizzare la versione di Nextflow e le informazioni di runtime, confermando che il vostro ambiente è configurato correttamente. + +## Risoluzione dei problemi + +Se riscontra problemi con la configurazione del devcontainer: + +1. Assicuratevi che la vostra installazione Docker (Docker Desktop, Colima, Docker Engine, ecc.) sia in esecuzione prima di aprire il devcontainer +2. Verifichi di aver selezionato la configurazione **local-dev** quando richiesto +3. Verifichi che Docker buildx sia installato e funzionante eseguendo `docker buildx version` +4. Se il container non riesce a costruirsi, provi a ricostruirlo eseguendo il comando "Dev Containers: Rebuild Container" +5. Per problemi persistenti, consulti la [guida alla risoluzione dei problemi di VS Code Dev Containers](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/it/docs/envsetup/index.md b/docs/it/docs/envsetup/index.md new file mode 100644 index 0000000000..61297e418c --- /dev/null +++ b/docs/it/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Opzioni per l'ambiente +description: Opzioni per configurare il proprio ambiente per le formazioni Nextflow +hide: + - toc + - footer +--- + +# Opzioni per l'ambiente + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Il nostro obiettivo è fornire un ambiente coerente e accuratamente testato che permetta ai partecipanti di concentrarsi sull'apprendimento di Nextflow senza dover dedicare tempo e sforzi alla gestione del software. +A tal fine, abbiamo sviluppato un ambiente containerizzato che contiene tutto il software necessario, i file di codice e i dati di esempio per lavorare attraverso tutti i nostri corsi. + +Questo ambiente containerizzato può essere eseguito direttamente su GitHub Codespaces o localmente in VS Code con l'estensione Devcontainers. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **Github Codespaces** + + *** + + GitHub Codespaces è un servizio basato sul web che ci permette di fornire un ambiente preconfigurato per la formazione, con tutti gli strumenti e i dati inclusi, supportato da macchine virtuali nel cloud. È accessibile gratuitamente a chiunque abbia un account Github. + + [Usa Github Codespaces:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Devcontainers Locali** + + *** + + VS Code con Devcontainers fornisce un ambiente di sviluppo containerizzato eseguito localmente con tutti gli strumenti di formazione preconfigurati. Offre lo stesso ambiente preconfigurato di Codespaces ma funziona interamente sul vostro hardware locale. + + [Usa Devcontainers localmente :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Istruzioni per l'installazione manuale + +Se nessuna delle opzioni sopra soddisfa le vostre esigenze, potete replicare questo ambiente sul vostro sistema locale installando manualmente le dipendenze software e clonando il repository della formazione. + +[Installazione manuale :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Deprecazione di Gitpod" + + Nextflow Training utilizzava [Gitpod](https://gitpod.io) fino a febbraio 2025. + Tuttavia, i creatori di Gitpod hanno deciso di ritirare la funzionalità gratuita a favore del sistema [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex). + Per questo motivo, siamo passati all'utilizzo di GitHub Codespaces, che offre anch'esso un ambiente di sviluppo con un solo clic senza configurazione preliminare. + + A seconda di quando si è registrato su Gitpod e di quando esattamente verrà ritirato il servizio, potrebbe ancora essere in grado di avviare la formazione nel loro vecchio IDE cloud, anche se non possiamo garantire un accesso affidabile in futuro: + [Apri in Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/it/docs/hello_nextflow/00_orientation.md b/docs/it/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..f0f84470d6 --- /dev/null +++ b/docs/it/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Per iniziare + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/00_orientation.md). +/// + +!!! tip "Suggerimento" + + I video di YouTube hanno alcune funzionalità speciali! + + - :fontawesome-solid-closed-captioning: Sottotitoli di alta qualità (curati manualmente). Li attivi con l'icona :material-subtitles: + - :material-bookmark: Capitoli video nella timeline che corrispondono alle intestazioni della pagina. + +## Avviare un ambiente di formazione + +Per utilizzare l'ambiente preconfigurato che forniamo su GitHub Codespaces, cliccate sul pulsante "Open in GitHub Codespaces" qui sotto. Per altre opzioni, consultate [Opzioni per l'ambiente](../envsetup/index.md). + +Vi consigliamo di aprire l'ambiente di formazione in una nuova scheda o finestra del browser (usate il clic destro, ctrl-clic o cmd-clic a seconda del vostro dispositivo) in modo da poter continuare a leggere mentre l'ambiente si carica. +Dovrete tenere queste istruzioni aperte in parallelo per lavorare attraverso il corso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Nozioni di base sull'ambiente + +Questo ambiente di formazione contiene tutto il software, il codice e i dati necessari per lavorare attraverso il corso di formazione, quindi non è necessario installare nulla. + +Il codespace è configurato con un'interfaccia VSCode, che include un esplora file, un editor di codice e una shell del terminale. +Tutte le istruzioni fornite durante il corso (ad es. 'aprite il file', 'modificate il codice' o 'eseguite questo comando') si riferiscono a queste tre parti dell'interfaccia VScode, salvo diversa indicazione. + +Se state seguendo questo corso autonomamente, familiarizzatevi con le [nozioni di base sull'ambiente](../envsetup/01_setup.md) per ulteriori dettagli. + +### Requisiti di versione + +Questa formazione è progettata per Nextflow 25.10.2 o successivo **con il parser di sintassi v2 ABILITATO**. +Se state utilizzando un ambiente locale o personalizzato, assicuratevi di utilizzare le impostazioni corrette come documentato [qui](../info/nxf_versions.md). + +## Prepararsi a lavorare + +Una volta che il codespace è in esecuzione, ci sono due cose da fare prima di immergersi nella formazione: impostare la directory di lavoro per questo corso specifico e dare un'occhiata ai materiali forniti. + +### Impostare la directory di lavoro + +Per impostazione predefinita, il codespace si apre con la directory di lavoro impostata alla radice di tutti i corsi di formazione, ma per questo corso lavoreremo nella directory `hello-nextflow/`. + +Cambiate directory ora eseguendo questo comando nel terminale: + +```bash +cd hello-nextflow/ +``` + +Potete impostare VSCode per focalizzarsi su questa directory, in modo che solo i file rilevanti vengano mostrati nella barra laterale dell'esplora file: + +```bash +code . +``` + +!!! tip "Suggerimento" + + Se per qualsiasi motivo uscite da questa directory (ad es. il codespace va in sleep), potete sempre usare il percorso completo per tornarci, assumendo che stiate eseguendo all'interno dell'ambiente di formazione Github Codespaces: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Ora diamo un'occhiata ai contenuti. + +### Esplorare i materiali forniti + +Potete esplorare i contenuti di questa directory utilizzando l'esplora file sul lato sinistro dell'area di lavoro di formazione. +In alternativa, potete usare il comando `tree`. + +Durante il corso, utilizziamo l'output di `tree` per rappresentare la struttura della directory e i contenuti in una forma leggibile, a volte con piccole modifiche per chiarezza. + +Qui generiamo una tabella dei contenuti fino al secondo livello: + +```bash +tree . -L 2 +``` + +??? abstract "Contenuti della directory" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Cliccate sul riquadro colorato per espandere la sezione e visualizzarne i contenuti. +Utilizziamo sezioni espandibili come questa per includere l'output dei comandi atteso in modo conciso. + +- **I file `.nf`** sono script di workflow denominati in base alla parte del corso in cui vengono utilizzati. + +- **Il file `nextflow.config`** è un file di configurazione che imposta proprietà minime dell'ambiente. + Potete ignorarlo per ora. + +- **Il file `greetings.csv`** sotto `data/` contiene i dati di input che useremo nella maggior parte del corso. È descritto nella Parte 2 (Channels), quando lo introduciamo per la prima volta. + +- **I file `test-params.*`** sono file di configurazione che useremo nella Parte 6 (Configuration). Potete ignorarli per ora. + +- **La directory `solutions`** contiene gli script di workflow completati che risultano da ogni passaggio del corso. + Sono pensati per essere usati come riferimento per verificare il vostro lavoro e risolvere eventuali problemi. + +## Checklist di preparazione + +Pensate di essere pronti a iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio ambiente è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato + +Se potete spuntare tutte le caselle, siete pronti a partire. + +**Per continuare alla [Parte 1: Hello World](./01_hello_world.md), cliccate sulla freccia nell'angolo in basso a destra di questa pagina.** diff --git a/docs/it/docs/hello_nextflow/01_hello_world.md b/docs/it/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..bf0d266327 --- /dev/null +++ b/docs/it/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Parte 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/01_hello_world.md). +/// + +In questa prima parte del corso di formazione Hello Nextflow, introduciamo l'argomento con un esempio Hello World molto semplice e indipendente dal dominio, che costruiremo progressivamente per dimostrare l'uso della logica e dei componenti fondamentali di Nextflow. + +??? info "Cos'è un esempio Hello World?" + + Un "Hello World!" è un esempio minimalista pensato per dimostrare la sintassi e la struttura di base di un linguaggio di programmazione o framework software. + L'esempio consiste tipicamente nella stampa della frase "Hello, World!" su un dispositivo di output, come la console o il terminale, oppure nella sua scrittura su un file. + +--- + +## 0. Riscaldamento: Eseguire un esempio Hello World direttamente + +Dimostriamolo con un semplice comando che eseguiamo direttamente nel terminale, per mostrare cosa fa prima di incapsularlo in Nextflow. + +!!! tip "Suggerimento" + + Ricordate che ora dovreste trovarvi nella directory `hello-nextflow/` come descritto nella pagina [Per iniziare](00_orientation.md). + +### 0.1. Far dire hello al terminale + +Eseguite il seguente comando nel terminale. + +```bash +echo 'Hello World!' +``` + +??? success "Output del comando" + + ```console + Hello World! + ``` + +Questo produce il testo 'Hello World' direttamente nel terminale. + +### 0.2. Scrivere l'output su un file + +L'esecuzione di pipeline coinvolge principalmente la lettura di dati da file e la scrittura di risultati su altri file, quindi modifichiamo il comando per scrivere l'output testuale su un file per rendere l'esempio un po' più pertinente. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Output del comando" + + ```console + + ``` + +Questo non produce alcun output nel terminale. + +### 0.3. Trovare l'output + +Il testo 'Hello World' dovrebbe ora trovarsi nel file di output che abbiamo specificato, chiamato `output.txt`. +Potete aprirlo nell'esplora file o dalla riga di comando utilizzando l'utility `cat`, ad esempio. + +??? abstract "Contenuti del file" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Questo è ciò che cercheremo di replicare con il nostro primo workflow Nextflow. + +### Takeaway + +Ora sapete come eseguire un semplice comando nel terminale che produce del testo, e opzionalmente, come farlo scrivere l'output su un file. + +### Cosa c'è dopo? + +Scoprite come apparirebbe scritto come workflow Nextflow. + +--- + +## 1. Esaminare lo script ed eseguirlo + +Vi forniamo uno script di workflow completamente funzionale, anche se minimalista, chiamato `hello-world.nf` che fa la stessa cosa di prima (scrive 'Hello World!') ma con Nextflow. + +Per iniziare, apriamo lo script del workflow così potete farvi un'idea di come è strutturato. +Poi lo eseguiremo e cercheremo i suoi output. + +### 1.1. Esaminare il codice + +Troverete lo script `hello-world.nf` nella vostra directory corrente, che dovrebbe essere `hello-nextflow`. Apritelo nel riquadro dell'editor. + +??? full-code "File di codice completo" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usa echo per stampare 'Hello World!' su un file + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // emette un saluto + sayHello() + } + ``` + +Uno script di workflow Nextflow include tipicamente una o più definizioni di **process** e il **workflow** stesso, più alcuni blocchi opzionali (non presenti qui) che introdurremo più avanti. + +Ogni **process** descrive quale/i operazione/i il corrispondente step nella pipeline dovrebbe eseguire, mentre il **workflow** descrive la logica del flusso di dati che connette i vari step. + +Esamineremo prima più da vicino il blocco **process**, poi guarderemo il blocco **workflow**. + +#### 1.1.1. La definizione del `process` + +Il primo blocco di codice descrive un **process**. + +La definizione del process inizia con la parola chiave `process`, seguita dal nome del process e infine dal corpo del process delimitato da parentesi graffe. +Il corpo del process deve contenere un blocco script che specifica il comando da eseguire, che può essere qualsiasi cosa si possa eseguire in un terminale a riga di comando. + +```groovy title="hello-world.nf" linenums="3" +/* +* Usa echo per stampare 'Hello World!' su un file +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Qui abbiamo un **process** chiamato `sayHello` che scrive il suo **output** su un file chiamato `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +Questa è una definizione di process molto minimale che contiene solo una definizione di `output` e lo `script` da eseguire. + +La definizione di `output` include il qualificatore `path`, che dice a Nextflow che questo dovrebbe essere gestito come un percorso (include sia percorsi di directory che file). +Un altro qualificatore comune è `val`. + +È importante notare che la definizione di output non _determina_ quale output verrà creato. +Semplicemente _dichiara_ qual è l'output atteso, così che Nextflow possa cercarlo una volta completata l'esecuzione. +Questo è necessario per verificare che il comando sia stato eseguito con successo e per passare l'output ai processi a valle se necessario. L'output prodotto che non corrisponde a quanto dichiarato nel blocco output non verrà passato ai processi a valle. + +!!! warning "Avviso" + + Questo esempio è fragile perché abbiamo codificato in modo fisso il nome del file di output in due posti separati (lo script e i blocchi output). + Se modifichiamo uno ma non l'altro, lo script si romperà. + Più avanti imparerete modi per usare le variabili per mitigare questo problema. + +In una pipeline reale, un process contiene di solito blocchi aggiuntivi come direttive e input, che introdurremo tra poco. + +#### 1.1.2. La definizione del `workflow` + +Il secondo blocco di codice descrive il **workflow** stesso. +La definizione del workflow inizia con la parola chiave `workflow`, seguita da un nome opzionale, poi dal corpo del workflow delimitato da parentesi graffe. + +Qui abbiamo un **workflow** che consiste in un blocco `main:` (che dice 'questo è il corpo principale del workflow') contenente una chiamata al process `sayHello`. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // emette un saluto + sayHello() +} +``` + +Questa è una definizione di **workflow** molto minimale. +In una pipeline reale, il workflow contiene tipicamente multiple chiamate a **processi** connessi da **channel**, e i processi si aspettano uno o più **input** variabili. + +Imparerete come aggiungere input variabili più avanti in questo modulo di formazione; e imparerete come aggiungere più processi e connetterli tramite channel nella Parte 3 di questo corso. + +!!! tip "Suggerimento" + + Tecnicamente la riga `main:` non è richiesta per workflow semplici come questo, quindi potreste incontrare workflow che non ce l'hanno. + Ma ne avremo bisogno per sfruttare gli output a livello di workflow, quindi tanto vale includerla dall'inizio. + +### 1.2. Eseguire il workflow + +Guardare il codice non è divertente quanto eseguirlo, quindi proviamolo in pratica. + +#### 1.2.1. Avviare il workflow e monitorare l'esecuzione + +Nel terminale, eseguite il seguente comando: + +```bash +nextflow run hello-world.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Se l'output della console assomiglia a questo, congratulazioni, avete appena eseguito il vostro primo workflow Nextflow! + +L'output più importante qui è l'ultima riga, che è evidenziata nell'output sopra: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Questo ci dice che il process `sayHello` è stato eseguito con successo una volta (`1 of 1 ✔`). + +È importante notare che questa riga indica anche dove trovare l'output della chiamata al process `sayHello`. +Guardiamolo ora. + +#### 1.2.2. Trovare l'output e i log nella directory `work` + +Quando eseguite Nextflow per la prima volta in una data directory, crea una directory chiamata `work` dove scriverà tutti i file (e tutti i symlink) generati nel corso dell'esecuzione. + +All'interno della directory `work`, Nextflow organizza output e log per ogni chiamata di process. +Per ogni chiamata di process, Nextflow crea una sottodirectory nidificata, denominata con un hash per renderla unica, dove preparerà tutti gli input necessari (usando symlink per impostazione predefinita), scriverà file di supporto e scriverà log e tutti gli output del process. + +Il percorso di quella sottodirectory è mostrato in forma troncata tra parentesi quadre nell'output della console. +Guardando cosa abbiamo ottenuto per l'esecuzione mostrata sopra, la riga di log della console per il process sayHello inizia con `[65/7be2fa]`. Questo corrisponde al seguente percorso di directory: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +Diamo un'occhiata a cosa c'è dentro. + +??? abstract "Contenuti della directory" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Non vedete la stessa cosa?" + + I nomi esatti delle sottodirectory saranno diversi sul vostro sistema. + + Se naviga nei contenuti della sottodirectory dell'attività nell'esplora file di VSCode, vedrà tutti i file immediatamente. + Tuttavia, i file di log sono impostati per essere invisibili nel terminale, quindi se vuole usare `ls` o `tree` per visualizzarli, dovrà impostare l'opzione pertinente per visualizzare i file invisibili. + + ```bash + tree -a work + ``` + +La prima cosa che vorrete guardare è l'output effettivo del workflow, cioè il file `output.txt` prodotto dal process `sayHello`. +Apritelo e troverete il saluto `Hello World!`, che era lo scopo del nostro workflow minimalista. + +??? abstract "Contenuti del file" + + ```console title="output.txt" + Hello World! + ``` + +Ha funzionato! + +Certo, potrebbe sembrare molto codice di wrapper per un risultato così piccolo, ma il valore di tutto quel codice di wrapper diventerà più ovvio una volta che inizieremo a leggere file di input e a concatenare più step insieme. + +Detto questo, diamo anche un'occhiata agli altri file in quella directory. Sono file di supporto e di log prodotti da Nextflow come parte dell'esecuzione dell'attività. + +- **`.command.begin`**: Metadati relativi all'inizio dell'esecuzione della chiamata del process +- **`.command.err`**: Messaggi di errore (`stderr`) emessi dalla chiamata del process +- **`.command.log`**: Output di log completo emesso dalla chiamata del process +- **`.command.out`**: Output regolare (`stdout`) della chiamata del process +- **`.command.run`**: Script completo eseguito da Nextflow per eseguire la chiamata del process +- **`.command.sh`**: Il comando che è stato effettivamente eseguito dalla chiamata del process +- **`.exitcode`**: Il codice di uscita risultante dal comando + +Il file `.command.sh` è particolarmente utile perché indica il comando principale che Nextflow ha eseguito, non includendo tutta la contabilità e la configurazione dell'attività/ambiente. + +??? abstract "Contenuti del file" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Questo corrisponde a quanto abbiamo eseguito manualmente prima. + +In questo caso è molto semplice perché il comando del process era codificato in modo fisso, ma più avanti nel corso vedrà comandi di process che coinvolgono qualche interpolazione di variabili. +Questo rende particolarmente prezioso poter vedere esattamente come Nextflow ha interpretato il codice e quale comando è stato prodotto quando si sta risolvendo un problema in un'esecuzione fallita. + +### 1.3. Eseguire di nuovo il workflow + +Provate a rieseguire il workflow alcune volte, poi guardate le directory delle attività sotto `work/`. + +??? abstract "Contenuti della directory" + + ```console + 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 + ``` + +Vede che è stata creata una nuova sottodirectory con un set completo di file di output e log per ogni esecuzione. +Questo mostra che eseguire lo stesso workflow più volte non sovrascriverà i risultati delle esecuzioni precedenti. + +### Takeaway + +Sapete come decifrare un semplice script Nextflow, eseguirlo e trovare l'output e i file di log rilevanti nella directory work. + +### Cosa c'è dopo? + +Imparate come pubblicare gli output del workflow in una posizione più conveniente. + +--- + +## 2. Pubblicare gli output + +Come ha appena appreso, l'output prodotto dalla nostra pipeline è sepolto in una directory di lavoro a diversi livelli di profondità. +Questo è fatto di proposito; Nextflow ha il controllo di questa directory e non dovremmo interagire con essa. +Tuttavia, questo rende scomodo recuperare gli output che ci interessano. + +Fortunatamente, Nextflow fornisce un modo per pubblicare gli output in una directory designata usando le [definizioni di output a livello di workflow](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs). + +### 2.1. Uso di base + +Questo coinvolgerà due nuovi pezzi di codice: + +1. Un blocco `publish:` all'interno del corpo del `workflow`, che dichiara gli output dei processi. +2. Un blocco `output` nello script che specifica le opzioni di output come modalità e posizione. + +#### 2.1.1. Dichiarare l'output del process `sayHello` + +Dobbiamo aggiungere un blocco `publish:` al corpo del workflow (stesso tipo di elemento di codice del blocco `main:`) e listare l'output del process `sayHello()`. + +Nel file dello script del workflow `hello-world.nf`, aggiungete le seguenti righe di codice: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // emette un saluto + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emette un saluto + sayHello() + } + ``` + +Vedete che possiamo riferirci all'output del process semplicemente facendo `sayHello().out`, e assegnargli un nome arbitrario, `first_output`. + +#### 2.1.2. Aggiungere un blocco `output:` allo script + +Ora dobbiamo solo aggiungere il blocco `output:` dove verrà specificato il percorso della directory di output. Noti che questo nuovo blocco si trova **fuori** e **sotto** il blocco `workflow` all'interno dello script. + +Nel file dello script del workflow `hello-world.nf`, aggiungete le seguenti righe di codice: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // emette un saluto + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emette un saluto + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Possiamo usare questo per assegnare percorsi specifici a qualsiasi output di process dichiarato nel blocco `workflow`. +Più avanti imparerete modi per generare strutture di directory di output sofisticate, ma per ora stiamo semplicemente codificando in modo fisso un percorso minimo per semplicità. + +#### 2.1.3. Eseguire il workflow + +Ora eseguite lo script del workflow modificato: + +```bash +nextflow run hello-world.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +L'output del terminale dovrebbe sembrare familiare. Esternamente, nulla è cambiato. + +Tuttavia, controllate il vostro esplora file: questa volta, Nextflow ha creato una nuova directory chiamata `results/`. + +??? abstract "Contenuti della directory" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +All'interno della directory `results`, troviamo un link simbolico al file `output.txt` prodotto nella directory work dal comando che abbiamo appena eseguito. + +Questo ci permette di recuperare facilmente i file di output senza dover scavare nella sottodirectory work. + +### 2.2. Impostare una posizione personalizzata + +Avere una posizione predefinita è ottimo, ma potreste voler personalizzare dove vengono salvati i risultati e come sono organizzati. + +Per esempio, potreste voler organizzare i vostri output in sottodirectory. +Il modo più semplice per farlo è assegnare percorsi di output specifici per ogni output. + +#### 2.2.1. Modificare il percorso di output + +Ancora una volta, modificare il comportamento di pubblicazione per un output specifico è davvero semplice. +Per impostare una posizione personalizzata, basta modificare il `path` di conseguenza: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Poiché questo è impostato a livello del singolo output, potete specificare posizioni e sottodirectory diverse per soddisfare le vostre esigenze. + +#### 2.2.2. Eseguire di nuovo il workflow + +Proviamo. + +```bash +nextflow run hello-world.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Questa volta il risultato viene scritto nella sottodirectory specificata. + +??? abstract "Contenuti della directory" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Vedete che il risultato dell'esecuzione precedente è ancora lì. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +Potete usare quanti livelli di nidificazione desiderate. +È anche possibile usare il nome del process o altre variabili per nominare le directory usate per organizzare i risultati, ed è possibile cambiare il nome predefinito della directory di output di primo livello (che è controllata dalla variabile speciale `outputDir`). +Copriremo queste opzioni in formazioni successive. + +### 2.3. Impostare la modalità di pubblicazione su copy + +Per impostazione predefinita, gli output vengono pubblicati come link simbolici dalla directory `work`. +Questo significa che c'è un solo file nel filesystem. + +Questo è ottimo quando si hanno a che fare con file molto grandi, per i quali non si vogliono memorizzare copie multiple. +Tuttavia, se eliminate la directory work in qualsiasi momento (copriremo le operazioni di pulizia a breve), perderete l'accesso al file. +Quindi dovete avere un piano per salvare copie di tutti i file importanti in un posto sicuro. + +Un'opzione facile è cambiare la modalità di pubblicazione su copy per gli output che vi interessano. + +#### 2.3.1. Aggiungere la direttiva mode + +Questa parte è davvero semplice. +Basta aggiungere `mode 'copy'` alla definizione di output a livello di workflow pertinente: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Questo imposta la modalità di pubblicazione per quello specifico output. + +#### 2.3.2. Eseguire di nuovo il workflow + +Proviamo. + +```bash +nextflow run hello-world.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Questa volta, se guarda i risultati, il file è una copia vera e propria invece di un semplice symlink. + +??? abstract "Contenuti della directory" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Poiché anche questo è impostato a livello del singolo output, vi permette di impostare la modalità di pubblicazione in modo granulare. +Questo sarà particolarmente utile più avanti quando passeremo a pipeline multi-step, dove potrebbe voler copiare solo gli output finali e lasciare gli output intermedi come symlink, per esempio. + +Come notato prima, ci sono altre opzioni più sofisticate per controllare come vengono pubblicati gli output. +Vi mostreremo come usarle a tempo debito nel vostro percorso con Nextflow. + +### 2.4. Nota sulle direttive `publishDir` a livello di process + +Fino a molto recentemente, il modo stabilito per pubblicare gli output era farlo a livello di ogni singolo process usando una direttiva `publishDir`. + +Per ottenere quanto abbiamo appena fatto per gli output del process `sayHello`, avremmo invece aggiunto la seguente riga alla definizione del process: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Troverete ancora questo pattern di codice ovunque nelle pipeline Nextflow più vecchie e nei moduli di process, quindi è importante esserne consapevoli. +Tuttavia, non raccomandiamo di usarlo in nessun nuovo lavoro poiché sarà eventualmente vietato nelle versioni future del linguaggio Nextflow. + +### Takeaway + +Sapete come pubblicare gli output del workflow in una posizione più conveniente. + +### Cosa c'è dopo? + +Imparate a fornire un input variabile tramite un parametro da riga di comando e utilizzare efficacemente i valori predefiniti. + +--- + +## 3. Usare un input variabile passato dalla riga di comando + +Nel suo stato attuale, il nostro workflow usa un saluto codificato in modo fisso nel comando del process. +Vogliamo aggiungere un po' di flessibilità usando una variabile di input, così da poter cambiare più facilmente il saluto a runtime. + +Questo richiede di apportare tre serie di modifiche al nostro script: + +1. Modificare il process per aspettarsi un input variabile +2. Impostare un parametro da riga di comando per catturare l'input dell'utente +3. Passare l'input al process nel corpo del workflow + +Facciamo queste modifiche una alla volta. + +### 3.1. Modificare il process `sayHello` per aspettarsi un input variabile + +Dobbiamo modificare la definizione del process per (1) accettare una variabile di input e (2) usare quella variabile nella riga di comando. + +#### 3.1.1. Aggiungere un blocco input alla definizione del process + +Prima, adattiamo la definizione del process per accettare un input chiamato `greeting`. + +Nel blocco del process, fate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +La variabile `greeting` è prefissata da `val` per dire a Nextflow che è un valore (non un percorso). + +#### 3.1.2. Modificare il comando del process per usare la variabile di input + +Ora scambiamo il valore originale codificato in modo fisso con il valore della variabile di input che ci aspettiamo di ricevere. + +Nel blocco del process, fate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +Il simbolo `$` e le parentesi graffe (`{ }`) dicono a Nextflow che questo è un nome di variabile che deve essere sostituito con il valore di input effettivo (=interpolato). + +!!! tip "Suggerimento" + + Le parentesi graffe (`{ }`) erano tecnicamente opzionali nelle versioni precedenti di Nextflow, quindi potreste vedere workflow più vecchi dove questo è scritto come `echo '$greeting' > output.txt`. + +Ora che il process `sayHello()` è pronto ad accettare un input variabile, abbiamo bisogno di un modo per fornire un valore di input alla chiamata del process a livello di workflow. + +### 3.2. Impostare un parametro da riga di comando per catturare l'input dell'utente + +Potremmo semplicemente codificare in modo fisso un input direttamente facendo la chiamata al process `sayHello('Hello World!')`. +Tuttavia, quando facciamo lavoro reale con il nostro workflow, vorremo essere in grado di controllare i suoi input dalla riga di comando. + +Buone notizie: Nextflow ha un sistema di parametri di workflow integrato chiamato `params`, che rende facile dichiarare e usare parametri CLI. + +La sintassi generale è dichiarare `params.<nome_parametro>` per dire a Nextflow di aspettarsi un parametro `--<nome_parametro>` sulla riga di comando. + +Qui vogliamo creare un parametro chiamato `--input`, quindi dobbiamo dichiarare `params.input` da qualche parte nel workflow. +In linea di principio possiamo scriverlo ovunque; ma poiché vorremo darlo alla chiamata del process `sayHello()`, possiamo inserirlo direttamente lì scrivendo `sayHello(params.input)`. + +Nel blocco del workflow, fate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emette un saluto + sayHello(params.input) + ``` + +=== "Prima" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emette un saluto + sayHello() + ``` + +Questo dice a Nextflow di eseguire il process `sayHello` sul valore fornito tramite il parametro `--input`. + +In effetti, abbiamo compiuto i passaggi (2) e (3) delineati all'inizio della sezione in un colpo solo. + +### 3.3. Eseguire il comando del workflow + +Eseguiamolo! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Se avete fatto tutte queste modifiche correttamente, dovreste ottenere un'altra esecuzione riuscita. + +Assicuratevi di aprire il file di output per verificare che ora abbiate la nuova versione del saluto. + +??? abstract "Contenuti del file" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Noti come la nuova esecuzione ha sovrascritto il file di output pubblicato nella directory `results`. +Tuttavia, i risultati delle esecuzioni precedenti sono ancora conservati nelle directory delle attività sotto `work`. + +!!! tip "Suggerimento" + + Potete facilmente distinguere i parametri a livello di Nextflow dai parametri a livello di pipeline. + + - I parametri che si applicano a una pipeline prendono sempre un doppio trattino (`--`). + - I parametri che modificano un'impostazione di Nextflow, _ad es._ la funzione `-resume` che abbiamo usato prima, prendono un singolo trattino (`-`). + +### 3.4. Usare valori predefiniti per i parametri da riga di comando + +Ok, quello era conveniente, ma in molti casi ha senso fornire un valore predefinito per un dato parametro così da non doverlo specificare per ogni esecuzione. + +#### 3.4.1. Impostare un valore predefinito per il parametro CLI + +Diamo al parametro `input` un valore predefinito dichiarandolo prima della definizione del workflow. + +```groovy title="hello-world.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String = 'Holà mundo!' +} +``` + +Come vedete, possiamo specificare il tipo di input che il workflow si aspetta (Nextflow 25.10.2 e successivi). +La sintassi è `nome: Tipo = valore_predefinito`. +I tipi supportati includono `String`, `Integer`, `Float`, `Boolean` e `Path`. + +!!! info "Nota" + + Nei workflow più vecchi, potreste vedere quel intero blocco `params` scritto semplicemente come `input = 'Holà mundo!'`. + +Man mano che aggiungete più parametri alla vostra pipeline, dovreste aggiungerli tutti a questo blocco, che debbano o meno avere un valore predefinito. +Questo renderà facile trovare tutti i parametri configurabili a colpo d'occhio. + +#### 3.4.2. Eseguire di nuovo il workflow senza specificare il parametro + +Ora che avete un valore predefinito impostato, potete eseguire di nuovo il workflow senza dover specificare un valore nella riga di comando. + +```bash +nextflow run hello-world.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +L'output sarà nella stessa posizione di prima, ma i contenuti dovrebbero essere aggiornati con il nuovo testo. + +??? abstract "Contenuti del file" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow ha usato il valore predefinito del parametro greeting per creare l'output. + +#### 3.4.3. Sovrascrivere il valore predefinito + +Se fornite il parametro sulla riga di comando, il valore CLI sovrascriverà il valore predefinito. + +Provate: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Ancora una volta, dovreste trovare l'output aggiornato corrispondente nella vostra directory results. + +??? abstract "Contenuti del file" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Nota" + + In Nextflow, ci sono più posti dove può specificare valori per i parametri. + Se lo stesso parametro è impostato su valori diversi in più posti, Nexflow determinerà quale valore usare in base all'ordine di precedenza descritto [qui](https://www.nextflow.io/docs/latest/config.html). + + Copriremo questo in maggior dettaglio nella Parte 6 (Configuration). + +### Takeaway + +Sapete come usare un semplice input variabile fornito a runtime tramite un parametro da riga di comando, così come impostare, usare e sovrascrivere valori predefiniti. + +### Cosa c'è dopo? + +Imparate a gestire le esecuzioni in modo più conveniente. + +--- + +## 4. Gestire le esecuzioni del workflow + +Sapere come avviare workflow e recuperare output è ottimo, ma scoprirete rapidamente che ci sono alcuni altri aspetti della gestione del workflow che vi renderanno la vita più facile, specialmente se state sviluppando i vostri workflow. + +Qui vi mostriamo come usare la funzione `resume` per quando dovete ri-avviare lo stesso workflow, come ispezionare il log delle esecuzioni passate con `nextflow log`, e come eliminare le directory work più vecchie con `nextflow clean`. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. Ri-avviare un workflow con `-resume` + +A volte vorrà ri-eseguire una pipeline che ha già avviato in precedenza senza rifare alcuno step che è già stato completato con successo. + +Nextflow ha un'opzione chiamata `-resume` che vi permette di fare questo. +Specificamente, in questa modalità, tutti i processi che sono già stati eseguiti con lo stesso identico codice, impostazioni e input verranno saltati. +Questo significa che Nextflow eseguirà solo i processi che ha aggiunto o modificato dalla precedente esecuzione, o a cui sta fornendo nuove impostazioni o input. + +Ci sono due vantaggi chiave nel fare questo: + +- Se state sviluppando la vostra pipeline, potete iterare più rapidamente poiché dovete solo eseguire il/i process su cui state lavorando attivamente per testare le vostre modifiche. +- Se state eseguendo una pipeline in produzione e qualcosa va storto, in molti casi potete risolvere il problema e ri-avviare la pipeline, e riprenderà dal punto di fallimento, il che può farvi risparmiare molto tempo e calcolo. + +Per usarlo, aggiungete semplicemente `-resume` al vostro comando ed eseguite: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Output del comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +L'output della console dovrebbe sembrare familiare, ma c'è una cosa leggermente diversa rispetto a prima. + +Cercate la parte `cached:` che è stata aggiunta nella riga di stato del process (riga 5), che significa che Nextflow ha riconosciuto che ha già fatto questo lavoro e ha semplicemente riutilizzato il risultato dall'esecuzione precedente riuscita. + +Potete anche vedere che l'hash della sottodirectory work è lo stesso dell'esecuzione precedente. +Nextflow vi sta letteralmente indicando l'esecuzione precedente e dicendo "Ho già fatto quello lì." + +!!! tip "Suggerimento" + + Quando ri-esegue una pipeline con `resume`, Nextflow non sovrascrive alcun file pubblicato fuori dalla directory work da esecuzioni che sono state eseguite con successo in precedenza. + +### 4.2. Ispezionare il log delle esecuzioni passate + +Che stiate sviluppando una nuova pipeline o eseguendo pipeline in produzione, a un certo punto avrete probabilmente bisogno di cercare informazioni sulle esecuzioni passate. +Ecco come fare. + +Ogni volta che avvia un workflow nextflow, una riga viene scritta in un file di log chiamato `history`, sotto una directory nascosta chiamata `.nextflow` nella directory di lavoro corrente. + +??? abstract "Contenuti del file" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Questo file fornisce il timestamp, il nome dell'esecuzione, lo stato, l'ID di revisione, l'ID di sessione e la riga di comando completa per ogni esecuzione Nextflow che è stata avviata dalla directory di lavoro corrente. + +Un modo più conveniente per accedere a queste informazioni è usare il comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Output del comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Questo produrrà i contenuti del file di log nel terminale, arricchiti con una riga di intestazione. + +Noterete che l'ID di sessione cambia ogni volta che eseguite un nuovo comando `nextflow run`, ECCETTO se state usando l'opzione `-resume`. +In quel caso, l'ID di sessione rimane lo stesso. + +Nextflow usa l'ID di sessione per raggruppare le informazioni di cache dell'esecuzione nella directory `cache`, anch'essa situata sotto `.nextflow`. + +### 4.3. Eliminare le directory work più vecchie + +Durante il processo di sviluppo, tipicamente eseguirete la vostra bozza di pipeline un gran numero di volte, il che può portare a un accumulo di molti file in molte sottodirectory. + +Fortunatamente Nextflow include un utile sottocomando `clean` che potete eliminare automaticamente le sottodirectory work per le esecuzioni passate che non Le interessano più. + +#### 4.3.1. Determinare i criteri di eliminazione + +Ci sono multiple [opzioni](https://www.nextflow.io/docs/latest/reference/cli.html#clean) per determinare cosa eliminare. + +Qui vi mostriamo un esempio che elimina tutte le sottodirectory dalle esecuzioni precedenti a una data esecuzione, specificata usando il suo nome di esecuzione. + +Cercate l'esecuzione riuscita più recente dove non avete usato `-resume`; nel nostro caso il nome dell'esecuzione era `golden_cantor`. + +Il nome dell'esecuzione è la stringa in due parti generata dalla macchina mostrata tra parentesi quadre nell'output della console `Launching (...)`. +Potete anche usare il log di Nextflow per cercare un'esecuzione in base al suo timestamp e/o riga di comando. + +#### 4.3.2. Fare una prova a secco + +Prima usiamo il flag di prova a secco `-n` per verificare cosa verrà eliminato dato il comando: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Output del comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Il vostro output avrà nomi di directory di attività diversi e potrebbe avere un numero diverso di righe, ma dovrebbe sembrare simile all'esempio. + +Se non vedete alcuna riga di output, o non avete fornito un nome di esecuzione valido o non ci sono esecuzioni passate da eliminare. Assicuratevi di cambiare `golden_cantor` nel comando di esempio con qualunque sia il nome dell'esecuzione più recente corrispondente nel vostro log. + +#### 4.3.3. Procedere con l'eliminazione + +Se l'output sembra come previsto e volete procedere con l'eliminazione, ri-eseguite il comando con il flag `-f` invece di `-n`: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Output del comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +L'output dovrebbe essere simile a prima, ma ora dicendo 'Removed' invece di 'Would remove'. +Noti che questo non rimuove le sottodirectory a due caratteri (come `a3/` sopra) ma ne svuota il contenuto. + +!!! Warning "Avviso" + + Eliminare le sottodirectory work dalle esecuzioni passate le rimuove dalla cache di Nextflow e cancella tutti gli output che erano memorizzati in quelle directory. + Questo significa che interrompe la capacità di Nextflow di riprendere l'esecuzione senza ri-eseguire i processi corrispondenti. + + È vostra responsabilità salvare tutti gli output che vi interessano o su cui contate! Questo è il motivo principale per cui preferiamo usare la modalità `copy` piuttosto che la modalità `symlink` per la direttiva `publish`. + +### Takeaway + +Sapete come pubblicare output in una directory specifica, ri-avviare una pipeline senza ripetere step che erano già stati eseguiti in modo identico, e usare il comando `nextflow clean` per pulire le directory work vecchie. + +Più in generale, sapete come interpretare un semplice workflow Nextflow, gestire la sua esecuzione e recuperare gli output. + +### Cosa c'è dopo? + +Prendetevi una piccola pausa, ve la siete meritata! + +Quando siete pronti, passate alla [**Parte 2: Hello Channels**](./02_hello_channels.md) per imparare come usare i channel per alimentare gli input nel vostro workflow, il che vi permetterà di sfruttare il parallelismo del flusso dati integrato di Nextflow e altre potenti funzionalità. + +--- + +## Quiz + +<quiz> +Quali sono i componenti minimi richiesti di un process Nextflow? +- [ ] Solo blocchi input e output +- [x] Blocchi output e script +- [ ] Blocchi input, output e script +- [ ] Solo un blocco script + +Approfondisci: [1.1.1. La definizione del process](#111-la-definizione-del-process) +</quiz> + +<quiz> +Qual è lo scopo del blocco output in un process? +- [ ] Stampare i risultati sulla console +- [ ] Salvare i file nella directory work +- [x] Dichiarare gli output attesi dal process +- [ ] Definire variabili d'ambiente + +Approfondisci: [1.1.1. La definizione del process](#111-la-definizione-del-process) +</quiz> + +<quiz> +Quale comando viene usato per eseguire un workflow Nextflow? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Guardando la directory work di un'attività, quale file contiene il comando effettivo che è stato eseguito? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Approfondisci: [1.2.2. Trovare l'output e i log nella directory `work`](#122-trovare-loutput-e-i-log-nella-directory-work) +</quiz> + +<quiz> +Cosa fa il flag `-resume`? +- [ ] Riavvia il workflow dall'inizio +- [ ] Mette in pausa il workflow +- [x] Salta i processi che sono già stati completati con successo +- [ ] Crea un backup del workflow + +Approfondisci: [4.1. Ri-avviare un workflow con `-resume`](#41-ri-avviare-un-workflow-con--resume) +</quiz> + +<quiz> +Qual è la modalità predefinita per pubblicare gli output del workflow? +- [ ] Copiare i file nella directory di output +- [x] Creare link simbolici nella directory di output +- [ ] Spostare i file nella directory di output +- [ ] Comprimere i file nella directory di output + +Approfondisci: [2.3. Impostare la modalità di pubblicazione su copy](#23-impostare-la-modalità-di-pubblicazione-su-copy) +</quiz> + +<quiz> +Come si passa un valore di parametro a un workflow Nextflow dalla riga di comando? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +Approfondisci: [3.2. Impostare un parametro da riga di comando per catturare l'input dell'utente](#32-impostare-un-parametro-da-riga-di-comando-per-catturare-linput-dellutente) +</quiz> + +<quiz> +Come si fa riferimento a una variabile all'interno di un blocco script Nextflow? +- [ ] Usare la sintassi `%variable%` +- [x] Usare la sintassi `#!groovy ${variable}` +- [ ] Usare la sintassi `{{variable}}` +- [ ] Usare la sintassi `[variable]` +</quiz> diff --git a/docs/it/docs/hello_nextflow/02_hello_channels.md b/docs/it/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..64e60cd50c --- /dev/null +++ b/docs/it/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Parte 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/02_hello_channels.md). +/// + +Nella Parte 1 di questo corso (Hello World), vi abbiamo mostrato come fornire un input variabile a un processo passandolo direttamente nella chiamata al processo: `sayHello(params.input)`. +Quello era un approccio volutamente semplificato. +In pratica, quell'approccio ha limitazioni importanti; in particolare, funziona solo per casi molto semplici in cui vogliamo eseguire il processo una sola volta, su un singolo valore. +Nella maggior parte dei casi d'uso realistici dei workflow, vogliamo elaborare più valori (dati sperimentali per più campioni, per esempio), quindi abbiamo bisogno di un modo più sofisticato per gestire gli input. + +Ecco a cosa servono i **channel** di Nextflow. +I channel sono code progettate per gestire gli input in modo efficiente e trasferirli da un passaggio all'altro nei workflow multi-step, fornendo al contempo parallelismo integrato e molti altri vantaggi. + +In questa parte del corso, imparerete come utilizzare un channel per gestire più input da diverse fonti. +Imparerete anche a utilizzare gli **operatori** per trasformare i contenuti dei channel secondo necessità. + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che abbiate completato la Parte 1 del corso [Hello Nextflow](./index.md), ma se avete familiarità con i concetti base trattati in quella sezione, potete iniziare da qui senza fare nulla di speciale. + +--- + +## 0. Riscaldamento: Eseguire `hello-channels.nf` + +Useremo lo script del workflow `hello-channels.nf` come punto di partenza. +È equivalente allo script prodotto seguendo la Parte 1 di questo corso di formazione, tranne che abbiamo cambiato la destinazione dell'output: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Solo per assicurarci che tutto funzioni, eseguite lo script una volta prima di apportare modifiche: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Come in precedenza, troverete il file di output chiamato `output.txt` nella directory `results/hello_channels` (come specificato nel blocco `output` dello script del workflow, mostrato sopra). + +??? abstract "Contenuti della directory" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenuti del file" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Se tutto ha funzionato, siete pronti a imparare i channel. + +--- + +## 1. Fornire input variabili tramite un channel esplicitamente + +Creeremo un **channel** per passare l'input variabile al processo `sayHello()` invece di affidarci alla gestione implicita, che ha alcune limitazioni. + +### 1.1. Creare un channel di input + +Esistono diverse **channel factory** che possiamo usare per configurare un channel. +Per mantenere le cose semplici per ora, useremo la channel factory più basilare, chiamata `channel.of`, che creerà un channel contenente un singolo valore. +Funzionalmente sarà simile a come lo avevamo configurato prima, ma invece di far creare a Nextflow un channel implicitamente, ora lo stiamo facendo esplicitamente. + +Questa è la riga di codice che useremo: + +```console title="Syntax" +greeting_ch = channel.of('Hello Channels!') +``` + +Questo crea un channel chiamato `greeting_ch` usando la channel factory `channel.of()`, che configura un semplice queue channel, e carica la stringa `'Hello Channels!'` da usare come valore di saluto. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Nota" + + Stiamo temporaneamente tornando alle stringhe hardcoded invece di usare un parametro CLI per motivi di leggibilità. Torneremo a usare i parametri CLI una volta che avremo spiegato cosa succede a livello di channel. + +Nel blocco workflow, aggiungete il codice della channel factory: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels!') + // emette un saluto + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // emette un saluto + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Questo non è ancora funzionale poiché non abbiamo ancora cambiato l'input nella chiamata al processo. + +### 1.2. Aggiungere il channel come input alla chiamata del processo + +Ora dobbiamo effettivamente collegare il nostro channel appena creato alla chiamata del processo `sayHello()`, sostituendo il parametro CLI che fornivamo direttamente prima. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels!') + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels!') + // emette un saluto + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Questo dice a Nextflow di eseguire il processo `sayHello` sui contenuti del channel `greeting_ch`. + +Ora il nostro workflow è correttamente funzionale; è l'equivalente esplicito di scrivere `sayHello('Hello Channels!')`. + +### 1.3. Eseguire il workflow + +Eseguiamolo! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Se avete effettuato entrambe le modifiche correttamente, dovreste ottenere un'esecuzione riuscita. +Potete controllare la directory dei risultati per verificare che l'output sia ancora lo stesso di prima. + +??? abstract "Contenuti del file" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Quindi abbiamo aumentato la flessibilità del nostro workflow ottenendo lo stesso risultato finale. +Questo può sembrare scrivere più codice senza un beneficio tangibile, ma il valore diventerà chiaro non appena inizieremo a gestire più input. + +Come anteprima, vediamo un'altra cosa prima di procedere: un piccolo ma conveniente vantaggio dell'uso di un channel esplicito per gestire l'input dei dati. + +### 1.4. Usare `view()` per ispezionare i contenuti del channel + +I channel di Nextflow sono costruiti in modo da permetterci di operare sui loro contenuti usando operatori, che tratteremo in dettaglio più avanti in questo capitolo. + +Per ora, vi mostreremo semplicemente come usare un operatore super semplice chiamato [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) per ispezionare i contenuti di un channel. +Potete pensare a `view()` come uno strumento di debug, come un'istruzione `print()` in Python, o il suo equivalente in altri linguaggi. + +Aggiungete questa piccola riga al blocco workflow: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels!') + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels!') + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +La quantità esatta di spazi non importa purché sia un multiplo di 4; stiamo solo cercando di allineare l'inizio dell'istruzione `.view()` alla parte `.of()` della costruzione del channel. + +Ora eseguite di nuovo il workflow: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Come potete vedere, questo mostra i contenuti del channel sulla console. +Qui abbiamo solo un elemento, ma quando inizieremo a caricare più valori nel channel nella prossima sezione, vedrete che questo è impostato per mostrare un elemento per riga. + +### Takeaway + +Sapete come usare una channel factory di base per fornire un input a un processo. + +### Cosa c'è dopo? + +Imparate come usare i channel per far iterare il workflow su più valori di input. + +--- + +## 2. Modificare il workflow per eseguire su più valori di input + +I workflow tipicamente vengono eseguiti su lotti di input che devono essere elaborati in blocco, quindi vogliamo aggiornare il workflow per accettare più valori di input. + +### 2.1. Caricare più saluti nel channel di input + +Convenientemente, la channel factory `channel.of()` che abbiamo usato è perfettamente in grado di accettare più di un valore, quindi non abbiamo bisogno di modificarla affatto. +Possiamo semplicemente caricare più valori nel channel. + +Usiamo `'Hello'`, `'Bonjour'` e `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Nel diagramma, il channel è rappresentato in verde, e l'ordine degli elementi è rappresentato come biglie in un tubo: il primo caricato è a destra, poi il secondo al centro, poi il terzo è a sinistra._ + +#### 2.1.1. Aggiungere più saluti + +Prima del blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // crea un canale per gli input + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // crea un canale per gli input + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +La documentazione ci dice che questo dovrebbe funzionare. Può davvero essere così semplice? + +#### 2.1.2. Eseguire il comando e guardare l'output del log + +Proviamo. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Sembra certamente che abbia funzionato correttamente. +Il monitor di esecuzione mostra che sono state effettuate `3 of 3` chiamate per il processo `sayHello`, e vediamo i tre saluti elencati dall'istruzione `view()`, uno per riga come promesso. + +Tuttavia, c'è ancora un solo output nella directory dei risultati: + +??? abstract "Contenuti della directory" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Contenuti del file" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Dovreste vedere uno dei tre saluti lì dentro, ma quello che avete ottenuto potrebbe essere diverso da quello mostrato qui. +Riuscite a pensare al motivo? + +Guardando indietro al monitor di esecuzione, ci ha dato solo un percorso di sottodirectory (`f4/c9962c`). +Diamo un'occhiata lì dentro. + +??? abstract "Contenuti della directory" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenuti del file" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +Questo non è nemmeno lo stesso saluto che abbiamo ottenuto nella directory dei risultati! Cosa sta succedendo? + +A questo punto, dobbiamo dirvi che per impostazione predefinita, il sistema di logging ANSI scrive il logging di più chiamate allo stesso processo sulla stessa riga. +Quindi lo stato di tutte e tre le chiamate al processo sayHello() finiscono nello stesso punto. + +Fortunatamente, possiamo disabilitare quel comportamento per vedere l'elenco completo delle chiamate ai processi. + +#### 2.1.3. Eseguire di nuovo il comando con l'opzione `-ansi-log false` + +Per espandere il logging e visualizzare una riga per chiamata di processo, aggiungete `-ansi-log false` al comando. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Questa volta vediamo tutte e tre le esecuzioni dei processi e le loro sottodirectory di lavoro associate elencate nell'output. + +Molto meglio, almeno per un workflow semplice. +Per un workflow complesso, o un grande numero di input, avere l'elenco completo in output sul terminale diventerebbe un po' opprimente. +Ecco perché `-ansi-log false` non è il comportamento predefinito. + +!!! tip "Suggerimento" + + Il modo in cui viene riportato lo stato è un po' diverso tra le due modalità di logging. + Nella modalità condensata, Nextflow riporta se le chiamate sono state completate con successo o meno. + In questa modalità espansa, riporta solo che sono state inviate. + +Comunque, ora che abbiamo le sottodirectory di ogni chiamata di processo, possiamo cercare i loro log e output. + +??? abstract "Contenuti della directory" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Contenuti del file" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Questo mostra che tutti e tre i processi sono stati eseguiti con successo (evviva). + +Detto questo, abbiamo ancora il problema che c'è un solo file di output nella directory dei risultati. + +Potete ricordare che abbiamo hardcodato il nome del file di output per il processo `sayHello`, quindi tutte e tre le chiamate hanno prodotto un file chiamato `output.txt`. + +Finché i file di output rimangono nelle sottodirectory di lavoro, isolati dagli altri processi, va bene. +Ma quando vengono pubblicati nella stessa directory dei risultati, quello che viene copiato per primo viene sovrascritto dal successivo, e così via. + +### 2.2. Assicurarsi che i nomi dei file di output siano unici + +Possiamo continuare a pubblicare tutti gli output nella stessa directory dei risultati, ma dobbiamo assicurarci che abbiano nomi unici. +Nello specifico, dobbiamo modificare il primo processo per generare un nome di file dinamicamente in modo che i nomi dei file finali siano unici. + +Quindi come rendiamo i nomi dei file unici? +Un modo comune per farlo è usare qualche pezzo unico di metadati dagli input (ricevuti dal channel di input) come parte del nome del file di output. +Qui, per comodità, useremo semplicemente il saluto stesso poiché è solo una stringa corta, e lo anteporremo al nome base del file di output. + +#### 2.2.1. Costruire un nome di file di output dinamico + +Nel blocco process, effettuate le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Assicuratevi di sostituire `output.txt` sia nella definizione dell'output che nel blocco del comando `script:`. + +!!! tip "Suggerimento" + + Nella definizione dell'output, DEVE usare le virgolette doppie attorno all'espressione del nome del file (NON le virgolette singole), altrimenti fallirà. + +Questo dovrebbe produrre un nome di file di output unico ogni volta che il processo viene chiamato, in modo che possa essere distinto dagli output di altre chiamate allo stesso processo nella directory di output. + +#### 2.2.2. Eseguire il workflow + +Eseguiamolo. Nota che siamo tornati a eseguire con le impostazioni predefinite del log ANSI. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Tornando alla vista riassuntiva, l'output è di nuovo riassunto su una riga. +Date un'occhiata alla directory `results` per vedere se tutti i saluti di output sono presenti. + +??? abstract "Contenuti della directory" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Sì! E ognuno ha i contenuti attesi. + +??? abstract "Contenuti del file" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Successo! Ora possiamo aggiungere quanti saluti vogliamo senza preoccuparci che i file di output vengano sovrascritti. + +!!! tip "Suggerimento" + + In pratica, nominare i file basandosi sui dati di input stessi è quasi sempre poco pratico. + Il modo migliore per generare nomi di file dinamici è passare metadati a un processo insieme ai file di input. + I metadati sono tipicamente forniti tramite un 'sample sheet' o equivalenti. + Imparerete come farlo più avanti nella vostra formazione su Nextflow (vedete la [side quest sui metadati](../side_quests/metadata.md)). + +### Takeaway + +Sapete come fornire più elementi di input attraverso un channel. + +### Cosa c'è dopo? + +Imparate a usare un operatore per trasformare i contenuti di un channel. + +--- + +## 3. Fornire più input tramite un array + +Vi abbiamo appena mostrato come gestire più elementi di input che erano hardcodati direttamente nella channel factory. +E se volessimo fornire questi input multipli in modo diverso? + +Per esempio, immaginate di configurare una variabile di input contenente un array di elementi come questo: + +`greetings_array = ['Hello','Bonjour','Holà']` + +Possiamo caricarla nel nostro channel di output e aspettarci che funzioni? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Scopriamolo. + +### 3.1. Fornire un array di valori come input al channel + +Il buon senso suggerisce che dovremmo essere in grado di passare semplicemente un array di valori invece di un singolo valore. +Proviamo; dovremo configurare la variabile di input e caricarla nella channel factory. + +#### 3.1.1. Configurare la variabile di input + +Prendiamo la variabile `greetings_array` che abbiamo appena immaginato e rendiamola realtà aggiungendola al blocco workflow: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crea un canale per gli input + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Questo non è ancora funzionale, abbiamo solo aggiunto una dichiarazione per l'array. + +#### 3.1.2. Impostare l'array di saluti come input alla channel factory + +Ora sostituiremo i valori `'Hello','Bonjour','Holà'` attualmente hardcodati nella channel factory con il `greetings_array` che abbiamo appena creato. + +Nel blocco workflow, effettuate la seguente modifica: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Questo dovrebbe essere funzionale ora. + +#### 3.1.3. Eseguire il workflow + +Proviamo a eseguirlo: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Output del comando" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +Oh no! C'è un errore! + +Guardate l'output di `view()` e i messaggi di errore. + +Sembra che Nextflow abbia provato a eseguire una singola chiamata di processo, usando `[Hello, Bonjour, Holà]` come valore stringa, invece di usare le tre stringhe nell'array come valori separati. + +Quindi è il 'confezionamento' che sta causando il problema. +Come facciamo a far sì che Nextflow spacchetti l'array e carichi le singole stringhe nel channel? + +### 3.2. Usare un operatore per trasformare i contenuti del channel + +Qui entrano in gioco gli **[operatori](https://www.nextflow.io/docs/latest/reference/operator.html)**. +Avete già usato l'operatore `.view()`, che semplicemente guarda cosa c'è dentro. +Ora vedremo operatori che ci permettono di agire sui contenuti di un channel. + +Se scorrete la [lista degli operatori](https://www.nextflow.io/docs/latest/reference/operator.html) nella documentazione di Nextflow, troverete [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), che fa esattamente ciò di cui abbiamo bisogno: spacchetta i contenuti di un array e li emette come elementi individuali. + +#### 3.2.1. Aggiungere l'operatore `flatten()` + +Per applicare l'operatore `flatten()` al nostro channel di input, lo aggiungiamo alla dichiarazione della channel factory. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Qui abbiamo aggiunto l'operatore sulla riga successiva per leggibilità, ma potete aggiungere operatori sulla stessa riga della channel factory se preferite, così: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Affinare le istruzioni `view()` + +Potremmo eseguirlo subito per testare se funziona, ma già che ci siamo, affineremo come ispezioniamo i contenuti del channel. + +Vogliamo poter confrontare come appaiono i contenuti prima e dopo l'applicazione dell'operatore `flatten()`, quindi ne aggiungeremo un secondo, E aggiungeremo un po' di codice per etichettarli più chiaramente nell'output. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Vedete che abbiamo aggiunto una seconda istruzione `.view`, e per ciascuna di esse, abbiamo sostituito le parentesi vuote (`()`) con parentesi graffe contenenti del codice, come `{ greeting -> "Before flatten: $greeting" }`. + +Queste si chiamano _closure_. Il codice che contengono verrà eseguito per ogni elemento nel channel. +Definiamo una variabile temporanea per il valore interno, qui chiamata `greeting` (ma potrebbe essere qualsiasi nome arbitrario), che viene usata solo nell'ambito di quella closure. + +In questo esempio, `$greeting` rappresenta ogni singolo elemento caricato nel channel. +Questo risulterà in un output della console ordinatamente etichettato. + +!!! info "Informazione" + + In alcune pipeline potrete vedere una variabile speciale chiamata `$it` usata all'interno delle closure degli operatori. + Questa è una variabile _implicita_ che permette un accesso abbreviato alla variabile interna, + senza doverla definire con un `->`. + + Preferiamo essere espliciti per aiutare la chiarezza del codice, quindi la sintassi `$it` è sconsigliata e sarà gradualmente eliminata dal linguaggio Nextflow. + +#### 3.2.3. Eseguire il workflow + +Finalmente, potete provare a eseguire di nuovo il workflow! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Questa volta funziona E ci dà la comprensione aggiuntiva di come appaiono i contenuti del channel prima e dopo l'esecuzione dell'operatore `flatten()`. + +- Vedete che otteniamo una singola istruzione `Before flatten:` perché a quel punto il channel contiene un elemento, l'array originale. + Poi otteniamo tre istruzioni separate `After flatten:`, una per ogni saluto, che ora sono elementi individuali nel channel. + +Importante, questo significa che ogni elemento può ora essere elaborato separatamente dal workflow. + +!!! tip "Suggerimento" + + È tecnicamente possibile ottenere gli stessi risultati usando una channel factory diversa, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), che include un passo di mapping implicito nella sua operazione. + Qui abbiamo scelto di non usarla per dimostrare l'uso di un operatore su un caso d'uso semplice. + +### Takeaway + +Sapete come usare un operatore come `flatten()` per trasformare i contenuti di un channel, e come usare l'operatore `view()` per ispezionare i contenuti del channel prima e dopo l'applicazione di un operatore. + +### Cosa c'è dopo? + +Imparate come far prendere al workflow un file come fonte di valori di input. + +--- + +## 4. Leggere i valori di input da un file CSV + +Realisticamente, raramente o mai partiremo da un array di valori. +Molto probabilmente, avremo uno o più file contenenti i dati che devono essere elaborati, in qualche tipo di formato strutturato. + +Abbiamo preparato un file CSV chiamato `greetings.csv` che contiene diversi saluti di input, imitando il tipo di dati colonnari che potreste voler elaborare in un'analisi dati reale, memorizzato sotto `data/`. +(I numeri non sono significativi, sono lì solo a scopo illustrativo.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Il nostro prossimo compito è adattare il nostro workflow per leggere i valori da questo file. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Vediamo come possiamo realizzarlo. + +### 4.1. Modificare lo script per aspettarsi un file CSV come fonte di saluti + +Per iniziare, dovremo apportare due modifiche chiave allo script: + +- Cambiare il parametro di input per puntare al file CSV +- Cambiare la channel factory con una progettata per gestire un file + +#### 4.1.1. Cambiare il parametro di input per puntare al file CSV + +Ricordate il parametro `params.input` che abbiamo configurato nella Parte 1? +Lo aggiorneremo per puntare al file CSV contenente i nostri saluti. + +Effettuate la seguente modifica alla dichiarazione del parametro: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + input: String = 'Holà mundo!' + ``` + +Questo presuppone che il file sia nella stessa posizione del codice del workflow. +Imparerete come gestire altre posizioni dei dati più avanti nel vostro percorso con Nextflow. + +#### 4.1.2. Passare a una channel factory progettata per gestire un file + +Poiché ora vogliamo usare un file invece di semplici stringhe come input, non possiamo usare la channel factory `channel.of()` di prima. +Dobbiamo passare a usare una nuova channel factory, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), che ha alcune funzionalità integrate per gestire i percorsi dei file. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // crea un canale per gli input from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // dichiara un array di saluti di input + greetings_array = ['Hello','Bonjour','Holà'] + // crea un canale per gli input + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Noterete che abbiamo riportato l'input del channel a `param.input`, e cancellato la dichiarazione `greetings_array` poiché non ne avremo più bisogno. +Abbiamo anche commentato `flatten()` e la seconda istruzione `view()`. + +#### 4.1.3. Eseguire il workflow + +Proviamo a eseguire il workflow con la nuova channel factory e il file di input. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Output del comando" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Oh no, non funziona. Date un'occhiata all'inizio dell'output della console e al messaggio di errore. +La parte `Command executed:` è particolarmente utile qui. + +Questo potrebbe sembrare un po' familiare. +Sembra che Nextflow abbia provato a eseguire una singola chiamata di processo usando il percorso del file stesso come valore stringa. +Quindi ha risolto correttamente il percorso del file, ma non ha effettivamente analizzato i suoi contenuti, che è quello che volevamo. + +Come facciamo a far sì che Nextflow apra il file e carichi i suoi contenuti nel channel? + +Sembra che abbiamo bisogno di un altro [operatore](https://www.nextflow.io/docs/latest/reference/operator.html)! + +### 4.2. Usare l'operatore `splitCsv()` per analizzare il file + +Guardando di nuovo la lista degli operatori, troviamo [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), che è progettato per analizzare e dividere testo formattato CSV. + +#### 4.2.1. Applicare `splitCsv()` al channel + +Per applicare l'operatore, lo aggiungiamo alla riga della channel factory come fatto in precedenza. + +Nel blocco workflow, effettuate la seguente modifica al codice per sostituire `flatten()` con `splitcsv()` (senza commento): + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // crea un canale per gli input from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // crea un canale per gli input from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Come potete vedere, abbiamo anche aggiornato le istruzioni `view()` prima/dopo. +Tecnicamente avremmo potuto usare lo stesso nome di variabile (`greeting`) ma l'abbiamo aggiornato a qualcosa di più appropriato (`csv`) per rendere il codice più leggibile agli altri. + +#### 4.2.2. Eseguire di nuovo il workflow + +Proviamo a eseguire il workflow con la logica di parsing CSV aggiunta. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Output del comando" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Interessante, fallisce anche questo, ma con un errore diverso. +Questa volta Nextflow ha analizzato i contenuti del file (evviva!) ma ha caricato ogni riga come un array, e ogni array è un elemento nel channel. + +Dobbiamo dirgli di prendere solo la prima colonna di ogni riga. +Quindi come spacchettamo questo? + +Abbiamo usato precedentemente `flatten()` per spacchettare i contenuti di un channel, ma non funzionerebbe qui perché flatten spacchetta _tutto_ (potete provarlo se volete vedere di persona). + +Invece, useremo un altro operatore chiamato `map()` che è davvero utile e compare spesso nelle pipeline Nextflow. + +### 4.3. Usare l'operatore `map()` per estrarre i saluti + +L'operatore [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) è un piccolo strumento molto utile che ci permette di fare ogni tipo di mappatura sui contenuti di un channel. + +In questo caso, lo useremo per estrarre quell'unico elemento che vogliamo da ogni riga nel nostro file di dati. +Ecco come appare la sintassi: + +```groovy title="Syntax" +.map { row -> row[0] } +``` + +Questo significa 'per ogni riga nel channel, prendi l'elemento 0 (primo) che contiene'. + +Quindi applichiamolo al nostro parsing CSV. + +#### 4.3.1. Applicare `map()` al channel + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // crea un canale per gli input from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // crea un canale per gli input from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Vedete che abbiamo aggiunto un'altra chiamata `view()` per confermare che l'operatore fa quello che ci aspettiamo. + +#### 4.3.2. Eseguire il workflow + +Eseguiamolo ancora una volta: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Questa volta dovrebbe funzionare senza errori. + +Guardando l'output delle istruzioni `view()`, vedete il seguente: + +- Una singola istruzione `Before splitCsv:`: a quel punto il channel contiene un elemento, il percorso del file originale. +- Tre istruzioni separate `After splitCsv:`: una per ogni saluto, ma ciascuna è contenuta in un array che corrisponde a quella riga nel file. +- Tre istruzioni separate `After map:`: una per ogni saluto, che ora sono elementi individuali nel channel. + +Nota che le righe potrebbero apparire in un ordine diverso nel vostro output. + +Potete anche guardare i file di output per verificare che ogni saluto sia stato correttamente estratto ed elaborato attraverso il workflow. + +Abbiamo ottenuto lo stesso risultato di prima, ma ora abbiamo molta più flessibilità per aggiungere più elementi al channel di saluti che vogliamo elaborare modificando un file di input, senza modificare alcun codice. +Imparerete approcci più sofisticati per gestire input complessi in una formazione successiva. + +### Takeaway + +Sapete come usare il costruttore di channel `.fromPath()` e gli operatori `splitCsv()` e `map()` per leggere un file di valori di input e gestirli appropriatamente. + +Più in generale, avete una comprensione di base di come Nextflow usa i **channel** per gestire gli input ai processi e gli **operatori** per trasformare i loro contenuti. + +### Cosa c'è dopo? + +Prendetevi una bella pausa, avete lavorato duramente in questa sezione! + +Quando siete pronti, passate alla [**Parte 3: Hello Workflow**](./03_hello_workflow.md) per imparare come aggiungere più passaggi e connetterli insieme in un workflow vero e proprio. + +--- + +## Quiz + +<quiz> +Cos'è un channel in Nextflow? +- [ ] Una specifica di percorso file +- [ ] Una definizione di processo +- [x] Una struttura simile a una coda per passare dati tra processi +- [ ] Un'impostazione di configurazione + +Per approfondire: [1.1. Creare un channel di input](#11-creare-un-channel-di-input) +</quiz> + +<quiz> +Cosa produrrà questo codice? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (una singola lista) +- [x] Ogni elemento su una riga separata: `Hello`, `Bonjour`, `Hola` +- [ ] Niente (i channel non stampano per impostazione predefinita) +- [ ] Un errore (sintassi non valida) + +Per approfondire: [1.1. Creare un channel di input](#11-creare-un-channel-di-input) +</quiz> + +<quiz> +Quando un channel contiene più valori, come gestisce Nextflow l'esecuzione del processo? +- [ ] Il processo viene eseguito una volta con tutti i valori +- [x] Il processo viene eseguito una volta per ogni valore nel channel +- [ ] Il processo viene eseguito solo con il primo valore +- [ ] Il processo viene eseguito solo con l'ultimo valore + +Per approfondire: [2. Modificare il workflow per eseguire su più valori di input](#2-modificare-il-workflow-per-eseguire-su-piu-valori-di-input) +</quiz> + +<quiz> +Cosa fa l'operatore `flatten()`? +- [ ] Combina più channel in uno +- [ ] Ordina gli elementi del channel +- [x] Spacchetta gli array in elementi individuali +- [ ] Rimuove gli elementi duplicati + +Per approfondire: [3.2.1. Aggiungere l'operatore `flatten()`](#321-aggiungere-loperatore-flatten) +</quiz> + +<quiz> +Qual è lo scopo dell'operatore `view()`? +- [ ] Filtrare i contenuti del channel +- [ ] Trasformare gli elementi del channel +- [x] Ispezionare e fare debug dei contenuti del channel +- [ ] Salvare i contenuti del channel in un file + +Per approfondire: [1.4. Usare `view()` per ispezionare i contenuti del channel](#14-usare-view-per-ispezionare-i-contenuti-del-channel) +</quiz> + +<quiz> +Cosa fa `splitCsv()`? +- [ ] Crea un file CSV dai contenuti del channel +- [ ] Divide una stringa per virgole +- [x] Analizza un file CSV in array che rappresentano ogni riga +- [ ] Unisce più file CSV + +Per approfondire: [4.2. Usare l'operatore `splitCsv()` per analizzare il file](#42-usare-loperatore-splitcsv-per-analizzare-il-file) +</quiz> + +<quiz> +Qual è lo scopo dell'operatore `map()`? +- [ ] Filtrare elementi da un channel +- [ ] Combinare più channel +- [x] Trasformare ogni elemento in un channel +- [ ] Contare gli elementi in un channel + +Per approfondire: [4.3. Usare l'operatore `map()` per estrarre i saluti](#43-usare-loperatore-map-per-estrarre-i-saluti) +</quiz> + +<quiz> +Perché è importante usare nomi di file di output dinamici quando si elaborano più input? +- [ ] Per migliorare le prestazioni +- [ ] Per ridurre lo spazio su disco +- [x] Per evitare che i file di output si sovrascrivano a vicenda +- [ ] Per abilitare la funzionalità di resume + +Per approfondire: [2.2. Assicurarsi che i nomi dei file di output siano unici](#22-assicurarsi-che-i-nomi-dei-file-di-output-siano-unici) +</quiz> diff --git a/docs/it/docs/hello_nextflow/03_hello_workflow.md b/docs/it/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..f9b53141c1 --- /dev/null +++ b/docs/it/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Parte 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/03_hello_workflow.md). +/// + +La maggior parte dei workflow reali coinvolgono più di un passaggio. +In questo modulo di formazione, imparerete come connettere i processi insieme in un workflow multi-step. + +Questo vi insegnerà il modo Nextflow per ottenere quanto segue: + +1. Far fluire i dati da un processo al successivo +2. Raccogliere gli output da più chiamate di processo in una singola chiamata di processo +3. Passare più di un input a un processo +4. Gestire output multipli provenienti da un processo + +Per dimostrare, continueremo a costruire sull'esempio Hello World indipendente dal dominio delle Parti 1 e 2. +Questa volta, apporteremo le seguenti modifiche al nostro workflow per riflettere meglio come le persone costruiscono workflow reali: + +1. Aggiungere un secondo passaggio che converte il saluto in maiuscolo. +2. Aggiungere un terzo passaggio che raccoglie tutti i saluti trasformati e li scrive in un singolo file. +3. Aggiungere un parametro per nominare il file di output finale e passarlo come input secondario al passaggio di raccolta. +4. Far sì che il passaggio di raccolta riporti anche una semplice statistica su ciò che è stato elaborato. + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che abbiate completato le Parti 1-2 del corso [Hello Nextflow](./index.md), ma se avete familiarità con i concetti base trattati in quelle sezioni, potete iniziare da qui senza fare nulla di speciale. + +--- + +## 0. Riscaldamento: Eseguire `hello-workflow.nf` + +Useremo lo script del workflow `hello-workflow.nf` come punto di partenza. +È equivalente allo script prodotto seguendo la Parte 2 di questo corso di formazione, tranne che abbiamo rimosso le istruzioni `view()` e cambiato la destinazione dell'output: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Solo per assicurarci che tutto funzioni, eseguite lo script una volta prima di apportare modifiche: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Come in precedenza, troverete i file di output nella posizione specificata nel blocco `output`. +Per questo capitolo, è sotto `results/hello_workflow/`. + +??? abstract "Contenuti della directory" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Se tutto ha funzionato, siete pronti a imparare come assemblare un workflow multi-step. + +--- + +## 1. Aggiungere un secondo passaggio al workflow + +Aggiungeremo un passaggio per convertire ogni saluto in maiuscolo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +A tal fine, dobbiamo fare tre cose: + +- Definire il comando che useremo per fare la conversione in maiuscolo. +- Scrivere un nuovo processo che incapsula il comando di conversione in maiuscolo. +- Chiamare il nuovo processo nel blocco workflow e configurarlo per prendere l'output del processo `sayHello()` come input. + +### 1.1. Definire il comando di conversione in maiuscolo e testarlo nel terminale + +Per effettuare la conversione dei saluti in maiuscolo, useremo un classico strumento UNIX chiamato `tr` per 'text replacement' (sostituzione di testo), con la seguente sintassi: + +```bash title="Syntax" +tr '[a-z]' '[A-Z]' +``` + +Questa è una sostituzione di testo molto semplice che non tiene conto delle lettere accentate, quindi per esempio 'Holà' diventerà 'HOLà', ma farà un lavoro abbastanza buono per dimostrare i concetti di Nextflow e questo è ciò che conta. + +Per testarlo, possiamo eseguire il comando `echo 'Hello World'` e fare il pipe del suo output al comando `tr`: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +L'output è un file di testo chiamato `UPPER-output.txt` che contiene la versione maiuscola della stringa `Hello World`. + +??? abstract "Contenuti del file" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +Questo è fondamentalmente ciò che cercheremo di fare con il nostro workflow. + +### 1.2. Scrivere il passaggio di conversione in maiuscolo come processo Nextflow + +Possiamo modellare il nostro nuovo processo sul primo, dato che vogliamo usare tutti gli stessi componenti. + +Aggiungete la seguente definizione di processo allo script del workflow, subito sotto il primo: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Use a text replacement tool to convert the greeting to uppercase + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +In questo, componiamo il nome del secondo file di output basandoci sul nome del file di input, similmente a quello che abbiamo fatto originariamente per l'output del primo processo. + +### 1.3. Aggiungere una chiamata al nuovo processo nel blocco workflow + +Ora dobbiamo dire a Nextflow di chiamare effettivamente il processo che abbiamo appena definito. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Questo non è ancora funzionale perché non abbiamo specificato cosa dovrebbe essere l'input al processo `convertToUpper()`. + +### 1.4. Passare l'output del primo processo al secondo processo + +Ora dobbiamo far fluire l'output del processo `sayHello()` nel processo `convertToUpper()`. + +Convenientemente, Nextflow impacchetta automaticamente l'output di un processo in un channel chiamato `<process>.out`. +Quindi l'output del processo `sayHello` è un channel chiamato `sayHello.out`, che possiamo collegare direttamente alla chiamata di `convertToUpper()`. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // converte il saluto in maiuscolo + convertToUpper() + ``` + +Per un caso semplice come questo (un output verso un input), questo è tutto ciò che dobbiamo fare per connettere due processi! + +### 1.5. Configurare la pubblicazione dell'output del workflow + +Infine, aggiorniamo gli output del workflow per pubblicare anche i risultati del secondo processo. + +#### 1.5.1. Aggiornare la sezione `publish:` del blocco `workflow` + +Nel blocco `workflow`, effettui la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +La logica è la stessa di prima. + +#### 1.5.2. Aggiornare il blocco `output` + +Nel blocco `output`, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Ancora una volta, la logica è la stessa di prima. + +Questo vi mostra che potete controllare le impostazioni di output a un livello molto granulare, per ogni singolo output. +Sentitevi liberi di provare a cambiare i percorsi o la modalità di pubblicazione per uno dei processi per vedere cosa succede. + +Naturalmente, questo significa che stiamo ripetendo alcune informazioni qui, il che potrebbe diventare scomodo se volessimo aggiornare la posizione per tutti gli output nello stesso modo. +Più avanti nel corso, imparerete come configurare queste impostazioni per output multipli in modo strutturato. + +### 1.6. Eseguire il workflow con `-resume` + +Testiamo questo usando il flag `-resume`, dato che abbiamo già eseguito con successo il primo passaggio del workflow. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Ora c'è una riga extra nell'output della console che corrisponde al nuovo processo che abbiamo appena aggiunto. + +Troverete gli output nella directory `results/hello_workflow` come impostato nel blocco `output`. + +??? abstract "Contenuti della directory" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Comodo! Ma vale comunque la pena dare un'occhiata dentro la directory di lavoro di una delle chiamate al secondo processo. + +??? abstract "Contenuti della directory" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Nota che ci sono due file `*-output`: l'output del primo processo così come l'output del secondo. + +L'output del primo processo è lì perché Nextflow lo ha **staged** lì per avere tutto il necessario per l'esecuzione nella stessa sottodirectory. + +Tuttavia, è in realtà un link simbolico che punta al file originale nella sottodirectory della prima chiamata di processo. +Per impostazione predefinita, quando si esegue su una singola macchina come stiamo facendo qui, Nextflow usa link simbolici piuttosto che copie per fare lo staging dei file di input e intermedi. + +Ora, prima di procedere, pensate a come tutto ciò che abbiamo fatto è stato connettere l'output di `sayHello` all'input di `convertToUpper` e i due processi hanno potuto essere eseguiti in serie. +Nextflow ha fatto il lavoro duro di gestire i singoli file di input e output e passarli tra i due comandi per noi. + +Questa è una delle ragioni per cui i channel di Nextflow sono così potenti: si occupano del lavoro noioso coinvolto nel connettere insieme i passaggi del workflow. + +### Takeaway + +Sapete come concatenare processi insieme fornendo l'output di un passaggio come input al passaggio successivo. + +### Cosa c'è dopo? + +Imparare come raccogliere gli output da chiamate di processo in batch e alimentarli in un singolo processo. + +--- + +## 2. Aggiungere un terzo passaggio per raccogliere tutti i saluti + +Quando usiamo un processo per applicare una trasformazione a ciascuno degli elementi in un channel, come stiamo facendo qui ai saluti multipli, a volte vogliamo raccogliere elementi dal channel di output di quel processo, e alimentarli in un altro processo che esegue qualche tipo di analisi o somma. + +Per dimostrare, aggiungeremo un nuovo passaggio alla nostra pipeline che raccoglie tutti i saluti maiuscoli prodotti dal processo `convertToUpper` e li scrive in un singolo file. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Senza rovinare la sorpresa, questo coinvolgerà un operatore molto utile. + +### 2.1. Definire il comando di raccolta e testarlo nel terminale + +Il passaggio di raccolta che vogliamo aggiungere al nostro workflow userà il comando `cat` per concatenare più saluti maiuscoli in un singolo file. + +Eseguiamo il comando da solo nel terminale per verificare che funzioni come previsto, proprio come abbiamo fatto in precedenza. + +Eseguite il seguente nel vostro terminale: + +```bash +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 +``` + +L'output è un file di testo chiamato `COLLECTED-output.txt` che contiene le versioni maiuscole dei saluti originali. + +??? abstract "Contenuti del file" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Questo è il risultato che vogliamo ottenere con il nostro workflow. + +### 2.2. Creare un nuovo processo per fare il passaggio di raccolta + +Creiamo un nuovo processo e chiamiamolo `collectGreetings()`. +Possiamo iniziare a scriverlo basandoci su ciò che abbiamo visto prima. + +#### 2.2.1. Scrivere le parti 'ovvie' del processo + +Aggiungete la seguente definizione di processo allo script del workflow: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Collect uppercase greetings into a single output file + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +Questo è ciò che possiamo scrivere con fiducia basandoci su ciò che avete imparato finora. +Ma questo non è funzionale! +Omette la/le definizione/i di input e la prima metà del comando script perché dobbiamo capire come scriverlo. + +#### 2.2.2. Definire gli input di `collectGreetings()` + +Dobbiamo raccogliere i saluti da tutte le chiamate al processo `convertToUpper()`. +Cosa sappiamo di poter ottenere dal passaggio precedente nel workflow? + +Il channel emesso da `convertToUpper()` conterrà i percorsi ai singoli file contenenti i saluti maiuscoli. +Questo equivale a uno slot di input; chiamiamolo `input_files` per semplicità. + +Nel blocco process, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Nota che usiamo il prefisso `path` anche se ci aspettiamo che questo contenga più file. + +#### 2.2.3. Comporre il comando di concatenazione + +Qui le cose potrebbero diventare un po' complicate, perché dobbiamo essere in grado di gestire un numero arbitrario di file di input. +Nello specifico, non possiamo scrivere il comando in anticipo, quindi dobbiamo dire a Nextflow come comporlo a runtime basandosi su quali input fluiscono nel processo. + +In altre parole, se abbiamo un channel di input contenente l'elemento `[file1.txt, file2.txt, file3.txt]`, abbiamo bisogno che Nextflow lo trasformi in `cat file1.txt file2.txt file3.txt`. + +Fortunatamente, Nextflow è perfettamente in grado di farlo per noi se scriviamo semplicemente `cat ${input_files}` nel comando script. + +Nel blocco process, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +In teoria questo dovrebbe gestire qualsiasi numero arbitrario di file di input. + +!!! tip "Suggerimento" + + Alcuni strumenti da riga di comando richiedono di fornire un argomento (come `-input`) per ogni file di input. + In quel caso, dovremmo fare un po' di lavoro extra per comporre il comando. + Potete vedere un esempio di questo nel corso di formazione [Nextflow for Genomics](../../nf4_science/genomics/). + +### 2.3. Aggiungere il passaggio di raccolta al workflow + +Ora dovremmo solo aver bisogno di chiamare il processo di raccolta sull'output del passaggio di conversione in maiuscolo. + +#### 2.3.1. Connettere le chiamate dei processi + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out) + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="75" + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + } + ``` + +Questo connette l'output di `convertToUpper()` all'input di `collectGreetings()`. + +#### 2.3.2. Eseguire il workflow con `-resume` + +Proviamo. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Output del comando" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Viene eseguito con successo, incluso il terzo passaggio. + +Tuttavia, guardi il numero di chiamate per `collectGreetings()` nell'ultima riga. +Ce ne aspettavamo solo una, ma ce ne sono tre. + +Ora dia un'occhiata ai contenuti del file di output finale. + +??? abstract "Contenuti del file" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Oh no. Il passaggio di raccolta è stato eseguito individualmente su ogni saluto, il che NON è quello che volevamo. + +Dobbiamo fare qualcosa per dire esplicitamente a Nextflow che vogliamo che quel terzo passaggio venga eseguito su tutti gli elementi nel channel emesso da `convertToUpper()`. + +### 2.4. Usare un operatore per raccogliere i saluti in un singolo input + +Sì, ancora una volta la risposta al nostro problema è un operatore. + +Nello specifico, useremo l'operatore [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect) dal nome appropriato. + +#### 2.4.1. Aggiungere l'operatore `collect()` + +Questa volta apparirà un po' diverso perché non stiamo aggiungendo l'operatore nel contesto di una channel factory; lo stiamo aggiungendo a un channel di output. + +Prendiamo il `convertToUpper.out` e aggiungiamo l'operatore `collect()`, che ci dà `convertToUpper.out.collect()`. +Possiamo collegarlo direttamente alla chiamata del processo `collectGreetings()`. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Aggiungere alcune istruzioni `view()` + +Includiamo anche un paio di istruzioni `view()` per visualizzare gli stati prima e dopo dei contenuti del channel. + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="73" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + } + ``` + +Le istruzioni `view()` possono andare dove volete; le abbiamo messe subito dopo la chiamata per leggibilità. + +#### 2.4.3. Eseguire di nuovo il workflow con `-resume` + +Proviamo: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Output del comando" + + ```console + 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] + ``` + +Viene eseguito con successo, anche se l'output del log potrebbe apparire un po' più disordinato di questo (l'abbiamo ripulito per leggibilità). + +Questa volta il terzo passaggio è stato chiamato solo una volta! + +Guardando l'output delle istruzioni `view()`, vedrete il seguente: + +- Tre istruzioni `Before collect:`, una per ogni saluto: a quel punto i percorsi dei file sono elementi individuali nel channel. +- Una singola istruzione `After collect:`: i tre percorsi dei file sono ora impacchettati in un singolo elemento. + +Date un'occhiata ai contenuti del file di output finale. + +??? abstract "Contenuti del file" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Questa volta abbiamo tutti e tre i saluti nel file di output finale. Successo! + +!!! note "Nota" + + Se eseguite questo più volte senza `-resume`, vedrete che l'ordine dei saluti cambia da un'esecuzione all'altra. + Questo vi mostra che l'ordine in cui gli elementi fluiscono attraverso le chiamate dei processi non è garantito essere consistente. + +#### 2.4.4. Rimuovere le istruzioni `view()` per leggibilità + +Prima di passare alla prossima sezione, raccomandiamo di cancellare le istruzioni `view()` per evitare di ingombrare l'output della console. + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="73" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +Questa è fondamentalmente l'operazione inversa dal punto 2.4.2. + +### Takeaway + +Sapete come raccogliere gli output da un batch di chiamate di processo e alimentarli in un passaggio di analisi o somma congiunta. + +### Cosa c'è dopo? + +Imparare come passare più di un input a un processo. + +--- + +## 3. Passare più di un input a un processo + +Vogliamo essere in grado di nominare il file di output finale con qualcosa di specifico per poter elaborare batch successivi di saluti senza sovrascrivere i risultati finali. + +A tal fine, apporteremo i seguenti perfezionamenti al workflow: + +- Modificare il processo di raccolta per accettare un nome definito dall'utente per il file di output +- Aggiungere un parametro da riga di comando al workflow e passarlo al processo di raccolta + +### 3.1. Modificare il processo di raccolta + +Dovremo dichiarare l'input aggiuntivo e integrarlo nel nome del file di output. + +#### 3.1.1. Dichiarare l'input aggiuntivo + +Buone notizie: possiamo dichiarare quante variabili di input vogliamo nella definizione del processo. +Chiamiamo questa `batch_name`. + +Nel blocco process, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Potete configurare i vostri processi per aspettarsi quanti input volete. +Al momento, questi sono tutti configurati come input obbligatori; _dovete_ fornire un valore affinché il workflow funzioni. + +Imparerete come gestire input obbligatori vs. opzionali più avanti nel vostro percorso con Nextflow. + +#### 3.1.2. Usare la variabile `batch_name` nel nome del file di output + +Possiamo inserire la variabile nel nome del file di output nello stesso modo in cui abbiamo composto nomi di file dinamici prima. + +Nel blocco process, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Questo configura il processo per usare il valore `batch_name` per generare un nome di file specifico per l'output finale del workflow. + +### 3.2. Aggiungere un parametro da riga di comando `batch` + +Ora abbiamo bisogno di un modo per fornire il valore per `batch_name` e alimentarlo nella chiamata del processo. + +#### 3.2.1. Usare `params` per configurare il parametro + +Sa già come usare il sistema `params` per dichiarare parametri CLI. +Usiamolo per dichiarare un parametro `batch` (con un valore predefinito perché siamo pigri). + +Nella sezione dei parametri della pipeline, effettuate le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Proprio come abbiamo dimostrato per `--input`, potete sovrascrivere quel valore predefinito specificando un valore con `--batch` sulla riga di comando. + +#### 3.2.2. Passare il parametro `batch` al processo + +Per fornire il valore del parametro al processo, dobbiamo aggiungerlo nella chiamata del processo. + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect()) + ``` + +Vedete che per fornire input multipli a un processo, li si elenca semplicemente nelle parentesi della chiamata, separati da virgole. + +!!! warning "Avviso" + + DEVE fornire gli input al processo ESATTAMENTE NELLO STESSO ORDINE in cui sono elencati nel blocco di definizione degli input del processo. + +### 3.3. Eseguire il workflow + +Proviamo a eseguirlo con un nome di batch sulla riga di comando. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Viene eseguito con successo e produce l'output desiderato: + +??? abstract "Contenuti del file" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Ora, purché specifichiamo il parametro appropriatamente, le esecuzioni successive su altri batch di input non sovrascriveranno i risultati precedenti. + +### Takeaway + +Sapete come passare più di un input a un processo. + +### Cosa c'è dopo? + +Imparare come emettere output multipli e gestirli comodamente. + +--- + +## 4. Aggiungere un output al passaggio di raccolta + +Finora abbiamo usato processi che producevano solo un output ciascuno. +Abbiamo potuto accedere ai rispettivi output molto comodamente usando la sintassi `<process>.out`, che abbiamo usato sia nel contesto di passare un output al processo successivo (es. `convertToUpper(sayHello.out)`) che nel contesto della sezione `publish:` (es. `first_output = sayHello.out`). + +Cosa succede quando un processo produce più di uno? +Come gestiamo gli output multipli? +Possiamo selezionare e usare un output specifico? + +Tutte ottime domande, e la risposta breve è sì, possiamo! + +Output multipli saranno impacchettati in channel separati. +Possiamo scegliere di dare nomi a quei channel di output, il che rende facile riferirsi a loro individualmente in seguito, oppure possiamo riferirci a loro per indice. + +Approfondiamo con un esempio. + +A scopo dimostrativo, diciamo che vogliamo contare il numero di saluti che vengono raccolti per un dato batch di input e riportarlo in un file. + +### 4.1. Modificare il processo per contare e produrre il numero di saluti + +Questo richiederà due modifiche chiave alla definizione del processo: abbiamo bisogno di un modo per contare i saluti e scrivere un file di report, poi dobbiamo aggiungere quel file di report al blocco `output` del processo. + +#### 4.1.1. Contare il numero di saluti raccolti + +Convenientemente, Nextflow ci permette di aggiungere codice arbitrario nel blocco `script:` della definizione del processo, il che è davvero utile per fare cose come questa. + +Questo significa che possiamo usare la funzione incorporata `size()` di Nextflow per ottenere il numero di file nell'array `input_files`, e scrivere il risultato su file con un comando `echo`. + +Nel blocco process `collectGreetings`, effettui le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +La variabile `count_greetings` sarà calcolata a runtime. + +#### 4.1.2. Emettere il file di report e nominare gli output + +In principio tutto ciò che dobbiamo fare è aggiungere il file di report al blocco `output:`. + +Tuttavia, già che ci siamo, aggiungeremo anche alcuni tag `emit:` alle nostre dichiarazioni di output. Questi ci permetteranno di selezionare gli output per nome invece di dover usare indici posizionali. + +Nel blocco process, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +I tag `emit:` sono opzionali, e avremmo potuto aggiungere un tag solo a uno degli output. +Ma come dice il detto, perché non entrambi? + +!!! tip "Suggerimento" + + Se non nominate gli output di un processo usando `emit:`, potete comunque accedervi individualmente usando il rispettivo indice (a base zero). + Per esempio, userebbe `<process>.out[0]` per ottenere il primo output, `<process>.out[1]` per ottenere il secondo output, e così via. + + Preferiamo nominare gli output perché altrimenti, è troppo facile prendere l'indice sbagliato per errore, specialmente quando il processo produce molti output. + +### 4.2. Aggiornare gli output del workflow + +Ora che abbiamo due output provenienti dal processo `collectGreetings`, l'output `collectGreetings.out` contiene due channel: + +- `collectGreetings.out.outfile` contiene il file di output finale +- `collectGreetings.out.report` contiene il file di report + +Dobbiamo aggiornare gli output del workflow di conseguenza. + +#### 4.2.1. Aggiornare la sezione `publish:` + +Nel `blocco workflow`, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Come potete vedere, riferirsi a output specifici dei processi è ora banale. +Quando aggiungeremo un altro passaggio alla nostra pipeline nella Parte 5 (Containers), saremo in grado di riferirci facilmente a `collectGreetings.out.outfile` e passarlo al nuovo processo (spoiler: il nuovo processo si chiama `cowpy`). + +Ma per ora, finiamo di aggiornare gli output a livello di workflow. + +#### 4.2.2. Aggiornare il blocco `output` + +Nel blocco `output`, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Non abbiamo bisogno di aggiornare la definizione dell'output `collected` dato che quel nome non è cambiato. +Dobbiamo solo aggiungere il nuovo output. + +### 4.3. Eseguire il workflow + +Proviamo a eseguirlo con l'attuale batch di saluti. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Se guardate nella directory `results/hello_workflow/`, troverete il nuovo file di report, `trio-report.txt`. +Apritelo per verificare che il workflow abbia correttamente riportato il conteggio dei saluti che sono stati elaborati. + +??? abstract "Contenuti del file" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +Sentitevi liberi di aggiungere più saluti al CSV e testare cosa succede. + +### Takeaway + +Sapete come far emettere a un processo output multipli nominati e come gestirli appropriatamente a livello di workflow. + +Più in generale, capite i principi chiave coinvolti nel connettere processi insieme in modi comuni. + +### Cosa c'è dopo? + +Prendetevi una pausa extra lunga, ve la siete guadagnata. + +Quando siete pronti, passate alla [**Parte 4: Hello Modules**](./04_hello_modules.md) per imparare come modularizzare il vostro codice per una migliore manutenibilità ed efficienza del codice. + +--- + +## Quiz + +<quiz> +Come si accede all'output di un processo nel blocco workflow? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Per approfondire: [1.4. Passare l'output del primo processo al secondo processo](#14-passare-loutput-del-primo-processo-al-secondo-processo) +</quiz> + +<quiz> +Cosa determina l'ordine di esecuzione dei processi in Nextflow? +- [ ] L'ordine in cui i processi sono scritti nel blocco workflow +- [ ] Ordine alfabetico per nome del processo +- [x] Le dipendenze dei dati tra i processi +- [ ] Ordine casuale per esecuzione parallela + +Per approfondire: [1.4. Passare l'output del primo processo al secondo processo](#14-passare-loutput-del-primo-processo-al-secondo-processo) +</quiz> + +<quiz> +Quale operatore dovrebbe sostituire `???` per raccogliere tutti gli output in una singola lista per il processo a valle? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Per approfondire: [2.4. Usare un operatore per raccogliere i saluti in un singolo input](#24-usare-un-operatore-per-raccogliere-i-saluti-in-un-singolo-input) +</quiz> + +<quiz> +Quando si dovrebbe usare l'operatore `collect()`? +- [ ] Quando si vogliono elaborare gli elementi in parallelo +- [ ] Quando si ha bisogno di filtrare i contenuti del channel +- [x] Quando un processo a valle ha bisogno di tutti gli elementi da un processo a monte +- [ ] Quando si vogliono dividere i dati tra più processi + +Per approfondire: [2.4. Usare un operatore per raccogliere i saluti in un singolo input](#24-usare-un-operatore-per-raccogliere-i-saluti-in-un-singolo-input) +</quiz> + +<quiz> +Come si accede a un output nominato da un processo? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Per approfondire: [4.1.2. Emettere il file di report e nominare gli output](#412-emettere-il-file-di-report-e-nominare-gli-output) +</quiz> + +<quiz> +Qual è la sintassi corretta per nominare un output in un processo? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Per approfondire: [4.1.2. Emettere il file di report e nominare gli output](#412-emettere-il-file-di-report-e-nominare-gli-output) +</quiz> + +<quiz> +Quando si forniscono input multipli a un processo, cosa deve essere vero? +- [ ] Tutti gli input devono essere dello stesso tipo +- [ ] Gli input devono essere forniti in ordine alfabetico +- [x] L'ordine degli input deve corrispondere all'ordine definito nel blocco input +- [ ] Possono essere forniti solo due input alla volta + +Per approfondire: [3. Passare più di un input a un processo](#3-passare-piu-di-un-input-a-un-processo) +</quiz> diff --git a/docs/it/docs/hello_nextflow/04_hello_modules.md b/docs/it/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..b8336687b6 --- /dev/null +++ b/docs/it/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Parte 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/04_hello_modules.md). +/// + +Questa sezione tratta come organizzare il codice del workflow per rendere lo sviluppo e la manutenzione della pipeline più efficienti e sostenibili. +Nello specifico, dimostreremo come usare i **moduli**. + +In Nextflow, un **modulo** è una singola definizione di processo che è incapsulata da sola in un file di codice autonomo. +Per usare un modulo in un workflow, basta aggiungere una singola riga di import al file di codice del workflow; poi potete integrare il processo nel workflow nello stesso modo in cui farebbe normalmente. +Questo rende possibile riutilizzare le definizioni dei processi in più workflow senza produrre copie multiple del codice. + +Quando abbiamo iniziato a sviluppare il nostro workflow, abbiamo scritto tutto in un singolo file di codice. +Ora sposteremo i processi in moduli individuali. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Questo renderà il nostro codice più condivisibile, flessibile e manutenibile. + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che abbiate completato le Parti 1-3 del corso [Hello Nextflow](./index.md), ma se avete familiarità con i concetti base trattati in quelle sezioni, potete iniziare da qui senza fare nulla di speciale. + +--- + +## 0. Riscaldamento: Eseguire `hello-modules.nf` + +Useremo lo script del workflow `hello-modules.nf` come punto di partenza. +È equivalente allo script prodotto seguendo la Parte 3 di questo corso di formazione, tranne che abbiamo cambiato le destinazioni dell'output: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Solo per assicurarci che tutto funzioni, eseguite lo script una volta prima di apportare modifiche: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Come in precedenza, troverete i file di output nella directory specificata nel blocco `output` (qui, `results/hello_modules/`). + +??? abstract "Contenuti della directory" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Se tutto ha funzionato, siete pronti a imparare come modularizzare il codice del workflow. + +--- + +## 1. Creare una directory per memorizzare i moduli + +È buona pratica memorizzare i moduli in una directory specifica. +Potete chiamare quella directory come volete, ma la convenzione è chiamarla `modules/`. + +```bash +mkdir modules +``` + +!!! tip "Suggerimento" + + Qui vi stiamo mostrando come usare **moduli locali**, cioè moduli memorizzati localmente nello stesso repository del resto del codice del workflow, in contrasto con i moduli remoti, che sono memorizzati in altri repository (remoti). + Per maggiori informazioni sui **moduli remoti**, vedete la [documentazione](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Creare un modulo per `sayHello()` + +Nella sua forma più semplice, trasformare un processo esistente in un modulo è poco più di un'operazione di copia-incolla. +Creeremo uno stub di file per il modulo, copieremo il codice rilevante e poi lo cancelleremo dal file del workflow principale. + +Poi tutto ciò che dovremo fare è aggiungere un'istruzione di import in modo che Nextflow sappia di importare il codice rilevante a runtime. + +### 2.1. Creare uno stub di file per il nuovo modulo + +Creiamo un file vuoto per il modulo chiamato `sayHello.nf`. + +```bash +touch modules/sayHello.nf +``` + +Questo ci dà un posto dove mettere il codice del processo. + +### 2.2. Spostare il codice del processo `sayHello` nel file del modulo + +Copiate l'intera definizione del processo dal file del workflow al file del modulo, assicurandovi di copiare anche lo shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Use echo to print 'Hello World!' to a file + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Una volta fatto, cancellate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. + +### 2.3. Aggiungere una dichiarazione di import prima del blocco workflow + +La sintassi per importare un modulo locale è abbastanza semplice: + +```groovy title="Syntax: Import declaration" +include { <MODULE_NAME> } from '<path_to_module>' +``` + +Inseriamola sopra il blocco `params` e compiliamola appropriatamente. + +=== "Dopo" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Prima" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Vedete che abbiamo inserito il nome del modulo, `sayHello`, e il percorso al file contenente il codice del modulo, `./modules/sayHello.nf`. + +### 2.4. Eseguire il workflow + +Stiamo eseguendo il workflow essenzialmente con lo stesso codice e input di prima, quindi eseguiamo con il flag `-resume` e vediamo cosa succede. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Questo dovrebbe funzionare molto velocemente perché tutto è in cache. +Sentitevi liberi di controllare gli output pubblicati. + +Nextflow ha riconosciuto che è ancora tutto lo stesso lavoro da fare, anche se il codice è diviso in più file. + +### Takeaway + +Sapete come estrarre un processo in un modulo locale e sapete che fare questo non compromette la ripristinabilità del workflow. + +### Cosa c'è dopo? + +Fare pratica creando più moduli. +Una volta che ne avete fatto uno, potete farne un milione di più... +Ma per ora ne facciamo solo altri due. + +--- + +## 3. Modularizzare il processo `convertToUpper()` + +### 3.1. Creare uno stub di file per il nuovo modulo + +Create un file vuoto per il modulo chiamato `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Spostare il codice del processo `convertToUpper` nel file del modulo + +Copiate l'intera definizione del processo dal file del workflow al file del modulo, assicurandovi di copiare anche lo shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Use a text replacement tool to convert the greeting to uppercase + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Una volta fatto, cancellate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. + +### 3.3. Aggiungere una dichiarazione di import prima del blocco `params` + +Inserite la dichiarazione di import sopra il blocco `params` e compilatela appropriatamente. + +=== "Dopo" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Prima" + + ```groovy title="hello-modules.nf" linenums="23" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Questo dovrebbe iniziare a sembrare molto familiare. + +### 3.4. Eseguire di nuovo il workflow + +Eseguite questo con il flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Questo dovrebbe ancora produrre lo stesso output di prima. + +Due fatti, ne manca ancora uno! + +--- + +## 4. Modularizzare il processo `collectGreetings()` + +### 4.1. Creare uno stub di file per il nuovo modulo + +Create un file vuoto per il modulo chiamato `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Spostare il codice del processo `collectGreetings` nel file del modulo + +Copiate l'intera definizione del processo dal file del workflow al file del modulo, assicurandovi di copiare anche lo shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Collect uppercase greetings into a single output file + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Una volta fatto, cancellate la definizione del processo dal file del workflow, ma assicuratevi di lasciare lo shebang al suo posto. + +### 4.3. Aggiungere una dichiarazione di import prima del blocco `params` + +Inserite la dichiarazione di import sopra il blocco `params` e compilatela appropriatamente. + +=== "Dopo" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Prima" + + ```groovy title="hello-modules.nf" linenums="3" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Ultimo! + +### 4.4. Eseguire il workflow + +Eseguite questo con il flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Questo dovrebbe ancora produrre lo stesso output di prima. + +### Takeaway + +Sapete come modularizzare più processi in un workflow. + +Congratulazioni, avete fatto tutto questo lavoro e non è cambiato assolutamente nulla nel funzionamento della pipeline! + +A parte gli scherzi, ora il vostro codice è più modulare, e se decidete di scrivere un'altra pipeline che chiama uno di quei processi, vi basta digitare una breve istruzione di import per usare il modulo rilevante. +Questo è meglio che fare copia-incolla del codice, perché se in seguito decidete di migliorare il modulo, tutte le vostre pipeline erediteranno i miglioramenti. + +### Cosa c'è dopo? + +Prendetevi una breve pausa se ne avete voglia. + +Quando siete pronti, passate alla [**Parte 5: Hello Containers**](./05_hello_containers.md) per imparare come usare i container per gestire le dipendenze software in modo più conveniente e riproducibile. + +--- + +## Quiz + +<quiz> +Cos'è un modulo in Nextflow? +- [ ] Un file di configurazione +- [x] Un file autonomo contenente una singola definizione di processo +- [ ] Una definizione di workflow +- [ ] Un operatore di channel + +Per approfondire: [2. Creare un modulo per `sayHello()`](#2-creare-un-modulo-per-sayhello) +</quiz> + +<quiz> +Qual è la convenzione di denominazione raccomandata per i file dei moduli? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Dove dovrebbero essere memorizzati i file dei moduli? +- [ ] Nella stessa directory del workflow +- [ ] In una directory `bin/` +- [x] In una directory `modules/` +- [ ] In una directory `lib/` + +Per approfondire: [1. Creare una directory per memorizzare i moduli](#1-creare-una-directory-per-memorizzare-i-moduli) +</quiz> + +<quiz> +Qual è la sintassi corretta per importare un modulo? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Per approfondire: [2.3. Aggiungere una dichiarazione di import](#23-aggiungere-una-dichiarazione-di-import-prima-del-blocco-workflow) +</quiz> + +<quiz> +Cosa succede alla funzionalità `-resume` quando si usano i moduli? +- [ ] Non funziona più +- [ ] Richiede configurazione aggiuntiva +- [x] Funziona come prima +- [ ] Funziona solo per i moduli locali +</quiz> + +<quiz> +Quali sono i vantaggi dell'uso dei moduli? (Selezioni tutte le risposte applicabili) +- [x] Riutilizzabilità del codice tra workflow +- [x] Manutenzione più facile +- [x] Migliore organizzazione del codice del workflow +- [ ] Velocità di esecuzione più rapida +</quiz> diff --git a/docs/it/docs/hello_nextflow/05_hello_containers.md b/docs/it/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..44076c2199 --- /dev/null +++ b/docs/it/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Parte 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/05_hello_containers.md). +/// + +Nelle Parti 1-4 di questo corso di formazione, avete imparato come usare i blocchi di costruzione di base di Nextflow per assemblare un semplice workflow capace di elaborare del testo, parallelizzare l'esecuzione se ci sono più input, e raccogliere i risultati per ulteriori elaborazioni. + +Tuttavia, eravate limitati agli strumenti UNIX di base disponibili nel vostro ambiente. +Le attività del mondo reale spesso richiedono vari strumenti e pacchetti non inclusi di default. +Tipicamente, dovreste installare questi strumenti, gestire le loro dipendenze e risolvere eventuali conflitti. + +Tutto ciò è molto tedioso e fastidioso, quindi vi mostreremo come usare i **container** per risolvere questo problema in modo molto più conveniente. + +Un **container** è un'unità di software leggera, autonoma ed eseguibile creata da un'**immagine** container che include tutto il necessario per eseguire un'applicazione, incluso codice, librerie di sistema e impostazioni. +Come potete immaginare, questo sarà molto utile per rendere le vostre pipeline più riproducibili. + +Nota che insegneremo questo usando [Docker](https://www.docker.com/get-started/), ma tenete presente che Nextflow supporta anche [diverse altre tecnologie container](https://www.nextflow.io/docs/latest/container.html#). + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che abbiate completato le Parti 1-4 del corso [Hello Nextflow](./index.md) e abbiate una pipeline funzionante completa. + + Se state iniziando il corso da questo punto, dovrete copiare la directory `modules` dalle soluzioni: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Riscaldamento: Eseguire `hello-containers.nf` + +Useremo lo script del workflow `hello-containers.nf` come punto di partenza. +È equivalente allo script prodotto seguendo la Parte 4 di questo corso di formazione, tranne che abbiamo cambiato le destinazioni dell'output: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Solo per assicurarci che tutto funzioni, eseguite lo script una volta prima di apportare modifiche: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Come in precedenza, troverete i file di output nella directory specificata nel blocco `output` (`results/hello_containers/`). + +??? abstract "Contenuti della directory" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Se tutto ha funzionato, siete pronti a imparare come usare i container. + +--- + +## 1. Usare un container 'manualmente' + +Quello che vogliamo fare è aggiungere un passaggio al nostro workflow che userà un container per l'esecuzione. + +Tuttavia, prima esamineremo alcuni concetti e operazioni di base per consolidare la vostra comprensione di cosa sono i container prima di iniziare a usarli in Nextflow. + +### 1.1. Scaricare l'immagine del container + +Per usare un container, di solito si scarica o si fa il _pull_ di un'immagine container da un registro container, e poi si esegue l'immagine container per creare un'istanza container. + +La sintassi generale è la seguente: + +```bash title="Syntax" +docker pull '<container>' +``` + +La parte `docker pull` è l'istruzione al sistema container per scaricare un'immagine container da un repository. + +La parte `'<container>'` è l'indirizzo URI dell'immagine container. + +Come esempio, scarichiamo un'immagine container che contiene [cowpy](https://github.com/jeffbuttars/cowpy), un'implementazione Python di uno strumento chiamato `cowsay` che genera ASCII art per visualizzare input di testo arbitrari in modo divertente. + +```txt title="Example" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Ci sono vari repository dove potete trovare container pubblicati. +Abbiamo usato il servizio [Seqera Containers](https://seqera.io/containers/) per generare questa immagine Docker container dal pacchetto Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Eseguite il comando pull completo: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Output del comando" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Se non avete mai scaricato l'immagine prima, potrebbe richiedere un minuto per completare. +Una volta fatto, avrete una copia locale dell'immagine container. + +### 1.2. Usare il container per eseguire `cowpy` come comando singolo + +Un modo molto comune in cui le persone usano i container è eseguirli direttamente, _cioè_ in modo non interattivo. +Questo è ottimo per eseguire comandi una tantum. + +La sintassi generale è la seguente: + +```bash title="Syntax" +docker run --rm '<container>' [tool command] +``` + +La parte `docker run --rm '<container>'` è l'istruzione al sistema container per avviare un'istanza container da un'immagine container ed eseguire un comando al suo interno. +Il flag `--rm` dice al sistema di spegnere l'istanza container dopo che il comando è stato completato. + +La sintassi `[tool command]` dipende dallo strumento che state usando e da come è configurato il container. +Iniziamo semplicemente con `cowpy`. + +Completamente assemblato, il comando di esecuzione del container appare così; procedete ed eseguitelo. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Output del comando" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Il sistema ha avviato il container, eseguito il comando `cowpy` con i suoi parametri, inviato l'output alla console e infine, spento l'istanza container. + +### 1.3. Usare il container per eseguire `cowpy` interattivamente + +Potete anche eseguire un container interattivamente, il che vi dà un prompt di shell all'interno del container e vi permette di giocare con il comando. + +#### 1.3.1. Avviare il container + +Per eseguire interattivamente, basta aggiungere `-it` al comando `docker run`. +Opzionalmente, possiamo specificare la shell che vogliamo usare all'interno del container aggiungendo _es._ `/bin/bash` al comando. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Nota che il vostro prompt cambia in qualcosa come `(base) root@b645838b3314:/tmp#`, che indica che ora siete all'interno del container. + +Potete verificarlo eseguendo `ls /` per elencare i contenuti della directory dalla radice del filesystem: + +```bash +ls / +``` + +??? abstract "Output del comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Usiamo `ls` qui invece di `tree` perché l'utility `tree` non è disponibile in questo container. +Potete vedere che il filesystem all'interno del container è diverso dal filesystem sul vostro sistema host. + +Una limitazione di quello che abbiamo appena fatto è che il container è completamente isolato dal sistema host per impostazione predefinita. +Questo significa che il container non può accedere a nessun file sul sistema host a meno che non gli si permetta esplicitamente di farlo. + +Vi mostreremo come farlo tra un minuto. + +#### 1.3.2. Eseguire il/i comando/i dello strumento desiderato + +Ora che siete all'interno del container, potete eseguire il comando `cowpy` direttamente e dargli alcuni parametri. +Per esempio, la documentazione dello strumento dice che possiamo cambiare il personaggio ('cowacter') con `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Output del comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Ora l'output mostra il pinguino Linux, Tux, invece della mucca predefinita, perché abbiamo specificato il parametro `-c tux`. + +Poiché siete all'interno del container, potete eseguire il comando `cowpy` quante volte volete, variando i parametri di input, senza dovervi preoccupare dei comandi Docker. + +!!! Tip "Suggerimento" + + Usate il flag '-c' per scegliere un personaggio diverso, inclusi: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Questo è carino. Sarebbe ancora più carino se potessimo passare il nostro `greetings.csv` come input. +Ma dato che non abbiamo accesso al filesystem, non possiamo. + +Risolviamo questo problema. + +#### 1.3.3. Uscire dal container + +Per uscire dal container, potete digitare `exit` al prompt o usare la scorciatoia da tastiera ++ctrl+d++. + +```bash +exit +``` + +Il vostro prompt dovrebbe ora essere tornato a quello che era prima di avviare il container. + +#### 1.3.4. Montare i dati nel container + +Come notato in precedenza, il container è isolato dal sistema host per impostazione predefinita. + +Per permettere al container di accedere al filesystem host, potete **montare** un **volume** dal sistema host nel container usando la seguente sintassi: + +```bash title="Syntax" +-v <outside_path>:<inside_path> +``` + +Nel nostro caso `<outside_path>` sarà la directory di lavoro corrente, quindi possiamo semplicemente usare un punto (`.`), e `<inside_path>` è solo un alias che inventiamo; chiamiamolo `/my_project` (il percorso interno deve essere assoluto). + +Per montare un volume, sostituiamo i percorsi e aggiungiamo l'argomento di montaggio del volume al comando docker run come segue: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Questo monta la directory di lavoro corrente come volume che sarà accessibile sotto `/my_project` all'interno del container. + +Potete verificare che funzioni elencando i contenuti di `/my_project`: + +```bash +ls /my_project +``` + +??? success "Output del comando" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Ora potete vedere i contenuti della directory di lavoro dall'interno del container, incluso il file `greetings.csv` sotto `data/`. + +Questo ha effettivamente stabilito un tunnel attraverso la parete del container che potete usare per accedere a quella parte del vostro filesystem. + +#### 1.3.5. Usare i dati montati + +Ora che abbiamo montato la directory di lavoro nel container, possiamo usare il comando `cowpy` per visualizzare i contenuti del file `greetings.csv`. + +Per fare questo, useremo `cat /my_project/data/greetings.csv | ` per fare il pipe dei contenuti del file CSV nel comando `cowpy`. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Output del comando" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Questo produce l'ASCII art desiderata di un tacchino che recita i nostri saluti di esempio! +Tranne che qui il tacchino sta ripetendo le righe complete invece di solo i saluti. +Sappiamo già che il nostro workflow Nextflow farà un lavoro migliore! + +Sentitevi liberi di giocare con questo comando. +Quando avete finito, uscite dal container come in precedenza: + +```bash +exit +``` + +Vi ritroverete nella vostra shell normale. + +### Takeaway + +Sapete come scaricare un container ed eseguirlo sia come comando singolo che interattivamente. Sapete anche come rendere i vostri dati accessibili dall'interno del vostro container, il che vi permette di provare qualsiasi strumento che vi interessa su dati reali senza dover installare alcun software sul vostro sistema. + +### Cosa c'è dopo? + +Imparare come usare i container per l'esecuzione dei processi Nextflow. + +--- + +## 2. Usare i container in Nextflow + +Nextflow ha supporto integrato per eseguire processi all'interno di container per permettervi di eseguire strumenti che non avete installato nel vostro ambiente di calcolo. +Questo significa che potete usare qualsiasi immagine container che desiderate per eseguire i vostri processi, e Nextflow si occuperà di scaricare l'immagine, montare i dati ed eseguire il processo al suo interno. + +Per dimostrare questo, aggiungeremo un passaggio `cowpy` alla pipeline che abbiamo sviluppato, dopo il passaggio `collectGreetings`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Muggite se siete pronti a tuffarvi! + +### 2.1. Scrivere un modulo `cowpy` + +Prima, creiamo il modulo del processo `cowpy`. + +#### 2.1.1. Creare uno stub di file per il nuovo modulo + +Create un file vuoto per il modulo chiamato `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +Questo ci dà un posto dove mettere il codice del processo. + +#### 2.1.2. Copiare il codice del processo `cowpy` nel file del modulo + +Possiamo modellare il nostro processo `cowpy` sugli altri processi che abbiamo scritto in precedenza. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generate ASCII art with cowpy +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Il processo si aspetta un `input_file` contenente i saluti così come un valore `character`. + +L'output sarà un nuovo file di testo contenente l'ASCII art generata dallo strumento `cowpy`. + +### 2.2. Aggiungere cowpy al workflow + +Ora dobbiamo importare il modulo e chiamare il processo. + +#### 2.2.1. Importare il processo `cowpy` in `hello-containers.nf` + +Inserite la dichiarazione di import sopra il blocco workflow e compilatela appropriatamente. + +=== "Dopo" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Prima" + + ```groovy title="hello-containers.nf" linenums="3" + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Ora il modulo `cowpy` è disponibile per l'uso nel workflow. + +#### 2.2.2. Aggiungere una chiamata al processo `cowpy` nel workflow + +Connettiamo il processo `cowpy()` all'output del processo `collectGreetings()`, che come potete ricordare produce due output: + +- `collectGreetings.out.outfile` contiene il file di output <--_quello che vogliamo_ +- `collectGreetings.out.report` contiene il file di report con il conteggio dei saluti per batch + +Nel blocco workflow, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Prima" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Nota che abbiamo dichiarato un nuovo parametro CLI, `params.character`, per specificare quale personaggio vogliamo che dica i saluti. + +#### 2.2.3. Aggiungere il parametro `character` al blocco `params` + +Questo è tecnicamente opzionale ma è la pratica raccomandata ed è un'opportunità per impostare un valore predefinito per il personaggio mentre ci siamo. + +=== "Dopo" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Prima" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Ora possiamo essere pigri e saltare la digitazione del parametro character nelle nostre righe di comando. + +#### 2.2.4. Aggiornare gli output del workflow + +Dobbiamo aggiornare gli output del workflow per pubblicare l'output del processo `cowpy`. + +##### 2.2.4.1. Aggiornare la sezione `publish:` + +Nel `blocco workflow`, effettuate la seguente modifica al codice: + +=== "Dopo" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Prima" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +Il processo `cowpy` produce solo un output quindi possiamo riferirci ad esso nel modo usuale aggiungendo `.out`. + +Ma per ora, finiamo di aggiornare gli output a livello di workflow. + +##### 2.2.4.2. Aggiornare il blocco `output` + +Dobbiamo aggiungere l'output finale `cowpy_art` al blocco `output`. Già che ci siamo, modifichiamo anche le destinazioni di pubblicazione dato che ora la nostra pipeline è completa e sappiamo quali output ci interessano davvero. + +Nel blocco `output`, effettuate le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Ora gli output pubblicati saranno un po' più organizzati. + +#### 2.2.5. Eseguire il workflow + +Per ricapitolare, questo è quello a cui miriamo: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Pensate che funzionerà? + +Cancelliamo gli output pubblicati precedenti per avere una lavagna pulita, ed eseguiamo il workflow con il flag `-resume`. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Output del comando (modificato per chiarezza)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +Oh no, c'è un errore! +Il codice di errore dato da `error exit status (127)` significa che l'eseguibile che abbiamo richiesto non è stato trovato. + +Ha senso, dato che chiamiamo lo strumento `cowpy` ma non abbiamo ancora specificato un container (oops). + +### 2.3. Usare un container per eseguire il processo `cowpy` + +Dobbiamo specificare un container e dire a Nextflow di usarlo per il processo `cowpy()`. + +#### 2.3.1. Specificare un container per `cowpy` + +Possiamo usare la stessa immagine che stavamo usando direttamente nella prima sezione di questo tutorial. + +Modificate il modulo `cowpy.nf` per aggiungere la direttiva `container` alla definizione del processo come segue: + +=== "Dopo" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Prima" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Questo dice a Nextflow che _se l'uso di Docker è abilitato_, dovrebbe usare l'immagine container specificata qui per eseguire il processo. + +#### 2.3.2. Abilitare l'uso di Docker tramite il file `nextflow.config` + +Nota che abbiamo detto _'se l'uso di Docker è abilitato'_. Per impostazione predefinita, non lo è, quindi dobbiamo dire a Nextflow che è autorizzato a usare Docker. +A tal fine, anticiperemo leggermente l'argomento della prossima e ultima parte di questo corso (Parte 6), che tratta la configurazione. + +Uno dei modi principali che Nextflow offre per configurare l'esecuzione del workflow è usare un file `nextflow.config`. +Quando tale file è presente nella directory corrente, Nextflow lo caricherà automaticamente e applicherà qualsiasi configurazione contenga. + +Abbiamo fornito un file `nextflow.config` con una singola riga di codice che disabilita esplicitamente Docker: `docker.enabled = false`. + +Ora, cambiamo quello a `true` per abilitare Docker: + +=== "Dopo" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Prima" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Suggerimento" + + È possibile abilitare l'esecuzione Docker dalla riga di comando, su base per esecuzione, usando il parametro `-with-docker <container>`. + Tuttavia, questo ci permette solo di specificare un container per l'intero workflow, mentre l'approccio che Le abbiamo appena mostrato ci permette di specificare un container diverso per processo. + Questo è meglio per modularità, manutenzione del codice e riproducibilità. + +#### 2.3.3. Eseguire il workflow con Docker abilitato + +Eseguite il workflow con il flag `-resume`: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Questa volta funziona davvero! +Come al solito potete trovare gli output del workflow nella directory dei risultati corrispondente, anche se questa volta sono un po' più ordinatamente organizzati, con solo il report e l'output finale al livello superiore, e tutti i file intermedi spostati in una sottodirectory. + +??? abstract "Contenuti della directory" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +L'output ASCII art finale è nella directory `results/hello_containers/`, sotto il nome `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenuti del file" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Ed eccolo, il nostro bellissimo tacchino che dice i saluti come desiderateto. + +#### 2.3.4. Ispezionare come Nextflow ha lanciato il task containerizzato + +Come coda finale a questa sezione, diamo un'occhiata alla sottodirectory di lavoro per una delle chiamate del processo `cowpy` per ottenere un po' più di comprensione su come Nextflow lavora con i container sotto il cofano. + +Controllate l'output dal vostro comando `nextflow run` per trovare il percorso alla sottodirectory di lavoro per il processo `cowpy`. +Guardando quello che abbiamo ottenuto per l'esecuzione mostrata sopra, la riga del log della console per il processo `cowpy` inizia con `[98/656c6c]`. +Questo corrisponde al seguente percorso di directory troncato: `work/98/656c6c`. + +In quella directory, troverete il file `.command.run` che contiene tutti i comandi che Nextflow ha eseguito per vostro conto nel corso dell'esecuzione della pipeline. + +??? abstract "Contenuti del file" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Se cercate `nxf_launch` in questo file, dovreste vedere qualcosa come questo: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Come potete vedere, Nextflow sta usando il comando `docker run` per lanciare la chiamata del processo. +Monta anche la sottodirectory di lavoro corrispondente nel container, imposta la directory di lavoro all'interno del container di conseguenza, ed esegue il nostro script bash templato nel file `.command.sh`. + +Tutto il lavoro duro che abbiamo dovuto fare manualmente nella prima sezione? Nextflow lo fa per noi dietro le quinte! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Takeaway + +Sapete come usare i container in Nextflow per eseguire processi. + +### Cosa c'è dopo? + +Prendetevi una pausa! + +Quando siete pronti, passate alla [**Parte 6: Hello Config**](./06_hello_config.md) per imparare come configurare l'esecuzione della vostra pipeline per adattarla alla vostra infrastruttura e gestire la configurazione di input e parametri. + +È l'ultima parte, e poi avrà finito con questo corso! + +--- + +## Quiz + +<quiz> +Cos'è un container? +- [ ] Un tipo di macchina virtuale +- [ ] Un formato di compressione file +- [x] Un'unità eseguibile leggera e autonoma che include tutto il necessario per eseguire un'applicazione +- [ ] Un protocollo di rete +</quiz> + +<quiz> +Qual è la differenza tra un'immagine container e un'istanza container? +- [ ] Sono la stessa cosa +- [x] Un'immagine è un template; un'istanza è un container in esecuzione creato da quell'immagine +- [ ] Un'istanza è un template; un'immagine è un container in esecuzione +- [ ] Le immagini sono per Docker; le istanze sono per Singularity +</quiz> + +<quiz> +Cosa fa il flag `-v` in un comando `docker run`? +- [ ] Abilita l'output verbose +- [ ] Valida il container +- [x] Monta un volume dal sistema host nel container +- [ ] Specifica la versione del container + +Per approfondire: [1.3.4. Montare i dati nel container](#134-montare-i-dati-nel-container) +</quiz> + +<quiz> +Perché è necessario montare i volumi quando si usano i container? +- [ ] Per migliorare le prestazioni del container +- [ ] Per risparmiare spazio su disco +- [x] Perché i container sono isolati dal filesystem host per impostazione predefinita +- [ ] Per abilitare il networking + +Per approfondire: [1.3.4. Montare i dati nel container](#134-montare-i-dati-nel-container) +</quiz> + +<quiz> +Come si specifica un container per un processo Nextflow? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Per approfondire: [2.3.1. Specificare un container per cowpy](#231-specificare-un-container-per-cowpy) +</quiz> + +<quiz> +Quale impostazione `nextflow.config` abilita Docker per il vostro workflow? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Per approfondire: [2.3.2. Abilitare l'uso di Docker tramite il file `nextflow.config`](#232-abilitare-luso-di-docker-tramite-il-file-nextflowconfig) +</quiz> + +<quiz> +Cosa gestisce automaticamente Nextflow quando esegue un processo in un container? (Selezioni tutte le risposte applicabili) +- [x] Scaricare l'immagine container se necessario +- [x] Montare la directory di lavoro +- [x] Eseguire lo script del processo all'interno del container +- [x] Pulire l'istanza container dopo l'esecuzione + +Per approfondire: [2.3.4. Ispezionare come Nextflow ha lanciato il task containerizzato](#234-ispezionare-come-nextflow-ha-lanciato-il-task-containerizzato) +</quiz> diff --git a/docs/it/docs/hello_nextflow/06_hello_config.md b/docs/it/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..7f3f6b7ce0 --- /dev/null +++ b/docs/it/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# Parte 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) sul canale YouTube di Nextflow. + +:green_book: La trascrizione del video è disponibile [qui](./transcripts/06_hello_config.md). +/// + +Questa sezione esplorerà come configurare e gestire la configurazione della vostra pipeline Nextflow in modo che possiate personalizzarne il comportamento, adattarla a diversi ambienti e ottimizzare l'uso delle risorse _senza modificare una singola riga del codice del workflow stesso_. + +Ci sono diversi modi per farlo, che possono essere usati in combinazione e vengono interpretati secondo l'ordine di precedenza descritto [qui](https://www.nextflow.io/docs/latest/config.html). + +In questa parte del corso, vi mostreremo il meccanismo di file di configurazione più semplice e comune, il file `nextflow.config`, che avete già incontrato nella Parte 5: Hello Containers. + +Esamineremo i componenti essenziali della configurazione di Nextflow come le direttive dei processi, gli executor, i profili e i file di parametri. +Imparando a utilizzare efficacemente queste opzioni di configurazione, potete migliorare la flessibilità, la scalabilità e le prestazioni delle vostre pipeline. + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che abbiate completato le Parti 1-5 del corso [Hello Nextflow](./index.md) e abbiate una pipeline funzionante completa. + + Se state iniziando il corso da questo punto, dovrete copiare la directory `modules` e il file `nextflow.config` dalle soluzioni: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + Il file `nextflow.config` contiene la riga `docker.enabled = true` che abilita l'uso dei container Docker. + + Se non avete familiarità con la pipeline Hello o avete bisogno di un promemoria, vedete [questa pagina informativa](../info/hello_pipeline.md). + +--- + +## 0. Riscaldamento: Eseguire `hello-config.nf` + +Useremo lo script del workflow `hello-config.nf` come punto di partenza. +È equivalente allo script prodotto seguendo la Parte 5 di questo corso di formazione, tranne che abbiamo cambiato le destinazioni dell'output: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Solo per assicurarci che tutto funzioni, eseguite lo script una volta prima di apportare modifiche: + +```bash +nextflow run hello-config.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Come in precedenza, troverete i file di output nella directory specificata nel blocco `output` (`results/hello_config/`). + +??? abstract "Contenuti della directory" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +L'output ASCII art finale è nella directory `results/hello_config/`, sotto il nome `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Contenuti del file" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Se tutto ha funzionato, siete pronti a imparare come configurare le vostre pipeline. + +--- + +## 1. Gestire i parametri di input del workflow + +Inizieremo con un aspetto della configurazione che è semplicemente un'estensione di ciò con cui abbiamo lavorato finora: la gestione dei parametri di input. + +Attualmente, il nostro workflow è configurato per accettare diversi valori di parametro tramite la riga di comando, con valori predefiniti impostati in un blocco `params` nello script del workflow stesso. +Tuttavia, potreste voler sovrascrivere quei valori predefiniti senza dover specificare parametri sulla riga di comando, o modificare il file di script originale. + +Ci sono diversi modi per farlo; vi mostreremo tre modi di base che sono molto comunemente usati. + +### 1.1. Spostare i valori predefiniti in `nextflow.config` + +Questo è l'approccio più semplice, anche se è forse il meno flessibile dato che il file `nextflow.config` principale non è qualcosa che si vuole modificare per ogni esecuzione. +Ma ha il vantaggio di separare le preoccupazioni della _dichiarazione_ dei parametri nel workflow (che appartiene sicuramente lì) rispetto alla fornitura di _valori predefiniti_, che sono più appropriati in un file di configurazione. + +Facciamo questo in due passaggi. + +#### 1.1.1. Creare un blocco `params` nel file di configurazione + +Effettuate le seguenti modifiche al codice nel file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Nota che non abbiamo semplicemente copiato il blocco `params` dal workflow al file di configurazione. +La sintassi è leggermente diversa. +Nel file del workflow, quelle sono dichiarazioni tipizzate. +Nella configurazione, quelle sono assegnazioni di valori. + +Tecnicamente, questo è sufficiente per sovrascrivere i valori predefiniti ancora specificati nel file del workflow. +Potreste modificare il personaggio, per esempio, ed eseguire il workflow per verificare che il valore impostato nel file di configurazione sovrascriva quello impostato nel file del workflow. + +Ma nello spirito di spostare completamente la configurazione nel file di configurazione, rimuoviamo completamente quei valori dal file del workflow. + +#### 1.1.2. Rimuovere i valori dal blocco `params` nel file del workflow + +Effettuate le seguenti modifiche al codice nel file del workflow `hello-config.nf`: + +=== "Dopo" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Prima" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Ora il file del workflow stesso non imposta alcun valore predefinito per questi parametri. + +#### 1.1.3. Eseguire la pipeline + +Testiamo che funzioni correttamente. + +```bash +nextflow run hello-config.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima. + +L'output ASCII art finale è nella directory `results/hello_config/`, sotto il nome `cowpy-COLLECTED-batch-output.txt`, come prima. + +??? abstract "Contenuti del file" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funzionalmente, questo spostamento non ha cambiato nulla, ma concettualmente è un po' più pulito avere i valori predefiniti impostati nel file di configurazione. + +### 1.2. Usare un file di configurazione specifico per l'esecuzione + +Questo è ottimo, ma a volte potreste voler eseguire alcuni esperimenti temporanei con valori predefiniti diversi senza toccare il file di configurazione principale. +Potete farlo creando un nuovo file `nextflow.config` in una sottodirectory che userete come directory di lavoro per i vostri esperimenti. + +#### 1.2.1. Creare la directory di lavoro con una configurazione vuota + +Iniziamo creando una nuova directory e spostandoci al suo interno: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Poi, crei un file di configurazione vuoto in quella directory: + +```bash +touch nextflow.config +``` + +Questo produce un file vuoto. + +#### 1.2.2. Configurare la configurazione sperimentale + +Ora aprite il nuovo file e aggiungete i parametri che volete personalizzare: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Nota che il percorso al file di input deve riflettere la struttura della directory. + +#### 1.2.3. Eseguire la pipeline + +Ora possiamo eseguire la nostra pipeline dall'interno della nostra nuova directory di lavoro. +Assicuratevi di adattare il percorso di conseguenza! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Questo creerà un nuovo set di directory sotto `tux-run/` incluse `tux-run/work/` e `tux-run/results/`. + +In questa esecuzione, Nextflow combina il `nextflow.config` nella nostra directory corrente con il `nextflow.config` nella directory radice della pipeline, e quindi sovrascrive il personaggio predefinito (turkey) con il personaggio tux. + +Il file di output finale dovrebbe contenere il personaggio tux che dice i saluti. + +??? abstract "Contenuti del file" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Ecco fatto; ora avete uno spazio per sperimentare senza modificare la vostra configurazione 'normale'. + +!!! warning "Avviso" + + Assicuratevi di tornare alla directory precedente prima di passare alla prossima sezione! + + ```bash + cd .. + ``` + +Ora vediamo un altro modo utile per impostare i valori dei parametri. + +### 1.3. Usare un file di parametri + +L'approccio della sottodirectory funziona benissimo per sperimentare, ma comporta un po' di configurazione e richiede di adattare i percorsi di conseguenza. +C'è un approccio più semplice per quando volete eseguire la vostra pipeline con un set specifico di valori, o permettere a qualcun altro di farlo con il minimo sforzo. + +Nextflow vi permette di specificare parametri tramite un file di parametri in formato YAML o JSON, il che rende molto conveniente gestire e distribuire set alternativi di valori predefiniti, per esempio, così come valori di parametri specifici per l'esecuzione. + +#### 1.3.1. Esaminare il file di parametri di esempio + +Per dimostrare questo, forniamo un file di parametri di esempio nella directory corrente, chiamato `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Questo file di parametri contiene una coppia chiave-valore per ciascuno degli input che vogliamo specificare. +Nota l'uso dei due punti (`:`) invece dei segni di uguale (`=`) se confronta la sintassi con il file di configurazione. +Il file di configurazione è scritto in Groovy, mentre il file di parametri è scritto in YAML. + +!!! info "Informazione" + + Forniamo anche una versione JSON del file di parametri come esempio ma non la eseguiremo qui. + Sentitevi liberi di provare quella da soli. + +#### 1.3.2. Eseguire la pipeline + +Per eseguire il workflow con questo file di parametri, aggiunga semplicemente `-params-file <filename>` al comando base. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Il file di output finale dovrebbe contenere il personaggio stegosaurus che dice i saluti. + +??? abstract "Contenuti del file" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usare un file di parametri può sembrare eccessivo quando si hanno solo pochi parametri da specificare, ma alcune pipeline si aspettano decine di parametri. +In quei casi, usare un file di parametri ci permetterà di fornire valori di parametri a runtime senza dover digitare righe di comando massive e senza modificare lo script del workflow. + +Rende anche più facile distribuire set di parametri ai collaboratori, o come informazione di supporto per una pubblicazione, per esempio. +Questo rende il vostro lavoro più riproducibile da altri. + +### Takeaway + +Sapete come sfruttare le principali opzioni di configurazione per gestire gli input del workflow. + +### Cosa c'è dopo? + +Imparare come gestire dove e come vengono pubblicati gli output del vostro workflow. + +--- + +## 2. Gestire gli output del workflow + +Finora abbiamo hardcodato tutti i percorsi per le dichiarazioni di output a livello di workflow, e come abbiamo notato quando abbiamo iniziato ad aggiungere output multipli, può esserci un po' di ripetizione coinvolta. + +Vediamo alcuni modi comuni in cui potreste configurare questo per essere più flessibile. + +### 2.1. Personalizzare il nome della directory `outputDir` + +Per ogni capitolo di questo corso, abbiamo pubblicato gli output in una sottodirectory diversa hardcodata nelle definizioni di output. + +Cambiamo questo per usare un parametro configurabile dall'utente. +Potremmo creare un parametro completamente nuovo per questo, ma useremo il parametro `batch` dato che è già lì. + +#### 2.1.1. Impostare un valore per `outputDir` nel file di configurazione + +Il percorso che Nextflow usa per pubblicare gli output è controllato dall'opzione `outputDir`. +Per cambiare il percorso per tutti gli output, potete impostare un valore per questa opzione nel file di configurazione `nextflow.config`. + +Aggiungete il seguente codice al file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Questo sostituirà il percorso predefinito integrato, `results/`, con `results/` più il valore del parametro `batch` come sottodirectory. +Potreste anche cambiare la parte `results` se lo desideraste. + +Per un cambiamento temporaneo, potreste impostare questa opzione dalla riga di comando usando il parametro `-output-dir` nel vostro comando (ma in quel caso non potreste usare il valore del parametro `batch`). + +#### 2.1.2. Rimuovere la parte ripetuta del percorso hardcodato + +Abbiamo ancora una sottodirectory hardcodata nelle opzioni di output, quindi eliminiamola ora. + +Effettuate le seguenti modifiche al codice nel file del workflow: + +=== "Dopo" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +Avremmo anche potuto semplicemente aggiungere `${params.batch}` a ogni percorso invece di modificare il `outputDir` predefinito, ma questo è più conciso. + +#### 2.1.3. Eseguire la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `outdir` dalla riga di comando. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/outdir/`. + +??? abstract "Contenuti della directory" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Potete combinare questo approccio con definizioni di percorso personalizzate per costruire qualsiasi gerarchia di directory desideriate. + +### 2.2. Organizzare gli output per processo + +Un modo popolare per organizzare ulteriormente gli output è farlo per processo, _cioè_ creare sottodirectory per ogni processo eseguito nella pipeline. + +#### 2.2.1. Sostituire i percorsi di output con un riferimento ai nomi dei processi + +Tutto ciò che dovete fare è riferirvi al nome del processo come `<task>.name` nella dichiarazione del percorso di output. + +Effettuate le seguenti modifiche nel file del workflow: + +=== "Dopo" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Questo rimuove gli elementi hardcodati rimanenti dalla configurazione del percorso di output. + +#### 2.2.2. Eseguire la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `pnames` dalla riga di comando. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/pnames/`, e sono raggruppati per processo. + +??? abstract "Contenuti della directory" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Nota che qui abbiamo eliminato la distinzione tra `intermediates` rispetto agli output finali al livello superiore. +Potreste ovviamente mescolare questi approcci, per esempio impostando il percorso del primo output come `intermediates/${sayHello.process}` + +### 2.3. Impostare la modalità di pubblicazione a livello di workflow + +Infine, nello spirito di ridurre la quantità di codice ripetitivo, possiamo sostituire le dichiarazioni `mode` per-output con una singola riga nella configurazione. + +#### 2.3.1. Aggiungere `workflow.output.mode` al file di configurazione + +Aggiungete il seguente codice al file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Proprio come l'opzione `outputDir`, dare a `workflow.output.mode` un valore nel file di configurazione sarebbe sufficiente per sovrascrivere ciò che è impostato nel file del workflow, ma rimuoviamo comunque il codice non necessario. + +#### 2.3.2. Rimuovere la modalità di output dal file del workflow + +Effettuate le seguenti modifiche nel file del workflow: + +=== "Dopo" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Prima" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +Più conciso, vero? + +#### 2.3.3. Eseguire la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `outmode` dalla riga di comando. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/outmode/`. +Sono ancora tutte copie appropriate, non symlink. + +??? abstract "Contenuti della directory" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Il motivo principale per cui potreste ancora voler usare il modo per-output di impostare la modalità è se volete mescolare all'interno dello stesso workflow, _cioè_ avere alcuni output copiati e alcuni come symlink. + +Ci sono molte altre opzioni che potete personalizzare in questo modo, ma speriamo che questo vi dia un senso della gamma di opzioni e di come utilizzarle efficacemente per adattarle alle vostre preferenze. + +### Takeaway + +Sapete come controllare la denominazione e la struttura delle directory dove vengono pubblicati i vostri output, così come la modalità di pubblicazione dell'output del workflow. + +### Cosa c'è dopo? + +Imparare come adattare la configurazione del vostro workflow al vostro ambiente di calcolo, partendo dalla tecnologia di packaging del software. + +--- + +## 3. Selezionare una tecnologia di packaging del software + +Finora abbiamo esaminato elementi di configurazione che controllano come gli input entrano e dove escono gli output. Ora è il momento di concentrarci più specificamente sull'adattamento della configurazione del vostro workflow al vostro ambiente di calcolo. + +Il primo passo su quel percorso è specificare da dove provengono i pacchetti software che verranno eseguiti in ogni passaggio. +Sono già installati nell'ambiente di calcolo locale? +Dobbiamo recuperare immagini ed eseguirle tramite un sistema container? +O dobbiamo recuperare pacchetti Conda e costruire un ambiente Conda locale? + +Nella primissima parte di questo corso di formazione (Parti 1-4) abbiamo semplicemente usato software installato localmente nel nostro workflow. +Poi nella Parte 5, abbiamo introdotto i container Docker e il file `nextflow.config`, che abbiamo usato per abilitare l'uso dei container Docker. + +Ora vediamo come potete configurare un'opzione alternativa di packaging del software tramite il file `nextflow.config`. + +### 3.1. Disabilitare Docker e abilitare Conda nel file di configurazione + +Facciamo finta di lavorare su un cluster HPC e l'amministratore non permette l'uso di Docker per motivi di sicurezza. +Fortunatamente per noi, Nextflow supporta diverse altre tecnologie container come Singularity (che è più ampiamente usato su HPC), e gestori di pacchetti software come Conda. + +Potete cambiare il vostro file di configurazione per usare Conda invece di Docker. +Per farlo, cambiate il valore di `docker.enabled` a `false`, e aggiungete una direttiva che abilita l'uso di Conda: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Questo permetterà a Nextflow di creare e utilizzare ambienti Conda per i processi che hanno pacchetti Conda specificati. +Il che significa che ora dobbiamo aggiungere uno di quelli al nostro processo `cowpy`! + +### 3.2. Specificare un pacchetto Conda nella definizione del processo + +Abbiamo già recuperato l'URI per un pacchetto Conda contenente lo strumento `cowpy`: `conda-forge::cowpy==1.1.5` + +Ora aggiungiamo l'URI alla definizione del processo `cowpy` usando la direttiva `conda`: + +=== "Dopo" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Prima" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Per essere chiari, non stiamo _sostituendo_ la direttiva `docker`, stiamo _aggiungendo_ un'opzione alternativa. + +!!! tip "Suggerimento" + + Ci sono diversi modi per ottenere l'URI per un dato pacchetto conda. + Raccomandiamo di usare la query di ricerca di [Seqera Containers](https://seqera.io/containers/), che vi darà un URI che potete copiare e incollare, anche se non avete intenzione di creare un container da esso. + +### 3.3. Eseguire il workflow per verificare che possa usare Conda + +Proviamo. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Output del comando" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Questo dovrebbe funzionare senza problemi e produrre gli stessi output di prima sotto `results/conda`. + +Dietro le quinte, Nextflow ha recuperato i pacchetti Conda e creato l'ambiente, il che normalmente richiede un po' di lavoro; quindi è bello che non dobbiamo fare nulla di tutto ciò noi stessi! + +!!! note "Nota" + + Questo viene eseguito rapidamente perché il pacchetto `cowpy` è abbastanza piccolo, ma se state lavorando con pacchetti grandi, potrebbe richiedere un po' più di tempo del solito la prima volta, e potreste vedere l'output della console rimanere 'bloccato' per un minuto o così prima di completare. + Questo è normale ed è dovuto al lavoro extra che Nextflow fa la prima volta che usa un nuovo pacchetto. + +Dal nostro punto di vista, sembra che funzioni esattamente come l'esecuzione con Docker, anche se sul backend i meccanismi sono un po' diversi. + +Questo significa che siamo pronti a eseguire con ambienti Conda se necessario. + +??? info "Mescolare Docker e Conda" + + Dato che queste direttive sono assegnate per processo, è possibile 'mescolare', _cioè_ configurare alcuni dei processi nel vostro workflow per essere eseguiti con Docker e altri con Conda, per esempio, se l'infrastruttura di calcolo che state usando supporta entrambi. + In quel caso, abilitereste sia Docker che Conda nel vostro file di configurazione. + Se entrambi sono disponibili per un dato processo, Nextflow darà priorità ai container. + + E come notato in precedenza, Nextflow supporta diverse altre tecnologie di packaging software e container, quindi non è limitato a quelle due. + +### Takeaway + +Sapete come configurare quale pacchetto software ogni processo dovrebbe usare, e come passare da una tecnologia all'altra. + +### Cosa c'è dopo? + +Imparare come cambiare la piattaforma di esecuzione usata da Nextflow per effettivamente fare il lavoro. + +--- + +## 4. Selezionare una piattaforma di esecuzione + +Finora, abbiamo eseguito la nostra pipeline con l'executor locale. +Questo esegue ogni task sulla macchina su cui è in esecuzione Nextflow. +Quando Nextflow inizia, guarda le CPU e la memoria disponibili. +Se le risorse dei task pronti per l'esecuzione superano le risorse disponibili, Nextflow tratterrà gli ultimi task dall'esecuzione fino a quando uno o più dei task precedenti non sono terminati, liberando le risorse necessarie. + +L'executor locale è conveniente ed efficiente, ma è limitato a quella singola macchina. Per carichi di lavoro molto grandi, potreste scoprire che la vostra macchina locale è un collo di bottiglia, sia perché avete un singolo task che richiede più risorse di quelle disponibili, sia perché avete così tanti task che aspettare che una singola macchina li esegua richiederebbe troppo tempo. + +Nextflow supporta [molti backend di esecuzione diversi](https://www.nextflow.io/docs/latest/executor.html), inclusi scheduler HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor e altri) così come backend di esecuzione cloud (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes e altro). + +### 4.1. Puntare a un backend diverso + +La scelta dell'executor è impostata da una direttiva di processo chiamata `executor`. +Per impostazione predefinita è impostato su `local`, quindi la seguente configurazione è implicita: + +```groovy title="Built-in configuration" +process { + executor = 'local' +} +``` + +Per impostare l'executor per puntare a un backend diverso, specificate semplicemente l'executor che volete usando una sintassi simile a quella descritta sopra per le allocazioni di risorse (vedete la [documentazione](https://www.nextflow.io/docs/latest/executor.html) per tutte le opzioni). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Avviso" + + Non possiamo effettivamente testare questo nell'ambiente di formazione perché non è configurato per connettersi a un HPC. + +### 4.2. Gestire la sintassi specifica del backend per i parametri di esecuzione + +La maggior parte delle piattaforme di calcolo ad alte prestazioni permette (e a volte richiede) di specificare certi parametri come le richieste di allocazione delle risorse e le limitazioni (per es. numero di CPU e memoria) e nome della coda di lavoro da usare. + +Sfortunatamente, ciascuno di questi sistemi usa tecnologie, sintassi e configurazioni diverse per definire come un lavoro dovrebbe essere definito e inviato allo scheduler rilevante. + +??? abstract "Esempi" + + Per esempio, lo stesso lavoro che richiede 8 CPU e 4GB di RAM per essere eseguito sulla coda "my-science-work" deve essere espresso in modi diversi a seconda del backend. + + ```bash title="Config for SLURM / submit using sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config for PBS / submit using qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config for SGE / submit using qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Fortunatamente, Nextflow semplifica tutto questo. +Fornisce una sintassi standardizzata in modo che possa specificare le proprietà rilevanti come `cpus`, `memory` e `queue` (veda la documentazione per altre proprietà) una sola volta. +Poi, a runtime, Nextflow userà quelle impostazioni per generare gli script appropriati specifici del backend basandosi sull'impostazione dell'executor. + +Tratteremo quella sintassi standardizzata nella prossima sezione. + +### Takeaway + +Ora sapete come cambiare l'executor per usare diversi tipi di infrastruttura di calcolo. + +### Cosa c'è dopo? + +Imparare come valutare ed esprimere allocazioni e limitazioni di risorse in Nextflow. + +--- + +## 5. Controllare le allocazioni delle risorse di calcolo + +La maggior parte delle piattaforme di calcolo ad alte prestazioni permette (e a volte richiede) di specificare certi parametri di allocazione delle risorse come numero di CPU e memoria. + +Per impostazione predefinita, Nextflow userà una singola CPU e 2GB di memoria per ogni processo. +Le corrispondenti direttive di processo si chiamano `cpus` e `memory`, quindi la seguente configurazione è implicita: + +```groovy title="Built-in configuration" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Potete modificare questi valori, sia per tutti i processi che per processi specifici nominati, usando direttive di processo aggiuntive nel vostro file di configurazione. +Nextflow le tradurrà nelle istruzioni appropriate per l'executor scelto. + +Ma come sapete quali valori usare? + +### 5.1. Eseguire il workflow per generare un report di utilizzo delle risorse + +Se non sapete in anticipo quanta CPU e memoria i vostri processi probabilmente necessitano, potete fare un po' di profilazione delle risorse, il che significa che eseguite il workflow con alcune allocazioni predefinite, registrate quanto ogni processo ha usato, e da lì, stimate come regolare le allocazioni base. + +Convenientemente, Nextflow include strumenti integrati per farlo, e genererà felicemente un report per voi su richiesta. + +Per farlo, aggiungete `-with-report <filename>.html` alla vostra riga di comando. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Il report è un file html, che potete scaricare e aprire nel vostro browser. Potete anche fare clic destro su di esso nell'esploratore file a sinistra e cliccare su `Show preview` per visualizzarlo nell'ambiente di formazione. + +Prendetevi qualche minuto per esaminare il report e vedere se riuscite a identificare alcune opportunità per regolare le risorse. +Assicuratevi di cliccare sulle schede che mostrano i risultati di utilizzo come percentuale di ciò che è stato allocato. +C'è della [documentazione](https://www.nextflow.io/docs/latest/reports.html) che descrive tutte le funzionalità disponibili. + +### 5.2. Impostare allocazioni di risorse per tutti i processi + +La profilazione mostra che i processi nel nostro workflow di formazione sono molto leggeri, quindi riduciamo l'allocazione di memoria predefinita a 1GB per processo. + +Aggiungete il seguente al vostro file `nextflow.config`, prima della sezione dei parametri della pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Questo aiuterà a ridurre la quantità di calcolo che consumiamo. + +### 5.3. Impostare allocazioni di risorse per un processo specifico + +Allo stesso tempo, facciamo finta che il processo `cowpy` richieda più risorse degli altri, solo per dimostrare come regolare le allocazioni per un singolo processo. + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Con questa configurazione, tutti i processi richiederanno 1GB di memoria e una singola CPU (il valore predefinito implicito), tranne il processo `cowpy`, che richiederà 2GB e 2 CPU. + +!!! tip "Suggerimento" + + Se avete una macchina con poche CPU e allocate un numero elevato per processo, potreste vedere le chiamate dei processi accodarsi l'una dietro l'altra. + Questo perché Nextflow si assicura che non richiediamo più CPU di quelle disponibili. + +### 5.4. Eseguire il workflow con la configurazione aggiornata + +Proviamo, fornendo un nome di file diverso per il report di profilazione in modo da poter confrontare le prestazioni prima e dopo le modifiche alla configurazione. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Probabilmente non noterete alcuna differenza reale dato che questo è un carico di lavoro così piccolo, ma questo è l'approccio che usereste per analizzare le prestazioni e i requisiti di risorse di un workflow del mondo reale. + +È molto utile quando i vostri processi hanno requisiti di risorse diversi. Vi permette di dimensionare correttamente le allocazioni di risorse che impostate per ogni processo basandovi su dati reali, non su congetture. + +!!! tip "Suggerimento" + + Questo è solo un piccolo assaggio di ciò che potete fare per ottimizzare il vostro uso delle risorse. + Nextflow stesso ha una [logica di retry dinamica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) davvero interessante integrata per riprovare i lavori che falliscono a causa di limitazioni di risorse. + Inoltre, la Piattaforma Seqera offre strumenti guidati dall'AI per ottimizzare le vostre allocazioni di risorse automaticamente. + +### 5.5. Aggiungere limiti di risorse + +A seconda di quale executor di calcolo e infrastruttura di calcolo state usando, potrebbero esserci alcuni vincoli su ciò che potete (o dovete) allocare. +Per esempio, il vostro cluster potrebbe richiedere di rimanere entro certi limiti. + +Potete usare la direttiva `resourceLimits` per impostare le limitazioni rilevanti. La sintassi appare così quando è da sola in un blocco process: + +```groovy title="Syntax example" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow tradurrà questi valori nelle istruzioni appropriate a seconda dell'executor che avete specificato. + +Non eseguiremo questo, dato che non abbiamo accesso all'infrastruttura rilevante nell'ambiente di formazione. +Tuttavia, se provaste a eseguire il workflow con allocazioni di risorse che superano questi limiti, poi cercaste il comando `sbatch` nel file di script `.command.run`, vedreste che le richieste che effettivamente vengono inviate all'executor sono limitate ai valori specificati da `resourceLimits`. + +??? info "Configurazioni di riferimento istituzionali" + + Il progetto nf-core ha compilato una [collezione di file di configurazione](https://nf-co.re/configs/) condivisi da varie istituzioni in tutto il mondo, che coprono una vasta gamma di executor HPC e cloud. + + Quelle configurazioni condivise sono preziose sia per le persone che lavorano lì e possono quindi semplicemente utilizzare la configurazione della loro istituzione pronta all'uso, sia come modello per le persone che stanno cercando di sviluppare una configurazione per la propria infrastruttura. + +### Takeaway + +Sapete come generare un report di profilazione per valutare l'utilizzo delle risorse e come modificare le allocazioni di risorse per tutti i processi e/o per singoli processi, così come impostare limitazioni di risorse per l'esecuzione su HPC. + +### Cosa c'è dopo? + +Imparare come configurare profili di configurazione preimpostati e passare da uno all'altro a runtime. + +--- + +## 6. Usare profili per passare tra configurazioni preimpostate + +Vi abbiamo mostrato diversi modi in cui potete personalizzare la configurazione della vostra pipeline a seconda del progetto su cui state lavorando o dell'ambiente di calcolo che state usando. + +Potreste voler passare tra impostazioni alternative a seconda di quale infrastruttura di calcolo state usando. Per esempio, potreste voler sviluppare ed eseguire test su piccola scala localmente sul vostro laptop, poi eseguire carichi di lavoro su scala completa su HPC o cloud. + +Nextflow vi permette di configurare qualsiasi numero di profili che descrivono diverse configurazioni, che potete poi selezionare a runtime usando un argomento da riga di comando, piuttosto che dover modificare il file di configurazione stesso. + +### 6.1. Creare profili per passare tra sviluppo locale ed esecuzione su HPC + +Configuriamo due profili alternativi; uno per eseguire carichi su piccola scala su un computer normale, dove useremo container Docker, e uno per eseguire su un HPC universitario con uno scheduler Slurm, dove useremo pacchetti Conda. + +#### 6.1.1. Configurare i profili + +Aggiungete il seguente al vostro file `nextflow.config`, dopo la sezione dei parametri della pipeline ma prima delle impostazioni di output: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Vedete che per l'HPC universitario, stiamo anche specificando limitazioni di risorse. + +#### 6.1.2. Eseguire il workflow con un profilo + +Per specificare un profilo nella nostra riga di comando Nextflow, usiamo l'argomento `-profile`. + +Proviamo a eseguire il workflow con la configurazione `my_laptop`. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Come potete vedere, questo ci permette di alternare tra configurazioni molto comodamente a runtime. + +!!! warning "Avviso" + + Il profilo `univ_hpc` non funzionerà correttamente nell'ambiente di formazione dato che non abbiamo accesso a uno scheduler Slurm. + +Se in futuro troviamo altri elementi di configurazione che co-occorrono sempre con questi, possiamo semplicemente aggiungerli al/ai profilo/i corrispondente/i. +Possiamo anche creare profili aggiuntivi se ci sono altri elementi di configurazione che vogliamo raggruppare insieme. + +### 6.2. Creare un profilo di parametri di test + +I profili non sono solo per la configurazione dell'infrastruttura. +Possiamo anche usarli per impostare valori predefiniti per i parametri del workflow, per rendere più facile per altri provare il workflow senza dover raccogliere valori di input appropriati da soli. +Potete considerare questo un'alternativa all'uso di un file di parametri. + +#### 6.2.1. Configurare il profilo + +La sintassi per esprimere valori predefiniti in questo contesto appare così, per un profilo che chiamiamo `test`: + +```groovy title="Syntax example" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Se aggiungiamo un profilo di test per il nostro workflow, il blocco `profiles` diventa: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Proprio come per i profili di configurazione tecnica, potete configurare più profili diversi specificando parametri sotto qualsiasi nome arbitrario che desiderate. + +#### 6.2.2. Eseguire il workflow localmente con il profilo di test + +Convenientemente, i profili non sono mutuamente esclusivi, quindi possiamo specificare più profili nella nostra riga di comando usando la seguente sintassi `-profile <profile1>,<profile2>` (per qualsiasi numero di profili). + +Se combinate profili che impostano valori per gli stessi elementi di configurazione e sono descritti nello stesso file di configurazione, Nextflow risolverà il conflitto usando qualsiasi valore abbia letto per ultimo (_cioè_ qualsiasi cosa venga dopo nel file). +Se le impostazioni in conflitto sono impostate in diverse fonti di configurazione, si applica l'[ordine di precedenza](https://www.nextflow.io/docs/latest/config.html) predefinito. + +Proviamo ad aggiungere il profilo di test al nostro comando precedente: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Questo userà Docker dove possibile e produrrà output sotto `results/test`, e questa volta il personaggio è il duo comico `dragonandcow`. + +??? abstract "Contenuti del file" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Questo significa che finché distribuiamo qualsiasi file di dati di test con il codice del workflow, chiunque può provare rapidamente il workflow senza dover fornire i propri input tramite la riga di comando o un file di parametri. + +!!! tip "Suggerimento" + + Possiamo puntare a URL per file più grandi che sono memorizzati esternamente. + Nextflow li scaricherà automaticamente finché c'è una connessione aperta. + + Per maggiori dettagli, vedete la Side Quest [Lavorare con i file](../side_quests/working_with_files.md) + +### 6.3. Usare `nextflow config` per vedere la configurazione risolta + +Come notato sopra, a volte lo stesso parametro può essere impostato a valori diversi in profili che volete combinare. +E più in generale, ci sono numerosi posti dove elementi di configurazione possono essere memorizzati, e a volte le stesse proprietà possono essere impostate a valori diversi in posti diversi. + +Nextflow applica un [ordine di precedenza](https://www.nextflow.io/docs/latest/config.html) stabilito per risolvere qualsiasi conflitto, ma può essere complicato da determinare da soli. +E anche se nulla è in conflitto, può essere tedioso cercare tutti i possibili posti dove le cose potrebbero essere configurate: + +Fortunatamente, Nextflow include uno strumento utility conveniente chiamato `config` che può automatizzare l'intero processo per voi. + +Lo strumento `config` esplorerà tutti i contenuti nella vostra directory di lavoro corrente, raccoglierà qualsiasi file di configurazione, e produrrà la configurazione completamente risolta che Nextflow userebbe per eseguire il workflow. +Questo vi permette di scoprire quali impostazioni verranno usate senza dover lanciare nulla. + +#### 6.3.1. Risolvere la configurazione predefinita + +Eseguite questo comando per risolvere la configurazione che verrebbe applicata per impostazione predefinita. + +```bash +nextflow config +``` + +??? success "Output del comando" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Questo vi mostra la configurazione base che ottenete se non specificate nulla di extra nella riga di comando. + +#### 6.3.2. Risolvere la configurazione con impostazioni specifiche attivate + +Se fornite parametri da riga di comando, es. abilitando uno o più profili o caricando un file di parametri, il comando prenderà in considerazione anche quelli. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Output del comando" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Questo diventa particolarmente utile per progetti complessi che coinvolgono più livelli di configurazione. + +### Takeaway + +Sapete come usare i profili per selezionare una configurazione preimpostata a runtime con il minimo sforzo. +Più in generale, sapete come configurare le esecuzioni del vostro workflow per adattarsi a diverse piattaforme di calcolo e migliorare la riproducibilità delle vostre analisi. + +### Cosa c'è dopo? + +Festeggiate e datevi una bella pacca sulla spalla! Avete completato il vostro primo corso di sviluppo Nextflow. + +Passate al [riepilogo finale del corso](./next_steps.md) per rivedere ciò che avete imparato e scoprire cosa viene dopo. + +--- + +## Quiz + +<quiz> +Qual è il nome del file di configurazione che Nextflow carica automaticamente? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +Cosa ha la precedenza quando lo stesso parametro è impostato sia nel file di configurazione che nella riga di comando? +- [ ] Il valore del file di configurazione +- [x] Il valore della riga di comando +- [ ] Il primo valore incontrato +- [ ] Nessuno dei due; causa un errore + +Per approfondire: [1.1. Spostare i valori predefiniti in `nextflow.config`](#11-spostare-i-valori-predefiniti-in-nextflowconfig) +</quiz> + +<quiz> +Si possono avere sia Docker che Conda abilitati nella stessa configurazione? +- [x] Sì, Nextflow potete usare entrambi a seconda delle direttive del processo +- [ ] No, solo uno può essere abilitato alla volta +- [ ] Sì, ma solo nei profili +- [ ] No, sono mutuamente esclusivi +</quiz> + +<quiz> +Se sia Docker che Conda sono abilitati e un processo ha entrambe le direttive, quale ha la priorità? +- [x] Docker (container) +- [ ] Conda +- [ ] Il primo definito +- [ ] Causa un errore + +Per approfondire: [3. Selezionare una tecnologia di packaging del software](#3-selezionare-una-tecnologia-di-packaging-del-software) +</quiz> + +<quiz> +Qual è l'allocazione di memoria predefinita per i processi Nextflow? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] Nessun limite +</quiz> + +<quiz> +Come si impostano i requisiti di risorse per un processo specifico nel file di configurazione? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +Per approfondire: [5.3. Impostare allocazioni di risorse per un processo specifico](#53-impostare-allocazioni-di-risorse-per-un-processo-specifico) +</quiz> + +<quiz> +Quale opzione da riga di comando genera un report di utilizzo delle risorse? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +Per approfondire: [5.1. Eseguire il workflow per generare un report di utilizzo delle risorse](#51-eseguire-il-workflow-per-generare-un-report-di-utilizzo-delle-risorse) +</quiz> + +<quiz> +Cosa fa la direttiva `resourceLimits`? +- [ ] Imposta i requisiti minimi di risorse +- [ ] Alloca risorse ai processi +- [x] Limita le risorse massime che possono essere richieste +- [ ] Monitora l'uso delle risorse + +Per approfondire: [5.5. Aggiungere limiti di risorse](#55-aggiungere-limiti-di-risorse) +</quiz> + +<quiz> +Qual è l'executor predefinito in Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Per approfondire: [4. Selezionare una piattaforma di esecuzione](#4-selezionare-una-piattaforma-di-esecuzione) +</quiz> + +<quiz> +Come si specifica un file di parametri quando si esegue Nextflow? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +Per approfondire: [1.3. Usare un file di parametri](#13-usare-un-file-di-parametri) +</quiz> + +<quiz> +Per cosa possono essere usati i profili? (Selezioni tutte le risposte applicabili) +- [x] Definire impostazioni specifiche dell'infrastruttura +- [x] Impostare limiti di risorse per ambienti diversi +- [x] Fornire parametri di test +- [ ] Definire nuovi processi + +Per approfondire: [6. Usare profili per passare tra configurazioni preimpostate](#6-usare-profili-per-passare-tra-configurazioni-preimpostate) +</quiz> + +<quiz> +Come si specificano più profili in un singolo comando? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Per approfondire: [6. Usare profili per passare tra configurazioni preimpostate](#6-usare-profili-per-passare-tra-configurazioni-preimpostate) +</quiz> diff --git a/docs/it/docs/hello_nextflow/index.md b/docs/it/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..037fed096e --- /dev/null +++ b/docs/it/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Avviare e gestire l'esecuzione di workflow Nextflow + - Trovare e interpretare gli output (risultati) e i file di log generati da Nextflow + - Risolvere problemi di base + - Costruire un workflow semplice multi-step dai componenti fondamentali di Nextflow + - Distinguere tra tipi essenziali di channel factory e operatori e utilizzarli efficacemente in un workflow semplice + - Configurare l'esecuzione della pipeline per funzionare su piattaforme di calcolo comuni inclusi HPC e cloud + - Applicare le best practice per riproducibilità, portabilità e riutilizzo del codice che rendono le pipeline FAIR, inclusa la modularità del codice e i container software + audience_prerequisites: + - "**Pubblico:** Questo corso è progettato per chi è completamente nuovo a Nextflow e desidera sviluppare le proprie pipeline." + - "**Competenze:** Si presume una certa familiarità con la riga di comando, concetti di base di scripting e formati di file comuni." + - "**Dominio:** Gli esercizi sono tutti indipendenti dal dominio applicativo, quindi non è richiesta alcuna conoscenza scientifica preliminare." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow è un'introduzione pratica alla costruzione di workflow di analisi dati riproducibili e scalabili.** + +Attraverso esempi pratici ed esercizi guidati, imparerete i fondamenti dello sviluppo di pipeline con Nextflow, incluso come definire processi, connetterli in pipeline, gestire file e dipendenze software, parallelizzare l'esecuzione senza sforzo ed eseguire workflow in diversi ambienti di calcolo. + +Acquisirete le competenze e la sicurezza per iniziare a sviluppare e eseguire i vostri workflow con Nextflow. + +<!-- additional_information --> + +## Panoramica del corso + +Questo corso è progettato per essere pratico, con esercizi orientati agli obiettivi strutturati per introdurre le informazioni gradualmente. + +Svilupperete una semplice pipeline Nextflow che prende alcuni input di testo, esegue alcuni passaggi di trasformazione e produce un singolo file di testo contenente un'immagine ASCII di un personaggio che dice il testo trasformato. + +### Piano delle lezioni + +Per evitare di sovraccaricarvi con concetti e codice, abbiamo suddiviso questo in sei parti che si concentreranno ciascuna su aspetti specifici dello sviluppo di pipeline con Nextflow. + +| Capitolo del corso | Riepilogo | Durata stimata | +| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Parte 1: Hello World](./01_hello_world.md) | Componenti e principi di base coinvolti nell'assemblaggio e nell'esecuzione di un workflow Nextflow | 30 min | +| [Parte 2: Hello Channels](./02_hello_channels.md) | Utilizzo di channel e operatori per elaborare input e parallelizzare l'esecuzione senza sforzo | 45 min | +| [Parte 3: Hello Workflow](./03_hello_workflow.md) | Utilizzo dei channel per concatenare più step e gestire il trasferimento di dati tra gli step | 60 min | +| [Parte 4: Hello Modules](./04_hello_modules.md) | Applicazione dei principi di modularità del codice per aumentare la riusabilità e ridurre l'onere di manutenzione | 20 min | +| [Parte 5: Hello Containers](./05_hello_containers.md) | Utilizzo dei container come meccanismo per gestire le dipendenze software e aumentare la riproducibilità | 60 min | +| [Parte 6: Hello Config](./06_hello_config.md) | Personalizzazione del comportamento della pipeline e ottimizzazione dell'utilizzo in diversi ambienti computazionali | 60 min | + +Al termine di questo corso, sarete ben preparati per affrontare i prossimi passi nel vostro percorso per sviluppare workflow riproducibili per le vostre esigenze di calcolo scientifico. + +Pronto a seguire il corso? + +[Inizia :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/it/docs/hello_nextflow/next_steps.md b/docs/it/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..637905d693 --- /dev/null +++ b/docs/it/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Riepilogo del corso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni per aver completato il corso di formazione Hello Nextflow! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Guarda [l'intera playlist sul canale YouTube di Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Potete leggere la [trascrizione del video](./transcripts/07_next_steps.md) insieme al video. +/// + +## Il vostro percorso + +Avete iniziato con un workflow molto semplice che eseguiva un comando codificato in modo fisso. +Nel corso delle sei parti, avete trasformato quel workflow di base in una pipeline modulare multi-step che esercita le funzionalità chiave di Nextflow inclusi channel, operatori, supporto integrato per container e opzioni di configurazione. + +### Cosa avete costruito + +- La forma finale del workflow Hello prende come input un file CSV contenente saluti testuali. +- I quattro step sono implementati come processi Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) memorizzati in file di modulo separati. +- I risultati vengono pubblicati in una directory chiamata `results/`. +- L'output finale della pipeline è un file di testo semplice contenente arte ASCII di un personaggio che dice i saluti in maiuscolo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Scrive ogni saluto nel proprio file di output (ad es. "Hello-output.txt") +2. **`convertToUpper`:** Converte ogni saluto in maiuscolo (ad es. "HELLO") +3. **`collectGreetings`:** Raccoglie tutti i saluti in maiuscolo in un singolo file batch +4. **`cowpy`:** Genera arte ASCII utilizzando lo strumento `cowpy` + +La configurazione del workflow supporta la fornitura di input e parametri in modo flessibile e riproducibile. + +### Competenze acquisite + +Attraverso questo corso pratico, avete imparato a: + +- Descrivere e utilizzare i componenti fondamentali di Nextflow sufficienti per costruire un workflow multi-step semplice +- Descrivere concetti successivi come operatori e channel factory +- Avviare un workflow Nextflow localmente +- Trovare e interpretare output (risultati) e file di log generati da Nextflow +- Risolvere problemi di base + +Ora siete equipaggiati con le conoscenze fondamentali per iniziare a sviluppare le vostre pipeline in Nextflow. + +## Prossimi passi per sviluppare le vostre competenze + +Ecco i nostri 3 principali suggerimenti su cosa fare dopo: + +- Applicare Nextflow a un caso d'uso di analisi scientifica con [Nextflow for Science](../nf4_science/index.md) +- Iniziare con nf-core con [Hello nf-core](../../hello_nf-core/index.md) +- Esplorare funzionalità Nextflow più avanzate con le [Side Quests](../side_quests/index.md) + +Infine, vi consigliamo di dare un'occhiata a [**Seqera Platform**](https://seqera.io/), una piattaforma basata su cloud sviluppata dai creatori di Nextflow che rende ancora più facile avviare e gestire i workflow, oltre a gestire i dati ed eseguire analisi in modo interattivo in qualsiasi ambiente. + +## Sondaggio di feedback + +Prima di procedere, dedicate un minuto per completare il sondaggio del corso! Il vostro feedback ci aiuta a migliorare i nostri materiali formativi per tutti. + +[Vai al sondaggio :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/it/docs/hello_nextflow/survey.md b/docs/it/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..51ea74bcef --- /dev/null +++ b/docs/it/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Sondaggio di feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Prima di procedere, completate questo breve sondaggio di 5 domande per valutare la formazione, condividere eventuali feedback sulla vostra esperienza e farci sapere cos'altro potremmo fare per aiutarvi nel vostro percorso con Nextflow. + +Questo dovrebbe richiedere meno di un minuto per essere completato. Grazie per aiutarci a migliorare i nostri materiali formativi per tutti! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/it/docs/hello_nextflow/transcripts/00_orientation.md b/docs/it/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..9b418d74cb --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Orientamento - Trascrizione Video + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Nota importante" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, torni al [materiale del corso](../00_orientation.md). + +## Benvenuto + +Salve, benvenuto a Hello Nextflow. Mi chiamo Phil Ewels. Sono Product Manager per Open Source in Seqera, e sono lieto di essere qui oggi per accompagnarla attraverso questo primo corso di formazione su Nextflow. + +Esamineremo le basi di Nextflow, spiegando come scrivere ed eseguire pipeline e come configurarle. + +E costruirà la sua semplice pipeline multi-step. Tratteremo terminologia come operatori e channel factories, e alla fine del corso, sarà pronto per iniziare a costruire le sue pipeline bioinformatiche. + +Se ha domande, la preghiamo di contattarci su community.seqera.io. Abbiamo una comunità Nextflow molto attiva con una sezione dedicata alla formazione, quindi ci faccia sapere dove ha difficoltà e qualcuno sarà in grado di aiutare. + +Bene. Iniziamo. + +## Sito Web di Formazione + +Tutto il materiale di formazione per i corsi Nextflow si trova su training.nextflow.io. Può accedervi nel suo browser web. Lo avvii ora e possiamo dare un'occhiata. + +Eseguirò questo con la versione 2.1.1. Pubblichiamo piccoli aggiornamenti e correzioni qua e là, quindi non si preoccupi se è leggermente diverso, ma se il materiale è troppo cambiato, può sempre usare questo selettore di versione in alto per scegliere la versione esatta dei materiali che tratterò. + +Se preferisce la modalità chiara, può cambiare il tema del sito web qui. + +Veda le traduzioni qui, anche se al momento della registrazione, è disponibile solo in inglese, che copre questo nuovo materiale. + +E veda anche tutto il codice sorgente per il sito web di formazione e tutto ciò con cui lavoreremo su GitHub. + +La homepage qui elenca tutti i diversi corsi di materiale di formazione che abbiamo. Quindi scorrendo verso il basso, vedremo Nextflow per principianti con il corso Hello Nextflow che faremo qui. Può vedere tutti gli altri corsi che abbiamo anche, che funzionano in modo simile. + +## Configurazione dell'Ambiente + +In realtà inizierò usando questo primo in alto, che è comune per tutti i corsi di formazione, e riguarda specificamente la configurazione del nostro ambiente. + +Cliccando, mi porta a questa sezione, e possiamo vedere le istruzioni per sviluppare localmente. Se vuole usare il suo laptop con la sua copia di VS Code e le sue installazioni software, o quello che ci aspettiamo che facciano la maggior parte delle persone, che è usare qualcosa chiamato GitHub Codespaces. + +Codespaces è un servizio fornito da GitHub dove eseguono un server web nel cloud, a cui può connettersi. Quel server ha VS Code installato, dove può eseguirlo nel suo browser web, o se preferisce, connetterlo alla sua installazione locale di VS Code. Tutti i calcoli, tutti i file, tutte le modifiche avvengono in remoto, il che significa che tutto il software di cui ha bisogno viene preinstallato ed è lo stesso per tutti. + +## Creazione di un GitHub Codespace + +Per creare il codespace con tutto ciò di cui abbiamo bisogno, cerchi i pulsanti nei documenti del materiale, che dicono "Open in GitHub Codespaces". Cliccherò ora, aprendolo in una nuova scheda. E mi viene presentata questa pagina web. Ora può vedere che è preconfigurato per essere impostato con nextflow-io training. + +Posso semplicemente cliccare crea nuovo codespace. Ma in realtà raccomandiamo di usare una macchina leggermente più grande per la formazione Nextflow con quattro CPU invece di due. Può cambiare quale versione del materiale utilizza. Quindi questo è predefinito su 2.1.1 perché è la versione dei documenti da cui ho seguito il collegamento. Ma potrei anche impostarlo su un branch specifico del repository se voglio. + +Ora cliccherò crea codespace. E inizierà a configurare l'ambiente per me. + +## Creazione del Codespace + +Ora, la prima volta che lo fa, ci vorrà parecchio tempo, quindi ora è un buon momento per andare a prendere una tazza di tè. Si metta comodo, chiacchieri con la persona seduta accanto a lei. + +Se è interessato, può cliccare building codespace qui sotto per vedere i log della configurazione. E può vedere qui che sta scaricando un'immagine Docker con tutto ciò di cui ho bisogno e configurando l'ambiente. + +Ora, deve aspettare così solo la prima volta che crea un codespace. Se va su github.com/codespaces qui, vedrà tutti i diversi Codespaces che ha aperti. Ecco quello che ho appena creato. La prossima volta che lo fa, può andare qui e può selezionare il codespace precedente e tornare direttamente ad esso. Ed è un processo molto, molto più veloce per avviare quell'ambiente esistente. Questo manterrà anche tutte le modifiche che ha apportato a VS Code e ai file, quindi non perderà i suoi progressi se esce e torna. + +Può cliccare i tre punti qui per eseguire altre azioni. Ad esempio, se l'ha configurato con due CPU e ora ne vuole quattro, può cambiare il tipo di macchina. O se vuole ricominciare da capo e da zero, può eliminare il codespace. + +## Introduzione a VS Code + +Okay, Codespaces ha finito di configurare il mio ambiente e ora mi viene presentato VS Code nel browser web. + +Se è abituato a VS Code. Questo sembrerà molto familiare se non l'ha mai usato prima, è abbastanza semplice. Ci sono alcune parti diverse della pagina di cui deve essere consapevole. + +Qui a sinistra, abbiamo la barra laterale. Può vedere l'Explorer configurato con tutti i diversi file nel repository GitHub dal repository di formazione. + +Su questi pulsanti in basso a sinistra, possono esserci strumenti diversi. Nella barra laterale. Posso cercare tutti i file in tutto il progetto. Posso lavorare con Git, posso lavorare con GitHub, tutte cose diverse come quella. + +In alto qui c'è il menu principale. L'esploratore di file è quello che avremo aperto per la maggior parte del tempo qui, e può fare clic destro su uno qualsiasi di questi file e fare le cose normali che si aspetterebbe. Potrebbe dover cliccare attraverso alcuni avvisi come questo dove dice taglia copia e può anche scaricare sulla sua macchina locale. + +Quando il codespace si carica, ci dà un'anteprima del file markdown in quest'area principale qui. Questo è proprio lo stesso di quello che viene visualizzato su github.com. Posso chiuderlo e se faccio doppio clic su quel file Readme, vedrà che lo apre come codice nell'editor di codice e proprio come con qualsiasi altro file, possiamo modificare questo codice direttamente. + +Infine qui in basso, abbiamo la finestra del terminale. Stavo guardando i log mentre si costruiva, quindi è quello che sta mostrando la cosa corrente. Posso anche premere questo pulsante più per avviare una nuova sessione di terminale. Questo non è in esecuzione sulla mia macchina. Ricordi, questo è in esecuzione nel cloud, e se faccio tree tre alla profondità di due, vedrà tutti gli stessi file qui, che erano sulla sinistra. + +## Mostrare solo i file "hello-nextflow" + +Questo repository GitHub contiene tutti i diversi set di formazione, non solo quello che stiamo facendo. Quindi se vuole, può concentrarsi solo sulla cartella Hello Nextflow. Un modo per pulire un po' questo è andare al menu file e poi aggiungere cartella all'area di lavoro. + +Facciamo clic su quello, andiamo a training. Hello nextflow, e clicchiamo aggiungi. Aggiornerà il suo schermo. E poi nell'Explorer, ora abbiamo due diverse aree di lavoro, quella che avevamo prima per training e una con solo Hello Nextflow. + +Se vuole, può fare clic destro su training e fare clic su rimuovi cartella dall'area di lavoro per eliminarla completamente dalla barra laterale. + +Ora abbiamo solo i file per questo particolare corso di formazione nella barra laterale. Posso nascondere quell'avviso e ora posso fare la stessa cosa nel terminale qui e fare CD per cambiare directory. Hello, Nextflow. E di nuovo, abbiamo gli stessi file qui, che sono nella barra laterale. + +## Hello Nextflow: file + +Guardando questi file per il corso Hello Nextflow. + +Abbiamo un gruppo di file .nf, che sono per Nextflow, e c'è uno di questi file per ciascuno dei capitoli del corso di formazione. Lavoreremo su questi file e li modificheremo negli esercizi. + +Abbiamo anche un file nextflow.config, che ha solo impostazioni di configurazione di base per eseguire Nextflow in questo ambiente, di cui non deve davvero preoccuparsi a questo punto. Un file greetings.csv, che useremo per elaborare i dati, che verrà introdotto nella prossima parte di questo corso, e un file test-params.json, che verrà utilizzato nella parte sei e che può ignorare per ora. + +Questi file Nextflow sono solo l'inizio di ogni esercizio. Se vuole vedere come dovrebbero apparire quando sono finiti, può andare in una directory solutions e ci sono le risposte per ogni parte del corso di formazione, quindi può vedere una versione funzionante di ciò che sta cercando di raggiungere. + +## Apertura di un terminale + +Se in qualsiasi momento chiude il terminale e non riesce a ricordare come tornare indietro, non si preoccupi. Questi pulsanti in alto a destra aprono e chiudono diversi pannelli nell'area di lavoro. Quindi clicchi questo per il pannello inferiore e riapparirà. E si assicuri solo di aver selezionato terminal qui. Può anche cliccare questo pulsante qui, la freccia sul lato destro del terminale per renderlo a schermo intero. + +Mi vedrà farlo molto spesso perché ho VS Code ingrandito in modo che possa leggere il testo. A seconda delle dimensioni del suo schermo, potrebbe o meno aver bisogno di farlo. Lo stesso vale per ridurre al minimo il pannello laterale. + +Bene. Questo è abbastanza per l'ambiente. Penso che siamo pronti per iniziare. Mi raggiunga nel prossimo video per il capitolo uno. + +[Prossima trascrizione video :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/it/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..8d9dd56ff1 --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Parte 1: Hello World - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, tornare al [materiale del corso](../01_hello_world.md). + + I numeri delle sezioni mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuti + +Salve, benvenuti al Capitolo Uno di Hello Nextflow. + +In questa prima parte di un corso di sei parti, esamineremo le basi fondamentali di Nextflow. Inizieremo eseguendo alcuni comandi in un terminale, e poi prenderemo quei comandi Bash e vedremo come integrarli in uno script Nextflow. + +Proveremo ad eseguire quella prima pipeline Nextflow, vedremo cosa fa Nextflow, dove viene eseguito, quali file crea e qual è lo scopo di quei file. + +Bene, cominciamo. + +## training.nextflow.io + +Prima di tutto, andate su training.nextflow.io. Proprio come prima, tutto il materiale è scritto qui, e lo seguirò passo dopo passo. Mostrerò il mio schermo mentre eseguo i passaggi della formazione, ma tutto ciò che sto dicendo è nel materiale di formazione quindi potete seguirlo al vostro ritmo, e potete trovare tutto scritto lì. + +Questo video ha anche i sottotitoli abilitati, quindi sentitevi liberi di attivarli e seguire esattamente ciò che sto dicendo mentre lo dico. + +Okay, andiamo a Hello Nextflow. Questo è il corso che faremo oggi, e abbiamo già fatto l'orientamento nel primo video, quindi andremo direttamente alla parte uno. Hello World. + +Okay, lascerò ora questo materiale di formazione e passerò al mio ambiente Code Spaces. Questo è ciò che abbiamo configurato nel primo video. Spero che abbiate qualcosa di molto simile a questo nel vostro sistema. Sto usando VS Code e sto guardando il materiale di formazione e ho cambiato directory nella directory hello Nextflow. + +## 0. Riscaldamento: Eseguire Hello World direttamente + +Okay. Iniziamo con un paio di nozioni di base, che si spera sembrino familiari a tutti. Inizierò semplicemente scrivendo un comando molto semplice nel terminale. Qui sotto dirò 'echo Hello World!"' premo invio e, senza sorprese, il terminale fa quello che chiedo e restituisce quella stringa. Hello world. + +Okay, poi premerò su per ottenere quel comando e lo modificherò un po'. Questa volta reindirizziamo quell'output a un file. Lo scriverò invece in output.txt e premerò invio niente sul terminale questa volta perché l'output non è arrivato al terminale. È andato in quel file. + +Posso poi leggere quel file facendo 'cat output.txt' premo tab lì per espandere automaticamente il nome del file ed ecco fatto. Il file è lì. + +Posso anche vedere quel file nella barra laterale nell'esploratore file in VS Code. Posso farci doppio clic e aprirlo qui. Se volete aprirlo in VS Code senza cliccare nulla, potete anche fare "code" e poi "output.txt" e fa la stessa cosa. + +Ottimo. Questo è il primo passo. Molto semplice. + +## 1. Esaminare lo script iniziale del workflow Hello World + +Okay. Ora faremo esattamente la stessa cosa, ma in Nextflow, invece che direttamente nel terminale. + +Useremo il primo script di esempio per iniziare, questo file si chiama Hello World. Posso fare "ls" per visualizzarlo in un terminale, e sono su Mac, quindi posso fare comando clic per aprire quel file, o avrei potuto semplicemente fare doppio clic nella barra laterale qui. + +Ci sono alcune cose che possiamo vedere in questo file. Proprio in alto, c'è un'istruzione hash che dice che questo è un file Nextflow e che potrebbe essere eseguito. Ci sono alcuni commenti qui, solo commenti di codice normali in grigio chiaro, che non influenzano l'esecuzione, e aiutano solo a leggere lo script. + +E poi ci sono due strutture principali. C'è un process qui e un workflow. + +I processes in Nextflow sono i passaggi della pipeline. Sono le parti che effettivamente eseguono la logica e fanno l'elaborazione. + +Il workflow poi in basso unisce questi processes e governa la logica del workflow, come tutto si connette l'uno all'altro. + +Inizieremo guardando un process. Torneremo al workflow tra un momento. + +## 1.2 La definizione del process + +Quindi ogni process inizia con una parola chiave process. Ha un nome e poi ha alcune parentesi graffe e tutto all'interno di quelle parentesi graffe è quel singolo process. + +Un process deve avere una sezione script, e qui contenuto c'è uno snippet bash in una stringa multilinea, che è la parte del codice che viene effettivamente eseguita nell'ambiente di calcolo. + +Abbiamo anche un'istruzione output qui, che dice a Nextflow quali file sono previsti essere creati dallo script. Notate che l'output qui ha una parola chiave path, che dice a Nextflow che questo è un file, non un valore, o una stringa. + +All'interno del blocco script, questa è solo un'istruzione bash normale, ed è esattamente la stessa di quella che abbiamo scritto nel terminale. Stiamo facendo echo di hello world in un file chiamato output.txt. Questo output.txt viene poi raccolto dalla definizione di output. La definizione di output in realtà non sta facendo nulla. Sta solo dicendo a Nextflow cosa aspettarsi, e se questo file non fosse stato creato, Nextflow avrebbe generato un errore. + +Notate che questo esempio non è ottimo perché abbiamo codificato rigidamente il nome del file qui, output.txt e output.txt. Se uno di questi fosse stato modificato, ciò avrebbe causato un errore nel nostro workflow. + +C'è un modo migliore per farlo con variabili, che tratteremo tra un minuto. + +## 1.3 La definizione del workflow + +Okay. Scendendo al workflow, possiamo vedere che abbiamo un commento e poi eseguiamo il process chiamato sayHello. Questa è la stessa parola chiave che è qui sopra. Questo è semplice quanto può essere un workflow. Stiamo solo chiamando un singolo process senza input variabili, quindi non lo stiamo collegando a nient'altro. Nella parte successiva di questo corso, parleremo di come rendere questo più potente usando input variabili e collegando le cose con i channels. + +## 2. Eseguire il workflow + +Okay, questo è tutto ciò di cui abbiamo bisogno. Vediamo se possiamo eseguirlo e vedere cosa succede. Pulirò solo il terminale e poi farò "nextflow run", e chiamerò il nome del file, che è hello-world.nf. Questo è tutto ciò di cui abbiamo bisogno per eseguire una pipeline Nextflow. Questa pipeline non prende alcun input, quindi non abbiamo bisogno di altri argomenti. + +Premiamo invio e vediamo cosa succede. + +Okay. Si spera che abbiate un output che assomigli a questo. Abbiamo alcune informazioni che ci dicono che Nextflow è stato eseguito e quale versione stava usando. Ci dice quale script è stato lanciato e ci dà un nome generato casualmente per questa particolare esecuzione del workflow. In questo caso, il mio si chiamava "gloomy_crick". + +La parte più importante però, è che ci dice quali passaggi sono stati eseguiti nella pipeline. Potete vedere che il nostro process chiamato sayHello è stato eseguito, ed è stato eseguito una volta ed era completo al cento per cento. + +Questa parte qui è l'hash per quella particolare attività del workflow. Ogni process viene eseguito una o più volte, e ciascuna di quelle esecuzioni è chiamata attività. + +## 2.2. Trovare l'output e i log nella directory di lavoro + +Ogni attività ottiene la propria directory isolata dove viene eseguita, quindi è separata dal resto dell'esecuzione del workflow. Questo hash corrisponde alla struttura dei file all'interno della directory di lavoro. Se faccio "tree work", possiamo vedere a0, e poi una versione più lunga di un hash breve, e poi il nostro file output.txt. Potete anche vederlo in una barra laterale. + +Potete vedere nella barra laterale che ci sono alcuni file aggiuntivi qui. Il motivo per cui questi non sono apparsi in un terminale è perché sono file nascosti, iniziano con un punto. E infatti, se faccio "tree -a" per tutti, e "work", possiamo vederli qui. + +Questi file punto sono presenti in ogni singola directory di lavoro. Che Nextflow crea, e ognuno ha un'attività leggermente diversa. In primo luogo .command.begin include solo alcune istruzioni per Nextflow che configura l'attività prima che venga eseguita. .command.run sono le istruzioni effettive eseguite da Nextflow stesso. Poi .command.sh è probabilmente quello più interessante. Questo è lo script che è stato risolto dal nostro blocco script del process. + +Se lo apro, potete vedere che abbiamo il nostro "echo Hello World" nel file output.txt. Questo è esattamente lo stesso del nostro process in questo caso, ma se abbiamo variabili all'interno del nostro codice Nextflow, ogni attività avrà un .command.sh diverso, e potete vedere come quelle variabili sono state risolte. + +Gli altri file riguardano come l'attività è stata eseguita. Quindi .command.err, .log e .out sono l'errore standard, l'output standard e i due combinati. E .exitcode dice a Nextflow come questa attività è stata eseguita con quale codice di uscita, se è riuscita o meno. + +Infine, abbiamo il nostro file output.txt e certamente, "Hello World" questo è ciò che ci aspettavamo e questo è ciò che è stato creato. + +Okay, ottimo. Questa è stata la vostra prima esecuzione Nextflow. Congratulazioni. È davvero così semplice. + +Successivamente, vedremo come farlo in modo un po' più conveniente in modo da non dover modificare il codice ogni volta che vogliamo apportare una modifica al modo in cui viene eseguita la pipeline. + +## 3. Gestire le esecuzioni del workflow + +Questa struttura di directory è ottima per mantenere tutte le attività separate e tutto organizzato, ma ovviamente non è molto conveniente trovare i file di output. Non volete scavare attraverso molte directory nidificate cercando di trovare i risultati della vostra pipeline. + +## 3.1. Pubblicare gli output + +La buona notizia è che non è previsto che lo facciate. Le directory di lavoro sono davvero solo per Nextflow da usare. Quindi quello che faremo è che useremo una funzione di Nextflow chiamata "publishDir". + +Torniamo al nostro workflow, andiamo al process. Possiamo aggiungere una nuova istruzione qui chiamata direttiva. Questo è ciò che Nextflow chiama queste cose in cima ai processes che aumentano il funzionamento, e quella che useremo si chiama publishDir. + +Potete vedere che ho iniziato a digitare qui e l'estensione Nextflow per VS Code mi ha suggerito la direttiva, quindi posso semplicemente premere invio. + +Okay, seguirò questo con una directory chiamata "results" e le diremo di copiare i file di output lì. Quindi dirò mode copy. Ottimo. premerò salva e rilanciamo il workflow. + +nextflow run hello-world.nf + +Viene eseguito esattamente allo stesso modo. Anche se notate abbiamo un hash leggermente diverso questa volta. Nextflow utilizzerà un hash diverso ogni volta che eseguite il workflow. E abbiamo un insieme diverso di directory di lavoro di conseguenza. Aree, una chiamata EB invece, ma potete vedere che tutti i file sono gli stessi. Tuttavia, ciò che è nuovo questa volta è che abbiamo anche una directory chiamata "results". + +All'interno di "results" qui abbiamo il nostro file di output. Questo è ciò che abbiamo detto a Nextflow di fare. Abbiamo detto, salva i file di risultati in una directory chiamata "results" e copiali lì. E quindi questo è ora molto più facile da trovare. È proprio lì accanto a dove abbiamo lanciato un workflow e tutti i diversi file possono essere organizzati lì come desideriamo, indipendentemente da dove o come Nextflow ha eseguito l'esecuzione effettiva. + +Notate che publishDir può gestire symlink, il che è buono se state lavorando su un file system condiviso e volete risparmiare spazio. E inoltre non dovete definire tutti i file che vengono creati da un process come output. + +Nextflow copierà solo le cose che sono definite in questo blocco output. Quindi se avete file intermedi creati dal passaggio, che non sono necessari a valle di questo process, semplicemente non li definite in output e non appariranno nel publishDir. Quindi questo è un modo per mantenere i vostri file di output da una pipeline puliti e eliminare facilmente i file intermedi una volta terminato il posto di lavoro. + +Una nota rapida qui. C'è una nuova sintassi Nextflow in arrivo chiamata workflow output definitions, che alla fine sostituirà publishDir. Questo ci dà un modo per definire tutti gli output da un workflow a livello di pipeline giù nel blocco workflow. Questo è descritto nei documenti Nextflow se volete provarlo. Ma per ora, publishDir sarà in circolazione per un po', quindi lo manteniamo ancora nella formazione per il 2025. + +## 3.2. Rilanciare un workflow con -resume + +Okay. Ho menzionato che la directory di lavoro qui ora ha due serie di risultati con un hash diverso da ogni volta che eseguiamo il workflow. Questo è buono. Tuttavia, a volte non vogliamo ricalcolare i passaggi ogni volta se non ne abbiamo bisogno. + +Forse state costruendo iterativamente il vostro workflow e state aggiungendo passaggi e volete che i primi passaggi riutilizzino semplicemente le versioni memorizzate nella cache. O forse qualcosa è andato storto sul vostro sistema di calcolo a metà del vostro workflow e volete che continui da dove si era interrotto, ma saltando i passaggi che aveva già completato. + +Nextflow ha funzionalità integrate per questo chiamate resume. Proviamole. Quindi prima di tutto, darò solo un'occhiata alla directory di lavoro così possiamo ricordare cosa c'era. + +E poi farò "nextflow run hello-world.nf" e aggiungerò un singolo comando qui, "-resume". + +Notate, singolo trattino, questo è davvero importante. Lo eseguirò e l'output sembrerà fondamentalmente esattamente lo stesso, con un paio di piccole differenze. + +Notate qui dice "cached" in grigio. Ciò significa che Nextflow non ha eseguito l'attività. Questa volta ha trovato qualcosa che corrispondeva ai requisiti e ha riutilizzato direttamente quegli output piuttosto che rieseguire il passaggio. + +E certamente, se guardate l'hash qui, potete vedere che questo corrisponde all'hash esistente che avevamo da un'esecuzione precedente. + +## 3.3. Eliminare le directory di lavoro precedenti + +Okay. Ma se state sviluppando in modo iterativo, accumulerete molti di questi file del workflow. Questo può essere un problema se potreste essere a corto di spazio. + +Nextflow può aiutarci a pulire queste directory di lavoro con un paio di comandi di aiuto. Se faccio "nextflow log". Questo mi darà un elenco di tutte le diverse esecuzioni del workflow che ho fatto in questa directory, e hanno i nomi di esecuzione qui. Potete vedere quello gloomy quick, che è stato il primo che abbiamo eseguito, e poi questi due nuovi. + +Possiamo ora prendere quel nome e usarlo con il comando "nextflow clean". Posso specificare un singolo nome di esecuzione. O ancora meglio, posso dire a Nextflow di eliminare tutto da prima di un singolo nome del workflow con "-before", e inserirò "stupefied_shaw". Quella è stata la mia esecuzione più recente, "-n". + +Il comando "-n" ha detto a Nextflow di farlo come prova senza eliminare effettivamente nulla per davvero, e ci dice quali delle directory hash sarebbero state rimosse. Certamente, è solo quella della prima esecuzione. Entrambe le seconde esecuzioni usano la stessa directory hash. + +Lo eseguirò di nuovo, ma ora invece di "-n" per prova, farò "-f" per forzare e ha rimosso quella directory hash. Ora se faccio "tree work", possiamo vedere, abbiamo solo questo file di output rimasto. + +Ottimo. Quindi siamo riusciti a pulire un sacco di spazio su disco lì. + +Un paio di cose da notare quando si eliminano le directory di lavoro, se fate symlink di cose alla vostra directory di risultati, quelle fonti di symlink saranno ora eliminate e i vostri risultati saranno persi per sempre. Quindi ecco perché usare la modalità copy è una cosa più sicura da fare, e generalmente ciò che raccomandiamo. + +In secondo luogo, la funzionalità resume di Nextflow si basa su queste directory di lavoro. Quindi se le eliminate e eseguite di nuovo Nextflow, la funzionalità resume non funzionerà più. Quindi sta a voi tenere traccia di quali cose potreste avere bisogno o meno, ed eliminare le cose solo quando siete sicuri che sia sicuro farlo. + +L'altra cosa che possiamo fare è che possiamo semplicemente eliminare l'intera directory di lavoro se abbiamo terminato l'esecuzione del nostro workflow e siamo sicuri di non averne più bisogno. + +Quindi posso fare "rm -r work". So che non c'era nulla di importante lì. Ho i miei risultati che mi interessano nella directory results dove li abbiamo copiati. E quindi era sicuro eliminare la directory di lavoro. Sta a voi quale di questi approcci usate. + +## 4. Usare un input variabile passato sulla riga di comando + +Okay, cosa c'è dopo? Ho menzionato che avevamo codificato rigidamente alcuni dei valori nel nostro script del workflow qui, il file output.txt, e che potrebbe esserci un modo migliore per farlo. + +Iniziamo con questo. Quello che faremo sono tre cose. Aggiungeremo un nuovo input al process. Diremo allo script del process come usare quell'input, e poi lo collegheremo nel workflow in modo da poterlo usare dinamicamente con un flag della riga di comando quando eseguiamo Nextflow. + +Quindi prima di tutto. Aggiungiamo un blocco input qui. Proprio come output. Questa è una nuova sezione per il process, e dirò, "val greeting". + +Notate qui, sto dicendo "val", che dice che questa è una variabile, non un path. + +Posso poi scendere nello script e poi posso togliere questo testo codificato rigidamente qui e fare $greeting. Questo funziona proprio come qualsiasi altro linguaggio di programmazione. Stiamo definendo una variabile qui e la stiamo referenziando all'interno di questo blocco script. Quando Nextflow esegue questo process, la variabile sarà interpolata. E quando andiamo a guardare quel file .command.sh, vedremo la stringa effettiva codificata rigidamente qui invece. + +## 4.1.3. Configurare un parametro CLI e fornirlo come input alla chiamata del process + +Okay, ma dove forniamo la variabile? Successivamente andiamo giù alla sezione workflow, e potete vedere che l'estensione qui sta dicendo, ora ci aspettiamo un input, e mi ha dato un avviso. + +Ora, la cosa più semplice che potremmo fare è semplicemente codificarlo rigidamente. Potrei scrivere "Hello World" e fornire quell'input stringa al process. Ma ancora, questo non risolverebbe davvero alcun problema. Dovremmo ancora tornare indietro e modificare il codice della pipeline ogni volta che vogliamo cambiare qualcosa, il che non va bene. + +La buona notizia è che Nextflow ha un sistema integrato per gestire gli argomenti della riga di comando chiamati parametri. Quindi invece, posso usare una di queste variabili speciali chiamate params e posso chiamarla come voglio, ma dirò greeting in modo che corrisponda alla logica del workflow. + +Premo salva e vediamo cosa possiamo fare con questo. + +Quindi se torno al terminale. Quindi facciamo "nextflow run hello-world.nf". Proprio come prima, ma la differenza chiave è che facciamo --greeting + +Notate, ci sono due trattini qui perché questo è un parametro. Quando abbiamo ripreso il workflow prima, era un singolo trattino. Questo perché resume è un'opzione core di Nextflow, e questo è un parametro che è specifico per la nostra pipeline. + +Non confondete i due. È facile farlo. Se faceste --resume invece di un solo trattino, allora sarebbe "params.resume", che non farebbe nulla. Allo stesso modo, se faceste un singolo trattino qui, Nextflow non lo riconoscerebbe come argomento chiave. + +Quindi è --greeting, che corrisponde a parameters greeting. + +Posso ora seguire quello con qualsiasi testo voglio. Quindi sono in Svezia al momento, quindi dirò, "Hej världen". + +Quindi eseguiamolo, vediamo cosa succede, momento della verità. + +Okay, quindi potete vedere che il process è stato eseguito di nuovo, proprio come prima, sayHello con una singola esecuzione. + +Questo avrà sovrascritto il file che era nella directory publishDir "results". E quindi fate attenzione quando rieseguite i file perché le cose nella directory pubblicata verranno sovrascritte. + +Posso ora fare "code results/output.txt", e certamente, il nostro output è stato aggiornato e ora dice "Hej världen". + +## 4.2. Usare valori predefiniti per i parametri della riga di comando + +Okay, questo è ottimo. Ma il problema ora è che il nostro workflow si basa sul fatto che definiamo sempre questo parametro, ed è bello avere valori predefiniti sensati in modo che le cose vengano eseguite in modo sensato per il vostro workflow a meno che non sovrascriviate i valori predefiniti. + +Quindi il modo in cui lo facciamo è impostando un valore predefinito per il parametro nel nostro script del workflow. + +Quindi se torno al mio file hello-world.nf, posso andare nello script appena sopra workflow, digitare "params.greeting" e definirlo come qualsiasi altra variabile. Quindi mettiamo una stringa qui e diciamo "Holà mundo!" + +Ora questo parametro ha un valore predefinito definito, che sarà usato qui, o possiamo ancora sovrascriverlo sulla riga di comando con --greeting, proprio come abbiamo fatto prima. + +Quindi verifichiamo che funzioni. "nextflow run hello-world.nf" + +Nessun argomento della riga di comando questa volta, e verifichiamo se ha fatto la cosa giusta. + +"code results/output.txt". Ed eccolo. Abbiamo il nostro valore predefinito. + +Okay, proviamo di nuovo, solo per verificare che non vi stia dicendo bugie. Eseguiamolo di nuovo, ma facciamo --greeting, e usiamo l'esempio dal materiale di formazione, diciamo "Konnichiwa!" + +Riesegue il workflow, e certamente, il nostro file di output in alto è appena stato aggiornato con il nuovo valore che abbiamo fornito sulla riga di comando. + +Ottimo. Questo è un aspetto davvero centrale nella scrittura di qualsiasi workflow Nextflow. Definire valori predefiniti sensati nel codice della pipeline, ma renderlo molto facile da configurare per l'utente finale avendo argomenti della riga di comando sul terminale. + +Notate che l'utente finale può sovrascrivere la configurazione in più posti diversi. Potete avere un file di configurazione nella vostra directory home, che viene applicato a ogni singola esecuzione Nextflow che fate. Potete avere un file di configurazione in una directory di lancio. Potete avere un file di configurazione in una directory della pipeline. Tutte queste diverse posizioni di configurazione vengono caricate in un ordine specifico, che è descritto nei documenti Nextflow. + +Okay, questa è la fine della sezione uno. Abbiamo avuto il nostro primo script del workflow in Nextflow con un process e un workflow. Abbiamo esaminato input, output, script e pubblicazione, e come collegare parametri e un canale di input nel nostro process. + +Congratulazioni, il vostro primo passo verso la scrittura di codice Nextflow è completo. + +Fate una piccola pausa e ci vediamo tra qualche minuto per il capitolo due. + +[Trascrizione video successiva :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/it/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..5d4affe367 --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Parte 2: Hello Channels - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, ritorni al [materiale del corso](../02_hello_channels.md). + + I numeri di sezione mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuto + +Salve, benvenuti alla parte due di Hello Nextflow. + +Questo capitolo si chiama Hello Channels. Parleremo di questo aspetto fondamentale di Nextflow. + +I channel sono gli elementi che collegano i diversi passaggi nella sua pipeline, il modo in cui i suoi dati e la logica fluiscono attraverso il suo workflow. + +Bene, iniziamo. + +Iniziamo andando su training.nextflow.io + +Hello Nextflow nella barra laterale e facendo clic sulla parte due, Hello Channels. + +Tutto il materiale è scritto qui, così può seguire al suo ritmo e recuperare qualsiasi cosa possa aver perso. + +Una volta aperto il sito web, può caricare Codespaces e continueremo da dove eravamo rimasti alla fine del capitolo precedente. + +## 0. Riscaldamento: Eseguire hello-channels.nf + +Per questo capitolo, modificheremo un file diverso. Questo si chiama Hello Channels, quindi può trovarlo nella barra laterale, faccia doppio clic per aprirlo. + +Ora, se proviene appena dal capitolo uno, questo file le sembrerà molto familiare. Il punto di partenza qui è sostanzialmente dove finiamo il capitolo uno, con il nostro process chiamato sayHello, il nostro input, output, il nostro publishDir e il nostro params.greeting, e il nostro workflow semplice. + +Stiamo iniziando con un nuovo file, quindi è un terreno di gioco livellato per tutti, ma può continuare con il suo file precedente se preferisce. + +Nota, ho anche eliminato tutti i file .nextflow\* e le directory work qui, solo per avere un punto di partenza pulito. Non importa se lo fa o no, dipende da Lei. + +Bene. Iniziamo verificando che questa pipeline funzioni ancora come ci aspettiamo. Porterò su il terminale qui. + +Faccio "nextflow run hello-channels.nf" e premo invio. + +Eseguirà quel piccolo workflow, esegue il nostro passaggio sayHello, genera una directory work con quell'hash, ed ecco la nostra cartella results e c'è il nostro file di output, proprio come ci aspettavamo dal nostro params.greeting predefinito. + +Quindi è ottimo. Esattamente come nel capitolo uno, funziona come ci aspettiamo. + +## 1. Fornire input variabili tramite un channel in modo esplicito + +Nel capitolo uno, stava già utilizzando i channel, solo che non se ne rendeva conto. Quando abbiamo specificato una stringa qui, Nextflow ha automaticamente creato un channel attorno a quella stringa per noi, proprio perché sapeva che stavamo chiamando un process, quindi avevamo bisogno di un channel di input. + +La prima cosa che faremo è renderla esplicita scrivendo effettivamente il channel stesso. + +## 1.1. Creare un channel di input + +Quindi andrò al workflow qui in fondo allo script, e dirò greeting_ch. Questa è una convenzione che spesso usiamo nel codice Nextflow: avere un underscore ch alla fine di un nome di variabile quando è un channel, solo per rendere facile identificare che è un channel, ma non è obbligatorio farlo. Uguale channel of Hello Channels. + +Quello che abbiamo appena usato è qualcosa chiamato "Channel Factory" nel linguaggio Nextflow. È questa cosa qui, stiamo impostando questa variabile su un nuovo channel, e questa channel factory qui sta creando un channel per noi in un modo particolare. + +Ci sono una manciata di diverse channel factory che Nextflow ha, per creare channel da diversi tipi di input. Dot of è la più semplice, e accetta semplicemente qualsiasi stringa che le forniamo. + +Noti che quando passo il mouse su queste parole in VS Code, l'estensione Nextflow mi sta dando un popup che spiega cosa fa questa sintassi, e c'è anche un testo "leggi di più" in fondo a quella finestra popup. + +Se faccio clic su quello, aprirà la documentazione Nextflow in una nuova scheda e mi porterà direttamente alla documentazione per questa cosa specifica. In questo caso per channel.of. + +## 1.2. Aggiungere il channel come input alla chiamata del process + +Noti che l'estensione ci sta anche dando un avviso, dicendo che abbiamo creato un nuovo channel qui, ma non viene utilizzato da nulla. + +Quindi, sistemiamolo. Prenderò il nuovo nome del channel e sostituirò questo params.greeting con il nostro nuovo channel. + +Noti che non stiamo più usando il flag della riga di comando --greeting ora, params.greeting non viene utilizzato, stiamo tornando a codificare questa stringa in modo fisso. Va bene. Sto solo cercando di mantenere le cose semplici. Torneremo più tardi e useremo di nuovo i params. + +## 1.3. Eseguire nuovamente il comando workflow + +Bene, verifichiamo solo che questo funzioni. Portiamo su il terminale e notiamo di nuovo. Nextflow run hello channels. Verifico output.txt, ed eccolo. + +Ottimo, un esempio un po' noioso, che fa esattamente la stessa cosa di prima, ma ora almeno la logica è un po' più chiara. Stiamo essendo espliciti nello scrivere un nuovo channel. + +Abbiamo effettivamente appena scritto più codice per fare la stessa cosa. Ma questo inizierà ad avere più senso man mano che diventiamo un po' più complicati nel modo in cui creiamo i nostri channel. + +## 2. Modificare il workflow per eseguirlo su valori di input multipli + +Bene, rendiamo questo un po' più interessante. È molto raro che si voglia eseguire una pipeline Nextflow su un singolo input, quindi diamogli diversi input. + +## 2.1. Caricare più saluti nel channel di input + +Dalla documentazione qui. Copierò questi diversi stringhe, tre di esse. Hello, Bonjour, Olà. Oh, ottieni Speranza. Copilot sta suggerendo un paio di altri. Quindi premiamo tab e inseriamo quelli. + +La documentazione Nextflow qui ci dice che possiamo dare valori multipli a questo operatore, quindi dovrebbe funzionare, ma proviamolo e vediamo cosa succede. + +## 2.1.2. Eseguire il comando e guardare l'output del log + +Bene. Sì e no. Vediamo. Dice che cinque di cinque attività sono state eseguite qui, ma ci mostra solo un hash, il che è un po' strano. Va bene. Tutto è come previsto qui. Per impostazione predefinita. Nextflow utilizza un tipo speciale di output per un terminale chiamato codici di controllo ANSI, il che significa che sovrascrive determinate righe per dare una bella visualizzazione compressa di tutti i diversi processi che vengono eseguiti. + +Questo ha molto più senso quando si hanno workflow più grandi e si stanno eseguendo centinaia o migliaia di campioni diversi. Si può semplicemente generare così tanto output sul terminale che è impossibile guardarlo, mentre questa visualizzazione di aggiornamento le dà un progresso in tempo reale. + +## 2.1.3. Eseguire nuovamente il comando con l'opzione -ansi-log false + +Se vuole, può eseguirlo di nuovo, e questa volta userò un argomento core Nextflow aggiuntivo con un singolo trattino che dice, "-ansi-log false". Questo utilizza la versione precedente dell'output del log Nextflow. E qui può vedere tutti i processi individuali che sono stati lanciati. + +Sta a Lei decidere se farlo o no. L'output da Nextflow è esattamente lo stesso in entrambi i casi. + +## 2.2. Assicurarsi che i nomi dei file di output siano univoci + +Bene, diamo un'occhiata ai file di output, poi andremo ai results. Ma c'è solo un singolo file di output. Cosa è successo? Abbiamo visto che il process era stato eseguito molte volte. Possiamo andare nella directory work e vedere tutti i diversi hash, tutte le attività sono state eseguite correttamente. Ma se ricorda nel nostro process qui, stiamo salvando tutto in un file output.txt e poi pubblicando quello in questa directory. + +Quindi lo stesso file è stato creato cinque volte, e poi è stato sovrascritto cinque volte. E abbiamo solo qualsiasi attività sia stata eseguita per ultima. + +## 2.2.1. Costruire un nome di file di output dinamico + +Il modo in cui risolviamo questo è utilizzando un nome di file di output dinamico. Qui abbiamo già una variabile chiamata greeting all'interno del process, quindi possiamo usarla nel nome del file di output. La copio e faccio $greeting-output.txt. + +Circonderò questo tra virgolette, solo per evitare che bash si confonda con eventuali spazi che potrebbero insinuarsi qui. E poi prenderò lo stesso nome di file e aggiornerò l'output qui. + +È davvero importante che l'output corrisponda a questo, perché altrimenti, questo file non verrà trovato e Nextflow andrà in crash. + +Farò un'altra modifica davvero importante, che è cambierò questi apici singoli per apici doppi. Noti che il colore del codice è cambiato quando l'ho fatto. Questa variabile viene espansa solo se usiamo apici doppi. Se uso apici singoli qui, viene usata come valore letterale, e otterrei un singolo file chiamato $greeting-output, che non è quello che voglio. + +## 2.2.2. Eseguire il workflow + +Quindi rimettiamo gli apici doppi e proviamo. + +Pulirò solo la mia directory prima di iniziare, così è facile vedere i nuovi file. Eliminerò tutto ciò che si chiama .nextflow, work e results. + +E eseguirò di nuovo quel comando Nextflow e vediamo quali file vengono creati. Quindi esegue i cinque processi là. Se stava guardando molto attentamente, potrebbe aver visto quella riga aggiornarsi mentre era in esecuzione. + +E ora possiamo andare nella directory results, e infatti, abbiamo cinque output diversi, e sono tutti prefissati con il saluto diverso. + +Se apro ognuno di questi, vedremo che ognuno contiene il saluto corrispondente. Fantastico. È quello che vogliamo. + +## 3. Utilizzare un operatore per trasformare il contenuto di un channel + +Bene, quindi ora sappiamo cosa sono i channel e sappiamo cosa sono le channel factory. E gli operatori? Questo è un altro termine per parte del linguaggio Nextflow, che è una serie di funzioni che ci permettono di operare sui channel per fare certe cose con loro. Nextflow, viene fornito con una suite di operatori, che ci permettono di manipolare i channel in una varietà di modi diversi. + +## 3.1. Fornire un array di valori come input al channel + +Lavoriamo attraverso questo con un esempio. Diciamo che vogliamo prendere queste stringhe di input, ma invece di metterle direttamente in una channel factory, vogliamo definirle come un array. + +## 3.1.1. Impostare la variabile di input + +Quindi prenderò queste e lo farò come una nuova riga sopra e dirò, greetings, array. + +Ecco qua. Prenderò quella variabile array e la metterò nel channel.of, e premo salva. + +## 3.1.3. Eseguire il workflow + +Ora, vediamo cosa succede. Torno al mio terminale. Pulirò di nuovo tutti quei file temporanei. E eseguiamo il workflow. + +Non bene. Bene. Si è rotto. Va bene. Me lo aspettavo questa volta. Il debug di cosa va storto quando un workflow Nextflow fallisce è una parte fondamentale dell'essere uno sviluppatore Nextflow. Questo accadrà molto ed è importante capire cosa dice il messaggio di errore e come gestirlo. + +I messaggi di errore Nextflow sono in realtà abbastanza strutturati. Ci dice quale process è andato storto. Ci dà un messaggio di errore per una ragione. Dice quale era il comando che ha cercato di eseguire all'interno di quella particolare attività, quale era lo stato di uscita, quale era l'output su dove si trovava quella directory work dell'attività. + +Noti che posso option, fare clic su questo in VS Code e lo apre in una barra laterale così posso andare direttamente lì e visualizzare tutti questi file nascosti, di cui abbiamo parlato nel capitolo precedente, incluso il file .command.sh. Questo può vedere che è lo stesso dei comandi che è stato eseguito qui. + +Guardando questo file, possiamo avere un'idea di cosa potrebbe essere andato storto qui invece di eseguire una singola attività per ciascun elemento nell'array come ha fatto l'ultima volta, ha semplicemente fornito l'intero array in una volta come una stringa. Quindi dobbiamo decomprimere quell'array in valori individuali prima di passarlo nel channel. Torniamo indietro e vediamo se possiamo farlo usando un operatore. + +## 3.2. Utilizzare un operatore per trasformare il contenuto del channel + +In questo caso, non cambieremo l'array prima di passarlo nel channel. Adatteremo il channel in modo che si comporti nel modo che ci aspettiamo. Lo faremo usando l'operatore flatten può fare dot iniziare a digitare e possiamo vedere che l'estensione VS Code inizia a suggerire tutti i diversi operatori che abbiamo disponibili. + +## 3.2.1. Aggiungere l'operatore flatten() + +E selezionerò flatten. Noti che lo spazio bianco non importa in questo contesto per Nextflow. Quindi può mettere questi operatori su una nuova riga se vuole. Quindi posso far cadere questo qui e indentarlo in modo che si trovi sotto ".of" e vedrà che le persone spesso concatenano molti operatori come questo su un channel e lo indentano in questo modo in modo che sia più facile da leggere. + +Può anche vedere, come prima posso passare il mouse su questo e leggere cosa sta facendo l'operatore flatten, e seguire anche un link alla documentazione se voglio. + +Quindi questo operatore sta prendendo questo channel, che ha un singolo array al suo interno, e separando i valori dell'array. + +## 3.2.2. Aggiungere view() per ispezionare il contenuto del channel + +Possiamo sbirciare nei channel utilizzando lo speciale operatore view, e ne aggiungerò un paio qui. Questo è un po' come usare istruzioni di stampa in altri linguaggi. Quindi farò dot view e poi userò queste parentesi graffe. + +Questo si chiama closure. Questo fondamentalmente fornisce codice aggiuntivo all'operatore view, che eseguirà su ciascun elemento all'interno del channel. In questo caso, dirò greeting before flatten. Greeting. + +Sto definendo una variabile qui, che è solo all'interno dell'ambito di questa closure. Quindi questa variabile viene utilizzata solo qui e potrei chiamarla come voglio. Non importa davvero. Sto solo usando greeting per renderla facile da leggere. + +In alcune pipeline Nextflow, potrebbe vedere persone usare una variabile implicita speciale chiamata "$it". Così. Questa è una variabile speciale all'interno del codice Nextflow, che è una scorciatoia in modo da non dover fare la piccola definizione di una variabile. Tuttavia, nel tempo stiamo pensando, questo non è molto chiaro per le persone che sono nuove a Nextflow, e scoraggiamo l'uso di "$it" ora. + +Quindi mi atterrò al comportamento precedente di greeting e lo userò così perché è più esplicito ed è più chiaro su cosa sta succedendo. + +Copierò quindi questa riga e farò esattamente la stessa cosa di nuovo dopo gli argomenti flatten. L'operatore view è un po' speciale perché fa qualcosa sugli elementi, ma continua anche a passarli all'operatore successivo così possiamo concatenarlo nel mezzo di una catena di operazioni come questa, e stamperà lo stato lì e continuerà. Quindi speriamo che questo ci mostri come appare il channel prima e dopo l'operatore flatten. + +## 3.2.3. Eseguire il workflow + +Proviamolo. Pulisci. Pulisci tutto nello spazio di lavoro. Esegui di nuovo la pipeline. + +Bene, quindi possiamo vedere che ha eseguito i nostri cinque processi. Di nuovo, non si è schiantato con un errore, quindi è decisamente buono. E ora abbiamo il before flatten e sicuramente abbiamo il nostro array e abbiamo after flatten, stampato cinque volte una volta per ciascun elemento dell'array. È esattamente quello che speravamo. Quindi è davvero una buona notizia. E questo si adatta esattamente a quello che ci aspetteremmo dal codice. + +Non abbiamo più bisogno di queste istruzioni di debug, quindi posso commentarle o eliminarle. Le eliminerò solo per mantenere il mio codice bello e pulito. Bene, ottimo. Questo esempio ora funziona bene e possiamo iniziare a vedere come i channel possono fare una logica un po' più complicata. + +## 4. Utilizzare un operatore per analizzare i valori di input da un file CSV + +Ora proveremo a farlo usando un file con una serie di input invece. Questo è un modo molto comune per scrivere pipeline Nextflow usando un foglio campione o un CSV di metadati. + +## 4.1. Modificare lo script per aspettarsi un file CSV come fonte di saluti + +Se vado sulla barra laterale, può vedere greetings.csv nel repository di esempio, e questo è un file CSV molto, molto semplice che contiene solo tre righe con tre saluti diversi. Vediamo se possiamo usare questo file CSV all'interno del nostro workflow. + +Ora tornerò a usare params come abbiamo fatto nel capitolo uno, in modo da poter avere un input da riga di comando. + +Eliminerò questo array greetings. + +## 4.1.1. Cambiare il parametro di input per puntare al file CSV + +Imposterò params greeting al nome del file, che è greetings.csv, e userò questa variabile speciale per generare il channel. Metterò quello lì, e gli errori scompaiono. Ricorda che questo sta impostando questa variabile per impostazione predefinita ora. Quindi se eseguo la pipeline senza alcun argomento, userà greetings.csv, ma potrei fare --greeting per sovrascrivere questa variabile se volessi. + +## 4.1.2. Passare a una channel factory progettata per gestire un file + +Bene, stiamo passando un file ora piuttosto che una stringa o un array di stringhe, quindi probabilmente abbiamo bisogno di una channel factory diversa. + +Ci libereremo di "of" che abbiamo usato finora, e useremo invece .fromPath. Questo fa esattamente quello che sembra. Crea un channel con percorsi invece di valori, usando un nome di file stringa o glob. Rimuoverò anche l'operatore flatten poiché non ne abbiamo più bisogno, ora che stiamo passando un file. + +## 4.1.3. Eseguire il workflow + +Premerò salva, aprirò il terminale, eseguirò il workflow, e poi vedremo cosa succede. + +Bene. Si è schiantato di nuovo. Non si preoccupi. Me lo aspettavo anche questo. Diamo un'occhiata al messaggio di errore e vediamo se possiamo capire cosa sta andando storto. Qui possiamo vedere il comando eseguito, e un po' come prima dove avevamo l'intero array stampato. Ora abbiamo il percorso del file che viene fatto echo nel comando, piuttosto che passare attraverso il contenuto del file. + +## 4.2. Utilizzare l'operatore splitCsv() per analizzare il file + +Quindi per usare il contenuto del file invece, abbiamo bisogno di un altro operatore. L'operatore che useremo per questo è chiamato splitCsv. Ha senso, perché è un file CSV che stiamo caricando. + +## 4.2.1. Applicare splitCsv() al channel + +Ok, quindi splitCsv. Chiudi parentesi. Non abbiamo bisogno di alcun argomento qui. E di nuovo, userò alcuni operatori view per dare un'idea di cosa sta succedendo qui. + +.view csv after splitCsv. Before split Csv. + +## 4.2.2. Eseguire nuovamente il workflow + +Bene, proviamo a eseguire questo e vedere cosa succede. + +Bene, abbiamo un po' più di output questa volta, ma è ancora fallito. Possiamo guardare le istruzioni view, e qui può vedere before split CSV, e abbiamo un percorso di file come abbiamo visto nel messaggio di errore precedente. After split CSV, ora abbiamo tre valori corrispondenti alle tre righe nel file CSV. + +Tuttavia, può vedere che ognuno di questi valori è circondato da parentesi quadre. Quindi ognuno di quelli era un array a sé stante, e questo ci ha dato la stessa area che avevamo prima dove sta cercando di fare echo di un array piuttosto che solo una singola stringa. + +Se pensiamo a un file CSV, questo ha un certo senso. Tipicamente, un file CSV avrà righe e colonne, quindi split CSV fa un array bidimensionale. La prima dimensione dell'array è ogni riga, e poi c'è una seconda dimensione, che è ogni colonna per ogni riga. + +Quindi qui abbiamo solo un singolo valore su ogni riga, quindi abbiamo una singola colonna, quindi abbiamo un array di un elemento per ogni riga del file. + +Va bene. Abbiamo solo bisogno di un altro operatore per collassare quell'array per ogni riga del file CSV analizzato. Puliamo questo. Sbarazzarsi di un terminale e vedere cosa possiamo fare. + +## 4.3. Utilizzare l'operatore map() per estrarre i saluti + +Ora potremmo usare di nuovo l'operatore flatten, che abbiamo usato prima. Abbiamo visto come quello può collassare un array in una serie di valori, che funzionerebbe molto bene qui. Ma userò l'opportunità per dimostrare un altro operatore, che è molto comune all'interno dei workflow chiamato operatore map. + +## 4.3.1. Applicare map() al channel + +Farò dot map e farò item item[0]. + +Se scrive molto altro codice in linguaggi, potrebbe già avere familiarità con l'operatore map. Prende un iterabile, come un array o un channel, e fa un'operazione su ciascun valore di quello. + +Qui stiamo dicendo che dovremmo definire una variabile chiamata item all'interno dell'ambito di questa closure, e poi vogliamo restituire, solo il primo valore in quell'array. Quindi item indice zero. + +Questo sta effettivamente appiattendo l'array. Può vedere come potremmo estendere questo per essere più complesso, però: se il nostro file CSV avesse sei colonne, ma siamo interessati solo alla quarta colonna, potremmo accedere a un indice specifico qui. O fare qualsiasi altro tipo di operazione sul valore prima di passarlo all'elaborazione a valle. + +Quindi l'operatore map è estremamente flessibile e molto potente per modificare i channel in volo. Mettiamo un'altra istruzione view solo per poter vedere cosa sta facendo nella nostra esecuzione. Può giudicare quella riga e spostarla verso il basso. E after map. + +## 4.3.2. Eseguire il workflow un'ultima volta + +Portiamo su il terminale e proviamo a eseguire il workflow. + +Bene, nessun errore questa volta. È un buon segno. Ora possiamo passare attraverso tutti questi diversi output dalle istruzioni view. Before split CSV, avevamo un singolo percorso. After split CSV, avevamo gli array di valore singolo, e poi after map, abbiamo solo i valori senza alcuna sintassi di array. Andiamo alla directory results, ed ecco i nostri file di output che si comportano esattamente come volevamo. + +C'è un piccolo bonus qui. Può effettivamente vedere che gli operatori view sono leggermente mescolati nell'ordine in cui hanno fatto l'output. Questo perché Nextflow sta facendo la parallelizzazione di queste diverse attività. Quindi dopo aver diviso il CSV, ci sono tre elementi in questo channel, e sta gestendo l'elaborazione di quei tre elementi in parallelo automaticamente. Ciò significa che l'ordine degli output è stocastico e può variare. In questo caso, è semplicemente successo che alcuni degli operatori view sono stati restituiti dopo che il passaggio successivo era stato completato, e quindi è arrivato in questo ordine. + +Se eseguo di nuovo lo stesso workflow. Allora infatti, è arrivato in un ordine diverso e questa volta abbiamo gli split CSV e le map nell'ordine che ci aspetteremmo. + +Quindi tenga solo presente, non può fare affidamento sull'ordine degli output da un'attività del process perché Nextflow sta gestendo questa parallelizzazione per Lei automaticamente. Nextflow lo fa per Lei con la sua logica di flusso dati, e questo è il vero potere di Nextflow. + +Bene, questo è probabilmente uno dei capitoli più importanti di tutta la formazione. Una volta compresi i channel, le channel factory e gli operatori, inizia a entrare nella forza di Nextflow e ciò che lo rende unico come linguaggio di programmazione. Questa funzionalità consente a Nextflow di parallelizzare tutti i suoi workflow per Lei e generare una logica di workflow estremamente complessa con una sintassi molto pulita e un modello di flusso di dati push. Può essere un concetto un po' strano all'inizio, ma una volta che si abitua a scrivere codice come questo, si sentirà rapidamente naturale e prima che se ne renda conto, scriverà fantastici workflow. + +Faccia una pausa, una tazza di tè, cammini un po' e passiamo al capitolo tre, dove iniziamo ad estendere questi concetti in workflow più complessi. Ci vediamo nel prossimo video. + +[Trascrizione video successivo :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/it/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..f00035250d --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Parte 3: Hello Workflow - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per istruzioni complete passo dopo passo, tornare al [materiale del corso](../03_hello_workflow.md). + + I numeri di sezione mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuto + +Salve, benvenuti alla parte tre del corso di formazione "Hello Nextflow". + +Questo capitolo si intitola "Hello Workflow". + +Nel capitolo due, abbiamo costruito un semplice workflow di un processo, ma in realtà, i pipeline sono utili perché possono concatenare più passaggi di analisi insieme. + +In questo capitolo, prenderemo quell'esempio iniziale e lo estenderemo per renderlo un po' più realistico. + +Aggiungeremo alcuni passaggi aggiuntivi e vedremo come utilizziamo i canali per collegare questi passaggi. + +Esamineremo più attività, che possono essere raccolte in un singolo processo, e vedremo i processi che possono avere più input e più output. + +Bene, iniziamo. + +Quindi, cominciamo. Come prima. Andiamo su training.nextflow.io. Hello Nextflow, capitolo tre. Hello Workflow. E apriamo il nostro spazio di lavoro. Ho pulito tutti i miei file di lavoro dai capitoli precedenti e aprirò Hello Workflow. + +Ora questo è lo stesso file su cui abbiamo lavorato finora, quindi dovrebbe sembrare familiare. Abbiamo il nostro processo say hello. Abbiamo il nostro params.greeting con il suo file greetings CSV, e abbiamo il nostro workflow in fondo, che carica quel file CSV, crea il canale e lo passa al nostro processo. + +## 0. Riscaldamento: Eseguire hello-workflow.nf + +Se volete, possiamo provarlo e verificare che funzioni come previsto. Aprite un terminale e digitate nextflow run hello workflow nf e premete invio. + +Bene, ottimo. I nostri tre processi vengono eseguiti. Abbiamo la nostra directory results con i nostri tre output. Bonjour. Hello. Holà. Quindi chiudiamo quei file, chiudiamo il terminale e torniamo allo script. + +## 1. Aggiungere un secondo passaggio al workflow + +Okay. Per il nostro esempio, rimaniamo semplici e cerchiamo di rimanere agnostici dal dominio. Quindi il nostro secondo processo manipolerà semplicemente queste stringhe, queste parole, in modo semplice. Useremo il comando Unix translate per prendere questi file e renderli tutti maiuscoli. Lo facciamo con il comando "tr". + +## 1.1. Definire il comando di conversione in maiuscolo e testarlo nel terminale + +Possiamo provare questo direttamente nel terminale bash e vedere se funziona. Quindi digitate echo, Hello World, e poi passatelo con il carattere pipe a tr, e gli diamo un pattern di riconoscimento, a-z e a cosa dovrebbe tradurlo. A-Z in maiuscolo. + +Questo è molto semplice perché sta letteralmente convertendo i caratteri A-Z. Quindi non funzionerà su nulla che abbia accenti o cose simili. Ma ai fini dell'esempio, dovreste capire l'idea. + +Premo invio e stampa sul terminale HELLO WORLD in maiuscolo. E proprio come prima, potremmo reindirizzare questo a un file se volessimo. Outfile. + +Okay. Puliamo questo. + +## 1.1. Scrivere il passaggio di conversione in maiuscolo come processo Nextflow + +Torniamo al nostro script e scriviamo un nuovo processo per gestire questo comando bash. Copierò il processo precedente, lo incollerò sotto e lo chiamerò convert to upper. Per maiuscolo. Userò lo stesso publishDir results, ma farò alcuni cambiamenti qui. Invece di prendere un val, prenderò un path input file, e avrò un prefisso qui upper, in modo che i nostri file di output non sovrascrivano l'output. E userò il nome della variabile dall'input. E poi cambierò lo script qui sotto, e invece userò cat sul file di input e proprio come abbiamo fatto in Bash TR, a-z, upper input file .txt. Okay, clicchiamo su salva. + +## 1.2. Aggiungere una chiamata al nuovo processo nel blocco workflow + +Ora se scorro verso il basso, dobbiamo effettivamente chiamare questo processo. Aggiungere semplicemente il processo in uno script non è sufficiente. Dobbiamo dire a Nextflow che dobbiamo eseguire questo processo e dove farlo. + +Quindi scriverò qui, convert to upper e + +okay, stiamo ricevendo un errore qui che dice che si aspetta un argomento. Certo, dobbiamo passare qualcosa a questo processo in modo che abbia effettivamente qualcosa da fare. + +## 1.3. Passare l'output del primo processo al secondo processo + +Quello che faremo è prendere l'output da questo processo. Quindi prendo il nome, say hello, e quando faccio dot out. + +Per un esempio semplice come questo, dove abbiamo un processo che ha solo un output e lo passiamo a un nuovo processo, quindi ha un input, questo dovrebbe essere tutto ciò di cui abbiamo bisogno. Quindi cliccherò su salva, aprirò il terminale e proviamo a eseguirlo di nuovo. + +## 1.4. Eseguire nuovamente il workflow + +Ora, non ho ripulito la mia directory work dall'ultima volta che ho eseguito questo workflow. Lo eseguirò di nuovo e userò questa opportunità per mostrare come funziona il caching parziale. Quindi se faccio singolo trattino resume. Si spera che dovrebbe riutilizzare gli output da quel primo processo, che erano esattamente gli stessi dell'ultima volta che l'ho eseguito. Ma ora abbiamo un nuovo processo qui che non è stato eseguito prima, che viene eseguito da zero. E infatti, potete vedere che il primo processo ha utilizzato gli output memorizzati nella cache, e il secondo output ha eseguito tre di tre. Potete anche vedere che abbiamo entrambi i nostri processi qui ora, il nostro primo processo, say hello, eseguito tre volte, e il nostro secondo processo convert to upper eseguito tre volte. + +Se eseguo questo di nuovo, come promemoria, con -ansi-log false, dovremmo vedere che vengono eseguite sei diverse attività di processo, tre per ciascuna di esse. Quindi questo sta facendo esattamente quello che speravamo. Il primo processo viene eseguito tre volte, passando quegli output a un secondo processo, che viene poi eseguito tre volte. + +Quindi diamo un'occhiata all'interno della directory work e vediamo come Nextflow gestisce questi input di file. Se prendo questa directory hash qui dal secondo processo, possiamo usare di nuovo il comando tree con -a solo per guardare questi file. Potete vedere qui che abbiamo il nostro file di input, che è il file Bonjour-output.txt, e in realtà è un symlink. Questo è ciò che ci mostra questa freccia, e sta puntando al file nella directory work precedente. + +Questo ha senso. Nextflow gestisce l'esecuzione di ogni attività nella propria directory incapsulata, quindi è completamente autonoma. Tuttavia, deve fornire i file da passaggi precedenti come input. Piuttosto che raggiungere al di fuori della directory work per ottenere quei file, Nextflow li prepara nella directory work. + +Se abbiamo un file system condiviso come qui, lo fa utilizzando un symlink in modo da non utilizzare spazio file aggiuntivo. Se utilizziamo l'archiviazione cloud con bucket in posizioni diverse, recupererebbe quei file e li copierebbe effettivamente nella directory work. + +Diamo un'occhiata al file command sh. Se faccio code work, command sh, potete vedere, infatti, sta accedendo a quel file dalla directory locale. Quindi tutto è molto autonomo e pulito. + +Possiamo anche controllare la directory results e assicurarci che questi file siano stati emessi correttamente. E infatti, in results, possiamo vedere tutti i file di output dal primo processo e tutti i file di output dal secondo. E sono tutti in maiuscolo come speravamo. + +Qui inizia a brillare la potenza di Nextflow. Con un codice molto minimale, Nextflow ha gestito l'esecuzione in parallelo di queste attività con incapsulamento pulito all'interno di directory work separate e preparazione dei file di input e output e pubblicazione dei file, tutto automaticamente per noi, semplicemente pronto all'uso. Quindi potete vedere come, man mano che aumentiamo la complessità dei nostri workflow di analisi, questa funzionalità sia davvero, davvero preziosa. + +## 2. Aggiungere un terzo passaggio per raccogliere tutti i saluti + +Okay. Questi passaggi erano uno a uno. Avevamo un output dal primo processo che andava a un input per il secondo processo. Successivamente, parleremo di come raccogliere questi diversi output in una singola attività di processo, che è di nuovo una cosa molto comune da fare. Quindi apriamo rapidamente il terminale e facciamo una prova a secco di questo. + +## 2.1. Definire il comando di raccolta e testarlo nel terminale + +Farò un trucco e copierò il codice bash di esempio dal materiale di formazione e premerò semplicemente invio. + +Quello che possiamo vedere qui è che abbiamo eseguito questo comando echo tre volte su tre diversi file di output, che posso vedere qui. E poi abbiamo usato il comando cat per stampare l'output di ciascuno di questi tre diversi file e reindirizzarlo a un singolo file raccolto. + +E se faccio "cat COLLECTED-output", potete vedere che ha il contenuto di quei tre diversi file, ora in un singolo file. + +## 2.2. Creare un nuovo processo per eseguire il passaggio di raccolta + +Quindi vediamo se possiamo replicare la stessa cosa all'interno del nostro pipeline Nextflow. + +Scorriamo verso l'alto e creiamo un terzo processo. Copierò questo precedente, e questa volta lo chiamerò Collect Greetings. + +Nel terminale bash, l'abbiamo chiamato collected output txt. Quindi dirò lo stesso path output qui. E farò il reindirizzamento qui, quindi viene salvato nello stesso modo. + +Okay. Dobbiamo cambiare ciò che accade all'inizio di quel comando, e dobbiamo pensare a quale sia il file di input qui. In effetti, questo processo prenderà più file di input. Manterrò path e cambierò questo in una nuova variabile chiamata input files, plurale. + +Poi farò di nuovo cat su di essi come abbiamo fatto nel nostro script bash. E userò qui la variabile. + +Ora, potreste pensare che questo non funzionerebbe. Abbiamo visto in precedenza fallimenti in cui un array di stringhe o un array di percorsi è stato passato a un processo e ciò ha causato un errore. Ma in realtà, qui Nextflow gestirà questo automaticamente per noi nel modo giusto. Prenderà diversi file di input, e stamperà semplicemente i diversi percorsi dei file qui. + +Naturalmente aiuta che il comando cat possa prendere una serie di nomi di file come questo. Se stessi usando un comando diverso che richiedesse un argomento prima di ogni percorso di file o qualcosa del genere, dovremmo avere un po' più di codice qui e logica per poter gestire l'iterazione di questi percorsi di file. Ma in questo caso, dovrebbe semplicemente funzionare. + +## 2.3. Aggiungere il passaggio di raccolta al workflow + +Okay, scendiamo al workflow e aggiungiamo il nostro nuovo processo. Collect greetings. E di nuovo, prendiamo l'output da convert to upper out. Salviamo questo. + +Proviamolo. nextflow run hello workflow. + +Okay, il workflow è stato eseguito, ma qualcosa è un po' strano qui. Abbiamo tre esecuzioni del primo passaggio, che ci aspettiamo. Tre attività per il secondo, ma abbiamo anche tre attività alla fine quando ci aspettavamo di avere solo una singola attività qui che unisce tutti gli output. + +Se andiamo nella nostra directory results. Vediamo anche che l'output raccolto ha solo un singolo valore invece di tutti e tre. Questo perché quel file di output è stato sovrascritto tre volte con tre valori diversi. + +Questo ha senso perché abbiamo passato un output a un input qui nello stesso modo in cui abbiamo fatto nel passaggio precedente. + +## 2.4. Utilizzare un operatore per raccogliere i saluti in un singolo input + +Quindi abbiamo bisogno di un operatore qui per prendere questo canale con tre elementi e ridurli a un singolo elemento, in modo che quel processo finale venga eseguito solo una volta. + +Per farlo, useremo l'operatore collect. Posso farlo direttamente all'interno del workflow. Posso fare .out e concatenare un operatore qui alla fine .collect. + +Clicco salva. E poi ai fini di questa formazione, farò anche alcuni operatori view come abbiamo fatto prima, così possiamo dare un'occhiata a questo canale prima e dopo aver utilizzato l'operatore collect, in modo da poter capire cosa sta succedendo. + +Prenderò questo canale, rimuoverò il collect e dot view greetings, e poi duplicherò questa riga, aggiungerò l'operatore collect. E cambierò quello in after. + +Questo è separato da dove stiamo chiamando questo, ma va bene perché stiamo usando le stesse chiamate di operatori sullo stesso canale di output. + +Okay, clicchiamo su salva e proviamolo nel terminale. Farò lgoing nextflow run. Hello, workflow. Rieseguiamo il nostro script. + +Okay. Questo sembra meglio. Come prima possiamo vedere i primi due processi eseguiti tre volte e ora il nostro processo finale è stato eseguito solo una volta. + +Se guardiamo cosa è stato stampato dall'operatore view, qui sotto, abbiamo detto before collect, che è questo output qui, e che viene stampato tre volte. E potete vedere che c'è un singolo percorso per ognuno di questi. E poi after collect, potete vedere che abbiamo questo array di tre percorsi. Quindi è come ci aspettavamo. + +Okay, controlliamo il file results e vediamo se è quello che ci aspettiamo questa volta. Infatti, ora ci sono tre righe nel file - ha concatenato con successo questi tre output in un singolo file di output. Fantastico. + +Okay, farò pulizia e passiamo al prossimo passaggio. E cancellerò queste istruzioni view solo per mantenere le cose pulite. + +## 3. Passare più di un input a un processo per nominare il file di output finale in modo univoco + +Okay. Finora, tutti i nostri processi hanno preso solo un singolo input. Ora faremo un esercizio in cui aggiungiamo più di un input a un processo per vedere come funziona. Per farlo, useremo questo esempio collect greetings. + +Ogni volta che eseguivo il workflow, sovrascriveva quel file nella directory results, che potrebbe non essere quello che vogliamo. + +## 3.1. Modificare il processo di raccolta per accettare un nome definito dall'utente per il file di output + +Quindi per questo esempio, passeremo un parametro aggiuntivo in modo da poter personalizzare il nome del file di output. + +Aggiungere un secondo input a un processo è molto semplice. Aggiungo semplicemente una seconda riga nel blocco input. Questa volta sarà un valore, piuttosto che un percorso, perché vogliamo passare una stringa e lo chiamerò batch underscore name. + +Posso ora usare questa variabile nel blocco script, e dirò collected dash dollar batch name. + +Sto usando parentesi graffe qui intorno al nome della variabile. Questo è solo per tenerlo separato dal resto di una stringa, e probabilmente non è necessario in questo caso, ma penso che renda più facile la lettura. + +Okay. Infine, ricordate di aggiornare il percorso di output perché ora il nome del file è cambiato, quindi farò la stessa cosa e metterò il batch name nell'output del percorso come previsto. + +## 3.2. Aggiungere un parametro batch da riga di comando + +Ora dobbiamo passare un batch name da qualche parte, e creerò un secondo parametro per farlo in modo da poterlo fare sulla riga di comando quando eseguiamo il workflow. + +Quindi farò params batch name, e per impostazione predefinita, chiamiamolo test batch. Ora posso usare questa variabile di parametri speciale in basso, dove chiamiamo il processo. + +E infatti VS Code ci sta dicendo che non ci sono abbastanza argomenti per questo processo ora, e che si aspetta un secondo input. + +Semplicemente faccio virgola e passo la nostra nuova variabile e l'errore scompare. + +Notate che l'ordine degli input qui è davvero importante. Il primo input del processo era il percorso, e il secondo input è il nome. Se cambio l'ordine qui, devo anche cambiare l'ordine quando chiamo il processo. Altrimenti Nextflow passerà il canale sbagliato all'input sbagliato. + +## 3.3. Eseguire il workflow + +Okay, proviamo e vediamo se funziona. Facciamo "nextflow run hello-workflow. Okay, è stato eseguito come prima. Diamo un'occhiata nella directory results. + +Infatti, il nostro nome di file qui ora si chiama "collected test batch output txt". Fantastico. + +E ora vediamo se possiamo sovrascriverlo eseguendolo di nuovo. Questa volta farò --batch_name per corrispondere a quel nome di variabile di parametro speciale qui. E lo chiamerò demo output. + +Eseguiamo di nuovo il workflow e vedremo se succede qualcosa. + +Okay, ora abbiamo un collected demo output .txt. E poiché questo nome di file è diverso da quello, non l'ha sovrascritto. Entrambi sono ora presenti nella directory results. + +## 4. Aggiungere un output al passaggio di raccolta + +Okay, quindi abbiamo mostrato come dare più input a un processo, ma per quanto riguarda più output? Per questo esempio, calcoleremo il numero di saluti che vengono elaborati e lo emetteremo come output secondario per questo passaggio collect greeting. + +## 4.1. Modificare il processo per contare ed emettere il numero di saluti + +Faremo un piccolo trucco qui. I processi Nextflow hanno questo blocco script con una stringa multi-linea, e quella viene passata come output bash al dot command dot sh. Ma possiamo effettivamente scrivere qualsiasi codice personalizzato sopra quello, e quello verrà eseguito come parte di un'attività ma non incluso all'interno dello script bash. + +Una delle funzioni integrate nella sintassi Nextflow si chiama size. Quindi prenderò l'input del percorso, e dirò count underscore greetings, solo per definire un nome di variabile. Prenderò i file di input e chiamerò "size" su di esso. + +Questa funzione conterà la dimensione di questo canale di input e lo assegnerà a una variabile. + +Possiamo ora restituire quella variabile come parte del blocco output. Quindi diciamo, val, perché è un valore, non un file. E count greetings. + +Ora questo è sufficiente da solo, e potremmo ora accedere a questi diversi output da questo processo. Tuttavia, dovremmo accedervi in modo posizionale. Quindi usando una chiave di indice come zero e uno. + +Per rendere un po' più facile ottenere gli output, possiamo nominarli e lo facciamo utilizzando un'istruzione emit. + +Quindi facciamo virgola emit out file o come voglio chiamarlo. E qui faccio emit count. Questo è fondamentalmente solo un decoratore, che ci aiuta a scrivere codice leggermente più pulito in modo da poter facilmente fare riferimento agli output specifici in seguito nel blocco workflow. + +## 4.2. Riportare l'output alla fine del workflow + +Okay. Se scorro verso il basso al blocco workflow, posso ora prendere gli output di collect greetings, fare collect greetings, dot out, e possiamo vedere i nostri due output denominati sono suggeriti qui dall'estensione VS Code. Molto utile. + +Quindi farò dot count per ottenere il valore count che abbiamo appena creato, e farò view, in modo che venga stampato nella riga di comando. Così possiamo vederlo quando eseguiamo il workflow. + +Scriviamo qualcosa nella closure qui solo per renderlo un po' più carino. num greetings, there were greetings greetings. + +E in realtà non ci interessa l'altro output perché non lo stiamo usando come input per nessun altro processo. Ma potete vedere come potremmo facilmente passarlo come input a un altro processo se volessimo, a valle. + +## 4.3. Eseguire il workflow + +Cliccheremo su salva. Diamo un'occhiata al terminale e proviamolo. + +Okay, fantastico. Eccoci qui. There are three greetings. È esattamente giusto. + +Okay, ottimo lavoro. Questa è la fine di questo capitolo. Abbiamo finito per essere arrivati fin qui. Ora state iniziando a costruire un workflow piuttosto realistico, dove siamo in grado di gestire input e output e logica all'interno del nostro workflow. + +Man mano che questi file di workflow diventano più lunghi, iniziano a diventare un po' ingombranti. Quindi nel prossimo capitolo, esamineremo come possiamo modularizzare il codice Nextflow in file separati in modo che sia più facile trovare e mantenere il codice all'interno del workflow. + +Unitevi a noi nel prossimo video per il capitolo quattro. Hello Modules. + +[Trascrizione video successivo :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/it/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..462d0fa7fd --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Parte 4: Hello Modules - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, torni al [materiale del corso](../04_hello_modules.md). + + I numeri delle sezioni mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuto + +Salve, benvenuto alla Parte Quattro del corso di formazione Hello Nextflow. + +Questo capitolo si chiama Hello Modules, e parleremo di come modularizzare il codice Nextflow. Ciò che faremo è prendere il nostro script di workflow unico e dividerlo in file separati. + +Questo rende il codice più facile da navigare e mantenere man mano che il workflow diventa più grande, e rende anche possibile condividere moduli tra pipeline in modo che se ha più pipeline che utilizzano lo stesso strumento, debba scrivere quel process solo una volta. + +Un esempio classico di questo è il repository dei moduli nf-core, che ha migliaia di diversi strumenti in moduli pronti all'uso, che può installare e utilizzare nel suo workflow. + +Nextflow può anche lavorare con sub workflow, che sono come moduli, ma hanno più processi. Questo è al di fuori dello scopo di questa formazione, ma funziona sostanzialmente nello stesso modo. + +Bene. Diamo un'occhiata. + +Come al solito, inizi andando su training.nextflow.io. + +Vada su "Hello Nextflow" nella barra laterale, e stiamo facendo la parte quattro: "Hello Modules". + +Ora sto per saltare nel mio ambiente GitHub Code Spaces e dare un'occhiata al file "hello-modules". + +Proprio come prima, stiamo partendo dal punto finale del capitolo precedente, quindi questo script dovrebbe risultare familiare. Abbiamo i nostri tre processi, say hello, convert to upper e collect greetings, e in un workflow semplice, che esegue questi tre comandi ed emette un messaggio alla fine. Abbiamo due parametri chiamati greeting e batch, che specifica il nome, che viene utilizzato per il file di output raccolto alla fine. + +## 0. Riscaldamento: Eseguire hello-modules.nf + +Possiamo verificare che questo workflow funzioni ancora come ci aspettiamo facendo nextflow run hello modules. + +Ottimo. Ha eseguito tre attività con ciascuno di questi processi, un'attività collect, e ci ha detto che ci sono tre saluti in questo batch. Se andiamo in results, abbiamo i nostri diversi file di output qui, incluso l'output di test batch raccolto. + +## 1. Creare una directory per memorizzare i moduli + +Giusto. Facciamo un po' di modularizzazione. + +È generalmente una buona idea mettere i moduli in una sottocartella nel repository della pipeline, solo per mantenere le cose ordinate. Può chiamarla come vuole, ma per convenzione di solito la chiamiamo modules. + +Quindi procediamo, andiamo in un terminale e facciamo make the modules. Può vederla apparire nella barra laterale e VS Code qui. + +## 2. Creare un modulo per sayHello() + +Poi creerò un nuovo file per il mio primo modulo. Può fare "touch" o "code" o può farlo nella barra laterale, non importa davvero. Quindi farò code modules e lo chiamerò come il process. Quindi sayHello.nf. NF è un'estensione di file tradizionale per i file Nextflow. + +Salverò qui e possiamo vedere che il nostro nuovo file di modulo appare. + +## 2.2. Spostare il codice del process sayHello nel file del modulo + +Bene, successivamente prenderò il codice del modulo dal workflow. Prenderò anche lo shebang qui e lo copierò per primo in modo che sia chiaramente un file Nextflow. E poi prenderò questo process e lo taglierò. Quindi lo rimuoverò dal mio script di workflow principale e lo incollerò in questo nuovo modulo. + +Questo è tutto il contenuto che questo file di modulo conterrà. Solo un singolo process, nessun workflow, nessuna logica, solo un process da solo. + +Ora posso chiudere questo file. + +## 2.3. Aggiungere una dichiarazione import prima del blocco workflow + +Ora al mio workflow manca quel primo process, quindi dobbiamo riportarlo importandolo. La sintassi per questo è molto simile ad altri linguaggi di programmazione, quindi potrebbe risultare familiare. Facciamo include parentesi graffe, il nome del process, say hello, e poi from il percorso del file modules, say hello, nf. Fantastico. + +Un paio di trucchi qui. L'estensione VS Code è intelligente riguardo a questo. Riconosce questo percorso del file e può passarci sopra con il mouse e fare follow link. Oppure sono su Mac, posso fare option click e apre questo file. Quindi possiamo saltare rapidamente ad esso. + +Questo nome di process è ora utilizzato dal workflow qui sotto, e possiamo fare la stessa cosa qui. Ci mostra un po' di informazioni su quel process, e di nuovo, posso tenere premuto option, cliccarci sopra, e lo aprirà nell'editor. + +Quindi è un modo davvero veloce quando ha molti file per i suoi diversi processi per navigare rapidamente nella sua base di codice in VS Code. + +Bene. Questo è sostanzialmente tutto per questo capitolo. Ora facciamo semplicemente la stessa cosa di nuovo per gli altri processi. + +## 3. Modularizzare il process convertToUpper() + +Quindi creiamo un nuovo file qui. Lo chiamiamo Convert to upper nf. Di nuovo, copiamo lo shebang. E poi tagliamo il process. + +Copiamo il nome del process lì, includiamo una nuova dichiarazione include con il nuovo nome del process. + +## 4. Modularizzare il process collectGreetings() + +E poi facciamo lo stesso per il terzo process. Nuovo file, connect Greetings, + +facciamo lo shebang. Tagliamo il process, incolliamo il process, e facciamo una nuova dichiarazione include. + +Ora può vedere qui che ho una sottolineatura di errore qui che dice invalid include source. E questo è in realtà un errore genuino che ho fatto perché mi stavo muovendo un po' troppo velocemente. Se guarda attentamente, può vedere che ho perso la T in convert to upper + +Quindi VS Code molto utilmente mi ha detto che ho fatto un errore lì. Se correggo quel nome file, l'errore scompare. È un buon esempio del motivo per cui il controllo degli errori all'interno di VS Code è così utile per scrivere codice Nextflow. Altrimenti non l'avrei notato e l'avrei scoperto solo molto più tardi quando avessi provato ad eseguire il workflow. + +Il nostro script di pipeline principale ora sembra molto più semplice. Non ha alcun process, abbiamo solo tre dichiarazioni include e il nostro workflow. Non abbiamo cambiato nessuna logica del workflow. Non abbiamo cambiato nessun codice del process, quindi si spera che funzioni esattamente nello stesso modo. + +## 4.4. Eseguire il workflow per verificare che faccia la stessa cosa di prima + +Verifichiamo. Aprirò un terminale e eseguirò esattamente lo stesso comando di prima. + +Certo, ha eseguito i nostri processi, say hello, convert to upper collect greetings, e ci ha dato di nuovo tre saluti. + +Quindi abbiamo spostato il nostro codice, ma non abbiamo cambiato nulla su come il workflow viene eseguito ed è completamente invariato. L'unica differenza è che ora abbiamo un codice più pulito, più facile da mantenere, e più facile da condividere con altri. + +E questo è tutto. È stato un capitolo breve. È un concetto semplice, ma è molto potente e fondamentale per come scriviamo workflow Nextflow più complessi. Quindi è importante che lo comprenda e prenda l'abitudine di utilizzarlo. + +Nel prossimo capitolo, avremo un po' di cambiamento di ritmo e smetteremo di pensare così tanto alla sintassi di scrittura del codice Nextflow, e penseremo un po' a come utilizziamo il software nei processi stessi. Ci raggiunga nella parte cinque per Hello Containers. + +[Prossima trascrizione video :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/it/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..71d89f4610 --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Parte 5: Hello Containers - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, torni al [materiale del corso](../05_hello_containers.md). + + I numeri di sezione mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuto + +Salve, benvenuti alla Parte Cinque del corso di formazione Hello Nextflow. + +Questo capitolo si intitola Hello Containers. Parleremo di come Nextflow si integra con strumenti come Docker e Singularity per utilizzare container software per fornire software agli utenti del Suo pipeline. + +Questo significa che quando le persone eseguono il Suo pipeline, non devono andare ad installare tutti i diversi strumenti da soli. Nextflow lo farà per loro. + +I container sono una tecnologia estremamente potente e cruciale per la riproducibilità e la facilità d'uso. Inizieremo con una breve introduzione ai container stessi, eseguendo alcuni comandi docker manualmente, e poi prenderemo gli stessi container e li inseriremo nel nostro pipeline Nextflow. + +Bene. Iniziamo. + +Quindi, proprio come prima, iniziamo caricando il materiale di formazione. Vada su training.nextflow.io. Hello Nextflow, Capitolo Cinque, Hello Containers. + +Salto nel mio ambiente Codespaces e sulla sinistra qui vediamo hello containers punto nf. + +Proprio come prima, questo è lo stesso script con cui abbiamo finito il capitolo quattro precedente, quindi dovrebbe essere familiare. + +Abbiamo i nostri parametri da linea di comando per specificare il file di input e il nome del batch. Stiamo includendo i nostri tre moduli, e abbiamo il nostro workflow dove eseguiamo i tre processi. + +## 0. Riscaldamento: Eseguire hello-containers.nf + +Si senta libero di eseguire nuovamente questo workflow e verificare che stia producendo gli output che si aspetta. Per ora, in realtà lo chiuderò e mi immergerò nel terminale. + +## 1. Usare un container 'manualmente' + +Per iniziare questo capitolo, faremo un po' di riepilogo sulla tecnologia dei container. Se è molto abituato a docker o singularity o altre tecnologie di container, allora lo consideri un ripasso, o si senta libero di saltarlo completamente. + +Nextflow supporta molti tipi diversi di tecnologie di container. Ciò include Docker, Singularity, Podman, Shifter, Charliecloud e altri. + +In questa formazione, ci concentreremo su Docker. Questo viene preinstallato negli spazi di codice ed è una delle tecnologie di container più popolari, specialmente se sta sviluppando sul Suo computer o sul Suo laptop. + +Se sta lavorando in un ambiente accademico su un HPC condiviso, potrebbe scoprire che Singularity è disponibile e Docker no. Va bene. Tutti i concetti sono esattamente gli stessi. Alcuni dei comandi manuali sono diversi, ma se comprende Docker, comprenderà anche singularity. + +In effetti, Singularity è installato anche nell'ambiente Code Spaces. Quindi, se vuole, può provare a eseguire le stesse attività utilizzando Singularity invece di Docker. + +Bene, cos'è la tecnologia dei container? L'idea dietro Docker è che può recuperare un'immagine da una fonte remota. Scaricarla sulla Sua macchina locale e quindi creare un container basato su quell'immagine. + +Questo container in esecuzione è un po' come una macchina virtuale in esecuzione sul Suo computer. È isolato dal Suo ambiente e viene preconfezionato con un sistema operativo e un insieme di software disponibili. + +## 1.1. Scaricare l'immagine del container + +La sintassi di cui abbiamo bisogno per recuperare un'immagine preesistente è "docker pull". Quindi lo digiterò nel mio terminale, ma ora abbiamo bisogno di un'immagine con cui giocare. + +Può creare immagini Lei stesso. Può trovarle su registri pubblici come Docker Hub o quay.io. Ma un modo davvero efficace per ottenere immagini rapidamente è utilizzare Seqera Containers. + +Questo è un servizio comunitario gratuito che abbiamo costruito nel 2024, che può utilizzare senza login o altro. + +Se va su seqera.io/containers o clicca su containers in alto qui, Le viene presentata un'interfaccia di ricerca e può digitare il nome di qualsiasi strumento disponibile in Conda o sul Python Package Index. + +Per impostazione predefinita, cerca i canali Bioconda e Conda Forge, ma può prefissare qualsiasi canale Conda. Sono qui se vuole. + +Per un po' di divertimento, usiamo cowpy. Digiterò cowpy. Mi dà risultati da Python Package Index e Conda Forge. Cliccherò su quello per aggiungerlo al mio container. Potrei aggiungere più pacchetti qui se volessi. Seleziono Docker, seleziono linux/amd64 e clicco Get Container. + +Questo costruisce l'immagine per me su richiesta se non è già stata creata, e mi dà un URL che posso copiare. + +Se è interessato, può cliccare view Build Details, e questo La porta a una pagina, che mostra il file di ambiente conda che è stato utilizzato e il log di build completo per la build, insieme ai risultati della scansione di sicurezza. + +Se torno ai miei code spaces, ora posso incollare questo nome di container e premere invio. + +Docker ora scarica tutti i diversi layer all'interno di questa immagine del container, e ora ci dice che questa immagine è disponibile per l'uso. + +## Scaricare un'immagine Singularity + +Se sta utilizzando singularity, il processo è sostanzialmente lo stesso. Selezioniamo i nostri pacchetti di immagini, selezioniamo cowpy. Ora scegliamo Singularity invece di Docker e clicchiamo Get Container. Questo ci dà un URL dell'immagine usando oras://. Oppure, se preferisce, può utilizzare https:// selezionando quella casella. Copi quell'URL. Ora vada a Code Spaces. Abbiamo effettivamente Apptainer installato in questo spazio, che è lo stesso di Singularity, ma sono alias l'uno dell'altro. Quindi farò apptainer pull e poi lo chiamerò cowpy sif, ma può chiamarlo come vuole. Incollo l'URL. E questo scaricherà quell'immagine per me. + +Potrei fare ls -lh e vedere cowpy.sif + +Singularity è diverso da Docker, in quanto singularity memorizza tutte le immagini in file flat, mentre Docker ha un registro dove mantiene tutti i layer separatamente sulla Sua macchina host, e ha un demone in esecuzione per tenere traccia di tutto questo. + +## 1.2. Usare il container per eseguire cowpy come comando singolo + +Bene, torniamo a Docker. Ora possiamo provare a eseguire questa immagine che abbiamo creato facendo docker run. + +Farò dash dash rm, che esegue semplicemente un'esecuzione singola dell'immagine. E incollerò l'URL dell'immagine. E poi infine, termini questo con un comando che vuole eseguire. + +L'immagine che abbiamo generato aveva cowpy installato, quindi proviamo cowpy. + +Ecco fatto. Ha eseguito il nostro comando. Non ho cowpy installato localmente. Può vedere se provo a eseguirlo, non esiste. Tuttavia, in questo comando, l'ho eseguito usando Docker e ha generato correttamente questo output. + +## 1.3. Usare il container per eseguire cowpy interattivamente + +Possiamo andare oltre se vogliamo e avviare un container interattivamente e guardarci dentro. Ancora, faccio "docker run dash dash rm". Ora farò dash it, che dice a Docker che vogliamo un terminale interattivo. Faccio di nuovo l'URL dell'immagine, e questa volta, invece di fare cowpy, farò bin bash perché il comando che vogliamo eseguire è bash. + +Questo ci porta dentro questo container in esecuzione e può vedere che il prompt è cambiato ora. + +Se faccio LS slash può vedere che le directory qui sono diverse. + +Se apro un secondo terminale qui sulla destra, che è solo in esecuzione in GitHub Code Spaces e faccio LS slash, vede che abbiamo directory come workspaces e temp, mentre qui in Docker è diverso. + +Quindi questo ambiente è completamente separato all'interno di Docker e isolato dal mio ambiente host. Questa è una cosa buona, perché isola l'esecuzione di questo comando nell'immagine Docker e lo mantiene riproducibile tra persone diverse su sistemi host diversi. + +Se vuole utilizzare dati dal Suo sistema host all'interno dell'immagine Docker, deve montarlo esplicitamente nel container. + +Lo faremo tra un secondo. + +## 1.3.2. Eseguire il/i comando/i dello strumento desiderato/i + +Prima però, vediamo se possiamo eseguire cowpy. Ancora una volta, il comando è disponibile ora direttamente sulla linea di comando, e possiamo iniziare a fare cose più complesse e passare argomenti. Hello containers e invece della mucca, facciamo il pinguino tux. Vediamo cos'altro abbiamo. + +Facciamo cheese. Meraviglioso. Che ne dice di Dragon e Cow? Abbastanza bene. + +## 1.3.3. Uscire dal container + +Bene. Non posso fare molto di più perché non ho dati in questo container. Quindi usciamo da questa immagine in esecuzione e vediamo se possiamo montare alcuni dati nel container. Posso farlo facendo control D o digitando exit. Bene, sono tornato nel mio normale spazio di codice GitHub. + +## 1.3.4. Montare dati nel container + +Per montare alcuni dati nel container Docker, devo usare dash V. Quindi prenderò il mio comando docker precedente, tornerò all'inizio faccio dash v. Farò "." per la directory di lavoro locale corrente, e poi due punti per dire dove dovrebbe essere montata nella directory host e faccio slash data. Quindi questo sta montando questa particolare directory nel container in slash data. + +Ora se faccio LS slash possiamo vedere che abbiamo una nuova directory chiamata data, e se faccio LS data, può vedere tutti i file che abbiamo nella barra laterale qui. Fantastico. + +## 1.3.5. Usare i dati montati + +Ora possiamo iniziare a utilizzare alcuni dei file che sono sul sistema host all'interno dell'immagine Docker. Quindi posso dire cat data greetings csv. Se ricorda, questo è il nostro file CSV con i nostri diversi saluti di prima, e posso passarlo a cowpy. Fantastico. Ora stiamo andando da qualche parte. + +Bene. Questo è abbastanza per eseguire Docker interattivamente. Spero che ora abbia un'idea di cosa sia approssimativamente Docker e come usarlo sia per eseguire un comando in modo singolo, sia per usare un'immagine interattivamente. Se sta utilizzando singularity. I comandi sono tutti molto simili tranne che fa cose come apptainer exec o apptainer run, o singularity exec o singularity run. + +## 2. Usare i container in Nextflow + +Successivamente torneremo al nostro workflow Nextflow e vedremo come utilizzare questa tecnologia all'interno del pipeline Nextflow. + +Chiudiamo il terminale e apriamo di nuovo Hello Containers. + +## 2.1. Scrivere un modulo cowpy + +Per restare con il nostro esempio cowpy, creiamo un nuovo processo nel nostro workflow, che utilizza cowpy. Andiamo su moduli, creiamo un nuovo file e chiamiamolo cowpy nf. Ora barare un po' e copierò il codice dal materiale di formazione e premo salva. E diamo un'occhiata. + +Quindi questo è un processo semplice. Spero che ora comprenda come appaiono i blocchi di costruzione di un processo. Abbiamo il nostro publishDir di nuovo, che va in results. Abbiamo due input, un file di input e una stringa chiamata character. Abbiamo un output cowpy input file, e abbiamo uno script che sembra esattamente uguale a quello che abbiamo eseguito manualmente all'interno della nostra immagine docker un secondo fa: cat per stampare un file, passandolo a cowpy, dicendo quale tipo di personaggio cowpy vogliamo utilizzare, e producendo quello nel file di output, che passiamo come output qui. + +## 2.2. Aggiungere cowpy al workflow + +Bene, torniamo al nostro workflow, importiamo questo nuovo processo. Quindi cowpy da modules cowpy nf. Creiamo un nuovo parametro in modo da poter specificare quale personaggio vogliamo. Diciamo Turkey per impostazione predefinita. E poi chiamiamo questo nuovo processo alla fine del workflow, + +cowpy. E usiamo l'output qui da Collect Greetings. Quindi collect greetings out, out file qui. E poi abbiamo bisogno di un secondo argomento, che è il nuovo parametro che abbiamo appena creato. params punto character. + +## 2.2.4. Eseguire il workflow per verificare che funzioni + +Bene, vediamo se il nostro nuovo processo funziona. Nextflow run hello containers. Questo dovrebbe eseguire quei primi tre processi e poi provare a eseguire cowpy alla fine. + +Abbiamo un errore. Quello che sta dicendo qui, cowpy ha avuto un errore e aveva uno stato di uscita 127 e infatti, command sh cowpy command not found. + +Non abbiamo detto a Nextflow che abbiamo un'immagine Docker disponibile per cowpy, quindi ha provato a eseguirlo sul nostro sistema host e non abbiamo cowpy installato sul nostro sistema host, quindi ha innescato un errore. + +## 2.3. Usare un container per eseguirlo + +Quindi quello che dobbiamo fare è che dobbiamo dire a Nextflow che abbiamo un container disponibile. Andiamo al nostro processo cowpy e aggiungeremo una nuova direttiva in cima al processo chiamata container. + +Quindi troviamo la nostra immagine, copiamo l'URL e lo mettiamo in una stringa. + +Questo non è sufficiente di per sé perché un pipeline Nextflow può avere diversi modi per specificare il software. Potrei anche fare conda conda-forge cowpy, per esempio. E Nextflow deve sapere quale di queste tecnologie vuole utilizzare. + +## 2.3.2. Abilitare l'uso di Docker tramite il file nextflow.config + +Quindi, per eseguire con Docker abilitato, ci anticiperemo leggermente e useremo il file di configurazione Nextflow, che è qualcosa che tratteremo in modo più dettagliato nel prossimo capitolo. Può vedere in questa directory che abbiamo un file chiamato Nextflow Config, e qui ha già docker.enabled False. + +Lo cambieremo in True per abilitare Docker, e poi possiamo provare a eseguire di nuovo il workflow. + +## 2.3.3. Eseguire il workflow con Docker abilitato + +Nextflow run hello containers nf e questa volta cowpy è stato eseguito con successo. Guardiamo in Results. cowpy collected test e c'è il nostro Turkey. Meraviglioso. + +Quindi in background lì, Nextflow sapeva di avere un container disponibile per quel processo. + +Ha recuperato l'immagine e ha eseguito i comandi per noi. + +## 2.3.4. Ispezionare come Nextflow ha lanciato l'attività containerizzata + +Se è curioso, possiamo effettivamente vedere esattamente cosa ha fatto guardando nella directory work. Se faccio code work, e poi l'hash e poi command run, che se ricorda è il file effettivo che viene eseguito per quell'attività, possiamo entrare e possiamo cercare una funzione chiamata NXF launch. E qui può vedere l'esatto comando docker che Nextflow ha utilizzato, che assomiglia molto a quello che stavamo facendo manualmente nel terminale prima. Docker run. Collegamento di questa directory host nel container, e poi specificando l'URL del container. + +Quindi non c'è magia qui. È solo che Nextflow sta automaticamente facendo il lavoro pesante per Lei in un modo che significa che può facilmente specificare container nel Suo pipeline, che sono poi prontamente disponibili per chiunque altro utilizzi il Suo workflow. E quelle persone non devono più pensare alla gestione del software per eseguire il Suo pipeline di analisi. + +Molto, molto semplice, molto conveniente, e anche davvero riproducibile. Buono a tutto tondo. + +Bene, ottimo lavoro. Questa è la fine del Capitolo Cinque. Ci raggiunga nel prossimo video per la parte sei, che è la parte finale di questa formazione Hello Nextflow, dove parleremo della configurazione Nextflow in modo più dettagliato. + +Ci vediamo nel prossimo video. + +[Trascrizione del prossimo video :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/it/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..db2f24f8eb --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Parte 6: Hello Config - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo-passo, tornare al [materiale del corso](../06_hello_config.md). + + I numeri di sezione mostrati nella trascrizione sono forniti solo a scopo indicativo e potrebbero non includere tutti i numeri di sezione presenti nei materiali. + +## Benvenuto + +Salve, benvenuti alla parte sei del corso di formazione Hello Nextflow. + +Questo capitolo si chiama Hello Config, ed è la parte finale del nostro corso di formazione. + +In questo capitolo parleremo della configurazione di Nextflow. La configurazione di Nextflow è davvero potente. Ci permette di eseguire la stessa pipeline su diverse infrastrutture di calcolo con diversi sistemi di provisioning del software e diverse opzioni nella pipeline stessa. + +Questo significa che è possibile prendere pipeline Nextflow create da altre persone ed eseguirle sul proprio sistema, anche se potrebbero essere state create per un'infrastruttura completamente diversa. Questa capacità di configurare Nextflow rende i flussi di lavoro veramente portabili e condivisibili. + +In questo capitolo utilizzeremo il flusso di lavoro che abbiamo costruito nelle parti precedenti, ma non modificheremo affatto il codice del flusso di lavoro. Esamineremo solo il nostro file di configurazione Nextflow e vedremo come la modifica della configurazione altera il modo in cui Nextflow viene eseguito. + +Bene, iniziamo. + +Come prima, iniziamo andando su training.nextflow.io. Andiamo sulla sinistra su Hello Nextflow e capitolo sei, Hello config. Ora entrerò nel mio ambiente GitHub Codespaces e controllerò lo script che utilizzeremo. + +## 0. Preparazione: Verificare che Docker sia abilitato ed eseguire il flusso di lavoro Hello Config + +Questo si chiama Hello Config, e parte da dove eravamo prima. Quindi appare esattamente uguale con i nostri tre parametri: greetings per il file CSV, batch per il nome del batch di output e character per il nome cowpy. Abbiamo i nostri quattro import dei diversi processi, e poi abbiamo un flusso di lavoro dove li concateniamo insieme. + +Sto per chiudere questo file ora perché non toccheremo affatto il file Nextflow in questo capitolo. Lavoreremo esclusivamente all'interno del file di configurazione. Se guardo il file Nextflow.config che abbiamo brevemente esaminato nel precedente capitolo cinque, possiamo vedere che abbiamo una singola istruzione qui: Docker enabled equals true, che sta dicendo a Nextflow di usare Docker quando esegue questo flusso di lavoro. + +Sto usando Nextflow.config nella root della pipeline qui, che viene caricato automaticamente quando eseguo Nextflow. Ma ricordate, Nextflow può caricare file di configurazione da più posizioni. + +Se controllo con i documenti Nextflow vado su Configuration, potete vedere un elenco di questi luoghi e una priorità in cui vengono caricati. + +Bene. Verifichiamo che il nostro flusso di lavoro si stia eseguendo come previsto. Apro un terminale. Faccio Nextflow. Run. Hello, config. E premo invio. Dovremmo avere quei quattro processi in esecuzione, che terminano con un comando cowpy. Infatti, ha funzionato correttamente. Avevo Docker abilitato, ha scaricato Docker ed ha eseguito cowpy per me, proprio come ha fatto alla fine del capitolo cinque. + +## 1. Determinare quale tecnologia di packaging del software utilizzare + +Bene. Diciamo che sto eseguendo su un HPC e non ho Docker installato. La cosa migliore da fare in questo scenario sarebbe usare Singularity o Apptainer. Se dovessi farlo, andrei nel modulo cowpy e cambierei questo container per usare l'immagine singularity come ho mostrato nel capitolo precedente, con un oras://, che potete anche ottenere da Seqera Containers. + +Andrei poi su Nextflow.config impostando Docker enabled a false e farei singularity enabled equals true. O, se si usa Apptainer, apptainer enabled equals true e funzionerebbe. + +Nextflow supporta anche altre tecnologie oltre ai container, qualcosa con cui potreste avere familiarità è conda. Qui possiamo fare conda enabled equals true e impostare Docker a false. conda non usa la stessa direttiva container. Invece, possiamo aggiungerne una nuova qui chiamata conda. Specifichiamo quindi il pacchetto conda che vogliamo usare. È buona prassi essere il più specifici possibile per cercare di rendere la pipeline il più riproducibile possibile. Quindi specificherò il canale conda, conda-forge, e poi cowpy, e la versione esatta, che era 1.1.5. + +Potrei anche scrivere semplicemente cowpy se volessi, ma potrebbe risolversi in una versione diversa di cowpy in diverse esecuzioni della pipeline. + +La cosa bella di questo è che non ho toccato affatto la direttiva docker. Questa immagine Docker è ancora lì. Sto solo fornendo due alternative ora, e queste possono essere attivate o disattivate usando solo un file di configurazione. + +## 1.3. Eseguire il flusso di lavoro per verificare che possa utilizzare Conda + +Conda è ora abilitato, quindi proviamolo. + +Ottimo. È in esecuzione e potete vedere che c'è un messaggio da Nextflow qui che dice che Nextflow sta creando un ambiente conda per me, e sta usando questa posizione di cache. + +In background, Nextflow sta eseguendo comandi "conda create" per me per creare un nuovo ambiente conda isolato con solo i pacchetti che voglio, e poi installa e recupera quei pacchetti conda in modo che possa eseguire il processo. + +Potete vedere che ci è voluto un po' di tempo lì perché stava creando l'ambiente e installando il software per la prima volta. Tuttavia, ha memorizzato questo ambiente nella cache, quindi se eseguo di nuovo lo stesso comando Nextflow, dovrebbe essere molto più veloce perché riutilizzerà lo stesso ambiente conda. + +Una delle cose belle di questo è che queste direttive possono essere specificate a livello di processo, non solo per l'intero flusso di lavoro. Quindi, se volete, potete mescolare e abbinare quale tecnologia viene utilizzata per diversi processi. + +## 2. Allocare risorse di calcolo con le direttive di processo + +Il file di configurazione Nextflow può fare molto di più che solo il packaging del software. Possiamo anche dire a Nextflow come eseguire effettivamente i passaggi nella pipeline. Un esempio è dire a un sistema host quali risorse dovrebbero essere rese disponibili per ogni attività in esecuzione. + +Per impostazione predefinita, Nextflow non fornisce molto. Fornisce una singola CPU e solo due gigabyte di memoria per ogni processo. + +Questo è probabilmente qualcosa che vorremmo cambiare, in modo che i processi che richiedono molto tempo per essere eseguiti possano avere più risorse ed eseguirsi più rapidamente, ma può essere difficile sapere cosa allocare a un processo. Nextflow ha alcuni bei trucchi che possono aiutarvi in questo. + +## 2.1. Eseguire il flusso di lavoro per generare un report di utilizzo delle risorse + +Eseguiamo di nuovo il flusso di lavoro. Questa volta, aggiungerò un argomento aggiuntivo, che è dash with reports. È un'opzione principale di Nextflow, quindi è un singolo trattino. E poi qualsiasi nome di file mi piaccia. In questo caso, lo chiamerò report config one html. + +Eseguirò di nuovo il flusso di lavoro. Verrà eseguito esattamente come prima, ma mi darà un report di supporto aggiuntivo, che potete vedere è ora apparso qui nella barra laterale. + +Farò clic destro su questo file, cliccherò download, che lo scarica da GitHub Codespaces al mio sistema locale, in modo da poterlo poi visualizzare facilmente nel browser web qui sopra. + +Questo report può essere generato per qualsiasi esecuzione Nextflow, e contiene molte informazioni. Inizia in alto con alcuni metadati sul comando utilizzato, quando il flusso di lavoro è stato eseguito, quanto tempo ha impiegato, ma scorrendo verso il basso, otteniamo informazioni più dettagliate sulle risorse che sono state utilizzate da ogni passaggio della pipeline. + +Poiché ogni processo viene eseguito più volte per attività diverse, abbiamo un box plot che mostra la variazione delle risorse che abbiamo utilizzato per ogni processo. + +Se scorro un po' più in basso, vedo informazioni simili sulla memoria utilizzata e sulla durata del lavoro. Anche lettura e scrittura del disco. + +Potete immaginare per una grande pipeline con attività di lunga durata, questo può essere molto informativo su come mettere a punto la configurazione delle risorse che state richiedendo in modo da non richiederne troppe, ma anche in modo da poterne fornire abbastanza che si esegua rapidamente. + +Se continuo a scorrere il report, vediamo anche una tabella delle attività, che ci mostra informazioni dettagliate su ogni singola attività che è stata eseguita nel flusso di lavoro. Questo include informazioni come lo script risolto, che è stato eseguito. + +Bene, torniamo al nostro file di configurazione. Abbiamo visto che non avevamo davvero bisogno di molto per il nostro flusso di lavoro, quindi diciamo a Nextflow che abbiamo bisogno solo di un gigabyte di memoria per ogni processo nel flusso di lavoro. + +Ora quando lo definiamo così a livello di processo, questo viene applicato a ogni singolo processo nella pipeline. + +## 2.3. Impostare le allocazioni di risorse per un singolo processo + +Per il gusto della discussione, fingiamo che cowpy stia davvero facendo molto lavoro pesante e abbia bisogno di più risorse rispetto alle altre attività. Possiamo definire un blocco extra di configurazione qui, che si applica solo a quel processo usando, with name cowpy. + +Questo è chiamato selettore di configurazione, e possiamo definire diversi pattern qui per corrispondere a diversi processi. Per esempio, potrei fare cow star. Poi seguo con alcune parentesi graffe e diamogli due gigabyte di memoria invece di uno e diciamo due CPU. + +Ora Nextflow darà a ogni processo nel flusso di lavoro un gigabyte tranne questa richiesta, che è più specifica. Quindi la sovrascrive. E solo per qualsiasi processo che si chiama cowpy, otterrà due giga di memoria e due CPU. + +Notate che Nextflow è intelligente riguardo all'utilizzo delle risorse. Quindi se iniziate a mettere questi numeri a valori più alti, vedrete che Nextflow inizia a mettere in coda le sottomissioni di lavoro una dopo l'altra, piuttosto che eseguirle tutte in parallelo, in modo che non richieda eccessivamente le risorse disponibili. + +## 2.4. Eseguire il flusso di lavoro con la configurazione modificata + +Proviamo ad eseguire di nuovo il flusso di lavoro e salviamo un nuovo report questa volta. + +Bene, possiamo scaricare questo file e dare un'occhiata. + +Sì, non sorprendentemente, sembra praticamente esattamente lo stesso perché questo è un flusso di lavoro fittizio, che non sta facendo nulla di reale. Ma potete immaginare come questo approccio iterativo di definizione dei limiti e di esecuzione di flussi di lavoro reali con questo tipo di reportistica vi permetta di fare un approccio basato sull'evidenza per impostare una configurazione appropriata e sfruttare davvero al massimo le risorse computazionali che avete a disposizione. + +Potete iniziare ad essere davvero intelligenti riguardo a questo. Nextflow ha una capacità integrata di riprovare in caso di fallimenti, e potete sfruttare nel vostro file di configurazione utilizzando una closure come questa e impostando dinamicamente le risorse che vengono rese disponibili. Quindi qui ho detto a Nextflow di moltiplicare quei due gigabyte per il tentativo di retry. Quindi il secondo retry otterrà quattro giga, il terzo retry otterrà sei giga e così via. Questo va un po' oltre lo scopo di questo corso di formazione, ma se siete interessati, consultate i documenti Nextflow, che hanno una bella sezione sulla logica di retry dinamico. + +## 2.5. Aggiungere limiti di risorse + +Ora, una cosa che potreste notare su questo è che questo tipo di cosa potrebbe rendere piuttosto facile andare accidentalmente oltre le risorse disponibili sul vostro sistema. Se richiedete più risorse di quelle disponibili Nextflow genererà un errore sulla vostra configurazione e interromperà l'esecuzione. Per evitare ciò, potete usare qualcosa chiamato limiti di risorse. + +Sotto l'ambito del processo, nel nostro flusso di lavoro, possiamo definire limiti di risorse come questo, che prende un array, e possiamo specificare la memoria massima, le CPU e il tempo che sono disponibili su questo sistema. + +Impostare valori alti qui non aumenta la quantità di risorse richieste. Useremo ancora un gigabyte nelle nostre richieste, ma significa che se una qualsiasi di queste richieste arriva a 750, raggiungerà quel limite massimo e non verrà richiesto nulla di più, il che significa che Nextflow continuerà a funzionare e non si bloccherà a causa di risorse non disponibili. + +Quindi questa è una bella salvaguardia da usare, specialmente se state usando una logica dinamica con la vostra allocazione di risorse. + +L'altra situazione in cui questo è davvero utile è se state usando pipeline che sono pubbliche e non controllate da voi. Potrebbero venire con valori predefiniti di configurazione, e Nextflow prenderà automaticamente l'approccio giusto di sogliare qualsiasi richiesta di risorse per eseguire sul vostro sistema. + +Bene, ottimo. Abbiamo parlato di software. Abbiamo parlato di allocazione di risorse, e abbiamo descritto diversi ambiti di configurazione, sia per tutti i processi che per processi specifici. + +## 3. Utilizzare un file di parametri per memorizzare i parametri del flusso di lavoro + +Bene, ora rivolgeremo la nostra attenzione ai parametri. Possiamo definire parametri nel file di configurazione proprio come abbiamo fatto prima nello script Nextflow. Quindi params.greeting equals hello o usare l'ambito params e impostare foo equals bar. + +E questo è ottimo per impostare i valori predefiniti per il vostro flusso di lavoro. Tuttavia, quando si eseguono pipeline, può essere carino specificare parametri in un file JSON o YAML. + +Usare un file come questo è molto meglio che specificare opzioni da riga di comando con dash dash. Poiché quando si esegue un flusso di lavoro, potrebbe essere necessario specificare molti parametri e può essere noioso scriverli tutti in una singola CLI e soggetto a errori. Inoltre, è improbabile che ricordiate tutti i parametri che avete usato, quindi se li codificate in un file, è più facile avviare di nuovo il flusso di lavoro, usando gli stessi parametri in futuro. + +Abbiamo un file di esempio qui chiamato test params, e potete vedere che specifica i tre parametri che abbiamo nel nostro flusso di lavoro con tre valori diversi. Personalmente, trovo YAML più facile da scrivere rispetto a JSON. Quindi solo per dimostrare che funziona, creerò un nuovo file chiamato Test yaml e copierò questi dentro, eliminerò le virgolette. E salverò. + +Questi file JSON e YAML possono essere più facili da scrivere poiché hanno una sintassi più familiare. Ma notate che questi sono solo per parametri e accettano solo sintassi chiave-valore come questa. + +## 3.1. Eseguire il flusso di lavoro utilizzando un file di parametri + +Proviamolo. Faccio lo stesso comando di prima. Elimino il report e farò dash params file test params yaml. + +No, questa è un'opzione principale di Nextflow, quindi è un singolo trattino. + +Bene. Ha eseguito il flusso di lavoro e ha usato i parametri in quel file YAML invece che io specifichi tutti sulla riga di comando. Potrebbe sembrare eccessivo solo per questo semplice esempio, ma potete immaginare se avete 10 o 20 parametri diversi, può essere una seccatura digitare manualmente, e questo è semplicemente molto più facile da modificare in un editor di codice e conservare per motivi di riproducibilità. + +## 3. Determinare quale executor dovrebbe essere utilizzato per eseguire il lavoro + +Bene. Abbiamo parlato di packaging del software con Docker e conda. Abbiamo parlato dei requisiti di risorse di processo con CPU e memoria. E abbiamo parlato un po' di come specificare parametri quando si eseguono flussi di lavoro. + +Le parti finali della configurazione riguardano davvero l'esecuzione, l'infrastruttura di calcolo sottostante stessa, e questo è il vero gioiello della corona di Nextflow: che possiamo eseguire questi stessi flussi di lavoro su più diverse infrastrutture di calcolo. + +In realtà passerò al materiale di formazione scritto per un secondo. In questa parte della formazione, possiamo vedere alcuni esempi diversi di come diversi executor, in questo caso, schedulatori HPC, definiscono i requisiti di risorse necessari per sottomettere un lavoro. + +Quindi per Slurm, avete queste intestazioni SBATCH, che definiscono dash dash mem e il numero di CPU. Se state usando PBS, avete intestazioni diverse, e se usate Grid Engine, avete ancora intestazioni diverse. + +Potete immaginare che sia ancora più diverso se volete eseguire sul cloud, sia esso AWS batch, Google Cloud, Azure o altro. + +Ognuna di queste infrastrutture di calcolo sottostanti è chiamata executor e Nextflow sa come comunicare con tutti questi diversi executor per sottomettere lavori con la sintassi corretta. + +La buona notizia è che non dovete sapere di questo. Tutto quello che dovete fare è dire a Nextflow, quale executor usare. + +## 3.1. Indirizzare un backend diverso + +Torniamo al nostro file di configurazione e al processo facciamo executor, e scriverò local. + +Local è in realtà quello predefinito, se non specificate nessun altro executor, local è quello che verrà usato, e questo significa semplicemente il vostro sistema host, ovunque abbiate lanciato Nextflow, + +Potrei specificare invece, Slurm. E questo sottometterebbe lavori Slurm, oppure potrei dire AWS batch, e questo sottometterebbe lavori ad AWS batch. + +Avete bisogno di una configurazione aggiuntiva in alcuni casi, per esempio, eseguire sul cloud avrà bisogno di certe credenziali, ma davvero questo è il nucleo di esso, e può essere semplice come una o due righe di configurazione per eseguire il vostro flusso di lavoro in un ambiente di calcolo completamente diverso. + +Anche se stiamo eseguendo su un sistema semplice all'interno di Codespaces, posso ancora giocare un po' con questo e fingere che stiamo eseguendo su Slurm. Se poi lancio di nuovo il flusso di lavoro, Nextflow run, hello config. Fallirà perché non sarà in grado di sottomettere lavori a Slurm. Ma possiamo ancora andare nelle directory di lavoro e vedere cosa ha fatto Nextflow. Quindi se andiamo in questa directory di lavoro e guardiamo Command Run. Potete vedere in cima a questo file, ora abbiamo queste righe di intestazione sbatch, che hanno provato a specificare le risorse necessarie per il lavoro Slurm. + +## 4. Utilizzare i profili per selezionare configurazioni preimpostate + +Bene, ci siamo quasi. La parte finale di questo capitolo parla dei profili di configurazione. Se state eseguendo la vostra pipeline su diversi sistemi, potrebbe essere fastidioso avere tutti questi diversi file di configurazione Nextflow, che dovete specificare ogni volta. + +Invece, potete codificare raggruppamenti di configurazione all'interno del vostro file di configurazione Nextflow, e attivare o disattivare quei gruppi usando un flag di profilo. Vediamo come appare. + +## 4.1. Creare profili per passare tra sviluppo locale ed esecuzione su HPC + +Creeremo due profili nel nostro esempio qui, uno per il mio laptop e uno per un sistema HPC più pesante. Barò un po' e copierò semplicemente il codice dal materiale di formazione e lo metterò qui. + +Abbiamo un nuovo ambito chiamato profiles, e poi abbiamo un nome per ogni profilo, che può essere qualsiasi cosa. E all'interno di quello abbiamo una configurazione, che sembra esattamente la stessa della configurazione di primo livello che abbiamo già scritto. Quindi di nuovo, abbiamo l'ambito del processo. L'ambito di Docker. + +Sul profilo chiamato my laptop. Sto dicendo di eseguire usando l'executor local, quindi sul mio sistema host e di usare Docker. + +Sul profilo university HPC qui sto dicendo di usare Slurm per sottomettere lavori, di usare conda invece di Docker, e sto specificando diversi limiti di risorse, che potrebbero corrispondere alla dimensione del sistema dei nodi sull'HPC che sto usando. + +Per impostazione predefinita, nessuna di questa configurazione verrà utilizzata quando eseguo Nextflow, devo specificare che voglio usare uno di questi profili. + +## 4.2. Eseguire il flusso di lavoro con un profilo + +Facciamo nextflow run hello config. E farò dash profile, singolo trattino perché è un'opzione principale di Nextflow. E poi il nome che gli ho dato, che è my laptop. Nextflow dovrebbe ora usare il blocco di configurazione che è stato specificato all'interno di quel profilo di configurazione, e applicarlo quando esegue Nextflow. Se volessi usare l'altro blocco di configurazione, devo solo cambiare quel nome di profilo. Molto più facile da ricordare. Molto più facile da usare. + +## 4.3. Creare un profilo di test + +Notate, i profili possono avere qualsiasi tipo di configurazione, quindi non deve essere correlato al vostro ambiente di esecuzione. Per esempio, creiamo un nuovo profilo qui, che ha un insieme di parametri. Possiamo cambiare questo in tux e cambiare in my profile, e ora quando facciamo profile test, specificherà questi parametri, che sovrascriveranno i parametri specificati al livello superiore del flusso di lavoro. + +Quando eseguite Nextflow, potete concatenare più profili e verranno applicati in sequenza. + +## 4.4. Eseguire il flusso di lavoro localmente con il profilo di test + +Quindi posso prendere il comando precedente e fare virgola test. Questo applicherà la configurazione my laptop per prima, e poi applicherà la configurazione test. Se c'è qualche sovrapposizione, allora il profilo a destra sovrascriverà qualsiasi configurazione nei profili precedenti. Se premo invio, vediamo cosa succede. + +Bene, abbiamo un nuovo file di risultati qui. Potete vedere My Profile, che ho specificato come una delle opzioni. E possiamo anche vedere cowpy, my profile, e infatti, c'è tux. Quindi ha funzionato. + +## Conclusione + +Bene! Fantastico. È tutto. Siete arrivati alla fine del corso. Avete un po' di coriandoli di celebrazione. Ben fatto per aver finito questo capitolo. + +[Trascrizione del video successivo :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/it/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/it/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..cea64723c6 --- /dev/null +++ b/docs/it/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Prossimi Passi - Trascrizione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Note importanti" + + Questa pagina mostra solo la trascrizione. Per le istruzioni complete passo dopo passo, torni al [materiale del corso](../05_hello_containers.md). + +## Benvenuto + +Congratulazioni, ce l'ha fatta. Ha completato il primo corso di formazione Nextflow, chiamato Hello Nextflow. + +Ben fatto. La ringraziamo per aver seguito il corso e apprezziamo molto il tempo e l'impegno che ha dedicato all'apprendimento di Nextflow, e speriamo sinceramente che Le sia utile per il Suo lavoro. + +## Prossimi Passi + +Per i prossimi passi, tenga d'occhio il portale di formazione: training.nextflow.io. Pubblichiamo continuamente nuovo materiale del corso e lo aggiorniamo regolarmente. Potrebbe quindi trovare formazione più avanzata o formazione specifica per un campo di ricerca di Suo interesse. + +In particolare, consulti la pagina Nextflow for Science. Questa contiene una serie di corsi brevi che sono autonomi e che estendono ciò che ha imparato in Hello Nextflow a casi d'uso specifici. + +Ce n'è uno per la Genomica e anche uno per l'RNA-seq. Speriamo di portarne presto altri. + +## Side Quests + +Ci sono molti argomenti di cui avremmo potuto parlare in Hello Nextflow, ma che sarebbero stati troppo dettagliati. Alcuni di questi argomenti li stiamo inserendo nei Side Quests, che sono corsi brevi su temi specifici. + +Ci sono anche i corsi più ampi di formazione fondamentale e formazione avanzata, che potrebbero includere contenuti di Suo interesse. + +## nf-core + +È stato menzionato una o due volte in questo corso, ma consulti sicuramente il progetto nf-core. Ci sono oltre cento pipeline per diversi tipi di dati, quindi è del tutto possibile che non debba costruire la propria pipeline. + +Ci sono anche quasi millecinquecento moduli di processo dove, se utilizza gli strumenti di sviluppo nf-core, può creare una pipeline e importare quei moduli in pochi secondi. + +## Seqera Platform + +Infine, una rapida presentazione di Seqera Platform. Questo è senza dubbio il modo migliore per eseguire Nextflow nella pratica, è una piattaforma basata sul cloud, ma Lei collega la propria infrastruttura di calcolo, che sia il proprio account cloud su AWS, Google Batch o Azure, o persino il proprio HPC. Il livello gratuito è disponibile per tutti, e se è un accademico, può candidarsi al nostro programma accademico per un accesso gratuito di livello pro. + +Seqera Platform va oltre una semplice interfaccia grafica per avviare e monitorare i workflow. Ci sono anche strumenti aggiuntivi come Data Studios per eseguire sessioni interattive e strumenti fondamentali come Fusion, che offre un accesso ai dati più veloce ed economico sul cloud. + +## Supporto ed eventi + +Ricordi, se dovesse incontrare qualsiasi difficoltà, vada su community.seqera.io. Il nostro forum è molto attivo, la comunità Nextflow è estremamente forte e ci sono quasi sempre persone pronte ad aiutare, sia per la formazione che per qualsiasi cosa riguardante l'uso quotidiano di Nextflow. + +E naturalmente, un ottimo prossimo passo è partecipare a uno dei nostri eventi della comunità, che sia un hackathon nf-core o uno degli eventi Nextflow Summit. Sono molto divertenti e sarebbe davvero bello incontrarLa lì e parlare di come sta utilizzando Nextflow. + +## Ringraziamenti + +Vorrei ringraziare enormemente tutti coloro che sono stati coinvolti nella scrittura di questo materiale di formazione. Io l'ho presentato, ma tutto il lavoro duro è stato fatto dal team di formazione di Seqera. In particolare Geraldine, che ha dedicato un'enorme quantità di lavoro alla riscrittura di questo materiale. + +Anche Marcel, Ken, Adam, John, altri del team di sviluppo scientifico e altri membri della comunità. + +## Sondaggio di feedback + +Ora che ha completato il corso, ci piacerebbe sapere cosa ne pensa. Su training.nextflow.io, troverà un sondaggio di feedback sotto la sezione Hello Nextflow. + +Ci sono solo quattro domande ma è davvero importante per noi. Se non altro, ci dice approssimativamente quante persone stanno seguendo la formazione. Ci dice anche se Le è piaciuto e se ha suggerimenti, li inserisca pure alla fine. Leggiamo ogni singola risposta. + +Se individua errori, tutto è open source su GitHub, quindi può creare un issue o fare una pull request o lasciarci un messaggio nel forum. Ci piacerebbe sapere cosa ne pensa e come potremmo migliorarlo. Grazie ancora. Speriamo di vederLa presto. diff --git a/docs/it/docs/hello_nf-core/00_orientation.md b/docs/it/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..d397bbe705 --- /dev/null +++ b/docs/it/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Iniziare + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Avviare un ambiente di formazione + +Per utilizzare l'ambiente preconfigurato che forniamo su GitHub Codespaces, cliccate sul pulsante "Open in GitHub Codespaces" qui sotto. Per altre opzioni, consultate [Opzioni di ambiente](../envsetup/index.md). + +Consigliamo di aprire l'ambiente di formazione in una nuova scheda o finestra del browser (utilizzi il clic destro, ctrl-clic o cmd-clic a seconda della sua dotazione) in modo da poter continuare a leggere mentre l'ambiente si carica. +Dovrà tenere queste istruzioni aperte in parallelo per seguire il corso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Nozioni di base sull'ambiente + +Questo ambiente di formazione contiene tutto il software, il codice e i dati necessari per seguire il corso di formazione, quindi non dovrà installare nulla da sola/o. + +Il codespace è configurato con un'interfaccia VSCode, che include un esploratore del filesystem, un editor di codice e una shell di terminale. +Tutte le istruzioni fornite durante il corso (ad es. 'aprite il file', 'modificate il codice' o 'eseguite questo comando') si riferiscono a queste tre parti dell'interfaccia VSCode, salvo diversa indicazione. + +Se sta seguendo questo corso autonomamente, Vi preghiamo di familiarizzare con le [nozioni di base sull'ambiente](../envsetup/01_setup.md) per ulteriori dettagli. + +### Requisiti di versione + +Questa formazione è progettata per **Nextflow 25.10.2** o successivo **con il parser di sintassi v2 DISABILITATO**. + +#### Se sta utilizzando il nostro ambiente di formazione: + +DEVE eseguire il seguente comando prima di procedere oltre: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Se state utilizzando un ambiente locale o personalizzato: + +Assicuratevi di utilizzare le impostazioni corrette come documentato [qui](../info/nxf_versions.md). + +La formazione richiede inoltre **nf-core tools 3.4.1**. +Se utilizzate una versione diversa degli strumenti nf-core, potreste avere difficoltà a seguire. + +Potete verificare quale versione è installata nel vostro ambiente utilizzando il comando `nf-core --version`. + +## Prepararsi a lavorare + +Una volta che il vostro codespace è in esecuzione, ci sono due cose da fare prima di immergersi nella formazione: impostare la directory di lavoro per questo corso specifico e dare un'occhiata ai materiali forniti. + +### Impostare la directory di lavoro + +Per impostazione predefinita, il codespace si apre con la directory di lavoro impostata alla radice di tutti i corsi di formazione, ma per questo corso lavoreremo nella directory `hello-nf-core/`. + +Cambiate directory ora eseguendo questo comando nel terminale: + +```bash +cd hello-nf-core/ +``` + +!!! tip "Suggerimento" + + Se per qualsiasi motivo vi spostate fuori da questa directory (ad es. il vostro codespace va in sospensione), potete sempre utilizzare il percorso completo per ritornarvi, supponendo che stiate eseguendo questo all'interno dell'ambiente di formazione Github Codespaces: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Ora diamo un'occhiata al contenuto di questa directory. + +### Esplorare i materiali forniti + +Potete esplorare il contenuto di questa directory utilizzando l'esploratore di file sul lato sinistro dello spazio di lavoro di formazione. +In alternativa, potete utilizzare il comando `tree`. + +Durante il corso, utilizziamo l'output di `tree` per rappresentare la struttura e il contenuto delle directory in forma leggibile, a volte con lievi modifiche per chiarezza. + +Qui generiamo un indice dei contenuti fino al secondo livello: + +```bash +tree . -L 2 +``` + +??? abstract "Contenuto della directory" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Clicchi sulla casella colorata per espandere la sezione e visualizzarne il contenuto. +Utilizziamo sezioni espandibili come questa per includere l'output previsto dei comandi in modo conciso. + +- **Il file `greetings.csv`** è un CSV contenente alcuni dati colonnari minimi che utilizziamo a scopo di test. + +- **La directory `original-hello`** contiene una copia del codice sorgente prodotto lavorando attraverso la serie completa di formazione Hello Nextflow (con Docker abilitato). + +- **La directory `solutions`** contiene gli script del flusso di lavoro completati che risultano da ogni fase del corso. + Sono destinati a essere utilizzati come riferimento per verificare il suo lavoro e risolvere eventuali problemi. + +## Lista di controllo della preparazione + +Pensa di essere pronto/a per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio ambiente è attivo e funzionante +- [ ] Mi sono assicurato/a che il parser di sintassi sia impostato su **v1** +- [ ] Ho impostato la mia directory di lavoro in modo appropriato + +Se potete spuntare tutte le caselle, siete pronti per iniziare. + +**Per continuare con la Parte 1, cliccate sulla freccia nell'angolo in basso a destra di questa pagina.** diff --git a/docs/it/docs/hello_nf-core/01_run_demo.md b/docs/it/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..4562e326af --- /dev/null +++ b/docs/it/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,644 @@ +# Parte 1: Eseguire una pipeline demo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa prima parte del corso di formazione Hello nf-core, mostreremo come trovare e provare una pipeline nf-core, comprendere come è organizzato il codice e riconoscere come differisce dal codice Nextflow semplice mostrato in [Hello Nextflow](../hello_nextflow/index.md). + +Utilizzeremo una pipeline chiamata nf-core/demo che è mantenuta dal progetto nf-core come parte del suo inventario di pipeline per dimostrare la struttura del codice e le operazioni degli strumenti. + +Assicuratevi che la vostra directory di lavoro sia impostata su `hello-nf-core/` come indicato nella pagina [Iniziare](./00_orientation.md). + +--- + +## 1. Trovare e recuperare la pipeline nf-core/demo + +Iniziamo localizzando la pipeline nf-core/demo sul sito web del progetto [nf-co.re](https://nf-co.re), che centralizza tutte le informazioni come: documentazione generale e articoli di aiuto, documentazione per ciascuna delle pipeline, post di blog, annunci di eventi e così via. + +### 1.1. Trovare la pipeline sul sito web + +Nel vostro browser web, vada su [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) e digiti `demo` nella barra di ricerca. + +![risultati della ricerca](./img/search-results.png) + +Clicchi sul nome della pipeline, `demo`, per accedere alla pagina di documentazione della pipeline. + +Ogni pipeline rilasciata ha una pagina dedicata che include le seguenti sezioni di documentazione: + +- **Introduction:** Un'introduzione e panoramica della pipeline +- **Usage:** Descrizioni di come eseguire la pipeline +- **Parameters:** Parametri della pipeline raggruppati con descrizioni +- **Output:** Descrizioni ed esempi dei file di output previsti +- **Results:** File di output di esempio generati dal dataset di test completo +- **Releases & Statistics:** Cronologia delle versioni della pipeline e statistiche + +Quando sta considerando di adottare una nuova pipeline, dovrebbe leggere attentamente la documentazione della pipeline prima per comprendere cosa fa e come dovrebbe essere configurata prima di tentare di eseguirla. + +Dia un'occhiata ora e veda se riesce a scoprire: + +- Quali strumenti la pipeline eseguirà (Controlli la scheda: `Introduction`) +- Quali input e parametri la pipeline accetta o richiede (Controlli la scheda: `Parameters`) +- Quali sono gli output prodotti dalla pipeline (Controlli la scheda: `Output`) + +#### 1.1.1. Panoramica della pipeline + +La scheda `Introduction` fornisce una panoramica della pipeline, inclusa una rappresentazione visiva (chiamata mappa della metropolitana) e un elenco di strumenti che vengono eseguiti come parte della pipeline. + +![mappa della metropolitana della pipeline](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Esempio di riga di comando + +La documentazione fornisce anche un file di input di esempio (discusso ulteriormente più avanti) e un esempio di riga di comando. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Noterà che il comando di esempio NON specifica un file workflow, solo il riferimento al repository della pipeline, `nf-core/demo`. + +Quando invocato in questo modo, Nextflow assumerà che il codice sia organizzato in un certo modo. +Recuperiamo il codice così possiamo esaminare questa struttura. + +### 1.2. Recuperare il codice della pipeline + +Una volta determinato che la pipeline sembra essere adatta ai nostri scopi, proviamola. +Fortunatamente Nextflow rende facile recuperare pipeline da repository formattati correttamente senza dover scaricare nulla manualmente. + +Torniamo al terminale ed eseguiamo quanto segue: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Output del comando" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow esegue un `pull` del codice della pipeline, cioè scarica il repository completo sul vostro disco locale. + +Per essere chiari, potete farlo con qualsiasi pipeline Nextflow che sia configurata appropriatamente in GitHub, non solo le pipeline nf-core. +Tuttavia nf-core è la più grande collezione open-source di pipeline Nextflow. + +Potete ottenere da Nextflow un elenco di quali pipeline avete recuperato in questo modo: + +```bash +nextflow list +``` + +??? success "Output del comando" + + ```console + nf-core/demo + ``` + +Noterete che i file non sono nella vostra directory di lavoro corrente. +Per impostazione predefinita, Nextflow li salva in `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Contenuto della directory" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + Il percorso completo potrebbe differire sul vostro sistema se non state utilizzando il nostro ambiente di formazione. + +Nextflow mantiene intenzionalmente il codice sorgente scaricato 'fuori mano' sul principio che queste pipeline dovrebbero essere utilizzate più come librerie che come codice con cui interagire direttamente. + +Tuttavia, per gli scopi di questa formazione, vogliamo essere in grado di esplorare e vedere cosa c'è dentro. +Quindi per rendere ciò più facile, creiamo un collegamento simbolico a quella posizione dalla nostra directory di lavoro corrente. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Questo crea una scorciatoia che rende più facile esplorare il codice appena scaricato. + +```bash +tree -L 2 pipelines +``` + +```console title="Contenuto della directory" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Ora possiamo più facilmente sbirciare nel codice sorgente secondo necessità. + +Ma prima, proviamo ad eseguire la nostra prima pipeline nf-core! + +### Takeaway + +Ora sapete come trovare una pipeline tramite il sito web nf-core e recuperare una copia locale del codice sorgente. + +### Prossimi passi + +Imparate come provare una pipeline nf-core con il minimo sforzo. + +--- + +## 2. Provare la pipeline con il suo profilo di test + +Convenientemente, ogni pipeline nf-core viene fornita con un profilo di test. +Questo è un set minimo di impostazioni di configurazione per l'esecuzione della pipeline utilizzando un piccolo dataset di test ospitato nel repository [nf-core/test-datasets](https://github.com/nf-core/test-datasets). +È un ottimo modo per provare rapidamente una pipeline su piccola scala. + +!!! note + + Il sistema di profili di configurazione di Nextflow Le permette di passare facilmente tra diversi motori di container o ambienti di esecuzione. + Per maggiori dettagli, veda [Hello Nextflow Parte 6: Configuration](../hello_nextflow/06_hello_config.md). + +### 2.1. Esaminare il profilo di test + +È buona pratica verificare cosa specifica il profilo di test di una pipeline prima di eseguirla. +Il profilo `test` per `nf-core/demo` risiede nel file di configurazione `conf/test.config` ed è mostrato di seguito. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dati di input + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Noterà subito che il blocco di commenti in alto include un esempio di utilizzo che mostra come eseguire la pipeline con questo profilo di test. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Le uniche cose che dobbiamo fornire sono quelle mostrate tra parentesi angolari nell'esempio di comando: `<docker/singularity>` e `<OUTDIR>`. + +Come promemoria, `<docker/singularity>` si riferisce alla scelta del sistema di container. Tutte le pipeline nf-core sono progettate per essere utilizzabili con container (Docker, Singularity, ecc.) per garantire la riproducibilità ed eliminare problemi di installazione del software. +Quindi dovremo specificare se vogliamo usare Docker o Singularity per testare la pipeline. + +La parte `--outdir <OUTDIR>` si riferisce alla directory in cui Nextflow scriverà gli output della pipeline. +Dobbiamo fornire un nome per essa, che possiamo semplicemente inventare. +Se non esiste già, Nextflow la creerà per noi durante l'esecuzione. + +Passando alla sezione dopo il blocco di commenti, il profilo di test ci mostra cosa è stato preconfigurato per il test: in particolare, il parametro `input` è già impostato per puntare a un dataset di test, quindi non dobbiamo fornire i nostri dati. +Se segue il link all'input preconfigurato, vedrà che è un file csv contenente identificatori di campioni e percorsi di file per diversi campioni sperimentali. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Questo è chiamato samplesheet, ed è la forma più comune di input per le pipeline nf-core. + +!!! note + + Non si preoccupi se non ha familiarità con i formati e i tipi di dati, non è importante per quello che segue. + +Quindi questo conferma che abbiamo tutto ciò di cui abbiamo bisogno per provare la pipeline. + +### 2.2. Eseguire la pipeline + +Decidiamo di usare Docker per il sistema di container e `demo-results` come directory di output, e siamo pronti per eseguire il comando di test: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Se il vostro output corrisponde a quello, congratulazioni! Avete appena eseguito la vostra prima pipeline nf-core. + +Noterete che c'è molto più output sulla console rispetto a quando eseguite una pipeline Nextflow di base. +C'è un'intestazione che include un riepilogo della versione della pipeline, input e output, e alcuni elementi di configurazione. + +!!! note + + Il vostro output mostrerà timestamp, nomi di esecuzione e percorsi di file diversi, ma la struttura complessiva e l'esecuzione dei processi dovrebbero essere simili. + +Passando all'output di esecuzione, diamo un'occhiata alle righe che ci dicono quali processi sono stati eseguiti: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Questo ci dice che sono stati eseguiti tre processi, corrispondenti ai tre strumenti mostrati nella pagina di documentazione della pipeline sul sito web nf-core: FASTQC, SEQTK_TRIM e MULTIQC. + +I nomi completi dei processi come mostrati qui, come `NFCORE_DEMO:DEMO:MULTIQC`, sono più lunghi di quelli che potreste aver visto nel materiale introduttivo Hello Nextflow. +Questi includono i nomi dei loro workflow padre e riflettono la modularità del codice della pipeline. +Entreremo più nel dettaglio tra poco. + +### 2.3. Esaminare gli output della pipeline + +Infine, diamo un'occhiata alla directory `demo-results` prodotta dalla pipeline. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Contenuto della directory" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Potrebbe sembrare molto. +Per saperne di più sugli output della pipeline `nf-core/demo`, consulti la sua [pagina di documentazione](https://nf-co.re/demo/1.0.2/docs/output/). + +In questa fase, ciò che è importante osservare è che i risultati sono organizzati per modulo, e c'è inoltre una directory chiamata `pipeline_info` contenente vari report con timestamp sull'esecuzione della pipeline. + +Per esempio, il file `execution_timeline_*` vi mostra quali processi sono stati eseguiti, in quale ordine e quanto tempo hanno impiegato per essere eseguiti: + +![report della timeline di esecuzione](./img/execution_timeline.png) + +!!! note + + Qui le attività non sono state eseguite in parallelo perché stiamo eseguendo su una macchina minimalista in Github Codespaces. + Per vedere queste eseguite in parallelo, provate ad aumentare l'allocazione CPU del vostro codespace e i limiti di risorse nella configurazione di test. + +Questi report sono generati automaticamente per tutte le pipeline nf-core. + +### Takeaway + +Sapete come eseguire una pipeline nf-core utilizzando il suo profilo di test integrato e dove trovare i suoi output. + +### Prossimi passi + +Imparate come è organizzato il codice della pipeline. + +--- + +## 3. Esaminare la struttura del codice della pipeline + +Ora che abbiamo eseguito con successo la pipeline come utenti, spostiamo la nostra prospettiva per guardare come le pipeline nf-core sono strutturate internamente. + +Il progetto nf-core applica linee guida rigorose su come le pipeline sono strutturate e su come il codice è organizzato, configurato e documentato. +Comprendere come tutto questo è organizzato è il primo passo verso lo sviluppo delle proprie pipeline compatibili con nf-core, che affronteremo nella Parte 2 di questo corso. + +Diamo un'occhiata a come il codice della pipeline è organizzato nel repository `nf-core/demo`, utilizzando il symlink `pipelines` che abbiamo creato in precedenza. + +Potete usare `tree` o utilizzare l'esploratore di file per trovare e aprire la directory `nf-core/demo`. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Contenuto della directory" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +C'è molto in corso là dentro, quindi affronteremo questo passo per passo. + +Prima, notiamo che al livello superiore, potete trovare un file README con informazioni di riepilogo, così come file accessori che riassumono informazioni sul progetto come licenza, linee guida per i contributi, citazioni e codice di condotta. +La documentazione dettagliata della pipeline si trova nella directory `docs`. +Tutto questo contenuto viene utilizzato per generare le pagine web sul sito web nf-core in modo programmatico, quindi sono sempre aggiornate con il codice. + +Ora, per il resto, divideremo la nostra esplorazione in tre fasi: + +1. Componenti del codice della pipeline (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Configurazione della pipeline +3. Input e validazione + +Iniziamo con i componenti del codice della pipeline. +Ci concentreremo sulla gerarchia dei file e sull'organizzazione strutturale, piuttosto che immergerci nel codice all'interno dei singoli file. + +### 3.1. Componenti del codice della pipeline + +L'organizzazione standard del codice della pipeline nf-core segue una struttura modulare progettata per massimizzare il riutilizzo del codice, come introdotto in [Hello Modules](../hello_nextflow/04_hello_modules.md), Parte 4 del corso [Hello Nextflow](../hello_nextflow/index.md), sebbene nel vero stile nf-core, questo sia implementato con un po' di complessità aggiuntiva. +Specificamente, le pipeline nf-core fanno uso abbondante di subworkflow, cioè script di workflow che sono importati da un workflow padre. + +Questo potrebbe sembrare un po' astratto, quindi diamo un'occhiata a come viene utilizzato nella pratica nella pipeline `nf-core/demo`. + +!!! note + + Non esamineremo il codice effettivo per _come_ questi componenti modulari sono connessi, perché c'è una certa complessità aggiuntiva associata all'uso dei subworkflow che può risultare confusa, e comprendere questo non è necessario in questa fase della formazione. + Per ora, ci concentreremo sull'organizzazione generale e sulla logica. + +#### 3.1.1. Panoramica generale + +Ecco come appaiono le relazioni tra i componenti di codice rilevanti per la pipeline `nf-core/demo`: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +C'è un cosiddetto script _entrypoint_ chiamato `main.nf`, che funge da wrapper per due tipi di workflow nidificati: il workflow contenente la logica di analisi effettiva, situato sotto `workflows/` e chiamato `demo.nf`, e un set di workflow di gestione situati sotto `subworkflows/`. +Il workflow `demo.nf` richiama **moduli** situati sotto `modules/`; questi contengono i **processi** che eseguiranno le effettive fasi di analisi. + +!!! note + + I subworkflow non sono limitati a funzioni di gestione e possono utilizzare moduli di processo. + + La pipeline `nf-core/demo` mostrata qui si trova sul lato più semplice dello spettro, ma altre pipeline nf-core (come `nf-core/rnaseq`) utilizzano subworkflow che sono coinvolti nell'analisi effettiva. + +Ora, esaminiamo questi componenti a turno. + +#### 3.1.2. Lo script entrypoint: `main.nf` + +Lo script `main.nf` è l'entrypoint da cui parte Nextflow quando eseguiamo `nextflow run nf-core/demo`. +Ciò significa che quando esegue `nextflow run nf-core/demo` per eseguire la pipeline, Nextflow trova ed esegue automaticamente lo script `main.nf`. +Questo funziona per qualsiasi pipeline Nextflow che segua questa convenzione di denominazione e struttura, non solo le pipeline nf-core. + +L'uso di uno script entrypoint rende facile eseguire subworkflow di 'gestione' standardizzati prima e dopo l'esecuzione dello script di analisi effettivo. +Esamineremo questi dopo aver esaminato il workflow di analisi effettivo e i suoi moduli. + +#### 3.1.3. Lo script di analisi: `workflows/demo.nf` + +Il workflow `workflows/demo.nf` è dove è memorizzata la logica centrale della pipeline. +È strutturato molto come un normale workflow Nextflow, tranne che è progettato per essere chiamato da un workflow padre, il che richiede alcune funzionalità extra. +Copriremo le differenze rilevanti nella prossima parte di questo corso, quando affronteremo la conversione della semplice pipeline Hello da Hello Nextflow in una forma compatibile con nf-core. + +Il workflow `demo.nf` richiama **moduli** situati sotto `modules/`, che esamineremo successivamente. + +!!! note + + Alcuni workflow di analisi nf-core mostrano livelli aggiuntivi di nidificazione richiamando subworkflow di livello inferiore. + Questo è usato principalmente per incapsulare due o più moduli che sono comunemente usati insieme in segmenti di pipeline facilmente riutilizzabili. + Può vedere alcuni esempi esplorando i [subworkflow nf-core](https://nf-co.re/subworkflows/) disponibili sul sito web nf-core. + + Quando lo script di analisi usa subworkflow, questi sono memorizzati sotto la directory `subworkflows/`. + +#### 3.1.4. I moduli + +I moduli sono dove risiede il codice del processo, come descritto nella [Parte 4 del corso di formazione Hello Nextflow](../hello_nextflow/04_hello_modules.md). + +Nel progetto nf-core, i moduli sono organizzati utilizzando una struttura nidificata multi-livello che riflette sia la loro origine che il loro contenuto. +Al livello superiore, i moduli sono differenziati come `nf-core` o `local` (non parte del progetto nf-core), e poi ulteriormente posizionati in una directory denominata in base allo strumento/agli strumenti che incapsulano. +Se lo strumento appartiene a un toolkit (cioè un pacchetto contenente più strumenti) allora c'è un livello di directory intermedio denominato in base al toolkit. + +Può vedere questo applicato nella pratica ai moduli della pipeline `nf-core/demo`: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Contenuto della directory" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Qui vede che i moduli `fastqc` e `multiqc` si trovano al livello superiore all'interno dei moduli `nf-core`, mentre il modulo `trim` si trova sotto il toolkit a cui appartiene, `seqtk`. +In questo caso non ci sono moduli `local`. + +Il file del codice del modulo che descrive il processo è sempre chiamato `main.nf`, ed è accompagnato da test e file `.yml` che ignoreremo per ora. + +Presi insieme, il workflow entrypoint, il workflow di analisi e i moduli sono sufficienti per eseguire le parti 'interessanti' della pipeline. +Tuttavia, sappiamo che ci sono anche subworkflow di gestione lì dentro, quindi guardiamoli ora. + +#### 3.1.5. I subworkflow di gestione + +Come i moduli, i subworkflow sono differenziati in directory `local` e `nf-core`, e ogni subworkflow ha la propria struttura di directory nidificata con il proprio script `main.nf`, test e file `.yml`. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Contenuto della directory" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Come notato sopra, la pipeline `nf-core/demo` non include subworkflow specifici per l'analisi, quindi tutti i subworkflow che vediamo qui sono cosiddetti workflow di 'gestione' o 'utility', come denotato dal prefisso `utils_` nei loro nomi. +Questi subworkflow sono ciò che produce l'intestazione nf-core elegante nell'output della console, tra altre funzioni accessorie. + +!!! tip + + Oltre al loro pattern di denominazione, un'altra indicazione che questi subworkflow non eseguono alcuna funzione realmente correlata all'analisi è che non richiamano alcun processo. + +Questo completa il riepilogo dei componenti di codice centrali che costituiscono la pipeline `nf-core/demo`. +Ora diamo un'occhiata agli elementi rimanenti che dovrebbe conoscere un po' prima di immergersi nello sviluppo: configurazione della pipeline e validazione dell'input. + +### 3.2. Configurazione della pipeline + +Ha appreso in precedenza che Nextflow offre molte opzioni per configurare l'esecuzione della pipeline, sia in termini di input e parametri, risorse di calcolo e altri aspetti dell'orchestrazione. +Il progetto nf-core applica linee guida altamente standardizzate per la configurazione della pipeline che mirano a costruire sulle opzioni di personalizzazione flessibili di Nextflow in un modo che fornisca maggiore coerenza e manutenibilità tra le pipeline. + +Il file di configurazione centrale `nextflow.config` è utilizzato per impostare i valori predefiniti per i parametri e altre opzioni di configurazione. +La maggior parte di queste opzioni di configurazione sono applicate per impostazione predefinita mentre altre (ad esempio, profili di dipendenze software) sono incluse come profili opzionali. + +Ci sono diversi file di configurazione aggiuntivi che sono memorizzati nella cartella `conf` e che possono essere aggiunti alla configurazione per impostazione predefinita o opzionalmente come profili: + +- `base.config`: Un file di configurazione 'da zero', appropriato per l'uso generale nella maggior parte degli ambienti di calcolo ad alte prestazioni. Questo definisce ampie categorie di utilizzo delle risorse, per esempio, che sono convenienti da applicare ai moduli. +- `modules.config`: Direttive e argomenti aggiuntivi del modulo. +- `test.config`: Un profilo per eseguire la pipeline con dati di test minimi, che abbiamo usato quando abbiamo eseguito la pipeline demo. +- `test_full.config`: Un profilo per eseguire la pipeline con un dataset di test completo. + +Toccheremo alcuni di questi file più avanti nel corso. + +### 3.3. Input e validazione + +Come abbiamo notato in precedenza, quando abbiamo esaminato il profilo di test della pipeline `nf-core/demo`, è progettata per prendere come input un samplesheet contenente percorsi di file e identificatori di campioni. +I percorsi di file collegati a dati reali situati nel repository `nf-core/test-datasets`. + +Un samplesheet di esempio è fornito anche sotto la directory `assets`, sebbene i percorsi in questo non siano reali. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Questo particolare samplesheet è abbastanza semplice, ma alcune pipeline vengono eseguite su samplesheet più complessi, con molti più metadati associati agli input primari. + +Sfortunatamente, poiché questi file possono essere difficili da verificare a occhio, la formattazione impropria dei dati di input è una fonte molto comune di fallimenti della pipeline. +Un problema correlato è quando i parametri sono forniti in modo errato. + +La soluzione a questi problemi è eseguire controlli di validazione automatizzati su tutti i file di input per garantire che contengano i tipi di informazioni previsti, formattati correttamente, e sui parametri per garantire che siano del tipo previsto. +Questo è chiamato validazione dell'input, e dovrebbe idealmente essere fatto _prima_ di provare a eseguire una pipeline, piuttosto che aspettare che la pipeline fallisca per scoprire che c'era un problema con gli input. + +Proprio come per la configurazione, il progetto nf-core ha opinioni molto forti sulla validazione dell'input, e raccomanda l'uso del [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/), un plugin Nextflow che fornisce capacità di validazione complete per le pipeline Nextflow. + +Copriremo questo argomento in maggior dettaglio nella Parte 5 di questo corso. +Per ora, sia consapevole che ci sono due file JSON forniti per quello scopo, `nextflow_schema.json` e `assets/schema_input.json`. + +Il `nextflow_schema.json` è un file utilizzato per memorizzare informazioni sui parametri della pipeline inclusi tipo, descrizione e testo di aiuto in un formato leggibile dalle macchine. +Questo è utilizzato per vari scopi, inclusa la validazione automatizzata dei parametri, la generazione di testo di aiuto e il rendering di form di parametri interattivi nelle interfacce UI. + +Il `schema_input.json` è un file utilizzato per definire la struttura del samplesheet di input. +Ogni colonna può avere un tipo, pattern, descrizione e testo di aiuto in un formato leggibile dalle macchine. + +### Takeaway + +Sapete quali sono i componenti principali di una pipeline nf-core e come il codice è organizzato; dove si trovano gli elementi principali di configurazione; e siete consapevoli di cosa serve la validazione dell'input. + +### Prossimi passi + +Si prenda una pausa! È stato molto. Quando si sente riposato e pronto, passi alla sezione successiva per applicare ciò che avete appreso per scrivere una pipeline compatibile con nf-core. + +!!! tip + + Se desiderate imparare come comporre workflow con subworkflow prima di passare alla parte successiva, consulti la [Side Quest Workflows of Workflows](../side_quests/workflows_of_workflows.md). diff --git a/docs/it/docs/hello_nf-core/02_rewrite_hello.md b/docs/it/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..071ea76b49 --- /dev/null +++ b/docs/it/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1434 @@ +# Parte 2: Riscrivere Hello per nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa seconda parte del corso di formazione Hello nf-core, Le mostriamo come creare una versione compatibile con nf-core della pipeline prodotta dal corso per principianti [Hello Nextflow](../hello_nextflow/index.md). + +Avrà notato nella prima sezione della formazione che le pipeline nf-core seguono una struttura abbastanza elaborata con molti file accessori. +Creare tutto ciò da zero sarebbe molto tedioso, quindi la comunità nf-core ha sviluppato strumenti per farlo invece da un template, per avviare il processo. + +Le mostreremo come utilizzare questi strumenti per creare uno scaffold della pipeline, quindi adattare il codice esistente della pipeline 'regolare' sullo scaffold nf-core. + +Se non ha familiarità con la pipeline Hello o potrebbe aver bisogno di un ripasso, consulti [questa pagina informativa](../info/hello_pipeline.md). + +--- + +## 1. Creare un nuovo progetto pipeline + +Prima di tutto, creiamo lo scaffold per la nuova pipeline. + +!!! note "Nota" + + Assicuratevi di trovarsi nella directory `hello-nf-core` nel suo terminale. + +### 1.1. Eseguire lo strumento di creazione pipeline basato su template + +Iniziamo creando una nuova pipeline con il comando `nf-core pipelines create`. +Questo creerà un nuovo scaffold di pipeline utilizzando il template base nf-core, personalizzato con un nome, una descrizione e un autore della pipeline. + +```bash +nf-core pipelines create +``` + +L'esecuzione di questo comando aprirà un'interfaccia utente testuale (TUI) per la creazione della pipeline: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Questa TUI Le chiederà di fornire informazioni di base sulla vostra pipeline e Le offrirà una scelta di funzionalità da includere o escludere nello scaffold della pipeline. + +- Nella schermata di benvenuto, cliccate su **Let's go!**. +- Nella schermata `Choose pipeline type`, cliccate su **Custom**. +- Inserite i dettagli della vostra pipeline come segue (sostituendo `< IL VOSTRO NOME >` con il vostro nome), quindi cliccate su **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < IL VOSTRO NOME > +``` + +- Nella schermata Template features, impostate `Toggle all features` su **off**, quindi **abilitate** selettivamente i seguenti. Controllate le vostre selezioni e cliccate su **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- Nella schermata `Final details`, cliccate su **Finish**. Attendete che la pipeline venga creata, quindi cliccate su **Continue**. +- Nella schermata Create GitHub repository, cliccate su **Finish without creating a repo**. Questo mostrerà le istruzioni per creare successivamente un repository GitHub. Ignoratele e cliccate su **Close**. + +Una volta chiusa la TUI, dovrebbe vedere il seguente output nella console. + +??? success "Output del comando" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +Non c'è una conferma esplicita nell'output della console che la creazione della pipeline abbia funzionato, ma dovrebbe vedere una nuova directory chiamata `core-hello`. + +Visualizzi i contenuti della nuova directory per vedere quanto lavoro si è risparmiato utilizzando il template. + +```bash +tree core-hello +``` + +??? abstract "Contenuti della directory" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +Sono molti file! + +Speriamo riconosca molti di essi come gli stessi che abbiamo incontrato quando abbiamo esplorato la struttura della pipeline `nf-core/demo`. +Ma non si preoccupi se si sente ancora un po' spaesato; percorreremo insieme le parti importanti nel corso di questa formazione. + +!!! note "Nota" + + Una differenza importante rispetto alla pipeline `nf-core/demo` che abbiamo esaminato nella prima parte di questa formazione è che non c'è una directory `modules`. + Questo perché non abbiamo scelto di includere nessuno dei moduli nf-core predefiniti. + +### 1.2. Testare che lo scaffold sia funzionale + +Che ci crediate o no, anche se non avete ancora aggiunto alcun modulo per farle svolgere un lavoro reale, lo scaffold della pipeline può effettivamente essere eseguito utilizzando il profilo test, nello stesso modo in cui abbiamo eseguito la pipeline `nf-core/demo`. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Questo Le mostra che tutto il cablaggio di base è a posto. +Quindi, dove sono gli output? Ce ne sono? + +In effetti, è stata creata una nuova directory di risultati chiamata `core-hello-results` contenente i report di esecuzione standard: + +```bash +tree core-hello-results +``` + +??? abstract "Contenuti della directory" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Può dare un'occhiata ai report per vedere cosa è stato eseguito, e la risposta è: niente del tutto! + +![report timeline di esecuzione vuoto](./img/execution_timeline_empty.png) + +Diamo un'occhiata a cosa c'è effettivamente nel codice. + +### 1.3. Esaminare il workflow placeholder + +Se guarda dentro il file `main.nf`, vedrà che importa un workflow chiamato `HELLO` da `workflows/hello`. + +Questo è equivalente al workflow `workflows/demo.nf` che abbiamo incontrato nella Parte 1, e serve come workflow placeholder per il nostro workflow di interesse, con alcune funzionalità nf-core già in atto. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Rispetto a un workflow Nextflow di base come quello sviluppato in [Hello Nextflow](../hello_nextflow/index.md), noterà alcune cose nuove qui (righe evidenziate sopra): + +- Il blocco workflow ha un nome +- Gli input del workflow sono dichiarati utilizzando la parola chiave `take:` e la costruzione del canale viene spostata al workflow genitore +- Il contenuto del workflow è posizionato all'interno di un blocco `main:` +- Gli output sono dichiarati utilizzando la parola chiave `emit:` + +Queste sono funzionalità opzionali di Nextflow che rendono il workflow **componibile**, il che significa che può essere richiamato dall'interno di un altro workflow. + +!!! note "Workflow componibili in profondità" + + La [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest esplora la composizione dei workflow in modo molto più approfondito, incluso come comporre più workflow insieme e gestire flussi di dati complessi tra di essi. Stiamo introducendo la componibilità qui perché è un requisito fondamentale dell'architettura del template nf-core, che utilizza workflow annidati per organizzare l'inizializzazione della pipeline, il workflow di analisi principale e le attività di completamento in componenti separati e riutilizzabili. + +Dovremo collegare la logica pertinente dal nostro workflow di interesse in quella struttura. +Il primo passo per questo è rendere il nostro workflow originale componibile. + +### Riepilogo + +Ora sa come creare uno scaffold di pipeline utilizzando gli strumenti nf-core. + +### Prossimi passi? + +Imparare come rendere un workflow semplice componibile come preludio a renderlo compatibile con nf-core. + +--- + +## 2. Rendere il workflow Hello Nextflow originale componibile + +Ora è il momento di mettersi al lavoro per integrare il nostro workflow nello scaffold nf-core. +Come promemoria, stiamo lavorando con il workflow presentato nel nostro corso di formazione [Hello Nextflow](../hello_nextflow/index.md). + +!!! tip "Suggerimento" + + Se non ha familiarità con quella pipeline o potrebbe aver bisogno di un ripasso, consulti [The Hello pipeline](../info/hello_pipeline.md). + +Le forniamo una copia pulita e completamente funzionale del workflow Hello Nextflow completato nella directory `original-hello` insieme ai suoi moduli e al file CSV predefinito che si aspetta di utilizzare come input. + +```bash +tree original-hello/ +``` + +??? abstract "Contenuti della directory" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Si senta libero di eseguirla per assicurarsi che funzioni: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Apriamo il file workflow `hello.nf` per ispezionare il codice, che è mostrato per intero di seguito (senza contare i processi, che sono nei moduli): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Include i moduli +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Come potete vedere, questo workflow è stato scritto come un semplice workflow senza nome che può essere eseguito autonomamente. +Per renderlo eseguibile dall'interno di un workflow genitore come richiede il template nf-core, dobbiamo renderlo **componibile**. + +Esaminiamo le modifiche necessarie una per una. + +### 2.1. Nominare il workflow + +Prima di tutto, diamo un nome al workflow così possiamo fare riferimento ad esso da un workflow genitore. + +=== "Dopo" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Prima" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Le stesse convenzioni si applicano ai nomi dei workflow come ai nomi dei moduli. + +### 2.2. Sostituire la costruzione del canale con `take` + +Ora, sostituisca la costruzione del canale con una semplice dichiarazione `take` che dichiara gli input attesi. + +=== "Dopo" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // channel of greetings + greeting_ch + ``` + +=== "Prima" + + ```groovy title="original-hello/hello.nf" linenums="18" + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Questo lascia i dettagli di come vengono forniti gli input al workflow genitore. + +Mentre ci siamo, possiamo anche commentare la riga `params.greeting = 'greetings.csv'` + +=== "Dopo" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Prima" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Nota" + + Se ha installato l'estensione del language server di Nextflow, il controllo della sintassi evidenzierà il suo codice con sottolineature rosse ondulate. + Questo perché se inserisce una dichiarazione `take:`, deve anche avere un `main:`. + + Lo aggiungeremo nel prossimo passaggio. + +### 2.3. Prefare le operazioni del workflow con la dichiarazione `main` + +Successivamente, aggiunga una dichiarazione `main` prima del resto delle operazioni chiamate nel corpo del workflow. + +=== "Dopo" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Prima" + + ```groovy title="original-hello/hello.nf" linenums="21" + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Questo sostanzialmente dice 'questo è ciò che questo workflow _fa_'. + +### 2.4. Aggiungere la dichiarazione `emit` + +Infine, aggiunga una dichiarazione `emit` che dichiara quali sono gli output finali del workflow. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Questa è un'aggiunta completamente nuova al codice rispetto al workflow originale. + +### 2.5. Riepilogo delle modifiche completate + +Se ha effettuato tutte le modifiche come descritto, il suo workflow dovrebbe ora apparire così: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Include i moduli +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // channel of greetings + greeting_ch + + main: + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Questo descrive tutto ciò di cui Nextflow ha bisogno TRANNE cosa alimentare nel canale di input. +Ciò sarà definito nel workflow genitore, chiamato anche workflow **entrypoint**. + +### 2.6. Creare un workflow entrypoint fittizio + +Prima di integrare il nostro workflow componibile nello scaffold complesso nf-core, verifichiamo che funzioni correttamente. +Possiamo creare un semplice workflow entrypoint fittizio per testare il workflow componibile in isolamento. + +Crei un file vuoto chiamato `main.nf` nella stessa directory `original-hello`. + +```bash +touch original-hello/main.nf +``` + +Copi il seguente codice nel file `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// import the workflow code from the hello.nf file +include { HELLO } from './hello.nf' + +// declare input parameter +params.greeting = 'greetings.csv' + +workflow { + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // call the imported workflow on the channel of greetings + HELLO(greeting_ch) + + // view the outputs emitted by the workflow + HELLO.out.view { output -> "Output: $output" } +} +``` + +Ci sono due osservazioni importanti da fare qui: + +- La sintassi per chiamare il workflow importato è essenzialmente la stessa della sintassi per chiamare i moduli. +- Tutto ciò che è correlato al trasferimento degli input nel workflow (parametro di input e costruzione del canale) è ora dichiarato in questo workflow genitore. + +!!! note "Nota" + + Nominare il file del workflow entrypoint `main.nf` è una convenzione, non un requisito. + + Se seguite questa convenzione, potete omettere di specificare il nome del file del workflow nel vostro comando `nextflow run`. + Nextflow cercherà automaticamente un file chiamato `main.nf` nella directory di esecuzione. + + Tuttavia, potete nominare il file del workflow entrypoint in altro modo se preferite. + In tal caso, assicuratevi di specificare il nome del file del workflow nel suo comando `nextflow run`. + +### 2.7. Testare che il workflow venga eseguito + +Abbiamo finalmente tutti i pezzi di cui abbiamo bisogno per verificare che il workflow componibile funzioni. +Eseguiamolo! + +```bash +nextflow run ./original-hello +``` + +Qui vede il vantaggio di utilizzare la convenzione di denominazione `main.nf`. +Se avessimo nominato il workflow entrypoint `something_else.nf`, avremmo dovuto fare `nextflow run original-hello/something_else.nf`. + +Se ha effettuato tutte le modifiche correttamente, questo dovrebbe essere eseguito fino al completamento. + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Questo significa che abbiamo aggiornato con successo il nostro workflow HELLO per essere componibile. + +### Riepilogo + +Sa come rendere un workflow componibile dandogli un nome e aggiungendo dichiarazioni `take`, `main` ed `emit`, e come chiamarlo da un workflow entrypoint. + +### Prossimi passi? + +Imparare come innestare un workflow componibile di base sullo scaffold nf-core. + +--- + +## 3. Adattare la logica del workflow aggiornato nel workflow placeholder + +Ora che abbiamo verificato che il nostro workflow componibile funziona correttamente, torniamo allo scaffold della pipeline nf-core che abbiamo creato nella sezione 1. +Vogliamo integrare il workflow componibile che abbiamo appena sviluppato nella struttura del template nf-core, quindi il risultato finale dovrebbe apparire così. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Quindi come facciamo a farlo accadere? Diamo un'occhiata al contenuto attuale del workflow `HELLO` in `core-hello/workflows/hello.nf` (lo scaffold nf-core). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Nel complesso, questo codice fa molto poco oltre a qualche housekeeping che ha a che fare con la cattura della versione di qualsiasi strumento software che viene eseguito nella pipeline. + +Dobbiamo aggiungere il codice pertinente dalla versione componibile del workflow originale che abbiamo sviluppato nella sezione 2. + +Affronteremo questo nelle seguenti fasi: + +1. Copiare i moduli e configurare le importazioni dei moduli +2. Lasciare la dichiarazione `take` così com'è +3. Aggiungere la logica del workflow al blocco `main` +4. Aggiornare il blocco `emit` + +!!! note "Nota" + + Ignoreremo la cattura della versione per questo primo passaggio e vedremo come collegarla in una parte successiva di questa formazione. + +### 3.1. Copiare i moduli e configurare le importazioni dei moduli + +I quattro processi del nostro workflow Hello Nextflow sono memorizzati come moduli in `original-hello/modules/`. +Dobbiamo copiare quei moduli nella struttura del progetto nf-core (sotto `core-hello/modules/local/`) e aggiungere dichiarazioni di importazione al file del workflow nf-core. + +Prima copiamo i file dei moduli da `original-hello/` a `core-hello/`: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Ora dovrebbe vedere la directory dei moduli elencata sotto `core-hello/`. + +```bash +tree core-hello/modules +``` + +??? abstract "Contenuti della directory" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Ora configuriamo le dichiarazioni di importazione dei moduli. + +Queste erano le dichiarazioni di importazione nel workflow `original-hello/hello.nf`: + +```groovy title="original-hello/hello.nf" linenums="9" +// Include i moduli +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Aprite il file `core-hello/workflows/hello.nf` e trasponga quelle dichiarazioni di importazione in esso come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Altre due osservazioni interessanti qui: + +- Abbiamo adattato la formattazione delle dichiarazioni di importazione per seguire la convenzione di stile nf-core. +- Abbiamo aggiornato i percorsi relativi ai moduli per riflettere che ora sono memorizzati a un livello diverso di annidamento. + +### 3.2. Lasciare la dichiarazione `take` così com'è + +Il progetto nf-core ha molte funzionalità pre-costruite intorno al concetto di samplesheet, che è tipicamente un file CSV contenente dati in colonne. +Poiché è essenzialmente ciò che è il nostro file `greetings.csv`, manterremo l'attuale dichiarazione `take` così com'è, e aggiorneremo semplicemente il nome del canale di input nel prossimo passaggio. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +La gestione dell'input sarà fatta a monte di questo workflow (non in questo file di codice). + +### 3.3. Aggiungere la logica del workflow al blocco `main` + +Ora che i nostri moduli sono disponibili per il workflow, possiamo collegare la logica del workflow nel blocco `main`. + +Come promemoria, questo è il codice pertinente nel workflow originale, che non è cambiato molto quando l'abbiamo reso componibile (abbiamo solo aggiunto la riga `main:`): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) +``` + +Dobbiamo copiare il codice che viene dopo `main:` nella nuova versione del workflow. + +C'è già del codice lì che ha a che fare con la cattura delle versioni degli strumenti che vengono eseguiti dal workflow. Lo lasceremo in pace per ora (ci occuperemo delle versioni degli strumenti più tardi). +Manterremo l'inizializzazione `ch_versions = channel.empty()` in alto, quindi inseriremo la nostra logica del workflow, mantenendo il codice di raccolta delle versioni alla fine. +Questo ordinamento ha senso perché in una pipeline reale, i processi emetterebbero informazioni sulla versione che verrebbero aggiunte al canale `ch_versions` mentre il workflow viene eseguito. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +Noterà che abbiamo anche aggiunto una riga vuota prima di `main:` per rendere il codice più leggibile. + +Sembra ottimo, ma dobbiamo ancora aggiornare il nome del canale che stiamo passando al processo `sayHello()` da `greeting_ch` a `ch_samplesheet` come mostrato di seguito, per corrispondere a ciò che è scritto sotto la parola chiave `take:`. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emette un saluto (updated to use the nf-core convention for samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emette un saluto + sayHello(greeting_ch) + ``` + +Ora la logica del workflow è correttamente collegata. + +### 3.4. Aggiornare il blocco `emit` + +Infine, dobbiamo aggiornare il blocco `emit` per includere la dichiarazione degli output finali del workflow. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +Questo conclude le modifiche che dobbiamo apportare al workflow HELLO stesso. +A questo punto, abbiamo raggiunto la struttura complessiva del codice che ci eravamo proposti di implementare. + +### Riepilogo + +Sa come adattare i pezzi principali di un workflow componibile in un workflow placeholder nf-core. + +### Prossimi passi? + +Imparare come adattare la gestione degli input nello scaffold della pipeline nf-core. + +--- + +## 4. Adattare la gestione degli input + +Ora che abbiamo integrato con successo la nostra logica del workflow nello scaffold nf-core, dobbiamo affrontare un altro pezzo critico: assicurarci che i nostri dati di input siano elaborati correttamente. +Il template nf-core viene fornito con una gestione degli input sofisticata progettata per dataset genomici complessi, quindi dobbiamo adattarla per funzionare con il nostro file `greetings.csv` più semplice. + +### 4.1. Identificare dove vengono gestiti gli input + +Il primo passo è capire dove viene eseguita la gestione degli input. + +Potrà ricordare che quando abbiamo riscritto il workflow Hello Nextflow per renderlo componibile, abbiamo spostato la dichiarazione del parametro di input di un livello verso l'alto, nel workflow entrypoint `main.nf`. +Quindi diamo un'occhiata al workflow entrypoint `main.nf` di livello superiore che è stato creato come parte dello scaffold della pipeline: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Run main analysis pipeline depending on type of input +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Run pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Run initialisation tasks + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Run main workflow + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Run completion tasks + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Il progetto nf-core fa un uso intensivo di subworkflow annidati, quindi questa parte può risultare un po' confusa al primo approccio. + +Ciò che conta qui è che ci sono due workflow definiti: + +- `CORE_HELLO` è un wrapper sottile per l'esecuzione del workflow HELLO che abbiamo appena finito di adattare in `core-hello/workflows/hello.nf`. +- Un workflow senza nome che chiama `CORE_HELLO` così come altri due subworkflow, `PIPELINE_INITIALISATION` e `PIPELINE_COMPLETION`. + +Ecco un diagramma di come si relazionano tra loro: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Importante, non possiamo trovare alcun codice che costruisce un canale di input a questo livello, solo riferimenti a un samplesheet fornito tramite il parametro `--input`. + +Un po' di ricerca rivela che la gestione degli input è eseguita dal subworkflow `PIPELINE_INITIALISATION`, appropriatamente, che è importato da `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`. + +Se apriamo quel file e scorriamo verso il basso, arriviamo a questo blocco di codice: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +Questa è la factory del canale che analizza il samplesheet e lo passa in una forma pronta per essere consumata dal workflow HELLO. + +!!! note "Nota" + + La sintassi sopra è un po' diversa da quella che abbiamo usato in precedenza, ma fondamentalmente questo: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + è equivalente a questo: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Questo codice coinvolge alcuni passaggi di analisi e validazione che sono altamente specifici per il samplesheet di esempio incluso con il template della pipeline nf-core, che al momento della scrittura è molto specifico del dominio e non adatto per il nostro progetto di pipeline semplice. + +### 4.2. Sostituire il codice del canale di input del template + +La buona notizia è che le esigenze della nostra pipeline sono molto più semplici, quindi possiamo sostituire tutto ciò con il codice di costruzione del canale che abbiamo sviluppato nel workflow Hello Nextflow originale. + +Come promemoria, ecco come appariva la costruzione del canale (come visto nella directory delle soluzioni): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Quindi dobbiamo solo collegarlo nel workflow di inizializzazione, con modifiche minori: aggiorniamo il nome del canale da `greeting_ch` a `ch_samplesheet`, e il nome del parametro da `params.greeting` a `params.input` (vedi riga evidenziata). + +=== "Dopo" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Create channel from input file provided through params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Prima" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Questo completa le modifiche di cui abbiamo bisogno per far funzionare l'elaborazione degli input. + +Nella sua forma attuale, questo non ci permetterà di sfruttare le capacità integrate di nf-core per la validazione dello schema, ma possiamo aggiungere ciò in seguito. +Per ora, ci stiamo concentrando nel mantenerlo il più semplice possibile per arrivare a qualcosa che possiamo eseguire con successo sui dati di test. + +### 4.3. Aggiornare il profilo test + +Parlando di dati e parametri di test, aggiorniamo il profilo test per questa pipeline per utilizzare il mini-samplesheet `greetings.csv` invece del samplesheet di esempio fornito nel template. + +Sotto `core-hello/conf`, troviamo due profili test del template: `test.config` e `test_full.config`, che sono pensati per testare un piccolo campione di dati e uno di dimensioni complete. +Dato lo scopo della nostra pipeline, non c'è davvero un punto nell'impostare un profilo test di dimensioni complete, quindi si senta libero di ignorare o eliminare `test_full.config`. +Ci concentreremo sulla configurazione di `test.config` per essere eseguito sul nostro file `greetings.csv` con alcuni parametri predefiniti. + +#### 4.3.1. Copiare il file `greetings.csv` + +Prima dobbiamo copiare il file `greetings.csv` in un posto appropriato nel nostro progetto pipeline. +Tipicamente i piccoli file di test sono memorizzati nella directory `assets`, quindi copiamo il file dalla nostra directory di lavoro. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Ora il file `greetings.csv` è pronto per essere utilizzato come input di test. + +#### 4.3.2. Aggiornare il file `test.config` + +Ora possiamo aggiornare il file `test.config` come segue: + +=== "Dopo" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dati di input + input = "${projectDir}/assets/greetings.csv" + + // Other parameters + batch = 'test' + character = 'tux' + } + ``` + +=== "Prima" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dati di input + // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets + // TODO nf-core: Give any required params for the test so that command line flags are not needed + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Punti chiave: + +- **Utilizzo di `${projectDir}`**: Questa è una variabile implicita di Nextflow che punta alla directory dove si trova lo script del workflow principale (la radice della pipeline). Utilizzarla garantisce che il percorso funzioni indipendentemente da dove viene eseguita la pipeline. +- **Percorsi assoluti**: Utilizzando `${projectDir}`, creiamo un percorso assoluto, che è importante per i dati di test che vengono forniti con la pipeline. +- **Posizione dei dati di test**: Le pipeline nf-core tipicamente memorizzano i dati di test nella directory `assets/` all'interno del repository della pipeline per i piccoli file di test, o fanno riferimento a dataset di test esterni per i file più grandi. + +E mentre ci siamo, stringiamo i limiti di risorse predefiniti per assicurarci che questo venga eseguito su macchine molto basilari (come le VM minimali in Github Codespaces): + +=== "Dopo" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Prima" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Questo completa le modifiche del codice che dobbiamo fare. + +### 4.4. Eseguire la pipeline con il profilo test + +È stato molto, ma possiamo finalmente provare a eseguire la pipeline! +Noti che dobbiamo aggiungere `--validate_params false` alla riga di comando perché non abbiamo ancora configurato la validazione (che arriverà più tardi). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Se ha effettuato tutte le modifiche correttamente, dovrebbe essere eseguita fino al completamento. + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Come potete vedere, questo ha prodotto il tipico riepilogo nf-core all'inizio grazie al subworkflow di inizializzazione, e le righe per ogni modulo ora mostrano i nomi completi PIPELINE:WORKFLOW:module. + +### 4.5. Trovare gli output della pipeline + +La domanda ora è: dove sono gli output della pipeline? +E la risposta è abbastanza interessante: ci sono ora due posti diversi dove cercare i risultati. + +Come potrà ricordare da prima, la nostra prima esecuzione del workflow appena creato ha prodotto una directory chiamata `core-hello-results/` che conteneva vari report di esecuzione e metadati. + +```bash +tree core-hello-results +``` + +??? abstract "Contenuti della directory" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_07-29-37.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── execution_trace_2025-11-21_07-29-37.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-13.json + ├── params_2025-11-21_07-29-41.json + └── pipeline_dag_2025-11-21_04-47-18.html + └── pipeline_dag_2025-11-21_07-29-37.html + + 1 directory, 12 files + ``` + +Vede che abbiamo ottenuto un altro set di report di esecuzione oltre a quelli che abbiamo ottenuto dalla prima esecuzione, quando il workflow era ancora solo un placeholder. +Questa volta vede tutte le attività che sono state eseguite come previsto. + +![report timeline di esecuzione per la pipeline Hello](./img/execution_timeline_hello.png) + +!!! note "Nota" + + Ancora una volta le attività non sono state eseguite in parallelo perché stiamo eseguendo su una macchina minimalista in Github Codespaces. + Per vederle eseguire in parallelo, provi ad aumentare l'allocazione della CPU del suo codespace e i limiti di risorse nella configurazione di test. + +È fantastico, ma i nostri risultati effettivi della pipeline non sono lì! + +Ecco cosa è successo: non abbiamo cambiato nulla ai moduli stessi, quindi gli output gestiti dalle direttive `publishDir` a livello di modulo vanno ancora in una directory `results` come specificato nella pipeline originale. + +```bash +tree results +``` + +??? abstract "Contenuti della directory" + + ```console + results + ├── Bonjour-output.txt + ├── COLLECTED-test-batch-output.txt + ├── COLLECTED-test-output.txt + ├── cowpy-COLLECTED-test-batch-output.txt + ├── cowpy-COLLECTED-test-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + 0 directories, 10 files + ``` + +Ah, eccoli, mescolati con gli output delle esecuzioni precedenti della pipeline Hello originale. + +Se vogliamo che siano organizzati ordinatamente come gli output della pipeline demo, dovremo cambiare il modo in cui impostiamo la pubblicazione degli output. +Le mostreremo come farlo più tardi in questo corso di formazione. + +<!-- TODO: Update this once we've updated Hello Nextflow to use workflow-level outputs --> + +Ed eccolo! Può sembrare molto lavoro per ottenere lo stesso risultato della pipeline originale, ma ottiene tutti quei bei report generati automaticamente, e ora ha una solida base per sfruttare le funzionalità aggiuntive di nf-core, inclusa la validazione degli input e alcune interessanti capacità di gestione dei metadati che tratteremo in una sezione successiva. + +--- + +### Riepilogo + +Sa come convertire una pipeline Nextflow normale in una pipeline in stile nf-core utilizzando il template nf-core. +Come parte di ciò, ha imparato come rendere un workflow componibile e come identificare gli elementi del template nf-core che più comunemente necessitano di essere adattati quando si sviluppa una pipeline personalizzata in stile nf-core. + +### Prossimi passi? + +Si prenda una pausa, è stato un lavoro duro! Quando sarà pronto, passi a [Part 3: Use an nf-core module](./03_use_module.md) per imparare come sfruttare i moduli mantenuti dalla comunità dal repository nf-core/modules. diff --git a/docs/it/docs/hello_nf-core/03_use_module.md b/docs/it/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..611074532b --- /dev/null +++ b/docs/it/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,812 @@ +# Parte 3: Usare un modulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa terza parte del corso di formazione Hello nf-core, mostreremo come trovare, installare e utilizzare un modulo nf-core esistente nella propria pipeline. + +Uno dei grandi vantaggi di lavorare con nf-core è la possibilità di sfruttare moduli pre-costruiti e testati dal repository [nf-core/modules](https://github.com/nf-core/modules). +Invece di scrivere ogni processo da zero, è possibile installare e utilizzare moduli mantenuti dalla comunità che seguono le best practice. + +Per dimostrare come funziona, sostituiremo il modulo personalizzato `collectGreetings` con il modulo `cat/cat` da nf-core/modules nella pipeline `core-hello`. + +??? info "Come iniziare da questa sezione" + + Questa sezione del corso presuppone che sia stata completata la [Parte 2: Riscrivere Hello per nf-core](./02_rewrite_hello.md) e si disponga di una pipeline `core-hello` funzionante. + + Se non è stata completata la Parte 2 o si desidera iniziare da zero per questa parte, è possibile utilizzare la soluzione `core-hello-part2` come punto di partenza. + Eseguire questo comando dalla directory `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Questo fornisce una pipeline nf-core completamente funzionale pronta per l'aggiunta di moduli. + È possibile verificare che funzioni correttamente eseguendo il seguente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Trovare e installare un modulo nf-core adatto + +Per prima cosa, impariamo come trovare un modulo nf-core esistente e installarlo nella nostra pipeline. + +L'obiettivo sarà sostituire il processo `collectGreetings`, che utilizza il comando Unix `cat` per concatenare più file di saluto in uno solo. +La concatenazione di file è un'operazione molto comune, quindi è ragionevole pensare che potrebbe già esistere un modulo in nf-core progettato per questo scopo. + +Iniziamo. + +### 1.1. Esplorare i moduli disponibili sul sito web nf-core + +Il progetto nf-core mantiene un catalogo centralizzato di moduli su [https://nf-co.re/modules](https://nf-co.re/modules). + +Navigare alla pagina dei moduli nel browser web e utilizzare la barra di ricerca per cercare 'concatenate'. + +![risultati ricerca moduli](./img/module-search-results.png) + +Come potete vedere, ci sono diversi risultati, molti dei quali moduli progettati per concatenare tipi di file molto specifici. +Tra questi, dovrebbe essercene uno chiamato `cat_cat` che è generico. + +!!! note "Convenzione di denominazione dei moduli" + + Il trattino basso (`_`) viene utilizzato come sostituto del carattere barra (`/`) nei nomi dei moduli. + + I moduli nf-core seguono la convenzione di denominazione `software/comando` quando uno strumento fornisce più comandi, come `samtools/view` (pacchetto samtools, comando view) o `gatk/haplotypecaller` (pacchetto GATK, comando HaplotypeCaller). + Per gli strumenti che forniscono solo un comando principale, i moduli utilizzano un singolo livello come `fastqc` o `multiqc`. + +Fare clic sulla casella del modulo `cat_cat` per visualizzare la documentazione del modulo. + +La pagina del modulo mostra: + +- Una breve descrizione: "Un modulo per la concatenazione di file compressi o non compressi con gzip" +- Comando di installazione: `nf-core modules install cat/cat` +- Struttura del canale di input e output +- Parametri disponibili + +### 1.2. Elencare i moduli disponibili dalla riga di comando + +In alternativa, è possibile cercare moduli direttamente dalla riga di comando utilizzando gli strumenti nf-core. + +```bash +nf-core modules list remote +``` + +Questo visualizzerà un elenco di tutti i moduli disponibili nel repository nf-core/modules, anche se è un po' meno conveniente se non si conosce già il nome del modulo che si sta cercando. +Tuttavia, se lo si conosce, è possibile inviare l'elenco a `grep` per trovare moduli specifici: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Output del comando" + + ```console + │ cat/cat + ``` + +Tenere presente che l'approccio con `grep` estrarrà solo risultati con il termine di ricerca nel loro nome, il che non funzionerebbe per `cat_cat`. + +### 1.3. Ottenere informazioni dettagliate sul modulo + +Per visualizzare informazioni dettagliate su un modulo specifico dalla riga di comando, utilizzare il comando `info`: + +```bash +nf-core modules info cat/cat +``` + +Questo visualizza la documentazione sul modulo, inclusi input, output e informazioni di base sull'utilizzo. + +??? success "Output del comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map contenente informazioni sul │ + │campione es. [ id:'test', single_end:false│ + │] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│Elenco di file compressi / non compressi │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map contenente │ + │informazioni sul campione │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │File concatenato. Sarà compresso │ ${file_out} + │con gzip se file_out termina con │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File contenente le versioni del │versions.yml + │software │ + ╵ ╵ + + 💻 Comando di installazione: nf-core modules install cat/cat + + ``` + +Queste sono esattamente le stesse informazioni che si possono trovare sul sito web. + +### 1.4. Installare il modulo cat/cat + +Ora che abbiamo trovato il modulo che vogliamo, dobbiamo aggiungerlo al codice sorgente della nostra pipeline. + +La buona notizia è che il progetto nf-core include degli strumenti per rendere questa parte facile. +Specificamente, il comando `nf-core modules install` permette di automatizzare il recupero del codice e renderlo disponibile al proprio progetto in un singolo passaggio. + +Navigare nella directory della pipeline ed eseguire il comando di installazione: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +Lo strumento potrebbe prima richiedere di specificare un tipo di repository. +(In caso contrario, saltare alla parte "Infine, lo strumento procederà con l'installazione del modulo.") + +??? success "Output del comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' non definito in .nf-core.yml + ? Questo repository è una pipeline o un repository di moduli? (Usa i tasti freccia) + » Pipeline + Repository di moduli + ``` + +Se appare, premere invio per accettare la risposta predefinita (`Pipeline`) e continuare. + +Lo strumento offrirà quindi di modificare la configurazione del progetto per evitare questo prompt in futuro. + +??? success "Output del comando" + + ```console + INFO Per evitare questo prompt in futuro, aggiungere la chiave 'repository_type' al file .nf-core.yml. + ? Desideri che aggiunga questa configurazione ora? [y/n] (y): + ``` + +Tanto vale approfittare di questo strumento conveniente! +Premere invio per accettare la risposta predefinita (sì). + +Infine, lo strumento procederà con l'installazione del modulo. + +??? success "Output del comando" + + ```console + INFO Configurazione aggiunta a '.nf-core.yml' + INFO Reinstallazione dei moduli trovati in 'modules.json' ma mancanti dalla directory: + INFO Installazione di 'cat/cat' + INFO Utilizzare la seguente istruzione per includere questo modulo: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Il comando automaticamente: + +- Scarica i file del modulo in `modules/nf-core/cat/cat/` +- Aggiorna `modules.json` per tracciare il modulo installato +- Fornisce l'istruzione `include` corretta da utilizzare nel workflow + +!!! tip + + Assicurarsi sempre che la directory di lavoro corrente sia la radice del progetto della pipeline prima di eseguire il comando di installazione del modulo. + +Verifichiamo che il modulo sia stato installato correttamente: + +```bash +tree -L 4 modules +``` + +??? abstract "Contenuto della directory" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +È anche possibile verificare l'installazione chiedendo all'utility nf-core di elencare i moduli installati localmente: + +```bash +nf-core modules list local +``` + +??? success "Output del comando" + + ```console + INFO Tipo di repository: pipeline + INFO Moduli installati in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Nome Modulo ┃ Repository ┃ Version SHA ┃ Messaggio ┃ Data ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Questo conferma che il modulo `cat/cat` fa ora parte del codice sorgente del progetto. + +Tuttavia, per utilizzare effettivamente il nuovo modulo, dobbiamo importarlo nella nostra pipeline. + +### 1.5. Aggiornare le importazioni dei moduli + +Sostituiamo l'istruzione `include` per il modulo `collectGreetings` con quella per `CAT_CAT` nella sezione delle importazioni del workflow `workflows/hello.nf`. + +Come promemoria, lo strumento di installazione del modulo ci ha fornito l'esatta istruzione da utilizzare: + +```groovy title="Istruzione di importazione prodotta dal comando di installazione" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Si noti che la convenzione nf-core prevede l'uso di maiuscole per i nomi dei moduli quando li si importa. + +Aprire [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) e apportare la seguente sostituzione: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Notare come il percorso per il modulo nf-core differisca dai moduli locali: + +- **modulo nf-core**: `'../modules/nf-core/cat/cat/main'` (riferimento a `main.nf`) +- **modulo locale**: `'../modules/local/collectGreetings.nf'` (riferimento a singolo file) + +Il modulo è ora disponibile per il workflow, quindi tutto ciò che dobbiamo fare è sostituire la chiamata a `collectGreetings` per usare `CAT_CAT`. Giusto? + +Non così in fretta. + +A questo punto, si potrebbe essere tentati di immergersi e iniziare a modificare il codice, ma vale la pena prendersi un momento per esaminare attentamente cosa si aspetta il nuovo modulo e cosa produce. + +Affronteremo questo aspetto come sezione separata perché coinvolge un nuovo meccanismo che non abbiamo ancora trattato: le mappe di metadati. + +!!! note + + È possibile eliminare facoltativamente il file `collectGreetings.nf`: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Tuttavia, potrebbe essere utile mantenerlo come riferimento per comprendere le differenze tra moduli locali e nf-core. + +### Riepilogo + +Ora si sa come trovare un modulo nf-core e renderlo disponibile al proprio progetto. + +### Prossimi passi + +Valutare cosa richiede un nuovo modulo e identificare eventuali modifiche importanti necessarie per integrarlo in una pipeline. + +--- + +## 2. Valutare i requisiti del nuovo modulo + +Nello specifico, dobbiamo esaminare l'**interfaccia** del modulo, cioè le sue definizioni di input e output, e confrontarla con l'interfaccia del modulo che stiamo cercando di sostituire. +Questo ci permetterà di determinare se possiamo semplicemente trattare il nuovo modulo come una sostituzione diretta o se dovremo adattare parte del collegamento. + +Idealmente questo è qualcosa che si dovrebbe fare _prima_ di installare il modulo, ma meglio tardi che mai. +(Tanto per la cronaca, esiste un comando `uninstall` per eliminare i moduli che si decide di non volere più.) + +!!! note + + Il processo CAT_CAT include una gestione piuttosto intelligente di diversi tipi di compressione, estensioni di file e così via che non sono strettamente rilevanti per ciò che stiamo cercando di mostrarvi qui, quindi ignoreremo la maggior parte di essi e ci concentreremo solo sulle parti che sono importanti. + +### 2.1. Confrontare le interfacce dei due moduli + +Come promemoria, questa è l'interfaccia del nostro modulo `collectGreetings`: + +```groovy title="modules/local/collectGreetings.nf (estratto)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +Il modulo `collectGreetings` accetta due input: + +- `input_files` contiene uno o più file di input da elaborare; +- `batch_name` è un valore che utilizziamo per assegnare un nome specifico all'esecuzione al file di output, che è una forma di metadati. + +Al completamento, `collectGreetings` produce un singolo percorso di file, emesso con il tag `outfile`. + +In confronto, l'interfaccia del modulo `cat/cat` è più complessa: + +```groovy title="modules/nf-core/cat/cat/main.nf (estratto)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +Il modulo CAT_CAT accetta un singolo input, ma quell'input è una tupla contenente due cose: + +- `meta` è una struttura contenente metadati, chiamata metamap; +- `files_in` contiene uno o più file di input da elaborare, equivalente a `input_files` di `collectGreetings`. + +Al completamento, CAT_CAT fornisce i suoi output in due parti: + +- Un'altra tupla contenente la metamap e il file di output concatenato, emessa con il tag `file_out`; +- Un file `versions.yml` che cattura informazioni sulla versione del software utilizzata, emesso con il tag `versions`. + +Si noti anche che per impostazione predefinita, il file di output sarà denominato in base a un identificatore che fa parte dei metadati (codice non mostrato qui). + +Questo potrebbe sembrare molto da tenere a mente guardando solo il codice, quindi ecco un diagramma per aiutare a visualizzare come tutto si integra. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Potete vedere che i due moduli hanno requisiti di input simili in termini di contenuto (un insieme di file di input più alcuni metadati) ma aspettative molto diverse per come quel contenuto è confezionato. +Ignorando per ora il file delle versioni, anche il loro output principale è equivalente (un file concatenato), tranne che CAT_CAT emette anche la metamap insieme al file di output. + +Le differenze di confezionamento saranno abbastanza facili da gestire, come vedrete tra poco. +Tuttavia, per comprendere la parte della metamap, dobbiamo introdurre qualche contesto aggiuntivo. + +### 2.2. Comprendere le metamap + +Abbiamo appena detto che il modulo CAT_CAT si aspetta una mappa di metadati come parte della sua tupla di input. +Prendiamoci qualche minuto per dare un'occhiata più da vicino a cosa sia. + +La **mappa di metadati**, spesso chiamata **metamap** in breve, è una mappa in stile Groovy contenente informazioni sulle unità di dati. +Nel contesto delle pipeline Nextflow, le unità di dati possono essere qualsiasi cosa si desideri: campioni individuali, batch di campioni o interi dataset. + +Per convenzione, una metamap nf-core è denominata `meta` e contiene il campo obbligatorio `id`, che viene utilizzato per denominare gli output e tracciare le unità di dati. + +Ad esempio, una tipica mappa di metadati potrebbe apparire così: + +```groovy title="Esempio di metamap a livello di campione" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +O nel caso in cui i metadati siano associati a livello di batch: + +```groovy title="Esempio di metamap a livello di batch" +[id: 'batch1', date: '25.10.01'] +``` + +Ora mettiamo questo nel contesto del processo `CAT_CAT`, che si aspetta che i file di input siano confezionati in una tupla con una metamap, ed emette anche la metamap come parte della tupla di output. + +```groovy title="modules/nf-core/cat/cat/main.nf (estratto)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +Di conseguenza, ogni unità di dati viaggia attraverso la pipeline con i metadati rilevanti allegati. +I processi successivi possono quindi accedere facilmente anche a quei metadati. + +Ricordate quando vi abbiamo detto che il file prodotto da `CAT_CAT` sarà denominato in base a un identificatore che fa parte dei metadati? +Questo è il codice rilevante: + +```groovy title="modules/nf-core/cat/cat/main.nf (estratto)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Questo si traduce approssimativamente come segue: se un `prefix` viene fornito tramite il sistema di parametri esterni delle attività (`task.ext`), usarlo per denominare il file di output; altrimenti crearne uno usando `${meta.id}`, che corrisponde al campo `id` nella metamap. + +Potete immaginare il canale di input che arriva a questo modulo con contenuti come questo: + +```groovy title="Esempio di contenuto del canale di input" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Quindi il contenuto del canale di output che esce così: + +```groovy title="Esempio di contenuto del canale di output" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Come accennato in precedenza, la configurazione di input `tuple val(meta), path(files_in)` è un pattern standard utilizzato in tutti i moduli nf-core. + +Speriamo che possiate iniziare a vedere quanto questo possa essere utile. +Non solo permette di denominare gli output in base ai metadati, ma è possibile anche fare cose come usarli per applicare valori di parametri diversi, e in combinazione con operatori specifici, è possibile persino raggruppare, ordinare o filtrare i dati mentre fluiscono attraverso la pipeline. + +!!! note "Ulteriori informazioni sui metadati" + + Per un'introduzione completa al lavoro con i metadati nei workflow Nextflow, incluso come leggere i metadati dai samplesheet e utilizzarli per personalizzare l'elaborazione, consultare la missione secondaria [Metadati nei workflow](../side_quests/metadata). + +### 2.3. Riepilogare le modifiche da apportare + +In base a quanto abbiamo esaminato, queste sono le modifiche principali che dobbiamo apportare alla nostra pipeline per utilizzare il modulo `cat/cat`: + +- Creare una metamap contenente il nome del batch; +- Confezionare la metamap in una tupla con l'insieme di file di input da concatenare (provenienti da `convertToUpper`); +- Cambiare la chiamata da `collectGreetings()` a `CAT_CAT`; +- Estrarre il file di output dalla tupla prodotta dal processo `CAT_CAT` prima di passarlo a `cowpy`. + +Questo dovrebbe essere sufficiente! Ora che abbiamo un piano, siamo pronti ad immergerci. + +### Riepilogo + +Si sa come valutare l'interfaccia di input e output di un nuovo modulo per identificare i suoi requisiti, e si è appreso come le metamap vengono utilizzate dalle pipeline nf-core per mantenere i metadati strettamente associati ai dati mentre fluiscono attraverso una pipeline. + +### Prossimi passi + +Integrare il nuovo modulo in un workflow. + +--- + +## 3. Integrare CAT_CAT nel workflow `hello.nf` + +Ora che sapete tutto sulle metamap (o abbastanza per gli scopi di questo corso, comunque), è tempo di implementare effettivamente le modifiche che abbiamo delineato sopra. + +Per chiarezza, suddivideremo questo processo e tratteremo ogni passaggio separatamente. + +!!! note + + Tutte le modifiche mostrate di seguito sono apportate alla logica del workflow nel blocco `main` nel file del workflow `core-hello/workflows/hello.nf`. + +### 3.1. Creare una mappa di metadati + +Per prima cosa, dobbiamo creare una mappa di metadati per `CAT_CAT`, tenendo presente che i moduli nf-core richiedono che la metamap abbia almeno un campo `id`. + +Poiché non abbiamo bisogno di altri metadati, possiamo mantenerla semplice e usare qualcosa come questo: + +```groovy title="Esempio di sintassi" +def cat_meta = [id: 'test'] +``` + +Tranne che non vogliamo codificare il valore di `id`; vogliamo usare il valore del parametro `params.batch`. +Quindi il codice diventa: + +```groovy title="Esempio di sintassi" +def cat_meta = [id: params.batch] +``` + +Sì, è letteralmente così semplice creare una metamap di base. + +Aggiungiamo queste righe dopo la chiamata a `convertToUpper`, rimuovendo la chiamata a `collectGreetings`: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // raccogliere tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Questo crea una semplice mappa di metadati dove l'`id` è impostato sul nome del nostro batch (che sarà `test` quando si usa il profilo test). + +### 3.2. Creare un canale con tuple di metadati + +Successivamente, trasformare il canale di file in un canale di tuple contenenti metadati e file: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // creare un canale con metadati e file in formato tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +La riga che abbiamo aggiunto realizza due cose: + +- `.collect()` raccoglie tutti i file dall'output di `convertToUpper` in un singolo elenco +- `.map { files -> tuple(cat_meta, files) }` crea una tupla di `[metadati, file]` nel formato che `CAT_CAT` si aspetta + +Questo è tutto ciò che dobbiamo fare per configurare la tupla di input per `CAT_CAT`. + +### 3.3. Chiamare il modulo CAT_CAT + +Ora chiamare `CAT_CAT` sul canale appena creato: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // creare un canale con metadati e file in formato tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenare i file utilizzando il modulo nf-core cat/cat + CAT_CAT(ch_for_cat) + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // creare un canale con metadati e file in formato tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Questo completa la parte più complessa di questa sostituzione, ma non abbiamo ancora finito: dobbiamo ancora aggiornare il modo in cui passiamo l'output concatenato al processo `cowpy`. + +### 3.4. Estrarre il file di output dalla tupla per `cowpy` + +In precedenza, il processo `collectGreetings` produceva solo un file che potevamo passare a `cowpy` direttamente. +Tuttavia, il processo `CAT_CAT` produce una tupla che include la metamap oltre al file di output. + +Poiché `cowpy` non accetta ancora tuple di metadati (risolveremo questo problema nella prossima parte del corso), dobbiamo estrarre il file di output dalla tupla prodotta da `CAT_CAT` prima di passarlo a `cowpy`: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // creare un canale con metadati e file in formato tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenare i saluti + CAT_CAT(ch_for_cat) + + // estrarre il file dalla tupla poiché cowpy non usa ancora metadati + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // generare arte ASCII dei saluti con cowpy + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // emettere un saluto + sayHello(ch_samplesheet) + + // convertire il saluto in maiuscolo + convertToUpper(sayHello.out) + + // creare mappa di metadati con il nome del batch come ID + def cat_meta = [ id: params.batch ] + + // creare un canale con metadati e file in formato tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenare i saluti + CAT_CAT(ch_for_cat) + + // generare arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +L'operazione `.map{ meta, file -> file }` estrae il file dalla tupla `[metadati, file]` prodotta da `CAT_CAT` in un nuovo canale, `ch_for_cowpy`. + +Quindi è solo questione di passare `ch_for_cowpy` a `cowpy` invece di `collectGreetings.out.outfile` in quest'ultima riga. + +!!! note + + Nella prossima parte del corso, aggiorneremo `cowpy` per lavorare direttamente con tuple di metadati, quindi questo passaggio di estrazione non sarà più necessario. + +### 3.5. Testare il workflow + +Testiamo che il workflow funzioni con il modulo `cat/cat` appena integrato: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Questo dovrebbe eseguirsi ragionevolmente rapidamente. + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Si noti che `CAT_CAT` appare ora nell'elenco di esecuzione dei processi invece di `collectGreetings`. + +E questo è tutto! Stiamo ora utilizzando un modulo robusto curato dalla comunità invece di codice personalizzato di livello prototipale per quel passaggio nella pipeline. + +### Riepilogo + +Ora si sa come: + +- Trovare e installare moduli nf-core +- Valutare i requisiti di un modulo nf-core +- Creare una semplice mappa di metadati da utilizzare con un modulo nf-core +- Integrare un modulo nf-core nel proprio workflow + +### Prossimi passi + +Imparare ad adattare i propri moduli locali per seguire le convenzioni nf-core. +Mostreremo anche come creare nuovi moduli nf-core da un template utilizzando gli strumenti nf-core. diff --git a/docs/it/docs/hello_nf-core/04_make_module.md b/docs/it/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..05307c14e6 --- /dev/null +++ b/docs/it/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1179 @@ +# Parte 4: Creare un modulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa quarta parte del corso di formazione Hello nf-core, vi mostreremo come creare un modulo nf-core applicando le convenzioni chiave che rendono i moduli portabili e manutenibili. + +Il progetto nf-core fornisce un comando (`nf-core modules create`) che genera automaticamente template di moduli correttamente strutturati, simile a quello che abbiamo utilizzato per il workflow nella Parte 2. +Tuttavia, per scopi didattici, inizieremo facendolo manualmente: trasformando il modulo locale `cowpy` nel vostro pipeline `core-hello` in un modulo in stile nf-core passo dopo passo. +Successivamente, vi mostreremo come utilizzare la creazione di moduli basata su template per lavorare in modo più efficiente in futuro. + +??? info "Come iniziare da questa sezione" + + Questa sezione presuppone che abbiate completato la [Parte 3: Utilizzare un modulo nf-core](./03_use_module.md) e abbiate integrato il modulo `CAT_CAT` nel vostro pipeline. + + Se non avete completato la Parte 3 o desiderate iniziare da zero per questa parte, potete utilizzare la soluzione `core-hello-part3` come punto di partenza. + Eseguite questi comandi dall'interno della directory `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Questo vi fornisce un pipeline con il modulo `CAT_CAT` già integrato. + Potete verificare che funzioni correttamente eseguendo il seguente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Trasformare `cowpy` in un modulo nf-core + +In questa sezione, applicheremo le convenzioni nf-core al modulo locale `cowpy` nel vostro pipeline `core-hello`, trasformandolo in un modulo che segue gli standard della community nf-core. + +Questo è il codice attuale per il modulo di processo `cowpy`: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Applicheremo le seguenti convenzioni nf-core in modo incrementale: + +1. **Mettere in maiuscolo il nome del processo in `COWPY`** per seguire la convenzione. +2. **Aggiornare `COWPY` per utilizzare tuple di metadati** per propagare i metadati dei campioni attraverso il workflow. +3. **Centralizzare la configurazione degli argomenti dello strumento con `ext.args`** per aumentare la versatilità del modulo mantenendo l'interfaccia minimale. +4. **Standardizzare la denominazione dell'output con `ext.prefix`** per promuovere la coerenza. +5. **Centralizzare la configurazione di pubblicazione** per promuovere la coerenza. + +Dopo ogni passaggio, eseguiremo il pipeline per verificare che tutto funzioni come previsto. + +!!! warning "Directory di lavoro" + + Assicuratevi di trovarvi nella directory `core-hello` (la radice del vostro pipeline) per tutte le modifiche ai file e le esecuzioni di comandi in questa sezione. + + ```bash + cd core-hello + ``` + +### 1.1. Mettere in maiuscolo il nome del processo + +Questa è puramente una convenzione stilistica (non c'è alcuna giustificazione tecnica) ma poiché è la norma per i moduli nf-core, conformiamoci. + +Dobbiamo effettuare tre serie di modifiche: + +1. Aggiornare il nome del processo nel modulo +2. Aggiornare l'istruzione di import del modulo nell'intestazione del workflow +3. Aggiornare la chiamata del processo e la dichiarazione emit nel corpo del workflow + +Iniziamo! + +#### 1.1.1. Aggiornare il nome del processo nel modulo + +Aprite il file del modulo `cowpy.nf` (sotto `core-hello/modules/local/`) e modificate il nome del processo in maiuscolo: + +=== "Dopo" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Prima" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +In questo caso la conversione in maiuscolo è completamente diretta. + +Se il nome del processo fosse composto da più parole, ad esempio se avessimo un processo chiamato MyCowpyTool originariamente in camel case, la convenzione nf-core sarebbe utilizzare underscore per separarle, ottenendo MY_COWPY_TOOL. + +#### 1.1.2. Aggiornare l'istruzione di import del modulo + +I nomi dei processi sono case-sensitive, quindi ora che abbiamo cambiato il nome del processo, dobbiamo aggiornare di conseguenza l'istruzione di import del modulo nell'intestazione del workflow di `hello.nf`: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Potremmo utilizzare un alias nell'istruzione di import per evitare di dover aggiornare le chiamate al processo, ma ciò vanificherebbe in qualche modo lo scopo di adottare la convenzione delle maiuscole. + +#### 1.1.3. Aggiornare la chiamata del processo e la dichiarazione emit + +Quindi ora aggiorniamo i due riferimenti al processo nel blocco workflow di `hello.nf`: + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // genera arte ASCII dei saluti con cowpy + COWPY(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // genera arte ASCII dei saluti con cowpy + cowpy(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Assicuratevi di effettuare **entrambe** le modifiche, altrimenti riceverà un errore quando eseguirà questo. + +#### 1.1.4. Eseguire il pipeline per testarlo + +Eseguiamo il workflow per verificare che tutto funzioni correttamente dopo queste modifiche. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Bene, funziona! Ora passiamo a effettuare modifiche più sostanziali. + +### 1.2. Aggiornare `COWPY` per utilizzare tuple di metadati + +Nella versione attuale del pipeline `core-hello`, stiamo estraendo il file dalla tupla di output di `CAT_CAT` per passarlo a `COWPY`, come mostrato nella metà superiore del diagramma sottostante. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Sarebbe meglio avere `COWPY` che accetta direttamente tuple di metadati, permettendo ai metadati di fluire attraverso il workflow, come mostrato nella metà inferiore del diagramma. + +A tal fine, dovremo effettuare le seguenti modifiche: + +1. Aggiornare le definizioni di input e output +2. Aggiornare la chiamata del processo nel workflow +3. Aggiornare il blocco emit nel workflow + +Una volta fatto tutto ciò, eseguiremo il pipeline per verificare che tutto funzioni ancora come prima. + +#### 1.2.1. Aggiornare le definizioni di input e output + +Torni al file del modulo `cowpy.nf` e lo modifichi per accettare tuple di metadati come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Prima" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Come potete vedere, abbiamo modificato sia l'**input principale** che l'**output** in una tupla che segue il pattern `tuple val(meta), path(input_file)` introdotto nella Parte 3 di questa formazione. +Per l'output, abbiamo anche colto questa opportunità per aggiungere `emit: cowpy_output` al fine di dare al canale di output un nome descrittivo. + +Ora che abbiamo cambiato ciò che il processo si aspetta, dobbiamo aggiornare ciò che gli forniamo nella chiamata del processo. + +#### 1.2.2. Aggiornare la chiamata del processo nel workflow + +La buona notizia è che questa modifica semplificherà la chiamata del processo. +Ora che l'output di `CAT_CAT` e l'input di `COWPY` hanno la stessa 'forma', cioè entrambi consistono in una struttura `tuple val(meta), path(input_file)`, possiamo semplicemente connetterli direttamente invece di dover estrarre esplicitamente il file dall'output del processo `CAT_CAT`. + +Aprite il file del workflow `hello.nf` (sotto `core-hello/workflows/`) e aggiorni la chiamata a `COWPY` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // genera arte ASCII dei saluti con cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extract the file from the tuple since cowpy doesn't use metadata yet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // genera arte ASCII dei saluti con cowpy + COWPY(ch_for_cowpy, params.character) + ``` + +Ora chiamiamo `COWPY` su `CAT_CAT.out.file_out` direttamente. + +Di conseguenza, non abbiamo più bisogno di costruire il canale `ch_for_cowpy`, quindi quella riga (e la sua riga di commento) può essere rimossa completamente. + +#### 1.2.3. Aggiornare il blocco emit nel workflow + +Poiché `COWPY` ora emette un output nominato, `cowpy_output`, possiamo aggiornare il blocco `emit:` del workflow `hello.nf` per utilizzarlo. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Questo tecnicamente non è richiesto, ma è buona pratica fare riferimento a output nominati quando possibile. + +#### 1.2.4. Eseguire il pipeline per testarlo + +Eseguiamo il workflow per verificare che tutto funzioni correttamente dopo queste modifiche. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Il pipeline dovrebbe essere eseguito con successo, con i metadati che ora fluiscono da `CAT_CAT` attraverso `COWPY`. + +Questo completa ciò che dovevamo fare per far gestire a `COWPY` le tuple di metadati. +Ora, vediamo cos'altro possiamo fare per sfruttare i pattern dei moduli nf-core. + +### 1.3. Centralizzare la configurazione degli argomenti dello strumento con `ext.args` + +Nel suo stato attuale, il processo `COWPY` si aspetta di ricevere un valore per il parametro `character`. +Di conseguenza, dobbiamo fornire un valore ogni volta che chiamiamo il processo, anche se saremmo contenti con i valori predefiniti impostati dallo strumento. +Per `COWPY` questo non è certamente un grande problema, ma per strumenti con molti parametri opzionali, può diventare piuttosto oneroso. + +Il progetto nf-core raccomanda di utilizzare una funzionalità Nextflow chiamata [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) per gestire gli argomenti degli strumenti in modo più conveniente tramite file di configurazione. + +Invece di dichiarare input di processo per ogni opzione dello strumento, si scrive il modulo per riferirsi a `ext.args` nella costruzione della sua riga di comando. +Quindi è solo questione di configurare la variabile `ext.args` per contenere gli argomenti e i valori che si desidera utilizzare nel file `modules.config`, che consolida i dettagli di configurazione per tutti i moduli. +Nextflow aggiungerà quegli argomenti con i loro valori nella riga di comando dello strumento a runtime. + +Applichiamo questo approccio al modulo `COWPY`. +Dovremo effettuare le seguenti modifiche: + +1. Aggiornare il modulo `COWPY` +2. Configurare `ext.args` nel file `modules.config` +3. Aggiornare il workflow `hello.nf` + +Una volta fatto tutto ciò, eseguiremo il pipeline per verificare che tutto funzioni ancora come prima. + +#### 1.3.1. Aggiornare il modulo `COWPY` + +Facciamolo. +Aprite il file del modulo `cowpy.nf` (sotto `core-hello/modules/local/`) e lo modifichi per riferirsi a `ext.args` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Prima" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Può vedere che abbiamo effettuato tre modifiche. + +1. **Nel blocco `input:`, abbiamo rimosso l'input `val character`.** + D'ora in poi, forniremo quell'argomento tramite la configurazione `ext.args` come descritto più avanti. + +2. **Nel blocco `script:`, abbiamo aggiunto la riga `def args = task.ext.args ?: ''`.** + Quella riga utilizza l'operatore `?:` per determinare il valore della variabile `args`: il contenuto di `task.ext.args` se non è vuoto, o una stringa vuota se lo è. + Notate che mentre generalmente ci riferiamo a `ext.args`, questo codice deve riferirsi a `task.ext.args` per estrarre la configurazione `ext.args` a livello di modulo. + +3. **Nella riga di comando, abbiamo sostituito `-c "$character"` con `$args`.** + Qui è dove Nextflow inietterà eventuali argomenti dello strumento impostati in `ext.args` nel file `modules.config`. + +Di conseguenza, l'interfaccia del modulo è ora più semplice: si aspetta solo gli input essenziali di metadati e file. + +!!! note + + L'operatore `?:` è spesso chiamato 'operatore Elvis' perché assomiglia a un viso di Elvis Presley laterale, con il carattere `?` che simboleggia l'onda nei suoi capelli. + +#### 1.3.2. Configurare `ext.args` nel file `modules.config` + +Ora che abbiamo tolto la dichiarazione `character` dal modulo, dobbiamo aggiungerla a `ext.args` nel file di configurazione `modules.config`. + +Nello specifico, aggiungeremo questo piccolo pezzo di codice al blocco `process {}`: + +```groovy title="Codice da aggiungere" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +La sintassi `withName:` assegna questa configurazione solo al processo `COWPY`, e `ext.args = { "-c ${params.character}" }` semplicemente compone una stringa che includerà il valore del parametro `character`. +Notate l'uso delle parentesi graffe, che dicono a Nextflow di valutare il valore del parametro a runtime. + +Ha senso? Aggiungiamolo. + +Aprite `conf/modules.config` e aggiungete il codice di configurazione all'interno del blocco `process {}` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Prima" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Speriamo possiate immaginare di avere tutti i moduli in un pipeline con i loro `ext.args` specificati in questo file, con i seguenti vantaggi: + +- L'**interfaccia del modulo rimane semplice** - Accetta solo gli input essenziali di metadati e file +- Il **pipeline espone ancora `params.character`** - Gli utenti finali possono ancora configurarlo come prima +- Il **modulo è ora portabile** - Può essere riutilizzato in altri pipeline senza dover aspettarsi un nome di parametro specifico +- La configurazione è **centralizzata** in `modules.config`, mantenendo pulita la logica del workflow + +Utilizzando il file `modules.config` come luogo dove tutti i pipeline centralizzano la configurazione per-modulo, rendiamo i nostri moduli più riutilizzabili attraverso diversi pipeline. + +#### 1.3.3. Aggiornare il workflow `hello.nf` + +Poiché il modulo `COWPY` non richiede più il parametro `character` come input, dobbiamo aggiornare di conseguenza la chiamata del workflow. + +Aprite il file del workflow `hello.nf` (sotto `core-hello/workflows/`) e aggiorni la chiamata a `COWPY` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // genera arte ASCII dei saluti con cowpy + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Prima" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // genera arte ASCII dei saluti con cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +Il codice del workflow è ora più pulito: non abbiamo bisogno di passare `params.character` direttamente al processo. +L'interfaccia del modulo è mantenuta minimale, rendendola più portabile, mentre il pipeline fornisce ancora l'opzione esplicita tramite configurazione. + +#### 1.3.4. Eseguire il pipeline per testarlo + +Verifichiamo che il workflow funzioni ancora come previsto, specificando un personaggio diverso per verificare che la configurazione `ext.args` funzioni. + +Eseguite questo comando usando `kosh`, una delle opzioni più... enigmatiche: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Questo dovrebbe essere eseguito con successo come in precedenza. + +Verifichiamo che la configurazione `ext.args` abbia funzionato controllando l'output. +Trovi l'output nel file browser o utilizzi l'hash dell'attività (la parte `38/eb29ea` nell'esempio sopra) per guardare il file di output: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Output del comando" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +Dovrebbe vedere l'arte ASCII visualizzata con il personaggio `kosh`, confermando che la configurazione `ext.args` ha funzionato! + +??? info "(Opzionale) Ispezionare il file di comando" + + Se desideratete vedere esattamente come è stata applicata la configurazione, potete ispezionare il file `.command.sh`: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Vedrà il comando `cowpy` con l'argomento `-c kosh`: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Questo mostra che il file `.command.sh` è stato generato correttamente in base alla configurazione `ext.args`. + +Si prenda un momento per riflettere su ciò che abbiamo ottenuto qui. +Questo approccio mantiene l'interfaccia del modulo focalizzata sui dati essenziali (file, metadati e eventuali parametri obbligatori per campione), mentre le opzioni che controllano il comportamento dello strumento sono gestite separatamente tramite configurazione. + +Questo può sembrare superfluo per uno strumento semplice come `cowpy`, ma potete fare una grande differenza per gli strumenti di analisi dati che hanno molti argomenti opzionali. + +Per riassumere i vantaggi di questo approccio: + +- **Interfaccia pulita**: Il modulo si concentra sugli input di dati essenziali (metadati e file) +- **Flessibilità**: Gli utenti possono specificare argomenti dello strumento tramite configurazione, inclusi valori specifici per campione +- **Coerenza**: Tutti i moduli nf-core seguono questo pattern +- **Portabilità**: I moduli possono essere riutilizzati senza opzioni dello strumento hardcoded +- **Nessuna modifica al workflow**: Aggiungere o modificare opzioni dello strumento non richiede l'aggiornamento del codice del workflow + +!!! note + + Il sistema `ext.args` ha potenti capacità aggiuntive non trattate qui, inclusa la commutazione dinamica dei valori degli argomenti in base ai metadati. Veda le [specifiche dei moduli nf-core](https://nf-co.re/docs/guidelines/components/modules) per maggiori dettagli. + +### 1.4. Standardizzare la denominazione dell'output con `ext.prefix` + +Ora che abbiamo dato al processo `COWPY` accesso alla metamap, possiamo iniziare a sfruttare un altro utile pattern nf-core: denominare i file di output in base ai metadati. + +Qui utilizzeremo una funzionalità Nextflow chiamata `ext.prefix` che ci permetterà di standardizzare la denominazione dei file di output attraverso i moduli usando `meta.id` (l'identificatore incluso nella metamap), pur essendo ancora in grado di configurare i moduli individualmente se desiderateto. + +Questo sarà simile a ciò che abbiamo fatto con `ext.args`, con alcune differenze che dettaglieremo man mano che procediamo. + +Applichiamo questo approccio al modulo `COWPY`. +Dovremo effettuare le seguenti modifiche: + +1. Aggiornare il modulo `COWPY` +2. Configurare `ext.prefix` nel file `modules.config` + +(Nessuna modifica necessaria al workflow.) + +Una volta fatto ciò, eseguiremo il pipeline per verificare che tutto funzioni ancora come prima. + +#### 1.4.1. Aggiornare il modulo `COWPY` + +Aprite il file del modulo `cowpy.nf` (sotto `core-hello/modules/local/`) e lo modifichi per riferirsi a `ext.prefix` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Prima" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Potete vedere che abbiamo effettuato tre modifiche. + +1. **Nel blocco `script:`, abbiamo aggiunto la riga `prefix = task.ext.prefix ?: "${meta.id}"`.** + Quella riga utilizza l'operatore `?:` per determinare il valore della variabile `prefix`: il contenuto di `task.ext.prefix` se non è vuoto, o l'identificatore dalla metamap (`meta.id`) se lo è. + Notate che mentre generalmente ci riferiamo a `ext.prefix`, questo codice deve riferirsi a `task.ext.prefix` per estrarre la configurazione `ext.prefix` a livello di modulo. + +2. **Nella riga di comando, abbiamo sostituito `cowpy-${input_file}` con `${prefix}.txt`.** + Qui è dove Nextflow inietterà il valore di `prefix` determinato dalla riga sopra. + +3. **Nel blocco `output:`, abbiamo sostituito `path("cowpy-${input_file}")` con `path("${prefix}.txt")`.** + Questo semplicemente ribadisce quale sarà il percorso del file secondo ciò che è scritto nella riga di comando. + +Di conseguenza, il nome del file di output è ora costruito utilizzando un valore predefinito sensato (l'identificatore dalla metamap) combinato con l'estensione del formato file appropriata. + +#### 1.4.2. Configurare `ext.prefix` nel file `modules.config` + +In questo caso il valore predefinito sensato non è sufficientemente espressivo per il nostro gusto; vogliamo utilizzare un pattern di denominazione personalizzato che includa il nome dello strumento, `cowpy-<id>.txt`, come avevamo prima. + +Lo faremo configurando `ext.prefix` in `modules.config`, proprio come abbiamo fatto per il parametro `character` con `ext.args`, tranne che questa volta il blocco `withName: 'COWPY' {}` esiste già, e dobbiamo solo aggiungere la seguente riga: + +```groovy title="Codice da aggiungere" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Questo comporrà la stringa che vogliamo. +Notate che ancora una volta utilizziamo le parentesi graffe, questa volta per dire a Nextflow di valutare il valore di `meta.id` a runtime. + +Aggiungiamolo. + +Aprite `conf/modules.config` e aggiungete il codice di configurazione all'interno del blocco `process {}` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Prima" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Nel caso si stesse chiedendo, la closure `ext.prefix` ha accesso al pezzo corretto di metadati perché la configurazione viene valutata nel contesto dell'esecuzione del processo, dove i metadati sono disponibili. + +#### 1.4.3. Eseguire il pipeline per testarlo + +Verifichiamo che il workflow funzioni ancora come previsto. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dia un'occhiata all'output nella directory dei risultati. +Dovrebbe vedere il file di output cowpy con la stessa denominazione di prima: `cowpy-test.txt`, basato sul nome batch predefinito. + +??? abstract "Contenuto della directory" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Sentitevi liberi di cambiare la configurazione `ext.prefix` in `conf/modules.config` per convincervi che potete cambiare il pattern di denominazione senza dover apportare modifiche al codice del modulo o del workflow. + +In alternativa, potete anche provare a eseguirlo di nuovo con un parametro `--batch` diverso specificato sulla riga di comando per convincervi che quella parte sia ancora personalizzabile al volo. + +Questo dimostra come `ext.prefix` vi permetta di mantenere la vostra convenzione di denominazione preferita mantenendo flessibile l'interfaccia del modulo. + +Per riassumere i vantaggi di questo approccio: + +- **Denominazione standardizzata**: I file di output sono tipicamente denominati utilizzando gli ID dei campioni dai metadati +- **Configurabile**: Gli utenti possono sovrascrivere la denominazione predefinita se necessario +- **Coerente**: Tutti i moduli nf-core seguono questo pattern +- **Prevedibile**: Facile sapere come saranno chiamati i file di output + +Abbastanza bene, vero? +Beh, c'è un'altra modifica importante che dobbiamo fare per migliorare il nostro modulo per adattarlo alle linee guida nf-core. + +### 1.5. Centralizzare la configurazione di pubblicazione + +Potrebbe aver notato che abbiamo pubblicato output in due directory diverse: + +- **`results`** — La directory di output originale che abbiamo utilizzato dall'inizio per i nostri moduli locali, impostata individualmente utilizzando direttive `publishDir` per-modulo; +- **`core-hello-results`** — La directory di output impostata con `--outdir` sulla riga di comando, che ha ricevuto i log nf-core e i risultati pubblicati da `CAT_CAT`. + +Questo è disordinato e subottimale; sarebbe meglio avere una posizione per tutto. +Ovviamente, potremmo andare in ciascuno dei nostri moduli locali e aggiornare manualmente la direttiva `publishDir` per utilizzare la directory `core-hello-results`, ma che dire della prossima volta che decidiamo di cambiare la directory di output? + +Avere moduli individuali che prendono decisioni di pubblicazione non è chiaramente la strada da percorrere, specialmente in un mondo dove lo stesso modulo potrebbe essere utilizzato in molti pipeline diversi, da persone che hanno esigenze o preferenze diverse. +Vogliamo poter controllare dove vengono pubblicati gli output a livello di configurazione del workflow. + +"Ehi," potrebbe dire, "`CAT_CAT` sta inviando i suoi output a `--outdir`. Forse dovremmo copiare la sua direttiva `publishDir`?" + +Sì, è un'ottima idea. + +Tranne che non ha una direttiva `publishDir`. (Vada avanti, guardi il codice del modulo.) + +Questo perché i pipeline nf-core centralizzano il controllo a livello di workflow configurando `publishDir` in `conf/modules.config` piuttosto che nei singoli moduli. +Nello specifico, il template nf-core dichiara una direttiva `publishDir` predefinita (con una struttura di directory predefinita) che si applica a tutti i moduli a meno che non venga fornita una direttiva sovrascrivente. + +Non suona fantastico? Potrebbe essere che per sfruttare questa direttiva predefinita, tutto ciò che dobbiamo fare è rimuovere la direttiva `publishDir` attuale dai nostri moduli locali? + +Proviamolo su `COWPY` per vedere cosa succede, poi guarderemo il codice per la configurazione predefinita per capire come funziona. + +Infine, dimostreremo come sovrascrivere il comportamento predefinito se desiderateto. + +#### 1.5.1. Rimuovere la direttiva `publishDir` da `COWPY` + +Facciamolo. +Aprite il file del modulo `cowpy.nf` (sotto `core-hello/modules/local/`) e rimuova la direttiva `publishDir` come mostrato di seguito. + +=== "Dopo" + + ```groovy title="core-hello/modules/local/cowpy.nf (estratto)" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Prima" + + ```groovy title="core-hello/modules/local/cowpy.nf (estratto)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +È tutto! + +#### 1.5.2. Eseguire il pipeline per testarlo + +Diamo un'occhiata a cosa succede se eseguiamo il pipeline ora. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dia un'occhiata alla vostra directory di lavoro corrente. +Ora `core-hello-results` contiene anche gli output del modulo `COWPY`. + +??? abstract "Contenuto della directory" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Potete vedere che Nextflow ha creato questa gerarchia di directory basata sui nomi del workflow e del modulo. + +Il codice responsabile si trova nel file `conf/modules.config`. +Questa è la configurazione `publishDir` predefinita che fa parte del template nf-core e si applica a tutti i processi: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Questo può sembrare complicato, quindi esaminiamo ciascuno dei tre componenti: + +- **`path:`** Determina la directory di output in base al nome del processo. + Il nome completo di un processo contenuto in `task.process` include la gerarchia di import di workflow e moduli (come `CORE_HELLO:HELLO:CAT_CAT`). + Le operazioni `tokenize` eliminano quella gerarchia per ottenere solo il nome del processo, poi prendono la prima parte prima di qualsiasi underscore (se applicabile), e la convertono in minuscolo. + Questo è ciò che determina che i risultati di `CAT_CAT` vengano pubblicati in `${params.outdir}/cat/`. +- **`mode:`** Controlla come vengono pubblicati i file (copy, symlink, ecc.). + Questo è configurabile tramite il parametro `params.publish_dir_mode`. +- **`saveAs:`** Filtra quali file pubblicare. + Questo esempio esclude i file `versions.yml` restituendo `null` per loro, impedendo che vengano pubblicati. + +Questo fornisce una logica coerente per organizzare gli output. + +L'output appare ancora meglio quando tutti i moduli in un pipeline adottano questa convenzione, quindi sentitevi liberi di andare a eliminare le direttive `publishDir` dagli altri moduli nel vostro pipeline. +Questo valore predefinito verrà applicato anche ai moduli che non abbiamo esplicitamente modificato per seguire le linee guida nf-core. + +Detto questo, potreste decidere di voler organizzare i vostri input in modo diverso, e la buona notizia è che è facile farlo. + +#### 1.5.3. Sovrascrivere il valore predefinito + +Per sovrascrivere la direttiva `publishDir` predefinita, potete semplicemente aggiungere le vostre direttive al file `conf/modules.config`. + +Ad esempio, potreste sovrascrivere il valore predefinito per un singolo processo utilizzando il selettore `withName:`, come in questo esempio dove aggiungiamo una direttiva `publishDir` personalizzata per il processo 'COWPY'. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +Non effettueremo effettivamente quella modifica, ma sentitevi liberi di sperimentare con questo e vedere quale logica potete implementare. + +Il punto è che questo sistema vi dà il meglio di entrambi i mondi: coerenza per default e la flessibilità di personalizzare la configurazione su richiesta. + +Per riassumere, ottenete: + +- **Unica fonte di verità**: Tutta la configurazione di pubblicazione risiede in `modules.config` +- **Default utile**: I processi funzionano out-of-the-box senza configurazione per-modulo +- **Personalizzazione facile**: Sovrascrivete il comportamento di pubblicazione nella configurazione, non nel codice del modulo +- **Moduli portabili**: I moduli non hardcodeano le posizioni di output + +Questo completa l'insieme di funzionalità dei moduli nf-core che dovreste assolutamente imparare a utilizzare, ma ce ne sono altre che potete leggere nelle [specifiche dei moduli nf-core](https://nf-co.re/docs/guidelines/components/modules). + +### Takeaway + +Ora sa come adattare i moduli locali per seguire le convenzioni nf-core: + +- Progettare i vostri moduli per accettare e propagare tuple di metadati; +- Utilizzare `ext.args` per mantenere le interfacce dei moduli minimali e portabili; +- Utilizzare `ext.prefix` per una denominazione dei file di output configurabile e standardizzata; +- Adottare la direttiva `publishDir` centralizzata predefinita per una struttura della directory dei risultati coerente. + +### Prossimi passi + +Imparate come utilizzare gli strumenti integrati nf-core basati su template per creare moduli nel modo più semplice. + +--- + +## 2. Creare un modulo con gli strumenti nf-core + +Ora che ha imparato i pattern dei moduli nf-core applicandoli manualmente, vediamo come creerebbe i moduli nella pratica. + +### 2.1. Generare una struttura di modulo da un template + +Simile a ciò che esiste per la creazione di pipeline, il progetto nf-core fornisce strumenti per generare moduli correttamente strutturati basati su un template, con tutti questi pattern integrati dall'inizio. + +#### 2.1.1. Eseguire il comando di creazione del modulo + +Il comando `nf-core modules create` genera un template di modulo che segue già tutte le convenzioni che ha imparato. + +Creiamo una nuova versione del modulo `COWPY` con un template minimale eseguendo questo comando: + +```bash +nf-core modules create --empty-template COWPY +``` + +Il flag `--empty-template` crea un template iniziale pulito senza codice extra, rendendo più facile vedere la struttura essenziale. + +Il comando viene eseguito in modo interattivo, guidandoLa attraverso la configurazione. +Cerca automaticamente le informazioni sullo strumento da repository di pacchetti come Bioconda e bio.tools per pre-popolare i metadati. + +Le verrà richiesto di configurare diverse opzioni: + +- **Informazioni sull'autore**: Il vostro nome utente GitHub per l'attribuzione +- **Etichetta di risorsa**: Un insieme predefinito di requisiti computazionali. + Il progetto nf-core fornisce etichette standard come `process_single` per strumenti leggeri e `process_high` per quelli impegnativi. + Queste etichette aiutano a gestire l'allocazione delle risorse in diversi ambienti di esecuzione. +- **Requisito di metadati**: Se il modulo necessita di informazioni specifiche per campione tramite una mappa `meta` (di solito sì per i moduli di elaborazione dati). + +Lo strumento gestisce la complessità di trovare informazioni sui pacchetti e configurare la struttura, permettendoLe di concentrarSi sull'implementazione della logica specifica dello strumento. + +#### 2.1.2. Esaminare la struttura del modulo + +Lo strumento crea una struttura di modulo completa in `modules/local/` (o `modules/nf-core/` se si trova nel repository nf-core/modules): + +??? abstract "Contenuto della directory" + + ```console + modules/local/cowpy + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + └── main.nf.test + ``` + +Ogni file serve uno scopo specifico: + +- **`main.nf`**: Definizione del processo con tutti i pattern nf-core integrati +- **`meta.yml`**: Documentazione del modulo che descrive input, output e lo strumento +- **`environment.yml`**: Specifica dell'ambiente Conda per le dipendenze +- **`tests/main.nf.test`**: Casi di test nf-test per validare il funzionamento del modulo + +!!! tip "Impari di più sui test" + + Il file di test generato utilizza nf-test, un framework di testing per pipeline e moduli Nextflow. Per imparare come scrivere ed eseguire questi test, veda la [side quest nf-test](../side_quests/nf-test.md). + +Il `main.nf` generato include tutti i pattern che ha appena imparato, più alcune funzionalità aggiuntive: + +```groovy title="modules/local/cowpy/main.nf" hl_lines="11 21 22" +process COWPY { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot. +``` diff --git a/docs/it/docs/hello_nf-core/05_input_validation.md b/docs/it/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..47eb849414 --- /dev/null +++ b/docs/it/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Parte 5: Validazione degli input + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa quinta parte del corso di formazione Hello nf-core, mostriamo come utilizzare il plugin nf-schema per validare gli input e i parametri della pipeline. + +??? info "Come iniziare da questa sezione" + + Questa sezione presuppone che abbiate completato la [Parte 4: Creare un modulo nf-core](./04_make_module.md) e che abbiate aggiornato il modulo del processo `COWPY` agli standard nf-core nella vostra pipeline. + + Se non avete completato la Parte 4 o desiderate ripartire da zero per questa parte, potete utilizzare la soluzione `core-hello-part4` come punto di partenza. + Eseguite questi comandi dall'interno della directory `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Questo vi fornisce una pipeline con il modulo `COWPY` già aggiornato per seguire gli standard nf-core. + Potete verificare che venga eseguita con successo eseguendo il seguente comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Riscaldamento: Un po' di contesto + +### 0.1. Perché la validazione è importante + +Immaginate di eseguire la vostra pipeline per due ore, solo per vederla interrompersi perché un utente ha fornito un file con l'estensione sbagliata. O di passare ore a debuggare errori criptici, solo per scoprire che un parametro era scritto in modo errato. Senza validazione degli input, questi scenari sono comuni. + +Considerate questo esempio: + +```console title="Senza validazione" +$ nextflow run my-pipeline --input data.txt --output results + +...2 ore dopo... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +La pipeline ha accettato input non validi ed è stata eseguita per ore prima di fallire. Con una validazione adeguata: + +```console title="Con validazione" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +La pipeline fallisce immediatamente con messaggi di errore chiari e attuabili. Questo risparmia tempo, risorse di calcolo e frustrazione. + +### 0.2. Il plugin nf-schema + +Il [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/) è un plugin Nextflow che fornisce capacità di validazione complete per le pipeline Nextflow. +Sebbene nf-schema funzioni con qualsiasi workflow Nextflow, è la soluzione di validazione standard per tutte le pipeline nf-core. + +nf-schema fornisce diverse funzioni chiave: + +- **Validazione dei parametri**: Valida i parametri della pipeline rispetto a `nextflow_schema.json` +- **Validazione del sample sheet**: Valida i file di input rispetto a `assets/schema_input.json` +- **Conversione dei canali**: Converte i sample sheet validati in canali Nextflow +- **Generazione del testo di aiuto**: Genera automaticamente l'output `--help` dalle definizioni dello schema +- **Riepilogo dei parametri**: Mostra quali parametri differiscono dai valori predefiniti + +nf-schema è il successore del plugin nf-validation deprecato e utilizza lo standard [JSON Schema Draft 2020-12](https://json-schema.org/) per la validazione. + +??? info "Cosa sono i plugin Nextflow?" + + I plugin sono estensioni che aggiungono nuove funzionalità al linguaggio Nextflow stesso. Vengono installati tramite un blocco `plugins{}` in `nextflow.config` e possono fornire: + + - Nuove funzioni e classi che possono essere importate (come `samplesheetToList`) + - Nuove funzionalità DSL e operatori + - Integrazione con servizi esterni + + Il plugin nf-schema è specificato in `nextflow.config`: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Una volta installato, potete importare funzioni dai plugin utilizzando la sintassi `include { functionName } from 'plugin/plugin-name'`. + +### 0.3. Due file schema per due tipi di validazione + +Una pipeline nf-core utilizzerà due file schema separati, che corrispondono a due tipi di validazione: + +| File Schema | Scopo | Valida | +| -------------------------- | -------------------------- | --------------------------------------------------------- | +| `nextflow_schema.json` | Validazione dei parametri | Flag da riga di comando: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Validazione dei dati input | Contenuto dei sample sheet e dei file di input | + +Entrambi gli schema utilizzano il formato JSON Schema, uno standard ampiamente adottato per descrivere e validare strutture di dati. + +**La validazione dei parametri** valida i parametri da riga di comando (flag come `--outdir`, `--batch`, `--input`): + +- Controlla i tipi, gli intervalli e i formati dei parametri +- Assicura che i parametri richiesti siano forniti +- Valida che i percorsi dei file esistano +- Definita in `nextflow_schema.json` + +**La validazione dei dati input** valida la struttura dei sample sheet e dei file manifest (file CSV/TSV che descrivono i vostri dati): + +- Controlla la struttura delle colonne e i tipi di dati +- Valida che i percorsi dei file referenziati nel sample sheet esistano +- Assicura che i campi richiesti siano presenti +- Definita in `assets/schema_input.json` + +!!! warning "Cosa NON fa la validazione dei dati input" + + La validazione dei dati input controlla la struttura dei *file manifest* (sample sheet, file CSV), NON il contenuto dei vostri file di dati effettivi (FASTQ, BAM, VCF, ecc.). + + Per dati su larga scala, la validazione del contenuto dei file (come il controllo dell'integrità dei BAM) dovrebbe avvenire nei processi della pipeline in esecuzione sui nodi worker, non durante la fase di validazione sulla macchina orchestratrice. + +### 0.4. Quando dovrebbe avvenire la validazione? + +```mermaid +graph LR + A[L'utente esegue la pipeline] --> B[Validazione dei parametri] + B -->|✓ Valido| C[Validazione dei dati input] + B -->|✗ Non valido| D[Errore: Correggere i parametri] + C -->|✓ Valido| E[La pipeline viene eseguita] + C -->|✗ Non valido| F[Errore: Correggere i dati input] +``` + +La validazione dovrebbe avvenire **prima** che qualsiasi processo della pipeline venga eseguito, per fornire un feedback rapido e prevenire tempo di calcolo sprecato. + +Ora applichiamo questi principi nella pratica, iniziando con la validazione dei parametri. + +--- + +## 1. Validazione dei parametri (nextflow_schema.json) + +Iniziamo aggiungendo la validazione dei parametri alla nostra pipeline. Questo valida i flag da riga di comando come `--input`, `--outdir` e `--batch`. + +### 1.1. Configurare la validazione per saltare la validazione del file di input + +Il template della pipeline nf-core viene fornito con nf-schema già installato e configurato: + +- Il plugin nf-schema è installato tramite il blocco `plugins{}` in `nextflow.config` +- La validazione dei parametri è abilitata per impostazione predefinita tramite `params.validate_params = true` +- La validazione viene eseguita dal subworkflow `UTILS_NFSCHEMA_PLUGIN` durante l'inizializzazione della pipeline + +Il comportamento della validazione è controllato tramite lo scope `validation{}` in `nextflow.config`. + +Poiché lavoreremo prima sulla validazione dei parametri (questa sezione) e non configureremo lo schema dei dati input fino alla sezione 2, dobbiamo temporaneamente dire a nf-schema di saltare la validazione del contenuto del file del parametro `input`. + +Aprite `nextflow.config` e trovate il blocco `validation` (intorno alla riga 246). Aggiungete `ignoreParams` per saltare la validazione del file di input: + +=== "Dopo" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Questa configurazione dice a nf-schema di: + +- **`defaultIgnoreParams`**: Saltare la validazione di parametri complessi come `genomes` (impostato dagli sviluppatori del template) +- **`ignoreParams`**: Saltare la validazione del contenuto del file del parametro `input` (temporaneo; riabiliteremo questo nella sezione 2) +- **`monochromeLogs`**: Disabilitare l'output colorato nei messaggi di validazione quando impostato su `true` (controllato da `params.monochrome_logs`) + +!!! note "Perché ignorare il parametro input?" + + Il parametro `input` in `nextflow_schema.json` ha `"schema": "assets/schema_input.json"` che dice a nf-schema di validare il *contenuto* del file CSV di input rispetto a quello schema. + Poiché non abbiamo ancora configurato quello schema, ignoriamo temporaneamente questa validazione. + Rimuoveremo questa impostazione nella sezione 2 dopo aver configurato lo schema dei dati input. + +### 1.2. Esaminare lo schema dei parametri + +Diamo un'occhiata a una sezione del file `nextflow_schema.json` che è venuto con il nostro template della pipeline: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +Lo schema dei parametri è organizzato in gruppi. Ecco il gruppo `input_output_options`: + +```json title="core-hello/nextflow_schema.json (estratto)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Ogni input descritto qui ha le seguenti proprietà chiave che possono essere validate: + +- **`type`**: Tipo di dato (string, integer, boolean, number) +- **`format`**: Formati speciali come `file-path` o `directory-path` +- **`exists`**: Per i percorsi di file, controlla se il file esiste +- **`pattern`**: Espressione regolare che il valore deve corrispondere +- **`required`**: Array di nomi di parametri che devono essere forniti +- **`mimetype`**: Mimetype del file atteso per la validazione + +Se avete un occhio attento, potreste notare che il parametro input `batch` che abbiamo usato non è ancora definito nello schema. +Lo aggiungeremo nella prossima sezione. + +??? info "Da dove provengono i parametri dello schema?" + + La validazione dello schema utilizza `nextflow.config` come base per le definizioni dei parametri. + I parametri dichiarati altrove negli script del vostro workflow (come in `main.nf` o nei file dei moduli) **non** vengono automaticamente rilevati dal validatore dello schema. + + Questo significa che dovreste sempre dichiarare i parametri della vostra pipeline in `nextflow.config`, e poi definire le loro regole di validazione in `nextflow_schema.json`. + +### 1.3. Aggiungere il parametro batch + +Sebbene lo schema sia un file JSON che può essere modificato manualmente, **la modifica manuale è soggetta a errori e non è consigliata**. +Invece, nf-core fornisce uno strumento GUI interattivo che gestisce la sintassi JSON Schema per voi e valida le vostre modifiche: + +```bash +nf-core pipelines schema build +``` + +Dovreste vedere qualcosa del genere: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Digitate `y` e premete Invio per avviare l'interfaccia web interattiva. + +Il vostro browser si aprirà mostrando il costruttore dello schema dei parametri: + +![Interfaccia del costruttore dello schema](./img/schema_build.png) + +Per aggiungere il parametro `batch`: + +1. Cliccate sul pulsante **"Add parameter"** in alto +2. Utilizzate la maniglia di trascinamento (⋮⋮) per spostare il nuovo parametro verso l'alto nel gruppo "Input/output options", sotto il parametro `input` +3. Compilate i dettagli del parametro: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: spuntate la casella + - Opzionalmente, selezionate un'icona dal selettore di icone (ad es., `fas fa-layer-group`) + +![Aggiunta del parametro batch](./img/schema_add.png) + +Quando avete finito, cliccate sul pulsante **"Finished"** in alto a destra. + +Tornando al vostro terminale, vedrete: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Premete `Ctrl+C` per uscire dal costruttore dello schema. + +Lo strumento ha ora aggiornato il vostro file `nextflow_schema.json` con il nuovo parametro `batch`, gestendo correttamente tutta la sintassi JSON Schema. + +### 1.4. Verificare le modifiche + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (estratto)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Dovreste vedere che il parametro `batch` è stato aggiunto allo schema con il campo "required" che ora mostra `["input", "outdir", "batch"]`. + +### 1.5. Testare la validazione dei parametri + +Ora testiamo che la validazione dei parametri funzioni correttamente. + +Prima, provate a eseguire senza il parametro `input` richiesto: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Output del comando" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Perfetto! La validazione rileva il parametro richiesto mancante prima che la pipeline venga eseguita. + +Ora provate con un set valido di parametri: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +La pipeline dovrebbe essere eseguita con successo, e il parametro `batch` è ora validato. + +### Takeaway + +Avete imparato come utilizzare lo strumento interattivo `nf-core pipelines schema build` per aggiungere parametri a `nextflow_schema.json` e avete visto la validazione dei parametri in azione. +L'interfaccia web gestisce tutta la sintassi JSON Schema per voi, rendendo facile gestire schemi di parametri complessi senza modifiche JSON manuali soggette a errori. + +### Cosa c'è dopo? + +Ora che la validazione dei parametri funziona, aggiungiamo la validazione per il contenuto del file di dati input. + +--- + +## 2. Validazione dei dati input (schema_input.json) + +Aggiungeremo la validazione per il contenuto del nostro file CSV di input. +Mentre la validazione dei parametri controlla i flag da riga di comando, la validazione dei dati input assicura che i dati all'interno del file CSV siano strutturati correttamente. + +### 2.1. Comprendere il formato greetings.csv + +Ricordiamoci come appare il nostro input: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Questo è un semplice CSV con: + +- Tre colonne (nessuna intestazione) +- Su ogni riga: un saluto, una lingua e un punteggio +- Le prime due colonne sono stringhe di testo senza requisiti di formato speciali +- La terza colonna è un intero + +Per la nostra pipeline, è richiesta solo la prima colonna. + +### 2.2. Progettare la struttura dello schema + +Per il nostro caso d'uso, vogliamo: + +1. Accettare input CSV con almeno una colonna +2. Trattare il primo elemento di ogni riga come una stringa di saluto +3. Assicurarsi che i saluti non siano vuoti e non inizino con spazi +4. Assicurarsi che il campo lingua corrisponda a uno dei codici lingua supportati (en, fr, es, it, de) +5. Assicurarsi che il campo punteggio sia un intero con un valore compreso tra 0 e 100 + +Struttureremo questo come un array di oggetti, dove ogni oggetto ha almeno un campo `greeting`. + +### 2.3. Aggiornare il file schema + +Il template della pipeline nf-core include uno `assets/schema_input.json` predefinito progettato per dati di sequenziamento paired-end. +Dobbiamo sostituirlo con uno schema più semplice per il nostro caso d'uso dei saluti. + +Aprite `assets/schema_input.json` e sostituite le sezioni `properties` e `required`: + +=== "Dopo" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Prima" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Le modifiche chiave: + +- **`description`**: Aggiornata per menzionare "greetings file" +- **`properties`**: Sostituite `sample`, `fastq_1` e `fastq_2` con `greeting`, `language` e `score` + - **`type:`** Impone string (`greeting`, `language`) o integer (`score`) + - **`pattern: "^\\S.*$"`**: Il saluto deve iniziare con un carattere non spazio (ma può contenere spazi dopo) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: Il codice lingua deve essere nel set supportato + - **`"minimum": 0` e `"maximum": 100`**: Il valore del punteggio deve essere compreso tra 0 e 100 + - **`errorMessage`**: Messaggio di errore personalizzato mostrato se la validazione fallisce +- **`required`**: Cambiato da `["sample", "fastq_1"]` a `["greeting"]` + +### 2.4. Aggiungere un'intestazione al file greetings.csv + +Quando nf-schema legge un file CSV, si aspetta che la prima riga contenga intestazioni di colonne che corrispondano ai nomi dei campi nello schema. + +Per il nostro caso semplice, dobbiamo aggiungere una riga di intestazione al nostro file di saluti: + +=== "Dopo" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Prima" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Ora il file CSV ha una riga di intestazione che corrisponde ai nomi dei campi nel nostro schema. + +Il passaggio finale è implementare la validazione nel codice della pipeline utilizzando `samplesheetToList`. + +### 2.5. Implementare la validazione nella pipeline + +Ora dobbiamo sostituire il nostro semplice parsing CSV con la funzione `samplesheetToList` di nf-schema, che validerà e analizzerà il samplesheet. + +La funzione `samplesheetToList`: + +1. Legge il sample sheet di input (CSV, TSV, JSON o YAML) +2. Lo valida rispetto allo schema JSON fornito +3. Restituisce una lista Groovy dove ogni voce corrisponde a una riga +4. Genera messaggi di errore utili se la validazione fallisce + +Aggiorniamo il codice di gestione dell'input: + +Aprite `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` e localizzate la sezione dove creiamo il canale di input (intorno alla riga 80). + +Dobbiamo: + +1. Utilizzare la funzione `samplesheetToList` (già importata nel template) +2. Validare e analizzare l'input +3. Estrarre solo le stringhe di saluto per il nostro workflow + +Prima, notate che la funzione `samplesheetToList` è già importata all'inizio del file (il template nf-core include questo per impostazione predefinita): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subworkflow with functionality specific to the core/hello pipeline +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Ora aggiornate il codice di creazione del canale: + +=== "Dopo" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Prima" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Analizziamo cosa è cambiato: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Valida il file di input rispetto al nostro schema e restituisce una lista +2. **`Channel.fromList(...)`**: Converte la lista in un canale Nextflow + +Questo completa l'implementazione della validazione dei dati input utilizzando `samplesheetToList` e schemi JSON. + +Ora che abbiamo configurato lo schema dei dati input, possiamo rimuovere l'impostazione ignore temporanea che abbiamo aggiunto in precedenza. + +### 2.6. Riabilitare la validazione dell'input + +Aprite `nextflow.config` e rimuovete la riga `ignoreParams` dal blocco `validation`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Ora nf-schema validerà sia i tipi di parametri CHE il contenuto del file di input. + +### 2.7. Testare la validazione dell'input + +Verifichiamo che la nostra validazione funzioni testando sia input validi che non validi. + +#### 2.7.1. Test con input valido + +Prima, confermiamo che la pipeline venga eseguita con successo con un input valido. +Notate che non abbiamo più bisogno di `--validate_params false` poiché la validazione funziona! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Output del comando" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Ottimo! La pipeline viene eseguita con successo e la validazione passa silenziosamente. +L'avviso su `--character` è solo informativo poiché non è definito nello schema. +Se volete, utilizzate ciò che avete imparato per aggiungere la validazione anche per quel parametro! + +#### 2.7.2. Test con input non valido + +Superare la validazione è sempre una bella sensazione, ma assicuriamoci che la validazione rilevi effettivamente gli errori. + +Per creare un file di test con un nome di colonna non valido, iniziate facendo una copia del file `greetings.csv`: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Ora aprite il file e cambiate il nome della prima colonna, nella riga di intestazione, da `greeting` a `message`: + +=== "Dopo" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Prima" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Questo non corrisponde al nostro schema, quindi la validazione dovrebbe generare un errore. + +Provate a eseguire la pipeline con questo input non valido: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Perfetto! La validazione ha rilevato l'errore e ha fornito un messaggio di errore chiaro e utile che indica: + +- Quale file ha fallito la validazione +- Quale voce (riga 1, la prima riga di dati) ha il problema +- Qual è il problema specifico (campo richiesto `greeting` mancante) + +La validazione dello schema assicura che i file di input abbiano la struttura corretta prima che la pipeline venga eseguita, risparmiando tempo e prevenendo errori confusi più avanti nell'esecuzione. + +Se volete esercitarvi, sentitevi liberi di creare altri file di input di saluti che violano lo schema in altri modi divertenti. + +### Takeaway + +Avete implementato e testato sia la validazione dei parametri che la validazione dei dati input. La vostra pipeline ora valida gli input prima dell'esecuzione, fornendo feedback rapido e messaggi di errore chiari. + +!!! tip "Ulteriori letture" + + Per saperne di più sulle funzionalità e sui pattern di validazione avanzati, consultate la [documentazione di nf-schema](https://nextflow-io.github.io/nf-schema/latest/). Il comando `nf-core pipelines schema build` fornisce una GUI interattiva per gestire schemi complessi. + +### Cosa c'è dopo? + +Avete completato tutte e cinque le parti del corso di formazione Hello nf-core! + +Continuate con il [Riepilogo](summary.md) per riflettere su ciò che avete costruito e imparato. diff --git a/docs/it/docs/hello_nf-core/index.md b/docs/it/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..c20244172a --- /dev/null +++ b/docs/it/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Recuperare, lanciare e gestire l'esecuzione di pipeline nf-core + - Descrivere la struttura del codice e l'organizzazione dei progetti delle pipeline nf-core + - Creare una pipeline di base compatibile con nf-core da un template + - Aggiornare un workflow Nextflow semplice per adattarlo agli standard nf-core + - Aggiungere moduli nf-core a una pipeline compatibile con nf-core + - Contribuire con i propri moduli a nf-core + - Validare input e parametri utilizzando gli strumenti nf-core + audience_prerequisites: + - "**Pubblico:** Questo corso è progettato per studenti che hanno già familiarità con Nextflow di base e vogliono imparare a utilizzare le risorse e le best practice di nf-core." + - "**Competenze:** Si presume familiarità con la riga di comando, concetti di scripting di base e formati di file comuni." + - "**Corsi:** È necessario aver completato il corso [Hello Nextflow](../hello_nextflow/index.md) o equivalente." + - "**Dominio:** Gli esercizi sono tutti indipendenti dal dominio, quindi non è richiesta alcuna conoscenza scientifica preliminare." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core è un'introduzione pratica all'uso delle risorse e delle best practice di nf-core.** + +![nf-core logo](./img/nf-core-logo.png) + +Attraverso esempi pratici ed esercizi guidati, imparerete a utilizzare e sviluppare moduli e pipeline compatibili con nf-core, e a utilizzare efficacemente gli strumenti nf-core. + +Acquisirà le competenze e la sicurezza per iniziare a sviluppare pipeline secondo le best practice di nf-core. + +<!-- additional_information --> + +## Panoramica del corso + +Questo corso è progettato per essere pratico, con esercizi orientati agli obiettivi strutturati per introdurre le informazioni gradualmente. + +Verrà introdotto a [**nf-core**](https://nf-co.re/), uno sforzo comunitario per sviluppare e mantenere un insieme curato di pipeline scientifiche costruite utilizzando Nextflow, oltre a strumenti e linee guida rilevanti che promuovono lo sviluppo aperto, i test e la revisione tra pari ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +Le pipeline sviluppate dalla comunità nf-core sono progettate per essere modulari, scalabili e portabili, consentendo ai ricercatori di adattarle ed eseguirle facilmente utilizzando i propri dati e risorse di calcolo. +Le linee guida sulle best practice applicate dal progetto garantiscono inoltre che le pipeline siano robuste, ben documentate e validate su dataset reali. +Questo aiuta ad aumentare l'affidabilità e la riproducibilità delle analisi scientifiche e, in definitiva, consente ai ricercatori di accelerare le proprie scoperte scientifiche. + +Non copriremo tutto ciò che c'è da sapere sulle pipeline nf-core in questo corso, perché nf-core comprende molte funzionalità e convenzioni sviluppate dalla comunità nel corso degli anni. +Ci concentreremo invece sui concetti essenziali che La aiuteranno a iniziare e a capire come funziona nf-core. + +### Piano delle lezioni + +Abbiamo suddiviso il corso in cinque parti, ciascuna focalizzata su aspetti specifici dell'utilizzo delle risorse nf-core. + +| Capitolo del corso | Riepilogo | Durata stimata | +| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Parte 1: Eseguire una pipeline demo](./01_run_demo.md) | Eseguire una pipeline nf-core esistente ed esaminare la sua struttura di codice per comprendere cosa rende queste pipeline diverse dai workflow Nextflow di base | 30 minuti | +| [Parte 2: Riscrivere Hello per nf-core](./02_rewrite_hello.md) | Adattare un workflow esistente allo scaffold del template nf-core, partendo dal workflow semplice prodotto nel corso [Hello Nextflow](../hello_nextflow/index.md) | 60 minuti | +| [Parte 3: Usare un modulo nf-core](./03_use_module.md) | Esplorare la libreria di moduli della comunità e imparare a integrare moduli pre-costruiti e testati che incapsulano strumenti bioinformatici comuni | 30 minuti | +| [Parte 4: Creare un modulo nf-core](./04_make_module.md) | Creare il proprio modulo in stile nf-core utilizzando la struttura specifica, le convenzioni di denominazione e i requisiti di metadati stabiliti da nf-core | 30 minuti | +| [Parte 5: Aggiungere la validazione dell'input](./05_input_validation.md) | Implementare la validazione dell'input sia per i parametri da riga di comando che per i file di dati di input utilizzando nf-schema | 30 minuti | + +Al termine di questo corso, sarà in grado di sfruttare l'enorme ricchezza di risorse offerte dal progetto nf-core. + +Pronto a iniziare il corso? + +[Inizia a imparare :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/it/docs/hello_nf-core/next_steps.md b/docs/it/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..cf4639de1f --- /dev/null +++ b/docs/it/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Riepilogo del corso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni per aver completato il corso di formazione Hello nf-core! 🎉 + +<!-- placeholder for video --> + +## Il suo percorso + +Ha iniziato imparando a recuperare ed eseguire una pipeline demo, poi ha affrontato la conversione di un semplice workflow Nextflow in una pipeline nf-core. +Ha imparato a creare uno scaffold di pipeline utilizzando un template e ha innestato la pipeline esistente su quello scaffold. +Poi ha gradualmente perfezionato la pipeline sostituendo uno dei moduli locali con un modulo nf-core, ha trasformato un altro modulo locale per adattarlo agli standard nf-core e ha aggiunto la validazione dell'input. + +### Cosa ha costruito + +La sua pipeline finale `core-hello` ora dispone di: + +- **Struttura standardizzata** utilizzando il template nf-core con directory organizzate per workflows, subworkflows, moduli e configurazione +- **Moduli della community** dal repository nf-core (`cat/cat`) insieme ai suoi moduli personalizzati +- **Validazione completa** che verifica sia i parametri che i dati di input prima dell'esecuzione della pipeline +- **Configurazione professionale** con profili per diversi ambienti di esecuzione +- **Documentazione completa** e metadati seguendo le convenzioni nf-core + +### Competenze chiave acquisite + +Attraverso questo corso pratico, ha imparato a: + +1. **Navigare e comprendere** la struttura delle pipeline nf-core esplorando una pipeline esistente +2. **Ristrutturare i workflow** per renderli componibili e adattarli al template nf-core +3. **Trovare e integrare** moduli pre-costruiti dal repository della community +4. **Creare moduli personalizzati** seguendo gli standard nf-core per denominazione, struttura e metadati +5. **Implementare la validazione** utilizzando nf-schema per individuare errori precocemente con feedback chiari + +È ora equipaggiato con le conoscenze fondamentali per costruire pipeline nf-core pronte per la produzione che seguono le best practice della community. + +## Prossimi passi per sviluppare le sue competenze + +Ecco i nostri 3 suggerimenti principali per i prossimi passi: + +- Applicare Nextflow a un caso d'uso di analisi scientifica con [Nextflow for Science](../nf4_science/index.md) +- Esplorare funzionalità più avanzate di Nextflow con le [Side Quests](../side_quests/index.md) +- Partecipare [unendosi alla community nf-core](https://nf-co.re/join). + +Infine, Le raccomandiamo di dare un'occhiata a [**Seqera Platform**](https://seqera.io/), una piattaforma basata su cloud sviluppata dai creatori di Nextflow che rende ancora più facile lanciare e gestire i suoi workflow, oltre a gestire i suoi dati ed eseguire analisi in modo interattivo in qualsiasi ambiente. + +## Questionario di feedback + +Prima di proseguire, Vi preghiamo di dedicare un minuto per completare il questionario del corso! Il suo feedback ci aiuta a migliorare i nostri materiali di formazione per tutti. + +[Compili il questionario :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/it/docs/hello_nf-core/survey.md b/docs/it/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..11d73f1bad --- /dev/null +++ b/docs/it/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Questionario di feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Prima di proseguire, completi questo breve questionario di 5 domande per valutare la formazione, condividere eventuali feedback sulla sua esperienza e farci sapere cos'altro potremmo fare per aiutarla nel suo percorso con Nextflow. + +Il completamento dovrebbe richiedere meno di un minuto. Grazie per aiutarci a migliorare i nostri materiali di formazione per tutti! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/it/docs/help.md b/docs/it/docs/help.md new file mode 100644 index 0000000000..86dfb543fa --- /dev/null +++ b/docs/it/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Ottenere aiuto +description: Risorse utili quando si ha un problema con la formazione Nextflow +hide: + - toc + - footer +--- + +# Ottenere aiuto + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Che si tratti di difficoltà nell'iniziare, di un blocco a metà percorso o di domande di approfondimento, non esiti a contattarci! Il nostro team community è qui per aiutare, e la community Nextflow in generale è molto attiva, inclusiva e desiderosa di dare una mano. + +Ecco le principali opzioni disponibili a seconda di ciò che sta cercando. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Forum della community__ + + --- + + Il nostro forum della community ha una categoria dedicata alla formazione, che è un ottimo posto per pubblicare domande o segnalare eventuali problemi riscontrati con la formazione. Potrebbe anche scoprire che la vostra domanda è già stata posta -- e ha già ricevuto risposta! + + [Vai al forum di formazione:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Canale Slack__ + + --- + + Se utilizza Slack, è il benvenuto a contattarci nel canale training nel workspace Slack di Nextflow. Lo Slack di Nextflow è un ottimo posto per chattare con altri sviluppatori e interagire con la community Nextflow in generale. + + [Unisciti allo Slack di Nextflow :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Segnalazioni su Github__ + + --- + + Se individua un errore nei materiali formativi, Vi preghiamo di segnalarlo aprendo una issue nel repository Github. Che si tratti di un refuso, un problema di formattazione o un bug effettivo che influisce sul codice, fatecelo sapere in modo da poterlo correggere! Accogliamo anche le PR direttamente. + + [Segnala un problema:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Assistente AI Seqera__ + + --- + + Seqera AI è un assistente AI addestrato sulle risorse Nextflow e nf-core. Può aiutare a fare debug del codice, chiarire concetti Nextflow e cercare la documentazione più velocemente. Consideri come avere un tutor disponibile 24/7 mentre lavora attraverso i corsi. + + [Chiedi a Seqera AI:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Documentazione Nextflow__ + + --- + + La documentazione ufficiale è la guida definitiva a tutte le funzionalità del linguaggio e le opzioni di configurazione. La utilizzi insieme a questa formazione per approfondire argomenti specifici, esplorare funzionalità avanzate e trovare riferimenti dettagliati sulla sintassi. + + [Consulta la documentazione:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Supporto professionale__ + + --- + + Nextflow è un software gratuito e open-source sviluppato da [Seqera](https://seqera.io/), un'azienda con sede in Spagna e uffici satellite nel Regno Unito e negli Stati Uniti. Offriamo servizi di supporto professionale per Nextflow, inclusa la formazione personalizzata. + + [Contattaci:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/it/docs/index.md b/docs/it/docs/index.md new file mode 100644 index 0000000000..42035c1a89 --- /dev/null +++ b/docs/it/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Home +description: Benvenuti nel portale di formazione della community Nextflow! +hide: + - toc + - footer +--- + +# Formazione Nextflow + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Corsi self-service__ + + --- + + **Benvenuti nel portale di formazione della community Nextflow!** + + I corsi di formazione elencati di seguito sono progettati per essere utilizzati come risorse self-service. + È possibile seguirli autonomamente in qualsiasi momento, sia nell'ambiente web che forniamo tramite Github Codespaces, sia nel proprio ambiente locale. + + [Esplora i corsi :material-arrow-right:](#catalogo-dei-corsi-di-formazione-nextflow){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Informazioni aggiuntive__ + + --- + + ??? warning "Compatibilità delle versioni" + + <!-- Any update to this content needs to be copied to the local installation page --> + **A partire da gennaio 2026, tutti i nostri corsi di formazione Nextflow richiedono Nextflow versione 25.10.2 o successiva, con la sintassi strict attivata, salvo diversa indicazione.** + + Per maggiori informazioni sui requisiti di versione e sulla sintassi strict, consultare la [guida alla migrazione nella documentazione Nextflow](https://nextflow.io/docs/latest/strict-syntax.html). + + Le versioni precedenti del materiale formativo corrispondenti alla sintassi precedente sono disponibili tramite il selettore di versione nella barra del menu di questa pagina web. + + ??? terminal "Opzioni per l'ambiente" + + Forniamo un ambiente di formazione basato sul web dove tutto il necessario per seguire la formazione è preinstallato, disponibile tramite Github Codespaces (richiede un account GitHub gratuito). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Se questa opzione non soddisfa le vostre esigenze, consulti le altre [Opzioni per l'ambiente](./envsetup/index.md). + + ??? learning "Eventi formativi" + + Se preferisce seguire la formazione Nextflow come parte di un evento strutturato, ci sono molte opportunità per farlo. vi consigliamo di esplorare le seguenti opzioni: + + - **[Training Weeks]()** organizzate trimestralmente dal team Community + - **[Seqera Events](https://seqera.io/events/)** includono eventi formativi in presenza organizzati da Seqera (cercare 'Seqera Sessions' e 'Nextflow Summit') + - **[Nextflow Ambassadors]()** organizzano eventi per le loro community locali + - **[nf-core events](https://nf-co.re/events)** includono hackathon della community + + ??? people "Informazioni per i formatori" + + Se siete un formatore che organizza le proprie sessioni di formazione, siete liberi di utilizzare i nostri materiali direttamente dal portale di formazione, a condizione di attribuire il corretto credito. Vedere 'Crediti e contributi' di seguito per i dettagli. + + Inoltre, ci piacerebbe ricevere il vostro feedback su come potremmo supportare meglio i vostri sforzi formativi! Vi preghiamo di contattarci all'indirizzo [community@seqera.io](mailto:community@seqera.io) o sul forum della community (vedere la pagina [Aiuto](help.md)). + + ??? licensing "Licenza open-source e politica sui contributi" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Questo materiale formativo è sviluppato e mantenuto da [Seqera](https://seqera.io) e rilasciato con una licenza open-source ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) a beneficio della community. Se desiderate utilizzare questo materiale in un modo che non rientra nell'ambito della licenza (si noti le limitazioni sull'uso commerciale e la redistribuzione), Vi preghiamo di contattarci all'indirizzo [community@seqera.io](mailto:community@seqera.io) per discutere la vostra richiesta. + + Accogliamo con piacere miglioramenti, correzioni e segnalazioni di bug dalla community. Ogni pagina ha un'icona :material-file-edit-outline: in alto a destra che collega al repository del codice, dove è possibile segnalare problemi o proporre modifiche al materiale sorgente della formazione tramite una pull request. Consultare il `README.md` nel repository per maggiori dettagli. + +</div> + +!!! note "Traduzione assistita da IA" + + Questa traduzione è stata creata utilizzando l'intelligenza artificiale e revisionata da traduttori umani. + Apprezziamo il tuo feedback e i tuoi suggerimenti per miglioramenti. + Consulta la nostra [guida alla traduzione](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) per maggiori informazioni. + +## Catalogo dei corsi di formazione Nextflow + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Percorso introduttivo__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow per principianti {.mt-1} + + Corsi indipendenti dal dominio applicativo, pensati per chi è completamente nuovo a Nextflow. Ogni corso consiste in una serie di moduli formativi progettati per aiutare gli studenti a sviluppare le proprie competenze progressivamente. + + ??? courses "**Hello Nextflow:** Impara a sviluppare le tue pipeline" + + Questo corso copre i componenti fondamentali del linguaggio Nextflow con sufficiente dettaglio per consentire lo sviluppo di pipeline semplici ma pienamente funzionanti, oltre agli elementi chiave della progettazione, sviluppo e configurazione delle pipeline. + + [Inizia la formazione Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Impara a eseguire pipeline esistenti" + + Un'introduzione concisa all'esecuzione e alla configurazione di pipeline Nextflow, basata sul corso Hello Nextflow per sviluppatori ma con meno enfasi sul codice. Copre esecuzione, output, struttura di base del codice e configurazione per diversi ambienti di calcolo. + + [Inizia la formazione Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow per la Scienza {.mt-1} + + Impara ad applicare i concetti e i componenti presentati in 'Hello Nextflow' a casi d'uso scientifici specifici. + + ??? courses "**Nextflow per la Genomica** (variant calling)" + + Per i ricercatori che desiderano imparare a sviluppare le proprie pipeline genomiche. Il corso utilizza un caso d'uso di variant calling per dimostrare come sviluppare una pipeline genomica semplice ma funzionale. + + [Inizia la formazione Nextflow per la Genomica :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow per RNAseq** (bulk RNAseq)" + + Per i ricercatori che desiderano imparare a sviluppare le proprie pipeline RNAseq. Il corso utilizza un caso d'uso di elaborazione bulk RNAseq per dimostrare come sviluppare una pipeline RNAseq semplice ma funzionale. + + [Inizia la formazione Nextflow per RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow per l'Imaging** (spatial omics)" + + Per i ricercatori in imaging e spatial omics che desiderano imparare a eseguire e personalizzare pipeline di analisi. Il corso utilizza la pipeline nf-core/molkart per fornire una pipeline biologicamente rilevante e dimostrare come eseguire, configurare e gestire gli input per i workflow Nextflow. + + [Inizia la formazione Nextflow per l'Imaging :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Percorso avanzato__ + + --- + + ### :material-bridge:{.nextflow-primary} Da Nextflow a nf-core {.mt-1} + + Impara a utilizzare il codice e le best practice del progetto community [nf-core](https://nf-co.re/). + + Questi corsi aiutano a passare dai fondamenti di Nextflow alle best practice di nf-core. + Comprenda come e perché la community nf-core costruisce le pipeline, e come contribuire e riutilizzare queste tecniche. + + ??? courses "**Hello nf-core:** Inizia con nf-core" + + Per gli sviluppatori che desiderano imparare a eseguire e sviluppare pipeline conformi a [nf-core](https://nf-co.re/). Il corso copre la struttura delle pipeline nf-core con sufficiente dettaglio per consentire lo sviluppo di pipeline semplici ma pienamente funzionali che seguono il template nf-core e le best practice di sviluppo, oltre all'utilizzo dei moduli nf-core esistenti. + + [Inizia la formazione Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Formazione Nextflow Avanzata {.mt-1} + + Impara concetti e meccanismi avanzati per sviluppare e distribuire pipeline Nextflow per affrontare casi d'uso reali. + + ??? courses "**Side Quests:** Approfondimenti su argomenti specifici" + + Mini-corsi indipendenti pensati per sviluppatori Nextflow che desiderano ampliare il proprio raggio d'azione e/o approfondire le proprie competenze su argomenti particolari. Sono presentati in modo lineare ma possono essere seguiti in qualsiasi ordine (vedere le dipendenze nella panoramica di ogni mini-corso). + + [Esplora le Side Quests :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Training Collections:** Percorsi di apprendimento consigliati attraverso le Side Quests" + + Le Training Collections combinano più Side Quests per fornire un'esperienza di apprendimento completa su un tema o caso d'uso particolare. + + [Esplora le Training Collections :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Cerchi materiali formativi archiviati?" + + I materiali formativi più vecchi (Fundamentals Training, Advanced Training e altri corsi sperimentali) sono stati rimossi dal portale di formazione in quanto incompatibili con la sintassi strict di Nextflow 3.0. + Se hai bisogno di accedere a questi materiali, sono disponibili nella [cronologia git](https://github.com/nextflow-io/training) prima di gennaio 2026. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/it/docs/info/conventions.md b/docs/it/docs/info/conventions.md new file mode 100644 index 0000000000..49782ffee6 --- /dev/null +++ b/docs/it/docs/info/conventions.md @@ -0,0 +1,3 @@ +<!-- Posizione temporanea per note specifiche che dovranno essere generalizzate --> + +Utilizziamo il prefisso `ch_` per tutte le variabili channel per indicare chiaramente che sono channel Nextflow. diff --git a/docs/it/docs/info/hello_pipeline.md b/docs/it/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..ad678b6973 --- /dev/null +++ b/docs/it/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: La pipeline Hello +description: Riepilogo di cosa fa la pipeline Hello e come è strutturata. +hide: + - toc + - footer +--- + +# La pipeline Hello + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +La maggior parte dei nostri corsi di formazione utilizza una semplice pipeline agnostica rispetto al dominio per dimostrare i concetti e i meccanismi di Nextflow. +Il corso Hello Nextflow mostra come sviluppare questa pipeline passo dopo passo, spiegando ogni decisione di progettazione e implementazione. +Altri corsi di formazione utilizzano questa pipeline, o parti di essa, come punto di partenza. + +Questa pagina riassume lo stato della pipeline al completamento del corso Hello Nextflow. + +### Descrizione di riepilogo + +Il workflow Hello prende un file CSV contenente saluti, li scrive in file separati, converte ciascuno in maiuscolo, li raccoglie nuovamente insieme e produce un singolo file di testo contenente un'immagine ASCII di un personaggio divertente che pronuncia i saluti. + +### Passaggi del workflow (process) + +I quattro passaggi sono implementati come process Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) memorizzati in file modulo separati. + +1. **`sayHello`:** Scrive ogni saluto nel proprio file di output (es. "Hello-output.txt") +2. **`convertToUpper`:** Converte ogni saluto in maiuscolo (es. "HELLO") +3. **`collectGreetings`:** Raccoglie tutti i saluti in maiuscolo in un singolo file batch +4. **`cowpy`:** Genera arte ASCII utilizzando lo strumento `cowpy` + +### Diagramma + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Risultati + +I risultati vengono pubblicati in una directory chiamata `results/`, e l'output finale della pipeline (quando eseguita con i parametri predefiniti) è un file di testo semplice contenente arte ASCII di un tacchino che pronuncia i saluti in maiuscolo. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Potrebbe incontrare alcune variazioni nei dettagli a seconda del corso in cui la pipeline è presente. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/it/docs/info/nxf_versions.md b/docs/it/docs/info/nxf_versions.md new file mode 100644 index 0000000000..a9b2ab7185 --- /dev/null +++ b/docs/it/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Versioni di Nextflow +description: Comprendere e gestire l'evoluzione delle versioni della sintassi di Nextflow +hide: + - toc + - footer +--- + +## Versione attuale della sintassi Nextflow supportata e requisiti + +A partire dalla versione 3.0 del portale di formazione, tutti i nostri corsi di formazione sono basati sulla versione 25.10.2 di Nextflow, salvo diversa indicazione nella pagina indice del corso (ad eccezione dei materiali deprecati o archiviati che potrebbero non includere un avviso di versione). + +Poiché i corsi ora utilizzano input tipizzati a livello di workflow così come direttive di output a livello di workflow, richiedono l'uso del parser di sintassi V2. +Se prevede di utilizzare l'ambiente che forniamo attraverso [Github Codespaces](../envsetup/01_setup.md) o [devcontainer locali](../envsetup/03_devcontainer.md), non è necessario fare nulla a meno che non sia specificatamente indicato nelle istruzioni del corso. +Tuttavia, se prevede di seguire le formazioni nel proprio ambiente ([Installazione manuale](../envsetup/02_local.md)), dovrà assicurarsi di utilizzare Nextflow versione 25.10.2 o successiva con il parser di sintassi v2 abilitato. + +## Versioni precedenti dei materiali di formazione + +I nostri materiali di formazione sono versionati da febbraio 2025. + +Può accedere alle versioni precedenti dei materiali di formazione che funzionano con versioni di Nextflow **precedenti alla 25.10.2** tramite il menu a discesa in cima a ogni pagina che mostra la versione numerata dei materiali di formazione. +Quando seleziona una versione precedente dei materiali di formazione, i link all'ambiente di formazione specificheranno automaticamente la versione corrispondente dell'ambiente. + +## Altre informazioni sulle versioni della sintassi Nextflow + +Nextflow ha due concetti di versionamento distinti che vengono talvolta confusi: **versioni DSL** e **versioni del parser di sintassi**. + +**DSL1 vs DSL2** si riferisce a modi fondamentalmente diversi di scrivere pipeline Nextflow. +DSL1 era la sintassi originale dove i process erano implicitamente connessi attraverso i channel. +DSL2, introdotto in Nextflow 20.07, ha aggiunto funzionalità di modularità: la capacità di importare process e workflow da altri file, blocchi `workflow` espliciti e output dei process nominati. +DSL1 è stato deprecato in Nextflow 22.03 e rimosso in 22.12. +Tutto il codice Nextflow moderno utilizza DSL2. + +**Parser di sintassi v1 vs v2** si riferisce a parser diversi che funzionano entrambi con codice DSL2. +Il parser v1 è quello originale, più permissivo. +Il parser v2 è più rigoroso e abilita nuove funzionalità del linguaggio come la tipizzazione statica (input e output tipizzati) e direttive di output a livello di workflow. +Il parser v2 fornisce anche messaggi di errore migliori e rileva più errori in fase di parsing piuttosto che a runtime. +Il parser v2 diventerà predefinito in Nextflow 26.04. + +In sintesi: DSL2 è il linguaggio che si scrive; la versione del parser di sintassi determina con quanta rigidità viene interpretato quel linguaggio e quali funzionalità avanzate sono disponibili. + +### Controllare e impostare la versione di Nextflow + +Può verificare quale versione di Nextflow è installata sul sistema utilizzando il comando `nextflow --version`. + +Per maggiori informazioni su come aggiornare la versione di Nextflow, consulti la documentazione di riferimento su [Aggiornamento di Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Abilitare il parser di sintassi v2 + +Per **abilitare** il parser di sintassi v2 per la sessione corrente, eseguite il seguente comando nel terminale: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Per rendere questa impostazione permanente (in attesa che v2 diventi predefinito in Nextflow 26.04), aggiunga il comando export al profilo della shell (`~/.bashrc`, `~/.zshrc`, ecc.): + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Si noti che la variabile d'ambiente `NXF_SYNTAX_PARSER=v2` è un requisito temporaneo. +Da Nextflow 26.04 in poi, il parser v2 diventerà predefinito e questa impostazione non sarà più necessaria. + +### Disabilitare il parser di sintassi v2 + +Per **disabilitare** il parser di sintassi v2 per la sessione corrente, eseguite il seguente comando nel terminale: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migrazione del codice esistente + +Per una guida sulla migrazione del codice esistente per conformarsi alle versioni più recenti di Nextflow, consulti le [Note di migrazione](https://www.nextflow.io/docs/latest/migrations/index.html) nella documentazione di riferimento. + +Questi due articoli sono particolarmente utili per la migrazione alla release più recente: + +- [Migrazione agli output del workflow](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrazione ai tipi statici](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Entrambe queste funzionalità sono trattate come parte della formazione per principianti a partire dalla versione 3.0 dei materiali di formazione. + +A seconda della generazione di codice Nextflow che intende migrare, potrebbe essere in grado di completare la maggior parte del lavoro tramite il linter di Nextflow utilizzando il comando `nextflow lint -format`. +Consulti il riferimento CLI per [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) per maggiori dettagli. + +Speriamo che questo sia utile. +Se avete bisogno di aiuto, ci contatti su Slack o sul forum. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/it/docs/nextflow_run/00_orientation.md b/docs/it/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..a0d2a81c17 --- /dev/null +++ b/docs/it/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Per iniziare + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Avvia un ambiente di formazione + +Per utilizzare l'ambiente pre-costruito che forniamo su GitHub Codespaces, clicca sul pulsante "Open in GitHub Codespaces" qui sotto. Per altre opzioni, consulta [Opzioni di ambiente](../envsetup/index.md). + +Ti consigliamo di aprire l'ambiente di formazione in una nuova scheda o finestra del browser (usa clic destro, ctrl-clic o cmd-clic a seconda del tuo dispositivo) in modo da poter continuare a leggere mentre l'ambiente si carica. +Dovrai tenere queste istruzioni aperte in parallelo per seguire il corso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Nozioni base sull'ambiente + +Questo ambiente di formazione contiene tutto il software, il codice e i dati necessari per seguire il corso, quindi non devi installare nulla. + +Il codespace è configurato con un'interfaccia VSCode, che include un esploratore del filesystem, un editor di codice e un terminale shell. +Tutte le istruzioni fornite durante il corso (es. 'apri il file', 'modifica il codice' o 'esegui questo comando') si riferiscono a queste tre parti dell'interfaccia VSCode salvo diversa indicazione. + +Se stai seguendo questo corso da solo, ti preghiamo di familiarizzare con le [nozioni base sull'ambiente](../envsetup/01_setup.md) per ulteriori dettagli. + +### Requisiti di versione + +Questa formazione è progettata per Nextflow 25.10.2 o successivo **con il parser della sintassi v2 ABILITATO**. +Se stai usando un ambiente locale o personalizzato, assicurati di utilizzare le impostazioni corrette come documentato [qui](../info/nxf_versions.md). + +## Preparati al lavoro + +Una volta che il tuo codespace è in esecuzione, ci sono due cose da fare prima di immergerti nella formazione: impostare la directory di lavoro per questo corso specifico e dare un'occhiata ai materiali forniti. + +### Imposta la directory di lavoro + +Per impostazione predefinita, il codespace si apre con la directory di lavoro impostata alla radice di tutti i corsi di formazione, ma per questo corso lavoreremo nella directory `nextflow-run/`. + +Cambia directory ora eseguendo questo comando nel terminale: + +```bash +cd nextflow-run/ +``` + +Puoi impostare VSCode per concentrarsi su questa directory, in modo che solo i file rilevanti vengano mostrati nella barra laterale dell'esploratore file: + +```bash +code . +``` + +!!! tip "Suggerimento" + + Se per qualsiasi motivo esci da questa directory (es. il tuo codespace va in sospensione), puoi sempre usare il percorso completo per tornare, assumendo che tu stia eseguendo questo all'interno dell'ambiente di formazione di Github Codespaces: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Ora diamo un'occhiata ai contenuti. + +### Esplora i materiali forniti + +Puoi esplorare i contenuti di questa directory usando l'esploratore file sul lato sinistro dello spazio di lavoro di formazione. +In alternativa, puoi usare il comando `tree`. + +Durante il corso, usiamo l'output di `tree` per rappresentare la struttura e i contenuti delle directory in forma leggibile, a volte con modifiche minori per chiarezza. + +Qui generiamo un indice dei contenuti fino al secondo livello: + +```bash +tree . -L 2 +``` + +??? abstract "Contenuti della directory" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Clicca sulla casella colorata per espandere la sezione e visualizzarne i contenuti. +Usiamo sezioni espandibili come questa per mostrare in modo conciso l'output dei comandi previsto e i contenuti di directory e file. + +- **I file `.nf`** sono script di workflow numerati in base alla parte del corso in cui vengono utilizzati. + +- **Il file `nextflow.config`** è un file di configurazione che imposta proprietà minime dell'ambiente. + Puoi ignorarlo per ora. + +- **Il file `greetings.csv`** sotto `data/` contiene i dati di input che useremo nella maggior parte del corso. Viene descritto nella Parte 2 (Eseguire pipeline), quando lo introduciamo per la prima volta. + +- **I file `test-params.*`** sono file di configurazione che useremo nella Parte 3 (Configurazione). Puoi ignorarli per ora. + +- **La directory `solutions`** contiene lo stato finale del workflow e dei suoi file accessori (config e moduli) che risultano dal completamento del corso. + Sono pensati per essere usati come riferimento per controllare il tuo lavoro e risolvere eventuali problemi. + +## Checklist di preparazione + +Pensi di essere pronto a iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio ambiente è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato + +Se puoi spuntare tutte le caselle, sei pronto per partire. + +**Per continuare alla [Parte 1: Operazioni base](./01_basics.md), clicca sulla freccia nell'angolo in basso a destra di questa pagina.** diff --git a/docs/it/docs/nextflow_run/01_basics.md b/docs/it/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..6fb87645f4 --- /dev/null +++ b/docs/it/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Parte 1: Operazioni base + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa prima parte del corso di formazione Nextflow Run, ci introduciamo all'argomento con un esempio Hello World molto basilare e indipendente dal dominio, che useremo per dimostrare le operazioni essenziali e indicare i corrispondenti componenti del codice Nextflow. + +??? info "Cos'è un esempio Hello World?" + + Un "Hello World!" è un esempio minimalista pensato per dimostrare la sintassi base e la struttura di un linguaggio di programmazione o framework software. + L'esempio tipicamente consiste nello stampare la frase "Hello, World!" sul dispositivo di output, come la console o il terminale, o nello scriverla su un file. + +--- + +## 1. Esegui un Hello World direttamente + +Dimostriamo questo concetto con un semplice comando che eseguiamo direttamente nel terminale, per mostrare cosa fa prima di incapsularlo in Nextflow. + +!!! tip "Suggerimento" + + Ricorda che dovresti ora trovarti all'interno della directory `nextflow-run/` come descritto nella pagina [Per iniziare](00_orientation.md). + +### 1.1. Fai dire hello al terminale + +Esegui il seguente comando nel tuo terminale. + +```bash +echo 'Hello World!' +``` + +??? success "Output del comando" + + ```console + Hello World! + ``` + +Questo stampa il testo 'Hello World' proprio lì nel terminale. + +### 1.2. Scrivi l'output su un file + +Eseguire pipeline comporta principalmente la lettura di dati da file e la scrittura di risultati su altri file, quindi modifichiamo il comando per scrivere l'output di testo su un file per rendere l'esempio un po' più rilevante. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Output del comando" + + ```console + + ``` + +Questo non stampa nulla nel terminale. + +### 1.3. Trova l'output + +Il testo 'Hello World' dovrebbe ora essere nel file di output che abbiamo specificato, chiamato `output.txt`. +Puoi aprirlo nell'esploratore file o dalla riga di comando usando l'utility `cat`, per esempio. + +??? abstract "Contenuto del file" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Questo è ciò che cercheremo di replicare con il nostro primo workflow Nextflow. + +### Riepilogo + +Ora sai come eseguire un semplice comando nel terminale che produce del testo, e opzionalmente, come fargli scrivere l'output su un file. + +### Cosa c'è dopo? + +Scopri cosa serve per eseguire un workflow Nextflow che ottiene lo stesso risultato. + +--- + +## 2. Esegui il workflow + +Ti forniamo uno script di workflow chiamato `1-hello.nf` che prende un saluto in input tramite un argomento da riga di comando chiamato `--input` e produce un file di testo contenente quel saluto. + +Non guarderemo ancora il codice; prima vediamo come appare eseguirlo. + +### 2.1. Avvia il workflow e monitora l'esecuzione + +Nel terminale, esegui il seguente comando: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Output del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Se l'output della tua console appare più o meno così, congratulazioni, hai appena eseguito il tuo primo workflow Nextflow! + +L'output più importante qui è l'ultima riga, che è evidenziata nell'output sopra: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Questo ci dice che il process `sayHello` è stato eseguito con successo una volta (`1 of 1 ✔`). + +Ottimo, ma potresti chiederti: dov'è l'output? + +### 2.2. Trova il file di output nella directory `results` + +Questo workflow è configurato per pubblicare il suo output in una directory dei risultati. +Se guardi la tua directory corrente, vedrai che quando hai eseguito il workflow, Nextflow ha creato una nuova directory chiamata `results`, oltre a una sottodirectory chiamata `1-hello` sotto di essa, contenente un file chiamato `output.txt`. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Apri il file; il contenuto dovrebbe corrispondere alla stringa che hai specificato nella riga di comando. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +Ottimo, il nostro workflow ha fatto ciò che doveva fare! + +Tuttavia, tieni presente che il risultato 'pubblicato' è una copia (o in alcuni casi un link simbolico) dell'output effettivo prodotto da Nextflow quando ha eseguito il workflow. + +Quindi ora daremo un'occhiata sotto il cofano per vedere dove Nextflow ha effettivamente eseguito il lavoro. + +!!! Warning "Avviso" + + Non tutti i workflow saranno configurati per pubblicare output in una directory dei risultati, e/o i nomi delle directory e la struttura potrebbero essere diversi. + Un po' più avanti in questa sezione, ti mostreremo come scoprire dove questo comportamento viene specificato. + +### 2.3. Trova l'output originale e i log nella directory `work/` + +Quando esegui un workflow, Nextflow crea una distinta 'directory di attività' per ogni singola invocazione di ogni process nel workflow (=ogni step nella pipeline). +Per ciascuna, metterà in staging gli input necessari, eseguirà le istruzioni rilevanti e scriverà output e file di log all'interno di quella singola directory, che viene nominata automaticamente usando un hash per renderla unica. + +Tutte queste directory di attività risiederanno sotto una directory chiamata `work` nella tua directory corrente (dove stai eseguendo il comando). + +Potrebbe sembrare confuso, quindi vediamo come appare in pratica. + +Tornando all'output della console per il workflow che abbiamo eseguito prima, avevamo questa riga: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Vedi come la riga inizia con `[a3/7be2fa]`? +Questa è una forma troncata del percorso della directory di attività per quella chiamata di process, e ti dice dove trovare l'output della chiamata al process `sayHello` all'interno del percorso della directory `work/`. + +Puoi trovare il percorso completo digitando il seguente comando (sostituendo `a3/7be2fa` con quello che vedi nel tuo terminale) e premendo il tasto tab per l'autocompletamento del percorso o aggiungendo un asterisco: + +```bash +ls work/a3/7be2fa* +``` + +Questo dovrebbe produrre il percorso completo della directory: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Diamo un'occhiata a cosa c'è dentro. + +??? abstract "Contenuti della directory" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Non vedi la stessa cosa?" + + I nomi esatti delle sottodirectory saranno diversi sul tuo sistema. + + Se esplori i contenuti della sottodirectory di attività nell'esploratore file di VSCode, vedrai tutti i file subito. + Tuttavia, i file di log sono impostati per essere invisibili nel terminale, quindi se vuoi usare `ls` o `tree` per visualizzarli, dovrai impostare l'opzione rilevante per mostrare i file invisibili. + + ```bash + tree -a work + ``` + +Dovresti riconoscere immediatamente il file `output.txt`, che è infatti l'output originale del process `sayHello` che è stato pubblicato nella directory `results`. +Se lo apri, troverai di nuovo il saluto `Hello World!`. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +E tutti quegli altri file? + +Questi sono i file helper e di log che Nextflow ha scritto come parte dell'esecuzione dell'attività: + +- **`.command.begin`**: File sentinella creato non appena l'attività viene lanciata. +- **`.command.err`**: Messaggi di errore (`stderr`) emessi dalla chiamata del process +- **`.command.log`**: Output di log completo emesso dalla chiamata del process +- **`.command.out`**: Output regolare (`stdout`) della chiamata del process +- **`.command.run`**: Script completo eseguito da Nextflow per eseguire la chiamata del process +- **`.command.sh`**: Il comando che è stato effettivamente eseguito dalla chiamata del process +- **`.exitcode`**: Il codice di uscita risultante dal comando + +Il file `.command.sh` è particolarmente utile perché ti mostra il comando principale che Nextflow ha eseguito, non includendo tutta la gestione e il setup dell'attività/ambiente. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Quindi questo conferma che il workflow ha composto lo stesso comando che abbiamo eseguito direttamente sulla riga di comando prima. + +Quando qualcosa va storto e devi risolvere il problema, può essere utile guardare lo script `command.sh` per controllare esattamente quale comando Nextflow ha composto in base alle istruzioni del workflow, all'interpolazione delle variabili e così via. + +### 2.4. Riesegui il workflow con saluti diversi + +Prova a rieseguire il workflow alcune volte con valori diversi per l'argomento `--input`, poi guarda le directory di attività. + +??? abstract "Contenuti della directory" + + ```console + 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 + ``` + +Vedi che una nuova sottodirectory con un set completo di file di output e log è stata creata per ogni esecuzione. + +Al contrario, se guardi la directory `results`, c'è ancora solo un set di risultati, e il contenuto del file di output corrisponde a qualunque cosa tu abbia eseguito per ultima. + +??? abstract "Contenuti della directory" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Questo ti mostra che i risultati pubblicati verranno sovrascritti dalle esecuzioni successive, mentre le directory di attività sotto `work/` vengono preservate. + +### Riepilogo + +Sai come eseguire un semplice script Nextflow, monitorare la sua esecuzione e trovare i suoi output. + +### Cosa c'è dopo? + +Impara a leggere uno script Nextflow base e identificare come i suoi componenti si relazionano alla sua funzionalità. + +--- + +## 3. Esamina lo script starter del workflow Hello World + +Ciò che abbiamo fatto finora era trattare lo script del workflow come una scatola nera. +Ora che abbiamo visto cosa fa, apriamo la scatola e guardiamo dentro. + +Il nostro obiettivo qui non è memorizzare la sintassi del codice Nextflow, ma formare un'intuizione di base su quali sono i componenti principali e come sono organizzati. + +### 3.1. Esamina la struttura generale del codice + +Troverai lo script `1-hello.nf` nella tua directory corrente, che dovrebbe essere `nextflow-run`. Aprilo nel pannello dell'editor. + +??? full-code "File di codice completo" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parameters + */ + params { + input: String + } + + workflow { + + main: + // emette un saluto + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Uno script di workflow Nextflow tipicamente include una o più definizioni di **process**, il **workflow** stesso, e alcuni blocchi opzionali come **params** e **output**. + +Ogni **process** descrive quale/i operazione/i lo step corrispondente nella pipeline dovrebbe compiere, mentre il **workflow** descrive la logica del dataflow che connette i vari step. + +Diamo prima uno sguardo più da vicino al blocco **process**, poi guarderemo il blocco **workflow**. + +### 3.2. La definizione del `process` + +Il primo blocco di codice descrive un **process**. +La definizione del process inizia con la parola chiave `process`, seguita dal nome del process e infine dal corpo del process delimitato da parentesi graffe. +Il corpo del process deve contenere un blocco script che specifica il comando da eseguire, che può essere qualsiasi cosa tu possa eseguire in un terminale da riga di comando. + +```groovy title="1-hello.nf" linenums="3" +/* +* Use echo to print a greeting to a file +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Qui abbiamo un **process** chiamato `sayHello` che prende una variabile di **input** chiamata `greeting` e scrive il suo **output** in un file chiamato `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +Questa è una definizione di process molto minimale che contiene solo una definizione `input`, una definizione `output` e lo `script` da eseguire. + +La definizione `input` include il qualificatore `val`, che dice a Nextflow di aspettarsi un valore di qualche tipo (può essere una stringa, un numero, qualsiasi cosa). + +La definizione `output` include il qualificatore `path`, che dice a Nextflow che questo dovrebbe essere gestito come un percorso (include sia percorsi di directory che file). + +### 3.3. La definizione del `workflow` + +Il secondo blocco di codice descrive il **workflow** stesso. +La definizione del workflow inizia con la parola chiave `workflow`, seguita da un nome opzionale, poi il corpo del workflow delimitato da parentesi graffe. + +Qui abbiamo un **workflow** che consiste in un blocco `main:` e un blocco `publish:`. +Il blocco `main:` è il corpo principale del workflow e il blocco `publish:` elenca gli output che dovrebbero essere pubblicati nella directory `results`. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // emette un saluto + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +In questo caso il blocco `main:` contiene una chiamata al process `sayHello` e gli fornisce un input chiamato `params.input` da usare come saluto. + +Come discuteremo più in dettaglio tra un momento, `params.input` contiene il valore che abbiamo dato al parametro `--input` nella nostra riga di comando. + +Il blocco `publish:` elenca l'output della chiamata al process `sayHello()`, a cui si riferisce come `sayHello.out` e dà il nome `first_output` (questo può essere qualsiasi cosa l'autore del workflow voglia). + +Questa è una definizione di **workflow** molto minimale. +In una pipeline del mondo reale, il workflow tipicamente contiene chiamate multiple a **processes** connessi da **channels**, e potrebbero esserci valori predefiniti impostati per gli input variabili. + +Approfondiremo questo nella Parte 2 del corso. +Per ora, diamo uno sguardo più da vicino a come il nostro workflow gestisce input e output. + +### 3.4. Il sistema `params` per i parametri da riga di comando + +Il `params.input` che forniamo alla chiamata del process `sayHello()` è un utile pezzo di codice Nextflow e vale la pena spendere un minuto in più. + +Come menzionato sopra, è così che passiamo il valore del parametro da riga di comando `--input` alla chiamata del process `sayHello()`. +In realtà, semplicemente dichiarare `params.someParameterName` è sufficiente per dare al workflow un parametro chiamato `--someParameterName` dalla riga di comando. + +Qui abbiamo formalizzato quella dichiarazione di parametro impostando un blocco `params` che specifica il tipo di input che il workflow si aspetta (Nextflow 25.10.2 e successivi). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +I tipi supportati includono `String`, `Integer`, `Float`, `Boolean` e `Path`. + +!!! tip "Suggerimento" + + I parametri del workflow dichiarati usando il sistema `params` prendono sempre due trattini nella riga di comando (`--`). + Questo li distingue dai parametri a livello di Nextflow, che prendono solo un trattino (`-`). + +### 3.5. La direttiva `publish` + +All'altra estremità del workflow, abbiamo già dato un'occhiata al blocco `publish:`. +Questa è una metà del sistema di gestione dell'output; l'altra metà è il blocco `output` situato sotto. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Questo specifica che l'output `first_output` elencato nel blocco `publish:` dovrebbe essere copiato in una sottodirectory chiamata `1-hello` sotto la directory di output predefinita `results`. + +La riga `mode 'copy'` sovrascrive il comportamento predefinito del sistema, che è di creare un link simbolico (o symlink) al file originale nella directory `work/` invece di una copia vera e propria. + +Ci sono più opzioni di quelle mostrate qui per controllare il comportamento di pubblicazione; ne copriremo alcune più avanti. +Vedrai anche che quando un workflow genera output multipli, ognuno viene elencato in questo modo nel blocco `output`. + +??? info "Sintassi precedente per pubblicare output usando `publishDir`" + + Fino a molto recentemente, il modo stabilito per pubblicare gli output era farlo a livello di ogni singolo process usando una direttiva `publishDir`. + + Troverai ancora questo pattern di codice ovunque nelle pipeline Nextflow più vecchie e nei moduli di process, quindi è importante esserne consapevoli. + + Invece di avere un blocco `publish:` nel workflow e un blocco `output` al livello superiore, vedresti una riga `publishDir` nella definizione del process `sayHello`: + + ```groovy title="Esempio di sintassi" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + Tuttavia, non raccomandiamo di usarlo in nessun nuovo lavoro poiché verrà eventualmente vietato nelle future versioni del linguaggio Nextflow. + +### Riepilogo + +Ora sai come è strutturato un semplice workflow Nextflow, e come i componenti base si relazionano alla sua funzionalità. + +### Cosa c'è dopo? + +Impara a gestire le esecuzioni del tuo workflow in modo conveniente. + +--- + +## 4. Gestisci le esecuzioni del workflow + +Sapere come lanciare workflow e recuperare output è ottimo, ma scoprirai presto che ci sono alcuni altri aspetti della gestione dei workflow che ti renderanno la vita più facile. + +Qui ti mostriamo come sfruttare la funzionalità `resume` per quando devi rilanciare lo stesso workflow, come ispezionare i log di esecuzione con `nextflow log`, e come eliminare le vecchie directory di lavoro con `nextflow clean`. + +### 4.1. Rilancia un workflow con `-resume` + +A volte, vorrai rieseguire una pipeline che hai già lanciato in precedenza senza rifare alcun lavoro che è già stato completato con successo. + +Nextflow ha un'opzione chiamata `-resume` che ti permette di farlo. +Specificamente, in questa modalità, tutti i process che sono già stati eseguiti con lo stesso identico codice, impostazioni e input verranno saltati. +Questo significa che Nextflow eseguirà solo i process che hai aggiunto o modificato dall'ultima esecuzione, o a cui stai fornendo nuove impostazioni o input. + +Ci sono due vantaggi chiave nel farlo: + +- Se sei nel mezzo dello sviluppo di una pipeline, puoi iterare più rapidamente poiché devi eseguire solo il/i process su cui stai attivamente lavorando per testare le tue modifiche. +- Se stai eseguendo una pipeline in produzione e qualcosa va storto, in molti casi puoi risolvere il problema e rilanciare la pipeline, e riprenderà l'esecuzione dal punto di fallimento, il che può farti risparmiare molto tempo e calcolo. + +Per usarlo, aggiungi semplicemente `-resume` al tuo comando ed eseguilo: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Output del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +L'output della console dovrebbe sembrare familiare, ma c'è una cosa che è un po' diversa rispetto a prima. + +Cerca la parte `cached:` che è stata aggiunta nella riga di stato del process (riga 5), il che significa che Nextflow ha riconosciuto che ha già fatto questo lavoro e ha semplicemente riutilizzato il risultato dell'esecuzione precedente riuscita. + +Puoi anche vedere che l'hash della sottodirectory di lavoro è lo stesso dell'esecuzione precedente. +Nextflow ti sta letteralmente indicando l'esecuzione precedente e dicendo "L'ho già fatto laggiù." + +!!! tip "Suggerimento" + + Quando riesegui una pipeline con `resume`, Nextflow non sovrascrive alcun file pubblicato al di fuori della directory di lavoro da esecuzioni che sono state eseguite con successo in precedenza. + +### 4.2. Ispeziona il log delle esecuzioni passate + +Ogni volta che lanci un workflow nextflow, una riga viene scritta in un file di log chiamato `history`, sotto una directory nascosta chiamata `.nextflow` nella directory di lavoro corrente. + +??? abstract "Contenuto del file" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Questo file ti dà il timestamp, il nome dell'esecuzione, lo stato, l'ID di revisione, l'ID di sessione e la riga di comando completa per ogni esecuzione Nextflow che è stata lanciata dalla directory di lavoro corrente. + +Un modo più conveniente per accedere a queste informazioni è usare il comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Output del comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Questo stamperà i contenuti del file di log nel terminale, arricchiti con una riga di intestazione. + +Noterai che l'ID di sessione cambia ogni volta che esegui un nuovo comando `nextflow run`, TRANNE se stai usando l'opzione `-resume`. +In quel caso, l'ID di sessione rimane lo stesso. + +Nextflow usa l'ID di sessione per raggruppare le informazioni di caching dell'esecuzione sotto la directory `cache`, anch'essa situata sotto `.nextflow`. + +### 4.3. Elimina le vecchie directory di lavoro + +Se esegui molte pipeline, potresti finire per accumulare moltissimi file in molte sottodirectory. +Poiché le sottodirectory sono nominate casualmente, è difficile capire dai loro nomi quali sono esecuzioni più vecchie vs. più recenti. + +Fortunatamente Nextflow include un utile sottocomando `clean` che può automaticamente eliminare le sottodirectory di lavoro per le esecuzioni passate che non ti interessano più. + +#### 4.3.1. Determina i criteri di eliminazione + +Ci sono molteplici [opzioni](https://www.nextflow.io/docs/latest/reference/cli.html#clean) per determinare cosa eliminare. + +Qui ti mostriamo un esempio che elimina tutte le sottodirectory dalle esecuzioni prima di una data esecuzione, specificata usando il suo nome di esecuzione. + +Cerca l'esecuzione riuscita più recente dove non hai usato `-resume`; nel nostro caso il nome dell'esecuzione era `backstabbing_swartz`. + +Il nome dell'esecuzione è la stringa in due parti generata automaticamente mostrata tra parentesi quadre nell'output della console nella riga `Launching (...)`. +Puoi anche usare il log di Nextflow per cercare un'esecuzione in base al suo timestamp e/o riga di comando. + +#### 4.3.2. Fai un'esecuzione di prova + +Prima usiamo il flag dry run `-n` per controllare cosa verrà eliminato dato il comando: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Output del comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Il tuo output avrà nomi di directory di attività diversi e potrebbe avere un numero diverso di righe, ma dovrebbe apparire simile all'esempio. + +Se non vedi righe nell'output, o non hai fornito un nome di esecuzione valido o non ci sono esecuzioni passate da eliminare. Assicurati di cambiare `backstabbing_swartz` nel comando di esempio con qualsiasi sia il nome dell'esecuzione più recente corrispondente nel tuo log. + +#### 4.3.3. Procedi con l'eliminazione + +Se l'output sembra come previsto e vuoi procedere con l'eliminazione, riesegui il comando con il flag `-f` invece di `-n`: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Output del comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +L'output dovrebbe essere simile a prima, ma ora dicendo 'Removed' invece di 'Would remove'. +Nota che questo non rimuove le sottodirectory di due caratteri (come `eb/` sopra) ma ne svuota i contenuti. + +!!! Warning "Avviso" + + Eliminare le sottodirectory di lavoro dalle esecuzioni passate le rimuove dalla cache di Nextflow ed elimina tutti gli output che erano memorizzati in quelle directory. + Questo significa che rompe la capacità di Nextflow di riprendere l'esecuzione senza rieseguire i process corrispondenti. + + Sei responsabile di salvare tutti gli output a cui tieni! Questo è il motivo principale per cui preferiamo usare la modalità `copy` piuttosto che la modalità `symlink` per la direttiva `publish`. + +### Riepilogo + +Sai come rilanciare una pipeline senza ripetere step che sono già stati eseguiti in modo identico, ispezionare il log di esecuzione, e usare il comando `nextflow clean` per pulire le vecchie directory di lavoro. + +### Cosa c'è dopo? + +Prenditi una piccola pausa! Hai appena assorbito i blocchi costitutivi della sintassi Nextflow e le istruzioni di utilizzo base. + +Nella prossima sezione di questa formazione, guarderemo quattro versioni successivamente più realistiche della pipeline Hello World che dimostreranno come Nextflow ti permette di elaborare input multipli efficientemente, eseguire workflow composti da step multipli connessi insieme, sfruttare componenti di codice modulari, e utilizzare container per una maggiore riproducibilità e portabilità. + +--- + +## Quiz + +<quiz> +Nella riga di output della console `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`, cosa rappresenta `[a3/7be2fa]`? +- [ ] Il numero di versione del process +- [ ] Un identificatore univoco dell'esecuzione +- [x] Il percorso troncato alla directory di lavoro dell'attività +- [ ] Il checksum del file di output + +Approfondisci: [2.3. Trova l'output originale e i log nella directory `work/`](#23-trova-loutput-originale-e-i-log-nella-directory-work) +</quiz> + +<quiz> +Qual è lo scopo del file `.command.sh` in una directory di attività? +- [ ] Memorizza le impostazioni di configurazione dell'attività +- [x] Mostra il comando effettivo che è stato eseguito dal process +- [ ] Contiene messaggi di errore dalle attività fallite +- [ ] Elenca i file di input messi in staging per l'attività + +Approfondisci: [2.3. Trova l'output originale e i log nella directory `work/`](#23-trova-loutput-originale-e-i-log-nella-directory-work) +</quiz> + +<quiz> +Cosa succede ai risultati pubblicati quando riesegui un workflow senza `-resume`? +- [ ] Vengono preservati in directory separate con timestamp +- [x] Vengono sovrascritti dalla nuova esecuzione +- [ ] Nextflow previene la sovrascrittura e fallisce +- [ ] Vengono automaticamente backed up + +Approfondisci: [2.4. Riesegui il workflow con saluti diversi](#24-riesegui-il-workflow-con-saluti-diversi) +</quiz> + +<quiz> +Cosa indica questo output della console? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] L'attività è fallita ed è stata saltata +- [ ] L'attività è in attesa in una coda +- [x] Nextflow ha riutilizzato i risultati di una precedente esecuzione identica +- [ ] L'attività è stata cancellata manualmente + +Approfondisci: [4.1. Rilancia un workflow con `-resume`](#41-rilancia-un-workflow-con--resume) +</quiz> + +<quiz> +Dove memorizza Nextflow la cronologia delle esecuzioni che il comando `nextflow log` visualizza? +- [ ] Nella directory results +- [ ] Nella directory work +- [x] Nel file `.nextflow/history` +- [ ] In `nextflow.config` + +Approfondisci: [4.2. Ispeziona il log delle esecuzioni passate](#42-ispeziona-il-log-delle-esecuzioni-passate) +</quiz> + +<quiz> +Qual è lo scopo del blocco `params` in un file di workflow? +- [ ] Definire i requisiti di risorse dei process +- [ ] Configurare l'executor +- [x] Dichiarare e tipizzare i parametri di input del workflow +- [ ] Specificare le opzioni di pubblicazione dell'output + +Approfondisci: [3.4. Il sistema params per i parametri da riga di comando](#34-il-sistema-params-per-i-parametri-da-riga-di-comando) +</quiz> + +<quiz> +Nel blocco `output` del workflow, cosa fa `mode 'copy'`? +- [ ] Crea un backup della directory di lavoro +- [x] Fa una copia completa dei file invece di link simbolici +- [ ] Copia lo script del workflow nei risultati +- [ ] Abilita la copia incrementale dei file + +Approfondisci: [3.5. La direttiva publish](#35-la-direttiva-publish) +</quiz> + +<quiz> +Qual è il flag raccomandato da usare con il comando `nextflow clean` prima di eliminare effettivamente i file? +- [x] `-n` (dry run) per vedere in anteprima cosa verrebbe eliminato +- [ ] `-v` (verbose) per vedere output dettagliato +- [ ] `-a` (all) per selezionare tutte le directory +- [ ] `-q` (quiet) per sopprimere gli avvisi + +Approfondisci: [4.3. Elimina le vecchie directory di lavoro](#43-elimina-le-vecchie-directory-di-lavoro) +</quiz> diff --git a/docs/it/docs/nextflow_run/02_pipeline.md b/docs/it/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..80a6669f45 --- /dev/null +++ b/docs/it/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1544 @@ +# Parte 2: Eseguire pipeline reali + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella Parte 1 di questo corso (Operazioni base), abbiamo iniziato con un workflow di esempio che aveva solo funzionalità minime per mantenere bassa la complessità del codice. +Per esempio, `1-hello.nf` usava un parametro da riga di comando (`--input`) per fornire un singolo valore alla volta. + +Tuttavia, la maggior parte delle pipeline del mondo reale usa funzionalità più sofisticate per consentire l'elaborazione efficiente di grandi quantità di dati su scala, e applicare step di elaborazione multipli concatenati insieme da logiche a volte complesse. + +In questa parte della formazione, dimostriamo le funzionalità chiave delle pipeline del mondo reale provando versioni espanse della pipeline Hello World originale. + +## 1. Elaborare dati di input da un file + +In una pipeline del mondo reale, tipicamente vogliamo elaborare punti dati multipli (o serie di dati) contenuti in uno o più file di input. +E dove possibile, vogliamo eseguire l'elaborazione di dati indipendenti in parallelo, per ridurre il tempo di attesa per l'analisi. + +Per dimostrare come Nextflow fa questo, abbiamo preparato un file CSV chiamato `greetings.csv` che contiene diversi saluti di input, simulando il tipo di dati in colonne che potresti voler elaborare in un'analisi dati reale. +Nota che i numeri non sono significativi, sono lì solo a scopo illustrativo. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Abbiamo anche scritto una versione migliorata del workflow originale, ora chiamata `2a-inputs.nf`, che leggerà il file CSV, estrarrà i saluti e scriverà ciascuno di essi in un file separato. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Eseguiamo prima il workflow, e poi daremo un'occhiata al codice Nextflow rilevante. + +### 1.1. Esegui il workflow + +Esegui il seguente comando nel tuo terminale. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Eccitante, questo sembra indicare che sono state fatte '3 of 3' chiamate per il process, il che è incoraggiante, dato che c'erano tre righe di dati nel CSV che abbiamo fornito come input. +Questo suggerisce che il process `sayHello()` è stato chiamato tre volte, una volta per ogni riga di input. + +### 1.2. Trova gli output pubblicati nella directory `results` + +Guardiamo la directory 'results' per vedere se il nostro workflow sta ancora scrivendo una copia dei nostri output lì. + +??? abstract "Contenuti della directory" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Sì! Vediamo una nuova directory chiamata `2a-inputs` con tre file di output con nomi diversi, convenientemente. + +Puoi aprire ciascuno di essi per verificare che contengano la stringa di saluto appropriata. + +??? abstract "Contenuto dei file" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Questo conferma che ogni saluto nel file di input è stato elaborato appropriatamente. + +### 1.3. Trova gli output originali e i log + +Potresti aver notato che l'output della console sopra si riferiva a una sola directory di attività. +Significa che tutte e tre le chiamate a `sayHello()` sono state eseguite all'interno di quella singola directory di attività? + +#### 1.3.1. Esamina la directory di attività data nel terminale + +Diamo un'occhiata dentro quella directory di attività `8e/0eb066`. + +??? abstract "Contenuti della directory" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Troviamo solo l'output corrispondente a uno dei saluti (così come i file accessori se abilitiamo la visualizzazione dei file nascosti). + +Quindi cosa sta succedendo? + +Per impostazione predefinita, il sistema di logging ANSI scrive le informazioni di stato per tutte le chiamate allo stesso process sulla stessa riga. +Di conseguenza, ci ha mostrato solo uno dei tre percorsi delle directory di attività (`8e/0eb066`) nell'output della console. +Ce ne sono altri due che non sono elencati lì. + +#### 1.3.2. Fai mostrare al terminale più dettagli + +Possiamo modificare il comportamento del logging per vedere la lista completa delle chiamate ai process aggiungendo `-ansi-log false` al comando come segue: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Output del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Questa volta vediamo tutti e tre i process eseguiti e le loro sottodirectory di lavoro associate elencate nell'output. +Disabilitare il logging ANSI ha anche impedito a Nextflow di usare i colori nell'output del terminale. + +Nota che il modo in cui viene riportato lo stato è un po' diverso tra le due modalità di logging. +Nella modalità condensata, Nextflow riporta se le chiamate sono state completate con successo o meno. +In questa modalità espansa, riporta solo che sono state sottomesse. + +Questo conferma che il process `sayHello()` viene chiamato tre volte, e una directory di attività separata viene creata per ciascuna. + +Se guardiamo dentro ciascuna delle directory di attività elencate lì, possiamo verificare che ognuna corrisponde a uno dei saluti. + +??? abstract "Contenuti della directory" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Questo conferma che ogni chiamata al process viene eseguita in isolamento da tutte le altre. +Questo ha molti vantaggi, incluso evitare collisioni se il process produce file intermedi con nomi non univoci. + +!!! tip "Suggerimento" + + Per un workflow complesso, o un grande numero di input, avere la lista completa stampata nel terminale potrebbe diventare un po' opprimente, quindi le persone normalmente non usano `-ansi-log false` nell'utilizzo di routine. + +### 1.4. Esamina il codice del workflow + +Quindi questa versione del workflow è capace di leggere un file CSV di input, elaborare gli input separatamente, e nominare gli output in modo univoco. + +Diamo un'occhiata a cosa rende questo possibile nel codice del workflow. + +??? full-code "File di codice completo" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + } + + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Ancora una volta, non devi memorizzare la sintassi del codice, ma è bene imparare a riconoscere i componenti chiave del workflow che forniscono funzionalità importanti. + +#### 1.4.1. Caricare i dati di input dal CSV + +Questa è la parte più interessante: come siamo passati dal prendere un singolo valore dalla riga di comando, al prendere un file CSV, analizzarlo ed elaborare i singoli saluti che contiene? + +In Nextflow, lo facciamo con un **channel**: un costrutto progettato per gestire gli input efficientemente e trasferirli da uno step all'altro in workflow multi-step, fornendo al contempo parallelismo integrato e molti altri benefici. + +Analizziamolo. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) +``` + +Questo codice crea un channel chiamato `greeting_ch` che legge il file CSV, lo analizza, e estrae la prima colonna da ogni riga. +Il risultato è un channel contenente `Hello`, `Bonjour`, e `Holà`. + +??? tip "Come funziona?" + + Ecco cosa significa quella riga in italiano semplice: + + - `channel.fromPath` è una **channel factory** che crea un channel da percorsi di file + - `(params.input)` specifica che il percorso del file è fornito da `--input` sulla riga di comando + + In altre parole, quella riga dice a Nextflow: prendi il percorso del file dato con `--input` e preparati a trattare i suoi contenuti come dati di input. + + Poi le due righe successive applicano **operatori** che fanno l'effettivo parsing del file e il caricamento dei dati nella struttura dati appropriata: + + - `.splitCsv()` dice a Nextflow di analizzare il file CSV in un array che rappresenta righe e colonne + - `.map { line -> line[0] }` dice a Nextflow di prendere solo l'elemento nella prima colonna da ogni riga + + Quindi in pratica, partendo dal seguente file CSV: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Abbiamo trasformato quello in un array che appare così: + + ```txt title="Contenuti dell'array" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + E poi abbiamo preso il primo elemento da ciascuna delle tre righe e li abbiamo caricati in un channel Nextflow che ora contiene: `Hello`, `Bonjour`, e `Holà`. + + Se vuoi capire i channel e gli operatori in profondità, incluso come scriverli tu stesso, vedi [Hello Nextflow Parte 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Chiama il process su ogni saluto + +Successivamente, nell'ultima riga del blocco `main:` del workflow, forniamo il channel `greeting_ch` caricato come input al process `sayHello()`. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) +``` + +Questo dice a Nextflow di eseguire il process individualmente su ogni elemento nel channel, _cioè_ su ogni saluto. +E poiché Nextflow è intelligente così, eseguirà queste chiamate al process in parallelo se possibile, a seconda dell'infrastruttura di calcolo disponibile. + +È così che puoi ottenere un'elaborazione efficiente e scalabile di molti dati (molti campioni, o punti dati, qualunque sia la tua unità di ricerca) con relativamente pochissimo codice. + +#### 1.4.3. Come vengono nominati gli output + +Infine, vale la pena dare una rapida occhiata al codice del process per vedere come facciamo a nominare i file di output in modo univoco. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Vedi che, rispetto alla versione di questo process in `1-hello.nf`, la dichiarazione dell'output e la parte rilevante del comando sono cambiate per includere il valore del saluto nel nome del file di output. + +Questo è un modo per assicurarsi che i nomi dei file di output non collideranno quando vengono pubblicati nella directory dei risultati comune. + +E questa è l'unica modifica che abbiamo dovuto fare dentro la dichiarazione del process! + +### Riepilogo + +Capisci a livello base come i channel e gli operatori ci permettono di elaborare input multipli efficientemente. + +### Cosa c'è dopo? + +Scopri come sono costruiti i workflow multi-step e come operano. + +--- + +## 2. Eseguire workflow multi-step + +La maggior parte dei workflow del mondo reale coinvolge più di uno step. +Costruiamo su ciò che abbiamo appena imparato sui channel, e guardiamo come Nextflow usa channel e operatori per connettere i process insieme in un workflow multi-step. + +A tal fine, ti forniamo un workflow di esempio che concatena tre step separati e dimostra quanto segue: + +1. Far fluire i dati da un process al successivo +2. Raccogliere output da chiamate multiple al process in una singola chiamata al process + +Specificamente, abbiamo fatto una versione espansa del workflow chiamata `2b-multistep.nf` che prende ogni saluto di input, lo converte in maiuscolo, poi raccoglie tutti i saluti maiuscoli in un singolo file di output. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Come in precedenza, eseguiremo prima il workflow poi guarderemo il codice per vedere cosa c'è di nuovo. + +### 2.1. Esegui il workflow + +Esegui il seguente comando nel tuo terminale: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Output del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Vedi che come promesso, step multipli sono stati eseguiti come parte del workflow; i primi due (`sayHello` e `convertToUpper`) sono stati presumibilmente eseguiti su ogni singolo saluto, e il terzo (`collectGreetings`) sarà stato eseguito solo una volta, sugli output di tutte e tre le chiamate di `convertToUpper`. + +### 2.2. Trova gli output + +Verifichiamo che sia effettivamente ciò che è successo dando un'occhiata nella directory `results`. + +??? abstract "Contenuti della directory" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Come puoi vedere, abbiamo una nuova directory chiamata `2b-multistep`, e contiene molti più file di prima. +Alcuni dei file sono stati raggruppati in una sottodirectory chiamata `intermediates`, mentre due file si trovano al livello superiore. + +Questi due sono i risultati finali del workflow multi-step. +Prenditi un minuto per guardare i nomi dei file e controllare i loro contenuti per confermare che sono ciò che ti aspetti. + +??? abstract "Contenuto dei file" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +Il primo contiene i nostri tre saluti, convertiti in maiuscolo e raccolti di nuovo in un singolo file come promesso. +Il secondo è un file di report che riassume alcune informazioni sull'esecuzione. + +### 2.3. Esamina il codice + +Guardiamo il codice e identifichiamo i pattern chiave per i workflow multi-step. + +??? full-code "File di codice completo" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Use a text replacement tool to convert the greeting to uppercase + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +C'è molto da vedere lì dentro, ma la differenza più ovvia rispetto alla versione precedente del workflow è che ora ci sono definizioni di process multiple, e corrispondentemente, diverse chiamate ai process nel blocco workflow. + +Diamo uno sguardo più da vicino e vediamo se possiamo identificare i pezzi più interessanti. + +#### 2.3.1. Visualizzare la struttura del workflow + +Se stai usando VSCode con l'estensione Nextflow, puoi ottenere un diagramma utile di come i process sono connessi cliccando sul piccolo link `DAG preview` visualizzato appena sopra il blocco workflow in qualsiasi script Nextflow. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Questo ti dà una bella panoramica di come i process sono connessi e cosa producono. + +Vedi che oltre al process originale `sayHello`, ora abbiamo anche `convertToUpper` e `collectGreetings`, che corrispondono ai nomi dei process che abbiamo visto nell'output della console. +Le due nuove definizioni di process sono strutturate nello stesso modo del process `sayHello`, tranne che `collectGreetings` prende un parametro di input aggiuntivo chiamato `batch` e produce due output. + +Non entreremo nel codice per ciascuno in dettaglio, ma se sei curioso, puoi cercare i dettagli nella [Parte 2 di Hello Nextflow](../hello_nextflow/03_hello_workflow.md). + +Per ora, approfondiamo come i process sono connessi l'uno all'altro. + +#### 2.3.2. Come sono connessi i process + +La cosa veramente interessante da guardare qui è come le chiamate ai process sono concatenate insieme nel blocco `main:` del workflow. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Puoi vedere che la prima chiamata al process, `sayHello(greeting_ch)`, è invariata. +Poi la chiamata successiva al process, a `convertToUpper`, si riferisce all'output di `sayHello` come `sayHello.out`. + +Il pattern è semplice: `processName.out` si riferisce al channel di output di un process, che può essere passato direttamente al process successivo. +È così che trasferiamo i dati da uno step al successivo in Nextflow. + +#### 2.3.3. Un process può prendere input multipli + +La terza chiamata al process, a `collectGreetings`, è un po' diversa. + +```groovy title="2b-multistep.nf" linenums="77" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Vedi che a questa chiamata vengono dati due input, `convertToUpper.out.collect()` e `params.batch`. +Ignorando la parte `.collect()` per ora, possiamo generalizzare questo come `collectGreetings(input1, input2)`. + +Questo corrisponde alle due dichiarazioni di input nel modulo del process: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Quando Nextflow analizza questo, assegnerà il primo input nella chiamata a `path input_files`, e il secondo a `val batch_name`. + +Quindi ora sai che un process può prendere input multipli, e come appare la chiamata nel blocco workflow. + +Ora diamo uno sguardo più da vicino a quel primo input, `convertToUpper.out.collect()`. + +#### 2.3.4. Cosa fa `collect()` nella chiamata `collectGreetings` + +Per passare l'output di `sayHello` a `convertToUpper`, abbiamo semplicemente fatto riferimento al channel di output di `sayHello` come `sayHello.out`. Ma per lo step successivo, stiamo vedendo un riferimento a `convertToUpper.out.collect()`. + +Cos'è questa parte `collect()` e cosa fa? + +È un operatore, naturalmente. Proprio come gli operatori `splitCsv` e `map` che abbiamo incontrato prima. +Questa volta l'operatore si chiama `collect`, ed è applicato al channel di output prodotto da `convertToUpper`. + +L'operatore `collect` è usato per raccogliere gli output da chiamate multiple allo stesso process e impacchettarli in un singolo elemento del channel. + +Nel contesto di questo workflow, sta prendendo i tre saluti maiuscoli nel channel `convertToUpper.out` --che sono tre elementi separati del channel, e normalmente verrebbero gestiti in chiamate separate dal process successivo-- e li impacchetta in un singolo elemento. + +In termini più pratici: se non applicassimo `collect()` all'output di `convertToUpper()` prima di passarlo a `collectGreetings()`, Nextflow eseguirebbe semplicemente `collectGreetings()` indipendentemente su ogni saluto, il che non raggiungerebbe il nostro obiettivo. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +Al contrario, usare `collect()` ci permette di prendere tutti i saluti maiuscoli separati prodotti dal secondo step del workflow e passarli tutti insieme a una singola chiamata nel terzo step della pipeline. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +È così che otteniamo tutti i saluti di nuovo nello stesso file. + +Ci sono molti altri [operatori](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) disponibili per applicare trasformazioni ai contenuti dei channel tra le chiamate ai process. + +Questo dà agli sviluppatori di pipeline molta flessibilità per personalizzare la logica di flusso della loro pipeline. +Il lato negativo è che a volte può rendere più difficile decifrare cosa sta facendo la pipeline. + +#### 2.3.5. Un parametro di input può avere un valore predefinito + +Potresti aver notato che `collectGreetings` prende un secondo input, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Questo passa un parametro CLI chiamato `--batch` al workflow. +Tuttavia, quando abbiamo lanciato il workflow prima, non abbiamo specificato un parametro `--batch`. + +Cosa sta succedendo? +Dai un'occhiata al blocco `params`: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +C'è un valore predefinito configurato nel workflow, quindi non dobbiamo fornirlo. +Ma se ne forniamo uno sulla riga di comando, il valore che specifichiamo verrà usato al posto di quello predefinito. + +Provalo: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Output del comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Dovresti vedere nuovi output finali nominati con il tuo nome batch personalizzato. + +??? abstract "Contenuti della directory" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Questo è un aspetto della configurazione degli input, che copriremo più in dettaglio nella Parte 3, ma per ora la cosa importante è sapere che i parametri di input possono avere valori predefiniti. + +#### 2.3.6. Un process può produrre output multipli + +Nella definizione del process `collectGreetings`, vediamo le seguenti dichiarazioni di output: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +A cui poi si fa riferimento con il nome dato con `emit:` nel blocco `publish:`: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Questo rende facile passare output specifici individualmente ad altri process nel workflow, in combinazione con vari operatori. + +#### 2.3.7. Gli output pubblicati possono essere organizzati + +Nel blocco `output`, abbiamo usato percorsi personalizzati per raggruppare i risultati intermedi in modo da rendere più facile individuare solo gli output finali del workflow. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Ci sono modi più sofisticati per organizzare gli output pubblicati; ne toccheremo alcuni nella parte sulla configurazione. + +!!! tip "Vuoi saperne di più sulla costruzione di workflow?" + + Per una copertura dettagliata sulla costruzione di workflow multi-step, vedi [Hello Nextflow Parte 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Riepilogo + +Capisci a livello base come i workflow multi-step sono costruiti usando channel e operatori e come operano. +Hai anche visto che i process possono prendere input multipli e produrre output multipli, e che questi possono essere pubblicati in modo strutturato. + +### Cosa c'è dopo? + +Impara come le pipeline Nextflow possono essere modularizzate per promuovere il riuso del codice e la manutenibilità. + +--- + +## 3. Eseguire pipeline modularizzate + +Finora, tutti i workflow che abbiamo guardato consistevano in un singolo file di workflow contenente tutto il codice rilevante. + +Tuttavia, le pipeline del mondo reale tipicamente beneficiano dall'essere _modularizzate_, il che significa che il codice è diviso in file diversi. +Questo può rendere il loro sviluppo e manutenzione più efficienti e sostenibili. + +Qui dimostreremo la forma più comune di modularità del codice in Nextflow, che è l'uso dei **moduli**. + +In Nextflow, un **modulo** è una singola definizione di process che è incapsulata da sola in un file di codice standalone. +Per usare un modulo in un workflow, aggiungi semplicemente una dichiarazione import di una riga al tuo file di codice del workflow; poi puoi integrare il process nel workflow nello stesso modo in cui lo faresti normalmente. +Questo rende possibile riutilizzare le definizioni dei process in workflow multipli senza produrre copie multiple del codice. + +Fino ad ora abbiamo eseguito workflow che avevano tutti i loro process inclusi in un file di codice monolitico. +Ora vedremo come appare quando i process sono memorizzati in moduli individuali. + +Abbiamo ovviamente preparato ancora una volta un workflow adatto per scopi dimostrativi, chiamato `2c-modules.nf`, insieme a un set di moduli situati nella directory `modules/`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Contenuti della directory" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Vedi che ci sono quattro file Nextflow, ciascuno nominato dopo uno dei process. +Puoi ignorare il file `cowpy.nf` per ora; ci arriveremo dopo. + +### 3.1. Esamina il codice + +Questa volta guarderemo prima il codice. +Inizia aprendo il file di workflow `2c-modules.nf`. + +??? full-code "File di codice completo" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Vedi che la logica del workflow è esattamente la stessa della versione precedente del workflow. +Tuttavia, il codice del process non c'è più nel file del workflow, e invece ci sono dichiarazioni `include` che puntano a file separati sotto `modules`. + +```groovy title="hello-modules.nf" linenums="3" +// Include i moduli +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Apri uno di quei file e troverai il codice per il process corrispondente. + +??? full-code "File di codice completo" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Come puoi vedere, il codice del process non è cambiato; è stato semplicemente copiato in un file modulo individuale invece di essere nel file del workflow principale. +Lo stesso vale per gli altri due process. + +Quindi vediamo come appare eseguire questa nuova versione. + +### 3.2. Esegui il workflow + +Esegui questo comando nel tuo terminale, con il flag `-resume`: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Noterai che le esecuzioni dei process sono state tutte salvate nella cache con successo, il che significa che Nextflow ha riconosciuto che ha già fatto il lavoro richiesto, anche se il codice è stato diviso e il file del workflow principale è stato rinominato. + +Niente di tutto ciò importa a Nextflow; ciò che importa è lo script del job che viene generato una volta che tutto il codice è stato messo insieme e valutato. + +!!! tip "Suggerimento" + + È anche possibile incapsulare una sezione di un workflow come un 'subworkflow' che può essere importato in una pipeline più grande, ma questo è al di fuori dello scopo di questo corso. + + Puoi saperne di più sullo sviluppo di workflow componibili nella Side Quest su [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/). + +### Riepilogo + +Sai come i process possono essere memorizzati in moduli standalone per promuovere il riuso del codice e migliorare la manutenibilità. + +### Cosa c'è dopo? + +Impara a usare i container per gestire le dipendenze software. + +--- + +## 4. Usare software containerizzato + +Finora i workflow che abbiamo usato come esempi avevano solo bisogno di eseguire operazioni di elaborazione di testo molto basilari usando strumenti UNIX disponibili nel nostro ambiente. + +Tuttavia, le pipeline del mondo reale tipicamente richiedono strumenti e pacchetti specializzati che non sono inclusi di default nella maggior parte degli ambienti. +Di solito, dovresti installare questi strumenti, gestire le loro dipendenze, e risolvere eventuali conflitti. + +Tutto questo è molto noioso e fastidioso. +Un modo molto migliore per affrontare questo problema è usare i **container**. + +Un **container** è un'unità software leggera, standalone ed eseguibile creata da un'**immagine** container che include tutto il necessario per eseguire un'applicazione incluso codice, librerie di sistema e impostazioni. + +!!! Tip "Suggerimento" + + Insegniamo questo usando la tecnologia [Docker](https://www.docker.com/get-started/), ma Nextflow supporta [diverse altre tecnologie container](https://www.nextflow.io/docs/latest/container.html#) altrettanto bene. + +### 4.1. Usa un container direttamente + +Prima, proviamo a interagire direttamente con un container. +Questo aiuterà a consolidare la tua comprensione di cosa sono i container prima di iniziare a usarli in Nextflow. + +#### 4.1.1. Scarica l'immagine container + +Per usare un container, di solito scarichi o "pulli" un'immagine container da un registry di container, e poi esegui l'immagine container per creare un'istanza del container. + +La sintassi generale è la seguente: + +```bash title="Sintassi" +docker pull '<container>' +``` + +- `docker pull` è l'istruzione al sistema container per scaricare un'immagine container da un repository. +- `'<container>'` è l'indirizzo URI dell'immagine container. + +Come esempio, scarichiamo un'immagine container che contiene [cowpy](https://github.com/jeffbuttars/cowpy), un'implementazione python di uno strumento chiamato `cowsay` che genera arte ASCII per visualizzare input di testo arbitrari in modo divertente. + +Ci sono vari repository dove puoi trovare container pubblicati. +Abbiamo usato il servizio [Seqera Containers](https://seqera.io/containers/) per generare questa immagine container Docker dal pacchetto Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Esegui il comando pull completo: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Output del comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Questo dice al sistema di scaricare l'immagine specificata. +Una volta completato il download, hai una copia locale dell'immagine container. + +#### 4.1.2. Avvia il container + +I container possono essere eseguiti come comando singolo, ma puoi anche usarli interattivamente, il che ti dà un prompt shell all'interno del container e ti permette di giocare con il comando. + +La sintassi generale è la seguente: + +```bash title="Sintassi" +docker run --rm '<container>' [comando dello strumento] +``` + +- `docker run --rm '<container>'` è l'istruzione al sistema container per avviare un'istanza del container da un'immagine container ed eseguire un comando al suo interno. +- `--rm` dice al sistema di spegnere l'istanza del container dopo che il comando è stato completato. + +Completamente assemblato, il comando di esecuzione del container appare così: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Esegui quel comando, e dovresti vedere il tuo prompt cambiare in qualcosa come `(base) root@b645838b3314:/tmp#`, che indica che sei ora dentro il container. + +Puoi verificare questo eseguendo `ls` per elencare i contenuti della directory: + +```bash +ls / +``` + +??? success "Output del comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Vedi che il filesystem dentro il container è diverso dal filesystem sul tuo sistema host. + +!!! Tip "Suggerimento" + + Quando esegui un container, è isolato dal sistema host di default. + Questo significa che il container non può accedere a nessun file sul sistema host a meno che tu non gli permetta esplicitamente di farlo specificando che vuoi montare un volume come parte del comando `docker run` usando la seguente sintassi: + + ```bash title="Sintassi" + -v <percorso_esterno>:<percorso_interno> + ``` + + Questo effettivamente stabilisce un tunnel attraverso la parete del container che puoi usare per accedere a quella parte del tuo filesystem. + + Questo è coperto più in dettaglio nella [Parte 5 di Hello Nextflow](../hello_nextflow/05_hello_containers.md). + +#### 4.1.3. Esegui lo strumento `cowpy` + +Dall'interno del container, puoi eseguire il comando `cowpy` direttamente. + +```bash +cowpy "Hello Containers" +``` + +??? success "Output del comando" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Questo produce arte ASCII della mucca predefinita (o 'cowacter') con un fumetto contenente il testo che abbiamo specificato. + +Ora che hai testato l'utilizzo base, puoi provare a dargli alcuni parametri. +Per esempio, la documentazione dello strumento dice che possiamo impostare il personaggio con `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Output del comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Questa volta l'output dell'arte ASCII mostra il pinguino Linux, Tux, perché abbiamo specificato il parametro `-c tux`. + +Dato che sei dentro il container, puoi eseguire il comando cowpy quante volte vuoi, variando i parametri di input, senza doverti preoccupare di installare librerie sul tuo sistema stesso. + +??? tip "Altri personaggi disponibili" + + Usa il flag '-c' per scegliere un personaggio diverso, inclusi: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Sentiti libero di giocare con questo. +Quando hai finito, esci dal container usando il comando `exit`: + +```bash +exit +``` + +Ti ritroverai di nuovo nella tua shell normale. + +### 4.2. Usa un container in un workflow + +Quando eseguiamo una pipeline, vogliamo essere in grado di dire a Nextflow quale container usare a ogni step, e importante, vogliamo che gestisca tutto quel lavoro che abbiamo appena fatto: scaricare il container, avviarlo, eseguire il comando e chiudere il container quando ha finito. + +Buone notizie: è esattamente ciò che Nextflow farà per noi. +Dobbiamo solo specificare un container per ogni process. + +Per dimostrare come funziona, abbiamo fatto un'altra versione del nostro workflow che esegue `cowpy` sul file di saluti raccolti prodotto nel terzo step. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Questo dovrebbe produrre un file contenente l'arte ASCII con i tre saluti nel fumetto. + +#### 4.2.1. Esamina il codice + +Il workflow è molto simile a quello precedente, più lo step extra per eseguire `cowpy`. + +??? full-code "File di codice completo" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Include i moduli + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emette un saluto + sayHello(greeting_ch) + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + // raccoglie tutti i saluti in un file + collectGreetings(convertToUpper.out.collect(), params.batch) + // genera arte ASCII dei saluti con cowpy + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Vedi che questo workflow importa un process `cowpy` da un file modulo, e lo chiama sull'output della chiamata `collectGreetings()`, più un parametro di input chiamato `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// genera arte ASCII con cowpy +cowpy(collectGreetings.out, params.character) +``` + +Il process `cowpy`, che incapsula il comando cowpy per generare arte ASCII, è definito nel modulo `cowpy.nf`. + +??? full-code "File di codice completo" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Il process `cowpy` richiede due input: il percorso di un file di input contenente il testo da mettere nel fumetto (`input_file`), e un valore per la variabile character. + +Importante, include anche la riga `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`, che punta all'URI del container che abbiamo usato prima. + +#### 4.2.2. Verifica che Docker sia abilitato nella configurazione + +Anticiperemo leggermente la Parte 3 di questo corso di formazione introducendo il file di configurazione `nextflow.config`, che è uno dei modi principali che Nextflow offre per configurare l'esecuzione del workflow. +Quando un file chiamato `nextflow.config` è presente nella directory corrente, Nextflow lo caricherà automaticamente e applicherà qualsiasi configurazione contenga. + +A tal fine, abbiamo incluso un file `nextflow.config` con una singola riga di codice che abilita Docker. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Questa configurazione dice a Nextflow di usare Docker per qualsiasi process che specifica un container compatibile. + +!!! tip "Suggerimento" + + È tecnicamente possibile abilitare l'esecuzione Docker dalla riga di comando, su base per-esecuzione, usando il parametro `-with-docker <container>`. + Tuttavia, questo ci permette solo di specificare un container per l'intero workflow, mentre l'approccio che ti abbiamo appena mostrato ci permette di specificare un container diverso per process. + Quest'ultimo è molto meglio per la modularità, la manutenzione del codice e la riproducibilità. + +#### 4.2.3. Esegui il workflow + +Solo per riepilogare, questo è ciò che stiamo per eseguire: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Pensi che funzionerà? + +Eseguiamo il workflow con il flag `-resume`, e specifichiamo che vogliamo che il personaggio sia il tacchino. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +I primi tre step sono stati salvati nella cache dato che li abbiamo già eseguiti prima, ma il process `cowpy` è nuovo quindi viene effettivamente eseguito. + +Puoi trovare l'output dello step `cowpy` nella directory `results`. + +??? abstract "Contenuto del file" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Vedi che il personaggio sta dicendo tutti i saluti, dato che è stato eseguito sul file di saluti maiuscoli raccolti. + +Ancora più importante, siamo stati in grado di eseguire questo come parte della nostra pipeline senza dover fare un'installazione vera e propria di cowpy e tutte le sue dipendenze. +E ora possiamo condividere la pipeline con i collaboratori e farla eseguire sulla loro infrastruttura senza che loro debbano installare nulla, a parte Docker o una delle sue alternative (come Singularity/Apptainer) come menzionato sopra. + +#### 4.2.4. Ispeziona come Nextflow ha lanciato l'attività containerizzata + +Come coda finale a questa sezione, diamo un'occhiata alla sottodirectory di lavoro per una delle chiamate al process `cowpy` per ottenere un po' più di insight su come Nextflow lavora con i container sotto il cofano. + +Controlla l'output dal tuo comando `nextflow run` per trovare il percorso alla sottodirectory di lavoro per il process `cowpy`. +Guardando ciò che abbiamo ottenuto per l'esecuzione mostrata sopra, la riga del log della console per il process `cowpy` inizia con `[7f/caf718]`. +Questo corrisponde al seguente percorso di directory troncato: `work/7f/caf718`. + +In quella directory, troverai il file `.command.run` che contiene tutti i comandi che Nextflow ha eseguito per te nel corso dell'esecuzione della pipeline. + +??? abstract "Contenuto del file" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + ... + ``` + +Se cerchi `nxf_launch` in questo file, dovresti vedere qualcosa come questo: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh +} +``` + +Questo comando di lancio mostra che Nextflow sta usando un comando `docker run` molto simile per lanciare la chiamata al process come abbiamo fatto quando l'abbiamo eseguito manualmente. +Monta anche la corrispondente sottodirectory di lavoro nel container, imposta la directory di lavoro all'interno del container di conseguenza, e esegue il nostro script bash templato nel file `.command.sh`. + +Questo conferma che tutto il duro lavoro che abbiamo dovuto fare manualmente nella sezione precedente viene ora fatto per noi da Nextflow! + +### Riepilogo + +Capisci quale ruolo giocano i container nella gestione delle versioni degli strumenti software e nell'assicurare la riproducibilità. + +Più in generale, hai una comprensione di base di quali sono i componenti principali delle pipeline Nextflow del mondo reale e come sono organizzati. +Conosci i fondamenti di come Nextflow può elaborare input multipli efficientemente, eseguire workflow composti da step multipli connessi insieme, sfruttare componenti di codice modulari, e utilizzare container per una maggiore riproducibilità e portabilità. + +### Cosa c'è dopo? + +Prenditi un'altra pausa! Era un grande mucchio di informazioni su come funzionano le pipeline Nextflow. + +Nell'ultima sezione di questa formazione, approfondiremo il tema della configurazione. +Imparerai come configurare l'esecuzione della tua pipeline per adattarla alla tua infrastruttura e come gestire la configurazione di input e parametri. + +--- + +## Quiz + +<quiz> +Perché Nextflow crea una directory di attività separata per ogni chiamata al process? +- [ ] Per migliorare la velocità di esecuzione +- [ ] Per ridurre l'utilizzo della memoria +- [x] Per isolare le esecuzioni ed evitare collisioni tra gli output +- [ ] Per abilitare la compressione dei file in parallelo + +Approfondisci: [1.3. Trova gli output originali e i log](#13-trova-gli-output-originali-e-i-log) +</quiz> + +<quiz> +Cosa fa l'opzione `-ansi-log false` quando si esegue un workflow? +- [ ] Disabilita tutto l'output della console +- [x] Rimuove i colori dall'output +- [x] Mostra tutti i percorsi delle directory di attività invece di condensarli su una riga +- [ ] Abilita la modalità di debug verbose + +Approfondisci: [1.3.2. Fai mostrare al terminale più dettagli](#132-fai-mostrare-al-terminale-piu-dettagli) + +Puoi anche usare una delle seguenti variabili d'ambiente se preferisci questo stile: + +```bash +export NXF_ANSI_LOG=0 +# oppure +export NO_COLOR=1 +``` + +</quiz> + +<quiz> +Nel codice `#!groovy channel.fromPath(params.input).splitCsv().map { line -> line[0] }`, cosa fa `#!groovy .map { line -> line[0] }`? +- [ ] Filtra le righe vuote +- [ ] Ordina le righe alfabeticamente +- [x] Estrae la prima colonna da ogni riga CSV +- [ ] Conta il numero di righe + +Approfondisci: [1.4.1. Caricare i dati di input dal CSV](#141-caricare-i-dati-di-input-dal-csv) +</quiz> + +<quiz> +Perché è importante includere il valore di input nei nomi dei file di output (es. `#!groovy "${greeting}-output.txt"`)? +- [ ] Per migliorare la velocità di elaborazione +- [ ] Per abilitare la funzionalità resume +- [x] Per evitare che i file di output si sovrascrivano a vicenda quando si elaborano input multipli +- [ ] Per rendere i file più facili da comprimere + +Approfondisci: [1.4.3. Come vengono nominati gli output](#143-come-vengono-nominati-gli-output) +</quiz> + +<quiz> +Qual è lo scopo della dichiarazione `include` in un workflow modularizzato? +- [ ] Copiare il codice del process nel file del workflow +- [x] Importare una definizione di process da un file modulo esterno +- [ ] Includere impostazioni di configurazione +- [ ] Aggiungere commenti di documentazione + +Approfondisci: [3. Eseguire pipeline modularizzate](#3-eseguire-pipeline-modularizzate) +</quiz> + +<quiz> +Quando modularizzi un workflow e lo esegui con `-resume`, cosa succede? +- [ ] Il caching è disabilitato per i process modulari +- [ ] Tutte le attività devono essere rieseguite +- [x] Il caching funziona normalmente in base agli script di job generati +- [ ] Solo il file del workflow principale viene salvato nella cache + +Approfondisci: [3.2. Esegui il workflow](#32-esegui-il-workflow) +</quiz> + +<quiz> +Cosa specifica la direttiva `container` in una definizione di process? +- [ ] La directory di lavoro per il process +- [ ] L'allocazione massima di memoria +- [x] L'URI dell'immagine container da usare per eseguire il process +- [ ] Il formato del file di output + +Approfondisci: [4.2. Usa un container in un workflow](#42-usa-un-container-in-un-workflow) +</quiz> + +<quiz> +Nel file `.command.run`, cosa contiene la funzione `nxf_launch`? +- [ ] Le informazioni sulla versione di Nextflow +- [ ] I parametri del workflow +- [x] Il comando `docker run` con i mount dei volumi e le impostazioni del container +- [ ] Le dichiarazioni di input del process + +Approfondisci: [4.2.4. Ispeziona come Nextflow ha lanciato l'attività containerizzata](#424-ispeziona-come-nextflow-ha-lanciato-lattivita-containerizzata) +</quiz> + +<quiz> +Cosa gestisce automaticamente Nextflow quando esegue un process containerizzato? (Seleziona tutte le risposte corrette) +- [x] Scaricare l'immagine container se necessario +- [x] Montare la directory di lavoro nel container +- [x] Eseguire lo script del process all'interno del container +- [x] Pulire l'istanza del container dopo l'esecuzione + +Approfondisci: [4. Usare software containerizzato](#4-usare-software-containerizzato) +</quiz> diff --git a/docs/it/docs/nextflow_run/03_config.md b/docs/it/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..e54f82bc2a --- /dev/null +++ b/docs/it/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Parte 3: Configurazione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questa sezione esplorerà come gestire la configurazione di una pipeline Nextflow per personalizzarne il comportamento, adattarla a diversi ambienti e ottimizzare l'uso delle risorse _senza modificare una singola riga del codice del workflow stesso_. + +Ci sono molteplici modi per farlo, che possono essere usati in combinazione e vengono interpretati secondo l'ordine di precedenza descritto [qui](https://www.nextflow.io/docs/latest/config.html). + +In questa parte del corso, ti mostreremo il meccanismo di file di configurazione più semplice e comune, il file `nextflow.config`, che hai già incontrato nella sezione sui container nella Parte 2. + +Esamineremo i componenti essenziali della configurazione di Nextflow come le direttive dei process, gli executor, i profili e i file di parametri. +Imparando a utilizzare efficacemente queste opzioni di configurazione, puoi sfruttare appieno la flessibilità, la scalabilità e le prestazioni delle pipeline Nextflow. + +Per esercitare questi elementi di configurazione, eseguiremo una copia fresca del workflow che abbiamo eseguito per ultimo alla fine della Parte 2 di questo corso di formazione, rinominato `3-main.nf`. + +Se non hai familiarità con la pipeline Hello o potresti aver bisogno di un promemoria, consulta [questa pagina informativa](../info/hello_pipeline.md). + +--- + +## 1. Gestire i parametri di input del workflow + +??? example "Scenario" + + Hai scaricato una pipeline e vuoi eseguirla ripetutamente con gli stessi file di input e impostazioni, ma non vuoi digitare tutti i parametri ogni volta. + O forse stai configurando la pipeline per un collega che non è a suo agio con gli argomenti da riga di comando. + +Inizieremo con un aspetto della configurazione che è semplicemente un'estensione di ciò con cui abbiamo lavorato finora: la gestione dei parametri di input. + +Attualmente, il nostro workflow è configurato per accettare diversi valori di parametri tramite la riga di comando, dichiarati in un blocco `params` nello script del workflow stesso. +Uno ha un valore predefinito impostato come parte della sua dichiarazione. + +Tuttavia, potresti voler impostare valori predefiniti per tutti loro, o sovrascrivere il valore predefinito esistente senza dover specificare parametri sulla riga di comando o modificare il file di script originale. + +Ci sono molteplici modi per farlo; ti mostreremo tre modi base che sono molto comunemente usati. + +### 1.1. Imposta i valori in `nextflow.config` + +Questo è l'approccio più semplice, sebbene sia probabilmente il meno flessibile poiché il file `nextflow.config` principale non è qualcosa che vuoi modificare per ogni esecuzione. +Ma ha il vantaggio di separare le preoccupazioni della _dichiarazione_ dei parametri nel workflow (che decisamente appartiene lì) rispetto alla fornitura dei _valori predefiniti_, che sono più a loro agio in un file di configurazione. + +Facciamolo in due step. + +#### 1.1.1. Crea un blocco `params` nel file di configurazione + +Fai le seguenti modifiche al codice nel file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Nota che non abbiamo semplicemente copiato il blocco `params` dal workflow al file di configurazione. +Per il parametro `batch` che aveva già un valore predefinito dichiarato, la sintassi è un po' diversa. +Nel file del workflow, quella è una dichiarazione tipizzata. +Nella configurazione, quelle sono assegnazioni di valori. + +Tecnicamente, questo è sufficiente per sovrascrivere i valori predefiniti ancora specificati nel file del workflow. +Potresti modificare il valore predefinito per `batch` ed eseguire il workflow per verificare che il valore impostato nel file di configurazione sovrascrive quello impostato nel file del workflow. + +Ma nello spirito di spostare la configurazione completamente al file di configurazione, rimuoviamo quel valore predefinito dal file del workflow completamente. + +#### 1.1.2. Rimuovi il valore predefinito per `batch` nel file del workflow + +Fai la seguente modifica al codice nel file del workflow `3-main.nf`: + +=== "Dopo" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Prima" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Ora il file del workflow stesso non imposta alcun valore predefinito per questi parametri. + +#### 1.1.3. Esegui la pipeline + +Testiamo che funzioni correttamente senza specificare alcun parametro nella riga di comando. + +```bash +nextflow run 3-main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima. + +L'output finale dell'arte ASCII è nella directory `results/3-main/`, sotto il nome `cowpy-COLLECTED-batch-output.txt`, come prima. + +??? abstract "Contenuto del file" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funzionalmente, questo spostamento non ha cambiato nulla, ma concettualmente è un po' più pulito avere i valori predefiniti impostati nel file di configurazione. + +### 1.2. Usa un file di configurazione specifico per l'esecuzione + +??? example "Scenario" + + Vuoi sperimentare con diverse impostazioni senza modificare il tuo file di configurazione principale. + +Puoi farlo creando un nuovo file `nextflow.config` in una sottodirectory che userai come directory di lavoro per i tuoi esperimenti. + +#### 1.2.1. Crea la directory di lavoro con una configurazione vuota + +Iniziamo creando una nuova directory e spostandoci al suo interno: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Poi, crea un file di configurazione vuoto in quella directory: + +```bash +touch nextflow.config +``` + +Questo produce un file vuoto. + +#### 1.2.2. Imposta la configurazione sperimentale + +Ora apri il nuovo file e aggiungi i parametri che vuoi personalizzare: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Nota che il percorso del file di input deve riflettere la struttura delle directory. + +#### 1.2.3. Esegui la pipeline + +Ora possiamo eseguire la nostra pipeline dall'interno della nostra nuova directory di lavoro. +Assicurati di adattare il percorso di conseguenza! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Questo creerà un nuovo set di directory sotto `tux-run/` incluse `tux-run/work/` e `tux-run/results/`. + +In questa esecuzione, Nextflow combina il `nextflow.config` nella nostra directory corrente con il `nextflow.config` nella directory root della pipeline, e quindi sovrascrive il personaggio predefinito (turkey) con il personaggio tux. + +Il file di output finale dovrebbe contenere il personaggio tux che dice i saluti. + +??? abstract "Contenuto del file" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Ecco fatto; ora hai uno spazio per sperimentare senza modificare la tua configurazione 'normale'. + +!!! warning "Avviso" + + Assicurati di tornare alla directory precedente prima di passare alla prossima sezione! + + ```bash + cd .. + ``` + +Ora guardiamo un altro modo utile per impostare i valori dei parametri. + +### 1.3. Usa un file di parametri + +??? example "Scenario" + + Devi condividere i parametri esatti dell'esecuzione con un collaboratore, o registrarli per una pubblicazione. + +L'approccio con la sottodirectory funziona benissimo per sperimentare, ma comporta un po' di setup e richiede che tu adatti i percorsi di conseguenza. +C'è un approccio più semplice per quando vuoi eseguire la tua pipeline con un set specifico di valori, o permettere a qualcun altro di farlo con il minimo sforzo. + +Nextflow ci permette di specificare parametri tramite un file di parametri in formato YAML o JSON, il che lo rende molto conveniente per gestire e distribuire set alternativi di valori predefiniti, per esempio, così come valori di parametri specifici per l'esecuzione. + +#### 1.3.1. Esamina il file di parametri di esempio + +Per dimostrare questo, forniamo un file di parametri di esempio nella directory corrente, chiamato `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Questo file di parametri contiene una coppia chiave-valore per ciascuno degli input che vogliamo specificare. +Nota l'uso dei due punti (`:`) invece dei segni di uguale (`=`) se confronti la sintassi con il file di configurazione. +Il file config è scritto in Groovy, mentre il file di parametri è scritto in YAML. + +!!! info "Informazione" + + Forniamo anche una versione JSON del file di parametri come esempio ma non lo eseguiremo qui. + Sentiti libero di provare quello da solo. + +#### 1.3.2. Esegui la pipeline + +Per eseguire il workflow con questo file di parametri, aggiungi semplicemente `-params-file <nomefile>` al comando base. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Il file di output finale dovrebbe contenere il personaggio stegosaurus che dice i saluti. + +??? abstract "Contenuto del file" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usare un file di parametri potrebbe sembrare eccessivo quando hai solo pochi parametri da specificare, ma alcune pipeline si aspettano dozzine di parametri. +In quei casi, usare un file di parametri ci permetterà di fornire valori di parametri a runtime senza dover digitare linee di comando massive e senza modificare lo script del workflow. + +Rende anche più facile distribuire set di parametri ai collaboratori, o come informazione di supporto per una pubblicazione, per esempio. +Questo rende il tuo lavoro più riproducibile da altri. + +### Riepilogo + +Sai come sfruttare le opzioni di configurazione chiave per gestire gli input del workflow. + +### Cosa c'è dopo? + +Impara come gestire dove e come vengono pubblicati gli output del tuo workflow. + +--- + +## 2. Gestire gli output del workflow + +??? example "Scenario" + + La tua pipeline pubblica gli output in una directory hardcoded, ma vuoi organizzare i risultati per progetto o nome dell'esperimento senza modificare il codice del workflow ogni volta. + +Il workflow che abbiamo ereditato usa percorsi per le dichiarazioni di output a livello di workflow, il che non è terribilmente flessibile e comporta molta ripetizione. + +Guardiamo alcuni modi comuni in cui potresti configurare questo per essere più flessibile. + +### 2.1. Personalizza il nome della directory `outputDir` + +Ogni versione del workflow che abbiamo eseguito finora ha pubblicato i suoi output in una sottodirectory diversa hardcoded nelle definizioni di output. + +Cambiamo questo per usare un parametro configurabile dall'utente. +Potremmo creare un parametro completamente nuovo per questo, ma usiamo il parametro `batch` dato che è già lì. + +#### 2.1.1. Imposta un valore per `outputDir` nel file di configurazione + +Il percorso che Nextflow usa per pubblicare gli output è controllato dall'opzione `outputDir`. +Per cambiare il percorso per tutti gli output, puoi impostare un valore per questa opzione nel file di configurazione `nextflow.config`. + +Aggiungi il seguente codice al file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Questo sostituirà il percorso predefinito integrato, `results/`, con `results/` più il valore del parametro `batch` come sottodirectory. +Potresti anche cambiare la parte `results` se volessi. + +Per una modifica temporanea, potresti impostare questa opzione dalla riga di comando usando il parametro `-output-dir` nel tuo comando (ma allora non potresti usare il valore del parametro `batch`). + +#### 2.1.2. Rimuovi la parte ripetuta del percorso hardcoded + +Abbiamo ancora una sottodirectory hardcoded nelle opzioni di output, quindi togliamola ora. + +Fai le seguenti modifiche al codice nel file del workflow: + +=== "Dopo" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +Avremmo anche potuto semplicemente aggiungere `${params.batch}` a ogni percorso invece di modificare il predefinito di `outputDir`, ma questo è più conciso. + +#### 2.1.3. Esegui la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `outdir` dalla riga di comando. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/outdir/`. + +??? abstract "Contenuti della directory" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Puoi combinare questo approccio con definizioni di percorsi personalizzate per costruire qualsiasi gerarchia di directory ti piaccia. + +### 2.2. Organizza gli output per process + +Un modo popolare per organizzare ulteriormente gli output è farlo per process, _cioè_ creare sottodirectory per ogni process eseguito nella pipeline. + +#### 2.2.1. Sostituisci i percorsi di output con un riferimento ai nomi dei process + +Tutto ciò che devi fare è fare riferimento al nome del process come `<task>.name` nella dichiarazione del percorso di output. + +Fai le seguenti modifiche nel file del workflow: + +=== "Dopo" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Prima" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Questo rimuove gli elementi hardcoded rimanenti dalla configurazione del percorso di output. + +#### 2.2.2. Esegui la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `pnames` dalla riga di comando. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/pnames/`, e sono raggruppati per process. + +??? abstract "Contenuti della directory" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Nota che qui abbiamo eliminato la distinzione tra `intermediates` rispetto agli output finali al livello superiore. +Potresti ovviamente mescolare e abbinare questi approcci, per esempio impostando il percorso del primo output come `intermediates/${sayHello.name}` + +### 2.3. Imposta la modalità di pubblicazione a livello di workflow + +Infine, nello spirito di ridurre la quantità di codice ripetitivo, possiamo sostituire le dichiarazioni `mode` per-output con una singola riga nella configurazione. + +#### 2.3.1. Aggiungi `workflow.output.mode` al file di configurazione + +Aggiungi il seguente codice al file `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Proprio come l'opzione `outputDir`, dare a `workflow.output.mode` un valore nel file di configurazione sarebbe sufficiente per sovrascrivere ciò che è impostato nel file del workflow, ma rimuoviamo comunque il codice non necessario. + +#### 2.3.2. Rimuovi la modalità di output dal file del workflow + +Fai le seguenti modifiche nel file del workflow: + +=== "Dopo" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Prima" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +È più conciso, vero? + +#### 2.3.3. Esegui la pipeline + +Testiamo che funzioni correttamente, impostando il nome del batch a `outmode` dalla riga di comando. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Questo produce ancora lo stesso output di prima, tranne che questa volta troviamo i nostri output sotto `results/outmode/`. +Sono ancora tutte copie vere, non symlink. + +??? abstract "Contenuti della directory" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Il motivo principale per cui potresti ancora voler usare il modo per-output di impostare la modalità è se vuoi mescolare e abbinare all'interno dello stesso workflow, _cioè_ avere alcuni output copiati e alcuni linkati simbolicamente. + +Ci sono molte altre opzioni che puoi personalizzare in questo modo, ma speriamo che questo ti dia un'idea della gamma di opzioni e di come utilizzarle efficacemente per adattarle alle tue preferenze. + +### Riepilogo + +Sai come controllare la denominazione e la struttura delle directory dove vengono pubblicati i tuoi output, così come la modalità di pubblicazione dell'output del workflow. + +### Cosa c'è dopo? + +Impara come adattare la configurazione del tuo workflow al tuo ambiente di calcolo, partendo dalla tecnologia di pacchettizzazione software. + +--- + +## 3. Seleziona una tecnologia di pacchettizzazione software + +Finora abbiamo guardato elementi di configurazione che controllano come gli input entrano e dove gli output escono. Ora è il momento di concentrarsi più specificamente sull'adattare la configurazione del tuo workflow al tuo ambiente di calcolo. + +Il primo passo su quel percorso è specificare da dove verranno i pacchetti software che verranno eseguiti in ogni step. +Sono già installati nell'ambiente di calcolo locale? +Dobbiamo recuperare immagini ed eseguirle tramite un sistema container? +O dobbiamo recuperare pacchetti Conda e costruire un ambiente Conda locale? + +Nella prima parte di questo corso di formazione (Parti 1-4) abbiamo semplicemente usato software installato localmente nel nostro workflow. +Poi nella Parte 5, abbiamo introdotto i container Docker e il file `nextflow.config`, che abbiamo usato per abilitare l'uso dei container Docker. + +Ora vediamo come possiamo configurare un'opzione alternativa di pacchettizzazione software tramite il file `nextflow.config`. + +### 3.1. Disabilita Docker e abilita Conda nel file di config + +??? example "Scenario" + + Stai spostando la tua pipeline su un cluster HPC dove Docker non è permesso per motivi di sicurezza. + Il cluster supporta Singularity e Conda, quindi devi cambiare la tua configurazione di conseguenza. + +Nextflow supporta molteplici tecnologie container incluso Singularity (che è più ampiamente usato su HPC), così come gestori di pacchetti software come Conda. + +Possiamo cambiare il nostro file di configurazione per usare Conda invece di Docker. +Per farlo, cambiamo il valore di `docker.enabled` a `false`, e aggiungiamo una direttiva che abilita l'uso di Conda: + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Questo permetterà a Nextflow di creare e utilizzare ambienti Conda per i process che hanno pacchetti Conda specificati. +Il che significa che ora dobbiamo aggiungerne uno al nostro process `cowpy`! + +### 3.2. Specifica un pacchetto Conda nella definizione del process + +Abbiamo già recuperato l'URI per un pacchetto Conda contenente lo strumento `cowpy`: `conda-forge::cowpy==1.1.5` + +Ora aggiungiamo l'URI alla definizione del process `cowpy` usando la direttiva `conda`: + +=== "Dopo" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Prima" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Per essere chiari, non stiamo _sostituendo_ la direttiva `docker`, stiamo _aggiungendo_ un'opzione alternativa. + +!!! tip "Suggerimento" + + Ci sono alcuni modi diversi per ottenere l'URI per un dato pacchetto conda. + Raccomandiamo di usare la query di ricerca di [Seqera Containers](https://seqera.io/containers/), che ti darà un URI che puoi copiare e incollare, anche se non stai pianificando di creare un container da esso. + +### 3.3. Esegui il workflow per verificare che possa usare Conda + +Proviamolo. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Output del comando" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Questo dovrebbe funzionare senza problemi e produrre gli stessi output di prima sotto `results/conda`. + +Dietro le quinte, Nextflow ha recuperato i pacchetti Conda e creato l'ambiente, che normalmente richiede un po' di lavoro; quindi è bello che non dobbiamo fare niente di tutto ciò noi stessi! + +!!! info "Informazione" + + Questo viene eseguito velocemente perché il pacchetto `cowpy` è abbastanza piccolo, ma se stai lavorando con pacchetti grandi, potrebbe richiedere un po' più di tempo del solito la prima volta, e potresti vedere l'output della console rimanere 'bloccato' per un minuto circa prima di completarsi. + Questo è normale ed è dovuto al lavoro extra che Nextflow fa la prima volta che usi un nuovo pacchetto. + +Dal nostro punto di vista, sembra che funzioni esattamente come l'esecuzione con Docker, anche se nel backend la meccanica è un po' diversa. + +Questo significa che siamo pronti per eseguire con ambienti Conda se necessario. + +??? info "Mescolare e abbinare Docker e Conda" + + Dato che queste direttive sono assegnate per process, è possibile 'mescolare e abbinare', _cioè_ configurare alcuni dei process nel tuo workflow per essere eseguiti con Docker e altri con Conda, per esempio, se l'infrastruttura di calcolo che stai usando supporta entrambi. + In quel caso, abiliteresti sia Docker che Conda nel tuo file di configurazione. + Se entrambi sono disponibili per un dato process, Nextflow darà priorità ai container. + + E come notato prima, Nextflow supporta molteplici altre tecnologie di pacchettizzazione software e container, quindi non sei limitato a solo quelle due. + +### Riepilogo + +Sai come configurare quale pacchetto software ogni process dovrebbe usare, e come passare da una tecnologia all'altra. + +### Cosa c'è dopo? + +Impara come cambiare la piattaforma di esecuzione usata da Nextflow per fare effettivamente il lavoro. + +--- + +## 4. Seleziona una piattaforma di esecuzione + +??? example "Scenario" + + Hai sviluppato e testato la tua pipeline sul tuo laptop, ma ora devi eseguirla su migliaia di campioni. + La tua istituzione ha un cluster HPC con uno scheduler Slurm che vorresti usare invece. + +Finora, abbiamo eseguito la nostra pipeline con l'executor locale. +Questo esegue ogni attività sulla macchina su cui Nextflow è in esecuzione. +Quando Nextflow inizia, guarda le CPU e la memoria disponibili. +Se le risorse delle attività pronte per l'esecuzione superano le risorse disponibili, Nextflow tratterrà le ultime attività dall'esecuzione fino a quando una o più delle attività precedenti sono terminate, liberando le risorse necessarie. + +L'executor locale è conveniente ed efficiente, ma è limitato a quella singola macchina. Per carichi di lavoro molto grandi, potresti scoprire che la tua macchina locale è un collo di bottiglia, o perché hai una singola attività che richiede più risorse di quelle disponibili, o perché hai così tante attività che aspettare che una singola macchina le esegua richiederebbe troppo tempo. + +Nextflow supporta [molti backend di esecuzione diversi](https://www.nextflow.io/docs/latest/executor.html), inclusi scheduler HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor e altri) così come backend di esecuzione cloud come (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes e altri). + +### 4.1. Puntare a un backend diverso + +La scelta dell'executor è impostata da una direttiva del process chiamata `executor`. +Per impostazione predefinita è impostata su `local`, quindi la seguente configurazione è implicita: + +```groovy title="Configurazione integrata" +process { + executor = 'local' +} +``` + +Per impostare l'executor per puntare a un backend diverso, specificheresti semplicemente l'executor che vuoi usando una sintassi simile a quella descritta sopra per le allocazioni di risorse (vedi [documentazione](https://www.nextflow.io/docs/latest/executor.html) per tutte le opzioni). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Avviso" + + Non possiamo effettivamente testare questo nell'ambiente di formazione perché non è configurato per connettersi a un HPC. + +### 4.2. Gestire la sintassi specifica del backend per i parametri di esecuzione + +La maggior parte delle piattaforme di calcolo ad alte prestazioni permettono (e a volte richiedono) di specificare certi parametri come richieste e limitazioni di allocazione delle risorse (per es. numero di CPU e memoria) e nome della coda di job da usare. + +Sfortunatamente, ciascuno di questi sistemi usa tecnologie, sintassi e configurazioni diverse per definire come un job dovrebbe essere definito e sottomesso allo scheduler rilevante. + +??? abstract "Esempi" + + Per esempio, lo stesso job che richiede 8 CPU e 4GB di RAM per essere eseguito sulla coda "my-science-work" deve essere espresso in modi diversi a seconda del backend. + + ```bash title="Config per SLURM / sottometti usando sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config per PBS / sottometti usando qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config per SGE / sottometti usando qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Fortunatamente, Nextflow semplifica tutto questo. +Fornisce una sintassi standardizzata in modo che tu possa specificare le proprietà rilevanti come `cpus`, `memory` e `queue` (vedi documentazione per altre proprietà) solo una volta. +Poi, a runtime, Nextflow userà quelle impostazioni per generare gli script specifici del backend appropriati basati sull'impostazione dell'executor. + +Copriremo quella sintassi standardizzata nella prossima sezione. + +### Riepilogo + +Ora sai come cambiare l'executor per usare diversi tipi di infrastruttura di calcolo. + +### Cosa c'è dopo? + +Impara come valutare ed esprimere allocazioni e limitazioni delle risorse in Nextflow. + +--- + +## 5. Controlla le allocazioni delle risorse di calcolo + +??? example "Scenario" + + La tua pipeline continua a fallire sul cluster perché le attività vengono terminate per aver superato i limiti di memoria. + O forse ti vengono addebitate risorse che non stai usando e vuoi ottimizzare i costi. + +La maggior parte delle piattaforme di calcolo ad alte prestazioni permettono (e a volte richiedono) di specificare certi parametri di allocazione delle risorse come il numero di CPU e la memoria. + +Per impostazione predefinita, Nextflow userà una singola CPU e 2GB di memoria per ogni process. +Le corrispondenti direttive del process sono chiamate `cpus` e `memory`, quindi la seguente configurazione è implicita: + +```groovy title="Configurazione integrata" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Puoi modificare questi valori, sia per tutti i process che per process specifici nominati, usando direttive di process aggiuntive nel tuo file di configurazione. +Nextflow le tradurrà nelle istruzioni appropriate per l'executor scelto. + +Ma come sai quali valori usare? + +### 5.1. Esegui il workflow per generare un report di utilizzo delle risorse + +??? example "Scenario" + + Non sai quanta memoria o CPU i tuoi process hanno bisogno e vuoi evitare di sprecare risorse o avere job terminati. + +Se non sai in anticipo quanta CPU e memoria i tuoi process probabilmente avranno bisogno, puoi fare del profiling delle risorse, il che significa eseguire il workflow con alcune allocazioni predefinite, registrare quanto ogni process ha usato, e da lì, stimare come regolare le allocazioni base. + +Convenientemente, Nextflow include strumenti integrati per fare questo, e genererà felicemente un report per te su richiesta. + +Per farlo, aggiungi `-with-report <nomefile>.html` alla tua riga di comando. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Il report è un file html, che puoi scaricare e aprire nel tuo browser. Puoi anche fare clic destro su di esso nell'esploratore file a sinistra e cliccare su `Show preview` per visualizzarlo nell'ambiente di formazione. + +Prenditi qualche minuto per guardare il report e vedere se riesci a identificare alcune opportunità per regolare le risorse. +Assicurati di cliccare sulle schede che mostrano i risultati di utilizzo come percentuale di ciò che è stato allocato. +C'è della [documentazione](https://www.nextflow.io/docs/latest/reports.html) che descrive tutte le funzionalità disponibili. + +### 5.2. Imposta le allocazioni delle risorse per tutti i process + +Il profiling mostra che i process nel nostro workflow di formazione sono molto leggeri, quindi riduciamo l'allocazione di memoria predefinita a 1GB per process. + +Aggiungi quanto segue al tuo file `nextflow.config`, prima della sezione dei parametri della pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Questo aiuterà a ridurre la quantità di calcolo che consumiamo. + +### 5.3. Imposta le allocazioni delle risorse per un process specifico + +Allo stesso tempo, faremo finta che il process `cowpy` richieda più risorse degli altri, solo per poter dimostrare come regolare le allocazioni per un process individuale. + +=== "Dopo" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Prima" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Con questa configurazione, tutti i process richiederanno 1GB di memoria e una singola CPU (il predefinito implicito), tranne il process `cowpy`, che richiederà 2GB e 2 CPU. + +!!! info "Informazione" + + Se hai una macchina con poche CPU e allochi un numero elevato per process, potresti vedere chiamate ai process mettersi in coda l'una dietro l'altra. + Questo perché Nextflow assicura che non richiediamo più CPU di quelle disponibili. + +### 5.4. Esegui il workflow con la configurazione aggiornata + +Proviamolo, fornendo un nome file diverso per il report di profiling così possiamo confrontare le prestazioni prima e dopo i cambiamenti di configurazione. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Probabilmente non noterai alcuna differenza reale dato che questo è un carico di lavoro così piccolo, ma questo è l'approccio che useresti per analizzare le prestazioni e i requisiti di risorse di un workflow del mondo reale. + +È molto utile quando i tuoi process hanno requisiti di risorse diversi. Ti permette di dimensionare correttamente le allocazioni delle risorse che imposti per ogni process basandoti su dati reali, non su supposizioni. + +!!! tip "Suggerimento" + + Questo è solo un piccolo assaggio di ciò che puoi fare per ottimizzare il tuo uso delle risorse. + Nextflow stesso ha una logica di [retry dinamico](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) davvero interessante integrata per ritentare i job che falliscono a causa di limitazioni delle risorse. + Inoltre, Seqera Platform offre anche strumenti basati sull'IA per ottimizzare automaticamente le tue allocazioni delle risorse. + +### 5.5. Aggiungi limiti alle risorse + +A seconda di quale executor di calcolo e infrastruttura di calcolo stai usando, potrebbero esserci alcuni vincoli su ciò che puoi (o devi) allocare. +Per esempio, il tuo cluster potrebbe richiedere di rimanere entro certi limiti. + +Puoi usare la direttiva `resourceLimits` per impostare le limitazioni rilevanti. La sintassi appare così quando è da sola in un blocco process: + +```groovy title="Esempio di sintassi" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow tradurrà questi valori nelle istruzioni appropriate a seconda dell'executor che hai specificato. + +Non eseguiremo questo, dato che non abbiamo accesso a un'infrastruttura rilevante nell'ambiente di formazione. +Tuttavia, se provassi a eseguire il workflow con allocazioni di risorse che superano questi limiti, poi cercassi il comando `sbatch` nel file di script `.command.run`, vedresti che le richieste che vengono effettivamente inviate all'executor sono limitate ai valori specificati da `resourceLimits`. + +??? info "Configurazioni di riferimento istituzionali" + + Il progetto nf-core ha compilato una [collezione di file di configurazione](https://nf-co.re/configs/) condivisi da varie istituzioni in tutto il mondo, coprendo una vasta gamma di executor HPC e cloud. + + Quei config condivisi sono preziosi sia per le persone che lavorano lì e possono quindi semplicemente utilizzare la configurazione della loro istituzione out of the box, sia come modello per le persone che cercano di sviluppare una configurazione per la propria infrastruttura. + +### Riepilogo + +Sai come generare un report di profiling per valutare l'utilizzo delle risorse e come modificare le allocazioni delle risorse per tutti i process e/o per process individuali, oltre a impostare limitazioni delle risorse per l'esecuzione su HPC. + +### Cosa c'è dopo? + +Impara come impostare profili di configurazione preimpostati e passare da uno all'altro a runtime. + +--- + +## 6. Usa i profili per passare da una configurazione preimpostata all'altra + +??? example "Scenario" + + Passi regolarmente dall'esecuzione di pipeline sul tuo laptop per lo sviluppo all'HPC della tua istituzione per le esecuzioni in produzione. + Sei stanco di cambiare manualmente le impostazioni di configurazione ogni volta che cambi ambiente. + +Ti abbiamo mostrato diversi modi in cui puoi personalizzare la configurazione della tua pipeline a seconda del progetto su cui stai lavorando o dell'ambiente di calcolo che stai usando. + +Potresti voler passare da un'impostazione alternativa all'altra a seconda di quale infrastruttura di calcolo stai usando. Per esempio, potresti voler sviluppare e eseguire test su piccola scala localmente sul tuo laptop, poi eseguire carichi di lavoro su scala completa su HPC o cloud. + +Nextflow ti permette di impostare un numero qualsiasi di profili che descrivono diverse configurazioni, che puoi poi selezionare a runtime usando un argomento da riga di comando, piuttosto che dover modificare il file di configurazione stesso. + +### 6.1. Crea profili per passare dallo sviluppo locale all'esecuzione su HPC + +Impostiamo due profili alternativi; uno per eseguire carichi su piccola scala su un computer normale, dove useremo container Docker, e uno per l'esecuzione su un HPC universitario con uno scheduler Slurm, dove useremo pacchetti Conda. + +#### 6.1.1. Imposta i profili + +Aggiungi quanto segue al tuo file `nextflow.config`, dopo la sezione dei parametri della pipeline ma prima delle impostazioni di output: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Vedi che per l'HPC universitario, stiamo anche specificando limitazioni delle risorse. + +#### 6.1.2. Esegui il workflow con un profilo + +Per specificare un profilo nella nostra riga di comando di Nextflow, usiamo l'argomento `-profile`. + +Proviamo a eseguire il workflow con la configurazione `my_laptop`. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Come puoi vedere, questo ci permette di alternare tra configurazioni molto comodamente a runtime. + +!!! warning "Avviso" + + Il profilo `univ_hpc` non funzionerà correttamente nell'ambiente di formazione dato che non abbiamo accesso a uno scheduler Slurm. + +Se in futuro troviamo altri elementi di configurazione che co-occorrono sempre con questi, possiamo semplicemente aggiungerli al/i profilo/i corrispondente/i. +Possiamo anche creare profili aggiuntivi se ci sono altri elementi di configurazione che vogliamo raggruppare insieme. + +### 6.2. Crea un profilo di parametri di test + +??? example "Scenario" + + Vuoi che altri possano provare rapidamente la tua pipeline senza dover raccogliere i propri dati di input. + +I profili non sono solo per la configurazione dell'infrastruttura. +Possiamo anche usarli per impostare valori predefiniti per i parametri del workflow, per rendere più facile per gli altri provare il workflow senza dover raccogliere valori di input appropriati loro stessi. +Puoi considerare questo un'alternativa all'uso di un file di parametri. + +#### 6.2.1. Imposta il profilo + +La sintassi per esprimere valori predefiniti in questo contesto appare così, per un profilo che chiamiamo `test`: + +```groovy title="Esempio di sintassi" + test { + params.<parametro1> + params.<parametro2> + ... + } +``` + +Se aggiungiamo un profilo test per il nostro workflow, il blocco `profiles` diventa: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Proprio come per i profili di configurazione tecnica, puoi impostare molteplici profili diversi che specificano parametri sotto qualsiasi nome arbitrario tu voglia. + +#### 6.2.2. Esegui il workflow localmente con il profilo test + +Convenientemente, i profili non sono mutuamente esclusivi, quindi possiamo specificare profili multipli nella nostra riga di comando usando la seguente sintassi `-profile <profilo1>,<profilo2>` (per qualsiasi numero di profili). + +Se combini profili che impostano valori per gli stessi elementi di configurazione e sono descritti nello stesso file di configurazione, Nextflow risolverà il conflitto usando qualunque valore abbia letto per ultimo (_cioè_ qualunque cosa venga dopo nel file). +Se le impostazioni in conflitto sono impostate in diverse fonti di configurazione, si applica l'[ordine di precedenza](https://www.nextflow.io/docs/latest/config.html) predefinito. + +Proviamo ad aggiungere il profilo test al nostro comando precedente: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Questo userà Docker dove possibile e produrrà output sotto `results/test`, e questa volta il personaggio è il duo comico `dragonandcow`. + +??? abstract "Contenuto del file" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Questo significa che finché distribuiamo tutti i file di dati di test con il codice del workflow, chiunque può provare rapidamente il workflow senza dover fornire i propri input tramite la riga di comando o un file di parametri. + +!!! tip "Suggerimento" + + Possiamo puntare a URL per file più grandi che sono memorizzati esternamente. + Nextflow li scaricherà automaticamente finché c'è una connessione aperta. + + Per maggiori dettagli, vedi la Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Usa `nextflow config` per vedere la configurazione risolta + +Come notato sopra, a volte lo stesso parametro può essere impostato a valori diversi in profili che vuoi combinare. +E più in generale, ci sono numerosi posti dove gli elementi di configurazione possono essere memorizzati, e a volte le stesse proprietà possono essere impostate a valori diversi in posti diversi. + +Nextflow applica un [ordine di precedenza](https://www.nextflow.io/docs/latest/config.html) stabilito per risolvere qualsiasi conflitto, ma può essere difficile determinarlo da solo. +E anche se nulla è in conflitto, può essere noioso cercare tutti i possibili posti dove le cose potrebbero essere configurate. + +Fortunatamente, Nextflow include un conveniente strumento utility chiamato `config` che può automatizzare tutto quel processo per te. + +Lo strumento `config` esplorerà tutti i contenuti nella tua directory di lavoro corrente, raccoglierà tutti i file di configurazione, e produrrà la configurazione completamente risolta che Nextflow userebbe per eseguire il workflow. +Questo ti permette di scoprire quali impostazioni verranno usate senza dover lanciare nulla. + +#### 6.3.1. Risolvi la configurazione predefinita + +Esegui questo comando per risolvere la configurazione che verrebbe applicata per impostazione predefinita. + +```bash +nextflow config +``` + +??? success "Output del comando" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Questo ti mostra la configurazione base che ottieni se non specifichi nulla di extra nella riga di comando. + +#### 6.3.2. Risolvi la configurazione con impostazioni specifiche attivate + +Se fornisci parametri da riga di comando, es. abilitando uno o più profili o caricando un file di parametri, il comando terrà conto anche di quelli. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Output del comando" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Questo diventa particolarmente utile per progetti complessi che coinvolgono molteplici livelli di configurazione. + +### Riepilogo + +Sai come usare i profili per selezionare una configurazione preimpostata a runtime con il minimo fastidio. +Più in generale, sai come configurare le esecuzioni del tuo workflow per adattarle a diverse piattaforme di calcolo e migliorare la riproducibilità delle tue analisi. + +### Cosa c'è dopo? + +Impara come eseguire pipeline direttamente da repository remoti come GitHub. + +--- + +## 7. Esegui pipeline da repository remoti + +??? example "Scenario" + + Vuoi eseguire una pipeline ben consolidata come quelle di nf-core senza dover scaricare e gestire il codice tu stesso. + +Finora abbiamo eseguito script di workflow situati nella directory corrente. +In pratica, vorrai spesso eseguire pipeline memorizzate in repository remoti, come GitHub. + +Nextflow rende questo semplice: puoi eseguire qualsiasi pipeline direttamente da un URL di un repository Git senza scaricarlo manualmente prima. + +### 7.1. Esegui una pipeline da GitHub + +La sintassi base per eseguire una pipeline remota è `nextflow run <repository>`, dove `<repository>` può essere un percorso di repository GitHub come `nextflow-io/hello`, un URL completo, o un percorso a GitLab, Bitbucket, o altri servizi di hosting Git. + +Prova a eseguire la pipeline demo ufficiale di Nextflow "hello": + +```bash +nextflow run nextflow-io/hello +``` + +La prima volta che esegui una pipeline remota, Nextflow la scarica e la mette in cache localmente. +Le esecuzioni successive usano la versione in cache a meno che tu non richieda esplicitamente un aggiornamento. + +### 7.2. Specifica una versione per la riproducibilità + +Per impostazione predefinita, Nextflow esegue l'ultima versione dal branch predefinito. +Puoi specificare una particolare versione, branch, o commit usando il flag `-r`: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Specificare versioni esatte è essenziale per la riproducibilità. + +### Riepilogo + +Sai come eseguire pipeline direttamente da GitHub e altri repository remoti, e come specificare versioni per la riproducibilità. + +### Cosa c'è dopo? + +Datti una bella pacca sulla spalla! +Sai tutto ciò che devi sapere per iniziare a eseguire e gestire pipeline Nextflow. + +Questo conclude questo corso, ma se sei desideroso di continuare a imparare, abbiamo due raccomandazioni principali: + +- Se vuoi approfondire lo sviluppo delle tue pipeline, dai un'occhiata a [Hello Nextflow](../hello_nextflow/index.md), un corso per principianti che copre la stessa progressione generale di questo ma va molto più in dettaglio su channel e operatori. +- Se vorresti continuare a imparare come eseguire pipeline Nextflow senza andare più in profondità nel codice, dai un'occhiata alla prima parte di [Hello nf-core](../hello_nf-core/index.md), che introduce gli strumenti per trovare e eseguire pipeline dall'estremamente popolare progetto [nf-core](https://nf-co.re/). + +Buon divertimento! + +--- + +## Quiz + +<quiz> +Quando i valori dei parametri sono impostati sia nel file del workflow che in `nextflow.config`, quale ha la precedenza? +- [ ] Il valore del file del workflow +- [x] Il valore del file di configurazione +- [ ] Il primo valore incontrato +- [ ] Causa un errore + +Approfondisci: [1.1. Imposta i valori in `nextflow.config`](#11-imposta-i-valori-in-nextflowconfig) +</quiz> + +<quiz> +Qual è la differenza di sintassi tra l'impostazione di un valore predefinito di un parametro in un file workflow vs. un file config? +- [ ] Usano la stessa sintassi +- [x] Il workflow usa dichiarazione tipizzata (`#!groovy param: Type = value`), il config usa assegnazione (`#!groovy param = value`) +- [ ] Il config usa dichiarazione tipizzata, il workflow usa assegnazione +- [ ] Solo i file config possono impostare valori predefiniti + +Approfondisci: [1.1. Imposta i valori in `nextflow.config`](#11-imposta-i-valori-in-nextflowconfig) +</quiz> + +<quiz> +Come specifichi un file di parametri quando esegui un workflow? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Approfondisci: [1.3. Usa un file di parametri](#13-usa-un-file-di-parametri) +</quiz> + +<quiz> +Cosa controlla l'opzione di configurazione `outputDir`? +- [ ] La posizione della directory di lavoro +- [x] Il percorso base dove vengono pubblicati gli output del workflow +- [ ] La directory per i file di log +- [ ] La posizione dei file modulo + +Approfondisci: [2.1. Personalizza il nome della directory outputDir](#21-personalizza-il-nome-della-directory-outputdir) +</quiz> + +<quiz> +Come si fa riferimento dinamicamente al nome di un process nella configurazione del percorso di output? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Approfondisci: [2.2. Organizza gli output per process](#22-organizza-gli-output-per-process) +</quiz> + +<quiz> +Se sia Docker che Conda sono abilitati e un process ha entrambe le direttive, quale ha la priorità? +- [x] Docker (container) +- [ ] Conda +- [ ] Il primo definito nel process +- [ ] Causa un errore + +Approfondisci: [3. Seleziona una tecnologia di pacchettizzazione software](#3-seleziona-una-tecnologia-di-pacchettizzazione-software) +</quiz> + +<quiz> +Qual è l'executor predefinito in Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Approfondisci: [4. Seleziona una piattaforma di esecuzione](#4-seleziona-una-piattaforma-di-esecuzione) +</quiz> + +<quiz> +Quale comando genera un report di utilizzo delle risorse? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Approfondisci: [5.1. Esegui il workflow per generare un report di utilizzo delle risorse](#51-esegui-il-workflow-per-generare-un-report-di-utilizzo-delle-risorse) +</quiz> + +<quiz> +Come si impostano i requisiti di risorse per un process specifico chiamato `cowpy` nel file config? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Approfondisci: [5.3. Imposta le allocazioni delle risorse per un process specifico](#53-imposta-le-allocazioni-delle-risorse-per-un-process-specifico) +</quiz> + +<quiz> +Cosa fa la direttiva `resourceLimits`? +- [ ] Imposta i requisiti minimi di risorse +- [ ] Alloca risorse ai process +- [x] Limita le risorse massime che possono essere richieste +- [ ] Monitora l'utilizzo delle risorse in tempo reale + +Approfondisci: [5.5. Aggiungi limiti alle risorse](#55-aggiungi-limiti-alle-risorse) +</quiz> + +<quiz> +Come si specificano profili multipli in un singolo comando? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Approfondisci: [6. Usa i profili per passare da una configurazione preimpostata all'altra](#6-usa-i-profili-per-passare-da-una-configurazione-preimpostata-allaltra) +</quiz> + +<quiz> +Quale comando mostra la configurazione completamente risolta che Nextflow userebbe? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Approfondisci: [6.3. Usa `nextflow config` per vedere la configurazione risolta](#63-usa-nextflow-config-per-vedere-la-configurazione-risolta) +</quiz> + +<quiz> +Per cosa possono essere usati i profili? (Seleziona tutte le risposte corrette) +- [x] Definire impostazioni specifiche dell'infrastruttura (executor, container) +- [x] Impostare limiti di risorse per diversi ambienti +- [x] Fornire parametri di test per testare facilmente il workflow +- [ ] Definire nuovi process + +Approfondisci: [6. Usa i profili per passare da una configurazione preimpostata all'altra](#6-usa-i-profili-per-passare-da-una-configurazione-preimpostata-allaltra) +</quiz> diff --git a/docs/it/docs/nextflow_run/index.md b/docs/it/docs/nextflow_run/index.md new file mode 100644 index 0000000000..69a647c8b5 --- /dev/null +++ b/docs/it/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Avviare e gestire l'esecuzione di workflow Nextflow + - Trovare e interpretare output (risultati) e file di log + - Riconoscere i componenti principali di Nextflow in un semplice workflow multi-step + - Configurare l'esecuzione di pipeline per piattaforme di calcolo comuni inclusi HPC e cloud + - Riassumere le best practice per riproducibilità, portabilità e riuso del codice che rendono le pipeline FAIR, inclusa la modularità del codice e i container software + audience_prerequisites: + - "**Pubblico:** Questo corso è progettato per chi è completamente nuovo a Nextflow e vuole eseguire pipeline esistenti." + - "**Competenze:** Si assume una certa familiarità con la linea di comando, concetti base di scripting e formati di file comuni." + - "**Dominio:** Gli esercizi sono tutti indipendenti dal dominio, quindi non è richiesta alcuna conoscenza scientifica pregressa." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run è un'introduzione pratica all'esecuzione di workflow di analisi dati riproducibili e scalabili.** + +Lavorando attraverso esempi pratici ed esercizi guidati, imparerai i fondamenti dell'utilizzo di Nextflow, incluso come eseguire pipeline, gestire file e dipendenze software, parallelizzare l'esecuzione senza sforzo, e far girare workflow su diversi ambienti di calcolo. + +Acquisirai le competenze e la sicurezza per iniziare a eseguire workflow con Nextflow. + +<!-- additional_information --> + +## Panoramica del corso + +### Cosa farai + +Questo corso è pratico, con esercizi orientati agli obiettivi strutturati per introdurre le informazioni gradualmente. + +Eseguirai diverse versioni di una pipeline Nextflow che elabora input di testo. +Inizierai con una versione semplice che consiste in un singolo step, e progredirai eventualmente verso una versione multi-step che prende un file CSV di input di testo tabulari, esegue alcuni step di trasformazione, e produce un singolo file di testo contenente un'immagine ASCII di un personaggio che pronuncia il testo trasformato. + +Questo corso si concentra sull'esecuzione di pipeline (dal nome del comando principale `nextflow run`). +Se cerchi un'introduzione allo sviluppo di pipeline Nextflow, consulta [Hello Nextflow](../hello_nextflow/index.md). + +### Piano delle lezioni + +Abbiamo suddiviso questo corso in tre parti che si concentreranno ciascuna su aspetti specifici dell'esecuzione e gestione di pipeline scritte in Nextflow. + +| Capitolo del corso | Riepilogo | Durata stimata | +| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Parte 1: Operazioni base](./01_basics.md) | Avvio e gestione dell'esecuzione di un semplice workflow | 30 min | +| [Parte 2: Eseguire pipeline reali](./02_pipeline.md) | Elaborazione di input complessi, esecuzione di workflow multi-step, utilizzo di container e parallelizzazione semplice | 60 min | +| [Parte 3: Configurazione](./03_config.md) | Personalizzazione del comportamento della pipeline e ottimizzazione dell'utilizzo in diversi ambienti di calcolo | 60 min | + +Al termine di questo corso, sarai ben preparato per affrontare i prossimi passi nel tuo percorso verso l'esecuzione di workflow riproducibili per le tue esigenze di calcolo scientifico. + +Pronto per iniziare il corso? + +[Inizia a imparare :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/it/docs/nextflow_run/next_steps.md b/docs/it/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..b055d8c958 --- /dev/null +++ b/docs/it/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Riepilogo del corso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni per aver completato il corso di formazione Nextflow Run! + +<!-- placeholder for video --> + +## Il tuo percorso + +Hai iniziato con un workflow molto basilare, e hai imparato a eseguirlo, trovare gli output e gestire la sua esecuzione. +Poi, hai lavorato attraverso versioni sempre più complesse di quel workflow e hai imparato a riconoscere i concetti e i meccanismi essenziali che alimentano le pipeline Nextflow, inclusi channel e operatori, modularizzazione del codice e container. +Infine, hai imparato come personalizzare la configurazione di una pipeline per adattarla alle tue preferenze e alla tua infrastruttura di calcolo. + +### Cosa hai imparato + +Ora sei in grado di gestire l'esecuzione della pipeline Hello, descrivere come è strutturata e identificare i principali pezzi di codice coinvolti. + +- La forma finale del workflow Hello prende come input un file CSV contenente saluti di testo. +- I quattro step sono implementati come process Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) memorizzati in file modulo separati. +- I risultati vengono pubblicati in una directory chiamata `results/`. +- L'output finale della pipeline è un file di testo semplice contenente arte ASCII di un personaggio che pronuncia i saluti in maiuscolo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Scrive ogni saluto nel suo file di output (es. "Hello-output.txt") +2. **`convertToUpper`:** Converte ogni saluto in maiuscolo (es. "HELLO") +3. **`collectGreetings`:** Raccoglie tutti i saluti maiuscoli in un singolo file batch +4. **`cowpy`:** Genera arte ASCII usando lo strumento `cowpy` + +La configurazione del workflow supporta la fornitura di input e parametri in modo flessibile e riproducibile. + +### Competenze acquisite + +Attraverso questo corso pratico, hai imparato come: + +- Lanciare un workflow Nextflow localmente +- Trovare e interpretare output (risultati) e file di log generati da Nextflow +- Riconoscere i componenti principali di Nextflow che costituiscono un semplice workflow multi-step +- Descrivere concetti avanzati come operatori e channel factory +- Configurare pipeline per diversi ambienti di calcolo + +Ora sei equipaggiato con le conoscenze fondamentali per iniziare a integrare le pipeline Nextflow esistenti nel tuo lavoro. + +## Prossimi passi per sviluppare le tue competenze + +Ecco i nostri migliori suggerimenti su cosa fare dopo: + +- Non limitarti a eseguire Nextflow, scrivilo! Diventa uno sviluppatore Nextflow con [Hello Nextflow](../hello_nextflow/index.md) +- Applica Nextflow a un caso d'uso di analisi scientifica con [Nextflow for Science](../nf4_science/index.md) +- Inizia con nf-core con [Hello nf-core](../hello_nf-core/index.md) +- Impara tecniche di troubleshooting con la [Debugging Side Quest](../side_quests/debugging.md) + +Infine, ti raccomandiamo di dare un'occhiata a [**Seqera Platform**](https://seqera.io/), una piattaforma cloud-based sviluppata dai creatori di Nextflow che rende ancora più facile lanciare e gestire i tuoi workflow, oltre a gestire i tuoi dati e eseguire analisi interattivamente in qualsiasi ambiente. + +## Ottenere aiuto + +Per risorse di aiuto e supporto della community, consulta la [pagina di Aiuto](../help.md). + +## Sondaggio di feedback + +Prima di proseguire, prenditi un minuto per completare il sondaggio del corso! Il tuo feedback ci aiuta a migliorare i nostri materiali di formazione per tutti. + +[Compila il sondaggio :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/it/docs/nextflow_run/survey.md b/docs/it/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..707bcf6c25 --- /dev/null +++ b/docs/it/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Sondaggio di feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Prima di proseguire, completa questo breve sondaggio di 5 domande per valutare la formazione, condividere eventuali feedback sulla tua esperienza e farci sapere cos'altro potremmo fare per aiutarti nel tuo percorso con Nextflow. + +Questo dovrebbe richiederti meno di un minuto per essere completato. Grazie per aiutarci a migliorare i nostri materiali di formazione per tutti! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/it/docs/nf4_science/genomics/00_orientation.md b/docs/it/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..a7de08a75d --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'ambiente di formazione contiene tutto il software, il codice e i dati necessari per seguire questo corso di formazione, quindi non è necessario installare nulla autonomamente. +Tuttavia, è necessario un account (gratuito) per accedere, e si dovrebbe dedicare qualche minuto per familiarizzare con l'interfaccia. + +Se non lo ha ancora fatto, segua [questo link](../../../envsetup/) prima di procedere oltre. + +## Materiali forniti + +Durante questo corso di formazione, lavoreremo nella directory `nf4-science/genomics/`, nella quale è necessario spostarsi quando si apre lo spazio di lavoro della formazione. +Questa directory contiene tutti i file di codice, i dati di test e i file accessori di cui avrà bisogno. + +Si senta libero di esplorare i contenuti di questa directory; il modo più semplice per farlo è utilizzare l'esploratore di file sul lato sinistro dello spazio di lavoro della formazione nell'interfaccia VSCode. +In alternativa, potete utilizzare il comando `tree`. +Durante il corso, utilizziamo l'output di `tree` per rappresentare la struttura e i contenuti della directory in forma leggibile, talvolta con modifiche minori per chiarezza. + +Qui generiamo un indice dei contenuti fino al secondo livello: + +```bash +tree . -L 2 +``` + +Se esegue questo comando all'interno di `nf4-science/genomics`, dovrebbe vedere il seguente output: + +```console title="Contenuti della directory" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Nota" + + Non si preoccupi se questo sembra molto; esamineremo le parti rilevanti in ogni fase del corso. + Questo è solo per fornirLe una panoramica. + +**Ecco un riepilogo di ciò che dovrebbe sapere per iniziare:** + +- **I file `.nf`** sono script di workflow denominati in base alla parte del corso in cui vengono utilizzati. + +- **Il file `nextflow.config`** è un file di configurazione che imposta proprietà minime dell'ambiente. + Può ignorarlo per ora. + +- **La directory `data`** contiene dati di input e risorse correlate, descritte più avanti nel corso. + +- **La directory `solutions`** contiene file di moduli e configurazioni di test che risultano dalle Parti 3 e 4 del corso. + Sono destinati ad essere utilizzati come riferimento per verificare il vostro lavoro e risolvere eventuali problemi. + +!!!tip "Suggerimento" + + Se per qualsiasi motivo vi spostate fuori da questa directory, potete sempre eseguire questo comando per ritornarvi: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Ora, per iniziare il corso, cliccate sulla freccia nell'angolo in basso a destra di questa pagina. diff --git a/docs/it/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/it/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..cf67c5b2c0 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1054 @@ +# Parte 1: Chiamata di varianti per campione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella prima parte di questo corso, Le mostreremo come costruire una semplice pipeline di chiamata di varianti che applica la chiamata di varianti GATK a singoli campioni di sequenziamento. + +### Panoramica del metodo + +La chiamata di varianti è un metodo di analisi genomica che mira a identificare variazioni in una sequenza genomica rispetto a un genoma di riferimento. +Qui utilizzeremo strumenti e metodi progettati per chiamare varianti brevi, _cioè_ SNP e indel. + +![GATK pipeline](img/gatk-pipeline.png) + +Una pipeline completa di chiamata di varianti coinvolge tipicamente molti passaggi, incluso il mapping al riferimento (a volte chiamato allineamento del genoma) e il filtraggio e la prioritizzazione delle varianti. +Per semplicità, in questa parte del corso ci concentreremo solo sulla parte di chiamata delle varianti. + +### Dataset + +Forniamo i seguenti dati e risorse correlate: + +- **Un genoma di riferimento** costituito da una piccola regione del cromosoma umano 20 (da hg19/b37) e i suoi file accessori (indice e dizionario di sequenza). +- **Tre campioni di sequenziamento dell'intero genoma** corrispondenti a un trio familiare (madre, padre e figlio), che sono stati ridotti a una piccola porzione di dati sul cromosoma 20 per mantenere le dimensioni dei file ridotte. + Si tratta di dati di sequenziamento Illumina a lettura breve che sono già stati mappati al genoma di riferimento, forniti in formato [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) (Binary Alignment Map, una versione compressa di SAM, Sequence Alignment Map). +- **Un elenco di intervalli genomici**, cioè coordinate sul genoma dove i nostri campioni hanno dati adatti per chiamare varianti, fornito in formato BED. + +### Workflow + +In questa parte del corso, svilupperemo un workflow che fa quanto segue: + +1. Generare un file indice per ciascun file BAM di input utilizzando [Samtools](https://www.htslib.org/) +2. Eseguire GATK HaplotypeCaller su ciascun file BAM di input per generare chiamate di varianti per campione in VCF (Variant Call Format) + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note "Nota" + + I file indice sono una caratteristica comune dei formati di file bioinformatici; contengono informazioni sulla struttura del file principale che consente a strumenti come GATK di accedere a un sottoinsieme dei dati senza dover leggere l'intero file. + Questo è importante a causa delle dimensioni che questi file possono raggiungere. + +--- + +## 0. Riscaldamento: Testare i comandi Samtools e GATK in modo interattivo + +Prima vogliamo provare i comandi manualmente prima di tentare di includerli in un workflow. +Gli strumenti di cui abbiamo bisogno (Samtools e GATK) non sono installati nell'ambiente GitHub Codespaces, quindi li useremo tramite container (vedere [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Nota" + + Assicuratevi di trovarsi nella directory `nf4-science/genomics` in modo che l'ultima parte del percorso mostrato quando digita `pwd` sia `genomics`. + +### 0.1. Indicizzare un file BAM di input con Samtools + +Scaricheremo un container Samtools, lo avvieremo in modo interattivo ed eseguiremo il comando `samtools index` su uno dei file BAM. + +#### 0.1.1. Scaricare il container Samtools + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.1.2. Avviare il container Samtools in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.1.3. Eseguire il comando di indicizzazione + +La [documentazione di Samtools](https://www.htslib.org/doc/samtools-index.html) ci fornisce la riga di comando da eseguire per indicizzare un file BAM. + +Dobbiamo solo fornire il file di input; lo strumento genererà automaticamente un nome per l'output aggiungendo `.bai` al nome del file di input. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Questo dovrebbe completarsi immediatamente, e ora dovrebbe vedere un file chiamato `reads_mother.bam.bai` nella stessa directory del file BAM di input originale. + +??? abstract "Contenuto della directory" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Uscire dal container Samtools + +```bash +exit +``` + +### 0.2. Chiamare varianti con GATK HaplotypeCaller + +Scaricheremo un container GATK, lo avvieremo in modo interattivo ed eseguiremo il comando `gatk HaplotypeCaller` sul file BAM che abbiamo appena indicizzato. + +#### 0.2.1. Scaricare il container GATK + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.2.2. Avviare il container GATK in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.2.3. Eseguire il comando di chiamata di varianti + +La [documentazione di GATK](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) ci fornisce la riga di comando da eseguire per effettuare la chiamata di varianti su un file BAM. + +Dobbiamo fornire il file BAM di input (`-I`) così come il genoma di riferimento (`-R`), un nome per il file di output (`-O`) e un elenco di intervalli genomici da analizzare (`-L`). + +Tuttavia, non è necessario specificare il percorso del file indice; lo strumento lo cercherà automaticamente nella stessa directory, basandosi sulla convenzione stabilita di denominazione e co-localizzazione. +Lo stesso vale per i file accessori del genoma di riferimento (file indice e dizionario di sequenza, `*.fai` e `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +Il file di output `reads_mother.vcf` viene creato all'interno della vostra directory di lavoro nel container, quindi non lo vedrà nell'explorer di file di VS Code a meno che non modifichi il percorso del file di output. +Tuttavia, è un piccolo file di test, quindi potete usare `cat` per aprirlo e visualizzarne il contenuto. +Se scorrete fino all'inizio del file, troverete un'intestazione composta da molte righe di metadati, seguita da un elenco di chiamate di varianti, una per riga. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Ogni riga descrive una possibile variante identificata nei dati di sequenziamento del campione. Per una guida sull'interpretazione del formato VCF, consulti [questo articolo utile](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +Il file VCF di output è accompagnato da un file indice chiamato `reads_mother.vcf.idx` che è stato creato automaticamente da GATK. +Ha la stessa funzione del file indice BAM, per consentire agli strumenti di cercare e recuperare sottoinsiemi di dati senza caricare l'intero file. + +#### 0.2.4. Uscire dal container GATK + +```bash +exit +``` + +### Takeaway + +Sa come testare i comandi di indicizzazione Samtools e di chiamata di varianti GATK nei rispettivi container. + +### Cosa c'è dopo? + +Imparare come includere quegli stessi comandi in un workflow a due passaggi che utilizza container per eseguire il lavoro. + +--- + +## 1. Scrivere un workflow a singolo stadio che esegue Samtools index su un file BAM + +Le forniamo un file workflow, `genomics-1.nf`, che delinea le parti principali del workflow. +Non è funzionale; il suo scopo è solo quello di servire come scheletro che utilizzerà per scrivere il workflow effettivo. + +### 1.1. Definire il processo di indicizzazione + +Iniziamo scrivendo un processo, che chiameremo `SAMTOOLS_INDEX`, che descrive l'operazione di indicizzazione. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Generate BAM index file + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Dovrebbe riconoscere tutti i pezzi da quello che ha imparato nella Parte 1 e Parte 2 di questa serie di formazione. + +Questo processo richiederà che passiamo un percorso di file tramite l'input `input_bam`, quindi configuriamo questo aspetto successivamente. + +### 1.2. Aggiungere una dichiarazione di parametro di input + +All'inizio del file, sotto la sezione `Pipeline parameters`, dichiariamo un parametro CLI chiamato `reads_bam` e gli diamo un valore predefinito. +In questo modo, possiamo essere pigri e non specificare l'input quando digitiamo il comando per avviare la pipeline (a scopo di sviluppo). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Pipeline parameters + */ +params { + // Input primario + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Ora abbiamo un processo pronto, così come un parametro per dargli un input su cui eseguire, quindi colleghiamo queste cose insieme. + +!!! note "Nota" + + `${projectDir}` è una variabile Nextflow integrata che punta alla directory dove si trova lo script workflow Nextflow corrente (`genomics-1.nf`). + + Questo facilita il riferimento a file, directory di dati e altre risorse incluse nel repository del workflow senza codificare percorsi assoluti. + +### 1.3. Aggiungere il blocco workflow per eseguire SAMTOOLS_INDEX + +Nel blocco `workflow`, dobbiamo configurare un **channel** per alimentare l'input al processo `SAMTOOLS_INDEX`; quindi possiamo chiamare il processo stesso per eseguirlo sul contenuto di quel channel. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Crea canale di input (singolo file tramite parametro CLI) + reads_ch = channel.fromPath(params.reads_bam) + + // Create index file for input BAM file + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +Il blocco workflow ha due sezioni: + +- `main:` contiene le operazioni sui channel e le chiamate ai processi +- `publish:` dichiara quali output devono essere pubblicati, assegnandoli a target nominati + +Noterà che stiamo usando lo stesso channel factory `.fromPath` che abbiamo usato in [Hello Channels](../../hello_nextflow/02_hello_channels.md). +Infatti, stiamo facendo qualcosa di molto simile. +La differenza è che stiamo dicendo a Nextflow di caricare semplicemente il percorso del file stesso nel channel come elemento di input, piuttosto che leggerne il contenuto. + +### 1.4. Aggiungere un blocco output per definire dove vengono pubblicati i risultati + +Dopo il blocco workflow, aggiungiamo un blocco `output` che specifica dove pubblicare gli output del workflow. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Ogni target nominato dalla sezione `publish:` (come `bam_index`) ottiene il proprio blocco dove è possibile configurare il percorso di output relativo alla directory di output base. + +!!! note "Nota" + + Anche se i file di dati che stiamo usando qui sono molto piccoli, nella genomica possono diventare molto grandi. + Per impostazione predefinita, Nextflow crea collegamenti simbolici ai file di output nella directory di pubblicazione, il che evita copie di file non necessarie. + È possibile modificare questo comportamento utilizzando l'opzione `mode` (ad esempio, `mode 'copy'`) per creare copie effettive invece. + Sia consapevole che i collegamenti simbolici si romperanno quando pulirà la vostra directory `work`, quindi per i workflow di produzione potrebbe voler usare `mode 'copy'`. + +### 1.5. Configurare la directory di output + +La directory di output base viene impostata tramite l'opzione di configurazione `outputDir`. La aggiunga a `nextflow.config`: + +=== "Dopo" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Prima" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Eseguire il workflow per verificare che il passaggio di indicizzazione funzioni + +Eseguiamo il workflow! Come promemoria, non è necessario specificare un input nella riga di comando perché abbiamo impostato un valore predefinito per l'input quando abbiamo dichiarato il parametro di input. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Può verificare che il file indice sia stato generato correttamente guardando nella directory di lavoro o nella directory dei risultati. + +??? abstract "Contenuto della directory di lavoro" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Contenuto della directory dei risultati" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +Eccolo! + +### Takeaway + +Sa come includere uno strumento genomico in un workflow Nextflow a passaggio singolo e farlo eseguire utilizzando un container. + +### Cosa c'è dopo? + +Aggiungere un secondo passaggio che consuma l'output del primo. + +--- + +## 2. Aggiungere un secondo processo per eseguire GATK HaplotypeCaller sul file BAM indicizzato + +Ora che abbiamo un indice per il nostro file di input, possiamo passare alla configurazione del passaggio di chiamata di varianti, che è la parte interessante del workflow. + +### 2.1. Definire il processo di chiamata di varianti + +Scriviamo un processo, che chiameremo `GATK_HAPLOTYPECALLER`, che descrive l'operazione di chiamata di varianti. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Call variants with GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Noterà che abbiamo introdotto una nuova sintassi qui (`emit:`) per nominare in modo univoco ciascuno dei nostri channel di output, e le ragioni di questo diventeranno presto chiare. + +Questo comando richiede molti più input, perché GATK ha bisogno di più informazioni per eseguire l'analisi rispetto a un semplice lavoro di indicizzazione. +Ma noterà che ci sono ancora più input definiti nel blocco degli input rispetto a quelli elencati nel comando GATK. Perché? + +!!! note "Nota" + + GATK sa cercare il file indice BAM e i file accessori del genoma di riferimento perché è consapevole delle convenzioni relative a quei file. + Tuttavia, Nextflow è progettato per essere indipendente dal dominio e non sa nulla dei requisiti dei formati di file bioinformatici. + +Dobbiamo dire esplicitamente a Nextflow che deve preparare quei file nella directory di lavoro in fase di esecuzione; altrimenti non lo farà, e GATK (correttamente) genererà un errore riguardo alla mancanza dei file indice. + +Allo stesso modo, dobbiamo elencare esplicitamente il file indice del VCF di output (il file `"${input_bam}.vcf.idx"`) in modo che Nextflow sappia di tenere traccia di quel file nel caso sia necessario nei passaggi successivi. + +### 2.2. Aggiungere definizioni per gli input accessori + +Poiché il nostro nuovo processo si aspetta che vengano forniti alcuni file aggiuntivi, configuriamo alcuni parametri CLI per essi nella sezione `Pipeline parameters`, insieme ad alcuni valori predefiniti (per le stesse ragioni di prima). + +```groovy title="genomics-1.nf" linenums="8" + // Accessory files + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Creare variabili per contenere i percorsi dei file accessori + +Mentre gli input di dati principali vengono trasmessi dinamicamente attraverso i channel, ci sono due approcci per gestire i file accessori. L'approccio raccomandato è creare channel espliciti, il che rende il flusso di dati più chiaro e coerente. In alternativa, la funzione file() per creare variabili può essere utilizzata per casi più semplici, in particolare quando è necessario fare riferimento allo stesso file in più processi - anche se sia consapevole che questo crea comunque channel implicitamente. + +Aggiunga questo al blocco workflow (dopo la creazione di `reads_ch`, all'interno della sezione `main:`): + +```groovy title="genomics-1.nf" linenums="79" + // Load the file paths for the accessory files (reference and intervals) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Questo renderà disponibili i percorsi dei file accessori per essere forniti come input a qualsiasi processo che ne abbia bisogno. + +### 2.4. Aggiungere una chiamata al blocco workflow per eseguire GATK_HAPLOTYPECALLER + +Ora che abbiamo configurato il nostro secondo processo e tutti gli input e i file accessori sono pronti e disponibili, possiamo aggiungere una chiamata al processo `GATK_HAPLOTYPECALLER` nel corpo del workflow. + +```groovy title="genomics-1.nf" linenums="88" + // Call variants from the indexed BAM file + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Dovrebbe riconoscere la sintassi `*.out` dalla Parte 1 di questa serie di formazione; stiamo dicendo a Nextflow di prendere l'output del channel da `SAMTOOLS_INDEX` e collegarlo alla chiamata del processo `GATK_HAPLOTYPECALLER`. + +!!! note "Nota" + + Noterà che gli input vengono forniti esattamente nello stesso ordine nella chiamata al processo come sono elencati nel blocco input del processo. + In Nextflow, gli input sono posizionali, il che significa che _deve_ seguire lo stesso ordine; e ovviamente ci devono essere lo stesso numero di elementi. + +### 2.5. Aggiornare la sezione publish e il blocco output + +Dobbiamo aggiornare la sezione `publish:` per includere gli output VCF, e aggiungere target corrispondenti nel blocco `output`. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Eseguire il workflow per verificare che il passaggio di chiamata di varianti funzioni + +Eseguiamo il workflow espanso con `-resume` in modo da non dover eseguire nuovamente il passaggio di indicizzazione. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Ora se guardiamo l'output della console, vediamo i due processi elencati. + +Il primo processo è stato saltato grazie alla memorizzazione nella cache, come previsto, mentre il secondo processo è stato eseguito poiché è completamente nuovo. + +Troverà i file di output nella directory dei risultati (come collegamenti simbolici alla directory di lavoro). + +??? abstract "Contenuto della directory" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Se apre il file VCF, dovrebbe vedere lo stesso contenuto del file che ha generato eseguendo il comando GATK direttamente nel container. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Questo è l'output che ci interessa generare per ciascun campione nel nostro studio. + +### Takeaway + +Sa come creare un workflow a due passaggi molto semplice che fa un lavoro di analisi reale ed è in grado di gestire le idiosincrasie dei formati di file genomici come i file accessori. + +### Cosa c'è dopo? + +Fare in modo che il workflow gestisca più campioni in blocco. + +--- + +## 3. Adattare il workflow per eseguirlo su un batch di campioni + +È tutto bello avere un workflow che può automatizzare l'elaborazione su un singolo campione, ma cosa succede se avete 1000 campioni? +Ha bisogno di scrivere uno script bash che scorra attraverso tutti i vostri campioni? + +No, per fortuna! Basta fare una piccola modifica al codice e Nextflow gestirà anche questo per voi. + +### 3.1. Trasformare la dichiarazione del parametro di input in un array che elenca i tre campioni + +Trasformiamo quel percorso di file predefinito nella dichiarazione del file BAM di input in un array che elenca i percorsi dei file per i nostri tre campioni di test, nella sezione `Pipeline parameters`. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="7" + // Input primario (array di tre campioni) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="7" + // Input primario + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note "Nota" + + Quando si utilizzano dichiarazioni di parametri tipizzate (come `reads_bam: Path`), non è possibile assegnare un valore array. + Per gli array, ometta l'annotazione del tipo. + +E questo è in realtà tutto ciò che dobbiamo fare, perché il channel factory che usiamo nel corpo del workflow (`.fromPath`) è altrettanto felice di accettare più percorsi di file da caricare nel channel di input quanto lo era di caricarne uno solo. + +!!! note "Nota" + + Normalmente, non vorrebbe codificare l'elenco dei campioni nel vostro file workflow, ma lo stiamo facendo qui per mantenere le cose semplici. + Presenteremo modi più eleganti per gestire gli input più avanti in questa serie di formazione. + +### 3.2. Eseguire il workflow per verificare che venga eseguito su tutti e tre i campioni + +Proviamo a eseguire il workflow ora che l'impianto è configurato per eseguire tutti e tre i campioni di test. + +```bash +nextflow run genomics-1.nf -resume +``` + +Cosa divertente: questo _potrebbe funzionare_, OPPURE _potrebbe fallire_. Ad esempio, ecco un'esecuzione riuscita: + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Se l'esecuzione del vostro workflow è riuscita, eseguitela di nuovo finché non ottenete un errore come questo: + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Se guarda l'output di errore del comando GATK, ci sarà una riga come questa: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Beh, è strano, considerando che abbiamo esplicitamente indicizzato i file BAM nel primo passaggio del workflow. Potrebbe esserci qualcosa di sbagliato nell'impianto? + +#### 3.2.1. Controllare le directory di lavoro per le chiamate rilevanti + +Diamo un'occhiata all'interno della directory di lavoro per la chiamata al processo `GATK_HAPLOTYPECALLER` fallita elencata nell'output della console. + +??? abstract "Contenuto della directory" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Presti particolare attenzione ai nomi del file BAM e dell'indice BAM elencati in questa directory: `reads_son.bam` e `reads_father.bam.bai`. + +Che diavolo? Nextflow ha preparato un file indice nella directory di lavoro di questa chiamata al processo, ma è quello sbagliato. Come è potuto succedere? + +#### 3.2.2. Usare l'[operatore view()](https://www.nextflow.io/docs/latest/reference/operator.html#view) per ispezionare il contenuto del channel + +Aggiunga queste due righe nel corpo del workflow prima della chiamata al processo `GATK_HAPLOTYPER`: + +```groovy title="genomics-1.nf" linenums="84" + // temporary diagnostics + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Quindi eseguite di nuovo il comando del workflow. + +```bash +nextflow run genomics-1.nf +``` + +Ancora una volta, questo può avere successo o fallire. Ecco un'esecuzione riuscita: + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +Ed ecco una fallita: + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Potrebbe dover eseguire più volte perché fallisca di nuovo. +Questo errore non si riprodurrà in modo coerente perché dipende da una certa variabilità nei tempi di esecuzione delle singole chiamate ai processi. + +Questo è l'aspetto dell'output delle due chiamate `.view()` che abbiamo aggiunto per un'esecuzione fallita: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +Le prime tre righe corrispondono al channel di input e la seconda, al channel di output. +Può vedere che i file BAM e i file indice per i tre campioni non sono elencati nello stesso ordine! + +!!! note "Nota" + + Quando chiama un processo Nextflow su un channel contenente più elementi, Nextflow tenterà di parallelizzare l'esecuzione il più possibile e raccoglierà gli output in qualsiasi ordine diventino disponibili. + La conseguenza è che gli output corrispondenti possono essere raccolti in un ordine diverso rispetto a quello in cui sono stati forniti gli input originali. + +Come attualmente scritto, il nostro script workflow presume che i file indice escano dal passaggio di indicizzazione elencati nello stesso ordine madre/padre/figlio degli input forniti. +Ma questo non è garantito, motivo per cui a volte (anche se non sempre) i file sbagliati vengono accoppiati nel secondo passaggio. + +Per risolvere questo problema, dobbiamo assicurarci che i file BAM e i loro file indice viaggino insieme attraverso i channel. + +!!! tip "Suggerimento" + + Le istruzioni `view()` nel codice del workflow non fanno nulla, quindi non è un problema lasciarle. + Tuttavia, ingombreranno l'output della vostra console, quindi vi consigliamo di rimuoverle quando ha finito di risolvere il problema. + +### 3.3. Modificare l'output del processo SAMTOOLS_INDEX in una tupla che mantiene insieme il file di input e il suo indice + +Il modo più semplice per garantire che un file BAM e il suo indice rimangano strettamente associati è confezionarli insieme in una tupla in uscita dall'attività di indicizzazione. + +!!! note "Nota" + + Una **tupla** è una lista ordinata finita di elementi che viene comunemente utilizzata per restituire più valori da una funzione. Le tuple sono particolarmente utili per passare più input o output tra processi preservandone l'associazione e l'ordine. + +Prima, modifichiamo l'output del processo `SAMTOOLS_INDEX` per includere il file BAM nella sua dichiarazione di output. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +In questo modo, ciascun file indice sarà strettamente accoppiato con il suo file BAM originale, e l'output complessivo del passaggio di indicizzazione sarà un singolo channel contenente coppie di file. + +### 3.4. Modificare l'input del processo GATK_HAPLOTYPECALLER per essere una tupla + +Poiché abbiamo modificato la 'forma' dell'output del primo processo nel workflow, dobbiamo aggiornare la definizione dell'input del secondo processo per corrispondere. + +Specificamente, dove in precedenza dichiaravamo due percorsi di input separati nel blocco input del processo `GATK_HAPLOTYPECALLER`, ora dichiariamo un singolo input che corrisponde alla struttura della tupla emessa da `SAMTOOLS_INDEX`. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Naturalmente, poiché ora abbiamo modificato la forma degli input che `GATK_HAPLOTYPECALLER` si aspetta, dobbiamo aggiornare di conseguenza la chiamata al processo nel corpo del workflow. + +### 3.5. Aggiornare la chiamata a GATK_HAPLOTYPECALLER nel blocco workflow + +Non è più necessario fornire il `reads_ch` originale al processo `GATK_HAPLOTYPECALLER`, poiché il file BAM è ora incluso nel channel di output da `SAMTOOLS_INDEX`. + +Di conseguenza, possiamo semplicemente eliminare quella riga. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +Questa è tutta la riconfigurazione necessaria per risolvere il problema di mancata corrispondenza dell'indice. + +### 3.6. Aggiornare la sezione publish e il blocco output per la tupla + +Poiché `SAMTOOLS_INDEX.out` è ora una tupla contenente sia il BAM che il suo indice, entrambi i file verranno pubblicati insieme. +Rinominiamo il target da `bam_index` a `indexed_bam` per riflettere che ora contiene entrambi i file. + +=== "Dopo" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Dobbiamo anche aggiornare il blocco output per usare il nuovo nome del target: + +=== "Dopo" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Eseguire il workflow per verificare che funzioni correttamente su tutti e tre i campioni ogni volta + +Naturalmente, la prova è nel budino, quindi eseguiamo il workflow di nuovo alcune volte per assicurarci che funzionerà in modo affidabile andando avanti. + +```bash +nextflow run genomics-1.nf +``` + +Questa volta (e ogni volta) tutto dovrebbe funzionare correttamente: + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +La directory dei risultati ora contiene sia file BAM che BAI per ciascun campione (dalla tupla), insieme agli output VCF: + +??? abstract "Contenuto della directory dei risultati" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Se desiderate, potete usare `.view()` di nuovo per dare un'occhiata a come appare il contenuto del channel di output di `SAMTOOLS_INDEX`: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Vedrà che il channel contiene le tre tuple previste (percorsi dei file troncati per leggibilità). + +```console title="Output" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Questo sarà molto più sicuro, andando avanti. + +### Takeaway + +Sa come fare in modo che il vostro workflow venga eseguito su più campioni (in modo indipendente). + +### Cosa c'è dopo? + +Rendere più facile gestire campioni in blocco. + +--- + +## 4. Fare in modo che il workflow accetti un file di testo contenente un batch di file di input + +Un modo molto comune per fornire più file di dati di input a un workflow è farlo con un file di testo contenente i percorsi dei file. +Può essere semplice come un file di testo che elenca un percorso di file per riga e nient'altro, oppure il file può contenere metadati aggiuntivi, nel qual caso è spesso chiamato samplesheet. + +Qui Le mostreremo come fare nel caso semplice. + +### 4.1. Esaminare il file di testo fornito che elenca i percorsi dei file di input + +Abbiamo già creato un file di testo che elenca i percorsi dei file di input, chiamato `sample_bams.txt`, che potete trovare nella directory `data/`. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Come potete vedere, abbiamo elencato un percorso di file per riga, e sono percorsi assoluti. + +!!! note "Nota" + + I file che stiamo usando qui sono semplicemente sul filesystem locale del vostro GitHub Codespaces, ma potremmo anche puntare a file nello storage cloud. + +### 4.2. Aggiornare il valore predefinito del parametro + +Cambiamo il valore predefinito per il nostro parametro di input `reads_bam` per puntare al file `sample_bams.txt`. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="7" + // Input primario (file di file di input, uno per riga) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="7" + // Input primario (array di tre campioni) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +In questo modo possiamo continuare a essere pigri, ma l'elenco dei file non vive più nel codice del workflow stesso, il che è un grande passo nella giusta direzione. + +### 4.3. Aggiornare il channel factory per leggere righe da un file + +Attualmente, il nostro channel factory di input tratta qualsiasi file che gli forniamo come input di dati che vogliamo alimentare al processo di indicizzazione. +Poiché ora gli stiamo dando un file che elenca i percorsi dei file di input, dobbiamo cambiare il suo comportamento per analizzare il file e trattare i percorsi dei file che contiene come input di dati. + +Fortunatamente possiamo farlo molto semplicemente, semplicemente aggiungendo l'[operatore `.splitText()`](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) al passaggio di costruzione del channel. + +=== "Dopo" + + ```groovy title="genomics-1.nf" linenums="68" + // Crea canale di input da un file di testo che elenca i percorsi dei file di input + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Prima" + + ```groovy title="genomics-1.nf" linenums="68" + // Crea canale di input (singolo file tramite parametro CLI) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip "Suggerimento" + + Questa è un'altra grande opportunità per usare l'operatore `.view()` per vedere come appaiono i contenuti del channel prima e dopo l'applicazione di un operatore. + +### 4.4. Eseguire il workflow per verificare che funzioni correttamente + +Eseguiamo il workflow un'ultima volta. Questo dovrebbe produrre lo stesso risultato di prima, giusto? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + ``` + +Sì! Infatti, Nextflow rileva correttamente che le chiamate ai processi sono esattamente le stesse, e non si preoccupa nemmeno di rieseguire tutto, poiché stavamo eseguendo con `-resume`. + +E questo è tutto! Il nostro semplice workflow di chiamata di varianti ha tutte le funzionalità di base che volevamo. + +### Takeaway + +Sa come creare un workflow lineare a più passaggi per indicizzare un file BAM e applicare la chiamata di varianti per campione utilizzando GATK. + +Più in generale, ha imparato come utilizzare componenti e logica essenziali di Nextflow per costruire una semplice pipeline genomica che fa un lavoro reale, tenendo conto delle idiosincrasie dei formati di file genomici e dei requisiti degli strumenti. + +### Cosa c'è dopo? + +Celebrate il vostro successo e prendetevi una pausa extra lunga! + +Nella prossima parte di questo corso, imparerà come utilizzare alcune funzionalità aggiuntive di Nextflow (inclusi più operatori di channel) per applicare la chiamata congiunta di varianti ai dati. diff --git a/docs/it/docs/nf4_science/genomics/02_joint_calling.md b/docs/it/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..f9b43d43e0 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1026 @@ +# Parte 2: Chiamata congiunta su una coorte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella prima parte di questo corso, avete costruito una pipeline di chiamata delle varianti completamente lineare che processava i dati di ciascun campione indipendentemente dagli altri. +Tuttavia, in un caso d'uso genomico reale, tipicamente sarà necessario esaminare le chiamate di varianti di più campioni insieme. + +In questa seconda parte, Le mostriamo come utilizzare i canali e gli operatori di canale per implementare la chiamata congiunta delle varianti con GATK, basandosi sulla pipeline della Parte 1. + +### Panoramica del metodo + +Il metodo di chiamata delle varianti GATK che abbiamo utilizzato nella prima parte di questo corso generava semplicemente chiamate di varianti per campione. +Questo va bene se si desidera solo esaminare le varianti di ciascun campione in isolamento, ma ciò fornisce informazioni limitate. +Spesso è più interessante esaminare come le chiamate di varianti differiscono tra più campioni, e per fare ciò, GATK offre un metodo alternativo chiamato chiamata congiunta delle varianti, che dimostriamo qui. + +La chiamata congiunta delle varianti comporta la generazione di un tipo speciale di output di varianti chiamato GVCF (per Genomic VCF) per ciascun campione, quindi la combinazione dei dati GVCF di tutti i campioni e infine, l'esecuzione di un'analisi statistica di 'genotipizzazione congiunta'. + +![Analisi congiunta](img/joint-calling.png) + +Ciò che è speciale in un GVCF di un campione è che contiene record che riassumono le statistiche dei dati di sequenza su tutte le posizioni nell'area mirata del genoma, non solo le posizioni in cui il programma ha trovato evidenza di variazione. +Questo è fondamentale per il calcolo della genotipizzazione congiunta ([ulteriori informazioni](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +Il GVCF è prodotto da GATK HaplotypeCaller, lo stesso strumento che abbiamo utilizzato nella Parte 1, con un parametro aggiuntivo (`-ERC GVCF`). +La combinazione dei GVCF viene eseguita con GATK GenomicsDBImport, che combina le chiamate per campione in un archivio dati (analogo a un database), quindi l'analisi vera e propria di 'genotipizzazione congiunta' viene eseguita con GATK GenotypeGVCFs. + +### Workflow + +Quindi per ricapitolare, in questa parte del corso, svilupperemo un workflow che fa quanto segue: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Generare un file di indice per ciascun file BAM di input utilizzando Samtools +2. Eseguire GATK HaplotypeCaller su ciascun file BAM di input per generare un GVCF delle chiamate di varianti genomiche per campione +3. Raccogliere tutti i GVCF e combinarli in un archivio dati GenomicsDB +4. Eseguire la genotipizzazione congiunta sull'archivio dati GVCF combinato per produrre un VCF a livello di coorte + +Applicheremo questo allo stesso dataset della Parte 1. + +--- + +## 0. Riscaldamento: Eseguire Samtools e GATK direttamente + +Proprio come in precedenza, vogliamo provare i comandi manualmente prima di tentare di incorporarli in un workflow. + +!!! note + + Assicuratevi di essere nella directory di lavoro corretta: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Indicizzare un file BAM di input con Samtools + +Questo primo passo è lo stesso della Parte 1, quindi dovrebbe risultare molto familiare, ma questa volta dobbiamo farlo per tutti e tre i campioni. + +!!! note + + Tecnicamente abbiamo già generato file di indice per i tre campioni attraverso la nostra pipeline, quindi potremmo andare a recuperarli dalla directory dei risultati. Tuttavia, è più pulito semplicemente rifarlo manualmente, e ci vorrà solo un minuto. + +#### 0.1.1. Avviare il container Samtools in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.1.2. Eseguire il comando di indicizzazione per i tre campioni + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Proprio come in precedenza, questo dovrebbe produrre i file di indice nella stessa directory dei file BAM corrispondenti. + +??? abstract "Contenuto della directory" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Ora che abbiamo file di indice per tutti e tre i campioni, possiamo procedere alla generazione dei GVCF per ciascuno di essi. + +#### 0.1.3. Uscire dal container Samtools + +```bash +exit +``` + +### 0.2. Chiamare le varianti con GATK HaplotypeCaller in modalità GVCF + +Questo secondo passo è molto simile a ciò che abbiamo fatto nella Parte 1: Hello Genomics, ma ora eseguiremo GATK in 'modalità GVCF'. + +#### 0.2.1. Avviare il container GATK in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +#### 0.2.2. Eseguire il comando di chiamata delle varianti con l'opzione GVCF + +Per produrre un VCF genomico (GVCF), aggiungiamo l'opzione `-ERC GVCF` al comando di base, che attiva la modalità GVCF di HaplotypeCaller. + +Modifichiamo anche l'estensione del file per il file di output da `.vcf` a `.g.vcf`. +Tecnicamente questo non è un requisito, ma è una convenzione fortemente raccomandata. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +Questo crea il file di output GVCF `reads_mother.g.vcf` nella directory di lavoro corrente nel container. + +Se lo visualizzate con `cat` per vederne il contenuto, vedrà che è molto più lungo del VCF equivalente che abbiamo generato nella Parte 1. Non potete nemmeno scorrere fino all'inizio del file, e la maggior parte delle righe appare abbastanza diversa da ciò che abbiamo visto nel VCF della Parte 1. + +```console title="Output" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Questi rappresentano regioni non varianti dove il chiamante di varianti non ha trovato evidenza di variazione, quindi ha catturato alcune statistiche che descrivono il suo livello di confidenza nell'assenza di variazione. Questo rende possibile distinguere tra due casi molto diversi: (1) ci sono dati di buona qualità che mostrano che il campione è omozigote-riferimento, e (2) non ci sono abbastanza dati di buona qualità disponibili per fare una determinazione in un modo o nell'altro. + +In un GVCF, ci sono tipicamente molte di queste righe non varianti, con un numero minore di record di varianti sparse tra di esse. Provi a eseguire `head -176` sul GVCF per caricare solo le prime 176 righe del file per trovare una chiamata di variante effettiva. + +```console title="Output" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +La seconda riga mostra il primo record di variante nel file, che corrisponde alla prima variante nel file VCF che abbiamo esaminato nella Parte 1. + +Proprio come il VCF originale, anche il file GVCF di output è accompagnato da un file di indice, chiamato `reads_mother.g.vcf.idx`. + +#### 0.2.3. Ripetere il processo sugli altri due campioni + +Per testare il passo di genotipizzazione congiunta, abbiamo bisogno di GVCF per tutti e tre i campioni, quindi generiamoli manualmente ora. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +Una volta completato, dovrebbe avere tre file che terminano con `.g.vcf` nella vostra directory corrente (uno per campione) e i rispettivi file di indice che terminano con `.g.vcf.idx`. + +### 0.3. Eseguire la genotipizzazione congiunta + +Ora che abbiamo tutti i GVCF, possiamo finalmente provare l'approccio di genotipizzazione congiunta per generare chiamate di varianti per una coorte di campioni. +Come promemoria, è un metodo in due fasi che consiste nel combinare i dati di tutti i GVCF in un archivio dati, quindi eseguire l'analisi di genotipizzazione congiunta vera e propria per generare il VCF finale delle varianti chiamate congiuntamente. + +#### 0.3.1. Combinare tutti i GVCF per campione + +Questa prima fase utilizza un altro strumento GATK, chiamato GenomicsDBImport, per combinare i dati di tutti i GVCF in un archivio dati GenomicsDB. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +L'output di questa fase è effettivamente una directory contenente un insieme di ulteriori directory nidificate che contengono i dati di varianti combinati sotto forma di più file diversi. +Può esplorarlo ma vedrà rapidamente che questo formato di archivio dati non è destinato a essere letto direttamente dagli esseri umani. + +!!! note + + GATK include strumenti che rendono possibile ispezionare ed estrarre dati di chiamate di varianti dall'archivio dati secondo necessità. + +#### 0.3.2. Eseguire l'analisi di genotipizzazione congiunta vera e propria + +Questa seconda fase utilizza un altro strumento GATK, chiamato GenotypeGVCFs, per ricalcolare le statistiche delle varianti e i genotipi individuali alla luce dei dati disponibili in tutti i campioni della coorte. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +Questo crea il file di output VCF `family_trio.vcf` nella directory di lavoro corrente nel container. +È un altro file ragionevolmente piccolo quindi potete visualizzare questo file con `cat` per vederne il contenuto, e scorrere verso l'alto per trovare le prime righe di varianti. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Questo assomiglia di più al VCF originale che abbiamo generato nella Parte 1, tranne che questa volta abbiamo informazioni a livello di genotipo per tutti e tre i campioni. +Le ultime tre colonne nel file sono i blocchi di genotipo per i campioni, elencati in ordine alfabetico. + +Se guardiamo ai genotipi chiamati per il nostro trio familiare di test per la primissima variante, vediamo che il padre è eterozigote-variante (`0/1`), e la madre e il figlio sono entrambi omozigoti-variante (`1/1`). + +Questa è in definitiva l'informazione che stiamo cercando di estrarre dal dataset! Quindi andiamo a incorporare tutto questo in un workflow Nextflow in modo da poterlo fare su larga scala. + +#### 0.3.3. Uscire dal container GATK + +```bash +exit +``` + +### Takeaway + +Sa come eseguire i singoli comandi coinvolti nella chiamata congiunta delle varianti nel terminale per verificare che producano le informazioni desiderate. + +### Quali sono i prossimi passi? + +Incorporare questi comandi in una pipeline vera e propria. + +--- + +## 1. Modificare il passo di chiamata delle varianti per campione per produrre un GVCF + +La buona notizia è che non dobbiamo ricominciare da zero, poiché abbiamo già scritto un workflow che fa parte di questo lavoro nella Parte 1. +Tuttavia, quella pipeline produce file VCF, mentre ora vogliamo file GVCF per fare la genotipizzazione congiunta. +Quindi dobbiamo iniziare attivando la modalità di chiamata delle varianti GVCF e aggiornando l'estensione del file di output. + +!!! note + + Per convenienza, lavoreremo con una copia fresca del workflow GATK come si presenta alla fine della Parte 1, ma con un nome diverso: `genomics-2.nf`. + +### 1.1. Dire a HaplotypeCaller di emettere un GVCF e aggiornare l'estensione di output + +Apriamo il file `genomics-2.nf` nell'editor di codice. +Dovrebbe apparire molto familiare, ma si senta libero di eseguirlo se vuole accertarsi che funzioni come previsto. + +Inizieremo facendo due modifiche: + +- Aggiungere il parametro `-ERC GVCF` al comando GATK HaplotypeCaller; +- Aggiornare il percorso del file di output per utilizzare l'estensione corrispondente `.g.vcf`, secondo la convenzione GATK. + +Assicuratevi di aggiungere una barra rovesciata (`\`) alla fine della riga precedente quando aggiunge `-ERC GVCF`. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +E questo è tutto ciò che serve per passare HaplotypeCaller alla generazione di GVCF invece di VCF, giusto? + +### 1.2. Eseguire la pipeline per verificare che si possano generare GVCF + +Il comando di esecuzione Nextflow è lo stesso di prima, salvo per il nome del file del workflow stesso. +Assicuratevi di aggiornarlo appropriatamente. + +```bash +nextflow run genomics-2.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +E l'output è... tutto rosso! Oh no. + +Il comando che è stato eseguito è corretto, quindi avevamo ragione sul fatto che quello fosse sufficiente per cambiare il comportamento dello strumento GATK. +Ma guardi quella riga sul file di output mancante. Nota qualcosa? + +Esatto, abbiamo dimenticato di dire a Nextflow di aspettarsi un nuovo nome di file. Ops. + +### 1.3. Aggiornare l'estensione del file di output anche nel blocco degli output del processo + +Perché non è sufficiente cambiare solo l'estensione del file nel comando dello strumento stesso, bisogna anche dire a Nextflow che il nome del file di output previsto è cambiato. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Aggiornare i target di pubblicazione per i nuovi output GVCF + +Poiché ora stiamo producendo GVCF invece di VCF, dovremmo aggiornare la sezione `publish:` del workflow per utilizzare nomi più descrittivi. +Organizzeremo anche i file GVCF nella loro sottodirectory per chiarezza. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Aggiornare il blocco output per la nuova struttura di directory + +Dobbiamo anche aggiornare il blocco `output` per mettere i file GVCF in una sottodirectory `gvcf`. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Eseguire nuovamente la pipeline + +Eseguiamola con `-resume` questa volta. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Questa volta funziona. + +L'output di Nextflow stesso non appare diverso (rispetto a un'esecuzione riuscita in modalità VCF normale), ma ora possiamo trovare i file `.g.vcf` e i rispettivi file di indice, per tutti e tre i campioni, organizzati in sottodirectory. + +??? abstract "Contenuto della directory (symlink abbreviati)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Se apre uno dei file GVCF e lo scorre, potete verificare che GATK HaplotypeCaller abbia prodotto file GVCF come richiesto. + +### Takeaway + +Ok, questo è stato minimo in termini di apprendimento di Nextflow... +Ma è stata una bella opportunità per ribadire l'importanza del blocco di output del processo! + +### Quali sono i prossimi passi? + +Imparare a raccogliere il contenuto di un canale e trasmetterlo al processo successivo come singolo input. + +--- + +## 2. Raccogliere e combinare i dati GVCF su tutti i campioni + +Ora dobbiamo combinare i dati di tutti i GVCF per campione in una forma che supporti l'analisi di genotipizzazione congiunta che vogliamo fare. + +### 2.1. Definire il processo che combinerà i GVCF + +Come promemoria di ciò che abbiamo fatto in precedenza nella sezione di riscaldamento, combinare i GVCF è un compito per lo strumento GATK GenomicsDBImport, che produrrà un archivio dati nel cosiddetto formato GenomicsDB. + +Scriviamo un nuovo processo per definire come funzionerà, basato sul comando che abbiamo usato in precedenza nella sezione di riscaldamento. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Combinare i GVCF in un archivio dati GenomicsDB + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +Cosa ne pensa, sembra ragionevole? + +Colleghiamolo e vediamo cosa succede. + +### 2.2. Aggiungere un parametro `cohort_name` con un valore predefinito + +Dobbiamo fornire un nome arbitrario per la coorte. +Più avanti nella serie di formazione imparerà come utilizzare i metadati dei campioni per questo tipo di cosa, ma per ora dichiariamo semplicemente un parametro CLI usando `params` e diamogli un valore predefinito per convenienza. + +```groovy title="genomics-2.nf" linenums="16" + // Nome base per il file di output finale + cohort_name: String = "family_trio" +``` + +### 2.3. Raccogliere gli output di GATK_HAPLOTYPECALLER attraverso i campioni + +Se dovessimo semplicemente collegare il canale di output dal processo `GATK_HAPLOTYPECALLER` così com'è, Nextflow chiamerebbe il processo su ciascun GVCF del campione separatamente. +Tuttavia, vogliamo raggruppare tutti e tre i GVCF (e i loro file di indice) in modo tale che Nextflow li consegni tutti insieme a una singola chiamata di processo. + +Buone notizie: possiamo farlo usando l'operatore di canale `collect()`. Aggiungiamo le seguenti righe al corpo del `workflow`, subito dopo la chiamata a GATK_HAPLOTYPECALLER: + +```groovy title="genomics-2.nf" linenums="118" +// Raccogliere gli output di chiamata delle varianti attraverso i campioni +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Sembra un po' complicato? Scomponiamolo e traduciamolo in linguaggio semplice. + +1. Stiamo prendendo il canale di output dal processo `GATK_HAPLOTYPECALLER`, a cui si fa riferimento usando la proprietà `.out`. +2. Ogni 'elemento' che esce dal canale è una coppia di file: il GVCF e il suo file di indice, in quest'ordine perché è l'ordine in cui sono elencati nel blocco di output del processo. Convenientemente, poiché nell'ultima sessione abbiamo nominato gli output di questo processo (usando `emit:`), possiamo selezionare i GVCF da un lato aggiungendo `.vcf` e i file di indice dall'altro aggiungendo `.idx` dopo la proprietà `.out`. Se non avessimo nominato quegli output, avremmo dovuto fare riferimento ad essi rispettivamente con `.out[0]` e `.out[1]`. +3. Aggiungiamo l'operatore di canale `collect()` per raggruppare tutti i file GVCF insieme in un singolo elemento in un nuovo canale chiamato `all_gvcfs_ch`, e facciamo lo stesso con i file di indice per formare il nuovo canale chiamato `all_idxs_ch`. + +!!! tip + + Se avete difficoltà a visualizzare esattamente cosa sta succedendo qui, ricordate che potete utilizzare l'operatore `view()` per ispezionare il contenuto dei canali prima e dopo l'applicazione degli operatori di canale. + +I canali risultanti `all_gvcfs_ch` e `all_idxs_ch` sono ciò che collegheremo al processo `GATK_GENOMICSDB` che abbiamo appena scritto. + +!!! note + + Nel caso si stesse chiedendo, raccogliamo i GVCF e i loro file di indice separatamente perché il comando GATK GenomicsDBImport vuole vedere solo i percorsi dei file GVCF. Fortunatamente, poiché Nextflow organizzerà tutti i file insieme per l'esecuzione, non dobbiamo preoccuparci dell'ordine dei file come abbiamo fatto per i BAM e il loro indice nella Parte 1. + +### 2.4. Aggiungere una chiamata al blocco workflow per eseguire GATK_GENOMICSDB + +Abbiamo un processo e abbiamo canali di input. Dobbiamo solo aggiungere la chiamata al processo. + +```groovy title="genomics-2.nf" linenums="122" + // Combinare i GVCF in un archivio dati GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, tutto è collegato. + +### 2.5. Eseguire il workflow + +Vediamo se funziona. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Viene eseguito abbastanza rapidamente, poiché stiamo eseguendo con `-resume`, ma fallisce! + +Ah. Dal lato positivo, vediamo che Nextflow ha rilevato il processo `GATK_GENOMICSDB`, e in particolare lo ha chiamato solo una volta. +Ciò suggerisce che l'approccio `collect()` ha funzionato, fino a un certo punto. +Ma, ed è un grande ma, la chiamata al processo è fallita. + +Quando approfondiamo l'output della console sopra, possiamo vedere che il comando eseguito non è corretto. + +Riesce a individuare l'errore? +Guardi questo bit: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Abbiamo dato a `gatk GenomicsDBImport` più file GVCF per un singolo argomento `-V`, ma lo strumento si aspetta un argomento `-V` separato per ciascun file GVCF. + +Come promemoria, questo era il comando che abbiamo eseguito nel container: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Quindi significa che dobbiamo in qualche modo trasformare il nostro pacchetto di file GVCF in una stringa di comando formattata correttamente. + +### 2.6. Costruire una riga di comando con un argomento `-V` separato per ciascun GVCF di input + +È qui che Nextflow essendo basato su Groovy torna utile, perché ci permetterà di utilizzare alcune manipolazioni di stringhe abbastanza semplici per costruire la stringa di comando necessaria. + +Specificamente, usando questa sintassi: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ancora una volta, scomponiamolo nei suoi componenti. + +1. Prima, prendiamo il contenuto del canale di input `all_gvcfs` e applichiamo `.collect()` su di esso (proprio come prima). +2. Ciò ci consente di passare ciascun percorso di file GVCF individuale nel pacchetto alla **closure**, `{ gvcf -> "-V ${gvcf}" }`, dove `gvcf` si riferisce a quel percorso di file GVCF. + La closure è una mini-funzione che usiamo per anteporre `-V ` al percorso del file, nella forma di `"-V ${gvcf}"`. +3. Quindi usiamo `.join(' ')` per concatenare tutte e tre le stringhe con un singolo spazio come separatore. + +Con un esempio concreto, appare così: + +1. Abbiamo tre file: + + `[A.ext, B.ext, C.ext]` + +2. La closure modifica ciascuno per creare le stringhe: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. L'operazione `.join(' ')` genera la stringa finale: + + `"-V A.ext -V B.ext -V C.ext"` + +Una volta che abbiamo quella stringa, possiamo assegnarla a una variabile locale, `gvcfs_line`, definita con la parola chiave `def`: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, quindi abbiamo la nostra cosa di manipolazione delle stringhe. Dove la mettiamo? + +Vogliamo che questo vada da qualche parte all'interno della definizione del processo, perché vogliamo farlo _dopo_ aver canalizzato i percorsi dei file GVCF nel processo. +Questo perché Nextflow deve vederli come percorsi di file per organizzare i file stessi correttamente per l'esecuzione. + +Ma _dove_ nel processo possiamo aggiungere questo? + +Fatto divertente: potete aggiungere codice arbitrario dopo `script:` e prima del `"""` ! + +Ottimo, aggiungiamo la nostra riga di manipolazione delle stringhe lì allora, e aggiorniamo il comando `gatk GenomicsDBImport` per utilizzare la stringa concatenata che produce. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Questo dovrebbe essere tutto ciò che è necessario per fornire correttamente gli input a `gatk GenomicsDBImport`. + +!!! tip + + Quando aggiorna il comando `gatk GenomicsDBImport`, assicuratevi di rimuovere il prefisso `-V ` quando sostituisce con la variabile `${gvcfs_line}`. + +### 2.7. Eseguire il workflow per verificare che generi l'output GenomicsDB come previsto + +Va bene, vediamo se questo ha risolto il problema. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha! Sembra funzionare ora. + +I primi due passi sono stati saltati con successo, e il terzo passo ha funzionato perfettamente questa volta. +L'archivio dati GenomicsDB viene creato nella directory di lavoro ma non pubblicato nei risultati, poiché è solo un formato intermedio che useremo per la genotipizzazione congiunta. + +Tra l'altro, non abbiamo dovuto fare nulla di speciale per gestire l'output che è una directory invece di un singolo file. + +### Takeaway + +Ora sa come raccogliere output da un canale e raggrupparli come singolo input a un altro processo. +Sa anche come costruire una riga di comando per fornire input a un determinato strumento con la sintassi appropriata. + +### Quali sono i prossimi passi? + +Imparare come aggiungere un secondo comando allo stesso processo. + +--- + +## 3. Eseguire il passo di genotipizzazione congiunta come parte dello stesso processo + +Ora che abbiamo le chiamate di varianti genomiche combinate, possiamo eseguire lo strumento di genotipizzazione congiunta, che produrrà l'output finale che ci interessa veramente: il VCF delle chiamate di varianti a livello di coorte. + +Per ragioni logistiche, decidiamo di includere la genotipizzazione congiunta all'interno dello stesso processo. + +### 3.1. Rinominare il processo da GATK_GENOMICSDB a GATK_JOINTGENOTYPING + +Poiché il processo eseguirà più di uno strumento, cambiamo il suo nome per fare riferimento all'operazione complessiva piuttosto che a un singolo nome di strumento. + +=== "Dopo" + + ```groovy title="genomics-2.nf" + /* + * Combinare i GVCF in un archivio dati GenomicsDB ed eseguire la genotipizzazione congiunta per produrre chiamate a livello di coorte + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" + /* + * Combinare i GVCF in un archivio dati GenomicsDB + */ + process GATK_GENOMICSDB { + ``` + +Ricordi di mantenere i nomi dei vostri processi il più descrittivi possibile, per massimizzare la leggibilità per i vostri colleghi — e il vostro futuro sé! + +### 3.2. Aggiungere il comando di genotipizzazione congiunta al processo GATK_JOINTGENOTYPING + +Semplicemente aggiunga il secondo comando dopo il primo all'interno della sezione script. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +I due comandi verranno eseguiti in serie, nello stesso modo in cui lo farebbero se dovessimo eseguirli manualmente nel terminale. + +### 3.3. Aggiungere i file del genoma di riferimento alle definizioni di input del processo GATK_JOINTGENOTYPING + +Il secondo comando richiede i file del genoma di riferimento, quindi dobbiamo aggiungerli agli input del processo. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Può sembrare fastidioso digitarli, ma ricordi, li digita una volta, e poi potete eseguire il workflow un milione di volte. Ne vale la pena? + +### 3.4. Aggiornare la definizione di output del processo per emettere il VCF delle chiamate di varianti a livello di coorte + +Non ci interessa veramente salvare l'archivio dati GenomicsDB, che è solo un formato intermedio che esiste solo per ragioni logistiche, quindi possiamo semplicemente rimuoverlo dal blocco di output se vogliamo. + +L'output a cui siamo effettivamente interessati è il VCF prodotto dal comando di genotipizzazione congiunta. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Abbiamo quasi finito! + +### 3.5. Aggiornare la chiamata al processo da GATK_GENOMICSDB a GATK_JOINTGENOTYPING + +Non dimentichiamo di rinominare la chiamata al processo nel corpo del workflow da GATK_GENOMICSDB a GATK_JOINTGENOTYPING. E mentre ci siamo, dovremmo anche aggiungere i file del genoma di riferimento come input, poiché dobbiamo fornirli allo strumento di genotipizzazione congiunta. + +=== "Dopo" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinare i GVCF in un archivio dati GenomicsDB e applicare la genotipizzazione congiunta + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Prima" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinare i GVCF in un archivio dati GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Ora il processo è completamente collegato. + +### 3.6. Aggiungere il VCF congiunto alla sezione publish + +Dobbiamo pubblicare gli output del VCF congiunto dal nuovo processo. +Aggiunga queste righe alla sezione `publish:` del workflow: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Aggiungere i target del VCF congiunto al blocco output + +Infine, aggiunga target di output per i file VCF congiunti. +Li metteremo alla radice della directory dei risultati poiché questo è l'output finale. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Ora tutto dovrebbe essere completamente collegato. + +### 3.8. Eseguire il workflow + +Finalmente, possiamo eseguire il workflow modificato... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +E funziona! + +Troverà il file di output finale, `family_trio.joint.vcf` (e il suo indice di file), nella directory dei risultati. + +??? abstract "Contenuto della directory (symlink abbreviati)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Se è del tipo scettico, potete fare clic sul file VCF congiunto per aprirlo e verificare che il workflow abbia generato le stesse chiamate di varianti che avete ottenuto eseguendo gli strumenti manualmente all'inizio di questa sezione. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Ora ha un workflow di chiamata congiunta delle varianti automatizzato, completamente riproducibile! + +!!! note + + Tenga presente che i file di dati che Le abbiamo fornito coprono solo una piccola porzione del cromosoma 20. + La dimensione reale di un set di chiamate di varianti sarebbe contata in milioni di varianti. + Ecco perché usiamo solo piccoli sottoinsiemi di dati per scopi formativi! + +### Takeaway + +Sa come utilizzare alcuni operatori comuni così come le closure di Groovy per controllare il flusso di dati nel vostro workflow. + +### Quali sono i prossimi passi? + +Celebrate il vostro successo e prendetevi una meritata pausa. + +Nella prossima parte di questo corso, imparerà come modularizzare il vostro workflow estraendo le definizioni dei processi in moduli riutilizzabili. diff --git a/docs/it/docs/nf4_science/genomics/03_modules.md b/docs/it/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..822a685a0b --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Parte 3: Spostare il codice in moduli + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella prima parte di questo corso, avete costruito una pipeline di variant calling completamente lineare che processava i dati di ciascun campione indipendentemente dagli altri. + +Nella seconda parte, Le abbiamo mostrato come utilizzare i canali e gli operatori di canale per implementare il joint variant calling con GATK, costruendo sulla pipeline della Parte 1. + +In questa parte, Le mostreremo come convertire il codice in quel workflow in moduli. Per seguire questa parte della formazione, dovrebbe aver completato la Parte 1 e la Parte 2, così come [Hello Modules](../../../hello_nextflow/hello_modules.md), che copre le basi dei moduli. + +--- + +## 0. Preparazione + +Quando abbiamo iniziato a sviluppare il nostro workflow, abbiamo inserito tutto in un unico file di codice. +Ora è il momento di affrontare la **modularizzazione** del nostro codice, _cioè_ estrarre le definizioni dei processi in moduli. + +Inizieremo con lo stesso workflow della Parte 2, che Le abbiamo fornito nel file `genomics-3.nf`. + +!!! note "Nota" + + Assicuratevi di essere nella directory di lavoro corretta: + `cd /workspaces/training/nf4-science/genomics` + +Esegua il workflow per verificare il punto di partenza: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Output" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Ora ci sarà una directory `work` e una directory `results_genomics` all'interno della vostra directory di progetto. + +### Takeaway + +È pronto per iniziare a modularizzare il vostro workflow. + +### Prossimi passi + +Spostare i processi del workflow Genomics in moduli. + +--- + +## 1. Spostare i processi in moduli + +Come avete appreso in [Hello Modules](../../../hello_nextflow/hello_modules.md), potete creare un modulo semplicemente copiando la definizione del processo in un proprio file, in qualsiasi directory, e potete nominare quel file come desiderate. + +Per motivi che diventeranno chiari più avanti (in particolare quando arriveremo ai test), in questa formazione seguiremo la convenzione di nominare il file `main.nf`, e posizionarlo in una struttura di directory denominata secondo il toolkit e il comando. + +### 1.1. Creare un modulo per il processo `SAMTOOLS_INDEX` + +Nel caso del processo `SAMTOOLS_INDEX`, 'samtools' è il toolkit e 'index' è il comando. Quindi, creeremo una struttura di directory `modules/samtools/index` e inseriremo la definizione del processo `SAMTOOLS_INDEX` nel file `main.nf` all'interno di quella directory. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Aprite il file `main.nf` e copi la definizione del processo `SAMTOOLS_INDEX` al suo interno. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * Genera il file indice BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Poi, rimuova la definizione del processo `SAMTOOLS_INDEX` da `genomics-3.nf`, e aggiunga una dichiarazione di importazione per il modulo prima della definizione del processo successivo, in questo modo: + +=== "Dopo" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Includi moduli + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Chiama varianti con GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Prima" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Chiama varianti con GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +Ora potete eseguire nuovamente il workflow, e dovrebbe continuare a funzionare nello stesso modo di prima. Se fornisce il flag `-resume`, non dovrebbe nemmeno essere necessario eseguire nuove attività: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Creare moduli per i processi `GATK_HAPLOTYPECALLER` e `GATK_JOINTGENOTYPING` + +Ripeta gli stessi passaggi per i processi rimanenti. +Per ciascun processo: + +1. Crei la struttura di directory (`modules/gatk/haplotypecaller/` e `modules/gatk/jointgenotyping/`) +2. Crei un file `main.nf` contenente la definizione del processo +3. Rimuova la definizione del processo da `genomics-3.nf` +4. Aggiunga una dichiarazione di importazione per il modulo + +Una volta terminato, verifichi che la struttura della directory dei moduli sia corretta eseguendo: + +```bash +tree modules/ +``` + +??? abstract "Contenuto della directory" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Dovrebbe anche avere qualcosa di simile nel file del workflow principale, dopo la sezione dei parametri: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Takeaway + +Ha praticato la modularizzazione di un workflow, con il workflow genomics come esempio. + +### Prossimi passi + +Testare il workflow modularizzato. + +--- + +## 2. Testare il workflow modularizzato + +Esegua il workflow modularizzato per verificare che tutto funzioni ancora. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Output" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Tutto funziona ancora, inclusa la capacità di riprendere la pipeline. +I risultati continuano ad essere pubblicati nella directory `results_genomics`. + +```console title="Contenuto della directory" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Takeaway + +Ha modularizzato un workflow e verificato che funzioni ancora nello stesso modo di prima. + +### Prossimi passi + +Rivedere ciò che avete appreso e guardare avanti ai test. + +--- + +## 3. Riepilogo + +Ha modularizzato il workflow, e nulla è cambiato nel modo in cui la pipeline funziona. +Questo è intenzionale: ha ristrutturato il codice senza impattare la sua funzione. + +I moduli contengono solo la logica del processo, rendendoli puliti e riutilizzabili. +Lo script principale controlla cosa viene pubblicato e dove, mentre i moduli rimangono focalizzati sulla loro attività computazionale. + +Ha posto le fondamenta per cose che renderanno il vostro codice più facile da mantenere. +Ad esempio, ora potete aggiungere test alla vostra pipeline utilizzando il framework nf-test. +Questo è ciò che esamineremo nella prossima parte di questo corso. diff --git a/docs/it/docs/nf4_science/genomics/04_testing.md b/docs/it/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..32a7aeab48 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Parte 4: Aggiunta di test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella prima parte di questo corso, avete costruito una pipeline di variant calling completamente lineare che processava i dati di ciascun campione indipendentemente dagli altri. + +Nella seconda parte, Le abbiamo mostrato come utilizzare i canali e gli operatori di canale per implementare il joint variant calling con GATK. + +Nella terza parte, abbiamo modularizzato la pipeline. + +In questa parte della formazione, Le mostreremo come utilizzare [**nf-test**](https://www.nf-test.com/), un framework di testing che si integra bene con Nextflow e rende semplice aggiungere test sia a livello di modulo che a livello di workflow alla vostra pipeline. Per seguire questa parte della formazione, dovrebbe aver completato la Parte 1, la Parte 2 e la Parte 3, nonché la [side quest su nf-test](../../side_quests/nf-test.md), che copre le basi di nf-test e il motivo per cui il testing è importante. + +--- + +## 0. Riscaldamento + +!!! note "Nota" + + Assicuratevi di essere nella directory di lavoro corretta: + `cd /workspaces/training/nf4-science/genomics` + +Se ha completato le parti precedenti di questo corso di formazione, dovrebbe avere una versione funzionante della pipeline genomics con l'appropriata struttura di directory dei moduli. + +??? abstract "Contenuti della directory" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Questa directory dei moduli può essere trovata nella directory `solutions` se ne avete bisogno. + +Inizieremo con lo stesso workflow della Parte 3, che Le abbiamo fornito nel file `genomics-4.nf`. Esattamente come per la [side quest su nf-test](../../side_quests/nf-test.md), aggiungeremo alcuni tipi diversi di test ai tre processi in questa pipeline, nonché un test a livello di workflow. + +### 0.1. Verificare che il workflow funzioni + +Prima di iniziare ad aggiungere test, assicuratevi che il workflow funzioni come previsto. + +```bash +nextflow run genomics-4.nf -resume +``` + +Questo dovrebbe sembrare molto familiare ormai se avete seguito questo corso di formazione dall'inizio. + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Come in precedenza, ci sarà ora una directory `work` e una directory `results_genomics` all'interno della vostra directory di progetto. Utilizzeremo effettivamente questi risultati più avanti nei nostri test. Ma da ora in poi utilizzeremo il pacchetto `nf-test` per testare la pipeline. + +### 0.2. Inizializzare `nf-test` + +Come per la [side quest su nf-test](../../side_quests/nf-test.md), dobbiamo inizializzare il pacchetto `nf-test`. + +```bash +nf-test init +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "Contenuti di nf-test.config" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Crea anche una directory `tests` contenente uno stub del file di configurazione. + +### Takeaway + +Ora siamo pronti per iniziare a scrivere test per la nostra pipeline genomics. + +### Quali sono i prossimi passi? + +Scrivere test di base che valutano se le chiamate ai processi sono riuscite e hanno prodotto gli output corretti. + +--- + +## 1. Testare un processo per successo e corrispondenza degli output + +Inizieremo testando il processo `SAMTOOLS_INDEX`, che crea file indice per i file BAM per consentire un accesso casuale efficiente. Questo è un buon primo caso di test perché: + +1. Ha un singolo input ben definito (un file BAM) +2. Produce un output prevedibile (un file indice BAI) +3. L'output dovrebbe essere identico per input identici + +### 1.1. Generare uno stub del file di test + +Prima, generiamo uno stub del file di test: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Output del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Questo crea un file nella stessa directory di `main.nf`. +Può navigare alla directory nel file explorer e aprire il file, che dovrebbe contenere il seguente codice: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Le asserzioni iniziali dovrebbero essere familiari dalla [side quest su nf-test](../../side_quests/nf-test.md): + +- `assert process.success` afferma che ci aspettiamo che il processo venga eseguito con successo e si completi senza errori. +- `snapshot(process.out).match()` afferma che ci aspettiamo che il risultato dell'esecuzione sia identico al risultato ottenuto in un'esecuzione precedente (se applicabile). + Discuteremo questo in dettaglio più avanti. + +Utilizzando questo come punto di partenza, dobbiamo aggiungere gli input di test corretti per il processo samtools index, e qualsiasi parametro se applicabile. + +### 1.2. Spostare il file di test e aggiornare il percorso dello script + +Prima di metterci al lavoro per compilare il test, dobbiamo spostare il file nella sua posizione definitiva. Parte del motivo per cui abbiamo aggiunto una directory per ciascun modulo è che ora possiamo fornire i test in una directory `tests` co-localizzata con il file `main.nf` di ciascun modulo. Crei quella directory e sposti il file di test lì. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Ora possiamo semplificare la sezione `script` del file di test con un percorso relativo: + +=== "Dopo" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Prima" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Questo indica al test dove trovare il file `main.nf` del modulo, senza dover specificare il percorso completo. + +### 1.3. Fornire input di test per SAMTOOLS_INDEX + +Il file stub include un segnaposto che dobbiamo sostituire con un input di test effettivo, appropriato all'input di `samtools index`. L'input appropriato è un file BAM, che abbiamo disponibile nella directory `data/bam`. + +=== "Dopo" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Prima" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Denominare il test in base alla funzionalità + +Come abbiamo appreso in precedenza, è buona pratica rinominare il test con qualcosa che abbia senso nel contesto del test. + +=== "Dopo" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Questo accetta una stringa arbitraria, quindi potremmo inserire qualsiasi cosa vogliamo. + Qui scegliamo di fare riferimento al nome del file e al suo formato. + +=== "Prima" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Eseguire il test ed esaminare l'output + +Esegua il test: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Come abbiamo appreso in precedenza, questo ha verificato l'asserzione di base sul successo del processo e ha creato un file snapshot basato sull'output del processo. Possiamo vedere i contenuti del file snapshot nel file `tests/modules/samtools/index/tests/main.nf.test.snap`: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Possiamo anche eseguire nuovamente il test e vedere che passa, perché l'output è identico allo snapshot: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Aggiungere più test a `SAMTOOLS_INDEX` + +A volte è utile testare una gamma di file di input diversi per assicurarsi di testare una varietà di potenziali problemi. Aggiunga test per i file BAM della madre e del padre nel trio dei nostri dati di test. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Quindi potete eseguire nuovamente il test: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Noti l'avviso, che si riferisce all'effetto del parametro `--update-snapshot`. + +!!! note "Nota" + + Qui stiamo utilizzando dati di test che abbiamo usato in precedenza per dimostrare gli output scientifici della pipeline. + Se avessimo pianificato di utilizzare questi test in un ambiente di produzione, avremmo generato input più piccoli per scopi di testing. + + In generale è importante mantenere i test unitari il più leggeri possibile utilizzando i pezzi di dati più piccoli necessari e sufficienti per valutare la funzionalità del processo, altrimenti il tempo di esecuzione totale può accumularsi in modo significativo. + Una suite di test che richiede troppo tempo per essere eseguita regolarmente è una suite di test che probabilmente verrà saltata nell'interesse della rapidità. + +### Takeaway + +Ha scritto il vostro primo test di modulo per un processo genomics, verificando che `SAMTOOLS_INDEX` crei correttamente file indice per diversi file BAM. La suite di test garantisce che: + +1. Il processo venga eseguito con successo +2. I file indice vengano creati +3. Gli output siano coerenti tra le esecuzioni +4. Il processo funzioni per tutti i file BAM dei campioni + +### Quali sono i prossimi passi? + +Imparare a scrivere test per altri processi nel nostro workflow genomics, utilizzando il metodo setup per gestire processi concatenati. Valuteremo anche se gli output, in particolare i nostri file VCF, contengono le chiamate di varianti attese. + +--- + +## 2. Aggiungere test a un processo concatenato e testare i contenuti + +Per testare `GATK_HAPLOTYPECALLER`, dobbiamo fornire al processo l'output di `SAMTOOLS_INDEX` come input. Potremmo farlo eseguendo `SAMTOOLS_INDEX`, recuperando i suoi output e memorizzandoli con i dati di test per il workflow. Questo è in realtà l'approccio raccomandato per una pipeline rifinita, ma nf-test fornisce un approccio alternativo, utilizzando il metodo `setup`. + +Con il metodo setup, possiamo attivare il processo `SAMTOOLS_INDEX` come parte della configurazione del test, e quindi utilizzare il suo output come input per `GATK_HAPLOTYPECALLER`. Questo ha un costo: dovremo eseguire il processo `SAMTOOLS_INDEX` ogni volta che eseguiamo il test per `GATK_HAPLOTYPECALLER`. Tuttavia, forse stiamo ancora sviluppando il workflow e non vogliamo pre-generare dati di test che potremmo dover cambiare successivamente. Il processo `SAMTOOLS_INDEX` è anche molto veloce, quindi forse i benefici di pre-generare e memorizzare i suoi output sono trascurabili. Ecco come funziona il metodo setup. + +### 2.1. Generare e posizionare il file di test + +Come in precedenza, prima generiamo lo stub del file: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Output del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Questo produce il seguente stub di test: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Spostare il file di test e aggiornare il percorso dello script + +Creiamo una directory per il file di test co-localizzata con il file `main.nf` del modulo: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +E spostiamo il file stub di test lì: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Infine, non dimentichi di aggiornare il percorso dello script: + +=== "Dopo" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Prima" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Fornire input utilizzando il metodo setup + +Inseriamo un blocco `setup` prima del blocco `when`, dove possiamo attivare un'esecuzione del processo `SAMTOOLS_INDEX` su uno dei nostri file di input originali. Inoltre, ricordate come prima di cambiare il nome del test in qualcosa di significativo. + +=== "Dopo" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Prima" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Quindi possiamo fare riferimento all'output di quel processo nel blocco `when` dove specifichiamo gli input del test: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Effettuate quella modifica ed eseguite nuovamente il test: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Produce anche un file snapshot come prima. + +### 2.4. Eseguire nuovamente e osservare il fallimento + +Interessante, se esegue esattamente lo stesso comando di nuovo, questa volta il test fallirà. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +Il messaggio di errore Le indica che c'erano differenze tra gli snapshot per le due esecuzioni; in particolare, i valori md5sum sono diversi per i file VCF. + +Perché? Per farla breve, lo strumento HaplotypeCaller include un timestamp nell'intestazione del VCF che è diverso ogni volta (per definizione). +Di conseguenza, non possiamo semplicemente aspettarci che i file abbiano md5sum identici anche se hanno contenuti identici in termini delle chiamate di varianti stesse. + +Come affrontiamo questo? + +### 2.5. Utilizzare un metodo di asserzione del contenuto per verificare una variante specifica + +Un modo per risolvere il problema è utilizzare un [diverso tipo di asserzione](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions). +In questo caso, verificheremo un contenuto specifico invece di asserire l'identità. +Più esattamente, faremo leggere allo strumento le righe del file VCF e verificheremo l'esistenza di righe specifiche. + +In pratica, sostituiamo la seconda asserzione nel blocco `then` come segue: + +=== "Dopo" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Prima" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Qui stiamo leggendo l'intero contenuto del file di output VCF e cercando una corrispondenza di contenuto, il che va bene su un piccolo file di test, ma non vorrebbe farlo su un file più grande. +Potrebbe invece scegliere di leggere righe specifiche. + +Questo approccio richiede di scegliere più attentamente cosa vogliamo usare come 'segnale' da testare. +Il lato positivo è che può essere usato per testare con grande precisione se uno strumento di analisi può identificare in modo coerente caratteristiche 'difficili' (come varianti rare) mentre subisce ulteriore sviluppo. + +### 2.6. Eseguire nuovamente e osservare il successo + +Una volta che abbiamo modificato il test in questo modo, possiamo eseguire il test più volte, e passerà costantemente. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Aggiungere più test + +Aggiunga test simili per i campioni della madre e del padre: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Eseguire il comando di test + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Questo completa il piano di test di base per questo secondo passaggio nella pipeline. Avanti verso il terzo e ultimo test a livello di modulo! + +### Takeaway + +Ha imparato a: + +1. Testare processi che dipendono da output di altri processi +2. Verificare varianti genomiche specifiche nei file di output VCF +3. Gestire output non deterministici verificando contenuti specifici +4. Testare il variant calling su più campioni + +### Quali sono i prossimi passi? + +Imparare a scrivere test che utilizzano dati di test pre-generati per il passaggio di joint genotyping. + +--- + +## 3. Utilizzare dati di test pre-generati + +Per il passaggio di joint genotyping, utilizzeremo un approccio diverso - utilizzando dati di test pre-generati. Questo è spesso preferibile per: + +1. Processi complessi con più dipendenze +2. Processi che richiedono molto tempo per essere eseguiti +3. Processi che fanno parte di una pipeline stabile e di produzione + +### 3.1. Generare dati di test + +Ispezioni i risultati che abbiamo generato all'inizio di questa sezione: + +```bash +tree results_genomics/ +``` + +```console title="Contenuti della directory dei risultati" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +Il passaggio di joint genotyping necessita dei file VCF prodotti dai passaggi di haplotype caller come input, insieme agli indici. Quindi copiamo i risultati che abbiamo nella directory di test del modulo `jointgenotyping`. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Ora possiamo utilizzare questi file come input per il test che stiamo per scrivere per il passaggio di joint genotyping. + +### 3.2. Generare lo stub del file di test + +Come in precedenza, prima generiamo lo stub del file: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Output del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Questo produce il seguente stub di test: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Spostare il file di test e aggiornare il percorso dello script + +Questa volta abbiamo già una directory per i test co-localizzata con il file `main.nf` del modulo, quindi possiamo spostare il file stub di test lì: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +E non dimentichi di aggiornare il percorso dello script: + +=== "Dopo" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Prima" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Fornire input + +Compili gli input in base alle definizioni degli input del processo e rinomini il test di conseguenza: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Utilizzare asserzioni di contenuto + +L'output del passaggio di joint genotyping è un altro file VCF, quindi utilizzeremo nuovamente un'asserzione di contenuto. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Verificando il contenuto di una variante specifica nel file di output, questo test verifica che: + +1. Il processo di joint genotyping venga eseguito con successo +2. L'output VCF contenga tutti e tre i campioni nell'ordine corretto +3. Una variante specifica sia chiamata correttamente con: + - Genotipi accurati per ciascun campione (0/1 per il padre, 1/1 per madre e figlio) + - Profondità di lettura e qualità dei genotipi corrette + - Statistiche a livello di popolazione come la frequenza allelica (AF=0.833) + +Non abbiamo fatto uno snapshot dell'intero file, ma verificando una variante specifica, possiamo essere sicuri che il processo di joint genotyping funzioni come previsto. + +### 3.6. Eseguire il test + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +Il test passa, verificando che il nostro processo di joint genotyping correttamente: + +1. Combina i VCF dei singoli campioni +2. Esegue il variant calling congiunto +3. Produce un VCF multi-campione con chiamate genotipiche coerenti tra le esecuzioni + +### Takeaway + +Sa come: + +- Utilizzare risultati generati in precedenza come input per i test +- Scrivere test utilizzando dati di test pre-generati + +### Quali sono i prossimi passi? + +Aggiungere un test a livello di workflow per verificare che l'intera pipeline di variant calling funzioni end-to-end. + +--- + +## 4. Aggiungere un test a livello di workflow + +Ora testeremo la pipeline completa di variant calling, dai file BAM ai genotipi congiunti. Questo verifica che: + +1. Tutti i processi funzionino correttamente insieme +2. I dati fluiscano correttamente tra i passaggi +3. Le chiamate di varianti finali siano coerenti + +### 4.1. Generare il test del workflow + +Generi un file di test per la pipeline completa: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Output del comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Questo crea uno stub di test di base: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Corregga solo il nome in qualcosa di significativo (vedrà perché questo è utile a breve). + +=== "Dopo" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Prima" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "Nota" + + In questo caso il file di test può rimanere dove `nf-test` l'ha creato. + +### 4.2. Specificare i parametri di input + +Dobbiamo ancora specificare gli input, il che viene fatto in modo leggermente diverso a livello di workflow rispetto ai test a livello di modulo. +Ci sono diversi modi per farlo, incluso specificando un profilo. +Tuttavia, un modo più semplice è configurare un blocco `params {}` nel file `nextflow.config` che `nf-test init` ha originariamente creato nella directory `tests`. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow config file for running tests +======================================================================================== +*/ + +// Output directory for workflow outputs +outputDir = 'results_genomics' + +/* + * Pipeline parameters + */ + +params { + // Input primario (file di file di input, uno per riga) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Accessory files + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Base name for final output file + cohort_name = "family_trio" +} +``` + +Quando eseguiamo il test, `nf-test` preleverà questo file di configurazione e caricherà gli input di conseguenza. + +### 4.3. Eseguire il test del workflow + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +Il test passa, confermando che la nostra pipeline completa di variant calling: + +1. Processa con successo tutti i campioni +2. Concatena correttamente tutti i passaggi + +### 4.4. Eseguire TUTTI i test + +nf-test ha un altro asso nella manica. Possiamo eseguire tutti i test contemporaneamente! Modifichi il file `nf-test.config` in modo che nf-test cerchi in ogni directory i file nf-test. Può farlo modificando il parametro `testsDir`: + +=== "Dopo" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Prima" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Ora, possiamo semplicemente eseguire nf-test e eseguirà _ogni singolo test_ nel nostro repository: + +```bash +nf-test test +``` + +??? success "Output del comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +8 test in 1 comando! Abbiamo speso molto tempo configurando molti test, ma quando è arrivato il momento di eseguirli è stato molto rapido e facile. Può vedere quanto sia utile quando si mantiene una grande pipeline, che potrebbe includere centinaia di elementi diversi. Spendiamo tempo scrivendo i test una volta così possiamo risparmiare tempo eseguendoli molte volte. + +Inoltre, possiamo automatizzare questo! Immagini che i test vengano eseguiti ogni volta che voi o un collega cerca di aggiungere nuovo codice. Questo è il modo in cui garantiamo che le nostre pipeline mantengano uno standard elevato. + +## Takeaway + +Ora sa come scrivere ed eseguire diversi tipi di test per la vostra pipeline genomics utilizzando nf-test. Questo framework di testing aiuta a garantire che il vostro workflow di variant calling produca risultati coerenti e affidabili in diversi ambienti e mentre apporta modifiche al codice. + +Ha imparato a testare componenti critici come: + +- Il processo `SAMTOOLS_INDEX` che prepara i file BAM per il variant calling +- Il processo `GATK_HAPLOTYPECALLER` che identifica varianti nei singoli campioni +- Il processo `GATK_JOINTGENOTYPING` che combina le chiamate di varianti attraverso una coorte + +Ha anche implementato diverse strategie di testing specifiche per i dati genomici: + +- Verificare che i file VCF contengano le chiamate di varianti attese nonostante elementi non deterministici come i timestamp +- Testare con un dataset di trio familiare per garantire la corretta identificazione delle varianti tra campioni correlati +- Verificare coordinate genomiche specifiche e informazioni sulle varianti nei vostri file di output + +Queste competenze di testing sono essenziali per sviluppare pipeline bioinformatiche robuste che possono processare in modo affidabile dati genomici e produrre chiamate di varianti accurate. Man mano che continua a lavorare con Nextflow per l'analisi genomica, questa base di testing La aiuterà a mantenere codice di alta qualità che produce risultati scientifici affidabili. diff --git a/docs/it/docs/nf4_science/genomics/05_configuration.md b/docs/it/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..a78cf75121 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Parte 3: Profilazione e ottimizzazione delle risorse + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +QUESTO È UN SEGNAPOSTO + +!!!note "Nota" + + Questo modulo di formazione è in fase di aggiornamento. + +--- + +TODO + +### 1.1. Eseguire il workflow per generare un report di utilizzo delle risorse + +Per fare in modo che Nextflow generi il report automaticamente, è sufficiente aggiungere `-with-report <filename>.html` alla riga di comando. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +Il report è un file html, che potete scaricare e aprire nel suo browser. Può anche fare clic con il tasto destro su di esso nell'esploratore file a sinistra e fare clic su `Show preview` per visualizzarlo in VS Code. + +Si prenda alcuni minuti per esaminare il report e verificare se riesce a identificare alcune opportunità per regolare le risorse. +Assicuratevi di fare clic sulle schede che mostrano i risultati di utilizzo come percentuale di ciò che è stato allocato. +È disponibile una [documentazione](https://www.nextflow.io/docs/latest/reports.html) che descrive tutte le funzionalità disponibili. + +<!-- TODO: insert images --> + +Un'osservazione è che `GATK_JOINTGENOTYPING` sembra richiedere molte risorse CPU, il che ha senso poiché esegue molti calcoli complessi. +Potremmo quindi provare ad aumentare questa risorsa e verificare se riduce i tempi di esecuzione. + +Tuttavia, sembra che abbiamo sovrastimato le allocazioni di memoria; tutti i processi stanno utilizzando solo una frazione di ciò che stiamo fornendo loro. +Dovremmo ridurre questa allocazione e risparmiare alcune risorse. + +### 1.2. Regolare le allocazioni di risorse per un processo specifico + +Possiamo specificare allocazioni di risorse per un determinato processo utilizzando il selettore di processo `withName`. +La sintassi appare così quando è da solo in un blocco process: + +```groovy title="Sintassi" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Aggiungiamo questo al blocco process esistente nel file `nextflow.config`. + +```groovy title="nextflow.config" linenums="11" +process { + // impostazioni predefinite per tutti i processi + cpus = 2 + memory = 2.GB + // allocazioni per un processo specifico + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Con questa specifica, le impostazioni predefinite si applicheranno a tutti i processi **eccetto** il processo `GATK_JOINTGENOTYPING`, che è un caso particolare che riceve molte più CPU. +Speriamo che questo abbia un effetto. + +### 1.3. Eseguire nuovamente con la configurazione modificata + +Eseguiamo il workflow nuovamente con la configurazione modificata e con il flag di reporting attivato, ma notiamo che stiamo dando al report un nome diverso in modo da poterli differenziare. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Ancora una volta, probabilmente non noterà una differenza sostanziale nei tempi di esecuzione, perché questo è un carico di lavoro così ridotto e gli strumenti trascorrono più tempo in attività accessorie che nell'eseguire il lavoro 'reale'. + +Tuttavia, il secondo report mostra che il nostro utilizzo delle risorse è ora più equilibrato. + +<!-- **TODO: screenshots?** --> + +Come potete vedere, questo approccio è utile quando i vostri processi hanno requisiti di risorse diversi. Le permette di dimensionare correttamente le allocazioni di risorse che configura per ciascun processo in base a dati effettivi, non a ipotesi. + +!!!note "Nota" + + Questo è solo un piccolo assaggio di ciò che potete fare per ottimizzare l'utilizzo delle risorse. + Nextflow stesso ha una [logica di retry dinamica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) davvero interessante integrata per riprovare le attività che falliscono a causa di limitazioni di risorse. + Inoltre, Seqera Platform offre strumenti basati su AI per ottimizzare le allocazioni di risorse automaticamente. + + Tratteremo entrambi questi approcci in una prossima parte di questo corso di formazione. + +Detto questo, potrebbero esserci alcuni vincoli su ciò che può (o deve) allocare a seconda dell'executor di calcolo e dell'infrastruttura di calcolo che state utilizzando. Ad esempio, il vostro cluster potrebbe richiedere di rimanere entro determinati limiti che non si applicano quando si esegue altrove. diff --git a/docs/it/docs/nf4_science/genomics/index.md b/docs/it/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..fb3722a715 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/index.md @@ -0,0 +1,42 @@ +--- +title: Nextflow per la Genomica +hide: + - toc +--- + +# Nextflow per la Genomica + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questo corso di formazione è destinato ai ricercatori nel campo della genomica e settori correlati che sono interessati a sviluppare o personalizzare pipeline di analisi dei dati. +Si basa sulla formazione per principianti [Hello Nextflow](../../hello_nextflow/) e dimostra come utilizzare Nextflow nel contesto specifico del dominio della genomica. + +In particolare, questo corso dimostra come implementare una semplice pipeline di variant calling con [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit), un pacchetto software ampiamente utilizzato per analizzare dati di sequenziamento ad alto rendimento. + +Cominciamo! Clicchi sul pulsante "Open in GitHub Codespaces" qui sotto per avviare l'ambiente di formazione (preferibilmente in una scheda separata), quindi continui a leggere durante il caricamento. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Obiettivi di apprendimento + +Seguendo questo corso, imparerà ad applicare concetti e strumenti fondamentali di Nextflow a un caso d'uso tipico della genomica. + +Al termine di questo workshop sarà in grado di: + +- Scrivere un workflow lineare per applicare il variant calling a un singolo campione +- Gestire appropriatamente file accessori come file indice e risorse del genoma di riferimento +- Sfruttare il paradigma di dataflow di Nextflow per parallelizzare il variant calling per campione +- Implementare il variant calling multi-campione utilizzando operatori di canale rilevanti +- Implementare test di pipeline per singolo passaggio e end-to-end che gestiscono appropriatamente le idiosincrasie specifiche della genomica + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Prerequisiti + +Il corso presuppone una familiarità minima con quanto segue: + +- Strumenti e formati di file comunemente utilizzati in questo dominio scientifico +- Esperienza con la riga di comando +- Concetti e strumenti fondamentali di Nextflow trattati nella formazione per principianti [Hello Nextflow](../../hello_nextflow/) + +Per i requisiti tecnici e la configurazione dell'ambiente, consulti il mini-corso [Configurazione dell'Ambiente](../../envsetup/). diff --git a/docs/it/docs/nf4_science/genomics/next_steps.md b/docs/it/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..b76135725e --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Prossimi Passi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni ancora per aver completato il corso di formazione Nextflow For Genomics e grazie per aver completato il nostro sondaggio! + +--- + +## 1. I 3 modi migliori per migliorare le vostre competenze in Nextflow + +Ecco le nostre tre raccomandazioni principali su cosa fare successivamente in base al corso che ha appena completato. + +### 1.1. Applicare Nextflow ad altri casi d'uso di analisi scientifica + +**Consulti la pagina [Nextflow for Science](../index.md)** per un elenco di altri brevi corsi autonomi che dimostrano come applicare i concetti e i meccanismi di base presentati in Hello Nextflow a casi d'uso comuni di analisi scientifica. + +Se non vede il vostro dominio rappresentato da un caso d'uso pertinente, fatecelo sapere nel [forum della Community](https://community.seqera.io/) in modo che possiamo aggiungerlo alla nostra lista di sviluppo. + +### 1.2. Iniziare con nf-core + +**[nf-core](https://nf-co.re/)** è uno sforzo collaborativo mondiale per sviluppare pipeline open-source standardizzate per un'ampia gamma di applicazioni di ricerca scientifica. +Il progetto include [oltre 100 pipeline](https://nf-co.re/pipelines/) disponibili per l'uso immediato e [ben oltre 1400 moduli di processo](https://nf-co.re/modules/) che possono essere integrati nei vostri progetti, oltre a un ricco set di strumenti per sviluppatori. + +Il corso di formazione **[Hello nf-core](../../hello_nf-core/index.md)** vi introdurrà alle pipeline curate dalla community nf-core e al framework di sviluppo, progettato per aiutarvi a scrivere flussi di lavoro riproducibili, scalabili e standardizzati. Imparerà come utilizzare le pipeline nf-core esistenti, contribuire al loro sviluppo e persino iniziare a costruire le vostre, supportato dalle migliori pratiche e da una community vivace. Se è pronto ad applicare le vostre competenze in Nextflow in progetti reali, questo è il passo successivo perfetto. + +### 1.3. Padroneggiare funzionalità più avanzate di Nextflow + +Nei corsi Hello, manteniamo intenzionalmente basso il livello di complessità tecnica per evitare di sovraccaricarvi con informazioni di cui non avete bisogno per iniziare con Nextflow. +Man mano che procede con il vostro lavoro, vorrà imparare come utilizzare l'intero set di funzionalità e la potenza di Nextflow. + +A tal fine, stiamo attualmente lavorando su una **raccolta di [Side Quests](../side_quests/index.md)**, che sono corsi autonomi brevi che approfondiscono argomenti specifici come i test e la gestione dei metadati. + +--- + +## 2. Esplorare Seqera Platform + +**[Seqera Platform](https://seqera.io/) è il modo migliore per eseguire Nextflow nella pratica.** + +È una piattaforma basata su cloud sviluppata dai creatori di Nextflow che potete connettere alla vostra infrastruttura di calcolo (che sia locale, HPC o cloud) per rendere molto più facile avviare e gestire i vostri flussi di lavoro, oltre a gestire i vostri dati ed eseguire analisi in modo interattivo in un ambiente cloud. + +Il Free Tier è disponibile per l'uso gratuito da parte di tutti (con quote di utilizzo). +Gli accademici qualificati possono ottenere accesso gratuito a livello Pro (nessuna limitazione di utilizzo) attraverso il [Programma Accademico](https://seqera.io/academic/program/). + +Dia un'occhiata ai [tutorial di Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) per vedere se questo potrebbe esserLe utile. + +--- + +### È tutto per ora! + +**Buona fortuna nel vostro percorso con Nextflow e non esitate a farci sapere nel [forum della Community](https://community.seqera.io/) cos'altro potremmo fare per aiutarvi.** diff --git a/docs/it/docs/nf4_science/genomics/survey.md b/docs/it/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..d2412799f3 --- /dev/null +++ b/docs/it/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Sondaggio di feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Prima di proseguire, completi questo breve sondaggio di 5 domande per valutare la formazione, condividere eventuali feedback sulla sua esperienza e farci sapere cos'altro potremmo fare per aiutarla nel suo percorso con Nextflow. + +Il completamento dovrebbe richiedere meno di un minuto. Grazie per aiutarci a migliorare i nostri materiali di formazione per tutti! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/it/docs/nf4_science/imaging/00_orientation.md b/docs/it/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..ce22a715c2 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questo orientamento presuppone che abbiate già aperto l'ambiente di formazione cliccando sul pulsante "Open in GitHub Codespaces". +Se non l'ha ancora fatto, Vi preghiamo di farlo ora, idealmente in una seconda finestra o scheda del browser in modo da poter consultare queste istruzioni. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Requisito dimensione macchina" + + Assicuratevi di selezionare una **macchina a 8 core** quando crea il vostro Codespace per questo corso di formazione. I workflow di bioimaging richiedono risorse di calcolo aggiuntive. + +## GitHub Codespaces + +L'ambiente GitHub Codespaces contiene tutto il software, il codice e i dati necessari per seguire questo corso di formazione, quindi non è necessario installare nulla autonomamente. +Tuttavia, è necessario un account GitHub (gratuito) per effettuare l'accesso e, se non ha familiarità con l'interfaccia, dovrebbe dedicare qualche minuto per familiarizzare con essa completando il mini-corso [GitHub Codespaces Orientation](../../envsetup/index.md). + +## Pre-download delle immagini Docker + +Una volta aperto il vostro Codespace, scarichiamo preventivamente tutte le immagini Docker che ci serviranno per questo corso di formazione. +Questo farà risparmiare tempo in seguito e garantirà un'esecuzione fluida dei workflow. + +Aprite una nuova scheda del terminale ed eseguite il seguente comando: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Questo comando scaricherà tutte le immagini Docker necessarie in background. +Può continuare con il resto dell'orientamento mentre questo è in esecuzione. + +!!!tip "Suggerimento" + + Il flag `-stub` consente al pipeline di essere eseguito rapidamente senza elaborare dati reali, il che è perfetto per scaricare le immagini. Può monitorare il progresso nella scheda del terminale. + +## Directory di lavoro + +Durante questo corso di formazione, lavoreremo nella directory `nf4-science/imaging/`. + +Cambi directory ora eseguendo questo comando nel terminale: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "Suggerimento" + + Se per qualsiasi motivo vi spostate fuori da questa directory, potete sempre utilizzare il percorso completo per ritornarvi, assumendo che stiate lavorando nell'ambiente di formazione GitHub Codespaces: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Ora, per iniziare il corso, cliccate sulla freccia nell'angolo in basso a destra di questa pagina.** diff --git a/docs/it/docs/nf4_science/imaging/01_basics.md b/docs/it/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..623d1461b6 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Parte 1: Eseguire operazioni di base + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa prima parte del corso di formazione Nextflow per il Bioimaging, utilizzeremo un esempio Hello World molto semplice e indipendente dal dominio per dimostrare operazioni essenziali e indicare i componenti corrispondenti del codice Nextflow. + +## 1. Eseguire il workflow + +Le forniamo uno script di workflow denominato `hello-world.nf` che accetta un input tramite un argomento da riga di comando chiamato `--greeting` e produce un file di testo contenente quel saluto. +Non esamineremo ancora il codice; vediamo prima come si presenta la sua esecuzione. + +### 1.1. Avviare il workflow e monitorare l'esecuzione + +Nel terminale, eseguite il seguente comando: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +L'output della console dovrebbe apparire così: + +```console title="Output" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Congratulazioni, ha appena eseguito il suo primo workflow Nextflow! + +L'output più importante qui è l'ultima riga (riga 6): + +```console title="Output" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Questo ci indica che il processo `sayHello` è stato eseguito con successo una volta (`1 of 1 ✔`). + +È ottimo, ma potrebbe chiedersi: dove si trova l'output? + +### 1.2. Trovare il file di output nella directory `results` + +Questo workflow è configurato per pubblicare il suo output in una directory chiamata `results`. +Se osserva la directory corrente, vedrà che quando ha eseguito il workflow, Nextflow ha creato una nuova directory chiamata `results`, che contiene un file chiamato `output.txt`. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Aprite il file; il contenuto dovrebbe corrispondere al saluto che ha specificato dalla riga di comando. + +<details> + <summary>Contenuto del file</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +È ottimo, il nostro workflow ha fatto ciò che doveva fare! + +Tuttavia, sia consapevole che il risultato 'pubblicato' è una copia (o in alcuni casi un symlink) dell'output effettivo prodotto da Nextflow quando ha eseguito il workflow. + +Quindi ora, daremo un'occhiata dietro le quinte per vedere dove Nextflow ha effettivamente eseguito il lavoro. + +!!! warning "Avviso" + + Non tutti i workflow saranno configurati per pubblicare gli output in una directory results, e/o il nome della directory potrebbe essere diverso. + Un po' più avanti in questa sezione, le mostreremo come scoprire dove è specificato questo comportamento. + +### 1.3. Trovare l'output originale e i log nella directory `work/` + +Quando esegue un workflow, Nextflow crea una 'directory di attività' distinta per ogni singola invocazione di ciascun processo nel workflow (=ogni passaggio nella pipeline). +Per ognuna, preparerà gli input necessari, eseguirà le istruzioni pertinenti e scriverà output e file di log all'interno di quella directory, che viene nominata automaticamente utilizzando un hash per renderla unica. + +Tutte queste directory di attività risiederanno sotto una directory chiamata `work` all'interno della vostra directory corrente (dove state eseguendo il comando). + +Questo potrebbe sembrare confuso, quindi vediamo come appare nella pratica. + +Tornando all'output della console per il workflow che abbiamo eseguito in precedenza, avevamo questa riga: + +```console title="Estratto dell'output del comando" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Vede come la riga inizia con `[a3/7be2fa]`? +Questa è una forma troncata del percorso della directory di attività per quella singola chiamata di processo, e le indica dove trovare l'output della chiamata del processo `sayHello` all'interno del percorso della directory `work/`. + +Può trovare il percorso completo digitando il seguente comando (sostituendo `a3/7be2fa` con ciò che vede nel suo terminale) e premendo il tasto tab per completare automaticamente il percorso o aggiungendo un asterisco: + +```bash +tree work/a3/7be2fa* +``` + +Questo dovrebbe produrre il percorso completo della directory: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Diamo un'occhiata a cosa c'è dentro. + +!!! Tip "Suggerimento" + + Se esplora il contenuto della sottodirectory di attività nell'esploratore file di VSCode, vedrà tutti i file immediatamente. + Tuttavia, i file di log sono impostati per essere invisibili nel terminale, quindi se vuole utilizzare `ls` o `tree` per visualizzarli, dovrà impostare l'opzione pertinente per visualizzare i file invisibili. + + ```bash + tree -a work + ``` + +I nomi esatti delle sottodirectory saranno diversi sul suo sistema. + +<details> + <summary>Contenuto della directory</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Dovrebbe riconoscere immediatamente il file `output.txt`, che è infatti l'output originale del processo `sayHello` che è stato pubblicato nella directory `results`. +Se lo aprite, troverete di nuovo il saluto `Hello World!`. + +<details> + <summary>Contenuto del file output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +E quindi tutti quegli altri file? + +Questi sono i file helper e di log che Nextflow ha scritto come parte dell'esecuzione dell'attività: + +- **`.command.begin`**: File sentinella creato non appena l'attività viene avviata. +- **`.command.err`**: Messaggi di errore (`stderr`) emessi dalla chiamata del processo +- **`.command.log`**: Output di log completo emesso dalla chiamata del processo +- **`.command.out`**: Output normale (`stdout`) della chiamata del processo +- **`.command.run`**: Script completo eseguito da Nextflow per eseguire la chiamata del processo +- **`.command.sh`**: Il comando che è stato effettivamente eseguito dalla chiamata del processo +- **`.exitcode`**: Il codice di uscita risultante dal comando + +Il file `.command.sh` è particolarmente utile perché mostra il comando principale che Nextflow ha eseguito senza includere tutta la gestione contabile e la configurazione dell'attività/ambiente. + +<details> + <summary>Contenuto del file</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Suggerimento" + + Quando qualcosa va storto e deve risolvere il problema, può essere utile guardare lo script `command.sh` per verificare esattamente quale comando Nextflow ha composto in base alle istruzioni del workflow, all'interpolazione delle variabili e così via. + +### 1.4. Esercizio facoltativo: rieseguire con saluti diversi + +Provi a rieseguire il workflow alcune volte con valori diversi per l'argomento `--greeting`, quindi osservi sia il contenuto della directory `results/` che le directory di attività. + +Osservi come gli output e i log delle directory di attività isolate vengono preservati, mentre il contenuto della directory `results` viene sovrascritto dall'output delle esecuzioni successive. + +### Takeaway + +Sa come eseguire un semplice script Nextflow, monitorarne l'esecuzione e trovare i suoi output. + +### Cosa succede dopo? + +Imparate a leggere uno script Nextflow di base e a identificare come i suoi componenti si relazionano alla sua funzionalità. + +--- + +## 2. Esaminare lo script iniziale del workflow Hello World + +Quello che abbiamo fatto è stato sostanzialmente trattare lo script del workflow come una scatola nera. +Ora che abbiamo visto cosa fa, apriamo la scatola e guardiamo dentro. + +_L'obiettivo qui non è memorizzare la sintassi del codice Nextflow, ma formare un'intuizione di base di quali sono i componenti principali e come sono organizzati._ + +### 2.1. Esaminare la struttura complessiva del codice + +Apriamo lo script `hello-world.nf` nel pannello dell'editor. + +<details> + <summary>Codice</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // emette un saluto + sayHello(params.greeting) +} +``` + +</details> + +Uno script Nextflow coinvolge due tipi principali di componenti fondamentali: uno o più **processi**, e il **workflow** stesso. +Ogni **processo** descrive quale operazione/i deve compiere il passaggio corrispondente nella pipeline, mentre il **workflow** descrive la logica del flusso di dati che collega i vari passaggi. + +Diamo prima un'occhiata più da vicino al blocco **process**, poi esamineremo il blocco **workflow**. + +### 2.2. La definizione di `process` + +Il primo blocco di codice descrive un **processo**. +La definizione del processo inizia con la parola chiave `process`, seguita dal nome del processo e infine dal corpo del processo delimitato da parentesi graffe. +Il corpo del processo deve contenere un blocco script che specifica il comando da eseguire, che può essere qualsiasi cosa sia in grado di eseguire in un terminale a riga di comando. + +Qui abbiamo un **processo** chiamato `sayHello` che accetta una variabile di **input** chiamata `greeting` e scrive il suo **output** in un file denominato `output.txt`. + +<details> + <summary>Codice</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +Questa è una definizione di processo molto minimale che contiene solo una definizione `input`, una definizione `output` e lo `script` da eseguire. + +La definizione `input` include il qualificatore `val`, che dice a Nextflow di aspettarsi un valore di qualche tipo (può essere una stringa, un numero, qualsiasi cosa). + +La definizione `output` include il qualificatore `path`, che dice a Nextflow che questo dovrebbe essere gestito come un percorso (include sia percorsi di directory che file). + +!!! Tip "Suggerimento" + + La definizione di output non _determina_ quale output verrà creato. + Semplicemente _dichiara_ dove trovare il/i file di output previsti, in modo che Nextflow possa cercarlo una volta completata l'esecuzione. + + Questo è necessario per verificare che il comando sia stato eseguito con successo e per passare l'output ai processi successivi se necessario. + L'output prodotto che non corrisponde a ciò che è dichiarato nel blocco di output non verrà passato ai processi successivi. + +In una pipeline del mondo reale, un processo di solito contiene informazioni aggiuntive come direttive di processo, che introdurremo tra poco. + +### 2.3. La definizione di `workflow` + +Il secondo blocco di codice descrive il **workflow** stesso. +La definizione del workflow inizia con la parola chiave `workflow`, seguita da un nome opzionale, quindi dal corpo del workflow delimitato da parentesi graffe. + +Qui abbiamo un **workflow** che consiste in una chiamata al processo `sayHello`, che accetta un input, `params.greeting`, che contiene il valore che abbiamo dato al parametro `--greeting`. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // emette un saluto + sayHello(params.greeting) +} +``` + +Questa è una definizione di **workflow** molto minimale. +In una pipeline del mondo reale, il workflow contiene tipicamente più chiamate a **processi** collegati da **canali**, e potrebbero esserci valori predefiniti impostati per gli input delle variabili. + +Vedremo questo in azione quando eseguiremo nf-core/molkart nella Parte 2 del corso. + +### 2.4. Il sistema `params` dei parametri da riga di comando + +Il `params.greeting` che forniamo alla chiamata del processo `sayHello()` è un frammento di codice Nextflow interessante e vale la pena dedicargli un minuto in più. + +Come menzionato sopra, è così che passiamo il valore del parametro da riga di comando `--greeting` alla chiamata del processo `sayHello()`. +Infatti, semplicemente dichiarando `params.someParameterName` ci permetterà di dare al workflow un parametro denominato `--someParameterName` dalla riga di comando. + +!!! Tip "Suggerimento" + + Questi parametri del workflow dichiarati utilizzando il sistema `params` richiedono sempre due trattini (`--`). + Questo li distingue dai parametri a livello Nextflow, che richiedono solo un trattino (`-`). + +### Takeaway + +Ora sa come è strutturato un semplice workflow Nextflow e come i componenti di base si relazionano alla sua funzionalità. + +### Cosa succede dopo? + +Imparate a gestire comodamente le esecuzioni del workflow. + +--- + +## 3. Gestire le esecuzioni del workflow + +Sapere come avviare workflow e recuperare output è ottimo, ma scoprirà rapidamente che ci sono alcuni altri aspetti della gestione del workflow che renderanno la sua vita più facile. + +Qui vi mostriamo come sfruttare la funzione `resume` per quando deve rilanciare lo stesso workflow, come ispezionare i log di esecuzione con `nextflow log`, e come eliminare le directory work più vecchie con `nextflow clean`. + +### 3.1. Rilanciare un workflow con `-resume` + +A volte, vorrà rieseguire una pipeline che ha già avviato in precedenza senza rifare alcun lavoro che è già stato completato con successo. + +Nextflow ha un'opzione chiamata `-resume` che le permette di farlo. +Specificamente, in questa modalità, tutti i processi che sono già stati eseguiti con esattamente lo stesso codice, impostazioni e input verranno saltati. +Questo significa che Nextflow eseguirà solo i processi che ha aggiunto o modificato dall'ultima esecuzione, o ai quali sta fornendo nuove impostazioni o input. + +Ci sono due vantaggi chiave nel farlo: + +- Se sta sviluppando una pipeline, potete iterare più rapidamente poiché deve solo eseguire il/i processo/i su cui state lavorando attivamente per testare le vostre modifiche. +- Se state eseguendo una pipeline in produzione e qualcosa va storto, in molti casi potete risolvere il problema e rilanciare la pipeline, e riprenderà l'esecuzione dal punto di errore, il che può farvi risparmiare molto tempo e calcolo. + +Per utilizzarlo, aggiungete semplicemente `-resume` al vostro comando ed eseguite: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Cerchi il bit `cached:` che è stato aggiunto nella riga dello stato del processo (riga 5), che significa che Nextflow ha riconosciuto di aver già fatto questo lavoro e ha semplicemente riutilizzato il risultato dall'esecuzione precedente riuscita. + +Può anche vedere che l'hash della sottodirectory work è lo stesso dell'esecuzione precedente. +Nextflow vi sta letteralmente indicando l'esecuzione precedente e dicendo "L'ho già fatto lì." + +!!! Tip "Suggerimento" + + Quando riesegue una pipeline con `resume`, Nextflow non sovrascrive nessun file scritto in una directory `publishDir` da alcuna chiamata di processo che è stata precedentemente eseguita con successo. + +### 3.2. Ispezionare il log delle esecuzioni passate + +Ogni volta che avvia un workflow nextflow, viene scritta una riga in un file di log chiamato `history`, sotto una directory nascosta chiamata `.nextflow` nella directory di lavoro corrente. + +Un modo più conveniente per accedere a queste informazioni è utilizzare il comando `nextflow log`. + +```bash +nextflow log +``` + +Questo produrrà il contenuto del file di log nel terminale, mostrandole il timestamp, il nome dell'esecuzione, lo stato e la riga di comando completa per ogni esecuzione Nextflow che è stata avviata dall'interno della directory di lavoro corrente. + +### 3.3. Eliminare le directory work più vecchie + +Durante il processo di sviluppo, tipicamente eseguirete le vostre bozze di pipeline un gran numero di volte, il che può portare a un accumulo di molti file in molte sottodirectory. +Poiché le sottodirectory sono nominate casualmente, è difficile dire dai loro nomi quali sono le esecuzioni più vecchie rispetto a quelle più recenti. + +Nextflow include un comodo sottocomando `clean` che potete eliminare automaticamente le sottodirectory work per esecuzioni passate che non vi interessano più, con diverse [opzioni](https://www.nextflow.io/docs/latest/reference/cli.html#clean) per controllare cosa verrà eliminato. + +Può utilizzare il log Nextflow per cercare un'esecuzione in base al suo timestamp e/o alla riga di comando, quindi utilizzare `nextflow clean -before <run_name> -f` per eliminare le directory work dalle esecuzioni precedenti. + +!!! Warning "Avviso" + + L'eliminazione delle sottodirectory work dalle esecuzioni passate le rimuove dalla cache di Nextflow ed elimina qualsiasi output che era memorizzato in quelle directory. + Questo significa che interrompe la capacità di Nextflow di riprendere l'esecuzione senza rieseguire i processi corrispondenti. + + È responsabile del salvataggio di qualsiasi output che vi interessa o su cui prevedete di fare affidamento! Se sta utilizzando la direttiva `publishDir` per questo scopo, assicuratevi di utilizzare la modalità `copy`, non la modalità `symlink`. + +### Takeaway + +Sa come rilanciare una pipeline senza ripetere i passaggi che sono già stati eseguiti in modo identico, ispezionare il log di esecuzione e utilizzare il comando `nextflow clean` per ripulire le vecchie directory work. + +### Cosa succede dopo? + +Ora che comprende le operazioni di base di Nextflow, è pronto per eseguire una vera pipeline di bioimaging con nf-core/molkart. diff --git a/docs/it/docs/nf4_science/imaging/02_run_molkart.md b/docs/it/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..df31d80e89 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Parte 2: Eseguire nf-core/molkart + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella Parte 1, abbiamo eseguito un semplice workflow Hello World per comprendere le basi dell'esecuzione di Nextflow. +Ora eseguiremo una pipeline di bioimaging reale: **nf-core/molkart**. + +Questa pipeline elabora dati di trascrittomica spaziale Molecular Cartography da Resolve Bioscience. +Tuttavia, i pattern di Nextflow che apprenderà qui si applicano a qualsiasi pipeline nf-core o workflow di produzione. + +## 1. Comprendere le pipeline nf-core + +Prima di eseguire la pipeline, comprendiamo cos'è nf-core e perché è importante per l'esecuzione dei workflow. + +### 1.1. Cos'è nf-core? + +[nf-core](https://nf-co.re/) è una raccolta guidata dalla comunità di pipeline Nextflow di alta qualità. +Tutte le pipeline nf-core seguono la stessa struttura e convenzioni, il che significa che una volta imparato a eseguirne una, potete eseguirle tutte. + +Caratteristiche chiave delle pipeline nf-core: + +- **Struttura standardizzata**: Tutte le pipeline hanno nomi di parametri e pattern di utilizzo coerenti +- **Dati di test integrati**: Ogni pipeline include profili di test per una validazione rapida +- **Documentazione completa**: Istruzioni dettagliate sull'uso e descrizioni dei parametri +- **Controllo qualità**: Report QC automatizzati utilizzando MultiQC +- **Supporto container**: Container predefiniti per la riproducibilità + +!!! tip "Desidera saperne di più su nf-core?" + + Per un'introduzione approfondita allo sviluppo di pipeline nf-core, consulti il corso di formazione [Hello nf-core](../../hello_nf-core/index.md). + Copre come creare e personalizzare pipeline nf-core da zero. + +### 1.2. La pipeline molkart + +![nf-core/molkart pipeline](img/molkart.png) + +La pipeline [nf-core/molkart](https://nf-co.re/molkart) elabora dati di imaging di trascrittomica spaziale attraverso diverse fasi: + +1. **Preprocessing delle immagini**: Riempimento del pattern a griglia e miglioramento opzionale del contrasto +2. **Segmentazione cellulare**: Opzioni di algoritmi multipli (Cellpose, Mesmer, ilastik, Stardist) +3. **Assegnazione degli spot**: Assegnare spot di trascritti a cellule segmentate +4. **Controllo qualità**: Generare report QC completi + +Gli output chiave sono: + +- Tabelle di conteggio cellula-per-trascritto +- Maschere di segmentazione +- Report di controllo qualità MultiQC + +--- + +## 2. Eseguire molkart con dati di test + +Prima di iniziare, cloniamo il repository molkart localmente in modo da poter ispezionare il suo codice: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Questo crea una directory `molkart/` contenente il codice sorgente completo della pipeline. + +!!! note "Perché stiamo clonando localmente?" + + Tipicamente, si eseguirebbero le pipeline nf-core direttamente da GitHub usando `nextflow run nf-core/molkart -r 1.2.0`. + Nextflow scarica automaticamente la versione richiesta della pipeline in `$HOME/.nextflow/assets/nf-core/molkart` e la esegue da lì. + Tuttavia, per questa formazione, stiamo clonando la pipeline in una directory locale diversa in modo da poter ispezionare più facilmente il codice. + +### 2.1. Comprendere i requisiti dei container + +Prima di eseguire la pipeline completa, comprendiamo perché i container sono essenziali per le pipeline nf-core. + +Proviamo a eseguire la pipeline utilizzando il dataset di test e i parametri dalla configurazione di test di molkart: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Analizziamo questi parametri: + +- `--input`: Percorso al samplesheet contenente i metadati del campione +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Parametri per il riempimento del pattern a griglia +- `--clahe_pyramid_tile`: Dimensione del kernel per il miglioramento del contrasto +- `--segmentation_method`: Quale/i algoritmo/i utilizzare per la segmentazione cellulare +- `--outdir`: Dove salvare i risultati + +!!! Warning "Questo comando fallirà - è intenzionale!" + + Stiamo deliberatamente eseguendo questo senza container per dimostrare perché sono necessari. + +Dopo alcuni istanti, vedrà un errore come questo: + +??? failure "Output del comando" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**Cosa sta succedendo?** + +L'errore `command not found` (stato di uscita 127) significa che Nextflow ha tentato di eseguire `duplicate_finder.py` ma non è riuscito a trovarlo sul vostro sistema. +Questo perché: + +1. La pipeline si aspetta che software bioinformatico specializzato sia installato +2. Questi strumenti (come `duplicate_finder.py`, `apply_clahe.dask.py`, ecc.) non fanno parte delle distribuzioni Linux standard +3. Senza container, Nextflow tenta di eseguire i comandi direttamente sulla vostra macchina locale + +**Da dove dovrebbero provenire questi strumenti?** + +Ispezioniamo uno dei moduli process per vedere come dichiara i suoi requisiti software. + +Aprite il modulo di preprocessing CLAHE: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Guardi alla riga 5 - vedrà: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Questa riga dice a Nextflow: "Per eseguire questo process, utilizzare l'immagine Docker `ghcr.io/schapirolabor/molkart-local:v0.0.4`, che contiene tutto il software richiesto." + +Ogni process dichiara quale immagine container fornisce i suoi strumenti richiesti. +Tuttavia, Nextflow utilizza questi container solo se glielo indica! + +**La soluzione: Abilitare Docker nella configurazione** + +### 2.2. Configurare Docker e lanciare la pipeline + +Per abilitare Docker, dobbiamo cambiare `docker.enabled` da `false` a `true` nel file `nextflow.config`. + +Aprite il file di configurazione: + +```bash +code nextflow.config +``` + +Cambi `docker.enabled = false` in `docker.enabled = true`: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Ora eseguite nuovamente la pipeline con lo stesso comando: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Questa volta, Nextflow: + +1. Leggerà l'impostazione `docker.enabled = true` dalla configurazione +2. Scaricherà le immagini Docker richieste (solo la prima volta) +3. Eseguirà ogni process all'interno del suo container specificato +4. Eseguirà con successo perché tutti gli strumenti sono disponibili all'interno dei container + +!!! Tip "Perché i container sono importanti" + + La maggior parte delle pipeline nf-core **richiede** la containerizzazione (Docker, Singularity, Podman, ecc.) perché: + + - Utilizzano software bioinformatico specializzato non disponibile negli ambienti standard + - I container garantiscono la riproducibilità - le stesse identiche versioni del software vengono eseguite ovunque + - Non è necessario installare manualmente dozzine di strumenti e le loro dipendenze + + Per maggiori dettagli sui container in Nextflow, consulti [Hello Containers](../../hello_nextflow/05_hello_containers.md) dalla formazione Hello Nextflow. + +### 2.3. Monitorare l'esecuzione + +Durante l'esecuzione della pipeline, vedrà un output simile a questo: + +??? success "Output del comando" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Noti come questo output sia più dettagliato rispetto al nostro esempio Hello World grazie alle convenzioni nf-core che la pipeline segue: + +- La pipeline mostra la sua versione e il logo +- I parametri di configurazione vengono visualizzati +- Più process vengono eseguiti in parallelo (indicato da più righe di process) +- I nomi dei process includono il percorso completo del modulo (es., `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Comprendere l'esecuzione dei process + +La riga executor `executor > local (22)` Le dice: + +- **executor**: Quale ambiente di calcolo viene utilizzato (`local` = la vostra macchina) +- **(22)**: Numero totale di attività lanciate + +Ogni riga di process mostra: + +- **Hash** (`[1a/2b3c4d]`): Identificatore della directory di lavoro (come prima) +- **Nome del process**: Percorso completo del modulo e nome del process +- **Identificatore input**: Nome del campione tra parentesi +- **Progresso**: Percentuale completata e conteggio (es., `1 of 1 ✔`) + +### Takeaway + +Sa come lanciare una pipeline nf-core con dati di test e interpretare il suo output di esecuzione. + +### Prossimi passi + +Impari dove trovare i risultati e come interpretarli. + +--- + +## 3. Trovare ed esaminare gli output + +Quando la pipeline viene completata con successo, vedrà un messaggio di completamento e un riepilogo dell'esecuzione. + +### 3.1. Localizzare la directory dei risultati + +Per impostazione predefinita, le pipeline nf-core scrivono gli output in una directory specificata dal parametro `outdir`, che abbiamo impostato su `results/`. + +Elenchi i contenuti: + +```bash +tree results/ +``` + +Dovrebbe vedere diverse subdirectory: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Ogni subdirectory contiene output da una fase specifica della pipeline: + +- **mindagap/**: Immagini riempite a griglia dal passaggio di preprocessing MindaGap +- **clahe/**: Immagini con contrasto migliorato dal preprocessing CLAHE +- **stack/**: Stack di immagini multi-canale creati per la segmentazione +- **segmentation/**: Risultati di segmentazione da diversi algoritmi (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Tabelle di conteggio cellula-per-trascritto +- **anndata/**: Oggetti AnnData contenenti matrici cellula-per-trascritto e coordinate spaziali +- **molkartqc/**: Metriche di controllo qualità per l'assegnazione degli spot +- **multiqc/**: Report completo di controllo qualità +- **pipeline_info/**: Report di esecuzione e log + +### 3.2. Esaminare il report MultiQC + +Il report MultiQC è un file HTML completo che aggrega le metriche di qualità da tutti i passaggi della pipeline. + +Aprite il report nel file browser e poi cliccate sul pulsante "Show Preview" per vederlo renderizzato direttamente in VS Code. + +Il report include: + +- Statistiche generali per tutti i campioni +- Metriche di preprocessing +- Metriche di qualità della segmentazione +- Numero di cellule e spot rilevati + +!!! Tip + + I report MultiQC sono tipicamente inclusi in tutte le pipeline nf-core. + Forniscono sempre una panoramica ad alto livello dell'esecuzione della pipeline e della qualità dei dati. + +### 3.3. Esaminare le tabelle cellula-per-trascritto + +L'output scientifico più importante è la tabella di conteggio cellula-per-trascritto. +Questa Le dice quanti trascritti di ciascun tipo sono stati rilevati in ogni cellula. + +Navighi alla directory spot2cell: + +```bash +ls results/spot2cell/ +``` + +Troverà file come: + +- `cellxgene_mem_only_cellpose.csv`: Tabella cellula-per-trascritto usando la segmentazione Cellpose +- `cellxgene_mem_only_mesmer.csv`: Tabella cellula-per-trascritto usando la segmentazione Mesmer +- `cellxgene_mem_only_stardist.csv`: Tabella cellula-per-trascritto usando la segmentazione Stardist + +Abbiamo eseguito solo 1 campione in questo dataset di test, ma in un esperimento reale avremmo queste tabelle per ogni campione. +Noti come Nextflow è in grado di elaborare più metodi di segmentazione in parallelo, rendendo facile confrontare i risultati. + +### 3.4. Visualizzare i report di esecuzione + +Nextflow genera automaticamente diversi report di esecuzione. + +Verifichi la directory pipeline_info: + +```bash +ls results/pipeline_info/ +``` + +File chiave: + +- **execution_report.html**: Timeline e visualizzazione dell'utilizzo delle risorse +- **execution_timeline.html**: Diagramma di Gantt dell'esecuzione dei process +- **execution_trace.txt**: Metriche dettagliate dell'esecuzione delle attività +- **pipeline_dag.html**: Grafico aciclico diretto che mostra la struttura del workflow + +Aprite il report di esecuzione per vedere l'utilizzo delle risorse: + +```bash +code results/pipeline_info/execution_report.html +``` + +Questo mostra: + +- Quanto tempo ha impiegato ogni process +- Utilizzo di CPU e memoria +- Quali attività sono state memorizzate nella cache vs. eseguite + +!!! Tip + + Questi report sono incredibilmente utili per ottimizzare l'allocazione delle risorse e risolvere problemi di prestazioni. + +### Takeaway + +Sa come localizzare gli output della pipeline, esaminare i report di controllo qualità e accedere alle metriche di esecuzione. + +### Prossimi passi + +Impari sulla directory di lavoro e come Nextflow gestisce i file intermedi. + +--- + +## 4. Esplorare la directory di lavoro + +Proprio come nel nostro esempio Hello World, tutto il lavoro effettivo avviene nella directory `work/`. + +### 4.1. Comprendere la struttura della directory di lavoro + +La directory di lavoro contiene una subdirectory per ogni attività che è stata eseguita. +Per questa pipeline con 12 attività, ci saranno 12 subdirectory di lavoro. + +Elenchi la directory di lavoro: + +```bash +ls -d work/*/*/ | head -5 +``` + +Questo mostra le prime 5 directory di attività. + +### 4.2. Ispezionare una directory di attività + +Scelga uno degli hash dei process di segmentazione dall'output della console (es., `[3m/4n5o6p]`) e guardi all'interno: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Vedrà: + +- **File .command.\***: Script di esecuzione Nextflow e log (come prima) +- **File di input staged**: Symlink ai file di input effettivi +- **File di output**: Maschere di segmentazione, risultati intermedi, ecc. + +La differenza chiave rispetto a Hello World: + +- Le pipeline reali preparano grandi file di input (immagini, dati di riferimento) +- I file di output possono essere piuttosto grandi (maschere di segmentazione, immagini elaborate) +- Più file di input e output per attività + +!!! Tip + + Se un process fallisce, potete navigare alla vostra directory di lavoro, esaminare `.command.err` per i messaggi di errore e persino rieseguire `.command.sh` manualmente per il debug del problema. + +### 4.3. Pulizia della directory di lavoro + +La directory di lavoro può diventare piuttosto grande nel corso di più esecuzioni della pipeline. +Come abbiamo appreso nella Parte 1, potete utilizzare `nextflow clean` per rimuovere le directory di lavoro dalle vecchie esecuzioni. + +Tuttavia, per le pipeline nf-core con grandi file intermedi, è particolarmente importante pulire regolarmente. + +### Takeaway + +Comprende come le pipeline nf-core organizzano le loro directory di lavoro e come ispezionare singole attività per il debugging. + +### Prossimi passi + +Impari sulla cache di Nextflow e come riprendere esecuzioni della pipeline fallite. + +--- + +## 5. Riprendere un'esecuzione della pipeline + +Una delle caratteristiche più potenti di Nextflow è la capacità di riprendere una pipeline dal punto di fallimento. + +### 5.1. Il meccanismo di cache + +Quando esegue una pipeline con `-resume`, Nextflow: + +1. Controlla la cache per ogni attività +2. Se input, codice e parametri sono identici, riutilizza il risultato memorizzato nella cache +3. Riesegue solo le attività che sono cambiate o fallite + +Questo è essenziale per pipeline di lunga durata dove i fallimenti potrebbero verificarsi in ritardo nell'esecuzione. + +### 5.2. Provare resume con molkart + +Esegua nuovamente lo stesso comando, ma aggiunga `-resume`: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Dovrebbe vedere un output come: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Noti `cached: 2` o `cached: 1` per ogni process - nulla è stato rieseguito! + +### 5.3. Quando resume è utile + +Resume è particolarmente prezioso quando: + +- Una pipeline fallisce a causa di limiti di risorse (memoria esaurita, limite di tempo superato) +- È necessario modificare i process a valle senza rieseguire i passaggi a monte +- La vostra connessione di rete si interrompe durante il download dei dati +- Desidera aggiungere output aggiuntivi senza rifare il calcolo + +!!! Warning + + Resume funziona solo se non ha modificato i dati di input, il codice della pipeline o i parametri. + Se modifica uno di questi, Nextflow rieseguirà correttamente le attività interessate. + +### Takeaway + +Sa come utilizzare `-resume` per rieseguire efficientemente le pipeline senza ripetere attività riuscite. + +### Prossimi passi + +Ora che potete eseguire nf-core/molkart con dati di test, siete pronti per imparare come configurarla per i vostri dataset. diff --git a/docs/it/docs/nf4_science/imaging/03_inputs.md b/docs/it/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..f673474e72 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Parte 3: Organizzazione degli input + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nella Parte 2, abbiamo eseguito molkart con più parametri dalla riga di comando. +Ora impareremo due approcci migliori per gestire gli input: **file di parametri** e **samplesheet**. + +## 1. Utilizzo dei file di parametri + +### 1.1. Il problema delle righe di comando lunghe + +Ricordiamo il nostro comando dalla Parte 2: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Questo funziona, ma è difficile da riprodurre, condividere o modificare. +Cosa succede se è necessario eseguire nuovamente la stessa analisi il prossimo mese? +Cosa succede se un collaboratore vuole utilizzare le vostre stesse impostazioni? + +### 1.2. Soluzione: Utilizzare un file di parametri + +Creare un file chiamato `params.yaml`: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Ora il vostro comando diventa: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +Ecco fatto! Il file di parametri documenta la vostra configurazione esatta e rende facile rieseguire o condividere. + +### 1.3. Sovrascrittura dei parametri + +È ancora possibile sovrascrivere parametri specifici dalla riga di comando: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +La riga sopra cambia il `segmentation_method` in `stardist` e il nome di `--outdir` in `stardist_results` invece dei parametri nel file `params.yaml`. +Inoltre, potete vedere che il flag `-resume` ci ha permesso di riutilizzare i risultati di pre-elaborazione dall'esecuzione precedente, risparmiando tempo. +Può utilizzare questo schema per testare rapidamente diverse variazioni della pipeline. + +### Takeaway + +I file di parametri rendono le vostre analisi riproducibili e facili da condividere. +Li utilizzi per qualsiasi lavoro di analisi reale. + +### Prossimi passi + +Scopra come i samplesheet organizzano le informazioni su più campioni. + +--- + +## 2. Il pattern samplesheet + +### 2.1. Cos'è un samplesheet? + +Un samplesheet è un file CSV che descrive i vostri campioni di input. +Ogni riga è un campione e le colonne specificano i file e i metadati per quel campione. + +Esaminiamo il samplesheet che abbiamo utilizzato: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Le colonne sono: + +- `sample`: Identificatore univoco del campione +- `nuclear_image`: Immagine di colorazione nucleare (TIFF) +- `spot_table`: Punti di trascrizione (TXT) +- `membrane_image`: Immagine di colorazione della membrana (TIFF, opzionale) + +### 2.2. Percorsi dei file + +I samplesheet accettano diversi tipi di percorso: + +- **URL**: Nextflow scarica automaticamente (come mostrato sopra) +- **Percorsi locali**: `data/nuclear.tiff` o `/absolute/path/to/nuclear.tiff` +- **Cloud storage**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Può combinare tipi di percorso nello stesso samplesheet. + +### 2.3. Creazione del proprio samplesheet + +Prima, scarichiamo i file di dati di test localmente: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Ora modifichiamo il samplesheet per fare riferimento a questi file locali: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Avviso" + + Noti che i percorsi nel samplesheet sono relativi a dove **esegue** Nextflow, non a dove si trova il samplesheet. + +Infine, eseguiamo nf-core/molkart un'altra volta con il samplesheet con percorsi di file locali: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Come potete vedere, Nextflow esegue questa esecuzione in modo simile a quando i file sono stati scaricati da GitHub. Questa è una delle grandi caratteristiche di Nextflow: prepara i dati correttamente per voi, indipendentemente da dove si trovano. + +### Takeaway + +I samplesheet organizzano set di dati multi-campione in modo da permettervi di definire esplicitamente i vostri metadati insieme ai percorsi dei file. +La maggior parte delle pipeline nf-core utilizza questo pattern. + +### Prossimi passi + +Ora che abbiamo trattato gli input, esploriamo come configurare le pipeline Nextflow per diversi ambienti di calcolo. diff --git a/docs/it/docs/nf4_science/imaging/04_config.md b/docs/it/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..d212bcd323 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Parte 4: Configurazione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nelle Parti 1-3, abbiamo imparato come eseguire Nextflow, eseguire una pipeline nf-core e gestire gli input con file di parametri e samplesheet. +Ora esploreremo come configurare le pipeline per diversi ambienti di calcolo utilizzando **file di configurazione** e **profili**. + +## Obiettivi di apprendimento + +Al termine di questa parte, sarai in grado di: + +- Comprendere come Nextflow risolve la configurazione da più fonti +- Utilizzare i profili integrati di nf-core per container e test +- Creare profili personalizzati per diversi ambienti di calcolo +- Personalizzare le richieste di risorse utilizzando le etichette dei processi +- Gestire i limiti di risorse in ambienti con risorse limitate +- Ispezionare la configurazione risolta con `nextflow config` + +--- + +## 1. Comprendere la configurazione di Nextflow + +### 1.1. Cos'è un file di configurazione? + +Nextflow utilizza file di configurazione per separare la **logica del workflow** (cosa fare) dalle **impostazioni di esecuzione** (come e dove farlo). + +I file di configurazione controllano: + +- Motori per container (Docker, Singularity, Conda) +- Risorse di calcolo (CPU, memoria, tempo) +- Piattaforme di esecuzione (locale, HPC, cloud) +- Parametri della pipeline + +### 1.2. Precedenza della configurazione + +Nextflow carica la configurazione da più fonti, con le fonti successive che sovrascrivono quelle precedenti: + +1. **Configurazione della pipeline**: `nextflow.config` nel repository della pipeline +2. **Configurazione della directory**: `nextflow.config` nella directory di lavoro corrente +3. **Configurazione utente**: `~/.nextflow/config` +4. **Riga di comando**: Parametri e opzioni passate direttamente + +Questo approccio a livelli consente di mantenere le impostazioni predefinite nella pipeline, sovrascriverle con impostazioni specifiche dell'utente e apportare modifiche rapide dalla riga di comando. + +### 1.3. La nostra configurazione attuale + +Diamo un'occhiata alla configurazione che abbiamo utilizzato: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Commentiamo o modifichiamo la riga `docker.enabled = true` dalla Parte 2, e scopriamo come possiamo ottenere lo stesso risultato utilizzando un profilo in molkart. + +--- + +## 2. Utilizzo dei profili + +### 2.1. Cosa sono i profili? + +I profili sono insiemi nominati di configurazione che possono essere attivati con il flag `-profile` tramite il comando `nextflow run`. +Facilitano il passaggio tra diversi scenari di calcolo senza modificare i file di configurazione. + +Tutte le pipeline nf-core sono fornite con un numero di profili predefiniti che possiamo utilizzare. + +### 2.2. Ispezione dei profili integrati + +Ispezioniamoli nel file `molkart/nextflow.config` associato alla codebase della pipeline: + +```bash +code molkart/nextflow.config +``` + +Cercare il blocco `profiles`: + +```groovy title="molkart/nextflow.config (estratto)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Profili comuni per container: + +- `docker`: Utilizza container Docker (più comune per lo sviluppo locale) +- `singularity`: Utilizza Singularity/Apptainer (comune su HPC) +- `conda`: Utilizza ambienti Conda +- `apptainer`: Utilizza container Apptainer + +### 2.3. Riesecuzione con profili invece di nextflow.config + +Ora che abbiamo disabilitato la configurazione docker nel nostro file `nextflow.config` locale e compreso i profili, rieseguiamo la pipeline utilizzando il flag `-profile`. + +Precedentemente nella Parte 3, abbiamo creato un file `params.yaml` con i nostri parametri personalizzati. +Possiamo ora combinarlo con il profilo Docker integrato: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Analizziamo cosa fa ciascun flag: + +- `-profile docker`: Attiva il profilo Docker dal `nextflow.config` di molkart, che imposta `docker.enabled = true` +- `-params-file params.yaml`: Carica tutti i parametri della pipeline dal nostro file YAML +- `-resume`: Riutilizza i risultati memorizzati nella cache delle esecuzioni precedenti + +Poiché stiamo utilizzando `-resume`, Nextflow verificherà se qualcosa è cambiato dall'ultima esecuzione. +Se i parametri, gli input e il codice sono gli stessi, tutte le attività verranno recuperate dalla cache e la pipeline si completerà quasi istantaneamente. + +```console title="Output (estratto)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Si noti che tutti i processi mostrano `cached: 2` o `cached: 1` - nulla è stato rieseguito! + +### 2.4. Profili di test + +I profili di test forniscono modi rapidi per specificare parametri di input predefiniti e file di dati per consentire di verificare il funzionamento della pipeline. +Le pipeline nf-core includeranno sempre almeno due profili di test: + +- `test`: Dataset piccolo con parametri veloci per test rapidi +- `test_full`: Test più completo con dati più grandi + +Diamo un'occhiata più da vicino al profilo `test` in molkart che è incluso utilizzando la direttiva `includeConfig`: + +```groovy title="molkart/nextflow.config (estratto)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Questo significa che ogni volta che eseguiamo la pipeline con `-profile test`, Nextflow caricherà la configurazione da `conf/test.config`. + +```groovy title="molkart/conf/test.config (estratto)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Si noti che questo profilo contiene gli stessi parametri che abbiamo utilizzato nel nostro file `params.yaml` in precedenza. + +È possibile attivare più profili separandoli con virgole. +Utilizziamo questo per testare la nostra pipeline senza bisogno del nostro file params: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Questo combina: + +- `docker`: Abilita i container Docker +- `test`: Utilizza dataset e parametri di test + +I profili vengono applicati da sinistra a destra, quindi i profili successivi sovrascrivono quelli precedenti se impostano gli stessi valori. + +### Takeaway + +Le pipeline nf-core sono fornite con profili integrati per container, test e ambienti speciali. +È possibile combinare più profili per costruire la configurazione necessaria. + +### Prossimi passi + +Scopri come creare i tuoi profili personalizzati per diversi ambienti di calcolo. + +--- + +## 3. Creazione di profili personalizzati + +### 3.1. Creare profili per passare tra sviluppo locale ed esecuzione su HPC + +Creiamo profili personalizzati per due scenari: + +1. Sviluppo locale con Docker +2. HPC universitario con scheduler Slurm e Singularity + +Aggiungere quanto segue al proprio `nextflow.config`: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Ora è possibile passare facilmente tra ambienti: + +```bash +# Per lo sviluppo locale +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Per HPC (quando disponibile) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "Nota" + + Non possiamo testare il profilo HPC in questo ambiente di formazione poiché non abbiamo accesso a uno scheduler Slurm. + Ma questo mostra come lo si configurerebbe per l'uso nel mondo reale. + +### 3.2. Utilizzare `nextflow config` per ispezionare la configurazione + +Il comando `nextflow config` mostra la configurazione completamente risolta senza eseguire la pipeline. + +Visualizzare la configurazione predefinita: + +```bash +nextflow config ./molkart +``` + +Visualizzare la configurazione con un profilo specifico: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Questo è estremamente utile per: + +- Debug di problemi di configurazione +- Comprendere quali valori verranno effettivamente utilizzati +- Verificare come interagiscono più profili + +### Takeaway + +I profili personalizzati consentono di passare tra diversi ambienti di calcolo con un singolo flag da riga di comando. +Utilizzare `nextflow config` per ispezionare la configurazione risolta prima dell'esecuzione. + +### Prossimi passi + +Scopri come personalizzare le richieste di risorse per singoli processi utilizzando il sistema di etichette dei processi di nf-core. + +--- + +## 4. Personalizzazione delle richieste di risorse + +### 4.1. Comprendere le etichette dei processi nelle pipeline nf-core + +Per semplicità, le pipeline nf-core utilizzano [**etichette dei processi**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) per standardizzare l'allocazione delle risorse in tutte le pipeline. +Ogni processo è etichettato con un'etichetta come `process_low`, `process_medium` o `process_high` per descrivere rispettivamente requisiti di risorse di calcolo bassi, medi o alti. +Queste etichette vengono convertite in richieste di risorse specifiche in uno dei file di configurazione situati nella directory `conf/` della pipeline. + +```groovy title="molkart/conf/base.config (estratto)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Si noti il moltiplicatore `task.attempt` - questo consente ai tentativi successivi di attività di richiedere più risorse, se la pipeline è impostata con `process.maxRetries > 1`. + +### 4.2. Sovrascrittura delle risorse per processi specifici + +Per un controllo più preciso, indirizzare singoli processi per nome: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Se proviamo a eseguire questa pipeline con la sovrascrittura precedente, il processo `CELLPOSE` richiederà 16 CPU e 32 GB di memoria invece del valore predefinito definito dalla sua etichetta. +Ciò causerà il fallimento della pipeline nel nostro ambiente attuale poiché non abbiamo così tanta RAM disponibile. +Nella prossima sezione impareremo come prevenire questi tipi di fallimenti. + +!!! tip "Suggerimento" + + Per trovare i nomi dei processi, consultare l'output di esecuzione della pipeline o verificare `.nextflow.log`. + I nomi dei processi seguono il modello `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### Takeaway + +Le pipeline nf-core utilizzano etichette dei processi per standardizzare l'allocazione delle risorse. +È possibile sovrascrivere le risorse per etichetta (influisce su più processi) o per nome (influisce su un processo specifico). + +### Prossimi passi + +Scopri come gestire i limiti di risorse in ambienti con risorse limitate come GitHub Codespaces. + +--- + +## 5. Gestione delle risorse in ambienti con risorse limitate + +### 5.1. Il problema dei limiti di risorse + +Se provassimo a eseguire molkart con un processo che richiede 16 CPU e 32 GB di memoria (come mostrato nella sezione 4.2), fallirebbe nel nostro ambiente attuale perché non abbiamo così tante risorse disponibili. +In un ambiente cluster con nodi più grandi, tali richieste verrebbero inviate allo scheduler. + +In ambienti con risorse limitate come GitHub Codespaces, senza limiti, Nextflow si rifiuterebbe di eseguire processi che superano le risorse disponibili. + +### 5.2. Impostazione dei limiti di risorse + +La direttiva `resourceLimits` limita le richieste di risorse ai valori specificati: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Questo dice a Nextflow: "Se qualsiasi processo richiede più di 2 CPU o 7 GB di memoria, limitalo invece a questi limiti." + +### 5.3. Aggiunta di limiti di risorse ai profili personalizzati + +Aggiornare i propri profili personalizzati per includere limiti appropriati: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "Avviso" + + Impostare limiti di risorse troppo bassi può causare il fallimento dei processi o un'esecuzione lenta. + La pipeline potrebbe dover utilizzare algoritmi meno intensivi in termini di memoria o elaborare i dati in blocchi più piccoli. + +### Takeaway + +Utilizzare `resourceLimits` per eseguire pipeline in ambienti con risorse limitate limitando le richieste di risorse dei processi. +Profili diversi possono avere limiti diversi appropriati per il loro ambiente. + +### Prossimi passi + +Hai completato la formazione principale su Nextflow per Bioimaging! + +--- + +## Takeaway + +Ora comprendi come configurare le pipeline Nextflow per diversi ambienti di calcolo. + +Competenze chiave che hai appreso: + +- **Precedenza della configurazione**: Come Nextflow risolve le impostazioni da più fonti +- **Profili nf-core**: Utilizzo dei profili integrati per container, test e utilità +- **Profili personalizzati**: Creazione dei propri profili per diversi ambienti +- **Etichette dei processi**: Comprensione e sovrascrittura delle richieste di risorse per etichetta +- **Limiti di risorse**: Gestione di ambienti con risorse limitate con `resourceLimits` +- **Ispezione della configurazione**: Utilizzo di `nextflow config` per debug e verifica delle impostazioni + +Queste competenze di configurazione sono trasferibili a qualsiasi pipeline Nextflow e ti aiuteranno a eseguire workflow in modo efficiente su macchine locali, cluster HPC e piattaforme cloud. + +### Prossimi passi + +Congratulazioni per aver completato il corso Nextflow per Bioimaging! + +Prossimi passi: + +- Compilare il sondaggio del corso per fornire feedback +- Consultare [Hello Nextflow](../hello_nextflow/index.md) per saperne di più sullo sviluppo di workflow +- Esplorare [Hello nf-core](../hello_nf-core/index.md) per approfondire gli strumenti nf-core +- Sfogliare altri corsi nelle [collezioni di formazione](../training_collections/index.md) diff --git a/docs/it/docs/nf4_science/imaging/index.md b/docs/it/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..aa6c7c8852 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/index.md @@ -0,0 +1,38 @@ +--- +title: Nextflow run per l'Imaging +hide: + - toc +--- + +# Nextflow run per l'Imaging + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questo corso di formazione è destinato ai ricercatori nel campo dell'imaging e della biologia spaziale interessati ad eseguire e personalizzare pipeline di analisi dati. +Insegna i concetti fondamentali di Nextflow relativi all'esecuzione, all'organizzazione e alla configurazione dei workflow utilizzando [nf-core/molkart](https://nf-co.re/molkart), una pipeline per l'elaborazione di dati di trascrittomica spaziale Molecular Cartography. +Le competenze acquisite qui sono trasferibili a qualsiasi pipeline Nextflow o nf-core. + +Iniziamo! Clicchi sul pulsante "Open in GitHub Codespaces" qui sotto per avviare l'ambiente di formazione (preferibilmente in una scheda separata), quindi continui a leggere mentre si carica. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Obiettivi di apprendimento + +Lavorando attraverso questo corso, imparerà ad applicare i concetti e gli strumenti fondamentali di Nextflow all'esecuzione di pipeline di analisi di imaging. + +Al termine di questo workshop sarà in grado di: + +- Avviare un workflow Nextflow localmente e monitorarne l'esecuzione +- Trovare e interpretare gli output (risultati) e i file di log generati da Nextflow +- Eseguire una pipeline nf-core con dati di test e input personalizzati +- Configurare l'esecuzione della pipeline utilizzando profili e file di parametri +- Gestire gli input utilizzando samplesheet e parametri da riga di comando + +## Pubblico e prerequisiti + +Questo corso presuppone una minima familiarità con quanto segue: + +- Esperienza con la riga di comando +- Familiarità di base con i formati di file di imaging (immagini TIFF, dati tabulari) + +Per i requisiti tecnici e la configurazione dell'ambiente, consulti il mini-corso [Configurazione dell'Ambiente](../../envsetup/). diff --git a/docs/it/docs/nf4_science/imaging/next_steps.md b/docs/it/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..4d12399873 --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Prossimi passi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni per aver completato la formazione Nextflow per il Bioimaging! + +Ora possiede le competenze fondamentali per eseguire e configurare pipeline Nextflow per l'analisi di dati di imaging. + +## Continui l'apprendimento + +Ecco alcuni passi successivi consigliati per approfondire la vostra conoscenza di Nextflow: + +### Esplori altre pipeline nf-core + +- **Esplori tutte le pipeline**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Sviluppi le vostre proprie pipeline + +Se desiderate imparare a scrivere pipeline Nextflow: + +- **[Hello Nextflow](../../hello_nextflow/)**: Formazione completa sullo sviluppo con Nextflow +- **[Side Quests](../../side_quests/)**: Argomenti avanzati per sviluppatori di pipeline + +### Si unisca alla community + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Ottenga supporto e si connetta con altri utenti +- **[nf-core Slack](https://nf-co.re/join)**: Si unisca alla community nf-core +- **[Seqera Community Forum](https://community.seqera.io)**: Ponga domande e condivida esperienze + +### Risorse aggiuntive + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Documentazione di riferimento completa +- **[nf-core Documentation](https://nf-co.re/docs)**: Linee guida e best practice + +## Si coinvolga + +- **Contribuisca a nf-core**: Aiuti a migliorare le pipeline o la documentazione +- **Condividete i vostri workflow**: Contribuite con le vostre proprie pipeline alla community +- **Partecipi agli eventi**: Si unisca al Nextflow Summit e alle sessioni di formazione della community + +Grazie per aver imparato con noi! diff --git a/docs/it/docs/nf4_science/imaging/survey.md b/docs/it/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..1ba8f042fa --- /dev/null +++ b/docs/it/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Sondaggio + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Grazie per aver completato la formazione Nextflow per Bioimaging! + +Apprezzeremmo molto il vostro feedback per aiutarci a migliorare questo materiale di formazione. + +Vi preghiamo di dedicare qualche minuto per completare il nostro breve sondaggio: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Le vostre risposte ci aiuteranno a comprendere cosa ha funzionato bene e cosa possiamo migliorare per i futuri partecipanti. + +Grazie per il vostro tempo e la vostra partecipazione! diff --git a/docs/it/docs/nf4_science/index.md b/docs/it/docs/nf4_science/index.md new file mode 100644 index 0000000000..f0bc40cc91 --- /dev/null +++ b/docs/it/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow per la Scienza +hide: + - toc +--- + +# Nextflow per la Scienza + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questi sono corsi che dimostrano come applicare i concetti e i componenti presentati nel corso per principianti [Hello Nextflow](../hello_nextflow/) a casi d'uso scientifici specifici. Ogni corso consiste in una serie di moduli di formazione progettati per aiutare i partecipanti a sviluppare progressivamente le proprie competenze. + +!!! exercise "Nextflow per la Genomica" + + !!! tip inline end "" + + :material-run-fast: Imparate a sviluppare una pipeline per la genomica in Nextflow. + + Questo è un corso per ricercatori che desiderano imparare a sviluppare le proprie pipeline genomiche. Il corso utilizza un caso d'uso di variant calling per dimostrare come sviluppare una pipeline genomica semplice ma funzionale. + + [Inizi la formazione Nextflow per la Genomica :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Nextflow per RNAseq" + + !!! tip inline end "" + + :material-run-fast: Imparate a sviluppare una pipeline per l'elaborazione di dati RNAseq in Nextflow. + + Questo è un corso per ricercatori che desiderano imparare a sviluppare le proprie pipeline RNAseq. Il corso utilizza un caso d'uso di elaborazione RNAseq bulk per dimostrare come sviluppare una pipeline RNAseq semplice ma funzionale. + + [Inizi la formazione Nextflow per RNAseq :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Nextflow per il Bioimaging" + + !!! tip inline end "" + + :material-run-fast: Imparate a eseguire pipeline per dati di imaging in Nextflow. + + Questo è un corso per ricercatori che desiderano imparare a eseguire e configurare pipeline di bioimaging. Il corso utilizza nf-core/molkart per dimostrare i pattern di utilizzo essenziali di Nextflow applicabili a qualsiasi pipeline. + + [Inizi la formazione Nextflow per il Bioimaging :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Ci faccia sapere quali altri domini e casi d'uso vorrebbe vedere trattati qui pubblicando nella [sezione Training](https://community.seqera.io/c/training/) del forum della comunità. diff --git a/docs/it/docs/nf4_science/rnaseq/00_orientation.md b/docs/it/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..591dc2487b --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'ambiente di formazione contiene tutto il software, il codice e i dati necessari per seguire questo corso di formazione, quindi non è necessario installare nulla autonomamente. +Tuttavia, è necessario un account (gratuito) per effettuare l'accesso, e si dovrebbe dedicare qualche minuto per familiarizzare con l'interfaccia. + +Se non lo ha ancora fatto, completi il mini-corso [Configurazione dell'Ambiente](../../envsetup/) prima di procedere. + +## Materiali forniti + +Nel corso di questa formazione, lavoreremo nella directory `nf4-science/rnaseq/`, nella quale è necessario spostarsi all'apertura dell'ambiente di formazione. +Questa directory contiene tutti i file di codice, i dati di test e i file accessori necessari. + +Si senta libero di esplorare i contenuti di questa directory; il modo più semplice per farlo è utilizzare l'esploratore di file sul lato sinistro dell'ambiente di formazione nell'interfaccia VSCode. +In alternativa, potete utilizzare il comando `tree`. +Nel corso della formazione, utilizziamo l'output di `tree` per rappresentare la struttura e i contenuti delle directory in una forma leggibile, talvolta con modifiche minori per chiarezza. + +Qui generiamo un sommario dei contenuti fino al secondo livello: + +```bash +tree . -L 3 +``` + +??? success "Contenuti della directory" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + Non si preoccupi se questo sembra molto; esamineremo le parti pertinenti in ogni fase del corso. + Questo è solo per fornire una panoramica generale. + +**Ecco un riepilogo di ciò che dovrebbe sapere per iniziare:** + +- **Il file `rnaseq.nf`** è la struttura dello script del workflow che svilupperemo. + +- **Il file `nextflow.config`** è un file di configurazione che imposta proprietà minime dell'ambiente. Può ignorarlo per ora. + +- **La directory `data`** contiene i dati di input e le risorse correlate: + + - _Un genoma di riferimento_ chiamato `genome.fa` costituito da una piccola regione del cromosoma umano 20 (da hg19/b37). + - _Dati RNAseq_ che sono stati ridotti a una piccola regione per mantenere ridotte le dimensioni dei file, nella directory `reads/`. + - _File CSV_ che elencano gli ID e i percorsi dei file di dati di esempio, per l'elaborazione in batch. + +- **La directory `solutions`** contiene gli script del workflow completi e i moduli risultanti da ogni fase del corso. + Sono destinati a essere utilizzati come riferimento per verificare il proprio lavoro e risolvere eventuali problemi. + Il numero nel nome del file corrisponde alla fase della parte pertinente del corso. + +!!!tip + + Se per qualsiasi motivo vi spostate fuori da questa directory, potete sempre eseguire questo comando per ritornarvi: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Ora, per iniziare il corso, cliccate sulla freccia nell'angolo in basso a destra di questa pagina. diff --git a/docs/it/docs/nf4_science/rnaseq/01_method.md b/docs/it/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..9252c4701f --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Parte 1: Panoramica del metodo e test manuali + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esistono molteplici metodi validi per elaborare e analizzare dati RNAseq in bulk. +Per questo corso, seguiamo il metodo descritto [qui](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) dai Dott. Simon Andrews e Laura Biggins presso il [Babraham Institute](https://www.babraham.ac.uk/). + +Il nostro obiettivo è sviluppare un workflow che implementi le seguenti fasi di elaborazione: eseguire il controllo qualità iniziale sulle read in un campione RNAseq in bulk, rimuovere le sequenze degli adapter dalle read, allineare le read a un genoma di riferimento e produrre un report completo di controllo qualità (QC). + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** Eseguire il QC sui dati delle read prima del trimming utilizzando FastQC +- **TRIM_GALORE:** Rimuovere le sequenze degli adapter ed eseguire il QC dopo il trimming utilizzando Trim Galore (che include Cutadapt e FastQC) +- **HISAT2_ALIGN:** Allineare le read al genoma di riferimento utilizzando Hisat2 +- **MULTIQC:** Generare un report QC completo utilizzando MultiQC + +Tuttavia, prima di iniziare a scrivere qualsiasi codice del workflow, proveremo i comandi manualmente su alcuni dati di test. +Gli strumenti necessari non sono installati nell'ambiente GitHub Codespaces, quindi li utilizzeremo tramite container (vedere [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Nota" + + Verificare di trovarsi nella directory `nf4-science/rnaseq`. L'ultima parte del percorso mostrato quando si digita `pwd` dovrebbe essere `rnaseq`. + +--- + +## 1. QC iniziale e rimozione degli adapter + +Otterremo un'immagine container che ha sia `fastqc` che `trim_galore` installati, la avvieremo in modo interattivo ed eseguiremo i comandi di trimming e QC su uno dei file di dati di esempio. + +### 1.1. Ottenere il container + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Questo produce il seguente output della console mentre il sistema scarica l'immagine: + +??? success "Output del comando" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Avviare il container in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Output del comando" + + ```console + + ``` +--> + +Il prompt cambierà in qualcosa come `(base) root@b645838b3314:/tmp#`, il che indica che ci si trova all'interno del container. + +La parte `-v ./data:/data` del comando consentirà di accedere ai contenuti della directory `data/` dall'interno del container. + +```bash +ls /data/reads +``` + +??? success "Output del comando" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Eseguire il primo comando `fastqc` + +Eseguiamo `fastqc` per raccogliere le metriche di controllo qualità sui dati delle read. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Output del comando" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Questo dovrebbe essere eseguito molto rapidamente. +È possibile trovare i file di output nella stessa directory dei dati originali: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Output" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Rimuovere le sequenze degli adapter con `trim_galore` + +Ora eseguiamo `trim_galore`, che include Cutadapt e FastQC, per rimuovere le sequenze degli adapter e raccogliere le metriche QC post-trimming. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +Il flag `--fastqc` fa sì che il comando esegua automaticamente una fase di raccolta QC dopo il completamento del trimming. + +_L'output è molto dettagliato, quindi quanto segue è abbreviato._ + +??? success "Output del comando" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +È possibile trovare i file di output nella directory di lavoro: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Output" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Spostare i file di output nel filesystem esterno al container + +Tutto ciò che rimane all'interno del container sarà inaccessibile per il lavoro futuro, quindi spostiamo questi file in una nuova directory. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Uscire dal container + +```bash +exit +``` + +--- + +## 2. Allineare le read al genoma di riferimento + +Otterremo un'immagine container che ha `hisat2` installato, la avvieremo in modo interattivo ed eseguiremo il comando di allineamento per allineare i dati RNAseq a un genoma di riferimento. + +### 2.1. Ottenere il container `hisat2` + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Output del comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. Avviare il container `hisat2` in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +Il comando è lo stesso di prima, con l'URI del container pertinente sostituito. + +### 2.3. Creare i file di indice del genoma per Hisat2 + +Hisat2 richiede che il riferimento del genoma sia fornito in un formato molto specifico e non può semplicemente utilizzare il file FASTA `genome.fa` che forniamo, quindi coglieremo questa opportunità per creare le risorse pertinenti. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +L'output è molto dettagliato, quindi quanto segue è abbreviato: + +<!-- TODO: switch to full output --> + +??? success "Output del comando" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Questo crea molteplici file di indice del genoma, che è possibile trovare nella directory di lavoro. + +```bash +ls genome_index.* +``` + +```console title="Output" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Li utilizzeremo tra un momento, ma prima generiamo un tarball compresso con questi file di indice del genoma; ne avremo bisogno più avanti e generarli non è tipicamente qualcosa che vogliamo fare come parte di un workflow. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Questo memorizza un tarball `genome_index.tar.gz` contenente i file di indice del genoma nella directory `data/` sul nostro filesystem, il che tornerà utile nella Parte 2 di questo corso. + +### 2.4. Eseguire il comando `hisat2` + +Ora possiamo eseguire il comando di allineamento, che esegue la fase di allineamento con `hisat2` e poi invia l'output a `samtools` per scrivere l'output come file BAM. + +L'input dei dati delle read è il file `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` che abbiamo generato con `trim_galore` nella fase precedente. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Output del comando" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Questo viene eseguito quasi istantaneamente perché è un file di test molto piccolo. +Su scala reale potrebbe richiedere molto più tempo. + +Ancora una volta è possibile trovare i file di output nella directory di lavoro: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Output" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Spostare i file di output nel filesystem esterno al container + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Uscire dal container + +```bash +exit +``` + +--- + +## 3. Generare un report QC completo + +Otterremo un'immagine container che ha `multiqc` installato, la avvieremo in modo interattivo ed eseguiremo un comando di generazione del report sui file di report FastQC prima/dopo. + +### 3.1. Ottenere il container `multiqc` + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Output del comando" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. Avviare il container `multiqc` in modo interattivo + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. Eseguire il comando `multiqc` + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Output del comando" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC è in grado di cercare nelle directory i report QC compatibili e aggrega tutto ciò che trova. + +Qui vediamo che lo strumento ha trovato tutti e tre i report QC che abbiamo generato: il QC iniziale eseguito con `fastqc`, il report post-trimming da `cutadapt` (prodotto tramite `trim_galore`) e il QC post-allineamento prodotto da `hisat2`. + +I file di output sono ancora una volta nella directory di lavoro: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Output" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Spostare i file di output nel filesystem esterno al container + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Uscire dal container + +```bash +exit +``` + +--- + +### Takeaway + +Sono stati testati tutti i comandi individuali in modo interattivo nei container pertinenti. + +### Passi successivi + +Imparare come inserire gli stessi comandi in un workflow multi-fase che utilizza container per eseguire il lavoro. diff --git a/docs/it/docs/nf4_science/rnaseq/02_single-sample.md b/docs/it/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..0bcf6a2746 --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Parte 2: Implementazione per singolo campione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa parte del corso, scriveremo il workflow più semplice possibile che racchiude tutti i comandi eseguiti nella Parte 1 per automatizzarne l'esecuzione, e ci limiteremo a processare un campione alla volta. + +Lo faremo in tre fasi: + +1. Scrivere un workflow a singolo stadio che esegue il passaggio iniziale di QC +2. Aggiungere il trimming degli adapter e il QC post-trimming +3. Aggiungere l'allineamento al genoma di riferimento + +!!! warning "Prerequisito" + + È necessario completare la Parte 1 del corso prima di iniziare questa lezione. + Nello specifico, il completamento delle sezioni 2.1-3 crea il file di indice del genoma (`data/genome_index.tar.gz`) richiesto per il passaggio di allineamento in questa lezione. + +--- + +## 1. Scrivere un workflow a singolo stadio che esegue il QC iniziale + +Iniziamo scrivendo un semplice workflow che esegue lo strumento FastQC su un file FASTQ contenente letture RNAseq single-end. + +Forniamo un file di workflow, `rnaseq.nf`, che delinea le parti principali del workflow. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Istruzioni INCLUDE dei moduli + +/* + * Parametri della pipeline + */ + +// Input primario + +workflow { + + // Crea canale di input + + // Chiama i processi + +} +``` + +Tenere presente che questo codice del workflow è corretto ma non è funzionale; il suo scopo è solo quello di servire come scheletro da utilizzare per scrivere il workflow effettivo. + +### 1.1. Creare una directory per memorizzare i moduli + +Creeremo moduli standalone per ciascun processo per facilitarne la gestione e il riutilizzo, quindi creiamo una directory per memorizzarli. + +```bash +mkdir modules +``` + +### 1.2. Creare un modulo per il processo di raccolta delle metriche QC + +Creiamo un file modulo chiamato `modules/fastqc.nf` per contenere il processo `FASTQC`: + +```bash +touch modules/fastqc.nf +``` + +Aprire il file nell'editor di codice e copiarvi il seguente codice: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Dovrebbe riconoscere tutti gli elementi da quanto appreso nella Parte 1 e nella Parte 2 di questa serie di formazione; l'unica modifica degna di nota è che questa volta stiamo usando `mode: symlink` per la direttiva `publishDir`, e stiamo usando un parametro per definire la `publishDir`. + +!!! note "Nota" + + Anche se i file di dati che stiamo utilizzando qui sono molto piccoli, in genomica possono diventare molto grandi. Ai fini della dimostrazione nell'ambiente di formazione, stiamo usando la modalità di pubblicazione 'symlink' per evitare copie di file non necessarie. Non dovrebbe farlo nei workflow finali, poiché perderà i risultati quando pulisce la directory `work`. + +### 1.3. Importare il modulo nel file del workflow + +Aggiungere l'istruzione `include { FASTQC } from './modules/fastqc.nf'` al file `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Istruzioni INCLUDE dei moduli +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Aggiungere una dichiarazione di input + +Dichiarare un parametro di input con un valore predefinito: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Input primario + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Creare un canale di input nel blocco workflow + +Utilizzare un factory di canale `.fromPath()` di base per creare il canale di input: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Crea canale di input da un percorso file + read_ch = channel.fromPath(params.reads) + + // Chiama i processi + +} +``` + +### 1.6. Chiamare il processo `FASTQC` sul canale di input + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Crea canale di input da un percorso file + read_ch = channel.fromPath(params.reads) + + // Controllo di qualità iniziale + FASTQC(read_ch) + +} +``` + +### 1.7. Eseguire il workflow per verificare che funzioni + +Potremmo usare il parametro `--reads` per specificare un input dalla riga di comando, ma durante lo sviluppo possiamo essere pigri e semplicemente usare il test predefinito che abbiamo configurato. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Questo dovrebbe essere eseguito molto rapidamente se avete completato la Parte 1 e ha già scaricato il container. +Se lo avete saltato, Nextflow scaricherà il container per voi; non deve fare nulla perché accada, ma potrebbe dover attendere fino a un minuto. + +Può trovare gli output in `results/fastqc` come specificato nel processo `FASTQC` dalla direttiva `publishDir`. + +```bash +ls results/fastqc +``` + +```console title="Output" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Aggiungere il trimming degli adapter e il controllo di qualità post-trimming + +Utilizzeremo il wrapper Trim_Galore, che raggruppa Cutadapt per il trimming stesso e FastQC per il controllo di qualità post-trimming. + +### 2.1. Creare un modulo per il processo di trimming e QC + +Creiamo un file modulo chiamato `modules/trim_galore.nf` per contenere il processo `TRIM_GALORE`: + +```bash +touch modules/trim_galore.nf +``` + +Aprire il file nell'editor di codice e copiarvi il seguente codice: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Importare il modulo nel file del workflow + +Aggiungere l'istruzione `include { TRIM_GALORE } from './modules/trim_galore.nf'` al file `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Istruzioni INCLUDE dei moduli +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Chiamare il processo sul canale di input + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Crea canale di input da un percorso file + read_ch = channel.fromPath(params.reads) + + // Controllo di qualità iniziale + FASTQC(read_ch) + + // Trimming degli adapter e QC post-trimming + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Eseguire il workflow per verificare che funzioni + +```bash +nextflow run rnaseq.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Anche questo dovrebbe essere eseguito molto rapidamente, dato che stiamo lavorando su un file di input così piccolo. + +Può trovare gli output in `results/trimming` come specificato nel processo `TRIM_GALORE` dalla direttiva `publishDir`. + +```bash +ls results/trimming +``` + +```console title="Output" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Allineare le letture al genoma di riferimento + +Infine possiamo eseguire il passaggio di allineamento del genoma utilizzando Hisat2, che emetterà anche metriche di controllo della qualità in stile FastQC. + +### 3.1. Creare un modulo per il processo HiSat2 + +Creiamo un file modulo chiamato `modules/hisat2_align.nf` per contenere il processo `HISAT2_ALIGN`: + +```bash +touch modules/hisat2_align.nf +``` + +Aprire il file nell'editor di codice e copiarvi il seguente codice: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Importare il modulo nel file del workflow + +Aggiungere l'istruzione `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` al file `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Istruzioni INCLUDE dei moduli +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Aggiungere una dichiarazione di parametro per fornire l'indice del genoma + +Dichiarare un parametro di input con un valore predefinito: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Input primario + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Archivio del genoma di riferimento + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Chiamare il processo `HISAT2_ALIGN` sulle letture trimmate prodotte da `TRIM_GALORE` + +Le letture trimmate si trovano nel canale `TRIM_GALORE.out.trimmed_reads` prodotto dal passaggio precedente. + +Inoltre, utilizziamo `file (params.hisat2_index_zip)` per fornire allo strumento Hisat2 il tarball compresso dell'indice del genoma. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Crea canale di input da un percorso file + read_ch = channel.fromPath(params.reads) + + // Controllo di qualità iniziale + FASTQC(read_ch) + + // Trimming degli adapter e QC post-trimming + TRIM_GALORE(read_ch) + + // Allineamento a un genoma di riferimento + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Eseguire il workflow per verificare che funzioni + +```bash +nextflow run rnaseq.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Può trovare gli output in `results/align` come specificato nel processo `HISAT2_ALIGN` dalla direttiva `publishDir`. + +```bash +ls results/align +``` + +```console title="Output" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Questo completa l'elaborazione di base che dobbiamo applicare a ciascun campione. + +_Aggiungeremo l'aggregazione dei report MultiQC nella Parte 2, dopo aver modificato il workflow per accettare più campioni contemporaneamente._ + +--- + +### Takeaway + +Sa come racchiudere tutti i passaggi principali per processare campioni RNAseq single-end individualmente. + +### Qual è il prossimo passo? + +Imparate come modificare il workflow per processare più campioni in parallelo, aggregare i report QC attraverso tutti i passaggi per tutti i campioni e abilitare l'esecuzione del workflow su dati RNAseq paired-end. diff --git a/docs/it/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/it/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..15fc4c4723 --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Parte 3: Implementazione con campioni multipli paired-end + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In questa parte finale del corso, porteremo il nostro semplice workflow al livello successivo trasformandolo in un potente strumento di automazione batch per gestire un numero arbitrario di campioni. +E mentre ci siamo, lo modificheremo anche per accettare dati paired-end, che sono più comuni negli studi più recenti. + +Lo faremo in tre fasi: + +1. Far accettare al workflow campioni di input multipli e parallelizzare l'esecuzione +2. Aggiungere la generazione di report QC completi +3. Passare a dati RNAseq paired-end + +--- + +## 1. Far accettare al workflow campioni di input multipli e parallelizzare l'esecuzione + +Dovremo cambiare il modo in cui gestiamo l'input. + +### 1.1. Modificare l'input primario in un CSV di percorsi di file invece di un singolo file + +Forniamo un file CSV contenente ID dei campioni e percorsi dei file FASTQ nella directory `data/`. +Questo file CSV include una riga di intestazione. +Si noti che i percorsi dei file FASTQ sono percorsi assoluti. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Rinominiamo il parametro di input primario in `input_csv` e modifichiamo il valore predefinito nel percorso del file `single-end.csv`. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Input primario + input_csv: Path = "data/single-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Aggiornare la factory del canale di input per gestire un CSV come input + +Vogliamo caricare il contenuto del file nel canale invece del solo percorso del file, quindi usiamo l'operatore `.splitCsv()` per analizzare il formato CSV, poi l'operatore `.map()` per acquisire l'informazione specifica che vogliamo (il percorso del file FASTQ). + +```groovy title="rnaseq.nf" linenums="16" + // Crea canale di input dal contenuto di un file CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Eseguire il workflow per verificare che funzioni + +```bash +nextflow run rnaseq.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Questa volta vediamo che ogni passaggio viene eseguito 6 volte, su ciascuno dei 6 file di dati che abbiamo fornito. + +Questo è tutto ciò che è servito per far eseguire il workflow su file multipli! +Nextflow gestisce tutto il parallelismo per noi. + +--- + +## 2. Aggregare le metriche QC di pre-elaborazione in un singolo report MultiQC + +Tutto questo produce molti report QC, e non vogliamo dover esaminare i singoli report. +Questo è il punto perfetto per inserire un passaggio di aggregazione dei report MultiQC! + +### 2.1. Creare un modulo per il processo di aggregazione QC + +Creiamo un file di modulo chiamato `modules/multiqc.nf` per ospitare il processo `MULTIQC`: + +```bash +touch modules/multiqc.nf +``` + +Aprire il file nell'editor di codice e copiarvi il seguente codice: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Importare il modulo nel file del workflow + +Aggiungere l'istruzione `include { MULTIQC } from './modules/multiqc.nf'` al file `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Module INCLUDE statements +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Aggiungere un parametro `report_id` e dargli un valore predefinito sensato + +```groovy title="rnaseq.nf" linenums="9" +params { + // Input primario + input_csv: Path = "data/single-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_single-end" +} +``` + +### 2.4. Chiamare il processo sugli output dei passaggi precedenti + +Dobbiamo dare al processo `MULTIQC` tutti gli output relativi al QC dai passaggi precedenti. + +Per questo, useremo l'operatore `.mix()`, che aggrega più canali in uno solo. + +Se avessimo quattro processi chiamati A, B, C e D con un semplice canale `.out` ciascuno, la sintassi sarebbe così: `A.out.mix( B.out, C.out, D.out )`. Come si potete vedere, lo si applica al primo dei canali che si vogliono combinare (non importa quale) e si aggiungono tutti gli altri, separati da virgole, nelle parentesi che seguono. + +Nel caso del nostro workflow, abbiamo i seguenti output da aggregare: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Quindi l'esempio di sintassi diventa: + +```groovy title="Applicare .mix() nella chiamata MULTIQC" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Questo raccoglierà i report QC per campione. +Ma poiché vogliamo aggregarli attraverso tutti i campioni, dobbiamo aggiungere l'operatore `collect()` per raccogliere i report di tutti i campioni in una singola chiamata a `MULTIQC`. +E dobbiamo anche dargli il parametro `report_id`. + +Questo ci dà quanto segue: + +```groovy title="La chiamata MULTIQC completa" linenums="33" + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Nel contesto del blocco del workflow completo, finisce per apparire così: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Crea canale di input dal contenuto di un file CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// Initial quality control + FASTQC(read_ch) + + // Adapter trimming and post-trimming QC + TRIM_GALORE(read_ch) + + // Alignment to a reference genome + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Eseguire il workflow per verificare che funzioni + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Questa volta vediamo una singola chiamata a MULTIQC aggiunta dopo le chiamate ai processi in cache: + +È possibile trovare gli output in `results/trimming` come specificato nel processo `TRIM_GALORE` dalla direttiva `publishDir`. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Output" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Quell'ultimo file `all_single-end.html` è il report aggregato completo, comodamente confezionato in un unico file HTML facile da consultare. + +--- + +## 3. Abilitare l'elaborazione di dati RNAseq paired-end + +Attualmente il nostro workflow può gestire solo dati RNAseq single-end. +È sempre più comune vedere dati RNAseq paired-end, quindi vogliamo essere in grado di gestirli. + +Rendere il workflow completamente agnostico del tipo di dati richiederebbe l'uso di funzionalità del linguaggio Nextflow leggermente più avanzate, quindi non lo faremo qui, ma possiamo creare una versione per l'elaborazione paired-end per dimostrare cosa deve essere adattato. + +### 3.1. Creare una copia del workflow chiamata `rnaseq_pe.nf` + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Modificare l'`input_csv` predefinito per puntare ai dati paired-end + +Forniamo un secondo file CSV contenente ID dei campioni e percorsi di file FASTQ paired nella directory `data/` + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Modifichiamo il valore predefinito di `input_csv` nel percorso del file `paired-end.csv`. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Input primario + input_csv: Path = "data/paired-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_single-end" +} +``` + +### 3.3. Aggiornare la factory del canale + +Dobbiamo dire all'operatore `.map()` di acquisire ora entrambi i percorsi dei file FASTQ. + +Quindi `row -> file(row.fastq_path)` diventa `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Crea canale di input dal contenuto di un file CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Creare una versione paired-end del processo FASTQC + +Creiamo una copia del modulo in modo da avere entrambe le versioni a disposizione. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Aprire il nuovo file di modulo `fastqc_pe.nf` nell'editor di codice e apportare le seguenti modifiche al codice: + +- Modificare `fastqc $reads` in `fastqc ${reads}` nel blocco `script` (riga 17) in modo che l'input `reads` venga decompresso, poiché ora è una tupla di due percorsi invece di un singolo percorso. +- Sostituire `${reads.simpleName}` con un carattere jolly (`*`) per evitare di dover gestire i file di output individualmente. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Tecnicamente questo generalizza il processo `FASTQC` in modo da renderlo in grado di gestire sia dati RNAseq single-end che paired-end. + +Infine, aggiornare l'istruzione di importazione del modulo per usare la versione paired-end del modulo. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Creare una versione paired-end del processo TRIM_GALORE + +Creare una copia del modulo in modo da avere entrambe le versioni a disposizione. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Aprire il nuovo file di modulo `trim_galore_pe.nf` nell'editor di codice e apportare le seguenti modifiche al codice: + +- Modificare la dichiarazione di input da `path reads` a `tuple path(read1), path(read2)` +- Aggiornare il comando nel blocco `script`, sostituendo `$reads` con `--paired ${read1} ${read2}` +- Aggiornare le dichiarazioni di output per riflettere i file aggiunti e le diverse convenzioni di denominazione, usando caratteri jolly per evitare di dover elencare tutto. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Infine, aggiornare l'istruzione di importazione del modulo per usare la versione paired-end del modulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Aggiornare la chiamata al processo MULTIQC per aspettarsi due report da TRIM_GALORE + +Il processo `TRIM_GALORE` ora produce un canale di output aggiuntivo, quindi dobbiamo fornirlo a MultiQC. + +Sostituire `TRIM_GALORE.out.fastqc_reports,` con `TRIM_GALORE.out.fastqc_reports_1,` più `TRIM_GALORE.out.fastqc_reports_2,`: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Comprehensive QC report generation + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Mentre siamo su MultiQC, aggiorniamo anche il valore predefinito del parametro `report_id` da `"all_single-end"` a `"all_paired-end"`. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Input primario + input_csv: Path = "data/paired-end.csv" + + // Reference genome archive + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Report ID + report_id: String = "all_paired-end" +} +``` + +### 3.7. Creare una versione paired-end del processo HISAT2_ALIGN + +Creare una copia del modulo in modo da avere entrambe le versioni a disposizione. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Aprire il nuovo file di modulo `hisat2_align_pe.nf` nell'editor di codice e apportare le seguenti modifiche al codice: + +- Modificare la dichiarazione di input da `path reads` a `tuple path(read1), path(read2)` +- Aggiornare il comando nel blocco `script`, sostituendo `-U $reads` con `-1 ${read1} -2 ${read2}` +- Sostituire tutte le istanze di `${reads.simpleName}` con `${read1.simpleName}` nel comando nel blocco `script` così come nelle dichiarazioni di output. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Infine, aggiornare l'istruzione di importazione del modulo per usare la versione paired-end del modulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Eseguire il workflow per verificare che funzioni + +Non usiamo `-resume` poiché questo non verrebbe messo in cache, e c'è il doppio dei dati da elaborare rispetto a prima, ma dovrebbe comunque completarsi in meno di un minuto. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +Ed è tutto! Ora abbiamo due versioni leggermente divergenti del nostro workflow, una per dati single-end read e una per dati paired-end. +Il passo logico successivo sarebbe rendere il workflow in grado di accettare entrambi i tipi di dati al volo, che è al di fuori dello scopo di questo corso, ma potremmo affrontarlo in un seguito. + +--- + +### Takeaway + +Sapete come adattare un workflow per campione singolo per parallelizzare l'elaborazione di campioni multipli, generare un report QC completo e adattare il workflow per utilizzare dati read paired-end se necessario. + +### Cosa seguirà? + +Congratulazioni, ha completato il mini-corso Nextflow Per RNAseq! Celebrate il vostro successo e prendetevi una meritata pausa! + +Successivamente, vi chiediamo di completare un breve sondaggio sulla vostra esperienza con questo corso di formazione, poi vi porteremo a una pagina con collegamenti a ulteriori risorse di formazione e collegamenti utili. diff --git a/docs/it/docs/nf4_science/rnaseq/index.md b/docs/it/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..d058cd7345 --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: Nextflow per RNAseq +hide: + - toc +--- + +# Nextflow per RNAseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questo corso di formazione è destinato a ricercatori in trascrittomica e campi correlati interessati allo sviluppo o alla personalizzazione di pipeline di analisi dati. +Si basa sulla formazione per principianti [Hello Nextflow](../../hello_nextflow/) e dimostra come utilizzare Nextflow nel contesto specifico dell'analisi RNAseq bulk. + +In particolare, questo corso dimostra come implementare una semplice pipeline di elaborazione RNAseq bulk per rimuovere le sequenze adattatrici, allineare le letture a un genoma di riferimento ed eseguire il controllo qualità (QC) in diverse fasi. + +Cominciamo! Clicchi sul pulsante "Open in GitHub Codespaces" qui sotto per avviare l'ambiente di formazione (preferibilmente in una scheda separata), quindi continui a leggere mentre si carica. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Obiettivi di apprendimento + +Seguendo questo corso, imparerà ad applicare i concetti e gli strumenti fondamentali di Nextflow a un caso d'uso tipico di RNAseq. + +Al termine di questo workshop sarà in grado di: + +- Scrivere un workflow lineare per applicare metodi di elaborazione e QC di base per RNAseq +- Gestire appropriatamente file specifici del dominio come FASTQ e risorse di genomi di riferimento +- Gestire dati di sequenziamento single-end e paired-end +- Sfruttare il paradigma dataflow di Nextflow per parallelizzare l'elaborazione RNAseq per campione +- Aggregare report di QC attraverso più fasi e campioni utilizzando operatori di canale appropriati + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Prerequisiti + +Il corso presuppone una minima familiarità con quanto segue: + +- Strumenti e formati di file comunemente utilizzati in questo dominio scientifico +- Esperienza con la riga di comando +- Concetti e strumenti fondamentali di Nextflow trattati nella formazione per principianti [Hello Nextflow](../../hello_nextflow/) + +Per i requisiti tecnici e la configurazione dell'ambiente, consulti il mini-corso [Configurazione dell'Ambiente](../../envsetup/). diff --git a/docs/it/docs/nf4_science/rnaseq/next_steps.md b/docs/it/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..ffddc03545 --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Prossimi Passi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Congratulazioni ancora per aver completato il corso di formazione Nextflow per RNAseq e grazie per aver completato il nostro questionario! + +--- + +## 1. I 3 modi migliori per migliorare le sue competenze in Nextflow + +Ecco le nostre tre raccomandazioni principali su cosa fare dopo, basate sul corso che ha appena completato. + +### 1.1. Applicare Nextflow ad altri casi d'uso di analisi scientifica + +**Consulti la pagina [Nextflow for Science](../nf4_science/index.md)** per un elenco di altri brevi corsi autonomi che dimostrano come applicare i concetti e i meccanismi di base presentati in Hello Nextflow a casi d'uso comuni di analisi scientifica. + +Se non vede il suo dominio rappresentato da un caso d'uso pertinente, fatecelo sapere nel [Forum della Community](https://community.seqera.io/) così potremo aggiungerlo alla nostra lista di sviluppo. + +### 1.2. Iniziare con nf-core + +**[nf-core](https://nf-co.re/)** è uno sforzo collaborativo mondiale per sviluppare pipeline open-source standardizzate per un'ampia gamma di applicazioni di ricerca scientifica. +Il progetto include [oltre 100 pipeline](https://nf-co.re/pipelines/) disponibili per l'uso immediato e [ben oltre 1400 moduli di processo](https://nf-co.re/modules/) che possono essere integrati nei suoi progetti, oltre a un ricco set di strumenti per sviluppatori. + +Il corso di formazione **[Hello nf-core](../../hello_nf-core/index.md)** la introdurrà alle pipeline curate dalla community nf-core e al framework di sviluppo, progettato per aiutarla a scrivere workflow riproducibili, scalabili e standardizzati. Imparerà come utilizzare le pipeline nf-core esistenti, contribuire al loro sviluppo e persino iniziare a costruire le sue, supportato da best practice e da una community vivace. Se è pronto ad applicare le sue competenze Nextflow in progetti del mondo reale, questo è il passo successivo perfetto. + +### 1.3. Padroneggiare funzionalità più avanzate di Nextflow + +Nei corsi Hello, manteniamo intenzionalmente basso il livello di complessità tecnica per evitare di sovraccaricarla con informazioni non necessarie per iniziare con Nextflow. +Man mano che procede con il suo lavoro, vorrà imparare come utilizzare l'intero set di funzionalità e la potenza di Nextflow. + +A tal fine, stiamo attualmente lavorando a una **raccolta di [Side Quests](../side_quests/index.md)**, che sono pensati come brevi corsi autonomi che approfondiscono argomenti specifici come il testing e la gestione dei metadati. + +--- + +## 2. Scopra Seqera Platform + +**[Seqera Platform](https://seqera.io/) è il modo migliore per eseguire Nextflow nella pratica.** + +È una piattaforma basata su cloud sviluppata dai creatori di Nextflow che potete connettere alla sua infrastruttura di calcolo (sia locale, HPC o cloud) per rendere molto più semplice lanciare e gestire i suoi workflow, nonché gestire i suoi dati ed eseguire analisi in modo interattivo in un ambiente cloud. + +Il Free Tier è disponibile per l'uso gratuito da parte di tutti (con quote di utilizzo). +Gli accademici qualificati possono ottenere accesso gratuito a livello Pro (senza limitazioni di utilizzo) attraverso l'[Academic Program](https://seqera.io/academic/program/). + +Dia un'occhiata ai [tutorial di Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) per vedere se questo potrebbe esserle utile. + +--- + +### Per ora è tutto! + +**Buona fortuna nel suo percorso con Nextflow e non esitate a farci sapere nel [Forum della Community](https://community.seqera.io/) cos'altro potremmo fare per aiutarla.** diff --git a/docs/it/docs/nf4_science/rnaseq/survey.md b/docs/it/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..0f24b48327 --- /dev/null +++ b/docs/it/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Sondaggio di feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Prima di proseguire, completi questo breve sondaggio di 5 domande per valutare la formazione, condividere eventuali feedback sulla sua esperienza e farci sapere cos'altro potremmo fare per aiutarla nel suo percorso con Nextflow. + +Dovrebbe richiedere meno di un minuto per completarlo. Grazie per aiutarci a migliorare i nostri materiali di formazione per tutti! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/it/docs/side_quests/README.md b/docs/it/docs/side_quests/README.md new file mode 100644 index 0000000000..7f4c08d01e --- /dev/null +++ b/docs/it/docs/side_quests/README.md @@ -0,0 +1 @@ +Questo è un segnaposto per i futuri Side Quest (formazioni approfondite). I documenti attualmente presenti qui sono bozze basate su contenuti riadattati da altre fonti. diff --git a/docs/it/docs/side_quests/debugging.md b/docs/it/docs/side_quests/debugging.md new file mode 100644 index 0000000000..2274b7e988 --- /dev/null +++ b/docs/it/docs/side_quests/debugging.md @@ -0,0 +1,1671 @@ +# Debug dei Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Il debug è una competenza critica che può farvi risparmiare ore di frustrazione e aiutarvi a diventare sviluppatori Nextflow più efficaci. Durante la vostra carriera, specialmente quando state iniziando, incontrerete bug durante la costruzione e manutenzione dei vostri workflow. Imparare approcci sistematici al debug vi aiuterà a identificare e risolvere i problemi rapidamente. + +### Obiettivi di apprendimento + +In questa missione secondaria, esploreremo **tecniche sistematiche di debug** per i workflow Nextflow: + +- **Debug degli errori di sintassi**: Utilizzo efficace delle funzionalità IDE e dei messaggi di errore di Nextflow +- **Debug dei canali**: Diagnosi dei problemi di flusso dati e dei problemi di struttura dei canali +- **Debug dei processi**: Investigazione dei fallimenti di esecuzione e dei problemi di risorse +- **Strumenti di debug integrati**: Utilizzo della modalità preview, stub running e directory di lavoro di Nextflow +- **Approcci sistematici**: Una metodologia in quattro fasi per un debug efficiente + +Alla fine, avrete una metodologia di debug robusta che trasforma frustranti messaggi di errore in chiare roadmap per le soluzioni. + +### Prerequisiti + +Prima di intraprendere questa missione secondaria, dovreste: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso per principianti equivalente. +- Essere a vostro agio nell'uso di concetti e meccanismi base di Nextflow (processi, canali, operatori) + +**Opzionale:** Raccomandiamo di completare prima la missione secondaria [Funzionalità IDE per lo Sviluppo Nextflow](./ide_features.md). +Quella copre in modo completo le funzionalità IDE che supportano il debug (evidenziazione sintassi, rilevamento errori, ecc.), che useremo intensamente qui. + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non l'avete ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/debugging +``` + +Potete impostare VSCode per focalizzarsi su questa directory: + +```bash +code . +``` + +#### Rivedere i materiali + +Troverete un insieme di workflow di esempio con vari tipi di bug che useremo per la pratica: + +??? abstract "Contenuto della directory" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Questi file rappresentano scenari comuni di debug che incontrerete nello sviluppo reale. + +#### Rivedere l'assegnazione + +La vostra sfida è eseguire ogni workflow, identificare gli errori e correggerli. + +Per ogni workflow con bug: + +1. **Eseguire il workflow** e osservare l'errore +2. **Analizzare il messaggio di errore**: cosa vi sta dicendo Nextflow? +3. **Localizzare il problema** nel codice usando gli indizi forniti +4. **Correggere il bug** e verificare che la vostra soluzione funzioni +5. **Ripristinare il file** prima di passare alla sezione successiva (usare `git checkout <filename>`) + +Gli esercizi procedono da semplici errori di sintassi a problemi di runtime più sottili. +Le soluzioni sono discusse inline, ma provate a risolvere ognuno da soli prima di leggere avanti. + +#### Checklist di preparazione + +Pensate di essere pronti per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro appropriatamente +- [ ] Comprendo l'assegnazione + +Se potete spuntare tutte le caselle, siete pronti per iniziare. + +--- + +## 1. Errori di Sintassi + +Gli errori di sintassi sono il tipo più comune di errore che incontrerete quando scrivete codice Nextflow. Avvengono quando il codice non si conforma alle regole di sintassi attese del DSL Nextflow. Questi errori impediscono al vostro workflow di eseguire del tutto, quindi è importante imparare come identificarli e correggerli rapidamente. + +### 1.1. Parentesi graffe mancanti + +Uno degli errori di sintassi più comuni, e talvolta uno dei più complessi da debuggare è quello delle **parentesi mancanti o non corrispondenti**. + +Iniziamo con un esempio pratico. + +#### Eseguire il pipeline + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Elementi chiave dei messaggi di errore di sintassi:** + +- **File e posizione**: Mostra quale file e quale riga/colonna contengono l'errore (`bad_syntax.nf:24:1`) +- **Descrizione dell'errore**: Spiega cosa ha trovato il parser che non si aspettava (`Unexpected input: '<EOF>'`) +- **Indicatore EOF**: Il messaggio `<EOF>` (End Of File) indica che il parser ha raggiunto la fine del file mentre ancora si aspettava più contenuto - un segno classico di parentesi graffe non chiuse + +#### Controllare il codice + +Ora, esaminiamo `bad_syntax.nf` per capire cosa sta causando l'errore: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Missing closing brace for the process + +workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) +} +``` + +Per gli scopi di questo esempio abbiamo lasciato un commento per mostrarvi dove si trova l'errore. L'estensione Nextflow per VSCode dovrebbe anche darvi alcuni suggerimenti su cosa potrebbe essere sbagliato, mettendo la parentesi graffa non corrispondente in rosso e evidenziando la fine prematura del file: + +![Bad syntax](img/bad_syntax.png) + +**Strategia di debug per errori di parentesi:** + +1. Usare la corrispondenza delle parentesi di VS Code (posizionare il cursore vicino a una parentesi) +2. Controllare il pannello Problemi per messaggi relativi alle parentesi +3. Assicurarsi che ogni `{` di apertura abbia una `}` di chiusura corrispondente + +#### Correggere il codice + +Sostituire il commento con la parentesi graffa di chiusura mancante: + +=== "Dopo" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Add the missing closing brace + + workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) + } + ``` + +=== "Prima" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Missing closing brace for the process + + workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) + } + ``` + +#### Eseguire il pipeline + +Ora eseguite nuovamente il workflow per confermare che funzioni: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Uso di parole chiave o direttive di processo errate + +Un altro errore di sintassi comune è una **definizione di processo non valida**. Questo può accadere se dimenticate di definire blocchi richiesti o usate direttive errate nella definizione del processo. + +#### Eseguire il pipeline + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Controllare il codice + +L'errore indica una "Invalid process definition" e mostra il contesto intorno al problema. Guardando le righe 3-7, possiamo vedere `inputs:` alla riga 4, che è il problema. Esaminiamo `invalid_process.nf`: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // ERROR: Should be 'input' not 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) +} +``` + +Guardando la riga 4 nel contesto dell'errore, possiamo individuare il problema: stiamo usando `inputs` invece della corretta direttiva `input`. L'estensione Nextflow per VSCode segnalerà anche questo: + +![Invalid process message](img/invalid_process_message.png) + +#### Correggere il codice + +Sostituire la parola chiave errata con quella corretta facendo riferimento [alla documentazione](https://www.nextflow.io/docs/latest/process.html#): + +=== "Dopo" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Fixed: Changed 'inputs' to 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) + } + ``` + +=== "Prima" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // ERROR: Should be 'input' not 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Crea canale di input + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chiama il processo con il canale di input + PROCESS_FILES(input_ch) + } + ``` + +#### Eseguire il pipeline + +Ora eseguite nuovamente il workflow per confermare che funzioni: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Uso di nomi di variabili errati + +I nomi delle variabili che usate nei vostri blocchi script devono essere validi, derivati o dagli input o da codice groovy inserito prima dello script. Ma quando state gestendo la complessità all'inizio dello sviluppo del pipeline, è facile fare errori nella denominazione delle variabili, e Nextflow ve lo farà sapere rapidamente. + +#### Eseguire il pipeline + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +L'errore viene catturato al momento della compilazione e punta direttamente alla variabile non definita alla riga 17, con un cursore che indica esattamente dove si trova il problema. + +#### Controllare il codice + +Esaminiamo `no_such_var.nf`: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +Il messaggio di errore indica che la variabile non è riconosciuta nel template dello script, e eccola lì - dovreste essere in grado di vedere `${undefined_var}` usato nel blocco script, ma non definito altrove. + +#### Correggere il codice + +Se ricevete un errore 'No such variable', potete correggerlo definendo la variabile (correggendo i nomi delle variabili di input o modificando il codice groovy prima dello script), o rimuovendola dal blocco script se non è necessaria: + +=== "Dopo" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Removed the line with undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Prima" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Eseguire il pipeline + +Ora eseguite nuovamente il workflow per confermare che funzioni: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Uso errato delle variabili Bash + +Iniziando con Nextflow, può essere difficile capire la differenza tra variabili Nextflow (Groovy) e Bash. Questo può generare un'altra forma di errore di variabile errata che appare quando si cerca di usare variabili nel contenuto Bash del blocco script. + +#### Eseguire il pipeline + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Controllare il codice + +L'errore punta alla riga 13 dove viene usato `${prefix}`. Esaminiamo `bad_bash_var.nf` per vedere cosa sta causando il problema: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +In questo esempio, stiamo definendo la variabile `prefix` in Bash, ma in un processo Nextflow la sintassi `$` che abbiamo usato per riferirci ad essa (`${prefix}`) viene interpretata come una variabile Groovy, non Bash. La variabile non esiste nel contesto Groovy, quindi otteniamo un errore 'no such variable'. + +#### Correggere il codice + +Se volete usare una variabile Bash, dovete escludere il simbolo del dollaro in questo modo: + +=== "Dopo" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Prima" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +Questo dice a Nextflow di interpretarla come una variabile Bash. + +#### Eseguire il pipeline + +Ora eseguite nuovamente il workflow per confermare che funzioni: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Variabili Groovy vs Bash" + + Per semplici manipolazioni di variabili come concatenazione di stringhe o operazioni di prefisso/suffisso, è solitamente più leggibile usare variabili Groovy nella sezione script piuttosto che variabili Bash nel blocco script: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Questo approccio evita la necessità di escludere i simboli del dollaro e rende il codice più facile da leggere e mantenere. + +### 1.5. Istruzioni fuori dal blocco Workflow + +L'estensione Nextflow per VSCode evidenzia problemi con la struttura del codice che causeranno errori. Un esempio comune è la definizione di canali fuori dal blocco `workflow {}` - questo ora è imposto come errore di sintassi. + +#### Eseguire il pipeline + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Il messaggio di errore indica chiaramente il problema: le istruzioni (come le definizioni di canali) non possono essere mischiate con le dichiarazioni di script fuori da un blocco workflow o process. + +#### Controllare il codice + +Esaminiamo `badpractice_syntax.nf` per vedere cosa sta causando l'errore: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +Anche l'estensione VSCode evidenzierà la variabile `input_ch` come definita fuori dal blocco workflow: + +![Non-lethal syntax error](img/nonlethal.png) + +#### Correggere il codice + +Spostare la definizione del canale all'interno del blocco workflow: + +=== "Dopo" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Moved inside workflow block + PROCESS_FILES(input_ch) + } + ``` + +=== "Prima" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Eseguire il pipeline + +Eseguite nuovamente il workflow per confermare che la correzione funzioni: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Mantenete i vostri canali di input definiti all'interno del blocco workflow, e in generale seguite qualsiasi altra raccomandazione che l'estensione fa. + +### Takeaway + +Potete identificare e correggere sistematicamente gli errori di sintassi usando i messaggi di errore di Nextflow e gli indicatori visivi dell'IDE. Gli errori di sintassi comuni includono parentesi graffe mancanti, parole chiave di processo errate, variabili non definite e uso improprio di variabili Bash vs. Nextflow. L'estensione VSCode aiuta a catturare molti di questi prima del runtime. Con queste competenze di debug della sintassi nel vostro toolkit, sarete in grado di risolvere rapidamente gli errori di sintassi più comuni di Nextflow e passare ad affrontare problemi di runtime più complessi. + +### Prossimi passi? + +Imparate a debuggare errori di struttura dei canali più complessi che si verificano anche quando la sintassi è corretta. + +--- + +## 2. Errori di Struttura dei Canali + +Gli errori di struttura dei canali sono più sottili degli errori di sintassi perché il codice è sintatticamente corretto, ma le forme dei dati non corrispondono a ciò che i processi si aspettano. Nextflow cercherà di eseguire il pipeline, ma potrebbe trovare che il numero di input non corrisponde a ciò che si aspetta e fallire. Questi errori tipicamente appaiono solo al runtime e richiedono una comprensione dei dati che fluiscono attraverso il vostro workflow. + +!!! tip "Debug dei Canali con `.view()`" + + Durante questa sezione, ricordate che potete usare l'operatore `.view()` per ispezionare il contenuto del canale in qualsiasi punto del vostro workflow. Questo è uno degli strumenti di debug più potenti per capire i problemi di struttura dei canali. Esploreremo questa tecnica in dettaglio nella sezione 2.4, ma sentitevi liberi di usarla mentre lavorate attraverso gli esempi. + + ```groovy + my_channel.view() // Shows what's flowing through the channel + ``` + +### 2.1. Numero Errato di Canali di Input + +Questo errore si verifica quando passate un numero diverso di canali rispetto a quelli che un processo si aspetta. + +#### Eseguire il pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Controllare il codice + +Il messaggio di errore afferma chiaramente che la chiamata si aspettava 1 argomento ma ne ha ricevuti 2, e punta alla riga 23. Esaminiamo `bad_number_inputs.nf`: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Passing 2 channels but process expects only 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Dovreste vedere la chiamata a `PROCESS_FILES` non corrispondente, che fornisce più canali di input quando il processo ne definisce solo uno. L'estensione VSCode sottolineerà anche la chiamata al processo in rosso e fornirà un messaggio diagnostico quando ci passate sopra con il mouse: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Correggere il codice + +Per questo esempio specifico, il processo si aspetta un singolo canale e non richiede il secondo canale, quindi possiamo correggerlo passando solo il canale `samples_ch`: + +=== "Dopo" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Fixed: Pass only the channel the process expects + PROCESS_FILES(samples_ch) + } + ``` + +=== "Prima" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Passing 2 channels but process expects only 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Eseguire il pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Più comunemente di questo esempio, potreste aggiungere input aggiuntivi a un processo e dimenticare di aggiornare la chiamata al workflow di conseguenza, il che può portare a questo tipo di errore. Fortunatamente, questo è uno degli errori più facili da capire e correggere, poiché il messaggio di errore è abbastanza chiaro sulla mancata corrispondenza. + +### 2.2. Esaurimento del Canale (Il Processo Viene Eseguito Meno Volte del Previsto) + +Alcuni errori di struttura dei canali sono molto più sottili e non producono alcun errore. Probabilmente il più comune di questi riflette una sfida che i nuovi utenti Nextflow affrontano nel capire che i canali queue possono esaurirsi e rimanere senza elementi, il che significa che il workflow finisce prematuramente. + +#### Eseguire il pipeline + +```bash +nextflow run exhausted.nf +``` + +??? success "Output del comando" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Questo workflow si completa senza errori, ma elabora solo un singolo campione! + +#### Controllare il codice + +Esaminiamo `exhausted.nf` per vedere se è corretto: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Define variables in Groovy code before the script + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Il processo viene eseguito solo una volta invece di tre volte perché il canale `reference_ch` è un canale queue che si esaurisce dopo la prima esecuzione del processo. Quando un canale si esaurisce, l'intero processo si ferma, anche se altri canali hanno ancora elementi. + +Questo è un pattern comune in cui avete un singolo file di riferimento che deve essere riutilizzato attraverso più campioni. La soluzione è convertire il canale di riferimento in un canale value che può essere riutilizzato indefinitamente. + +#### Correggere il codice + +Ci sono un paio di modi per affrontare questo a seconda di quanti file sono coinvolti. + +**Opzione 1**: Avete un singolo file di riferimento che state riutilizzando molto. Potete semplicemente creare un tipo di canale value, che può essere usato più e più volte. Ci sono tre modi per farlo: + +**1a** Usare `channel.value()`: + +```groovy title="exhausted.nf (corretto - Opzione 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Value channel can be reused + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Usare l'[operatore](https://www.nextflow.io/docs/latest/reference/operator.html#first) `first()`: + +```groovy title="exhausted.nf (corretto - Opzione 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Usare l'[operatore](https://www.nextflow.io/docs/latest/reference/operator.html#collect) `collect()`: + +```groovy title="exhausted.nf (corretto - Opzione 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Opzione 2**: In scenari più complessi, forse dove avete più file di riferimento per tutti i campioni nel canale dei campioni, potete usare l'operatore `combine` per creare un nuovo canale che combina i due canali in tuple: + +```groovy title="exhausted.nf (corretto - Opzione 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Creates cartesian product + + PROCESS_FILES(combined_ch) +} +``` + +L'operatore `.combine()` genera un prodotto cartesiano dei due canali, quindi ogni elemento in `reference_ch` sarà accoppiato con ogni elemento in `input_ch`. Questo permette al processo di eseguire per ogni campione mentre si usa ancora il riferimento. + +Questo richiede che l'input del processo sia regolato. Nel nostro esempio, l'inizio della definizione del processo dovrebbe essere regolato come segue: + +```groovy title="exhausted.nf (corretto - Opzione 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Questo approccio potrebbe non essere adatto in tutte le situazioni. + +#### Eseguire il pipeline + +Provate una delle correzioni sopra ed eseguite nuovamente il workflow: + +```bash +nextflow run exhausted.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Dovreste ora vedere tutti e tre i campioni elaborati invece di uno solo. + +### 2.3. Struttura del Contenuto del Canale Errata + +Quando i workflow raggiungono un certo livello di complessità, può essere un po' difficile tenere traccia delle strutture interne di ogni canale, e le persone generano comunemente mancate corrispondenze tra ciò che il processo si aspetta e ciò che il canale contiene effettivamente. Questo è più sottile del problema di cui abbiamo discusso in precedenza, dove il numero di canali era errato. In questo caso, potete avere il numero corretto di canali di input, ma la struttura interna di uno o più di quei canali non corrisponde a ciò che il processo si aspetta. + +#### Eseguire il pipeline + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Output del comando" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Controllare il codice + +Le parentesi quadre nel messaggio di errore forniscono l'indizio qui - il processo sta trattando la tupla come un singolo valore, che non è ciò che vogliamo. Esaminiamo `bad_channel_shape.nf`: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Potete vedere che stiamo generando un canale composto da tuple: `['sample1', 'file1.txt']`, ma il processo si aspetta un singolo valore, `val sample_name`. Il comando eseguito mostra che il processo sta cercando di creare un file chiamato `[sample3, file3.txt]_output.txt`, che non è l'output previsto. + +#### Correggere il codice + +Per correggere questo, se il processo richiede entrambi gli input potremmo regolare il processo per accettare una tupla: + +=== "Opzione 1: Accettare tupla nel processo" + + === "Dopo" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Fixed: Accept tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Prima" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Opzione 2: Estrarre primo elemento" + + === "Dopo" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Fixed: Extract first element + } + ``` + + === "Prima" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Eseguire il pipeline + +Scegliete una delle soluzioni ed eseguite nuovamente il workflow: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Tecniche di Debug dei Canali + +#### Uso di `.view()` per l'Ispezione dei Canali + +Lo strumento di debug più potente per i canali è l'operatore `.view()`. Con `.view()`, potete capire la forma dei vostri canali in tutte le fasi per aiutare con il debug. + +#### Eseguire il pipeline + +Eseguite `bad_channel_shape_viewed.nf` per vedere questo in azione: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Controllare il codice + +Esaminiamo `bad_channel_shape_viewed.nf` per vedere come viene usato `.view()`: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debug: Show original channel content + .map { tuple -> tuple[0] } // Transform: Extract first element + .view { "After mapping: $it" } // Debug: Show transformed channel content + + PROCESS_FILES(input_ch) +} +``` + +#### Correggere il codice + +Per evitarvi di usare eccessivamente operazioni `.view()` in futuro per capire il contenuto dei canali, è consigliabile aggiungere alcuni commenti per aiutare: + +```groovy title="bad_channel_shape_viewed.nf (con commenti)" linenums="16" hl_lines="8 9" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Questo diventerà più importante man mano che i vostri workflow crescono in complessità e la struttura dei canali diventa più opaca. + +#### Eseguire il pipeline + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Takeaway + +Molti errori di struttura dei canali possono essere creati con sintassi Nextflow valida. Potete debuggare gli errori di struttura dei canali comprendendo il flusso dei dati, usando operatori `.view()` per l'ispezione e riconoscendo pattern di errore come parentesi quadre che indicano strutture di tuple inaspettate. + +### Prossimi passi? + +Imparate sugli errori creati dalle definizioni dei processi. + +--- + +## 3. Errori di Struttura dei Processi + +La maggior parte degli errori che incontrerete relativi ai processi sarà legata a errori che avete fatto nella formazione del comando, o a problemi relativi al software sottostante. Detto questo, similmente ai problemi dei canali sopra, potete fare errori nella definizione del processo che non si qualificano come errori di sintassi, ma che causeranno errori al runtime. + +### 3.1. File di Output Mancanti + +Un errore comune quando si scrivono processi è fare qualcosa che genera una mancata corrispondenza tra ciò che il processo si aspetta e ciò che viene generato. + +#### Eseguire il pipeline + +```bash +nextflow run missing_output.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Controllare il codice + +Il messaggio di errore indica che il processo si aspettava di produrre un file di output chiamato `sample3.txt`, ma lo script crea effettivamente `sample3_output.txt`. Esaminiamo la definizione del processo in `missing_output.nf`: + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Expects: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Creates: sample3_output.txt + """ +} +``` + +Dovreste vedere che c'è una mancata corrispondenza tra il nome del file di output nel blocco `output:` e quello usato nello script. Questa mancata corrispondenza causa il fallimento del processo. Se incontrate questo tipo di errore, tornate indietro e verificate che gli output corrispondano tra la definizione del vostro processo e il vostro blocco output. + +Se il problema ancora non è chiaro, controllate la directory di lavoro stessa per identificare i file di output effettivamente creati: + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Per questo esempio questo ci evidenzierebbe che un suffisso `_output` viene incorporato nel nome del file di output, contrariamente alla nostra definizione `output:`. + +#### Correggere il codice + +Correggete la mancata corrispondenza rendendo il nome del file di output coerente: + +=== "Dopo" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Fixed: Match the script output + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Prima" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Expects: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Creates: sample3_output.txt + """ + } + ``` + +#### Eseguire il pipeline + +```bash +nextflow run missing_output.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [elated_hamilton] DSL2 - revision: 961938ee2b + + executor > local (3) + [16/1c437c] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +### 3.2. Software mancante + +Un'altra classe di errori si verifica a causa di errori nel provisioning del software. `missing_software.nf` è un workflow sintatticamente valido, ma dipende da del software esterno per fornire il comando `cowpy` che usa. + +#### Eseguire il pipeline + +```bash +nextflow run missing_software.nf +``` + +??? failure "Output del comando" + + ```console hl_lines="12 18" + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Process `PROCESS_FILES (3)` terminated with an error exit status (127) + + + Command executed: + + cowpy sample3 > sample3_output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/side-quests/debugging/work/82/42a5bfb60c9c6ee63ebdbc2d51aa6e + + Tip: you can try to figure out what's wrong by changing to the process work directory and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Il processo non ha accesso al comando che stiamo specificando. A volte questo è perché uno script è presente nella directory `bin` del workflow, ma non è stato reso eseguibile. Altre volte è perché il software non è installato nel container o nell'ambiente dove il workflow sta eseguendo. + +#### Controllare il codice + +Fate attenzione a quel codice di uscita `127` - vi dice esattamente il problema. Esaminiamo `missing_software.nf`: + +```groovy title="missing_software.nf" linenums="3" hl_lines="3" +process PROCESS_FILES { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + cowpy ${sample_name} > ${sample_name}_output.txt + """ +} +``` + +#### Correggere il codice + +Siamo stati un po' disonesti qui, e in realtà non c'è niente di sbagliato con il codice. Dobbiamo solo specificare la configurazione necessaria per eseguire il processo in modo tale che abbia accesso al comando in questione. In questo caso il processo ha una definizione container, quindi tutto ciò che dobbiamo fare è eseguire il workflow con Docker abilitato. + +#### Eseguire il pipeline + +Abbiamo configurato un profilo Docker per voi in `nextflow.config`, quindi potete eseguire il workflow con: + +```bash +nextflow run missing_software.nf -profile docker +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_software.nf` [awesome_stonebraker] DSL2 - revision: 0296d12839 + + executor > local (3) + [38/ab20d1] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +!!! note + + Per saperne di più su come Nextflow usa i container, vedere [Hello Nextflow](../hello_nextflow/05_hello_containers.md) + +### 3.3. Configurazione delle risorse errata + +Nell'uso in produzione, configurerete le risorse sui vostri processi. Per esempio `memory` definisce la quantità massima di memoria disponibile per il vostro processo, e se il processo supera quella, il vostro scheduler tipicamente ucciderà il processo e restituirà un codice di uscita `137`. Non possiamo dimostrarlo qui perché stiamo usando l'executor `local`, ma possiamo diff --git a/docs/it/docs/side_quests/dev_environment.md b/docs/it/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..4e1ea5ec68 --- /dev/null +++ b/docs/it/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Ambiente di Sviluppo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gli Ambienti di Sviluppo Integrati (IDE) moderni possono trasformare radicalmente la vostra esperienza di sviluppo in Nextflow. Questa quest secondaria si concentra specificamente sull'utilizzo di VS Code e della sua estensione Nextflow per scrivere codice più velocemente, individuare errori tempestivamente e navigare workflow complessi in modo efficiente. + +!!! note "Questo non è un tutorial tradizionale" + + A differenza di altri moduli di formazione, questa guida è organizzata come una raccolta di suggerimenti rapidi, consigli ed esempi pratici piuttosto che come un tutorial passo-passo. Ogni sezione può essere esplorata indipendentemente in base ai vostri interessi e alle attuali esigenze di sviluppo. Sentitevi liberi di spostarvi tra le sezioni e concentrarvi sulle funzionalità che saranno immediatamente più utili per lo sviluppo del vostro workflow. + +## Cosa dovreste sapere prima + +Questa guida presuppone che abbiate completato il corso di formazione [Hello Nextflow](../hello_nextflow/) e che abbiate familiarità con i concetti fondamentali di Nextflow, tra cui: + +- **Struttura base del workflow**: Comprensione dei process, workflow e come si collegano tra loro +- **Operazioni sui channel**: Creazione di channel, passaggio di dati tra process e utilizzo di operatori base +- **Moduli e organizzazione**: Creazione di moduli riutilizzabili e utilizzo delle istruzioni include +- **Nozioni di base sulla configurazione**: Utilizzo di `nextflow.config` per parametri, direttive dei process e profili + +## Cosa imparerete qui + +Questa guida si concentra sulle **funzionalità di produttività dell'IDE** che vi renderanno sviluppatori Nextflow più efficienti: + +- **Evidenziazione avanzata della sintassi**: Comprendere cosa VS Code vi sta mostrando sulla struttura del codice +- **Auto-completamento intelligente**: Sfruttare suggerimenti contestuali per una scrittura del codice più rapida +- **Rilevamento degli errori e diagnostica**: Individuare errori di sintassi prima di eseguire il workflow +- **Navigazione del codice**: Spostarvi rapidamente tra process, moduli e definizioni +- **Formattazione e organizzazione**: Mantenere uno stile di codice coerente e leggibile +- **Sviluppo assistito da AI** (facoltativo): Utilizzare strumenti AI moderni integrati con il vostro IDE + +!!! info "Perché le funzionalità dell'IDE adesso?" + + Probabilmente avete già utilizzato VS Code durante il corso [Hello Nextflow](../hello_nextflow/), ma abbiamo mantenuto il focus sull'apprendimento dei fondamenti di Nextflow piuttosto che sulle funzionalità dell'IDE. Ora che avete familiarità con i concetti base di Nextflow come process, workflow, channel e moduli, siete pronti per sfruttare le sofisticate funzionalità dell'IDE che vi renderanno sviluppatori più efficienti. + + Pensate a questo come a un "potenziamento" del vostro ambiente di sviluppo - lo stesso editor che avete utilizzato ha capacità molto più potenti che diventano veramente preziose una volta compreso ciò con cui vi stanno aiutando. + +--- + +## 0. Configurazione e Preparazione + +Configuriamo uno spazio di lavoro specificamente per esplorare le funzionalità dell'IDE: + +```bash title="Navigare alla directory delle funzionalità IDE" +cd side-quests/ide_features +``` + +Aprite questa directory in VS Code: + +```bash title="Aprire VS Code nella directory corrente" +code . +``` + +La directory `ide_features` contiene workflow di esempio che dimostrano varie funzionalità dell'IDE: + +```bash title="Mostrare la struttura della directory" +tree . +``` + +```console title="Struttura del progetto" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "Informazioni sui File di Esempio" + + - `basic_workflow.nf` è un workflow base funzionante che potete eseguire e modificare + - `complex_workflow.nf` è progettato solo per scopi illustrativi per dimostrare le funzionalità di navigazione - potrebbe non essere eseguito con successo ma mostra una struttura realistica di workflow multi-file + +### Scorciatoie da Tastiera + +Alcune delle funzionalità in questa guida utilizzeranno scorciatoie da tastiera facoltative. Potreste accedere a questo materiale tramite GitHub Codespaces nel browser, e in questo caso a volte le scorciatoie potrebbero non funzionare come previsto perché sono utilizzate per altre funzioni nel vostro sistema. + +Se state eseguendo VS Code localmente, come probabilmente farete quando effettivamente scriverete workflow, le scorciatoie funzioneranno come descritto. + +Se state utilizzando un Mac, alcune (non tutte) scorciatoie da tastiera utilizzeranno "cmd" invece di "ctrl", e lo indicheremo nel testo come `Ctrl/Cmd`. + +### 0.1. Installazione dell'Estensione Nextflow + +!!! note "State già utilizzando Devcontainers?" + + Se state lavorando in **GitHub Codespaces** o utilizzando un **devcontainer locale**, l'estensione Nextflow è probabilmente già installata e configurata. Potete saltare i passaggi di installazione manuale qui sotto e procedere direttamente all'esplorazione delle funzionalità dell'estensione. + +Per installare manualmente l'estensione: + +1. Aprite VS Code +2. Andate alla vista Estensioni cliccando sull'icona delle estensioni a sinistra: ![icona estensioni](img/extensions_icon.png) (scorciatoia `Ctrl/Cmd+Shift+X` se state eseguendo VSCode localmente) +3. Cercate "Nextflow" +4. Installate l'estensione ufficiale Nextflow + +![Installare l'Estensione Nextflow](img/install_extension.png) + +### 0.2. Layout dello Spazio di Lavoro + +Poiché avete utilizzato VS Code durante tutto Hello Nextflow, avete già familiarità con le nozioni di base. Ecco come organizzare il vostro spazio di lavoro in modo efficiente per questa sessione: + +- **Area Editor**: Per visualizzare e modificare file. Potete dividere questa area in più pannelli per confrontare file affiancati. +- **Esplora File** click (![icona esplora file](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): I file e le cartelle locali sul vostro sistema. Tenetelo aperto a sinistra per navigare tra i file +- **Terminale Integrato** (`Ctrl+Shift+` backtick sia per Windows che per MacOS): Un terminale per interagire con il computer in basso. Utilizzatelo per eseguire Nextflow o altri comandi. +- **Pannello Problemi** (`Ctrl+Shift+M`): VS Code mostrerà qui eventuali errori e problemi rilevati. Questo è utile per evidenziare problemi a colpo d'occhio. + +Potete trascinare i pannelli o nasconderli (`Ctrl/Cmd+B` per attivare/disattivare la barra laterale) per personalizzare il vostro layout mentre lavoriamo sugli esempi. + +### Takeaway + +Avete configurato VS Code con l'estensione Nextflow e comprendete il layout dello spazio di lavoro per uno sviluppo efficiente. + +### Prossimo passo + +Imparate come l'evidenziazione della sintassi vi aiuta a comprendere la struttura del codice Nextflow a colpo d'occhio. + +--- + +## 1. Evidenziazione della Sintassi e Struttura del Codice + +Ora che il vostro spazio di lavoro è configurato, esploriamo come l'evidenziazione della sintassi di VS Code vi aiuta a leggere e scrivere codice Nextflow in modo più efficace. + +### 1.1. Elementi di Sintassi Nextflow + +Aprite `basic_workflow.nf` per vedere l'evidenziazione della sintassi in azione: + +![Dimostrazione Sintassi](img/syntax_showcase.png) + +Notate come VS Code evidenzia: + +- **Parole chiave** (`process`, `workflow`, `input`, `output`, `script`) con colori distinti +- **Stringhe letterali** e **parametri** con stili diversi +- **Commenti** con un colore tenue +- **Variabili** e **chiamate a funzione** con enfasi appropriata +- **Blocchi di codice** con guide di indentazione appropriate + +!!! note "Colori Dipendenti dal Tema" + + I colori specifici che vedete dipenderanno dal vostro tema VS Code (modalità scura/chiara), impostazioni dei colori ed eventuali personalizzazioni effettuate. L'aspetto importante è che diversi elementi sintattici siano visivamente distinti l'uno dall'altro, rendendo la struttura del codice più facile da comprendere indipendentemente dalla combinazione di colori scelta. + +### 1.2. Comprensione della Struttura del Codice + +L'evidenziazione della sintassi vi aiuta a identificare rapidamente: + +- **Confini dei process**: Distinzione chiara tra diversi process +- **Blocchi input/output**: Facile individuazione delle definizioni di flusso dati +- **Blocchi script**: I comandi effettivi che vengono eseguiti +- **Operazioni sui channel**: Passaggi di trasformazione dei dati +- **Direttive di configurazione**: Impostazioni specifiche dei process + +Questa organizzazione visiva diventa inestimabile quando si lavora con workflow complessi contenenti molteplici process e flussi di dati intricati. + +### Takeaway + +Comprendete come l'evidenziazione della sintassi di VS Code vi aiuta a leggere la struttura del codice Nextflow e identificare diversi elementi del linguaggio per uno sviluppo più rapido. + +### Prossimo passo + +Imparate come l'auto-completamento intelligente accelera la scrittura del codice con suggerimenti contestuali. + +--- + +## 2. Auto-completamento Intelligente + +Le funzionalità di auto-completamento di VS Code vi aiutano a scrivere codice più velocemente e con meno errori suggerendo opzioni appropriate in base al contesto. + +### 2.1. Suggerimenti Contestuali + +Le opzioni di auto-completamento variano a seconda di dove vi trovate nel vostro codice: + +#### Operazioni sui Channel + +Aprite nuovamente `basic_workflow.nf` e provate a digitare `channel.` nel blocco workflow: + +![Auto-completamento channel](img/autocomplete_channel.png) + +Vedrà suggerimenti per: + +- `fromPath()` - Creare channel da percorsi di file +- `fromFilePairs()` - Creare channel da file accoppiati +- `of()` - Creare channel da valori +- `fromSRA()` - Creare channel da accessi SRA +- E molti altri... + +Questo vi aiuta a trovare rapidamente il factory channel giusto da utilizzare senza dover ricordare i nomi esatti dei metodi. + +Potete anche scoprire gli operatori disponibili da applicare ai channel. Per esempio, digitate `FASTQC.out.html.` per vedere le operazioni disponibili: + +![Auto-completamento operazioni channel](img/autocomplete_operators.png) + +#### Direttive dei Process + +All'interno di un blocco script di un process, digiti `task.` per vedere le proprietà runtime disponibili: + +![Auto-completamento proprietà task](img/autocomplete_task.png) + +#### Configurazione + +Apra nextflow.config e digiti `process.` in qualsiasi punto per vedere le direttive dei process disponibili: + +![Auto-completamento config](img/autocomplete_config.png) + +Vedrà suggerimenti per: + +- `executor` +- `memory` +- `cpus` + +Questo fa risparmiare tempo durante la configurazione dei process e funziona attraverso diversi ambiti di configurazione. Per esempio, provi a digitare `docker.` per vedere le opzioni di configurazione specifiche di Docker. + +### Takeaway + +Può utilizzare l'auto-completamento intelligente di VS Code per scoprire operazioni sui channel, direttive dei process e opzioni di configurazione disponibili senza memorizzare la sintassi. + +### Prossimo passo + +Imparate come il rilevamento degli errori in tempo reale La aiuta a individuare problemi prima di eseguire il vostro workflow, semplicemente leggendo il codice. + +## 3. Rilevamento degli Errori e Diagnostica + +Il rilevamento degli errori in tempo reale di VS Code La aiuta a individuare problemi prima di eseguire il vostro workflow. + +### 3.1. Rilevamento degli Errori di Sintassi + +Creiamo un errore deliberato per vedere il rilevamento in azione. Apra `basic_workflow.nf` e cambi il nome del process da `FASTQC` a `FASTQ` (o qualsiasi altro nome non valido). VS Code evidenzierà immediatamente l'errore nel blocco workflow con una sottolineatura ondulata rossa: + +![Sottolineatura errore](img/error_underline.png) + +### 3.2. Pannello Problemi + +Oltre all'evidenziazione dei singoli errori, VS Code fornisce un Pannello Problemi centralizzato che aggrega tutti gli errori, avvisi e messaggi informativi nel vostro spazio di lavoro. Lo apra con `Ctrl/Cmd+Shift+M` e utilizzi l'icona filtro per mostrare solo gli errori rilevanti per il file corrente: + +![Filtrare il pannello problemi](img/active_file.png) + +Clicchi su qualsiasi problema per saltare direttamente alla riga problematica + +![Pannello Problemi](img/problems_panel.png) + +Corregga l'errore cambiando il nome del process di nuovo in `FASTQC`. + +### 3.3. Pattern di Errori Comuni + +Gli errori comuni nella sintassi Nextflow includono: + +- **Parentesi mancanti**: `{` o `}` non corrispondenti +- **Blocchi incompleti**: Sezioni richieste mancanti nei process +- **Sintassi non valida**: DSL Nextflow malformato +- **Errori di battitura nelle parole chiave**: Direttive dei processes scritte in modo errato +- **Mancata corrispondenza dei channel**: Incompatibilità di tipo + +Il language server Nextflow evidenzia questi problemi nel pannello Problemi. Può controllarli preventivamente per evitare errori di sintassi durante l'esecuzione di una pipeline. + +### Takeaway + +Può utilizzare il rilevamento degli errori e il Pannello Problemi di VS Code per individuare errori di sintassi e problemi prima di eseguire il vostro workflow, risparmiando tempo e prevenendo frustrazioni. + +### Prossimo passo + +Imparate come navigare in modo efficiente tra process, moduli e definizioni in workflow complessi. + +--- + +## 4. Navigazione del Codice e Gestione dei Simboli + +Una navigazione efficiente è cruciale quando si lavora con workflow complessi che si estendono su più file. Per comprendere questo, sostituisca la definizione del process in `basic_workflow.nf` con un import per il modulo che Le abbiamo fornito: + +=== "Dopo" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Prima" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Vai alla Definizione + +Se passa il mouse sopra un nome di process come `FASTQC`, vedrà un popup con l'interfaccia del modulo (input e output): + +![Vai alla definizione](img/syntax.png) + +Questa funzionalità è particolarmente preziosa durante la scrittura di workflow, poiché Le consente di comprendere l'interfaccia del modulo senza aprire direttamente il file del modulo. + +Può navigare rapidamente a qualsiasi definizione di process, modulo o variabile usando **Ctrl/Cmd-click**. Passi il mouse sul link al file del modulo in cima allo script e segua il link come suggerito: + +![Seguire il link](img/follow_link.png) + +La stessa cosa funziona per i nomi dei process. Torni a `basic_workflow.nf` e provi questo sul nome del process `FASTQC` nel blocco workflow. Questo La collega direttamente al nome del process (che è lo stesso del file del modulo in questo esempio, ma potrebbe essere a metà di un file molto più grande). + +Per tornare dove era, usi **Alt+←** (o **Ctrl+-** su Mac). Questo è un modo potente per esplorare il codice senza perdere la vostra posizione. + +Ora esploriamo la navigazione in un workflow più complesso usando `complex_workflow.nf` (il file solo illustrativo menzionato in precedenza). Questo workflow contiene molteplici process definiti in file di moduli separati, oltre ad alcuni inline. Sebbene strutture multi-file complesse possano essere difficili da navigare manualmente, la capacità di saltare alle definizioni rende l'esplorazione molto più gestibile. + +1. Apra `complex_workflow.nf` +2. Navighi alle definizioni dei moduli +3. Usi **Alt+←** (o **Ctrl+-**) per navigare indietro +4. Navighi al nome del process `FASTQC` nel blocco workflow. Questo La collega direttamente al nome del process (che è lo stesso del file del modulo in questo esempio, ma potrebbe essere a metà di un file molto più grande). +5. Navighi nuovamente indietro +6. Navighi al process `TRIM_GALORE` nel blocco workflow. Questo è definito inline, quindi non La porterà a un file separato, ma Le mostrerà comunque la definizione del process, e potrà comunque navigare indietro a dove era. + +### 4.2. Navigazione dei Simboli + +Con `complex_workflow.nf` ancora aperto, può ottenere una panoramica di tutti i simboli nel file digitando `@` nella barra di ricerca in cima a VSCode (la scorciatoia da tastiera è `Ctrl/Cmd+Shift+O`, ma potrebbe non funzionare in Codespaces). Questo apre il pannello di navigazione dei simboli, che elenca tutti i simboli nel file corrente: + +![Navigazione simboli](img/symbols.png) + +Questo mostra: + +- Tutte le definizioni dei process +- Definizioni dei workflows (ci sono due workflows definiti in questo file) +- Definizioni delle funzioni + +Inizi a digitare per filtrare i risultati. + +### 4.3. Trova Tutti i Riferimenti + +Comprendere dove un process o una variabile viene utilizzata in tutto il vostro codebase può essere molto utile. Per esempio, se volete trovare tutti i riferimenti al process `FASTQC`, iniziate navigando alla sua definizione. Potete farlo aprendo direttamente `modules/fastqc.nf`, o utilizzando la funzione di navigazione rapida di VS Code con `Ctrl/Cmd-click` come abbiamo fatto sopra. Una volta alla definizione del process, cliccate con il tasto destro sul nome del process `FASTQC` e selezionate "Find All References" dal menu contestuale per vedere tutte le istanze dove viene utilizzato. + +![Trova riferimenti](img/references.png) + +Questa funzionalità visualizza tutte le istanze dove `FASTQC` è referenziato all'interno del vostro spazio di lavoro, incluso il suo utilizzo nei due workflows distinti. Questa comprensione è cruciale per valutare il potenziale impatto delle modifiche al process `FASTQC`. + +### 4.4. Pannello Outline + +Il pannello Outline, situato nella barra laterale Explorer (cliccate ![Icona Explorer](img/files_icon.png)), fornisce una panoramica conveniente di tutti i simboli nel vostro file corrente. Questa funzionalità vi consente di navigare e gestire rapidamente la struttura del vostro codice visualizzando funzioni, variabili e altri elementi chiave in una vista gerarchica. + +![Pannello outline](img/outline.png) + +Utilizzi il pannello Outline per navigare rapidamente a diverse parti del vostro codice senza usare il browser dei file. + +### 4.5. Visualizzazione DAG + +L'estensione Nextflow di VS Code potete visualizzare il vostro workflow come un Grafo Aciclico Diretto (DAG). Questo vi aiuta a comprendere il flusso dei dati e le dipendenze tra i processes. Aprite `complex_workflow.nf` e cliccate il pulsante "Preview DAG" sopra `workflow {` (il secondo blocco `workflow` in questo file): + +![Anteprima DAG](img/dag_preview.png) + +Questo è solo il workflow 'principale', ma può anche visualizzare in anteprima il DAG per i workflows interni cliccando il pulsante "Preview DAG" sopra il workflow `RNASEQ_PIPELINE {` più in alto: + +![Anteprima DAG workflow interno](img/dag_preview_inner.png) + +Per questo workflow, potete utilizzare i nodi nel DAG per navigare alle corrispondenti definizioni dei processes nel codice. Clicchi su un nodo, e La porterà alla definizione del process rilevante nell'editor. Particolarmente quando un workflow cresce a dimensioni considerevoli, questo può davvero aiutarvi a navigare nel codice e comprendere come i processes sono collegati. + +### Takeaway + +Può navigare workflow complessi in modo efficiente usando vai-alla-definizione, ricerca dei simboli, trova riferimenti e visualizzazione DAG per comprendere la struttura del codice e le dipendenze. + +### Prossimo passo + +Imparate come lavorare efficacemente su più file interconnessi in progetti Nextflow più grandi. + +## 5. Lavorare su Più File + +Lo sviluppo Nextflow reale implica lavorare con molteplici file interconnessi. Esploriamo come VS Code La aiuta a gestire progetti complessi in modo efficiente. + +### 5.1. Navigazione Rapida dei File + +Con `complex_workflow.nf` aperto, noterà che importa diversi moduli. Pratichiamo la navigazione rapida tra di essi. + +Prema **Ctrl+P** (o **Cmd+P**) e inizi a digitare "fast": + +VS Code Le mostrerà i file corrispondenti. Selezioni `modules/fastqc.nf` per saltarci istantaneamente. Questo è molto più veloce che cliccare attraverso l'esplora file quando sa approssimativamente quale file sta cercando. + +Provi questo con altri pattern: + +- Digiti "star" per trovare il file del modulo di allineamento STAR (`star.nf`) +- Digiti "utils" per trovare il file delle funzioni di utilità (`utils.nf`) +- Digiti "config" per saltare ai file di configurazione (`nextflow.config`) + +### 5.2. Editor Diviso per Sviluppo Multi-file + +Quando si lavora con i moduli, spesso è necessario vedere sia il workflow principale che le definizioni dei moduli simultaneamente. Configuriamo questo: + +1. Apra `complex_workflow.nf` +2. Apra `modules/fastqc.nf` in una nuova scheda +3. Clicchi con il tasto destro sulla scheda `modules/fastqc.nf` e selezioni "Split Right" +4. Ora potete vedere entrambi i file affiancati + +![Editor diviso](img/split_editor.png) + +Questo è inestimabile quando: + +- Si controllano le interfacce dei moduli durante la scrittura delle chiamate del workflow, e l'anteprima non è sufficiente +- Si confrontano processes simili tra diversi moduli +- Si effettua il debug del flusso dati tra workflow e moduli + +### 5.3. Ricerca a Livello di Progetto + +A volte è necessario trovare dove pattern specifici sono utilizzati nell'intero progetto. Prema `Ctrl/Cmd+Shift+F` per aprire il pannello di ricerca. + +Provi a cercare `publishDir` nell'intero spazio di lavoro: + +![Ricerca progetto](img/project_search.png) + +Questo Le mostra ogni file che utilizza directory di pubblicazione, aiutandoLa a: + +- Comprendere i pattern di organizzazione dell'output +- Trovare esempi di direttive specifiche +- Garantire coerenza tra i moduli + +### Takeaway + +Può gestire progetti multi-file complessi usando la navigazione rapida dei file, editor divisi e ricerca a livello di progetto per lavorare in modo efficiente su workflows e moduli. + +### Prossimo passo + +Imparate come le funzionalità di formattazione e manutenzione del codice mantengono i vostri workflows organizzati e leggibili. + +--- + +## 6. Formattazione e Manutenzione del Codice + +Una corretta formattazione del codice è essenziale non solo per l'estetica ma anche per migliorare la leggibilità, la comprensione e la facilità di aggiornamento di workflows complessi. + +### 6.1. Formattazione Automatica in Azione + +Apra `basic_workflow.nf` e rovini deliberatamente la formattazione: + +- Rimuova alcune indentazioni: Evidenzi l'intero documento e prema `shift+tab` molte volte per rimuovere quante più indentazioni possibile. +- Aggiunga spazi extra in punti casuali: nell'istruzione `channel.fromPath`, aggiunga 30 spazi dopo `(`. +- Interrompa alcune righe in modo scomodo: Aggiunga una nuova riga tra l'operatore `.view {` e la stringa `Processing sample:` ma non aggiunga una nuova riga corrispondente prima della parentesi di chiusura `}`. + +Ora prema `Shift+Alt+F` (o `Shift+Option+F` su MacOS) per la formattazione automatica: + +VS Code immediatamente: + +- Corregge l'indentazione per mostrare chiaramente la struttura del process +- Allinea elementi simili in modo coerente +- Rimuove spazi bianchi non necessari +- Mantiene interruzioni di riga leggibili + +Noti che la formattazione automatica potrebbe non risolvere ogni problema di stile del codice. Il language server Nextflow mira a mantenere il vostro codice ordinato, ma rispetta anche le vostre preferenze personali in certe aree. Per esempio, se rimuove l'indentazione all'interno del blocco `script` di un process, il formattatore la lascerà così com'è, poiché potrebbe preferire intenzionalmente quello stile. + +Attualmente, non esiste un'applicazione rigorosa dello stile per Nextflow, quindi il language server offre una certa flessibilità. Tuttavia, applicherà in modo coerente le regole di formattazione attorno alle definizioni di metodi e funzioni per mantenere la chiarezza. + +### 6.2. Funzionalità di Organizzazione del Codice + +#### Commento Rapido + +Selezionate un blocco di codice nel vostro workflow e prema **Ctrl+/** (o **Cmd+/**) per commentarlo: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +Questo è perfetto per: + +- Disabilitare temporaneamente parti di workflows durante lo sviluppo +- Aggiungere commenti esplicativi a operazioni sui channel complesse +- Documentare sezioni del workflow + +Usi nuovamente **Ctrl+/** (o **Cmd+/**) per decommentare il codice. + +#### Ripiegamento del Codice per Panoramica + +In `complex_workflow.nf`, notate le piccole frecce accanto alle definizioni dei processes. Cliccatele per ripiegare (comprimere) i processes: + +![Ripiegamento codice](img/code_folding.png) + +Questo Le dà una panoramica di alto livello della struttura del vostro workflow senza perdersi nei dettagli di implementazione. + +#### Corrispondenza delle Parentesi + +Posizioni il cursore accanto a qualsiasi parentesi `{` o `}` e VS Code evidenzia la parentesi corrispondente. Usi **Ctrl+Shift+\\** (o **Cmd+Shift+\\**) per saltare tra parentesi corrispondenti. + +Questo è cruciale per: + +- Comprendere i confini dei processes +- Trovare parentesi mancanti o extra +- Navigare strutture di workflow annidate + +#### Selezione e Modifica Multi-linea + +Per modificare molteplici righe simultaneamente, VS Code offre potenti capacità multi-cursore: + +- **Selezione multi-linea**: Tenga premuto **Ctrl+Alt** (o **Cmd+Option** per MacOS) e usi i tasti freccia per selezionare molteplici righe +- **Indentazione multi-linea**: Selezioni molteplici righe e usi **Tab** per indentare o **Shift+Tab** per rimuovere l'indentazione di interi blocchi + +Questo è particolarmente utile per: + +- Indentare interi blocchi di processes in modo coerente +- Aggiungere commenti a molteplici righe contemporaneamente +- Modificare definizioni di parametri simili attraverso molteplici processes + +### Takeaway + +Può mantenere un codice pulito e leggibile usando formattazione automatica, funzionalità di commento, ripiegamento del codice, corrispondenza delle parentesi e modifica multi-linea per organizzare workflow complessi in modo efficiente. + +### Prossimo passo + +Imparate come VS Code si integra con il vostro workflow di sviluppo più ampio oltre alla semplice modifica del codice. + +--- + +## 7. Integrazione del Workflow di Sviluppo + +VS Code si integra bene con il vostro workflow di sviluppo oltre alla semplice modifica del codice. + +### 7.1. Integrazione del Controllo Versione + +!!! note "Codespaces e Integrazione Git" + + Se sta lavorando in **GitHub Codespaces**, alcune funzionalità di integrazione Git potrebbero non funzionare come previsto, in particolare le scorciatoie da tastiera per Source Control. Potrebbe anche aver rifiutato di aprire la directory come repository Git durante la configurazione iniziale, il che va bene per scopi di formazione. + +Se il vostro progetto è un repository git (come lo è questo), VS Code mostra: + +- File modificati con indicatori colorati +- Stato Git nella barra di stato +- Viste diff inline +- Capacità di commit e push + +Aprite il pannello Source Control usando il pulsante source control (![Icona Source control](img/source_control_icon.png)) (`Ctrl+Shift+G` o `Cmd+Shift+G` se state lavorando con VSCode localmente) per vedere le modifiche git e effettuare commit direttamente nell'editor. + +![Pannello Source Control](img/source_control.png) + +### 7.2. Esecuzione e Ispezione dei Workflows + +Eseguiamo un workflow e quindi ispezioniamo i risultati. Nel terminale integrato (`Ctrl+Shift+` backtick sia in Windows che in MacOS), eseguite il workflow base: + +```bash title="Eseguire il workflow base" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Mentre il workflow è in esecuzione, vedrà l'output in tempo reale nel terminale. Dopo il completamento, potete utilizzare VS Code per ispezionare i risultati senza lasciare il vostro editor: + +1. **Navigare alle directory di lavoro**: Utilizzi l'esplora file o il terminale per navigare `.nextflow/work` +2. **Aprire file di log**: Clicchi sui percorsi dei file di log nell'output del terminale per aprirli direttamente in VS Code +3. **Ispezionare gli output**: Navighi le directory dei risultati pubblicati nell'esplora file +4. **Visualizzare report di esecuzione**: Apra report HTML direttamente in VS Code o nel vostro browser + +Questo mantiene tutto in un unico posto piuttosto che cambiare tra molteplici applicazioni. + +### Takeaway + +Può integrare VS Code con il controllo versione e l'esecuzione del workflow per gestire l'intero processo di sviluppo da un'unica interfaccia. + +### Prossimo passo + +Vedete come tutte queste funzionalità dell'IDE lavorano insieme nel vostro workflow di sviluppo quotidiano. + +--- + +## 8. Riepilogo e Note Rapide + +Ecco alcune note rapide su ciascuna delle funzionalità dell'IDE discusse sopra: + +### 8.1. Iniziare una Nuova Funzionalità + +1. **Apertura rapida file** (`Ctrl+P` o `Cmd+P`) per trovare moduli esistenti rilevanti +2. **Editor diviso** per visualizzare processes simili affiancati +3. **Navigazione simboli** (`Ctrl+Shift+O` o `Cmd+Shift+O`) per comprendere la struttura del file +4. **Auto-completamento** per scrivere nuovo codice rapidamente + +### 8.2. Debug dei Problemi + +1. **Pannello problemi** (`Ctrl+Shift+M` o `Cmd+Shift+M`) per vedere tutti gli errori contemporaneamente +2. **Vai alla definizione** (`Ctrl-click` o `Cmd-click`) per comprendere le interfacce dei processes +3. **Trova tutti i riferimenti** per vedere come i processes vengono utilizzati +4. **Ricerca a livello di progetto** per trovare pattern o problemi simili + +### 8.3. Refactoring e Miglioramento + +1. **Ricerca a livello di progetto** (`Ctrl+Shift+F` o `Cmd+Shift+F`) per trovare pattern +2. **Formattazione automatica** (`Shift+Alt+F` o `Shift+Option+F`) per mantenere la coerenza +3. **Ripiegamento del codice** per concentrarsi sulla struttura +4. **Integrazione Git** per tracciare le modifiche + +--- + +## Riepilogo + +Ha ora avuto un tour rapido delle funzionalità dell'IDE di VS Code per lo sviluppo Nextflow. Questi strumenti La renderanno significativamente più produttivo: + +- **Riducendo gli errori** attraverso il controllo della sintassi in tempo reale +- **Accelerando lo sviluppo** con auto-completamento intelligente +- **Migliorando la navigazione** in workflows multi-file complessi +- **Mantenendo la qualità** attraverso formattazione coerente +- **Migliorando la comprensione** attraverso evidenziazione avanzata e visualizzazione della struttura + +Non ci aspettiamo che ricordi tutto, ma ora sa che queste funzionalità esistono e sarà in grado di trovarle quando ne avrà bisogno. Man mano che continua a sviluppare workflows Nextflow, queste funzionalità dell'IDE diventeranno una seconda natura, permettendoLe di concentrarsi sulla scrittura di codice di alta qualità piuttosto che lottare con sintassi e struttura. + +### Prossimo passo + +Applichi queste competenze dell'IDE mentre lavora attraverso altri moduli di formazione, per esempio: + +- **[nf-test](nf-test.md)**: Creare suite di test complete per i vostri workflows +- **[Hello nf-core](../../hello_nf-core/)**: Costruire pipeline di qualità per la produzione con standard della comunità + +Il vero potere di queste funzionalità dell'IDE emerge mentre lavora su progetti più grandi e complessi. Inizi a incorporarle gradualmente nel vostro workflow - nel giro di poche sessioni, diventeranno una seconda natura e trasformeranno il vostro approccio allo sviluppo Nextflow. + +Dall'individuare errori prima che La rallentino alla navigazione di codebase complessi con facilità, questi strumenti La renderanno uno sviluppatore più sicuro ed efficiente. + +Buona programmazione! diff --git a/docs/it/docs/side_quests/essential_scripting_patterns.md b/docs/it/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..6ccfc89698 --- /dev/null +++ b/docs/it/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1180 @@ +# Pattern di Scripting Essenziali in Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow è un linguaggio di programmazione che viene eseguito sulla Java Virtual Machine. Sebbene Nextflow sia costruito su [Groovy](http://groovy-lang.org/) e ne condivida gran parte della sintassi, Nextflow è più di un semplice "Groovy con estensioni" -- è un linguaggio autonomo con una [sintassi](https://nextflow.io/docs/latest/reference/syntax.html) completamente specificata e una [libreria standard](https://nextflow.io/docs/latest/reference/stdlib.html). + +È possibile scrivere molto codice Nextflow senza andare oltre la sintassi di base per variabili, mappe e liste. La maggior parte dei tutorial su Nextflow si concentra sull'orchestrazione dei workflow (canali, processi e flusso di dati), e si può andare sorprendentemente lontano con solo questo. + +Tuttavia, quando è necessario manipolare dati, analizzare nomi di file complessi, implementare logica condizionale o costruire workflow di produzione robusti, è utile pensare a due aspetti distinti del codice: **dataflow** (canali, operatori, processi e workflow) e **scripting** (il codice all'interno di closure, funzioni e script di processo). Sebbene questa distinzione sia in qualche modo arbitraria—è tutto codice Nextflow—fornisce un modello mentale utile per comprendere quando si sta orchestrando la pipeline rispetto a quando si stanno manipolando i dati. Padroneggiare entrambi migliora notevolmente la capacità di scrivere workflow chiari e manutenibili. + +### Obiettivi di apprendimento + +Questa missione secondaria ti accompagna in un percorso pratico dai concetti di base ai pattern pronti per la produzione. +Trasformeremo un semplice workflow di lettura CSV in una sofisticata pipeline bioinformatica, evolvendola passo dopo passo attraverso sfide realistiche: + +- **Comprendere i confini:** Distinguere tra operazioni di dataflow e scripting, e capire come lavorano insieme +- **Manipolazione dei dati:** Estrarre, trasformare e creare sottoinsiemi di mappe e collezioni utilizzando operatori potenti +- **Elaborazione delle stringhe:** Analizzare schemi di denominazione dei file complessi con pattern regex e padroneggiare l'interpolazione delle variabili +- **Funzioni riutilizzabili:** Estrarre logica complessa in funzioni nominate per workflow più puliti e manutenibili +- **Logica dinamica:** Costruire processi che si adattano a diversi tipi di input e utilizzare closure per l'allocazione dinamica delle risorse +- **Routing condizionale:** Instradare intelligentemente i campioni attraverso diversi processi in base alle loro caratteristiche di metadati +- **Operazioni sicure:** Gestire in modo elegante i dati mancanti con operatori null-safe e validare gli input con messaggi di errore chiari +- **Handler basati sulla configurazione:** Utilizzare handler di eventi del workflow per logging, notifiche e gestione del ciclo di vita + +### Prerequisiti + +Prima di intraprendere questa missione secondaria, dovreste: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso equivalente per principianti. +- Essere a proprio agio nell'uso di concetti e meccanismi di base di Nextflow (processi, canali, operatori, lavoro con file, metadati) +- Avere familiarità di base con costrutti di programmazione comuni (variabili, mappe, liste) + +Questo tutorial spiegherà i concetti di programmazione man mano che li incontriamo, quindi non è necessaria un'esperienza di programmazione approfondita. +Inizieremo con concetti fondamentali e costruiremo fino a pattern avanzati. + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non lo ha ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione Ambiente](../envsetup/index.md). + +[![Apri in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Rivedere i materiali + +Troverà un file workflow principale e una directory `data` contenente file di dati di esempio. + +```console title="Contenuto della directory" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Il nostro CSV di esempio contiene informazioni sui campioni biologici che necessitano di elaborazioni diverse in base alle loro caratteristiche: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Utilizzeremo questo dataset realistico per esplorare tecniche di programmazione pratiche che incontrerà in workflow bioinformatici reali. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### Checklist di preparazione + +Pensa di essere pronto per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato +<!-- - [ ] I understand the assignment --> + +Se può spuntare tutte le caselle, è pronto per partire. + +--- + +## 1. Dataflow vs Scripting: Comprendere i Confini + +### 1.1. Identificare Cosa è Cosa + +Quando si scrivono workflow Nextflow, è importante distinguere tra **dataflow** (come i dati si muovono attraverso canali e processi) e **scripting** (il codice che manipola i dati e prende decisioni). Costruiamo un workflow che dimostri come lavorano insieme. + +#### 1.1.1. Workflow Nextflow di Base + +Iniziamo con un semplice workflow che legge solo il file CSV (lo abbiamo già fatto per voi in `main.nf`): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +Il blocco `workflow` definisce la struttura della nostra pipeline, mentre `channel.fromPath()` crea un canale da un percorso di file. L'operatore `.splitCsv()` elabora il file CSV e converte ogni riga in una struttura dati di tipo mappa. + +Esegua questo workflow per vedere i dati CSV grezzi: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Aggiungere l'Operatore Map + +Ora aggiungeremo scripting per trasformare i dati, utilizzando l'operatore `.map()` che probabilmente conosce già. Questo operatore prende una 'closure' dove possiamo scrivere codice per trasformare ogni elemento. + +!!! note + + Una **closure** è un blocco di codice che può essere passato in giro ed eseguito successivamente. Pensate ad essa come a una funzione definita inline. Le closure sono scritte con parentesi graffe `{ }` e possono prendere parametri. Sono fondamentali per come funzionano gli operatori Nextflow e se avete scritto Nextflow per un po', potrebbe averle già utilizzate senza rendersene conto! + +Ecco come appare quell'operazione map: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +Questa è la nostra prima **closure** - una funzione anonima che si può passare come argomento (simile alle lambda in Python o alle arrow function in JavaScript). Le closure sono essenziali per lavorare con gli operatori Nextflow. + +La closure `{ row -> return row }` prende un parametro `row` (potrebbe essere qualsiasi nome: `item`, `sample`, ecc.). + +Quando l'operatore `.map()` elabora ogni elemento del canale, passa quell'elemento alla closure. Qui, `row` contiene una riga CSV alla volta. + +Applicate questa modifica ed eseguite il workflow: + +```bash +nextflow run main.nf +``` + +Vedrà lo stesso output di prima, perché stiamo semplicemente restituendo l'input invariato. Questo conferma che l'operatore map funziona correttamente. Ora iniziamo a trasformare i dati. + +#### 1.1.3. Creare una Struttura Dati Map + +Ora scriveremo logica di **scripting** all'interno della nostra closure per trasformare ogni riga di dati. Questo è dove elaboriamo i singoli elementi di dati piuttosto che orchestrare il flusso di dati. + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting per la trasformazione dei dati + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +La mappa `sample_meta` è una struttura dati chiave-valore (come i dizionari in Python, gli oggetti in JavaScript o gli hash in Ruby) che memorizza informazioni correlate: ID campione, organismo, tipo di tessuto, profondità di sequenziamento e punteggio di qualità. + +Utilizziamo metodi di manipolazione delle stringhe come `.toLowerCase()` e `.replaceAll()` per pulire i nostri dati, e metodi di conversione di tipo come `.toInteger()` e `.toDouble()` per convertire i dati stringa dal CSV nei tipi numerici appropriati. + +Applicate questa modifica ed eseguite il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Aggiungere Logica Condizionale + +Ora aggiungiamo più scripting - questa volta utilizzando un operatore ternario per prendere decisioni in base ai valori dei dati. + +Effettui la seguente modifica: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +L'operatore ternario è una scorciatoia per un'istruzione if/else che segue il pattern `condizione ? valore_se_vero : valore_se_falso`. Questa riga significa: "Se la qualità è maggiore di 40, usa 'high', altrimenti usa 'normal'". Il suo cugino, l'**operatore Elvis** (`?:`), fornisce valori predefiniti quando qualcosa è null o vuoto - esploreremo quel pattern più avanti in questo tutorial. + +L'operatore di addizione di mappe `+` crea una **nuova mappa** piuttosto che modificare quella esistente. Questa riga crea una nuova mappa che contiene tutte le coppie chiave-valore da `sample_meta` più la nuova chiave `priority`. + +!!! Note + + Non modifichi mai le mappe passate nelle closure - crei sempre nuove mappe utilizzando `+` (per esempio). In Nextflow, gli stessi dati spesso fluiscono attraverso più operazioni simultaneamente. Modificare una mappa sul posto può causare effetti collaterali imprevedibili quando altre operazioni fanno riferimento a quello stesso oggetto. Creare nuove mappe assicura che ogni operazione abbia la propria copia pulita. + +Esegua il workflow modificato: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Abbiamo aggiunto con successo logica condizionale per arricchire i nostri metadati con un livello di priorità basato sui punteggi di qualità. + +#### 1.1.5. Creare Sottoinsiemi di Mappe con `.subMap()` + +Mentre l'operatore `+` aggiunge chiavi a una mappa, a volte è necessario fare il contrario - estrarre solo chiavi specifiche. Il metodo `.subMap()` è perfetto per questo. + +Aggiungiamo una riga per creare una versione semplificata dei nostri metadati che contiene solo i campi di identificazione: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting per la trasformazione dei dati + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Solo campi ID: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting per la trasformazione dei dati + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Esegua il workflow modificato: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Solo campi ID: [id:sample_001, organism:human, tissue:liver] + Solo campi ID: [id:sample_002, organism:mouse, tissue:brain] + Solo campi ID: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Questo mostra sia i metadati completi visualizzati dall'operazione `view()` che il sottoinsieme estratto che abbiamo stampato con `println`. + +Il metodo `.subMap()` prende una lista di chiavi e restituisce una nuova mappa contenente solo quelle chiavi. Se una chiave non esiste nella mappa originale, semplicemente non viene inclusa nel risultato. + +Questo è particolarmente utile quando è necessario creare diverse versioni di metadati per diversi processi - alcuni potrebbero aver bisogno di metadati completi mentre altri necessitano solo di campi di identificazione minimali. + +Ora rimuova quelle istruzioni println per ripristinare il workflow allo stato precedente, poiché non ne abbiamo bisogno andando avanti. + +!!! tip "Riepilogo Operazioni su Mappe" + + - **Aggiungere chiavi**: `map1 + [new_key: value]` - Crea nuova mappa con chiavi aggiuntive + - **Estrarre chiavi**: `map1.subMap(['key1', 'key2'])` - Crea nuova mappa con solo le chiavi specificate + - **Entrambe le operazioni creano nuove mappe** - Le mappe originali rimangono invariate + +#### 1.1.6. Combinare Mappe e Restituire Risultati + +Finora, abbiamo restituito solo quella che la comunità Nextflow chiama 'meta map', e abbiamo ignorato i file a cui quei metadati si riferiscono. Ma se state scrivendo workflow Nextflow, probabilmente vuole fare qualcosa con quei file. + +Produciamo una struttura di canale comprendente una tupla di 2 elementi: la mappa di metadati arricchita e il percorso di file corrispondente. Questo è un pattern comune in Nextflow per passare dati ai processi. + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Applicate questa modifica ed eseguite il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Questa struttura di tupla `[meta, file]` è un pattern comune in Nextflow per passare sia metadati che file associati ai processi. + +!!! note + + **Mappe e Metadati**: Le mappe sono fondamentali per lavorare con i metadati in Nextflow. Per una spiegazione più dettagliata del lavoro con mappe di metadati, veda la missione secondaria [Lavorare con i metadati](./metadata.md). + +Il nostro workflow dimostra il pattern centrale: **operazioni di dataflow** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orchestrano come i dati si muovono attraverso la pipeline, mentre **scripting** (mappe `[key: value]`, metodi di stringhe, conversioni di tipo, operatori ternari) all'interno della closure `.map()` gestisce la trasformazione dei singoli elementi di dati. + +### 1.2. Comprendere Diversi Tipi: Channel vs List + +Finora, tutto bene, possiamo distinguere tra operazioni di dataflow e scripting. Ma che dire quando lo stesso nome di metodo esiste in entrambi i contesti? + +Un esempio perfetto è il metodo `collect`, che esiste sia per i tipi di canale che per i tipi List nella libreria standard Nextflow. Il metodo `collect()` su una List trasforma ogni elemento, mentre l'operatore `collect()` su un canale raccoglie tutte le emissioni del canale in un canale a singolo elemento. + +Dimostriamo questo con alcuni dati di esempio, iniziando col rinfrescarci su cosa fa l'operatore `collect()` del canale. Dia un'occhiata a `collect.nf`: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - raggruppa più emissioni di canale in una +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Elemento individuale del canale: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "Risultato channel.collect(): ${list} (${list.size()} elementi raggruppati in 1)" } +``` + +Passaggi: + +- Definire una List di ID campione +- Creare un canale con `fromList()` che emette ogni ID campione separatamente +- Stampare ogni elemento con `view()` mentre fluisce attraverso +- Raccogliere tutti gli elementi in una singola lista con l'operatore `collect()` del canale +- Stampare il risultato raccolto (singolo elemento contenente tutti gli ID campione) con un secondo `view()` + +Abbiamo cambiato la struttura del canale, ma non abbiamo cambiato i dati stessi. + +Esegua il workflow per confermarlo: + +```bash +nextflow run collect.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Elemento individuale del canale: sample_001 + Elemento individuale del canale: sample_002 + Elemento individuale del canale: sample_003 + Risultato channel.collect(): [sample_001, sample_002, sample_003] (3 elementi raggruppati in 1) + ``` + +`view()` restituisce un output per ogni emissione del canale, quindi sappiamo che questo singolo output contiene tutti e 3 gli elementi originali raggruppati in una lista. + +Ora vediamo il metodo `collect` su una List in azione. Modifichi `collect.nf` per applicare il metodo `collect` della List alla lista originale di ID campione: + +=== "Dopo" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - raggruppa più emissioni di canale in una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento individuale del canale: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Risultato channel.collect(): ${list} (${list.size()} elementi raggruppati in 1)" } + + // List.collect() - trasforma ogni elemento, preserva la struttura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Risultato List.collect(): ${formatted_ids} (${sample_ids.size()} elementi trasformati in ${formatted_ids.size()})" + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - raggruppa più emissioni di canale in una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento individuale del canale: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Risultato channel.collect(): ${list} (${list.size()} elementi raggruppati in 1)" } + ``` + +In questo nuovo snippet: + +- Definiamo una nuova variabile `formatted_ids` che utilizza il metodo `collect` della List per trasformare ogni ID campione nella lista originale +- Stampiamo il risultato usando `println` + +Esegua il workflow modificato: + +```bash +nextflow run collect.nf +``` + +??? success "Output del comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + Risultato List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementi trasformati in 3) + Elemento individuale del canale: sample_001 + Elemento individuale del canale: sample_002 + Elemento individuale del canale: sample_003 + Risultato channel.collect(): [sample_001, sample_002, sample_003] (3 elementi raggruppati in 1) + ``` + +Questa volta, NON abbiamo cambiato la struttura dei dati, abbiamo ancora 3 elementi nella lista, ma ABBIAMO trasformato ogni elemento usando il metodo `collect` della List per produrre una nuova lista con valori modificati. Questo è simile all'uso dell'operatore `map` su un canale, ma sta operando su una struttura dati List piuttosto che su un canale. + +`collect` è un caso estremo che stiamo usando qui per fare un punto. La lezione chiave è che quando si scrivono workflow, si deve sempre distinguere tra **strutture dati** (List, Map, ecc.) e **canali** (costrutti di dataflow). Le operazioni possono condividere nomi ma comportarsi in modo completamente diverso a seconda del tipo su cui vengono chiamate. + +### 1.3. L'Operatore Spread (`*.`) - Scorciatoia per l'Estrazione di Proprietà + +Correlato al metodo `collect` della List è l'operatore spread (`*.`), che fornisce un modo conciso per estrarre proprietà dalle collezioni. È essenzialmente zucchero sintattico per un pattern `collect` comune. + +Aggiungiamo una dimostrazione al nostro file `collect.nf`: + +=== "Dopo" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - raggruppa più emissioni di canale in una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento individuale del canale: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Risultato channel.collect(): ${list} (${list.size()} elementi raggruppati in 1)" } + + // List.collect() - trasforma ogni elemento, preserva la struttura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Risultato List.collect(): ${formatted_ids} (${sample_ids.size()} elementi trasformati in ${formatted_ids.size()})" + + // Operatore spread - accesso conciso alle proprietà + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Risultato operatore spread: ${all_ids}" + ``` + +=== "Prima" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - raggruppa più emissioni di canale in una + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Elemento individuale del canale: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Risultato channel.collect(): ${list} (${list.size()} elementi raggruppati in 1)" } + + // List.collect() - trasforma ogni elemento, preserva la struttura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Risultato List.collect(): ${formatted_ids} (${sample_ids.size()} elementi trasformati in ${formatted_ids.size()})" + ``` + +Esegua il workflow aggiornato: + +```bash title="Testare operatore spread" +nextflow run collect.nf +``` + +??? success "Output del comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + Risultato List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementi trasformati in 3) + Risultato operatore spread: [s1, s2, s3] + Elemento individuale del canale: sample_001 + Elemento individuale del canale: sample_002 + Elemento individuale del canale: sample_003 + Risultato channel.collect(): [sample_001, sample_002, sample_003] (3 elementi raggruppati in 1) + ``` + +L'operatore spread `*.` è una scorciatoia per un pattern collect comune: + +```groovy +// Questi sono equivalenti: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Funziona anche con chiamate a metodi: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +L'operatore spread è particolarmente utile quando è necessario estrarre una singola proprietà da una lista di oggetti - è più leggibile che scrivere la closure `collect` completa. + +!!! tip "Quando Usare Spread vs Collect" + + - **Usare spread (`*.`)** per accesso semplice alle proprietà: `samples*.id`, `files*.name` + - **Usare collect** per trasformazioni o logica complessa: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Takeaway + +In questa sezione, ha imparato: + +- **Dataflow vs scripting**: Gli operatori di canale orchestrano come i dati fluiscono attraverso la pipeline, mentre lo scripting trasforma i singoli elementi di dati +- **Comprendere i tipi**: Lo stesso nome di metodo (come `collect`) può comportarsi in modo diverso a seconda del tipo su cui viene chiamato (Channel vs List) +- **Il contesto conta**: Sia sempre consapevole se state lavorando con canali (dataflow) o strutture dati (scripting) + +Comprendere questi confini è essenziale per il debug, la documentazione e la scrittura di workflow manutenibili. + +Successivamente approfondiremo le capacità di elaborazione delle stringhe, che sono essenziali per gestire dati del mondo reale. + +--- + +## 2. Elaborazione di Stringhe e Generazione Dinamica di Script + +Padroneggiare l'elaborazione delle stringhe separa i workflow fragili dalle pipeline robuste. Questa sezione copre l'analisi di nomi di file complessi, la generazione dinamica di script e l'interpolazione di variabili. + +### 2.1. Pattern Matching ed Espressioni Regolari + +I file bioinformatici hanno spesso convenzioni di denominazione complesse che codificano metadati. Estraiamoli automaticamente usando il pattern matching con espressioni regolari. + +Torneremo al nostro workflow `main.nf` e aggiungeremo un po' di logica di pattern matching per estrarre informazioni aggiuntive sui campioni dai nomi dei file. I file FASTQ nel nostro dataset seguono convenzioni di denominazione in stile Illumina con nomi come `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Questi potrebbero sembrare criptici, ma in realtà codificano metadati utili come ID campione, numero di lane e direzione di lettura. Useremo le capacità regex per analizzare questi nomi. + +Effettui la seguente modifica al workflow `main.nf` esistente: + +=== "Dopo" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Scripting per la trasformazione dei dati + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Scripting per la trasformazione dei dati + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Questo dimostra **concetti chiave di elaborazione delle stringhe**: + +1. **Letterali di espressioni regolari** usando la sintassi `~/pattern/` - questo crea un pattern regex senza bisogno di escape dei backslash +2. **Pattern matching** con l'operatore `=~` - questo tenta di abbinare una stringa a un pattern regex +3. **Oggetti matcher** che catturano gruppi con `[0][1]`, `[0][2]`, ecc. - `[0]` si riferisce all'intera corrispondenza, `[1]`, `[2]`, ecc. si riferiscono ai gruppi catturati tra parentesi + +Analizziamo il pattern regex `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$`: + +| Pattern | Corrisponde | Cattura | +| ------------------- | -------------------------------------- | ----------------------------------- | +| `^(.+)` | Nome campione dall'inizio | Gruppo 1: nome campione | +| `_S(\d+)` | Numero campione `_S1`, `_S2`, ecc. | Gruppo 2: numero campione | +| `_L(\d{3})` | Numero lane `_L001` | Gruppo 3: lane (3 cifre) | +| `_(R[12])` | Direzione lettura `_R1` o `_R2` | Gruppo 4: direzione lettura | +| `_(\d{3})` | Numero chunk `_001` | Gruppo 5: chunk (3 cifre) | +| `\.fastq(?:\.gz)?$` | Estensione file `.fastq` o `.fastq.gz` | Non catturato (?: è non-catturante) | + +Questo analizza le convenzioni di denominazione in stile Illumina per estrarre automaticamente i metadati. + +Esegua il workflow modificato: + +```bash title="Testare pattern matching" +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Questo mostra i metadati arricchiti dai nomi dei file. + +### 2.2. Generazione Dinamica di Script nei Processi + +I blocchi script dei processi sono essenzialmente stringhe multi-linea che vengono passate alla shell. Si potete usare **logica condizionale** (if/else, operatori ternari) per generare dinamicamente diverse stringhe di script in base alle caratteristiche dell'input. Questo è essenziale per gestire diversi tipi di input—come letture single-end vs paired-end—senza duplicare le definizioni dei processi. + +Aggiungiamo un processo al nostro workflow che dimostri questo pattern. Apra `modules/fastp.nf` e dia un'occhiata: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Il processo prende file FASTQ come input ed esegue lo strumento `fastp` per tagliare adapter e filtrare letture di bassa qualità. Sfortunatamente, la persona che ha scritto questo processo non ha previsto le letture single-end che abbiamo nel nostro dataset di esempio. Aggiungiamolo al nostro workflow e vediamo cosa succede: + +Per prima cosa, includa il modulo alla prima riga del workflow `main.nf`: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Quindi modifichi il blocco `workflow` per collegare il canale `ch_samples` al processo `FASTP`: + +=== "Dopo" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Esegua questo workflow modificato: + +```bash +nextflow run main.nf +``` + +??? failure "Output del comando" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Si potete vedere che il processo sta cercando di eseguire `fastp` con un valore `null` per il secondo file di input, il che lo fa fallire. Questo perché il nostro dataset contiene letture single-end, ma il processo è codificato per aspettarsi letture paired-end (due file di input alla volta). + +Corregga questo aggiungendo logica condizionale al blocco `script:` del processo `FASTP`. Un'istruzione if/else controlla il conteggio dei file di lettura e regola il comando di conseguenza. + +=== "Dopo" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Semplice rilevamento single-end vs paired-end + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Ora il workflow può gestire con eleganza sia letture single-end che paired-end. La logica condizionale controlla il numero di file di input e costruisce il comando appropriato per `fastp`. Vediamo se funziona: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +Sembra buono! Se controlliamo i comandi effettivi che sono stati eseguiti (personalizzi per il suo hash di attività): + +```console title="Controllare comandi eseguiti" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Possiamo vedere che Nextflow ha correttamente scelto il comando giusto per le letture single-end: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Un altro uso comune della logica dinamica degli script può essere visto in [il modulo Genomics di Nextflow for Science](../../nf4science/genomics/02_joint_calling). In quel modulo, il processo GATK chiamato può prendere più file di input, ma ciascuno deve essere prefissato con `-V` per formare una riga di comando corretta. Il processo usa scripting per trasformare una collezione di file di input (`all_gvcfs`) negli argomenti di comando corretti: + +```groovy title="manipolazione riga di comando per GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Questi pattern di utilizzo dello scripting nei blocchi script dei processi sono estremamente potenti e possono essere applicati in molti scenari - dalla gestione di tipi di input variabili alla costruzione di argomenti di riga di comando complessi da collezioni di file, rendendo i processi veramente adattabili ai requisiti diversificati dei dati del mondo reale. + +### 2.3. Interpolazione di Variabili: Variabili Nextflow e Shell + +Gli script dei processi mescolano variabili Nextflow, variabili shell e sostituzioni di comandi, ciascuna con sintassi di interpolazione diversa. Usare la sintassi sbagliata causa errori. Esploriamo questi con un processo che crea un report di elaborazione. + +Dia un'occhiata al file modulo `modules/generate_report.nf`: + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Elaborazione ${reads}" > ${meta.id}_report.txt + echo "Campione: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Questo processo scrive un semplice report con l'ID campione e il nome del file. Ora eseguiamolo per vedere cosa succede quando dobbiamo mescolare diversi tipi di variabili. + +Includa il processo nel suo `main.nf` e lo aggiunga al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +Ora eseguite il workflow e controllate i report generati in `results/reports/`. Dovrebbero contenere informazioni di base su ogni campione. + +<!-- TODO: add the run command --> + +??? success "Output del comando" + + ```console + <!-- TODO: output --> + ``` + +Ma cosa succederebbe se volessimo aggiungere informazioni su quando e dove è avvenuta l'elaborazione? Modifichiamo il processo per utilizzare variabili **shell** e un po' di sostituzione di comandi per includere l'utente corrente, l'hostname e la data nel report: + +=== "Dopo" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Elaborazione ${reads}" > ${meta.id}_report.txt + echo "Campione: ${meta.id}" >> ${meta.id}_report.txt + echo "Elaborato da: ${USER}" >> ${meta.id}_report.txt + echo "Hostname: $(hostname)" >> ${meta.id}_report.txt + echo "Data: $(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Prima" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Elaborazione ${reads}" > ${meta.id}_report.txt + echo "Campione: ${meta.id}" >> ${meta.id}_report.txt + """ + ``` + +Se esegue questo, noterà un errore - Nextflow cerca di interpretare `${USER}` come una variabile Nextflow che non esiste. + +??? failure "Output del comando" + + ```console + Error modules/generate_report.nf:15:27: `USER` is not defined + │ 15 | echo "Elaborato da: ${USER}" >> ${meta.id}_report.txt + ╰ | ^^^^ + + ERROR ~ Script compilation failed + ``` + +Dobbiamo fare l'escape così che Bash possa gestirlo invece. + +Corregga questo facendo l'escape delle variabili shell e delle sostituzioni di comandi con un backslash (`\`): + +=== "Dopo" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Elaborazione ${reads}" > ${meta.id}_report.txt + echo "Campione: ${meta.id}" >> ${meta.id}_report.txt + echo "Elaborato da: \${USER}" >> ${meta.id}_report.txt + echo "Hostname: \$(hostname)" >> ${meta.id}_report.txt + echo "Data: \$(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Prima" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Elaborazione ${reads}" > ${meta.id}_report.txt + echo "Campione: ${meta.id}" >> ${meta.id}_report.txt + echo "Elaborato da: ${USER}" >> ${meta.id}_report.txt + echo "Hostname: $(hostname)" >> ${meta.id}_report.txt + echo "Data: $(date)" >> ${meta.id}_report.txt + """ + ``` + +Ora funziona! Il backslash (`\`) dice a Nextflow "non interpretare questo, passalo a Bash." + +### Takeaway + +In questa sezione, ha imparato tecniche di **elaborazione delle stringhe**: + +- **Espressioni regolari per l'analisi dei file**: Utilizzare l'operatore `=~` e pattern regex (`~/pattern/`) per estrarre metadati da convenzioni di denominazione dei file complesse +- **Generazione dinamica di script**: Utilizz diff --git a/docs/it/docs/side_quests/ideas/containers.md b/docs/it/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..53e7aa6185 --- /dev/null +++ b/docs/it/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Parte 1: Maggiori Informazioni sui Container + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Come trovare o creare immagini di container + +Alcuni sviluppatori di software forniscono immagini di container per i loro software disponibili su registri di container come Docker Hub, ma molti non lo fanno. +In questa sezione opzionale, le mostreremo due modi per ottenere un'immagine di container per gli strumenti che desidera utilizzare nelle sue pipeline Nextflow: utilizzando Seqera Containers e costruendo l'immagine del container da sé. + +Otterrà/costruirà un'immagine di container per il pacchetto pip `quote`, che sarà utilizzato nell'esercizio alla fine di questa sezione. + +### 1.1. Ottenere un'immagine di container da Seqera Containers + +Seqera Containers è un servizio gratuito che costruisce immagini di container per strumenti installabili tramite pip e conda (incluso bioconda). +Navighi su [Seqera Containers](https://www.seqera.io/containers/) e cerchi il pacchetto pip `quote`. + +![Seqera Containers](img/seqera-containers-1.png) + +Clicchi su "+Add" e poi su "Get Container" per richiedere un'immagine di container per il pacchetto pip `quote`. + +![Seqera Containers](img/seqera-containers-2.png) + +Se è la prima volta che viene costruito un container di comunità per questa versione del pacchetto, potrebbero essere necessari alcuni minuti per completare l'operazione. +Clicchi per copiare l'URI (ad es. `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) dell'immagine di container che è stata creata per voi. + +Ora potete utilizzare l'immagine di container per eseguire il comando `quote` e ottenere un detto casuale di Grace Hopper. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Output: + +```console title="Output" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Costruire l'immagine del container da sé + +Utilizziamo alcuni dettagli di costruzione dal sito web di Seqera Containers per costruire noi stessi l'immagine di container per il pacchetto pip `quote`. +Ritornate al sito web di Seqera Containers e cliccate sul pulsante "Build Details". + +Il primo elemento che esamineremo è il `Dockerfile`, un tipo di file di script che contiene tutti i comandi necessari per costruire l'immagine di container. +Abbiamo aggiunto alcuni commenti esplicativi al Dockerfile qui sotto per aiutarla a comprendere cosa fa ciascuna parte. + +```Dockerfile title="Dockerfile" +# Inizia dall'immagine docker di base micromamba +FROM mambaorg/micromamba:1.5.10-noble +# Copia il file conda.yml nel container +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Installa varie utilità per Nextflow da utilizzare e i pacchetti nel file conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Esegui il container come utente root +USER root +# Imposta la variabile d'ambiente PATH per includere la directory di installazione di micromamba +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +Il secondo elemento che esamineremo è il file `conda.yml`, che contiene l'elenco dei pacchetti che devono essere installati nell'immagine di container. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Copiate il contenuto di questi file negli stub situati nella directory `containers/build`, quindi eseguite il seguente comando per costruire l'immagine di container da sé. + +!!! Note "Nota" + + Utilizziamo il flag `-t quote:latest` per etichettare l'immagine di container con il nome `quote` e il tag `latest`. + Saremo in grado di utilizzare questo tag per riferirci all'immagine di container quando la eseguiremo su questo sistema. + +```bash +docker build -t quote:latest containers/build +``` + +Dopo che la costruzione è terminata, potete eseguire l'immagine di container che avete appena costruito. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Riepilogo + +Ha imparato due modi diversi per ottenere un'immagine di container per uno strumento che desidera utilizzare nelle sue pipeline Nextflow: utilizzando Seqera Containers e costruendo l'immagine di container da sé. + +### Qual è il prossimo passo? + +Ha tutto ciò di cui ha bisogno per continuare al [prossimo capitolo](./04_hello_genomics.md) di questa serie di formazione. +Può anche continuare con un esercizio opzionale per recuperare citazioni di pionieri dell'informatica/biologia utilizzando il container `quote` e visualizzarle utilizzando il container `cowsay`. + +--- + +## 2. Fare in modo che la mucca citi scienziati famosi + +Questa sezione contiene alcuni esercizi avanzati, per praticare ciò che ha imparato finora. +Completare questi esercizi _non è richiesto_ per comprendere le parti successive della formazione, ma fornisce un modo divertente per rafforzare le sue conoscenze capendo come fare in modo che la mucca citi scienziati famosi. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Modificare lo script `hello-containers.nf` per utilizzare un processo getQuote + +Abbiamo un elenco di pionieri dell'informatica e della biologia nel file `containers/data/pioneers.csv`. +Ad alto livello, per completare questo esercizio dovrà: + +- Modificare il `params.input_file` predefinito per puntare al file `pioneers.csv`. +- Creare un processo `getQuote` che utilizza il container `quote` per recuperare una citazione per ogni input. +- Connettere l'output del processo `getQuote` al processo `cowsay` per visualizzare la citazione. + +Per l'immagine di container `quote`, potete utilizzare quella che avete costruito da sé nell'esercizio avanzato precedente o utilizzare quella ottenuta da Seqera Containers. + +!!! Hint "Suggerimento" + + Una buona scelta per il blocco `script` del suo processo getQuote potrebbe essere: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Può trovare una soluzione a questo esercizio in `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Modificare la sua pipeline Nextflow per permetterle di eseguire nelle modalità `quote` e `sayHello`. + +Aggiunga della logica di ramificazione alla sua pipeline per permetterle di accettare input destinati sia a `quote` che a `sayHello`. +Ecco un esempio di come utilizzare un'istruzione `if` in un workflow Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint "Suggerimento" + + Può utilizzare `new_ch = processName.out` per assegnare un nome al canale di output di un processo. + +Può trovare una soluzione a questo esercizio in `containers/solutions/hello-containers-4.2.nf`. + +### Riepilogo + +Sa come utilizzare i container in Nextflow per eseguire processi e come costruire della logica di ramificazione nelle sue pipeline! + +### Qual è il prossimo passo? + +Festeggi, faccia una pausa e beva dell'acqua! + +Quando sarà pronto, passi alla Parte 3 di questa serie di formazione per imparare come applicare ciò che ha imparato finora a un caso d'uso di analisi dati più realistico. diff --git a/docs/it/docs/side_quests/ideas/if_else.md b/docs/it/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..78c89da983 --- /dev/null +++ b/docs/it/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Parte 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Far citare dal cow scienziati famosi + +Questa sezione contiene alcuni esercizi avanzati, per mettere in pratica quanto appreso finora. +Svolgere questi esercizi _non è obbligatorio_ per comprendere le parti successive della formazione, ma forniscono un modo divertente per consolidare le conoscenze imparando a far citare dal cow scienziati famosi. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Modificare lo script `hello-containers.nf` per utilizzare un processo getQuote + +Abbiamo un elenco di pionieri dell'informatica e della biologia nel file `containers/data/pioneers.csv`. +Ad alto livello, per completare questo esercizio sarà necessario: + +- Modificare il `params.input_file` predefinito per puntare al file `pioneers.csv`. +- Creare un processo `getQuote` che utilizzi il container `quote` per recuperare una citazione per ogni input. +- Collegare l'output del processo `getQuote` al processo `cowsay` per visualizzare la citazione. + +Per l'immagine del container `quote`, è possibile utilizzare quella costruita personalmente nell'esercizio avanzato precedente oppure quella ottenuta da Seqera Containers. + +!!! Hint + + Una buona scelta per il blocco `script` del processo getQuote potrebbe essere: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +È possibile trovare una soluzione a questo esercizio in `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Modificare il pipeline Nextflow per consentirne l'esecuzione nelle modalità `quote` e `sayHello`. + +Aggiungere della logica di ramificazione al pipeline per consentirgli di accettare input destinati sia a `quote` che a `sayHello`. +Ecco un esempio di come utilizzare un'istruzione `if` in un workflow Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + È possibile utilizzare `new_ch = processName.out` per assegnare un nome al canale di output di un processo. + +È possibile trovare una soluzione a questo esercizio in `containers/solutions/hello-containers-4.2.nf`. + +### Conclusioni + +Ora sa come utilizzare i container in Nextflow per eseguire processi e come costruire della logica di ramificazione nei suoi pipeline! + +### Prossimi passi + +Celebri, prendetevi una pausa per fare stretching e beva dell'acqua! + +Quando è pronto, passi alla Parte 3 di questa serie di formazione per imparare ad applicare quanto appreso finora a un caso d'uso di analisi dati più realistico. diff --git a/docs/it/docs/side_quests/index.md b/docs/it/docs/side_quests/index.md new file mode 100644 index 0000000000..35df9939a8 --- /dev/null +++ b/docs/it/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: Missioni Secondarie +hide: + - toc +--- + +# Missioni Secondarie + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questa è una raccolta di mini-corsi di formazione indipendenti che approfondiscono argomenti specifici. Può seguirli in qualsiasi ordine. + +Iniziamo! Clicchi sul pulsante "Open in GitHub Codespaces" qui sotto per avviare l'ambiente di formazione (preferibilmente in una scheda separata), quindi continui a leggere mentre si carica. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Prerequisiti + +I prerequisiti specifici di ciascun mini-corso variano e sono documentati nelle pagine corrispondenti. +Tuttavia, tutti presuppongono una familiarità minima con i seguenti aspetti: + +- Esperienza con la linea di comando +- Concetti e strumenti fondamentali di Nextflow trattati nel corso di formazione per principianti [Hello Nextflow](../../hello_nextflow/). + +Per i requisiti tecnici e la configurazione dell'ambiente, consulti il mini-corso [Configurazione dell'Ambiente](../../envsetup/). + +**Se questa è la prima volta che si avventura nelle Missioni Secondarie, assicuratevi di consultare prima la pagina [Orientamento](./orientation.md)!** + +Altrimenti, selezioni una missione secondaria dalla tabella qui sotto. + +## Missioni Secondarie + +| Missione Secondaria | Tempo Stimato per l'Insegnamento | +| --------------------------------------------------------------------------------- | -------------------------------- | +| [Panoramica dell'ambiente di sviluppo Nextflow](./ide_features.md) | 45 minuti | +| [Pattern di Scripting Essenziali per Nextflow](./essential_scripting_patterns.md) | 90 minuti | +| [Metadati nei workflow](./metadata.md) | 45 minuti | +| [Suddivisione e Raggruppamento](./splitting_and_grouping.md) | 45 minuti | +| [Test con nf-test](./nf-test.md) | 1 ora | +| [Workflow di workflow](./workflows_of_workflows.md) | 30 minuti | +| [Lavorare con i file](./working_with_files.md) | 45 minuti | +| [Debug dei workflow](./debugging.md) | 1 ora | + +Ci faccia sapere quali altri domini e casi d'uso vorrebbe vedere trattati qui pubblicando nella [sezione Training](https://community.seqera.io/c/training/) del forum della community. diff --git a/docs/it/docs/side_quests/metadata.md b/docs/it/docs/side_quests/metadata.md new file mode 100644 index 0000000000..e954aa2196 --- /dev/null +++ b/docs/it/docs/side_quests/metadata.md @@ -0,0 +1,1275 @@ +# Metadati e meta map + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +In qualsiasi analisi scientifica, raramente lavoriamo solo con i file di dati grezzi. +Ogni file è accompagnato da informazioni aggiuntive: cosa rappresenta, da dove proviene e cosa lo rende speciale. +Queste informazioni extra sono ciò che chiamiamo metadati. + +I metadati sono dati che descrivono altri dati. +I metadati tengono traccia di dettagli importanti sui file e sulle condizioni sperimentali, e aiutano ad adattare le analisi alle caratteristiche uniche di ciascun dataset. + +Pensate ad esso come al catalogo di una biblioteca: mentre i libri contengono il contenuto effettivo (dati grezzi), le schede del catalogo forniscono informazioni essenziali su ciascun libro—quando è stato pubblicato, chi lo ha scritto, dove trovarlo (metadati). +Nelle pipeline Nextflow, i metadati possono essere utilizzati per: + +- Tracciare informazioni specifiche sui file durante tutto il workflow +- Configurare i processi in base alle caratteristiche dei file +- Raggruppare file correlati per analisi congiunte + +### Obiettivi di apprendimento + +In questa side quest, esploreremo come gestire i metadati nei workflow. +Partendo da un semplice datasheet (spesso chiamato samplesheet in bioinformatica) contenente informazioni di base sui file, imparerete come: + +- Leggere e analizzare i metadati dei file da file CSV +- Creare e manipolare meta map +- Aggiungere nuovi campi di metadati durante l'esecuzione del workflow +- Utilizzare i metadati per personalizzare il comportamento dei processi + +Queste competenze vi aiuteranno a costruire pipeline più robuste e flessibili in grado di gestire relazioni tra file complesse e requisiti di elaborazione. + +### Prerequisiti + +Prima di intraprendere questa side quest, dovrebbe: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso equivalente per principianti. +- Essere a vostro agio nell'utilizzo di concetti e meccanismi di base di Nextflow (processi, canali, operatori) + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non lo ha ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione dell'Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/metadata +``` + +Può configurare VSCode per concentrarsi su questa directory: + +```bash +code . +``` + +#### Esaminare i materiali + +Troverà un file di workflow principale e una directory `data` contenente un datasheet e una manciata di file di dati. + +??? abstract "Contenuti della directory" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +Il workflow nel file `main.nf` è una bozza che espanderà gradualmente in un workflow completamente funzionante. + +Il datasheet elenca i percorsi ai file di dati e alcuni metadati associati, organizzati in 3 colonne: + +- `id`: autoesplicativo, un ID assegnato al file +- `character`: un nome di personaggio, che useremo più avanti per disegnare creature diverse +- `data`: percorsi a file `.txt` che contengono saluti in lingue diverse + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Ogni file di dati contiene del testo di saluto in una di cinque lingue (fr: francese, de: tedesco, es: spagnolo, it: italiano, en: inglese). + +Le forniremo anche uno strumento di analisi linguistica containerizzato chiamato `langid`. + +#### Esaminare l'assegnazione + +La vostra sfida è scrivere un workflow Nextflow che: + +1. **Identifichi** automaticamente la lingua in ciascun file +2. **Raggruppi** i file per famiglia linguistica (lingue germaniche vs lingue romanze) +3. **Personalizzi** l'elaborazione per ciascun file in base alla sua lingua e ai suoi metadati +4. **Organizzi** gli output per gruppo linguistico + +Questo rappresenta un pattern di workflow tipico in cui i metadati specifici dei file guidano le decisioni di elaborazione; esattamente il tipo di problema che le meta map risolvono in modo elegante. + +#### Lista di controllo della preparazione + +Pensa di essere pronto per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato +- [ ] Comprendo l'assegnazione + +Se può spuntare tutte le caselle, è pronto per iniziare. + +--- + +## 1. Caricare metadati da un datasheet + +Aprite il file di workflow `main.nf` per esaminare la bozza di workflow che Le forniamo come punto di partenza. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Può vedere che abbiamo configurato un channel factory di base per caricare il datasheet di esempio come file, ma questo non leggerà ancora il contenuto del file. +Iniziamo aggiungendo questo. + +### 1.1. Leggere il contenuto con `splitCsv` + +Dobbiamo scegliere un operatore che analizzerà il contenuto del file in modo appropriato con il minimo sforzo da parte nostra. +Poiché il nostro datasheet è in formato CSV, questo è un lavoro per l'operatore [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv), che carica ogni riga nel file come elemento nel canale. + +Apporti le seguenti modifiche per aggiungere un'operazione `splitCsv()` al codice di costruzione del canale, più un'operazione `view()` per verificare che il contenuto del file venga caricato correttamente nel canale. + +=== "Dopo" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Noti che stiamo usando l'opzione `header: true` per dire a Nextflow di leggere la prima riga del file CSV come riga di intestazione. + +Vediamo cosa ne esce, va bene? +Esegua il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Possiamo vedere che l'operatore ha costruito una mappa di coppie chiave-valore per ogni riga nel file CSV, con le intestazioni delle colonne come chiavi per i valori corrispondenti. + +Ogni voce della mappa corrisponde a una colonna nel nostro datasheet: + +- `id` +- `character` +- `recording` + +Questo è ottimo! Rende facile accedere a campi specifici da ciascun file. +Ad esempio, potremmo accedere all'ID del file con `id` o al percorso del file txt con `recording`. + +??? info "(Opzionale) Maggiori informazioni sulle map" + + In Groovy, il linguaggio di programmazione su cui è costruito Nextflow, una map è una struttura dati chiave-valore simile ai dizionari in Python, agli oggetti in JavaScript o agli hash in Ruby. + + Ecco uno script eseguibile che mostra come è possibile definire una map e accedere ai suoi contenuti nella pratica: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Crea una map semplice + def my_map = [id:'sampleA', character:'squirrel'] + + // Stampa l'intera map + println "map: ${my_map}" + + // Accede ai singoli valori usando la notazione con punto + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Anche se non ha un blocco `workflow` appropriato, Nextflow può eseguirlo come se fosse un workflow: + + ```bash + nextflow run examples/map_demo.nf + ``` + + Ed ecco cosa può aspettarsi di vedere nell'output: + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Selezionare campi specifici con `map` + +Diciamo che vogliamo accedere alla colonna `character` dal datasheet e stamparla. +Possiamo usare l'operatore Nextflow `map` per iterare su ogni elemento nel nostro canale e selezionare specificamente la voce `character` dall'oggetto map. + +Apporti le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Ora eseguite nuovamente il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Successo! Abbiamo sfruttato la struttura della map derivata dal nostro datasheet per accedere ai valori delle singole colonne per ogni riga. + +Ora che abbiamo letto con successo il datasheet e abbiamo accesso ai dati in ogni riga, possiamo iniziare a implementare la logica della nostra pipeline. + +### 1.3. Organizzare i metadati in una 'meta map' + +Nello stato attuale del workflow, i file di input (sotto la chiave `recording`) e i metadati associati (`id`, `character`) sono tutti sullo stesso piano, come se fossero tutti in un grande contenitore. +La conseguenza pratica è che ogni processo che consuma questo canale dovrebbe essere configurato con questa struttura in mente: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +Va bene finché il numero di colonne nel datasheet non cambia. +Tuttavia, se aggiunge anche solo una colonna al datasheet, la forma del canale non corrisponderà più a ciò che il processo si aspetta, e il workflow produrrà errori. +Rende anche difficile condividere il processo con altri che potrebbero avere dati di input leggermente diversi, e potrebbe finire per dover codificare variabili nel processo che non sono necessarie per il blocco script. + +Per evitare questo problema, dobbiamo trovare un modo per mantenere la struttura del canale coerente indipendentemente da quante colonne contiene quel datasheet. + +Possiamo farlo raccogliendo tutti i metadati in un elemento all'interno della tupla, che chiameremo meta map, o più semplicemente 'meta map'. + +Apporti le seguenti modifiche all'operazione `map`: + +=== "Dopo" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Abbiamo ristrutturato gli elementi del nostro canale in una tupla composta da due elementi, la meta map e l'oggetto file corrispondente. + +Eseguiamo il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console title="Visualizza meta map" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Ora, ogni elemento nel canale contiene prima la meta map e poi l'oggetto file corrispondente: + +```console title="Esempio di struttura di output" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +Di conseguenza, l'aggiunta di più colonne nel datasheet renderà disponibili più metadati nella map `meta`, ma non cambierà la forma del canale. +Questo ci consente di scrivere processi che consumano il canale senza dover codificare gli elementi dei metadati nella specifica di input: + +```groovy title="Esempio di sintassi" + input: + tuple val(meta), file(recording) +``` + +Questa è una convenzione ampiamente utilizzata per organizzare i metadati nei workflow Nextflow. + +### Concetti chiave + +In questa sezione, ha imparato: + +- **Perché i metadati sono importanti:** Mantenere i metadati con i vostri dati preserva informazioni importanti sui file durante tutto il workflow. +- **Come leggere i datasheet:** Utilizzare `splitCsv` per leggere file CSV con informazioni di intestazione e trasformare le righe in dati strutturati +- **Come creare una meta map:** Separare i metadati dai dati dei file utilizzando la struttura di tupla `[ [id:value, ...], file ]` + +--- + +## 2. Manipolare i metadati + +Ora che abbiamo caricato i nostri metadati, facciamo qualcosa con essi! + +Useremo uno strumento chiamato [`langid`](https://github.com/saffsd/langid.py) per identificare la lingua contenuta nel file di registrazione di ogni creatura. +Lo strumento è pre-addestrato su un insieme di lingue e, dato un frammento di testo, produrrà una previsione linguistica e un punteggio di probabilità associato, entrambi su `stdout`. + +### 2.1. Importare il processo ed esaminare il codice + +Le forniamo un modulo di processo pre-scritto chiamato `IDENTIFY_LANGUAGE` che avvolge lo strumento `langid`, quindi deve solo aggiungere un'istruzione include prima del blocco workflow. + +Apporti la seguente modifica al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Può aprire il file del modulo per esaminarne il codice: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Usa langid per prevedere la lingua di ciascun file di input +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Come potete vedere, la definizione di input utilizza la stessa struttura `tuple val(meta), path(file)` che abbiamo appena applicato al nostro canale di input. + +La definizione di output è strutturata come una tupla con una struttura simile a quella dell'input, tranne per il fatto che contiene anche `stdout` come terzo elemento. +Questo pattern `tuple val(meta), path(file), <output>` mantiene i metadati associati sia ai dati di input che agli output mentre scorrono attraverso la pipeline. + +Noti che stiamo usando il qualificatore di output [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) di Nextflow qui perché lo strumento stampa il suo output direttamente sulla console piuttosto che scrivere un file; e usiamo `sed` nella riga di comando per rimuovere il punteggio di probabilità, pulire la stringa rimuovendo i caratteri di nuova riga e restituire solo la previsione linguistica. + +### 2.2. Aggiungere una chiamata a `IDENTIFY_LANGUAGE` + +Ora che il processo è disponibile per il workflow, possiamo aggiungere una chiamata al processo `IDENTIFY_LANGUAGE` per eseguirlo sul canale dati. + +Apporti le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Noti che abbiamo rimosso l'operazione `.view()` originale nella costruzione del canale. + +Possiamo ora eseguire il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Eccellente! Ora abbiamo una previsione per quale lingua parla ogni personaggio. + +E come notato in precedenza, abbiamo anche incluso il file di input e la meta map nell'output, il che significa che entrambi rimangono associati alle nuove informazioni che abbiamo appena prodotto. +Questo si rivelerà utile nel prossimo passaggio. + +!!! note + + Più in generale, questo pattern di mantenere la meta map associata ai risultati rende più facile associare risultati correlati che condividono gli stessi identificatori. + + Come avrà già imparato, non potete fare affidamento sull'ordine degli elementi nei canali per abbinare i risultati tra di essi. + Invece, deve usare chiavi per associare correttamente i dati, e le meta map forniscono una struttura ideale per questo scopo. + + Esploriamo questo caso d'uso in dettaglio nella side quest [Splitting & Grouping](./splitting_and_grouping.md). + +### 2.3. Aumentare i metadati con gli output dei processi + +Dato che i risultati che abbiamo appena prodotto sono di per sé una forma di metadati sui contenuti dei file, sarebbe utile aggiungerli alla nostra meta map. + +Tuttavia, non vogliamo modificare la meta map esistente sul posto. +Da un punto di vista tecnico, è _possibile_ farlo, ma non è sicuro. + +Quindi invece, creeremo una nuova meta map contenente il contenuto della meta map esistente più una nuova coppia chiave-valore `lang: lang_id` che contiene le nuove informazioni, utilizzando l'operatore `+` (una caratteristica di Groovy). +E combineremo questo con un'operazione [`map`](https://www.nextflow.io/docs/latest/operator.html#map) per sostituire la vecchia map con quella nuova. + +Ecco le modifiche che deve apportare al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Se non ha ancora familiarità con l'operatore `+`, o se questo sembra confuso, si prenda qualche minuto per esaminare la spiegazione dettagliata qui sotto. + +??? info "Creazione della nuova meta map usando l'operatore `+`" + + **Prima di tutto, deve sapere che possiamo unire i contenuti di due map usando l'operatore Groovy `+`.** + + Diciamo che abbiamo le seguenti map: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Possiamo unirle in questo modo: + + ```groovy + new_map = map1 + map2 + ``` + + Il contenuto di `new_map` sarà: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Ottimo! + + **Ma cosa succede se deve aggiungere un campo che non fa già parte di una map?** + + Diciamo che riparte da `map1`, ma la previsione linguistica non è nella sua map (non c'è `map2`). + Invece, è contenuta in una variabile chiamata `lang_id`, e sa che vuole memorizzare il suo valore (`'fr'`) con la chiave `lang`. + + Può effettivamente fare quanto segue: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Qui, `[lang: new_info]` crea una nuova map senza nome al volo, e `map1 + ` unisce `map1` con la nuova map senza nome, producendo gli stessi contenuti di `new_map` come prima. + + Elegante, vero? + + **Ora trasponiamo questo nel contesto di un'operazione `channel.map()` di Nextflow.** + + Il codice diventa: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Questo fa quanto segue: + + - `map1, lang_id ->` prende i due elementi nella tupla + - `[map1 + [lang: lang_id]]` crea la nuova map come dettagliato sopra + + L'output è una singola map senza nome con gli stessi contenuti di `new_map` nel nostro esempio sopra. + Quindi abbiamo effettivamente trasformato: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + in: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Si spera che possa vedere che se cambiamo `map1` in `meta`, è fondamentalmente tutto ciò di cui abbiamo bisogno per aggiungere la previsione linguistica alla nostra meta map nel nostro workflow. + + Tranne una cosa! + + Nel caso del nostro workflow, **dobbiamo anche tenere conto della presenza dell'oggetto `file` nella tupla**, che è composta da `meta, file, lang_id`. + + Quindi il codice qui diventerebbe: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Se avete difficoltà a capire perché il `file` sembra muoversi nell'operazione `map`, immagini che invece di `[meta + [lang: lang_id], file]`, quella riga legga `[new_map, file]`. + Questo dovrebbe rendere più chiaro che stiamo semplicemente lasciando il `file` nella sua posizione originale in seconda posizione nella tupla. Abbiamo appena preso il valore `new_info` e lo abbiamo incorporato nella map che è in prima posizione. + + **E questo ci riporta alla struttura del canale `tuple val(meta), path(file)`!** + +Una volta che siete sicuri di aver capito cosa fa questo codice, eseguite il workflow per vedere se ha funzionato: + +```bash +nextflow run main.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Sì, è corretto! +Abbiamo riorganizzato ordinatamente l'output del processo da `meta, file, lang_id` in modo che `lang_id` sia ora una delle chiavi nella meta map, e le tuple del canale si adattino nuovamente al modello `meta, file`. + +<!-- TODO (future) Should we also show how to remove a key using subMap?! Or note where to find that. --> + +### 2.4. Assegnare un gruppo linguistico usando i condizionali + +Ora che abbiamo le nostre previsioni linguistiche, usiamo le informazioni per assegnare alcuni nuovi raggruppamenti. + +Nei nostri dati di esempio, le lingue utilizzate dai nostri personaggi possono essere raggruppate in lingue germaniche (inglese, tedesco) e lingue romanze (francese, spagnolo, italiano). +Potrebbe essere utile avere quella classificazione facilmente disponibile da qualche parte più avanti nella pipeline, quindi aggiungiamo quelle informazioni nella meta map. + +E, buone notizie, questo è ancora un altro caso che si presta perfettamente all'uso dell'operatore `map`! + +Nello specifico, definiremo una variabile chiamata `lang_group`, useremo una logica condizionale semplice per determinare quale valore assegnare a `lang_group` per ciascun pezzo di dati. + +La sintassi generale sarà così: + +```groovy +.map { meta, file -> + + // la logica condizionale che definisce lang_group va qui + + [meta + [lang_group: lang_group], file] +} +``` + +Può vedere che questo è molto simile all'operazione di fusione di map al volo che abbiamo usato nel passaggio precedente. +Dobbiamo solo scrivere le istruzioni condizionali. + +Ecco la logica condizionale che vogliamo applicare: + +- Definire una variabile chiamata `lang_group` con valore predefinito `'unknown'`. +- Se `lang` è tedesco (`'de'`) o inglese (`'en'`), cambiare `lang_group` in `germanic`. +- Altrimenti se `lang` è incluso in un elenco contenente francese (`'fr'`), spagnolo (`'es'`) e italiano (`'it'`), cambiare `lang_group` in `romance`. + +Provi a scriverlo voi stessi se sa già come scrivere istruzioni condizionali in Nextflow. + +!!! tip + + Può accedere al valore di `lang` all'interno dell'operazione map con `meta.lang`. + +Dovrebbe finire per apportare le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Ecco i punti chiave: + +- Usiamo `def lang_group = "unknown"` per creare la variabile `lang_group` con valore predefinito impostato su `unknown`. +- Usiamo una struttura `if {} else if {}` per la logica condizionale, con test `.equals()` alternativi per le due lingue germaniche, e un test di esistenza in un elenco per le tre lingue romanze. +- Usiamo l'operazione di fusione `meta + [lang_group:lang_group]` come precedentemente per generare la meta map aggiornata. + +<!-- TODO (future) Add note/links to relevant docs in additional resources section --> + +Una volta che tutto ha senso, eseguite nuovamente il workflow per vedere il risultato: + +```bash +nextflow run main.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Come potete vedere, gli elementi del canale mantengono la loro struttura `[meta, file]`, ma la meta map ora include questa nuova classificazione. + +### Concetti chiave + +In questa sezione, ha imparato come: + +- **Applicare i metadati di input ai canali di output**: Copiare i metadati in questo modo ci consente di associare i risultati successivamente in base al contenuto dei metadati. +- **Creare chiavi personalizzate**: Ha creato due nuove chiavi nella vostra meta map, fondendole con `meta + [new_key:value]` nella meta map esistente. Una basata su un valore calcolato da un processo e una basata su una condizione impostata nell'operatore `map`. + +Questi vi consentono di associare metadati nuovi ed esistenti con i file man mano che procede attraverso la vostra pipeline. +Anche se non sta utilizzando i metadati come parte di un processo, mantenere la meta map associata ai dati in questo modo rende facile tenere insieme tutte le informazioni rilevanti. + +--- + +## 3. Utilizzare le informazioni della meta map in un processo + +Ora che sa come creare e aggiornare la meta map, possiamo arrivare alla parte davvero divertente: usare effettivamente i metadati in un processo. + +Più specificamente, aggiungeremo un secondo passaggio al nostro workflow per disegnare ogni animale come arte ASCII e fargli dire il testo registrato in un fumetto. +Lo faremo utilizzando uno strumento chiamato [`cowpy`](https://github.com/jeffbuttars/cowpy). + +??? info "Cosa fa `cowpy`?" + + `cowpy` è uno strumento da riga di comando che genera arte ASCII per visualizzare input di testo arbitrari in modo divertente. + È un'implementazione python del classico strumento [cowsay](https://en.wikipedia.org/wiki/Cowsay) di Tony Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Opzionalmente, può selezionare un personaggio (o 'cowacter') da utilizzare al posto della mucca predefinita. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Se ha seguito il corso Hello Nextflow, ha già visto questo strumento in azione. +In caso contrario, non si preoccupi; tratteremo tutto ciò che deve sapere mentre procediamo. + +### 3.1. Importare il processo ed esaminare il codice + +Le forniamo un modulo di processo pre-scritto chiamato `COWPY` che avvolge lo strumento `cowpy`, quindi deve solo aggiungere un'istruzione include prima del blocco workflow. + +Apporti la seguente modifica al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Può aprire il file del modulo per esaminarne il codice: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Genera arte ASCII con cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Come potete vedere, questo processo è attualmente progettato per prendere un file di input (contenente il testo da visualizzare) e un valore che specifica il personaggio che dovrebbe essere disegnato in arte ASCII, solitamente fornito a livello di workflow da un parametro da riga di comando. + +### 3.2. Passare un campo della meta map come input + +Quando abbiamo usato lo strumento `cowpy` nel corso Hello Nextflow, abbiamo usato un parametro da riga di comando per determinare quale personaggio utilizzare per disegnare l'immagine finale. +Aveva senso, perché stavamo generando solo un'immagine per esecuzione della pipeline. + +Tuttavia, in questo tutorial, vogliamo generare un'immagine appropriata per ogni soggetto che stiamo elaborando, quindi l'uso di un parametro da riga di comando sarebbe troppo limitante. + +Buone notizie: abbiamo una colonna `character` nel nostro datasheet e quindi, nella nostra meta map. +Usiamo quella per impostare il personaggio che il processo dovrebbe usare per ogni voce. + +A tal fine, dovremo fare tre cose: + +1. Dare un nome al canale di output proveniente dal processo precedente in modo da potervi operare più comodamente. +2. Determinare come accedere alle informazioni di interesse +3. Aggiungere una chiamata al secondo processo e fornire le informazioni in modo appropriato. + +Iniziamo. + +#### 3.2.1. Nominare il canale di output precedente + +Abbiamo applicato le manipolazioni precedenti direttamente sul canale di output del primo processo, `IDENTIFY_LANGUAGE.out`. +Per alimentare il contenuto di quel canale al processo successivo (e farlo in modo chiaro e facile da leggere) vogliamo dargli un nome proprio, `ch_languages`. + +Possiamo farlo usando l'operatore [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set). + +Nel workflow principale, sostituisca l'operatore `.view()` con `.set { ch_languages }`, e aggiunga una riga per testare che possiamo riferirci al canale per nome. + +=== "Dopo" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Temporaneo: sbirciare dentro ch_languages + ch_languages.view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Esegue langid per identificare la lingua di ogni saluto + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Eseguiamo questo: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Questo conferma che ora possiamo riferirci al canale per nome. + +#### 3.2.2. Accedere al file e ai metadati del personaggio + +Sappiamo dall'esame del codice del modulo che il processo `COWPY` si aspetta di ricevere un file di testo e un valore `character`. +Per scrivere la chiamata al processo `COWPY`, dobbiamo solo sapere come estrarre il corrispondente oggetto file e i metadati da ciascun elemento nel canale. + +Come spesso accade, il modo più semplice per farlo è usare un'operazione `map`. + +Il nostro canale contiene tuple strutturate come `[meta, file]`, quindi possiamo accedere direttamente all'oggetto `file`, e possiamo accedere al valore `character` memorizzato all'interno della meta map riferendoci ad esso come `meta.character`. + +Nel workflow principale, apporti le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="main.nf" linenums="34" + // Temporaneo: accedere al file e al personaggio + ch_languages.map { meta, file -> file }.view { file -> "File: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Character: " + character } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="34" + // Temporaneo: sbirciare dentro ch_languages + ch_languages.view() + ``` + +Noti che stiamo usando closure (come `{ file -> "File: " + file }`) per rendere l'output delle operazioni `.view` più leggibile. + +Eseguiamo questo: + +```bash +nextflow run main.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Character: squirrel + File: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + File: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Character: tux + Character: turkey + File: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + File: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Character: sheep + Character: moose + Character: stegosaurus + File: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + File: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + File: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Character: turtle + ``` + +_I percorsi dei file e i valori dei personaggi potrebbero uscire in un ordine diverso nel vostro output._ + +Questo conferma che siamo in grado di accedere al file e al personaggio per ogni elemento nel canale. + +#### 3.2.3. Chiamare il processo `COWPY` + +Ora mettiamo tutto insieme e chiamiamo effettivamente il processo `COWPY` sul canale `ch_languages`. + +Nel workflow principale, apporti le seguenti modifiche al codice: + +=== "Dopo" + + ```groovy title="main.nf" linenums="34" + // Esegue cowpy per generare arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="34" + // Temporaneo: accedere al file e al personaggio + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Vede che copiamo semplicemente le due operazioni map (meno le istruzioni `.view()`) come input alla chiamata del processo. +Assicuratevi solo di non dimenticare la virgola tra di loro! + +È un po' goffo, ma vedremo come migliorarlo nella prossima sezione. + +Eseguiamo questo: + +```bash +nextflow run main.nf -resume +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Se guarda nella directory results, dovrebbe vedere i singoli file contenenti l'arte ASCII di ogni saluto pronunciato dal personaggio corrispondente. + +??? abstract "Contenuti della directory e file di esempio" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola.txt + └── cowpy-salut.txt + ``` + + ```text title="results/cowpy-bonjour.txt" + _________________ + / Bonjour \ + \ Salut, à demain / + ----------------- + \ + \ + _ _ + | \__/| .~ ~. + /oo `./ .' + {o__, \ { + / . . ) \ + `-` '-' \ } + .( _( )_.' + '---.~_ _ _| + ``` + +Questo mostra che siamo stati in grado di utilizzare le informazioni nella meta map per parametrizzare il comando nel secondo passaggio della pipeline. + +Tuttavia, come notato sopra, parte del codice coinvolto era un po' goffo, poiché abbiamo dovuto decomprimere i metadati mentre eravamo ancora nel contesto del corpo del workflow. +Questo approccio funziona bene per l'utilizzo di un piccolo numero di campi dalla meta map, ma scalrebbe male se volessimo usarne molti di più. + +C'è un altro operatore chiamato `multiMap()` che ci consente di semplificare questo un po', ma anche allora non è ideale. + +??? info "(Opzionale) Versione alternativa con `multiMap()`" + + Nel caso si stia chiedendo, non potevamo semplicemente scrivere una singola operazione `map()` che restituisse sia il `file` che il `character`, perché ciò li restituirebbe come tupla. + Abbiamo dovuto scrivere due operazioni `map()` separate per alimentare gli elementi `file` e `character` al processo separatamente. + + Tecnicamente c'è un altro modo per farlo attraverso una singola operazione di mapping, usando l'operatore `multiMap()`, che è in grado di emettere più canali. + Ad esempio, potrebbe sostituire la chiamata a `COWPY` sopra con il seguente codice: + + === "Dopo" + + ```groovy title="main.nf" linenums="34" + // Esegue cowpy per generare arte ASCII + COWPY( + ch_languages.multiMap { meta, file -> + file: file + character: meta.character + } + ) + ``` + + === "Prima" + + ```groovy title="main.nf" linenums="34" + // Esegue cowpy per generare arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + + Questo produce esattamente lo stesso risultato. + +In entrambi i casi, è scomodo dover fare della decompressione a livello di workflow. + +Sarebbe meglio se potessimo alimentare l'intera meta map nel processo e scegliere ciò di cui abbiamo bisogno una volta lì. + +### 3.3. Passare e utilizzare l'intera meta map + +Il punto della meta map è dopo tutto di passare tutti i metadati insieme come un pacchetto. +L'unica ragione per cui non potevamo farlo sopra è che il processo non è configurato per accettare una meta map. +Ma poiché controlliamo il codice del processo, possiamo cambiarlo. + +Modifichiamo il processo `COWPY` per accettare la struttura di tupla `[meta, file]` che abbiamo usato nel primo processo in modo da poter semplificare il workflow. + +A tal fine, dovremo fare tre cose: + +1. Modificare le definizioni di input del modulo del processo `COWPY` +2. Aggiornare il comando del processo per utilizzare la meta map +3. Aggiornare la chiamata del processo nel corpo del workflow + +Pronto? Andiamo! + +#### 3.3.1. Modificare l'input del modulo `COWPY` + +Apporti le seguenti modifiche al file del modulo `cowpy.nf`: + +=== "Dopo" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2" + input: + tuple val(meta), path(input_file) + ``` + +=== "Prima" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2-3" + input: + path(input_file) + val character + ``` + +Questo ci consente di utilizzare la struttura di tupla `[meta, file]` che abbiamo trattato in precedenza nel tutorial. + +Noti che non abbiamo aggiornato la definizione di output del processo per restituire la meta map, al fine di mantenere il tutorial snello, ma si senta libero di farlo voi stessi come esercizio seguendo il modello del processo `IDENTIFY_LANGUAGE`. + +#### 3.3.2. Aggiornare il comando per utilizzare il campo della meta map + +L'intera meta map è ora disponibile all'interno del processo, quindi possiamo riferirci alle informazioni che contiene direttamente dall'interno del blocco comando. + +Apporti le seguenti modifiche al file del modulo `cowpy.nf`: + +=== "Dopo" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${meta.character} > cowpy-${input_file} + """ + ``` + +=== "Prima" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ + ``` + +Abbiamo sostituito il riferimento al valore `character` precedentemente passato come input autonomo con il valore contenuto nella meta map, a cui ci riferiamo usando `meta.character`. + +Ora aggiorniamo la chiamata del processo di conseguenza. + +#### 3.3.3. Aggiornare la chiamata del processo ed eseguirlo + +Il processo ora si aspetta che il suo input utilizzi la struttura di tupla `[meta, file]`, che è ciò che il processo precedente restituisce, quindi possiamo semplicemente passare l'intero canale `ch_languages` al processo `COWPY`. + +Apporti le seguenti modifiche al workflow principale: + +=== "Dopo" + + ```groovy title="main.nf" linenums="34" hl_lines="2" + // Esegue cowpy per generare arte ASCII diff --git a/docs/it/docs/side_quests/nf-test.md b/docs/it/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..6bc1a8bdbd --- /dev/null +++ b/docs/it/docs/side_quests/nf-test.md @@ -0,0 +1,1196 @@ +# Testing con nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Essere in grado di testare sistematicamente che ogni parte del workflow faccia ciò che dovrebbe fare è fondamentale per la riproducibilità e la manutenzione a lungo termine, e può essere di grande aiuto durante il processo di sviluppo. + +Prendiamoci un momento per parlare del perché il testing è così importante. Se state sviluppando un workflow, una delle prime cose che farete è prendere alcuni dati di test che sapete essere validi e che dovrebbero produrre un risultato. Aggiungete il primo processo alla pipeline e lo collegate ai vostri input per farlo funzionare. Poi, per verificare che tutto funzioni, lo eseguite sui dati di test. Supponendo che funzioni, passate al processo successivo ed eseguite di nuovo i dati di test. Ripetete questo processo fino a quando avete una pipeline di cui siete soddisfatti. + +Poi, magari aggiungete un semplice parametro vero o falso come `--skip_process`. Ora dovete eseguire la pipeline due volte, una volta con ciascun parametro per assicurarvi che funzioni come previsto. Ma aspettate, come verifichiamo se `--skip_process` salta effettivamente il processo? Dobbiamo scavare negli output o controllare i file di log! Questo è fastidioso e soggetto a errori. + +Man mano che sviluppate la vostra pipeline, diventerà rapidamente così complessa che testare manualmente ogni iterazione sarà lento e soggetto a errori. Inoltre, se trovate un errore, sarà molto difficile individuare esattamente da dove nella vostra pipeline proviene l'errore. È qui che entra in gioco il testing. + +Il testing consente di verificare sistematicamente che ogni parte della pipeline funzioni come previsto. I vantaggi per uno sviluppatore di test ben scritti sono enormi: + +- **Fiducia**: Poiché i test coprono l'intera pipeline, potete essere sicuri che la modifica di qualcosa non influisca su nient'altro +- **Affidabilità**: Quando più sviluppatori lavorano sulla pipeline, sanno che gli altri sviluppatori non hanno rotto la pipeline e ogni componente. +- **Trasparenza**: I test mostrano dove una pipeline sta fallendo e rendono più facile rintracciare il problema. Funzionano anche come una forma di documentazione, mostrando come eseguire un processo o un workflow. +- **Velocità**: Poiché i test sono automatizzati, possono essere eseguiti molto rapidamente e ripetutamente. Potete iterare rapidamente con meno paura di introdurre nuovi bug. + +Ci sono molti tipi diversi di test che possiamo scrivere: + +1. **Test a livello di modulo**: Per processi individuali +2. **Test a livello di workflow**: Per un singolo workflow +3. **Test a livello di pipeline**: Per la pipeline nel suo complesso +4. **Test di performance**: Per la velocità e l'efficienza della pipeline +5. **Stress test**: Valutazione delle prestazioni della pipeline in condizioni estreme per determinarne i limiti + +Testare i processi individuali è analogo agli unit test in altri linguaggi. Testare il workflow o l'intera pipeline è analogo a quello che viene chiamato integration test in altri linguaggi, dove testiamo le interazioni dei componenti. + +[**nf-test**](https://www.nf-test.com/) è uno strumento che consente di scrivere test a livello di modulo, workflow e pipeline. In breve, consente di verificare sistematicamente che ogni singola parte della pipeline funzioni come previsto, _in isolamento_. + +### Obiettivi di apprendimento + +In questa side quest, imparerete a utilizzare nf-test per scrivere un test a livello di workflow per la pipeline nonché test a livello di modulo per i tre processi che chiama. + +Alla fine di questa side quest, sarete in grado di utilizzare efficacemente le seguenti tecniche: + +- Inizializzare nf-test nel vostro progetto +- Generare test a livello di modulo e di workflow +- Aggiungere tipi comuni di asserzioni +- Comprendere quando utilizzare snapshot vs. asserzioni di contenuto +- Eseguire test per un intero progetto + +Queste competenze vi aiuteranno a implementare una strategia di testing completa nei vostri progetti di pipeline, assicurando che siano più robusti e manutenibili. + +### Prerequisiti + +Prima di intraprendere questa side quest, dovreste: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso per principianti equivalente. +- Essere a vostro agio con i concetti e i meccanismi di base di Nextflow (processi, canali, operatori, lavorare con file, metadati) + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non l'avete ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione dell'Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/nf-test +``` + +Potete impostare VSCode per concentrarsi su questa directory: + +```bash +code . +``` + +#### Rivedere i materiali + +Troverete un file di workflow principale e un file CSV chiamato `greetings.csv` che contiene l'input alla pipeline. + +```console title="Contenuto della directory" +. +├── greetings.csv +└── main.nf +``` + +Per una descrizione dettagliata dei file, vedere il [warmup da Hello Nextflow](../hello_nextflow/00_orientation.md). + +Il workflow che testeremo è un sottoinsieme del workflow Hello costruito in [Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +??? example "Cosa fa il workflow Hello Nextflow?" + + Se non avete seguito la formazione [Hello Nextflow](../hello_nextflow/index.md), ecco una rapida panoramica di ciò che fa questo semplice workflow. + + Il workflow prende un file CSV contenente saluti, esegue quattro passaggi di trasformazione consecutivi su di essi e produce un singolo file di testo contenente un'immagine ASCII di un personaggio divertente che dice i saluti. + + I quattro passaggi sono implementati come processi Nextflow (`sayHello`, `convertToUpper`, `collectGreetings`, e `cowpy`) memorizzati in file di modulo separati. + + 1. **`sayHello`:** Scrive ogni saluto nel proprio file di output (es. "Hello-output.txt") + 2. **`convertToUpper`:** Converte ogni saluto in maiuscolo (es. "HELLO") + 3. **`collectGreetings`:** Raccoglie tutti i saluti in maiuscolo in un singolo file batch + 4. **`cowpy`:** Genera arte ASCII utilizzando lo strumento `cowpy` + + I risultati vengono pubblicati in una directory chiamata `results/`, e l'output finale della pipeline (quando eseguita con parametri predefiniti) è un file di testo normale contenente arte ASCII di un personaggio che dice i saluti in maiuscolo. + + In questa side quest, utilizziamo una forma intermedia del workflow Hello che contiene solo i primi due processi. <!-- TODO: change this to use the full finished workflow as suggested in https://github.com/nextflow-io/training/issues/735 --> + +Il sottoinsieme con cui lavoreremo è composto da due processi: `sayHello` e `convertToUpper`. +Potete vedere il codice completo del workflow qui sotto. + +??? example "Codice del workflow" + + ```groovy title="main.nf" + /* + * Parametri della pipeline + */ + params.input_file = "greetings.csv" + + /* + * Usa echo per stampare 'Hello World!' sullo standard out + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Usa un'utilità di sostituzione di testo per convertire il saluto in maiuscolo + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // crea un canale per gli input da un file CSV + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // emette un saluto + sayHello(greeting_ch) + + // converte il saluto in maiuscolo + convertToUpper(sayHello.out) + } + ``` + +#### Eseguire il workflow + +Eseguiamo il workflow per assicurarci che funzioni come previsto. + +```bash +nextflow run main.nf +``` + +```console title="Risultato dell'esecuzione del workflow" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +CONGRATULAZIONI! Avete appena eseguito un test! + +"Aspetta, cosa? Ho appena eseguito il workflow e ha funzionato! Come può essere un test?" + +Bella domanda! + +Analizziamo cosa è appena successo. + +Avete eseguito il workflow con i parametri predefiniti, avete confermato che ha funzionato e siete soddisfatti dei risultati. Questa è l'essenza del testing. Se avete seguito il corso di formazione Hello Nextflow, avrete notato che abbiamo sempre iniziato ogni sezione eseguendo il workflow che stavamo usando come punto di partenza, per confermare che tutto fosse configurato correttamente. + +Il testing del software essenzialmente fa questo processo per noi. + +#### Rivedere l'incarico + +La vostra sfida è aggiungere test standardizzati a questo workflow utilizzando nf-test, al fine di rendere facile verificare che ogni parte continui a funzionare come previsto nel caso vengano apportate ulteriori modifiche. + +<!-- TODO: give a bit more details, similar to how it's done in the Metadata side quest --> + +#### Checklist di preparazione + +Pensate di essere pronti per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato +- [ ] Ho eseguito con successo il workflow +- [ ] Comprendo l'incarico + +Se potete spuntare tutte le caselle, siete pronti per iniziare. + +--- + +## 1. Inizializzare `nf-test` + +Il pacchetto `nf-test` fornisce un comando di inizializzazione che configura alcune cose per consentirci di iniziare a sviluppare test per il nostro progetto. + +```bash +nf-test init +``` + +Questo dovrebbe produrre il seguente output: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Crea anche una directory `tests` contenente uno stub di file di configurazione. + +### 1.1. Generare un nf-test + +`nf-test` viene fornito con un set di strumenti per costruire file nf-test, risparmiandoci la maggior parte del lavoro. Questi rientrano nel sottocomando `generate`. Generiamo un test per la pipeline: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Output" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Questo creerà un file `main.nf.test` all'interno della directory `tests`. Questo è il nostro file di test a livello di pipeline. Se eseguite `tree tests/` dovreste vedere qualcosa del genere: + +```console title="Contenuto della directory test" +tests/ +├── main.nf.test +└── nextflow.config +``` + +Il file `main.nf.test` è il nostro file di test a livello di pipeline. Apriamolo e diamo un'occhiata al contenuto. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Prendiamoci un momento per capire la struttura del file di test. + +Il blocco `nextflow_pipeline` è il punto di ingresso per tutti i test a livello di pipeline. Contiene quanto segue: + +- `name`: Il nome del test. +- `script`: Il percorso allo script della pipeline. + +Il blocco `test` è il test vero e proprio. Contiene quanto segue: + +- `when`: Le condizioni in cui il test dovrebbe essere eseguito. Questo include i parametri che verranno utilizzati per eseguire la pipeline. +- `then`: Le asserzioni che dovrebbero essere fatte. Questo include i risultati attesi della pipeline. + +In parole semplici, la logica del test si legge come segue: +"**Quando** questi _parametri_ vengono forniti a questa _pipeline_, **allora** ci aspettiamo di vedere questi risultati." + +Questo non è un test funzionale, dimostreremo come trasformarlo in uno nella prossima sezione. + +### Una nota sui nomi dei test + +Nell'esempio sopra, abbiamo utilizzato il nome predefinito "Should run without failures" che è appropriato per un test di base che verifica solo se la pipeline viene eseguita con successo. Tuttavia, man mano che aggiungiamo casi di test più specifici, dovremmo usare nomi più descrittivi che indicano cosa stiamo effettivamente testando. Per esempio: + +- "Should convert input to uppercase" - quando testiamo funzionalità specifiche +- "Should handle empty input gracefully" - quando testiamo casi limite +- "Should respect max memory parameter" - quando testiamo vincoli di risorse +- "Should create expected output files" - quando testiamo la generazione di file + +I buoni nomi dei test dovrebbero: + +1. Iniziare con "Should" per rendere chiaro quale sia il comportamento atteso +2. Descrivere la funzionalità specifica o lo scenario che viene testato +3. Essere abbastanza chiari che se il test fallisce, sapete quale funzionalità è rotta + +Man mano che aggiungiamo più asserzioni e casi di test specifici in seguito, useremo questi nomi più descrittivi per rendere chiaro cosa sta verificando ogni test. + +### 1.2. Eseguire il test + +Eseguiamo il test per vedere cosa succede. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test pipeline fail" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Il test fallisce! Cosa è successo? + +1. nf-test ha tentato di eseguire la pipeline così com'è, utilizzando le impostazioni nel blocco `when`: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test ha controllato lo stato della pipeline e l'ha confrontato con il blocco `when`: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Notate come nf-test ha riportato che la pipeline è fallita e ha fornito il messaggio di errore da Nextflow: + +```console title="Errore" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Quindi qual era il problema? Ricordate che la pipeline ha un file greetings.csv nella directory del progetto. Quando nf-test esegue la pipeline, cercherà questo file, ma non riesce a trovarlo. Il file è lì, cosa sta succedendo? Bene, se guardiamo il percorso possiamo vedere che il test sta avvenendo nel percorso `./nf-test/tests/longHashString/`. Proprio come Nextflow, nf-test crea una nuova directory per ogni test per mantenere tutto isolato. Il file di dati non si trova lì quindi dobbiamo correggere il percorso del file nel test originale. + +Potreste chiedervi come faremo a puntare alla radice della pipeline nel test. Poiché questa è una situazione comune, nf-test ha una serie di variabili globali che possiamo usare per facilitarci la vita. Potete trovare l'elenco completo [qui](https://www.nf-test.com/docs/testcases/global_variables/) ma nel frattempo useremo la variabile `projectDir`, che indica la radice del progetto della pipeline. + +_Prima:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Dopo:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Eseguiamo di nuovo il test per vedere se funziona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="La pipeline passa" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Successo! La pipeline viene eseguita con successo e il test passa. Eseguitelo quante volte volete e otterrete sempre lo stesso risultato! + +Per impostazione predefinita, l'output di Nextflow è nascosto, ma per convincervi che nf-test stia effettivamente eseguendo il workflow, potete usare il flag `--verbose`: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="La pipeline esegue tutti i processi" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Aggiungere asserzioni + +Un controllo semplice è assicurarsi che la nostra pipeline esegua tutti i processi che ci aspettiamo e non ne salti nessuno silenziosamente. Ricordate che la nostra pipeline esegue 6 processi, uno chiamato `sayHello` e uno chiamato `convertToUpper` per ciascuno dei 3 saluti. + +Aggiungiamo un'asserzione al nostro test per verificare che la pipeline eseguite il numero atteso di processi. Aggiorneremo anche il nome del nostro test per riflettere meglio ciò che stiamo testando. + +**Prima:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Dopo:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Il nome del test ora riflette meglio ciò che stiamo effettivamente verificando - non solo che la pipeline viene eseguita senza fallire, ma che esegue il numero atteso di processi. + +Eseguiamo di nuovo il test per vedere se funziona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="La pipeline passa con asserzioni" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Successo! La pipeline viene eseguita con successo e il test passa. Ora abbiamo iniziato a testare i dettagli della pipeline, oltre allo stato generale. + +### 1.4. Testare l'output + +Aggiungiamo un'asserzione al nostro test per verificare che il file di output sia stato creato. Lo aggiungeremo come test separato, con un nome informativo, per rendere i risultati più facili da interpretare. + +**Prima:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Dopo:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Eseguire di nuovo il test per vedere se funziona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="La pipeline passa con asserzioni sui file" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Successo! I test passano perché la pipeline è stata completata con successo, è stato eseguito il numero corretto di processi e i file di output sono stati creati. Questo dovrebbe anche mostrarvi quanto sia utile fornire quei nomi informativi per i vostri test. + +Questa è solo la superficie, possiamo continuare a scrivere asserzioni per verificare i dettagli della pipeline, ma per ora passiamo a testare gli elementi interni della pipeline. + +### Riepilogo + +Sapete come scrivere un nf-test per una pipeline. + +### Qual è il prossimo passo? + +Imparate come testare un processo Nextflow. + +--- + +## 2. Testare un processo Nextflow + +Non dobbiamo scrivere test per ogni parte della pipeline, ma più test abbiamo, più possiamo essere completi sulla pipeline e più possiamo essere sicuri che funzioni come previsto. In questa sezione testeremo entrambi i processi nella pipeline come unità individuali. + +### 2.1. Testare il processo `sayHello` + +Iniziamo con il processo `sayHello`. + +Utilizziamo di nuovo il comando `nf-test generate` per generare test per il processo. + +```bash +nf-test generate process main.nf +``` + +```console title="Output" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Concentriamoci per ora sul processo `sayhello` nel file `main.sayhello.nf.test`. + +Apriamo il file e diamo un'occhiata al contenuto. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Come prima, iniziamo con i dettagli del test, seguiti dai blocchi `when` e `then`. Tuttavia, abbiamo anche un blocco `process` aggiuntivo che ci consente di definire gli input al processo. + +Eseguiamo il test per vedere se funziona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Il test del processo fallisce" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Il test fallisce perché il processo `sayHello` dichiara 1 input ma è stato chiamato con 0 argomenti. Risolviamo questo problema aggiungendo un input al processo. Ricordate da [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (e dalla sezione di warmup sopra) che il nostro processo `sayHello` prende un singolo input di valore, che dovremo fornire. Dovremmo anche correggere il nome del test per riflettere meglio ciò che stiamo testando. + +**Prima:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Dopo:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Eseguiamo di nuovo il test per vedere se funziona. + +```console title="nf-test pipeline pass" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Successo! Il test passa perché il processo `sayHello` è stato eseguito con successo e l'output è stato creato. + +### 2.2. Verificare lo snapshot creato dal test + +Se guardiamo il file `tests/main.sayhello.nf.test`, possiamo vedere che utilizza un metodo `snapshot()` nel blocco di asserzione: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Questo sta dicendo a nf-test di creare uno snapshot dell'output del processo `sayHello`. Diamo un'occhiata al contenuto del file di snapshot. + +```console title="Contenuto del file snapshot" +code tests/main.sayhello.nf.test.snap +``` + +Non lo stamperemo qui, ma dovreste vedere un file JSON contenente i dettagli del processo e degli output del processo. In particolare, possiamo vedere una riga che assomiglia a questa: + +```json title="Contenuto del file snapshot" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Questo rappresenta gli output creati dal processo `sayHello`, che stiamo testando esplicitamente. Se rieseguiamo il test, il programma verificherà che il nuovo output corrisponda all'output che è stato originariamente registrato. Questo è un modo rapido e semplice per testare che gli output del processo non cambino, ed è per questo che nf-test lo fornisce come predefinito. + +!!!warning "Avviso" + + Ciò significa che dobbiamo essere sicuri che l'output che registriamo nell'esecuzione originale sia corretto! + +Se, nel corso dello sviluppo futuro, qualcosa nel codice cambia e causa un output diverso, il test fallirà e dovremo determinare se il cambiamento è previsto o meno. + +- Se si scopre che qualcosa nel codice si è rotto, dovremo risolverlo, con l'aspettativa che il codice corretto passerà il test. +- Se è un cambiamento previsto (ad esempio, lo strumento è stato migliorato e i risultati sono migliori) allora dovremo aggiornare lo snapshot per accettare il nuovo output come riferimento da abbinare. nf-test ha un parametro `--update-snapshot` a questo scopo. + +Possiamo eseguire di nuovo il test e vedere che il test dovrebbe passare: + +```console title="nf-test process pass con snapshot" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Successo! Il test passa perché il processo `sayHello` è stato eseguito con successo e l'output corrisponde allo snapshot. + +### 2.3. Alternativa agli Snapshot: Asserzioni Dirette sul Contenuto + +Sebbene gli snapshot siano ottimi per rilevare qualsiasi modifica nell'output, a volte si desidera verificare contenuti specifici senza essere così rigorosi sull'intera corrispondenza del file. Per esempio: + +- Quando parti dell'output potrebbero cambiare (timestamp, ID casuali, ecc.) ma determinati contenuti chiave devono essere presenti +- Quando si desidera verificare modelli o valori specifici nell'output +- Quando si desidera rendere il test più esplicito su cosa costituisce il successo + +Ecco come potremmo modificare il nostro test per verificare contenuti specifici: + +**Prima:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Dopo:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // definire parametri qui + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Notate che nf-test vede gli output del processo come una lista di liste, quindi `process.out[0][0]` sta recuperando la prima parte del primo elemento del canale (o 'emissione') da questo processo. + +Questo approccio: + +- Rende chiaro esattamente cosa ci aspettiamo nell'output +- È più resiliente a modifiche irrilevanti nell'output +- Fornisce messaggi di errore migliori quando i test falliscono +- Consente validazioni più complesse (modelli regex, confronti numerici, ecc.) + +Eseguiamo il test per vedere se funziona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Il test del processo fallisce" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Testare il processo `convertToUpper` + +Apriamo il file `tests/main.converttoupper.nf.test` e diamo un'occhiata al contenuto: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Questo è un test simile al processo `sayHello`, ma sta testando il processo `convertToUpper`. Sappiamo che questo fallirà perché proprio come con `sayHello`, il processo `convertToUpper` prende un singolo input path, ma non ne abbiamo specificato uno. + +Ora dobbiamo fornire un singolo file di input al processo convertToUpper, che include del testo che vogliamo convertire in maiuscolo. Ci sono molti modi per farlo: + +- Potremmo creare un file dedicato da testare +- Potremmo riutilizzare il file data/greetings.csv esistente +- Potremmo crearlo al volo all'interno del test + +Per ora, riutilizziamo il file data/greetings.csv esistente utilizzando l'esempio che abbiamo usato con il test a livello di pipeline. Come prima, possiamo nominare il test per riflettere meglio ciò che stiamo testando, ma questa volta lasciamo che crei uno 'snapshot' del contenuto piuttosto che verificare stringhe specifiche (come abbiamo fatto nell'altro processo). + +**Prima:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Dopo:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Ed eseguire il test! + +```bash title="nf-test pipeline pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Notate, abbiamo creato un file di snapshot per il processo `convertToUpper` in `tests/main.converttoupper.nf.test.snap`. Se eseguiamo di nuovo il test, dovremmo vedere che nf-test passa di nuovo. + +```bash title="nf-test process convertToUpper pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Riepilogo + +Sapete come scrivere test per un processo Nextflow ed eseguirli. + +### Qual è il prossimo passo? + +Imparate come eseguire test per tutto in una volta! + +## 3. Eseguire test per l'intero repository + +Eseguire nf-test su ogni componente va bene, ma è laborioso e soggetto a errori. Non possiamo testare tutto in una volta? + +Sì, possiamo! + +Eseguiamo nf-test sull'intero repo. + +### 3.1. Eseguire nf-test sull'intero repo + +Possiamo eseguire nf-test sull'intero repo eseguendo il comando `nf-test test`. + +```bash +nf-test test . +``` + +Notate, stiamo solo usando il `.` per eseguire tutto dalla nostra directory corrente. Questo includerà ogni test! + +```console title="nf-test repo pass" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Guardate! Abbiamo eseguito 4 test, 1 per ogni processo e 2 per l'intera pipeline con un singolo comando. Immaginate quanto sia potente questo su una grande base di codice! + +--- + +## Riepilogo + +In questa side quest, avete imparato a sfruttare le funzionalità di nf-test per creare ed eseguire test per processi individuali nonché test end-to-end per l'intera pipeline. +Ora siete consapevoli dei due principali approcci alla validazione dell'output, snapshot e asserzioni dirette sul contenuto, e quando utilizzare l'uno o l'altro. +Sapete anche come eseguire test uno per uno o per un intero progetto. + +L'applicazione di queste tecniche nel vostro lavoro vi consentirà di garantire che: + +- Il vostro codice funzioni come previsto +- Le modifiche non rompano la funzionalità esistente +- Altri sviluppatori possano contribuire con fiducia +- I problemi possano essere identificati e risolti rapidamente +- Il contenuto dell'output corrisponda alle aspettative + +### Pattern chiave + +<!-- TODO: Can we add snippets of code below to illustrate? --> + +1. Test a livello di pipeline: + - Testing di successo di base + - Verifica del conteggio dei processi + - Controlli di esistenza dei file di output +2. Test a livello di processo +3. Due approcci alla validazione dell'output: + - Utilizzo di snapshot per la verifica completa dell'output + - Utilizzo di asserzioni dirette sul contenuto per controlli di contenuto specifici +4. Esecuzione di tutti i test in un repository con un singolo comando + +### Risorse aggiuntive + +Consultate la [documentazione di nf-test](https://www.nf-test.com/) per funzionalità di testing più avanzate e best practice. Potreste voler: + +- Aggiungere asserzioni più complete ai vostri test +- Scrivere test per casi limite e condizioni di errore +- Impostare l'integrazione continua per eseguire i test automaticamente +- Imparare su altri tipi di test come test di workflow e moduli +- Esplorare tecniche di validazione del contenuto più avanzate + +**Ricordate:** I test sono documentazione viva di come il vostro codice dovrebbe comportarsi. Più test scrivete, e più specifiche sono le vostre asserzioni, più potete essere sicuri dell'affidabilità della vostra pipeline. + +--- + +## Qual è il prossimo passo? + +Tornate al [menu delle Side Quest](./index.md) o cliccate il pulsante in basso a destra della pagina per passare al prossimo argomento nell'elenco. diff --git a/docs/it/docs/side_quests/orientation.md b/docs/it/docs/side_quests/orientation.md new file mode 100644 index 0000000000..db1bd328a7 --- /dev/null +++ b/docs/it/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +L'ambiente GitHub Codespaces contiene tutto il software, il codice e i dati necessari per seguire questo corso di formazione, quindi non è necessario installare nulla autonomamente. +Tuttavia, è necessario un account (gratuito) per effettuare l'accesso, e dovrebbe dedicare alcuni minuti per familiarizzare con l'interfaccia. + +Se non lo ha ancora fatto, segua [questo link](../../envsetup/) prima di proseguire. + +## Materiali forniti + +Durante questo corso di formazione, lavoreremo nella directory `side-quests/`. +Questa directory contiene tutti i file di codice, i dati di test e i file accessori di cui avrà bisogno. + +Si senta libero di esplorare il contenuto di questa directory; il modo più semplice per farlo è utilizzare l'explorer dei file sul lato sinistro dell'area di lavoro di GitHub Codespaces. +In alternativa, potete utilizzare il comando `tree`. +Durante il corso, utilizziamo l'output di `tree` per rappresentare la struttura e il contenuto delle directory in forma leggibile, talvolta con modifiche minori per maggiore chiarezza. + +Qui generiamo un indice dei contenuti fino al secondo livello: + +```bash +tree . -L 2 +``` + +Se esegue questo comando all'interno di `side-quests`, dovrebbe vedere il seguente output: + +```console title="Contenuto della directory" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Ecco un riepilogo di ciò che dovrebbe sapere per iniziare:** + +- **Ogni directory corrisponde a una side quest individuale.** + I loro contenuti sono dettagliati nella pagina della corrispondente side quest. + +- **La directory `solutions`** contiene gli script di workflow e/o modulo completati che risultano dall'esecuzione dei vari passaggi di ciascuna side quest. + Sono destinati ad essere utilizzati come riferimento per verificare il suo lavoro e risolvere eventuali problemi. + +!!!tip "Suggerimento" + + Se per qualsiasi motivo doveste uscire da questa directory, potete sempre eseguire questo comando per tornarvi: + + ```bash + cd /workspaces/training/side-quests + ``` + +Ora, per iniziare il corso, cliccate sulla freccia nell'angolo in basso a destra di questa pagina. diff --git a/docs/it/docs/side_quests/splitting_and_grouping.md b/docs/it/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..214c3c1d94 --- /dev/null +++ b/docs/it/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,1061 @@ +# Divisione e Raggruppamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow fornisce strumenti potenti per lavorare con i dati in modo flessibile. Una capacità chiave è la divisione dei dati in flussi diversi e il successivo raggruppamento degli elementi correlati. Questo è particolarmente prezioso nei workflow di bioinformatica dove è necessario processare diversi tipi di campioni separatamente prima di combinare i risultati per l'analisi. + +Pensatelo come smistare la posta: separate le lettere per destinazione, processate ogni pila in modo diverso, poi ricombinate gli elementi destinati alla stessa persona. Nextflow utilizza operatori speciali per realizzare questo con dati scientifici. Questo approccio è anche comunemente noto come pattern **scatter/gather** nel computing distribuito e nei workflow di bioinformatica. + +Il sistema di canali di Nextflow è al centro di questa flessibilità. I canali connettono diverse parti del workflow, permettendo ai dati di fluire attraverso l'analisi. È possibile creare canali multipli da una singola fonte di dati, processare ciascun canale in modo diverso, e poi unire i canali quando necessario. Questo approccio permette di progettare workflow che rispecchiano naturalmente i percorsi ramificati e convergenti delle analisi bioinformatiche complesse. + +### Obiettivi di apprendimento + +In questa missione secondaria, imparerete a dividere e raggruppare dati usando gli operatori di canale di Nextflow. +Inizieremo con un file CSV contenente informazioni sui campioni e file di dati associati, poi manipoleremo e riorganizzeremo questi dati. + +Alla fine di questa missione secondaria, sarete in grado di separare e combinare flussi di dati in modo efficace, utilizzando le seguenti tecniche: + +- Leggere dati da file usando `splitCsv` +- Filtrare e trasformare dati con `filter` e `map` +- Combinare dati correlati usando `join` e `groupTuple` +- Creare combinazioni di dati con `combine` per l'elaborazione parallela +- Ottimizzare la struttura dati usando `subMap` e strategie di deduplicazione +- Costruire funzioni riutilizzabili con closure nominate per aiutarvi a manipolare le strutture dei canali + +Queste competenze vi aiuteranno a costruire workflow che possono gestire file di input multipli e diversi tipi di dati in modo efficiente, mantenendo una struttura di codice pulita e manutenibile. + +### Prerequisiti + +Prima di intraprendere questa missione secondaria, dovreste: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso equivalente per principianti. +- Essere a proprio agio con i concetti e meccanismi base di Nextflow (processi, canali, operatori, lavoro con file, meta data) + +**Opzionale:** Raccomandiamo di completare prima la missione secondaria [Metadata nei workflow](./metadata.md). +Questa copre i fondamenti della lettura di file CSV con `splitCsv` e della creazione di meta map, che useremo intensamente qui. + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non lo avete ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto nella [Configurazione dell'Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/splitting_and_grouping +``` + +Potete impostare VSCode per concentrarsi su questa directory: + +```bash +code . +``` + +#### Rivedere i materiali + +Troverete un file workflow principale e una directory `data` contenente un samplesheet chiamato `samplesheet.csv`. + +```console title="Contenuti della directory" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +Il samplesheet contiene informazioni sui campioni di diversi pazienti, inclusi l'ID paziente, il numero di ripetizione del campione, il tipo (normale o tumorale), e i percorsi ai file di dati ipotetici (che in realtà non esistono, ma faremo finta che esistano). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Questo samplesheet elenca otto campioni da tre pazienti (A, B, C). + +Per ciascun paziente, abbiamo campioni di tipo `tumor` (tipicamente originati da biopsie tumorali) o `normal` (prelevati da tessuto sano o sangue). +Se non avete familiarità con l'analisi del cancro, sappiate semplicemente che questo corrisponde a un modello sperimentale che utilizza campioni appaiati tumore/normale per eseguire analisi contrastive. + +Per il paziente A specificatamente, abbiamo due set di repliche tecniche. + +!!! note + + Non preoccupatevi se non avete familiarità con questo disegno sperimentale, non è critico per comprendere questo tutorial. + +#### Rivedere l'incarico + +La vostra sfida è scrivere un workflow Nextflow che: + +1. **Legga** i dati dei campioni da un file CSV e li strutturi con meta map +2. **Separi** i campioni in canali diversi in base al tipo (normale vs tumore) +3. **Unisca** le coppie tumore/normale corrispondenti per ID paziente e numero di replica +4. **Distribuisca** i campioni attraverso intervalli genomici per l'elaborazione parallela +5. **Raggruppi** i campioni correlati per l'analisi downstream + +Questo rappresenta un pattern bioinformatico comune dove è necessario dividere i dati per l'elaborazione indipendente, poi ricombinare gli elementi correlati per l'analisi comparativa. + +#### Checklist di preparazione + +Pensate di essere pronti per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la directory di lavoro appropriatamente +- [ ] Comprendo l'incarico + +Se potete spuntare tutte le caselle, siete pronti per partire. + +--- + +## 1. Leggere i dati dei campioni + +### 1.1. Leggere i dati dei campioni con `splitCsv` e creare meta map + +Iniziamo leggendo i dati dei campioni con `splitCsv` e organizzandoli nel pattern meta map. Nel `main.nf`, vedrete che abbiamo già iniziato il workflow. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + In tutto questo tutorial, useremo il prefisso `ch_` per tutte le variabili canale per indicare chiaramente che sono canali Nextflow. + +Se avete completato la missione secondaria [Metadata nei workflow](./metadata.md), riconoscerete questo pattern. Useremo `splitCsv` per leggere il CSV e strutturare immediatamente i dati con una meta map per separare i metadata dai percorsi dei file. + +!!! info + + Incontreremo due concetti diversi chiamati `map` in questa formazione: + + - **Struttura dati**: La map Groovy (equivalente a dizionari/hash in altri linguaggi) che memorizza coppie chiave-valore + - **Operatore di canale**: L'operatore `.map()` che trasforma elementi in un canale + + Chiariremo quale intendiamo nel contesto, ma questa distinzione è importante da comprendere quando si lavora con Nextflow. + +Applicate questi cambiamenti al `main.nf`: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Questo combina l'operazione `splitCsv` (lettura del CSV con intestazioni) e l'operazione `map` (strutturazione dei dati come tuple `[meta, file]`) in un solo passaggio. Applicate quella modifica ed eseguite il pipeline: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Ora abbiamo un canale dove ogni elemento è una tupla `[meta, file]` - metadata separati dai percorsi dei file. Questa struttura ci permette di dividere e raggruppare il nostro carico di lavoro in base ai campi dei metadata. + +--- + +## 2. Filtrare e trasformare i dati + +### 2.1. Filtrare i dati con `filter` + +Possiamo usare l'[operatore `filter`](https://www.nextflow.io/docs/latest/operator.html#filter) per filtrare i dati in base a una condizione. Diciamo che vogliamo processare solo campioni normali. Possiamo farlo filtrando i dati in base al campo `type`. Inseriamo questo prima dell'operatore `view`. + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Eseguite di nuovo il workflow per vedere il risultato filtrato: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Abbiamo filtrato con successo i dati per includere solo i campioni normali. Ricapitoliamo come funziona. + +L'operatore `filter` prende una closure che viene applicata a ciascun elemento nel canale. Se la closure restituisce `true`, l'elemento viene incluso; se restituisce `false`, l'elemento viene escluso. + +Nel nostro caso, vogliamo mantenere solo i campioni dove `meta.type == 'normal'`. La closure usa la tupla `meta,file` per riferirsi a ciascun campione, accede al tipo di campione con `meta.type`, e verifica se è uguale a `'normal'`. + +Questo viene realizzato con la singola closure che abbiamo introdotto sopra: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Creare canali filtrati separati + +Attualmente stiamo applicando il filtro al canale creato direttamente dal CSV, ma vogliamo filtrare questo in più modi di uno, quindi riscriviamo la logica per creare un canale filtrato separato per i campioni normali: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Eseguite il pipeline per vedere i risultati: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Abbiamo filtrato con successo i dati e creato un canale separato per i campioni normali. + +Creiamo anche un canale filtrato per i campioni tumorali: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Abbiamo separato i campioni normali e tumorali in due canali diversi, e usato una closure fornita a `view()` per etichettarli diversamente nell'output: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Sintesi + +In questa sezione, avete imparato: + +- **Filtrare i dati**: Come filtrare i dati con `filter` +- **Dividere i dati**: Come dividere i dati in canali diversi in base a una condizione +- **Visualizzare i dati**: Come usare `view` per stampare i dati ed etichettare l'output da canali diversi + +Abbiamo ora separato i campioni normali e tumorali in due canali diversi. Successivamente, uniremo i campioni normali e tumorali sul campo `id`. + +--- + +## 3. Unire i canali per identificatori + +Nella sezione precedente, abbiamo separato i campioni normali e tumorali in due canali diversi. Questi potrebbero essere processati indipendentemente usando processi o workflow specifici in base al loro tipo. Ma cosa succede quando vogliamo confrontare i campioni normali e tumorali dello stesso paziente? A questo punto, dobbiamo unirli assicurandoci di abbinare i campioni in base al loro campo `id`. + +Nextflow include molti metodi per combinare i canali, ma in questo caso l'operatore più appropriato è [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Se avete familiarità con SQL, agisce come l'operazione `JOIN`, dove specifichiamo la chiave su cui unire e il tipo di join da eseguire. + +### 3.1. Usare `map` e `join` per combinare in base all'ID paziente + +Se controlliamo la documentazione di [`join`](https://www.nextflow.io/docs/latest/operator.html#join), possiamo vedere che per impostazione predefinita unisce due canali in base al primo elemento in ciascuna tupla. + +#### 3.1.1. Controllare la struttura dati + +Se non avete ancora l'output della console disponibile, eseguiamo il pipeline per controllare la nostra struttura dati e vedere come dobbiamo modificarla per unire sul campo `id`. + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Possiamo vedere che il campo `id` è il primo elemento in ciascuna meta map. Perché `join` funzioni, dovremmo isolare il campo `id` in ciascuna tupla. Dopo di che, possiamo semplicemente usare l'operatore `join` per combinare i due canali. + +#### 3.1.2. Isolare il campo `id` + +Per isolare il campo `id`, possiamo usare l'[operatore `map`](https://www.nextflow.io/docs/latest/operator.html#map) per creare una nuova tupla con il campo `id` come primo elemento. + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Potrebbe essere sottile, ma dovreste essere in grado di vedere che il primo elemento in ciascuna tupla è il campo `id`. + +#### 3.1.3. Combinare i due canali + +Ora possiamo usare l'operatore `join` per combinare i due canali in base al campo `id`. + +Ancora una volta, useremo `view` per stampare gli output uniti. + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +È un po' difficile da leggere perché è molto largo, ma dovreste essere in grado di vedere che i campioni sono stati uniti per il campo `id`. Ciascuna tupla ora ha il formato: + +- `id`: L'ID del campione +- `normal_meta_map`: I metadata del campione normale inclusi tipo, replica e percorso al file bam +- `normal_sample_file`: Il file del campione normale +- `tumor_meta_map`: I metadata del campione tumorale inclusi tipo, replica e percorso al file bam +- `tumor_sample`: Il campione tumorale inclusi tipo, replica e percorso al file bam + +!!! warning + + L'operatore `join` scarterà qualsiasi tupla non abbinata. In questo esempio, ci siamo assicurati che tutti i campioni fossero abbinati per tumore e normale ma se questo non è vero dovete usare il parametro `remainder: true` per mantenere le tuple non abbinate. Controllate la [documentazione](https://www.nextflow.io/docs/latest/operator.html#join) per maggiori dettagli. + +Quindi ora sapete come usare `map` per isolare un campo in una tupla, e come usare `join` per combinare tuple in base al primo campo. +Con questa conoscenza, possiamo combinare con successo i canali in base a un campo condiviso. + +Successivamente, considereremo la situazione in cui volete unire su campi multipli. + +### 3.2. Unire su campi multipli + +Abbiamo 2 repliche per il sampleA, ma solo 1 per sampleB e sampleC. In questo caso siamo stati in grado di unirli efficacemente usando il campo `id`, ma cosa succederebbe se fossero fuori sincronizzazione? Potremmo mescolare i campioni normali e tumorali da diverse repliche! + +Per evitare questo, possiamo unire su campi multipli. Ci sono in realtà diversi modi per ottenere questo ma ci concentreremo sulla creazione di una nuova chiave di unione che include sia il campo `id` che il numero di `replicate`. + +Iniziamo creando una nuova chiave di unione. Possiamo farlo nello stesso modo di prima usando l'[operatore `map`](https://www.nextflow.io/docs/latest/operator.html#map) per creare una nuova tupla con i campi `id` e `repeat` come primo elemento. + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Ora dovremmo vedere l'unione avvenire ma usando sia i campi `id` che `repeat`. Eseguite il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Notate come abbiamo una tupla di due elementi (campi `id` e `repeat`) come primo elemento di ciascun risultato unito. Questo dimostra come elementi complessi possono essere usati come chiave di unione, abilitando abbinamenti abbastanza intricati tra campioni delle stesse condizioni. + +Se volete esplorare altri modi per unire su chiavi diverse, controllate la [documentazione dell'operatore join](https://www.nextflow.io/docs/latest/operator.html#join) per opzioni ed esempi aggiuntivi. + +### 3.3. Usare `subMap` per creare una nuova chiave di unione + +L'approccio precedente perde i nomi dei campi dalla nostra chiave di unione - i campi `id` e `repeat` diventano solo una lista di valori. Per mantenere i nomi dei campi per l'accesso successivo, possiamo usare il [metodo `subMap`](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>). + +Il metodo `subMap` estrae solo le coppie chiave-valore specificate da una map. Qui estrarremo solo i campi `id` e `repeat` per creare la nostra chiave di unione. + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Ora abbiamo una nuova chiave di unione che non solo include i campi `id` e `repeat` ma mantiene anche i nomi dei campi così possiamo accedervi successivamente per nome, ad esempio `meta.id` e `meta.repeat`. + +### 3.4. Usare una closure nominata in map + +Per evitare duplicazioni e ridurre errori, possiamo usare una closure nominata. Una closure nominata ci permette di creare una funzione riutilizzabile che possiamo chiamare in più posti. + +Per farlo, prima definiamo la closure come una nuova variabile: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Abbiamo definito la trasformazione map come variabile nominata che possiamo riutilizzare. + +Notate che convertiamo anche il percorso del file in un oggetto Path usando `file()` così che qualsiasi processo che riceve questo canale possa gestire il file correttamente (per maggiori informazioni vedere [Lavorare con i file](./working_with_files.md)). + +Implementiamo la closure nel nostro workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + L'operatore `map` è passato dall'usare `{ }` all'usare `( )` per passare la closure come argomento. Questo perché l'operatore `map` si aspetta una closure come argomento e `{ }` viene usato per definire una closure anonima. Quando si chiama una closure nominata, usare la sintassi `( )`. + +Eseguite di nuovo il workflow per verificare che tutto funzioni ancora: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Usare una closure nominata ci permette di riutilizzare la stessa trasformazione in più posti, riducendo il rischio di errori e rendendo il codice più leggibile e manutenibile. + +### 3.5. Ridurre la duplicazione dei dati + +Abbiamo molti dati duplicati nel nostro workflow. Ciascun elemento nei campioni uniti ripete i campi `id` e `repeat`. Dato che questa informazione è già disponibile nella chiave di raggruppamento, possiamo evitare questa ridondanza. Come promemoria, la nostra struttura dati attuale appare così: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Dato che i campi `id` e `repeat` sono disponibili nella chiave di raggruppamento, rimuoviamoli dal resto di ciascun elemento del canale per evitare la duplicazione. Possiamo farlo usando il metodo `subMap` per creare una nuova map con solo il campo `type`. Questo approccio ci permette di mantenere tutte le informazioni necessarie eliminando la ridondanza nella nostra struttura dati. + +=== "Dopo" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Ora la closure restituisce una tupla dove il primo elemento contiene i campi `id` e `repeat`, e il secondo elemento contiene solo il campo `type`. Questo elimina la ridondanza memorizzando le informazioni `id` e `repeat` una volta nella chiave di raggruppamento, mantenendo tutte le informazioni necessarie. + +Eseguite il workflow per vedere come appare: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Possiamo vedere che dichiariamo i campi `id` e `repeat` solo una volta nella chiave di raggruppamento e abbiamo il campo `type` nei dati del campione. Non abbiamo perso alcuna informazione ma siamo riusciti a rendere i contenuti del nostro canale più succinti. + +### 3.6. Rimuovere informazioni ridondanti + +Abbiamo rimosso le informazioni duplicate sopra, ma abbiamo ancora altre informazioni ridondanti nei nostri canali. + +All'inizio, abbiamo separato i campioni normali e tumorali usando `filter`, poi li abbiamo uniti in base alle chiavi `id` e `repeat`. L'operatore `join` preserva l'ordine in cui le tuple vengono unite, quindi nel nostro caso, con i campioni normali sul lato sinistro e i campioni tumorali sulla destra, il canale risultante mantiene questa struttura: `id, <elementi normali>, <elementi tumorali>`. + +Dato che conosciamo la posizione di ciascun elemento nel nostro canale, possiamo semplificare ulteriormente la struttura eliminando i metadata `[type:normal]` e `[type:tumor]`. + +=== "Dopo" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Eseguite di nuovo per vedere il risultato: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Sintesi + +In questa sezione, avete imparato: + +- **Manipolare le Tuple**: Come usare `map` per isolare un campo in una tupla +- **Unire le Tuple**: Come usare `join` per combinare tuple in base al primo campo +- **Creare Chiavi di Unione**: Come usare `subMap` per creare una nuova chiave di unione +- **Closure Nominate**: Come usare una closure nominata in map +- **Unione su Campi Multipli**: Come unire su campi multipli per abbinamenti più precisi +- **Ottimizzazione della Struttura Dati**: Come semplificare la struttura del canale rimuovendo informazioni ridondanti + +Ora avete un workflow che può dividere un samplesheet, filtrare i campioni normali e tumorali, unirli per ID campione e numero di replica, poi stampare i risultati. + +Questo è un pattern comune nei workflow di bioinformatica dove è necessario abbinare campioni o altri tipi di dati dopo l'elaborazione indipendente, quindi è una competenza utile. Successivamente, vedremo come ripetere un campione più volte. + +## 4. Distribuire campioni su intervalli + +Un pattern chiave nei workflow di bioinformatica è la distribuzione dell'analisi attraverso regioni genomiche. Ad esempio, il variant calling può essere parallelizzato dividendo il genoma in intervalli (come cromosomi o regioni più piccole). Questa strategia di parallelizzazione migliora significativamente l'efficienza del pipeline distribuendo il carico computazionale attraverso core o nodi multipli, riducendo il tempo complessivo di esecuzione. + +Nella sezione seguente, dimostreremo come distribuire i nostri dati dei campioni attraverso intervalli genomici multipli. Abbineremo ciascun campione con ogni intervallo, permettendo l'elaborazione parallela di diverse regioni genomiche. Questo moltiplicherà la dimensione del nostro dataset per il numero di intervalli, creando unità di analisi indipendenti multiple che possono essere riportate insieme successivamente. + +### 4.1. Distribuire campioni su intervalli usando `combine` + +Iniziamo creando un canale di intervalli. Per mantenere la vita semplice, useremo solo 3 intervalli che definiremo manualmente. In un workflow reale, potreste leggerli da un file di input o persino creare un canale con molti file di intervalli. + +=== "Dopo" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Ora ricordate, vogliamo ripetere ciascun campione per ogni intervallo. Questo è a volte chiamato prodotto Cartesiano dei campioni e intervalli. Possiamo ottenere questo usando l'[operatore `combine`](https://www.nextflow.io/docs/latest/operator.html#combine). Questo prenderà ogni elemento dal canale 1 e lo ripeterà per ogni elemento nel canale 2. Aggiungiamo un operatore combine al nostro workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Ora eseguiamolo e vediamo cosa succede: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Successo! Abbiamo ripetuto ogni campione per ogni singolo intervallo nella nostra lista di 3 intervalli. Abbiamo effettivamente triplicato il numero di elementi nel nostro canale. + +È un po' difficile da leggere però, quindi nella prossima sezione lo riordineremo. + +### 4.2. Organizzare il canale + +Possiamo usare l'operatore `map` per riordinare e ristrutturare i dati del nostro campione così che siano più facili da comprendere. Spostiamo la stringa degli intervalli alla map di unione al primo elemento. + +=== "Dopo" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Analizziamo cosa fa questa operazione map passo dopo passo. + +Prima, usiamo parametri nominati per rendere il codice più leggibile. Usando i nomi `grouping_key`, `normal`, `tumor` e `interval`, possiamo riferirci agli elementi nella tupla per nome invece che per indice: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Successivamente, combiniamo la `grouping_key` con il campo `interval`. La `grouping_key` è una map contenente i campi `id` e `repeat`. Creiamo una nuova map con l'`interval` e le uniamo usando l'addizione di map Groovy (`+`): + +```groovy + grouping_key + [interval: interval], +``` + +Infine, restituiamo questo come tupla con tre elementi: la map di metadata combinata, il file del campione normale, e il file del campione tumorale: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Eseguiamolo di nuovo e controlliamo i contenuti del canale: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Usare `map` per coercere i dati nella struttura corretta può essere complicato, ma è cruciale per la manipolazione efficace dei dati. + +Ora abbiamo ogni campione ripetuto attraverso tutti gli intervalli genomici, creando unità di analisi indipendenti multiple che possono essere processate in parallelo. Ma cosa succede se vogliamo riportare insieme campioni correlati? Nella prossima sezione, impareremo come raggruppare campioni che condividono attributi comuni. + +### Sintesi + +In questa sezione, avete imparato: + +- **Distribuire campioni su intervalli**: Come usare `combine` per ripetere campioni su intervalli +- **Creare prodotti Cartesiani**: Come generare tutte le combinazioni di campioni e intervalli +- **Organizzare la struttura del canale**: Come usare `map` per ristrutturare i dati per una migliore leggibilità +- **Preparazione all'elaborazione parallela**: Come impostare i dati per l'analisi distribuita + +## 5. Aggregare campioni usando `groupTuple` + +Nelle sezioni precedenti, abbiamo imparato come dividere i dati da un file di input e filtrare per campi specifici (nel nostro caso campioni normali e tumorali). Ma questo copre solo un singolo tipo di unione. Cosa succede se vogliamo raggruppare campioni per un attributo specifico? Ad esempio, invece di unire coppie tumore-normale abbinate, potremmo voler processare tutti i campioni da "sampleA" insieme indipendentemente dal loro tipo. Questo pattern è comune nei workflow di bioinformatica dove potreste voler processare campioni correlati separatamente per ragioni di efficienza prima di confrontare o combinare i risultati alla fine. + +Nextflow include metodi integrati per fare questo, il principale che vedremo è `groupTuple`. + +Iniziamo raggruppando tutti i nostri campioni che hanno gli stessi campi `id` e `interval`, questo sarebbe tipico di un'analisi dove vogliamo raggruppare repliche tecniche ma mantenere campioni significativamente diversi separati. + +Per farlo, dovremmo separare le nostre variabili di raggruppamento così possiamo usarle in isolamento. + +Il primo passo è simile a quello che abbiamo fatto nella sezione precedente. Dobbiamo isolare la nostra variabile di raggruppamento come primo elemento della tupla. Ricordate, il nostro primo elemento è attualmente una map dei campi `id`, `repeat` e `interval`: + +```groovy title="main.nf" linenums="1" +{ + "id": "sampleA", + "repeat": "1", + "interval": "chr1" +} +``` + +Possiamo riutilizzare il metodo `subMap` da prima per isolare i nostri campi `id` e `interval` dalla map. Come prima, useremo l'operatore `map` per applicare il metodo `subMap` al primo elemento della tupla per ciascun campione. + +=== "Dopo" + + ```groovy title="main.nf" linenums="20" hl_lines="11-19" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="20" hl_lines="10" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +Eseguiamolo di nuovo e controlliamo i contenuti del canale: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [hop diff --git a/docs/it/docs/side_quests/workflows_of_workflows.md b/docs/it/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..1770fc878b --- /dev/null +++ b/docs/it/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Workflows di Workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Quando si sviluppa una pipeline, ci si ritrova spesso a creare sequenze simili di processi per diversi tipi di dati o fasi di analisi. Si potrebbe finire per copiare e incollare queste sequenze di processi, con conseguente duplicazione del codice difficile da mantenere; oppure si potrebbe creare un unico workflow massiccio difficile da comprendere e modificare. + +Una delle funzionalità più potenti di Nextflow è la sua capacità di comporre pipeline complesse da moduli workflow più piccoli e riutilizzabili. Questo approccio modulare rende le pipeline più facili da sviluppare, testare e mantenere. + +### Obiettivi di apprendimento + +In questa missione secondaria, esploreremo come sviluppare moduli workflow che possono essere testati e utilizzati separatamente, comporre questi moduli in una pipeline più grande e gestire il flusso di dati tra moduli. + +Al termine di questa missione secondaria, sarete in grado di: + +- Suddividere pipeline complesse in unità logiche e riutilizzabili +- Testare ogni modulo workflow in modo indipendente +- Combinare e abbinare workflows per creare nuove pipeline +- Condividere moduli workflow comuni tra diverse pipeline +- Rendere il codice più manutenibile e più facile da comprendere + +Queste competenze vi aiuteranno a costruire pipeline complesse mantenendo una struttura del codice pulita e manutenibile. + +### Prerequisiti + +Prima di affrontare questa missione secondaria dovreste: + +- Aver completato il tutorial [Hello Nextflow](../hello_nextflow/README.md) o un corso per principianti equivalente. +- Essere a proprio agio con l'utilizzo di concetti e meccanismi di base di Nextflow (processi, canali, operatori, moduli) + +--- + +## 0. Iniziare + +#### Aprire il codespace di formazione + +Se non lo avete ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione dell'Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/workflows_of_workflows +``` + +Potete impostare VSCode per focalizzarsi su questa directory: + +```bash +code . +``` + +#### Esaminare i materiali + +Troverete una directory `modules` contenente diverse definizioni di processi che si basano su quanto appreso in 'Hello Nextflow': + +```console title="Contenuto della directory" +modules/ +├── say_hello.nf # Crea un saluto (da Hello Nextflow) +├── say_hello_upper.nf # Converte in maiuscolo (da Hello Nextflow) +├── timestamp_greeting.nf # Aggiunge timestamp ai saluti +├── validate_name.nf # Valida i nomi di input +└── reverse_text.nf # Inverte il contenuto del testo +``` + +#### Esaminare l'assegnazione + +La vostra sfida è assemblare questi moduli in due workflows separati che poi comporremo in un workflow principale: + +- Un `GREETING_WORKFLOW` che valida i nomi, crea i saluti e aggiunge timestamp +- Un `TRANSFORM_WORKFLOW` che converte il testo in maiuscolo e lo inverte + +#### Lista di controllo della preparazione + +Pensate di essere pronti ad iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro appropriatamente +- [ ] Comprendo l'assegnazione + +Se potete spuntare tutte le caselle, siete pronti per iniziare. + +--- + +## 1. Creare il Greeting Workflow + +Iniziamo creando un workflow che valida i nomi e genera saluti con timestamp. + +### 1.1. Creare la struttura del workflow + +```bash title="Creare la directory e il file del workflow" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Aggiungere il codice del primo (sub)workflow + +Aggiungete questo codice a `workflows/greeting.nf`: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Concatenare i processi: validate -> create greeting -> add timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Questo è un workflow completo, con una struttura simile a quelli visti nel tutorial 'Hello Nextflow', che possiamo testare in modo indipendente. Proviamolo ora: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Funziona come previsto, ma per renderlo componibile ci sono alcune cose che dobbiamo modificare. + +### 1.3. Rendere il workflow componibile + +I workflows componibili presentano alcune differenze rispetto a quelli visti nel tutorial 'Hello Nextflow': + +- Il blocco workflow deve essere nominato +- Gli input sono dichiarati utilizzando la parola chiave `take:` +- Il contenuto del workflow è posto all'interno del blocco `main:` +- Gli output sono dichiarati utilizzando la parola chiave `emit:` + +Aggiorniamo il greeting workflow per corrispondere a questa struttura. Modificate il codice nel seguente modo: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Canale di input con i nomi + + main: + // Concatenare i processi: validate -> create greeting -> add timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Saluti originali + timestamped = timestamped_ch // Saluti con timestamp +} +``` + +Potete vedere che il workflow è ora nominato e ha un blocco `take:` e `emit:`, e queste sono le connessioni che useremo per comporre un workflow di livello superiore. +Il contenuto del workflow è anche posto all'interno del blocco `main:`. Notate inoltre che abbiamo rimosso la dichiarazione del canale di input `names_ch`, poiché ora viene passato come argomento al workflow. + +Testiamo di nuovo il workflow per vedere se funziona come previsto: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Questo vi informa di un altro nuovo concetto, un 'entry workflow'. L'entry workflow è il workflow che viene chiamato quando si esegue uno script Nextflow. Per impostazione predefinita, Nextflow utilizzerà un workflow senza nome come entry workflow, quando presente, ed è ciò che avete fatto finora, con blocchi workflow che iniziano così: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Ma il nostro greeting workflow non ha un workflow senza nome, piuttosto abbiamo un workflow nominato: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +Ecco perché Nextflow ha generato un errore e non ha fatto ciò che volevamo. + +Non abbiamo aggiunto la sintassi `take:`/`emit:` per poter chiamare direttamente il workflow - l'abbiamo fatto per poterlo comporre con altri workflows. La soluzione è creare uno script principale con un entry workflow senza nome che importa e chiama il nostro workflow nominato. + +### 1.4. Creare e testare il workflow principale + +Ora creeremo un workflow principale che importa e utilizza il workflow `greeting`. + +Create `main.nf`: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Notate che la voce workflow in questo file è senza nome, e questo perché la useremo come entry workflow. + +Eseguite questo e osservate l'output: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Funziona! Abbiamo racchiuso il greeting workflow nominato in un workflow principale con un blocco `workflow` di ingresso senza nome. Il workflow principale sta utilizzando il workflow `GREETING_WORKFLOW` quasi (non proprio) come un processo, e sta passando il canale `names` come argomento. + +### Conclusioni + +In questa sezione, avete appreso diversi concetti importanti: + +- **Workflows Nominati**: Creare un workflow nominato (`GREETING_WORKFLOW`) che può essere importato e riutilizzato +- **Interfacce di Workflow**: Definire input chiari con `take:` e output con `emit:` per creare un workflow componibile +- **Punti di Ingresso**: Comprendere che Nextflow necessita di un entry workflow senza nome per eseguire uno script +- **Composizione di Workflow**: Importare e utilizzare un workflow nominato all'interno di un altro workflow +- **Namespace di Workflow**: Accedere agli output del workflow utilizzando il namespace `.out` (`GREETING_WORKFLOW.out.greetings`) + +Ora avete un greeting workflow funzionante che: + +- Prende un canale di nomi come input +- Valida ogni nome +- Crea un saluto per ogni nome valido +- Aggiunge timestamp ai saluti +- Espone sia i saluti originali che quelli con timestamp come output + +Questo approccio modulare vi consente di testare il greeting workflow in modo indipendente o di utilizzarlo come componente in pipeline più grandi. + +--- + +## 2. Aggiungere il Transform Workflow + +Ora creiamo un workflow che applica trasformazioni di testo ai saluti. + +### 2.1. Creare il file del workflow + +```bash +touch workflows/transform.nf +``` + +### 2.2. Aggiungere il codice del workflow + +Aggiungete questo codice a `workflows/transform.nf`: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Canale di input con i messaggi + + main: + // Applicare le trasformazioni in sequenza + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Saluti in maiuscolo + reversed = reversed_ch // Saluti in maiuscolo invertiti +} +``` + +Non ripeteremo qui la spiegazione della sintassi componibile, ma notate che il workflow nominato è nuovamente dichiarato con un blocco `take:` e `emit:`, e il contenuto del workflow è posto all'interno del blocco `main:`. + +### 2.3. Aggiornare il workflow principale + +Aggiornate `main.nf` per utilizzare entrambi i workflows: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Eseguire il greeting workflow + GREETING_WORKFLOW(names) + + // Eseguire il transform workflow + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Visualizzare i risultati + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Eseguite la pipeline completa: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Se date un'occhiata a uno di quei file invertiti, vedrete che è la versione in maiuscolo del saluto invertita: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Contenuto del file invertito" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Conclusioni + +Ora dovreste avere una pipeline completa che: + +- Elabora i nomi attraverso il greeting workflow +- Invia i saluti con timestamp al transform workflow +- Produce sia versioni in maiuscolo che invertite dei saluti + +--- + +## Riepilogo + +In questa missione secondaria, abbiamo esplorato il potente concetto di composizione di workflow in Nextflow, che ci consente di costruire pipeline complesse da componenti più piccoli e riutilizzabili. + +Questo approccio modulare offre diversi vantaggi rispetto alle pipeline monolitiche: + +- Ogni workflow può essere sviluppato, testato e sottoposto a debug in modo indipendente +- I workflows possono essere riutilizzati in diverse pipeline +- La struttura complessiva della pipeline diventa più leggibile e manutenibile +- Le modifiche a un workflow non influenzano necessariamente gli altri se le interfacce rimangono coerenti +- I punti di ingresso possono essere configurati per eseguire diverse parti della pipeline secondo necessità + +_È importante notare tuttavia che, sebbene chiamare i workflows sia un po' come chiamare i processi, non è effettivamente la stessa cosa. Non è possibile, ad esempio, eseguire un workflow N volte chiamandolo con un canale di dimensione N - sarebbe necessario passare un canale di dimensione N al workflow e iterare internamente._ + +L'applicazione di queste tecniche nel vostro lavoro vi consentirà di costruire pipeline Nextflow più sofisticate in grado di gestire attività bioinformatiche complesse rimanendo manutenibili e scalabili. + +### Modelli chiave + +1. **Struttura del workflow**: Abbiamo definito input e output chiari per ogni workflow utilizzando la sintassi `take:` e `emit:`, creando interfacce ben definite tra i componenti, e racchiuso la logica del workflow all'interno del blocco `main:`. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // I canali di input sono dichiarati qui + input_ch + + main: + // La logica del workflow va qui + // Qui è dove i processi vengono chiamati e i canali vengono manipolati + result_ch = SOME_PROCESS(input_ch) + + emit: + // I canali di output sono dichiarati qui + output_ch = result_ch + } + ``` + +2. **Importazioni di workflow:** Abbiamo costruito due moduli workflow indipendenti e li abbiamo importati in una pipeline principale con istruzioni include. + + - Includere un singolo workflow + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Includere più workflows + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Includere con alias per evitare conflitti di nomi + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Punti di ingresso**: Nextflow richiede un entry workflow senza nome per sapere da dove iniziare l'esecuzione. Questo entry workflow chiama i vostri workflows nominati. + + - Workflow senza nome (punto di ingresso) + + ```groovy + workflow { + // Questo è il punto di ingresso quando lo script viene eseguito + NAMED_WORKFLOW(input_ch) + } + ``` + + - Workflow nominato (chiamato dall'entry workflow) + + ```groovy + workflow NAMED_WORKFLOW { + // Deve essere chiamato dall'entry workflow + } + ``` + +4. **Gestione del flusso di dati:** Abbiamo imparato come accedere agli output del workflow utilizzando la notazione namespace (`WORKFLOW_NAME.out.channel_name`) e passarli ad altri workflows. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Risorse aggiuntive + +- [Documentazione Nextflow Workflow](https://www.nextflow.io/docs/latest/workflow.html) +- [Riferimento Channel Operators](https://www.nextflow.io/docs/latest/operator.html) +- [Documentazione Error Strategy](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## Cosa c'è dopo? + +Tornate al [menu delle Missioni Secondarie](./index.md) o cliccate il pulsante in basso a destra della pagina per passare all'argomento successivo nell'elenco. diff --git a/docs/it/docs/side_quests/working_with_files.md b/docs/it/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..f6a7e104d0 --- /dev/null +++ b/docs/it/docs/side_quests/working_with_files.md @@ -0,0 +1,1297 @@ +# Elaborazione di file in input + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +I workflow di analisi scientifica spesso comportano l'elaborazione di un gran numero di file. +Nextflow fornisce strumenti potenti per gestire i file in modo efficiente, aiutandola ad organizzare ed elaborare i suoi dati con codice minimo. + +### Obiettivi di apprendimento + +In questa side quest, esploreremo come Nextflow gestisce i file, dalle operazioni di base a tecniche più avanzate per lavorare con collezioni di file. +Imparerà ad estrarre metadati dai nomi dei file, che è un requisito comune nei pipeline di analisi scientifica. + +Al termine di questa side quest, sarà in grado di: + +- Creare oggetti Path da stringhe di percorsi file utilizzando il metodo `file()` di Nextflow +- Accedere agli attributi dei file come nome, estensione e directory principale +- Gestire trasparentemente sia file locali che remoti utilizzando URI +- Utilizzare i canali per automatizzare la gestione dei file con `channel.fromPath()` e `channel.fromFilePairs()` +- Estrarre e strutturare metadati dai nomi dei file utilizzando la manipolazione di stringhe +- Raggruppare file correlati utilizzando pattern matching ed espressioni glob +- Integrare le operazioni sui file nei processi Nextflow con una gestione appropriata degli input +- Organizzare gli output dei processi utilizzando strutture di directory basate sui metadati + +Queste competenze la aiuteranno a costruire workflow che possono gestire diversi tipi di input di file con grande flessibilità. + +### Prerequisiti + +Prima di intraprendere questa side quest, dovrebbe: + +- Aver completato il tutorial [Hello Nextflow](../../hello_nextflow/) o un corso equivalente per principianti. +- Essere a suo agio nell'utilizzo di concetti e meccanismi base di Nextflow (processi, canali, operatori) + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. Iniziare + +#### Aprire il codespace per la formazione + +Se non l'ha ancora fatto, assicuratevi di aprire l'ambiente di formazione come descritto in [Configurazione dell'Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Spostarsi nella directory del progetto + +Spostiamoci nella directory dove si trovano i file per questo tutorial. + +```bash +cd side-quests/working_with_files +``` + +Può configurare VSCode per focalizzarsi su questa directory: + +```bash +code . +``` + +#### Esaminare i materiali + +Troverà un semplice file di workflow chiamato `main.nf`, una directory `modules` contenente due file modulo, e una directory `data` contenente alcuni file di dati di esempio. + +??? abstract "Contenuti della directory" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Questa directory contiene dati di sequenziamento paired-end da tre pazienti (A, B, C). + +Per ciascun paziente, abbiamo campioni di tipo `tumor` (tipicamente provenienti da biopsie tumorali) o `normal` (prelevati da tessuto sano o sangue). +Se non ha familiarità con l'analisi oncologica, sappia semplicemente che questo corrisponde ad un modello sperimentale che utilizza campioni tumore/normale appaiati per eseguire analisi contrastive. + +Per il paziente A in particolare, abbiamo due set di repliche tecniche (ripetizioni). + +I file di dati di sequenziamento sono denominati con una convenzione tipica `_R1_` e `_R2_` per quelli che sono conosciuti come 'forward reads' e 'reverse reads'. + +_Non si preoccupi se non ha familiarità con questo disegno sperimentale, non è critico per comprendere questo tutorial._ + +#### Esaminare l'incarico + +La sua sfida è scrivere un workflow Nextflow che: + +1. **Carichi** i file di input utilizzando i metodi di gestione file di Nextflow +2. **Estragga** i metadati (ID paziente, replica, tipo di campione) dalla struttura del nome del file +3. **Raggruppi** i file appaiati (R1/R2) insieme utilizzando `channel.fromFilePairs()` +4. **Elabori** i file con un modulo di analisi fornito +5. **Organizzi** gli output in una struttura di directory basata sui metadati estratti + +#### Checklist di preparazione + +Pensa di essere pronto per iniziare? + +- [ ] Comprendo l'obiettivo di questo corso e i suoi prerequisiti +- [ ] Il mio codespace è attivo e funzionante +- [ ] Ho impostato la mia directory di lavoro in modo appropriato +- [ ] Comprendo l'incarico + +Se può spuntare tutte le caselle, è pronto per iniziare. + +--- + +## 1. Operazioni di base sui file + +### 1.1. Identificare il tipo di un oggetto con `.class` + +Dia un'occhiata al file workflow `main.nf`: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +Questo è un mini-workflow (senza processi) che fa riferimento ad un singolo percorso di file nel suo workflow, poi lo stampa sulla console, insieme alla sua classe. + +??? info "Cos'è `.class`?" + + In Nextflow, `.class` ci dice che tipo di oggetto stiamo utilizzando. È come chiedere "che tipo di cosa è questa?" per scoprire se è una stringa, un numero, un file, o qualcos'altro. + Questo ci aiuterà ad illustrare la differenza tra una semplice stringa e un oggetto Path nelle prossime sezioni. + +Eseguiamo il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Come potete vedere, Nextflow ha stampato il percorso stringa esattamente come l'abbiamo scritto. + +Questo è solo output di testo; Nextflow non ha ancora fatto nulla di speciale con esso. +Abbiamo anche confermato che per quanto riguarda Nextflow, questa è solo una stringa (di classe `java.lang.String`). +Ha senso, dal momento che non abbiamo ancora detto a Nextflow che corrisponde ad un file. + +### 1.2. Creare un oggetto Path con file() + +Possiamo dire a Nextflow come gestire i file creando [oggetti Path](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) da stringhe di percorsi. + +Nel nostro workflow, possiamo convertire il percorso stringa `data/patientA_rep1_normal_R1_001.fastq.gz` in un oggetto Path utilizzando il metodo `file()`, che fornisce accesso alle proprietà e operazioni sui file. + +Modifichi `main.nf` per avvolgere la stringa con `file()` come segue: + +=== "Dopo" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Ora eseguite nuovamente il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Questa volta, vede il percorso assoluto completo invece del percorso relativo che abbiamo fornito come input. + +Nextflow ha convertito la nostra stringa in un oggetto Path e l'ha risolto nella posizione effettiva del file sul sistema. +Il percorso del file sarà ora assoluto, come in `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Noti anche che la classe dell'oggetto Path è `sun.nio.fs.UnixPath`: questo è il modo di Nextflow di rappresentare i file locali. +Come vedremo più avanti, i file remoti avranno nomi di classi diversi (come `nextflow.file.http.XPath` per i file HTTP), ma funzionano tutti esattamente allo stesso modo e possono essere utilizzati in modo identico nei suoi workflow. + +!!! tip + + **La differenza chiave:** + + - **Stringa di percorso**: Solo testo che Nextflow tratta come caratteri + - **Oggetto Path**: Un riferimento intelligente al file con cui Nextflow può lavorare + + Pensate a questo: una stringa di percorso è come scrivere un indirizzo su carta, mentre un oggetto Path è come avere l'indirizzo caricato in un dispositivo GPS che sa come navigare lì e può dirle dettagli sul viaggio. + +### 1.3. Accedere agli attributi del file + +Perché questo è utile? Beh, ora che Nextflow comprende che `myFile` è un oggetto Path e non solo una stringa, possiamo accedere ai vari attributi dell'oggetto Path. + +Aggiorniamo il nostro workflow per stampare gli attributi file integrati: + +=== "Dopo" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Esegua il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Vede i vari attributi del file stampati sulla console sopra. + +### 1.4. Fornire il file ad un processo + +La differenza tra stringhe e oggetti Path diventa critica quando si inizia a costruire workflow effettivi con processi. +Finora abbiamo verificato che Nextflow sta ora trattando il nostro file di input come un file, ma vediamo se possiamo effettivamente eseguire qualcosa su quel file in un processo. + +#### 1.4.1. Importare il processo ed esaminare il codice + +Le forniamo un modulo processo pre-scritto chiamato `COUNT_LINES` che prende un input file e conta quante righe contiene. + +Per utilizzare il processo nel workflow, deve solo aggiungere un'istruzione include prima del blocco workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Può aprire il file modulo per esaminarne il codice: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Come potete vedere, è uno script abbastanza semplice che decomprime il file e conta quante righe contiene. + +??? info "Cosa fa `debug true`?" + + La direttiva `debug true` nella definizione del processo fa sì che Nextflow stampi l'output dal suo script (come il conteggio righe "40") direttamente nel log di esecuzione. + Senza questo, vedrebbe solo lo stato di esecuzione del processo ma non l'output effettivo dal suo script. + + Per maggiori informazioni sul debugging dei workflow Nextflow, consulti la side quest [Debugging Nextflow Workflows](debugging.md). + +#### 1.4.2. Aggiungere una chiamata a `COUNT_LINES` + +Ora che il processo è disponibile per il workflow, possiamo aggiungere una chiamata al processo `COUNT_LINES` per eseguirlo sul file di input. + +Effettui le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +E ora eseguite il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Questo mostra che siamo in grado di operare sul file in modo appropriato all'interno di un processo. + +Nello specifico, Nextflow ha eseguito con successo le seguenti operazioni: + +- Preparato il file nella directory di lavoro +- Decompresso il file .gz +- Contato le righe (40 righe in questo caso) +- Completato senza errori + +La chiave di questa operazione senza intoppi è che stiamo esplicitamente dicendo a Nextflow che il nostro input è un file e dovrebbe essere trattato come tale. + +### 1.5. Risolvere errori base di input file + +Questo spesso fa inciampare i nuovi utenti di Nextflow, quindi dedichiamo qualche minuto a vedere cosa succede quando lo si fa in modo errato. + +Ci sono due posti principali dove si può sbagliare la gestione dei file: a livello del workflow e a livello del processo. + +#### 1.5.1. Errore a livello di workflow + +Vediamo cosa succede se torniamo a trattare il file come una stringa quando specifichiamo l'input nel blocco workflow. + +Effettui le seguenti modifiche al workflow, assicurandosi di commentare le istruzioni di stampa specifiche per i percorsi: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Create a Path object from a string path + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Print file attributes + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +E ora eseguite il workflow: + +```bash +nextflow run main.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Questa è la parte importante: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Quando specifica un input `path`, Nextflow valida che stia passando effettivi riferimenti a file, non solo stringhe. +Questo errore le sta dicendo che `'data/patientA_rep1_normal_R1_001.fastq.gz'` non è un valore di percorso valido perché è una stringa, non un oggetto Path. + +Nextflow ha immediatamente rilevato il problema e si è fermato prima ancora di avviare il processo. + +#### 1.5.2. Errore a livello di processo + +L'altro posto dove potremmo dimenticare di specificare che vogliamo che Nextflow tratti l'input come un file è nella definizione del processo. + +!!! warning "Mantenga l'errore del workflow da 1.5.1" + + Affinché questo test funzioni correttamente, mantenga il workflow nel suo stato errato (usando una semplice stringa invece di `file()`). + Quando combinato con `val` nel processo, questo produce l'errore mostrato sotto. + +Effettui la seguente modifica al modulo: + +=== "Dopo" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Prima" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +E ora eseguite nuovamente il workflow: + +```bash +nextflow run main.nf +``` + +??? failure "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Questo mostra molti dettagli sull'errore perché il processo è impostato per produrre informazioni di debugging, come notato sopra. + +Queste sono le sezioni più rilevanti: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Questo dice che il sistema non ha potuto trovare il file; tuttavia se cerca il percorso, c'è un file con quel nome in quella posizione. + +Quando abbiamo eseguito questo, Nextflow ha passato il valore stringa allo script, ma non ha _preparato_ il file effettivo nella directory di lavoro. +Quindi il processo ha provato ad utilizzare la stringa relativa, `data/patientA_rep1_normal_R1_001.fastq.gz`, ma quel file non esiste all'interno della directory di lavoro del processo. + +Presi insieme, questi due esempi le mostrano quanto sia importante dire a Nextflow se un input dovrebbe essere gestito come un file. + +!!! note + + Assicuratevi di tornare indietro e correggere entrambi gli errori intenzionali prima di continuare alla sezione successiva. + +### Conclusioni + +- Stringhe di percorso vs oggetti Path: Le stringhe sono solo testo, gli oggetti Path sono riferimenti intelligenti a file +- Il metodo `file()` converte un percorso stringa in un oggetto Path con cui Nextflow può lavorare +- È possibile accedere alle proprietà dei file come `name`, `simpleName`, `extension` e `parent` [utilizzando gli attributi file](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) +- Utilizzare oggetti Path invece di stringhe consente a Nextflow di gestire correttamente i file nel suo workflow +- Risultati Input Processo: Una corretta gestione dei file richiede oggetti Path, non stringhe, per garantire che i file siano correttamente preparati e accessibili per l'uso da parte dei processi. + +--- + +## 2. Utilizzo di file remoti + +Una delle caratteristiche chiave di Nextflow è la capacità di passare senza problemi tra file locali (sulla stessa macchina) e file remoti accessibili via internet. + +Se lo fa correttamente, non dovrebbe mai aver bisogno di cambiare la logica del suo workflow per accogliere file provenienti da diverse posizioni. +Tutto ciò che deve fare per usare un file remoto è specificare il prefisso appropriato nel percorso del file quando lo fornisce al workflow. + +Ad esempio, `/path/to/data` non ha prefisso, indicando che è un percorso file locale 'normale', mentre `s3://path/to/data` include il prefisso `s3://`, indicando che si trova nell'object storage S3 di Amazon. + +Sono supportati molti protocolli diversi: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Per utilizzare uno qualsiasi di questi, specifichi semplicemente il prefisso rilevante nella stringa, che è poi tecnicamente chiamata Uniform Resource Identifier (URI) invece di percorso file. +Nextflow gestirà l'autenticazione e la preparazione dei file nel posto giusto, scaricando o caricando e tutte le altre operazioni sui file che ci si aspetterebbe. + +La forza chiave di questo sistema è che ci consente di passare tra ambienti senza cambiare alcuna logica del pipeline. +Ad esempio, può sviluppare con un piccolo set di test locale prima di passare ad un set di test su larga scala situato in storage remoto semplicemente cambiando l'URI. + +### 2.1. Utilizzare un file da internet + +Testiamo questo sostituendo il percorso locale che stiamo fornendo al nostro workflow con un percorso HTTPS che punta ad una copia degli stessi dati memorizzata in Github. + +!!! warning + + Questo funzionerà solo se avete una connessione internet attiva. + +Apra `main.nf` di nuovo e cambi il percorso input come segue: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Using a remote file from the internet + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Eseguiamo il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Funziona! Può vedere che è cambiato molto poco. + +L'unica differenza nell'output della console è che la classe dell'oggetto percorso è ora `nextflow.file.http.XPath`, mentre per il percorso locale la classe era `sun.nio.fs.UnixPath`. +Non ha bisogno di ricordare queste classi; menzioniamo solo questo per dimostrare che Nextflow identifica e gestisce in modo appropriato le diverse posizioni. + +Dietro le quinte, Nextflow ha scaricato il file in una directory di staging situata all'interno della directory di lavoro. +Quel file preparato può quindi essere trattato come un file locale e collegato simbolicamente nella directory del processo rilevante. + +Può verificare che ciò sia accaduto qui guardando i contenuti della directory di lavoro situata al valore hash del processo. + +??? abstract "Contenuti della directory di lavoro" + + Se l'hash del processo era `8a/2ab7ca`, potrebbe esplorare la directory di lavoro: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Il link simbolico punta ad una copia preparata del file remoto che Nextflow ha scaricato automaticamente. + +Noti che per file più grandi, il passaggio di download richiederà tempo extra rispetto all'esecuzione su file locali. +Tuttavia, Nextflow verifica se avete già una copia preparata per evitare download non necessari. +Quindi se esegue nuovamente sullo stesso file e non ha eliminato il file preparato, Nextflow utilizzerà la copia preparata. + +Questo mostra quanto sia facile passare tra dati locali e remoti usando Nextflow, che è una caratteristica chiave di Nextflow. + +!!! note + + L'unica importante eccezione a questo principio è che non potete utilizzare pattern glob o percorsi di directory con HTTPS perché HTTPS non può elencare più file, quindi deve specificare URL esatti di file. + Tuttavia, altri protocolli di storage come blob storage (`s3://`, `az://`, `gs://`) possono utilizzare sia glob che percorsi di directory. + + Ecco come potrebbe utilizzare pattern glob con cloud storage: + + ```groovy title="Esempi di cloud storage (non eseguibili in questo ambiente)" + // S3 con pattern glob - corrisponderebbe a più file + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage con pattern glob + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage con pattern glob + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Le mostreremo come lavorare con i glob in pratica nella prossima sezione. + +### 2.2. Tornare al file locale + +Torneremo ad utilizzare i nostri file di esempio locali per il resto di questa side quest, quindi cambiamo l'input del workflow tornando al file originale: + +=== "Dopo" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Create a Path object from a string path + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Conclusioni + +- L'accesso ai dati remoti avviene utilizzando un URI (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow scaricherà e preparerà automaticamente i dati nel posto giusto, purché questi percorsi vengano forniti ai processi +- Non scriva logica per scaricare o caricare file remoti! +- I file locali e remoti producono tipi di oggetti diversi ma funzionano in modo identico +- **Importante**: HTTP/HTTPS funzionano solo con singoli file (nessun pattern glob) +- Il cloud storage (S3, Azure, GCS) supporta sia singoli file che pattern glob +- Può passare senza problemi tra sorgenti di dati locali e remote senza cambiare la logica del codice (purché il protocollo supporti le operazioni richieste) + +--- + +## 3. Utilizzo del channel factory `fromPath()` + +Finora abbiamo lavorato con un singolo file alla volta, ma in Nextflow, tipicamente vorremo creare un canale di input con più file di input da elaborare. + +Un modo ingenuo per farlo sarebbe combinare il metodo `file()` con [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) così: + +```groovy title="Esempio di sintassi" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Funziona, ma è goffo. + +!!! tip "Quando usare `file()` vs `channel.fromPath()`" + + - Usi `file()` quando ha bisogno di un singolo oggetto Path per manipolazione diretta (controllare se un file esiste, leggere i suoi attributi, o passarlo ad una singola invocazione di processo) + - Usi `channel.fromPath()` quando ha bisogno di un canale che può contenere più file, specialmente con pattern glob, o quando i file fluiranno attraverso più processi + +È qui che entra in gioco [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath): un comodo channel factory che raggruppa tutta la funzionalità di cui abbiamo bisogno per generare un canale da una o più stringhe di file statici così come pattern glob. + +### 3.1. Aggiungere il channel factory + +Aggiorniamo il nostro workflow per usare `channel.fromPath`. + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Print file attributes + /* Comment these out for now, we'll come back to them! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Count the lines in the file + // COUNT_LINES(myFile) + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Create a Path object from a string path + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Print file attributes + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Count the lines in the file + COUNT_LINES(myFile) + ``` + +Abbiamo anche commentato il codice che stampa gli attributi per ora, e aggiunto un'istruzione `.view` per stampare solo il nome del file. + +Esegua il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Come potete vedere, il percorso del file viene caricato come un oggetto di tipo `Path` nel canale. +Questo è simile a quello che avrebbe fatto `file()`, eccetto che ora abbiamo un canale in cui possiamo caricare più file se vogliamo. + +Usare `channel.fromPath()` è un modo conveniente di creare un nuovo canale popolato da una lista di file. + +### 3.2. Visualizzare gli attributi dei file nel canale + +Nel nostro primo tentativo di utilizzare il channel factory, abbiamo semplificato il codice e stampato solo il nome del file. + +Torniamo a stampare gli attributi completi del file: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Count the lines in the file + COUNT_LINES(ch_files) + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Count the lines in the file + // COUNT_LINES(ch_files) + ``` + +Stiamo anche riabilitando la chiamata al processo `COUNT_LINES` per verificare che l'elaborazione dei file funzioni ancora correttamente con il nostro approccio basato sui canali. + +Esegua il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ed eccolo, stessi risultati di prima ma ora abbiamo il file in un canale, quindi possiamo aggiungerne altri. + +### 3.3. Utilizzare un glob per corrispondere a più file + +Ci sono diversi modi in cui potremmo caricare più file nel canale. +Qui le mostreremo come utilizzare i pattern glob, che sono un modo conveniente per corrispondere e recuperare nomi di file e directory basati su caratteri jolly. +Il processo di corrispondenza di questi pattern è chiamato "globbing" o "espansione del nome file". + +!!! note + + Come notato precedentemente, Nextflow supporta il globbing per gestire file di input e output nella maggior parte dei casi, eccetto con i percorsi file HTTPS perché HTTPS non può elencare più file. + +Diciamo che vogliamo recuperare entrambi i file in una coppia di file associati ad un dato paziente, `patientA`: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Poiché l'unica differenza tra i nomi dei file è il numero della replica, _ovvero_ il numero dopo `R`, possiamo usare il carattere jolly `*` per rappresentare il numero come segue: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +Questo è il pattern glob di cui abbiamo bisogno. + +Ora tutto ciò che dobbiamo fare è aggiornare il percorso del file nel channel factory per utilizzare quel pattern glob come segue: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow riconoscerà automaticamente che questo è un pattern glob e lo gestirà in modo appropriato. + +Esegua il workflow per testarlo: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Come potete vedere, ora abbiamo due oggetti Path nel nostro canale, il che mostra che Nextflow ha fatto correttamente l'espansione del nome file, e ha caricato ed elaborato entrambi i file come previsto. + +Utilizzando questo metodo, possiamo recuperare quanti file vogliamo semplicemente cambiando il pattern glob. Se lo rendessimo più generoso, ad esempio sostituendo tutte le parti variabili dei nomi file con `*` (_ad es._ `data/patient*_rep*_*_R*_001.fastq.gz`) potremmo prendere tutti i file di esempio nella directory `data`. + +### Conclusioni + +- `channel.fromPath()` crea un canale con file che corrispondono ad un pattern +- Ogni file viene emesso come elemento separato nel canale +- Possiamo usare un pattern glob per corrispondere a più file +- I file vengono automaticamente convertiti in oggetti Path con attributi completi +- Il metodo `.view()` consente l'ispezione dei contenuti del canale + +--- + +## 4. Estrazione di metadati di base dai nomi dei file + +Nella maggior parte dei domini scientifici, è molto comune avere metadati codificati nei nomi dei file che contengono i dati. +Ad esempio, in bioinformatica, i file contenenti dati di sequenziamento sono spesso denominati in modo da codificare informazioni sul campione, condizione, replica e numero di lettura. + +Se i nomi dei file sono costruiti secondo una convenzione consistente, può estrarre quei metadati in modo standardizzato e utilizzarli nel corso della sua analisi. +Questo è un grande 'se', ovviamente, e dovrebbe essere molto cauto ogni volta che si basa sulla struttura del nome del file; ma la realtà è che questo approccio è molto ampiamente utilizzato, quindi diamo un'occhiata a come si fa in Nextflow. + +Nel caso dei nostri dati di esempio, sappiamo che i nomi dei file includono metadati strutturati in modo consistente. +Ad esempio, il nome del file `patientA_rep1_normal_R2_001` codifica quanto segue: + +- ID paziente: `patientA` +- ID replica: `rep1` +- tipo di campione: `normal` (in contrapposizione a `tumor`) +- set di letture: `R1` (in contrapposizione a `R2`) + +Modificheremo il nostro workflow per recuperare queste informazioni in tre passaggi: + +1. Recuperare il `simpleName` del file, che include i metadati +2. Separare i metadati usando un metodo chiamato `tokenize()` +3. Utilizzare una map per organizzare i metadati + +!!! warning + + Non dovrebbe mai codificare informazioni sensibili nei nomi dei file, come nomi di pazienti o altre caratteristiche identificative, poiché ciò può compromettere la privacy dei pazienti o altre restrizioni di sicurezza rilevanti. + +### 4.1. Recuperare il `simpleName` + +Il `simpleName` è un attributo file che corrisponde al nome del file privato del suo percorso e dell'estensione. + +Effettui le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +Questo recupera il `simpleName` e lo associa all'oggetto file completo usando un'operazione `map()`. + +Esegua il workflow per verificare che funzioni: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Ogni elemento nel canale è ora una tupla contenente il `simpleName` e l'oggetto file originale. + +### 4.2. Estrarre i metadati dal `simplename` + +A questo punto, i metadati che vogliamo sono incorporati nel `simplename`, ma non possiamo accedere direttamente ai singoli elementi. +Quindi dobbiamo dividere il `simplename` nelle sue componenti. +Fortunatamente, quelle componenti sono semplicemente separate da underscore nel nome file originale, quindi possiamo applicare un metodo comune di Nextflow chiamato `tokenize()` che è perfetto per questo compito. + +Effettui le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +Il metodo `tokenize()` dividerà la stringa `simpleName` ovunque trovi underscore, e restituirà una lista contenente le sottostringhe. + +Esegua il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ora la tupla per ogni elemento nel nostro canale contiene la lista di metadati (_ad es._ `[patientA, rep1, normal, R1, 001]`) e l'oggetto file originale. + +Fantastico! +Abbiamo suddiviso le nostre informazioni sul paziente da una singola stringa in una lista di stringhe. +Possiamo ora gestire ogni parte delle informazioni sul paziente separatamente. + +### 4.3. Utilizzare una map per organizzare i metadati + +I nostri metadati sono solo una lista piatta al momento. +È abbastanza facile da usare ma difficile da leggere. + +```console +[patientA, rep1, normal, R1, 001] +``` + +Qual è l'elemento all'indice 3? Può dirlo senza fare riferimento alla spiegazione originale della struttura dei metadati? + +Questa è una grande opportunità per usare un archivio chiave-valore, dove ogni elemento ha un set di chiavi e i loro valori associati, quindi può facilmente fare riferimento ad ogni chiave per ottenere il valore corrispondente. + +Nel nostro esempio, ciò significa passare da questa organizzazione: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +A questa: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +In Nextflow, questo è chiamato [map](https://nextflow.io/docs/latest/script.html#maps). + +Convertiamo ora la nostra lista piatta in una map. +Effettui le seguenti modifiche al workflow: + +=== "Dopo" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== "Prima" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Load files with channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +I cambiamenti chiave qui sono: + +- **Assegnazione destrutturante**: `def (patient, replicate, type, readNum) = ...` estrae i valori tokenizzati in variabili nominate in una sola riga +- **Sintassi letterale map**: `[id: patient, replicate: ...]` crea una map dove ogni chiave (come `id`) è associata ad un valore (come `patient`) +- **Struttura annidata**: La lista esterna `[..., myFile]` accoppia la map dei metadati con l'oggetto file originale + +Abbiamo anche semplificato un paio di stringhe di metadati usando un metodo di sostituzione di stringhe chiamato `replace()` per rimuovere alcuni caratteri non necessari (_ad es._ `replicate.replace('rep', '')` per mantenere solo il numero dagli ID replica). + +Eseguiamo nuovamente il workflow: + +```bash +nextflow run main.nf +``` + +??? success "Output del comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [infallible_swartz] DSL2 - revision: 7f4e68c0cb + + executor > local (2) + [1b/e7fb27] COUNT_LINES (1) [100%] 2 of 2 ✔ + [[id:patientA, replicate:1, type:normal, readNum:2], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[id:patientA, replicate:1, type:normal, readNum:1], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Ora i metadati sono etichettati in modo ordinato (_ad es._ `[id:patientA, replicate:1, type:normal, readNum:2]`) quindi è molto più facile distinguere cosa è cosa. + +Sarà anche molto più facile effettivamente utilizzare elementi di metadati nel workflow, e renderà il nostro codice più facile da leggere e più manutenibile. + +### Conclusioni + +- Possiamo gestire i nomi dei file in Nextflow con la potenza di un linguaggio di programmazione completo +- Possiamo trattare i nomi dei file come stringhe per estrarre informazioni rilevanti +- L'uso di metodi come `tokenize()` e `replace()` ci consente di manipolare le stringhe nel nome del file +- L'operazione `.map()` trasforma gli elementi del canale preservando la struttura +- Metadati strutturati (maps) rendono il codice più leggibile e manutenibile rispetto alle liste posizionali + +Prossimamente, vedremo come gestire file di dati appaiati. + +--- + +## 5. Gestione di file di dati appaiati + +Molti disegni sperimentali producono file di dati appaiati che beneficiano di essere gestiti in modo esplicitamente appaiato. +Ad esempio, in bioinformatica, i dati di sequenziamento sono spesso generati sotto forma di letture appaiate, ovvero stringhe di sequenza che originano dallo stesso frammento di DNA (spesso chiamate 'forward' e 'reverse' perché vengono lette da estremità opposte). + +Questo è il caso dei nostri dati di esempio, dove R1 e R2 si riferiscono ai due set di letture. + +```console +data/patientA_rep1_normal_R1_001.fastq.gz +data/patientA_rep1_normal_R2_001.fastq.gz +``` + +Nextflow fornisce un channel factory specializzato per lavorare con file appaiati come questo chiamato `channel.fromFilePairs diff --git a/docs/it/docs/training_collections/architects_toolkit_1.md b/docs/it/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..393593cc99 --- /dev/null +++ b/docs/it/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: Il Toolkit dell'Architetto I +hide: + - toc +--- + +# Il Toolkit dell'Architetto I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Le nostre Raccolte di Formazione forniscono percorsi di apprendimento curati attraverso i nostri materiali di formazione avanzati (chiamati [Side Quests](../../side_quests)). Questa raccolta copre quattro argomenti essenziali che vengono frequentemente utilizzati insieme per costruire workflow robusti e scalabili. + +## Obiettivi di apprendimento + +Al termine di questa raccolta, avrete esperienza con: + +- **Architetture di workflow modulari complesse** - Combinare più workflow in pipeline coese +- **Strategie di testing complete** - Assicurare che i vostri workflow siano affidabili e manutenibili +- **Gestione dei metadata** - Gestire i metadata specifici dei campioni in modo efficace durante i vostri workflow +- **Elaborazione avanzata dei dati** - Implementare pattern efficienti di suddivisione e raggruppamento dei dati + +Queste competenze vi permetteranno di costruire workflow Nextflow robusti, scalabili e manutenibili per applicazioni reali. + +## Pubblico e prerequisiti + +Questa raccolta è progettata per utenti che hanno completato la formazione base di Nextflow e desiderano approfondire i pattern avanzati dei workflow, le strategie di testing e le tecniche di gestione dei dati e metadata. + +**Prerequisiti** + +- Completamento della formazione [Hello Nextflow](../../hello_nextflow/) o esperienza equivalente +- Familiarità di base con la sintassi e i concetti di Nextflow +- Comprensione dei pattern di base per lo sviluppo di workflow +- Esperienza con strumenti da riga di comando + +## Contenuti della raccolta + +Questa raccolta consiste di quattro Side Quests che coprono argomenti complementari di ingegneria dei workflow: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - Architettura e composizione complessa di workflow +2. **[Testing with nf-test](../../side_quests/nf-test)** - Strategie di testing per workflow Nextflow +3. **[Metadata](../../side_quests/metadata)** - Gestione dei metadata per elementi nei channel Nextflow +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - Pattern avanzati di elaborazione dati + +Ogni Side Quest è autonomo e copre concetti indipendenti, ma raccomandiamo di completarli nell'ordine elencato sopra per una progressione logica attraverso gli argomenti. + +## Come utilizzare questa raccolta + +Per prima cosa, fate command-clic sul pulsante "Open in GitHub Codespaces" qui sotto per avviare l'ambiente di formazione in una scheda separata, poi continuate a leggere mentre si carica. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Una volta che il vostro ambiente è in esecuzione, procedete con la raccolta come segue: + +1. In questa scheda: Navigate al primo Side Quest elencato sopra, che descrive esercizi di sviluppo passo dopo passo. +2. Nella vostra scheda Codespaces: Lavorate attraverso gli esercizi del Side Quest. +3. Quando completate un Side Quest, tornate a questa pagina e navigate al successivo nell'elenco sopra. +4. Quando avete completato la raccolta, fate clic sul pulsante qui sotto per compilare un breve questionario. Il vostro feedback ci permette di continuare a migliorare i materiali di formazione per tutti. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Pronti per iniziare? Cominciate con il primo modulo sopra! diff --git a/docs/it/docs/training_collections/index.md b/docs/it/docs/training_collections/index.md new file mode 100644 index 0000000000..74d915a2c7 --- /dev/null +++ b/docs/it/docs/training_collections/index.md @@ -0,0 +1,23 @@ +# Collezioni di Formazione + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Traduzione assistita da IA - [scopri di più e suggerisci miglioramenti](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Questa sezione contiene collezioni curate di moduli di formazione chiamati [Side Quests](../side_quests/index.md) che mirano a fornire un'esperienza di apprendimento completa su un tema o caso d'uso particolare. + +## Prerequisiti + +Ogni collezione ha prerequisiti specifici documentati nella propria pagina indice. Tuttavia, la maggior parte delle collezioni presuppone: + +- Esperienza con la riga di comando +- Concetti fondamentali di Nextflow e strumenti trattati nel corso di formazione per principianti [Hello Nextflow](../../hello_nextflow/) + +Per i requisiti tecnici e la configurazione dell'ambiente, vedere il mini-corso [Configurazione dell'Ambiente](../../envsetup/). + +## Collezioni disponibili + +- [The Architect's Toolkit I](./architects_toolkit_1.md) - Una collezione di quattro Side Quests che coprono i pattern di architettura dei workflow per assemblare pipeline complessi, implementare strategie di test, gestire i metadati e raggruppare e dividere i dati. _Durata stimata: 4 ore in formazione di gruppo._ + +## Suggerire nuove collezioni + +Stiamo lavorando attivamente allo sviluppo di ulteriori Side Quests e Collezioni. +Si prega di suggerire argomenti che si ritiene abbiano senso coprire in una Collezione pubblicando nella [sezione Training](https://community.seqera.io/c/training/) del forum della community. diff --git a/docs/it/llm-prompt.md b/docs/it/llm-prompt.md new file mode 100644 index 0000000000..e2722f85a4 --- /dev/null +++ b/docs/it/llm-prompt.md @@ -0,0 +1,172 @@ +# Translation Rules for Italian + +The target language for this translation is **Italian** (`it`). + +## 1. Grammar & Tone + +- Use first person plural inclusive (noi/voi) rather than formal Lei - this creates a more collaborative, educational tone +- Example: "ci addentriamo", "apriamo", "eseguiamo", "vediamo insieme" +- Follow standard Italian spelling conventions +- Prefer active voice when possible +- Use natural Italian expressions (e.g., "Voilà!" is acceptable as it's commonly used in Italian) + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Italian (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "Il canale di input riceve i file..." (translate "channel" to "canale") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// emette un saluto` + +## 3. Code Comments + +**Always translate code comments to Italian.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Italian translation +params.greeting = "Hello" // imposta il saluto predefinito +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Italian: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Canale.fromPath('*.fastq') +processo FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ versione 24.04.0 +esecutore > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Using formal Lei when voi/noi is more appropriate + +```markdown +// Wrong - too formal for tutorial +Lei dovrà eseguire il comando seguente... + +// Correct - collaborative, educational tone +Eseguiamo il comando seguente... +// or +Eseguite il comando seguente... +``` + +### ❌ Translating English loanwords common in Italian tech + +Italian tech writing commonly keeps these in English: + +```markdown +// Acceptable - these are standard in Italian tech docs +Il file di output... +La directory di lavoro... +Il container Docker... + +// "Archivio" and "cartella" are NOT preferred +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code). + +Note: Italian tech writing commonly keeps "file", "directory", "output", "input", and "container" in English. + +| English | Italian | Notes | +| --------------- | -------------------------------- | ------------------------------------- | +| channel | canale / canali | Translate in prose | +| process | processo | Translate in prose | +| workflow | flusso di lavoro | Always translate in prose | +| pipeline | pipeline | Keep in English | +| channel factory | fabbrica di canali | | +| queue channel | canale di coda | | +| work directory | directory di lavoro | Note: "directory" stays English | +| directive | direttiva | | +| container | container | Keep in English (standard in Italian) | +| input | input | Keep in English (standard in Italian) | +| output | output | Keep in English (standard in Italian) | +| file | file | Keep in English (standard in Italian) | +| directory | directory | Keep in English (standard in Italian) | +| task | attività | | +| tuple | tupla | | +| operator | operatore | | +| parameter | parametro | | +| qualifier | qualificatore | | +| environment | ambiente | | +| sample | campione | | +| alignment | allineamento | | +| reference | riferimento | | +| training | formazione | | +| module | modulo | | +| command | comando | | +| index | indice | | +| run | eseguire / esecuzione / lanciare | | +| greeting | saluto | In context of Hello World examples | +| log | registri / log | Both acceptable | + +## 6. Admonition Titles + +| English | Italian | +| -------- | ------------------- | +| Note | Nota | +| Tip | Suggerimento | +| Warning | Avviso / Attenzione | +| Exercise | Esercizio | +| Solution | Soluzione | +| Example | Esempio | + +## 7. Section Headers + +These recurring section headers should be translated consistently: + +| English | Italian | Notes | +| ------------------ | ------------------ | ------------------------------------------------------- | +| Takeaway | Takeaway | Keep in English - common in Italian educational content | +| What's next? | Cosa c'è dopo? | | +| Warmup | Riscaldamento | | +| Directory contents | Directory contents | Keep in code block titles | +| Output | Output | Keep in code block titles | + +## 8. Tab Labels + +| English | Italian | +| ------- | ------- | +| After | Dopo | +| Before | Prima | +| Gitpod | Gitpod | +| Local | Locale | + +## 9. Common Expressions + +| English | Italian | +| ------------------ | ------------------------------ | +| Congratulations! | Congratulazioni! | +| Good news | Buone notizie | +| Voilà! | Voilà! (acceptable in Italian) | +| Take a short break | Prendetevi una piccola pausa | +| you've earned it | ve la siete meritata | diff --git a/docs/it/mkdocs.yml b/docs/it/mkdocs.yml new file mode 100644 index 0000000000..6dc15eaf59 --- /dev/null +++ b/docs/it/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: it + custom_dir: ../en/overrides +extra: + consent: + title: "Consenso ai cookie" + description: >- + Utilizziamo i cookie per riconoscere le tue visite ripetute e le tue preferenze, + nonché per misurare l'efficacia della nostra documentazione e se gli utenti + trovano ciò che cercano. Con il tuo consenso, ci aiuti a migliorare i nostri + materiali di formazione. + Scopri di più su + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">come utilizziamo i cookie</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/it/ui-strings.yml b/docs/it/ui-strings.yml new file mode 100644 index 0000000000..8a6f89ebd3 --- /dev/null +++ b/docs/it/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - Italian (Italiano) +# Queste stringhe sono utilizzate da index_page_hook.py per le pagine +# iniziali dei corsi e in mkdocs.yml per il consenso ai cookie. + +index_page: + course_summary: "Riepilogo del corso" + additional_information: "Informazioni aggiuntive" + technical_requirements: "Requisiti tecnici" + learning_objectives: "Obiettivi di apprendimento" + audience_prerequisites: "Destinatari e prerequisiti" + course_videos: "Video del corso" + +defaults: + technical_requirements: >- + Avrai bisogno di un account GitHub OPPURE di un'installazione locale di Nextflow. + Consulta [Opzioni ambiente](../envsetup/index.md) per maggiori dettagli. + videos: >- + Sono disponibili video per ogni capitolo, in cui un istruttore lavora + attraverso gli esercizi. Il video di ogni parte del corso è incorporato + nella parte superiore della pagina corrispondente. + view_playlist: "Guarda la playlist su YouTube" diff --git a/docs/ko/docs/envsetup/01_setup.md b/docs/ko/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..e353cc7415 --- /dev/null +++ b/docs/ko/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces는 클라우드의 가상 머신에 의해 지원되는 사전 구성된 교육 환경을 제공할 수 있는 웹 기반 플랫폼입니다. +이 플랫폼은 Github(Microsoft 소유)에서 운영되며, Github 계정이 있는 누구나 무료(사용량 할당량 내에서)로 이용할 수 있습니다. + +!!! warning + + 조직에 연결된 계정은 특정 추가 제한이 적용될 수 있습니다. + 이 경우 독립적인 개인 계정을 사용하거나 대신 로컬 설치를 사용해야 할 수 있습니다. + +## GitHub 계정 생성 + +[GitHub 홈페이지](https://github.com/)에서 무료 GitHub 계정을 만들 수 있습니다. + +## GitHub Codespace 시작하기 + +GitHub에 로그인한 후 브라우저에서 이 링크를 열어 Nextflow 교육 환경을 엽니다: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +또는 아래 표시된 버튼을 클릭할 수 있습니다. 이 버튼은 각 교육 과정(일반적으로 Orientation 페이지)에서 반복됩니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +새 GitHub Codespace를 생성할 수 있는 페이지가 표시됩니다: + +![GitHub Codespace 생성](img/codespaces_create.png) + +### 구성 + +일반적인 사용에서는 별도로 구성할 필요가 없습니다. +시작하려는 과정에서 별도로 지정하지 않는 한 기본 버튼을 클릭하여 계속 진행하면 됩니다. + +그러나 "Change options" 버튼을 클릭하여 환경을 사용자 정의할 수 있습니다. + +??? info "구성 옵션" + + "Change options" 버튼을 클릭하면 다음 사항을 사용자 정의할 수 있습니다: + + #### 브랜치 + + 다른 버전의 교육 자료를 선택할 수 있습니다. + `master` 브랜치에는 일반적으로 버그 수정과 최근에 개발되어 승인되었지만 아직 웹사이트에 릴리스되지 않은 자료가 포함되어 있습니다. + 다른 브랜치에는 완전히 기능하지 않을 수 있는 진행 중인 작업이 포함되어 있습니다. + + #### 머신 유형 + + 교육을 진행하는 데 사용할 가상 머신을 사용자 정의할 수 있습니다. + + 더 많은 코어가 있는 머신을 사용하면 Nextflow의 워크플로우 실행 병렬화 기능을 더 잘 활용할 수 있습니다. + 그러나 무료 할당량을 더 빨리 소비하므로 수강하려는 과정 지침에서 권장하지 않는 한 이 설정을 변경하는 것은 권장하지 않습니다. + + 할당량에 대한 자세한 내용은 아래 'GitHub Codespaces 할당량'을 참조하십시오. + +### 시작 시간 + +처음으로 새 GitHub Codespaces 환경을 여는 데 몇 분이 걸릴 수 있습니다. 시스템이 가상 머신을 설정해야 하므로 대기 시간이 있더라도 걱정하지 마십시오. +그러나 5분 이상 걸리지 않아야 합니다. + +## 교육 인터페이스 탐색 + +GitHub Codespaces가 로드되면 다음과 유사한 화면이 표시됩니다(계정 기본 설정에 따라 라이트 모드로 열릴 수 있습니다): + +![GitHub Codespaces 시작 화면](img/codespaces_welcome.png) + +이것은 Nextflow 개발에 사용하기를 권장하는 인기 있는 코드 개발 애플리케이션인 VSCode IDE의 인터페이스입니다. + +- **메인 에디터**는 Nextflow 코드 및 기타 텍스트 파일이 열리는 곳입니다. 여기에서 코드를 편집합니다. codespace를 열면 `README.md` 파일의 미리보기가 표시됩니다. +- 메인 에디터 아래의 **터미널**에서 명령을 실행할 수 있습니다. 과정 지침에 제공된 모든 명령줄은 여기에서 실행합니다. +- **사이드바**를 사용하면 환경을 사용자 정의하고 기본 작업(복사, 붙여넣기, 파일 열기, 검색, git 등)을 수행할 수 있습니다. 기본적으로 저장소의 내용을 탐색할 수 있는 파일 탐색기가 열려 있습니다. 탐색기에서 파일을 클릭하면 메인 에디터 창에서 열립니다. + +원하는 대로 창 패널의 상대적 비율을 조정할 수 있습니다. + +<!-- TODO (future) Link to development best practices side quest? --> + +## GitHub Codespaces 사용에 대한 기타 참고 사항 + +### 세션 재개 + +환경을 생성한 후에는 쉽게 재개하거나 다시 시작하여 중단한 곳에서 계속할 수 있습니다. +환경은 30분간 비활동 후 타임아웃되며 최대 2주 동안 변경 사항을 저장합니다. + +<https://github.com/codespaces/>에서 환경을 다시 열 수 있습니다. +이전 환경이 나열됩니다. +세션을 클릭하여 재개합니다. + +![GitHub Codespace 세션 목록](img/codespaces_list.png) + +이전 GitHub Codespaces 환경의 URL을 저장해 두었다면 브라우저에서 바로 열 수 있습니다. +또는 처음에 생성할 때 사용한 것과 동일한 버튼을 클릭하면 됩니다: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +이전 세션이 표시되며 기본 옵션은 재개하는 것입니다: + +![GitHub Codespace 재개](img/codespaces_resume.png) + +### 로컬 머신에 파일 저장 + +탐색기 패널에서 파일을 저장하려면 파일을 마우스 오른쪽 버튼으로 클릭하고 `Download`를 선택합니다. + +### GitHub Codespaces 할당량 관리 + +GitHub Codespaces는 월 최대 15GB-월 스토리지와 월 120 코어-시간을 제공합니다. +이는 표준 워크스페이스(2코어, 8GB RAM, 32GB 스토리지)를 사용하는 기본 환경 런타임의 약 60시간에 해당합니다. + +더 많은 리소스로 생성할 수 있지만(위의 설명 참조), 무료 사용량을 더 빨리 소비하게 되어 이 공간에 대한 액세스 시간이 줄어듭니다. +예를 들어, 2코어 기본값 대신 4코어 머신을 선택하면 할당량이 절반의 시간 내에 소진됩니다. + +선택적으로 더 많은 리소스에 대한 액세스를 구매할 수 있습니다. + +자세한 내용은 GitHub 문서를 참조하십시오: +[GitHub Codespaces 청구에 대해](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/ko/docs/envsetup/02_local.md b/docs/ko/docs/envsetup/02_local.md new file mode 100644 index 0000000000..95fc113b21 --- /dev/null +++ b/docs/ko/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# 수동 설치 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +자체 로컬 환경에서 교육을 실행하는 데 필요한 모든 것을 수동으로 설치할 수 있습니다. + +여기서는 표준 POSIX 호환 시스템(노트북과 같은 개인용 머신 가정)에서 이를 수행하는 방법을 문서화했습니다. +특정 시스템에 따라 일부 세부 사항이 다를 수 있다는 점에 유의하십시오. + +!!! tip + + 진행하기 전에 [Devcontainers 방식](03_devcontainer.md)을 고려해 보셨나요? + 수동 설치 없이 필요한 모든 도구와 종속성을 제공합니다. + +## 일반 소프트웨어 요구 사항 + +Nextflow는 Java가 설치된 모든 POSIX 호환 시스템(Linux, macOS, Windows Subsystem for Linux 등)에서 사용할 수 있습니다. +저희 교육 과정에는 몇 가지 추가 요구 사항이 있습니다. + +총합적으로 다음 소프트웨어가 설치되어 있어야 합니다: + +- Bash 또는 동등한 셸 +- [Java 11 (또는 최대 21까지의 이후 버전)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (또는 이후 버전) +- [VSCode](https://code.visualstudio.com)와 [Nextflow 확장](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +VSCode 애플리케이션은 기술적으로 선택 사항이지만 과정을 진행하는 데뿐만 아니라 일반적인 Nextflow 개발 작업에도 사용하는 것을 강력히 권장합니다. + +Nextflow 문서 매뉴얼에서는 [환경 설정](https://www.nextflow.io/docs/latest/developer-env.html)에서 이러한 종속성 설치에 대한 지침을 제공합니다. + +## Nextflow 및 nf-core 도구 + +Nextflow 자체와 nf-core 도구를 설치해야 합니다. 아래 링크된 문서에 자세히 설명되어 있습니다: + +- [Nextflow 설치](https://www.nextflow.io/docs/latest/install.html) +- [nf-core 도구](https://nf-co.re/docs/nf-core-tools/installation) + +Nextflow의 경우 self-install 옵션을, nf-core 도구의 경우 PyPI 옵션을 사용하는 것을 권장합니다. + +!!! warning "버전 호환성" + + <!-- Any update to this content needs to be copied to the home page --> + **2026년 1월 기준, 별도의 언급이 없는 한 모든 Nextflow 교육 과정은 strict v2 구문이 활성화된 Nextflow 버전 25.10.2 이상을 필요로 합니다.** + + 버전 요구 사항 및 strict v2 구문에 대한 자세한 내용은 [Nextflow 버전](../info/nxf_versions.md) 가이드를 참조하십시오. + + 이전 구문에 해당하는 이전 버전의 교육 자료는 이 웹페이지 메뉴 바의 버전 선택기를 통해 사용할 수 있습니다. + +## 교육 자료 + +교육 자료를 다운로드하는 가장 쉬운 방법은 다음 명령을 사용하여 전체 저장소를 복제하는 것입니다: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +각 과정에는 자체 디렉토리가 있습니다. +과정을 진행하려면 터미널 창(이상적으로는 VSCode 애플리케이션 내부)을 열고 해당 디렉토리로 `cd`합니다. + +그런 다음 웹사이트에 제공된 과정 지침을 따를 수 있습니다. diff --git a/docs/ko/docs/envsetup/03_devcontainer.md b/docs/ko/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..53dbc17936 --- /dev/null +++ b/docs/ko/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# 로컬 Devcontainers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +로컬 Docker 설치가 있거나 설치할 의향이 있다면, 이 자료로 로컬에서 작업하는 가장 쉬운 방법은 Visual Studio Code의 devcontainer 기능을 사용하는 것입니다. 이 방식은 수동 설치 없이 필요한 모든 도구와 종속성을 제공합니다. + +## 요구 사항 + +로컬 devcontainer 설정을 사용하려면 다음이 필요합니다: + +- [Visual Studio Code](https://code.visualstudio.com/) +- 로컬 Docker 설치, 예: + - [Docker Desktop](https://docs.docker.com/get-docker/) (Windows/macOS용) + - [Docker Engine](https://docs.docker.com/engine/install/) (Linux용) + - [Colima](https://github.com/abiosoft/colima) (macOS 대안) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (Docker Desktop에 포함되어 있지만 다른 Docker 설정에서는 별도 설치가 필요할 수 있음) +- VS Code용 [Dev Containers 확장](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +devcontainer를 열기 전에 Docker 설치가 실행 중이어야 합니다. + +Docker buildx가 사용 가능한지 확인하려면 다음을 실행하십시오: + +```bash +docker buildx version +``` + +이 명령이 실패하면 진행하기 전에 buildx 확장을 설치해야 합니다. + +## 설정 지침 + +VS Code devcontainers를 사용하여 로컬 환경을 설정하려면 다음 단계를 따르십시오: + +### VS Code에 "Dev Containers" 확장 설치 + +- VS Code 열기 +- Extensions로 이동 (Ctrl+Shift+X 또는 macOS에서 Cmd+Shift+X) +- "Dev Containers" 검색 +- "Install" 클릭 + +![VS Code에서 Dev Containers 확장 프로그램 설치](img/install_extension.png) + +### 저장소 복제: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### VS Code에서 저장소 열기: + +- VS Code 실행 +- 메뉴에서 **File -> Open Folder** 선택 +- 방금 복제한 training 저장소 폴더로 이동하여 선택 +- **Open** 클릭 + +### 컨테이너에서 다시 열기 + +VS Code에서 "Reopen in Container"라는 메시지가 표시되면 클릭합니다. 또는: + +- F1 누르기 (또는 macOS에서 Ctrl+Shift+P / Cmd+Shift+P) +- "Dev Containers: Reopen in Container" 입력 +- **중요**: 구성을 선택하라는 메시지가 표시되면 **local-dev** devcontainer 구성을 선택합니다 + +![컨테이너에서 다시 열기 프롬프트](img/reopen_prompt.png) + +![로컬 구성 선택](img/select_local_config.png) + +컨테이너가 빌드될 때까지 기다립니다. 처음에는 필요한 모든 구성 요소를 다운로드하고 설정해야 하므로 몇 분이 걸릴 수 있습니다. + +컨테이너가 빌드되고 실행되면 다음을 포함한 필요한 모든 도구가 설치된 완전히 구성된 환경이 제공됩니다: + +- Java +- Nextflow +- Docker +- Git +- 교육에 필요한 기타 모든 종속성 + +![devcontainer가 실행 중인 VS Code](img/running_container.png) + +## Devcontainers 사용의 이점 + +devcontainer 방식을 사용하면 여러 가지 이점이 있습니다: + +- **일관성**: 다른 머신에서도 일관된 개발 환경 보장 +- **단순성**: 모든 종속성이 사전 설치되고 구성됨 +- **격리**: 개발 환경이 로컬 시스템과 격리됨 +- **재현성**: devcontainer를 사용하는 모든 사람이 동일한 설정을 얻음 +- **수동 설치 불필요**: Java, Nextflow 및 기타 도구를 수동으로 설치할 필요 없음 + +## 환경 확인 + +devcontainer가 실행되면 다음을 실행하여 모든 것이 올바르게 설정되었는지 확인할 수 있습니다: + +```bash +nextflow info +``` + +Nextflow 버전 및 런타임 정보가 표시되어 환경이 올바르게 구성되었음을 확인할 수 있습니다. + +## 문제 해결 + +devcontainer 설정에 문제가 발생하면: + +1. devcontainer를 열기 전에 Docker 설치(Docker Desktop, Colima, Docker Engine 등)가 실행 중인지 확인하십시오 +2. 메시지가 표시되면 **local-dev** 구성을 선택했는지 확인하십시오 +3. `docker buildx version`을 실행하여 Docker buildx가 설치되어 있고 작동하는지 확인하십시오 +4. 컨테이너 빌드가 실패하면 "Dev Containers: Rebuild Container" 명령을 실행하여 다시 빌드해 보십시오 +5. 지속적인 문제의 경우 [VS Code Dev Containers 문제 해결 가이드](https://code.visualstudio.com/docs/devcontainers/troubleshooting)를 참조하십시오 diff --git a/docs/ko/docs/envsetup/index.md b/docs/ko/docs/envsetup/index.md new file mode 100644 index 0000000000..2917080dde --- /dev/null +++ b/docs/ko/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: 환경 옵션 +description: Nextflow 교육을 위한 환경 설정 옵션 +hide: + - toc + - footer +--- + +# 환경 옵션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +학습자가 소프트웨어 관리에 시간과 노력을 들이지 않고 Nextflow 학습에 집중할 수 있도록 일관되고 철저히 테스트된 환경을 제공하는 것을 목표로 합니다. +이를 위해 모든 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 파일 및 예제 데이터가 포함된 컨테이너화된 환경을 개발했습니다. + +이 컨테이너화된 환경은 Github Codespaces에서 즉시 실행하거나 Devcontainers 확장 기능이 있는 VS Code에서 로컬로 실행할 수 있습니다. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **Github Codespaces** + + *** + + GitHub Codespaces는 클라우드의 가상 머신에 의해 지원되는, 모든 도구와 데이터가 포함된 사전 구축된 교육 환경을 제공할 수 있는 웹 기반 서비스입니다. Github 계정이 있는 누구나 무료로 이용할 수 있습니다. + + [Github Codespaces 사용하기:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **로컬 Devcontainers** + + *** + + Devcontainers가 있는 VS Code는 모든 교육 도구가 사전 구성된 로컬 실행 컨테이너화된 개발 환경을 제공합니다. Codespaces와 동일한 사전 구축된 환경을 제공하지만 전적으로 로컬 하드웨어에서 실행됩니다. + + [로컬에서 Devcontainers 사용하기 :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## 수동 설치 안내 + +위의 옵션이 적합하지 않은 경우 소프트웨어 종속성을 수동으로 설치하고 교육 저장소를 복제하여 자체 로컬 시스템에서 이 환경을 복제할 수 있습니다. + +[수동 설치 :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Gitpod 지원 중단" + + Nextflow Training은 2025년 2월까지 [Gitpod](https://gitpod.io)를 사용했습니다. + 그러나 Gitpod 제작자들은 [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex) 시스템을 위해 무료 기능을 종료하기로 결정했습니다. + 그 이유로 사전 설정 없이 원클릭 개발자 환경을 제공하는 GitHub Codespaces로 전환했습니다. + + Gitpod에 가입한 시기와 서비스 종료 시기에 따라 이전 클라우드 IDE에서 교육을 시작할 수 있지만 앞으로 안정적인 액세스를 보장할 수 없습니다: + [Gitpod에서 열기](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/ko/docs/hello_nextflow/00_orientation.md b/docs/ko/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..a1e9786075 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# 시작하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생 목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하세요. + +:green_book: 비디오 스크립트는 [여기](./transcripts/00_orientation.md)에서 확인할 수 있습니다. +/// + +!!! tip + + YouTube 비디오에는 몇 가지 강력한 기능이 있습니다! + + - :fontawesome-solid-closed-captioning: 고품질(수동 큐레이팅된) 자막. :material-subtitles: 아이콘으로 켤 수 있습니다 + - :material-bookmark: 페이지 제목에 해당하는 타임라인의 비디오 챕터 + +## 교육 환경 시작 + +GitHub Codespaces에서 제공하는 사전 구축된 환경을 사용하려면 아래 "Open in GitHub Codespaces" 버튼을 클릭하십시오. 다른 옵션은 [환경 옵션](../envsetup/index.md)을 참조하십시오. + +환경이 로드되는 동안 계속 읽을 수 있도록 새 브라우저 탭이나 창에서 교육 환경을 여는 것이 좋습니다(장비에 따라 우클릭, ctrl-클릭 또는 cmd-클릭 사용). +과정을 진행하려면 이 지침을 병렬로 열어 두어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### 환경 기초 + +이 교육 환경에는 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 직접 아무것도 설치할 필요가 없습니다. + +codespace는 파일 시스템 탐색기, 코드 편집기 및 터미널 셸을 포함하는 VSCode 인터페이스로 설정되어 있습니다. +과정 중 제공되는 모든 지침(예: '파일 열기', '코드 편집' 또는 '이 명령 실행')은 별도로 지정하지 않는 한 VScode 인터페이스의 이 세 부분을 참조합니다. + +직접 이 과정을 진행하는 경우 [환경 기초](../envsetup/01_setup.md)를 참조하여 자세한 내용을 확인하십시오. + +### 버전 요구 사항 + +이 교육은 **v2 구문 파서가 활성화된** Nextflow 25.10.2 이상용으로 설계되었습니다. +로컬 또는 사용자 정의 환경을 사용하는 경우 [여기](../info/nxf_versions.md)에 문서화된 대로 올바른 설정을 사용하고 있는지 확인하십시오. + +## 작업 준비 + +codespace가 실행되면 교육에 들어가기 전에 두 가지를 해야 합니다: 이 특정 과정에 대한 작업 디렉토리 설정 및 제공된 자료 살펴보기. + +### 작업 디렉토리 설정 + +기본적으로 codespace는 모든 교육 과정의 루트에서 작업 디렉토리가 설정된 상태로 열리지만, 이 과정에서는 `hello-nextflow/` 디렉토리에서 작업합니다. + +터미널에서 다음 명령을 실행하여 지금 디렉토리를 변경하십시오: + +```bash +cd hello-nextflow/ +``` + +VSCode가 이 디렉토리에 초점을 맞추도록 설정하여 파일 탐색기 사이드바에 관련 파일만 표시되도록 할 수 있습니다: + +```bash +code . +``` + +!!! tip + + 어떤 이유로든 이 디렉토리에서 벗어난 경우(예: codespace가 절전 모드로 전환된 경우), Github Codespaces 교육 환경 내에서 실행한다고 가정하고 전체 경로를 사용하여 언제든지 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +이제 내용을 살펴보겠습니다. + +### 제공된 자료 탐색 + +교육 작업 공간의 왼쪽에 있는 파일 탐색기를 사용하여 이 디렉토리의 내용을 탐색할 수 있습니다. +또는 `tree` 명령을 사용할 수 있습니다. + +과정 전체에서 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간의 수정을 가합니다. + +여기서는 두 번째 수준까지 목차를 생성합니다: + +```bash +tree . -L 2 +``` + +??? abstract "디렉토리 내용" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +색상이 있는 상자를 클릭하여 섹션을 확장하고 내용을 봅니다. +예상되는 명령 출력을 간결하게 포함하기 위해 이와 같은 접을 수 있는 섹션을 사용합니다. + +- **`.nf` 파일**은 과정의 어느 부분에서 사용되는지에 따라 이름이 지정된 워크플로우 스크립트입니다. + +- **`nextflow.config` 파일**은 최소한의 환경 속성을 설정하는 구성 파일입니다. + 지금은 무시해도 됩니다. + +- **`data/` 아래의 `greetings.csv` 파일**에는 과정 대부분에서 사용할 입력 데이터가 포함되어 있습니다. Part 2(Channels)에서 처음 소개할 때 설명합니다. + +- **`test-params.*` 파일**은 Part 6(Configuration)에서 사용할 구성 파일입니다. 지금은 무시해도 됩니다. + +- **`solutions` 디렉토리**에는 과정의 각 단계에서 나온 완성된 워크플로우 스크립트가 포함되어 있습니다. + 작업을 확인하고 문제를 해결하기 위한 참조용입니다. + +## 준비 완료 체크리스트 + +들어갈 준비가 되셨다고 생각하시나요? + +- [ ] 이 과정의 목표와 전제 조건을 이해합니다 +- [ ] 환경이 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 + +모든 항목을 체크할 수 있다면 준비 완료입니다. + +**[Part 1: Hello World](./01_hello_world.md)로 계속하려면 이 페이지 오른쪽 하단의 화살표를 클릭하십시오.** diff --git a/docs/ko/docs/hello_nextflow/01_hello_world.md b/docs/ko/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..0d736f8bdf --- /dev/null +++ b/docs/ko/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# 파트 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생 목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하세요. + +:green_book: 비디오 스크립트는 [여기](./transcripts/01_hello_world.md)에서 확인할 수 있습니다. +/// + +Hello Nextflow 교육 과정의 첫 번째 부분에서는 매우 기본적인 도메인에 구애받지 않는 Hello World 예제로 주제에 쉽게 접근합니다. 이 예제를 점진적으로 구축하여 기본 Nextflow 로직과 구성 요소의 사용법을 시연합니다. + +??? info "Hello World 예제란 무엇인가요?" + + "Hello World!"는 프로그래밍 언어 또는 소프트웨어 프레임워크의 기본 구문과 구조를 보여주기 위한 최소한의 예제입니다. + 이 예제는 일반적으로 콘솔이나 터미널과 같은 출력 장치에 "Hello, World!"라는 문구를 출력하거나 파일에 쓰는 것으로 구성됩니다. + +--- + +## 0. 워밍업: Hello World 예제 직접 실행 + +Nextflow로 감싸기 전에 터미널에서 직접 실행하는 간단한 명령으로 시작하여 무엇을 하는지 보여드리겠습니다. + +!!! tip + + [시작하기](00_orientation.md) 페이지에 설명된 대로 이제 `hello-nextflow/` 디렉토리 안에 있어야 합니다. + +### 0.1. 터미널이 hello라고 말하게 하기 + +터미널에서 다음 명령을 실행하십시오. + +```bash +echo 'Hello World!' +``` + +??? success "명령 출력" + + ```console + Hello World! + ``` + +이것은 터미널에 'Hello World' 텍스트를 출력합니다. + +### 0.2. 출력을 파일에 쓰기 + +파이프라인 실행은 대부분 파일에서 데이터를 읽고 결과를 다른 파일에 쓰는 것을 포함하므로, 예제를 좀 더 관련성 있게 만들기 위해 텍스트 출력을 파일에 쓰도록 명령을 수정해 보겠습니다. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "명령 출력" + + ```console + + ``` + +이것은 터미널에 아무것도 출력하지 않습니다. + +### 0.3. 출력 찾기 + +'Hello World' 텍스트는 이제 지정한 출력 파일인 `output.txt`에 있어야 합니다. +파일 탐색기에서 열거나 예를 들어 `cat` 유틸리티를 사용하여 명령줄에서 열 수 있습니다. + +??? abstract "파일 내용" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +이것이 첫 번째 Nextflow 워크플로우로 복제하려는 것입니다. + +### 요약 + +터미널에서 텍스트를 출력하는 간단한 명령을 실행하는 방법과 선택적으로 출력을 파일에 쓰는 방법을 알게 되었습니다. + +### 다음 단계 + +Nextflow 워크플로우로 작성하면 어떻게 보이는지 알아보세요. + +--- + +## 1. 스크립트 검토 및 실행 + +이전과 동일한 작업('Hello World!' 출력)을 수행하지만 Nextflow로 수행하는 완전히 기능적이지만 최소한의 워크플로우 스크립트 `hello-world.nf`를 제공합니다. + +시작하기 위해 워크플로우 스크립트를 열어 구조를 파악해 보겠습니다. +그런 다음 실행하고 출력을 찾아봅니다. + +### 1.1. 코드 검토 + +`hello-world.nf` 스크립트는 현재 디렉토리인 `hello-nextflow`에 있습니다. 편집기 창에서 여십시오. + +??? full-code "전체 코드 파일" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * echo를 사용하여 'Hello World!'를 파일에 출력 + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // 인사말을 내보냅니다 + sayHello() + } + ``` + +Nextflow 워크플로우 스크립트는 일반적으로 하나 이상의 **process** 정의와 **workflow** 자체, 그리고 나중에 소개할 몇 가지 선택적 블록(여기에는 없음)을 포함합니다. + +각 **process**는 파이프라인의 해당 단계가 수행해야 할 작업을 설명하고, **workflow**는 다양한 단계를 연결하는 데이터 흐름 로직을 설명합니다. + +먼저 **process** 블록을 자세히 살펴본 다음 **workflow** 블록을 살펴보겠습니다. + +#### 1.1.1. `process` 정의 + +첫 번째 코드 블록은 **process**를 설명합니다. + +프로세스 정의는 `process` 키워드로 시작하고 프로세스 이름이 뒤따르며 마지막으로 중괄호로 구분된 프로세스 본문이 옵니다. +프로세스 본문에는 실행할 명령을 지정하는 script 블록이 포함되어야 하며, 이는 명령줄 터미널에서 실행할 수 있는 모든 것이 될 수 있습니다. + +```groovy title="hello-world.nf" linenums="3" +/* +* echo를 사용하여 'Hello World!'를 파일에 출력 +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +여기에 `output.txt`라는 파일에 **출력**을 쓰는 `sayHello`라는 **프로세스**가 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +이것은 `output` 정의와 실행할 `script`만 포함하는 매우 최소한의 프로세스 정의입니다. + +`output` 정의에는 `path` 한정자가 포함되어 있으며, 이는 Nextflow에게 이것이 경로(디렉토리 경로와 파일 모두 포함)로 처리되어야 함을 알려줍니다. +또 다른 일반적인 한정자는 `val`입니다. + +중요한 것은 출력 정의가 어떤 출력이 생성될지 *결정*하지 않는다는 것입니다. +실행이 완료된 후 Nextflow가 찾을 수 있도록 예상 출력을 단순히 *선언*합니다. +이는 명령이 성공적으로 실행되었는지 확인하고 필요한 경우 출력을 다운스트림 프로세스에 전달하는 데 필요합니다. 출력 블록에 선언된 것과 일치하지 않는 생성된 출력은 다운스트림 프로세스로 전달되지 않습니다. + +!!! warning + + 이 예제는 두 개의 별도 위치(스크립트와 출력 블록)에 출력 파일 이름을 하드코딩했기 때문에 취약합니다. + 하나를 변경하고 다른 하나를 변경하지 않으면 스크립트가 중단됩니다. + 나중에 이 문제를 완화하기 위해 변수를 사용하는 방법을 배웁니다. + +실제 파이프라인에서 프로세스는 일반적으로 지시문과 입력과 같은 추가 블록을 포함하며, 이에 대해서는 곧 소개합니다. + +#### 1.1.2. `workflow` 정의 + +두 번째 코드 블록은 **workflow** 자체를 설명합니다. +워크플로우 정의는 `workflow` 키워드로 시작하고 선택적 이름이 뒤따르며 중괄호로 구분된 워크플로우 본문이 옵니다. + +여기에 `main:` 블록('이것이 워크플로우의 메인 본문입니다'라고 말하는 코드 요소)과 `sayHello` 프로세스에 대한 호출을 포함하는 **workflow**가 있습니다. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // 인사말을 내보냅니다 + sayHello() +} +``` + +이것은 매우 최소한의 **workflow** 정의입니다. +실제 파이프라인에서 워크플로우는 일반적으로 **채널**로 연결된 **프로세스**에 대한 여러 호출을 포함하고, 프로세스는 하나 이상의 변수 **입력**을 기대합니다. + +이 교육 모듈의 후반부에서 변수 입력을 추가하는 방법을 배웁니다. 그리고 이 과정의 Part 3에서 더 많은 프로세스를 추가하고 채널로 연결하는 방법을 배웁니다. + +!!! tip + + 기술적으로 `main:` 줄은 이와 같은 간단한 워크플로우에는 필요하지 않으므로 이를 포함하지 않는 워크플로우를 만날 수 있습니다. + 그러나 워크플로우 수준 출력을 활용하려면 필요하므로 처음부터 포함하는 것이 좋습니다. + +### 1.2. 워크플로우 실행 + +코드를 보는 것은 실행하는 것만큼 재미있지 않으므로 실제로 실행해 보겠습니다. + +#### 1.2.1. 워크플로우 시작 및 실행 모니터링 + +터미널에서 다음 명령을 실행하십시오: + +```bash +nextflow run hello-world.nf +``` + +??? success "명령 출력" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +콘솔 출력이 이와 같다면 축하합니다. 첫 번째 Nextflow 워크플로우를 실행하셨습니다! + +여기서 가장 중요한 출력은 위의 출력에서 강조 표시된 마지막 줄입니다: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +이것은 `sayHello` 프로세스가 성공적으로 한 번 실행되었음을 알려줍니다(`1 of 1 ✔`). + +중요한 것은 이 줄이 `sayHello` 프로세스 호출의 출력을 찾을 위치도 알려준다는 것입니다. +이제 살펴보겠습니다. + +#### 1.2.2. `work` 디렉토리에서 출력 및 로그 찾기 + +지정된 디렉토리에서 Nextflow를 처음 실행하면 실행 과정에서 생성된 모든 파일(및 심볼릭 링크)을 쓸 `work`라는 디렉토리가 생성됩니다. + +`work` 디렉토리 내에서 Nextflow는 프로세스 호출별로 출력과 로그를 구성합니다. +각 프로세스 호출에 대해 Nextflow는 고유하게 만들기 위해 해시로 이름이 지정된 중첩된 하위 디렉토리를 생성하며, 여기에 필요한 모든 입력을 스테이징하고(기본적으로 심볼릭 링크 사용), 도우미 파일을 작성하고, 프로세스의 로그와 출력을 기록합니다. + +해당 하위 디렉토리의 경로는 콘솔 출력의 대괄호 안에 잘린 형태로 표시됩니다. +위에 표시된 실행에서 얻은 것을 보면 sayHello 프로세스의 콘솔 로그 줄은 `[65/7be2fa]`로 시작합니다. 이것은 다음 디렉토리 경로에 해당합니다: `work/65/7be2fad5e71e5f49998f795677fd68` + +그 안에 무엇이 있는지 살펴보겠습니다. + +??? abstract "디렉토리 내용" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "같은 것이 보이지 않나요?" + + 정확한 하위 디렉토리 이름은 시스템에서 다를 것입니다. + + VSCode 파일 탐색기에서 작업 하위 디렉토리의 내용을 탐색하면 모든 파일이 바로 표시됩니다. + 그러나 로그 파일은 터미널에서 보이지 않도록 설정되어 있으므로 `ls` 또는 `tree`를 사용하여 보려면 보이지 않는 파일을 표시하는 관련 옵션을 설정해야 합니다. + + ```bash + tree -a work + ``` + +먼저 워크플로우의 실제 출력, 즉 `sayHello` 프로세스에서 생성된 `output.txt` 파일을 살펴보고 싶을 것입니다. +열어보면 `Hello World!` 인사말이 있으며, 이것이 최소한의 워크플로우의 목적이었습니다. + +??? abstract "파일 내용" + + ```console title="output.txt" + Hello World! + ``` + +작동했습니다! + +물론, 이렇게 작은 결과에 비해 래퍼 코드가 많아 보일 수 있지만, 입력 파일을 읽고 여러 단계를 연결하기 시작하면 모든 래퍼 코드의 가치가 더 분명해질 것입니다. + +그렇긴 하지만 해당 디렉토리의 다른 파일도 살펴보겠습니다. 이것들은 작업 실행의 일부로 Nextflow가 생성한 도우미 및 로그 파일입니다. + +- **`.command.begin`**: 프로세스 호출 실행 시작과 관련된 메타데이터 +- **`.command.err`**: 프로세스 호출에서 발생한 오류 메시지(`stderr`) +- **`.command.log`**: 프로세스 호출에서 발생한 전체 로그 출력 +- **`.command.out`**: 프로세스 호출의 일반 출력(`stdout`) +- **`.command.run`**: 프로세스 호출을 실행하기 위해 Nextflow가 실행한 전체 스크립트 +- **`.command.sh`**: 프로세스 호출에서 실제로 실행된 명령 +- **`.exitcode`**: 명령에서 나온 종료 코드 + +`.command.sh` 파일은 모든 북키핑 및 작업/환경 설정을 포함하지 않고 Nextflow가 실행한 메인 명령을 알려주므로 특히 유용합니다. + +??? abstract "파일 내용" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +이것은 이전에 수동으로 실행한 것과 일치합니다. + +이 경우 프로세스 명령이 하드코딩되어 있으므로 매우 간단하지만, 나중에 과정에서 일부 변수 보간을 포함하는 프로세스 명령을 보게 될 것입니다. +실패한 실행을 문제 해결할 때 Nextflow가 코드를 어떻게 해석했고 어떤 명령이 생성되었는지 정확히 볼 수 있다는 것이 특히 가치 있습니다. + +### 1.3. 워크플로우 다시 실행 + +워크플로우를 몇 번 다시 실행한 다음 `work/` 아래의 작업 디렉토리를 살펴보십시오. + +??? abstract "디렉토리 내용" + + ```console + 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 + ``` + +각 실행에 대해 완전한 출력 및 로그 파일 세트가 있는 새 하위 디렉토리가 생성된 것을 볼 수 있습니다. +이것은 동일한 워크플로우를 여러 번 실행해도 이전 실행의 결과를 덮어쓰지 않는다는 것을 보여줍니다. + +### 요약 + +간단한 Nextflow 스크립트를 해독하고 실행하며 작업 디렉토리에서 출력 및 관련 로그 파일을 찾는 방법을 알게 되었습니다. + +### 다음 단계 + +워크플로우 출력을 더 편리한 위치에 게시하는 방법을 배웁니다. + +--- + +## 2. 출력 게시 + +방금 배운 것처럼, 파이프라인에서 생성된 출력은 여러 계층 깊이의 작업 디렉토리에 묻혀 있습니다. +이것은 의도적으로 수행된 것입니다. Nextflow가 이 디렉토리를 제어하며 우리는 상호 작용해서는 안 됩니다. +그러나 이것은 관심 있는 출력을 검색하기 불편하게 만듭니다. + +다행히 Nextflow는 [워크플로우 수준 출력 정의](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs)를 사용하여 출력을 지정된 디렉토리에 게시하는 방법을 제공합니다. + +### 2.1. 기본 사용법 + +이것은 두 가지 새로운 코드 조각이 필요합니다: + +1. `workflow` 본문 내의 `publish:` 블록에서 프로세스 출력을 선언합니다. +2. 모드 및 위치와 같은 출력 옵션을 지정하는 스크립트에 `output` 블록을 추가합니다. + +#### 2.1.1. `sayHello` 프로세스의 출력 선언 + +워크플로우 본문에 `publish:` 블록(`main:` 블록과 같은 종류의 코드 요소)을 추가하고 `sayHello()` 프로세스의 출력을 나열해야 합니다. + +워크플로우 스크립트 파일 `hello-world.nf`에 다음 코드 줄을 추가하십시오: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // 인사말을 내보냅니다 + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // 인사말을 내보냅니다 + sayHello() + } + ``` + +`sayHello().out`을 통해 프로세스의 출력을 간단히 참조하고 임의의 이름 `first_output`을 할당할 수 있습니다. + +#### 2.1.2. 스크립트에 `output:` 블록 추가 + +이제 출력 디렉토리 경로가 지정될 `output:` 블록을 추가하기만 하면 됩니다. 이 새 블록은 스크립트 내에서 `workflow` 블록 **외부** 및 **아래**에 위치합니다. + +워크플로우 스크립트 파일 `hello-world.nf`에 다음 코드 줄을 추가하십시오: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // 인사말을 내보냅니다 + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // 인사말을 내보냅니다 + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +이것을 사용하여 `workflow` 블록에 선언된 모든 프로세스 출력에 특정 경로를 할당할 수 있습니다. +나중에 정교한 출력 디렉토리 구조를 생성하는 방법을 배우겠지만, 지금은 단순함을 위해 최소한의 경로만 하드코딩합니다. + +#### 2.1.3. 워크플로우 실행 + +이제 수정된 워크플로우 스크립트를 실행하십시오: + +```bash +nextflow run hello-world.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +터미널 출력은 익숙해 보일 것입니다. 외부적으로는 아무것도 변경되지 않았습니다. + +그러나 파일 탐색기를 확인하십시오: 이번에는 Nextflow가 `results/`라는 새 디렉토리를 생성했습니다. + +??? abstract "디렉토리 내용" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +`results` 디렉토리 안에는 방금 실행한 명령에 의해 작업 디렉토리에 생성된 `output.txt`에 대한 심볼릭 링크가 있습니다. + +이를 통해 작업 하위 디렉토리를 뒤지지 않고도 출력 파일을 쉽게 검색할 수 있습니다. + +### 2.2. 사용자 정의 위치 설정 + +기본 위치가 있는 것은 좋지만 결과가 저장되는 위치와 구성 방법을 사용자 정의하고 싶을 수 있습니다. + +예를 들어, 출력을 하위 디렉토리로 구성하고 싶을 수 있습니다. +가장 간단한 방법은 출력별로 특정 출력 경로를 할당하는 것입니다. + +#### 2.2.1. 출력 경로 수정 + +특정 출력의 게시 동작을 수정하는 것은 정말 간단합니다. +사용자 정의 위치를 설정하려면 `path`를 적절하게 편집하기만 하면 됩니다: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +개별 출력 수준에서 설정되므로 필요에 맞게 다른 위치와 하위 디렉토리를 지정할 수 있습니다. + +#### 2.2.2. 워크플로우 다시 실행 + +시도해 보겠습니다. + +```bash +nextflow run hello-world.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +이번에는 결과가 지정된 하위 디렉토리 아래에 기록됩니다. + +??? abstract "디렉토리 내용" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +이전 실행의 결과도 여전히 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +원하는 만큼 중첩 수준을 사용할 수 있습니다. +프로세스 이름이나 다른 변수를 사용하여 결과를 구성하는 데 사용되는 디렉토리 이름을 지정할 수도 있으며, 최상위 출력 디렉토리의 기본 이름을 변경할 수도 있습니다(특수 변수 `outputDir`에 의해 제어됨). +이러한 옵션은 이후 교육에서 다룹니다. + +### 2.3. 게시 모드를 copy로 설정 + +기본적으로 출력은 `work` 디렉토리의 심볼릭 링크로 게시됩니다. +즉, 파일 시스템에 단일 파일만 있습니다. + +이것은 여러 복사본을 저장하고 싶지 않은 매우 큰 파일을 다룰 때 좋습니다. +그러나 어느 시점에서 작업 디렉토리를 삭제하면(곧 정리 작업을 다룰 것입니다) 파일에 대한 액세스를 잃게 됩니다. +따라서 중요한 파일의 복사본을 안전한 장소에 저장하는 계획이 필요합니다. + +쉬운 옵션 중 하나는 관심 있는 출력의 게시 모드를 copy로 전환하는 것입니다. + +#### 2.3.1. mode 지시문 추가 + +이 부분은 정말 간단합니다. +관련 워크플로우 수준 출력 정의에 `mode 'copy'`를 추가하기만 하면 됩니다: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +이것은 해당 특정 출력의 게시 모드를 설정합니다. + +#### 2.3.2. 워크플로우 다시 실행 + +시도해 보겠습니다. + +```bash +nextflow run hello-world.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +이번에는 결과를 보면 파일이 심볼릭 링크가 아닌 적절한 복사본입니다. + +??? abstract "디렉토리 내용" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +이것도 개별 출력 수준에서 설정되므로 세분화된 방식으로 게시 모드를 설정할 수 있습니다. +나중에 다단계 파이프라인으로 이동할 때 특히 유용할 것입니다. 예를 들어 최종 출력만 복사하고 중간 출력은 심볼릭 링크로 둘 수 있습니다. + +앞서 언급했듯이 출력이 게시되는 방식을 제어하는 다른 더 정교한 옵션이 있습니다. +Nextflow 여정에서 적절한 시기에 사용 방법을 보여드리겠습니다. + +### 2.4. 프로세스 수준 `publishDir` 지시문에 대한 참고 + +최근까지 출력을 게시하는 확립된 방법은 `publishDir` 지시문을 사용하여 각 개별 프로세스 수준에서 수행하는 것이었습니다. + +`sayHello` 프로세스의 출력에 대해 방금 수행한 것을 달성하려면 대신 프로세스 정의에 다음 줄을 추가했을 것입니다: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +이 코드 패턴은 이전 Nextflow 파이프라인과 프로세스 모듈 전반에 걸쳐 여전히 발견되므로 알아두는 것이 중요합니다. +그러나 향후 버전의 Nextflow 언어에서는 결국 허용되지 않을 것이므로 새 작업에서는 사용하지 않는 것이 좋습니다. + +### 요약 + +워크플로우 출력을 더 편리한 위치에 게시하는 방법을 알게 되었습니다. + +### 다음 단계 + +명령줄 매개변수를 통해 전달된 변수 입력을 제공하고 기본값을 효과적으로 활용하는 방법을 배웁니다. + +--- + +## 3. 명령줄에서 전달된 변수 입력 사용 + +현재 상태에서 워크플로우는 프로세스 명령에 하드코딩된 인사말을 사용합니다. +입력 변수를 사용하여 런타임에 인사말을 더 쉽게 변경할 수 있도록 유연성을 추가하고자 합니다. + +이를 위해 스크립트에 세 가지 변경이 필요합니다: + +1. 프로세스가 변수 입력을 기대하도록 변경 +2. 사용자 입력을 캡처하기 위한 명령줄 매개변수 설정 +3. 워크플로우 본문에서 프로세스에 입력 전달 + +이러한 변경을 한 번에 하나씩 수행해 보겠습니다. + +### 3.1. `sayHello` 프로세스가 변수 입력을 기대하도록 변경 + +프로세스 정의를 편집하여 (1) 입력 변수를 받고 (2) 명령줄에서 해당 변수를 사용해야 합니다. + +#### 3.1.1. 프로세스 정의에 입력 블록 추가 + +먼저 `greeting`이라는 입력을 받도록 프로세스 정의를 조정해 보겠습니다. + +프로세스 블록에서 다음 코드 변경을 수행하십시오: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +`greeting` 변수는 값(경로가 아님)임을 Nextflow에 알리기 위해 `val` 접두사가 붙습니다. + +#### 3.1.2. 입력 변수를 사용하도록 프로세스 명령 편집 + +이제 원래 하드코딩된 값을 받을 것으로 예상되는 입력 변수의 값으로 교체합니다. + +프로세스 블록에서 다음 코드 변경을 수행하십시오: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +`$` 기호와 중괄호(`{ }`)는 Nextflow에게 이것이 실제 입력 값으로 대체(=보간)해야 하는 변수 이름임을 알려줍니다. + +!!! tip + + 중괄호(`{ }`)는 이전 버전의 Nextflow에서는 기술적으로 선택 사항이었으므로 `echo '$greeting' > output.txt`로 작성된 이전 워크플로우를 볼 수 있습니다. + +이제 `sayHello()` 프로세스가 변수 입력을 받을 준비가 되었으므로 워크플로우 수준에서 프로세스 호출에 입력 값을 제공하는 방법이 필요합니다. + +### 3.2. 사용자 입력을 캡처하기 위한 명령줄 매개변수 설정 + +`sayHello('Hello World!')`를 프로세스 호출로 만들어 입력을 직접 하드코딩할 수 있습니다. +그러나 워크플로우로 실제 작업을 수행할 때는 명령줄에서 입력을 제어할 수 있어야 합니다. + +좋은 소식: Nextflow에는 CLI 매개변수를 쉽게 선언하고 사용할 수 있는 `params`라는 내장 워크플로우 매개변수 시스템이 있습니다. + +일반적인 구문은 `params.<parameter_name>`을 선언하여 Nextflow에게 명령줄에서 `--<parameter_name>` 매개변수를 기대하도록 알리는 것입니다. + +여기서는 `--input`이라는 매개변수를 만들고 싶으므로 워크플로우 어딘가에 `params.input`을 선언해야 합니다. +원칙적으로 어디에나 쓸 수 있지만, `sayHello()` 프로세스 호출에 전달해야 하므로 `sayHello(params.input)`을 작성하여 직접 연결할 수 있습니다. + +워크플로우 블록에서 다음 코드 변경을 수행하십시오: + +=== "이후" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // 인사말을 내보냅니다 + sayHello(params.input) + ``` + +=== "이전" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // 인사말을 내보냅니다 + sayHello() + ``` + +이것은 Nextflow에게 `--input` 매개변수를 통해 제공된 값으로 `sayHello` 프로세스를 실행하도록 지시합니다. + +사실상 섹션 시작 부분에 설명된 단계 (2)와 (3)을 한 번에 달성했습니다. + +### 3.3. 워크플로우 명령 실행 + +실행해 보겠습니다! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +이러한 편집을 모두 올바르게 수행했다면 또 다른 성공적인 실행을 얻어야 합니다. + +출력 파일을 열어 이제 새 버전의 인사말이 있는지 확인하십시오. + +??? abstract "파일 내용" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +새 실행이 `results` 디렉토리에 게시된 출력 파일을 덮어썼습니다. +그러나 이전 실행의 결과는 여전히 `work` 아래의 작업 디렉토리에 보존되어 있습니다. + +!!! tip + + Nextflow 수준 매개변수와 파이프라인 수준 매개변수를 쉽게 구분할 수 있습니다. + + - 파이프라인에 적용되는 매개변수는 항상 이중 하이픈(`--`)을 사용합니다. + - Nextflow 설정을 수정하는 매개변수, 예를 들어 앞서 사용한 `-resume` 기능은 단일 하이픈(`-`)을 사용합니다. + +### 3.4. 명령줄 매개변수에 기본값 사용 + +좋습니다. 편리했지만, 많은 경우 모든 실행에 지정할 필요가 없도록 매개변수에 기본값을 제공하는 것이 좋습니다. + +#### 3.4.1. CLI 매개변수에 기본값 설정 + +워크플로우 정의 전에 `input` 매개변수를 선언하여 기본값을 제공해 보겠습니다. + +```groovy title="hello-world.nf" linenums="20" +/* + * 파이프라인 매개변수 + */ +params { + input: String = 'Holà mundo!' +} +``` + +보시다시피 워크플로우가 기대하는 입력 유형을 지정할 수 있습니다(Nextflow 25.10.2 이상). +구문은 `name: Type = default_value`입니다. +지원되는 유형에는 `String`, `Integer`, `Float`, `Boolean`, `Path`가 포함됩니다. + +!!! info + + 이전 워크플로우에서는 전체 `params` 블록이 `input = 'Holà mundo!'`로만 작성된 것을 볼 수 있습니다. + +파이프라인에 더 많은 매개변수를 추가할 때 기본값을 제공해야 하든 아니든 이 블록에 모두 추가해야 합니다. +이렇게 하면 한눈에 모든 구성 가능한 매개변수를 쉽게 찾을 수 있습니다. + +#### 3.4.2. 매개변수를 지정하지 않고 워크플로우 다시 실행 + +기본값이 설정되었으므로 명령줄에서 값을 지정하지 않고 워크플로우를 다시 실행할 수 있습니다. + +```bash +nextflow run hello-world.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +출력은 이전과 같은 위치에 있지만 내용은 새 텍스트로 업데이트되어야 합니다. + +??? abstract "파일 내용" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow는 인사말 매개변수의 기본값을 사용하여 출력을 생성했습니다. + +#### 3.4.3. 기본값 재정의 + +명령줄에서 매개변수를 제공하면 CLI 값이 기본값을 재정의합니다. + +시도해 보십시오: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +다시 한번 results 디렉토리에서 해당하는 업데이트된 출력을 찾을 수 있습니다. + +??? abstract "파일 내용" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note + + Nextflow에서는 매개변수 값을 지정할 수 있는 여러 곳이 있습니다. + 동일한 매개변수가 여러 곳에서 다른 값으로 설정된 경우 Nextflow는 [여기](https://www.nextflow.io/docs/latest/config.html)에 설명된 우선순위에 따라 사용할 값을 결정합니다. + + Part 6(Configuration)에서 이에 대해 더 자세히 다룹니다. + +### 요약 + +명령줄 매개변수를 통해 런타임에 제공되는 간단한 변수 입력을 사용하는 방법과 기본값을 설정, 사용 및 재정의하는 방법을 알게 되었습니다. + +### 다음 단계 + +워크플로우 실행을 더 편리하게 관리하는 방법을 배웁니다. + +--- + +## 4. 워크플로우 실행 관리 + +워크플로우를 시작하고 출력을 검색하는 방법을 아는 것은 좋지만, 특히 자체 워크플로우를 개발하는 경우 워크플로우 관리의 몇 가지 다른 측면이 생활을 더 쉽게 만들어 줄 것입니다. + +여기서는 동일한 워크플로우를 다시 실행해야 할 때 `resume` 기능을 사용하는 방법, `nextflow log`로 과거 실행 로그를 검사하는 방법, `nextflow clean`으로 이전 작업 디렉토리를 삭제하는 방법을 보여드립니다. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. `-resume`으로 워크플로우 다시 실행 + +때로는 이전에 이미 실행한 파이프라인을 이미 성공적으로 완료된 단계를 다시 수행하지 않고 다시 실행하고 싶을 것입니다. + +Nextflow에는 이를 수행할 수 있는 `-resume`이라는 옵션이 있습니다. +구체적으로 이 모드에서는 정확히 동일한 코드, 설정 및 입력으로 이미 실행된 프로세스가 건너뛰어집니다. +이것은 Nextflow가 마지막 실행 이후 추가하거나 수정한 프로세스 또는 새 설정이나 입력을 제공하는 프로세스만 실행한다는 것을 의미합니다. + +이렇게 하는 두 가지 주요 이점이 있습니다: + +- 파이프라인을 개발하는 중이라면 변경 사항을 테스트하기 위해 현재 작업 중인 프로세스만 실행하면 되므로 더 빠르게 반복할 수 있습니다. +- 프로덕션에서 파이프라인을 실행하고 문제가 발생하면 많은 경우 문제를 수정하고 파이프라인을 다시 실행하면 실패 지점부터 실행이 재개되어 많은 시간과 컴퓨팅을 절약할 수 있습니다. + +사용하려면 명령에 `-resume`을 추가하고 실행하기만 하면 됩니다: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "명령 출력" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +콘솔 출력은 익숙해 보이지만, 이전과 약간 다른 점이 있습니다. + +프로세스 상태 줄(5줄)에 추가된 `cached:` 비트를 찾으십시오. 이것은 Nextflow가 이 작업을 이미 수행했음을 인식하고 이전 성공적인 실행의 결과를 단순히 재사용했음을 의미합니다. + +작업 하위 디렉토리 해시가 이전 실행과 동일한 것도 볼 수 있습니다. +Nextflow는 문자 그대로 이전 실행을 가리키며 "이미 저기서 했습니다"라고 말합니다. + +!!! tip + + `resume`으로 파이프라인을 다시 실행하면 Nextflow는 이전에 성공적으로 실행된 실행에서 작업 디렉토리 외부에 게시된 파일을 덮어쓰지 않습니다. + +### 4.2. 과거 실행 로그 검사 + +새 파이프라인을 개발하든 프로덕션에서 파이프라인을 실행하든 어느 시점에서 과거 실행에 대한 정보를 찾아야 할 것입니다. +방법은 다음과 같습니다. + +nextflow 워크플로우를 시작할 때마다 현재 작업 디렉토리의 `.nextflow`라는 숨겨진 디렉토리 아래의 `history`라는 로그 파일에 줄이 기록됩니다. + +??? abstract "파일 내용" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +이 파일은 현재 작업 디렉토리 내에서 시작된 모든 Nextflow 실행의 타임스탬프, 실행 이름, 상태, 리비전 ID, 세션 ID 및 전체 명령줄을 제공합니다. + +이 정보에 액세스하는 더 편리한 방법은 `nextflow log` 명령을 사용하는 것입니다. + +```bash +nextflow log +``` + +??? success "명령 출력" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +이것은 헤더 줄이 추가된 로그 파일의 내용을 터미널에 출력합니다. + +새 `nextflow run` 명령을 실행할 때마다 세션 ID가 변경되지만 `-resume` 옵션을 사용하는 경우는 제외됩니다. +이 경우 세션 ID는 동일하게 유지됩니다. + +Nextflow는 세션 ID를 사용하여 `.nextflow` 아래에도 위치한 `cache` 디렉토리 아래에 실행 캐싱 정보를 그룹화합니다. + +### 4.3. 이전 작업 디렉토리 삭제 + +개발 과정에서 일반적으로 초안 파이프라인을 많이 실행하여 많은 하위 디렉토리에 많은 파일이 축적될 수 있습니다. + +다행히 Nextflow에는 더 이상 관심 없는 과거 실행의 작업 하위 디렉토리를 자동으로 삭제할 수 있는 유용한 `clean` 하위 명령이 포함되어 있습니다. + +#### 4.3.1. 삭제 기준 결정 + +삭제할 항목을 결정하는 여러 [옵션](https://www.nextflow.io/docs/latest/reference/cli.html#clean)이 있습니다. + +여기서는 실행 이름을 사용하여 지정된 실행 이전의 모든 실행에서 하위 디렉토리를 삭제하는 예제를 보여드립니다. + +`-resume`을 사용하지 않은 가장 최근 성공적인 실행을 찾으십시오. 우리의 경우 실행 이름은 `golden_cantor`였습니다. + +실행 이름은 `Launching (...)` 콘솔 출력 줄의 대괄호 안에 표시된 기계 생성 두 부분 문자열입니다. +Nextflow 로그를 사용하여 타임스탬프 및/또는 명령줄을 기반으로 실행을 조회할 수도 있습니다. + +#### 4.3.2. 드라이 런 수행 + +먼저 드라이 런 플래그 `-n`을 사용하여 명령이 주어졌을 때 무엇이 삭제될지 확인합니다: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "명령 출력" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +출력에는 다른 작업 디렉토리 이름이 있고 줄 수가 다를 수 있지만 예제와 비슷하게 보일 것입니다. + +줄이 출력되지 않으면 유효한 실행 이름을 제공하지 않았거나 삭제할 과거 실행이 없는 것입니다. 예제 명령에서 `golden_cantor`를 로그의 해당 최신 실행 이름으로 변경하십시오. + +#### 4.3.3. 삭제 진행 + +출력이 예상대로 보이고 삭제를 진행하려면 `-n` 대신 `-f` 플래그를 사용하여 명령을 다시 실행하십시오: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "명령 출력" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +출력은 이전과 비슷하지만 이제 'Would remove' 대신 'Removed'라고 표시됩니다. +이것은 두 문자 하위 디렉토리(위의 `a3/`와 같은)를 제거하지 않지만 내용을 비웁니다. + +!!! Warning + + 과거 실행의 작업 하위 디렉토리를 삭제하면 Nextflow 캐시에서 제거되고 해당 디렉토리에 저장된 모든 출력이 삭제됩니다. + 이것은 해당 프로세스를 다시 실행하지 않고 실행을 재개하는 Nextflow의 기능을 중단시킵니다. + + 관심 있거나 의존하려는 출력을 저장하는 것은 귀하의 책임입니다! 이것이 `publish` 지시문에 `symlink` 모드보다 `copy` 모드를 선호하는 주된 이유입니다. + +### 요약 + +특정 디렉토리에 출력을 게시하고, 이미 동일한 방식으로 실행된 단계를 반복하지 않고 파이프라인을 다시 실행하고, `nextflow clean` 명령을 사용하여 이전 작업 디렉토리를 정리하는 방법을 알게 되었습니다. + +더 일반적으로 간단한 Nextflow 워크플로우를 해석하고 실행을 관리하며 출력을 검색하는 방법을 알게 되었습니다. + +### 다음 단계 + +잠시 쉬세요, 받을 자격이 있습니다! + +준비가 되면 [**Part 2: Hello Channels**](./02_hello_channels.md)로 이동하여 채널을 사용하여 워크플로우에 입력을 공급하는 방법을 배우십시오. 이를 통해 Nextflow의 내장 데이터 흐름 병렬 처리 및 기타 강력한 기능을 활용할 수 있습니다. + +--- + +## 퀴즈 + +<quiz> +Nextflow 프로세스의 최소 필수 구성 요소는 무엇입니까? +- [ ] 입력 및 출력 블록만 +- [x] 출력 및 스크립트 블록 +- [ ] 입력, 출력 및 스크립트 블록 +- [ ] 스크립트 블록만 + +자세히 알아보기: [1.1.1. 프로세스 정의](#111-process-정의) +</quiz> + +<quiz> +프로세스에서 출력 블록의 목적은 무엇입니까? +- [ ] 결과를 콘솔에 출력 +- [ ] 작업 디렉토리에 파일 저장 +- [x] 프로세스에서 예상되는 출력 선언 +- [ ] 환경 변수 정의 + +자세히 알아보기: [1.1.1. 프로세스 정의](#111-process-정의) +</quiz> + +<quiz> +Nextflow 워크플로우를 실행하는 데 사용되는 명령은 무엇입니까? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +작업의 작업 디렉토리를 보면 실제로 실행된 명령이 포함된 파일은 무엇입니까? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +자세히 알아보기: [1.2.2. `work` 디렉토리에서 출력 및 로그 찾기](#122-work-디렉토리에서-출력-및-로그-찾기) +</quiz> + +<quiz> +`-resume` 플래그는 무엇을 합니까? +- [ ] 워크플로우를 처음부터 다시 시작 +- [ ] 워크플로우 일시 중지 +- [x] 이미 성공적으로 완료된 프로세스 건너뛰기 +- [ ] 워크플로우 백업 생성 + +자세히 알아보기: [4.1. `-resume`으로 워크플로우 다시 실행](#41--resume으로-워크플로우-다시-실행) +</quiz> + +<quiz> +워크플로우 출력 게시의 기본 모드는 무엇입니까? +- [ ] 출력 디렉토리에 파일 복사 +- [x] 출력 디렉토리에 심볼릭 링크 생성 +- [ ] 출력 디렉토리로 파일 이동 +- [ ] 출력 디렉토리에 파일 압축 + +자세히 알아보기: [2.3. 게시 모드를 copy로 설정](#23-게시-모드를-copy로-설정) +</quiz> + +<quiz> +명령줄에서 Nextflow 워크플로우에 매개변수 값을 어떻게 전달합니까? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +자세히 알아보기: [3.2. 사용자 입력을 캡처하기 위한 명령줄 매개변수 설정](#32-사용자-입력을-캡처하기-위한-명령줄-매개변수-설정) +</quiz> + +<quiz> +Nextflow 스크립트 블록 내에서 변수를 어떻게 참조합니까? +- [ ] `%variable%` 구문 사용 +- [x] `#!groovy ${variable}` 구문 사용 +- [ ] `{{variable}}` 구문 사용 +- [ ] `[variable]` 구문 사용 +</quiz> diff --git a/docs/ko/docs/hello_nextflow/02_hello_channels.md b/docs/ko/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..ccd9e19266 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1430 @@ +# 파트 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하십시오. + +:green_book: 비디오 스크립트는 [여기](./transcripts/02_hello_channels.md)에서 확인하실 수 있습니다. +/// + +이 과정의 파트 1(Hello World)에서는 process 호출에서 직접 입력을 제공하여 process에 변수 입력을 전달하는 방법을 보여드렸습니다: `sayHello(params.input)`. +이것은 의도적으로 단순화된 접근 방식이었습니다. +실제로 이 접근 방식은 주요한 제한 사항이 있습니다. 즉, 단일 값에 대해 process를 한 번만 실행하려는 매우 간단한 경우에만 작동합니다. +대부분의 실제 workflow 사용 사례에서는 여러 값(예: 여러 샘플의 실험 데이터)을 처리하려고 하므로 입력을 처리하는 더 정교한 방법이 필요합니다. + +이것이 바로 Nextflow **channel**의 역할입니다. +Channel은 입력을 효율적으로 처리하고 다단계 workflow에서 한 단계에서 다른 단계로 입력을 전달하도록 설계된 큐(queue)이며, 내장된 병렬 처리와 많은 추가적인 이점을 제공합니다. + +이 파트에서는 다양한 소스에서 여러 입력을 처리하기 위해 channel을 사용하는 방법을 배웁니다. +또한 필요에 따라 channel 내용을 변환하기 위해 **연산자**를 사용하는 방법도 배웁니다. + +??? info "이 섹션부터 시작하는 방법" + + 이 섹션은 [Hello Nextflow](./index.md) 과정의 파트 1을 완료했다고 가정하지만, 해당 섹션에서 다룬 기본 사항에 익숙하다면 특별한 준비 없이 여기서 시작할 수 있습니다. + +--- + +## 0. 워밍업: `hello-channels.nf` 실행 + +시작점으로 workflow 스크립트 `hello-channels.nf`를 사용할 것입니다. +이 스크립트는 이 교육 과정의 파트 1을 완료하여 생성된 스크립트와 동일하지만, 출력 대상을 변경했습니다: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +변경을 시작하기 전에 모든 것이 제대로 작동하는지 확인하기 위해 스크립트를 한 번 실행하십시오: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +이전과 마찬가지로, 위에 표시된 workflow 스크립트의 `output` 블록에 지정된 대로 `results/hello_channels` 디렉토리에서 `output.txt`라는 이름의 출력 파일을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "파일 내용" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +이것이 정상적으로 작동했다면 channel에 대해 배울 준비가 되었습니다. + +--- + +## 1. Channel을 통해 명시적으로 변수 입력 제공 + +암묵적 처리에 의존하는 대신, `sayHello()` process에 변수 입력을 전달하기 위해 **channel**을 생성할 것입니다. 암묵적 처리에는 특정 제한 사항이 있습니다. + +### 1.1. 입력 channel 생성 + +Channel을 설정하는 데 사용할 수 있는 다양한 **channel 팩토리**가 있습니다. +지금은 간단하게 유지하기 위해 단일 값을 포함하는 channel을 생성하는 `channel.of`라는 가장 기본적인 channel 팩토리를 사용할 것입니다. +기능적으로는 이전에 설정한 방식과 유사하지만, Nextflow가 암묵적으로 channel을 생성하는 대신 명시적으로 수행합니다. + +사용할 코드 라인입니다: + +```console title="구문" +greeting_ch = channel.of('Hello Channels!') +``` + +이것은 `channel.of()` channel 팩토리를 사용하여 `greeting_ch`라는 channel을 생성하며, 간단한 queue channel을 설정하고 인사 값으로 사용할 문자열 `'Hello Channels!'`를 로드합니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "참고" + + 가독성을 위해 CLI 매개변수 대신 임시로 하드코딩된 문자열로 전환합니다. Channel 수준에서 무슨 일이 일어나는지 다룬 후에 CLI 매개변수 사용으로 돌아갈 것입니다. + +workflow 블록에서 channel 팩토리 코드를 추가하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels!') + // 인사말을 내보냅니다 + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // 인사말을 내보냅니다 + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +아직 process 호출의 입력을 전환하지 않았으므로 아직 작동하지 않습니다. + +### 1.2. Process 호출에 channel을 입력으로 추가 + +이제 새로 생성한 channel을 `sayHello()` process 호출에 연결하여 이전에 직접 제공하던 CLI 매개변수를 대체해야 합니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels!') + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels!') + // 인사말을 내보냅니다 + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +이것은 Nextflow에게 `greeting_ch` channel의 내용에 대해 `sayHello` process를 실행하도록 지시합니다. + +이제 workflow가 제대로 작동합니다; 이것은 `sayHello('Hello Channels!')`를 작성하는 것과 동일한 명시적 표현입니다. + +### 1.3. Workflow 실행 + +실행해 봅시다! + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +두 편집을 모두 올바르게 수행했다면 성공적으로 실행될 것입니다. +results 디렉토리를 확인하여 결과가 이전과 동일한지 확인할 수 있습니다. + +??? abstract "파일 내용" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +동일한 최종 결과를 얻으면서 workflow의 유연성을 높였습니다. +더 많은 코드를 작성하면서 실질적인 이점이 없는 것처럼 보일 수 있지만, 더 많은 입력을 처리하기 시작하면 그 가치가 명확해질 것입니다. + +다음으로 넘어가기 전에 한 가지 더 살펴보겠습니다: 데이터 입력 관리를 위해 명시적 channel을 사용하는 것의 작지만 편리한 이점입니다. + +### 1.4. `view()`를 사용하여 channel 내용 검사 + +Nextflow channel은 연산자를 사용하여 내용을 조작할 수 있도록 설계되어 있으며, 이에 대해서는 이 장의 후반부에서 자세히 다룰 것입니다. + +지금은 channel의 내용을 검사하기 위해 [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view)라는 매우 간단한 연산자를 사용하는 방법만 보여드리겠습니다. +`view()`를 Python의 `print()` 문이나 다른 언어의 동등한 것과 같은 디버깅 도구로 생각할 수 있습니다. + +workflow 블록에 이 작은 라인을 추가하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels!') + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels!') + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +정확한 공백 수는 4의 배수인 한 중요하지 않습니다; `.view()` 문의 시작을 channel 구성의 `.of()` 부분에 맞추는 것이 목표입니다. + +이제 workflow를 다시 실행하십시오: + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +보시다시피 channel 내용이 콘솔에 출력됩니다. +여기서는 요소가 하나뿐이지만, 다음 섹션에서 channel에 여러 값을 로드하기 시작하면 줄당 하나의 요소가 출력되도록 설정되어 있는 것을 볼 수 있습니다. + +### 핵심 내용 + +기본 channel 팩토리를 사용하여 process에 입력을 제공하는 방법을 알게 되었습니다. + +### 다음 단계 + +Channel을 사용하여 workflow가 여러 입력 값을 반복 처리하도록 하는 방법을 배웁니다. + +--- + +## 2. Workflow를 수정하여 여러 입력 값에서 실행 + +Workflow는 일반적으로 대량으로 처리해야 하는 입력 배치에서 실행되므로, workflow를 업그레이드하여 여러 입력 값을 허용하도록 해야 합니다. + +### 2.1. 입력 channel에 여러 인사말 로드 + +편리하게도, 사용해 온 `channel.of()` channel 팩토리는 둘 이상의 값을 기꺼이 허용하므로 전혀 수정할 필요가 없습니다. +Channel에 여러 값을 로드하기만 하면 됩니다. + +`'Hello'`, `'Bonjour'`, `'Holà'`로 만들어 봅시다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_다이어그램에서 channel은 녹색으로 표시되며, 요소의 순서는 파이프 안의 구슬처럼 표현됩니다: 처음 로드된 것이 오른쪽에, 두 번째가 중간에, 세 번째가 왼쪽에 있습니다._ + +#### 2.1.1. 더 많은 인사말 추가 + +workflow 블록 전에 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // 입력용 channel 생성 + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // 입력용 channel 생성 + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +문서에 따르면 이것이 작동해야 합니다. 정말 이렇게 간단할 수 있을까요? + +#### 2.1.2. 명령을 실행하고 로그 출력 확인 + +시도해 봅시다. + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +확실히 잘 실행된 것 같습니다. +실행 모니터는 `sayHello` process에 대해 `3 of 3` 호출이 이루어졌음을 보여주며, 약속한 대로 `view()` 문에 의해 세 개의 인사말이 줄당 하나씩 나열되어 있습니다. + +그러나 results 디렉토리에는 여전히 하나의 출력만 있습니다: + +??? abstract "디렉토리 내용" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "파일 내용" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +세 개의 인사말 중 하나가 있어야 하지만, 여기에 표시된 것과 다를 수 있습니다. +왜 그럴 수 있는지 생각해 보셨습니까? + +실행 모니터를 다시 살펴보면, 하나의 하위 디렉토리 경로(`f4/c9962c`)만 제공했습니다. +그 안을 살펴봅시다. + +??? abstract "디렉토리 내용" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "파일 내용" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +results 디렉토리에서 얻은 것과 같은 인사말도 아닙니다! 무슨 일이 일어나고 있는 걸까요? + +이 시점에서 기본적으로 ANSI 로깅 시스템은 동일한 process에 대한 여러 호출의 로깅을 같은 줄에 기록한다는 것을 알려드려야 합니다. +따라서 sayHello() process에 대한 세 번의 호출 상태가 모두 같은 위치에 표시됩니다. + +다행히도 전체 process 호출 목록을 볼 수 있도록 해당 동작을 비활성화할 수 있습니다. + +#### 2.1.3. `-ansi-log false` 옵션으로 명령을 다시 실행 + +로깅을 확장하여 process 호출당 한 줄씩 표시하려면 명령에 `-ansi-log false`를 추가하십시오. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +이번에는 세 개의 process 실행과 관련 작업 하위 디렉토리가 모두 출력에 나열됩니다. + +훨씬 낫습니다, 적어도 간단한 workflow에서는요. +복잡한 workflow나 많은 수의 입력의 경우 전체 목록이 터미널에 출력되면 다소 압도적일 수 있습니다. +그래서 `-ansi-log false`가 기본 동작이 아닙니다. + +!!! tip "팁" + + 상태가 보고되는 방식은 두 로깅 모드 간에 약간 다릅니다. + 압축 모드에서 Nextflow는 호출이 성공적으로 완료되었는지 여부를 보고합니다. + 이 확장 모드에서는 제출되었다는 것만 보고합니다. + +어쨌든 이제 각 process 호출의 하위 디렉토리가 있으므로 로그와 출력을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "파일 내용" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +이것은 세 개의 process가 모두 성공적으로 실행되었음을 보여줍니다. + +그렇긴 하지만, results 디렉토리에 여전히 하나의 출력 파일만 있다는 문제가 있습니다. + +`sayHello` process의 출력 파일 이름을 하드코딩했기 때문에 세 번의 호출 모두 `output.txt`라는 파일을 생성했던 것을 기억하실 것입니다. + +출력 파일이 다른 process와 격리된 작업 하위 디렉토리에 있는 한 괜찮습니다. +그러나 동일한 results 디렉토리에 게시되면 먼저 복사된 것이 다음 것에 의해 덮어쓰여지고, 계속 반복됩니다. + +### 2.2. 출력 파일 이름이 고유하도록 보장 + +모든 출력을 동일한 results 디렉토리에 계속 게시할 수 있지만 고유한 이름을 갖도록 해야 합니다. +구체적으로, 최종 파일 이름이 고유하도록 동적으로 파일 이름을 생성하도록 첫 번째 process를 수정해야 합니다. + +그러면 파일 이름을 어떻게 고유하게 만들까요? +일반적인 방법은 입력(입력 channel에서 받은)의 고유한 메타데이터 조각을 출력 파일 이름의 일부로 사용하는 것입니다. +여기서는 편의상 인사말 자체가 짧은 문자열이므로 그것을 사용하여 기본 출력 파일명 앞에 추가하겠습니다. + +#### 2.2.1. 동적 출력 파일 이름 구성 + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +출력 정의와 `script:` 명령 블록 모두에서 `output.txt`를 교체해야 합니다. + +!!! tip "팁" + + 출력 정의에서 출력 파일명 표현식 주위에 큰따옴표를 사용해야 합니다(작은따옴표가 아님). 그렇지 않으면 실패합니다. + +이렇게 하면 process가 호출될 때마다 고유한 출력 파일 이름이 생성되어 출력 디렉토리에서 동일한 process에 대한 다른 호출의 출력과 구별될 수 있습니다. + +#### 2.2.2. Workflow 실행 + +실행해 봅시다. 기본 ANSI 로그 설정으로 다시 실행합니다. + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +요약 보기로 돌아가면 출력이 다시 한 줄로 요약됩니다. +`results` 디렉토리를 확인하여 모든 출력 인사말이 있는지 확인하십시오. + +??? abstract "디렉토리 내용" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +그렇습니다! 각각 예상한 내용이 들어 있습니다. + +??? abstract "파일 내용" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +성공입니다! 이제 출력 파일이 덮어쓰여지는 것에 대해 걱정하지 않고 원하는 만큼 많은 인사말을 추가할 수 있습니다. + +!!! tip "팁" + + 실제로 입력 데이터 자체를 기반으로 파일 이름을 지정하는 것은 거의 항상 비실용적입니다. + 동적 파일 이름을 생성하는 더 좋은 방법은 입력 파일과 함께 메타데이터를 process에 전달하는 것입니다. + 메타데이터는 일반적으로 'sample sheet' 또는 이와 동등한 것을 통해 제공됩니다. + 나중에 Nextflow 교육에서 이를 수행하는 방법을 배우게 됩니다([메타데이터 사이드 퀘스트](../side_quests/metadata.md) 참조). + +### 핵심 내용 + +Channel을 통해 여러 입력 요소를 공급하는 방법을 알게 되었습니다. + +### 다음 단계 + +연산자를 사용하여 channel의 내용을 변환하는 방법을 배웁니다. + +--- + +## 3. 배열을 통해 여러 입력 제공 + +방금 channel 팩토리에 직접 하드코딩된 여러 입력 요소를 처리하는 방법을 보여드렸습니다. +다른 방식으로 여러 입력을 제공하려면 어떻게 해야 할까요? + +예를 들어, 다음과 같이 요소 배열을 포함하는 입력 변수를 설정한다고 상상해 보십시오: + +`greetings_array = ['Hello','Bonjour','Holà']` + +이것을 출력 channel에 로드하고 작동할 것으로 기대할 수 있을까요? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +알아봅시다. + +### 3.1. Channel에 값 배열을 입력으로 제공 + +상식적으로 단일 값 대신 값 배열을 간단히 전달할 수 있어야 합니다. +시도해 봅시다; 입력 변수를 설정하고 channel 팩토리에 로드해야 합니다. + +#### 3.1.1. 입력 변수 설정 + +방금 상상한 `greetings_array` 변수를 workflow 블록에 추가하여 현실로 만들어 봅시다: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // 입력용 channel 생성 + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +아직 작동하지 않습니다. 배열에 대한 선언만 추가했습니다. + +#### 3.1.2. Channel 팩토리에 인사말 배열을 입력으로 설정 + +이제 channel 팩토리에 현재 하드코딩된 값 `'Hello','Bonjour','Holà'`를 방금 생성한 `greetings_array`로 교체할 것입니다. + +workflow 블록에서 다음 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +이제 작동해야 합니다. + +#### 3.1.3. Workflow 실행 + +실행해 봅시다: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "명령 출력" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +오류가 발생했습니다! + +`view()`의 출력과 오류 메시지를 살펴보십시오. + +Nextflow가 배열의 세 문자열을 별도의 값으로 사용하는 대신 `[Hello, Bonjour, Holà]`를 문자열 값으로 사용하여 단일 process 호출을 실행하려고 시도한 것 같습니다. + +따라서 '패키징'이 문제를 일으키고 있습니다. +Nextflow가 배열을 풀고 개별 문자열을 channel에 로드하도록 하려면 어떻게 해야 할까요? + +### 3.2. 연산자를 사용하여 channel 내용 변환 + +여기서 **[연산자](https://www.nextflow.io/docs/latest/reference/operator.html)**가 등장합니다. +내부 내용을 확인하는 `.view()` 연산자를 이미 사용했습니다. +이제 channel의 내용에 대해 작업할 수 있는 연산자를 살펴보겠습니다. + +Nextflow 문서의 [연산자 목록](https://www.nextflow.io/docs/latest/reference/operator.html)을 훑어보면, 정확히 필요한 것을 수행하는 [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten)을 찾을 수 있습니다: 배열의 내용을 풀고 개별 항목으로 내보냅니다. + +#### 3.2.1. `flatten()` 연산자 추가 + +입력 channel에 `flatten()` 연산자를 적용하려면 channel 팩토리 선언에 추가합니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +여기서 가독성을 위해 다음 줄에 연산자를 추가했지만, 원한다면 다음과 같이 channel 팩토리와 같은 줄에 연산자를 추가할 수 있습니다: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. `view()` 문 개선 + +이것이 작동하는지 테스트하기 위해 바로 실행할 수 있지만, 그러는 김에 channel 내용을 검사하는 방식을 개선하겠습니다. + +`flatten()` 연산자가 적용되기 전과 후의 내용이 어떻게 보이는지 대조할 수 있도록 두 번째 것을 추가하고, 출력에서 더 명확하게 레이블이 지정되도록 약간의 코드를 추가하겠습니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +두 번째 `.view` 문을 추가했으며, 각각에 대해 빈 괄호(`()`)를 `{ greeting -> "Before flatten: $greeting" }`와 같은 코드가 포함된 중괄호로 교체했습니다. + +이것을 *클로저*라고 합니다. 포함된 코드는 channel의 각 항목에 대해 실행됩니다. +해당 클로저의 범위 내에서만 사용되는 내부 값에 대한 임시 변수를 정의합니다. 여기서는 `greeting`이라고 합니다(임의의 이름일 수 있음). + +이 예에서 `$greeting`은 channel에 로드된 각 개별 항목을 나타냅니다. +이렇게 하면 깔끔하게 레이블이 지정된 콘솔 출력이 생성됩니다. + +!!! info "정보" + + 일부 파이프라인에서는 연산자 클로저 내에서 `$it`라는 특수 변수가 사용되는 것을 볼 수 있습니다. + 이것은 `->`로 정의할 필요 없이 내부 변수에 대한 단축 액세스를 허용하는 _암묵적_ 변수입니다. + + 코드 명확성을 위해 명시적으로 표현하는 것을 선호하므로, `$it` 구문은 권장되지 않으며 Nextflow 언어에서 점차 단계적으로 제거될 것입니다. + +#### 3.2.3. Workflow 실행 + +마지막으로 workflow를 다시 실행해 볼 수 있습니다! + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +이번에는 작동하며 `flatten()` 연산자를 실행하기 전과 후에 channel의 내용이 어떻게 보이는지에 대한 추가 통찰력을 제공합니다. + +- - 해당 시점에서 channel에는 원래 배열인 하나의 항목이 포함되어 있으므로 단일 `Before flatten:` 문이 표시됩니다. + 그런 다음 이제 channel의 개별 항목인 각 인사말에 대해 세 개의 별도 `After flatten:` 문이 표시됩니다. + +중요한 것은 이제 각 항목이 workflow에서 별도로 처리될 수 있다는 것입니다. + +!!! tip "팁" + + 작동에 암묵적 매핑 단계를 포함하는 다른 channel 팩토리인 [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist)를 사용하여 기술적으로 동일한 결과를 얻을 수 있습니다. + 여기서는 간단한 사용 사례에서 연산자 사용을 시연하기 위해 이를 사용하지 않기로 했습니다. + +### 핵심 내용 + +`flatten()`과 같은 연산자를 사용하여 channel의 내용을 변환하는 방법과 연산자를 적용하기 전과 후에 channel 내용을 검사하기 위해 `view()` 연산자를 사용하는 방법을 알게 되었습니다. + +### 다음 단계 + +Workflow가 파일을 입력 값의 소스로 사용하도록 하는 방법을 배웁니다. + +--- + +## 4. CSV 파일에서 입력 값 읽기 + +현실적으로 값 배열에서 시작하는 경우는 거의 없습니다. +대부분의 경우 일종의 구조화된 형식으로 처리해야 하는 데이터가 포함된 하나 이상의 파일이 있을 것입니다. + +실제 데이터 분석에서 처리하고자 하는 종류의 열 형식 데이터를 모방하여 여러 입력 인사말이 포함된 `greetings.csv`라는 CSV 파일을 `data/` 아래에 준비했습니다. +(숫자는 의미가 없으며 설명 목적으로만 있습니다.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +다음 작업은 이 파일에서 값을 읽도록 workflow를 조정하는 것입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +이를 구현하는 방법을 살펴봅시다. + +### 4.1. CSV 파일을 인사말 소스로 기대하도록 스크립트 수정 + +시작하려면 스크립트에 두 가지 주요 변경이 필요합니다: + +- 입력 매개변수를 CSV 파일을 가리키도록 전환 +- Channel 팩토리를 파일을 처리하도록 설계된 것으로 전환 + +#### 4.1.1. 입력 매개변수를 CSV 파일을 가리키도록 전환 + +파트 1에서 설정한 `params.input` 매개변수를 기억하십니까? +인사말이 포함된 CSV 파일을 가리키도록 업데이트하겠습니다. + +매개변수 선언을 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * 파이프라인 매개변수 + */ + input: String = 'Holà mundo!' + ``` + +이것은 파일이 workflow 코드와 같은 위치에 있다고 가정합니다. +나중에 Nextflow 여정에서 다른 데이터 위치를 다루는 방법을 배우게 됩니다. + +#### 4.1.2. 파일을 처리하도록 설계된 channel 팩토리로 전환 + +이제 입력으로 단순 문자열 대신 파일을 사용하고자 하므로 이전의 `channel.of()` channel 팩토리를 사용할 수 없습니다. +파일 경로 처리를 위한 일부 내장 기능이 있는 새로운 channel 팩토리 [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path)를 사용하도록 전환해야 합니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // 입력 인사말 배열 선언 + greetings_array = ['Hello','Bonjour','Holà'] + // 입력용 channel 생성 + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +channel 입력을 다시 `param.input`으로 전환하고, 더 이상 필요하지 않으므로 `greetings_array` 선언을 삭제했습니다. +또한 `flatten()`과 두 번째 `view()` 문을 주석 처리했습니다. + +#### 4.1.3. Workflow 실행 + +새 channel 팩토리와 입력 파일로 workflow를 실행해 봅시다. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "명령 출력" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +작동하지 않습니다. 콘솔 출력의 시작과 오류 메시지를 살펴보십시오. +`Command executed:` 부분이 특히 도움이 됩니다. + +약간 익숙해 보일 수 있습니다. +Nextflow가 파일 경로 자체를 문자열 값으로 사용하여 단일 process 호출을 실행하려고 시도한 것 같습니다. +파일 경로를 올바르게 확인했지만 실제로 원하는 내용을 구문 분석하지 않았습니다. + +Nextflow가 파일을 열고 그 내용을 channel에 로드하도록 하려면 어떻게 해야 할까요? + +또 다른 [연산자](https://www.nextflow.io/docs/latest/reference/operator.html)가 필요한 것 같습니다! + +### 4.2. `splitCsv()` 연산자를 사용하여 파일 구문 분석 + +연산자 목록을 다시 살펴보면, CSV 형식 텍스트를 구문 분석하고 분할하도록 설계된 [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv)를 찾을 수 있습니다. + +#### 4.2.1. Channel에 `splitCsv()` 적용 + +연산자를 적용하려면 이전처럼 channel 팩토리 라인에 추가합니다. + +workflow 블록에서 `flatten()`을 `splitcsv()`로 교체(주석 해제)하는 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +보시다시피 전후 `view()` 문도 업데이트했습니다. +기술적으로 동일한 변수 이름(`greeting`)을 사용할 수 있었지만, 다른 사람이 코드를 더 읽기 쉽게 하기 위해 더 적절한 것(`csv`)으로 업데이트했습니다. + +#### 4.2.2. Workflow를 다시 실행 + +추가된 CSV 구문 분석 로직으로 workflow를 실행해 봅시다. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "명령 출력" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +흥미롭게도 이것도 실패하지만 다른 오류가 발생합니다. +이번에 Nextflow는 파일 내용을 구문 분석했지만(야호!) 각 행을 배열로 로드했으며 각 배열이 channel의 요소입니다. + +각 행에서 첫 번째 열만 가져오도록 지시해야 합니다. +그러면 이것을 어떻게 풀까요? + +이전에 channel의 내용을 풀기 위해 `flatten()`을 사용했지만, flatten은 *모든 것*을 푸는 방식이므로 여기서는 작동하지 않습니다(직접 시도해 보고 싶다면 해 보십시오). + +대신 Nextflow 파이프라인에서 정말 유용하고 자주 등장하는 `map()`이라는 다른 연산자를 사용할 것입니다. + +### 4.3. `map()` 연산자를 사용하여 인사말 추출 + +[`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) 연산자는 channel의 내용에 모든 종류의 매핑을 수행할 수 있게 해주는 매우 편리한 도구입니다. + +이 경우 데이터 파일의 각 행에서 원하는 요소를 추출하는 데 사용할 것입니다. +구문은 다음과 같습니다: + +```groovy title="구문" +.map { row -> row[0] } +``` + +이것은 'channel의 각 행에 대해 포함된 0번째(첫 번째) 항목을 가져오라'는 의미입니다. + +이것을 CSV 구문 분석에 적용해 봅시다. + +#### 4.3.1. Channel에 `map()` 적용 + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +연산자가 예상대로 작동하는지 확인하기 위해 또 다른 `view()` 호출을 추가했습니다. + +#### 4.3.2. Workflow 실행 + +한 번 더 실행해 봅시다: + +```bash +nextflow run hello-channels.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +이번에는 오류 없이 실행될 것입니다. + +`view()` 문의 출력을 보면 다음을 볼 수 있습니다: + +- 단일 `Before splitCsv:` 문: 해당 시점에서 channel에는 원래 파일 경로인 하나의 항목이 포함됩니다. +- 세 개의 별도 `After splitCsv:` 문: 각 인사말에 대해 하나씩이지만 각각 파일의 해당 줄에 해당하는 배열 내에 포함되어 있습니다. +- 세 개의 별도 `After map:` 문: 각 인사말에 대해 하나씩이며 이제 channel의 개별 요소입니다. + +출력에서 줄이 다른 순서로 나타날 수 있습니다. + +출력 파일을 확인하여 각 인사말이 올바르게 추출되어 workflow를 통해 처리되었는지 확인할 수도 있습니다. + +이전과 동일한 결과를 얻었지만, 이제 코드를 수정하지 않고 입력 파일을 수정하여 처리하려는 인사말 channel에 더 많은 요소를 추가할 수 있는 훨씬 더 많은 유연성을 갖게 되었습니다. +나중 교육에서 복잡한 입력을 처리하는 더 정교한 접근 방식을 배우게 됩니다. + +### 핵심 내용 + +`.fromPath()` channel 생성자와 `splitCsv()` 및 `map()` 연산자를 사용하여 입력 값 파일을 읽고 적절하게 처리하는 방법을 알게 되었습니다. + +더 일반적으로, Nextflow가 process에 대한 입력을 관리하기 위해 **channel**을 사용하고 내용을 변환하기 위해 **연산자**를 사용하는 방법에 대한 기본적인 이해를 갖게 되었습니다. + +### 다음 단계 + +충분히 휴식을 취하십시오. 이 파트에서 열심히 작업했습니다! + +준비가 되면 [**파트 3: Hello Workflow**](./03_hello_workflow.md)로 이동하여 더 많은 단계를 추가하고 적절한 workflow로 연결하는 방법을 배우십시오. + +--- + +## 퀴즈 + +<quiz> +Nextflow에서 channel이란 무엇입니까? +- [ ] 파일 경로 지정 +- [ ] Process 정의 +- [x] Process 간 데이터 전달을 위한 큐와 같은 구조 +- [ ] 구성 설정 + +자세히 알아보기: [1.1. 입력 channel 생성](#11-입력-channel-생성) +</quiz> + +<quiz> +이 코드는 무엇을 출력합니까? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (단일 리스트) +- [x] 각 요소가 별도의 줄에: `Hello`, `Bonjour`, `Hola` +- [ ] 아무것도 (channel은 기본적으로 출력하지 않음) +- [ ] 오류 (잘못된 구문) + +자세히 알아보기: [1.1. 입력 channel 생성](#11-입력-channel-생성) +</quiz> + +<quiz> +Channel에 여러 값이 포함되어 있을 때 Nextflow는 process 실행을 어떻게 처리합니까? +- [ ] Process가 모든 값으로 한 번 실행됨 +- [x] Process가 channel의 각 값에 대해 한 번씩 실행됨 +- [ ] Process가 첫 번째 값으로만 실행됨 +- [ ] Process가 마지막 값으로만 실행됨 + +자세히 알아보기: [2. Workflow를 수정하여 여러 입력 값에서 실행](#2-workflow를-수정하여-여러-입력-값에서-실행) +</quiz> + +<quiz> +`flatten()` 연산자는 무엇을 합니까? +- [ ] 여러 channel을 하나로 결합 +- [ ] Channel 요소 정렬 +- [x] 배열을 개별 요소로 풀기 +- [ ] 중복 요소 제거 + +자세히 알아보기: [3.2.1. `flatten()` 연산자 추가](#321-flatten-연산자-추가) +</quiz> + +<quiz> +`view()` 연산자의 목적은 무엇입니까? +- [ ] Channel 내용 필터링 +- [ ] Channel 요소 변환 +- [x] Channel 내용 검사 및 디버깅 +- [ ] Channel 내용을 파일에 저장 + +자세히 알아보기: [1.4. `view()`를 사용하여 channel 내용 검사](#14-view를-사용하여-channel-내용-검사) +</quiz> + +<quiz> +`splitCsv()`는 무엇을 합니까? +- [ ] Channel 내용에서 CSV 파일 생성 +- [ ] 문자열을 쉼표로 분할 +- [x] CSV 파일을 각 행을 나타내는 배열로 구문 분석 +- [ ] 여러 CSV 파일 병합 + +자세히 알아보기: [4.2. `splitCsv()` 연산자를 사용하여 파일 구문 분석](#42-splitcsv-연산자를-사용하여-파일-구문-분석) +</quiz> + +<quiz> +`map()` 연산자의 목적은 무엇입니까? +- [ ] Channel에서 요소 필터링 +- [ ] 여러 channel 결합 +- [x] Channel의 각 요소 변환 +- [ ] Channel의 요소 수 세기 + +자세히 알아보기: [4.3. `map()` 연산자를 사용하여 인사말 추출](#43-map-연산자를-사용하여-인사말-추출) +</quiz> + +<quiz> +여러 입력을 처리할 때 동적 출력 파일 이름을 사용하는 것이 중요한 이유는 무엇입니까? +- [ ] 성능 향상 +- [ ] 디스크 공간 절약 +- [x] 출력 파일이 서로 덮어쓰이는 것을 방지 +- [ ] 재개 기능 활성화 + +자세히 알아보기: [2.2. 출력 파일 이름이 고유하도록 보장](#22-출력-파일-이름이-고유하도록-보장) +</quiz> diff --git a/docs/ko/docs/hello_nextflow/03_hello_workflow.md b/docs/ko/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..6950315e82 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# 파트 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하십시오. + +:green_book: 비디오 스크립트는 [여기](./transcripts/03_hello_workflow.md)에서 확인하실 수 있습니다. +/// + +대부분의 실제 workflow는 둘 이상의 단계를 포함합니다. +이 교육 모듈에서는 다단계 workflow에서 process를 함께 연결하는 방법을 배웁니다. + +이것은 다음을 달성하는 Nextflow 방식을 가르쳐 드릴 것입니다: + +1. 한 process에서 다음 process로 데이터 흐르게 하기 +2. 여러 process 호출의 출력을 단일 process 호출로 수집하기 +3. Process에 둘 이상의 입력 전달하기 +4. Process에서 나오는 여러 출력 처리하기 + +시연을 위해 파트 1과 2의 도메인에 구애받지 않는 Hello World 예제를 계속 구축할 것입니다. +이번에는 사람들이 실제 workflow를 구축하는 방식을 더 잘 반영하기 위해 workflow에 다음과 같은 변경을 수행할 것입니다: + +1. 인사말을 대문자로 변환하는 두 번째 단계 추가 +2. 모든 변환된 인사말을 수집하여 단일 파일에 기록하는 세 번째 단계 추가 +3. 최종 출력 파일의 이름을 지정하는 매개변수를 추가하고 이를 수집 단계에 보조 입력으로 전달 +4. 수집 단계에서 처리된 내용에 대한 간단한 통계도 보고하도록 설정 + +??? info "이 섹션부터 시작하는 방법" + + 이 섹션은 [Hello Nextflow](./index.md) 과정의 파트 1-2를 완료했다고 가정하지만, 해당 섹션에서 다룬 기본 사항에 익숙하다면 특별한 준비 없이 여기서 시작할 수 있습니다. + +--- + +## 0. 워밍업: `hello-workflow.nf` 실행 + +시작점으로 workflow 스크립트 `hello-workflow.nf`를 사용할 것입니다. +이 스크립트는 이 교육 과정의 파트 2를 완료하여 생성된 스크립트와 동일하지만, `view()` 문을 제거하고 출력 대상을 변경했습니다: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +변경을 시작하기 전에 모든 것이 제대로 작동하는지 확인하기 위해 스크립트를 한 번 실행하십시오: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +이전과 마찬가지로 `output` 블록에 지정된 위치에서 출력 파일을 찾을 수 있습니다. +이 장에서는 `results/hello_workflow/` 아래에 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +이것이 정상적으로 작동했다면 다단계 workflow를 조립하는 방법을 배울 준비가 되었습니다. + +--- + +## 1. Workflow에 두 번째 단계 추가 + +각 인사말을 대문자로 변환하는 단계를 추가할 것입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +이를 위해 세 가지를 수행해야 합니다: + +- 대문자 변환에 사용할 명령 정의 +- 대문자 변환 명령을 감싸는 새 process 작성 +- Workflow 블록에서 새 process를 호출하고 `sayHello()` process의 출력을 입력으로 받도록 설정 + +### 1.1. 대문자 변환 명령 정의 및 터미널에서 테스트 + +인사말을 대문자로 변환하기 위해 다음 구문과 함께 '텍스트 대체'를 위한 `tr`이라는 고전적인 UNIX 도구를 사용할 것입니다: + +```bash title="구문" +tr '[a-z]' '[A-Z]' +``` + +이것은 악센트가 있는 문자를 고려하지 않는 매우 단순한 텍스트 대체 한 줄 명령이므로 예를 들어 'Holà'는 'HOLà'가 됩니다. 하지만 Nextflow 개념을 시연하기에는 충분히 작동하며 그것이 중요합니다. + +테스트하려면 `echo 'Hello World'` 명령을 실행하고 그 출력을 `tr` 명령으로 파이프할 수 있습니다: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +출력은 `Hello World` 문자열의 대문자 버전이 포함된 `UPPER-output.txt`라는 텍스트 파일입니다. + +??? abstract "파일 내용" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +이것이 기본적으로 workflow로 수행하려는 것입니다. + +### 1.2. 대문자 변환 단계를 Nextflow process로 작성 + +첫 번째 process를 모델로 새 process를 만들 수 있습니다. 동일한 모든 구성 요소를 사용하려고 하기 때문입니다. + +다음 process 정의를 첫 번째 바로 아래에 workflow 스크립트에 추가하십시오: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * 텍스트 대체 도구를 사용하여 인사말을 대문자로 변환 + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +이 process에서는 첫 번째 process의 출력에 대해 원래 수행했던 것과 유사하게 입력 파일 이름을 기반으로 두 번째 출력 파일 이름을 구성합니다. + +### 1.3. Workflow 블록에 새 process 호출 추가 + +이제 방금 정의한 process를 실제로 호출하도록 Nextflow에 지시해야 합니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +`convertToUpper()` process에 무엇을 입력해야 하는지 지정하지 않았기 때문에 아직 작동하지 않습니다. + +### 1.4. 첫 번째 process의 출력을 두 번째 process로 전달 + +이제 `sayHello()` process의 출력이 `convertToUpper()` process로 흐르도록 해야 합니다. + +편리하게도 Nextflow는 자동으로 process의 출력을 `<process>.out`이라는 channel로 패키징합니다. +따라서 `sayHello` process의 출력은 `sayHello.out`이라는 channel이며, 이를 `convertToUpper()` 호출에 바로 연결할 수 있습니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // 인사말을 대문자로 변환 + convertToUpper() + ``` + +이와 같이 간단한 경우(하나의 출력에서 하나의 입력으로)에는 두 process를 연결하기 위해 이것만 하면 됩니다! + +### 1.5. Workflow 출력 게시 설정 + +마지막으로, 두 번째 process의 결과도 게시하도록 workflow 출력을 업데이트합시다. + +#### 1.5.1. `workflow` 블록의 `publish:` 섹션 업데이트 + +`workflow` 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +로직은 이전과 동일합니다. + +#### 1.5.2. `output` 블록 업데이트 + +`output` 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +다시 한 번, 로직은 이전과 동일합니다. + +이것은 모든 개별 출력에 대해 매우 세분화된 수준에서 출력 설정을 제어할 수 있음을 보여줍니다. +process 중 하나에 대해 경로나 게시 모드를 변경하여 어떤 일이 발생하는지 자유롭게 시도해 보십시오. + +물론, 이것은 여기서 일부 정보를 반복하고 있다는 것을 의미하며, 모든 출력의 위치를 같은 방식으로 업데이트하려면 불편해질 수 있습니다. +과정의 후반부에서 구조화된 방식으로 여러 출력에 대한 이러한 설정을 구성하는 방법을 배우게 됩니다. + +### 1.6. `-resume`으로 workflow 실행 + +workflow의 첫 번째 단계를 이미 성공적으로 실행했으므로 `-resume` 플래그를 사용하여 테스트해 봅시다. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +방금 추가한 새 process에 해당하는 추가 줄이 콘솔 출력에 나타납니다. + +`output` 블록에 설정된 대로 `results/hello_workflow` 디렉토리에서 출력을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +편리합니다! 하지만 두 번째 process 호출 중 하나의 작업 디렉토리를 살펴볼 가치가 있습니다. + +??? abstract "디렉토리 내용" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +두 개의 `*-output` 파일이 있습니다: 첫 번째 process의 출력과 두 번째의 출력입니다. + +첫 번째 process의 출력이 거기에 있는 이유는 Nextflow가 실행에 필요한 모든 것을 동일한 하위 디렉토리 내에 갖추기 위해 거기에 **스테이징**했기 때문입니다. + +그러나 실제로는 첫 번째 process 호출의 하위 디렉토리에 있는 원본 파일을 가리키는 심볼릭 링크입니다. +기본적으로, 여기서처럼 단일 머신에서 실행할 때 Nextflow는 입력 및 중간 파일을 스테이징하기 위해 복사본 대신 심볼릭 링크를 사용합니다. + +이제, 계속 진행하기 전에, `sayHello`의 출력을 `convertToUpper`의 입력에 연결하기만 하면 두 process가 직렬로 실행될 수 있었다는 점을 생각해 보십시오. +Nextflow가 개별 입력 및 출력 파일을 처리하고 두 명령 사이에 전달하는 어려운 작업을 대신해 주었습니다. + +이것이 Nextflow channel이 매우 강력한 이유 중 하나입니다: workflow 단계를 함께 연결하는 데 관련된 반복 작업을 처리해 줍니다. + +### 핵심 내용 + +한 단계의 출력을 다음 단계의 입력으로 제공하여 process를 함께 연결하는 방법을 알게 되었습니다. + +### 다음 단계 + +일괄 process 호출에서 출력을 수집하고 단일 process에 공급하는 방법을 배웁니다. + +--- + +## 2. 모든 인사말을 수집하는 세 번째 단계 추가 + +여기서 여러 인사말에 대해 수행하는 것처럼 channel의 각 요소에 변환을 적용하기 위해 process를 사용할 때, 때때로 해당 process의 출력 channel에서 요소를 수집하여 일종의 분석 또는 요약을 수행하는 다른 process에 공급하고 싶을 수 있습니다. + +시연을 위해, `convertToUpper` process에서 생성된 모든 대문자 인사말을 수집하여 단일 파일에 기록하는 새 단계를 파이프라인에 추가할 것입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +미리 스포일러를 하자면, 이것은 매우 유용한 연산자를 포함할 것입니다. + +### 2.1. 수집 명령 정의 및 터미널에서 테스트 + +Workflow에 추가하려는 수집 단계는 `cat` 명령을 사용하여 여러 대문자 인사말을 단일 파일로 연결합니다. + +이전에 했던 것처럼 터미널에서 명령 자체를 실행하여 예상대로 작동하는지 확인해 봅시다. + +터미널에서 다음을 실행하십시오: + +```bash +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 +``` + +출력은 원래 인사말의 대문자 버전이 포함된 `COLLECTED-output.txt`라는 텍스트 파일입니다. + +??? abstract "파일 내용" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +이것이 workflow로 달성하려는 결과입니다. + +### 2.2. 수집 단계를 수행하는 새 process 생성 + +새 process를 생성하고 `collectGreetings()`라고 부릅시다. +지금까지 본 것을 기반으로 작성을 시작할 수 있습니다. + +#### 2.2.1. Process의 '명백한' 부분 작성 + +다음 process 정의를 workflow 스크립트에 추가하십시오: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * 대문자 인사말을 하나의 출력 파일에 수집 + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +이것은 지금까지 배운 것을 기반으로 자신 있게 작성할 수 있는 부분입니다. +그러나 이것은 작동하지 않습니다! +입력 정의와 스크립트 명령의 첫 번째 절반을 생략했는데, 이것을 어떻게 작성해야 하는지 알아내야 합니다. + +#### 2.2.2. `collectGreetings()`에 대한 입력 정의 + +`convertToUpper()` process에 대한 모든 호출에서 인사말을 수집해야 합니다. +Workflow의 이전 단계에서 얻을 수 있는 것이 무엇인지 알고 있습니까? + +`convertToUpper()`에서 출력되는 channel에는 대문자 인사말이 포함된 개별 파일의 경로가 포함됩니다. +이것은 하나의 입력 슬롯에 해당합니다; 단순함을 위해 `input_files`라고 부르겠습니다. + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +여러 파일이 포함될 것으로 예상하지만 `path` 접두사를 사용합니다. + +#### 2.2.3. 연결 명령 구성 + +여기서 약간 까다로워질 수 있는데, 임의의 수의 입력 파일을 처리할 수 있어야 하기 때문입니다. +구체적으로, 명령을 미리 작성할 수 없으므로, 런타임에 process로 흘러 들어오는 입력을 기반으로 명령을 구성하는 방법을 Nextflow에 알려줘야 합니다. + +다시 말해, `[file1.txt, file2.txt, file3.txt]` 요소가 포함된 입력 channel이 있으면 Nextflow가 이를 `cat file1.txt file2.txt file3.txt`로 변환해야 합니다. + +다행히도, 스크립트 명령에 `cat ${input_files}`라고 간단히 작성하면 Nextflow가 기꺼이 이를 수행합니다. + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +이론적으로 이것은 임의의 수의 입력 파일을 처리해야 합니다. + +!!! tip "팁" + + 일부 명령줄 도구는 각 입력 파일에 대해 인수(예: `-input`)를 제공해야 합니다. + 그런 경우 명령을 구성하기 위해 약간의 추가 작업을 수행해야 합니다. + [Nextflow for Genomics](../../nf4_science/genomics/) 교육 과정에서 이에 대한 예를 볼 수 있습니다. + +### 2.3. Workflow에 수집 단계 추가 + +이제 대문자 변환 단계의 출력에서 수집 process를 호출하기만 하면 됩니다. + +#### 2.3.1. Process 호출 연결 + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out) + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="75" + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + } + ``` + +이것은 `convertToUpper()`의 출력을 `collectGreetings()`의 입력에 연결합니다. + +#### 2.3.2. `-resume`으로 workflow 실행 + +시도해 봅시다. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "명령 출력" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +세 번째 단계를 포함하여 성공적으로 실행됩니다. + +그러나 마지막 줄에서 `collectGreetings()`에 대한 호출 수를 보십시오. +하나만 예상했지만 세 개가 있습니다. + +이제 최종 출력 파일의 내용을 살펴보십시오. + +??? abstract "파일 내용" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +이런. 수집 단계가 각 인사말에 대해 개별적으로 실행되었으며, 이것은 우리가 원했던 것이 아닙니다. + +세 번째 단계가 `convertToUpper()`에서 출력된 channel의 모든 요소에서 실행되기를 원한다고 Nextflow에 명시적으로 알려야 합니다. + +### 2.4. 연산자를 사용하여 인사말을 단일 입력으로 수집 + +네, 다시 한번 우리 문제에 대한 답은 연산자입니다. + +구체적으로, 적절한 이름의 [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect) 연산자를 사용할 것입니다. + +#### 2.4.1. `collect()` 연산자 추가 + +이번에는 channel 팩토리의 컨텍스트에서 연산자를 추가하는 것이 아니라 출력 channel에 추가하기 때문에 약간 다르게 보일 것입니다. + +`convertToUpper.out`을 가져와서 `collect()` 연산자를 추가하면 `convertToUpper.out.collect()`가 됩니다. +이를 `collectGreetings()` process 호출에 직접 연결할 수 있습니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. `view()` 문 추가 + +channel 내용의 전후 상태를 시각화하기 위해 몇 가지 `view()` 문도 포함합시다. + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="73" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + } + ``` + +`view()` 문은 원하는 곳에 배치할 수 있습니다; 가독성을 위해 호출 바로 뒤에 배치했습니다. + +#### 2.4.3. `-resume`으로 workflow 다시 실행 + +시도해 봅시다: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "명령 출력" + + ```console + 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] + ``` + +성공적으로 실행되지만, 로그 출력이 이것보다 약간 지저분하게 보일 수 있습니다(가독성을 위해 정리했습니다). + +이번에는 세 번째 단계가 한 번만 호출되었습니다! + +`view()` 문의 출력을 보면 다음을 볼 수 있습니다: + +- 세 개의 `Before collect:` 문, 각 인사말에 대해 하나씩: 해당 시점에서 파일 경로는 channel의 개별 항목입니다. +- 단일 `After collect:` 문: 세 개의 파일 경로가 이제 단일 요소로 패키징되었습니다. + +최종 출력 파일의 내용을 살펴보십시오. + +??? abstract "파일 내용" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +이번에는 최종 출력 파일에 세 개의 인사말이 모두 있습니다. 성공입니다! + +!!! note "참고" + + `-resume` 없이 여러 번 실행하면 인사말의 순서가 실행마다 변경되는 것을 볼 수 있습니다. + 이것은 요소가 process 호출을 통해 흐르는 순서가 일관되게 보장되지 않음을 보여줍니다. + +#### 2.4.4. 가독성을 위해 `view()` 문 제거 + +다음 섹션으로 넘어가기 전에 콘솔 출력을 어지럽히지 않도록 `view()` 문을 삭제하는 것이 좋습니다. + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="73" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + + // optional view statements + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +이것은 기본적으로 2.4.2 지점의 역순 작업입니다. + +### 핵심 내용 + +일괄 process 호출에서 출력을 수집하고 공동 분석 또는 요약 단계에 공급하는 방법을 알게 되었습니다. + +### 다음 단계 + +Process에 둘 이상의 입력을 전달하는 방법을 배웁니다. + +--- + +## 3. Process에 둘 이상의 입력 전달 + +최종 결과를 덮어쓰지 않고 후속 인사말 배치를 처리하기 위해 최종 출력 파일에 특정 이름을 지정할 수 있기를 원합니다. + +이를 위해 workflow에 다음과 같은 개선을 수행할 것입니다: + +- 수집기 process가 출력 파일에 대해 사용자 정의 이름을 허용하도록 수정 +- Workflow에 명령줄 매개변수를 추가하고 수집기 process에 전달 + +### 3.1. 수집기 process 수정 + +추가 입력을 선언하고 출력 파일 이름에 통합해야 합니다. + +#### 3.1.1. 추가 입력 선언 + +좋은 소식: process 정의에서 원하는 만큼 많은 입력 변수를 선언할 수 있습니다. +이것을 `batch_name`이라고 부르겠습니다. + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Process가 원하는 만큼 많은 입력을 예상하도록 설정할 수 있습니다. +현재 이것들은 모두 필수 입력으로 설정되어 있습니다; workflow가 작동하려면 반드시 값을 제공해야 합니다. + +Nextflow 여정의 후반부에서 필수 입력과 선택적 입력을 관리하는 방법을 배우게 됩니다. + +#### 3.1.2. 출력 파일 이름에 `batch_name` 변수 사용 + +이전에 동적 파일 이름을 구성한 것과 같은 방식으로 출력 파일 이름에 변수를 삽입할 수 있습니다. + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +이것은 process가 `batch_name` 값을 사용하여 workflow의 최종 출력에 대한 특정 파일 이름을 생성하도록 설정합니다. + +### 3.2. `batch` 명령줄 매개변수 추가 + +이제 `batch_name`에 대한 값을 제공하고 process 호출에 공급하는 방법이 필요합니다. + +#### 3.2.1. `params`를 사용하여 매개변수 설정 + +CLI 매개변수를 선언하기 위해 `params` 시스템을 사용하는 방법을 이미 알고 있습니다. +이를 사용하여 `batch` 매개변수를 선언합시다(게으르기 때문에 기본값과 함께). + +파이프라인 매개변수 섹션에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +`--input`에 대해 시연한 것처럼 명령줄에서 `--batch`로 값을 지정하여 기본값을 재정의할 수 있습니다. + +#### 3.2.2. `batch` 매개변수를 process에 전달 + +매개변수 값을 process에 제공하려면 process 호출에 추가해야 합니다. + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect()) + ``` + +Process에 여러 입력을 제공하려면 호출 괄호 안에 쉼표로 구분하여 나열하기만 하면 됩니다. + +!!! warning "경고" + + Process에 대한 입력은 process의 입력 정의 블록에 나열된 것과 정확히 동일한 순서로 제공해야 합니다. + +### 3.3. Workflow 실행 + +명령줄에서 배치 이름으로 실행해 봅시다. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +성공적으로 실행되고 원하는 출력을 생성합니다: + +??? abstract "파일 내용" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +이제 매개변수를 적절하게 지정하는 한 다른 입력 배치에 대한 후속 실행은 이전 결과를 덮어쓰지 않습니다. + +### 핵심 내용 + +Process에 둘 이상의 입력을 전달하는 방법을 알게 되었습니다. + +### 다음 단계 + +여러 출력을 내보내고 편리하게 처리하는 방법을 배웁니다. + +--- + +## 4. 수집기 단계에 출력 추가 + +지금까지 하나의 출력만 생성하는 process를 사용해 왔습니다. +출력을 다음 process로 전달하는 컨텍스트(예: `convertToUpper(sayHello.out)`)와 `publish:` 섹션의 컨텍스트(예: `first_output = sayHello.out`) 모두에서 `<process>.out` 구문을 사용하여 각각의 출력에 매우 편리하게 액세스할 수 있었습니다. + +Process가 둘 이상을 생성할 때는 어떻게 됩니까? +여러 출력을 어떻게 처리합니까? +특정 출력을 선택하여 사용할 수 있습니까? + +모두 훌륭한 질문이며, 간단한 대답은 그렇습니다! + +여러 출력은 별도의 channel로 패키징됩니다. +해당 출력 channel에 이름을 지정하여 나중에 개별적으로 쉽게 참조하거나 인덱스로 참조할 수 있습니다. + +예를 들어 살펴봅시다. + +시연 목적으로, 주어진 입력 배치에 대해 수집되는 인사말 수를 세고 파일에 보고하고 싶다고 가정합시다. + +### 4.1. 인사말 수를 세고 출력하도록 process 수정 + +이것은 process 정의에 두 가지 주요 변경이 필요합니다: 인사말을 세고 보고 파일을 작성하는 방법이 필요하고, 해당 보고 파일을 process의 `output` 블록에 추가해야 합니다. + +#### 4.1.1. 수집된 인사말 수 세기 + +편리하게도 Nextflow는 process 정의의 `script:` 블록에 임의의 코드를 추가할 수 있으며, 이것은 이와 같은 작업을 수행하는 데 매우 유용합니다. + +즉, Nextflow의 내장 `size()` 함수를 사용하여 `input_files` 배열의 파일 수를 가져오고 `echo` 명령으로 결과를 파일에 쓸 수 있습니다. + +`collectGreetings` process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +`count_greetings` 변수는 런타임에 계산됩니다. + +#### 4.1.2. 보고 파일 내보내기 및 출력 이름 지정 + +원칙적으로 해야 할 일은 보고 파일을 `output:` 블록에 추가하는 것뿐입니다. + +그러나 그러는 동안 출력 선언에 `emit:` 태그도 추가할 것입니다. 이렇게 하면 위치 인덱스를 사용하지 않고 이름으로 출력을 선택할 수 있습니다. + +process 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +`emit:` 태그는 선택 사항이며 출력 중 하나에만 태그를 추가할 수도 있었습니다. +하지만 속담처럼, 둘 다 하면 안 될 이유가 있습니까? + +!!! tip "팁" + + `emit:`를 사용하여 process의 출력에 이름을 지정하지 않으면 각각의 (0 기반) 인덱스를 사용하여 개별적으로 액세스할 수 있습니다. + 예를 들어, `<process>.out[0]`을 사용하여 첫 번째 출력을 가져오고, `<process>.out[1]`을 사용하여 두 번째 출력을 가져오는 식입니다. + + 출력에 이름을 지정하는 것을 선호하는 이유는 그렇지 않으면 특히 process가 많은 출력을 생성할 때 실수로 잘못된 인덱스를 가져오기 너무 쉽기 때문입니다. + +### 4.2. Workflow 출력 업데이트 + +이제 `collectGreetings` process에서 두 개의 출력이 나오므로 `collectGreetings.out` 출력에는 두 개의 channel이 포함됩니다: + +- `collectGreetings.out.outfile`에는 최종 출력 파일이 포함됩니다 +- `collectGreetings.out.report`에는 보고 파일이 포함됩니다 + +이에 따라 workflow 출력을 업데이트해야 합니다. + +#### 4.2.1. `publish:` 섹션 업데이트 + +`workflow 블록`에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +보시다시피, 특정 process 출력을 참조하는 것이 이제 간단해졌습니다. +파트 5(컨테이너)에서 파이프라인에 단계를 하나 더 추가할 때 `collectGreetings.out.outfile`을 쉽게 참조하고 새 process에 전달할 수 있습니다(스포일러: 새 process는 `cowpy`라고 합니다). + +하지만 지금은 workflow 수준 출력 업데이트를 마무리합시다. + +#### 4.2.2. `output` 블록 업데이트 + +`output` 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +`collected` 출력 정의는 이름이 변경되지 않았으므로 업데이트할 필요가 없습니다. +새 출력만 추가하면 됩니다. + +### 4.3. Workflow 실행 + +현재 인사말 배치로 실행해 봅시다. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +`results/hello_workflow/` 디렉토리를 보면 새 보고 파일인 `trio-report.txt`를 찾을 수 있습니다. +열어서 workflow가 처리된 인사말 수를 올바르게 보고했는지 확인하십시오. + +??? abstract "파일 내용" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +CSV에 더 많은 인사말을 추가하고 어떤 일이 발생하는지 테스트해 보십시오. + +### 핵심 내용 + +Process가 여러 명명된 출력을 내보내도록 하는 방법과 workflow 수준에서 이를 적절하게 처리하는 방법을 알게 되었습니다. + +더 일반적으로, 일반적인 방식으로 process를 함께 연결하는 데 관련된 핵심 원칙을 이해하게 되었습니다. + +### 다음 단계 + +충분히 긴 휴식을 취하십시오. 충분히 그럴 자격이 있습니다. + +준비가 되면 [**파트 4: Hello Modules**](./04_hello_modules.md)로 이동하여 더 나은 유지보수성과 코드 효율성을 위해 코드를 모듈화하는 방법을 배우십시오. + +--- + +## 퀴즈 + +<quiz> +Workflow 블록에서 process의 출력에 어떻게 액세스합니까? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +자세히 알아보기: [1.4. 첫 번째 process의 출력을 두 번째 process로 전달](#14-첫-번째-process의-출력을-두-번째-process로-전달) +</quiz> + +<quiz> +Nextflow에서 process 실행 순서를 결정하는 것은 무엇입니까? +- [ ] Workflow 블록에서 process가 작성된 순서 +- [ ] Process 이름의 알파벳 순서 +- [x] Process 간의 데이터 종속성 +- [ ] 병렬 실행을 위한 무작위 순서 + +자세히 알아보기: [1.4. 첫 번째 process의 출력을 두 번째 process로 전달](#14-첫-번째-process의-출력을-두-번째-process로-전달) +</quiz> + +<quiz> +다운스트림 process를 위해 모든 출력을 단일 목록으로 수집하려면 `???`를 어떤 연산자로 교체해야 합니까? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +자세히 알아보기: [2.4. 연산자를 사용하여 인사말을 단일 입력으로 수집](#24-연산자를-사용하여-인사말을-단일-입력으로-수집) +</quiz> + +<quiz> +`collect()` 연산자는 언제 사용해야 합니까? +- [ ] 항목을 병렬로 처리하려고 할 때 +- [ ] Channel 내용을 필터링해야 할 때 +- [x] 다운스트림 process가 업스트림 process의 모든 항목을 필요로 할 때 +- [ ] 여러 process에 걸쳐 데이터를 분할하려고 할 때 + +자세히 알아보기: [2.4. 연산자를 사용하여 인사말을 단일 입력으로 수집](#24-연산자를-사용하여-인사말을-단일-입력으로-수집) +</quiz> + +<quiz> +Process에서 명명된 출력에 어떻게 액세스합니까? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +자세히 알아보기: [4.1.2. 보고 파일 내보내기 및 출력 이름 지정](#412-보고-파일-내보내기-및-출력-이름-지정) +</quiz> + +<quiz> +Process에서 출력의 이름을 지정하는 올바른 구문은 무엇입니까? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +자세히 알아보기: [4.1.2. 보고 파일 내보내기 및 출력 이름 지정](#412-보고-파일-내보내기-및-출력-이름-지정) +</quiz> + +<quiz> +Process에 여러 입력을 제공할 때 무엇이 참이어야 합니까? +- [ ] 모든 입력이 동일한 유형이어야 함 +- [ ] 입력은 알파벳 순서로 제공되어야 함 +- [x] 입력 순서가 입력 블록에 정의된 순서와 일치해야 함 +- [ ] 한 번에 두 개의 입력만 제공할 수 있음 + +자세히 알아보기: [3. Process에 둘 이상의 입력 전달](#3-process에-둘-이상의-입력-전달) +</quiz> diff --git a/docs/ko/docs/hello_nextflow/04_hello_modules.md b/docs/ko/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..142edffd90 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# 파트 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하십시오. + +:green_book: 비디오 스크립트는 [여기](./transcripts/04_hello_modules.md)에서 확인하실 수 있습니다. +/// + +이 섹션에서는 파이프라인의 개발 및 유지보수를 더 효율적이고 지속 가능하게 만들기 위해 workflow 코드를 구성하는 방법을 다룹니다. +구체적으로, **모듈**을 사용하는 방법을 시연할 것입니다. + +Nextflow에서 **모듈**은 독립적인 코드 파일에 캡슐화된 단일 process 정의입니다. +Workflow에서 모듈을 사용하려면 workflow 코드 파일에 한 줄의 import 문만 추가하면 됩니다; 그런 다음 일반적으로 하는 것과 같은 방식으로 process를 workflow에 통합할 수 있습니다. +이렇게 하면 코드의 여러 복사본을 생성하지 않고도 여러 workflow에서 process 정의를 재사용할 수 있습니다. + +Workflow 개발을 시작했을 때, 우리는 모든 것을 하나의 단일 코드 파일에 작성했습니다. +이제 process를 개별 모듈로 이동할 것입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +이렇게 하면 코드가 더 공유 가능하고, 유연하며, 유지보수하기 쉬워집니다. + +??? info "이 섹션부터 시작하는 방법" + + 이 섹션은 [Hello Nextflow](./index.md) 과정의 파트 1-3을 완료했다고 가정하지만, 해당 섹션에서 다룬 기본 사항에 익숙하다면 특별한 준비 없이 여기서 시작할 수 있습니다. + +--- + +## 0. 워밍업: `hello-modules.nf` 실행 + +시작점으로 workflow 스크립트 `hello-modules.nf`를 사용할 것입니다. +이 스크립트는 이 교육 과정의 파트 3을 완료하여 생성된 스크립트와 동일하지만, 출력 대상을 변경했습니다: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +변경을 시작하기 전에 모든 것이 제대로 작동하는지 확인하기 위해 스크립트를 한 번 실행하십시오: + +```bash +nextflow run hello-modules.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +이전과 마찬가지로 `output` 블록에 지정된 디렉토리(여기서는 `results/hello_modules/`)에서 출력 파일을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +이것이 정상적으로 작동했다면 workflow 코드를 모듈화하는 방법을 배울 준비가 되었습니다. + +--- + +## 1. 모듈을 저장할 디렉토리 생성 + +모듈을 특정 디렉토리에 저장하는 것이 모범 사례입니다. +해당 디렉토리의 이름은 원하는 대로 지을 수 있지만, 관례상 `modules/`라고 부릅니다. + +```bash +mkdir modules +``` + +!!! tip "팁" + + 여기서는 **로컬 모듈**을 사용하는 방법을 보여드리고 있습니다. 이는 workflow 코드의 나머지 부분과 동일한 저장소에 로컬로 저장된 모듈을 의미하며, 다른 (원격) 저장소에 저장된 원격 모듈과 대조됩니다. + **원격 모듈**에 대한 자세한 내용은 [문서](https://www.nextflow.io/docs/latest/module.html)를 참조하십시오. + +--- + +## 2. `sayHello()`용 모듈 생성 + +가장 간단한 형태에서, 기존 process를 모듈로 전환하는 것은 복사-붙여넣기 작업에 불과합니다. +모듈에 대한 파일 스텁을 생성하고, 관련 코드를 복사한 다음 메인 workflow 파일에서 삭제할 것입니다. + +그런 다음 import 문만 추가하면 Nextflow가 런타임에 관련 코드를 가져올 것입니다. + +### 2.1. 새 모듈에 대한 파일 스텁 생성 + +`sayHello.nf`라는 모듈에 대한 빈 파일을 생성합시다. + +```bash +touch modules/sayHello.nf +``` + +이것은 process 코드를 넣을 장소를 제공합니다. + +### 2.2. `sayHello` process 코드를 모듈 파일로 이동 + +전체 process 정의를 workflow 파일에서 모듈 파일로 복사하고, `#!/usr/bin/env nextflow` shebang도 함께 복사해야 합니다. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * echo를 사용하여 'Hello World!'를 파일에 출력 + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +완료되면 workflow 파일에서 process 정의를 삭제하되, shebang은 그대로 두십시오. + +### 2.3. Workflow 블록 전에 import 선언 추가 + +로컬 모듈을 가져오는 구문은 매우 간단합니다: + +```groovy title="구문: Import 선언" +include { <MODULE_NAME> } from '<path_to_module>' +``` + +`params` 블록 위에 이것을 삽입하고 적절하게 채웁시다. + +=== "수정 후" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "수정 전" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +모듈 이름인 `sayHello`와 모듈 코드가 포함된 파일 경로인 `./modules/sayHello.nf`를 채웠습니다. + +### 2.4. Workflow 실행 + +이전과 본질적으로 동일한 코드와 입력으로 workflow를 실행하고 있으므로, `-resume` 플래그로 실행하고 어떻게 되는지 살펴봅시다. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +모든 것이 캐시되어 있으므로 매우 빠르게 실행되어야 합니다. +게시된 출력을 자유롭게 확인하십시오. + +Nextflow는 코드가 여러 파일로 분할되어 있더라도 여전히 동일한 작업이 수행되어야 함을 인식했습니다. + +### 핵심 내용 + +Process를 로컬 모듈로 추출하는 방법과 이렇게 해도 workflow의 재개 가능성이 깨지지 않는다는 것을 알게 되었습니다. + +### 다음 단계 + +더 많은 모듈을 만드는 연습을 합니다. +하나를 만들면 백만 개 더 만들 수 있습니다... +하지만 지금은 두 개만 더 만들겠습니다. + +--- + +## 3. `convertToUpper()` process 모듈화 + +### 3.1. 새 모듈에 대한 파일 스텁 생성 + +`convertToUpper.nf`라는 모듈에 대한 빈 파일을 생성합니다. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. `convertToUpper` process 코드를 모듈 파일로 이동 + +전체 process 정의를 workflow 파일에서 모듈 파일로 복사하고, `#!/usr/bin/env nextflow` shebang도 함께 복사해야 합니다. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * 텍스트 대체 도구를 사용하여 인사말을 대문자로 변환 + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +완료되면 workflow 파일에서 process 정의를 삭제하되, shebang은 그대로 두십시오. + +### 3.3. `params` 블록 전에 import 선언 추가 + +`params` 블록 위에 import 선언을 삽입하고 적절하게 채웁니다. + +=== "수정 후" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "수정 전" + + ```groovy title="hello-modules.nf" linenums="23" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +이것이 매우 익숙해지기 시작해야 합니다. + +### 3.4. Workflow 다시 실행 + +`-resume` 플래그로 실행합니다. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성해야 합니다. + +두 개 완료, 하나 더 남았습니다! + +--- + +## 4. `collectGreetings()` process 모듈화 + +### 4.1. 새 모듈에 대한 파일 스텁 생성 + +`collectGreetings.nf`라는 모듈에 대한 빈 파일을 생성합니다. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. `collectGreetings` process 코드를 모듈 파일로 이동 + +전체 process 정의를 workflow 파일에서 모듈 파일로 복사하고, `#!/usr/bin/env nextflow` shebang도 함께 복사해야 합니다. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * 대문자 인사말을 하나의 출력 파일에 수집 + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +완료되면 workflow 파일에서 process 정의를 삭제하되, shebang은 그대로 두십시오. + +### 4.3. `params` 블록 전에 import 선언 추가 + +`params` 블록 위에 import 선언을 삽입하고 적절하게 채웁니다. + +=== "수정 후" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "수정 전" + + ```groovy title="hello-modules.nf" linenums="3" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * 파이프라인 매개변수 + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +마지막입니다! + +### 4.4. Workflow 실행 + +`-resume` 플래그로 실행합니다. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성해야 합니다. + +### 핵심 내용 + +Workflow에서 여러 process를 모듈화하는 방법을 알게 되었습니다. + +축하합니다, 이 모든 작업을 수행했지만 파이프라인 작동 방식에는 아무것도 변경되지 않았습니다! + +농담은 제쳐두고, 이제 코드가 더 모듈화되었으며, 해당 process 중 하나를 호출하는 다른 파이프라인을 작성하기로 결정하면 관련 모듈을 사용하기 위해 짧은 import 문 하나만 입력하면 됩니다. +이것은 코드를 복사-붙여넣기하는 것보다 낫습니다. 나중에 모듈을 개선하기로 결정하면 모든 파이프라인이 개선 사항을 상속받기 때문입니다. + +### 다음 단계 + +원한다면 잠시 휴식을 취하십시오. + +준비가 되면 [**파트 5: Hello Containers**](./05_hello_containers.md)로 이동하여 소프트웨어 종속성을 더 편리하고 재현 가능하게 관리하기 위해 컨테이너를 사용하는 방법을 배우십시오. + +--- + +## 퀴즈 + +<quiz> +Nextflow에서 모듈이란 무엇입니까? +- [ ] 구성 파일 +- [x] 단일 process 정의가 포함된 독립 파일 +- [ ] Workflow 정의 +- [ ] Channel 연산자 + +자세히 알아보기: [2. `sayHello()`용 모듈 생성](#2-sayhello용-모듈-생성) +</quiz> + +<quiz> +모듈 파일에 권장되는 명명 규칙은 무엇입니까? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +모듈 파일은 어디에 저장해야 합니까? +- [ ] Workflow와 같은 디렉토리에 +- [ ] `bin/` 디렉토리에 +- [x] `modules/` 디렉토리에 +- [ ] `lib/` 디렉토리에 + +자세히 알아보기: [1. 모듈을 저장할 디렉토리 생성](#1-모듈을-저장할-디렉토리-생성) +</quiz> + +<quiz> +모듈을 가져오는 올바른 구문은 무엇입니까? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +자세히 알아보기: [2.3. import 선언 추가](#23-workflow-블록-전에-import-선언-추가) +</quiz> + +<quiz> +모듈을 사용할 때 `-resume` 기능은 어떻게 됩니까? +- [ ] 더 이상 작동하지 않음 +- [ ] 추가 구성이 필요함 +- [x] 이전과 동일하게 작동함 +- [ ] 로컬 모듈에서만 작동함 +</quiz> + +<quiz> +모듈 사용의 이점은 무엇입니까? (해당되는 것 모두 선택) +- [x] Workflow 간 코드 재사용 가능 +- [x] 더 쉬운 유지보수 +- [x] Workflow 코드의 더 나은 구성 +- [ ] 더 빠른 실행 속도 +</quiz> diff --git a/docs/ko/docs/hello_nextflow/05_hello_containers.md b/docs/ko/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..ae546cd48f --- /dev/null +++ b/docs/ko/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# 파트 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하십시오. + +:green_book: 비디오 스크립트는 [여기](./transcripts/05_hello_containers.md)에서 확인하실 수 있습니다. +/// + +이 교육 과정의 파트 1-4에서는 Nextflow의 기본 구성 요소를 사용하여 텍스트를 처리하고, 여러 입력이 있는 경우 실행을 병렬화하며, 추가 처리를 위해 결과를 수집할 수 있는 간단한 workflow를 조립하는 방법을 배웠습니다. + +그러나 환경에서 사용할 수 있는 기본 UNIX 도구로 제한되었습니다. +실제 작업에는 기본적으로 포함되지 않은 다양한 도구와 패키지가 필요한 경우가 많습니다. +일반적으로 이러한 도구를 설치하고, 종속성을 관리하며, 충돌을 해결해야 합니다. + +이 모든 것이 매우 지루하고 귀찮으므로, 이 문제를 훨씬 더 편리하게 해결하기 위해 **컨테이너**를 사용하는 방법을 보여드리겠습니다. + +**컨테이너**는 코드, 시스템 라이브러리 및 설정을 포함하여 애플리케이션을 실행하는 데 필요한 모든 것이 포함된 컨테이너 **이미지**에서 생성된 경량의 독립 실행형 소프트웨어 단위입니다. +예상하시다시피, 이것은 파이프라인을 더 재현 가능하게 만드는 데 매우 도움이 될 것입니다. + +여기서는 [Docker](https://www.docker.com/get-started/)를 사용하여 이를 가르치지만, Nextflow가 [여러 다른 컨테이너 기술](https://www.nextflow.io/docs/latest/container.html#)도 지원한다는 점을 유의하십시오. + +??? info "이 섹션부터 시작하는 방법" + + 이 섹션은 [Hello Nextflow](./index.md) 과정의 파트 1-4를 완료하고 완전히 작동하는 파이프라인이 있다고 가정합니다. + + 이 시점부터 과정을 시작하는 경우 solutions에서 `modules` 디렉토리를 복사해야 합니다: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. 워밍업: `hello-containers.nf` 실행 + +시작점으로 workflow 스크립트 `hello-containers.nf`를 사용할 것입니다. +이 스크립트는 이 교육 과정의 파트 4를 완료하여 생성된 스크립트와 동일하지만, 출력 대상을 변경했습니다: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +변경을 시작하기 전에 모든 것이 제대로 작동하는지 확인하기 위해 스크립트를 한 번 실행하십시오: + +```bash +nextflow run hello-containers.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +이전과 마찬가지로 `output` 블록에 지정된 디렉토리(`results/hello_containers/`)에서 출력 파일을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +이것이 정상적으로 작동했다면 컨테이너를 사용하는 방법을 배울 준비가 되었습니다. + +--- + +## 1. 컨테이너를 '수동으로' 사용 + +우리가 하고자 하는 것은 실행에 컨테이너를 사용하는 단계를 workflow에 추가하는 것입니다. + +그러나 먼저 Nextflow에서 컨테이너를 사용하기 전에 컨테이너가 무엇인지에 대한 이해를 확고히 하기 위해 몇 가지 기본 개념과 작업을 살펴볼 것입니다. + +### 1.1. 컨테이너 이미지 풀(Pull) + +컨테이너를 사용하려면 일반적으로 컨테이너 레지스트리에서 컨테이너 이미지를 다운로드하거나 *풀(pull)*한 다음, 컨테이너 이미지를 실행하여 컨테이너 인스턴스를 생성합니다. + +일반적인 구문은 다음과 같습니다: + +```bash title="구문" +docker pull '<container>' +``` + +`docker pull` 부분은 저장소에서 컨테이너 이미지를 풀(pull)하라는 컨테이너 시스템에 대한 명령입니다. + +`'<container>'` 부분은 컨테이너 이미지의 URI 주소입니다. + +예를 들어, 임의의 텍스트 입력을 재미있는 방식으로 표시하는 ASCII 아트를 생성하는 `cowsay`라는 도구의 Python 구현인 [cowpy](https://github.com/jeffbuttars/cowpy)가 포함된 컨테이너 이미지를 풀해 봅시다. + +```txt title="예제" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +게시된 컨테이너를 찾을 수 있는 다양한 저장소가 있습니다. +우리는 [Seqera Containers](https://seqera.io/containers/) 서비스를 사용하여 `cowpy` Conda 패키지에서 이 Docker 컨테이너 이미지를 생성했습니다: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +전체 풀 명령을 실행하십시오: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "명령 출력" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +이전에 이미지를 다운로드한 적이 없다면 완료하는 데 1분 정도 걸릴 수 있습니다. +완료되면 컨테이너 이미지의 로컬 복사본이 생깁니다. + +### 1.2. 컨테이너를 사용하여 `cowpy`를 일회성 명령으로 실행 + +사람들이 컨테이너를 사용하는 매우 일반적인 방법 중 하나는 직접 실행하는 것, 즉 비대화식으로 실행하는 것입니다. +이것은 일회성 명령을 실행하는 데 적합합니다. + +일반적인 구문은 다음과 같습니다: + +```bash title="구문" +docker run --rm '<container>' [tool command] +``` + +`docker run --rm '<container>'` 부분은 컨테이너 이미지에서 컨테이너 인스턴스를 생성하고 그 안에서 명령을 실행하라는 컨테이너 시스템에 대한 명령입니다. +`--rm` 플래그는 명령이 완료된 후 컨테이너 인스턴스를 종료하도록 시스템에 지시합니다. + +`[tool command]` 구문은 사용 중인 도구와 컨테이너 설정 방식에 따라 다릅니다. +`cowpy`로 시작해 봅시다. + +완전히 조립된 컨테이너 실행 명령은 다음과 같습니다; 계속 진행하여 실행하십시오. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "명령 출력" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +시스템이 컨테이너를 생성하고, 매개변수와 함께 `cowpy` 명령을 실행하고, 출력을 콘솔로 보내고, 마지막으로 컨테이너 인스턴스를 종료했습니다. + +### 1.3. 컨테이너를 대화식으로 사용하여 `cowpy` 실행 + +컨테이너를 대화식으로 실행할 수도 있으며, 이렇게 하면 컨테이너 내부에서 셸 프롬프트를 받고 명령으로 작업할 수 있습니다. + +#### 1.3.1. 컨테이너 생성 + +대화식으로 실행하려면 `docker run` 명령에 `-it`를 추가하기만 하면 됩니다. +선택적으로, 명령에 예를 들어 `/bin/bash`를 추가하여 컨테이너 내부에서 사용할 셸을 지정할 수 있습니다. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +프롬프트가 `(base) root@b645838b3314:/tmp#`과 같은 것으로 변경되는 것을 확인하십시오. 이는 이제 컨테이너 내부에 있음을 나타냅니다. + +파일 시스템의 루트에서 디렉토리 내용을 나열하는 `ls /`를 실행하여 이를 확인할 수 있습니다: + +```bash +ls / +``` + +??? abstract "명령 출력" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +`tree` 유틸리티가 이 컨테이너에서 사용할 수 없기 때문에 여기서 `tree` 대신 `ls`를 사용합니다. +컨테이너 내부의 파일 시스템이 호스트 시스템의 파일 시스템과 다르다는 것을 알 수 있습니다. + +방금 수행한 작업의 한 가지 제한 사항은 컨테이너가 기본적으로 호스트 시스템과 완전히 격리되어 있다는 것입니다. +이것은 명시적으로 허용하지 않는 한 컨테이너가 호스트 시스템의 파일에 액세스할 수 없음을 의미합니다. + +잠시 후에 그 방법을 보여드리겠습니다. + +#### 1.3.2. 원하는 도구 명령 실행 + +이제 컨테이너 내부에 있으므로 `cowpy` 명령을 직접 실행하고 몇 가지 매개변수를 제공할 수 있습니다. +예를 들어, 도구 문서에 따르면 `-c`로 캐릭터('cowacter')를 변경할 수 있습니다. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "명령 출력" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +이제 출력에 기본 소 대신 리눅스 펭귄 Tux가 표시됩니다. `-c tux` 매개변수를 지정했기 때문입니다. + +컨테이너 내부에 있으므로 Docker 명령을 다룰 필요 없이 입력 매개변수를 변경하면서 `cowpy` 명령을 원하는 만큼 실행할 수 있습니다. + +!!! Tip "팁" + + '-c' 플래그를 사용하여 다른 캐릭터를 선택할 수 있습니다: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +좋습니다. 더 좋은 것은 `greetings.csv`를 입력으로 제공할 수 있다면 좋겠습니다. +그러나 파일 시스템에 액세스할 수 없으므로 그렇게 할 수 없습니다. + +수정해 봅시다. + +#### 1.3.3. 컨테이너 종료 + +컨테이너를 종료하려면 프롬프트에서 `exit`를 입력하거나 ++ctrl+d++ 키보드 단축키를 사용할 수 있습니다. + +```bash +exit +``` + +이제 프롬프트가 컨테이너를 시작하기 전 상태로 돌아가야 합니다. + +#### 1.3.4. 컨테이너에 데이터 마운트 + +앞서 언급했듯이 컨테이너는 기본적으로 호스트 시스템과 격리되어 있습니다. + +컨테이너가 호스트 파일 시스템에 액세스할 수 있도록 하려면 다음 구문을 사용하여 호스트 시스템에서 컨테이너로 **볼륨**을 **마운트**할 수 있습니다: + +```bash title="구문" +-v <outside_path>:<inside_path> +``` + +우리의 경우 `<outside_path>`는 현재 작업 디렉토리이므로 점(`.`)만 사용할 수 있고, `<inside_path>`는 우리가 만든 별칭일 뿐입니다; `/my_project`라고 부르겠습니다(내부 경로는 절대 경로여야 함). + +볼륨을 마운트하려면 경로를 교체하고 다음과 같이 docker run 명령에 볼륨 마운트 인수를 추가합니다: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +이렇게 하면 현재 작업 디렉토리가 컨테이너 내부의 `/my_project` 아래에서 액세스할 수 있는 볼륨으로 마운트됩니다. + +`/my_project`의 내용을 나열하여 작동하는지 확인할 수 있습니다: + +```bash +ls /my_project +``` + +??? success "명령 출력" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +이제 컨테이너 내부에서 `data/` 아래의 `greetings.csv` 파일을 포함하여 작업 디렉토리의 내용을 볼 수 있습니다. + +이것은 효과적으로 파일 시스템의 해당 부분에 액세스하는 데 사용할 수 있는 컨테이너 벽을 통한 터널을 설정했습니다. + +#### 1.3.5. 마운트된 데이터 사용 + +이제 작업 디렉토리를 컨테이너에 마운트했으므로 `cowpy` 명령을 사용하여 `greetings.csv` 파일의 내용을 표시할 수 있습니다. + +이를 위해 `cat /my_project/data/greetings.csv | `를 사용하여 CSV 파일의 내용을 `cowpy` 명령으로 파이프합니다. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "명령 출력" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +이것은 예제 인사말을 읊는 칠면조의 ASCII 아트를 생성합니다! +단, 여기서 칠면조는 인사말만이 아닌 전체 행을 반복하고 있습니다. +우리는 Nextflow workflow가 더 잘할 것이라는 것을 이미 알고 있습니다! + +이 명령으로 자유롭게 작업해 보십시오. +완료되면 이전처럼 컨테이너를 종료하십시오: + +```bash +exit +``` + +일반 셸로 돌아갑니다. + +### 핵심 내용 + +컨테이너를 풀하고 일회성 또는 대화식으로 실행하는 방법을 알게 되었습니다. 또한 컨테이너 내부에서 데이터에 액세스할 수 있도록 하는 방법을 알게 되었으며, 이를 통해 시스템에 소프트웨어를 설치하지 않고도 관심 있는 도구를 실제 데이터로 시험해 볼 수 있습니다. + +### 다음 단계 + +Nextflow process 실행에 컨테이너를 사용하는 방법을 배웁니다. + +--- + +## 2. Nextflow에서 컨테이너 사용 + +Nextflow는 컴퓨팅 환경에 설치되지 않은 도구를 실행할 수 있도록 컨테이너 내부에서 process를 실행하는 기능을 기본적으로 지원합니다. +즉, process를 실행하는 데 원하는 컨테이너 이미지를 사용할 수 있으며, Nextflow가 이미지 풀, 데이터 마운트 및 그 안에서 process 실행을 처리합니다. + +이를 시연하기 위해 개발해 온 파이프라인에 `collectGreetings` 단계 이후에 `cowpy` 단계를 추가할 것입니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +시작할 준비가 되었으면 Moo! + +### 2.1. `cowpy` 모듈 작성 + +먼저 `cowpy` process 모듈을 생성합시다. + +#### 2.1.1. 새 모듈에 대한 파일 스텁 생성 + +`cowpy.nf`라는 모듈에 대한 빈 파일을 생성합니다. + +```bash +touch modules/cowpy.nf +``` + +이것은 process 코드를 넣을 장소를 제공합니다. + +#### 2.1.2. 모듈 파일에 `cowpy` process 코드 복사 + +이전에 작성한 다른 process를 모델로 `cowpy` process를 만들 수 있습니다. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy로 ASCII 아트 생성 +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Process는 인사말이 포함된 `input_file`과 `character` 값을 예상합니다. + +출력은 `cowpy` 도구에서 생성된 ASCII 아트가 포함된 새 텍스트 파일입니다. + +### 2.2. Workflow에 cowpy 추가 + +이제 모듈을 가져오고 process를 호출해야 합니다. + +#### 2.2.1. `hello-containers.nf`에 `cowpy` process 가져오기 + +workflow 블록 위에 import 선언을 삽입하고 적절하게 채웁니다. + +=== "수정 후" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "수정 전" + + ```groovy title="hello-containers.nf" linenums="3" + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +이제 `cowpy` 모듈을 workflow에서 사용할 수 있습니다. + +#### 2.2.2. Workflow에 `cowpy` process 호출 추가 + +기억하시다시피 두 개의 출력을 생성하는 `collectGreetings()` process의 출력에 `cowpy()` process를 연결합시다: + +- `collectGreetings.out.outfile`에는 출력 파일이 포함됩니다 <--_우리가 원하는 것_ +- `collectGreetings.out.report`에는 배치당 인사말 수가 포함된 보고 파일이 포함됩니다 + +workflow 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "수정 전" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // CSV 파일에서 입력용 channel 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말을 내보냅니다 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +인사말을 말할 캐릭터를 지정하기 위해 새 CLI 매개변수 `params.character`를 선언했습니다. + +#### 2.2.3. `params` 블록에 `character` 매개변수 추가 + +이것은 기술적으로 선택 사항이지만 권장되는 관행이며, 그러는 동안 캐릭터의 기본값을 설정할 기회입니다. + +=== "수정 후" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "수정 전" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +이제 게으르게 명령줄에서 캐릭터 매개변수 입력을 건너뛸 수 있습니다. + +#### 2.2.4. Workflow 출력 업데이트 + +`cowpy` process의 출력을 게시하도록 workflow 출력을 업데이트해야 합니다. + +##### 2.2.4.1. `publish:` 섹션 업데이트 + +`workflow 블록`에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "수정 전" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +`cowpy` process는 하나의 출력만 생성하므로 `.out`을 추가하여 일반적인 방식으로 참조할 수 있습니다. + +하지만 지금은 workflow 수준 출력 업데이트를 마무리합시다. + +##### 2.2.4.2. `output` 블록 업데이트 + +`output` 블록에 최종 `cowpy_art` 출력을 추가해야 합니다. 그러는 동안 파이프라인이 완료되어 실제로 중요한 출력이 무엇인지 알게 되었으므로 게시 대상도 편집합시다. + +`output` 블록에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +이제 게시된 출력이 약간 더 정리됩니다. + +#### 2.2.5. Workflow 실행 + +요약하자면, 우리가 목표로 하는 것은 다음과 같습니다: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +작동할 것 같습니까? + +이전에 게시된 출력을 삭제하여 깨끗한 상태로 만들고 `-resume` 플래그로 workflow를 실행합시다. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "명령 출력 (명확성을 위해 편집됨)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +오류가 발생했습니다! +`error exit status (127)`에서 제공된 오류 코드는 요청한 실행 파일을 찾을 수 없음을 의미합니다. + +`cowpy` 도구를 호출하고 있지만 아직 컨테이너를 지정하지 않았기 때문에(이런) 당연히 그렇습니다. + +### 2.3. 컨테이너를 사용하여 `cowpy` process 실행 + +컨테이너를 지정하고 Nextflow에게 `cowpy()` process에 사용하도록 지시해야 합니다. + +#### 2.3.1. `cowpy`에 대한 컨테이너 지정 + +이 튜토리얼의 첫 번째 섹션에서 직접 사용했던 동일한 이미지를 사용할 수 있습니다. + +다음과 같이 process 정의에 `container` 지시문을 추가하도록 `cowpy.nf` 모듈을 편집하십시오: + +=== "수정 후" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "수정 전" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +이것은 _Docker 사용이 활성화된 경우_, Nextflow가 여기에 지정된 컨테이너 이미지를 사용하여 process를 실행해야 함을 알려줍니다. + +#### 2.3.2. `nextflow.config` 파일을 통해 Docker 사용 활성화 + +*'Docker 사용이 활성화된 경우'*라고 말했다는 것을 주목하십시오. 기본적으로 활성화되어 있지 않으므로 Nextflow에게 Docker를 사용할 수 있도록 허용해야 합니다. +이를 위해 구성을 다루는 이 과정의 다음이자 마지막 파트(파트 6)의 주제를 약간 앞당기겠습니다. + +Nextflow가 workflow 실행을 구성하기 위해 제공하는 주요 방법 중 하나는 `nextflow.config` 파일을 사용하는 것입니다. +현재 디렉토리에 이러한 파일이 있으면 Nextflow가 자동으로 로드하고 포함된 모든 구성을 적용합니다. + +Docker를 명시적으로 비활성화하는 한 줄의 코드가 포함된 `nextflow.config` 파일을 제공했습니다: `docker.enabled = false`. + +이제 Docker를 활성화하기 위해 `true`로 전환합시다: + +=== "수정 후" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "수정 전" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "팁" + + `-with-docker <container>` 매개변수를 사용하여 명령줄에서 실행별로 Docker 실행을 활성화할 수 있습니다. + 그러나 이것은 전체 workflow에 대해 하나의 컨테이너만 지정할 수 있는 반면, 방금 보여드린 접근 방식은 process당 다른 컨테이너를 지정할 수 있습니다. + 이것은 모듈성, 코드 유지보수 및 재현성에 더 좋습니다. + +#### 2.3.3. Docker가 활성화된 상태로 workflow 실행 + +`-resume` 플래그로 workflow를 실행하십시오: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +이번에는 정말로 작동합니다! +평소와 같이 해당 results 디렉토리에서 workflow 출력을 찾을 수 있지만, 이번에는 보고서와 최종 출력만 최상위 수준에 있고 모든 중간 파일은 하위 디렉토리로 이동되어 약간 더 깔끔하게 정리되어 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +최종 ASCII 아트 출력은 `results/hello_containers/` 디렉토리에 `cowpy-COLLECTED-batch-output.txt`라는 이름으로 있습니다. + +??? abstract "파일 내용" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +우리의 아름다운 칠면조가 원하는 대로 인사말을 말하고 있습니다. + +#### 2.3.4. Nextflow가 컨테이너화된 작업을 시작한 방법 검사 + +이 섹션의 마지막 코다로, Nextflow가 내부적으로 컨테이너와 어떻게 작동하는지에 대해 조금 더 통찰력을 얻기 위해 `cowpy` process 호출 중 하나의 작업 하위 디렉토리를 살펴봅시다. + +`nextflow run` 명령의 출력을 확인하여 `cowpy` process의 작업 하위 디렉토리 경로를 찾으십시오. +위에 표시된 실행에서 얻은 것을 보면, `cowpy` process의 콘솔 로그 라인은 `[98/656c6c]`로 시작합니다. +이것은 다음 잘린 디렉토리 경로에 해당합니다: `work/98/656c6c`. + +해당 디렉토리에서 파이프라인을 실행하는 과정에서 Nextflow가 대신 실행한 모든 명령이 포함된 `.command.run` 파일을 찾을 수 있습니다. + +??? abstract "파일 내용" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +이 파일에서 `nxf_launch`를 검색하면 다음과 같은 것을 볼 수 있습니다: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +보시다시피, Nextflow는 `docker run` 명령을 사용하여 process 호출을 시작합니다. +또한 해당 작업 하위 디렉토리를 컨테이너에 마운트하고, 컨테이너 내부의 작업 디렉토리를 적절하게 설정하고, `.command.sh` 파일에서 템플릿된 bash 스크립트를 실행합니다. + +첫 번째 섹션에서 수동으로 해야 했던 모든 어려운 작업? Nextflow가 백그라운드에서 우리를 위해 해줍니다! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### 핵심 내용 + +Process를 실행하기 위해 Nextflow에서 컨테이너를 사용하는 방법을 알게 되었습니다. + +### 다음 단계 + +휴식을 취하십시오! + +준비가 되면 [**파트 6: Hello Config**](./06_hello_config.md)로 이동하여 인프라에 맞게 파이프라인 실행을 구성하고 입력 및 매개변수 구성을 관리하는 방법을 배우십시오. + +마지막 파트이며, 이것을 완료하면 이 과정을 마치게 됩니다! + +--- + +## 퀴즈 + +<quiz> +컨테이너란 무엇입니까? +- [ ] 가상 머신의 일종 +- [ ] 파일 압축 형식 +- [x] 애플리케이션 실행에 필요한 모든 것이 포함된 경량의 독립 실행형 단위 +- [ ] 네트워크 프로토콜 +</quiz> + +<quiz> +컨테이너 이미지와 컨테이너 인스턴스의 차이점은 무엇입니까? +- [ ] 동일한 것임 +- [x] 이미지는 템플릿이고 인스턴스는 해당 이미지에서 생성된 실행 중인 컨테이너임 +- [ ] 인스턴스는 템플릿이고 이미지는 실행 중인 컨테이너임 +- [ ] 이미지는 Docker용이고 인스턴스는 Singularity용임 +</quiz> + +<quiz> +`docker run` 명령에서 `-v` 플래그는 무엇을 합니까? +- [ ] 자세한 출력 활성화 +- [ ] 컨테이너 유효성 검사 +- [x] 호스트 시스템에서 컨테이너로 볼륨 마운트 +- [ ] 컨테이너 버전 지정 + +자세히 알아보기: [1.3.4. 컨테이너에 데이터 마운트](#134-컨테이너에-데이터-마운트) +</quiz> + +<quiz> +컨테이너를 사용할 때 볼륨을 마운트해야 하는 이유는 무엇입니까? +- [ ] 컨테이너 성능 향상 +- [ ] 디스크 공간 절약 +- [x] 컨테이너가 기본적으로 호스트 파일 시스템과 격리되어 있기 때문 +- [ ] 네트워킹 활성화 + +자세히 알아보기: [1.3.4. 컨테이너에 데이터 마운트](#134-컨테이너에-데이터-마운트) +</quiz> + +<quiz> +Nextflow process에 컨테이너를 어떻게 지정합니까? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +자세히 알아보기: [2.3.1. cowpy에 대한 컨테이너 지정](#231-cowpy에-대한-컨테이너-지정) +</quiz> + +<quiz> +어떤 `nextflow.config` 설정이 workflow에 대해 Docker를 활성화합니까? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +자세히 알아보기: [2.3.2. `nextflow.config` 파일을 통해 Docker 사용 활성화](#232-nextflowconfig-파일을-통해-docker-사용-활성화) +</quiz> + +<quiz> +컨테이너에서 process를 실행할 때 Nextflow가 자동으로 처리하는 것은 무엇입니까? (해당되는 것 모두 선택) +- [x] 필요한 경우 컨테이너 이미지 풀 +- [x] 작업 디렉토리 마운트 +- [x] 컨테이너 내부에서 process 스크립트 실행 +- [x] 실행 후 컨테이너 인스턴스 정리 + +자세히 알아보기: [2.3.4. Nextflow가 컨테이너화된 작업을 시작한 방법 검사](#234-nextflow가-컨테이너화된-작업을-시작한-방법-검사) +</quiz> diff --git a/docs/ko/docs/hello_nextflow/06_hello_config.md b/docs/ko/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..f89f0faa45 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# 파트 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하십시오. + +:green_book: 비디오 스크립트는 [여기](./transcripts/06_hello_config.md)에서 확인하실 수 있습니다. +/// + +이 섹션에서는 _workflow 코드 자체를 한 줄도 변경하지 않고_ 동작을 사용자 정의하고, 다른 환경에 적응시키며, 리소스 사용을 최적화할 수 있도록 Nextflow 파이프라인의 구성을 설정하고 관리하는 방법을 탐색합니다. + +이를 수행하는 여러 방법이 있으며, 조합하여 사용할 수 있고 [여기](https://www.nextflow.io/docs/latest/config.html)에 설명된 우선순위에 따라 해석됩니다. + +이 파트에서는 파트 5: Hello Containers에서 이미 접한 가장 간단하고 일반적인 구성 파일 메커니즘인 `nextflow.config` 파일을 보여드릴 것입니다. + +Process 지시문, 실행자, 프로필 및 매개변수 파일과 같은 Nextflow 구성의 필수 구성 요소를 살펴볼 것입니다. +이러한 구성 옵션을 효과적으로 활용하는 방법을 배우면 파이프라인의 유연성, 확장성 및 성능을 향상시킬 수 있습니다. + +??? info "이 섹션부터 시작하는 방법" + + 이 섹션은 [Hello Nextflow](./index.md) 과정의 파트 1-5를 완료하고 완전히 작동하는 파이프라인이 있다고 가정합니다. + + 이 시점부터 과정을 시작하는 경우 solutions에서 `modules` 디렉토리와 `nextflow.config` 파일을 복사해야 합니다: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + `nextflow.config` 파일에는 Docker 컨테이너 사용을 활성화하는 `docker.enabled = true` 줄이 포함되어 있습니다. + + Hello 파이프라인에 익숙하지 않거나 상기가 필요하면 [이 정보 페이지](../info/hello_pipeline.md)를 참조하십시오. + +--- + +## 0. 워밍업: `hello-config.nf` 실행 + +시작점으로 workflow 스크립트 `hello-config.nf`를 사용할 것입니다. +이 스크립트는 이 교육 과정의 파트 5를 완료하여 생성된 스크립트와 동일하지만, 출력 대상을 변경했습니다: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +변경을 시작하기 전에 모든 것이 제대로 작동하는지 확인하기 위해 스크립트를 한 번 실행하십시오: + +```bash +nextflow run hello-config.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이전과 마찬가지로 `output` 블록에 지정된 디렉토리(`results/hello_config/`)에서 출력 파일을 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +최종 ASCII 아트 출력은 `results/hello_config/` 디렉토리에 `cowpy-COLLECTED-batch-output.txt`라는 이름으로 있습니다. + +??? abstract "파일 내용" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +이것이 정상적으로 작동했다면 파이프라인을 구성하는 방법을 배울 준비가 되었습니다. + +--- + +## 1. Workflow 입력 매개변수 관리 + +지금까지 작업해 온 것의 확장인 구성의 한 측면부터 시작할 것입니다: 입력 매개변수의 관리입니다. + +현재 workflow는 명령줄을 통해 여러 매개변수 값을 허용하도록 설정되어 있으며, 기본값은 workflow 스크립트 자체의 `params` 블록에 설정되어 있습니다. +그러나 명령줄에서 매개변수를 지정하거나 원본 스크립트 파일을 수정하지 않고 해당 기본값을 재정의하고 싶을 수 있습니다. + +이를 수행하는 여러 방법이 있습니다; 매우 일반적으로 사용되는 세 가지 기본 방법을 보여드리겠습니다. + +### 1.1. 기본값을 `nextflow.config`로 이동 + +이것은 가장 간단한 접근 방식이지만, 실행할 때마다 편집하고 싶지 않은 기본 `nextflow.config` 파일이므로 아마도 가장 유연하지 않습니다. +그러나 workflow에서 매개변수를 _선언하는_ 것(확실히 거기에 속함)과 구성 파일에 더 적합한 *기본값*을 제공하는 것의 관심사를 분리하는 이점이 있습니다. + +두 단계로 수행해 봅시다. + +#### 1.1.1. 구성 파일에 `params` 블록 생성 + +`nextflow.config` 파일에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * 파이프라인 매개변수 + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +workflow에서 구성 파일로 `params` 블록을 단순히 복사한 것이 아닙니다. +구문이 약간 다릅니다. +Workflow 파일에서는 타입이 지정된 선언입니다. +구성에서는 값 할당입니다. + +기술적으로 이것만으로도 workflow 파일에 여전히 지정된 기본값을 재정의하기에 충분합니다. +예를 들어 캐릭터를 수정하고 workflow를 실행하여 구성 파일에 설정된 값이 workflow 파일에 설정된 값을 재정의하는지 확인할 수 있습니다. + +그러나 구성을 완전히 구성 파일로 이동하는 정신으로, workflow 파일에서 해당 값을 완전히 제거합시다. + +#### 1.1.2. Workflow 파일의 `params` 블록에서 값 제거 + +`hello-config.nf` workflow 파일에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * 파이프라인 매개변수 + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "수정 전" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * 파이프라인 매개변수 + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +이제 workflow 파일 자체는 이러한 매개변수에 대한 기본값을 설정하지 않습니다. + +#### 1.1.3. 파이프라인 실행 + +올바르게 작동하는지 테스트해 봅시다. + +```bash +nextflow run hello-config.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 이전과 동일한 출력을 생성합니다. + +최종 ASCII 아트 출력은 이전과 마찬가지로 `results/hello_config/` 디렉토리에 `cowpy-COLLECTED-batch-output.txt`라는 이름으로 있습니다. + +??? abstract "파일 내용" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +기능적으로 이 이동은 아무것도 변경하지 않았지만, 개념적으로 구성 파일에 기본값을 설정하는 것이 약간 더 깔끔합니다. + +### 1.2. 실행별 구성 파일 사용 + +좋습니다만, 때때로 메인 구성 파일을 건드리지 않고 다른 기본값으로 일부 임시 실험을 실행하고 싶을 수 있습니다. +실험을 위한 작업 디렉토리로 사용할 하위 디렉토리에 새 `nextflow.config` 파일을 생성하여 이를 수행할 수 있습니다. + +#### 1.2.1. 빈 구성으로 작업 디렉토리 생성 + +새 디렉토리를 생성하고 그곳으로 이동하는 것으로 시작합시다: + +```bash +mkdir -p tux-run +cd tux-run +``` + +그런 다음 해당 디렉토리에 빈 구성 파일을 생성합니다: + +```bash +touch nextflow.config +``` + +이렇게 하면 빈 파일이 생성됩니다. + +#### 1.2.2. 실험 구성 설정 + +이제 새 파일을 열고 사용자 정의하려는 매개변수를 추가하십시오: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +입력 파일 경로는 디렉토리 구조를 반영해야 합니다. + +#### 1.2.3. 파이프라인 실행 + +이제 새 작업 디렉토리 내에서 파이프라인을 실행할 수 있습니다. +경로를 적절하게 조정해야 합니다! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +이렇게 하면 `tux-run/work/` 및 `tux-run/results/`를 포함하여 `tux-run/` 아래에 새 디렉토리 세트가 생성됩니다. + +이 실행에서 Nextflow는 현재 디렉토리의 `nextflow.config`를 파이프라인 루트 디렉토리의 `nextflow.config`와 결합하여 기본 캐릭터(칠면조)를 tux 캐릭터로 재정의합니다. + +최종 출력 파일에는 인사말을 말하는 tux 캐릭터가 포함되어야 합니다. + +??? abstract "파일 내용" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +이제 '정상적인' 구성을 수정하지 않고 실험할 공간이 생겼습니다. + +!!! warning "경고" + + 다음 섹션으로 이동하기 전에 이전 디렉토리로 다시 변경해야 합니다! + + ```bash + cd .. + ``` + +이제 매개변수 값을 설정하는 또 다른 유용한 방법을 살펴봅시다. + +### 1.3. 매개변수 파일 사용 + +하위 디렉토리 접근 방식은 실험에 적합하지만, 약간의 설정이 필요하고 그에 따라 경로를 조정해야 합니다. +특정 값 세트로 파이프라인을 실행하거나 다른 사람이 최소한의 노력으로 실행할 수 있도록 하려는 경우 더 간단한 접근 방식이 있습니다. + +Nextflow를 사용하면 YAML 또는 JSON 형식의 매개변수 파일을 통해 매개변수를 지정할 수 있으므로, 예를 들어 대체 기본값 세트와 실행별 매개변수 값을 관리하고 배포하는 것이 매우 편리합니다. + +#### 1.3.1. 예제 매개변수 파일 검사 + +이를 시연하기 위해 현재 디렉토리에 `test-params.yaml`이라는 예제 매개변수 파일을 제공합니다: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +이 매개변수 파일에는 지정하려는 각 입력에 대한 키-값 쌍이 포함되어 있습니다. +구문을 구성 파일과 비교하면 등호(`=`) 대신 콜론(`:`)을 사용합니다. +구성 파일은 Groovy로 작성되고, 매개변수 파일은 YAML로 작성됩니다. + +!!! info "정보" + + 예제로 매개변수 파일의 JSON 버전도 제공하지만 여기서는 실행하지 않을 것입니다. + 직접 시도해 보십시오. + +#### 1.3.2. 파이프라인 실행 + +이 매개변수 파일로 workflow를 실행하려면 기본 명령에 `-params-file <filename>`을 추가하기만 하면 됩니다. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +최종 출력 파일에는 인사말을 말하는 스테고사우루스 캐릭터가 포함되어야 합니다. + +??? abstract "파일 내용" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +몇 개의 매개변수만 지정해야 할 때 매개변수 파일을 사용하는 것은 과도해 보일 수 있지만, 일부 파이프라인은 수십 개의 매개변수를 예상합니다. +그런 경우 매개변수 파일을 사용하면 방대한 명령줄을 입력하거나 workflow 스크립트를 수정하지 않고도 런타임에 매개변수 값을 제공할 수 있습니다. + +또한 예를 들어 공동 작업자에게 매개변수 세트를 배포하거나 출판물의 보충 정보로 제공하는 것이 더 쉬워집니다. +이렇게 하면 다른 사람들이 작업을 더 재현할 수 있습니다. + +### 핵심 내용 + +Workflow 입력 관리를 위한 주요 구성 옵션을 활용하는 방법을 알게 되었습니다. + +### 다음 단계 + +Workflow 출력이 게시되는 위치와 방법을 관리하는 방법을 배웁니다. + +--- + +## 2. Workflow 출력 관리 + +지금까지 workflow 수준 출력 선언에 대한 모든 경로를 하드코딩해 왔으며, 여러 출력을 추가하기 시작할 때 언급했듯이 약간의 반복이 있을 수 있습니다. + +이를 더 유연하게 구성할 수 있는 몇 가지 일반적인 방법을 살펴봅시다. + +### 2.1. `outputDir` 디렉토리 이름 사용자 정의 + +이 과정의 각 장에서 출력 정의에 하드코딩된 다른 하위 디렉토리에 출력을 게시해 왔습니다. + +사용자 구성 가능한 매개변수를 사용하도록 변경합시다. +이를 위해 완전히 새로운 매개변수를 만들 수 있지만, 바로 거기에 있으므로 `batch` 매개변수를 사용합시다. + +#### 2.1.1. 구성 파일에서 `outputDir` 값 설정 + +Nextflow가 출력을 게시하는 데 사용하는 경로는 `outputDir` 옵션으로 제어됩니다. +모든 출력의 경로를 변경하려면 `nextflow.config` 구성 파일에서 이 옵션에 대한 값을 설정할 수 있습니다. + +`nextflow.config` 파일에 다음 코드를 추가하십시오: + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * 파이프라인 매개변수 + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * 출력 설정 + */ + outputDir = "results/${params.batch}" + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="9" + /* + * 파이프라인 매개변수 + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +이렇게 하면 내장 기본 경로인 `results/`가 `results/` 더하기 하위 디렉토리로서 `batch` 매개변수 값으로 대체됩니다. +원한다면 `results` 부분도 변경할 수 있습니다. + +임시 변경의 경우 명령에서 `-output-dir` 매개변수를 사용하여 명령줄에서 이 옵션을 설정할 수 있습니다(하지만 그러면 `batch` 매개변수 값을 사용할 수 없습니다). + +#### 2.1.2. 하드코딩된 경로의 반복되는 부분 제거 + +출력 옵션에 여전히 하드코딩된 하위 디렉토리가 있으므로 이제 제거합시다. + +workflow 파일에서 다음 코드 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +`outputDir` 기본값을 수정하는 대신 각 경로에 `${params.batch}`를 추가할 수도 있었지만 이것이 더 간결합니다. + +#### 2.1.3. 파이프라인 실행 + +올바르게 작동하는지 테스트해 봅시다. 명령줄에서 배치 이름을 `outdir`로 설정합니다. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 이전과 동일한 출력을 생성하지만, 이번에는 `results/outdir/` 아래에서 출력을 찾습니다. + +??? abstract "디렉토리 내용" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +이 접근 방식을 사용자 정의 경로 정의와 결합하여 원하는 디렉토리 계층을 구성할 수 있습니다. + +### 2.2. Process별로 출력 구성 + +출력을 추가로 구성하는 인기 있는 방법 중 하나는 process별로 수행하는 것입니다. 즉, 파이프라인에서 실행되는 각 process에 대해 하위 디렉토리를 만드는 것입니다. + +#### 2.2.1. 출력 경로를 process 이름에 대한 참조로 교체 + +출력 경로 선언에서 process 이름을 `<task>.name`으로 참조하기만 하면 됩니다. + +workflow 파일에서 다음 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +이렇게 하면 출력 경로 구성에서 남은 하드코딩된 요소가 제거됩니다. + +#### 2.2.2. 파이프라인 실행 + +올바르게 작동하는지 테스트해 봅시다. 명령줄에서 배치 이름을 `pnames`로 설정합니다. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 이전과 동일한 출력을 생성하지만, 이번에는 `results/pnames/` 아래에서 출력을 찾고 process별로 그룹화되어 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +여기서 `intermediates`와 최상위 수준의 최종 출력 간의 구분이 지워졌습니다. +물론 이러한 접근 방식을 혼합하여 예를 들어 첫 번째 출력의 경로를 `intermediates/${sayHello.process}`로 설정할 수 있습니다. + +### 2.3. Workflow 수준에서 게시 모드 설정 + +마지막으로, 반복적인 코드의 양을 줄이는 정신으로 출력별 `mode` 선언을 구성의 단일 줄로 대체할 수 있습니다. + +#### 2.3.1. 구성 파일에 `workflow.output.mode` 추가 + +`nextflow.config` 파일에 다음 코드를 추가하십시오: + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * 출력 설정 + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="12" + /* + * 출력 설정 + */ + outputDir = "results/${params.batch}" + ``` + +`outputDir` 옵션과 마찬가지로, 구성 파일에서 `workflow.output.mode`에 값을 지정하면 workflow 파일에 설정된 것을 재정의하기에 충분하지만, 불필요한 코드를 어쨌든 제거합시다. + +#### 2.3.2. Workflow 파일에서 출력 모드 제거 + +workflow 파일에서 다음 변경을 수행하십시오: + +=== "수정 후" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "수정 전" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +더 간결하지 않습니까? + +#### 2.3.3. 파이프라인 실행 + +올바르게 작동하는지 테스트해 봅시다. 명령줄에서 배치 이름을 `outmode`로 설정합니다. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 이전과 동일한 출력을 생성하지만, 이번에는 `results/outmode/` 아래에서 출력을 찾습니다. +여전히 심볼릭 링크가 아닌 적절한 복사본입니다. + +??? abstract "디렉토리 내용" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +출력별 모드 설정 방식을 여전히 사용하려는 주된 이유는 동일한 workflow 내에서 혼합하고 싶은 경우입니다. 즉, 일부 출력은 복사하고 일부는 심볼릭 링크로 설정합니다. + +이 방식으로 사용자 정의할 수 있는 다른 옵션도 많이 있지만, 이를 통해 옵션의 범위와 선호도에 맞게 효과적으로 활용하는 방법에 대한 감각을 얻을 수 있기를 바랍니다. + +### 핵심 내용 + +출력이 게시되는 디렉토리의 이름 지정 및 구조와 workflow 출력 게시 모드를 제어하는 방법을 알게 되었습니다. + +### 다음 단계 + +소프트웨어 패키징 기술부터 시작하여 컴퓨팅 환경에 workflow 구성을 적응시키는 방법을 배웁니다. + +--- + +## 3. 소프트웨어 패키징 기술 선택 + +지금까지 입력이 어떻게 들어가고 출력이 어디에서 나오는지를 제어하는 구성 요소를 살펴보았습니다. 이제 컴퓨팅 환경에 workflow 구성을 적응시키는 데 더 구체적으로 집중할 때입니다. + +그 경로의 첫 번째 단계는 각 단계에서 실행될 소프트웨어 패키지가 어디에서 오는지 지정하는 것입니다. +로컬 컴퓨팅 환경에 이미 설치되어 있습니까? +이미지를 검색하고 컨테이너 시스템을 통해 실행해야 합니까? +아니면 Conda 패키지를 검색하고 로컬 Conda 환경을 빌드해야 합니까? + +이 교육 과정의 첫 번째 부분(파트 1-4)에서는 workflow에서 로컬로 설치된 소프트웨어만 사용했습니다. +그런 다음 파트 5에서 Docker 컨테이너와 `nextflow.config` 파일을 도입하여 Docker 컨테이너 사용을 활성화했습니다. + +이제 `nextflow.config` 파일을 통해 대체 소프트웨어 패키징 옵션을 구성하는 방법을 살펴봅시다. + +### 3.1. 구성 파일에서 Docker 비활성화 및 Conda 활성화 + +보안상의 이유로 관리자가 Docker 사용을 허용하지 않는 HPC 클러스터에서 작업한다고 가정해 봅시다. +다행히도 Nextflow는 Singularity(HPC에서 더 널리 사용됨)를 포함한 여러 다른 컨테이너 기술과 Conda와 같은 소프트웨어 패키지 관리자를 지원합니다. + +Docker 대신 Conda를 사용하도록 구성 파일을 변경할 수 있습니다. +그렇게 하려면 `docker.enabled` 값을 `false`로 전환하고 Conda 사용을 활성화하는 지시문을 추가합시다: + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +이렇게 하면 Nextflow가 Conda 패키지가 지정된 process에 대해 Conda 환경을 생성하고 활용할 수 있습니다. +즉, 이제 `cowpy` process에 그 중 하나를 추가해야 합니다! + +### 3.2. Process 정의에서 Conda 패키지 지정 + +`cowpy` 도구가 포함된 Conda 패키지의 URI를 이미 검색했습니다: `conda-forge::cowpy==1.1.5` + +이제 `conda` 지시문을 사용하여 `cowpy` process 정의에 URI를 추가합니다: + +=== "수정 후" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "수정 전" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +명확히 하자면, `docker` 지시문을 *교체*하는 것이 아니라 대체 옵션을 *추가*하는 것입니다. + +!!! tip "팁" + + 주어진 conda 패키지에 대한 URI를 얻는 몇 가지 다른 방법이 있습니다. + 컨테이너를 생성할 계획이 없더라도 복사하여 붙여넣을 수 있는 URI를 제공하는 [Seqera Containers](https://seqera.io/containers/) 검색 쿼리를 사용하는 것이 좋습니다. + +### 3.3. Workflow를 실행하여 Conda를 사용할 수 있는지 확인 + +시도해 봅시다. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "명령 출력" + + ```console title="출력" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +이것은 문제 없이 작동하고 `results/conda` 아래에 이전과 동일한 출력을 생성해야 합니다. + +백그라운드에서 Nextflow는 Conda 패키지를 검색하고 환경을 생성했으며, 이는 일반적으로 약간의 작업이 필요합니다; 그래서 우리가 직접 그 작업을 하지 않아도 되니 좋습니다! + +!!! note "참고" + + `cowpy` 패키지가 상당히 작기 때문에 빠르게 실행되지만, 큰 패키지로 작업하는 경우 처음에는 평소보다 약간 더 오래 걸릴 수 있으며, 콘솔 출력이 완료되기 전에 1분 정도 '멈춰' 있는 것처럼 보일 수 있습니다. + 이것은 정상이며 새 패키지를 처음 사용할 때 Nextflow가 수행하는 추가 작업 때문입니다. + +우리 관점에서 보면 백엔드의 메커니즘이 약간 다르더라도 Docker로 실행하는 것과 정확히 동일하게 작동하는 것 같습니다. + +이것은 필요한 경우 Conda 환경으로 실행할 준비가 되었음을 의미합니다. + +??? info "Docker와 Conda 혼합 사용" + + 이러한 지시문은 process별로 할당되므로 '혼합 사용'이 가능합니다. 즉, 사용 중인 컴퓨팅 인프라가 둘 다 지원하는 경우 예를 들어 workflow의 일부 process는 Docker로 실행하고 다른 process는 Conda로 실행하도록 구성할 수 있습니다. + 이 경우 구성 파일에서 Docker와 Conda를 모두 활성화합니다. + 주어진 process에 대해 둘 다 사용 가능한 경우 Nextflow는 컨테이너를 우선시합니다. + + 앞서 언급했듯이 Nextflow는 여러 다른 소프트웨어 패키징 및 컨테이너 기술을 지원하므로 이 두 가지에만 국한되지 않습니다. + +### 핵심 내용 + +각 process가 사용해야 하는 소프트웨어 패키지를 구성하는 방법과 기술 간 전환 방법을 알게 되었습니다. + +### 다음 단계 + +Nextflow가 실제로 작업을 수행하는 데 사용하는 실행 플랫폼을 변경하는 방법을 배웁니다. + +--- + +## 4. 실행 플랫폼 선택 + +지금까지 로컬 실행자로 파이프라인을 실행해 왔습니다. +이것은 Nextflow가 실행 중인 머신에서 각 작업을 실행합니다. +Nextflow가 시작되면 사용 가능한 CPU와 메모리를 확인합니다. +실행할 준비가 된 작업의 리소스가 사용 가능한 리소스를 초과하면 Nextflow는 하나 이상의 이전 작업이 완료되어 필요한 리소스가 확보될 때까지 마지막 작업을 실행에서 보류합니다. + +로컬 실행자는 편리하고 효율적이지만 해당 단일 머신으로 제한됩니다. 매우 큰 워크로드의 경우 사용 가능한 것보다 더 많은 리소스가 필요한 단일 작업이 있거나 단일 머신에서 실행하기를 기다리는 데 너무 오래 걸릴 정도로 많은 작업이 있어 로컬 머신이 병목 현상을 일으키는 것을 발견할 수 있습니다. + +Nextflow는 HPC 스케줄러(Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor 등)뿐만 아니라 클라우드 실행 백엔드(AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes 등)를 포함한 [많은 다른 실행 백엔드](https://www.nextflow.io/docs/latest/executor.html)를 지원합니다. + +### 4.1. 다른 백엔드 대상 지정 + +실행자 선택은 `executor`라는 process 지시문으로 설정됩니다. +기본적으로 `local`로 설정되어 있으므로 다음 구성이 암시됩니다: + +```groovy title="내장 구성" +process { + executor = 'local' +} +``` + +다른 백엔드를 대상으로 하도록 실행자를 설정하려면 리소스 할당에 대해 위에서 설명한 것과 유사한 구문을 사용하여 원하는 실행자를 지정하기만 하면 됩니다(모든 옵션에 대해서는 [문서](https://www.nextflow.io/docs/latest/executor.html) 참조). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "경고" + + HPC에 연결하도록 설정되지 않았기 때문에 교육 환경에서 이것을 실제로 테스트할 수 없습니다. + +### 4.2. 실행 매개변수에 대한 백엔드별 구문 처리 + +대부분의 고성능 컴퓨팅 플랫폼은 리소스 할당 요청 및 제한(예: CPU 수 및 메모리) 및 사용할 작업 큐의 이름과 같은 특정 매개변수를 지정할 수 있도록 허용하고 때로는 요구합니다. + +불행히도 이러한 각 시스템은 작업이 정의되고 관련 스케줄러에 제출되는 방법을 정의하는 데 다른 기술, 구문 및 구성을 사용합니다. + +??? abstract "예제" + + 예를 들어, "my-science-work" 큐에서 8개의 CPU와 4GB의 RAM이 필요한 동일한 작업은 백엔드에 따라 다른 방식으로 표현해야 합니다. + + ```bash title="SLURM 구성 / sbatch를 사용하여 제출" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="PBS 구성 / qsub을 사용하여 제출" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="SGE 구성 / qsub을 사용하여 제출" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +다행히도 Nextflow는 이 모든 것을 단순화합니다. +`cpus`, `memory` 및 `queue`(다른 속성은 문서 참조)와 같은 관련 속성을 한 번만 지정할 수 있도록 표준화된 구문을 제공합니다. +그런 다음 런타임에 Nextflow는 해당 설정을 사용하여 실행자 설정에 따라 적절한 백엔드별 스크립트를 생성합니다. + +다음 섹션에서 해당 표준화된 구문을 다룰 것입니다. + +### 핵심 내용 + +이제 다른 종류의 컴퓨팅 인프라를 사용하도록 실행자를 변경하는 방법을 알게 되었습니다. + +### 다음 단계 + +Nextflow에서 리소스 할당 및 제한을 평가하고 표현하는 방법을 배웁니다. + +--- + +## 5. 컴퓨팅 리소스 할당 제어 + +대부분의 고성능 컴퓨팅 플랫폼은 CPU 수 및 메모리와 같은 특정 리소스 할당 매개변수를 지정할 수 있도록 허용하고 때로는 요구합니다. + +기본적으로 Nextflow는 각 process에 대해 단일 CPU와 2GB의 메모리를 사용합니다. +해당 process 지시문은 `cpus` 및 `memory`라고 하므로 다음 구성이 암시됩니다: + +```groovy title="내장 구성" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +구성 파일에서 추가 process 지시문을 사용하여 모든 process 또는 특정 명명된 process에 대해 이러한 값을 수정할 수 있습니다. +Nextflow는 선택한 실행자에 적합한 명령으로 변환합니다. + +그러나 어떤 값을 사용해야 하는지 어떻게 알 수 있습니까? + +### 5.1. 리소스 활용 보고서를 생성하기 위해 workflow 실행 + +Process에 얼마나 많은 CPU와 메모리가 필요한지 미리 알지 못하는 경우 리소스 프로파일링을 수행할 수 있습니다. 즉, 일부 기본 할당으로 workflow를 실행하고, 각 process가 사용한 양을 기록하고, 거기서 기본 할당을 조정하는 방법을 추정합니다. + +편리하게도 Nextflow에는 이를 수행하기 위한 내장 도구가 포함되어 있으며 요청 시 보고서를 기꺼이 생성합니다. + +그렇게 하려면 명령줄에 `-with-report <filename>.html`을 추가하십시오. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +보고서는 html 파일이며 다운로드하여 브라우저에서 열 수 있습니다. 왼쪽의 파일 탐색기에서 마우스 오른쪽 버튼으로 클릭하고 `미리 보기 표시`를 클릭하여 교육 환경에서 볼 수도 있습니다. + +보고서를 살펴보고 리소스를 조정할 수 있는 기회를 식별할 수 있는지 확인하는 데 몇 분을 투자하십시오. +할당된 것에 대한 백분율로 활용 결과를 보여주는 탭을 클릭해야 합니다. +사용 가능한 모든 기능을 설명하는 [문서](https://www.nextflow.io/docs/latest/reports.html)가 있습니다. + +### 5.2. 모든 process에 대한 리소스 할당 설정 + +프로파일링은 교육 workflow의 process가 매우 가볍다는 것을 보여주므로 process당 기본 메모리 할당을 1GB로 줄입시다. + +파이프라인 매개변수 섹션 앞에 `nextflow.config` 파일에 다음을 추가하십시오: + +```groovy title="nextflow.config" linenums="4" +/* +* Process 설정 +*/ +process { + memory = 1.GB +} +``` + +이렇게 하면 소비하는 컴퓨팅 양을 줄이는 데 도움이 됩니다. + +### 5.3. 특정 process에 대한 리소스 할당 설정 + +동시에 `cowpy` process가 다른 process보다 더 많은 리소스를 필요로 한다고 가정하여 개별 process에 대한 할당을 조정하는 방법을 시연하겠습니다. + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process 설정 + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process 설정 + */ + process { + memory = 1.GB + } + ``` + +이 구성으로 모든 process는 1GB의 메모리와 단일 CPU(암시된 기본값)를 요청하지만, `cowpy` process는 2GB와 2개의 CPU를 요청합니다. + +!!! tip "팁" + + CPU가 적은 머신이 있고 process당 많은 수를 할당하면 process 호출이 서로 뒤에 대기열에 있는 것을 볼 수 있습니다. + 이것은 Nextflow가 사용 가능한 것보다 더 많은 CPU를 요청하지 않도록 보장하기 때문입니다. + +### 5.4. 업데이트된 구성으로 workflow 실행 + +시도해 봅시다. 구성 변경 전후의 성능을 비교할 수 있도록 프로파일링 보고서에 대해 다른 파일 이름을 제공합니다. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +워크로드가 너무 작기 때문에 실제 차이를 느끼지 못할 수 있지만, 이것은 실제 workflow의 성능 및 리소스 요구 사항을 분석하는 데 사용할 접근 방식입니다. + +Process에 다른 리소스 요구 사항이 있는 경우 매우 유용합니다. 추측이 아닌 실제 데이터를 기반으로 각 process에 대해 설정하는 리소스 할당을 적절한 크기로 조정할 수 있습니다. + +!!! tip "팁" + + 이것은 리소스 사용을 최적화하기 위해 할 수 있는 것의 아주 작은 맛보기에 불과합니다. + Nextflow 자체에는 리소스 제한으로 인해 실패한 작업을 재시도하는 정말 멋진 [동적 재시도 로직](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources)이 내장되어 있습니다. + 또한 Seqera Platform은 리소스 할당을 자동으로 최적화하기 위한 AI 기반 도구도 제공합니다. + +### 5.5. 리소스 제한 추가 + +사용 중인 컴퓨팅 실행자와 컴퓨팅 인프라에 따라 할당할 수 있는(또는 해야 하는) 것에 대한 제약이 있을 수 있습니다. +예를 들어, 클러스터에서 특정 제한 내에 있어야 할 수 있습니다. + +`resourceLimits` 지시문을 사용하여 관련 제한을 설정할 수 있습니다. process 블록에 단독으로 있을 때 구문은 다음과 같습니다: + +```groovy title="구문 예제" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow는 지정한 실행자에 따라 이러한 값을 적절한 명령으로 변환합니다. + +교육 환경에서 관련 인프라에 액세스할 수 없으므로 이것을 실행하지 않을 것입니다. +그러나 이러한 제한을 초과하는 리소스 할당으로 workflow를 실행한 다음 `.command.run` 스크립트 파일에서 `sbatch` 명령을 조회하면 실행자에게 실제로 전송되는 요청이 `resourceLimits`에서 지정한 값으로 제한되어 있는 것을 볼 수 있습니다. + +??? info "기관 참조 구성" + + nf-core 프로젝트는 전 세계 다양한 기관에서 공유하는 [구성 파일 모음](https://nf-co.re/configs/)을 컴파일하여 광범위한 HPC 및 클라우드 실행자를 다룹니다. + + 이러한 공유 구성은 해당 기관에서 일하는 사람들이 자신의 기관 구성을 바로 활용할 수 있다는 점과 자체 인프라에 대한 구성을 개발하려는 사람들을 위한 모델로서 모두 가치가 있습니다. + +### 핵심 내용 + +리소스 활용을 평가하기 위한 프로파일링 보고서를 생성하는 방법과 모든 process 및/또는 개별 process에 대한 리소스 할당을 수정하는 방법, HPC에서 실행하기 위한 리소스 제한을 설정하는 방법을 알게 되었습니다. + +### 다음 단계 + +사전 설정 구성 프로필을 설정하고 런타임에 전환하는 방법을 배웁니다. + +--- + +## 6. 프로필을 사용하여 사전 설정 구성 간 전환 + +작업 중인 프로젝트나 사용 중인 컴퓨팅 환경에 따라 파이프라인 구성을 사용자 정의할 수 있는 여러 방법을 보여드렸습니다. + +사용 중인 컴퓨팅 인프라에 따라 대체 설정 간에 전환하고 싶을 수 있습니다. 예를 들어, 노트북에서 로컬로 개발하고 소규모 테스트를 실행한 다음 HPC 또는 클라우드에서 전체 규모 워크로드를 실행하고 싶을 수 있습니다. + +Nextflow를 사용하면 다양한 구성을 설명하는 여러 프로필을 설정할 수 있으며, 구성 파일 자체를 수정하지 않고 명령줄 인수를 사용하여 런타임에 선택할 수 있습니다. + +### 6.1. 로컬 개발과 HPC에서 실행 간 전환을 위한 프로필 생성 + +두 가지 대체 프로필을 설정합시다; 하나는 Docker 컨테이너를 사용하는 일반 컴퓨터에서 소규모 로드를 실행하고, 하나는 Conda 패키지를 사용하는 Slurm 스케줄러가 있는 대학 HPC에서 실행하기 위한 것입니다. + +#### 6.1.1. 프로필 설정 + +파이프라인 매개변수 섹션 뒤에 그리고 출력 설정 앞에 `nextflow.config` 파일에 다음을 추가하십시오: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +대학 HPC의 경우 리소스 제한도 지정하고 있습니다. + +#### 6.1.2. 프로필로 workflow 실행 + +Nextflow 명령줄에서 프로필을 지정하려면 `-profile` 인수를 사용합니다. + +`my_laptop` 구성으로 workflow를 실행해 봅시다. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +보시다시피 런타임에 매우 편리하게 구성 간에 전환할 수 있습니다. + +!!! warning "경고" + + Slurm 스케줄러에 액세스할 수 없으므로 교육 환경에서 `univ_hpc` 프로필은 제대로 실행되지 않습니다. + +앞으로 이러한 프로필과 항상 함께 발생하는 다른 구성 요소를 찾으면 해당 프로필에 간단히 추가할 수 있습니다. +함께 그룹화하려는 다른 구성 요소가 있는 경우 추가 프로필을 만들 수도 있습니다. + +### 6.2. 테스트 매개변수 프로필 생성 + +프로필은 인프라 구성만을 위한 것이 아닙니다. +다른 사람들이 적절한 입력 값을 직접 수집하지 않고도 workflow를 쉽게 시험해 볼 수 있도록 workflow 매개변수의 기본값을 설정하는 데도 사용할 수 있습니다. +이것을 매개변수 파일 사용의 대안으로 고려할 수 있습니다. + +#### 6.2.1. 프로필 설정 + +이 컨텍스트에서 기본값을 표현하는 구문은 `test`라고 이름 지은 프로필에 대해 다음과 같습니다: + +```groovy title="구문 예제" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +workflow에 대한 테스트 프로필을 추가하면 `profiles` 블록은 다음과 같이 됩니다: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +기술 구성 프로필과 마찬가지로 원하는 임의의 이름으로 매개변수를 지정하는 여러 다른 프로필을 설정할 수 있습니다. + +#### 6.2.2. 테스트 프로필로 로컬에서 workflow 실행 + +편리하게도 프로필은 상호 배타적이지 않으므로 다음 구문 `-profile <profile1>,<profile2>`를 사용하여 명령줄에서 여러 프로필을 지정할 수 있습니다(프로필 수에 관계없이). + +동일한 구성 파일에 설명되어 있고 동일한 구성 요소에 대해 값을 설정하는 프로필을 결합하면 Nextflow는 마지막으로 읽은 값을 사용하여 충돌을 해결합니다(즉, 파일에서 나중에 나오는 것). +충돌하는 설정이 다른 구성 소스에 설정된 경우 기본 [우선순위](https://www.nextflow.io/docs/latest/config.html)가 적용됩니다. + +이전 명령에 테스트 프로필을 추가해 봅시다: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +이것은 가능한 경우 Docker를 사용하고 `results/test` 아래에 출력을 생성하며, 이번에 캐릭터는 코믹 듀오 `dragonandcow`입니다. + +??? abstract "파일 내용" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +이것은 workflow 코드와 함께 테스트 데이터 파일을 배포하는 한, 누구나 명령줄이나 매개변수 파일을 통해 자신의 입력을 제공하지 않고도 workflow를 빠르게 시험해 볼 수 있음을 의미합니다. + +!!! tip "팁" + + 외부에 저장된 더 큰 파일에 대한 URL을 가리킬 수 있습니다. + 열린 연결이 있는 한 Nextflow가 자동으로 다운로드합니다. + + 자세한 내용은 사이드 퀘스트 [파일 작업](../side_quests/working_with_files.md)을 참조하십시오. + +### 6.3. `nextflow config`를 사용하여 해결된 구성 확인 + +위에서 언급했듯이 때때로 동일한 매개변수가 결합하려는 프로필에서 다른 값으로 설정될 수 있습니다. +그리고 더 일반적으로, 구성 요소가 저장될 수 있는 수많은 장소가 있으며, 때때로 동일한 속성이 다른 장소에서 다른 값으로 설정될 수 있습니다. + +Nextflow는 충돌을 해결하기 위해 설정된 [우선순위](https://www.nextflow.io/docs/latest/config.html)를 적용하지만 직접 결정하기 어려울 수 있습니다. +그리고 충돌이 없더라도 구성할 수 있는 모든 가능한 장소를 조회하는 것은 지루할 수 있습니다. + +다행히도 Nextflow에는 전체 프로세스를 자동화할 수 있는 `config`라는 편리한 유틸리티 도구가 포함되어 있습니다. + +`config` 도구는 현재 작업 디렉토리의 모든 내용을 탐색하고, 모든 구성 파일을 수집하고, Nextflow가 workflow를 실행하는 데 사용할 완전히 해결된 구성을 생성합니다. +이렇게 하면 아무것도 시작하지 않고도 어떤 설정이 사용될지 알 수 있습니다. + +#### 6.3.1. 기본 구성 해결 + +기본적으로 적용될 구성을 해결하려면 이 명령을 실행하십시오. + +```bash +nextflow config +``` + +??? success "명령 출력" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +이것은 명령줄에서 추가 항목을 지정하지 않으면 얻는 기본 구성을 보여줍니다. + +#### 6.3.2. 특정 설정이 활성화된 구성 해결 + +명령줄 매개변수(예: 하나 이상의 프로필 활성화 또는 매개변수 파일 로드)를 제공하면 명령이 이를 추가로 고려합니다. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "명령 출력" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +이것은 여러 계층의 구성을 포함하는 복잡한 프로젝트에 특히 유용합니다. + +### 핵심 내용 + +프로필을 사용하여 최소한의 번거로움으로 런타임에 사전 설정 구성을 선택하는 방법을 알게 되었습니다. +더 일반적으로, 다른 컴퓨팅 플랫폼에 맞게 workflow 실행을 구성하고 분석의 재현성을 향상시키는 방법을 알게 되었습니다. + +### 다음 단계 + +축하하고 자신에게 큰 칭찬을 해주십시오! 첫 번째 Nextflow 개발자 과정을 완료했습니다. + +배운 내용을 검토하고 다음에 무엇이 올지 알아보려면 최종 [과정 요약](./next_steps.md)으로 이동하십시오. + +--- + +## 퀴즈 + +<quiz> +Nextflow가 자동으로 로드하는 구성 파일의 이름은 무엇입니까? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +동일한 매개변수가 구성 파일과 명령줄 모두에 설정된 경우 어떤 것이 우선합니까? +- [ ] 구성 파일 값 +- [x] 명령줄 값 +- [ ] 먼저 만난 값 +- [ ] 둘 다 아님; 오류가 발생함 + +자세히 알아보기: [1.1. 기본값을 `nextflow.config`로 이동](#11-기본값을-nextflowconfig로-이동) +</quiz> + +<quiz> +동일한 구성에서 Docker와 Conda를 모두 활성화할 수 있습니까? +- [x] 예, Nextflow는 process 지시문에 따라 둘 다 사용할 수 있음 +- [ ] 아니요, 한 번에 하나만 활성화할 수 있음 +- [ ] 예, 하지만 프로필에서만 가능 +- [ ] 아니요, 상호 배타적임 +</quiz> + +<quiz> +Docker와 Conda가 모두 활성화되어 있고 process에 두 지시문이 모두 있는 경우 어떤 것이 우선합니까? +- [x] Docker (컨테이너) +- [ ] Conda +- [ ] 먼저 정의된 것 +- [ ] 오류가 발생함 + +자세히 알아보기: [3. 소프트웨어 패키징 기술 선택](#3-소프트웨어-패키징-기술-선택) +</quiz> + +<quiz> +Nextflow process의 기본 메모리 할당은 얼마입니까? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] 제한 없음 +</quiz> + +<quiz> +구성 파일에서 특정 process에 대한 리소스 요구 사항을 어떻게 설정합니까? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +자세히 알아보기: [5.3. 특정 process에 대한 리소스 할당 설정](#53-특정-process에-대한-리소스-할당-설정) +</quiz> + +<quiz> +리소스 활용 보고서를 생성하는 명령줄 옵션은 무엇입니까? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +자세히 알아보기: [5.1. 리소스 활용 보고서를 생성하기 위해 workflow 실행](#51-리소스-활용-보고서를-생성하기-위해-workflow-실행) +</quiz> + +<quiz> +`resourceLimits` 지시문은 무엇을 합니까? +- [ ] 최소 리소스 요구 사항 설정 +- [ ] Process에 리소스 할당 +- [x] 요청할 수 있는 최대 리소스 제한 +- [ ] 리소스 사용 모니터링 + +자세히 알아보기: [5.5. 리소스 제한 추가](#55-리소스-제한-추가) +</quiz> + +<quiz> +Nextflow의 기본 실행자는 무엇입니까? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +자세히 알아보기: [4. 실행 플랫폼 선택](#4-실행-플랫폼-선택) +</quiz> + +<quiz> +Nextflow를 실행할 때 매개변수 파일을 어떻게 지정합니까? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +자세히 알아보기: [1.3. 매개변수 파일 사용](#13-매개변수-파일-사용) +</quiz> + +<quiz> +프로필은 무엇에 사용할 수 있습니까? (해당되는 것 모두 선택) +- [x] 인프라별 설정 정의 +- [x] 다른 환경에 대한 리소스 제한 설정 +- [x] 테스트 매개변수 제공 +- [ ] 새 process 정의 + +자세히 알아보기: [6. 프로필을 사용하여 사전 설정 구성 간 전환](#6-프로필을-사용하여-사전-설정-구성-간-전환) +</quiz> + +<quiz> +단일 명령에서 여러 프로필을 어떻게 지정합니까? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +자세히 알아보기: [6. 프로필을 사용하여 사전 설정 구성 간 전환](#6-프로필을-사용하여-사전-설정-구성-간-전환) +</quiz> diff --git a/docs/ko/docs/hello_nextflow/index.md b/docs/ko/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..fd41c730ac --- /dev/null +++ b/docs/ko/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow 워크플로우 실행 시작 및 관리 + - Nextflow가 생성한 출력(결과) 및 로그 파일 찾기 및 해석 + - 기본적인 문제 해결 + - 핵심 Nextflow 구성 요소로 간단한 다단계 워크플로우 구축 + - 필수 유형의 채널 팩토리와 연산자를 구분하고 간단한 워크플로우에서 효과적으로 활용 + - HPC 및 클라우드를 포함한 일반적인 컴퓨팅 플랫폼에서 실행되도록 파이프라인 실행 구성 + - 코드 모듈화 및 소프트웨어 컨테이너를 포함하여 파이프라인을 FAIR하게 만드는 재현성, 이식성 및 코드 재사용을 위한 모범 사례 적용 + audience_prerequisites: + - "**대상:** 이 과정은 Nextflow를 처음 접하고 자체 파이프라인을 개발하고자 하는 학습자를 위해 설계되었습니다." + - "**기술:** 명령줄, 기본 스크립팅 개념 및 일반적인 파일 형식에 대한 약간의 친숙함이 있다고 가정합니다." + - "**도메인:** 모든 연습은 도메인에 구애받지 않으므로 사전 과학적 지식이 필요하지 않습니다." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow는 재현 가능하고 확장 가능한 데이터 분석 워크플로우 구축에 대한 실습 입문 과정입니다.** + +실제 예제와 안내 연습을 통해 프로세스 정의, 파이프라인 연결, 파일 및 소프트웨어 종속성 관리, 손쉬운 실행 병렬화, 다양한 컴퓨팅 환경에서 워크플로우 실행 등 Nextflow로 파이프라인을 개발하는 기초를 배웁니다. + +Nextflow로 자체 워크플로우를 개발하고 실행하기 시작할 수 있는 기술과 자신감을 갖추게 됩니다. + +<!-- additional_information --> + +## 과정 개요 + +이 과정은 정보를 점진적으로 소개하는 목표 지향적 연습과 함께 실습 중심으로 설계되었습니다. + +텍스트 입력을 받아 몇 가지 변환 단계를 실행하고 변환된 텍스트를 말하는 캐릭터의 ASCII 그림이 포함된 단일 텍스트 파일을 출력하는 간단한 Nextflow 파이프라인을 개발합니다. + +### 강의 계획 + +개념과 코드로 압도하지 않기 위해 Nextflow로 파이프라인을 개발하는 특정 측면에 초점을 맞춘 여섯 부분으로 나누었습니다. + +| 과정 챕터 | 요약 | 예상 소요 시간 | +| ---------------------------------------------------- | ------------------------------------------------------------------------ | -------------- | +| [파트 1: Hello World](./01_hello_world.md) | Nextflow 워크플로우를 조립하고 실행하는 데 관련된 기본 구성 요소 및 원리 | 30분 | +| [파트 2: Hello Channels](./02_hello_channels.md) | 입력 처리 및 손쉬운 실행 병렬화를 위한 채널과 연산자 사용 | 45분 | +| [파트 3: Hello Workflow](./03_hello_workflow.md) | 채널을 사용하여 여러 단계를 연결하고 단계 간 데이터 전송 처리 | 60분 | +| [파트 4: Hello Modules](./04_hello_modules.md) | 재사용성을 높이고 유지 보수 부담을 줄이기 위한 코드 모듈화 원칙 적용 | 20분 | +| [파트 5: Hello Containers](./05_hello_containers.md) | 소프트웨어 종속성 관리 및 재현성 향상을 위한 메커니즘으로 컨테이너 사용 | 60분 | +| [파트 6: Hello Config](./06_hello_config.md) | 파이프라인 동작 사용자 정의 및 다양한 컴퓨팅 환경에서 사용 최적화 | 60분 | + +이 과정을 마치면 과학적 컴퓨팅 요구 사항에 맞는 재현 가능한 워크플로우를 개발하는 다음 단계를 수행할 준비가 잘 되어 있을 것입니다. + +과정을 수강할 준비가 되셨나요? + +[시작하기 :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/ko/docs/hello_nextflow/next_steps.md b/docs/ko/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..8ad3db276a --- /dev/null +++ b/docs/ko/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# 과정 요약 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello Nextflow 교육 과정을 완료하신 것을 축하드립니다! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube 채널에서 [전체 재생 목록](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik)을 확인하세요. + +:green_book: 비디오와 함께 [비디오 스크립트](./transcripts/07_next_steps.md)를 읽을 수 있습니다. +/// + +## 여러분의 여정 + +하드코딩된 명령을 실행하는 매우 기본적인 워크플로우로 시작했습니다. +여섯 부분에 걸쳐 그 기본 워크플로우를 채널, 연산자, 컨테이너에 대한 내장 지원 및 구성 옵션을 포함한 Nextflow의 핵심 기능을 활용하는 모듈식 다단계 파이프라인으로 변환했습니다. + +### 구축한 것 + +- Hello 워크플로우의 최종 형태는 텍스트 인사말이 포함된 CSV 파일을 입력으로 받습니다. +- 네 단계는 별도의 모듈 파일에 저장된 Nextflow 프로세스(`sayHello`, `convertToUpper`, `collectGreetings`, `cowpy`)로 구현됩니다. +- 결과는 `results/`라는 디렉토리에 게시됩니다. +- 파이프라인의 최종 출력은 대문자로 변환된 인사말을 말하는 캐릭터의 ASCII 아트가 포함된 일반 텍스트 파일입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** 각 인사말을 자체 출력 파일에 씁니다 (예: "Hello-output.txt") +2. **`convertToUpper`:** 각 인사말을 대문자로 변환합니다 (예: "HELLO") +3. **`collectGreetings`:** 모든 대문자 인사말을 단일 배치 파일로 수집합니다 +4. **`cowpy`:** `cowpy` 도구를 사용하여 ASCII 아트를 생성합니다 + +워크플로우 구성은 유연하고 재현 가능한 방식으로 입력과 매개변수를 제공할 수 있도록 지원합니다. + +### 습득한 기술 + +이 실습 과정을 통해 다음을 배웠습니다: + +- 간단한 다단계 워크플로우를 구축하기에 충분한 핵심 Nextflow 구성 요소 설명 및 활용 +- 연산자 및 채널 팩토리와 같은 다음 단계 개념 설명 +- Nextflow 워크플로우를 로컬에서 실행 +- Nextflow가 생성한 출력(결과) 및 로그 파일 찾기 및 해석 +- 기본적인 문제 해결 + +이제 Nextflow에서 자체 파이프라인을 개발하기 시작할 수 있는 기초 지식을 갖추게 되었습니다. + +## 기술 향상을 위한 다음 단계 + +다음에 할 일에 대한 상위 3가지 제안입니다: + +- [과학을 위한 Nextflow](../nf4_science/index.md)로 과학적 분석 사용 사례에 Nextflow 적용 +- [Hello nf-core](../../hello_nf-core/index.md)로 nf-core 시작하기 +- [Side Quests](../side_quests/index.md)로 더 고급 Nextflow 기능 탐색 + +마지막으로, Nextflow 제작자가 개발한 클라우드 기반 플랫폼인 [**Seqera Platform**](https://seqera.io/)을 살펴보시기 바랍니다. 이 플랫폼은 워크플로우 시작 및 관리, 데이터 관리, 모든 환경에서 대화형 분석 실행을 더욱 쉽게 해줍니다. + +## 피드백 설문조사 + +계속 진행하기 전에 과정 설문조사를 완료해 주세요! 여러분의 피드백은 모든 사람을 위한 교육 자료를 개선하는 데 도움이 됩니다. + +[설문조사 참여하기 :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/ko/docs/hello_nextflow/survey.md b/docs/ko/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..2c28281a44 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# 피드백 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +계속 진행하기 전에 이 간단한 5문항 설문조사를 완료하여 교육을 평가하고, 경험에 대한 피드백을 공유하고, Nextflow 여정에서 도움이 될 수 있는 다른 방법을 알려주세요. + +이 설문은 1분 이내에 완료할 수 있습니다. 모든 사람을 위한 교육 자료 개선에 도움을 주셔서 감사합니다! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/ko/docs/hello_nextflow/transcripts/00_orientation.md b/docs/ko/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..9daa7446ed --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# 오리엔테이션 - 비디오 스크립트 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 참고사항" + + 이 페이지는 스크립트만 보여줍니다. 전체 단계별 지침을 보려면 [강좌 자료](../00_orientation.md)로 돌아가십시오. + +## 환영합니다 + +안녕하세요, Hello Nextflow에 오신 것을 환영합니다. 제 이름은 Phil Ewels입니다. 저는 Seqera의 오픈 소스 제품 관리자이며, 오늘 이 첫 번째 Nextflow 교육 과정을 안내하게 되어 매우 기쁩니다. + +저희는 Nextflow의 기초를 다루며, 파이프라인을 작성하고 실행하고 구성하는 방법을 설명할 것입니다. + +그리고 여러분은 간단한 다단계 파이프라인을 직접 구축하게 될 것입니다. 연산자와 채널 팩토리와 같은 용어를 다룰 것이며, 과정이 끝날 때쯤이면 여러분은 자신만의 생물정보학 파이프라인을 구축할 준비가 될 것입니다. + +질문이 있으시면 community.seqera.io로 연락해 주십시오. 저희는 매우 활발한 Nextflow 커뮤니티를 운영하고 있으며, 교육 전용 섹션이 있으니 어디에서 막히셨는지 알려주시면 누군가가 도와드릴 수 있을 것입니다. + +좋습니다. 시작하겠습니다. + +## 교육 웹사이트 + +Nextflow 강좌의 모든 교육 자료는 training.nextflow.io에 있습니다. 웹 브라우저에서 접속하실 수 있습니다. 지금 열어서 함께 살펴보겠습니다. + +저는 버전 2.1.1로 진행할 것입니다. 저희는 여기저기 작은 업데이트와 수정 사항을 푸시하므로 조금 다르더라도 걱정하지 마십시오. 하지만 자료가 너무 많이 변경되었다면 상단의 버전 선택기를 사용하여 제가 설명할 정확한 버전의 자료를 선택하실 수 있습니다. + +라이트 모드를 선호하시는 분들은 여기에서 웹사이트의 테마를 변경하실 수 있습니다. + +여기에서 번역을 볼 수 있지만, 녹화 당시에는 이 새로운 자료를 다루는 것이 실제로 영어뿐입니다. + +또한 GitHub에서 교육 웹사이트와 저희가 작업할 모든 것의 소스 코드를 볼 수 있습니다. + +홈페이지에는 저희가 보유한 모든 다양한 교육 자료 강좌가 나열되어 있습니다. 스크롤을 내리면 여기서 진행할 Hello Nextflow 강좌가 포함된 초보자용 Nextflow를 볼 수 있습니다. 유사한 방식으로 작동하는 다른 모든 강좌도 볼 수 있습니다. + +## 환경 설정 + +저는 실제로 상단의 첫 번째 것으로 시작할 것인데, 이것은 모든 교육 강좌에 공통적이며 특히 환경 설정에 관한 것입니다. + +클릭하면 이 섹션으로 이동하며, 자신의 노트북에서 자신의 VS Code 복사본과 자신의 소프트웨어 설치를 사용하여 로컬에서 개발하는 방법에 대한 지침을 볼 수 있습니다. 또는 대부분의 사람들이 하기를 기대하는 것은 GitHub Codespaces라는 것을 사용하는 것입니다. + +Codespaces는 GitHub에서 제공하는 서비스로, 클라우드에서 웹 서버를 실행하며 여러분이 연결할 수 있습니다. 해당 서버에는 VS Code가 설치되어 있어 웹 브라우저에서 실행할 수 있으며, 원하시면 로컬 VS Code 설치에 연결할 수도 있습니다. 모든 계산, 모든 파일, 모든 편집이 원격으로 발생하므로 필요한 모든 소프트웨어가 사전 설치되어 있고 모두에게 동일합니다. + +## GitHub Codespace 생성하기 + +필요한 모든 것이 포함된 Codespace를 생성하려면 문서 자료에서 "GitHub Codespaces에서 열기"라고 표시된 버튼을 찾으십시오. 지금 클릭하여 새 탭에서 열겠습니다. 그러면 이 웹페이지가 표시됩니다. 이제 nextflow-io 교육으로 사전 구성되어 있음을 알 수 있습니다. + +새 Codespace 생성을 클릭하기만 하면 됩니다. 하지만 실제로는 2개가 아닌 4개의 CPU를 가진 약간 더 큰 머신을 Nextflow 교육에 사용할 것을 권장합니다. 사용할 자료의 버전을 변경할 수 있습니다. 따라서 제가 링크를 따라온 문서 버전이기 때문에 기본값은 2.1.1입니다. 하지만 원한다면 리포지토리의 특정 브랜치로 설정할 수도 있습니다. + +이제 Codespace 생성을 클릭하겠습니다. 그러면 환경 설정이 시작됩니다. + +## Codespace 생성 + +처음 이 작업을 수행할 때는 시간이 꽤 오래 걸리므로 지금이 차 한 잔을 마시기 좋은 시간입니다. 편안하게 앉으시고, 옆에 앉은 사람과 이야기를 나누십시오. + +관심이 있으시면 여기 아래의 codespace 빌드를 클릭하여 설정 로그를 볼 수 있습니다. 여기서 필요한 모든 것이 포함된 Docker 이미지를 가져와 환경을 구성하고 있음을 알 수 있습니다. + +이제 Codespace를 처음 생성할 때만 이렇게 기다려야 합니다. github.com/codespaces로 이동하면 열려 있는 모든 다양한 Codespace를 볼 수 있습니다. 여기 방금 생성한 것이 있습니다. 다음에 이 작업을 수행할 때 여기로 가서 이전 Codespace를 선택하고 바로 다시 돌아갈 수 있습니다. 기존 환경을 준비하는 것이 훨씬 더 빠른 프로세스입니다. 이렇게 하면 VS Code와 파일에 대한 모든 변경 사항도 유지되므로 나갔다가 다시 돌아와도 진행 상황을 잃지 않습니다. + +여기에서 세 개의 점을 클릭하여 다른 작업을 수행할 수 있습니다. 예를 들어, 2개의 CPU로 구성했는데 이제 4개를 원한다면 머신 유형을 변경할 수 있습니다. 또는 처음부터 새로 시작하려면 Codespace를 삭제할 수 있습니다. + +## VS Code 소개 + +좋습니다, Codespace가 환경 설정을 완료했고 이제 웹 브라우저에서 VS Code가 표시됩니다. + +VS Code에 익숙하시다면 매우 친숙하게 느껴질 것입니다. 이전에 사용해 본 적이 없다면 꽤 간단합니다. 알아야 할 페이지의 몇 가지 다른 부분이 있습니다. + +왼쪽에는 사이드바가 있습니다. 교육 리포지토리의 GitHub 리포지토리에 있는 모든 다양한 파일로 설정된 탐색기를 볼 수 있습니다. + +왼쪽의 이 버튼들은 사이드바에서 다양한 도구가 될 수 있습니다. 프로젝트의 모든 파일을 검색할 수 있습니다. Git, GitHub 등 다양한 작업을 할 수 있습니다. + +상단에는 메인 메뉴가 있습니다. 파일 탐색기는 여기에서 가장 많이 사용할 것이며, 이러한 파일 중 하나를 마우스 오른쪽 버튼으로 클릭하여 예상하는 일반적인 작업을 수행할 수 있습니다. 잘라내기, 복사와 같은 경고를 클릭해야 할 수도 있으며 로컬 머신으로 다운로드할 수도 있습니다. + +Codespace가 로드되면 이 메인 영역에 마크다운 파일의 미리보기가 제공됩니다. 이것은 github.com에서 렌더링되는 것과 동일합니다. 닫을 수 있으며 Readme 파일을 더블 클릭하면 코드 편집기에서 코드로 열리는 것을 볼 수 있습니다. 다른 파일과 마찬가지로 이 코드를 직접 편집할 수 있습니다. + +마지막으로 여기 하단에 터미널 창이 있습니다. 빌드 중에 로그를 보고 있었으므로 현재 표시되는 것입니다. 이 플러스 버튼을 눌러 새 터미널 세션을 시작할 수도 있습니다. 이것은 제 머신에서 실행되는 것이 아닙니다. 기억하십시오, 이것은 클라우드에서 실행되고 있으며, tree를 깊이 2로 실행하면 왼쪽에 있던 것과 동일한 모든 파일을 볼 수 있습니다. + +## "hello-nextflow" 파일만 표시하기 + +이 GitHub 리포지토리에는 저희가 진행하는 것뿐만 아니라 모든 다양한 교육 세트가 포함되어 있습니다. 원한다면 Hello Nextflow 폴더에만 집중할 수 있습니다. 이를 조금 정리하는 한 가지 방법은 메뉴 파일로 이동한 다음 작업 공간에 폴더 추가를 선택하는 것입니다. + +클릭하면 training으로 이동하고 Hello Nextflow를 선택한 다음 추가를 클릭합니다. 화면이 새로 고쳐집니다. 그런 다음 탐색기에서 이제 두 개의 다른 작업 공간이 있습니다. 하나는 이전에 교육용으로 사용했던 것이고 다른 하나는 Hello Nextflow만 있는 것입니다. + +원한다면 training을 마우스 오른쪽 버튼으로 클릭하고 작업 공간에서 폴더 제거를 클릭하여 사이드바에서 완전히 제거할 수 있습니다. + +이제 사이드에 이 특정 교육 과정의 파일만 있습니다. 경고를 숨길 수 있으며 이제 여기 터미널에서도 동일한 작업을 수행하고 디렉토리 변경을 위해 CD를 수행할 수 있습니다. Hello Nextflow. 그리고 다시 사이드바에 있는 것과 동일한 파일이 여기에 있습니다. + +## Hello Nextflow: 파일 + +Hello Nextflow 강좌의 이 파일들을 살펴보겠습니다. + +Nextflow용 .nf 파일이 많이 있으며, 교육 과정의 각 챕터마다 이러한 파일 중 하나가 있습니다. 이 파일들을 작업하고 연습에서 수정할 것입니다. + +또한 이 환경에서 Nextflow를 실행하기 위한 기본 구성 설정만 있는 nextflow.config 파일이 있으며, 이 시점에서는 실제로 걱정할 필요가 없습니다. 데이터 처리에 사용할 greetings.csv 파일이 있으며, 이는 이 과정의 다음 부분에서 소개될 것입니다. 그리고 6부에서 사용될 test-params.json 파일이 있으며 지금은 무시할 수 있습니다. + +이러한 Nextflow 파일은 각 연습의 시작일 뿐입니다. 완료되었을 때 어떻게 보여야 하는지 보고 싶다면 solutions 디렉토리로 이동하면 교육 과정의 각 부분에 대한 답이 있으므로 목표로 하는 작동하는 버전을 볼 수 있습니다. + +## 터미널 열기 + +어느 시점에서 터미널을 닫았는데 다시 돌아가는 방법을 기억하지 못하더라도 걱정하지 마십시오. 상단 오른쪽의 이 버튼들은 작업 공간에서 다양한 패널을 열고 닫습니다. 따라서 하단 패널용 버튼을 클릭하면 다시 나타납니다. 여기에서 터미널이 선택되어 있는지 확인하십시오. 터미널 오른쪽의 화살표 버튼을 클릭하여 전체 화면으로 만들 수도 있습니다. + +텍스트를 읽을 수 있도록 VS Code를 확대했기 때문에 제가 이것을 자주 하는 것을 보실 것입니다. 화면 크기에 따라 이 작업을 수행해야 할 수도 있고 아닐 수도 있습니다. 사이드 패널을 최소화하는 것도 마찬가지입니다. + +좋습니다. 환경에 대해서는 충분하다고 생각합니다. 시작할 준비가 된 것 같습니다. 1장을 위해 다음 비디오에서 다시 만나요. + +[다음 비디오 스크립트 :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/ko/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..c625fe8df6 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# 파트 1: Hello World - 대본 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 참고사항" + + 이 페이지는 대본만 보여줍니다. 전체 단계별 지침은 [강의 자료](../01_hello_world.md)로 돌아가십시오. + + 대본에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하세요, Hello Nextflow 첫 번째 장에 오신 것을 환영합니다. + +여섯 파트로 구성된 강의의 첫 번째 파트에서는 Nextflow의 기초를 다루겠습니다. 터미널에서 몇 가지 명령을 실행하는 것부터 시작하여, 그 Bash 명령을 Nextflow 스크립트로 구축하는 방법을 살펴보겠습니다. + +첫 번째 Nextflow 파이프라인을 실행해보고, Nextflow가 무엇을 하는지, 어디서 실행되는지, 어떤 파일을 생성하는지, 그리고 그 파일들의 목적이 무엇인지 확인하겠습니다. + +좋습니다, 시작하겠습니다. + +## training.nextflow.io + +먼저, training.nextflow.io로 이동하십시오. 이전과 마찬가지로 모든 자료가 여기에 작성되어 있으며, 단계별로 작업하겠습니다. 교육 단계를 진행하면서 제 화면을 보여드리겠습니다. 제가 말하는 모든 내용은 교육 자료에 있으므로 자신의 속도에 맞춰 따라올 수 있으며, 모두 거기에서 찾을 수 있습니다. + +이 비디오는 자막도 활성화되어 있으니, 원하시면 자막을 켜서 제가 말하는 내용을 정확히 따라갈 수 있습니다. + +좋습니다, Hello Nextflow로 가겠습니다. 오늘 진행할 강의이며, 첫 번째 비디오에서 오리엔테이션은 이미 완료했으므로 바로 파트 1로 들어가겠습니다. Hello World. + +이제 교육 자료를 떠나 Code Spaces 환경으로 이동하겠습니다. 이것은 첫 번째 비디오에서 설정한 것입니다. 여러분의 시스템에도 이와 매우 유사한 것이 있기를 바랍니다. 저는 VS Code를 사용하고 있으며 교육 자료를 보고 있고, hello Nextflow 디렉토리로 디렉토리를 변경했습니다. + +## 0. 워밍업: Hello World 직접 실행 + +좋습니다. 모두에게 익숙하게 느껴질 몇 가지 기본 사항부터 시작하겠습니다. 터미널에서 매우 기본적인 명령을 작성하는 것부터 시작하겠습니다. 여기 아래에서 'echo Hello World!"'라고 입력하고 엔터를 누르겠습니다. 놀랍지 않게도 터미널은 제가 요청한 대로 해당 문자열을 반환합니다. Hello world. + +좋습니다, 그 다음 위쪽 화살표를 눌러 해당 명령을 가져와서 조금 더 편집하겠습니다. 이번에는 출력을 파일로 리디렉션하겠습니다. 대신 output.txt에 작성하겠습니다. 엔터를 누르면 이번에는 터미널에 아무것도 나타나지 않습니다. 출력이 터미널로 가지 않았기 때문입니다. 파일로 들어갔습니다. + +그런 다음 'cat output.txt'를 수행하여 해당 파일을 읽을 수 있습니다. 여기서 탭을 눌러 파일 이름을 자동 확장하면 거기 있습니다. 파일이 있습니다. + +VS Code의 사이드바 파일 탐색기에서도 해당 파일을 볼 수 있습니다. 더블 클릭하면 여기에서 열 수 있습니다. 클릭하지 않고 VS Code에서 열고 싶다면 "code" 다음 "output.txt"를 입력하면 동일하게 작동합니다. + +좋습니다. 첫 번째 단계입니다. 매우 간단합니다. + +## 1. Hello World 워크플로우 시작 스크립트 검토 + +좋습니다. 이제 정확히 동일한 작업을 수행하겠지만, 터미널에서 직접이 아니라 Nextflow에서 수행하겠습니다. + +시작하기 위해 첫 번째 예제 스크립트를 사용하겠습니다. 이 파일은 Hello World라고 합니다. "ls"를 수행하여 터미널에서 볼 수 있으며, 저는 Mac을 사용하고 있으므로 command 클릭으로 해당 파일을 열 수 있습니다. 또는 여기 사이드바에서 더블 클릭할 수도 있습니다. + +이 파일에서 몇 가지를 볼 수 있습니다. 맨 위에는 이것이 Nextflow 파일임을 나타내는 해시 문이 있으며, 이것이 실행될 수 있는 방법입니다. 여기에 연한 회색의 일반 코드 주석이 있으며, 실행에 영향을 주지 않고 스크립트를 읽는 데 도움이 됩니다. + +그런 다음 두 가지 주요 구조가 있습니다. 여기에 프로세스와 워크플로우가 있습니다. + +Nextflow의 프로세스는 파이프라인의 단계입니다. 실제로 로직을 수행하고 처리를 수행하는 부분입니다. + +그런 다음 하단의 워크플로우는 이러한 프로세스를 함께 연결하고 워크플로우의 로직, 모든 것이 서로 어떻게 연결되는지를 관리합니다. + +프로세스를 먼저 살펴보겠습니다. 잠시 후 워크플로우로 돌아오겠습니다. + +## 1.2 프로세스 정의 + +모든 프로세스는 process 키워드로 시작합니다. 이름이 있고 중괄호가 있으며 중괄호 내의 모든 것이 해당 단일 프로세스입니다. + +프로세스는 script 섹션이 있어야 하며, 여기에는 컴퓨팅 환경에서 실제로 실행되는 코드 부분인 다중 행 문자열의 bash 스니펫이 포함되어 있습니다. + +여기에는 output 문도 있습니다. 이것은 Nextflow에게 스크립트에 의해 생성될 것으로 예상되는 파일을 알려줍니다. 여기서 output에는 path 키워드가 있으며, 이것은 Nextflow에게 이것이 값이나 문자열이 아니라 파일임을 알려줍니다. + +script 블록 내에서 이것은 일반 bash 문일 뿐이며, 터미널에서 작성한 것과 정확히 동일합니다. output.txt라는 파일에 hello world를 에코합니다. 이 output.txt는 output 정의에 의해 선택됩니다. output 정의는 실제로 아무것도 하지 않습니다. 단지 Nextflow에게 무엇을 기대할지 알려주는 것이며, 이 파일이 생성되지 않으면 Nextflow는 오류를 발생시킵니다. + +이 예제는 output.txt와 output.txt를 여기에 하드코딩했기 때문에 좋은 예제가 아닙니다. 이 중 하나가 변경되면 워크플로우에서 오류가 발생합니다. + +잠시 후 다룰 변수를 사용하는 더 나은 방법이 있습니다. + +## 1.3 워크플로우 정의 + +좋습니다. 워크플로우로 내려가면 주석이 있고 sayHello라는 프로세스를 실행합니다. 이것은 여기 위에 있는 동일한 키워드입니다. 이것은 워크플로우가 될 수 있는 가장 간단한 형태입니다. 변수 입력 없이 단일 프로세스를 호출하는 것이므로 다른 것에 연결하지 않습니다. 이 강의의 후반부에서는 변수 입력을 사용하고 채널과 연결하여 이를 더 강력하게 만드는 방법에 대해 이야기하겠습니다. + +## 2. 워크플로우 실행 + +좋습니다, 이것이 필요한 전부입니다. 실행해보고 무슨 일이 일어나는지 봅시다. 터미널을 지우고 "nextflow run"을 수행하겠습니다. 파일 이름인 hello-world.nf를 호출하겠습니다. 이것이 Nextflow 파이프라인을 실행하는 데 필요한 전부입니다. 이 파이프라인은 입력을 받지 않으므로 다른 인수가 필요하지 않습니다. + +엔터를 누르고 무슨 일이 일어나는지 봅시다. + +좋습니다. 다음과 같은 출력이 표시되기를 바랍니다. Nextflow가 실행되었고 어떤 버전을 사용하고 있는지 알려주는 몇 가지 정보가 있습니다. 어떤 스크립트가 시작되었는지 알려주고 이 특정 워크플로우 실행에 대해 무작위로 생성된 이름을 제공합니다. 이 경우 제 것은 "gloomy_crick"이라고 불렸습니다. + +그러나 이 중 가장 중요한 부분은 파이프라인에서 어떤 단계가 실행되었는지 알려주는 것입니다. sayHello라는 프로세스가 실행되었으며 한 번 실행되었고 백 퍼센트 완료되었음을 볼 수 있습니다. + +여기 이 부분은 해당 특정 워크플로우 작업의 해시입니다. 각 프로세스는 한 번 이상 실행되며, 이러한 각 실행을 작업이라고 합니다. + +## 2.2. work 디렉토리에서 출력 및 로그 찾기 + +모든 작업은 실행되는 자체 격리된 디렉토리를 가지므로 워크플로우의 나머지 실행과 분리됩니다. 이 해시는 work 디렉토리 내의 파일 구조에 해당합니다. "tree work"를 수행하면 a0, 그 다음 짧은 해시의 더 긴 버전, 그리고 output.txt 파일을 볼 수 있습니다. 사이드바에서도 볼 수 있습니다. + +사이드바에서 여기에 몇 가지 추가 파일이 있음을 볼 수 있습니다. 터미널에 표시되지 않은 이유는 숨김 파일이기 때문이며, 점으로 시작합니다. 실제로 "tree -a"(모두를 의미)와 "work"를 수행하면 여기에서 볼 수 있습니다. + +이러한 점 파일은 Nextflow가 생성하는 모든 단일 work 디렉토리에 존재하며, 각각 약간 다른 작업을 수행합니다. 먼저 .command.begin은 실행하기 전에 작업을 설정하는 Nextflow 지침을 포함합니다. .command.run은 Nextflow 자체에 의해 실행되는 실제 지침입니다. 그런 다음 .command.sh는 아마도 가장 흥미로운 것입니다. 이것은 프로세스 블록 script에서 해석된 스크립트입니다. + +열어보면 output.txt 파일에 대한 "echo Hello World"가 있음을 볼 수 있습니다. 이 경우 프로세스와 정확히 동일하지만, Nextflow 코드 내에 변수가 있는 경우 모든 작업은 다른 .command.sh를 가지며, 해당 변수가 어떻게 해석되었는지 볼 수 있습니다. + +다른 파일들은 작업이 어떻게 실행되었는지와 관련이 있습니다. 따라서 .command.err, .log 및 .out은 표준 오류, 표준 출력 및 두 가지 결합입니다. 그리고 .exitcode는 Nextflow에게 이 작업이 어떤 종료 코드로 실행되었는지, 성공했는지 아닌지 알려줍니다. + +마지막으로 output.txt 파일이 있으며 확실히 "Hello World"입니다. 이것은 우리가 기대했던 것이고 생성된 것입니다. + +좋습니다. 처음으로 Nextflow를 실행했습니다. 축하합니다. 정말 그렇게 간단합니다. + +다음으로, 파이프라인 실행 방식을 변경할 때마다 코드를 편집할 필요가 없도록 좀 더 편리하게 수행하는 방법으로 넘어가겠습니다. + +## 3. 워크플로우 실행 관리 + +이 디렉토리 구조는 모든 작업을 분리하고 모든 것을 정리하는 데 좋지만, 물론 출력 파일을 찾기에는 그다지 편리하지 않습니다. 파이프라인 결과를 찾기 위해 중첩된 많은 디렉토리를 뒤지고 싶지 않을 것입니다. + +## 3.1. 출력 게시 + +좋은 소식은 그럴 필요가 없다는 것입니다. work 디렉토리는 실제로 Nextflow 자체가 사용하기 위한 것입니다. 따라서 우리가 할 일은 publishDir라는 Nextflow 함수를 사용하는 것입니다. + +워크플로우로 돌아가서 프로세스로 이동합니다. 여기에 지시문이라는 새로운 문을 추가할 수 있습니다. 이것은 Nextflow가 기능 작동 방식을 증강하는 프로세스 상단의 이러한 것들을 부르는 것이며, 우리가 사용할 것은 publishDir라고 합니다. + +여기에서 입력을 시작했으며 VS Code용 Nextflow 확장이 지시문을 제안했음을 볼 수 있으므로 엔터를 누르면 됩니다. + +좋습니다. "results"라는 디렉토리를 지정하고 출력 파일을 거기에 복사하도록 지시하겠습니다. 따라서 mode copy라고 하겠습니다. 좋습니다. 저장하고 워크플로우를 다시 실행하겠습니다. + +nextflow run hello-world.nf + +정확히 동일하게 실행됩니다. 이번에는 해시가 약간 다르지만. Nextflow는 워크플로우를 실행할 때마다 다른 해시를 사용합니다. 그 결과 다른 work 디렉토리 세트가 있습니다. 영역이 대신 EB라고 불리지만, 모든 파일이 동일함을 볼 수 있습니다. 그러나 이번에 새로운 것은 "results"라는 디렉토리도 있다는 것입니다. + +여기 "results" 내에 출력 파일이 있습니다. 이것이 Nextflow에게 지시한 것입니다. "results"라는 디렉토리에 결과 파일을 저장하고 거기에 복사하라고 말했습니다. 따라서 이제 찾기가 훨씬 쉽습니다. 워크플로우를 시작한 위치 옆에 있으며 Nextflow가 실제 실행을 실행한 위치나 방법과 관계없이 원하는 대로 다른 파일을 거기에 구성할 수 있습니다. + +publishDir는 심볼릭 링크를 처리할 수 있으며, 공유 파일 시스템에서 작업하고 공간을 절약하려는 경우 유용합니다. 또한 프로세스에 의해 생성된 모든 파일을 출력으로 정의할 필요가 없습니다. + +Nextflow는 이 output 블록에 정의된 것만 복사합니다. 따라서 이 프로세스의 다운스트림에서 필요하지 않은 단계에서 생성된 중간 파일이 있는 경우 출력에 정의하지 않으면 publishDir에 나타나지 않습니다. 따라서 이것은 파이프라인의 출력 파일을 깨끗하게 유지하고 작업 위치가 완료되면 중간 파일을 쉽게 삭제하는 방법입니다. + +간단한 참고사항입니다. workflow output definitions라는 새로운 Nextflow 구문이 나오고 있으며, 이는 결국 publishDir를 대체할 것입니다. 이것은 workflow 블록의 파이프라인 수준에서 워크플로우의 모든 출력을 정의하는 방법을 제공합니다. 시도해보고 싶다면 Nextflow 문서에 설명되어 있습니다. 그러나 지금은 publishDir가 한동안 있을 것이므로 2025년 교육에 여전히 포함되어 있습니다. + +## 3.2. -resume으로 워크플로우 재시작 + +좋습니다. 여기 work 디렉토리에는 이제 워크플로우를 실행할 때마다 다른 해시의 두 세트 결과가 있다고 언급했습니다. 좋습니다. 그러나 때로는 필요하지 않은 경우 매번 단계를 다시 계산하고 싶지 않습니다. + +워크플로우를 반복적으로 구축하고 단계를 추가하고 있으며 첫 번째 단계가 캐시된 버전을 재사용하기를 원할 수 있습니다. 또는 워크플로우 중간에 컴퓨팅 시스템에 문제가 발생하여 중단된 위치에서 계속하되 이미 완료한 단계는 건너뛰기를 원할 수 있습니다. + +Nextflow에는 resume이라는 이를 위한 내장 기능이 있습니다. 시도해봅시다. 먼저 work 디렉토리를 살펴보겠습니다. 그래서 거기에 무엇이 있었는지 기억할 수 있습니다. + +그런 다음 "nextflow run hello-world.nf"를 수행하고 여기에 단일 명령 "-resume"을 추가하겠습니다. + +단일 대시에 주목하십시오. 정말 중요합니다. 실행하면 출력이 몇 가지 작은 차이점을 제외하고는 기본적으로 정확히 동일하게 보일 것입니다. + +여기 회색으로 "cached"라고 표시되어 있습니다. 이것은 Nextflow가 이번에 작업을 실행하지 않았음을 의미합니다. 요구 사항과 일치하는 것을 찾았고 단계를 다시 실행하는 대신 해당 출력을 직접 재사용했습니다. + +확실히 여기 해시를 보면 이전 실행에서 가졌던 기존 해시에 해당함을 볼 수 있습니다. + +## 3.3. 이전 work 디렉토리 삭제 + +좋습니다. 그러나 반복적으로 개발하는 경우 이러한 워크플로우 파일이 많이 쌓일 것입니다. 공간이 부족한 경우 문제가 될 수 있습니다. + +Nextflow는 몇 가지 도우미 명령으로 이러한 work 디렉토리를 정리하는 데 도움을 줄 수 있습니다. "nextflow log"를 수행하면 이 디렉토리에서 수행한 모든 다른 워크플로우 실행 목록이 제공되며, 여기에 실행 이름이 있습니다. 처음 실행한 gloomy quick 하나와 이 두 개의 새로운 것을 볼 수 있습니다. + +이제 해당 이름을 가져와서 "nextflow clean" 명령과 함께 사용할 수 있습니다. 단일 실행 이름을 지정할 수 있습니다. 또는 더 나은 방법은 "-before"로 단일 워크플로우 이름 이전의 모든 것을 삭제하도록 Nextflow에 지시할 수 있으며, "stupefied_shaw"를 입력하겠습니다. 그것이 가장 최근 실행이었습니다. "-n". + +"-n" 명령은 Nextflow에게 실제로 아무것도 삭제하지 않고 드라이 런으로 수행하도록 지시했으며, 제거되었을 해시 디렉토리를 알려줍니다. 확실히 첫 번째 실행에서 그 하나만 있습니다. 두 번째 실행 모두 동일한 해시 디렉토리를 사용합니다. + +다시 실행하겠지만 이번에는 드라이 런을 위한 "-n" 대신 force를 위한 "-f"를 수행하겠습니다. 그러면 해당 해시 디렉토리가 제거되었습니다. 이제 "tree work"를 수행하면 이 출력 파일만 남아 있음을 볼 수 있습니다. + +좋습니다. 그래서 거기서 많은 디스크 공간을 정리할 수 있었습니다. + +work 디렉토리를 삭제할 때 주의해야 할 몇 가지 사항이 있습니다. results 디렉토리에 심볼릭 링크한 경우 해당 심볼릭 링크 소스가 이제 삭제되고 결과가 영원히 사라집니다. 그래서 copy 모드를 사용하는 것이 더 안전한 일이며 일반적으로 권장하는 것입니다. + +둘째, Nextflow의 resume 기능은 이러한 work 디렉토리에 의존합니다. 따라서 삭제하고 Nextflow를 다시 실행하면 resume 기능이 더 이상 작동하지 않습니다. 따라서 필요할 수도 있고 필요하지 않을 수도 있는 것을 추적하고 안전하다고 확신할 때만 삭제하는 것은 사용자의 몫입니다. + +우리가 할 수 있는 다른 방법은 워크플로우 실행을 완료하고 더 이상 필요하지 않다고 확신하는 경우 전체 work 디렉토리를 삭제하는 것입니다. + +따라서 "rm -r work"를 수행할 수 있습니다. 거기에 중요한 것이 없다는 것을 알고 있습니다. 우리가 복사한 results 디렉토리에 우리가 관심 있는 결과가 있습니다. 따라서 work 디렉토리를 삭제하는 것이 안전했습니다. 어떤 접근 방식을 사용할지는 사용자에게 달려 있습니다. + +## 4. 명령줄에서 전달된 변수 입력 사용 + +좋습니다, 다음은 무엇입니까? 여기 워크플로우 스크립트에 output.txt 파일의 일부 값을 하드코딩했으며, 더 나은 방법이 있을 수 있다고 언급했습니다. + +이것을 시작하겠습니다. 세 가지 작업을 수행할 것입니다. 프로세스에 새 입력을 추가하고, 프로세스 스크립트에 해당 입력을 사용하는 방법을 알려주고, Nextflow를 실행할 때 명령줄 플래그로 동적으로 사용할 수 있도록 워크플로우에 연결하겠습니다. + +먼저 할 일. 여기에 input 블록을 추가하겠습니다. output과 마찬가지로 이것은 프로세스의 새 섹션이며, "val greeting"이라고 하겠습니다. + +여기서 "val"이라고 하는 것에 주목하십시오. 이것은 path가 아니라 변수임을 나타냅니다. + +그런 다음 스크립트로 내려가서 여기 하드코딩된 텍스트를 제거하고 $greeting을 수행할 수 있습니다. 이것은 다른 프로그래밍 언어와 마찬가지로 작동합니다. 여기에서 변수를 정의하고 이 script 블록 내에서 참조합니다. Nextflow가 이 프로세스를 실행하면 변수가 보간됩니다. 그리고 .command.sh 파일을 보러 가면 대신 실제 하드코딩된 문자열을 여기에서 볼 수 있습니다. + +## 4.1.3. CLI 매개변수 설정 및 프로세스 호출에 입력으로 제공 + +좋습니다, 그러나 변수를 어디에 제공합니까? 다음으로 workflow 섹션으로 이동하면, 여기 확장이 이제 입력을 기대한다고 말하고 있으며 경고를 주었습니다. + +이제 가장 간단하게 할 수 있는 것은 하드코딩하는 것입니다. "Hello World"를 작성하고 해당 문자열 입력을 프로세스에 제공할 수 있습니다. 그러나 다시 말하지만 그것은 실제로 어떤 문제도 해결하지 못할 것입니다. 무언가를 변경하고 싶을 때마다 파이프라인 코드를 편집해야 하므로 좋지 않습니다. + +좋은 소식은 Nextflow에 매개변수라는 명령줄 인수를 처리하는 내장 시스템이 있다는 것입니다. 따라서 대신 params라는 특수 변수 중 하나를 사용할 수 있으며 원하는 대로 호출할 수 있지만 워크플로우 로직과 일치하도록 greeting이라고 하겠습니다. + +저장하고 이것으로 무엇을 할 수 있는지 봅시다. + +터미널로 돌아가면 "nextflow run hello-world.nf"를 수행합니다. 이전과 마찬가지지만 주요 차이점은 --greeting을 수행한다는 것입니다. + +여기에 두 개의 대시가 있다는 점에 주목하십시오. 이것은 매개변수이기 때문입니다. 이전에 워크플로우를 재개했을 때 단일 대시였습니다. 그것은 resume이 핵심 Nextflow 옵션이고 이것은 파이프라인에 특정한 매개변수이기 때문입니다. + +두 가지를 혼동하지 마십시오. 그렇게 하기 쉽습니다. 단일 대시 대신 --resume을 수행했다면 "params.resume"이 되어 아무것도 하지 않을 것입니다. 마찬가지로 여기에서 단일 대시를 수행했다면 Nextflow는 이것을 주요 인수로 인식하지 못할 것입니다. + +따라서 params.greeting에 해당하는 --greeting입니다. + +이제 원하는 텍스트를 뒤따를 수 있습니다. 현재 스웨덴에 있으므로 "Hej världen"이라고 하겠습니다. + +실행해서 무슨 일이 일어나는지 봅시다. 진실의 순간입니다. + +좋습니다. 이전과 마찬가지로 프로세스가 단일 실행으로 sayHello가 실행되었음을 볼 수 있습니다. + +이것은 publishDir "results" 디렉토리에 있던 파일을 덮어썼을 것입니다. 따라서 파일을 다시 실행할 때 주의하십시오. 게시 영역의 것들이 덮어쓰여질 것이기 때문입니다. + +이제 "code results/output.txt"를 수행할 수 있으며, 확실히 출력이 업데이트되어 이제 "Hej världen"이라고 표시됩니다. + +## 4.2. 명령줄 매개변수에 기본값 사용 + +좋습니다, 훌륭합니다. 그러나 이제 문제는 워크플로우가 항상 이 매개변수를 정의하는 것에 의존한다는 것이며, 기본값을 재정의하지 않는 한 워크플로우에 대해 합리적인 방식으로 실행되도록 합리적인 기본값을 갖는 것이 좋습니다. + +따라서 우리가 하는 방법은 워크플로우 스크립트에서 매개변수에 대한 기본값을 설정하는 것입니다. + +hello-world.nf 파일로 돌아가서 workflow 바로 위의 스크립트로 이동하여 "params.greeting"을 입력하고 다른 변수처럼 정의할 수 있습니다. 여기에 문자열을 넣고 "Holà mundo!"라고 하겠습니다. + +이제 이 매개변수에는 여기서 사용될 기본값이 정의되어 있거나 이전과 마찬가지로 --greeting으로 명령줄에서 여전히 재정의할 수 있습니다. + +작동하는지 확인해 봅시다. "nextflow run hello-world.nf" + +이번에는 명령줄 인수가 없으며 올바른 작업을 수행했는지 확인합니다. + +"code results/output.txt". 거기 있습니다. 기본값을 얻었습니다. + +좋습니다. 다시 시도해 봅시다. 거짓말을 하고 있지 않은지 확인하십시오. 다시 실행하되 --greeting을 수행하고 교육 자료의 예제를 사용하여 "Konnichiwa!"라고 하겠습니다. + +워크플로우를 다시 실행하면 확실히 상단의 출력 파일이 명령줄에서 제공한 새 값으로 업데이트되었습니다. + +좋습니다. 이것은 Nextflow 워크플로우를 작성하는 데 있어 정말 중심적인 측면입니다. 파이프라인 코드에서 합리적인 기본값을 정의하되, 터미널에 명령줄 인수를 사용하여 최종 사용자가 구성하기 매우 쉽게 만듭니다. + +최종 사용자는 여러 다른 위치에서 config를 덮어쓸 수 있습니다. 수행하는 모든 단일 Nextflow 실행에 적용되는 홈 디렉토리에 config 파일이 있을 수 있습니다. 시작 디렉토리에 config 파일이 있을 수 있습니다. 파이프라인 디렉토리에 config 파일이 있을 수 있습니다. 이러한 모든 다른 config 위치는 Nextflow 문서에 설명된 특정 순서로 로드됩니다. + +좋습니다, 섹션 1의 끝입니다. 프로세스와 워크플로우를 포함한 Nextflow의 첫 번째 워크플로우 스크립트를 가졌습니다. 입력, 출력, 스크립트 및 게시, 그리고 매개변수와 입력 채널을 프로세스에 연결하는 방법을 살펴보았습니다. + +축하합니다. Nextflow 코드 작성을 위한 첫 번째 단계가 완료되었습니다. + +잠시 쉬고 몇 분 후 2장에서 뵙겠습니다. + +[다음 비디오 대본 :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/ko/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..aebdefe3fa --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Part 2: Hello Channels - 스크립트 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 사항" + + 이 페이지는 스크립트만 보여줍니다. 전체 단계별 지침을 보려면 [교육 자료](../02_hello_channels.md)로 돌아가십시오. + + 스크립트에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하십니까, Hello Nextflow의 파트 2에 오신 것을 환영합니다. + +이 장의 제목은 Hello Channels입니다. Nextflow의 이 기본적인 부분에 대해 모두 이야기할 것입니다. + +Channel은 파이프라인의 서로 다른 단계를 연결하는 것으로, 데이터와 로직이 워크플로우를 통해 흐르는 방식입니다. + +좋습니다, 시작해 보겠습니다. + +training.nextflow.io로 이동하는 것부터 시작하겠습니다. + +사이드바에서 Hello Nextflow를 찾아 파트 2를 클릭하십시오. Hello Channels입니다. + +모든 자료가 여기에 작성되어 있으므로 자신의 속도로 따라가며 놓친 부분을 확인할 수 있습니다. + +웹사이트를 열었으면 Codespaces를 로드할 수 있으며, 지난 장의 마지막 부분부터 계속 진행하겠습니다. + +## 0. 준비운동: hello-channels.nf 실행하기 + +이 장에서는 다른 파일을 편집할 것입니다. 이 파일의 이름은 Hello Channels이므로 사이드바에서 찾아 더블 클릭하여 여십시오. + +이제 막 1장에서 오셨다면 이 파일이 매우 익숙해 보일 것입니다. 여기의 시작점은 기본적으로 1장을 마친 곳으로, sayHello라는 프로세스, 입력, 출력, publishDir, params.greeting, 그리고 간단한 워크플로우가 있습니다. + +새로운 파일로 시작하고 있으므로 모두에게 공평한 출발점이지만, 원하시면 이전 파일을 계속 사용하셔도 됩니다. + +참고로, 저는 모든 .nextflow\* 파일과 work 디렉토리를 삭제하여 깨끗한 시작점을 만들었습니다. 이것을 하든 안 하든 상관없으며, 선택에 달려 있습니다. + +좋습니다. 이 파이프라인이 예상대로 작동하는지 확인하는 것부터 시작하겠습니다. 여기서 터미널을 열겠습니다. + +"nextflow run hello-channels.nf"를 입력하고 엔터를 누르십시오. + +작은 워크플로우를 실행하고, sayHello 단계를 실행하고, 해시가 있는 work 디렉토리를 생성하며, 여기 results 폴더가 있고 출력 파일이 있습니다. 기본 params.greeting에서 예상한 대로입니다. + +좋습니다. 1장과 정확히 같으며, 예상대로 작동합니다. + +## 1. 채널을 통해 명시적으로 변수 입력 제공하기 + +1장에서는 실제로 이미 channel을 사용하고 있었지만, 그것을 깨닫지 못했을 뿐입니다. 여기에 문자열을 지정했을 때, Nextflow는 프로세스를 호출하고 있다는 것을 알았기 때문에 입력 channel이 필요하다는 것을 알고 자동으로 해당 문자열 주위에 channel을 생성했습니다. + +우리가 할 첫 번째 일은 실제로 channel 자체를 입력하여 명시적으로 만드는 것입니다. + +## 1.1. 입력 채널 생성하기 + +스크립트 하단의 workflow로 이동하여 greeting_ch라고 입력하겠습니다. 이것은 Nextflow 코드에서 자주 사용하는 관례로, channel일 때 변수 이름 끝에 언더스코어 ch를 붙이는 것입니다. 이렇게 하면 channel임을 쉽게 식별할 수 있지만, 반드시 그렇게 할 필요는 없습니다. equals channel of Hello Channels. + +방금 사용한 것은 Nextflow 언어에서 "Channel Factory"라고 불리는 것입니다. 이것이 여기 있는 것으로, 이 변수를 새 channel로 설정하고 있으며, 여기의 이 channel factory가 특정 방식으로 channel을 생성하고 있습니다. + +Nextflow에는 다양한 유형의 입력에서 channel을 생성하는 여러 가지 channel factory가 있습니다. Dot of는 가장 간단한 것으로, 우리가 제공하는 모든 문자열을 받습니다. + +VS Code에서 이러한 단어 위에 마우스를 올려놓으면 Nextflow 확장 프로그램이 이 구문이 무엇을 하는지 설명하는 팝업을 제공하며, 팝업 창 하단에 더 읽기 텍스트도 있습니다. + +그것을 클릭하면 Nextflow 문서가 새 탭에서 열리고 이 특정 항목에 대한 문서로 바로 이동합니다. 이 경우 channel.of에 대한 것입니다. + +## 1.2. 프로세스 호출에 채널을 입력으로 추가하기 + +확장 프로그램이 경고도 제공하고 있으며, 여기서 새 channel을 생성했지만 아무것도 사용하지 않고 있다고 말하고 있습니다. + +그러니 고쳐봅시다. 새 channel 이름을 가져와서 이 params.greeting을 우리의 새 channel로 교체하겠습니다. + +이제 명령줄 플래그 --greeting을 더 이상 사용하지 않으며, params.greeting이 사용되지 않고, 이 문자열을 다시 하드코딩하고 있습니다. 괜찮습니다. 저는 단순하게 유지하려고 합니다. 나중에 다시 돌아와서 params를 사용하겠습니다. + +## 1.3. 워크플로우 명령을 다시 실행하기 + +좋습니다, 이것이 작동하는지 다시 확인해 봅시다. 터미널을 열고 다시 확인합니다. Nextflow run hello channels. output.txt를 확인하면, 거기 있습니다. + +좋습니다. 약간 지루한 예제이지만, 이전과 정확히 같은 일을 하고 있습니다. 하지만 이제 적어도 로직이 좀 더 명확합니다. 새 channel을 작성하는 것에 대해 명시적으로 작성하고 있습니다. + +효과적으로 같은 일을 하기 위해 더 많은 코드를 작성했습니다. 하지만 channel을 생성하는 방법이 좀 더 복잡해지면서 이것이 더 의미가 있기 시작할 것입니다. + +## 2. 여러 입력 값에서 실행되도록 워크플로우 수정하기 + +좋습니다, 이것을 좀 더 흥미롭게 만들어 봅시다. Nextflow 파이프라인을 단일 입력에서 실행하는 것은 매우 드물므로 여러 입력을 제공해 봅시다. + +## 2.1. 입력 채널에 여러 인사말 로드하기 + +여기 문서에서 이러한 다른 문자열 세 개를 복사하겠습니다. Hello, Bonjour, Olà. 오, Copilot이 몇 가지 다른 것을 제안하고 있습니다. 그러니 탭으로 입력하겠습니다. + +여기 Nextflow 문서는 이 연산자에 여러 값을 제공할 수 있다고 알려주므로 작동해야 하지만, 시도해 보고 무슨 일이 일어나는지 봅시다. + +## 2.1.2. 명령을 실행하고 로그 출력 보기 + +음. 예, 아니오. 봅시다. 여기서 5개 중 5개의 작업이 실행되었다고 말하지만, 하나의 해시만 표시하는데, 이것은 약간 이상합니다. 괜찮습니다. 여기서 모든 것이 예상대로입니다. 기본적으로 Nextflow는 ANSI 제어 코드라고 하는 특별한 유형의 터미널 출력을 사용하며, 이는 실행 중인 모든 다른 프로세스의 멋진 압축 보기를 제공하기 위해 특정 줄을 덮어씁니다. + +이것은 더 큰 워크플로우가 있고 수백 또는 수천 개의 다른 샘플을 실행할 때 훨씬 더 의미가 있습니다. 터미널에서 너무 많은 출력을 생성하여 보는 것이 불가능한 반면, 이 업데이트 보기는 실시간 진행 상황을 제공합니다. + +## 2.1.3. -ansi-log false 옵션으로 명령을 다시 실행하기 + +원하시면 다시 실행할 수 있으며, 이번에는 단일 하이픈과 함께 추가 Nextflow 핵심 인수를 사용하여 "-ansi-log false"라고 하겠습니다. 이것은 이전 버전의 Nextflow 로그 출력을 사용합니다. 그리고 여기서 시작된 모든 개별 프로세스를 볼 수 있습니다. + +이것을 하든 안 하든 선택 사항입니다. Nextflow의 출력은 두 경우 모두 정확히 같습니다. + +## 2.2. 출력 파일 이름이 고유하도록 보장하기 + +좋습니다, 출력 파일을 봅시다. results로 가겠습니다. 하지만 단일 출력 파일만 있습니다. 무슨 일이 일어났나요? 프로세스가 여러 번 실행되었다는 것을 보았습니다. work 디렉토리로 가서 모든 다른 해시를 볼 수 있으며, 모든 작업이 제대로 실행되었습니다. 하지만 여기 프로세스에서 모든 것을 output.txt 파일에 저장한 다음 이 디렉토리에 게시하는 것을 기억하신다면, + +동일한 파일이 5번 생성된 다음 5번 덮어쓰기 되었습니다. 그리고 마지막으로 실행된 작업만 있습니다. + +## 2.2.1. 동적 출력 파일 이름 구성하기 + +이것을 수정하는 방법은 동적 출력 파일 이름을 사용하는 것입니다. 여기 프로세스 내에 이미 greeting이라는 변수가 있으므로 출력 파일 이름에 사용할 수 있습니다. 복사하고 $greeting-output.txt를 수행하겠습니다. + +bash가 여기에 들어갈 수 있는 공백으로 인해 혼란스러워하지 않도록 따옴표로 둘러싸겠습니다. 그런 다음 동일한 파일 이름을 가져와 여기 출력을 업데이트하겠습니다. + +출력이 이것과 일치하는 것이 정말 중요합니다. 그렇지 않으면 이 파일을 찾을 수 없고 Nextflow가 충돌합니다. + +하나 더 정말 중요한 편집을 하겠습니다. 이 단일 따옴표를 이중 따옴표로 변경하겠습니다. 그렇게 했을 때 코드의 색상이 변경된 것을 주목하십시오. 이 변수는 이중 따옴표를 사용할 때만 확장됩니다. 여기서 단일 따옴표를 사용하면 리터럴 값으로 사용되며, $greeting-output이라는 단일 파일을 얻게 되는데, 이것은 제가 원하는 것이 아닙니다. + +## 2.2.2. 워크플로우 실행하기 + +그러니 이중 따옴표를 다시 넣고 시도해 봅시다. + +시작하기 전에 디렉토리를 정리하여 새 파일을 쉽게 볼 수 있도록 하겠습니다. .nextflow, work, results라는 모든 것을 삭제하겠습니다. + +그리고 Nextflow 명령을 다시 실행하고 어떤 파일이 생성되는지 봅시다. 거기서 5개의 프로세스를 실행합니다. 매우 자세히 보고 있었다면 실행 중에 해당 줄이 업데이트되는 것을 보았을 것입니다. + +이제 results 디렉토리로 들어가면, 확실히 5개의 다른 출력이 있고 모두 다른 인사말로 접두사가 붙어 있습니다. + +각각을 열면 각각 해당 인사말이 포함되어 있음을 알 수 있습니다. 환상적입니다. 그것이 우리가 원하는 것입니다. + +## 3. 연산자를 사용하여 채널의 내용 변환하기 + +좋습니다, 이제 channel이 무엇인지, channel factory가 무엇인지 알고 있습니다. operator는 어떻습니까? 이것은 Nextflow 언어의 또 다른 용어로, channel에서 작동하여 특정 작업을 수행할 수 있는 일련의 함수입니다. Nextflow는 다양한 방식으로 channel을 조작할 수 있는 일련의 operator와 함께 제공됩니다. + +## 3.1. 채널에 입력으로 값 배열 제공하기 + +예제를 통해 작업해 봅시다. 이러한 입력 문자열을 가져오되, channel factory에 직접 넣는 대신 배열로 정의하고 싶다고 가정해 봅시다. + +## 3.1.1. 입력 변수 설정하기 + +그러니 이것들을 가져와서 위에 새 줄로 만들고 greetings, array라고 하겠습니다. + +됐습니다. 그 배열 변수를 가져와 channel.of에 넣고 저장을 누르겠습니다. + +## 3.1.3. 워크플로우 실행하기 + +이제 무슨 일이 일어나는지 봅시다. 터미널로 돌아가겠습니다. 모든 임시 파일을 다시 정리하겠습니다. 그리고 워크플로우를 실행해 봅시다. + +좋지 않습니다. 좋습니다. 깨졌습니다. 괜찮습니다. 이번에는 깨질 것으로 예상했습니다. Nextflow 워크플로우가 실패할 때 무엇이 잘못되었는지 디버깅하는 것은 Nextflow 개발자가 되는 핵심 부분입니다. 이것은 많이 발생할 것이며 오류 메시지가 무엇을 말하는지, 어떻게 처리하는지 이해하는 것이 중요합니다. + +Nextflow 오류 메시지는 실제로 매우 구조화되어 있습니다. 어떤 프로세스가 잘못되었는지 알려줍니다. 이유에 대한 오류 메시지를 제공합니다. 특정 작업 내에서 실행하려고 시도한 명령이 무엇이었는지, 종료 상태가 무엇이었는지, 해당 작업 work 디렉토리가 어디에 있었는지에 대한 출력이 무엇이었는지 말합니다. + +VS Code에서 이것을 옵션 클릭하면 사이드바에서 열리므로 바로 거기로 가서 이전 장에서 이야기한 모든 숨겨진 파일을 볼 수 있습니다. .command.sh 파일을 포함합니다. 이것을 보면 여기에서 실행된 명령과 동일합니다. + +이 파일을 보면 배열의 각 요소에 대해 단일 작업을 실행하는 대신 마지막에 수행한 것처럼 전체 배열을 문자열로 한 번에 제공했다는 것을 알 수 있습니다. 그러므로 channel에 전달하기 전에 해당 배열을 개별 값으로 풀어야 합니다. 돌아가서 operator를 사용하여 그렇게 할 수 있는지 봅시다. + +## 3.2. 연산자를 사용하여 채널 내용 변환하기 + +이 경우 channel에 전달하기 전에 배열을 변경하지 않을 것입니다. 예상하는 방식으로 작동하도록 channel을 조정할 것입니다. flatten operator를 사용하여 그렇게 할 것이며 dot를 입력하기 시작하면 VS Code 확장 프로그램이 사용할 수 있는 모든 다른 operator를 제안하기 시작하는 것을 볼 수 있습니다. + +## 3.2.1. flatten() 연산자 추가하기 + +그리고 flatten을 선택하겠습니다. Nextflow에서 이 컨텍스트에서 공백은 중요하지 않습니다. 원하시면 새 줄에 이러한 operator를 넣을 수 있습니다. 그래서 여기 아래로 내려서 ".of" 아래에 오도록 들여쓰기를 할 수 있으며, 사람들이 종종 channel에 많은 operator를 이런 식으로 연결하고 읽기 쉽도록 이런 식으로 들여쓰기하는 것을 볼 수 있습니다. + +이전처럼 이것 위에 마우스를 올려놓고 flatten operator가 무엇을 하는지 읽을 수 있으며, 원하시면 문서에 대한 링크를 따라갈 수도 있습니다. + +따라서 이 operator는 내부에 단일 배열이 있는 이 channel을 가져와서 배열 값을 분리합니다. + +## 3.2.2. view()를 추가하여 채널 내용 검사하기 + +특별한 view operator를 사용하여 channel을 들여다볼 수 있으며, 여기에 몇 개를 추가하겠습니다. 이것은 다른 언어에서 print 문을 사용하는 것과 비슷합니다. 그래서 dot view를 수행한 다음 이러한 물결 모양 괄호를 사용하겠습니다. + +이것을 closure라고 합니다. 이것은 기본적으로 view operator에 추가 코드를 제공하며, channel 내의 각 항목에 대해 실행됩니다. 이 경우 greeting before flatten이라고 하겠습니다. Greeting. + +여기서 이 closure의 범위 내에서만 사용되는 변수를 정의하고 있습니다. 따라서 이 변수는 여기서만 사용되며 원하는 대로 호출할 수 있습니다. 읽기 쉽게 하기 위해 greeting을 사용하고 있을 뿐입니다. + +일부 Nextflow 파이프라인에서는 사람들이 "$it"라는 특별한 암시적 변수를 사용하는 것을 볼 수 있습니다. 이와 같이. 이것은 Nextflow 코드 내의 특별한 변수로, 작은 변수 정의를 할 필요가 없도록 하는 약어입니다. 그러나 시간이 지남에 따라 우리는 이것이 Nextflow를 처음 접하는 사람들에게 매우 명확하지 않다고 생각하고 있으며, 이제 "$it"의 사용을 권장하지 않습니다. + +그러니 greeting을 사용하는 이전 동작을 고수하고 이렇게 사용하겠습니다. 무슨 일이 일어나고 있는지 더 명시적이고 명확하기 때문입니다. + +그런 다음 이 줄을 복사하고 flatten 인수 다음에 정확히 같은 작업을 다시 수행하겠습니다. view operator는 요소에서 무언가를 수행하지만 다음 operator로 계속 전달하므로 이와 같이 작업 체인 중간에 연결할 수 있으며 거기에 상태를 인쇄하고 계속 진행합니다. 따라서 이것이 flatten operator 전후에 channel이 어떻게 보이는지 보여줄 것입니다. + +## 3.2.3. 워크플로우 실행하기 + +시도해 봅시다. 워크스페이스의 모든 것을 정리합니다. 파이프라인을 다시 실행합니다. + +좋습니다, 5개의 프로세스를 다시 실행했다는 것을 볼 수 있습니다. 오류와 함께 충돌하지 않았으므로 확실히 좋습니다. 이제 before flatten이 있고 확실히 배열이 있으며 after flatten이 5번 인쇄되었으며 배열의 각 요소마다 한 번씩입니다. 그것이 정확히 우리가 바라던 것입니다. 그래서 정말 좋은 소식입니다. 그리고 그것은 코드에서 예상한 것과 정확히 일치합니다. + +더 이상 이러한 디버그 문이 필요하지 않으므로 주석 처리하거나 삭제할 수 있습니다. 코드를 깔끔하고 깨끗하게 유지하기 위해 삭제하겠습니다. 좋습니다, 좋습니다. 이 예제는 이제 잘 작동하고 있으며 channel이 좀 더 복잡한 로직을 수행할 수 있는 방법을 보기 시작할 수 있습니다. + +## 4. 연산자를 사용하여 CSV 파일에서 입력 값 파싱하기 + +이제 대신 일련의 입력이 있는 파일을 사용하여 이것을 수행해 보겠습니다. 이것은 샘플 시트 또는 메타데이터 CSV를 사용하여 Nextflow 파이프라인을 작성하는 매우 일반적인 방법입니다. + +## 4.1. CSV 파일을 인사말 소스로 예상하도록 스크립트 수정하기 + +사이드바로 이동하면 예제 리포지토리에서 greetings.csv를 볼 수 있으며, 이것은 세 가지 다른 인사말이 포함된 세 줄만 포함하는 매우 매우 간단한 CSV 파일입니다. 워크플로우 내에서 이 CSV 파일을 사용할 수 있는지 봅시다. + +이제 1장에서 했던 것처럼 params를 사용하여 명령줄 입력을 가질 수 있도록 하겠습니다. + +이 greetings 배열을 삭제하겠습니다. + +## 4.1.1. 입력 매개변수를 CSV 파일을 가리키도록 전환하기 + +params greeting을 파일 이름인 greetings.csv로 설정하겠습니다. 그리고 이 특별한 변수를 사용하여 channel을 생성하겠습니다. 거기에 넣겠습니다. 오류가 사라집니다. 이것이 기본적으로 이 변수를 설정하고 있다는 것을 기억하십시오. 따라서 인수 없이 파이프라인을 실행하면 greetings.csv를 사용하지만, 원하면 --greeting을 수행하여 이 변수를 덮어쓸 수 있습니다. + +## 4.1.2. 파일을 처리하도록 설계된 채널 팩토리로 전환하기 + +좋습니다, 이제 문자열이나 문자열 배열이 아닌 파일을 전달하고 있으므로 다른 channel factory가 필요할 것입니다. + +지금까지 사용해 온 "of"를 없애고 대신 .fromPath를 사용하겠습니다. 이것은 들리는 것처럼 정확히 수행합니다. 문자열 파일 이름이나 glob을 사용하여 값 대신 경로가 있는 channel을 생성합니다. 또한 파일을 전달하고 있으므로 더 이상 필요하지 않으므로 flatten operator를 제거하겠습니다. + +## 4.1.3. 워크플로우 실행하기 + +저장을 누르고 터미널을 열고 워크플로우를 실행한 다음 무슨 일이 일어나는지 봅시다. + +좋습니다. 다시 충돌했습니다. 걱정하지 마십시오. 이것도 예상했습니다. 오류 메시지를 살펴보고 무엇이 잘못되고 있는지 알아낼 수 있는지 봅시다. 여기서 실행된 명령을 볼 수 있으며, 전체 배열이 인쇄된 것처럼 이전과 비슷합니다. 이제 파일 내용을 살펴보는 대신 명령으로 에코되는 파일 경로가 있습니다. + +## 4.2. splitCsv() 연산자를 사용하여 파일 파싱하기 + +따라서 대신 파일의 내용을 사용하려면 다른 operator가 필요합니다. 이것에 사용할 operator는 splitCsv라고 합니다. CSV 파일을 로드하고 있으므로 의미가 있습니다. + +## 4.2.1. 채널에 splitCsv() 적용하기 + +좋습니다, splitCsv. 닫는 괄호. 여기에는 인수가 필요하지 않습니다. 그리고 다시, 여기서 무슨 일이 일어나고 있는지에 대한 통찰력을 제공하기 위해 일부 view operator를 사용하겠습니다. + +.view csv after splitCsv. Before split Csv. + +## 4.2.2. 워크플로우를 다시 실행하기 + +좋습니다, 이것을 실행하고 무슨 일이 일어나는지 봅시다. + +좋습니다, 이번에는 좀 더 많은 출력이 있지만 여전히 실패했습니다. view 문을 보면 여기서 before split CSV를 볼 수 있으며, 이전 오류 메시지에서 보았던 것처럼 파일 경로가 있습니다. After split CSV에서는 이제 CSV 파일의 세 줄에 해당하는 세 개의 값이 있습니다. + +그러나 이러한 각 값이 대괄호로 둘러싸여 있는 것을 볼 수 있습니다. 따라서 그 각각은 그 자체로 배열이었고, 이것은 문자열이 아닌 배열을 에코하려고 시도하는 이전과 동일한 영역을 제공했습니다. + +CSV 파일에 대해 생각해 보면 이것은 어느 정도 의미가 있습니다. 일반적으로 CSV 파일에는 행과 열이 있으므로 split CSV는 2차원 배열을 수행합니다. 배열의 첫 번째 차원은 각 행이고, 각 행의 각 열인 두 번째 차원이 있습니다. + +따라서 여기서는 각 줄에 단일 값만 있으므로 단일 열이 있으므로 파일의 각 줄에 대해 1개 요소 배열이 있습니다. + +괜찮습니다. 파싱된 CSV 파일의 각 줄에 대해 해당 배열을 축소하려면 다른 operator가 필요합니다. 이것을 정리합시다. 터미널을 없애고 무엇을 할 수 있는지 봅시다. + +## 4.3. map() 연산자를 사용하여 인사말 추출하기 + +이제 이전에 사용했던 flatten operator를 다시 사용할 수 있습니다. 배열을 일련의 값으로 축소할 수 있는 방법을 보았으며, 여기서 매우 잘 작동할 것입니다. 하지만 map operator라는 워크플로우 내에서 매우 일반적인 다른 operator를 시연할 기회를 사용하겠습니다. + +## 4.3.1. 채널에 map() 적용하기 + +dot map을 수행하고 item item[0]을 수행하겠습니다. + +다른 많은 코드 언어를 작성하는 경우 이미 map operator에 익숙할 수 있습니다. 배열이나 channel과 같은 반복 가능한 것을 가져와서 그 각 값에 대해 일부 작업을 수행합니다. + +여기서 우리는 이 closure의 범위 내에서 item이라는 변수를 정의해야 한다고 말하고 있으며, 그 다음 해당 배열의 첫 번째 값만 반환하기를 원합니다. 따라서 item index zero입니다. + +이것은 효과적으로 배열을 평탄화하고 있습니다. 하지만 이것을 더 복잡하게 확장할 수 있는 방법을 볼 수 있습니다: CSV 파일에 6개의 열이 있지만 네 번째 열에만 관심이 있다면 여기에서 특정 인덱스에 액세스할 수 있습니다. 또는 다운스트림 처리로 전달하기 전에 값에 대해 다른 종류의 작업을 수행할 수 있습니다. + +따라서 map operator는 비행 중에 channel을 수정하는 데 매우 유연하고 강력합니다. 실행에서 무엇을 하고 있는지 볼 수 있도록 다른 view 문을 넣겠습니다. 해당 줄을 판결하고 아래로 이동할 수 있습니다. 그리고 after map. + +## 4.3.2. 워크플로우를 한 번 더 실행하기 + +터미널을 열고 워크플로우를 실행해 봅시다. + +좋습니다, 이번에는 오류가 없습니다. 좋은 신호입니다. 이제 view 문의 모든 다른 출력을 살펴볼 수 있습니다. Before split CSV에서 단일 경로가 있었습니다. After split CSV에서 단일 값 배열이 있었고, after map 다음에 배열 구문 없이 값만 있습니다. results 디렉토리로 올라가면 출력 파일이 우리가 원하는 대로 정확히 작동하고 있습니다. + +여기에 작은 보너스가 있습니다. view operator가 수행한 출력 순서가 약간 섞여 있는 것을 실제로 볼 수 있습니다. 이것은 Nextflow가 이러한 다른 작업의 병렬화를 수행하고 있기 때문입니다. 따라서 CSV를 분할한 후 이 channel에 세 개의 요소가 있으며 이러한 세 요소의 처리를 자동으로 병렬로 처리하고 있습니다. 즉, 출력 순서가 확률적이며 변할 수 있습니다. 이 경우 일부 view operator가 후속 단계가 완료된 후 반환되어 이 순서로 나왔습니다. + +동일한 워크플로우를 다시 실행하면. 확실히 다른 순서로 나왔으며 이번에는 예상대로 순서대로 split CSV와 map을 얻었습니다. + +따라서 Nextflow가 이 병렬화를 자동으로 처리하고 있기 때문에 프로세스 작업의 출력 순서에 의존할 수 없다는 점을 명심하십시오. Nextflow는 데이터 흐름 로직으로 그것을 수행하며, 그것이 Nextflow의 진정한 힘입니다. + +좋습니다, 이것은 아마도 전체 교육에서 가장 중요한 장 중 하나일 것입니다. channel, channel factory 및 operator를 이해하면 Nextflow의 강점과 프로그래밍 언어로서 독특하게 만드는 것에 대한 열쇠를 얻기 시작합니다. 이 기능을 통해 Nextflow는 모든 워크플로우를 자동으로 병렬화하고 매우 깔끔한 구문과 푸시 데이터 흐름 모델로 극도로 복잡한 워크플로우 로직을 생성할 수 있습니다. 처음에는 약간 이상한 개념일 수 있지만, 이와 같은 코드를 작성하는 데 익숙해지면 빠르게 자연스럽게 느껴질 것이며, 알기도 전에 환상적인 워크플로우를 작성하게 될 것입니다. + +휴식을 취하고 차 한 잔을 마시고 산책을 하고 이러한 개념을 더 복잡한 워크플로우로 확장하기 시작하는 3장으로 넘어갑시다. 다음 비디오에서 뵙겠습니다. + +[다음 비디오 스크립트 :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/ko/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..fd2c1ea8ed --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Part 3: Hello Workflow - 대본 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 사항" + + 이 페이지는 대본만 보여줍니다. 전체 단계별 지침은 [교육 자료](../03_hello_workflow.md)로 돌아가십시오. + + 대본에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하세요, "Hello Nextflow" 교육 과정의 세 번째 파트에 오신 것을 환영합니다. + +이 챕터의 제목은 "Hello Workflow"입니다. + +챕터 2에서는 하나의 프로세스로 구성된 간단한 워크플로를 만들었지만, 실제로 파이프라인은 여러 분석 단계를 함께 연결할 수 있기 때문에 유용합니다. + +이 챕터에서는 초기 예제를 가져와서 좀 더 현실적으로 확장할 것입니다. + +몇 가지 추가 단계를 추가하고 채널을 사용하여 이러한 단계를 연결하는 방법을 살펴볼 것입니다. + +단일 프로세스로 축소할 수 있는 여러 작업을 살펴보고 여러 입력과 여러 출력을 가질 수 있는 프로세스를 살펴볼 것입니다. + +좋습니다, 시작하겠습니다. + +자, 시작해봅시다. 이전과 동일합니다. training.nextflow.io로 이동합니다. Hello Nextflow, 챕터 3. Hello Workflow. 그리고 작업 공간을 열겠습니다. 이전 챕터의 모든 작업 파일을 정리했고 Hello Workflow를 열겠습니다. + +이것은 지금까지 작업해온 것과 동일한 파일이므로 익숙할 것입니다. say hello 프로세스가 있습니다. greetings CSV 파일이 있는 params.greeting이 있고, CSV 파일을 로드하고 채널을 생성하여 프로세스에 전달하는 하단의 워크플로가 있습니다. + +## 0. 준비 운동: hello-workflow.nf 실행하기 + +원하시면 이것을 시도해보고 예상대로 작동하는지 확인할 수 있습니다. 터미널을 로드하여 nextflow run hello workflow nf를 실행하고 엔터를 누릅니다. + +좋습니다. 세 개의 프로세스가 실행됩니다. 세 개의 출력이 있는 results 디렉토리가 있습니다. Bonjour. Hello. Holà. 그럼 이 파일들을 닫고, 터미널을 닫고, 스크립트로 돌아갑시다. + +## 1. 워크플로에 두 번째 단계 추가하기 + +좋습니다. 예제에서는 기본적이고 도메인에 구애받지 않도록 노력하겠습니다. 따라서 두 번째 프로세스는 이러한 문자열과 단어를 간단한 방식으로 조작할 것입니다. translate Unix 명령을 사용하여 이러한 파일을 가져와서 모두 대문자로 만들 것입니다. "tr" 명령으로 수행합니다. + +## 1.1. 대문자 변환 명령을 정의하고 터미널에서 테스트하기 + +bash 터미널에서 이것을 시도하고 작동하는지 확인할 수 있습니다. echo, Hello World를 입력하고 파이프 문자로 tr에 전달합니다. 그리고 인식 패턴, a부터 z, 그리고 변환할 대상을 제공합니다. 대문자 A부터 Z까지. + +이것은 문자 그대로 A부터 Z까지의 문자를 다루기 때문에 매우 간단합니다. 따라서 악센트가 있는 문자나 그런 것들에는 작동하지 않습니다. 하지만 예제의 목적으로는 이해하실 수 있을 것입니다. + +엔터를 누르면 터미널에 대문자 HELLO WORLD가 출력됩니다. 그리고 이전과 마찬가지로 원하면 파일로 리디렉션할 수 있습니다. Outfile. + +좋습니다. 이것을 정리하겠습니다. + +## 1.1. 대문자 변환 단계를 Nextflow 프로세스로 작성하기 + +스크립트로 돌아가서 이 bash 명령을 처리할 새 프로세스를 작성하겠습니다. 이전 프로세스를 복사하여 아래에 붙여넣고 convert to upper라고 부르겠습니다. 대문자용입니다. 동일한 publishDir results를 사용하겠지만 여기서 몇 가지 변경을 하겠습니다. val 대신 path input file을 사용하고, 출력 파일이 덮어쓰기되지 않도록 여기에 upper라는 접두사를 사용하겠습니다. 그리고 입력의 변수 이름을 사용하겠습니다. 그런 다음 여기 스크립트를 변경하고, 대신 입력 파일에 cat을 사용하고 Bash에서 했던 것처럼 TR, a-z, upper input file .txt를 사용하겠습니다. 좋습니다, 저장을 클릭하겠습니다. + +## 1.2. workflow 블록에 새 프로세스 호출 추가하기 + +이제 아래로 스크롤하면 실제로 이 프로세스를 호출해야 합니다. 스크립트에 프로세스를 추가하는 것만으로는 충분하지 않습니다. Nextflow에게 이 프로세스를 실행해야 하고 어디서 실행해야 하는지 알려야 합니다. + +그래서 여기서 convert to upper를 실행하겠습니다. + +좋습니다, 여기서 인수가 필요하다는 오류가 발생하고 있습니다. 확실히 이 프로세스가 실제로 무언가를 할 수 있도록 무언가를 전달해야 합니다. + +## 1.3. 첫 번째 프로세스의 출력을 두 번째 프로세스로 전달하기 + +우리가 할 일은 이 프로세스에서 출력을 가져오는 것입니다. 그래서 이름 say hello를 가져와서 dot out을 수행합니다. + +단일 출력만 있는 프로세스를 새 프로세스에 전달하는 이와 같은 간단한 예제의 경우, 단일 입력이 있으므로 필요한 전부여야 합니다. 저장을 클릭하고 터미널을 불러와서 다시 실행해보겠습니다. + +## 1.4. 워크플로를 다시 실행하기 + +이제 이전에 이 워크플로를 실행했을 때의 work 디렉토리를 정리하지 않았습니다. 다시 실행하고 부분 캐싱이 어떻게 작동하는지 보여주는 기회로 사용하겠습니다. 그래서 단일 대시 resume을 수행합니다. 마지막으로 실행했을 때와 정확히 동일했던 첫 번째 프로세스의 출력을 재사용하기를 바랍니다. 하지만 이제 이전에 실행된 적이 없는 새 프로세스가 있으므로 처음부터 실행됩니다. 그리고 확실히 첫 번째 프로세스가 캐시 출력을 사용했고 두 번째 출력이 3개 중 3개를 실행했음을 알 수 있습니다. 또한 이제 첫 번째 프로세스인 say hello가 세 번 실행되고 두 번째 프로세스인 convert to upper가 세 번 실행되는 두 프로세스가 모두 여기에 있음을 알 수 있습니다. + +다시 실행하면, 상기시켜드리자면, -ansi-log false로 실행하면 각각 세 개씩 총 6개의 다른 프로세스 작업이 실행되는 것을 볼 수 있습니다. 이것은 우리가 기대했던 것과 정확히 일치합니다. 첫 번째 프로세스가 세 번 실행되고 해당 출력을 두 번째 프로세스로 전달하여 세 번 실행됩니다. + +work 디렉토리 내부를 살펴보고 Nextflow가 이러한 파일 입력을 어떻게 처리하는지 확인해봅시다. 두 번째 프로세스에서 여기 해시 디렉토리를 가져오면 이러한 파일을 보기 위해 -a로 tree 명령을 다시 사용할 수 있습니다. 여기에 Bonjour-output.txt 파일인 입력 파일이 있고 실제로 심볼릭 링크입니다. 이 화살표가 보여주는 것이고, 이전 work 디렉토리의 파일을 가리키고 있습니다. + +이것은 말이 됩니다. Nextflow는 자체 캡슐화된 디렉토리에서 각 작업의 실행을 처리하므로 완전히 독립적입니다. 그러나 이전 단계의 파일을 입력으로 제공해야 합니다. work 디렉토리 외부에 도달하여 해당 파일을 가져오는 대신, Nextflow는 work 디렉토리로 스테이징합니다. + +여기처럼 공유 파일 시스템이 있는 경우 추가 파일 공간을 사용하지 않도록 심볼릭 링크를 사용하여 수행합니다. 다른 위치의 버킷이 있는 클라우드 스토리지를 사용하는 경우 해당 파일을 가져와서 실제로 work 디렉토리에 복사합니다. + +command sh 파일을 살펴봅시다. code work, command sh를 수행하면 확실히 로컬 디렉토리에서 해당 파일에 액세스하고 있음을 알 수 있습니다. 따라서 모든 것이 매우 독립적이고 깨끗합니다. + +또한 results 디렉토리를 확인하고 이러한 파일이 제대로 출력되었는지 확인할 수 있습니다. 그리고 확실히 results에서 첫 번째 프로세스의 모든 출력 파일과 두 번째 프로세스의 모든 출력 파일을 볼 수 있습니다. 그리고 우리가 바랐던 대로 모두 대문자입니다. + +여기서 Nextflow의 힘이 빛나기 시작합니다. 매우 최소한의 코드로 Nextflow는 별도의 work 디렉토리 내에서 깨끗한 캡슐화와 입력 및 출력 파일 스테이징 및 파일 게시를 자동으로 처리하여 이러한 작업을 병렬로 실행합니다. 따라서 분석 워크플로의 복잡성을 확장함에 따라 이 기능이 정말 정말 가치가 있음을 알 수 있습니다. + +## 2. 모든 인사말을 수집하는 세 번째 단계 추가하기 + +좋습니다. 이러한 단계는 일대일이었습니다. 첫 번째 프로세스에서 하나의 출력이 두 번째 프로세스의 하나의 입력으로 전달되었습니다. 다음으로, 이러한 다른 출력을 단일 프로세스 작업으로 수집하는 방법에 대해 이야기하겠습니다. 이것은 다시 매우 일반적인 작업입니다. 그럼 빠르게 터미널을 불러와서 이것의 드라이 런을 수행해봅시다. + +## 2.1. 수집 명령을 정의하고 터미널에서 테스트하기 + +속임수를 쓰고 교육 자료에서 예제 bash 코드를 복사하여 엔터를 누르겠습니다. + +여기서 볼 수 있는 것은 이 echo 명령을 세 개의 다른 출력 파일에 세 번 실행했고, 여기서 볼 수 있습니다. 그런 다음 cat 명령을 사용하여 이 세 개의 다른 파일 각각의 출력을 출력하고 단일 수집 파일로 리디렉션했습니다. + +그리고 "cat COLLECTED-output"을 수행하면 이제 단일 파일에 이 세 개의 다른 파일의 내용이 있는 것을 볼 수 있습니다. + +## 2.2. 수집 단계를 수행하는 새 프로세스 만들기 + +이제 Nextflow 파이프라인 내에서 동일한 것을 복제할 수 있는지 확인해봅시다. + +위로 스크롤하여 세 번째 프로세스를 만들겠습니다. 이전 프로세스를 복사하고 이번에는 Collect Greetings라고 부르겠습니다. + +bash 터미널에서 collected output txt라고 불렀습니다. 그래서 여기에 동일한 path output을 사용하겠습니다. 그리고 여기서 리디렉션을 수행하므로 동일한 방식으로 저장됩니다. + +좋습니다. 해당 명령의 시작 부분에서 발생하는 것을 변경해야 하며 여기서 입력 파일이 무엇인지 생각해야 합니다. 사실 이 프로세스는 여러 입력 파일을 받을 것입니다. path를 유지하고 이것을 input files(복수형)라는 새 변수로 변경하겠습니다. + +그런 다음 bash 스크립트에서 했던 것처럼 다시 cat을 사용하겠습니다. 그리고 여기서 변수를 사용하겠습니다. + +이제 이것이 작동하지 않을 것이라고 생각할 수 있습니다. 이전에 문자열 배열 또는 경로 배열이 프로세스에 전달되어 오류가 발생한 실패를 봤습니다. 하지만 실제로 여기서 Nextflow는 올바른 방식으로 자동으로 이것을 처리할 것입니다. 여러 다른 입력 파일을 가져와서 여기에 다른 파일 경로를 출력할 것입니다. + +물론 cat 명령이 이와 같은 일련의 파일 이름을 받을 수 있다는 것이 도움이 됩니다. 각 파일 경로 전에 인수가 필요한 다른 명령이나 그런 것을 사용하는 경우 이러한 파일 경로의 반복을 처리할 수 있도록 여기에 좀 더 많은 코드와 로직이 있어야 합니다. 하지만 이 경우에는 그냥 작동해야 합니다. + +## 2.3. 워크플로에 수집 단계 추가하기 + +좋습니다, 워크플로로 내려가서 새 프로세스를 추가하겠습니다. Collect greetings. 그리고 다시 convert to upper out의 출력을 가져옵니다. 저장하겠습니다. + +시도해봅시다. nextflow run hello workflow. + +좋습니다, 워크플로가 실행되었지만 뭔가 이상합니다. 예상대로 첫 번째 단계가 세 번 실행되었습니다. 두 번째는 세 번의 작업이 있지만 마지막에도 모든 출력을 병합하는 단일 작업만 예상했는데 세 개의 작업이 있습니다. + +results 디렉토리로 가면. 또한 collected output에 세 개 대신 단일 값만 있는 것을 볼 수 있습니다. 이는 해당 출력 파일이 세 개의 다른 값으로 세 번 덮어쓰기되었기 때문입니다. + +이것은 이전 단계에서 했던 것과 같은 방식으로 여기서 하나의 출력을 하나의 입력으로 전달했기 때문에 말이 됩니다. + +## 2.4. 연산자를 사용하여 인사말을 단일 입력으로 수집하기 + +따라서 여기서 세 개의 요소가 있는 이 채널을 가져와서 단일 요소로 축소하여 최종 프로세스가 한 번만 실행되도록 하는 연산자가 필요합니다. + +이를 위해 collect 연산자를 사용할 것입니다. 워크플로 내에서 직접 수행할 수 있습니다. .out을 수행하고 마지막에 .collect 연산자를 연결할 수 있습니다. + +저장을 누릅니다. 그리고 이 교육의 목적을 위해 이전에 했던 것처럼 몇 가지 view 연산자도 수행하겠습니다. 그래서 collect 연산자를 사용하기 전과 후의 이 채널을 살펴볼 수 있으므로 무슨 일이 일어나고 있는지 이해할 수 있습니다. + +이 채널을 가져와서 collect를 제거하고 dot view greetings를 수행하겠습니다. 그런 다음 이 줄을 복제하고 collect 연산자를 추가하겠습니다. 그리고 그것을 after로 변경하겠습니다. + +이것은 이것을 호출하는 곳과 별개이지만 동일한 출력 채널에서 동일한 연산자 호출을 사용하고 있으므로 괜찮습니다. + +좋습니다, 저장을 누르고 터미널에서 시도해봅시다. nextflow run을 수행하겠습니다. Hello, workflow. 스크립트를 다시 실행합니다. + +좋습니다. 더 나아 보입니다. 이전과 마찬가지로 처음 두 프로세스가 세 번 실행되었고 이제 최종 프로세스는 한 번만 실행되었습니다. + +view 연산자로 출력된 것을 보면 아래에 before collect라고 했고, 이것이 여기 출력이고, 세 번 출력되었습니다. 그리고 각각에 대해 단일 경로가 있음을 알 수 있습니다. 그리고 after collect 이후에는 세 개의 경로 배열이 있는 것을 볼 수 있습니다. 따라서 예상대로입니다. + +좋습니다, results 파일을 확인하고 이번에는 예상대로인지 확인해봅시다. 확실히 이제 파일에 세 줄이 있습니다 - 이 세 개의 출력을 단일 출력 파일로 성공적으로 연결했습니다. 환상적입니다. + +좋습니다, 정리하고 다음 단계로 넘어가겠습니다. 그리고 깔끔하게 유지하기 위해 이러한 view 문을 삭제하겠습니다. + +## 3. 최종 출력 파일 이름을 고유하게 지정하기 위해 프로세스에 하나 이상의 입력 전달하기 + +좋습니다. 지금까지 모든 프로세스는 단일 입력만 받았습니다. 이제 프로세스에 하나 이상의 입력을 추가하여 어떻게 작동하는지 확인하는 연습을 하겠습니다. 이를 위해 이 collect greetings 예제를 사용하겠습니다. + +워크플로를 실행할 때마다 results 디렉토리에서 해당 파일을 덮어썼는데, 우리가 원하는 것이 아닐 수 있습니다. + +## 3.1. 출력 파일에 대한 사용자 정의 이름을 허용하도록 수집기 프로세스 수정하기 + +이 예제에서는 출력 파일 이름을 사용자 정의할 수 있도록 추가 매개변수를 전달할 것입니다. + +프로세스에 두 번째 입력을 추가하는 것은 매우 간단합니다. input 블록에 두 번째 줄을 추가하기만 하면 됩니다. 이번에는 문자열을 전달하려고 하므로 path가 아니라 value이고 batch underscore name이라고 부르겠습니다. + +이제 script 블록에서 이 변수를 사용할 수 있으며, collected dash dollar batch name이라고 하겠습니다. + +여기서 변수 이름 주위에 중괄호를 사용하고 있습니다. 이것은 단지 문자열의 나머지 부분과 분리하기 위한 것이며 이 경우에는 필요하지 않을 수도 있지만 읽기가 더 쉽다고 생각합니다. + +좋습니다. 마지막으로 이제 파일 이름이 변경되었으므로 출력 경로를 업데이트해야 합니다. 따라서 예상대로 batch name을 출력 경로에 넣겠습니다. + +## 3.2. batch 명령줄 매개변수 추가하기 + +이제 어딘가에서 batch name을 전달해야 하며, 워크플로를 실행할 때 명령줄에서 수행할 수 있도록 두 번째 매개변수를 만들 것입니다. + +그래서 params batch name을 수행하고 기본적으로 이것을 test batch라고 부르겠습니다. 이제 프로세스를 호출하는 곳에서 이 특수 매개변수 변수를 사용할 수 있습니다. + +그리고 확실히 VS Code는 이제 이 프로세스에 인수가 충분하지 않으며 두 번째 입력이 필요하다고 알려주고 있습니다. + +간단히 쉼표를 수행하고 새 변수를 전달하면 오류가 사라집니다. + +여기서 입력의 순서가 정말 중요합니다. 첫 번째 프로세스 입력은 path였고 두 번째 입력은 name입니다. 여기서 순서를 변경하면 프로세스를 호출할 때도 순서를 변경해야 합니다. 그렇지 않으면. Next는 잘못된 채널을 잘못된 입력에 전달할 것입니다. + +## 3.3. 워크플로 실행하기 + +좋습니다, 시도해보고 작동하는지 확인해봅시다. "nextflow run hello- workflow를 수행해봅시다. 좋습니다, 이전처럼 실행되었습니다. results 디렉토리를 살펴봅시다. + +확실히 여기 파일 이름은 이제 "collected test batch output txt"라고 합니다. 환상적입니다. + +이제 다시 실행하여 덮어쓸 수 있는지 확인해봅시다. 이번에는 여기 특수 매개변수 변수 이름과 일치하도록 --batch_name을 수행하겠습니다. 그리고 demo output이라고 부르겠습니다. + +워크플로를 다시 실행하고 무슨 일이 일어나는지 확인하겠습니다. + +좋습니다, 이제 collected demo output .txt가 있습니다. 그리고 이 파일 이름이 저것과 다르기 때문에 덮어쓰지 않았습니다. 둘 다 이제 results 디렉토리에 있습니다. + +## 4. 수집기 단계에 출력 추가하기 + +좋습니다, 거기서 프로세스에 여러 입력을 제공하는 것을 보여줬지만 여러 출력은 어떻습니까? 이 예제에서는 처리된 인사말의 수를 계산하고 이 collect greeting 단계의 보조 출력으로 출력할 것입니다. + +## 4.1. 인사말을 카운트하고 출력하도록 프로세스 수정하기 + +여기서 약간의 트릭을 사용할 것입니다. Nextflow 프로세스에는 다중 줄 문자열이 있는 script 블록이 있으며, 이것은 bash 출력으로 dot 명령 dot sh에 전달됩니다. 하지만 실제로 그 위에 사용자 정의 코드를 작성할 수 있으며, 이것은 작업의 일부로 실행되지만 bash 스크립트 내에 포함되지 않습니다. + +Nextflow 구문의 내장 함수 중 하나는 size라고 합니다. 그래서 path input을 가져와서 count underscore greetings라고 하겠습니다. 변수 이름을 정의하기 위해서입니다. input files를 가져와서 그것에 "size"를 호출할 것입니다. + +이 함수는 이 입력 채널의 크기를 계산하여 변수에 할당합니다. + +이제 output 블록의 일부로 해당 변수를 반환할 수 있습니다. 따라서 파일이 아니라 값이므로 val이라고 합니다. 그리고 count greetings. + +이제 이것만으로도 충분하며 이제 이 프로세스에서 이러한 다른 출력에 액세스할 수 있습니다. 그러나 위치 방식으로 액세스해야 합니다. 따라서 0과 1과 같은 인덱스 키를 사용합니다. + +출력을 더 쉽게 얻을 수 있도록 이름을 지정할 수 있으며 emit 문을 사용하여 수행합니다. + +그래서 쉼표 emit out file 또는 이것을 호출하고 싶은 것을 수행합니다. 그리고 여기서 emit count를 수행합니다. 이것은 기본적으로 워크플로 블록 나중에 특정 출력을 쉽게 참조할 수 있도록 약간 더 깨끗한 코드를 작성하는 데 도움이 되는 데코레이터일 뿐입니다. + +## 4.2. 워크플로 끝에서 출력 보고하기 + +좋습니다. 워크플로 블록으로 스크롤하면 이제 collect greetings의 출력을 가져올 수 있고, collect greetings, dot out을 수행할 수 있으며, VS Code 확장에서 제안하는 두 개의 명명된 출력을 볼 수 있습니다. 매우 편리합니다. + +그래서 방금 생성한 count 값을 얻기 위해 dot count를 수행하고 view를 수행하여 명령줄에 출력되도록 하겠습니다. 따라서 워크플로를 실행할 때 볼 수 있습니다. + +조금 더 좋게 만들기 위해 클로저에 뭔가를 작성하겠습니다. num greetings, there were greetings greetings. + +그리고 실제로 다른 출력은 신경 쓰지 않습니다. 왜냐하면 다른 프로세스의 입력으로 사용하지 않기 때문입니다. 하지만 원하면 다운스트림에서 다른 프로세스에 입력으로 쉽게 전달할 수 있는 방법을 볼 수 있습니다. + +## 4.3. 워크플로 실행하기 + +저장을 클릭하겠습니다. 터미널을 살펴보고 시도해봅시다. + +좋습니다, 환상적입니다. 여기 있습니다. 세 개의 인사말이 있습니다. 정확히 맞습니다. + +좋습니다, 대단합니다. 이 챕터의 끝입니다. 여기까지 오신 것을 축하합니다. 이제 입력과 출력 및 워크플로 내의 로직을 처리할 수 있는 매우 현실적인 워크플로를 구축하기 시작했습니다. + +이러한 워크플로 파일이 길어지면 약간 다루기 어려워지기 시작합니다. 따라서 다음 챕터에서는 워크플로 내에서 코드를 찾고 유지 관리하기 쉽도록 Nextflow 코드를 별도의 파일로 모듈화하는 방법을 살펴보겠습니다. + +다음 비디오 챕터 4에서 만나요. Hello Modules. + +[다음 비디오 대본 :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/ko/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..46ca72aee9 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Part 4: Hello Modules - 대본 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 참고 사항" + + 이 페이지는 대본만 표시합니다. 전체 단계별 지침은 [교육 자료](../04_hello_modules.md)로 돌아가십시오. + + 대본에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하세요, Hello Nextflow 교육 과정의 Part 4에 오신 것을 환영합니다. + +이 장은 Hello Modules라고 하며, Nextflow 코드를 모듈화하는 방법에 대해 이야기하겠습니다. 우리가 할 일은 하나의 workflow 스크립트를 가져와서 별도의 파일로 분리하는 것입니다. + +이렇게 하면 workflow가 커질수록 코드를 더 쉽게 탐색하고 유지 관리할 수 있으며, pipeline 간에 모듈을 공유할 수 있게 되어 동일한 도구를 사용하는 여러 pipeline이 있는 경우 해당 process를 한 번만 작성하면 됩니다. + +이에 대한 전형적인 예가 nf-core modules 저장소로, 수천 개의 다양한 도구가 바로 사용 가능한 모듈로 제공되어 workflow에 설치하고 사용할 수 있습니다. + +Nextflow는 sub workflow와도 작동할 수 있는데, 이는 모듈과 비슷하지만 여러 process를 가지고 있습니다. 이것은 이 교육의 범위를 벗어나지만 기본적으로 같은 방식으로 작동합니다. + +좋습니다. 살펴보겠습니다. + +평소와 같이 training.nextflow.io로 이동하여 시작하십시오. + +사이드바에서 "Hello Nextflow"로 가서 part 4: "Hello Modules"를 진행합니다. + +이제 GitHub Code Spaces 환경으로 이동하여 "hello-modules" 파일을 살펴보겠습니다. + +이전과 마찬가지로 이전 장의 끝 지점에서 시작하므로 이 스크립트가 익숙할 것입니다. 세 개의 process가 있습니다: say hello, convert to upper, collect greetings가 있고, 간단한 workflow에서 이 세 가지 명령을 실행하고 마지막에 메시지를 emit합니다. greeting과 batch라는 두 개의 매개변수가 있으며, 마지막에 수집된 출력 파일에 사용되는 이름을 지정합니다. + +## 0. 워밍업: hello-modules.nf 실행 + +nextflow run hello, modules를 실행하여 이 workflow가 예상대로 작동하는지 확인할 수 있습니다. + +좋습니다. 각 process에서 세 개의 작업, 하나의 수집 작업이 실행되었으며, 이 batch에 세 개의 greetings가 있다고 알려줍니다. results로 이동하면 수집된 test, batch 출력을 포함하여 다양한 출력 파일이 있습니다. + +## 1. 모듈을 저장할 디렉토리 생성 + +좋습니다. 모듈화를 해봅시다. + +일반적으로 깔끔하게 정리하기 위해 pipeline 저장소의 하위 폴더에 모듈을 넣는 것이 좋습니다. 원하는 이름으로 부를 수 있지만 관례상 보통 modules라고 부릅니다. + +그럼 터미널로 가서 make the modules를 실행하겠습니다. VS Code의 사이드바에 나타나는 것을 볼 수 있습니다. + +## 2. sayHello() 모듈 생성 + +그런 다음 첫 번째 모듈을 위한 새 파일을 만들겠습니다. "touch"나 "code"를 사용할 수 있고 사이드바에서 할 수도 있습니다. 정말 중요하지 않습니다. 그래서 code modules를 실행하고 process 이름을 따서 이름을 지정하겠습니다. 그래서 sayHello.nf라고 하겠습니다. NF는 Nextflow 파일의 전통적인 파일 확장자입니다. + +여기서 저장하면 새 모듈 파일이 나타나는 것을 볼 수 있습니다. + +## 2.2. sayHello process 코드를 모듈 파일로 이동 + +좋습니다. 다음으로 workflow에서 모듈 코드를 가져오겠습니다. 또한 여기 hash bang도 가져와서 먼저 복사하여 명확하게 Nextflow 파일임을 표시하겠습니다. 그런 다음 이 process를 가져와서 잘라내겠습니다. 메인 workflow 스크립트에서 제거하고 이 새 모듈에 붙여넣겠습니다. + +이것이 이 모듈 파일에 포함될 모든 내용입니다. 단일 process만 있고, workflow도 없고, 로직도 없고, process만 있습니다. + +이제 이 파일을 닫을 수 있습니다. + +## 2.3. workflow 블록 앞에 import 선언 추가 + +이제 workflow에 첫 번째 process가 없으므로 import하여 다시 가져와야 합니다. 이에 대한 구문은 다른 프로그래밍 언어와 매우 유사하므로 익숙하게 느껴질 수 있습니다. include 중괄호를 사용하고, process 이름인 say hello를 넣은 다음 파일 경로 modules, say hello, nf에서 가져옵니다. 훌륭합니다. + +여기 몇 가지 트릭이 있습니다. VS Code 확장 프로그램은 이것에 대해 영리합니다. 이 파일 경로를 인식하고 마우스를 올려놓고 링크 따라가기를 할 수 있습니다. 또는 Mac을 사용 중이라면 option을 누르고 클릭하면 이 파일이 열립니다. 그래서 빠르게 이동할 수 있습니다. + +이 process 이름은 이제 아래 workflow에서 사용되고 있으며, 여기서도 같은 작업을 할 수 있습니다. 해당 process에 대한 약간의 정보를 보여주고, 다시 option을 누르고 클릭하면 편집기에서 열립니다. + +따라서 다양한 process를 위한 많은 파일이 있을 때 VS Code에서 코드베이스를 빠르게 탐색할 수 있는 정말 빠른 방법입니다. + +좋습니다. 기본적으로 이것이 이 장의 전부입니다. 이제 다른 process에 대해서도 같은 작업을 반복하면 됩니다. + +## 3. convertToUpper() process 모듈화 + +그럼 여기에 새 파일을 만들어 봅시다. Convert to upper nf라고 부르겠습니다. 다시 hash bang을 복사합니다. 그런 다음 process를 잘라냅니다. + +거기에 process 이름을 복사하고, 새 process 이름으로 새 include 문을 포함합니다. + +## 4. collectGreetings() process 모듈화 + +그리고 세 번째 process에 대해서도 같은 작업을 합니다. 새 파일, connect. Greetings, + +hash bang을 작성합니다. process를 잘라내고, process를 붙여넣고, 새 include 문을 작성합니다. + +이제 여기에 잘못된 include 소스라고 하는 오류 밑줄이 있는 것을 볼 수 있습니다. 그리고 이것은 제가 너무 빨리 이동하여 실제로 발생한 진짜 오류입니다. 자세히 보면 T를 빠뜨리고 convert to upper라고 한 것을 볼 수 있습니다. + +따라서 VS Code는 매우 유용하게도 제가 거기서 실수했다고 알려주었습니다. 파일 이름을 수정하면 오류가 사라집니다. 이것은 VS Code 내의 오류 검사가 Nextflow 코드를 작성하는 데 왜 그렇게 유용한지를 보여주는 좋은 예입니다. 그렇지 않았다면 이것을 발견하지 못했을 것이고 workflow를 실행하려고 할 때 훨씬 나중에야 알게 되었을 것입니다. + +이제 메인 pipeline 스크립트가 훨씬 더 간단해 보입니다. process가 하나도 없고, 세 개의 include 문과 workflow만 있습니다. workflow의 로직을 변경하지 않았습니다. process 코드를 변경하지 않았으므로 정확히 같은 방식으로 작동해야 합니다. + +## 4.4. 이전과 같은 작업을 수행하는지 확인하기 위해 workflow 실행 + +확인해 봅시다. 터미널을 열고 이전과 정확히 같은 명령을 실행하겠습니다. + +확실히 process인 say hello, convert to upper collect greetings가 실행되었고, 다시 세 개의 greetings를 주었습니다. + +그래서 코드를 이동했지만, workflow가 실행되는 방식에 대해서는 아무것도 변경하지 않았으며 완전히 변경되지 않았습니다. 유일한 차이점은 이제 더 깨끗한 코드를 가지고 있고, 유지 관리가 더 쉽고, 다른 사람과 공유하기가 더 쉽다는 것입니다. + +그리고 그게 전부입니다. 짧은 장이었습니다. 간단한 개념이지만 매우 강력하고 더 복잡한 Nextflow workflow를 작성하는 방법의 핵심입니다. 따라서 이를 이해하고 사용하는 습관을 들이는 것이 중요합니다. + +다음 장에서는 약간 속도를 바꿔서 Nextflow 코드를 작성하는 구문에 대해 생각하는 것을 멈추고, process 자체에서 소프트웨어를 사용하는 방법에 대해 조금 생각해 보겠습니다. part 5의 Hello Containers에 참여하십시오. + +[다음 동영상 대본 :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/ko/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..8ca708d0ae --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Part 5: Hello Containers - 스크립트 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 사항" + + 이 페이지는 스크립트만 표시합니다. 전체 단계별 지침은 [교육 자료](../05_hello_containers.md)로 돌아가십시오. + + 스크립트에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하세요, Hello Nextflow 교육 과정의 Part Five에 오신 것을 환영합니다. + +이 장의 제목은 Hello Containers입니다. Nextflow가 Docker 및 Singularity와 같은 도구와 통합되어 소프트웨어 컨테이너를 사용하여 파이프라인 사용자에게 소프트웨어를 제공하는 방법에 대해 이야기하겠습니다. + +이는 사람들이 파이프라인을 실행할 때 모든 다양한 도구를 직접 설치할 필요가 없다는 것을 의미합니다. Nextflow가 대신 해줄 것입니다. + +컨테이너는 매우 강력한 기술이며 재현성과 사용 편의성에 매우 중요합니다. 먼저 컨테이너 자체에 대한 간략한 소개로 시작하여 몇 가지 docker 명령을 수동으로 실행한 다음, 동일한 컨테이너를 Nextflow 파이프라인에 넣을 것입니다. + +좋습니다. 시작하겠습니다. + +이전과 마찬가지로 교육 자료를 로드하는 것으로 시작하겠습니다. training.nextflow.io로 이동하십시오. Hello Nextflow, Chapter Five, Hello Containers. + +Codespaces 환경으로 이동하여 왼쪽에서 hello containers dot nf를 볼 수 있습니다. + +이전과 마찬가지로 이것은 이전 4장에서 완료한 것과 동일한 스크립트이므로 익숙할 것입니다. + +입력 파일과 배치 이름을 지정하는 명령줄 매개변수가 있습니다. 세 개의 모듈을 포함하고 있으며, 세 개의 프로세스를 실행하는 워크플로우가 있습니다. + +## 0. 워밍업: hello-containers.nf 실행 + +이 워크플로우를 다시 실행하고 예상한 출력을 생성하는지 다시 확인하십시오. 지금은 실제로 닫고 터미널로 들어가겠습니다. + +## 1. 컨테이너를 '수동으로' 사용 + +이 장을 시작하기 위해 컨테이너 기술에 대해 조금 복습하겠습니다. docker나 singularity 또는 다른 컨테이너 기술에 매우 익숙하다면 이것을 복습으로 간주하거나 완전히 건너뛰어도 됩니다. + +Nextflow는 다양한 유형의 컨테이너 기술을 지원합니다. 여기에는 Docker, Singularity, Podman, Shifter, Charliecloud 등이 포함됩니다. + +이 교육에서는 Docker에 중점을 둘 것입니다. 이는 code spaces에 사전 설치되어 있으며 특히 자신의 컴퓨터나 노트북에서 개발하는 경우 가장 인기 있는 컨테이너 기술 중 하나입니다. + +공유 HPC의 학술 환경에서 작업하는 경우 Singularity를 사용할 수 있고 Docker는 사용할 수 없을 수 있습니다. 괜찮습니다. 모든 개념은 정확히 동일합니다. 몇 가지 수동 명령은 다르지만 Docker를 이해하면 singularity도 이해할 수 있습니다. + +실제로 Singularity도 Code Spaces 환경에 설치되어 있습니다. 원한다면 Docker 대신 Singularity를 사용하여 동일한 작업을 시도할 수 있습니다. + +좋습니다, 컨테이너 기술이란 무엇입니까? Docker의 아이디어는 원격 소스에서 이미지를 가져올 수 있다는 것입니다. 로컬 머신으로 가져온 다음 해당 이미지를 기반으로 컨테이너를 생성합니다. + +이 실행 중인 컨테이너는 컴퓨터에서 실행되는 가상 머신과 비슷합니다. 환경에서 격리되어 있으며 운영 체제 및 사용 가능한 소프트웨어 세트와 함께 사전 패키지되어 있습니다. + +## 1.1. 컨테이너 이미지 가져오기 + +기존 이미지를 가져오는 데 필요한 구문은 "docker pull"입니다. 터미널에 입력하겠지만 이제 작업할 이미지가 필요합니다. + +이미지를 직접 빌드할 수 있습니다. Docker Hub 또는 quay.io와 같은 공개 레지스트리에서 찾을 수 있습니다. 그러나 이미지를 빠르게 얻는 정말 좋은 방법은 Seqera Containers를 사용하는 것입니다. + +이것은 2024년에 구축한 무료 커뮤니티 서비스로 로그인 없이 사용할 수 있습니다. + +seqera.io/containers로 이동하거나 여기 상단에서 containers를 클릭하면 검색 인터페이스가 나타나며 Conda 또는 Python 패키지 인덱스에서 사용 가능한 도구의 이름을 입력할 수 있습니다. + +기본적으로 Bioconda 및 Conda Forge 채널을 검색하지만 원하는 경우 Conda 채널 앞에 접두사를 붙일 수 있습니다. + +재미를 위해 cowpy를 사용하겠습니다. cowpy를 입력하겠습니다. Python Package Index 및 Conda Forge에서 결과를 제공합니다. 컨테이너에 추가하기 위해 클릭하겠습니다. 원한다면 여기에 여러 패키지를 추가할 수 있습니다. Docker를 선택하고 linux/amd64를 선택한 다음 Get Container를 클릭합니다. + +이것은 아직 생성되지 않은 경우 요청 시 이미지를 빌드하고 복사할 수 있는 URL을 제공합니다. + +관심이 있으시면 view Build Details를 클릭하면 사용된 conda 환경 파일과 빌드에 대한 전체 빌드 로그 및 보안 스캔 결과를 보여주는 페이지로 이동합니다. + +code spaces로 돌아가면 이제 이 컨테이너 이름을 붙여넣고 엔터를 칠 수 있습니다. + +Docker는 이제 이 컨테이너 이미지 내의 모든 다른 레이어를 다운로드하고 이제 이 이미지를 사용할 수 있다고 알려줍니다. + +## Singularity 이미지 가져오기 + +singularity를 사용하는 경우 프로세스는 기본적으로 동일합니다. 이미지 패키지를 선택하고 cowpy를 선택합니다. 이제 Docker 대신 Singularity를 선택하고 Get Container를 클릭합니다. oras://를 사용하는 이미지 URL을 제공합니다. 또는 원하는 경우 해당 상자를 선택하여 https://를 사용할 수 있습니다. 해당 URL을 복사합니다. 이제 Code Spaces로 이동합니다. 실제로 이 공간에 Apptainer가 설치되어 있는데, 이는 Singularity와 동일하지만 서로 별칭이 지정되어 있습니다. 따라서 apptainer pull을 수행한 다음 cowpy sif라고 부르겠지만 원하는 대로 부를 수 있습니다. URL을 붙여넣습니다. 그러면 해당 이미지를 다운로드합니다. + +ls -lh를 수행하면 cowpy.sif를 볼 수 있습니다. + +Singularity는 Docker와 다릅니다. singularity는 모든 이미지를 플랫 파일에 저장하는 반면 Docker는 호스트 머신에 모든 레이어를 별도로 보관하는 레지스트리가 있으며 이 모든 것을 추적하기 위해 실행 중인 데몬이 있습니다. + +## 1.2. 컨테이너를 사용하여 cowpy를 일회성 명령으로 실행 + +좋습니다, Docker로 돌아가겠습니다. 이제 docker run을 수행하여 생성한 이 이미지를 실행해 볼 수 있습니다. + +dash dash rm을 수행하겠습니다. 이것은 이미지의 일회성 실행만 수행합니다. 그리고 이미지 URL을 붙여넣겠습니다. 그런 다음 마지막으로 실행하려는 명령으로 완료합니다. + +생성한 이미지에는 cowpy가 설치되어 있으므로 cowpy를 시도해 보겠습니다. + +됩니다. 명령이 실행되었습니다. cowpy가 로컬에 설치되어 있지 않습니다. 실행하려고 하면 존재하지 않는 것을 볼 수 있습니다. 그러나 이 명령에서는 Docker를 사용하여 실행했으며 이 출력을 올바르게 생성했습니다. + +## 1.3. 컨테이너를 사용하여 cowpy를 대화식으로 실행 + +원한다면 더 나아가 컨테이너를 대화식으로 실행하고 내부를 둘러볼 수 있습니다. 다시 "docker run dash dash rm"을 수행합니다. 이제 대화형 터미널을 원한다고 Docker에 알리는 dash it를 수행하겠습니다. 이미지 URL을 다시 수행하고 이번에는 cowpy 대신 bin bash를 수행하겠습니다. 왜냐하면 실행하려는 명령이 bash이기 때문입니다. + +이것은 실행 중인 컨테이너로 이동하며 이제 프롬프트가 변경된 것을 볼 수 있습니다. + +LS slash를 수행하면 여기의 디렉토리가 다른 것을 볼 수 있습니다. + +GitHub Code Spaces에서 실행 중인 오른쪽에 두 번째 터미널을 열고 LS slash를 수행하면 workspaces 및 temp와 같은 디렉토리가 있는 것을 볼 수 있지만 Docker의 여기는 다릅니다. + +따라서 이 환경은 Docker 내에서 완전히 분리되어 있으며 호스트 환경에서 격리되어 있습니다. 이것은 좋은 일입니다. 왜냐하면 이 명령의 실행을 Docker 이미지로 격리하고 다른 호스트 시스템의 다른 사람들 사이에서 재현 가능하게 유지하기 때문입니다. + +Docker 이미지 내에서 호스트 시스템의 데이터를 사용하려면 명시적으로 컨테이너에 마운트해야 합니다. + +잠시 후에 그렇게 하겠습니다. + +## 1.3.2. 원하는 도구 명령 실행 + +먼저 cowpy를 실행할 수 있는지 확인해 보겠습니다. 다시 명령줄에서 직접 사용할 수 있으며 더 복잡한 작업을 시작하고 인수를 전달할 수 있습니다. Hello containers 그리고 소 대신 tux 펭귄을 수행하겠습니다. 다른 무엇이 있는지 보겠습니다. + +cheese를 수행하겠습니다. 훌륭합니다. Dragon과 Cow는 어떻습니까? 꽤 좋습니다. + +## 1.3.3. 컨테이너 종료 + +좋습니다. 이 컨테이너에 데이터가 없기 때문에 더 이상 할 수 없습니다. 그래서 이 실행 중인 이미지를 종료하고 컨테이너에 일부 데이터를 마운트할 수 있는지 확인하겠습니다. control D를 수행하거나 exit를 입력하여 수행할 수 있습니다. 좋습니다, 이제 일반 GitHub code space로 돌아왔습니다. + +## 1.3.4. 컨테이너에 데이터 마운트 + +Docker 컨테이너에 일부 데이터를 마운트하려면 dash V를 사용해야 합니다. 이전 docker 명령을 가져와서 시작 부분으로 이동하여 dash v를 수행하겠습니다. 현재 로컬 작업 디렉토리에 대해 "."를 수행한 다음 콜론을 사용하여 호스트 디렉토리에서 마운트될 위치를 지정하고 slash data를 수행합니다. 따라서 이것은 이 특정 디렉토리를 slash data의 컨테이너에 마운트합니다. + +이제 LS slash를 수행하면 data라는 새 디렉토리가 있는 것을 볼 수 있으며 LS data를 수행하면 사이드바에 있는 모든 파일을 볼 수 있습니다. 훌륭합니다. + +## 1.3.5. 마운트된 데이터 사용 + +이제 Docker 이미지 내의 호스트 시스템에 있는 일부 파일을 사용할 수 있습니다. cat data greetings csv라고 말할 수 있습니다. 기억하시다시피 이것은 이전의 다양한 인사말이 포함된 CSV 파일이며 cowpy로 파이프할 수 있습니다. 훌륭합니다. 이제 진전이 있습니다. + +좋습니다. Docker를 대화식으로 실행하는 것은 충분합니다. Docker가 무엇인지, 일회성 방식으로 명령을 실행하는 방법과 이미지를 대화식으로 사용하는 방법에 대해 대략적으로 느끼셨기를 바랍니다. singularity를 사용하는 경우 apptainer exec 또는 apptainer run 또는 singularity exec 또는 singularity run과 같은 작업을 수행한다는 점을 제외하고 명령은 모두 매우 유사합니다. + +## 2. Nextflow에서 컨테이너 사용 + +다음으로 Nextflow 워크플로우로 돌아가서 Nextflow 파이프라인 내에서 이 기술을 사용하는 방법을 살펴보겠습니다. + +터미널을 닫고 Hello Containers를 다시 열겠습니다. + +## 2.1. cowpy 모듈 작성 + +cowpy 예제를 고수하기 위해 cowpy를 사용하는 워크플로우에 새 프로세스를 생성하겠습니다. 모듈로 이동하여 새 파일을 생성하고 cowpy nf라고 부르겠습니다. 이제 조금 속임수를 쓰고 교육 자료에서 코드를 복사하여 저장을 누르겠습니다. 그리고 살펴보겠습니다. + +이것은 간단한 프로세스입니다. 이제 프로세스의 구성 요소가 어떻게 생겼는지 이해하기를 바랍니다. 다시 결과로 이동하는 publishDir이 있습니다. 입력 파일과 character라는 문자열의 두 가지 입력이 있습니다. cowpy 입력 파일의 출력이 있으며 잠시 전에 docker 이미지 내에서 수동으로 실행한 것과 정확히 동일하게 보이는 스크립트가 있습니다: 파일을 인쇄하는 cat, cowpy에 파이프하고 사용하려는 cowpy 문자 유형을 지정하고 여기에서 출력으로 전달하는 출력 파일로 출력합니다. + +## 2.2. 워크플로우에 cowpy 추가 + +좋습니다, 워크플로우로 돌아가서 이 새 프로세스를 가져오겠습니다. 그래서 modules cowpy nf에서 cowpy. 원하는 문자를 지정할 수 있도록 새 매개변수를 생성하겠습니다. 기본적으로 Turkey라고 하겠습니다. 그런 다음 워크플로우 끝에서 이 새 프로세스를 호출하겠습니다. + +cowpy. 그리고 Collect Greetings의 출력을 사용하겠습니다. 따라서 collect greetings out, out file입니다. 그런 다음 방금 만든 새 params인 두 번째 인수가 필요합니다. params dot character. + +## 2.2.4. 워크플로우를 실행하여 작동하는지 확인 + +좋습니다, 새 프로세스가 작동하는지 확인하겠습니다. Nextflow run hello containers. 이것은 처음 세 개의 프로세스를 실행한 다음 끝에 cowpy를 실행하려고 시도해야 합니다. + +오류가 발생했습니다. 여기서 말하는 것은 cowpy에 오류가 있었고 종료 상태 127이 있었으며 확실히 command sh cowpy command not found입니다. + +cowpy에 사용할 수 있는 Docker 이미지가 있다고 Nextflow에 알리지 않았으므로 호스트 시스템에서 실행하려고 시도했으며 호스트 시스템에 cowpy가 설치되어 있지 않아 오류가 발생했습니다. + +## 2.3. 컨테이너를 사용하여 실행 + +따라서 해야 할 일은 사용 가능한 컨테이너가 있다고 Nextflow에 알려야 하는 것입니다. cowpy 프로세스로 이동하여 프로세스 상단에 container라는 새 지시문을 추가하겠습니다. + +그런 다음 이미지를 찾아 URL을 복사하고 문자열에 넣습니다. + +이것만으로는 충분하지 않습니다. X Flow 파이프라인에는 소프트웨어를 지정하는 여러 가지 방법이 있을 수 있기 때문입니다. 예를 들어 conda conda-forge cowpy도 수행할 수 있습니다. 그리고 Nextflow는 사용하려는 기술을 알아야 합니다. + +## 2.3.2. nextflow.config 파일을 통해 Docker 사용 활성화 + +따라서 Docker가 활성화된 상태로 실행하려면 다음 장에서 더 자세히 다룰 내용인 Nextflow config 파일을 사용하여 약간 앞서나가겠습니다. 이 디렉토리에 Nextflow Config라는 파일이 있으며 여기에 이미 docker.enabled False가 있습니다. + +Docker를 활성화하기 위해 True로 변경한 다음 워크플로우를 다시 실행할 수 있습니다. + +## 2.3.3. Docker가 활성화된 상태로 워크플로우 실행 + +Nextflow run hello containers nf 이번에는 cowpy가 성공적으로 실행되었습니다. Results를 살펴보겠습니다. cowpy collected test 그리고 우리의 Turkey가 있습니다. 훌륭합니다. + +따라서 백그라운드에서 Nextflow는 해당 프로세스에 사용 가능한 컨테이너가 있다는 것을 알았습니다. + +이미지를 가져와서 명령을 실행했습니다. + +## 2.3.4. Nextflow가 컨테이너화된 작업을 시작한 방법 검사 + +궁금하시다면 work 디렉토리를 살펴봄으로써 실제로 수행한 작업을 정확히 볼 수 있습니다. code work를 수행한 다음 해시를 수행하고 command run을 수행합니다. 기억하시다시피 이것은 해당 작업에 대해 실제로 실행되는 파일입니다. NXF launch라는 함수를 찾을 수 있습니다. 그리고 여기에서 Nextflow가 사용한 정확한 docker 명령을 볼 수 있습니다. 이것은 이전에 터미널에서 수동으로 수행한 것과 매우 유사합니다. Docker run. 이 호스트 디렉토리를 컨테이너에 바인딩한 다음 컨테이너 URL을 지정합니다. + +따라서 여기에는 마법이 없습니다. Nextflow가 파이프라인에서 컨테이너를 쉽게 지정할 수 있는 방식으로 자동으로 무거운 작업을 수행하고 있을 뿐이며, 워크플로우를 실행하는 다른 사람들이 쉽게 사용할 수 있습니다. 그리고 그 사람들은 더 이상 분석 파이프라인을 실행하기 위해 소프트웨어 관리에 대해 생각할 필요가 없습니다. + +매우 매우 간단하고 매우 편리하며 재현성도 뛰어납니다. 전반적으로 좋습니다. + +좋습니다, 수고하셨습니다. Chapter Five의 끝입니다. 다음 비디오에서 Hello Nextflow 교육의 마지막 부분인 part six에 참여하여 Nextflow 구성에 대해 더 자세히 이야기하겠습니다. + +다음 비디오에서 뵙겠습니다. + +[다음 비디오 스크립트 :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/ko/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..2b140a5be9 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Part 6: Hello Config - 대본 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요 사항" + + 이 페이지는 대본만 표시합니다. 전체 단계별 지침은 [교육 자료](../06_hello_config.md)로 돌아가십시오. + + 대본에 표시된 섹션 번호는 참고용으로만 제공되며 자료의 모든 섹션 번호를 포함하지 않을 수 있습니다. + +## 환영합니다 + +안녕하세요, Hello Nextflow 교육 과정의 여섯 번째 파트에 오신 것을 환영합니다. + +이번 챕터는 Hello Config이며, 우리 교육 과정의 마지막 파트입니다. + +이번 챕터에서는 Nextflow 구성에 대해 이야기할 것입니다. Nextflow 구성은 정말 강력합니다. 동일한 pipeline을 여러 다른 컴퓨팅 인프라에서 다른 소프트웨어 프로비저닝과 pipeline 자체의 다른 옵션으로 실행할 수 있게 해줍니다. + +이것은 다른 사람들이 만든 Nextflow pipeline을 가져다가 여러분의 시스템에서 실행할 수 있다는 것을 의미하며, 완전히 다른 인프라를 위해 만들어졌을 수도 있습니다. Nextflow를 구성하는 이 능력은 workflow를 진정으로 이식 가능하고 공유 가능하게 만듭니다. + +이번 챕터에서는 이전 파트에서 만든 workflow를 사용할 것이지만, workflow 코드는 전혀 편집하지 않을 것입니다. 단지 Nextflow config 파일을 살펴보고 config를 변경하면 Nextflow가 실행되는 방식이 어떻게 바뀌는지 볼 것입니다. + +좋습니다, 시작해 봅시다. + +이전과 마찬가지로, training.nextflow.io로 가서 시작해 봅시다. 왼쪽의 Hello Nextflow와 챕터 6으로 이동합니다. Hello config입니다. 이제 제 GitHub code Spaces 환경으로 들어가서 사용할 스크립트를 다시 확인하겠습니다. + +## 0. 워밍업: Docker가 활성화되어 있는지 확인하고 Hello Config workflow 실행하기 + +이것은 Hello Config라고 불리며, 이전에 있던 곳에서 시작합니다. CSV 파일에 대한 greetings, 출력 batch 이름에 대한 batch, 그리고 cowpy 이름에 대한 character라는 세 가지 매개변수가 있는 것과 정확히 같게 보입니다. 서로 다른 프로세스의 네 가지 imports가 있고, 그것들을 함께 체인으로 연결하는 workflow가 있습니다. + +실제로 이 챕터에서는 Nextflow 파일을 전혀 건드리지 않을 것이기 때문에, 이제 이 파일을 닫겠습니다. 순전히 구성 파일 내에서 작업할 것입니다. 이전 챕터 5에서 간단히 살펴본 Nextflow dot config 파일을 보면, 여기에 단일 문장이 있습니다: Docker enabled equals true, 이것은 Nextflow에게 이 workflow를 실행할 때 Docker를 사용하라고 지시합니다. + +저는 여기 pipeline 루트에 있는 Nextflow dot config를 사용하고 있으며, Nextflow를 실행할 때 자동으로 로드됩니다. 하지만 기억하세요, Nextflow는 여러 위치에서 config 파일을 로드할 수 있습니다. + +Nextflow docs에서 확인하고 Configuration으로 이동하면, 이러한 위치 목록과 로드되는 우선순위를 볼 수 있습니다. + +좋습니다. workflow가 예상대로 실행되는지 확인해 봅시다. 터미널을 열고 Nextflow를 입력합니다. Run. Hello, config. 그리고 엔터를 누릅니다. 네 개의 프로세스가 실행되어 cowpy 명령으로 끝나야 합니다. 확실히, 이것은 제대로 작동했습니다. Docker를 활성화했고, Docker를 가져와서 cowpy를 실행했으며, 챕터 5 끝에서 했던 것과 같습니다. + +## 1. 사용할 소프트웨어 패키징 기술 결정하기 + +좋습니다. HPC에서 실행 중이고 Docker가 설치되어 있지 않다고 가정해 봅시다. 이 시나리오에서 가장 좋은 방법은 Singularity 또는 Apptainer를 사용하는 것입니다. 그렇게 하려면, module cowpy로 이동하여 이전 챕터에서 보여드린 것처럼 oras://로 시작하는 singularity 이미지를 사용하도록 이 container를 변경할 것입니다. 이것도 Seqera Containers에서 얻을 수 있습니다. + +그런 다음 Nextflow dot config로 이동하여 Docker enabled를 false로 설정하고 singularity enabled equals true를 수행합니다. 또는 Apptainer를 사용하는 경우 apptainer enabled equals true를 수행하면 작동할 것입니다. + +Nextflow는 컨테이너 외에도 다른 기술도 지원합니다. 익숙할 수 있는 것은 conda입니다. 여기서 conda enabled equals true를 수행하고 Docker를 false로 설정할 수 있습니다. conda는 동일한 container 지시문을 사용하지 않습니다. 대신, conda라는 새 지시문을 여기에 추가할 수 있습니다. 그런 다음 사용하려는 conda 패키지를 지정합니다. pipeline을 가능한 한 재현 가능하게 만들기 위해 가능한 한 구체적으로 지정하는 것이 좋습니다. 그래서 conda 채널인 conda-forge를 지정하고, 그 다음 cowpy와 정확한 버전인 1.1.5를 지정하겠습니다. + +원한다면 cowpy만 쓸 수도 있지만, 그것은 pipeline의 다른 실행에서 cowpy의 다른 버전으로 해석될 수 있습니다. + +좋은 점은 docker 지시문을 전혀 건드리지 않았다는 것입니다. 이 Docker 이미지는 여전히 존재합니다. 지금은 두 가지 대안을 제공하고 있으며, config 파일만으로 켜고 끌 수 있습니다. + +## 1.3. workflow를 실행하여 Conda를 사용할 수 있는지 확인하기 + +Conda가 이제 활성화되었으니, 시험해 봅시다. + +좋습니다. 실행 중이고 여기에 Nextflow의 메시지가 있습니다. Nextflow가 저를 위해 conda 환경을 생성하고 있으며, 이 캐시 위치를 사용하고 있다는 것을 볼 수 있습니다. + +백그라운드에서 Nextflow는 저를 위해 "conda create" 명령을 실행하여 원하는 패키지만 있는 새로운 격리된 conda 환경을 만들고, 그런 다음 프로세스를 실행할 수 있도록 해당 conda 패키지를 설치하고 가져옵니다. + +환경을 만들고 처음으로 소프트웨어를 설치하고 있었기 때문에 약간의 시간이 걸렸습니다. 하지만 이 환경을 캐시했으므로, 동일한 Nextflow 명령을 다시 실행하면 동일한 conda 환경을 재사용하기 때문에 훨씬 빠를 것입니다. + +이것의 멋진 점 중 하나는 이러한 지시문을 전체 workflow가 아닌 프로세스 수준에서 지정할 수 있다는 것입니다. 따라서 원한다면 서로 다른 프로세스에 사용되는 기술을 혼합하고 일치시킬 수 있습니다. + +## 2. process 지시문으로 컴퓨팅 리소스 할당하기 + +Nextflow 구성 파일은 소프트웨어 패키징보다 훨씬 더 많은 작업을 수행할 수 있습니다. Nextflow에게 pipeline의 단계를 실제로 어떻게 실행할지도 알려줄 수 있습니다. 한 예는 호스트 시스템에 각 실행 작업에 어떤 리소스를 사용할 수 있어야 하는지 알려주는 것입니다. + +기본적으로 Nextflow는 많이 제공하지 않습니다. 각 프로세스에 단일 CPU와 2기가바이트의 메모리만 제공합니다. + +이것은 아마도 우리가 변경하고 싶은 것일 것입니다. 실행하는 데 오랜 시간이 걸리는 프로세스가 더 많은 리소스를 가지고 더 빠르게 실행될 수 있도록 하기 위해서입니다. 하지만 프로세스에 무엇을 할당해야 할지 알기 어려울 수 있습니다. Nextflow는 이것을 도와주는 멋진 트릭을 가지고 있습니다. + +## 2.1. workflow를 실행하여 리소스 사용 보고서 생성하기 + +workflow를 다시 실행해 봅시다. 이번에는 추가 인수를 추가하겠습니다. dash with reports입니다. 이것은 핵심 Nextflow 옵션이므로 단일 하이픈입니다. 그런 다음 제가 원하는 파일 이름을 입력합니다. 이 경우 report config one html이라고 부르겠습니다. + +workflow를 다시 실행하겠습니다. 이전과 정확히 같이 실행될 것이지만, 사이드바에 나타난 것처럼 추가 도우미 보고서를 제공할 것입니다. + +이 파일을 마우스 오른쪽 버튼으로 클릭하고 다운로드를 클릭하면 GitHub code Spaces에서 로컬 시스템으로 다운로드되어 웹 브라우저에서 쉽게 볼 수 있습니다. + +이 보고서는 모든 Nextflow 실행에 대해 생성될 수 있으며, 많은 정보가 들어 있습니다. 맨 위에는 어떤 명령이 사용되었는지, workflow가 언제 실행되었는지, 얼마나 걸렸는지에 대한 메타데이터로 시작하지만, 아래로 스크롤하면 pipeline의 모든 단계에서 사용된 리소스에 대한 더 자세한 정보를 얻습니다. + +각 프로세스는 서로 다른 작업에 대해 여러 번 실행되기 때문에 각 프로세스에 사용한 리소스의 변동을 보여주는 상자 그림이 있습니다. + +조금 더 아래로 스크롤하면 사용된 메모리와 작업 기간에 대한 유사한 정보가 표시됩니다. 또한 디스크 읽기 쓰기도 표시됩니다. + +오래 실행되는 작업이 있는 큰 pipeline의 경우, 이것이 요청하는 리소스의 구성을 미세 조정하는 방법에 대해 매우 유익할 수 있으며, 과도하게 요청하지 않지만 빠르게 실행될 수 있도록 충분히 제공할 수 있습니다. + +보고서를 계속 아래로 스크롤하면 workflow에서 실행된 모든 단일 작업에 대한 자세한 정보를 보여주는 작업 테이블도 볼 수 있습니다. 여기에는 실행된 해석된 스크립트와 같은 정보가 포함됩니다. + +좋습니다, config 파일로 돌아가 봅시다. workflow에 실제로 많이 필요하지 않다는 것을 보았으므로, Nextflow에게 workflow의 모든 프로세스에 1기가바이트의 메모리만 필요하다고 알려줍시다. + +이제 이와 같이 프로세스 수준에서 정의하면, 이것은 pipeline의 모든 단일 프로세스에 적용됩니다. + +## 2.3. 개별 프로세스에 리소스 할당 설정하기 + +논의를 위해, cowpy가 실제로 많은 무거운 작업을 하고 있고 다른 작업보다 더 많은 리소스가 필요하다고 가정해 봅시다. 여기서 with name cowpy를 사용하여 해당 프로세스에만 적용되는 추가 config 블록을 정의할 수 있습니다. + +이것을 config selector라고 하며, 여기서 서로 다른 프로세스와 일치하는 다른 패턴을 정의할 수 있습니다. 예를 들어, cow star를 할 수 있습니다. 그런 다음 중괄호를 붙이고 1기가바이트 대신 2기가바이트의 메모리를 제공하고 2개의 CPU를 제공해 봅시다. + +이제 Nextflow는 workflow의 모든 프로세스에 1기가바이트를 제공할 것이며, 더 구체적인 이 요청은 제외됩니다. 따라서 이것을 재정의합니다. 그리고 cowpy라고 불리는 프로세스에만 2기가바이트의 메모리와 2개의 CPU가 제공됩니다. + +Nextflow는 리소스 활용에 대해 영리하다는 점에 유의하십시오. 따라서 이 숫자를 더 높은 값으로 설정하기 시작하면, Nextflow가 모두 병렬로 실행하는 대신 작업 제출을 하나씩 대기열에 넣기 시작하여 사용 가능한 리소스를 과도하게 요청하지 않는 것을 볼 수 있습니다. + +## 2.4. 수정된 구성으로 workflow 실행하기 + +workflow를 다시 실행해 보고 이번에는 새 보고서를 저장합시다. + +좋습니다, 이 파일을 다운로드하여 살펴볼 수 있습니다. + +네, 예상대로 이것은 기본적으로 정확히 같아 보입니다. 왜냐하면 이것은 실제로 아무것도 하지 않는 더미 workflow이기 때문입니다. 하지만 이러한 반복적인 접근 방식으로 제한을 정의하고 이런 종류의 보고를 통해 실제 workflow를 수행하면 적절한 구성을 설정하는 증거 기반 접근 방식을 허용하고 사용 가능한 계산 리소스를 최대한 활용할 수 있다고 상상할 수 있습니다. + +이것에 대해 정말 영리해질 수 있습니다. Nextflow에는 실패를 재시도하는 내장 기능이 있으며, 이와 같은 closure를 사용하여 config 파일에서 이를 활용하고 사용 가능한 리소스를 동적으로 설정할 수 있습니다. 여기서 저는 Nextflow에게 해당 2기가바이트를 재시도 횟수로 곱하라고 지시했습니다. 따라서 두 번째 재시도는 4기가바이트를 받고, 세 번째 재시도는 6기가바이트를 받는 식입니다. 이것은 이 교육 과정의 범위를 약간 벗어나지만, 관심이 있다면 동적 재시도 로직에 대한 좋은 섹션이 있는 Nextflow docs를 확인하십시오. + +## 2.5. 리소스 제한 추가하기 + +이제 이것에 대해 알아차릴 수 있는 한 가지는 이런 종류의 것이 실수로 시스템에서 사용 가능한 리소스를 넘어서는 것을 매우 쉽게 만들 수 있다는 것입니다. 사용 가능한 것보다 더 많은 리소스를 요청하면 Nextflow는 구성에 대한 오류를 발생시키고 실행을 중단합니다. 이를 방지하기 위해 리소스 제한이라는 것을 사용할 수 있습니다. + +workflow의 프로세스 scope 아래에서 배열을 취하는 이와 같은 리소스 제한을 정의할 수 있으며, 이 시스템에서 사용 가능한 최대 메모리 CPU 및 시간을 지정할 수 있습니다. + +여기에 높은 값을 설정해도 요청되는 리소스의 양이 증가하지 않습니다. 여전히 요청에서 1기가바이트를 사용할 것이지만, 이러한 요청 중 하나라도 750에 도달하면 해당 상한선에 도달하여 그 이상은 요청되지 않으므로 Nextflow가 계속 실행되고 사용할 수 없는 리소스로 인해 충돌하지 않습니다. + +따라서 이것은 특히 리소스 할당과 함께 동적 로직을 사용하는 경우 사용하는 좋은 안전장치입니다. + +이것이 정말 유용한 다른 상황은 공개되어 있고 여러분이 제어하지 않는 pipeline을 사용하는 경우입니다. 구성 기본값이 함께 제공될 수 있으며, Nextflow는 시스템에서 실행되도록 모든 리소스 요청을 임계값으로 설정하는 올바른 접근 방식을 자동으로 취합니다. + +좋습니다, 훌륭합니다. 소프트웨어에 대해 이야기했습니다. 리소스 할당에 대해 이야기했고, 모든 프로세스와 특정 프로세스 모두에 대한 서로 다른 config scope를 설명했습니다. + +## 3. 매개변수 파일을 사용하여 workflow 매개변수 저장하기 + +좋습니다, 다음으로 매개변수에 관심을 돌릴 것입니다. Nextflow 스크립트에서 이전에 했던 것처럼 config 파일에서 매개변수를 정의할 수 있습니다. 따라서 params dot greeting equals hello 또는 params scope를 사용하고 foo equals bar를 설정합니다. + +그리고 그것은 workflow의 기본값을 설정하는 데 좋습니다. 그러나 pipeline을 실행할 때 JSON 또는 YAML 파일에 매개변수를 지정하는 것이 좋을 수 있습니다. + +이와 같은 파일을 사용하는 것이 dash dash로 명령줄 옵션을 지정하는 것보다 훨씬 낫습니다. workflow를 실행할 때 많은 매개변수를 지정해야 할 수 있으며 단일 CLI에 모두 작성하는 것은 지루하고 오류가 발생하기 쉽습니다. 또한 사용한 모든 매개변수를 기억할 가능성이 낮으므로, 파일에 코딩하면 미래에 동일한 매개변수를 사용하여 workflow를 다시 시작하기가 더 쉽습니다. + +여기에 test params라는 예제 파일이 있으며, 이것은 세 가지 다른 값으로 workflow에 있는 세 가지 매개변수를 지정합니다. 개인적으로 저는 JSON보다 YAML을 작성하기가 더 쉽다고 생각합니다. 따라서 작동한다는 것을 보여주기 위해 Test yaml이라는 새 파일을 만들고 이것들을 복사하여 따옴표를 제거하고 저장하겠습니다. + +이러한 JSON 및 YAML 파일은 더 익숙한 구문이기 때문에 작성하기가 더 쉬울 수 있습니다. 하지만 이것들은 매개변수에만 해당되며 이와 같은 키 값 구문만 사용한다는 점에 유의하십시오. + +## 3.1. 매개변수 파일을 사용하여 workflow 실행하기 + +시험해 봅시다. 이전과 동일한 명령을 수행합니다. 보고서를 제거하고 dash params file test params yaml을 수행하겠습니다. + +아니요, 이것은 핵심 Nextflow 옵션이므로 단일 하이픈입니다. + +좋습니다. workflow를 실행했고 명령줄에서 모두 지정하는 대신 해당 YAML 파일의 매개변수를 사용했습니다. 이 간단한 예제에는 과도해 보일 수 있지만, 10개 또는 20개의 서로 다른 매개변수가 있다면 수동으로 입력하는 것이 고통스러울 수 있으며, 코드 편집기에서 편집하고 재현성을 위해 보관하는 것이 훨씬 쉽다고 상상할 수 있습니다. + +## 3. 작업을 수행하는 데 사용해야 하는 executor 결정하기 + +좋습니다. Docker와 conda를 사용한 소프트웨어 패키징에 대해 이야기했습니다. CPU와 메모리를 사용한 프로세스 리소스 요구 사항에 대해 이야기했습니다. 그리고 workflow를 실행할 때 매개변수를 지정하는 방법에 대해 조금 이야기했습니다. + +구성의 마지막 부분은 실제로 실행, 기본 컴퓨팅 인프라 자체이며, 이것이 Nextflow의 진정한 보석입니다: 동일한 workflow를 여러 다른 컴퓨팅 인프라에서 실행할 수 있습니다. + +실제로 잠시 서면 교육 자료로 전환하겠습니다. 교육의 이 부분에서 서로 다른 executor, 이 경우 HPC 스케줄러가 작업을 제출하는 데 필요한 리소스 요구 사항을 정의하는 방법에 대한 몇 가지 다른 예를 볼 수 있습니다. + +Slurm의 경우 dash dash mem과 CPU 번호를 정의하는 이러한 SBATCH 헤더가 있습니다. PBS를 사용하는 경우 다른 헤더가 있고, Grid Engine을 사용하는 경우 다시 다른 헤더가 있습니다. + +클라우드에서 실행하려는 경우, AWS batch, Google Cloud, Azure 등 더 다를 것이라고 상상할 수 있습니다. + +이러한 기본 컴퓨팅 인프라 각각을 executor라고 하며, Nextflow는 올바른 구문으로 작업을 제출하기 위해 이러한 모든 다른 executor와 통신하는 방법을 알고 있습니다. + +좋은 소식은 이것에 대해 알 필요가 없다는 것입니다. 해야 할 일은 Nextflow에게 어떤 executor를 사용할지 알려주기만 하면 됩니다. + +## 3.1. 다른 백엔드 타겟팅하기 + +config 파일로 돌아가서 프로세스에서 executor를 수행하고 local을 입력하겠습니다. + +Local은 실제로 기본값입니다. 다른 executor를 지정하지 않으면 local이 사용되며, 이것은 단지 Nextflow를 시작한 호스트 시스템을 의미합니다. + +대신 Slurm을 지정할 수 있습니다. 그러면 Slurm 작업이 제출되거나 AWS batch라고 할 수 있으며, 그러면 AWS batch에 작업이 제출됩니다. + +일부 경우에는 추가 구성이 필요합니다. 예를 들어 클라우드에서 실행하려면 특정 자격 증명이 필요하지만 실제로 이것이 핵심이며, 완전히 다른 컴퓨팅 환경에서 workflow를 실행하기 위해 한두 줄의 config만큼 간단할 수 있습니다. + +code spaces 내의 간단한 시스템에서 실행하고 있지만, 여전히 이것을 가지고 놀면서 Slurm에서 실행하는 척할 수 있습니다. 그런 다음 workflow를 다시 시작하면 Nextflow run, hello config를 수행합니다. Slurm에 작업을 제출할 수 없기 때문에 실패할 것입니다. 하지만 여전히 작업 디렉토리로 들어가서 Nextflow가 무엇을 했는지 볼 수 있습니다. 따라서 이 작업 디렉토리로 이동하여 Command Run을 보면 이 파일의 맨 위에 이제 Slurm 작업에 필요한 리소스를 지정하려고 시도한 이러한 sbatch 헤더 줄이 있습니다. + +## 4. 프로필을 사용하여 사전 설정 구성 선택하기 + +좋습니다, 거의 다 왔습니다. 이 챕터의 마지막 부분은 구성 프로필에 대해 이야기하는 것입니다. 여러 다른 시스템에서 pipeline을 실행하는 경우 매번 지정해야 하는 이러한 모든 다른 Nextflow config 파일을 갖는 것이 짜증날 수 있습니다. + +대신 Nextflow config 파일 내에 구성 그룹화를 인코딩하고 프로필 플래그를 사용하여 해당 그룹을 켜고 끌 수 있습니다. 어떻게 보이는지 봅시다. + +## 4.1. 로컬 개발과 HPC 실행 간 전환을 위한 프로필 생성하기 + +여기 예제에서 두 개의 프로필을 만들 것입니다. 하나는 제 노트북용이고 다른 하나는 더 무거운 HPC 시스템용입니다. 조금 속임수를 쓰고 교육 자료에서 코드를 복사하여 여기에 넣겠습니다. + +profiles라는 새로운 scope가 있고, 각 프로필의 이름이 있으며 무엇이든 될 수 있습니다. 그리고 그 안에는 우리가 이미 작성한 최상위 config와 정확히 같아 보이는 구성이 있습니다. 따라서 다시 프로세스 scope가 있습니다. Docker scope가 있습니다. + +my laptop이라고 불리는 프로필에서 로컬 executor를 사용하여 실행하라고 말하고 있습니다. 따라서 내 호스트 시스템에서 Docker를 사용합니다. + +여기 university HPC 프로필에서는 Slurm을 사용하여 작업을 제출하고 Docker 대신 conda를 사용하며, 사용 중인 HPC의 노드 시스템 크기와 일치할 수 있는 서로 다른 리소스 제한을 지정하고 있습니다. + +기본적으로 Nextflow를 실행할 때 이 구성 중 아무것도 사용되지 않습니다. 이러한 프로필 중 하나를 사용하고 싶다고 지정해야 합니다. + +## 4.2. 프로필로 workflow 실행하기 + +nextflow run hello config를 수행해 봅시다. 그리고 dash profile을 수행하겠습니다. 핵심 Nextflow 옵션이기 때문에 단일 하이픈입니다. 그런 다음 제가 지정한 이름인 my laptop입니다. Nextflow는 이제 해당 구성 프로필 내에서 지정된 config 블록을 사용하고 Nextflow를 실행할 때 적용해야 합니다. 다른 config 블록을 사용하고 싶다면 해당 프로필 이름을 전환하기만 하면 됩니다. 훨씬 기억하기 쉽습니다. 훨씬 사용하기 쉽습니다. + +## 4.3. 테스트 프로필 생성하기 + +참고로, 프로필은 모든 종류의 구성을 가질 수 있으므로 실행 환경과 관련이 있을 필요가 없습니다. 예를 들어, 일련의 매개변수가 있는 새 프로필을 여기에 만들어 봅시다. 이것을 tux로 변경하고 my profile로 변경할 수 있으며, 이제 profile test를 수행하면 workflow의 최상위 수준에서 지정된 매개변수를 덮어쓸 이러한 매개변수를 지정할 것입니다. + +Nextflow를 실행할 때 여러 프로필을 체인으로 연결할 수 있으며 순서대로 적용됩니다. + +## 4.4. 테스트 프로필로 로컬에서 workflow 실행하기 + +따라서 이전 명령을 가져와서 comma test를 수행할 수 있습니다. 그러면 my laptop config가 먼저 적용된 다음 test config가 적용됩니다. 중복되는 부분이 있으면 오른쪽의 프로필이 이전 프로필의 모든 구성을 덮어씁니다. 엔터를 누르면 무슨 일이 일어나는지 봅시다. + +좋습니다, 여기에 새 results 파일이 있습니다. 옵션 중 하나로 지정한 My Profile을 볼 수 있습니다. 그리고 cowpy, my profile도 볼 수 있으며, 확실히 tux가 있습니다. 따라서 작동했습니다. + +## 마무리 + +좋습니다! 놀랍습니다. 끝났습니다. 과정을 끝까지 마쳤습니다. 작은 축하 색종이 조각을 받으십시오. 이 챕터를 마친 것을 축하합니다. + +[다음 비디오 대본 :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/ko/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/ko/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..23e932ee17 --- /dev/null +++ b/docs/ko/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# 다음 단계 - 대본 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "중요한 참고 사항" + + 이 페이지는 대본만 보여줍니다. 전체 단계별 지침은 [강의 자료](../05_hello_containers.md)로 돌아가십시오. + +## 환영합니다 + +축하합니다. 해내셨습니다. Hello Nextflow라고 불리는 첫 번째 Nextflow 교육 강좌를 완료하셨습니다. + +잘 하셨습니다. 끝까지 함께해 주셔서 감사합니다. Nextflow 학습에 투자하신 시간과 노력에 진심으로 감사드리며, 여러분의 업무에 유용하게 사용되기를 진심으로 바랍니다. + +## 다음 단계 + +다음 단계로는 교육 포털 training.nextflow.io를 주목해 주십시오. 저희는 항상 새로운 강의 자료를 게시하고 업데이트하고 있습니다. 따라서 더 고급 교육이나 여러분이 관심 있는 연구 분야에 특화된 교육을 찾으실 수 있을 것입니다. + +특히 Nextflow for Science 페이지를 확인해 보십시오. 이곳에는 독립적으로 구성된 일련의 단기 강좌가 있으며, Hello Nextflow에서 배운 내용을 특정 사용 사례로 확장합니다. + +Genomics에 관한 강좌와 RNA-seq에 관한 강좌가 있습니다. 곧 더 많은 강좌를 제공할 예정입니다. + +## 사이드 퀘스트 + +Hello Nextflow에서 다루었다면 너무 세부적이었을 많은 주제들이 있습니다. 이러한 주제들 중 일부를 사이드 퀘스트로 제공하고 있으며, 이는 특정 주제에 대한 단기 강좌입니다. + +또한 더 큰 규모의 기초 교육과 고급 교육 강좌가 있으며, 여기에서 흥미로운 내용을 찾으실 수 있을 것입니다. + +## nf-core + +이 강좌에서 한두 번 언급되었지만, nf-core 프로젝트를 꼭 확인해 보십시오. 다양한 데이터 유형에 대한 백 개 이상의 파이프라인이 있으므로, 여러분이 직접 파이프라인을 구축할 필요가 없을 가능성도 있습니다. + +또한 거의 천오백 개의 프로세스 모듈이 있어서 nf-core 개발자 도구를 사용하면 파이프라인을 만들고 해당 모듈을 몇 초 만에 가져올 수 있습니다. + +## Seqera Platform + +마지막으로 Seqera Platform을 간단히 소개하겠습니다. 이것은 의심할 여지 없이 실무에서 Nextflow를 실행하는 가장 좋은 방법입니다. 클라우드 기반 플랫폼이지만 AWS, Google Batch, Azure의 자체 클라우드 계정이나 심지어 자체 HPC 등 여러분 자신의 컴퓨팅 인프라를 연결합니다. 무료 등급은 모든 사람에게 제공되며, 학계에 계신다면 무료 프로급 액세스를 위한 학술 프로그램에 지원하실 수 있습니다. + +Seqera Platform은 워크플로우 시작 및 모니터링을 위한 그래픽 인터페이스를 넘어섭니다. 대화형 세션 실행을 위한 Data Studios와 같은 추가 도구가 있으며, 클라우드를 통해 데이터에 더 빠르고 저렴하게 액세스할 수 있는 Fusion과 같은 기본 도구도 있습니다. + +## 지원 및 이벤트 + +어려움이 생기면 언제든지 community.seqera.io를 방문해 주십시오. 그곳의 포럼은 매우 활발하며, Nextflow 커뮤니티는 매우 강력하고 교육이나 Nextflow의 일상적인 사용과 관련된 모든 것에 대해 도움을 줄 준비가 된 사람들이 거의 항상 있습니다. + +그리고 물론, 훌륭한 다음 단계는 커뮤니티 이벤트 중 하나에 참여하는 것입니다. nf-core 해커톤이든 Nextflow Summit 이벤트 중 하나든 상관없습니다. 매우 재미있으며, 그곳에서 여러분을 만나 Nextflow를 무엇에 사용하고 계신지 이야기를 나눌 수 있으면 정말 좋겠습니다. + +## 감사의 말 + +이 교육 자료를 작성하는 데 참여한 모든 분들께 큰 감사를 드립니다. 제가 발표했지만, 실제로 모든 어려운 작업은 Seqera의 교육 팀이 수행했습니다. 특히 Geraldine은 이 자료를 다시 작성하는 데 엄청난 노력을 기울였습니다. + +또한 Marcel, Ken, Adam, John, 과학 개발 팀의 다른 분들과 커뮤니티의 다른 분들께도 감사드립니다. + +## 피드백 설문조사 + +강좌를 마치셨으니, 여러분의 생각을 듣고 싶습니다. training.nextflow.io에서 Hello Nextflow 섹션 아래에 피드백 설문조사를 찾으실 수 있습니다. + +단 네 개의 질문이지만 저희에게 정말 중요합니다. 무엇보다도, 대략 얼마나 많은 사람들이 교육을 받고 있는지 알려줍니다. 또한 여러분이 좋아하셨는지 알려주며, 제안이 있으시면 마지막에 남겨주십시오. 모든 제출 내용을 읽고 있습니다. + +오류를 발견하시면 모든 것이 GitHub에서 오픈 소스이므로 이슈를 생성하거나 풀 리퀘스트를 만들거나 포럼에 메시지를 남겨주십시오. 여러분의 생각과 개선 방법에 대해 듣고 싶습니다. 다시 한 번 감사드립니다. 곧 뵙기를 바랍니다. diff --git a/docs/ko/docs/hello_nf-core/00_orientation.md b/docs/ko/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..00a9ec01ab --- /dev/null +++ b/docs/ko/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# 시작하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## 교육 환경 시작하기 + +GitHub Codespaces에서 제공하는 사전 구축된 환경을 사용하려면 아래의 "Open in GitHub Codespaces" 버튼을 클릭하십시오. 다른 옵션은 [환경 옵션](../envsetup/index.md)을 참조하십시오. + +환경이 로드되는 동안 계속 읽을 수 있도록 새 브라우저 탭 또는 창에서 교육 환경을 여는 것을 권장합니다(장비에 따라 우클릭, ctrl-클릭 또는 cmd-클릭 사용). +과정을 진행하려면 이 지침을 계속 열어두어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### 환경 기본 사항 + +이 교육 환경에는 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 직접 설치할 필요가 없습니다. + +codespace는 VSCode 인터페이스로 설정되어 있으며, 파일 시스템 탐색기, 코드 편집기 및 터미널 셸이 포함되어 있습니다. +과정 중에 제공되는 모든 지침(예: '파일 열기', '코드 편집' 또는 '이 명령 실행')은 달리 명시되지 않는 한 VSCode 인터페이스의 이 세 부분을 참조합니다. + +이 과정을 혼자 진행하는 경우 자세한 내용은 [환경 기본 사항](../envsetup/01_setup.md)을 숙지하십시오. + +### 버전 요구 사항 + +이 교육은 **Nextflow 25.10.2** 또는 이후 버전에서 **v2 syntax parser가 비활성화된 상태**로 설계되었습니다. + +#### 제공하는 교육 환경을 사용하는 경우: + +더 진행하기 전에 다음 명령을 반드시 실행해야 합니다: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### 로컬 또는 사용자 지정 환경을 사용하는 경우: + +[여기](../info/nxf_versions.md)에 문서화된 올바른 설정을 사용하고 있는지 확인하십시오. + +이 교육에는 추가로 **nf-core tools 3.4.1**이 필요합니다. +다른 버전의 nf-core 도구를 사용하는 경우 따라가기 어려울 수 있습니다. + +`nf-core --version` 명령을 사용하여 환경에 설치된 버전을 확인할 수 있습니다. + +## 작업 준비하기 + +codespace가 실행되면 교육에 들어가기 전에 두 가지 작업을 수행해야 합니다: 이 특정 과정의 작업 디렉토리를 설정하고 제공된 자료를 살펴보는 것입니다. + +### 작업 디렉토리 설정하기 + +기본적으로 codespace는 모든 교육 과정의 루트에 작업 디렉토리가 설정된 상태로 열리지만, 이 과정에서는 `hello-nf-core/` 디렉토리에서 작업할 것입니다. + +터미널에서 다음 명령을 실행하여 지금 디렉토리를 변경하십시오: + +```bash +cd hello-nf-core/ +``` + +!!! tip "팁" + + 어떤 이유로든 이 디렉토리를 벗어나는 경우(예: codespace가 절전 모드로 전환됨) Github Codespaces 교육 환경 내에서 실행하는 경우 전체 경로를 사용하여 언제든지 돌아갈 수 있습니다: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +이제 이 디렉토리의 내용을 살펴보겠습니다. + +### 제공된 자료 탐색하기 + +교육 작업 공간의 왼쪽에 있는 파일 탐색기를 사용하여 이 디렉토리의 내용을 탐색할 수 있습니다. +또는 `tree` 명령을 사용할 수 있습니다. + +과정 전반에 걸쳐 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간 수정합니다. + +여기서는 두 번째 레벨까지 목차를 생성합니다: + +```bash +tree . -L 2 +``` + +??? abstract "디렉토리 내용" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +색상이 있는 상자를 클릭하여 섹션을 확장하고 내용을 확인하십시오. +예상되는 명령 출력을 간결한 방식으로 포함하기 위해 이와 같은 접을 수 있는 섹션을 사용합니다. + +- **`greetings.csv` 파일**은 테스트 목적으로 사용하는 최소한의 열 데이터가 포함된 CSV입니다. + +- **`original-hello` 디렉토리**에는 전체 Hello Nextflow 교육 시리즈를 진행하여 생성된 소스 코드의 사본이 포함되어 있습니다(Docker 활성화 상태). + +- **`solutions` 디렉토리**에는 과정의 각 단계에서 생성되는 완성된 workflow 스크립트가 포함되어 있습니다. + 작업을 확인하고 문제를 해결하는 데 사용할 참조 자료로 제공됩니다. + +## 준비 상태 체크리스트 + +시작할 준비가 되었다고 생각하십니까? + +- [ ] 이 과정의 목표와 전제 조건을 이해했습니다 +- [ ] 환경이 실행 중입니다 +- [ ] syntax parser가 **v1**로 설정되어 있는지 확인했습니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 + +모든 항목을 체크할 수 있다면 준비가 완료된 것입니다. + +**Part 1로 계속하려면 이 페이지의 오른쪽 하단 모서리에 있는 화살표를 클릭하십시오.** diff --git a/docs/ko/docs/hello_nf-core/01_run_demo.md b/docs/ko/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..d551177fe1 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# 파트 1: 데모 파이프라인 실행하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정의 첫 번째 파트에서는 nf-core 파이프라인을 찾아서 사용해보고, 코드 구성 방식을 이해하며, [Hello Nextflow](../hello_nextflow/index.md)에서 보여드린 일반 Nextflow 코드와 어떻게 다른지 알아보겠습니다. + +nf-core 프로젝트에서 코드 구조와 도구 작동을 시연하기 위한 파이프라인 모음의 일부로 유지 관리하는 nf-core/demo라는 파이프라인을 사용하겠습니다. + +[시작하기](./00_orientation.md) 페이지의 안내에 따라 작업 디렉토리를 `hello-nf-core/`로 설정했는지 확인하십시오. + +--- + +## 1. nf-core/demo 파이프라인 찾기 및 가져오기 + +[nf-co.re](https://nf-co.re) 프로젝트 웹사이트에서 nf-core/demo 파이프라인을 찾는 것부터 시작하겠습니다. 이 웹사이트는 일반 문서 및 도움말 기사, 각 파이프라인에 대한 문서, 블로그 게시물, 이벤트 공지 등 모든 정보를 중앙에서 관리합니다. + +### 1.1. 웹사이트에서 파이프라인 찾기 + +웹 브라우저에서 [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/)로 이동하여 검색창에 `demo`를 입력하십시오. + +![검색 결과](./img/search-results.png) + +파이프라인 이름인 `demo`를 클릭하여 파이프라인 문서 페이지에 접근하십시오. + +릴리스된 각 파이프라인에는 다음 문서 섹션이 포함된 전용 페이지가 있습니다: + +- **Introduction:** 파이프라인의 소개 및 개요 +- **Usage:** 파이프라인 실행 방법에 대한 설명 +- **Parameters:** 설명과 함께 그룹화된 파이프라인 매개변수 +- **Output:** 예상되는 출력 파일에 대한 설명 및 예제 +- **Results:** 전체 테스트 데이터셋에서 생성된 출력 파일 예제 +- **Releases & Statistics:** 파이프라인 버전 기록 및 통계 + +새로운 파이프라인 도입을 고려할 때는 실행을 시도하기 전에 파이프라인 문서를 주의 깊게 읽어 파이프라인이 무엇을 하는지, 어떻게 구성해야 하는지 이해해야 합니다. + +지금 살펴보시고 다음을 찾을 수 있는지 확인해보십시오: + +- 파이프라인이 실행할 도구들 (`Introduction` 탭 확인) +- 파이프라인이 받거나 요구하는 입력 및 매개변수 (`Parameters` 탭 확인) +- 파이프라인이 생성하는 출력 (`Output` 탭 확인) + +#### 1.1.1. 파이프라인 개요 + +`Introduction` 탭은 시각적 표현(지하철 노선도라고 함)과 파이프라인의 일부로 실행되는 도구 목록을 포함한 파이프라인의 개요를 제공합니다. + +![파이프라인 지하철 노선도](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. 명령줄 예제 + +문서는 또한 입력 파일 예제(아래에서 자세히 설명)와 명령줄 예제를 제공합니다. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +예제 명령이 workflow 파일을 지정하지 않고 파이프라인 저장소에 대한 참조인 `nf-core/demo`만 지정한다는 것을 알 수 있습니다. + +이런 방식으로 호출되면 Nextflow는 코드가 특정 방식으로 구성되어 있다고 가정합니다. +이 구조를 살펴볼 수 있도록 코드를 가져오겠습니다. + +### 1.2. 파이프라인 코드 가져오기 + +파이프라인이 우리의 목적에 적합해 보인다고 판단했다면 사용해보겠습니다. +다행히 Nextflow는 수동으로 다운로드할 필요 없이 올바르게 형식화된 저장소에서 파이프라인을 쉽게 가져올 수 있게 해줍니다. + +터미널로 돌아가서 다음을 실행하겠습니다: + +```bash +nextflow pull nf-core/demo +``` + +??? success "명령 출력" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow는 파이프라인 코드를 `pull`하여 전체 저장소를 로컬 드라이브에 다운로드합니다. + +명확히 하자면, nf-core 파이프라인뿐만 아니라 GitHub에서 적절하게 설정된 모든 Nextflow 파이프라인에 대해 이 작업을 수행할 수 있습니다. +그러나 nf-core는 가장 큰 오픈소스 Nextflow 파이프라인 모음입니다. + +Nextflow에게 이런 방식으로 가져온 파이프라인 목록을 제공하도록 할 수 있습니다: + +```bash +nextflow list +``` + +??? success "명령 출력" + + ```console + nf-core/demo + ``` + +파일들이 현재 작업 디렉토리에 없다는 것을 알 수 있습니다. +기본적으로 Nextflow는 `$NXF_HOME/assets`에 저장합니다. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="디렉토리 내용" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + 교육 환경을 사용하지 않는 경우 시스템에서 전체 경로가 다를 수 있습니다. + +Nextflow는 이러한 파이프라인을 직접 상호작용하는 코드가 아닌 라이브러리처럼 사용해야 한다는 원칙에 따라 다운로드된 소스 코드를 의도적으로 '방해가 되지 않는' 위치에 보관합니다. + +그러나 이 교육의 목적상 내부를 살펴보고 무엇이 있는지 확인하고 싶습니다. +따라서 쉽게 확인할 수 있도록 현재 작업 디렉토리에서 해당 위치로의 심볼릭 링크를 만들겠습니다. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +이렇게 하면 방금 다운로드한 코드를 더 쉽게 탐색할 수 있는 바로가기가 만들어집니다. + +```bash +tree -L 2 pipelines +``` + +```console title="디렉토리 내용" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +이제 필요에 따라 소스 코드를 더 쉽게 살펴볼 수 있습니다. + +하지만 먼저 첫 번째 nf-core 파이프라인을 실행해보겠습니다! + +### 요약 + +이제 nf-core 웹사이트를 통해 파이프라인을 찾고 소스 코드의 로컬 사본을 가져오는 방법을 알게 되었습니다. + +### 다음 단계 + +최소한의 노력으로 nf-core 파이프라인을 사용해보는 방법을 배워보겠습니다. + +--- + +## 2. 테스트 프로파일로 파이프라인 사용해보기 + +편리하게도 모든 nf-core 파이프라인에는 test 프로파일이 함께 제공됩니다. +이것은 [nf-core/test-datasets](https://github.com/nf-core/test-datasets) 저장소에서 호스팅되는 작은 테스트 데이터셋을 사용하여 파이프라인을 실행하기 위한 최소한의 구성 설정 모음입니다. +작은 규모로 파이프라인을 빠르게 사용해볼 수 있는 좋은 방법입니다. + +!!! note + + Nextflow의 configuration profile 시스템을 사용하면 다양한 컨테이너 엔진이나 실행 환경 간에 쉽게 전환할 수 있습니다. + 자세한 내용은 [Hello Nextflow Part 6: Configuration](../hello_nextflow/06_hello_config.md)을 참조하십시오. + +### 2.1. 테스트 프로파일 살펴보기 + +파이프라인을 실행하기 전에 파이프라인의 test 프로파일이 무엇을 지정하는지 확인하는 것이 좋습니다. +`nf-core/demo`의 `test` 프로파일은 구성 파일 `conf/test.config`에 있으며 아래에 표시되어 있습니다. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // 입력 데이터 + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +상단의 주석 블록에 이 테스트 프로파일로 파이프라인을 실행하는 방법을 보여주는 사용 예제가 포함되어 있음을 바로 알 수 있습니다. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +제공해야 하는 것은 예제 명령에서 꺾쇠괄호 안에 표시된 것뿐입니다: `<docker/singularity>`와 `<OUTDIR>`. + +다시 말하지만, `<docker/singularity>`는 컨테이너 시스템의 선택을 의미합니다. 모든 nf-core 파이프라인은 재현성을 보장하고 소프트웨어 설치 문제를 제거하기 위해 컨테이너(Docker, Singularity 등)와 함께 사용할 수 있도록 설계되었습니다. +따라서 파이프라인을 테스트하기 위해 Docker 또는 Singularity를 사용할지 지정해야 합니다. + +`--outdir <OUTDIR>` 부분은 Nextflow가 파이프라인의 출력을 작성할 디렉토리를 의미합니다. +직접 만들 수 있는 이름을 제공해야 합니다. +이미 존재하지 않는 경우 Nextflow가 실행 시 생성합니다. + +주석 블록 다음 섹션으로 이동하면, test 프로파일이 테스트를 위해 미리 구성된 내용을 보여줍니다: 가장 주목할 점은 `input` 매개변수가 이미 테스트 데이터셋을 가리키도록 설정되어 있으므로 자체 데이터를 제공할 필요가 없다는 것입니다. +미리 구성된 입력 링크를 따라가면 여러 실험 샘플에 대한 샘플 식별자와 파일 경로가 포함된 csv 파일임을 알 수 있습니다. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +이것은 샘플시트라고 하며, nf-core 파이프라인에 대한 가장 일반적인 입력 형식입니다. + +!!! note + + 데이터 형식과 유형에 익숙하지 않더라도 걱정하지 마십시오. 이후 내용에 중요하지 않습니다. + +따라서 파이프라인을 사용해보는 데 필요한 모든 것이 있음을 확인했습니다. + +### 2.2. 파이프라인 실행하기 + +컨테이너 시스템으로 Docker를, 출력 디렉토리로 `demo-results`를 사용하기로 결정했다면, 테스트 명령을 실행할 준비가 된 것입니다: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +출력이 일치한다면 축하합니다! 첫 번째 nf-core 파이프라인을 실행했습니다. + +기본 Nextflow 파이프라인을 실행할 때보다 콘솔 출력이 훨씬 많다는 것을 알 수 있습니다. +파이프라인의 버전, 입력 및 출력, 그리고 몇 가지 구성 요소의 요약이 포함된 헤더가 있습니다. + +!!! note + + 출력에는 다른 타임스탬프, 실행 이름 및 파일 경로가 표시되지만 전체 구조와 프로세스 실행은 유사해야 합니다. + +실행 출력으로 이동하여 어떤 프로세스가 실행되었는지 알려주는 줄을 살펴보겠습니다: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +이것은 nf-core 웹사이트의 파이프라인 문서 페이지에 표시된 세 가지 도구에 해당하는 세 개의 프로세스가 실행되었음을 알려줍니다: FASTQC, SEQTK_TRIM 및 MULTIQC. + +여기에 표시된 `NFCORE_DEMO:DEMO:MULTIQC`와 같은 전체 프로세스 이름은 Hello Nextflow 입문 자료에서 본 것보다 깁니다. +여기에는 상위 workflow의 이름이 포함되어 있으며 파이프라인 코드의 모듈성을 반영합니다. +조금 후에 이에 대해 자세히 설명하겠습니다. + +### 2.3. 파이프라인 출력 살펴보기 + +마지막으로 파이프라인이 생성한 `demo-results` 디렉토리를 살펴보겠습니다. + +```bash +tree -L 2 demo-results +``` + +??? abstract "디렉토리 내용" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +많아 보일 수 있습니다. +`nf-core/demo` 파이프라인의 출력에 대해 자세히 알아보려면 [문서 페이지](https://nf-co.re/demo/1.0.2/docs/output/)를 확인하십시오. + +현 단계에서 중요한 것은 결과가 모듈별로 구성되어 있고, 파이프라인 실행에 대한 다양한 타임스탬프가 있는 보고서가 포함된 `pipeline_info`라는 디렉토리가 추가로 있다는 것입니다. + +예를 들어, `execution_timeline_*` 파일은 어떤 프로세스가 실행되었는지, 어떤 순서로, 얼마나 오래 실행되었는지 보여줍니다: + +![실행 타임라인 보고서](./img/execution_timeline.png) + +!!! note + + 여기서 작업이 병렬로 실행되지 않은 이유는 Github Codespaces의 최소 사양 머신에서 실행하고 있기 때문입니다. + 병렬 실행을 보려면 codespace의 CPU 할당과 테스트 구성의 리소스 제한을 늘려보십시오. + +이러한 보고서는 모든 nf-core 파이프라인에 대해 자동으로 생성됩니다. + +### 요약 + +내장된 test 프로파일을 사용하여 nf-core 파이프라인을 실행하는 방법과 출력을 찾을 수 있는 위치를 알게 되었습니다. + +### 다음 단계 + +파이프라인 코드가 어떻게 구성되어 있는지 배워보겠습니다. + +--- + +## 3. 파이프라인 코드 구조 살펴보기 + +이제 사용자로서 파이프라인을 성공적으로 실행했으니, nf-core 파이프라인이 내부적으로 어떻게 구성되어 있는지 살펴보기 위해 관점을 전환해보겠습니다. + +nf-core 프로젝트는 파이프라인 구조, 코드 구성 방법, 구성 및 문서화에 대한 강력한 가이드라인을 적용합니다. +이 모든 것이 어떻게 구성되어 있는지 이해하는 것이 이 과정의 Part 2에서 다룰 nf-core 호환 파이프라인을 개발하기 위한 첫 번째 단계입니다. + +앞서 만든 `pipelines` 심볼릭 링크를 사용하여 `nf-core/demo` 저장소에서 파이프라인 코드가 어떻게 구성되어 있는지 살펴보겠습니다. + +`tree`를 사용하거나 파일 탐색기를 사용하여 `nf-core/demo` 디렉토리를 찾아 열 수 있습니다. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "디렉토리 내용" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +여기에는 많은 내용이 있으므로 단계별로 다루겠습니다. + +먼저, 최상위 레벨에서 요약 정보가 있는 README 파일과 라이선싱, 기여 가이드라인, 인용 및 행동 강령과 같은 프로젝트 정보를 요약하는 보조 파일을 찾을 수 있습니다. +상세한 파이프라인 문서는 `docs` 디렉토리에 있습니다. +이 모든 콘텐츠는 nf-core 웹사이트의 웹 페이지를 프로그래밍 방식으로 생성하는 데 사용되므로 항상 코드와 최신 상태를 유지합니다. + +이제 나머지 부분에 대해서는 세 단계로 나누어 살펴보겠습니다: + +1. 파이프라인 코드 구성요소 (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. 파이프라인 구성 +3. 입력 및 검증 + +파이프라인 코드 구성요소부터 시작하겠습니다. +개별 파일 내의 코드를 자세히 살펴보기보다는 파일 계층 구조와 구조적 구성에 중점을 둘 것입니다. + +### 3.1. 파이프라인 코드 구성요소 + +표준 nf-core 파이프라인 코드 구성은 [Hello Nextflow](../hello_nextflow/index.md) 과정의 Part 4인 [Hello Modules](../hello_nextflow/04_hello_modules.md)에서 소개된 것처럼 코드 재사용을 극대화하도록 설계된 모듈식 구조를 따릅니다. 다만 진정한 nf-core 방식으로 약간의 복잡성이 추가되어 구현됩니다. +특히, nf-core 파이프라인은 subworkflow, 즉 상위 workflow에서 가져오는 workflow 스크립트를 풍부하게 사용합니다. + +조금 추상적으로 들릴 수 있으므로 `nf-core/demo` 파이프라인에서 실제로 어떻게 사용되는지 살펴보겠습니다. + +!!! note + + 이러한 모듈식 구성요소가 _어떻게_ 연결되는지에 대한 실제 코드는 다루지 않을 것입니다. subworkflow 사용과 관련된 복잡성이 혼란스러울 수 있고, 이를 이해하는 것이 교육의 현 단계에서는 필요하지 않기 때문입니다. + 지금은 전체적인 구성과 논리에 초점을 맞추겠습니다. + +#### 3.1.1. 일반 개요 + +다음은 `nf-core/demo` 파이프라인에 대한 관련 코드 구성요소 간의 관계를 나타낸 것입니다: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +`main.nf`라는 _엔트리포인트_ 스크립트가 있으며, 이는 두 종류의 중첩된 workflow에 대한 래퍼 역할을 합니다: `workflows/` 아래에 있고 `demo.nf`라고 하는 실제 분석 로직을 포함하는 workflow와 `subworkflows/` 아래에 있는 관리용 workflow 집합입니다. +`demo.nf` workflow는 `modules/` 아래에 있는 **모듈**을 호출하며, 이들은 실제 분석 단계를 수행할 **프로세스**를 포함합니다. + +!!! note + + Subworkflow는 관리 기능에만 국한되지 않으며 프로세스 모듈을 사용할 수 있습니다. + + 여기에 표시된 `nf-core/demo` 파이프라인은 스펙트럼에서 단순한 편에 속하지만, 다른 nf-core 파이프라인(예: `nf-core/rnaseq`)은 실제 분석에 관여하는 subworkflow를 활용합니다. + +이제 이러한 구성요소를 차례로 검토하겠습니다. + +#### 3.1.2. 엔트리포인트 스크립트: `main.nf` + +`main.nf` 스크립트는 `nextflow run nf-core/demo`를 실행할 때 Nextflow가 시작하는 엔트리포인트입니다. +즉, `nextflow run nf-core/demo`를 실행하여 파이프라인을 실행하면 Nextflow가 자동으로 `main.nf` 스크립트를 찾아 실행합니다. +이것은 nf-core 파이프라인뿐만 아니라 이러한 관례적인 명명 및 구조를 따르는 모든 Nextflow 파이프라인에 적용됩니다. + +엔트리포인트 스크립트를 사용하면 실제 분석 스크립트가 실행되기 전후에 표준화된 '관리용' subworkflow를 쉽게 실행할 수 있습니다. +실제 분석 workflow와 그 모듈을 검토한 후에 이에 대해 살펴보겠습니다. + +#### 3.1.3. 분석 스크립트: `workflows/demo.nf` + +`workflows/demo.nf` workflow는 파이프라인의 핵심 로직이 저장된 곳입니다. +상위 workflow에서 호출되도록 설계되어 몇 가지 추가 기능이 필요하다는 점을 제외하면 일반 Nextflow workflow와 매우 유사하게 구성됩니다. +다음 과정 파트에서 Hello Nextflow의 간단한 Hello 파이프라인을 nf-core 호환 형태로 변환할 때 관련 차이점을 다루겠습니다. + +`demo.nf` workflow는 다음에 검토할 `modules/` 아래에 있는 **모듈**을 호출합니다. + +!!! note + + 일부 nf-core 분석 workflow는 하위 레벨 subworkflow를 호출하여 추가 중첩 레벨을 표시합니다. + 이것은 주로 일반적으로 함께 사용되는 두 개 이상의 모듈을 쉽게 재사용 가능한 파이프라인 세그먼트로 적용하는 데 사용됩니다. + nf-core 웹사이트에서 사용 가능한 [nf-core subworkflows](https://nf-co.re/subworkflows/)를 탐색하여 몇 가지 예제를 볼 수 있습니다. + + 분석 스크립트가 subworkflow를 사용하는 경우 `subworkflows/` 디렉토리 아래에 저장됩니다. + +#### 3.1.4. 모듈 + +모듈은 [Hello Nextflow 교육 과정의 Part 4](../hello_nextflow/04_hello_modules.md)에 설명된 대로 프로세스 코드가 있는 곳입니다. + +nf-core 프로젝트에서 모듈은 출처와 내용을 모두 반영하는 다단계 중첩 구조를 사용하여 구성됩니다. +최상위 레벨에서 모듈은 `nf-core` 또는 `local`(nf-core 프로젝트의 일부가 아님)로 구분되며, 그런 다음 적용하는 도구의 이름을 따서 명명된 디렉토리에 배치됩니다. +도구가 툴킷(즉, 여러 도구를 포함하는 패키지)에 속하는 경우 툴킷 이름을 따서 명명된 중간 디렉토리 레벨이 있습니다. + +`nf-core/demo` 파이프라인 모듈에 실제로 적용된 것을 볼 수 있습니다: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "디렉토리 내용" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +여기서 `fastqc` 및 `multiqc` 모듈은 `nf-core` 모듈 내 최상위 레벨에 있는 반면, `trim` 모듈은 속해 있는 툴킷인 `seqtk` 아래에 있습니다. +이 경우 `local` 모듈은 없습니다. + +프로세스를 설명하는 모듈 코드 파일은 항상 `main.nf`라고 하며, 지금은 무시할 테스트 및 `.yml` 파일이 함께 제공됩니다. + +엔트리포인트 workflow, 분석 workflow 및 모듈을 종합하면 파이프라인의 '흥미로운' 부분을 실행하기에 충분합니다. +그러나 관리용 subworkflow도 있다는 것을 알고 있으므로 이제 살펴보겠습니다. + +#### 3.1.5. 관리용 subworkflow + +모듈과 마찬가지로 subworkflow는 `local` 및 `nf-core` 디렉토리로 구분되며, 각 subworkflow에는 자체 `main.nf` 스크립트, 테스트 및 `.yml` 파일이 있는 고유한 중첩 디렉토리 구조가 있습니다. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "디렉토리 내용" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +위에서 언급했듯이 `nf-core/demo` 파이프라인에는 분석 관련 subworkflow가 포함되어 있지 않으므로 여기에 표시된 모든 subworkflow는 이름의 `utils_` 접두사로 표시된 것처럼 소위 '관리용' 또는 '유틸리티' workflow입니다. +이러한 subworkflow는 다른 보조 기능 중에서도 콘솔 출력에 멋진 nf-core 헤더를 생성하는 것입니다. + +!!! tip + + 명명 패턴 외에도 이러한 subworkflow가 진정한 분석 관련 기능을 수행하지 않는다는 또 다른 표시는 프로세스를 전혀 호출하지 않는다는 것입니다. + +이것으로 `nf-core/demo` 파이프라인을 구성하는 핵심 코드 구성요소의 정리가 완료되었습니다. +이제 개발에 뛰어들기 전에 조금 알아야 할 나머지 요소인 파이프라인 구성과 입력 검증을 살펴보겠습니다. + +### 3.2. 파이프라인 구성 + +이전에 Nextflow가 입력 및 매개변수, 컴퓨팅 리소스 및 오케스트레이션의 기타 측면과 관련하여 파이프라인 실행을 구성하기 위한 많은 옵션을 제공한다는 것을 배웠습니다. +nf-core 프로젝트는 파이프라인 간 일관성과 유지 관리성을 제공하는 방식으로 Nextflow의 유연한 사용자 정의 옵션을 기반으로 구축하는 것을 목표로 하는 파이프라인 구성에 대한 고도로 표준화된 가이드라인을 적용합니다. + +중앙 구성 파일 `nextflow.config`는 매개변수 및 기타 구성 옵션의 기본값을 설정하는 데 사용됩니다. +이러한 구성 옵션의 대부분은 기본적으로 적용되는 반면 다른 옵션(예: 소프트웨어 종속성 프로파일)은 선택적 프로파일로 포함됩니다. + +`conf` 폴더에 저장된 여러 추가 구성 파일이 있으며, 기본적으로 또는 선택적으로 프로파일로 구성에 추가할 수 있습니다: + +- `base.config`: 대부분의 고성능 컴퓨팅 환경에서 일반적으로 사용하기에 적합한 '백지 상태' 구성 파일입니다. 예를 들어 모듈에 적용하기 편리한 광범위한 리소스 사용 구간을 정의합니다. +- `modules.config`: 추가 모듈 지시문 및 인수입니다. +- `test.config`: 데모 파이프라인을 실행할 때 사용한 최소 테스트 데이터로 파이프라인을 실행하기 위한 프로파일입니다. +- `test_full.config`: 전체 크기 테스트 데이터셋으로 파이프라인을 실행하기 위한 프로파일입니다. + +과정 후반부에서 이러한 파일 중 몇 가지를 다루겠습니다. + +### 3.3. 입력 및 검증 + +앞서 `nf-core/demo` 파이프라인의 test 프로파일을 살펴보았을 때 언급했듯이, 파일 경로와 샘플 식별자가 포함된 샘플시트를 입력으로 받도록 설계되었습니다. +파일 경로는 `nf-core/test-datasets` 저장소에 있는 실제 데이터에 연결되어 있습니다. + +샘플시트 예제도 `assets` 디렉토리에 제공되지만 이 파일의 경로는 실제가 아닙니다. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +이 특정 샘플시트는 상당히 간단하지만, 일부 파이프라인은 기본 입력과 관련된 더 많은 메타데이터가 있는 더 복잡한 샘플시트에서 실행됩니다. + +안타깝게도 이러한 파일은 눈으로 확인하기 어려울 수 있으므로 입력 데이터의 부적절한 형식 지정은 파이프라인 실패의 매우 일반적인 원인입니다. +관련 문제는 매개변수가 잘못 제공되는 경우입니다. + +이러한 문제에 대한 해결책은 모든 입력 파일에 대해 예상되는 정보 유형이 올바르게 형식화되어 포함되어 있는지 확인하기 위해 자동 검증 확인을 실행하고, 매개변수가 예상 유형인지 확인하는 것입니다. +이것을 입력 검증이라고 하며, 파이프라인이 실패하여 입력에 문제가 있음을 알아낼 때까지 기다리기보다는 파이프라인을 실행하기 _전에_ 이상적으로 수행되어야 합니다. + +구성과 마찬가지로 nf-core 프로젝트는 입력 검증에 대해 매우 의견이 강하며, Nextflow 파이프라인에 포괄적인 검증 기능을 제공하는 Nextflow 플러그인인 [nf-schema plugin](https://nextflow-io.github.io/nf-schema/latest/)의 사용을 권장합니다. + +이 주제는 이 과정의 Part 5에서 더 자세히 다루겠습니다. +지금은 해당 목적으로 `nextflow_schema.json` 및 `assets/schema_input.json`이라는 두 개의 JSON 파일이 제공된다는 점만 알아두십시오. + +`nextflow_schema.json`은 유형, 설명 및 도움말 텍스트를 포함한 파이프라인 매개변수에 대한 정보를 기계 판독 가능한 형식으로 저장하는 데 사용되는 파일입니다. +이것은 자동 매개변수 검증, 도움말 텍스트 생성, UI 인터페이스의 대화형 매개변수 양식 렌더링을 포함한 다양한 목적으로 사용됩니다. + +`schema_input.json`은 입력 샘플시트 구조를 정의하는 데 사용되는 파일입니다. +각 열은 기계 판독 가능한 형식으로 유형, 패턴, 설명 및 도움말 텍스트를 가질 수 있습니다. +스키마는 자동 검증 및 유용한 오류 메시지 제공을 포함한 다양한 목적으로 사용됩니다. + +### 요약 + +이제 nf-core 파이프라인의 주요 구성요소와 코드 구성 방법, 주요 구성 요소가 어디에 있는지, 입력 검증이 무엇을 위한 것인지 알게 되었습니다. + +### 다음 단계 + +휴식을 취하십시오! 많은 내용이었습니다. 기분이 상쾌하고 준비가 되었을 때 다음 섹션으로 이동하여 배운 내용을 적용하여 nf-core 호환 파이프라인을 작성하십시오. + +!!! tip + + 다음 파트로 이동하기 전에 subworkflow를 사용하여 workflow를 구성하는 방법을 배우고 싶다면 [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest를 확인하십시오. diff --git a/docs/ko/docs/hello_nf-core/02_rewrite_hello.md b/docs/ko/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..6f4c4e77b1 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1237 @@ +# 2부: nf-core용 Hello 재작성 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정의 두 번째 부분에서는 [Hello Nextflow](../hello_nextflow/index.md) 초급자 과정에서 만든 파이프라인의 nf-core 호환 버전을 생성하는 방법을 보여드립니다. + +교육의 첫 번째 섹션에서 nf-core 파이프라인이 많은 부속 파일과 함께 상당히 정교한 구조를 따른다는 것을 알아차리셨을 것입니다. +이 모든 것을 처음부터 만드는 것은 매우 지루할 것이므로, nf-core 커뮤니티는 프로세스를 시작하기 위해 템플릿에서 이를 수행하는 도구를 개발했습니다. + +파이프라인 스캐폴드를 생성하기 위해 이 도구를 사용하는 방법을 보여드린 다음, 기존의 '일반' 파이프라인 코드를 nf-core 스캐폴드에 맞게 조정하겠습니다. + +Hello 파이프라인에 익숙하지 않거나 복습이 필요하시면 [이 정보 페이지](../info/hello_pipeline.md)를 참조하세요. + +--- + +## 1. 새 파이프라인 프로젝트 생성 + +먼저 새 파이프라인의 스캐폴드를 생성합니다. + +!!! note "참고" + + 터미널에서 `hello-nf-core` 디렉토리에 있는지 확인하세요. + +### 1.1. 템플릿 기반 파이프라인 생성 도구 실행 + +`nf-core pipelines create` 명령으로 새 파이프라인을 생성하는 것부터 시작하겠습니다. +이는 파이프라인 이름, 설명, 작성자로 커스터마이징된 nf-core 기본 템플릿을 사용하여 새 파이프라인 스캐폴드를 생성합니다. + +```bash +nf-core pipelines create +``` + +이 명령을 실행하면 파이프라인 생성을 위한 텍스트 사용자 인터페이스(TUI)가 열립니다: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +이 TUI는 파이프라인에 대한 기본 정보를 제공하도록 요청하며 파이프라인 스캐폴드에 포함하거나 제외할 기능을 선택할 수 있게 해줍니다. + +- 시작 화면에서 **Let's go!**를 클릭합니다. +- `Choose pipeline type` 화면에서 **Custom**을 클릭합니다. +- 다음과 같이 파이프라인 세부 정보를 입력한 후(< YOUR NAME >을 자신의 이름으로 교체), **Next**를 클릭합니다. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < YOUR NAME > +``` + +- Template features 화면에서 `Toggle all features`를 **off**로 설정한 다음, 다음 항목을 선택적으로 **활성화**합니다. 선택 사항을 확인하고 **Continue**를 클릭합니다. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- `Final details` 화면에서 **Finish**를 클릭합니다. 파이프라인이 생성될 때까지 기다린 다음 **Continue**를 클릭합니다. +- Create GitHub repository 화면에서 **Finish without creating a repo**를 클릭합니다. 이렇게 하면 나중에 GitHub 저장소를 생성하기 위한 지침이 표시됩니다. 이를 무시하고 **Close**를 클릭합니다. + +TUI가 닫히면 다음과 같은 콘솔 출력이 표시됩니다. + +??? success "명령 출력" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +파이프라인 생성이 성공했다는 명시적인 확인은 콘솔 출력에 없지만, `core-hello`라는 새 디렉토리가 보일 것입니다. + +새 디렉토리의 내용을 확인하여 템플릿을 사용함으로써 얼마나 많은 작업을 절약했는지 확인하세요. + +```bash +tree core-hello +``` + +??? abstract "디렉토리 내용" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +정말 많은 파일입니다! + +`nf-core/demo` 파이프라인 구조를 탐색할 때 만났던 것과 동일한 많은 파일을 인식하실 것입니다. +하지만 아직 조금 헷갈리더라도 걱정하지 마세요. 이 교육 과정에서 중요한 부분들을 함께 살펴보겠습니다. + +!!! note "참고" + + 이 교육의 첫 번째 부분에서 살펴본 `nf-core/demo` 파이프라인과 비교했을 때 한 가지 중요한 차이점은 `modules` 디렉토리가 없다는 것입니다. + 이는 기본 nf-core 모듈을 포함하지 않기로 선택했기 때문입니다. + +### 1.2. 스캐폴드가 작동하는지 테스트 + +믿기 어렵겠지만, 실제 작업을 수행할 모듈을 아직 추가하지 않았음에도 불구하고, 파이프라인 스캐폴드는 실제로 `nf-core/demo` 파이프라인을 실행했던 것과 동일한 방식으로 test 프로필을 사용하여 실행할 수 있습니다. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +이는 모든 기본 배선이 제자리에 있음을 보여줍니다. +그렇다면 출력은 어디에 있을까요? 출력이 있기는 한가요? + +실제로 표준 실행 보고서를 포함하는 `core-hello-results`라는 새 결과 디렉토리가 생성되었습니다: + +```bash +tree core-hello-results +``` + +??? abstract "디렉토리 내용" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +보고서를 살펴보면 무엇이 실행되었는지 확인할 수 있는데, 답은 아무것도 실행되지 않았다는 것입니다! + +![비어있는 실행 타임라인 보고서](./img/execution_timeline_empty.png) + +코드에 실제로 무엇이 있는지 살펴보겠습니다. + +### 1.3. 플레이스홀더 workflow 검사 + +`main.nf` 파일 내부를 보면 `workflows/hello`에서 `HELLO`라는 workflow를 가져오는 것을 볼 수 있습니다. + +이것은 1부에서 만난 `workflows/demo.nf` workflow와 동등하며, 이미 일부 nf-core 기능이 갖춰진 관심 workflow의 플레이스홀더 역할을 합니다. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: --input에서 읽은 샘플시트 + main: + + ch_versions = channel.empty() + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 끝 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +[Hello Nextflow](../hello_nextflow/index.md)에서 개발된 것과 같은 기본 Nextflow workflow와 비교하면, 여기에서 새로운 몇 가지 사항(위의 강조 표시된 줄)을 발견할 수 있습니다: + +- workflow 블록에 이름이 있습니다 +- workflow 입력은 `take:` 키워드를 사용하여 선언되고 채널 구성은 상위 workflow로 이동됩니다 +- workflow 내용은 `main:` 블록 내부에 배치됩니다 +- 출력은 `emit:` 키워드를 사용하여 선언됩니다 + +이것들은 workflow를 **구성 가능(composable)**하게 만드는 Nextflow의 선택적 기능으로, 다른 workflow 내에서 호출될 수 있음을 의미합니다. + +!!! note "구성 가능한 workflow 심화" + + [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest는 여러 workflow를 함께 구성하고 그들 사이의 복잡한 데이터 흐름을 관리하는 방법을 포함하여 workflow 구성을 훨씬 더 심도 있게 탐구합니다. 여기서 구성 가능성을 소개하는 이유는 nf-core 템플릿 아키텍처의 기본 요구 사항이기 때문입니다. nf-core 템플릿 아키텍처는 중첩된 workflow를 사용하여 파이프라인 초기화, 메인 분석 workflow, 완료 작업을 별도의 재사용 가능한 컴포넌트로 구성합니다. + +우리는 관심 있는 workflow의 관련 로직을 해당 구조에 연결해야 합니다. +그를 위한 첫 번째 단계는 원래 workflow를 구성 가능하게 만드는 것입니다. + +### 요약 + +이제 nf-core 도구를 사용하여 파이프라인 스캐폴드를 생성하는 방법을 알게 되었습니다. + +### 다음 단계 + +nf-core와 호환되도록 만들기 위한 전제로 간단한 workflow를 구성 가능하게 만드는 방법을 배웁니다. + +--- + +## 2. 원래 Hello Nextflow workflow를 구성 가능하게 만들기 + +이제 workflow를 nf-core 스캐폴드에 통합하는 작업을 시작할 때입니다. +상기하자면, 우리는 [Hello Nextflow](../hello_nextflow/index.md) 교육 과정에서 다룬 workflow로 작업하고 있습니다. + +!!! tip "팁" + + 해당 파이프라인에 익숙하지 않거나 복습이 필요하시면 [Hello 파이프라인](../info/hello_pipeline.md)을 참조하세요. + +완성된 Hello Nextflow workflow의 깨끗하고 완전히 작동하는 복사본을 모듈 및 입력으로 사용할 것으로 예상되는 기본 CSV 파일과 함께 `original-hello` 디렉토리에 제공합니다. + +```bash +tree original-hello/ +``` + +??? abstract "디렉토리 내용" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +작동하는지 확인하기 위해 자유롭게 실행해 보세요: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +`hello.nf` workflow 파일을 열어 아래에 전체적으로 표시된 코드를 검사해 봅시다(모듈에 있는 프로세스는 제외): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// 모듈 포함 +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // CSV 파일에서 입력용 채널 생성 + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +보시다시피, 이 workflow는 단독으로 실행할 수 있는 간단한 이름 없는 workflow로 작성되었습니다. +nf-core 템플릿이 요구하는 대로 상위 workflow 내에서 실행 가능하게 만들려면 **구성 가능**하게 만들어야 합니다. + +필요한 변경 사항을 하나씩 살펴보겠습니다. + +### 2.1. workflow에 이름 지정 + +먼저 상위 workflow에서 참조할 수 있도록 workflow에 이름을 지정하겠습니다. + +=== "변경 후" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "변경 전" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +모듈 이름과 동일한 규칙이 workflow 이름에도 적용됩니다. + +### 2.2. 채널 구성을 `take`로 교체 + +이제 채널 구성을 예상 입력을 선언하는 간단한 `take` 문으로 교체합니다. + +=== "변경 후" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // 인사말 채널 + greeting_ch + ``` + +=== "변경 전" + + ```groovy title="original-hello/hello.nf" linenums="18" + // CSV 파일에서 입력용 채널 생성 + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +이는 입력이 어떻게 제공되는지에 대한 세부 사항을 상위 workflow에 맡깁니다. + +이 기회에 `params.greeting = 'greetings.csv'` 줄도 주석 처리할 수 있습니다. + +=== "변경 후" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "변경 전" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "참고" + + Nextflow 언어 서버 확장이 설치되어 있다면 구문 검사기가 코드에 빨간 물결선을 표시할 것입니다. + 이는 `take:` 문을 넣으면 `main:`도 있어야 하기 때문입니다. + + 다음 단계에서 추가하겠습니다. + +### 2.3. workflow 작업 앞에 `main` 문 추가 + +다음으로, workflow 본문에서 호출되는 나머지 작업 앞에 `main` 문을 추가합니다. + +=== "변경 후" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "변경 전" + + ```groovy title="original-hello/hello.nf" linenums="21" + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +이것은 기본적으로 '이것이 이 workflow가 _하는_ 일'이라고 말하는 것입니다. + +### 2.4. `emit` 문 추가 + +마지막으로 workflow의 최종 출력이 무엇인지 선언하는 `emit` 문을 추가합니다. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +이것은 원래 workflow와 비교하여 코드에 새롭게 추가된 부분입니다. + +### 2.5. 완료된 변경 사항 요약 + +설명대로 모든 변경을 수행했다면 workflow는 이제 다음과 같이 보일 것입니다: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// 모듈 포함 +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // 인사말 채널 + greeting_ch + + main: + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +이는 입력 채널에 무엇을 공급할지를 제외하고 Nextflow가 필요로 하는 모든 것을 설명합니다. +그것은 **진입점(entrypoint)** workflow라고도 불리는 상위 workflow에서 정의될 것입니다. + +### 2.6. 더미 진입점 workflow 만들기 + +구성 가능한 workflow를 복잡한 nf-core 스캐폴드에 통합하기 전에, 올바르게 작동하는지 확인해봅시다. +구성 가능한 workflow를 독립적으로 테스트하기 위해 간단한 더미 진입점 workflow를 만들 수 있습니다. + +동일한 `original-hello` 디렉토리에 `main.nf`라는 빈 파일을 만듭니다. + +```bash +touch original-hello/main.nf +``` + +다음 코드를 `main.nf` 파일에 복사합니다. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// hello.nf 파일에서 workflow 코드 가져오기 +include { HELLO } from './hello.nf' + +// 입력 매개변수 선언 +params.greeting = 'greetings.csv' + +workflow { + // CSV 파일에서 입력용 채널 생성 + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // 인사말 채널에서 가져온 workflow 호출 + HELLO(greeting_ch) + + // workflow에서 방출된 출력 보기 + HELLO.out.view { output -> "Output: $output" } +} +``` + +여기서 두 가지 중요한 관찰 사항이 있습니다: + +- 가져온 workflow를 호출하는 구문은 모듈을 호출하는 구문과 본질적으로 동일합니다. +- 입력을 workflow로 가져오는 것과 관련된 모든 것(입력 매개변수 및 채널 구성)은 이제 이 상위 workflow에 선언됩니다. + +!!! note "참고" + + 진입점 workflow 파일의 이름을 `main.nf`로 지정하는 것은 규칙이지 요구 사항이 아닙니다. + + 이 규칙을 따르면 `nextflow run` 명령에서 workflow 파일 이름을 지정하지 않아도 됩니다. + Nextflow는 실행 디렉토리에서 `main.nf`라는 파일을 자동으로 찾습니다. + + 그러나 원한다면 진입점 workflow 파일의 이름을 다르게 지정할 수 있습니다. + 그 경우 `nextflow run` 명령에서 workflow 파일 이름을 반드시 지정해야 합니다. + +### 2.7. workflow가 실행되는지 테스트 + +마침내 구성 가능한 workflow가 작동하는지 확인하는 데 필요한 모든 조각을 갖추게 되었습니다. +실행해 봅시다! + +```bash +nextflow run ./original-hello +``` + +여기서 `main.nf` 명명 규칙을 사용하는 이점을 볼 수 있습니다. +진입점 workflow의 이름을 `something_else.nf`로 지정했다면 `nextflow run original-hello/something_else.nf`를 해야 했을 것입니다. + +모든 변경 사항을 올바르게 수행했다면 완료될 때까지 실행되어야 합니다. + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +이는 HELLO workflow를 구성 가능하게 업그레이드하는 데 성공했음을 의미합니다. + +### 요약 + +이름을 지정하고 `take`, `main`, `emit` 문을 추가하여 workflow를 구성 가능하게 만드는 방법과 진입점 workflow에서 호출하는 방법을 알게 되었습니다. + +### 다음 단계 + +nf-core 호환 가능하게 만들기 위한 전제로 기본 구성 가능한 workflow를 nf-core 스캐폴드에 접목하는 방법을 배웁니다. + +--- + +## 3. 업데이트된 workflow 로직을 플레이스홀더 workflow에 맞추기 + +이제 구성 가능한 workflow가 올바르게 작동하는 것을 확인했으므로, 섹션 1에서 생성한 nf-core 파이프라인 스캐폴드로 돌아가겠습니다. +방금 개발한 구성 가능한 workflow를 nf-core 템플릿 구조에 통합하여 최종 결과가 다음과 같이 보이기를 원합니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +그렇다면 어떻게 이를 실현할까요? `core-hello/workflows/hello.nf`(nf-core 스캐폴드)에 있는 `HELLO` workflow의 현재 내용을 살펴보겠습니다. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: --input에서 읽어온 samplesheet + main: + + ch_versions = channel.empty() + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 끝 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +전반적으로 이 코드는 파이프라인에서 실행되는 소프트웨어 도구의 버전을 캡처하는 것과 관련된 일부 관리 작업을 제외하고는 거의 아무것도 하지 않습니다. + +섹션 2에서 개발한 원래 workflow의 구성 가능한 버전에서 관련 코드를 추가해야 합니다. + +다음 단계로 이 작업을 처리할 것입니다: + +1. 모듈을 복사하고 모듈 import 설정 +2. `take` 선언은 그대로 유지 +3. workflow 로직을 `main` 블록에 추가 +4. `emit` 블록 업데이트 + +!!! note "참고" + + 이번 첫 번째 패스에서는 버전 캡처를 무시하고 나중에 이 교육의 뒷부분에서 이를 연결하는 방법을 살펴볼 것입니다. + +### 3.1. 모듈 복사 및 모듈 import 설정 + +Hello Nextflow workflow의 네 가지 프로세스는 `original-hello/modules/`에 모듈로 저장됩니다. +이러한 모듈을 nf-core 프로젝트 구조(`core-hello/modules/local/` 아래)에 복사하고 nf-core workflow 파일에 import 문을 추가해야 합니다. + +먼저 `original-hello/`에서 `core-hello/`로 모듈 파일을 복사하겠습니다: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +이제 `core-hello/` 아래에 나열된 모듈 디렉토리를 볼 수 있어야 합니다. + +```bash +tree core-hello/modules +``` + +??? abstract "디렉토리 내용" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +이제 모듈 import 문을 설정하겠습니다. + +`original-hello/hello.nf` workflow의 import 문은 다음과 같았습니다: + +```groovy title="original-hello/hello.nf" linenums="9" +// 모듈 포함 +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +`core-hello/workflows/hello.nf` 파일을 열고 아래와 같이 이러한 import 문을 변환합니다. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +여기서 두 가지 더 흥미로운 관찰 사항이 있습니다: + +- import 문의 형식을 nf-core 스타일 규칙을 따르도록 조정했습니다. +- 이제 다른 중첩 수준에 저장되어 있음을 반영하도록 모듈에 대한 상대 경로를 업데이트했습니다. + +### 3.2. `take` 선언은 그대로 유지 + +nf-core 프로젝트에는 일반적으로 열 데이터를 포함하는 CSV 파일인 samplesheet 개념과 관련된 많은 사전 구축 기능이 있습니다. +본질적으로 우리의 `greetings.csv` 파일이 그러하므로 현재 `take` 선언을 그대로 유지하고 다음 단계에서 입력 채널의 이름만 업데이트하겠습니다. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: --input에서 읽어온 samplesheet +``` + +입력 처리는 이 workflow의 상위에서 수행됩니다(이 코드 파일에서가 아님). + +### 3.3. workflow 로직을 `main` 블록에 추가 + +이제 모듈을 workflow에서 사용할 수 있으므로 workflow 로직을 `main` 블록에 연결할 수 있습니다. + +참고로, 이것은 원래 workflow의 관련 코드이며, 구성 가능하게 만들 때 많이 변경되지 않았습니다(`main:` 줄만 추가했습니다): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) +``` + +`main:` 뒤에 오는 코드를 workflow의 새 버전에 복사해야 합니다. + +workflow를 실행하는 도구의 버전을 캡처하는 것과 관련된 일부 코드가 이미 있습니다. 지금은 그대로 두겠습니다(도구 버전은 나중에 처리하겠습니다). +맨 위에 `ch_versions = channel.empty()` 초기화를 유지한 다음 workflow 로직을 삽입하고 버전 수집 코드를 끝에 유지하겠습니다. +이러한 순서는 실제 파이프라인에서 프로세스가 workflow가 실행될 때 `ch_versions` 채널에 추가될 버전 정보를 방출하기 때문에 의미가 있습니다. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: --input에서 읽어온 samplesheet + + main: + + ch_versions = Channel.empty() + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: --input에서 읽어온 samplesheet + main: + + ch_versions = channel.empty() + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +`main:` 앞에 빈 줄을 추가하여 코드를 더 읽기 쉽게 만들었습니다. + +좋아 보이지만 `take:` 키워드 아래에 작성된 것과 일치하도록 아래와 같이 `sayHello()` 프로세스에 전달하는 채널의 이름을 `greeting_ch`에서 `ch_samplesheet`로 업데이트해야 합니다. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // 인사말 출력 (nf-core samplesheet 규칙을 사용하도록 업데이트됨) + sayHello(ch_samplesheet) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // 인사말 출력 + sayHello(greeting_ch) + ``` + +이제 workflow 로직이 올바르게 연결되었습니다. + +### 3.4. `emit` 블록 업데이트 + +마지막으로 workflow의 최종 출력 선언을 포함하도록 `emit` 블록을 업데이트해야 합니다. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +이것으로 HELLO workflow 자체에 대한 수정이 완료됩니다. +이 시점에서 우리는 구현하기로 설정한 전반적인 코드 구조를 달성했습니다. + +### 요약 + +구성 가능한 workflow의 핵심 부분을 nf-core 플레이스홀더 workflow에 맞추는 방법을 알게 되었습니다. + +### 다음 단계 + +nf-core 파이프라인 스캐폴드에서 입력이 처리되는 방식을 조정하는 방법을 배웁니다. + +--- + +## 4. 입력 처리 조정 + +workflow 로직을 nf-core 스캐폴드에 성공적으로 통합했으므로 이제 한 가지 더 중요한 부분을 처리해야 합니다: 입력 데이터가 올바르게 처리되도록 하는 것입니다. +nf-core 템플릿은 복잡한 유전체학 데이터 세트를 위해 설계된 정교한 입력 처리와 함께 제공되므로 더 간단한 `greetings.csv` 파일과 작동하도록 조정해야 합니다. + +### 4.1. 입력이 처리되는 위치 식별 + +첫 번째 단계는 입력 처리가 어디에서 수행되는지 파악하는 것입니다. + +Hello Nextflow workflow를 구성 가능하게 다시 작성할 때 입력 매개변수 선언을 `main.nf` 진입점 workflow로 한 단계 위로 이동한 것을 기억하실 것입니다. +따라서 파이프라인 스캐폴드의 일부로 생성된 최상위 `main.nf` 진입점 workflow를 살펴보겠습니다: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: 입력 유형에 따라 메인 분석 파이프라인 실행 +// +workflow CORE_HELLO { + + take: + samplesheet // channel: --input에서 읽어온 samplesheet + + main: + + // + // WORKFLOW: 파이프라인 실행 + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 메인 WORKFLOW 실행 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: 초기화 작업 실행 + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: 메인 워크플로우 실행 + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: 완료 작업 실행 + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 끝 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +nf-core 프로젝트는 중첩된 subworkflow를 많이 사용하므로 이 부분은 처음 접근할 때 약간 혼란스러울 수 있습니다. + +여기서 중요한 것은 두 개의 workflow가 정의되어 있다는 것입니다: + +- `CORE_HELLO`는 `core-hello/workflows/hello.nf`에서 방금 조정을 완료한 HELLO workflow를 실행하기 위한 얇은 래퍼입니다. +- `CORE_HELLO`와 `PIPELINE_INITIALISATION`, `PIPELINE_COMPLETION`이라는 두 개의 다른 subworkflow를 호출하는 이름 없는 workflow입니다. + +그들이 서로 어떻게 관련되어 있는지 보여주는 다이어그램이 있습니다: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +중요한 것은 이 수준에서 입력 채널을 구성하는 코드를 찾을 수 없고, `--input` 매개변수를 통해 제공되는 samplesheet에 대한 참조만 있다는 것입니다. + +약간의 조사 결과 입력 처리는 적절하게도 `PIPELINE_INITIALISATION` subworkflow에서 수행되며, 이는 `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`에서 가져온다는 것이 드러납니다. + +해당 파일을 열고 아래로 스크롤하면 다음 코드 덩어리에 도달합니다: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // params.input을 통해 제공된 입력 파일에서 채널 생성 + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +이것은 samplesheet를 구문 분석하고 HELLO workflow에서 소비할 준비가 된 형태로 전달하는 channel factory입니다. + +!!! note "참고" + + 위의 구문은 이전에 사용한 것과 약간 다르지만 기본적으로 다음은: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + 다음과 동등합니다: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +이 코드에는 nf-core 파이프라인 템플릿에 포함된 예제 samplesheet에 매우 특정적인 일부 구문 분석 및 검증 단계가 포함되어 있으며, 작성 당시 이는 매우 도메인별로 특정적이어서 우리의 간단한 파이프라인 프로젝트에 적합하지 않습니다. + +### 4.2. 템플릿 입력 채널 코드 교체 + +좋은 소식은 우리 파이프라인의 요구 사항이 훨씬 더 간단하므로 원래 Hello Nextflow workflow에서 개발한 채널 구성 코드로 이 모든 것을 교체할 수 있다는 것입니다. + +참고로 채널 구성은 다음과 같았습니다(solutions 디렉토리에서 확인): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // CSV 파일에서 입력용 채널 생성 + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +따라서 약간의 변경을 통해 초기화 workflow에 연결하기만 하면 됩니다: 채널 이름을 `greeting_ch`에서 `ch_samplesheet`로, 매개변수 이름을 `params.greeting`에서 `params.input`으로 업데이트합니다(강조 표시된 줄 참조). + +=== "변경 후" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // params.input을 통해 제공된 입력 파일에서 채널 생성 + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "변경 전" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // params.input을 통해 제공된 입력 파일에서 채널 생성 + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +이것으로 입력 처리가 작동하도록 만드는 데 필요한 변경 사항이 완료됩니다. + +현재 형태에서는 스키마 검증을 위한 nf-core의 내장 기능을 활용할 수 없지만 나중에 추가할 수 있습니다. +지금은 테스트 데이터에서 성공적으로 실행할 수 있는 것을 얻기 위해 가능한 한 간단하게 유지하는 데 중점을 둡니다. + +### 4.3. 테스트 프로필 업데이트 + +테스트 데이터와 매개변수에 대해 말하자면, 템플릿에 제공된 예제 samplesheet 대신 `greetings.csv` 미니 samplesheet를 사용하도록 이 파이프라인의 테스트 프로필을 업데이트하겠습니다. + +`core-hello/conf` 아래에는 작은 데이터 샘플과 전체 크기 데이터를 테스트하기 위한 두 개의 템플릿 테스트 프로필인 `test.config`와 `test_full.config`가 있습니다. +우리 파이프라인의 목적을 고려할 때 전체 크기 테스트 프로필을 설정하는 데는 실제로 의미가 없으므로 `test_full.config`를 무시하거나 삭제하셔도 됩니다. +몇 가지 기본 매개변수로 `greetings.csv` 파일에서 실행되도록 `test.config`를 설정하는 데 집중하겠습니다. + +#### 4.3.1. `greetings.csv` 파일 복사 + +먼저 파이프라인 프로젝트의 적절한 위치에 `greetings.csv` 파일을 복사해야 합니다. +일반적으로 작은 테스트 파일은 `assets` 디렉토리에 저장되므로 작업 디렉토리에서 파일을 복사하겠습니다. + +```bash +cp greetings.csv core-hello/assets/. +``` + +이제 `greetings.csv` 파일을 테스트 입력으로 사용할 준비가 되었습니다. + +#### 4.3.2. `test.config` 파일 업데이트 + +이제 다음과 같이 `test.config` 파일을 업데이트할 수 있습니다: + +=== "변경 후" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_ diff --git a/docs/ko/docs/hello_nf-core/03_use_module.md b/docs/ko/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..22f6ec6008 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# 파트 3: nf-core 모듈 사용하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정의 세 번째 파트에서는 기존 nf-core 모듈을 파이프라인에서 찾고, 설치하고, 사용하는 방법을 보여드립니다. + +nf-core로 작업할 때 얻을 수 있는 큰 이점 중 하나는 [nf-core/modules](https://github.com/nf-core/modules) 저장소에서 사전 구축되고 테스트된 모듈을 활용할 수 있다는 것입니다. +모든 프로세스를 처음부터 작성하는 대신, 모범 사례를 따르는 커뮤니티 유지 관리 모듈을 설치하고 사용할 수 있습니다. + +이것이 어떻게 작동하는지 보여드리기 위해, `core-hello` 파이프라인에서 사용자 정의 `collectGreetings` 모듈을 nf-core/modules의 `cat/cat` 모듈로 교체하겠습니다. + +??? info "이 섹션을 시작하는 방법" + + 이 과정 섹션은 [파트 2: nf-core용 Hello 재작성하기](./02_rewrite_hello.md)를 완료했고 작동하는 `core-hello` 파이프라인이 있다고 가정합니다. + + 파트 2를 완료하지 않았거나 이 파트를 새로 시작하고 싶다면, `core-hello-part2` 솔루션을 시작점으로 사용할 수 있습니다. + `hello-nf-core/` 디렉토리 내에서 이 명령을 실행하세요: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + 이렇게 하면 모듈을 추가할 준비가 된 완전히 기능하는 nf-core 파이프라인을 얻게 됩니다. + 다음 명령을 실행하여 성공적으로 실행되는지 테스트할 수 있습니다: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. 적합한 nf-core 모듈 찾기 및 설치하기 + +먼저, 기존 nf-core 모듈을 찾고 파이프라인에 설치하는 방법을 배워봅시다. + +우리는 여러 인사말 파일을 하나로 연결하기 위해 Unix `cat` 명령을 사용하는 `collectGreetings` 프로세스를 교체하는 것을 목표로 합니다. +파일 연결은 매우 일반적인 작업이므로, 이미 nf-core에 그 목적을 위해 설계된 모듈이 있을 것이라고 추론할 수 있습니다. + +바로 시작해봅시다. + +### 1.1. nf-core 웹사이트에서 사용 가능한 모듈 찾아보기 + +nf-core 프로젝트는 [https://nf-co.re/modules](https://nf-co.re/modules)에서 모듈의 중앙화된 카탈로그를 유지 관리합니다. + +웹 브라우저에서 모듈 페이지로 이동하고 검색 바를 사용하여 'concatenate'를 검색하세요. + +![모듈 검색 결과](./img/module-search-results.png) + +보시다시피, 많은 결과가 있으며, 그중 많은 것들이 매우 특정한 유형의 파일을 연결하도록 설계된 모듈입니다. +그중에서 범용인 `cat_cat`이라는 모듈을 볼 수 있을 것입니다. + +!!! note "모듈 명명 규칙" + + 밑줄(`_`)은 모듈 이름에서 슬래시(`/`) 문자의 대체로 사용됩니다. + + nf-core 모듈은 도구가 여러 명령을 제공할 때 `software/command` 명명 규칙을 따릅니다. 예를 들어 `samtools/view` (samtools 패키지, view 명령) 또는 `gatk/haplotypecaller` (GATK 패키지, HaplotypeCaller 명령)와 같습니다. + 하나의 주요 명령만 제공하는 도구의 경우, 모듈은 `fastqc` 또는 `multiqc`와 같이 단일 레벨을 사용합니다. + +`cat_cat` 모듈 박스를 클릭하여 모듈 문서를 확인하세요. + +모듈 페이지는 다음을 보여줍니다: + +- 간단한 설명: "A module for concatenation of gzipped or uncompressed files" +- 설치 명령: `nf-core modules install cat/cat` +- 입력 및 출력 채널 구조 +- 사용 가능한 매개변수 + +### 1.2. 명령줄에서 사용 가능한 모듈 목록 보기 + +또는 nf-core 도구를 사용하여 명령줄에서 직접 모듈을 검색할 수도 있습니다. + +```bash +nf-core modules list remote +``` + +이것은 nf-core/modules 저장소의 모든 사용 가능한 모듈 목록을 표시하지만, 찾고 있는 모듈의 이름을 이미 모르는 경우 약간 덜 편리합니다. +하지만 이름을 알고 있다면, 목록을 `grep`으로 파이프하여 특정 모듈을 찾을 수 있습니다: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "명령 출력" + + ```console + │ cat/cat + ``` + +`grep` 접근 방식은 이름에 검색어가 있는 결과만 추출한다는 점을 명심하세요. 이것은 `cat_cat`에는 작동하지 않습니다. + +### 1.3. 모듈에 대한 상세 정보 얻기 + +명령줄에서 특정 모듈에 대한 상세 정보를 보려면 `info` 명령을 사용하세요: + +```bash +nf-core modules info cat/cat +``` + +이것은 입력, 출력 및 기본 사용 정보를 포함한 모듈에 대한 문서를 표시합니다. + +??? success "명령 출력" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +이것은 웹사이트에서 찾을 수 있는 것과 정확히 동일한 정보입니다. + +### 1.4. cat/cat 모듈 설치하기 + +이제 원하는 모듈을 찾았으므로, 파이프라인의 소스 코드에 추가해야 합니다. + +좋은 소식은 nf-core 프로젝트에 이 부분을 쉽게 만드는 도구가 포함되어 있다는 것입니다. +특히, `nf-core modules install` 명령을 사용하면 코드를 검색하고 한 단계로 프로젝트에서 사용할 수 있도록 자동화할 수 있습니다. + +파이프라인 디렉토리로 이동하여 설치 명령을 실행하세요: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +도구가 먼저 저장소 유형을 지정하라는 메시지를 표시할 수 있습니다. +(그렇지 않은 경우 "Finally, the tool will proceed to install the module."로 건너뛰세요.) + +??? success "명령 출력" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +그렇다면 엔터 키를 눌러 기본 응답(`Pipeline`)을 수락하고 계속하세요. + +그런 다음 도구는 향후 이 프롬프트를 피하기 위해 프로젝트 구성을 수정할 것을 제안합니다. + +??? success "명령 출력" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +이 편리한 도구를 활용하는 것이 좋습니다! +엔터 키를 눌러 기본 응답(yes)을 수락하세요. + +마지막으로 도구가 모듈 설치를 진행합니다. + +??? success "명령 출력" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +명령은 자동으로: + +- 모듈 파일을 `modules/nf-core/cat/cat/`에 다운로드합니다 +- 설치된 모듈을 추적하기 위해 `modules.json`을 업데이트합니다 +- 워크플로에서 사용할 올바른 `include` 문을 제공합니다 + +!!! tip + + 모듈 설치 명령을 실행하기 전에 현재 작업 디렉토리가 파이프라인 프로젝트의 루트인지 항상 확인하세요. + +모듈이 올바르게 설치되었는지 확인해봅시다: + +```bash +tree -L 4 modules +``` + +??? abstract "디렉토리 내용" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +또한 nf-core 유틸리티에 로컬에 설치된 모듈을 나열하도록 요청하여 설치를 확인할 수 있습니다: + +```bash +nf-core modules list local +``` + +??? success "명령 출력" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +이것은 `cat/cat` 모듈이 이제 프로젝트의 소스 코드의 일부임을 확인합니다. + +그러나 새 모듈을 실제로 사용하려면 파이프라인으로 가져와야 합니다. + +### 1.5. 모듈 임포트 업데이트하기 + +`workflows/hello.nf` 워크플로의 임포트 섹션에서 `collectGreetings` 모듈에 대한 `include` 문을 `CAT_CAT`에 대한 것으로 교체합시다. + +참고로, 모듈 설치 도구가 우리에게 사용할 정확한 문을 제공했습니다: + +```groovy title="설치 명령으로 생성된 임포트 문" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +nf-core 규칙은 모듈을 가져올 때 모듈 이름에 대문자를 사용하는 것입니다. + +[core-hello/workflows/hello.nf](core-hello/workflows/hello.nf)를 열고 다음과 같이 교체하세요: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +nf-core 모듈의 경로가 로컬 모듈과 어떻게 다른지 주목하세요: + +- **nf-core 모듈**: `'../modules/nf-core/cat/cat/main'` (`main.nf` 참조) +- **로컬 모듈**: `'../modules/local/collectGreetings.nf'` (단일 파일 참조) + +이제 모듈이 워크플로에서 사용 가능하므로, `collectGreetings` 호출을 `CAT_CAT`를 사용하도록 교체하기만 하면 됩니다. 그렇죠? + +그렇게 빠르지 않습니다. + +이 시점에서 코드를 편집하고 싶은 유혹을 받을 수 있지만, 새 모듈이 무엇을 기대하고 무엇을 생성하는지 주의 깊게 검토하는 것이 좋습니다. + +우리는 이것을 별도의 섹션으로 다룰 것입니다. 왜냐하면 아직 다루지 않은 새로운 메커니즘, 즉 메타데이터 맵이 포함되기 때문입니다. + +!!! note + + 선택적으로 `collectGreetings.nf` 파일을 삭제할 수 있습니다: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + 그러나 로컬 모듈과 nf-core 모듈의 차이점을 이해하기 위한 참조로 유지하고 싶을 수도 있습니다. + +### 요점 정리 + +nf-core 모듈을 찾고 프로젝트에서 사용할 수 있도록 만드는 방법을 배웠습니다. + +### 다음 단계 + +새 모듈이 요구하는 것을 평가하고 파이프라인에 통합하기 위해 필요한 중요한 변경 사항을 식별합니다. + +--- + +## 2. 새 모듈의 요구사항 평가하기 + +특히, 모듈의 **인터페이스**, 즉 입력 및 출력 정의를 검토하고 교체하려는 모듈의 인터페이스와 비교해야 합니다. +이를 통해 새 모듈을 단순히 드롭인 대체로 처리할 수 있는지 아니면 일부 연결을 조정해야 하는지 결정할 수 있습니다. + +이상적으로는 모듈을 설치하기 전에 이 작업을 수행해야 하지만, 늦더라도 안 하는 것보다는 낫습니다. +(참고로 더 이상 원하지 않는 모듈을 제거하는 `uninstall` 명령이 있습니다.) + +!!! note + + CAT_CAT 프로세스에는 우리가 여기서 보여드리려는 것과 엄격하게 관련이 없는 다양한 압축 유형, 파일 확장자 등에 대한 상당히 영리한 처리가 포함되어 있으므로, 대부분을 무시하고 중요한 부분에만 집중하겠습니다. + +### 2.1. 두 모듈의 인터페이스 비교하기 + +참고로, 우리의 `collectGreetings` 모듈의 인터페이스는 다음과 같습니다: + +```groovy title="modules/local/collectGreetings.nf (발췌)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +`collectGreetings` 모듈은 두 개의 입력을 받습니다: + +- `input_files`는 처리할 하나 이상의 입력 파일을 포함합니다; +- `batch_name`은 출력 파일에 실행별 이름을 할당하는 데 사용하는 값으로, 메타데이터의 한 형태입니다. + +완료되면 `collectGreetings`는 `outfile` 태그로 방출되는 단일 파일 경로를 출력합니다. + +이에 비해 `cat/cat` 모듈의 인터페이스는 더 복잡합니다: + +```groovy title="modules/nf-core/cat/cat/main.nf (발췌)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +CAT_CAT 모듈은 단일 입력을 받지만, 그 입력은 두 가지를 포함하는 튜플입니다: + +- `meta`는 metamap이라고 하는 메타데이터를 포함하는 구조입니다; +- `files_in`은 처리할 하나 이상의 입력 파일을 포함하며, `collectGreetings`의 `input_files`와 동등합니다. + +완료되면 CAT_CAT는 두 부분으로 출력을 전달합니다: + +- metamap과 연결된 출력 파일을 포함하는 또 다른 튜플, `file_out` 태그로 방출됩니다; +- 사용된 소프트웨어 버전에 대한 정보를 캡처하는 `versions.yml` 파일, `versions` 태그로 방출됩니다. + +또한 기본적으로 출력 파일은 메타데이터의 일부인 식별자를 기반으로 이름이 지정됩니다(여기에는 코드가 표시되지 않음). + +코드만 보면 추적해야 할 것이 많아 보일 수 있으므로, 모든 것이 어떻게 함께 맞춰지는지 시각화하는 데 도움이 되는 다이어그램이 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +두 모듈이 콘텐츠 측면에서(입력 파일 세트와 일부 메타데이터) 유사한 입력 요구 사항을 가지고 있지만 해당 콘텐츠가 패키징되는 방식에 대한 기대가 매우 다르다는 것을 알 수 있습니다. +버전 파일을 무시하면, 주요 출력도 동등합니다(연결된 파일). 다만 CAT_CAT는 출력 파일과 함께 metamap도 방출합니다. + +곧 보시겠지만 패키징 차이는 처리하기 상당히 쉬울 것입니다. +그러나 metamap 부분을 이해하려면 추가 컨텍스트를 소개해야 합니다. + +### 2.2. metamap 이해하기 + +방금 CAT_CAT 모듈이 입력 튜플의 일부로 메타데이터 맵을 기대한다고 말씀드렸습니다. +그것이 무엇인지 자세히 살펴보는 데 몇 분을 할애합시다. + +**메타데이터 맵**은 종종 줄여서 **metamap**이라고 하며, 데이터 단위에 대한 정보를 포함하는 Groovy 스타일 맵입니다. +Nextflow 파이프라인의 컨텍스트에서 데이터 단위는 개별 샘플, 샘플 배치 또는 전체 데이터세트 등 원하는 무엇이든 될 수 있습니다. + +관례상 nf-core metamap은 `meta`로 명명되며 출력 이름 지정 및 데이터 단위 추적에 사용되는 필수 필드 `id`를 포함합니다. + +예를 들어, 일반적인 메타데이터 맵은 다음과 같을 수 있습니다: + +```groovy title="샘플 레벨 metamap 예제" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +또는 메타데이터가 배치 레벨에 첨부된 경우: + +```groovy title="배치 레벨 metamap 예제" +[id: 'batch1', date: '25.10.01'] +``` + +이제 이것을 입력 파일이 metamap과 함께 튜플로 패키징되기를 기대하고 출력 튜플의 일부로도 metamap을 출력하는 `CAT_CAT` 프로세스의 컨텍스트에 넣어봅시다. + +```groovy title="modules/nf-core/cat/cat/main.nf (발췌)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +결과적으로, 모든 데이터 단위는 관련 메타데이터가 첨부된 상태로 파이프라인을 통과합니다. +후속 프로세스도 해당 메타데이터에 쉽게 액세스할 수 있습니다. + +`CAT_CAT`에 의해 출력된 파일이 메타데이터의 일부인 식별자를 기반으로 이름이 지정될 것이라고 말씀드린 것을 기억하시나요? +이것이 관련 코드입니다: + +```groovy title="modules/nf-core/cat/cat/main.nf (발췌)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +이것은 대략 다음과 같이 번역됩니다: `prefix`가 외부 작업 매개변수 시스템(`task.ext`)을 통해 제공되면 출력 파일 이름을 지정하는 데 사용합니다; 그렇지 않으면 metamap의 `id` 필드에 해당하는 `${meta.id}`를 사용하여 생성합니다. + +다음과 같은 내용으로 이 모듈에 들어오는 입력 채널을 상상할 수 있습니다: + +```groovy title="입력 채널 내용 예제" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +그러면 출력 채널 내용은 다음과 같이 나옵니다: + +```groovy title="출력 채널 내용 예제" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +앞서 언급했듯이, `tuple val(meta), path(files_in)` 입력 설정은 모든 nf-core 모듈에서 사용되는 표준 패턴입니다. + +이것이 얼마나 유용할 수 있는지 이해하기 시작했기를 바랍니다. +메타데이터를 기반으로 출력 이름을 지정할 수 있을 뿐만 아니라, 다른 매개변수 값을 적용하는 것과 같은 작업을 수행할 수 있으며, 특정 연산자와 함께 사용하면 파이프라인을 통과하는 데이터를 그룹화, 정렬 또는 필터링할 수도 있습니다. + +!!! note "메타데이터에 대해 자세히 알아보기" + + 샘플시트에서 메타데이터를 읽고 처리를 사용자 정의하는 데 사용하는 방법을 포함하여 Nextflow 워크플로에서 메타데이터를 사용하는 방법에 대한 포괄적인 소개는 [워크플로의 메타데이터](../side_quests/metadata) 사이드 퀘스트를 참조하세요. + +### 2.3. 변경할 사항 요약하기 + +우리가 검토한 내용을 바탕으로 `cat/cat` 모듈을 활용하기 위해 파이프라인에 수행해야 할 주요 변경 사항은 다음과 같습니다: + +- 배치 이름을 포함하는 metamap 생성; +- metamap을 연결할 입력 파일 세트(`convertToUpper`에서 나오는)와 함께 튜플로 패키징; +- `collectGreetings()`에서 `CAT_CAT`로 호출 전환; +- `cowpy`에 전달하기 전에 `CAT_CAT` 프로세스에서 생성된 튜플에서 출력 파일 추출. + +이것으로 충분할 것입니다! 이제 계획이 있으니 시작할 준비가 되었습니다. + +### 요점 정리 + +새 모듈의 입력 및 출력 인터페이스를 평가하여 요구 사항을 식별하는 방법을 알고 있으며, metamap이 nf-core 파이프라인에서 파이프라인을 통과하는 데이터와 메타데이터를 밀접하게 연결하는 데 사용되는 방법을 배웠습니다. + +### 다음 단계 + +새 모듈을 워크플로에 통합합니다. + +--- + +## 3. CAT_CAT를 `hello.nf` 워크플로에 통합하기 + +이제 metamap에 대한 모든 것(또는 적어도 이 과정의 목적을 위해 충분한 것)을 알았으므로, 위에서 설명한 변경 사항을 실제로 구현할 시간입니다. + +명확성을 위해, 이것을 분류하고 각 단계를 개별적으로 다루겠습니다. + +!!! note + + 아래에 표시된 모든 변경 사항은 `core-hello/workflows/hello.nf` 워크플로 파일의 `main` 블록에 있는 워크플로 로직에 적용됩니다. + +### 3.1. 메타데이터 맵 생성하기 + +먼저, `CAT_CAT`에 대한 메타데이터 맵을 생성해야 하며, nf-core 모듈이 최소한 `id` 필드를 가진 metamap을 요구한다는 점을 명심해야 합니다. + +다른 메타데이터가 필요하지 않으므로, 간단하게 유지하고 다음과 같은 것을 사용할 수 있습니다: + +```groovy title="구문 예제" +def cat_meta = [id: 'test'] +``` + +단, `id` 값을 하드코딩하고 싶지 않습니다; `params.batch` 매개변수의 값을 사용하고 싶습니다. +따라서 코드는 다음과 같이 됩니다: + +```groovy title="구문 예제" +def cat_meta = [id: params.batch] +``` + +네, 기본 metamap을 생성하는 것은 정말 그렇게 간단합니다. + +`convertToUpper` 호출 후에 이 줄들을 추가하고 `collectGreetings` 호출을 제거합시다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 모든 인사말을 하나의 파일로 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +이것은 `id`가 배치 이름(테스트 프로필을 사용할 때 `test`가 됩니다)으로 설정된 간단한 메타데이터 맵을 생성합니다. + +### 3.2. 메타데이터 튜플이 있는 채널 생성하기 + +다음으로, 파일 채널을 메타데이터와 파일을 포함하는 튜플 채널로 변환합니다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // 튜플 형식으로 메타데이터와 파일이 있는 채널 생성 + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +추가한 줄은 두 가지를 달성합니다: + +- `.collect()`는 `convertToUpper` 출력의 모든 파일을 단일 목록으로 수집합니다 +- `.map { files -> tuple(cat_meta, files) }`는 `CAT_CAT`가 기대하는 형식인 `[metadata, files]`의 튜플을 생성합니다 + +이것이 `CAT_CAT`에 대한 입력 튜플을 설정하기 위해 수행해야 하는 전부입니다. + +### 3.3. CAT_CAT 모듈 호출하기 + +이제 새로 생성된 채널에 대해 `CAT_CAT`를 호출합니다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // 튜플 형식으로 메타데이터와 파일이 있는 채널 생성 + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // nf-core cat/cat 모듈을 사용하여 파일 연결 + CAT_CAT(ch_for_cat) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // 튜플 형식으로 메타데이터와 파일이 있는 채널 생성 + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +이것으로 이 교체의 가장 까다로운 부분이 완료되었지만, 아직 완전히 끝나지 않았습니다: 여전히 연결된 출력을 `cowpy` 프로세스에 전달하는 방식을 업데이트해야 합니다. + +### 3.4. `cowpy`를 위해 튜플에서 출력 파일 추출하기 + +이전에는 `collectGreetings` 프로세스가 `cowpy`에 직접 전달할 수 있는 파일만 생성했습니다. +그러나 `CAT_CAT` 프로세스는 출력 파일 외에 metamap을 포함하는 튜플을 생성합니다. + +`cowpy`가 아직 메타데이터 튜플을 받아들이지 않으므로(과정의 다음 파트에서 수정하겠습니다), `CAT_CAT`에서 생성된 튜플에서 출력 파일을 추출한 후 `cowpy`에 전달해야 합니다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // 튜플 형식으로 메타데이터와 파일이 있는 채널 생성 + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // 인사말 연결 + CAT_CAT(ch_for_cat) + + // cowpy가 아직 메타데이터를 사용하지 않으므로 튜플에서 파일 추출 + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(ch_for_cowpy, params.character) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // 인사말 방출 + sayHello(ch_samplesheet) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + + // 배치 이름을 ID로 하는 메타데이터 맵 생성 + def cat_meta = [ id: params.batch ] + + // 튜플 형식으로 메타데이터와 파일이 있는 채널 생성 + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // 인사말 연결 + CAT_CAT(ch_for_cat) + + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + ``` + +`.map{ meta, file -> file }` 연산은 `CAT_CAT`에서 생성된 `[metadata, file]` 튜플에서 파일을 새 채널인 `ch_for_cowpy`로 추출합니다. + +그런 다음 마지막 줄에서 `collectGreetings.out.outfile` 대신 `ch_for_cowpy`를 `cowpy`에 전달하기만 하면 됩니다. + +!!! note + + 과정의 다음 파트에서 `cowpy`를 메타데이터 튜플과 직접 작동하도록 업데이트하므로 이 추출 단계는 더 이상 필요하지 않습니다. + +### 3.5. 워크플로 테스트하기 + +새로 통합된 `cat/cat` 모듈로 워크플로가 작동하는지 테스트해봅시다: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +이것은 상당히 빠르게 실행되어야 합니다. + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +`collectGreetings` 대신 `CAT_CAT`가 프로세스 실행 목록에 나타나는 것을 주목하세요. + +그리고 끝났습니다! 이제 파이프라인의 해당 단계에 대해 사용자 정의 프로토타입 등급 코드 대신 강력한 커뮤니티 큐레이션 모듈을 사용하고 있습니다. + +### 요점 정리 + +이제 다음 방법을 알고 있습니다: + +- nf-core 모듈 찾기 및 설치하기 +- nf-core 모듈의 요구 사항 평가하기 +- nf-core 모듈과 함께 사용할 간단한 메타데이터 맵 생성하기 +- nf-core 모듈을 워크플로에 통합하기 + +### 다음 단계 + +nf-core 규칙을 따르도록 로컬 모듈을 적응시키는 방법을 배웁니다. +또한 nf-core 도구를 사용하여 템플릿에서 새로운 nf-core 모듈을 생성하는 방법도 보여드리겠습니다. diff --git a/docs/ko/docs/hello_nf-core/04_make_module.md b/docs/ko/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..17a8ea7fbe --- /dev/null +++ b/docs/ko/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,975 @@ +# 파트 4: nf-core 모듈 만들기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정의 네 번째 파트에서는 모듈을 이식 가능하고 유지보수 가능하게 만드는 주요 규칙을 적용하여 nf-core 모듈을 만드는 방법을 보여드립니다. + +nf-core 프로젝트는 Part 2에서 워크플로에 사용했던 것과 유사하게 적절하게 구조화된 모듈 템플릿을 자동으로 생성하는 명령(`nf-core modules create`)을 제공합니다. +하지만 교육 목적으로, 먼저 수동으로 작업을 진행할 것입니다: `core-hello` 파이프라인의 로컬 `cowpy` 모듈을 단계별로 nf-core 스타일 모듈로 변환하겠습니다. +그 후에, 향후 더 효율적으로 작업하기 위해 템플릿 기반 모듈 생성을 사용하는 방법을 보여드리겠습니다. + +??? info "이 섹션을 시작하는 방법" + + 이 섹션은 [Part 3: nf-core 모듈 사용하기](./03_use_module.md)를 완료하고 `CAT_CAT` 모듈을 파이프라인에 통합했다고 가정합니다. + + Part 3을 완료하지 않았거나 이 파트를 새롭게 시작하려는 경우, `core-hello-part3` 솔루션을 시작점으로 사용할 수 있습니다. + `hello-nf-core/` 디렉토리 내에서 다음 명령을 실행하십시오: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + 이렇게 하면 `CAT_CAT` 모듈이 이미 통합된 파이프라인을 얻게 됩니다. + 다음 명령을 실행하여 성공적으로 실행되는지 테스트할 수 있습니다: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. `cowpy`를 nf-core 모듈로 변환하기 + +이 섹션에서는 nf-core 규칙을 `core-hello` 파이프라인의 로컬 `cowpy` 모듈에 적용하여 nf-core 커뮤니티 표준을 따르는 모듈로 변환합니다. + +현재 `cowpy` 프로세스 모듈의 코드는 다음과 같습니다: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +다음 nf-core 규칙을 점진적으로 적용하겠습니다: + +1. **프로세스 이름을 `COWPY`로 대문자화** - 규칙을 따르기 위함입니다. +2. **`COWPY`를 메타데이터 튜플을 사용하도록 업데이트** - 워크플로를 통해 샘플 메타데이터를 전달하기 위함입니다. +3. **`ext.args`로 도구 인수 구성 중앙화** - 인터페이스는 최소화하면서 모듈 다용성을 높이기 위함입니다. +4. **`ext.prefix`로 출력 이름 표준화** - 일관성을 촉진하기 위함입니다. +5. **발행 구성 중앙화** - 일관성을 촉진하기 위함입니다. + +각 단계 후에는 모든 것이 예상대로 작동하는지 테스트하기 위해 파이프라인을 실행합니다. + +!!! warning "작업 디렉토리" + + 이 섹션의 모든 파일 편집과 명령 실행을 위해 `core-hello` 디렉토리(파이프라인 루트)에 있는지 확인하십시오. + + ```bash + cd core-hello + ``` + +### 1.1. 프로세스 이름 대문자화 + +이것은 순전히 스타일 규칙입니다(기술적 정당성은 없음) 하지만 nf-core 모듈의 표준이므로 준수하겠습니다. + +세 가지 변경 사항을 적용해야 합니다: + +1. 모듈에서 프로세스 이름 업데이트 +2. 워크플로 헤더에서 모듈 import 문 업데이트 +3. 워크플로 본문에서 프로세스 호출 및 emit 선언 업데이트 + +시작하겠습니다! + +#### 1.1.1. 모듈에서 프로세스 이름 업데이트 + +`cowpy.nf` 모듈 파일(`core-hello/modules/local/` 아래)을 열고 프로세스 이름을 대문자로 수정하십시오: + +=== "변경 후" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "변경 전" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +이 경우 대문자화는 완전히 직관적입니다. + +프로세스 이름이 여러 단어로 구성된 경우, 예를 들어 원래 camel case로 MyCowpyTool이라는 프로세스가 있었다면, nf-core 규칙은 밑줄을 사용하여 분리하여 MY_COWPY_TOOL이 됩니다. + +#### 1.1.2. 모듈 import 문 업데이트 + +프로세스 이름은 대소문자를 구분하므로, 프로세스 이름을 변경했으므로 `hello.nf`의 워크플로 헤더에서 모듈 import 문을 업데이트해야 합니다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +import 문에서 별칭을 사용하여 프로세스 호출을 업데이트하지 않을 수도 있지만, 그렇게 하면 대문자화 규칙을 채택하는 목적이 다소 상실됩니다. + +#### 1.1.3. 프로세스 호출 및 emit 선언 업데이트 + +이제 `hello.nf`의 workflow 블록에서 프로세스에 대한 두 참조를 업데이트하겠습니다: + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy로 인사말의 ASCII 아트 생성 + COWPY(CAT_CAT.out.file_out) + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(CAT_CAT.out.file_out) + + // + // 소프트웨어 버전 수집 및 저장 + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +**두 가지** 변경 사항을 모두 적용해야 합니다. 그렇지 않으면 실행할 때 오류가 발생합니다. + +#### 1.1.4. 파이프라인을 실행하여 테스트 + +이러한 변경 후 모든 것이 올바르게 작동하는지 테스트하기 위해 워크플로를 실행해 봅시다. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +잘 작동합니다! 이제 더 실질적인 변경을 진행하겠습니다. + +### 1.2. `COWPY`를 메타데이터 튜플을 사용하도록 업데이트 + +현재 버전의 `core-hello` 파이프라인에서는 아래 다이어그램의 상단에 표시된 것처럼 `CAT_CAT`의 출력 튜플에서 파일을 추출하여 `COWPY`에 전달하고 있습니다. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +다이어그램의 하단에 표시된 것처럼 `COWPY`가 메타데이터 튜플을 직접 받아들이도록 하여 워크플로를 통해 메타데이터가 계속 흐르도록 하는 것이 더 좋습니다. + +이를 위해 다음 변경 사항을 적용해야 합니다: + +1. 입력 및 출력 정의 업데이트 +2. 워크플로에서 프로세스 호출 업데이트 +3. 워크플로에서 emit 블록 업데이트 + +이 모든 작업을 완료한 후, 모든 것이 이전과 같이 작동하는지 확인하기 위해 파이프라인을 실행합니다. + +#### 1.2.1. 입력 및 출력 정의 업데이트 + +`cowpy.nf` 모듈 파일로 돌아가서 아래와 같이 메타데이터 튜플을 받아들이도록 수정하십시오. + +=== "변경 후" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "변경 전" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +보시다시피, **주요 입력**과 **출력** 모두를 Part 3에서 소개한 `tuple val(meta), path(input_file)` 패턴을 따르는 튜플로 변경했습니다. +출력의 경우, 출력 채널에 설명적인 이름을 부여하기 위해 `emit: cowpy_output`을 추가하는 기회를 가졌습니다. + +이제 프로세스가 예상하는 것을 변경했으므로, 프로세스 호출에서 제공하는 것을 업데이트해야 합니다. + +#### 1.2.2. 워크플로에서 프로세스 호출 업데이트 + +좋은 소식은 이 변경으로 프로세스 호출이 단순화된다는 것입니다. +이제 `CAT_CAT`의 출력과 `COWPY`의 입력이 동일한 '형태', 즉 둘 다 `tuple val(meta), path(input_file)` 구조로 구성되므로, `CAT_CAT` 프로세스의 출력에서 파일을 명시적으로 추출하는 대신 직접 연결할 수 있습니다. + +`hello.nf` 워크플로 파일(`core-hello/workflows/` 아래)을 열고 아래와 같이 `COWPY` 호출을 업데이트하십시오. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // cowpy로 인사말의 ASCII 아트 생성 + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // cowpy가 아직 메타데이터를 사용하지 않으므로 튜플에서 파일 추출 + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy로 인사말의 ASCII 아트 생성 + COWPY(ch_for_cowpy, params.character) + ``` + +이제 `CAT_CAT.out.file_out`에서 직접 `COWPY`를 호출합니다. + +결과적으로 더 이상 `ch_for_cowpy` 채널을 구성할 필요가 없으므로 해당 줄(및 주석 줄)을 완전히 삭제할 수 있습니다. + +#### 1.2.3. 워크플로에서 emit 블록 업데이트 + +`COWPY`가 이제 명명된 출력인 `cowpy_output`을 방출하므로, `hello.nf` 워크플로의 `emit:` 블록을 이를 사용하도록 업데이트할 수 있습니다. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +이것은 기술적으로 필요하지 않지만, 가능한 한 명명된 출력을 참조하는 것이 좋은 관행입니다. + +#### 1.2.4. 파이프라인을 실행하여 테스트 + +이러한 변경 후 모든 것이 올바르게 작동하는지 테스트하기 위해 워크플로를 실행해 봅시다. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +파이프라인은 성공적으로 실행되어야 하며, 이제 메타데이터가 `CAT_CAT`에서 `COWPY`로 흐릅니다. + +이것으로 `COWPY`가 메타데이터 튜플을 처리하도록 하기 위해 필요한 작업이 완료되었습니다. +이제 nf-core 모듈 패턴을 활용하기 위해 할 수 있는 다른 작업을 살펴보겠습니다. + +### 1.3. `ext.args`로 도구 인수 구성 중앙화 + +현재 상태에서 `COWPY` 프로세스는 `character` 매개변수에 대한 값을 받을 것으로 예상합니다. +결과적으로, 도구에서 설정한 기본값으로 만족하더라도 프로세스를 호출할 때마다 값을 제공해야 합니다. +`COWPY`의 경우 이것이 큰 문제는 아니지만, 많은 선택적 매개변수가 있는 도구의 경우 상당히 번거로울 수 있습니다. + +nf-core 프로젝트는 구성 파일을 통해 도구 인수를 더 편리하게 관리하기 위해 [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext)라는 Nextflow 기능을 사용할 것을 권장합니다. + +모든 도구 옵션에 대한 프로세스 입력을 선언하는 대신, 명령줄 구성에서 `ext.args`를 참조하도록 모듈을 작성합니다. +그런 다음 모든 모듈에 대한 구성 세부 정보를 통합하는 `modules.config` 파일에서 사용하려는 인수와 값을 보유하도록 `ext.args` 변수를 설정하기만 하면 됩니다. +Nextflow는 런타임에 해당 인수와 값을 도구 명령줄에 추가합니다. + +이 접근 방식을 `COWPY` 모듈에 적용해 봅시다. +다음 변경 사항을 적용해야 합니다: + +1. `COWPY` 모듈 업데이트 +2. `modules.config` 파일에서 `ext.args` 구성 +3. `hello.nf` 워크플로 업데이트 + +이 모든 작업을 완료한 후, 모든 것이 이전과 같이 작동하는지 확인하기 위해 파이프라인을 실행합니다. + +#### 1.3.1. `COWPY` 모듈 업데이트 + +실행해 봅시다. +`cowpy.nf` 모듈 파일(`core-hello/modules/local/` 아래)을 열고 아래와 같이 `ext.args`를 참조하도록 수정하십시오. + +=== "변경 후" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "변경 전" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +세 가지 변경 사항을 적용한 것을 볼 수 있습니다. + +1. **`input:` 블록에서 `val character` 입력을 제거했습니다.** + 앞으로는 아래에 설명된 대로 `ext.args` 구성을 통해 해당 인수를 제공하겠습니다. + +2. **`script:` 블록에서 `def args = task.ext.args ?: ''` 줄을 추가했습니다.** + 이 줄은 `?:` 연산자를 사용하여 `args` 변수의 값을 결정합니다: 비어 있지 않으면 `task.ext.args`의 내용, 비어 있으면 빈 문자열입니다. + 일반적으로 `ext.args`를 참조하지만, 이 코드는 모듈 수준 `ext.args` 구성을 가져오기 위해 `task.ext.args`를 참조해야 합니다. + +3. **명령줄에서 `-c "$character"`를 `$args`로 대체했습니다.** + 여기에 Nextflow가 `modules.config` 파일의 `ext.args`에 설정된 모든 도구 인수를 주입합니다. + +결과적으로 모듈 인터페이스가 더 간단해졌습니다: 필수 메타데이터와 파일 입력만 예상합니다. + +!!! note + + `?:` 연산자는 옆으로 누운 Elvis Presley의 얼굴처럼 보이기 때문에 'Elvis 연산자'라고 불리며, `?` 문자가 그의 머리카락의 웨이브를 상징합니다. + +#### 1.3.2. `modules.config` 파일에서 `ext.args` 구성 + +이제 모듈에서 `character` 선언을 제거했으므로, `modules.config` 구성 파일의 `ext.args`에 추가해야 합니다. + +구체적으로, `process {}` 블록에 다음 코드 조각을 추가하겠습니다: + +```groovy title="추가할 코드" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +`withName:` 구문은 이 구성을 `COWPY` 프로세스에만 할당하며, `ext.args = { "-c ${params.character}" }`는 단순히 `character` 매개변수의 값을 포함할 문자열을 구성합니다. +중괄호 사용에 주목하십시오. 이는 Nextflow에게 런타임에 매개변수 값을 평가하도록 지시합니다. + +이해가 되시나요? 추가해 봅시다. + +`conf/modules.config`를 열고 아래와 같이 `process {}` 블록 내에 구성 코드를 추가하십시오. + +=== "변경 후" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "변경 전" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +파이프라인의 모든 모듈이 이 파일에서 `ext.args`를 지정하도록 하는 것을 상상할 수 있기를 바랍니다. 다음과 같은 이점이 있습니다: + +- **모듈 인터페이스가 간단하게 유지됩니다** - 필수 메타데이터와 파일 입력만 받습니다 +- **파이프라인은 여전히 `params.character`를 노출합니다** - 최종 사용자는 여전히 이전과 같이 구성할 수 있습니다 +- **모듈은 이제 이식 가능합니다** - 특정 매개변수 이름을 기대하지 않고 다른 파이프라인에서 재사용할 수 있습니다 +- 구성이 `modules.config`에 **중앙화되어** 워크플로 로직을 깔끔하게 유지합니다 + +모든 파이프라인이 모듈별 구성을 중앙화하는 장소로 `modules.config` 파일을 사용함으로써, 다른 파이프라인에서 모듈을 더 재사용 가능하게 만듭니다. + +#### 1.3.3. `hello.nf` 워크플로 업데이트 + +`COWPY` 모듈이 더 이상 `character` 매개변수를 입력으로 요구하지 않으므로, 워크플로 호출을 그에 따라 업데이트해야 합니다. + +`hello.nf` 워크플로 파일(`core-hello/workflows/` 아래)을 열고 아래와 같이 `COWPY` 호출을 업데이트하십시오. + +=== "변경 후" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy로 인사말의 ASCII 아트 생성 + COWPY(CAT_CAT.out.file_out) + ``` + +=== "변경 전" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy로 인사말의 ASCII 아트 생성 + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +워크플로 코드가 이제 더 깨끗해졌습니다: 프로세스에 `params.character`를 직접 전달할 필요가 없습니다. +모듈 인터페이스는 최소한으로 유지되어 더 이식 가능하게 만들면서, 파이프라인은 여전히 구성을 통해 명시적 옵션을 제공합니다. + +#### 1.3.4. 파이프라인을 실행하여 테스트 + +워크플로가 여전히 예상대로 작동하는지 테스트해 봅시다. `ext.args` 구성이 작동하는지 확인하기 위해 다른 character를 지정합니다. + +더 수수께끼 같은 옵션 중 하나인 `kosh`를 사용하여 이 명령을 실행하십시오: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +이전처럼 성공적으로 실행되어야 합니다. + +`ext.args` 구성이 작동했는지 출력을 확인하여 검증해 봅시다. +파일 브라우저에서 출력을 찾거나 작업 해시(위 예제의 `38/eb29ea` 부분)를 사용하여 출력 파일을 확인하십시오: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "명령 출력" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +`kosh` character로 표시된 ASCII 아트를 확인할 수 있어야 하며, 이는 `ext.args` 구성이 작동했음을 확인합니다! + +??? info "(선택 사항) 명령 파일 검사" + + 구성이 정확히 어떻게 적용되었는지 확인하려면, `.command.sh` 파일을 검사할 수 있습니다: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + `-c kosh` 인수가 포함된 `cowpy` 명령을 볼 수 있습니다: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + 이는 `.command.sh` 파일이 `ext.args` 구성에 따라 올바르게 생성되었음을 보여줍니다. + +여기서 우리가 달성한 것에 대해 생각해 보십시오. +이 접근 방식은 모듈 인터페이스를 필수 데이터(파일, 메타데이터 및 모든 필수 샘플별 매개변수)에 집중하도록 유지하면서, 도구의 동작을 제어하는 옵션은 구성을 통해 별도로 처리합니다. + +이것은 `cowpy`와 같은 간단한 도구에는 불필요해 보일 수 있지만, 많은 선택적 인수가 있는 데이터 분석 도구의 경우 큰 차이를 만들 수 있습니다. + +이 접근 방식의 이점을 요약하면: + +- **깨끗한 인터페이스**: 모듈은 필수 데이터 입력(메타데이터 및 파일)에 집중합니다 +- **유연성**: 사용자는 샘플별 값을 포함하여 구성을 통해 도구 인수를 지정할 수 있습니다 +- **일관성**: 모든 nf-core 모듈이 이 패턴을 따릅니다 +- **이식성**: 하드코딩된 도구 옵션 없이 모듈을 재사용할 수 있습니다 +- **워크플로 변경 없음**: 도구 옵션을 추가하거나 변경해도 워크플로 코드를 업데이트할 필요가 없습니다 + +!!! note + + `ext.args` 시스템은 메타데이터에 따라 인수 값을 동적으로 전환하는 것을 포함하여 여기서 다루지 않은 강력한 추가 기능이 있습니다. 자세한 내용은 [nf-core 모듈 사양](https://nf-co.re/docs/guidelines/components/modules)을 참조하십시오. + +### 1.4. `ext.prefix`로 출력 이름 표준화 + +이제 `COWPY` 프로세스가 메타맵에 액세스할 수 있게 되었으므로, 또 다른 유용한 nf-core 패턴을 활용할 수 있습니다: 메타데이터를 기반으로 출력 파일 이름을 지정하는 것입니다. + +여기서는 `meta.id`(메타맵에 포함된 식별자)를 사용하여 모듈 전체에서 출력 파일 이름을 표준화하면서도 필요한 경우 개별적으로 모듈을 구성할 수 있도록 하는 `ext.prefix`라는 Nextflow 기능을 사용하겠습니다. + +이것은 `ext.args`와 유사하지만, 진행하면서 자세히 설명할 몇 가지 차이점이 있습니다. + +이 접근 방식을 `COWPY` 모듈에 적용해 봅시다. +다음 변경 사항을 적용해야 합니다: + +1. `COWPY` 모듈 업데이트 +2. `modules.config` 파일에서 `ext.prefix` 구성 + +(워크플로에는 변경이 필요하지 않습니다.) + +이 작업을 완료한 후, 모든 것이 이전과 같이 작동하는지 확인하기 위해 파이프라인을 실행합니다. + +#### 1.4.1. `COWPY` 모듈 업데이트 + +`cowpy.nf` 모듈 파일(`core-hello/modules/local/` 아래)을 열고 아래와 같이 `ext.prefix`를 참조하도록 수정하십시오. + +=== "변경 후" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "변경 전" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +세 가지 변경 사항을 적용한 것을 볼 수 있습니다. + +1. **`script:` 블록에서 `prefix = task.ext.prefix ?: "${meta.id}"` 줄을 추가했습니다.** + 이 줄은 `?:` 연산자를 사용하여 `prefix` 변수의 값을 결정합니다: 비어 있지 않으면 `task.ext.prefix`의 내용, 비어 있으면 메타맵의 식별자(`meta.id`)입니다. + 일반적으로 `ext.prefix`를 참조하지만, 이 코드는 모듈 수준 `ext.prefix` 구성을 가져오기 위해 `task.ext.prefix`를 참조해야 합니다. + +2. **명령줄에서 `cowpy-${input_file}`을 `${prefix}.txt`로 대체했습니다.** + 여기에 Nextflow가 위 줄에서 결정된 `prefix` 값을 주입합니다. + +3. **`output:` 블록에서 `path("cowpy-${input_file}")`을 `path("${prefix}.txt")`로 대체했습니다.** + 이것은 단순히 명령줄에 작성된 내용에 따라 파일 경로가 무엇인지 반복합니다. + +결과적으로 출력 파일 이름은 이제 적절한 파일 형식 확장자와 결합된 합리적인 기본값(메타맵의 식별자)을 사용하여 구성됩니다. + +#### 1.4.2. `modules.config` 파일에서 `ext.prefix` 구성 + +이 경우 합리적인 기본값은 우리의 취향에 충분히 표현적이지 않습니다. 이전과 같이 도구 이름을 포함하는 사용자 정의 명명 패턴인 `cowpy-<id>.txt`를 사용하고 싶습니다. + +`ext.args`로 `character` 매개변수를 처리했던 것처럼 `modules.config`에서 `ext.prefix`를 구성하여 이를 수행하겠습니다. 단, 이번에는 `withName: 'COWPY' {}` 블록이 이미 존재하므로 다음 줄만 추가하면 됩니다: + +```groovy title="추가할 코드" +ext.prefix = { "cowpy-${meta.id}" } +``` + +이것은 원하는 문자열을 구성합니다. +다시 한 번 중괄호를 사용하여 Nextflow에게 런타임에 `meta.id` 값을 평가하도록 지시합니다. + +추가해 봅시다. + +`conf/modules.config`를 열고 아래와 같이 `process {}` 블록 내에 구성 코드를 추가하십시오. + +=== "변경 후" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "변경 전" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +궁금하실 수도 있는데, `ext.prefix` 클로저는 구성이 메타데이터를 사용할 수 있는 프로세스 실행 컨텍스트에서 평가되기 때문에 올바른 메타데이터 조각에 액세스할 수 있습니다. + +#### 1.4.3. 파이프라인을 실행하여 테스트 + +워크플로가 여전히 예상대로 작동하는지 테스트해 봅시다. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +결과 디렉토리의 출력을 살펴보십시오. +기본 배치 이름을 기반으로 이전과 동일한 이름을 가진 cowpy 출력 파일 `cowpy-test.txt`를 볼 수 있어야 합니다. + +??? abstract "디렉토리 내용" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +모듈이나 워크플로 코드를 변경하지 않고도 명명 패턴을 변경할 수 있다는 것을 확인하기 위해 `conf/modules.config`에서 `ext.prefix` 구성을 자유롭게 변경해 보십시오. + +또는 명령줄에서 다른 `--batch` 매개변수를 지정하여 다시 실행하여 해당 부분이 여전히 즉시 사용자 정의 가능한지 확인할 수도 있습니다. + +이것은 `ext.prefix`를 통해 모듈 인터페이스를 유연하게 유지하면서 선호하는 명명 규칙을 유지할 수 있는 방법을 보여줍니다. + +이 접근 방식의 이점을 요약하면: + +- **표준화된 명명**: 출력 파일은 일반적으로 메타데이터의 샘플 ID를 사용하여 명명됩니다 +- **구성 가능**: 필요한 경우 사용자가 기본 명명을 재정의할 수 있습니다 +- **일관성**: 모든 nf-core 모듈이 이 패턴을 따릅니다 +- **예측 가능**: 출력 파일이 무엇으로 호출될지 쉽게 알 수 있습니다 + +꽤 좋죠? +그런데 nf-core 가이드라인에 맞게 모듈을 개선하기 위해 수행해야 할 중요한 변경 사항이 하나 더 있습니다. + +### 1.5. 발행 구성 중앙화 + +이제 두 개의 서로 다른 디렉토리에 출력을 발행하고 있다는 것을 알아차렸을 것입니다: + +- **`results`** — 로컬 모듈에 대해 처음부터 사용해 온 원래 출력 디렉토리로, 모듈별 `publishDir` 지시문을 사용하여 개별적으로 설정됨; +- **`core-hello-results`** — 명령줄에서 `--outdir`로 설정된 출력 디렉토리로, nf-core 로그와 `CAT_CAT`이 발행한 결과를 받고 있음. + +이것은 지저분하고 최적이 아닙니다. 모든 것에 대해 하나의 위치를 갖는 것이 더 좋을 것입니다. +물론, 각 로컬 모듈로 이동하여 `publishDir` 지시문을 수동으로 업데이트하여 `core-hello-results` 디렉토리를 사용하도록 할 수 있지만, 다음에 출력 디렉토리를 변경하기로 결정하면 어떻게 될까요? + +개별 모듈이 발행 결정을 내리도록 하는 것은 명백히 올바른 방법이 아닙니다. 특히 동일한 모듈이 다양한 요구 사항이나 선호도를 가진 사람들에 의해 많은 다른 파이프라인에서 사용될 수 있는 세상에서는 말입니다. +워크플로 구성 수준에서 출력이 발행되는 위치를 제어할 수 있어야 합니다. + +"잠깐," 여러분이 말할 수 있습니다. "`CAT_CAT`은 `--outdir`로 출력을 보내고 있습니다. `publishDir` 지시문을 복사해야 할까요?" + +네, 훌륭한 아이디어입니다. + +단, `publishDir` 지시문이 없습니다. (계속해서 모듈 코드를 보십시오.) + +nf-core 파이프라인은 개별 모듈에서 `publishDir`을 구성하는 대신 `conf/modules.config`에서 구성하여 워크플로 수준에서 제어를 중앙화하기 때문입니다. +구체적으로, nf-core 템플릿은 재정의 지시문이 제공되지 않는 한 모든 모듈에 적용되는 기본 `publishDir` 지시문(미리 정의된 디렉토리 구조 포함)을 선언합니다. + +멋지게 들리지 않나요? 이 기본 지시문을 활용하기 위해 로컬 모듈에서 현재 `publishDir` 지시문을 제거하기만 하면 될까요? + +`COWPY`에서 시도하여 어떤 일이 일어나는지 확인한 다음, 작동 방식을 이해하기 위해 기본 구성 코드를 살펴보겠습니다. + +마지막으로, 원하는 경우 기본 동작을 재정의하는 방법을 보여드리겠습니다. + +#### 1.5.1. `COWPY`에서 `publishDir` 지시문 제거 + +실행해 봅시다. +`cowpy.nf` 모듈 파일(`core-hello/modules/local/` 아래)을 열고 아래와 같이 `publishDir` 지시문을 제거하십시오. + +=== "변경 후" + + ```groovy title="core-hello/modules/local/cowpy.nf (발췌)" linenums="1" + #!/usr/bin/env nextflow + + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "변경 전" + + ```groovy title="core-hello/modules/local/cowpy.nf (발췌)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // cowpy로 ASCII 아트 생성 (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +이게 전부입니다! + +#### 1.5.2. 파이프라인을 실행하여 테스트 + +이제 파이프라인을 실행하면 어떤 일이 일어나는지 살펴봅시다. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /worksp diff --git a/docs/ko/docs/hello_nf-core/05_input_validation.md b/docs/ko/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..86a2288ff9 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# 파트 5: 입력 검증 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정의 다섯 번째 파트에서는 nf-schema 플러그인을 사용하여 파이프라인 입력과 매개변수를 검증하는 방법을 보여드립니다. + +??? info "이 섹션을 시작하는 방법" + + 이 섹션은 [Part 4: Make an nf-core module](./04_make_module.md)을 완료하고 파이프라인의 `COWPY` process 모듈을 nf-core 표준으로 업데이트했다고 가정합니다. + + Part 4를 완료하지 않았거나 이 파트를 새로 시작하고 싶다면, `core-hello-part4` 솔루션을 시작점으로 사용할 수 있습니다. + `hello-nf-core/` 디렉토리 안에서 다음 명령을 실행하십시오: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + 이렇게 하면 `COWPY` 모듈이 이미 nf-core 표준을 따르도록 업그레이드된 파이프라인을 얻게 됩니다. + 다음 명령을 실행하여 성공적으로 실행되는지 테스트할 수 있습니다: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. 준비 운동: 배경 지식 + +### 0.1. 검증이 중요한 이유 + +파이프라인을 두 시간 동안 실행했는데, 사용자가 잘못된 확장자를 가진 파일을 제공하여 실패하는 상황을 상상해 보십시오. 또는 수수께끼 같은 오류를 디버깅하는 데 몇 시간을 소비한 끝에 매개변수의 철자가 잘못되었다는 것을 발견하는 경우도 있습니다. 입력 검증이 없으면 이러한 시나리오가 흔하게 발생합니다. + +다음 예시를 고려해 보십시오: + +```console title="검증이 없는 경우" +$ nextflow run my-pipeline --input data.txt --output results + +...2시간 후... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +파이프라인이 잘못된 입력을 받아들이고 실패하기 전까지 몇 시간 동안 실행되었습니다. 적절한 검증이 있는 경우: + +```console title="검증이 있는 경우" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +파이프라인이 명확하고 실행 가능한 오류 메시지와 함께 즉시 실패합니다. 이는 시간, 컴퓨팅 리소스, 그리고 좌절을 절약해 줍니다. + +### 0.2. nf-schema 플러그인 + +[nf-schema 플러그인](https://nextflow-io.github.io/nf-schema/latest/)은 Nextflow 파이프라인에 포괄적인 검증 기능을 제공하는 Nextflow 플러그인입니다. +nf-schema는 모든 Nextflow workflow에서 작동하지만, 모든 nf-core 파이프라인의 표준 검증 솔루션입니다. + +nf-schema는 여러 주요 기능을 제공합니다: + +- **매개변수 검증**: `nextflow_schema.json`에 대해 파이프라인 매개변수 검증 +- **샘플 시트 검증**: `assets/schema_input.json`에 대해 입력 파일 검증 +- **채널 변환**: 검증된 샘플 시트를 Nextflow channel로 변환 +- **도움말 텍스트 생성**: 스키마 정의로부터 `--help` 출력 자동 생성 +- **매개변수 요약**: 기본값과 다른 매개변수를 표시 + +nf-schema는 더 이상 사용되지 않는 nf-validation 플러그인의 후속 버전이며 검증을 위해 표준 [JSON Schema Draft 2020-12](https://json-schema.org/)를 사용합니다. + +??? info "Nextflow 플러그인이란 무엇입니까?" + + 플러그인은 Nextflow 언어 자체에 새로운 기능을 추가하는 확장입니다. `nextflow.config`의 `plugins{}` 블록을 통해 설치되며 다음을 제공할 수 있습니다: + + - 가져올 수 있는 새로운 함수와 클래스 (`samplesheetToList`와 같은) + - 새로운 DSL 기능과 연산자 + - 외부 서비스와의 통합 + + nf-schema 플러그인은 `nextflow.config`에 지정됩니다: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + 설치된 후에는 `include { functionName } from 'plugin/plugin-name'` 구문을 사용하여 플러그인에서 함수를 가져올 수 있습니다. + +### 0.3. 두 가지 검증 유형을 위한 두 개의 스키마 파일 + +nf-core 파이프라인은 두 가지 검증 유형에 해당하는 두 개의 별도 스키마 파일을 사용합니다: + +| 스키마 파일 | 목적 | 검증 대상 | +| -------------------------- | ---------------- | ----------------------------------------------- | +| `nextflow_schema.json` | 매개변수 검증 | 명령줄 플래그: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | 입력 데이터 검증 | 샘플 시트 및 입력 파일의 내용 | + +두 스키마 모두 JSON Schema 형식을 사용하며, 이는 데이터 구조를 설명하고 검증하기 위해 널리 채택된 표준입니다. + +**매개변수 검증**은 명령줄 매개변수(플래그 예: `--outdir`, `--batch`, `--input`)를 검증합니다: + +- 매개변수 타입, 범위, 형식 확인 +- 필수 매개변수가 제공되었는지 확인 +- 파일 경로가 존재하는지 검증 +- `nextflow_schema.json`에 정의됨 + +**입력 데이터 검증**은 샘플 시트 및 매니페스트 파일(데이터를 설명하는 CSV/TSV 파일)의 구조를 검증합니다: + +- 컬럼 구조 및 데이터 타입 확인 +- 샘플 시트에 참조된 파일 경로가 존재하는지 검증 +- 필수 필드가 있는지 확인 +- `assets/schema_input.json`에 정의됨 + +!!! warning "입력 데이터 검증이 하지 않는 것" + + 입력 데이터 검증은 *매니페스트 파일*(샘플 시트, CSV 파일)의 구조를 확인하지만 실제 데이터 파일(FASTQ, BAM, VCF 등)의 내용을 검증하지는 않습니다. + + 대규모 데이터의 경우, 파일 내용 검증(예: BAM 무결성 확인)은 오케스트레이션 머신의 검증 단계가 아니라 워커 노드에서 실행되는 파이프라인 process에서 수행되어야 합니다. + +### 0.4. 검증은 언제 발생해야 합니까? + +```mermaid +graph LR + A[사용자가 파이프라인 실행] --> B[매개변수 검증] + B -->|✓ 유효함| C[입력 데이터 검증] + B -->|✗ 유효하지 않음| D[오류: 매개변수 수정] + C -->|✓ 유효함| E[파이프라인 실행] + C -->|✗ 유효하지 않음| F[오류: 입력 데이터 수정] +``` + +검증은 파이프라인 process가 실행되기 **전에** 발생하여 빠른 피드백을 제공하고 컴퓨팅 시간 낭비를 방지해야 합니다. + +이제 이러한 원칙을 실제로 적용해 보겠습니다. 매개변수 검증부터 시작하겠습니다. + +--- + +## 1. 매개변수 검증 (nextflow_schema.json) + +파이프라인에 매개변수 검증을 추가하는 것부터 시작하겠습니다. 이는 `--input`, `--outdir`, `--batch`와 같은 명령줄 플래그를 검증합니다. + +### 1.1. 입력 파일 검증을 건너뛰도록 검증 구성 + +nf-core 파이프라인 템플릿은 이미 nf-schema가 설치되고 구성되어 제공됩니다: + +- nf-schema 플러그인은 `nextflow.config`의 `plugins{}` 블록을 통해 설치됩니다 +- 매개변수 검증은 `params.validate_params = true`를 통해 기본적으로 활성화됩니다 +- 검증은 파이프라인 초기화 중에 `UTILS_NFSCHEMA_PLUGIN` 서브워크플로우에 의해 수행됩니다 + +검증 동작은 `nextflow.config`의 `validation{}` 범위를 통해 제어됩니다. + +매개변수 검증을 먼저 작업할 것이고(이 섹션) 섹션 2까지 입력 데이터 스키마를 구성하지 않을 것이므로, 일시적으로 nf-schema에게 `input` 매개변수의 파일 내용 검증을 건너뛰도록 지시해야 합니다. + +`nextflow.config`를 열고 `validation` 블록을 찾으십시오(246줄 근처). 입력 파일 검증을 건너뛰기 위해 `ignoreParams`를 추가하십시오: + +=== "수정 후" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +이 구성은 nf-schema에게 다음을 지시합니다: + +- **`defaultIgnoreParams`**: `genomes`와 같은 복잡한 매개변수의 검증 건너뛰기 (템플릿 개발자가 설정) +- **`ignoreParams`**: `input` 매개변수의 파일 내용 검증 건너뛰기 (일시적; 섹션 2에서 다시 활성화할 것임) +- **`monochromeLogs`**: `true`로 설정되면 검증 메시지의 색상 출력 비활성화 (`params.monochrome_logs`로 제어됨) + +!!! note "input 매개변수를 무시하는 이유는 무엇입니까?" + + `nextflow_schema.json`의 `input` 매개변수는 `"schema": "assets/schema_input.json"`을 가지고 있어 nf-schema에게 해당 스키마에 대해 입력 CSV 파일의 *내용*을 검증하도록 지시합니다. + 아직 해당 스키마를 구성하지 않았으므로 일시적으로 이 검증을 무시합니다. + 섹션 2에서 입력 데이터 스키마를 구성한 후 이 설정을 제거할 것입니다. + +### 1.2. 매개변수 스키마 검토 + +파이프라인 템플릿과 함께 제공된 `nextflow_schema.json` 파일의 섹션을 살펴보겠습니다: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +매개변수 스키마는 그룹으로 구성됩니다. 다음은 `input_output_options` 그룹입니다: + +```json title="core-hello/nextflow_schema.json (발췌)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +여기에 설명된 각 입력은 검증할 수 있는 다음과 같은 주요 속성을 가지고 있습니다: + +- **`type`**: 데이터 타입 (string, integer, boolean, number) +- **`format`**: `file-path` 또는 `directory-path`와 같은 특수 형식 +- **`exists`**: 파일 경로의 경우 파일이 존재하는지 확인 +- **`pattern`**: 값이 일치해야 하는 정규 표현식 +- **`required`**: 제공되어야 하는 매개변수 이름의 배열 +- **`mimetype`**: 검증을 위해 예상되는 파일 mimetype + +예리한 눈을 가지고 있다면, 우리가 사용해 온 `batch` 입력 매개변수가 아직 스키마에 정의되지 않았다는 것을 알아차릴 수 있습니다. +다음 섹션에서 추가하겠습니다. + +??? info "스키마 매개변수는 어디에서 왔습니까?" + + 스키마 검증은 `nextflow.config`를 매개변수 정의의 기본으로 사용합니다. + workflow 스크립트의 다른 곳(`main.nf` 또는 모듈 파일)에서 선언된 매개변수는 스키마 검증기에 의해 자동으로 **인식되지 않습니다**. + + 이는 항상 `nextflow.config`에서 파이프라인 매개변수를 선언한 다음 `nextflow_schema.json`에서 검증 규칙을 정의해야 함을 의미합니다. + +### 1.3. batch 매개변수 추가 + +스키마는 수동으로 편집할 수 있는 JSON 파일이지만, **수동 편집은 오류가 발생하기 쉽고 권장되지 않습니다**. +대신 nf-core는 JSON Schema 구문을 처리하고 변경 사항을 검증하는 대화형 GUI 도구를 제공합니다: + +```bash +nf-core pipelines schema build +``` + +다음과 같은 내용이 표시될 것입니다: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +`y`를 입력하고 Enter를 눌러 대화형 웹 인터페이스를 실행하십시오. + +브라우저가 열리면서 Parameter schema builder가 표시됩니다: + +![Schema builder 인터페이스](./img/schema_build.png) + +`batch` 매개변수를 추가하려면: + +1. 상단의 **"Add parameter"** 버튼을 클릭하십시오 +2. 드래그 핸들(⋮⋮)을 사용하여 새 매개변수를 "Input/output options" 그룹으로 `input` 매개변수 아래로 이동시키십시오 +3. 매개변수 세부 정보를 입력하십시오: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: 체크박스 선택 + - 선택적으로, 아이콘 선택기에서 아이콘 선택 (예: `fas fa-layer-group`) + +![batch 매개변수 추가](./img/schema_add.png) + +완료되면 오른쪽 상단의 **"Finished"** 버튼을 클릭하십시오. + +터미널로 돌아가면 다음이 표시됩니다: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +`Ctrl+C`를 눌러 schema builder를 종료하십시오. + +이제 도구가 새로운 `batch` 매개변수로 `nextflow_schema.json` 파일을 업데이트했으며, 모든 JSON Schema 구문을 올바르게 처리했습니다. + +### 1.4. 변경 사항 확인 + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (발췌)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +`batch` 매개변수가 스키마에 추가되었고 "required" 필드가 이제 `["input", "outdir", "batch"]`를 표시하는 것을 확인할 수 있습니다. + +### 1.5. 매개변수 검증 테스트 + +이제 매개변수 검증이 올바르게 작동하는지 테스트해 보겠습니다. + +먼저 필수 `input` 매개변수 없이 실행해 보십시오: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "명령 출력" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +완벽합니다! 검증이 파이프라인이 실행되기 전에 누락된 필수 매개변수를 잡아냅니다. + +이제 유효한 매개변수 세트로 시도해 보십시오: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +파이프라인이 성공적으로 실행되어야 하며 `batch` 매개변수가 이제 검증됩니다. + +### 정리 + +대화형 `nf-core pipelines schema build` 도구를 사용하여 `nextflow_schema.json`에 매개변수를 추가하는 방법을 배웠고 실제로 매개변수 검증을 확인했습니다. +웹 인터페이스가 모든 JSON Schema 구문을 처리해 주므로 오류가 발생하기 쉬운 수동 JSON 편집 없이도 복잡한 매개변수 스키마를 쉽게 관리할 수 있습니다. + +### 다음 단계는? + +이제 매개변수 검증이 작동하니 입력 데이터 파일 내용에 대한 검증을 추가해 보겠습니다. + +--- + +## 2. 입력 데이터 검증 (schema_input.json) + +입력 CSV 파일의 내용에 대한 검증을 추가하겠습니다. +매개변수 검증이 명령줄 플래그를 확인하는 반면, 입력 데이터 검증은 CSV 파일 내부의 데이터가 올바르게 구조화되었는지 확인합니다. + +### 2.1. greetings.csv 형식 이해 + +입력이 어떻게 생겼는지 다시 살펴보겠습니다: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +이것은 다음과 같은 간단한 CSV입니다: + +- 세 개의 컬럼 (헤더 없음) +- 각 줄에: 인사말, 언어, 점수 +- 처음 두 컬럼은 특별한 형식 요구 사항이 없는 텍스트 문자열 +- 세 번째 컬럼은 정수 + +우리 파이프라인의 경우 첫 번째 컬럼만 필수입니다. + +### 2.2. 스키마 구조 설계 + +우리의 사용 사례에서는 다음을 원합니다: + +1. 최소 하나의 컬럼을 가진 CSV 입력 허용 +2. 각 행의 첫 번째 요소를 인사말 문자열로 취급 +3. 인사말이 비어 있지 않고 공백으로 시작하지 않는지 확인 +4. 언어 필드가 지원되는 언어 코드 중 하나와 일치하는지 확인 (en, fr, es, it, de) +5. 점수 필드가 0에서 100 사이의 값을 가진 정수인지 확인 + +이를 객체 배열로 구조화하며, 각 객체는 최소한 `greeting` 필드를 가집니다. + +### 2.3. 스키마 파일 업데이트 + +nf-core 파이프라인 템플릿은 paired-end 시퀀싱 데이터를 위해 설계된 기본 `assets/schema_input.json`을 포함합니다. +이를 우리의 인사말 사용 사례에 맞는 더 간단한 스키마로 교체해야 합니다. + +`assets/schema_input.json`을 열고 `properties`와 `required` 섹션을 교체하십시오: + +=== "수정 후" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "수정 전" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +주요 변경 사항: + +- **`description`**: "greetings file"을 언급하도록 업데이트 +- **`properties`**: `sample`, `fastq_1`, `fastq_2`를 `greeting`, `language`, `score`로 교체 + - **`type:`** string (`greeting`, `language`) 또는 integer (`score`) 적용 + - **`pattern: "^\\S.*$"`**: 인사말은 공백이 아닌 문자로 시작해야 함 (하지만 그 이후에는 공백을 포함할 수 있음) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: 언어 코드는 지원되는 세트에 있어야 함 + - **`"minimum": 0` 및 `"maximum": 100`**: 점수 값은 0에서 100 사이여야 함 + - **`errorMessage`**: 검증이 실패하면 표시되는 사용자 지정 오류 메시지 +- **`required`**: `["sample", "fastq_1"]`에서 `["greeting"]`으로 변경 + +### 2.4. greetings.csv 파일에 헤더 추가 + +nf-schema가 CSV 파일을 읽을 때, 스키마의 필드 이름과 일치하는 컬럼 헤더가 첫 번째 행에 있어야 합니다. + +우리의 간단한 경우, 인사말 파일에 헤더 라인을 추가해야 합니다: + +=== "수정 후" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "수정 전" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +이제 CSV 파일에 스키마의 필드 이름과 일치하는 헤더 라인이 있습니다. + +마지막 단계는 `samplesheetToList`를 사용하여 파이프라인 코드에서 검증을 구현하는 것입니다. + +### 2.5. 파이프라인에서 검증 구현 + +이제 간단한 CSV 파싱을 nf-schema의 `samplesheetToList` 함수로 교체해야 합니다. 이 함수는 samplesheet를 검증하고 파싱합니다. + +`samplesheetToList` 함수는: + +1. 입력 샘플 시트를 읽음 (CSV, TSV, JSON, 또는 YAML) +2. 제공된 JSON 스키마에 대해 검증 +3. 각 항목이 행에 해당하는 Groovy 리스트를 반환 +4. 검증이 실패하면 도움이 되는 오류 메시지를 발생시킴 + +입력 처리 코드를 업데이트해 보겠습니다: + +`subworkflows/local/utils_nfcore_hello_pipeline/main.nf`를 열고 입력 channel을 생성하는 섹션을 찾으십시오(80줄 근처). + +다음을 수행해야 합니다: + +1. `samplesheetToList` 함수 사용 (템플릿에 이미 import됨) +2. 입력 검증 및 파싱 +3. workflow를 위해 인사말 문자열만 추출 + +먼저 `samplesheetToList` 함수가 파일 상단에 이미 import되어 있음을 확인하십시오 (nf-core 템플릿에 기본적으로 포함됨): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// core/hello 파이프라인 전용 기능을 가진 서브워크플로우 +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +이제 channel 생성 코드를 업데이트하십시오: + +=== "수정 후" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // params.input을 통해 제공된 입력 파일에서 채널 생성 + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "수정 전" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // params.input을 통해 제공된 입력 파일에서 채널 생성 + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +변경된 내용을 분석해 보겠습니다: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: 스키마에 대해 입력 파일을 검증하고 리스트를 반환 +2. **`Channel.fromList(...)`**: 리스트를 Nextflow channel로 변환 + +이것으로 `samplesheetToList`와 JSON 스키마를 사용한 입력 데이터 검증의 구현이 완료됩니다. + +이제 입력 데이터 스키마를 구성했으므로, 앞서 추가한 임시 무시 설정을 제거할 수 있습니다. + +### 2.6. 입력 검증 재활성화 + +`nextflow.config`를 열고 `validation` 블록에서 `ignoreParams` 라인을 제거하십시오: + +=== "수정 후" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "수정 전" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +이제 nf-schema는 매개변수 타입과 입력 파일 내용을 모두 검증할 것입니다. + +### 2.7. 입력 검증 테스트 + +유효한 입력과 유효하지 않은 입력을 모두 테스트하여 검증이 작동하는지 확인해 보겠습니다. + +#### 2.7.1. 유효한 입력으로 테스트 + +먼저 유효한 입력으로 파이프라인이 성공적으로 실행되는지 확인하십시오. +검증이 작동하므로 더 이상 `--validate_params false`가 필요하지 않습니다! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "명령 출력" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +훌륭합니다! 파이프라인이 성공적으로 실행되고 검증이 조용히 통과합니다. +`--character`에 대한 경고는 스키마에 정의되지 않았기 때문에 정보 제공용입니다. +원한다면 배운 것을 사용하여 해당 매개변수에 대한 검증도 추가할 수 있습니다! + +#### 2.7.2. 유효하지 않은 입력으로 테스트 + +검증 통과는 항상 기분 좋지만, 검증이 실제로 오류를 잡아내는지 확인해 보겠습니다. + +유효하지 않은 컬럼 이름을 가진 테스트 파일을 만들기 위해 먼저 `greetings.csv` 파일의 복사본을 만드십시오: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +이제 파일을 열고 헤더 라인에서 첫 번째 컬럼의 이름을 `greeting`에서 `message`로 변경하십시오: + +=== "수정 후" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "수정 전" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +이것은 스키마와 일치하지 않으므로 검증에서 오류를 발생시켜야 합니다. + +이 유효하지 않은 입력으로 파이프라인을 실행해 보십시오: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +완벽합니다! 검증이 오류를 잡아내고 다음을 가리키는 명확하고 도움이 되는 오류 메시지를 제공했습니다: + +- 어떤 파일의 검증이 실패했는지 +- 어떤 항목(첫 번째 데이터 행인 row 1)에 문제가 있는지 +- 구체적인 문제가 무엇인지 (필수 필드 `greeting` 누락) + +스키마 검증은 파이프라인이 실행되기 전에 입력 파일이 올바른 구조를 가지고 있는지 확인하여 시간을 절약하고 나중에 실행 중 혼란스러운 오류를 방지합니다. + +연습하고 싶다면 스키마를 다른 재미있는 방식으로 위반하는 다른 인사말 입력 파일을 자유롭게 만들어 보십시오. + +### 정리 + +매개변수 검증과 입력 데이터 검증을 모두 구현하고 테스트했습니다. 파이프라인이 이제 실행 전에 입력을 검증하여 빠른 피드백과 명확한 오류 메시지를 제공합니다. + +!!! tip "추가 읽을거리" + + 고급 검증 기능과 패턴에 대해 자세히 알아보려면 [nf-schema 문서](https://nextflow-io.github.io/nf-schema/latest/)를 확인하십시오. `nf-core pipelines schema build` 명령은 복잡한 스키마를 관리하기 위한 대화형 GUI를 제공합니다. + +### 다음 단계는? + +Hello nf-core 교육 과정의 다섯 개 파트를 모두 완료했습니다! + +[Summary](summary.md)로 계속 진행하여 구축하고 배운 내용을 돌아보십시오. diff --git a/docs/ko/docs/hello_nf-core/index.md b/docs/ko/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..9db3a08bd4 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - nf-core 파이프라인의 실행을 검색하고, 시작하고, 관리합니다 + - nf-core 파이프라인의 코드 구조와 프로젝트 구성을 설명합니다 + - 템플릿에서 기본 nf-core 호환 파이프라인을 생성합니다 + - 일반 Nextflow 워크플로우를 nf-core 표준에 맞게 업그레이드합니다 + - nf-core 호환 파이프라인에 nf-core 모듈을 추가합니다 + - 자신의 모듈을 nf-core에 기여합니다 + - nf-core 도구를 사용하여 입력과 매개변수를 검증합니다 + audience_prerequisites: + - "**대상:** 이 과정은 기본 Nextflow에 이미 익숙하며 nf-core 리소스와 모범 사례 사용법을 배우고자 하는 학습자를 위해 설계되었습니다." + - "**기술:** 명령줄, 기본 스크립팅 개념 및 일반적인 파일 형식에 대한 지식이 있다고 가정합니다." + - "**과정:** [Hello Nextflow](../hello_nextflow/index.md) 과정 또는 이에 상응하는 과정을 완료해야 합니다." + - "**영역:** 모든 연습은 영역에 구애받지 않으므로 사전 과학 지식이 필요하지 않습니다." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core는 nf-core 리소스와 모범 사례 사용에 대한 실습 입문 과정입니다.** + +![nf-core logo](./img/nf-core-logo.png) + +실용적인 예제와 안내된 연습을 통해 nf-core 호환 모듈과 파이프라인을 사용하고 개발하는 방법, 그리고 nf-core 도구를 효과적으로 활용하는 방법을 배우게 됩니다. + +nf-core 모범 사례에 따라 파이프라인을 개발할 수 있는 기술과 자신감을 얻게 됩니다. + +<!-- additional_information --> + +## 과정 개요 + +이 과정은 정보를 점진적으로 소개하도록 구성된 목표 지향적 연습과 함께 실습 중심으로 설계되었습니다. + +Nextflow를 사용하여 구축된 과학 파이프라인의 큐레이션된 세트를 개발하고 유지 관리하는 커뮤니티 활동인 [**nf-core**](https://nf-co.re/)와, 개방형 개발, 테스트 및 동료 검토를 촉진하는 관련 도구 및 가이드라인에 대해 소개합니다([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +nf-core 커뮤니티가 개발한 파이프라인은 모듈식이고, 확장 가능하며, 이식 가능하도록 설계되어 연구자들이 자신의 데이터와 컴퓨팅 리소스를 사용하여 쉽게 적응하고 실행할 수 있습니다. +프로젝트에서 시행하는 모범 사례 가이드라인은 파이프라인이 견고하고, 잘 문서화되며, 실제 데이터 세트에 대해 검증되도록 보장합니다. +이는 과학 분석의 신뢰성과 재현성을 높이는 데 도움이 되며, 궁극적으로 연구자들이 과학적 발견을 가속화할 수 있도록 합니다. + +이 과정에서는 nf-core 파이프라인에 대한 모든 것을 다루지는 않습니다. nf-core는 커뮤니티가 수년에 걸쳐 개발한 많은 기능과 규칙을 포함하고 있기 때문입니다. +대신, 시작하는 데 도움이 되고 nf-core가 어떻게 작동하는지 이해하는 데 필요한 필수 개념에 초점을 맞출 것입니다. + +### 수업 계획 + +이 과정은 nf-core 리소스 사용의 특정 측면에 각각 초점을 맞춘 다섯 부분으로 나뉩니다. + +| 과정 챕터 | 요약 | 예상 소요 시간 | +| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [파트 1: 데모 파이프라인 실행](./01_run_demo.md) | 기존 nf-core 파이프라인을 실행하고 코드 구조를 검토하여 이러한 파이프라인이 기본 Nextflow 워크플로우와 무엇이 다른지 파악합니다 | 30분 | +| [파트 2: nf-core용 Hello 재작성](./02_rewrite_hello.md) | [Hello Nextflow](../hello_nextflow/index.md) 과정에서 생성한 간단한 워크플로우를 nf-core 템플릿 스캐폴드에 맞게 적응시킵니다 | 60분 | +| [파트 3: nf-core 모듈 사용](./03_use_module.md) | 커뮤니티 모듈 라이브러리를 탐색하고 일반적인 생물정보학 도구를 적용하는 사전 구축되고 테스트된 모듈을 통합하는 방법을 배웁니다 | 30분 | +| [파트 4: nf-core 모듈 만들기](./04_make_module.md) | nf-core가 정한 특정 구조, 명명 규칙 및 메타데이터 요구사항을 사용하여 자신만의 nf-core 스타일 모듈을 생성합니다 | 30분 | +| [파트 5: 입력 검증 추가](./05_input_validation.md) | nf-schema를 사용하여 명령줄 매개변수와 입력 데이터 파일 모두에 대한 입력 검증을 구현합니다 | 30분 | + +이 과정을 마치면 nf-core 프로젝트가 제공하는 방대한 리소스를 활용할 수 있게 됩니다. + +과정을 시작할 준비가 되셨습니까? + +[학습 시작 :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/ko/docs/hello_nf-core/next_steps.md b/docs/ko/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..4cef4b751d --- /dev/null +++ b/docs/ko/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# 교육 과정 요약 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core 교육 과정을 완료하신 것을 축하드립니다! 🎉 + +<!-- placeholder for video --> + +## 학습 여정 + +데모 pipeline을 가져와서 실행하는 방법을 배우는 것으로 시작하여, 간단한 Nextflow workflow를 nf-core pipeline으로 변환하는 작업을 수행하셨습니다. +template을 사용하여 pipeline scaffold를 생성하는 방법을 배우고 기존 pipeline을 해당 scaffold에 접목시켰습니다. +그런 다음 local module 중 하나를 nf-core module로 교체하고, 다른 local module을 nf-core 표준에 맞게 변환하며, 입력 검증을 추가하여 pipeline을 점진적으로 개선하셨습니다. + +### 구축한 결과물 + +최종 `core-hello` pipeline은 다음을 갖추고 있습니다: + +- **표준화된 구조**: nf-core template을 사용하여 workflow, subworkflow, module 및 구성을 위한 체계적인 디렉토리 구조 +- **커뮤니티 module**: nf-core 저장소의 module(`cat/cat`)과 함께 사용자 정의 module +- **포괄적인 검증**: pipeline 실행 전에 매개변수와 입력 데이터를 모두 확인 +- **전문적인 구성**: 다양한 실행 환경을 위한 프로파일 +- **완전한 문서화**: nf-core 규칙을 따르는 메타데이터 + +### 습득한 핵심 기술 + +이 실습 교육 과정을 통해 다음을 배우셨습니다: + +1. 기존 pipeline을 탐색하여 nf-core pipeline 구조를 **탐색하고 이해하기** +2. nf-core template 내에서 조합 가능하도록 workflow를 **재구성하기** +3. 커뮤니티 저장소에서 사전 구축된 module을 **찾아서 통합하기** +4. 명명, 구조 및 메타데이터에 대한 nf-core 표준을 따라 **사용자 정의 module 생성하기** +5. nf-schema를 사용하여 명확한 피드백으로 오류를 조기에 발견하는 **검증 구현하기** + +이제 커뮤니티 모범 사례를 따르는 프로덕션 준비가 된 nf-core pipeline을 구축하기 위한 기초 지식을 갖추셨습니다. + +## 기술 향상을 위한 다음 단계 + +다음 단계로 추천하는 상위 3가지 사항입니다: + +- [Nextflow for Science](../nf4_science/index.md)를 통해 과학적 분석 사용 사례에 Nextflow 적용하기 +- [Side Quests](../side_quests/index.md)를 통해 더 고급 Nextflow 기능 탐색하기 +- [nf-core 커뮤니티 참여](https://nf-co.re/join)를 통해 참여하기 + +마지막으로, Nextflow 제작자들이 개발한 클라우드 기반 플랫폼인 [**Seqera Platform**](https://seqera.io/)을 살펴보시길 권장합니다. 이 플랫폼을 사용하면 workflow를 더 쉽게 시작하고 관리할 수 있으며, 데이터를 관리하고 모든 환경에서 대화형으로 분석을 실행할 수 있습니다. + +## 피드백 설문조사 + +다음 단계로 넘어가기 전에, 교육 과정 설문조사를 작성하는 데 1분만 투자해 주십시오! 여러분의 피드백은 모두를 위한 교육 자료를 개선하는 데 도움이 됩니다. + +[설문조사 참여하기 :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/ko/docs/hello_nf-core/survey.md b/docs/ko/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..47bf19ffb9 --- /dev/null +++ b/docs/ko/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# 피드백 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +다음 단계로 넘어가기 전에, 이 짧은 5개 질문 설문조사를 완료하여 교육을 평가하고, 경험에 대한 피드백을 공유하며, Nextflow 여정에서 도움이 될 수 있는 다른 방법을 알려주시기 바랍니다. + +완료하는 데 1분도 걸리지 않습니다. 모두를 위한 교육 자료 개선에 도움을 주셔서 감사합니다! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/ko/docs/help.md b/docs/ko/docs/help.md new file mode 100644 index 0000000000..cd23eb3d90 --- /dev/null +++ b/docs/ko/docs/help.md @@ -0,0 +1,77 @@ +--- +title: 도움말 +description: Nextflow 교육에 문제가 있을 때 유용한 리소스 +hide: + - toc + - footer +--- + +# 도움말 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +시작하는 데 어려움이 있거나, 진행 중에 막히거나, 후속 질문이 있더라도 언제든지 연락해 주세요! 저희 커뮤니티 팀이 도움을 드릴 준비가 되어 있으며, Nextflow 커뮤니티 전체가 매우 활발하고 포용적이며 기꺼이 도움을 드립니다. + +찾고 계신 내용에 따라 사용할 수 있는 주요 옵션은 다음과 같습니다. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __커뮤니티 포럼__ + + --- + + 커뮤니티 포럼에는 교육 전용 카테고리가 있어 질문을 게시하거나 교육과 관련하여 겪고 있는 문제를 보고하기에 좋은 장소입니다. 이미 질문이 올라와 있고 답변이 되어 있을 수도 있습니다! + + [교육 포럼 참여하기:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Slack 채널__ + + --- + + Slack을 사용하신다면 Nextflow Slack 워크스페이스의 교육 채널에서 연락해 주세요. Nextflow Slack은 동료 개발자들과 대화하고 Nextflow 커뮤니티 전반과 교류하기에 좋은 장소입니다. + + [Nextflow Slack 참여하기 :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __GitHub 이슈__ + + --- + + 교육 자료에서 오류를 발견하면 Github 저장소에 이슈를 열어 보고해 주세요. 오타, 형식 문제 또는 코드에 영향을 미치는 실제 버그 등 무엇이든 알려주시면 수정하겠습니다! PR도 직접 환영합니다. + + [이슈 보고하기:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Seqera AI 어시스턴트__ + + --- + + Seqera AI는 Nextflow 및 nf-core 리소스에 대해 훈련된 AI 어시스턴트입니다. 코드 디버깅, Nextflow 개념 설명, 문서 검색을 더 빠르게 도와줄 수 있습니다. 과정을 진행하는 동안 24시간 연중무휴로 이용할 수 있는 튜터라고 생각하시면 됩니다. + + [Seqera AI에게 질문하기:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Nextflow 문서__ + + --- + + 공식 문서는 모든 언어 기능과 구성 옵션에 대한 최종 가이드입니다. 특정 주제를 더 깊이 파고들고, 고급 기능을 탐색하고, 자세한 구문 참조를 찾기 위해 이 교육과 함께 사용하십시오. + + [문서 둘러보기:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __전문 지원__ + + --- + + Nextflow는 스페인에 본사를 두고 영국과 미국에 위성 사무소가 있는 회사인 [Seqera](https://seqera.io/)에서 개발한 무료 오픈 소스 소프트웨어입니다. 맞춤형 교육을 포함한 Nextflow 전문 지원 서비스를 제공합니다. + + [연락하기:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/ko/docs/index.md b/docs/ko/docs/index.md new file mode 100644 index 0000000000..a6ece0b403 --- /dev/null +++ b/docs/ko/docs/index.md @@ -0,0 +1,174 @@ +--- +title: 홈 +description: Nextflow 커뮤니티 교육 포털에 오신 것을 환영합니다! +hide: + - toc + - footer +--- + +# Nextflow 교육 + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __셀프 서비스 과정__ + + --- + + **Nextflow 커뮤니티 교육 포털에 오신 것을 환영합니다!** + + 아래 나열된 교육 과정은 셀프 서비스 리소스로 사용할 수 있도록 설계되었습니다. + Github Codespaces를 통해 제공되는 웹 기반 환경이나 자체 환경에서 언제든지 원하는 시간에 학습할 수 있습니다. + + [과정 둘러보기 :material-arrow-right:](#nextflow-교육-과정-목록){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __추가 정보__ + + --- + + ??? warning "버전 호환성" + + <!-- Any update to this content needs to be copied to the local installation page --> + **2026년 1월 기준, 별도의 언급이 없는 한 모든 Nextflow 교육 과정은 strict 구문이 활성화된 Nextflow 버전 25.10.2 이상을 필요로 합니다.** + + 버전 요구 사항 및 strict 구문에 대한 자세한 내용은 [Nextflow 문서 마이그레이션 가이드](https://nextflow.io/docs/latest/strict-syntax.html)를 참조하십시오. + + 이전 구문에 해당하는 이전 버전의 교육 자료는 이 웹페이지 메뉴 바의 버전 선택기를 통해 사용할 수 있습니다. + + ??? terminal "환경 옵션" + + 교육에 필요한 모든 것이 사전 설치된 웹 기반 교육 환경을 Github Codespaces를 통해 제공합니다(무료 GitHub 계정 필요). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + 이 옵션이 적합하지 않은 경우 다른 [환경 옵션](./envsetup/index.md)을 참조하십시오. + + ??? learning "교육 이벤트" + + 구조화된 이벤트의 일부로 Nextflow 교육을 받고 싶다면 다양한 기회가 있습니다. 다음 옵션을 확인해 보시기 바랍니다: + + - **[Training Weeks]()** - 커뮤니티 팀이 분기별로 개최 + - **[Seqera 이벤트](https://seqera.io/events/)** - Seqera가 주최하는 대면 교육 이벤트 포함('Seqera Sessions' 및 'Nextflow Summit' 검색) + - **[Nextflow 앰배서더]()** - 지역 커뮤니티를 위한 이벤트 개최 + - **[nf-core 이벤트](https://nf-co.re/events)** - 커뮤니티 해커톤 포함 + + ??? people "강사를 위한 정보" + + 자체 교육을 진행하는 강사라면 적절한 출처를 표시하는 한 교육 포털에서 직접 자료를 사용하실 수 있습니다. 자세한 내용은 아래 '크레딧 및 기여'를 참조하십시오. + + 또한, 교육 노력을 더 잘 지원할 수 있는 방법에 대해 의견을 듣고 싶습니다! [community@seqera.io](mailto:community@seqera.io)로 연락하시거나 커뮤니티 포럼을 이용해 주십시오([도움말](help.md) 페이지 참조). + + ??? licensing "오픈 소스 라이선스 및 기여 정책" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + 이 교육 자료는 [Seqera](https://seqera.io)에서 개발 및 유지 관리하며 커뮤니티의 이익을 위해 오픈 소스 라이선스([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/))로 공개됩니다. 라이선스 범위를 벗어나는 방식으로 이 자료를 사용하고자 하는 경우(상업적 사용 및 재배포에 대한 제한 사항 참고) [community@seqera.io](mailto:community@seqera.io)로 연락하여 요청 사항을 논의해 주십시오. + + 커뮤니티의 개선, 수정 및 버그 리포트를 환영합니다. 모든 페이지 오른쪽 상단에 있는 :material-file-edit-outline: 아이콘을 클릭하면 코드 저장소로 연결되며, 여기서 문제를 보고하거나 pull request를 통해 교육 소스 자료에 대한 변경을 제안할 수 있습니다. 자세한 내용은 저장소의 `README.md`를 참조하십시오. + +</div> + +!!! note "AI 지원 번역" + + 이 번역은 인공지능을 사용하여 생성되었으며 인간 번역가가 검토했습니다. + 피드백과 개선 제안을 환영합니다. + 자세한 내용은 [번역 가이드](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)를 참조하세요. + +## Nextflow 교육 과정 목록 + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __입문 트랙__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow 입문자를 위한 과정 {.mt-1} + + Nextflow를 처음 접하는 분들을 위한 도메인에 구애받지 않는 과정입니다. 각 과정은 학습자가 점진적으로 기술을 쌓을 수 있도록 설계된 일련의 교육 모듈로 구성되어 있습니다. + + ??? courses "**Hello Nextflow:** 자신만의 파이프라인 개발 배우기" + + 이 과정은 간단하지만 완전히 기능하는 파이프라인을 개발할 수 있을 정도로 Nextflow 언어의 핵심 구성 요소와 파이프라인 설계, 개발 및 구성 방법의 핵심 요소를 다룹니다. + + [Hello Nextflow 교육 시작하기 :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** 기존 파이프라인 실행 방법 배우기" + + Nextflow 파이프라인을 실행하고 구성하는 방법에 대한 간결한 소개로, Hello Nextflow 개발자 과정을 기반으로 하지만 코드에 대한 집중도가 낮습니다. 실행, 출력, 기본 코드 구조 및 다양한 컴퓨팅 환경에 대한 구성을 다룹니다. + + [Nextflow Run 교육 시작하기 :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} 과학을 위한 Nextflow {.mt-1} + + 'Hello Nextflow'에서 제시된 개념과 구성 요소를 특정 과학적 사용 사례에 적용하는 방법을 배웁니다. + + ??? courses "**유전체학을 위한 Nextflow** (변이 호출)" + + 자체 유전체학 파이프라인을 개발하고자 하는 연구자를 위한 과정입니다. 변이 호출 사용 사례를 통해 간단하지만 기능적인 유전체학 파이프라인을 개발하는 방법을 시연합니다. + + [유전체학을 위한 Nextflow 교육 시작하기 :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**RNAseq를 위한 Nextflow** (벌크 RNAseq)" + + 자체 RNAseq 파이프라인을 개발하고자 하는 연구자를 위한 과정입니다. 벌크 RNAseq 처리 사용 사례를 통해 간단하지만 기능적인 RNAseq 파이프라인을 개발하는 방법을 시연합니다. + + [RNAseq를 위한 Nextflow 교육 시작하기 :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**이미징을 위한 Nextflow** (공간 오믹스)" + + 이미징 및 공간 오믹스 연구자로서 분석 파이프라인을 실행하고 사용자 정의하는 방법을 배우고자 하는 분들을 위한 과정입니다. nf-core/molkart 파이프라인을 사용하여 생물학적으로 관련된 파이프라인을 제공하고 Nextflow 파이프라인 워크플로우를 실행, 구성 및 입력 관리하는 방법을 시연합니다. + + [이미징을 위한 Nextflow 교육 시작하기 :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __고급 트랙__ + + --- + + ### :material-bridge:{.nextflow-primary} Nextflow에서 nf-core로 {.mt-1} + + [nf-core](https://nf-co.re/) 커뮤니티 프로젝트의 코드와 모범 사례를 활용하는 방법을 배웁니다. + + 이 과정들은 Nextflow 기초에서 nf-core 모범 사례로 나아가는 데 도움이 됩니다. + nf-core 커뮤니티가 파이프라인을 구축하는 방법과 이유를 이해하고, 이러한 기술을 어떻게 기여하고 재사용할 수 있는지 배웁니다. + + ??? courses "**Hello nf-core:** nf-core 시작하기" + + [nf-core](https://nf-co.re/) 규격에 맞는 파이프라인을 실행하고 개발하고자 하는 개발자를 위한 과정입니다. nf-core 파이프라인의 구조를 충분히 자세히 다루어 nf-core 템플릿과 개발 모범 사례를 따르는 간단하지만 완전히 기능하는 파이프라인을 개발하고 기존 nf-core 모듈을 사용할 수 있도록 합니다. + + [Hello nf-core 교육 시작하기 :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} 고급 Nextflow 교육 {.mt-1} + + 실제 사용 사례를 해결하기 위한 Nextflow 파이프라인 개발 및 배포에 대한 고급 개념과 메커니즘을 배웁니다. + + ??? courses "**Side Quests:** 독립 주제에 대한 심층 탐구" + + 특정 주제에 대한 범위를 넓히거나 기술을 심화하고자 하는 Nextflow 개발자를 위한 단독형 단기 과정입니다. 순차적으로 제시되지만 어떤 순서로든 수강할 수 있습니다(각 단기 과정 개요에서 의존성 참조). + + [Side Quests 둘러보기 :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Training Collections:** Side Quests를 통한 권장 학습 경로" + + Training Collections는 특정 주제나 사용 사례에 대한 포괄적인 학습 경험을 제공하기 위해 여러 Side Quests를 결합합니다. + + [Training Collections 둘러보기 :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "보관된 교육 자료를 찾고 계신가요?" + + 이전 교육 자료(Fundamentals Training, Advanced Training 및 기타 실험적 과정)는 Nextflow 3.0 strict 구문과 호환되지 않아 교육 포털에서 제거되었습니다. + 이러한 자료가 필요한 경우 2026년 1월 이전의 [git 기록](https://github.com/nextflow-io/training)에서 확인할 수 있습니다. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/ko/docs/info/conventions.md b/docs/ko/docs/info/conventions.md new file mode 100644 index 0000000000..45863a6ded --- /dev/null +++ b/docs/ko/docs/info/conventions.md @@ -0,0 +1 @@ +모든 채널 변수에 `ch_` 접두사를 사용하여 Nextflow channel임을 명확히 표시합니다. diff --git a/docs/ko/docs/info/hello_pipeline.md b/docs/ko/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..b9fa2325bb --- /dev/null +++ b/docs/ko/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Hello pipeline +description: Hello pipeline이 무엇을 하고 어떻게 구성되어 있는지에 대한 요약. +hide: + - toc + - footer +--- + +# Hello pipeline + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +대부분의 교육 과정에서는 Nextflow 개념과 메커니즘을 시연하기 위해 간단한 도메인 비의존적 pipeline을 사용합니다. +Hello Nextflow 과정에서는 모든 설계 및 구현 결정을 설명하면서 이 pipeline을 단계별로 개발하는 방법을 보여줍니다. +다른 교육에서는 이 pipeline 또는 그 일부를 시작점으로 사용합니다. + +이 페이지는 Hello Nextflow 과정 완료 시점의 pipeline 상태를 요약합니다. + +### 요약 설명 + +Hello workflow는 인사말이 포함된 CSV 파일을 받아 별도의 파일에 작성하고, 각각을 대문자로 변환하고, 다시 모아서 인사말을 말하는 재미있는 캐릭터의 ASCII 그림이 포함된 단일 텍스트 파일을 출력합니다. + +### Workflow 단계 (process) + +네 단계는 별도의 모듈 파일에 저장된 Nextflow process(`sayHello`, `convertToUpper`, `collectGreetings`, `cowpy`)로 구현됩니다. + +1. **`sayHello`:** 각 인사말을 자체 출력 파일에 작성합니다 (예: "Hello-output.txt") +2. **`convertToUpper`:** 각 인사말을 대문자로 변환합니다 (예: "HELLO") +3. **`collectGreetings`:** 모든 대문자 인사말을 단일 배치 파일로 수집합니다 +4. **`cowpy`:** `cowpy` 도구를 사용하여 ASCII 아트를 생성합니다 + +### 다이어그램 + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### 결과 + +결과는 `results/`라는 디렉토리에 게시되며, pipeline의 최종 출력(기본 매개변수로 실행 시)은 대문자 인사말을 말하는 칠면조의 ASCII 아트가 포함된 일반 텍스트 파일입니다. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +pipeline이 포함된 과정에 따라 세부 사항에서 약간의 차이가 있을 수 있습니다. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/ko/docs/info/nxf_versions.md b/docs/ko/docs/info/nxf_versions.md new file mode 100644 index 0000000000..432f28fa95 --- /dev/null +++ b/docs/ko/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Nextflow 버전 +description: Nextflow 문법 버전의 발전을 이해하고 관리하기 +hide: + - toc + - footer +--- + +## 현재 지원되는 Nextflow 문법 버전 및 요구 사항 + +교육 포털 버전 3.0부터 모든 교육 과정은 과정 인덱스 페이지에 별도로 명시되지 않는 한 Nextflow 25.10.2 버전 릴리스를 기반으로 합니다(버전 공지가 포함되지 않을 수 있는 더 이상 사용되지 않거나 보관된 자료 제외). + +과정에서 이제 workflow 수준의 typed inputs과 workflow 수준 output directives를 사용하기 때문에 V2 syntax parser를 사용해야 합니다. +[Github Codespaces](../envsetup/01_setup.md) 또는 [로컬 devcontainer](../envsetup/03_devcontainer.md)를 통해 제공하는 환경을 사용할 계획이라면 과정 지침에 특별히 명시되지 않는 한 별도의 작업이 필요하지 않습니다. +그러나 자체 환경에서 교육을 진행할 계획이라면([수동 설치](../envsetup/02_local.md)), v2 syntax parser가 활성화된 Nextflow 버전 25.10.2 이상을 사용해야 합니다. + +## 교육 자료의 이전 버전 + +교육 자료는 2025년 2월부터 버전 관리되고 있습니다. + +모든 페이지 상단의 드롭다운 메뉴 항목을 통해 교육 자료의 번호가 매겨진 버전을 확인하고 **25.10.2 이전** Nextflow 버전에서 작동하는 이전 버전의 교육 자료에 접근할 수 있습니다. +이전 버전의 교육 자료를 선택하면 교육 환경 링크가 자동으로 해당 환경 버전을 지정합니다. + +## Nextflow 문법 버전에 대한 기타 정보 + +Nextflow에는 때때로 혼동되는 두 가지 별개의 버전 관리 개념이 있습니다: **DSL 버전**과 **syntax parser 버전**. + +**DSL1 대 DSL2**는 Nextflow pipeline을 작성하는 근본적으로 다른 방식을 나타냅니다. +DSL1은 process가 channel을 통해 암묵적으로 연결되는 원래 문법이었습니다. +Nextflow 20.07에 도입된 DSL2는 모듈성 기능을 추가했습니다: 다른 파일에서 process와 workflow를 가져오는 기능, 명시적인 `workflow` 블록, 명명된 process outputs. +DSL1은 Nextflow 22.03에서 더 이상 사용되지 않게 되었고 22.12에서 제거되었습니다. +모든 현대적인 Nextflow 코드는 DSL2를 사용합니다. + +**Syntax parser v1 대 v2**는 둘 다 DSL2 코드와 함께 작동하는 서로 다른 parser를 나타냅니다. +v1 parser는 원래의 더 관대한 parser입니다. +v2 parser는 더 엄격하며 static typing(typed inputs 및 outputs)과 workflow 수준 output directives 같은 새로운 언어 기능을 활성화합니다. +v2 parser는 또한 더 나은 오류 메시지를 제공하고 런타임이 아닌 파싱 시점에 더 많은 오류를 잡아냅니다. +v2 parser는 Nextflow 26.04에서 기본값이 됩니다. + +요약하면: DSL2는 작성하는 언어이고, syntax parser 버전은 해당 언어가 얼마나 엄격하게 해석되는지와 어떤 고급 기능을 사용할 수 있는지를 결정합니다. + +### Nextflow 버전 확인 및 설정 + +`nextflow --version` 명령을 사용하여 시스템에 설치된 Nextflow 버전을 확인할 수 있습니다. + +Nextflow 버전 업데이트 방법에 대한 자세한 내용은 [Nextflow 업데이트](https://www.nextflow.io/docs/latest/updating-nextflow.html)에 대한 참조 문서를 확인하십시오. + +### v2 syntax parser 활성화 + +현재 세션에서 v2 syntax parser를 **활성화**하려면 터미널에서 다음 명령을 실행하십시오: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +이를 영구적으로 만들려면(Nextflow 26.04에서 v2가 기본값이 될 때까지), export 명령을 shell 프로필(`~/.bashrc`, `~/.zshrc` 등)에 추가하십시오: + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +`NXF_SYNTAX_PARSER=v2` 환경 변수는 임시 요구 사항입니다. +Nextflow 26.04부터 v2 parser가 기본값이 되며 이 설정은 더 이상 필요하지 않습니다. + +### v2 syntax parser 비활성화 + +현재 세션에서 v2 syntax parser를 **비활성화**하려면 터미널에서 다음 명령을 실행하십시오: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### 기존 코드 마이그레이션 + +최신 Nextflow 버전에 맞게 기존 코드를 마이그레이션하는 방법에 대한 안내는 참조 문서의 [마이그레이션 노트](https://www.nextflow.io/docs/latest/migrations/index.html)를 참조하십시오. + +다음 두 문서는 최신 릴리스로 마이그레이션하는 데 특히 유용합니다: + +- [workflow outputs로 마이그레이션](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [static types로 마이그레이션](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +이 두 기능은 교육 자료 버전 3.0부터 시작하는 초급 교육의 일부로 다룹니다. + +마이그레이션하려는 Nextflow 코드의 세대에 따라 `nextflow lint -format` 명령을 사용하여 Nextflow linter로 대부분의 작업을 완료할 수 있습니다. +자세한 내용은 [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint)에 대한 CLI 참조를 확인하십시오. + +이것이 도움이 되기를 바랍니다. +도움이 필요하시면 Slack이나 포럼에서 연락해 주십시오. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/ko/docs/nextflow_run/00_orientation.md b/docs/ko/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..22fb580177 --- /dev/null +++ b/docs/ko/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# 시작하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## 교육 환경 시작 + +GitHub Codespaces에서 제공하는 사전 구축 환경을 사용하려면 아래의 "Open in GitHub Codespaces" 버튼을 클릭하세요. 다른 옵션은 [환경 옵션](../envsetup/index.md)을 참조하세요. + +환경이 로드되는 동안 계속 읽을 수 있도록 새 브라우저 탭이나 창에서 교육 환경을 여는 것을 권장합니다(장비에 따라 마우스 오른쪽 클릭, ctrl-클릭 또는 cmd-클릭 사용). +과정을 진행하는 동안 이 지침을 병렬로 열어 두어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### 환경 기본 사항 + +이 교육 환경에는 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 직접 설치할 필요가 없습니다. + +codespace는 파일 시스템 탐색기, 코드 편집기 및 터미널 셸을 포함하는 VSCode 인터페이스로 설정됩니다. +과정 중에 제공되는 모든 지침(예: '파일 열기', '코드 편집' 또는 '이 명령 실행')은 별도로 지정하지 않는 한 VSCode 인터페이스의 세 부분을 참조합니다. + +이 과정을 혼자 진행하는 경우 자세한 내용은 [환경 기본 사항](../envsetup/01_setup.md)을 참조하세요. + +### 버전 요구 사항 + +이 교육은 Nextflow 25.10.2 이상에서 **v2 구문 파서가 활성화된 상태**로 설계되었습니다. +로컬 또는 사용자 정의 환경을 사용하는 경우 [여기](../info/nxf_versions.md)에 설명된 대로 올바른 설정을 사용하고 있는지 확인하세요. + +## 작업 준비 + +codespace가 실행되면 교육에 들어가기 전에 두 가지를 수행해야 합니다: 이 특정 과정의 작업 디렉토리를 설정하고 제공된 자료를 살펴봅니다. + +### 작업 디렉토리 설정 + +기본적으로 codespace는 모든 교육 과정의 루트로 작업 디렉토리가 설정된 상태로 열리지만, 이 과정에서는 `nextflow-run/` 디렉토리에서 작업합니다. + +터미널에서 다음 명령을 실행하여 지금 디렉토리를 변경하세요: + +```bash +cd nextflow-run/ +``` + +VSCode가 이 디렉토리에 집중하도록 설정하여 파일 탐색기 사이드바에 관련 파일만 표시되도록 할 수 있습니다: + +```bash +code . +``` + +!!! tip + + 어떤 이유로든 이 디렉토리를 벗어난 경우(예: codespace가 절전 상태가 됨), Github Codespaces 교육 환경 내에서 실행하고 있다고 가정하면 항상 전체 경로를 사용하여 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +이제 내용을 살펴보겠습니다. + +### 제공된 자료 탐색 + +교육 작업 공간 왼쪽의 파일 탐색기를 사용하여 이 디렉토리의 내용을 탐색할 수 있습니다. +또는 `tree` 명령을 사용할 수 있습니다. + +과정 전체에서 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간의 수정을 합니다. + +여기서는 두 번째 레벨까지의 목차를 생성합니다: + +```bash +tree . -L 2 +``` + +??? abstract "디렉토리 내용" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +색상 상자를 클릭하여 섹션을 확장하고 내용을 볼 수 있습니다. +이와 같은 접을 수 있는 섹션을 사용하여 예상 명령 출력과 디렉토리 및 파일 내용을 간결하게 표시합니다. + +- **`.nf` 파일**은 과정의 어느 부분에서 사용되는지에 따라 번호가 매겨진 workflow 스크립트입니다. + +- **`nextflow.config` 파일**은 최소한의 환경 속성을 설정하는 구성 파일입니다. + 지금은 무시해도 됩니다. + +- **`data/` 아래의 `greetings.csv` 파일**에는 과정의 대부분에서 사용할 입력 데이터가 포함되어 있습니다. Part 2(Pipeline 실행)에서 처음 소개할 때 설명됩니다. + +- **`test-params.*` 파일**은 Part 3(구성)에서 사용할 구성 파일입니다. 지금은 무시해도 됩니다. + +- **`solutions` 디렉토리**에는 과정을 완료하면 생성되는 workflow의 최종 상태와 그 부속 파일(config 및 modules)이 포함되어 있습니다. + 작업을 확인하고 문제를 해결하기 위한 참조용으로 사용됩니다. + +## 준비 점검 목록 + +시작할 준비가 되었다고 생각하시나요? + +- [ ] 이 과정의 목표와 선수 조건을 이해합니다 +- [ ] 환경이 가동되어 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 + +모든 항목을 체크할 수 있다면 준비가 완료된 것입니다. + +**[Part 1: 기본 작업 실행](./01_basics.md)으로 계속하려면 이 페이지 오른쪽 하단의 화살표를 클릭하세요.** diff --git a/docs/ko/docs/nextflow_run/01_basics.md b/docs/ko/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..3fab5487ca --- /dev/null +++ b/docs/ko/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# 파트 1: 기본 작업 실행 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run 교육 과정의 첫 번째 파트에서는 매우 기본적인 도메인에 구애받지 않는 Hello World 예제로 주제를 시작하며, 이를 사용하여 필수 작업을 시연하고 해당 Nextflow 코드 구성 요소를 설명합니다. + +??? info "Hello World 예제란 무엇인가요?" + + "Hello World!"는 프로그래밍 언어나 소프트웨어 프레임워크의 기본 구문과 구조를 보여주기 위한 최소한의 예제입니다. + 일반적으로 "Hello, World!"라는 문구를 콘솔이나 터미널과 같은 출력 장치에 출력하거나 파일에 쓰는 것으로 구성됩니다. + +--- + +## 1. Hello World 직접 실행 + +Nextflow로 적용하기 전에 터미널에서 직접 실행하는 간단한 명령으로 이 개념을 시연하여 무엇을 하는지 보여드리겠습니다. + +!!! tip + + [시작하기](00_orientation.md) 페이지에 설명된 대로 지금 `nextflow-run/` 디렉토리 안에 있어야 합니다. + +### 1.1. 터미널에 hello 출력하기 + +터미널에서 다음 명령을 실행하세요. + +```bash +echo 'Hello World!' +``` + +??? success "명령 출력" + + ```console + Hello World! + ``` + +이렇게 하면 터미널에 'Hello World' 텍스트가 바로 출력됩니다. + +### 1.2. 출력을 파일에 쓰기 + +pipeline 실행은 대부분 파일에서 데이터를 읽고 다른 파일에 결과를 쓰는 것을 포함하므로, 예제를 좀 더 관련성 있게 만들기 위해 텍스트 출력을 파일에 쓰도록 명령을 수정해 보겠습니다. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "명령 출력" + + ```console + + ``` + +이것은 터미널에 아무것도 출력하지 않습니다. + +### 1.3. 출력 찾기 + +'Hello World' 텍스트는 이제 지정한 출력 파일인 `output.txt`에 있어야 합니다. +파일 탐색기에서 열거나 예를 들어 `cat` 유틸리티를 사용하여 명령줄에서 열 수 있습니다. + +??? abstract "파일 내용" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +이것이 우리의 첫 번째 Nextflow workflow로 복제하려는 것입니다. + +### 요약 + +이제 텍스트를 출력하는 간단한 명령을 터미널에서 실행하는 방법과 선택적으로 출력을 파일에 쓰는 방법을 알게 되었습니다. + +### 다음 단계 + +동일한 결과를 달성하는 Nextflow workflow를 실행하는 데 무엇이 필요한지 알아봅니다. + +--- + +## 2. Workflow 실행 + +`--input` 명령줄 인수를 통해 입력 인사말을 받아 해당 인사말이 포함된 텍스트 파일을 생성하는 `1-hello.nf`라는 workflow 스크립트를 제공합니다. + +코드를 아직 살펴보지 않겠습니다. 먼저 실행하면 어떻게 되는지 살펴보겠습니다. + +### 2.1. Workflow 시작 및 실행 모니터링 + +터미널에서 다음 명령을 실행하세요: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "명령 출력" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +콘솔 출력이 이와 비슷하다면 축하합니다. 첫 번째 Nextflow workflow를 실행했습니다! + +여기서 가장 중요한 출력은 위 출력에서 강조된 마지막 줄입니다: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +이것은 `sayHello` process가 한 번 성공적으로 실행되었음을 알려줍니다(`1 of 1 ✔`). + +훌륭합니다. 하지만 출력은 어디에 있을까요? + +### 2.2. `results` 디렉토리에서 출력 파일 찾기 + +이 workflow는 출력을 results 디렉토리에 게시하도록 구성되어 있습니다. +현재 디렉토리를 보면 workflow를 실행할 때 Nextflow가 `results`라는 새 디렉토리와 그 아래에 `1-hello`라는 하위 디렉토리를 생성하고 `output.txt`라는 파일을 포함하는 것을 볼 수 있습니다. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +파일을 열어보세요. 내용은 명령줄에서 지정한 문자열과 일치해야 합니다. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +훌륭합니다. workflow가 해야 할 일을 했습니다! + +그러나 '게시된' 결과는 Nextflow가 workflow를 실행할 때 생성한 실제 출력의 사본(또는 경우에 따라 심볼릭 링크)임을 알아두세요. + +이제 Nextflow가 실제로 작업을 실행한 위치를 확인하기 위해 내부를 살펴보겠습니다. + +!!! Warning + + 모든 workflow가 results 디렉토리에 출력을 게시하도록 설정되어 있는 것은 아니며, 디렉토리 이름과 구조가 다를 수 있습니다. + 이 섹션의 조금 더 뒤에서 이 동작이 어디에 지정되어 있는지 확인하는 방법을 보여드리겠습니다. + +### 2.3. `work/` 디렉토리에서 원본 출력 및 로그 찾기 + +workflow를 실행할 때 Nextflow는 workflow의 각 process 호출(=pipeline의 각 단계)에 대해 별도의 '작업 디렉토리'를 생성합니다. +각각에 대해 필요한 입력을 스테이징하고, 관련 명령을 실행하고, 출력과 로그 파일을 해당 디렉토리 내에 작성합니다. 이 디렉토리는 고유하게 만들기 위해 해시를 사용하여 자동으로 이름이 지정됩니다. + +이러한 모든 작업 디렉토리는 현재 디렉토리(명령을 실행하는 위치) 내의 `work`라는 디렉토리 아래에 위치합니다. + +혼란스럽게 들릴 수 있으므로 실제로 어떻게 보이는지 살펴보겠습니다. + +앞서 실행한 workflow의 콘솔 출력으로 돌아가면 다음 줄이 있었습니다: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +줄이 `[a3/7be2fa]`로 시작하는 것을 보셨나요? +이것은 해당 process 호출의 작업 디렉토리 경로의 축약된 형태이며, `work/` 디렉토리 경로 내에서 `sayHello` process 호출의 출력을 찾을 위치를 알려줍니다. + +다음 명령을 입력하고(자신의 터미널에 표시된 것으로 `a3/7be2fa`를 대체) Tab 키를 눌러 경로를 자동 완성하거나 별표를 추가하여 전체 경로를 찾을 수 있습니다: + +```bash +ls work/a3/7be2fa* +``` + +이렇게 하면 전체 경로 디렉토리 경로가 표시됩니다: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +그 안에 무엇이 있는지 살펴보겠습니다. + +??? abstract "디렉토리 내용" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "같은 것이 보이지 않나요?" + + 정확한 하위 디렉토리 이름은 시스템에서 다를 것입니다. + + VSCode 파일 탐색기에서 작업 하위 디렉토리의 내용을 찾아보면 모든 파일이 바로 표시됩니다. + 그러나 로그 파일은 터미널에서 보이지 않도록 설정되어 있으므로 `ls` 또는 `tree`를 사용하여 보려면 보이지 않는 파일을 표시하는 관련 옵션을 설정해야 합니다. + + ```bash + tree -a work + ``` + +`output.txt` 파일을 바로 알아볼 수 있을 것입니다. 이 파일은 실제로 `results` 디렉토리에 게시된 `sayHello` process의 원본 출력입니다. +열어보면 `Hello World!` 인사말을 다시 찾을 수 있습니다. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +그렇다면 다른 모든 파일들은 무엇일까요? + +이것들은 Nextflow가 작업 실행의 일부로 작성한 도우미 및 로그 파일입니다: + +- **`.command.begin`**: 작업이 시작되자마자 생성되는 센티넬 파일. +- **`.command.err`**: process 호출에서 발생한 오류 메시지(`stderr`) +- **`.command.log`**: process 호출에서 발생한 전체 로그 출력 +- **`.command.out`**: process 호출의 일반 출력(`stdout`) +- **`.command.run`**: Nextflow가 process 호출을 실행하기 위해 실행한 전체 스크립트 +- **`.command.sh`**: process 호출에서 실제로 실행된 명령 +- **`.exitcode`**: 명령에서 발생한 종료 코드 + +`.command.sh` 파일은 모든 부기 및 작업/환경 설정을 포함하지 않고 Nextflow가 실행한 기본 명령을 보여주기 때문에 특히 유용합니다. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +이것은 workflow가 이전에 명령줄에서 직접 실행한 것과 동일한 명령을 구성했음을 확인합니다. + +문제가 발생하여 무슨 일이 있었는지 해결해야 할 때, `command.sh` 스크립트를 보고 Nextflow가 workflow 지침, 변수 보간 등을 기반으로 어떤 명령을 구성했는지 정확히 확인하는 것이 유용할 수 있습니다. + +### 2.4. 다른 인사말로 workflow 다시 실행 + +`--input` 인수에 다른 값을 사용하여 workflow를 몇 번 더 실행한 다음 작업 디렉토리를 살펴보세요. + +??? abstract "디렉토리 내용" + + ```console + 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 + ``` + +각 실행에 대해 완전한 출력 및 로그 파일 세트가 포함된 새 하위 디렉토리가 생성된 것을 볼 수 있습니다. + +반면에 `results` 디렉토리를 보면 여전히 결과 세트가 하나뿐이며 출력 파일의 내용은 마지막으로 실행한 것에 해당합니다. + +??? abstract "디렉토리 내용" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +이것은 게시된 결과가 후속 실행에 의해 덮어쓰여지는 반면, `work/` 아래의 작업 디렉토리는 보존된다는 것을 보여줍니다. + +### 요약 + +간단한 Nextflow 스크립트를 실행하고 실행을 모니터링하고 출력을 찾는 방법을 알게 되었습니다. + +### 다음 단계 + +기본 Nextflow 스크립트를 읽고 구성 요소가 기능과 어떻게 관련되는지 식별하는 방법을 배웁니다. + +--- + +## 3. Hello World workflow 시작 스크립트 검토 + +방금 한 것은 기본적으로 workflow 스크립트를 블랙 박스로 취급한 것입니다. +이제 무엇을 하는지 보았으니 상자를 열고 내부를 살펴보겠습니다. + +여기서 목표는 Nextflow 코드의 구문을 암기하는 것이 아니라 주요 구성 요소가 무엇이고 어떻게 구성되어 있는지에 대한 기본적인 직관을 형성하는 것입니다. + +### 3.1. 전체 코드 구조 검토 + +`1-hello.nf` 스크립트는 현재 디렉토리인 `nextflow-run`에서 찾을 수 있습니다. 편집기 창에서 열어보세요. + +??? full-code "전체 코드 파일" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * echo를 사용하여 'Hello World!'를 파일에 출력 + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * 파이프라인 매개변수 + */ + params { + input: String + } + + workflow { + + main: + // 인사말 출력 + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Nextflow workflow 스크립트는 일반적으로 하나 이상의 **process** 정의, **workflow** 자체, 그리고 **params** 및 **output**과 같은 몇 가지 선택적 블록을 포함합니다. + +각 **process**는 pipeline의 해당 단계가 수행해야 할 작업을 설명하고, **workflow**는 다양한 단계를 연결하는 데이터 흐름 로직을 설명합니다. + +먼저 **process** 블록을 자세히 살펴본 다음 **workflow** 블록을 살펴보겠습니다. + +### 3.2. `process` 정의 + +첫 번째 코드 블록은 **process**를 설명합니다. +process 정의는 `process` 키워드로 시작하고 그 뒤에 process 이름이 오고 마지막으로 중괄호로 구분된 process 본문이 옵니다. +process 본문에는 실행할 명령을 지정하는 script 블록이 포함되어야 하며, 이 명령은 명령줄 터미널에서 실행할 수 있는 모든 것이 될 수 있습니다. + +```groovy title="1-hello.nf" linenums="3" +/* +* echo를 사용하여 인사말을 파일에 출력 +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +여기서는 `greeting`이라는 **input** 변수를 받아 `output.txt`라는 파일에 **output**을 쓰는 `sayHello`라는 **process**가 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +이것은 `input` 정의, `output` 정의 및 실행할 `script`만 포함하는 매우 최소한의 process 정의입니다. + +`input` 정의에는 Nextflow에게 어떤 종류의 값(문자열, 숫자 등)을 기대하도록 알려주는 `val` 한정자가 포함되어 있습니다. + +`output` 정의에는 이것이 경로로 처리되어야 함을 Nextflow에게 알려주는 `path` 한정자가 포함되어 있습니다(디렉토리 경로와 파일 모두 포함). + +### 3.3. `workflow` 정의 + +두 번째 코드 블록은 **workflow** 자체를 설명합니다. +workflow 정의는 `workflow` 키워드로 시작하고 그 뒤에 선택적 이름이 오고, 그 다음 중괄호로 구분된 workflow 본문이 옵니다. + +여기서는 `main:` 블록과 `publish:` 블록으로 구성된 **workflow**가 있습니다. +`main:` 블록은 workflow의 기본 본문이고 `publish:` 블록은 `results` 디렉토리에 게시되어야 하는 출력을 나열합니다. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // 인사말 출력 + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +이 경우 `main:` 블록에는 `sayHello` process 호출이 포함되어 있으며 인사말로 사용할 `params.input`이라는 입력을 제공합니다. + +잠시 후 더 자세히 논의하겠지만, `params.input`은 명령줄에서 `--input` 매개변수에 제공한 값을 보유합니다. + +`publish:` 블록은 `sayHello()` process 호출의 출력을 나열하며, 이를 `sayHello.out`으로 참조하고 `first_output`이라는 이름을 부여합니다(이것은 workflow 작성자가 원하는 대로 지정할 수 있습니다). + +이것은 매우 최소한의 **workflow** 정의입니다. +실제 pipeline에서 workflow는 일반적으로 **channels**로 연결된 **processes**에 대한 여러 호출을 포함하며, 변수 입력에 대한 기본값이 설정될 수 있습니다. + +이것은 과정의 Part 2에서 다룰 것입니다. +지금은 workflow가 입력과 출력을 어떻게 처리하는지 자세히 살펴보겠습니다. + +### 3.4. 명령줄 매개변수의 `params` 시스템 + +`sayHello()` process 호출에 제공하는 `params.input`은 Nextflow 코드의 깔끔한 부분이며 잠시 더 살펴볼 가치가 있습니다. + +위에서 언급했듯이, 이것이 `--input` 명령줄 매개변수의 값을 `sayHello()` process 호출에 전달하는 방법입니다. +실제로 `params.someParameterName`을 선언하는 것만으로 workflow에 명령줄에서 `--someParameterName`이라는 매개변수를 부여할 수 있습니다. + +여기서는 workflow가 기대하는 입력 유형을 지정하는 `params` 블록을 설정하여 해당 매개변수 선언을 공식화했습니다(Nextflow 25.10.2 이상). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +지원되는 유형에는 `String`, `Integer`, `Float`, `Boolean` 및 `Path`가 포함됩니다. + +!!! tip + + `params` 시스템을 사용하여 선언된 workflow 매개변수는 항상 명령줄에서 두 개의 대시(`--`)를 사용합니다. + 이것은 하나의 대시(`-`)만 사용하는 Nextflow 수준 매개변수와 구분됩니다. + +### 3.5. `publish` 지시문 + +workflow의 다른 쪽에서 `publish:` 블록을 이미 살펴보았습니다. +그것은 출력 처리 시스템의 절반이며, 나머지 절반은 아래에 있는 `output` 블록입니다. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +이것은 `publish:` 블록에 나열된 `first_output` 출력이 기본 `results` 출력 디렉토리 아래의 `1-hello`라는 하위 디렉토리에 복사되어야 함을 지정합니다. + +`mode 'copy'` 줄은 `work/` 디렉토리의 원본 파일에 대한 심볼릭 링크(또는 symlink)를 만드는 대신 적절한 복사본을 만드는 시스템의 기본 동작을 재정의합니다. + +게시 동작을 제어하기 위한 옵션이 여기에 표시된 것보다 더 많이 있습니다. 나중에 몇 가지를 다룰 것입니다. +또한 workflow가 여러 출력을 생성할 때 각각이 이 방식으로 `output` 블록에 나열되는 것을 볼 수 있습니다. + +??? info "`publishDir`을 사용한 출력 게시의 이전 구문" + + 매우 최근까지 출력을 게시하는 확립된 방법은 `publishDir` 지시문을 사용하여 각 개별 process 수준에서 수행하는 것이었습니다. + + 이 코드 패턴은 여전히 이전 Nextflow pipeline 및 process 모듈 전체에서 찾을 수 있으므로 이를 알고 있는 것이 중요합니다. + + workflow의 `publish:` 블록과 최상위 수준의 `output` 블록 대신 `sayHello` process 정의에 `publishDir` 줄이 표시됩니다: + + ```groovy title="구문 예제" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + 그러나 향후 Nextflow 언어 버전에서 결국 허용되지 않을 것이므로 새 작업에서 이것을 사용하는 것은 권장하지 않습니다. + +### 요약 + +이제 간단한 Nextflow workflow가 어떻게 구조화되어 있고 기본 구성 요소가 기능과 어떻게 관련되는지 알게 되었습니다. + +### 다음 단계 + +workflow 실행을 편리하게 관리하는 방법을 배웁니다. + +--- + +## 4. Workflow 실행 관리 + +workflow를 시작하고 출력을 검색하는 방법을 아는 것은 훌륭하지만, 작업을 더 쉽게 만들어 주는 workflow 관리의 몇 가지 다른 측면이 있습니다. + +여기서는 동일한 workflow를 다시 시작해야 할 때 `resume` 기능을 활용하는 방법, `nextflow log`로 실행 로그를 검사하는 방법, `nextflow clean`으로 이전 작업 디렉토리를 삭제하는 방법을 보여드립니다. + +### 4.1. `-resume`으로 workflow 다시 시작 + +때때로 이전에 이미 시작한 pipeline을 이미 성공적으로 완료된 작업을 다시 수행하지 않고 다시 실행하고 싶을 것입니다. + +Nextflow에는 이를 수행할 수 있는 `-resume`이라는 옵션이 있습니다. +구체적으로 이 모드에서는 정확히 동일한 코드, 설정 및 입력으로 이미 실행된 모든 process가 건너뛰어집니다. +이것은 Nextflow가 마지막 실행 이후 추가하거나 수정한 process 또는 새 설정이나 입력을 제공하는 process만 실행한다는 것을 의미합니다. + +이렇게 하면 두 가지 주요 이점이 있습니다: + +- pipeline을 개발하는 중이라면 변경 사항을 테스트하기 위해 현재 작업 중인 process만 실행하면 되므로 더 빠르게 반복할 수 있습니다. +- 프로덕션에서 pipeline을 실행 중이고 문제가 발생하면 많은 경우 문제를 수정하고 pipeline을 다시 시작할 수 있으며, 실패 지점부터 실행을 재개하여 많은 시간과 컴퓨팅을 절약할 수 있습니다. + +사용하려면 명령에 `-resume`을 추가하고 실행하면 됩니다: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "명령 출력" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +콘솔 출력은 익숙해 보이지만 이전과 약간 다른 점이 있습니다. + +process 상태 줄(5번째 줄)에 추가된 `cached:` 부분을 찾아보세요. 이것은 Nextflow가 이 작업을 이미 수행했음을 인식하고 이전 성공적인 실행의 결과를 단순히 재사용했음을 의미합니다. + +작업 하위 디렉토리 해시가 이전 실행과 동일한 것도 볼 수 있습니다. +Nextflow는 문자 그대로 이전 실행을 가리키며 "저기서 이미 했어요"라고 말하는 것입니다. + +!!! tip + + `resume`으로 pipeline을 다시 실행할 때 Nextflow는 이전에 성공적으로 실행된 실행에 의해 작업 디렉토리 외부에 게시된 파일을 덮어쓰지 않습니다. + +### 4.2. 과거 실행 로그 검사 + +nextflow workflow를 시작할 때마다 현재 작업 디렉토리의 `.nextflow`라는 숨겨진 디렉토리 아래에 `history`라는 로그 파일에 줄이 기록됩니다. + +??? abstract "파일 내용" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +이 파일은 현재 작업 디렉토리 내에서 시작된 모든 Nextflow 실행에 대한 타임스탬프, 실행 이름, 상태, 리비전 ID, 세션 ID 및 전체 명령줄을 제공합니다. + +이 정보에 액세스하는 더 편리한 방법은 `nextflow log` 명령을 사용하는 것입니다. + +```bash +nextflow log +``` + +??? success "명령 출력" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +이렇게 하면 헤더 줄이 추가된 로그 파일의 내용이 터미널에 출력됩니다. + +새 `nextflow run` 명령을 실행할 때마다 세션 ID가 변경되지만, `-resume` 옵션을 사용하는 경우에는 예외입니다. +그 경우 세션 ID가 동일하게 유지됩니다. + +Nextflow는 세션 ID를 사용하여 `.nextflow` 아래에 있는 `cache` 디렉토리 아래에 실행 캐싱 정보를 그룹화합니다. + +### 4.3. 이전 작업 디렉토리 삭제 + +많은 pipeline을 실행하면 많은 하위 디렉토리에 매우 많은 파일이 축적될 수 있습니다. +하위 디렉토리는 무작위로 이름이 지정되므로 이름만으로는 이전 실행과 최근 실행을 구분하기 어렵습니다. + +다행히 Nextflow에는 더 이상 관심이 없는 과거 실행에 대한 작업 하위 디렉토리를 자동으로 삭제할 수 있는 유용한 `clean` 하위 명령이 포함되어 있습니다. + +#### 4.3.1. 삭제 기준 결정 + +삭제할 항목을 결정하는 여러 [옵션](https://www.nextflow.io/docs/latest/reference/cli.html#clean)이 있습니다. + +여기서는 실행 이름을 사용하여 지정된 실행 이전의 모든 하위 디렉토리를 삭제하는 예를 보여드립니다. + +`-resume`을 사용하지 않은 가장 최근의 성공적인 실행을 찾아보세요. 우리의 경우 실행 이름은 `backstabbing_swartz`였습니다. + +실행 이름은 `Launching (...)` 콘솔 출력 줄에서 대괄호 안에 표시되는 기계 생성 두 부분 문자열입니다. +Nextflow 로그를 사용하여 타임스탬프 및/또는 명령줄을 기반으로 실행을 찾을 수도 있습니다. + +#### 4.3.2. 드라이 런 수행 + +먼저 드라이 런 플래그 `-n`을 사용하여 명령에 따라 삭제될 항목을 확인합니다: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "명령 출력" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +출력에는 다른 작업 디렉토리 이름이 있고 줄 수가 다를 수 있지만 예제와 비슷해 보여야 합니다. + +줄이 출력되지 않으면 유효한 실행 이름을 제공하지 않았거나 삭제할 과거 실행이 없는 것입니다. 예제 명령의 `backstabbing_swartz`를 로그의 해당 최신 실행 이름으로 변경해야 합니다. + +#### 4.3.3. 삭제 진행 + +출력이 예상대로 보이고 삭제를 진행하려면 `-n` 대신 `-f` 플래그로 명령을 다시 실행하세요: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "명령 출력" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +출력은 이전과 비슷해야 하지만 이제 'Would remove' 대신 'Removed'라고 표시됩니다. +이것은 두 문자 하위 디렉토리(위의 `eb/`와 같은)를 제거하지 않지만 그 내용을 비웁니다. + +!!! Warning + + 과거 실행에서 작업 하위 디렉토리를 삭제하면 Nextflow의 캐시에서 제거되고 해당 디렉토리에 저장된 모든 출력이 삭제됩니다. + 이것은 해당 process를 다시 실행하지 않고 실행을 재개하는 Nextflow의 기능을 손상시킵니다. + + 관심 있는 출력을 저장하는 것은 사용자의 책임입니다! 이것이 `publish` 지시문에 `symlink` 모드보다 `copy` 모드를 선호하는 주된 이유입니다. + +### 요약 + +이미 동일한 방식으로 실행된 단계를 반복하지 않고 pipeline을 다시 시작하는 방법, 실행 로그를 검사하는 방법, `nextflow clean` 명령을 사용하여 이전 작업 디렉토리를 정리하는 방법을 알게 되었습니다. + +### 다음 단계 + +잠시 휴식을 취하세요! Nextflow 구문과 기본 사용 지침의 구성 요소를 방금 흡수했습니다. + +교육의 다음 섹션에서는 Hello World pipeline의 점점 더 현실적인 네 가지 버전을 살펴보며 Nextflow가 여러 입력을 효율적으로 처리하고, 함께 연결된 여러 단계로 구성된 workflow를 실행하고, 모듈식 코드 구성 요소를 활용하고, 더 큰 재현성과 이식성을 위해 컨테이너를 활용하는 방법을 시연합니다. + +--- + +## 퀴즈 + +<quiz> +콘솔 출력 줄 `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`에서 `[a3/7be2fa]`는 무엇을 나타내나요? +- [ ] process 버전 번호 +- [ ] 고유 실행 식별자 +- [x] 작업의 작업 디렉토리에 대한 축약된 경로 +- [ ] 출력 파일의 체크섬 + +자세히 알아보기: [2.3. `work/` 디렉토리에서 원본 출력 및 로그 찾기](#23-work-디렉토리에서-원본-출력-및-로그-찾기) +</quiz> + +<quiz> +작업 디렉토리의 `.command.sh` 파일의 목적은 무엇인가요? +- [ ] 작업의 구성 설정을 저장합니다 +- [x] process에서 실행된 실제 명령을 보여줍니다 +- [ ] 실패한 작업의 오류 메시지를 포함합니다 +- [ ] 작업을 위해 스테이징된 입력 파일을 나열합니다 + +자세히 알아보기: [2.3. `work/` 디렉토리에서 원본 출력 및 로그 찾기](#23-work-디렉토리에서-원본-출력-및-로그-찾기) +</quiz> + +<quiz> +`-resume` 없이 workflow를 다시 실행하면 게시된 결과는 어떻게 되나요? +- [ ] 별도의 타임스탬프가 있는 디렉토리에 보존됩니다 +- [x] 새 실행에 의해 덮어쓰여집니다 +- [ ] Nextflow가 덮어쓰기를 방지하고 실패합니다 +- [ ] 자동으로 백업됩니다 + +자세히 알아보기: [2.4. 다른 인사말로 workflow 다시 실행](#24-다른-인사말로-workflow-다시-실행) +</quiz> + +<quiz> +이 콘솔 출력은 무엇을 나타내나요? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] 작업이 실패하여 건너뛰었습니다 +- [ ] 작업이 대기열에서 대기 중입니다 +- [x] Nextflow가 이전 동일한 실행의 결과를 재사용했습니다 +- [ ] 작업이 수동으로 취소되었습니다 + +자세히 알아보기: [4.1. `-resume`으로 workflow 다시 시작](#41--resume으로-workflow-다시-시작) +</quiz> + +<quiz> +`nextflow log` 명령이 표시하는 실행 히스토리는 어디에 저장되나요? +- [ ] results 디렉토리에 +- [ ] work 디렉토리에 +- [x] `.nextflow/history` 파일에 +- [ ] `nextflow.config`에 + +자세히 알아보기: [4.2. 과거 실행 로그 검사](#42-과거-실행-로그-검사) +</quiz> + +<quiz> +workflow 파일에서 `params` 블록의 목적은 무엇인가요? +- [ ] process 리소스 요구 사항을 정의합니다 +- [ ] executor를 구성합니다 +- [x] workflow 입력 매개변수를 선언하고 유형을 지정합니다 +- [ ] 출력 게시 옵션을 지정합니다 + +자세히 알아보기: [3.4. 명령줄 매개변수의 params 시스템](#34-명령줄-매개변수의-params-시스템) +</quiz> + +<quiz> +workflow의 `output` 블록에서 `mode 'copy'`는 무엇을 하나요? +- [ ] 작업 디렉토리의 백업을 생성합니다 +- [x] 심볼릭 링크 대신 파일의 전체 복사본을 만듭니다 +- [ ] workflow 스크립트를 results에 복사합니다 +- [ ] 증분 파일 복사를 활성화합니다 + +자세히 알아보기: [3.5. publish 지시문](#35-publish-지시문) +</quiz> + +<quiz> +파일을 실제로 삭제하기 전에 `nextflow clean` 명령과 함께 사용하는 것이 권장되는 플래그는 무엇인가요? +- [x] `-n` (드라이 런)으로 삭제될 항목을 미리 봅니다 +- [ ] `-v` (상세)로 자세한 출력을 봅니다 +- [ ] `-a` (전체)로 모든 디렉토리를 선택합니다 +- [ ] `-q` (조용)으로 경고를 숨깁니다 + +자세히 알아보기: [4.3. 이전 작업 디렉토리 삭제](#43-이전-작업-디렉토리-삭제) +</quiz> diff --git a/docs/ko/docs/nextflow_run/02_pipeline.md b/docs/ko/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..7a91bf89b6 --- /dev/null +++ b/docs/ko/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1514 @@ +# 파트 2: 실제 pipeline 실행 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 Part 1(기본 작업 실행)에서 코드 복잡성을 낮추기 위해 최소한의 기능만 있는 예제 workflow로 시작했습니다. +예를 들어 `1-hello.nf`는 명령줄 매개변수(`--input`)를 사용하여 한 번에 하나의 값을 제공했습니다. + +그러나 대부분의 실제 pipeline은 대규모 데이터를 효율적으로 처리하고 때로는 복잡한 로직으로 연결된 여러 처리 단계를 적용하기 위해 더 정교한 기능을 사용합니다. + +교육의 이 부분에서는 원래 Hello World pipeline의 확장된 버전을 시험해 보며 실제 pipeline의 핵심 기능을 시연합니다. + +## 1. 파일에서 입력 데이터 처리 + +실제 pipeline에서는 일반적으로 하나 이상의 입력 파일에 포함된 여러 데이터 포인트(또는 데이터 시리즈)를 처리하려고 합니다. +그리고 가능하면 분석 대기 시간을 줄이기 위해 독립적인 데이터의 처리를 병렬로 실행하려고 합니다. + +Nextflow가 이를 어떻게 수행하는지 보여주기 위해 실제 데이터 분석에서 처리할 수 있는 열 형식 데이터를 모방하여 여러 입력 인사말이 포함된 `greetings.csv`라는 CSV 파일을 준비했습니다. +숫자는 의미가 없으며 설명 목적으로만 있습니다. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +원본 workflow의 개선된 버전인 `2a-inputs.nf`도 작성했습니다. 이 버전은 CSV 파일을 읽어 인사말을 추출하고 각각을 별도의 파일에 씁니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +먼저 workflow를 실행한 다음 관련 Nextflow 코드를 살펴보겠습니다. + +### 1.1. Workflow 실행 + +터미널에서 다음 명령을 실행하세요. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +흥미롭게도 이것은 process에 대해 '3 of 3' 호출이 이루어졌음을 나타내며, 입력으로 제공한 CSV에 세 개의 데이터 행이 있었기 때문에 고무적입니다. +이것은 `sayHello()` process가 각 입력 행에 대해 한 번씩 세 번 호출되었음을 시사합니다. + +### 1.2. `results` 디렉토리에서 게시된 출력 찾기 + +'results' 디렉토리를 살펴보고 workflow가 여전히 출력 사본을 거기에 쓰고 있는지 확인해 보겠습니다. + +??? abstract "디렉토리 내용" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +네! 편리하게도 다른 이름을 가진 세 개의 출력 파일이 있는 `2a-inputs`라는 새 디렉토리가 보입니다. + +각각을 열어 적절한 인사말 문자열이 포함되어 있는지 확인할 수 있습니다. + +??? abstract "파일 내용" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +이것은 입력 파일의 각 인사말이 적절하게 처리되었음을 확인합니다. + +### 1.3. 원본 출력 및 로그 찾기 + +위의 콘솔 출력에서 하나의 작업 디렉토리만 참조된 것을 눈치채셨을 것입니다. +그것은 세 번의 `sayHello()` 호출이 모두 하나의 작업 디렉토리 내에서 실행되었다는 것을 의미하나요? + +#### 1.3.1. 터미널에 제공된 작업 디렉토리 검토 + +`8e/0eb066` 작업 디렉토리 내부를 살펴보겠습니다. + +??? abstract "디렉토리 내용" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +인사말 중 하나에 해당하는 출력만 찾을 수 있습니다(숨김 파일 표시를 활성화하면 부속 파일도 볼 수 있습니다). + +무슨 일이 일어나고 있는 걸까요? + +기본적으로 ANSI 로깅 시스템은 동일한 process에 대한 모든 호출의 상태 정보를 같은 줄에 씁니다. +결과적으로 콘솔 출력에서 세 개의 작업 디렉토리 경로 중 하나만(`8e/0eb066`) 표시했습니다. +거기에 나열되지 않은 두 개가 더 있습니다. + +#### 1.3.2. 터미널에 더 많은 세부 정보 표시 + +다음과 같이 명령에 `-ansi-log false`를 추가하여 process 호출의 전체 목록을 보도록 로깅 동작을 수정할 수 있습니다: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "명령 출력" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +이번에는 출력에 세 가지 process 실행과 관련 작업 하위 디렉토리가 모두 나열됩니다. +ANSI 로깅을 비활성화하면 Nextflow가 터미널 출력에서 색상을 사용하지 못하게 됩니다. + +두 로깅 모드 간에 상태 보고 방식이 약간 다릅니다. +압축 모드에서 Nextflow는 호출이 성공적으로 완료되었는지 여부를 보고합니다. +이 확장 모드에서는 제출되었다는 것만 보고합니다. + +이것은 `sayHello()` process가 세 번 호출되고 각각에 대해 별도의 작업 디렉토리가 생성된다는 것을 확인합니다. + +거기에 나열된 각 작업 디렉토리 내부를 살펴보면 각각이 인사말 중 하나에 해당하는지 확인할 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +이것은 각 process 호출이 다른 모든 것과 격리되어 실행된다는 것을 확인합니다. +이것은 process가 고유하지 않은 이름을 가진 중간 파일을 생성하는 경우 충돌을 피하는 것을 포함하여 많은 장점이 있습니다. + +!!! tip + + 복잡한 workflow나 많은 수의 입력의 경우 전체 목록을 터미널에 출력하면 약간 압도적일 수 있으므로 사람들은 일반적으로 일상적인 사용에서 `-ansi-log false`를 사용하지 않습니다. + +### 1.4. Workflow 코드 검토 + +이 버전의 workflow는 입력의 CSV 파일을 읽고 입력을 별도로 처리하고 출력 이름을 고유하게 지정할 수 있습니다. + +workflow 코드에서 무엇이 이를 가능하게 하는지 살펴보겠습니다. + +??? full-code "전체 코드 파일" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + } + + workflow { + + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +다시 한번, 코드 구문을 암기할 필요는 없지만 중요한 기능을 제공하는 workflow의 핵심 구성 요소를 인식하는 방법을 배우는 것이 좋습니다. + +#### 1.4.1. CSV에서 입력 데이터 로드 + +이것이 가장 흥미로운 부분입니다: 명령줄에서 단일 값을 가져오는 것에서 CSV 파일을 가져와 구문 분석하고 포함된 개별 인사말을 처리하는 것으로 어떻게 전환했을까요? + +Nextflow에서는 **channel**로 이를 수행합니다. channel은 입력을 효율적으로 처리하고 다단계 workflow에서 한 단계에서 다른 단계로 셔틀하도록 설계된 구조로, 내장된 병렬 처리와 많은 추가 이점을 제공합니다. + +분석해 보겠습니다. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) +``` + +이 코드는 CSV 파일을 읽고 구문 분석하고 각 행에서 첫 번째 열을 추출하는 `greeting_ch`라는 channel을 생성합니다. +결과는 `Hello`, `Bonjour`, `Holà`를 포함하는 channel입니다. + +??? tip "이것이 어떻게 작동하나요?" + + 이 줄이 일반 영어로 무엇을 의미하는지 설명하면: + + - `channel.fromPath`는 파일 경로에서 channel을 생성하는 **channel factory**입니다 + - `(params.input)`은 파일 경로가 명령줄의 `--input`에 의해 제공됨을 지정합니다 + + 즉, 그 줄은 Nextflow에게 `--input`으로 제공된 파일 경로를 가져와 그 내용을 입력 데이터로 처리할 준비를 하라고 말합니다. + + 그런 다음 다음 두 줄은 파일의 실제 구문 분석과 적절한 데이터 구조로의 데이터 로드를 수행하는 **연산자**를 적용합니다: + + - `.splitCsv()`는 Nextflow에게 CSV 파일을 행과 열을 나타내는 배열로 구문 분석하라고 말합니다 + - `.map { line -> line[0] }`는 Nextflow에게 각 행에서 첫 번째 열의 요소만 가져오라고 말합니다 + + 실제로 다음 CSV 파일에서 시작하여: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + 이것을 다음과 같은 배열로 변환했습니다: + + ```txt title="배열 내용" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + 그런 다음 세 행 각각에서 첫 번째 요소를 가져와 이제 `Hello`, `Bonjour`, `Holà`를 포함하는 Nextflow channel에 로드했습니다. + + channel과 연산자를 깊이 이해하고 직접 작성하는 방법을 포함하여 [Hello Nextflow Part 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file)를 참조하세요. + +#### 1.4.2. 각 인사말에 대해 process 호출 + +다음으로 workflow의 `main:` 블록의 마지막 줄에서 로드된 `greeting_ch` channel을 `sayHello()` process에 입력으로 제공합니다. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) +``` + +이것은 Nextflow에게 channel의 각 요소, 즉 각 인사말에 대해 process를 개별적으로 실행하라고 말합니다. +그리고 Nextflow는 똑똑하기 때문에 사용 가능한 컴퓨팅 인프라에 따라 가능한 경우 이러한 process 호출을 병렬로 실행합니다. + +이것이 상대적으로 매우 적은 코드로 많은 데이터(많은 샘플, 데이터 포인트 또는 연구 단위)의 효율적이고 확장 가능한 처리를 달성할 수 있는 방법입니다. + +#### 1.4.3. 출력 이름 지정 방법 + +마지막으로 출력 파일의 이름이 고유하게 지정되는 방법을 보기 위해 process 코드를 간략히 살펴볼 가치가 있습니다. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +`1-hello.nf`의 이 process 버전과 비교하여 출력 선언과 명령의 관련 부분이 출력 파일 이름에 인사말 값을 포함하도록 변경된 것을 볼 수 있습니다. + +이것은 출력 파일 이름이 공통 results 디렉토리에 게시될 때 충돌하지 않도록 하는 한 가지 방법입니다. + +그리고 이것이 process 선언 내에서 변경해야 했던 유일한 변경 사항입니다! + +### 요약 + +channel과 연산자가 여러 입력을 효율적으로 처리하는 방법을 기본적인 수준에서 이해합니다. + +### 다음 단계 + +다단계 workflow가 어떻게 구성되고 작동하는지 알아봅니다. + +--- + +## 2. 다단계 workflow 실행 + +대부분의 실제 workflow에는 둘 이상의 단계가 포함됩니다. +channel에 대해 방금 배운 것을 바탕으로 Nextflow가 channel과 연산자를 사용하여 다단계 workflow에서 process를 함께 연결하는 방법을 살펴보겠습니다. + +이를 위해 세 개의 별도 단계를 연결하고 다음을 시연하는 예제 workflow를 제공합니다: + +1. 데이터가 한 process에서 다음 process로 흐르도록 만들기 +2. 여러 process 호출의 출력을 단일 process 호출로 수집 + +구체적으로 각 입력 인사말을 가져와 대문자로 변환한 다음 모든 대문자 인사말을 단일 출력 파일로 수집하는 `2b-multistep.nf`라는 workflow의 확장된 버전을 만들었습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +이전과 마찬가지로 먼저 workflow를 실행한 다음 코드를 살펴보며 새로운 것이 무엇인지 확인합니다. + +### 2.1. Workflow 실행 + +터미널에서 다음 명령을 실행하세요: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "명령 출력" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +약속대로 workflow의 일부로 여러 단계가 실행된 것을 볼 수 있습니다. 처음 두 개(`sayHello`와 `convertToUpper`)는 아마도 각 개별 인사말에서 실행되었고, 세 번째(`collectGreetings`)는 세 개의 `convertToUpper` 호출 모두의 출력에서 한 번만 실행되었을 것입니다. + +### 2.2. 출력 찾기 + +`results` 디렉토리를 살펴보며 실제로 그런 일이 일어났는지 확인해 보겠습니다. + +??? abstract "디렉토리 내용" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +보시다시피 `2b-multistep`이라는 새 디렉토리가 있으며 이전보다 훨씬 더 많은 파일이 포함되어 있습니다. +일부 파일은 `intermediates`라는 하위 디렉토리에 그룹화되어 있고 두 개의 파일은 최상위 수준에 있습니다. + +그 두 개가 다단계 workflow의 최종 결과입니다. +파일 이름을 살펴보고 내용을 확인하여 예상대로인지 확인하세요. + +??? abstract "파일 내용" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +첫 번째는 약속대로 세 개의 인사말이 대문자로 변환되어 단일 파일로 수집된 것을 포함합니다. +두 번째는 실행에 대한 일부 정보를 요약하는 보고서 파일입니다. + +### 2.3. 코드 검토 + +코드를 살펴보고 다단계 workflow의 핵심 패턴을 식별해 보겠습니다. + +??? full-code "전체 코드 파일" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Use a text replacement tool to convert the greeting to uppercase + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +많은 일이 일어나고 있지만 이전 버전의 workflow와 비교했을 때 가장 명백한 차이점은 이제 여러 process 정의가 있고 해당하여 workflow 블록에 여러 process 호출이 있다는 것입니다. + +자세히 살펴보고 가장 흥미로운 부분을 식별할 수 있는지 확인해 보겠습니다. + +#### 2.3.1. Workflow 구조 시각화 + +Nextflow 확장이 있는 VSCode를 사용하는 경우 Nextflow 스크립트의 workflow 블록 바로 위에 표시되는 작은 `DAG preview` 링크를 클릭하여 process가 어떻게 연결되어 있는지에 대한 유용한 다이어그램을 얻을 수 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +이것은 process가 어떻게 연결되어 있고 무엇을 생성하는지에 대한 좋은 개요를 제공합니다. + +원래 `sayHello` process 외에도 이제 `convertToUpper`와 `collectGreetings`도 있으며, 이는 콘솔 출력에서 본 process 이름과 일치합니다. +두 개의 새 process 정의는 `sayHello` process와 동일한 방식으로 구조화되어 있지만, `collectGreetings`는 `batch`라는 추가 입력 매개변수를 받고 두 개의 출력을 생성합니다. + +각각의 코드에 대해 자세히 다루지 않겠지만, 궁금하시다면 [Hello Nextflow의 Part 2](../hello_nextflow/03_hello_workflow.md)에서 세부 사항을 찾아볼 수 있습니다. + +지금은 process가 서로 어떻게 연결되어 있는지 살펴보겠습니다. + +#### 2.3.2. Process 연결 방법 + +여기서 정말 흥미로운 것은 workflow의 `main:` 블록에서 process 호출이 어떻게 연결되어 있는지입니다. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +첫 번째 process 호출인 `sayHello(greeting_ch)`는 변경되지 않은 것을 볼 수 있습니다. +그런 다음 `convertToUpper`에 대한 다음 process 호출은 `sayHello`의 출력을 `sayHello.out`으로 참조합니다. + +패턴은 간단합니다: `processName.out`은 process의 출력 channel을 참조하며, 이를 다음 process에 직접 전달할 수 있습니다. +이것이 Nextflow에서 한 단계에서 다음 단계로 데이터를 셔틀하는 방법입니다. + +#### 2.3.3. Process는 여러 입력을 받을 수 있습니다 + +세 번째 process 호출인 `collectGreetings`는 약간 다릅니다. + +```groovy title="2b-multistep.nf" linenums="77" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +이 호출에 `convertToUpper.out.collect()`와 `params.batch`라는 두 개의 입력이 제공되는 것을 볼 수 있습니다. +지금은 `.collect()` 부분을 무시하고 이것을 `collectGreetings(input1, input2)`로 일반화할 수 있습니다. + +이것은 process 모듈의 두 입력 선언과 일치합니다: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Nextflow가 이것을 구문 분석할 때 호출의 첫 번째 입력을 `path input_files`에 할당하고 두 번째를 `val batch_name`에 할당합니다. + +이제 process가 여러 입력을 받을 수 있다는 것과 workflow 블록에서 호출이 어떻게 보이는지 알게 되었습니다. + +이제 첫 번째 입력인 `convertToUpper.out.collect()`를 자세히 살펴보겠습니다. + +#### 2.3.4. `collectGreetings` 호출에서 `collect()`가 하는 일 + +`sayHello`의 출력을 `convertToUpper`에 전달하기 위해 `sayHello.out`으로 `sayHello`의 출력 channel을 간단히 참조했습니다. 그러나 다음 단계에서는 `convertToUpper.out.collect()`에 대한 참조를 보고 있습니다. + +이 `collect()` 부분은 무엇이고 무엇을 하나요? + +물론 연산자입니다. 앞서 만난 `splitCsv` 및 `map` 연산자와 마찬가지입니다. +이번에는 연산자가 `collect`이라고 하며 `convertToUpper`가 생성한 출력 channel에 적용됩니다. + +`collect` 연산자는 동일한 process에 대한 여러 호출의 출력을 수집하고 단일 channel 요소로 패키징하는 데 사용됩니다. + +이 workflow의 맥락에서 `convertToUpper.out` channel의 세 개의 대문자 인사말(세 개의 별도 channel 항목이며 일반적으로 다음 process에 의해 별도의 호출로 처리됨)을 가져와 단일 항목으로 패키징합니다. + +더 실용적인 용어로: `convertToUpper()`의 출력을 `collectGreetings()`에 공급하기 전에 `collect()`를 적용하지 않으면 Nextflow는 단순히 각 인사말에 대해 `collectGreetings()`를 독립적으로 실행하여 목표를 달성하지 못합니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +반대로 `collect()`를 사용하면 workflow의 두 번째 단계에서 생성된 모든 별도의 대문자 인사말을 가져와 pipeline의 세 번째 단계에서 단일 호출에 모두 함께 공급할 수 있습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +이것이 모든 인사말을 같은 파일로 다시 가져오는 방법입니다. + +process 호출 간에 channel 내용에 변환을 적용할 수 있는 다른 많은 [연산자](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page)가 있습니다. + +이것은 pipeline 개발자에게 pipeline의 흐름 로직을 사용자 정의하는 데 많은 유연성을 제공합니다. +단점은 때때로 pipeline이 무엇을 하고 있는지 해독하기 어렵게 만들 수 있다는 것입니다. + +#### 2.3.5. 입력 매개변수는 기본값을 가질 수 있습니다 + +`collectGreetings`가 두 번째 입력인 `params.batch`를 받는 것을 눈치채셨을 것입니다: + +```groovy title="2b-multistep.nf" linenums="77" + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +이것은 `--batch`라는 CLI 매개변수를 workflow에 전달합니다. +그러나 이전에 workflow를 시작할 때 `--batch` 매개변수를 지정하지 않았습니다. + +무슨 일이 일어나고 있을까요? +`params` 블록을 살펴보세요: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +workflow에 기본값이 구성되어 있으므로 제공할 필요가 없습니다. +하지만 명령줄에서 제공하면 지정한 값이 기본값 대신 사용됩니다. + +시도해 보세요: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "명령 출력" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +사용자 정의 배치 이름으로 명명된 새 최종 출력을 볼 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +이것은 Part 3에서 더 자세히 다룰 입력 구성의 한 측면이지만, 지금 중요한 것은 입력 매개변수에 기본값을 부여할 수 있다는 것입니다. + +#### 2.3.6. Process는 여러 출력을 생성할 수 있습니다 + +`collectGreetings` process 정의에서 다음 출력 선언을 볼 수 있습니다: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +이것은 `publish:` 블록에서 `emit:`으로 지정된 이름으로 참조됩니다: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +이렇게 하면 다양한 연산자와 함께 workflow의 다른 process에 특정 출력을 개별적으로 쉽게 전달할 수 있습니다. + +#### 2.3.7. 게시된 출력을 구성할 수 있습니다 + +`output` 블록에서 workflow의 최종 출력만 쉽게 선택할 수 있도록 중간 결과를 그룹화하기 위해 사용자 정의 경로를 사용했습니다. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +게시된 출력을 구성하는 더 정교한 방법이 있습니다. 구성에 관한 부분에서 몇 가지를 다룰 것입니다. + +!!! tip "Workflow 구축에 대해 더 알고 싶으신가요?" + + 다단계 workflow 구축에 대한 자세한 내용은 [Hello Nextflow Part 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md)를 참조하세요. + +### 요약 + +channel과 연산자를 사용하여 다단계 workflow가 어떻게 구성되고 작동하는지 기본적인 수준에서 이해합니다. +또한 process가 여러 입력을 받고 여러 출력을 생성할 수 있으며 이것들이 구조화된 방식으로 게시될 수 있음을 보았습니다. + +### 다음 단계 + +Nextflow pipeline이 코드 재사용과 유지 관리성을 촉진하기 위해 어떻게 모듈화될 수 있는지 배웁니다. + +--- + +## 3. 모듈화된 pipeline 실행 + +지금까지 살펴본 모든 workflow는 모든 관련 코드를 포함하는 하나의 단일 workflow 파일로 구성되었습니다. + +그러나 실제 pipeline은 일반적으로 *모듈화*의 이점을 누리며, 이는 코드가 다른 파일로 분할됨을 의미합니다. +이렇게 하면 개발 및 유지 관리가 더 효율적이고 지속 가능해질 수 있습니다. + +여기서는 Nextflow에서 가장 일반적인 코드 모듈성 형태인 **모듈** 사용을 시연하겠습니다. + +Nextflow에서 **모듈**은 독립 실행형 코드 파일에 자체적으로 캡슐화된 단일 process 정의입니다. +workflow에서 모듈을 사용하려면 workflow 코드 파일에 한 줄 import 문을 추가하기만 하면 됩니다. 그런 다음 일반적으로 하는 것과 같은 방식으로 process를 workflow에 통합할 수 있습니다. +이를 통해 코드의 여러 복사본을 생성하지 않고도 여러 workflow에서 process 정의를 재사용할 수 있습니다. + +지금까지 모든 process가 단일 코드 파일에 포함된 workflow를 실행해 왔습니다. +이제 process가 개별 모듈에 저장될 때 어떻게 보이는지 살펴보겠습니다. + +물론 `modules/` 디렉토리에 있는 모듈 세트와 함께 시연 목적으로 `2c-modules.nf`라는 적합한 workflow를 준비했습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "디렉토리 내용" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +각각 process 중 하나의 이름을 딴 네 개의 Nextflow 파일이 있습니다. +지금은 `cowpy.nf` 파일을 무시해도 됩니다. 나중에 다룰 것입니다. + +### 3.1. 코드 검토 + +이번에는 먼저 코드를 살펴보겠습니다. +`2c-modules.nf` workflow 파일을 열어 시작하세요. + +??? full-code "전체 코드 파일" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +workflow 로직이 이전 버전의 workflow와 정확히 동일한 것을 볼 수 있습니다. +그러나 process 코드가 workflow 파일에서 사라지고 대신 `modules` 아래의 별도 파일을 가리키는 `include` 문이 있습니다. + +```groovy title="hello-modules.nf" linenums="3" +// 모듈 포함 +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +해당 파일 중 하나를 열면 해당 process의 코드를 찾을 수 있습니다. + +??? full-code "전체 코드 파일" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Use echo to print 'Hello World!' to a file + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +보시다시피 process 코드는 변경되지 않았습니다. 기본 workflow 파일에 있는 대신 개별 모듈 파일에 복사되었을 뿐입니다. +다른 두 process에도 동일하게 적용됩니다. + +이제 이 새 버전을 실행하면 어떻게 보이는지 살펴보겠습니다. + +### 3.2. Workflow 실행 + +`-resume` 플래그와 함께 터미널에서 이 명령을 실행하세요: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +코드가 분할되고 기본 workflow 파일 이름이 변경되었음에도 불구하고 process 실행이 모두 성공적으로 캐시되었음을 알 수 있습니다. 이는 Nextflow가 요청된 작업을 이미 수행했음을 인식했다는 것을 의미합니다. + +Nextflow에게 중요한 것은 모든 코드가 함께 가져와지고 평가된 후 생성되는 작업 스크립트입니다. + +!!! tip + + workflow의 한 섹션을 더 큰 pipeline에 가져올 수 있는 '하위 workflow'로 캡슐화하는 것도 가능하지만, 이 과정의 범위를 벗어납니다. + + [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/)에 대한 Side Quest에서 조합 가능한 workflow 개발에 대해 더 자세히 알아볼 수 있습니다. + +### 요약 + +process가 코드 재사용을 촉진하고 유지 관리성을 개선하기 위해 독립 실행형 모듈에 저장될 수 있음을 알게 되었습니다. + +### 다음 단계 + +소프트웨어 종속성을 관리하기 위해 컨테이너를 사용하는 방법을 배웁니다. + +--- + +## 4. 컨테이너화된 소프트웨어 사용 + +지금까지 예제로 사용한 workflow는 환경에서 사용 가능한 UNIX 도구를 사용하여 매우 기본적인 텍스트 처리 작업만 실행하면 되었습니다. + +그러나 실제 pipeline은 일반적으로 대부분의 환경에 기본적으로 포함되지 않은 전문 도구와 패키지가 필요합니다. +일반적으로 이러한 도구를 설치하고 종속성을 관리하고 충돌을 해결해야 합니다. + +이 모든 것은 매우 지루하고 짜증나는 일입니다. +이 문제를 해결하는 훨씬 더 좋은 방법은 **컨테이너**를 사용하는 것입니다. + +**컨테이너**는 컨테이너 **이미지**에서 생성된 경량의 독립 실행형 실행 가능한 소프트웨어 단위로, 코드, 시스템 라이브러리 및 설정을 포함하여 애플리케이션을 실행하는 데 필요한 모든 것을 포함합니다. + +!!! Tip + + [Docker](https://www.docker.com/get-started/) 기술을 사용하여 가르치지만, Nextflow는 [다른 여러 컨테이너 기술](https://www.nextflow.io/docs/latest/container.html#)도 지원합니다. + +### 4.1. 컨테이너 직접 사용 + +먼저 컨테이너와 직접 상호 작용해 보겠습니다. +이렇게 하면 Nextflow에서 사용하기 전에 컨테이너가 무엇인지에 대한 이해를 확고히 하는 데 도움이 됩니다. + +#### 4.1.1. 컨테이너 이미지 가져오기 + +컨테이너를 사용하려면 일반적으로 컨테이너 레지스트리에서 컨테이너 이미지를 다운로드하거나 "가져온" 다음 컨테이너 이미지를 실행하여 컨테이너 인스턴스를 생성합니다. + +일반 구문은 다음과 같습니다: + +```bash title="구문" +docker pull '<container>' +``` + +- `docker pull`은 컨테이너 시스템에 저장소에서 컨테이너 이미지를 가져오라는 지시입니다. +- `'<container>'`는 컨테이너 이미지의 URI 주소입니다. + +예를 들어 임의의 텍스트 입력을 재미있는 방식으로 표시하기 위해 ASCII 아트를 생성하는 `cowsay`라는 도구의 Python 구현인 [cowpy](https://github.com/jeffbuttars/cowpy)가 포함된 컨테이너 이미지를 가져와 보겠습니다. + +게시된 컨테이너를 찾을 수 있는 다양한 저장소가 있습니다. +[Seqera Containers](https://seqera.io/containers/) 서비스를 사용하여 `cowpy` Conda 패키지에서 이 Docker 컨테이너 이미지를 생성했습니다: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +전체 가져오기 명령을 실행하세요: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "명령 출력" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +이것은 시스템에 지정된 이미지를 다운로드하라고 지시합니다. +다운로드가 완료되면 컨테이너 이미지의 로컬 복사본이 생깁니다. + +#### 4.1.2. 컨테이너 시작 + +컨테이너는 일회성 명령으로 실행할 수 있지만, 대화형으로 사용할 수도 있어 컨테이너 내부에서 셸 프롬프트를 제공하고 명령으로 놀 수 있습니다. + +일반 구문은 다음과 같습니다: + +```bash title="구문" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'`는 컨테이너 시스템에 컨테이너 이미지에서 컨테이너 인스턴스를 시작하고 그 안에서 명령을 실행하라는 지시입니다. +- `--rm`은 명령이 완료된 후 컨테이너 인스턴스를 종료하라고 시스템에 지시합니다. + +완전히 조립된 컨테이너 실행 명령은 다음과 같습니다: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +이 명령을 실행하면 프롬프트가 `(base) root@b645838b3314:/tmp#`과 같은 것으로 변경되어 이제 컨테이너 내부에 있음을 나타냅니다. + +`ls`를 실행하여 디렉토리 내용을 나열하여 이를 확인할 수 있습니다: + +```bash +ls / +``` + +??? success "명령 출력" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +컨테이너 내부의 파일 시스템이 호스트 시스템의 파일 시스템과 다르다는 것을 볼 수 있습니다. + +!!! Tip + + 컨테이너를 실행할 때 기본적으로 호스트 시스템과 격리됩니다. + 이는 다음 구문을 사용하여 `docker run` 명령의 일부로 볼륨을 마운트하도록 명시적으로 허용하지 않는 한 컨테이너가 호스트 시스템의 파일에 액세스할 수 없음을 의미합니다: + + ```bash title="구문" + -v <outside_path>:<inside_path> + ``` + + 이것은 파일 시스템의 해당 부분에 액세스하는 데 사용할 수 있는 컨테이너 벽을 통해 터널을 효과적으로 설정합니다. + + 이에 대한 자세한 내용은 [Hello Nextflow의 Part 5](../hello_nextflow/05_hello_containers.md)에서 다룹니다. + +#### 4.1.3. `cowpy` 도구 실행 + +컨테이너 내부에서 `cowpy` 명령을 직접 실행할 수 있습니다. + +```bash +cowpy "Hello Containers" +``` + +??? success "명령 출력" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +이것은 지정한 텍스트가 포함된 말풍선이 있는 기본 소 캐릭터(또는 'cowacter')의 ASCII 아트를 생성합니다. + +이제 기본 사용법을 테스트했으니 몇 가지 매개변수를 제공해 볼 수 있습니다. +예를 들어 도구 문서에 따르면 `-c`로 캐릭터를 설정할 수 있습니다. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "명령 출력" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +이번에는 `-c tux` 매개변수를 지정했기 때문에 ASCII 아트 출력에 Linux 펭귄 Tux가 표시됩니다. + +컨테이너 내부에 있으므로 시스템 자체에 라이브러리를 설치할 필요 없이 입력 매개변수를 다양하게 변경하면서 cowpy 명령을 원하는 만큼 실행할 수 있습니다. + +??? tip "다른 사용 가능한 캐릭터" + + 다른 캐릭터를 선택하려면 '-c' 플래그를 사용하세요: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +마음껏 가지고 놀아 보세요. +완료되면 `exit` 명령을 사용하여 컨테이너를 종료하세요: + +```bash +exit +``` + +일반 셸로 돌아옵니다. + +### 4.2. Workflow에서 컨테이너 사용 + +pipeline을 실행할 때 각 단계에서 사용할 컨테이너를 Nextflow에 알려주고, 중요하게도 방금 수행한 모든 작업(컨테이너 가져오기, 시작, 명령 실행 및 완료 시 컨테이너 해제)을 처리하도록 하고 싶습니다. + +좋은 소식: 바로 Nextflow가 우리를 위해 할 일입니다. +각 process에 대해 컨테이너를 지정하기만 하면 됩니다. + +이것이 어떻게 작동하는지 보여주기 위해 세 번째 단계에서 생성된 수집된 인사말 파일에서 `cowpy`를 실행하는 workflow의 또 다른 버전을 만들었습니다. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +이것은 말풍선에 세 개의 인사말이 포함된 ASCII 아트가 포함된 파일을 출력해야 합니다. + +#### 4.2.1. 코드 검토 + +workflow는 `cowpy`를 실행하는 추가 단계를 제외하고 이전 것과 매우 유사합니다. + +??? full-code "전체 코드 파일" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // 모듈 포함 + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // 인사말 출력 + sayHello(greeting_ch) + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + // 모든 인사말을 하나의 파일에 수집 + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy로 인사말의 ASCII 아트 생성 + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +이 workflow가 모듈 파일에서 `cowpy` process를 가져오고 `collectGreetings()` 호출의 출력과 `params.character`라는 입력 매개변수에서 호출하는 것을 볼 수 있습니다. + +```groovy title="2d-container.nf" linenums="25" +// cowpy로 ASCII 아트 생성 +cowpy(collectGreetings.out, params.character) +``` + +ASCII 아트를 생성하기 위해 cowpy 명령을 적용하는 `cowpy` process는 `cowpy.nf` 모듈에 정의되어 있습니다. + +??? full-code "전체 코드 파일" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +`cowpy` process에는 두 개의 입력이 필요합니다: 말풍선에 넣을 텍스트가 포함된 입력 파일의 경로(`input_file`)와 캐릭터 변수의 값입니다. + +중요하게도 이전에 사용한 컨테이너 URI를 가리키는 `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'` 줄도 포함합니다. + +#### 4.2.2. 구성에서 Docker가 활성화되어 있는지 확인 + +`nextflow.config` 구성 파일을 소개하여 이 교육 과정의 Part 3를 약간 앞당기겠습니다. 이것은 Nextflow가 workflow 실행을 구성하는 주요 방법 중 하나입니다. +현재 디렉토리에 `nextflow.config`라는 이름의 파일이 있으면 Nextflow가 자동으로 로드하고 포함된 모든 구성을 적용합니다. + +이를 위해 Docker를 활성화하는 한 줄의 코드가 포함된 `nextflow.config` 파일을 포함했습니다. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +이 구성은 호환되는 컨테이너를 지정하는 모든 process에 대해 Docker를 사용하도록 Nextflow에 지시합니다. + +!!! tip + + 기술적으로 `-with-docker <container>` 매개변수를 사용하여 실행별로 명령줄에서 Docker 실행을 활성화할 수 있습니다. + 그러나 이것은 전체 workflow에 대해 하나의 컨테이너만 지정할 수 있는 반면, 방금 보여드린 접근 방식은 process별로 다른 컨테이너를 지정할 수 있습니다. + 후자는 모듈성, 코드 유지 관리 및 재현성에 훨씬 더 좋습니다. + +#### 4.2.3. Workflow 실행 + +요약하자면, 우리가 실행하려는 것은 다음과 같습니다: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +작동할 것 같나요? + +`-resume` 플래그와 함께 workflow를 실행하고 캐릭터를 turkey로 지정해 보겠습니다. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +처음 세 단계는 이전에 이미 실행했으므로 캐시되었지만 `cowpy` process는 새로운 것이므로 실제로 실행됩니다. + +`results` 디렉토리에서 `cowpy` 단계의 출력을 찾을 수 있습니다. + +??? abstract "파일 내용" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +캐릭터가 수집된 대문자 인사말 파일에서 실행되었기 때문에 모든 인사말을 말하고 있는 것을 볼 수 있습니다. + +더 중요한 것은 cowpy와 모든 종속성을 제대로 설치하지 않고도 pipeline의 일부로 이것을 실행할 수 있었다는 것입니다. +그리고 이제 pipeline을 협력자와 공유하고 위에서 언급한 Docker 또는 그 대안(예: Singularity/Apptainer) 외에는 아무것도 설치할 필요 없이 인프라에서 실행하도록 할 수 있습니다. + +#### 4.2.4. Nextflow가 컨테이너화된 작업을 어떻게 시작했는지 검사 + +이 섹션의 마지막 코다로, `cowpy` process 호출 중 하나의 작업 하위 디렉토리를 살펴보고 Nextflow가 컨테이너와 함께 작동하는 방식에 대해 더 많은 통찰력을 얻어 보겠습니다. + +`nextflow run` 명령의 출력을 확인하여 `cowpy` process의 작업 하위 디렉토리 경로를 찾으세요. +위에 표시된 실행에서 얻은 것을 보면 `cowpy` process의 콘솔 로그 줄은 `[7f/caf718]`로 시작합니다. +이것은 다음 축약된 디렉토리 경로에 해당합니다: `work/7f/caf718`. + +그 디렉토리에서 Nextflow가 pipeline을 실행하는 과정에서 사용자를 대신하여 실행한 모든 명령이 포함된 `.command.run` 파일을 찾을 수 있습니다. + +??? abstract "파일 내용" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + ... + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf71890cce1667c094d880f4b6dcc/.command.sh + } + ``` + +이 파일에서 `nxf_launch`를 검색하면 다음과 같은 것을 볼 수 있습니다: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh +} +``` + +이 시작 명령은 Nextflow가 수동으로 실행할 때와 매우 유사한 `docker run` 명령을 사용하여 process 호출을 시작하고 있음을 보여줍니다. +또한 해당 작업 하위 디렉토리를 컨테이너에 마운트하고, 그에 따라 컨테이너 내부의 작업 디렉토리를 설정하고, `.command.sh` 파일의 템플릿화된 bash 스크립트를 실행합니다. + +이것은 이전 섹션에서 수동으로 수행해야 했던 모든 힘든 작업이 이제 Nextflow에 의해 수행된다는 것을 확인합니다! + +### 요약 + +컨테이너가 소프트웨어 도구 버전을 관리하고 재현성을 보장하는 데 어떤 역할을 하는지 이해합니다. + +더 일반적으로 실제 Nextflow pipeline의 핵심 구성 요소가 무엇이고 어떻게 구성되어 있는지에 대한 기본적인 이해가 있습니다. +Nextflow가 여러 입력을 효율적으로 처리하고, 함께 연결된 여러 단계로 구성된 workflow를 실행하고, 모듈식 코드 구성 요소를 활용하고, 더 큰 재현성과 이식성을 위해 컨테이너를 활용하는 방법의 기본 사항을 알고 있습니다. + +### 다음 단계 + +또 다른 휴식을 취하세요! Nextflow pipeline이 작동하는 방법에 대한 많은 정보였습니다. + +교육의 마지막 섹션에서는 구성 주제에 대해 더 깊이 파고들 것입니다. +인프라에 맞게 pipeline 실행을 구성하고 입력 및 매개변수의 구성을 관리하는 방법을 배웁니다. + +--- + +## 퀴즈 + +<quiz> +Nextflow가 각 process 호출에 대해 별도의 작업 디렉토리를 생성하는 이유는 무엇인가요? +- [ ] 실행 속도를 향상시키기 위해 +- [ ] 메모리 사용량을 줄이기 위해 +- [x] 실행을 격리하고 출력 간의 충돌을 피하기 위해 +- [ ] 병렬 파일 압축을 활성화하기 위해 + +자세히 알아보기: [1.3. 원본 출력 및 로그 찾기](#13-원본-출력-및-로그-찾기) +</quiz> + +<quiz> +workflow를 실행할 때 `-ansi-log false` 옵션은 무엇을 하나요? +- [ ] 모든 콘솔 출력을 비활성화합니다 +- [x] 출력에서 색상을 제거합니다 +- [x] 한 줄에 압축하는 대신 모든 작업 디렉토리 경로를 표시합니다 +- [ ] 상세 디버깅 모드를 활성화합니다 + +자세히 알아보기: [1.3.2. 터미널에 더 많은 세부 정보 표시](#132-터미널에-더-많은-세부-정보-표시) + +이 스타일을 선호하는 경우 다음 환경 변수 중 하나를 사용할 수도 있습니다: + +```bash +export NXF_ANSI_LOG=0 +# 또는 +export NO_COLOR=1 +``` + +</quiz> + +<quiz> +`#!groovy channel.fromPath(params.input).splitCsv().map { line -> line[0] }` 코드에서 `#!groovy .map { line -> line[0] }`는 무엇을 하나요? +- [ ] 빈 줄을 필터링합니다 +- [ ] 줄을 알파벳순으로 정렬합니다 +- [x] 각 CSV 행에서 첫 번째 열을 추출합니다 +- [ ] 줄 수를 셉니다 + +자세히 알아보기: [1.4.1. CSV에서 입력 데이터 로드](#141-csv에서-입력-데이터-로드) +</quiz> + +<quiz> +출력 파일 이름에 입력 값을 포함하는 것이 중요한 이유는 무엇인가요(예: `#!groovy "${greeting}-output.txt"`)? +- [ ] 처리 속도를 향상시키기 위해 +- [ ] resume 기능을 활성화하기 위해 +- [x] 여러 입력을 처리할 때 출력 파일이 서로 덮어쓰지 않도록 방지하기 위해 +- [ ] 파일을 더 쉽게 압축하기 위해 + +자세히 알아보기: [1.4.3. 출력 이름 지정 방법](#143-출력-이름-지정-방법) +</quiz> + +<quiz> +모듈화된 workflow에서 `include` 문의 목적은 무엇인가요? +- [ ] process 코드를 workflow 파일에 복사합니다 +- [x] 외부 모듈 파일에서 process 정의를 가져옵니다 +- [ ] 구성 설정을 포함합니다 +- [ ] 문서 주석을 추가합니다 + +자세히 알아보기: [3. 모듈화된 pipeline 실행](#3-모듈화된-pipeline-실행) +</quiz> + +<quiz> +workflow를 모듈화하고 `-resume`으로 실행하면 어떻게 되나요? +- [ ] 모듈식 process에 대해 캐싱이 비활성화됩니다 +- [ ] 모든 작업을 다시 실행해야 합니다 +- [x] 생성된 작업 스크립트를 기반으로 캐싱이 정상적으로 작동합니다 +- [ ] 기본 workflow 파일만 캐시됩니다 + +자세히 알아보기: [3.2. Workflow 실행](#32-workflow-실행) +</quiz> + +<quiz> +process 정의의 `container` 지시문은 무엇을 지정하나요? +- [ ] process의 작업 디렉토리 +- [ ] 최대 메모리 할당 +- [x] process 실행에 사용할 컨테이너 이미지 URI +- [ ] 출력 파일 형식 + +자세히 알아보기: [4.2. Workflow에서 컨테이너 사용](#42-workflow에서-컨테이너-사용) +</quiz> + +<quiz> +`.command.run` 파일에서 `nxf_launch` 함수에는 무엇이 포함되어 있나요? +- [ ] Nextflow 버전 정보 +- [ ] workflow 매개변수 +- [x] 볼륨 마운트 및 컨테이너 설정이 포함된 `docker run` 명령 +- [ ] process 입력 선언 + +자세히 알아보기: [4.2.4. Nextflow가 컨테이너화된 작업을 어떻게 시작했는지 검사](#424-nextflow가-컨테이너화된-작업을-어떻게-시작했는지-검사) +</quiz> + +<quiz> +Nextflow가 컨테이너화된 process를 실행할 때 자동으로 처리하는 것은 무엇인가요? (해당하는 모든 것을 선택하세요) +- [x] 필요한 경우 컨테이너 이미지 가져오기 +- [x] 작업 디렉토리를 컨테이너에 마운트 +- [x] 컨테이너 내에서 process 스크립트 실행 +- [x] 실행 후 컨테이너 인스턴스 정리 + +자세히 알아보기: [4. 컨테이너화된 소프트웨어 사용](#4-컨테이너화된-소프트웨어-사용) +</quiz> diff --git a/docs/ko/docs/nextflow_run/03_config.md b/docs/ko/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..2e7a68dac0 --- /dev/null +++ b/docs/ko/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# 파트 3: 실행 구성 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 섹션에서는 _workflow 코드 자체를 한 줄도 변경하지 않고_ pipeline의 동작을 사용자 정의하고, 다양한 환경에 적응시키고, 리소스 사용을 최적화하기 위해 Nextflow pipeline의 구성을 관리하는 방법을 살펴봅니다. + +이를 수행하는 여러 가지 방법이 있으며, 조합하여 사용할 수 있고 [여기](https://www.nextflow.io/docs/latest/config.html)에 설명된 우선순위에 따라 해석됩니다. + +과정의 이 부분에서는 Part 2의 컨테이너 섹션에서 이미 접한 `nextflow.config` 파일이라는 가장 간단하고 일반적인 구성 파일 메커니즘을 보여드리겠습니다. + +process 지시문, executor, profile 및 매개변수 파일과 같은 Nextflow 구성의 필수 구성 요소를 살펴볼 것입니다. +이러한 구성 옵션을 효과적으로 활용하는 방법을 배우면 Nextflow pipeline의 유연성, 확장성 및 성능을 최대한 활용할 수 있습니다. + +이러한 구성 요소를 연습하기 위해 이 교육 과정의 Part 2 끝에서 마지막으로 실행한 workflow의 새 복사본인 `3-main.nf`를 실행할 것입니다. + +Hello pipeline에 익숙하지 않거나 복습이 필요하다면 [이 정보 페이지](../info/hello_pipeline.md)를 참조하세요. + +--- + +## 1. Workflow 입력 매개변수 관리 + +??? example "시나리오" + + pipeline을 다운로드했고 동일한 입력 파일과 설정으로 반복적으로 실행하려고 하지만 매번 모든 매개변수를 입력하고 싶지 않습니다. + 또는 명령줄 인수에 익숙하지 않은 동료를 위해 pipeline을 설정하고 있을 수도 있습니다. + +지금까지 작업해 온 것의 단순한 확장인 측면인 입력 매개변수 관리로 시작하겠습니다. + +현재 workflow는 workflow 스크립트 자체의 `params` 블록에 선언된 여러 매개변수 값을 명령줄을 통해 받도록 설정되어 있습니다. +하나는 선언의 일부로 기본값이 설정되어 있습니다. + +그러나 모든 매개변수에 기본값을 설정하거나 명령줄에서 매개변수를 지정하거나 원본 스크립트 파일을 수정하지 않고 기존 기본값을 재정의하고 싶을 수 있습니다. + +이를 수행하는 여러 가지 방법이 있습니다. 매우 일반적으로 사용되는 세 가지 기본 방법을 보여드리겠습니다. + +### 1.1. `nextflow.config`에서 값 설정 + +이것은 가장 간단한 접근 방식이지만, 기본 `nextflow.config` 파일은 모든 실행에 대해 편집하고 싶은 것이 아니기 때문에 가장 유연하지 않을 수 있습니다. +그러나 workflow에서 매개변수를 *선언*하는 것(확실히 거기에 속함)과 *기본값*을 제공하는 것(구성 파일에 더 적합함)의 관심사를 분리하는 이점이 있습니다. + +두 단계로 수행해 보겠습니다. + +#### 1.1.1. 구성 파일에 `params` 블록 생성 + +`nextflow.config` 파일에서 다음 코드를 변경하세요: + +=== "변경 후" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +workflow의 `params` 블록을 구성 파일에 단순히 복사하지 않았습니다. +이미 기본값이 선언된 `batch` 매개변수의 경우 구문이 약간 다릅니다. +workflow 파일에서는 타입이 지정된 선언입니다. +구성에서는 값 할당입니다. + +기술적으로 이것은 workflow 파일에 여전히 지정된 기본값을 재정의하기에 충분합니다. +`batch`의 기본값을 수정하고 workflow를 실행하여 구성 파일에 설정된 값이 workflow 파일에 설정된 값을 재정의하는지 확인할 수 있습니다. + +그러나 구성을 완전히 구성 파일로 이동하는 정신으로 workflow 파일에서 해당 기본값을 완전히 제거해 보겠습니다. + +#### 1.1.2. Workflow 파일에서 `batch`의 기본값 제거 + +`3-main.nf` workflow 파일에서 다음 코드를 변경하세요: + +=== "변경 후" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "변경 전" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +이제 workflow 파일 자체는 이러한 매개변수에 대한 기본값을 설정하지 않습니다. + +#### 1.1.3. Pipeline 실행 + +명령줄에서 매개변수를 지정하지 않고 올바르게 작동하는지 테스트해 보겠습니다. + +```bash +nextflow run 3-main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성합니다. + +최종 ASCII 아트 출력은 `results/3-main/` 디렉토리에 있으며, 이전과 마찬가지로 `cowpy-COLLECTED-batch-output.txt`라는 이름입니다. + +??? abstract "파일 내용" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +기능적으로 이 이동은 아무것도 변경하지 않았지만, 개념적으로 구성 파일에 기본값을 설정하는 것이 약간 더 깔끔합니다. + +### 1.2. 실행별 구성 파일 사용 + +??? example "시나리오" + + 기본 구성 파일을 수정하지 않고 다른 설정으로 실험하고 싶습니다. + +실험을 위한 작업 디렉토리로 사용할 하위 디렉토리에 새 `nextflow.config` 파일을 생성하여 이를 수행할 수 있습니다. + +#### 1.2.1. 빈 구성으로 작업 디렉토리 생성 + +새 디렉토리를 생성하고 그 안으로 이동하는 것으로 시작해 보겠습니다: + +```bash +mkdir -p tux-run +cd tux-run +``` + +그런 다음 해당 디렉토리에 빈 구성 파일을 생성합니다: + +```bash +touch nextflow.config +``` + +이것은 빈 파일을 생성합니다. + +#### 1.2.2. 실험적 구성 설정 + +이제 새 파일을 열고 사용자 정의하려는 매개변수를 추가합니다: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +입력 파일 경로는 디렉토리 구조를 반영해야 합니다. + +#### 1.2.3. Pipeline 실행 + +이제 새 작업 디렉토리 내에서 pipeline을 실행할 수 있습니다. +경로를 적절히 조정해야 합니다! + +```bash +nextflow run ../3-main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +이것은 `tux-run/work/` 및 `tux-run/results/`를 포함하여 `tux-run/` 아래에 새 디렉토리 세트를 생성합니다. + +이 실행에서 Nextflow는 현재 디렉토리의 `nextflow.config`를 pipeline 루트 디렉토리의 `nextflow.config`와 결합하여 기본 캐릭터(turkey)를 tux 캐릭터로 재정의합니다. + +최종 출력 파일에는 인사말을 말하는 tux 캐릭터가 포함되어야 합니다. + +??? abstract "파일 내용" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +이렇게 하면 '일반' 구성을 수정하지 않고 실험할 수 있는 공간이 생겼습니다. + +!!! warning + + 다음 섹션으로 이동하기 전에 이전 디렉토리로 다시 변경해야 합니다! + + ```bash + cd .. + ``` + +이제 매개변수 값을 설정하는 또 다른 유용한 방법을 살펴보겠습니다. + +### 1.3. 매개변수 파일 사용 + +??? example "시나리오" + + 협력자와 정확한 실행 매개변수를 공유하거나 출판물을 위해 기록해야 합니다. + +하위 디렉토리 접근 방식은 실험에 좋지만, 약간의 설정이 필요하고 그에 따라 경로를 조정해야 합니다. +특정 값 세트로 pipeline을 실행하거나 다른 사람이 최소한의 노력으로 할 수 있도록 하려는 경우 더 간단한 접근 방식이 있습니다. + +Nextflow를 사용하면 YAML 또는 JSON 형식의 매개변수 파일을 통해 매개변수를 지정할 수 있어 기본값의 대체 세트와 실행별 매개변수 값을 관리하고 배포하기가 매우 편리합니다. + +#### 1.3.1. 예제 매개변수 파일 검토 + +이를 시연하기 위해 현재 디렉토리에 `test-params.yaml`이라는 예제 매개변수 파일을 제공합니다: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +이 매개변수 파일에는 지정하려는 각 입력에 대한 키-값 쌍이 포함되어 있습니다. +구성 파일과 구문을 비교할 때 등호(`=`) 대신 콜론(`:`)을 사용합니다. +구성 파일은 Groovy로 작성되고 매개변수 파일은 YAML로 작성됩니다. + +!!! info + + 예제로 매개변수 파일의 JSON 버전도 제공하지만 여기서는 실행하지 않겠습니다. + 직접 시도해 보세요. + +#### 1.3.2. Pipeline 실행 + +이 매개변수 파일로 workflow를 실행하려면 기본 명령에 `-params-file <filename>`을 추가하기만 하면 됩니다. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +최종 출력 파일에는 인사말을 말하는 stegosaurus 캐릭터가 포함되어야 합니다. + +??? abstract "파일 내용" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +지정할 매개변수가 몇 개밖에 없을 때 매개변수 파일을 사용하는 것은 과도해 보일 수 있지만, 일부 pipeline은 수십 개의 매개변수를 기대합니다. +이러한 경우 매개변수 파일을 사용하면 방대한 명령줄을 입력하지 않고 workflow 스크립트를 수정하지 않고도 런타임에 매개변수 값을 제공할 수 있습니다. + +또한 협력자에게 매개변수 세트를 배포하거나 예를 들어 출판물의 보충 정보로 사용하기가 더 쉬워집니다. +이렇게 하면 다른 사람들이 작업을 더 재현 가능하게 만들 수 있습니다. + +### 요약 + +workflow 입력 관리를 위한 주요 구성 옵션을 활용하는 방법을 알게 되었습니다. + +### 다음 단계 + +workflow 출력이 게시되는 위치와 방법을 관리하는 방법을 배웁니다. + +--- + +## 2. Workflow 출력 관리 + +??? example "시나리오" + + pipeline이 하드코딩된 디렉토리에 출력을 게시하지만 매번 workflow 코드를 편집하지 않고 프로젝트나 실험 이름별로 결과를 구성하고 싶습니다. + +상속받은 workflow는 workflow 수준 출력 선언에 경로를 사용하며, 이는 유연성이 떨어지고 많은 반복을 포함합니다. + +이를 더 유연하게 구성할 수 있는 몇 가지 일반적인 방법을 살펴보겠습니다. + +### 2.1. `outputDir` 디렉토리 이름 사용자 정의 + +지금까지 실행한 workflow의 각 버전은 출력 정의에 하드코딩된 다른 하위 디렉토리에 출력을 게시했습니다. + +사용자가 구성할 수 있는 매개변수를 사용하도록 변경해 보겠습니다. +이를 위해 완전히 새로운 매개변수를 만들 수도 있지만, `batch` 매개변수가 바로 있으니 사용해 보겠습니다. + +#### 2.1.1. 구성 파일에서 `outputDir` 값 설정 + +Nextflow가 출력을 게시하는 데 사용하는 경로는 `outputDir` 옵션으로 제어됩니다. +모든 출력의 경로를 변경하려면 `nextflow.config` 구성 파일에서 이 옵션의 값을 설정할 수 있습니다. + +`nextflow.config` 파일에 다음 코드를 추가하세요: + +=== "변경 후" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +이것은 내장 기본 경로인 `results/`를 `results/`에 `batch` 매개변수의 값을 하위 디렉토리로 더한 것으로 대체합니다. +원한다면 `results` 부분도 변경할 수 있습니다. + +일시적인 변경의 경우 명령의 `-output-dir` 매개변수를 사용하여 명령줄에서 이 옵션을 설정할 수 있습니다(하지만 그러면 `batch` 매개변수 값을 사용할 수 없습니다). + +#### 2.1.2. 하드코딩된 경로의 반복 부분 제거 + +출력 옵션에 여전히 하위 디렉토리가 하드코딩되어 있으므로 이제 제거해 보겠습니다. + +workflow 파일에서 다음 코드를 변경하세요: + +=== "변경 후" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "변경 전" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +`outputDir` 기본값을 수정하는 대신 각 경로에 `${params.batch}`를 추가할 수도 있었지만, 이것이 더 간결합니다. + +#### 2.1.3. Pipeline 실행 + +명령줄에서 배치 이름을 `outdir`로 설정하여 올바르게 작동하는지 테스트해 보겠습니다. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성하지만, 이번에는 출력을 `results/outdir/` 아래에서 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +이 접근 방식을 사용자 정의 경로 정의와 결합하여 원하는 디렉토리 계층 구조를 구성할 수 있습니다. + +### 2.2. Process별로 출력 구성 + +출력을 더 구성하는 인기 있는 방법 중 하나는 process별로 수행하는 것입니다. 즉, pipeline에서 실행된 각 process에 대해 하위 디렉토리를 만드는 것입니다. + +#### 2.2.1. 출력 경로를 process 이름 참조로 대체 + +출력 경로 선언에서 process 이름을 `<task>.name`으로 참조하기만 하면 됩니다. + +workflow 파일에서 다음 변경을 수행하세요: + +=== "변경 후" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "변경 전" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +이것은 출력 경로 구성에서 남아 있는 하드코딩된 요소를 제거합니다. + +#### 2.2.2. Pipeline 실행 + +명령줄에서 배치 이름을 `pnames`로 설정하여 올바르게 작동하는지 테스트해 보겠습니다. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성하지만, 이번에는 출력을 `results/pnames/` 아래에서 찾을 수 있으며 process별로 그룹화됩니다. + +??? abstract "디렉토리 내용" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +여기서 `intermediates`와 최상위 수준의 최종 출력 간의 구분을 지웠습니다. +물론 이러한 접근 방식을 혼합하여 사용할 수 있습니다. 예를 들어 첫 번째 출력의 경로를 `intermediates/${sayHello.name}`으로 설정할 수 있습니다. + +### 2.3. Workflow 수준에서 게시 모드 설정 + +마지막으로 반복적인 코드의 양을 줄이는 정신으로 출력별 `mode` 선언을 구성의 단일 줄로 대체할 수 있습니다. + +#### 2.3.1. 구성 파일에 `workflow.output.mode` 추가 + +`nextflow.config` 파일에 다음 코드를 추가하세요: + +=== "변경 후" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +`outputDir` 옵션과 마찬가지로 구성 파일에서 `workflow.output.mode`에 값을 부여하면 workflow 파일에 설정된 것을 재정의하기에 충분하지만, 어쨌든 불필요한 코드를 제거해 보겠습니다. + +#### 2.3.2. Workflow 파일에서 출력 모드 제거 + +workflow 파일에서 다음 변경을 수행하세요: + +=== "변경 후" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "변경 전" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +더 간결하지 않나요? + +#### 2.3.3. Pipeline 실행 + +명령줄에서 배치 이름을 `outmode`로 설정하여 올바르게 작동하는지 테스트해 보겠습니다. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +이것은 여전히 이전과 동일한 출력을 생성하지만, 이번에는 출력을 `results/outmode/` 아래에서 찾을 수 있습니다. +여전히 모두 symlink가 아닌 적절한 복사본입니다. + +??? abstract "디렉토리 내용" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +출력별 모드 설정 방식을 여전히 사용하고 싶은 주된 이유는 동일한 workflow 내에서 혼합하여 사용하려는 경우입니다. 즉, 일부 출력은 복사하고 일부는 symlink로 연결하는 경우입니다. + +이 방식으로 사용자 정의할 수 있는 다른 많은 옵션이 있지만, 이를 통해 옵션의 범위와 선호도에 맞게 효과적으로 활용하는 방법에 대한 감각을 얻을 수 있기를 바랍니다. + +### 요약 + +출력이 게시되는 디렉토리의 이름 지정 및 구조와 workflow 출력 게시 모드를 제어하는 방법을 알게 되었습니다. + +### 다음 단계 + +소프트웨어 패키징 기술부터 시작하여 컴퓨팅 환경에 맞게 workflow 구성을 조정하는 방법을 배웁니다. + +--- + +## 3. 소프트웨어 패키징 기술 선택 + +지금까지 입력이 어떻게 들어가고 출력이 어디서 나오는지 제어하는 구성 요소를 살펴보았습니다. 이제 컴퓨팅 환경에 맞게 workflow 구성을 조정하는 데 더 구체적으로 집중할 때입니다. + +그 경로의 첫 번째 단계는 각 단계에서 실행될 소프트웨어 패키지가 어디에서 올 것인지 지정하는 것입니다. +로컬 컴퓨팅 환경에 이미 설치되어 있나요? +이미지를 검색하고 컨테이너 시스템을 통해 실행해야 하나요? +아니면 Conda 패키지를 검색하고 로컬 Conda 환경을 구축해야 하나요? + +이 교육 과정의 맨 처음 부분(Parts 1-4)에서는 workflow에서 로컬로 설치된 소프트웨어만 사용했습니다. +그런 다음 Part 5에서 Docker 컨테이너와 `nextflow.config` 파일을 소개했으며, 이를 사용하여 Docker 컨테이너 사용을 활성화했습니다. + +이제 `nextflow.config` 파일을 통해 대체 소프트웨어 패키징 옵션을 구성하는 방법을 살펴보겠습니다. + +### 3.1. 구성 파일에서 Docker 비활성화 및 Conda 활성화 + +??? example "시나리오" + + 보안상의 이유로 Docker가 허용되지 않는 HPC 클러스터로 pipeline을 이동하고 있습니다. + 클러스터는 Singularity와 Conda를 지원하므로 그에 맞게 구성을 전환해야 합니다. + +Nextflow는 HPC에서 더 널리 사용되는 Singularity와 Conda와 같은 소프트웨어 패키지 관리자를 포함한 여러 컨테이너 기술을 지원합니다. + +Docker 대신 Conda를 사용하도록 구성 파일을 변경할 수 있습니다. +이를 위해 `docker.enabled`의 값을 `false`로 전환하고 Conda 사용을 활성화하는 지시문을 추가합니다: + +=== "변경 후" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +이렇게 하면 Nextflow가 Conda 패키지가 지정된 process에 대해 Conda 환경을 생성하고 활용할 수 있습니다. +즉, 이제 `cowpy` process에 해당 패키지 중 하나를 추가해야 합니다! + +### 3.2. Process 정의에서 Conda 패키지 지정 + +`cowpy` 도구를 포함하는 Conda 패키지의 URI를 이미 검색했습니다: `conda-forge::cowpy==1.1.5` + +이제 `conda` 지시문을 사용하여 `cowpy` process 정의에 URI를 추가합니다: + +=== "변경 후" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "변경 전" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +명확히 말해서 `docker` 지시문을 *대체*하는 것이 아니라 대체 옵션을 *추가*하는 것입니다. + +!!! tip + + 주어진 conda 패키지의 URI를 얻는 몇 가지 방법이 있습니다. + 컨테이너를 생성할 계획이 없더라도 복사하여 붙여넣을 수 있는 URI를 제공하는 [Seqera Containers](https://seqera.io/containers/) 검색 쿼리를 사용하는 것을 권장합니다. + +### 3.3. Conda를 사용할 수 있는지 확인하기 위해 workflow 실행 + +시도해 보겠습니다. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "명령 출력" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +이것은 문제없이 작동하고 이전과 동일한 출력을 `results/conda` 아래에 생성해야 합니다. + +백그라운드에서 Nextflow가 Conda 패키지를 검색하고 환경을 생성했으며, 이는 일반적으로 약간의 작업이 필요합니다. 그래서 직접 수행할 필요가 없어서 좋습니다! + +!!! info + + `cowpy` 패키지가 매우 작기 때문에 빠르게 실행되지만, 큰 패키지로 작업하는 경우 처음에는 평소보다 시간이 조금 더 걸릴 수 있으며, 완료되기 전에 콘솔 출력이 1분 정도 '멈춘' 상태로 유지될 수 있습니다. + 이것은 정상이며 새 패키지를 처음 사용할 때 Nextflow가 수행하는 추가 작업 때문입니다. + +우리 관점에서 보면 백엔드의 메커니즘이 약간 다르더라도 Docker로 실행하는 것과 정확히 동일하게 작동하는 것처럼 보입니다. + +이것은 필요한 경우 Conda 환경으로 실행할 준비가 되었음을 의미합니다. + +??? info "Docker와 Conda 혼합 사용" + + 이러한 지시문은 process별로 할당되므로 '혼합하여 사용'할 수 있습니다. 즉, 사용 중인 컴퓨팅 인프라가 둘 다 지원하는 경우 workflow의 일부 process는 Docker로, 다른 일부는 Conda로 실행하도록 구성할 수 있습니다. + 이 경우 구성 파일에서 Docker와 Conda를 모두 활성화합니다. + 주어진 process에 둘 다 사용 가능한 경우 Nextflow는 컨테이너를 우선시합니다. + + 그리고 앞서 언급했듯이 Nextflow는 여러 다른 소프트웨어 패키징 및 컨테이너 기술을 지원하므로 이 두 가지에만 제한되지 않습니다. + +### 요약 + +각 process가 사용해야 하는 소프트웨어 패키지를 구성하고 기술 간에 전환하는 방법을 알게 되었습니다. + +### 다음 단계 + +Nextflow가 실제로 작업을 수행하는 데 사용하는 실행 플랫폼을 변경하는 방법을 배웁니다. + +--- + +## 4. 실행 플랫폼 선택 + +??? example "시나리오" + + 노트북에서 pipeline을 개발하고 테스트해 왔지만, 이제 수천 개의 샘플에서 실행해야 합니다. + 기관에 Slurm 스케줄러가 있는 HPC 클러스터가 있어 대신 사용하고 싶습니다. + +지금까지 로컬 executor로 pipeline을 실행해 왔습니다. +이것은 Nextflow가 실행 중인 머신에서 각 작업을 실행합니다. +Nextflow가 시작되면 사용 가능한 CPU와 메모리를 확인합니다. +실행할 준비가 된 작업의 리소스가 사용 가능한 리소스를 초과하면 Nextflow는 하나 이상의 이전 작업이 완료되어 필요한 리소스가 확보될 때까지 마지막 작업의 실행을 보류합니다. + +로컬 executor는 편리하고 효율적이지만 단일 머신으로 제한됩니다. 매우 큰 워크로드의 경우 로컬 머신이 병목 현상이 되는 것을 발견할 수 있습니다. 사용 가능한 것보다 더 많은 리소스가 필요한 단일 작업이 있거나, 단일 머신이 실행하기를 기다리는 데 너무 오래 걸리는 작업이 너무 많기 때문입니다. + +Nextflow는 HPC 스케줄러(Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor 등)와 클라우드 실행 백엔드(AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes 등)를 포함한 [많은 다른 실행 백엔드](https://www.nextflow.io/docs/latest/executor.html)를 지원합니다. + +### 4.1. 다른 백엔드 대상으로 지정 + +executor의 선택은 `executor`라는 process 지시문으로 설정됩니다. +기본적으로 `local`로 설정되어 있으므로 다음 구성이 암시됩니다: + +```groovy title="내장 구성" +process { + executor = 'local' +} +``` + +다른 백엔드를 대상으로 executor를 설정하려면 리소스 할당에 대해 위에서 설명한 것과 유사한 구문을 사용하여 원하는 executor를 지정하기만 하면 됩니다(모든 옵션은 [문서](https://www.nextflow.io/docs/latest/executor.html) 참조). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning + + Slurm 스케줄러에 연결하도록 설정되어 있지 않기 때문에 교육 환경에서는 실제로 이것을 테스트할 수 없습니다. + +### 4.2. 실행 매개변수에 대한 백엔드별 구문 처리 + +대부분의 고성능 컴퓨팅 플랫폼은 리소스 할당 요청 및 제한(예: CPU 수 및 메모리)과 사용할 작업 대기열 이름과 같은 특정 매개변수를 지정할 수 있습니다(때로는 필수). + +불행히도 이러한 각 시스템은 작업이 정의되고 관련 스케줄러에 제출되는 방법을 정의하기 위해 다른 기술, 구문 및 구성을 사용합니다. + +??? abstract "예제" + + 예를 들어 "my-science-work" 대기열에서 실행되려면 8개의 CPU와 4GB의 RAM이 필요한 동일한 작업을 백엔드에 따라 다음과 같은 다른 방식으로 표현해야 합니다. + + ```bash title="SLURM 구성 / sbatch로 제출" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="PBS 구성 / qsub로 제출" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="SGE 구성 / qsub로 제출" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +다행히 Nextflow는 이 모든 것을 단순화합니다. +`cpus`, `memory` 및 `queue`(다른 속성은 문서 참조)와 같은 관련 속성을 한 번만 지정할 수 있도록 표준화된 구문을 제공합니다. +그런 다음 런타임에 Nextflow는 해당 설정을 사용하여 executor 설정에 따라 적절한 백엔드별 스크립트를 생성합니다. + +다음 섹션에서 해당 표준화된 구문을 다룰 것입니다. + +### 요약 + +이제 다양한 종류의 컴퓨팅 인프라를 사용하도록 executor를 변경하는 방법을 알게 되었습니다. + +### 다음 단계 + +Nextflow에서 리소스 할당 및 제한을 평가하고 표현하는 방법을 배웁니다. + +--- + +## 5. 컴퓨팅 리소스 할당 제어 + +??? example "시나리오" + + 작업이 메모리 제한을 초과하여 종료되어 클러스터에서 pipeline이 계속 실패합니다. + 또는 사용하지 않는 리소스에 대해 비용이 청구되고 있어 비용을 최적화하고 싶습니다. + +대부분의 고성능 컴퓨팅 플랫폼은 CPU 수 및 메모리와 같은 특정 리소스 할당 매개변수를 지정할 수 있습니다(때로는 필수). + +기본적으로 Nextflow는 각 process에 대해 단일 CPU와 2GB의 메모리를 사용합니다. +해당 process 지시문은 `cpus`와 `memory`라고 하므로 다음 구성이 암시됩니다: + +```groovy title="내장 구성" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +구성 파일에서 추가 process 지시문을 사용하여 모든 process 또는 특정 명명된 process에 대해 이러한 값을 수정할 수 있습니다. +Nextflow는 선택한 executor에 대한 적절한 지침으로 변환합니다. + +그러나 어떤 값을 사용해야 하는지 어떻게 알 수 있을까요? + +### 5.1. 리소스 활용 보고서를 생성하기 위해 workflow 실행 + +??? example "시나리오" + + process에 얼마나 많은 메모리나 CPU가 필요한지 모르며 리소스 낭비나 작업 종료를 피하고 싶습니다. + +process에 얼마나 많은 CPU와 메모리가 필요한지 미리 알지 못하는 경우 리소스 프로파일링을 수행할 수 있습니다. 즉, 일부 기본 할당으로 workflow를 실행하고 각 process가 사용한 양을 기록한 다음 거기서 기본 할당을 조정하는 방법을 추정합니다. + +편리하게도 Nextflow에는 이를 수행하기 위한 내장 도구가 포함되어 있으며 요청 시 보고서를 기꺼이 생성합니다. + +이렇게 하려면 명령줄에 `-with-report <filename>.html`을 추가합니다. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +보고서는 브라우저에서 다운로드하여 열 수 있는 html 파일입니다. 교육 환경에서 보려면 왼쪽의 파일 탐색기에서 마우스 오른쪽 버튼을 클릭하고 `Show preview`를 클릭할 수도 있습니다. + +몇 분 동안 보고서를 살펴보고 리소스 조정 기회를 식별할 수 있는지 확인하세요. +할당된 것의 백분율로 활용 결과를 보여주는 탭을 클릭해야 합니다. +사용 가능한 모든 기능을 설명하는 [문서](https://www.nextflow.io/docs/latest/reports.html)가 있습니다. + +### 5.2. 모든 process에 대한 리소스 할당 설정 + +프로파일링 결과 교육 workflow의 process가 매우 가볍기 때문에 기본 메모리 할당을 process당 1GB로 줄여 보겠습니다. + +`nextflow.config` 파일의 pipeline 매개변수 섹션 앞에 다음을 추가하세요: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +그러면 사용하는 컴퓨팅 양을 줄이는 데 도움이 됩니다. + +### 5.3. 특정 process에 대한 리소스 할당 설정 + +동시에 `cowpy` process가 다른 것보다 더 많은 리소스를 필요로 한다고 가정하여 개별 process에 대한 할당 조정 방법을 시연해 보겠습니다. + +=== "변경 후" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +이 구성을 사용하면 모든 process는 1GB의 메모리와 단일 CPU(암시된 기본값)를 요청하지만, `cowpy` process는 2GB와 2개의 CPU를 요청합니다. + +!!! info + + CPU가 적은 머신에서 process당 높은 수의 CPU를 할당하면 process 호출이 서로 뒤에 대기열에 들어가는 것을 볼 수 있습니다. + 이것은 Nextflow가 사용 가능한 것보다 더 많은 CPU를 요청하지 않도록 하기 때문입니다. + +### 5.4. 업데이트된 구성으로 workflow 실행 + +구성 변경 전후의 성능을 비교할 수 있도록 프로파일링 보고서에 다른 파일 이름을 제공하여 시도해 보겠습니다. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +워크로드가 너무 작기 때문에 실제 차이를 느끼지 못할 것이지만, 이것이 실제 workflow의 성능 및 리소스 요구 사항을 분석하는 데 사용하는 접근 방식입니다. + +process마다 리소스 요구 사항이 다를 때 매우 유용합니다. 추측이 아닌 실제 데이터를 기반으로 각 process에 대해 설정한 리소스 할당을 적정 크기로 조정할 수 있습니다. + +!!! tip + + 이것은 리소스 사용을 최적화하기 위해 할 수 있는 것의 아주 작은 맛보기입니다. + Nextflow 자체에는 리소스 제한으로 인해 실패한 작업을 다시 시도하는 정말 멋진 [동적 재시도 로직](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources)이 내장되어 있습니다. + 또한 Seqera Platform은 리소스 할당을 자동으로 최적화하기 위한 AI 기반 도구도 제공합니다. + +### 5.5. 리소스 제한 추가 + +사용 중인 컴퓨팅 executor와 컴퓨팅 인프라에 따라 할당할 수 있는(또는 해야 하는) 것에 대한 제약이 있을 수 있습니다. +예를 들어 클러스터에서 특정 제한 내에 있어야 할 수 있습니다. + +`resourceLimits` 지시문을 사용하여 관련 제한을 설정할 수 있습니다. process 블록에서 단독으로 있을 때 구문은 다음과 같습니다: + +```groovy title="구문 예제" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow는 지정한 executor에 따라 이러한 값을 적절한 지침으로 변환합니다. + +교육 환경에서 관련 인프라에 액세스할 수 없으므로 이것을 실행하지 않겠습니다. +그러나 이러한 제한을 초과하는 리소스 할당으로 workflow를 실행한 다음 `.command.run` 스크립트 파일에서 `sbatch` 명령을 찾아보면 executor에 실제로 전송되는 요청이 `resourceLimits`에서 지정한 값으로 제한되는 것을 볼 수 있습니다. + +??? info "기관 참조 구성" + + nf-core 프로젝트는 다양한 HPC 및 클라우드 executor를 포괄하는 전 세계 여러 기관에서 공유하는 [구성 파일 모음](https://nf-co.re/configs/)을 컴파일했습니다. + + 이러한 공유 구성은 해당 기관의 구성을 바로 활용할 수 있는 해당 기관에서 근무하는 사람들과 자체 인프라에 대한 구성을 개발하려는 사람들의 모델로 모두 가치가 있습니다. + +### 요약 + +리소스 활용을 평가하기 위한 프로파일링 보고서를 생성하고 모든 process 및/또는 개별 process에 대한 리소스 할당을 수정하고 HPC에서 실행하기 위한 리소스 제한을 설정하는 방법을 알게 되었습니다. + +### 다음 단계 + +사전 설정 구성 프로필을 설정하고 런타임에 전환하는 방법을 배웁니다. + +--- + +## 6. 프로필을 사용하여 사전 설정 구성 간 전환 + +??? example "시나리오" + + 개발을 위해 노트북에서 pipeline을 실행하고 프로덕션 실행을 위해 기관의 HPC에서 정기적으로 전환합니다. + 환경을 전환할 때마다 구성 설정을 수동으로 변경하는 것이 지겹습니다. + +작업 중인 프로젝트나 사용 중인 컴퓨팅 환경에 따라 pipeline 구성을 사용자 정의할 수 있는 여러 가지 방법을 보여드렸습니다. + +사용 중인 컴퓨팅 인프라에 따라 대체 설정 간에 전환하고 싶을 수 있습니다. 예를 들어 노트북에서 로컬로 개발하고 소규모 테스트를 실행한 다음 HPC 또는 클라우드에서 전체 규모 워크로드를 실행할 수 있습니다. + +Nextflow를 사용하면 다양한 구성을 설명하는 프로필을 원하는 수만큼 설정한 다음 구성 파일 자체를 수정하지 않고 명령줄 인수를 사용하여 런타임에 선택할 수 있습니다. + +### 6.1. 로컬 개발과 HPC 실행 간 전환을 위한 프로필 생성 + +Docker 컨테이너를 사용하는 일반 컴퓨터에서 소규모 로드를 실행하기 위한 프로필과 Conda 패키지를 사용하는 Slurm 스케줄러가 있는 대학 HPC에서 실행하기 위한 프로필의 두 가지 대체 프로필을 설정해 보겠습니다. + +#### 6.1.1. 프로필 설정 + +`nextflow.config` 파일의 pipeline 매개변수 섹션 다음이지만 출력 설정 앞에 다음을 추가하세요: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +대학 HPC의 경우 리소스 제한도 지정하고 있습니다. + +#### 6.1.2. 프로필로 workflow 실행 + +Nextflow 명령줄에서 프로필을 지정하려면 `-profile` 인수를 사용합니다. + +`my_laptop` 구성으로 workflow를 실행해 보겠습니다. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +보시다시피 런타임에 구성 간에 매우 편리하게 전환할 수 있습니다. + +!!! warning + + Slurm 스케줄러에 액세스할 수 없으므로 `univ_hpc` 프로필은 교육 환경에서 제대로 실행되지 않습니다. + +향후 이와 항상 함께 발생하는 다른 구성 요소를 발견하면 해당 프로필에 간단히 추가할 수 있습니다. +함께 그룹화하려는 다른 구성 요소가 있는 경우 추가 프로필을 만들 수도 있습니다. + +### 6.2. 테스트 매개변수 프로필 생성 + +??? example "시나리오" + + 다른 사람들이 자체 입력 데이터를 수집하지 않고도 pipeline을 빠르게 시험해 볼 수 있도록 하고 싶습니다. + +프로필은 인프라 구성만을 위한 것이 아닙니다. +workflow 매개변수의 기본값을 설정하여 다른 사람들이 적절한 입력 값을 직접 수집하지 않고도 workflow를 쉽게 시험해 볼 수 있도록 사용할 수도 있습니다. +이것을 매개변수 파일 사용의 대안으로 생각할 수 있습니다. + +#### 6.2.1. 프로필 설정 + +이 컨텍스트에서 기본값을 표현하는 구문은 `test`라는 이름의 프로필에 대해 다음과 같습니다: + +```groovy title="구문 예제" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +workflow에 테스트 프로필을 추가하면 `profiles` 블록은 다음과 같이 됩니다: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +기술 구성 프로필과 마찬가지로 원하는 임의의 이름으로 매개변수를 지정하는 여러 다른 프로필을 설정할 수 있습니다. + +#### 6.2.2. 테스트 프로필로 로컬에서 workflow 실행 + +편리하게도 프로필은 상호 배타적이지 않으므로 `-profile <profile1>,<profile2>` 구문을 사용하여 명령줄에 여러 프로필을 지정할 수 있습니다(프로필 수에 관계없이). + +동일한 구성 요소에 대해 값을 설정하는 프로필을 결합하고 동일한 구성 파일에 설명되어 있는 경우 Nextflow는 마지막으로 읽은 값(즉, 파일에서 나중에 나오는 값)을 사용하여 충돌을 해결합니다. +충돌하는 설정이 다른 구성 소스에 설정된 경우 기본 [우선순위](https://www.nextflow.io/docs/latest/config.html)가 적용됩니다. + +이전 명령에 테스트 프로필을 추가해 보겠습니다: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +이것은 가능한 경우 Docker를 사용하고 `results/test` 아래에 출력을 생성하며, 이번에는 캐릭터가 코믹 듀오 `dragonandcow`입니다. + +??? abstract "파일 내용" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +이것은 workflow 코드와 함께 테스트 데이터 파일을 배포하는 한, 누구나 명령줄이나 매개변수 파일을 통해 자체 입력을 제공하지 않고도 workflow를 빠르게 시험해 볼 수 있음을 의미합니다. + +!!! tip + + 외부에 저장된 대용량 파일에 대한 URL을 가리킬 수 있습니다. + Nextflow는 열린 연결이 있는 한 자동으로 다운로드합니다. + + 자세한 내용은 Side Quest [Working with Files](../side_quests/working_with_files.md)를 참조하세요 + +### 6.3. `nextflow config`를 사용하여 해결된 구성 확인 + +위에서 언급했듯이 때때로 결합하려는 프로필에서 동일한 매개변수를 다른 값으로 설정할 수 있습니다. +그리고 더 일반적으로 구성 요소를 저장할 수 있는 곳이 많고 때때로 동일한 속성이 다른 곳에서 다른 값으로 설정될 수 있습니다. + +Nextflow는 충돌을 해결하기 위해 설정된 [우선순위](https://www.nextflow.io/docs/latest/config.html)를 적용하지만, 직접 결정하기 어려울 수 있습니다. +그리고 충돌이 없더라도 구성될 수 있는 모든 가능한 장소를 찾는 것은 지루할 수 있습니다. + +다행히 Nextflow에는 전체 프로세스를 자동화할 수 있는 `config`라는 편리한 유틸리티 도구가 포함되어 있습니다. + +`config` 도구는 현재 작업 디렉토리의 모든 내용을 탐색하고 모든 구성 파일을 수집한 다음 Nextflow가 workflow를 실행하는 데 사용할 완전히 해결된 구성을 생성합니다. +이렇게 하면 아무것도 시작하지 않고도 어떤 설정이 사용될지 알 수 있습니다. + +#### 6.3.1. 기본 구성 해결 + +기본적으로 적용될 구성을 해결하려면 이 명령을 실행하세요. + +```bash +nextflow config +``` + +??? success "명령 출력" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +이것은 명령줄에서 추가로 지정하지 않으면 얻을 수 있는 기본 구성을 보여줍니다. + +#### 6.3.2. 특정 설정이 활성화된 구성 해결 + +명령줄 매개변수를 제공하면(예: 하나 이상의 프로필을 활성화하거나 매개변수 파일을 로드하는 경우) 명령은 추가로 이를 고려합니다. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "명령 출력" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +이것은 여러 계층의 구성을 포함하는 복잡한 프로젝트에 특히 유용합니다. + +### 요약 + +런타임에 최소한의 번거로움으로 사전 설정 구성을 선택하기 위해 프로필을 사용하는 방법을 알게 되었습니다. +더 일반적으로 다양한 컴퓨팅 플랫폼에 맞게 workflow 실행을 구성하고 분석의 재현성을 향상시키는 방법을 알게 되었습니다. + +### 다음 단계 + +GitHub와 같은 원격 저장소에서 직접 pipeline을 실행하는 방법을 배웁니다. + +--- + +## 7. 원격 저장소에서 pipeline 실행 + +??? example "시나리오" + + nf-core와 같은 잘 확립된 pipeline을 코드를 직접 다운로드하고 관리하지 않고 실행하고 싶습니다. + +지금까지 현재 디렉토리에 있는 workflow 스크립트를 실행해 왔습니다. +실제로는 GitHub와 같은 원격 저장소에 저장된 pipeline을 실행하고 싶을 때가 많습니다. + +Nextflow는 이를 간단하게 만듭니다: 먼저 수동으로 다운로드하지 않고 Git 저장소 URL에서 직접 pipeline을 실행할 수 있습니다. + +### 7.1. GitHub에서 pipeline 실행 + +원격 pipeline을 실행하는 기본 구문은 `nextflow run <repository>`이며, 여기서 `<repository>`는 `nextflow-io/hello`와 같은 GitHub 저장소 경로, 전체 URL 또는 GitLab, Bitbucket 또는 기타 Git 호스팅 서비스의 경로가 될 수 있습니다. + +공식 Nextflow "hello" 데모 pipeline을 실행해 보세요: + +```bash +nextflow run nextflow-io/hello +``` + +원격 pipeline을 처음 실행하면 Nextflow가 이를 다운로드하고 로컬에 캐시합니다. +후속 실행은 업데이트를 명시적으로 요청하지 않는 한 캐시된 버전을 사용합니다. + +### 7.2. 재현성을 위해 버전 지정 + +기본적으로 Nextflow는 기본 브랜치의 최신 버전을 실행합니다. +`-r` 플래그를 사용하여 특정 버전, 브랜치 또는 커밋을 지정할 수 있습니다: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +정확한 버전을 지정하는 것은 재현성에 필수적입니다. + +### 요약 + +GitHub 및 기타 원격 저장소에서 직접 pipeline을 실행하는 방법과 재현성을 위해 버전을 지정하는 방법을 알게 되었습니다. + +### 다음 단계 + +스스로를 크게 칭찬해 주세요! +Nextflow pipeline을 실행하고 관리하기 시작하는 데 필요한 모든 것을 알게 되었습니다. + +이 과정은 여기서 끝나지만, 계속 배우고 싶다면 두 가지 주요 권장 사항이 있습니다: + +- 자체 pipeline을 개발하는 것에 대해 더 깊이 파고들고 싶다면 channel과 연산자에 대해 훨씬 더 자세히 다루지만 이 과정과 동일한 일반적인 진행을 다루는 초보자를 위한 과정인 [Hello Nextflow](../hello_nextflow/index.md)를 살펴보세요. +- 코드에 더 깊이 들어가지 않고 Nextflow pipeline을 실행하는 방법을 계속 배우고 싶다면 매우 인기 있는 [nf-core](https://nf-co.re/) 프로젝트의 pipeline을 찾고 실행하기 위한 도구를 소개하는 [Hello nf-core](../hello_nf-core/index.md)의 첫 번째 부분을 살펴보세요. + +즐거운 시간 되세요! + +--- + +## 퀴즈 + +<quiz> +workflow 파일과 `nextflow.config` 모두에서 매개변수 값이 설정된 경우 어느 것이 우선인가요? +- [ ] workflow 파일 값 +- [x] 구성 파일 값 +- [ ] 먼저 만나는 값 +- [ ] 오류가 발생합니다 + +자세히 알아보기: [1.1. `nextflow.config`에서 값 설정](#11-nextflowconfig에서-값-설정) +</quiz> + +<quiz> +workflow 파일과 구성 파일에서 매개변수 기본값을 설정하는 구문의 차이점은 무엇인가요? +- [ ] 동일한 구문을 사용합니다 +- [x] workflow는 타입이 지정된 선언(`#!groovy param: Type = value`)을 사용하고, 구성은 할당(`#!groovy param = value`)을 사용합니다 +- [ ] 구성은 타입이 지정된 선언을 사용하고, workflow는 할당을 사용합니다 +- [ ] 구성 파일만 기본값을 설정할 수 있습니다 + +자세히 알아보기: [1.1. `nextflow.config`에서 값 설정](#11-nextflowconfig에서-값-설정) +</quiz> + +<quiz> +workflow를 실행할 때 매개변수 파일을 어떻게 지정하나요? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +자세히 알아보기: [1.3. 매개변수 파일 사용](#13-매개변수-파일-사용) +</quiz> + +<quiz> +`outputDir` 구성 옵션은 무엇을 제어하나요? +- [ ] 작업 디렉토리의 위치 +- [x] workflow 출력이 게시되는 기본 경로 +- [ ] 로그 파일 디렉토리 +- [ ] 모듈 파일의 위치 + +자세히 알아보기: [2.1. outputDir 디렉토리 이름 사용자 정의](#21-outputdir-디렉토리-이름-사용자-정의) +</quiz> + +<quiz> +출력 경로 구성에서 process 이름을 동적으로 참조하는 방법은 무엇인가요? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +자세히 알아보기: [2.2. Process별로 출력 구성](#22-process별로-출력-구성) +</quiz> + +<quiz> +Docker와 Conda가 모두 활성화되어 있고 process에 두 지시문이 모두 있는 경우 어느 것이 우선인가요? +- [x] Docker (컨테이너) +- [ ] Conda +- [ ] process에서 먼저 정의된 것 +- [ ] 오류가 발생합니다 + +자세히 알아보기: [3. 소프트웨어 패키징 기술 선택](#3-소프트웨어-패키징-기술-선택) +</quiz> + +<quiz> +Nextflow의 기본 executor는 무엇인가요? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +자세히 알아보기: [4. 실행 플랫폼 선택](#4-실행-플랫폼-선택) +</quiz> + +<quiz> +리소스 활용 보고서를 생성하는 명령은 무엇인가요? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +자세히 알아보기: [5.1. 리소스 활용 보고서를 생성하기 위해 workflow 실행](#51-리소스-활용-보고서를-생성하기-위해-workflow-실행) +</quiz> + +<quiz> +구성 파일에서 `cowpy`라는 특정 process에 대한 리소스 요구 사항을 어떻게 설정하나요? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +자세히 알아보기: [5.3. 특정 process에 대한 리소스 할당 설정](#53-특정-process에-대한-리소스-할당-설정) +</quiz> + +<quiz> +`resourceLimits` 지시문은 무엇을 하나요? +- [ ] 최소 리소스 요구 사항을 설정합니다 +- [ ] process에 리소스를 할당합니다 +- [x] 요청할 수 있는 최대 리소스를 제한합니다 +- [ ] 리소스 사용량을 실시간으로 모니터링합니다 + +자세히 알아보기: [5.5. 리소스 제한 추가](#55-리소스-제한-추가) +</quiz> + +<quiz> +단일 명령에서 여러 프로필을 어떻게 지정하나요? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +자세히 알아보기: [6. 프로필을 사용하여 사전 설정 구성 간 전환](#6-프로필을-사용하여-사전-설정-구성-간-전환) +</quiz> + +<quiz> +Nextflow가 사용할 완전히 해결된 구성을 보여주는 명령은 무엇인가요? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +자세히 알아보기: [6.3. `nextflow config`를 사용하여 해결된 구성 확인](#63-nextflow-config를-사용하여-해결된-구성-확인) +</quiz> + +<quiz> +프로필은 무엇에 사용될 수 있나요? (해당하는 모든 것을 선택하세요) +- [x] 인프라별 설정 정의(executor, 컨테이너) +- [x] 다양한 환경에 대한 리소스 제한 설정 +- [x] 쉬운 workflow 테스트를 위한 테스트 매개변수 제공 +- [ ] 새 process 정의 + +자세히 알아보기: [6. 프로필을 사용하여 사전 설정 구성 간 전환](#6-프로필을-사용하여-사전-설정-구성-간-전환) +</quiz> diff --git a/docs/ko/docs/nextflow_run/index.md b/docs/ko/docs/nextflow_run/index.md new file mode 100644 index 0000000000..949d858fc7 --- /dev/null +++ b/docs/ko/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow workflow 실행 및 관리 + - 출력(결과) 및 로그 파일 찾기 및 해석 + - 간단한 다단계 workflow에서 핵심 Nextflow 구성 요소 인식 + - HPC 및 클라우드를 포함한 일반적인 컴퓨팅 플랫폼에서 실행하도록 pipeline 구성 + - 코드 모듈화 및 소프트웨어 컨테이너를 포함하여 pipeline을 FAIR하게 만드는 재현성, 이식성 및 코드 재사용을 위한 모범 사례 요약 + audience_prerequisites: + - "**대상:** 이 과정은 Nextflow를 처음 접하고 기존 pipeline을 실행하려는 학습자를 위해 설계되었습니다." + - "**기술:** 명령줄, 기본 스크립팅 개념 및 일반적인 파일 형식에 대한 어느 정도의 친숙함이 필요합니다." + - "**도메인:** 모든 연습은 도메인에 구애받지 않으므로 사전 과학 지식이 필요하지 않습니다." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run은 재현 가능하고 확장 가능한 데이터 분석 workflow 실행에 대한 실습 입문 과정입니다.** + +실용적인 예제와 안내된 연습을 통해 pipeline 실행, 파일 및 소프트웨어 종속성 관리, 손쉬운 병렬 실행, 다양한 컴퓨팅 환경에서의 workflow 실행 방법을 포함한 Nextflow 사용의 기본 사항을 배웁니다. + +Nextflow로 workflow를 실행하기 위한 기술과 자신감을 얻게 됩니다. + +<!-- additional_information --> + +## 과정 개요 + +### 학습 내용 + +이 과정은 실습 중심이며, 정보를 점진적으로 소개하는 목표 지향적인 연습으로 구성되어 있습니다. + +텍스트 입력을 처리하는 Nextflow pipeline의 여러 버전을 실행합니다. +단일 단계로 구성된 간단한 버전부터 시작하여 결국 CSV 파일의 표 형식 텍스트 입력을 받아 몇 가지 변환 단계를 거친 후 변환된 텍스트를 말하는 캐릭터의 ASCII 그림을 포함하는 단일 텍스트 파일을 출력하는 다단계 버전으로 진행합니다. + +이 과정은 pipeline 실행에 중점을 둡니다(핵심 `nextflow run` 명령의 이름을 따서 명명됨). +Nextflow pipeline 개발에 대한 입문을 찾고 있다면 [Hello Nextflow](../hello_nextflow/index.md)를 참조하세요. + +### 학습 계획 + +Nextflow로 작성된 pipeline을 실행하고 관리하는 특정 측면에 초점을 맞춘 세 부분으로 나누었습니다. + +| 과정 챕터 | 요약 | 예상 소요 시간 | +| ---------------------------------------------- | ------------------------------------------------------------------------- | -------------- | +| [파트 1: 기본 작업 실행](./01_basics.md) | 간단한 workflow의 실행 및 관리 | 30분 | +| [파트 2: 실제 pipeline 실행](./02_pipeline.md) | 복잡한 입력 처리, 다단계 workflow 실행, 컨테이너 사용 및 손쉬운 병렬 실행 | 60분 | +| [파트 3: 실행 구성](./03_config.md) | pipeline 동작 사용자 정의 및 다양한 컴퓨팅 환경에서의 사용 최적화 | 60분 | + +이 과정이 끝나면 과학 컴퓨팅 요구 사항에 맞는 재현 가능한 workflow를 실행하기 위한 다음 단계를 수행할 준비가 됩니다. + +과정을 시작할 준비가 되셨나요? + +[학습 시작 :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/ko/docs/nextflow_run/next_steps.md b/docs/ko/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..5ccbc82e06 --- /dev/null +++ b/docs/ko/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# 과정 요약 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run 교육 과정을 완료하신 것을 축하합니다! 🎉 + +<!-- placeholder for video --> + +## 여러분의 여정 + +매우 기본적인 workflow로 시작하여 실행하고, 출력을 찾고, 실행을 관리하는 방법을 배웠습니다. +그런 다음 해당 workflow의 점점 더 복잡한 버전을 통해 작업하고 channel과 연산자, 코드 모듈화, 컨테이너를 포함하여 Nextflow pipeline을 구동하는 필수 개념과 메커니즘을 인식하는 방법을 배웠습니다. +마지막으로 선호도와 컴퓨팅 인프라에 맞게 pipeline의 구성을 사용자 정의하는 방법을 배웠습니다. + +### 배운 내용 + +이제 Hello pipeline의 실행을 관리하고, 구조화 방법을 설명하고, 관련된 주요 코드 조각을 식별할 수 있습니다. + +- Hello workflow의 최종 형태는 텍스트 인사말이 포함된 CSV 파일을 입력으로 받습니다. +- 네 단계는 Nextflow process(`sayHello`, `convertToUpper`, `collectGreetings`, `cowpy`)로 구현되어 별도의 모듈 파일에 저장됩니다. +- 결과는 `results/`라는 디렉토리에 게시됩니다. +- pipeline의 최종 출력은 대문자 인사말을 말하는 캐릭터의 ASCII 아트가 포함된 일반 텍스트 파일입니다. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** 각 인사말을 자체 출력 파일에 씁니다(예: "Hello-output.txt") +2. **`convertToUpper`:** 각 인사말을 대문자로 변환합니다(예: "HELLO") +3. **`collectGreetings`:** 모든 대문자 인사말을 단일 배치 파일로 수집합니다 +4. **`cowpy`:** `cowpy` 도구를 사용하여 ASCII 아트를 생성합니다 + +workflow 구성은 유연하고 재현 가능한 방식으로 입력 및 매개변수를 제공하는 것을 지원합니다. + +### 습득한 기술 + +이 실습 과정을 통해 다음 방법을 배웠습니다: + +- 로컬에서 Nextflow workflow 시작 +- Nextflow가 생성한 출력(결과) 및 로그 파일 찾기 및 해석 +- 간단한 다단계 workflow를 구성하는 핵심 Nextflow 구성 요소 인식 +- 연산자 및 channel factory와 같은 다음 단계 개념 설명 +- 다양한 컴퓨팅 환경에 맞게 pipeline 구성 + +이제 기존 Nextflow pipeline을 자신의 작업에 통합하기 위한 기초 지식을 갖추었습니다. + +## 기술 향상을 위한 다음 단계 + +다음에 무엇을 할지에 대한 최고의 제안입니다: + +- Nextflow를 실행만 하지 말고 작성하세요! [Hello Nextflow](../hello_nextflow/index.md)로 Nextflow 개발자가 되세요 +- [Nextflow for Science](../nf4_science/index.md)로 과학적 분석 사용 사례에 Nextflow 적용 +- [Hello nf-core](../hello_nf-core/index.md)로 nf-core 시작하기 +- [디버깅 Side Quest](../side_quests/debugging.md)로 문제 해결 기술 배우기 + +마지막으로 [**Seqera Platform**](https://seqera.io/)을 살펴보시기를 권장합니다. Nextflow 제작자가 개발한 클라우드 기반 플랫폼으로 workflow를 시작하고 관리하고, 데이터를 관리하고, 모든 환경에서 대화형으로 분석을 실행하는 것을 더욱 쉽게 해줍니다. + +## 도움 받기 + +도움 리소스 및 커뮤니티 지원은 [도움말 페이지](../help.md)를 참조하세요. + +## 피드백 설문조사 + +다음으로 넘어가기 전에 과정 설문조사를 완료해 주세요! 여러분의 피드백은 모든 사람을 위한 교육 자료를 개선하는 데 도움이 됩니다. + +[설문조사 참여 :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/ko/docs/nextflow_run/survey.md b/docs/ko/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..bf420fe6c8 --- /dev/null +++ b/docs/ko/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# 피드백 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +다음으로 넘어가기 전에 이 짧은 5개 질문 설문조사를 완료하여 교육을 평가하고, 경험에 대한 피드백을 공유하고, Nextflow 여정에서 도움이 될 수 있는 다른 것들을 알려주세요. + +완료하는 데 1분도 걸리지 않습니다. 모든 사람을 위한 교육 자료 개선에 도움을 주셔서 감사합니다! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/ko/docs/nf4_science/genomics/00_orientation.md b/docs/ko/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..a0e1041f5c --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# 오리엔테이션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +교육 환경에는 이 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 직접 설치할 필요가 없습니다. +그러나 로그인하려면 (무료) 계정이 필요하며, 인터페이스에 익숙해지는 데 몇 분 정도 시간을 할애해야 합니다. + +아직 완료하지 않으셨다면, 더 진행하기 전에 [이 링크](../../../envsetup/)를 따라가 주십시오. + +## 제공되는 자료 + +이 교육 과정 전반에 걸쳐 `nf4-science/genomics/` 디렉토리에서 작업할 것이며, 교육 작업 공간을 열 때 이 디렉토리로 이동해야 합니다. +이 디렉토리에는 필요한 모든 코드 파일, 테스트 데이터 및 보조 파일이 포함되어 있습니다. + +이 디렉토리의 내용을 자유롭게 탐색해 보십시오. 가장 쉬운 방법은 VSCode 인터페이스의 교육 작업 공간 왼쪽에 있는 파일 탐색기를 사용하는 것입니다. +또는 `tree` 명령을 사용할 수 있습니다. +과정 전반에 걸쳐 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간 수정합니다. + +여기서는 두 번째 레벨까지 목차를 생성합니다: + +```bash +tree . -L 2 +``` + +`nf4-science/genomics` 내부에서 이 명령을 실행하면 다음과 같은 출력이 표시됩니다: + +```console title="디렉토리 내용" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "참고" + + 이것이 많아 보여도 걱정하지 마십시오. 과정의 각 단계에서 관련 부분을 다룰 것입니다. + 이것은 단지 개요를 제공하기 위한 것입니다. + +**시작하기 위해 알아야 할 사항에 대한 요약입니다:** + +- **`.nf` 파일**은 과정의 어느 부분에서 사용되는지에 따라 이름이 지정된 워크플로우 스크립트입니다. + +- **`nextflow.config` 파일**은 최소한의 환경 속성을 설정하는 구성 파일입니다. + 지금은 무시하셔도 됩니다. + +- **`data` 디렉토리**에는 입력 데이터와 관련 리소스가 포함되어 있으며, 과정 후반부에 설명됩니다. + +- **`solutions` 디렉토리**에는 과정의 Part 3와 4에서 생성되는 모듈 파일과 테스트 구성이 포함되어 있습니다. + 이는 작업을 확인하고 문제를 해결하기 위한 참조 자료로 사용됩니다. + +!!!tip "팁" + + 어떤 이유로든 이 디렉토리에서 이동한 경우, 항상 다음 명령을 실행하여 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +이제 과정을 시작하려면 이 페이지 오른쪽 하단의 화살표를 클릭하십시오. diff --git a/docs/ko/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/ko/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..fbb49af3b6 --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,923 @@ +# 파트 1: 샘플별 변이 호출 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 첫 번째 파트에서는 개별 시퀀싱 샘플에 GATK 변이 호출을 적용하는 간단한 변이 호출 파이프라인을 구축하는 방법을 보여드립니다. + +### 방법 개요 + +변이 호출은 참조 게놈에 대한 게놈 서열의 변이를 식별하는 것을 목표로 하는 게놈 분석 방법입니다. +여기서는 짧은 변이, 즉 SNP와 indel을 호출하기 위해 설계된 도구와 방법을 사용할 것입니다. + +![GATK 파이프라인](img/gatk-pipeline.png) + +완전한 변이 호출 파이프라인은 일반적으로 참조에 대한 매핑(게놈 정렬이라고도 함)과 변이 필터링 및 우선순위 지정을 포함한 많은 단계를 포함합니다. +간단하게 하기 위해 이 과정의 이 파트에서는 변이 호출 부분에만 집중하겠습니다. + +### 데이터셋 + +다음과 같은 데이터와 관련 리소스를 제공합니다: + +- 인간 염색체 20의 작은 영역(hg19/b37에서)과 그 보조 파일(인덱스 및 서열 사전)로 구성된 **참조 게놈**. +- 가족 3인조(어머니, 아버지, 아들)에 해당하는 **세 개의 전체 게놈 시퀀싱 샘플**로, 파일 크기를 작게 유지하기 위해 염색체 20의 작은 슬라이스 데이터로 부분 집합화되었습니다. + 이는 이미 참조 게놈에 매핑된 Illumina 단일 리드 시퀀싱 데이터이며, [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) 형식(Binary Alignment Map, SAM(Sequence Alignment Map)의 압축 버전)으로 제공됩니다. +- **게놈 간격 목록**, 즉 변이 호출에 적합한 데이터가 있는 샘플의 게놈 좌표로, BED 형식으로 제공됩니다. + +### 워크플로우 + +이 과정의 이 파트에서는 다음을 수행하는 워크플로우를 개발할 것입니다: + +1. [Samtools](https://www.htslib.org/)를 사용하여 각 BAM 입력 파일에 대한 인덱스 파일 생성 +2. 각 BAM 입력 파일에 대해 GATK HaplotypeCaller를 실행하여 VCF(Variant Call Format)로 샘플별 변이 호출 생성 + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note "참고" + + 인덱스 파일은 생물정보학 파일 형식의 일반적인 기능입니다. 이들은 GATK와 같은 도구가 전체 파일을 읽지 않고도 데이터의 하위 집합에 액세스할 수 있도록 하는 메인 파일의 구조에 대한 정보를 포함합니다. + 이는 이러한 파일이 얼마나 커질 수 있는지 때문에 중요합니다. + +--- + +## 0. 워밍업: Samtools 및 GATK 명령을 대화형으로 테스트합니다 + +먼저 워크플로우에 적용하기 전에 명령을 수동으로 시도해보고 싶습니다. +필요한 도구(Samtools 및 GATK)는 GitHub Codespaces 환경에 설치되어 있지 않으므로 컨테이너를 통해 사용할 것입니다([Hello Containers](../../hello_nextflow/05_hello_containers.md) 참조). + +!!! note "참고" + + `pwd`를 입력할 때 표시되는 경로의 마지막 부분이 `genomics`가 되도록 `nf4-science/genomics` 디렉토리에 있는지 확인하십시오. + +### 0.1. Samtools로 BAM 입력 파일 인덱싱 + +Samtools 컨테이너를 가져와서 대화형으로 실행하고 BAM 파일 중 하나에 `samtools index` 명령을 실행할 것입니다. + +#### 0.1.1. Samtools 컨테이너 가져오기 + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.1.2. Samtools 컨테이너를 대화형으로 실행 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.1.3. 인덱싱 명령 실행 + +[Samtools 문서](https://www.htslib.org/doc/samtools-index.html)는 BAM 파일을 인덱싱하기 위해 실행할 명령줄을 제공합니다. + +입력 파일만 제공하면 됩니다. 도구는 입력 파일 이름에 `.bai`를 추가하여 출력 이름을 자동으로 생성합니다. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +이것은 즉시 완료되어야 하며, 이제 원본 BAM 입력 파일과 같은 디렉토리에 `reads_mother.bam.bai`라는 파일이 표시되어야 합니다. + +??? abstract "디렉토리 내용" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Samtools 컨테이너 종료 + +```bash +exit +``` + +### 0.2. GATK HaplotypeCaller로 변이 호출 + +GATK 컨테이너를 가져와서 대화형으로 실행하고 방금 인덱싱한 BAM 파일에 `gatk HaplotypeCaller` 명령을 실행할 것입니다. + +#### 0.2.1. GATK 컨테이너 가져오기 + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.2.2. GATK 컨테이너를 대화형으로 실행 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.2.3. 변이 호출 명령 실행 + +[GATK 문서](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller)는 BAM 파일에서 변이 호출을 수행하기 위해 실행할 명령줄을 제공합니다. + +BAM 입력 파일(`-I`)과 참조 게놈(`-R`), 출력 파일 이름(`-O`) 및 분석할 게놈 간격 목록(`-L`)을 제공해야 합니다. + +그러나 인덱스 파일의 경로를 지정할 필요는 없습니다. 도구는 확립된 명명 및 공동 배치 규칙에 따라 동일한 디렉토리에서 자동으로 찾습니다. +참조 게놈의 보조 파일(인덱스 및 서열 사전 파일, `*.fai` 및 `*.dict`)에도 동일하게 적용됩니다. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +출력 파일 `reads_mother.vcf`는 컨테이너 내의 작업 디렉토리에 생성되므로 출력 파일 경로를 변경하지 않는 한 VS Code 파일 탐색기에 표시되지 않습니다. +그러나 작은 테스트 파일이므로 `cat`으로 열어서 내용을 볼 수 있습니다. +파일의 시작 부분까지 스크롤하면 여러 줄의 메타데이터로 구성된 헤더가 있고, 그 다음에 한 줄에 하나씩 변이 호출 목록이 있습니다. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +각 줄은 샘플의 시퀀싱 데이터에서 식별된 가능한 변이를 설명합니다. VCF 형식 해석에 대한 지침은 [이 유용한 문서](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/)를 참조하십시오. + +출력 VCF 파일에는 GATK가 자동으로 생성한 `reads_mother.vcf.idx`라는 인덱스 파일이 함께 제공됩니다. +이것은 BAM 인덱스 파일과 같은 기능을 하며, 도구가 전체 파일을 로드하지 않고도 데이터의 하위 집합을 찾아서 검색할 수 있도록 합니다. + +#### 0.2.4. GATK 컨테이너 종료 + +```bash +exit +``` + +### 핵심 사항 + +Samtools 인덱싱 및 GATK 변이 호출 명령을 각각의 컨테이너에서 테스트하는 방법을 알게 되었습니다. + +### 다음은? + +동일한 명령을 컨테이너를 사용하여 작업을 실행하는 2단계 워크플로우로 적용하는 방법을 배웁니다. + +--- + +## 1. BAM 파일에 Samtools index를 실행하는 단일 단계 워크플로우 작성 + +워크플로우의 주요 부분을 개괄하는 워크플로우 파일 `genomics-1.nf`를 제공합니다. +기능적이지 않습니다. 그 목적은 실제 워크플로우를 작성하는 데 사용할 골격 역할을 하는 것입니다. + +### 1.1. 인덱싱 프로세스 정의 + +인덱싱 작업을 설명하는 `SAMTOOLS_INDEX`라는 프로세스를 작성하는 것부터 시작하겠습니다. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Generate BAM index file + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +이 교육 시리즈의 파트 1 & 파트 2에서 배운 모든 요소를 인식할 수 있을 것입니다. + +이 프로세스는 `input_bam` 입력을 통해 파일 경로를 전달해야 하므로 다음에 설정하겠습니다. + +### 1.2. 입력 매개변수 선언 추가 + +파일 상단의 `Pipeline parameters` 섹션 아래에 `reads_bam`이라는 CLI 매개변수를 선언하고 기본값을 지정합니다. +이렇게 하면 게으르게 파이프라인을 시작하는 명령을 입력할 때 입력을 지정하지 않을 수 있습니다(개발 목적). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Pipeline parameters + */ +params { + // 기본 입력 + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +이제 프로세스가 준비되었고 실행할 입력을 제공할 매개변수도 있으므로 이들을 함께 연결해 봅시다. + +!!! note "참고" + + `${projectDir}`는 현재 Nextflow 워크플로우 스크립트(`genomics-1.nf`)가 위치한 디렉토리를 가리키는 내장 Nextflow 변수입니다. + + 이를 통해 절대 경로를 하드코딩하지 않고도 워크플로우 리포지토리에 포함된 파일, 데이터 디렉토리 및 기타 리소스를 쉽게 참조할 수 있습니다. + +### 1.3. SAMTOOLS_INDEX를 실행하기 위한 workflow 블록 추가 + +`workflow` 블록에서는 `SAMTOOLS_INDEX` 프로세스에 입력을 공급하기 위한 **채널**을 설정해야 합니다. 그런 다음 프로세스 자체를 호출하여 해당 채널의 내용에 대해 실행할 수 있습니다. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // 입력 채널 생성 (CLI 매개변수를 통한 단일 파일) + reads_ch = channel.fromPath(params.reads_bam) + + // 입력 BAM 파일에 대한 인덱스 파일 생성 + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +workflow 블록에는 두 개의 섹션이 있습니다: + +- `main:`에는 채널 작업 및 프로세스 호출이 포함됩니다 +- `publish:`는 게시해야 하는 출력을 선언하고 명명된 타겟에 할당합니다 + +[Hello Channels](../../hello_nextflow/02_hello_channels.md)에서 사용한 것과 동일한 `.fromPath` channel factory를 사용하고 있음을 알 수 있습니다. +실제로 매우 유사한 작업을 하고 있습니다. +차이점은 Nextflow에게 내용을 읽어들이는 대신 파일 경로 자체를 입력 요소로 채널에 로드하도록 지시한다는 것입니다. + +### 1.4. 결과가 게시되는 위치를 정의하기 위한 output 블록 추가 + +workflow 블록 이후에 워크플로우 출력을 게시할 위치를 지정하는 `output` 블록을 추가합니다. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +`publish:` 섹션의 각 명명된 타겟(예: `bam_index`)은 기본 출력 디렉토리에 상대적인 출력 경로를 구성할 수 있는 자체 블록을 갖습니다. + +!!! note "참고" + + 여기서 사용하는 데이터 파일은 매우 작지만 게놈학에서는 매우 클 수 있습니다. + 기본적으로 Nextflow는 게시 디렉토리의 출력 파일에 대한 심볼릭 링크를 생성하여 불필요한 파일 복사를 방지합니다. + `mode` 옵션(예: `mode 'copy'`)을 사용하여 이 동작을 변경하여 실제 복사본을 대신 생성할 수 있습니다. + `work` 디렉토리를 정리하면 심볼릭 링크가 끊어지므로 프로덕션 워크플로우의 경우 `mode 'copy'`를 사용할 수 있습니다. + +### 1.5. 출력 디렉토리 구성 + +기본 출력 디렉토리는 `outputDir` 구성 옵션을 통해 설정됩니다. `nextflow.config`에 추가하십시오: + +=== "변경 후" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "변경 전" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. 워크플로우를 실행하여 인덱싱 단계가 작동하는지 확인 + +워크플로우를 실행해 봅시다! 상기시키자면, 입력 매개변수를 선언할 때 입력의 기본값을 설정했기 때문에 명령줄에서 입력을 지정할 필요가 없습니다. + +```bash +nextflow run genomics-1.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +작업 디렉토리 또는 결과 디렉토리를 살펴보면 인덱스 파일이 올바르게 생성되었는지 확인할 수 있습니다. + +??? abstract "작업 디렉토리 내용" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "결과 디렉토리 내용" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +여기 있습니다! + +### 핵심 사항 + +게놈학 도구를 단일 단계 Nextflow 워크플로우로 적용하고 컨테이너를 사용하여 실행하는 방법을 알게 되었습니다. + +### 다음은? + +첫 번째 단계의 출력을 소비하는 두 번째 단계를 추가합니다. + +--- + +## 2. 인덱싱된 BAM 파일에 GATK HaplotypeCaller를 실행하는 두 번째 프로세스 추가 + +이제 입력 파일에 대한 인덱스가 있으므로 워크플로우의 흥미로운 부분인 변이 호출 단계 설정으로 넘어갈 수 있습니다. + +### 2.1. 변이 호출 프로세스 정의 + +변이 호출 작업을 설명하는 `GATK_HAPLOTYPECALLER`라는 프로세스를 작성하겠습니다. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Call variants with GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +여기서 각 출력 채널에 고유한 이름을 지정하기 위해 새로운 구문(`emit:`)을 도입했으며, 그 이유는 곧 명확해질 것입니다. + +이 명령은 간단한 인덱싱 작업에 비해 GATK가 분석을 수행하기 위해 더 많은 정보가 필요하기 때문에 훨씬 더 많은 입력을 사용합니다. +그러나 입력 블록에 정의된 입력이 GATK 명령에 나열된 것보다 훨씬 더 많다는 것을 알 수 있습니다. 왜 그럴까요? + +!!! note "참고" + + GATK는 해당 파일을 둘러싼 규칙을 인식하기 때문에 BAM 인덱스 파일과 참조 게놈의 보조 파일을 찾을 줄 압니다. + 그러나 Nextflow는 도메인에 구애받지 않도록 설계되었으며 생물정보학 파일 형식 요구 사항에 대해 아무것도 알지 못합니다. + +런타임에 작업 디렉토리에 해당 파일을 스테이징해야 한다고 Nextflow에 명시적으로 알려야 합니다. 그렇지 않으면 수행하지 않으며 GATK는 인덱스 파일이 누락되었다는 오류를 (올바르게) 발생시킵니다. + +마찬가지로 Nextflow가 후속 단계에서 필요한 경우 해당 파일을 추적하도록 출력 VCF의 인덱스 파일(`"${input_bam}.vcf.idx"` 파일)을 명시적으로 나열해야 합니다. + +### 2.2. 보조 입력에 대한 정의 추가 + +새 프로세스는 추가 파일이 제공될 것으로 예상하므로 `Pipeline parameters` 섹션 아래에 일부 기본값과 함께 CLI 매개변수를 설정합니다(이전과 같은 이유). + +```groovy title="genomics-1.nf" linenums="8" + // 보조 파일 + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. 보조 파일 경로를 보유할 변수 생성 + +메인 데이터 입력은 채널을 통해 동적으로 스트리밍되지만 보조 파일을 처리하는 두 가지 접근 방식이 있습니다. 권장되는 접근 방식은 명시적 채널을 생성하는 것으로, 데이터 흐름을 더 명확하고 일관되게 만듭니다. 또는 더 간단한 경우, 특히 여러 프로세스에서 동일한 파일을 참조해야 할 때 변수를 생성하기 위해 file() 함수를 사용할 수 있습니다. 다만 이것도 암묵적으로 채널을 생성한다는 점에 유의하십시오. <!-- TODO: Clarify: is this still necessary with typed inputs? --> + +workflow 블록에 추가하십시오(`main:` 섹션 내부의 `reads_ch` 생성 후): + +```groovy title="genomics-1.nf" linenums="79" + // 보조 파일(참조 및 인터벌)에 대한 파일 경로 로드 + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +이렇게 하면 보조 파일 경로를 필요한 프로세스에 입력으로 제공할 수 있습니다. + +### 2.4. GATK_HAPLOTYPECALLER를 실행하기 위한 workflow 블록에 호출 추가 + +이제 두 번째 프로세스를 설정하고 모든 입력과 보조 파일이 준비되고 사용 가능하므로 워크플로우 본문에 `GATK_HAPLOTYPECALLER` 프로세스 호출을 추가할 수 있습니다. + +```groovy title="genomics-1.nf" linenums="88" + // 인덱싱된 BAM 파일에서 변이 호출 + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +이 교육 시리즈의 파트 1에서 `*.out` 구문을 인식해야 합니다. Nextflow에게 `SAMTOOLS_INDEX`가 출력한 채널을 가져와서 `GATK_HAPLOTYPECALLER` 프로세스 호출에 연결하도록 지시하고 있습니다. + +!!! note "참고" + + 입력이 프로세스 호출에서 제공되는 순서가 프로세스의 input 블록에 나열된 순서와 정확히 동일하다는 것을 알 수 있습니다. + Nextflow에서 입력은 위치 지정적입니다. 즉, 동일한 순서를 _따라야_ 합니다. 그리고 물론 동일한 수의 요소가 있어야 합니다. + +### 2.5. publish 섹션 및 output 블록 업데이트 + +VCF 출력을 포함하도록 `publish:` 섹션을 업데이트하고 `output` 블록에 해당 타겟을 추가해야 합니다. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. 워크플로우를 실행하여 변이 호출 단계가 작동하는지 확인 + +인덱싱 단계를 다시 실행할 필요가 없도록 `-resume`으로 확장된 워크플로우를 실행해 봅시다. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +이제 콘솔 출력을 보면 두 프로세스가 나열됩니다. + +예상대로 캐싱 덕분에 첫 번째 프로세스는 건너뛰었고, 두 번째 프로세스는 완전히 새로운 것이므로 실행되었습니다. + +결과 디렉토리에서 출력 파일을 찾을 수 있습니다(작업 디렉토리에 대한 심볼릭 링크로). + +??? abstract "디렉토리 내용" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +VCF 파일을 열면 컨테이너에서 GATK 명령을 직접 실행하여 생성한 파일과 동일한 내용을 볼 수 있습니다. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +이것이 연구의 각 샘플에 대해 생성하려는 출력입니다. + +### 핵심 사항 + +보조 파일과 같은 게놈학 파일 형식의 특이성을 처리할 수 있는 실제 분석 작업을 수행하는 매우 기본적인 2단계 워크플로우를 만드는 방법을 알게 되었습니다. + +### 다음은? + +워크플로우가 여러 샘플을 일괄 처리하도록 만듭니다. + +--- + +## 3. 샘플 배치에서 실행되도록 워크플로우 조정 + +단일 샘플에 대한 처리를 자동화할 수 있는 워크플로우를 갖는 것은 좋지만 1000개의 샘플이 있으면 어떻게 될까요? +모든 샘플을 반복하는 bash 스크립트를 작성해야 합니까? + +아니요, 다행히도! 코드를 약간만 수정하면 Nextflow가 이를 처리해 줄 것입니다. + +### 3.1. 입력 매개변수 선언을 세 개의 샘플을 나열하는 배열로 변환 + +`Pipeline parameters` 섹션 아래의 입력 BAM 파일 선언에서 해당 기본 파일 경로를 세 개의 테스트 샘플에 대한 파일 경로를 나열하는 배열로 바꿔 봅시다. + +=== "변경 후" + + ```groovy title="genomics-1.nf" linenums="7" + // 기본 입력 (세 샘플의 배열) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" linenums="7" + // 기본 입력 + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note "참고" + + 타입이 지정된 매개변수 선언(예: `reads_bam: Path`)을 사용하는 경우 배열 값을 할당할 수 없습니다. + 배열의 경우 타입 주석을 생략하십시오. + +그리고 실제로 우리가 해야 할 일은 이것뿐입니다. 워크플로우 본문에서 사용하는 channel factory(`.fromPath`)는 입력 채널에 로드할 여러 파일 경로를 받는 것을 단일 파일 경로를 로드하는 것만큼 기쁘게 여기기 때문입니다. + +!!! note "참고" + + 일반적으로 샘플 목록을 워크플로우 파일에 하드코딩하고 싶지 않지만 여기서는 단순하게 유지하기 위해 그렇게 하고 있습니다. + 이 교육 시리즈의 후반부에서 입력을 처리하는 더 우아한 방법을 제시할 것입니다. + +### 3.2. 워크플로우를 실행하여 세 샘플 모두에서 실행되는지 확인 + +이제 세 개의 테스트 샘플 모두에서 실행되도록 배관이 설정되었으니 워크플로우를 실행해 봅시다. + +```bash +nextflow run genomics-1.nf -resume +``` + +재미있는 점: 이것이 _작동할 수도_ 있고 _실패할 수도_ 있습니다. 예를 들어 다음은 성공한 실행입니다: + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +워크플로우 실행이 성공했다면 다음과 같은 오류가 발생할 때까지 다시 실행하십시오: + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +GATK 명령 오류 출력을 보면 다음과 같은 줄이 있을 것입니다: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +글쎄요, 워크플로우의 첫 번째 단계에서 BAM 파일을 명시적으로 인덱싱했다는 점을 고려하면 이상합니다. 배관에 문제가 있을까요? + +#### 3.2.1. 관련 호출에 대한 작업 디렉토리 확인 + +콘솔 출력에 나열된 실패한 `GATK_HAPLOTYPECALLER` 프로세스 호출의 작업 디렉토리 내부를 살펴보겠습니다. + +??? abstract "디렉토리 내용" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +이 디렉토리에 나열된 BAM 파일과 BAM 인덱스의 이름에 특히 주의하십시오: `reads_son.bam` 및 `reads_father.bam.bai`. + +뭐라고요? Nextflow가 이 프로세스 호출의 작업 디렉토리에 인덱스 파일을 스테이징했지만 잘못된 것입니다. 어떻게 이런 일이 일어날 수 있었을까요? + +#### 3.2.2. [view() 연산자](https://www.nextflow.io/docs/latest/reference/operator.html#view)를 사용하여 채널 내용 검사 + +`GATK_HAPLOTYPER` 프로세스 호출 전에 workflow 본문에 이 두 줄을 추가하십시오: + +```groovy title="genomics-1.nf" linenums="84" + // 임시 진단 + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +그런 다음 워크플로우 명령을 다시 실행하십시오. + +```bash +nextflow run genomics-1.nf +``` + +다시 한 번, 이것이 성공하거나 실패할 수 있습니다. 다음은 성공적인 실행입니다: + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +그리고 다음은 실패한 것입니다: + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +다시 실패하려면 여러 번 실행해야 할 수 있습니다. +이 오류는 개별 프로세스 호출의 실행 시간에 일부 변동성에 의존하기 때문에 일관되게 재현되지 않습니다. + +다음은 실패한 실행에 대해 추가한 두 개의 `.view()` 호출의 출력이 어떻게 보이는지입니다: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +처음 세 줄은 입력 채널에 해당하고 두 번째는 출력 채널에 해당합니다. +세 샘플의 BAM 파일과 인덱스 파일이 같은 순서로 나열되지 않았음을 알 수 있습니다! + +!!! note "참고" + + 여러 요소를 포함하는 채널에서 Nextflow 프로세스를 호출하면 Nextflow는 가능한 한 많이 병렬로 실행하려고 시도하고 사용 가능해지는 순서대로 출력을 수집합니다. + 결과적으로 해당 출력은 원래 입력이 제공된 것과 다른 순서로 수집될 수 있습니다. + +현재 작성된 대로, 우리의 워크플로우 스크립트는 인덱스 파일이 입력이 제공된 것과 동일한 어머니/아버지/아들 순서로 인덱싱 단계에서 나올 것으로 가정합니다. +그러나 이것은 보장되지 않으며, 그래서 때때로(항상 그런 것은 아니지만) 잘못된 파일이 두 번째 단계에서 짝지어집니다. + +이를 해결하려면 BAM 파일과 해당 인덱스 파일이 채널을 통해 함께 이동하도록 해야 합니다. + +!!! tip "팁" + + 워크플로우 코드의 `view()` 문은 아무것도 하지 않으므로 그대로 두는 것은 문제가 되지 않습니다. + 그러나 콘솔 출력이 복잡해지므로 문제 해결을 마치면 제거하는 것이 좋습니다. + +### 3.3. SAMTOOLS_INDEX 프로세스의 출력을 입력 파일과 인덱스를 함께 유지하는 튜플로 변경 + +BAM 파일과 인덱스가 밀접하게 연관되도록 하는 가장 간단한 방법은 인덱스 작업에서 나오는 튜플로 함께 패키징하는 것입니다. + +!!! note "참고" + + **튜플**은 함수에서 여러 값을 반환하는 데 일반적으로 사용되는 유한하고 순서가 지정된 요소 목록입니다. 튜플은 연관성과 순서를 유지하면서 프로세스 간에 여러 입력 또는 출력을 전달하는 데 특히 유용합니다. + +먼저, `SAMTOOLS_INDEX` 프로세스의 출력을 출력 선언에 BAM 파일을 포함하도록 변경하겠습니다. + +=== "변경 후" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +이렇게 하면 각 인덱스 파일이 원본 BAM 파일과 긴밀하게 결합되고 인덱싱 단계의 전체 출력은 파일 쌍을 포함하는 단일 채널이 됩니다. + +### 3.4. GATK_HAPLOTYPECALLER 프로세스의 입력을 튜플로 변경 + +워크플로우의 첫 번째 프로세스 출력의 '형태'를 변경했으므로 일치하도록 두 번째 프로세스의 입력 정의를 업데이트해야 합니다. + +특히 이전에 `GATK_HAPLOTYPECALLER` 프로세스의 input 블록에서 두 개의 별도 입력 경로를 선언했던 곳에서 이제 `SAMTOOLS_INDEX`가 방출한 튜플의 구조와 일치하는 단일 입력을 선언합니다. + +=== "변경 후" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +물론 이제 `GATK_HAPLOTYPECALLER`가 기대하는 입력의 형태를 변경했으므로 워크플로우 본문의 프로세스 호출을 그에 따라 업데이트해야 합니다. + +### 3.5. workflow 블록에서 GATK_HAPLOTYPECALLER 호출 업데이트 + +BAM 파일이 이제 `SAMTOOLS_INDEX`의 채널 출력에 번들로 제공되므로 더 이상 원래 `reads_ch`를 `GATK_HAPLOTYPECALLER` 프로세스에 제공할 필요가 없습니다. + +결과적으로 해당 줄을 삭제하기만 하면 됩니다. + +=== "변경 후" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +인덱스 불일치 문제를 해결하기 위해 필요한 재배선은 이것뿐입니다. + +### 3.6. 튜플에 대한 publish 섹션 및 output 블록 업데이트 + +`SAMTOOLS_INDEX.out`은 이제 BAM과 인덱스를 모두 포함하는 튜플이므로 두 파일이 함께 게시됩니다. +타겟 이름을 `bam_index`에서 `indexed_bam`으로 변경하여 이제 두 파일을 모두 포함한다는 것을 반영합니다. + +=== "변경 후" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +또한 새 타겟 이름을 사용하도록 output 블록을 업데이트해야 합니다: + +=== "변경 후" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "변경 전" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. 워크플로우를 실행하여 매번 세 샘플 모두에서 올바르게 작동하는지 확인 + +물론 증명은 푸딩에 있으므로 앞으로 안정적으로 작동하는지 확인하기 위해 워크플로우를 몇 번 더 실행해 봅시다. + +```bash +nextflow run genomics-1.nf +``` + +이번에는(그리고 매번) 모든 것이 올바르게 실행되어야 합니다: + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +결과 디렉토리에는 이제 VCF 출력과 함께 각 샘플에 대한 BAM 및 BAI 파일(튜플에서)이 모두 포함됩니다: + +??? abstract "결과 디렉토리 내용" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +원한다면 `.view()`를 다시 사용하여 `SAMTOOLS_INDEX` 출력 채널의 내용이 어떻게 diff --git a/docs/ko/docs/nf4_science/genomics/02_joint_calling.md b/docs/ko/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..f667b2e93b --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,940 @@ +# 파트 2: 코호트에 대한 조인트 콜링 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 첫 번째 파트에서는 완전히 선형적이고 각 샘플의 데이터를 독립적으로 처리하는 변이 콜링 파이프라인을 구축했습니다. +그러나 실제 유전체학 사용 사례에서는 일반적으로 여러 샘플의 변이 콜을 함께 살펴봐야 합니다. + +두 번째 파트에서는 채널과 채널 연산자를 사용하여 GATK로 조인트 변이 콜링을 구현하는 방법을 보여드리며, 파트 1의 파이프라인을 기반으로 합니다. + +### 방법 개요 + +이 과정의 첫 번째 파트에서 사용한 GATK 변이 콜링 방법은 단순히 샘플별 변이 콜을 생성했습니다. +각 샘플의 변이를 개별적으로만 보려는 경우에는 괜찮지만, 제한적인 정보만 제공합니다. +여러 샘플에서 변이 콜이 어떻게 다른지 살펴보는 것이 더 흥미로운 경우가 많으며, 이를 위해 GATK는 조인트 변이 콜링이라는 대체 방법을 제공합니다. + +조인트 변이 콜링은 각 샘플에 대해 GVCF(Genomic VCF)라는 특별한 종류의 변이 출력을 생성한 다음, 모든 샘플의 GVCF 데이터를 결합하고 마지막으로 '조인트 유전자형 분석(joint genotyping)' 통계 분석을 실행하는 과정을 포함합니다. + +![조인트 분석](img/joint-calling.png) + +샘플의 GVCF가 특별한 이유는 프로그램이 변이의 증거를 발견한 위치뿐만 아니라 유전체의 대상 영역에 있는 모든 위치에 대한 시퀀스 데이터 통계를 요약하는 레코드를 포함하기 때문입니다. +이는 조인트 유전자형 분석 계산에 매우 중요합니다([추가 자료](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +GVCF는 파트 1에서 사용한 것과 동일한 도구인 GATK HaplotypeCaller에 추가 매개변수(`-ERC GVCF`)를 사용하여 생성됩니다. +GVCF를 결합하는 작업은 GATK GenomicsDBImport로 수행되며, 이는 샘플별 콜을 데이터 저장소(데이터베이스와 유사)로 결합한 다음, 실제 '조인트 유전자형 분석' 분석은 GATK GenotypeGVCFs로 수행됩니다. + +### 워크플로 + +요약하자면, 이 과정의 이 파트에서는 다음을 수행하는 워크플로를 개발할 것입니다: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Samtools를 사용하여 각 BAM 입력 파일에 대한 인덱스 파일 생성 +2. 각 BAM 입력 파일에 대해 GATK HaplotypeCaller를 실행하여 샘플별 유전체 변이 콜의 GVCF 생성 +3. 모든 GVCF를 수집하고 GenomicsDB 데이터 저장소로 결합 +4. 결합된 GVCF 데이터 저장소에 대해 조인트 유전자형 분석을 실행하여 코호트 수준의 VCF 생성 + +이를 파트 1과 동일한 데이터셋에 적용할 것입니다. + +--- + +## 0. 준비 운동: Samtools 및 GATK를 직접 실행 + +이전과 마찬가지로, 워크플로로 적용하기 전에 명령을 수동으로 시도해보고자 합니다. + +!!! note + + 올바른 작업 디렉토리에 있는지 확인하세요: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Samtools로 BAM 입력 파일 인덱싱 + +이 첫 번째 단계는 파트 1과 동일하므로 매우 익숙하게 느껴질 것입니다. 하지만 이번에는 세 개의 샘플 모두에 대해 수행해야 합니다. + +!!! note + + 파이프라인을 통해 이미 세 샘플에 대한 인덱스 파일을 생성했으므로, 결과 디렉토리에서 찾을 수 있습니다. 그러나 수동으로 다시 수행하는 것이 더 깔끔하며, 1분밖에 걸리지 않습니다. + +#### 0.1.1. Samtools 컨테이너를 대화형으로 실행 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.1.2. 세 샘플에 대해 인덱싱 명령 실행 + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +이전과 마찬가지로 해당 BAM 파일과 동일한 디렉토리에 인덱스 파일이 생성됩니다. + +??? abstract "디렉토리 내용" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +이제 세 샘플 모두에 대한 인덱스 파일이 있으므로 각 샘플에 대한 GVCF 생성을 진행할 수 있습니다. + +#### 0.1.3. Samtools 컨테이너 종료 + +```bash +exit +``` + +### 0.2. GATK HaplotypeCaller로 GVCF 모드에서 변이 콜링 + +이 두 번째 단계는 파트 1: Hello Genomics에서 수행한 것과 매우 유사하지만, 이제 'GVCF 모드'에서 GATK를 실행할 것입니다. + +#### 0.2.1. GATK 컨테이너를 대화형으로 실행 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +#### 0.2.2. GVCF 옵션으로 변이 콜링 명령 실행 + +genomic VCF(GVCF)를 생성하기 위해 기본 명령에 `-ERC GVCF` 옵션을 추가하여 HaplotypeCaller의 GVCF 모드를 활성화합니다. + +또한 출력 파일의 파일 확장자를 `.vcf`에서 `.g.vcf`로 변경합니다. +이는 기술적으로 요구 사항은 아니지만 강력히 권장되는 규칙입니다. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +이렇게 하면 컨테이너의 현재 작업 디렉토리에 GVCF 출력 파일 `reads_mother.g.vcf`가 생성됩니다. + +`cat`으로 내용을 보면 파트 1에서 생성한 동등한 VCF보다 훨씬 길다는 것을 알 수 있습니다. 파일의 시작 부분까지 스크롤할 수도 없고, 대부분의 줄이 파트 1의 VCF에서 본 것과 상당히 다릅니다. + +```console title="출력" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +이들은 변이 콜러가 변이의 증거를 발견하지 못한 비변이 영역을 나타내므로, 변이가 없다는 확신 수준을 설명하는 몇 가지 통계를 캡처했습니다. 이를 통해 두 가지 매우 다른 경우를 구별할 수 있습니다: (1) 샘플이 동형접합 참조임을 보여주는 양질의 데이터가 있는 경우, (2) 어느 쪽으로든 결정을 내리기에 충분한 좋은 데이터가 없는 경우. + +GVCF에는 일반적으로 이러한 비변이 줄이 많이 있으며, 그 사이에 소수의 변이 레코드가 흩어져 있습니다. GVCF에서 `head -176`을 실행하여 파일의 처음 176줄만 로드하여 실제 변이 콜을 찾아보세요. + +```console title="출력" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +두 번째 줄은 파일의 첫 번째 변이 레코드를 보여주며, 이는 파트 1에서 살펴본 VCF 파일의 첫 번째 변이에 해당합니다. + +원래 VCF와 마찬가지로 출력 GVCF 파일에도 `reads_mother.g.vcf.idx`라는 인덱스 파일이 함께 제공됩니다. + +#### 0.2.3. 다른 두 샘플에 대해 프로세스 반복 + +조인트 유전자형 분석 단계를 테스트하려면 세 샘플 모두에 대한 GVCF가 필요하므로 지금 수동으로 생성하겠습니다. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +이 작업이 완료되면 현재 디렉토리에 `.g.vcf`로 끝나는 세 개의 파일(샘플당 하나)과 해당 인덱스 파일(`.g.vcf.idx`로 끝남)이 있어야 합니다. + +### 0.3. 조인트 유전자형 분석 실행 + +이제 모든 GVCF가 있으므로 마침내 샘플 코호트에 대한 변이 콜을 생성하는 조인트 유전자형 분석 방법을 시도할 수 있습니다. +복습하자면, 모든 GVCF의 데이터를 데이터 저장소로 결합한 다음, 조인트 유전자형 분석 자체를 실행하여 조인트 콜 변이의 최종 VCF를 생성하는 2단계 방법입니다. + +#### 0.3.1. 모든 샘플별 GVCF 결합 + +이 첫 번째 단계는 GATK의 또 다른 도구인 GenomicsDBImport를 사용하여 모든 GVCF의 데이터를 GenomicsDB 데이터 저장소로 결합합니다. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +이 단계의 출력은 실제로 여러 다른 파일 형태로 결합된 변이 데이터를 보유하는 추가 중첩 디렉토리 세트를 포함하는 디렉토리입니다. +둘러볼 수 있지만 이 데이터 저장소 형식은 사람이 직접 읽도록 의도되지 않았음을 빠르게 알 수 있습니다. + +!!! note + + GATK에는 필요에 따라 데이터 저장소에서 변이 콜 데이터를 검사하고 추출할 수 있는 도구가 포함되어 있습니다. + +#### 0.3.2. 조인트 유전자형 분석 자체 실행 + +이 두 번째 단계는 GATK의 또 다른 도구인 GenotypeGVCFs를 사용하여 코호트의 모든 샘플에서 사용 가능한 데이터를 고려하여 변이 통계 및 개별 유전자형을 다시 계산합니다. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +이렇게 하면 컨테이너의 현재 작업 디렉토리에 VCF 출력 파일 `family_trio.vcf`가 생성됩니다. +또 다른 합리적으로 작은 파일이므로 이 파일을 `cat`하여 내용을 보고 위로 스크롤하여 처음 몇 개의 변이 줄을 찾을 수 있습니다. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +이것은 파트 1에서 생성한 원래 VCF와 더 비슷해 보이지만, 이번에는 세 샘플 모두에 대한 유전자형 수준 정보가 있습니다. +파일의 마지막 세 열은 알파벳 순서로 나열된 샘플의 유전자형 블록입니다. + +첫 번째 변이에 대해 테스트 가족 삼인조에 대해 호출된 유전자형을 살펴보면, 아버지는 이형접합 변이(`0/1`)이고 어머니와 아들은 모두 동형접합 변이(`1/1`)임을 알 수 있습니다. + +이것이 궁극적으로 데이터셋에서 추출하려는 정보입니다! 이제 이 모든 것을 Nextflow 워크플로로 적용하여 대규모로 수행할 수 있습니다. + +#### 0.3.3. GATK 컨테이너 종료 + +```bash +exit +``` + +### 핵심 내용 + +터미널에서 조인트 변이 콜링과 관련된 개별 명령을 실행하여 원하는 정보를 생성할 수 있는지 확인하는 방법을 알게 되었습니다. + +### 다음 단계는? + +이러한 명령을 실제 파이프라인으로 적용합니다. + +--- + +## 1. 샘플별 변이 콜링 단계를 수정하여 GVCF 생성 + +좋은 소식은 파트 1에서 이미 이 작업의 일부를 수행하는 워크플로를 작성했기 때문에 처음부터 다시 시작할 필요가 없다는 것입니다. +그러나 해당 파이프라인은 VCF 파일을 생성하는 반면, 이제 조인트 유전자형 분석을 수행하기 위해 GVCF 파일을 원합니다. +따라서 GVCF 변이 콜링 모드를 활성화하고 출력 파일 확장자를 업데이트하는 것부터 시작해야 합니다. + +!!! note + + 편의를 위해 파트 1의 끝에 있는 GATK 워크플로의 새 복사본으로 작업하되 다른 이름인 `genomics-2.nf`를 사용합니다. + +### 1.1. HaplotypeCaller에 GVCF 출력을 지시하고 출력 확장자 업데이트 + +코드 편집기에서 `genomics-2.nf` 파일을 열어봅시다. +매우 익숙하게 느껴질 것이지만, 예상대로 실행되는지 확인하고 싶다면 자유롭게 실행하세요. + +두 가지 변경부터 시작하겠습니다: + +- GATK HaplotypeCaller 명령에 `-ERC GVCF` 매개변수 추가 +- GATK 규칙에 따라 해당 `.g.vcf` 확장자를 사용하도록 출력 파일 경로 업데이트 + +`-ERC GVCF`를 추가할 때 이전 줄 끝에 백슬래시(`\`)를 추가해야 합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +그리고 이것이 HaplotypeCaller를 VCF 대신 GVCF를 생성하도록 전환하는 데 필요한 전부입니다, 맞죠? + +### 1.2. 파이프라인을 실행하여 GVCF를 생성할 수 있는지 확인 + +Nextflow 실행 명령은 워크플로 파일 이름 자체를 제외하고 이전과 동일합니다. +적절하게 업데이트했는지 확인하세요. + +```bash +nextflow run genomics-2.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +그리고 출력은... 모두 빨간색입니다! 오 이런. + +실행된 명령은 올바르므로 GATK 도구의 동작을 변경하기에 충분하다는 것이 맞았습니다. +하지만 누락된 출력 파일에 대한 줄을 보세요. 뭔가 눈에 띄나요? + +맞습니다, Nextflow에게 새 파일 이름을 예상하도록 알려주는 것을 잊었습니다. 죄송합니다. + +### 1.3. process 출력 블록에서도 출력 파일 확장자 업데이트 + +도구 명령 자체의 파일 확장자만 변경하는 것으로는 충분하지 않습니다. 예상되는 출력 파일 이름이 변경되었음을 Nextflow에게도 알려야 합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. 새 GVCF 출력에 대한 게시 대상 업데이트 + +이제 VCF 대신 GVCF를 생성하므로 더 설명적인 이름을 사용하도록 워크플로의 `publish:` 섹션을 업데이트해야 합니다. +또한 명확성을 위해 GVCF 파일을 자체 하위 디렉토리로 구성합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. 새 디렉토리 구조에 맞게 output 블록 업데이트 + +또한 GVCF 파일을 `gvcf` 하위 디렉토리에 넣도록 `output` 블록을 업데이트해야 합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. 파이프라인 다시 실행 + +이번에는 `-resume`과 함께 실행해봅시다. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +이번에는 작동합니다. + +Nextflow 출력 자체는 다르게 보이지 않지만(일반 VCF 모드에서 성공적인 실행과 비교하여), 이제 세 샘플 모두에 대해 하위 디렉토리에 구성된 `.g.vcf` 파일과 해당 인덱스 파일을 찾을 수 있습니다. + +??? abstract "디렉토리 내용 (심볼릭 링크 단축)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +GVCF 파일 중 하나를 열고 스크롤하면 GATK HaplotypeCaller가 요청에 따라 GVCF 파일을 생성했음을 확인할 수 있습니다. + +### 핵심 내용 + +좋아요, 이번 것은 Nextflow 학습 측면에서 최소한이었습니다... +하지만 process 출력 블록의 중요성을 반복할 좋은 기회였습니다! + +### 다음 단계는? + +채널의 내용을 수집하고 단일 입력으로 다음 process에 전달하는 방법을 배웁니다. + +--- + +## 2. 모든 샘플에서 GVCF 데이터 수집 및 결합 + +이제 샘플별 모든 GVCF의 데이터를 우리가 수행하고자 하는 조인트 유전자형 분석을 지원하는 형태로 결합해야 합니다. + +### 2.1. GVCF를 결합할 process 정의 + +준비 운동 섹션에서 이전에 수행한 작업을 상기시키자면, GVCF를 결합하는 것은 GATK 도구 GenomicsDBImport의 작업이며, 이는 소위 GenomicsDB 형식의 데이터 저장소를 생성합니다. + +준비 운동 섹션에서 이전에 사용한 명령을 기반으로 이것이 어떻게 작동할지 정의하는 새 process를 작성해봅시다. + +```groovy title="genomics-2.nf" linenums="66" +/* + * GVCF를 GenomicsDB 데이터 저장소로 결합 + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +어떻게 생각하시나요, 합리적으로 보이나요? + +연결해서 무슨 일이 일어나는지 봅시다. + +### 2.2. 기본값과 함께 `cohort_name` 매개변수 추가 + +코호트에 대한 임의의 이름을 제공해야 합니다. +교육 시리즈 후반부에서 이러한 종류의 작업에 샘플 메타데이터를 사용하는 방법을 배우게 되지만, 지금은 `params`를 사용하여 CLI 매개변수를 선언하고 편의를 위해 기본값을 제공합니다. + +```groovy title="genomics-2.nf" linenums="16" + // 최종 출력 파일의 기본 이름 + cohort_name: String = "family_trio" +``` + +### 2.3. 샘플 전체에서 GATK_HAPLOTYPECALLER의 출력 수집 + +`GATK_HAPLOTYPECALLER` process의 출력 채널을 그대로 연결하면 Nextflow는 각 샘플 GVCF에 대해 process를 개별적으로 호출합니다. +그러나 세 개의 GVCF(및 인덱스 파일) 모두를 Nextflow가 하나의 process 호출에 함께 전달하는 방식으로 묶고 싶습니다. + +좋은 소식: `collect()` 채널 연산자를 사용하여 이를 수행할 수 있습니다. GATK_HAPLOTYPECALLER 호출 직후 `workflow` 본문에 다음 줄을 추가해봅시다: + +```groovy title="genomics-2.nf" linenums="118" +// 샘플 전체에서 변이 콜링 출력 수집 +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +좀 복잡해 보이나요? 이를 분해하여 일반 언어로 번역해봅시다. + +1. `.out` 속성을 사용하여 참조되는 `GATK_HAPLOTYPECALLER` process의 출력 채널을 가져옵니다. +2. 채널에서 나오는 각 '요소'는 파일 쌍입니다: GVCF와 인덱스 파일이 process 출력 블록에 나열된 순서대로 있습니다. 편리하게도 마지막 세션에서 이 process의 출력 이름을 지정했기 때문에(`emit:` 사용), `.out` 속성 뒤에 `.vcf`를 추가하여 한편으로는 GVCF를, 다른 한편으로는 `.idx`를 추가하여 인덱스 파일을 선택할 수 있습니다. 이러한 출력 이름을 지정하지 않았다면 각각 `.out[0]`과 `.out[1]`로 참조해야 했을 것입니다. +3. `collect()` 채널 연산자를 추가하여 모든 GVCF 파일을 `all_gvcfs_ch`라는 새 채널의 단일 요소로 묶고, 인덱스 파일에 대해서도 동일하게 수행하여 `all_idxs_ch`라는 새 채널을 형성합니다. + +!!! tip + + 여기서 정확히 무슨 일이 일어나고 있는지 상상하기 어렵다면, `view()` 연산자를 사용하여 채널 연산자를 적용하기 전후에 채널 내용을 검사할 수 있다는 것을 기억하세요. + +결과 `all_gvcfs_ch` 및 `all_idxs_ch` 채널은 방금 작성한 `GATK_GENOMICSDB` process에 연결할 것입니다. + +!!! note + + 궁금하실 경우를 대비하여, GATK GenomicsDBImport 명령이 GVCF 파일 경로만 보기를 원하기 때문에 GVCF와 인덱스 파일을 별도로 수집합니다. 다행히 Nextflow가 실행을 위해 모든 파일을 함께 스테이징하므로 파트 1에서 BAM과 인덱스에 대해 했던 것처럼 파일 순서를 걱정할 필요가 없습니다. + +### 2.4. GATK_GENOMICSDB를 실행하기 위해 workflow 블록에 호출 추가 + +process가 있고 입력 채널이 있습니다. process 호출만 추가하면 됩니다. + +```groovy title="genomics-2.nf" linenums="122" + // GVCF를 GenomicsDB 데이터 저장소로 결합 + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +좋아요, 모든 것이 연결되었습니다. + +### 2.5. 워크플로 실행 + +이것이 작동하는지 봅시다. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +`-resume`으로 실행하고 있으므로 상당히 빠르게 실행되지만 실패합니다! + +아. 밝은 면에서, Nextflow가 `GATK_GENOMICSDB` process를 선택했고 특히 한 번만 호출했음을 볼 수 있습니다. +이는 `collect()` 접근 방식이 어느 정도 작동했음을 시사합니다. +하지만 큰 문제가 있습니다. process 호출이 실패했습니다. + +위의 콘솔 출력을 자세히 살펴보면 실행된 명령이 올바르지 않음을 알 수 있습니다. + +오류를 발견할 수 있나요? +이 부분을 보세요: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +단일 `-V` 인수에 대해 `gatk GenomicsDBImport`에 여러 GVCF 파일을 제공했지만, 도구는 각 GVCF 파일에 대해 별도의 `-V` 인수를 예상합니다. + +복습하자면, 컨테이너에서 실행한 명령은 다음과 같습니다: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +즉, GVCF 파일 번들을 적절한 형식의 명령 문자열로 변환해야 합니다. + +### 2.6. 각 입력 GVCF에 대해 별도의 `-V` 인수를 사용하여 명령줄 구성 + +여기서 Groovy를 기반으로 하는 Nextflow가 유용한데, 필요한 명령 문자열을 구성하기 위해 상당히 간단한 문자열 조작을 사용할 수 있기 때문입니다. + +특히 이 구문을 사용합니다: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +다시 한 번, 구성 요소로 분해해봅시다. + +1. 먼저 `all_gvcfs` 입력 채널의 내용을 가져와서 `.collect()`를 적용합니다(이전처럼). +2. 이를 통해 번들의 각 개별 GVCF 파일 경로를 **클로저** `{ gvcf -> "-V ${gvcf}" }`에 전달할 수 있습니다. 여기서 `gvcf`는 해당 GVCF 파일 경로를 나타냅니다. + 클로저는 파일 경로 앞에 `-V `를 추가하는 데 사용하는 미니 함수로, `"-V ${gvcf}"` 형태입니다. +3. 그런 다음 `.join(' ')`을 사용하여 세 문자열을 단일 공백을 구분자로 연결합니다. + +구체적인 예를 들면 다음과 같습니다: + +1. 세 개의 파일이 있습니다: + + `[A.ext, B.ext, C.ext]` + +2. 클로저가 각각을 수정하여 문자열을 생성합니다: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. `.join(' ')` 연산이 최종 문자열을 생성합니다: + + `"-V A.ext -V B.ext -V C.ext"` + +이 문자열이 있으면 `def` 키워드로 정의된 로컬 변수 `gvcfs_line`에 할당할 수 있습니다: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +좋아요, 문자열 조작 작업이 있습니다. 어디에 넣을까요? + +GVCF 파일 경로를 process로 채널링한 _후에_ 수행하고 싶기 때문에 process 정의 내부 어딘가에 이것을 넣고 싶습니다. +Nextflow가 파일 자체를 실행을 위해 올바르게 스테이징하려면 파일 경로로 보아야 하기 때문입니다. + +하지만 process의 _어디에_ 이것을 추가할 수 있을까요? + +재미있는 사실: `script:` 뒤와 `"""` 앞에 임의의 코드를 추가할 수 있습니다! + +좋습니다, 거기에 문자열 조작 줄을 추가하고 생성하는 연결된 문자열을 사용하도록 `gatk GenomicsDBImport` 명령을 업데이트합시다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +이것이 `gatk GenomicsDBImport`에 입력을 올바르게 제공하는 데 필요한 전부일 것입니다. + +!!! tip + + `gatk GenomicsDBImport` 명령을 업데이트할 때 `${gvcfs_line}` 변수를 교체할 때 `-V ` 접두사를 제거했는지 확인하세요. + +### 2.7. 워크플로를 실행하여 예상대로 GenomicsDB 출력을 생성하는지 확인 + +좋습니다, 이것이 문제를 해결했는지 봅시다. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +아하! 이제 작동하는 것 같습니다. + +처음 두 단계는 성공적으로 건너뛰었고 세 번째 단계는 이번에 완벽하게 작동했습니다. +GenomicsDB 데이터 저장소는 작업 디렉토리에 생성되지만 조인트 유전자형 분석에 사용할 중간 형식일 뿐이므로 결과에 게시되지 않습니다. + +참고로, 출력이 단일 파일이 아닌 디렉토리인 것을 처리하기 위해 특별한 작업을 수행할 필요가 없었습니다. + +### 핵심 내용 + +이제 채널에서 출력을 수집하고 다른 process에 단일 입력으로 묶는 방법을 알게 되었습니다. +또한 적절한 구문으로 주어진 도구에 입력을 제공하기 위한 명령줄을 구성하는 방법도 알게 되었습니다. + +### 다음 단계는? + +동일한 process의 일부로 두 번째 명령을 추가하는 방법을 배웁니다. + +--- + +## 3. 동일한 process의 일부로 조인트 유전자형 분석 단계 실행 + +이제 결합된 유전체 변이 콜이 있으므로 조인트 유전자형 분석 도구를 실행할 수 있으며, 이는 실제로 우리가 관심 있는 최종 출력인 코호트 수준 변이 콜의 VCF를 생성합니다. + +물류상의 이유로 동일한 process 내에 조인트 유전자형 분석을 포함하기로 결정했습니다. + +### 3.1. process 이름을 GATK_GENOMICSDB에서 GATK_JOINTGENOTYPING으로 변경 + +process가 하나 이상의 도구를 실행할 것이므로 단일 도구 이름이 아닌 전체 작업을 참조하도록 이름을 변경합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" + /* + * GVCF를 GenomicsDB 데이터 저장소로 결합하고 조인트 유전자형 분석을 실행하여 코호트 수준 콜 생성 + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" + /* + * GVCF를 GenomicsDB 데이터 저장소로 결합 + */ + process GATK_GENOMICSDB { + ``` + +가독성을 극대화하기 위해 process 이름을 가능한 한 설명적으로 유지하는 것을 기억하세요. 동료와 미래의 자신을 위해서입니다! + +### 3.2. GATK_JOINTGENOTYPING process에 조인트 유전자형 분석 명령 추가 + +script 섹션 내부의 첫 번째 명령 뒤에 두 번째 명령을 추가하기만 하면 됩니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +두 명령은 터미널에서 수동으로 실행하는 것과 동일한 방식으로 순차적으로 실행됩니다. + +### 3.3. GATK_JOINTGENOTYPING process 입력 정의에 참조 유전체 파일 추가 + +두 번째 명령은 참조 유전체 파일이 필요하므로 process 입력에 추가해야 합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +입력하기 귀찮아 보일 수 있지만, 한 번만 입력하면 백만 번 워크플로를 실행할 수 있습니다. 그만한 가치가 있나요? + +### 3.4. 코호트 수준 변이 콜의 VCF를 출력하도록 process 출력 정의 업데이트 + +물류상의 이유로만 존재하는 중간 형식인 GenomicsDB 데이터 저장소를 저장하는 데 실제로 관심이 없으므로 원하면 출력 블록에서 제거할 수 있습니다. + +실제로 관심 있는 출력은 조인트 유전자형 분석 명령에 의해 생성된 VCF입니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +거의 다 됐습니다! + +### 3.5. process 호출을 GATK_GENOMICSDB에서 GATK_JOINTGENOTYPING으로 업데이트 + +workflow 본문에서 process 호출 이름을 GATK_GENOMICSDB에서 GATK_JOINTGENOTYPING으로 변경하는 것을 잊지 맙시다. 그리고 조인트 유전자형 분석 도구에 제공해야 하므로 참조 유전체 파일도 입력으로 추가해야 합니다. + +=== "수정 후" + + ```groovy title="genomics-2.nf" linenums="126" + // GVCF를 GenomicsDB 데이터 저장소로 결합하고 조인트 유전자형 분석 적용 + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "수정 전" + + ```groovy title="genomics-2.nf" linenums="126" + // GVCF를 GenomicsDB 데이터 저장소로 결합 + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +이제 process가 완전히 연결되었습니다. + +### 3.6. 조인트 VCF를 publish 섹션에 추가 + +새 process의 조인트 VCF 출력을 게시해야 합니다. +워크플로의 `publish:` 섹션에 다음 줄을 추가하세요: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. output 블록에 조인트 VCF 대상 추가 + +마지막 diff --git a/docs/ko/docs/nf4_science/genomics/03_modules.md b/docs/ko/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..dd004a2cb7 --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# 파트 3: 코드를 모듈로 이동하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 첫 번째 부분에서는 완전히 선형적이며 각 샘플의 데이터를 다른 샘플과 독립적으로 처리하는 변이 호출 파이프라인을 구축했습니다. + +두 번째 부분에서는 채널과 채널 연산자를 사용하여 GATK로 공동 변이 호출을 구현하는 방법을 보여드렸으며, Part 1의 파이프라인을 기반으로 했습니다. + +이 부분에서는 해당 워크플로우의 코드를 모듈로 변환하는 방법을 보여드리겠습니다. 이 교육 부분을 따라하려면 Part 1과 Part 2는 물론 모듈의 기본 사항을 다루는 [Hello Modules](../../../hello_nextflow/hello_modules.md)를 완료해야 합니다. + +--- + +## 0. 준비 운동 + +워크플로우 개발을 시작할 때 모든 것을 하나의 코드 파일에 넣었습니다. +이제 코드를 **모듈화**할 시간입니다. 즉, 프로세스 정의를 모듈로 추출하는 것입니다. + +Part 2와 동일한 워크플로우부터 시작하겠으며, `genomics-3.nf` 파일에 제공되어 있습니다. + +!!! note "참고" + + 올바른 작업 디렉토리에 있는지 확인하십시오: + `cd /workspaces/training/nf4-science/genomics` + +시작점을 확인하기 위해 워크플로우를 실행하십시오: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="출력" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +이제 프로젝트 디렉토리 내에 `work` 디렉토리와 `results_genomics` 디렉토리가 생성됩니다. + +### 요점 정리 + +워크플로우를 모듈화할 준비가 되었습니다. + +### 다음 단계는? + +Genomics 워크플로우의 프로세스를 모듈로 이동합니다. + +--- + +## 1. 프로세스를 모듈로 이동하기 + +[Hello Modules](../../../hello_nextflow/hello_modules.md)에서 배운 것처럼, 프로세스 정의를 임의의 디렉토리에 있는 자체 파일로 복사하기만 하면 모듈을 만들 수 있으며, 해당 파일의 이름은 원하는 대로 지정할 수 있습니다. + +나중에 명확해질 이유로 (특히 테스트를 할 때), 이 교육에서는 파일 이름을 `main.nf`로 지정하고 툴킷과 명령의 이름을 따서 명명된 디렉토리 구조에 배치하는 관례를 따르겠습니다. + +### 1.1. `SAMTOOLS_INDEX` 프로세스를 위한 모듈 생성하기 + +`SAMTOOLS_INDEX` 프로세스의 경우, 'samtools'는 툴킷이고 'index'는 명령입니다. 따라서 `modules/samtools/index` 디렉토리 구조를 만들고 해당 디렉토리 내의 `main.nf` 파일에 `SAMTOOLS_INDEX` 프로세스 정의를 넣겠습니다. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +`main.nf` 파일을 열고 `SAMTOOLS_INDEX` 프로세스 정의를 복사합니다. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * BAM 인덱스 파일 생성 + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +그런 다음 `genomics-3.nf`에서 `SAMTOOLS_INDEX` 프로세스 정의를 제거하고, 다음 프로세스 정의 앞에 모듈에 대한 import 선언을 추가합니다: + +=== "변경 후" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // 모듈 포함 + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * GATK HaplotypeCaller로 변이 호출 + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "변경 전" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * GATK HaplotypeCaller로 변이 호출 + */ + process GATK_HAPLOTYPECALLER { + ``` + +이제 워크플로우를 다시 실행할 수 있으며, 이전과 동일한 방식으로 작동해야 합니다. `-resume` 플래그를 제공하면 새 작업을 실행할 필요조차 없어야 합니다: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. `GATK_HAPLOTYPECALLER` 및 `GATK_JOINTGENOTYPING` 프로세스를 위한 모듈 생성하기 + +나머지 프로세스에 대해서도 동일한 단계를 반복합니다. +각 프로세스에 대해: + +1. 디렉토리 구조 생성 (`modules/gatk/haplotypecaller/` 및 `modules/gatk/jointgenotyping/`) +2. 프로세스 정의를 포함하는 `main.nf` 파일 생성 +3. `genomics-3.nf`에서 프로세스 정의 제거 +4. 모듈에 대한 import 선언 추가 + +완료되면 다음을 실행하여 modules 디렉토리 구조가 올바른지 확인하십시오: + +```bash +tree modules/ +``` + +??? abstract "디렉토리 내용" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +또한 메인 워크플로우 파일의 매개변수 섹션 다음에 다음과 같은 내용이 있어야 합니다: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### 요점 정리 + +Genomics 워크플로우를 예제로 워크플로우를 모듈화하는 연습을 했습니다. + +### 다음 단계는? + +모듈화된 워크플로우를 테스트합니다. + +--- + +## 2. 모듈화된 워크플로우 테스트하기 + +모듈화된 워크플로우를 실행하여 모든 것이 여전히 작동하는지 확인합니다. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="출력" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +파이프라인의 재개 가능성을 포함하여 모든 것이 여전히 작동합니다. +결과는 계속해서 `results_genomics` 디렉토리에 게시됩니다. + +```console title="디렉토리 내용" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### 요점 정리 + +워크플로우를 모듈화했으며 이전과 동일한 방식으로 작동하는지 확인했습니다. + +### 다음 단계는? + +학습한 내용을 검토하고 테스트를 살펴봅니다. + +--- + +## 3. 요약 + +워크플로우를 모듈화했으며 파이프라인 작동 방식에는 아무것도 변경되지 않았습니다. +이는 의도적인 것입니다: 기능에 영향을 주지 않고 코드를 재구성했습니다. + +모듈은 프로세스 로직만 포함하여 깔끔하고 재사용 가능합니다. +메인 스크립트는 무엇이 어디에 게시되는지 제어하는 반면, 모듈은 계산 작업에 집중합니다. + +코드를 더 쉽게 유지 관리할 수 있게 하는 기반을 마련했습니다. +예를 들어, 이제 nf-test 프레임워크를 사용하여 파이프라인에 테스트를 추가할 수 있습니다. +이것이 이 과정의 다음 부분에서 살펴볼 내용입니다. diff --git a/docs/ko/docs/nf4_science/genomics/04_testing.md b/docs/ko/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..7c1fad6a2f --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1180 @@ +# 파트 4: 테스트 추가하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 교육 과정의 첫 번째 파트에서는 완전히 선형적이며 각 샘플의 데이터를 독립적으로 처리하는 변이 호출 파이프라인을 구축했습니다. + +두 번째 파트에서는 GATK를 사용한 공동 변이 호출을 구현하기 위해 채널과 채널 연산자를 사용하는 방법을 보여드렸습니다. + +세 번째 파트에서는 파이프라인을 모듈화했습니다. + +교육의 이번 파트에서는 Nextflow와 잘 통합되며 파이프라인에 모듈 수준 및 workflow 수준 테스트를 추가하는 것을 간단하게 만들어주는 테스트 프레임워크인 [**nf-test**](https://www.nf-test.com/)를 사용하는 방법을 보여드리겠습니다. 이번 파트를 따라하려면 Part 1, Part 2, Part 3뿐만 아니라 nf-test의 기본 사항과 테스트가 중요한 이유를 다루는 [nf-test side quest](../../side_quests/nf-test.md)를 완료해야 합니다. + +--- + +## 0. 워밍업 + +!!! note "참고" + + 올바른 작업 디렉토리에 있는지 확인하십시오: + `cd /workspaces/training/nf4-science/genomics` + +이 교육 과정의 이전 파트를 완료했다면, 적절한 모듈 디렉토리 구조를 갖춘 작동하는 버전의 genomics 파이프라인을 가지고 있어야 합니다. + +??? abstract "디렉토리 내용" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +이 모듈 디렉토리는 필요한 경우 `solutions` 디렉토리에서 찾을 수 있습니다. + +Part 3과 동일한 workflow로 시작하겠습니다. 이는 `genomics-4.nf` 파일에 제공되어 있습니다. [nf-test side quest](../../side_quests/nf-test.md)와 마찬가지로, 이 파이프라인의 세 가지 프로세스와 workflow 수준 테스트에 몇 가지 다른 유형의 테스트를 추가할 것입니다. + +### 0.1. workflow 실행 확인 + +테스트를 추가하기 전에 workflow가 예상대로 실행되는지 확인하십시오. + +```bash +nextflow run genomics-4.nf -resume +``` + +이 교육 과정의 처음부터 작업해 오셨다면 이제 매우 익숙해 보일 것입니다. + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +이전과 마찬가지로 이제 프로젝트 디렉토리 내에 `work` 디렉토리와 `results_genomics` 디렉토리가 생성됩니다. 나중에 테스트에서 이러한 결과를 실제로 사용할 것입니다. 하지만 지금부터는 파이프라인을 테스트하기 위해 `nf-test` 패키지를 사용할 것입니다. + +### 0.2. `nf-test` 초기화 + +[nf-test side quest](../../side_quests/nf-test.md)와 마찬가지로 `nf-test` 패키지를 초기화해야 합니다. + +```bash +nf-test init +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "nf-test.config 내용" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +또한 설정 파일 스텁이 포함된 `tests` 디렉토리를 생성합니다. + +### 핵심 요약 + +이제 genomics 파이프라인에 대한 테스트를 작성할 준비가 되었습니다. + +### 다음 단계는? + +프로세스 호출이 성공했고 올바른 출력을 생성했는지 평가하는 기본 테스트를 작성합니다. + +--- + +## 1. 성공 및 일치하는 출력에 대한 프로세스 테스트 + +BAM 파일에 대한 인덱스 파일을 생성하여 효율적인 임의 접근을 가능하게 하는 `SAMTOOLS_INDEX` 프로세스를 테스트하는 것으로 시작하겠습니다. 이것은 다음과 같은 이유로 좋은 첫 번째 테스트 사례입니다: + +1. 단일하고 명확하게 정의된 입력(BAM 파일)을 가집니다 +2. 예측 가능한 출력(BAI 인덱스 파일)을 생성합니다 +3. 동일한 입력에 대해 출력이 동일해야 합니다 + +### 1.1. 테스트 파일 스텁 생성 + +먼저 테스트 파일 스텁을 생성합니다: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "명령 출력" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +이것은 `main.nf`와 동일한 디렉토리에 파일을 생성합니다. +파일 탐색기에서 디렉토리로 이동하여 파일을 열면 다음 코드가 포함되어 있어야 합니다: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +시작 어설션은 [nf-test side quest](../../side_quests/nf-test.md)에서 익숙해야 합니다: + +- `assert process.success`는 프로세스가 성공적으로 실행되고 오류 없이 완료될 것으로 예상한다는 것을 나타냅니다. +- `snapshot(process.out).match()`는 실행 결과가 이전 실행에서 얻은 결과와 동일할 것으로 예상한다는 것을 나타냅니다(해당되는 경우). + 이에 대해서는 나중에 더 자세히 설명합니다. + +이것을 시작점으로 사용하여 samtools index 프로세스에 대한 올바른 테스트 입력과 해당하는 경우 매개변수를 추가해야 합니다. + +### 1.2. 테스트 파일 이동 및 스크립트 경로 업데이트 + +테스트를 작성하기 전에 파일을 최종 위치로 이동해야 합니다. 각 모듈에 디렉토리를 추가한 이유 중 하나는 이제 각 모듈의 `main.nf` 파일과 함께 위치한 `tests` 디렉토리에 테스트를 배치할 수 있기 때문입니다. 해당 디렉토리를 생성하고 테스트 파일을 그곳으로 이동합니다. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +이제 테스트 파일의 `script` 섹션을 상대 경로로 단순화할 수 있습니다: + +=== "변경 후" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "변경 전" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +이것은 테스트에게 전체 경로를 지정하지 않고도 모듈의 `main.nf` 파일을 찾을 위치를 알려줍니다. + +### 1.3. SAMTOOLS_INDEX에 대한 테스트 입력 제공 + +스텁 파일에는 `samtools index`의 입력에 적합한 실제 테스트 입력으로 교체해야 하는 자리 표시자가 포함되어 있습니다. 적절한 입력은 `data/bam` 디렉토리에서 사용할 수 있는 BAM 파일입니다. + +=== "변경 후" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "변경 전" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. 기능에 따라 테스트 이름 지정 + +이전에 배운 것처럼 테스트 컨텍스트에서 의미가 있는 것으로 테스트 이름을 변경하는 것이 좋은 관행입니다. + +=== "변경 후" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + 이것은 임의의 문자열을 사용하므로 원하는 것을 넣을 수 있습니다. + 여기서는 파일 이름과 형식을 참조하도록 선택합니다. + +=== "변경 전" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. 테스트 실행 및 출력 검사 + +테스트를 실행합니다: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +이전에 배운 것처럼, 이것은 프로세스의 성공에 대한 기본 어설션을 검증하고 프로세스의 출력을 기반으로 스냅샷 파일을 생성했습니다. `tests/modules/samtools/index/tests/main.nf.test.snap` 파일에서 스냅샷 파일의 내용을 볼 수 있습니다: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +테스트를 다시 실행하면 출력이 스냅샷과 동일하기 때문에 통과하는 것을 볼 수 있습니다: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. SAMTOOLS_INDEX에 더 많은 테스트 추가 + +다양한 잠재적 문제를 테스트하기 위해 다양한 입력 파일을 테스트하는 것이 유용할 때가 있습니다. 테스트 데이터의 trio에서 어머니와 아버지의 BAM 파일에 대한 테스트를 추가합니다. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +그런 다음 테스트를 다시 실행할 수 있습니다: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +`--update-snapshot` 매개변수의 효과를 언급하는 경고에 주목하십시오. + +!!! note "참고" + + 여기서는 파이프라인의 과학적 출력을 시연하기 위해 이전에 사용했던 테스트 데이터를 사용하고 있습니다. + 프로덕션 환경에서 이러한 테스트를 운영할 계획이었다면 테스트 목적으로 더 작은 입력을 생성했을 것입니다. + + 일반적으로 프로세스 기능을 평가하는 데 필요하고 충분한 가장 작은 데이터 조각을 사용하여 단위 테스트를 가능한 한 가볍게 유지하는 것이 중요합니다. 그렇지 않으면 총 실행 시간이 심각하게 증가할 수 있습니다. + 실행하는 데 너무 오래 걸리는 테스트 스위트는 신속함을 위해 건너뛸 가능성이 높은 테스트 스위트입니다. + +### 핵심 요약 + +genomics 프로세스에 대한 첫 번째 모듈 테스트를 작성하여 `SAMTOOLS_INDEX`가 다른 BAM 파일에 대해 인덱스 파일을 올바르게 생성하는지 확인했습니다. 테스트 스위트는 다음을 보장합니다: + +1. 프로세스가 성공적으로 실행됩니다 +2. 인덱스 파일이 생성됩니다 +3. 출력이 실행 간에 일관됩니다 +4. 프로세스가 모든 샘플 BAM 파일에 대해 작동합니다 + +### 다음 단계는? + +연결된 프로세스를 처리하기 위해 setup 메서드를 사용하여 genomics workflow의 다른 프로세스에 대한 테스트를 작성하는 방법을 배웁니다. 또한 VCF 파일인 출력에 예상되는 변이 호출이 포함되어 있는지 평가합니다. + +--- + +## 2. 연결된 프로세스에 테스트 추가 및 내용 테스트 + +`GATK_HAPLOTYPECALLER`를 테스트하려면 프로세스에 `SAMTOOLS_INDEX` 출력을 입력으로 제공해야 합니다. `SAMTOOLS_INDEX`를 실행하고 출력을 검색한 다음 workflow의 테스트 데이터와 함께 저장하여 이를 수행할 수 있습니다. 이것은 실제로 세련된 파이프라인에 권장되는 접근 방식이지만, nf-test는 `setup` 메서드를 사용하는 대안적 접근 방식을 제공합니다. + +setup 메서드를 사용하면 테스트 설정의 일부로 `SAMTOOLS_INDEX` 프로세스를 트리거한 다음 그 출력을 `GATK_HAPLOTYPECALLER`의 입력으로 사용할 수 있습니다. 이것에는 비용이 있습니다: `GATK_HAPLOTYPECALLER`에 대한 테스트를 실행할 때마다 `SAMTOOLS_INDEX` 프로세스를 실행해야 합니다. 그러나 아마도 우리는 여전히 workflow를 개발 중이고 나중에 변경해야 할 수 있는 테스트 데이터를 미리 생성하고 싶지 않을 수 있습니다. `SAMTOOLS_INDEX` 프로세스도 매우 빠르므로 출력을 미리 생성하고 저장하는 이점이 무시할 만할 수 있습니다. setup 메서드가 작동하는 방식은 다음과 같습니다. + +### 2.1. 테스트 파일 생성 및 배치 + +이전과 마찬가지로 먼저 파일 스텁을 생성합니다: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "명령 출력" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +다음 테스트 스텁을 생성합니다: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. 테스트 파일 이동 및 스크립트 경로 업데이트 + +모듈의 `main.nf` 파일과 함께 위치한 테스트 파일을 위한 디렉토리를 생성합니다: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +그리고 테스트 스텁 파일을 그곳으로 이동합니다: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +마지막으로 스크립트 경로를 업데이트하는 것을 잊지 마십시오: + +=== "변경 후" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "변경 전" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. setup 메서드를 사용하여 입력 제공 + +`when` 블록 앞에 `setup` 블록을 삽입하여 원본 입력 파일 중 하나에서 `SAMTOOLS_INDEX` 프로세스 실행을 트리거할 수 있습니다. 또한 이전과 마찬가지로 테스트 이름을 의미 있는 것으로 변경하는 것을 기억하십시오. + +=== "변경 후" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "변경 전" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +그런 다음 테스트 입력을 지정하는 `when` 블록에서 해당 프로세스의 출력을 참조할 수 있습니다: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +해당 변경 사항을 적용하고 테스트를 다시 실행합니다: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +이전처럼 스냅샷 파일도 생성합니다. + +### 2.4. 다시 실행하고 실패 관찰 + +흥미롭게도 정확히 같은 명령을 다시 실행하면 이번에는 테스트가 실패합니다. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +오류 메시지는 두 실행의 스냅샷 간에 차이가 있음을 알려줍니다. 구체적으로 VCF 파일에 대한 md5sum 값이 다릅니다. + +왜 그럴까요? 간단히 말해서, HaplotypeCaller 도구는 매번 다른(정의상) 타임스탬프를 VCF 헤더에 포함합니다. +결과적으로, 변이 호출 자체의 내용이 동일하더라도 파일이 동일한 md5sum을 가질 것으로 기대할 수 없습니다. + +이것을 어떻게 처리할까요? + +### 2.5. 내용 어설션 메서드를 사용하여 특정 변이 확인 + +문제를 해결하는 한 가지 방법은 [다른 종류의 어설션](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions)을 사용하는 것입니다. +이 경우 동일성을 주장하는 대신 특정 내용을 확인할 것입니다. +더 정확히는, 도구가 VCF 파일의 라인을 읽고 특정 라인의 존재를 확인하도록 할 것입니다. + +실제로 `then` 블록의 두 번째 어설션을 다음과 같이 교체합니다: + +=== "변경 후" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "변경 전" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +여기서는 VCF 출력 파일의 전체 내용을 읽고 내용 일치를 검색하는데, 이는 작은 테스트 파일에서는 괜찮지만 더 큰 파일에서는 하고 싶지 않을 것입니다. +대신 특정 라인을 읽도록 선택할 수 있습니다. + +이 접근 방식은 테스트할 '신호'로 사용할 것을 더 신중하게 선택해야 합니다. +긍정적인 측면에서, 분석 도구가 추가 개발을 거치면서 '어려운' 기능(예: 희귀 변이)을 일관되게 식별할 수 있는지 매우 정밀하게 테스트하는 데 사용할 수 있습니다. + +### 2.6. 다시 실행하고 성공 관찰 + +이런 식으로 테스트를 수정하면 테스트를 여러 번 실행할 수 있으며 일관되게 통과할 것입니다. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. 더 많은 테스트 추가 + +어머니와 아버지 샘플에 대한 유사한 테스트를 추가합니다: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. 테스트 명령 실행 + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +파이프라인의 두 번째 단계에 대한 기본 테스트 계획이 완료되었습니다. 세 번째이자 마지막 모듈 수준 테스트로 넘어갑니다! + +### 핵심 요약 + +다음을 배웠습니다: + +1. 다른 프로세스의 출력에 의존하는 프로세스를 테스트하는 방법 +2. VCF 출력 파일에서 특정 genomic 변이를 확인하는 방법 +3. 특정 내용을 확인하여 비결정적 출력을 처리하는 방법 +4. 여러 샘플에 걸쳐 변이 호출을 테스트하는 방법 + +### 다음 단계는? + +공동 유전자형 분석 단계에 대해 미리 생성된 테스트 데이터를 사용하는 테스트를 작성하는 방법을 배웁니다. + +--- + +## 3. 미리 생성된 테스트 데이터 사용 + +공동 유전자형 분석 단계의 경우 다른 접근 방식을 사용합니다 - 미리 생성된 테스트 데이터를 사용합니다. 이것은 다음과 같은 경우에 종종 선호됩니다: + +1. 여러 의존성을 가진 복잡한 프로세스 +2. 실행하는 데 오랜 시간이 걸리는 프로세스 +3. 안정적이고 프로덕션 파이프라인의 일부인 프로세스 + +### 3.1. 테스트 데이터 생성 + +이 섹션의 시작 부분에서 생성한 결과를 검사합니다: + +```bash +tree results_genomics/ +``` + +```console title="결과 디렉토리 내용" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +공동 유전자형 분석 단계는 haplotype caller 단계에서 생성된 VCF 파일을 인덱스와 함께 입력으로 필요로 합니다. 그래서 우리가 가지고 있는 결과를 `jointgenotyping` 모듈의 테스트 디렉토리로 복사합시다. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +이제 이 파일들을 공동 유전자형 분석 단계에 대해 작성할 테스트의 입력으로 사용할 수 있습니다. + +### 3.2. 테스트 파일 스텁 생성 + +이전과 마찬가지로 먼저 파일 스텁을 생성합니다: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "명령 출력" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +다음 테스트 스텁을 생성합니다: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. 테스트 파일 이동 및 스크립트 경로 업데이트 + +이번에는 이미 모듈의 `main.nf` 파일과 함께 위치한 테스트 디렉토리가 있으므로 테스트 스텁 파일을 그곳으로 이동할 수 있습니다: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +그리고 스크립트 경로를 업데이트하는 것을 잊지 마십시오: + +=== "변경 후" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "변경 전" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. 입력 제공 + +프로세스 입력 정의를 기반으로 입력을 채우고 그에 따라 테스트 이름을 변경합니다: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. 내용 어설션 사용 + +공동 유전자형 분석 단계의 출력은 또 다른 VCF 파일이므로 다시 내용 어설션을 사용할 것입니다. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +출력 파일에서 특정 변이의 내용을 확인함으로써 이 테스트는 다음을 검증합니다: + +1. 공동 유전자형 분석 프로세스가 성공적으로 실행됩니다 +2. 출력 VCF에 올바른 순서로 세 샘플이 모두 포함됩니다 +3. 특정 변이가 다음과 함께 올바르게 호출됩니다: + - 각 샘플에 대한 정확한 유전자형(아버지는 0/1, 어머니와 아들은 1/1) + - 올바른 읽기 깊이 및 유전자형 품질 + - 대립 유전자 빈도(AF=0.833)와 같은 집단 수준 통계 + +전체 파일을 스냅샷하지는 않았지만 특정 변이를 확인함으로써 공동 유전자형 분석 프로세스가 예상대로 작동하고 있다고 확신할 수 있습니다. + +### 3.6. 테스트 실행 + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +테스트가 통과하여 공동 유전자형 분석 프로세스가 올바르게 다음을 수행함을 확인했습니다: + +1. 개별 샘플 VCF를 결합합니다 +2. 공동 변이 호출을 수행합니다 +3. 실행 간에 일관된 유전자형 호출을 가진 다중 샘플 VCF를 생성합니다 + +### 핵심 요약 + +다음을 배웠습니다: + +- 이전에 생성된 결과를 테스트 입력으로 사용하는 방법 +- 미리 생성된 테스트 데이터를 사용하여 테스트를 작성하는 방법 + +### 다음 단계는? + +전체 변이 호출 파이프라인이 엔드 투 엔드로 작동하는지 확인하기 위해 workflow 수준 테스트를 추가합니다. + +--- + +## 4. workflow 수준 테스트 추가 + +이제 BAM 파일에서 공동 유전자형까지 전체 변이 호출 파이프라인을 테스트할 것입니다. 이것은 다음을 확인합니다: + +1. 모든 프로세스가 함께 올바르게 작동합니다 +2. 단계 간에 데이터가 적절하게 흐릅니다 +3. 최종 변이 호출이 일관됩니다 + +### 4.1. workflow 테스트 생성 + +전체 파이프라인에 대한 테스트 파일을 생성합니다: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "명령 출력" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +기본 테스트 스텁을 생성합니다: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +이름을 의미 있는 것으로 수정하기만 하면 됩니다(곧 이것이 왜 유용한지 알게 될 것입니다). + +=== "변경 후" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "변경 전" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "참고" + + 이 경우 테스트 파일은 `nf-test`가 생성한 위치에 그대로 둘 수 있습니다. + +### 4.2. 입력 매개변수 지정 + +여전히 입력을 지정해야 하는데, 이것은 모듈 수준 테스트와 비교하여 workflow 수준에서 약간 다르게 수행됩니다. +프로파일을 지정하는 것을 포함하여 이를 수행하는 몇 가지 방법이 있습니다. +그러나 더 간단한 방법은 `nf-test init`이 원래 `tests` 디렉토리에 생성한 `nextflow.config` 파일에서 `params {}` 블록을 설정하는 것입니다. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + 테스트 실행을 위한 Nextflow 설정 파일 +======================================================================================== +*/ + +// workflow 출력을 위한 출력 디렉토리 +outputDir = 'results_genomics' + +/* + * 파이프라인 매개변수 + */ + +params { + // 기본 입력 (입력 파일 목록, 한 줄에 하나씩) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // 보조 파일 + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // 최종 출력 파일의 기본 이름 + cohort_name = "family_trio" +} +``` + +테스트를 실행하면 `nf-test`는 이 설정 파일을 가져와서 그에 따라 입력을 가져옵니다. + +### 4.3. workflow 테스트 실행 + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "명령 출력" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +테스트가 통과하여 전체 변이 호출 파이프라인이 다음을 수행함을 확인했습니다: + +1. 모든 샘플을 성공적으로 처리합니다 +2. 모든 단계를 올바르게 연결합니다 + +### 4.4. 모든 테스트 실행 + +nf-test에는 한 가지 더 기능이 있습니다. 모든 테스트를 한 번에 실행할 수 있습니다! nf-test가 모든 디렉토리에서 nf-test 파일 diff --git a/docs/ko/docs/nf4_science/genomics/05_configuration.md b/docs/ko/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..5321d7d06f --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# 파트 3: 리소스 프로파일링 및 최적화 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이것은 임시 자리표시자입니다 + +!!!note "참고" + + 이 교육 모듈은 현재 재개발 중입니다. + +--- + +TODO + +### 1.1. 리소스 사용률 보고서를 생성하기 위해 워크플로우 실행하기 + +Nextflow가 보고서를 자동으로 생성하도록 하려면, 명령줄에 `-with-report <파일명>.html`을 추가하기만 하면 됩니다. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +보고서는 html 파일이며, 다운로드하여 브라우저에서 열 수 있습니다. 또한 왼쪽의 파일 탐색기에서 마우스 오른쪽 버튼을 클릭하고 `Show preview`를 클릭하여 VS Code에서 볼 수도 있습니다. + +시간을 내어 보고서를 살펴보고 리소스 조정 기회를 찾을 수 있는지 확인하십시오. +할당된 리소스의 백분율로 사용률 결과를 보여주는 탭을 클릭하십시오. +사용 가능한 모든 기능을 설명하는 [문서](https://www.nextflow.io/docs/latest/reports.html)가 있습니다. + +<!-- TODO: insert images --> + +한 가지 관찰 사항은 `GATK_JOINTGENOTYPING`이 CPU를 매우 많이 사용하는 것으로 보이며, 이는 복잡한 계산을 많이 수행하기 때문에 당연합니다. +따라서 이를 증가시켜 실행 시간을 단축할 수 있는지 시도해 볼 수 있습니다. + +그러나 메모리 할당은 과도하게 설정한 것으로 보입니다. 모든 프로세스가 할당된 양의 일부만 사용하고 있습니다. +이를 줄여서 리소스를 절약해야 합니다. + +### 1.2. 특정 프로세스에 대한 리소스 할당 조정하기 + +`withName` 프로세스 선택자를 사용하여 특정 프로세스에 대한 리소스 할당을 지정할 수 있습니다. +프로세스 블록에 단독으로 있을 때의 구문은 다음과 같습니다: + +```groovy title="구문" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +이것을 `nextflow.config` 파일의 기존 프로세스 블록에 추가해 보겠습니다. + +```groovy title="nextflow.config" linenums="11" +process { + // 모든 프로세스에 대한 기본값 + cpus = 2 + memory = 2.GB + // 특정 프로세스에 대한 할당 + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +이렇게 지정하면 기본 설정이 `GATK_JOINTGENOTYPING` 프로세스를 **제외한** 모든 프로세스에 적용됩니다. `GATK_JOINTGENOTYPING` 프로세스는 훨씬 더 많은 CPU를 받는 특별한 경우입니다. +이것이 효과가 있기를 바랍니다. + +### 1.3. 수정된 구성으로 다시 실행하기 + +수정된 구성과 보고 플래그를 켠 상태로 워크플로우를 다시 실행해 보겠습니다. 하지만 보고서를 구별할 수 있도록 다른 이름을 지정합니다. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +다시 한번, 실행 시간에서 큰 차이를 느끼지 못할 것입니다. 이는 워크로드가 매우 작고 도구들이 '실제' 작업을 수행하는 것보다 보조 작업에 더 많은 시간을 소비하기 때문입니다. + +그러나 두 번째 보고서는 리소스 사용률이 이제 더 균형 잡혔음을 보여줍니다. + +<!-- **TODO: screenshots?** --> + +보시다시피, 이 접근 방식은 프로세스마다 다른 리소스 요구 사항이 있을 때 유용합니다. 추측이 아닌 실제 데이터를 기반으로 각 프로세스에 설정한 리소스 할당을 적정 크기로 조정할 수 있게 해줍니다. + +!!!note "참고" + + 이것은 리소스 사용을 최적화하기 위해 할 수 있는 작은 맛보기일 뿐입니다. + Nextflow 자체에는 리소스 제한으로 인해 실패한 작업을 재시도하는 정말 멋진 [동적 재시도 로직](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources)이 내장되어 있습니다. + 또한 Seqera Platform은 리소스 할당을 자동으로 최적화하기 위한 AI 기반 도구도 제공합니다. + + 이 두 접근 방식은 이 교육 과정의 향후 부분에서 다룰 예정입니다. + +그렇긴 하지만, 사용하는 컴퓨팅 실행자와 컴퓨팅 인프라에 따라 할당할 수 있는(또는 할당해야 하는) 것에 몇 가지 제약이 있을 수 있습니다. 예를 들어, 클러스터에서 다른 곳에서 실행할 때는 적용되지 않는 특정 제한 내에서 유지하도록 요구할 수 있습니다. diff --git a/docs/ko/docs/nf4_science/genomics/index.md b/docs/ko/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..53b75fe325 --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/index.md @@ -0,0 +1,42 @@ +--- +title: 유전체학을 위한 Nextflow +hide: + - toc +--- + +# 유전체학을 위한 Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 교육 과정은 데이터 분석 파이프라인을 개발하거나 맞춤화하는 데 관심이 있는 유전체학 및 관련 분야의 연구자를 위한 것입니다. +이 과정은 [Hello Nextflow](../../hello_nextflow/) 초급 교육을 기반으로 하며, 유전체학 도메인의 특정 맥락에서 Nextflow를 사용하는 방법을 보여줍니다. + +구체적으로, 이 과정은 고처리량 시퀀싱 데이터를 분석하기 위해 널리 사용되는 소프트웨어 패키지인 [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit)를 사용하여 간단한 변이 호출 파이프라인을 구현하는 방법을 보여줍니다. + +시작해봅시다! 아래의 "Open in GitHub Codespaces" 버튼을 클릭하여 교육 환경을 실행하고(가급적 별도의 탭에서), 로딩되는 동안 계속 읽어주십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## 학습 목표 + +이 과정을 통해 기초적인 Nextflow 개념과 도구를 일반적인 유전체학 사용 사례에 적용하는 방법을 배우게 됩니다. + +이 워크숍을 마치면 다음을 수행할 수 있게 됩니다: + +- 단일 샘플에 변이 호출을 적용하는 선형 workflow 작성하기 +- 인덱스 파일 및 참조 유전체 리소스와 같은 보조 파일을 적절하게 처리하기 +- Nextflow의 dataflow 패러다임을 활용하여 샘플별 변이 호출을 병렬화하기 +- 관련 channel 연산자를 사용하여 다중 샘플 변이 호출 구현하기 +- 유전체학 특유의 특성을 적절하게 처리하는 단계별 및 종단간 파이프라인 테스트 구현하기 + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## 전제 조건 + +이 과정은 다음에 대한 최소한의 친숙함을 가정합니다: + +- 이 과학 분야에서 일반적으로 사용되는 도구 및 파일 형식 +- 명령줄 경험 +- [Hello Nextflow](../../hello_nextflow/) 초급 교육에서 다루는 기초적인 Nextflow 개념 및 도구 + +기술 요구 사항 및 환경 설정은 [환경 설정](../../envsetup/) 단기 과정을 참조하십시오. diff --git a/docs/ko/docs/nf4_science/genomics/next_steps.md b/docs/ko/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..994e389d2c --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# 다음 단계 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For Genomics 교육 과정을 완료하신 것을 다시 한번 축하드리며, 설문조사에 응해주셔서 감사합니다! + +--- + +## 1. Nextflow 기술을 향상시키는 3가지 주요 방법 + +방금 완료하신 과정을 기반으로 다음에 수행할 작업에 대한 세 가지 주요 권장 사항입니다. + +### 1.1. 다른 과학적 분석 사용 사례에 Nextflow 적용하기 + +**다른 짧은 단독 과정 목록을 보려면 [Nextflow for Science](../index.md) 페이지를 확인하십시오.** 이 과정들은 Hello Nextflow에서 제시된 기본 개념과 메커니즘을 일반적인 과학적 분석 사용 사례에 적용하는 방법을 보여줍니다. + +관련 사용 사례로 귀하의 도메인이 표현되지 않은 경우, [커뮤니티 포럼](https://community.seqera.io/)에 알려주시면 개발 목록에 추가하겠습니다. + +### 1.2. nf-core 시작하기 + +**[nf-core](https://nf-co.re/)**는 광범위한 과학 연구 응용 프로그램을 위한 표준화된 오픈 소스 pipeline을 개발하기 위한 전 세계적인 협력 노력입니다. +이 프로젝트에는 즉시 사용할 수 있는 [100개 이상의 pipeline](https://nf-co.re/pipelines/)과 귀하의 프로젝트에 통합할 수 있는 [1400개 이상의 process 모듈](https://nf-co.re/modules/)이 포함되어 있으며, 풍부한 개발자 도구 세트도 제공됩니다. + +**[Hello nf-core](../../hello_nf-core/index.md)** 교육 과정은 재현 가능하고 확장 가능하며 표준화된 workflow를 작성하는 데 도움이 되도록 설계된 nf-core 커뮤니티 큐레이션 pipeline 및 개발 프레임워크를 소개합니다. 기존 nf-core pipeline을 사용하고, 개발에 기여하며, 모범 사례와 활발한 커뮤니티의 지원을 받아 자신만의 pipeline을 구축하는 방법을 배우게 됩니다. 실제 프로젝트에 Nextflow 기술을 적용할 준비가 되었다면, 이것이 완벽한 다음 단계입니다. + +### 1.3. 더욱 고급 Nextflow 기능 마스터하기 + +Hello 과정에서는 Nextflow를 시작하는 데 필요하지 않은 정보로 여러분을 과부하시키지 않기 위해 의도적으로 기술적 복잡성 수준을 낮게 유지합니다. +작업을 진행하면서 Nextflow의 전체 기능 세트와 성능을 사용하는 방법을 배우고 싶으실 것입니다. + +이를 위해 현재 **[Side Quests](../side_quests/index.md) 모음**을 작업하고 있으며, 이는 테스트 및 메타데이터 처리와 같은 특정 주제를 깊이 있게 다루는 짧은 단독 과정입니다. + +--- + +## 2. Seqera Platform 확인하기 + +**[Seqera Platform](https://seqera.io/)은 실제로 Nextflow를 실행하는 가장 좋은 방법입니다.** + +이는 Nextflow의 제작자가 개발한 클라우드 기반 플랫폼으로, 자신의 컴퓨팅 인프라(로컬, HPC 또는 클라우드)에 연결하여 workflow를 시작하고 관리하며, 데이터를 관리하고 클라우드 환경에서 대화형으로 분석을 실행하는 것을 훨씬 쉽게 만들어줍니다. + +Free Tier는 모든 사람이 무료로 사용할 수 있습니다(사용 할당량 있음). +자격을 갖춘 학계 사용자는 [Academic Program](https://seqera.io/academic/program/)을 통해 무료 Pro 수준 액세스(사용 제한 없음)를 받을 수 있습니다. + +이것이 귀하에게 유용할 수 있는지 확인하려면 [Seqera Platform 튜토리얼](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase)을 살펴보십시오. + +--- + +### 여기까지입니다! + +**Nextflow 여정에서 행운을 빕니다. [커뮤니티 포럼](https://community.seqera.io/)에서 저희가 더 도울 수 있는 방법을 주저하지 말고 알려주십시오.** diff --git a/docs/ko/docs/nf4_science/genomics/survey.md b/docs/ko/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..7070318040 --- /dev/null +++ b/docs/ko/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# 피드백 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +계속 진행하기 전에, 이 간단한 5개 질문 설문조사를 완료하여 교육을 평가하고, 귀하의 경험에 대한 피드백을 공유하며, Nextflow 여정에서 도움을 드리기 위해 우리가 할 수 있는 다른 일들을 알려주시기 바랍니다. + +이 설문조사는 완료하는 데 1분도 채 걸리지 않습니다. 모두를 위한 교육 자료 개선에 도움을 주셔서 감사합니다! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/ko/docs/nf4_science/imaging/00_orientation.md b/docs/ko/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..db88937188 --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# 오리엔테이션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 오리엔테이션은 "Open in GitHub Codespaces" 버튼을 클릭하여 이미 교육 환경을 열었다고 가정합니다. +아직 열지 않았다면, 지금 여십시오. 가능하면 이 지침을 참조할 수 있도록 두 번째 브라우저 창이나 탭에서 여는 것이 좋습니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "머신 크기 요구사항" + + 이 교육 과정을 위한 Codespace를 생성할 때 **8코어 머신**을 선택하십시오. 생물 이미징 워크플로우에는 추가 컴퓨팅 리소스가 필요합니다. + +## GitHub Codespaces + +GitHub Codespaces 환경에는 이 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 별도로 설치할 필요가 없습니다. +다만, 로그인하려면 (무료) GitHub 계정이 필요하며, 인터페이스에 익숙하지 않으시다면 [GitHub Codespaces 오리엔테이션](../../envsetup/index.md) 단기 과정을 완료하여 몇 분간 익숙해지시기 바랍니다. + +## Docker 이미지 사전 다운로드 + +Codespace를 열었으면, 이 교육 과정에 필요한 모든 Docker 이미지를 사전에 다운로드하겠습니다. +이렇게 하면 나중에 시간을 절약하고 워크플로우가 원활하게 실행됩니다. + +새 터미널 탭을 열고 다음 명령을 실행하십시오: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +이 명령은 백그라운드에서 필요한 모든 Docker 이미지를 다운로드합니다. +이 작업이 실행되는 동안 오리엔테이션의 나머지 부분을 계속 진행할 수 있습니다. + +!!!tip "팁" + + `-stub` 플래그를 사용하면 실제 데이터를 처리하지 않고 파이프라인이 빠르게 실행되므로 이미지 다운로드에 완벽합니다. 터미널 탭에서 진행 상황을 모니터링할 수 있습니다. + +## 작업 디렉토리 + +이 교육 과정 전체에서 `nf4-science/imaging/` 디렉토리에서 작업합니다. + +터미널에서 다음 명령을 실행하여 지금 디렉토리를 변경하십시오: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "팁" + + 어떤 이유로든 이 디렉토리에서 벗어났다면, GitHub Codespaces 교육 환경 내에서 실행 중이라고 가정할 때 항상 전체 경로를 사용하여 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**이제 과정을 시작하려면 이 페이지의 오른쪽 하단 모서리에 있는 화살표를 클릭하십시오.** diff --git a/docs/ko/docs/nf4_science/imaging/01_basics.md b/docs/ko/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..ad4ab7014a --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# 파트 1: 기본 작업 실행하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging 교육 과정의 첫 번째 파트에서는 매우 기본적인 도메인 독립적 Hello World 예제를 사용하여 필수 작업을 시연하고 해당하는 Nextflow 코드 구성 요소를 설명하겠습니다. + +## 1. 워크플로우 실행하기 + +`--greeting`이라는 명령줄 인수를 통해 입력을 받아 해당 인사말이 포함된 텍스트 파일을 생성하는 `hello-world.nf`라는 워크플로우 스크립트를 제공합니다. +아직 코드를 살펴보지는 않을 것이며, 먼저 실행하는 것이 어떤 모습인지 확인해 보겠습니다. + +### 1.1. 워크플로우 시작 및 실행 모니터링하기 + +터미널에서 다음 명령을 실행하십시오: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +콘솔 출력은 다음과 같이 표시되어야 합니다: + +```console title="출력" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +축하합니다. 첫 번째 Nextflow 워크플로우를 실행하셨습니다! + +여기서 가장 중요한 출력은 마지막 줄(6번 줄)입니다: + +```console title="출력" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +이는 `sayHello` process가 한 번 성공적으로 실행되었음을 알려줍니다(`1 of 1 ✔`). + +좋습니다만, 출력이 어디에 있는지 궁금하실 것입니다. + +### 1.2. `results` 디렉토리에서 출력 파일 찾기 + +이 워크플로우는 출력을 `results`라는 디렉토리에 게시하도록 구성되어 있습니다. +현재 디렉토리를 살펴보면 워크플로우를 실행할 때 Nextflow가 `results`라는 새 디렉토리를 생성했으며, 이 디렉토리에는 `output.txt`라는 파일이 포함되어 있습니다. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +파일을 열어보십시오. 내용은 명령줄에서 지정한 인사말과 일치해야 합니다. + +<details> + <summary>파일 내용</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +훌륭합니다. 워크플로우가 의도한 대로 작동했습니다! + +그러나 '게시된' 결과는 Nextflow가 워크플로우를 실행할 때 생성한 실제 출력의 사본(또는 경우에 따라 심볼릭 링크)이라는 점을 알아두십시오. + +이제 Nextflow가 실제로 작업을 실행한 위치를 확인하기 위해 내부를 살펴보겠습니다. + +!!! warning "경고" + + 모든 워크플로우가 results 디렉토리에 출력을 게시하도록 설정되어 있는 것은 아니며, 디렉토리 이름이 다를 수 있습니다. + 이 섹션 후반부에서 이 동작이 어디에 지정되어 있는지 확인하는 방법을 보여드리겠습니다. + +### 1.3. `work/` 디렉토리에서 원본 출력 및 로그 찾기 + +워크플로우를 실행하면 Nextflow는 워크플로우의 각 process 호출마다 별도의 'task 디렉토리'를 생성합니다(=파이프라인의 각 단계). +각각에 대해 필요한 입력을 준비하고, 관련 명령을 실행하며, 해당 디렉토리 내에 출력 및 로그 파일을 작성합니다. 이 디렉토리는 고유성을 위해 해시를 사용하여 자동으로 이름이 지정됩니다. + +이러한 모든 task 디렉토리는 현재 디렉토리(명령을 실행하는 위치) 내의 `work`라는 디렉토리 아래에 위치합니다. + +혼란스러울 수 있으니 실제로 어떤 모습인지 살펴보겠습니다. + +앞서 실행한 워크플로우의 콘솔 출력으로 돌아가면 다음과 같은 줄이 있었습니다: + +```console title="명령 출력 발췌" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +줄이 `[a3/7be2fa]`로 시작하는 것이 보이시나요? +이것은 해당 process 호출에 대한 task 디렉토리 경로의 축약된 형태이며, `work/` 디렉토리 경로 내에서 `sayHello` process 호출의 출력을 어디에서 찾을 수 있는지 알려줍니다. + +다음 명령을 입력하고(`a3/7be2fa`를 터미널에 표시된 것으로 교체) tab 키를 눌러 경로를 자동 완성하거나 별표를 추가하여 전체 경로를 찾을 수 있습니다: + +```bash +tree work/a3/7be2fa* +``` + +전체 디렉토리 경로가 표시됩니다: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +그 안에 무엇이 있는지 살펴보겠습니다. + +!!! Tip "팁" + + VSCode 파일 탐색기에서 task 하위 디렉토리의 내용을 탐색하면 모든 파일을 바로 볼 수 있습니다. + 그러나 로그 파일은 터미널에서 보이지 않도록 설정되어 있으므로 `ls` 또는 `tree`를 사용하여 보려면 보이지 않는 파일을 표시하는 관련 옵션을 설정해야 합니다. + + ```bash + tree -a work + ``` + +시스템에서는 정확한 하위 디렉토리 이름이 다를 것입니다. + +<details> + <summary>디렉토리 내용</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +`output.txt` 파일을 바로 확인할 수 있을 것입니다. 이것은 실제로 `results` 디렉토리에 게시된 `sayHello` process의 원본 출력입니다. +파일을 열면 다시 `Hello World!` 인사말을 찾을 수 있습니다. + +<details> + <summary>output.txt의 파일 내용</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +그렇다면 다른 모든 파일은 무엇일까요? + +이것들은 Nextflow가 task 실행의 일부로 작성한 도우미 및 로그 파일입니다: + +- **`.command.begin`**: task가 시작되자마자 생성되는 센티넬 파일 +- **`.command.err`**: process 호출에서 발생한 오류 메시지(`stderr`) +- **`.command.log`**: process 호출에서 발생한 전체 로그 출력 +- **`.command.out`**: process 호출의 일반 출력(`stdout`) +- **`.command.run`**: Nextflow가 process 호출을 실행하기 위해 실행한 전체 스크립트 +- **`.command.sh`**: process 호출에서 실제로 실행된 명령 +- **`.exitcode`**: 명령 실행 결과로 생성된 종료 코드 + +`.command.sh` 파일은 Nextflow가 모든 장부 처리와 task/환경 설정을 제외하고 실제로 실행한 주요 명령을 보여주기 때문에 특히 유용합니다. + +<details> + <summary>파일 내용</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "팁" + + 문제가 발생하여 무엇이 잘못되었는지 문제를 해결해야 할 때, `command.sh` 스크립트를 살펴보면 워크플로우 지시사항, 변수 보간 등을 기반으로 Nextflow가 구성한 정확한 명령을 확인하는 데 유용할 수 있습니다. + +### 1.4. 선택 연습: 다른 인사말로 다시 실행하기 + +`--greeting` 인수에 다른 값을 사용하여 워크플로우를 여러 번 다시 실행한 다음 `results/` 디렉토리와 task 디렉토리의 내용을 모두 살펴보십시오. + +격리된 task 디렉토리의 출력 및 로그가 어떻게 보존되는지 관찰하고, `results` 디렉토리의 내용은 후속 실행의 출력으로 덮어쓰이는 것을 확인하십시오. + +### 핵심 사항 + +간단한 Nextflow 스크립트를 실행하고, 실행을 모니터링하며, 출력을 찾는 방법을 알게 되었습니다. + +### 다음 단계 + +기본 Nextflow 스크립트를 읽고 그 구성 요소가 기능과 어떻게 연관되는지 식별하는 방법을 배웁니다. + +--- + +## 2. Hello World 워크플로우 스타터 스크립트 살펴보기 + +앞서 우리가 한 것은 기본적으로 워크플로우 스크립트를 블랙박스처럼 취급한 것입니다. +이제 무엇을 하는지 확인했으니 상자를 열어 내부를 살펴보겠습니다. + +_여기서의 목표는 Nextflow 코드의 구문을 암기하는 것이 아니라 주요 구성 요소가 무엇이며 어떻게 구성되는지에 대한 기본적인 직관을 형성하는 것입니다._ + +### 2.1. 전체 코드 구조 살펴보기 + +편집기 창에서 `hello-world.nf` 스크립트를 열어보겠습니다. + +<details> + <summary>코드</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // 인사말 출력 + sayHello(params.greeting) +} +``` + +</details> + +Nextflow 스크립트는 두 가지 주요 핵심 구성 요소를 포함합니다: 하나 이상의 **process**와 **workflow** 자체입니다. +각 **process**는 파이프라인의 해당 단계가 수행해야 할 작업을 설명하며, **workflow**는 다양한 단계를 연결하는 데이터 흐름 논리를 설명합니다. + +먼저 **process** 블록을 자세히 살펴본 다음 **workflow** 블록을 살펴보겠습니다. + +### 2.2. `process` 정의 + +첫 번째 코드 블록은 **process**를 설명합니다. +process 정의는 `process` 키워드로 시작하고 process 이름이 뒤따르며 마지막으로 중괄호로 구분된 process 본문이 옵니다. +process 본문에는 실행할 명령을 지정하는 script 블록이 포함되어야 하며, 명령줄 터미널에서 실행할 수 있는 모든 것이 가능합니다. + +여기에는 `greeting`이라는 **input** 변수를 받아 `output.txt`라는 파일에 **output**을 작성하는 `sayHello`라는 **process**가 있습니다. + +<details> + <summary>코드</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Use echo to print a greeting to a file + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +이것은 `input` 정의, `output` 정의 및 실행할 `script`만 포함하는 매우 최소한의 process 정의입니다. + +`input` 정의에는 `val` 한정자가 포함되어 있으며, 이는 Nextflow에게 어떤 종류의 값(문자열, 숫자 등)을 기대하도록 지시합니다. + +`output` 정의에는 `path` 한정자가 포함되어 있으며, 이는 Nextflow에게 이것을 경로로 처리하도록 지시합니다(디렉토리 경로와 파일 모두 포함). + +!!! Tip "팁" + + output 정의는 어떤 출력이 생성될지 _결정_하지 않습니다. + 단순히 예상되는 출력 파일을 어디에서 찾을 수 있는지 _선언_하므로 Nextflow가 실행이 완료되면 이를 찾을 수 있습니다. + + 이는 명령이 성공적으로 실행되었는지 확인하고 필요한 경우 출력을 다운스트림 process에 전달하는 데 필요합니다. + output 블록에 선언된 것과 일치하지 않는 출력은 다운스트림 process로 전달되지 않습니다. + +실제 파이프라인에서 process는 일반적으로 추가 정보(예: process 지시문)를 포함하며, 이는 곧 소개하겠습니다. + +### 2.3. `workflow` 정의 + +두 번째 코드 블록은 **workflow** 자체를 설명합니다. +workflow 정의는 `workflow` 키워드로 시작하고 선택적 이름이 뒤따르며 중괄호로 구분된 workflow 본문이 옵니다. + +여기에는 `--greeting` 매개변수에 제공한 값을 담고 있는 `params.greeting`이라는 입력을 받는 `sayHello` process를 한 번 호출하는 **workflow**가 있습니다. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // 인사말 출력 + sayHello(params.greeting) +} +``` + +이것은 매우 최소한의 **workflow** 정의입니다. +실제 파이프라인에서 workflow는 일반적으로 **channel**로 연결된 여러 **process** 호출을 포함하며, 변수 입력에 대한 기본값이 설정될 수 있습니다. + +파트 2에서 nf-core/molkart를 실행할 때 이를 실제로 볼 수 있습니다. + +### 2.4. 명령줄 매개변수의 `params` 시스템 + +`sayHello()` process 호출에 제공하는 `params.greeting`은 Nextflow 코드의 깔끔한 부분이며 추가로 1분 정도 시간을 투자할 가치가 있습니다. + +위에서 언급한 것처럼 이것이 `--greeting` 명령줄 매개변수의 값을 `sayHello()` process 호출에 전달하는 방법입니다. +실제로 `params.someParameterName`을 선언하기만 하면 명령줄에서 `--someParameterName`이라는 매개변수를 워크플로우에 제공할 수 있게 됩니다. + +!!! Tip "팁" + + `params` 시스템을 사용하여 선언된 이러한 워크플로우 매개변수는 항상 두 개의 대시(`--`)를 사용합니다. + 이는 한 개의 대시(`-`)만 사용하는 Nextflow 수준 매개변수와 구별됩니다. + +### 핵심 사항 + +이제 간단한 Nextflow 워크플로우가 어떻게 구조화되어 있으며 기본 구성 요소가 기능과 어떻게 연관되는지 알게 되었습니다. + +### 다음 단계 + +워크플로우 실행을 편리하게 관리하는 방법을 배웁니다. + +--- + +## 3. 워크플로우 실행 관리하기 + +워크플로우를 시작하고 출력을 검색하는 방법을 아는 것은 훌륭하지만, 삶을 더 쉽게 만들어줄 워크플로우 관리의 몇 가지 다른 측면이 있다는 것을 곧 알게 될 것입니다. + +여기서는 동일한 워크플로우를 다시 시작해야 할 때 `resume` 기능을 활용하는 방법, `nextflow log`로 실행 로그를 검사하는 방법, `nextflow clean`으로 이전 작업 디렉토리를 삭제하는 방법을 보여드립니다. + +### 3.1. `-resume`으로 워크플로우 다시 시작하기 + +때때로 이전에 이미 시작한 파이프라인을 성공적으로 완료된 작업을 다시 수행하지 않고 다시 실행하고 싶을 것입니다. + +Nextflow에는 이를 수행할 수 있는 `-resume`이라는 옵션이 있습니다. +구체적으로 이 모드에서는 정확히 동일한 코드, 설정 및 입력으로 이미 실행된 process는 건너뜁니다. +즉, Nextflow는 마지막 실행 이후 추가하거나 수정한 process 또는 새로운 설정이나 입력을 제공하는 process만 실행합니다. + +이렇게 하면 두 가지 주요 이점이 있습니다: + +- 파이프라인을 개발 중인 경우 변경 사항을 테스트하기 위해 작업 중인 process만 실행하면 되므로 더 빠르게 반복할 수 있습니다. +- 프로덕션에서 파이프라인을 실행하다가 문제가 발생한 경우 대부분의 경우 문제를 해결하고 파이프라인을 다시 시작할 수 있으며, 실패 지점부터 실행이 재개되므로 많은 시간과 컴퓨팅 리소스를 절약할 수 있습니다. + +사용하려면 명령에 `-resume`을 추가하고 실행하십시오: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +process 상태 줄(5번 줄)에 추가된 `cached:` 부분을 찾아보십시오. 이는 Nextflow가 이미 이 작업을 수행했음을 인식하고 이전에 성공한 실행의 결과를 단순히 재사용했음을 의미합니다. + +작업 하위 디렉토리 해시가 이전 실행과 동일하다는 것도 확인할 수 있습니다. +Nextflow는 말 그대로 이전 실행을 가리키며 "저기에서 이미 했습니다"라고 말하고 있습니다. + +!!! Tip "팁" + + `resume`으로 파이프라인을 다시 실행할 때 Nextflow는 이전에 성공적으로 실행된 process 호출에 의해 `publishDir` 디렉토리에 작성된 파일을 덮어쓰지 않습니다. + +### 3.2. 과거 실행 로그 검사하기 + +nextflow 워크플로우를 시작할 때마다 현재 작업 디렉토리의 `.nextflow`라는 숨겨진 디렉토리 아래에 있는 `history`라는 로그 파일에 한 줄이 기록됩니다. + +이 정보에 액세스하는 더 편리한 방법은 `nextflow log` 명령을 사용하는 것입니다. + +```bash +nextflow log +``` + +이렇게 하면 로그 파일의 내용이 터미널에 출력되어 현재 작업 디렉토리 내에서 시작된 모든 Nextflow 실행의 타임스탬프, 실행 이름, 상태 및 전체 명령줄을 보여줍니다. + +### 3.3. 이전 작업 디렉토리 삭제하기 + +개발 프로세스 중에 일반적으로 초안 파이프라인을 여러 번 실행하게 되며, 이로 인해 많은 하위 디렉토리에 걸쳐 매우 많은 파일이 축적될 수 있습니다. +하위 디렉토리의 이름이 무작위로 지정되므로 이름만으로는 이전 실행과 최근 실행을 구별하기 어렵습니다. + +Nextflow에는 더 이상 필요하지 않은 과거 실행의 작업 하위 디렉토리를 자동으로 삭제할 수 있는 편리한 `clean` 하위 명령이 포함되어 있으며, 삭제할 항목을 제어하는 여러 [옵션](https://www.nextflow.io/docs/latest/reference/cli.html#clean)이 있습니다. + +Nextflow 로그를 사용하여 타임스탬프 및/또는 명령줄을 기반으로 실행을 조회한 다음 `nextflow clean -before <run_name> -f`를 사용하여 이전 실행의 작업 디렉토리를 삭제할 수 있습니다. + +!!! Warning "경고" + + 과거 실행의 작업 하위 디렉토리를 삭제하면 Nextflow의 캐시에서 제거되고 해당 디렉토리에 저장된 모든 출력이 삭제됩니다. + 즉, 해당 process를 다시 실행하지 않고 Nextflow가 실행을 재개할 수 있는 기능이 손상됩니다. + + 보관하거나 의존할 계획인 모든 출력을 저장하는 것은 귀하의 책임입니다! 이 목적으로 `publishDir` 지시문을 사용하는 경우 `symlink` 모드가 아닌 `copy` 모드를 사용해야 합니다. + +### 핵심 사항 + +이미 동일한 방식으로 실행된 단계를 반복하지 않고 파이프라인을 다시 시작하고, 실행 로그를 검사하며, `nextflow clean` 명령을 사용하여 이전 작업 디렉토리를 정리하는 방법을 알게 되었습니다. + +### 다음 단계 + +이제 기본 Nextflow 작업을 이해했으므로 nf-core/molkart로 실제 생물 이미징 파이프라인을 실행할 준비가 되었습니다. diff --git a/docs/ko/docs/nf4_science/imaging/02_run_molkart.md b/docs/ko/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..305a736d7c --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# 파트 2: nf-core/molkart 실행하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Part 1에서는 간단한 Hello World 워크플로를 실행하여 Nextflow 실행의 기본 사항을 이해했습니다. +이제 실제 바이오이미징 파이프라인인 **nf-core/molkart**를 실행하겠습니다. + +이 파이프라인은 Resolve Bioscience의 Molecular Cartography 공간 전사체학 데이터를 처리합니다. +하지만 여기서 배우는 Nextflow 패턴은 모든 nf-core 파이프라인이나 프로덕션 워크플로에 적용됩니다. + +## 1. nf-core 파이프라인 이해하기 + +파이프라인을 실행하기 전에 nf-core가 무엇이며 워크플로 실행에 왜 중요한지 이해하겠습니다. + +### 1.1. nf-core란 무엇인가? + +[nf-core](https://nf-co.re/)는 고품질 Nextflow 파이프라인의 커뮤니티 기반 컬렉션입니다. +모든 nf-core 파이프라인은 동일한 구조와 규칙을 따르므로, 하나를 실행하는 방법을 배우면 모든 파이프라인을 실행할 수 있습니다. + +nf-core 파이프라인의 주요 특징: + +- **표준화된 구조**: 모든 파이프라인이 일관된 매개변수 이름과 사용 패턴을 가짐 +- **내장된 테스트 데이터**: 모든 파이프라인에 빠른 검증을 위한 테스트 프로파일 포함 +- **포괄적인 문서**: 상세한 사용 지침 및 매개변수 설명 +- **품질 관리**: MultiQC를 사용한 자동 QC 보고서 +- **컨테이너 지원**: 재현성을 위해 미리 빌드된 컨테이너 제공 + +!!! tip "nf-core에 대해 더 알고 싶으신가요?" + + nf-core 파이프라인 개발에 대한 심층적인 소개를 보려면 [Hello nf-core](../../hello_nf-core/index.md) 교육 과정을 확인하세요. + 처음부터 nf-core 파이프라인을 생성하고 사용자 정의하는 방법을 다룹니다. + +### 1.2. molkart 파이프라인 + +![nf-core/molkart 파이프라인](img/molkart.png) + +[nf-core/molkart](https://nf-co.re/molkart) 파이프라인은 공간 전사체학 이미징 데이터를 여러 단계로 처리합니다: + +1. **이미지 전처리**: 그리드 패턴 채우기 및 선택적 대비 향상 +2. **세포 분할**: 다중 알고리즘 옵션 (Cellpose, Mesmer, ilastik, Stardist) +3. **스팟 할당**: 전사체 스팟을 분할된 세포에 할당 +4. **품질 관리**: 포괄적인 QC 보고서 생성 + +주요 출력물: + +- 세포별 전사체 카운트 테이블 +- 분할 마스크 +- MultiQC 품질 관리 보고서 + +--- + +## 2. 테스트 데이터로 molkart 실행하기 + +시작하기 전에 molkart 저장소를 로컬에 클론하여 코드를 검사할 수 있도록 하겠습니다: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +이렇게 하면 전체 파이프라인 소스 코드가 포함된 `molkart/` 디렉토리가 생성됩니다. + +!!! note "왜 로컬에 클론하나요?" + + 일반적으로 `nextflow run nf-core/molkart -r 1.2.0`을 사용하여 GitHub에서 직접 nf-core 파이프라인을 실행합니다. + Nextflow는 요청된 파이프라인 버전을 자동으로 `$HOME/.nextflow/assets/nf-core/molkart`에 다운로드하고 거기서 실행합니다. + 하지만 이 교육에서는 코드를 더 쉽게 검사할 수 있도록 파이프라인을 다른 로컬 디렉토리에 클론하고 있습니다. + +### 2.1. 컨테이너 요구사항 이해하기 + +전체 파이프라인을 실행하기 전에 컨테이너가 nf-core 파이프라인에 왜 필수적인지 알아보겠습니다. + +molkart 테스트 구성의 테스트 데이터셋과 매개변수를 사용하여 파이프라인을 실행해 보겠습니다: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +이 매개변수들을 분석해 보겠습니다: + +- `--input`: 샘플 메타데이터가 포함된 샘플시트 경로 +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: 그리드 패턴 채우기를 위한 매개변수 +- `--clahe_pyramid_tile`: 대비 향상을 위한 커널 크기 +- `--segmentation_method`: 세포 분할에 사용할 알고리즘 +- `--outdir`: 결과를 저장할 위치 + +!!! Warning "이 명령은 실패할 것입니다 - 의도적입니다!" + + 컨테이너가 필요한 이유를 보여주기 위해 의도적으로 컨테이너 없이 실행하고 있습니다. + +잠시 후 다음과 같은 오류가 표시됩니다: + +??? failure "명령 출력" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**무슨 일이 일어나고 있나요?** + +`command not found` 오류 (종료 상태 127)는 Nextflow가 `duplicate_finder.py`를 실행하려고 했지만 시스템에서 찾을 수 없다는 의미입니다. +이는 다음과 같은 이유 때문입니다: + +1. 파이프라인이 특수한 바이오인포매틱스 소프트웨어가 설치되어 있을 것으로 예상합니다 +2. 이러한 도구들 (예: `duplicate_finder.py`, `apply_clahe.dask.py` 등)은 표준 Linux 배포판에 포함되어 있지 않습니다 +3. 컨테이너 없이 Nextflow는 로컬 머신에서 직접 명령을 실행하려고 합니다 + +**이 도구들은 어디서 와야 하나요?** + +프로세스 모듈 중 하나를 검사하여 소프트웨어 요구사항을 어떻게 선언하는지 살펴보겠습니다. + +CLAHE 전처리 모듈을 열어보세요: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +5번째 줄을 보면 다음과 같이 표시됩니다: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +이 줄은 Nextflow에게 다음과 같이 알려줍니다: "이 프로세스를 실행하려면 필요한 모든 소프트웨어가 포함된 Docker 이미지 `ghcr.io/schapirolabor/molkart-local:v0.0.4`를 사용하세요." + +각 프로세스는 필요한 도구를 제공하는 컨테이너 이미지를 선언합니다. +하지만 Nextflow는 사용자가 지시할 때만 이러한 컨테이너를 사용합니다! + +**해결책: 구성에서 Docker 활성화** + +### 2.2. Docker 구성 및 파이프라인 실행 + +Docker를 활성화하려면 `nextflow.config` 파일에서 `docker.enabled`를 `false`에서 `true`로 변경해야 합니다. + +구성 파일을 여세요: + +```bash +code nextflow.config +``` + +`docker.enabled = false`를 `docker.enabled = true`로 변경하세요: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +이제 동일한 명령으로 파이프라인을 다시 실행하세요: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +이번에는 Nextflow가: + +1. 구성에서 `docker.enabled = true` 설정을 읽습니다 +2. 필요한 Docker 이미지를 가져옵니다 (처음만) +3. 각 프로세스를 지정된 컨테이너 내에서 실행합니다 +4. 모든 도구가 컨테이너 내에서 사용 가능하므로 성공적으로 실행됩니다 + +!!! Tip "컨테이너가 중요한 이유" + + 대부분의 nf-core 파이프라인은 컨테이너화 (Docker, Singularity, Podman 등)를 **필요로** 합니다. 왜냐하면: + + - 표준 환경에서 사용할 수 없는 특수한 바이오인포매틱스 소프트웨어를 사용합니다 + - 컨테이너는 재현성을 보장합니다 - 정확히 동일한 소프트웨어 버전이 모든 곳에서 실행됩니다 + - 수십 개의 도구와 그 종속성을 수동으로 설치할 필요가 없습니다 + + Nextflow의 컨테이너에 대한 자세한 내용은 Hello Nextflow 교육의 [Hello Containers](../../hello_nextflow/05_hello_containers.md)를 참조하세요. + +### 2.3. 실행 모니터링 + +파이프라인이 실행되는 동안 다음과 유사한 출력이 표시됩니다: + +??? success "명령 출력" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +파이프라인이 따르는 nf-core 규칙 때문에 이 출력이 Hello World 예제보다 더 상세하다는 것을 알 수 있습니다: + +- 파이프라인이 버전과 로고를 표시합니다 +- 구성 매개변수가 표시됩니다 +- 여러 프로세스가 병렬로 실행됩니다 (여러 프로세스 라인으로 표시) +- 프로세스 이름에는 전체 모듈 경로가 포함됩니다 (예: `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. 프로세스 실행 이해하기 + +executor 라인 `executor > local (22)`는 다음을 알려줍니다: + +- **executor**: 사용 중인 컴퓨팅 환경 (`local` = 사용자의 머신) +- **(22)**: 실행된 총 작업 수 + +각 프로세스 라인은 다음을 보여줍니다: + +- **해시** (`[1a/2b3c4d]`): 작업 디렉토리 식별자 (이전과 같음) +- **프로세스 이름**: 전체 모듈 경로 및 프로세스 이름 +- **입력 식별자**: 괄호 안의 샘플 이름 +- **진행률**: 완료 백분율 및 개수 (예: `1 of 1 ✔`) + +### 핵심 사항 + +테스트 데이터로 nf-core 파이프라인을 실행하고 실행 출력을 해석하는 방법을 알게 되었습니다. + +### 다음 단계 + +결과를 찾는 위치와 해석하는 방법을 배웁니다. + +--- + +## 3. 출력물 찾기 및 검사하기 + +파이프라인이 성공적으로 완료되면 완료 메시지와 실행 요약이 표시됩니다. + +### 3.1. 결과 디렉토리 찾기 + +기본적으로 nf-core 파이프라인은 `outdir` 매개변수로 지정된 디렉토리에 출력을 작성하며, 우리는 이를 `results/`로 설정했습니다. + +내용을 나열하세요: + +```bash +tree results/ +``` + +여러 하위 디렉토리가 표시됩니다: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +각 하위 디렉토리에는 파이프라인의 특정 단계에서 나온 출력물이 포함되어 있습니다: + +- **mindagap/**: MindaGap 전처리 단계의 그리드 채워진 이미지 +- **clahe/**: CLAHE 전처리의 대비 향상된 이미지 +- **stack/**: 분할을 위해 생성된 다중 채널 이미지 스택 +- **segmentation/**: 다양한 알고리즘의 분할 결과 (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: 세포별 전사체 카운트 테이블 +- **anndata/**: 세포별 전사체 매트릭스 및 공간 좌표를 포함하는 AnnData 객체 +- **molkartqc/**: 스팟 할당을 위한 품질 관리 메트릭 +- **multiqc/**: 포괄적인 품질 관리 보고서 +- **pipeline_info/**: 실행 보고서 및 로그 + +### 3.2. MultiQC 보고서 검사하기 + +MultiQC 보고서는 모든 파이프라인 단계의 품질 메트릭을 집계하는 포괄적인 HTML 파일입니다. + +파일 브라우저에서 보고서를 연 다음 "Show Preview" 버튼을 클릭하여 VS Code에서 직접 렌더링된 내용을 확인하세요. + +보고서에는 다음이 포함됩니다: + +- 모든 샘플에 대한 일반 통계 +- 전처리 메트릭 +- 분할 품질 메트릭 +- 감지된 세포 및 스팟 수 + +!!! Tip + + MultiQC 보고서는 일반적으로 모든 nf-core 파이프라인에 포함됩니다. + 항상 파이프라인 실행 및 데이터 품질에 대한 높은 수준의 개요를 제공합니다. + +### 3.3. 세포별 전사체 테이블 검사하기 + +가장 중요한 과학적 출력물은 세포별 전사체 카운트 테이블입니다. +이는 각 세포에서 각 전사체가 몇 개 감지되었는지 알려줍니다. + +spot2cell 디렉토리로 이동하세요: + +```bash +ls results/spot2cell/ +``` + +다음과 같은 파일들을 찾을 수 있습니다: + +- `cellxgene_mem_only_cellpose.csv`: Cellpose 분할을 사용한 세포별 전사체 테이블 +- `cellxgene_mem_only_mesmer.csv`: Mesmer 분할을 사용한 세포별 전사체 테이블 +- `cellxgene_mem_only_stardist.csv`: Stardist 분할을 사용한 세포별 전사체 테이블 + +이 테스트 데이터셋에서는 1개의 샘플만 실행했지만, 실제 실험에서는 각 샘플에 대해 이러한 테이블이 있을 것입니다. +Nextflow가 여러 분할 방법을 병렬로 처리하여 결과를 쉽게 비교할 수 있도록 하는 방법을 주목하세요. + +### 3.4. 실행 보고서 보기 + +Nextflow는 여러 실행 보고서를 자동으로 생성합니다. + +pipeline_info 디렉토리를 확인하세요: + +```bash +ls results/pipeline_info/ +``` + +주요 파일: + +- **execution_report.html**: 타임라인 및 리소스 사용량 시각화 +- **execution_timeline.html**: 프로세스 실행의 Gantt 차트 +- **execution_trace.txt**: 상세한 작업 실행 메트릭 +- **pipeline_dag.html**: 워크플로 구조를 보여주는 방향성 비순환 그래프 + +실행 보고서를 열어 리소스 사용량을 확인하세요: + +```bash +code results/pipeline_info/execution_report.html +``` + +다음을 보여줍니다: + +- 각 프로세스가 소요된 시간 +- CPU 및 메모리 사용량 +- 캐시된 작업과 실행된 작업 + +!!! Tip + + 이러한 보고서는 리소스 할당을 최적화하고 성능 문제를 해결하는 데 매우 유용합니다. + +### 핵심 사항 + +파이프라인 출력물을 찾고, 품질 관리 보고서를 검사하고, 실행 메트릭에 액세스하는 방법을 알게 되었습니다. + +### 다음 단계 + +작업 디렉토리와 Nextflow가 중간 파일을 관리하는 방법에 대해 배웁니다. + +--- + +## 4. 작업 디렉토리 탐색하기 + +Hello World 예제와 마찬가지로 모든 실제 작업은 `work/` 디렉토리에서 발생합니다. + +### 4.1. 작업 디렉토리 구조 이해하기 + +작업 디렉토리에는 실행된 각 작업에 대한 하위 디렉토리가 포함됩니다. +22개의 작업이 있는 이 파이프라인의 경우 22개의 작업 하위 디렉토리가 있습니다. + +작업 디렉토리를 나열하세요: + +```bash +ls -d work/*/*/ | head -5 +``` + +처음 5개의 작업 디렉토리가 표시됩니다. + +### 4.2. 작업 디렉토리 검사하기 + +콘솔 출력의 분할 프로세스 해시 중 하나를 선택하고 (예: `[3m/4n5o6p]`) 내부를 살펴보세요: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +다음을 볼 수 있습니다: + +- **.command.\* 파일**: Nextflow 실행 스크립트 및 로그 (이전과 같음) +- **스테이징된 입력 파일**: 실제 입력 파일에 대한 심볼릭 링크 +- **출력 파일**: 분할 마스크, 중간 결과 등 + +Hello World와의 주요 차이점: + +- 실제 파이프라인은 대용량 입력 파일 (이미지, 참조 데이터)을 스테이징합니다 +- 출력 파일이 상당히 클 수 있습니다 (분할 마스크, 처리된 이미지) +- 작업당 여러 입력 및 출력 파일 + +!!! Tip + + 프로세스가 실패하면 해당 작업 디렉토리로 이동하여 `.command.err`에서 오류 메시지를 검사하고, 문제를 디버그하기 위해 `.command.sh`를 수동으로 다시 실행할 수도 있습니다. + +### 4.3. 작업 디렉토리 정리 + +여러 파이프라인 실행을 거치면서 작업 디렉토리가 상당히 커질 수 있습니다. +Part 1에서 배운 것처럼 `nextflow clean`을 사용하여 이전 실행의 작업 디렉토리를 제거할 수 있습니다. + +하지만 대용량 중간 파일이 있는 nf-core 파이프라인의 경우 정기적으로 정리하는 것이 특히 중요합니다. + +### 핵심 사항 + +nf-core 파이프라인이 작업 디렉토리를 구성하는 방법과 디버깅을 위해 개별 작업을 검사하는 방법을 이해했습니다. + +### 다음 단계 + +Nextflow 캐시와 실패한 파이프라인 실행을 재개하는 방법에 대해 배웁니다. + +--- + +## 5. 파이프라인 실행 재개하기 + +Nextflow의 가장 강력한 기능 중 하나는 실패 지점부터 파이프라인을 재개할 수 있는 능력입니다. + +### 5.1. 캐시 메커니즘 + +`-resume`으로 파이프라인을 실행하면 Nextflow는: + +1. 각 작업에 대해 캐시를 확인합니다 +2. 입력, 코드 및 매개변수가 동일하면 캐시된 결과를 재사용합니다 +3. 변경되거나 실패한 작업만 다시 실행합니다 + +이는 실행 후반에 실패가 발생할 수 있는 장시간 실행 파이프라인에 필수적입니다. + +### 5.2. molkart로 재개 시도하기 + +동일한 명령을 다시 실행하되 `-resume`을 추가하세요: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +다음과 같은 출력이 표시됩니다: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +각 프로세스에 대해 `cached: 2` 또는 `cached: 1`이 표시되는 것을 주목하세요 - 아무것도 다시 실행되지 않았습니다! + +### 5.3. 재개가 유용한 경우 + +재개는 다음과 같은 경우에 특히 유용합니다: + +- 리소스 제한으로 인해 파이프라인이 실패한 경우 (메모리 부족, 시간 제한 초과) +- 업스트림 단계를 다시 실행하지 않고 다운스트림 프로세스를 수정해야 하는 경우 +- 데이터 다운로드 중 네트워크 연결이 끊긴 경우 +- 계산을 다시 하지 않고 추가 출력물을 추가하려는 경우 + +!!! Warning + + 입력 데이터, 파이프라인 코드 또는 매개변수를 변경하지 않은 경우에만 재개가 작동합니다. + 이 중 하나를 변경하면 Nextflow는 영향을 받는 작업을 올바르게 다시 실행합니다. + +### 핵심 사항 + +성공한 작업을 반복하지 않고 파이프라인을 효율적으로 다시 실행하기 위해 `-resume`을 사용하는 방법을 알게 되었습니다. + +### 다음 단계 + +이제 테스트 데이터로 nf-core/molkart를 실행할 수 있으므로 자신의 데이터셋에 맞게 구성하는 방법을 배울 준비가 되었습니다. diff --git a/docs/ko/docs/nf4_science/imaging/03_inputs.md b/docs/ko/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..8bcd5e950a --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# 파트 3: 입력 구성하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Part 2에서는 명령줄에서 여러 매개변수를 사용하여 molkart를 실행했습니다. +이제 입력을 관리하는 두 가지 더 나은 방법인 **매개변수 파일**과 **샘플시트**를 배우겠습니다. + +## 1. 매개변수 파일 사용하기 + +### 1.1. 긴 명령줄의 문제점 + +Part 2의 명령을 다시 살펴보겠습니다: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +이 방법은 작동하지만, 재현하거나 공유하거나 수정하기 어렵습니다. +다음 달에 동일한 분석을 다시 실행해야 한다면 어떻게 하시겠습니까? +동료가 정확히 같은 설정을 사용하고 싶어한다면 어떻게 하시겠습니까? + +### 1.2. 해결책: 매개변수 파일 사용 + +`params.yaml`이라는 파일을 생성하십시오: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +이제 명령이 다음과 같이 간단해집니다: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +이것으로 끝입니다! 매개변수 파일은 정확한 구성을 문서화하고 재실행이나 공유를 쉽게 만듭니다. + +### 1.3. 매개변수 재정의하기 + +명령줄에서 특정 매개변수를 여전히 재정의할 수 있습니다: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +위 명령은 `segmentation_method`를 `stardist`로 변경하고 `--outdir` 이름을 `params.yaml` 파일의 매개변수 대신 `stardist_results`로 변경합니다. +또한 `-resume` 플래그가 이전 실행의 전처리 결과를 재사용하여 시간을 절약했음을 확인할 수 있습니다. +이 패턴을 사용하여 파이프라인의 다양한 변형을 빠르게 테스트할 수 있습니다. + +### 요점 + +매개변수 파일은 분석을 재현 가능하고 공유하기 쉽게 만듭니다. +실제 분석 작업에는 매개변수 파일을 사용하십시오. + +### 다음 단계 + +샘플시트가 여러 샘플에 대한 정보를 어떻게 구성하는지 알아보겠습니다. + +--- + +## 2. 샘플시트 패턴 + +### 2.1. 샘플시트란 무엇입니까? + +샘플시트는 입력 샘플을 설명하는 CSV 파일입니다. +각 행은 샘플이며, 열은 해당 샘플의 파일과 메타데이터를 지정합니다. + +지금까지 사용해온 샘플시트를 살펴보겠습니다: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +열은 다음과 같습니다: + +- `sample`: 고유한 샘플 식별자 +- `nuclear_image`: 핵 염색 이미지 (TIFF) +- `spot_table`: 전사체 스팟 (TXT) +- `membrane_image`: 막 염색 이미지 (TIFF, 선택사항) + +### 2.2. 파일 경로 + +샘플시트는 여러 경로 유형을 허용합니다: + +- **URL**: Nextflow가 자동으로 다운로드합니다 (위에 표시된 대로) +- **로컬 경로**: `data/nuclear.tiff` 또는 `/absolute/path/to/nuclear.tiff` +- **클라우드 스토리지**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +동일한 샘플시트에서 경로 유형을 혼합할 수 있습니다. + +### 2.3. 자신만의 샘플시트 만들기 + +먼저 테스트 데이터 파일을 로컬로 다운로드하겠습니다: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +이제 이러한 로컬 파일을 참조하도록 샘플시트를 수정하겠습니다: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "경고" + + 샘플시트의 경로는 샘플시트가 위치한 곳이 아니라 Nextflow를 **실행**하는 위치에 상대적입니다. + +마지막으로 로컬 파일 경로가 있는 샘플시트로 nf-core/molkart를 한 번 더 실행하겠습니다: + +`nextflow run ./molkart -params-file params.yaml -resume` + +보시다시피 Nextflow는 파일이 Github에서 다운로드되었을 때와 유사하게 이 실행을 수행합니다. 이것은 Nextflow의 훌륭한 기능 중 하나로, 데이터가 어디에 위치하든 상관없이 적절하게 스테이징합니다. + +### 요점 + +샘플시트는 파일 경로와 함께 메타데이터를 명시적으로 정의할 수 있는 방식으로 다중 샘플 데이터셋을 구성합니다. +대부분의 nf-core 파이프라인은 이 패턴을 사용합니다. + +### 다음 단계 + +입력에 대해 다루었으니, 이제 다양한 컴퓨팅 환경에 맞게 Nextflow 파이프라인을 구성하는 방법을 살펴보겠습니다. diff --git a/docs/ko/docs/nf4_science/imaging/04_config.md b/docs/ko/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..3c4b7d4ba3 --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# 파트 4: 구성 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +파트 1-3에서는 Nextflow를 실행하고, nf-core 파이프라인을 실행하며, 매개변수 파일과 샘플시트로 입력을 관리하는 방법을 배웠습니다. +이제 **구성 파일**과 **프로파일**을 사용하여 다양한 컴퓨팅 환경에 맞게 파이프라인을 구성하는 방법을 살펴보겠습니다. + +## 학습 목표 + +이 파트를 마치면 다음을 수행할 수 있습니다: + +- 여러 소스에서 Nextflow가 구성을 해석하는 방법 이해하기 +- 컨테이너 및 테스트를 위한 nf-core 내장 프로파일 사용하기 +- 다양한 컴퓨팅 환경을 위한 사용자 정의 프로파일 생성하기 +- 프로세스 레이블을 사용하여 리소스 요청 사용자 정의하기 +- 제한된 환경에서 리소스 제한 관리하기 +- `nextflow config`로 해석된 구성 검사하기 + +--- + +## 1. Nextflow 구성 이해하기 + +### 1.1. 구성 파일이란 무엇인가요? + +Nextflow는 구성 파일을 사용하여 **워크플로우 로직**(무엇을 할 것인가)과 **실행 설정**(어떻게 그리고 어디서 할 것인가)을 분리합니다. + +구성 파일이 제어하는 것: + +- 컨테이너 엔진(Docker, Singularity, Conda) +- 컴퓨팅 리소스(CPU, 메모리, 시간) +- 실행 플랫폼(로컬, HPC, 클라우드) +- 파이프라인 매개변수 + +### 1.2. 구성 우선순위 + +Nextflow는 여러 소스에서 구성을 로드하며, 나중에 로드된 소스가 이전 소스를 재정의합니다: + +1. **파이프라인 구성**: 파이프라인 저장소의 `nextflow.config` +2. **디렉토리 구성**: 현재 작업 디렉토리의 `nextflow.config` +3. **사용자 구성**: `~/.nextflow/config` +4. **명령줄**: 직접 전달된 매개변수 및 옵션 + +이러한 계층적 접근 방식을 통해 파이프라인의 기본값을 유지하고, 사용자별 설정으로 재정의하며, 명령줄에서 빠른 조정을 할 수 있습니다. + +### 1.3. 현재 구성 + +지금까지 사용한 구성을 살펴보겠습니다: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +파트 2에서 추가한 `docker.enabled = true` 줄을 주석 처리하거나 다시 변경하고, 대신 molkart에서 프로파일을 사용하여 동일한 결과를 얻을 수 있는 방법을 알아보겠습니다. + +--- + +## 2. 프로파일 사용하기 + +### 2.1. 프로파일이란 무엇인가요? + +프로파일은 `nextflow run` 명령을 통해 `-profile` 플래그로 활성화할 수 있는 명명된 구성 세트입니다. +프로파일을 사용하면 구성 파일을 편집하지 않고도 다양한 컴퓨팅 시나리오 간에 쉽게 전환할 수 있습니다. + +모든 nf-core 파이프라인에는 우리가 사용할 수 있는 여러 기본 프로파일이 함께 제공됩니다. + +### 2.2. 내장 프로파일 검사하기 + +파이프라인 코드베이스와 관련된 `molkart/nextflow.config` 파일에서 이들을 검사해 보겠습니다: + +```bash +code molkart/nextflow.config +``` + +`profiles` 블록을 검색하십시오: + +```groovy title="molkart/nextflow.config (발췌)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +일반적인 컨테이너 프로파일: + +- `docker`: Docker 컨테이너 사용(로컬 개발에 가장 일반적) +- `singularity`: Singularity/Apptainer 사용(HPC에서 일반적) +- `conda`: Conda 환경 사용 +- `apptainer`: Apptainer 컨테이너 사용 + +### 2.3. nextflow.config 대신 프로파일로 다시 실행하기 + +이제 로컬 `nextflow.config` 파일에서 docker 구성을 비활성화하고 프로파일을 이해했으므로, `-profile` 플래그를 사용하여 파이프라인을 다시 실행해 보겠습니다. + +이전 파트 3에서는 사용자 정의 매개변수가 포함된 `params.yaml` 파일을 만들었습니다. +이제 이를 내장 Docker 프로파일과 결합할 수 있습니다: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +각 플래그가 수행하는 작업을 살펴보겠습니다: + +- `-profile docker`: molkart의 `nextflow.config`에서 Docker 프로파일을 활성화하여 `docker.enabled = true`로 설정합니다 +- `-params-file params.yaml`: YAML 파일에서 모든 파이프라인 매개변수를 로드합니다 +- `-resume`: 이전 실행에서 캐시된 결과를 재사용합니다 + +`-resume`을 사용하기 때문에 Nextflow는 마지막 실행 이후 변경 사항이 있는지 확인합니다. +매개변수, 입력 및 코드가 동일하면 모든 작업이 캐시에서 검색되고 파이프라인이 거의 즉시 완료됩니다. + +```console title="출력 (발췌)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +모든 프로세스가 `cached: 2` 또는 `cached: 1`을 표시하는 것을 확인하십시오 - 아무것도 재실행되지 않았습니다! + +### 2.4. 테스트 프로파일 + +테스트 프로파일은 파이프라인이 작동하는지 확인할 수 있도록 기본 입력 매개변수와 데이터 파일을 지정하는 빠른 방법을 제공합니다. +nf-core 파이프라인은 항상 최소 두 개의 테스트 프로파일을 포함합니다: + +- `test`: 빠른 테스트를 위한 작은 데이터셋과 빠른 매개변수 +- `test_full`: 더 큰 데이터로 더 포괄적인 테스트 + +`includeConfig` 지시문을 사용하여 포함되는 molkart의 `test` 프로파일을 자세히 살펴보겠습니다: + +```groovy title="molkart/nextflow.config (발췌)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +이는 `-profile test`로 파이프라인을 실행할 때마다 Nextflow가 `conf/test.config`에서 구성을 로드한다는 의미입니다. + +```groovy title="molkart/conf/test.config (발췌)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +이 프로파일에는 이전에 `params.yaml` 파일에서 사용했던 것과 동일한 매개변수가 포함되어 있습니다. + +쉼표로 구분하여 여러 프로파일을 활성화할 수 있습니다. +이를 사용하여 params 파일 없이 파이프라인을 테스트해 보겠습니다: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +이것은 다음을 결합합니다: + +- `docker`: Docker 컨테이너 활성화 +- `test`: 테스트 데이터셋 및 매개변수 사용 + +프로파일은 왼쪽에서 오른쪽으로 적용되므로, 동일한 값을 설정하는 경우 나중 프로파일이 이전 프로파일을 재정의합니다. + +### 요점 + +nf-core 파이프라인에는 컨테이너, 테스트 및 특수 환경을 위한 내장 프로파일이 함께 제공됩니다. +여러 프로파일을 결합하여 필요한 구성을 만들 수 있습니다. + +### 다음 단계 + +다양한 컴퓨팅 환경을 위한 자체 사용자 정의 프로파일을 만드는 방법을 배웁니다. + +--- + +## 3. 사용자 정의 프로파일 만들기 + +### 3.1. 로컬 개발과 HPC 실행 간 전환을 위한 프로파일 만들기 + +두 가지 시나리오에 대한 사용자 정의 프로파일을 만들어 보겠습니다: + +1. Docker를 사용한 로컬 개발 +2. Slurm 스케줄러와 Singularity를 사용하는 대학 HPC + +`nextflow.config`에 다음을 추가하십시오: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +이제 환경 간에 쉽게 전환할 수 있습니다: + +```bash +# 로컬 개발용 +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# HPC용 (사용 가능한 경우) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! Note "참고" + + Slurm 스케줄러에 접근할 수 없으므로 이 교육 환경에서는 HPC 프로파일을 테스트할 수 없습니다. + 하지만 이것은 실제 사용을 위해 구성하는 방법을 보여줍니다. + +### 3.2. `nextflow config`를 사용하여 구성 검사하기 + +`nextflow config` 명령은 파이프라인을 실행하지 않고 완전히 해석된 구성을 보여줍니다. + +기본 구성 보기: + +```bash +nextflow config ./molkart +``` + +특정 프로파일로 구성 보기: + +```bash +nextflow config -profile local_dev ./molkart +``` + +이것은 다음에 매우 유용합니다: + +- 구성 문제 디버깅 +- 실제로 사용될 값 이해 +- 여러 프로파일이 상호 작용하는 방식 확인 + +### 요점 + +사용자 정의 프로파일을 사용하면 단일 명령줄 플래그로 다양한 컴퓨팅 환경 간에 전환할 수 있습니다. +`nextflow config`를 사용하여 실행 전에 해석된 구성을 검사하십시오. + +### 다음 단계 + +nf-core의 프로세스 레이블 시스템을 사용하여 개별 프로세스에 대한 리소스 요청을 사용자 정의하는 방법을 배웁니다. + +--- + +## 4. 리소스 요청 사용자 정의하기 + +### 4.1. nf-core 파이프라인의 프로세스 레이블 이해하기 + +간단히 하기 위해, nf-core 파이프라인은 [**프로세스 레이블**](https://www.nextflow.io/docs/latest/reference/process.html#process-label)을 사용하여 모든 파이프라인에서 리소스 할당을 표준화합니다. +각 프로세스에는 낮음, 중간 또는 높은 컴퓨팅 리소스 요구 사항을 설명하는 `process_low`, `process_medium` 또는 `process_high`와 같은 레이블이 태그됩니다. +이러한 레이블은 파이프라인의 `conf/` 디렉토리에 있는 구성 파일 중 하나에서 특정 리소스 요청으로 변환됩니다. + +```groovy title="molkart/conf/base.config (발췌)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +`task.attempt` 승수를 주목하십시오 - 이를 통해 파이프라인이 `process.maxRetries > 1`로 설정된 경우 후속 작업 재시도가 더 많은 리소스를 요청할 수 있습니다. + +### 4.2. 특정 프로세스에 대한 리소스 재정의 + +세밀한 제어를 위해 이름으로 개별 프로세스를 대상으로 지정하십시오: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +위의 재정의로 이 파이프라인을 실행하려고 하면 `CELLPOSE` 프로세스는 해당 레이블로 정의된 기본값 대신 16개의 CPU와 32GB 메모리를 요청합니다. +사용 가능한 RAM이 충분하지 않기 때문에 현재 환경에서는 파이프라인이 실패합니다. +다음 섹션에서 이러한 유형의 실패를 방지하는 방법을 배웁니다. + +!!! Tip "팁" + + 프로세스 이름을 찾으려면 파이프라인 실행 출력을 살펴보거나 `.nextflow.log`를 확인하십시오. + 프로세스 이름은 `WORKFLOW:SUBWORKFLOW:PROCESS` 패턴을 따릅니다. + +### 요점 + +nf-core 파이프라인은 프로세스 레이블을 사용하여 리소스 할당을 표준화합니다. +레이블별로(여러 프로세스에 영향) 또는 이름별로(특정 프로세스 하나에 영향) 리소스를 재정의할 수 있습니다. + +### 다음 단계 + +GitHub Codespaces와 같이 제한된 환경에서 리소스 제한을 관리하는 방법을 배웁니다. + +--- + +## 5. 제한된 환경에서 리소스 관리하기 + +### 5.1. 리소스 제한 문제 + +섹션 4.2에 표시된 것처럼 16개의 CPU와 32GB 메모리를 요청하는 프로세스로 molkart를 실행하려고 하면 사용 가능한 리소스가 충분하지 않아 현재 환경에서 실패합니다. +더 큰 노드가 있는 클러스터 환경에서는 이러한 요청이 스케줄러에 제출됩니다. + +GitHub Codespaces와 같이 제한된 환경에서 제한이 없으면 Nextflow는 사용 가능한 리소스를 초과하는 프로세스의 실행을 거부합니다. + +### 5.2. 리소스 제한 설정하기 + +`resourceLimits` 지시문은 지정된 값으로 리소스 요청을 제한합니다: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +이것은 Nextflow에게 다음과 같이 알려줍니다: "프로세스가 2개 이상의 CPU 또는 7GB 이상의 메모리를 요청하면 대신 이러한 제한으로 제한하십시오." + +### 5.3. 사용자 정의 프로파일에 리소스 제한 추가하기 + +적절한 제한을 포함하도록 사용자 정의 프로파일을 업데이트하십시오: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! Warning "경고" + + 리소스 제한을 너무 낮게 설정하면 프로세스가 실패하거나 느리게 실행될 수 있습니다. + 파이프라인은 메모리 집약도가 낮은 알고리즘을 사용하거나 더 작은 청크로 데이터를 처리해야 할 수 있습니다. + +### 요점 + +프로세스 리소스 요청을 제한하여 리소스 제약 환경에서 파이프라인을 실행하려면 `resourceLimits`를 사용하십시오. +서로 다른 프로파일은 해당 환경에 적합한 서로 다른 제한을 가질 수 있습니다. + +### 다음 단계 + +바이오이미징을 위한 핵심 Nextflow 교육을 완료했습니다! + +--- + +## 결론 + +이제 다양한 컴퓨팅 환경에 맞게 Nextflow 파이프라인을 구성하는 방법을 이해했습니다. + +배운 주요 기술: + +- **구성 우선순위**: 여러 소스에서 Nextflow가 설정을 해석하는 방법 +- **nf-core 프로파일**: 컨테이너, 테스트 및 유틸리티를 위한 내장 프로파일 사용 +- **사용자 정의 프로파일**: 다양한 환경을 위한 자체 프로파일 생성 +- **프로세스 레이블**: 레이블별 리소스 요청 이해 및 재정의 +- **리소스 제한**: `resourceLimits`로 제약된 환경 관리 +- **구성 검사**: 설정을 디버그하고 확인하기 위해 `nextflow config` 사용 + +이러한 구성 기술은 모든 Nextflow 파이프라인에 적용 가능하며 로컬 머신, HPC 클러스터 및 클라우드 플랫폼에서 워크플로우를 효율적으로 실행하는 데 도움이 됩니다. + +### 다음 단계 + +바이오이미징을 위한 Nextflow 과정을 완료한 것을 축하합니다! + +다음 단계: + +- 피드백을 제공하기 위해 과정 설문조사를 작성하십시오 +- 워크플로우 개발에 대해 더 자세히 알아보려면 [Hello Nextflow](../hello_nextflow/index.md)를 확인하십시오 +- nf-core 도구에 대해 더 깊이 이해하려면 [Hello nf-core](../hello_nf-core/index.md)를 살펴보십시오 +- [교육 컬렉션](../training_collections/index.md)에서 다른 과정을 찾아보십시오 diff --git a/docs/ko/docs/nf4_science/imaging/index.md b/docs/ko/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..412c6482ce --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/index.md @@ -0,0 +1,38 @@ +--- +title: 이미징을 위한 Nextflow 실행 +hide: + - toc +--- + +# 이미징을 위한 Nextflow 실행 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 교육 과정은 데이터 분석 파이프라인을 실행하고 사용자 정의하는 데 관심이 있는 이미징 및 공간 생물학 연구자를 위한 것입니다. +이 과정은 Molecular Cartography 공간 전사체학 데이터를 처리하는 파이프라인인 [nf-core/molkart](https://nf-co.re/molkart)를 사용하여 워크플로우를 실행하고, 구성하고, 설정하는 것과 관련된 기본 Nextflow 개념을 가르칩니다. +여기서 배우는 기술은 모든 Nextflow 또는 nf-core 파이프라인에 적용할 수 있습니다. + +시작해봅시다! 아래의 "Open in GitHub Codespaces" 버튼을 클릭하여 교육 환경을 실행하고(가급적 별도의 탭에서), 로드되는 동안 계속 읽어주십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## 학습 목표 + +이 과정을 통해 이미징 분석 파이프라인을 실행하는 데 기본 Nextflow 개념과 도구를 적용하는 방법을 배우게 됩니다. + +이 워크샵을 마치면 다음을 수행할 수 있습니다: + +- 로컬에서 Nextflow 워크플로우를 실행하고 실행을 모니터링합니다 +- Nextflow에서 생성된 출력(결과) 및 로그 파일을 찾고 해석합니다 +- 테스트 데이터 및 사용자 정의 입력으로 nf-core 파이프라인을 실행합니다 +- 프로파일 및 매개변수 파일을 사용하여 파이프라인 실행을 구성합니다 +- 샘플시트 및 명령줄 매개변수를 사용하여 입력을 관리합니다 + +## 대상 및 전제 조건 + +이 과정은 다음에 대한 최소한의 지식을 전제로 합니다: + +- 명령줄 사용 경험 +- 이미징 파일 형식에 대한 기본적인 지식(TIFF 이미지, 표 형식 데이터) + +기술적 요구 사항 및 환경 설정에 대해서는 [환경 설정](../../envsetup/) 단기 과정을 참조하십시오. diff --git a/docs/ko/docs/nf4_science/imaging/next_steps.md b/docs/ko/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..482ecabceb --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# 다음 단계 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging 교육을 완료하신 것을 축하합니다! + +이제 이미징 데이터 분석을 위한 Nextflow pipeline을 실행하고 구성하는 기초 기술을 갖추셨습니다. + +## 학습 계속하기 + +Nextflow 지식을 심화하기 위한 권장 다음 단계는 다음과 같습니다: + +### 더 많은 nf-core pipeline 탐색하기 + +- **모든 pipeline 둘러보기**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### 자신만의 pipeline 개발하기 + +Nextflow pipeline 작성 방법을 배우고 싶다면: + +- **[Hello Nextflow](../../hello_nextflow/)**: 포괄적인 Nextflow 개발 교육 +- **[Side Quests](../../side_quests/)**: pipeline 개발자를 위한 고급 주제 + +### 커뮤니티 참여하기 + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: 도움을 받고 다른 사용자들과 연결하세요 +- **[nf-core Slack](https://nf-co.re/join)**: nf-core 커뮤니티에 참여하세요 +- **[Seqera Community Forum](https://community.seqera.io)**: 질문하고 경험을 공유하세요 + +### 추가 자료 + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: 완전한 참조 문서 +- **[nf-core Documentation](https://nf-co.re/docs)**: 가이드라인 및 모범 사례 + +## 참여하기 + +- **nf-core에 기여하기**: pipeline 또는 문서 개선에 도움을 주세요 +- **workflow 공유하기**: 자신의 pipeline을 커뮤니티에 기여하세요 +- **이벤트 참석하기**: Nextflow Summit 및 커뮤니티 교육 세션에 참여하세요 + +함께 학습해 주셔서 감사합니다! diff --git a/docs/ko/docs/nf4_science/imaging/survey.md b/docs/ko/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..8aded925ef --- /dev/null +++ b/docs/ko/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging 교육을 완료해 주셔서 감사합니다! + +교육 자료를 개선하는 데 도움이 되도록 여러분의 피드백을 주시면 대단히 감사하겠습니다. + +간단한 설문조사를 완료하는 데 몇 분만 시간을 내주시기 바랍니다: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +여러분의 응답은 무엇이 잘 작동했고 향후 학습자들을 위해 무엇을 개선할 수 있는지 이해하는 데 도움이 될 것입니다. + +시간을 내어 참여해 주셔서 감사합니다! diff --git a/docs/ko/docs/nf4_science/index.md b/docs/ko/docs/nf4_science/index.md new file mode 100644 index 0000000000..62088d7e09 --- /dev/null +++ b/docs/ko/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: 과학을 위한 Nextflow +hide: + - toc +--- + +# 과학을 위한 Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정들은 [Hello Nextflow](../hello_nextflow/) 초급 과정에서 제시된 개념과 구성 요소를 특정 과학적 사용 사례에 적용하는 방법을 보여줍니다. 각 과정은 학습자가 점진적으로 기술을 쌓을 수 있도록 설계된 일련의 교육 모듈로 구성되어 있습니다. + +!!! exercise "유전체학을 위한 Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow로 유전체학 파이프라인을 개발하는 방법을 배웁니다. + + 이 과정은 자신만의 유전체학 파이프라인을 개발하고자 하는 연구자를 위한 것입니다. 이 과정은 변이 호출 사용 사례를 활용하여 간단하지만 기능적인 유전체학 파이프라인을 개발하는 방법을 보여줍니다. + + [유전체학을 위한 Nextflow 교육 시작하기 :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "RNAseq를 위한 Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow로 RNAseq 데이터 처리 파이프라인을 개발하는 방법을 배웁니다. + + 이 과정은 자신만의 RNAseq 파이프라인을 개발하고자 하는 연구자를 위한 것입니다. 이 과정은 벌크 RNAseq 처리 사용 사례를 활용하여 간단하지만 기능적인 RNAseq 파이프라인을 개발하는 방법을 보여줍니다. + + [RNAseq를 위한 Nextflow 교육 시작하기 :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "생물영상을 위한 Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow로 영상 데이터 파이프라인을 실행하는 방법을 배웁니다. + + 이 과정은 생물영상 파이프라인을 실행하고 구성하는 방법을 배우고자 하는 연구자를 위한 것입니다. 이 과정은 nf-core/molkart를 활용하여 모든 파이프라인에 적용 가능한 필수 Nextflow 사용 패턴을 보여줍니다. + + [생물영상을 위한 Nextflow 교육 시작하기 :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +커뮤니티 포럼의 [교육 섹션](https://community.seqera.io/c/training/)에 게시하여 여기에서 다루었으면 하는 다른 영역과 사용 사례를 알려주십시오. diff --git a/docs/ko/docs/nf4_science/rnaseq/00_orientation.md b/docs/ko/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..1b7d6edbfc --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# 오리엔테이션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +교육 환경에는 이 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로 직접 설치할 필요가 없습니다. +그러나 로그인하려면 (무료) 계정이 필요하며, 인터페이스에 익숙해지기 위해 몇 분 정도 시간을 할애해야 합니다. + +아직 완료하지 않았다면 더 진행하기 전에 [환경 설정](../../envsetup/) 단기 과정을 수강하시기 바랍니다. + +## 제공되는 자료 + +이 교육 과정 전반에 걸쳐 `nf4-science/rnaseq/` 디렉토리에서 작업하게 되며, 교육 작업 공간을 열 때 이 디렉토리로 이동해야 합니다. +이 디렉토리에는 필요한 모든 코드 파일, 테스트 데이터 및 부속 파일이 포함되어 있습니다. + +이 디렉토리의 내용을 자유롭게 탐색하십시오. 가장 쉬운 방법은 VSCode 인터페이스의 교육 작업 공간 왼쪽에 있는 파일 탐색기를 사용하는 것입니다. +또는 `tree` 명령을 사용할 수도 있습니다. +과정 전반에 걸쳐 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간 수정하기도 합니다. + +여기서는 두 번째 수준까지 목차를 생성합니다: + +```bash +tree . -L 3 +``` + +??? success "디렉토리 내용" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + 이것이 많아 보여도 걱정하지 마십시오. 과정의 각 단계에서 관련 부분을 살펴보겠습니다. + 이는 단지 개요를 제공하기 위한 것입니다. + +**시작하기 위해 알아야 할 사항은 다음과 같습니다:** + +- **`rnaseq.nf` 파일**은 개발할 워크플로우 스크립트의 개요입니다. + +- **`nextflow.config` 파일**은 최소한의 환경 속성을 설정하는 설정 파일입니다. 지금은 무시하셔도 됩니다. + +- **`data` 디렉토리**에는 입력 데이터 및 관련 리소스가 포함되어 있습니다: + + - 인간 염색체 20의 작은 영역(hg19/b37에서)으로 구성된 `genome.fa`라는 _참조 게놈_. + - 파일 크기를 줄이기 위해 작은 영역으로 부분 집합된 _RNAseq 데이터_, `reads/` 디렉토리에 있습니다. + - 일괄 처리를 위한 예제 데이터 파일의 ID 및 경로를 나열하는 _CSV 파일_. + +- **`solutions` 디렉토리**에는 과정의 각 단계에서 생성되는 완성된 워크플로우 스크립트 및 모듈이 포함되어 있습니다. + 이들은 작업을 확인하고 문제를 해결하기 위한 참조로 사용하기 위한 것입니다. + 파일 이름의 번호는 과정의 해당 부분 단계에 해당합니다. + +!!!tip + + 어떤 이유로든 이 디렉토리에서 벗어난 경우, 다음 명령을 실행하여 항상 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +이제 과정을 시작하려면 이 페이지의 오른쪽 하단 모서리에 있는 화살표를 클릭하십시오. diff --git a/docs/ko/docs/nf4_science/rnaseq/01_method.md b/docs/ko/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..45311720ab --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# 파트 1: 방법 개요 및 수동 테스트 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +대량 RNAseq 데이터를 처리하고 분석하는 여러 가지 유효한 방법이 있습니다. +이 과정에서는 [Babraham Institute](https://www.babraham.ac.uk/)의 Simon Andrews 박사와 Laura Biggins 박사가 [여기](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf)에서 설명한 방법을 따릅니다. + +우리의 목표는 다음 처리 단계를 구현하는 워크플로우를 개발하는 것입니다: 대량 RNAseq 샘플의 리드에 대한 초기 품질 관리 실행, 리드에서 어댑터 서열 트리밍, 참조 게놈에 리드 정렬, 그리고 포괄적인 품질 관리(QC) 보고서 생성. + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** FastQC를 사용하여 트리밍 전 리드 데이터에 대한 QC 수행 +- **TRIM_GALORE:** Trim Galore를 사용하여 어댑터 서열 트리밍 및 트리밍 후 QC 수행 (Cutadapt 및 FastQC 번들) +- **HISAT2_ALIGN:** Hisat2를 사용하여 참조 게놈에 리드 정렬 +- **MULTIQC:** MultiQC를 사용하여 포괄적인 QC 보고서 생성 + +그러나 워크플로우 코드를 작성하기 전에 먼저 일부 테스트 데이터로 명령을 수동으로 시도해 보겠습니다. +필요한 도구가 GitHub Codespaces 환경에 설치되어 있지 않으므로 컨테이너를 통해 사용할 것입니다 ([Hello Containers](../../hello_nextflow/05_hello_containers.md) 참조). + +!!! note "참고" + + `nf4-science/rnaseq` 디렉토리에 있는지 확인하십시오. `pwd`를 입력할 때 표시되는 경로의 마지막 부분은 `rnaseq`이어야 합니다. + +--- + +## 1. 초기 QC 및 어댑터 트리밍 + +`fastqc`와 `trim_galore`가 모두 설치된 컨테이너 이미지를 가져와서 대화형으로 실행하고 예제 데이터 파일 중 하나에서 트리밍 및 QC 명령을 실행할 것입니다. + +### 1.1. 컨테이너 가져오기 + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +시스템이 이미지를 다운로드하면 다음과 같은 콘솔 출력이 표시됩니다: + +??? success "명령 출력" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. 대화형으로 컨테이너 실행하기 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "명령 출력" + + ```console + + ``` +--> + +프롬프트가 `(base) root@b645838b3314:/tmp#`와 같이 변경되며, 이는 이제 컨테이너 내부에 있음을 나타냅니다. + +명령의 `-v ./data:/data` 부분은 컨테이너 내부에서 `data/` 디렉토리의 내용에 액세스할 수 있게 합니다. + +```bash +ls /data/reads +``` + +??? success "명령 출력" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. 첫 번째 `fastqc` 명령 실행하기 + +`fastqc`를 실행하여 리드 데이터에 대한 품질 관리 메트릭을 수집해 보겠습니다. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "명령 출력" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +이 명령은 매우 빠르게 실행됩니다. +원본 데이터와 동일한 디렉토리에서 출력 파일을 찾을 수 있습니다: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="출력" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. `trim_galore`로 어댑터 서열 트리밍하기 + +이제 Cutadapt 및 FastQC를 번들로 제공하는 `trim_galore`를 실행하여 어댑터 서열을 트리밍하고 트리밍 후 QC 메트릭을 수집해 보겠습니다. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +`--fastqc` 플래그는 트리밍이 완료된 후 QC 수집 단계를 자동으로 실행하도록 합니다. + +_출력이 매우 상세하므로 다음은 축약된 내용입니다._ + +??? success "명령 출력" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +작업 디렉토리에서 출력 파일을 찾을 수 있습니다: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="출력" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. 출력 파일을 컨테이너 외부의 파일시스템으로 이동하기 + +컨테이너 내부에 남아 있는 모든 것은 향후 작업에 액세스할 수 없으므로 새 디렉토리로 이동하겠습니다. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. 컨테이너 종료하기 + +```bash +exit +``` + +--- + +## 2. 참조 게놈에 리드 정렬하기 + +`hisat2`가 설치된 컨테이너 이미지를 가져와서 대화형으로 실행하고 RNAseq 데이터를 참조 게놈에 정렬하는 정렬 명령을 실행할 것입니다. + +### 2.1. `hisat2` 컨테이너 가져오기 + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "명령 출력" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. 대화형으로 `hisat2` 컨테이너 실행하기 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +명령은 이전과 동일하며 관련 컨테이너 URI로 교체되었습니다. + +### 2.3. Hisat2 게놈 인덱스 파일 생성하기 + +Hisat2는 게놈 참조가 매우 특정한 형식으로 제공되어야 하며 우리가 제공하는 `genome.fa` FASTA 파일만으로는 사용할 수 없으므로 이 기회에 관련 리소스를 생성하겠습니다. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +출력이 매우 상세하므로 다음은 축약된 내용입니다: + +<!-- TODO: switch to full output --> + +??? success "명령 출력" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +이렇게 하면 작업 디렉토리에서 찾을 수 있는 여러 게놈 인덱스 파일이 생성됩니다. + +```bash +ls genome_index.* +``` + +```console title="출력" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +잠시 후에 사용할 것이지만 먼저 이러한 게놈 인덱스 파일로 gzip 압축된 tarball을 생성하겠습니다. 나중에 필요하며 이러한 파일을 생성하는 것은 일반적으로 워크플로우의 일부로 수행하고 싶지 않은 작업입니다. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +이렇게 하면 게놈 인덱스 파일이 포함된 `genome_index.tar.gz` tarball이 파일시스템의 `data/` 디렉토리에 저장되며, 이 과정의 파트 2에서 유용하게 사용됩니다. + +### 2.4. `hisat2` 명령 실행하기 + +이제 `hisat2`로 정렬 단계를 수행한 다음 출력을 `samtools`로 파이프하여 출력을 BAM 파일로 작성하는 정렬 명령을 실행할 수 있습니다. + +리드 데이터 입력은 이전 단계에서 `trim_galore`로 생성한 `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` 파일입니다. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "명령 출력" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +매우 작은 테스트 파일이므로 거의 즉시 실행됩니다. +실제 규모에서는 훨씬 더 오래 걸릴 수 있습니다. + +다시 한 번 작업 디렉토리에서 출력 파일을 찾을 수 있습니다: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="출력" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. 출력 파일을 컨테이너 외부의 파일시스템으로 이동하기 + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. 컨테이너 종료하기 + +```bash +exit +``` + +--- + +## 3. 포괄적인 QC 보고서 생성하기 + +`multiqc`가 설치된 컨테이너 이미지를 가져와서 대화형으로 실행하고 before/after FastQC 보고서 파일에서 보고서 생성 명령을 실행할 것입니다. + +### 3.1. `multiqc` 컨테이너 가져오기 + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "명령 출력" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. 대화형으로 `multiqc` 컨테이너 실행하기 + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. `multiqc` 명령 실행하기 + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "명령 출력" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC는 호환 가능한 QC 보고서를 찾기 위해 디렉토리를 검색할 수 있으며 찾은 모든 것을 집계합니다. + +여기서 도구가 우리가 생성한 세 가지 QC 보고서를 모두 찾았음을 알 수 있습니다: `fastqc`로 수행한 초기 QC, (`trim_galore`를 통해 생성된) `cutadapt`의 트리밍 후 보고서, 그리고 `hisat2`가 생성한 정렬 후 QC입니다. + +출력 파일은 다시 작업 디렉토리에 있습니다: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="출력" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. 출력 파일을 컨테이너 외부의 파일시스템으로 이동하기 + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. 컨테이너 종료하기 + +```bash +exit +``` + +--- + +### 핵심 정리 + +관련 컨테이너에서 모든 개별 명령을 대화형으로 테스트했습니다. + +### 다음 단계는? + +동일한 명령을 컨테이너를 사용하여 작업을 실행하는 다단계 워크플로우로 적용하는 방법을 배웁니다. diff --git a/docs/ko/docs/nf4_science/rnaseq/02_single-sample.md b/docs/ko/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..e0f913e162 --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# 파트 2: 단일 샘플 구현 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 이 부분에서는 파트 1에서 실행한 모든 명령을 적용하여 자동으로 실행하는 가장 간단한 워크플로우를 작성하며, 한 번에 하나의 샘플만 처리하는 것을 목표로 합니다. + +이를 세 단계로 진행합니다: + +1. 초기 QC 단계를 실행하는 단일 단계 워크플로우 작성 +2. 어댑터 트리밍 및 트리밍 후 QC 추가 +3. 참조 게놈에 대한 정렬 추가 + +!!! warning "필수 조건" + + 이 레슨을 시작하기 전에 과정의 파트 1을 완료해야 합니다. + 특히, 섹션 2.1-3을 진행하면 이 레슨의 정렬 단계에 필요한 게놈 인덱스 파일(`data/genome_index.tar.gz`)이 생성됩니다. + +--- + +## 1. 초기 QC를 실행하는 단일 단계 워크플로우 작성 + +단일 말단 RNAseq 리드가 포함된 FASTQ 파일에서 FastQC 도구를 실행하는 간단한 워크플로우를 작성하는 것부터 시작하겠습니다. + +워크플로우의 주요 부분을 요약한 워크플로우 파일 `rnaseq.nf`를 제공합니다. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// 모듈 INCLUDE 문 + +/* + * Pipeline parameters + */ + +// 기본 입력 + +workflow { + + // 입력 채널 생성 + + // 프로세스 호출 + +} +``` + +이 워크플로우 코드는 정확하지만 기능적이지 않다는 점을 유념하십시오. 이는 실제 워크플로우를 작성하는 데 사용할 골격 역할만 하기 위한 것입니다. + +### 1.1. 모듈을 저장할 디렉토리 생성 + +각 프로세스에 대해 독립적인 모듈을 생성하여 관리 및 재사용을 쉽게 할 것이므로 모듈을 저장할 디렉토리를 생성하겠습니다. + +```bash +mkdir modules +``` + +### 1.2. QC 메트릭 수집 프로세스용 모듈 생성 + +`FASTQC` 프로세스를 담을 `modules/fastqc.nf`라는 모듈 파일을 생성하겠습니다: + +```bash +touch modules/fastqc.nf +``` + +코드 편집기에서 파일을 열고 다음 코드를 복사합니다: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +이 교육 시리즈의 파트 1 및 파트 2에서 배운 모든 요소를 인식할 수 있을 것입니다. 유일한 주목할 만한 변경 사항은 이번에 `publishDir` 지시문에 `mode: symlink`를 사용하고 매개변수를 사용하여 `publishDir`를 정의한다는 것입니다. + +!!! note + + 여기서 사용하는 데이터 파일은 매우 작지만, 유전체학에서는 매우 커질 수 있습니다. 교육 환경에서의 시연 목적으로 불필요한 파일 복사를 피하기 위해 'symlink' 게시 모드를 사용하고 있습니다. `work` 디렉토리를 정리할 때 결과를 잃게 되므로 최종 워크플로우에서는 이렇게 하지 않아야 합니다. + +### 1.3. 워크플로우 파일에 모듈 가져오기 + +`rnaseq.nf` 파일에 `include { FASTQC } from './modules/fastqc.nf'` 문을 추가합니다: + +```groovy title="rnaseq.nf" linenums="3" +// 모듈 INCLUDE 문 +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. 입력 선언 추가 + +기본값이 있는 입력 매개변수를 선언합니다: + +```groovy title="rnaseq.nf" linenums="10" +params { + // 기본 입력 + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. workflow 블록에 입력 채널 생성 + +기본 `.fromPath()` 채널 팩토리를 사용하여 입력 채널을 생성합니다: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // 파일 경로에서 입력 채널 생성 + read_ch = channel.fromPath(params.reads) + + // 프로세스 호출 + +} +``` + +### 1.6. 입력 채널에서 `FASTQC` 프로세스 호출 + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // 파일 경로에서 입력 채널 생성 + read_ch = channel.fromPath(params.reads) + + // 초기 품질 관리 + FASTQC(read_ch) + +} +``` + +### 1.7. 워크플로우를 실행하여 작동 확인 + +명령줄에서 `--reads` 매개변수를 사용하여 입력을 지정할 수 있지만, 개발 중에는 설정한 테스트 기본값을 사용할 수 있습니다. + +```bash +nextflow run rnaseq.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +파트 1을 진행하고 이미 컨테이너를 가져왔다면 매우 빠르게 실행될 것입니다. +건너뛰었다면 Nextflow가 컨테이너를 가져올 것입니다. 이를 위해 아무것도 할 필요가 없지만 최대 1분 정도 기다려야 할 수 있습니다. + +`FASTQC` 프로세스의 `publishDir` 지시문에 지정된 대로 `results/fastqc` 아래에서 출력을 찾을 수 있습니다. + +```bash +ls results/fastqc +``` + +```console title="출력" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. 어댑터 트리밍 및 트리밍 후 품질 관리 추가 + +트리밍 자체를 위한 Cutadapt와 트리밍 후 품질 관리를 위한 FastQC를 번들로 제공하는 Trim_Galore 래퍼를 사용할 것입니다. + +### 2.1. 트리밍 및 QC 프로세스용 모듈 생성 + +`TRIM_GALORE` 프로세스를 담을 `modules/trim_galore.nf`라는 모듈 파일을 생성하겠습니다: + +```bash +touch modules/trim_galore.nf +``` + +코드 편집기에서 파일을 열고 다음 코드를 복사합니다: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. 워크플로우 파일에 모듈 가져오기 + +`rnaseq.nf` 파일에 `include { TRIM_GALORE } from './modules/trim_galore.nf'` 문을 추가합니다: + +```groovy title="rnaseq.nf" linenums="3" +// 모듈 INCLUDE 문 +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. 입력 채널에서 프로세스 호출 + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // 파일 경로에서 입력 채널 생성 + read_ch = channel.fromPath(params.reads) + + // 초기 품질 관리 + FASTQC(read_ch) + + // 어댑터 트리밍 및 트리밍 후 QC + TRIM_GALORE(read_ch) +} +``` + +### 2.4. 워크플로우를 실행하여 작동 확인 + +```bash +nextflow run rnaseq.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +매우 작은 입력 파일에서 실행하고 있으므로 이것도 매우 빠르게 실행될 것입니다. + +`TRIM_GALORE` 프로세스의 `publishDir` 지시문에 지정된 대로 `results/trimming` 아래에서 출력을 찾을 수 있습니다. + +```bash +ls results/trimming +``` + +```console title="출력" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. 리드를 참조 게놈에 정렬 + +마지막으로 Hisat2를 사용하여 게놈 정렬 단계를 실행할 수 있으며, 이는 FastQC 스타일의 품질 관리 메트릭도 출력합니다. + +### 3.1. HiSat2 프로세스용 모듈 생성 + +`HISAT2_ALIGN` 프로세스를 담을 `modules/hisat2_align.nf`라는 모듈 파일을 생성하겠습니다: + +```bash +touch modules/hisat2_align.nf +``` + +코드 편집기에서 파일을 열고 다음 코드를 복사합니다: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. 워크플로우 파일에 모듈 가져오기 + +`rnaseq.nf` 파일에 `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` 문을 추가합니다: + +```groovy title="rnaseq.nf" linenums="3" +// 모듈 INCLUDE 문 +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. 게놈 인덱스를 제공하기 위한 매개변수 선언 추가 + +기본값이 있는 입력 매개변수를 선언합니다: + +```groovy title="rnaseq.nf" linenums="8" +params { + // 기본 입력 + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // 참조 게놈 아카이브 + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. `TRIM_GALORE`에서 출력된 트리밍된 리드에서 `HISAT2_ALIGN` 프로세스 호출 + +트리밍된 리드는 이전 단계에서 출력된 `TRIM_GALORE.out.trimmed_reads` 채널에 있습니다. + +또한 `file (params.hisat2_index_zip)`를 사용하여 Hisat2 도구에 gzip으로 압축된 게놈 인덱스 tarball을 제공합니다. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // 파일 경로에서 입력 채널 생성 + read_ch = channel.fromPath(params.reads) + + // 초기 품질 관리 + FASTQC(read_ch) + + // 어댑터 트리밍 및 트리밍 후 QC + TRIM_GALORE(read_ch) + + // 참조 게놈에 정렬 + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. 워크플로우를 실행하여 작동 확인 + +```bash +nextflow run rnaseq.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +`HISAT2_ALIGN` 프로세스의 `publishDir` 지시문에 지정된 대로 `results/align` 아래에서 출력을 찾을 수 있습니다. + +```bash +ls results/align +``` + +```console title="출력" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +이것으로 각 샘플에 적용해야 하는 기본 처리가 완료됩니다. + +_워크플로우가 한 번에 여러 샘플을 허용하도록 만든 후 파트 2에서 MultiQC 보고서 집계를 추가할 것입니다._ + +--- + +### 요약 + +단일 말단 RNAseq 샘플을 개별적으로 처리하는 모든 핵심 단계를 적용하는 방법을 배웠습니다. + +### 다음 단계는? + +여러 샘플을 병렬로 처리하도록 워크플로우를 수정하고, 모든 샘플의 모든 단계에서 QC 보고서를 집계하며, 페어드 엔드 RNAseq 데이터에서 워크플로우를 실행할 수 있도록 하는 방법을 배웁니다. diff --git a/docs/ko/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/ko/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..b238f9671a --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# 파트 3: 다중 샘플 paired-end 구현 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 과정의 마지막 파트에서는 간단한 워크플로우를 한 단계 더 발전시켜 임의의 수의 샘플을 처리할 수 있는 강력한 배치 자동화 도구로 전환하겠습니다. +그리고 그 과정에서 더 최근 연구에서 일반적으로 사용되는 paired-end 데이터를 처리하도록 전환하겠습니다. + +이를 세 단계로 진행하겠습니다: + +1. 워크플로우가 여러 입력 샘플을 받고 병렬로 실행하도록 만들기 +2. 포괄적인 QC 보고서 생성 추가 +3. paired-end RNAseq 데이터로 전환 + +--- + +## 1. 워크플로우가 여러 입력 샘플을 받고 병렬로 실행하도록 만들기 + +입력을 관리하는 방식을 변경해야 합니다. + +### 1.1. 기본 입력을 단일 파일 대신 파일 경로의 CSV로 변경 + +`data/` 디렉토리에 샘플 ID와 FASTQ 파일 경로가 포함된 CSV 파일을 제공합니다. +이 CSV 파일에는 헤더 줄이 포함되어 있습니다. +FASTQ 파일 경로는 절대 경로입니다. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +기본 입력 매개변수의 이름을 `input_csv`로 바꾸고 기본값을 `single-end.csv` 파일의 경로로 변경하겠습니다. + +```groovy title="rnaseq.nf" linenums="13" +params { + // 기본 입력 + input_csv: Path = "data/single-end.csv" + + // 참조 게놈 아카이브 + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. CSV를 입력으로 처리하도록 입력 채널 팩토리 업데이트 + +파일 경로 자체가 아니라 파일의 내용을 채널에 로드하려고 하므로 `.splitCsv()` 연산자를 사용하여 CSV 형식을 파싱한 다음 `.map()` 연산자를 사용하여 원하는 특정 정보(FASTQ 파일 경로)를 가져옵니다. + +```groovy title="rnaseq.nf" linenums="16" + // CSV 파일의 내용에서 입력 채널 생성 + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. 워크플로우를 실행하여 작동하는지 테스트 + +```bash +nextflow run rnaseq.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +이번에는 제공한 6개의 데이터 파일 각각에 대해 각 단계가 6번씩 실행되는 것을 볼 수 있습니다. + +워크플로우가 여러 파일에서 실행되도록 하는 데 필요한 것은 이것이 전부입니다! +Nextflow가 모든 병렬 처리를 자동으로 처리합니다. + +--- + +## 2. 전처리 QC 메트릭을 단일 MultiQC 보고서로 집계 + +이렇게 하면 많은 QC 보고서가 생성되며, 개별 보고서를 일일이 찾아보고 싶지 않습니다. +이것이 MultiQC 보고서 집계 단계를 추가하기에 완벽한 시점입니다! + +### 2.1. QC 집계 프로세스를 위한 모듈 생성 + +`MULTIQC` 프로세스를 담을 `modules/multiqc.nf`라는 모듈 파일을 만들겠습니다: + +```bash +touch modules/multiqc.nf +``` + +코드 편집기에서 파일을 열고 다음 코드를 복사합니다: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. 워크플로우 파일에 모듈 import + +`rnaseq.nf` 파일에 `include { MULTIQC } from './modules/multiqc.nf'` 문을 추가합니다: + +```groovy title="rnaseq.nf" linenums="3" +// 모듈 INCLUDE 문 +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. `report_id` 매개변수를 추가하고 적절한 기본값 지정 + +```groovy title="rnaseq.nf" linenums="9" +params { + // 기본 입력 + input_csv: Path = "data/single-end.csv" + + // 참조 게놈 아카이브 + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // 보고서 ID + report_id: String = "all_single-end" +} +``` + +### 2.4. 이전 단계의 출력에 대해 프로세스 호출 + +이전 단계의 모든 QC 관련 출력을 `MULTIQC` 프로세스에 제공해야 합니다. + +이를 위해 여러 채널을 하나로 집계하는 `.mix()` 연산자를 사용하겠습니다. + +각각 간단한 `.out` 채널을 가진 A, B, C, D라는 네 개의 프로세스가 있다면 구문은 다음과 같습니다: `A.out.mix( B.out, C.out, D.out )`. 보시다시피, 결합하려는 채널 중 첫 번째 채널에 적용하고(어느 것이든 상관없음) 그 뒤에 나오는 괄호 안에 쉼표로 구분하여 나머지를 모두 추가합니다. + +우리 워크플로우의 경우 집계할 출력은 다음과 같습니다: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +따라서 구문 예제는 다음과 같이 됩니다: + +```groovy title="MULTIQC 호출에서 .mix() 적용" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +이렇게 하면 샘플당 QC 보고서가 수집됩니다. +그러나 모든 샘플에 걸쳐 집계하려면 모든 샘플의 보고서를 단일 `MULTIQC` 호출로 가져오기 위해 `collect()` 연산자를 추가해야 합니다. +그리고 `report_id` 매개변수도 제공해야 합니다. + +이렇게 하면 다음과 같이 됩니다: + +```groovy title="완성된 MULTIQC 호출" linenums="33" + // 종합 QC 보고서 생성 + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +전체 워크플로우 블록의 컨텍스트에서는 다음과 같이 보입니다: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // CSV 파일의 내용에서 입력 채널 생성 + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// 초기 품질 관리 + FASTQC(read_ch) + + // 어댑터 트리밍 및 트리밍 후 QC + TRIM_GALORE(read_ch) + + // 참조 게놈에 정렬 + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // 종합 QC 보고서 생성 + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. 워크플로우를 실행하여 작동하는지 테스트 + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +이번에는 캐시된 프로세스 호출 후에 단일 MULTIQC 호출이 추가된 것을 볼 수 있습니다: + +`TRIM_GALORE` 프로세스의 `publishDir` 지시문에 지정된 대로 `results/trimming` 아래에서 출력을 찾을 수 있습니다. + +```bash +tree -L 2 results/multiqc +``` + +```console title="출력" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +마지막 `all_single-end.html` 파일은 하나의 쉽게 탐색할 수 있는 HTML 파일로 편리하게 패키징된 전체 집계 보고서입니다. + +--- + +## 3. paired-end RNAseq 데이터 처리 활성화 + +현재 우리의 워크플로우는 single-end RNAseq 데이터만 처리할 수 있습니다. +paired-end RNAseq 데이터를 보는 것이 점점 일반적이므로 이를 처리할 수 있기를 원합니다. + +워크플로우를 데이터 타입에 완전히 독립적으로 만들려면 약간 더 고급 Nextflow 언어 기능을 사용해야 하므로 여기서는 그렇게 하지 않겠지만, 무엇을 조정해야 하는지 보여주기 위해 paired-end 처리 버전을 만들 수 있습니다. + +### 3.1. `rnaseq_pe.nf`라는 워크플로우 복사본 만들기 + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. 기본 `input_csv`를 paired-end 데이터를 가리키도록 수정 + +`data/` 디렉토리에 샘플 ID와 paired FASTQ 파일 경로가 포함된 두 번째 CSV 파일을 제공합니다 + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +`input_csv` 기본값을 `paired-end.csv` 파일의 경로로 변경하겠습니다. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // 기본 입력 + input_csv: Path = "data/paired-end.csv" + + // 참조 게놈 아카이브 + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // 보고서 ID + report_id: String = "all_single-end" +} +``` + +### 3.3. 채널 팩토리 업데이트 + +이제 두 FASTQ 파일 경로를 모두 가져오도록 `.map()` 연산자에 지시해야 합니다. + +따라서 `row -> file(row.fastq_path)`는 `row -> [file(row.fastq_1), file(row.fastq_2)]`가 됩니다 + +```groovy title="rnaseq_pe.nf" linenums="19" + // CSV 파일의 내용에서 입력 채널 생성 + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. FASTQC 프로세스의 paired-end 버전 만들기 + +두 버전을 모두 사용할 수 있도록 모듈 복사본을 만들겠습니다. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +코드 편집기에서 새 `fastqc_pe.nf` 모듈 파일을 열고 다음 코드 변경 사항을 적용합니다: + +- `script` 블록(17번째 줄)에서 `fastqc $reads`를 `fastqc ${reads}`로 변경하여 `reads` 입력이 이제 단일 경로가 아니라 두 경로의 튜플이므로 압축이 해제되도록 합니다. +- 출력 파일을 개별적으로 처리하지 않도록 `${reads.simpleName}`을 와일드카드(`*`)로 바꿉니다. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +기술적으로 이것은 `FASTQC` 프로세스를 single-end 또는 paired-end RNAseq 데이터를 처리할 수 있도록 일반화합니다. + +마지막으로, 모듈의 paired-end 버전을 사용하도록 모듈 import 문을 업데이트합니다. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. TRIM_GALORE 프로세스의 paired-end 버전 만들기 + +두 버전을 모두 사용할 수 있도록 모듈 복사본을 만듭니다. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +코드 편집기에서 새 `trim_galore_pe.nf` 모듈 파일을 열고 다음 코드 변경 사항을 적용합니다: + +- 입력 선언을 `path reads`에서 `tuple path(read1), path(read2)`로 변경 +- `script` 블록의 명령을 업데이트하여 `$reads`를 `--paired ${read1} ${read2}`로 바꿉니다 +- 추가된 파일과 다른 명명 규칙을 반영하도록 출력 선언을 업데이트하고, 모든 것을 나열하지 않도록 와일드카드를 사용합니다. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +마지막으로, 모듈의 paired-end 버전을 사용하도록 모듈 import 문을 업데이트합니다. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. TRIM_GALORE에서 두 개의 보고서를 받을 것으로 예상하도록 MULTIQC 프로세스 호출 업데이트 + +`TRIM_GALORE` 프로세스가 이제 추가 출력 채널을 생성하므로 이를 MultiQC에 공급해야 합니다. + +`TRIM_GALORE.out.fastqc_reports,`를 `TRIM_GALORE.out.fastqc_reports_1,`과 `TRIM_GALORE.out.fastqc_reports_2,`로 바꿉니다: + +```groovy title="rnaseq_pe.nf" linenums="33" + // 종합 QC 보고서 생성 + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +MultiQC에 대해 이야기하는 김에 `report_id` 매개변수 기본값도 `"all_single-end"`에서 `"all_paired-end"`로 업데이트하겠습니다. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // 기본 입력 + input_csv: Path = "data/paired-end.csv" + + // 참조 게놈 아카이브 + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // 보고서 ID + report_id: String = "all_paired-end" +} +``` + +### 3.7. HISAT2_ALIGN 프로세스의 paired-end 버전 만들기 + +두 버전을 모두 사용할 수 있도록 모듈 복사본을 만듭니다. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +코드 편집기에서 새 `hisat2_align_pe.nf` 모듈 파일을 열고 다음 코드 변경 사항을 적용합니다: + +- 입력 선언을 `path reads`에서 `tuple path(read1), path(read2)`로 변경 +- `script` 블록의 명령을 업데이트하여 `-U $reads`를 `-1 ${read1} -2 ${read2}`로 바꿉니다 +- `script` 블록의 명령과 출력 선언에서 `${reads.simpleName}`의 모든 인스턴스를 `${read1.simpleName}`으로 바꿉니다. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +마지막으로, 모듈의 paired-end 버전을 사용하도록 모듈 import 문을 업데이트합니다. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. 워크플로우를 실행하여 작동하는지 테스트 + +캐시되지 않으므로 `-resume`을 사용하지 않으며, 이전보다 처리할 데이터가 두 배 더 많지만 1분 이내에 완료되어야 합니다. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +이것으로 끝입니다! 이제 워크플로우의 약간 다른 두 버전이 있습니다. 하나는 single-end 읽기 데이터용이고 다른 하나는 paired-end 데이터용입니다. +다음 논리적 단계는 워크플로우가 즉시 두 데이터 타입을 모두 받을 수 있도록 만드는 것이며, 이는 이 과정의 범위를 벗어나지만 후속 과정에서 다룰 수 있습니다. + +--- + +### 요점 정리 + +단일 샘플 워크플로우를 여러 샘플의 병렬 처리로 조정하고, 포괄적인 QC 보고서를 생성하며, 필요한 경우 paired-end 읽기 데이터를 사용하도록 워크플로우를 조정하는 방법을 알게 되었습니다. + +### 다음 단계는? + +축하합니다. Nextflow For RNAseq 단기 과정을 완료하셨습니다! 성공을 축하하고 충분한 휴식을 취하세요! + +다음으로, 이 교육 과정에 대한 귀하의 경험에 대한 매우 짧은 설문조사를 완료해 주시기 바라며, 그런 다음 추가 교육 리소스 및 유용한 링크가 포함된 페이지로 안내해 드리겠습니다. diff --git a/docs/ko/docs/nf4_science/rnaseq/index.md b/docs/ko/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..f2558a0999 --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: RNAseq을 위한 Nextflow +hide: + - toc +--- + +# RNAseq을 위한 Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 교육 과정은 데이터 분석 파이프라인을 개발하거나 맞춤화하는 데 관심이 있는 전사체학 및 관련 분야의 연구자를 위한 것입니다. +이 과정은 [Hello Nextflow](../../hello_nextflow/) 초급 교육을 기반으로 하며 bulk RNAseq 분석의 특정 맥락에서 Nextflow를 사용하는 방법을 보여줍니다. + +구체적으로, 이 과정은 어댑터 서열을 트리밍하고, 리드를 참조 게놈에 정렬하며, 여러 단계에서 품질 관리(QC)를 수행하는 간단한 bulk RNAseq 처리 파이프라인을 구현하는 방법을 보여줍니다. + +시작해 봅시다! 아래의 "Open in GitHub Codespaces" 버튼을 클릭하여 교육 환경을 실행하고(별도 탭에서 여는 것을 권장합니다), 로딩되는 동안 계속 읽어 주시기 바랍니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## 학습 목표 + +이 과정을 진행하면서 일반적인 RNAseq 사용 사례에 기본적인 Nextflow 개념과 도구를 적용하는 방법을 배우게 됩니다. + +이 워크샵을 마치면 다음을 수행할 수 있게 됩니다: + +- 기본 RNAseq 처리 및 QC 방법을 적용하는 선형 워크플로우 작성하기 +- FASTQ 및 참조 게놈 리소스와 같은 도메인별 파일을 적절하게 처리하기 +- 단일 말단 및 쌍 말단 시퀀싱 데이터 처리하기 +- Nextflow의 데이터 플로우 패러다임을 활용하여 샘플별 RNAseq 처리를 병렬화하기 +- 관련 채널 연산자를 사용하여 여러 단계와 샘플에 걸쳐 QC 리포트를 집계하기 + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## 전제 조건 + +이 과정은 다음에 대한 최소한의 친숙함을 가정합니다: + +- 이 과학 분야에서 일반적으로 사용되는 도구 및 파일 형식 +- 명령줄 사용 경험 +- [Hello Nextflow](../../hello_nextflow/) 초급 교육에서 다룬 기본적인 Nextflow 개념 및 도구 + +기술적 요구 사항 및 환경 설정에 대해서는 [환경 설정](../../envsetup/) 단기 과정을 참조하십시오. diff --git a/docs/ko/docs/nf4_science/rnaseq/next_steps.md b/docs/ko/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..b110283801 --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# 다음 단계 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For RNAseq 교육 과정을 완료하신 것을 다시 한번 축하드리며, 설문조사에 응해 주셔서 감사합니다! + +--- + +## 1. Nextflow 기술을 향상시키는 3가지 방법 + +방금 완료하신 과정을 바탕으로 다음에 수행할 작업에 대한 세 가지 권장 사항을 소개합니다. + +### 1.1. 다른 과학적 분석 사용 사례에 Nextflow 적용하기 + +**[Nextflow for Science](../nf4_science/index.md) 페이지를 확인하십시오.** Hello Nextflow에서 제시된 기본 개념과 메커니즘을 일반적인 과학적 분석 사용 사례에 적용하는 방법을 보여주는 짧은 단독형 과정 목록이 있습니다. + +관련성 있는 사용 사례로 귀하의 도메인이 표현되지 않은 경우, [Community forum](https://community.seqera.io/)에 알려주시면 개발 목록에 추가하겠습니다. + +### 1.2. nf-core 시작하기 + +**[nf-core](https://nf-co.re/)**는 다양한 과학 연구 응용 프로그램을 위한 표준화된 오픈 소스 pipeline을 개발하기 위한 전 세계적인 공동 작업입니다. +이 프로젝트에는 즉시 사용할 수 있는 [100개 이상의 pipeline](https://nf-co.re/pipelines/)과 자신의 프로젝트에 통합할 수 있는 [1400개 이상의 process 모듈](https://nf-co.re/modules/), 그리고 풍부한 개발자 도구 세트가 포함되어 있습니다. + +**[Hello nf-core](../../hello_nf-core/index.md)** 교육 과정은 재현 가능하고 확장 가능하며 표준화된 workflow를 작성하는 데 도움이 되도록 설계된 nf-core 커뮤니티 관리 pipeline 및 개발 프레임워크를 소개합니다. 기존 nf-core pipeline을 사용하고, 개발에 기여하며, 모범 사례와 활발한 커뮤니티의 지원을 받아 자신만의 pipeline을 구축하는 방법을 배우게 됩니다. 실제 프로젝트에 Nextflow 기술을 적용할 준비가 되었다면, 이것이 완벽한 다음 단계입니다. + +### 1.3. 고급 Nextflow 기능 마스터하기 + +Hello 과정에서는 Nextflow를 시작하는 데 필요하지 않은 정보로 여러분을 과부하시키지 않기 위해 의도적으로 기술적 복잡성 수준을 낮게 유지합니다. +작업을 진행하면서 Nextflow의 전체 기능 세트와 성능을 사용하는 방법을 배우고 싶으실 것입니다. + +이를 위해 현재 **[Side Quests](../side_quests/index.md) 모음**을 작업 중입니다. 이는 테스트 및 메타데이터 처리와 같은 특정 주제를 심도 있게 다루는 짧은 단독형 과정입니다. + +--- + +## 2. Seqera Platform 확인하기 + +**[Seqera Platform](https://seqera.io/)은 실제로 Nextflow를 실행하는 가장 좋은 방법입니다.** + +Nextflow 창시자들이 개발한 클라우드 기반 플랫폼으로, 자체 컴퓨팅 인프라(로컬, HPC 또는 클라우드)에 연결하여 workflow를 훨씬 쉽게 시작하고 관리할 수 있으며, 데이터를 관리하고 클라우드 환경에서 대화형으로 분석을 실행할 수 있습니다. + +Free Tier는 모든 사용자가 무료로 사용할 수 있습니다(사용량 할당량 있음). +자격을 갖춘 학술 사용자는 [Academic Program](https://seqera.io/academic/program/)을 통해 무료 Pro 수준 액세스(사용량 제한 없음)를 받을 수 있습니다. + +[Seqera Platform 튜토리얼](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase)을 살펴보시고 이것이 유용할지 확인해 보십시오. + +--- + +### 이것으로 마치겠습니다! + +**Nextflow 여정에서 행운을 빌며, 저희가 도울 수 있는 다른 방법이 있다면 [Community forum](https://community.seqera.io/)에 주저 없이 알려주십시오.** diff --git a/docs/ko/docs/nf4_science/rnaseq/survey.md b/docs/ko/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..c63b21c08a --- /dev/null +++ b/docs/ko/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# 피드백 설문조사 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +계속 진행하기 전에, 교육 내용을 평가하고 경험에 대한 피드백을 공유하며 Nextflow 여정에서 저희가 어떻게 도움을 드릴 수 있는지 알려주시기 위한 5개 문항의 짧은 설문조사를 완료해 주십시오. + +이 설문조사는 1분 이내로 완료하실 수 있습니다. 모든 분들을 위한 교육 자료 개선에 도움을 주셔서 감사합니다! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/ko/docs/side_quests/README.md b/docs/ko/docs/side_quests/README.md new file mode 100644 index 0000000000..c88772ace8 --- /dev/null +++ b/docs/ko/docs/side_quests/README.md @@ -0,0 +1 @@ +이것은 향후 Side Quests(심화 교육)를 위한 플레이스홀더입니다. 현재 여기에 있는 문서는 다른 곳에서 재활용된 콘텐츠를 기반으로 한 초안입니다. diff --git a/docs/ko/docs/side_quests/debugging.md b/docs/ko/docs/side_quests/debugging.md new file mode 100644 index 0000000000..9fd42d4c62 --- /dev/null +++ b/docs/ko/docs/side_quests/debugging.md @@ -0,0 +1,1410 @@ +# 워크플로우 디버깅 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +디버깅은 수 시간의 좌절을 줄여주고 더 효과적인 Nextflow 개발자가 되도록 도와주는 핵심 기술입니다. 경력 전반에 걸쳐, 특히 시작 단계에서는 워크플로우를 구축하고 유지보수하면서 버그를 마주하게 될 것입니다. 체계적인 디버깅 접근법을 배우면 문제를 빠르게 식별하고 해결하는 데 도움이 됩니다. + +### 학습 목표 + +이 사이드 퀘스트에서는 Nextflow 워크플로우를 위한 **체계적인 디버깅 기법**을 탐구합니다: + +- **구문 오류 디버깅**: IDE 기능과 Nextflow 오류 메시지를 효과적으로 사용하기 +- **채널 디버깅**: 데이터 흐름 문제와 채널 구조 문제 진단하기 +- **프로세스 디버깅**: 실행 실패와 리소스 문제 조사하기 +- **내장 디버깅 도구**: Nextflow의 미리보기 모드, stub 실행, 작업 디렉토리 활용하기 +- **체계적 접근법**: 효율적인 디버깅을 위한 4단계 방법론 + +마지막에는 좌절스러운 오류 메시지를 해결책으로 가는 명확한 로드맵으로 변환하는 강력한 디버깅 방법론을 갖추게 될 것입니다. + +### 사전 요구사항 + +이 사이드 퀘스트를 시작하기 전에 다음을 완료해야 합니다: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 동등한 초급 과정을 완료했어야 합니다. +- 기본 Nextflow 개념과 메커니즘(프로세스, 채널, 연산자) 사용에 익숙해야 합니다. + +**선택 사항:** [IDE Features for Nextflow Development](./ide_features.md) 사이드 퀘스트를 먼저 완료하는 것을 권장합니다. +이는 여기서 많이 사용할 디버깅을 지원하는 IDE 기능(구문 강조, 오류 감지 등)에 대한 포괄적인 내용을 다룹니다. + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 하지 않았다면, [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 여는지 확인하십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일들이 위치한 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/debugging +``` + +VSCode가 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +연습에 사용할 다양한 유형의 버그가 있는 예제 워크플로우 세트를 찾을 수 있습니다: + +??? abstract "디렉토리 내용" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +이 파일들은 실제 개발에서 마주치게 될 일반적인 디버깅 시나리오를 나타냅니다. + +#### 과제 검토 + +여러분의 과제는 각 워크플로우를 실행하고, 오류를 식별하고, 수정하는 것입니다. + +각 버그가 있는 워크플로우에 대해: + +1. **워크플로우 실행**하고 오류 관찰하기 +2. **오류 메시지 분석**: Nextflow가 무엇을 알려주고 있는가? +3. **문제 위치 찾기**: 제공된 단서를 사용하여 코드에서 찾기 +4. **버그 수정**하고 해결책이 작동하는지 확인하기 +5. 다음 섹션으로 넘어가기 전에 **파일 재설정**하기 (`git checkout <filename>` 사용) + +연습은 간단한 구문 오류에서 더 미묘한 런타임 문제로 진행됩니다. +해결책은 인라인으로 논의되지만, 앞으로 읽기 전에 각각을 직접 해결해 보십시오. + +#### 준비 체크리스트 + +뛰어들 준비가 되었다고 생각하십니까? + +- [ ] 이 과정의 목표와 사전 요구사항을 이해합니다 +- [ ] 코드스페이스가 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 과제를 이해합니다 + +모든 항목을 체크할 수 있다면, 시작할 준비가 되었습니다. + +--- + +## 1. 구문 오류 + +구문 오류는 Nextflow 코드를 작성할 때 마주치게 될 가장 일반적인 유형의 오류입니다. 코드가 Nextflow DSL의 예상 구문 규칙을 준수하지 않을 때 발생합니다. 이러한 오류는 워크플로우가 전혀 실행되지 않도록 하므로, 빠르게 식별하고 수정하는 방법을 배우는 것이 중요합니다. + +### 1.1. 중괄호 누락 + +가장 일반적인 구문 오류 중 하나이며, 때로는 디버그하기 더 복잡한 것 중 하나는 **괄호가 누락되거나 일치하지 않는 경우**입니다. + +실용적인 예제로 시작하겠습니다. + +#### 파이프라인 실행 + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**구문 오류 메시지의 주요 요소:** + +- **파일과 위치**: 오류가 포함된 파일과 줄/열을 보여줍니다 (`bad_syntax.nf:24:1`) +- **오류 설명**: 파서가 예상하지 않은 것을 찾았다고 설명합니다 (`Unexpected input: '<EOF>'`) +- **EOF 표시**: `<EOF>` (End Of File) 메시지는 파서가 여전히 더 많은 내용을 기대하면서 파일 끝에 도달했음을 나타냅니다 - 닫히지 않은 중괄호의 전형적인 징후 + +#### 코드 확인 + +이제 `bad_syntax.nf`를 검토하여 오류의 원인을 이해하겠습니다: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// process에 닫는 중괄호가 누락됨 + +workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) +} +``` + +이 예제의 목적을 위해 오류가 어디에 있는지 보여주는 주석을 남겨두었습니다. Nextflow VSCode 확장도 일치하지 않는 중괄호를 빨간색으로 표시하고 파일의 조기 종료를 강조하여 무엇이 잘못되었는지에 대한 힌트를 제공할 것입니다: + +![잘못된 구문](img/bad_syntax.png) + +**괄호 오류 디버깅 전략:** + +1. VS Code의 괄호 일치 사용 (괄호 옆에 커서 배치) +2. Problems 패널에서 괄호 관련 메시지 확인 +3. 각 여는 `{`에 대응하는 닫는 `}`가 있는지 확인 + +#### 코드 수정 + +주석을 누락된 닫는 중괄호로 교체합니다: + +=== "수정 후" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // 누락된 닫는 중괄호 추가 + + workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) + } + ``` + +=== "수정 전" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // process에 닫는 중괄호가 누락됨 + + workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) + } + ``` + +#### 파이프라인 실행 + +이제 워크플로우를 다시 실행하여 작동하는지 확인합니다: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. 잘못된 프로세스 키워드 또는 지시문 사용 + +또 다른 일반적인 구문 오류는 **잘못된 프로세스 정의**입니다. 이는 필수 블록을 정의하는 것을 잊거나 프로세스 정의에서 잘못된 지시문을 사용할 때 발생할 수 있습니다. + +#### 파이프라인 실행 + +```bash +nextflow run invalid_process.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### 코드 확인 + +오류는 "Invalid process definition"을 나타내고 문제 주변의 컨텍스트를 보여줍니다. 3-7줄을 보면 4번 줄에 `inputs:`가 있는데, 이것이 문제입니다. `invalid_process.nf`를 살펴보겠습니다: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // 오류: 'inputs'가 아니라 'input'이어야 함 + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) +} +``` + +오류 컨텍스트의 4번 줄을 보면 문제를 발견할 수 있습니다: 올바른 `input` 지시문 대신 `inputs`를 사용하고 있습니다. Nextflow VSCode 확장도 이를 표시할 것입니다: + +![잘못된 process 메시지](img/invalid_process_message.png) + +#### 코드 수정 + +[문서](https://www.nextflow.io/docs/latest/process.html#)를 참조하여 잘못된 키워드를 올바른 것으로 교체합니다: + +=== "수정 후" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // 수정됨: 'inputs'를 'input'으로 변경 + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) + } + ``` + +=== "수정 전" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // 오류: 'inputs'가 아니라 'input'이어야 함 + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 입력 채널 생성 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // 입력 채널로 process 호출 + PROCESS_FILES(input_ch) + } + ``` + +#### 파이프라인 실행 + +이제 워크플로우를 다시 실행하여 작동하는지 확인합니다: + +```bash +nextflow run invalid_process.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. 잘못된 변수 이름 사용 + +스크립트 블록에서 사용하는 변수 이름은 입력에서 파생되거나 스크립트 전에 삽입된 groovy 코드에서 파생된 유효한 것이어야 합니다. 하지만 파이프라인 개발 초기에 복잡성을 다루다 보면 변수 이름에서 실수하기 쉽고, Nextflow가 빠르게 알려줄 것입니다. + +#### 파이프라인 실행 + +```bash +nextflow run no_such_var.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +오류는 컴파일 시간에 포착되고 17번 줄의 정의되지 않은 변수를 직접 가리키며, 캐럿이 문제가 정확히 어디에 있는지 표시합니다. + +#### 코드 확인 + +`no_such_var.nf`를 살펴보겠습니다: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // 오류: undefined_var가 정의되지 않음 + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +오류 메시지는 변수가 스크립트 템플릿에서 인식되지 않음을 나타내며, 스크립트 블록에서 사용되지만 다른 곳에서 정의되지 않은 `${undefined_var}`를 볼 수 있어야 합니다. + +#### 코드 수정 + +'No such variable' 오류가 발생하면 변수를 정의하거나(입력 변수 이름을 수정하거나 스크립트 전에 groovy 코드를 편집하여) 필요하지 않은 경우 스크립트 블록에서 제거하여 수정할 수 있습니다: + +=== "수정 후" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // undefined_var가 있는 줄 제거됨 + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "수정 전" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // 오류: undefined_var가 정의되지 않음 + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### 파이프라인 실행 + +이제 워크플로우를 다시 실행하여 작동하는지 확인합니다: + +```bash +nextflow run no_such_var.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Bash 변수의 잘못된 사용 + +Nextflow를 시작할 때 Nextflow(Groovy)와 Bash 변수의 차이를 이해하기 어려울 수 있습니다. 이는 스크립트 블록의 Bash 내용에서 변수를 사용하려고 할 때 나타나는 또 다른 형태의 잘못된 변수 오류를 생성할 수 있습니다. + +#### 파이프라인 실행 + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### 코드 확인 + +오류는 `${prefix}`가 사용된 13번 줄을 가리킵니다. `bad_bash_var.nf`를 살펴보고 무엇이 문제를 일으키는지 확인하겠습니다: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # 오류: ${prefix}는 Bash가 아닌 Groovy 구문임 + """ +} +``` + +이 예제에서 Bash에서 `prefix` 변수를 정의하고 있지만, Nextflow 프로세스에서 이를 참조하기 위해 사용한 `$` 구문(`${prefix}`)은 Bash가 아닌 Groovy 변수로 해석됩니다. 변수가 Groovy 컨텍스트에 존재하지 않으므로 'no such variable' 오류가 발생합니다. + +#### 코드 수정 + +Bash 변수를 사용하려면 다음과 같이 달러 기호를 이스케이프해야 합니다: + +=== "수정 후" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # 수정됨: 달러 기호를 이스케이프함 + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "수정 전" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # 오류: ${prefix}는 Bash가 아닌 Groovy 구문임 + """ + } + ``` + +이는 Nextflow에게 이것을 Bash 변수로 해석하도록 알려줍니다. + +#### 파이프라인 실행 + +이제 워크플로우를 다시 실행하여 작동하는지 확인합니다: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Groovy vs Bash 변수" + + 문자열 연결이나 접두사/접미사 작업과 같은 간단한 변수 조작의 경우, 스크립트 블록의 Bash 변수보다 스크립트 섹션의 Groovy 변수를 사용하는 것이 일반적으로 더 읽기 쉽습니다: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + 이 접근 방식은 달러 기호를 이스케이프할 필요를 피하고 코드를 더 읽기 쉽고 유지보수하기 쉽게 만듭니다. + +### 1.5. Workflow 블록 외부의 문장 + +Nextflow VSCode 확장은 오류를 일으킬 코드 구조의 문제를 강조합니다. 일반적인 예는 `workflow {}` 블록 외부에서 채널을 정의하는 것입니다 - 이는 이제 구문 오류로 시행됩니다. + +#### 파이프라인 실행 + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +오류 메시지는 문제를 명확하게 나타냅니다: 워크플로우나 프로세스 블록 외부에서 스크립트 선언과 문장(채널 정의와 같은)을 혼합할 수 없습니다. + +#### 코드 확인 + +`badpractice_syntax.nf`를 살펴보고 오류의 원인을 확인하겠습니다: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // 오류: workflow 외부에서 정의된 채널 + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +VSCode 확장은 또한 워크플로우 블록 외부에서 정의된 `input_ch` 변수를 강조할 것입니다: + +![치명적이지 않은 구문 오류](img/nonlethal.png) + +#### 코드 수정 + +채널 정의를 워크플로우 블록 내부로 이동합니다: + +=== "수정 후" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // workflow 블록 내부로 이동됨 + PROCESS_FILES(input_ch) + } + ``` + +=== "수정 전" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // 오류: workflow 외부에서 정의된 채널 + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### 파이프라인 실행 + +워크플로우를 다시 실행하여 수정이 작동하는지 확인합니다: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +입력 채널을 워크플로우 블록 내에 정의하고, 일반적으로 확장이 제공하는 다른 권장 사항을 따르십시오. + +### 핵심 요약 + +Nextflow 오류 메시지와 IDE 시각적 표시를 사용하여 구문 오류를 체계적으로 식별하고 수정할 수 있습니다. 일반적인 구문 오류에는 중괄호 누락, 잘못된 프로세스 키워드, 정의되지 않은 변수, Bash와 Nextflow 변수의 부적절한 사용이 포함됩니다. VSCode 확장은 런타임 전에 이러한 많은 것들을 포착하는 데 도움이 됩니다. 이러한 구문 디버깅 기술을 도구 상자에 넣으면, 가장 일반적인 Nextflow 구문 오류를 빠르게 해결하고 더 복잡한 런타임 문제를 다루는 데 집중할 수 있습니다. + +### 다음은? + +구문이 올바른 경우에도 발생하는 더 복잡한 채널 구조 오류를 디버그하는 방법을 배웁니다. + +--- + +## 2. 채널 구조 오류 + +채널 구조 오류는 코드가 구문적으로 올바르지만 데이터 형태가 프로세스가 예상하는 것과 일치하지 않기 때문에 구문 오류보다 더 미묘합니다. Nextflow는 파이프라인을 실행하려고 시도하지만, 입력 수가 예상과 일치하지 않음을 발견하고 실패할 수 있습니다. 이러한 오류는 일반적으로 런타임에만 나타나며 워크플로우를 통해 흐르는 데이터에 대한 이해가 필요합니다. + +!!! tip "`.view()`로 채널 디버깅" + + 이 섹션 전체에서 `.view()` 연산자를 사용하여 워크플로우의 어느 지점에서든 채널 내용을 검사할 수 있다는 것을 기억하십시오. 이것은 채널 구조 문제를 이해하기 위한 가장 강력한 디버깅 도구 중 하나입니다. 섹션 2.4에서 이 기법을 자세히 탐구할 것이지만, 예제를 작업하면서 자유롭게 사용하십시오. + + ```groovy + my_channel.view() // 채널을 통해 흐르는 내용을 표시 + ``` + +### 2.1. 잘못된 입력 채널 수 + +이 오류는 프로세스가 예상하는 것과 다른 수의 채널을 전달할 때 발생합니다. + +#### 파이프라인 실행 + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### 코드 확인 + +오류 메시지는 호출이 1개의 인수를 예상했지만 2개를 받았다고 명확히 설명하며 23번 줄을 가리킵니다. `bad_number_inputs.nf`를 살펴보겠습니다: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // process는 1개의 입력만 예상함 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // 두 개의 별도 채널 생성 + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // 오류: 2개의 채널을 전달하지만 process는 1개만 예상함 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +프로세스가 하나만 정의하는데 여러 입력 채널을 제공하는 일치하지 않는 `PROCESS_FILES` 호출을 볼 수 있어야 합니다. VSCode 확장도 프로세스 호출 아래에 빨간 줄을 표시하고 마우스를 올리면 진단 메시지를 제공할 것입니다: + +![잘못된 인수 개수 메시지](img/incorrect_num_args.png) + +#### 코드 수정 + +이 특정 예제의 경우, 프로세스는 단일 채널을 예상하고 두 번째 채널이 필요하지 않으므로 `samples_ch` 채널만 전달하여 수정할 수 있습니다: + +=== "수정 후" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // process는 1개의 입력만 예상함 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 두 개의 별도 채널 생성 + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // 수정됨: process가 예상하는 채널만 전달 + PROCESS_FILES(samples_ch) + } + ``` + +=== "수정 전" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // process는 1개의 입력만 예상함 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 두 개의 별도 채널 생성 + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // 오류: 2개의 채널을 전달하지만 process는 1개만 예상함 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### 파이프라인 실행 + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +이 예제보다 더 일반적으로, 프로세스에 추가 입력을 추가하고 워크플로우 호출을 그에 따라 업데이트하는 것을 잊어버릴 수 있으며, 이는 이러한 유형의 오류로 이어질 수 있습니다. 다행히도 오류 메시지가 불일치에 대해 매우 명확하므로 이것은 이해하고 수정하기 더 쉬운 오류 중 하나입니다. + +### 2.2. 채널 소진 (프로세스가 예상보다 적게 실행됨) + +일부 채널 구조 오류는 훨씬 더 미묘하고 전혀 오류를 생성하지 않습니다. 아마도 가장 일반적인 것은 queue 채널이 소진되어 항목이 부족할 수 있다는 것을 이해하는 데 새로운 Nextflow 사용자가 직면하는 문제를 반영하며, 워크플로우가 조기에 종료됩니다. + +#### 파이프라인 실행 + +```bash +nextflow run exhausted.nf +``` + +??? success "명령 출력" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +이 워크플로우는 오류 없이 완료되지만, 단일 샘플만 처리합니다! + +#### 코드 확인 + +`exhausted.nf`를 살펴보고 맞는지 확인하겠습니다: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // 스크립트 전에 Groovy 코드에서 변수 정의 + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +프로세스가 세 번 대신 한 번만 실행되는 이유는 `reference_ch` 채널이 첫 번째 프로세스 실행 후 소진되는 queue 채널이기 때문입니다. 한 채널이 소진되면, 다른 채널에 여전히 항목이 있더라도 전체 프로세스가 중지됩니다. + +이것은 여러 샘플에서 재사용해야 하는 단일 참조 파일이 있는 일반적인 패턴입니다. 해결책은 참조 채널을 무기한 재사용할 수 있는 value 채널로 변환하는 것입니다. + +#### 코드 수정 + +영향을 받는 파일 수에 따라 이를 해결하는 몇 가지 방법이 있습니다. + +**옵션 1**: 많이 재사용하는 단일 참조 파일이 있습니다. 반복해서 사용할 수 있는 value 채널 타입을 간단히 생성할 수 있습니다. 이를 수행하는 세 가지 방법이 있습니다: + +**1a** `channel.value()` 사용: + +```groovy title="exhausted.nf (fixed - Option 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // value 채널은 재사용 가능 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** `first()` [연산자](https://www.nextflow.io/docs/latest/reference/operator.html#first) 사용: + +```groovy title="exhausted.nf (fixed - Option 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // value 채널로 변환 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** `collect()` [연산자](https://www.nextflow.io/docs/latest/reference/operator.html#collect) 사용: + +```groovy title="exhausted.nf (fixed - Option 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // value 채널로 변환 + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**옵션 2**: 더 복잡한 시나리오에서, 아마도 샘플 채널의 모든 샘플에 대한 여러 참조 파일이 있는 경우, `combine` 연산자를 사용하여 두 채널을 튜플로 결합하는 새 채널을 생성할 수 있습니다: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // 데카르트 곱 생성 + + PROCESS_FILES(combined_ch) +} +``` + +`.combine()` 연산자는 두 채널의 데카르트 곱을 생성하므로 `reference_ch`의 각 항목이 `input_ch`의 각 항목과 쌍을 이룹니다. 이를 통해 프로세스가 참조를 계속 사용하면서 각 샘플에 대해 실행될 수 있습니다. + +이를 위해서는 프로세스 입력을 조정해야 합니다. 우리 예제에서 프로세스 정의의 시작 부분은 다음과 같이 조정해야 합니다: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +이 접근 방식은 모든 상황에서 적합하지 않을 수 있습니다. + +#### 파이프라인 실행 + +위의 수정 사항 중 하나를 시도하고 워크플로우를 다시 실행합니다: + +```bash +nextflow run exhausted.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +이제 하나 대신 세 개의 샘플이 모두 처리되는 것을 볼 수 있어야 합니다. + +### 2.3. 잘못된 채널 내용 구조 + +워크플로우가 특정 수준의 복잡성에 도달하면 각 채널의 내부 구조를 추적하기가 조금 어려울 수 있으며, 사람들은 일반적으로 프로세스가 예상하는 것과 채널이 실제로 포함하는 것 사이에 불일치를 생성합니다. 이것은 채널 수가 잘못되었던 앞서 논의한 문제보다 더 미묘합니다. 이 경우 올바른 수의 입력 채널을 가질 수 있지만, 하나 이상의 채널의 내부 구조가 프로세스가 예상하는 것과 일치하지 않습니다. + +#### 파이프라인 실행 + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "명령 출력" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### 코드 확인 + +오류 메시지의 대괄호가 여기서 단서를 제공합니다 - 프로세스가 튜플을 단일 값으로 처리하고 있으며, 이것은 우리가 원하는 것이 아닙니다. `bad_channel_shape.nf`를 살펴보겠습니다: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // 단일 값을 예상하지만 튜플을 받음 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +튜플로 구성된 채널을 생성하고 있음을 볼 수 있습니다: `['sample1', 'file1.txt']`, 하지만 프로세스는 단일 값 `val sample_name`을 예상합니다. 실행된 명령은 프로세스가 `[sample3, file3.txt]_output.txt`라는 파일을 생성하려고 시도하고 있음을 보여주며, 이는 의도한 출력이 아닙니다. + +#### 코드 수정 + +이를 수정하려면 프로세스가 두 입력이 모두 필요한 경우 튜플을 수락하도록 프로세스를 조정할 수 있습니다: + +=== "옵션 1: 프로세스에서 튜플 수락" + + === "수정 후" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // 수정됨: 튜플 수락 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "수정 전" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // 단일 값을 예상하지만 튜플을 받음 + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "옵션 2: 첫 번째 요소 추출" + + === "수정 후" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // 수정됨: 첫 번째 요소 추출 + } + ``` + + === "수정 전" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### 파이프라인 실행 + +해결책 중 하나를 선택하고 워크플로우를 다시 실행합니다: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. 채널 디버깅 기법 + +#### 채널 검사를 위한 `.view()` 사용 + +채널을 위한 가장 강력한 디버깅 도구는 `.view()` 연산자입니다. `.view()`를 사용하면 디버깅에 도움이 되도록 모든 단계에서 채널의 형태를 이해할 수 있습니다. + +#### 파이프라인 실행 + +`bad_channel_shape_viewed.nf`를 실행하여 이를 실제로 확인합니다: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### 코드 확인 + +`bad_channel_shape_viewed.nf`를 살펴보고 `.view()`가 어떻게 사용되는지 확인하겠습니다: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // 디버그: 원래 채널 내용 표시 + .map { tuple -> tuple[0] } // 변환: 첫 번째 요소 추출 + .view { "After mapping: $it" } // 디버그: 변환된 채널 내용 표시 + + PROCESS_FILES(input_ch) +} +``` + +#### 코드 수정 + +미래에 채널 내용을 이해하기 위해 과도하게 `.view()` 연산을 사용하는 것을 피하려면 도움이 되는 주석을 추가하는 것이 좋습니다: + +```groovy title="bad_channel_shape_viewed.nf (with comments)" linenums="16" hl_lines="8 9" +workflow { + + // 채널이 튜플을 내보내지만 process는 단일 값을 예상함 + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +이것은 워크플로우가 복잡성이 증가하고 diff --git a/docs/ko/docs/side_quests/dev_environment.md b/docs/ko/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..1b8fc13662 --- /dev/null +++ b/docs/ko/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# 개발 환경 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +현대적인 통합 개발 환경(IDE)은 Nextflow 개발 경험을 극적으로 변화시킬 수 있습니다. 이 사이드 퀘스트는 VS Code와 Nextflow 확장 프로그램을 활용하여 코드를 더 빠르게 작성하고, 오류를 조기에 발견하며, 복잡한 워크플로우를 효율적으로 탐색하는 데 중점을 둡니다. + +!!! note "이것은 전통적인 튜토리얼이 아닙니다" + + 다른 교육 모듈과 달리, 이 가이드는 단계별 튜토리얼이 아닌 빠른 힌트, 팁, 실용적인 예제의 모음으로 구성되어 있습니다. 각 섹션은 여러분의 관심사와 현재 개발 요구사항에 따라 독립적으로 탐색할 수 있습니다. 자유롭게 둘러보며 워크플로우 개발에 가장 즉각적으로 유용할 기능에 집중하세요. + +## 먼저 알아야 할 것 + +이 가이드는 여러분이 [Hello Nextflow](../hello_nextflow/) 교육 과정을 완료했으며 다음을 포함한 기본 Nextflow 개념에 익숙하다고 가정합니다: + +- **기본 워크플로우 구조**: 프로세스, 워크플로우, 그리고 이들이 어떻게 연결되는지 이해하기 +- **채널 작업**: 채널 생성, 프로세스 간 데이터 전달, 기본 연산자 사용 +- **모듈과 구조화**: 재사용 가능한 모듈 생성 및 include 문 사용 +- **설정 기초**: 매개변수, 프로세스 지시문, 프로필을 위한 `nextflow.config` 사용 + +## 여기서 배울 내용 + +이 가이드는 여러분을 더 효율적인 Nextflow 개발자로 만들어 줄 **IDE 생산성 기능**에 중점을 둡니다: + +- **고급 구문 강조**: VS Code가 코드 구조에 대해 무엇을 보여주는지 이해하기 +- **지능형 자동 완성**: 더 빠른 코드 작성을 위한 컨텍스트 인식 제안 활용 +- **오류 감지 및 진단**: 워크플로우를 실행하기 전에 구문 오류 포착 +- **코드 탐색**: 프로세스, 모듈, 정의 사이를 빠르게 이동 +- **서식 지정 및 구조화**: 일관되고 읽기 쉬운 코드 스타일 유지 +- **AI 지원 개발** (선택 사항): IDE와 통합된 최신 AI 도구 사용 + +!!! info "왜 지금 IDE 기능인가요?" + + 여러분은 이미 [Hello Nextflow](../hello_nextflow/) 과정 동안 VS Code를 사용해 왔을 가능성이 높지만, IDE 기능보다는 Nextflow 기본 사항 학습에 중점을 두었습니다. 이제 프로세스, 워크플로우, 채널, 모듈과 같은 기본 Nextflow 개념에 익숙해졌으므로, 여러분을 더 효율적인 개발자로 만들어 줄 정교한 IDE 기능을 활용할 준비가 되었습니다. + + 이것을 개발 환경을 "레벨업"하는 것으로 생각하세요 - 여러분이 사용해 온 동일한 편집기에는 여러분이 그것이 무엇을 도와주는지 이해하게 되면 진정으로 가치 있게 되는 훨씬 더 강력한 기능이 있습니다. + +--- + +## 0. 설정 및 준비 + +IDE 기능을 탐색하기 위한 작업 공간을 설정해 봅시다: + +```bash title="IDE 기능 디렉토리로 이동" +cd side-quests/ide_features +``` + +이 디렉토리를 VS Code에서 엽니다: + +```bash title="현재 디렉토리에서 VS Code 열기" +code . +``` + +`ide_features` 디렉토리에는 다양한 IDE 기능을 보여주는 예제 워크플로우가 포함되어 있습니다: + +```bash title="디렉토리 구조 보기" +tree . +``` + +```console title="프로젝트 구조" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "예제 파일에 대하여" + + - `basic_workflow.nf`는 실행하고 수정할 수 있는 기본 워크플로우입니다 + - `complex_workflow.nf`는 탐색 기능을 보여주기 위한 설명 전용으로 설계되었습니다 - 성공적으로 실행되지 않을 수 있지만 현실적인 다중 파일 워크플로우 구조를 보여줍니다 + +### 키보드 단축키 + +이 가이드의 일부 기능은 선택적 키보드 단축키를 사용합니다. 브라우저를 통해 GitHub Codespaces로 이 자료에 접근하는 경우, 단축키가 시스템의 다른 용도로 사용되기 때문에 예상대로 작동하지 않을 수 있습니다. + +실제로 워크플로우를 작성할 때처럼 VS Code를 로컬에서 실행하는 경우, 단축키는 설명된 대로 작동합니다. + +Mac을 사용하는 경우, 일부(전부는 아님) 키보드 단축키가 "ctrl" 대신 "cmd"를 사용하며, 텍스트에서 이를 `Ctrl/Cmd`와 같이 표시하겠습니다. + +### 0.1. Nextflow 확장 프로그램 설치 + +!!! note "이미 Devcontainer를 사용하고 계신가요?" + + **GitHub Codespaces**에서 작업하거나 **로컬 devcontainer**를 사용하는 경우, Nextflow 확장 프로그램이 이미 설치되고 구성되어 있을 가능성이 높습니다. 아래의 수동 설치 단계를 건너뛰고 확장 프로그램 기능 탐색으로 바로 진행할 수 있습니다. + +확장 프로그램을 수동으로 설치하려면: + +1. VS Code를 엽니다 +2. 왼쪽의 확장 프로그램 아이콘을 클릭하여 확장 프로그램 보기로 이동합니다: ![확장 프로그램 아이콘](img/extensions_icon.png) (VSCode를 로컬에서 실행하는 경우 단축키 `Ctrl/Cmd+Shift+X`) +3. "Nextflow"를 검색합니다 +4. 공식 Nextflow 확장 프로그램을 설치합니다 + +![Nextflow 확장 프로그램 설치](img/install_extension.png) + +### 0.2. 작업 공간 레이아웃 + +Hello Nextflow 전반에 걸쳐 VS Code를 사용해 왔기 때문에, 이미 기본 사항에 익숙합니다. 이 세션을 위해 작업 공간을 효율적으로 구성하는 방법은 다음과 같습니다: + +- **편집기 영역**: 파일 보기 및 편집용. 파일을 나란히 비교하기 위해 여러 창으로 분할할 수 있습니다. +- **파일 탐색기** 클릭 (![파일 탐색기 아이콘](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): 시스템의 로컬 파일 및 폴더. 파일 간 탐색을 위해 왼쪽에 열어 두세요 +- **통합 터미널** (Windows 및 MacOS 모두 `Ctrl+Shift+` 백틱): 하단에서 컴퓨터와 상호작용하기 위한 터미널. Nextflow 또는 다른 명령을 실행하는 데 사용합니다. +- **문제 패널** (`Ctrl+Shift+M`): VS Code가 감지한 오류 및 문제를 여기에 표시합니다. 한눈에 문제를 강조 표시하는 데 유용합니다. + +예제를 진행하면서 패널을 드래그하거나 숨겨서(사이드바를 토글하려면 `Ctrl/Cmd+B`) 레이아웃을 사용자 지정할 수 있습니다. + +### 요약 + +Nextflow 확장 프로그램이 설치된 VS Code가 설정되었으며 효율적인 개발을 위한 작업 공간 레이아웃을 이해했습니다. + +### 다음 단계는? + +구문 강조가 Nextflow 코드 구조를 한눈에 이해하는 데 어떻게 도움이 되는지 알아보세요. + +--- + +## 1. 구문 강조 및 코드 구조 + +이제 작업 공간이 설정되었으므로, VS Code의 구문 강조가 Nextflow 코드를 더 효과적으로 읽고 작성하는 데 어떻게 도움이 되는지 살펴봅시다. + +### 1.1. Nextflow 구문 요소 + +구문 강조가 작동하는 것을 보려면 `basic_workflow.nf`를 엽니다: + +![구문 쇼케이스](img/syntax_showcase.png) + +VS Code가 다음을 강조하는 방식을 확인하세요: + +- **키워드** (`process`, `workflow`, `input`, `output`, `script`)는 뚜렷한 색상으로 +- **문자열 리터럴**과 **매개변수**는 다른 스타일로 +- **주석**은 음소거된 색상으로 +- **변수**와 **함수 호출**은 적절한 강조로 +- **코드 블록**은 적절한 들여쓰기 안내선과 함께 + +!!! note "테마에 따른 색상" + + 표시되는 특정 색상은 VS Code 테마(다크/라이트 모드), 색상 설정 및 사용자 지정 사항에 따라 달라집니다. 중요한 것은 선택한 색상 구성표에 관계없이 다른 구문 요소가 시각적으로 서로 구별되어 코드 구조를 더 쉽게 이해할 수 있다는 것입니다. + +### 1.2. 코드 구조 이해 + +구문 강조는 다음을 빠르게 식별하는 데 도움이 됩니다: + +- **프로세스 경계**: 다른 프로세스 간의 명확한 구분 +- **입력/출력 블록**: 데이터 흐름 정의를 쉽게 파악 +- **스크립트 블록**: 실행되는 실제 명령 +- **채널 작업**: 데이터 변환 단계 +- **설정 지시문**: 프로세스별 설정 + +이러한 시각적 구성은 여러 프로세스와 복잡한 데이터 흐름을 포함하는 복잡한 워크플로우로 작업할 때 매우 중요합니다. + +### 요약 + +VS Code의 구문 강조가 Nextflow 코드 구조를 읽고 다양한 언어 요소를 식별하여 더 빠른 개발을 가능하게 하는 방법을 이해했습니다. + +### 다음 단계는? + +지능형 자동 완성이 컨텍스트 인식 제안으로 코드 작성 속도를 높이는 방법을 알아보세요. + +--- + +## 2. 지능형 자동 완성 + +VS Code의 자동 완성 기능은 컨텍스트에 따라 적절한 옵션을 제안하여 코드를 더 빠르고 오류 없이 작성할 수 있도록 도와줍니다. + +### 2.1. 컨텍스트 인식 제안 + +자동 완성 옵션은 코드 내 위치에 따라 달라집니다: + +#### 채널 작업 + +`basic_workflow.nf`를 다시 열고 workflow 블록에서 `channel.`을 입력해 보세요: + +![채널 자동 완성](img/autocomplete_channel.png) + +다음에 대한 제안이 표시됩니다: + +- `fromPath()` - 파일 경로에서 채널 생성 +- `fromFilePairs()` - 쌍을 이루는 파일에서 채널 생성 +- `of()` - 값에서 채널 생성 +- `fromSRA()` - SRA 접근 번호에서 채널 생성 +- 그리고 더 많은 것들... + +이렇게 하면 정확한 메서드 이름을 기억하지 않고도 사용할 올바른 channel 팩토리를 빠르게 찾을 수 있습니다. + +채널에 적용할 수 있는 연산자도 찾을 수 있습니다. 예를 들어, `FASTQC.out.html.`을 입력하여 사용 가능한 작업을 확인하세요: + +![채널 연산자 자동 완성](img/autocomplete_operators.png) + +#### 프로세스 지시문 + +프로세스 script 블록 내부에서 `task.`를 입력하여 사용 가능한 런타임 속성을 확인하세요: + +![작업 속성 자동 완성](img/autocomplete_task.png) + +#### 설정 + +nextflow.config를 열고 아무 곳에나 `process.`를 입력하여 사용 가능한 프로세스 지시문을 확인하세요: + +![설정 자동 완성](img/autocomplete_config.png) + +다음에 대한 제안이 표시됩니다: + +- `executor` +- `memory` +- `cpus` + +이렇게 하면 프로세스를 구성할 때 시간을 절약할 수 있으며 다양한 설정 범위에서 작동합니다. 예를 들어, `docker.`를 입력하여 Docker 관련 설정 옵션을 확인해 보세요. + +### 요약 + +VS Code의 지능형 자동 완성을 사용하여 구문을 암기하지 않고도 사용 가능한 채널 작업, 프로세스 지시문, 설정 옵션을 찾을 수 있습니다. + +### 다음 단계는? + +실시간 오류 감지가 워크플로우를 실행하기 전에 코드를 읽는 것만으로 문제를 포착하는 데 어떻게 도움이 되는지 알아보세요. + +## 3. 오류 감지 및 진단 + +VS Code의 실시간 오류 감지는 워크플로우를 실행하기 전에 문제를 포착하는 데 도움이 됩니다. + +### 3.1. 구문 오류 감지 + +감지 기능을 확인하기 위해 의도적으로 오류를 만들어 봅시다. `basic_workflow.nf`를 열고 프로세스 이름을 `FASTQC`에서 `FASTQ`(또는 다른 잘못된 이름)로 변경하세요. VS Code는 workflow 블록의 오류를 빨간색 물결 밑줄로 즉시 강조 표시합니다: + +![오류 밑줄](img/error_underline.png) + +### 3.2. 문제 패널 + +개별 오류 강조를 넘어, VS Code는 작업 공간 전체의 모든 오류, 경고, 정보 메시지를 집계하는 중앙 집중식 문제 패널을 제공합니다. `Ctrl/Cmd+Shift+M`으로 열고 필터 아이콘을 사용하여 현재 파일과 관련된 오류만 표시하세요: + +![문제 패널 필터링](img/active_file.png) + +문제를 클릭하여 문제가 있는 줄로 바로 이동하세요 + +![문제 패널](img/problems_panel.png) + +프로세스 이름을 `FASTQC`로 다시 변경하여 오류를 수정하세요. + +### 3.3. 일반적인 오류 패턴 + +Nextflow 구문의 일반적인 오류는 다음과 같습니다: + +- **괄호 누락**: 일치하지 않는 `{` 또는 `}` +- **불완전한 블록**: 프로세스에 필요한 섹션 누락 +- **잘못된 구문**: 잘못된 형식의 Nextflow DSL +- **키워드 오타**: 잘못 철자된 프로세스 지시문 +- **채널 불일치**: 타입 비호환성 + +Nextflow 언어 서버는 문제 패널에서 이러한 문제를 강조 표시합니다. 파이프라인을 실행하는 동안 구문 오류를 방지하기 위해 이를 조기에 확인할 수 있습니다. + +### 요약 + +VS Code의 오류 감지 및 문제 패널을 사용하여 워크플로우를 실행하기 전에 구문 오류 및 문제를 포착하여 시간을 절약하고 좌절을 방지할 수 있습니다. + +### 다음 단계는? + +복잡한 워크플로우에서 프로세스, 모듈, 정의 간을 효율적으로 탐색하는 방법을 알아보세요. + +--- + +## 4. 코드 탐색 및 심볼 관리 + +여러 파일에 걸쳐 있는 복잡한 워크플로우를 작업할 때는 효율적인 탐색이 중요합니다. 이를 이해하기 위해 `basic_workflow.nf`의 프로세스 정의를 제공한 모듈에 대한 가져오기로 교체하세요: + +=== "변경 후" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "변경 전" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. 정의로 이동 + +`FASTQC`와 같은 프로세스 이름 위에 마우스를 올리면 모듈 인터페이스(입력 및 출력)가 포함된 팝업이 표시됩니다: + +![정의로 이동](img/syntax.png) + +이 기능은 모듈 파일을 직접 열지 않고도 모듈 인터페이스를 이해할 수 있게 해주므로 워크플로우를 작성할 때 특히 유용합니다. + +**Ctrl/Cmd-클릭**을 사용하여 모든 프로세스, 모듈 또는 변수 정의로 빠르게 이동할 수 있습니다. 스크립트 상단의 모듈 파일 링크 위에 마우스를 올리고 제안된 대로 링크를 따라가세요: + +![링크 따라가기](img/follow_link.png) + +프로세스 이름에서도 동일하게 작동합니다. `basic_workflow.nf`로 돌아가서 workflow 블록의 `FASTQC` 프로세스 이름에서 이것을 시도해 보세요. 이것은 프로세스 이름으로 직접 연결됩니다(이 예제에서는 모듈 파일과 동일하지만 훨씬 더 큰 파일의 중간 부분일 수 있습니다). + +원래 위치로 돌아가려면 **Alt+←** (또는 Mac에서 **Ctrl+-**)를 사용하세요. 이것은 위치를 잃지 않고 코드를 탐색하는 강력한 방법입니다. + +이제 `complex_workflow.nf`(앞서 언급한 설명 전용 파일)를 사용하여 더 복잡한 워크플로우에서 탐색을 살펴봅시다. 이 워크플로우에는 별도의 모듈 파일에 정의된 여러 프로세스와 일부 인라인 프로세스가 포함되어 있습니다. 복잡한 다중 파일 구조는 수동으로 탐색하기 어려울 수 있지만, 정의로 이동하는 기능은 탐색을 훨씬 더 관리하기 쉽게 만듭니다. + +1. `complex_workflow.nf`를 엽니다 +2. 모듈 정의로 이동합니다 +3. **Alt+←** (또는 **Ctrl+-**)를 사용하여 뒤로 이동합니다 +4. workflow 블록의 `FASTQC` 프로세스 이름으로 이동합니다. 이것은 프로세스 이름으로 직접 연결됩니다(이 예제에서는 모듈 파일과 동일하지만 훨씬 더 큰 파일의 중간 부분일 수 있습니다). +5. 다시 뒤로 이동합니다 +6. workflow 블록의 `TRIM_GALORE` 프로세스로 이동합니다. 이것은 인라인으로 정의되어 있으므로 별도의 파일로 이동하지 않지만, 여전히 프로세스 정의를 보여주며, 여전히 원래 위치로 돌아갈 수 있습니다. + +### 4.2. 심볼 탐색 + +`complex_workflow.nf`가 여전히 열려 있는 상태에서, VSCode 상단의 검색 창에 `@`를 입력하여 파일의 모든 심볼에 대한 개요를 얻을 수 있습니다(키보드 단축키는 `Ctrl/Cmd+Shift+O`이지만 Codespaces에서는 작동하지 않을 수 있습니다). 이렇게 하면 현재 파일의 모든 심볼을 나열하는 심볼 탐색 패널이 열립니다: + +![심볼 탐색](img/symbols.png) + +다음이 표시됩니다: + +- 모든 프로세스 정의 +- 워크플로우 정의(이 파일에 두 개의 워크플로우가 정의되어 있습니다) +- 함수 정의 + +입력을 시작하여 결과를 필터링하세요. + +### 4.3. 모든 참조 찾기 + +프로세스나 변수가 코드베이스 전체에서 어디에 사용되는지 이해하는 것은 매우 유용할 수 있습니다. 예를 들어, `FASTQC` 프로세스에 대한 모든 참조를 찾으려면 먼저 정의로 이동하세요. `modules/fastqc.nf`를 직접 열거나 위에서 했던 것처럼 VS Code의 빠른 탐색 기능을 `Ctrl/Cmd-클릭`으로 사용할 수 있습니다. 프로세스 정의에 도착하면 `FASTQC` 프로세스 이름을 마우스 오른쪽 버튼으로 클릭하고 컨텍스트 메뉴에서 "모든 참조 찾기"를 선택하여 사용된 모든 인스턴스를 확인하세요. + +![참조 찾기](img/references.png) + +이 기능은 두 개의 별개 워크플로우에서의 사용을 포함하여 `FASTQC`가 작업 공간 내에서 참조되는 모든 인스�스를 표시합니다. 이 통찰력은 `FASTQC` 프로세스 수정의 잠재적 영향을 평가하는 데 중요합니다. + +### 4.4. 개요 패널 + +탐색기 사이드바(![탐색기 아이콘](img/files_icon.png) 클릭)에 있는 개요 패널은 현재 파일의 모든 심볼에 대한 편리한 개요를 제공합니다. 이 기능을 사용하면 함수, 변수 및 기타 주요 요소를 계층적 보기로 표시하여 코드 구조를 빠르게 탐색하고 관리할 수 있습니다. + +![개요 패널](img/outline.png) + +개요 패널을 사용하여 파일 브라우저를 사용하지 않고 코드의 다른 부분으로 빠르게 이동하세요. + +### 4.5. DAG 시각화 + +VS Code의 Nextflow 확장 프로그램은 워크플로우를 방향성 비순환 그래프(DAG)로 시각화할 수 있습니다. 이것은 프로세스 간의 데이터 흐름과 종속성을 이해하는 데 도움이 됩니다. `complex_workflow.nf`를 열고 `workflow {` 위의 "Preview DAG" 버튼을 클릭하세요(이 파일의 두 번째 `workflow` 블록): + +![DAG 미리보기](img/dag_preview.png) + +이것은 단지 '진입' 워크플로우이지만, 위쪽의 workflow `RNASEQ_PIPELINE {` 위의 "Preview DAG" 버튼을 클릭하여 내부 워크플로우의 DAG도 미리 볼 수 있습니다: + +![내부 워크플로우 DAG 미리보기](img/dag_preview_inner.png) + +이 워크플로우의 경우, DAG의 노드를 사용하여 코드의 해당 프로세스 정의로 이동할 수 있습니다. 노드를 클릭하면 편집기에서 관련 프로세스 정의로 이동합니다. 특히 워크플로우가 큰 규모로 성장하면, 이것은 코드를 탐색하고 프로세스가 어떻게 연결되어 있는지 이해하는 데 정말로 도움이 될 수 있습니다. + +### 요약 + +정의로 이동, 심볼 검색, 참조 찾기, DAG 시각화를 사용하여 복잡한 워크플로우를 효율적으로 탐색하여 코드 구조와 종속성을 이해할 수 있습니다. + +### 다음 단계는? + +더 큰 Nextflow 프로젝트에서 여러 상호 연결된 파일로 효과적으로 작업하는 방법을 알아보세요. + +## 5. 여러 파일에서 작업하기 + +실제 Nextflow 개발은 여러 상호 연결된 파일로 작업하는 것을 포함합니다. VS Code가 복잡한 프로젝트를 효율적으로 관리하는 데 어떻게 도움이 되는지 살펴봅시다. + +### 5.1. 빠른 파일 탐색 + +`complex_workflow.nf`가 열려 있는 상태에서, 여러 모듈을 가져오는 것을 알 수 있습니다. 이들 간의 빠른 탐색을 연습해 봅시다. + +**Ctrl+P** (또는 **Cmd+P**)를 누르고 "fast"를 입력하기 시작하세요: + +VS Code가 일치하는 파일을 보여줍니다. `modules/fastqc.nf`를 선택하여 즉시 이동하세요. 이것은 찾고 있는 파일을 대략적으로 알고 있을 때 파일 탐색기를 클릭하는 것보다 훨씬 빠릅니다. + +다른 패턴으로 시도해 보세요: + +- "star"를 입력하여 STAR 정렬 모듈 파일(`star.nf`)을 찾습니다 +- "utils"를 입력하여 유틸리티 함수 파일(`utils.nf`)을 찾습니다 +- "config"를 입력하여 설정 파일(`nextflow.config`)로 이동합니다 + +### 5.2. 다중 파일 개발을 위한 분할 편집기 + +모듈로 작업할 때는 종종 메인 워크플로우와 모듈 정의를 동시에 봐야 합니다. 이를 설정해 봅시다: + +1. `complex_workflow.nf`를 엽니다 +2. 새 탭에서 `modules/fastqc.nf`를 엽니다 +3. `modules/fastqc.nf` 탭을 마우스 오른쪽 버튼으로 클릭하고 "Split Right"를 선택합니다 +4. 이제 두 파일을 나란히 볼 수 있습니다 + +![분할 편집기](img/split_editor.png) + +다음과 같은 경우에 매우 유용합니다: + +- 워크플로우 호출을 작성하는 동안 모듈 인터페이스 확인, 그리고 미리보기가 충분하지 않은 경우 +- 다른 모듈 간의 유사한 프로세스 비교 +- 워크플로우와 모듈 간의 데이터 흐름 디버깅 + +### 5.3. 프로젝트 전체 검색 + +때로는 특정 패턴이 전체 프로젝트에서 어디에 사용되는지 찾아야 합니다. `Ctrl/Cmd+Shift+F`를 눌러 검색 패널을 엽니다. + +작업 공간 전체에서 `publishDir`을 검색해 보세요: + +![프로젝트 검색](img/project_search.png) + +이것은 publish 디렉토리를 사용하는 모든 파일을 보여주며, 다음에 도움이 됩니다: + +- 출력 구성 패턴 이해 +- 특정 지시문의 예제 찾기 +- 모듈 간 일관성 보장 + +### 요약 + +빠른 파일 탐색, 분할 편집기, 프로젝트 전체 검색을 사용하여 복잡한 다중 파일 프로젝트를 관리하여 워크플로우와 모듈에서 효율적으로 작업할 수 있습니다. + +### 다음 단계는? + +코드 서식 지정 및 유지 관리 기능이 워크플로우를 구성되고 읽기 쉽게 유지하는 방법을 알아보세요. + +--- + +## 6. 코드 서식 지정 및 유지 관리 + +적절한 코드 서식 지정은 미학뿐만 아니라 가독성, 이해, 복잡한 워크플로우를 업데이트하는 용이성을 향상시키는 데 필수적입니다. + +### 6.1. 자동 서식 지정 실습 + +`basic_workflow.nf`를 열고 의도적으로 서식을 망쳐 봅시다: + +- 일부 들여쓰기 제거: 전체 문서를 강조 표시하고 `shift+tab`을 여러 번 눌러 가능한 한 많은 들여쓰기를 제거합니다. +- 무작위로 여분의 공백 추가: `channel.fromPath` 문에서 `(` 뒤에 공백 30개를 추가합니다. +- 일부 줄을 어색하게 나눔: `.view {` 연산자와 `Processing sample:` 문자열 사이에 새 줄을 추가하되 닫는 괄호 `}` 앞에는 해당 줄바꿈을 추가하지 않습니다. + +이제 `Shift+Alt+F` (또는 MacOS에서 `Shift+Option+F`)를 눌러 자동 서식 지정을 하세요: + +VS Code가 즉시: + +- 프로세스 구조를 명확하게 보여주도록 들여쓰기 수정 +- 유사한 요소를 일관되게 정렬 +- 불필요한 공백 제거 +- 읽기 쉬운 줄 나눔 유지 + +자동 서식 지정이 모든 코드 스타일 문제를 해결하지 못할 수 있음에 유의하세요. Nextflow 언어 서버는 코드를 깔끔하게 유지하는 것을 목표로 하지만, 특정 영역에서는 개인의 선호도도 존중합니다. 예를 들어, 프로세스의 `script` 블록 내부에서 들여쓰기를 제거하면 포맷터는 그대로 두는데, 의도적으로 그 스타일을 선호할 수 있기 때문입니다. + +현재 Nextflow에 대한 엄격한 스타일 적용이 없으므로 언어 서버는 어느 정도의 유연성을 제공합니다. 그러나 명확성을 유지하기 위해 메서드 및 함수 정의 주변에 서식 지정 규칙을 일관되게 적용합니다. + +### 6.2. 코드 구성 기능 + +#### 빠른 주석 처리 + +워크플로우에서 코드 블록을 선택하고 **Ctrl+/** (또는 **Cmd+/**)를 눌러 주석 처리하세요: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +다음에 완벽합니다: + +- 개발 중에 워크플로우의 일부를 일시적으로 비활성화 +- 복잡한 채널 작업에 설명 주석 추가 +- 워크플로우 섹션 문서화 + +**Ctrl+/** (또는 **Cmd+/**)를 다시 사용하여 코드 주석을 해제하세요. + +#### 개요를 위한 코드 접기 + +`complex_workflow.nf`에서 프로세스 정의 옆의 작은 화살표를 확인하세요. 클릭하여 프로세스를 접습니다(축소): + +![코드 접기](img/code_folding.png) + +이렇게 하면 구현 세부 사항에 빠지지 않고 워크플로우 구조의 높은 수준 개요를 얻을 수 있습니다. + +#### 괄호 일치 + +커서를 `{` 또는 `}` 괄호 옆에 놓으면 VS Code가 일치하는 괄호를 강조 표시합니다. **Ctrl+Shift+\\** (또는 **Cmd+Shift+\\**)를 사용하여 일치하는 괄호 사이를 이동하세요. + +다음에 중요합니다: + +- 프로세스 경계 이해 +- 누락되거나 추가된 괄호 찾기 +- 중첩된 워크플로우 구조 탐색 + +#### 다중 줄 선택 및 편집 + +여러 줄을 동시에 편집하기 위해 VS Code는 강력한 다중 커서 기능을 제공합니다: + +- **다중 줄 선택**: **Ctrl+Alt** (또는 MacOS의 경우 **Cmd+Option**)를 누른 상태에서 화살표 키를 사용하여 여러 줄을 선택합니다 +- **다중 줄 들여쓰기**: 여러 줄을 선택하고 **Tab**을 사용하여 들여쓰기하거나 **Shift+Tab**을 사용하여 전체 블록을 내어쓰기합니다 + +다음에 특히 유용합니다: + +- 전체 프로세스 블록을 일관되게 들여쓰기 +- 여러 줄에 한 번에 주석 추가 +- 여러 프로세스에서 유사한 매개변수 정의 편집 + +### 요약 + +자동 서식 지정, 주석 처리 기능, 코드 접기, 괄호 일치, 다중 줄 편집을 사용하여 깔끔하고 읽기 쉬운 코드를 유지하여 복잡한 워크플로우를 효율적으로 구성할 수 있습니다. + +### 다음 단계는? + +VS Code가 코드 편집을 넘어 더 넓은 개발 워크플로우와 어떻게 통합되는지 알아보세요. + +--- + +## 7. 개발 워크플로우 통합 + +VS Code는 코드 편집을 넘어 개발 워크플로우와 잘 통합됩니다. + +### 7.1. 버전 관리 통합 + +!!! note "Codespaces와 Git 통합" + + **GitHub Codespaces**에서 작업하는 경우, 일부 Git 통합 기능, 특히 소스 제어를 위한 키보드 단축키가 예상대로 작동하지 않을 수 있습니다. 초기 설정 중에 디렉토리를 Git 리포지토리로 여는 것을 거부했을 수도 있으며, 이는 교육 목적으로는 괜찮습니다. + +프로젝트가 git 리포지토리인 경우(이것이 그렇습니다), VS Code는 다음을 표시합니다: + +- 색상 표시기가 있는 수정된 파일 +- 상태 표시줄의 Git 상태 +- 인라인 diff 보기 +- 커밋 및 푸시 기능 + +소스 제어 버튼(![소스 제어 아이콘](img/source_control_icon.png))을 사용하여 소스 제어 패널을 엽니다(VSCode를 로컬에서 작업하는 경우 `Ctrl+Shift+G` 또는 `Cmd+Shift+G`)하여 git 변경 사항을 확인하고 편집기에서 직접 커밋을 스테이징하세요. + +![소스 제어 패널](img/source_control.png) + +### 7.2. 워크플로우 실행 및 검사 + +워크플로우를 실행한 다음 결과를 검사해 봅시다. 통합 터미널(Windows 및 MacOS 모두에서 `Ctrl+Shift+` 백틱)에서 기본 워크플로우를 실행하세요: + +```bash title="기본 워크플로우 실행" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +워크플로우가 실행되는 동안 터미널에서 실시간 출력을 볼 수 있습니다. 완료 후 편집기를 떠나지 않고 VS Code를 사용하여 결과를 검사할 수 있습니다: + +1. **작업 디렉토리로 이동**: 파일 탐색기 또는 터미널을 사용하여 `.nextflow/work`를 탐색합니다 +2. **로그 파일 열기**: 터미널 출력의 로그 파일 경로를 클릭하여 VS Code에서 직접 엽니다 +3. **출력 검사**: 파일 탐색기에서 게시된 결과 디렉토리를 탐색합니다 +4. **실행 보고서 보기**: HTML 보고서를 VS Code 또는 브라우저에서 직접 엽니다 + +이렇게 하면 여러 애플리케이션 간에 전환하지 않고 모든 것을 한 곳에 보관할 수 있습니다. + +### 요약 + +VS Code를 버전 관리 및 워크플로우 실행과 통합하여 단일 인터페이스에서 전체 개발 프로세스를 관리할 수 있습니다. + +### 다음 단계는? + +이러한 모든 IDE 기능이 일상적인 개발 워크플로우에서 어떻게 함께 작동하는지 확인하세요. + +--- + +## 8. 요약 및 빠른 참고 사항 + +위에서 논의한 각 IDE 기능에 대한 빠른 참고 사항은 다음과 같습니다: + +### 8.1. 새로운 기능 시작 + +1. **빠른 파일 열기** (`Ctrl+P` 또는 `Cmd+P`)로 관련 기존 모듈 찾기 +2. **분할 편집기**로 유사한 프로세스를 나란히 보기 +3. **심볼 탐색** (`Ctrl+Shift+O` 또는 `Cmd+Shift+O`)으로 파일 구조 이해 +4. **자동 완성**으로 새 코드를 빠르게 작성 + +### 8.2. 문제 디버깅 + +1. **문제 패널** (`Ctrl+Shift+M` 또는 `Cmd+Shift+M`)로 모든 오류를 한 번에 확인 +2. **정의로 이동** (`Ctrl-클릭` 또는 `Cmd-클릭`)으로 프로세스 인터페이스 이해 +3. **모든 참조 찾기**로 프로세스가 어떻게 사용되는지 확인 +4. **프로젝트 전체 검색**으로 유사한 패턴 또는 문제 찾기 + +### 8.3. 리팩토링 및 개선 + +1. **프로젝트 전체 검색** (`Ctrl+Shift+F` 또는 `Cmd+Shift+F`)으로 패턴 찾기 +2. **자동 서식 지정** (`Shift+Alt+F` 또는 `Shift+Option+F`)으로 일관성 유지 +3. **코드 접기**로 구조에 집중 +4. **Git 통합**으로 변경 사항 추적 + +--- + +## 요약 + +이제 Nextflow 개발을 위한 VS Code의 IDE 기능에 대한 빠른 여행을 마쳤습니다. 이러한 도구는 다음을 통해 생산성을 크게 향상시킬 것입니다: + +- 실시간 구문 검사를 통한 **오류 감소** +- 지능형 자동 완성으로 **개발 속도 향상** +- 복잡한 다중 파일 워크플로우에서 **탐색 개선** +- 일관된 서식 지정을 통한 **품질 유지** +- 고급 강조 표시 및 구조 시각화를 통한 **이해 향상** + +모든 것을 기억하기를 기대하지 않지만, 이제 이러한 기능이 존재한다는 것을 알았으므로 필요할 때 찾을 수 있을 것입니다. Nextflow 워크플로우를 계속 개발하면서 이러한 IDE 기능은 자연스럽게 익숙해져, 구문 및 구조와 씨름하는 대신 고품질 코드 작성에 집중할 수 있게 될 것입니다. + +### 다음 단계는? + +다음과 같은 다른 교육 모듈을 진행하면서 이러한 IDE 기술을 적용하세요: + +- **[nf-test](nf-test.md)**: 워크플로우를 위한 포괄적인 테스트 스위트 생성 +- **[Hello nf-core](../../hello_nf-core/)**: 커뮤니티 표준을 사용하여 프로덕션 품질의 파이프라인 구축 + +이러한 IDE 기능의 진정한 힘은 더 크고 복잡한 프로젝트를 작업하면서 나타납니다. 점진적으로 워크플로우에 통합하기 시작하세요 - 몇 번의 세션 내에 자연스럽게 익숙해지고 Nextflow 개발에 접근하는 방식을 변화시킬 것입니다. + +속도를 늦추기 전에 오류를 포착하는 것부터 복잡한 코드베이스를 쉽게 탐색하는 것까지, 이러한 도구는 여러분을 더 자신감 있고 효율적인 개발자로 만들어 줄 것입니다. + +즐거운 코딩 되세요! diff --git a/docs/ko/docs/side_quests/essential_scripting_patterns.md b/docs/ko/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..dc8d0857c1 --- /dev/null +++ b/docs/ko/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,915 @@ +# 필수 Nextflow 스크립팅 패턴 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow는 Java Virtual Machine에서 실행되는 프로그래밍 언어입니다. Nextflow는 [Groovy](http://groovy-lang.org/)를 기반으로 구축되어 많은 구문을 공유하지만, Nextflow는 단순히 "확장 기능이 있는 Groovy"가 아닙니다. 완전히 명세화된 [구문](https://nextflow.io/docs/latest/reference/syntax.html)과 [표준 라이브러리](https://nextflow.io/docs/latest/reference/stdlib.html)를 갖춘 독립적인 언어입니다. + +변수, 맵, 리스트에 대한 기본 구문을 넘어서지 않고도 많은 Nextflow 코드를 작성할 수 있습니다. 대부분의 Nextflow 튜토리얼은 워크플로 오케스트레이션(채널, 프로세스, 데이터 흐름)에 초점을 맞추며, 이것만으로도 놀라울 정도로 많은 것을 할 수 있습니다. + +그러나 데이터를 조작하거나, 복잡한 파일 이름을 파싱하거나, 조건부 로직을 구현하거나, 견고한 프로덕션 워크플로를 구축해야 할 때는 코드의 두 가지 측면을 구분하여 생각하는 것이 도움이 됩니다: **데이터플로**(채널, 연산자, 프로세스, 워크플로)와 **스크립팅**(클로저, 함수, 프로세스 스크립트 내부의 코드). 이 구분은 다소 임의적이지만(모두 Nextflow 코드입니다), 파이프라인을 오케스트레이션할 때와 데이터를 조작할 때를 이해하는 데 유용한 멘탈 모델을 제공합니다. 두 가지를 모두 마스터하면 명확하고 유지보수 가능한 워크플로를 작성하는 능력이 크게 향상됩니다. + +### 학습 목표 + +이 사이드 퀘스트는 기본 개념부터 프로덕션 준비 패턴까지 실습을 통한 여정을 안내합니다. +간단한 CSV 읽기 워크플로를 정교한 생물정보학 파이프라인으로 변환하며, 현실적인 과제를 통해 단계별로 발전시킵니다: + +- **경계 이해하기:** 데이터플로 작업과 스크립팅을 구분하고 이들이 함께 작동하는 방식 이해하기 +- **데이터 조작:** 강력한 연산자를 사용하여 맵과 컬렉션 추출, 변환, 부분집합 만들기 +- **문자열 처리:** 정규식 패턴으로 복잡한 파일 명명 규칙 파싱 및 변수 보간 마스터하기 +- **재사용 가능한 함수:** 복잡한 로직을 명명된 함수로 추출하여 더 깔끔하고 유지보수 가능한 워크플로 만들기 +- **동적 로직:** 다양한 입력 타입에 적응하는 프로세스 구축 및 동적 리소스 할당을 위한 클로저 사용 +- **조건부 라우팅:** 메타데이터 특성에 따라 샘플을 다양한 프로세스로 지능적으로 라우팅 +- **안전한 작업:** null-safe 연산자로 누락된 데이터를 우아하게 처리하고 명확한 오류 메시지로 입력 검증 +- **설정 기반 핸들러:** 로깅, 알림, 라이프사이클 관리를 위한 워크플로 이벤트 핸들러 사용 + +### 사전 요구사항 + +이 사이드 퀘스트를 시작하기 전에: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 이에 상응하는 초급 과정을 완료해야 합니다. +- 기본 Nextflow 개념과 메커니즘(프로세스, 채널, 연산자, 파일 작업, 메타데이터)을 편안하게 사용할 수 있어야 합니다. +- 일반적인 프로그래밍 구조(변수, 맵, 리스트)에 대한 기본적인 친숙도가 필요합니다. + +이 튜토리얼은 프로그래밍 개념을 만나면서 설명하므로 광범위한 프로그래밍 경험이 필요하지 않습니다. +기본 개념부터 시작하여 고급 패턴까지 단계적으로 구축합니다. + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 완료하지 않았다면, [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 엽니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 있는 디렉토리로 이동합니다. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### 자료 검토 + +메인 워크플로 파일과 예제 데이터 파일이 포함된 `data` 디렉토리를 찾을 수 있습니다. + +```console title="디렉토리 내용" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +샘플 CSV에는 특성에 따라 다른 처리가 필요한 생물학적 샘플에 대한 정보가 포함되어 있습니다: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +이 현실적인 데이터셋을 사용하여 실제 생물정보학 워크플로에서 마주치게 될 실용적인 프로그래밍 기법을 탐색합니다. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### 준비 체크리스트 + +시작할 준비가 되었나요? + +- [ ] 이 과정의 목표와 사전 요구사항을 이해했습니다 +- [ ] 코드스페이스가 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +<!-- - [ ] I understand the assignment --> + +모든 항목을 체크할 수 있다면, 시작할 준비가 되었습니다. + +--- + +## 1. 데이터플로 vs 스크립팅: 경계 이해하기 + +### 1.1. 무엇이 무엇인지 식별하기 + +Nextflow 워크플로를 작성할 때 **데이터플로**(채널과 프로세스를 통한 데이터 이동 방식)와 **스크립팅**(데이터를 조작하고 결정을 내리는 코드)을 구분하는 것이 중요합니다. 이들이 함께 작동하는 방식을 보여주는 워크플로를 구축해 봅시다. + +#### 1.1.1. 기본 Nextflow 워크플로 + +CSV 파일을 읽는 간단한 워크플로부터 시작합니다(`main.nf`에 이미 준비되어 있습니다): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +`workflow` 블록은 파이프라인 구조를 정의하고, `channel.fromPath()`는 파일 경로에서 채널을 생성합니다. `.splitCsv()` 연산자는 CSV 파일을 처리하고 각 행을 맵 데이터 구조로 변환합니다. + +이 워크플로를 실행하여 원시 CSV 데이터를 확인합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Map 연산자 추가하기 + +이제 이미 익숙할 `.map()` 연산자를 사용하여 데이터를 변환하는 스크립팅을 추가합니다. 이 연산자는 각 항목을 변환할 수 있는 코드를 작성할 수 있는 '클로저'를 받습니다. + +!!! note + + **클로저**는 전달되고 나중에 실행될 수 있는 코드 블록입니다. 인라인으로 정의하는 함수로 생각하면 됩니다. 클로저는 중괄호 `{ }`로 작성되며 매개변수를 받을 수 있습니다. Nextflow 연산자 작동 방식의 기본이며, Nextflow를 작성한 지 오래되었다면 이미 알지 못한 채 사용하고 있었을 수 있습니다! + +다음은 map 연산의 모습입니다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +이것이 첫 번째 **클로저**입니다 - 인수로 전달할 수 있는 익명 함수입니다(Python의 람다나 JavaScript의 화살표 함수와 유사합니다). 클로저는 Nextflow 연산자 작업에 필수적입니다. + +클로저 `{ row -> return row }`는 매개변수 `row`를 받습니다(어떤 이름이든 가능: `item`, `sample` 등). + +`.map()` 연산자가 각 채널 항목을 처리할 때 해당 항목을 클로저에 전달합니다. 여기서 `row`는 한 번에 하나의 CSV 행을 보유합니다. + +이 변경 사항을 적용하고 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +map 연산자가 입력을 변경 없이 반환하므로 이전과 동일한 출력이 표시됩니다. 이는 map 연산자가 올바르게 작동하는 것을 확인합니다. 이제 데이터 변환을 시작해 봅시다. + +#### 1.1.3. Map 데이터 구조 생성하기 + +이제 클로저 내부에 **스크립팅** 로직을 작성하여 각 데이터 행을 변환합니다. 여기서 데이터 흐름을 오케스트레이션하는 것이 아니라 개별 데이터 항목을 처리합니다. + +=== "변경 후" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // 데이터 변환을 위한 스크립팅 + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +`sample_meta` 맵은 관련 정보를 저장하는 키-값 데이터 구조입니다(Python의 딕셔너리, JavaScript의 객체, Ruby의 해시와 유사): 샘플 ID, 유기체, 조직 유형, 시퀀싱 깊이, 품질 점수. + +`.toLowerCase()`와 `.replaceAll()` 같은 문자열 조작 메서드를 사용하여 데이터를 정리하고, `.toInteger()`와 `.toDouble()` 같은 타입 변환 메서드를 사용하여 CSV의 문자열 데이터를 적절한 숫자 타입으로 변환합니다. + +이 변경 사항을 적용하고 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. 조건부 로직 추가하기 + +이제 더 많은 스크립팅을 추가합니다 - 이번에는 삼항 연산자를 사용하여 데이터 값을 기반으로 결정을 내립니다. + +다음 변경을 수행합니다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +삼항 연산자는 `condition ? value_if_true : value_if_false` 패턴을 따르는 if/else 문의 축약형입니다. 이 줄은 "품질이 40보다 크면 'high'를 사용하고, 그렇지 않으면 'normal'을 사용한다"는 의미입니다. 이와 유사한 **Elvis 연산자**(`?:`)는 무언가가 null이거나 비어있을 때 기본값을 제공합니다 - 이 패턴은 이 튜토리얼의 뒷부분에서 살펴보겠습니다. + +맵 덧셈 연산자 `+`는 기존 맵을 수정하는 것이 아니라 **새로운 맵**을 생성합니다. 이 줄은 `sample_meta`의 모든 키-값 쌍과 새로운 `priority` 키를 포함하는 새로운 맵을 생성합니다. + +!!! Note + + 클로저에 전달된 맵을 절대 수정하지 마세요 - 항상 `+`(예를 들어)를 사용하여 새로운 맵을 생성하세요. Nextflow에서는 동일한 데이터가 종종 여러 작업을 통해 동시에 흐릅니다. 맵을 제자리에서 수정하면 다른 작업이 동일한 객체를 참조할 때 예측할 수 없는 부작용이 발생할 수 있습니다. 새로운 맵을 생성하면 각 작업이 자체적인 깨끗한 복사본을 갖도록 보장합니다. + +수정된 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +품질 점수를 기반으로 우선순위 수준으로 메타데이터를 풍부하게 하는 조건부 로직을 성공적으로 추가했습니다. + +#### 1.1.5. `.subMap()`으로 맵 부분집합 만들기 + +`+` 연산자가 맵에 키를 추가하는 반면, 때로는 그 반대가 필요합니다 - 특정 키만 추출하기. `.subMap()` 메서드가 이에 완벽합니다. + +식별 필드만 포함하는 메타데이터의 단순화된 버전을 생성하는 줄을 추가해 봅시다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // 데이터 변환을 위한 스크립팅 + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "ID fields only: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // 데이터 변환을 위한 스크립팅 + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +수정된 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + ID fields only: [id:sample_001, organism:human, tissue:liver] + ID fields only: [id:sample_002, organism:mouse, tissue:brain] + ID fields only: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +이는 `view()` 작업으로 표시된 전체 메타데이터와 `println`으로 출력한 추출된 부분집합을 모두 보여줍니다. + +`.subMap()` 메서드는 키 목록을 받아 해당 키만 포함하는 새로운 맵을 반환합니다. 키가 원본 맵에 존재하지 않으면 결과에 포함되지 않습니다. + +이는 다양한 프로세스에 대해 다양한 메타데이터 버전을 생성해야 할 때 특히 유용합니다 - 일부는 전체 메타데이터가 필요하고 다른 일부는 최소한의 식별 필드만 필요할 수 있습니다. + +이제 앞으로 필요하지 않으므로 워크플로를 이전 상태로 복원하기 위해 println 문을 제거합니다. + +!!! tip "맵 작업 요약" + + - **키 추가**: `map1 + [new_key: value]` - 추가 키가 있는 새로운 맵 생성 + - **키 추출**: `map1.subMap(['key1', 'key2'])` - 지정된 키만 있는 새로운 맵 생성 + - **두 작업 모두 새로운 맵을 생성** - 원본 맵은 변경되지 않음 + +#### 1.1.6. 맵 결합 및 결과 반환 + +지금까지는 Nextflow 커뮤니티가 '메타 맵'이라고 부르는 것만 반환했고, 해당 메타데이터와 관련된 파일은 무시했습니다. 하지만 Nextflow 워크플로를 작성한다면 아마도 그 파일로 무언가를 하고 싶을 것입니다. + +2개 요소로 구성된 튜플을 포함하는 채널 구조를 출력해 봅시다: 풍부한 메타데이터 맵과 해당 파일 경로. 이는 프로세스에 데이터를 전달하는 Nextflow의 일반적인 패턴입니다. + +=== "변경 후" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +이 변경 사항을 적용하고 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +이 `[meta, file]` 튜플 구조는 메타데이터와 관련 파일을 프로세스에 전달하는 Nextflow의 일반적인 패턴입니다. + +!!! note + + **맵과 메타데이터**: 맵은 Nextflow에서 메타데이터 작업의 기본입니다. 메타데이터 맵 작업에 대한 자세한 설명은 [메타데이터 작업](./metadata.md) 사이드 퀘스트를 참조하세요. + +우리 워크플로는 핵심 패턴을 보여줍니다: **데이터플로 작업**(`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`)은 파이프라인을 통한 데이터 이동 방식을 오케스트레이션하고, **스크립팅**(맵 `[key: value]`, 문자열 메서드, 타입 변환, 삼항 연산자)은 `.map()` 클로저 내부에서 개별 데이터 항목의 변환을 처리합니다. + +### 1.2. 다른 타입 이해하기: Channel vs List + +지금까지는 데이터플로 작업과 스크립팅을 구분할 수 있었습니다. 하지만 두 컨텍스트 모두에 동일한 메서드 이름이 존재하는 경우는 어떻게 될까요? + +완벽한 예는 Nextflow 표준 라이브러리의 채널 타입과 List 타입 모두에 존재하는 `collect` 메서드입니다. List의 `collect()` 메서드는 각 요소를 변환하는 반면, 채널의 `collect()` 연산자는 모든 채널 방출을 단일 항목 채널로 수집합니다. + +채널 `collect()` 연산자가 무엇을 하는지 복습하면서 샘플 데이터로 이를 시연해 봅시다. `collect.nf`를 확인합니다: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - 여러 채널 방출을 하나로 그룹화 +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Individual channel item: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } +``` + +단계: + +- 샘플 ID 목록 정의 +- 각 샘플 ID를 별도로 방출하는 `fromList()`로 채널 생성 +- 흐르는 각 항목을 `view()`로 출력 +- 채널의 `collect()` 연산자로 모든 항목을 단일 리스트로 수집 +- 두 번째 `view()`로 수집된 결과(모든 샘플 ID를 포함하는 단일 항목) 출력 + +채널의 구조를 변경했지만 데이터 자체는 변경하지 않았습니다. + +이를 확인하기 위해 워크플로를 실행합니다: + +```bash +nextflow run collect.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +`view()`는 모든 채널 방출에 대해 출력을 반환하므로, 이 단일 출력에는 하나의 리스트로 그룹화된 원래 3개 항목이 모두 포함되어 있음을 알 수 있습니다. + +이제 List의 `collect` 메서드가 작동하는 것을 봅시다. `collect.nf`를 수정하여 원래 샘플 ID 리스트에 List의 `collect` 메서드를 적용합니다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - 여러 채널 방출을 하나로 그룹화 + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - 각 요소 변환, 구조 유지 + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - 여러 채널 방출을 하나로 그룹화 + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + ``` + +이 새로운 스니펫에서 우리는: + +- List의 `collect` 메서드를 사용하여 원래 리스트의 각 샘플 ID를 변환하는 새로운 변수 `formatted_ids`를 정의 +- `println`을 사용하여 결과 출력 + +수정된 워크플로를 실행합니다: + +```bash +nextflow run collect.nf +``` + +??? success "명령 출력" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +이번에는 일부 샘플을 제외하는 필터를 선택했기 때문에 데이터 구조를 변경하지 않았고, 리스트에 여전히 3개 항목이 있지만, List의 `collect` 메서드를 사용하여 각 항목을 변환하여 수정된 값이 있는 새로운 리스트를 생성했습니다. 이는 채널에서 `map` 연산자를 사용하는 것과 유사하지만 채널이 아닌 List 데이터 구조에서 작동합니다. + +`collect`는 여기서 포인트를 만들기 위해 사용하는 극단적인 경우입니다. 핵심 교훈은 워크플로를 작성할 때 항상 **데이터 구조**(Lists, Maps 등)와 **채널**(데이터플로 구조)을 구분해야 한다는 것입니다. 작업은 이름을 공유할 수 있지만 호출되는 타입에 따라 완전히 다르게 작동합니다. + +### 1.3. 스프레드 연산자(`*.`) - 속성 추출의 축약형 + +List의 `collect` 메서드와 관련된 것은 스프레드 연산자(`*.`)로, 컬렉션에서 속성을 추출하는 간결한 방법을 제공합니다. 이는 기본적으로 일반적인 `collect` 패턴의 문법적 설탕입니다. + +`collect.nf` 파일에 데모를 추가해 봅시다: + +=== "변경 후" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - 여러 채널 방출을 하나로 그룹화 + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - 각 요소 변환, 구조 유지 + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + + // 스프레드 연산자 - 간결한 속성 접근 + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Spread operator result: ${all_ids}" + ``` + +=== "변경 전" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - 여러 채널 방출을 하나로 그룹화 + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Individual channel item: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() result: ${list} (${list.size()} items grouped into 1)" } + + // List.collect() - 각 요소 변환, 구조 유지 + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() result: ${formatted_ids} (${sample_ids.size()} items transformed into ${formatted_ids.size()})" + ``` + +업데이트된 워크플로를 실행합니다: + +```bash title="스프레드 연산자 테스트" +nextflow run collect.nf +``` + +??? success "명령 출력" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + List.collect() result: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 items transformed into 3) + Spread operator result: [s1, s2, s3] + Individual channel item: sample_001 + Individual channel item: sample_002 + Individual channel item: sample_003 + channel.collect() result: [sample_001, sample_002, sample_003] (3 items grouped into 1) + ``` + +스프레드 연산자 `*.`는 일반적인 collect 패턴의 축약형입니다: + +```groovy +// 다음은 동등합니다: +def ids = samples*.id +def ids = samples.collect { it.id } + +// 메서드 호출과도 작동합니다: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +스프레드 연산자는 객체 리스트에서 단일 속성을 추출해야 할 때 특히 유용합니다 - 전체 `collect` 클로저를 작성하는 것보다 더 읽기 쉽습니다. + +!!! tip "스프레드 vs Collect 사용 시기" + + - **스프레드(`*.`) 사용**: 간단한 속성 접근: `samples*.id`, `files*.name` + - **collect 사용**: 변환 또는 복잡한 로직: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### 요약 + +이 섹션에서 배운 내용: + +- **데이터플로 vs 스크립팅**: 채널 연산자는 파이프라인을 통한 데이터 흐름 방식을 오케스트레이션하고, 스크립팅은 개별 데이터 항목을 변환합니다 +- **타입 이해**: 동일한 메서드 이름(`collect` 같은)이 호출되는 타입(Channel vs List)에 따라 다르게 작동할 수 있습니다 +- **컨텍스트의 중요성**: 채널(데이터플로) 또는 데이터 구조(스크립팅) 중 무엇을 다루고 있는지 항상 인식해야 합니다 + +이러한 경계를 이해하는 것은 디버깅, 문서화, 유지보수 가능한 워크플로 작성에 필수적입니다. + +다음으로는 실제 데이터 처리에 필수적인 문자열 처리 기능을 더 깊이 살펴보겠습니다. + +--- + +## 2. 문자열 처리 및 동적 스크립트 생성 + +문자열 처리를 마스터하는 것은 취약한 워크플로와 견고한 파이프라인을 구분합니다. 이 섹션에서는 복잡한 파일 이름 파싱, 동적 스크립트 생성, 변수 보간을 다룹니다. + +### 2.1. 패턴 매칭과 정규 표현식 + +생물정보학 파일은 종종 메타데이터를 인코딩하는 복잡한 명명 규칙을 가지고 있습니다. 정규 표현식으로 패턴 매칭을 사용하여 이를 자동으로 추출해 봅시다. + +`main.nf` 워크플로로 돌아가서 파일 이름에서 추가 샘플 정보를 추출하는 패턴 매칭 로직을 추가합니다. 데이터셋의 FASTQ 파일은 `SAMPLE_001_S1_L001_R1_001.fastq.gz`와 같은 이름으로 Illumina 스타일 명명 규칙을 따릅니다. 이러한 이름은 암호처럼 보일 수 있지만, 실제로는 샘플 ID, 레인 번호, 읽기 방향과 같은 유용한 메타데이터를 인코딩합니다. 정규식 기능을 사용하여 이러한 이름을 파싱합니다. + +기존 `main.nf` 워크플로를 다음과 같이 변경합니다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // 데이터 변환을 위한 스크립팅 + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // 데이터 변환을 위한 스크립팅 + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +이는 핵심 **문자열 처리 개념**을 보여줍니다: + +1. **정규 표현식 리터럴** `~/pattern/` 구문 사용 - 백슬래시를 이스케이프할 필요 없이 정규식 패턴 생성 +2. **패턴 매칭** `=~` 연산자 사용 - 문자열을 정규식 패턴과 매칭 시도 +3. **Matcher 객체** `[0][1]`, `[0][2]` 등으로 캡처 그룹 - `[0]`은 전체 매칭을 참조하고, `[1]`, `[2]` 등은 괄호 안의 캡처 그룹을 참조 + +정규식 패턴 `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$`을 분석해 봅시다: + +| 패턴 | 매칭 | 캡처 | +| ------------------- | ------------------------------------- | ---------------------------- | +| `^(.+)` | 시작부터 샘플 이름 | 그룹 1: 샘플 이름 | +| `_S(\d+)` | 샘플 번호 `_S1`, `_S2` 등 | 그룹 2: 샘플 번호 | +| `_L(\d{3})` | 레인 번호 `_L001` | 그룹 3: 레인 (3자리) | +| `_(R[12])` | 읽기 방향 `_R1` 또는 `_R2` | 그룹 4: 읽기 방향 | +| `_(\d{3})` | 청크 번호 `_001` | 그룹 5: 청크 (3자리) | +| `\.fastq(?:\.gz)?$` | 파일 확장자 `.fastq` 또는 `.fastq.gz` | 캡처되지 않음 (?: 는 비캡처) | + +이는 메타데이터를 자동으로 추출하기 위해 Illumina 스타일 명명 규칙을 파싱합니다. + +수정된 워크플로를 실행합니다: + +```bash title="패턴 매칭 테스트" +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +파일 이름에서 풍부해진 메타데이터가 표시됩니다. + +### 2.2. 프로세스의 동적 스크립트 생성 + +프로세스 스크립트 블록은 본질적으로 셸에 전달되는 다중 라인 문자열입니다. **조건부 로직**(if/else, 삼항 연산자)을 사용하여 입력 특성에 따라 다양한 스크립트 문자열을 동적으로 생성할 수 있습니다. 이는 프로세스 정의를 복제하지 않고 단일 말단 대 쌍 말단 시퀀싱 읽기와 같은 다양한 입력 타입을 처리하는 데 필수적입니다. + +이 패턴을 보여주는 프로세스를 워크플로에 추가해 봅시다. `modules/fastp.nf`를 열어 확인합니다: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +이 프로세스는 FASTQ 파일을 입력으로 받아 `fastp` 도구를 실행하여 어댑터를 트리밍하고 저품질 읽기를 필터링합니다. 불행히도 이 프로세스를 작성한 사람은 예제 데이터셋에 있는 단일 말단 읽기를 고려하지 않았습니다. 워크플로에 추가하고 무슨 일이 일어나는지 봅시다: + +먼저 `main.nf` 워크플로의 맨 첫 번째 줄에 모듈을 포함합니다: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +그런 다음 `workflow` 블록을 수정하여 `ch_samples` 채널을 `FASTP` 프로세스에 연결합니다: + +=== "변경 후" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "변경 전" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +이 수정된 워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? failure "명령 출력" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +프로세스가 두 번째 입력 파일에 대해 `null` 값으로 `fastp`를 실행하려고 시도하여 실패하는 것을 볼 수 있습니다. 이는 데이터셋에 단일 말단 읽기가 포함되어 있지만 프로세스가 쌍 말단 읽기(한 번에 두 개의 입력 파일)를 기대하도록 하드코딩되어 있기 때문입니다. + +`FASTP` 프로세스 `script:` 블록에 조건부 로직을 추가하여 이를 수정합니다. if/else 문이 읽기 파일 개수를 확인하고 그에 따라 명령을 조정합니다. + +=== "변경 후" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // 간단한 단일 말단 vs 쌍 말단 감지 + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ diff --git a/docs/ko/docs/side_quests/ideas/containers.md b/docs/ko/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..6928f72f17 --- /dev/null +++ b/docs/ko/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# 파트 1: 더 많은 컨테이너 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. 컨테이너 이미지를 찾거나 만드는 방법 + +일부 소프트웨어 개발자는 Docker Hub와 같은 컨테이너 레지스트리에서 사용할 수 있는 소프트웨어용 컨테이너 이미지를 제공하지만, 많은 경우 제공하지 않습니다. +이 선택적 섹션에서는 Nextflow 파이프라인에서 사용하려는 도구의 컨테이너 이미지를 얻는 두 가지 방법을 보여드리겠습니다: Seqera Containers를 사용하는 방법과 컨테이너 이미지를 직접 빌드하는 방법입니다. + +이 섹션 마지막의 연습에서 사용할 `quote` pip 패키지의 컨테이너 이미지를 가져오거나 빌드하게 됩니다. + +### 1.1. Seqera Containers에서 컨테이너 이미지 가져오기 + +Seqera Containers는 pip 및 conda(bioconda 포함) 설치 가능한 도구의 컨테이너 이미지를 빌드하는 무료 서비스입니다. +[Seqera Containers](https://www.seqera.io/containers/)로 이동하여 `quote` pip 패키지를 검색하십시오. + +![Seqera Containers](img/seqera-containers-1.png) + +"+Add"를 클릭한 다음 "Get Container"를 클릭하여 `quote` pip 패키지의 컨테이너 이미지를 요청하십시오. + +![Seqera Containers](img/seqera-containers-2.png) + +이 버전의 패키지에 대해 커뮤니티 컨테이너가 처음 빌드되는 경우 완료하는 데 몇 분이 걸릴 수 있습니다. +생성된 컨테이너 이미지의 URI(예: `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`)를 복사하려면 클릭하십시오. + +이제 컨테이너 이미지를 사용하여 `quote` 명령을 실행하고 Grace Hopper의 무작위 명언을 가져올 수 있습니다. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +출력: + +```console title="출력" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. 컨테이너 이미지를 직접 빌드하기 + +Seqera Containers 웹사이트의 빌드 세부 정보를 사용하여 `quote` pip 패키지의 컨테이너 이미지를 직접 빌드해 보겠습니다. +Seqera Containers 웹사이트로 돌아가서 "Build Details" 버튼을 클릭하십시오. + +먼저 살펴볼 항목은 `Dockerfile`입니다. 이는 컨테이너 이미지를 빌드하는 데 필요한 모든 명령이 포함된 스크립트 파일 유형입니다. +각 부분이 수행하는 작업을 이해하는 데 도움이 되도록 아래 Dockerfile에 몇 가지 설명 주석을 추가했습니다. + +```Dockerfile title="Dockerfile" +# micromamba 베이스 docker 이미지에서 시작 +FROM mambaorg/micromamba:1.5.10-noble +# conda.yml 파일을 컨테이너로 복사 +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Nextflow가 사용할 다양한 유틸리티와 conda.yml 파일의 패키지 설치 +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# 루트 사용자로 컨테이너 실행 +USER root +# micromamba 설치 디렉토리를 포함하도록 PATH 환경 변수 설정 +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +두 번째로 살펴볼 항목은 `conda.yml` 파일로, 컨테이너 이미지에 설치해야 하는 패키지 목록이 포함되어 있습니다. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +이 파일의 내용을 `containers/build` 디렉토리에 있는 스텁에 복사한 다음 다음 명령을 실행하여 컨테이너 이미지를 직접 빌드하십시오. + +!!! note "참고" + + `-t quote:latest` 플래그를 사용하여 컨테이너 이미지에 `quote`라는 이름과 `latest`라는 태그를 지정합니다. + 이 시스템에서 실행할 때 이 태그를 사용하여 컨테이너 이미지를 참조할 수 있습니다. + +```bash +docker build -t quote:latest containers/build +``` + +빌드가 완료되면 방금 빌드한 컨테이너 이미지를 실행할 수 있습니다. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### 요점 정리 + +Nextflow 파이프라인에서 사용하려는 도구의 컨테이너 이미지를 얻는 두 가지 방법을 배웠습니다: Seqera Containers를 사용하는 방법과 컨테이너 이미지를 직접 빌드하는 방법입니다. + +### 다음 단계는? + +이 교육 시리즈의 [다음 장](./04_hello_genomics.md)을 계속 진행하는 데 필요한 모든 것을 갖추셨습니다. +`quote` 컨테이너를 사용하여 컴퓨터/생물학 선구자들의 명언을 가져오고 `cowsay` 컨테이너를 사용하여 출력하는 선택적 연습을 계속할 수도 있습니다. + +--- + +## 2. 소가 유명한 과학자를 인용하도록 만들기 + +이 섹션에는 지금까지 배운 내용을 연습할 수 있는 몇 가지 추가 연습이 포함되어 있습니다. +이러한 연습을 수행하는 것은 교육의 이후 부분을 이해하는 데 _필수는 아니지만_, 소가 유명한 과학자를 인용하도록 만드는 방법을 알아내면서 학습 내용을 강화하는 재미있는 방법을 제공합니다. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. getQuote 프로세스를 사용하도록 `hello-containers.nf` 스크립트 수정하기 + +`containers/data/pioneers.csv` 파일에 컴퓨터 및 생물학 선구자 목록이 있습니다. +높은 수준에서 이 연습을 완료하려면 다음을 수행해야 합니다: + +- 기본 `params.input_file`을 `pioneers.csv` 파일을 가리키도록 수정합니다. +- `quote` 컨테이너를 사용하여 각 입력에 대한 명언을 가져오는 `getQuote` 프로세스를 생성합니다. +- `getQuote` 프로세스의 출력을 `cowsay` 프로세스에 연결하여 명언을 표시합니다. + +`quote` 컨테이너 이미지의 경우, 이전 추가 연습에서 직접 빌드한 것을 사용하거나 Seqera Containers에서 가져온 것을 사용할 수 있습니다. + +!!! tip "힌트" + + getQuote 프로세스의 `script` 블록에 대한 좋은 선택은 다음과 같습니다: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +이 연습의 해결책은 `containers/solutions/hello-containers-4.1.nf`에서 찾을 수 있습니다. + +### 2.2. Nextflow 파이프라인을 수정하여 `quote` 및 `sayHello` 모드에서 실행되도록 허용하기 + +파이프라인에 분기 로직을 추가하여 `quote`와 `sayHello` 모두를 위한 입력을 허용하도록 하십시오. +다음은 Nextflow 워크플로우에서 `if` 문을 사용하는 방법의 예입니다: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "힌트" + + `new_ch = processName.out`을 사용하여 프로세스의 출력 채널에 이름을 할당할 수 있습니다. + +이 연습의 해결책은 `containers/solutions/hello-containers-4.2.nf`에서 찾을 수 있습니다. + +### 요점 정리 + +Nextflow에서 컨테이너를 사용하여 프로세스를 실행하는 방법과 파이프라인에 일부 분기 로직을 구축하는 방법을 알게 되었습니다! + +### 다음 단계는? + +축하하고, 스트레칭 휴식을 취하고 물을 마시십시오! + +준비가 되면 이 교육 시리즈의 파트 3으로 이동하여 지금까지 배운 내용을 보다 현실적인 데이터 분석 사용 사례에 적용하는 방법을 배우십시오. diff --git a/docs/ko/docs/side_quests/ideas/if_else.md b/docs/ko/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..86bfdfca4e --- /dev/null +++ b/docs/ko/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# 파트 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. 소를 유명한 과학자들의 인용구를 말하게 만들기 + +이 섹션에는 지금까지 배운 내용을 연습할 수 있는 심화 연습 문제가 포함되어 있습니다. +이러한 연습 문제를 수행하는 것은 교육의 이후 부분을 이해하는 데 _필수는 아니지만_, 소가 유명한 과학자들의 말을 인용하도록 만드는 방법을 알아내면서 학습한 내용을 강화하는 재미있는 방법을 제공합니다. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. `hello-containers.nf` 스크립트를 수정하여 getQuote 프로세스 사용하기 + +`containers/data/pioneers.csv` 파일에 컴퓨터 및 생물학 분야 선구자들의 목록이 있습니다. +높은 수준에서 이 연습 문제를 완료하려면 다음이 필요합니다: + +- 기본 `params.input_file`을 `pioneers.csv` 파일을 가리키도록 수정합니다. +- `quote` 컨테이너를 사용하여 각 입력에 대한 인용구를 가져오는 `getQuote` 프로세스를 생성합니다. +- `getQuote` 프로세스의 출력을 `cowsay` 프로세스에 연결하여 인용구를 표시합니다. + +`quote` 컨테이너 이미지의 경우, 이전 심화 연습 문제에서 직접 빌드한 것을 사용하거나 Seqera Containers에서 가져온 것을 사용할 수 있습니다. + +!!! Hint + + getQuote 프로세스의 `script` 블록에 적합한 선택은 다음과 같습니다: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +이 연습 문제의 해결책은 `containers/solutions/hello-containers-4.1.nf`에서 찾을 수 있습니다. + +### 1.2. Nextflow 파이프라인을 수정하여 `quote` 및 `sayHello` 모드에서 실행되도록 하기 + +파이프라인에 분기 로직을 추가하여 `quote`와 `sayHello` 모두를 위한 입력을 받을 수 있도록 합니다. +다음은 Nextflow 워크플로우에서 `if` 문을 사용하는 방법의 예시입니다: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + `new_ch = processName.out`을 사용하여 프로세스의 출력 채널에 이름을 할당할 수 있습니다. + +이 연습 문제의 해결책은 `containers/solutions/hello-containers-4.2.nf`에서 찾을 수 있습니다. + +### 요점 + +Nextflow에서 컨테이너를 사용하여 프로세스를 실행하는 방법과 파이프라인에 분기 로직을 구축하는 방법을 알게 되었습니다! + +### 다음 단계 + +축하하고, 스트레칭 휴식을 취하고 물을 마시십시오! + +준비가 되면, 지금까지 배운 내용을 보다 현실적인 데이터 분석 사용 사례에 적용하는 방법을 배우기 위해 이 교육 시리즈의 Part 3로 이동하십시오. diff --git a/docs/ko/docs/side_quests/index.md b/docs/ko/docs/side_quests/index.md new file mode 100644 index 0000000000..70f56f4f4f --- /dev/null +++ b/docs/ko/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: 사이드 퀘스트 +hide: + - toc +--- + +# 사이드 퀘스트 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이것은 특정 주제를 더 깊이 다루는 단독 교육 단기 과정 모음입니다. 순서에 관계없이 진행하실 수 있습니다. + +시작해 봅시다! 아래 "Open in GitHub Codespaces" 버튼을 클릭하여 교육 환경을 시작하시고(별도 탭에서 여는 것을 권장합니다), 로딩되는 동안 계속 읽어주십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## 사전 요구 사항 + +각 단기 과정의 구체적인 사전 요구 사항은 다르며 해당 페이지에 문서화되어 있습니다. +그럼에도 불구하고, 모두 다음 항목에 대한 최소한의 익숙함을 가정합니다: + +- 명령줄 사용 경험 +- [Hello Nextflow](../../hello_nextflow/) 초급 교육 코스에서 다루는 기초적인 Nextflow 개념 및 도구 + +기술 요구 사항 및 환경 설정에 대해서는 [Environment Setup](../../envsetup/) 단기 과정을 참고하십시오. + +**사이드 퀘스트를 처음 접하시는 경우, 먼저 [Orientation](./orientation.md) 페이지를 확인하십시오!** + +그렇지 않은 경우, 아래 표에서 사이드 퀘스트를 선택하십시오. + +## 사이드 퀘스트 + +| 사이드 퀘스트 | 교육 예상 시간 | +| -------------------------------------------------------------------------- | -------------- | +| [Nextflow development environment walkthrough](./ide_features.md) | 45분 | +| [Essential Nextflow Scripting Patterns](./essential_scripting_patterns.md) | 90분 | +| [Metadata in workflows](./metadata.md) | 45분 | +| [Splitting and Grouping](./splitting_and_grouping.md) | 45분 | +| [Testing with nf-test](./nf-test.md) | 1시간 | +| [Workflows of workflows](./workflows_of_workflows.md) | 30분 | +| [Working with files](./working_with_files.md) | 45분 | +| [Debugging workflows](./debugging.md) | 1시간 | + +커뮤니티 포럼의 [Training 섹션](https://community.seqera.io/c/training/)에 게시하여 여기에서 다루고 싶은 다른 도메인 및 사용 사례를 알려주십시오. diff --git a/docs/ko/docs/side_quests/metadata.md b/docs/ko/docs/side_quests/metadata.md new file mode 100644 index 0000000000..94f8498302 --- /dev/null +++ b/docs/ko/docs/side_quests/metadata.md @@ -0,0 +1,1008 @@ +# 메타데이터와 메타 맵 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +과학적 분석에서 우리는 원시 데이터 파일만으로 작업하는 경우가 거의 없습니다. +각 파일에는 고유한 추가 정보가 함께 제공됩니다: 그것이 무엇인지, 어디서 왔는지, 무엇이 특별한지 등입니다. +이러한 추가 정보를 우리는 메타데이터라고 부릅니다. + +메타데이터는 다른 데이터를 설명하는 데이터입니다. +메타데이터는 파일과 실험 조건에 대한 중요한 세부 정보를 추적하고 각 데이터세트의 고유한 특성에 맞게 분석을 조정하는 데 도움이 됩니다. + +도서관 목록과 같다고 생각하시면 됩니다: 책에는 실제 콘텐츠(원시 데이터)가 포함되어 있지만, 목록 카드는 각 책에 대한 필수 정보(언제 출판되었는지, 누가 썼는지, 어디서 찾을 수 있는지 등 메타데이터)를 제공합니다. +Nextflow 파이프라인에서 메타데이터는 다음과 같은 용도로 사용될 수 있습니다: + +- 워크플로 전체에서 파일별 정보 추적 +- 파일 특성에 따라 프로세스 구성 +- 공동 분석을 위해 관련 파일 그룹화 + +### 학습 목표 + +이 사이드 퀘스트에서는 워크플로에서 메타데이터를 처리하는 방법을 탐구합니다. +기본 파일 정보가 포함된 간단한 데이터시트(생물정보학에서는 종종 샘플시트라고 함)부터 시작하여 다음을 학습합니다: + +- CSV 파일에서 파일 메타데이터 읽기 및 파싱 +- 메타데이터 맵 생성 및 조작 +- 워크플로 실행 중 새 메타데이터 필드 추가 +- 메타데이터를 사용하여 프로세스 동작 사용자 정의 + +이러한 기술은 복잡한 파일 관계와 처리 요구 사항을 처리할 수 있는 더 견고하고 유연한 파이프라인을 구축하는 데 도움이 됩니다. + +### 사전 요구 사항 + +이 사이드 퀘스트를 시작하기 전에 다음을 충족해야 합니다: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 동등한 초급 과정을 완료했어야 합니다. +- 기본 Nextflow 개념과 메커니즘(프로세스, 채널, 연산자) 사용에 익숙해야 합니다. + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 하지 않았다면 [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 열어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 있는 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/metadata +``` + +VSCode가 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +메인 워크플로 파일과 데이터시트 및 여러 데이터 파일이 포함된 `data` 디렉토리를 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +`main.nf` 파일의 워크플로는 점진적으로 완전히 작동하는 워크플로로 확장할 스텁입니다. + +데이터시트는 데이터 파일의 경로와 관련 메타데이터를 3개의 열로 구성하여 나열합니다: + +- `id`: 설명이 필요 없는 파일에 부여된 ID +- `character`: 캐릭터 이름으로, 나중에 다양한 생물을 그리는 데 사용됩니다 +- `data`: 다양한 언어의 인사말이 포함된 `.txt` 파일 경로 + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +각 데이터 파일에는 5개 언어(fr: 프랑스어, de: 독일어, es: 스페인어, it: 이탈리아어, en: 영어) 중 하나로 된 인사말 텍스트가 포함되어 있습니다. + +또한 `langid`라는 컨테이너화된 언어 분석 도구도 제공됩니다. + +#### 과제 검토 + +귀하의 과제는 다음을 수행하는 Nextflow 워크플로를 작성하는 것입니다: + +1. 각 파일의 언어를 자동으로 **식별** +2. 언어 계열(게르만어 대 로망스어)별로 파일 **그룹화** +3. 언어 및 메타데이터에 따라 각 파일의 처리 **사용자 정의** +4. 언어 그룹별로 출력 **구성** + +이것은 파일별 메타데이터가 처리 결정을 주도하는 일반적인 워크플로 패턴을 나타내며, 메타데이터 맵이 우아하게 해결하는 문제 유형입니다. + +#### 준비 체크리스트 + +시작할 준비가 되었다고 생각하십니까? + +- [ ] 이 과정의 목표와 사전 요구 사항을 이해합니다 +- [ ] 코드스페이스가 정상적으로 실행되고 있습니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 과제를 이해합니다 + +모든 항목을 체크할 수 있다면 시작할 준비가 된 것입니다. + +--- + +## 1. 데이터시트에서 메타데이터 로드 + +`main.nf` 워크플로 파일을 열어 시작점으로 제공하는 워크플로 스텁을 확인하십시오. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +예제 데이터시트를 파일로 로드하는 기본 채널 팩토리를 설정했지만, 아직 파일 내용을 읽지는 않습니다. +먼저 이것을 추가하겠습니다. + +### 1.1. `splitCsv`로 내용 읽기 + +최소한의 노력으로 파일 내용을 적절하게 파싱하는 연산자를 선택해야 합니다. +데이터시트가 CSV 형식이므로 이것은 [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv) 연산자의 역할입니다. 이 연산자는 파일의 각 행을 채널의 요소로 로드합니다. + +다음과 같이 변경하여 채널 구성 코드에 `splitCsv()` 작업을 추가하고, 파일 내용이 채널에 올바르게 로드되고 있는지 확인하기 위한 `view()` 작업을 추가하십시오. + +=== "수정 후" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +`header: true` 옵션을 사용하여 Nextflow에게 CSV 파일의 첫 번째 행을 헤더 행으로 읽도록 지시하고 있습니다. + +결과를 확인해 볼까요? +워크플로를 실행합니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +연산자가 CSV 파일의 각 행에 대한 키-값 쌍 맵을 구성했으며, 열 헤더를 해당 값의 키로 사용한 것을 볼 수 있습니다. + +각 맵 항목은 데이터시트의 열에 해당합니다: + +- `id` +- `character` +- `recording` + +훌륭합니다! 이렇게 하면 각 파일의 특정 필드에 쉽게 액세스할 수 있습니다. +예를 들어 `id`로 파일 ID에 액세스하거나 `recording`으로 txt 파일 경로에 액세스할 수 있습니다. + +??? info "(선택 사항) 맵에 대한 추가 정보" + + Groovy는 Nextflow가 구축된 프로그래밍 언어로, 맵은 Python의 딕셔너리, JavaScript의 객체 또는 Ruby의 해시와 유사한 키-값 데이터 구조입니다. + + 다음은 실제로 맵을 정의하고 그 내용에 액세스하는 방법을 보여주는 실행 가능한 스크립트입니다: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // 간단한 맵 생성 + def my_map = [id:'sampleA', character:'squirrel'] + + // 전체 맵 출력 + println "map: ${my_map}" + + // 점 표기법을 사용하여 개별 값 액세스 + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + 적절한 `workflow` 블록이 없더라도 Nextflow는 이것을 워크플로처럼 실행할 수 있습니다: + + ```bash + nextflow run examples/map_demo.nf + ``` + + 출력에서 다음을 볼 수 있습니다: + + ```console title="출력" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. `map`으로 특정 필드 선택 + +데이터시트에서 `character` 열에 액세스하여 출력하고 싶다고 가정해 봅시다. +Nextflow `map` 연산자를 사용하여 채널의 각 항목을 반복하고 맵 객체에서 `character` 항목을 구체적으로 선택할 수 있습니다. + +워크플로를 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +이제 워크플로를 다시 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +성공입니다! 데이터시트에서 파생된 맵 구조를 활용하여 각 행의 개별 열 값에 액세스했습니다. + +이제 데이터시트를 성공적으로 읽었고 각 행의 데이터에 액세스할 수 있으므로 파이프라인 로직 구현을 시작할 수 있습니다. + +### 1.3. 메타데이터를 '메타 맵'으로 구성 + +워크플로의 현재 상태에서 입력 파일(`recording` 키 아래)과 관련 메타데이터(`id`, `character`)는 모두 동일한 위치에 있습니다. 마치 모두 하나의 큰 가방에 있는 것과 같습니다. +실질적인 결과는 이 채널을 사용하는 모든 프로세스가 이 구조를 염두에 두고 구성되어야 한다는 것입니다: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +데이터시트의 열 수가 변경되지 않는 한 괜찮습니다. +그러나 데이터시트에 하나의 열만 추가해도 채널의 형태가 프로세스가 예상하는 것과 더 이상 일치하지 않아 워크플로에서 오류가 발생합니다. +또한 프로세스를 공유하기 어렵게 만들며, 스크립트 블록에서 필요하지 않은 변수를 프로세스에 하드코딩해야 할 수도 있습니다. + +이 문제를 피하려면 데이터시트에 포함된 열 수에 관계없이 채널 구조를 일관되게 유지하는 방법을 찾아야 합니다. + +튜플 내의 한 항목에 모든 메타데이터를 수집하여 이를 수행할 수 있습니다. 이를 메타데이터 맵 또는 더 간단히 '메타 맵'이라고 합니다. + +`map` 작업을 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +채널 요소를 메타 맵과 해당 파일 객체라는 두 요소로 구성된 튜플로 재구성했습니다. + +워크플로를 실행해 봅시다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console title="메타 맵 보기" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +이제 채널의 각 요소에는 메타데이터 맵이 먼저 나오고 해당 파일 객체가 두 번째로 포함됩니다: + +```console title="예제 출력 구조" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +결과적으로 데이터시트에 더 많은 열을 추가하면 `meta` 맵에서 더 많은 메타데이터를 사용할 수 있지만 채널 형태는 변경되지 않습니다. +이를 통해 메타데이터 항목을 입력 사양에 하드코딩하지 않고도 채널을 사용하는 프로세스를 작성할 수 있습니다: + +```groovy title="구문 예제" + input: + tuple val(meta), file(recording) +``` + +이것은 Nextflow 워크플로에서 메타데이터를 구성하는 데 널리 사용되는 규칙입니다. + +### 요점 + +이 섹션에서 다음을 학습했습니다: + +- **메타데이터가 중요한 이유:** 데이터와 함께 메타데이터를 유지하면 워크플로 전체에서 중요한 파일 정보가 보존됩니다. +- **데이터시트 읽는 방법:** `splitCsv`를 사용하여 헤더 정보가 있는 CSV 파일을 읽고 행을 구조화된 데이터로 변환하는 방법 +- **메타 맵 생성 방법:** 튜플 구조 `[ [id:value, ...], file ]`을 사용하여 메타데이터를 파일 데이터에서 분리하는 방법 + +--- + +## 2. 메타데이터 조작 + +이제 메타데이터를 로드했으니 활용해 봅시다! + +각 생물의 녹음 파일에 포함된 언어를 식별하기 위해 [`langid`](https://github.com/saffsd/langid.py)라는 도구를 사용할 것입니다. +이 도구는 언어 세트에 대해 사전 학습되어 있으며, 텍스트 조각이 주어지면 언어 예측과 관련 확률 점수를 모두 `stdout`으로 출력합니다. + +### 2.1. 프로세스 가져오기 및 코드 검토 + +`langid` 도구를 적용하는 `IDENTIFY_LANGUAGE`라는 사전 작성된 프로세스 모듈을 제공하므로 workflow 블록 앞에 include 문을 추가하기만 하면 됩니다. + +워크플로를 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +모듈 파일을 열어 코드를 확인할 수 있습니다: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// langid를 사용하여 각 입력 파일의 언어 예측 +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +보시다시피 입력 정의는 입력 채널에 방금 적용한 것과 동일한 `tuple val(meta), path(file)` 구조를 사용합니다. + +출력 정의는 입력과 유사한 구조의 튜플로 구성되지만 세 번째 요소로 `stdout`도 포함합니다. +이 `tuple val(meta), path(file), <output>` 패턴은 파이프라인을 통해 흐르는 메타데이터를 입력 데이터 및 출력과 연관시켜 유지합니다. + +도구가 파일을 작성하지 않고 출력을 콘솔에 직접 출력하기 때문에 Nextflow의 [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) 출력 한정자를 사용하고 있습니다. 그리고 명령줄에서 `sed`를 사용하여 확률 점수를 제거하고 개행 문자를 제거하여 문자열을 정리하고 언어 예측만 반환합니다. + +### 2.2. `IDENTIFY_LANGUAGE` 호출 추가 + +이제 프로세스를 워크플로에서 사용할 수 있으므로 데이터 채널에서 실행하기 위해 `IDENTIFY_LANGUAGE` 프로세스 호출을 추가할 수 있습니다. + +워크플로를 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +채널 구성의 원래 `.view()` 작업을 제거했습니다. + +이제 워크플로를 실행할 수 있습니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +훌륭합니다! 이제 각 캐릭터가 어떤 언어를 사용하는지 예측했습니다. + +그리고 앞서 언급했듯이 출력에 입력 파일과 메타 맵도 포함했습니다. 즉, 방금 생성한 새 정보와 연결된 상태로 유지됩니다. +이것은 다음 단계에서 유용하게 사용될 것입니다. + +!!! note + + 더 일반적으로, 메타 맵을 결과와 연결된 상태로 유지하는 이 패턴은 동일한 식별자를 공유하는 관련 결과를 연결하기 쉽게 만듭니다. + + 이미 배웠듯이 채널의 항목 순서에 의존하여 결과를 일치시킬 수 없습니다. + 대신 키를 사용하여 데이터를 올바르게 연결해야 하며, 메타 맵은 이 목적에 이상적인 구조를 제공합니다. + + 이 사용 사례는 [분할 및 그룹화](./splitting_and_grouping.md) 사이드 퀘스트에서 자세히 탐구합니다. + +### 2.3. 프로세스 출력으로 메타데이터 확장 + +방금 생성한 결과 자체가 파일 내용에 대한 메타데이터 형태이므로 메타 맵에 추가하면 유용합니다. + +그러나 기존 메타 맵을 제자리에서 수정하고 싶지는 않습니다. +기술적 관점에서 그렇게 _할 수는_ 있지만 안전하지 않습니다. + +따라서 대신 `+` 연산자(Groovy 기능)를 사용하여 기존 메타 맵의 내용과 새 정보를 보유하는 새 `lang: lang_id` 키-값 쌍을 포함하는 새 메타 맵을 만들 것입니다. +그리고 [`map`](https://www.nextflow.io/docs/latest/operator.html#map) 작업과 결합하여 기존 맵을 새 맵으로 교체합니다. + +워크플로에 다음과 같은 편집을 해야 합니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +`+` 연산자에 아직 익숙하지 않거나 혼란스럽다면 아래의 자세한 설명을 살펴보는 데 몇 분을 할애하십시오. + +??? info "`+` 연산자를 사용한 새 메타 맵 생성" + + **먼저, Groovy 연산자 `+`를 사용하여 두 맵의 내용을 병합할 수 있다는 것을 알아야 합니다.** + + 다음과 같은 맵이 있다고 가정해 봅시다: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + 이렇게 병합할 수 있습니다: + + ```groovy + new_map = map1 + map2 + ``` + + `new_map`의 내용은 다음과 같습니다: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + 훌륭합니다! + + **그러나 맵의 일부가 아닌 필드를 추가해야 한다면 어떻게 해야 할까요?** + + `map1`에서 다시 시작하지만 언어 예측이 자체 맵에 없다고 가정해 봅시다(map2가 없습니다). + 대신 `lang_id`라는 변수에 보관되어 있으며 해당 값(`'fr'`)을 `lang` 키로 저장하려고 합니다. + + 실제로 다음과 같이 할 수 있습니다: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + 여기서 `[lang: new_info]`는 즉석에서 새로운 이름 없는 맵을 생성하고 `map1 +`는 `map1`을 새로운 이름 없는 맵과 병합하여 이전과 동일한 `new_map` 내용을 생성합니다. + + 멋지지 않나요? + + **이제 이것을 Nextflow `channel.map()` 작업의 맥락으로 변환해 봅시다.** + + 코드는 다음과 같이 됩니다: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + 이것은 다음을 수행합니다: + + - `map1, lang_id ->` 튜플의 두 항목을 가져옵니다 + - `[map1 + [lang: lang_id]]` 위에서 설명한 대로 새 맵을 생성합니다 + + 출력은 위 예제의 `new_map`과 동일한 내용을 가진 단일 이름 없는 맵입니다. + 따라서 효과적으로 다음을 변환했습니다: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + 다음으로: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + `map1`을 `meta`로 변경하면 워크플로의 메타 맵에 언어 예측을 추가하기 위해 필요한 거의 모든 것임을 알 수 있을 것입니다. + + 한 가지를 제외하고! + + 워크플로의 경우 **튜플에 `file` 객체의 존재도 고려해야 합니다**. 튜플은 `meta, file, lang_id`로 구성됩니다. + + 따라서 여기의 코드는 다음과 같이 됩니다: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + `file`이 `map` 작업에서 이동하는 것처럼 보이는 이유를 따라가기 어렵다면, `[meta + [lang: lang_id], file]` 대신 그 줄이 `[new_map, file]`로 읽힌다고 상상해 보십시오. + 이렇게 하면 튜플의 두 번째 위치에 원래 위치에 `file`을 그대로 두고 있다는 것이 더 명확해질 것입니다. `new_info` 값을 가져와 첫 번째 위치의 맵에 접었습니다. + + **그리고 이것이 우리를 `tuple val(meta), path(file)` 채널 구조로 다시 데려옵니다!** + +이 코드가 무엇을 하는지 확신이 서면 워크플로를 실행하여 작동하는지 확인하십시오: + +```bash +nextflow run main.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +네, 확인되었습니다! +프로세스의 출력을 `meta, file, lang_id`에서 깔끔하게 재구성했으므로 `lang_id`가 이제 메타 맵의 키 중 하나이고 채널의 튜플이 `meta, file` 모델에 다시 맞습니다. + +<!-- TODO (future) Should we also show how to remove a key using subMap?! Or note where to find that. --> + +### 2.4. 조건문을 사용하여 언어 그룹 할당 + +이제 언어 예측이 있으므로 정보를 사용하여 새 그룹을 할당해 봅시다. + +예제 데이터에서 캐릭터가 사용하는 언어는 게르만 언어(영어, 독일어)와 로망스 언어(프랑스어, 스페인어, 이탈리아어)로 그룹화할 수 있습니다. +파이프라인 후반에 해당 분류를 쉽게 사용할 수 있도록 메타 맵에 해당 정보를 추가해 봅시다. + +그리고 좋은 소식은 이것이 `map` 연산자를 사용하기에 완벽한 또 다른 경우라는 것입니다! + +구체적으로 `lang_group`이라는 변수를 정의하고 간단한 조건부 로직을 사용하여 각 데이터에 대해 `lang_group`에 할당할 값을 결정할 것입니다. + +일반적인 구문은 다음과 같습니다: + +```groovy +.map { meta, file -> + + // lang_group을 정의하는 조건부 로직이 여기에 들어갑니다 + + [meta + [lang_group: lang_group], file] +} +``` + +이것이 이전 단계에서 사용한 즉석 맵 병합 작업과 매우 유사한 것을 볼 수 있습니다. +조건문만 작성하면 됩니다. + +적용하려는 조건부 로직은 다음과 같습니다: + +- 기본값이 `'unknown'`인 `lang_group`이라는 변수를 정의합니다. +- `lang`이 독일어(`'de'`) 또는 영어(`'en'`)이면 `lang_group`을 `germanic`으로 변경합니다. +- 그렇지 않고 `lang`이 프랑스어(`'fr'`), 스페인어(`'es'`) 및 이탈리아어(`'it'`)를 포함하는 목록에 포함되어 있으면 `lang_group`을 `romance`로 변경합니다. + +Nextflow에서 조건문을 작성하는 방법을 이미 알고 있다면 직접 작성해 보십시오. + +!!! tip + + 맵 작업 내에서 `meta.lang`으로 `lang` 값에 액세스할 수 있습니다. + +워크플로를 다음과 같이 변경해야 합니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +핵심 사항은 다음과 같습니다: + +- `def lang_group = "unknown"`을 사용하여 기본값이 `unknown`으로 설정된 `lang_group` 변수를 생성합니다. +- 조건부 로직에 `if {} else if {}` 구조를 사용하며, 두 게르만 언어에 대한 대체 `.equals()` 테스트와 세 로망스 언어에 대한 목록 존재 테스트를 사용합니다. +- 이전과 같이 `meta + [lang_group:lang_group]` 병합 작업을 사용하여 업데이트된 메타 맵을 생성합니다. + +<!-- TODO (future) Add note/links to relevant docs in additional resources section --> + +모두 이해가 되면 워크플로를 다시 실행하여 결과를 확인하십시오: + +```bash +nextflow run main.nf -resume +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +보시다시피 채널 요소는 `[meta, file]` 구조를 유지하지만 메타 맵에는 이제 이 새로운 분류가 포함됩니다. + +### 요점 + +이 섹션에서 다음을 학습했습니다 : + +- **출력 채널에 입력 메타데이터 적용**: 이러한 방식으로 메타데이터를 복사하면 나중에 메타데이터 내용을 기반으로 결과를 연결할 수 있습니다. +- **사용자 정의 키 생성**: 메타 맵에 두 개의 새 키를 생성하고 `meta + [new_key:value]`로 기존 메타 맵에 병합했습니다. 하나는 프로세스의 계산된 값을 기반으로 하고 다른 하나는 `map` 연산자에서 설정한 조건을 기반으로 합니다. + +이를 통해 파이프라인을 진행하면서 파일과 새 메타데이터 및 기존 메타데이터를 연결할 수 있습니다. +프로세스의 일부로 메타데이터를 사용하지 않더라도 이와 같이 메타 맵을 데이터와 연결된 상태로 유지하면 모든 관련 정보를 함께 유지하기 쉽습니다. + +--- + +## 3. 프로세스에서 메타 맵 정보 사용 + +이제 메타 맵을 만들고 업데이트하는 방법을 알았으므로 정말 재미있는 부분, 즉 프로세스에서 메타데이터를 실제로 사용하는 것으로 넘어갈 수 있습니다. + +더 구체적으로, 각 동물을 ASCII 아트로 그리고 말풍선에 녹음된 텍스트를 말하게 하는 두 번째 단계를 워크플로에 추가할 것입니다. +[`cowpy`](https://github.com/jeffbuttars/cowpy)라는 도구를 사용하여 이 작업을 수행할 것입니다. + +??? info "`cowpy`는 무엇을 하나요?" + + `cowpy`는 임의의 텍스트 입력을 재미있는 방식으로 표시하는 ASCII 아트를 생성하는 명령줄 도구입니다. + Tony Monroe의 클래식 [cowsay](https://en.wikipedia.org/wiki/Cowsay) 도구의 Python 구현입니다. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + 선택적으로 기본 소 대신 사용할 캐릭터(또는 'cowacter')를 선택할 수 있습니다. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Hello Nextflow 과정을 진행했다면 이미 이 도구가 실행되는 것을 보았을 것입니다. +그렇지 않더라도 걱정하지 마십시오. 진행하면서 알아야 할 모든 것을 다룰 것입니다. + +### 3.1. 프로세스 가져오기 및 코드 검토 + +`cowpy` 도구를 적용하는 `COWPY`라는 사전 작성된 프로세스 모듈을 제공하므로 workflow 블록 앞에 include 문을 추가하기만 하면 됩니다. + +워크플로를 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +모듈 파일을 열어 코드를 확인할 수 있습니다: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy로 ASCII 아트 생성 +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +보시다시피 이 프로세스는 현재 입력 파일(표시할 텍스트 포함)과 ASCII 아트로 그릴 캐릭터를 지정하는 값을 받도록 설계되어 있으며, 일반적으로 명령줄 매개변수에 의해 워크플로 수준에서 제공됩니다. + +### 3.2. 메타 맵 필드를 입력으로 전달 + +Hello Nextflow 과정에서 `cowpy` 도구를 사용할 때 명령줄 매개변수를 사용하여 최종 이미지를 그리는 데 사용할 캐릭터를 결정했습니다. +파이프라인 실행당 하나의 이미지만 생성했기 때문에 그것이 타당했습니다. + +그러나 이 튜토리얼에서는 처리하는 각 대상에 대해 적절한 이미지를 생성하려고 하므로 명령줄 매개변수를 사용하면 너무 제한적입니다. + +좋은 소식: 데이터시트에 `character` 열이 있으므로 메타 맵에도 있습니다. +프로세스가 각 항목에 사용해야 하는 캐릭터를 설정하는 데 사용해 봅시다. + +이를 위해 세 가지를 수행해야 합니다: + +1. 이전 프로세스에서 나오는 출력 채널에 이름을 지정하여 더 편리하게 작업할 수 있도록 합니다. +2. 관심 있는 정보에 액세스하는 방법을 결정합니다. +3. 두 번째 프로세스 호출을 추가하고 정보를 적절하게 제공합니다. + +시작하겠습니다. + +#### 3.2.1. 이전 출력 채널에 이름 지정 + +첫 번째 프로세스 `IDENTIFY_LANGUAGE.out`의 출력 채널에 직접 이전 조작을 적용했습니다. +해당 채널의 내용을 다음 프로세스에 제공하기 위해(명확하고 읽기 쉬운 방식으로) 자체 이름 `ch_languages`를 지정하려고 합니다. + +[`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set) 연산자를 사용하여 그렇게 할 수 있습니다. + +메인 워크플로에서 `.view()` 연산자를 `.set { ch_languages }`로 교체하고 이름으로 채널을 참조할 수 있는지 테스트하는 라인을 추가하십시오. + +=== "수정 후" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // 임시: ch_languages 살펴보기 + ch_languages.view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // langid를 실행하여 각 인사말의 언어 식별 + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +이것을 실행해 봅시다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/ diff --git a/docs/ko/docs/side_quests/nf-test.md b/docs/ko/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..7ca3c2334f --- /dev/null +++ b/docs/ko/docs/side_quests/nf-test.md @@ -0,0 +1,1170 @@ +# nf-test로 테스트하기 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +워크플로우의 모든 부분이 의도한 대로 작동하는지 체계적으로 테스트할 수 있는 능력은 재현성과 장기적인 유지보수에 매우 중요하며, 개발 과정에서도 큰 도움이 될 수 있습니다. + +테스트가 왜 그렇게 중요한지 잠시 이야기해 보겠습니다. 워크플로우를 개발할 때 가장 먼저 하는 일 중 하나는 유효하고 결과를 생성해야 하는 테스트 데이터를 가져오는 것입니다. 파이프라인에 첫 번째 프로세스를 추가하고 입력과 연결하여 작동하도록 만듭니다. 그런 다음 모든 것이 작동하는지 확인하기 위해 테스트 데이터로 실행합니다. 이것이 작동한다고 가정하면 다음 프로세스로 이동하여 테스트 데이터를 다시 실행합니다. 만족스러운 파이프라인을 완성할 때까지 이 과정을 반복합니다. + +그런 다음 `--skip_process`와 같은 간단한 참 또는 거짓 매개변수를 추가할 수 있습니다. 이제 파이프라인이 예상대로 작동하는지 확인하기 위해 각 매개변수로 한 번씩 두 번 실행해야 합니다. 하지만 잠깐, `--skip_process`가 실제로 프로세스를 건너뛰는지 어떻게 확인할까요? 출력을 확인하거나 로그 파일을 확인해야 합니다! 이는 번거롭고 오류가 발생하기 쉽습니다. + +파이프라인을 개발하면서 매 반복마다 수동으로 테스트하는 것이 느리고 오류가 발생하기 쉬울 정도로 빠르게 복잡해질 것입니다. 게다가 오류를 발견하더라도 파이프라인의 어디에서 오류가 발생하는지 정확히 찾아내기가 매우 어려울 것입니다. 바로 여기에 테스트가 필요합니다. + +테스트를 통해 파이프라인의 모든 부분이 예상대로 작동하는지 체계적으로 확인할 수 있습니다. 잘 작성된 테스트가 개발자에게 주는 이점은 엄청납니다: + +- **자신감**: 테스트가 전체 파이프라인을 다루므로 무언가를 변경해도 다른 것에 영향을 미치지 않는다는 확신을 가질 수 있습니다 +- **신뢰**: 여러 개발자가 파이프라인에서 작업할 때 다른 개발자가 파이프라인과 모든 구성 요소를 손상시키지 않았다는 것을 알 수 있습니다 +- **투명성**: 테스트는 파이프라인이 어디서 실패하는지 보여주고 문제를 추적하기 쉽게 만듭니다. 또한 프로세스나 워크플로우를 실행하는 방법을 보여주는 일종의 문서 역할을 합니다 +- **속도**: 테스트가 자동화되어 있으므로 매우 빠르고 반복적으로 실행할 수 있습니다. 새로운 버그를 도입할 두려움 없이 빠르게 반복할 수 있습니다 + +작성할 수 있는 다양한 유형의 테스트가 있습니다: + +1. **모듈 수준 테스트**: 개별 프로세스용 +2. **워크플로우 수준 테스트**: 단일 워크플로우용 +3. **파이프라인 수준 테스트**: 전체 파이프라인용 +4. **성능 테스트**: 파이프라인의 속도와 효율성용 +5. **스트레스 테스트**: 극한 조건에서 파이프라인의 성능을 평가하여 한계를 결정 + +개별 프로세스를 테스트하는 것은 다른 언어의 단위 테스트와 유사합니다. 워크플로우나 전체 파이프라인을 테스트하는 것은 다른 언어에서 통합 테스트라고 하는 것과 유사하며, 여기서 구성 요소의 상호 작용을 테스트합니다. + +[**nf-test**](https://www.nf-test.com/)는 모듈, 워크플로우 및 파이프라인 수준 테스트를 작성할 수 있는 도구입니다. 간단히 말해서, 파이프라인의 모든 개별 부분이 _격리된 상태에서_ 예상대로 작동하는지 체계적으로 확인할 수 있습니다. + +### 학습 목표 + +이 사이드 퀘스트에서는 nf-test를 사용하여 파이프라인에 대한 워크플로우 수준 테스트와 호출하는 세 가지 프로세스에 대한 모듈 수준 테스트를 작성하는 방법을 배웁니다. + +이 사이드 퀘스트가 끝날 때쯤이면 다음 기술을 효과적으로 사용할 수 있을 것입니다: + +- 프로젝트에서 nf-test 초기화 +- 모듈 수준 및 워크플로우 수준 테스트 생성 +- 일반적인 유형의 단언문 추가 +- 스냅샷과 콘텐츠 단언문을 언제 사용할지 이해 +- 전체 프로젝트에 대한 테스트 실행 + +이러한 기술은 파이프라인 프로젝트에서 포괄적인 테스트 전략을 구현하여 더욱 견고하고 유지보수가 가능하도록 하는 데 도움이 될 것입니다. + +### 사전 요구 사항 + +이 사이드 퀘스트를 시작하기 전에 다음을 충족해야 합니다: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 동등한 초급 과정을 완료했습니다 +- 기본적인 Nextflow 개념과 메커니즘(프로세스, 채널, 연산자, 파일 작업, 메타데이터)을 사용하는 데 익숙합니다 + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 열지 않았다면 [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 열어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 있는 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/nf-test +``` + +VSCode를 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +메인 워크플로우 파일과 파이프라인에 대한 입력이 포함된 `greetings.csv`라는 CSV 파일을 찾을 수 있습니다. + +```console title="디렉토리 내용" +. +├── greetings.csv +└── main.nf +``` + +파일에 대한 자세한 설명은 [Hello Nextflow의 워밍업](../hello_nextflow/00_orientation.md)을 참조하십시오. + +테스트할 워크플로우는 [Hello Workflow](../hello_nextflow/03_hello_workflow.md)에서 작성한 Hello 워크플로우의 하위 집합입니다. + +??? example "Hello Nextflow 워크플로우는 무엇을 하나요?" + + [Hello Nextflow](../hello_nextflow/index.md) 교육을 받지 않았다면 이 간단한 워크플로우가 무엇을 하는지에 대한 간단한 개요가 있습니다. + + 워크플로우는 인사말이 포함된 CSV 파일을 가져와서 네 가지 연속적인 변환 단계를 실행하고 재미있는 캐릭터가 인사말을 하는 ASCII 그림이 포함된 단일 텍스트 파일을 출력합니다. + + 네 단계는 별도의 모듈 파일에 저장된 Nextflow 프로세스(`sayHello`, `convertToUpper`, `collectGreetings`, `cowpy`)로 구현됩니다. + + 1. **`sayHello`:** 각 인사말을 자체 출력 파일에 작성합니다(예: "Hello-output.txt") + 2. **`convertToUpper`:** 각 인사말을 대문자로 변환합니다(예: "HELLO") + 3. **`collectGreetings`:** 모든 대문자 인사말을 단일 배치 파일로 수집합니다 + 4. **`cowpy`:** `cowpy` 도구를 사용하여 ASCII 아트를 생성합니다 + + 결과는 `results/`라는 디렉토리에 게시되며, 파이프라인의 최종 출력(기본 매개변수로 실행할 때)은 대문자로 된 인사말을 하는 캐릭터의 ASCII 아트가 포함된 일반 텍스트 파일입니다. + + 이 사이드 퀘스트에서는 처음 두 프로세스만 포함하는 Hello 워크플로우의 중간 형태를 사용합니다. <!-- TODO: change this to use the full finished workflow as suggested in https://github.com/nextflow-io/training/issues/735 --> + +작업할 하위 집합은 두 개의 프로세스로 구성됩니다: `sayHello`와 `convertToUpper`. +전체 워크플로우 코드는 아래에서 볼 수 있습니다. + +??? example "워크플로우 코드" + + ```groovy title="main.nf" + /* + * Pipeline parameters + */ + params.input_file = "greetings.csv" + + /* + * Use echo to print 'Hello World!' to standard out + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Use a text replace utility to convert the greeting to uppercase + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // 입력용 채널 생성 + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // 인사말 출력 + sayHello(greeting_ch) + + // 인사말을 대문자로 변환 + convertToUpper(sayHello.out) + } + ``` + +#### 워크플로우 실행 + +워크플로우를 실행하여 예상대로 작동하는지 확인하겠습니다. + +```bash +nextflow run main.nf +``` + +```console title="워크플로우 실행 결과" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +축하합니다! 방금 테스트를 실행했습니다! + +"잠깐, 뭐라고요? 워크플로우를 실행했고 작동했어요! 이게 어떻게 테스트인가요?" + +좋은 질문입니다! + +방금 무슨 일이 있었는지 분석해 보겠습니다. + +기본 매개변수로 워크플로우를 실행하고 작동하는 것을 확인했으며 결과에 만족합니다. 이것이 테스트의 본질입니다. Hello Nextflow 교육 과정을 진행했다면 모든 것이 올바르게 설정되었는지 확인하기 위해 항상 시작점으로 사용하던 워크플로우를 실행하는 것으로 모든 섹션을 시작했다는 것을 알아차렸을 것입니다. + +소프트웨어 테스트는 본질적으로 이 과정을 자동화합니다. + +#### 과제 검토 + +여러분의 과제는 nf-test를 사용하여 이 워크플로우에 표준화된 테스트를 추가하는 것입니다. 이를 통해 추가 변경 사항이 있을 경우 모든 부분이 계속 예상대로 작동하는지 쉽게 확인할 수 있습니다. + +<!-- TODO: give a bit more details, similar to how it's done in the Metadata side quest --> + +#### 준비 체크리스트 + +바로 시작할 준비가 되셨나요? + +- [ ] 이 과정의 목표와 사전 요구 사항을 이해합니다 +- [ ] 코드스페이스가 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 워크플로우를 성공적으로 실행했습니다 +- [ ] 과제를 이해합니다 + +모든 항목을 확인할 수 있다면 시작할 준비가 된 것입니다. + +--- + +## 1. `nf-test` 초기화 + +`nf-test` 패키지는 프로젝트에 대한 테스트 개발을 시작하기 위해 몇 가지 설정을 수행하는 초기화 명령을 제공합니다. + +```bash +nf-test init +``` + +다음과 같은 출력이 생성됩니다: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +또한 구성 파일 스텁이 포함된 `tests` 디렉토리를 생성합니다. + +### 1.1. nf-test 생성 + +`nf-test`는 nf-test 파일을 작성하기 위한 도구 세트를 제공하여 작업의 대부분을 절약해 줍니다. 이는 `generate` 하위 명령 아래에 있습니다. 파이프라인에 대한 테스트를 생성하겠습니다: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="출력" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +이렇게 하면 `tests` 디렉토리 내에 `main.nf.test` 파일이 생성됩니다. 이것이 파이프라인 수준 테스트 파일입니다. `tree tests/`를 실행하면 다음과 같이 표시됩니다: + +```console title="테스트 디렉토리 내용" +tests/ +├── main.nf.test +└── nextflow.config +``` + +`main.nf.test` 파일이 파이프라인 수준 테스트 파일입니다. 이를 열어서 내용을 살펴보겠습니다. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +테스트 파일의 구조를 이해하기 위해 잠시 시간을 갖겠습니다. + +`nextflow_pipeline` 블록은 모든 파이프라인 수준 테스트의 진입점입니다. 다음을 포함합니다: + +- `name`: 테스트의 이름 +- `script`: 파이프라인 스크립트의 경로 + +`test` 블록은 실제 테스트입니다. 다음을 포함합니다: + +- `when`: 테스트가 실행되어야 하는 조건. 여기에는 파이프라인을 실행하는 데 사용될 매개변수가 포함됩니다 +- `then`: 수행되어야 하는 단언문. 여기에는 파이프라인의 예상 결과가 포함됩니다 + +평이한 언어로 테스트의 논리는 다음과 같이 읽힙니다: +"이 *파이프라인*에 이러한 *매개변수*가 제공될 **때**, 이러한 결과를 볼 것으로 **예상**합니다." + +이것은 기능적 테스트가 아닙니다. 다음 섹션에서 이를 기능적 테스트로 전환하는 방법을 보여드리겠습니다. + +### 테스트 이름에 대한 참고 사항 + +위의 예에서는 파이프라인이 성공적으로 실행되는지만 확인하는 기본 테스트에 적합한 기본 이름 "Should run without failures"를 사용했습니다. 그러나 더 구체적인 테스트 케이스를 추가할 때는 실제로 테스트하는 내용을 나타내는 더 설명적인 이름을 사용해야 합니다. 예를 들어: + +- "Should convert input to uppercase" - 특정 기능을 테스트할 때 +- "Should handle empty input gracefully" - 엣지 케이스를 테스트할 때 +- "Should respect max memory parameter" - 리소스 제약을 테스트할 때 +- "Should create expected output files" - 파일 생성을 테스트할 때 + +좋은 테스트 이름은 다음과 같아야 합니다: + +1. 예상되는 동작이 무엇인지 명확하게 하기 위해 "Should"로 시작 +2. 테스트 중인 특정 기능이나 시나리오 설명 +3. 테스트가 실패하면 어떤 기능이 손상되었는지 알 수 있을 만큼 명확 + +나중에 더 많은 단언문과 특정 테스트 케이스를 추가할 때 각 테스트가 무엇을 확인하는지 명확하게 하기 위해 이러한 더 설명적인 이름을 사용할 것입니다. + +### 1.2. 테스트 실행 + +테스트를 실행하여 어떤 일이 일어나는지 봅시다. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test 파이프라인 실패" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +테스트가 실패합니다! 무슨 일이 있었나요? + +1. nf-test는 `when` 블록의 설정을 사용하여 파이프라인을 있는 그대로 실행하려고 했습니다: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test는 파이프라인의 상태를 확인하고 `when` 블록과 비교했습니다: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +nf-test가 파이프라인 실패를 보고하고 Nextflow의 오류 메시지를 제공한 방법에 주목하세요: + +```console title="오류" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +그렇다면 무엇이 문제였나요? 파이프라인에는 프로젝트 디렉토리에 greetings.csv 파일이 있다는 것을 기억하세요. nf-test가 파이프라인을 실행하면 이 파일을 찾지만 찾을 수 없습니다. 파일은 거기에 있는데 무슨 일이 일어나고 있나요? 경로를 보면 테스트가 `./nf-test/tests/longHashString/` 경로에서 발생하고 있음을 알 수 있습니다. Nextflow처럼 nf-test도 모든 것을 격리된 상태로 유지하기 위해 각 테스트에 대해 새 디렉토리를 만듭니다. 데이터 파일이 거기에 없으므로 원래 테스트에서 파일 경로를 수정해야 합니다. + +테스트 파일로 돌아가서 `when` 블록의 파일 경로를 변경하겠습니다. + +테스트에서 파이프라인의 루트를 어떻게 가리킬지 궁금할 것입니다. 이것은 일반적인 상황이므로 nf-test에는 우리의 삶을 더 쉽게 만들기 위해 사용할 수 있는 전역 변수가 있습니다. 전체 목록은 [여기](https://www.nf-test.com/docs/testcases/global_variables/)에서 찾을 수 있지만 지금은 파이프라인 프로젝트의 루트를 의미하는 `projectDir` 변수를 사용하겠습니다. + +_변경 전:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_변경 후:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +테스트를 다시 실행하여 작동하는지 확인하겠습니다. + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.nf.test +``` + +```console title="파이프라인 통과" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +성공! 파이프라인이 성공적으로 실행되고 테스트가 통과합니다. 원하는 만큼 실행하면 항상 동일한 결과를 얻을 것입니다! + +기본적으로 Nextflow 출력은 숨겨지지만 nf-test가 확실히 워크플로우를 실행하고 있다는 것을 확신하려면 `--verbose` 플래그를 사용할 수 있습니다: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="파이프라인이 모든 프로세스 실행" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. 단언문 추가 + +간단한 확인은 파이프라인이 예상하는 모든 프로세스를 실행하고 있고 어떤 것도 조용히 건너뛰지 않는지 확인하는 것입니다. 파이프라인은 3개의 인사말 각각에 대해 `sayHello`라는 하나와 `convertToUpper`라는 하나씩 총 6개의 프로세스를 실행한다는 것을 기억하세요. + +파이프라인이 예상 수의 프로세스를 실행하는지 확인하기 위해 테스트에 단언문을 추가하겠습니다. 또한 테스트하는 내용을 더 잘 반영하도록 테스트 이름을 업데이트하겠습니다. + +**변경 전:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**변경 후:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +이제 테스트 이름이 실제로 확인하는 내용을 더 잘 반영합니다 - 파이프라인이 실패하지 않고 실행되는 것뿐만 아니라 예상 수의 프로세스를 실행합니다. + +테스트를 다시 실행하여 작동하는지 확인하겠습니다. + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.nf.test +``` + +```console title="단언문이 있는 파이프라인 통과" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +성공! 파이프라인이 성공적으로 실행되고 테스트가 통과합니다. 이제 전체 상태뿐만 아니라 파이프라인의 세부 사항도 테스트하기 시작했습니다. + +### 1.4. 출력 테스트 + +출력 파일이 생성되었는지 확인하기 위해 테스트에 단언문을 추가하겠습니다. 결과를 더 쉽게 해석할 수 있도록 정보를 제공하는 이름으로 별도의 테스트로 추가하겠습니다. + +**변경 전:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**변경 후:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +테스트를 다시 실행하여 작동하는지 확인하세요. + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.nf.test +``` + +```console title="파일 단언문이 있는 파이프라인 통과" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +성공! 파이프라인이 성공적으로 완료되고 올바른 수의 프로세스가 실행되었으며 출력 파일이 생성되었기 때문에 테스트가 통과합니다. 이것은 테스트에 정보를 제공하는 이름을 제공하는 것이 얼마나 유용한지도 보여줍니다. + +이것은 표면에 불과하며 파이프라인의 세부 사항을 확인하기 위해 계속해서 단언문을 작성할 수 있지만 지금은 파이프라인의 내부를 테스트하는 것으로 넘어가겠습니다. + +### 핵심 요점 + +파이프라인에 대한 nf-test를 작성하는 방법을 알고 있습니다. + +### 다음은? + +Nextflow 프로세스를 테스트하는 방법을 배웁니다. + +--- + +## 2. Nextflow 프로세스 테스트 + +파이프라인의 모든 부분에 대해 테스트를 작성할 필요는 없지만 더 많은 테스트가 있을수록 파이프라인에 대해 더 포괄적으로 알 수 있고 예상대로 작동한다는 확신을 더 가질 수 있습니다. 이 섹션에서는 파이프라인의 두 프로세스를 개별 단위로 테스트하겠습니다. + +### 2.1. `sayHello` 프로세스 테스트 + +`sayHello` 프로세스부터 시작하겠습니다. + +프로세스에 대한 테스트를 생성하기 위해 `nf-test generate` 명령을 다시 사용하겠습니다. + +```bash +nf-test generate process main.nf +``` + +```console title="출력" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +지금은 `main.sayhello.nf.test` 파일의 `sayhello` 프로세스에 집중하겠습니다. + +파일을 열어서 내용을 살펴보겠습니다. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +이전과 마찬가지로 테스트 세부 정보로 시작하고 그 다음에 `when` 및 `then` 블록이 옵니다. 그러나 프로세스에 대한 입력을 정의할 수 있는 추가 `process` 블록도 있습니다. + +테스트를 실행하여 작동하는지 확인하겠습니다. + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="프로세스 테스트 실패" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +`sayHello` 프로세스가 1개의 입력을 선언하지만 0개의 인수로 호출되었기 때문에 테스트가 실패합니다. 프로세스에 입력을 추가하여 이를 수정하겠습니다. [Hello Workflow](../hello_nextflow/03_hello_workflow.md)(및 위의 워밍업 섹션)에서 `sayHello` 프로세스가 제공해야 하는 단일 값 입력을 받는다는 것을 기억하세요. 또한 테스트하는 내용을 더 잘 반영하도록 테스트 이름을 수정해야 합니다. + +**변경 전:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**변경 후:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +테스트를 다시 실행하여 작동하는지 확인하겠습니다. + +```console title="nf-test 파이프라인 통과" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +성공! `sayHello` 프로세스가 성공적으로 실행되고 출력이 생성되었기 때문에 테스트가 통과합니다. + +### 2.2. 테스트로 생성된 스냅샷 확인 + +`tests/main.sayhello.nf.test` 파일을 보면 단언문 블록에서 `snapshot()` 메서드를 사용하는 것을 볼 수 있습니다: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +이는 nf-test에게 `sayHello` 프로세스의 출력 스냅샷을 생성하도록 지시합니다. 스냅샷 파일의 내용을 살펴보겠습니다. + +```console title="스냅샷 파일 내용" +code tests/main.sayhello.nf.test.snap +``` + +여기에 출력하지는 않겠지만 프로세스 및 프로세스 출력에 대한 세부 정보가 포함된 JSON 파일을 볼 수 있습니다. 특히 다음과 같은 줄을 볼 수 있습니다: + +```json title="스냅샷 파일 내용" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +이것은 명시적으로 테스트하고 있는 `sayHello` 프로세스에 의해 생성된 출력을 나타냅니다. 테스트를 다시 실행하면 프로그램은 새 출력이 원래 기록된 출력과 일치하는지 확인합니다. 이것은 프로세스 출력이 변경되지 않았는지 테스트하는 빠르고 간단한 방법이므로 nf-test는 이를 기본값으로 제공합니다. + +!!!warning + + 즉, 원래 실행에서 기록하는 출력이 올바른지 확신해야 합니다! + +향후 개발 과정에서 출력이 달라지도록 코드에 변경 사항이 있으면 테스트가 실패하고 변경이 예상된 것인지 아닌지 판단해야 합니다. + +- 코드에 문제가 생긴 것으로 밝혀지면 수정된 코드가 테스트를 통과할 것으로 기대하면서 수정해야 합니다. +- 예상된 변경인 경우(예: 도구가 개선되어 결과가 더 나아짐) 새 출력을 일치시킬 참조로 받아들이도록 스냅샷을 업데이트해야 합니다. nf-test에는 이 목적을 위한 `--update-snapshot` 매개변수가 있습니다. + +테스트를 다시 실행하면 테스트가 통과해야 합니다: + +```console title="스냅샷이 있는 nf-test 프로세스 통과" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +성공! `sayHello` 프로세스가 성공적으로 실행되고 출력이 스냅샷과 일치하기 때문에 테스트가 통과합니다. + +### 2.3. 스냅샷의 대안: 직접 콘텐츠 단언문 + +스냅샷은 출력의 모든 변경 사항을 포착하는 데 유용하지만 때로는 전체 파일이 일치하는 것에 대해 그렇게 엄격하지 않고 특정 콘텐츠를 확인하고 싶을 때가 있습니다. 예를 들어: + +- 출력의 일부가 변경될 수 있지만(타임스탬프, 임의 ID 등) 특정 주요 콘텐츠가 있어야 하는 경우 +- 출력에서 특정 패턴이나 값을 확인하려는 경우 +- 성공을 구성하는 것에 대해 테스트를 더 명시적으로 만들고 싶은 경우 + +다음은 특정 콘텐츠를 확인하도록 테스트를 수정하는 방법입니다: + +**변경 전:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**변경 후:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +nf-test는 프로세스 출력을 리스트의 리스트로 보므로 `process.out[0][0]`은 이 프로세스의 첫 번째 채널 항목(또는 '방출')의 첫 번째 부분을 가져오는 것입니다. + +이 접근 방식은: + +- 출력에서 정확히 무엇을 기대하는지 명확하게 합니다 +- 출력의 관련 없는 변경 사항에 더 탄력적입니다 +- 테스트가 실패할 때 더 나은 오류 메시지를 제공합니다 +- 더 복잡한 검증(정규식 패턴, 숫자 비교 등)을 허용합니다 + +테스트를 실행하여 작동하는지 확인하겠습니다. + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="프로세스 테스트 실패" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. `convertToUpper` 프로세스 테스트 + +`tests/main.converttoupper.nf.test` 파일을 열어서 내용을 살펴보겠습니다: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +이것은 `sayHello` 프로세스와 유사한 테스트이지만 `convertToUpper` 프로세스를 테스트합니다. `sayHello`와 마찬가지로 `convertToUpper` 프로세스가 단일 경로 입력을 받지만 지정하지 않았기 때문에 이것도 실패할 것임을 알고 있습니다. + +이제 대문자로 변환하려는 텍스트가 포함된 단일 입력 파일을 convertToUpper 프로세스에 제공해야 합니다. 이를 수행할 수 있는 많은 방법이 있습니다: + +- 테스트할 전용 파일을 만들 수 있습니다 +- 기존 data/greetings.csv 파일을 재사용할 수 있습니다 +- 테스트 내에서 즉석에서 만들 수 있습니다 + +지금은 파이프라인 수준 테스트에서 사용한 예제를 사용하여 기존 data/greetings.csv 파일을 재사용하겠습니다. 이전과 마찬가지로 테스트하는 내용을 더 잘 반영하도록 테스트 이름을 지정할 수 있지만 이번에는 특정 문자열을 확인하는 대신(다른 프로세스에서 했던 것처럼) 콘텐츠를 '스냅샷'하도록 두겠습니다. + +**변경 전:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**변경 후:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +그리고 테스트를 실행하세요! + +```bash title="nf-test 파이프라인 통과" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test 프로세스 convertToUpper 통과" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +참고로 `tests/main.converttoupper.nf.test.snap`에 `convertToUpper` 프로세스에 대한 스냅샷 파일을 만들었습니다. 테스트를 다시 실행하면 nf-test가 다시 통과하는 것을 볼 수 있습니다. + +```bash title="nf-test 프로세스 convertToUpper 통과" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test 프로세스 convertToUpper 통과" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### 핵심 요점 + +Nextflow 프로세스에 대한 테스트를 작성하고 실행하는 방법을 알고 있습니다. + +### 다음은? + +한 번에 모든 것에 대한 테스트를 실행하는 방법을 배웁니다! + +## 3. 전체 저장소에 대한 테스트 실행 + +각 구성 요소에서 nf-test를 실행하는 것은 괜찮지만 번거롭고 오류가 발생하기 쉽습니다. 한 번에 모든 것을 테스트할 수 없을까요? + +네, 할 수 있습니다! + +전체 저장소에서 nf-test를 실행하겠습니다. + +### 3.1. 전체 저장소에서 nf-test 실행 + +`nf-test test` 명령을 실행하여 전체 저장소에서 nf-test를 실행할 수 있습니다. + +```bash +nf-test test . +``` + +참고로 현재 디렉토리에서 모든 것을 실행하기 위해 `.`를 사용하고 있습니다. 이것은 모든 테스트를 포함할 것입니다! + +```console title="nf-test 저장소 통과" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +확인해보세요! 단일 명령으로 각 프로세스에 대해 1개, 전체 파이프라인에 대해 2개, 총 4개의 테스트를 실행했습니다. 대규모 코드베이스에서 이것이 얼마나 강력한지 상상해보세요! + +--- + +## 요약 + +이 사이드 퀘스트에서는 nf-test의 기능을 활용하여 개별 프로세스에 대한 테스트와 전체 파이프라인에 대한 엔드투엔드 테스트를 생성하고 실행하는 방법을 배웠습니다. +이제 출력 검증에 대한 두 가지 주요 접근 방식인 스냅샷과 직접 콘텐츠 단언문을 알고 있으며 각각을 언제 사용할지 알고 있습니다. +또한 하나씩 또는 전체 프로젝트에 대해 테스트를 실행하는 방법도 알고 있습니다. + +자신의 작업에 이러한 기술을 적용하면 다음을 보장할 수 있습니다: + +- 코드가 예상대로 작동합니다 +- 변경 사항이 기존 기능을 손상시키지 않습니다 +- 다른 개발자가 자신감을 가지고 기여할 수 있습니다 +- 문제를 빠르게 식별하고 수정할 수 있습니다 +- 출력 콘텐츠가 예상과 일치합니다 + +### 주요 패턴 + +<!-- TODO: Can we add snipp diff --git a/docs/ko/docs/side_quests/orientation.md b/docs/ko/docs/side_quests/orientation.md new file mode 100644 index 0000000000..669de082f8 --- /dev/null +++ b/docs/ko/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# 오리엔테이션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces 환경에는 이 교육 과정을 진행하는 데 필요한 모든 소프트웨어, 코드 및 데이터가 포함되어 있으므로, 별도로 설치할 필요가 없습니다. +그러나 로그인하려면 (무료) 계정이 필요하며, 인터페이스에 익숙해지는 데 몇 분 정도 시간을 할애하시기 바랍니다. + +아직 수행하지 않으셨다면, 계속 진행하기 전에 [이 링크](../../envsetup/)를 따라가 주시기 바랍니다. + +## 제공되는 자료 + +이 교육 과정을 진행하는 동안 `side-quests/` 디렉토리에서 작업하게 됩니다. +이 디렉토리에는 필요한 모든 코드 파일, 테스트 데이터 및 부속 파일이 포함되어 있습니다. + +이 디렉토리의 내용을 자유롭게 탐색하시기 바랍니다. 가장 쉬운 방법은 GitHub Codespaces 작업 공간의 왼쪽에 있는 파일 탐색기를 사용하는 것입니다. +또는 `tree` 명령을 사용할 수도 있습니다. +과정 전반에 걸쳐 `tree`의 출력을 사용하여 디렉토리 구조와 내용을 읽기 쉬운 형태로 표현하며, 때로는 명확성을 위해 약간 수정하기도 합니다. + +여기서는 두 번째 수준까지 목차를 생성합니다: + +```bash +tree . -L 2 +``` + +`side-quests` 내부에서 이를 실행하면 다음과 같은 출력이 표시됩니다: + +```console title="디렉토리 내용" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**시작하기 위해 알아야 할 내용을 요약하면 다음과 같습니다:** + +- **각 디렉토리는 개별 사이드 퀘스트에 해당합니다.** + 각 내용은 해당 사이드 퀘스트 페이지에 자세히 설명되어 있습니다. + +- **`solutions` 디렉토리**에는 각 사이드 퀘스트의 다양한 단계를 진행하여 생성된 완성된 워크플로우 및/또는 모듈 스크립트가 포함되어 있습니다. + 이는 작업을 확인하고 문제를 해결하는 데 참조로 사용하도록 제공됩니다. + +!!!tip + + 어떤 이유로든 이 디렉토리를 벗어났다면, 다음 명령을 실행하여 언제든지 돌아올 수 있습니다: + + ```bash + cd /workspaces/training/side-quests + ``` + +이제 과정을 시작하려면 이 페이지의 오른쪽 하단에 있는 화살표를 클릭하시기 바랍니다. diff --git a/docs/ko/docs/side_quests/splitting_and_grouping.md b/docs/ko/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..a9a861de84 --- /dev/null +++ b/docs/ko/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,833 @@ +# 데이터 분할 및 그룹화 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow는 데이터를 유연하게 다룰 수 있는 강력한 도구를 제공합니다. 주요 기능 중 하나는 데이터를 여러 스트림으로 분할한 다음 관련 항목을 다시 그룹화하는 것입니다. 이는 특히 생물정보학 워크플로에서 유용합니다. 이러한 워크플로에서는 서로 다른 유형의 샘플을 별도로 처리한 후 분석을 위해 결과를 결합해야 합니다. + +우편물을 분류하는 것으로 생각해 보십시오. 목적지별로 편지를 분리하고, 각 묶음을 다르게 처리한 다음, 동일한 사람에게 보내지는 항목을 다시 결합합니다. Nextflow는 과학 데이터로 이를 수행하기 위해 특수 연산자를 사용합니다. 이 접근 방식은 분산 컴퓨팅 및 생물정보학 워크플로에서 일반적으로 **scatter/gather** 패턴으로 알려져 있습니다. + +Nextflow의 채널 시스템은 이러한 유연성의 핵심입니다. 채널은 워크플로의 여러 부분을 연결하여 데이터가 분석을 통해 흐를 수 있도록 합니다. 단일 데이터 소스에서 여러 채널을 생성하고, 각 채널을 다르게 처리한 다음, 필요할 때 채널을 다시 병합할 수 있습니다. 이 접근 방식을 사용하면 복잡한 생물정보학 분석의 분기 및 수렴 경로를 자연스럽게 반영하는 워크플로를 설계할 수 있습니다. + +### 학습 목표 + +이 사이드 퀘스트에서는 Nextflow의 채널 연산자를 사용하여 데이터를 분할하고 그룹화하는 방법을 배웁니다. +샘플 정보 및 관련 데이터 파일이 포함된 CSV 파일로 시작한 다음 이 데이터를 조작하고 재구성합니다. + +이 사이드 퀘스트가 끝나면 다음 기술을 사용하여 데이터 스트림을 효과적으로 분리하고 결합할 수 있습니다: + +- `splitCsv`를 사용하여 파일에서 데이터 읽기 +- `filter` 및 `map`으로 데이터 필터링 및 변환 +- `join` 및 `groupTuple`을 사용하여 관련 데이터 결합 +- 병렬 처리를 위해 `combine`으로 데이터 조합 생성 +- `subMap` 및 중복 제거 전략을 사용하여 데이터 구조 최적화 +- 명명된 클로저를 사용하여 채널 구조를 조작하는 데 도움이 되는 재사용 가능한 함수 구축 + +이러한 기술은 깨끗하고 유지 관리 가능한 코드 구조를 유지하면서 여러 입력 파일과 다양한 유형의 데이터를 효율적으로 처리할 수 있는 워크플로를 구축하는 데 도움이 됩니다. + +### 전제 조건 + +이 사이드 퀘스트를 시작하기 전에 다음을 수행해야 합니다: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 이에 상응하는 초급 과정을 완료했습니다. +- 기본적인 Nextflow 개념 및 메커니즘(프로세스, 채널, 연산자, 파일 작업, 메타데이터)을 사용하는 데 익숙합니다. + +**선택 사항:** 먼저 [워크플로의 메타데이터](./metadata.md) 사이드 퀘스트를 완료하는 것이 좋습니다. +여기에서는 `splitCsv`로 CSV 파일을 읽고 메타 맵을 생성하는 기본 사항을 다룹니다. 이는 여기에서 많이 사용할 것입니다. + +--- + +## 0. 시작하기 + +#### 교육 codespace 열기 + +아직 수행하지 않았다면 [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 열어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 있는 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/splitting_and_grouping +``` + +VSCode가 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +메인 워크플로 파일과 `samplesheet.csv`라는 샘플시트가 포함된 `data` 디렉토리를 찾을 수 있습니다. + +```console title="디렉토리 내용" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +샘플시트에는 환자 ID, 샘플 반복 번호, 유형(정상 또는 종양) 및 가상 데이터 파일 경로(실제로 존재하지 않지만 존재한다고 가정함)를 포함하여 여러 환자의 샘플에 대한 정보가 포함되어 있습니다. + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +이 샘플시트에는 세 명의 환자(A, B, C)로부터 얻은 8개의 샘플이 나열되어 있습니다. + +각 환자에 대해 `tumor`(일반적으로 종양 생검에서 유래) 또는 `normal`(건강한 조직 또는 혈액에서 채취) 유형의 샘플이 있습니다. +암 분석에 익숙하지 않다면 이것이 대조 분석을 수행하기 위해 쌍을 이루는 종양/정상 샘플을 사용하는 실험 모델에 해당한다는 것만 알아두십시오. + +특히 환자 A의 경우 두 세트의 기술적 복제(반복)가 있습니다. + +!!! note "참고" + + 이 실험 설계에 익숙하지 않더라도 걱정하지 마십시오. 이 튜토리얼을 이해하는 데 중요하지 않습니다. + +#### 과제 검토 + +귀하의 과제는 다음을 수행하는 Nextflow 워크플로를 작성하는 것입니다: + +1. CSV 파일에서 샘플 데이터를 **읽고** 메타 맵으로 구조화합니다 +2. 유형(정상 대 종양)에 따라 샘플을 여러 채널로 **분리**합니다 +3. 환자 ID 및 복제 번호로 일치하는 종양/정상 쌍을 **조인**합니다 +4. 병렬 처리를 위해 게놈 간격에 샘플을 **분산**합니다 +5. 다운스트림 분석을 위해 관련 샘플을 다시 **그룹화**합니다 + +이것은 독립적인 처리를 위해 데이터를 분할한 다음 비교 분석을 위해 관련 항목을 다시 결합해야 하는 일반적인 생물정보학 패턴을 나타냅니다. + +#### 준비 상태 체크리스트 + +준비가 되었다고 생각하십니까? + +- [ ] 이 과정의 목표와 전제 조건을 이해합니다 +- [ ] codespace가 작동 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 과제를 이해합니다 + +모든 항목을 체크할 수 있다면 시작할 준비가 된 것입니다. + +--- + +## 1. 샘플 데이터 읽기 + +### 1.1. `splitCsv`로 샘플 데이터를 읽고 메타 맵 생성 + +먼저 `splitCsv`로 샘플 데이터를 읽고 메타 맵 패턴으로 구성해 보겠습니다. `main.nf`에서 워크플로를 이미 시작했음을 알 수 있습니다. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note "참고" + + 이 튜토리얼 전체에서 모든 채널 변수에 `ch_` 접두사를 사용하여 Nextflow 채널임을 명확하게 표시합니다. + +[워크플로의 메타데이터](./metadata.md) 사이드 퀘스트를 완료했다면 이 패턴을 알아볼 것입니다. `splitCsv`를 사용하여 CSV를 읽고 즉시 메타 맵으로 데이터를 구조화하여 메타데이터를 파일 경로와 분리합니다. + +!!! info + + 이 교육에서 `map`이라는 두 가지 개념을 접하게 됩니다: + + - **데이터 구조**: 키-값 쌍을 저장하는 Groovy 맵(다른 언어의 딕셔너리/해시에 해당) + - **채널 연산자**: 채널의 항목을 변환하는 `.map()` 연산자 + + 컨텍스트에서 어떤 것을 의미하는지 명확히 하겠지만 이 구분은 Nextflow 작업 시 이해하는 것이 중요합니다. + +`main.nf`에 다음 변경 사항을 적용하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +이것은 `splitCsv` 작업(헤더가 있는 CSV 읽기)과 `map` 작업(데이터를 `[meta, file]` 튜플로 구조화)을 한 단계로 결합합니다. 해당 변경 사항을 적용하고 파이프라인을 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +이제 각 항목이 `[meta, file]` 튜플인 채널이 있습니다. 메타데이터가 파일 경로와 분리되었습니다. 이 구조를 통해 메타데이터 필드를 기반으로 작업을 분할하고 그룹화할 수 있습니다. + +--- + +## 2. 데이터 필터링 및 변환 + +### 2.1. `filter`로 데이터 필터링 + +[`filter` 연산자](https://www.nextflow.io/docs/latest/operator.html#filter)를 사용하여 조건에 따라 데이터를 필터링할 수 있습니다. 정상 샘플만 처리하려고 한다고 가정해 보겠습니다. `type` 필드를 기반으로 데이터를 필터링하여 이를 수행할 수 있습니다. `view` 연산자 앞에 이것을 삽입해 보겠습니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +워크플로를 다시 실행하여 필터링된 결과를 확인하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +정상 샘플만 포함하도록 데이터를 성공적으로 필터링했습니다. 이것이 어떻게 작동하는지 요약해 보겠습니다. + +`filter` 연산자는 채널의 각 요소에 적용되는 클로저를 사용합니다. 클로저가 `true`를 반환하면 요소가 포함되고, `false`를 반환하면 요소가 제외됩니다. + +우리의 경우 `meta.type == 'normal'`인 샘플만 유지하려고 합니다. 클로저는 튜플 `meta,file`을 사용하여 각 샘플을 참조하고, `meta.type`으로 샘플 유형에 액세스하고, 그것이 `'normal'`과 같은지 확인합니다. + +이는 위에서 소개한 단일 클로저로 수행됩니다: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. 별도의 필터링된 채널 생성 + +현재 CSV에서 직접 생성된 채널에 필터를 적용하고 있지만 이것을 하나 이상의 방법으로 필터링하려고 하므로 정상 샘플에 대한 별도의 필터링된 채널을 생성하도록 로직을 다시 작성해 보겠습니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +파이프라인을 실행하여 결과를 확인하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +데이터를 성공적으로 필터링하고 정상 샘플에 대한 별도의 채널을 생성했습니다. + +종양 샘플에 대한 필터링된 채널도 생성해 보겠습니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +정상 및 종양 샘플을 두 개의 다른 채널로 분리하고 `view()`에 제공된 클로저를 사용하여 출력에서 다르게 레이블을 지정했습니다: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### 핵심 요약 + +이 섹션에서는 다음을 배웠습니다: + +- **데이터 필터링**: `filter`로 데이터를 필터링하는 방법 +- **데이터 분할**: 조건에 따라 데이터를 여러 채널로 분할하는 방법 +- **데이터 보기**: `view`를 사용하여 데이터를 출력하고 여러 채널의 출력에 레이블을 지정하는 방법 + +이제 정상 및 종양 샘플을 두 개의 다른 채널로 분리했습니다. 다음으로 `id` 필드에서 정상 및 종양 샘플을 조인하겠습니다. + +--- + +## 3. 식별자로 채널 조인 + +이전 섹션에서는 정상 및 종양 샘플을 두 개의 다른 채널로 분리했습니다. 이들은 유형에 따라 특정 프로세스 또는 워크플로를 사용하여 독립적으로 처리될 수 있습니다. 그러나 동일한 환자의 정상 및 종양 샘플을 비교하려면 어떻게 해야 합니까? 이 시점에서 `id` 필드를 기반으로 샘플을 일치시켜 다시 조인해야 합니다. + +Nextflow에는 채널을 결합하는 여러 방법이 포함되어 있지만 이 경우 가장 적절한 연산자는 [`join`](https://www.nextflow.io/docs/latest/operator.html#join)입니다. SQL에 익숙하다면 `JOIN` 연산처럼 작동하며, 조인할 키와 수행할 조인 유형을 지정합니다. + +### 3.1. `map` 및 `join`을 사용하여 환자 ID를 기반으로 결합 + +[`join`](https://www.nextflow.io/docs/latest/operator.html#join) 문서를 확인하면 기본적으로 각 튜플의 첫 번째 항목을 기반으로 두 채널을 조인한다는 것을 알 수 있습니다. + +#### 3.1.1. 데이터 구조 확인 + +콘솔 출력을 계속 사용할 수 없는 경우 파이프라인을 실행하여 데이터 구조를 확인하고 `id` 필드에서 조인하도록 수정해야 하는 방법을 살펴보겠습니다. + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +`id` 필드가 각 메타 맵의 첫 번째 요소임을 알 수 있습니다. `join`이 작동하려면 각 튜플에서 `id` 필드를 분리해야 합니다. 그런 다음 `join` 연산자를 사용하여 두 채널을 결합하면 됩니다. + +#### 3.1.2. `id` 필드 분리 + +`id` 필드를 분리하려면 [`map` 연산자](https://www.nextflow.io/docs/latest/operator.html#map)를 사용하여 `id` 필드를 첫 번째 요소로 하는 새 튜플을 생성할 수 있습니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +미묘할 수 있지만 각 튜플의 첫 번째 요소가 `id` 필드임을 알 수 있어야 합니다. + +#### 3.1.3. 두 채널 결합 + +이제 `join` 연산자를 사용하여 `id` 필드를 기반으로 두 채널을 결합할 수 있습니다. + +다시 한 번 `view`를 사용하여 조인된 출력을 출력합니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +너무 넓어서 알기 어렵지만 샘플이 `id` 필드로 조인되었음을 알 수 있어야 합니다. 이제 각 튜플은 다음 형식을 갖습니다: + +- `id`: 샘플 ID +- `normal_meta_map`: 유형, 복제 및 bam 파일 경로를 포함한 정상 샘플 메타데이터 +- `normal_sample_file`: 정상 샘플 파일 +- `tumor_meta_map`: 유형, 복제 및 bam 파일 경로를 포함한 종양 샘플 메타데이터 +- `tumor_sample`: 유형, 복제 및 bam 파일 경로를 포함한 종양 샘플 + +!!! warning "경고" + + `join` 연산자는 일치하지 않는 튜플을 삭제합니다. 이 예제에서는 모든 샘플이 종양 및 정상에 대해 일치하는지 확인했지만 그렇지 않은 경우 일치하지 않는 튜플을 유지하려면 매개변수 `remainder: true`를 사용해야 합니다. 자세한 내용은 [문서](https://www.nextflow.io/docs/latest/operator.html#join)를 확인하십시오. + +이제 `map`을 사용하여 튜플의 필드를 분리하는 방법과 `join`을 사용하여 첫 번째 필드를 기반으로 튜플을 결합하는 방법을 알았습니다. +이 지식을 통해 공유 필드를 기반으로 채널을 성공적으로 결합할 수 있습니다. + +다음으로 여러 필드에서 조인하려는 상황을 고려하겠습니다. + +### 3.2. 여러 필드에서 조인 + +sampleA에는 2개의 복제가 있지만 sampleB와 sampleC에는 1개만 있습니다. 이 경우 `id` 필드를 사용하여 효과적으로 조인할 수 있었지만 동기화되지 않으면 어떻게 될까요? 서로 다른 복제의 정상 및 종양 샘플을 혼동할 수 있습니다! + +이를 방지하려면 여러 필드에서 조인할 수 있습니다. 실제로 이를 달성하는 여러 방법이 있지만 샘플 `id`와 `replicate` 번호를 모두 포함하는 새 조인 키를 만드는 데 집중하겠습니다. + +새 조인 키를 만드는 것부터 시작하겠습니다. 이전과 같은 방법으로 [`map` 연산자](https://www.nextflow.io/docs/latest/operator.html#map)를 사용하여 `id` 및 `repeat` 필드를 첫 번째 요소로 하는 새 튜플을 생성할 수 있습니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +이제 `id` 및 `repeat` 필드를 모두 사용하여 조인이 발생하는 것을 볼 수 있어야 합니다. 워크플로를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +각 조인 결과의 첫 번째 요소로 두 요소(`id` 및 `repeat` 필드)의 튜플이 어떻게 있는지 주목하십시오. 이것은 복잡한 항목을 조인 키로 사용할 수 있음을 보여주며 동일한 조건의 샘플 간에 상당히 복잡한 일치를 가능하게 합니다. + +다른 키에서 조인하는 더 많은 방법을 탐색하려면 추가 옵션 및 예제에 대한 [join 연산자 문서](https://www.nextflow.io/docs/latest/operator.html#join)를 확인하십시오. + +### 3.3. `subMap`을 사용하여 새 조인 키 생성 + +이전 접근 방식은 조인 키에서 필드 이름을 잃어버립니다. `id` 및 `repeat` 필드는 값 목록이 됩니다. 나중에 액세스할 수 있도록 필드 이름을 유지하려면 [`subMap` 메서드](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>)를 사용할 수 있습니다. + +`subMap` 메서드는 맵에서 지정된 키-값 쌍만 추출합니다. 여기서는 `id` 및 `repeat` 필드만 추출하여 조인 키를 만듭니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +이제 `id` 및 `repeat` 필드를 포함할 뿐만 아니라 필드 이름도 유지하여 나중에 이름으로 액세스할 수 있는 새 조인 키가 있습니다(예: `meta.id` 및 `meta.repeat`). + +### 3.4. map에서 명명된 클로저 사용 + +중복을 피하고 오류를 줄이기 위해 명명된 클로저를 사용할 수 있습니다. 명명된 클로저를 사용하면 여러 곳에서 호출할 수 있는 재사용 가능한 함수를 만들 수 있습니다. + +이를 위해 먼저 클로저를 새 변수로 정의합니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +재사용할 수 있는 명명된 변수로 맵 변환을 정의했습니다. + +또한 `file()`을 사용하여 파일 경로를 Path 객체로 변환하여 이 채널을 수신하는 모든 프로세스가 파일을 올바르게 처리할 수 있도록 합니다(자세한 내용은 [파일 작업](./working_with_files.md) 참조). + +워크플로에서 클로저를 구현해 보겠습니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note "참고" + + `map` 연산자는 클로저를 인수로 전달하기 위해 `{ }`를 사용하는 것에서 `( )`를 사용하는 것으로 전환되었습니다. `map` 연산자는 클로저를 인수로 예상하고 `{ }`는 익명 클로저를 정의하는 데 사용되기 때문입니다. 명명된 클로저를 호출할 때는 `( )` 구문을 사용하십시오. + +모든 것이 여전히 작동하는지 확인하기 위해 워크플로를 한 번 더 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +명명된 클로저를 사용하면 여러 곳에서 동일한 변환을 재사용할 수 있으므로 오류 위험이 줄어들고 코드의 가독성과 유지 관리성이 향상됩니다. + +### 3.5. 데이터 중복 감소 + +워크플로에 많은 중복 데이터가 있습니다. 조인된 샘플의 각 항목은 `id` 및 `repeat` 필드를 반복합니다. 이 정보는 이미 그룹화 키에서 사용할 수 있으므로 이러한 중복을 피할 수 있습니다. 다시 말해서, 현재 데이터 구조는 다음과 같습니다: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +`id` 및 `repeat` 필드는 그룹화 키에서 사용할 수 있으므로 중복을 방지하기 위해 각 채널 항목의 나머지 부분에서 제거해 보겠습니다. `subMap` 메서드를 사용하여 `type` 필드만 있는 새 맵을 생성하면 됩니다. 이 접근 방식을 통해 데이터 구조의 중복을 제거하면서 필요한 모든 정보를 유지할 수 있습니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +이제 클로저는 첫 번째 요소에 `id` 및 `repeat` 필드가 포함되고 두 번째 요소에는 `type` 필드만 포함된 튜플을 반환합니다. 이는 `id` 및 `repeat` 정보를 그룹화 키에 한 번 저장하여 중복을 제거하면서 필요한 모든 정보를 유지합니다. + +워크플로를 실행하여 어떻게 보이는지 확인하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +그룹화 키에서 `id` 및 `repeat` 필드를 한 번만 명시하고 샘플 데이터에 `type` 필드가 있음을 알 수 있습니다. 정보를 잃지 않았지만 채널 내용을 더 간결하게 만들었습니다. + +### 3.6. 중복 정보 제거 + +위에서 중복된 정보를 제거했지만 채널에는 여전히 다른 중복 정보가 있습니다. + +처음에 우리는 `filter`를 사용하여 정상 및 종양 샘플을 분리한 다음 `id` 및 `repeat` 키를 기반으로 조인했습니다. `join` 연산자는 튜플이 병합되는 순서를 보존하므로 우리의 경우 왼쪽에 정상 샘플이 있고 오른쪽에 종양 샘플이 있는 경우 결과 채널은 이 구조를 유지합니다: `id, <정상 요소>, <종양 요소>`. + +채널에서 각 요소의 위치를 알고 있으므로 `[type:normal]` 및 `[type:tumor]` 메타데이터를 삭제하여 구조를 더 단순화할 수 있습니다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +다시 실행하여 결과를 확인하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### 핵심 요약 + +이 섹션에서는 다음을 배웠습니다: + +- **튜플 조작**: `map`을 사용하여 튜플의 필드를 분리하는 방법 +- **튜플 조인**: `join`을 사용하여 첫 번째 필드를 기반으로 튜플을 결합하는 방법 +- **조인 키 생성**: `subMap`을 사용하여 새 조인 키를 생성하는 방법 +- **명명된 클로저**: map에서 명명된 클로저를 사용하는 방법 +- **여러 필드 조인**: 더 정확한 일치를 위해 여러 필드에서 조인하는 방법 +- **데이터 구조 최적화**: 중복 정보를 제거하여 채널 구조를 간소화하는 방법 + +이제 샘플시트를 분할하고, 정상 및 종양 샘플을 필터링하고, 샘플 ID 및 복제 번호로 함께 조인한 다음 결과를 출력할 수 있는 워크플로가 있습니다. + +이것은 독립적으로 처리한 후 샘플 또는 기타 유형의 데이터를 일치시켜야 하는 생물정보학 워크플로의 일반적인 패턴이므로 유용한 기술입니다. 다음으로 샘플을 여러 번 반복하는 방법을 살펴보겠습니다. + +## 4. 샘플을 간격으로 분산 + +생물정보학 워크플로의 핵심 패턴은 게놈 영역에 분석을 분산하는 것입니다. 예를 들어, 변이 호출은 게놈을 간격(염색체 또는 더 작은 영역과 같은)으로 나누어 병렬화할 수 있습니다. 이 병렬화 전략은 계산 부하를 여러 코어 또는 노드에 분산시켜 전체 실행 시간을 줄임으로써 파이프라인 효율성을 크게 향상시킵니다. + +다음 섹션에서는 샘플 데이터를 여러 게놈 간격에 분산하는 방법을 보여줍니다. 각 샘플을 모든 간격과 쌍으로 묶어 다른 게놈 영역의 병렬 처리를 허용합니다. 이렇게 하면 간격 수만큼 데이터 세트 크기가 배가되어 나중에 다시 가져올 수 있는 여러 독립적인 분석 단위가 생성됩니다. + +### 4.1. `combine`을 사용하여 간격에 샘플 분산 + +간격 채널을 만드는 것부터 시작하겠습니다. 간단하게 유지하기 위해 수동으로 정의할 3개의 간격만 사용합니다. 실제 diff --git a/docs/ko/docs/side_quests/workflows_of_workflows.md b/docs/ko/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..aa996ffed5 --- /dev/null +++ b/docs/ko/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# 워크플로우의 워크플로우 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +파이프라인을 개발할 때, 다양한 데이터 유형이나 분석 단계에 대해 유사한 프로세스 시퀀스를 생성하는 경우가 종종 있습니다. 이러한 프로세스 시퀀스를 복사하고 붙여넣게 되면 유지 관리가 어려운 중복 코드가 생성되거나, 이해하고 수정하기 어려운 하나의 거대한 워크플로우를 만들게 될 수 있습니다. + +Nextflow의 가장 강력한 기능 중 하나는 작고 재사용 가능한 워크플로우 모듈로부터 복잡한 파이프라인을 구성할 수 있는 능력입니다. 이러한 모듈식 접근 방식은 파이프라인을 더 쉽게 개발, 테스트 및 유지 관리할 수 있게 합니다. + +### 학습 목표 + +이 사이드 퀘스트에서는 개별적으로 테스트하고 사용할 수 있는 워크플로우 모듈을 개발하는 방법, 해당 모듈을 더 큰 파이프라인으로 구성하는 방법, 그리고 모듈 간 데이터 흐름을 관리하는 방법을 살펴보겠습니다. + +이 사이드 퀘스트를 마치면 다음을 할 수 있게 됩니다: + +- 복잡한 파이프라인을 논리적이고 재사용 가능한 단위로 분해하기 +- 각 워크플로우 모듈을 독립적으로 테스트하기 +- 워크플로우를 조합하여 새로운 파이프라인 생성하기 +- 여러 파이프라인에서 공통 워크플로우 모듈 공유하기 +- 코드를 더 유지 관리하기 쉽고 이해하기 쉽게 만들기 + +이러한 기술은 깔끔하고 유지 관리 가능한 코드 구조를 유지하면서 복잡한 파이프라인을 구축하는 데 도움이 될 것입니다. + +### 사전 요구 사항 + +이 사이드 퀘스트를 시작하기 전에 다음을 완료해야 합니다: + +- [Hello Nextflow](../hello_nextflow/README.md) 튜토리얼 또는 이에 상응하는 초급 과정을 완료했어야 합니다. +- 기본 Nextflow 개념과 메커니즘(프로세스, 채널, 연산자, 모듈)을 편안하게 사용할 수 있어야 합니다. + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 하지 않았다면, [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 여십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 위치한 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/workflows_of_workflows +``` + +VSCode가 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +'Hello Nextflow'에서 학습한 내용을 기반으로 하는 여러 프로세스 정의가 포함된 `modules` 디렉토리를 찾을 수 있습니다: + +```console title="디렉토리 내용" +modules/ +├── say_hello.nf # 인사말 생성 (Hello Nextflow에서) +├── say_hello_upper.nf # 대문자로 변환 (Hello Nextflow에서) +├── timestamp_greeting.nf # 인사말에 타임스탬프 추가 +├── validate_name.nf # 입력 이름 검증 +└── reverse_text.nf # 텍스트 내용 역순으로 변환 +``` + +#### 과제 검토 + +여러분의 과제는 이러한 모듈을 두 개의 개별 워크플로우로 조합한 다음, 이를 메인 워크플로우로 구성하는 것입니다: + +- 이름을 검증하고, 인사말을 생성하며, 타임스탬프를 추가하는 `GREETING_WORKFLOW` +- 텍스트를 대문자로 변환하고 역순으로 바꾸는 `TRANSFORM_WORKFLOW` + +#### 준비 체크리스트 + +시작할 준비가 되었다고 생각하시나요? + +- [ ] 이 과정의 목표와 사전 요구 사항을 이해했습니다 +- [ ] 코드스페이스가 실행되고 있습니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 과제를 이해했습니다 + +모든 항목을 확인할 수 있다면 시작할 준비가 된 것입니다. + +--- + +## 1. 인사말 워크플로우 생성 + +이름을 검증하고 타임스탬프가 찍힌 인사말을 생성하는 워크플로우를 만들어 보겠습니다. + +### 1.1. 워크플로우 구조 생성 + +```bash title="워크플로우 디렉토리 및 파일 생성" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. 첫 번째 (서브)워크플로우 코드 추가 + +다음 코드를 `workflows/greeting.nf`에 추가하십시오: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // 프로세스 체인: 검증 -> 인사말 생성 -> 타임스탬프 추가 + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +이것은 'Hello Nextflow' 튜토리얼에서 본 것과 유사한 구조를 가진 완전한 워크플로우이며, 독립적으로 테스트할 수 있습니다. 지금 시도해 보겠습니다: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +예상대로 작동하지만, 구성 가능하게 만들기 위해 변경해야 할 몇 가지 사항이 있습니다. + +### 1.3. 워크플로우를 구성 가능하게 만들기 + +구성 가능한 워크플로우는 'Hello Nextflow' 튜토리얼에서 본 것과 몇 가지 차이점이 있습니다: + +- 워크플로우 블록에 이름이 필요합니다 +- 입력은 `take:` 키워드를 사용하여 선언됩니다 +- 워크플로우 내용은 `main:` 블록 내부에 배치됩니다 +- 출력은 `emit:` 키워드를 사용하여 선언됩니다 + +인사말 워크플로우를 이 구조에 맞게 업데이트해 보겠습니다. 코드를 다음과 같이 변경하십시오: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // 이름이 담긴 입력 채널 + + main: + // 프로세스 체인: 검증 -> 인사말 생성 -> 타임스탬프 추가 + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // 원본 인사말 + timestamped = timestamped_ch // 타임스탬프가 찍힌 인사말 +} +``` + +워크플로우에 이제 이름이 있고 `take:` 및 `emit:` 블록이 있으며, 이것들이 상위 레벨 워크플로우를 구성하는 데 사용할 연결입니다. +워크플로우 내용도 `main:` 블록 내부에 배치됩니다. 또한 `names_ch` 입력 채널 선언을 제거했는데, 이는 이제 워크플로우에 인수로 전달되기 때문입니다. + +워크플로우가 예상대로 작동하는지 다시 테스트해 보겠습니다: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +이것은 '엔트리 워크플로우'라는 또 다른 새로운 개념에 대해 알려줍니다. 엔트리 워크플로우는 Nextflow 스크립트를 실행할 때 호출되는 워크플로우입니다. 기본적으로 Nextflow는 이름 없는 워크플로우가 있을 때 이를 엔트리 워크플로우로 사용하며, 지금까지 다음과 같이 시작하는 워크플로우 블록으로 이를 수행해 왔습니다: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +그러나 우리의 인사말 워크플로우에는 이름 없는 워크플로우가 없고, 대신 이름이 있는 워크플로우가 있습니다: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +이것이 Nextflow가 오류를 발생시키고 우리가 원하는 작업을 수행하지 않은 이유입니다. + +워크플로우를 직접 호출할 수 있도록 `take:`/`emit:` 구문을 추가한 것이 아닙니다 - 다른 워크플로우와 구성할 수 있도록 추가한 것입니다. 해결책은 이름이 있는 워크플로우를 가져와서 호출하는 이름 없는 엔트리 워크플로우가 있는 메인 스크립트를 만드는 것입니다. + +### 1.4. 메인 워크플로우 생성 및 테스트 + +이제 `greeting` 워크플로우를 가져와서 사용하는 메인 워크플로우를 만들겠습니다. + +`main.nf`를 생성하십시오: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +이 파일의 워크플로우 엔트리는 이름이 없으며, 이는 엔트리 워크플로우로 사용할 것이기 때문입니다. + +이를 실행하고 출력을 확인하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +작동합니다! 우리는 이름이 있는 인사말 워크플로우를 이름 없는 엔트리 `workflow` 블록이 있는 메인 워크플로우로 적용했습니다. 메인 워크플로우는 `GREETING_WORKFLOW` 워크플로우를 거의 (완전히는 아니지만) 프로세스처럼 사용하고 있으며, `names` 채널을 인수로 전달하고 있습니다. + +### 요점 정리 + +이 섹션에서는 몇 가지 중요한 개념을 학습했습니다: + +- **이름이 있는 워크플로우**: 가져와서 재사용할 수 있는 이름이 있는 워크플로우(`GREETING_WORKFLOW`) 생성하기 +- **워크플로우 인터페이스**: `take:`로 명확한 입력을 정의하고 `emit:`로 출력을 정의하여 구성 가능한 워크플로우 만들기 +- **엔트리 포인트**: Nextflow가 스크립트를 실행하기 위해 이름 없는 엔트리 워크플로우가 필요하다는 것 이해하기 +- **워크플로우 구성**: 다른 워크플로우 내에서 이름이 있는 워크플로우를 가져와서 사용하기 +- **워크플로우 네임스페이스**: `.out` 네임스페이스를 사용하여 워크플로우 출력에 액세스하기 (`GREETING_WORKFLOW.out.greetings`) + +이제 다음과 같은 작동하는 인사말 워크플로우가 있습니다: + +- 이름 채널을 입력으로 받습니다 +- 각 이름을 검증합니다 +- 각 유효한 이름에 대해 인사말을 생성합니다 +- 인사말에 타임스탬프를 추가합니다 +- 원본 및 타임스탬프가 찍힌 인사말을 모두 출력으로 노출합니다 + +이러한 모듈식 접근 방식을 사용하면 인사말 워크플로우를 독립적으로 테스트하거나 더 큰 파이프라인의 구성 요소로 사용할 수 있습니다. + +--- + +## 2. 변환 워크플로우 추가 + +이제 인사말에 텍스트 변환을 적용하는 워크플로우를 만들어 보겠습니다. + +### 2.1. 워크플로우 파일 생성 + +```bash +touch workflows/transform.nf +``` + +### 2.2. 워크플로우 코드 추가 + +다음 코드를 `workflows/transform.nf`에 추가하십시오: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // 메시지가 담긴 입력 채널 + + main: + // 순차적으로 변환 적용 + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // 대문자 인사말 + reversed = reversed_ch // 역순으로 된 대문자 인사말 +} +``` + +여기서는 구성 가능한 구문에 대한 설명을 반복하지 않겠지만, 이름이 있는 워크플로우가 다시 `take:` 및 `emit:` 블록으로 선언되었고, 워크플로우 내용이 `main:` 블록 내부에 배치되었음을 주목하십시오. + +### 2.3. 메인 워크플로우 업데이트 + +두 워크플로우를 모두 사용하도록 `main.nf`를 업데이트하십시오: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // 인사말 워크플로우 실행 + GREETING_WORKFLOW(names) + + // 변환 워크플로우 실행 + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // 결과 보기 + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +완전한 파이프라인을 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +역순으로 된 파일 중 하나를 살펴보면, 대문자 버전의 인사말이 역순으로 되어 있는 것을 볼 수 있습니다: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="역순으로 된 파일 내용" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### 요점 정리 + +이제 다음을 수행하는 완전한 파이프라인이 있어야 합니다: + +- 인사말 워크플로우를 통해 이름을 처리합니다 +- 타임스탬프가 찍힌 인사말을 변환 워크플로우에 전달합니다 +- 인사말의 대문자 버전과 역순 버전을 모두 생성합니다 + +--- + +## 요약 + +이 사이드 퀘스트에서는 작고 재사용 가능한 구성 요소로부터 복잡한 파이프라인을 구축할 수 있게 해주는 Nextflow의 강력한 워크플로우 구성 개념을 살펴보았습니다. + +이러한 모듈식 접근 방식은 모놀리식 파이프라인에 비해 여러 가지 이점을 제공합니다: + +- 각 워크플로우를 독립적으로 개발, 테스트 및 디버그할 수 있습니다 +- 워크플로우를 다양한 파이프라인에서 재사용할 수 있습니다 +- 전체 파이프라인 구조가 더 읽기 쉽고 유지 관리하기 쉬워집니다 +- 인터페이스가 일관성을 유지하는 한 한 워크플로우의 변경이 다른 워크플로우에 반드시 영향을 미치지 않습니다 +- 필요에 따라 파이프라인의 다른 부분을 실행하도록 엔트리 포인트를 구성할 수 있습니다 + +_그러나 워크플로우를 호출하는 것이 프로세스를 호출하는 것과 약간 비슷하지만, 실제로는 같은 것이 아니라는 점에 유의하는 것이 중요합니다. 예를 들어, 크기 N의 채널로 워크플로우를 호출하여 워크플로우를 N번 실행할 수 없습니다 - 크기 N의 채널을 워크플로우에 전달하고 내부적으로 반복해야 합니다._ + +이러한 기술을 자신의 작업에 적용하면 유지 관리가 가능하고 확장 가능한 상태를 유지하면서 복잡한 생물정보학 작업을 처리할 수 있는 더 정교한 Nextflow 파이프라인을 구축할 수 있습니다. + +### 주요 패턴 + +1. **워크플로우 구조**: `take:` 및 `emit:` 구문을 사용하여 각 워크플로우에 대해 명확한 입력과 출력을 정의하여 구성 요소 간에 잘 정의된 인터페이스를 생성하고, `main:` 블록 내에 워크플로우 로직을 적용했습니다. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // 입력 채널이 여기에 선언됩니다 + input_ch + + main: + // 워크플로우 로직이 여기에 들어갑니다 + // 프로세스가 호출되고 채널이 조작되는 곳입니다 + result_ch = SOME_PROCESS(input_ch) + + emit: + // 출력 채널이 여기에 선언됩니다 + output_ch = result_ch + } + ``` + +2. **워크플로우 가져오기:** 두 개의 독립적인 워크플로우 모듈을 만들고 include 문으로 메인 파이프라인에 가져왔습니다. + + - 단일 워크플로우 가져오기 + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - 여러 워크플로우 가져오기 + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - 이름 충돌을 피하기 위해 별칭과 함께 가져오기 + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **엔트리 포인트**: Nextflow는 실행을 시작할 위치를 알기 위해 이름 없는 엔트리 워크플로우가 필요합니다. 이 엔트리 워크플로우는 이름이 있는 워크플로우를 호출합니다. + + - 이름 없는 워크플로우 (엔트리 포인트) + + ```groovy + workflow { + // 스크립트를 실행할 때의 엔트리 포인트입니다 + NAMED_WORKFLOW(input_ch) + } + ``` + + - 이름이 있는 워크플로우 (엔트리 워크플로우에서 호출됨) + + ```groovy + workflow NAMED_WORKFLOW { + // 엔트리 워크플로우에서 호출되어야 합니다 + } + ``` + +4. **데이터 흐름 관리:** 네임스페이스 표기법(`WORKFLOW_NAME.out.channel_name`)을 사용하여 워크플로우 출력에 액세스하고 이를 다른 워크플로우에 전달하는 방법을 학습했습니다. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### 추가 자료 + +- [Nextflow Workflow 문서](https://www.nextflow.io/docs/latest/workflow.html) +- [Channel Operators 참조](https://www.nextflow.io/docs/latest/operator.html) +- [Error Strategy 문서](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## 다음 단계는? + +[사이드 퀘스트 메뉴](./index.md)로 돌아가거나 페이지 오른쪽 하단의 버튼을 클릭하여 목록의 다음 주제로 이동하십시오. diff --git a/docs/ko/docs/side_quests/working_with_files.md b/docs/ko/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..7cf3148f6c --- /dev/null +++ b/docs/ko/docs/side_quests/working_with_files.md @@ -0,0 +1,1029 @@ +# 파일 입력 처리 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +과학 분석 워크플로우는 종종 대량의 파일 처리를 포함합니다. +Nextflow는 파일을 효율적으로 처리할 수 있는 강력한 도구를 제공하여, 최소한의 코드로 데이터를 구성하고 처리할 수 있도록 돕습니다. + +### 학습 목표 + +이 사이드 퀘스트에서는 기본 파일 작업부터 파일 컬렉션 작업을 위한 고급 기술까지 Nextflow가 파일을 처리하는 방법을 살펴봅니다. +과학 분석 파이프라인에서 일반적으로 요구되는 파일 이름에서 메타데이터를 추출하는 방법을 배우게 됩니다. + +이 사이드 퀘스트를 마치면 다음을 수행할 수 있습니다: + +- Nextflow의 `file()` 메서드를 사용하여 파일 경로 문자열에서 Path 객체 생성하기 +- 이름, 확장자, 상위 디렉토리와 같은 파일 속성에 접근하기 +- URI를 사용하여 로컬 파일과 원격 파일을 투명하게 처리하기 +- `channel.fromPath()` 및 `channel.fromFilePairs()`를 사용하여 채널로 파일 처리 자동화하기 +- 문자열 조작을 사용하여 파일 이름에서 메타데이터 추출 및 구조화하기 +- 패턴 매칭과 glob 표현식을 사용하여 관련 파일 그룹화하기 +- 적절한 입력 처리로 파일 작업을 Nextflow process에 통합하기 +- 메타데이터 기반 디렉토리 구조를 사용하여 process 출력 구성하기 + +이러한 기술은 다양한 종류의 파일 입력을 뛰어난 유연성으로 처리할 수 있는 워크플로우를 구축하는 데 도움이 됩니다. + +### 사전 요구 사항 + +이 사이드 퀘스트를 시작하기 전에 다음을 완료해야 합니다: + +- [Hello Nextflow](../../hello_nextflow/) 튜토리얼 또는 이에 상응하는 초급 과정을 완료했어야 합니다. +- 기본 Nextflow 개념과 메커니즘(process, channel, operator)을 편안하게 사용할 수 있어야 합니다. + +--- + +## 0. 시작하기 + +#### 교육 코드스페이스 열기 + +아직 수행하지 않았다면, [환경 설정](../envsetup/index.md)에 설명된 대로 교육 환경을 열어야 합니다. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### 프로젝트 디렉토리로 이동 + +이 튜토리얼의 파일이 있는 디렉토리로 이동하겠습니다. + +```bash +cd side-quests/working_with_files +``` + +VSCode가 이 디렉토리에 집중하도록 설정할 수 있습니다: + +```bash +code . +``` + +#### 자료 검토 + +`main.nf`라는 간단한 워크플로우 파일, 두 개의 모듈 파일이 포함된 `modules` 디렉토리, 그리고 일부 예제 데이터 파일이 포함된 `data` 디렉토리를 찾을 수 있습니다. + +??? abstract "디렉토리 내용" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +이 디렉토리에는 세 명의 환자(A, B, C)로부터 얻은 페어드 엔드 시퀀싱 데이터가 포함되어 있습니다. + +각 환자에 대해 `tumor`(일반적으로 종양 생검에서 유래) 또는 `normal`(건강한 조직이나 혈액에서 채취) 타입의 샘플이 있습니다. +암 분석에 익숙하지 않다면, 이것이 대조 분석을 수행하기 위해 페어드 tumor/normal 샘플을 사용하는 실험 모델에 해당한다는 것만 알아두시면 됩니다. + +특히 환자 A의 경우, 두 세트의 기술적 복제(반복)가 있습니다. + +시퀀싱 데이터 파일은 '정방향 리드'와 '역방향 리드'로 알려진 것에 대한 일반적인 `_R1_` 및 `_R2_` 규칙으로 명명되어 있습니다. + +_이 실험 설계에 익숙하지 않더라도 걱정하지 마십시오. 이 튜토리얼을 이해하는 데 중요하지 않습니다._ + +#### 과제 검토 + +여러분의 과제는 다음을 수행하는 Nextflow 워크플로우를 작성하는 것입니다: + +1. Nextflow의 파일 처리 메서드를 사용하여 입력 파일 **로드** +2. 파일 이름 구조에서 메타데이터(환자 ID, 복제, 샘플 타입) **추출** +3. `channel.fromFilePairs()`를 사용하여 페어드 파일(R1/R2) **그룹화** +4. 제공된 분석 모듈로 파일 **처리** +5. 추출된 메타데이터를 기반으로 디렉토리 구조로 출력 **구성** + +#### 준비 체크리스트 + +준비가 되었다고 생각하십니까? + +- [ ] 이 과정의 목표와 사전 요구 사항을 이해합니다 +- [ ] 코드스페이스가 실행 중입니다 +- [ ] 작업 디렉토리를 적절하게 설정했습니다 +- [ ] 과제를 이해합니다 + +모든 항목을 체크할 수 있다면 시작할 준비가 된 것입니다. + +--- + +## 1. 기본 파일 작업 + +### 1.1. `.class`로 객체의 타입 식별 + +워크플로우 파일 `main.nf`를 살펴보십시오: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // 문자열 경로에서 Path 객체 생성 + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +이것은 워크플로우에서 단일 파일 경로를 참조한 다음, 해당 클래스와 함께 콘솔에 출력하는 미니 워크플로우(process 없이)입니다. + +??? info "`.class`란 무엇입니까?" + + Nextflow에서 `.class`는 우리가 다루고 있는 객체의 타입을 알려줍니다. 이것은 문자열인지, 숫자인지, 파일인지, 아니면 다른 것인지 알아보기 위해 "이것이 무엇인가요?"라고 묻는 것과 같습니다. + 이것은 다음 섹션에서 일반 문자열과 Path 객체의 차이를 설명하는 데 도움이 됩니다. + +워크플로우를 실행해 보겠습니다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +보시다시피, Nextflow는 우리가 작성한 대로 문자열 경로를 정확히 출력했습니다. + +이것은 단지 텍스트 출력입니다. Nextflow는 아직 이것으로 특별한 작업을 수행하지 않았습니다. +또한 Nextflow에 관한 한 이것은 문자열(`java.lang.String` 클래스)일 뿐이라는 것을 확인했습니다. +이것은 이해가 됩니다. 우리는 아직 Nextflow에게 이것이 파일에 해당한다고 말하지 않았기 때문입니다. + +### 1.2. file()로 Path 객체 생성 + +경로 문자열에서 [Path 객체](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path)를 생성하여 Nextflow에게 파일을 처리하는 방법을 알려줄 수 있습니다. + +워크플로우에서 `file()` 메서드를 사용하여 문자열 경로 `data/patientA_rep1_normal_R1_001.fastq.gz`를 Path 객체로 변환할 수 있으며, 이는 파일 속성 및 작업에 대한 접근을 제공합니다. + +`main.nf`를 다음과 같이 편집하여 문자열을 `file()`로 감싸십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // 문자열 경로에서 Path 객체 생성 + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +이제 워크플로우를 다시 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +이번에는 입력으로 제공한 상대 경로 대신 전체 절대 경로를 볼 수 있습니다. + +Nextflow는 우리의 문자열을 Path 객체로 변환하고 시스템의 실제 파일 위치로 확인했습니다. +파일 경로는 이제 `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`와 같이 절대 경로가 됩니다. + +또한 Path 객체 클래스가 `sun.nio.fs.UnixPath`임을 주목하십시오. 이것은 Nextflow가 로컬 파일을 표현하는 방식입니다. +나중에 보겠지만, 원격 파일은 다른 클래스 이름(예: HTTP 파일의 경우 `nextflow.file.http.XPath`)을 가지지만, 모두 정확히 동일한 방식으로 작동하며 워크플로우에서 동일하게 사용할 수 있습니다. + +!!! tip + + **주요 차이점:** + + - **경로 문자열**: Nextflow가 문자로 처리하는 텍스트일 뿐입니다 + - **Path 객체**: Nextflow가 작업할 수 있는 스마트 파일 참조입니다 + + 이렇게 생각하십시오: 경로 문자열은 종이에 주소를 쓰는 것과 같고, Path 객체는 해당 위치로 이동하는 방법을 알고 여정에 대한 세부 정보를 알려줄 수 있는 GPS 장치에 주소를 로드한 것과 같습니다. + +### 1.3. 파일 속성 접근 + +이것이 왜 유용할까요? 이제 Nextflow가 `myFile`이 단순한 문자열이 아니라 Path 객체라는 것을 이해하므로, Path 객체의 다양한 속성에 접근할 수 있습니다. + +워크플로우를 업데이트하여 내장 파일 속성을 출력해 봅시다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +워크플로우를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +위 콘솔에 출력된 다양한 파일 속성을 볼 수 있습니다. + +### 1.4. process에 파일 제공 + +문자열과 Path 객체의 차이는 process를 사용하여 실제 워크플로우를 구축하기 시작할 때 중요해집니다. +지금까지 Nextflow가 입력 파일을 파일로 처리하고 있다는 것을 확인했지만, process에서 실제로 해당 파일에 대해 무언가를 실행할 수 있는지 살펴봅시다. + +#### 1.4.1. process 가져오기 및 코드 검토 + +파일 입력을 받아 포함된 줄 수를 세는 `COUNT_LINES`라는 미리 작성된 process 모듈을 제공합니다. + +워크플로우에서 process를 사용하려면 workflow 블록 앞에 include 문을 추가하기만 하면 됩니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +모듈 파일을 열어 코드를 검토할 수 있습니다: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +보시다시피, 파일의 압축을 풀고 포함된 줄 수를 세는 상당히 간단한 작은 스크립트입니다. + +??? info "`debug true`는 무엇을 합니까?" + + process 정의의 `debug true` 지시문은 Nextflow가 스크립트의 출력(줄 수 "40"과 같은)을 실행 로그에 직접 출력하도록 합니다. + 이것이 없으면 process 실행 상태만 볼 수 있고 스크립트의 실제 출력은 볼 수 없습니다. + + Nextflow process 디버깅에 대한 자세한 내용은 [Debugging Nextflow Workflows](debugging.md) 사이드 퀘스트를 참조하십시오. + +#### 1.4.2. `COUNT_LINES` 호출 추가 + +이제 process를 워크플로우에서 사용할 수 있으므로, 입력 파일에서 실행하기 위해 `COUNT_LINES` process에 대한 호출을 추가할 수 있습니다. + +워크플로우를 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // 파일의 줄 수 계산 + COUNT_LINES(myFile) + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +이제 워크플로우를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +이것은 process 내부에서 파일을 적절하게 조작할 수 있음을 보여줍니다. + +구체적으로, Nextflow는 다음 작업을 성공적으로 수행했습니다: + +- 작업 디렉토리에 파일 스테이징 +- .gz 파일 압축 해제 +- 줄 수 세기(이 경우 40줄) +- 오류 없이 완료 + +이 원활한 작업의 핵심은 Nextflow에게 입력이 파일이며 그렇게 처리되어야 함을 명시적으로 알려주는 것입니다. + +### 1.5. 기본 파일 입력 오류 문제 해결 + +이것은 종종 Nextflow 초보자를 당황하게 하므로, 잘못 수행했을 때 어떤 일이 발생하는지 몇 분 동안 살펴보겠습니다. + +파일 처리를 잘못할 수 있는 주요 위치가 두 곳 있습니다: 워크플로우 수준과 process 수준입니다. + +#### 1.5.1. 워크플로우 수준 오류 + +workflow 블록에서 입력을 지정할 때 파일을 문자열로 처리하도록 되돌리면 어떤 일이 발생하는지 살펴봅시다. + +워크플로우를 다음과 같이 편집하고, 경로 관련 print 문은 주석 처리하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // 문자열 경로에서 Path 객체 생성 + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // 파일의 줄 수 계산 + COUNT_LINES(myFile) + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // 파일의 줄 수 계산 + COUNT_LINES(myFile) + ``` + +이제 워크플로우를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +중요한 부분은 다음과 같습니다: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +`path` 입력을 지정하면 Nextflow는 단순한 문자열이 아닌 실제 파일 참조를 전달하는지 확인합니다. +이 오류는 `'data/patientA_rep1_normal_R1_001.fastq.gz'`가 Path 객체가 아니라 문자열이기 때문에 유효한 경로 값이 아니라고 알려줍니다. + +Nextflow는 즉시 문제를 감지하고 process를 시작하기 전에 중지했습니다. + +#### 1.5.2. Process 수준 오류 + +입력을 파일로 처리하도록 Nextflow에게 지정하는 것을 잊을 수 있는 다른 위치는 process 정의입니다. + +!!! warning "1.5.1의 워크플로우 오류 유지" + + 이 테스트가 올바르게 작동하려면 워크플로우를 손상된 상태로 유지하십시오(`file()` 대신 일반 문자열 사용). + process에서 `val`과 결합하면 아래에 표시된 오류가 발생합니다. + +모듈을 다음과 같이 편집하십시오: + +=== "수정 후" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "수정 전" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +이제 워크플로우를 다시 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? failure "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +이것은 위에서 언급한 대로 process가 디버깅 정보를 출력하도록 설정되어 있기 때문에 오류에 대한 많은 세부 정보를 보여줍니다. + +가장 관련성이 높은 섹션은 다음과 같습니다: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +시스템이 파일을 찾을 수 없다고 말합니다. 그러나 경로를 찾아보면 해당 위치에 그 이름의 파일이 있습니다. + +이것을 실행했을 때, Nextflow는 문자열 값을 스크립트로 전달했지만 작업 디렉토리에 실제 파일을 *스테이징*하지 않았습니다. +따라서 process는 상대 문자열 `data/patientA_rep1_normal_R1_001.fastq.gz`를 사용하려고 했지만, 해당 파일은 process 작업 디렉토리 내에 존재하지 않습니다. + +이 두 예제를 종합하면, 입력을 파일로 처리해야 한다고 Nextflow에게 알려주는 것이 얼마나 중요한지 알 수 있습니다. + +!!! note + + 다음 섹션으로 계속하기 전에 두 의도적 오류를 모두 수정하십시오. + +### 요점 정리 + +- 경로 문자열 vs Path 객체: 문자열은 단순한 텍스트이고, Path 객체는 스마트 파일 참조입니다 +- `file()` 메서드는 문자열 경로를 Nextflow가 작업할 수 있는 Path 객체로 변환합니다 +- `name`, `simpleName`, `extension`, `parent`와 같은 파일 속성에 [파일 속성을 사용하여](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) 접근할 수 있습니다 +- 문자열 대신 Path 객체를 사용하면 Nextflow가 워크플로우에서 파일을 적절하게 관리할 수 있습니다 +- Process 입력 결과: 적절한 파일 처리는 파일이 올바르게 스테이징되고 process에서 사용할 수 있도록 문자열이 아닌 Path 객체가 필요합니다 + +--- + +## 2. 원격 파일 사용 + +Nextflow의 주요 기능 중 하나는 로컬 파일(동일한 머신에 있는)에서 인터넷을 통해 접근할 수 있는 원격 파일로 원활하게 전환할 수 있다는 것입니다. + +올바르게 수행하면 다른 위치에서 오는 파일을 수용하기 위해 워크플로우의 로직을 변경할 필요가 없어야 합니다. +원격 파일을 사용하기 위해 해야 할 일은 워크플로우에 파일을 제공할 때 파일 경로에 적절한 접두사를 지정하는 것뿐입니다. + +예를 들어, `/path/to/data`에는 접두사가 없어 '일반' 로컬 파일 경로임을 나타내는 반면, `s3://path/to/data`에는 Amazon의 S3 객체 스토리지에 위치함을 나타내는 `s3://` 접두사가 포함되어 있습니다. + +다양한 프로토콜이 지원됩니다: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +이들 중 하나를 사용하려면 문자열에 관련 접두사를 지정하기만 하면 되며, 이는 기술적으로 파일 경로 대신 URI(Uniform Resource Identifier)라고 불립니다. +Nextflow는 인증 및 파일을 적절한 위치로 스테이징, 다운로드 또는 업로드 및 예상되는 모든 다른 파일 작업을 처리합니다. + +이 시스템의 주요 강점은 환경 간 전환 시 파이프라인 로직을 변경하지 않고도 가능하다는 것입니다. +예를 들어, URI만 변경하여 작고 로컬인 테스트 세트로 개발한 후 원격 스토리지에 있는 전체 규모 테스트 세트로 전환할 수 있습니다. + +### 2.1. 인터넷의 파일 사용 + +워크플로우에 제공하는 로컬 경로를 Github에 저장된 동일한 데이터의 사본을 가리키는 HTTPS 경로로 전환하여 이것을 테스트해 봅시다. + +!!! warning + + 이것은 활성 인터넷 연결이 있는 경우에만 작동합니다. + +`main.nf`를 다시 열고 다음과 같이 입력 경로를 변경하십시오: + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // 인터넷에서 원격 파일 사용 + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +워크플로우를 실행해 봅시다: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +작동합니다! 콘솔 출력에서 변경된 것이 거의 없음을 볼 수 있습니다. + +콘솔 출력의 한 가지 차이점은 경로 객체 클래스가 이제 `nextflow.file.http.XPath`인 반면 로컬 경로의 경우 클래스는 `sun.nio.fs.UnixPath`였다는 것입니다. +이러한 클래스를 기억할 필요는 없습니다. Nextflow가 다른 위치를 적절하게 식별하고 처리한다는 것을 보여주기 위해 언급하는 것입니다. + +백그라운드에서 Nextflow는 work 디렉토리 내에 있는 스테이징 디렉토리로 파일을 다운로드했습니다. +그런 다음 스테이징된 파일은 로컬 파일로 처리되어 관련 process 디렉토리에 심볼릭 링크될 수 있습니다. + +process의 해시 값에 있는 작업 디렉토리의 내용을 살펴보면 이것이 발생했음을 확인할 수 있습니다. + +??? abstract "작업 디렉토리 내용" + + process 해시가 `8a/2ab7ca`인 경우 작업 디렉토리를 탐색할 수 있습니다: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + 심볼릭 링크는 Nextflow가 자동으로 다운로드한 원격 파일의 스테이징된 사본을 가리킵니다. + +더 큰 파일의 경우 다운로드 단계가 로컬 파일에서 실행하는 것에 비해 추가 시간이 걸립니다. +그러나 Nextflow는 불필요한 다운로드를 피하기 위해 이미 스테이징된 사본이 있는지 확인합니다. +따라서 동일한 파일에서 다시 실행하고 스테이징된 파일을 삭제하지 않았다면 Nextflow는 스테이징된 사본을 사용합니다. + +이것은 Nextflow를 사용하여 로컬 및 원격 데이터 간을 전환하는 것이 얼마나 쉬운지 보여주며, 이것이 Nextflow의 주요 기능입니다. + +!!! note + + 이 원칙에 대한 한 가지 중요한 예외는 HTTPS가 여러 파일을 나열할 수 없기 때문에 HTTPS에서 glob 패턴이나 디렉토리 경로를 사용할 수 없다는 것입니다. 따라서 정확한 파일 URL을 지정해야 합니다. + 그러나 blob 스토리지(`s3://`, `az://`, `gs://`)와 같은 다른 스토리지 프로토콜은 glob과 디렉토리 경로를 모두 사용할 수 있습니다. + + 클라우드 스토리지에서 glob 패턴을 사용하는 방법은 다음과 같습니다: + + ```groovy title="클라우드 스토리지 예제 (이 환경에서 실행 불가)" + // glob 패턴을 사용한 S3 - 여러 파일과 일치 + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // glob 패턴을 사용한 Azure Blob Storage + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // glob 패턴을 사용한 Google Cloud Storage + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + 다음 섹션에서 glob를 실제로 사용하는 방법을 보여드리겠습니다. + +### 2.2. 로컬 파일로 다시 전환 + +이 사이드 퀘스트의 나머지 부분에서는 로컬 예제 파일을 사용할 것이므로 워크플로우 입력을 원래 파일로 다시 전환하겠습니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // 문자열 경로에서 Path 객체 생성 + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### 요점 정리 + +- 원격 데이터는 URI를 사용하여 접근합니다(HTTP, FTP, S3, Azure, Google Cloud) +- 이러한 경로를 process에 제공하는 한 Nextflow는 자동으로 데이터를 다운로드하고 적절한 위치로 스테이징합니다 +- 원격 파일을 다운로드하거나 업로드하는 로직을 작성하지 마십시오! +- 로컬 및 원격 파일은 다른 객체 타입을 생성하지만 동일하게 작동합니다 +- **중요**: HTTP/HTTPS는 단일 파일에서만 작동합니다(glob 패턴 없음) +- 클라우드 스토리지(S3, Azure, GCS)는 단일 파일과 glob 패턴을 모두 지원합니다 +- 프로토콜이 필요한 작업을 지원하는 한 코드 로직을 변경하지 않고 로컬 및 원격 데이터 소스 간을 원활하게 전환할 수 있습니다 + +--- + +## 3. `fromPath()` 채널 팩토리 사용 + +지금까지 우리는 한 번에 하나의 파일로 작업했지만, Nextflow에서는 일반적으로 처리할 여러 입력 파일이 있는 입력 채널을 생성하려고 합니다. + +이를 수행하는 단순한 방법은 `file()` 메서드를 다음과 같이 [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of)와 결합하는 것입니다: + +```groovy title="구문 예제" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +이것은 작동하지만 투박합니다. + +!!! tip "`file()` vs `channel.fromPath()`를 사용할 때" + + - 단일 Path 객체를 직접 조작해야 할 때(파일이 존재하는지 확인, 속성 읽기 또는 단일 process 호출로 전달) `file()`을 사용하십시오 + - 여러 파일을 보유할 수 있는 채널이 필요할 때, 특히 glob 패턴을 사용하거나 파일이 여러 process를 통해 흐를 때 `channel.fromPath()`를 사용하십시오 + +여기서 [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath)가 등장합니다: 하나 이상의 정적 파일 문자열뿐만 아니라 glob 패턴에서 채널을 생성하는 데 필요한 모든 기능을 번들로 제공하는 편리한 채널 팩토리입니다. + +### 3.1. 채널 팩토리 추가 + +`channel.fromPath`를 사용하도록 워크플로우를 업데이트해 봅시다. + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // channel.fromPath로 파일 로드 + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // 파일 속성 출력 + /* Comment these out for now, we'll come back to them! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // 파일의 줄 수 계산 + // COUNT_LINES(myFile) + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // 문자열 경로에서 Path 객체 생성 + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // 파일 속성 출력 + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // 파일의 줄 수 계산 + COUNT_LINES(myFile) + ``` + +또한 지금은 속성을 출력하는 코드를 주석 처리했으며 대신 파일 이름만 출력하는 `.view` 문을 추가했습니다. + +워크플로우를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +보시다시피, 파일 경로가 채널에 `Path` 타입 객체로 로드되고 있습니다. +이것은 `file()`이 했을 것과 유사하지만, 이제 원한다면 더 많은 파일을 로드할 수 있는 채널이 있습니다. + +`channel.fromPath()`를 사용하는 것은 파일 목록으로 채워진 새 채널을 생성하는 편리한 방법입니다. + +### 3.2. 채널의 파일 속성 보기 + +채널 팩토리를 사용한 첫 번째 시도에서는 코드를 단순화하고 파일 이름만 출력했습니다. + +전체 파일 속성을 출력하는 것으로 돌아가 봅시다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // channel.fromPath로 파일 로드 + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // 파일의 줄 수 계산 + COUNT_LINES(ch_files) + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // channel.fromPath로 파일 로드 + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // 파일의 줄 수 계산 + // COUNT_LINES(ch_files) + ``` + +또한 채널 기반 접근 방식으로 파일 처리가 여전히 올바르게 작동하는지 확인하기 위해 `COUNT_LINES` process 호출을 다시 활성화하고 있습니다. + +워크플로우를 실행하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +이제 파일이 채널에 있으므로 이전과 동일한 결과를 얻었으며, 더 많이 추가할 수 있습니다. + +### 3.3. glob을 사용하여 여러 파일 매칭 + +채널에 더 많은 파일을 로드할 수 있는 여러 방법이 있습니다. +여기서는 와일드카드 문자를 기반으로 파일 및 디렉토리 이름을 매칭하고 검색하는 편리한 방법인 glob 패턴을 사용하는 방법을 보여드리겠습니다. +이러한 패턴을 매칭하는 프로세스를 "globbing" 또는 "filename expansion"이라고 합니다. + +!!! note + + 이전에 언급했듯이, HTTPS가 여러 파일을 나열할 수 없기 때문에 HTTPS 파일 경로를 제외한 대부분의 경우 Nextflow는 입력 및 출력 파일을 관리하기 위한 globbing을 지원합니다. + +특정 환자 `patientA`와 관련된 파일 쌍의 두 파일을 모두 검색하고 싶다고 가정해 봅시다: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +파일 이름 간의 유일한 차이점은 복제 번호, 즉 `R` 뒤의 숫자이므로 다음과 같이 와일드카드 문자 `*`를 사용하여 숫자를 대신할 수 있습니다: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +이것이 우리에게 필요한 glob 패턴입니다. + +이제 채널 팩토리의 파일 경로를 다음과 같이 해당 glob 패턴을 사용하도록 업데이트하기만 하면 됩니다: + +=== "수정 후" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath로 파일 로드 + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "수정 전" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath로 파일 로드 + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow는 이것이 glob 패턴임을 자동으로 인식하고 적절하게 처리합니다. + +워크플로우를 실행하여 테스트하십시오: + +```bash +nextflow run main.nf +``` + +??? success "명령 출력" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +보시다시피, 이제 채널에 두 개의 Path 객체가 있으며, 이는 Nextflow가 파일 이름 확장을 올바르게 수행했고 예상대로 두 파일을 모두 로드하고 처리했음을 보여줍니다. + +이 방법을 사용하면 glob 패턴을 변경하기만 하면 원하는 만큼 많은 파일을 검색할 수 있습니다. 예를 들어 파일 이름의 모든 가변 부분을 `*`로 바꾸어 더 관대하게 만들면(_예:_ `data/patient*_rep*_*_R*_001.fastq.gz`) `data` 디렉토리의 모든 예제 파일을 가져올 수 있습니다. + +### 요점 정리 + +- `channel.fromPath()`는 패턴과 매칭하는 파일로 채널을 생성합니다 +- 각 파일은 채널의 별도 요소로 방출됩니다 +- glob 패턴을 사용하여 여러 파일을 매칭할 수 있습니다 +- 파일은 전체 속성을 가진 Path 객체로 자동 변환됩니다 +- `.view()` 메서드를 사용하면 채널 내용을 검사할 수 있습니다 + +--- + +## 4. 파일 이름에서 기본 메타데이터 추출 + +대부분의 과학 분야에서 데이터를 포함하는 파일 이름 diff --git a/docs/ko/docs/training_collections/architects_toolkit_1.md b/docs/ko/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..dd7db466f0 --- /dev/null +++ b/docs/ko/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,63 @@ +```yaml +--- +title: 아키텍트 툴킷 I +hide: + - toc +--- + +# 아키텍트 툴킷 I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +트레이닝 컬렉션은 고급 교육 자료([Side Quests](../../side_quests)라고 함)를 통한 선별된 학습 경로를 제공합니다. 이 컬렉션은 견고하고 확장 가능한 workflow를 구축하기 위해 자주 함께 사용되는 네 가지 필수 주제를 다룹니다. + +## 학습 목표 + +이 컬렉션을 완료하면 다음에 대한 경험을 얻게 됩니다: + +- **복잡한 모듈식 workflow 아키텍처** - 여러 workflow를 응집력 있는 pipeline으로 결합하기 +- **포괄적인 테스트 전략** - workflow의 신뢰성과 유지 관리 가능성 보장하기 +- **메타데이터 관리** - workflow 전반에 걸쳐 샘플별 메타데이터를 효과적으로 처리하기 +- **고급 데이터 처리** - 효율적인 데이터 분할 및 그룹화 패턴 구현하기 + +이러한 기술을 통해 실제 애플리케이션을 위한 견고하고 확장 가능하며 유지 관리 가능한 Nextflow workflow를 구축할 수 있습니다. + +## 대상 및 사전 요구 사항 + +이 컬렉션은 기본 Nextflow 교육을 완료하고 고급 workflow 패턴, 테스트 전략, 데이터 및 메타데이터 처리 기법에 대해 더 깊이 배우고자 하는 사용자를 위해 설계되었습니다. + +**사전 요구 사항** + +- [Hello Nextflow](../../hello_nextflow/) 교육 완료 또는 이에 상응하는 경험 +- Nextflow 구문 및 개념에 대한 기본적인 이해 +- 기본 workflow 개발 패턴에 대한 이해 +- 명령줄 도구 사용 경험 + +## 컬렉션 내용 + +이 컬렉션은 상호 보완적인 workflow 엔지니어링 주제를 다루는 네 개의 Side Quest로 구성됩니다: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - 복잡한 workflow 아키텍처 및 구성 +2. **[Testing with nf-test](../../side_quests/nf-test)** - Nextflow workflow를 위한 테스트 전략 +3. **[Metadata](../../side_quests/metadata)** - Nextflow channel의 항목에 대한 메타데이터 처리 +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - 고급 데이터 처리 패턴 + +각 Side Quest는 독립적인 개념을 다루는 자체 완결형이지만, 주제에 대한 논리적 진행을 위해 위에 나열된 순서대로 완료하는 것을 권장합니다. + +## 이 컬렉션 사용 방법 + +먼저, 아래의 "Open in GitHub Codespaces" 버튼을 Command+클릭하여 별도 탭에서 교육 환경을 실행한 다음, 로딩되는 동안 계속 읽어주십시오. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +환경이 실행되면 다음과 같이 컬렉션을 진행하십시오: + +1. 이 탭에서: 위에 나열된 첫 번째 Side Quest로 이동하여 단계별 개발 연습을 확인합니다. +2. Codespaces 탭에서: Side Quest의 연습을 진행합니다. +3. Side Quest를 완료하면 이 페이지로 돌아와 위 목록의 다음 항목으로 이동합니다. +4. 컬렉션을 모두 완료하면 아래 버튼을 클릭하여 매우 짧은 설문조사를 작성해 주십시오. 여러분의 피드백은 모든 사람을 위한 교육 자료를 지속적으로 개선하는 데 도움이 됩니다. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +시작할 준비가 되셨나요? 위의 첫 번째 모듈부터 시작하십시오! +``` diff --git a/docs/ko/docs/training_collections/index.md b/docs/ko/docs/training_collections/index.md new file mode 100644 index 0000000000..574d0b473f --- /dev/null +++ b/docs/ko/docs/training_collections/index.md @@ -0,0 +1,29 @@ +--- +title: 교육 컬렉션 +hide: + - toc +--- + +# 교육 컬렉션 + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } AI 지원 번역 - [자세히 알아보기 및 개선 제안](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +이 섹션에는 특정 주제나 사용 사례를 중심으로 포괄적인 학습 경험을 제공하는 것을 목표로 하는 [Side Quests](../side_quests/index.md)라는 교육 모듈의 큐레이션된 컬렉션이 포함되어 있습니다. + +## 전제 조건 + +각 컬렉션에는 인덱스 페이지에 문서화된 특정 전제 조건이 있습니다. 그러나 대부분의 컬렉션은 다음을 가정합니다: + +- 명령줄 사용 경험 +- [Hello Nextflow](../../hello_nextflow/) 초급 교육 과정에서 다루는 기본적인 Nextflow 개념 및 도구 + +기술적 요구 사항 및 환경 설정에 대해서는 [Environment Setup](../../envsetup/) 단기 과정을 참조하십시오. + +## 사용 가능한 컬렉션 + +- [The Architect's Toolkit I](./architects_toolkit_1.md) - 복잡한 파이프라인 조립, 테스트 전략 구현, 메타데이터 관리, 데이터 그룹화 및 분할을 위한 워크플로우 아키텍처 패턴을 다루는 네 가지 Side Quest 컬렉션입니다. _예상 소요 시간: 그룹 교육 기준 4시간._ + +## 새로운 컬렉션 제안하기 + +저희는 추가 Side Quest 및 컬렉션 개발을 적극적으로 진행하고 있습니다. +컬렉션에서 다루는 것이 적절하다고 생각하시는 주제를 커뮤니티 포럼의 [Training 섹션](https://community.seqera.io/c/training/)에 게시하여 제안해 주시기 바랍니다. diff --git a/docs/ko/llm-prompt.md b/docs/ko/llm-prompt.md new file mode 100644 index 0000000000..8b5aa9bfe2 --- /dev/null +++ b/docs/ko/llm-prompt.md @@ -0,0 +1,190 @@ +# Translation Rules for Korean + +The target language for this translation is **Korean** (`ko`). + +## 1. Grammar & Tone + +- Use formal polite speech level (합쇼체/하십시오체) +- Sentence endings: "~입니다", "~습니다", "~하세요", "~수 있습니다" +- Maintain consistent honorific usage throughout +- Follow standard Korean spelling conventions (한글 맞춤법) +- Preserve personality and humor where present (e.g., "그동안 차 한 잔을 준비하거나" for suggesting a tea break) + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Korean (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "입력 채널이 파일을 받습니다..." (translate "channel" to "채널") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// 인사말을 내보냅니다` + +## 3. Code Comments + +**Always translate code comments to Korean.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Korean translation +params.greeting = "Hello" // 기본 인사말 설정 +``` + +## 4. English Terms with Korean Particles + +Korean uses particles attached to words. When English terms appear in Korean text, attach Korean particles directly: + +- "README.md 파일" (README.md file) +- "VSCode IDE에서" (in VSCode IDE) +- "Docker를" (Docker + object marker) + +## 5. UI Element Pattern + +For UI elements, consider including English in parentheses to help users match translations to what they see in the (often English) interface: + +- "**사이드바(Sidebar)**" +- "**파일 탐색기(File Explorer)**" + +## 6. Image Alt Text + +Translate image alt text to Korean for accessibility: + +- "GitHub Codespace 세션 리스트" +- "GitHub Codespaces 환영 화면" + +## 7. Common Mistakes + +Avoid these translation errors specific to Korean: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +채널.fromPath('*.fastq') +프로세스 FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ 버전 24.04.0 +실행자 > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Inconsistent honorific levels + +```markdown +// Wrong - mixing speech levels +워크플로우를 실행하세요. 결과가 나온다. + +// Correct - consistent formal polite level +워크플로우를 실행하세요. 결과가 나옵니다. +``` + +### ❌ Using overly academic translations + +```markdown +// Wrong - sounds like political independence +독립 실행형 스크립트... + +// Correct - appropriate technical meaning +단독 실행형 스크립트... +``` + +## 8. Terms to Translate + +These terms should be translated in prose (but kept in English in code). + +Note: Some terms use transliteration (음차) while others use actual Korean translations. Follow these patterns: + +### Transliterations (음차) + +| English | Korean | Notes | +| --------- | ---------- | -------------------------- | +| workflow | 워크플로우 | Common transliteration | +| pipeline | 파이프라인 | Common transliteration | +| terminal | 터미널 | Common transliteration | +| container | 컨테이너 | Common transliteration | +| sidebar | 사이드바 | Common transliteration | +| module | 모듈 | Common transliteration | +| sample | 샘플 | Common transliteration | +| tuple | 튜플 | Common transliteration | +| index | 인덱스 | Common transliteration | +| core | 코어 | Common transliteration | +| directory | 디렉토리 | Transliteration acceptable | +| file | 파일 | Transliteration | + +### Actual Translations + +| English | Korean | Notes | +| ------------- | ----------- | --------------------------------------------- | +| channel | 채널 | Transliteration but treated as translation | +| process | 프로세스 | Transliteration but treated as translation | +| standalone | 단독 | Not 독립 (political independence) | +| mini-course | 단기 과정 | Not 미니 과정 (too casual) | +| wrap | 적용하다 | Not 래핑하다 (sounds like physical packaging) | +| training | 교육 | Actual translation | +| environment | 환경 | Actual translation | +| repository | 저장소 | Actual translation | +| file explorer | 파일 탐색기 | Mixed | +| main editor | 메인 편집기 | Mixed | +| alignment | 정렬 | Actual translation | +| command | 명령 | Actual translation | +| directive | 지시문 | Actual translation | +| input | 입력 | Actual translation | +| output | 출력 | Actual translation | +| operator | 연산자 | Actual translation | +| parameter | 매개변수 | Actual translation | +| reference | 참조 | Actual translation | +| run | 실행 | Actual translation | +| task | 작업 | Actual translation | +| lowercase | 소문자 | Actual translation | +| materials | 자료 | Actual translation | +| course | 과정 | Actual translation | + +## 9. Admonition Titles + +| English | Korean | +| -------- | ------ | +| Note | 참고 | +| Tip | 팁 | +| Warning | 경고 | +| Exercise | 연습 | +| Solution | 해결책 | +| Example | 예제 | + +## 10. Section Headers + +| English | Korean | +| ----------------- | --------- | +| Takeaway | 핵심 정리 | +| What's next? | 다음 단계 | +| Warmup | 준비 운동 | +| Environment Setup | 환경 설정 | +| Getting Started | 시작하기 | + +## 11. Tab Labels + +| English | Korean | +| ------- | ------ | +| After | 후 | +| Before | 전 | +| Gitpod | Gitpod | +| Local | 로컬 | diff --git a/docs/ko/mkdocs.yml b/docs/ko/mkdocs.yml new file mode 100644 index 0000000000..f79b50886b --- /dev/null +++ b/docs/ko/mkdocs.yml @@ -0,0 +1,14 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: ko + custom_dir: ../en/overrides +extra: + consent: + title: "쿠키 동의" + description: >- + 저희는 귀하의 반복 방문과 선호도를 인식하고, 문서의 효과성과 사용자가 + 원하는 정보를 찾고 있는지 측정하기 위해 쿠키를 사용합니다. 동의해 주시면 + 교육 자료를 개선하는 데 도움이 됩니다. + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">쿠키 사용 방법</a>에 대해 자세히 알아보세요. + cookies: + posthog: "PostHog 분석" diff --git a/docs/ko/ui-strings.yml b/docs/ko/ui-strings.yml new file mode 100644 index 0000000000..1f6af22481 --- /dev/null +++ b/docs/ko/ui-strings.yml @@ -0,0 +1,20 @@ +# UI strings for translation - Korean (한국어) +# 이 문자열들은 index_page_hook.py에서 과정 시작 페이지에 사용되며 +# mkdocs.yml에서 쿠키 동의에 사용됩니다. + +index_page: + course_summary: "과정 요약" + additional_information: "추가 정보" + technical_requirements: "기술 요구사항" + learning_objectives: "학습 목표" + audience_prerequisites: "대상 및 선수조건" + course_videos: "과정 동영상" + +defaults: + technical_requirements: >- + GitHub 계정 또는 Nextflow 로컬 설치가 필요합니다. + 자세한 내용은 [환경 옵션](../envsetup/index.md)을 참조하세요. + videos: >- + 각 장에는 강사가 연습 문제를 진행하는 동영상이 제공됩니다. + 각 과정 부분의 동영상은 해당 페이지 상단에 포함되어 있습니다. + view_playlist: "YouTube에서 재생목록 보기" diff --git a/docs/language_names.yml b/docs/language_names.yml new file mode 100644 index 0000000000..c39393d523 --- /dev/null +++ b/docs/language_names.yml @@ -0,0 +1,10 @@ +de: deutsch +en: English +es: español +fr: français +hi: हिन्दी +it: italiano +ko: 한국어 +pl: Polski +pt: português +tr: Türkçe diff --git a/docs/missing-translation.md b/docs/missing-translation.md new file mode 100644 index 0000000000..87b2fb49fb --- /dev/null +++ b/docs/missing-translation.md @@ -0,0 +1,6 @@ +!!! warning "Translation in Progress" + + This page has not yet been translated into your language. + You are viewing the original English content. + + Want to help? See our [translation guide](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md). diff --git a/docs/pl/docs/envsetup/01_setup.md b/docs/pl/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..b8e72c076d --- /dev/null +++ b/docs/pl/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces to platforma internetowa, która pozwala nam dostarczyć prekonfigurowane środowisko do szkoleń, wspierane przez maszyny wirtualne w chmurze. +Platforma jest obsługiwana przez GitHub (który należy do Microsoft) i jest dostępna bezpłatnie (z limitami użycia) dla każdego z kontem GitHub. + +!!! warning "Ostrzeżenie" + + Konta powiązane z organizacjami mogą podlegać pewnym dodatkowym ograniczeniom. + W takim przypadku może być konieczne użycie niezależnego konta osobistego lub lokalna instalacja. + +## Tworzenie konta GitHub + +Możesz utworzyć darmowe konto GitHub na [stronie głównej GitHub](https://github.com/). + +## Uruchamianie GitHub Codespace + +Po zalogowaniu się do GitHub otwórz ten link w przeglądarce, aby otworzyć środowisko szkoleniowe Nextflow: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Alternatywnie możesz kliknąć przycisk pokazany poniżej, który jest powtórzony w każdym kursie szkoleniowym (zazwyczaj na stronie Orientacji). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Powinieneś zobaczyć stronę, na której możesz utworzyć nowy GitHub Codespace: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Konfiguracja + +Do ogólnego użytku nie powinieneś potrzebować niczego konfigurować. +O ile nie zaznaczono inaczej w kursie, który rozpoczynasz, możesz po prostu kliknąć główny przycisk, aby kontynuować. + +Jednak możliwe jest dostosowanie środowiska, klikając przycisk "Change options". + +??? info "Opcje konfiguracji" + + Jeśli klikniesz przycisk "Change options", będziesz mieć możliwość dostosowania następujących elementów: + + #### Branch + + Pozwala wybrać inną wersję materiałów szkoleniowych. + Branch `master` zazwyczaj zawiera poprawki błędów i materiały, które zostały niedawno opracowane i zatwierdzone, ale nie zostały jeszcze opublikowane na stronie. + Inne branche zawierają prace w toku, które mogą nie być w pełni funkcjonalne. + + #### Machine type + + Pozwala dostosować maszynę wirtualną, której będziesz używać do pracy ze szkoleniem. + + Używanie maszyny z większą liczbą rdzeni pozwala lepiej wykorzystać zdolność Nextflow do równoległego wykonywania workflow'ów. + Jednak zużyje to szybciej Twój darmowy limit, więc nie zalecamy zmiany tego ustawienia, chyba że jest to zalecane w instrukcjach kursu, który planujesz realizować. + + Zobacz 'Limity GitHub Codespaces' poniżej, aby uzyskać więcej szczegółów o limitach. + +### Czas uruchamiania + +Otwieranie nowego środowiska GitHub Codespaces po raz pierwszy może zająć kilka minut, ponieważ system musi skonfigurować Twoją maszynę wirtualną, więc nie martw się, jeśli jest czas oczekiwania. +Jednak nie powinno to trwać dłużej niż pięć minut. + +## Nawigacja w interfejsie szkoleniowym + +Po załadowaniu GitHub Codespaces powinieneś zobaczyć coś podobnego do poniższego (może otworzyć się w trybie jasnym w zależności od preferencji Twojego konta): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +To jest interfejs VSCode IDE, popularnej aplikacji do tworzenia kodu, którą polecamy do pracy z Nextflow. + +- **Główny edytor** to miejsce, gdzie będą otwierane kod Nextflow i inne pliki tekstowe. Tutaj będziesz edytować kod. Po otwarciu codespace wyświetli podgląd pliku `README.md`. +- **Terminal** poniżej głównego edytora pozwala uruchamiać polecenia. Tutaj będziesz uruchamiać wszystkie polecenia podane w instrukcjach kursu. +- **Pasek boczny** pozwala dostosować środowisko i wykonywać podstawowe zadania (kopiowanie, wklejanie, otwieranie plików, wyszukiwanie, git itp.). Domyślnie jest otwarty na eksploratorze plików, który pozwala przeglądać zawartość repozytorium. Kliknięcie pliku w eksploratorze otworzy go w głównym oknie edytora. + +Możesz dostosować względne proporcje paneli okna według własnych upodobań. + +<!-- TODO (future) Link to development best practices side quest? --> + +## Inne uwagi dotyczące korzystania z GitHub Codespaces + +### Wznawianie sesji + +Po utworzeniu środowiska możesz je łatwo wznowić lub uruchomić ponownie i kontynuować od miejsca, w którym skończyłeś. +Twoje środowisko automatycznie zakończy sesję po 30 minutach bezczynności i zachowa Twoje zmiany przez maksymalnie 2 tygodnie. + +Możesz ponownie otworzyć środowisko z <https://github.com/codespaces/>. +Poprzednie środowiska będą wyświetlone na liście. +Kliknij sesję, aby ją wznowić. + +![List GitHub Codespace sessions](img/codespaces_list.png) + +Jeśli zapisałeś URL swojego poprzedniego środowiska GitHub Codespaces, możesz po prostu otworzyć go w przeglądarce. +Alternatywnie kliknij ten sam przycisk, którego użyłeś do jego utworzenia: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Powinieneś zobaczyć poprzednią sesję, domyślną opcją jest jej wznowienie: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Zapisywanie plików na lokalną maszynę + +Aby zapisać dowolny plik z panelu eksploratora, kliknij prawym przyciskiem myszy na pliku i wybierz `Download`. + +### Zarządzanie limitami GitHub Codespaces + +GitHub Codespaces daje Ci do 15 GB-miesięcy przestrzeni dyskowej miesięcznie i 120 godzin rdzeniowych miesięcznie. +Jest to równoważne około 60 godzinom domyślnego czasu działania środowiska przy użyciu standardowej przestrzeni roboczej (2 rdzenie, 8 GB RAM i 32 GB przestrzeni dyskowej). + +Możesz tworzyć je z większymi zasobami (patrz wyjaśnienie powyżej), ale spowoduje to szybsze zużycie darmowego limitu i będziesz mieć mniej godzin dostępu do tej przestrzeni. +Na przykład, jeśli wybierzesz maszynę 4-rdzeniową zamiast domyślnej 2-rdzeniowej, Twój limit wyczerpie się o połowę szybciej. + +Opcjonalnie możesz zakupić dostęp do większych zasobów. + +Więcej informacji znajdziesz w dokumentacji GitHub: +[About billing for GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/pl/docs/envsetup/02_local.md b/docs/pl/docs/envsetup/02_local.md new file mode 100644 index 0000000000..95cab3d49f --- /dev/null +++ b/docs/pl/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Ręczna instalacja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Możliwe jest ręczne zainstalowanie wszystkiego, czego potrzebujesz do uruchomienia szkolenia w Twoim własnym lokalnym środowisku. + +Tutaj udokumentowaliśmy, jak to zrobić na standardowych systemach zgodnych z POSIX (zakładając komputer osobisty, taki jak laptop). +Pamiętaj, że niektóre szczegóły mogą się różnić w zależności od Twojego konkretnego systemu. + +!!! tip "Wskazówka" + + Zanim przejdziesz dalej, czy rozważyłeś użycie [podejścia Devcontainers](03_devcontainer.md)? + Zapewnia ono wszystkie niezbędne narzędzia i zależności bez konieczności ręcznej instalacji. + +## Ogólne wymagania programowe + +Nextflow może być używany na dowolnym systemie zgodnym z POSIX (Linux, macOS, Windows Subsystem for Linux itp.) z zainstalowaną Javą. +Nasze kursy szkoleniowe mają kilka dodatkowych wymagań. + +W sumie będziesz potrzebować następującego oprogramowania: + +- Bash lub równoważna powłoka +- [Java 11 (lub nowsza, do 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (lub nowsza) +- [VSCode](https://code.visualstudio.com) z [rozszerzeniem Nextflow](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +Aplikacja VSCode jest technicznie opcjonalna, ale zdecydowanie zalecamy jej użycie zarówno do pracy z kursami, jak i do ogólnej pracy z Nextflow. + +Podręcznik dokumentacji Nextflow zawiera instrukcje instalacji tych zależności w sekcji [Environment setup](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow i narzędzia nf-core + +Będziesz musiał zainstalować sam Nextflow oraz narzędzia nf-core, jak opisano w artykułach podlinkowanych poniżej: + +- [Instalacja Nextflow](https://www.nextflow.io/docs/latest/install.html) +- [Narzędzia nf-core](https://nf-co.re/docs/nf-core-tools/installation) + +Zalecamy użycie opcji samoinstalacji dla Nextflow i opcji PyPI dla narzędzi nf-core. + +!!! warning "Kompatybilność wersji" + + <!-- Any update to this content needs to be copied to the home page --> + **Od stycznia 2026 roku wszystkie nasze kursy szkoleniowe Nextflow wymagają wersji Nextflow 25.10.2 lub nowszej, z włączoną ścisłą składnią v2, chyba że zaznaczono inaczej.** + + Więcej informacji o wymaganiach wersji i ścisłej składni v2 znajdziesz w przewodniku [Wersje Nextflow](../info/nxf_versions.md). + + Starsze wersje materiałów szkoleniowych odpowiadające wcześniejszej składni są dostępne poprzez selektor wersji w pasku menu tej strony. + +## Materiały szkoleniowe + +Najprostszym sposobem pobrania materiałów szkoleniowych jest sklonowanie całego repozytorium za pomocą tego polecenia: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Każdy kurs ma swój własny katalog. +Aby pracować z kursem, otwórz okno terminala (najlepiej z poziomu aplikacji VSCode) i przejdź za pomocą `cd` do odpowiedniego katalogu. + +Następnie możesz postępować zgodnie z instrukcjami kursu dostarczonymi na stronie internetowej. diff --git a/docs/pl/docs/envsetup/03_devcontainer.md b/docs/pl/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..22a005066d --- /dev/null +++ b/docs/pl/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Lokalne Devcontainers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Jeśli masz lokalną instalację Docker lub chętnie ją zainstalujesz, najłatwiejszym sposobem pracy lokalnej z tymi materiałami jest użycie funkcji devcontainer w Visual Studio Code. To podejście zapewnia wszystkie niezbędne narzędzia i zależności bez konieczności ręcznej instalacji. + +## Wymagania + +Aby użyć lokalnej konfiguracji devcontainer, będziesz potrzebować: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Lokalnej instalacji Docker, na przykład: + - [Docker Desktop](https://docs.docker.com/get-docker/) (dla Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (dla Linux) + - [Colima](https://github.com/abiosoft/colima) (alternatywa dla macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (dołączony do Docker Desktop, ale może wymagać osobnej instalacji z innymi konfiguracjami Docker) +- [Rozszerzenie Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) dla VS Code + +Twoja instalacja Docker musi być uruchomiona przed próbą otwarcia devcontainer. + +Aby sprawdzić, czy Docker buildx jest dostępny, uruchom: + +```bash +docker buildx version +``` + +Jeśli to polecenie nie powiedzie się, będziesz musiał zainstalować rozszerzenie buildx przed kontynuowaniem. + +## Instrukcje konfiguracji + +Wykonaj następujące kroki, aby skonfigurować lokalne środowisko za pomocą devcontainers VS Code: + +### Zainstaluj rozszerzenie "Dev Containers" w VS Code + +- Otwórz VS Code +- Przejdź do Extensions (Ctrl+Shift+X lub Cmd+Shift+X na macOS) +- Wyszukaj "Dev Containers" +- Kliknij "Install" + +![Installing Dev Containers extension in VS Code](img/install_extension.png) + +### Sklonuj repozytorium: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Otwórz repozytorium w VS Code: + +- Uruchom VS Code +- Wybierz **File -> Open Folder** z menu +- Przejdź do i wybierz folder repozytorium szkoleniowego, który właśnie sklonowałeś +- Kliknij **Open** + +### Otwórz ponownie w kontenerze + +Jeśli VS Code wyświetli monit "Reopen in Container", kliknij go. Alternatywnie: + +- Naciśnij F1 (lub Ctrl+Shift+P / Cmd+Shift+P na macOS) +- Wpisz "Dev Containers: Reopen in Container" +- **Ważne**: Gdy pojawi się monit o wybór konfiguracji, wybierz konfigurację devcontainer **local-dev** + +![Reopen in Container prompt](img/reopen_prompt.png) + +![Selecting local configuration](img/select_local_config.png) + +Poczekaj, aż kontener się zbuduje. Za pierwszym razem może to zająć kilka minut, ponieważ pobiera i konfiguruje wszystkie niezbędne komponenty. + +Po zbudowaniu i uruchomieniu kontenera będziesz mieć w pełni skonfigurowane środowisko ze wszystkimi niezbędnymi narzędziami, w tym: + +- Java +- Nextflow +- Docker +- Git +- I wszystkie inne zależności wymagane do szkolenia + +![VS Code with devcontainer running](img/running_container.png) + +## Zalety korzystania z Devcontainers + +Korzystanie z podejścia devcontainer oferuje kilka zalet: + +- **Spójność**: Zapewnia spójne środowisko programistyczne na różnych maszynach +- **Prostota**: Wszystkie zależności są preinstalowane i skonfigurowane +- **Izolacja**: Środowisko programistyczne jest odizolowane od Twojego lokalnego systemu +- **Powtarzalność**: Każdy korzystający z devcontainer otrzymuje taką samą konfigurację +- **Brak ręcznej instalacji**: Nie ma potrzeby ręcznej instalacji Java, Nextflow i innych narzędzi + +## Sprawdzanie środowiska + +Po uruchomieniu devcontainer możesz sprawdzić, czy wszystko jest poprawnie skonfigurowane, uruchamiając: + +```bash +nextflow info +``` + +Powinno to wyświetlić wersję Nextflow i informacje o środowisku wykonawczym, potwierdzając, że Twoje środowisko jest poprawnie skonfigurowane. + +## Rozwiązywanie problemów + +Jeśli napotkasz problemy z konfiguracją devcontainer: + +1. Upewnij się, że Twoja instalacja Docker (Docker Desktop, Colima, Docker Engine itp.) jest uruchomiona przed otwarciem devcontainer +2. Sprawdź, czy wybrałeś konfigurację **local-dev**, gdy pojawił się monit +3. Sprawdź, czy Docker buildx jest zainstalowany i działa, uruchamiając `docker buildx version` +4. Jeśli kontener nie zbuduje się, spróbuj go przebudować, uruchamiając polecenie "Dev Containers: Rebuild Container" +5. W przypadku trwałych problemów zapoznaj się z [przewodnikiem rozwiązywania problemów VS Code Dev Containers](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/pl/docs/envsetup/index.md b/docs/pl/docs/envsetup/index.md new file mode 100644 index 0000000000..e98b8d83e7 --- /dev/null +++ b/docs/pl/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Opcje środowiska +description: Opcje konfiguracji środowiska do szkoleń Nextflow +hide: + - toc + - footer +--- + +# Opcje środowiska + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Naszym celem jest zapewnienie spójnego i dokładnie przetestowanego środowiska, które pozwala uczącym się skupić się na nauce Nextflow bez konieczności poświęcania czasu i wysiłku na zarządzanie oprogramowaniem. +W tym celu opracowaliśmy skonteneryzowane środowisko zawierające całe niezbędne oprogramowanie, pliki kodu i przykładowe dane do pracy ze wszystkimi naszymi kursami. + +To skonteneryzowane środowisko można uruchomić bezpośrednio w GitHub Codespaces lub lokalnie w VS Code z rozszerzeniem Devcontainers. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **GitHub Codespaces** + + *** + + GitHub Codespaces to usługa internetowa, która pozwala nam dostarczyć prekonfigurowane środowisko do szkoleń, ze wszystkimi narzędziami i danymi, wspierane przez maszyny wirtualne w chmurze. Jest dostępna bezpłatnie dla każdego z kontem GitHub. + + [Użyj GitHub Codespaces :material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Lokalne Devcontainers** + + *** + + VS Code z Devcontainers zapewnia lokalnie uruchamiane skonteneryzowane środowisko programistyczne ze wszystkimi narzędziami szkoleniowymi prekonfigurowanymi. Oferuje to samo prekonfigurowane środowisko co Codespaces, ale działa całkowicie na Twoim lokalnym sprzęcie. + + [Użyj Devcontainers lokalnie :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Instrukcje ręcznej instalacji + +Jeśli żadna z powyższych opcji nie odpowiada Twoim potrzebom, możesz odtworzyć to środowisko na własnym systemie lokalnym, ręcznie instalując zależności oprogramowania i klonując repozytorium szkoleniowe. + +[Ręczna instalacja :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Wycofanie Gitpod" + + Szkolenie Nextflow korzystało z [Gitpod](https://gitpod.io) do lutego 2025 roku. + Jednak twórcy Gitpod zdecydowali się wycofać darmową funkcjonalność na rzecz systemu [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex). + Z tego powodu przeszliśmy na GitHub Codespaces, które również oferują jednoklkowe środowisko deweloperskie bez wcześniejszej konfiguracji. + + W zależności od tego, kiedy zarejestrowałeś się w Gitpod i kiedy dokładnie wycofają usługę, możesz nadal być w stanie uruchomić szkolenie w ich starym IDE chmurowym, choć nie możemy zagwarantować niezawodnego dostępu w przyszłości: + [Otwórz w Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/pl/docs/hello_nextflow/00_orientation.md b/docs/pl/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..3da3bc0b1b --- /dev/null +++ b/docs/pl/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Rozpoczęcie pracy + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Zobacz [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/00_orientation.md). +/// + +!!! tip "Wskazówka" + + Filmy na YouTube mają specjalne funkcje! + + - :fontawesome-solid-closed-captioning: Wysokiej jakości (ręcznie przygotowane) napisy. Włącz je ikoną :material-subtitles: + - :material-bookmark: Rozdziały wideo na osi czasu odpowiadające nagłówkom strony. + +## Uruchom środowisko szkoleniowe + +Aby użyć prekonfigurowanego środowiska, które udostępniamy na GitHub Codespaces, kliknij przycisk "Open in GitHub Codespaces" poniżej. Inne opcje znajdziesz w [Opcjach środowiska](../envsetup/index.md). + +Zalecamy otwarcie środowiska szkoleniowego w nowej karcie lub oknie przeglądarki (użyj prawego przycisku myszy, ctrl-click lub cmd-click w zależności od sprzętu), abyś mógł czytać dalej podczas ładowania środowiska. +Będziesz musiał trzymać te instrukcje otwarte równolegle, aby pracować z kursem. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Podstawy środowiska + +To środowisko szkoleniowe zawiera całe oprogramowanie, kod i dane niezbędne do pracy z kursem szkoleniowym, więc nie musisz niczego instalować samodzielnie. + +Codespace jest skonfigurowany z interfejsem VSCode, który obejmuje eksplorator systemu plików, edytor kodu i powłokę terminala. +Wszystkie instrukcje podane podczas kursu (np. 'otwórz plik', 'edytuj kod' lub 'uruchom to polecenie') odnoszą się do tych trzech części interfejsu VSCode, chyba że zaznaczono inaczej. + +Jeśli pracujesz z tym kursem samodzielnie, zapoznaj się z [podstawami środowiska](../envsetup/01_setup.md), aby uzyskać więcej szczegółów. + +### Wymagania wersji + +To szkolenie jest zaprojektowane dla Nextflow 25.10.2 lub nowszego **z WŁĄCZONYM parserem składni v2**. +Jeśli używasz lokalnego lub niestandardowego środowiska, upewnij się, że używasz prawidłowych ustawień, jak udokumentowano [tutaj](../info/nxf_versions.md). + +## Przygotuj się do pracy + +Po uruchomieniu codespace są dwie rzeczy, które musisz zrobić przed zanurzeniem się w szkoleniu: ustawić katalog roboczy dla tego konkretnego kursu i przejrzeć dostarczone materiały. + +### Ustaw katalog roboczy + +Domyślnie codespace otwiera się z katalogiem roboczym ustawionym na główny katalog wszystkich kursów szkoleniowych, ale dla tego kursu będziemy pracować w katalogu `hello-nextflow/`. + +Zmień teraz katalog, uruchamiając to polecenie w terminalu: + +```bash +cd hello-nextflow/ +``` + +Możesz ustawić VSCode, aby skupił się na tym katalogu, tak aby w pasku bocznym eksploratora plików wyświetlały się tylko odpowiednie pliki: + +```bash +code . +``` + +!!! tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu wyjdziesz z tego katalogu (np. Twój codespace przejdzie w stan uśpienia), zawsze możesz użyć pełnej ścieżki, aby do niego wrócić, zakładając, że uruchamiasz to w środowisku szkoleniowym GitHub Codespaces: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Teraz przyjrzyjmy się zawartości. + +### Przeglądaj dostarczone materiały + +Możesz przeglądać zawartość tego katalogu za pomocą eksploratora plików po lewej stronie przestrzeni roboczej szkolenia. +Alternatywnie możesz użyć polecenia `tree`. + +W trakcie kursu używamy wyjścia `tree` do reprezentowania struktury katalogów i zawartości w czytelnej formie, czasami z drobnymi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu w głąb: + +```bash +tree . -L 2 +``` + +??? abstract "Zawartość katalogu" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Kliknij na kolorowe pole, aby rozwinąć sekcję i zobaczyć jej zawartość. +Używamy takich rozwijanych sekcji, aby zwięźle włączać oczekiwane wyjście poleceń. + +- **Pliki `.nf`** to skrypty workflow'ów nazwane na podstawie części kursu, w której są używane. + +- **Plik `nextflow.config`** to plik konfiguracyjny, który ustawia minimalne właściwości środowiska. + Na razie możesz go zignorować. + +- **Plik `greetings.csv`** w `data/` zawiera dane wejściowe, których użyjemy w większości kursu. Jest opisany w Części 2 (Channels), kiedy wprowadzamy go po raz pierwszy. + +- **Pliki `test-params.*`** to pliki konfiguracyjne, których użyjemy w Części 6 (Configuration). Na razie możesz je zignorować. + +- **Katalog `solutions`** zawiera ukończone skrypty workflow'ów, które są wynikiem każdego etapu kursu. + Są przeznaczone do użycia jako odniesienie do sprawdzenia swojej pracy i rozwiązywania problemów. + +## Lista kontrolna gotowości + +Myślisz, że jesteś gotowy do zanurzenia się? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Moje środowisko jest uruchomione +- [ ] Ustawiłem odpowiednio swój katalog roboczy + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +**Aby przejść do [Części 1: Hello World](./01_hello_world.md), kliknij strzałkę w prawym dolnym rogu tej strony.** diff --git a/docs/pl/docs/hello_nextflow/01_hello_world.md b/docs/pl/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..304f015d19 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Część 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Zobacz [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/01_hello_world.md). +/// + +W tej pierwszej części kursu szkoleniowego Hello Nextflow łagodnie wchodzimy w temat z bardzo podstawowym, niezależnym od dziedziny przykładem Hello World, który będziemy stopniowo rozbudowywać, aby zademonstrować użycie podstawowej logiki i komponentów Nextflow. + +??? info "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 frameworku oprogramowania. + Przykład zazwyczaj polega na wypisaniu frazy "Hello, World!" na urządzeniu wyjściowym, takim jak konsola lub terminal, lub zapisaniu jej do pliku. + +--- + +## 0. Rozgrzewka: Uruchom przykład Hello World bezpośrednio + +Zademonstrujmy to prostym poleceniem, które uruchomimy bezpośrednio w terminalu, aby pokazać, co robi, zanim opakujemy je w Nextflow. + +!!! tip "Wskazówka" + + Pamiętaj, że powinieneś teraz znajdować się w katalogu `hello-nextflow/`, jak opisano na stronie [Rozpoczęcie pracy](00_orientation.md). + +### 0.1. Spraw, aby terminal powiedział "hello" + +Uruchom następujące polecenie w terminalu. + +```bash +echo 'Hello World!' +``` + +??? success "Wyjście polecenia" + + ```console + Hello World! + ``` + +To wyświetla tekst 'Hello World' bezpośrednio w terminalu. + +### 0.2. Zapisz wyjście do pliku + +Uruchamianie pipeline'ów zazwyczaj polega na odczytywaniu danych z plików i zapisywaniu wyników do innych plików, więc zmodyfikujmy polecenie, aby zapisać tekstowe wyjście do pliku, czyniąc przykład bardziej odpowiednim. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Wyjście polecenia" + + ```console + + ``` + +To nie wyświetla niczego w terminalu. + +### 0.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`. + +??? abstract "Zawartość pliku" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +To jest to, co spróbujemy odtworzyć w naszym pierwszym workflow'ie Nextflow. + +### Podsumowanie + +Wiesz już, jak uruchomić proste polecenie w terminalu, które wyświetla tekst, i opcjonalnie, jak sprawić, by zapisało wyjście do pliku. + +### Co dalej? + +Dowiedz się, jak wyglądałoby to napisane jako workflow Nextflow. + +--- + +## 1. Przeanalizuj skrypt i uruchom go + +Dostarczamy Ci w pełni funkcjonalny, choć minimalistyczny skrypt workflow'u o nazwie `hello-world.nf`, który robi to samo co wcześniej (wypisuje 'Hello World!'), ale z Nextflow. + +Na początek otwórzmy skrypt workflow'u, abyś mógł zorientować się w jego strukturze. +Następnie uruchomimy go i poszukamy jego wyjść. + +### 1.1. Przeanalizuj kod + +Skrypt `hello-world.nf` znajdziesz w swoim bieżącym katalogu, którym powinien być `hello-nextflow`. Otwórz go w panelu edytora. + +??? full-code "Pełny plik kodu" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Użyj echo do wypisania 'Hello World!' do pliku + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // wyemituj pozdrowienie + sayHello() + } + ``` + +Skrypt workflow'u Nextflow zazwyczaj zawiera jedną lub więcej definicji **process** oraz sam **workflow**, plus kilka opcjonalnych bloków (nieobecnych tutaj), które wprowadzimy później. + +Każdy **process** opisuje, jakie operacje powinien wykonać odpowiedni krok w pipeline'ie, podczas gdy **workflow** opisuje logikę przepływu danych, która łączy poszczególne kroki. + +Najpierw przyjrzymy się bliżej blokowi **process**, a następnie blokowi **workflow**. + +#### 1.1.1. Definicja `process` + +Pierwszy blok kodu opisuje **process**. + +Definicja procesu zaczyna się od słowa kluczowego `process`, po którym następuje nazwa procesu i wreszcie ciało procesu ograniczone nawiasami klamrowymi. +Ciało procesu musi zawierać blok script, który określa polecenie do uruchomienia, które może być wszystkim, co mógłbyś uruchomić w terminalu wiersza poleceń. + +```groovy title="hello-world.nf" linenums="3" +/* +* Użyj echo do wypisania 'Hello World!' do pliku +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Tutaj mamy **process** o nazwie `sayHello`, który zapisuje swoje **wyjście** do pliku o nazwie `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +To jest bardzo minimalna definicja procesu, która zawiera tylko definicję `output` i `script` do wykonania. + +Definicja `output` zawiera kwalifikator `path`, który mówi Nextflow, że powinien to traktować jako ścieżkę (obejmuje zarówno ścieżki katalogów, jak i pliki). +Innym popularnym kwalifikatorem jest `val`. + +Co ważne, definicja wyjścia nie _określa_, jakie wyjście zostanie utworzone. +Po prostu _deklaruje_, jakie jest oczekiwane wyjście, aby Nextflow mógł go szukać po zakończeniu wykonywania. +Jest to konieczne do weryfikacji, czy polecenie zostało wykonane pomyślnie i do przekazania wyjścia do procesów downstream, jeśli to konieczne. Wyjście utworzone, które nie pasuje do tego, co jest zadeklarowane w bloku output, nie zostanie przekazane do procesów downstream. + +!!! warning "Ostrzeżenie" + + Ten przykład jest kruchy, ponieważ zakodowaliśmy na sztywno nazwę pliku wyjściowego w dwóch oddzielnych miejscach (bloki script i output). + Jeśli zmienimy jedno, a nie drugie, skrypt się zepsuje. + Później nauczysz się sposobów na użycie zmiennych, aby złagodzić ten problem. + +W rzeczywistym pipeline'ie proces zazwyczaj zawiera dodatkowe bloki, takie jak dyrektywy i wejścia, które wprowadzimy za chwilę. + +#### 1.1.2. Definicja `workflow` + +Drugi blok kodu opisuje sam **workflow**. +Definicja workflow'u zaczyna się od słowa kluczowego `workflow`, po którym następuje opcjonalna nazwa, a następnie ciało workflow'u ograniczone nawiasami klamrowymi. + +Tutaj mamy **workflow**, który składa się z bloku `main:` (który mówi 'to jest główne ciało workflow'u') zawierającego wywołanie procesu `sayHello`. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // wyemituj pozdrowienie + sayHello() +} +``` + +To jest bardzo minimalna definicja **workflow**. +W rzeczywistym pipeline'ie workflow zazwyczaj zawiera wiele wywołań **procesów** połączonych **kanałami**, a procesy oczekują jednego lub więcej zmiennych **wejść**. + +Nauczysz się, jak dodawać zmienne wejścia później w tym module szkoleniowym; a w Części 3 tego kursu nauczysz się, jak dodawać więcej procesów i łączyć je kanałami. + +!!! tip "Wskazówka" + + Technicznie linia `main:` nie jest wymagana dla prostych workflow'ów takich jak ten, więc możesz napotkać workflow'y, które jej nie mają. + Ale będziemy jej potrzebować, aby skorzystać z wyjść na poziomie workflow'u, więc równie dobrze możemy ją uwzględnić od początku. + +### 1.2. Uruchom workflow + +Patrzenie na kod nie jest tak zabawne jak uruchamianie go, więc wypróbujmy to w praktyce. + +#### 1.2.1. Uruchom workflow i monitoruj wykonywanie + +W terminalu uruchom następujące polecenie: + +```bash +nextflow run hello-world.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Jeśli Twoje wyjście konsoli wygląda mniej więcej tak, to gratulacje, właśnie uruchomiłeś swój pierwszy workflow Nextflow! + +Najważniejszym wyjściem tutaj jest ostatnia linia, która jest podświetlona w wyjściu powyżej: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +To mówi nam, że proces `sayHello` został pomyślnie wykonany raz (`1 of 1 ✔`). + +Co ważne, ta linia mówi również, gdzie znaleźć wyjście wywołania procesu `sayHello`. +Przyjrzyjmy się temu teraz. + +#### 1.2.2. Znajdź wyjście i dzienniki w katalogu `work` + +Kiedy uruchamiasz Nextflow po raz pierwszy w danym katalogu, tworzy on katalog o nazwie `work`, w którym będzie zapisywał wszystkie pliki (i wszelkie dowiązania symboliczne) wygenerowane w trakcie wykonywania. + +W katalogu `work` Nextflow organizuje wyjścia i dzienniki dla każdego wywołania procesu. +Dla każdego wywołania procesu Nextflow tworzy zagnieżdżony podkatalog, nazwany hashem, aby był unikalny, gdzie przygotuje wszystkie niezbędne wejścia (domyślnie używając dowiązań symbolicznych), zapisze pliki pomocnicze i zapisze dzienniki oraz wszelkie wyjścia procesu. + +Ścieżka do tego podkatalogu jest pokazana w skróconej formie w nawiasach kwadratowych w wyjściu konsoli. +Patrząc na to, co otrzymaliśmy dla uruchomienia pokazanego powyżej, linia dziennika konsoli dla procesu sayHello zaczyna się od `[65/7be2fa]`. To odpowiada następującej ścieżce katalogu: `work/65/7be2fad5e71e5f49998f795677fd68` + +Zobaczmy, co tam jest. + +??? abstract "Zawartość katalogu" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Nie widzisz tego samego?" + + Dokładne nazwy podkatalogów będą różne 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 przeglądania, będziesz musiał ustawić odpowiednią opcję wyświetlania niewidocznych plików. + + ```bash + tree -a work + ``` + +Pierwszą rzeczą, na którą chcesz spojrzeć, jest faktyczne wyjście workflow'u, czyli plik `output.txt` utworzony przez proces `sayHello`. +Otwórz go, a znajdziesz pozdrowienie `Hello World!`, które było celem naszego minimalistycznego workflow'u. + +??? abstract "Zawartość pliku" + + ```console title="output.txt" + Hello World! + ``` + +Zadziałało! + +Trzeba przyznać, że może to wydawać się dużo kodu opakowującego dla tak małego wyniku, ale wartość całego tego kodu opakowującego stanie się bardziej oczywista, gdy zaczniemy wczytywać pliki wejściowe i łączyć wiele kroków. + +To powiedziawszy, przyjrzyjmy się również innym plikom w tym katalogu. To są pliki pomocnicze i dziennika tworzone przez Nextflow jako część wykonywania zadania. + +- **`.command.begin`**: Metadane związane z początkiem wykonywania wywołania procesu +- **`.command.err`**: Komunikaty o błędach (`stderr`) emitowane przez wywołanie procesu +- **`.command.log`**: Pełne wyjście dziennika emitowane przez wywołanie procesu +- **`.command.out`**: Zwykłe wyjście (`stdout`) wywołania 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ż mówi Ci główne polecenie, które Nextflow wykonał, nie włączając w to całej księgowości i konfiguracji zadania/środowiska. + +??? abstract "Zawartość pliku" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +To pasuje do tego, co wcześniej uruchomiliśmy ręcznie. + +W tym przypadku jest to bardzo proste, ponieważ polecenie procesu było zakodowane na sztywno, ale później w kursie zobaczysz polecenia procesów, które zawierają interpolację zmiennych. +To sprawia, że szczególnie cenne jest móc zobaczyć dokładnie, jak Nextflow zinterpretował kod i jakie polecenie zostało wygenerowane, gdy rozwiązujesz problemy z nieudanym uruchomieniem. + +### 1.3. Uruchom workflow ponownie + +Spróbuj uruchomić workflow jeszcze kilka razy, a następnie spójrz na katalogi zadań w `work/`. + +??? abstract "Zawartość katalogu" + + ```console + 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 + ``` + +Widzisz, że dla każdego uruchomienia został utworzony nowy podkatalog z kompletnym zestawem plików wyjściowych i dziennika. +To pokazuje, że uruchomienie tego samego workflow'u kilka razy nie nadpisze wyników poprzednich uruchomień. + +### Podsumowanie + +Wiesz, jak odczytać prosty skrypt Nextflow, uruchomić go i znaleźć wyjście oraz odpowiednie pliki dziennika w katalogu work. + +### Co dalej? + +Naucz się publikować wyjścia workflow'u do bardziej wygodnej lokalizacji. + +--- + +## 2. Publikuj wyjścia + +Jak właśnie się dowiedziałeś, wyjście utworzone przez nasz pipeline jest zakopane w katalogu roboczym kilka poziomów w głąb. +Jest to zrobione celowo; Nextflow kontroluje ten katalog i nie powinniśmy z nim wchodzić w interakcję. +Jednak to sprawia, że jest niewygodne pobieranie wyjść, na których nam zależy. + +Na szczęście Nextflow zapewnia sposób publikowania wyjść do wyznaczonego katalogu za pomocą [definicji wyjść na poziomie workflow'u](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs). + +### 2.1. Podstawowe użycie + +To będzie wymagało dwóch nowych fragmentów kodu: + +1. Bloku `publish:` wewnątrz ciała `workflow`, deklarującego wyjścia procesu. +2. Bloku `output` w skrypcie określającego opcje wyjścia, takie jak tryb i lokalizacja. + +#### 2.1.1. Zadeklaruj wyjście procesu `sayHello` + +Musimy dodać blok `publish:` do ciała workflow'u (ten sam rodzaj elementu kodu co blok `main:`) i wymienić wyjście procesu `sayHello()`. + +W pliku skryptu workflow'u `hello-world.nf` dodaj następujące linie kodu: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // wyemituj pozdrowienie + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // wyemituj pozdrowienie + sayHello() + } + ``` + +Widzisz, że możemy odwołać się do wyjścia procesu po prostu robiąc `sayHello().out` i przypisać mu dowolną nazwę, `first_output`. + +#### 2.1.2. Dodaj blok `output:` do skryptu + +Teraz musimy tylko dodać blok `output:`, w którym zostanie określona ścieżka katalogu wyjściowego. Zauważ, że ten nowy blok znajduje się **poza** i **poniżej** bloku `workflow` w skrypcie. + +W pliku skryptu workflow'u `hello-world.nf` dodaj następujące linie kodu: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // wyemituj pozdrowienie + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // wyemituj pozdrowienie + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Możemy użyć tego do przypisania określonych ścieżek do dowolnych wyjść procesów zadeklarowanych w bloku `workflow`. +Później nauczysz się sposobów generowania zaawansowanych struktur katalogów wyjściowych, ale na razie po prostu zakodowujemy minimalną ścieżkę dla prostoty. + +#### 2.1.3. Uruchom workflow + +Teraz uruchom zmodyfikowany skrypt workflow'u: + +```bash +nextflow run hello-world.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +Wyjście terminala powinno wyglądać znajomo. Zewnętrznie nic się nie zmieniło. + +Jednak sprawdź eksplorator plików: tym razem Nextflow utworzył nowy katalog o nazwie `results/`. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +Wewnątrz katalogu `results` znajdziemy dowiązanie symboliczne do pliku `output.txt` utworzonego w katalogu work przez polecenie, które właśnie uruchomiliśmy. + +To pozwala nam łatwo pobierać pliki wyjściowe bez konieczności przekopywania się przez podkatalogi work. + +### 2.2. Ustaw niestandardową lokalizację + +Posiadanie domyślnej lokalizacji jest świetne, ale możesz chcieć dostosować, gdzie wyniki są zapisywane i jak są zorganizowane. + +Na przykład możesz chcieć zorganizować swoje wyjścia w podkatalogi. +Najprostszym sposobem na to jest przypisanie określonej ścieżki wyjściowej dla każdego wyjścia. + +#### 2.2.1. Zmodyfikuj ścieżkę wyjściową + +Po raz kolejny modyfikacja zachowania publikowania dla określonego wyjścia jest naprawdę prosta. +Aby ustawić niestandardową lokalizację, po prostu edytuj `path` odpowiednio: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Ponieważ jest to ustawiane na poziomie pojedynczego wyjścia, możesz określić różne lokalizacje i podkatalogi, aby dopasować się do swoich potrzeb. + +#### 2.2.2. Uruchom workflow ponownie + +Wypróbujmy to. + +```bash +nextflow run hello-world.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Tym razem wynik jest zapisywany w określonym podkatalogu. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Widzisz, że wynik z poprzedniego wykonania nadal tam jest. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +Możesz użyć tylu poziomów zagnieżdżenia, ile chcesz. +Możliwe jest również użycie nazwy procesu lub innych zmiennych do nazywania katalogów używanych do organizowania wyników, a także możliwe jest zmienienie domyślnej nazwy katalogu wyjściowego najwyższego poziomu (która jest kontrolowana przez specjalną zmienną `outputDir`). +Omówimy te opcje w późniejszych szkoleniach. + +### 2.3. Ustaw tryb publikowania na kopiowanie + +Domyślnie wyjścia są publikowane jako dowiązania symboliczne z katalogu `work`. +To oznacza, że na systemie plików znajduje się tylko jeden plik. + +To świetne, gdy masz do czynienia z bardzo dużymi plikami, dla których nie chcesz przechowywać wielu kopii. +Jednak jeśli w pewnym momencie usuniesz katalog work (wkrótce omówimy operacje czyszczenia), stracisz dostęp do pliku. +Więc musisz mieć plan zapisywania kopii wszystkich ważnych plików w bezpiecznym miejscu. + +Jedną z łatwych opcji jest przełączenie trybu publikowania na kopiowanie dla wyjść, na których Ci zależy. + +#### 2.3.1. Dodaj dyrektywę mode + +Ta część jest naprawdę prosta. +Po prostu dodaj `mode 'copy'` do odpowiedniej definicji wyjścia na poziomie workflow'u: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +To ustawia tryb publikowania dla tego konkretnego wyjścia. + +#### 2.3.2. Uruchom workflow ponownie + +Wypróbujmy to. + +```bash +nextflow run hello-world.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Tym razem, jeśli spojrzysz na wyniki, plik jest właściwą kopią, a nie tylko dowiązaniem symbolicznym. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Ponieważ to również jest ustawiane na poziomie pojedynczego wyjścia, pozwala to ustawić tryb publikowania w sposób szczegółowy. +To będzie szczególnie przydatne później, gdy przejdziemy do wieloetapowych pipeline'ów, gdzie możesz chcieć kopiować tylko końcowe wyjścia i zostawiać pośrednie wyjścia jako dowiązania symboliczne, na przykład. + +Jak zauważono wcześniej, istnieją inne, bardziej zaawansowane opcje kontrolowania sposobu publikowania wyjść. +Pokażemy Ci, jak ich używać w odpowiednim czasie w Twojej podróży z Nextflow. + +### 2.4. Uwaga o dyrektywach `publishDir` na poziomie procesu + +Do niedawna ustalonym sposobem publikowania wyjść było robienie tego na poziomie każdego pojedynczego procesu za pomocą dyrektywy `publishDir`. + +Aby osiągnąć to, co właśnie zrobiliśmy dla wyjść procesu `sayHello`, zamiast tego dodalibyśmy następującą linię do definicji procesu: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Nadal znajdziesz ten wzorzec kodu wszędzie w starszych pipeline'ach Nextflow i modułach procesów, więc ważne jest, aby być tego świadomym. +Jednak nie zalecamy używania go w żadnej nowej pracy, ponieważ ostatecznie zostanie niedozwolony w przyszłych wersjach języka Nextflow. + +### Podsumowanie + +Wiesz, jak publikować wyjścia workflow'u do bardziej wygodnej lokalizacji. + +### Co dalej? + +Naucz się dostarczać zmienne wejście poprzez parametr wiersza poleceń i efektywnie wykorzystywać wartości domyślne. + +--- + +## 3. Użyj zmiennego wejścia przekazywanego z wiersza poleceń + +W obecnym stanie nasz workflow używa pozdrowienia zakodowanego na sztywno w poleceniu procesu. +Chcemy dodać pewną elastyczność, używając zmiennej wejściowej, abyśmy mogli łatwiej zmieniać pozdrowienie w czasie wykonywania. + +Wymaga to wprowadzenia trzech zestawów zmian w naszym skrypcie: + +1. Zmiana procesu, aby oczekiwał zmiennego wejścia +2. Skonfigurowanie parametru wiersza poleceń do przechwytywania danych wejściowych użytkownika +3. Przekazanie wejścia do procesu w ciele workflow'u + +Wprowadźmy te zmiany po kolei. + +### 3.1. Zmień proces `sayHello`, aby oczekiwał zmiennego wejścia + +Musimy edytować definicję procesu, aby (1) akceptowała zmienną wejściową i (2) używała tej zmiennej w wierszu poleceń. + +#### 3.1.1. Dodaj blok wejściowy do definicji procesu + +Najpierw dostosujmy definicję procesu, aby akceptowała wejście o nazwie `greeting`. + +W bloku procesu wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +Zmienna `greeting` jest poprzedzona `val`, aby powiedzieć Nextflow, że to wartość (nie ścieżka). + +#### 3.1.2. Edytuj polecenie procesu, aby używać zmiennej wejściowej + +Teraz zamieniamy oryginalną wartość zakodowaną na sztywno na wartość zmiennej wejściowej, którą oczekujemy otrzymać. + +W bloku procesu wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +Symbol `$` i nawiasy klamrowe (`{ }`) mówią Nextflow, że to jest nazwa zmiennej, która musi być zastąpiona faktyczną wartością wejściową (=interpolowana). + +!!! tip "Wskazówka" + + Nawiasy klamrowe (`{ }`) były technicznie opcjonalne w poprzednich wersjach Nextflow, więc możesz zobaczyć starsze workflow'y, gdzie to jest zapisane jako `echo '$greeting' > output.txt`. + +Teraz, gdy proces `sayHello()` jest gotowy do przyjęcia zmiennego wejścia, potrzebujemy sposobu na dostarczenie wartości wejściowej do wywołania procesu na poziomie workflow'u. + +### 3.2. Skonfiguruj parametr wiersza poleceń do przechwytywania danych wejściowych użytkownika + +Moglibyśmy po prostu zakodować wejście na sztywno, robiąc wywołanie procesu `sayHello('Hello World!')`. +Jednak gdy wykonujemy prawdziwą pracę z naszym workflow'em, będziemy chcieli móc kontrolować jego wejścia z wiersza poleceń. + +Dobra wiadomość: Nextflow ma wbudowany system parametrów workflow'u o nazwie `params`, który ułatwia deklarowanie i używanie parametrów CLI. + +Ogólna składnia to zadeklarowanie `params.<nazwa_parametru>`, aby powiedzieć Nextflow, że ma oczekiwać parametru `--<nazwa_parametru>` w wierszu poleceń. + +Tutaj chcemy utworzyć parametr o nazwie `--input`, więc musimy zadeklarować `params.input` gdzieś w workflow'ie. +Zasadniczo możemy to napisać gdziekolwiek; ale ponieważ zamierzamy przekazać go do wywołania procesu `sayHello()`, możemy wstawić go tam bezpośrednio, pisząc `sayHello(params.input)`. + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // wyemituj pozdrowienie + sayHello(params.input) + ``` + +=== "Przed" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // wyemituj pozdrowienie + sayHello() + ``` + +To mówi Nextflow, aby uruchomił proces `sayHello` na wartości dostarczonej przez parametr `--input`. + +W efekcie osiągnęliśmy kroki (2) i (3) opisane na początku sekcji za jednym razem. + +### 3.3. Uruchom polecenie workflow'u + +Uruchommy to! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Jeśli wprowadzono wszystkie te edycje poprawnie, powinieneś uzyskać kolejne pomyślne wykonanie. + +Koniecznie otwórz plik wyjściowy, aby sprawdzić, czy masz teraz nową wersję pozdrowienia. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Zauważ, że nowe wykonanie nadpisało plik wyjściowy opublikowany w katalogu `results`. +Jednak wyniki poprzednich uruchomień są nadal zachowane w katalogach zadań w `work`. + +!!! tip "Wskazówka" + + Możesz łatwo odróżnić parametry na poziomie Nextflow od parametrów na poziomie pipeline'u. + + - Parametry, które mają zastosowanie do pipeline'u, zawsze mają podwójny myślnik (`--`). + - Parametry, które modyfikują ustawienie Nextflow, _np._ funkcja `-resume`, której użyliśmy wcześniej, mają pojedynczy myślnik (`-`). + +### 3.4. Użyj wartości domyślnych dla parametrów wiersza poleceń + +Ok, to było wygodne, ale w wielu przypadkach ma sens dostarczenie wartości domyślnej dla danego parametru, abyś nie musiał go określać przy każdym uruchomieniu. + +#### 3.4.1. Ustaw wartość domyślną dla parametru CLI + +Nadajmy parametrowi `input` wartość domyślną, deklarując go przed definicją workflow'u. + +```groovy title="hello-world.nf" linenums="20" +/* + * Parametry pipeline'u + */ +params { + input: String = 'Holà mundo!' +} +``` + +Jak widzisz, możemy określić typ wejścia, którego oczekuje workflow (Nextflow 25.10.2 i nowsze). +Składnia to `nazwa: Typ = wartość_domyślna`. +Obsługiwane typy to `String`, `Integer`, `Float`, `Boolean` i `Path`. + +!!! info "Informacja" + + W starszych workflow'ach możesz zobaczyć, że cały blok `params` jest zapisany po prostu jako `input = 'Holà mundo!'`. + +Gdy dodajesz więcej parametrów do swojego pipeline'u, powinieneś dodawać je wszystkie do tego bloku, niezależnie od tego, czy musisz nadać im wartość domyślną. +To ułatwi znalezienie wszystkich konfigurowalnych parametrów na pierwszy rzut oka. + +#### 3.4.2. Uruchom workflow ponownie bez określania parametru + +Teraz, gdy masz ustawioną wartość domyślną, możesz uruchomić workflow ponownie bez konieczności określania wartości w wierszu poleceń. + +```bash +nextflow run hello-world.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +Wyjście będzie w tym samym miejscu co poprzednio, ale zawartość powinna być zaktualizowana o nowy tekst. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow użył domyślnej wartości parametru greeting do utworzenia wyjścia. + +#### 3.4.3. Nadpisz wartość domyślną + +Jeśli podasz parametr w wierszu poleceń, wartość CLI nadpisze wartość domyślną. + +Wypróbuj: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Po raz kolejny powinieneś znaleźć odpowiednie zaktualizowane wyjście w swoim katalogu wyników. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Uwaga" + + W Nextflow istnieje wiele miejsc, gdzie możesz określić wartości dla parametrów. + Jeśli ten sam parametr jest ustawiony na różne wartości w wielu miejscach, Nextflow określi, jakiej wartości użyć, na podstawie kolejności pierwszeństwa opisanej [tutaj](https://www.nextflow.io/docs/latest/config.html). + + Omówimy to bardziej szczegółowo w Części 6 (Configuration). + +### Podsumowanie + +Wiesz, jak używać prostego zmiennego wejścia dostarczanego w czasie wykonywania przez parametr wiersza poleceń, a także jak konfigurować, używać i nadpisywać wartości domyślne. + +### Co dalej? + +Naucz się wygodniej zarządzać wykonywaniem. + +--- + +## 4. Zarządzaj wykonywaniem workflow'u + +Wiedza o tym, jak uruchamiać workflow'y i pobierać wyjścia, jest świetna, ale szybko przekonasz się, że jest kilka innych aspektów zarządzania workflow'em, które ułatwią Ci życie, szczególnie jeśli tworzysz własne workflow'y. + +Tutaj pokażemy Ci, jak używać funkcji `resume`, gdy musisz ponownie uruchomić ten sam workflow, jak przeglądać dziennik poprzednich wykonań za pomocą `nextflow log` i jak usuwać starsze katalogi work za pomocą `nextflow clean`. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. Uruchom ponownie workflow z `-resume` + +Czasami będziesz chciał ponownie uruchomić pipeline, który już wcześniej uruchomiłeś, bez powtarzania żadnych kroków, które już zakończyły się pomyślnie. + +Nextflow ma opcję o nazwie `-resume`, która pozwala to zrobić. +Konkretnie, w tym trybie wszelkie procesy, które już zostały uruchomione z dokładnie tym samym kodem, ustawieniami i wejściami, zostaną pominięte. +Oznacza to, że Nextflow uruchomi tylko procesy, które dodałeś lub zmodyfikowałeś od ostatniego uruchomienia, lub dla których dostarczasz nowe ustawienia lub wejścia. + +Są dwie kluczowe zalety takiego postępowania: + +- Jeśli jesteś w trakcie tworzenia swojego pipeline'u, możesz szybciej iterować, ponieważ musisz uruchamiać tylko proces(y), nad którymi aktywnie pracujesz, aby przetestować swoje zmiany. +- Jeśli uruchamiasz pipeline w produkcji i coś pójdzie nie tak, w wielu przypadkach możesz naprawić problem i ponownie uruchomić pipeline, a on wznowi działanie od punktu awarii, co może zaoszczędzić Ci dużo czasu i zasobów obliczeniowych. + +Aby jej użyć, po prostu dodaj `-resume` do swojego polecenia i uruchom go: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Wyjście konsoli powinno wyglądać znajomo, ale jest jedna rzecz, która jest nieco inna w porównaniu do poprzedniego. + +Szukaj części `cached:`, która została dodana 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 work jest taki sam jak w poprzednim uruchomieniu. +Nextflow dosłownie wskazuje Ci poprzednie wykonanie i mówi "Już to zrobiłem tam." + +!!! tip "Wskazówka" + + Gdy ponownie uruchamiasz pipeline z `resume`, Nextflow nie nadpisuje żadnych plików opublikowanych poza katalogiem work przez żadne wykonania, które zostały pomyślnie uruchomione wcześniej. + +### 4.2. Przeglądaj dziennik poprzednich wykonań + +Niezależnie od tego, czy tworzysz nowy pipeline, czy uruchamiasz pipeline'y w produkcji, w pewnym momencie prawdopodobnie będziesz musiał wyszukać informacje o poprzednich uruchomieniach. +Oto jak to zrobić. + +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. + +??? abstract "Zawartość pliku" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Ten plik zawiera znacznik czasu, nazwę uruchomienia, status, ID rewizji, ID sesji i pełny wiersz poleceń dla każdego uruchomienia Nextflow, które zostało uruchomione z bieżącego katalogu roboczego. + +Wygodniejszym sposobem uzyskania dostępu do tych informacji jest użycie polecenia `nextflow log`. + +```bash +nextflow log +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +To wyświetli zawartość pliku dziennika w terminalu, 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 sytuacji, gdy używasz opcji `-resume`. +W takim przypadku ID sesji pozostaje takie samo. + +Nextflow używa ID sesji do grupowania informacji o cache'owaniu uruchomień w katalogu `cache`, również znajdującym się w `.nextflow`. + +### 4.3. Usuń starsze katalogi work + +Podczas procesu tworzenia zazwyczaj uruchomisz swój szkic pipeline'u wiele razy, co może prowadzić do nagromadzenia wielu plików w wielu podkatalogach. + +Na szczęście Nextflow zawiera pomocne podpolecenie `clean`, które może automatycznie usunąć podkatalogi work dla poprzednich uruchomień, które już Cię nie interesują. + +#### 4.3.1. Określ kryteria usuwania + +Istnieje wiele [opcji](https://www.nextflow.io/docs/latest/reference/cli.html#clean) do określenia, co usunąć. + +Tutaj pokazujemy przykład, który usuwa wszystkie podkatalogi z uruchomień przed danym uruchomieniem, określonym za pomocą jego nazwy uruchomienia. + +Wyszukaj najnowsze pomyślne uruchomienie, w którym nie używałeś `-resume`; w naszym przypadku nazwa uruchomienia to `golden_cantor`. + +Nazwa uruchomienia to generowany maszynowo dwuczęściowy ciąg 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: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Wyjście polecenia" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +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 wyświetlonych linii, albo nie podałeś prawidłowej nazwy uruchomienia, albo nie ma poprzednich uruchomień do usunięcia. Upewnij się, że zmienisz `golden_cantor` w przykładowym poleceniu na odpowiednią najnowszą nazwę uruchomienia w Twoim dzienniku. + +#### 4.3.3. Kontynuuj z usuwaniem + +Jeśli wyjście wygląda zgodnie z oczekiwaniami i chcesz kontynuować usuwanie, uruchom polecenie ponownie z flagą `-f` zamiast `-n`: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Wyjście polecenia" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Wyjście powinno być podobne do poprzedniego, ale teraz mówi 'Removed' zamiast 'Would remove'. +Zauważ, że to nie usuwa dwuznakowych podkatalogów (jak `a3/` powyżej), ale opróżnia ich zawartość. + +!!! warning "Ostrzeżenie" + + Usunięcie podkatalogów work z poprzednich uruchomień usuwa je z cache'u Nextflow i usuwa wszelkie wyjścia, które były przechowywane w tych katalogach. + Oznacza to, że psuje to zdolność Nextflow do wznawiania wykonywania bez ponownego uruchamiania odpowiednich procesów. + + Jesteś odpowiedzialny za zapisywanie wszelkich wyjść, na których Ci zależy lub na których planujesz polegać! To jest główny powód, dla którego wolimy używać trybu `copy` zamiast trybu `symlink` dla dyrektywy `publish`. + +### Podsumowanie + +Wiesz, jak publikować wyjścia do określonego katalogu, ponownie uruchamiać pipeline bez powtarzania kroków, które już zostały uruchomione w identyczny sposób, i używać polecenia `nextflow clean` do czyszczenia starych katalogów work. + +Ogólniej rzecz biorąc, wiesz, jak interpretować prosty workflow Nextflow, zarządzać jego wykonywaniem i pobierać wyjścia. + +### Co dalej? + +Zrób sobie małą przerwę, zasłużyłeś na to! + +Gdy będziesz gotowy, przejdź do [**Części 2: Hello Channels**](./02_hello_channels.md), aby nauczyć się, jak używać kanałów do zasilania wejść do workflow'u, co pozwoli Ci skorzystać z wbudowanego równoległości przepływu danych Nextflow i innych potężnych funkcji. + +--- + +## Quiz + +<quiz> +Jakie są minimalne wymagane komponenty procesu Nextflow? +- [ ] Tylko bloki wejścia i wyjścia +- [x] Bloki wyjścia i script +- [ ] Bloki wejścia, wyjścia i script +- [ ] Tylko blok script + +Dowiedz się więcej: [1.1.1. Definicja process](#111-definicja-process) +</quiz> + +<quiz> +Jaki jest cel bloku output w procesie? +- [ ] Wypisywanie wyników do konsoli +- [ ] Zapisywanie plików do katalogu work +- [x] Deklarowanie oczekiwanych wyjść z procesu +- [ ] Definiowanie zmiennych środowiskowych + +Dowiedz się więcej: [1.1.1. Definicja process](#111-definicja-process) +</quiz> + +<quiz> +Jakiego polecenia używa się do uruchomienia workflow'u Nextflow? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Patrząc na katalog work zadania, który plik zawiera faktyczne polecenie, które zostało wykonane? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Dowiedz się więcej: [1.2.2. Znajdź wyjście i dzienniki w katalogu `work`](#122-znajdz-wyjscie-i-dzienniki-w-katalogu-work) +</quiz> + +<quiz> +Co robi flaga `-resume`? +- [ ] Restartuje workflow od początku +- [ ] Wstrzymuje workflow +- [x] Pomija procesy, które już zakończyły się pomyślnie +- [ ] Tworzy kopię zapasową workflow'u + +Dowiedz się więcej: [4.1. Uruchom ponownie workflow z `-resume`](#41-uruchom-ponownie-workflow-z--resume) +</quiz> + +<quiz> +Jaki jest domyślny tryb publikowania wyjść workflow'u? +- [ ] Kopiowanie plików do katalogu wyjściowego +- [x] Tworzenie dowiązań symbolicznych w katalogu wyjściowym +- [ ] Przenoszenie plików do katalogu wyjściowego +- [ ] Kompresowanie plików w katalogu wyjściowym + +Dowiedz się więcej: [2.3. Ustaw tryb publikowania na kopiowanie](#23-ustaw-tryb-publikowania-na-kopiowanie) +</quiz> + +<quiz> +Jak przekazujesz wartość parametru do workflow'u Nextflow z wiersza poleceń? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +Dowiedz się więcej: [3.2. Skonfiguruj parametr wiersza poleceń do przechwytywania danych wejściowych użytkownika](#32-skonfiguruj-parametr-wiersza-polecen-do-przechwytywania-danych-wejsciowych-uzytkownika) +</quiz> + +<quiz> +Jak odwołujesz się do zmiennej wewnątrz bloku script w Nextflow? +- [ ] Używa składni `%variable%` +- [x] Używa składni `#!groovy ${variable}` +- [ ] Używa składni `{{variable}}` +- [ ] Używa składni `[variable]` +</quiz> diff --git a/docs/pl/docs/hello_nextflow/02_hello_channels.md b/docs/pl/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..4e9cc84826 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Część 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Zobacz [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/02_hello_channels.md). +/// + +W Części 1 tego kursu (Hello World) pokazaliśmy Ci, jak dostarczyć zmienne wejście do procesu, podając je bezpośrednio w wywołaniu procesu: `sayHello(params.input)`. +To było celowo uproszczone podejście. +W praktyce to podejście ma poważne ograniczenia; mianowicie działa tylko dla bardzo prostych przypadków, gdy chcemy uruchomić proces tylko raz, na pojedynczej wartości. +W większości realistycznych przypadków użycia workflow'u chcemy przetwarzać wiele wartości (dane eksperymentalne dla wielu próbek, na przykład), więc potrzebujemy bardziej wyrafinowanego sposobu obsługi wejść. + +Do tego służą **kanały** Nextflow. +Kanały to kolejki zaprojektowane do efektywnej obsługi wejść i przekazywania ich z jednego kroku do drugiego w wieloetapowych workflow'ach, zapewniając jednocześnie wbudowaną równoległość i wiele dodatkowych korzyści. + +W tej części kursu nauczysz się, jak używać kanału do obsługi wielu wejść z różnych źródeł. +Nauczysz się również używać **operatorów** do transformowania zawartości kanału w razie potrzeby. + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś Część 1 kursu [Hello Nextflow](./index.md), ale jeśli czujesz się komfortowo z podstawami omówionymi w tej sekcji, możesz zacząć od tego miejsca bez robienia czegokolwiek specjalnego. + +--- + +## 0. Rozgrzewka: Uruchom `hello-channels.nf` + +Użyjemy skryptu workflow'u `hello-channels.nf` jako punktu wyjścia. +Jest on równoważny ze skryptem powstałym w wyniku pracy przez Część 1 tego kursu szkoleniowego, z wyjątkiem tego, że zmieniliśmy miejsce docelowe wyjścia: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Jak poprzednio, plik wyjściowy o nazwie `output.txt` znajdziesz w katalogu `results/hello_channels` (jak określono w bloku `output` skryptu workflow'u, pokazanym powyżej). + +??? abstract "Zawartość katalogu" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Zawartość pliku" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Jeśli to zadziałało, jesteś gotowy do nauki o kanałach. + +--- + +## 1. Dostarczaj zmienne wejścia przez kanał jawnie + +Zamierzamy utworzyć **kanał** do przekazania zmiennego wejścia do procesu `sayHello()` zamiast polegać na niejawnej obsłudze, która ma pewne ograniczenia. + +### 1.1. Utwórz kanał wejściowy + +Istnieje wiele **channel factories**, których możemy użyć do skonfigurowania kanału. +Aby na razie zachować prostotę, użyjemy najbardziej podstawowej channel factory o nazwie `channel.of`, która utworzy kanał zawierający pojedynczą wartość. +Funkcjonalnie będzie to podobne do tego, jak mieliśmy to skonfigurowane wcześniej, ale zamiast tego, żeby Nextflow tworzył kanał niejawnie, robimy to teraz jawnie. + +Oto linia kodu, której użyjemy: + +```console title="Składnia" +greeting_ch = channel.of('Hello Channels!') +``` + +To tworzy kanał o nazwie `greeting_ch` używając channel factory `channel.of()`, która konfiguruje prosty kanał kolejki, i ładuje ciąg `'Hello Channels!'` jako wartość pozdrowienia. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Uwaga" + + Tymczasowo wracamy do zakodowanych na sztywno ciągów zamiast używać parametru CLI ze względu na czytelność. Wrócimy do używania parametrów CLI, gdy omówimy, co dzieje się na poziomie kanału. + +W bloku workflow dodaj kod channel factory: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels!') + // wyemituj pozdrowienie + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // wyemituj pozdrowienie + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +To jeszcze nie jest funkcjonalne, ponieważ nie przełączyliśmy jeszcze wejścia do wywołania procesu. + +### 1.2. Dodaj kanał jako wejście do wywołania procesu + +Teraz musimy faktycznie podłączyć nasz nowo utworzony kanał do wywołania procesu `sayHello()`, zastępując parametr CLI, który podawaliśmy bezpośrednio wcześniej. + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels!') + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels!') + // wyemituj pozdrowienie + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +To mówi Nextflow, aby uruchomił proces `sayHello` na zawartości kanału `greeting_ch`. + +Teraz nasz workflow jest właściwie funkcjonalny; jest jawnym odpowiednikiem napisania `sayHello('Hello Channels!')`. + +### 1.3. Uruchom workflow + +Uruchommy to! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Jeśli wprowadziłeś obie edycje poprawnie, powinieneś uzyskać pomyślne wykonanie. +Możesz sprawdzić katalog wyników, aby upewnić się, że wynik jest nadal taki sam jak poprzednio. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Zwiększyliśmy więc elastyczność naszego workflow'u, osiągając ten sam końcowy wynik. +Może się wydawać, że piszemy więcej kodu bez wymiernej korzyści, ale wartość stanie się jasna, gdy tylko zaczniemy obsługiwać więcej wejść. + +Jako podgląd tego, spójrzmy na jeszcze jedną rzecz, zanim przejdziemy dalej: jedną małą, ale wygodną korzyść z używania jawnego kanału do zarządzania wejściem danych. + +### 1.4. Użyj `view()` do inspekcji zawartości kanału + +Kanały Nextflow są zbudowane w sposób, który pozwala nam operować na ich zawartości za pomocą operatorów, które omówimy szczegółowo później w tym rozdziale. + +Na razie pokażemy Ci tylko, jak używać super prostego operatora o nazwie [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) do inspekcji zawartości kanału. +Możesz myśleć o `view()` jako o narzędziu do debugowania, jak instrukcja `print()` w Pythonie lub jej odpowiednik w innych językach. + +Dodaj tę małą linię do bloku workflow: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels!') + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels!') + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Dokładna liczba spacji nie ma znaczenia, o ile jest wielokrotnością 4; dążymy tylko do wyrównania początku instrukcji `.view()` do części `.of()` konstrukcji kanału. + +Teraz uruchom workflow ponownie: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Jak widzisz, to wyświetla zawartość kanału do konsoli. +Tutaj mamy tylko jeden element, ale gdy zaczniemy ładować wiele wartości do kanału w następnej sekcji, zobaczysz, że jest ustawione na wyświetlanie jednego elementu na linię. + +### Podsumowanie + +Wiesz, jak używać podstawowej channel factory do dostarczenia wejścia do procesu. + +### Co dalej? + +Naucz się używać kanałów, aby workflow iterował po wielu wartościach wejściowych. + +--- + +## 2. Zmodyfikuj workflow, aby działał na wielu wartościach wejściowych + +Workflow'y zazwyczaj działają na partiach wejść, które mają być przetwarzane masowo, więc chcemy ulepszyć workflow, aby akceptował wiele wartości wejściowych. + +### 2.1. Załaduj wiele pozdrowień do kanału wejściowego + +Dogodnie, channel factory `channel.of()`, której używamy, chętnie przyjmuje więcej niż jedną wartość, więc nie musimy jej w ogóle modyfikować. +Możemy po prostu załadować wiele wartości do kanału. + +Niech to będą `'Hello'`, `'Bonjour'` i `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Na diagramie kanał jest reprezentowany na zielono, a kolejność elementów jest reprezentowana jak kulki w rurze: pierwsza załadowana jest po prawej, potem druga w środku, potem trzecia po lewej._ + +#### 2.1.1. Dodaj więcej pozdrowień + +Przed blokiem workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +Dokumentacja mówi, że to powinno działać. Czy to naprawdę może być takie proste? + +#### 2.1.2. Uruchom polecenie i spójrz na wyjście dziennika + +Sprawdźmy. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Z pewnością wygląda na to, że uruchomił się bez problemów. +Monitor wykonywania pokazuje, że `3 of 3` wywołania zostały wykonane dla procesu `sayHello`, i widzimy trzy pozdrowienia wyliczone przez instrukcję `view()`, jedno na linię, jak obiecano. + +Jednak w katalogu wyników nadal jest tylko jedno wyjście: + +??? abstract "Zawartość katalogu" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Zawartość pliku" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Powinieneś zobaczyć tam jedno z trzech pozdrowień, ale to, które otrzymałeś, może być inne niż pokazane tutaj. +Czy możesz się domyślić, dlaczego tak może być? + +Patrząc wstecz na monitor wykonywania, dał nam tylko jedną ścieżkę podkatalogu (`f4/c9962c`). +Zajrzyjmy tam. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Zawartość pliku" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +To nawet nie jest to samo pozdrowienie, które mamy w katalogu wyników! Co się dzieje? + +W tym momencie musimy Ci powiedzieć, że domyślnie system logowania ANSI zapisuje logowanie z wielu wywołań do tego samego procesu w tej samej linii. +Więc status ze wszystkich trzech wywołań procesu sayHello() ląduje w tym samym miejscu. + +Na szczęście możemy wyłączyć to zachowanie, aby zobaczyć pełną listę wywołań procesów. + +#### 2.1.3. Uruchom polecenie ponownie z opcją `-ansi-log false` + +Aby rozwinąć logowanie do wyświetlania jednej linii na wywołanie procesu, dodaj `-ansi-log false` do polecenia. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Tym razem widzimy wszystkie trzy uruchomienia procesów i ich powiązane podkatalogi work wymienione w wyjściu. + +To znacznie lepiej, przynajmniej dla prostego workflow'u. +Dla złożonego workflow'u lub dużej liczby wejść, posiadanie pełnej listy wyświetlanej w terminalu byłoby nieco przytłaczające. +Dlatego `-ansi-log false` nie jest domyślnym zachowaniem. + +!!! tip "Wskazówka" + + Sposób raportowania statusu jest nieco inny między dwoma trybami logowania. + W trybie skondensowanym Nextflow raportuje, czy wywołania zakończyły się pomyślnie, czy nie. + W tym rozwiniętym trybie raportuje tylko, że zostały przesłane. + +W każdym razie, teraz mamy podkatalogi każdego wywołania procesu, możemy szukać ich logów i wyjść. + +??? abstract "Zawartość katalogu" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Zawartość pliku" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +To pokazuje, że wszystkie trzy procesy uruchomiły się pomyślnie (juhu). + +To powiedziawszy, nadal mamy problem, że w katalogu wyników jest tylko jeden plik wyjściowy. + +Możesz pamiętać, że zakodowaliśmy na sztywno nazwę pliku wyjściowego dla procesu `sayHello`, więc wszystkie trzy wywołania utworzyły plik o nazwie `output.txt`. + +Dopóki pliki wyjściowe pozostają w podkatalogach work, odizolowane od innych procesów, jest to w porządku. +Ale gdy są publikowane do tego samego katalogu wyników, którykolwiek został tam skopiowany jako pierwszy, jest nadpisywany przez następny, i tak dalej. + +### 2.2. Upewnij się, że nazwy plików wyjściowych będą unikalne + +Możemy kontynuować publikowanie wszystkich wyjść do tego samego katalogu wyników, ale musimy upewnić się, że będą miały unikalne nazwy. +Konkretnie, musimy zmodyfikować pierwszy proces, aby generował nazwę pliku dynamicznie, tak aby końcowe nazwy plików były unikalne. + +Więc jak sprawić, żeby nazwy plików były unikalne? +Powszechnym sposobem na to jest użycie jakiegoś unikalnego fragmentu metadanych z wejść (otrzymanych z kanału wejściowego) jako części nazwy pliku wyjściowego. +Tutaj, dla wygody, użyjemy po prostu samego pozdrowienia, ponieważ to tylko krótki ciąg, i dodamy go na początku podstawowej nazwy pliku wyjściowego. + +#### 2.2.1. Skonstruuj dynamiczną nazwę pliku wyjściowego + +W bloku procesu wprowadź następujące zmiany kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Upewnij się, że zastąpisz `output.txt` zarówno w definicji output, jak i w bloku polecenia `script:`. + +!!! tip "Wskazówka" + + W definicji output MUSISZ użyć podwójnych cudzysłowów wokół wyrażenia nazwy pliku wyjściowego (NIE pojedynczych cudzysłowów), w przeciwnym razie to się nie powiedzie. + +To powinno generować unikalną nazwę pliku wyjściowego za każdym razem, gdy proces jest wywoływany, tak aby można go było odróżnić od wyjść z innych wywołań tego samego procesu w katalogu wyjściowym. + +#### 2.2.2. Uruchom workflow + +Uruchommy to. Zauważ, że wracamy do uruchamiania z domyślnymi ustawieniami logu ANSI. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Wracając do widoku podsumowania, wyjście jest ponownie podsumowane w jednej linii. +Spójrz na katalog `results`, aby zobaczyć, czy wszystkie wyjściowe pozdrowienia tam są. + +??? abstract "Zawartość katalogu" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Tak! I każdy ma oczekiwaną zawartość. + +??? abstract "Zawartość pliku" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Sukces! Teraz możemy dodawać tyle pozdrowień, ile chcemy, bez martwienia się o nadpisywanie plików wyjściowych. + +!!! tip "Wskazówka" + + W praktyce nazywanie plików na podstawie samych danych wejściowych jest prawie zawsze niepraktyczne. + Lepszym sposobem na generowanie dynamicznych nazw plików jest przekazywanie metadanych do procesu wraz z plikami wejściowymi. + Metadane są zazwyczaj dostarczane przez 'arkusz próbek' lub odpowiedniki. + Nauczysz się, jak to zrobić później w swoim szkoleniu Nextflow (zobacz [Side quest dotyczący metadanych](../side_quests/metadata.md)). + +### Podsumowanie + +Wiesz, jak przeprowadzać wiele elementów wejściowych przez kanał. + +### Co dalej? + +Naucz się używać operatora do transformowania zawartości kanału. + +--- + +## 3. Dostarcz wiele wejść przez tablicę + +Właśnie pokazaliśmy Ci, jak obsługiwać wiele elementów wejściowych, które były zakodowane na sztywno bezpośrednio w channel factory. +Co jeśli chcielibyśmy dostarczyć te wiele wejść w inny sposób? + +Na przykład, wyobraź sobie, że skonfigurowaliśmy zmienną wejściową zawierającą tablicę elementów w ten sposób: + +`greetings_array = ['Hello','Bonjour','Holà']` + +Czy możemy załadować to do naszego kanału wyjściowego i oczekiwać, że zadziała? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Dowiedzmy się. + +### 3.1. Dostarcz tablicę wartości jako wejście do kanału + +Zdrowy rozsądek sugeruje, że powinniśmy móc po prostu przekazać tablicę wartości zamiast pojedynczej wartości. +Spróbujmy; będziemy musieli skonfigurować zmienną wejściową i załadować ją do channel factory. + +#### 3.1.1. Skonfiguruj zmienną wejściową + +Weźmy zmienną `greetings_array`, którą właśnie sobie wyobraziłeś, i uczyńmy ją rzeczywistością, dodając ją do bloku workflow: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +To jeszcze nie jest funkcjonalne, dodaliśmy tylko deklarację tablicy. + +#### 3.1.2. Ustaw tablicę pozdrowień jako wejście do channel factory + +Teraz zamierzamy zastąpić wartości `'Hello','Bonjour','Holà'` aktualnie zakodowane na sztywno w channel factory tablicą `greetings_array`, którą właśnie utworzyliśmy. + +W bloku workflow wprowadź następującą zmianę: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +To powinno być teraz funkcjonalne. + +#### 3.1.3. Uruchom workflow + +Spróbujmy go uruchomić: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Wyjście polecenia" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +O nie! Jest błąd! + +Spójrz na wyjście `view()` i komunikaty o błędach. + +Wygląda na to, że Nextflow próbował uruchomić pojedyncze wywołanie procesu, używając `[Hello, Bonjour, Holà]` jako wartości ciągu, zamiast używać trzech ciągów w tablicy jako osobnych wartości. + +Więc to 'opakowanie' powoduje problem. +Jak sprawić, żeby Nextflow rozpakował tablicę i załadował poszczególne ciągi do kanału? + +### 3.2. Użyj operatora do transformowania zawartości kanału + +Tutaj wchodzą do gry **[operatory](https://www.nextflow.io/docs/latest/reference/operator.html)**. +Już używałeś operatora `.view()`, który po prostu patrzy na to, co tam jest. +Teraz przyjrzymy się operatorom, które pozwalają nam działać na zawartości kanału. + +Jeśli przejrzysz [listę operatorów](https://www.nextflow.io/docs/latest/reference/operator.html) w dokumentacji Nextflow, znajdziesz [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), który robi dokładnie to, czego potrzebujemy: rozpakowuje zawartość tablicy i emituje je jako pojedyncze elementy. + +#### 3.2.1. Dodaj operator `flatten()` + +Aby zastosować operator `flatten()` do naszego kanału wejściowego, dodajemy go do deklaracji channel factory. + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Tutaj dodaliśmy operator w następnej linii dla czytelności, ale możesz dodać operatory w tej samej linii co channel factory, jeśli wolisz, w ten sposób: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Doprecyzuj instrukcje `view()` + +Moglibyśmy uruchomić to od razu, aby sprawdzić, czy działa, ale przy okazji doprecyzujemy sposób, w jaki sprawdzamy zawartość kanału. + +Chcemy móc porównać, jak zawartość wygląda przed i po zastosowaniu operatora `flatten()`, więc dodamy drugą instrukcję I dodamy trochę kodu, aby były wyraźniej oznaczone w wyjściu. + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Widzisz, że dodaliśmy drugą instrukcję `.view`, a dla każdej z nich zastąpiliśmy puste nawiasy (`()`) nawiasami klamrowymi zawierającymi kod, taki jak `{ greeting -> "Before flatten: $greeting" }`. + +Są to tak zwane _closures_. Kod, który zawierają, będzie wykonywany dla każdego elementu w kanale. +Definiujemy tymczasową zmienną dla wewnętrznej wartości, tutaj nazwaną `greeting` (ale mogłaby mieć dowolną nazwę), która jest używana tylko w zakresie tej closure. + +W tym przykładzie `$greeting` reprezentuje każdy pojedynczy element załadowany do kanału. +To spowoduje ładnie oznaczone wyjście konsoli. + +!!! info "Informacja" + + W niektórych pipeline'ach możesz zobaczyć specjalną zmienną o nazwie `$it` używaną wewnątrz closures operatorów. + Jest to _niejawna_ zmienna, która pozwala na skrócony dostęp do wewnętrznej zmiennej, + bez potrzeby definiowania jej za pomocą `->`. + + Preferujemy być jawni, aby pomóc w czytelności kodu, więc składnia `$it` jest odradzana i będzie stopniowo wycofywana z języka Nextflow. + +#### 3.2.3. Uruchom workflow + +W końcu możesz spróbować uruchomić workflow ponownie! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Tym razem działa I daje nam dodatkowy wgląd w to, jak zawartość kanału wygląda przed i po uruchomieniu operatora `flatten()`. + +- Widzisz, że otrzymujemy pojedynczą instrukcję `Before flatten:`, ponieważ w tym momencie kanał zawiera jeden element, oryginalną tablicę. + Następnie otrzymujemy trzy oddzielne instrukcje `After flatten:`, jedną dla każdego pozdrowienia, które są teraz pojedynczymi elementami w kanale. + +Co ważne, oznacza to, że każdy element może być teraz przetwarzany osobno przez workflow. + +!!! tip "Wskazówka" + + Technicznie możliwe jest osiągnięcie tych samych wyników przez użycie innej channel factory, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), która zawiera niejawny krok mapowania w swojej operacji. + Tutaj zdecydowaliśmy się tego nie używać, aby zademonstrować użycie operatora na prostym przypadku użycia. + +### Podsumowanie + +Wiesz, jak używać operatora takiego jak `flatten()` do transformowania zawartości kanału i jak używać operatora `view()` do inspekcji zawartości kanału przed i po zastosowaniu operatora. + +### Co dalej? + +Naucz się, jak sprawić, żeby workflow przyjmował plik jako źródło wartości wejściowych. + +--- + +## 4. Odczytaj wartości wejściowe z pliku CSV + +Realistycznie rzecz biorąc, rzadko, jeśli w ogóle, będziemy zaczynać od tablicy wartości. +Najprawdopodobniej będziemy mieć jeden lub więcej plików zawierających dane, które muszą być przetworzone, w jakimś rodzaju strukturyzowanego formatu. + +Przygotowaliśmy plik CSV o nazwie `greetings.csv`, który zawiera kilka pozdrowień wejściowych, naśladując rodzaj danych kolumnowych, które możesz chcieć przetworzyć w rzeczywistej analizie danych, przechowywany w `data/`. +(Liczby nie mają znaczenia, są tam tylko w celach ilustracyjnych.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Naszym następnym zadaniem jest dostosowanie naszego workflow'u do odczytania wartości z tego pliku. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Zobaczmy, jak możemy to zrobić. + +### 4.1. Zmodyfikuj skrypt, aby oczekiwał pliku CSV jako źródła pozdrowień + +Aby zacząć, musimy wprowadzić dwie kluczowe zmiany w skrypcie: + +- Przełączyć parametr wejściowy, aby wskazywał na plik CSV +- Przełączyć channel factory na taką, która jest zaprojektowana do obsługi pliku + +#### 4.1.1. Przełącz parametr wejściowy, aby wskazywał na plik CSV + +Pamiętasz parametr `params.input`, który skonfigurowaliśmy w Części 1? +Zaktualizujemy go, aby wskazywał na plik CSV zawierający nasze pozdrowienia. + +Wprowadź następującą edycję deklaracji parametru: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + input: String = 'Holà mundo!' + ``` + +To zakłada, że plik jest współlokalizowany z kodem workflow'u. +Nauczysz się, jak radzić sobie z innymi lokalizacjami danych później w swojej podróży z Nextflow. + +#### 4.1.2. Przełącz na channel factory zaprojektowaną do obsługi pliku + +Ponieważ teraz chcemy użyć pliku zamiast prostych ciągów jako wejścia, nie możemy użyć channel factory `channel.of()` z poprzedniego. +Musimy przełączyć się na użycie nowej channel factory, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), która ma wbudowaną funkcjonalność do obsługi ścieżek plików. + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // utwórz kanał dla danych wejściowych from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // zadeklaruj tablicę pozdrowień wejściowych + greetings_array = ['Hello','Bonjour','Holà'] + // utwórz kanał dla danych wejściowych + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Zauważysz, że przełączyliśmy wejście kanału z powrotem na `param.input` i usunęliśmy deklarację `greetings_array`, ponieważ nie będziemy już jej potrzebować. +Zakomentowaliśmy też `flatten()` i drugą instrukcję `view()`. + +#### 4.1.3. Uruchom workflow + +Spróbujmy uruchomić workflow z nową channel factory i plikiem wejściowym. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Wyjście polecenia" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +O nie, to nie działa. Spójrz na początek wyjścia konsoli i komunikat o błędzie. +Część `Command executed:` jest tu szczególnie pomocna. + +To może wyglądać trochę znajomo. +Wygląda na to, że Nextflow próbował uruchomić pojedyncze wywołanie procesu, używając samej ścieżki pliku jako wartości ciągu. +Więc poprawnie rozpoznał ścieżkę pliku, ale faktycznie nie sparsował jego zawartości, czego chcieliśmy. + +Jak sprawić, żeby Nextflow otworzył plik i załadował jego zawartość do kanału? + +Brzmi jakbyśmy potrzebowali kolejnego [operatora](https://www.nextflow.io/docs/latest/reference/operator.html)! + +### 4.2. Użyj operatora `splitCsv()` do parsowania pliku + +Przeglądając ponownie listę operatorów, znajdujemy [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), który jest zaprojektowany do parsowania i dzielenia tekstu w formacie CSV. + +#### 4.2.1. Zastosuj `splitCsv()` do kanału + +Aby zastosować operator, dodajemy go do linii channel factory, jak poprzednio. + +W bloku workflow wprowadź następującą zmianę kodu, aby zastąpić `flatten()` (zakomentowane) przez `splitCsv()`: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // utwórz kanał dla danych wejściowych from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // utwórz kanał dla danych wejściowych from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Jak widzisz, zaktualizowaliśmy też instrukcje before/after `view()`. +Technicznie mogliśmy użyć tej samej nazwy zmiennej (`greeting`), ale zaktualizowaliśmy ją na coś bardziej odpowiedniego (`csv`), aby kod był bardziej czytelny dla innych. + +#### 4.2.2. Uruchom workflow ponownie + +Spróbujmy uruchomić workflow z dodaną logiką parsowania CSV. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Wyjście polecenia" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Co ciekawe, to też się nie udaje, ale z innym błędem. +Tym razem Nextflow sparsował zawartość pliku (juhu!), ale załadował każdy wiersz jako tablicę, a każda tablica jest elementem w kanale. + +Musimy mu powiedzieć, żeby wziął tylko pierwszą kolumnę w każdym wierszu. +Więc jak to rozpakować? + +Wcześniej użyliśmy `flatten()` do rozpakowania zawartości kanału, ale to by tu nie zadziałało, ponieważ flatten rozpakowuje _wszystko_ (możesz spróbować sam, jeśli chcesz zobaczyć na własne oczy). + +Zamiast tego użyjemy innego operatora o nazwie `map()`, który jest naprawdę użyteczny i pojawia się często w pipeline'ach Nextflow. + +### 4.3. Użyj operatora `map()` do wyodrębnienia pozdrowień + +Operator [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) to bardzo poręczne małe narzędzie, które pozwala nam robić różne mapowania na zawartości kanału. + +W tym przypadku użyjemy go do wyodrębnienia tego jednego elementu, który chcemy z każdego wiersza w naszym pliku danych. +Oto jak wygląda składnia: + +```groovy title="Składnia" +.map { row -> row[0] } +``` + +Oznacza to 'dla każdego wiersza w kanale, weź 0-ty (pierwszy) element, który zawiera'. + +Więc zastosujmy to do naszego parsowania CSV. + +#### 4.3.1. Zastosuj `map()` do kanału + +W bloku workflow wprowadź następującą zmianę kodu: + +=== "Po" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // utwórz kanał dla danych wejściowych from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // utwórz kanał dla danych wejściowych from a CSV file + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Widzisz, że dodaliśmy kolejne wywołanie `view()`, aby potwierdzić, że operator robi to, czego oczekujemy. + +#### 4.3.2. Uruchom workflow + +Uruchommy to jeszcze raz: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Tym razem powinno się uruchomić bez błędu. + +Patrząc na wyjście instrukcji `view()`, widzisz następujące rzeczy: + +- Pojedynczą instrukcję `Before splitCsv:`: w tym momencie kanał zawiera jeden element, oryginalną ścieżkę pliku. +- Trzy oddzielne instrukcje `After splitCsv:`: jedną dla każdego pozdrowienia, ale każde jest zawarte w tablicy odpowiadającej tej linii w pliku. +- Trzy oddzielne instrukcje `After map:`: jedną dla każdego pozdrowienia, które są teraz pojedynczymi elementami w kanale. + +Zauważ, że linie mogą pojawiać się w innej kolejności w Twoim wyjściu. + +Możesz też spojrzeć na pliki wyjściowe, aby zweryfikować, że każde pozdrowienie zostało poprawnie wyodrębnione i przetworzone przez workflow. + +Osiągnęliśmy ten sam wynik co poprzednio, ale teraz mamy znacznie większą elastyczność, aby dodawać więcej elementów do kanału pozdrowień, które chcemy przetworzyć, modyfikując plik wejściowy, bez modyfikowania żadnego kodu. +Nauczysz się bardziej zaawansowanych podejść do obsługi złożonych wejść w późniejszym szkoleniu. + +### Podsumowanie + +Wiesz, jak używać konstruktora kanału `.fromPath()` i operatorów `splitCsv()` oraz `map()` do wczytania pliku wartości wejściowych i odpowiedniego ich obsłużenia. + +Ogólniej rzecz biorąc, masz podstawowe zrozumienie tego, jak Nextflow używa **kanałów** do zarządzania wejściami do procesów i **operatorów** do transformowania ich zawartości. + +### Co dalej? + +Zrób sobie dużą przerwę, ciężko pracowałeś w tej części! + +Gdy będziesz gotowy, przejdź do [**Części 3: Hello Workflow**](./03_hello_workflow.md), aby nauczyć się, jak dodawać więcej kroków i łączyć je w prawdziwy workflow. + +--- + +## Quiz + +<quiz> +Czym jest kanał w Nextflow? +- [ ] Specyfikacją ścieżki pliku +- [ ] Definicją procesu +- [x] Strukturą podobną do kolejki do przekazywania danych między procesami +- [ ] Ustawieniem konfiguracji + +Dowiedz się więcej: [1.1. Utwórz kanał wejściowy](#11-utworz-kanal-wejsciowy) +</quiz> + +<quiz> +Co wyświetli ten kod? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (pojedyncza lista) +- [x] Każdy element w osobnej linii: `Hello`, `Bonjour`, `Hola` +- [ ] Nic (kanały domyślnie nie wypisują) +- [ ] Błąd (nieprawidłowa składnia) + +Dowiedz się więcej: [1.1. Utwórz kanał wejściowy](#11-utworz-kanal-wejsciowy) +</quiz> + +<quiz> +Gdy kanał zawiera wiele wartości, jak Nextflow obsługuje wykonywanie procesu? +- [ ] Proces uruchamia się raz ze wszystkimi wartościami +- [x] Proces uruchamia się raz dla każdej wartości w kanale +- [ ] Proces uruchamia się tylko z pierwszą wartością +- [ ] Proces uruchamia się tylko z ostatnią wartością + +Dowiedz się więcej: [2. Zmodyfikuj workflow, aby działał na wielu wartościach wejściowych](#2-zmodyfikuj-workflow-aby-dzialal-na-wielu-wartosciach-wejsciowych) +</quiz> + +<quiz> +Co robi operator `flatten()`? +- [ ] Łączy wiele kanałów w jeden +- [ ] Sortuje elementy kanału +- [x] Rozpakowuje tablice na pojedyncze elementy +- [ ] Usuwa duplikaty elementów + +Dowiedz się więcej: [3.2.1. Dodaj operator `flatten()`](#321-dodaj-operator-flatten) +</quiz> + +<quiz> +Jaki jest cel operatora `view()`? +- [ ] Filtrowanie zawartości kanału +- [ ] Transformowanie elementów kanału +- [x] Inspekcja i debugowanie zawartości kanału +- [ ] Zapisywanie zawartości kanału do pliku + +Dowiedz się więcej: [1.4. Użyj `view()` do inspekcji zawartości kanału](#14-uzyj-view-do-inspekcji-zawartosci-kanalu) +</quiz> + +<quiz> +Co robi `splitCsv()`? +- [ ] Tworzy plik CSV z zawartości kanału +- [ ] Dzieli ciąg przez przecinki +- [x] Parsuje plik CSV na tablice reprezentujące każdy wiersz +- [ ] Łączy wiele plików CSV + +Dowiedz się więcej: [4.2. Użyj operatora `splitCsv()` do parsowania pliku](#42-uzyj-operatora-splitcsv-do-parsowania-pliku) +</quiz> + +<quiz> +Jaki jest cel operatora `map()`? +- [ ] Filtrowanie elementów z kanału +- [ ] Łączenie wielu kanałów +- [x] Transformowanie każdego elementu w kanale +- [ ] Liczenie elementów w kanale + +Dowiedz się więcej: [4.3. Użyj operatora `map()` do wyodrębnienia pozdrowień](#43-uzyj-operatora-map-do-wyodrebnienia-pozdrowien) +</quiz> + +<quiz> +Dlaczego ważne jest używanie dynamicznych nazw plików wyjściowych przy przetwarzaniu wielu wejść? +- [ ] Aby poprawić wydajność +- [ ] Aby zmniejszyć zużycie miejsca na dysku +- [x] Aby zapobiec nadpisywaniu plików wyjściowych przez siebie nawzajem +- [ ] Aby włączyć funkcjonalność resume + +Dowiedz się więcej: [2.2. Upewnij się, że nazwy plików wyjściowych będą unikalne](#22-upewnij-sie-ze-nazwy-plikow-wyjsciowych-beda-unikalne) +</quiz> diff --git a/docs/pl/docs/hello_nextflow/03_hello_workflow.md b/docs/pl/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..d8fc5d025f --- /dev/null +++ b/docs/pl/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Część 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Obejrzyj [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/03_hello_workflow.md). +/// + +Większość rzeczywistych workflow składa się z więcej niż jednego kroku. +W tym module szkoleniowym nauczysz się łączyć procesy w wieloetapowy workflow. + +Poznasz następujące techniki Nextflow: + +1. Przekazywanie danych z jednego procesu do następnego +2. Zbieranie wyjść z wielu wywołań procesu do pojedynczego wywołania +3. Przekazywanie więcej niż jednego wejścia do procesu +4. Obsługa wielu wyjść z procesu + +Dla demonstracji będziemy kontynuować rozbudowę domenowo-agnostycznego przykładu Hello World z Części 1 i 2. +Tym razem wprowadzimy następujące zmiany w naszym workflow, aby lepiej odzwierciedlić sposób budowania rzeczywistych workflow: + +1. Dodamy drugi krok, który konwertuje pozdrowienie na wielkie litery. +2. Dodamy trzeci krok, który zbiera wszystkie przekształcone pozdrowienia i zapisuje je do pojedynczego pliku. +3. Dodamy parametr do nazwania końcowego pliku wyjściowego i przekażemy go jako dodatkowe wejście do kroku zbierania. +4. Sprawimy, że krok zbierania będzie również raportował prostą statystykę o tym, co zostało przetworzone. + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś Części 1-2 kursu [Hello Nextflow](./index.md), ale jeśli znasz podstawy omówione w tych sekcjach, możesz zacząć od tego miejsca bez żadnych dodatkowych przygotowań. + +--- + +## 0. Rozgrzewka: Uruchom `hello-workflow.nf` + +Użyjemy skryptu workflow `hello-workflow.nf` jako punktu wyjścia. +Jest on równoważny skryptowi utworzonemu podczas pracy nad Częścią 2 tego szkolenia, z tą różnicą, że usunęliśmy instrukcje `view()` i zmieniliśmy miejsce docelowe wyjścia: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Jak poprzednio, pliki wyjściowe znajdziesz w lokalizacji określonej w bloku `output`. +W tym rozdziale jest to katalog `results/hello_workflow/`. + +??? abstract "Zawartość katalogu" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Jeśli to zadziałało, jesteś gotowy do nauki składania wieloetapowego workflow. + +--- + +## 1. Dodaj drugi krok do workflow + +Dodamy krok konwertujący każde pozdrowienie na wielkie litery. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +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 workflow i skonfigurować go tak, aby przyjmował wyjście procesu `sayHello()` jako wejście. + +### 1.1. Zdefiniuj polecenie konwersji na wielkie litery i przetestuj je w terminalu + +Do konwersji pozdrowień na wielkie litery użyjemy klasycznego narzędzia UNIX o nazwie `tr` (od 'text replacement'), z następującą składnią: + +```bash title="Składnia" +tr '[a-z]' '[A-Z]' +``` + +Jest to bardzo prosty one-liner do zamiany tekstu, który nie uwzględnia liter z akcentami, więc na przykład 'Holà' zostanie zamienione na 'HOLà', ale wystarczająco dobrze posłuży do demonstracji koncepcji Nextflow i to jest najważniejsze. + +Aby to przetestować, możemy uruchomić polecenie `echo 'Hello World'` i przekierować jego wyjście do polecenia `tr`: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +Wyjściem jest plik tekstowy o nazwie `UPPER-output.txt`, który zawiera wersję ciągu `Hello World` napisaną wielkimi literami. + +??? abstract "Zawartość pliku" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +To właśnie zamierzamy zrobić w naszym workflow. + +### 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, tuż pod pierwszym procesem: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Użyj narzędzia zamiany tekstu do przekształcenia pozdrowienia na wielkie litery + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +W tym procesie komponujemy nazwę drugiego pliku wyjściowego na podstawie nazwy pliku wejściowego, podobnie jak zrobiliśmy to oryginalnie dla wyjścia pierwszego procesu. + +### 1.3. Dodaj wywołanie nowego procesu w bloku workflow + +Teraz musimy powiedzieć Nextflow, aby faktycznie wywołał proces, który właśnie zdefiniowaliśmy. + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +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()` trafiało do procesu `convertToUpper()`. + +Wygodnie jest to, że Nextflow automatycznie pakuje wyjście procesu do channel o nazwie `<process>.out`. +Więc wyjście procesu `sayHello` to channel o nazwie `sayHello.out`, który możemy bezpośrednio podłączyć do wywołania `convertToUpper()`. + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // przekształć pozdrowienie na wielkie litery + convertToUpper() + ``` + +Dla prostego przypadku takiego 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 + +Na koniec zaktualizujmy wyjścia workflow, aby publikować również wyniki z drugiego procesu. + +#### 1.5.1. Zaktualizuj sekcję `publish:` bloku `workflow` + +W bloku `workflow` wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +Logika jest taka sama jak poprzednio. + +#### 1.5.2. Zaktualizuj blok `output` + +W bloku `output` wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +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. +Spróbuj zmienić ścieżki lub tryb publikacji 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, jeśli chcielibyśmy zaktualizować lokalizację dla wszystkich wyjść w ten sam sposób. +Później w kursie dowiesz się, jak konfigurować te ustawienia dla wielu wyjść w uporządkowany sposób. + +### 1.6. Uruchom workflow z `-resume` + +Przetestujmy to używając flagi `-resume`, ponieważ już pomyślnie uruchomiliśmy pierwszy krok workflow. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +W wyniku konsoli pojawia się teraz dodatkowa linia odpowiadająca nowemu procesowi, który właśnie dodaliśmy. + +Wyjścia znajdziesz w katalogu `results/hello_workflow` zgodnie z ustawieniami w bloku `output`. + +??? abstract "Zawartość katalogu" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +To wygodne! Ale warto też zajrzeć do katalogu roboczego jednego z wywołań drugiego procesu. + +??? abstract "Zawartość katalogu" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Zauważ, że są tam dwa pliki `*-output`: wyjście pierwszego procesu oraz wyjście drugiego. + +Wyjście pierwszego procesu znajduje się tam, ponieważ Nextflow **przygotował** (ang. _staged_) je tam, aby mieć wszystko potrzebne do wykonania w tym samym podkatalogu. + +Jednak w rzeczywistości jest to dowiązanie symboliczne wskazujące na oryginalny plik w podkatalogu wywołania pierwszego procesu. +Domyślnie, podczas uruchamiania na pojedynczej maszynie, jak to robimy tutaj, Nextflow używa dowiązań symbolicznych zamiast kopii do przygotowywania plików wejściowych i pośrednich. + +Teraz, zanim przejdziemy dalej, pomyśl o tym, jak wszystko, co zrobiliśmy, to połączenie wyjścia `sayHello` z wejściem `convertToUpper` i dwa procesy mogły być uruchomione szeregowo. +Nextflow wykonał za nas ciężką pracę związaną z obsługą poszczególnych plików wejściowych i wyjściowych oraz przekazywaniem ich między dwoma poleceniami. + +To jeden z powodów, dla których channels w Nextflow są tak potężne: zajmują się rutynową pracą związaną z łączeniem kroków workflow. + +### Podsumowanie + +Wiesz już, jak łączyć procesy w łańcuch, przekazując wyjście jednego kroku jako wejście do następnego. + +### Co dalej? + +Dowiedz się, jak zbierać wyjścia z wielu wywołań procesu i przekazywać je do pojedynczego procesu. + +--- + +## 2. Dodaj trzeci krok do zbierania wszystkich pozdrowień + +Gdy używamy procesu do zastosowania transformacji na każdym z elementów w channel, jak to robimy tutaj z wieloma pozdrowieni, czasami chcemy zebrać elementy z channel wyjściowego tego procesu i przekazać je do innego procesu, który wykonuje jakąś analizę lub podsumowanie. + +Dla demonstracji dodamy nowy krok do naszego pipeline, który zbiera wszystkie pozdrowienia zapisane wielkimi literami, wyprodukowane przez proces `convertToUpper`, i zapisuje je do pojedynczego pliku. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Nie zdradzając niespodzianki, ale będzie to wymagało użycia bardzo przydatnego operatora. + +### 2.1. Zdefiniuj polecenie zbierania i przetestuj je w terminalu + +Krok zbierania, który chcemy dodać do naszego workflow, użyje polecenia `cat` do połączenia wielu pozdrowień zapisanych wielkimi literami w pojedynczy plik. + +Uruchommy polecenie samodzielnie w terminalu, aby sprawdzić, czy działa zgodnie z oczekiwaniami, tak jak robiliśmy to wcześniej. + +Uruchom w terminalu: + +```bash +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 pozdrowień zapisane wielkimi literami. + +??? abstract "Zawartość pliku" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +To jest wynik, który chcemy osiągnąć za pomocą naszego workflow. + +### 2.2. Utwórz nowy proces do kroku zbierania + +Utwó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: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Zbierz pozdrowienia pisane wielkimi literami do jednego pliku wyjściowego + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +To jest to, co możemy napisać z pewnością na podstawie tego, czego się dotąd nauczyłeś. +Ale to nie jest funkcjonalne! +Brakuje definicji wejść i pierwszej połowy polecenia skryptu, ponieważ musimy wymyślić, jak to napisać. + +#### 2.2.2. Zdefiniuj wejścia do `collectGreetings()` + +Musimy zebrać pozdrowienia ze wszystkich wywołań procesu `convertToUpper()`. +Co wiemy, że możemy uzyskać z poprzedniego kroku workflow? + +Channel wyprodukowany przez `convertToUpper()` będzie zawierał ścieżki do poszczególnych plików zawierających pozdrowienia zapisane wielkimi literami. +To odpowiada jednemu slotowi wejściowemu; nazwijmy go `input_files` dla uproszczenia. + +W bloku procesu wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Zauważ, że używamy przedrostka `path`, mimo że oczekujemy, że będzie to zawierało wiele plików. + +#### 2.2.3. Skomponuj polecenie konkatenacji + +Tu sprawa może być nieco trudniejsza, 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, jak je skomponować w czasie wykonania na podstawie tego, jakie wejścia trafią do procesu. + +Innymi słowy, jeśli mamy channel wejściowy zawierający element `[file1.txt, file2.txt, file3.txt]`, potrzebujemy, aby Nextflow zamienił to na `cat file1.txt file2.txt file3.txt`. + +Na szczęście Nextflow z przyjemnością zrobi to za nas, jeśli po prostu napiszemy `cat ${input_files}` w poleceniu skryptu. + +W bloku procesu wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +W teorii powinno to obsłużyć dowolną liczbę plików wejściowych. + +!!! tip "Wskazówka" + + Niektóre narzędzia wiersza poleceń wymagają podania argumentu (np. `-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 [Nextflow dla genomiki](../../nf4_science/genomics/). + +### 2.3. Dodaj krok zbierania do workflow + +Teraz powinniśmy tylko wywołać proces zbierania na wyjściu kroku konwersji na wielkie litery. + +#### 2.3.1. Połącz wywołania procesów + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out) + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="75" + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + } + ``` + +To łączy wyjście `convertToUpper()` z wejściem `collectGreetings()`. + +#### 2.3.2. Uruchom workflow z `-resume` + +Spróbujmy. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Wynik polecenia" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Uruchomienie zakończyło się pomyślnie, włącznie z trzecim krokiem. + +Jednak spójrz na liczbę wywołań `collectGreetings()` w ostatniej linii. +Oczekiwaliśmy tylko jednego, ale są trzy. + +Teraz spójrz na zawartość końcowego pliku wyjściowego. + +??? abstract "Zawartość pliku" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +O nie. Krok zbierania został uruchomiony indywidualnie dla każdego pozdrowienia, co NIE jest tym, czego chcieliśmy. + +Musimy coś zrobić, aby wyraźnie powiedzieć Nextflow, że chcemy, aby ten trzeci krok działał na wszystkich elementach w channel wyprodukowanym przez `convertToUpper()`. + +### 2.4. Użyj operatora do zebrania pozdrowień w pojedyncze wejście + +Tak, ponownie odpowiedzią na nasz problem jest operator. + +Konkretnie użyjemy trafnie nazwanego operatora [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect). + +#### 2.4.1. Dodaj operator `collect()` + +Tym razem będzie to wyglądać nieco inaczej, ponieważ nie dodajemy operatora w kontekście channel factory; dodajemy go do channel wyjściowego. + +Bierzemy `convertToUpper.out` i dołączamy operator `collect()`, co daje nam `convertToUpper.out.collect()`. +Możemy to bezpośrednio podłączyć do wywołania procesu `collectGreetings()`. + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Dodaj instrukcje `view()` + +Dodajmy również kilka instrukcji `view()`, aby zwizualizować stany channel przed i po. + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + + // opcjonalne instrukcje view + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="73" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + } + ``` + +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 `-resume` + +Spróbujmy: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + 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] + ``` + +Uruchomienie zakończyło się pomyślnie, chociaż wynik w logu może wyglądać nieco bardziej chaotycznie (uporządkowaliśmy go dla czytelności). + +Tym razem trzeci krok został wywołany tylko raz! + +Patrząc na wynik instrukcji `view()`, widzimy: + +- Trzy instrukcje `Before collect:`, po jednej dla każdego pozdrowienia: w tym momencie ścieżki plików są indywidualnymi elementami w channel. +- Pojedyncza instrukcja `After collect:`: trzy ścieżki plików są teraz spakowane w pojedynczy element. + +Spójrz na zawartość końcowego pliku wyjściowego. + +??? abstract "Zawartość pliku" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Tym razem mamy wszystkie trzy pozdrowienia w końcowym pliku wyjściowym. Sukces! + +!!! note "Uwaga" + + Jeśli uruchomisz to kilka razy bez `-resume`, zobaczysz, że kolejność pozdrowień zmienia się od uruchomienia do uruchomienia. + To pokazuje, że kolejność, w jakiej elementy przepływają przez wywołania procesów, nie jest gwarantowana jako stała. + +#### 2.4.4. Usuń instrukcje `view()` dla czytelności + +Zanim przejdziesz do następnej sekcji, zalecamy usunięcie instrukcji `view()`, aby nie zaśmiecać wyjścia konsoli. + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="73" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + + // opcjonalne instrukcje view + convertToUpper.out.view { contents -> "Before collect: $contents" } + convertToUpper.out.collect().view { contents -> "After collect: $contents" } + ``` + +To jest zasadniczo odwrotna operacja od punktu 2.4.2. + +### Podsumowanie + +Wiesz już, jak zbierać wyjścia z wielu wywołań procesu i przekazywać je do wspólnego kroku analizy lub podsumowania. + +### Co dalej? + +Dowiedz się, jak przekazać więcej niż jedno wejście do procesu. + +--- + +## 3. Przekaż więcej niż jedno wejście do procesu + +Chcemy mieć możliwość nazwania końcowego pliku wyjściowego konkretną nazwą, aby móc przetwarzać kolejne partie pozdrowień bez nadpisywania końcowych wyników. + +W tym celu wprowadzimy następujące udoskonalenia do workflow: + +- Zmodyfikujemy proces zbierający, aby akceptował zdefiniowaną przez użytkownika nazwę pliku wyjściowego +- Dodamy parametr wiersza poleceń do workflow i przekażemy go do procesu zbierającego + +### 3.1. Zmodyfikuj proces zbierający + +Musimy 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ę zmienną `batch_name`. + +W bloku procesu wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Możesz skonfigurować 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ł. + +Dowiesz się, jak zarządzać wymaganymi i opcjonalnymi wejściami później w swojej podróży 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 ten sam sposób, w jaki komponowaliśmy dynamiczne nazwy plików wcześniej. + +W bloku procesu wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +To konfiguruje proces do używania wartości `batch_name` do generowania konkretnej nazwy pliku dla końcowego wyjścia workflow. + +### 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 + +Wiesz już, jak używać systemu `params` do deklarowania parametrów CLI. +Użyjmy tego do zadeklarowania parametru `batch` (z domyślną wartością, bo jesteśmy leniwi). + +W sekcji parametrów pipeline wprowadź następujące zmiany w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Tak jak demonstrowaliśmy dla `--input`, możesz nadpisać tę domyślną wartość, określając wartość z `--batch` w wierszu poleceń. + +#### 3.2.2. Przekaż parametr `batch` do procesu + +Aby dostarczyć wartość parametru do procesu, musimy dodać ją w wywołaniu procesu. + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect()) + ``` + +Widzisz, że aby dostarczyć wiele wejść do procesu, po prostu wymieniasz je w nawiasach wywołania, oddzielone przecinkami. + +!!! warning "Ostrzeżenie" + + MUSISZ dostarczyć wejścia do procesu w DOKŁADNIE TEJ SAMEJ KOLEJNOŚCI, w jakiej są wymienione w bloku definicji wejść procesu. + +### 3.3. Uruchom workflow + +Spróbujmy uruchomić to z nazwą partii w wierszu poleceń. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Uruchomienie zakończyło się pomyślnie i wygenerowało oczekiwane wyjście: + +??? abstract "Zawartość pliku" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Teraz, o ile odpowiednio określimy parametr, kolejne uruchomienia na innych partiach wejść nie nadpiszą poprzednich wyników. + +### Podsumowanie + +Wiesz już, jak przekazać więcej niż jedno wejście do procesu. + +### Co dalej? + +Dowiedz się, jak 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 uzyskać dostęp do ich wyjść bardzo wygodnie za pomocą składni `<process>.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? + +Wszystko to doskonałe pytania, a krótka odpowiedź brzmi: tak, możemy! + +Wiele wyjść zostanie spakowanych w oddzielne channels. +Możemy albo zdecydować się nadać tym channel wyjściowym nazwy, co ułatwia późniejsze odnoszenie się do nich indywidualnie, albo możemy się do nich odnosić przez indeks. + +Zagłębmy się w przykład. + +Dla celów demonstracyjnych załóżmy, że chcemy policzyć liczbę pozdrowień zbieranych dla danej partii wejść i zaraportować to w pliku. + +### 4.1. Zmodyfikuj proces, aby liczył i wyprowadzał liczbę pozdrowień + +To będzie wymagało dwóch kluczowych zmian w definicji procesu: potrzebujemy sposobu na policzenie pozdrowień i zapisanie pliku raportu, a następnie musimy dodać ten plik raportu do bloku `output` procesu. + +#### 4.1.1. Policz liczbę zebranych pozdrowień + +Wygodnie jest to, że Nextflow pozwala nam dodawać dowolny kod w bloku `script:` definicji procesu, co jest bardzo przydatne do robienia takich rzeczy jak ta. + +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 w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +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ść. Pozwoli nam to wybierać wyjścia po nazwie zamiast używać indeksów pozycyjnych. + +W bloku procesu wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +Tagi `emit:` są opcjonalne i mogliśmy dodać tag tylko do jednego z wyjść. +Ale jak mówi powiedzenie, czemu nie obu? + +!!! tip "Wskazówka" + + Jeśli nie nazwiesz wyjść procesu za pomocą `emit:`, nadal możesz uzyskać do nich dostęp indywidualnie, używając ich odpowiedniego indeksu (liczonego od zera). + Na przykład, użyłbyś `<process>.out[0]`, aby uzyskać pierwsze wyjście, `<process>.out[1]`, aby uzyskać drugie wyjście, i tak dalej. + + Preferujemy nazywanie wyjść, ponieważ w przeciwnym razie zbyt łatwo jest przez pomyłkę użyć złego indeksu, szczególnie gdy proces produkuje wiele wyjść. + +### 4.2. Zaktualizuj wyjścia workflow + +Teraz, gdy mamy dwa wyjścia z procesu `collectGreetings`, wyjście `collectGreetings.out` zawiera dwa channels: + +- `collectGreetings.out.outfile` zawiera końcowy plik wyjściowy +- `collectGreetings.out.report` zawiera plik raportu + +Musimy odpowiednio zaktualizować wyjścia workflow. + +#### 4.2.1. Zaktualizuj sekcję `publish:` + +W bloku `workflow` wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Jak widać, odnoszenie się do konkretnych wyjść procesu jest teraz trywialne. +Gdy dodamy jeszcze jeden krok do naszego pipeline w Części 5 (Kontenery), będziemy mogli łatwo odnieść 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. + +#### 4.2.2. Zaktualizuj blok `output` + +W bloku `output` wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +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 bieżącą partią pozdrowień. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Jeśli zajrzysz do katalogu `results/hello_workflow/`, znajdziesz nowy plik raportu `trio-report.txt`. +Otwórz go, aby sprawdzić, czy workflow poprawnie zaraportował liczbę przetworzonych pozdrowień. + +??? abstract "Zawartość pliku" + + ```txt title="trio-report.txt" + There were 3 greetings in this batch. + ``` + +Możesz dodać więcej pozdrowień do pliku CSV i przetestować, co się stanie. + +### Podsumowanie + +Wiesz już, jak sprawić, aby proces emitował wiele nazwanych wyjść i jak odpowiednio obsługiwać je na poziomie workflow. + +Ogólnie rzecz biorąc, rozumiesz kluczowe zasady związane z łączeniem procesów na typowe sposoby. + +### Co dalej? + +Weź dodatkową długą przerwę, zasłużyłeś na to. + +Gdy będziesz gotowy, przejdź do [**Część 4: Hello Modules**](./04_hello_modules.md), aby dowiedzieć się, jak modularyzować swój kod dla lepszej utrzymywalności i efektywności. + +--- + +## Quiz + +<quiz> +Jak uzyskujesz dostęp do wyjścia procesu w bloku workflow? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Dowiedz się więcej: [1.4. Przekaż wyjście pierwszego procesu do drugiego procesu](#14-przekaz-wyjscie-pierwszego-procesu-do-drugiego-procesu) +</quiz> + +<quiz> +Co determinuje kolejność wykonywania procesów w Nextflow? +- [ ] Kolejność, w jakiej procesy są zapisane w bloku workflow +- [ ] Kolejność alfabetyczna według nazwy procesu +- [x] Zależności danych między procesami +- [ ] Losowa kolejność dla równoległego wykonania + +Dowiedz się więcej: [1.4. Przekaż wyjście pierwszego procesu do drugiego procesu](#14-przekaz-wyjscie-pierwszego-procesu-do-drugiego-procesu) +</quiz> + +<quiz> +Który operator powinien zastąpić `???`, aby zebrać wszystkie wyjścia w pojedynczą listę dla procesu następczego? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Dowiedz się więcej: [2.4. Użyj operatora do zebrania pozdrowień w pojedyncze wejście](#24-uzyj-operatora-do-zebrania-pozdrowien-w-pojedyncze-wejscie) +</quiz> + +<quiz> +Kiedy należy używać operatora `collect()`? +- [ ] Gdy chcesz przetwarzać elementy równolegle +- [ ] Gdy potrzebujesz filtrować zawartość channel +- [x] Gdy proces następczy potrzebuje wszystkich elementów z procesu poprzedzającego +- [ ] Gdy chcesz rozdzielić dane między wiele procesów + +Dowiedz się więcej: [2.4. Użyj operatora do zebrania pozdrowień w pojedyncze wejście](#24-uzyj-operatora-do-zebrania-pozdrowien-w-pojedyncze-wejscie) +</quiz> + +<quiz> +Jak uzyskujesz dostęp do nazwanego wyjścia z procesu? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Dowiedz się więcej: [4.1.2. Wyemituj plik raportu i nazwij wyjścia](#412-wyemituj-plik-raportu-i-nazwij-wyjscia) +</quiz> + +<quiz> +Jaka jest poprawna składnia do nazywania wyjścia w procesie? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Dowiedz się więcej: [4.1.2. Wyemituj plik raportu i nazwij wyjścia](#412-wyemituj-plik-raportu-i-nazwij-wyjscia) +</quiz> + +<quiz> +Przy dostarczaniu wielu wejść do procesu, co musi być prawdą? +- [ ] Wszystkie wejścia muszą być tego samego typu +- [ ] Wejścia muszą być podane w kolejności alfabetycznej +- [x] Kolejność wejść musi odpowiadać kolejności zdefiniowanej w bloku input +- [ ] Tylko dwa wejścia mogą być podane jednocześnie + +Dowiedz się więcej: [3. Przekaż więcej niż jedno wejście do procesu](#3-przekaz-wiecej-niz-jedno-wejscie-do-procesu) +</quiz> diff --git a/docs/pl/docs/hello_nextflow/04_hello_modules.md b/docs/pl/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..93b501777c --- /dev/null +++ b/docs/pl/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Część 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Obejrzyj [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/04_hello_modules.md). +/// + +Ta sekcja opisuje, jak organizować kod workflow, aby rozwój i utrzymanie pipeline było bardziej efektywne i zrównoważone. +W szczególności pokażemy, jak używać **modułów**. + +W Nextflow **moduł** to pojedyncza definicja procesu, która jest zamknięta w samodzielnym pliku kodu. +Aby użyć modułu w workflow, wystarczy dodać jednoliniową instrukcję importu do pliku kodu workflow; następnie możesz zintegrować proces z workflow w taki sam sposób, jak normalnie. +To umożliwia ponowne wykorzystanie definicji procesów w wielu workflow bez tworzenia wielu kopii kodu. + +Kiedy zaczęliśmy rozwijać nasz workflow, napisaliśmy wszystko w jednym pliku kodu. +Teraz przeniesiemy procesy do indywidualnych modułów. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +To sprawi, że nasz kod będzie bardziej współdzielny, elastyczny i łatwy w utrzymaniu. + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś Części 1-3 kursu [Hello Nextflow](./index.md), ale jeśli znasz podstawy omówione w tych sekcjach, możesz zacząć od tego miejsca bez żadnych dodatkowych przygotowań. + +--- + +## 0. Rozgrzewka: Uruchom `hello-modules.nf` + +Użyjemy skryptu workflow `hello-modules.nf` jako punktu wyjścia. +Jest on równoważny skryptowi utworzonemu podczas pracy nad Częścią 3 tego szkolenia, z tą różnicą, że zmieniliśmy miejsca docelowe wyjść: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Jak poprzednio, pliki wyjściowe znajdziesz w katalogu określonym w bloku `output` (tutaj `results/hello_modules/`). + +??? abstract "Zawartość katalogu" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Jeśli to zadziałało, jesteś gotowy do nauki modularyzacji kodu workflow. + +--- + +## 1. Utwórz katalog do przechowywania modułów + +Najlepszą praktyką jest przechowywanie modułów w konkretnym katalogu. +Możesz nazwać ten katalog jak chcesz, ale konwencja nakazuje nazywać go `modules/`. + +```bash +mkdir modules +``` + +!!! tip "Wskazówka" + + Tutaj pokazujemy, jak używać **lokalnych modułów**, czyli modułów przechowywanych lokalnie w tym samym repozytorium co reszta kodu workflow, w przeciwieństwie do modułów zdalnych, które są przechowywane w innych (zdalnych) repozytoriach. + Więcej informacji o **modułach zdalnych** znajdziesz w [dokumentacji](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Utwórz moduł dla `sayHello()` + +W najprostszej formie przekształcenie istniejącego procesu w moduł to niewiele więcej niż operacja kopiuj-wklej. +Utworzymy plik dla modułu, skopiujemy odpowiedni kod, a następnie usuniemy go z głównego pliku workflow. + +Potem wystarczy dodać instrukcję importu, aby Nextflow wiedział, że ma pobrać odpowiedni kod w czasie wykonania. + +### 2.1. Utwórz plik dla nowego modułu + +Utwórzmy pusty plik dla modułu o nazwie `sayHello.nf`. + +```bash +touch modules/sayHello.nf +``` + +To daje nam miejsce na umieszczenie kodu procesu. + +### 2.2. Przenieś kod procesu `sayHello` do pliku modułu + +Skopiuj całą definicję procesu z pliku workflow do pliku modułu, upewniając się, że kopiujesz również shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Użyj echo do wypisania 'Hello World!' do pliku + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Po wykonaniu tego usuń definicję procesu z pliku workflow, ale upewnij się, że zostawiasz shebang na miejscu. + +### 2.3. Dodaj deklarację importu przed blokiem workflow + +Składnia importowania lokalnego modułu jest dość prosta: + +```groovy title="Składnia: Deklaracja importu" +include { <NAZWA_MODUŁU> } from '<ścieżka_do_modułu>' +``` + +Wstawmy ją powyżej bloku `params` i wypełnijmy odpowiednio. + +=== "Po" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Przed" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Widzisz, że wypełniliśmy nazwę modułu, `sayHello`, oraz ścieżkę do pliku zawierającego kod modułu, `./modules/sayHello.nf`. + +### 2.4. Uruchom workflow + +Uruchamiamy workflow z zasadniczo tym samym kodem i wejściami co poprzednio, więc uruchommy z flagą `-resume` i zobaczmy, co się stanie. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +To powinno się wykonać bardzo szybko, ponieważ wszystko jest w cache. +Możesz sprawdzić opublikowane wyjścia. + +Nextflow rozpoznał, że nadal jest to ta sama praca do wykonania, nawet jeśli kod jest podzielony na wiele plików. + +### Podsumowanie + +Wiesz już, jak wyodrębnić proces do lokalnego modułu i wiesz, że nie wpływa to na możliwość wznawiania workflow. + +### Co dalej? + +Ćwicz tworzenie kolejnych modułów. +Gdy zrobisz jeden, możesz zrobić milion więcej... +Ale na razie zróbmy jeszcze tylko dwa. + +--- + +## 3. Zmodularyzuj proces `convertToUpper()` + +### 3.1. Utwórz plik dla nowego modułu + +Utwórz pusty plik dla modułu o nazwie `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Przenieś kod procesu `convertToUpper` do pliku modułu + +Skopiuj całą definicję procesu z pliku workflow do pliku modułu, upewniając się, że kopiujesz również shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Użyj narzędzia zamiany tekstu do przekształcenia pozdrowienia na wielkie litery + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Po wykonaniu tego usuń definicję procesu z pliku workflow, ale upewnij się, że zostawiasz shebang na miejscu. + +### 3.3. Dodaj deklarację importu przed blokiem `params` + +Wstaw deklarację importu powyżej bloku `params` i wypełnij ją odpowiednio. + +=== "Po" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Przed" + + ```groovy title="hello-modules.nf" linenums="23" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +To powinno zacząć wyglądać bardzo znajomo. + +### 3.4. Uruchom workflow ponownie + +Uruchom z flagą `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +To powinno nadal produkować takie same wyjście jak poprzednio. + +Dwa zrobione, jeszcze jeden do zrobienia! + +--- + +## 4. Zmodularyzuj proces `collectGreetings()` + +### 4.1. Utwórz plik dla nowego modułu + +Utwórz pusty plik dla modułu o nazwie `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Przenieś kod procesu `collectGreetings` do pliku modułu + +Skopiuj całą definicję procesu z pliku workflow do pliku modułu, upewniając się, że kopiujesz również shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Zbierz pozdrowienia pisane wielkimi literami do jednego pliku wyjściowego + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Po wykonaniu tego usuń definicję procesu z pliku workflow, ale upewnij się, że zostawiasz shebang na miejscu. + +### 4.3. Dodaj deklarację importu przed blokiem `params` + +Wstaw deklarację importu powyżej bloku `params` i wypełnij ją odpowiednio. + +=== "Po" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Przed" + + ```groovy title="hello-modules.nf" linenums="3" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Ostatni! + +### 4.4. Uruchom workflow + +Uruchom z flagą `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +To powinno nadal produkować takie same wyjście jak poprzednio. + +### Podsumowanie + +Wiesz już, jak modularyzować wiele procesów w workflow. + +Gratulacje, wykonałeś całą tę pracę i absolutnie nic się nie zmieniło w działaniu pipeline! + +Żarty na bok, teraz Twój kod jest bardziej modularny, a jeśli zdecydujesz się napisać inny pipeline, który wywołuje jeden z tych procesów, wystarczy wpisać jedną krótką instrukcję importu, aby użyć odpowiedniego modułu. +To jest lepsze niż kopiowanie-wklejanie kodu, ponieważ jeśli później zdecydujesz się ulepszyć moduł, wszystkie Twoje pipeline odziedziczą te ulepszenia. + +### Co dalej? + +Zrób krótką przerwę, jeśli masz ochotę. + +Gdy będziesz gotowy, przejdź do [**Część 5: Hello Containers**](./05_hello_containers.md), aby dowiedzieć się, jak używać kontenerów do wygodniejszego i bardziej powtarzalnego zarządzania zależnościami oprogramowania. + +--- + +## Quiz + +<quiz> +Czym jest moduł w Nextflow? +- [ ] Plik konfiguracyjny +- [x] Samodzielny plik zawierający pojedynczą definicję procesu +- [ ] Definicja workflow +- [ ] Operator channel + +Dowiedz się więcej: [2. Utwórz moduł dla `sayHello()`](#2-utworz-modul-dla-sayhello) +</quiz> + +<quiz> +Jaka jest zalecana konwencja nazewnictwa plików modułów? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Gdzie powinny być przechowywane pliki modułów? +- [ ] W tym samym katalogu co workflow +- [ ] W katalogu `bin/` +- [x] W katalogu `modules/` +- [ ] W katalogu `lib/` + +Dowiedz się więcej: [1. Utwórz katalog do przechowywania modułów](#1-utworz-katalog-do-przechowywania-modulow) +</quiz> + +<quiz> +Jaka jest poprawna składnia do importowania modułu? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Dowiedz się więcej: [2.3. Dodaj deklarację importu](#23-dodaj-deklaracje-importu-przed-blokiem-workflow) +</quiz> + +<quiz> +Co się dzieje z funkcjonalnością `-resume` podczas używania modułów? +- [ ] Przestaje działać +- [ ] Wymaga dodatkowej konfiguracji +- [x] Działa tak samo jak wcześniej +- [ ] Działa tylko dla lokalnych modułów +</quiz> + +<quiz> +Jakie są korzyści z używania modułów? (Wybierz wszystkie pasujące) +- [x] Możliwość ponownego wykorzystania kodu w różnych workflow +- [x] Łatwiejsze utrzymanie +- [x] Lepsza organizacja kodu workflow +- [ ] Szybsza prędkość wykonania +</quiz> diff --git a/docs/pl/docs/hello_nextflow/05_hello_containers.md b/docs/pl/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..de7c28018a --- /dev/null +++ b/docs/pl/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Część 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Obejrzyj [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/05_hello_containers.md). +/// + +W Częściach 1-4 tego kursu nauczyłeś się używać podstawowych elementów budulcowych Nextflow do składania prostego workflow zdolnego do przetwarzania tekstu, równoległego wykonywania wielu wejść i zbierania wyników do dalszego przetwarzania. + +Jednak byłeś ograniczony do podstawowych narzędzi UNIX dostępnych w Twoim środowisku. +Rzeczywiste zadania często wymagają różnych narzędzi i pakietów, które nie są domyślnie dołączone. +Zazwyczaj musiałbyś zainstalować te narzędzia, zarządzać ich zależnościami i rozwiązywać konflikty. + +To wszystko jest bardzo nużące i irytujące, więc pokażemy Ci, jak używać **kontenerów**, aby rozwiązać ten problem znacznie wygodniej. + +**Kontener** to lekka, samodzielna, wykonywalna jednostka oprogramowania utworzona z **obrazu** kontenera, która zawiera wszystko potrzebne do uruchomienia aplikacji, w tym kod, biblioteki systemowe i ustawienia. +Jak można się domyślić, będzie to bardzo pomocne w zwiększeniu powtarzalności Twoich pipeline. + +Zauważ, że będziemy tego uczyć używając [Docker](https://www.docker.com/get-started/), ale pamiętaj, że Nextflow obsługuje również [kilka innych technologii kontenerowych](https://www.nextflow.io/docs/latest/container.html#). + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś Części 1-4 kursu [Hello Nextflow](./index.md) i masz kompletny działający pipeline. + + Jeśli zaczynasz kurs od tego miejsca, musisz skopiować katalog `modules` z rozwiązań: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Rozgrzewka: Uruchom `hello-containers.nf` + +Użyjemy skryptu workflow `hello-containers.nf` jako punktu wyjścia. +Jest on równoważny skryptowi utworzonemu podczas pracy nad Częścią 4 tego szkolenia, z tą różnicą, że zmieniliśmy miejsca docelowe wyjść: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Jak poprzednio, pliki wyjściowe znajdziesz w katalogu określonym w bloku `output` (`results/hello_containers/`). + +??? abstract "Zawartość katalogu" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Jeśli to zadziałało, jesteś gotowy do nauki używania kontenerów. + +--- + +## 1. Użyj kontenera 'ręcznie' + +Chcemy dodać krok do naszego workflow, który będzie używał kontenera do wykonania. + +Jednak najpierw omówimy podstawowe koncepcje i operacje, aby utrwalić Twoje zrozumienie tego, czym są kontenery, zanim zaczniemy ich używać w Nextflow. + +### 1.1. Pobierz obraz kontenera + +Aby użyć kontenera, zazwyczaj pobierasz lub _ściągasz_ obraz kontenera z rejestru kontenerów, a następnie uruchamiasz obraz kontenera, aby utworzyć instancję kontenera. + +Ogólna składnia jest następująca: + +```bash title="Składnia" +docker pull '<kontener>' +``` + +Część `docker pull` to instrukcja dla systemu kontenerowego, aby pobrał obraz kontenera z repozytorium. + +Część `'<kontener>'` to adres URI obrazu kontenera. + +Jako przykład pobierzmy obraz kontenera zawierający [cowpy](https://github.com/jeffbuttars/cowpy), pythonową implementację narzędzia o nazwie `cowsay`, które generuje grafikę ASCII do wyświetlania dowolnych tekstów wejściowych w zabawny sposób. + +```txt title="Przykład" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Istnieją różne repozytoria, w których można znaleźć opublikowane kontenery. +Użyliśmy usługi [Seqera Containers](https://seqera.io/containers/) do wygenerowania tego obrazu kontenera Docker z pakietu Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Uruchom pełne polecenie pobierania: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Wynik polecenia" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Jeśli nigdy wcześniej nie pobierałeś tego obrazu, może to zająć minutę. +Po zakończeniu masz lokalną kopię obrazu kontenera. + +### 1.2. Użyj kontenera do uruchomienia `cowpy` jako jednorazowego polecenia + +Bardzo częstym sposobem używania kontenerów jest uruchamianie ich bezpośrednio, czyli nieinteraktywnie. +To świetne rozwiązanie do uruchamiania jednorazowych poleceń. + +Ogólna składnia jest następująca: + +```bash title="Składnia" +docker run --rm '<kontener>' [polecenie narzędzia] +``` + +Część `docker run --rm '<kontener>'` to instrukcja dla systemu kontenerowego, aby uruchomił instancję kontenera z obrazu kontenera i wykonał w nim polecenie. +Flaga `--rm` mówi systemowi, aby wyłączył instancję kontenera po zakończeniu polecenia. + +Składnia `[polecenie narzędzia]` zależy od używanego narzędzia i konfiguracji kontenera. +Zacznijmy po prostu od `cowpy`. + +W pełni złożone polecenie wykonania kontenera wygląda tak; uruchom je: + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Wynik polecenia" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +System uruchomił kontener, wykonał polecenie `cowpy` z jego parametrami, wysłał wynik do konsoli i na koniec wyłączył instancję kontenera. + +### 1.3. Użyj kontenera do uruchomienia `cowpy` interaktywnie + +Możesz również uruchomić kontener interaktywnie, co daje Ci wiersz poleceń wewnątrz kontenera i pozwala eksperymentować z poleceniem. + +#### 1.3.1. Uruchom kontener + +Aby uruchomić interaktywnie, po prostu dodajemy `-it` do polecenia `docker run`. +Opcjonalnie możemy określić powłokę, której chcemy używać wewnątrz kontenera, dodając np. `/bin/bash` do polecenia. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Zauważ, że Twój wiersz poleceń zmienia się na coś w rodzaju `(base) root@b645838b3314:/tmp#`, co wskazuje, że jesteś teraz wewnątrz kontenera. + +Możesz to sprawdzić, uruchamiając `ls /`, aby wylistować zawartość katalogu od korzenia systemu plików: + +```bash +ls / +``` + +??? abstract "Wynik polecenia" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Używamy tutaj `ls` zamiast `tree`, ponieważ narzędzie `tree` nie jest dostępne w tym kontenerze. +Widać, że system plików wewnątrz kontenera różni się od systemu plików na Twoim systemie hosta. + +Jednym z ograniczeń tego, co właśnie zrobiliśmy, jest to, że kontener jest domyślnie całkowicie odizolowany od systemu hosta. +Oznacza to, że kontener nie może uzyskać dostępu do żadnych plików na systemie hosta, chyba że wyraźnie mu na to pozwolisz. + +Pokażemy Ci, jak to zrobić za chwilę. + +#### 1.3.2. Uruchom żądane polecenie(a) narzędzia + +Teraz, gdy jesteś wewnątrz kontenera, możesz uruchomić polecenie `cowpy` bezpośrednio i podać mu parametry. +Na przykład dokumentacja narzędzia mówi, że możemy zmienić postać ('cowacter') za pomocą `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Wynik polecenia" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Teraz wynik pokazuje pingwina Linuxa, Tuxa, zamiast domyślnej krowy, ponieważ określiliśmy parametr `-c tux`. + +Ponieważ jesteś wewnątrz kontenera, możesz uruchamiać polecenie `cowpy` ile razy chcesz, zmieniając parametry wejściowe, bez konieczności zajmowania się poleceniami Docker. + +!!! tip "Wskazówka" + + Użyj flagi '-c', aby wybrać inną postać, w tym: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +To fajne. Jeszcze fajniej byłoby, gdybyśmy mogli podać nasz plik `greetings.csv` jako wejście. +Ale ponieważ nie mamy dostępu do systemu plików, nie możemy. + +Naprawmy to. + +#### 1.3.3. Wyjdź z kontenera + +Aby wyjść z kontenera, możesz wpisać `exit` w wierszu poleceń lub użyć skrótu klawiaturowego ++ctrl+d++. + +```bash +exit +``` + +Twój wiersz poleceń powinien teraz wrócić do stanu sprzed uruchomienia kontenera. + +#### 1.3.4. Zamontuj dane w kontenerze + +Jak wspomniano wcześniej, kontener jest domyślnie odizolowany od systemu hosta. + +Aby pozwolić kontenerowi na dostęp do systemu plików hosta, możesz **zamontować** **wolumen** z systemu hosta do kontenera, używając następującej składni: + +```bash title="Składnia" +-v <ścieżka_zewnętrzna>:<ścieżka_wewnętrzna> +``` + +W naszym przypadku `<ścieżka_zewnętrzna>` będzie bieżącym katalogiem roboczym, więc możemy po prostu użyć kropki (`.`), a `<ścieżka_wewnętrzna>` to alias, który wymyślamy; nazwijmy go `/my_project` (ścieżka wewnętrzna musi być bezwzględna). + +Aby zamontować wolumen, zastępujemy ścieżki i dodajemy argument montowania wolumenu do polecenia docker run w następujący sposób: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +To montuje bieżący katalog roboczy jako wolumen, który będzie dostępny pod `/my_project` wewnątrz kontenera. + +Możesz sprawdzić, czy to działa, wylistowując zawartość `/my_project`: + +```bash +ls /my_project +``` + +??? success "Wynik polecenia" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Teraz możesz zobaczyć zawartość katalogu roboczego z wnętrza kontenera, w tym plik `greetings.csv` w katalogu `data/`. + +To skutecznie utworzyło tunel przez ścianę kontenera, którego możesz użyć do dostępu do tej części systemu plików. + +#### 1.3.5. Użyj zamontowanych danych + +Teraz, gdy zamontowaliśmy katalog roboczy w kontenerze, możemy użyć polecenia `cowpy` do wyświetlenia zawartości pliku `greetings.csv`. + +W tym celu użyjemy `cat /my_project/data/greetings.csv | `, aby przekierować zawartość pliku CSV do polecenia `cowpy`. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Wynik polecenia" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +To produkuje pożądaną grafikę ASCII indyka recytującego nasze przykładowe pozdrowienia! +Tyle że tutaj indyk powtarza pełne wiersze zamiast samych pozdrowień. +Wiemy już, że nasz workflow Nextflow zrobi to lepiej! + +Możesz poeksperymentować z tym poleceniem. +Gdy skończysz, wyjdź z kontenera jak poprzednio: + +```bash +exit +``` + +Wrócisz do normalnej powłoki. + +### Podsumowanie + +Wiesz już, jak pobrać kontener i uruchomić go jednorazowo lub interaktywnie. Wiesz również, jak udostępnić swoje dane z wnętrza kontenera, co pozwala wypróbować każde interesujące Cię narzędzie na prawdziwych danych bez konieczności instalowania oprogramowania na swoim systemie. + +### Co dalej? + +Naucz się używać kontenerów do wykonywania procesów Nextflow. + +--- + +## 2. Używaj kontenerów w Nextflow + +Nextflow ma wbudowaną obsługę uruchamiania procesów wewnątrz kontenerów, co pozwala uruchamiać narzędzia, których nie masz zainstalowanych w swoim środowisku obliczeniowym. +Oznacza to, że możesz użyć dowolnego obrazu kontenera do uruchamiania procesów, a Nextflow zajmie się pobieraniem obrazu, montowaniem danych i uruchamianiem procesu wewnątrz. + +Aby to zademonstrować, dodamy krok `cowpy` do pipeline, który rozwijaliśmy, po kroku `collectGreetings`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Zamuucz, jeśli jesteś gotowy! + +### 2.1. Napisz moduł `cowpy` + +Najpierw utwórzmy moduł procesu `cowpy`. + +#### 2.1.1. Utwórz plik dla nowego modułu + +Utwórz pusty plik dla modułu o nazwie `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +To daje nam miejsce na umieszczenie kodu procesu. + +#### 2.1.2. Skopiuj kod procesu `cowpy` do pliku modułu + +Możemy wzorować nasz proces `cowpy` na innych procesach, które napisaliśmy wcześniej. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Wygeneruj grafikę ASCII za pomocą cowpy +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Proces oczekuje `input_file` zawierającego pozdrowienia oraz wartości `character`. + +Wyjściem będzie nowy plik tekstowy zawierający grafikę ASCII wygenerowaną przez narzędzie `cowpy`. + +### 2.2. Dodaj cowpy do workflow + +Teraz musimy zaimportować moduł i wywołać proces. + +#### 2.2.1. Importuj proces `cowpy` do `hello-containers.nf` + +Wstaw deklarację importu powyżej bloku workflow i wypełnij ją odpowiednio. + +=== "Po" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Przed" + + ```groovy title="hello-containers.nf" linenums="3" + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Teraz moduł `cowpy` jest dostępny do użycia w workflow. + +#### 2.2.2. Dodaj wywołanie procesu `cowpy` w workflow + +Połączmy proces `cowpy()` z wyjściem procesu `collectGreetings()`, który jak pamiętasz produkuje dwa wyjścia: + +- `collectGreetings.out.outfile` zawiera plik wyjściowy <--_to, czego potrzebujemy_ +- `collectGreetings.out.report` zawiera plik raportu z liczbą pozdrowień na partię + +W bloku workflow wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Przed" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Zauważ, że zadeklarowaliśmy nowy parametr CLI, `params.character`, aby określić, która postać ma wypowiedzieć pozdrowienia. + +#### 2.2.3. Dodaj parametr `character` do bloku `params` + +To technicznie jest opcjonalne, ale jest to zalecana praktyka i okazja do ustawienia domyślnej wartości dla postaci. + +=== "Po" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Przed" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Teraz możemy być leniwi i pominąć wpisywanie parametru postaci w naszych poleceniach. + +#### 2.2.4. Zaktualizuj wyjścia workflow + +Musimy zaktualizować wyjścia workflow, aby publikować wyjście procesu `cowpy`. + +##### 2.2.4.1. Zaktualizuj sekcję `publish:` + +W bloku `workflow` wprowadź następującą zmianę w kodzie: + +=== "Po" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Przed" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +Proces `cowpy` produkuje tylko jedno wyjście, więc możemy się do niego odnieść w zwykły sposób, dodając `.out`. + +Ale na razie dokończmy aktualizację wyjść na poziomie workflow. + +##### 2.2.4.2. Zaktualizuj blok `output` + +Musimy dodać końcowe wyjście `cowpy_art` do bloku `output`. Przy okazji edytujmy również miejsca docelowe publikacji, ponieważ teraz nasz pipeline jest kompletny i wiemy, które wyjścia naprawdę nas interesują. + +W bloku `output` wprowadź następujące zmiany w kodzie: + +=== "Po" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Teraz opublikowane wyjścia będą nieco lepiej zorganizowane. + +#### 2.2.5. Uruchom workflow + +Podsumowując, oto co chcemy osiągnąć: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Myślisz, że zadziała? + +Usuńmy poprzednie opublikowane wyjścia, aby mieć czystą kartę, i uruchommy workflow z flagą `-resume`. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Wynik polecenia (zredagowany dla przejrzystości)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +O nie, jest błąd! +Kod błędu podany przez `error exit status (127)` oznacza, że żądany plik wykonywalny nie został znaleziony. + +To ma sens, ponieważ wywołujemy narzędzie `cowpy`, ale tak naprawdę nie określiliśmy jeszcze kontenera (ups). + +### 2.3. Użyj kontenera do uruchomienia procesu `cowpy` + +Musimy określić kontener i powiedzieć Nextflow, aby użył go dla procesu `cowpy()`. + +#### 2.3.1. Określ kontener dla `cowpy` + +Możemy użyć tego samego obrazu, którego używaliśmy bezpośrednio w pierwszej sekcji tego samouczka. + +Edytuj moduł `cowpy.nf`, aby dodać dyrektywę `container` do definicji procesu w następujący sposób: + +=== "Po" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Przed" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +To mówi Nextflow, że _jeśli użycie Docker jest włączone_, powinien użyć określonego tutaj obrazu kontenera do wykonania procesu. + +#### 2.3.2. Włącz użycie Docker przez plik `nextflow.config` + +Zauważ, że powiedzieliśmy _'jeśli użycie Docker jest włączone'_. Domyślnie nie jest, więc musimy powiedzieć Nextflow, że może używać Docker. +W tym celu nieco uprzedzamy temat następnej i ostatniej części tego kursu (Część 6), która obejmuje konfigurację. + +Jednym z głównych sposobów konfigurowania wykonywania workflow, które oferuje Nextflow, jest użycie pliku `nextflow.config`. +Gdy taki plik jest obecny w bieżącym katalogu, Nextflow automatycznie go załaduje i zastosuje zawartą w nim konfigurację. + +Dostarczyliśmy plik `nextflow.config` z jedną linią kodu, która jawnie wyłącza Docker: `docker.enabled = false`. + +Teraz zmieńmy to na `true`, aby włączyć Docker: + +=== "Po" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Przed" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Wskazówka" + + Możliwe jest włączenie wykonywania Docker z wiersza poleceń, dla pojedynczego uruchomienia, używając parametru `-with-docker <kontener>`. + Jednak pozwala to tylko na określenie jednego kontenera dla całego workflow, podczas gdy podejście, które właśnie pokazaliśmy, pozwala na określenie innego kontenera dla każdego procesu. + To jest lepsze dla modularności, utrzymania kodu i powtarzalności. + +#### 2.3.3. Uruchom workflow z włączonym Docker + +Uruchom workflow z flagą `-resume`: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Tym razem rzeczywiście działa! +Jak zwykle wyjścia workflow znajdziesz w odpowiednim katalogu results, choć tym razem są nieco lepiej zorganizowane, z tylko raportem i końcowym wyjściem na najwyższym poziomie, a wszystkie pliki pośrednie schowane w podkatalogu. + +??? abstract "Zawartość katalogu" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Końcowa grafika ASCII znajduje się w katalogu `results/hello_containers/`, pod nazwą `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +I oto jest, nasz piękny indyk wypowiadający pozdrowienia zgodnie z oczekiwaniami. + +#### 2.3.4. Sprawdź, jak Nextflow uruchomił skonteneryzowane zadanie + +Na zakończenie tej sekcji przyjrzyjmy się podkatalogowi work dla jednego z wywołań procesu `cowpy`, aby uzyskać trochę więcej wglądu w to, jak Nextflow pracuje z kontenerami pod maską. + +Sprawdź wynik polecenia `nextflow run`, aby znaleźć ścieżkę do podkatalogu work dla procesu `cowpy`. +Patrząc na to, co otrzymaliśmy dla pokazanego powyżej uruchomienia, linia logu konsoli dla procesu `cowpy` zaczyna się od `[98/656c6c]`. +Odpowiada to następującej skróconej ścieżce katalogu: `work/98/656c6c`. + +W tym katalogu znajdziesz plik `.command.run`, który zawiera wszystkie polecenia, które Nextflow uruchomił w Twoim imieniu podczas wykonywania pipeline. + +??? abstract "Zawartość pliku" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Jeśli wyszukasz `nxf_launch` w tym pliku, powinieneś zobaczyć coś takiego: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Jak widać, Nextflow używa polecenia `docker run` do uruchomienia wywołania procesu. +Montuje również odpowiedni podkatalog work do kontenera, ustawia odpowiednio katalog roboczy wewnątrz kontenera i uruchamia nasz szablonowy skrypt bash w pliku `.command.sh`. + +Cała ciężka praca, którą musieliśmy wykonać ręcznie w pierwszej sekcji? Nextflow robi to za nas za kulisami! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Podsumowanie + +Wiesz już, jak używać kontenerów w Nextflow do uruchamiania procesów. + +### Co dalej? + +Zrób przerwę! + +Gdy będziesz gotowy, przejdź do [**Część 6: Hello Config**](./06_hello_config.md), aby dowiedzieć się, jak konfigurować wykonywanie pipeline, aby dopasować go do Twojej infrastruktury, a także zarządzać konfiguracją wejść i parametrów. + +To ostatnia część i potem ukończysz ten kurs! + +--- + +## Quiz + +<quiz> +Czym jest kontener? +- [ ] Rodzaj maszyny wirtualnej +- [ ] Format kompresji plików +- [x] Lekka, samodzielna, wykonywalna jednostka zawierająca wszystko potrzebne do uruchomienia aplikacji +- [ ] Protokół sieciowy +</quiz> + +<quiz> +Jaka jest różnica między obrazem kontenera a instancją kontenera? +- [ ] To to samo +- [x] Obraz to szablon; instancja to działający kontener utworzony z tego obrazu +- [ ] Instancja to szablon; obraz to działający kontener +- [ ] Obrazy są dla Docker; instancje są dla Singularity +</quiz> + +<quiz> +Co robi flaga `-v` w poleceniu `docker run`? +- [ ] Włącza szczegółowe wyjście +- [ ] Waliduje kontener +- [x] Montuje wolumen z systemu hosta do kontenera +- [ ] Określa wersję kontenera + +Dowiedz się więcej: [1.3.4. Zamontuj dane w kontenerze](#134-zamontuj-dane-w-kontenerze) +</quiz> + +<quiz> +Dlaczego trzeba montować wolumeny podczas używania kontenerów? +- [ ] Aby poprawić wydajność kontenera +- [ ] Aby oszczędzić miejsce na dysku +- [x] Ponieważ kontenery są domyślnie odizolowane od systemu plików hosta +- [ ] Aby włączyć sieć + +Dowiedz się więcej: [1.3.4. Zamontuj dane w kontenerze](#134-zamontuj-dane-w-kontenerze) +</quiz> + +<quiz> +Jak określasz kontener dla procesu Nextflow? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Dowiedz się więcej: [2.3.1. Określ kontener dla cowpy](#231-okresl-kontener-dla-cowpy) +</quiz> + +<quiz> +Które ustawienie `nextflow.config` włącza Docker dla Twojego workflow? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Dowiedz się więcej: [2.3.2. Włącz użycie Docker przez plik `nextflow.config`](#232-wlacz-uzycie-docker-przez-plik-nextflowconfig) +</quiz> + +<quiz> +Co Nextflow automatycznie obsługuje podczas uruchamiania procesu w kontenerze? (Wybierz wszystkie pasujące) +- [x] Pobieranie obrazu kontenera w razie potrzeby +- [x] Montowanie katalogu work +- [x] Uruchamianie skryptu procesu wewnątrz kontenera +- [x] Czyszczenie instancji kontenera po wykonaniu + +Dowiedz się więcej: [2.3.4. Sprawdź, jak Nextflow uruchomił skonteneryzowane zadanie](#234-sprawdz-jak-nextflow-uruchomil-skonteneryzowane-zadanie) +</quiz> diff --git a/docs/pl/docs/hello_nextflow/06_hello_config.md b/docs/pl/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..f4b30e9910 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# Część 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Obejrzyj [całą playlistę](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) na kanale YouTube Nextflow. + +:green_book: Transkrypcja wideo jest dostępna [tutaj](./transcripts/06_hello_config.md). +/// + +Ta sekcja zbada, jak skonfigurować i zarządzać konfiguracją pipeline Nextflow, abyś mógł dostosować jego zachowanie, adaptować go do różnych środowisk i optymalizować wykorzystanie zasobów _bez zmiany ani jednej linii samego kodu workflow_. + +Istnieje wiele sposobów, aby to zrobić, które mogą być używane w kombinacji i są interpretowane zgodnie z kolejnością pierwszeństwa opisaną [tutaj](https://www.nextflow.io/docs/latest/config.html). + +W tej części kursu pokażemy Ci najprostszy i najczęściej używany mechanizm pliku konfiguracyjnego, plik `nextflow.config`, który już spotkałeś w Części 5: Hello Containers. + +Omówimy podstawowe komponenty konfiguracji Nextflow, takie jak dyrektywy procesów, executory, profile i pliki parametrów. +Ucząc się efektywnego wykorzystania tych opcji konfiguracyjnych, możesz zwiększyć elastyczność, skalowalność i wydajność swoich pipeline. + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś Części 1-5 kursu [Hello Nextflow](./index.md) i masz kompletny działający pipeline. + + Jeśli zaczynasz kurs od tego miejsca, musisz skopiować katalog `modules` i plik `nextflow.config` z rozwiązań: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + Plik `nextflow.config` zawiera linię `docker.enabled = true`, która włącza użycie kontenerów Docker. + + Jeśli nie znasz pipeline Hello lub potrzebujesz przypomnienia, zobacz [tę stronę informacyjną](../info/hello_pipeline.md). + +--- + +## 0. Rozgrzewka: Uruchom `hello-config.nf` + +Użyjemy skryptu workflow `hello-config.nf` jako punktu wyjścia. +Jest on równoważny skryptowi utworzonemu podczas pracy nad Częścią 5 tego szkolenia, z tą różnicą, że zmieniliśmy miejsca docelowe wyjść: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Aby upewnić się, że wszystko działa, uruchom skrypt raz przed wprowadzeniem jakichkolwiek zmian: + +```bash +nextflow run hello-config.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Jak poprzednio, pliki wyjściowe znajdziesz w katalogu określonym w bloku `output` (`results/hello_config/`). + +??? abstract "Zawartość katalogu" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Końcowa grafika ASCII znajduje się w katalogu `results/hello_config/`, pod nazwą `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Jeśli to zadziałało, jesteś gotowy do nauki konfigurowania pipeline. + +--- + +## 1. Zarządzanie parametrami wejściowymi workflow + +Zaczniemy od aspektu konfiguracji, który jest po prostu rozszerzeniem tego, nad czym pracowaliśmy do tej pory: zarządzanie parametrami wejściowymi. + +Obecnie nasz workflow jest skonfigurowany do przyjmowania wartości parametrów przez wiersz poleceń, z domyślnymi wartościami ustawionymi w bloku `params` w samym skrypcie workflow. +Jednak możesz chcieć nadpisać te wartości domyślne bez konieczności określania parametrów w wierszu poleceń lub modyfikowania oryginalnego pliku skryptu. + +Istnieje wiele sposobów, aby to zrobić; pokażemy Ci trzy podstawowe sposoby, które są bardzo często używane. + +### 1.1. Przenieś domyślne wartości do `nextflow.config` + +To najprostsze podejście, choć prawdopodobnie najmniej elastyczne, ponieważ główny plik `nextflow.config` nie jest czymś, co chcesz edytować przy każdym uruchomieniu. +Ale ma tę zaletę, że oddziela kwestie _deklarowania_ parametrów w workflow (co zdecydowanie tam należy) od dostarczania _domyślnych wartości_, które bardziej pasują do pliku konfiguracyjnego. + +Zróbmy to w dwóch krokach. + +#### 1.1.1. Utwórz blok `params` w pliku konfiguracyjnym + +Wprowadź następujące zmiany w kodzie w pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Zauważ, że nie skopiowaliśmy po prostu bloku `params` z workflow do pliku konfiguracyjnego. +Składnia jest nieco inna. +W pliku workflow są to deklaracje typowane. +W konfiguracji są to przypisania wartości. + +Technicznie to wystarczy do nadpisania domyślnych wartości nadal określonych w pliku workflow. +Możesz zmodyfikować postać, na przykład, i uruchomić workflow, aby upewnić się, że wartość ustawiona w pliku konfiguracyjnym nadpisuje tę ustawioną w pliku workflow. + +Ale w duchu przeniesienia konfiguracji całkowicie do pliku konfiguracyjnego, usuńmy te wartości z pliku workflow. + +#### 1.1.2. Usuń wartości z bloku `params` w pliku workflow + +Wprowadź następujące zmiany w kodzie w pliku workflow `hello-config.nf`: + +=== "Po" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Przed" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Teraz sam plik workflow nie ustawia żadnych domyślnych wartości dla tych parametrów. + +#### 1.1.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie. + +```bash +nextflow run hello-config.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje takie same wyjście jak poprzednio. + +Końcowa grafika ASCII znajduje się w katalogu `results/hello_config/`, pod nazwą `cowpy-COLLECTED-batch-output.txt`, tak samo jak wcześniej. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funkcjonalnie ta zmiana niczego nie zmieniła, ale koncepcyjnie jest nieco czystsze mieć domyślne wartości ustawione w pliku konfiguracyjnym. + +### 1.2. Użyj pliku konfiguracyjnego specyficznego dla uruchomienia + +To świetnie, ale czasami możesz chcieć przeprowadzić tymczasowe eksperymenty z innymi domyślnymi wartościami bez ingerowania w główny plik konfiguracyjny. +Możesz to zrobić, tworząc nowy plik `nextflow.config` w podkatalogu, którego użyjesz jako katalogu roboczego dla swoich eksperymentów. + +#### 1.2.1. Utwórz katalog roboczy z pustą konfiguracją + +Zacznijmy od utworzenia nowego katalogu i przejścia do niego: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Następnie utwórz pusty plik konfiguracyjny w tym katalogu: + +```bash +touch nextflow.config +``` + +To tworzy pusty plik. + +#### 1.2.2. Skonfiguruj eksperymentalną konfigurację + +Teraz otwórz nowy plik i dodaj parametry, które chcesz dostosować: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Zauważ, że ścieżka do pliku wejściowego musi odzwierciedlać strukturę katalogów. + +#### 1.2.3. Uruchom pipeline + +Teraz możemy uruchomić nasz pipeline z naszego nowego katalogu roboczego. +Upewnij się, że dostosujesz ścieżkę odpowiednio! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +To utworzy nowy zestaw katalogów w `tux-run/`, w tym `tux-run/work/` i `tux-run/results/`. + +W tym uruchomieniu Nextflow łączy `nextflow.config` w naszym bieżącym katalogu z `nextflow.config` w katalogu głównym pipeline i tym samym nadpisuje domyślną postać (turkey) postacią tux. + +Końcowy plik wyjściowy powinien zawierać postać tux wypowiadającą pozdrowienia. + +??? abstract "Zawartość pliku" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +To wszystko; teraz masz przestrzeń do eksperymentowania bez modyfikowania swojej 'normalnej' konfiguracji. + +!!! warning "Ostrzeżenie" + + Upewnij się, że wrócisz do poprzedniego katalogu przed przejściem do następnej sekcji! + + ```bash + cd .. + ``` + +Teraz spójrzmy na inny użyteczny sposób ustawiania wartości parametrów. + +### 1.3. Użyj pliku parametrów + +Podejście z podkatalogiem świetnie sprawdza się do eksperymentowania, ale wymaga trochę konfiguracji i wymaga dostosowania ścieżek. +Jest prostsze podejście, gdy chcesz uruchomić pipeline z konkretnym zestawem wartości lub umożliwić komuś innemu zrobienie tego z minimalnym wysiłkiem. + +Nextflow pozwala nam określić parametry za pomocą pliku parametrów w formacie YAML lub JSON, co sprawia, że bardzo wygodne jest zarządzanie i dystrybuowanie alternatywnych zestawów domyślnych wartości, na przykład, jak również wartości parametrów specyficznych dla uruchomienia. + +#### 1.3.1. Przejrzyj przykładowy plik parametrów + +Aby to zademonstrować, dostarczamy przykładowy plik parametrów w bieżącym katalogu o nazwie `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Ten plik parametrów zawiera parę klucz-wartość dla każdego z wejść, które chcemy określić. +Zauważ użycie dwukropków (`:`) zamiast znaków równości (`=`), jeśli porównasz składnię z plikiem konfiguracyjnym. +Plik konfiguracyjny jest napisany w Groovy, podczas gdy plik parametrów jest napisany w YAML. + +!!! info "Informacja" + + Dostarczamy również wersję JSON pliku parametrów jako przykład, ale nie będziemy jej tutaj uruchamiać. + Możesz spróbować samodzielnie. + +#### 1.3.2. Uruchom pipeline + +Aby uruchomić workflow z tym plikiem parametrów, po prostu dodaj `-params-file <nazwa_pliku>` do podstawowego polecenia. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Końcowy plik wyjściowy powinien zawierać postać stegosaurus wypowiadającą pozdrowienia. + +??? abstract "Zawartość pliku" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Używanie pliku parametrów może wydawać się przesadą, gdy masz tylko kilka parametrów do określenia, ale niektóre pipeline oczekują dziesiątek parametrów. +W takich przypadkach użycie pliku parametrów pozwoli nam podać wartości parametrów w czasie wykonania bez konieczności wpisywania masywnych poleceń wiersza poleceń i bez modyfikowania skryptu workflow. + +Ułatwia to również dystrybucję zestawów parametrów do współpracowników lub jako informacji uzupełniających do publikacji, na przykład. +To sprawia, że Twoja praca jest bardziej powtarzalna przez innych. + +### Podsumowanie + +Wiesz już, jak wykorzystać kluczowe opcje konfiguracyjne do zarządzania wejściami workflow. + +### Co dalej? + +Dowiedz się, jak zarządzać tym, gdzie i jak publikowane są wyjścia workflow. + +--- + +## 2. Zarządzanie wyjściami workflow + +Do tej pory kodowaliśmy na sztywno wszystkie ścieżki dla deklaracji wyjść na poziomie workflow i, jak zauważyliśmy, gdy zaczęliśmy dodawać wiele wyjść, może to powodować pewne powtórzenia. + +Przyjrzyjmy się kilku typowym sposobom konfiguracji, aby było to bardziej elastyczne. + +### 2.1. Dostosuj nazwę katalogu `outputDir` + +W każdym rozdziale tego kursu publikowaliśmy wyjścia do innego podkatalogu zakodowanego na sztywno w definicjach wyjść. + +Zmieńmy to, aby używać konfigurowalnego przez użytkownika parametru. +Moglibyśmy utworzyć zupełnie nowy parametr do tego celu, ale użyjmy parametru `batch`, skoro jest pod ręką. + +#### 2.1.1. Ustaw wartość dla `outputDir` w pliku konfiguracyjnym + +Ścieżka, której Nextflow używa do publikowania wyjść, jest kontrolowana przez opcję `outputDir`. +Aby zmienić ścieżkę dla wszystkich wyjść, możesz ustawić wartość dla tej opcji w pliku konfiguracyjnym `nextflow.config`. + +Dodaj następujący kod do pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +To zastąpi wbudowaną domyślną ścieżkę, `results/`, ścieżką `results/` plus wartość parametru `batch` jako podkatalog. +Możesz również zmienić część `results`, jeśli chcesz. + +Dla tymczasowej zmiany możesz ustawić tę opcję z wiersza poleceń używając parametru `-output-dir` w poleceniu (ale wtedy nie możesz użyć wartości parametru `batch`). + +#### 2.1.2. Usuń powtarzającą się część zakodowanej na sztywno ścieżki + +Nadal mamy podkatalog zakodowany na sztywno w opcjach wyjścia, więc pozbądźmy się tego teraz. + +Wprowadź następujące zmiany w kodzie w pliku workflow: + +=== "Po" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +Mogliśmy również po prostu dodać `${params.batch}` do każdej ścieżki zamiast modyfikować domyślną wartość `outputDir`, ale to jest bardziej zwięzłe. + +#### 2.1.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę partii na `outdir` z wiersza poleceń. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje takie same wyjście jak poprzednio, z tą różnicą, że tym razem nasze wyjścia znajdują się w `results/outdir/`. + +??? abstract "Zawartość katalogu" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Możesz połączyć to podejście z niestandardowymi definicjami ścieżek, aby skonstruować dowolną hierarchię katalogów, jaką chcesz. + +### 2.2. Organizuj wyjścia według procesu + +Jednym z popularnych sposobów dalszej organizacji wyjść jest robienie tego według procesu, tzn. tworzenie podkatalogów dla każdego procesu uruchomionego w pipeline. + +#### 2.2.1. Zastąp ścieżki wyjść odwołaniem do nazw procesów + +Wystarczy odwołać się do nazwy procesu jako `<task>.name` w deklaracji ścieżki wyjścia. + +Wprowadź następujące zmiany w pliku workflow: + +=== "Po" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +To usuwa pozostałe zakodowane na sztywno elementy z konfiguracji ścieżki wyjścia. + +#### 2.2.2. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę partii na `pnames` z wiersza poleceń. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje takie same wyjście jak poprzednio, z tą różnicą, że tym razem nasze wyjścia znajdują się w `results/pnames/` i są pogrupowane według procesu. + +??? abstract "Zawartość katalogu" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Zauważ, że tutaj usunęliśmy rozróżnienie między `intermediates` a końcowymi wyjściami na najwyższym poziomie. +Możesz oczywiście mieszać i dopasowywać te podejścia, na przykład ustawiając ścieżkę pierwszego wyjścia jako `intermediates/${sayHello.process}` + +### 2.3. Ustaw tryb publikacji na poziomie workflow + +Na koniec, w duchu redukcji ilości powtarzającego się kodu, możemy zastąpić deklaracje `mode` dla każdego wyjścia pojedynczą linią w konfiguracji. + +#### 2.3.1. Dodaj `workflow.output.mode` do pliku konfiguracyjnego + +Dodaj następujący kod do pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Podobnie jak opcja `outputDir`, nadanie `workflow.output.mode` wartości w pliku konfiguracyjnym wystarczyłoby do nadpisania tego, co jest ustawione w pliku workflow, ale i tak usuńmy niepotrzebny kod. + +#### 2.3.2. Usuń tryb wyjścia z pliku workflow + +Wprowadź następujące zmiany w pliku workflow: + +=== "Po" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Przed" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +To bardziej zwięzłe, prawda? + +#### 2.3.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę partii na `outmode` z wiersza poleceń. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje takie same wyjście jak poprzednio, z tą różnicą, że tym razem nasze wyjścia znajdują się w `results/outmode/`. +Nadal są to wszystkie właściwe kopie, a nie dowiązania symboliczne. + +??? abstract "Zawartość katalogu" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Głównym powodem, dla którego możesz chcieć używać sposobu ustawiania trybu dla każdego wyjścia osobno, jest sytuacja, gdy chcesz mieszać i dopasowywać w ramach tego samego workflow, tzn. mieć niektóre wyjścia kopiowane, a niektóre dowiązywane symbolicznie. + +Jest wiele innych opcji, które możesz dostosować w ten sposób, ale mam nadzieję, że to daje Ci poczucie zakresu opcji i tego, jak je efektywnie wykorzystać zgodnie z Twoimi preferencjami. + +### Podsumowanie + +Wiesz już, jak kontrolować nazewnictwo i strukturę katalogów, w których publikowane są wyjścia, a także tryb publikacji wyjść workflow. + +### Co dalej? + +Dowiedz się, jak dostosować konfigurację workflow do środowiska obliczeniowego, zaczynając od technologii pakowania oprogramowania. + +--- + +## 3. Wybierz technologię pakowania oprogramowania + +Do tej pory przyglądaliśmy się elementom konfiguracji kontrolującym, jak wejścia trafiają do pipeline i gdzie wychodzą wyjścia. Teraz czas skupić się bardziej konkretnie na dostosowaniu konfiguracji workflow do środowiska obliczeniowego. + +Pierwszym krokiem na tej ścieżce jest określenie, skąd będą pochodzić pakiety oprogramowania uruchamiane w każdym kroku. +Czy są już zainstalowane w lokalnym środowisku obliczeniowym? +Czy musimy pobrać obrazy i uruchomić je przez system kontenerowy? +A może musimy pobrać pakiety Conda i zbudować lokalne środowisko Conda? + +W pierwszej części tego kursu (Części 1-4) używaliśmy po prostu lokalnie zainstalowanego oprogramowania w naszym workflow. +Następnie w Części 5 wprowadziliśmy kontenery Docker i plik `nextflow.config`, którego użyliśmy do włączenia użycia kontenerów Docker. + +Teraz zobaczmy, jak możemy skonfigurować alternatywną opcję pakowania oprogramowania przez plik `nextflow.config`. + +### 3.1. Wyłącz Docker i włącz Conda w pliku konfiguracyjnym + +Udawajmy, że pracujemy na klastrze HPC i administrator nie zezwala na użycie Docker ze względów bezpieczeństwa. +Na szczęście dla nas Nextflow obsługuje wiele innych technologii kontenerowych, w tym Singularity (który jest szerzej używany na HPC), oraz menedżery pakietów oprogramowania takie jak Conda. + +Możemy zmienić nasz plik konfiguracyjny, aby używać Conda zamiast Docker. +W tym celu zmieńmy wartość `docker.enabled` na `false` i dodajmy dyrektywę włączającą użycie Conda: + +=== "Po" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +To pozwoli Nextflow tworzyć i wykorzystywać środowiska Conda dla procesów, które mają określone pakiety Conda. +Co oznacza, że teraz musimy dodać jeden z nich do naszego procesu `cowpy`! + +### 3.2. Określ pakiet Conda w definicji procesu + +Pobraliśmy już URI dla pakietu Conda zawierającego narzędzie `cowpy`: `conda-forge::cowpy==1.1.5` + +Teraz dodajemy URI do definicji procesu `cowpy` używając dyrektywy `conda`: + +=== "Po" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Przed" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Żeby było jasne, nie _zastępujemy_ dyrektywy `docker`, _dodajemy_ alternatywną opcję. + +!!! tip "Wskazówka" + + Jest kilka różnych sposobów na uzyskanie URI dla danego pakietu Conda. + Zalecamy użycie wyszukiwarki [Seqera Containers](https://seqera.io/containers/), która da Ci URI, które możesz skopiować i wkleić, nawet jeśli nie planujesz tworzyć z niego kontenera. + +### 3.3. Uruchom workflow, aby sprawdzić, czy może używać Conda + +Spróbujmy. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Wynik polecenia" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +To powinno działać bez problemu i produkować takie same wyjścia jak poprzednio w `results/conda`. + +Za kulisami Nextflow pobrał pakiety Conda i utworzył środowisko, co normalnie wymaga trochę pracy; więc miło jest, że nie musimy niczego robić sami! + +!!! note "Uwaga" + + To działa szybko, ponieważ pakiet `cowpy` jest dość mały, ale jeśli pracujesz z dużymi pakietami, może to zająć trochę więcej czasu za pierwszym razem i możesz zobaczyć, że wyjście konsoli pozostaje 'zawieszone' przez minutę lub dłużej przed zakończeniem. + To normalne i wynika z dodatkowej pracy, którą Nextflow wykonuje przy pierwszym użyciu nowego pakietu. + +Z naszej perspektywy wygląda to tak, jakby działało dokładnie tak samo jak uruchamianie z Docker, mimo że w tle mechanika jest nieco inna. + +Oznacza to, że jesteśmy gotowi do uruchamiania ze środowiskami Conda w razie potrzeby. + +??? info "Mieszanie Docker i Conda" + + Ponieważ te dyrektywy są przypisywane do każdego procesu osobno, możliwe jest 'mieszanie i dopasowywanie', tzn. konfigurowanie niektórych procesów w workflow do uruchamiania z Docker, a innych z Conda, na przykład, jeśli używana infrastruktura obliczeniowa obsługuje oba. + W takim przypadku włączyłbyś zarówno Docker, jak i Conda w pliku konfiguracyjnym. + Jeśli oba są dostępne dla danego procesu, Nextflow priorytetyzuje kontenery. + + Jak wspomniano wcześniej, Nextflow obsługuje wiele innych technologii pakowania oprogramowania i kontenerowych, więc nie jesteś ograniczony tylko do tych dwóch. + +### Podsumowanie + +Wiesz już, jak skonfigurować, jakiego pakietu oprogramowania każdy proces powinien używać, i jak przełączać się między technologiami. + +### Co dalej? + +Dowiedz się, jak zmienić platformę wykonawczą używaną przez Nextflow do faktycznego wykonywania pracy. + +--- + +## 4. Wybierz platformę wykonawczą + +Do tej pory uruchamialiśmy nasz pipeline z lokalnym executorem. +Wykonuje on każde zadanie na maszynie, na której działa Nextflow. +Gdy Nextflow startuje, sprawdza dostępne procesory i pamięć. +Jeśli zasoby zadań gotowych do uruchomienia przekraczają dostępne zasoby, Nextflow wstrzyma ostatnie zadania przed wykonaniem, dopóki jedno lub więcej wcześniejszych zadań nie zakończy się, zwalniając niezbędne zasoby. + +Lokalny executor jest wygodny i wydajny, ale jest ograniczony do tej pojedynczej maszyny. Przy bardzo dużych obciążeniach możesz odkryć, że Twoja lokalna maszyna jest wąskim gardłem, albo dlatego, że masz pojedyncze zadanie wymagające więcej zasobów niż masz dostępne, albo dlatego, że masz tak wiele zadań, że czekanie na pojedynczą maszynę, aby je uruchomić, trwałoby zbyt długo. + +Nextflow obsługuje [wiele różnych backendów wykonawczych](https://www.nextflow.io/docs/latest/executor.html), w tym harmonogramy HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor i inne), a także backenty wykonawcze w chmurze (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes i więcej). + +### 4.1. Kierowanie na inny backend + +Wybór executora jest ustawiany przez dyrektywę procesu o nazwie `executor`. +Domyślnie jest ustawiony na `local`, więc następująca konfiguracja jest domyślna: + +```groovy title="Wbudowana konfiguracja" +process { + executor = 'local' +} +``` + +Aby ustawić executor na inny backend, wystarczy określić żądany executor używając podobnej składni jak opisano powyżej dla alokacji zasobów (zobacz [dokumentację](https://www.nextflow.io/docs/latest/executor.html) dla wszystkich opcji). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Ostrzeżenie" + + Nie możemy tego przetestować w środowisku szkoleniowym, ponieważ nie jest ono skonfigurowane do łączenia się z HPC. + +### 4.2. Radzenie sobie ze składnią specyficzną dla backendu dla parametrów wykonania + +Większość platform obliczeniowych wysokiej wydajności pozwala (a czasami wymaga), abyś określił pewne parametry, takie jak żądania alokacji zasobów i ograniczenia (np. liczba procesorów i pamięć) oraz nazwę kolejki zadań do użycia. + +Niestety, każdy z tych systemów używa różnych technologii, składni i konfiguracji do definiowania, jak zadanie powinno być zdefiniowane i przesłane do odpowiedniego harmonogramu. + +??? abstract "Przykłady" + + Na przykład, to samo zadanie wymagające 8 procesorów i 4GB RAM do wykonania w kolejce "my-science-work" musi być wyrażone w różny sposób w zależności od backendu. + + ```bash title="Konfiguracja dla SLURM / wysyłanie przez sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Konfiguracja dla PBS / wysyłanie przez qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Konfiguracja dla SGE / wysyłanie przez qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Na szczęście Nextflow upraszcza to wszystko. +Dostarcza ustandaryzowaną składnię, dzięki której możesz określić odpowiednie właściwości takie jak `cpus`, `memory` i `queue` (zobacz dokumentację dla innych właściwości) tylko raz. +Następnie, w czasie wykonania, Nextflow użyje tych ustawień do wygenerowania odpowiednich skryptów specyficznych dla backendu na podstawie ustawienia executora. + +Omówimy tę ustandaryzowaną składnię w następnej sekcji. + +### Podsumowanie + +Wiesz już, jak zmienić executor, aby używać różnych rodzajów infrastruktury obliczeniowej. + +### Co dalej? + +Dowiedz się, jak oceniać i wyrażać alokacje zasobów i ograniczenia w Nextflow. + +--- + +## 5. Kontroluj alokacje zasobów obliczeniowych + +Większość platform obliczeniowych wysokiej wydajności pozwala (a czasami wymaga), abyś określił pewne parametry alokacji zasobów, takie jak liczba procesorów i pamięć. + +Domyślnie Nextflow użyje jednego procesora i 2GB pamięci dla każdego procesu. +Odpowiednie dyrektywy procesu nazywają się `cpus` i `memory`, więc następująca konfiguracja jest domyślna: + +```groovy title="Wbudowana konfiguracja" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Możesz modyfikować te wartości, dla wszystkich procesów lub dla konkretnych nazwanych procesów, używając dodatkowych dyrektyw procesu w pliku konfiguracyjnym. +Nextflow przetłumaczy je na odpowiednie instrukcje dla wybranego executora. + +Ale skąd wiesz, jakich wartości użyć? + +### 5.1. Uruchom workflow, aby wygenerować raport wykorzystania zasobów + +Jeśli nie wiesz z góry, ile procesora i pamięci Twoje procesy prawdopodobnie będą potrzebować, możesz przeprowadzić profilowanie zasobów, co oznacza, że uruchamiasz workflow z domyślnymi alokacjami, rejestrujesz, ile każdy proces użył, i na tej podstawie szacujesz, jak dostosować bazowe alokacje. + +Wygodnie jest to, że Nextflow zawiera wbudowane narzędzia do tego i chętnie wygeneruje dla Ciebie raport na żądanie. + +Aby to zrobić, dodaj `-with-report <nazwa_pliku>.html` do wiersza poleceń. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Raport to plik html, który możesz pobrać i otworzyć w przeglądarce. Możesz również kliknąć go prawym przyciskiem myszy w eksploratorze plików po lewej stronie i kliknąć `Show preview`, aby wyświetlić go w środowisku szkoleniowym. + +Poświęć kilka minut na przejrzenie raportu i sprawdź, czy możesz zidentyfikować możliwości dostosowania zasobów. +Upewnij się, że klikasz na zakładki pokazujące wyniki wykorzystania jako procent tego, co zostało przydzielone. +Jest [dokumentacja](https://www.nextflow.io/docs/latest/reports.html) opisująca wszystkie dostępne funkcje. + +### 5.2. Ustaw alokacje zasobów dla wszystkich procesów + +Profilowanie pokazuje, że procesy w naszym szkoleniowym workflow są bardzo lekkie, więc zmniejszmy domyślną alokację pamięci do 1GB na proces. + +Dodaj następujący kod do pliku `nextflow.config`, przed sekcją parametrów pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +To pomoże zmniejszyć ilość zużywanej mocy obliczeniowej. + +### 5.3. Ustaw alokacje zasobów dla konkretnego procesu + +Jednocześnie udawajmy, że proces `cowpy` wymaga więcej zasobów niż inne, tylko po to, abyśmy mogli zademonstrować, jak dostosować alokacje dla indywidualnego procesu. + +=== "Po" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Z tą konfiguracją wszystkie procesy będą żądać 1GB pamięci i jednego procesora (domyślna wartość domniemana), z wyjątkiem procesu `cowpy`, który będzie żądał 2GB i 2 procesorów. + +!!! tip "Wskazówka" + + Jeśli masz maszynę z małą liczbą procesorów i przydzielasz dużą liczbę na proces, możesz zobaczyć, że wywołania procesów są kolejkowane jedno za drugim. + To dlatego, że Nextflow zapewnia, że nie żądamy więcej procesorów niż jest dostępnych. + +### 5.4. Uruchom workflow ze zaktualizowaną konfiguracją + +Spróbujmy, dostarczając inną nazwę pliku dla raportu profilowania, abyśmy mogli porównać wydajność przed i po zmianach konfiguracji. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Prawdopodobnie nie zauważysz żadnej rzeczywistej różnicy, ponieważ to takie małe obciążenie, ale to jest podejście, którego użyłbyś do analizy wydajności i wymagań zasobowych rzeczywistego workflow. + +Jest to bardzo przydatne, gdy Twoje procesy mają różne wymagania zasobowe. Daje Ci to możliwość odpowiedniego doboru alokacji zasobów dla każdego procesu na podstawie rzeczywistych danych, a nie zgadywania. + +!!! tip "Wskazówka" + + To tylko mały przedsmak tego, co możesz zrobić, aby zoptymalizować wykorzystanie zasobów. + Sam Nextflow ma wbudowaną naprawdę fajną [dynamiczną logikę ponawiania](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources), która ponawia zadania, które nie powiodły się z powodu ograniczeń zasobów. + Dodatkowo platforma Seqera oferuje narzędzia oparte na AI do automatycznej optymalizacji alokacji zasobów. + +### 5.5. Dodaj limity zasobów + +W zależności od tego, jakiego executora i infrastruktury obliczeniowej używasz, mogą istnieć pewne ograniczenia dotyczące tego, co możesz (lub musisz) przydzielić. +Na przykład Twój klaster może wymagać, abyś pozostał w określonych limitach. + +Możesz użyć dyrektywy `resourceLimits`, aby ustawić odpowiednie ograniczenia. Składnia wygląda tak, gdy jest sama w bloku process: + +```groovy title="Przykład składni" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow przetłumaczy te wartości na odpowiednie instrukcje w zależności od określonego executora. + +Nie będziemy tego uruchamiać, ponieważ nie mamy dostępu do odpowiedniej infrastruktury w środowisku szkoleniowym. +Jednak gdybyś spróbował uruchomić workflow z alokacjami zasobów przekraczającymi te limity, a następnie sprawdził polecenie `sbatch` w pliku skryptu `.command.run`, zobaczyłbyś, że żądania faktycznie wysyłane do executora są ograniczone do wartości określonych przez `resourceLimits`. + +??? info "Konfiguracje referencyjne instytucji" + + Projekt nf-core skompilował [zbiór plików konfiguracyjnych](https://nf-co.re/configs/) udostępnionych przez różne instytucje na całym świecie, obejmujących szeroki zakres executorów HPC i chmurowych. + + Te współdzielone konfiguracje są wartościowe zarówno dla osób, które tam pracują i mogą zatem po prostu wykorzystać konfigurację swojej instytucji od razu, jak i jako model dla osób, które chcą opracować konfigurację dla własnej infrastruktury. + +### Podsumowanie + +Wiesz już, jak generować raport profilowania do oceny wykorzystania zasobów i jak modyfikować alokacje zasobów dla wszystkich procesów i/lub dla indywidualnych procesów, a także ustawiać ograniczenia zasobów dla uruchamiania na HPC. + +### Co dalej? + +Dowiedz się, jak skonfigurować predefiniowane profile konfiguracji i przełączać się między nimi w czasie wykonania. + +--- + +## 6. Używaj profili do przełączania między predefiniowanymi konfiguracjami + +Pokazaliśmy Ci wiele sposobów dostosowywania konfiguracji pipeline w zależności od projektu, nad którym pracujesz, lub środowiska obliczeniowego, którego używasz. + +Możesz chcieć przełączać się między alternatywnymi ustawieniami w zależności od tego, jakiej infrastruktury obliczeniowej używasz. Na przykład możesz chcieć rozwijać i uruchamiać małe testy lokalnie na laptopie, a następnie uruchamiać pełnoskalowe obciążenia na HPC lub w chmurze. + +Nextflow pozwala skonfigurować dowolną liczbę profili opisujących różne konfiguracje, które możesz następnie wybrać w czasie wykonania używając argumentu wiersza poleceń, zamiast modyfikować sam plik konfiguracyjny. + +### 6.1. Utwórz profile do przełączania między lokalnym rozwojem a wykonaniem na HPC + +Skonfigurujmy dwa alternatywne profile; jeden do uruchamiania małych obciążeń na zwykłym komputerze, gdzie będziemy używać kontenerów Docker, i jeden do uruchamiania na uniwersyteckim HPC z harmonogramem Slurm, gdzie będziemy używać pakietów Conda. + +#### 6.1.1. Skonfiguruj profile + +Dodaj następujący kod do pliku `nextflow.config`, po sekcji parametrów pipeline, ale przed ustawieniami wyjść: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Widzisz, że dla uniwersyteckiego HPC określamy również ograniczenia zasobów. + +#### 6.1.2. Uruchom workflow z profilem + +Aby określić profil w naszym poleceniu Nextflow, używamy argumentu `-profile`. + +Spróbujmy uruchomić workflow z konfiguracją `my_laptop`. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Jak widać, pozwala nam to bardzo wygodnie przełączać się między konfiguracjami w czasie wykonania. + +!!! warning "Ostrzeżenie" + + Profil `univ_hpc` nie będzie działał poprawnie w środowisku szkoleniowym, ponieważ nie mamy dostępu do harmonogramu Slurm. + +Jeśli w przyszłości znajdziemy inne elementy konfiguracji, które zawsze współwystępują z tymi, możemy po prostu dodać je do odpowiednich profili. +Możemy również tworzyć dodatkowe profile, jeśli są inne elementy konfiguracji, które chcemy pogrupować razem. + +### 6.2. Utwórz profil parametrów testowych + +Profile nie są tylko do konfiguracji infrastruktury. +Możemy ich również używać do ustawiania domyślnych wartości dla parametrów workflow, aby ułatwić innym wypróbowanie workflow bez konieczności samodzielnego zbierania odpowiednich wartości wejściowych. +Możesz to uznać za alternatywę dla używania pliku parametrów. + +#### 6.2.1. Skonfiguruj profil + +Składnia wyrażania domyślnych wartości w tym kontekście wygląda tak, dla profilu, który nazwiemy `test`: + +```groovy title="Przykład składni" + test { + params.<parametr1> + params.<parametr2> + ... + } +``` + +Jeśli dodamy profil testowy dla naszego workflow, blok `profiles` staje się: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Podobnie jak w przypadku profili konfiguracji technicznej, możesz skonfigurować wiele różnych profili określających parametry pod dowolną nazwą. + +#### 6.2.2. Uruchom workflow lokalnie z profilem testowym + +Wygodnie jest to, że profile nie wykluczają się wzajemnie, więc możemy określić wiele profili w naszym poleceniu używając następującej składni `-profile <profil1>,<profil2>` (dla dowolnej liczby profili). + +Jeśli łączysz profile, które ustawiają wartości dla tych samych elementów konfiguracji i są opisane w tym samym pliku konfiguracyjnym, Nextflow rozwiąże konflikt, używając wartości, którą wczytał jako ostatnią (tzn. cokolwiek pojawia się później w pliku). +Jeśli konfliktowe ustawienia są ustawione w różnych źródłach konfiguracji, obowiązuje domyślna [kolejność pierwszeństwa](https://www.nextflow.io/docs/latest/config.html). + +Spróbujmy dodać profil testowy do naszego poprzedniego polecenia: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +To użyje Docker tam, gdzie to możliwe, i wyprodukuje wyjścia w `results/test`, a tym razem postać to komediowy duet `dragonandcow`. + +??? abstract "Zawartość pliku" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +To oznacza, że dopóki dystrybuujemy pliki danych testowych wraz z kodem workflow, każdy może szybko wypróbować workflow bez konieczności dostarczania własnych wejść przez wiersz poleceń lub plik parametrów. + +!!! tip "Wskazówka" + + Możemy wskazywać na adresy URL dla większych plików przechowywanych zewnętrznie. + Nextflow pobierze je automatycznie, o ile jest otwarte połączenie. + + Więcej szczegółów znajdziesz w Side Quest [Praca z plikami](../side_quests/working_with_files.md) + +### 6.3. Użyj `nextflow config`, aby zobaczyć rozwiązaną konfigurację + +Jak wspomniano powyżej, czasami ten sam parametr może być ustawiony na różne wartości w profilach, które chcesz połączyć. +I bardziej ogólnie, jest wiele miejsc, gdzie elementy konfiguracji mogą być przechowywane, a czasami te same właściwości mogą być ustawione na różne wartości w różnych miejscach. + +Nextflow stosuje ustaloną [kolejność pierwszeństwa](https://www.nextflow.io/docs/latest/config.html) do rozwiązywania konfliktów, ale może to być trudne do samodzielnego określenia. +A nawet jeśli nic nie jest w konflikcie, może być nużące przeglądanie wszystkich możliwych miejsc, gdzie rzeczy mogłyby być skonfigurowane. + +Na szczęście Nextflow zawiera wygodne narzędzie o nazwie `config`, które może zautomatyzować cały ten proces za Ciebie. + +Narzędzie `config` przeszuka całą zawartość w Twoim bieżącym katalogu roboczym, zbierze wszystkie pliki konfiguracyjne i wyprodukuje w pełni rozwiązaną konfigurację, której Nextflow użyłby do uruchomienia workflow. +Pozwala to dowiedzieć się, jakie ustawienia zostaną użyte, bez konieczności uruchamiania czegokolwiek. + +#### 6.3.1. Rozwiąż domyślną konfigurację + +Uruchom to polecenie, aby rozwiązać konfigurację, która byłaby zastosowana domyślnie. + +```bash +nextflow config +``` + +??? success "Wynik polecenia" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +To pokazuje bazową konfigurację, którą otrzymujesz, jeśli nie określisz niczego dodatkowego w wierszu poleceń. + +#### 6.3.2. Rozwiąż konfigurację z aktywowanymi konkretnymi ustawieniami + +Jeśli podasz parametry wiersza poleceń, np. włączając jeden lub więcej profili lub ładując plik parametrów, polecenie dodatkowo je uwzględni. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Wynik polecenia" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +To staje się szczególnie przydatne dla złożonych projektów, które obejmują wiele warstw konfiguracji. + +### Podsumowanie + +Wiesz już, jak używać profili do wybierania predefiniowanej konfiguracji w czasie wykonania z minimalnym wysiłkiem. +Bardziej ogólnie, wiesz, jak konfigurować wykonania workflow, aby pasowały do różnych platform obliczeniowych i zwiększały powtarzalność Twoich analiz. + +### Co dalej? + +Świętuj i pogratuluj sobie! Ukończyłeś swój pierwszy kurs dla deweloperów Nextflow. + +Przejdź do końcowego [podsumowania kursu](./next_steps.md), aby przejrzeć, czego się nauczyłeś i dowiedzieć się, co dalej. + +--- + +## Quiz + +<quiz> +Jak nazywa się plik konfiguracyjny, który Nextflow automatycznie ładuje? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +Co ma pierwszeństwo, gdy ten sam parametr jest ustawiony zarówno w pliku konfiguracyjnym, jak i w wierszu poleceń? +- [ ] Wartość z pliku konfiguracyjnego +- [x] Wartość z wiersza poleceń +- [ ] Pierwsza napotkana wartość +- [ ] Żadna; powoduje to błąd + +Dowiedz się więcej: [1.1. Przenieś domyślne wartości do `nextflow.config`](#11-przenies-domyslne-wartosci-do-nextflowconfig) +</quiz> + +<quiz> +Czy możesz mieć włączone zarówno Docker, jak i Conda w tej samej konfiguracji? +- [x] Tak, Nextflow może używać obu w zależności od dyrektyw procesu +- [ ] Nie, tylko jedno może być włączone naraz +- [ ] Tak, ale tylko w profilach +- [ ] Nie, wykluczają się wzajemnie +</quiz> + +<quiz> +Jeśli zarówno Docker, jak i Conda są włączone, a proces ma obie dyrektywy, które jest priorytetyzowane? +- [x] Docker (kontenery) +- [ ] Conda +- [ ] To, które jest zdefiniowane jako pierwsze +- [ ] Powoduje to błąd + +Dowiedz się więcej: [3. Wybierz technologię pakowania oprogramowania](#3-wybierz-technologie-pakowania-oprogramowania) +</quiz> + +<quiz> +Jaka jest domyślna alokacja pamięci dla procesów Nextflow? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] Bez limitu +</quiz> + +<quiz> +Jak ustawiasz wymagania zasobów dla konkretnego procesu w pliku konfiguracyjnym? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +Dowiedz się więcej: [5.3. Ustaw alokacje zasobów dla konkretnego procesu](#53-ustaw-alokacje-zasobow-dla-konkretnego-procesu) +</quiz> + +<quiz> +Jaka opcja wiersza poleceń generuje raport wykorzystania zasobów? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +Dowiedz się więcej: [5.1. Uruchom workflow, aby wygenerować raport wykorzystania zasobów](#51-uruchom-workflow-aby-wygenerowac-raport-wykorzystania-zasobow) +</quiz> + +<quiz> +Co robi dyrektywa `resourceLimits`? +- [ ] Ustawia minimalne wymagania zasobów +- [ ] Przydziela zasoby do procesów +- [x] Ogranicza maksymalne zasoby, które mogą być żądane +- [ ] Monitoruje wykorzystanie zasobów + +Dowiedz się więcej: [5.5. Dodaj limity zasobów](#55-dodaj-limity-zasobow) +</quiz> + +<quiz> +Jaki jest domyślny executor w Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Dowiedz się więcej: [4. Wybierz platformę wykonawczą](#4-wybierz-platforme-wykonawcza) +</quiz> + +<quiz> +Jak określasz plik parametrów podczas uruchamiania Nextflow? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +Dowiedz się więcej: [1.3. Użyj pliku parametrów](#13-uzyj-pliku-parametrow) +</quiz> + +<quiz> +Do czego mogą być używane profile? (Wybierz wszystkie pasujące) +- [x] Definiowanie ustawień specyficznych dla infrastruktury +- [x] Ustawianie limitów zasobów dla różnych środowisk +- [x] Dostarczanie parametrów testowych +- [ ] Definiowanie nowych procesów + +Dowiedz się więcej: [6. Używaj profili do przełączania między predefiniowanymi konfiguracjami](#6-uzywaj-profili-do-przelaczania-miedzy-predefiniowanymi-konfiguracjami) +</quiz> + +<quiz> +Jak określasz wiele profili w pojedynczym poleceniu? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Dowiedz się więcej: [6. Używaj profili do przełączania między predefiniowanymi konfiguracjami](#6-uzywaj-profili-do-przelaczania-miedzy-predefiniowanymi-konfiguracjami) +</quiz> diff --git a/docs/pl/docs/hello_nextflow/index.md b/docs/pl/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..c5e902a2af --- /dev/null +++ b/docs/pl/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Uruchamianie i zarządzanie wykonywaniem workflow'ów Nextflow + - Znajdowanie i interpretowanie wyjść (wyników) i plików dziennika generowanych przez Nextflow + - Rozwiązywanie podstawowych problemów + - Budowanie prostego wieloetapowego workflow'u z podstawowych komponentów Nextflow + - Rozróżnianie między podstawowymi typami channel factories i operatorów oraz efektywne ich wykorzystywanie w prostym workflow'ie + - Konfigurowanie wykonywania pipeline'u do uruchamiania na popularnych platformach obliczeniowych, w tym HPC i chmurze + - Stosowanie najlepszych praktyk dotyczących powtarzalności, przenośności i ponownego wykorzystania kodu, które czynią pipeline'y FAIR, w tym modularność kodu i kontenery oprogramowania + audience_prerequisites: + - "**Odbiorcy:** Ten kurs jest przeznaczony dla osób, które są całkowicie nowe w Nextflow i chcą tworzyć własne pipeline'y." + - "**Umiejętności:** Zakłada się pewną znajomość wiersza poleceń, podstawowych koncepcji skryptowych i popularnych formatów plików." + - "**Dziedzina:** Ćwiczenia są niezależne od dziedziny, więc nie jest wymagana wcześniejsza wiedza naukowa." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow to praktyczne wprowadzenie do budowania powtarzalnych i skalowalnych workflow'ów analizy danych.** + +Pracując z praktycznymi przykładami i prowadzonymi ćwiczeniami, poznasz podstawy tworzenia pipeline'ów w Nextflow, w tym jak definiować procesy, łączyć je w pipeline'y, zarządzać plikami i zależnościami oprogramowania, bez wysiłku równolegle wykonywać zadania i uruchamiać workflow'y w różnych środowiskach obliczeniowych. + +Wyniesiesz umiejętności i pewność siebie, aby zacząć tworzyć i uruchamiać własne workflow'y w Nextflow. + +<!-- additional_information --> + +## Przegląd kursu + +Ten kurs jest zaprojektowany jako praktyczny, z ćwiczeniami zorientowanymi na cel, strukturyzowanymi tak, aby wprowadzać informacje stopniowo. + +Stworzysz prosty pipeline Nextflow, który przyjmuje tekstowe dane wejściowe, wykonuje kilka kroków transformacji i generuje pojedynczy plik tekstowy zawierający obraz ASCII postaci wypowiadającej przekształcony tekst. + +### Plan lekcji + +Aby uniknąć przytłoczenia Cię koncepcjami i kodem, podzieliliśmy to na sześć części, z których każda skupia się na konkretnych aspektach tworzenia pipeline'ów w Nextflow. + +| Rozdział kursu | Podsumowanie | Szacowany czas | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Część 1: Hello World](./01_hello_world.md) | Podstawowe komponenty i zasady składania i uruchamiania workflow'u Nextflow | 30 min | +| [Część 2: Hello Channels](./02_hello_channels.md) | Używanie kanałów i operatorów do przetwarzania wejść i bezwysiłkowej równoległości wykonywania | 45 min | +| [Część 3: Hello Workflow](./03_hello_workflow.md) | Używanie kanałów do łączenia wielu kroków i obsługi transferu danych między krokami | 60 min | +| [Część 4: Hello Modules](./04_hello_modules.md) | Stosowanie zasad modularności kodu w celu zwiększenia możliwości ponownego użycia i zmniejszenia obciążenia konserwacyjnego | 20 min | +| [Część 5: Hello Containers](./05_hello_containers.md) | Używanie kontenerów jako mechanizmu zarządzania zależnościami oprogramowania i zwiększenia powtarzalności | 60 min | +| [Część 6: Hello Config](./06_hello_config.md) | Dostosowywanie zachowania pipeline'u i optymalizacja użycia w różnych środowiskach obliczeniowych | 60 min | + +Pod koniec tego kursu będziesz dobrze przygotowany do podjęcia kolejnych kroków w swojej drodze do tworzenia powtarzalnych workflow'ów dla Twoich potrzeb obliczeniowych w nauce. + +Gotowy do rozpoczęcia kursu? + +[Rozpocznij :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/pl/docs/hello_nextflow/next_steps.md b/docs/pl/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..11ad6a3be3 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Podsumowanie kursu + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gratulacje z okazji ukończenia kursu szkoleniowego Hello Nextflow! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Zobacz [całą playlistę na kanale YouTube Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Możesz przeczytać [transkrypcję wideo](./transcripts/07_next_steps.md) wraz z filmem. +/// + +## Twoja podróż + +Zacząłeś od bardzo podstawowego workflow'u, który uruchamiał zakodowane na sztywno polecenie. +W ciągu sześciu części przekształciłeś ten podstawowy workflow w modularny, wieloetapowy pipeline, który wykorzystuje kluczowe funkcje Nextflow, w tym kanały, operatory, wbudowaną obsługę kontenerów i opcje konfiguracji. + +### Co zbudowałeś + +- Ostateczna forma workflow'u Hello przyjmuje jako wejście plik CSV zawierający tekstowe pozdrowienia. +- Cztery kroki są zaimplementowane jako procesy Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` i `cowpy`) przechowywane w osobnych plikach modułów. +- Wyniki są publikowane do katalogu o nazwie `results/`. +- Końcowe wyjście pipeline'u to plik tekstowy zawierający grafikę ASCII postaci wypowiadającej pozdrowienia zapisane wielkimi literami. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Zapisuje każde pozdrowienie do własnego pliku wyjściowego (_np._ "Hello-output.txt") +2. **`convertToUpper`:** Konwertuje każde pozdrowienie na wielkie litery (_np._ "HELLO") +3. **`collectGreetings`:** Zbiera wszystkie pozdrowienia z wielkimi literami do jednego pliku batch +4. **`cowpy`:** Generuje grafikę ASCII za pomocą narzędzia `cowpy` + +Konfiguracja workflow'u wspiera dostarczanie wejść i parametrów w elastyczny, powtarzalny sposób. + +### Nabyte umiejętności + +Przez ten praktyczny kurs nauczyłeś się: + +- Opisywać i wykorzystywać podstawowe komponenty Nextflow wystarczające do budowania prostego, wieloetapowego workflow'u +- Opisywać koncepcje kolejnego kroku, takie jak operatory i channel factories +- Uruchamiać workflow Nextflow lokalnie +- Znajdować i interpretować wyjścia (wyniki) i pliki dziennika generowane przez Nextflow +- Rozwiązywać podstawowe problemy + +Jesteś teraz wyposażony w fundamentalną wiedzę, aby zacząć tworzyć własne pipeline'y w Nextflow. + +## Kolejne kroki do rozwijania umiejętności + +Oto nasze 3 najlepsze sugestie, co robić dalej: + +- Zastosuj Nextflow do naukowego przypadku analizy z [Nextflow dla nauki](../nf4_science/index.md) +- Rozpocznij pracę z nf-core z [Hello nf-core](../../hello_nf-core/index.md) +- Odkryj bardziej zaawansowane funkcje Nextflow z [Side Quests](../side_quests/index.md) + +Na koniec polecamy zapoznać się z [**Seqera Platform**](https://seqera.io/), platformą chmurową opracowaną przez twórców Nextflow, która jeszcze bardziej ułatwia uruchamianie i zarządzanie workflow'ami, a także zarządzanie danymi i interaktywne uruchamianie analiz w dowolnym środowisku. + +## Ankieta zwrotna + +Zanim przejdziesz dalej, poświęć chwilę na wypełnienie ankiety kursu! Twoja opinia pomaga nam ulepszać materiały szkoleniowe dla wszystkich. + +[Wypełnij ankietę :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pl/docs/hello_nextflow/survey.md b/docs/pl/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..7eb0c5b440 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Ankieta zwrotna + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Zanim przejdziesz dalej, wypełnij tę krótką, 5-pytaniową ankietę, aby ocenić szkolenie, podzielić się opinią o swoim doświadczeniu i dać nam znać, co jeszcze moglibyśmy zrobić, aby pomóc Ci w Twojej podróży z Nextflow. + +Wypełnienie powinno zająć mniej niż minutę. Dziękujemy za pomoc w ulepszaniu naszych materiałów szkoleniowych dla wszystkich! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pl/docs/hello_nextflow/transcripts/00_orientation.md b/docs/pl/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..d0917a1220 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Orientacja - Transkrypcja Wideo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważna uwaga" + + Ta strona zawiera tylko transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów kursu](../00_orientation.md). + +## Powitanie + +Cześć, witaj w Hello Nextflow. Nazywam się Phil Ewels. Jestem Product Managerem ds. Open Source w Seqera i bardzo się cieszę, że mogę dzisiaj poprowadzić Cię przez ten pierwszy kurs szkoleniowy Nextflow. + +Przejdziemy przez podstawy Nextflow, wyjaśniając jak pisać i uruchamiać pipelines oraz jak je konfigurować. + +Zbudujesz własny prosty wieloetapowy pipeline. Omówimy terminologię taką jak operatory i fabryki kanałów, a pod koniec kursu będziesz gotowy, aby rozpocząć budowanie własnych pipelineów bioinformatycznych. + +Jeśli masz jakiekolwiek pytania, skontaktuj się z nami na community.seqera.io. Mamy tam bardzo aktywną społeczność Nextflow, jest sekcja poświęcona szkoleniom, więc po prostu daj nam znać, gdzie utknąłeś, a ktoś będzie w stanie pomóc. + +Dobrze. Zaczynajmy. + +## Strona Szkoleniowa + +Wszystkie materiały szkoleniowe dla kursów Nextflow znajdują się na training.nextflow.io. Możesz przejść do niej w swojej przeglądarce internetowej. Uruchom ją teraz i możemy się rozejrzeć. + +Będę korzystał z wersji 2.1.1. Wprowadzamy małe aktualizacje i poprawki co jakiś czas, więc nie martw się, jeśli będzie trochę inne, ale jeśli materiały zbyt bardzo się rozjechały, zawsze możesz użyć tego selektora wersji na górze, aby wybrać dokładną wersję materiałów, którą będę omawiał. + +Jeśli wolisz jasny motyw, możesz zmienić motyw strony tutaj. + +Zobacz tłumaczenia tutaj, chociaż w momencie nagrywania to tak naprawdę tylko angielski obejmuje te nowe materiały. + +I zobacz także cały kod źródłowy strony szkoleniowej i wszystko, z czym będziemy pracować, na GitHub. + +Strona główna tutaj wymienia wszystkie różne kursy materiałów szkoleniowych, które mamy. Jeśli przewinę w dół, zobaczymy Nextflow dla początkujących z kursem Hello Nextflow, który tutaj wykonamy. Możesz zobaczyć wszystkie inne kursy, które również mamy i które działają w podobny sposób. + +## Konfiguracja Środowiska + +Tak naprawdę zamierzam zacząć od tego pierwszego na górze, który jest wspólny dla wszystkich kursów szkoleniowych i dotyczy konkretnie konfigurowania naszego środowiska. + +Klikam go, przenosi mnie do tej sekcji i widzimy instrukcje dotyczące lokalnego programowania. Jeśli chcesz użyć swojego własnego laptopa z własną kopią VS Code i własnymi instalacjami oprogramowania, lub tego, czego oczekujemy od większości ludzi, czyli użycia czegoś, co nazywa się GitHub Codespaces. + +Codespaces to usługa świadczona przez GitHub, w której uruchamiają serwer WWW w chmurze, z którym możesz się połączyć. Ten serwer ma zainstalowany VS Code, gdzie możesz go uruchomić w przeglądarce internetowej, lub jeśli wolisz, połączyć go z lokalną instalacją VS Code. Wszystkie obliczenia, wszystkie pliki, cała edycja odbywa się zdalnie, co oznacza, że wszystkie potrzebne oprogramowanie jest preinstalowane i jest takie samo dla wszystkich. + +## Tworzenie GitHub Codespace + +Aby utworzyć codespace ze wszystkim, czego potrzebujemy, poszukaj przycisków w materiałach dokumentacji, które mówią "Open in GitHub Codespaces". Kliknę to teraz, otwieram to w nowej karcie. I pokazano mi tę stronę internetową. Teraz widzisz, że jest to wstępnie skonfigurowane z nextflow-io training. + +Mogę po prostu kliknąć create new codespace. Ale tak naprawdę zalecamy użycie nieco większej maszyny do szkolenia Nextflow z czterema procesorami zamiast dwóch. Możesz zmienić, której wersji materiałów używa. Więc to domyślnie ustawia się na 2.1.1, ponieważ to jest wersja dokumentacji, z której poszedłem za linkiem. Ale mogę też ustawić to na konkretną gałąź repozytorium, jeśli chcę. + +Teraz kliknę create codespace. I zacznie konfigurować dla mnie środowisko. + +## Tworzenie Codespace + +Teraz, za pierwszym razem, kiedy to robisz, zajmie to dość dużo czasu, więc teraz jest dobry moment, aby pójść zrobić sobie herbatę. Usiądź wygodnie, porozmawiaj z osobą, przy której siedzisz. + +Jeśli jesteś zainteresowany, możesz kliknąć building codespace tutaj na dole, aby zobaczyć logi konfiguracji. I możesz zobaczyć tutaj, że pobiera obraz Docker ze wszystkim, czego potrzebuję i konfiguruje środowisko. + +Teraz musisz czekać w ten sposób tylko za pierwszym razem, gdy tworzysz codespace. Jeśli przejdziesz do github.com/codespaces tutaj, zobaczysz wszystkie różne Codespaces, które masz otwarte. Oto ten, który właśnie utworzyłem. Następnym razem, gdy to zrobisz, możesz przejść tutaj i możesz wybrać poprzedni codespace i po prostu od razu do niego wrócić. I to jest znacznie, znacznie szybszy proces rozgrzania tego istniejącego środowiska. To również zachowa wszystkie zmiany, które wprowadzałeś w VS Code i w plikach, więc nie stracisz postępu, jeśli wyjdziesz i wrócisz. + +Możesz kliknąć trzy kropki tutaj, aby wykonać inne akcje. Na przykład, jeśli skonfigurowałeś go z dwoma procesorami, a teraz chcesz cztery, możesz zmienić typ maszyny. Lub jeśli chcesz zacząć od zera i od nowa, możesz usunąć codespace. + +## Wprowadzenie do VS Code + +Dobrze, Codespaces zakończył konfigurowanie mojego środowiska i teraz pokazano mi VS Code w przeglądarce internetowej. + +Jeśli jesteś przyzwyczajony do VS Code, będzie to bardzo znajome. Jeśli nie używałeś go wcześniej, jest całkiem proste. Jest kilka różnych części strony, o których musisz wiedzieć. + +Tutaj po lewej stronie mamy pasek boczny. Widzisz Eksplorator ustawiony ze wszystkimi różnymi plikami w repozytorium GitHub z repozytorium szkoleniowego. + +Te przyciski na dole po lewej stronie mogą być różnymi narzędziami. W pasku bocznym mogę przeszukiwać wszystkie pliki we wszystkich projektach. Mogę pracować z Git, mogę pracować z GitHub, wszystkimi różnymi rzeczami tego typu. + +Na górze tutaj jest główne menu. Eksplorator plików jest tym, który będziemy mieć najczęściej tutaj, i możesz kliknąć prawym przyciskiem myszy dowolny z tych plików i zrobić normalne rzeczy, których oczekujesz. Może być konieczne kliknięcie przez niektóre ostrzeżenia takie jak to, gdzie wytnij, kopiuj i możesz również pobrać na swoją lokalną maszynę. + +Gdy codespace się ładuje, daje nam podgląd pliku markdown w tym głównym obszarze tutaj. To jest dokładnie to samo, co renderuje się na github.com. Mogę to zamknąć, a jeśli kliknę dwukrotnie ten plik Readme, zobaczysz, że otwiera go jako kod w edytorze kodu i tak jak z każdym innym plikiem, możemy edytować ten kod bezpośrednio. + +Na końcu tutaj na dole mamy okno terminala. Patrzyłem na logi, gdy się budował, więc to jest to, co aktualnie pokazuje. Mogę również nacisnąć ten przycisk plus, aby rozpocząć nową sesję terminala. To nie działa na mojej maszynie. Pamiętaj, to działa w chmurze, i jeśli wykonam tree trzy do głębokości dwóch, zobaczysz wszystkie te same pliki tutaj, które były po lewej stronie. + +## Pokazywanie tylko plików "hello-nextflow" + +To repozytorium GitHub zawiera wszystkie różne zestawy szkoleniowe, nie tylko ten, który robimy. Więc jeśli chcesz, możesz skupić się tylko na katalogu Hello Nextflow. Jednym ze sposobów, aby to trochę uporządkować, jest przejście do menu file, a następnie add folder to workspace. + +Klikamy to, przechodzimy do training. Hello nextflow i klikamy add. Odświeży Twój ekran. A potem w Eksploratorze mamy teraz dwa różne przestrzenie robocze, tę, którą mieliśmy wcześniej dla training i jedną z tylko Hello Nextflow. + +Jeśli chcesz, możesz kliknąć prawym przyciskiem myszy na training i kliknąć remove folder from workspace, aby całkowicie usunąć go z paska bocznego. + +Teraz mamy tylko pliki dla tego konkretnego kursu szkoleniowego z boku. Mogę ukryć to ostrzeżenie i teraz mogę zrobić to samo w terminalu tutaj i wykonać CD dla zmiany katalogu. Hello, Nextflow. I znowu mamy te same pliki tutaj, które są w pasku bocznym. + +## Hello Nextflow: pliki + +Patrząc na te pliki dla kursu Hello Nextflow. + +Mamy kilka plików .nf, które są dla Nextflow, i jest jeden z tych plików dla każdego z rozdziałów kursu szkoleniowego. Będziemy pracować przez te pliki i modyfikować je w ćwiczeniach. + +Mamy również plik nextflow.config, który ma tylko podstawowe ustawienia konfiguracji do uruchamiania Nextflow w tym środowisku, którymi nie musisz się martwić w tym momencie. Plik greetings.csv, którego będziemy używać do przetwarzania danych, który zostanie wprowadzony w następnej części tego kursu, oraz plik test-params.json, który będzie używany w części szóstej i możesz zignorować go na razie. + +Te pliki Nextflow to tylko początek każdego ćwiczenia. Jeśli chcesz zobaczyć, jak powinny wyglądać, gdy są skończone, możesz przejść do katalogu solutions i tam są odpowiedzi dla każdej części kursu szkoleniowego, więc możesz zobaczyć działającą wersję tego, do czego dążysz. + +## Otwieranie terminala + +Jeśli w którymkolwiek momencie zamkniesz terminal i nie możesz sobie przypomnieć, jak wrócić, nie martw się. Te przyciski na górze po prawej otwierają i zamykają różne panele w przestrzeni roboczej. Kliknij więc ten dla dolnego panelu i pojawi się ponownie. I upewnij się, że masz tutaj wybrany terminal. Możesz również kliknąć ten przycisk tutaj, strzałkę po prawej stronie terminala, aby zrobić pełny ekran. + +Zobaczysz, jak robię to dość często, ponieważ mam VS Code powiększony, abyś mógł czytać tekst. W zależności od rozmiaru ekranu, możesz potrzebować lub nie potrzebować tego robić. To samo dotyczy minimalizowania panelu bocznego. + +Dobrze. To wystarczy dla środowiska. Myślę, że jesteśmy gotowi, aby zacząć. Dołącz do mnie w następnym filmie dla rozdziału pierwszego. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/pl/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..9a1874a463 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Część 1: Hello World - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne uwagi" + + Ta strona zawiera tylko transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów szkoleniowych](../01_hello_world.md). + + Numery sekcji pokazane w transkrypcji są podane wyłącznie w celach informacyjnych i mogą nie obejmować wszystkich numerów sekcji w materiałach. + +## Powitanie + +Cześć, witamy w pierwszym rozdziale Hello Nextflow. + +W tej pierwszej części sześcioczęściowego kursu przejdziemy przez same podstawy Nextflow. Zaczniemy od uruchomienia kilku poleceń w terminalu, a następnie zobaczymy, jak te polecenia Bash przekształcić w skrypt Nextflow. + +Spróbujemy uruchomić pierwszy pipeline Nextflow, zobaczymy, co Nextflow robi, gdzie działa, jakie pliki tworzy i jaki jest cel tych plików. + +W porządku, zaczynajmy. + +## training.nextflow.io + +Przede wszystkim przejdź do training.nextflow.io. Tak jak wcześniej, wszystkie materiały są tu zapisane i będę pracował przez nie krok po kroku. Będę pokazywał mój ekran podczas wykonywania kroków szkolenia, ale wszystko, co mówię, znajduje się w materiałach szkoleniowych, więc możesz je śledzić we własnym tempie i znajdziesz tam wszystko zapisane. + +To wideo ma również włączone napisy, więc możesz je włączyć i śledzić dokładnie to, co mówię, kiedy to mówię. + +Dobrze, przejdźmy do Hello Nextflow. To kurs, który dzisiaj będziemy robić, a orientację już zrobiliśmy w pierwszym wideo, więc przejdziemy od razu do części pierwszej. Hello World. + +Dobra, opuszczę teraz materiały szkoleniowe i przejdę do mojego środowiska Code Spaces. To jest to, co skonfigurowaliśmy w pierwszym wideo. Mam nadzieję, że masz coś, co wygląda bardzo podobnie w Twoim systemie. Używam VS Code, patrzę na materiały szkoleniowe i zmieniłem katalog na hello Nextflow. + +## 0. Rozgrzewka: Uruchom Hello World bezpośrednio + +Dobra. Zacznijmy od kilku podstaw, które mam nadzieję będą wszystkim znajome. Zacznę od napisania bardzo prostego polecenia w terminalu. Tutaj na dole napiszę 'echo Hello World!"', nacisnę enter i, bez niespodzianek, terminal robi to, czego od niego żądam i zwraca ten ciąg znaków. Hello world. + +Dobra, teraz nacisnę strzałkę w górę, żeby przywołać to polecenie i trochę je zmodyfikuję. Tym razem przekierujmy to wyjście do pliku. Zapiszę to zamiast tego do output.txt i nacisnę enter, nic tym razem w terminalu, ponieważ wyjście nie trafiło do terminalu. Trafiło do tego pliku. + +Mogę wtedy odczytać ten plik, robiąc 'cat output.txt', nacisnąć tab, żeby automatycznie rozszerzyć nazwę pliku i proszę. Plik jest tam. + +Widzę również ten plik na pasku bocznym w eksploratorze plików w VS code. Mogę go dwukrotnie kliknąć i otworzyć tutaj. Jeśli chcesz otworzyć go w VS Code bez klikania, możesz również zrobić "code" a następnie "output.txt" i robi to samo. + +Świetnie. To pierwszy krok. Bardzo prosty. + +## 1. Przeanalizuj startowy skrypt workflow Hello World + +Dobra. Teraz zrobimy dokładnie to samo, ale w Nextflow, zamiast bezpośrednio w terminalu. + +Użyjemy pierwszego przykładowego skryptu na początek, ten plik nazywa się Hello World. Mogę zrobić "ls", żeby go zobaczyć w terminalu, a jestem na Macu, więc mogę zrobić command click, żeby otworzyć ten plik, lub mogłem po prostu dwukrotnie kliknąć na pasku bocznym tutaj. + +Jest kilka rzeczy, które możemy zobaczyć w tym pliku. Na samej górze jest instrukcja hash mówiąca, że to jest plik Nextflow i tak mógłby być wykonany. Są tu jakieś komentarze, zwykłe komentarze kodu w jasnoszarym kolorze, które nie wpływają na wykonanie, a tylko pomagają nam czytać skrypt. + +A potem są dwie główne struktury. Jest tutaj process i workflow. + +Procesy w Nextflow to kroki pipeline. To części, które faktycznie wykonują logikę i przetwarzanie. + +Workflow na dole łączy te procesy razem i kontroluje logikę workflow, jak wszystko łączy się ze sobą. + +Zaczniemy od spojrzenia na process. Za chwilę wrócimy do workflow. + +## 1.2 Definicja procesu + +Więc każdy process zaczyna się od słowa kluczowego process. Ma nazwę, a następnie ma nawiasy klamrowe i wszystko w tych nawiasach klamrowych to ten pojedynczy process. + +Process musi mieć sekcję script, a zawarta tutaj jest fragmentu bash w wielowierszowym ciągu znaków, który jest częścią kodu faktycznie wykonywaną w środowisku obliczeniowym. + +Mamy również tutaj instrukcję output, która mówi Nextflow, jakie pliki mają zostać utworzone przez skrypt. Zauważ, że output tutaj ma słowo kluczowe path, które mówi Nextflow, że to jest plik, a nie wartość lub ciąg znaków. + +W bloku script jest to po prostu zwykła instrukcja bash i jest dokładnie taka sama jak to, co napisaliśmy w terminalu. Wykonujemy echo hello world do pliku o nazwie output.txt. Ten output.txt jest następnie przechwytywany przez definicję output. Definicja output tak naprawdę nic nie robi. Tylko mówi Nextflow, czego się spodziewać, a gdyby ten plik nie został utworzony, Nextflow zgłosiłby błąd. + +Zauważ, że ten przykład nie jest świetny, ponieważ sztywno zakodowaliśmy nazwę pliku tutaj, output.txt i output.txt. Gdyby którykolwiek z nich został zmieniony, spowodowałoby to błąd w naszym workflow. + +Jest lepszy sposób, aby to zrobić za pomocą zmiennych, co omówimy za chwilę. + +## 1.3 Definicja workflow + +Dobra. Przechodząc do workflow, możemy zobaczyć, że mamy komentarz, a następnie uruchamiamy process o nazwie sayHello. To jest to samo słowo kluczowe, które jest tutaj na górze. To jest mniej więcej najprostszy workflow, jaki może być. Po prostu wywołujemy pojedynczy process bez zmiennego wejścia, więc nie łączymy go z niczym innym. W późniejszej części tego kursu porozmawiamy o tym, jak uczynić to bardziej zaawansowanym, używając zmiennych wejść i łącząc rzeczy z kanałami. + +## 2. Uruchom workflow + +Dobra, to wszystko, czego potrzebujemy. Zobaczmy, czy możemy to uruchomić i zobaczyć, co się stanie. Wyczyśzczę terminal, a następnie zrobię "nextflow run" i wywołam nazwę pliku, która to hello-world.nf. To wszystko, czego potrzebujemy, aby uruchomić pipeline Nextflow. Ten pipeline nie przyjmuje żadnego wejścia, więc nie potrzebujemy żadnych innych argumentów. + +Naciśnijmy enter i zobaczmy, co się stanie. + +Dobra. Mam nadzieję, że powinieneś mieć jakieś wyjście, które wygląda tak. Mamy kilka informacji mówiących nam, że Nextflow został uruchomiony i jaka była używana wersja. Mówi nam, który skrypt został uruchomiony i podaje nam losowo wygenerowaną nazwę dla tego konkretnego wykonania workflow. W tym przypadku mój nazywał się "gloomy_crick". + +Najważniejszą częścią jest jednak to, że mówi nam, które kroki zostały uruchomione w pipeline. Możesz zobaczyć, że nasz process o nazwie sayHello został uruchomiony i został uruchomiony raz i został ukończony w stu procentach. + +Ta część tutaj to hash dla tego konkretnego zadania workflow. Każdy process działa jeden lub więcej razy, a każde z tych wykonań nazywa się zadaniem. + +## 2.2. Znajdź wyjście i logi w katalogu work + +Każde zadanie ma swój własny izolowany katalog, w którym działa, więc jest oddzielony od reszty wykonania workflow. Ten hash odpowiada strukturze plików w katalogu work. Jeśli zrobię "tree work", możemy zobaczyć a0, a następnie dłuższą wersję krótkiego hasha, a następnie nasz plik output.txt. Możesz również zobaczyć to na pasku bocznym. + +Możesz zobaczyć na pasku bocznym, że jest tu kilka dodatkowych plików. Powodem, dla którego nie pojawiły się one w terminalu, jest to, że są to ukryte pliki, zaczynają się od kropki. I rzeczywiście, jeśli zrobię "tree -a" dla wszystkich i "work", możemy je tutaj zobaczyć. + +Te pliki z kropką są obecne w każdym pojedynczym katalogu work, który tworzy Nextflow, i każdy z nich ma nieco inne zadanie. Po pierwsze .command.begin zawiera po prostu kilka instrukcji dla Nextflow, które konfigurują zadanie przed jego uruchomieniem. .command.run to rzeczywiste instrukcje wykonywane przez sam Nextflow. Następnie .command.sh jest prawdopodobnie najbardziej interesujący. To jest skrypt, który został rozwiązany z naszego bloku script procesu. + +Jeśli go otworzę, możesz zobaczyć, że mamy nasze "echo Hello World" do pliku output.txt. To jest dokładnie to samo co nasz process w tym przypadku, ale jeśli mamy jakiekolwiek zmienne w naszym kodzie Nextflow, każde zadanie będzie miało inny .command.sh i możesz zobaczyć, jak te zmienne zostały rozwiązane. + +Pozostałe pliki dotyczą tego, jak zadanie zostało wykonane. Więc .command.err, .log i .out to standardowy błąd, standardowe wyjście i oba połączone. A .exitcode mówi Nextflow, jak to zadanie zostało wykonane, z jakim kodem wyjścia, czy zakończyło się sukcesem, czy nie. + +Na koniec mamy nasz plik output.txt i oczywiście "Hello World", to jest to, czego oczekiwaliśmy i to jest to, co zostało utworzone. + +Dobra, świetnie. To było twoje pierwsze uruchomienie Nextflow. Gratulacje. Naprawdę jest tak proste. + +Następnie przejdziemy do tego, jak zrobić to trochę wygodniej, żebyśmy nie musieli edytować kodu za każdym razem, gdy chcemy dokonać zmiany w sposobie uruchamiania pipeline. + +## 3. Zarządzaj wykonaniami workflow + +Ta struktura katalogów jest świetna do utrzymywania wszystkich zadań oddzielonych i wszystkiego uporządkowanego, ale oczywiście nie jest zbyt wygodne znalezienie plików wyjściowych. Nie chcesz przeszukiwać mnóstwa zagnieżdżonych katalogów, próbując znaleźć wyniki swojego pipeline. + +## 3.1. Publikuj wyjścia + +Dobra wiadomość jest taka, że nie musisz. Katalogi work są naprawdę tylko dla Nextflow do własnego użytku. Więc to, co zrobimy, to użyjemy funkcji Nextflow zwanej "publishDir". + +Wracamy do naszego workflow, idziemy do procesu. Możemy dodać tutaj nową instrukcję zwaną dyrektywą. To jest to, jak Nextflow nazywa te rzeczy na górze procesów, które rozszerzają sposób działania funkcjonalności, a ta, której użyjemy, nazywa się publishDir. + +Możesz zobaczyć, że zacząłem tu pisać i rozszerzenie Nextflow dla VS Code zasugerowało mi dyrektywę, więc mogę po prostu nacisnąć enter. + +Dobra. Podam katalog o nazwie "results" i powiemy mu, żeby skopiował tam pliki wyjściowe. Więc powiem mode copy. Świetnie. Zapiszę i uruchommy workflow ponownie. + +nextflow run hello-world.nf + +Działa dokładnie tak samo. Chociaż zauważ, że mamy teraz nieco inny hash. Nextflow użyje innego hasha za każdym razem, gdy uruchomisz workflow. I w rezultacie mamy inny zestaw katalogów work. Obszary, jeden nazywa się EB, ale możesz zobaczyć, że wszystkie pliki są takie same. Jednak tym razem nowością jest to, że mamy również katalog o nazwie "results". + +W "results" tutaj mamy nasz plik wyjściowy. To jest to, co kazaliśmy zrobić Nextflow. Powiedzieliśmy, zapisz pliki wynikowe w katalogu o nazwie "results" i skopiuj je tam. I teraz jest to znacznie łatwiejsze do znalezienia. Jest tam po prostu obok miejsca, w którym uruchomiliśmy workflow i wszystkie różne pliki mogą być tam zorganizowane, jak chcemy, niezależnie od tego, gdzie lub jak Nextflow uruchomił faktyczne wykonanie. + +Zauważ, że publishDir może obsługiwać dowiązania symboliczne, co jest dobre, jeśli pracujesz na współdzielonym systemie plików i chcesz zaoszczędzić na miejscu. A także nie musisz definiować wszystkich plików, które są tworzone przez process jako output. + +Nextflow skopiuje tylko rzeczy, które są zdefiniowane w tym bloku output. Więc jeśli masz pliki pośrednie tworzone przez krok, które nie są potrzebne w dalszej części tego procesu, po prostu nie definiujesz ich w output i nie pojawią się w publishDir. To jest więc sposób na utrzymanie czystości plików wyjściowych z pipeline i łatwe usuwanie plików pośrednich po zakończeniu miejsca pracy. + +Krótka uwaga tutaj. Jest nowa składnia Nextflow, która nadchodzi, nazywana definicjami wyjścia workflow, która ostatecznie zastąpi publishDir. Daje nam to sposób na zdefiniowanie wszystkich wyjść z workflow na poziomie pipeline w dół w bloku workflow. Jest to opisane w dokumentacji Nextflow, jeśli chcesz to wypróbować. Ale na razie publishDir będzie jeszcze przez jakiś czas, więc nadal mamy to w szkoleniu na rok 2025. + +## 3.2. Uruchom ponownie workflow z -resume + +Dobra. Wspomniałem, że katalog work ma teraz dwa zestawy wyników z innym hashem z każdego uruchomienia workflow. To dobrze. Jednak czasami nie chcemy ponownie obliczać kroków za każdym razem, jeśli nie musimy. + +Może budujesz iteracyjnie swój workflow i dodajesz kroki i chcesz, aby pierwsze kroki po prostu użyły wersji z cache. Lub może coś poszło nie tak w twoim systemie obliczeniowym w połowie workflow i chcesz, aby kontynuował od miejsca, w którym przerwał, ale pominął kroki, które już wykonał. + +Nextflow ma wbudowaną funkcjonalność do tego, zwaną resume. Wypróbujmy to. Więc przede wszystkim, po prostu spojrzę na katalog work, żebyśmy mogli pamiętać, co tam było. + +A następnie zrobię "nextflow run hello-world.nf" i dodam jedno polecenie tutaj, "-resume". + +Zauważ, pojedynczy myślnik, to naprawdę ważne. Uruchomię to, a wyjście będzie wyglądać zasadniczo dokładnie tak samo, z kilkoma małymi różnicami. + +Zauważ tutaj, że mówi "cached" na szaro. To oznacza, że Nextflow nie uruchomił zadania. Tym razem znalazł coś, co pasowało do wymagań i użył tych wyjść bezpośrednio, zamiast ponownie uruchamiać krok. + +I rzeczywiście, jeśli spojrzysz na hash tutaj, możesz zobaczyć, że odpowiada istniejącemu hashowi, który mieliśmy z poprzedniego uruchomienia. + +## 3.3. Usuń starsze katalogi work + +Dobra. Ale jeśli rozwijasz iteracyjnie, zbudujesz wiele tych plików workflow. To może być problem, jeśli możesz mieć mało miejsca. + +Nextflow może nam pomóc wyczyścić te katalogi work za pomocą kilku poleceń pomocniczych. Jeśli zrobię "nextflow log". To da mi listę wszystkich różnych uruchomień workflow, które wykonałem w tym katalogu, i mają tutaj nazwy uruchomień. Możesz zobaczyć ten gloomy quick, który był pierwszym, który uruchomiliśmy, a następnie te dwa nowe. + +Możemy teraz wziąć tę nazwę i użyć ich z poleceniem "nextflow clean". Mogę określić pojedynczą nazwę uruchomienia. Lub jeszcze lepiej, mogę powiedzieć Nextflow, żeby usunął wszystko sprzed pojedynczej nazwy workflow za pomocą "-before", i podam "stupefied_shaw". To było moje najnowsze uruchomienie, "-n". + +Polecenie "-n" powiedziało Nextflow, aby zrobił to jako próbne uruchomienie bez faktycznego usuwania czegokolwiek na prawdę, i mówi nam, które z katalogów hash zostałyby usunięte. Rzeczywiście, to tylko ten z pierwszego wykonania. Oba drugie wykonania używają tego samego katalogu hash. + +Uruchomię to ponownie, ale teraz zamiast "-n" dla próbnego uruchomienia, zrobię "-f" dla force i usunął ten katalog hash. Teraz jeśli zrobię "tree work", możemy zobaczyć, że mamy tylko ten plik wyjściowy. + +Świetnie. Więc udało nam się wyczyścić sporo miejsca na dysku. + +Kilka rzeczy do zauważenia podczas usuwania katalogów work, jeśli stworzyłeś dowiązanie symboliczne do swojego katalogu wyników, te źródła dowiązań symbolicznych zostaną teraz usunięte i twoje wyniki znikną na zawsze. Dlatego użycie trybu copy jest bezpieczniejsze i ogólnie to zalecamy. + +Po drugie, funkcjonalność resume Nextflow opiera się na tych katalogach work. Więc jeśli je usuniesz i uruchomisz Nextflow ponownie, funkcjonalność resume nie będzie już działać. Więc to do ciebie należy śledzenie, których rzeczy możesz potrzebować lub nie, i usuwaj rzeczy tylko wtedy, gdy masz pewność, że jest to bezpieczne. + +Inna rzecz, którą możemy zrobić, to możemy po prostu usunąć cały katalog work, jeśli skończyliśmy uruchamianie workflow i mamy pewność, że już go nie potrzebujemy. + +Więc mogę zrobić "rm -r work". Wiem, że nie było tam nic ważnego. Mam swoje wyniki, na których mi zależy, w katalogu results, gdzie je skopiowaliśmy. I więc było bezpiecznie usunąć katalog work. To do ciebie należy, które z tych podejść zastosujesz. + +## 4. Użyj zmiennego wejścia przekazanego z linii poleceń + +Dobra, co dalej? Wspomniałem, że sztywno zakodowaliśmy niektóre wartości w naszym skrypcie workflow tutaj, plik output.txt, i że może być lepszy sposób, aby to zrobić. + +Zacznijmy od tego. Zrobimy trzy rzeczy. Dodamy nowe wejście do procesu. Powiemy skryptowi procesu, jak użyć tego wejścia, a następnie podłączymy to w workflow, abyśmy mogli używać tego dynamicznie z flagą linii poleceń podczas uruchamiania Nextflow. + +Więc przede wszystkim. Dodajmy blok input tutaj. Tak samo jak output. To jest nowa sekcja dla procesu, i powiem, "val greeting". + +Zauważ tutaj, mówię "val", co oznacza, że to jest zmienna, a nie path. + +Mogę wtedy przejść do skryptu i mogę wziąć ten sztywno zakodowany tekst tutaj i zrobić $greeting. To działa tak jak każdy inny język programowania. Definiujemy tutaj zmienną i odwołujemy się do niej w tym bloku script. Kiedy Nextflow uruchamia ten process, zmienna zostanie zinterpretowana. A kiedy zajrzymy do tego pliku .command.sh, zobaczymy faktyczny sztywno zakodowany ciąg znaków tutaj zamiast tego. + +## 4.1.3. Ustaw parametr CLI i podaj go jako wejście do wywołania procesu + +Dobra, ale gdzie podajemy zmienną? Następnie przechodzimy do sekcji workflow i możesz zobaczyć, że rozszerzenie tutaj mówi, że teraz oczekujemy wejścia i dało mi ostrzeżenie. + +Teraz najprostszą rzeczą, którą moglibyśmy zrobić, jest po prostu sztywne zakodowanie tego. Mógłbym napisać "Hello World" i podać to wejście ciągu znaków do procesu. Ale znowu, to tak naprawdę nie rozwiązałoby żadnych problemów. Nadal musielibyśmy wracać i edytować kod pipeline za każdym razem, gdy chcielibyśmy coś zmienić, co nie jest dobre. + +Dobra wiadomość jest taka, że Nextflow ma wbudowany system obsługi argumentów linii poleceń zwanych parametrami. Więc zamiast tego mogę użyć jednej z tych specjalnych zmiennych zwanych params i mogę nazwać to jak chcę, ale powiem greeting, żeby pasowało do logiki workflow. + +Zapisz i zobaczmy, co możemy z tym zrobić. + +Więc jeśli wrócę do terminala. Więc robimy "nextflow run hello-world.nf". Tak jak wcześniej, ale kluczowa różnica polega na tym, że robimy --greeting + +Zauważ, że są tutaj dwa myślniki, ponieważ to jest parametr. Kiedy wznawialiśmy workflow wcześniej, to był pojedynczy myślnik. To dlatego, że resume jest podstawową opcją Nextflow, a to jest parametr, który jest specyficzny dla naszego pipeline. + +Nie myl tych dwóch. Łatwo to zrobić. Gdybyś zrobił --resume zamiast tylko jednego myślnika, to byłoby "params.resume", co by nic nie zrobiło. Podobnie, gdybyś zrobił pojedynczy myślnik tutaj, Nextflow nie rozpoznałby tego jako kluczowego argumentu. + +Więc to --greeting, które odpowiada parameters greeting. + +Mogę teraz śledzić to dowolnym tekstem, jaki chcę. Więc jestem obecnie w Szwecji, więc powiem, "Hej världen". + +Więc uruchommy to, zobaczmy, co się stanie, moment prawdy. + +Dobra, więc możesz zobaczyć, że process został uruchomiony ponownie, tak jak wcześniej, sayHello z pojedynczym wykonaniem. + +To nadpisze plik, który był w katalogu publishDir "results". I więc bądź ostrożny, gdy ponownie uruchamiasz pliki, ponieważ rzeczy w publishDir zostaną nadpisane. + +Mogę teraz zrobić "code results/output.txt" i rzeczywiście, nasze wyjście zostało zaktualizowane i teraz mówi "Hej världen". + +## 4.2. Użyj wartości domyślnych dla parametrów linii poleceń + +Dobra, to świetnie. Ale problem polega teraz na tym, że nasz workflow polega na tym, że zawsze definiujemy ten parametr, i miło jest mieć rozsądne wartości domyślne, aby rzeczy działały w rozsądny sposób dla twojego workflow, chyba że nadpiszesz domyślne. + +Więc sposób, w jaki to robimy, to ustawienie wartości domyślnej dla parametru w naszym skrypcie workflow. + +Więc jeśli wrócę do mojego pliku hello-world.nf, mogę przejść do skryptu tuż nad workflow, wpisać "params.greeting" i zdefiniować to jak każdą inną zmienną. Więc umieśćmy tutaj ciąg znaków i powiedzmy "Holà mundo!" + +Teraz ten parametr ma zdefiniowaną wartość domyślną, która będzie używana tutaj, lub nadal możemy nadpisać to w linii poleceń za pomocą --greeting, tak jak robiliśmy wcześniej. + +Więc sprawdźmy, czy działa. "nextflow run hello-world.nf" + +Tym razem bez argumentów linii poleceń i sprawdźmy, czy zrobił właściwą rzecz. + +"code results/output.txt". I proszę. Dostaliśmy naszą wartość domyślną. + +Dobra, spróbujmy jeszcze raz, tylko sprawdź, że nie mówię nieprawdy. Uruchommy to ponownie, ale zróbmy --greeting i użyjmy przykładu z materiałów szkoleniowych, powiedzmy "Konnichiwa!" + +Ponownie uruchamia workflow i rzeczywiście, nasz plik wyjściowy na górze został właśnie zaktualizowany nową wartością, którą podaliśmy w linii poleceń. + +Świetnie. To jest naprawdę centralny aspekt pisania dowolnego workflow Nextflow. Definiowanie rozsądnych wartości domyślnych w kodzie pipeline, ale ułatwianie konfiguracji użytkownikowi końcowemu poprzez posiadanie argumentów linii poleceń w terminalu. + +Zauważ, że użytkownik końcowy może nadpisać konfigurację w wielu różnych miejscach. Możesz mieć plik konfiguracyjny w swoim katalogu domowym, który jest stosowany do każdego pojedynczego uruchomienia Nextflow, które robisz. Możesz mieć plik konfiguracyjny w katalogu startowym. Możesz mieć plik konfiguracyjny w katalogu pipeline. Wszystkie te różne lokalizacje konfiguracji są ładowane w określonej kolejności, która jest opisana w dokumentacji Nextflow. + +Dobra, to koniec sekcji pierwszej. Mieliśmy nasz pierwszy skrypt workflow w Nextflow z processem i workflow. Przyjrzeliśmy się wejściom, wyjściom, skryptom i publikowaniu oraz jak podłączyć parametry i kanał wejściowy do naszego procesu. + +Gratulacje, twój pierwszy krok w kierunku pisania kodu Nextflow jest ukończony. + +Zrób sobie małą przerwę, a zobaczę cię za kilka minut w rozdziale drugim. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/pl/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..c4d0c29151 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Część 2: Hello Channels - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne informacje" + + Ta strona zawiera jedynie transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów szkoleniowych](../02_hello_channels.md). + + Numery sekcji pokazane w transkrypcji są podane jedynie orientacyjnie i mogą nie obejmować wszystkich numerów sekcji w materiałach. + +## Powitanie + +Cześć, witamy w drugiej części Hello Nextflow. + +Ten rozdział nazywa się Hello Channels. Będziemy mówić o tej fundamentalnej części Nextflow. + +Channels to elementy, które łączą różne kroki w Twoim pipeline, sposób, w jaki Twoje dane i logika przepływają przez Twój workflow. + +Dobra, zanurzmy się w to. + +Zacznijmy od przejścia do training.nextflow.io + +Hello Nextflow w pasku bocznym i kliknięcia w część drugą, Hello Channels. + +Wszystkie materiały są tutaj napisane, więc możesz podążać we własnym tempie i nadrobić wszystko, co mogłeś przegapić. + +Gdy już otworzysz stronę internetową, możesz załadować Codespaces i będziemy kontynuować od miejsca, w którym zakończyliśmy ostatni rozdział. + +## 0. Rozgrzewka: Uruchom hello-channels.nf + +W tym rozdziale będziemy edytować inny plik. Ten nazywa się Hello Channels, więc możesz go znaleźć w pasku bocznym, kliknij dwukrotnie, aby otworzyć. + +Teraz, jeśli właśnie przyszedłeś z rozdziału pierwszego, ten plik będzie Ci bardzo znajomy. Punkt wyjścia tutaj to w zasadzie miejsce, w którym zakończyliśmy rozdział pierwszy, z naszym processem o nazwie sayHello, naszym wejściem, wyjściem, naszym publishDir i naszym params.greeting, oraz naszym prostym workflow. + +Zaczynamy od nowego pliku, więc to równe warunki dla wszystkich, ale możesz kontynuować z poprzednim plikiem, jeśli wolisz. + +Zauważ, że usunąłem również wszystkie pliki .nextflow\* i katalogi work tutaj, po prostu aby był czysty punkt wyjścia. Nie ma znaczenia, czy to zrobisz, czy nie, to zależy od Ciebie. + +Dobra. Zacznijmy od sprawdzenia, czy ten pipeline nadal działa zgodnie z naszymi oczekiwaniami. Wywołam terminal tutaj. + +Wpiszę "nextflow run hello-channels.nf" i nacisnę enter. + +To uruchomi ten mały workflow, uruchomi nasz krok sayHello, wygeneruje katalog work z tym hashem, i tutaj jest nasz folder results, a tam jest nasz plik wyjściowy, dokładnie tak, jak oczekiwaliśmy od naszego domyślnego params.greeting. + +To wspaniałe. Dokładnie to samo co w rozdziale pierwszym, działa zgodnie z oczekiwaniami. + +## 1. Dostarczanie zmiennych wejściowych przez channel jawnie + +W rozdziale pierwszym faktycznie już używałeś channels, po prostu nie zdawałeś sobie z tego sprawy. Gdy określiliśmy tutaj string, Nextflow automatycznie utworzył dla nas channel wokół tego stringa, po prostu dlatego, że wiedział, że wywołujemy process, więc potrzebowaliśmy input channel. + +Pierwszą rzeczą, którą zrobimy, jest uczynienie tego jawnym poprzez faktyczne wypisanie samego channel. + +## 1.1. Utwórz input channel + +Więc przejdę do workflow tutaj na dole skryptu i powiem greeting_ch. To jest konwencja, której często używamy w kodzie Nextflow, aby mieć podkreślenie ch na końcu nazwy zmiennej, gdy jest to channel, po prostu aby łatwo było zidentyfikować, że to jest channel, ale nie musisz tego robić. Równa się channel of Hello Channels. + +To, czego właśnie użyliśmy, nazywa się "Channel Factory" w języku Nextflow. To jest ta rzecz tutaj, ustawiamy tę zmienną na nowy channel, a ta fabryka channel tutaj tworzy dla nas channel w określony sposób. + +Istnieje kilka różnych fabryk channel, które ma Nextflow, aby tworzyć channels z różnych typów wejść. Dot of jest najprościejszy i po prostu przyjmuje wszystkie stringi, które mu przekażemy. + +Zauważ, że gdy najadę na te słowa w VS Code, rozszerzenie Nextflow pokazuje mi popup wyjaśniający, co robi ta składnia, a na dole tego okna popup jest również tekst "read more". + +Jeśli kliknę to, otworzy dokumentację Nextflow w nowej zakładce i zabierze mnie bezpośrednio do dokumentacji dla tej konkretnej rzeczy. W tym przypadku dla channel.of. + +## 1.2. Dodaj channel jako wejście do wywołania procesu + +Zauważ, że rozszerzenie również daje nam ostrzeżenie mówiące, że utworzyliśmy tutaj nowy channel, ale nic go nie używa. + +Więc naprawmy to. Wezmę nową nazwę channel i zastąpię ten params.greeting naszym nowym channel. + +Zauważ, że nie używamy już teraz flagi wiersza poleceń --greeting, params.greeting nie jest używany, wracamy do zakodowania na stałe tego stringa. To w porządku. Staram się po prostu utrzymać rzeczy prostymi. Wrócimy później i użyjemy params ponownie. + +## 1.3. Uruchom ponownie polecenie workflow + +Dobra, sprawdźmy tylko, czy to działa. Wywołam terminal i zauważ ponownie. Nextflow run hello channels. Sprawdź output.txt, i oto jest. + +Świetny, trochę nudny przykład, robiący dokładnie to samo co wcześniej, ale teraz przynajmniej logika jest bardziej czytelna. Jesteśmy jawni w pisaniu nowego channel. + +Właściwie właśnie napisaliśmy więcej kodu, aby zrobić to samo. Ale to zacznie mieć więcej sensu, gdy staniemy się nieco bardziej skomplikowani w sposobie tworzenia naszych channels. + +## 2. Zmodyfikuj workflow, aby działał na wielu wartościach wejściowych + +Dobra, uczyńmy to nieco ciekawszym. Bardzo rzadko chcesz uruchomić pipeline Nextflow na pojedynczym wejściu, więc dajmy mu kilka wejść. + +## 2.1. Załaduj wiele powitań do input channel + +Z dokumentacji tutaj. Skopiuję te różne stringi, trzy z nich. Hello, Bonjour, Olà. Oh, mam nadzieję. Copilot sugeruje kilka innych. Więc zatabulujmy i wprowadźmy je. + +Dokumentacja Nextflow tutaj mówi nam, że możemy przekazać wiele wartości do tego operatora, więc powinno działać, ale wypróbujmy to i zobaczmy, co się stanie. + +## 2.1.2. Uruchom polecenie i spójrz na wyjście logów + +Cóż. Tak i nie. Zobaczmy. Mówi, że pięć z pięciu zadań zostało uruchomionych tutaj, ale pokazuje nam tylko jeden hash, co jest trochę dziwne. To w porządku. Wszystko jest zgodne z oczekiwaniami tutaj. Domyślnie Nextflow używa specjalnego typu wyjścia do terminala zwanego kodami kontrolnymi ANSI, co oznacza, że nadpisuje pewne linie, aby dać ładny skompresowany widok wszystkich różnych procesów, które są uruchamiane. + +Ma to o wiele większy sens, gdy masz większe workflows i uruchamiasz setki lub tysiące różnych próbek. Po prostu możesz wygenerować tak wiele wyjścia na terminalu, że niemożliwe jest spojrzenie na nie, podczas gdy ten aktualizujący się widok daje ci postęp w czasie rzeczywistym. + +## 2.1.3. Uruchom polecenie ponownie z opcją -ansi-log false + +Jeśli chcesz, możesz uruchomić to ponownie, a tym razem użyję dodatkowego argumentu rdzenia Nextflow z pojedynczym myślnikiem mówiącym, "-ansi-log false". To używa poprzedniej wersji wyjścia logów Nextflow. I tutaj możesz zobaczyć wszystkie indywidualne procesy, które zostały uruchomione. + +To zależy od Ciebie, czy to zrobisz, czy nie. Wyjście z Nextflow jest dokładnie takie samo w obu przypadkach. + +## 2.2. Upewnij się, że nazwy plików wyjściowych będą unikalne + +Dobra, spójrzmy więc na pliki wyjściowe, następnie przejdziemy do results. Ale jest tylko pojedynczy plik wyjściowy. Co się stało? Widzieliśmy, że process był uruchamiany wiele razy. Możemy przejść do katalogu work i zobaczyć wszystkie różne hashe, wszystkie zadania zostały wykonane prawidłowo. Ale jeśli pamiętasz w naszym procesie tutaj, zapisujemy wszystko do pliku output.txt, a następnie publikujemy to do tego katalogu. + +Więc ten sam plik został utworzony pięć razy, a następnie został nadpisany pięć razy. I po prostu mamy to, które zadanie wykonało się ostatnie. + +## 2.2.1. Skonstruuj dynamiczną nazwę pliku wyjściowego + +Sposób, w jaki to naprawiamy, to użycie dynamicznej nazwy pliku wyjściowego. Tutaj już mamy zmienną o nazwie greeting w procesie, więc możemy użyć jej w nazwie pliku wyjściowego. Kopiuję to i robię $greeting-output.txt. + +Otoczę to w cudzysłowy, po prostu żeby bash nie pomylił się przez jakiekolwiek spacje, które mogą się tu pojawić. A następnie wezmę tę samą nazwę pliku i zaktualizuję tutaj wyjście. + +To jest naprawdę ważne, aby wyjście pasowało do tego, ponieważ w przeciwnym razie ten plik nie zostanie znaleziony i Nextflow się zawiesi. + +Zamierzam dokonać jeszcze jednej naprawdę ważnej edycji, czyli zamienię te pojedyncze cudzysłowy na podwójne cudzysłowy. Zauważ, że kolor kodu zmienił się, gdy to zrobiłem. Ta zmienna jest rozwijana tylko wtedy, gdy używamy podwójnych cudzysłowów. Jeśli użyję tutaj pojedynczych cudzysłowów, jest używana jako wartość literalna, i otrzymałbym pojedynczy plik o nazwie $greeting-output, co nie jest tym, czego chcę. + +## 2.2.2. Uruchom workflow + +Więc wróćmy do podwójnych cudzysłowów i spróbujmy. + +Po prostu zamierzam uporządkować mój katalog przed rozpoczęciem, więc będzie łatwo zobaczyć nowe pliki. Zamierzam usunąć wszystko o nazwie .nextflow, work i results. + +I zamierzam uruchomić to polecenie Nextflow ponownie i zobaczmy, jakie pliki zostały utworzone. Więc uruchamia pięć procesów tam. Jeśli bardzo uważnie patrzyłeś, mogłeś zobaczyć, że ta linia się aktualizowała podczas działania. + +I teraz możemy przejść do katalogu results, i rzeczywiście, mamy pięć różnych wyjść, i wszystkie są poprzedzone różnymi powitaniami. + +Jeśli otworzę każdy z nich, zobaczymy, że każdy zawiera odpowiednie powitanie. Fantastycznie. To jest to, czego chcemy. + +## 3. Użyj operatora do przekształcenia zawartości channel + +Dobra, więc teraz wiemy, czym są channels i wiemy, czym są fabryki channel. A co z operatorami? To kolejny termin dla części języka Nextflow, który jest serią funkcji, które pozwalają nam operować na channels, aby zrobić z nimi pewne rzeczy. Nextflow zawiera zestaw operatorów, które pozwalają nam manipulować channels na różne sposoby. + +## 3.1. Dostarcz tablicę wartości jako wejście do channel + +Przejdźmy przez to na przykładzie. Powiedzmy, że chcemy wziąć te stringi wejściowe, ale zamiast po prostu umieszczać je bezpośrednio w fabryce channel, chcemy zdefiniować je jako tablicę. + +## 3.1.1. Ustaw zmienną wejściową + +Więc wezmę je i zrobię to jako nową linię powyżej i powiem, greetings, array. + +Proszę bardzo. Wezmę tę zmienną array i umieszczę ją w channel.of, i nacisnę save. + +## 3.1.3. Uruchom workflow + +Teraz zobaczmy, co się stanie. Wracam do mojego terminala. Po prostu zamierzam uporządkować wszystkie te pliki tymczasowe ponownie. I uruchommy workflow. + +Niedobrze. Dobra. To się zepsuło. W porządku. Spodziewałem się, że to się zepsuje tym razem. Debugowanie tego, co idzie nie tak, gdy workflow Nextflow zawodzi, jest kluczową częścią bycia deweloperem Nextflow. To będzie się zdarzać często i ważne jest, aby zrozumieć, co mówi komunikat o błędzie i jak sobie z tym radzić. + +Komunikaty o błędach Nextflow są w rzeczywistości dość strukturalne. Mówi nam, który process poszedł nie tak. Podaje nam komunikat o błędzie z powodu. Mówi, jakie było polecenie, które próbowało uruchomić w ramach tego konkretnego zadania, jaki był status wyjścia, jakie było wyjście i gdzie był katalog work tego zadania. + +Zauważ, że mogę kliknąć to opcją w VS Code, a otwiera się to w pasku bocznym, więc mogę przejść tam bezpośrednio i wyświetlić wszystkie te ukryte pliki, o których mówiliśmy w poprzednim rozdziale, włącznie z plikiem .command.sh. Jak widać, jest to to samo co polecenia, które zostały wykonane tutaj. + +Patrząc na ten plik, możemy poczuć, co mogło pójść nie tak tutaj zamiast uruchamiania pojedynczego zadania dla każdego elementu w tablicy, jak to było ostatnim razem, po prostu dostarczyło całą tablicę na raz jako string. Więc musimy rozpakować tę tablicę na indywidualne wartości, zanim przekażemy ją do channel. Wróćmy i zobaczmy, czy możemy to zrobić za pomocą operatora. + +## 3.2. Użyj operatora do przekształcenia zawartości channel + +W tym przypadku nie zamierzamy zmieniać tablicy przed przekazaniem jej do channel. Zamierzamy dostosować channel tak, aby zachowywał się w sposób, jakiego oczekujemy. Zamierzamy to zrobić, używając operatora flatten, może zrobić dot, zacznij pisać i zobaczymy, że rozszerzenie VS Code zaczyna sugerować wszystkie różne operatory, które mamy dostępne. + +## 3.2.1. Dodaj operator flatten() + +I zamierzam wybrać flatten. Zauważ, że białe znaki nie mają znaczenia w tym kontekście dla Nextflow. Więc możesz umieścić te operatory w nowej linii, jeśli chcesz. Więc mogę upuścić to tutaj i wciąć, żeby znajdowało się pod ".of" i zobaczysz, że ludzie często łańcuchują wiele operatorów w ten sposób na channel i wcięli to w ten sposób, aby było łatwiej to czytać. + +Możesz również zobaczyć, tak jak wcześniej, mogę najechać na to i przeczytać, co robi operator flatten, a także podążyć za linkiem do dokumentacji, jeśli chcę. + +Więc ten operator bierze ten channel, który ma w sobie pojedynczą tablicę i rozdziela wartości tablicy. + +## 3.2.2. Dodaj view() aby sprawdzić zawartość channel + +Możemy zajrzeć do channels za pomocą specjalnego operatora view, i zamierzam dodać kilka z nich tutaj. To jest trochę jak używanie instrukcji print w innych językach. Więc zamierzam zrobić dot view, a następnie zamierzam użyć tych kręconych nawiasów. + +To nazywa się closure. To zasadniczo daje dodatkowy kod do operatora view, który wykona na każdym elemencie w channel. W tym przypadku zamierzam powiedzieć greeting before flatten. Greeting. + +Definiuję tutaj zmienną, która jest tylko w zakresie tego closure. Więc ta zmienna jest używana tylko tutaj i mogłem nazwać ją, jak chciałem. To naprawdę nie ma znaczenia. Po prostu używam greeting, aby było łatwo czytać. + +W niektórych pipeline Nextflow możesz zobaczyć, że ludzie używają specjalnej niejawnej zmiennej o nazwie "$it". Tak jak to. To jest specjalna zmienna w kodzie Nextflow, która jest skrótem, więc nie musisz robić małej definicji zmiennej. Jednak z czasem myślimy, że to nie jest bardzo jasne dla ludzi, którzy są nowi w Nextflow, i teraz zniechęcamy do używania "$it". + +Więc zamierzam trzymać się poprzedniego zachowania greeting i używać tego w ten sposób, ponieważ jest to bardziej jawne i jaśniejsze, co się dzieje. + +Następnie skopiuję tę linię i zrobię dokładnie to samo ponownie po argumentach flatten. Operator view jest trochę specjalny, ponieważ robi coś na elementach, ale także po prostu kontynuuje przekazywanie ich do następnego operatora, więc możemy połączyć go w środku łańcucha operacji w ten sposób, a on wydrukuje tam status i będzie kontynuował. Więc miejmy nadzieję, że to pokaże nam, jak wygląda channel przed i po operatorze flatten. + +## 3.2.3. Uruchom workflow + +Wypróbujmy to. Wyczyść. Wyczyść wszystko w przestrzeni roboczej. Uruchom pipeline ponownie. + +Dobra, więc możemy zobaczyć, że uruchomił nasze pięć procesów. Ponownie, nie zawiesił się z błędem, więc to zdecydowanie dobrze. I teraz mamy before flatten i rzeczywiście mamy naszą tablicę i mamy after flatten, wydrukowane pięć razy, raz dla każdego elementu tablicy. To dokładnie to, na co liczyliśmy. Więc to naprawdę dobra wiadomość. I to pasuje dokładnie do tego, czego oczekiwalibyśmy od kodu. + +Nie potrzebujemy już tych instrukcji debugowania, więc mogę je albo zakomentować, albo usunąć. Zamierzam je usunąć, żeby utrzymać mój kod ładny i czysty. Dobra, świetnie. Ten przykład działa teraz ładnie i możemy zacząć widzieć, jak channels mogą robić nieco bardziej skomplikowaną logikę. + +## 4. Użyj operatora do parsowania wartości wejściowych z pliku CSV + +Teraz spróbujemy to zrobić, używając pliku z serią wejść zamiast tego. To jest bardzo powszechny sposób pisania pipeline Nextflow przy użyciu arkusza próbek lub CSV z metadanymi. + +## 4.1. Zmodyfikuj skrypt, aby oczekiwał pliku CSV jako źródła powitań + +Jeśli przejdę do paska bocznego, możesz zobaczyć greetings.csv w repozytorium przykładowym, i to jest bardzo, bardzo prosty plik CSV, który po prostu zawiera trzy linie z trzema różnymi powitaniami. Zobaczmy, czy możemy użyć tego pliku CSV w naszym workflow. + +Teraz zamierzam wrócić do używania params, jak robiliśmy to w rozdziale pierwszym, abyśmy mogli mieć wejście wiersza poleceń. + +Zamierzam usunąć tę tablicę greetings. + +## 4.1.1. Przełącz parametr wejściowy na plik CSV + +Zamierzam ustawić params greeting na nazwę pliku, która jest greetings.csv, i zamierzam użyć tej specjalnej zmiennej do wygenerowania channel. Zamierzam umieścić to tam, a błędy znikają. Pamiętaj, że to ustawia tę zmienną domyślnie teraz. Więc jeśli uruchomię pipeline bez żadnych argumentów, użyje greetings.csv, ale mogłem zrobić --greeting, aby nadpisać tę zmienną, gdybym chciał. + +## 4.1.2. Przełącz się na fabrykę channel zaprojektowaną do obsługi pliku + +Dobra, przekazujemy teraz plik zamiast stringa lub tablicy stringów, więc prawdopodobnie potrzebujemy innej fabryki channel. + +Pozbędziemy się "of", którego używaliśmy do tej pory, a zamiast tego użyjemy .fromPath. To robi dokładnie to, jak brzmi. Tworzy channel ze ścieżkami zamiast wartości, używając nazwy pliku string lub glob. Zamierzam również usunąć operator flatten, ponieważ już go nie potrzebujemy, teraz, gdy przekazujemy plik. + +## 4.1.3. Uruchom workflow + +Zamierzam nacisnąć save, otworzyć terminal, uruchomić workflow i zobaczyć, co się stanie. + +Dobra. Znowu się zawiesiło. Nie martw się. Tego też się spodziewałem. Spójrzmy na komunikat o błędzie i zobaczmy, czy możemy dowiedzieć się, co idzie nie tak. Tutaj możemy zobaczyć wykonane polecenie, i trochę jak wcześniej, gdzie mieliśmy wydrukowaną całą tablicę. Teraz mamy ścieżkę pliku echo do polecenia, zamiast przechodzenia przez zawartość pliku. + +## 4.2. Użyj operatora splitCsv() do parsowania pliku + +Więc aby użyć zawartości pliku zamiast tego, potrzebujemy innego operatora. Operator, którego zamierzamy użyć dla tego, nazywa się splitCsv. Ma sens, ponieważ to jest plik CSV, który ładujemy. + +## 4.2.1. Zastosuj splitCsv() do channel + +Ok, więc splitCsv. Zamknij nawias. Nie potrzebujemy tutaj żadnych argumentów. I znowu zamierzam użyć kilku operatorów view, aby dać pewien wgląd w to, co się tutaj dzieje. + +.view csv after splitCsv. Before split Csv. + +## 4.2.2. Uruchom workflow ponownie + +Dobra, spróbujmy to uruchomić i zobaczymy, co się stanie. + +Dobra, tym razem mamy trochę więcej wyjścia, ale nadal się zawiodło. Możemy spojrzeć na instrukcje view, i tutaj możesz zobaczyć before split CSV, i mamy ścieżkę pliku, jak widzieliśmy w poprzednim komunikacie o błędzie. After split CSV, teraz mamy trzy wartości odpowiadające trzem linii w pliku CSV. + +Jednak możesz zobaczyć, że każda z tych wartości jest otoczona nawiasami kwadratowymi. Więc każda z nich była tablicą sama w sobie, i to dało nam ten sam obszar, który mieliśmy wcześniej, gdzie próbuje echo tablicę zamiast tylko pojedynczego stringa. + +Jeśli pomyślimy o pliku CSV, ma to trochę sensu. Zazwyczaj plik CSV będzie miał wiersze i kolumny, więc split CSV robi dwuwymiarową tablicę. Pierwszy wymiar tablicy to każdy wiersz, a następnie jest drugi wymiar, który jest każdą kolumną dla każdego wiersza. + +Więc tutaj mamy tylko pojedynczą wartość w każdej linii, więc mamy pojedynczą kolumnę, więc mamy tablicę jednooelementową dla każdej linii pliku. + +To w porządku. Po prostu potrzebujemy kolejnego operatora, aby zwinąć tę tablicę dla każdej linii parsowanego pliku CSV. Posprzątajmy to. Pozbądźmy się terminala i zobaczmy, co możemy zrobić. + +## 4.3. Użyj operatora map() do wyodrębnienia powitań + +Teraz moglibyśmy użyć operatora flatten ponownie, którego używaliśmy wcześniej. Widzieliśmy, jak może zwinąć tablicę w serię wartości, co bardzo dobrze by tutaj zadziałało. Ale zamierzam wykorzystać okazję, aby zademonstrować inny operator, który jest bardzo powszechny w workflows, zwany operatorem map. + +## 4.3.1. Zastosuj map() do channel + +Zamierzam zrobić dot map i zamierzam zrobić item item[0]. + +Jeśli piszesz wiele innych języków kodu, możesz być już zaznajomiony z operatorem map. Bierze iterowalny, taki jak tablica lub channel, i wykonuje jakąś operację na każdej wartości tego. + +Tutaj mówimy, że powinniśmy zdefiniować zmienną o nazwie item w zakresie tego closure, a następnie chcemy zwrócić, tylko pierwszą wartość w tej tablicy. Więc item indeks zero. + +To jest skuteczne spłaszczanie tablicy. Możesz zobaczyć, jak moglibyśmy rozszerzyć to, aby było bardziej złożone, chociaż: gdyby nasz plik CSV miał sześć kolumn, ale jesteśmy zainteresowani tylko czwartą kolumną, moglibyśmy uzyskać dostęp do konkretnego indeksu tutaj. Lub wykonać jakikolwiek inny rodzaj operacji na wartości przed przekazaniem jej do przetwarzania downstream. + +Więc operator map jest niezwykle elastyczny i bardzo potężny do modyfikowania channels w locie. Wstawmy kolejną instrukcję view, aby zobaczyć, co robi w naszym wykonaniu. Może adjudicat tę linię i przenieść ją w dół. I after map. + +## 4.3.2. Uruchom workflow jeszcze raz + +Wywołajmy terminal i spróbujmy uruchomić workflow. + +Dobra, tym razem nie ma błędów. To dobry znak. Możemy teraz przejść przez wszystkie te różne wyjścia z instrukcji view. Before split CSV, mieliśmy pojedynczą ścieżkę. After split CSV, mieliśmy tablice jednowartościowe, a następnie after map, mamy tylko wartości bez żadnej składni tablicy. Przejdźmy do katalogu results, i tutaj są nasze pliki wyjściowe zachowujące się dokładnie tak, jak chcieliśmy. + +Jest mały bonus tutaj. Możesz faktycznie zobaczyć, że operatory view są nieco pomieszane w kolejności, w jakiej wykonały wyjście. To dlatego, że Nextflow wykonuje równoległość tych różnych zadań. Więc po podzieleniu CSV, są trzy elementy w tym channel, i obsługuje przetwarzanie tych trzech elementów równolegle automatycznie. To oznacza, że kolejność wyjść jest stochastyczna i może się różnić. W tym przypadku po prostu zdarzyło się, że niektóre z operatorów view zwróciły po zakończeniu kolejnego kroku, więc przyszło w tej kolejności. + +Jeśli uruchomię ten sam workflow ponownie. To rzeczywiście, przyszło w innej kolejności i tym razem mamy split CSV i mapy w kolejności, jakiej byśmy oczekiwali. + +Więc po prostu pamiętaj, nie możesz polegać na kolejności wyjść z zadania procesu, ponieważ Nextflow obsługuje tę równoległość dla Ciebie automatycznie. Nextflow robi to dla Ciebie swoją logiką przepływu danych, i to jest prawdziwa moc Nextflow. + +Dobra, to prawdopodobnie jeden z najważniejszych rozdziałów całego szkolenia. Gdy zrozumiesz channels, fabryki channel i operatory, zaczniesz włączać się w siłę Nextflow i to, co czyni go wyjątkowym jako język programowania. Ta funkcjonalność pozwala Nextflow zrównoleglać wszystkie Twoje workflows dla Ciebie i generować niezwykle złożoną logikę workflow z bardzo czystą składnią i modelem przepływu danych push. To może być na początku trochę dziwna koncepcja, ale gdy już przyzwyczaisz się do pisania kodu w ten sposób, szybko poczuje się to naturalne i zanim się zorientujesz, będziesz pisać fantastyczne workflows. + +Zrób sobie przerwę, filiżankę herbaty, spacer dookoła i przejdźmy do rozdziału trzeciego, gdzie zaczynamy rozszerzać te koncepcje na bardziej złożone workflows. Do zobaczenia w następnym filmie. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/pl/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..eb04441622 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Część 3: Hello Workflow - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne uwagi" + + Ta strona zawiera tylko transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów szkoleniowych](../03_hello_workflow.md). + + Numery sekcji pokazane w transkrypcji są podane tylko orientacyjnie i mogą nie zawierać wszystkich numerów sekcji w materiałach. + +## Powitanie + +Witam, witamy w trzeciej części kursu szkoleniowego "Hello Nextflow". + +Ten rozdział nosi tytuł "Hello Workflow". + +W rozdziale drugim zbudowaliśmy prosty workflow składający się z jednego procesu, ale w rzeczywistości pipeline'y są użyteczne, ponieważ mogą łączyć wiele kroków analizy razem. + +W tym rozdziale weźmiemy ten początkowy przykład i rozszerzymy go, aby był nieco bardziej realistyczny. + +Dodamy kilka dodatkowych kroków i przyjrzymy się, jak używamy kanałów do łączenia tych kroków. + +Będziemy się zajmować wieloma zadaniami, które mogą się zwijać do jednego procesu, i przyjrzymy się procesom, które mogą mieć wiele wejść i wiele wyjść. + +Dobra, zaczynajmy. + +Więc zacznijmy. Tak jak poprzednio. Przejdźmy do training.nextflow.io. Hello Nextflow, rozdział trzeci. Hello Workflow. I otwórzmy nasz obszar roboczy. Uporządkowałem wszystkie moje pliki robocze z poprzednich rozdziałów i zamierzam otworzyć Hello Workflow. + +Teraz to jest ten sam plik, nad którym pracowaliśmy do tej pory, więc powinien wyglądać znajomo. Mamy nasz proces say hello. Mamy nasz params.greeting z plikiem CSV greetings i mamy nasz workflow na dole, który ładuje ten plik CSV, tworzy kanał i przekazuje go do naszego procesu. + +## 0. Rozgrzewka: Uruchomienie hello-workflow.nf + +Jeśli chcesz, możemy to wypróbować i dokładnie sprawdzić, czy działa zgodnie z oczekiwaniami. Otwórzmy terminal, aby uruchomić nextflow run hello workflow nf i kliknij enter. + +Dobra, świetnie. Nasze trzy procesy działają. Mamy nasz katalog results z naszymi trzema wyjściami. Bonjour. Hello. Holà. Więc zamknijmy te pliki, zamknijmy terminal, wróćmy do skryptu. + +## 1. Dodanie drugiego kroku do workflow + +Dobra. W naszym przykładzie pozostajemy przy podstawach i staramy się być niezależni od domeny. Więc nasz drugi proces po prostu będzie manipulował tymi łańcuchami znaków, tymi słowami, w prosty sposób. Użyjemy polecenia Unix translate, aby wziąć te pliki i zamienić je na duże litery. Robimy to za pomocą polecenia "tr". + +## 1.1. Zdefiniowanie polecenia zamiany na wielkie litery i przetestowanie go w terminalu + +Możemy to wypróbować w terminalu bash i sprawdzić, czy działa. Więc robisz echo, Hello World, a następnie przekazujesz to z symbolem pipe do tr, i podajemy mu wzorzec rozpoznawania, a do z i na co powinien to przetłumaczyć. A do Z wielkimi literami. + +To jest bardzo proste, ponieważ dosłownie używa znaków od A do Z. Więc nie będzie działać na niczym, co jest akcentowane ani nic podobnego. Ale dla celów przykładu powinniście zrozumieć ideę. + +Zamierzam nacisnąć enter i wypisuje w terminalu HELLO WORLD wielkimi literami. I tak jak poprzednio, moglibyśmy przekierować to do pliku, gdybyśmy chcieli. Outfile. + +Dobra. Posprzątajmy to. + +## 1.1. Napisanie kroku zamiany na wielkie litery jako proces Nextflow + +Wróćmy do naszego skryptu i napiszmy nowy proces do obsługi tego polecenia bash. Zamierzam skopiować poprzedni proces, wkleić go poniżej i nazwać convert to upper. Dla uppercase. Zamierzam użyć tego samego publishDir results, ale zamierzam wprowadzić kilka zmian tutaj. Zamiast przyjmować val, zamierzam przyjąć path input file i zamierzam mieć tutaj prefiks upper, aby nasze pliki wyjściowe nie nadpisały wyjścia. I zamierzam użyć nazwy zmiennej z wejścia. A potem zamierzam zmienić skrypt tutaj na dole, i zamiast tego zamierzam użyć cat na pliku wejściowym i tak jak zrobiliśmy w Bash TR, a-z, upper input file .txt. Dobra, kliknijmy zapisz. + +## 1.2. Dodanie wywołania nowego procesu w bloku workflow + +Teraz jeśli przewinę w dół, musimy faktycznie wywołać ten proces. Samo dodanie procesu do skryptu nie wystarczy. Musimy powiedzieć Nextflow, że musimy uruchomić ten proces i gdzie to zrobić. + +Więc zamierzam tutaj, convert to upper i + +dobra, dostajemy błąd mówiący, że oczekuje argumentu. Na pewno, musimy coś przekazać do tego procesu, aby faktycznie miał coś do zrobienia. + +## 1.3. Przekazanie wyjścia pierwszego procesu do drugiego procesu + +To, co zamierzamy zrobić, to weźmiemy wyjście z tego procesu. Więc biorę nazwę, say hello, i gdy robię dot out. + +Dla tak prostego przykładu jak ten, gdzie mamy proces, który ma tylko jedno wyjście i przekazujemy je do nowego procesu, więc ma jedno wejście, to powinno być wszystko, czego potrzebujemy. Więc zamierzam kliknąć zapisz, otworzyć terminal i spróbujmy uruchomić to ponownie. + +## 1.4. Ponowne uruchomienie workflow + +Teraz nie uporządkowałem mojego katalogu work od ostatniego razu, kiedy uruchomiłem ten workflow. Zamierzam uruchomić go ponownie i zamierzam użyć tego jako okazji do pokazania, jak działa częściowe cache'owanie. Więc jeśli zrobię pojedynczy kreska resume. Miejmy nadzieję, że powinien ponownie użyć wyjść z pierwszego procesu, które były dokładnie takie same jak ostatnim razem, kiedy uruchamiałem. Ale teraz mamy nowy proces tutaj, który nie był wcześniej uruchamiany, który działa od podstaw. I na pewno, możesz zobaczyć, że pierwszy proces użył cache'owanych wyjść, a drugie wyjście uruchomiło trzy z trzech. Możesz również zobaczyć, że mamy teraz oba nasze procesy tutaj, nasz pierwszy proces, say hello, uruchomiony trzy razy, i nasz drugi proces convert to upper uruchomiony trzy razy. + +Jeśli uruchomię to ponownie, jako przypomnienie, z -ansi-log false, powinniśmy zobaczyć, że sześć różnych zadań procesu uruchomiło się, trzy dla każdego z nich. Więc to robi dokładnie to, czego się spodziewaliśmy. Pierwszy proces działa trzy razy, przekazując te wyjścia do drugiego procesu, który następnie działa trzy razy. + +Więc przyjrzyjmy się wnętrzu katalogu work i zobaczmy, jak Nextflow obsługuje te pliki wejściowe. Jeśli wezmę ten katalog hash tutaj z drugiego procesu, możemy użyć polecenia tree ponownie z -a tylko po to, aby spojrzeć na te pliki. Widzisz tutaj, że mamy nasz plik wejściowy, którym jest plik Bonjour-output.txt, i to jest faktycznie symlink. To właśnie pokazuje nam ta strzałka i wskazuje na plik w poprzednim katalogu work. + +To ma sens. Nextflow obsługuje wykonanie każdego zadania we własnym zamkniętym katalogu, więc jest całkowicie samodzielne. Jednakże musi dostarczyć pliki z poprzednich kroków jako wejście. Zamiast sięgać poza katalog work, aby pobrać te pliki, Nextflow umieszcza je w katalogu work. + +Jeśli mamy współdzielony system plików jak tutaj, robi to za pomocą symlinku, tak aby nie używało dodatkowej przestrzeni na pliki. Jeśli używamy pamięci chmurowej z bucket'ami w różnych lokalizacjach, pobrałby te pliki i faktycznie skopiował je do katalogu work. + +Przyjrzyjmy się plikowi command sh. Jeśli zrobię code work, command sh, możesz zobaczyć, na pewno, że uzyskuje dostęp do tego pliku z lokalnego katalogu. Więc wszystko jest bardzo samodzielne i czyste. + +Możemy również sprawdzić katalog results i upewnić się, że te pliki zostały poprawnie wyprowadzone. I na pewno, w results możemy zobaczyć wszystkie pliki wyjściowe z pierwszego procesu i wszystkie pliki wyjściowe z drugiego. I wszystkie są wielkimi literami, jak się spodziewaliśmy. + +To tutaj zaczyna się pokazywać moc Nextflow. Za pomocą bardzo minimalnego kodu Nextflow obsługiwał równoległe wykonywanie tych zadań z czystą enkapsulacją w oddzielnych katalogach work oraz umieszczanie plików wejściowych i wyjściowych oraz publikowanie plików, wszystko automatycznie dla nas, od razu. Więc widzicie, jak, gdy skalujemy złożoność naszych workflow'ów analizy, ta funkcjonalność jest naprawdę, naprawdę cenna. + +## 2. Dodanie trzeciego kroku do zebrania wszystkich powitań + +Dobra. Te kroki były jeden-do-jednego. Mieliśmy jedno wyjście z pierwszego procesu trafiające do jednego wejścia dla drugiego procesu. Dalej będziemy mówić o tym, jak zebrać te różne wyjścia w jedno zadanie procesu, co znowu jest bardzo powszechną rzeczą do zrobienia. Więc szybko otwórzmy terminal i zróbmy próbny przebieg tego. + +## 2.1. Zdefiniowanie polecenia zbierania i przetestowanie go w terminalu + +Zamierzam oszukać i skopiować przykładowy kod bash z materiału szkoleniowego i po prostu nacisnąć enter. + +To, co możemy tutaj zobaczyć, to uruchomiliśmy to polecenie echo trzy razy do trzech różnych plików wyjściowych, które mogę tutaj zobaczyć. A następnie użyliśmy polecenia cat, aby wypisać wyjście każdego z tych trzech różnych plików i przekierować to do jednego zebranego pliku. + +I jeśli zrobię "cat COLLECTED-output", możesz zobaczyć, że zawiera zawartość tych trzech różnych plików, teraz w jednym pliku. + +## 2.2. Utworzenie nowego procesu do wykonania kroku zbierania + +Więc zobaczmy, czy możemy odtworzyć to samo w naszym pipeline Nextflow. + +Przewińmy w górę i stwórzmy trzeci proces. Zamierzam skopiować ten poprzedni, a tym razem zamierzam nazwać go Collect Greetings. + +W terminalu bash nazwaliśmy to collected output txt. Więc zamierzam powiedzieć to samo path output tutaj. I zamierzam zrobić przekierowanie tutaj, więc jest zapisywane w ten sam sposób. + +Dobra. Musimy zmienić to, co dzieje się na początku tego polecenia i musimy pomyśleć o tym, czym jest tutaj plik wejściowy. W rzeczywistości ten proces będzie przyjmował wiele plików wejściowych. Zamierzam zachować path i zamierzam zmienić to na nową zmienną o nazwie input files, w liczbie mnogiej. + +Następnie zamierzam ponownie, cat je, tak jak zrobiliśmy w naszym skrypcie bash. I zamierzam użyć tutaj zmiennej. + +Teraz możesz pomyśleć, że to nie zadziała. Widzieliśmy wcześniej błędy, gdzie tablica łańcuchów lub tablica ścieżek została przekazana do procesu i to spowodowało błąd. Ale w rzeczywistości tutaj Nextflow obsłuży to automatycznie dla nas we właściwy sposób. Weźmie kilka różnych plików wejściowych i po prostu wypisze różne ścieżki plików tutaj. + +Oczywiście pomaga to, że polecenie cat może przyjmować serię nazw plików w ten sposób. Gdybym używał innego polecenia, które wymagało argumentu przed każdą ścieżką pliku lub czegoś, musielibyśmy mieć tutaj trochę więcej kodu i logiki, aby móc obsłużyć iterację tych ścieżek plików. Ale w tym przypadku powinno po prostu zadziałać. + +## 2.3. Dodanie kroku zbierania do workflow + +Dobra, zejdźmy do workflow i dodajmy nasz nowy proces. Collect greetings. I znowu weźmy wyjście z convert to upper out. Zapiszmy to. + +Wypróbujmy to. nextflow run hello workflow. + +Dobra, workflow się uruchomił, ale coś jest trochę dziwne. Mamy trzy wykonania pierwszego kroku, czego się spodziewamy. Trzy zadania dla drugiego, ale mamy również trzy zadania na końcu, kiedy spodziewaliśmy się mieć tylko jedno zadanie tutaj łączące wszystkie wyjścia. + +Jeśli przejdziemy do naszego katalogu results. Widzimy również, że collected output ma tylko jedną wartość zamiast wszystkich trzech. To dlatego, że ten plik wyjściowy był nadpisywany trzy razy z trzema różnymi wartościami. + +To ma sens, ponieważ przekazaliśmy jedno wyjście do jednego wejścia tutaj w ten sam sposób, jak zrobiliśmy to w poprzednim kroku. + +## 2.4. Użycie operatora do zebrania powitań w jedno wejście + +Więc potrzebujemy operatora tutaj, aby wziąć ten kanał z trzema elementami i zwinąć je do jednego elementu, tak aby ten końcowy proces uruchomił się tylko raz. + +Aby to zrobić, użyjemy operatora collect. Mogę to zrobić bezpośrednio w workflow. Mogę zrobić .out i połączyć łańcuchowo z operatorem tutaj na końcu .collect. + +Kliknij zapisz. A następnie dla celów tego szkolenia zamierzam również zrobić kilka operatorów view, jak robiliśmy wcześniej, abyśmy mogli spojrzeć na ten kanał przed i po użyciu operatora collect, więc możemy zrozumieć, co się dzieje. + +Zamierzam wziąć ten kanał, pozbyć się collect i dot view greetings, a następnie zamierzam zduplikować tę linię, dodać operator collect. I zmienić to na after. + +To jest oddzielne od miejsca, gdzie to wywołujemy, ale to w porządku, ponieważ używamy tych samych wywołań operatorów na tym samym kanale wyjściowym. + +Dobra, kliknijmy zapisz i wypróbujmy to w terminalu. Zamierzam uruchomić nextflow run. Hello, workflow. Ponownie uruchomić nasz skrypt. + +Dobra. To wygląda lepiej. Tak jak poprzednio możemy zobaczyć, że pierwsze dwa procesy uruchamiają się trzy razy, a teraz nasz końcowy proces uruchomił się tylko raz. + +Jeśli spojrzymy na to, co zostało wypisane przez operator view, tutaj na dole, powiedzieliśmy before collect, co jest tym wyjściem tutaj, i to jest wypisane trzy razy. I widzisz, że jest pojedyncza ścieżka dla każdego z nich. A potem after collect, możesz zobaczyć, że mamy tę tablicę trzech ścieżek. Więc to jest zgodne z oczekiwaniami. + +Dobra, sprawdźmy plik results i zobaczmy, czy tym razem jest zgodny z oczekiwaniami. Na pewno, są teraz trzy linie w pliku - to z powodzeniem połączyło te trzy wyjścia w jeden plik wyjściowy. Fantastycznie. + +Dobra, zamierzam posprzątać i przejdźmy do następnego kroku. I zamierzam usunąć te instrukcje view tylko po to, aby zachować porządek. + +## 3. Przekazanie więcej niż jednego wejścia do procesu w celu unikalnego nazwania końcowego pliku wyjściowego + +Dobra. Do tej pory wszystkie nasze procesy przyjmowały tylko jedno wejście. Teraz zamierzamy wykonać ćwiczenie, w którym dodamy więcej niż jedno wejście do procesu, aby zobaczyć, jak to działa. Aby to zrobić, użyjemy tego przykładu collect greetings. + +Za każdym razem, gdy uruchamiałem workflow, nadpisywał ten plik w katalogu results, co może nie być tym, czego chcemy. + +## 3.1. Modyfikacja procesu zbierania, aby akceptował zdefiniowaną przez użytkownika nazwę dla pliku wyjściowego + +Więc dla tego przykładu zamierzamy przekazać dodatkowy parametr, abyśmy mogli dostosować nazwę pliku wyjściowego. + +Dodanie drugiego wejścia do procesu jest bardzo proste. Po prostu dodaję drugą linię w bloku input. Tym razem to będzie value, a nie path, ponieważ chcemy przekazać łańcuch i zamierzam nazwać to batch underscore name. + +Mogę teraz użyć tej zmiennej w bloku script i zamierzam powiedzieć collected dash dollar batch name. + +Używam tutaj nawiasów klamrowych wokół nazwy zmiennej. To tylko po to, aby oddzielić ją od reszty łańcucha i prawdopodobnie nie jest to potrzebne w tym przypadku, ale myślę, że ułatwia to czytanie. + +Dobra. Na koniec pamiętaj, aby zaktualizować ścieżkę wyjścia, ponieważ teraz nazwa pliku się zmieniła, więc zamierzam zrobić to samo i umieścić batch name w wyjściu path zgodnie z oczekiwaniami. + +## 3.2. Dodanie parametru wiersza poleceń batch + +Teraz musimy przekazać nazwę batch skądś i zamierzam stworzyć drugi parametr, aby to zrobić, abyśmy mogli to zrobić w wierszu poleceń, gdy uruchamiamy workflow. + +Więc zamierzam zrobić params batch name, a domyślnie nazwijmy to test batch. Teraz mogę użyć tej specjalnej zmiennej parametrów tam, gdzie wywołujemy proces. + +I na pewno VS Code mówi nam, że nie ma wystarczającej liczby argumentów dla tego procesu teraz i że oczekuje drugiego wejścia. + +Po prostu robię przecinek i przekazuję naszą nową zmienną i błąd znika. + +Zauważ, że kolejność wejść tutaj jest naprawdę ważna. Pierwsze wejście procesu było path, a drugie wejście to name. Jeśli zmienię kolejność tutaj, muszę również zmienić kolejność, gdy wywołuję proces. W przeciwnym razie. Dalej przekażemy niewłaściwy kanał do niewłaściwego wejścia. + +## 3.3. Uruchomienie workflow + +Dobra, wypróbujmy to i zobaczmy, czy działa. Zróbmy "nextflow run hello- workflow. Dobra, uruchomił się jak poprzednio. Przyjrzyjmy się katalogowi results. + +Na pewno, nasza nazwa pliku tutaj nazywa się teraz " collected test batch output txt". Fantastycznie. + +A teraz zobaczmy, czy możemy to nadpisać, uruchamiając ponownie. Tym razem zamierzam zrobić --batch_name, aby dopasować tę nazwę specjalnej zmiennej parametru tutaj. I zamierzam nazwać to demo output. + +Uruchom workflow ponownie i zobaczymy, czy coś się stanie. + +Dobra, teraz mamy collected demo output .txt. I ponieważ ta nazwa pliku różni się od tamtej, nie nadpisała jej. Obie są teraz obecne w katalogu results. + +## 4. Dodanie wyjścia do kroku zbierania + +Dobra, więc tam pokazaliśmy podawanie wielu wejść do procesu, ale co z wieloma wyjściami? W tym przykładzie zamierzamy obliczyć liczbę powitań, które są przetwarzane i wyprowadzić to jako drugorzędne wyjście dla tego kroku collect greeting. + +## 4.1. Modyfikacja procesu, aby liczył i wyprowadzał liczbę powitań + +Zamierzamy zrobić tutaj małą sztuczkę. Procesy Nextflow mają ten blok script z wieloliniowym łańcuchem i jest on przekazywany jako wyjście bash do dot command dot sh. Ale możemy faktycznie napisać dowolny niestandardowy kod powyżej tego, i zostanie on wykonany jako część zadania, ale nie zostanie włączony w skrypt bash. + +Jedną z wbudowanych funkcji w składni Nextflow jest funkcja size. Więc zamierzam wziąć wejście path i zamierzam powiedzieć count underscore greetings, tylko po to, aby zdefiniować nazwę zmiennej. Zamierzam wziąć pliki wejściowe i zamierzam wywołać "size" na nich. + +Ta funkcja policzy rozmiar tego kanału wejściowego i przypisze go do zmiennej. + +Możemy teraz zwrócić tę zmienną jako część bloku output. Więc mówimy, val, ponieważ jest to wartość, a nie plik. I count greetings. + +Teraz to samo w sobie jest wystarczające i moglibyśmy teraz uzyskać dostęp do tych różnych wyjść z tego procesu. Jednakże musielibyśmy uzyskać do nich dostęp w sposób pozycyjny. Więc używając klucza indeksu takiego jak zero i jeden. + +Aby ułatwić sobie dostęp do wyjść, możemy je nazwać i robimy to za pomocą instrukcji emit. + +Więc robimy przecinek emit out file lub cokolwiek chcę to nazwać. I robię tutaj emit count. To jest w zasadzie tylko dekorator, który pomaga nam pisać nieco czystszy kod, abyśmy mogli łatwo odwoływać się do konkretnych wyjść później w bloku workflow. + +## 4.2. Raportowanie wyjścia na końcu workflow + +Dobra. Jeśli przewinę w dół do bloku workflow, mogę teraz wziąć wyjścia collect greetings, zrobić collect greetings, dot out, i możemy zobaczyć nasze dwa nazwane wyjścia są sugerowane tutaj przez rozszerzenie VS Code. Bardzo przydatne. + +Więc zamierzam zrobić dot count, aby uzyskać wartość count, którą właśnie stworzyliśmy, i zamierzam zrobić view, aby zostało wypisane w wierszu poleceń. Więc możemy to zobaczyć, gdy uruchamiamy workflow. + +Napiszmy coś w domknięciu tutaj tylko po to, aby było to trochę ładniejsze. num greetings, there were greetings greetings. + +I tak naprawdę nie zależy nam na drugim wyjściu, ponieważ nie używamy go jako wejścia dla żadnych innych procesów. Ale widzicie, jak moglibyśmy łatwo przekazać to jako wejście do innego procesu, gdybyśmy chcieli, w dalszej części. + +## 4.3. Uruchomienie workflow + +Zamierzamy kliknąć zapisz. Przyjrzyjmy się terminalowi i wypróbujmy to. + +Dobra, fantastycznie. Proszę bardzo. There are three greetings. To dokładnie tak. + +Dobra, świetna robota. To koniec tego rozdziału. Wszystko zrobione, że dotarliście tak daleko. Teraz zaczynasz budować dość realistyczny workflow, gdzie jesteśmy w stanie obsługiwać wejścia i wyjścia oraz logikę w naszym workflow. + +Gdy te pliki workflow stają się dłuższe, zaczynają być nieco nieporęczne. Więc w następnym rozdziale przyjrzymy się, jak możemy modularyzować kod Nextflow do oddzielnych plików, aby łatwiej było znaleźć i utrzymać kod w workflow. + +Dołącz do nas w następnym filmie dla rozdziału czwartego. Hello Modules. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/pl/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..470121901c --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Część 4: Hello Modules - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne uwagi" + + Ta strona zawiera tylko transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów szkoleniowych](../04_hello_modules.md). + + Numery sekcji pokazane w transkrypcji są podane wyłącznie w celach poglądowych i mogą nie obejmować wszystkich numerów sekcji w materiałach. + +## Powitanie + +Cześć, witamy w czwartej części szkolenia Hello Nextflow. + +Ten rozdział nazywa się Hello Modules i będziemy mówić o tym, jak modularyzować kod Nextflow. Zamierzamy wziąć nasz jeden skrypt i podzielić go na osobne pliki. + +To sprawia, że kod jest łatwiejszy w nawigacji i utrzymaniu, gdy Twój przepływ pracy się powiększa, a także umożliwia udostępnianie modułów między pipelinami, dzięki czemu jeśli masz wiele pipelinów używających tego samego narzędzia, musisz napisać ten proces tylko raz. + +Klasycznym przykładem tego jest repozytorium nf-core modules, które zawiera tysiące różnych gotowych do użycia narzędzi w modułach, które możesz zainstalować i użyć w swoim przepływie pracy. + +Nextflow może również pracować z sub workflows, które są jak moduły, ale mają wiele procesów. To wykracza poza zakres tego szkolenia, ale działa to w zasadzie w ten sam sposób. + +Dobrze. Rzućmy okiem. + +Jak zwykle, zacznij od przejścia do training.nextflow.io. + +Przejdź do "Hello Nextflow" na pasku bocznym i robimy część czwartą: "Hello Modules". + +Teraz przejdę do mojego środowiska GitHub Codespaces i przyjrzę się plikowi "hello-modules". + +Tak jak wcześniej, zaczynamy od punktu końcowego poprzedniego rozdziału, więc ten skrypt powinien wyglądać znajomo. Mamy nasze trzy procesy, say hello, convert to upper i collect greetings, oraz prosty workflow, który uruchamia te trzy polecenia i emituje wiadomość na końcu. Mamy dwa parametry zwane greeting i batch, które określają nazwę, która jest używana dla zebranego pliku wyjściowego na końcu. + +## 0. Rozgrzewka: Uruchom hello-modules.nf + +Możemy zweryfikować, że ten workflow nadal działa zgodnie z oczekiwaniami, wykonując nextflow run hello-modules. + +Świetnie. Uruchomiło trzy zadania z każdym z tych procesów, jedno zadanie collect i powiedziało nam, że w tej partii są trzy powitania. Jeśli wejdziemy do results, mamy nasze różne pliki wyjściowe tutaj, włącznie ze zebranym plikiem wyjściowym test batch. + +## 1. Utwórz katalog do przechowywania modułów + +Dobrze. Zróbmy trochę modularyzacji. + +Generalnie dobrym pomysłem jest umieszczenie modułów w podfolderze w repozytorium Twojego pipeline'u, po prostu aby zachować porządek. Możesz nazwać to jak chcesz, ale zgodnie z konwencją zazwyczaj nazywamy to modules. + +Więc chodźmy do terminala i zróbmy mkdir modules. Możesz zobaczyć, jak pojawia się w pasku bocznym VS Code tutaj. + +## 2. Utwórz moduł dla sayHello() + +Następnie utworzę nowy plik dla mojego pierwszego modułu. Możesz zrobić "touch" lub "code" lub możesz to zrobić na pasku bocznym, naprawdę to nie ma znaczenia. Więc zrobię code modules i nazwę go od nazwy procesu. Więc sayHello.nf. NF jest tradycyjnym rozszerzeniem pliku dla plików Nextflow. + +Nacisnę zapisz tutaj i zobaczymy, jak pojawia się nasz nowy plik modułu. + +## 2.2. Przenieś kod procesu sayHello do pliku modułu + +Dobrze, teraz wezmę kod modułu z workflow. Wezmę również hash bang tutaj i najpierw go skopiuję, aby było jasne, że to plik Nextflow. A potem wezmę ten proces i wytnę. Więc usunę go z mojego głównego skryptu workflow i wkleję do tego nowego modułu. + +To cała zawartość, którą będzie zawierał ten plik modułu. Tylko jeden proces, żadnego workflow, żadnej logiki, tylko sam proces. + +Teraz mogę zamknąć ten plik. + +## 2.3. Dodaj deklarację import przed blokiem workflow + +Teraz mojemu workflow brakuje pierwszego procesu, więc musimy go przywrócić poprzez import. Składnia tego jest bardzo podobna do innych języków programowania, więc może być znajoma. Robimy include w klamrowych nawiasach, nazwa procesu, say hello, a następnie from i ścieżka pliku modules, say hello, nf. Fantastycznie. + +Kilka sztuczek tutaj. Rozszerzenie VS Code jest w tym mądre. Rozpoznaje tę ścieżkę pliku i możesz najechać na nią kursorem i kliknąć follow link. Albo jestem na Mac, mogę nacisnąć option i kliknąć, a otworzy ten plik. Więc możemy szybko do niego przeskoczyć. + +Ta nazwa procesu jest teraz używana przez workflow poniżej i możemy zrobić to samo tutaj. Pokazuje nam trochę informacji o tym procesie i znowu, mogę przytrzymać option, kliknąć na to i otworzy się w edytorze. + +Więc to naprawdę szybki sposób, gdy masz wiele plików dla swoich różnych procesów, aby szybko nawigować po bazie kodu w VS Code. + +Dobrze. To w zasadzie wszystko w tym rozdziale. Teraz po prostu robimy to samo dla innych procesów. + +## 3. Modularyzuj proces convertToUpper() + +Więc stwórzmy nowy plik tutaj. Nazwijmy go Convert to upper nf. Znowu skopiujmy hash bang. A potem wytnijmy proces. + +Skopiuj nazwę procesu tam, dodaj nową instrukcję include z nową nazwą procesu. + +## 4. Modularyzuj proces collectGreetings() + +A potem zróbmy to samo dla trzeciego procesu. Nowy plik, collect greetings, + +zróbmy hash bang. Wytnijmy proces, wklejmy proces i zróbmy nową instrukcję include. + +Teraz możesz zobaczyć tutaj, że mam podkreślenie błędu mówiące invalid include source. I to jest w rzeczywistości prawdziwy błąd, który popełniłem, ponieważ poruszałem się trochę za szybko. Jeśli spojrzysz uważnie, zobaczysz, że pominąłem T w convert to upper + +Więc VS Code bardzo pomocnie powiedział mi, że popełniłem tam błąd. Jeśli naprawię tę nazwę pliku, błąd znika. To dobry przykład, dlaczego sprawdzanie błędów w VS Code jest tak przydatne do pisania kodu Nextflow. Inaczej bym tego nie zauważył i dowiedziałbym się o tym znacznie później, gdy próbowałbym uruchomić workflow. + +Nasz główny skrypt pipeline wygląda teraz znacznie prościej. Nie ma w nim żadnych procesów, mamy tylko trzy instrukcje include i nasz workflow. Nie zmieniliśmy żadnej logiki workflow. Nie zmieniliśmy żadnego kodu procesu, więc miejmy nadzieję, że powinno działać dokładnie w ten sam sposób. + +## 4.4. Uruchom workflow, aby zweryfikować, że robi to samo co wcześniej + +Sprawdźmy. Otworzę terminal i uruchomię dokładnie to samo polecenie co wcześniej. + +I rzeczywiście, uruchomiło nasze procesy, say hello, convert to upper, collect greetings i dało nam znowu trzy powitania. + +Więc przenieśliśmy nasz kod, ale nie zmieniliśmy niczego w sposobie wykonywania workflow i jest całkowicie niezmieniony. Jedyna różnica polega na tym, że mamy teraz czystszy kod, łatwiejszy w utrzymaniu i łatwiejszy do udostępnienia innym. + +I to wszystko. To był krótki rozdział. To prosta koncepcja, ale bardzo potężna i kluczowa dla sposobu, w jaki piszemy bardziej złożone workflow Nextflow. Więc ważne jest, abyś to rozumiał i wyrobił sobie nawyk korzystania z tego. + +W następnym rozdziale zmienimy trochę tempo i przestaniemy myśleć tak dużo o składni pisania kodu Nextflow, a pomyślimy trochę o tym, jak używamy oprogramowania w samych procesach. Dołącz do nas w części piątej Hello Containers. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/pl/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..8feefb9bed --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Część 5: Hello Containers - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne informacje" + + Ta strona zawiera tylko transkrypcję. Pełne instrukcje krok po kroku znajdziesz w [materiale szkoleniowym](../05_hello_containers.md). + + Numery sekcji pokazane w transkrypcji mają charakter orientacyjny i mogą nie zawierać wszystkich numerów sekcji w materiałach. + +## Witamy + +Cześć, witamy w piątej części kursu szkoleniowego Hello Nextflow. + +Ten rozdział nosi tytuł Hello Containers. Porozmawiamy o tym, jak Nextflow integruje się z narzędziami takimi jak Docker i Singularity, aby używać kontenerów do dostarczania oprogramowania użytkownikom Twojego pipeline'u. + +Oznacza to, że kiedy ludzie uruchamiają Twój pipeline, nie muszą sami instalować wszystkich różnych narzędzi. Nextflow zrobi to za nich. + +Kontenery to niezwykle potężna technologia, kluczowa dla powtarzalności i łatwości użycia. Zaczniemy od krótkiego wprowadzenia do samych kontenerów, ręcznego uruchomienia kilku poleceń docker, a następnie użyjemy tych samych kontenerów w naszym pipeline'ie Nextflow. + +Dobra. Zaczynajmy. + +Tak jak poprzednio, zacznijmy od załadowania materiałów szkoleniowych. Wejdź na training.nextflow.io. Hello Nextflow, Rozdział 5, Hello Containers. + +Przejdę do mojego środowiska Codespaces, a po lewej stronie widzimy hello containers dot nf. + +Tak jak poprzednio, jest to ten sam skrypt, którym zakończyliśmy poprzedni rozdział 4, więc powinien wyglądać znajomo. + +Mamy nasze parametry wiersza poleceń do określenia pliku wejściowego i nazwy partii. Dołączamy nasze trzy moduły i mamy nasz workflow, w którym uruchamiamy trzy procesy. + +## 0. Rozgrzewka: Uruchom hello-containers.nf + +Możesz uruchomić ten workflow ponownie i sprawdzić, czy produkuje oczekiwane wyniki. Na razie zamknę go i przejdę do terminala. + +## 1. Użyj kontenera 'ręcznie' + +Na początku tego rozdziału zrobimy podsumowanie technologii kontenerów. Jeśli jesteś bardzo zaznajomiony z docker, singularity lub innymi technologiami kontenerów, potraktuj to jako odświeżenie wiedzy lub pomiń tę część całkowicie. + +Nextflow obsługuje wiele różnych typów technologii kontenerów. Obejmuje to Docker, Singularity, Podman, Shifter, Charliecloud i inne. + +W tym szkoleniu skupimy się na Docker. Jest on preinstalowany w code spaces i jest jedną z najpopularniejszych technologii kontenerów, szczególnie jeśli rozwijasz na własnym komputerze lub laptopie. + +Jeśli pracujesz w środowisku akademickim na współdzielonym HPC, możesz zauważyć, że dostępny jest Singularity, a nie Docker. To w porządku. Wszystkie koncepcje są dokładnie takie same. Kilka ręcznych poleceń jest różnych, ale jeśli rozumiesz Docker, zrozumiesz także singularity. + +W rzeczywistości Singularity jest również zainstalowany w środowisku Code Spaces. Więc jeśli chcesz, możesz spróbować wykonać te same zadania używając Singularity zamiast Docker. + +Dobra, czym jest technologia kontenerów? Ideą Docker jest to, że może pobrać obraz ze zdalnego źródła, ściągnąć go na lokalną maszynę, a następnie utworzyć kontener na podstawie tego obrazu. + +Ten działający kontener jest trochę jak maszyna wirtualna działająca na Twoim komputerze. Jest odizolowany od Twojego środowiska i jest wstępnie zapakowany z systemem operacyjnym i zestawem dostępnego oprogramowania. + +## 1.1. Pobierz obraz kontenera + +Składnia, której potrzebujemy do pobrania istniejącego obrazu to "docker pull". Wpiszę to w moim terminalu, ale teraz potrzebujemy obrazu, z którym będziemy się bawić. + +Możesz budować obrazy samodzielnie. Możesz je znaleźć w publicznych rejestrach takich jak Docker Hub czy quay.io. Ale naprawdę dobrym sposobem na szybkie uzyskanie obrazów jest użycie Seqera Containers. + +To darmowa usługa społecznościowa, którą stworzyliśmy w 2024 roku i którą możesz używać bez logowania czy czegokolwiek innego. + +Jeśli przejdziesz na seqera.io/containers lub klikniesz containers na górze, zobaczysz interfejs wyszukiwania i możesz wpisać nazwę dowolnego narzędzia dostępnego w Conda lub Python Package Index. + +Domyślnie przeszukuje kanały Bioconda i Conda Forge, ale możesz poprzedzić dowolny kanał Conda, jeśli chcesz. + +Dla zabawy użyjmy cowpy. Wpiszę cowpy. Daje mi wyniki z Python Package Index i Conda Forge. Kliknę to, aby dodać do mojego kontenera. Mógłbym dodać wiele pakietów, gdybym chciał. Wybieram Docker, wybieram linux/amd64 i klikam Get Container. + +To buduje dla mnie obraz na żądanie, jeśli nie został jeszcze utworzony, i daje mi URL, który mogę skopiować. + +Jeśli jesteś zainteresowany, możesz kliknąć view Build Details, co zabierze Cię na stronę pokazującą plik środowiska conda, który został użyty, oraz kompletny dziennik budowania wraz z wynikami skanowania bezpieczeństwa. + +Jeśli wrócę do moich code spaces, mogę teraz wkleić tę nazwę kontenera i nacisnąć enter. + +Docker teraz pobiera wszystkie różne warstwy w tym obrazie kontenera i teraz mówi nam, że ten obraz jest dostępny do użycia. + +## Pobieranie obrazu Singularity + +Jeśli używasz singularity, proces jest w zasadzie taki sam. Wybieramy nasze pakiety obrazów, wybieramy cowpy. Teraz wybieramy Singularity zamiast Docker i klikamy Get Container. To daje nam URL obrazu używający oras://. Lub jeśli wolisz, możesz użyć https:// zaznaczając to pole. Kopiuję ten URL. Teraz przechodzę do Code Spaces. W rzeczywistości mamy zainstalowany Apptainer w tej przestrzeni, który jest taki sam jak Singularity, ale są do siebie aliasowane. Więc zrobię apptainer pull, a następnie nazwę to cowpy sif, ale możesz nazwać to jak chcesz. Wklejam URL. I to pobierze dla mnie ten obraz. + +Mógłbym zrobić ls -lh i zobaczyć cowpy.sif + +Singularity różni się od Docker tym, że singularity przechowuje wszystkie obrazy w płaskich plikach, podczas gdy Docker ma rejestr, gdzie przechowuje wszystkie warstwy oddzielnie na Twojej maszynie hosta i ma działającego demona, aby śledzić to wszystko. + +## 1.2. Użyj kontenera do uruchomienia cowpy jako jednorazowego polecenia + +Dobra, wróćmy do Docker. Możemy teraz spróbować uruchomić ten obraz, który utworzyliśmy, robiąc docker run. + +Zrobię dash dash rm, co po prostu wykonuje jednorazowe wykonanie obrazu. I wkleję URL obrazu. A na końcu kończysz to poleceniem, które chcesz uruchomić. + +Obraz, który wygenerowaliśmy, miał zainstalowane cowpy, więc spróbujmy cowpy. + +Proszę bardzo. Uruchomił nasze polecenie. Nie mam cowpy zainstalowanego lokalnie. Możesz zobaczyć, że jeśli spróbuję to uruchomić, nie istnieje. Jednak w tym poleceniu uruchomiłem to używając Docker i poprawnie wygenerowało to wyjście. + +## 1.3. Użyj kontenera do uruchomienia cowpy interaktywnie + +Możemy pójść dalej, jeśli chcemy, i uruchomić kontener interaktywnie i rozejrzeć się w środku. Ponownie robię "docker run dash dash rm". Teraz zrobię dash it, co mówi Docker, że chcemy interaktywny terminal. Ponownie robię URL obrazu, a tym razem, zamiast robić cowpy, zrobię bin bash, ponieważ polecenie, które chcemy uruchomić, to bash. + +To zabiera nas do tego działającego kontenera i możesz zobaczyć, że prompt się teraz zmienił. + +Jeśli zrobię LS slash, możesz zobaczyć, że katalogi tutaj są inne. + +Jeśli otworzę drugi terminal tutaj po prawej stronie, który po prostu działa w GitHub Code Spaces i zrobię LS slash, widzisz, że mamy katalogi takie jak workspaces i temp, podczas gdy tutaj w Docker jest inaczej. + +Więc to środowisko jest całkowicie oddzielne w Docker i odizolowane od mojego środowiska hosta. To dobra rzecz, ponieważ to izoluje wykonanie tego polecenia w obrazie Docker i utrzymuje to powtarzalne między różnymi ludźmi na różnych systemach hosta. + +Jeśli chcesz użyć danych z Twojego systemu hosta w obrazie Docker, musisz jawnie zamontować to w kontenerze. + +Za chwilę to zrobimy. + +## 1.3.2. Uruchom żądane polecenia narzędzia + +Najpierw jednak sprawdźmy, czy możemy uruchomić cowpy. Ponownie, polecenie jest teraz dostępne bezpośrednio w wierszu poleceń i możemy zacząć robić bardziej złożone rzeczy i przekazywać argumenty. Hello containers i zamiast krowy, zróbmy pingwina tux. Zobaczmy, co jeszcze mamy. + +Zróbmy cheese. Wspaniale. Co powiesz na Dragon and Cow? Całkiem dobre. + +## 1.3.3. Wyjdź z kontenera + +Dobra. Nie mogę zrobić wiele więcej, ponieważ nie mam żadnych danych w tym kontenerze. Więc wyjdźmy z tego działającego obrazu i zobaczmy, czy możemy zamontować jakieś dane w kontenerze. Mogę to zrobić robiąc control D lub wpisując exit. Dobra, jestem teraz z powrotem w moim zwykłym GitHub code space. + +## 1.3.4. Zamontuj dane w kontenerze + +Aby zamontować jakieś dane w kontenerze Docker, muszę użyć dash V. Więc wezmę moje poprzednie polecenie docker, wrócę na początek i zrobię dash v. Zrobię "." dla bieżącego lokalnego katalogu roboczego, a następnie dwukropek, aby powiedzieć, gdzie to powinno być zamontowane w katalogu hosta i zrobię slash data. Więc to montuje ten konkretny katalog w kontenerze w slash data. + +Teraz jeśli zrobię LS slash, możemy zobaczyć, że mamy nowy katalog o nazwie data, a jeśli zrobię LS data, możesz zobaczyć wszystkie pliki, które mamy na pasku bocznym tutaj. Fantastycznie. + +## 1.3.5. Użyj zamontowanych danych + +Teraz możemy zacząć używać niektórych plików, które są w systemie hosta w obrazie Docker. Więc mogę powiedzieć cat data greetings csv. Jeśli pamiętasz, to jest nasz plik CSV z naszymi różnymi powitaniami sprzed chwili, i mogę przekazać to do cowpy. Fantastycznie. Teraz gdzieś docieramy. + +Dobra. Wystarczy uruchamiania Docker interaktywnie. Mam nadzieję, że masz teraz poczucie, czym w przybliżeniu jest Docker i jak go używać zarówno do uruchamiania polecenia jednorazowo, jak i do interaktywnego używania obrazu. Jeśli używasz singularity, polecenia są wszystkie bardzo podobne, z wyjątkiem tego, że robisz rzeczy takie jak apptainer exec lub apptainer run, lub singularity exec lub singularity run. + +## 2. Użyj kontenerów w Nextflow + +Następnie wrócimy do naszego workflow Nextflow i zobaczymy, jak używać tej technologii w pipeline'ie Nextflow. + +Zamknijmy terminal i otwórzmy ponownie Hello Containers. + +## 2.1. Napisz moduł cowpy + +Aby trzymać się naszego przykładu cowpy, stwórzmy nowy proces w naszym workflow, który używa cowpy. Przejdźmy do modules, utwórzmy nowy plik i nazwijmy go cowpy nf. Teraz trochę oszukam i skopiguję kod z materiału szkoleniowego i nacisnę save. I spójrzmy. + +To prosty proces. Mam nadzieję, że teraz rozumiesz, jak wyglądają elementy składowe procesu. Mamy ponownie nasz publishDir, idący do results. Mamy dwa wejścia, plik wejściowy i ciąg znaków o nazwie character. Mamy wyjście cowpy input file i mamy skrypt, który wygląda dokładnie tak samo jak to, co uruchamialiśmy ręcznie wewnątrz naszego obrazu docker przed chwilą: cat do wydrukowania pliku, przekazując to do cowpy, mówiąc, którego typu postaci cowpy chcemy użyć, i wyprowadzając to do pliku wyjściowego, który przekazujemy jako wyjście tutaj. + +## 2.2. Dodaj cowpy do workflow + +Dobra, wróćmy do naszego workflow, zaimportujmy ten nowy proces. Więc cowpy from modules cowpy nf. Stwórzmy nowy parametr, abyśmy mogli określić, którego znaku chcemy. Powiedzmy Turkey domyślnie. A następnie wywołajmy ten nowy proces na końcu workflow, + +cowpy. I użyjmy wyjścia tutaj z Collect Greetings. Więc collect greetings out, out file tutaj. A następnie potrzebujemy drugiego argumentu, którym są nowe params, które właśnie stworzyliśmy. params dot character. + +## 2.2.4. Uruchom workflow, aby sprawdzić, czy działa + +Dobra, zobaczmy, czy nasz nowy proces działa. Nextflow run hello containers. To powinno uruchomić te pierwsze trzy procesy, a następnie spróbować uruchomić cowpy na końcu. + +Mamy błąd. To, co tutaj mówi, cowpy miało błąd i miało status wyjścia 127 i rzeczywiście, polecenie sh cowpy polecenie nie znalezione. + +Nie powiedzieliśmy Nextflow, że mamy dostępny obraz Docker dla cowpy, więc próbował uruchomić to na naszym systemie hosta, a nie mamy cowpy zainstalowanego na naszym systemie hosta, więc wywołało to błąd. + +## 2.3. Użyj kontenera, aby to uruchomić + +Więc to, co musimy zrobić, to musimy powiedzieć Nextflow, że mamy dostępny kontener. Przejdźmy do naszego procesu cowpy i dodajmy nową dyrektywę na górze procesu o nazwie container. + +Następnie znajdujemy nasz obraz, kopiujemy URL i umieszczamy to w ciągu znaków. + +To samo w sobie nie wystarcza, ponieważ pipeline X Flow może mieć kilka sposobów określania oprogramowania. Mógłbym również zrobić conda conda-forge cowpy, na przykład. I Nextflow musi wiedzieć, której z tych technologii chcesz użyć. + +## 2.3.2. Włącz użycie Docker przez plik nextflow.config + +Więc aby uruchomić z włączonym Docker, wyprzedzimy się trochę i użyjemy pliku Nextflow config, którym zajmiemy się bardziej szczegółowo w następnym rozdziale. Możesz zobaczyć w tym katalogu, że mamy plik o nazwie Nextflow Config, i tutaj już masz docker.enabled False. + +Zmienimy to na True, aby włączyć Docker, a następnie możemy spróbować ponownie uruchomić workflow. + +## 2.3.3. Uruchom workflow z włączonym Docker + +Nextflow run hello containers nf i tym razem cowpy uruchomił się pomyślnie. Spójrzmy w Results. cowpy collected test i oto nasz Turkey. Wspaniale. + +Więc w tle tam Nextflow wiedział, że ma dostępny kontener dla tego procesu. + +Pobrał obraz i uruchomił dla nas polecenia. + +## 2.3.4. Sprawdź, jak Nextflow uruchomił zadanie w kontenerze + +Jeśli jesteś ciekawy, możemy faktycznie zobaczyć dokładnie, co to zrobiło, patrząc w katalog work. Jeśli zrobię code work, a następnie hash i następnie command run, który jeśli pamiętasz, to faktyczny plik, który jest wykonywany dla tego zadania, możemy wejść i możemy poszukać funkcji o nazwie NXF launch. I tutaj możesz zobaczyć dokładne polecenie docker, którego użył Nextflow, które wygląda podobnie do tego, co robiliśmy ręcznie w terminalu wcześniej. Docker run. Wiązanie tego katalogu hosta w kontenerze, a następnie określanie URL kontenera. + +Więc nie ma tu magii. Po prostu Nextflow automatycznie robi ciężką pracę za Ciebie w sposób, który oznacza, że możesz łatwo określić kontenery w swoim pipeline'ie, które są następnie łatwo dostępne dla każdego innego, kto uruchamia Twój workflow. I ci ludzie nie muszą już myśleć o zarządzaniu oprogramowaniem, aby uruchomić Twój pipeline analizy. + +Bardzo, bardzo proste, bardzo wygodne, a także naprawdę powtarzalne. Dobre ze wszystkich stron. + +Dobra, świetna robota. To koniec rozdziału 5. Dołącz do nas w następnym filmie w części 6, która jest ostatnią częścią tego szkolenia Hello Nextflow, gdzie porozmawiamy o konfiguracji Nextflow bardziej szczegółowo. + +Do zobaczenia w następnym filmie. + +[Następna transkrypcja wideo :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/pl/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..010f5dc895 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Część 6: Hello Config - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne informacje" + + Ta strona zawiera jedynie transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów szkoleniowych](../06_hello_config.md). + + Numery sekcji pokazane w transkrypcji są podane jedynie w celach orientacyjnych i mogą nie obejmować wszystkich numerów sekcji w materiałach. + +## Powitanie + +Cześć, witajcie w szóstej części kursu szkoleniowego Hello Nextflow. + +Ten rozdział nazywa się Hello Config i jest ostatnią częścią naszego kursu szkoleniowego. + +W tym rozdziale będziemy mówić o konfiguracji Nextflow. Konfiguracja Nextflow jest naprawdę potężna. Pozwala nam uruchamiać ten sam pipeline na wielu różnych infrastrukturach obliczeniowych z różnym dostarczaniem oprogramowania i różnymi opcjami w samym pipeline. + +Oznacza to, że możecie wziąć pipeline Nextflow zbudowane przez inne osoby i uruchomić je na swoim systemie, nawet jeśli mogły być zbudowane dla zupełnie innej infrastruktury. Ta możliwość konfigurowania Nextflow sprawia, że workflow są naprawdę przenośne i możliwe do udostępniania. + +W tym rozdziale będziemy używać workflow, który zbudowaliśmy w poprzednich częściach, ale nie będziemy w ogóle edytować kodu workflow. Przyjrzymy się tylko naszemu plikowi konfiguracyjnemu Nextflow i zobaczymy, jak zmiana konfiguracji zmienia sposób działania Nextflow. + +Dobrze, zaczynajmy. + +Tak jak wcześniej, zacznijmy od przejścia do training.nextflow.io. Po lewej stronie przejdźcie do Hello Nextflow i rozdziału szóstego. Hello config. Teraz przejdę do mojego środowiska GitHub Codespaces i sprawdzę skrypt, którego będziemy używać. + +## 0. Rozgrzewka: Sprawdź, czy Docker jest włączony i uruchom workflow Hello Config + +Ten nazywa się Hello Config i zaczyna od tego miejsca, w którym byliśmy wcześniej. Wygląda więc dokładnie tak samo z naszymi trzema parametrami. Greetings dla pliku CSV, batch dla nazwy partii wyjściowej i character dla nazwy cowpy. Mamy nasze cztery importy różnych procesów, a następnie mamy workflow, w którym je łączymy. + +Faktycznie zamknę teraz ten plik, ponieważ nie będziemy w ogóle dotykać pliku Nextflow w tym rozdziale. Będziemy pracować wyłącznie w pliku konfiguracyjnym. Jeśli spojrzę do pliku Nextflow dot config, który krótko omówiliśmy w poprzednim rozdziale piątym, możemy zobaczyć, że mamy tutaj pojedynczą instrukcję: Docker enabled równa się true, która mówi Nextflow, aby używał Dockera podczas wykonywania tego workflow. + +Używam Nextflow dot config w katalogu głównym pipeline tutaj, który jest ładowany automatycznie, gdy uruchamiam Nextflow. Ale pamiętajcie, Nextflow może ładować pliki konfiguracyjne z wielu miejsc. + +Jeśli sprawdzę w dokumentacji Nextflow, przejdę do Configuration, możecie zobaczyć listę tych miejsc i priorytet, w jakim są ładowane. + +Dobrze. Sprawdźmy, czy nasze workflow wykonuje się tak, jak oczekujemy. Otworzę terminal. Robię Nextflow. Run. Hello, config. I naciskam enter. Powinniśmy mieć te cztery procesy uruchomione, kończące się poleceniem cowpy. Rzeczywiście, to zadziałało prawidłowo. Miałem włączonego Dockera, pobrał Dockera i uruchomił dla mnie cowpy, tak jak na końcu rozdziału piątego. + +## 1. Określ, jakiej technologii pakowania oprogramowania użyć + +Dobrze. Powiedzmy, że pracuję na HPC i nie mam zainstalowanego Dockera. Najlepszą rzeczą do zrobienia w tym scenariuszu byłoby użycie Singularity lub Apptainer. Gdybym miał to zrobić, wszedłbym do modułu cowpy i zmieniłbym ten kontener, aby używał obrazu singularity, jak pokazałem w poprzednim rozdziale, z oras://, który również można uzyskać z Seqera Containers. + +Następnie przeszedłbym do Nextflow dot config, ustawiłbym Docker enabled na false i zrobiłbym singularity enabled równa się true. Lub, jeśli używam Apptainer, apptainer enabled równa się true i to by zadziałało. + +Nextflow obsługuje również inne technologie oprócz kontenerów, coś, co możecie znać, to conda. Tutaj możemy zrobić conda enabled równa się true i ustawić Docker na false. conda nie używa tej samej dyrektywy container. Zamiast tego możemy dodać nową tutaj o nazwie conda. Następnie określamy pakiet conda, którego chcemy użyć. Dobrą praktyką jest bycie tak szczegółowym, jak to możliwe, aby spróbować uczynić pipeline tak powtarzalnym, jak to możliwe. Więc zamierzam określić kanał conda, conda-forge, a następnie cowpy i dokładną wersję, którą była 1.1.5. + +Mógłbym też po prostu napisać cowpy, gdybym chciał, ale mogłoby to rozwiązać się do innej wersji cowpy przy różnych wykonaniach pipeline. + +Fajną rzeczą w tym jest to, że nie dotknąłem w ogóle dyrektywy docker. Ten obraz Dockera jest nadal tam. Po prostu dostarczam teraz dwie alternatywy, a te mogą być włączane lub wyłączane tylko za pomocą pliku konfiguracyjnego. + +## 1.3. Uruchom workflow, aby zweryfikować, że może używać Conda + +Conda jest teraz włączona, więc spróbujmy. + +Świetnie. Działa i możecie zobaczyć, że jest tu komunikat od Nextflow mówiący, że Nextflow tworzy dla mnie środowisko conda i używa tej lokalizacji cache. + +W tle Nextflow uruchamia dla mnie polecenia "conda create", aby stworzyć nowe izolowane środowisko conda z tylko tymi pakietami, których chcę, a następnie instaluje i pobiera te pakiety conda, aby mogło uruchomić proces. + +Możecie zobaczyć, że zajęło to trochę czasu, ponieważ tworzyło środowisko i instalowało oprogramowanie po raz pierwszy. Jednak buforuje to środowisko, więc jeśli uruchomię to samo polecenie Nextflow ponownie, powinno być znacznie szybsze, ponieważ będzie ponownie używać tego samego środowiska conda. + +Jedną z fajnych rzeczy w tym jest to, że te dyrektywy mogą być określone na poziomie procesu, a nie tylko całego workflow. Więc jeśli chcecie, możecie mieszać i dopasowywać, jaka technologia jest używana dla różnych procesów. + +## 2. Przydziel zasoby obliczeniowe za pomocą dyrektyw procesu + +Plik konfiguracyjny Nextflow może robić znacznie więcej niż tylko pakowanie oprogramowania. Możemy również powiedzieć Nextflow, jak faktycznie uruchamiać kroki w pipeline. Jednym z przykładów jest powiedzenie systemowi hostującemu, jakie zasoby powinny być udostępnione każdemu wykonywanemu zadaniu. + +Domyślnie Nextflow nie daje zbyt wiele. Daje pojedynczy procesor CPU i tylko dwa gigabajty pamięci każdemu procesowi. + +To jest prawdopodobnie coś, co chcielibyśmy zmienić, aby procesy, które zajmują dużo czasu, mogły mieć więcej zasobów i działać szybciej, ale może być trudno wiedzieć, co przydzielić procesowi. Nextflow ma kilka fajnych trików w rękawie, aby wam w tym pomóc. + +## 2.1. Uruchom workflow, aby wygenerować raport wykorzystania zasobów + +Uruchommy workflow ponownie. Tym razem zamierzam dodać dodatkowy argument, którym jest dash with reports. To jest podstawowa opcja Nextflow, więc jest to pojedynczy łącznik. A następnie dowolna nazwa pliku. W tym przypadku zamierzam nazwać to report config one html. + +Zamierzam uruchomić workflow ponownie. Będzie działać dokładnie tak samo jak wcześniej, ale da mi dodatkowy raport pomocniczy, który możecie zobaczyć, pojawił się teraz tutaj na pasku bocznym. + +Kliknę prawym przyciskiem myszy na ten plik, kliknę download, co pobierze go z GitHub Codespaces do mojego lokalnego systemu, abym mógł łatwo obejrzeć go w przeglądarce internetowej tutaj na górze. + +Ten raport może być wygenerowany dla każdego uruchomienia Nextflow i zawiera wiele informacji. Zaczyna się na górze od metadanych o tym, jakie polecenie zostało użyte, kiedy workflow został uruchomiony, ile czasu to zajęło, ale jak przewijamy w dół, otrzymujemy bardziej szczegółowe informacje o zasobach, które zostały użyte przez każdy krok w pipeline. + +Ponieważ każdy proces uruchamia się wiele razy dla różnych zadań, mamy wykres pudełkowy pokazujący zmienność zasobów, których użyliśmy dla każdego procesu. + +Jeśli przewinę trochę dalej w dół, zobaczę podobne informacje o użytej pamięci i czasie trwania zadania. Także odczyt zapis dysku. + +Możecie sobie wyobrazić, że dla dużego pipeline z długo działającymi zadaniami może to być bardzo pouczające o tym, jak dostroić konfigurację zasobów, o które prosimy, aby nie żądać zbyt wiele, ale także aby zapewnić wystarczająco dużo, że działa szybko. + +Jeśli będę przewijać w dół raportu, zobaczymy również tabelę zadań, która pokazuje nam szczegółowe informacje o każdym pojedynczym zadaniu, które zostało uruchomione w workflow. Obejmuje to informacje takie jak rozwiązany skrypt, który został uruchomiony. + +Dobrze, wróćmy do naszego pliku konfiguracyjnego. Zobaczyliśmy, że naprawdę nie potrzebowaliśmy zbyt wiele dla naszego workflow, więc powiedzmy Nextflow, że potrzebujemy tylko jednego gigabajta pamięci dla każdego procesu w workflow. + +Teraz, gdy definiujemy to w ten sposób na poziomie procesu, jest to stosowane do każdego pojedynczego procesu w pipeline. + +## 2.3. Ustaw alokacje zasobów dla pojedynczego procesu + +Dla przykładu, udajmy, że cowpy naprawdę wykonuje dużo ciężkiej pracy i potrzebuje więcej zasobów niż inne zadania. Możemy zdefiniować dodatkowy blok konfiguracji tutaj, który stosuje się tylko do tego procesu, używając with name cowpy. + +To jest nazywane selektorem konfiguracji i możemy tutaj zdefiniować różne wzorce, aby dopasować różne procesy. Na przykład, mógłbym zrobić cow star. Następnie następuję to nawiasami klamrowymi i dajmy mu dwa gigabajty pamięci zamiast jednego i powiedzmy dwa procesory CPU. + +Teraz Nextflow będzie dawać każdemu procesowi w workflow jeden gigabajt oprócz tego żądania, które jest bardziej szczegółowe. Więc nadpisuje to. I tylko dla procesów, które nazywają się cowpy, otrzymają dwa gigabajty pamięci i dwa procesory CPU. + +Zauważcie, że Nextflow jest mądry w kwestii wykorzystania zasobów. Więc jeśli zaczniesz umieszczać te liczby na wyższych wartościach, zobaczysz, że Nextflow zaczyna kolejkować przesyłanie zadań jedno po drugim, zamiast uruchamiać je wszystkie równolegle, aby nie nadmiernie żądać dostępnych zasobów. + +## 2.4. Uruchom workflow ze zmodyfikowaną konfiguracją + +Spróbujmy uruchomić workflow ponownie i zapiszmy nowy raport tym razem. + +Dobrze, możemy pobrać ten plik i rzucić okiem. + +Tak, nic dziwnego, wygląda to zasadniczo dokładnie tak samo, ponieważ to jest fikcyjne workflow, które nic prawdziwego nie robi. Ale możecie sobie wyobrazić, jak to iteracyjne podejście do definiowania limitów i wykonywania prawdziwych workflow z tego rodzaju raportowaniem pozwala na podejście oparte na dowodach do ustalania odpowiedniej konfiguracji i naprawdę maksymalne wykorzystanie dostępnych dla was zasobów obliczeniowych. + +Możecie zacząć być naprawdę sprytni w tej kwestii. Nextflow ma wbudowaną zdolność do ponawiania prób w przypadku awarii i możecie to wykorzystać w swoim pliku konfiguracyjnym, używając domknięcia takiego jak to i dynamicznie ustawiając dostępne zasoby. Więc tutaj powiedziałem Nextflow, aby pomnożył te dwa gigabajty przez próbę ponowienia. Więc druga próba otrzyma cztery gigabajty, trzecia próba otrzyma sześć gigabajtów i tak dalej. To trochę wykracza poza zakres tego kursu szkoleniowego, ale jeśli jesteście zainteresowani, sprawdźcie dokumentację Nextflow, która ma fajną sekcję o dynamicznej logice ponownych prób. + +## 2.5. Dodaj limity zasobów + +Teraz, jedną rzeczą, którą możecie zauważyć, jest to, że tego rodzaju rzecz może ułatwić przypadkowe wyjście poza zasoby dostępne w waszym systemie. Jeśli zażądacie więcej zasobów niż jest dostępnych, Nextflow wyrzuci błąd dotyczący waszej konfiguracji i zatrzyma uruchomienie. Aby tego uniknąć, możecie użyć czegoś, co nazywa się limitami zasobów. + +Pod zakresem process w naszym workflow możemy zdefiniować limity zasobów w ten sposób, co przyjmuje tablicę, i możemy określić maksymalną pamięć, procesory CPU i czas, które są dostępne w tym systemie. + +Ustawienie tutaj wysokich wartości nie zwiększa ilości żądanych zasobów. Nadal będziemy używać jednego gigabajta w naszych żądaniach, ale oznacza to, że jeśli którekolwiek z tych żądań osiągnie 750, osiągną ten pułap i nic więcej nie będzie żądane, co oznacza, że Nextflow będzie kontynuować działanie i nie zawiesi się z powodu niedostępnych zasobów. + +Więc to jest fajne zabezpieczenie do użycia, szczególnie jeśli używacie dynamicznej logiki z waszą alokacją zasobów. + +Druga sytuacja, w której jest to naprawdę użyteczne, jest wtedy, gdy używacie pipeline, które są publiczne i nie są kontrolowane przez was. Mogą pochodzić z domyślnymi konfiguracjami, a Nextflow automatycznie przyjmie właściwe podejście do ograniczenia wszelkich żądań zasobów, aby działać na waszym systemie. + +Dobrze, świetnie. Mówiliśmy o oprogramowaniu. Mówiliśmy o alokacji zasobów i opisaliśmy różne zakresy konfiguracji, zarówno dla wszystkich procesów, jak i konkretnych procesów. + +## 3. Użyj pliku parametrów do przechowywania parametrów workflow + +Dobrze, następnie zwrócimy naszą uwagę na parametry. Możemy zdefiniować parametry w pliku konfiguracyjnym tak samo, jak zrobiliśmy to wcześniej w skrypcie Nextflow. Więc params dot greeting równa się hello lub użyj zakresu params i ustaw foo równa się bar. + +I to świetnie nadaje się do ustawiania wartości domyślnych dla waszego workflow. Jednak podczas uruchamiania pipeline może być miło określić parametry w pliku JSON lub YAML. + +Używanie takiego pliku jest znacznie lepsze niż określanie opcji linii poleceń z dash dash. Ponieważ podczas uruchamiania workflow możecie musieć określić wiele parametrów i może być żmudne, aby je wszystkie napisać w jednym CLI i podatne na błędy. Ponadto jest mało prawdopodobne, że zapamiętacie wszystkie parametry, których użyliście, więc jeśli zakodujecie to w pliku, łatwiej jest uruchomić workflow ponownie, używając tych samych parametrów w przyszłości. + +Mamy tutaj przykładowy plik o nazwie test params i możecie zobaczyć, że określa to trzy parametry, które mamy w naszym workflow z trzema różnymi wartościami. Osobiście uważam, że YAML jest łatwiejszy do pisania niż JSON. Więc tylko po to, aby zademonstrować, że to działa, zamierzam utworzyć nowy plik o nazwie Test yaml i skopiować je, pozbyć się cudzysłowów. I nacisnąć zapisz. + +Te pliki JSON i YAML mogą być łatwiejsze do pisania, ponieważ są bardziej znaną składnią. Ale zauważcie, że są one tylko dla parametrów i przyjmują tylko składnię klucz-wartość taką jak ta. + +## 3.1. Uruchom workflow używając pliku parametrów + +Spróbujmy. Zrobię to samo polecenie co wcześniej. Pozbędę się raportu i zamierzam zrobić dash params file test params yaml. + +Nie, to jest podstawowa opcja Nextflow, więc jest to pojedynczy łącznik. + +Dobrze. Uruchomiło workflow i użyło parametrów z tego pliku YAML zamiast określania ich wszystkich w linii poleceń. Może wydawać się to przesadą tylko dla tego prostego przykładu, ale możecie sobie wyobrazić, że jeśli macie 10 lub 20 różnych parametrów, może być uciążliwe wpisywanie ręcznie, a to jest po prostu znacznie łatwiejsze do edycji w edytorze kodu i przechowywania ze względu na powtarzalność. + +## 3. Określ, jaki(e) executor(y) powinny być użyte do wykonania pracy + +Dobrze. Mówiliśmy o pakowaniu oprogramowania z Docker i conda. Mówiliśmy o wymaganiach zasobów procesu z procesorami CPU i pamięcią. I mówiliśmy trochę o tym, jak określić parametry podczas uruchamiania workflow. + +Końcowe części konfiguracji to naprawdę wykonanie, sama podstawowa infrastruktura obliczeniowa, i to jest prawdziwy klejnot w koronie Nextflow: to, że możemy uruchamiać te same workflow na wielu różnych infrastrukturach obliczeniowych. + +Faktycznie zamierzam przełączyć się na pisemny materiał szkoleniowy przez sekundę. W tej części szkolenia możemy zobaczyć kilka różnych przykładów tego, jak różne executors, w tym przypadku harmonogramy HPC, definiują wymagania zasobów potrzebne do przesłania zadania. + +Więc dla Slurm macie te nagłówki SBATCH, które definiują dash dash mem i numer CPU. Jeśli używacie PBS, macie różne nagłówki, a jeśli używacie Grid Engine, macie znowu różne nagłówki. + +Możecie sobie wyobrazić, że jest jeszcze bardziej różnie, jeśli chcecie uruchomić w chmurze, czy to AWS batch, Google Cloud, Azure czy więcej. + +Każda z tych podstawowych infrastruktur obliczeniowych nazywana jest executor i Nextflow wie, jak rozmawiać ze wszystkimi tymi różnymi executors, aby przesłać zadania z poprawną składnią. + +Dobra wiadomość jest taka, że nie musicie o tym wiedzieć. Wszystko, co musicie zrobić, to powiedzieć Nextflow, którego executor użyć. + +## 3.1. Targetowanie innego backendu + +Wracamy do naszego pliku konfiguracyjnego i procesu robimy executor, i zamierzam wpisać local. + +Local jest faktycznie domyślny, jeśli nie określicie żadnego innego executor, local jest tym, co będzie używane, a to po prostu oznacza wasz system hostujący, gdziekolwiek uruchomiliście Nextflow, + +Mógłbym określić zamiast tego Slurm. I to przesłałoby zadania Slurm, lub mógłbym powiedzieć AWS batch, i to przesłałoby zadania do AWS batch. + +W niektórych przypadkach potrzebujecie dodatkowej konfiguracji, na przykład uruchamianie w chmurze będzie wymagać pewnych poświadczeń, ale naprawdę to jest rdzeń tego, i może to być tak proste jak jedna lub dwie linie konfiguracji, aby uruchomić waszą workflow w zupełnie innym środowisku obliczeniowym. + +Mimo że działamy na prostym systemie w Codespaces, nadal mogę trochę się z tym pobawić i udawać, że działamy na Slurm. Jeśli następnie uruchomię workflow ponownie, Nextflow run, hello config. To się nie powiedzie, ponieważ nie będzie mogło przesłać zadań do Slurm. Ale nadal możemy wejść do katalogów work i zobaczyć, co Nextflow zrobiło. Więc jeśli przejdziemy do tego katalogu work i spojrzymy na Command Run. Możecie zobaczyć na górze tego pliku, że mamy teraz te linie nagłówka sbatch, które próbowały określić zasoby potrzebne dla zadania Slurm. + +## 4. Użyj profili do wyboru wstępnie ustawionych konfiguracji + +Dobrze, prawie jesteśmy na miejscu. Ostatnia część tego rozdziału to mówienie o profilach konfiguracyjnych. Jeśli uruchamiacie swój pipeline na kilku różnych systemach, mogłoby być irytujące mieć wszystkie te różne pliki konfiguracyjne Nextflow, które musicie określać za każdym razem. + +Zamiast tego możecie zakodować grupowania konfiguracji w waszym pliku konfiguracyjnym Nextflow i włączać i wyłączać te grupy, używając flagi profile. Zobaczmy, jak to wygląda. + +## 4.1. Utwórz profile do przełączania między lokalnym rozwojem a wykonaniem na HPC + +Zamierzamy utworzyć dwa profile w naszym przykładzie tutaj, jeden dla mojego laptopa i jeden dla cięższego systemu HPC. Zamierzam trochę oszukać i po prostu skopiować kod z materiału szkoleniowego i umieścić go tutaj. + +Mamy nowy zakres o nazwie profiles, a następnie mamy nazwę dla każdego profilu, która może być dowolna. I w tym mamy konfigurację, która wygląda dokładnie tak samo jak konfiguracja najwyższego poziomu, którą już napisaliśmy. Więc znowu mamy zakres process. Zakres Docker. + +W profilu o nazwie my laptop mówię, aby uruchomić używając executor local, więc na moim systemie hostującym i aby używać Dockera. + +W profilu university HPC tutaj mówię, aby używać Slurm do przesyłania zadań, aby używać conda zamiast Dockera, i określam różne limity zasobów, które mogą pasować do rozmiaru systemu węzłów na HPC, którego używam. + +Domyślnie żadna z tej konfiguracji nie będzie używana, gdy uruchomię Nextflow, muszę określić, że chcę użyć jednego z tych profili. + +## 4.2. Uruchom workflow z profilem + +Zróbmy nextflow run hello config. I zamierzam zrobić dash profile, pojedynczy łącznik, ponieważ to jest podstawowa opcja Nextflow. A następnie nazwa, którą mu nadałem, którą jest my laptop. Nextflow powinien teraz użyć bloku konfiguracji, który został określony w tym profilu konfiguracyjnym i zastosować go podczas uruchamiania Nextflow. Gdybym chciał użyć drugiego bloku konfiguracji, musiałbym tylko przełączyć tę nazwę profilu. Znacznie łatwiejsze do zapamiętania. Znacznie łatwiejsze w użyciu. + +## 4.3. Utwórz profil testowy + +Zauważcie, profile mogą mieć dowolny rodzaj konfiguracji, więc nie musi to być związane z waszym środowiskiem wykonawczym. Na przykład, stwórzmy tutaj nowy profil, który ma zestaw parametrów. Możemy zmienić to na tux i zmienić na my profile, a teraz gdy zrobimy profile test, to określi te parametry, które nadpiszą parametry, które są określone na najwyższym poziomie workflow. + +Kiedy uruchamiacie Nextflow, możecie połączyć wiele profili i będą one stosowane kolejno. + +## 4.4. Uruchom workflow lokalnie z profilem testowym + +Więc mogę wziąć poprzednie polecenie i zrobić przecinek test. To zastosuje konfigurację my laptop najpierw, a następnie zastosuje konfigurację test. Jeśli jest jakiekolwiek nakładanie się, to profil po prawej nadpisze wszelką konfigurację w poprzednich profilach. Jeśli nacisnę enter, zobaczmy, co się stanie. + +Dobrze, mamy tutaj nowy plik wyników. Możecie zobaczyć My Profile, który określiłem jako jedną z opcji. I możemy również zobaczyć cowpy, my profile, i rzeczywiście, jest tux. Więc to zadziałało. + +## Podsumowanie + +Dobrze! Niesamowite. To wszystko. Dotarliście do końca kursu. Dostajecie trochę konfetti celebracyjnego. Brawo za ukończenie tego rozdziału. + +[Transkrypcja następnego filmu :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/pl/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/pl/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..736cd92041 --- /dev/null +++ b/docs/pl/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Następne Kroki - Transkrypcja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Ważne uwagi" + + Ta strona zawiera tylko transkrypcję. Aby uzyskać pełne instrukcje krok po kroku, wróć do [materiałów kursu](../05_hello_containers.md). + +## Powitanie + +Gratulacje, udało się. Ukończyłeś pierwszy kurs szkoleniowy Nextflow, nazwany Hello Nextflow + +świetna robota. Dziękujemy za wytrwałość i naprawdę doceniamy czas i wysiłek, który włożyłeś w naukę Nextflow. Mamy nadzieję, że będzie to przydatne w Twojej pracy. + +## Następne Kroki + +Jeśli chodzi o kolejne kroki, śledź portal szkoleniowy: training.nextflow.io. Cały czas dodajemy tam nowe materiały szkoleniowe i je odświeżamy. Możesz tam znaleźć bardziej zaawansowane szkolenie lub szkolenie specyficzne dla dziedziny badań, która Cię interesuje. + +W szczególności sprawdź stronę Nextflow for Science. Zawiera ona serię krótkich kursów, które są samodzielne i rozszerzają to, czego nauczyłeś się w Hello Nextflow, na konkretne przypadki użycia. + +Jest jeden dla Genomiki, a także jeden dla RNA-seq. Mamy nadzieję wkrótce dodać więcej. + +## Side Quests + +Jest wiele rzeczy, o których mogliśmy porozmawiać w Hello Nextflow, ale byłoby to zbyt szczegółowe. Część z tych rzeczy umieszczamy w Side Quests, które są krótkimi kursami na konkretne tematy. + +Dostępne są również większe kursy fundamentals training i advanced training, które mogą zawierać treści, które uznasz za interesujące. + +## nf-core + +Było to wspomniane raz lub dwa razy w tym kursie, ale zdecydowanie sprawdź projekt nf-core. Jest tam ponad sto pipeline'ów dla różnych typów danych, więc całkiem możliwe, że nie będziesz musiał budować własnego pipeline'a. + +Jest tam również prawie półtora tysiąca modułów process, gdzie jeśli używasz narzędzi deweloperskich nf-core, możesz stworzyć pipeline i zaimportować te moduły w ciągu kilku sekund. + +## Seqera Platform + +Na koniec, krótka wzmianka o Seqera Platform. To bez wątpienia najlepszy sposób na uruchamianie Nextflow w praktyce, jest to platforma oparta na chmurze, ale podłączasz własną infrastrukturę obliczeniową, czy to własne konto w chmurze na AWS, Google Batch czy Azure, czy nawet własny HPC. Warstwa bezpłatna jest dostępna dla wszystkich, a jeśli jesteś pracownikiem naukowym, możesz ubiegać się o nasz program akademicki, aby uzyskać bezpłatny dostęp na poziomie pro. + +Seqera Platform wykracza poza zwykły interfejs graficzny do uruchamiania i monitorowania workflow'ów. Dostępne są również dodatkowe narzędzia, takie jak Data Studios do uruchamiania sesji interaktywnych, oraz fundamentalne narzędzia takie jak Fusion, które zapewniają szybszy i tańszy dostęp do danych w chmurze. + +## Wsparcie i wydarzenia + +Pamiętaj, jeśli kiedykolwiek napotkasz jakieś problemy, po prostu przejdź do community.seqera.io. Nasze forum jest naprawdę aktywne, społeczność Nextflow jest bardzo silna i prawie zawsze są tam ludzie gotowi pomóc, czy to w sprawie szkolenia, czy czegokolwiek związanego z codziennym korzystaniem z Nextflow. + +I oczywiście, świetnym kolejnym krokiem jest dołączenie do jednego z naszych wydarzeń społeczności, czy to hackathonu nf-core, czy jednego z wydarzeń Nextflow Summit. To świetna zabawa i miło byłoby spotkać Cię tam i porozmawiać o tym, do czego używasz Nextflow. + +## Podziękowania + +Chciałbym bardzo podziękować wszystkim, którzy byli zaangażowani w pisanie tego materiału szkoleniowego. Ja go prezentuję, ale naprawdę cała ciężka praca została wykonana przez zespół szkoleniowy w Seqera. W szczególności Geraldine, która włożyła ogromną ilość pracy w przepisanie tego materiału. + +Również Marcel, Ken, Adam, John, inni z zespołu rozwoju naukowego i inni w społeczności. + +## Ankieta zwrotna + +Teraz, gdy ukończyłeś kurs, chcielibyśmy wiedzieć, co o nim sądzisz. Na training.nextflow.io znajdziesz ankietę zwrotną pod sekcją Hello Nextflow. + +Jest tylko cztery pytania, ale jest to dla nas naprawdę ważne. Jeśli nic innego, mówi nam to mniej więcej, ile osób odbywa szkolenie. Mówi nam również, czy Ci się podobało i jeśli masz jakieś sugestie, proszę zostaw je na końcu. Czytamy każde zgłoszenie. + +Jeśli zauważysz jakieś błędy, wszystko jest open source na GitHub, więc możesz utworzyć issue lub pull request, lub wysłać nam wiadomość na forum. Chcielibyśmy usłyszeć, co o tym sądzisz i jak moglibyśmy to ulepszyć. Jeszcze raz dziękujemy. Mamy nadzieję wkrótce się zobaczyć. diff --git a/docs/pl/docs/hello_nf-core/00_orientation.md b/docs/pl/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..4280f92d83 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Wprowadzenie + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Uruchomienie środowiska szkoleniowego + +Aby skorzystać z przygotowanego przez nas środowiska w GitHub Codespaces, kliknij przycisk "Open in GitHub Codespaces" poniżej. Aby poznać inne opcje, zobacz [Opcje środowiska](../envsetup/index.md). + +Zalecamy otwarcie środowiska szkoleniowego w nowej karcie lub oknie przeglądarki (użyj kliknięcia prawym przyciskiem myszy, ctrl+kliknięcie lub cmd+kliknięcie w zależności od sprzętu), aby móc czytać instrukcje podczas ładowania środowiska. +Musisz zachować te instrukcje otwarte równolegle, aby przejść przez kurs. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Podstawy środowiska + +To środowisko szkoleniowe zawiera wszystkie oprogramowanie, kod i dane niezbędne do przejścia przez kurs szkoleniowy, więc nie musisz niczego samodzielnie instalować. + +Codespace jest skonfigurowany z interfejsem VSCode, który zawiera eksplorator systemu plików, edytor kodu i powłokę terminala. +Wszystkie instrukcje podane podczas kursu (np. „otwórz plik", „edytuj kod" lub „uruchom to polecenie") odnoszą się do tych trzech części interfejsu VSCode, chyba że określono inaczej. + +Jeśli przechodzisz przez ten kurs samodzielnie, zapoznaj się z [podstawami środowiska](../envsetup/01_setup.md), aby uzyskać więcej szczegółów. + +### Wymagania dotyczące wersji + +To szkolenie jest przeznaczone dla **Nextflow 25.10.2** lub nowszego **z WYŁĄCZONYM parserem składni v2**. + +#### Jeśli korzystasz z naszego środowiska szkoleniowego: + +MUSISZ uruchomić następujące polecenie przed kontynuowaniem: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Jeśli korzystasz ze środowiska lokalnego lub niestandardowego: + +Upewnij się, że używasz prawidłowych ustawień zgodnie z dokumentacją [tutaj](../info/nxf_versions.md). + +Szkolenie dodatkowo wymaga **nf-core tools 3.4.1**. +Jeśli używasz innej wersji narzędzi nf-core, możesz mieć trudności z podążaniem za kursem. + +Możesz sprawdzić, jaka wersja jest zainstalowana w Twoim środowisku za pomocą polecenia `nf-core --version`. + +## Przygotowanie do pracy + +Gdy Twój codespace już działa, musisz wykonać dwie rzeczy przed rozpoczęciem szkolenia: ustawić katalog roboczy dla tego konkretnego kursu i przyjrzeć się dostarczonym materiałom. + +### Ustawienie katalogu roboczego + +Domyślnie codespace otwiera się z katalogiem roboczym ustawionym w katalogu głównym wszystkich kursów szkoleniowych, ale w tym kursie będziemy pracować w katalogu `hello-nf-core/`. + +Zmień teraz katalog, uruchamiając to polecenie w terminalu: + +```bash +cd hello-nf-core/ +``` + +!!! tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu wyjdziesz z tego katalogu (np. Twój codespace przejdzie w stan uśpienia), zawsze możesz użyć pełnej ścieżki, aby do niego powrócić, zakładając, że pracujesz w środowisku szkoleniowym Github Codespaces: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Teraz przyjrzyjmy się zawartości tego katalogu. + +### Eksploracja dostarczonych materiałów + +Możesz przeglądać zawartość tego katalogu używając eksploratora plików po lewej stronie obszaru roboczego szkolenia. +Alternatywnie możesz użyć polecenia `tree`. + +W trakcie kursu używamy wyjścia `tree` do przedstawienia struktury katalogów i zawartości w czytelnej formie, czasami z drobnymi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu w dół: + +```bash +tree . -L 2 +``` + +??? abstract "Zawartość katalogu" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Kliknij na kolorowe pole, aby rozwinąć sekcję i wyświetlić jej zawartość. +Używamy zwijanych sekcji w ten sposób, aby w zwięzły sposób uwzględnić oczekiwane wyjście poleceń. + +- **Plik `greetings.csv`** to plik CSV zawierający minimalne dane kolumnowe, których używamy do celów testowych. + +- **Katalog `original-hello`** zawiera kopię kodu źródłowego powstałego w wyniku przejścia przez kompletną serię szkoleń Hello Nextflow (z włączonym Docker). + +- **Katalog `solutions`** zawiera ukończone skrypty workflow powstałe w wyniku każdego kroku kursu. + Są one przeznaczone do użycia jako punkt odniesienia do sprawdzenia Twojej pracy i rozwiązywania problemów. + +## Lista gotowości + +Myślisz, że jesteś gotowy, aby zacząć? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Moje środowisko jest uruchomione i działa +- [ ] Upewniłem się, że parser składni jest ustawiony na **v1** +- [ ] Ustawiłem odpowiednio mój katalog roboczy + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +**Aby przejść do Części 1, kliknij strzałkę w prawym dolnym rogu tej strony.** diff --git a/docs/pl/docs/hello_nf-core/01_run_demo.md b/docs/pl/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..9ce7c5995f --- /dev/null +++ b/docs/pl/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# Część 1: Uruchomienie demonstracyjnego pipeline'a + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej pierwszej części szkolenia Hello nf-core pokażemy Ci, jak znaleźć i wypróbować pipeline nf-core, zrozumieć, jak kod jest zorganizowany, oraz rozpoznać, czym różni się on od zwykłego kodu Nextflow przedstawionego w [Hello Nextflow](../hello_nextflow/index.md). + +Będziemy używać pipeline'a o nazwie nf-core/demo, który jest utrzymywany przez projekt nf-core jako część jego inwentarza pipeline'ów służących do demonstracji struktury kodu i operacji narzędzi. + +Upewnij się, że Twój katalog roboczy jest ustawiony na `hello-nf-core/`, jak wskazano na stronie [Pierwsze kroki](./00_orientation.md). + +--- + +## 1. Znajdź i pobierz pipeline nf-core/demo + +Zacznijmy od zlokalizowania pipeline'a nf-core/demo na stronie projektu pod adresem [nf-co.re](https://nf-co.re), która centralizuje wszystkie informacje takie jak: ogólna dokumentacja i artykuły pomocy, dokumentacja dla każdego z pipeline'ów, wpisy na blogu, ogłoszenia wydarzeń i tak dalej. + +### 1.1. Znajdź pipeline na stronie internetowej + +W przeglądarce internetowej przejdź do [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) i wpisz `demo` w pasku wyszukiwania. + +![wyniki wyszukiwania](./img/search-results.png) + +Kliknij nazwę pipeline'a, `demo`, aby uzyskać dostęp do strony dokumentacji pipeline'a. + +Każdy wydany pipeline ma dedykowaną stronę, która zawiera następujące sekcje dokumentacji: + +- **Introduction:** Wprowadzenie i przegląd pipeline'a +- **Usage:** Opisy sposobu wykonywania pipeline'a +- **Parameters:** Zgrupowane parametry pipeline'a z opisami +- **Output:** Opisy i przykłady oczekiwanych plików wyjściowych +- **Results:** Przykładowe pliki wyjściowe wygenerowane z pełnego zestawu danych testowych +- **Releases & Statistics:** Historia wersji pipeline'a i statystyki + +Za każdym razem, gdy rozważasz przyjęcie nowego pipeline'a, powinieneś najpierw uważnie przeczytać dokumentację pipeline'a, aby zrozumieć, co robi i jak powinien być skonfigurowany przed próbą jego uruchomienia. + +Spójrz teraz i zobacz, czy możesz dowiedzieć się: + +- Które narzędzia uruchomi pipeline (Sprawdź zakładkę: `Introduction`) +- Które wejścia i parametry pipeline akceptuje lub wymaga (Sprawdź zakładkę: `Parameters`) +- Jakie są wyjścia produkowane przez pipeline (Sprawdź zakładkę: `Output`) + +#### 1.1.1. Przegląd pipeline'a + +Zakładka `Introduction` dostarcza przegląd pipeline'a, w tym wizualną reprezentację (zwaną mapą metra) i listę narzędzi, które są uruchamiane jako część pipeline'a. + +![mapa metra pipeline'a](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Przykładowa linia poleceń + +Dokumentacja dostarcza również przykładowy plik wejściowy (omówiony dokładniej poniżej) i przykładową linię poleceń. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Zauważysz, że przykładowe polecenie NIE określa pliku workflow, tylko referencję do repozytorium pipeline'a, `nf-core/demo`. + +Gdy jest wywoływany w ten sposób, Nextflow zakłada, że kod jest zorganizowany w określony sposób. +Pobierzmy kod, abyśmy mogli zbadać tę strukturę. + +### 1.2. Pobierz kod pipeline'a + +Gdy ustaliliśmy już, że pipeline wydaje się być odpowiedni dla naszych celów, wypróbujmy go. +Na szczęście Nextflow ułatwia pobieranie pipeline'ów z poprawnie sformatowanych repozytoriów bez konieczności ręcznego pobierania czegokolwiek. + +Wróćmy do terminala i uruchommy następujące polecenie: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Wyjście polecenia" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow wykonuje `pull` kodu pipeline'a, co oznacza, że pobiera całe repozytorium na Twój dysk lokalny. + +Wyjaśnijmy, że możesz to zrobić z każdym pipeline'em Nextflow, który jest odpowiednio ustawiony w GitHub, nie tylko z pipeline'ami nf-core. +Jednak nf-core to największa otwarta kolekcja pipeline'ów Nextflow. + +Możesz uzyskać od Nextflow listę pipeline'ów, które pobrałeś w ten sposób: + +```bash +nextflow list +``` + +??? success "Wyjście polecenia" + + ```console + nf-core/demo + ``` + +Zauważysz, że pliki nie znajdują się w Twoim bieżącym katalogu roboczym. +Domyślnie Nextflow zapisuje je w `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Zawartość katalogu" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + Pełna ścieżka może się różnić w Twoim systemie, jeśli nie używasz naszego środowiska szkoleniowego. + +Nextflow celowo trzyma pobrany kod źródłowy 'z dala od drogi' w oparciu o zasadę, że te pipeline'y powinny być używane bardziej jak biblioteki niż kod, z którym bezpośrednio współdziałasz. + +Jednak dla celów tego szkolenia chcemy móc zagłębiać się i zobaczyć, co tam jest. +Więc aby to ułatwić, stwórzmy dowiązanie symboliczne do tej lokalizacji z naszego bieżącego katalogu roboczego. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +To tworzy skrót, który ułatwia eksplorację kodu, który właśnie pobraliśmy. + +```bash +tree -L 2 pipelines +``` + +```console title="Zawartość katalogu" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Teraz możemy łatwiej zajrzeć do kodu źródłowego w razie potrzeby. + +Ale najpierw spróbujmy uruchomić nasz pierwszy pipeline nf-core! + +### Podsumowanie + +Teraz wiesz, jak znaleźć pipeline za pośrednictwem strony nf-core i pobrać lokalną kopię kodu źródłowego. + +### Co dalej? + +Dowiedz się, jak wypróbować pipeline nf-core przy minimalnym wysiłku. + +--- + +## 2. Wypróbuj pipeline z jego profilem testowym + +Wygodnie, każdy pipeline nf-core jest dostarczany z profilem testowym. +Jest to minimalny zestaw ustawień konfiguracyjnych dla pipeline'a do uruchomienia z użyciem małego zestawu danych testowych hostowanego w repozytorium [nf-core/test-datasets](https://github.com/nf-core/test-datasets). +To świetny sposób, aby szybko wypróbować pipeline na małą skalę. + +!!! note + + System profili konfiguracyjnych Nextflow pozwala łatwo przełączać się między różnymi silnikami kontenerów lub środowiskami wykonawczymi. + Aby uzyskać więcej szczegółów, zobacz [Hello Nextflow Część 6: Konfiguracja](../hello_nextflow/06_hello_config.md). + +### 2.1. Zbadaj profil testowy + +Dobrą praktyką jest sprawdzenie, co określa profil testowy pipeline'a przed jego uruchomieniem. +Profil `test` dla `nf-core/demo` znajduje się w pliku konfiguracyjnym `conf/test.config` i jest pokazany poniżej. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Plik konfiguracyjny Nextflow do uruchamiania minimalnych testów +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Definiuje pliki wejściowe i wszystko, co jest wymagane do uruchomienia szybkiego i prostego testu pipeline'a. + + Użyj w następujący sposób: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dane wejściowe + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Od razu zauważysz, że blok komentarza na górze zawiera przykład użycia pokazujący, jak uruchomić pipeline z tym profilem testowym. + +```groovy title="conf/test.config" linenums="7" +Użyj w następujący sposób: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Jedyne rzeczy, które musimy dostarczyć, to to, co jest pokazane między nawiasami kątowymi w przykładowym poleceniu: `<docker/singularity>` i `<OUTDIR>`. + +Przypominając, `<docker/singularity>` odnosi się do wyboru systemu kontenerów. Wszystkie pipeline'y nf-core są zaprojektowane tak, aby były użyteczne z kontenerami (Docker, Singularity, itp.) w celu zapewnienia powtarzalności i eliminacji problemów z instalacją oprogramowania. +Więc będziemy musieli określić, czy chcemy użyć Docker czy Singularity do testowania pipeline'a. + +Część `--outdir <OUTDIR>` odnosi się do katalogu, w którym Nextflow zapisze wyjścia pipeline'a. +Musimy podać dla niego nazwę, którą możemy po prostu wymyślić. +Jeśli nie istnieje już, Nextflow utworzy go dla nas w czasie wykonywania. + +Przechodząc do sekcji po bloku komentarza, profil testowy pokazuje nam, co zostało wstępnie skonfigurowane do testowania: przede wszystkim parametr `input` jest już ustawiony tak, aby wskazywał na zestaw danych testowych, więc nie musimy dostarczać własnych danych. +Jeśli podążysz za linkiem do wstępnie skonfigurowanego wejścia, zobaczysz, że jest to plik csv zawierający identyfikatory próbek i ścieżki plików dla kilku próbek eksperymentalnych. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Nazywa się to samplesheet i jest to najczęstsza forma wejścia do pipeline'ów nf-core. + +!!! note + + Nie martw się, jeśli nie jesteś zaznajomiony z formatami i typami danych, nie jest to ważne dla tego, co następuje. + +Więc potwierdza to, że mamy wszystko, czego potrzebujemy, aby wypróbować pipeline. + +### 2.2. Uruchom pipeline + +Zdecydujmy się użyć Docker dla systemu kontenerów i `demo-results` jako katalogu wyjściowego, i jesteśmy gotowi do uruchomienia polecenia testowego: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Jeśli Twoje wyjście pasuje do tego, gratulacje! Właśnie uruchomiłeś swój pierwszy pipeline nf-core. + +Zauważysz, że jest znacznie więcej wyjścia konsoli niż podczas uruchamiania podstawowego pipeline'a Nextflow. +Jest nagłówek, który zawiera podsumowanie wersji pipeline'a, wejść i wyjść oraz kilka elementów konfiguracji. + +!!! note + + Twoje wyjście pokaże różne znaczniki czasu, nazwy wykonań i ścieżki plików, ale ogólna struktura i wykonanie procesów powinny być podobne. + +Przechodząc do wyjścia wykonania, spójrzmy na linie, które mówią nam, jakie procesy zostały uruchomione: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +To mówi nam, że zostały uruchomione trzy procesy, odpowiadające trzem narzędziom pokazanym na stronie dokumentacji pipeline'a na stronie nf-core: FASTQC, SEQTK_TRIM i MULTIQC. + +Pełne nazwy procesów, jak pokazano tutaj, takie jak `NFCORE_DEMO:DEMO:MULTIQC`, są dłuższe niż to, co mogłeś zobaczyć w wstępnym materiale Hello Nextflow. +Zawierają one nazwy ich workflow nadrzędnych i odzwierciedlają modularność kodu pipeline'a. +Zajmiemy się tym bardziej szczegółowo za chwilę. + +### 2.3. Zbadaj wyjścia pipeline'a + +Na koniec spójrzmy na katalog `demo-results` wyprodukowany przez pipeline. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Zawartość katalogu" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +To może wydawać się dużo. +Aby dowiedzieć się więcej o wyjściach pipeline'a `nf-core/demo`, sprawdź jego [stronę dokumentacji](https://nf-co.re/demo/1.0.2/docs/output/). + +Na tym etapie ważne jest zaobserwowanie, że wyniki są zorganizowane według modułu, a dodatkowo istnieje katalog o nazwie `pipeline_info` zawierający różne raporty z datami dotyczące wykonania pipeline'a. + +Na przykład plik `execution_timeline_*` pokazuje, jakie procesy zostały uruchomione, w jakiej kolejności i jak długo trwało ich uruchomienie: + +![raport osi czasu wykonania](./img/execution_timeline.png) + +!!! note + + Tutaj zadania nie zostały uruchomione równolegle, ponieważ działamy na minimalistycznej maszynie w Github Codespaces. + Aby zobaczyć ich równoległe uruchomienie, spróbuj zwiększyć alokację CPU swojego codespace i limity zasobów w konfiguracji testowej. + +Te raporty są generowane automatycznie dla wszystkich pipeline'ów nf-core. + +### Podsumowanie + +Wiesz, jak uruchomić pipeline nf-core używając jego wbudowanego profilu testowego i gdzie znaleźć jego wyjścia. + +### Co dalej? + +Dowiedz się, jak kod pipeline'a jest zorganizowany. + +--- + +## 3. Zbadaj strukturę kodu pipeline'a + +Teraz, gdy pomyślnie uruchomiliśmy pipeline jako użytkownicy, zmieńmy naszą perspektywę, aby przyjrzeć się, jak pipeline'y nf-core są wewnętrznie ustrukturyzowane. + +Projekt nf-core egzekwuje silne wytyczne dotyczące tego, jak pipeline'y są ustrukturyzowane oraz jak kod jest zorganizowany, skonfigurowany i udokumentowany. +Zrozumienie, jak to wszystko jest zorganizowane, jest pierwszym krokiem w kierunku tworzenia własnych pipeline'ów kompatybilnych z nf-core, co podejmiemy w Części 2 tego kursu. + +Spójrzmy, jak kod pipeline'a jest zorganizowany w repozytorium `nf-core/demo`, używając dowiązania symbolicznego `pipelines`, które utworzyliśmy wcześniej. + +Możesz użyć `tree` lub użyć eksploratora plików, aby znaleźć i otworzyć katalog `nf-core/demo`. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Zawartość katalogu" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Dzieje się tam dużo, więc zajmiemy się tym krok po kroku. + +Po pierwsze, zauważmy, że na najwyższym poziomie możesz znaleźć plik README z informacjami podsumowującymi, a także pliki akcesoriów, które podsumowują informacje o projekcie, takie jak licencjonowanie, wytyczne dotyczące wkładu, cytowania i kodeks postępowania. +Szczegółowa dokumentacja pipeline'a znajduje się w katalogu `docs`. +Cała ta zawartość jest używana do programowego generowania stron internetowych na stronie nf-core, więc są one zawsze aktualne z kodem. + +Teraz, co do reszty, podzielimy naszą eksplorację na trzy etapy: + +1. Komponenty kodu pipeline'a (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Konfiguracja pipeline'a +3. Wejścia i walidacja + +Zacznijmy od komponentów kodu pipeline'a. +Skoncentrujemy się na hierarchii plików i organizacji strukturalnej, zamiast zagłębiać się w kod w poszczególnych plikach. + +### 3.1. Komponenty kodu pipeline'a + +Standardowa organizacja kodu pipeline'a nf-core podąża za modularną strukturą, która jest zaprojektowana tak, aby maksymalizować ponowne użycie kodu, jak wprowadzono w [Hello Modules](../hello_nextflow/04_hello_modules.md), Części 4 kursu [Hello Nextflow](../hello_nextflow/index.md), chociaż w prawdziwie nf-core'owym stylu, jest to zaimplementowane z odrobiną dodatkowej złożoności. +Konkretnie, pipeline'y nf-core obficie wykorzystują subworkflows, tj. skrypty workflow, które są importowane przez workflow nadrzędny. + +To może brzmieć trochę abstrakcyjnie, więc spójrzmy, jak jest to używane w praktyce w pipeline'ie `nf-core/demo`. + +!!! note + + Nie przejdziemy przez faktyczny kod dla _sposobu_, w jaki te komponenty modułowe są połączone, ponieważ istnieje pewna dodatkowa złożoność związana z użyciem subworkflows, która może być myląca, a zrozumienie tego nie jest konieczne na tym etapie szkolenia. + Na razie skoncentrujemy się na ogólnej organizacji i logice. + +#### 3.1.1. Ogólny przegląd + +Oto jak wyglądają relacje między odpowiednimi komponentami kodu dla pipeline'a `nf-core/demo`: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +Istnieje tak zwany skrypt _entrypoint_ o nazwie `main.nf`, który działa jako wrapper dla dwóch rodzajów zagnieżdżonych workflow: workflow zawierającego rzeczywistą logikę analizy, zlokalizowanego w `workflows/` i nazwanego `demo.nf`, oraz zestawu workflow housekeepingowych zlokalizowanych w `subworkflows/`. +Workflow `demo.nf` wywołuje **moduły** zlokalizowane w `modules/`; zawierają one **procesy**, które będą wykonywać rzeczywiste kroki analizy. + +!!! note + + Subworkflows nie są ograniczone do funkcji housekeepingowych i mogą wykorzystywać moduły procesów. + + Pipeline `nf-core/demo` pokazany tutaj jest po prostszej stronie spektrum, ale inne pipeline'y nf-core (takie jak `nf-core/rnaseq`) wykorzystują subworkflows, które są zaangażowane w rzeczywistą analizę. + +Teraz przejrzyjmy te komponenty po kolei. + +#### 3.1.2. Skrypt entrypoint: `main.nf` + +Skrypt `main.nf` jest punktem wejścia, od którego Nextflow rozpoczyna, gdy wykonujemy `nextflow run nf-core/demo`. +Oznacza to, że gdy uruchamiasz `nextflow run nf-core/demo` aby uruchomić pipeline, Nextflow automatycznie znajduje i wykonuje skrypt `main.nf`. +Działa to dla każdego pipeline'a Nextflow, który podąża za tą konwencjonalną nazwą i strukturą, nie tylko dla pipeline'ów nf-core. + +Użycie skryptu entrypoint ułatwia uruchamianie ustandaryzowanych subworkflows 'housekeepingowych' przed i po uruchomieniu właściwego skryptu analizy. +Przejdziemy przez nie po tym, jak przejrzymy rzeczywisty workflow analizy i jego moduły. + +#### 3.1.3. Skrypt analizy: `workflows/demo.nf` + +Workflow `workflows/demo.nf` to miejsce, w którym przechowywana jest centralna logika pipeline'a. +Jest on ustrukturyzowany podobnie jak normalny workflow Nextflow, z wyjątkiem tego, że jest zaprojektowany tak, aby być wywoływanym z workflow nadrzędnego, co wymaga kilku dodatkowych funkcji. +Omówimy odpowiednie różnice w następnej części tego kursu, gdy zajmiemy się konwersją prostego pipeline'a Hello z Hello Nextflow do formy kompatybilnej z nf-core. + +Workflow `demo.nf` wywołuje **moduły** zlokalizowane w `modules/`, które przejrzymy w następnej kolejności. + +!!! note + + Niektóre workflow analizy nf-core wyświetlają dodatkowe poziomy zagnieżdżenia poprzez wywoływanie subworkflows niższego poziomu. + Jest to głównie używane do opakowywania dwóch lub więcej modułów, które są powszechnie używane razem, w łatwe do ponownego użycia segmenty pipeline'a. + Możesz zobaczyć kilka przykładów, przeglądając dostępne [subworkflows nf-core](https://nf-co.re/subworkflows/) na stronie nf-core. + + Gdy skrypt analizy używa subworkflows, są one przechowywane w katalogu `subworkflows/`. + +#### 3.1.4. Moduły + +Moduły to miejsce, w którym znajduje się kod procesu, jak opisano w [Części 4 kursu szkoleniowego Hello Nextflow](../hello_nextflow/04_hello_modules.md). + +W projekcie nf-core moduły są organizowane przy użyciu wielopoziomowej zagnieżdżonej struktury, która odzwierciedla zarówno ich pochodzenie, jak i ich zawartość. +Na najwyższym poziomie moduły są różnicowane jako `nf-core` lub `local` (nie będące częścią projektu nf-core), a następnie dalej umieszczane w katalogu nazwanym według narzędzia(i), które opakowują. +Jeśli narzędzie należy do zestawu narzędzi (tj. pakietu zawierającego wiele narzędzi), istnieje pośredni poziom katalogu nazwany według zestawu narzędzi. + +Możesz zobaczyć to zastosowane w praktyce do modułów pipeline'a `nf-core/demo`: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Zawartość katalogu" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Tutaj widzisz, że moduły `fastqc` i `multiqc` znajdują się na najwyższym poziomie w modułach `nf-core`, podczas gdy moduł `trim` znajduje się pod zestawem narzędzi, do którego należy, `seqtk`. +W tym przypadku nie ma żadnych modułów `local`. + +Plik kodu modułu opisujący proces zawsze nazywa się `main.nf` i jest accompanied by testami i plikami `.yml`, które na razie zignorujem. + +Razem wzięte, workflow entrypoint, workflow analizy i moduły są wystarczające do uruchomienia 'interesujących' części pipeline'a. +Jednak wiemy, że są tam również subworkflows housekeepingowe, więc spójrzmy na nie teraz. + +#### 3.1.5. Subworkflows housekeepingowe + +Podobnie jak moduły, subworkflows są różnicowane na katalogi `local` i `nf-core`, a każdy subworkflow ma swoją własną zagnieżdżoną strukturę katalogów ze swoim własnym skryptem `main.nf`, testami i plikiem `.yml`. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Zawartość katalogu" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Jak zauważono powyżej, pipeline `nf-core/demo` nie zawiera żadnych subworkflows specyficznych dla analizy, więc wszystkie subworkflows, które tutaj widzimy, są tak zwanymi workflow 'housekeepingowymi' lub 'użytkowymi', jak wskazuje prefiks `utils_` w ich nazwach. +Te subworkflows to te, które produkują wymyślny nagłówek nf-core w wyjściu konsoli, między innymi funkcjami akcesoriów. + +!!! tip + + Poza ich wzorcem nazewnictwa, inną wskazówką, że te subworkflows nie wykonują żadnej naprawdę związanej z analizą funkcji, jest to, że nie wywołują żadnych procesów w ogóle. + +To kończy zestawienie podstawowych komponentów kodu, które stanowią pipeline `nf-core/demo`. +Teraz spójrzmy na pozostałe elementy, o których powinieneś wiedzieć trochę przed zagłębieniem się w rozwój: konfigurację pipeline'a i walidację wejścia. + +### 3.2. Konfiguracja pipeline'a + +Nauczyłeś się wcześniej, że Nextflow oferuje wiele opcji konfigurowania wykonania pipeline'a, czy to w zakresie wejść i parametrów, zasobów obliczeniowych i innych aspektów orkiestracji. +Projekt nf-core stosuje wysoce ustandaryzowane wytyczne dotyczące konfiguracji pipeline'a, które mają na celu oparcie się na elastycznych opcjach dostosowywania Nextflow w sposób, który zapewnia większą spójność i łatwość konserwacji w pipeline'ach. + +Centralny plik konfiguracyjny `nextflow.config` jest używany do ustawiania domyślnych wartości dla parametrów i innych opcji konfiguracyjnych. +Większość tych opcji konfiguracyjnych jest stosowana domyślnie, podczas gdy inne (np. profile zależności oprogramowania) są włączone jako opcjonalne profile. + +Istnieje kilka dodatkowych plików konfiguracyjnych, które są przechowywane w katalogu `conf` i które mogą być dodane do konfiguracji domyślnie lub opcjonalnie jako profile: + +- `base.config`: Plik konfiguracyjny 'czystej karty', odpowiedni do ogólnego użytku w większości środowisk obliczeniowych o wysokiej wydajności. Definiuje szerokie przedziały użycia zasobów, na przykład, które są wygodne do zastosowania do modułów. +- `modules.config`: Dodatkowe dyrektywy i argumenty modułów. +- `test.config`: Profil do uruchomienia pipeline'a z minimalnymi danymi testowymi, który użyliśmy, gdy uruchomiliśmy pipeline demo. +- `test_full.config`: Profil do uruchomienia pipeline'a z pełnowymiarowym zestawem danych testowych. + +Dotniemy kilka z tych plików później w kursie. + +### 3.3. Wejścia i walidacja + +Jak zauważyliśmy wcześniej, gdy badaliśmy profil testowy pipeline'a `nf-core/demo`, jest on zaprojektowany tak, aby przyjmować jako wejście samplesheet zawierający ścieżki plików i identyfikatory próbek. +Ścieżki plików były powiązane z rzeczywistymi danymi zlokalizowanymi w repozytorium `nf-core/test-datasets`. + +Przykładowy samplesheet jest również dostarczany w katalogu `assets`, chociaż ścieżki w tym nie są rzeczywiste. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Ten konkretny samplesheet jest dość prosty, ale niektóre pipeline'y działają na samplesheets, które są bardziej złożone, z o wiele większą ilością metadanych związanych z podstawowymi wejściami. + +Niestety, ponieważ te pliki mogą być trudne do sprawdzenia gołym okiem, nieprawidłowe formatowanie danych wejściowych jest bardzo powszechnym źródłem awarii pipeline'a. +Powiązanym problemem jest sytuacja, gdy parametry są nieprawidłowo podane. + +Rozwiązaniem tych problemów jest uruchomienie automatycznych kontroli walidacyjnych na wszystkich plikach wejściowych, aby upewnić się, że zawierają oczekiwane typy informacji, poprawnie sformatowane, oraz na parametrach, aby upewnić się, że są oczekiwanego typu. +Nazywa się to walidacją wejścia i idealnie powinno być wykonane _przed_ próbą uruchomienia pipeline'a, zamiast czekać, aż pipeline się nie powiedzie, aby dowiedzieć się, że był problem z wejściami. + +Podobnie jak w przypadku konfiguracji, projekt nf-core jest bardzo zopiniowany na temat walidacji wejścia i zaleca użycie [wtyczki nf-schema](https://nextflow-io.github.io/nf-schema/latest/), wtyczki Nextflow, która zapewnia kompleksowe możliwości walidacji dla pipeline'ów Nextflow. + +Omówimy ten temat bardziej szczegółowo w Części 5 tego kursu. +Na razie po prostu bądź świadomy, że istnieją dwa pliki JSON dostarczone w tym celu, `nextflow_schema.json` i `assets/schema_input.json`. + +`nextflow_schema.json` to plik używany do przechowywania informacji o parametrach pipeline'a, w tym typ, opis i tekst pomocy w formacie czytelnym maszynowo. +Jest to używane do różnych celów, w tym automatycznej walidacji parametrów, generowania tekstu pomocy i interaktywnego renderowania formularza parametrów w interfejsach użytkownika. + +`schema_input.json` to plik używany do definiowania struktury samplesheet wejściowego. +Każda kolumna może mieć typ, wzorzec, opis i tekst pomocy w formacie czytelnym maszynowo. +Schemat jest używany do różnych celów, w tym automatycznej walidacji i dostarczania pomocnych komunikatów o błędach. + +### Podsumowanie + +Wiesz, jakie są główne komponenty pipeline'a nf-core i jak kod jest zorganizowany; gdzie znajdują się główne elementy konfiguracji; i jesteś świadomy, do czego służy walidacja wejścia. + +### Co dalej? + +Zrób sobie przerwę! To było dużo. Gdy poczujesz się odświeżony i gotowy, przejdź do następnej sekcji, aby zastosować to, czego się nauczyłeś, do napisania pipeline'a kompatybilnego z nf-core. + +!!! tip + + Jeśli chciałbyś dowiedzieć się, jak komponować workflow z subworkflows przed przejściem do następnej części, sprawdź [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest. diff --git a/docs/pl/docs/hello_nf-core/02_rewrite_hello.md b/docs/pl/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..17e515530f --- /dev/null +++ b/docs/pl/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1408 @@ +# Część 2: Przepisanie Hello dla nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej drugiej części kursu szkoleniowego Hello nf-core pokażemy, jak stworzyć wersję pipeline'u kompatybilną z nf-core, opartą na pipeline'ie stworzonym w kursie dla początkujących [Hello Nextflow](../hello_nextflow/index.md). + +Zauważyłeś w pierwszej sekcji szkolenia, że pipeline'y nf-core mają dość rozbudowaną strukturę z wieloma plikami pomocniczymi. +Tworzenie tego wszystkiego od zera byłoby bardzo żmudne, dlatego społeczność nf-core opracowała narzędzia, które wykorzystują szablon do stworzenia podstawowej struktury projektu. + +Pokażemy, jak użyć tych narzędzi do stworzenia szkieletu pipeline'u, a następnie zaadaptować istniejący kod 'zwykłego' pipeline'u na szkielet nf-core. + +Jeśli nie znasz pipeline'u Hello lub potrzebujesz przypomnienia, zobacz [tę stronę informacyjną](../info/hello_pipeline.md). + +--- + +## 1. Stworzenie nowego projektu pipeline'u + +Najpierw stworzymy szkielet dla nowego pipeline'u. + +!!! note "Uwaga" + + Upewnij się, że znajdujesz się w katalogu `hello-nf-core` w swoim terminalu. + +### 1.1. Uruchomienie narzędzia do tworzenia pipeline'u opartego na szablonie + +Zacznijmy od stworzenia nowego pipeline'u za pomocą polecenia `nf-core pipelines create`. +Spowoduje to utworzenie nowego szkieletu pipeline'u przy użyciu podstawowego szablonu nf-core, dostosowanego za pomocą nazwy pipeline'u, opisu i autora. + +```bash +nf-core pipelines create +``` + +Uruchomienie tego polecenia otworzy tekstowy interfejs użytkownika (TUI) do tworzenia pipeline'u: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Ten TUI poprosi Cię o podanie podstawowych informacji o pipeline'ie i pozwoli wybrać funkcje do włączenia lub wyłączenia w szkielecie pipeline'u. + +- Na ekranie powitalnym kliknij **Let's go!**. +- Na ekranie `Choose pipeline type` kliknij **Custom**. +- Wprowadź szczegóły swojego pipeline'u w następujący sposób (zastępując `< TWOJE IMIĘ >` swoim imieniem), następnie kliknij **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < TWOJE IMIĘ > +``` + +- Na ekranie Template features ustaw `Toggle all features` na **off**, następnie selektywnie **włącz** następujące opcje. Sprawdź swoje wybory i kliknij **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- Na ekranie `Final details` kliknij **Finish**. Poczekaj na utworzenie pipeline'u, następnie kliknij **Continue**. +- Na ekranie Create GitHub repository kliknij **Finish without creating a repo**. Wyświetlone zostaną instrukcje tworzenia repozytorium GitHub na później. Zignoruj je i kliknij **Close**. + +Po zamknięciu TUI powinieneś zobaczyć następujące wyjście konsoli. + +??? success "Wyjście polecenia" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +W wyjściu konsoli nie ma wyraźnego potwierdzenia, że utworzenie pipeline'u się powiodło, ale powinieneś zobaczyć nowy katalog o nazwie `core-hello`. + +Wyświetl zawartość nowego katalogu, aby zobaczyć, ile pracy zaoszczędziłeś używając szablonu. + +```bash +tree core-hello +``` + +??? abstract "Zawartość katalogu" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +To dużo plików! + +Miejmy nadzieję, że rozpoznasz wiele z nich jako te same, które napotkaliśmy podczas eksploracji struktury pipeline'u `nf-core/demo`. +Ale nie martw się, jeśli wciąż czujesz się trochę zagubiony; omówimy razem ważne części w trakcie tego szkolenia. + +!!! note "Uwaga" + + Jedna ważna różnica w porównaniu do pipeline'u `nf-core/demo`, który zbadaliśmy w pierwszej części tego szkolenia, polega na tym, że nie ma katalogu `modules`. + Dzieje się tak, ponieważ nie zdecydowaliśmy się uwzględnić żadnego z domyślnych modułów nf-core. + +### 1.2. Sprawdzenie, czy szkielet jest funkcjonalny + +Wierz lub nie, mimo że nie dodałeś jeszcze żadnych modułów do wykonywania rzeczywistej pracy, szkielet pipeline'u można uruchomić używając profilu testowego, tak samo jak uruchamialiśmy pipeline `nf-core/demo`. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +To pokazuje, że całe podstawowe okablowanie jest na miejscu. +Gdzie więc są wyniki? Czy w ogóle jakieś są? + +Tak naprawdę został utworzony nowy katalog wyników o nazwie `core-hello-results` zawierający standardowe raporty wykonania: + +```bash +tree core-hello-results +``` + +??? abstract "Zawartość katalogu" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Możesz zajrzeć do raportów, aby zobaczyć, co zostało uruchomione, a odpowiedzią jest: nic w ogóle! + +![pusty raport osi czasu wykonania](./img/execution_timeline_empty.png) + +Spójrzmy, co faktycznie znajduje się w kodzie. + +### 1.3. Zbadanie zastępczego workflow + +Jeśli zajrzysz do pliku `main.nf`, zobaczysz, że importuje on workflow o nazwie `HELLO` z `workflows/hello`. + +Jest to odpowiednik workflow `workflows/demo.nf`, który napotkaliśmy w Części 1, i służy jako zastępczy workflow dla naszego workflow, z niektórymi funkcjami nf-core już na miejscu. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +W porównaniu do podstawowego workflow Nextflow, takiego jak ten opracowany w [Hello Nextflow](../hello_nextflow/index.md), zauważysz kilka nowych rzeczy (podświetlone linie powyżej): + +- Blok workflow ma nazwę +- Wejścia workflow są deklarowane za pomocą słowa kluczowego `take:`, a konstrukcja kanału jest przenoszona do workflow nadrzędnego +- Zawartość workflow jest umieszczona w bloku `main:` +- Wyjścia są deklarowane za pomocą słowa kluczowego `emit:` + +Są to opcjonalne funkcje Nextflow, które sprawiają, że workflow jest **kompozycyjny**, co oznacza, że może być wywoływany z innego workflow. + +!!! note "Kompozycyjne workflow w szczegółach" + + [Side Quest Workflows of Workflows](../side_quests/workflows_of_workflows.md) bada kompozycję workflow znacznie głębiej, w tym jak komponować wiele workflow razem i zarządzać złożonymi przepływami danych między nimi. Wprowadzamy kompozycyjność tutaj, ponieważ jest to podstawowy wymóg architektury szablonu nf-core, która wykorzystuje zagnieżdżone workflow do organizowania inicjalizacji pipeline'u, głównego workflow analizy i zadań zakończenia w oddzielne, wielokrotnego użytku komponenty. + +Będziemy musieli podłączyć odpowiednią logikę z naszego workflow do tej struktury. +Pierwszym krokiem jest uczynienie naszego oryginalnego workflow kompozycyjnym. + +### Podsumowanie + +Teraz wiesz, jak stworzyć szkielet pipeline'u używając narzędzi nf-core. + +### Co dalej? + +Naucz się, jak uczynić prosty workflow kompozycyjnym jako preludium do uczynienia go kompatybilnym z nf-core. + +--- + +## 2. Uczynienie oryginalnego workflow Hello Nextflow kompozycyjnym + +Teraz czas rozpocząć pracę nad integracją naszego workflow do szkieletu nf-core. +Przypominamy, że pracujemy z workflow przedstawionym w naszym kursie szkoleniowym [Hello Nextflow](../hello_nextflow/index.md). + +!!! tip "Wskazówka" + + Jeśli nie znasz tego pipeline'u lub potrzebujesz przypomnienia, zobacz [Pipeline Hello](../info/hello_pipeline.md). + +Dostarczamy Ci czystą, w pełni funkcjonalną kopię ukończonego workflow Hello Nextflow w katalogu `original-hello` wraz z jego modułami i domyślnym plikiem CSV, którego oczekuje jako wejścia. + +```bash +tree original-hello/ +``` + +??? abstract "Zawartość katalogu" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Możesz go uruchomić, aby upewnić się, że działa: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Otwórzmy plik workflow `hello.nf`, aby sprawdzić kod, który jest pokazany w całości poniżej (nie licząc procesów, które są w modułach): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Dołącz moduły +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Jak widać, ten workflow został napisany jako prosty nienazwany workflow, który może być uruchomiony samodzielnie. +Aby uczynić go możliwym do uruchomienia z workflow nadrzędnego, jak wymaga szablon nf-core, musimy uczynić go **kompozycyjnym**. + +Przejdźmy przez niezbędne zmiany jedna po drugiej. + +### 2.1. Nazwanie workflow + +Najpierw nadajmy workflow nazwę, abyśmy mogli się do niego odwoływać z workflow nadrzędnego. + +=== "Po" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Przed" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Te same konwencje dotyczą nazw workflow, co nazw modułów. + +### 2.2. Zastąpienie konstrukcji kanału przez `take` + +Teraz zastąp konstrukcję kanału prostą instrukcją `take` deklarującą oczekiwane wejścia. + +=== "Po" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // kanał pozdrowień + greeting_ch + ``` + +=== "Przed" + + ```groovy title="original-hello/hello.nf" linenums="18" + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +To pozostawia szczegóły sposobu dostarczania wejść workflow nadrzędnemu. + +Skoro już przy tym jesteśmy, możemy również zakomentować linię `params.greeting = 'greetings.csv'` + +=== "Po" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Przed" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Uwaga" + + Jeśli masz zainstalowane rozszerzenie serwera języka Nextflow, sprawdzanie składni podświetli Twój kod czerwonymi falkami. + Dzieje się tak, ponieważ jeśli umieścisz instrukcję `take:`, musisz również mieć `main:`. + + Dodamy to w następnym kroku. + +### 2.3. Poprzedzenie operacji workflow instrukcją `main` + +Następnie dodaj instrukcję `main` przed pozostałymi operacjami wywoływanymi w ciele workflow. + +=== "Po" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Przed" + + ```groovy title="original-hello/hello.nf" linenums="21" + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +To w zasadzie mówi 'to jest to, co ten workflow _robi_'. + +### 2.4. Dodanie instrukcji `emit` + +Na koniec dodaj instrukcję `emit` deklarującą, jakie są końcowe wyjścia workflow. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +To jest nowy dodatek do kodu w porównaniu z oryginalnym workflow. + +### 2.5. Podsumowanie ukończonych zmian + +Jeśli wykonałeś wszystkie zmiany zgodnie z opisem, Twój workflow powinien teraz wyglądać następująco: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Dołącz moduły +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // kanał pozdrowień + greeting_ch + + main: + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +To opisuje wszystko, czego Nextflow potrzebuje, Z WYJĄTKIEM tego, co podać do kanału wejściowego. +To będzie zdefiniowane w workflow nadrzędnym, nazywanym również workflow **punktem wejścia**. + +### 2.6. Stworzenie fikcyjnego workflow punktu wejścia + +Zanim zintegrujemy nasz kompozycyjny workflow do złożonego szkieletu nf-core, sprawdźmy, czy działa poprawnie. +Możemy stworzyć prosty fikcyjny workflow punktu wejścia, aby przetestować kompozycyjny workflow w izolacji. + +Utwórz pusty plik o nazwie `main.nf` w tym samym katalogu `original-hello`. + +```bash +touch original-hello/main.nf +``` + +Skopiuj następujący kod do pliku `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// importuj kod workflow z pliku hello.nf +include { HELLO } from './hello.nf' + +// zadeklaruj parametr wejściowy +params.greeting = 'greetings.csv' + +workflow { + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // wywołaj zaimportowany workflow na kanale pozdrowień + HELLO(greeting_ch) + + // wyświetl wyjścia wyemitowane przez workflow + HELLO.out.view { output -> "Output: $output" } +} +``` + +Są tutaj dwie ważne obserwacje: + +- Składnia wywoływania zaimportowanego workflow jest zasadniczo taka sama jak składnia wywoływania modułów. +- Wszystko, co jest związane z wprowadzaniem wejść do workflow (parametr wejściowy i konstrukcja kanału) jest teraz zadeklarowane w tym workflow nadrzędnym. + +!!! note "Uwaga" + + Nazwanie pliku workflow punktu wejścia `main.nf` jest konwencją, a nie wymogiem. + + Jeśli zastosujesz się do tej konwencji, możesz pominąć podanie nazwy pliku workflow w poleceniu `nextflow run`. + Nextflow automatycznie poszuka pliku o nazwie `main.nf` w katalogu wykonania. + + Możesz jednak nazwać plik workflow punktu wejścia inaczej, jeśli wolisz. + W takim przypadku pamiętaj, aby określić nazwę pliku workflow w poleceniu `nextflow run`. + +### 2.7. Sprawdzenie, czy workflow działa + +W końcu mamy wszystkie elementy potrzebne do zweryfikowania, że kompozycyjny workflow działa. +Uruchommy go! + +```bash +nextflow run ./original-hello +``` + +Tutaj widać zalety używania konwencji nazewniczej `main.nf`. +Gdybyśmy nazwali workflow punktu wejścia `something_else.nf`, musielibyśmy wykonać `nextflow run original-hello/something_else.nf`. + +Jeśli wykonałeś wszystkie zmiany poprawnie, powinno to uruchomić się do końca. + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +To oznacza, że pomyślnie zaktualizowaliśmy nasz workflow HELLO, aby był kompozycyjny. + +### Podsumowanie + +Wiesz, jak uczynić workflow kompozycyjnym, nadając mu nazwę i dodając instrukcje `take`, `main` i `emit`, oraz jak wywoływać go z workflow punktu wejścia. + +### Co dalej? + +Naucz się, jak przeszczepić podstawowy kompozycyjny workflow na szkielet nf-core. + +--- + +## 3. Dopasowanie zaktualizowanej logiki workflow do zastępczego workflow + +Teraz, gdy zweryfikowaliśmy, że nasz kompozycyjny workflow działa poprawnie, wróćmy do szkieletu pipeline'u nf-core, który stworzyliśmy w sekcji 1. +Chcemy zintegrować kompozycyjny workflow, który właśnie opracowaliśmy, ze strukturą szablonu nf-core, więc wynik końcowy powinien wyglądać mniej więcej tak. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Jak więc to osiągnąć? Spójrzmy na obecną zawartość workflow `HELLO` w `core-hello/workflows/hello.nf` (szkielet nf-core). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Ogólnie rzecz biorąc, ten kod robi bardzo niewiele poza pewnymi czynnościami porządkowymi związanymi z przechwytywaniem wersji wszelkich narzędzi, które są uruchamiane w pipeline'ie. + +Musimy dodać odpowiedni kod z kompozycyjnej wersji oryginalnego workflow, który opracowaliśmy w sekcji 2. + +Zamierzamy zająć się tym w następujących etapach: + +1. Skopiowanie modułów i ustawienie importów modułów +2. Pozostawienie deklaracji `take` bez zmian +3. Dodanie logiki workflow do bloku `main` +4. Aktualizacja bloku `emit` + +!!! note "Uwaga" + + Na razie zignorujemy przechwytywanie wersji i przyjrzymy się, jak to podłączyć w późniejszej części tego szkolenia. + +### 3.1. Skopiowanie modułów i ustawienie importów modułów + +Cztery procesy z naszego workflow Hello Nextflow są przechowywane jako moduły w `original-hello/modules/`. +Musimy skopiować te moduły do struktury projektu nf-core (pod `core-hello/modules/local/`) i dodać instrukcje importu do pliku workflow nf-core. + +Najpierw skopiujmy pliki modułów z `original-hello/` do `core-hello/`: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Powinieneś teraz zobaczyć katalog modułów wymieniony pod `core-hello/`. + +```bash +tree core-hello/modules +``` + +??? abstract "Zawartość katalogu" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Teraz skonfigurujmy instrukcje importu modułów. + +To były instrukcje importu w workflow `original-hello/hello.nf`: + +```groovy title="original-hello/hello.nf" linenums="9" +// Dołącz moduły +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Otwórz plik `core-hello/workflows/hello.nf` i przenieś te instrukcje importu do niego, jak pokazano poniżej. + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Jeszcze dwie interesujące obserwacje: + +- Zaadaptowaliśmy formatowanie instrukcji importu, aby były zgodne z konwencją stylu nf-core. +- Zaktualizowaliśmy ścieżki względne do modułów, aby odzwierciedlały fakt, że są teraz przechowywane na innym poziomie zagnieżdżenia. + +### 3.2. Pozostawienie deklaracji `take` bez zmian + +Projekt nf-core ma wiele wbudowanych funkcji związanych z koncepcją samplesheet, który jest zazwyczaj plikiem CSV zawierającym dane kolumnowe. +Ponieważ to jest zasadniczo tym, czym jest nasz plik `greetings.csv`, zachowamy obecną deklarację `take` bez zmian i po prostu zaktualizujemy nazwę kanału wejściowego w następnym kroku. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +Obsługa wejścia będzie wykonywana przed tym workflow (nie w tym pliku kodu). + +### 3.3. Dodanie logiki workflow do bloku `main` + +Teraz, gdy nasze moduły są dostępne dla workflow, możemy podłączyć logikę workflow do bloku `main`. + +Przypominamy, że to jest odpowiedni kod w oryginalnym workflow, który nie zmienił się zbytnio, gdy uczyniliśmy go kompozycyjnym (dodaliśmy tylko linię `main:`): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) +``` + +Musimy skopiować kod, który następuje po `main:` do nowej wersji workflow. + +Jest tam już jakiś kod związany z przechwytywaniem wersji narzędzi, które są uruchamiane przez workflow. Na razie zostawimy to w spokoju (zajmiemy się wersjami narzędzi później). +Zachowamy inicjalizację `ch_versions = channel.empty()` na górze, następnie wstawimy naszą logikę workflow, zachowując kod zestawiania wersji na końcu. +Ta kolejność ma sens, ponieważ w prawdziwym pipeline'ie procesy emitowałyby informacje o wersji, które byłyby dodawane do kanału `ch_versions` podczas uruchamiania workflow. + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +Zauważysz, że dodaliśmy również pustą linię przed `main:`, aby kod był bardziej czytelny. + +To wygląda świetnie, ale nadal musimy zaktualizować nazwę kanału, który przekazujemy do procesu `sayHello()` z `greeting_ch` na `ch_samplesheet`, jak pokazano poniżej, aby pasowała do tego, co jest napisane pod słowem kluczowym `take:`. + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // wyemituj pozdrowienie (zaktualizowane do używania konwencji nf-core dla samplesheet) + sayHello(ch_samplesheet) + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // wyemituj pozdrowienie + sayHello(greeting_ch) + ``` + +Teraz logika workflow jest poprawnie podłączona. + +### 3.4. Aktualizacja bloku `emit` + +Na koniec musimy zaktualizować blok `emit`, aby uwzględnić deklarację końcowych wyników workflow. + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +To kończy modyfikacje, które musimy wprowadzić do samego workflow HELLO. +W tym momencie osiągnęliśmy ogólną strukturę kodu, którą zamierzaliśmy wdrożyć. + +### Podsumowanie + +Wiesz, jak dopasować podstawowe elementy kompozycyjnego workflow do zastępczego workflow nf-core. + +### Co dalej? + +Naucz się, jak dostosować sposób obsługi wejść w szkielecie pipeline'u nf-core. + +--- + +## 4. Dostosowanie obsługi wejść + +Teraz, gdy pomyślnie zintegrowaliśmy logikę workflow do szkieletu nf-core, musimy zająć się jeszcze jednym krytycznym elementem: zapewnieniem, że nasze dane wejściowe są prawidłowo przetwarzane. +Szablon nf-core jest wyposażony w zaawansowaną obsługę wejść zaprojektowaną dla złożonych zestawów danych genomicznych, więc musimy ją dostosować do pracy z naszym prostszym plikiem `greetings.csv`. + +### 4.1. Identyfikacja miejsca obsługi wejść + +Pierwszym krokiem jest ustalenie, gdzie odbywa się obsługa wejść. + +Możesz sobie przypomnieć, że kiedy przepisaliśmy workflow Hello Nextflow, aby był kompozycyjny, przenieśliśmy deklarację parametru wejściowego o jeden poziom wyżej, do workflow punktu wejścia `main.nf`. +Spójrzmy więc na workflow punktu wejścia najwyższego poziomu `main.nf`, który został utworzony jako część szkieletu pipeline'u: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Uruchom główny pipeline analizy w zależności od typu danych wejściowych +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Uruchom pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Uruchom zadania inicjalizacyjne + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Uruchom główny workflow + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Uruchom zadania końcowe + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Projekt nf-core intensywnie wykorzystuje zagnieżdżone subworkflow, więc ta część może być na początku trochę myląca. + +To, co tutaj ma znaczenie, to fakt, że zdefiniowane są dwa workflow: + +- `CORE_HELLO` to cienka otoczka do uruchamiania workflow HELLO, który właśnie zakończyliśmy adaptować w `core-hello/workflows/hello.nf`. +- Nienazwany workflow, który wywołuje `CORE_HELLO` oraz dwa inne subworkflow, `PIPELINE_INITIALISATION` i `PIPELINE_COMPLETION`. + +Oto diagram pokazujący, jak się do siebie odnoszą: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Co ważne, nie możemy znaleźć na tym poziomie żadnego kodu konstruującego kanał wejściowy, tylko odniesienia do samplesheet dostarczonego przez parametr `--input`. + +Trochę poszukiwań ujawnia, że obsługa wejść jest wykonywana przez subworkflow `PIPELINE_INITIALISATION`, co jest całkiem stosowne, który jest importowany z `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`. + +Jeśli otworzymy ten plik i przewiniemy w dół, natrafimy na ten fragment kodu: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Utwórz kanał z pliku wejściowego podanego przez params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +To jest fabryka kanałów, która parsuje samplesheet i przekazuje go dalej w formie gotowej do użycia przez workflow HELLO. + +!!! note "Uwaga" + + Składnia powyżej różni się nieco od tego, czego używaliśmy wcześniej, ale zasadniczo to: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + jest równoważne temu: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Ten kod obejmuje pewne kroki parsowania i walidacji, które są wysoce specyficzne dla przykładowego samplesheet dołączonego do szablonu pipeline'u nf-core, który w momencie pisania jest bardzo domenowo-specyficzny i nieodpowiedni dla naszego prostego projektu pipeline'u. + +### 4.2. Zastąpienie kodu kanału wejściowego z szablonu + +Dobrą wiadomością jest to, że potrzeby naszego pipeline'u są znacznie prostsze, więc możemy zastąpić to wszystko kodem konstrukcji kanału, który opracowaliśmy w oryginalnym workflow Hello Nextflow. + +Przypominamy, że konstrukcja kanału wyglądała tak (jak widać w katalogu rozwiązań): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Musimy więc po prostu podłączyć to do workflow inicjalizacji, z drobnymi zmianami: aktualizujemy nazwę kanału z `greeting_ch` na `ch_samplesheet` i nazwę parametru z `params.greeting` na `params.input` (zobacz podświetloną linię). + +=== "Po" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Utwórz kanał z pliku wejściowego podanego przez params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Przed" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Utwórz kanał z pliku wejściowego podanego przez params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +To kończy zmiany, które musimy wprowadzić, aby przetwarzanie wejść działało. + +W obecnej formie nie pozwoli nam to skorzystać z wbudowanych możliwości nf-core do walidacji schematu, ale możemy dodać to później. +Na razie skupiamy się na tym, aby było to jak najprostsze, aby uzyskać coś, co możemy pomyślnie uruchomić na danych testowych. + +### 4.3. Aktualizacja profilu testowego + +Mówiąc o danych testowych i parametrach, zaktualizujmy profil testowy tego pipeline'u, aby używał mini-samplesheet `greetings.csv` zamiast przykładowego samplesheet dostarczonego w szablonie. + +Pod `core-hello/conf` znajdujemy dwa szablonowe profile testowe: `test.config` i `test_full.config`, które są przeznaczone do testowania małej próbki danych i pełnowymiarowej. +Biorąc pod uwagę cel naszego pipeline'u, nie ma sensu konfigurowanie profilu testowego pełnowymiarowego, więc możesz zignorować lub usunąć `test_full.config`. +Skupimy się na skonfigurowaniu `test.config` do uruchomienia na naszym pliku `greetings.csv` z kilkoma domyślnymi parametrami. + +#### 4.3.1. Skopiowanie pliku `greetings.csv` + +Najpierw musimy skopiować plik `greetings.csv` do odpowiedniego miejsca w naszym projekcie pipeline'u. +Zazwyczaj małe pliki testowe są przechowywane w katalogu `assets`, więc skopiujmy plik z naszego katalogu roboczego. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Teraz plik `greetings.csv` jest gotowy do użycia jako dane wejściowe testowe. + +#### 4.3.2. Aktualizacja pliku `test.config` + +Teraz możemy zaktualizować plik `test.config` w następujący sposób: + +=== "Po" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dane wejściowe + input = "${projectDir}/assets/greetings.csv" + + // Inne parametry + batch = 'test' + character = 'tux' + } + ``` + +=== "Przed" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dane wejściowe + // TODO nf-core: Określ ścieżki do swoich danych testowych w nf-core/test-datasets + // TODO nf-core: Podaj wszystkie wymagane parametry dla testu, aby nie były potrzebne flagi linii poleceń + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Kluczowe punkty: + +- **Używanie `${projectDir}`**: To jest niejawna zmienna Nextflow, która wskazuje na katalog, w którym znajduje się główny skrypt workflow (katalog główny pipeline'u). Użycie jej zapewnia, że ścieżka działa niezależnie od tego, skąd pipeline jest uruchamiany. +- **Ścieżki bezwzględne**: Używając `${projectDir}`, tworzymy ścieżkę bezwzględną, co jest ważne dla danych testowych dostarczanych z pipeline'em. +- **Lokalizacja danych testowych**: Pipeline'y nf-core zazwyczaj przechowują dane testowe w katalogu `assets/` w repozytorium pipeline'u dla małych plików testowych lub odwołują się do zewnętrznych zestawów danych testowych dla większych plików. + +Skoro już przy tym jesteśmy, zaostrzmy domyślne limity zasobów, aby upewnić się, że będzie to działać na bardzo podstawowych maszynach (jak minimalne maszyny wirtualne w Github Codespaces): + +=== "Po" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Przed" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +To kończy modyfikacje kodu, które musimy wykonać. + +### 4.4. Uruchomienie pipeline'u z profilem testowym + +To było dużo, ale w końcu możemy spróbować uruchomić pipeline! +Zauważ, że musimy dodać `--validate_params false` do wiersza poleceń, ponieważ nie skonfigurowaliśmy jeszcze walidacji (to przyjdzie później). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Jeśli wykonałeś wszystkie modyfikacje poprawnie, powinno to uruchomić się do końca. + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Jak widać, wygenerowało to typowe podsumowanie nf-core na początku dzięki subworkflow inicjalizacji, a linie dla każdego modułu teraz pokazują pełne nazwy PIPELINE:WORKFLOW:moduł. + +### 4.5. Znalezienie wyników pipeline'u + +Pytanie brzmi teraz: gdzie są wyniki pipeline'u? +A odpowiedź jest dość interesująca: są teraz dwa różne miejsca, w których należy szukać wyników. + +Jak możesz sobie przypomnieć z wcześniejszych sekcji, nasze pierwsze uruchomienie nowo utworzonego workflow wytworzyło katalog o nazwie `core-hello-results/`, który zawierał różne raporty wykonania i metadane. + +```bash +tree core-hello-results +``` + +??? abstract "Zawartość katalogu" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_07-29-37.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── execution_trace_2025-11-21_07-29-37.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-13.json + ├── params_2025-11-21_07-29-41.json + └── pipeline_dag_2025-11-21_04-47-18.html + └── pipeline_dag_2025-11-21_07-29-37.html + + 1 directory, 12 files + ``` + +Widzisz, że otrzymaliśmy kolejny zestaw raportów wykonania oprócz tych, które otrzymaliśmy z pierwszego uruchomienia, gdy workflow był jeszcze tylko zastępczym. +Tym razem widzisz wszystkie zadania, które zostały uruchomione zgodnie z oczekiwaniami. + +![raport osi czasu wykonania dla pipeline'u Hello](./img/execution_timeline_hello.png) + +!!! note "Uwaga" + + Ponownie zadania nie były uruchamiane równolegle, ponieważ działamy na minimalistycznej maszynie w Github Codespaces. + Aby zobaczyć, jak te uruchamiają się równolegle, spróbuj zwiększyć alokację CPU swojego codespace oraz limity zasobów w konfiguracji testowej. + +To świetnie, ale nasze rzeczywiste wyniki pipeline'u tam nie są! + +Oto co się stało: nie zmieniliśmy niczego w samych modułach, więc wyniki obsługiwane przez dyrektywy `publishDir` na poziomie modułów nadal trafiają do katalogu `results`, jak określono w oryginalnym pipeline'ie. + +```bash +tree results +``` + +??? abstract "Zawartość katalogu" + + ```console + results + ├── Bonjour-output.txt + ├── COLLECTED-test-batch-output.txt + ├── COLLECTED-test-output.txt + ├── cowpy-COLLECTED-test-batch-output.txt + ├── cowpy-COLLECTED-test-output.txt + ├── Hello-output.txt + ├── Holà-output.txt diff --git a/docs/pl/docs/hello_nf-core/03_use_module.md b/docs/pl/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..6c06a0bc70 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Część 3: Użycie modułu nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W trzeciej części kursu szkoleniowego Hello nf-core pokażemy, jak znaleźć, zainstalować i użyć istniejącego modułu nf-core w swoim pipeline. + +Jedną z głównych korzyści pracy z nf-core jest możliwość wykorzystania wcześniej przygotowanych, przetestowanych modułów z repozytorium [nf-core/modules](https://github.com/nf-core/modules). +Zamiast pisać każdy proces od podstaw, możesz zainstalować i używać modułów utrzymywanych przez społeczność, które przestrzegają najlepszych praktyk. + +Aby pokazać, jak to działa, zastąpimy niestandardowy moduł `collectGreetings` modułem `cat/cat` z nf-core/modules w pipeline `core-hello`. + +??? info "Jak zacząć od tej sekcji" + + Ta sekcja kursu zakłada, że ukończyłeś [Część 2: Przepisanie Hello dla nf-core](./02_rewrite_hello.md) i masz działający pipeline `core-hello`. + + Jeśli nie ukończyłeś Części 2 lub chcesz zacząć od nowa dla tej części, możesz użyć rozwiązania `core-hello-part2` jako punktu wyjścia. + Uruchom to polecenie z poziomu katalogu `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Otrzymasz w ten sposób w pełni funkcjonalny pipeline nf-core gotowy do dodawania modułów. + Możesz sprawdzić, czy działa poprawnie, uruchamiając następujące polecenie: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Znajdź i zainstaluj odpowiedni moduł nf-core + +Najpierw nauczmy się, jak znaleźć istniejący moduł nf-core i zainstalować go w naszym pipeline. + +Będziemy dążyć do zastąpienia procesu `collectGreetings`, który używa polecenia Unix `cat` do łączenia wielu plików z powitaniami w jeden. +Łączenie plików jest bardzo powszechną operacją, więc jest prawdopodobne, że może już istnieć moduł w nf-core zaprojektowany do tego celu. + +Zagłębmy się w to. + +### 1.1. Przeglądanie dostępnych modułów na stronie nf-core + +Projekt nf-core utrzymuje scentralizowany katalog modułów pod adresem [https://nf-co.re/modules](https://nf-co.re/modules). + +Przejdź do strony modułów w swojej przeglądarce internetowej i użyj paska wyszukiwania, aby wyszukać 'concatenate'. + +![wyniki wyszukiwania modułów](./img/module-search-results.png) + +Jak widać, jest sporo wyników, wiele z nich to moduły zaprojektowane do łączenia bardzo specyficznych typów plików. +Wśród nich powinieneś zobaczyć jeden o nazwie `cat_cat`, który jest ogólnego przeznaczenia. + +!!! note "Konwencja nazewnictwa modułów" + + Podkreślenie (`_`) jest używane jako zastępnik znaku ukośnika (`/`) w nazwach modułów. + + Moduły nf-core przestrzegają konwencji nazewnictwa `software/command`, gdy narzędzie dostarcza wiele poleceń, jak `samtools/view` (pakiet samtools, polecenie view) lub `gatk/haplotypecaller` (pakiet GATK, polecenie HaplotypeCaller). + Dla narzędzi, które dostarczają tylko jedno główne polecenie, moduły używają jednego poziomu, jak `fastqc` lub `multiqc`. + +Kliknij na pole modułu `cat_cat`, aby wyświetlić dokumentację modułu. + +Strona modułu pokazuje: + +- Krótki opis: "A module for concatenation of gzipped or uncompressed files" +- Polecenie instalacji: `nf-core modules install cat/cat` +- Strukturę kanałów wejściowych i wyjściowych +- Dostępne parametry + +### 1.2. Wyświetlanie dostępnych modułów z wiersza poleceń + +Alternatywnie, możesz również wyszukiwać moduły bezpośrednio z wiersza poleceń używając narzędzi nf-core. + +```bash +nf-core modules list remote +``` + +To wyświetli listę wszystkich dostępnych modułów w repozytorium nf-core/modules, choć jest to nieco mniej wygodne, jeśli nie znasz już nazwy modułu, którego szukasz. +Jednak jeśli znasz, możesz przekierować listę do `grep`, aby znaleźć konkretne moduły: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Wynik polecenia" + + ```console + │ cat/cat + ``` + +Pamiętaj tylko, że podejście z `grep` wyciągnie tylko wyniki z wyszukiwanym terminem w nazwie, co nie zadziałałoby dla `cat_cat`. + +### 1.3. Uzyskanie szczegółowych informacji o module + +Aby zobaczyć szczegółowe informacje o konkretnym module z wiersza poleceń, użyj polecenia `info`: + +```bash +nf-core modules info cat/cat +``` + +To wyświetla dokumentację modułu, w tym jego wejścia, wyjścia i podstawowe informacje o użyciu. + +??? success "Wynik polecenia" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +To są dokładnie te same informacje, które możesz znaleźć na stronie internetowej. + +### 1.4. Instalacja modułu cat/cat + +Teraz, gdy znaleźliśmy moduł, którego chcemy, musimy dodać go do kodu źródłowego naszego pipeline. + +Dobra wiadomość jest taka, że projekt nf-core zawiera narzędzia, które ułatwiają tę część. +Konkretnie, polecenie `nf-core modules install` umożliwia zautomatyzowanie pobierania kodu i udostępnienia go projektowi w jednym kroku. + +Przejdź do katalogu swojego pipeline i uruchom polecenie instalacji: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +Narzędzie może najpierw poprosić Cię o określenie typu repozytorium. +(Jeśli nie, przejdź do "Na końcu narzędzie przystąpi do instalacji modułu.") + +??? success "Wynik polecenia" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Jeśli tak, naciśnij enter, aby zaakceptować domyślną odpowiedź (`Pipeline`) i kontynuować. + +Narzędzie następnie zaoferuje zmianę konfiguracji Twojego projektu, aby uniknąć tego monitu w przyszłości. + +??? success "Wynik polecenia" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +Warto skorzystać z tego wygodnego narzędzia! +Naciśnij enter, aby zaakceptować domyślną odpowiedź (tak). + +Na końcu narzędzie przystąpi do instalacji modułu. + +??? success "Wynik polecenia" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Polecenie automatycznie: + +- Pobiera pliki modułu do `modules/nf-core/cat/cat/` +- Aktualizuje `modules.json`, aby śledzić zainstalowany moduł +- Dostarcza Ci prawidłową instrukcję `include` do użycia w swoim workflow + +!!! tip + + Zawsze upewnij się, że Twój bieżący katalog roboczy to katalog główny projektu pipeline przed uruchomieniem polecenia instalacji modułu. + +Sprawdźmy, czy moduł został poprawnie zainstalowany: + +```bash +tree -L 4 modules +``` + +??? abstract "Zawartość katalogu" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +Możesz również zweryfikować instalację, prosząc narzędzie nf-core o wyświetlenie lokalnie zainstalowanych modułów: + +```bash +nf-core modules list local +``` + +??? success "Wynik polecenia" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +To potwierdza, że moduł `cat/cat` jest teraz częścią kodu źródłowego Twojego projektu. + +Jednak aby faktycznie użyć nowego modułu, musimy go zaimportować do naszego pipeline. + +### 1.5. Aktualizacja importów modułów + +Zastąpmy instrukcję `include` dla modułu `collectGreetings` instrukcją dla `CAT_CAT` w sekcji importów pliku workflow `workflows/hello.nf`. + +Przypominając, narzędzie instalacji modułu podało nam dokładną instrukcję do użycia: + +```groovy title="Instrukcja importu wygenerowana przez polecenie instalacji" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Zauważ, że konwencja nf-core polega na użyciu wielkich liter dla nazw modułów podczas ich importowania. + +Otwórz [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) i dokonaj następującej zamiany: + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Zauważ, jak ścieżka dla modułu nf-core różni się od modułów lokalnych: + +- **Moduł nf-core**: `'../modules/nf-core/cat/cat/main'` (odniesienie do `main.nf`) +- **Moduł lokalny**: `'../modules/local/collectGreetings.nf'` (odniesienie do pojedynczego pliku) + +Moduł jest teraz dostępny dla workflow, więc wszystko, co musimy zrobić, to zamienić wywołanie `collectGreetings` na użycie `CAT_CAT`. Prawda? + +Nie tak szybko. + +W tym momencie możesz być kuszony, aby zacząć edytować kod, ale warto poświęcić chwilę, aby dokładnie sprawdzić, czego oczekuje nowy moduł i co produkuje. + +Zajmiemy się tym jako osobną sekcją, ponieważ obejmuje to nowy mechanizm, którego jeszcze nie omówiliśmy: mapy metadanych. + +!!! note + + Opcjonalnie możesz usunąć plik `collectGreetings.nf`: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Możesz jednak chcieć go zachować jako punkt odniesienia do zrozumienia różnic między modułami lokalnymi a modułami nf-core. + +### Podsumowanie + +Wiesz, jak znaleźć moduł nf-core i udostępnić go swojemu projektowi. + +### Co dalej? + +Oceń, czego wymaga nowy moduł i zidentyfikuj wszelkie ważne zmiany potrzebne do zintegrowania go z pipeline. + +--- + +## 2. Ocena wymagań nowego modułu + +Konkretnie, musimy zbadać **interfejs** modułu, tj. jego definicje wejść i wyjść, i porównać go z interfejsem modułu, który chcemy zastąpić. +To pozwoli nam określić, czy możemy po prostu traktować nowy moduł jako zamiennik typu "drop-in", czy też będziemy musieli dostosować część połączeń. + +Najlepiej byłoby zrobić to _przed_ zainstalowaniem modułu, ale hej, lepiej późno niż wcale. +(Na marginesie, istnieje polecenie `uninstall`, aby pozbyć się modułów, których nie chcesz już używać.) + +!!! note + + Proces CAT_CAT zawiera dość sprytne obsługiwanie różnych typów kompresji, rozszerzeń plików itp., które nie są ściśle istotne dla tego, co próbujemy Ci tutaj pokazać, więc zignorujemy większość z tego i skupimy się tylko na częściach, które są ważne. + +### 2.1. Porównanie interfejsów dwóch modułów + +Przypominając, tak wygląda interfejs naszego modułu `collectGreetings`: + +```groovy title="modules/local/collectGreetings.nf (fragment)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +Moduł `collectGreetings` przyjmuje dwa wejścia: + +- `input_files` zawiera jeden lub więcej plików wejściowych do przetworzenia; +- `batch_name` to wartość, której używamy do przypisania nazwy specyficznej dla uruchomienia do pliku wyjściowego, co jest formą metadanych. + +Po zakończeniu `collectGreetings` wyprowadza pojedynczą ścieżkę pliku, emitowaną z tagiem `outfile`. + +W porównaniu, interfejs modułu `cat/cat` jest bardziej złożony: + +```groovy title="modules/nf-core/cat/cat/main.nf (fragment)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +Moduł CAT_CAT przyjmuje pojedyncze wejście, ale to wejście jest krotką zawierającą dwie rzeczy: + +- `meta` to struktura zawierająca metadane, nazywana metamapą; +- `files_in` zawiera jeden lub więcej plików wejściowych do przetworzenia, równoważne `input_files` z `collectGreetings`. + +Po zakończeniu CAT_CAT dostarcza swoje wyjścia w dwóch częściach: + +- Kolejna krotka zawierająca metamapę i połączony plik wyjściowy, emitowana z tagiem `file_out`; +- Plik `versions.yml`, który przechwytuje informacje o wersji oprogramowania, które zostało użyte, emitowany z tagiem `versions`. + +Zauważ również, że domyślnie plik wyjściowy będzie nazwany na podstawie identyfikatora będącego częścią metadanych (kod nie pokazany tutaj). + +Może to wydawać się dużo do śledzenia, patrząc tylko na kod, więc oto diagram, który pomoże Ci zwizualizować, jak wszystko do siebie pasuje. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Widać, że oba moduły mają podobne wymagania wejściowe pod względem zawartości (zestaw plików wejściowych plus niektóre metadane), ale bardzo różne oczekiwania co do sposobu pakowania tej zawartości. +Ignorując na razie plik wersji, ich główne wyjście jest również równoważne (połączony plik), z wyjątkiem tego, że CAT_CAT emituje również metamapę w połączeniu z plikiem wyjściowym. + +Różnice w pakowaniu będą dość łatwe do obsłużenia, jak zobaczysz za chwilę. +Jednak aby zrozumieć część z metamapą, musimy przedstawić Ci dodatkowy kontekst. + +### 2.2. Zrozumienie metamap + +Właśnie powiedzieliśmy, że moduł CAT_CAT oczekuje mapy metadanych jako części swojej krotki wejściowej. +Poświęćmy kilka minut na bliższe przyjrzenie się temu, czym to jest. + +**Mapa metadanych**, często nazywana w skrócie **metamapą**, to mapa w stylu Groovy zawierająca informacje o jednostkach danych. +W kontekście pipeline Nextflow jednostki danych mogą być czymkolwiek: pojedynczymi próbkami, partiami próbek lub całymi zbiorami danych. + +Zgodnie z konwencją, metamapa nf-core jest nazywana `meta` i zawiera wymagane pole `id`, które jest używane do nazywania wyjść i śledzenia jednostek danych. + +Na przykład, typowa mapa metadanych może wyglądać tak: + +```groovy title="Przykład metamapy na poziomie próbki" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +Lub w przypadku, gdy metadane są dołączone na poziomie partii: + +```groovy title="Przykład metamapy na poziomie partii" +[id: 'batch1', date: '25.10.01'] +``` + +Teraz umieśćmy to w kontekście procesu `CAT_CAT`, który oczekuje, że pliki wejściowe będą zapakowane w krotkę z metamapą, i również wyprowadza metamapę jako część krotki wyjściowej. + +```groovy title="modules/nf-core/cat/cat/main.nf (fragment)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +W rezultacie każda jednostka danych przemieszcza się przez pipeline z dołączonymi odpowiednimi metadanymi. +Kolejne procesy mogą następnie również łatwo uzyskać dostęp do tych metadanych. + +Pamiętasz, jak mówiliśmy, że plik wyprowadzany przez `CAT_CAT` będzie nazwany na podstawie identyfikatora będącego częścią metadanych? +To jest odpowiedni kod: + +```groovy title="modules/nf-core/cat/cat/main.nf (fragment)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Oznacza to mniej więcej następująco: jeśli `prefix` jest dostarczony przez system parametrów zewnętrznych zadania (`task.ext`), użyj tego do nazwania pliku wyjściowego; w przeciwnym razie utwórz go używając `${meta.id}`, który odpowiada polu `id` w metamapie. + +Możesz sobie wyobrazić kanał wejściowy wchodzący do tego modułu z zawartością taką jak ta: + +```groovy title="Przykład zawartości kanału wejściowego" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Następnie zawartość kanału wyjściowego wychodzącego wyglądałaby tak: + +```groovy title="Przykład zawartości kanału wyjściowego" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Jak wspomniano wcześniej, konfiguracja wejściowa `tuple val(meta), path(files_in)` jest standardowym wzorcem używanym we wszystkich modułach nf-core. + +Miejmy nadzieję, że zaczynasz widzieć, jak przydatne może to być. +Nie tylko pozwala to nazwać wyjścia na podstawie metadanych, ale możesz również robić takie rzeczy, jak używać ich do stosowania różnych wartości parametrów, a w połączeniu z określonymi operatorami możesz nawet grupować, sortować lub filtrować dane, gdy przepływają przez pipeline. + +!!! note "Dowiedz się więcej o metadanych" + + Aby uzyskać kompleksowe wprowadzenie do pracy z metadanymi w workflow Nextflow, w tym jak odczytywać metadane z arkuszy próbek i używać ich do dostosowywania przetwarzania, zobacz side quest [Metadane w workflow](../side_quests/metadata). + +### 2.3. Podsumowanie zmian do wprowadzenia + +Na podstawie tego, co przejrzeliśmy, oto główne zmiany, które musimy wprowadzić w naszym pipeline, aby wykorzystać moduł `cat/cat`: + +- Utworzyć metamapę zawierającą nazwę partii; +- Zapakować metamapę w krotkę z zestawem plików wejściowych do połączenia (wychodzących z `convertToUpper`); +- Zmienić wywołanie z `collectGreetings()` na `CAT_CAT`; +- Wyodrębnić plik wyjściowy z krotki wytworzonej przez proces `CAT_CAT` przed przekazaniem go do `cowpy`. + +To powinno załatwić sprawę! Teraz, gdy mamy plan, jesteśmy gotowi do działania. + +### Podsumowanie + +Wiesz, jak ocenić interfejs wejściowy i wyjściowy nowego modułu, aby zidentyfikować jego wymagania, i nauczyłeś się, jak metamapy są używane przez pipeline nf-core do utrzymywania metadanych ściśle powiązanych z danymi, gdy przepływają przez pipeline. + +### Co dalej? + +Zintegrować nowy moduł z workflow. + +--- + +## 3. Integracja CAT_CAT z workflow `hello.nf` + +Teraz, gdy wiesz wszystko o metamapach (lub wystarczająco dużo dla celów tego kursu), nadszedł czas, aby faktycznie zaimplementować zmiany, które opisaliśmy powyżej. + +Dla jasności podzielimy to i omówimy każdy krok osobno. + +!!! note + + Wszystkie zmiany pokazane poniżej są dokonywane w logice workflow w bloku `main` w pliku workflow `core-hello/workflows/hello.nf`. + +### 3.1. Utworzenie mapy metadanych + +Najpierw musimy utworzyć mapę metadanych dla `CAT_CAT`, pamiętając, że moduły nf-core wymagają, aby metamapa zawierała co najmniej pole `id`. + +Ponieważ nie potrzebujemy innych metadanych, możemy to uprościć i użyć czegoś takiego: + +```groovy title="Przykład składni" +def cat_meta = [id: 'test'] +``` + +Z tym że nie chcemy sztywno kodować wartości `id`; chcemy użyć wartości parametru `params.batch`. +Więc kod staje się: + +```groovy title="Przykład składni" +def cat_meta = [id: params.batch] +``` + +Tak, jest to dosłownie tak proste, aby utworzyć podstawową metamapę. + +Dodajmy te linie po wywołaniu `convertToUpper`, usuwając wywołanie `collectGreetings`: + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // zbierz wszystkie powitania w jeden plik + collectGreetings(convertToUpper.out.collect(), params.batch) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +To tworzy prostą mapę metadanych, gdzie `id` jest ustawione na naszą nazwę partii (która będzie `test` przy użyciu profilu testowego). + +### 3.2. Utworzenie kanału z krotkami metadanych + +Następnie przekształć kanał plików w kanał krotek zawierających metadane i pliki: + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // utwórz kanał z metadanymi i plikami w formacie krotki + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Linia, którą dodaliśmy, osiąga dwie rzeczy: + +- `.collect()` zbiera wszystkie pliki z wyjścia `convertToUpper` w jedną listę +- `.map { files -> tuple(cat_meta, files) }` tworzy krotkę `[metadata, files]` w formacie oczekiwanym przez `CAT_CAT` + +To wszystko, co musimy zrobić, aby przygotować krotkę wejściową dla `CAT_CAT`. + +### 3.3. Wywołanie modułu CAT_CAT + +Teraz wywołaj `CAT_CAT` na nowo utworzonym kanale: + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // utwórz kanał z metadanymi i plikami w formacie krotki + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // połącz pliki używając modułu nf-core cat/cat + CAT_CAT(ch_for_cat) + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // utwórz kanał z metadanymi i plikami w formacie krotki + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // wygeneruj grafikę ASCII pozdrowień za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +To kończy najtrudniejszą część tej zamiany, ale jeszcze nie skończyliśmy: nadal musimy zaktualizować sposób, w jaki przekazujemy połączone wyjście do procesu `cowpy`. + +### 3.4. Wyodrębnienie pliku wyjściowego z krotki dla `cowpy` + +Wcześniej proces `collectGreetings` po prostu produkował plik, który mogliśmy przekazać bezpośrednio do `cowpy`. +Jednak proces `CAT_CAT` produkuje krotkę, która zawiera metamapę oprócz pliku wyjściowego. + +Ponieważ `cowpy` nie akceptuje jeszcze krotek metadanych (naprawimy to w następnej części kursu), musimy wyodrębnić plik wyjściowy z krotki wytworzonej przez `CAT_CAT` przed przekazaniem go do `cowpy`: + +=== "Po" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // utwórz kanał z metadanymi i plikami w formacie krotki + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // połącz powitania + CAT_CAT(ch_for_cat) + + // wyodrębnij plik z krotki, ponieważ cowpy nie używa jeszcze metadanych + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // wygeneruj grafikę ASCII z powitaniami za pomocą cowpy + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Przed" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // wyemituj pozdrowienie + sayHello(ch_samplesheet) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + + // utwórz mapę metadanych z nazwą partii jako ID + def cat_meta = [ id: params.batch ] + + // utwórz kanał z metadanymi i plikami w formacie krotki + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // połącz powitania + CAT_CAT(ch_for_cat) + + // wygeneruj grafikę ASCII z powitaniami za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Operacja `.map{ meta, file -> file }` wyodrębnia plik z krotki `[metadata, file]` wytworzonej przez `CAT_CAT` do nowego kanału, `ch_for_cowpy`. + +Następnie wystarczy przekazać `ch_for_cowpy` do `cowpy` zamiast `collectGreetings.out.outfile` w tej ostatniej linii. + +!!! note + + W następnej części kursu zaktualizujemy `cowpy`, aby pracował bezpośrednio z krotkami metadanych, więc ten krok ekstrakcji nie będzie już potrzebny. + +### 3.5. Testowanie workflow + +Przetestujmy, czy workflow działa z nowo zintegrowanym modułem `cat/cat`: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +To powinno działać dość szybko. + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Zauważ, że `CAT_CAT` pojawia się teraz na liście wykonywanych procesów zamiast `collectGreetings`. + +I to wszystko! Teraz używamy solidnego, utrzymywanego przez społeczność modułu zamiast niestandardowego kodu na poziomie prototypu dla tego kroku w pipeline. + +### Podsumowanie + +Teraz wiesz, jak: + +- Znaleźć i zainstalować moduły nf-core +- Ocenić wymagania modułu nf-core +- Utworzyć prostą mapę metadanych do użycia z modułem nf-core +- Zintegrować moduł nf-core ze swoim workflow + +### Co dalej? + +Naucz się dostosowywać swoje moduły lokalne, aby przestrzegały konwencji nf-core. +Pokażemy Ci również, jak tworzyć nowe moduły nf-core z szablonu za pomocą narzędzi nf-core. diff --git a/docs/pl/docs/hello_nf-core/04_make_module.md b/docs/pl/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..1b132ccff7 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1106 @@ +# Część 4: Tworzenie modułu nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W czwartej części kursu szkoleniowego Hello nf-core pokażemy, jak utworzyć moduł nf-core, stosując kluczowe konwencje, które czynią moduły przenośnymi i łatwymi w utrzymaniu. + +Projekt nf-core udostępnia polecenie (`nf-core modules create`), które automatycznie generuje prawidłowo ustrukturyzowane szablony modułów, podobnie jak to, czego użyliśmy dla workflow w Części 2. +Jednak w celach edukacyjnych zaczniemy od wykonania tego ręcznie: przekształcenia lokalnego modułu `cowpy` w Twoim pipeline `core-hello` w moduł w stylu nf-core krok po kroku. +Następnie pokażemy, jak korzystać z tworzenia modułów opartych na szablonach, aby pracować wydajniej w przyszłości. + +??? info "Jak rozpocząć od tej sekcji" + + Ta sekcja zakłada, że ukończyłeś [Część 3: Użycie modułu nf-core](./03_use_module.md) i zintegrowałeś moduł `CAT_CAT` ze swoim pipeline. + + Jeśli nie ukończyłeś Części 3 lub chcesz zacząć od nowa w tej części, możesz użyć rozwiązania `core-hello-part3` jako punktu wyjścia. + Uruchom te polecenia z wnętrza katalogu `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + To daje Ci pipeline z już zintegrowanym modułem `CAT_CAT`. + Możesz przetestować, czy działa poprawnie, uruchamiając następujące polecenie: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Przekształcenie `cowpy` w moduł nf-core + +W tej sekcji zastosujemy konwencje nf-core do lokalnego modułu `cowpy` w Twoim pipeline `core-hello`, przekształcając go w moduł zgodny ze standardami społeczności nf-core. + +To jest aktualny kod modułu procesu `cowpy`: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Zastosujemy następujące konwencje nf-core stopniowo: + +1. **Zmiana nazwy procesu na wielkie litery `COWPY`** zgodnie z konwencją. +2. **Aktualizacja `COWPY` do używania krotek metadanych** w celu propagowania metadanych próbek przez workflow. +3. **Centralizacja konfiguracji argumentów narzędzia z `ext.args`** w celu zwiększenia wszechstronności modułu przy zachowaniu minimalnego interfejsu. +4. **Standaryzacja nazewnictwa wyjścia z `ext.prefix`** w celu promowania spójności. +5. **Centralizacja konfiguracji publikowania** w celu promowania spójności. + +Po każdym kroku uruchomimy pipeline, aby sprawdzić, czy wszystko działa zgodnie z oczekiwaniami. + +!!! warning "Katalog roboczy" + + Upewnij się, że jesteś w katalogu `core-hello` (głównym katalogu Twojego pipeline) dla wszystkich edycji plików i wykonywania poleceń w tej sekcji. + + ```bash + cd core-hello + ``` + +### 1.1. Zmiana nazwy procesu na wielkie litery + +To jest czysto stylistyczna konwencja (nie ma technicznego uzasadnienia), ale ponieważ jest to norma dla modułów nf-core, dostosujmy się. + +Musimy wprowadzić trzy zestawy zmian: + +1. Zaktualizować nazwę procesu w module +2. Zaktualizować instrukcję importu modułu w nagłówku workflow +3. Zaktualizować wywołanie procesu i deklarację emit w treści workflow + +Zaczynajmy! + +#### 1.1.1. Aktualizacja nazwy procesu w module + +Otwórz plik modułu `cowpy.nf` (w `core-hello/modules/local/`) i zmodyfikuj nazwę procesu na wielkie litery: + +=== "Po zmianach" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +W tym przypadku zmiana na wielkie litery jest całkowicie prosta. + +Gdyby nazwa procesu składała się z kilku słów, na przykład gdybyśmy mieli proces o nazwie MyCowpyTool pierwotnie w camel case, konwencją nf-core byłoby użycie podkreślników do ich rozdzielenia, dając MY_COWPY_TOOL. + +#### 1.1.2. Aktualizacja instrukcji importu modułu + +Nazwy procesów są wrażliwe na wielkość liter, więc teraz, gdy zmieniliśmy nazwę procesu, musimy odpowiednio zaktualizować instrukcję importu modułu w nagłówku workflow pliku `hello.nf`: + +=== "Po zmianach" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Moglibyśmy użyć aliasu w instrukcji importu, aby uniknąć konieczności aktualizacji wywołań procesu, ale to nieco zniweczyłoby sens przyjęcia konwencji pisania wielkimi literami. + +#### 1.1.3. Aktualizacja wywołania procesu i deklaracji emit + +Teraz zaktualizujmy dwa odwołania do procesu w bloku workflow pliku `hello.nf`: + +=== "Po zmianach" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // wygeneruj grafikę ASCII powitań za pomocą cowpy + COWPY(CAT_CAT.out.file_out) + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // wygeneruj grafikę ASCII powitań za pomocą cowpy + cowpy(CAT_CAT.out.file_out) + + // + // Zbierz i zapisz wersje oprogramowania + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Upewnij się, że wprowadzisz **obie** zmiany, w przeciwnym razie otrzymasz błąd podczas uruchamiania. + +#### 1.1.4. Uruchomienie pipeline w celu przetestowania + +Uruchommy workflow, aby sprawdzić, czy wszystko działa poprawnie po tych zmianach. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dobrze, to działa! Teraz przejdźmy do wprowadzania bardziej znaczących zmian. + +### 1.2. Aktualizacja `COWPY` do używania krotek metadanych + +W obecnej wersji pipeline `core-hello` wyodrębniamy plik z krotki wyjściowej `CAT_CAT`, aby przekazać go do `COWPY`, jak pokazano w górnej części diagramu poniżej. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Lepiej byłoby, gdyby `COWPY` akceptował krotki metadanych bezpośrednio, umożliwiając przepływ metadanych przez workflow, jak pokazano w dolnej części diagramu. + +W tym celu będziemy musieli wprowadzić następujące zmiany: + +1. Zaktualizować definicje wejścia i wyjścia +2. Zaktualizować wywołanie procesu w workflow +3. Zaktualizować blok emit w workflow + +Po wykonaniu wszystkich tych czynności uruchomimy pipeline, aby sprawdzić, czy wszystko nadal działa jak wcześniej. + +#### 1.2.1. Aktualizacja definicji wejścia i wyjścia + +Wróć do pliku modułu `cowpy.nf` i zmodyfikuj go, aby akceptował krotki metadanych, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Jak widzisz, zmieniliśmy zarówno **główne wejście**, jak i **wyjście** na krotkę zgodną ze wzorcem `tuple val(meta), path(input_file)` wprowadzonym w Części 3 tego szkolenia. +Dla wyjścia wykorzystaliśmy również tę okazję, aby dodać `emit: cowpy_output`, nadając kanałowi wyjściowemu opisową nazwę. + +Teraz, gdy zmieniliśmy to, czego oczekuje proces, musimy zaktualizować to, co mu dostarczamy w wywołaniu procesu. + +#### 1.2.2. Aktualizacja wywołania procesu w workflow + +Dobra wiadomość jest taka, że ta zmiana uprości wywołanie procesu. +Teraz, gdy wyjście `CAT_CAT` i wejście `COWPY` mają tę samą 'kształt', tzn. oba składają się ze struktury `tuple val(meta), path(input_file)`, możemy po prostu połączyć je bezpośrednio zamiast konieczności jawnego wyodrębniania pliku z wyjścia procesu `CAT_CAT`. + +Otwórz plik workflow `hello.nf` (w `core-hello/workflows/`) i zaktualizuj wywołanie `COWPY`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // wygeneruj grafikę ASCII powitań za pomocą cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extract the file from the tuple since cowpy doesn't use metadata yet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // wygeneruj grafikę ASCII powitań za pomocą cowpy + COWPY(ch_for_cowpy, params.character) + ``` + +Teraz wywołujemy `COWPY` bezpośrednio na `CAT_CAT.out.file_out`. + +W rezultacie nie musimy już konstruować kanału `ch_for_cowpy`, więc ta linia (i jej linia komentarza) może zostać całkowicie usunięta. + +#### 1.2.3. Aktualizacja bloku emit w workflow + +Ponieważ `COWPY` teraz emituje nazwane wyjście `cowpy_output`, możemy zaktualizować blok `emit:` workflow `hello.nf`, aby z niego korzystał. + +=== "Po zmianach" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Technicznie nie jest to wymagane, ale dobrą praktyką jest odwoływanie się do nazwanych wyjść, gdy tylko jest to możliwe. + +#### 1.2.4. Uruchomienie pipeline w celu przetestowania + +Uruchommy workflow, aby sprawdzić, czy wszystko działa poprawnie po tych zmianach. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Pipeline powinien działać pomyślnie, a metadane teraz przepływają z `CAT_CAT` przez `COWPY`. + +To kończy to, co musieliśmy zrobić, aby `COWPY` obsługiwał krotki metadanych. +Teraz spójrzmy, co jeszcze możemy zrobić, aby wykorzystać wzorce modułów nf-core. + +### 1.3. Centralizacja konfiguracji argumentów narzędzia z `ext.args` + +W obecnym stanie proces `COWPY` oczekuje otrzymania wartości dla parametru `character`. +W rezultacie musimy podać wartość za każdym razem, gdy wywołujemy proces, nawet jeśli bylibyśmy zadowoleni z wartości domyślnych ustawionych przez narzędzie. +Dla `COWPY` nie jest to wprawdzie duży problem, ale dla narzędzi z wieloma opcjonalnymi parametrami może to być dość uciążliwe. + +Projekt nf-core zaleca używanie funkcji Nextflow zwanej [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) do wygodniejszego zarządzania argumentami narzędzia poprzez pliki konfiguracyjne. + +Zamiast deklarować wejścia procesu dla każdej opcji narzędzia, piszesz moduł tak, aby odwoływał się do `ext.args` w konstrukcji swojej linii poleceń. +Następnie wystarczy skonfigurować zmienną `ext.args` tak, aby zawierała argumenty i wartości, których chcesz użyć w pliku `modules.config`, który konsoliduje szczegóły konfiguracji dla wszystkich modułów. +Nextflow doda te argumenty z ich wartościami do linii poleceń narzędzia w czasie wykonywania. + +Zastosujmy to podejście do modułu `COWPY`. +Będziemy musieli wprowadzić następujące zmiany: + +1. Zaktualizować moduł `COWPY` +2. Skonfigurować `ext.args` w pliku `modules.config` +3. Zaktualizować workflow `hello.nf` + +Po wykonaniu wszystkich tych czynności uruchomimy pipeline, aby sprawdzić, czy wszystko nadal działa jak wcześniej. + +#### 1.3.1. Aktualizacja modułu `COWPY` + +Zróbmy to. +Otwórz plik modułu `cowpy.nf` (w `core-hello/modules/local/`) i zmodyfikuj go, aby odwoływał się do `ext.args`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Jak widać, wprowadziliśmy trzy zmiany. + +1. **W bloku `input:` usunęliśmy wejście `val character`.** + Od tej pory będziemy dostarczać ten argument poprzez konfigurację `ext.args`, jak opisano poniżej. + +2. **W bloku `script:` dodaliśmy linię `def args = task.ext.args ?: ''`.** + Ta linia używa operatora `?:` do określenia wartości zmiennej `args`: zawartości `task.ext.args`, jeśli nie jest pusta, lub pustego ciągu, jeśli jest. + Zauważ, że chociaż ogólnie odwołujemy się do `ext.args`, ten kod musi odwoływać się do `task.ext.args`, aby wyciągnąć konfigurację `ext.args` na poziomie modułu. + +3. **W linii poleceń zastąpiliśmy `-c "$character"` przez `$args`.** + To tutaj Nextflow wstawi wszystkie argumenty narzędzia ustawione w `ext.args` w pliku `modules.config`. + +W rezultacie interfejs modułu jest teraz prostszy: oczekuje tylko podstawowych metadanych i wejść plikowych. + +!!! note + + Operator `?:` jest często nazywany 'operatorem Elvisa', ponieważ wygląda jak twarz Elvisa Presleya z profilu, gdzie znak `?` symbolizuje falę we włosach. + +#### 1.3.2. Konfiguracja `ext.args` w pliku `modules.config` + +Teraz, gdy usunęliśmy deklarację `character` z modułu, musimy dodać ją do `ext.args` w pliku konfiguracyjnym `modules.config`. + +Konkretnie, dodamy ten mały fragment kodu do bloku `process {}`: + +```groovy title="Kod do dodania" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +Składnia `withName:` przypisuje tę konfigurację tylko do procesu `COWPY`, a `ext.args = { "-c ${params.character}" }` po prostu tworzy ciąg, który będzie zawierał wartość parametru `character`. +Zauważ użycie nawiasów klamrowych, które mówią Nextflow, aby ocenił wartość parametru w czasie wykonywania. + +Ma sens? Dodajmy to. + +Otwórz `conf/modules.config` i dodaj kod konfiguracyjny wewnątrz bloku `process {}`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Miejmy nadzieję, że możesz sobie wyobrazić, że wszystkie moduły w pipeline mają swoje `ext.args` określone w tym pliku, z następującymi korzyściami: + +- **Interfejs modułu pozostaje prosty** - Akceptuje tylko podstawowe metadane i wejścia plikowe +- **Pipeline nadal udostępnia `params.character`** - Użytkownicy końcowi nadal mogą go konfigurować jak wcześniej +- **Moduł jest teraz przenośny** - Może być ponownie użyty w innych pipeline bez oczekiwania konkretnej nazwy parametru +- Konfiguracja jest **scentralizowana** w `modules.config`, utrzymując logikę workflow czystą + +Używając pliku `modules.config` jako miejsca, w którym wszystkie pipeline centralizują konfigurację dla poszczególnych modułów, sprawiamy, że nasze moduły są bardziej wielokrotnego użytku w różnych pipeline. + +#### 1.3.3. Aktualizacja workflow `hello.nf` + +Ponieważ moduł `COWPY` nie wymaga już parametru `character` jako wejścia, musimy odpowiednio zaktualizować wywołanie workflow. + +Otwórz plik workflow `hello.nf` (w `core-hello/workflows/`) i zaktualizuj wywołanie `COWPY`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // wygeneruj grafikę ASCII powitań za pomocą cowpy + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // wygeneruj grafikę ASCII powitań za pomocą cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +Kod workflow jest teraz czystszy: nie musimy przekazywać `params.character` bezpośrednio do procesu. +Interfejs modułu jest minimalny, co czyni go bardziej przenośnym, podczas gdy pipeline nadal udostępnia jawną opcję poprzez konfigurację. + +#### 1.3.4. Uruchomienie pipeline w celu przetestowania + +Sprawdźmy, czy workflow nadal działa zgodnie z oczekiwaniami, określając inną postać, aby sprawdzić, czy konfiguracja `ext.args` działa. + +Uruchom to polecenie używając `kosh`, jednej z bardziej... enigmatycznych opcji: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Powinno to działać pomyślnie jak wcześniej. + +Sprawdźmy, czy konfiguracja `ext.args` zadziałała, sprawdzając wyjście. +Znajdź wyjście w przeglądarce plików lub użyj hasha zadania (część `38/eb29ea` w przykładzie powyżej), aby spojrzeć na plik wyjściowy: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Wyjście polecenia" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +Powinieneś zobaczyć sztukę ASCII wyświetloną z postacią `kosh`, potwierdzając, że konfiguracja `ext.args` zadziałała! + +??? info "(Opcjonalnie) Sprawdź plik polecenia" + + Jeśli chcesz zobaczyć dokładnie, jak została zastosowana konfiguracja, możesz sprawdzić plik `.command.sh`: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Zobaczysz polecenie `cowpy` z argumentem `-c kosh`: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + To pokazuje, że plik `.command.sh` został wygenerowany poprawnie na podstawie konfiguracji `ext.args`. + +Poświęć chwilę, aby pomyśleć o tym, co tutaj osiągnęliśmy. +To podejście utrzymuje interfejs modułu skoncentrowany na podstawowych danych (plikach, metadanych i wszelkich obowiązkowych parametrach dla próbki), podczas gdy opcje kontrolujące zachowanie narzędzia są obsługiwane oddzielnie poprzez konfigurację. + +Może się to wydawać niepotrzebne dla prostego narzędzia jak `cowpy`, ale może zrobić dużą różnicę dla narzędzi analizy danych, które mają wiele opcjonalnych argumentów. + +Podsumowując korzyści tego podejścia: + +- **Czysty interfejs**: Moduł koncentruje się na podstawowych wejściach danych (metadanych i plikach) +- **Elastyczność**: Użytkownicy mogą określać argumenty narzędzia poprzez konfigurację, w tym wartości specyficzne dla próbki +- **Spójność**: Wszystkie moduły nf-core stosują ten wzorzec +- **Przenośność**: Moduły mogą być ponownie użyte bez zakodowanych opcji narzędzia +- **Brak zmian w workflow**: Dodawanie lub zmiana opcji narzędzia nie wymaga aktualizacji kodu workflow + +!!! note + + System `ext.args` ma potężne dodatkowe możliwości, których nie omówiono tutaj, w tym dynamiczne przełączanie wartości argumentów na podstawie metadanych. Zobacz [specyfikacje modułów nf-core](https://nf-co.re/docs/guidelines/components/modules) po więcej szczegółów. + +### 1.4. Standaryzacja nazewnictwa wyjścia z `ext.prefix` + +Teraz, gdy daliśmy procesowi `COWPY` dostęp do metamap, możemy zacząć wykorzystywać kolejny przydatny wzorzec nf-core: nazywanie plików wyjściowych na podstawie metadanych. + +Tutaj użyjemy funkcji Nextflow zwanej `ext.prefix`, która pozwoli nam standaryzować nazewnictwo plików wyjściowych w modułach używając `meta.id` (identyfikatora zawartego w metamap), przy jednoczesnym zachowaniu możliwości indywidualnej konfiguracji modułów w razie potrzeby. + +Będzie to podobne do tego, co zrobiliśmy z `ext.args`, z kilkoma różnicami, które szczegółowo opiszemy. + +Zastosujmy to podejście do modułu `COWPY`. +Będziemy musieli wprowadzić następujące zmiany: + +1. Zaktualizować moduł `COWPY` +2. Skonfigurować `ext.prefix` w pliku `modules.config` + +(Nie są potrzebne zmiany w workflow.) + +Po wykonaniu tego uruchomimy pipeline, aby sprawdzić, czy wszystko nadal działa jak wcześniej. + +#### 1.4.1. Aktualizacja modułu `COWPY` + +Otwórz plik modułu `cowpy.nf` (w `core-hello/modules/local/`) i zmodyfikuj go, aby odwoływał się do `ext.prefix`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Jak widać, wprowadziliśmy trzy zmiany. + +1. **W bloku `script:` dodaliśmy linię `prefix = task.ext.prefix ?: "${meta.id}"`.** + Ta linia używa operatora `?:` do określenia wartości zmiennej `prefix`: zawartości `task.ext.prefix`, jeśli nie jest pusta, lub identyfikatora z metamap (`meta.id`), jeśli jest. + Zauważ, że chociaż ogólnie odwołujemy się do `ext.prefix`, ten kod musi odwoływać się do `task.ext.prefix`, aby wyciągnąć konfigurację `ext.prefix` na poziomie modułu. + +2. **W linii poleceń zastąpiliśmy `cowpy-${input_file}` przez `${prefix}.txt`.** + To tutaj Nextflow wstawi wartość `prefix` określoną przez powyższą linię. + +3. **W bloku `output:` zastąpiliśmy `path("cowpy-${input_file}")` przez `path("${prefix}.txt")`.** + To po prostu powtarza, jaka będzie ścieżka pliku zgodnie z tym, co jest napisane w linii poleceń. + +W rezultacie nazwa pliku wyjściowego jest teraz konstruowana przy użyciu rozsądnej wartości domyślnej (identyfikatora z metamap) połączonej z odpowiednim rozszerzeniem formatu pliku. + +#### 1.4.2. Konfiguracja `ext.prefix` w pliku `modules.config` + +W tym przypadku rozsądna wartość domyślna nie jest wystarczająco ekspresyjna dla naszych potrzeb; chcemy użyć niestandardowego wzorca nazewnictwa, który zawiera nazwę narzędzia, `cowpy-<id>.txt`, tak jak mieliśmy wcześniej. + +Zrobimy to, konfigurując `ext.prefix` w `modules.config`, tak jak zrobiliśmy dla parametru `character` z `ext.args`, z tym że tym razem blok `withName: 'COWPY' {}` już istnieje i musimy tylko dodać następującą linię: + +```groovy title="Kod do dodania" +ext.prefix = { "cowpy-${meta.id}" } +``` + +To skomponuje ciąg, którego chcemy. +Zauważ, że ponownie używamy nawiasów klamrowych, tym razem aby powiedzieć Nextflow, aby ocenił wartość `meta.id` w czasie wykonywania. + +Dodajmy to. + +Otwórz `conf/modules.config` i dodaj kod konfiguracyjny wewnątrz bloku `process {}`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Jeśli się zastanawiasz, zamknięcie `ext.prefix` ma dostęp do właściwego fragmentu metadanych, ponieważ konfiguracja jest oceniana w kontekście wykonywania procesu, gdzie metadane są dostępne. + +#### 1.4.3. Uruchomienie pipeline w celu przetestowania + +Sprawdźmy, czy workflow nadal działa zgodnie z oczekiwaniami. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Spójrz na wyjście w katalogu wyników. +Powinieneś zobaczyć plik wyjściowy cowpy z takim samym nazewnictwem jak wcześniej: `cowpy-test.txt`, na podstawie domyślnej nazwy partii. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Możesz zmienić konfigurację `ext.prefix` w `conf/modules.config`, aby upewnić się, że możesz zmienić wzorzec nazewnictwa bez konieczności wprowadzania jakichkolwiek zmian w module lub kodzie workflow. + +Alternatywnie możesz również spróbować uruchomić to ponownie z innym parametrem `--batch` określonym w linii poleceń, aby upewnić się, że ta część jest nadal konfigurowalna na bieżąco. + +To pokazuje, jak `ext.prefix` pozwala zachować preferowaną konwencję nazewnictwa przy jednoczesnym zachowaniu elastyczności interfejsu modułu. + +Podsumowując korzyści tego podejścia: + +- **Standaryzowane nazewnictwo**: Pliki wyjściowe są zazwyczaj nazywane przy użyciu identyfikatorów próbek z metadanych +- **Konfigurowalne**: Użytkownicy mogą zastąpić domyślne nazewnictwo w razie potrzeby +- **Spójne**: Wszystkie moduły nf-core stosują ten wzorzec +- **Przewidywalne**: Łatwo wiedzieć, jak będą nazywane pliki wyjściowe + +Całkiem dobrze, prawda? +Cóż, jest jeszcze jedna ważna zmiana, którą musimy wprowadzić, aby ulepszyć nasz moduł zgodnie z wytycznymi nf-core. + +### 1.5. Centralizacja konfiguracji publikowania + +Mogłeś zauważyć, że publikowaliśmy wyjścia do dwóch różnych katalogów: + +- **`results`** — Oryginalny katalog wyjściowy, którego używaliśmy od początku dla naszych lokalnych modułów, ustawiony indywidualnie za pomocą dyrektyw `publishDir` dla każdego modułu; +- **`core-hello-results`** — Katalog wyjściowy ustawiony za pomocą `--outdir` w linii poleceń, który otrzymywał logi nf-core i wyniki publikowane przez `CAT_CAT`. + +To jest nieuporządkowane i nieoptymalne; lepiej byłoby mieć jedną lokalizację dla wszystkiego. +Oczywiście moglibyśmy wejść do każdego z naszych lokalnych modułów i ręcznie zaktualizować dyrektywę `publishDir`, aby używała katalogu `core-hello-results`, ale co z następnym razem, gdy zdecydujemy się zmienić katalog wyjściowy? + +Posiadanie indywidualnych modułów podejmujących decyzje o publikowaniu wyraźnie nie jest właściwym podejściem, szczególnie w świecie, w którym ten sam moduł może być używany w wielu różnych pipeline przez ludzi, którzy mają różne potrzeby lub preferencje. +Chcemy mieć możliwość kontrolowania, gdzie publikowane są wyjścia na poziomie konfiguracji workflow. + +"Hej," możesz powiedzieć, "`CAT_CAT` wysyła swoje wyjścia do `--outdir`. Może powinniśmy skopiować jego dyrektywę `publishDir`?" + +Tak, to świetny pomysł. + +Tyle że nie ma dyrektywy `publishDir`. (Śmiało, spójrz na kod modułu.) + +To dlatego, że pipeline nf-core centralizują kontrolę na poziomie workflow, konfigurując `publishDir` w `conf/modules.config` zamiast w poszczególnych modułach. +Konkretnie, szablon nf-core deklaruje domyślną dyrektywę `publishDir` (ze wstępnie zdefiniowaną strukturą katalogów), która ma zastosowanie do wszystkich modułów, chyba że zostanie dostarczona nadpisująca dyrektywa. + +Czy to nie brzmi świetnie? Czy może być tak, że aby skorzystać z tej domyślnej dyrektywy, wszystko, co musimy zrobić, to usunąć obecną dyrektywę `publishDir` z naszych lokalnych modułów? + +Wypróbujmy to na `COWPY`, aby zobaczyć, co się stanie, a następnie spojrzymy na kod domyślnej konfiguracji, aby zrozumieć, jak to działa. + +Na koniec pokażemy, jak w razie potrzeby przesłonić domyślne zachowanie. + +#### 1.5.1. Usunięcie dyrektywy `publishDir` z `COWPY` + +Zróbmy to. +Otwórz plik modułu `cowpy.nf` (w `core-hello/modules/local/`) i usuń dyrektywę `publishDir`, jak pokazano poniżej. + +=== "Po zmianach" + + ```groovy title="core-hello/modules/local/cowpy.nf (fragment)" linenums="1" + #!/usr/bin/env nextflow + + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Przed zmianami" + + ```groovy title="core-hello/modules/local/cowpy.nf (fragment)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +To wszystko! + +#### 1.5.2. Uruchomienie pipeline w celu przetestowania + +Zobaczmy, co się stanie, jeśli teraz uruchomimy pipeline. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Spójrz na swój obecny katalog roboczy. +Teraz `core-hello-results` zawiera również wyjścia modułu `COWPY`. + +??? abstract "Zawartość katalogu" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Widać, że Nextflow utworzył tę hierarchię katalogów na podstawie nazw workflow i modułu. + +Kod odpowiedzialny za to znajduje się w pliku `conf/modules.config`. +Jest to domyślna konfiguracja `publishDir`, która jest częścią szablonu nf-core i ma zastosowanie do wszystkich procesów: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +To może wyglądać na skomplikowane, więc spójrzmy na każdy z trzech komponentów: + +- **`path:`** Określa katalog wyjściowy na podstawie nazwy procesu. + Pełna nazwa procesu zawarta w `task.process` obejmuje hierarchię importów workflow i modułów (takich jak `CORE_HELLO:HELLO:CAT_CAT`). + Operacje `tokenize` usuwają tę hierarchię, aby uzyskać tylko nazwę procesu, następnie biorą pierwszą część przed dowolnym podkreśleniem (jeśli dotyczy) i konwertują ją na małe litery. + To właśnie określa, że wyniki `CAT_CAT` są publikowane w `${params.outdir}/cat/`. +- **`mode:`** Kontroluje sposób publikowania plików (kopiowanie, dowiązanie symboliczne itp.). + Jest to konfigurowalne za pomocą parametru `params.publish_dir_mode`. +- **`saveAs:`** Filtruje, które pliki publikować. + Ten przykład wyklucza pliki `versions.yml`, zwracając dla nich `null`, zapobiegając ich publikowaniu. + +To zapewnia spójną logikę organizowania wyjść. + +Wyjście wygląda jeszcze lepiej, gdy wszystkie moduły w pipeline przyjmą tę konwencję, więc śmiało usuń dyrektywy `publishDir` z innych modułów w swoim pipeline. +To ustawienie domyślne zostanie zastosowane nawet do modułów, których nie modyfikowaliśmy jawnie, aby były zgodne z wytycznymi nf-core. + +To powiedziawszy, możesz zdecydować, że chcesz zorganizować swoje wejścia inaczej, a dobrą wiadomością jest to, że łatwo to zrobić. + +#### 1.5.3. Przesłonięcie wartości domyślnej + +Aby przesłonić domyślną dyrektywę `publishDir`, możesz po prostu dodać własne dyrektywy do pliku `conf/modules.config`. + +Na przykład możesz przesłonić wartość domyślną dla pojedynczego procesu za pomocą selektora `withName:`, jak w tym przykładzie, gdzie dodajemy niestandardową dyrektywę `publishDir` dla procesu 'COWPY'. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +Właściwie nie zamierzamy wprowadzać tej zmiany, ale śmiało pobaw się tym i zobacz, jaką logikę możesz zaimplementować. + +Chodzi o to, że ten system daje najlepsze z obu światów: spójność domyślnie i elastyczność w dostosowywaniu konfiguracji na żądanie. + +Podsumowując, otrzymujesz: + +- **Pojedyncze źródło prawdy**: Cała konfiguracja publikowania znajduje się w `modules.config` +- **Przydatne ustawienie domyślne**: Procesy działają gotowe do użycia bez konfiguracji dla każdego modułu +- **Łatwe dostosowanie**: Przesłoń zachowanie publikowania w konfiguracji, a nie w kodzie modułu +- **Przenośne moduły**: Moduły nie kodują na stałe lokalizacji wyjściowych + +To kończy zestaw funkcji modułów nf-core, których bezwzględnie powinieneś się nauczyć używać, ale są inne, o których możesz przeczytać w [specyfikacjach modułów nf-core](https://nf-co.re/docs/guidelines/components/modules). + +### Wnioski + +Teraz wiesz, jak dostosować lokalne moduły, aby były zgodne z konwencjami nf-core: + +- Projektuj swoje moduły tak, aby akceptowały i propagowały krotki metadanych; +- Używaj `ext.args`, aby interfejsy modułów były minimalne i przenośne; +- Używaj `ext.prefix` dla konfigurowalnego, standaryzowanego nazewnictwa plików wyjściowych; +- Przyjmij domyślną scentralizowaną dyrektywę `publishDir` dla spójnej struktury katalogu wyników. + +### Co dalej? + +Dowiedz się, jak używać wbudowanych narzędzi nf-core diff --git a/docs/pl/docs/hello_nf-core/05_input_validation.md b/docs/pl/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..d11019e4d4 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Część 5: Walidacja danych wejściowych + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej piątej części kursu szkoleniowego Hello nf-core pokażemy, jak używać wtyczki nf-schema do walidacji danych wejściowych i parametrów potoku. + +??? info "Jak rozpocząć od tej sekcji" + + Ta sekcja zakłada, że ukończyłeś [Część 4: Tworzenie modułu nf-core](./04_make_module.md) i zaktualizowałeś moduł procesu `COWPY` do standardów nf-core w swoim potoku. + + Jeśli nie ukończyłeś Części 4 lub chcesz zacząć od nowa w tej części, możesz użyć rozwiązania `core-hello-part4` jako punktu wyjścia. + Uruchom te polecenia z wnętrza katalogu `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + To da Ci potok z modułem `COWPY` już zaktualizowanym zgodnie ze standardami nf-core. + Możesz przetestować, czy działa poprawnie, uruchamiając następujące polecenie: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Rozgrzewka: Trochę kontekstu + +### 0.1. Dlaczego walidacja ma znaczenie + +Wyobraź sobie, że uruchamiasz swój potok przez dwie godziny, tylko po to, by się zawiesił, ponieważ użytkownik podał plik z niewłaściwym rozszerzeniem. Lub spędzasz godziny na debugowaniu tajemniczych błędów, tylko po to, by odkryć, że parametr był błędnie napisany. Bez walidacji danych wejściowych takie scenariusze są powszechne. + +Rozważ ten przykład: + +```console title="Bez walidacji" +$ nextflow run my-pipeline --input data.txt --output results + +...2 godziny później... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +Potok zaakceptował nieprawidłowe dane wejściowe i działał przez godziny przed awarią. Z odpowiednią walidacją: + +```console title="Z walidacją" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +Potok zawodzi natychmiast z jasnymi, działającymi komunikatami o błędach. To oszczędza czas, zasoby obliczeniowe i frustrację. + +### 0.2. Wtyczka nf-schema + +[Wtyczka nf-schema](https://nextflow-io.github.io/nf-schema/latest/) to wtyczka Nextflow, która zapewnia kompleksowe możliwości walidacji dla potoków Nextflow. +Chociaż nf-schema działa z dowolnym przepływem pracy Nextflow, jest to standardowe rozwiązanie walidacyjne dla wszystkich potoków nf-core. + +nf-schema zapewnia kilka kluczowych funkcji: + +- **Walidacja parametrów**: Waliduje parametry potoku względem `nextflow_schema.json` +- **Walidacja arkuszy próbek**: Waliduje pliki wejściowe względem `assets/schema_input.json` +- **Konwersja kanałów**: Konwertuje zwalidowane arkusze próbek na kanały Nextflow +- **Generowanie tekstu pomocy**: Automatycznie generuje wyjście `--help` z definicji schematu +- **Podsumowanie parametrów**: Wyświetla, które parametry różnią się od wartości domyślnych + +nf-schema jest następcą przestarzałej wtyczki nf-validation i używa standardu [JSON Schema Draft 2020-12](https://json-schema.org/) do walidacji. + +??? info "Czym są wtyczki Nextflow?" + + Wtyczki to rozszerzenia, które dodają nowe funkcjonalności do samego języka Nextflow. Są instalowane przez blok `plugins{}` w `nextflow.config` i mogą zapewniać: + + - Nowe funkcje i klasy, które można zaimportować (jak `samplesheetToList`) + - Nowe funkcje DSL i operatory + - Integrację z zewnętrznymi usługami + + Wtyczka nf-schema jest określona w `nextflow.config`: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Po zainstalowaniu możesz importować funkcje z wtyczek używając składni `include { functionName } from 'plugin/plugin-name'`. + +### 0.3. Dwa pliki schematu dla dwóch typów walidacji + +Potok nf-core będzie wykorzystywał dwa oddzielne pliki schematu, które odpowiadają dwóm typom walidacji: + +| Plik schematu | Cel | Waliduje | +| -------------------------- | ---------------------------- | ----------------------------------------------------- | +| `nextflow_schema.json` | Walidacja parametrów | Flagi linii poleceń: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Walidacja danych wejściowych | Zawartość arkuszy próbek i plików wejściowych | + +Oba schematy używają formatu JSON Schema, szeroko przyjętego standardu do opisywania i walidacji struktur danych. + +**Walidacja parametrów** waliduje parametry linii poleceń (flagi takie jak `--outdir`, `--batch`, `--input`): + +- Sprawdza typy parametrów, zakresy i formaty +- Zapewnia, że wymagane parametry są podane +- Waliduje, czy ścieżki plików istnieją +- Zdefiniowana w `nextflow_schema.json` + +**Walidacja danych wejściowych** waliduje strukturę arkuszy próbek i plików manifestu (pliki CSV/TSV, które opisują Twoje dane): + +- Sprawdza strukturę kolumn i typy danych +- Waliduje, czy ścieżki plików wymienione w arkuszu próbek istnieją +- Zapewnia obecność wymaganych pól +- Zdefiniowana w `assets/schema_input.json` + +!!! warning "Czego walidacja danych wejściowych NIE robi" + + Walidacja danych wejściowych sprawdza strukturę *plików manifestu* (arkusze próbek, pliki CSV), NIE zawartość rzeczywistych plików danych (FASTQ, BAM, VCF, itp.). + + Dla danych na dużą skalę walidacja zawartości plików (jak sprawdzanie integralności BAM) powinna odbywać się w procesach potoku działających na węzłach roboczych, a nie podczas etapu walidacji na maszynie orkiestrującej. + +### 0.4. Kiedy powinna nastąpić walidacja? + +```mermaid +graph LR + A[Użytkownik uruchamia potok] --> B[Walidacja parametrów] + B -->|✓ Poprawne| C[Walidacja danych wejściowych] + B -->|✗ Niepoprawne| D[Błąd: Napraw parametry] + C -->|✓ Poprawne| E[Potok wykonuje się] + C -->|✗ Niepoprawne| F[Błąd: Napraw dane wejściowe] +``` + +Walidacja powinna nastąpić **przed** uruchomieniem jakichkolwiek procesów potoku, aby zapewnić szybkie informacje zwrotne i zapobiec marnowaniu czasu obliczeniowego. + +Teraz zastosujmy te zasady w praktyce, zaczynając od walidacji parametrów. + +--- + +## 1. Walidacja parametrów (nextflow_schema.json) + +Zacznijmy od dodania walidacji parametrów do naszego potoku. To waliduje flagi linii poleceń, takie jak `--input`, `--outdir` i `--batch`. + +### 1.1. Skonfiguruj walidację, aby pominąć walidację pliku wejściowego + +Szablon potoku nf-core jest dostarczany z już zainstalowanym i skonfigurowanym nf-schema: + +- Wtyczka nf-schema jest instalowana przez blok `plugins{}` w `nextflow.config` +- Walidacja parametrów jest domyślnie włączona przez `params.validate_params = true` +- Walidacja jest wykonywana przez podprzepływ pracy `UTILS_NFSCHEMA_PLUGIN` podczas inicjalizacji potoku + +Zachowanie walidacji jest kontrolowane przez zakres `validation{}` w `nextflow.config`. + +Ponieważ najpierw będziemy pracować nad walidacją parametrów (ta sekcja) i nie skonfigurujemy schematu danych wejściowych do sekcji 2, musimy tymczasowo powiedzieć nf-schema, aby pominął walidację zawartości pliku parametru `input`. + +Otwórz `nextflow.config` i znajdź blok `validation` (około linii 246). Dodaj `ignoreParams`, aby pominąć walidację pliku wejściowego: + +=== "Po" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Ta konfiguracja mówi nf-schema, aby: + +- **`defaultIgnoreParams`**: Pominął walidację złożonych parametrów, takich jak `genomes` (ustawione przez deweloperów szablonu) +- **`ignoreParams`**: Pominął walidację zawartości pliku parametru `input` (tymczasowo; ponownie włączymy to w sekcji 2) +- **`monochromeLogs`**: Wyłączył kolorowe wyjście w komunikatach walidacji, gdy ustawione na `true` (kontrolowane przez `params.monochrome_logs`) + +!!! note "Dlaczego ignorować parametr input?" + + Parametr `input` w `nextflow_schema.json` ma `"schema": "assets/schema_input.json"`, co mówi nf-schema, aby zwalidował *zawartość* pliku CSV wejściowego względem tego schematu. + Ponieważ jeszcze nie skonfigurowaliśmy tego schematu, tymczasowo ignorujemy tę walidację. + Usuniemy to ustawienie w sekcji 2 po skonfigurowaniu schematu danych wejściowych. + +### 1.2. Zbadaj schemat parametrów + +Spójrzmy na sekcję pliku `nextflow_schema.json`, który był dołączony do naszego szablonu potoku: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +Schemat parametrów jest zorganizowany w grupy. Oto grupa `input_output_options`: + +```json title="core-hello/nextflow_schema.json (fragment)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Każde wejście opisane tutaj ma następujące kluczowe właściwości, które mogą być walidowane: + +- **`type`**: Typ danych (string, integer, boolean, number) +- **`format`**: Specjalne formaty, takie jak `file-path` lub `directory-path` +- **`exists`**: Dla ścieżek plików, sprawdź, czy plik istnieje +- **`pattern`**: Wyrażenie regularne, któremu wartość musi odpowiadać +- **`required`**: Tablica nazw parametrów, które muszą być podane +- **`mimetype`**: Oczekiwany typ MIME pliku do walidacji + +Jeśli masz bystre oko, możesz zauważyć, że parametr wejściowy `batch`, którego używaliśmy, nie jest jeszcze zdefiniowany w schemacie. +Dodamy go w następnej sekcji. + +??? info "Skąd pochodzą parametry schematu?" + + Walidacja schematu używa `nextflow.config` jako bazy dla definicji parametrów. + Parametry zadeklarowane gdzie indziej w skryptach przepływu pracy (jak w `main.nf` lub plikach modułów) **nie** są automatycznie przechwytywane przez walidator schematu. + + To oznacza, że zawsze powinieneś deklarować parametry potoku w `nextflow.config`, a następnie definiować ich reguły walidacji w `nextflow_schema.json`. + +### 1.3. Dodaj parametr batch + +Chociaż schemat jest plikiem JSON, który można edytować ręcznie, **ręczna edycja jest podatna na błędy i nie jest zalecana**. +Zamiast tego nf-core zapewnia interaktywne narzędzie GUI, które obsługuje składnię JSON Schema za ciebie i waliduje Twoje zmiany: + +```bash +nf-core pipelines schema build +``` + +Powinieneś zobaczyć coś takiego: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Wpisz `y` i naciśnij Enter, aby uruchomić interaktywny interfejs webowy. + +Twoja przeglądarka otworzy się, pokazując konstruktor schematu parametrów: + +![Interfejs konstruktora schematu](./img/schema_build.png) + +Aby dodać parametr `batch`: + +1. Kliknij przycisk **"Add parameter"** na górze +2. Użyj uchwytu przeciągania (⋮⋮), aby przenieść nowy parametr w górę do grupy "Input/output options", poniżej parametru `input` +3. Wypełnij szczegóły parametru: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: zaznacz pole wyboru + - Opcjonalnie wybierz ikonę z selektora ikon (np. `fas fa-layer-group`) + +![Dodawanie parametru batch](./img/schema_add.png) + +Gdy skończysz, kliknij przycisk **"Finished"** w prawym górnym rogu. + +Z powrotem w terminalu zobaczysz: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Naciśnij `Ctrl+C`, aby wyjść z konstruktora schematu. + +Narzędzie zaktualizowało teraz Twój plik `nextflow_schema.json` nowym parametrem `batch`, obsługując całą składnię JSON Schema poprawnie. + +### 1.4. Zweryfikuj zmiany + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (fragment)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Powinieneś zobaczyć, że parametr `batch` został dodany do schematu z polem "required" teraz pokazującym `["input", "outdir", "batch"]`. + +### 1.5. Przetestuj walidację parametrów + +Teraz przetestujmy, czy walidacja parametrów działa poprawnie. + +Najpierw spróbuj uruchomić bez wymaganego parametru `input`: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Wyjście polecenia" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Doskonale! Walidacja wychwytuje brakujący wymagany parametr, zanim potok się uruchomi. + +Teraz spróbuj z poprawnym zestawem parametrów: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Potok powinien uruchomić się pomyślnie, a parametr `batch` jest teraz walidowany. + +### Wnioski + +Nauczyłeś się, jak używać interaktywnego narzędzia `nf-core pipelines schema build` do dodawania parametrów do `nextflow_schema.json` i widziałeś walidację parametrów w akcji. +Interfejs webowy obsługuje całą składnię JSON Schema za ciebie, ułatwiając zarządzanie złożonymi schematami parametrów bez podatnej na błędy ręcznej edycji JSON. + +### Co dalej? + +Teraz, gdy walidacja parametrów działa, dodajmy walidację dla zawartości pliku danych wejściowych. + +--- + +## 2. Walidacja danych wejściowych (schema_input.json) + +Zamierzamy dodać walidację dla zawartości naszego pliku CSV wejściowego. +Podczas gdy walidacja parametrów sprawdza flagi linii poleceń, walidacja danych wejściowych zapewnia, że dane wewnątrz pliku CSV są poprawnie ustrukturyzowane. + +### 2.1. Zrozum format greetings.csv + +Przypomnijmy sobie, jak wygląda nasze wejście: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +To prosty CSV z: + +- Trzema kolumnami (bez nagłówka) +- W każdej linii: powitanie, język i wynik +- Pierwsze dwie kolumny to ciągi tekstowe bez specjalnych wymagań formatowania +- Trzecia kolumna to liczba całkowita + +Dla naszego potoku wymagana jest tylko pierwsza kolumna. + +### 2.2. Zaprojektuj strukturę schematu + +W naszym przypadku użycia chcemy: + +1. Zaakceptować wejście CSV z co najmniej jedną kolumną +2. Traktować pierwszy element każdego wiersza jako ciąg powitania +3. Zapewnić, że powitania nie są puste i nie zaczynają się od białych znaków +4. Zapewnić, że pole języka pasuje do jednego z obsługiwanych kodów języków (en, fr, es, it, de) +5. Zapewnić, że pole wyniku jest liczbą całkowitą o wartości między 0 a 100 + +Ustrukturyzujemy to jako tablicę obiektów, gdzie każdy obiekt ma co najmniej pole `greeting`. + +### 2.3. Zaktualizuj plik schematu + +Szablon potoku nf-core zawiera domyślny `assets/schema_input.json` zaprojektowany dla danych sekwencjonowania parami końcowymi. +Musimy zastąpić go prostszym schematem dla naszego przypadku użycia powitań. + +Otwórz `assets/schema_input.json` i zastąp sekcje `properties` i `required`: + +=== "Po" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Przed" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Kluczowe zmiany: + +- **`description`**: Zaktualizowana, aby wspomnieć o "pliku powitań" +- **`properties`**: Zastąpiono `sample`, `fastq_1` i `fastq_2` przez `greeting`, `language` i `score` + - **`type:`** Wymusza albo string (`greeting`, `language`), albo integer (`score`) + - **`pattern: "^\\S.*$"`**: Powitanie musi zaczynać się od znaku niebędącego białym znakiem (ale może zawierać spacje później) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: Kod języka musi być w obsługiwanym zestawie + - **`"minimum": 0` i `"maximum": 100`**: Wartość wyniku musi być między 0 a 100 + - **`errorMessage`**: Niestandardowy komunikat o błędzie pokazywany, jeśli walidacja się nie powiedzie +- **`required`**: Zmieniono z `["sample", "fastq_1"]` na `["greeting"]` + +### 2.4. Dodaj nagłówek do pliku greetings.csv + +Gdy nf-schema odczytuje plik CSV, oczekuje, że pierwszy wiersz będzie zawierał nagłówki kolumn, które pasują do nazw pól w schemacie. + +W naszym prostym przypadku musimy dodać linię nagłówka do naszego pliku powitań: + +=== "Po" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Przed" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Teraz plik CSV ma linię nagłówka, która pasuje do nazw pól w naszym schemacie. + +Ostatnim krokiem jest wdrożenie walidacji w kodzie potoku używając `samplesheetToList`. + +### 2.5. Wdróż walidację w potoku + +Teraz musimy zastąpić nasze proste parsowanie CSV funkcją `samplesheetToList` z nf-schema, która zwaliduje i sparsuje arkusz próbek. + +Funkcja `samplesheetToList`: + +1. Odczytuje wejściowy arkusz próbek (CSV, TSV, JSON lub YAML) +2. Waliduje go względem dostarczonego schematu JSON +3. Zwraca listę Groovy, gdzie każdy wpis odpowiada wierszowi +4. Rzuca pomocne komunikaty o błędach, jeśli walidacja się nie powiedzie + +Zaktualizujmy kod obsługi wejścia: + +Otwórz `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` i zlokalizuj sekcję, gdzie tworzymy kanał wejściowy (około linii 80). + +Musimy: + +1. Użyć funkcji `samplesheetToList` (już zaimportowana w szablonie) +2. Zwalidować i sparsować wejście +3. Wyodrębnić tylko ciągi powitań dla naszego przepływu pracy + +Najpierw zauważ, że funkcja `samplesheetToList` jest już zaimportowana na górze pliku (szablon nf-core zawiera to domyślnie): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subworkflow z funkcjonalnością specyficzną dla pipeline'u core/hello +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Teraz zaktualizuj kod tworzenia kanału: + +=== "Po" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Utwórz kanał z pliku wejściowego podanego przez params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Przed" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Utwórz kanał z pliku wejściowego podanego przez params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Rozłóżmy, co się zmieniło: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Waliduje plik wejściowy względem naszego schematu i zwraca listę +2. **`Channel.fromList(...)`**: Konwertuje listę na kanał Nextflow + +To kończy implementację walidacji danych wejściowych używając `samplesheetToList` i schematów JSON. + +Teraz, gdy skonfigurowaliśmy schemat danych wejściowych, możemy usunąć tymczasowe ustawienie ignorowania, które dodaliśmy wcześniej. + +### 2.6. Ponownie włącz walidację wejścia + +Otwórz `nextflow.config` i usuń linię `ignoreParams` z bloku `validation`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Teraz nf-schema będzie walidował zarówno typy parametrów, JAK I zawartość pliku wejściowego. + +### 2.7. Przetestuj walidację wejścia + +Zweryfikujmy, że nasza walidacja działa, testując zarówno poprawne, jak i niepoprawne wejścia. + +#### 2.7.1. Przetestuj z poprawnym wejściem + +Najpierw potwierdź, że potok uruchamia się pomyślnie z poprawnym wejściem. +Zauważ, że nie potrzebujemy już `--validate_params false`, ponieważ walidacja działa! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Wyjście polecenia" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Świetnie! Potok uruchamia się pomyślnie, a walidacja przechodzi po cichu. +Ostrzeżenie o `--character` jest tylko informacyjne, ponieważ nie jest zdefiniowane w schemacie. +Jeśli chcesz, użyj tego, czego się nauczyłeś, aby dodać walidację również dla tego parametru! + +#### 2.7.2. Przetestuj z niepoprawnym wejściem + +Przejście walidacji zawsze daje dobre uczucie, ale upewnijmy się, że walidacja rzeczywiście wychwytuje błędy. + +Aby utworzyć plik testowy z niepoprawną nazwą kolumny, zacznij od skopiowania pliku `greetings.csv`: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Teraz otwórz plik i zmień nazwę pierwszej kolumny, w linii nagłówka, z `greeting` na `message`: + +=== "Po" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Przed" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +To nie pasuje do naszego schematu, więc walidacja powinna zgłosić błąd. + +Spróbuj uruchomić potok z tym niepoprawnym wejściem: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Doskonale! Walidacja wykryła błąd i dostarczyła jasny, pomocny komunikat o błędzie wskazujący na: + +- Który plik nie przeszedł walidacji +- Który wpis (wiersz 1, pierwszy wiersz danych) ma problem +- Jaki jest konkretny problem (brakujące wymagane pole `greeting`) + +Walidacja schematu zapewnia, że pliki wejściowe mają poprawną strukturę, zanim potok się uruchomi, oszczędzając czas i zapobiegając mylącym błędom później podczas wykonywania. + +Jeśli chcesz to przećwiczyć, śmiało twórz inne pliki wejściowe powitań, które naruszają schemat na inne zabawne sposoby. + +### Wnioski + +Zaimplementowałeś i przetestowałeś zarówno walidację parametrów, jak i walidację danych wejściowych. Twój potok waliduje teraz wejścia przed wykonaniem, zapewniając szybkie informacje zwrotne i jasne komunikaty o błędach. + +!!! tip "Dalsze czytanie" + + Aby dowiedzieć się więcej o zaawansowanych funkcjach i wzorcach walidacji, sprawdź [dokumentację nf-schema](https://nextflow-io.github.io/nf-schema/latest/). Polecenie `nf-core pipelines schema build` zapewnia interaktywny GUI do zarządzania złożonymi schematami. + +### Co dalej? + +Ukończyłeś wszystkie pięć części kursu szkoleniowego Hello nf-core! + +Przejdź do [Podsumowania](summary.md), aby zastanowić się nad tym, co zbudowałeś i czego się nauczyłeś. diff --git a/docs/pl/docs/hello_nf-core/index.md b/docs/pl/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..420e00c519 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Pobierać, uruchamiać i zarządzać wykonywaniem pipeline'ów nf-core + - Opisywać strukturę kodu i organizację projektów pipeline'ów nf-core + - Tworzyć podstawowy pipeline kompatybilny z nf-core na podstawie szablonu + - Uaktualniać prosty workflow Nextflow do standardów nf-core + - Dodawać moduły nf-core do pipeline'u kompatybilnego z nf-core + - Współtworzyć własne moduły dla nf-core + - Walidować dane wejściowe i parametry przy użyciu narzędzi nf-core + audience_prerequisites: + - "**Odbiorcy:** Ten kurs jest przeznaczony dla osób, które są już zaznajomione z podstawami Nextflow i chcą nauczyć się korzystać z zasobów i najlepszych praktyk nf-core." + - "**Umiejętności:** Zakłada się znajomość wiersza poleceń, podstawowych koncepcji skryptowania oraz popularnych formatów plików." + - "**Kursy:** Wymagane jest ukończenie kursu [Hello Nextflow](../hello_nextflow/index.md) lub równoważnego." + - "**Dziedzina:** Wszystkie ćwiczenia są niezależne od dziedziny, więc nie jest wymagana wcześniejsza wiedza naukowa." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core to praktyczne wprowadzenie do korzystania z zasobów i najlepszych praktyk nf-core.** + +![nf-core logo](./img/nf-core-logo.png) + +Pracując nad praktycznymi przykładami i prowadzonymi ćwiczeniami, nauczysz się używać i rozwijać moduły i pipeline'y kompatybilne z nf-core oraz efektywnie wykorzystywać narzędzia nf-core. + +Wyniesiesz umiejętności i pewność siebie, aby zacząć rozwijać pipeline'y zgodnie z najlepszymi praktykami nf-core. + +<!-- additional_information --> + +## Przegląd kursu + +Ten kurs został zaprojektowany jako praktyczny, z ćwiczeniami zorientowanymi na cel, ustrukturyzowanymi tak, aby stopniowo wprowadzać informacje. + +Zostaniesz zapoznany z [**nf-core**](https://nf-co.re/), inicjatywą społeczności mającą na celu rozwój i utrzymanie wyselekcjonowanego zestawu naukowych pipeline'ów zbudowanych przy użyciu Nextflow, a także odpowiednich narzędzi i wytycznych promujących otwartą współpracę, testowanie i przeglądy kodu ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +Pipeline'y opracowane przez społeczność nf-core zostały zaprojektowane jako modułowe, skalowalne i przenośne, pozwalając badaczom na łatwe dostosowanie i wykonanie ich przy użyciu własnych danych i zasobów obliczeniowych. +Wytyczne dotyczące najlepszych praktyk egzekwowane przez projekt dodatkowo zapewniają, że pipeline'y są niezawodne, dobrze udokumentowane i zwalidowane na rzeczywistych zestawach danych. +Pomaga to zwiększyć niezawodność i odtwarzalność analiz naukowych i ostatecznie umożliwia badaczom przyspieszenie ich odkryć naukowych. + +Nie omówimy wszystkiego, co można wiedzieć o pipeline'ach nf-core w tym kursie, ponieważ nf-core obejmuje wiele funkcji i konwencji opracowanych przez społeczność przez lata. +Zamiast tego skupimy się na podstawowych koncepcjach, które pomogą Ci zacząć i zrozumieć, jak działa nf-core. + +### Plan lekcji + +Podzieliliśmy to na pięć części, z których każda skupi się na określonych aspektach korzystania z zasobów nf-core. + +| Rozdział kursu | Podsumowanie | Szacowany czas | +| --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Część 1: Uruchomienie demo pipeline](./01_run_demo.md) | Uruchomienie istniejącego pipeline'u nf-core i zbadanie jego struktury kodu, aby uzyskać wyobrażenie o tym, co wyróżnia te pipeline'y od podstawowych workflow'ów Nextflow | 30 min | +| [Część 2: Przepisanie Hello dla nf-core](./02_rewrite_hello.md) | Dostosowanie istniejącego workflow do szkieletu szablonu nf-core, zaczynając od prostego workflow utworzonego w kursie [Hello Nextflow](../hello_nextflow/index.md) | 60 min | +| [Część 3: Użycie modułu nf-core](./03_use_module.md) | Eksploracja biblioteki modułów społeczności i nauka integrowania gotowych, przetestowanych modułów opakowujących popularne narzędzia bioinformatyczne | 30 min | +| [Część 4: Stworzenie modułu nf-core](./04_make_module.md) | Tworzenie własnego modułu w stylu nf-core przy użyciu określonej struktury, konwencji nazewnictwa i wymagań dotyczących metadanych ustanowionych przez nf-core | 30 min | +| [Część 5: Dodanie walidacji wejścia](./05_input_validation.md) | Implementacja walidacji wejścia zarówno dla parametrów wiersza poleceń, jak i plików danych wejściowych przy użyciu nf-schema | 30 min | + +Pod koniec tego kursu będziesz w stanie wykorzystać ogromne bogactwo zasobów oferowanych przez projekt nf-core. + +Gotowy rozpocząć kurs? + +[Rozpocznij naukę :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/pl/docs/hello_nf-core/next_steps.md b/docs/pl/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..42f17c28e9 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Podsumowanie kursu + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gratulacje ukończenia kursu szkoleniowego Hello nf-core! 🎉 + +<!-- placeholder for video --> + +## Twoja podróż + +Zacząłeś od nauki pobierania i uruchamiania demonstracyjnego pipeline, a następnie zajęłeś się konwersją prostego workflow Nextflow na pipeline nf-core. +Nauczyłeś się tworzyć szkielet pipeline przy użyciu szablonu i przeszczepiać istniejący pipeline na ten szkielet. +Następnie stopniowo udoskonalałeś pipeline, zastępując jeden z lokalnych modułów modułem nf-core, przekształcając kolejny z lokalnych modułów tak, aby odpowiadał standardom nf-core, i dodając walidację wejścia. + +### Co zbudowałeś + +Twój końcowy pipeline `core-hello` ma teraz: + +- **Ustandaryzowaną strukturę** wykorzystującą szablon nf-core z uporządkowanymi katalogami dla workflows, subworkflows, modułów i konfiguracji +- **Moduły społecznościowe** z repozytorium nf-core (`cat/cat`) obok Twoich niestandardowych modułów +- **Kompleksową walidację**, która sprawdza zarówno parametry, jak i dane wejściowe przed uruchomieniem pipeline +- **Profesjonalną konfigurację** z profilami dla różnych środowisk wykonawczych +- **Kompletną dokumentację** i metadane zgodne z konwencjami nf-core + +### Nabyte kluczowe umiejętności + +Dzięki temu praktycznemu kursowi nauczyłeś się: + +1. **Nawigować i rozumieć** strukturę pipeline nf-core, eksplorując istniejący pipeline +2. **Restrukturyzować workflows**, aby były kompatybilne i pasowały do szablonu nf-core +3. **Znajdować i integrować** gotowe moduły z repozytorium społecznościowego +4. **Tworzyć niestandardowe moduły** zgodnie ze standardami nf-core dotyczącymi nazewnictwa, struktury i metadanych +5. **Implementować walidację** przy użyciu nf-schema, aby wcześnie wychwytywać błędy z jasnymi komunikatami + +Jesteś teraz wyposażony w podstawową wiedzę, aby budować gotowe do produkcji pipeline nf-core, które przestrzegają najlepszych praktyk społeczności. + +## Kolejne kroki rozwoju umiejętności + +Oto nasze 3 najlepsze sugestie, co zrobić dalej: + +- Zastosuj Nextflow do naukowego przypadku analizy z [Nextflow for Science](../nf4_science/index.md) +- Poznaj bardziej zaawansowane funkcje Nextflow dzięki [Side Quests](../side_quests/index.md) +- Zaangażuj się, [dołączając do społeczności nf-core](https://nf-co.re/join). + +Na koniec zalecamy zapoznanie się z [**Seqera Platform**](https://seqera.io/), platformą chmurową opracowaną przez twórców Nextflow, która ułatwia uruchamianie i zarządzanie Twoimi workflows, a także zarządzanie danymi i przeprowadzanie analiz interaktywnie w dowolnym środowisku. + +## Ankieta opinii + +Zanim przejdziesz dalej, poświęć chwilę na wypełnienie ankiety kursu! Twoja opinia pomaga nam ulepszać nasze materiały szkoleniowe dla wszystkich. + +[Wypełnij ankietę :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pl/docs/hello_nf-core/survey.md b/docs/pl/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..3268655514 --- /dev/null +++ b/docs/pl/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Ankieta zwrotna + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Zanim przejdziesz dalej, wypełnij tę krótką ankietę składającą się z 5 pytań, aby ocenić szkolenie, podzielić się swoimi uwagami na temat Twoich doświadczeń i dać nam znać, co jeszcze możemy zrobić, aby pomóc Ci w Twojej podróży z Nextflow. + +Wypełnienie powinno zająć Ci mniej niż minutę. Dziękujemy za pomoc w ulepszaniu naszych materiałów szkoleniowych dla wszystkich! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pl/docs/help.md b/docs/pl/docs/help.md new file mode 100644 index 0000000000..bc7a9c8c1e --- /dev/null +++ b/docs/pl/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Uzyskiwanie pomocy +description: Przydatne zasoby, gdy masz problem ze szkoleniem Nextflow +hide: + - toc + - footer +--- + +# Uzyskiwanie pomocy + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Niezależnie od tego, czy masz trudności z rozpoczęciem, utknąłeś w połowie drogi czy masz pytania uzupełniające, nie wahaj się skontaktować! Nasz zespół społecznościowy jest tu, aby pomóc, a społeczność Nextflow jest bardzo aktywna, otwarta i chętna do pomocy. + +Oto główne dostępne opcje w zależności od tego, czego szukasz. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Forum społecznościowe__ + + --- + + Nasze forum społecznościowe ma kategorię poświęconą szkoleniom, która jest doskonałym miejscem do zadawania pytań lub zgłaszania problemów ze szkoleniem. Możesz nawet odkryć, że Twoje pytanie zostało już zadane — i udzielono na nie odpowiedzi! + + [Dołącz do forum szkoleniowego :material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Kanał Slack__ + + --- + + Jeśli korzystasz ze Slacka, możesz skontaktować się z nami na kanale szkoleniowym w przestrzeni roboczej Nextflow Slack. Slack Nextflow to świetne miejsce do rozmów z innymi programistami i angażowania się w społeczność Nextflow. + + [Dołącz do Slack Nextflow :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Issues na GitHub__ + + --- + + Jeśli zauważysz błąd w materiałach szkoleniowych, zgłoś go, otwierając issue w repozytorium GitHub. Niezależnie od tego, czy to literówka, problem z formatowaniem czy faktyczny błąd wpływający na kod, daj nam znać, abyśmy mogli to naprawić! Przyjmujemy również bezpośrednie PR-y. + + [Zgłoś problem :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Asystent AI Seqera__ + + --- + + Seqera AI to asystent AI przeszkolony na zasobach Nextflow i nf-core. Może pomóc Ci debugować kod, wyjaśniać koncepcje Nextflow i szybciej przeszukiwać dokumentację. Potraktuj go jako korepetytora dostępnego 24/7 podczas pracy z kursami. + + [Zapytaj Seqera AI :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Dokumentacja Nextflow__ + + --- + + Oficjalna dokumentacja to ostateczny przewodnik po wszystkich funkcjach języka i opcjach konfiguracji. Korzystaj z niej równolegle z tym szkoleniem, aby zgłębiać konkretne tematy, odkrywać zaawansowane funkcje i znajdować szczegółowe odniesienia do składni. + + [Przeglądaj dokumentację :material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Profesjonalne wsparcie__ + + --- + + Nextflow to darmowe oprogramowanie open-source tworzone przez [Seqera](https://seqera.io/), firmę z siedzibą w Hiszpanii z biurami satelitarnymi w Wielkiej Brytanii i USA. Oferujemy profesjonalne usługi wsparcia dla Nextflow, w tym szkolenia na zamówienie. + + [Skontaktuj się :material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pl/docs/index.md b/docs/pl/docs/index.md new file mode 100644 index 0000000000..73285dd5f8 --- /dev/null +++ b/docs/pl/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Strona główna +description: Witamy w portalu szkoleniowym społeczności Nextflow! +hide: + - toc + - footer +--- + +# Szkolenie Nextflow + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Kursy do samodzielnej nauki__ + + --- + + **Witamy w portalu szkoleniowym społeczności Nextflow!** + + Poniższe kursy szkoleniowe są zaprojektowane jako materiały do samodzielnej nauki. + Możesz przerabiać je we własnym tempie w dowolnym czasie, korzystając ze środowiska internetowego, które udostępniamy przez GitHub Codespaces, lub we własnym środowisku. + + [Przeglądaj kursy :material-arrow-right:](#katalog-kursow-szkoleniowych-nextflow){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Dodatkowe informacje__ + + --- + + ??? warning "Kompatybilność wersji" + + <!-- Any update to this content needs to be copied to the local installation page --> + **Od stycznia 2026 roku wszystkie nasze kursy szkoleniowe Nextflow wymagają wersji Nextflow 25.10.2 lub nowszej, z włączoną ścisłą składnią, chyba że zaznaczono inaczej.** + + Więcej informacji o wymaganiach wersji i ścisłej składni znajdziesz w [przewodniku migracji dokumentacji Nextflow](https://nextflow.io/docs/latest/strict-syntax.html). + + Starsze wersje materiałów szkoleniowych odpowiadające wcześniejszej składni są dostępne poprzez selektor wersji w pasku menu tej strony. + + ??? terminal "Opcje środowiska" + + Udostępniamy internetowe środowisko szkoleniowe, w którym wszystko, czego potrzebujesz do szkolenia, jest preinstalowane, dostępne przez GitHub Codespaces (wymaga darmowego konta GitHub). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Jeśli to nie odpowiada Twoim potrzebom, zapoznaj się z innymi [opcjami środowiska](./envsetup/index.md). + + ??? learning "Wydarzenia szkoleniowe" + + Jeśli wolisz uczestniczyć w szkoleniu Nextflow w ramach zorganizowanego wydarzenia, istnieje wiele możliwości. Polecamy sprawdzić następujące opcje: + + - **[Tygodnie szkoleniowe]()** organizowane kwartalnie przez zespół społeczności + - **[Wydarzenia Seqera](https://seqera.io/events/)** obejmują wydarzenia szkoleniowe organizowane przez Seqera (szukaj 'Seqera Sessions' i 'Nextflow Summit') + - **[Ambasadorzy Nextflow]()** organizują wydarzenia dla swojej lokalnej społeczności + - **[Wydarzenia nf-core](https://nf-co.re/events)** obejmują hackathony społecznościowe + + ??? people "Informacje dla prowadzących szkolenia" + + Jeśli jesteś instruktorem prowadzącym własne szkolenia, możesz korzystać z naszych materiałów bezpośrednio z portalu szkoleniowego, pod warunkiem podania odpowiedniego źródła. Szczegóły znajdziesz w sekcji 'Licencja i polityka współpracy' poniżej. + + Ponadto chętnie dowiemy się, jak moglibyśmy lepiej wspierać Twoje działania szkoleniowe! Skontaktuj się z nami pod adresem [community@seqera.io](mailto:community@seqera.io) lub na forum społecznościowym (zobacz stronę [Pomoc](help.md)). + + ??? licensing "Licencja open-source i polityka współpracy" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Te materiały szkoleniowe są tworzone i utrzymywane przez [Seqera](https://seqera.io) i udostępniane na licencji open-source ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) dla dobra społeczności. Jeśli chcesz wykorzystać te materiały w sposób wykraczający poza zakres licencji (zwróć uwagę na ograniczenia dotyczące użytku komercyjnego i redystrybucji), skontaktuj się z nami pod adresem [community@seqera.io](mailto:community@seqera.io), aby omówić swoją prośbę. + + Z przyjemnością przyjmujemy ulepszenia, poprawki i zgłoszenia błędów od społeczności. Każda strona ma ikonę :material-file-edit-outline: w prawym górnym rogu, która prowadzi do repozytorium kodu, gdzie możesz zgłaszać problemy lub proponować zmiany w materiałach szkoleniowych poprzez pull request. Więcej szczegółów znajdziesz w pliku `README.md` w repozytorium. + +</div> + +!!! note "Tłumaczenie wspomagane przez AI" + + To tłumaczenie zostało utworzone przy użyciu sztucznej inteligencji i zweryfikowane przez ludzkich tłumaczy. + Zachęcamy do przekazywania opinii i sugestii ulepszeń. + Więcej informacji znajdziesz w naszym [przewodniku tłumaczenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md). + +## Katalog kursów szkoleniowych Nextflow + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Ścieżka wprowadzająca__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow dla początkujących {.mt-1} + + Kursy niezależne od dziedziny, przeznaczone dla osób, które są całkowicie nowe w Nextflow. Każdy kurs składa się z serii modułów szkoleniowych zaprojektowanych tak, aby pomagać uczącym się stopniowo rozwijać swoje umiejętności. + + ??? courses "**Hello Nextflow:** Naucz się tworzyć własne pipeline'y" + + Ten kurs obejmuje podstawowe komponenty języka Nextflow w wystarczającym szczegółach, aby umożliwić tworzenie prostych, ale w pełni funkcjonalnych pipeline'ów, a także kluczowe elementy projektowania, tworzenia i konfigurowania pipeline'ów. + + [Rozpocznij szkolenie Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Naucz się uruchamiać istniejące pipeline'y" + + Zwięzłe wprowadzenie do uruchamiania i konfigurowania pipeline'ów Nextflow, oparte na kursie Hello Nextflow dla programistów, ale z mniejszym naciskiem na kod. Obejmuje wykonywanie, wyjścia, podstawową strukturę kodu i konfigurację dla różnych środowisk obliczeniowych. + + [Rozpocznij szkolenie Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow dla nauki {.mt-1} + + Naucz się stosować koncepcje i komponenty przedstawione w 'Hello Nextflow' do konkretnych zastosowań naukowych. + + ??? courses "**Nextflow dla genomiki** (wykrywanie wariantów)" + + Dla badaczy, którzy chcą nauczyć się tworzyć własne pipeline'y genomiczne. Kurs wykorzystuje przypadek wykrywania wariantów, aby pokazać, jak tworzyć prosty, ale funkcjonalny pipeline genomiczny. + + [Rozpocznij szkolenie Nextflow dla genomiki :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow dla RNAseq** (bulk RNAseq)" + + Dla badaczy, którzy chcą nauczyć się tworzyć własne pipeline'y RNAseq. Kurs wykorzystuje przypadek przetwarzania bulk RNAseq, aby pokazać, jak tworzyć prosty, ale funkcjonalny pipeline RNAseq. + + [Rozpocznij szkolenie Nextflow dla RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow dla obrazowania** (spatial omics)" + + Dla badaczy zajmujących się obrazowaniem i spatial omics, którzy chcą nauczyć się uruchamiać i dostosowywać pipeline'y analityczne. Kurs wykorzystuje pipeline nf-core/molkart, aby zapewnić biologicznie istotny pipeline demonstrujący, jak uruchamiać, konfigurować i zarządzać wejściami dla workflow'ów Nextflow. + + [Rozpocznij szkolenie Nextflow dla obrazowania :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Ścieżka zaawansowana__ + + --- + + ### :material-bridge:{.nextflow-primary} Od Nextflow do nf-core {.mt-1} + + Naucz się wykorzystywać kod i najlepsze praktyki z projektu społeczności [nf-core](https://nf-co.re/). + + Te kursy pomagają przejść od podstaw Nextflow do najlepszych praktyk nf-core. + Zrozum, jak i dlaczego społeczność nf-core buduje pipeline'y, oraz jak możesz współtworzyć i ponownie wykorzystywać te techniki. + + ??? courses "**Hello nf-core:** Rozpocznij pracę z nf-core" + + Dla programistów, którzy chcą nauczyć się uruchamiać i tworzyć pipeline'y zgodne z [nf-core](https://nf-co.re/). Kurs obejmuje strukturę pipeline'ów nf-core w wystarczającym szczegółach, aby umożliwić tworzenie prostych, ale w pełni funkcjonalnych pipeline'ów zgodnych z szablonem nf-core i najlepszymi praktykami deweloperskimi, a także wykorzystywanie istniejących modułów nf-core. + + [Rozpocznij szkolenie Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Zaawansowane szkolenie Nextflow {.mt-1} + + Poznaj zaawansowane koncepcje i mechanizmy tworzenia i wdrażania pipeline'ów Nextflow dla rzeczywistych przypadków użycia. + + ??? courses "**Side Quests:** Głębokie zanurzenia w samodzielne tematy" + + Samodzielne mini-kursy przeznaczone dla programistów Nextflow, którzy chcą poszerzyć swój zakres i/lub pogłębić umiejętności w określonych tematach. Są przedstawione liniowo, ale można je realizować w dowolnej kolejności (zobacz zależności w przeglądzie każdego mini-kursu). + + [Przeglądaj Side Quests :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Kolekcje szkoleniowe:** Polecane ścieżki nauki przez Side Quests" + + Kolekcje szkoleniowe łączą wiele Side Quests, aby zapewnić kompleksowe doświadczenie edukacyjne wokół określonego tematu lub przypadku użycia. + + [Przeglądaj kolekcje szkoleniowe :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Szukasz zarchiwizowanych materiałów szkoleniowych?" + + Starsze materiały szkoleniowe (Fundamentals Training, Advanced Training i inne eksperymentalne kursy) zostały usunięte z portalu szkoleniowego, ponieważ są niekompatybilne ze ścisłą składnią Nextflow 3.0. + Jeśli potrzebujesz dostępu do tych materiałów, są one dostępne w [historii git](https://github.com/nextflow-io/training) sprzed stycznia 2026 roku. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pl/docs/info/conventions.md b/docs/pl/docs/info/conventions.md new file mode 100644 index 0000000000..8d88c4db31 --- /dev/null +++ b/docs/pl/docs/info/conventions.md @@ -0,0 +1 @@ +Używamy prefiksu `ch_` dla wszystkich zmiennych kanałów, aby wyraźnie wskazać, że są to kanały Nextflow. diff --git a/docs/pl/docs/info/hello_pipeline.md b/docs/pl/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..b2cbb6ca09 --- /dev/null +++ b/docs/pl/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Pipeline Hello +description: Podsumowanie działania pipeline'u Hello i jego struktury. +hide: + - toc + - footer +--- + +# Pipeline Hello + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Większość naszych kursów szkoleniowych używa prostego, domenowo-agnostycznego pipeline'u do demonstracji koncepcji i mechanizmów Nextflow. +Kurs Hello Nextflow pokazuje, jak rozwijać ten pipeline krok po kroku, wyjaśniając każdą decyzję projektową i implementacyjną. +Inne szkolenia używają tego pipeline'u lub jego części jako punktu wyjścia. + +Ta strona podsumowuje stan pipeline'u po ukończeniu kursu Hello Nextflow. + +### Krótki opis + +Workflow Hello przyjmuje plik CSV zawierający pozdrowienia, zapisuje je do oddzielnych plików, konwertuje każde na wielkie litery, zbiera je z powrotem razem i generuje pojedynczy plik tekstowy zawierający obrazek ASCII zabawnej postaci wypowiadającej pozdrowienia. + +### Kroki workflow (procesy) + +Cztery kroki są zaimplementowane jako procesy Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` i `cowpy`) przechowywane w oddzielnych plikach modułów. + +1. **`sayHello`:** Zapisuje każde pozdrowienie do własnego pliku wyjściowego (np. "Hello-output.txt") +2. **`convertToUpper`:** Konwertuje każde pozdrowienie na wielkie litery (np. "HELLO") +3. **`collectGreetings`:** Zbiera wszystkie pozdrowienia wielkimi literami do pojedynczego pliku wsadowego +4. **`cowpy`:** Generuje grafikę ASCII za pomocą narzędzia `cowpy` + +### Diagram + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Wyniki + +Wyniki są publikowane do katalogu o nazwie `results/`, a końcowe wyjście pipeline'u (przy uruchomieniu z domyślnymi parametrami) to plik tekstowy zawierający grafikę ASCII indyka wypowiadającego pozdrowienia wielkimi literami. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Możesz napotkać pewne różnice w szczegółach w zależności od kursu, w którym pipeline jest prezentowany. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pl/docs/info/nxf_versions.md b/docs/pl/docs/info/nxf_versions.md new file mode 100644 index 0000000000..3fb7602c45 --- /dev/null +++ b/docs/pl/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Wersje Nextflow +description: Zrozumienie i zarządzanie ewolucją wersji składni Nextflow +hide: + - toc + - footer +--- + +## Aktualnie obsługiwana wersja składni Nextflow i wymagania + +Od wersji 3.0 portalu szkoleniowego wszystkie nasze kursy opierają się na wersji 25.10.2 Nextflow, chyba że na stronie indeksu kursu podano inaczej (z wyjątkiem przestarzałych lub zarchiwizowanych materiałów, które mogą nie zawierać informacji o wersji). + +Ponieważ kursy używają teraz typowanych wejść na poziomie workflow oraz dyrektyw wyjściowych na poziomie workflow, wymagają użycia parsera składni V2. +Jeśli planujesz korzystać ze środowiska, które udostępniamy poprzez [Github Codespaces](../envsetup/01_setup.md) lub [lokalne devcontainers](../envsetup/03_devcontainer.md), nie musisz nic robić, chyba że w instrukcjach kursu zaznaczono inaczej. +Jednak jeśli planujesz pracować przez szkolenia we własnym środowisku ([Instalacja ręczna](../envsetup/02_local.md)), musisz upewnić się, że używasz Nextflow w wersji 25.10.2 lub nowszej z włączonym parserem składni v2. + +## Starsze wersje materiałów szkoleniowych + +Nasze materiały szkoleniowe są wersjonowane od lutego 2025 roku. + +Możesz uzyskać dostęp do starszych wersji materiałów szkoleniowych, które działają z wersjami Nextflow **przed 25.10.2** poprzez menu rozwijane na górze każdej strony, które pokazuje numerowaną wersję materiałów szkoleniowych. +Gdy wybierzesz starszą wersję materiałów szkoleniowych, linki do środowiska szkoleniowego automatycznie określą odpowiednią wersję środowiska. + +## Inne informacje o wersjach składni Nextflow + +Nextflow ma dwie odrębne koncepcje wersjonowania, które są czasami mylone: **wersje DSL** i **wersje parsera składni**. + +**DSL1 vs DSL2** odnosi się do zasadniczo różnych sposobów pisania pipeline'ów Nextflow. +DSL1 był oryginalną składnią, gdzie procesy były niejawnie połączone przez channels. +DSL2, wprowadzony w Nextflow 20.07, dodał funkcje modularności: możliwość importowania procesów i workflows z innych plików, jawne bloki `workflow` oraz nazwane wyjścia procesów. +DSL1 został oznaczony jako przestarzały w Nextflow 22.03 i usunięty w 22.12. +Cały nowoczesny kod Nextflow używa DSL2. + +**Parser składni v1 vs v2** odnosi się do różnych parserów, które oba działają z kodem DSL2. +Parser v1 to oryginalny, bardziej tolerancyjny parser. +Parser v2 jest bardziej rygorystyczny i umożliwia nowe funkcje języka, takie jak statyczne typowanie (typowane wejścia i wyjścia) oraz dyrektywy wyjściowe na poziomie workflow. +Parser v2 zapewnia również lepsze komunikaty o błędach i wykrywa więcej błędów podczas parsowania, a nie w czasie wykonywania. +Parser v2 stanie się domyślny w Nextflow 26.04. + +Podsumowując: DSL2 to język, który piszesz; wersja parsera składni określa, jak ściśle ten język jest interpretowany i jakie zaawansowane funkcje są dostępne. + +### Sprawdzanie i ustawianie wersji Nextflow + +Możesz sprawdzić, jaka wersja Nextflow jest zainstalowana w Twoim systemie za pomocą polecenia `nextflow --version`. + +Więcej informacji o tym, jak zaktualizować wersję Nextflow, znajdziesz w dokumentacji referencyjnej na temat [Aktualizacji Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Włączanie parsera składni v2 + +Aby **włączyć** parser składni v2 dla bieżącej sesji, uruchom następujące polecenie w terminalu: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Aby ustawić to na stałe (do czasu, gdy v2 stanie się domyślny w Nextflow 26.04), dodaj polecenie export do profilu swojej powłoki (`~/.bashrc`, `~/.zshrc`, itp.): + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Zauważ, że zmienna środowiskowa `NXF_SYNTAX_PARSER=v2` jest tymczasowym wymogiem. +Od Nextflow 26.04 parser v2 stanie się domyślny i to ustawienie nie będzie już potrzebne. + +### Wyłączanie parsera składni v2 + +Aby **wyłączyć** parser składni v2 dla bieżącej sesji, uruchom następujące polecenie w terminalu: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migracja istniejącego kodu + +Wskazówki dotyczące migracji istniejącego kodu do zgodności z nowszymi wersjami Nextflow znajdziesz w [Notatkach migracyjnych](https://www.nextflow.io/docs/latest/migrations/index.html) w dokumentacji referencyjnej. + +Te dwa artykuły są szczególnie pomocne przy migracji do najnowszej wersji: + +- [Migracja do wyjść workflow](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migracja do typów statycznych](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Obie te funkcje są omówione w ramach szkolenia dla początkujących, począwszy od wersji 3.0 materiałów szkoleniowych. + +W zależności od generacji kodu Nextflow, który zamierzasz migrować, możesz być w stanie wykonać większość pracy za pomocą lintera Nextflow używając polecenia `nextflow lint -format`. +Zobacz dokumentację CLI dla [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint), aby uzyskać więcej szczegółów. + +Mamy nadzieję, że będzie to pomocne. +Jeśli potrzebujesz pomocy, skontaktuj się na Slacku lub na forum. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pl/docs/nextflow_run/00_orientation.md b/docs/pl/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..0bc796d188 --- /dev/null +++ b/docs/pl/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Rozpoczęcie pracy + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Uruchom środowisko szkoleniowe + +Aby skorzystać z gotowego środowiska, które udostępniamy na GitHub Codespaces, kliknij przycisk "Open in GitHub Codespaces" poniżej. Inne opcje znajdziesz w sekcji [Opcje środowiska](../envsetup/index.md). + +Zalecamy otwarcie środowiska szkoleniowego w nowej karcie lub oknie przeglądarki (użyj prawego przycisku myszy, ctrl-click lub cmd-click w zależności od sprzętu), aby móc czytać instrukcje podczas ładowania środowiska. +Będziesz musiał mieć te instrukcje otwarte równolegle, aby przejść przez kurs. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Podstawy środowiska + +To środowisko szkoleniowe zawiera całe oprogramowanie, kod i dane potrzebne do pracy z kursem, więc nie musisz niczego instalować samodzielnie. + +Codespace jest skonfigurowany z interfejsem VSCode, który zawiera eksplorator systemu plików, edytor kodu i powłokę terminala. +Wszystkie instrukcje podane podczas kursu (np. 'otwórz plik', 'edytuj kod' lub 'uruchom to polecenie') odnoszą się do tych trzech części interfejsu VSCode, chyba że określono inaczej. + +Jeśli pracujesz nad tym kursem samodzielnie, zapoznaj się z [podstawami środowiska](../envsetup/01_setup.md), aby uzyskać więcej szczegółów. + +### Wymagania dotyczące wersji + +To szkolenie jest przeznaczone dla Nextflow 25.10.2 lub nowszego **z WŁĄCZONYM parserem składni v2**. +Jeśli używasz lokalnego lub niestandardowego środowiska, upewnij się, że używasz prawidłowych ustawień, jak opisano [tutaj](../info/nxf_versions.md). + +## Przygotuj się do pracy + +Po uruchomieniu codespace są dwie rzeczy, które musisz zrobić przed rozpoczęciem szkolenia: ustawić katalog roboczy dla tego konkretnego kursu i przejrzeć dostarczone materiały. + +### Ustaw katalog roboczy + +Domyślnie codespace otwiera się z katalogiem roboczym ustawionym na katalog główny wszystkich kursów szkoleniowych, ale dla tego kursu będziemy pracować w katalogu `nextflow-run/`. + +Zmień katalog teraz, uruchamiając to polecenie w terminalu: + +```bash +cd nextflow-run/ +``` + +Możesz ustawić VSCode tak, aby koncentrował się na tym katalogu, dzięki czemu tylko odpowiednie pliki będą wyświetlane na pasku bocznym eksploratora plików: + +```bash +code . +``` + +!!! tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu wyjdziesz z tego katalogu (np. codespace przejdzie w stan uśpienia), zawsze możesz użyć pełnej ścieżki, aby do niego wrócić, zakładając, że pracujesz w środowisku szkoleniowym Github Codespaces: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Teraz przyjrzyjmy się zawartości. + +### Przejrzyj dostarczone materiały + +Możesz przeglądać zawartość tego katalogu, używając eksploratora plików po lewej stronie obszaru roboczego szkolenia. +Alternatywnie możesz użyć polecenia `tree`. + +W całym kursie używamy wyjścia `tree` do przedstawienia struktury i zawartości katalogów w czytelnej formie, czasami z drobnymi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu: + +```bash +tree . -L 2 +``` + +??? abstract "Zawartość katalogu" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Kliknij na kolorowe pole, aby rozwinąć sekcję i zobaczyć jej zawartość. +Używamy zwijanych sekcji takich jak ta do wyświetlania oczekiwanego wyjścia poleceń oraz zawartości katalogów i plików w zwięzły sposób. + +- **Pliki `.nf`** to skrypty workflow ponumerowane według części kursu, w której są używane. + +- **Plik `nextflow.config`** to plik konfiguracyjny, który ustawia minimalne właściwości środowiska. + Na razie możesz go zignorować. + +- **Plik `greetings.csv`** w katalogu `data/` zawiera dane wejściowe, których użyjemy w większości kursu. Jest opisany w Części 2 (Uruchamianie pipeline), kiedy wprowadzamy go po raz pierwszy. + +- **Pliki `test-params.*`** to pliki konfiguracyjne, których użyjemy w Części 3 (Konfiguracja). Na razie możesz je zignorować. + +- **Katalog `solutions`** zawiera końcowy stan workflow i jego plików pomocniczych (config i moduły), które są wynikiem ukończenia kursu. + Są przeznaczone do użycia jako odniesienie do sprawdzenia swojej pracy i rozwiązywania problemów. + +## Lista kontrolna gotowości + +Myślisz, że jesteś gotowy do rozpoczęcia? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Moje środowisko jest uruchomione i działa +- [ ] Ustawiłem odpowiednio swój katalog roboczy + +Jeśli możesz zaznaczyć wszystkie pola, jesteś gotowy do działania. + +**Aby przejść do [Części 1: Podstawowe operacje](./01_basics.md), kliknij strzałkę w prawym dolnym rogu tej strony.** diff --git a/docs/pl/docs/nextflow_run/01_basics.md b/docs/pl/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..89bdc50024 --- /dev/null +++ b/docs/pl/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Część 1: Podstawowe operacje + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej pierwszej części kursu szkoleniowego Nextflow Run, łagodnie wprowadzamy temat za pomocą bardzo podstawowego, niezależnego od domeny przykładu Hello World, którego użyjemy do zademonstrowania podstawowych operacji i wskazania odpowiednich komponentów kodu Nextflow. + +??? info "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. + +!!! tip "Wskazówka" + + Pamiętaj, że powinieneś teraz znajdować się w katalogu `nextflow-run/`, jak opisano na stronie [Rozpoczęcie pracy](00_orientation.md). + +### 1.1. Spraw, aby terminal powiedział cześć + +Uruchom następujące polecenie w terminalu. + +```bash +echo 'Hello World!' +``` + +??? success "Wyjście polecenia" + + ```console + Hello World! + ``` + +To wypisuje tekst 'Hello World' bezpośrednio w terminalu. + +### 1.2. Zapisz wyjście do pliku + +Uruchamianie pipeline 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. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Wyjście polecenia" + + ```console + + ``` + +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`. + +??? abstract "Zawartość pliku" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +To jest to, co będziemy próbowali odtworzyć za pomocą naszego pierwszego workflow 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 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: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +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: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +To mówi nam, że process `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 katalog, zobaczysz, że gdy uruchomiłeś workflow, Nextflow utworzył nowy katalog o nazwie `results`, a także podkatalog o nazwie `1-hello` pod nim, zawierający plik o nazwie `output.txt`. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Otwórz plik; zawartość powinna odpowiadać ciągowi znaków, który podałeś w wierszu poleceń. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +Ś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. + +Więc teraz zajrzymy pod maskę, aby zobaczyć, gdzie Nextflow faktycznie wykonał pracę. + +!!! warning "Ostrzeżenie" + + Nie wszystkie workflow 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 process w workflow (=każdego kroku w pipeline). +Dla każdego z nich przygotowuje niezbędne dane wejściowe, wykonuje odpowiednie instrukcje i zapisuje wyjścia i pliki dziennika w tym jednym katalogu, 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, który uruchomiliśmy wcześniej, mieliśmy tę linię: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Widzisz, jak linia zaczyna się od `[a3/7be2fa]`? +To jest skrócona forma ścieżki katalogu zadania dla tego jednego wywołania process i mówi, gdzie znaleźć wyjście wywołania `sayHello` process 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 swoim terminalu) i naciskając klawisz tab, aby automatycznie uzupełnić ścieżkę, lub dodając gwiazdkę: + +```bash +ls work/a3/7be2fa* +``` + +To powinno dać pełną ścieżkę katalogu: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Zobaczmy, co jest w środku. + +??? abstract "Zawartość katalogu" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "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. + + ```bash + tree -a work + ``` + +Powinieneś natychmiast rozpoznać plik `output.txt`, który jest w rzeczywistości oryginalnym wyjściem process `sayHello`, które zostało opublikowane do katalogu `results`. +Jeśli go otworzysz, znajdziesz ponownie powitanie `Hello World!`. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +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 process +- **`.command.log`**: Kompletne wyjście dziennika emitowane przez wywołanie process +- **`.command.out`**: Zwykłe wyjście (`stdout`) przez wywołanie process +- **`.command.run`**: Pełny skrypt uruchomiony przez Nextflow do wykonania wywołania process +- **`.command.sh`**: Polecenie, które zostało faktycznie uruchomione przez wywołanie process +- **`.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. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/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 i musisz rozwiązać problem, przydatne może być spojrzenie na skrypt `command.sh`, aby sprawdzić dokładnie, jakie polecenie Nextflow złożył na podstawie instrukcji workflow, 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ń. + +??? abstract "Zawartość katalogu" + + ```console + 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. + +??? abstract "Zawartość katalogu" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +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 Hello World + +To, co tam zrobiliśmy, to w zasadzie traktowanie skryptu workflow 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. + +??? full-code "Pełny plik kodu" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Użyj echo do wypisania 'Hello World!' do pliku + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parameters + */ + params { + input: String + } + + workflow { + + main: + // wyemituj pozdrowienie + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Skrypt workflow Nextflow zazwyczaj zawiera jedną lub więcej definicji **process**, sam **workflow** i kilka opcjonalnych bloków, takich jak **params** i **output**. + +Każdy **process** opisuje, jakie operacje powinien wykonać odpowiedni krok w pipeline, podczas gdy **workflow** opisuje logikę przepływu danych, która łączy różne kroki. + +Przyjrzyjmy się bliżej najpierw blokowi **process**, a potem spojrzymy na blok **workflow**. + +### 3.2. Definicja `process` + +Pierwszy blok kodu opisuje **process**. +Definicja process zaczyna się od słowa kluczowego `process`, po którym następuje nazwa process, a na końcu ciało process ograniczone nawiasami klamrowymi. +Ciało process musi zawierać blok script, który określa polecenie do uruchomienia, które może być czymkolwiek, co można by uruchomić w terminalu wiersza poleceń. + +```groovy title="1-hello.nf" linenums="3" +/* +* Użyj echo do wypisania pozdrowienia do pliku +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Tutaj mamy **process** o nazwie `sayHello`, który przyjmuje zmienną **input** o nazwie `greeting` i zapisuje swoje **output** do pliku o nazwie `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +To jest bardzo minimalna definicja process, 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, a blok `publish:` wymienia wyjścia, które powinny być opublikowane do katalogu `results`. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // wyemituj pozdrowienie + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +W tym przypadku blok `main:` zawiera wywołanie process `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 process `sayHello()`, które odnosi się jako `sayHello.out` i nadaje mu nazwę `first_output` (może to być cokolwiek, co chce autor workflow). + +To jest bardzo minimalna definicja **workflow**. +W rzeczywistym pipeline workflow zazwyczaj zawiera wiele wywołań **process** połączonych przez **channel** 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 process `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 process `sayHello()`. +W rzeczywistości samo zadeklarowanie `params.someParameterName` wystarczy, aby dać workflow 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). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +Obsługiwane typy obejmują `String`, `Integer`, `Float`, `Boolean` i `Path`. + +!!! tip "Wskazówka" + + Parametry workflow 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. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +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`. + +??? info "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 process przy użyciu dyrektywy `publishDir`. + + Nadal znajdziesz ten wzorzec kodu wszędzie w starszych pipeline Nextflow i modułach process, więc ważne jest, aby o nim wiedzieć. + + Zamiast mieć blok `publish:` w workflow i blok `output` na najwyższym poziomie, zobaczyłbyś linię `publishDir` w definicji process `sayHello`: + + ```groovy title="Przykład składni" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + 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. + +--- + +## 4. Zarządzaj wykonaniami workflow + +Wiedza o tym, jak uruchamiać workflow i pobierać wyjścia, jest świetna, ale szybko odkryjesz, że jest kilka innych aspektów zarządzania workflow, 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 procesy, które zostały już uruchomione z dokładnie tym samym kodem, ustawieniami i danymi wejściowymi, zostaną pominięte. +To oznacza, że Nextflow uruchomi tylko procesy, które dodałeś lub zmodyfikowałeś od ostatniego uruchomienia, lub do których przekazujesz nowe ustawienia lub dane wejściowe. + +Są dwie kluczowe zalety robienia tego: + +- Jeśli jesteś w trakcie rozwijania pipeline, możesz iterować szybciej, ponieważ musisz uruchomić tylko process(y), nad którymi aktywnie pracujesz, aby przetestować swoje zmiany. +- Jeśli uruchamiasz pipeline w produkcji i coś pójdzie nie tak, w wielu przypadkach możesz naprawić problem i ponownie uruchomić pipeline, a on wznowi działanie od punktu awarii, co może zaoszczędzić dużo czasu i zasobów obliczeniowych. + +Aby go użyć, po prostu dodaj `-resume` do polecenia i uruchom je: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +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 process (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". + +!!! tip "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. + +??? abstract "Zawartość pliku" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +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`. + +```bash +nextflow log +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +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, 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](https://www.nextflow.io/docs/latest/reference/cli.html#clean) 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: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Wyjście polecenia" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +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`: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Wyjście polecenia" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +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ść. + +!!! warning "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ś budulce składni Nextflow i podstawowe instrukcje użycia. + +W następnej sekcji tego szkolenia przyjrzymy się czterem kolejnym, coraz bardziej realistycznym wersjom pipeline Hello World, które pokażą, jak Nextflow pozwala efektywnie przetwarzać wiele danych wejściowych, uruchamiać workflow 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 + +<quiz> +W linii wyjścia konsoli `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`, co reprezentuje `[a3/7be2fa]`? +- [ ] Numer wersji process +- [ ] Unikalny identyfikator uruchomienia +- [x] Skrócona ścieżka do katalogu roboczego zadania +- [ ] Suma kontrolna pliku wyjściowego + +Dowiedz się więcej: [2.3. Znajdź oryginalne wyjście i logi w katalogu `work/`](#23-znajdz-oryginalne-wyjscie-i-logi-w-katalogu-work) +</quiz> + +<quiz> +Jaki jest cel pliku `.command.sh` w katalogu zadania? +- [ ] Przechowuje ustawienia konfiguracyjne zadania +- [x] Pokazuje rzeczywiste polecenie, które zostało wykonane przez process +- [ ] Zawiera komunikaty o błędach z nieudanych zadań +- [ ] Wymienia pliki wejściowe przygotowane dla zadania + +Dowiedz się więcej: [2.3. Znajdź oryginalne wyjście i logi w katalogu `work/`](#23-znajdz-oryginalne-wyjscie-i-logi-w-katalogu-work) +</quiz> + +<quiz> +Co dzieje się z opublikowanymi wynikami, gdy ponownie uruchamiasz workflow bez `-resume`? +- [ ] Są zachowane w oddzielnych katalogach ze znacznikami czasu +- [x] Są nadpisywane przez nowe wykonanie +- [ ] Nextflow zapobiega nadpisywaniu i kończy się niepowodzeniem +- [ ] Są automatycznie archiwizowane + +Dowiedz się więcej: [2.4. Uruchom ponownie workflow z różnymi powitaniami](#24-uruchom-ponownie-workflow-z-roznymi-powitaniami) +</quiz> + +<quiz> +Co wskazuje to wyjście konsoli? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] Zadanie nie powiodło się i zostało pominięte +- [ ] Zadanie czeka w kolejce +- [x] Nextflow ponownie użył wyników z poprzedniego identycznego wykonania +- [ ] Zadanie zostało ręcznie anulowane + +Dowiedz się więcej: [4.1. Ponownie uruchom workflow z `-resume`](#41-ponownie-uruchom-workflow-z--resume) +</quiz> + +<quiz> +Gdzie Nextflow przechowuje historię wykonania, którą wyświetla polecenie `nextflow log`? +- [ ] W katalogu results +- [ ] W katalogu work +- [x] W pliku `.nextflow/history` +- [ ] W `nextflow.config` + +Dowiedz się więcej: [4.2. Sprawdź dziennik poprzednich wykonań](#42-sprawdz-dziennik-poprzednich-wykonan) +</quiz> + +<quiz> +Jaki jest cel bloku `params` w pliku workflow? +- [ ] Definiowanie wymagań zasobów process +- [ ] Konfigurowanie executora +- [x] Deklarowanie i typowanie parametrów wejściowych workflow +- [ ] Określanie opcji publikowania wyjść + +Dowiedz się więcej: [3.4. System parametrów wiersza poleceń `params`](#34-system-parametrow-wiersza-polecen-params) +</quiz> + +<quiz> +Co robi `mode 'copy'` w bloku `output` workflow? +- [ ] Tworzy kopię zapasową katalogu roboczego +- [x] Tworzy pełną kopię plików zamiast dowiązań symbolicznych +- [ ] Kopiuje skrypt workflow do results +- [ ] Włącza przyrostowe kopiowanie plików + +Dowiedz się więcej: [3.5. Dyrektywa `publish`](#35-dyrektywa-publish) +</quiz> + +<quiz> +Jaka jest zalecana flaga do użycia z poleceniem `nextflow clean` przed faktycznym usunięciem plików? +- [x] `-n` (próbne uruchomienie) aby zobaczyć, co zostałoby usunięte +- [ ] `-v` (szczegółowe) aby zobaczyć szczegółowe wyjście +- [ ] `-a` (wszystko) aby wybrać wszystkie katalogi +- [ ] `-q` (cicho) aby pominąć ostrzeżenia + +Dowiedz się więcej: [4.3. Usuń starsze katalogi robocze](#43-usun-starsze-katalogi-robocze) +</quiz> diff --git a/docs/pl/docs/nextflow_run/02_pipeline.md b/docs/pl/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..d5497b4f1c --- /dev/null +++ b/docs/pl/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1384 @@ +# Część 2: Uruchamianie prawdziwych pipeline + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W Części 1 tego kursu (Podstawowe operacje) zaczęliśmy od przykładowego workflow, który miał tylko minimalne funkcje, aby utrzymać niską złożoność kodu. +Na przykład `1-hello.nf` używał parametru wiersza poleceń (`--input`) do przekazywania pojedynczej wartości na raz. + +Jednak większość rzeczywistych pipeline wykorzystuje bardziej zaawansowane funkcje, aby umożliwić efektywne przetwarzanie dużych ilości danych na skalę i stosowanie wielu kroków przetwarzania połączonych czasami złożoną logiką. + +W tej części szkolenia demonstrujemy kluczowe funkcje rzeczywistych pipeline, wypróbowując rozszerzone wersje oryginalnego pipeline Hello World. + +## 1. Przetwarzanie danych wejściowych z pliku + +W rzeczywistym pipeline zazwyczaj chcemy przetwarzać wiele punktów danych (lub serii danych) zawartych w jednym lub więcej plikach wejściowych. +I gdziekolwiek to możliwe, chcemy uruchamiać przetwarzanie niezależnych danych równolegle, aby skrócić czas oczekiwania na analizę. + +Aby zademonstrować, jak Nextflow to robi, przygotowaliśmy plik CSV o nazwie `greetings.csv`, który zawiera kilka powitań wejściowych, naśladując rodzaj danych kolumnowych, które możesz chcieć przetwarzać w prawdziwej analizie danych. +Zauważ, że liczby nie mają znaczenia, są tam tylko w celach ilustracyjnych. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Napisaliśmy również ulepszoną wersję oryginalnego workflow, teraz o nazwie `2a-inputs.nf`, która odczyta plik CSV, wyodrębni powitania i zapisze każde z nich do oddzielnego pliku. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Uruchommy najpierw workflow, a potem przyjrzymy się odpowiedniemu kodowi Nextflow. + +### 1.1. Uruchom workflow + +Uruchom następujące polecenie w terminalu. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Ekscytująco, wydaje się to wskazywać, że wykonano '3 of 3' wywołań dla process, co jest zachęcające, ponieważ w dostarczonym pliku CSV były trzy wiersze danych. +To sugeruje, że process `sayHello()` został wywołany trzy razy, raz dla każdego wiersza wejściowego. + +### 1.2. Znajdź opublikowane wyjścia w katalogu `results` + +Przyjrzyjmy się katalogowi 'results', aby zobaczyć, czy nasz workflow nadal zapisuje kopię naszych wyjść tam. + +??? abstract "Zawartość katalogu" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Tak! Widzimy nowy katalog o nazwie `2a-inputs` z trzema plikami wyjściowymi o różnych nazwach, co jest wygodne. + +Możesz otworzyć każdy z nich, aby upewnić się, że zawierają odpowiedni ciąg powitania. + +??? abstract "Zawartość plików" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +To potwierdza, że każde powitanie w pliku wejściowym zostało odpowiednio przetworzone. + +### 1.3. Znajdź oryginalne wyjścia i logi + +Być może zauważyłeś, że powyższe wyjście konsoli odnosiło się tylko do jednego katalogu zadania. +Czy to oznacza, że wszystkie trzy wywołania `sayHello()` zostały wykonane w tym jednym katalogu zadania? + +#### 1.3.1. Zbadaj katalog zadania podany w terminalu + +Zajrzyjmy do tego katalogu zadania `8e/0eb066`. + +??? abstract "Zawartość katalogu" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Znajdujemy tylko wyjście odpowiadające jednemu z powitań (oraz pliki pomocnicze, jeśli włączymy wyświetlanie ukrytych plików). + +Więc co się dzieje? + +Domyślnie system logowania ANSI zapisuje informacje o statusie dla wszystkich wywołań tego samego process w tej samej linii. +W rezultacie pokazał nam tylko jedną z trzech ścieżek katalogów zadań (`8e/0eb066`) w wyjściu konsoli. +Są dwie inne, które tam nie są wymienione. + +#### 1.3.2. Spraw, aby terminal pokazywał więcej szczegółów + +Możemy zmodyfikować zachowanie logowania, aby zobaczyć pełną listę wywołań process, dodając `-ansi-log false` do polecenia w następujący sposób: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Tym razem widzimy wszystkie trzy uruchomienia process i ich powiązane podkatalogi robocze wymienione w wyjściu. +Wyłączenie logowania ANSI również uniemożliwiło Nextflow używanie kolorów w wyjściu terminala. + +Zauważ, że sposób raportowania statusu jest nieco inny między dwoma trybami logowania. +W trybie skondensowanym Nextflow raportuje, czy wywołania zostały pomyślnie ukończone, czy nie. +W tym rozszerzonym trybie raportuje tylko, że zostały przesłane. + +To potwierdza, że process `sayHello()` jest wywoływany trzy razy i dla każdego wywołania tworzony jest oddzielny katalog zadania. + +Jeśli zajrzymy do każdego z katalogów zadań wymienionych tam, możemy zweryfikować, że każdy odpowiada jednemu z powitań. + +??? abstract "Zawartość katalogu" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +To potwierdza, że każde wywołanie process jest wykonywane w izolacji od wszystkich innych. +Ma to wiele zalet, w tym unikanie kolizji, jeśli process produkuje jakieś pliki pośrednie o nieunikatowych nazwach. + +!!! tip "Wskazówka" + + Dla złożonego workflow lub dużej liczby danych wejściowych wyświetlanie pełnej listy do terminala może być nieco przytłaczające, więc ludzie normalnie nie używają `-ansi-log false` w rutynowym użyciu. + +### 1.4. Zbadaj kod workflow + +Więc ta wersja workflow jest w stanie odczytać plik CSV z danymi wejściowymi, przetwarzać dane wejściowe osobno i nazywać wyjścia unikalnie. + +Przyjrzyjmy się, co to umożliwia w kodzie workflow. + +??? full-code "Pełny plik kodu" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Użyj echo do wypisania 'Hello World!' do pliku + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + } + + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Ponownie, nie musisz zapamiętywać składni kodu, ale dobrze jest nauczyć się rozpoznawać kluczowe komponenty workflow, które zapewniają ważną funkcjonalność. + +#### 1.4.1. Ładowanie danych wejściowych z CSV + +To jest najciekawsza część: jak przeszliśmy od przyjmowania pojedynczej wartości z wiersza poleceń do przyjmowania pliku CSV, parsowania go i przetwarzania zawartych w nim pojedynczych powitań? + +W Nextflow robimy to za pomocą **channel**: konstrukcji zaprojektowanej do efektywnego obsługiwania danych wejściowych i przekazywania ich z jednego kroku do drugiego w wieloetapowych workflow, zapewniając jednocześnie wbudowaną równoległość i wiele dodatkowych korzyści. + +Rozłóżmy to na czynniki. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) +``` + +Ten kod tworzy channel o nazwie `greeting_ch`, który odczytuje plik CSV, parsuje go i wyodrębnia pierwszą kolumnę z każdego wiersza. +Wynikiem jest channel zawierający `Hello`, `Bonjour` i `Holà`. + +??? tip "Jak to działa?" + + Oto co ta linia oznacza prostym językiem: + + - `channel.fromPath` to **fabryka channel**, która tworzy channel ze ścieżki(ek) pliku + - `(params.input)` określa, że ścieżka pliku jest podana przez `--input` w wierszu poleceń + + Innymi słowy, ta linia mówi Nextflow: weź ścieżkę pliku podaną z `--input` i przygotuj się do traktowania jej zawartości jako danych wejściowych. + + Następnie kolejne dwie linie stosują **operatory**, które wykonują faktyczne parsowanie pliku i ładowanie danych do odpowiedniej struktury danych: + + - `.splitCsv()` mówi Nextflow, aby sparsował plik CSV na tablicę reprezentującą wiersze i kolumny + - `.map { line -> line[0] }` mówi Nextflow, aby wziął tylko element z pierwszej kolumny z każdego wiersza + + Więc w praktyce, zaczynając od następującego pliku CSV: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Przekształciliśmy to w tablicę, która wygląda tak: + + ```txt title="Zawartość tablicy" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + A następnie wzięliśmy pierwszy element z każdego z trzech wierszy i załadowaliśmy je do channel Nextflow, który teraz zawiera: `Hello`, `Bonjour` i `Holà`. + + Jeśli chcesz zrozumieć channel i operatory dogłębnie, w tym jak je samodzielnie pisać, zobacz [Hello Nextflow Część 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Wywołaj process na każdym powitaniu + +Następnie, w ostatniej linii bloku `main:` workflow, przekazujemy załadowany channel `greeting_ch` jako dane wejściowe do process `sayHello()`. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) +``` + +To mówi Nextflow, aby uruchomił process indywidualnie na każdym elemencie w channel, _tzn._ na każdym powitaniu. +A ponieważ Nextflow jest tak inteligentny, uruchomi te wywołania process równolegle, jeśli to możliwe, w zależności od dostępnej infrastruktury obliczeniowej. + +W ten sposób można osiągnąć efektywne i skalowalne przetwarzanie dużej ilości danych (wielu próbek lub punktów danych, cokolwiek jest Twoją jednostką badawczą) przy stosunkowo niewielkiej ilości kodu. + +#### 1.4.3. Jak nazywane są wyjścia + +Na koniec warto szybko spojrzeć na kod process, aby zobaczyć, jak uzyskujemy unikalne nazwy plików wyjściowych. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Widzisz, że w porównaniu z wersją tego process w `1-hello.nf`, deklaracja wyjścia i odpowiednia część polecenia zmieniły się, aby uwzględnić wartość powitania w nazwie pliku wyjściowego. + +To jest jeden ze sposobów na upewnienie się, że nazwy plików wyjściowych nie będą kolidować, gdy zostaną opublikowane do wspólnego katalogu results. + +I to jest jedyna zmiana, którą musieliśmy wprowadzić wewnątrz deklaracji process! + +### Podsumowanie + +Rozumiesz na podstawowym poziomie, jak channel i operatory umożliwiają nam efektywne przetwarzanie wielu danych wejściowych. + +### Co dalej? + +Odkryj, jak konstruowane są wieloetapowe workflow i jak działają. + +--- + +## 2. Uruchamianie wieloetapowych workflow + +Większość rzeczywistych workflow obejmuje więcej niż jeden krok. +Opierając się na tym, czego właśnie nauczyliśmy się o channel, przyjrzyjmy się, jak Nextflow używa channel i operatorów do łączenia process w wieloetapowym workflow. + +W tym celu dostarczamy przykładowy workflow, który łączy trzy oddzielne kroki i demonstruje: + +1. Przepływ danych z jednego process do następnego +2. Zbieranie wyjść z wielu wywołań process do jednego wywołania process + +Konkretnie, stworzyliśmy rozszerzoną wersję workflow o nazwie `2b-multistep.nf`, która przyjmuje każde powitanie wejściowe, konwertuje je na wielkie litery, a następnie zbiera wszystkie powitania wielkimi literami do jednego pliku wyjściowego. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Jak poprzednio, najpierw uruchomimy workflow, a potem przyjrzymy się kodowi, aby zobaczyć, co jest nowe. + +### 2.1. Uruchom workflow + +Uruchom następujące polecenie w terminalu: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Widzisz, że zgodnie z obietnicą, wiele kroków zostało uruchomionych jako część workflow; pierwsze dwa (`sayHello` i `convertToUpper`) były prawdopodobnie uruchomione na każdym indywidualnym powitaniu, a trzeci (`collectGreetings`) został uruchomiony tylko raz, na wyjściach wszystkich trzech wywołań `convertToUpper`. + +### 2.2. Znajdź wyjścia + +Zweryfikujmy, że to faktycznie się stało, patrząc na katalog `results`. + +??? abstract "Zawartość katalogu" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Jak widzisz, mamy nowy katalog o nazwie `2b-multistep` i zawiera znacznie więcej plików niż wcześniej. +Niektóre pliki zostały zgrupowane w podkatalogu o nazwie `intermediates`, podczas gdy dwa pliki znajdują się na najwyższym poziomie. + +Te dwa to końcowe wyniki wieloetapowego workflow. +Poświęć chwilę, aby spojrzeć na nazwy plików i sprawdzić ich zawartość, aby potwierdzić, że są takie, jakich oczekujesz. + +??? abstract "Zawartość plików" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +Pierwszy zawiera nasze trzy powitania, wielkimi literami i zebrane z powrotem do jednego pliku, zgodnie z obietnicą. +Drugi to plik raportu, który podsumowuje pewne informacje o uruchomieniu. + +### 2.3. Zbadaj kod + +Przyjrzyjmy się kodowi i zidentyfikujmy kluczowe wzorce dla wieloetapowych workflow. + +??? full-code "Pełny plik kodu" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Użyj echo do wypisania 'Hello World!' do pliku + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Użyj narzędzia zamiany tekstu do przekształcenia pozdrowienia na wielkie litery + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Zbierz pozdrowienia pisane wielkimi literami do jednego pliku wyjściowego + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Dużo się tam dzieje, ale najbardziej oczywistą różnicą w porównaniu z poprzednią wersją workflow jest to, że teraz jest wiele definicji process i odpowiednio kilka wywołań process w bloku workflow. + +Przyjrzyjmy się bliżej i zobaczmy, czy możemy zidentyfikować najciekawsze elementy. + +#### 2.3.1. Wizualizacja struktury workflow + +Jeśli używasz VSCode z rozszerzeniem Nextflow, możesz uzyskać pomocny diagram pokazujący, jak procesy są połączone, klikając mały link `DAG preview` wyświetlany tuż nad blokiem workflow w dowolnym skrypcie Nextflow. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +To daje ładny przegląd tego, jak procesy są połączone i co produkują. + +Widzisz, że oprócz oryginalnego process `sayHello`, mamy teraz również `convertToUpper` i `collectGreetings`, które odpowiadają nazwom procesów, które widzieliśmy w wyjściu konsoli. +Dwie nowe definicje process są zbudowane w ten sam sposób co process `sayHello`, z wyjątkiem tego, że `collectGreetings` przyjmuje dodatkowy parametr wejściowy o nazwie `batch` i produkuje dwa wyjścia. + +Nie będziemy wchodzić w szczegóły kodu dla każdego z nich, ale jeśli jesteś ciekawy, możesz sprawdzić szczegóły w [Części 2 Hello Nextflow](../hello_nextflow/03_hello_workflow.md). + +Na razie przyjrzyjmy się, jak procesy są ze sobą połączone. + +#### 2.3.2. Jak procesy są połączone + +Naprawdę interesującą rzeczą do przyjrzenia się jest to, jak wywołania process są połączone ze sobą w bloku `main:` workflow. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Widzisz, że pierwsze wywołanie process, `sayHello(greeting_ch)`, jest niezmienione. +Następnie kolejne wywołanie process, do `convertToUpper`, odnosi się do wyjścia `sayHello` jako `sayHello.out`. + +Wzorzec jest prosty: `processName.out` odnosi się do wyjściowego channel process, który może być przekazany bezpośrednio do następnego process. +W ten sposób przekazujemy dane z jednego kroku do następnego w Nextflow. + +#### 2.3.3. Process może przyjmować wiele danych wejściowych + +Trzecie wywołanie process, do `collectGreetings`, jest nieco inne. + +```groovy title="2b-multistep.nf" linenums="77" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Widzisz, że to wywołanie otrzymuje dwa dane wejściowe, `convertToUpper.out.collect()` i `params.batch`. +Ignorując na razie część `.collect()`, możemy to uogólnić jako `collectGreetings(input1, input2)`. + +To odpowiada dwóm deklaracjom wejściowym w module process: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Gdy Nextflow parsuje to, przypisze pierwsze dane wejściowe w wywołaniu do `path input_files`, a drugie do `val batch_name`. + +Więc teraz wiesz, że process może przyjmować wiele danych wejściowych i jak wygląda wywołanie w bloku workflow. + +Teraz przyjrzyjmy się bliżej temu pierwszemu wejściu, `convertToUpper.out.collect()`. + +#### 2.3.4. Co robi `collect()` w wywołaniu `collectGreetings` + +Aby przekazać wyjście `sayHello` do `convertToUpper`, po prostu odwołaliśmy się do wyjściowego channel `sayHello` jako `sayHello.out`. Ale dla następnego kroku widzimy odniesienie do `convertToUpper.out.collect()`. + +Co to jest ten fragment `collect()` i co robi? + +To oczywiście operator. Tak jak operatory `splitCsv` i `map`, które napotkaliśmy wcześniej. +Tym razem operator nazywa się `collect` i jest stosowany do wyjściowego channel produkowanego przez `convertToUpper`. + +Operator `collect` służy do zbierania wyjść z wielu wywołań tego samego process i pakowania ich w pojedynczy element channel. + +W kontekście tego workflow bierze trzy powitania wielkimi literami w channel `convertToUpper.out` --które są trzema oddzielnymi elementami channel i normalnie byłyby obsługiwane w oddzielnych wywołaniach przez następny process-- i pakuje je w jeden element. + +Bardziej praktycznie: gdybyśmy nie zastosowali `collect()` do wyjścia `convertToUpper()` przed przekazaniem go do `collectGreetings()`, Nextflow po prostu uruchomiłby `collectGreetings()` niezależnie na każdym powitaniu, co nie osiągnęłoby naszego celu. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +W przeciwieństwie do tego, użycie `collect()` pozwala nam wziąć wszystkie oddzielne powitania wielkimi literami wyprodukowane przez drugi krok workflow i przekazać je wszystkie razem do jednego wywołania w trzecim kroku pipeline. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +W ten sposób otrzymujemy wszystkie powitania z powrotem do tego samego pliku. + +Jest wiele innych [operatorów](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) dostępnych do stosowania transformacji na zawartości channel między wywołaniami process. + +To daje twórcom pipeline dużo elastyczności w dostosowywaniu logiki przepływu ich pipeline. +Wadą jest to, że czasami może to utrudnić rozszyfrowanie tego, co pipeline robi. + +#### 2.3.5. Parametr wejściowy może mieć wartość domyślną + +Być może zauważyłeś, że `collectGreetings` przyjmuje drugie wejście, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +To przekazuje parametr CLI o nazwie `--batch` do workflow. +Jednak gdy uruchomiliśmy workflow wcześniej, nie określiliśmy parametru `--batch`. + +Co się dzieje? +Przyjrzyj się blokowi `params`: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +W workflow jest skonfigurowana wartość domyślna, więc nie musimy jej podawać. +Ale jeśli podamy jedną w wierszu poleceń, wartość, którą określimy, zostanie użyta zamiast domyślnej. + +Spróbuj: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Wyjście polecenia" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Powinieneś zobaczyć nowe końcowe wyjścia nazwane Twoją własną nazwą batch. + +??? abstract "Zawartość katalogu" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +To jest aspekt konfiguracji danych wejściowych, który omówimy bardziej szczegółowo w Części 3, ale na razie ważne jest, aby wiedzieć, że parametry wejściowe mogą mieć wartości domyślne. + +#### 2.3.6. Process może produkować wiele wyjść + +W definicji process `collectGreetings` widzimy następujące deklaracje wyjść: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Które są następnie przywoływane przez nazwę podaną z `emit:` w bloku `publish:`: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +To ułatwia przekazywanie konkretnych wyjść indywidualnie do innych procesów w workflow, w połączeniu z różnymi operatorami. + +#### 2.3.7. Opublikowane wyjścia można organizować + +W bloku `output` użyliśmy własnych ścieżek do grupowania wyników pośrednich, aby ułatwić wybranie tylko końcowych wyjść workflow. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Istnieją bardziej zaawansowane sposoby organizowania opublikowanych wyjść; omówimy kilka w części o konfiguracji. + +!!! tip "Chcesz dowiedzieć się więcej o budowaniu workflow?" + + Szczegółowe omówienie budowania wieloetapowych workflow znajdziesz w [Hello Nextflow Część 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Podsumowanie + +Rozumiesz na podstawowym poziomie, jak wieloetapowe workflow są konstruowane przy użyciu channel i operatorów oraz jak działają. +Widziałeś również, że procesy mogą przyjmować wiele danych wejściowych i produkować wiele wyjść, oraz że mogą być publikowane w uporządkowany sposób. + +### Co dalej? + +Dowiedz się, jak pipeline Nextflow mogą być modułowe, aby promować ponowne wykorzystanie kodu i łatwość konserwacji. + +--- + +## 3. Uruchamianie zmodularyzowanych pipeline + +Jak dotąd wszystkie workflow, które oglądaliśmy, składały się z jednego pojedynczego pliku workflow zawierającego cały odpowiedni kod. + +Jednak rzeczywiste pipeline zazwyczaj korzystają z _modularyzacji_, co oznacza, że kod jest podzielony na różne pliki. +To może uczynić ich rozwój i konserwację bardziej efektywnymi i zrównoważonymi. + +Tutaj zademonstrujemy najpopularniejszą formę modułowości kodu w Nextflow, czyli użycie **modułów**. + +W Nextflow **moduł** to pojedyncza definicja process, która jest zamknięta sama w sobie w samodzielnym pliku kodu. +Aby użyć modułu w workflow, wystarczy dodać jednoliniową instrukcję importu do pliku kodu workflow; następnie możesz zintegrować process z workflow w normalny sposób. +To umożliwia ponowne wykorzystanie definicji process w wielu workflow bez tworzenia wielu kopii kodu. + +Do tej pory uruchamialiśmy workflow, które miały wszystkie swoje procesy zawarte w monolitycznym pliku kodu. +Teraz zobaczymy, jak to wygląda, gdy procesy są przechowywane w indywidualnych modułach. + +Oczywiście znowu przygotowaliśmy odpowiedni workflow do celów demonstracyjnych, o nazwie `2c-modules.nf`, wraz z zestawem modułów znajdujących się w katalogu `modules/`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Zawartość katalogu" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Widzisz, że są cztery pliki Nextflow, każdy nazwany po jednym z procesów. +Na razie możesz zignorować plik `cowpy.nf`; zajmiemy się nim później. + +### 3.1. Zbadaj kod + +Tym razem najpierw przyjrzymy się kodowi. +Zacznij od otwarcia pliku workflow `2c-modules.nf`. + +??? full-code "Pełny plik kodu" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Widzisz, że logika workflow jest dokładnie taka sama jak w poprzedniej wersji workflow. +Jednak kod process zniknął z pliku workflow, a zamiast tego są instrukcje `include` wskazujące na oddzielne pliki w katalogu `modules`. + +```groovy title="hello-modules.nf" linenums="3" +// Dołącz moduły +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Otwórz jeden z tych plików, a znajdziesz kod dla odpowiedniego process. + +??? full-code "Pełny plik kodu" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Użyj echo do wypisania 'Hello World!' do pliku + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Jak widzisz, kod process nie zmienił się; został po prostu skopiowany do indywidualnego pliku modułu zamiast być w głównym pliku workflow. +To samo dotyczy pozostałych dwóch procesów. + +Zobaczmy więc, jak wygląda uruchomienie tej nowej wersji. + +### 3.2. Uruchom workflow + +Uruchom to polecenie w terminalu, z flagą `-resume`: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Zauważysz, że wykonania process wszystkie pomyślnie użyły pamięci podręcznej, co oznacza, że Nextflow rozpoznał, że już wykonał żądaną pracę, mimo że kod został podzielony, a główny plik workflow został przemianowany. + +Nic z tego nie ma znaczenia dla Nextflow; liczy się skrypt zadania, który jest generowany po zebraniu i ocenie całego kodu. + +!!! tip "Wskazówka" + + Możliwe jest również zamknięcie sekcji workflow jako 'subworkflow', który można zaimportować do większego pipeline, ale to wykracza poza zakres tego kursu. + + Więcej o rozwijaniu komponowalnych workflow możesz dowiedzieć się w Side Quest o [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/). + +### Podsumowanie + +Wiesz, jak procesy mogą być przechowywane w samodzielnych modułach, aby promować ponowne wykorzystanie kodu i poprawić łatwość konserwacji. + +### Co dalej? + +Naucz się używać kontenerów do zarządzania zależnościami oprogramowania. + +--- + +## 4. Używanie konteneryzowanego oprogramowania + +Jak dotąd workflow, których używaliśmy jako przykładów, musiały tylko uruchamiać bardzo podstawowe operacje przetwarzania tekstu przy użyciu narzędzi UNIX dostępnych w naszym środowisku. + +Jednak rzeczywiste pipeline zazwyczaj wymagają specjalistycznych narzędzi i pakietów, które nie są domyślnie zawarte w większości środowisk. +Zazwyczaj musiałbyś zainstalować te narzędzia, zarządzać ich zależnościami i rozwiązywać wszelkie konflikty. + +To wszystko jest bardzo żmudne i denerwujące. +Znacznie lepszym sposobem rozwiązania tego problemu jest użycie **kontenerów**. + +**Kontener** to lekka, samodzielna, wykonywalna jednostka oprogramowania utworzona z **obrazu** kontenera, która zawiera wszystko, co potrzebne do uruchomienia aplikacji, w tym kod, biblioteki systemowe i ustawienia. + +!!! tip "Wskazówka" + + Uczymy tego przy użyciu technologii [Docker](https://www.docker.com/get-started/), ale Nextflow obsługuje również [kilka innych technologii kontenerowych](https://www.nextflow.io/docs/latest/container.html#). + +### 4.1. Użyj kontenera bezpośrednio + +Najpierw spróbujmy bezpośrednio wejść w interakcję z kontenerem. +To pomoże utrwalić zrozumienie tego, czym są kontenery, zanim zaczniemy ich używać w Nextflow. + +#### 4.1.1. Pobierz obraz kontenera + +Aby użyć kontenera, zazwyczaj pobierasz lub "ściągasz" obraz kontenera z rejestru kontenerów, a następnie uruchamiasz obraz kontenera, aby utworzyć instancję kontenera. + +Ogólna składnia jest następująca: + +```bash title="Składnia" +docker pull '<container>' +``` + +- `docker pull` to instrukcja dla systemu kontenerowego, aby pobrać obraz kontenera z repozytorium. +- `'<container>'` to adres URI obrazu kontenera. + +Jako przykład pobierzmy obraz kontenera zawierający [cowpy](https://github.com/jeffbuttars/cowpy), pythonową implementację narzędzia o nazwie `cowsay`, które generuje grafikę ASCII do wyświetlania dowolnych tekstowych danych wejściowych w zabawny sposób. + +Istnieją różne repozytoria, w których można znaleźć opublikowane kontenery. +Użyliśmy usługi [Seqera Containers](https://seqera.io/containers/), aby wygenerować ten obraz kontenera Docker z pakietu Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Uruchom pełne polecenie pull: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Wyjście polecenia" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +To mówi systemowi, aby pobrał określony obraz. +Po zakończeniu pobierania masz lokalną kopię obrazu kontenera. + +#### 4.1.2. Uruchom kontener + +Kontenery można uruchamiać jako jednorazowe polecenie, ale można ich również używać interaktywnie, co daje Ci wiersz poleceń wewnątrz kontenera i pozwala bawić się poleceniem. + +Ogólna składnia jest następująca: + +```bash title="Składnia" +docker run --rm '<container>' [polecenie narzędzia] +``` + +- `docker run --rm '<container>'` to instrukcja dla systemu kontenerowego, aby uruchomić instancję kontenera z obrazu kontenera i wykonać w niej polecenie. +- `--rm` mówi systemowi, aby wyłączył instancję kontenera po zakończeniu polecenia. + +W pełni złożone polecenie wykonania kontenera wygląda tak: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Uruchom to polecenie, a powinieneś zobaczyć, że Twój znak zachęty zmienia się na coś takiego jak `(base) root@b645838b3314:/tmp#`, co wskazuje, że jesteś teraz wewnątrz kontenera. + +Możesz to zweryfikować, uruchamiając `ls`, aby wylistować zawartość katalogu: + +```bash +ls / +``` + +??? success "Wyjście polecenia" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Widzisz, że system plików wewnątrz kontenera jest inny niż system plików na Twoim systemie hosta. + +!!! tip "Wskazówka" + + Gdy uruchamiasz kontener, jest on domyślnie odizolowany od systemu hosta. + To oznacza, że kontener nie może uzyskać dostępu do żadnych plików w systemie hosta, chyba że wyraźnie na to pozwolisz, określając, że chcesz zamontować wolumin jako część polecenia `docker run` używając następującej składni: + + ```bash title="Składnia" + -v <ścieżka_zewnętrzna>:<ścieżka_wewnętrzna> + ``` + + To skutecznie ustanawia tunel przez ścianę kontenera, którego możesz użyć, aby uzyskać dostęp do tej części twojego systemu plików. + + Jest to omówione bardziej szczegółowo w [Części 5 Hello Nextflow](../hello_nextflow/05_hello_containers.md). + +#### 4.1.3. Uruchom narzędzie `cowpy` + +Z wnętrza kontenera możesz uruchomić polecenie `cowpy` bezpośrednio. + +```bash +cowpy "Hello Containers" +``` + +??? success "Wyjście polecenia" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +To produkuje grafikę ASCII domyślnej postaci krowy (lub 'cowacter') z dymkiem mowy zawierającym określony przez nas tekst. + +Teraz, gdy przetestowałeś podstawowe użycie, możesz spróbować podać mu jakieś parametry. +Na przykład dokumentacja narzędzia mówi, że możemy ustawić postać za pomocą `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Wyjście polecenia" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Tym razem wyjście grafiki ASCII pokazuje pingwina Linuxa, Tux, ponieważ określiliśmy parametr `-c tux`. + +Ponieważ jesteś wewnątrz kontenera, możesz uruchamiać polecenie cowpy tyle razy, ile chcesz, zmieniając parametry wejściowe, bez martwienia się o instalację jakichkolwiek bibliotek w samym systemie. + +??? tip "Inne dostępne postacie" + + Użyj flagi '-c', aby wybrać inną postać, w tym: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Możesz się tym pobawić. +Gdy skończysz, wyjdź z kontenera używając polecenia `exit`: + +```bash +exit +``` + +Znajdziesz się z powrotem w normalnej powłoce. + +### 4.2. Użyj kontenera w workflow + +Gdy uruchamiamy pipeline, chcemy mieć możliwość powiedzenia Nextflow, jakiego kontenera użyć w każdym kroku, i co ważne, chcemy, aby obsłużył całą tę pracę, którą właśnie wykonaliśmy: pobrał kontener, uruchomił go, wykonał polecenie i usunął kontener, gdy skończy. + +Dobra wiadomość: to dokładnie to, co Nextflow zrobi za nas. +Musimy tylko określić kontener dla każdego process. + +Aby zademonstrować, jak to działa, stworzyliśmy kolejną wersję naszego workflow, która uruchamia `cowpy` na pliku zebranych powitań wyprodukowanych w trzecim kroku. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +To powinno wyprodukować plik zawierający grafikę ASCII z trzema powitaniami w dymku mowy. + +#### 4.2.1. Zbadaj kod + +Workflow jest bardzo podobny do poprzedniego, plus dodatkowy krok do uruchomienia `cowpy`. + +??? full-code "Pełny plik kodu" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Dołącz moduły + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // wyemituj pozdrowienie + sayHello(greeting_ch) + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + // zbierz wszystkie pozdrowienia do jednego pliku + collectGreetings(convertToUpper.out.collect(), params.batch) + // wygeneruj grafikę ASCII powitań za pomocą cowpy + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Widzisz, że ten workflow importuje process `cowpy` z pliku modułu i wywołuje go na wyjściu wywołania `collectGreetings()`, plus parametr wejściowy o nazwie `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// wygeneruj grafikę ASCII za pomocą cowpy +cowpy(collectGreetings.out, params.character) +``` + +Process `cowpy`, który opakowuje polecenie cowpy do generowania grafiki ASCII, jest zdefiniowany w module `cowpy.nf`. + +??? full-code "Pełny plik kodu" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Wygeneruj grafikę ASCII za pomocą cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Process `cowpy` wymaga dwóch danych wejściowych: ścieżki do pliku wejściowego zawierającego tekst do umieszczenia w dymku mowy (`input_file`) oraz wartości zmiennej character. + +Co ważne, zawiera również linię `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`, która wskazuje na URI kontenera, którego użyliśmy wcześniej. + +#### 4.2.2. Sprawdź, czy Docker jest włączony w konfiguracji + +Trochę wyprzedzimy Część 3 tego kursu szkoleniowego, wprowadzając plik konfiguracyjny `nextflow.config`, który jest jednym z głównych sposobów, jakie Nextflow oferuje do konfigurowania wykonywania workflow. +Gdy plik o nazwie `nextflow.config` jest obecny w bieżącym katalogu, Nextflow automatycznie go załaduje i zastosuje zawartą w nim konfigurację. + +W tym celu dołączyliśmy plik `nextflow.config` z pojedynczą linią kodu, która włącza Docker. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Ta konfiguracja mówi Nextflow, aby używał Docker dla każdego process, który określa kompatybilny kontener. + +!!! tip "Wskazówka" + + Technicznie możliwe jest włączenie wykonywania Docker z wiersza poleceń, na podstawie pojedynczego uruchomienia, używając parametru `-with-docker <container>`. + Jednak to pozwala nam określić tylko jeden kontener dla całego workflow, podczas gdy podejście, które właśnie pokazaliśmy, pozwala nam określić inny kontener dla każdego process. + To drugie jest znacznie lepsze dla modułowości, konserwacji kodu i odtwarzalności. + +#### 4.2.3. Uruchom workflow + +Podsumowując, oto co zamierzamy uruchomić: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Myślisz, że zadziała? + +Uruchommy workflow z flagą `-resume` i określmy, że chcemy, aby postacią był indyk. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +Pierwsze trzy kroki użyły pamięci podręcznej, ponieważ już je wcześniej uruchomiliśmy, ale process `cowpy` jest nowy, więc faktycznie zostaje uruchomiony. + +Możesz znaleźć wyjście kroku `cowpy` w katalogu `results`. + +??? abstract "Zawartość pliku" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Widzisz, że postać mówi wszystkie powitania, ponieważ uruchomiła się na pliku zebranych powitań wielkimi literami. + +Co ważniejsze, mogliśmy to uruchomić jako część naszego pipeline bez konieczności prawidłowej instalacji cowpy i wszystkich jego zależności. +I teraz możemy udostępnić pipeline współpracownikom i sprawić, że uruchomią go na swojej infrastrukturze bez konieczności instalowania czegokolwiek, poza Docker lub jedną z jego alternatyw (taką jak Singularity/Apptainer) jak wspomniano powyżej. + +#### 4.2.4. Sprawdź, jak Nextflow uruchomił konteneryzowane zadanie + +Na zakończenie tej sekcji przyjrzyjmy się podkatalogowi roboczemu dla jednego z wywołań process `cowpy`, aby uzyskać nieco więcej wglądu w to, jak Nextflow pracuje z kontenerami pod maską. + +Sprawdź wyjście z polecenia `nextflow run`, aby znaleźć ścieżkę do podkatalogu roboczego dla process `cowpy`. +Patrząc na to, co otrzymaliśmy dla uruchomienia pokazanego powyżej, linia dziennika konsoli dla process `cowpy` zaczyna się od `[7f/caf718]`. +To odpowiada następującej skróconej ścieżce katalogu: `work/7f/caf718`. + +W tym katalogu znajdziesz plik `.command.run`, który zawiera wszystkie polecenia, które Nextflow uruchomił w Twoim imieniu w trakcie wykonywania pipeline. + +??? abstract "Zawartość pliku" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + ``` + +Są tam polecenia `docker`, które Nextflow składa na podstawie URI obrazu kontenera podanego w definicji process, a także innych ustawień, które możemy określić za pomocą konfiguracji. Domyślnie Nextflow montuje katalog roboczy wewnątrz kontenera, co sprawia, że wszystkie pliki wejściowe i wyjściowe są dostępne bez dodatkowych czynności z naszej strony. Całkiem sprytne! + +### Podsumowanie + +Wiesz, jak określić kontener dla process i jak Nextflow obsługuje go pod maską, aby uczynić Twój kod przenośnym i odtwarzalnym. + +### Co dalej? + +W następnej części kursu dowiesz się, jak dostosować konfigurację workflow do swoich preferencji i środowiska obliczeniowego. diff --git a/docs/pl/docs/nextflow_run/03_config.md b/docs/pl/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..d9d902431e --- /dev/null +++ b/docs/pl/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Część 3: Konfiguracja uruchamiania + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ta sekcja zbada, jak zarządzać konfiguracją pipeline Nextflow, aby dostosować jego zachowanie, zaadaptować go do różnych środowisk i zoptymalizować wykorzystanie zasobów _bez zmieniania ani jednej linii samego kodu workflow_. + +Istnieje wiele sposobów, aby to zrobić, które można łączyć i które są interpretowane zgodnie z kolejnością pierwszeństwa opisaną [tutaj](https://www.nextflow.io/docs/latest/config.html). + +W tej części kursu pokażemy najprosts i najpopularniejszy mechanizm pliku konfiguracyjnego, plik `nextflow.config`, z którym już się spotkałeś w sekcji o kontenerach w Części 2. + +Omówimy podstawowe elementy konfiguracji Nextflow, takie jak dyrektywy process, executory, profile i pliki parametrów. +Ucząc się efektywnie wykorzystywać te opcje konfiguracji, możesz w pełni wykorzystać elastyczność, skalowalność i wydajność pipeline Nextflow. + +Aby przećwiczyć te elementy konfiguracji, będziemy uruchamiać świeżą kopię workflow, który ostatnio uruchamialiśmy na końcu Części 2 tego kursu szkoleniowego, przemianowaną na `3-main.nf`. + +Jeśli nie znasz pipeline Hello lub potrzebujesz przypomnienia, zobacz [tę stronę informacyjną](../info/hello_pipeline.md). + +--- + +## 1. Zarządzaj parametrami wejściowymi workflow + +??? example "Scenariusz" + + Pobrałeś pipeline i chcesz go wielokrotnie uruchamiać z tymi samymi plikami wejściowymi i ustawieniami, ale nie chcesz za każdym razem wpisywać wszystkich parametrów. + Lub może konfigurujesz pipeline dla kolegi, który nie czuje się komfortowo z argumentami wiersza poleceń. + +Zaczniemy od aspektu konfiguracji, który jest po prostu rozszerzeniem tego, nad czym pracowaliśmy do tej pory: zarządzania parametrami wejściowymi. + +Obecnie nasz workflow jest skonfigurowany do przyjmowania kilku wartości parametrów przez wiersz poleceń, zadeklarowanych w bloku `params` w samym skrypcie workflow. +Jeden ma wartość domyślną ustawioną jako część swojej deklaracji. + +Jednak możesz chcieć ustawić wartości domyślne dla wszystkich z nich lub nadpisać istniejącą wartość domyślną bez konieczności określania parametrów w wierszu poleceń lub modyfikowania oryginalnego pliku skryptu. + +Istnieje wiele sposobów, aby to zrobić; pokażemy trzy podstawowe sposoby, które są bardzo powszechnie używane. + +### 1.1. Ustaw wartości w `nextflow.config` + +To najprostsze podejście, choć prawdopodobnie najmniej elastyczne, ponieważ główny plik `nextflow.config` nie jest czymś, co chcesz edytować przy każdym uruchomieniu. +Ma jednak zaletę oddzielenia kwestii _deklarowania_ parametrów w workflow (co zdecydowanie tam należy) od dostarczania _wartości domyślnych_, które lepiej pasują do pliku konfiguracyjnego. + +Zróbmy to w dwóch krokach. + +#### 1.1.1. Utwórz blok `params` w pliku konfiguracyjnym + +Wprowadź następujące zmiany w kodzie w pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Zauważ, że nie skopiowaliśmy po prostu bloku `params` z workflow do pliku konfiguracyjnego. +Dla parametru `batch`, który miał już zadeklarowaną wartość domyślną, składnia jest nieco inna. +W pliku workflow to jest deklaracja typowana. +W konfiguracji to są przypisania wartości. + +Technicznie to wystarczy do nadpisania wartości domyślnych nadal określonych w pliku workflow. +Możesz zmodyfikować wartość domyślną dla `batch` i uruchomić workflow, aby upewnić się, że wartość ustawiona w pliku konfiguracyjnym nadpisuje tę ustawioną w pliku workflow. + +Ale w duchu przeniesienia konfiguracji całkowicie do pliku konfiguracyjnego, usuńmy tę wartość domyślną z pliku workflow całkowicie. + +#### 1.1.2. Usuń wartość domyślną dla `batch` w pliku workflow + +Wprowadź następującą zmianę w kodzie do pliku workflow `3-main.nf`: + +=== "Po" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Przed" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Teraz sam plik workflow nie ustawia żadnych wartości domyślnych dla tych parametrów. + +#### 1.1.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie bez określania jakichkolwiek parametrów w wierszu poleceń. + +```bash +nextflow run 3-main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje to samo wyjście co poprzednio. + +Końcowe wyjście grafiki ASCII znajduje się w katalogu `results/3-main/`, pod nazwą `cowpy-COLLECTED-batch-output.txt`, tak samo jak wcześniej. + +??? abstract "Zawartość pliku" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funkcjonalnie ta zmiana niczego nie zmieniła, ale koncepcyjnie jest nieco czystsze mieć wartości domyślne ustawione w pliku konfiguracyjnym. + +### 1.2. Użyj pliku konfiguracyjnego specyficznego dla uruchomienia + +??? example "Scenariusz" + + Chcesz eksperymentować z różnymi ustawieniami bez modyfikowania głównego pliku konfiguracyjnego. + +Możesz to zrobić, tworząc nowy plik `nextflow.config` w podkatalogu, którego użyjesz jako katalog roboczy dla swoich eksperymentów. + +#### 1.2.1. Utwórz katalog roboczy z pustą konfiguracją + +Zacznijmy od utworzenia nowego katalogu i przejścia do niego: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Następnie utwórz pusty plik konfiguracyjny w tym katalogu: + +```bash +touch nextflow.config +``` + +To tworzy pusty plik. + +#### 1.2.2. Skonfiguruj eksperymentalną konfigurację + +Teraz otwórz nowy plik i dodaj parametry, które chcesz dostosować: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Zauważ, że ścieżka do pliku wejściowego musi odzwierciedlać strukturę katalogów. + +#### 1.2.3. Uruchom pipeline + +Możemy teraz uruchomić nasz pipeline z poziomu nowego katalogu roboczego. +Upewnij się, że odpowiednio dostosujesz ścieżkę! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +To utworzy nowy zestaw katalogów w `tux-run/`, w tym `tux-run/work/` i `tux-run/results/`. + +W tym uruchomieniu Nextflow łączy `nextflow.config` w naszym bieżącym katalogu z `nextflow.config` w katalogu głównym pipeline i tym samym nadpisuje domyślną postać (turkey) postacią tux. + +Końcowy plik wyjściowy powinien zawierać postać tux mówiącą powitania. + +??? abstract "Zawartość pliku" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +To wszystko; teraz masz przestrzeń do eksperymentowania bez modyfikowania swojej 'normalnej' konfiguracji. + +!!! warning "Ostrzeżenie" + + Upewnij się, że wrócisz do poprzedniego katalogu przed przejściem do następnej sekcji! + + ```bash + cd .. + ``` + +Teraz przyjrzyjmy się innemu przydatnemu sposobowi ustawiania wartości parametrów. + +### 1.3. Użyj pliku parametrów + +??? example "Scenariusz" + + Musisz udostępnić dokładne parametry uruchomienia współpracownikowi lub zapisać je do publikacji. + +Podejście z podkatalogiem działa świetnie do eksperymentowania, ale wymaga trochę konfiguracji i wymaga odpowiedniego dostosowania ścieżek. +Jest prostsze podejście, gdy chcesz uruchomić pipeline z określonym zestawem wartości lub umożliwić komuś innemu zrobienie tego przy minimalnym wysiłku. + +Nextflow pozwala nam określić parametry za pomocą pliku parametrów w formacie YAML lub JSON, co czyni bardzo wygodnym zarządzanie i dystrybucję alternatywnych zestawów wartości domyślnych, na przykład, a także wartości parametrów specyficznych dla uruchomienia. + +#### 1.3.1. Zbadaj przykładowy plik parametrów + +Aby to zademonstrować, dostarczamy przykładowy plik parametrów w bieżącym katalogu, o nazwie `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Ten plik parametrów zawiera parę klucz-wartość dla każdego z danych wejściowych, które chcemy określić. +Zwróć uwagę na użycie dwukropków (`:`) zamiast znaków równości (`=`), jeśli porównujesz składnię z plikiem konfiguracyjnym. +Plik config jest napisany w Groovy, podczas gdy plik parametrów jest napisany w YAML. + +!!! info "Informacja" + + Dostarczamy również wersję JSON pliku parametrów jako przykład, ale nie będziemy go tutaj uruchamiać. + Możesz spróbować tego samodzielnie. + +#### 1.3.2. Uruchom pipeline + +Aby uruchomić workflow z tym plikiem parametrów, po prostu dodaj `-params-file <nazwa_pliku>` do podstawowego polecenia. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Końcowy plik wyjściowy powinien zawierać postać stegosaurus mówiącą powitania. + +??? abstract "Zawartość pliku" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Użycie pliku parametrów może wydawać się przesadą, gdy masz tylko kilka parametrów do określenia, ale niektóre pipeline oczekują dziesiątek parametrów. +W takich przypadkach użycie pliku parametrów pozwoli nam podać wartości parametrów w czasie wykonania bez konieczności wpisywania ogromnych wierszy poleceń i bez modyfikowania skryptu workflow. + +Ułatwia również dystrybucję zestawów parametrów współpracownikom lub jako materiał pomocniczy do publikacji, na przykład. +To czyni Twoją pracę bardziej odtwarzalną przez innych. + +### Podsumowanie + +Wiesz, jak wykorzystać kluczowe opcje konfiguracji do zarządzania danymi wejściowymi workflow. + +### Co dalej? + +Dowiedz się, jak zarządzać tym, gdzie i jak Twoje wyjścia workflow są publikowane. + +--- + +## 2. Zarządzaj wyjściami workflow + +??? example "Scenariusz" + + Twój pipeline publikuje wyjścia do zakodowanego na stałe katalogu, ale chcesz organizować wyniki według nazwy projektu lub eksperymentu bez edytowania kodu workflow za każdym razem. + +Workflow, który odziedzczyliśmy, używa ścieżek dla deklaracji wyjść na poziomie workflow, co nie jest szczególnie elastyczne i wymaga dużo powtórzeń. + +Przyjrzyjmy się kilku typowym sposobom, w jakie możesz to skonfigurować, aby było bardziej elastyczne. + +### 2.1. Dostosuj nazwę katalogu `outputDir` + +Każda wersja workflow, którą do tej pory uruchomiliśmy, publikowała swoje wyjścia do innego podkatalogu zakodowanego na stałe w definicjach wyjść. + +Zmieńmy to, aby użyć parametru konfigurowalnego przez użytkownika. +Moglibyśmy stworzyć zupełnie nowy parametr do tego celu, ale użyjmy parametru `batch`, ponieważ jest tuż pod ręką. + +#### 2.1.1. Ustaw wartość dla `outputDir` w pliku konfiguracyjnym + +Ścieżka, której Nextflow używa do publikowania wyjść, jest kontrolowana przez opcję `outputDir`. +Aby zmienić ścieżkę dla wszystkich wyjść, możesz ustawić wartość tej opcji w pliku konfiguracyjnym `nextflow.config`. + +Dodaj następujący kod do pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +To zastąpi wbudowaną domyślną ścieżkę, `results/`, na `results/` plus wartość parametru `batch` jako podkatalog. +Możesz również zmienić część `results`, jeśli chcesz. + +Dla tymczasowej zmiany możesz ustawić tę opcję z wiersza poleceń używając parametru `-output-dir` w poleceniu (ale wtedy nie możesz użyć wartości parametru `batch`). + +#### 2.1.2. Usuń powtarzającą się część zakodowanej na stałe ścieżki + +Nadal mamy podkatalog zakodowany na stałe w opcjach wyjść, więc pozbądźmy się go teraz. + +Wprowadź następujące zmiany w kodzie w pliku workflow: + +=== "Po" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +Mogliśmy również po prostu dodać `${params.batch}` do każdej ścieżki zamiast modyfikować domyślną wartość `outputDir`, ale to jest bardziej zwięzłe. + +#### 2.1.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę batch na `outdir` z wiersza poleceń. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje to samo wyjście co poprzednio, z wyjątkiem tego, że tym razem znajdujemy nasze wyjścia w `results/outdir/`. + +??? abstract "Zawartość katalogu" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Możesz połączyć to podejście z niestandardowymi definicjami ścieżek, aby skonstruować dowolną hierarchię katalogów. + +### 2.2. Organizuj wyjścia według process + +Jednym z popularnych sposobów dalszej organizacji wyjść jest robienie tego według process, _tzn._ tworzenie podkatalogów dla każdego process uruchomionego w pipeline. + +#### 2.2.1. Zastąp ścieżki wyjść odniesieniem do nazw process + +Wystarczy odwołać się do nazwy process jako `<task>.name` w deklaracji ścieżki wyjścia. + +Wprowadź następujące zmiany w pliku workflow: + +=== "Po" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Przed" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +To usuwa pozostałe zakodowane na stałe elementy z konfiguracji ścieżki wyjścia. + +#### 2.2.2. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę batch na `pnames` z wiersza poleceń. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje to samo wyjście co poprzednio, z wyjątkiem tego, że tym razem znajdujemy nasze wyjścia w `results/pnames/` i są one pogrupowane według process. + +??? abstract "Zawartość katalogu" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Zauważ, że tutaj zatarliśmy rozróżnienie między `intermediates` a końcowymi wyjściami na najwyższym poziomie. +Możesz oczywiście mieszać i łączyć te podejścia, na przykład ustawiając ścieżkę pierwszego wyjścia jako `intermediates/${sayHello.name}` + +### 2.3. Ustaw tryb publikowania na poziomie workflow + +Na koniec, w duchu zmniejszania ilości powtarzającego się kodu, możemy zastąpić deklaracje `mode` dla każdego wyjścia pojedynczą linią w konfiguracji. + +#### 2.3.1. Dodaj `workflow.output.mode` do pliku konfiguracyjnego + +Dodaj następujący kod do pliku `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Tak jak opcja `outputDir`, nadanie `workflow.output.mode` wartości w pliku konfiguracyjnym wystarczyłoby do nadpisania tego, co jest ustawione w pliku workflow, ale i tak usuńmy niepotrzebny kod. + +#### 2.3.2. Usuń tryb wyjścia z pliku workflow + +Wprowadź następujące zmiany w pliku workflow: + +=== "Po" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Przed" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +To jest bardziej zwięzłe, prawda? + +#### 2.3.3. Uruchom pipeline + +Przetestujmy, czy działa poprawnie, ustawiając nazwę batch na `outmode` z wiersza poleceń. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +To nadal produkuje to samo wyjście co poprzednio, z wyjątkiem tego, że tym razem znajdujemy nasze wyjścia w `results/outmode/`. +Wszystkie nadal są właściwymi kopiami, nie symlinkami. + +??? abstract "Zawartość katalogu" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Głównym powodem, dla którego nadal możesz chcieć użyć sposobu ustawiania trybu dla każdego wyjścia, jest sytuacja, gdy chcesz mieszać i łączyć w tym samym workflow, _tzn._ mieć niektóre wyjścia kopiowane, a niektóre dowiązane symbolicznie. + +Jest wiele innych opcji, które możesz dostosować w ten sposób, ale mamy nadzieję, że to daje Ci poczucie zakresu opcji i jak je skutecznie wykorzystać, aby dopasować do swoich preferencji. + +### Podsumowanie + +Wiesz, jak kontrolować nazewnictwo i strukturę katalogów, w których publikowane są Twoje wyjścia, a także tryb publikowania wyjść workflow. + +### Co dalej? + +Dowiedz się, jak dostosować konfigurację workflow do swojego środowiska obliczeniowego, zaczynając od technologii pakowania oprogramowania. + +--- + +## 3. Wybierz technologię pakowania oprogramowania + +Do tej pory przyglądaliśmy się elementom konfiguracji, które kontrolują, jak dane wejściowe wchodzą i skąd dane wyjściowe wychodzą. Teraz czas skupić się bardziej konkretnie na dostosowywaniu konfiguracji workflow do środowiska obliczeniowego. + +Pierwszym krokiem na tej ścieżce jest określenie, skąd będą pochodzić pakiety oprogramowania, które będą uruchamiane w każdym kroku. +Czy są już zainstalowane w lokalnym środowisku obliczeniowym? +Czy musimy pobrać obrazy i uruchomić je przez system kontenerowy? +Czy musimy pobrać pakiety Conda i zbudować lokalne środowisko Conda? + +W pierwszej części tego kursu szkoleniowego (Części 1-4) używaliśmy po prostu lokalnie zainstalowanego oprogramowania w naszym workflow. +Następnie w Części 5 wprowadziliśmy kontenery Docker i plik `nextflow.config`, którego użyliśmy do włączenia korzystania z kontenerów Docker. + +Teraz zobaczmy, jak możemy skonfigurować alternatywną opcję pakowania oprogramowania za pomocą pliku `nextflow.config`. + +### 3.1. Wyłącz Docker i włącz Conda w pliku config + +??? example "Scenariusz" + + Przenosisz swój pipeline na klaster HPC, gdzie Docker nie jest dozwolony ze względów bezpieczeństwa. + Klaster obsługuje Singularity i Conda, więc musisz odpowiednio zmienić konfigurację. + +Nextflow obsługuje wiele technologii kontenerowych, w tym Singularity (który jest szerzej używany na HPC), a także menedżery pakietów oprogramowania, takie jak Conda. + +Możemy zmienić nasz plik konfiguracyjny, aby używał Conda zamiast Docker. +Aby to zrobić, zmieńmy wartość `docker.enabled` na `false` i dodajmy dyrektywę włączającą korzystanie z Conda: + +=== "Po" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +To pozwoli Nextflow tworzyć i wykorzystywać środowiska Conda dla procesów, które mają określone pakiety Conda. +Co oznacza, że teraz musimy dodać jeden z nich do naszego process `cowpy`! + +### 3.2. Określ pakiet Conda w definicji process + +Pobraliśmy już URI dla pakietu Conda zawierającego narzędzie `cowpy`: `conda-forge::cowpy==1.1.5` + +Teraz dodajemy URI do definicji process `cowpy` używając dyrektywy `conda`: + +=== "Po" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Przed" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Dla jasności, nie _zastępujemy_ dyrektywy `docker`, _dodajemy_ alternatywną opcję. + +!!! tip "Wskazówka" + + Jest kilka różnych sposobów na uzyskanie URI dla danego pakietu conda. + Zalecamy korzystanie z zapytania wyszukiwania [Seqera Containers](https://seqera.io/containers/), które da Ci URI, które możesz skopiować i wkleić, nawet jeśli nie planujesz tworzyć z niego kontenera. + +### 3.3. Uruchom workflow, aby zweryfikować, że może używać Conda + +Wypróbujmy to. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Wyjście polecenia" + + ```console title="Wyjście" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +To powinno działać bez problemu i produkować te same wyjścia co poprzednio w `results/conda`. + +Za kulisami Nextflow pobrał pakiety Conda i utworzył środowisko, co normalnie wymaga trochę pracy; więc miło, że nie musimy nic z tego robić sami! + +!!! info "Informacja" + + To działa szybko, ponieważ pakiet `cowpy` jest dość mały, ale jeśli pracujesz z dużymi pakietami, może to zająć nieco więcej czasu za pierwszym razem i możesz zobaczyć, że wyjście konsoli pozostaje 'zablokowane' przez minutę lub więcej przed zakończeniem. + To jest normalne i wynika z dodatkowej pracy, którą Nextflow wykonuje za pierwszym razem, gdy używasz nowego pakietu. + +Z naszej perspektywy wygląda to tak, jakby działało dokładnie tak samo jak uruchamianie z Docker, mimo że mechanizmy na zapleczu są nieco inne. + +To oznacza, że jesteśmy gotowi do uruchamiania ze środowiskami Conda, jeśli zajdzie taka potrzeba. + +??? info "Mieszanie i łączenie Docker i Conda" + + Ponieważ te dyrektywy są przypisywane dla każdego process, możliwe jest 'mieszanie i łączenie', _tzn._ konfigurowanie niektórych procesów w workflow do uruchamiania z Docker, a innych z Conda, na przykład, jeśli infrastruktura obliczeniowa, której używasz, obsługuje obie. + W takim przypadku włączyłbyś zarówno Docker, jak i Conda w pliku konfiguracyjnym. + Jeśli oba są dostępne dla danego process, Nextflow będzie priorytetyzować kontenery. + + I jak zauważono wcześniej, Nextflow obsługuje wiele innych technologii pakowania oprogramowania i kontenerów, więc nie jesteś ograniczony tylko do tych dwóch. + +### Podsumowanie + +Wiesz, jak skonfigurować, jakiego pakietu oprogramowania powinien używać każdy process i jak przełączać się między technologiami. + +### Co dalej? + +Dowiedz się, jak zmienić platformę wykonawczą używaną przez Nextflow do faktycznego wykonywania pracy. + +--- + +## 4. Wybierz platformę wykonawczą + +??? example "Scenariusz" + + Rozwijałeś i testowałeś swój pipeline na laptopie, ale teraz musisz uruchomić go na tysiącach próbek. + Twoja instytucja ma klaster HPC z harmonogramem Slurm, którego chciałbyś użyć. + +Do tej pory uruchamialiśmy nasz pipeline z lokalnym executorem. +Ten wykonuje każde zadanie na maszynie, na której działa Nextflow. +Gdy Nextflow się uruchamia, sprawdza dostępne procesory i pamięć. +Jeśli zasoby zadań gotowych do uruchomienia przekraczają dostępne zasoby, Nextflow wstrzyma ostatnie zadania przed wykonaniem, dopóki jedno lub więcej wcześniejszych zadań nie zakończy się, zwalniając niezbędne zasoby. + +Lokalny executor jest wygodny i wydajny, ale jest ograniczony do tej jednej maszyny. Dla bardzo dużych obciążeń możesz odkryć, że Twoja lokalna maszyna jest wąskim gardłem, albo dlatego, że masz pojedyncze zadanie wymagające więcej zasobów niż masz dostępne, albo dlatego, że masz tak wiele zadań, że czekanie, aż pojedyncza maszyna je uruchomi, zajęłoby zbyt długo. + +Nextflow obsługuje [wiele różnych backendów wykonawczych](https://www.nextflow.io/docs/latest/executor.html), w tym harmonogramy HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor i inne), a także backendy wykonywania w chmurze, takie jak (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes i więcej). + +### 4.1. Celowanie w inny backend + +Wybór executora jest ustawiany przez dyrektywę process o nazwie `executor`. +Domyślnie jest ustawiony na `local`, więc następująca konfiguracja jest domniemana: + +```groovy title="Wbudowana konfiguracja" +process { + executor = 'local' +} +``` + +Aby ustawić executor do celowania w inny backend, wystarczy określić executor, którego chcesz, używając podobnej składni jak opisano powyżej dla alokacji zasobów (zobacz [dokumentację](https://www.nextflow.io/docs/latest/executor.html) dla wszystkich opcji). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Ostrzeżenie" + + Nie możemy tego faktycznie przetestować w środowisku szkoleniowym, ponieważ nie jest ono skonfigurowane do łączenia się z HPC. + +### 4.2. Radzenie sobie ze składnią specyficzną dla backendu dla parametrów wykonania + +Większość platform obliczeniowych o wysokiej wydajności pozwala (a czasami wymaga), abyś określił pewne parametry, takie jak żądania alokacji zasobów i ograniczenia (np. liczba procesorów i pamięć) oraz nazwę kolejki zadań do użycia. + +Niestety, każdy z tych systemów używa różnych technologii, składni i konfiguracji do definiowania, jak zadanie powinno być zdefiniowane i przesłane do odpowiedniego harmonogramu. + +??? abstract "Przykłady" + + Na przykład to samo zadanie wymagające 8 procesorów i 4GB RAM do wykonania w kolejce "my-science-work" musi być wyrażone na różne sposoby w zależności od backendu. + + ```bash title="Config dla SLURM / przesyłanie przez sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config dla PBS / przesyłanie przez qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config dla SGE / przesyłanie przez qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Na szczęście Nextflow to wszystko upraszcza. +Zapewnia znormalizowaną składnię, dzięki której możesz określić odpowiednie właściwości, takie jak `cpus`, `memory` i `queue` (zobacz dokumentację dla innych właściwości) tylko raz. +Następnie, w czasie wykonania, Nextflow użyje tych ustawień do wygenerowania odpowiednich skryptów specyficznych dla backendu na podstawie ustawienia executora. + +Omówimy tę znormalizowaną składnię w następnej sekcji. + +### Podsumowanie + +Teraz wiesz, jak zmienić executor, aby używać różnych rodzajów infrastruktury obliczeniowej. + +### Co dalej? + +Dowiedz się, jak oceniać i wyrażać alokacje i ograniczenia zasobów w Nextflow. + +--- + +## 5. Kontroluj alokacje zasobów obliczeniowych + +??? example "Scenariusz" + + Twój pipeline ciągle zawodzi na klastrze, ponieważ zadania są zabijane za przekroczenie limitów pamięci. + Lub może jesteś obciążany za zasoby, których nie używasz i chcesz zoptymalizować koszty. + +Większość platform obliczeniowych o wysokiej wydajności pozwala (a czasami wymaga), abyś określił pewne parametry alokacji zasobów, takie jak liczba procesorów i pamięć. + +Domyślnie Nextflow użyje jednego procesora i 2GB pamięci dla każdego process. +Odpowiednie dyrektywy process nazywają się `cpus` i `memory`, więc następująca konfiguracja jest domniemana: + +```groovy title="Wbudowana konfiguracja" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Możesz modyfikować te wartości, zarówno dla wszystkich procesów, jak i dla konkretnych nazwanych procesów, używając dodatkowych dyrektyw process w pliku konfiguracyjnym. +Nextflow przetłumaczy je na odpowiednie instrukcje dla wybranego executora. + +Ale skąd wiesz, jakich wartości użyć? + +### 5.1. Uruchom workflow, aby wygenerować raport wykorzystania zasobów + +??? example "Scenariusz" + + Nie wiesz, ile pamięci lub CPU potrzebują Twoje procesy i chcesz uniknąć marnowania zasobów lub zabijania zadań. + +Jeśli nie wiesz z góry, ile CPU i pamięci prawdopodobnie będą potrzebować Twoje procesy, możesz przeprowadzić profilowanie zasobów, co oznacza, że uruchamiasz workflow z pewnymi domyślnymi alokacjami, rejestrujesz, ile każdy process użył, i na tej podstawie szacujesz, jak dostosować bazowe alokacje. + +Wygodnie, Nextflow zawiera wbudowane narzędzia do tego i chętnie wygeneruje dla Ciebie raport na żądanie. + +Aby to zrobić, dodaj `-with-report <nazwa_pliku>.html` do wiersza poleceń. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Raport jest plikiem html, który możesz pobrać i otworzyć w przeglądarce. Możesz również kliknąć go prawym przyciskiem myszy w eksploratorze plików po lewej stronie i kliknąć `Show preview`, aby wyświetlić go w środowisku szkoleniowym. + +Poświęć kilka minut na przejrzenie raportu i sprawdź, czy możesz zidentyfikować jakieś możliwości dostosowania zasobów. +Upewnij się, że klikasz na karty pokazujące wyniki wykorzystania jako procent tego, co zostało przydzielone. +Jest [dokumentacja](https://www.nextflow.io/docs/latest/reports.html) opisująca wszystkie dostępne funkcje. + +### 5.2. Ustaw alokacje zasobów dla wszystkich procesów + +Profilowanie pokazuje, że procesy w naszym szkoleniowym workflow są bardzo lekkie, więc zmniejszmy domyślną alokację pamięci do 1GB na process. + +Dodaj następujący kod do pliku `nextflow.config`, przed sekcją parametrów pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +To pomoże zmniejszyć ilość zużywanych zasobów obliczeniowych. + +### 5.3. Ustaw alokacje zasobów dla konkretnego process + +Jednocześnie będziemy udawać, że process `cowpy` wymaga więcej zasobów niż inne, tylko po to, abyśmy mogli zademonstrować, jak dostosować alokacje dla indywidualnego process. + +=== "Po" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Przed" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Z tą konfiguracją wszystkie procesy będą żądać 1GB pamięci i jednego procesora (domniemana wartość domyślna), z wyjątkiem process `cowpy`, który będzie żądał 2GB i 2 procesorów. + +!!! info "Informacja" + + Jeśli masz maszynę z małą liczbą procesorów i przydzielasz dużą liczbę na process, możesz zobaczyć, że wywołania process są kolejkowane jedno za drugim. + To dlatego, że Nextflow zapewnia, że nie żądamy więcej procesorów niż jest dostępnych. + +### 5.4. Uruchom workflow ze zaktualizowaną konfiguracją + +Wypróbujmy to, podając inną nazwę pliku dla raportu profilowania, abyśmy mogli porównać wydajność przed i po zmianach konfiguracji. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Prawdopodobnie nie zauważysz żadnej rzeczywistej różnicy, ponieważ to jest tak małe obciążenie, ale to jest podejście, którego użyjesz do analizy wydajności i wymagań zasobowych rzeczywistego workflow. + +Jest to bardzo przydatne, gdy Twoje procesy mają różne wymagania zasobowe. Pozwala Ci odpowiednio dostosować alokacje zasobów, które ustawiasz dla każdego process na podstawie rzeczywistych danych, a nie domysłów. + +!!! tip "Wskazówka" + + To tylko mały przedsmak tego, co możesz zrobić, aby zoptymalizować wykorzystanie zasobów. + Sam Nextflow ma wbudowaną naprawdę sprytną [dynamiczną logikę ponownych prób](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) do ponownego uruchamiania zadań, które nie powiodły się z powodu ograniczeń zasobów. + Dodatkowo platforma Seqera oferuje narzędzia oparte na sztucznej inteligencji do automatycznej optymalizacji alokacji zasobów. + +### 5.5. Dodaj limity zasobów + +W zależności od tego, jakiego executora i infrastruktury obliczeniowej używasz, mogą istnieć pewne ograniczenia dotyczące tego, co możesz (lub musisz) przydzielić. +Na przykład Twój klaster może wymagać, abyś pozostał w określonych limitach. + +Możesz użyć dyrektywy `resourceLimits`, aby ustawić odpowiednie ograniczenia. Składnia wygląda tak, gdy jest sama w bloku process: + +```groovy title="Przykład składni" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow przetłumaczy te wartości na odpowiednie instrukcje w zależności od określonego executora. + +Nie będziemy tego uruchamiać, ponieważ nie mamy dostępu do odpowiedniej infrastruktury w środowisku szkoleniowym. +Jednak gdybyś spróbował uruchomić workflow z alokacjami zasobów przekraczającymi te limity, a następnie sprawdził polecenie `sbatch` w pliku skryptu `.command.run`, zobaczyłbyś, że żądania, które faktycznie są wysyłane do executora, są ograniczone do wartości określonych przez `resourceLimits`. + +??? info "Instytucjonalne konfiguracje referencyjne" + + Projekt nf-core skompilował [kolekcję plików konfiguracyjnych](https://nf-co.re/configs/) udostępnionych przez różne instytucje na całym świecie, obejmujących szeroką gamę executorów HPC i chmurowych. + + Te udostępnione konfiguracje są wartościowe zarówno dla osób, które tam pracują i mogą po prostu wykorzystać konfigurację swojej instytucji od razu, jak i jako model dla osób, które chcą opracować konfigurację dla własnej infrastruktury. + +### Podsumowanie + +Wiesz, jak wygenerować raport profilowania do oceny wykorzystania zasobów i jak modyfikować alokacje zasobów dla wszystkich procesów i/lub dla poszczególnych procesów, a także ustawiać ograniczenia zasobów do uruchamiania na HPC. + +### Co dalej? + +Dowiedz się, jak skonfigurować predefiniowane profile konfiguracji i przełączać się między nimi w czasie wykonania. + +--- + +## 6. Używaj profili do przełączania między predefiniowanymi konfiguracjami + +??? example "Scenariusz" + + Regularnie przełączasz się między uruchamianiem pipeline na laptopie do rozwoju i na HPC swojej instytucji do uruchomień produkcyjnych. + Masz dość ręcznego zmieniania ustawień konfiguracji za każdym razem, gdy zmieniasz środowiska. + +Pokazaliśmy Ci wiele sposobów, w jakie możesz dostosować konfigurację pipeline w zależności od projektu, nad którym pracujesz, lub środowiska obliczeniowego, którego używasz. + +Możesz chcieć przełączać się między alternatywnymi ustawieniami w zależności od tego, jakiej infrastruktury obliczeniowej używasz. Na przykład możesz chcieć rozwijać i uruchamiać małe testy lokalnie na laptopie, a następnie uruchamiać pełnoskalowe obciążenia na HPC lub w chmurze. + +Nextflow pozwala Ci skonfigurować dowolną liczbę profili, które opisują różne konfiguracje, które możesz następnie wybrać w czasie wykonania używając argumentu wiersza poleceń, zamiast modyfikować sam plik konfiguracyjny. + +### 6.1. Utwórz profile do przełączania między lokalnym rozwojem a wykonaniem na HPC + +Skonfigurujmy dwa alternatywne profile; jeden do uruchamiania małych obciążeń na zwykłym komputerze, gdzie będziemy używać kontenerów Docker, i jeden do uruchamiania na uniwersyteckim HPC z harmonogramem Slurm, gdzie będziemy używać pakietów Conda. + +#### 6.1.1. Skonfiguruj profile + +Dodaj następujący kod do pliku `nextflow.config`, po sekcji parametrów pipeline, ale przed ustawieniami wyjść: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Widzisz, że dla uniwersyteckiego HPC określamy również ograniczenia zasobów. + +#### 6.1.2. Uruchom workflow z profilem + +Aby określić profil w wierszu poleceń Nextflow, używamy argumentu `-profile`. + +Spróbujmy uruchomić workflow z konfiguracją `my_laptop`. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Jak widzisz, to pozwala nam bardzo wygodnie przełączać się między konfiguracjami w czasie wykonania. + +!!! warning "Ostrzeżenie" + + Profil `univ_hpc` nie będzie działał prawidłowo w środowisku szkoleniowym, ponieważ nie mamy dostępu do harmonogramu Slurm. + +Jeśli w przyszłości znajdziemy inne elementy konfiguracji, które zawsze współwystępują z tymi, możemy po prostu dodać je do odpowiedniego profilu(ów). +Możemy również tworzyć dodatkowe profile, jeśli są inne elementy konfiguracji, które chcemy zgrupować. + +### 6.2. Utwórz profil parametrów testowych + +??? example "Scenariusz" + + Chcesz, aby inni mogli szybko wypróbować Twój pipeline bez zbierania własnych danych wejściowych. + +Profile służą nie tylko do konfiguracji infrastruktury. +Możemy ich również używać do ustawiania wartości domyślnych dla parametrów workflow, aby ułatwić innym wypróbowanie workflow bez konieczności samodzielnego zbierania odpowiednich wartości wejściowych. +Możesz rozważyć to jako alternatywę dla używania pliku parametrów. + +#### 6.2.1. Skonfiguruj profil + +Składnia wyrażania wartości domyślnych w tym kontekście wygląda tak, dla profilu, który nazywamy `test`: + +```groovy title="Przykład składni" + test { + params.<parametr1> + params.<parametr2> + ... + } +``` + +Jeśli dodamy profil testowy dla naszego workflow, blok `profiles` staje się: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Tak jak w przypadku profili konfiguracji technicznej, możesz skonfigurować wiele różnych profili określających parametry pod dowolną arbitralną nazwą. + +#### 6.2.2. Uruchom workflow lokalnie z profilem testowym + +Wygodnie, profile nie wykluczają się wzajemnie, więc możemy określić wiele profili w wierszu poleceń używając następującej składni `-profile <profil1>,<profil2>` (dla dowolnej liczby profili). + +Jeśli łączysz profile, które ustawiają wartości dla tych samych elementów konfiguracji i są opisane w tym samym pliku konfiguracyjnym, Nextflow rozwiąże konflikt, używając tej wartości, którą odczytał jako ostatnią (_tzn._ to, co pojawia się później w pliku). +Jeśli konfliktujące ustawienia są ustawione w różnych źródłach konfiguracji, obowiązuje domyślna [kolejność pierwszeństwa](https://www.nextflow.io/docs/latest/config.html). + +Spróbujmy dodać profil testowy do naszego poprzedniego polecenia: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +To użyje Docker, gdzie to możliwe, i wyprodukuje wyjścia w `results/test`, a tym razem postacią jest komiczny duet `dragonandcow`. + +??? abstract "Zawartość pliku" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +To oznacza, że dopóki dystrybuujemy jakiekolwiek pliki danych testowych z kodem workflow, każdy może szybko wypróbować workflow bez konieczności dostarczania własnych danych wejściowych przez wiersz poleceń lub plik parametrów. + +!!! tip "Wskazówka" + + Możemy wskazać URL-e dla większych plików, które są przechowywane zewnętrznie. + Nextflow automatycznie je pobierze, o ile istnieje otwarte połączenie. + + Więcej szczegółów znajdziesz w Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Użyj `nextflow config`, aby zobaczyć rozwiązaną konfigurację + +Jak zauważono powyżej, czasami ten sam parametr może być ustawiony na różne wartości w profilach, które chcesz połączyć. +I bardziej ogólnie, jest wiele miejsc, w których mogą być przechowywane elementy konfiguracji, a czasami te same właściwości mogą być ustawione na różne wartości w różnych miejscach. + +Nextflow stosuje ustaloną [kolejność pierwszeństwa](https://www.nextflow.io/docs/latest/config.html) do rozwiązywania wszelkich konfliktów, ale może to być trudne do samodzielnego określenia. +I nawet jeśli nic nie jest w konflikcie, może być żmudne sprawdzanie wszystkich możliwych miejsc, gdzie rzeczy mogą być skonfigurowane. + +Na szczęście Nextflow zawiera wygodne narzędzie o nazwie `config`, które może zautomatyzować cały ten proces za ciebie. + +Narzędzie `config` zbada całą zawartość w bieżącym katalogu roboczym, zbierze wszystkie pliki konfiguracyjne i wyprodukuje w pełni rozwiązaną konfigurację, której Nextflow użyłby do uruchomienia workflow. +To pozwala Ci dowiedzieć się, jakie ustawienia zostaną użyte bez konieczności uruchamiania czegokolwiek. + +#### 6.3.1. Rozwiąż domyślną konfigurację + +Uruchom to polecenie, aby rozwiązać konfigurację, która zostałaby zastosowana domyślnie. + +```bash +nextflow config +``` + +??? success "Wyjście polecenia" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +To pokazuje Ci bazową konfigurację, którą otrzymujesz, jeśli nie określisz niczego dodatkowego w wierszu poleceń. + +#### 6.3.2. Rozwiąż konfigurację z aktywowanymi konkretnymi ustawieniami + +Jeśli podasz parametry wiersza poleceń, np. włączając jeden lub więcej profili lub ładując plik parametrów, polecenie dodatkowo je uwzględni. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Wyjście polecenia" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +To jest szczególnie przydatne dla złożonych projektów, które obejmują wiele warstw konfiguracji. + +### Podsumowanie + +Wiesz, jak używać profili do wybierania predefiniowanej konfiguracji w czasie wykonania z minimalnym wysiłkiem. +Bardziej ogólnie, wiesz, jak konfigurować wykonania workflow, aby pasowały do różnych platform obliczeniowych i zwiększyć odtwarzalność analiz. + +### Co dalej? + +Dowiedz się, jak uruchamiać pipeline bezpośrednio ze zdalnych repozytoriów, takich jak GitHub. + +--- + +## 7. Uruchamiaj pipeline ze zdalnych repozytoriów + +??? example "Scenariusz" + + Chcesz uruchomić dobrze ugruntowany pipeline, taki jak te z nf-core, bez konieczności samodzielnego pobierania i zarządzania kodem. + +Do tej pory uruchamialiśmy skrypty workflow znajdujące się w bieżącym katalogu. +W praktyce często będziesz chciał uruchamiać pipeline przechowywane w zdalnych repozytoriach, takich jak GitHub. + +Nextflow czyni to prostym: możesz uruchomić dowolny pipeline bezpośrednio z URL repozytorium Git bez wcześniejszego ręcznego pobierania. + +### 7.1. Uruchom pipeline z GitHub + +Podstawowa składnia do uruchamiania zdalnego pipeline to `nextflow run <repozytorium>`, gdzie `<repozytorium>` może być ścieżką repozytorium GitHub jak `nextflow-io/hello`, pełnym URL-em lub ścieżką do GitLab, Bitbucket lub innych usług hostingu Git. + +Spróbuj uruchomić oficjalny demo pipeline Nextflow "hello": + +```bash +nextflow run nextflow-io/hello +``` + +Za pierwszym razem, gdy uruchamiasz zdalny pipeline, Nextflow pobiera go i buforuje lokalnie. +Kolejne uruchomienia używają wersji z pamięci podręcznej, chyba że wyraźnie zażądasz aktualizacji. + +### 7.2. Określ wersję dla odtwarzalności + +Domyślnie Nextflow uruchamia najnowszą wersję z domyślnej gałęzi. +Możesz określić konkretną wersję, gałąź lub commit używając flagi `-r`: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Określanie dokładnych wersji jest niezbędne dla odtwarzalności. + +### Podsumowanie + +Wiesz, jak uruchamiać pipeline bezpośrednio z GitHub i innych zdalnych repozytoriów oraz jak określać wersje dla odtwarzalności. + +### Co dalej? + +Pochwal się sam! +Wiesz wszystko, co musisz wiedzieć, aby rozpocząć uruchamianie i zarządzanie pipeline Nextflow. + +To kończy ten kurs, ale jeśli chcesz kontynuować naukę, mamy dwie główne rekomendacje: + +- Jeśli chcesz zagłębić się w tworzenie własnych pipeline, zajrzyj do [Hello Nextflow](../hello_nextflow/index.md), kursu dla początkujących, który obejmuje tę samą ogólną progresję co ten, ale wchodzi w znacznie więcej szczegółów na temat channel i operatorów. +- Jeśli chciałbyś kontynuować naukę uruchamiania pipeline Nextflow bez zagłębiania się w kod, zajrzyj do pierwszej części [Hello nf-core](../hello_nf-core/index.md), która wprowadza narzędzia do znajdowania i uruchamiania pipeline z niezwykle popularnego projektu [nf-core](https://nf-co.re/). + +Baw się dobrze! + +--- + +## Quiz + +<quiz> +Gdy wartości parametrów są ustawione zarówno w pliku workflow, jak i w `nextflow.config`, która ma pierwszeństwo? +- [ ] Wartość z pliku workflow +- [x] Wartość z pliku konfiguracyjnego +- [ ] Pierwsza napotkana wartość +- [ ] To powoduje błąd + +Dowiedz się więcej: [1.1. Ustaw wartości w `nextflow.config`](#11-ustaw-wartosci-w-nextflowconfig) +</quiz> + +<quiz> +Jaka jest różnica składniowa między ustawianiem domyślnej wartości parametru w pliku workflow a w pliku config? +- [ ] Używają tej samej składni +- [x] Workflow używa deklaracji typowanej (`#!groovy param: Type = value`), config używa przypisania (`#!groovy param = value`) +- [ ] Config używa deklaracji typowanej, workflow używa przypisania +- [ ] Tylko pliki config mogą ustawiać wartości domyślne + +Dowiedz się więcej: [1.1. Ustaw wartości w `nextflow.config`](#11-ustaw-wartosci-w-nextflowconfig) +</quiz> + +<quiz> +Jak określisz plik parametrów podczas uruchamiania workflow? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Dowiedz się więcej: [1.3. Użyj pliku parametrów](#13-uzyj-pliku-parametrow) +</quiz> + +<quiz> +Co kontroluje opcja konfiguracji `outputDir`? +- [ ] Lokalizację katalogu roboczego +- [x] Bazową ścieżkę, gdzie publikowane są wyjścia workflow +- [ ] Katalog dla plików dziennika +- [ ] Lokalizację plików modułów + +Dowiedz się więcej: [2.1. Dostosuj nazwę katalogu outputDir](#21-dostosuj-nazwe-katalogu-outputdir) +</quiz> + +<quiz> +Jak odwołujesz się do nazwy process dynamicznie w konfiguracji ścieżki wyjścia? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Dowiedz się więcej: [2.2. Organizuj wyjścia według process](#22-organizuj-wyjscia-wedlug-process) +</quiz> + +<quiz> +Jeśli zarówno Docker, jak i Conda są włączone i process ma obie dyrektywy, która ma priorytet? +- [x] Docker (kontenery) +- [ ] Conda +- [ ] Pierwsza zdefiniowana w process +- [ ] To powoduje błąd + +Dowiedz się więcej: [3. Wybierz technologię pakowania oprogramowania](#3-wybierz-technologie-pakowania-oprogramowania) +</quiz> + +<quiz> +Jaki jest domyślny executor w Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Dowiedz się więcej: [4. Wybierz platformę wykonawczą](#4-wybierz-platforme-wykonawcza) +</quiz> + +<quiz> +Jakie polecenie generuje raport wykorzystania zasobów? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Dowiedz się więcej: [5.1. Uruchom workflow, aby wygenerować raport wykorzystania zasobów](#51-uruchom-workflow-aby-wygenerowac-raport-wykorzystania-zasobow) +</quiz> + +<quiz> +Jak ustawiasz wymagania zasobowe dla konkretnego process o nazwie `cowpy` w pliku config? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Dowiedz się więcej: [5.3. Ustaw alokacje zasobów dla konkretnego process](#53-ustaw-alokacje-zasobow-dla-konkretnego-process) +</quiz> + +<quiz> +Co robi dyrektywa `resourceLimits`? +- [ ] Ustawia minimalne wymagania zasobowe +- [ ] Przydziela zasoby do procesów +- [x] Ogranicza maksymalne zasoby, które można zażądać +- [ ] Monitoruje wykorzystanie zasobów w czasie rzeczywistym + +Dowiedz się więcej: [5.5. Dodaj limity zasobów](#55-dodaj-limity-zasobow) +</quiz> + +<quiz> +Jak określasz wiele profili w jednym poleceniu? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Dowiedz się więcej: [6. Używaj profili do przełączania między predefiniowanymi konfiguracjami](#6-uzywaj-profili-do-przelaczania-miedzy-predefiniowanymi-konfiguracjami) +</quiz> + +<quiz> +Jakie polecenie pokazuje w pełni rozwiązaną konfigurację, której użyłby Nextflow? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Dowiedz się więcej: [6.3. Użyj `nextflow config`, aby zobaczyć rozwiązaną konfigurację](#63-uzyj-nextflow-config-aby-zobaczyc-rozwiazana-konfiguracje) +</quiz> + +<quiz> +Do czego mogą być używane profile? (Wybierz wszystkie, które pasują) +- [x] Definiowanie ustawień specyficznych dla infrastruktury (executory, kontenery) +- [x] Ustawianie limitów zasobów dla różnych środowisk +- [x] Dostarczanie parametrów testowych do łatwego testowania workflow +- [ ] Definiowanie nowych procesów + +Dowiedz się więcej: [6. Używaj profili do przełączania między predefiniowanymi konfiguracjami](#6-uzywaj-profili-do-przelaczania-miedzy-predefiniowanymi-konfiguracjami) +</quiz> diff --git a/docs/pl/docs/nextflow_run/index.md b/docs/pl/docs/nextflow_run/index.md new file mode 100644 index 0000000000..9ea3e792b8 --- /dev/null +++ b/docs/pl/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Uruchamianie i zarządzanie wykonywaniem workflow Nextflow + - Znajdowanie i interpretowanie wyników oraz plików dziennika + - Rozpoznawanie podstawowych komponentów Nextflow w prostym wieloetapowym workflow + - Konfigurowanie wykonywania pipeline na popularnych platformach obliczeniowych, w tym HPC i chmurze + - Podsumowanie najlepszych praktyk dotyczących odtwarzalności, przenośności i ponownego wykorzystania kodu, które czynią pipeline zgodnymi z zasadami FAIR, w tym modułowość kodu i kontenery oprogramowania + audience_prerequisites: + - "**Odbiorcy:** Ten kurs jest przeznaczony dla osób, które są całkowicie nowe w Nextflow i chcą uruchamiać istniejące pipeline." + - "**Umiejętności:** Zakładana jest pewna znajomość wiersza poleceń, podstawowych koncepcji skryptowania i popularnych formatów plików." + - "**Dziedzina:** Wszystkie ćwiczenia są niezależne od domeny, więc nie jest wymagana wcześniejsza wiedza naukowa." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run to praktyczne wprowadzenie do uruchamiania odtwarzalnych i skalowalnych workflow analizy danych.** + +Pracując z praktycznymi przykładami i ćwiczeniami z przewodnikiem, poznasz podstawy używania Nextflow, w tym jak wykonywać pipeline, zarządzać plikami i zależnościami oprogramowania, bez wysiłku równoleglić wykonywanie i uruchamiać workflow w różnych środowiskach obliczeniowych. + +Zdobędziesz umiejętności i pewność siebie, aby rozpocząć uruchamianie workflow z Nextflow. + +<!-- additional_information --> + +## Przegląd kursu + +### Co będziesz robić + +Ten kurs jest praktyczny, z ćwiczeniami zorientowanymi na cele, zaprojektowanymi tak, aby stopniowo wprowadzać informacje. + +Wykonasz kilka wersji pipeline Nextflow, który przetwarza tekstowe dane wejściowe. +Zaczniesz od prostej wersji składającej się z jednego kroku, a ostatecznie przejdziesz do wieloetapowej wersji, która pobiera plik CSV z tabelarycznymi danymi tekstowymi, wykonuje kilka kroków transformacji i generuje pojedynczy plik tekstowy zawierający obraz ASCII postaci mówiącej przekształcony tekst. + +Ten kurs koncentruje się na uruchamianiu pipeline (nazwany od podstawowego polecenia `nextflow run`). +Jeśli szukasz wprowadzenia do tworzenia pipeline Nextflow, zobacz [Hello Nextflow](../hello_nextflow/index.md). + +### Plan lekcji + +Podzieliliśmy to na trzy części, z których każda koncentruje się na konkretnych aspektach uruchamiania i zarządzania pipeline napisanymi w Nextflow. + +| Rozdział kursu | Podsumowanie | Szacowany czas | +| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | +| [Część 1: Podstawowe operacje](./01_basics.md) | Uruchamianie i zarządzanie wykonywaniem prostego workflow | 30 min | +| [Część 2: Uruchamianie prawdziwych pipeline](./02_pipeline.md) | Przetwarzanie złożonych danych wejściowych, uruchamianie wieloetapowych workflow, używanie kontenerów i bezproblemowe równoleglenie wykonywania | 60 min | +| [Część 3: Konfiguracja uruchamiania](./03_config.md) | Dostosowywanie zachowania pipeline i optymalizacja użycia w różnych środowiskach obliczeniowych | 60 min | + +Pod koniec tego kursu będziesz dobrze przygotowany do podjęcia kolejnych kroków w swojej podróży ku uruchamianiu odtwarzalnych workflow dla potrzeb obliczeń naukowych. + +Gotowy do rozpoczęcia kursu? + +[Rozpocznij naukę :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/pl/docs/nextflow_run/next_steps.md b/docs/pl/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..4876d251c9 --- /dev/null +++ b/docs/pl/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Podsumowanie kursu + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gratulacje z okazji ukończenia kursu szkoleniowego Nextflow Run! + +<!-- placeholder for video --> + +## Twoja podróż + +Zacząłeś od bardzo podstawowego workflow i nauczyłeś się go uruchamiać, znajdować wyjścia i zarządzać jego wykonaniem. +Następnie pracowałeś przez coraz bardziej złożone wersje tego workflow i nauczyłeś się rozpoznawać podstawowe koncepcje i mechanizmy, które napędzają pipeline Nextflow, w tym channel i operatory, modularyzację kodu i kontenery. +Na koniec nauczyłeś się, jak dostosować konfigurację pipeline do swoich preferencji i infrastruktury obliczeniowej. + +### Czego się nauczyłeś + +Jesteś teraz w stanie zarządzać wykonaniem pipeline Hello, opisać, jak jest zbudowany, i zidentyfikować główne elementy kodu. + +- Końcowa forma workflow Hello przyjmuje jako dane wejściowe plik CSV zawierający tekstowe powitania. +- Cztery kroki są zaimplementowane jako procesy Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` i `cowpy`) przechowywane w oddzielnych plikach modułów. +- Wyniki są publikowane do katalogu o nazwie `results/`. +- Końcowym wyjściem pipeline jest plik tekstowy zawierający grafikę ASCII postaci mówiącej powitania wielkimi literami. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Zapisuje każde powitanie do własnego pliku wyjściowego (_np._ "Hello-output.txt") +2. **`convertToUpper`:** Konwertuje każde powitanie na wielkie litery (_np._ "HELLO") +3. **`collectGreetings`:** Zbiera wszystkie powitania wielkimi literami do jednego pliku batch +4. **`cowpy`:** Generuje grafikę ASCII przy użyciu narzędzia `cowpy` + +Konfiguracja workflow wspiera dostarczanie danych wejściowych i parametrów w elastyczny, odtwarzalny sposób. + +### Zdobyte umiejętności + +Dzięki temu praktycznemu kursowi nauczyłeś się: + +- Uruchamiać workflow Nextflow lokalnie +- Znajdować i interpretować wyjścia (wyniki) i pliki dziennika generowane przez Nextflow +- Rozpoznawać podstawowe komponenty Nextflow, które tworzą prosty wieloetapowy workflow +- Opisywać koncepcje następnego poziomu, takie jak operatory i fabryki channel +- Konfigurować pipeline dla różnych środowisk obliczeniowych + +Jesteś teraz wyposażony w podstawową wiedzę, aby zacząć integrować istniejące pipeline Nextflow ze swoją własną pracą. + +## Następne kroki do rozwijania umiejętności + +Oto nasze najważniejsze sugestie, co robić dalej: + +- Nie tylko uruchamiaj Nextflow, pisz go! Zostań programistą Nextflow z [Hello Nextflow](../hello_nextflow/index.md) +- Zastosuj Nextflow do naukowego przypadku użycia z [Nextflow for Science](../nf4_science/index.md) +- Rozpocznij pracę z nf-core z [Hello nf-core](../hello_nf-core/index.md) +- Poznaj techniki rozwiązywania problemów z [Debugging Side Quest](../side_quests/debugging.md) + +Na koniec zalecamy zapoznanie się z [**Seqera Platform**](https://seqera.io/), platformą chmurową rozwijaną przez twórców Nextflow, która jeszcze bardziej ułatwia uruchamianie i zarządzanie workflow, a także zarządzanie danymi i interaktywne uruchamianie analiz w dowolnym środowisku. + +## Uzyskiwanie pomocy + +Zasoby pomocy i wsparcie społeczności znajdziesz na [stronie Pomocy](../help.md). + +## Ankieta zwrotna + +Zanim przejdziesz dalej, poświęć chwilę na wypełnienie ankiety kursu! Twoja opinia pomaga nam ulepszać nasze materiały szkoleniowe dla wszystkich. + +[Wypełnij ankietę :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pl/docs/nextflow_run/survey.md b/docs/pl/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..140c17c0c4 --- /dev/null +++ b/docs/pl/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Ankieta zwrotna + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Zanim przejdziesz dalej, wypełnij tę krótką 5-pytaniową ankietę, aby ocenić szkolenie, podzielić się opinią o swoich doświadczeniach i powiedzieć nam, co jeszcze moglibyśmy zrobić, aby pomóc Ci w Twojej podróży z Nextflow. + +Wypełnienie powinno zająć mniej niż minutę. Dziękujemy za pomoc w ulepszaniu naszych materiałów szkoleniowych dla wszystkich! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pl/docs/nf4_science/genomics/00_orientation.md b/docs/pl/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..a97a64b987 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientacja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Środowisko szkoleniowe zawiera wszystkie oprogramowanie, kod i dane niezbędne do pracy z tym kursem szkoleniowym, więc nie musisz niczego instalować samodzielnie. +Jednakże potrzebujesz (bezpłatnego) konta, aby się zalogować, i powinieneś poświęcić kilka minut na zapoznanie się z interfejsem. + +Jeśli jeszcze tego nie zrobiłeś, proszę skorzystaj z [tego linku](../../../envsetup/) przed dalszym przejściem. + +## Dostarczone materiały + +Przez cały kurs szkoleniowy będziemy pracować w katalogu `nf4-science/genomics/`, do którego musisz przejść po otwarciu przestrzeni roboczej szkolenia. +Ten katalog zawiera wszystkie pliki kodu, dane testowe i pliki pomocnicze, których będziesz potrzebować. + +Możesz swobodnie eksplorować zawartość tego katalogu; najłatwiejszym sposobem jest użycie eksploratora plików po lewej stronie przestrzeni roboczej szkolenia w interfejsie VSCode. +Alternatywnie możesz użyć polecenia `tree`. +W trakcie kursu używamy wyjścia z `tree` do przedstawienia struktury i zawartości katalogów w czytelnej formie, czasami z niewielkimi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu w dół: + +```bash +tree . -L 2 +``` + +Jeśli uruchomisz to wewnątrz `nf4-science/genomics`, powinieneś zobaczyć następujące wyjście: + +```console title="Zawartość katalogu" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Uwaga" + + Nie martw się, jeśli wydaje się to dużo; przejdziemy przez odpowiednie elementy na każdym etapie kursu. + Ma to na celu jedynie dać Ci przegląd. + +**Oto podsumowanie tego, co powinieneś wiedzieć, aby rozpocząć:** + +- **Pliki `.nf`** to skrypty workflow, które są nazwane na podstawie tego, w jakiej części kursu są używane. + +- **Plik `nextflow.config`** to plik konfiguracyjny, który ustawia minimalne właściwości środowiska. + Na razie możesz go zignorować. + +- **Katalog `data`** zawiera dane wejściowe i powiązane zasoby, opisane później w kursie. + +- **Katalog `solutions`** zawiera pliki modułów i konfiguracje testów, które są wynikiem części 3 i 4 kursu. + Są przeznaczone do użycia jako punkt odniesienia do sprawdzenia twojej pracy i rozwiązywania problemów. + +!!!tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu wyjdziesz z tego katalogu, zawsze możesz uruchomić to polecenie, aby do niego wrócić: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Teraz, aby rozpocząć kurs, kliknij strzałkę w prawym dolnym rogu tej strony. diff --git a/docs/pl/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/pl/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..219da6bf81 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1054 @@ +# Część 1: Wykrywanie wariantów dla pojedynczych próbek + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W pierwszej części tego kursu pokażemy, jak zbudować prosty pipeline do wykrywania wariantów, który aplikuje narzędzie GATK do wykrywania wariantów w indywidualnych próbkach sekwencjonowania. + +### Przegląd metody + +Wykrywanie wariantów to metoda analizy genomowej, która ma na celu identyfikację zmienności w sekwencji genomu względem genomu referencyjnego. +Tutaj użyjemy narzędzi i metod zaprojektowanych do wykrywania krótkich wariantów, _tzn._ SNP i indeli. + +![GATK pipeline](img/gatk-pipeline.png) + +Pełny pipeline do wykrywania wariantów zazwyczaj obejmuje wiele kroków, w tym mapowanie do referencji (czasami nazywane dopasowaniem genomu) oraz filtrowanie i priorytetyzację wariantów. +Dla uproszczenia, w tej części kursu skupimy się tylko na części wykrywania wariantów. + +### Zestaw danych + +Udostępniamy następujące dane i powiązane zasoby: + +- **Genom referencyjny** składający się z niewielkiego regionu ludzkiego chromosomu 20 (z hg19/b37) i jego plików pomocniczych (indeks i słownik sekwencji). +- **Trzy próbki sekwencjonowania całego genomu** odpowiadające trio rodzinnemu (matka, ojciec i syn), które zostały ograniczone do małego fragmentu danych na chromosomie 20, aby zachować małe rozmiary plików. + To dane z sekwencjonowania Illumina krótkich odczytów, które zostały już zmapowane do genomu referencyjnego, dostarczone w formacie [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) (Binary Alignment Map, skompresowana wersja SAM, Sequence Alignment Map). +- **Lista przedziałów genomowych**, _tzn._ współrzędnych na genomie, gdzie nasze próbki mają dane odpowiednie do wykrywania wariantów, dostarczona w formacie BED. + +### Workflow + +W tej części kursu opracujemy workflow, który wykonuje następujące czynności: + +1. Generuje plik indeksu dla każdego pliku wejściowego BAM używając [Samtools](https://www.htslib.org/) +2. Uruchamia GATK HaplotypeCaller na każdym pliku wejściowym BAM, aby wygenerować wykrycia wariantów dla pojedynczych próbek w formacie VCF (Variant Call Format) + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note "Uwaga" + + Pliki indeksów są powszechną cechą formatów plików bioinformatycznych; zawierają informacje o strukturze pliku głównego, które pozwalają narzędziom takim jak GATK na dostęp do podzbioru danych bez konieczności przeczytania całego pliku. + Jest to ważne ze względu na to, jak duże mogą być te pliki. + +--- + +## 0. Rozgrzewka: Przetestuj polecenia Samtools i GATK interaktywnie + +Najpierw chcemy wypróbować polecenia ręcznie, zanim spróbujemy umieścić je w workflow. +Narzędzia, których potrzebujemy (Samtools i GATK) nie są zainstalowane w środowisku GitHub Codespaces, więc użyjemy ich przez kontenery (zobacz [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Uwaga" + + Upewnij się, że jesteś w katalogu `nf4-science/genomics`, aby ostatnia część ścieżki pokazana po wpisaniu `pwd` była `genomics`. + +### 0.1. Indeksuj plik wejściowy BAM używając Samtools + +Pobierzemy kontener Samtools, uruchomimy go interaktywnie i wykonamy polecenie `samtools index` na jednym z plików BAM. + +#### 0.1.1. Pobierz kontener Samtools + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Wyjście polecenia" + + ```console + + ``` +--> + +#### 0.1.2. Uruchom kontener Samtools interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Wyjście polecenia" + + ```console + + ``` +--> + +#### 0.1.3. Uruchom polecenie indeksowania + +[Dokumentacja Samtools](https://www.htslib.org/doc/samtools-index.html) podaje nam linię poleceń do uruchomienia w celu indeksowania pliku BAM. + +Musimy tylko podać plik wejściowy; narzędzie automatycznie wygeneruje nazwę dla pliku wyjściowego, dodając `.bai` do nazwy pliku wejściowego. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +To powinno zakończyć się natychmiast, a teraz powinieneś zobaczyć plik o nazwie `reads_mother.bam.bai` w tym samym katalogu co oryginalny plik wejściowy BAM. + +??? abstract "Zawartość katalogu" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Wyjdź z kontenera Samtools + +```bash +exit +``` + +### 0.2. Wykryj warianty używając GATK HaplotypeCaller + +Pobierzemy kontener GATK, uruchomimy go interaktywnie i wykonamy polecenie `gatk HaplotypeCaller` na pliku BAM, który właśnie zaindeksowaliśmy. + +#### 0.2.1. Pobierz kontener GATK + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Wyjście polecenia" + + ```console + + ``` +--> + +#### 0.2.2. Uruchom kontener GATK interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Wyjście polecenia" + + ```console + + ``` +--> + +#### 0.2.3. Uruchom polecenie wykrywania wariantów + +[Dokumentacja GATK](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) podaje nam linię poleceń do uruchomienia w celu wykrycia wariantów w pliku BAM. + +Musimy podać plik wejściowy BAM (`-I`) oraz genom referencyjny (`-R`), nazwę dla pliku wyjściowego (`-O`) i listę przedziałów genomowych do analizy (`-L`). + +Nie musimy jednak podawać ścieżki do pliku indeksu; narzędzie automatycznie będzie go szukać w tym samym katalogu, w oparciu o ustaloną konwencję nazewnictwa i współlokalizacji. +To samo dotyczy plików pomocniczych genomu referencyjnego (pliki indeksu i słownika sekwencji, `*.fai` i `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Wyjście polecenia" + + ```console + + ``` +--> + +Plik wyjściowy `reads_mother.vcf` jest tworzony wewnątrz Twojego katalogu roboczego w kontenerze, więc nie zobaczysz go w eksploratorze plików VS Code, chyba że zmienisz ścieżkę pliku wyjściowego. +Jednak jest to mały plik testowy, więc możesz użyć `cat`, aby otworzyć i zobaczyć jego zawartość. +Jeśli przejdziesz na sam początek pliku, znajdziesz nagłówek składający się z wielu linii metadanych, po których następuje lista wykrytych wariantów, po jednym w każdej linii. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Każda linia opisuje możliwy wariant zidentyfikowany w danych sekwencjonowania próbki. Aby uzyskać wskazówki dotyczące interpretacji formatu VCF, zobacz [ten pomocny artykuł](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +Plikowi wyjściowemu VCF towarzyszy plik indeksu o nazwie `reads_mother.vcf.idx`, który został automatycznie utworzony przez GATK. +Ma taką samą funkcję jak plik indeksu BAM, aby umożliwić narzędziom wyszukiwanie i pobieranie podzbiorów danych bez ładowania całego pliku. + +#### 0.2.4. Wyjdź z kontenera GATK + +```bash +exit +``` + +### Podsumowanie + +Wiesz, jak przetestować polecenia indeksowania Samtools i wykrywania wariantów GATK w ich odpowiednich kontenerach. + +### Co dalej? + +Naucz się, jak opakować te same polecenia w dwuetapowy workflow, który używa kontenerów do wykonywania pracy. + +--- + +## 1. Napisz jednoetapowy workflow, który uruchamia Samtools index na pliku BAM + +Udostępniamy plik workflow, `genomics-1.nf`, który przedstawia główne części workflow. +Nie jest funkcjonalny; jego celem jest tylko służenie jako szkielet, którego użyjesz do napisania rzeczywistego workflow. + +### 1.1. Zdefiniuj proces indeksowania + +Zacznijmy od napisania procesu, który nazwiemy `SAMTOOLS_INDEX`, opisującego operację indeksowania. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Generuj plik indeksu BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Powinieneś rozpoznać wszystkie elementy z tego, czego nauczyłeś się w Części 1 i Części 2 tej serii szkoleń. + +Ten proces będzie wymagał od nas przekazania ścieżki pliku przez wejście `input_bam`, więc skonfigurujmy to następnie. + +### 1.2. Dodaj deklarację parametru wejściowego + +Na górze pliku, w sekcji `Pipeline parameters`, deklarujemy parametr CLI o nazwie `reads_bam` i nadajemy mu wartość domyślną. +W ten sposób możemy być leniwi i nie podawać wejścia podczas wpisywania polecenia uruchamiającego pipeline (w celach deweloperskich). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Parametry pipeline + */ +params { + // Główne wejście + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Teraz mamy gotowy proces, a także parametr do podania mu wejścia do przetworzenia, więc połączmy te rzeczy razem. + +!!! note "Uwaga" + + `${projectDir}` to wbudowana zmienna Nextflow, która wskazuje na katalog, w którym znajduje się obecny skrypt workflow Nextflow (`genomics-1.nf`). + + To ułatwia odwoływanie się do plików, katalogów danych i innych zasobów zawartych w repozytorium workflow bez kodowania ścieżek bezwzględnych. + +### 1.3. Dodaj blok workflow, aby uruchomić SAMTOOLS_INDEX + +W bloku `workflow` musimy skonfigurować **kanał**, aby przekazać wejście do procesu `SAMTOOLS_INDEX`; następnie możemy wywołać sam proces, aby uruchomić go na zawartości tego kanału. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Utwórz kanał wejściowy (pojedynczy plik przez parametr CLI) + reads_ch = channel.fromPath(params.reads_bam) + + // Utwórz plik indeksu dla wejściowego pliku BAM + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +Blok workflow ma dwie sekcje: + +- `main:` zawiera operacje na kanałach i wywołania procesów +- `publish:` deklaruje, które wyjścia powinny być opublikowane, przypisując je do nazwanych celów + +Zauważysz, że używamy tej samej fabryki kanałów `.fromPath`, której używaliśmy w [Hello Channels](../../hello_nextflow/02_hello_channels.md). +Rzeczywiście, robimy coś bardzo podobnego. +Różnica polega na tym, że mówimy Nextflow, aby po prostu załadował samą ścieżkę pliku do kanału jako element wejściowy, zamiast czytać jego zawartość. + +### 1.4. Dodaj blok output, aby zdefiniować, gdzie publikowane są wyniki + +Po bloku workflow dodajemy blok `output`, który określa, gdzie publikować wyjścia workflow. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Każdy nazwany cel z sekcji `publish:` (jak `bam_index`) otrzymuje swój własny blok, w którym można skonfigurować ścieżkę wyjściową względem bazowego katalogu wyjściowego. + +!!! note "Uwaga" + + Mimo że pliki danych, których używamy tutaj, są bardzo małe, w genomice mogą być bardzo duże. + Domyślnie Nextflow tworzy dowiązania symboliczne do plików wyjściowych w katalogu publikacji, co pozwala uniknąć niepotrzebnych kopii plików. + Możesz zmienić to zachowanie używając opcji `mode` (np. `mode 'copy'`), aby utworzyć rzeczywiste kopie. + Należy pamiętać, że dowiązania symboliczne przestaną działać po wyczyszczeniu katalogu `work`, więc dla produkcyjnych workflow możesz chcieć użyć `mode 'copy'`. + +### 1.5. Skonfiguruj katalog wyjściowy + +Bazowy katalog wyjściowy jest ustawiany przez opcję konfiguracyjną `outputDir`. Dodaj go do `nextflow.config`: + +=== "Po" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Przed" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Uruchom workflow, aby zweryfikować, że krok indeksowania działa + +Uruchommy workflow! Przypominamy, że nie musimy podawać wejścia w linii poleceń, ponieważ ustawiliśmy wartość domyślną dla wejścia podczas deklarowania parametru wejściowego. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Możesz sprawdzić, czy plik indeksu został wygenerowany poprawnie, przeglądając katalog roboczy lub katalog wyników. + +??? abstract "Zawartość katalogu roboczego" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Zawartość katalogu wyników" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +Oto jest! + +### Podsumowanie + +Wiesz, jak opakować narzędzie genomiczne w jednoetapowy workflow Nextflow i uruchomić je używając kontenera. + +### Co dalej? + +Dodaj drugi krok, który wykorzystuje wyjście pierwszego. + +--- + +## 2. Dodaj drugi proces, aby uruchomić GATK HaplotypeCaller na zaindeksowanym pliku BAM + +Teraz, gdy mamy indeks dla naszego pliku wejściowego, możemy przejść do skonfigurowania kroku wykrywania wariantów, który jest interesującą częścią workflow. + +### 2.1. Zdefiniuj proces wykrywania wariantów + +Napiszmy proces, który nazwiemy `GATK_HAPLOTYPECALLER`, opisujący operację wykrywania wariantów. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Wykryj warianty używając GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Zauważysz, że wprowadziliśmy tutaj nową składnię (`emit:`), aby jednoznacznie nazwać każdy z naszych kanałów wyjściowych, a powody tego staną się wkrótce jasne. + +To polecenie przyjmuje znacznie więcej wejść, ponieważ GATK potrzebuje więcej informacji do wykonania analizy w porównaniu do prostego zadania indeksowania. +Ale zauważysz, że jest jeszcze więcej wejść zdefiniowanych w bloku wejść niż jest wymienionych w poleceniu GATK. Dlaczego? + +!!! note "Uwaga" + + GATK wie, gdzie szukać pliku indeksu BAM i plików pomocniczych genomu referencyjnego, ponieważ zna konwencje związane z tymi plikami. + Jednak Nextflow jest zaprojektowany jako niezależny od domeny i nie wie nic o wymaganiach formatów plików bioinformatycznych. + +Musimy powiedzieć Nextflow wyraźnie, że musi umieścić te pliki w katalogu roboczym w czasie wykonywania; w przeciwnym razie tego nie zrobi, a GATK (prawidłowo) zgłosi błąd dotyczący brakujących plików indeksów. + +Podobnie musimy wyraźnie wymienić plik indeksu wyjściowego VCF (plik `"${input_bam}.vcf.idx"`), aby Nextflow wiedział, że ma śledzić ten plik na wypadek, gdyby był potrzebny w kolejnych krokach. + +### 2.2. Dodaj definicje dla wejść pomocniczych + +Ponieważ nasz nowy proces oczekuje kilku dodatkowych plików, ustawiamy dla nich parametry CLI w sekcji `Pipeline parameters`, wraz z wartościami domyślnymi (z tych samych powodów co wcześniej). + +```groovy title="genomics-1.nf" linenums="8" + // Pliki pomocnicze + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Utwórz zmienne do przechowywania ścieżek plików pomocniczych + +Podczas gdy główne wejścia danych są przesyłane dynamicznie przez kanały, istnieją dwa podejścia do obsługi plików pomocniczych. Zalecanym podejściem jest tworzenie jawnych kanałów, co sprawia, że przepływ danych jest bardziej przejrzysty i spójny. Alternatywnie, funkcja file() może być użyta do tworzenia zmiennych w prostszych przypadkach, szczególnie gdy musisz odwołać się do tego samego pliku w wielu procesach - chociaż pamiętaj, że nadal tworzy to kanały niejawnie. <!-- TODO: Wyjaśnić: czy to jest nadal konieczne z typowanymi wejściami? --> + +Dodaj to do bloku workflow (po utworzeniu `reads_ch`, wewnątrz sekcji `main:`): + +```groovy title="genomics-1.nf" linenums="79" + // Załaduj ścieżki plików dla plików pomocniczych (referencja i przedziały) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +To sprawi, że ścieżki plików pomocniczych będą dostępne do dostarczenia jako wejście do wszystkich procesów, które ich potrzebują. + +### 2.4. Dodaj wywołanie do bloku workflow, aby uruchomić GATK_HAPLOTYPECALLER + +Teraz, gdy mamy skonfigurowany nasz drugi proces i wszystkie wejścia oraz pliki pomocnicze są gotowe i dostępne, możemy dodać wywołanie procesu `GATK_HAPLOTYPECALLER` w ciele workflow. + +```groovy title="genomics-1.nf" linenums="88" + // Wykryj warianty z zaindeksowanego pliku BAM + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Powinieneś rozpoznać składnię `*.out` z Części 1 tej serii szkoleń; mówimy Nextflow, aby wziął kanał wyjściowy z `SAMTOOLS_INDEX` i podłączył go do wywołania procesu `GATK_HAPLOTYPECALLER`. + +!!! note "Uwaga" + + Zauważysz, że wejścia są podawane w dokładnie tej samej kolejności w wywołaniu procesu, jak są wymienione w bloku wejść procesu. + W Nextflow wejścia są pozycyjne, co oznacza, że _musisz_ zachować tę samą kolejność; i oczywiście musi być taka sama liczba elementów. + +### 2.5. Zaktualizuj sekcję publish i blok output + +Musimy zaktualizować sekcję `publish:`, aby uwzględnić wyjścia VCF, i dodać odpowiadające cele w bloku `output`. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Uruchom workflow, aby zweryfikować, że krok wykrywania wariantów działa + +Uruchommy rozszerzony workflow z `-resume`, aby nie musieć ponownie uruchamiać kroku indeksowania. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Teraz, jeśli spojrzymy na wyjście konsoli, zobaczymy wymienione dwa procesy. + +Pierwszy proces został pominięty dzięki cache'owaniu, zgodnie z oczekiwaniami, podczas gdy drugi proces został uruchomiony, ponieważ jest zupełnie nowy. + +Pliki wyjściowe znajdziesz w katalogu wyników (jako dowiązania symboliczne do katalogu roboczego). + +??? abstract "Zawartość katalogu" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Jeśli otworzysz plik VCF, powinieneś zobaczyć tę samą zawartość co w pliku wygenerowanym przez uruchomienie polecenia GATK bezpośrednio w kontenerze. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +To jest wyjście, które zależy nam na wygenerowaniu dla każdej próbki w naszym badaniu. + +### Podsumowanie + +Wiesz, jak zrobić bardzo prosty dwuetapowy workflow, który wykonuje prawdziwą pracę analityczną i jest w stanie radzić sobie z osobliwościami formatów plików genomicznych, takimi jak pliki pomocnicze. + +### Co dalej? + +Spraw, aby workflow obsługiwał wiele próbek zbiorczo. + +--- + +## 3. Dostosuj workflow do pracy z zestawem próbek + +Dobrze jest mieć workflow, który może zautomatyzować przetwarzanie pojedynczej próbki, ale co jeśli masz 1000 próbek? +Czy musisz napisać skrypt bash, który przechodzi przez wszystkie Twoje próbki w pętli? + +Nie, dzięki Bogu! Wystarczy dokonać drobnej zmiany w kodzie, a Nextflow również to dla Ciebie obsłuży. + +### 3.1. Przekształć deklarację parametru wejściowego w tablicę wymieniającą trzy próbki + +Przekształćmy tę domyślną ścieżkę pliku w deklaracji wejściowego pliku BAM w tablicę wymieniającą ścieżki plików dla naszych trzech próbek testowych, w górze w sekcji `Pipeline parameters`. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="7" + // Główne wejście (tablica trzech próbek) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="7" + // Główne wejście + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note "Uwaga" + + Używając typowanych deklaracji parametrów (jak `reads_bam: Path`), nie można przypisać wartości tablicowej. + Dla tablic pomiń adnotację typu. + +I to właściwie wszystko, co musimy zrobić, ponieważ fabryka kanałów, której używamy w ciele workflow (`.fromPath`), jest równie chętna do zaakceptowania wielu ścieżek plików do załadowania do kanału wejściowego, jak była do załadowania jednej. + +!!! note "Uwaga" + + Normalnie nie chciałbyś umieszczać listy próbek bezpośrednio w pliku workflow, ale robimy to tutaj, aby zachować prostotę. + Przedstawimy bardziej eleganckie sposoby obsługi wejść później w tej serii szkoleń. + +### 3.2. Uruchom workflow, aby zweryfikować, że działa na wszystkich trzech próbkach + +Spróbujmy teraz uruchomić workflow, gdy połączenia są skonfigurowane do pracy na wszystkich trzech próbkach testowych. + +```bash +nextflow run genomics-1.nf -resume +``` + +Ciekawa rzecz: to _może zadziałać_, LUB _może zawieść_. Na przykład, oto uruchomienie, które zakończyło się sukcesem: + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Jeśli Twoje uruchomienie workflow zakończyło się sukcesem, uruchom je ponownie, aż otrzymasz błąd taki jak ten: + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Jeśli spojrzysz na wyjście błędu polecenia GATK, będzie tam linia taka jak ta: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Cóż, to dziwne, biorąc pod uwagę, że wyraźnie zaindeksowaliśmy pliki BAM w pierwszym kroku workflow. Czy może być coś nie tak z połączeniami? + +#### 3.2.1. Sprawdź katalogi robocze dla odpowiednich wywołań + +Spójrzmy do środka katalogu roboczego dla nieudanego wywołania procesu `GATK_HAPLOTYPECALLER` wymienionego w wyjściu konsoli. + +??? abstract "Zawartość katalogu" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Zwróć szczególną uwagę na nazwy pliku BAM i indeksu BAM, które są wymienione w tym katalogu: `reads_son.bam` i `reads_father.bam.bai`. + +Co do cholery? Nextflow umieścił plik indeksu w katalogu roboczym tego wywołania procesu, ale jest to zły. Jak to mogło się stać? + +#### 3.2.2. Użyj [operatora view()](https://www.nextflow.io/docs/latest/reference/operator.html#view), aby sprawdzić zawartość kanału + +Dodaj te dwie linie w ciele workflow przed wywołaniem procesu `GATK_HAPLOTYPER`: + +```groovy title="genomics-1.nf" linenums="84" + // tymczasowa diagnostyka + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Następnie uruchom ponownie polecenie workflow. + +```bash +nextflow run genomics-1.nf +``` + +Ponownie, to może zakończyć się sukcesem lub porażką. Oto udane uruchomienie: + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +A oto nieudane: + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Może być konieczne uruchomienie go kilka razy, aby ponownie wystąpił błąd. +Ten błąd nie będzie się reprodukował konsekwentnie, ponieważ jest zależny od pewnej zmienności w czasach wykonywania poszczególnych wywołań procesów. + +Oto jak wygląda wyjście dwóch wywołań `.view()`, które dodaliśmy, dla nieudanego uruchomienia: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +Pierwsze trzy linie odpowiadają kanałowi wejściowemu, a drugie - kanałowi wyjściowemu. +Widać, że pliki BAM i pliki indeksów dla trzech próbek nie są wymienione w tej samej kolejności! + +!!! note "Uwaga" + + Gdy wywołujesz proces Nextflow na kanale zawierającym wiele elementów, Nextflow będzie próbował zrównoleglić wykonywanie tak bardzo, jak to możliwe, i będzie zbierał wyjścia w jakiejkolwiek kolejności, w jakiej staną się dostępne. + Konsekwencją jest to, że odpowiadające im wyjścia mogą być zebrane w innej kolejności niż oryginalne wejścia zostały podane. + +Zgodnie z obecnym zapisem, nasz skrypt workflow zakłada, że pliki indeksów wyjdą z kroku indeksowania wymienione w tej samej kolejności matka/ojciec/syn, jak podano wejścia. +Ale nie jest to gwarantowane, dlatego czasami (choć nie zawsze) złe pliki zostają sparowane w drugim kroku. + +Aby to naprawić, musimy upewnić się, że pliki BAM i ich pliki indeksów podróżują razem przez kanały. + +!!! tip "Wskazówka" + + Instrukcje `view()` w kodzie workflow nic nie robią, więc nie ma problemu, aby je zostawić. + Jednak będą zaśmiecać Twoje wyjście konsoli, więc zalecamy ich usunięcie, gdy zakończysz rozwiązywanie problemu. + +### 3.3. Zmień wyjście procesu SAMTOOLS_INDEX na krotkę, która trzyma plik wejściowy i jego indeks razem + +Najprostszym sposobem, aby upewnić się, że plik BAM i jego indeks pozostają ściśle powiązane, jest spakowanie ich razem w krotkę wychodzącą z zadania indeksowania. + +!!! note "Uwaga" + + **Krotka** to skończona, uporządkowana lista elementów, która jest powszechnie używana do zwracania wielu wartości z funkcji. Krotki są szczególnie przydatne do przekazywania wielu wejść lub wyjść między procesami przy zachowaniu ich powiązania i kolejności. + +Najpierw zmieńmy wyjście procesu `SAMTOOLS_INDEX`, aby uwzględnić plik BAM w swojej deklaracji wyjściowej. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +W ten sposób każdy plik indeksu będzie ściśle połączony z jego oryginalnym plikiem BAM, a ogólne wyjście kroku indeksowania będzie pojedynczym kanałem zawierającym pary plików. + +### 3.4. Zmień wejście do procesu GATK_HAPLOTYPECALLER na krotkę + +Ponieważ zmieniliśmy "kształt" wyjścia pierwszego procesu w workflow, musimy zaktualizować definicję wejścia drugiego procesu, aby pasowała. + +Konkretnie, tam gdzie wcześniej deklarowaliśmy dwie oddzielne ścieżki wejściowe w bloku wejść procesu `GATK_HAPLOTYPECALLER`, teraz deklarujemy pojedyncze wejście pasujące do struktury krotki emitowanej przez `SAMTOOLS_INDEX`. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Oczywiście, ponieważ zmieniliśmy teraz kształt wejść, których oczekuje `GATK_HAPLOTYPECALLER`, musimy odpowiednio zaktualizować wywołanie procesu w ciele workflow. + +### 3.5. Zaktualizuj wywołanie GATK_HAPLOTYPECALLER w bloku workflow + +Nie musimy już dostarczać oryginalnego `reads_ch` do procesu `GATK_HAPLOTYPECALLER`, ponieważ plik BAM jest teraz spakowany w kanał wyjściowy przez `SAMTOOLS_INDEX`. + +W rezultacie możemy po prostu usunąć tę linię. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +To wszystkie zmiany w połączeniach, które są konieczne do rozwiązania problemu niezgodności indeksów. + +### 3.6. Zaktualizuj sekcję publish i blok output dla krotki + +Ponieważ `SAMTOOLS_INDEX.out` jest teraz krotką zawierającą zarówno BAM, jak i jego indeks, oba pliki będą publikowane razem. +Zmieniamy nazwę celu z `bam_index` na `indexed_bam`, aby odzwierciedlić, że teraz zawiera oba pliki. + +=== "Po" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Musimy również zaktualizować blok output, aby używał nowej nazwy celu: + +=== "Po" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Uruchom workflow, aby zweryfikować, że działa poprawnie na wszystkich trzech próbkach za każdym razem + +Oczywiście, dowód jest w rezultacie, więc uruchommy workflow ponownie kilka razy, aby upewnić się, że będzie to działać niezawodnie w przyszłości. + +```bash +nextflow run genomics-1.nf +``` + +Tym razem (i za każdym razem) wszystko powinno działać poprawnie: + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Katalog wyników zawiera teraz zarówno pliki BAM, jak i BAI dla każdej próbki (z krotki), wraz z wyjściami VCF: + +??? abstract "Zawartość katalogu wyników" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Jeśli chcesz, możesz użyć `.view()` ponownie, aby zajrzeć do zawartości kanału wyjściowego `SAMTOOLS_INDEX`: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Zobaczysz, że kanał zawiera trzy oczekiwane krotki (ścieżki plików skrócone dla czytelności). + +```console title="Wyjście" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +To będzie znacznie bezpieczniejsze w przyszłości. + +### Podsumowanie + +Wiesz, jak sprawić, aby Twój workflow działał na wielu próbkach (niezależnie). + +### Co dalej? + +Ułatw obsługę próbek zbiorczo. + +--- + +## 4. Spraw, aby workflow akceptował plik tekstowy zawierający zestaw plików wejściowych + +Bardzo powszechnym sposobem dostarczania wielu plików danych wejściowych do workflow jest zrobienie tego za pomocą pliku tekstowego zawierającego ścieżki plików. +Może to być tak proste, jak plik tekstowy wymieniający jedną ścieżkę pliku na linię i nic więcej, lub plik może zawierać dodatkowe metadane, w którym to przypadku jest często nazywany arkuszem próbek. + +Tutaj pokażemy Ci, jak zrobić prosty przypadek. + +### 4.1. Sprawdź dostarczony plik tekstowy wymieniający ścieżki plików wejściowych + +Już utworzyliśmy plik tekstowy wymieniający ścieżki plików wejściowych, nazwany `sample_bams.txt`, który możesz znaleźć w katalogu `data/`. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Jak widać, wymieniliśmy jedną ścieżkę pliku na linię, i są to ścieżki bezwzględne. + +!!! note "Uwaga" + + Pliki, których tutaj używamy, znajdują się po prostu w lokalnym systemie plików Twojego GitHub Codespaces, ale moglibyśmy również wskazywać na pliki w chmurze. + +### 4.2. Zaktualizuj wartość domyślną parametru + +Zmieńmy wartość domyślną dla naszego parametru wejściowego `reads_bam`, aby wskazywał na plik `sample_bams.txt`. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="7" + // Główne wejście (plik plików wejściowych, jeden na linię) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="7" + // Główne wejście (tablica trzech próbek) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +W ten sposób możemy nadal być leniwi, ale lista plików nie znajduje się już w samym kodzie workflow, co jest dużym krokiem we właściwym kierunku. + +### 4.3. Zaktualizuj fabrykę kanałów, aby czytała linie z pliku + +Obecnie nasza fabryka kanałów wejściowych traktuje wszystkie pliki, które jej dajemy, jako dane wejściowe, które chcemy przekazać do procesu indeksowania. +Ponieważ teraz podajemy jej plik, który wymienia ścieżki plików wejściowych, musimy zmienić jej zachowanie, aby parsował plik i traktował ścieżki plików, które zawiera, jako dane wejściowe. + +Na szczęście możemy to zrobić bardzo prosto, po prostu dodając [operator `.splitText()`](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) do kroku konstrukcji kanału. + +=== "Po" + + ```groovy title="genomics-1.nf" linenums="68" + // Utwórz kanał wejściowy z pliku tekstowego wymieniającego ścieżki plików wejściowych + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Przed" + + ```groovy title="genomics-1.nf" linenums="68" + // Utwórz kanał wejściowy (pojedynczy plik przez parametr CLI) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip "Wskazówka" + + To kolejna świetna okazja do użycia operatora `.view()`, aby zobaczyć, jak wygląda zawartość kanału przed i po zastosowaniu operatora. + +### 4.4. Uruchom workflow, aby zweryfikować, że działa poprawnie + +Uruchommy workflow jeszcze raz. To powinno dać ten sam rezultat co wcześniej, prawda? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + ``` + +Tak! W rzeczywistości Nextflow poprawnie wykrywa, że wywołania procesów są dokładnie takie same, i nawet nie zadaje sobie trudu ponownego uruchomienia wszystkiego, ponieważ uruchamialiśmy z `-resume`. + +I to wszystko! Nasz prosty workflow do wykrywania wariantów ma wszystkie podstawowe funkcje, których chcieliśmy. + +### Podsumowanie + +Wiesz, jak stworzyć wieloetapowy liniowy workflow do indeksowania pliku BAM i aplikowania wykrywania wariantów dla pojedynczych próbek używając GATK. + +Ogólnie rzecz biorąc, nauczyłeś się używać podstawowych komponentów i logiki Nextflow do budowy prostego pipeline genomicznego, który wykonuje prawdziwą pracę, biorąc pod uwagę osobliwości formatów plików genomicznych i wymagania narzędzi. + +### Co dalej? + +Świętuj swój sukces i weź ekstra długą przerwę! + +W następnej części tego kursu nauczysz się używać kilku dodatkowych funkcji Nextflow (w tym więcej operatorów kanałów), aby zastosować wspólne wykrywanie wariantów do danych. diff --git a/docs/pl/docs/nf4_science/genomics/02_joint_calling.md b/docs/pl/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..ca8f83c227 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1026 @@ +# Część 2: Wspólne wywołanie wariantów dla kohorty + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W pierwszej części tego kursu zbudowałeś pipeline do wywoływania wariantów, który był całkowicie liniowy i przetwarzał dane każdej próbki niezależnie od innych. +Jednak w rzeczywistym przypadku użycia genomiki zazwyczaj będziesz musiał spojrzeć na wywołania wariantów wielu próbek razem. + +W tej drugiej części pokażemy Ci, jak używać kanałów i operatorów kanałów do implementacji wspólnego wywoływania wariantów za pomocą GATK, budując na pipeline z Części 1. + +### Przegląd metody + +Metoda wywoływania wariantów GATK, której użyliśmy w pierwszej części tego kursu, po prostu generowała wywołania wariantów dla każdej próbki. +To jest w porządku, jeśli chcesz tylko spojrzeć na warianty z każdej próbki osobno, ale to daje ograniczone informacje. +Często bardziej interesujące jest spojrzenie na to, jak wywołania wariantów różnią się między wieloma próbkami, a aby to zrobić, GATK oferuje alternatywną metodę zwaną wspólnym wywoływaniem wariantów, którą tutaj demonstrujemy. + +Wspólne wywoływanie wariantów polega na wygenerowaniu specjalnego rodzaju wyjścia wariantów zwanego GVCF (Genomic VCF) dla każdej próbki, następnie połączeniu danych GVCF ze wszystkich próbek i wreszcie uruchomieniu statystycznej analizy 'wspólnego genotypowania'. + +![Wspólna analiza](img/joint-calling.png) + +To, co jest specjalnego w GVCF próbki, to to, że zawiera rekordy podsumowujące statystyki danych sekwencyjnych o wszystkich pozycjach w docelowym obszarze genomu, nie tylko pozycjach, gdzie program znalazł dowody zmienności. +Jest to kluczowe dla obliczenia wspólnego genotypowania ([dalsza lektura](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +GVCF jest produkowany przez GATK HaplotypeCaller, to samo narzędzie, którego użyliśmy w Części 1, z dodatkowym parametrem (`-ERC GVCF`). +Łączenie GVCF odbywa się za pomocą GATK GenomicsDBImport, który łączy wywołania dla poszczególnych próbek w magazyn danych (analogiczny do bazy danych), a następnie właściwa analiza 'wspólnego genotypowania' jest wykonywana za pomocą GATK GenotypeGVCFs. + +### Workflow + +Podsumowując, w tej części kursu zamierzamy rozwinąć workflow, który wykonuje następujące czynności: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Wygenerować plik indeksu dla każdego pliku BAM wejściowego za pomocą Samtools +2. Uruchomić GATK HaplotypeCaller na każdym pliku BAM wejściowym, aby wygenerować GVCF wywołań wariantów genomowych dla każdej próbki +3. Zebrać wszystkie GVCF i połączyć je w magazyn danych GenomicsDB +4. Uruchomić wspólne genotypowanie na połączonym magazynie danych GVCF, aby wygenerować plik VCF na poziomie kohorty + +Zastosujemy to do tego samego zestawu danych, co w Części 1. + +--- + +## 0. Rozgrzewka: Uruchom Samtools i GATK bezpośrednio + +Tak jak wcześniej, chcemy wypróbować polecenia ręcznie, zanim spróbujemy opakować je w workflow. + +!!! note + + Upewnij się, że jesteś we właściwym katalogu roboczym: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Indeksuj plik BAM wejściowy za pomocą Samtools + +Ten pierwszy krok jest taki sam jak w Części 1, więc powinien być bardzo znajomy, ale tym razem musimy to zrobić dla wszystkich trzech próbek. + +!!! note + + Technicznie już wygenerowaliśmy pliki indeksu dla trzech próbek przez nasz pipeline, więc moglibyśmy pójść je wydobyć z katalogu wyników. Jednak czystsze jest po prostu powtórzenie tego ręcznie, a zajmie to tylko minutę. + +#### 0.1.1. Uruchom kontener Samtools interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.1.2. Uruchom polecenie indeksowania dla trzech próbek + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Tak jak wcześniej, to powinno wytworzyć pliki indeksu w tym samym katalogu co odpowiadające pliki BAM. + +??? abstract "Zawartość katalogu" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Teraz, gdy mamy pliki indeksu dla wszystkich trzech próbek, możemy przejść do generowania GVCF dla każdej z nich. + +#### 0.1.3. Wyjdź z kontenera Samtools + +```bash +exit +``` + +### 0.2. Wywołaj warianty za pomocą GATK HaplotypeCaller w trybie GVCF + +Ten drugi krok jest bardzo podobny do tego, co zrobiliśmy w Części 1: Hello Genomics, ale teraz zamierzamy uruchomić GATK w 'trybie GVCF'. + +#### 0.2.1. Uruchom kontener GATK interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +#### 0.2.2. Uruchom polecenie wywoływania wariantów z opcją GVCF + +Aby wytworzyć genomiczny VCF (GVCF), dodajemy opcję `-ERC GVCF` do podstawowego polecenia, co włącza tryb GVCF HaplotypeCaller. + +Zmieniamy również rozszerzenie pliku wyjściowego z `.vcf` na `.g.vcf`. +Technicznie nie jest to wymagane, ale jest to zdecydowanie zalecana konwencja. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +To tworzy plik wyjściowy GVCF `reads_mother.g.vcf` w bieżącym katalogu roboczym w kontenerze. + +Jeśli użyjesz `cat`, aby wyświetlić zawartość, zobaczysz, że jest on znacznie dłuższy niż odpowiadający VCF, który wygenerowaliśmy w Części 1. Nie możesz nawet przewinąć do początku pliku, a większość linii wygląda zupełnie inaczej niż to, co widzieliśmy w VCF w Części 1. + +```console title="Wyjście" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Reprezentują one regiony nie-wariantowe, gdzie wywołujący warianty nie znalazł dowodów zmienności, więc uchwycił pewne statystyki opisujące jego poziom pewności w braku zmienności. Umożliwia to rozróżnienie między dwoma bardzo różnymi przypadkami: (1) są dobre jakościowo dane pokazujące, że próbka jest homozygotyczna-referencyjna, i (2) nie ma wystarczająco dobrych danych dostępnych, aby dokonać określenia w każdy sposób. + +W GVCF zazwyczaj jest wiele takich linii nie-wariantowych, z mniejszą liczbą rekordów wariantów rozproszonymi wśród nich. Spróbuj uruchomić `head -176` na GVCF, aby załadować tylko pierwsze 176 linii pliku i znaleźć rzeczywiste wywołanie wariantu. + +```console title="Wyjście" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +Druga linia pokazuje pierwszy rekord wariantu w pliku, który odpowiada pierwszemu wariantowi w pliku VCF, na który patrzyliśmy w Części 1. + +Tak jak oryginalny VCF, plik wyjściowy GVCF jest również dołączony do pliku indeksu, zwanego `reads_mother.g.vcf.idx`. + +#### 0.2.3. Powtórz proces na dwóch pozostałych próbkach + +Aby przetestować krok wspólnego genotypowania, potrzebujemy GVCF dla wszystkich trzech próbek, więc wygenerujmy je teraz ręcznie. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +Po zakończeniu powinieneś mieć trzy pliki kończące się na `.g.vcf` w swoim bieżącym katalogu (jeden na próbkę) i ich odpowiednie pliki indeksu kończące się na `.g.vcf.idx`. + +### 0.3. Uruchom wspólne genotypowanie + +Teraz, gdy mamy wszystkie GVCF, możemy wreszcie wypróbować podejście wspólnego genotypowania do generowania wywołań wariantów dla kohorty próbek. +Jako przypomnienie, jest to dwuetapowa metoda, która polega na połączeniu danych ze wszystkich GVCF w magazyn danych, a następnie uruchomieniu właściwej analizy wspólnego genotypowania, aby wygenerować końcowy VCF wspólnie wywołanych wariantów. + +#### 0.3.1. Połącz wszystkie GVCF dla poszczególnych próbek + +Ten pierwszy krok używa innego narzędzia GATK, zwanego GenomicsDBImport, aby połączyć dane ze wszystkich GVCF w magazyn danych GenomicsDB. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +Wyjściem tego kroku jest faktycznie katalog zawierający zestaw dalej zagnieżdżonych katalogów przechowujących połączone dane wariantów w postaci wielu różnych plików. +Możesz w nim podziurać, ale szybko zobaczysz, że ten format magazynu danych nie jest przeznaczony do bezpośredniego czytania przez ludzi. + +!!! note + + GATK zawiera narzędzia, które umożliwiają inspekcję i wydobycie danych wywołań wariantów z magazynu danych w razie potrzeby. + +#### 0.3.2. Uruchom właściwą analizę wspólnego genotypowania + +Ten drugi krok używa jeszcze innego narzędzia GATK, zwanego GenotypeGVCFs, aby przeliczyć statystyki wariantów i indywidualne genotypy w świetle danych dostępnych we wszystkich próbkach w kohorcie. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Command output" + + ```console + + ``` +--> + +To tworzy plik wyjściowy VCF `family_trio.vcf` w bieżącym katalogu roboczym w kontenerze. +To kolejny dość mały plik, więc możesz użyć `cat` na tym pliku, aby wyświetlić jego zawartość i przewinąć w górę, aby znaleźć kilka pierwszych linii wariantów. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +To wygląda bardziej jak oryginalny VCF, który wygenerowaliśmy w Części 1, z tym że tym razem mamy informacje na poziomie genotypu dla wszystkich trzech próbek. +Ostatnie trzy kolumny w pliku to bloki genotypu dla próbek, wymienione w porządku alfabetycznym. + +Jeśli spojrzymy na genotypy wywołane dla naszego testowego tria rodzinnego dla pierwszego wariantu, widzimy, że ojciec jest heterozygotyczny-wariantowy (`0/1`), a matka i syn są obaj homozygotyczni-wariantowi (`1/1`). + +To jest ostatecznie informacja, którą chcemy wydobyć z zestawu danych! Więc opakowujmy to wszystko w workflow Nextflow, abyśmy mogli robić to na dużą skalę. + +#### 0.3.3. Wyjdź z kontenera GATK + +```bash +exit +``` + +### Wnioski + +Wiesz, jak uruchamiać poszczególne polecenia zaangażowane we wspólne wywoływanie wariantów w terminalu, aby sprawdzić, czy wyprodukują informacje, których chcesz. + +### Co dalej? + +Opakuj te polecenia w rzeczywisty pipeline. + +--- + +## 1. Zmodyfikuj krok wywoływania wariantów dla poszczególnych próbek, aby wytwarzał GVCF + +Dobra wiadomość jest taka, że nie musimy zaczynać od początku, ponieważ już napisaliśmy workflow, który wykonuje część tej pracy w Części 1. +Jednak ten pipeline produkuje pliki VCF, podczas gdy teraz chcemy plików GVCF, aby wykonać wspólne genotypowanie. +Więc musimy zacząć od włączenia trybu wywoływania wariantów GVCF i zaktualizowania rozszerzenia pliku wyjściowego. + +!!! note + + Dla wygody będziemy pracować z nową kopią workflow GATK, jak stoi na końcu Części 1, ale pod inną nazwą: `genomics-2.nf`. + +### 1.1. Powiedz HaplotypeCaller, aby emitował GVCF i zaktualizuj rozszerzenie wyjściowe + +Otwórzmy plik `genomics-2.nf` w edytorze kodu. +Powinien wyglądać bardzo znajomo, ale możesz go uruchomić, jeśli chcesz upewnić się, że działa zgodnie z oczekiwaniami. + +Zamierzamy zacząć od wprowadzenia dwóch zmian: + +- Dodać parametr `-ERC GVCF` do polecenia GATK HaplotypeCaller; +- Zaktualizować ścieżkę pliku wyjściowego, aby używała odpowiadającego rozszerzenia `.g.vcf`, zgodnie z konwencją GATK. + +Upewnij się, że dodajesz ukośnik wsteczny (`\`) na końcu poprzedniej linii, gdy dodajesz `-ERC GVCF`. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +I to wszystko, czego potrzeba, aby przełączyć HaplotypeCaller na generowanie GVCF zamiast VCF, prawda? + +### 1.2. Uruchom pipeline, aby sprawdzić, czy możesz generować GVCF + +Polecenie wykonania Nextflow jest takie samo jak wcześniej, z wyjątkiem samej nazwy pliku workflow. +Upewnij się, że odpowiednio to zaktualizowałeś. + +```bash +nextflow run genomics-2.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +A wyjście jest... całe czerwone! O nie. + +Polecenie, które zostało wykonane, jest poprawne, więc mieliśmy rację, że to wystarczyło do zmiany zachowania narzędzia GATK. +Ale spójrz na tę linię o brakującym pliku wyjściowym. Zauważyłeś coś? + +Tak jest, zapomnieliśmy powiedzieć Nextflow, aby oczekiwał nowej nazwy pliku. Ups. + +### 1.3. Zaktualizuj również rozszerzenie pliku wyjściowego w bloku wyjść procesu + +Ponieważ nie wystarczy po prostu zmienić rozszerzenie pliku w samym poleceniu narzędzia, musisz również powiedzieć Nextflow, że oczekiwana nazwa pliku wyjściowego się zmieniła. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Zaktualizuj cele publikacji dla nowych wyjść GVCF + +Ponieważ teraz produkujemy GVCF zamiast VCF, powinniśmy zaktualizować sekcję `publish:` workflow, aby używać bardziej opisowych nazw. +Zorganizujemy również pliki GVCF w ich własnym podkatalogu dla jasności. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Zaktualizuj blok wyjściowy dla nowej struktury katalogów + +Musimy również zaktualizować blok `output`, aby umieścić pliki GVCF w podkatalogu `gvcf`. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Uruchom pipeline ponownie + +Uruchommy go tym razem z `-resume`. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Tym razem działa. + +Same wyjście Nextflow nie wygląda inaczej (w porównaniu do pomyślnego uruchomienia w normalnym trybie VCF), ale teraz możemy znaleźć pliki `.g.vcf` i ich odpowiednie pliki indeksu, dla wszystkich trzech próbek, zorganizowane w podkatalogach. + +??? abstract "Zawartość katalogu (dowiązania symboliczne skrócone)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Jeśli otworzysz jeden z plików GVCF i przewiniesz go, możesz sprawdzić, że GATK HaplotypeCaller wytworzyło pliki GVCF zgodnie z życzeniem. + +### Wnioski + +Okej, ten był minimalny pod względem nauki Nextflow... +Ale to była miła okazja, aby powtórzyć znaczenie bloku wyjściowego procesu! + +### Co dalej? + +Naucz się zbierać zawartość kanału i przekazywać je do następnego procesu jako pojedyncze wejście. + +--- + +## 2. Zbierz i połącz dane GVCF ze wszystkich próbek + +Teraz musimy połączyć dane ze wszystkich GVCF dla poszczególnych próbek w formę, która wspiera analizę wspólnego genotypowania, którą chcemy wykonać. + +### 2.1. Zdefiniuj proces, który połączy GVCF + +Jako przypomnienie tego, co zrobiliśmy wcześniej w sekcji rozgrzewkowej, łączenie GVCF jest zadaniem dla narzędzia GATK GenomicsDBImport, które wytworzy magazyn danych w tak zwanym formacie GenomicsDB. + +Napiszmy nowy proces, aby zdefiniować, jak to będzie działać, na podstawie polecenia, którego użyliśmy wcześniej w sekcji rozgrzewkowej. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Połącz GVCF w magazyn danych GenomicsDB + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +Co myślisz, wygląda rozsądnie? + +Podłączmy to i zobaczmy, co się stanie. + +### 2.2. Dodaj parametr `cohort_name` z wartością domyślną + +Musimy podać arbitralną nazwę dla kohorty. +Później w serii szkoleń nauczysz się używać metadanych próbek do tego rodzaju rzeczy, ale na razie po prostu deklarujemy parametr CLI używając `params` i dajemy mu wartość domyślną dla wygody. + +```groovy title="genomics-2.nf" linenums="16" + // Nazwa bazowa dla końcowego pliku wyjściowego + cohort_name: String = "family_trio" +``` + +### 2.3. Zbierz wyjścia GATK_HAPLOTYPECALLER ze wszystkich próbek + +Gdybyśmy mieli po prostu podłączyć kanał wyjściowy z procesu `GATK_HAPLOTYPECALLER` tak jak jest, Nextflow wywołałby proces na każdym GVCF próbki osobno. +Jednak chcemy zgrupować wszystkie trzy GVCF (i ich pliki indeksu) w taki sposób, aby Nextflow przekazał wszystkie razem do pojedynczego wywołania procesu. + +Dobra wiadomość: możemy to zrobić za pomocą operatora kanału `collect()`. Dodajmy następujące linie do ciała `workflow`, zaraz po wywołaniu GATK_HAPLOTYPECALLER: + +```groovy title="genomics-2.nf" linenums="118" +// Zbierz wyjścia wywoływania wariantów ze wszystkich próbek +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Czy to wydaje się trochę skomplikowane? Rozbijmy to i przetłumaczmy na prosty język. + +1. Bierzemy kanał wyjściowy z procesu `GATK_HAPLOTYPECALLER`, odnoszony za pomocą właściwości `.out`. +2. Każdy 'element' wychodzący z kanału to para plików: GVCF i jego plik indeksu, w tej kolejności, ponieważ to jest kolejność, w jakiej są wymienione w bloku wyjściowym procesu. Wygodnie, ponieważ w ostatniej sesji nazwaliśmy wyjścia tego procesu (używając `emit:`), możemy wybrać GVCF z jednej strony, dodając `.vcf`, a pliki indeksu z drugiej strony, dodając `.idx` po właściwości `.out`. Gdybyśmy nie nazwali tych wyjść, musielibyśmy odnieść się do nich odpowiednio jako `.out[0]` i `.out[1]`. +3. Dołączamy operator kanału `collect()`, aby zgrupować wszystkie pliki GVCF razem w pojedynczy element w nowym kanale zwanym `all_gvcfs_ch`, i robimy to samo z plikami indeksu, aby utworzyć nowy kanał zwany `all_idxs_ch`. + +!!! tip + + Jeśli masz trudności z wyobrażeniem sobie dokładnie, co się tutaj dzieje, pamiętaj, że możesz użyć operatora `view()`, aby sprawdzić zawartość kanałów przed i po zastosowaniu operatorów kanału. + +Powstałe kanały `all_gvcfs_ch` i `all_idxs_ch` to te, które zamierzamy podłączyć do procesu `GATK_GENOMICSDB`, który właśnie napisaliśmy. + +!!! note + + W przypadku, gdybyś się zastanawiał, zbieramy GVCF i ich pliki indeksu osobno, ponieważ polecenie GATK GenomicsDBImport chce widzieć tylko ścieżki plików GVCF. Na szczęście, ponieważ Nextflow będzie przygotowywał wszystkie pliki razem do wykonania, nie musimy martwić się o kolejność plików, jak to zrobiliśmy w przypadku BAM i ich indeksów w Części 1. + +### 2.4. Dodaj wywołanie do bloku workflow, aby uruchomić GATK_GENOMICSDB + +Mamy proces i mamy kanały wejściowe. Musimy tylko dodać wywołanie procesu. + +```groovy title="genomics-2.nf" linenums="122" + // Połącz GVCF w magazyn danych GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, wszystko jest podłączone. + +### 2.5. Uruchom workflow + +Zobaczmy, czy to działa. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Uruchamia się dość szybko, ponieważ uruchamiamy z `-resume`, ale zawodzi! + +Ach. Z jasnej strony, widzimy, że Nextflow pobrał proces `GATK_GENOMICSDB` i konkretnie wywołał go tylko raz. +To sugeruje, że podejście `collect()` zadziałało, do pewnego stopnia. +Ale, i to duże, wywołanie procesu nie powiodło się. + +Kiedy wchodzimy w głąb wyjścia konsoli powyżej, możemy zobaczyć, że wykonane polecenie nie jest poprawne. + +Czy możesz zauważyć błąd? +Spójrz na ten fragment: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Daliśmy `gatk GenomicsDBImport` wiele plików GVCF dla pojedynczego argumentu `-V`, ale narzędzie oczekuje oddzielnego argumentu `-V` dla każdego pliku GVCF. + +Jako przypomnienie, to było polecenie, które uruchomiliśmy w kontenerze: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Więc to oznacza, że musimy jakoś przekształcić nasz pakiet plików GVCF w poprawnie sformatowany ciąg poleceń. + +### 2.6. Skonstruuj linię poleceń z osobnym argumentem `-V` dla każdego wejściowego GVCF + +To jest miejsce, gdzie Nextflow bazujący na Groovy okazuje się przydatny, ponieważ pozwoli nam użyć dość prostych manipulacji ciągami, aby skonstruować niezbędny ciąg poleceń. + +Konkretnie, używając tej składni: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Jeszcze raz rozbijmy to na składniki. + +1. Najpierw bierzemy zawartość kanału wejściowego `all_gvcfs` i stosujemy na nim `.collect()` (tak jak wcześniej). +2. Pozwala nam to przekazać każdą indywidualną ścieżkę pliku GVCF w pakiecie do **domknięcia**, `{ gvcf -> "-V ${gvcf}" }`, gdzie `gvcf` odnosi się do tej ścieżki pliku GVCF. + Domknięcie to mini-funkcja, której używamy, aby poprzedzić `-V ` do ścieżki pliku, w postaci `"-V ${gvcf}"`. +3. Następnie używamy `.join(' ')`, aby połączyć wszystkie trzy ciągi z pojedynczą spacją jako separatorem. + +Z konkretnym przykładem wygląda to tak: + +1. Mamy trzy pliki: + + `[A.ext, B.ext, C.ext]` + +2. Domknięcie modyfikuje każdy, aby utworzyć ciągi: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. Operacja `.join(' ')` generuje końcowy ciąg: + + `"-V A.ext -V B.ext -V C.ext"` + +Kiedy mamy ten ciąg, możemy przypisać go do zmiennej lokalnej, `gvcfs_line`, zdefiniowanej słowem kluczowym `def`: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, mamy więc naszą rzecz do manipulacji ciągami. Gdzie ją umieścić? + +Chcemy, aby to trafiło gdzieś do definicji procesu, ponieważ chcemy to zrobić _po_ tym, jak przekierowaliśmy ścieżki plików GVCF do procesu. +To dlatego, że Nextflow musi je zobaczyć jako ścieżki plików, aby poprawnie przygotować same pliki do wykonania. + +Ale _gdzie_ w procesie możemy to dodać? + +Ciekawy fakt: możesz dodać dowolny kod po `script:` i przed `"""` ! + +Świetnie, dodajmy więc tam naszą linię manipulacji ciągami, i zaktualizujmy polecenie `gatk GenomicsDBImport`, aby używało łączonego ciągu, który produkuje. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +To powinno być wszystko, czego potrzeba, aby prawidłowo dostarczyć wejścia do `gatk GenomicsDBImport`. + +!!! tip + + Kiedy aktualizujesz polecenie `gatk GenomicsDBImport`, upewnij się, że usunąłeś prefiks `-V `, gdy zamieniasz na zmienną `${gvcfs_line}`. + +### 2.7. Uruchom workflow, aby sprawdzić, czy generuje wyjście GenomicsDB zgodnie z oczekiwaniami + +W porządku, zobaczmy, czy to rozwiązało problem. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha! Wygląda na to, że tym razem działa. + +Pierwsze dwa kroki zostały pomyślnie pominięte, a trzeci krok zadziałał tym razem jak za dotknięciem różdżki. +Magazyn danych GenomicsDB jest tworzony w katalogu roboczym, ale nie jest publikowany do wyników, ponieważ to tylko format pośredni, którego użyjemy do wspólnego genotypowania. + +Nawiasem mówiąc, nie musieliśmy robić nic specjalnego, aby obsłużyć wyjście będące katalogiem zamiast pojedynczym plikiem. + +### Wnioski + +Teraz wiesz, jak zbierać wyjścia z kanału i grupować je jako pojedyncze wejście do innego procesu. +Wiesz również, jak skonstruować linię poleceń, aby dostarczyć wejścia do danego narzędzia z odpowiednią składnią. + +### Co dalej? + +Naucz się, jak dodać drugie polecenie do tego samego procesu. + +--- + +## 3. Uruchom krok wspólnego genotypowania jako część tego samego procesu + +Teraz, gdy mamy połączone genomowe wywołania wariantów, możemy uruchomić narzędzie do wspólnego genotypowania, które wytworzy końcowe wyjście, na którym nam naprawdę zależy: VCF wywołań wariantów na poziomie kohorty. + +Ze względów logistycznych decydujemy się włączyć wspólne genotypowanie do tego samego procesu. + +### 3.1. Zmień nazwę procesu z GATK_GENOMICSDB na GATK_JOINTGENOTYPING + +Ponieważ proces będzie uruchamiał więcej niż jedno narzędzie, zmieniamy jego nazwę, aby odnosiła się do całej operacji, a nie nazwy pojedynczego narzędzia. + +=== "Po" + + ```groovy title="genomics-2.nf" + /* + * Połącz GVCF w magazyn danych GenomicsDB i uruchom wspólne genotypowanie, aby wytworzyć wywołania na poziomie kohorty + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" + /* + * Połącz GVCF w magazyn danych GenomicsDB + */ + process GATK_GENOMICSDB { + ``` + +Pamiętaj, aby nazwy procesów były jak najbardziej opisowe, aby zmaksymalizować czytelność dla kolegów — i siebie w przyszłości! + +### 3.2. Dodaj polecenie wspólnego genotypowania do procesu GATK_JOINTGENOTYPING + +Po prostu dodaj drugie polecenie po pierwszym wewnątrz sekcji script. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Dwa polecenia będą uruchamiane sekwencyjnie, w taki sam sposób, jak gdybyśmy mieli uruchomić je ręcznie w terminalu. + +### 3.3. Dodaj pliki genomu referencyjnego do definicji wejść procesu GATK_JOINTGENOTYPING + +Drugie polecenie wymaga plików genomu referencyjnego, więc musimy dodać je do wejść procesu. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Może wydawać się irytujące pisanie tego, ale pamiętaj, że piszesz to tylko raz, a następnie możesz uruchomić workflow milion razy. Warte tego? + +### 3.4. Zaktualizuj definicję wyjścia procesu, aby emitowała VCF wywołań wariantów na poziomie kohorty + +Naprawdę nie zależy nam na zapisaniu magazynu danych GenomicsDB, który jest tylko formatem pośrednim istniejącym z przyczyn logistycznych, więc możemy po prostu usunąć go z bloku wyjściowego, jeśli chcemy. + +Wyjściem, na którym nam naprawdę zależy, jest VCF wytworzony przez polecenie wspólnego genotypowania. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Prawie skończyliśmy! + +### 3.5. Zaktualizuj wywołanie procesu z GATK_GENOMICSDB na GATK_JOINTGENOTYPING + +Nie zapomnijmy zmienić nazwy wywołania procesu w ciele workflow z GATK_GENOMICSDB na GATK_JOINTGENOTYPING. A skoro już przy tym jesteśmy, powinniśmy również dodać pliki genomu referencyjnego jako wejścia, ponieważ musimy je dostarczyć do narzędzia wspólnego genotypowania. + +=== "Po" + + ```groovy title="genomics-2.nf" linenums="126" + // Połącz GVCF w magazyn danych GenomicsDB i zastosuj wspólne genotypowanie + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Przed" + + ```groovy title="genomics-2.nf" linenums="126" + // Połącz GVCF w magazyn danych GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Teraz proces jest całkowicie podłączony. + +### 3.6. Dodaj wspólny VCF do sekcji publikacji + +Musimy opublikować wspólne wyjścia VCF z nowego procesu. +Dodaj te linie do sekcji `publish:` workflow: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Dodaj cele wspólnego VCF do bloku wyjściowego + +Na koniec dodaj cele wyjściowe dla wspólnych plików VCF. +Umieścimy je w głównym katalogu wyników, ponieważ to jest końcowe wyjście. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Teraz wszystko powinno być całkowicie podłączone. + +### 3.8. Uruchom workflow + +Wreszcie możemy uruchomić zmodyfikowany workflow... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +I to działa! + +Znajdziesz końcowy plik wyjściowy, `family_trio.joint.vcf` (i jego indeks pliku), w katalogu wyników. + +??? abstract "Zawartość katalogu (dowiązania symboliczne skrócone)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Jeśli jesteś typem sceptycznym, możesz kliknąć na wspólny plik VCF, aby go otworzyć i sprawdzić, że workflow wygenerował te same wywołania wariantów, które otrzymałeś, uruchamiając narzędzia ręcznie na początku tej sekcji. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Masz teraz zautomatyzowany, w pełni odtwarzalny workflow wspólnego wywoływania wariantów! + +!!! note + + Pamiętaj, że pliki danych, które Ci daliśmy, obejmują tylko maleńką część chromosomu 20. + Rzeczywisty rozmiar zestawu wywołań wariantów byłby liczony w milionach wariantów. + Dlatego używamy tylko małych podzbiorów danych do celów szkoleniowych! + +### Wnioski + +Wiesz, jak używać niektórych typowych operatorów, a także domknięć Groovy do kontrolowania przepływu danych w Twoim workflow. + +### Co dalej? + +Świętuj swój sukces i weź zasłużoną przerwę. + +W następnej części tego kursu nauczysz się, jak modularyzować swój workflow, wyodrębniając definicje procesów do modułów wielokrotnego użytku. diff --git a/docs/pl/docs/nf4_science/genomics/03_modules.md b/docs/pl/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..6cd8716aed --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Część 3: Przenoszenie kodu do modułów + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W pierwszej części tego kursu zbudowałeś pipeline do wywoływania wariantów, który był całkowicie liniowy i przetwarzał dane każdej próbki niezależnie od innych. + +W drugiej części pokazaliśmy, jak używać kanałów i operatorów kanałów do implementacji wspólnego wywoływania wariantów za pomocą GATK, rozbudowując pipeline z Części 1. + +W tej części pokażemy, jak przekonwertować kod z tego workflow na moduły. Aby przejść tę część szkolenia, powinieneś ukończyć Część 1 i Część 2, a także [Hello Modules](../../../hello_nextflow/hello_modules.md), które omawia podstawy modułów. + +--- + +## 0. Rozgrzewka + +Kiedy zaczęliśmy rozwijać nasz workflow, umieściliśmy wszystko w jednym pliku kodu. +Teraz nadszedł czas, aby zająć się **modularyzacją** naszego kodu, _tzn._ wyodrębnieniem definicji procesów do modułów. + +Zaczniemy od tego samego workflow co w Części 2, który udostępniliśmy w pliku `genomics-3.nf`. + +!!! note "Uwaga" + + Upewnij się, że jesteś we właściwym katalogu roboczym: + `cd /workspaces/training/nf4-science/genomics` + +Uruchom workflow, aby zweryfikować punkt wyjścia: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Wyjście" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +W katalogu projektu pojawi się teraz katalog `work` oraz katalog `results_genomics`. + +### Podsumowanie + +Jesteś gotowy, aby rozpocząć modularyzację swojego workflow. + +### Co dalej? + +Przenieś procesy workflow Genomics do modułów. + +--- + +## 1. Przeniesienie procesów do modułów + +Jak nauczyłeś się w [Hello Modules](../../../hello_nextflow/hello_modules.md), możesz utworzyć moduł po prostu kopiując definicję procesu do własnego pliku, w dowolnym katalogu, i możesz nazwać ten plik dowolnie. + +Z powodów, które staną się jasne później (w szczególności gdy przejdziemy do testowania), w tym szkoleniu będziemy stosować konwencję nazewnictwa pliku `main.nf` i umieszczania go w strukturze katalogów nazwanej według zestawu narzędzi i polecenia. + +### 1.1. Utwórz moduł dla procesu `SAMTOOLS_INDEX` + +W przypadku procesu `SAMTOOLS_INDEX`, 'samtools' jest zestawem narzędzi, a 'index' jest poleceniem. Utworzymy więc strukturę katalogów `modules/samtools/index` i umieścimy definicję procesu `SAMTOOLS_INDEX` w pliku `main.nf` wewnątrz tego katalogu. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Otwórz plik `main.nf` i skopiuj do niego definicję procesu `SAMTOOLS_INDEX`. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * Generuje plik indeksu BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Następnie usuń definicję procesu `SAMTOOLS_INDEX` z `genomics-3.nf` i dodaj deklarację importu dla modułu przed definicją następnego procesu, w ten sposób: + +=== "Po" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Dołącz moduły + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Wywołaj warianty za pomocą GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Przed" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Wywołaj warianty za pomocą GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +Możesz teraz ponownie uruchomić workflow i powinien działać tak samo jak wcześniej. Jeśli podasz flagę `-resume`, żadne nowe zadania nie powinny być nawet uruchamiane: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Utwórz moduły dla procesów `GATK_HAPLOTYPECALLER` i `GATK_JOINTGENOTYPING` + +Powtórz te same kroki dla pozostałych procesów. +Dla każdego procesu: + +1. Utwórz strukturę katalogów (`modules/gatk/haplotypecaller/` i `modules/gatk/jointgenotyping/`) +2. Utwórz plik `main.nf` zawierający definicję procesu +3. Usuń definicję procesu z `genomics-3.nf` +4. Dodaj deklarację importu dla modułu + +Po zakończeniu sprawdź, czy struktura katalogów modułów jest poprawna, uruchamiając: + +```bash +tree modules/ +``` + +??? abstract "Zawartość katalogu" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Powinieneś również mieć coś takiego w głównym pliku workflow, po sekcji parametrów: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Podsumowanie + +Przećwiczyłeś modularyzację workflow na przykładzie workflow genomiki. + +### Co dalej? + +Przetestuj zmodularyzowany workflow. + +--- + +## 2. Testowanie zmodularyzowanego workflow + +Uruchom zmodularyzowany workflow, aby zweryfikować, że wszystko nadal działa. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Wyjście" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Wszystko nadal działa, w tym możliwość wznowienia pipeline. +Wyniki są nadal publikowane w katalogu `results_genomics`. + +```console title="Zawartość katalogu" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Podsumowanie + +Zmodularyzowałeś workflow i zweryfikowałeś, że nadal działa tak samo jak wcześniej. + +### Co dalej? + +Przejrzyj to, czego się nauczyłeś i spójrz na testowanie. + +--- + +## 3. Podsumowanie + +Zmodularyzowałeś workflow i nic nie zmieniło się w sposobie działania pipeline. +To jest zamierzone: zrestrukturyzowałeś kod bez wpływu na jego funkcjonalność. + +Moduły zawierają tylko logikę procesu, co czyni je czystymi i wielokrotnego użytku. +Główny skrypt kontroluje, co jest publikowane i gdzie, podczas gdy moduły pozostają skoncentrowane na swoim zadaniu obliczeniowym. + +Położyłeś fundamenty pod rzeczy, które ułatwią utrzymanie kodu. +Na przykład możesz teraz dodać testy do swojego pipeline używając frameworka nf-test. +To właśnie przyjrzymy się w następnej części tego kursu. diff --git a/docs/pl/docs/nf4_science/genomics/04_testing.md b/docs/pl/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..e866754497 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Część 4: Dodawanie testów + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W pierwszej części tego kursu zbudowałeś pipeline do wykrywania wariantów, który był całkowicie liniowy i przetwarzał dane każdej próbki niezależnie od innych. + +W drugiej części pokazaliśmy Ci, jak używać kanałów i operatorów kanałów do implementacji wspólnego wykrywania wariantów za pomocą GATK. + +W trzeciej części zmodularyzowaliśmy pipeline. + +W tej części szkolenia pokażemy Ci, jak używać [**nf-test**](https://www.nf-test.com/), frameworka testowego, który dobrze integruje się z Nextflow i ułatwia dodawanie testów zarówno na poziomie modułów, jak i workflow do Twojego pipeline. Aby podążać za tą częścią szkolenia, powinieneś ukończyć Część 1, Część 2 i Część 3, a także [zadanie dodatkowe nf-test](../../side_quests/nf-test.md), które omawia podstawy nf-test i wyjaśnia, dlaczego testowanie jest ważne. + +--- + +## 0. Rozgrzewka + +!!! note "Uwaga" + + Upewnij się, że jesteś w poprawnym katalogu roboczym: + `cd /workspaces/training/nf4-science/genomics` + +Jeśli przepracowałeś poprzednie części tego kursu szkoleniowego, powinieneś mieć działającą wersję pipeline genomiki z odpowiednią strukturą katalogów modułów. + +??? abstract "Zawartość katalogów" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Ten katalog modułów można znaleźć w katalogu `solutions`, jeśli jest potrzebny. + +Rozpoczniemy od tego samego workflow co w Części 3, który przygotowaliśmy dla Ciebie w pliku `genomics-4.nf`. Dokładnie tak jak w [zadaniu dodatkowym nf-test](../../side_quests/nf-test.md), dodamy kilka różnych typów testów do trzech procesów w tym pipeline, a także test na poziomie workflow. + +### 0.1. Sprawdź, czy workflow działa + +Zanim zaczniemy dodawać testy, upewnij się, że workflow działa zgodnie z oczekiwaniami. + +```bash +nextflow run genomics-4.nf -resume +``` + +Powinno to wyglądać bardzo znajomo, jeśli pracowałeś nad tym kursem szkoleniowym od początku. + +??? success "Wynik polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Jak poprzednio, w Twoim katalogu projektu znajdzie się teraz katalog `work` i katalog `results_genomics`. Faktycznie wykorzystamy te wyniki później w naszych testach. Ale od teraz będziemy używać pakietu `nf-test` do testowania pipeline. + +### 0.2. Zainicjuj `nf-test` + +Tak jak w [zadaniu dodatkowym nf-test](../../side_quests/nf-test.md), musimy zainicjować pakiet `nf-test`. + +```bash +nf-test init +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "Zawartość nf-test.config" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Tworzy to również katalog `tests` zawierający szkielet pliku konfiguracyjnego. + +### Podsumowanie + +Teraz jesteśmy gotowi, aby zacząć pisać testy dla naszego pipeline genomiki. + +### Co dalej? + +Napisz podstawowe testy, które oceniają, czy wywołania procesów zakończyły się sukcesem i wygenerowały poprawne wyjścia. + +--- + +## 1. Testowanie procesu pod kątem sukcesu i zgodności wyjść + +Zaczniemy od testowania procesu `SAMTOOLS_INDEX`, który tworzy pliki indeksów dla plików BAM, aby umożliwić efektywny losowy dostęp. Jest to dobry pierwszy przypadek testowy, ponieważ: + +1. Ma pojedyncze, dobrze zdefiniowane wejście (plik BAM) +2. Produkuje przewidywalne wyjście (plik indeksu BAI) +3. Wyjście powinno być identyczne dla identycznych wejść + +### 1.1. Wygeneruj szkielet pliku testowego + +Najpierw wygeneruj szkielet pliku testowego: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Wynik polecenia" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +To tworzy plik w tym samym katalogu co `main.nf`. +Możesz przejść do katalogu w eksploratorze plików i otworzyć plik, który powinien zawierać następujący kod: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Początkowe asercje powinny być znajome z [zadania dodatkowego nf-test](../../side_quests/nf-test.md): + +- `assert process.success` stwierdza, że oczekujemy, że proces uruchomi się pomyślnie i zakończy bez żadnych błędów. +- `snapshot(process.out).match()` stwierdza, że oczekujemy, że wynik uruchomienia będzie identyczny z wynikiem uzyskanym w poprzednim uruchomieniu (jeśli dotyczy). + Omawiamy to bardziej szczegółowo później. + +Używając tego jako punktu wyjścia, musimy dodać odpowiednie wejścia testowe dla procesu samtools index oraz ewentualne parametry. + +### 1.2. Przenieś plik testowy i zaktualizuj ścieżkę skryptu + +Zanim przystąpimy do pracy nad uzupełnieniem testu, musimy przenieść plik do jego ostatecznej lokalizacji. Część powodu, dla którego dodaliśmy katalog dla każdego modułu, jest to, że możemy teraz dostarczać testy w katalogu `tests` znajdującym się w tym samym miejscu co plik `main.nf` każdego modułu. Utwórz ten katalog i przenieś tam plik testowy. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Teraz możemy uprościć sekcję `script` pliku testowego do ścieżki względnej: + +=== "Po zmianach" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Przed zmianami" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +To informuje test, gdzie znaleźć plik `main.nf` modułu, bez konieczności określania pełnej ścieżki. + +### 1.3. Dostarcz wejścia testowe dla SAMTOOLS_INDEX + +Plik szkieletowy zawiera symbol zastępczy, który musimy zastąpić faktycznym wejściem testowym, odpowiednim dla wejścia `samtools index`. Odpowiednim wejściem jest plik BAM, który mamy dostępny w katalogu `data/bam`. + +=== "Po zmianach" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Przed zmianami" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Nazwij test na podstawie funkcjonalności + +Jak nauczyliśmy się wcześniej, dobrą praktyką jest zmiana nazwy testu na coś, co ma sens w kontekście testu. + +=== "Po zmianach" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + To przyjmuje dowolny ciąg znaków, więc możemy umieścić cokolwiek chcemy. + Tutaj wybieramy odniesienie do nazwy pliku i jego formatu. + +=== "Przed zmianami" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Uruchom test i sprawdź wynik + +Uruchom test: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Jak nauczyliśmy się wcześniej, to zweryfikowało podstawową asercję o sukcesie procesu i utworzyło plik migawki na podstawie wyjścia procesu. Możemy zobaczyć zawartość pliku migawki w pliku `tests/modules/samtools/index/tests/main.nf.test.snap`: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Możemy również uruchomić test ponownie i zobaczyć, że przechodzi, ponieważ wyjście jest identyczne z migawką: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Dodaj więcej testów do `SAMTOOLS_INDEX` + +Czasami przydatne jest testowanie różnych plików wejściowych, aby upewnić się, że testujemy różne potencjalne problemy. Dodaj testy dla plików BAM matki i ojca z tria z naszych danych testowych. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Następnie możesz uruchomić test ponownie: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Zwróć uwagę na ostrzeżenie odnoszące się do efektu parametru `--update-snapshot`. + +!!! note "Uwaga" + + Tutaj używamy danych testowych, których użyliśmy wcześniej do zademonstrowania naukowych wyników pipeline. + Gdybyśmy planowali obsługiwać te testy w środowisku produkcyjnym, wygenerowalibyśmy mniejsze dane wejściowe do celów testowych. + + Ogólnie rzecz biorąc, ważne jest, aby testy jednostkowe były jak najlżejsze poprzez używanie najmniejszych elementów danych niezbędnych i wystarczających do oceny funkcjonalności procesu, w przeciwnym razie całkowity czas wykonania może znacznie się zwiększyć. + Zestaw testów, którego uruchomienie zajmuje zbyt dużo czasu, to zestaw testów, który prawdopodobnie zostanie pominięty w interesie szybkości. + +### Podsumowanie + +Napisałeś swój pierwszy test modułu dla procesu genomiki, weryfikując, że `SAMTOOLS_INDEX` poprawnie tworzy pliki indeksów dla różnych plików BAM. Zestaw testów zapewnia, że: + +1. Proces działa pomyślnie +2. Pliki indeksów są tworzone +3. Wyjścia są spójne między uruchomieniami +4. Proces działa dla wszystkich plików BAM próbek + +### Co dalej? + +Dowiedz się, jak pisać testy dla innych procesów w naszym workflow genomiki, używając metody setup do obsługi połączonych procesów. Ocenimy również, czy wyjścia, konkretnie nasze pliki VCF, zawierają oczekiwane wywołania wariantów. + +--- + +## 2. Dodaj testy do połączonego procesu i testuj zawartość + +Aby przetestować `GATK_HAPLOTYPECALLER`, musimy dostarczyć procesowi wyjście `SAMTOOLS_INDEX` jako wejście. Moglibyśmy to zrobić, uruchamiając `SAMTOOLS_INDEX`, pobierając jego wyjścia i przechowując je z danymi testowymi workflow. To faktycznie jest zalecanym podejściem dla dopracowanego pipeline, ale nf-test zapewnia alternatywne podejście, używając metody `setup`. + +Dzięki metodzie setup możemy wywołać proces `SAMTOOLS_INDEX` jako część konfiguracji testu, a następnie użyć jego wyjścia jako wejścia dla `GATK_HAPLOTYPECALLER`. Ma to koszt: będziemy musieli uruchamiać proces `SAMTOOLS_INDEX` za każdym razem, gdy uruchamiamy test dla `GATK_HAPLOTYPECALLER`. Jednak może nadal rozwijamy workflow i nie chcemy wstępnie generować danych testowych, które możemy później musieć zmienić. Proces `SAMTOOLS_INDEX` jest również bardzo szybki, więc może korzyści z wstępnego generowania i przechowywania jego wyjść są pomijalne. Oto jak działa metoda setup. + +### 2.1. Wygeneruj i umieść plik testowy + +Jak poprzednio, najpierw generujemy szkielet pliku: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Wynik polecenia" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +To tworzy następujący szkielet testu: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Przenieś plik testowy i zaktualizuj ścieżkę skryptu + +Tworzymy katalog dla pliku testowego znajdującego się w tym samym miejscu co plik `main.nf` modułu: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +I przenosimy tam plik szkieletowy testu: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Na koniec, nie zapomnij zaktualizować ścieżki skryptu: + +=== "Po zmianach" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Przed zmianami" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Dostarcz wejścia za pomocą metody setup + +Wstawiamy blok `setup` przed blokiem `when`, gdzie możemy wywołać uruchomienie procesu `SAMTOOLS_INDEX` na jednym z naszych oryginalnych plików wejściowych. Pamiętaj również, aby jak poprzednio zmienić nazwę testu na coś znaczącego. + +=== "Po zmianach" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Przed zmianami" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Następnie możemy odwołać się do wyjścia tego procesu w bloku `when`, gdzie określamy wejścia testowe: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Wprowadź tę zmianę i uruchom test ponownie: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Tworzy to również plik migawki jak wcześniej. + +### 2.4. Uruchom ponownie i zaobserwuj niepowodzenie + +Co ciekawe, jeśli uruchomisz to samo polecenie ponownie, tym razem test nie powiedzie się. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +Komunikat o błędzie informuje, że wystąpiły różnice między migawkami dla dwóch uruchomień; konkretnie, wartości md5sum są różne dla plików VCF. + +Dlaczego? Krótko mówiąc, narzędzie HaplotypeCaller zawiera znacznik czasu w nagłówku VCF, który jest różny za każdym razem (z definicji). +W rezultacie nie możemy po prostu oczekiwać, że pliki będą miały identyczne sumy md5, nawet jeśli mają identyczną zawartość w zakresie samych wywołań wariantów. + +Jak sobie z tym poradzić? + +### 2.5. Użyj metody asercji zawartości, aby sprawdzić konkretny wariant + +Jednym ze sposobów rozwiązania problemu jest użycie [innego rodzaju asercji](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions). +W tym przypadku sprawdzimy konkretną zawartość zamiast stwierdzać identyczność. +Dokładniej, każemy narzędziu odczytać linie pliku VCF i sprawdzić istnienie konkretnych linii. + +W praktyce zastępujemy drugą asercję w bloku `then` w następujący sposób: + +=== "Po zmianach" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Przed zmianami" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Tutaj odczytujemy pełną zawartość pliku wyjściowego VCF i szukamy dopasowania zawartości, co jest w porządku w przypadku małego pliku testowego, ale nie chciałbyś tego robić na większym pliku. +Możesz zamiast tego wybrać odczytanie konkretnych linii. + +To podejście wymaga bardziej starannego wyboru tego, czego chcemy użyć jako „sygnału" do przetestowania. +Z jasnej strony, może być używane do testowania z dużą precyzją, czy narzędzie analityczne może konsekwentnie identyfikować „trudne" cechy (takie jak rzadkie warianty) w miarę dalszego rozwoju. + +### 2.6. Uruchom ponownie i zaobserwuj sukces + +Po zmodyfikowaniu testu w ten sposób możemy uruchomić test wiele razy i będzie konsekwentnie przechodził. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Dodaj więcej testów + +Dodaj podobne testy dla próbek matki i ojca: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Uruchom polecenie testowe + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +To kończy podstawowy plan testów dla tego drugiego kroku w pipeline. Przechodzimy do trzeciego i ostatniego testu na poziomie modułu! + +### Podsumowanie + +Nauczyłeś się, jak: + +1. Testować procesy zależne od wyjść innych procesów +2. Weryfikować konkretne warianty genomiczne w plikach wyjściowych VCF +3. Obsługiwać niedeterministyczne wyjścia poprzez sprawdzanie konkretnej zawartości +4. Testować wykrywanie wariantów w wielu próbkach + +### Co dalej? + +Dowiedz się, jak pisać testy używające wstępnie wygenerowanych danych testowych dla etapu wspólnego genotypowania. + +--- + +## 3. Używanie wstępnie wygenerowanych danych testowych + +W przypadku etapu wspólnego genotypowania użyjemy innego podejścia - używania wstępnie wygenerowanych danych testowych. Jest to często preferowane dla: + +1. Złożonych procesów z wieloma zależnościami +2. Procesów, których uruchomienie zajmuje dużo czasu +3. Procesów będących częścią stabilnego, produkcyjnego pipeline + +### 3.1. Wygeneruj dane testowe + +Sprawdź wyniki, które wygenerowaliśmy na początku tej sekcji: + +```bash +tree results_genomics/ +``` + +```console title="Zawartość katalogu wyników" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +Etap wspólnego genotypowania potrzebuje plików VCF wygenerowanych przez etapy haplotype caller jako wejścia, wraz z indeksami. Więc skopiujmy wyniki, które mamy, do katalogu testowego modułu `jointgenotyping`. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Teraz możemy użyć tych plików jako wejść do testu, który zamierzamy napisać dla etapu wspólnego genotypowania. + +### 3.2. Wygeneruj szkielet pliku testowego + +Jak poprzednio, najpierw generujemy szkielet pliku: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Wynik polecenia" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +To tworzy następujący szkielet testu: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Przenieś plik testowy i zaktualizuj ścieżkę skryptu + +Tym razem mamy już katalog dla testów znajdujący się w tym samym miejscu co plik `main.nf` modułu, więc możemy przenieść tam plik szkieletowy testu: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +I nie zapomnij zaktualizować ścieżki skryptu: + +=== "Po zmianach" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Przed zmianami" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Dostarcz wejścia + +Wypełnij wejścia na podstawie definicji wejść procesu i odpowiednio zmień nazwę testu: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Użyj asercji zawartości + +Wyjściem etapu wspólnego genotypowania jest kolejny plik VCF, więc znowu użyjemy asercji zawartości. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Sprawdzając zawartość konkretnego wariantu w pliku wyjściowym, ten test weryfikuje, że: + +1. Proces wspólnego genotypowania działa pomyślnie +2. Wyjściowy VCF zawiera wszystkie trzy próbki we właściwej kolejności +3. Konkretny wariant jest wywoływany poprawnie z: + - Dokładnymi genotypami dla każdej próbki (0/1 dla ojca, 1/1 dla matki i syna) + - Poprawnymi głębokościami odczytów i jakościami genotypów + - Statystykami na poziomie populacji, takimi jak częstość alleli (AF=0.833) + +Nie zrobiliśmy migawki całego pliku, ale sprawdzając konkretny wariant, możemy być pewni, że proces wspólnego genotypowania działa zgodnie z oczekiwaniami. + +### 3.6. Uruchom test + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +Test przechodzi, weryfikując, że nasz proces wspólnego genotypowania poprawnie: + +1. Łączy indywidualne pliki VCF próbek +2. Wykonuje wspólne wykrywanie wariantów +3. Produkuje wielopróbkowy VCF ze spójnymi wywołaniami genotypów między uruchomieniami + +### Podsumowanie + +Wiesz, jak: + +- Używać wcześniej wygenerowanych wyników jako wejść dla testów +- Pisać testy używające wstępnie wygenerowanych danych testowych + +### Co dalej? + +Dodaj test na poziomie workflow, aby zweryfikować, że cały pipeline wykrywania wariantów działa od początku do końca. + +--- + +## 4. Dodaj test na poziomie workflow + +Teraz przetestujemy kompletny pipeline wykrywania wariantów, od plików BAM do wspólnych genotypów. To weryfikuje, że: + +1. Wszystkie procesy współpracują poprawnie +2. Dane przepływają prawidłowo między krokami +3. Ostateczne wywołania wariantów są spójne + +### 4.1. Wygeneruj test workflow + +Wygeneruj plik testowy dla kompletnego pipeline: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Wynik polecenia" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +To tworzy podstawowy szkielet testu: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Po prostu popraw nazwę na coś znaczącego (wkrótce zobaczysz, dlaczego to jest przydatne). + +=== "Po zmianach" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Przed zmianami" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "Uwaga" + + W tym przypadku plik testowy może pozostać tam, gdzie `nf-test` go utworzył. + +### 4.2. Określ parametry wejściowe + +Nadal musimy określić wejścia, co jest robione nieco inaczej na poziomie workflow w porównaniu z testami na poziomie modułów. +Istnieje kilka sposobów robienia tego, w tym poprzez określenie profilu. +Jednak prostszym sposobem jest skonfigurowanie bloku `params {}` w pliku `nextflow.config`, który `nf-test init` pierwotnie utworzył w katalogu `tests`. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow config file for running tests +======================================================================================== +*/ + +// Katalog wyjściowy dla wyników workflow +outputDir = 'results_genomics' + +/* + * Parametry pipeline'u + */ + +params { + // Główne dane wejściowe (plik z listą plików wejściowych, jeden na linię) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Pliki pomocnicze + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Nazwa bazowa dla końcowego pliku wyjściowego + cohort_name = "family_trio" +} +``` + +Gdy uruchomimy test, `nf-test` pobierze ten plik konfiguracyjny i odpowiednio pobierze wejścia. + +### 4.3. Uruchom test workflow + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +Test przechodzi, potwierdzając, że nasz kompletny pipeline wykrywania wariantów: + +1. Pomyślnie przetwarza wszystkie próbki +2. Poprawnie łączy wszystkie kroki + +### 4.4. Uruchom WSZYSTKIE testy + +nf-test ma jeszcze jedną sztuczkę w zanadrzu. Możemy uruchomić wszystkie testy naraz! Zmodyfikuj plik `nf-test.config` tak, aby nf-test szukał plików nf-test w każdym katalogu. Możesz to zrobić, modyfikując parametr `testsDir`: + +=== "Po zmianach" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Przed zmianami" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Teraz możemy po prostu uruchomić nf-test i uruchomi _każdy pojedynczy test_ w naszym repozytorium: + +```bash +nf-test test +``` + +??? success "Wynik polecenia" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +8 testów w 1 poleceniu! Poświęciliśmy dużo czasu na konfigurowanie wielu testów, ale jeśli chodzi o ich uruchamianie, było bardzo szybko i łatwo. Możesz zobaczyć, jak przydatne jest to podczas utrzymywania dużego pipeline, który może zawierać setki różnych elementów. Poświęcamy czas na napisanie testów raz, aby móc zaoszczędzić czas na uruchamianiu ich wiele razy. + +Co więcej, możemy to zautomatyzować! Wyobraź sobie testy uruchamiane za każdym razem, gdy Ty lub kolega próbujecie dodać nowy kod. W ten sposób zapewniamy, że nasze pipeline utrzymują wysoki standard. + +## Podsumowanie + +Teraz wiesz, jak pisać i uruchamiać kilka rodzajów testów dla swojego pipeline genomiki używając nf-test. Ten framework testowy pomaga zapewnić, że Twój workflow wykrywania wariantów produkuje spójne, niezawodne wyniki w różnych środowiskach i podczas wprowadzania zmian w kodzie. + +Nauczyłeś się testować krytyczne komponenty takie jak: + +- Proces `SAMTOOLS_INDEX`, który przygotowuje pliki BAM do wykrywania wariantów +- Proces `GATK_HAPLOTYPECALLER`, który identyfikuje warianty w poszczególnych próbkach +- Proces `GATK_JOINTGENOTYPING`, który łączy wywołania wariantów w całej kohorcie + +Wdrożyłeś również różne strategie testowania specyficzne dla danych genomicznych: + +- Weryfikowanie, że pliki VCF zawierają oczekiwane wywołania wariantów pomimo niedeterministycznych elementów, takich jak znaczniki czasu +- Testowanie zestawem danych tria rodzinnego, aby zapewnić prawidłową identyfikację wariantów w powiązanych próbkach +- Sprawdzanie konkretnych współrzędnych genomicznych i informacji o wariantach w plikach wyjściowych + +Te umiejętności testowania są niezbędne do rozwijania solidnych pipeline bioinformatycznych, które mogą niezawodnie przetwarzać dane genomiczne i produkować dokładne wywołania wariantów. W miarę dalszej pracy z Nextflow w analizie genomiki, te fundamenty testowania pomogą Ci utrzymać wysoką jakość kodu, który produkuje wiarygodne wyniki naukowe. diff --git a/docs/pl/docs/nf4_science/genomics/05_configuration.md b/docs/pl/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..79726c6610 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Część 3: Profilowanie i optymalizacja zasobów + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +TO JEST PLACEHOLDER + +!!!note "Uwaga" + + Ten moduł szkoleniowy jest w trakcie przebudowy. + +--- + +TODO + +### 1.1. Uruchom workflow w celu wygenerowania raportu wykorzystania zasobów + +Aby Nextflow automatycznie wygenerował raport, wystarczy dodać `-with-report <nazwa_pliku>.html` do polecenia. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +Raport jest plikiem html, który możesz pobrać i otworzyć w przeglądarce. Możesz również kliknąć na nim prawym przyciskiem myszy w eksploratorze plików po lewej stronie i wybrać `Show preview`, aby wyświetlić go w VS Code. + +Poświęć kilka minut na przejrzenie raportu i sprawdź, czy możesz zidentyfikować możliwości dostosowania zasobów. +Pamiętaj, aby kliknąć zakładki pokazujące wyniki wykorzystania jako procent tego, co zostało przydzielone. +Dostępna jest [dokumentacja](https://www.nextflow.io/docs/latest/reports.html) opisująca wszystkie dostępne funkcje. + +<!-- TODO: insert images --> + +Jedną z obserwacji jest to, że `GATK_JOINTGENOTYPING` wydaje się być bardzo żądny CPU, co ma sens, ponieważ wykonuje wiele złożonych obliczeń. +Moglibyśmy więc spróbować zwiększyć to i sprawdzić, czy skróci to czas wykonania. + +Jednak wygląda na to, że przesadziliśmy z przydziałem pamięci; wszystkie procesy wykorzystują tylko ułamek tego, co im dajemy. +Powinniśmy to zmniejszyć i zaoszczędzić trochę zasobów. + +### 1.2. Dostosuj alokację zasobów dla konkretnego procesu + +Możemy określić alokację zasobów dla danego procesu używając selektora `withName`. +Składnia wygląda następująco, gdy znajduje się samodzielnie w bloku process: + +```groovy title="Składnia" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Dodajmy to do istniejącego bloku process w pliku `nextflow.config`. + +```groovy title="nextflow.config" linenums="11" +process { + // domyślne dla wszystkich procesów + cpus = 2 + memory = 2.GB + // alokacje dla konkretnego procesu + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Po określeniu tego, domyślne ustawienia będą stosowane do wszystkich procesów **z wyjątkiem** procesu `GATK_JOINTGENOTYPING`, który jest wyjątkowy i otrzymuje znacznie więcej CPU. +Miejmy nadzieję, że to powinno mieć efekt. + +### 1.3. Uruchom ponownie ze zmodyfikowaną konfiguracją + +Uruchommy workflow ponownie ze zmodyfikowaną konfiguracją i z włączonym raportowaniem, ale zauważ, że nadajemy raportowi inną nazwę, abyśmy mogli je rozróżnić. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Po raz kolejny prawdopodobnie nie zauważysz istotnej różnicy w czasie wykonania, ponieważ to jest tak małe obciążenie, a narzędzia spędzają więcej czasu na zadaniach pomocniczych niż na wykonywaniu 'właściwej' pracy. + +Jednak drugi raport pokazuje, że nasze wykorzystanie zasobów jest teraz bardziej zrównoważone. + +<!-- **TODO: screenshots?** --> + +Jak widać, to podejście jest użyteczne, gdy Twoje procesy mają różne wymagania zasobowe. Daje Ci możliwość dostosowania alokacji zasobów dla każdego procesu na podstawie rzeczywistych danych, a nie domysłów. + +!!!note "Uwaga" + + To tylko mały przedsmak tego, co możesz zrobić, aby zoptymalizować wykorzystanie zasobów. + Nextflow sam w sobie ma naprawdę sprytną wbudowaną [logikę dynamicznego ponawiania](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources), która ponawia zadania, które zawiodły z powodu ograniczeń zasobowych. + Dodatkowo, Seqera Platform oferuje narzędzia oparte na AI do automatycznej optymalizacji alokacji zasobów. + + Omówimy oba te podejścia w nadchodzącej części tego kursu szkoleniowego. + +Mimo to mogą istnieć pewne ograniczenia dotyczące tego, co możesz (lub musisz) przydzielić, w zależności od tego, jakiego executora obliczeniowego i infrastruktury obliczeniowej używasz. Na przykład Twój klaster może wymagać, abyś pozostał w określonych granicach, które nie mają zastosowania, gdy pracujesz w innym miejscu. diff --git a/docs/pl/docs/nf4_science/genomics/index.md b/docs/pl/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..8283f14b71 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/index.md @@ -0,0 +1,36 @@ +# Nextflow dla Genomiki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ten kurs szkoleniowy jest przeznaczony dla badaczy w dziedzinie genomiki i pokrewnych obszarów, którzy są zainteresowani tworzeniem lub dostosowywaniem potoków analizy danych. +Opiera się na [Hello Nextflow](../../hello_nextflow/) – szkoleniu dla początkujących i демонструje, jak używać Nextflow w specyficznym kontekście dziedziny genomiki. + +W szczególności, ten kurs демонструje, jak zaimplementować prosty potok wykrywania wariantów z [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit), szeroko stosowanym pakietem oprogramowania do analizy danych z sekwencjonowania wysokoprzepustowego. + +Zaczynajmy! Kliknij przycisk "Open in GitHub Codespaces" poniżej, aby uruchomić środowisko szkoleniowe (najlepiej w oddzielnej karcie), a następnie czytaj dalej, podczas gdy się ładuje. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Cele szkoleniowe + +Przechodząc przez ten kurs, nauczysz się, jak stosować podstawowe koncepcje i narzędzia Nextflow do typowego przypadku użycia w genomice. + +Pod koniec tego warsztatu będziesz w stanie: + +- Napisać liniowy workflow do zastosowania wykrywania wariantów dla pojedynczej próbki +- Odpowiednio obsługiwać pliki pomocnicze, takie jak pliki indeksów i zasoby genomu referencyjnego +- Wykorzystać paradygmat przepływu danych Nextflow do zrównoleglenia wykrywania wariantów dla poszczególnych próbek +- Zaimplementować wykrywanie wariantów dla wielu próbek, używając odpowiednich operatorów kanałów +- Zaimplementować testy potoku dla poszczególnych kroków i całościowe, które odpowiednio obsługują specyficzne dla genomiki osobliwości + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Wymagania wstępne + +Kurs zakłada minimalną znajomość następujących zagadnień: + +- Narzędzia i formaty plików powszechnie używane w tej dziedzinie naukowej +- Doświadczenie z wierszem poleceń +- Podstawowe koncepcje i narzędzia Nextflow omówione w [Hello Nextflow](../../hello_nextflow/) – szkoleniu dla początkujących. + +Aby zapoznać się z wymaganiami technicznymi i konfiguracją środowiska, zobacz mini-kurs [Konfiguracja Środowiska](../../envsetup/). diff --git a/docs/pl/docs/nf4_science/genomics/next_steps.md b/docs/pl/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..9d2413a243 --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Następne kroki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gratulujemy ponownie ukończenia kursu szkoleniowego Nextflow For Genomics i dziękujemy za wypełnienie naszej ankiety! + +--- + +## 1. Top 3 sposoby na podniesienie umiejętności Nextflow + +Oto nasze trzy najlepsze rekomendacje dotyczące kolejnych kroków, oparte na kursie, który właśnie ukończyłeś. + +### 1.1. Zastosuj Nextflow do innych przypadków użycia w analizie naukowej + +**Sprawdź stronę [Nextflow for Science](../index.md)**, aby zobaczyć listę innych krótkich, samodzielnych kursów, które pokazują, jak zastosować podstawowe koncepcje i mechanizmy przedstawione w Hello Nextflow do typowych przypadków użycia w analizie naukowej. + +Jeśli nie widzisz swojej dziedziny reprezentowanej przez odpowiedni przypadek użycia, daj nam znać na [forum społeczności](https://community.seqera.io/), abyśmy mogli dodać ją do naszej listy rozwojowej. + +### 1.2. Zacznij pracę z nf-core + +**[nf-core](https://nf-co.re/)** to ogólnoświatowy wysiłek współpracy mający na celu opracowanie standaryzowanych pipeline'ów open-source dla szerokiego zakresu zastosowań w badaniach naukowych. +Projekt obejmuje [ponad 100 pipeline'ów](https://nf-co.re/pipelines/), które są dostępne do użycia od razu, oraz [ponad 1400 modułów procesów](https://nf-co.re/modules/), które można zintegrować z własnymi projektami, a także bogaty zestaw narzędzi deweloperskich. + +Kurs szkoleniowy **[Hello nf-core](../../hello_nf-core/index.md)** wprowadzi Cię w pipeline'y kuratorowane przez społeczność nf-core oraz framework deweloperski, zaprojektowane, aby pomóc Ci pisać powtarzalne, skalowalne i standaryzowane workflow. Nauczysz się, jak używać istniejących pipeline'ów nf-core, przyczyniać się do ich rozwoju, a nawet rozpocząć budowanie własnych, wspieranych przez najlepsze praktyki i żywą społeczność. Jeśli jesteś gotowy, aby zastosować swoje umiejętności Nextflow w rzeczywistych projektach, to jest idealny następny krok. + +### 1.3. Opanuj bardziej zaawansowane funkcje Nextflow + +W kursach Hello celowo utrzymujemy niski poziom złożoności technicznej, aby nie przeciążać Cię informacjami, których nie potrzebujesz, aby rozpocząć pracę z Nextflow. +Kontynuując swoją pracę, będziesz chciał nauczyć się, jak wykorzystać pełny zestaw funkcji i moc Nextflow. + +W tym celu obecnie pracujemy nad **kolekcją [Side Quests](../side_quests/index.md)**, które mają być krótkimi, samodzielnymi kursami zagłębiającymi się w konkretne tematy, takie jak testowanie i zarządzanie metadanymi. + +--- + +## 2. Sprawdź Seqera Platform + +**[Seqera Platform](https://seqera.io/) to najlepszy sposób na uruchamianie Nextflow w praktyce.** + +Jest to platforma chmurowa opracowana przez twórców Nextflow, którą można połączyć z własną infrastrukturą obliczeniową (lokalną, HPC lub chmurową), aby znacznie ułatwić uruchamianie i zarządzanie workflow, a także zarządzanie danymi i przeprowadzanie analiz interaktywnie w środowisku chmurowym. + +Free Tier jest dostępny do bezpłatnego użytku dla wszystkich (z limitami użytkowania). +Kwalifikujący się pracownicy naukowi mogą uzyskać bezpłatny dostęp na poziomie Pro (bez ograniczeń użytkowania) poprzez [Program Akademicki](https://seqera.io/academic/program/). + +Zapoznaj się z [samouczkami Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase), aby sprawdzić, czy może to być dla Ciebie przydatne. + +--- + +### To wszystko na razie! + +**Powodzenia w Twojej podróży z Nextflow i nie wahaj się dać nam znać na [forum społeczności](https://community.seqera.io/), co jeszcze możemy zrobić, aby pomóc.** diff --git a/docs/pl/docs/nf4_science/genomics/survey.md b/docs/pl/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..c1610c578d --- /dev/null +++ b/docs/pl/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Ankieta zwrotna + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Zanim przejdziesz dalej, wypełnij proszę tę krótką ankietę składającą się z 5 pytań, aby ocenić szkolenie, podzielić się opinią na temat swoich doświadczeń i dać nam znać, co jeszcze możemy zrobić, aby pomóc Ci w Twojej przygodzie z Nextflow. + +Wypełnienie ankiety powinno zająć Ci mniej niż minutę. Dziękujemy za pomoc w ulepszaniu naszych materiałów szkoleniowych dla wszystkich! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pl/docs/nf4_science/imaging/00_orientation.md b/docs/pl/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..2e358b3265 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientacja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ta orientacja zakłada, że już otworzyłeś środowisko szkoleniowe, klikając przycisk "Open in GitHub Codespaces". +Jeśli jeszcze tego nie zrobiłeś, zrób to teraz, najlepiej w drugim oknie lub karcie przeglądarki, abyś mógł wrócić do tych instrukcji. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Wymagania dotyczące rozmiaru maszyny" + + Upewnij się, że wybierasz **maszynę 8-rdzeniową** podczas tworzenia Codespace dla tego kursu szkoleniowego. Przepływy pracy bioimagingu wymagają dodatkowych zasobów obliczeniowych. + +## GitHub Codespaces + +Środowisko GitHub Codespaces zawiera wszystkie oprogramowanie, kod i dane niezbędne do pracy z tym kursem szkoleniowym, więc nie musisz niczego instalować samodzielnie. +Jednak potrzebujesz (bezpłatnego) konta GitHub, aby się zalogować, a jeśli nie znasz interfejsu, powinieneś poświęcić kilka minut na zapoznanie się z nim, przechodząc mini-kurs [GitHub Codespaces Orientation](../../envsetup/index.md). + +## Wstępne pobieranie obrazów Docker + +Gdy już otworzysz swój Codespace, pobierzmy wstępnie wszystkie obrazy Docker, których będziemy potrzebować do tego kursu szkoleniowego. +Zaoszczędzi to czas później i zapewni płynne wykonywanie przepływów pracy. + +Otwórz nową kartę terminala i uruchom następujące polecenie: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +To polecenie pobierze wszystkie niezbędne obrazy Docker w tle. +Możesz kontynuować resztę orientacji, podczas gdy to się wykonuje. + +!!!tip + + Flaga `-stub` pozwala na szybkie uruchomienie pipeline bez przetwarzania rzeczywistych danych, co jest idealne do pobierania obrazów. Możesz monitorować postęp w karcie terminala. + +## Katalog roboczy + +Przez cały ten kurs szkoleniowy będziemy pracować w katalogu `nf4-science/imaging/`. + +Zmień teraz katalog, uruchamiając to polecenie w terminalu: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip + + Jeśli z jakiegokolwiek powodu opuścisz ten katalog, zawsze możesz użyć pełnej ścieżki, aby do niego wrócić, zakładając, że pracujesz w środowisku szkoleniowym GitHub Codespaces: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Teraz, aby rozpocząć kurs, kliknij strzałkę w prawym dolnym rogu tej strony.** diff --git a/docs/pl/docs/nf4_science/imaging/01_basics.md b/docs/pl/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..6091d3c6fd --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Część 1: Uruchamianie podstawowych operacji + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej pierwszej części kursu szkoleniowego Nextflow dla Bioimagingu użyjemy bardzo prostego, niezależnego od domeny przykładu Hello World, aby zademonstrować podstawowe operacje i wskazać odpowiednie komponenty kodu Nextflow. + +## 1. Uruchomienie workflow + +Udostępniamy skrypt workflow o nazwie `hello-world.nf`, który przyjmuje dane wejściowe za pomocą argumentu wiersza poleceń o nazwie `--greeting` i tworzy plik tekstowy zawierający to powitanie. +Na razie nie będziemy przeglądać kodu; najpierw zobaczmy, jak wygląda jego uruchomienie. + +### 1.1. Uruchomienie workflow i monitorowanie wykonania + +W terminalu uruchom następujące polecenie: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +Wyjście w konsoli powinno wyglądać mniej więcej tak: + +```console title="Wyjście" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Gratulacje, właśnie uruchomiłeś swój pierwszy workflow Nextflow! + +Najważniejszym wyjściem jest tutaj ostatnia linia (linia 6): + +```console title="Wyjście" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +To mówi nam, że proces `sayHello` został pomyślnie wykonany raz (`1 of 1 ✔`). + +To świetnie, ale możesz się zastanawiać: gdzie jest wyjście? + +### 1.2. Znalezienie pliku wyjściowego w katalogu `results` + +Ten workflow jest skonfigurowany do publikowania swojego wyjścia do katalogu o nazwie `results`. +Jeśli spojrzysz na swój bieżący katalog, zobaczysz, że kiedy uruchomiłeś workflow, Nextflow utworzył nowy katalog o nazwie `results`, który zawiera plik o nazwie `output.txt`. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Otwórz plik; jego zawartość powinna odpowiadać powitaniu, które podałeś w wierszu poleceń. + +<details> + <summary>Zawartość pliku</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +Świetnie, nasz workflow zrobił to, co powinien! + +Należy jednak pamiętać, że 'opublikowany' wynik jest kopią (lub w niektórych przypadkach dowiązaniem symbolicznym) rzeczywistego wyjścia wygenerowanego przez Nextflow podczas wykonywania workflow. + +Teraz zajrzymy pod maskę, aby zobaczyć, gdzie Nextflow faktycznie wykonał pracę. + +!!! warning "Ostrzeżenie" + + Nie wszystkie workflow będą skonfigurowane do publikowania wyjść do katalogu results, i/lub nazwa katalogu może być inna. + Nieco dalej w tej sekcji pokażemy, jak dowiedzieć się, gdzie to zachowanie jest określone. + +### 1.3. Znalezienie oryginalnego wyjścia i logów w katalogu `work/` + +Kiedy uruchamiasz workflow, Nextflow tworzy odrębny 'katalog zadania' dla każdego pojedynczego wywołania każdego procesu w workflow (=każdego kroku w pipeline). +Dla każdego z nich przygotuje niezbędne wejścia, wykona odpowiednie instrukcje i zapisze wyjścia oraz pliki logów w tym jednym katalogu, który jest automatycznie nazwany przy użyciu hasha w celu zapewnienia unikalności. + +Wszystkie te katalogi zadań będą znajdować się w katalogu o nazwie `work` w Twoim bieżącym katalogu (gdzie uruchamiasz polecenie). + +To może brzmieć zagmatwanie, więc zobaczmy, jak to wygląda w praktyce. + +Wracając do wyjścia konsoli dla workflow, które uruchomiliśmy wcześniej, mieliśmy tę linię: + +```console title="Fragment wyjścia polecenia" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Widzisz, jak linia zaczyna się od `[a3/7be2fa]`? +To skrócona forma ścieżki katalogu zadania dla tego jednego wywołania procesu i mówi ci, 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 swoim własnym terminalu) i naciskając klawisz tab, aby automatycznie uzupełnić ścieżkę, lub dodając gwiazdkę: + +```bash +tree work/a3/7be2fa* +``` + +Powinno to zwrócić pełną ścieżkę katalogu: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Zobaczmy, co tam jest. + +!!! Tip "Wskazówka" + + Jeśli przeglądasz zawartość podkatalogu zadania w eksploratorze plików VSCode, zobaczysz wszystkie pliki od razu. + Jednak pliki logów są ustawione jako niewidoczne w terminalu, więc jeśli chcesz użyć `ls` lub `tree` do ich przeglądania, będziesz musiał ustawić odpowiednią opcję wyświetlania niewidocznych plików. + + ```bash + tree -a work + ``` + +Dokładne nazwy podkatalogów będą różne w Twoim systemie. + +<details> + <summary>Zawartość katalogu</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Powinieneś od razu rozpoznać plik `output.txt`, który jest w rzeczywistości oryginalnym wyjściem procesu `sayHello`, które zostało opublikowane w katalogu `results`. +Jeśli go otworzysz, znajdziesz ponownie powitanie `Hello World!`. + +<details> + <summary>Zawartość pliku output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +Co więc z tymi wszystkimi innymi plikami? + +To są pliki pomocnicze i logi, które Nextflow zapisał jako część wykonania zadania: + +- **`.command.begin`**: Plik wartowniczy utworzony natychmiast po uruchomieniu zadania. +- **`.command.err`**: Komunikaty o błędach (`stderr`) emitowane przez wywołanie procesu +- **`.command.log`**: Kompletny log wyjścia emitowany przez wywołanie procesu +- **`.command.out`**: Regularne wyjście (`stdout`) wywołania procesu +- **`.command.run`**: Pełny skrypt uruchomiony przez Nextflow w celu wykonania wywołania procesu +- **`.command.sh`**: Polecenie, które faktycznie zostało 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 Nextflow wykonał, nie włączając całej księgowości i konfiguracji zadania/środowiska. + +<details> + <summary>Zawartość pliku</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Wskazówka" + + Gdy coś pójdzie nie tak i musisz rozwiązać problem, może być przydatne sprawdzenie skryptu `command.sh`, aby sprawdzić dokładnie, jakie polecenie Nextflow skomponował na podstawie instrukcji workflow, interpolacji zmiennych i tak dalej. + +### 1.4. Ćwiczenie opcjonalne: ponowne uruchomienie z różnymi powitaniami + +Spróbuj ponownie uruchomić workflow kilka razy z różnymi wartościami dla argumentu `--greeting`, następnie sprawdź zarówno zawartość katalogu `results/`, jak i katalogów zadań. + +Zauważ, jak wyjścia i logi izolowanych katalogów zadań są zachowywane, podczas gdy zawartość katalogu `results` jest nadpisywana przez wyjście kolejnych wykonań. + +### Podsumowanie + +Wiesz, jak uruchomić prosty skrypt Nextflow, monitorować jego wykonanie i znaleźć jego wyjścia. + +### Co dalej? + +Dowiedz się, jak czytać podstawowy skrypt Nextflow i zidentyfikować, jak jego komponenty odnoszą się do jego funkcjonalności. + +--- + +## 2. Przegląd początkowego skryptu workflow Hello World + +To, co zrobiliśmy, to w zasadzie potraktowanie skryptu workflow jak czarnej skrzynki. +Teraz, gdy zobaczyliśmy, co robi, otwórzmy pudełko i zajrzyjmy do środka. + +_Celem tutaj nie jest zapamiętanie składni kodu Nextflow, ale zbudowanie podstawowej intuicji dotyczącej głównych komponentów i sposobu ich organizacji._ + +### 2.1. Przegląd ogólnej struktury kodu + +Otwórzmy skrypt `hello-world.nf` w panelu edytora. + +<details> + <summary>Kod</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Użyj echo do wypisania pozdrowienia do pliku + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // wyemituj pozdrowienie + sayHello(params.greeting) +} +``` + +</details> + +Skrypt Nextflow obejmuje dwa główne typy podstawowych komponentów: jeden lub więcej **procesów** oraz sam **workflow**. +Każdy **proces** opisuje, jakie operacje odpowiedni krok w pipeline powinien wykonać, podczas gdy **workflow** opisuje logikę przepływu danych, która łączy różne kroki. + +Przyjrzyjmy się najpierw bliżej blokowi **process**, a następnie przyjrzymy się blokowi **workflow**. + +### 2.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 treść procesu oddzielona klamrami. +Treść procesu musi zawierać blok script, który określa polecenie do uruchomienia, którym może być wszystko, co można uruchomić w terminalu wiersza poleceń. + +Tutaj mamy **proces** o nazwie `sayHello`, który przyjmuje zmienną **wejściową** o nazwie `greeting` i zapisuje swoje **wyjście** do pliku o nazwie `output.txt`. + +<details> + <summary>Kod</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Użyj echo do wypisania pozdrowienia do pliku + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +To bardzo minimalna definicja procesu, która zawiera tylko definicję `input`, definicję `output` oraz `script` do wykonania. + +Definicja `input` zawiera kwalifikator `val`, który mówi Nextflow, aby spodziewał się 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 powinno to być traktowane jako ścieżka (obejmuje zarówno ścieżki katalogów, jak i pliki). + +!!! Tip "Wskazówka" + + Definicja wyjścia nie _określa_, jakie wyjście zostanie utworzone. + Po prostu _deklaruje_, gdzie znaleźć oczekiwane pliki wyjściowe, aby Nextflow mógł je znaleźć po zakończeniu wykonania. + + Jest to konieczne do weryfikacji, że polecenie zostało wykonane pomyślnie oraz do przekazania wyjścia do procesów następnych, jeśli jest to potrzebne. + Wyjście wytworzone, które nie pasuje do tego, co jest zadeklarowane w bloku wyjścia, nie zostanie przekazane do procesów następnych. + +W rzeczywistym pipeline proces zazwyczaj zawiera dodatkowe informacje, takie jak dyrektywy procesu, które przedstawimy za chwilę. + +### 2.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 treść workflow oddzielona klamrami. + +Tutaj mamy **workflow**, który składa się z jednego wywołania procesu `sayHello`, który przyjmuje wejście, `params.greeting`, które przechowuje wartość, którą podaliśmy do parametru `--greeting`. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // wyemituj pozdrowienie + sayHello(params.greeting) +} +``` + +To bardzo minimalna definicja **workflow**. +W rzeczywistym pipeline, workflow zazwyczaj zawiera wiele wywołań **procesów** połączonych **kanałami**, i mogą być ustawione domyślne wartości dla zmiennych wejściowych. + +Zobaczymy to w akcji, gdy uruchomimy nf-core/molkart w Części 2 kursu. + +### 2.4. System `params` parametrów wiersza poleceń + +`params.greeting`, który przekazujemy do wywołania procesu `sayHello()`, to elegancki fragment kodu Nextflow i warto poświęcić na niego dodatkową minutę. + +Jak wspomniano powyżej, tak przekazujemy wartość parametru wiersza poleceń `--greeting` do wywołania procesu `sayHello()`. +W rzeczywistości, samo zadeklarowanie `params.someParameterName` umożliwi nam podanie workflow parametru o nazwie `--someParameterName` z wiersza poleceń. + +!!! Tip "Wskazówka" + + Te parametry workflow zadeklarowane przy użyciu systemu `params` zawsze przyjmują dwie myślniki (`--`). + To odróżnia je od parametrów poziomu Nextflow, które przyjmują tylko jeden myślnik (`-`). + +### Podsumowanie + +Wiesz teraz, jak jest zbudowany prosty workflow Nextflow i jak podstawowe komponenty odnoszą się do jego funkcjonalności. + +### Co dalej? + +Naucz się wygodnie zarządzać wykonaniami workflow. + +--- + +## 3. Zarządzanie wykonaniami workflow + +Wiedza, jak uruchamiać workflow i pobierać wyjścia, jest świetna, ale szybko odkryjesz, że jest kilka innych aspektów zarządzania workflow, które ułatwią Ci życie. + +Tutaj pokażemy ci, jak wykorzystać funkcję `resume` do ponownego uruchomienia tego samego workflow, jak sprawdzić logi wykonania za pomocą `nextflow log` oraz jak usunąć starsze katalogi robocze za pomocą `nextflow clean`. + +### 3.1. Ponowne uruchomienie workflow z `-resume` + +Czasami będziesz chciał ponownie uruchomić pipeline, który już wcześniej uruchomiłeś, bez powtarzania jakiejkolwiek pracy, która została już pomyślnie zakończona. + +Nextflow ma opcję o nazwie `-resume`, która pozwala Ci to zrobić. +W szczególności, w tym trybie, wszystkie procesy, które zostały już uruchomione z dokładnie tym samym kodem, ustawieniami i wejściami, zostaną pominięte. +Oznacza to, że Nextflow uruchomi tylko procesy, które dodałeś lub zmodyfikowałeś od ostatniego uruchomienia, lub którym przekazujesz nowe ustawienia lub wejścia. + +Są dwie kluczowe zalety tego podejścia: + +- Jeśli jesteś w trakcie opracowywania pipeline, możesz iterować szybciej, ponieważ musisz uruchomić tylko proces(y), nad którymi aktywnie pracujesz, aby przetestować swoje zmiany. +- Jeśli uruchamiasz pipeline w środowisku produkcyjnym i coś pójdzie nie tak, w wielu przypadkach możesz naprawić problem i ponownie uruchomić pipeline, a on wznowi działanie od punktu awarii, co może zaoszczędzić Ci dużo czasu i mocy obliczeniowej. + +Aby z niego skorzystać, po prostu dodaj `-resume` do swojego polecenia i uruchom je: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Zwróć uwagę na fragment `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 wykorzystał wynik 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 na poprzednie wykonanie mówiąc "Już to zrobiłem tam." + +!!! Tip "Wskazówka" + + Gdy ponownie uruchamiasz pipeline z `resume`, Nextflow nie nadpisuje żadnych plików zapisanych do katalogu `publishDir` przez żadne wywołanie procesu, które zostało wcześniej pomyślnie uruchomione. + +### 3.2. Przegląd logu wcześniejszych wykonań + +Za każdym razem, gdy uruchamiasz workflow nextflow, linia jest zapisywana do pliku logu o nazwie `history`, w ukrytym katalogu o nazwie `.nextflow` w bieżącym katalogu roboczym. + +Bardziej wygodnym sposobem dostępu do tych informacji jest użycie polecenia `nextflow log`. + +```bash +nextflow log +``` + +To wyświetli zawartość pliku logu w terminalu, pokazując Ci znacznik czasu, nazwę uruchomienia, status i pełną linię poleceń dla każdego uruchomienia Nextflow, które zostało uruchomione z bieżącego katalogu roboczego. + +### 3.3. Usuwanie starszych katalogów roboczych + +Podczas procesu rozwoju zazwyczaj uruchamiasz swoje robocze pipeline wiele razy, co może prowadzić do nagromadzenia bardzo wielu plików w wielu podkatalogach. +Ponieważ podkatalogi są nazwane losowo, trudno jest stwierdzić na podstawie ich nazw, które są starsze, a które nowsze. + +Nextflow zawiera wygodne podpolecenie `clean`, które może automatycznie usuwać podkatalogi robocze dla wcześniejszych uruchomień, o które już Ci nie zależy, z kilkoma [opcjami](https://www.nextflow.io/docs/latest/reference/cli.html#clean) do kontrolowania, co zostanie usunięte. + +Możesz użyć logu Nextflow, aby wyszukać uruchomienie na podstawie jego znacznika czasu i/lub linii poleceń, a następnie użyć `nextflow clean -before <run_name> -f`, aby usunąć katalogi robocze z wcześniejszych uruchomień. + +!!! Warning "Ostrzeżenie" + + Usuwanie podkatalogów roboczych z wcześniejszych uruchomień usuwa je z pamięci podręcznej Nextflow i usuwa wszystkie wyjścia, które były przechowywane w tych katalogach. + Oznacza to, że przerywa zdolność Nextflow do wznowienia wykonania bez ponownego uruchamiania odpowiednich procesów. + + Jesteś odpowiedzialny za zapisanie wszelkich wyjść, na których Ci zależy lub na których planujesz polegać! Jeśli używasz dyrektywy `publishDir` w tym celu, upewnij się, że używasz trybu `copy`, a nie trybu `symlink`. + +### Podsumowanie + +Wiesz, jak ponownie uruchomić pipeline bez powtarzania kroków, które zostały już uruchomione w identyczny sposób, sprawdzić log wykonania i użyć polecenia `nextflow clean` do czyszczenia starych katalogów roboczych. + +### Co dalej? + +Teraz, gdy rozumiesz podstawowe operacje Nextflow, jesteś gotowy, aby uruchomić prawdziwy pipeline bioimagingu z nf-core/molkart. diff --git a/docs/pl/docs/nf4_science/imaging/02_run_molkart.md b/docs/pl/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..b45c1e7f23 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Część 2: Uruchomienie nf-core/molkart + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W Części 1 uruchomiliśmy prosty przepływ pracy Hello World, aby zrozumieć podstawy wykonywania Nextflow. +Teraz uruchomimy rzeczywisty pipeline do bioobrażowania: **nf-core/molkart**. + +Ten pipeline przetwarza dane transkryptomiki przestrzennej Molecular Cartography z Resolve Bioscience. +Jednak wzorce Nextflow, których się tutaj nauczysz, mają zastosowanie do każdego pipeline'u nf-core lub produkcyjnego przepływu pracy. + +## 1. Zrozumienie pipeline'ów nf-core + +Zanim uruchomimy pipeline, zrozummy czym jest nf-core i dlaczego ma znaczenie przy uruchamianiu przepływów pracy. + +### 1.1. Czym jest nf-core? + +[nf-core](https://nf-co.re/) to wspierana przez społeczność kolekcja wysokiej jakości pipeline'ów Nextflow. +Wszystkie pipeline'y nf-core mają tę samą strukturę i konwencje, co oznacza, że nauczywszy się uruchamiać jeden, możesz uruchomić każdy z nich. + +Kluczowe cechy pipeline'ów nf-core: + +- **Znormalizowana struktura**: Wszystkie pipeline'y mają spójne nazwy parametrów i wzorce użycia +- **Wbudowane dane testowe**: Każdy pipeline zawiera profile testowe do szybkiej walidacji +- **Kompleksowa dokumentacja**: Szczegółowe instrukcje użycia i opisy parametrów +- **Kontrola jakości**: Automatyczne raporty QC przy użyciu MultiQC +- **Wsparcie dla kontenerów**: Gotowe kontenery dla powtarzalności + +!!! tip "Chcesz dowiedzieć się więcej o nf-core?" + + Aby zapoznać się ze szczegółowym wprowadzeniem do tworzenia pipeline'ów nf-core, sprawdź kurs szkoleniowy [Hello nf-core](../../hello_nf-core/index.md). + Obejmuje on tworzenie i dostosowywanie pipeline'ów nf-core od podstaw. + +### 1.2. Pipeline molkart + +![Pipeline nf-core/molkart](img/molkart.png) + +Pipeline [nf-core/molkart](https://nf-co.re/molkart) przetwarza dane obrazowania transkryptomiki przestrzennej przez kilka etapów: + +1. **Przetwarzanie wstępne obrazu**: Wypełnianie wzoru siatki i opcjonalne wzmocnienie kontrastu +2. **Segmentacja komórek**: Wiele opcji algorytmów (Cellpose, Mesmer, ilastik, Stardist) +3. **Przypisanie punktów**: Przypisanie punktów transkryptu do zsegmentowanych komórek +4. **Kontrola jakości**: Generowanie kompleksowych raportów QC + +Kluczowe wyjścia to: + +- Tabele liczby transkryptów według komórek +- Maski segmentacji +- Raport kontroli jakości MultiQC + +--- + +## 2. Uruchomienie molkart z danymi testowymi + +Zanim zaczniemy, sklonujmy repozytorium molkart lokalnie, abyśmy mogli sprawdzić jego kod: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +To tworzy katalog `molkart/` zawierający kompletny kod źródłowy pipeline'u. + +!!! note "Dlaczego klonujemy lokalnie?" + + Zazwyczaj uruchamiałbyś pipeline'y nf-core bezpośrednio z GitHub używając `nextflow run nf-core/molkart -r 1.2.0`. + Nextflow automatycznie pobiera żądaną wersję pipeline'u do `$HOME/.nextflow/assets/nf-core/molkart` i uruchamia go stamtąd. + Jednak dla celów tego szkolenia klonujemy pipeline do innego katalogu lokalnego, abyśmy mogli łatwiej sprawdzić kod. + +### 2.1. Zrozumienie wymagań kontenerów + +Zanim uruchomimy pełny pipeline, nauczmy się dlaczego kontenery są niezbędne dla pipeline'ów nf-core. + +Spróbujmy uruchomić pipeline używając zestawu danych testowych i parametrów z konfiguracji testowej molkart: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Rozbijmy te parametry: + +- `--input`: Ścieżka do arkusza próbek zawierającego metadane próbek +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Parametry dla wypełniania wzoru siatki +- `--clahe_pyramid_tile`: Rozmiar kernela dla wzmocnienia kontrastu +- `--segmentation_method`: Który algorytm(y) użyć do segmentacji komórek +- `--outdir`: Gdzie zapisać wyniki + +!!! Warning "To polecenie zakończy się niepowodzeniem - to zamierzone!" + + Celowo uruchamiamy to bez kontenerów, aby pokazać dlaczego są potrzebne. + +Po kilku chwilach zobaczysz błąd taki jak ten: + +??? failure "Wyjście polecenia" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**Co się dzieje?** + +Błąd `command not found` (status wyjścia 127) oznacza, że Nextflow próbował uruchomić `duplicate_finder.py`, ale nie mógł go znaleźć w Twoim systemie. +Dzieje się tak, ponieważ: + +1. Pipeline oczekuje zainstalowanego specjalistycznego oprogramowania bioinformatycznego +2. Te narzędzia (takie jak `duplicate_finder.py`, `apply_clahe.dask.py`, itp.) nie są częścią standardowych dystrybucji Linux +3. Bez kontenerów, Nextflow próbuje uruchomić polecenia bezpośrednio na twojej lokalnej maszynie + +**Skąd mają pochodzić te narzędzia?** + +Sprawdźmy jeden z modułów procesu, aby zobaczyć jak deklaruje swoje wymagania dotyczące oprogramowania. + +Otwórz moduł przetwarzania wstępnego CLAHE: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Spójrz na linię 5 - zobaczysz: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Ta linia informuje Nextflow: "Aby uruchomić ten proces, użyj obrazu Docker `ghcr.io/schapirolabor/molkart-local:v0.0.4`, który zawiera wszystkie wymagane oprogramowanie." + +Każdy proces deklaruje który obraz kontenera dostarcza wymagane narzędzia. +Jednak Nextflow używa tych kontenerów tylko jeśli mu powiesz! + +**Rozwiązanie: Włącz Docker w konfiguracji** + +### 2.2. Konfiguracja Docker i uruchomienie pipeline'u + +Aby włączyć Docker, musimy zmienić `docker.enabled` z `false` na `true` w pliku `nextflow.config`. + +Otwórz plik konfiguracyjny: + +```bash +code nextflow.config +``` + +Zmień `docker.enabled = false` na `docker.enabled = true`: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Teraz uruchom pipeline ponownie tym samym poleceniem: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Tym razem Nextflow: + +1. Odczyta ustawienie `docker.enabled = true` z konfiguracji +2. Pobierze wymagane obrazy Docker (tylko za pierwszym razem) +3. Uruchomi każdy proces wewnątrz określonego kontenera +4. Wykona się pomyślnie, ponieważ wszystkie narzędzia są dostępne wewnątrz kontenerów + +!!! Tip "Dlaczego kontenery są ważne" + + Większość pipeline'ów nf-core **wymaga** konteneryzacji (Docker, Singularity, Podman, itp.), ponieważ: + + - Używają specjalistycznego oprogramowania bioinformatycznego niedostępnego w standardowych środowiskach + - Kontenery zapewniają powtarzalność - dokładnie te same wersje oprogramowania działają wszędzie + - Nie musisz ręcznie instalować dziesiątek narzędzi i ich zależności + + Aby uzyskać więcej szczegółów o kontenerach w Nextflow, zobacz [Hello Containers](../../hello_nextflow/05_hello_containers.md) ze szkolenia Hello Nextflow. + +### 2.3. Monitorowanie wykonania + +Podczas działania pipeline'u zobaczysz wyjście podobne do tego: + +??? success "Wyjście polecenia" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Zauważ, jak to wyjście jest bardziej szczegółowe niż nasz przykład Hello World z powodu konwencji nf-core, których przestrzega pipeline: + +- Pipeline pokazuje swoją wersję i logo +- Wyświetlane są parametry konfiguracji +- Wiele procesów działa równolegle (wskazane przez wiele linii procesów) +- Nazwy procesów zawierają pełną ścieżkę modułu (np. `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Zrozumienie wykonania procesu + +Linia executor `executor > local (22)` informuje cię: + +- **executor**: Które środowisko obliczeniowe jest używane (`local` = Twoja maszyna) +- **(22)**: Całkowita liczba uruchomionych zadań + +Każda linia procesu pokazuje: + +- **Hash** (`[1a/2b3c4d]`): Identyfikator katalogu roboczego (jak wcześniej) +- **Nazwa procesu**: Pełna ścieżka modułu i nazwa procesu +- **Identyfikator wejścia**: Nazwa próbki w nawiasach +- **Postęp**: Procent zakończenia i liczba (np. `1 of 1 ✔`) + +### Podsumowanie + +Wiesz jak uruchomić pipeline nf-core z danymi testowymi i interpretować wyjście jego wykonania. + +### Co dalej? + +Naucz się gdzie znaleźć wyniki i jak je interpretować. + +--- + +## 3. Znajdowanie i badanie wyjść + +Kiedy pipeline zakończy się pomyślnie, zobaczysz komunikat o zakończeniu i podsumowanie wykonania. + +### 3.1. Zlokalizowanie katalogu wyników + +Domyślnie pipeline'y nf-core zapisują wyjścia do katalogu określonego przez parametr `outdir`, który ustawiliśmy na `results/`. + +Wyświetl zawartość: + +```bash +tree results/ +``` + +Powinieneś zobaczyć kilka podkatalogów: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Każdy podkatalog zawiera wyjścia z określonego etapu pipeline'u: + +- **mindagap/**: Obrazy z wypełnioną siatką z kroku przetwarzania wstępnego MindaGap +- **clahe/**: Obrazy ze wzmocnionym kontrastem z przetwarzania wstępnego CLAHE +- **stack/**: Stosy obrazów wielokanałowych utworzone do segmentacji +- **segmentation/**: Wyniki segmentacji z różnych algorytmów (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Tabele liczby transkryptów według komórek +- **anndata/**: Obiekty AnnData zawierające macierze transkryptów według komórek i współrzędne przestrzenne +- **molkartqc/**: Metryki kontroli jakości dla przypisania punktów +- **multiqc/**: Kompleksowy raport kontroli jakości +- **pipeline_info/**: Raporty wykonania i logi + +### 3.2. Badanie raportu MultiQC + +Raport MultiQC to kompleksowy plik HTML, który agreguje metryki jakości ze wszystkich kroków pipeline'u. + +Otwórz raport w przeglądarce plików, a następnie kliknij przycisk "Show Preview", aby zobaczyć go renderowanego bezpośrednio w VS Code. + +Raport zawiera: + +- Ogólne statystyki dla wszystkich próbek +- Metryki przetwarzania wstępnego +- Metryki jakości segmentacji +- Liczbę wykrytych komórek i punktów + +!!! Tip + + Raporty MultiQC są zwykle dołączane do wszystkich pipeline'ów nf-core. + Zawsze zapewniają ogólny przegląd wykonania pipeline'u i jakości danych. + +### 3.3. Badanie tabel transkryptów według komórek + +Najważniejszym wyjściem naukowym jest tabela liczby transkryptów według komórek. +Mówi ona ile transkryptów każdego typu zostało wykrytych w każdej komórce. + +Przejdź do katalogu spot2cell: + +```bash +ls results/spot2cell/ +``` + +Znajdziesz pliki takie jak: + +- `cellxgene_mem_only_cellpose.csv`: Tabela transkryptów według komórek używająca segmentacji Cellpose +- `cellxgene_mem_only_mesmer.csv`: Tabela transkryptów według komórek używająca segmentacji Mesmer +- `cellxgene_mem_only_stardist.csv`: Tabela transkryptów według komórek używająca segmentacji Stardist + +Uruchomiliśmy tylko 1 próbkę w tym zestawie danych testowych, ale w prawdziwym eksperymencie mielibyśmy te tabele dla każdej próbki. +Zauważ jak Nextflow jest w stanie przetwarzać wiele metod segmentacji równolegle, ułatwiając porównywanie wyników. + +### 3.4. Przeglądanie raportów wykonania + +Nextflow automatycznie generuje kilka raportów wykonania. + +Sprawdź katalog pipeline_info: + +```bash +ls results/pipeline_info/ +``` + +Kluczowe pliki: + +- **execution_report.html**: Oś czasu i wizualizacja użycia zasobów +- **execution_timeline.html**: Wykres Gantta wykonania procesu +- **execution_trace.txt**: Szczegółowe metryki wykonania zadań +- **pipeline_dag.html**: Skierowany graf acykliczny pokazujący strukturę przepływu pracy + +Otwórz raport wykonania, aby zobaczyć użycie zasobów: + +```bash +code results/pipeline_info/execution_report.html +``` + +To pokazuje: + +- Jak długo trwał każdy proces +- Użycie CPU i pamięci +- Które zadania były w pamięci podręcznej vs. wykonane + +!!! Tip + + Te raporty są niezwykle przydatne do optymalizacji alokacji zasobów i rozwiązywania problemów z wydajnością. + +### Podsumowanie + +Wiesz jak zlokalizować wyjścia pipeline'u, badać raporty kontroli jakości i uzyskać dostęp do metryk wykonania. + +### Co dalej? + +Naucz się o katalogu roboczym i jak Nextflow zarządza plikami pośrednimi. + +--- + +## 4. Eksploracja katalogu roboczego + +Tak jak w naszym przykładzie Hello World, cała rzeczywista praca odbywa się w katalogu `work/`. + +### 4.1. Zrozumienie struktury katalogu roboczego + +Katalog roboczy zawiera podkatalog dla każdego zadania, które zostało wykonane. +Dla tego pipeline'u z 12 zadaniami będzie 12 podkatalogów roboczych. + +Wyświetl listę katalogu roboczego: + +```bash +ls -d work/*/*/ | head -5 +``` + +To pokazuje pierwsze 5 katalogów zadań. + +### 4.2. Inspekcja katalogu zadania + +Wybierz jeden z hashy procesu segmentacji z wyjścia konsoli (np. `[3m/4n5o6p]`) i zajrzyj do środka: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Zobaczysz: + +- **Pliki .command.\***: Skrypty wykonania Nextflow i logi (jak wcześniej) +- **Przygotowane pliki wejściowe**: Dowiązania symboliczne do rzeczywistych plików wejściowych +- **Pliki wyjściowe**: Maski segmentacji, wyniki pośrednie, itp. + +Kluczowa różnica od Hello World: + +- Rzeczywiste pipeline'y przygotowują duże pliki wejściowe (obrazy, dane referencyjne) +- Pliki wyjściowe mogą być dość duże (maski segmentacji, przetworzone obrazy) +- Wiele plików wejściowych i wyjściowych na zadanie + +!!! Tip + + Jeśli proces się nie powiedzie, możesz przejść do jego katalogu roboczego, sprawdzić `.command.err` w poszukiwaniu komunikatów o błędach, a nawet ponownie uruchomić `.command.sh` ręcznie, aby debugować problem. + +### 4.3. Czyszczenie katalogu roboczego + +Katalog roboczy może stać się dość duży po wielu uruchomieniach pipeline'u. +Jak nauczyliśmy się w Części 1, możesz użyć `nextflow clean`, aby usunąć katalogi robocze ze starych uruchomień. + +Jednak dla pipeline'ów nf-core z dużymi plikami pośrednimi szczególnie ważne jest regularne czyszczenie. + +### Podsumowanie + +Rozumiesz jak pipeline'y nf-core organizują swoje katalogi robocze i jak sprawdzać poszczególne zadania w celu debugowania. + +### Co dalej? + +Naucz się o pamięci podręcznej Nextflow i jak wznowić nieudane uruchomienia pipeline'u. + +--- + +## 5. Wznowienie uruchomienia pipeline'u + +Jedną z najpotężniejszych funkcji Nextflow jest możliwość wznowienia pipeline'u od momentu niepowodzenia. + +### 5.1. Mechanizm pamięci podręcznej + +Kiedy uruchamiasz pipeline z `-resume`, Nextflow: + +1. Sprawdza pamięć podręczną dla każdego zadania +2. Jeśli wejścia, kod i parametry są identyczne, ponownie używa wyniku z pamięci podręcznej +3. Ponownie uruchamia tylko zadania, które się zmieniły lub zakończyły się niepowodzeniem + +Jest to niezbędne dla długo działających pipeline'ów, gdzie niepowodzenia mogą wystąpić późno w wykonaniu. + +### 5.2. Wypróbuj resume z molkart + +Uruchom to samo polecenie ponownie, ale dodaj `-resume`: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Powinieneś zobaczyć wyjście takie jak: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Zauważ `cached: 2` lub `cached: 1` dla każdego procesu - nic nie zostało ponownie wykonane! + +### 5.3. Kiedy resume jest przydatne + +Resume jest szczególnie wartościowe gdy: + +- Pipeline kończy się niepowodzeniem z powodu limitów zasobów (brak pamięci, przekroczenie limitu czasu) +- Musisz zmodyfikować procesy końcowe bez ponownego uruchamiania kroków początkowych +- Twoje połączenie sieciowe zostanie przerwane podczas pobierania danych +- Chcesz dodać dodatkowe wyjścia bez powtarzania obliczeń + +!!! Warning + + Resume działa tylko jeśli nie zmieniłeś danych wejściowych, kodu pipeline'u lub parametrów. + Jeśli zmienisz którekolwiek z nich, Nextflow poprawnie ponownie uruchomi dotknięte zadania. + +### Podsumowanie + +Wiesz jak używać `-resume`, aby efektywnie ponownie uruchamiać pipeline'y bez powtarzania udanych zadań. + +### Co dalej? + +Teraz gdy możesz uruchomić nf-core/molkart z danymi testowymi, jesteś gotowy nauczyć się jak skonfigurować go dla własnych zestawów danych. diff --git a/docs/pl/docs/nf4_science/imaging/03_inputs.md b/docs/pl/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..e10d8f0112 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Część 3: Organizowanie danych wejściowych + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W Części 2 uruchomiliśmy molkart z wieloma parametrami w wierszu poleceń. +Teraz poznamy dwa lepsze podejścia do zarządzania wejściami: **pliki parametrów** oraz **arkusze próbek**. + +## 1. Używanie plików parametrów + +### 1.1. Problem z długimi wierszami poleceń + +Przypomnijmy sobie nasze polecenie z Części 2: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +To działa, ale trudno to odtworzyć, udostępnić lub zmodyfikować. +Co jeśli musisz ponownie uruchomić tę samą analizę za miesiąc? +Co jeśli współpracownik chce użyć dokładnie Twoich ustawień? + +### 1.2. Rozwiązanie: Użyj pliku parametrów + +Utwórz plik o nazwie `params.yaml`: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Teraz Twoje polecenie staje się: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +To wszystko! Plik parametrów dokumentuje dokładną konfigurację i ułatwia ponowne uruchomienie lub udostępnienie. + +### 1.3. Nadpisywanie parametrów + +Nadal możesz nadpisać konkretne parametry z wiersza poleceń: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +Powyższa linia zmienia `segmentation_method` na `stardist` oraz nazwę `--outdir` na `stardist_results` zamiast parametrów z pliku `params.yaml`. +Dodatkowo możesz zauważyć, że flaga `-resume` pozwoliła nam ponownie użyć wyników przetwarzania wstępnego z poprzedniego uruchomienia, oszczędzając czas. +Możesz użyć tego wzorca, aby szybko testować różne warianty pipeline'u. + +### Podsumowanie + +Pliki parametrów sprawiają, że Twoje analizy są odtwarzalne i łatwe do udostępnienia. +Używaj ich do każdej rzeczywistej pracy analitycznej. + +### Co dalej? + +Dowiedz się, jak arkusze próbek organizują informacje o wielu próbkach. + +--- + +## 2. Wzorzec arkusza próbek + +### 2.1. Czym jest arkusz próbek? + +Arkusz próbek to plik CSV, który opisuje Twoje próbki wejściowe. +Każdy wiersz to próbka, a kolumny określają pliki i metadane dla tej próbki. + +Spójrzmy na arkusz próbek, którego używaliśmy: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Kolumny to: + +- `sample`: Unikalny identyfikator próbki +- `nuclear_image`: Obraz barwienia jądrowego (TIFF) +- `spot_table`: Punkty transkryptów (TXT) +- `membrane_image`: Obraz barwienia błonowego (TIFF, opcjonalny) + +### 2.2. Ścieżki do plików + +Arkusze próbek akceptują wiele typów ścieżek: + +- **URL**: Nextflow pobiera automatycznie (jak pokazano powyżej) +- **Ścieżki lokalne**: `data/nuclear.tiff` lub `/absolute/path/to/nuclear.tiff` +- **Przechowywanie w chmurze**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Możesz mieszać typy ścieżek w tym samym arkuszu próbek. + +### 2.3. Tworzenie własnego arkusza próbek + +Najpierw pobierzmy pliki danych testowych lokalnie: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Teraz zmodyfikujmy arkusz próbek, aby odwoływał się do tych lokalnych plików: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Ostrzeżenie" + + Zauważ, że ścieżki w arkuszu próbek są względne względem miejsca, **z którego uruchamiasz** Nextflow, a nie względem miejsca, w którym znajduje się arkusz próbek. + +Na koniec wykonajmy nf-core/molkart jeszcze raz z arkuszem próbek zawierającym lokalne ścieżki do plików: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Jak widzisz, Nextflow wykonuje to uruchomienie podobnie jak wtedy, gdy pliki były pobierane z Github. To jedna ze świetnych funkcji Nextflow - właściwie przygotowuje dane dla Ciebie, niezależnie od tego, gdzie się znajdują. + +### Podsumowanie + +Arkusze próbek organizują zestawy danych z wieloma próbkami w sposób, który pozwala jawnie zdefiniować metadane wraz ze ścieżkami do plików. +Większość pipeline'ów nf-core używa tego wzorca. + +### Co dalej? + +Teraz, gdy omówiliśmy dane wejściowe, zbadajmy, jak skonfigurować pipeline'y Nextflow dla różnych środowisk obliczeniowych. diff --git a/docs/pl/docs/nf4_science/imaging/04_config.md b/docs/pl/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..ab09c01404 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Część 4: Konfiguracja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W częściach 1-3 nauczyliśmy się jak uruchamiać Nextflow, uruchamiać pipeline nf-core oraz zarządzać wejściami za pomocą plików parametrów i arkuszy próbek. +Teraz zbadamy jak konfigurować pipeline'y dla różnych środowisk obliczeniowych używając **plików konfiguracyjnych** i **profili**. + +## Cele nauczania + +Pod koniec tej części będziesz potrafić: + +- Zrozumieć jak Nextflow rozwiązuje konfigurację z wielu źródeł +- Używać wbudowanych profili nf-core dla kontenerów i testowania +- Tworzyć własne profile dla różnych środowisk obliczeniowych +- Dostosowywać żądania zasobów używając etykiet procesów +- Zarządzać limitami zasobów w ograniczonych środowiskach +- Sprawdzać rozwiązaną konfigurację za pomocą `nextflow config` + +--- + +## 1. Zrozumienie konfiguracji Nextflow + +### 1.1. Czym jest plik konfiguracyjny? + +Nextflow używa plików konfiguracyjnych do oddzielenia **logiki workflow** (co robić) od **ustawień wykonania** (jak i gdzie to robić). + +Pliki konfiguracyjne kontrolują: + +- Silniki kontenerów (Docker, Singularity, Conda) +- Zasoby obliczeniowe (CPU, pamięć, czas) +- Platformy wykonania (lokalnie, HPC, chmura) +- Parametry pipeline'u + +### 1.2. Kolejność pierwszeństwa konfiguracji + +Nextflow wczytuje konfigurację z wielu źródeł, przy czym późniejsze źródła nadpisują wcześniejsze: + +1. **Konfiguracja pipeline'u**: `nextflow.config` w repozytorium pipeline'u +2. **Konfiguracja katalogu**: `nextflow.config` w bieżącym katalogu roboczym +3. **Konfiguracja użytkownika**: `~/.nextflow/config` +4. **Linia poleceń**: Parametry i opcje przekazane bezpośrednio + +To warstwowe podejście pozwala zachować wartości domyślne w pipeline'ie, nadpisać je ustawieniami użytkownika i dokonać szybkich dostosowań w linii poleceń. + +### 1.3. Nasza obecna konfiguracja + +Przyjrzyjmy się konfiguracji, której używaliśmy: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Zakomentujmy lub zmieńmy z powrotem linię `docker.enabled = true` z Części 2 i dowiedzmy się, jak możemy osiągnąć ten sam rezultat używając profilu w molkart. + +--- + +## 2. Używanie profili + +### 2.1. Czym są profile? + +Profile to nazwane zestawy konfiguracji, które można aktywować za pomocą flagi `-profile` poprzez polecenie `nextflow run`. +Ułatwiają one przełączanie między różnymi scenariuszami obliczeniowymi bez edycji plików konfiguracyjnych. + +Wszystkie pipeline'y nf-core zawierają szereg domyślnych profili, z których możemy skorzystać. + +### 2.2. Sprawdzanie wbudowanych profili + +Sprawdźmy je w pliku `molkart/nextflow.config` powiązanym z bazą kodu pipeline'u: + +```bash +code molkart/nextflow.config +``` + +Wyszukaj blok `profiles`: + +```groovy title="molkart/nextflow.config (fragment)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Popularne profile kontenerów: + +- `docker`: Używaj kontenerów Docker (najczęściej dla lokalnego rozwoju) +- `singularity`: Używaj Singularity/Apptainer (powszechne na HPC) +- `conda`: Używaj środowisk Conda +- `apptainer`: Używaj kontenerów Apptainer + +### 2.3. Ponowne uruchomienie z profilami zamiast nextflow.config + +Teraz, gdy wyłączyliśmy konfigurację docker w naszym lokalnym pliku `nextflow.config` i rozumiemy profile, uruchommy ponownie pipeline używając flagi `-profile`. + +Wcześniej w Części 3 utworzyliśmy plik `params.yaml` z naszymi własnymi parametrami. +Możemy teraz połączyć to z wbudowanym profilem Docker: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Rozłóżmy na czynniki pierwsze, co robi każda flaga: + +- `-profile docker`: Aktywuje profil Docker z `nextflow.config` molkart, który ustawia `docker.enabled = true` +- `-params-file params.yaml`: Wczytuje wszystkie parametry pipeline'u z naszego pliku YAML +- `-resume`: Ponownie używa wyników z cache'u z poprzednich uruchomień + +Ponieważ używamy `-resume`, Nextflow sprawdzi, czy coś się zmieniło od ostatniego uruchomienia. +Jeśli parametry, wejścia i kod są takie same, wszystkie zadania będą pobrane z cache'u i pipeline zakończy się niemal natychmiast. + +```console title="Wyjście (fragment)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Zauważ, że wszystkie procesy pokazują `cached: 2` lub `cached: 1` - nic nie zostało ponownie wykonane! + +### 2.4. Profile testowe + +Profile testowe zapewniają szybkie sposoby określania domyślnych parametrów wejściowych i plików danych, aby umożliwić weryfikację działania pipeline'u. +Pipeline'y nf-core zawsze zawierają co najmniej dwa profile testowe: + +- `test`: Mały zestaw danych z szybkimi parametrami do szybkiego testowania +- `test_full`: Bardziej kompleksowy test z większymi danymi + +Przyjrzyjmy się bliżej profilowi `test` w molkart, który jest dołączany za pomocą dyrektywy `includeConfig`: + +```groovy title="molkart/nextflow.config (fragment)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Oznacza to, że za każdym razem gdy uruchamiamy pipeline z `-profile test`, Nextflow wczyta konfigurację z `conf/test.config`. + +```groovy title="molkart/conf/test.config (fragment)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Zauważ, że ten profil zawiera te same parametry, których użyliśmy wcześniej w naszym pliku `params.yaml`. + +Możesz aktywować wiele profili oddzielając je przecinkami. +Użyjmy tego do przetestowania naszego pipeline'u bez potrzeby używania pliku params: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +To łączy: + +- `docker`: Włącz kontenery Docker +- `test`: Użyj zestawu danych testowych i parametrów + +Profile są stosowane od lewej do prawej, więc późniejsze profile nadpisują wcześniejsze, jeśli ustawiają te same wartości. + +### Podsumowanie + +Pipeline'y nf-core zawierają wbudowane profile dla kontenerów, testowania i specjalnych środowisk. +Możesz łączyć wiele profili, aby zbudować potrzebną konfigurację. + +### Co dalej? + +Naucz się jak tworzyć własne profile dla różnych środowisk obliczeniowych. + +--- + +## 3. Tworzenie własnych profili + +### 3.1. Tworzenie profili do przełączania między lokalnym rozwojem a wykonaniem na HPC + +Stwórzmy własne profile dla dwóch scenariuszy: + +1. Lokalny rozwój z Docker +2. Uniwersytecki HPC zeSchedulerem Slurm i Singularity + +Dodaj następujący kod do swojego `nextflow.config`: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Teraz możesz łatwo przełączać się między środowiskami: + +```bash +# Dla lokalnego rozwoju +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Dla HPC (gdy jest dostępny) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "Uwaga" + + Nie możemy przetestować profilu HPC w tym środowisku szkoleniowym, ponieważ nie mamy dostępu do schedulera Slurm. + Ale to pokazuje, jak skonfigurowałbyś go do rzeczywistego użycia. + +### 3.2. Użycie `nextflow config` do sprawdzenia konfiguracji + +Polecenie `nextflow config` pokazuje w pełni rozwiązaną konfigurację bez uruchamiania pipeline'u. + +Wyświetl domyślną konfigurację: + +```bash +nextflow config ./molkart +``` + +Wyświetl konfigurację z konkretnym profilem: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Jest to niezwykle przydatne do: + +- Debugowania problemów z konfiguracją +- Zrozumienia, jakie wartości będą faktycznie użyte +- Sprawdzania, jak wiele profili wchodzi w interakcje + +### Podsumowanie + +Własne profile pozwalają na przełączanie między różnymi środowiskami obliczeniowymi za pomocą pojedynczej flagi linii poleceń. +Użyj `nextflow config` do sprawdzenia rozwiązanej konfiguracji przed uruchomieniem. + +### Co dalej? + +Naucz się jak dostosować żądania zasobów dla poszczególnych procesów używając systemu etykiet procesów nf-core. + +--- + +## 4. Dostosowywanie żądań zasobów + +### 4.1. Zrozumienie etykiet procesów w pipeline'ach nf-core + +Dla uproszczenia, pipeline'y nf-core używają [**etykiet procesów**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) do standaryzacji alokacji zasobów we wszystkich pipeline'ach. +Każdy proces jest oznaczony etykietą taką jak `process_low`, `process_medium` lub `process_high` w celu opisania niskich, średnich lub wysokich wymagań zasobów obliczeniowych. +Te etykiety są konwertowane na konkretne żądania zasobów w jednym z plików konfiguracyjnych znajdujących się w katalogu `conf/` pipeline'u. + +```groovy title="molkart/conf/base.config (fragment)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Zauważ mnożnik `task.attempt` - pozwala to kolejnym ponownym próbom zadania zażądać więcej zasobów, jeśli pipeline jest ustawiony z `process.maxRetries > 1`. + +### 4.2. Nadpisywanie zasobów dla konkretnych procesów + +Aby uzyskać szczegółową kontrolę, wskaż poszczególne procesy po nazwie: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Jeśli spróbujemy uruchomić ten pipeline z powyższym nadpisaniem, proces `CELLPOSE` zażąda 16 CPU i 32 GB pamięci zamiast wartości domyślnej zdefiniowanej przez jego etykietę. +Spowoduje to niepowodzenie pipeline'u w naszym obecnym środowisku, ponieważ nie mamy dostępnej takiej ilości pamięci RAM. +W następnej sekcji nauczymy się, jak zapobiegać tego typu awariom. + +!!! tip "Wskazówka" + + Aby znaleźć nazwy procesów, sprawdź wyjście wykonania pipeline'u lub sprawdź `.nextflow.log`. + Nazwy procesów mają wzór `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### Podsumowanie + +Pipeline'y nf-core używają etykiet procesów do standaryzacji alokacji zasobów. +Możesz nadpisać zasoby według etykiety (wpływa na wiele procesów) lub według nazwy (wpływa na jeden konkretny proces). + +### Co dalej? + +Naucz się jak zarządzać limitami zasobów w ograniczonych środowiskach takich jak GitHub Codespaces. + +--- + +## 5. Zarządzanie zasobami w ograniczonych środowiskach + +### 5.1. Problem limitów zasobów + +Gdybyśmy spróbowali uruchomić molkart z procesem żądającym 16 CPU i 32 GB pamięci (jak pokazano w sekcji 4.2), nie powiódłby się w naszym obecnym środowisku, ponieważ nie mamy dostępnych tylu zasobów. +W środowisku klastra z większymi węzłami takie żądania zostałyby przesłane do schedulera. + +W ograniczonych środowiskach takich jak GitHub Codespaces, bez limitów, Nextflow odmówiłby uruchomienia procesów przekraczających dostępne zasoby. + +### 5.2. Ustawianie limitów zasobów + +Dyrektywa `resourceLimits` ogranicza żądania zasobów do określonych wartości: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Mówi to Nextflow: "Jeśli jakikolwiek proces zażąda więcej niż 2 CPU lub 7 GB pamięci, ogranicz to do tych limitów." + +### 5.3. Dodawanie limitów zasobów do własnych profili + +Zaktualizuj swoje własne profile, aby zawierały odpowiednie limity: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "Ostrzeżenie" + + Ustawienie limitów zasobów zbyt nisko może spowodować niepowodzenie procesów lub spowolnić ich działanie. + Pipeline może potrzebować użyć mniej wymagających pamięciowo algorytmów lub przetwarzać dane w mniejszych fragmentach. + +### Podsumowanie + +Użyj `resourceLimits`, aby uruchamiać pipeline'y w środowiskach z ograniczonymi zasobami poprzez ograniczenie żądań zasobów procesów. +Różne profile mogą mieć różne limity odpowiednie dla swojego środowiska. + +### Co dalej? + +Ukończyłeś podstawowe szkolenie Nextflow for Bioimaging! + +--- + +## Podsumowanie + +Teraz rozumiesz, jak konfigurować pipeline'y Nextflow dla różnych środowisk obliczeniowych. + +Kluczowe umiejętności, których się nauczyłeś: + +- **Kolejność pierwszeństwa konfiguracji**: Jak Nextflow rozwiązuje ustawienia z wielu źródeł +- **Profile nf-core**: Używanie wbudowanych profili dla kontenerów, testowania i narzędzi +- **Własne profile**: Tworzenie własnych profili dla różnych środowisk +- **Etykiety procesów**: Zrozumienie i nadpisywanie żądań zasobów według etykiety +- **Limity zasobów**: Zarządzanie ograniczonymi środowiskami za pomocą `resourceLimits` +- **Sprawdzanie konfiguracji**: Używanie `nextflow config` do debugowania i weryfikacji ustawień + +Te umiejętności konfiguracyjne są przydatne dla każdego pipeline'u Nextflow i pomogą Ci efektywnie uruchamiać przepływy pracy na lokalnych maszynach, klastrach HPC i platformach chmurowych. + +### Co dalej? + +Gratulacje ukończenia kursu Nextflow for Bioimaging! + +Następne kroki: + +- Wypełnij ankietę kursu, aby przekazać informację zwrotną +- Sprawdź [Hello Nextflow](../hello_nextflow/index.md), aby dowiedzieć się więcej o tworzeniu przepływów pracy +- Poznaj [Hello nf-core](../hello_nf-core/index.md), aby zgłębić narzędzia nf-core +- Przeglądaj inne kursy w [kolekcjach szkoleniowych](../training_collections/index.md) diff --git a/docs/pl/docs/nf4_science/imaging/index.md b/docs/pl/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..bf70078a26 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/index.md @@ -0,0 +1,40 @@ +```markdown +--- +title: Nextflow run dla Obrazowania +hide: + - toc +--- + +# Nextflow run dla Obrazowania + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ten kurs szkoleniowy jest przeznaczony dla naukowców zajmujących się obrazowaniem i biologią przestrzenną, którzy są zainteresowani uruchamianiem i dostosowywaniem potoków analizy danych. +Kurs uczy podstawowych koncepcji Nextflow związanych z uruchamianiem, organizowaniem i konfigurowaniem workflow przy użyciu [nf-core/molkart](https://nf-co.re/molkart), pipeline do przetwarzania danych transkryptomiki przestrzennej Molecular Cartography. +Umiejętności, których się tutaj nauczysz, można przenieść do dowolnego pipeline Nextflow lub nf-core. + +Zaczynajmy! Kliknij przycisk "Open in GitHub Codespaces" poniżej, aby uruchomić środowisko szkoleniowe (najlepiej w osobnej karcie), a następnie czytaj dalej podczas jego ładowania. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Cele szkolenia + +Pracując nad tym kursem, nauczysz się, jak stosować podstawowe koncepcje i narzędzia Nextflow do uruchamiania potoków analizy obrazowania. + +Pod koniec tego warsztatu będziesz w stanie: + +- Uruchomić workflow Nextflow lokalnie i monitorować jego wykonywanie +- Znaleźć i zinterpretować wyjścia (wyniki) i pliki dziennika wygenerowane przez Nextflow +- Uruchomić pipeline nf-core z danymi testowymi i własnymi danymi wejściowymi +- Skonfigurować wykonywanie pipeline przy użyciu profili i plików parametrów +- Zarządzać danymi wejściowymi za pomocą arkuszy próbek i parametrów wiersza poleceń + +## Odbiorcy i wymagania wstępne + +Ten kurs zakłada podstawową znajomość następujących zagadnień: + +- Doświadczenie z wierszem poleceń +- Podstawowa znajomość formatów plików obrazowych (obrazy TIFF, dane tabelaryczne) + +Wymagania techniczne i konfigurację środowiska można znaleźć w mini-kursie [Environment Setup](../../envsetup/). +``` diff --git a/docs/pl/docs/nf4_science/imaging/next_steps.md b/docs/pl/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..df7180e406 --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Następne kroki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Gratulacje ukończenia szkolenia Nextflow dla Bioimagingu! + +Posiadasz teraz podstawowe umiejętności do uruchamiania i konfigurowania pipeline'ów Nextflow do analizy danych obrazowych. + +## Kontynuuj naukę + +Oto kilka zalecanych następnych kroków, aby pogłębić swoją wiedzę o Nextflow: + +### Odkryj więcej pipeline'ów nf-core + +- **Przeglądaj wszystkie pipeline'y**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Twórz własne pipeline'y + +Jeśli chcesz nauczyć się pisać pipeline'y Nextflow: + +- **[Hello Nextflow](../../hello_nextflow/)**: Kompleksowe szkolenie z tworzenia w Nextflow +- **[Side Quests](../../side_quests/)**: Zaawansowane tematy dla twórców pipeline'ów + +### Dołącz do społeczności + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Uzyskaj pomoc i połącz się z innymi użytkownikami +- **[nf-core Slack](https://nf-co.re/join)**: Dołącz do społeczności nf-core +- **[Seqera Community Forum](https://community.seqera.io)**: Zadawaj pytania i dziel się doświadczeniami + +### Dodatkowe zasoby + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Kompletna dokumentacja referencyjna +- **[nf-core Documentation](https://nf-co.re/docs)**: Wytyczne i najlepsze praktyki + +## Zaangażuj się + +- **Wnieś wkład do nf-core**: Pomóż ulepszyć pipeline'y lub dokumentację +- **Udostępnij swoje workflow'y**: Przekaż własne pipeline'y społeczności +- **Weź udział w wydarzeniach**: Dołącz do Nextflow Summit i sesji szkoleniowych społeczności + +Dziękujemy za naukę z nami! diff --git a/docs/pl/docs/nf4_science/imaging/survey.md b/docs/pl/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..86d2bee98b --- /dev/null +++ b/docs/pl/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Ankieta + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Dziękujemy za ukończenie szkolenia Nextflow dla bioimagingu! + +Będziemy bardzo wdzięczni za opinię, która pomoże nam ulepszyć te materiały szkoleniowe. + +Prosimy o poświęcenie kilku minut na wypełnienie krótkiej ankiety: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Twoje odpowiedzi pomogą nam zrozumieć, co działało dobrze i co możemy poprawić dla przyszłych uczestników. + +Dziękujemy za czas i udział! diff --git a/docs/pl/docs/nf4_science/index.md b/docs/pl/docs/nf4_science/index.md new file mode 100644 index 0000000000..b78afe3b1c --- /dev/null +++ b/docs/pl/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow dla Nauki +hide: + - toc +--- + +# Nextflow dla Nauki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +To są kursy, które pokazują, jak zastosować koncepcje i komponenty przedstawione w kursie dla początkujących [Hello Nextflow](../hello_nextflow/) do konkretnych przypadków użycia naukowego. Każdy kurs składa się z serii modułów szkoleniowych zaprojektowanych, aby pomóc uczącym się stopniowo rozwijać swoje umiejętności. + +!!! exercise "Ćwiczenie" + + !!! tip inline end "" + + :material-run-fast: Naucz się opracowywać pipeline dla genomiki w Nextflow. + + To jest kurs dla badaczy, którzy chcą nauczyć się, jak opracowywać własne pipeline genomiczne. Kurs wykorzystuje przypadek użycia wykrywania wariantów, aby zademonstrować, jak opracować prosty, ale funkcjonalny pipeline genomiczny. + + [Rozpocznij szkolenie Nextflow dla Genomiki :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Ćwiczenie" + + !!! tip inline end "" + + :material-run-fast: Naucz się opracowywać pipeline do przetwarzania danych RNAseq w Nextflow. + + To jest kurs dla badaczy, którzy chcą nauczyć się, jak opracowywać własne pipeline RNAseq. Kurs wykorzystuje przypadek użycia przetwarzania bulk RNAseq, aby zademonstrować, jak opracować prosty, ale funkcjonalny pipeline RNAseq. + + [Rozpocznij szkolenie Nextflow dla RNAseq :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Ćwiczenie" + + !!! tip inline end "" + + :material-run-fast: Naucz się uruchamiać pipeline do przetwarzania danych obrazowych w Nextflow. + + To jest kurs dla badaczy, którzy chcą nauczyć się, jak uruchamiać i konfigurować pipeline bioimaging. Kurs wykorzystuje nf-core/molkart, aby zademonstrować podstawowe wzorce użycia Nextflow mające zastosowanie do każdego pipeline. + + [Rozpocznij szkolenie Nextflow dla Bioimaging :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Daj nam znać, jakie inne dziedziny i przypadki użycia chciałbyś zobaczyć tutaj, publikując w [sekcji Szkolenia](https://community.seqera.io/c/training/) na forum społeczności. diff --git a/docs/pl/docs/nf4_science/rnaseq/00_orientation.md b/docs/pl/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..98aebcf4bd --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientacja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Środowisko szkoleniowe zawiera wszystkie oprogramowanie, kod i dane niezbędne do pracy z tym kursem szkoleniowym, więc nie musisz niczego instalować samodzielnie. +Jednak potrzebujesz (darmowego) konta, aby się zalogować, i powinieneś poświęcić kilka minut na zapoznanie się z interfejsem. + +Jeśli jeszcze tego nie zrobiłeś, ukończ mini-kurs [Konfiguracja środowiska](../../envsetup/) przed dalszym postępowaniem. + +## Dostarczone materiały + +W trakcie tego kursu szkoleniowego będziemy pracować w katalogu `nf4-science/rnaseq/`, do którego należy przejść po otwarciu obszaru roboczego szkolenia. +Ten katalog zawiera wszystkie pliki kodu, dane testowe i pliki pomocnicze, których będziesz potrzebować. + +Możesz swobodnie eksplorować zawartość tego katalogu; najłatwiejszym sposobem jest użycie eksploratora plików po lewej stronie obszaru roboczego szkolenia w interfejsie VSCode. +Alternatywnie możesz użyć polecenia `tree`. +W trakcie kursu używamy wyjścia `tree` do przedstawienia struktury katalogów i zawartości w czytelnej formie, czasami z drobnymi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu: + +```bash +tree . -L 3 +``` + +??? success "Zawartość katalogu" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note "Uwaga" + + Nie martw się, jeśli wydaje się to dużo; przejdziemy przez odpowiednie elementy na każdym etapie kursu. + To ma jedynie na celu dać Ci przegląd. + +**Oto podsumowanie tego, co powinieneś wiedzieć, aby zacząć:** + +- **Plik `rnaseq.nf`** to zarys skryptu workflow, który będziemy rozwijać. + +- **Plik `nextflow.config`** to plik konfiguracyjny, który ustawia minimalne właściwości środowiska. Na razie możesz go zignorować. + +- **Katalog `data`** zawiera dane wejściowe i powiązane zasoby: + + - _Genom referencyjny_ o nazwie `genome.fa` składający się z małego regionu ludzkiego chromosomu 20 (z hg19/b37). + - _Dane RNAseq_, które zostały ograniczone do małego regionu, aby zmniejszyć rozmiar plików, w katalogu `reads/`. + - _Pliki CSV_ zawierające identyfikatory i ścieżki przykładowych plików danych, do przetwarzania wsadowego. + +- **Katalog `solutions`** zawiera ukończone skrypty workflow i moduły, które są wynikiem każdego etapu kursu. + Mają one służyć jako punkt odniesienia do sprawdzenia Twojej pracy i rozwiązywania ewentualnych problemów. + Numer w nazwie pliku odpowiada etapowi odpowiedniej części kursu. + +!!!tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu opuścisz ten katalog, zawsze możesz uruchomić to polecenie, aby do niego wrócić: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Teraz, aby rozpocząć kurs, kliknij strzałkę w prawym dolnym rogu tej strony. diff --git a/docs/pl/docs/nf4_science/rnaseq/01_method.md b/docs/pl/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..c24e7896a0 --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Część 1: Przegląd metody i manualne testowanie + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Istnieje wiele prawidłowych metod przetwarzania i analizy danych bulk RNAseq. +W tym szkoleniu stosujemy metodę opisaną [tutaj](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) przez dr Simon Andrews i dr Laurę Biggins z [Babraham Institute](https://www.babraham.ac.uk/). + +Naszym celem jest opracowanie przepływu pracy, który implementuje następujące etapy przetwarzania: przeprowadzenie wstępnej kontroli jakości odczytów w próbce bulk RNAseq, usunięcie sekwencji adapterów z odczytów, dopasowanie odczytów do genomu referencyjnego oraz wygenerowanie kompleksowego raportu kontroli jakości (QC). + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** Przeprowadzenie QC na danych odczytów przed przycinaniem przy użyciu FastQC +- **TRIM_GALORE:** Usunięcie sekwencji adapterów i przeprowadzenie QC po przycięciu przy użyciu Trim Galore (łączy Cutadapt i FastQC) +- **HISAT2_ALIGN:** Dopasowanie odczytów do genomu referencyjnego przy użyciu Hisat2 +- **MULTIQC:** Wygenerowanie kompleksowego raportu QC przy użyciu MultiQC + +Jednak zanim przejdziemy do pisania jakiegokolwiek kodu przepływu pracy, wypróbujemy polecenia ręcznie na danych testowych. +Narzędzia, których potrzebujemy, nie są zainstalowane w środowisku GitHub Codespaces, więc użyjemy ich za pośrednictwem kontenerów (zobacz [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Uwaga" + + Upewnij się, że jesteś w katalogu `nf4-science/rnaseq`. Ostatnia część ścieżki wyświetlana po wpisaniu `pwd` powinna być `rnaseq`. + +--- + +## 1. Wstępne QC i usuwanie adapterów + +Pobierzemy obraz kontenera, który ma zainstalowane zarówno `fastqc`, jak i `trim_galore`, uruchomimy go interaktywnie i wykonamy polecenia przycinania oraz QC na jednym z przykładowych plików danych. + +### 1.1. Pobranie kontenera + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Otrzymasz następujący wynik w konsoli, gdy system pobiera obraz: + +??? success "Wynik polecenia" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Uruchomienie kontenera interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Wynik polecenia" + + ```console + + ``` +--> + +Twój prompt zmieni się na coś w rodzaju `(base) root@b645838b3314:/tmp#`, co oznacza, że jesteś teraz wewnątrz kontenera. + +Część `-v ./data:/data` polecenia umożliwi nam dostęp do zawartości katalogu `data/` z wnętrza kontenera. + +```bash +ls /data/reads +``` + +??? success "Wynik polecenia" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Uruchomienie pierwszego polecenia `fastqc` + +Uruchommy `fastqc`, aby zebrać metryki kontroli jakości danych odczytów. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Wynik polecenia" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Powinno to działać bardzo szybko. +Pliki wyjściowe znajdziesz w tym samym katalogu co oryginalne dane: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Wyjście" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Usunięcie sekwencji adapterów za pomocą `trim_galore` + +Teraz uruchommy `trim_galore`, który łączy Cutadapt i FastQC, aby usunąć sekwencje adapterów i zebrać metryki QC po przycięciu. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +Flaga `--fastqc` powoduje, że polecenie automatycznie uruchamia etap zbierania QC po zakończeniu przycinania. + +_Wynik jest bardzo obszerny, więc poniżej przedstawiono wersję skróconą._ + +??? success "Wynik polecenia" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Pliki wyjściowe znajdziesz w katalogu roboczym: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Wyjście" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Przeniesienie plików wyjściowych do systemu plików poza kontenerem + +Wszystko, co pozostanie wewnątrz kontenera, będzie niedostępne dla przyszłej pracy, więc przenieśmy te pliki do nowego katalogu. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Wyjście z kontenera + +```bash +exit +``` + +--- + +## 2. Dopasowanie odczytów do genomu referencyjnego + +Pobierzemy obraz kontenera, który ma zainstalowany `hisat2`, uruchomimy go interaktywnie i wykonamy polecenie dopasowania, aby dopasować dane RNAseq do genomu referencyjnego. + +### 2.1. Pobranie kontenera `hisat2` + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Wynik polecenia" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. Uruchomienie kontenera `hisat2` interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +Polecenie jest takie samo jak wcześniej, z odpowiednim URI kontenera. + +### 2.3. Utworzenie plików indeksu genomu Hisat2 + +Hisat2 wymaga, aby referencja genomu była dostarczona w bardzo konkretnym formacie i nie może po prostu korzystać z pliku FASTA `genome.fa`, który dostarczamy, więc skorzystamy z tej okazji, aby utworzyć odpowiednie zasoby. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +Wynik jest bardzo obszerny, więc poniżej przedstawiono wersję skróconą: + +<!-- TODO: switch to full output --> + +??? success "Wynik polecenia" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +To tworzy wiele plików indeksu genomu, które można znaleźć w katalogu roboczym. + +```bash +ls genome_index.* +``` + +```console title="Wyjście" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Użyjemy ich za chwilę, ale najpierw wygenerujmy skompresowany tarball z tymi plikami indeksu genomu; będziemy ich potrzebować później, a generowanie ich nie jest zazwyczaj czymś, co chcemy robić w ramach przepływu pracy. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +To zapisuje tarball `genome_index.tar.gz` zawierający pliki indeksu genomu w katalogu `data/` w naszym systemie plików, co przyda się w Części 2 tego szkolenia. + +### 2.4. Uruchomienie polecenia `hisat2` + +Teraz możemy uruchomić polecenie dopasowania, które wykonuje etap dopasowania za pomocą `hisat2`, a następnie przekazuje wynik do `samtools`, aby zapisać wyjście jako plik BAM. + +Wejściem danych odczytu jest plik `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz`, który wygenerowaliśmy za pomocą `trim_galore` w poprzednim kroku. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Wynik polecenia" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +To działa niemal natychmiast, ponieważ jest to bardzo mały plik testowy. +W rzeczywistej skali może to potrwać znacznie dłużej. + +Ponownie pliki wyjściowe znajdziesz w katalogu roboczym: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Wyjście" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Przeniesienie plików wyjściowych do systemu plików poza kontenerem + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Wyjście z kontenera + +```bash +exit +``` + +--- + +## 3. Wygenerowanie kompleksowego raportu QC + +Pobierzemy obraz kontenera, który ma zainstalowany `multiqc`, uruchomimy go interaktywnie i wykonamy polecenie generowania raportu na plikach raportów FastQC przed i po. + +### 3.1. Pobranie kontenera `multiqc` + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Wynik polecenia" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. Uruchomienie kontenera `multiqc` interaktywnie + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. Uruchomienie polecenia `multiqc` + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Wynik polecenia" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC jest w stanie przeszukiwać katalogi w poszukiwaniu kompatybilnych raportów QC i zagreguje wszystko, co znajdzie. + +Tutaj widzimy, że narzędzie znalazło wszystkie trzy raporty QC, które wygenerowaliśmy: wstępny QC wykonany za pomocą `fastqc`, raport po przycięciu z `cutadapt` (wykonany za pomocą `trim_galore`) oraz QC po dopasowaniu wygenerowany przez `hisat2`. + +Pliki wyjściowe są ponownie w katalogu roboczym: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Wyjście" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Przeniesienie plików wyjściowych do systemu plików poza kontenerem + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Wyjście z kontenera + +```bash +exit +``` + +--- + +### Podsumowanie + +Przetestowałeś wszystkie poszczególne polecenia interaktywnie w odpowiednich kontenerach. + +### Co dalej? + +Dowiedz się, jak opakować te same polecenia w wieloetapowy przepływ pracy, który używa kontenerów do wykonywania zadań. diff --git a/docs/pl/docs/nf4_science/rnaseq/02_single-sample.md b/docs/pl/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..9915d7038e --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Część 2: Implementacja dla pojedynczej próbki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej części kursu napiszemy najprostszy możliwy workflow, który obejmie wszystkie polecenia uruchomione w Części 1, aby zautomatyzować ich wykonywanie, i będziemy dążyć do przetwarzania jednej próbki na raz. + +Zrobimy to w trzech etapach: + +1. Napisanie jednoetapowego workflow, który uruchamia początkowy krok kontroli jakości +2. Dodanie przycinania adapterów i kontroli jakości po przycięciu +3. Dodanie dopasowania do genomu referencyjnego + +!!! warning "Wymaganie wstępne" + + Musisz przejść przez Część 1 kursu przed rozpoczęciem tej lekcji. + W szczególności, praca przez sekcje 2.1-3 tworzy plik indeksu genomu (`data/genome_index.tar.gz`) wymagany do kroku dopasowania w tej lekcji. + +--- + +## 1. Napisanie jednoetapowego workflow, który uruchamia początkową kontrolę jakości + +Zacznijmy od napisania prostego workflow, który uruchamia narzędzie FastQC na pliku FASTQ zawierającym odczyty RNAseq pojedynczego końca. + +Udostępniamy plik workflow, `rnaseq.nf`, który określa główne części workflow. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Instrukcje INCLUDE modułów + +/* + * Parametry pipeline + */ + +// Główne wejście + +workflow { + + // Utwórz kanał wejściowy + + // Wywołaj procesy + +} +``` + +Pamiętaj, że ten kod workflow jest poprawny, ale nie jest funkcjonalny; jego celem jest jedynie służenie jako szkielet, którego użyjesz do napisania rzeczywistego workflow. + +### 1.1. Utworzenie katalogu do przechowywania modułów + +Utworzymy samodzielne moduły dla każdego procesu, aby ułatwić zarządzanie nimi i ich ponowne wykorzystanie, więc stwórzmy katalog do ich przechowywania. + +```bash +mkdir modules +``` + +### 1.2. Utworzenie modułu dla procesu zbierania metryk kontroli jakości + +Utwórzmy plik modułu o nazwie `modules/fastqc.nf` do przechowywania procesu `FASTQC`: + +```bash +touch modules/fastqc.nf +``` + +Otwórz plik w edytorze kodu i skopiuj do niego następujący kod: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Powinieneś rozpoznać wszystkie elementy z tego, czego nauczyłeś się w Części 1 i Części 2 tej serii szkoleń; jedyną godną uwagi zmianą jest to, że tym razem używamy `mode: symlink` dla dyrektywy `publishDir` i używamy parametru do zdefiniowania `publishDir`. + +!!! note "Uwaga" + + Mimo że pliki danych, których tutaj używamy, są bardzo małe, w genomice mogą być bardzo duże. W celach demonstracyjnych w środowisku szkoleniowym używamy trybu publikowania 'symlink', aby uniknąć niepotrzebnych kopii plików. Nie powinieneś tego robić w swoich finalnych workflow, ponieważ stracisz wyniki podczas czyszczenia katalogu `work`. + +### 1.3. Importowanie modułu do pliku workflow + +Dodaj instrukcję `include { FASTQC } from './modules/fastqc.nf'` do pliku `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Instrukcje INCLUDE modułów +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Dodanie deklaracji wejścia + +Zadeklaruj parametr wejściowy z wartością domyślną: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Główne wejście + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Utworzenie kanału wejściowego w bloku workflow + +Użyj podstawowej fabryki kanałów `.fromPath()`, aby utworzyć kanał wejściowy: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Utwórz kanał wejściowy ze ścieżki pliku + read_ch = channel.fromPath(params.reads) + + // Wywołaj procesy + +} +``` + +### 1.6. Wywołanie procesu `FASTQC` na kanale wejściowym + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Utwórz kanał wejściowy ze ścieżki pliku + read_ch = channel.fromPath(params.reads) + + // Początkowa kontrola jakości + FASTQC(read_ch) + +} +``` + +### 1.7. Uruchomienie workflow w celu przetestowania, czy działa + +Moglibyśmy użyć parametru `--reads`, aby określić wejście z linii poleceń, ale podczas programowania możemy być leniwi i po prostu użyć domyślnej wartości testowej, którą ustawiliśmy. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Powinno to działać bardzo szybko, jeśli pracowałeś przez Część 1 i już pobrałeś kontener. +Jeśli ją pominąłeś, Nextflow pobierze kontener za Ciebie; nie musisz nic robić, aby to się stało, ale możesz potrzebować poczekać do minuty. + +Możesz znaleźć wyjścia w `results/fastqc`, jak określono w procesie `FASTQC` przez dyrektywę `publishDir`. + +```bash +ls results/fastqc +``` + +```console title="Wyjście" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Dodanie przycinania adapterów i kontroli jakości po przycięciu + +Zamierzamy użyć wrappera Trim_Galore, który łączy Cutadapt do samego przycinania i FastQC do kontroli jakości po przycięciu. + +### 2.1. Utworzenie modułu dla procesu przycinania i kontroli jakości + +Utwórzmy plik modułu o nazwie `modules/trim_galore.nf` do przechowywania procesu `TRIM_GALORE`: + +```bash +touch modules/trim_galore.nf +``` + +Otwórz plik w edytorze kodu i skopiuj do niego następujący kod: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Importowanie modułu do pliku workflow + +Dodaj instrukcję `include { TRIM_GALORE } from './modules/trim_galore.nf'` do pliku `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Instrukcje INCLUDE modułów +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Wywołanie procesu na kanale wejściowym + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Utwórz kanał wejściowy ze ścieżki pliku + read_ch = channel.fromPath(params.reads) + + // Początkowa kontrola jakości + FASTQC(read_ch) + + // Przycinanie adapterów i kontrola jakości po przycięciu + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Uruchomienie workflow w celu przetestowania, czy działa + +```bash +nextflow run rnaseq.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +To również powinno działać bardzo szybko, ponieważ uruchamiamy na tak małym pliku wejściowym. + +Możesz znaleźć wyjścia w `results/trimming`, jak określono w procesie `TRIM_GALORE` przez dyrektywę `publishDir`. + +```bash +ls results/trimming +``` + +```console title="Wyjście" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Dopasowanie odczytów do genomu referencyjnego + +Na koniec możemy uruchomić krok dopasowania genomu przy użyciu Hisat2, który również wyemituje metryki kontroli jakości w stylu FastQC. + +### 3.1. Utworzenie modułu dla procesu HiSat2 + +Utwórzmy plik modułu o nazwie `modules/hisat2_align.nf` do przechowywania procesu `HISAT2_ALIGN`: + +```bash +touch modules/hisat2_align.nf +``` + +Otwórz plik w edytorze kodu i skopiuj do niego następujący kod: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Importowanie modułu do pliku workflow + +Dodaj instrukcję `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` do pliku `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Instrukcje INCLUDE modułów +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Dodanie deklaracji parametru do dostarczenia indeksu genomu + +Zadeklaruj parametr wejściowy z wartością domyślną: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Główne wejście + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Archiwum genomu referencyjnego + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Wywołanie procesu `HISAT2_ALIGN` na przyciętych odczytach wyjściowych z `TRIM_GALORE` + +Przycięte odczyty znajdują się w kanale `TRIM_GALORE.out.trimmed_reads` wyjściowym z poprzedniego kroku. + +Dodatkowo używamy `file (params.hisat2_index_zip)`, aby dostarczyć narzędziu Hisat2 spakowany archiwum tar indeksu genomu. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Utwórz kanał wejściowy ze ścieżki pliku + read_ch = channel.fromPath(params.reads) + + // Początkowa kontrola jakości + FASTQC(read_ch) + + // Przycinanie adapterów i kontrola jakości po przycięciu + TRIM_GALORE(read_ch) + + // Dopasowanie do genomu referencyjnego + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Uruchomienie workflow w celu przetestowania, czy działa + +```bash +nextflow run rnaseq.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Możesz znaleźć wyjścia w `results/align`, jak określono w procesie `HISAT2_ALIGN` przez dyrektywę `publishDir`. + +```bash +ls results/align +``` + +```console title="Wyjście" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +To kończy podstawowe przetwarzanie, które musimy zastosować do każdej próbki. + +_Dodamy agregację raportów MultiQC w Części 2, po tym, jak sprawimy, że workflow będzie akceptował wiele próbek naraz._ + +--- + +### Podsumowanie + +Wiesz, jak opakować wszystkie podstawowe kroki do przetwarzania próbek RNAseq pojedynczego końca indywidualnie. + +### Co dalej? + +Dowiedz się, jak zmodyfikować workflow, aby przetwarzać wiele próbek równolegle, agregować raporty kontroli jakości we wszystkich krokach dla wszystkich próbek i umożliwić uruchamianie workflow na danych RNAseq sparowanych końców. diff --git a/docs/pl/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/pl/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..4ba8def085 --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Część 3: Implementacja dla wielu próbek z danymi paired-end + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W tej ostatniej części kursu zamienimy nasz prosty przepływ pracy w potężne narzędzie do automatyzacji wsadowej, które obsłuży dowolną liczbę próbek. +Przy okazji przełączymy go również na obsługę danych paired-end, które są bardziej powszechne w nowszych badaniach. + +Zrobimy to w trzech etapach: + +1. Dostosujemy przepływ pracy do akceptowania wielu próbek wejściowych i zrównoleglenia wykonania +2. Dodamy kompleksowe generowanie raportów QC +3. Przełączymy się na dane RNAseq paired-end + +--- + +## 1. Dostosowanie przepływu pracy do akceptowania wielu próbek wejściowych i zrównoleglenia wykonania + +Musimy zmienić sposób zarządzania danymi wejściowymi. + +### 1.1. Zmiana głównego wejścia na plik CSV ze ścieżkami plików zamiast pojedynczego pliku + +W katalogu `data/` udostępniamy plik CSV zawierający identyfikatory próbek oraz ścieżki do plików FASTQ. +Ten plik CSV zawiera linię nagłówkową. +Zwróć uwagę, że ścieżki do plików FASTQ są ścieżkami bezwzględnymi. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Zmieńmy nazwę głównego parametru wejściowego na `input_csv` i zmieńmy wartość domyślną na ścieżkę do pliku `single-end.csv`. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Główne dane wejściowe + input_csv: Path = "data/single-end.csv" + + // Archiwum genomu referencyjnego + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Aktualizacja fabryki kanału wejściowego w celu obsługi pliku CSV jako danych wejściowych + +Chcemy wczytać zawartość pliku do kanału zamiast samej ścieżki pliku, więc używamy operatora `.splitCsv()` do parsowania formatu CSV, a następnie operatora `.map()` do pobrania konkretnej informacji, której potrzebujemy (ścieżki do pliku FASTQ). + +```groovy title="rnaseq.nf" linenums="16" + // Utwórz kanał wejściowy z zawartości pliku CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Uruchomienie przepływu pracy w celu sprawdzenia, czy działa + +```bash +nextflow run rnaseq.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Tym razem widzimy, że każdy krok jest uruchamiany 6 razy, na każdym z 6 dostarczonych plików danych. + +To wszystko, czego potrzeba, aby przepływ pracy uruchamiał się na wielu plikach! +Nextflow obsługuje całą równoległość za nas. + +--- + +## 2. Agregacja metryk QC wstępnego przetwarzania w pojedynczy raport MultiQC + +To wszystko generuje wiele raportów QC i nie chcemy musieć przeglądać poszczególnych raportów. +To idealny moment, aby dodać krok agregacji raportów MultiQC! + +### 2.1. Utworzenie modułu dla procesu agregacji QC + +Stwórzmy plik modułu o nazwie `modules/multiqc.nf`, który będzie zawierał proces `MULTIQC`: + +```bash +touch modules/multiqc.nf +``` + +Otwórz plik w edytorze kodu i skopiuj do niego następujący kod: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Zaimportowanie modułu do pliku przepływu pracy + +Dodaj instrukcję `include { MULTIQC } from './modules/multiqc.nf'` do pliku `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Instrukcje INCLUDE modułów +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Dodanie parametru `report_id` z rozsądną wartością domyślną + +```groovy title="rnaseq.nf" linenums="9" +params { + // Główne dane wejściowe + input_csv: Path = "data/single-end.csv" + + // Archiwum genomu referencyjnego + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID raportu + report_id: String = "all_single-end" +} +``` + +### 2.4. Wywołanie procesu na wyjściach poprzednich kroków + +Musimy przekazać procesowi `MULTIQC` wszystkie wyjścia związane z QC z poprzednich kroków. + +W tym celu użyjemy operatora `.mix()`, który agreguje wiele kanałów w jeden. + +Gdybyśmy mieli cztery procesy nazwane A, B, C i D, każdy z prostym kanałem `.out`, składnia wyglądałaby następująco: `A.out.mix( B.out, C.out, D.out )`. Jak widać, stosujesz go do pierwszego z kanałów, które chcesz połączyć (nie ma znaczenia którego) i po prostu dodajesz wszystkie pozostałe, oddzielone przecinkami, w nawiasie, który następuje. + +W przypadku naszego przepływu pracy mamy następujące wyjścia do agregacji: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Więc przykładowa składnia staje się: + +```groovy title="Zastosowanie .mix() w wywołaniu MULTIQC" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +To zbierze raporty QC dla każdej próbki. +Ale ponieważ chcemy je zagregować dla wszystkich próbek, musimy dodać operator `collect()`, aby zebrać raporty dla wszystkich próbek w jedno wywołanie `MULTIQC`. +Musimy również przekazać parametr `report_id`. + +Daje nam to następujący kod: + +```groovy title="Ukończone wywołanie MULTIQC" linenums="33" + // Generowanie kompleksowego raportu QC + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +W kontekście pełnego bloku przepływu pracy wygląda to tak: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Utwórz kanał wejściowy z zawartości pliku CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// Początkowa kontrola jakości + FASTQC(read_ch) + + // Przycinanie adapterów i kontrola jakości po przycięciu + TRIM_GALORE(read_ch) + + // Dopasowanie do genomu referencyjnego + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Generowanie kompleksowego raportu QC + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Uruchomienie przepływu pracy w celu sprawdzenia, czy działa + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Tym razem widzimy pojedyncze wywołanie MULTIQC dodane po zbuforowanych wywołaniach procesów: + +Wyniki możesz znaleźć w katalogu `results/trimming`, jak określono w procesie `TRIM_GALORE` przez dyrektywę `publishDir`. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Wyjście" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Ten ostatni plik `all_single-end.html` to pełny zagregowany raport, wygodnie zapakowany w jeden łatwy do przeglądania plik HTML. + +--- + +## 3. Umożliwienie przetwarzania danych RNAseq paired-end + +Obecnie nasz przepływ pracy obsługuje tylko dane RNAseq single-end. +Coraz częściej spotyka się dane RNAseq paired-end, więc chcemy móc je obsługiwać. + +Uczynienie przepływu pracy całkowicie niezależnym od typu danych wymagałoby użycia nieco bardziej zaawansowanych funkcji języka Nextflow, więc nie zrobimy tego tutaj, ale możemy stworzyć wersję do przetwarzania paired-end, aby zademonstrować, co należy dostosować. + +### 3.1. Utworzenie kopii przepływu pracy o nazwie `rnaseq_pe.nf` + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Modyfikacja domyślnej wartości `input_csv`, aby wskazywała na dane paired-end + +Udostępniamy drugi plik CSV zawierający identyfikatory próbek oraz ścieżki do sparowanych plików FASTQ w katalogu `data/` + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Zmieńmy wartość domyślną `input_csv` na ścieżkę do pliku `paired-end.csv`. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Główne dane wejściowe + input_csv: Path = "data/paired-end.csv" + + // Archiwum genomu referencyjnego + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID raportu + report_id: String = "all_single-end" +} +``` + +### 3.3. Aktualizacja fabryki kanału + +Musimy teraz powiedzieć operatorowi `.map()`, aby pobierał obie ścieżki do plików FASTQ. + +Więc `row -> file(row.fastq_path)` staje się `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Utwórz kanał wejściowy z zawartości pliku CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Utworzenie wersji paired-end procesu FASTQC + +Stwórzmy kopię modułu, abyśmy mieli obie wersje pod ręką. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Otwórz nowy plik modułu `fastqc_pe.nf` w edytorze kodu i wprowadź następujące zmiany: + +- Zmień `fastqc $reads` na `fastqc ${reads}` w bloku `script` (linia 17), aby wejście `reads` zostało rozpakowane, ponieważ jest teraz krotką dwóch ścieżek zamiast pojedynczej ścieżki. +- Zastąp `${reads.simpleName}` symbolem wieloznacznym (`*`), aby uniknąć konieczności indywidualnego obsługiwania plików wyjściowych. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Technicznie uogólnia to proces `FASTQC` w sposób, który umożliwia mu obsługę zarówno danych RNAseq single-end, jak i paired-end. + +Na koniec zaktualizuj instrukcję importu modułu, aby używała wersji paired-end modułu. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Utworzenie wersji paired-end procesu TRIM_GALORE + +Stwórz kopię modułu, abyśmy mieli obie wersje pod ręką. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Otwórz nowy plik modułu `trim_galore_pe.nf` w edytorze kodu i wprowadź następujące zmiany: + +- Zmień deklarację wejścia z `path reads` na `tuple path(read1), path(read2)` +- Zaktualizuj polecenie w bloku `script`, zastępując `$reads` przez `--paired ${read1} ${read2}` +- Zaktualizuj deklaracje wyjścia, aby odzwierciedlały dodane pliki i różne konwencje nazewnictwa, używając symboli wieloznacznych, aby uniknąć konieczności wymieniania wszystkiego. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Na koniec zaktualizuj instrukcję importu modułu, aby używała wersji paired-end modułu. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Aktualizacja wywołania procesu MULTIQC, aby oczekiwał dwóch raportów z TRIM_GALORE + +Proces `TRIM_GALORE` generuje teraz dodatkowy kanał wyjściowy, więc musimy przekazać go do MultiQC. + +Zastąp `TRIM_GALORE.out.fastqc_reports,` przez `TRIM_GALORE.out.fastqc_reports_1,` plus `TRIM_GALORE.out.fastqc_reports_2,`: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Generowanie kompleksowego raportu QC + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Skoro już przy MultiQC, zaktualizujmy również wartość domyślną parametru `report_id` z `"all_single-end"` na `"all_paired-end"`. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Główne dane wejściowe + input_csv: Path = "data/paired-end.csv" + + // Archiwum genomu referencyjnego + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID raportu + report_id: String = "all_paired-end" +} +``` + +### 3.7. Utworzenie wersji paired-end procesu HISAT2_ALIGN + +Stwórz kopię modułu, abyśmy mieli obie wersje pod ręką. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Otwórz nowy plik modułu `hisat2_align_pe.nf` w edytorze kodu i wprowadź następujące zmiany: + +- Zmień deklarację wejścia z `path reads` na `tuple path(read1), path(read2)` +- Zaktualizuj polecenie w bloku `script`, zastępując `-U $reads` przez `-1 ${read1} -2 ${read2}` +- Zastąp wszystkie wystąpienia `${reads.simpleName}` przez `${read1.simpleName}` w poleceniu w bloku `script`, a także w deklaracjach wyjścia. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Na koniec zaktualizuj instrukcję importu modułu, aby używała wersji paired-end modułu. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Uruchomienie przepływu pracy w celu sprawdzenia, czy działa + +Nie używamy `-resume`, ponieważ to nie zostałoby zbuforowane, a jest dwa razy więcej danych do przetworzenia niż wcześniej, ale i tak powinno zakończyć się w mniej niż minutę. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +I to wszystko! Teraz mamy dwie nieco rozbieżne wersje naszego przepływu pracy, jedną dla danych single-end i jedną dla danych paired-end. +Następnym logicznym krokiem byłoby sprawienie, aby przepływ pracy akceptował którykolwiek typ danych w locie, co wykracza poza zakres tego kursu, ale możemy się tym zająć w kontynuacji. + +--- + +### Podsumowanie + +Wiesz, jak dostosować przepływ pracy dla pojedynczej próbki, aby zrównoleglić przetwarzanie wielu próbek, wygenerować kompleksowy raport QC i dostosować przepływ pracy do używania danych paired-end, jeśli jest to potrzebne. + +### Co dalej? + +Gratulacje, ukończyłeś mini-kurs Nextflow dla RNAseq! Świętuj swój sukces i weź zasłużoną przerwę! + +Następnie prosimy o wypełnienie bardzo krótkiej ankiety dotyczącej Twoich doświadczeń z tym kursem szkoleniowym, a następnie przekierujemy Cię na stronę z linkami do dalszych materiałów szkoleniowych i pomocnych odnośników. diff --git a/docs/pl/docs/nf4_science/rnaseq/index.md b/docs/pl/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..d6e0c1fa2c --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: Nextflow dla RNAseq +hide: + - toc +--- + +# Nextflow dla RNAseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ten kurs szkoleniowy jest przeznaczony dla badaczy w dziedzinie transkryptomiki i pokrewnych obszarów, którzy są zainteresowani tworzeniem lub dostosowywaniem potoków analizy danych. +Opiera się on na szkoleniu dla początkujących [Hello Nextflow](../../hello_nextflow/) i demonstruje, jak używać Nextflow w konkretnym kontekście analizy masowego RNAseq. + +W szczególności, ten kurs pokazuje, jak zaimplementować prosty potok przetwarzania masowego RNAseq do przycinania sekwencji adapterów, dopasowywania odczytów do genomu referencyjnego i przeprowadzania kontroli jakości (QC) na kilku etapach. + +Zacznijmy! Kliknij przycisk "Open in GitHub Codespaces" poniżej, aby uruchomić środowisko szkoleniowe (najlepiej w osobnej karcie), a następnie kontynuuj czytanie podczas ładowania. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Cele szkoleniowe + +Przechodząc przez ten kurs, nauczysz się, jak zastosować podstawowe koncepcje i narzędzia Nextflow do typowego przypadku użycia RNAseq. + +Pod koniec tego warsztatu będziesz w stanie: + +- Napisać liniowy workflow do zastosowania podstawowych metod przetwarzania i QC dla RNAseq +- Odpowiednio obsługiwać pliki specyficzne dla domeny, takie jak FASTQ i zasoby genomu referencyjnego +- Obsługiwać dane sekwencjonowania jednoniciowego i dwuniciowego +- Wykorzystać paradygmat przepływu danych Nextflow do zrównoleglenia przetwarzania RNAseq na poziomie próbek +- Agregować raporty QC z wielu etapów i próbek przy użyciu odpowiednich operatorów kanałów + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Wymagania wstępne + +Kurs zakłada minimalną znajomość następujących zagadnień: + +- Narzędzia i formaty plików powszechnie używane w tej dziedzinie naukowej +- Doświadczenie z linią poleceń +- Podstawowe koncepcje i narzędzia Nextflow omówione w szkoleniu dla początkujących [Hello Nextflow](../../hello_nextflow/) + +Aby zapoznać się z wymaganiami technicznymi i konfiguracją środowiska, zobacz mini-kurs [Environment Setup](../../envsetup/). diff --git a/docs/pl/docs/nf4_science/rnaseq/next_steps.md b/docs/pl/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..5d2042fe28 --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Następne kroki + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Jeszcze raz gratulujemy ukończenia kursu szkoleniowego Nextflow dla RNAseq i dziękujemy za wypełnienie naszej ankiety! + +--- + +## 1. 3 najlepsze sposoby na rozwinięcie umiejętności Nextflow + +Oto nasze trzy najważniejsze rekomendacje dotyczące kolejnych kroków na podstawie kursu, który właśnie ukończyłeś. + +### 1.1. Zastosuj Nextflow do innych przypadków użycia w analizie naukowej + +**Sprawdź stronę [Nextflow for Science](../nf4_science/index.md)**, aby znaleźć listę innych krótkich, samodzielnych kursów, które pokazują, jak zastosować podstawowe koncepcje i mechanizmy przedstawione w Hello Nextflow do typowych przypadków użycia w analizie naukowej. + +Jeśli nie widzisz swojej dziedziny reprezentowanej przez odpowiedni przypadek użycia, daj nam znać na [forum społeczności](https://community.seqera.io/), abyśmy mogli dodać ją do naszej listy rozwojowej. + +### 1.2. Rozpocznij pracę z nf-core + +**[nf-core](https://nf-co.re/)** to światowa inicjatywa współpracy mająca na celu opracowanie znormalizowanych pipeline'ów open-source dla szerokiego zakresu zastosowań w badaniach naukowych. +Projekt obejmuje [ponad 100 pipeline'ów](https://nf-co.re/pipelines/) dostępnych do użycia od razu oraz [znacznie ponad 1400 modułów procesów](https://nf-co.re/modules/), które można zintegrować z własnymi projektami, a także bogaty zestaw narzędzi deweloperskich. + +Kurs szkoleniowy **[Hello nf-core](../../hello_nf-core/index.md)** wprowadzi Cię w pipeline'y kuratorowane przez społeczność nf-core oraz framework deweloperski, zaprojektowany, aby pomóc Ci pisać powtarzalne, skalowalne i znormalizowane workflow. Nauczysz się, jak używać istniejących pipeline'ów nf-core, przyczyniać się do ich rozwoju, a nawet rozpocząć budowanie własnych, wspieranych przez najlepsze praktyki i prężną społeczność. Jeśli jesteś gotowy, aby zastosować swoje umiejętności Nextflow w rzeczywistych projektach, to idealny następny krok. + +### 1.3. Opanuj bardziej zaawansowane funkcje Nextflow + +W kursach Hello celowo utrzymujemy niski poziom złożoności technicznej, aby nie przeciążać Cię informacjami, które nie są potrzebne do rozpoczęcia pracy z Nextflow. +W miarę postępów w pracy będziesz chciał nauczyć się, jak używać pełnego zestawu funkcji i mocy Nextflow. + +W tym celu obecnie pracujemy nad **kolekcją [Side Quests](../side_quests/index.md)**, które mają być krótkimi, samodzielnymi kursami dogłębnie omawiającymi konkretne tematy, takie jak testowanie i obsługa metadanych. + +--- + +## 2. Sprawdź Seqera Platform + +**[Seqera Platform](https://seqera.io/) to najlepszy sposób na uruchamianie Nextflow w praktyce.** + +Jest to platforma w chmurze opracowana przez twórców Nextflow, którą możesz połączyć z własną infrastrukturą obliczeniową (lokalną, HPC lub chmurową), aby znacznie ułatwić uruchamianie i zarządzanie workflow, a także zarządzać danymi i przeprowadzać analizy interaktywnie w środowisku chmurowym. + +Warstwa darmowa (Free Tier) jest dostępna do bezpłatnego użytku dla wszystkich (z limitami użytkowania). +Uprawnieni pracownicy akademiccy mogą uzyskać bezpłatny dostęp na poziomie Pro (bez ograniczeń użytkowania) poprzez [Program Akademicki](https://seqera.io/academic/program/). + +Zapoznaj się z [tutorialami Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase), aby sprawdzić, czy może być to dla Ciebie przydatne. + +--- + +### To wszystko na razie! + +**Powodzenia w Twojej podróży z Nextflow i nie wahaj się dać nam znać na [forum społeczności](https://community.seqera.io/), co jeszcze moglibyśmy zrobić, aby pomóc.** diff --git a/docs/pl/docs/nf4_science/rnaseq/survey.md b/docs/pl/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..7fb56e5a8d --- /dev/null +++ b/docs/pl/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Ankieta zwrotna + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Zanim przejdziesz dalej, prosimy o wypełnienie krótkiej 5-pytaniowej ankiety, aby ocenić szkolenie, podzielić się swoimi uwagami na temat swoich doświadczeń i dać nam znać, co jeszcze możemy zrobić, aby pomóc Ci w Twojej podróży z Nextflow. + +Wypełnienie ankiety zajmie Ci mniej niż minutę. Dziękujemy za pomoc w ulepszaniu naszych materiałów szkoleniowych dla wszystkich! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pl/docs/side_quests/README.md b/docs/pl/docs/side_quests/README.md new file mode 100644 index 0000000000..ad3561936b --- /dev/null +++ b/docs/pl/docs/side_quests/README.md @@ -0,0 +1 @@ +To jest zastępczy tekst dla przyszłych Side Quests (pogłębionych szkoleń). Dokumenty znajdujące się tutaj są szkicami opartymi na treściach pochodzących z innych źródeł. diff --git a/docs/pl/docs/side_quests/debugging.md b/docs/pl/docs/side_quests/debugging.md new file mode 100644 index 0000000000..42a2229496 --- /dev/null +++ b/docs/pl/docs/side_quests/debugging.md @@ -0,0 +1,1552 @@ +# Debugowanie Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Debugowanie to kluczowa umiejętność, która może zaoszczędzić Ci godzin frustracji i pomóc Ci stać się bardziej efektywnym programistą Nextflow. Przez całą swoją karierę, szczególnie na początku, będziesz napotykać błędy podczas budowania i utrzymywania swoich workflow. Nauka systematycznych podejść do debugowania pomoże Ci szybko identyfikować i rozwiązywać problemy. + +### Cele nauczania + +W tym side queście zbadamy **systematyczne techniki debugowania** dla workflow Nextflow: + +- **Debugowanie błędów składni**: Efektywne wykorzystywanie funkcji IDE i komunikatów błędów Nextflow +- **Debugowanie kanałów**: Diagnozowanie problemów z przepływem danych i strukturą kanałów +- **Debugowanie procesów**: Badanie błędów wykonania i problemów z zasobami +- **Wbudowane narzędzia debugowania**: Wykorzystanie trybu podglądu, uruchamiania zaślepek i katalogów roboczych Nextflow +- **Systematyczne podejścia**: Czterofazowa metodologia efektywnego debugowania + +Pod koniec będziesz mieć solidną metodologię debugowania, która przekształca frustrujące komunikaty błędów w jasne mapy drogowe do rozwiązań. + +### Wymagania wstępne + +Przed podjęciem tego side questa powinieneś: + +- Ukończyć tutorial [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Swobodnie posługiwać się podstawowymi koncepcjami i mechanizmami Nextflow (procesy, kanały, operatory) + +**Opcjonalnie:** Zalecamy najpierw ukończenie side questa [IDE Features for Nextflow Development](./ide_features.md). +Obejmuje on kompleksowe omówienie funkcji IDE wspierających debugowanie (podświetlanie składni, wykrywanie błędów itp.), których będziemy tutaj intensywnie używać. + +--- + +## 0. Rozpoczęcie pracy + +#### Otwórz codespace szkoleniowy + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otwierasz środowisko szkoleniowe zgodnie z opisem w [Konfiguracja Środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki dla tego tutoriala. + +```bash +cd side-quests/debugging +``` + +Możesz ustawić VSCode, aby skupić się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz zestaw przykładowych workflow z różnymi typami błędów, których użyjemy do ćwiczeń: + +??? abstract "Zawartość katalogu" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Te pliki reprezentują typowe scenariusze debugowania, z którymi spotkasz się w rzeczywistym rozwoju. + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest uruchomienie każdego workflow, zidentyfikowanie błędu(ów) i naprawienie ich. + +Dla każdego błędnego workflow: + +1. **Uruchom workflow** i obserwuj błąd +2. **Przeanalizuj komunikat błędu**: co Nextflow Ci mówi? +3. **Zlokalizuj problem** w kodzie używając dostarczonych wskazówek +4. **Napraw błąd** i zweryfikuj, że Twoje rozwiązanie działa +5. **Zresetuj plik** przed przejściem do następnej sekcji (użyj `git checkout <filename>`) + +Ćwiczenia postępują od prostych błędów składni do bardziej subtelnych problemów w czasie wykonania. +Rozwiązania są omawiane bezpośrednio, ale spróbuj rozwiązać każdy samodzielnie przed czytaniem dalej. + +#### Lista kontrolna gotowości + +Myślisz, że jesteś gotowy, aby się zanurzyć? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace jest uruchomiony +- [ ] Ustawiłem odpowiednio mój katalog roboczy +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +--- + +## 1. Błędy składni + +Błędy składni to najczęstszy typ błędów, z którymi się spotkasz podczas pisania kodu Nextflow. Występują, gdy kod nie jest zgodny z oczekiwanymi regułami składni DSL Nextflow. Te błędy uniemożliwiają uruchomienie Twojego workflow w ogóle, więc ważne jest, aby nauczyć się je szybko identyfikować i naprawiać. + +### 1.1. Brakujące nawiasy klamrowe + +Jednym z najczęstszych błędów składni, a czasem jednym z bardziej złożonych do debugowania, są **brakujące lub niedopasowane nawiasy**. + +Zacznijmy od praktycznego przykładu. + +#### Uruchom pipeline + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Kluczowe elementy komunikatów błędów składni:** + +- **Plik i lokalizacja**: Pokazuje, który plik i linia/kolumna zawierają błąd (`bad_syntax.nf:24:1`) +- **Opis błędu**: Wyjaśnia, co parser znalazł, czego się nie spodziewał (`Unexpected input: '<EOF>'`) +- **Wskaźnik EOF**: Komunikat `<EOF>` (End Of File) wskazuje, że parser dotarł do końca pliku, wciąż oczekując więcej treści - klasyczny znak niedomkniętych nawiasów klamrowych + +#### Sprawdź kod + +Teraz przeanalizujmy `bad_syntax.nf`, aby zrozumieć, co powoduje błąd: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Brakujący nawias zamykający dla procesu + +workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) +} +``` + +Na potrzeby tego przykładu zostawiliśmy komentarz pokazujący, gdzie jest błąd. Rozszerzenie Nextflow VSCode powinno również dawać wskazówki o tym, co może być nie tak, podświetlając niedopasowany nawias na czerwono i zaznaczając przedwczesny koniec pliku: + +![Bad syntax](img/bad_syntax.png) + +**Strategia debugowania błędów nawiasów:** + +1. Użyj dopasowywania nawiasów VS Code (umieść kursor obok nawiasu) +2. Sprawdź panel Problemów dla komunikatów związanych z nawiasami +3. Upewnij się, że każdy otwierający `{` ma odpowiadający zamykający `}` + +#### Napraw kod + +Zastąp komentarz brakującym nawiasem zamykającym: + +=== "Po" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Dodaj brakujący nawias zamykający + + workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) + } + ``` + +=== "Przed" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Brakujący nawias zamykający dla procesu + + workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) + } + ``` + +#### Uruchom pipeline + +Teraz uruchom workflow ponownie, aby potwierdzić, że działa: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Używanie nieprawidłowych słów kluczowych lub dyrektyw procesów + +Kolejnym częstym błędem składni jest **nieprawidłowa definicja procesu**. Może to się zdarzyć, jeśli zapomnisz zdefiniować wymagane bloki lub użyjesz nieprawidłowych dyrektyw w definicji procesu. + +#### Uruchom pipeline + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Sprawdź kod + +Błąd wskazuje "Invalid process definition" i pokazuje kontekst wokół problemu. Patrząc na linie 3-7, możemy zobaczyć `inputs:` w linii 4, co jest problemem. Przeanalizujmy `invalid_process.nf`: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // BŁĄD: Powinno być 'input' nie 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) +} +``` + +Patrząc na linię 4 w kontekście błędu, możemy dostrzec problem: używamy `inputs` zamiast poprawnego `input`. Rozszerzenie Nextflow VSCode również oznaczy to: + +![Invalid process message](img/invalid_process_message.png) + +#### Napraw kod + +Zastąp nieprawidłowe słowo kluczowe poprawnym, odwołując się do [dokumentacji](https://www.nextflow.io/docs/latest/process.html#): + +=== "Po" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Naprawiono: Zmieniono 'inputs' na 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) + } + ``` + +=== "Przed" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // BŁĄD: Powinno być 'input' nie 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Utwórz kanał wejściowy + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Wywołaj proces z kanałem wejściowym + PROCESS_FILES(input_ch) + } + ``` + +#### Uruchom pipeline + +Teraz uruchom workflow ponownie, aby potwierdzić, że działa: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Używanie nieprawidłowych nazw zmiennych + +Nazwy zmiennych używane w blokach script muszą być prawidłowe, pochodzące albo z wejść, albo z kodu groovy wstawionego przed skryptem. Ale kiedy opanujesz złożoność na początku rozwoju pipeline, łatwo jest popełnić błędy w nazewnictwie zmiennych, a Nextflow szybko Ci o tym powie. + +#### Uruchom pipeline + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Błąd jest wykrywany podczas kompilacji i wskazuje bezpośrednio na niezdefiniowaną zmienną w linii 17, ze znakiem karetki wskazującym dokładnie, gdzie jest problem. + +#### Sprawdź kod + +Przeanalizujmy `no_such_var.nf`: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // BŁĄD: undefined_var nie zdefiniowana + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +Komunikat błędu wskazuje, że zmienna nie jest rozpoznawana w szablonie skryptu, i tak - powinieneś móc zobaczyć `${undefined_var}` użyte w bloku script, ale nie zdefiniowane nigdzie indziej. + +#### Napraw kod + +Jeśli otrzymasz błąd 'No such variable', możesz go naprawić, definiując zmienną (poprawiając nazwy zmiennych wejściowych lub edytując kod groovy przed skryptem), lub usuwając ją z bloku script, jeśli nie jest potrzebna: + +=== "Po" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Usunięto linię z undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Przed" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // BŁĄD: undefined_var nie zdefiniowana + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Uruchom pipeline + +Teraz uruchom workflow ponownie, aby potwierdzić, że działa: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Nieprawidłowe użycie zmiennych Bash + +Na początku w Nextflow może być trudno zrozumieć różnicę między zmiennymi Nextflow (Groovy) a Bash. Może to wygenerować inną formę błędu nieprawidłowej zmiennej, który pojawia się podczas próby użycia zmiennych w treści Bash bloku script. + +#### Uruchom pipeline + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Sprawdź kod + +Błąd wskazuje na linię 13, gdzie używane jest `${prefix}`. Przeanalizujmy `bad_bash_var.nf`, aby zobaczyć, co powoduje problem: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # BŁĄD: ${prefix} to składnia Groovy, nie Bash + """ +} +``` + +W tym przykładzie definiujemy zmienną `prefix` w Bash, ale w procesie Nextflow składnia `$` użyta do odwołania się do niej (`${prefix}`) jest interpretowana jako zmienna Groovy, a nie Bash. Zmienna nie istnieje w kontekście Groovy, więc otrzymujemy błąd 'no such variable'. + +#### Napraw kod + +Jeśli chcesz użyć zmiennej Bash, musisz zmienić znaczenie znaku dolara w ten sposób: + +=== "Po" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Naprawiono: Zmieniono znaczenie znaku dolara + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Przed" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # BŁĄD: ${prefix} to składnia Groovy, nie Bash + """ + } + ``` + +To mówi Nextflow, aby interpretować to jako zmienną Bash. + +#### Uruchom pipeline + +Teraz uruchom workflow ponownie, aby potwierdzić, że działa: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Zmienne Groovy vs Bash" + + Dla prostych manipulacji zmiennymi, takich jak konkatenacja ciągów lub operacje na prefiksach/sufiksach, zwykle bardziej czytelne jest użycie zmiennych Groovy w sekcji script niż zmiennych Bash w bloku script: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + To podejście unika konieczności zmiany znaczenia znaków dolara i sprawia, że kod jest łatwiejszy do czytania i utrzymania. + +### 1.5. Instrukcje poza blokiem workflow + +Rozszerzenie Nextflow VSCode podświetla problemy ze strukturą kodu, które spowodują błędy. Częstym przykładem jest definiowanie kanałów poza blokiem `workflow {}` - jest to teraz wymuszane jako błąd składni. + +#### Uruchom pipeline + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Komunikat błędu jasno wskazuje problem: instrukcje (takie jak definicje kanałów) nie mogą być mieszane z deklaracjami skryptu poza blokiem workflow lub process. + +#### Sprawdź kod + +Przeanalizujmy `badpractice_syntax.nf`, aby zobaczyć, co powoduje błąd: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // BŁĄD: Kanał zdefiniowany poza workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +Rozszerzenie VSCode również podświetli zmienną `input_ch` jako zdefiniowaną poza blokiem workflow: + +![Non-lethal syntax error](img/nonlethal.png) + +#### Napraw kod + +Przenieś definicję kanału do wnętrza bloku workflow: + +=== "Po" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Przeniesiono do wnętrza bloku workflow + PROCESS_FILES(input_ch) + } + ``` + +=== "Przed" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // BŁĄD: Kanał zdefiniowany poza workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Uruchom pipeline + +Uruchom workflow ponownie, aby potwierdzić, że poprawka działa: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Trzymaj swoje kanały wejściowe zdefiniowane w bloku workflow i ogólnie postępuj zgodnie z wszelkimi innymi zaleceniami, które daje rozszerzenie. + +### Wnioski + +Możesz systematycznie identyfikować i naprawiać błędy składni używając komunikatów błędów Nextflow i wizualnych wskaźników IDE. Typowe błędy składni obejmują brakujące nawiasy klamrowe, nieprawidłowe słowa kluczowe procesów, niezdefiniowane zmienne i niewłaściwe użycie zmiennych Bash vs. Nextflow. Rozszerzenie VSCode pomaga wychwycić wiele z nich przed uruchomieniem. Mając te umiejętności debugowania składni w swoim zestawie narzędzi, będziesz w stanie szybko rozwiązywać najczęstsze błędy składni Nextflow i przejść do rozwiązywania bardziej złożonych problemów w czasie wykonania. + +### Co dalej? + +Naucz się debugować bardziej złożone błędy struktury kanałów, które występują nawet gdy składnia jest poprawna. + +--- + +## 2. Błędy struktury kanałów + +Błędy struktury kanałów są bardziej subtelne niż błędy składni, ponieważ kod jest syntaktycznie poprawny, ale kształty danych nie pasują do tego, czego oczekują procesy. Nextflow spróbuje uruchomić pipeline, ale może stwierdzić, że liczba wejść nie pasuje do tego, czego oczekuje i zawieść. Te błędy zwykle pojawiają się tylko w czasie wykonania i wymagają zrozumienia danych przepływających przez Twój workflow. + +!!! tip "Debugowanie kanałów za pomocą `.view()`" + + W tej sekcji pamiętaj, że możesz używać operatora `.view()` do inspekcji zawartości kanału w dowolnym momencie w swoim workflow. Jest to jedno z najpotężniejszych narzędzi debugowania do zrozumienia problemów ze strukturą kanałów. Zbadamy tę technikę szczegółowo w sekcji 2.4, ale śmiało używaj jej podczas pracy nad przykładami. + + ```groovy + my_channel.view() // Pokazuje, co przepływa przez kanał + ``` + +### 2.1. Zła liczba kanałów wejściowych + +Ten błąd występuje, gdy przekazujesz inną liczbę kanałów niż oczekuje proces. + +#### Uruchom pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Sprawdź kod + +Komunikat błędu jasno stwierdza, że wywołanie oczekiwało 1 argumentu, ale otrzymało 2, i wskazuje na linię 23. Przeanalizujmy `bad_number_inputs.nf`: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Proces oczekuje tylko 1 wejścia + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Utwórz dwa oddzielne kanały + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // BŁĄD: Przekazywanie 2 kanałów, ale proces oczekuje tylko 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Powinieneś zobaczyć niedopasowane wywołanie `PROCESS_FILES`, dostarczające wiele kanałów wejściowych, gdy proces definiuje tylko jeden. Rozszerzenie VSCode również podkreśli wywołanie procesu na czerwono i dostarczy komunikat diagnostyczny przy najechaniu myszką: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Napraw kod + +Dla tego konkretnego przykładu proces oczekuje pojedynczego kanału i nie wymaga drugiego kanału, więc możemy to naprawić przekazując tylko kanał `samples_ch`: + +=== "Po" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Proces oczekuje tylko 1 wejścia + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Utwórz dwa oddzielne kanały + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Naprawiono: Przekaż tylko kanał, którego oczekuje proces + PROCESS_FILES(samples_ch) + } + ``` + +=== "Przed" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Proces oczekuje tylko 1 wejścia + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Utwórz dwa oddzielne kanały + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // BŁĄD: Przekazywanie 2 kanałów, ale proces oczekuje tylko 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Uruchom pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Częściej niż w tym przykładzie możesz dodać dodatkowe wejścia do procesu i zapomnieć odpowiednio zaktualizować wywołanie workflow, co może prowadzić do tego typu błędu. Na szczęście jest to jeden z łatwiejszych do zrozumienia i naprawienia błędów, ponieważ komunikat błędu jest dość jasny co do niedopasowania. + +### 2.2. Wyczerpanie kanału (Proces uruchamia się rzadziej niż oczekiwano) + +Niektóre błędy struktury kanałów są znacznie bardziej subtelne i nie powodują żadnych błędów. Prawdopodobnie najczęstszym z nich jest wyzwanie, przed którym stają nowi użytkownicy Nextflow w zrozumieniu, że kanały kolejkowe mogą zostać wyczerpane i zabraknie elementów, co oznacza, że workflow kończy się przedwcześnie. + +#### Uruchom pipeline + +```bash +nextflow run exhausted.nf +``` + +??? success "Wyjście polecenia" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Ten workflow kończy się bez błędu, ale przetwarza tylko jedną próbkę! + +#### Sprawdź kod + +Przeanalizujmy `exhausted.nf`, aby zobaczyć, czy to jest w porządku: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Zdefiniuj zmienne w kodzie Groovy przed skryptem + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Proces uruchamia się tylko raz zamiast trzy razy, ponieważ kanał `reference_ch` jest kanałem kolejkowym, który zostaje wyczerpany po pierwszym wykonaniu procesu. Gdy jeden kanał jest wyczerpany, cały proces zatrzymuje się, nawet jeśli inne kanały nadal mają elementy. + +To jest powszechny wzorzec, w którym masz pojedynczy plik referencyjny, który musi być ponownie używany dla wielu próbek. Rozwiązaniem jest przekształcenie kanału referencyjnego w kanał wartości, który może być używany w nieskończoność. + +#### Napraw kod + +Istnieje kilka sposobów rozwiązania tego problemu w zależności od liczby dotkniętych plików. + +**Opcja 1**: Masz pojedynczy plik referencyjny, którego wielokrotnie używasz. Możesz po prostu utworzyć typ kanału wartości, który może być używany wielokrotnie. Istnieją trzy sposoby na to: + +**1a** Użyj `channel.value()`: + +```groovy title="exhausted.nf (naprawiony - Opcja 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Kanał wartości może być ponownie używany + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Użyj operatora `first()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#first): + +```groovy title="exhausted.nf (naprawiony - Opcja 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Konwertuj na kanał wartości + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Użyj operatora `collect()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#collect): + +```groovy title="exhausted.nf (naprawiony - Opcja 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Konwertuj na kanał wartości + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Opcja 2**: W bardziej złożonych scenariuszach, być może gdzie masz wiele plików referencyjnych dla wszystkich próbek w kanale próbek, możesz użyć operatora `combine` do utworzenia nowego kanału, który łączy dwa kanały w krotki: + +```groovy title="exhausted.nf (naprawiony - Opcja 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Tworzy iloczyn kartezjański + + PROCESS_FILES(combined_ch) +} +``` + +Operator `.combine()` generuje iloczyn kartezjański dwóch kanałów, więc każdy element w `reference_ch` zostanie sparowany z każdym elementem w `input_ch`. To pozwala procesowi uruchamiać się dla każdej próbki, wciąż używając referencji. + +To wymaga dostosowania wejścia procesu. W naszym przykładzie początek definicji procesu musiałby zostać dostosowany w następujący sposób: + +```groovy title="exhausted.nf (naprawiony - Opcja 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +To podejście może nie być odpowiednie we wszystkich sytuacjach. + +#### Uruchom pipeline + +Wypróbuj jedno z powyższych poprawek i uruchom workflow ponownie: + +```bash +nextflow run exhausted.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Powinieneś teraz zobaczyć, że wszystkie trzy próbki są przetwarzane zamiast tylko jednej. + +### 2.3. Zła struktura zawartości kanału + +Gdy workflow osiągną pewien poziom złożoności, może być trudno śledzić wewnętrzne struktury każdego kanału, a ludzie często generują niedopasowania między tym, czego oczekuje proces, a tym, co faktycznie zawiera kanał. Jest to bardziej subtelne niż problem, który omówiliśmy wcześniej, gdzie liczba kanałów była nieprawidłowa. W tym przypadku możesz mieć poprawną liczbę kanałów wejściowych, ale wewnętrzna struktura jednego lub więcej z tych kanałów nie pasuje do tego, czego oczekuje proces. + +#### Uruchom pipeline + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Wyjście polecenia" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Sprawdź kod + +Nawiasy kwadratowe w komunikacie błędu dostarczają wskazówki - proces traktuje krotkę jako pojedynczą wartość, co nie jest tym, czego chcemy. Przeanalizujmy `bad_channel_shape.nf`: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Oczekuje pojedynczej wartości, dostaje krotkę + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Możesz zobaczyć, że generujemy kanał złożony z krotek: `['sample1', 'file1.txt']`, ale proces oczekuje pojedynczej wartości, `val sample_name`. Wykonane polecenie pokazuje, że proces próbuje utworzyć plik o nazwie `[sample3, file3.txt]_output.txt`, co nie jest zamierzonym wyjściem. + +#### Napraw kod + +Aby to naprawić, jeśli proces wymaga obu wejść, możemy dostosować proces, aby akceptował krotkę: + +=== "Opcja 1: Akceptuj krotkę w procesie" + + === "Po" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Naprawiono: Akceptuj krotkę + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Przed" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Oczekuje pojedynczej wartości, dostaje krotkę + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Opcja 2: Wydobądź pierwszy element" + + === "Po" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Naprawiono: Wydobądź pierwszy element + } + ``` + + === "Przed" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Uruchom pipeline + +Wybierz jedno z rozwiązań i uruchom ponownie workflow: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Techniki debugowania kanałów + +#### Używanie `.view()` do inspekcji kanałów + +Najpotężniejszym narzędziem debugowania dla kanałów jest operator `.view()`. Dzięki `.view()` możesz zrozumieć kształt swoich kanałów na wszystkich etapach, aby pomóc w debugowaniu. + +#### Uruchom pipeline + +Uruchom `bad_channel_shape_viewed.nf`, aby to zobaczyć w akcji: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Sprawdź kod + +Przeanalizujmy `bad_channel_shape_viewed.nf`, aby zobaczyć, jak używane jest `.view()`: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debugowanie: Pokaż oryginalną zawartość kanału + .map { tuple -> tuple[0] } // Transformacja: Wydobądź pierwszy element + .view { "After mapping: $it" } // Debugowanie: Pokaż przekształconą zawartość kanału + + PROCESS_FILES(input_ch) +} +``` + +#### Napraw kod + +Aby oszczędzić sobie nadmiernego używania operacji `.view()` w przyszłości do zrozumienia zawartości kanału, wskazane jest dodanie kilku komentarzy pomocnych: + +```groovy title="bad_channel_shape_viewed.nf (z komentarzami)" linenums="16" hl_lines="8 9" +workflow { + + // Kanał emituje krotki, ale proces oczekuje pojedynczych wartości + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Będzie to ważniejsze w miarę jak Twoje workflow będą rosły w złożoności i struktura kanału stanie się bardziej nieprzejrzysta. + +#### Uruchom pipeline + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Wnioski + +Wiele błędów struktury kanałów może być utworzonych za pomocą prawidłowej składni Nextflow. Możesz debugować błędy struktury kanałów poprzez zrozumienie przepływu danych, używanie operatorów `.view()` do inspekcji i rozpoznawanie wzorców komunikatów błędów, takich jak nawiasy kwadratowe wskazujące nieoczekiwane struktury krotek. + +### Co dalej? + +Dowiedz się o błędach tworzonych przez definicje procesów. + +--- + +## 3. Błędy struktury procesów + +Większość błędów, które napotykasz związanych z procesami, będzie związana z błędami, które popełniłeś w formowaniu polecenia, lub z problemami związanymi z podstawowym oprogramowaniem. Mimo to, podobnie jak w przypadku problemów z kanałami powyżej, możesz popełnić błędy w definicji procesu, które nie kwalifikują się jako błędy składni, ale które spowodują błędy w czasie wykonania. + +### 3.1. Brakujące pliki wyjściowe + +Jednym z częstych błędów podczas pisania procesów jest zrobienie czegoś, co generuje niedopasowanie między tym, czego oczekuje proces, a tym, co jest generowane. + +#### Uruchom pipeline + +```bash +nextflow run missing_output.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Sprawdź kod + +Komunikat błędu wskazuje, że proces oczekiwał utworzenia pliku wyjściowego o nazwie `sample3.txt`, ale skrypt faktycznie tworzy `sample3_output.txt`. Przeanalizujmy definicję procesu w `missing_output.nf`: + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Oczekuje: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Tworzy: sample3_output.txt + """ +} +``` + +Powinieneś zobaczyć, że istnieje niedopasowanie między nazwą pliku wyjściowego w bloku `output:`, a tą użytą w skrypcie. To niedopasowanie powoduje, że proces zawodzi. Jeśli napotkasz tego rodzaju błąd, wróć i sprawdź, czy wyjścia pasują między Twoją definicją procesu a Twoim blokiem wyjściowym. + +Jeśli problem nadal nie jest jasny, sprawdź sam katalog roboczy, aby zidentyfikować faktycznie utworzone pliki wyjściowe: + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Dla tego przykładu to podkreśliłoby dla nas, że sufiks `_output` jest włączany do nazwy pliku wyjściowego, wbrew naszej definicji `output:`. + +#### Napraw kod + +Napraw niedopasowanie, czyniąc nazwę pliku wyjściowego spójną: + +=== "Po" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Naprawiono: Dopasuj wyjście skryptu + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Przed" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_ diff --git a/docs/pl/docs/side_quests/dev_environment.md b/docs/pl/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..df81840f92 --- /dev/null +++ b/docs/pl/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Środowisko programistyczne + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nowoczesne zintegrowane środowiska programistyczne (IDE) mogą dramatycznie zmienić Twoje doświadczenie z tworzeniem kodu w Nextflow. Ten quest poboczny koncentruje się konkretnie na wykorzystaniu VS Code i jego rozszerzenia Nextflow do szybszego pisania kodu, wczesnego wykrywania błędów i efektywnej nawigacji po złożonych workflow. + +!!! note "To nie jest tradycyjny samouczek" + + W przeciwieństwie do innych modułów szkoleniowych, ten przewodnik jest zorganizowany jako zbiór szybkich wskazówek, podpowiedzi i praktycznych przykładów, a nie samouczek krok po kroku. Każda sekcja może być eksplorowana niezależnie, w zależności od Twoich zainteresowań i bieżących potrzeb programistycznych. Śmiało przeskakuj między sekcjami i skup się na funkcjach, które będą najbardziej przydatne w Twoim procesie tworzenia workflow. + +## Co powinieneś wiedzieć wcześniej + +Ten przewodnik zakłada, że ukończyłeś kurs szkoleniowy [Hello Nextflow](../hello_nextflow/) i czujesz się komfortowo z podstawowymi koncepcjami Nextflow, w tym: + +- **Podstawowa struktura workflow**: Rozumienie procesów, workflow i sposobu ich łączenia +- **Operacje na kanałach**: Tworzenie kanałów, przekazywanie danych między procesami i używanie podstawowych operatorów +- **Moduły i organizacja**: Tworzenie modułów wielokrotnego użytku i używanie instrukcji include +- **Podstawy konfiguracji**: Używanie `nextflow.config` dla parametrów, dyrektyw procesów i profili + +## Czego się tutaj nauczysz + +Ten przewodnik koncentruje się na **funkcjach produktywności IDE**, które uczynią Cię bardziej efektywnym programistą Nextflow: + +- **Zaawansowane podświetlanie składni**: Zrozumienie tego, co VS Code pokazuje o strukturze Twojego kodu +- **Inteligentne automatyczne uzupełnianie**: Wykorzystywanie kontekstowych sugestii do szybszego pisania kodu +- **Wykrywanie błędów i diagnostyka**: Wychwytywanie błędów składni przed uruchomieniem workflow +- **Nawigacja po kodzie**: Szybkie przechodzenie między procesami, modułami i definicjami +- **Formatowanie i organizacja**: Utrzymywanie spójnego, czytelnego stylu kodu +- **Programowanie wspomagane AI** (opcjonalnie): Używanie nowoczesnych narzędzi AI zintegrowanych z Twoim IDE + +!!! info "Dlaczego funkcje IDE teraz?" + + Prawdopodobnie używałeś już VS Code podczas kursu [Hello Nextflow](../hello_nextflow/), ale skupiliśmy się na nauce podstaw Nextflow, a nie na funkcjach IDE. Teraz, gdy czujesz się komfortowo z podstawowymi koncepcjami Nextflow, takimi jak procesy, workflow, kanały i moduły, jesteś gotowy na wykorzystanie zaawansowanych funkcji IDE, które uczynią Cię bardziej efektywnym programistą. + + Pomyśl o tym jak o "awansowaniu" Twojego środowiska programistycznego - ten sam edytor, którego używałeś, ma znacznie potężniejsze możliwości, które stają się naprawdę wartościowe, gdy rozumiesz, w czym Ci pomagają. + +--- + +## 0. Konfiguracja i rozgrzewka + +Skonfigurujmy przestrzeń roboczą specjalnie do eksplorowania funkcji IDE: + +```bash title="Przejdź do katalogu z funkcjami IDE" +cd side-quests/ide_features +``` + +Otwórz ten katalog w VS Code: + +```bash title="Otwórz VS Code w bieżącym katalogu" +code . +``` + +Katalog `ide_features` zawiera przykładowe workflow demonstrujące różne funkcje IDE: + +```bash title="Pokaż strukturę katalogów" +tree . +``` + +```console title="Struktura projektu" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "O plikach przykładowych" + + - `basic_workflow.nf` to działający podstawowy workflow, który możesz uruchomić i modyfikować + - `complex_workflow.nf` jest przeznaczony wyłącznie do ilustracji, aby zademonstrować funkcje nawigacji - może nie uruchomić się pomyślnie, ale pokazuje realistyczną strukturę wieloplikowego workflow + +### Skróty klawiszowe + +Niektóre funkcje w tym przewodniku będą używać opcjonalnych skrótów klawiszowych. Być może uzyskujesz dostęp do tego materiału przez GitHub Codespaces w przeglądarce, a w takim przypadku czasami skróty nie będą działać zgodnie z oczekiwaniami, ponieważ są używane do innych rzeczy w Twoim systemie. + +Jeśli uruchamiasz VS Code lokalnie, tak jak prawdopodobnie będziesz robić, gdy faktycznie piszesz workflow, skróty będą działać zgodnie z opisem. + +Jeśli używasz Maca, niektóre (nie wszystkie) skróty klawiszowe będą używać "cmd" zamiast "ctrl", i zaznaczymy to w tekście w ten sposób `Ctrl/Cmd`. + +### 0.1. Instalacja rozszerzenia Nextflow + +!!! note "Już używasz Devcontainers?" + + Jeśli pracujesz w **GitHub Codespaces** lub używasz **lokalnego devcontainer**, rozszerzenie Nextflow jest prawdopodobnie już zainstalowane i skonfigurowane. Możesz pominąć poniższe kroki ręcznej instalacji i przejść bezpośrednio do eksplorowania funkcji rozszerzenia. + +Aby zainstalować rozszerzenie ręcznie: + +1. Otwórz VS Code +2. Przejdź do widoku rozszerzeń, klikając ikonę rozszerzeń po lewej stronie: ![ikona rozszerzeń](img/extensions_icon.png) (skrót `Ctrl/Cmd+Shift+X`, jeśli uruchamiasz VSCode lokalnie) +3. Wyszukaj "Nextflow" +4. Zainstaluj oficjalne rozszerzenie Nextflow + +![Instalacja rozszerzenia Nextflow](img/install_extension.png) + +### 0.2. Layout przestrzeni roboczej + +Ponieważ używałeś VS Code podczas całego kursu Hello Nextflow, jesteś już zaznajomiony z podstawami. Oto jak efektywnie zorganizować przestrzeń roboczą na tę sesję: + +- **Obszar edytora**: Do przeglądania i edytowania plików. Możesz podzielić go na wiele paneli, aby porównywać pliki obok siebie. +- **Eksplorator plików** kliknij (![ikona eksploratora plików](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): Lokalne pliki i foldery w Twoim systemie. Trzymaj to otwarte po lewej stronie, aby nawigować między plikami +- **Zintegrowany terminal** (`Ctrl+Shift+` backtick dla Windows i MacOS): Terminal do interakcji z komputerem u dołu. Użyj tego do uruchamiania Nextflow lub innych poleceń. +- **Panel problemów** (`Ctrl+Shift+M`): VS Code pokaże tutaj wszelkie wykryte błędy i problemy. Jest to przydatne do szybkiego podświetlenia problemów. + +Możesz przeciągać panele lub je ukrywać (`Ctrl/Cmd+B`, aby przełączyć pasek boczny), aby dostosować swój layout podczas pracy z przykładami. + +### Podsumowanie + +Masz skonfigurowany VS Code z rozszerzeniem Nextflow i rozumiesz layout przestrzeni roboczej dla efektywnego programowania. + +### Co dalej? + +Dowiedz się, jak podświetlanie składni pomaga zrozumieć strukturę kodu Nextflow na pierwszy rzut oka. + +--- + +## 1. Podświetlanie składni i struktura kodu + +Teraz, gdy Twoja przestrzeń robocza jest skonfigurowana, zbadajmy, jak podświetlanie składni VS Code pomaga Ci skuteczniej czytać i pisać kod Nextflow. + +### 1.1. Elementy składni Nextflow + +Otwórz `basic_workflow.nf`, aby zobaczyć podświetlanie składni w akcji: + +![Prezentacja składni](img/syntax_showcase.png) + +Zauważ, jak VS Code podświetla: + +- **Słowa kluczowe** (`process`, `workflow`, `input`, `output`, `script`) w wyróżniających się kolorach +- **Literały łańcuchowe** i **parametry** z różnym stylem +- **Komentarze** w stonowanym kolorze +- **Zmienne** i **wywołania funkcji** z odpowiednim wyróżnieniem +- **Bloki kodu** z odpowiednimi prowadnicami wcięć + +!!! note "Kolory zależne od motywu" + + Konkretne kolory, które widzisz, będą zależeć od Twojego motywu VS Code (tryb ciemny/jasny), ustawień kolorów i wszelkich dokonanych dostosowań. Ważne jest, że różne elementy składni są wizualnie odróżnione od siebie, co ułatwia zrozumienie struktury kodu niezależnie od wybranego schematu kolorów. + +### 1.2. Zrozumienie struktury kodu + +Podświetlanie składni pomaga szybko zidentyfikować: + +- **Granice procesów**: Wyraźne rozróżnienie między różnymi procesami +- **Bloki wejścia/wyjścia**: Łatwe do zauważenia definicje przepływu danych +- **Bloki script**: Faktycznie wykonywane polecenia +- **Operacje na kanałach**: Kroki transformacji danych +- **Dyrektywy konfiguracji**: Ustawienia specyficzne dla procesu + +Ta wizualna organizacja staje się nieoceniona podczas pracy ze złożonymi workflow zawierającymi wiele procesów i skomplikowane przepływy danych. + +### Podsumowanie + +Rozumiesz, jak podświetlanie składni VS Code pomaga czytać strukturę kodu Nextflow i identyfikować różne elementy języka dla szybszego programowania. + +### Co dalej? + +Dowiedz się, jak inteligentne automatyczne uzupełnianie przyspiesza pisanie kodu dzięki kontekstowym sugestiom. + +--- + +## 2. Inteligentne automatyczne uzupełnianie + +Funkcje automatycznego uzupełniania VS Code pomagają pisać kod szybciej i z mniejszą liczbą błędów, sugerując odpowiednie opcje w zależności od kontekstu. + +### 2.1. Sugestie kontekstowe + +Opcje automatycznego uzupełniania różnią się w zależności od miejsca w kodzie: + +#### Operacje na kanałach + +Otwórz ponownie `basic_workflow.nf` i spróbuj wpisać `channel.` w bloku workflow: + +![Automatyczne uzupełnianie kanału](img/autocomplete_channel.png) + +Zobaczysz sugestie dla: + +- `fromPath()` - Utworzenie kanału ze ścieżek plików +- `fromFilePairs()` - Utworzenie kanału z par plików +- `of()` - Utworzenie kanału z wartości +- `fromSRA()` - Utworzenie kanału z akcesji SRA +- I wiele więcej... + +To pomaga szybko znaleźć odpowiednią fabrykę kanałów do użycia bez konieczności zapamiętywania dokładnych nazw metod. + +Możesz także odkryć operatory dostępne do zastosowania na kanałach. Na przykład wpisz `FASTQC.out.html.`, aby zobaczyć dostępne operacje: + +![Automatyczne uzupełnianie operacji na kanałach](img/autocomplete_operators.png) + +#### Dyrektywy procesu + +Wewnątrz bloku script procesu wpisz `task.`, aby zobaczyć dostępne właściwości wykonania: + +![Automatyczne uzupełnianie właściwości task](img/autocomplete_task.png) + +#### Konfiguracja + +Otwórz nextflow.config i wpisz `process.` w dowolnym miejscu, aby zobaczyć dostępne dyrektywy procesu: + +![Automatyczne uzupełnianie konfiguracji](img/autocomplete_config.png) + +Zobaczysz sugestie dla: + +- `executor` +- `memory` +- `cpus` + +To oszczędza czas podczas konfigurowania procesów i działa w różnych zakresach konfiguracji. Na przykład spróbuj wpisać `docker.`, aby zobaczyć opcje konfiguracji specyficzne dla Docker. + +### Podsumowanie + +Możesz używać inteligentnego automatycznego uzupełniania VS Code do odkrywania dostępnych operacji na kanałach, dyrektyw procesów i opcji konfiguracji bez zapamiętywania składni. + +### Co dalej? + +Dowiedz się, jak wykrywanie błędów w czasie rzeczywistym pomaga wychwytywać problemy przed uruchomieniem workflow, po prostu przez czytanie kodu. + +## 3. Wykrywanie błędów i diagnostyka + +Wykrywanie błędów w czasie rzeczywistym w VS Code pomaga wychwytywać problemy przed uruchomieniem workflow. + +### 3.1. Wykrywanie błędów składni + +Stwórzmy celowy błąd, aby zobaczyć wykrywanie w akcji. Otwórz `basic_workflow.nf` i zmień nazwę procesu z `FASTQC` na `FASTQ` (lub jakąkolwiek inną nieprawidłową nazwę). VS Code natychmiast podświetli błąd w bloku workflow czerwoną falistą linią: + +![Podkreślenie błędu](img/error_underline.png) + +### 3.2. Panel problemów + +Poza podświetlaniem poszczególnych błędów, VS Code zapewnia scentralizowany panel problemów, który agreguje wszystkie błędy, ostrzeżenia i komunikaty informacyjne w całej przestrzeni roboczej. Otwórz go za pomocą `Ctrl/Cmd+Shift+M` i użyj ikony filtra, aby pokazać tylko błędy istotne dla bieżącego pliku: + +![Filtrowanie panelu problemów](img/active_file.png) + +Kliknij dowolny problem, aby przejść bezpośrednio do problematycznej linii + +![Panel problemów](img/problems_panel.png) + +Napraw błąd, zmieniając nazwę procesu z powrotem na `FASTQC`. + +### 3.3. Typowe wzorce błędów + +Typowe błędy w składni Nextflow obejmują: + +- **Brakujące nawiasy**: Niedopasowane `{` lub `}` +- **Niekompletne bloki**: Brakujące wymagane sekcje w procesach +- **Nieprawidłowa składnia**: Źle sformułowany Nextflow DSL +- **Literówki w słowach kluczowych**: Błędnie napisane dyrektywy procesu +- **Niedopasowanie kanałów**: Niekompatybilność typów + +Serwer języka Nextflow podświetla te problemy w panelu problemów. Możesz sprawdzić je wcześnie, aby uniknąć błędów składni podczas uruchamiania pipeline. + +### Podsumowanie + +Możesz używać wykrywania błędów VS Code i panelu problemów do wychwytywania błędów składni i problemów przed uruchomieniem workflow, oszczędzając czas i zapobiegając frustracji. + +### Co dalej? + +Dowiedz się, jak efektywnie nawigować między procesami, modułami i definicjami w złożonych workflow. + +--- + +## 4. Nawigacja po kodzie i zarządzanie symbolami + +Efektywna nawigacja jest kluczowa podczas pracy ze złożonymi workflow obejmującymi wiele plików. Aby to zrozumieć, zastąp definicję procesu w `basic_workflow.nf` importem dostarczonego modułu: + +=== "Po" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Przed" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Przejdź do definicji + +Jeśli najedziesz myszką na nazwę procesu, taką jak `FASTQC`, zobaczysz wyskakujące okienko z interfejsem modułu (wejścia i wyjścia): + +![Przejdź do definicji](img/syntax.png) + +Ta funkcja jest szczególnie cenna podczas tworzenia workflow, ponieważ pozwala zrozumieć interfejs modułu bez bezpośredniego otwierania pliku modułu. + +Możesz szybko przejść do dowolnej definicji procesu, modułu lub zmiennej, używając **Ctrl/Cmd-klik**. Najedź myszką na link do pliku modułu na górze skryptu i podążaj za linkiem zgodnie z sugestią: + +![Podążaj za linkiem](img/follow_link.png) + +To samo działa dla nazw procesów. Wróć do `basic_workflow.nf` i spróbuj tego na nazwie procesu `FASTQC` w bloku workflow. To łączy Cię bezpośrednio z nazwą procesu (która w tym przykładzie jest taka sama jak plik modułu, ale może być w połowie znacznie większego pliku). + +Aby wrócić do miejsca, w którym byłeś, użyj **Alt+←** (lub **Ctrl+-** na Mac). To potężny sposób eksplorowania kodu bez utraty miejsca. + +Teraz zbadajmy nawigację w bardziej złożonym workflow, używając `complex_workflow.nf` (pliku przeznaczonego wyłącznie do ilustracji, o którym wspomnieliśmy wcześniej). Ten workflow zawiera wiele procesów zdefiniowanych w oddzielnych plikach modułów, a także kilka inline. Chociaż złożone struktury wieloplikowe mogą być trudne do ręcznej nawigacji, możliwość przeskakiwania do definicji znacznie ułatwia eksplorację. + +1. Otwórz `complex_workflow.nf` +2. Nawiguj do definicji modułów +3. Użyj **Alt+←** (lub **Ctrl+-**), aby wrócić do poprzedniej lokalizacji +4. Nawiguj do nazwy procesu `FASTQC` w bloku workflow. To łączy Cię bezpośrednio z nazwą procesu (która w tym przykładzie jest taka sama jak plik modułu, ale może być w połowie znacznie większego pliku). +5. Nawiguj ponownie wstecz +6. Nawiguj do procesu `TRIM_GALORE` w bloku workflow. Jest on zdefiniowany inline, więc nie przeniesie Cię do oddzielnego pliku, ale nadal pokaże Ci definicję procesu i nadal możesz wrócić do miejsca, w którym byłeś. + +### 4.2. Nawigacja po symbolach + +Mając nadal otwarty `complex_workflow.nf`, możesz uzyskać przegląd wszystkich symboli w pliku, wpisując `@` w pasek wyszukiwania na górze VSCode (skrót klawiszowy to `Ctrl/Cmd+Shift+O`, ale może nie działać w Codespaces). Otwiera to panel nawigacji po symbolach, który wyświetla wszystkie symbole w bieżącym pliku: + +![Nawigacja po symbolach](img/symbols.png) + +To pokazuje: + +- Wszystkie definicje procesów +- Definicje workflow (w tym pliku zdefiniowano dwa workflow) +- Definicje funkcji + +Zacznij pisać, aby filtrować wyniki. + +### 4.3. Znajdź wszystkie odniesienia + +Zrozumienie, gdzie proces lub zmienna jest używana w całej bazie kodu, może być bardzo pomocne. Na przykład, jeśli chcesz znaleźć wszystkie odniesienia do procesu `FASTQC`, zacznij od przejścia do jego definicji. Możesz to zrobić, otwierając `modules/fastqc.nf` bezpośrednio lub używając funkcji szybkiej nawigacji VS Code z `Ctrl/Cmd-klik`, jak zrobiliśmy powyżej. Po dotarciu do definicji procesu kliknij prawym przyciskiem myszy na nazwie procesu `FASTQC` i wybierz "Find All References" z menu kontekstowego, aby zobaczyć wszystkie wystąpienia, w których jest używany. + +![Znajdź odniesienia](img/references.png) + +Ta funkcja wyświetla wszystkie wystąpienia, w których `FASTQC` jest przywoływany w Twojej przestrzeni roboczej, włączając jego użycie w dwóch różnych workflow. Ten wgląd jest kluczowy dla oceny potencjalnego wpływu modyfikacji procesu `FASTQC`. + +### 4.4. Panel konspektu + +Panel konspektu, znajdujący się na pasku bocznym eksploratora (kliknij ![Ikona eksploratora](img/files_icon.png)), zapewnia wygodny przegląd wszystkich symboli w bieżącym pliku. Ta funkcja pozwala szybko nawigować i zarządzać strukturą kodu, wyświetlając funkcje, zmienne i inne kluczowe elementy w widoku hierarchicznym. + +![Panel konspektu](img/outline.png) + +Użyj panelu konspektu do szybkiej nawigacji do różnych części kodu bez korzystania z przeglądarki plików. + +### 4.5. Wizualizacja DAG + +Rozszerzenie Nextflow VS Code może wizualizować Twoje workflow jako skierowany graf acykliczny (DAG). To pomaga zrozumieć przepływ danych i zależności między procesami. Otwórz `complex_workflow.nf` i kliknij przycisk "Preview DAG" nad `workflow {` (drugi blok `workflow` w tym pliku): + +![Podgląd DAG](img/dag_preview.png) + +To jest tylko workflow 'wejściowe', ale możesz także podejrzeć DAG dla wewnętrznych workflow, klikając przycisk "Preview DAG" nad workflow `RNASEQ_PIPELINE {` wyżej: + +![Podgląd DAG wewnętrznego workflow](img/dag_preview_inner.png) + +Dla tego workflow możesz używać węzłów w DAG do nawigacji do odpowiednich definicji procesów w kodzie. Kliknij węzeł, a przejdzie Cię do odpowiedniej definicji procesu w edytorze. Szczególnie gdy workflow urośnie do dużego rozmiaru, może to naprawdę pomóc w nawigacji po kodzie i zrozumieniu, jak procesy są połączone. + +### Podsumowanie + +Możesz nawigować złożone workflow efektywnie, używając przejdź-do-definicji, wyszukiwania symboli, znajdź odniesienia i wizualizacji DAG do zrozumienia struktury kodu i zależności. + +### Co dalej? + +Dowiedz się, jak efektywnie pracować z wieloma połączonymi plikami w większych projektach Nextflow. + +## 5. Praca z wieloma plikami + +Rzeczywiste programowanie Nextflow obejmuje pracę z wieloma połączonymi plikami. Zbadajmy, jak VS Code pomaga efektywnie zarządzać złożonymi projektami. + +### 5.1. Szybka nawigacja po plikach + +Mając otwarty `complex_workflow.nf`, zauważysz, że importuje kilka modułów. Przećwiczmy szybką nawigację między nimi. + +Naciśnij **Ctrl+P** (lub **Cmd+P**) i zacznij wpisywać "fast": + +VS Code pokaże Ci pasujące pliki. Wybierz `modules/fastqc.nf`, aby tam natychmiast przeskoczyć. To jest znacznie szybsze niż klikanie przez eksplorator plików, gdy mniej więcej wiesz, jakiego pliku szukasz. + +Spróbuj tego z innymi wzorcami: + +- Wpisz "star", aby znaleźć plik modułu dopasowania STAR (`star.nf`) +- Wpisz "utils", aby znaleźć plik funkcji użytkowych (`utils.nf`) +- Wpisz "config", aby przeskoczyć do plików konfiguracyjnych (`nextflow.config`) + +### 5.2. Podzielony edytor do programowania wieloplikowego + +Podczas pracy z modułami często musisz widzieć jednocześnie główne workflow i definicje modułów. Skonfigurujmy to: + +1. Otwórz `complex_workflow.nf` +2. Otwórz `modules/fastqc.nf` w nowej zakładce +3. Kliknij prawym przyciskiem myszy na zakładce `modules/fastqc.nf` i wybierz "Split Right" +4. Teraz możesz widzieć oba pliki obok siebie + +![Podzielony edytor](img/split_editor.png) + +To jest nieocenione podczas: + +- Sprawdzania interfejsów modułów podczas pisania wywołań workflow, gdy podgląd nie wystarczy +- Porównywania podobnych procesów w różnych modułach +- Debugowania przepływu danych między workflow a modułami + +### 5.3. Wyszukiwanie w całym projekcie + +Czasami musisz znaleźć, gdzie określone wzorce są używane w całym projekcie. Naciśnij `Ctrl/Cmd+Shift+F`, aby otworzyć panel wyszukiwania. + +Spróbuj wyszukać `publishDir` w całej przestrzeni roboczej: + +![Wyszukiwanie w projekcie](img/project_search.png) + +To pokazuje każdy plik, który używa katalogów publikacji, pomagając Ci: + +- Zrozumieć wzorce organizacji wyjść +- Znaleźć przykłady określonych dyrektyw +- Zapewnić spójność w modułach + +### Podsumowanie + +Możesz zarządzać złożonymi projektami wieloplikowymi, używając szybkiej nawigacji po plikach, podzielonych edytorów i wyszukiwania w całym projekcie do efektywnej pracy z workflow i modułami. + +### Co dalej? + +Dowiedz się, jak funkcje formatowania kodu i utrzymania utrzymują Twoje workflow zorganizowane i czytelne. + +--- + +## 6. Formatowanie i utrzymanie kodu + +Odpowiednie formatowanie kodu jest niezbędne nie tylko dla estetyki, ale także dla zwiększenia czytelności, zrozumienia i łatwości aktualizacji złożonych workflow. + +### 6.1. Automatyczne formatowanie w akcji + +Otwórz `basic_workflow.nf` i celowo zepsuj formatowanie: + +- Usuń część wcięć: Podświetl cały dokument i naciśnij `shift+tab` wiele razy, aby usunąć jak najwięcej wcięć. +- Dodaj dodatkowe spacje w losowych miejscach: w instrukcji `channel.fromPath`, dodaj 30 spacji po `(`. +- Złam kilka linii niezręcznie: Dodaj nową linię między operatorem `.view {` a łańcuchem `Processing sample:`, ale nie dodawaj odpowiedniego nowego wiersza przed zamykającym nawiasem `}`. + +Teraz naciśnij `Shift+Alt+F` (lub `Shift+Option+F` na MacOS), aby automatycznie sformatować: + +VS Code natychmiast: + +- Naprawia wcięcia, aby wyraźnie pokazać strukturę procesu +- Wyrównuje podobne elementy spójnie +- Usuwa niepotrzebne białe znaki +- Utrzymuje czytelne przerwy w liniach + +Zauważ, że automatyczne formatowanie może nie rozwiązać każdego problemu ze stylem kodu. Serwer języka Nextflow ma na celu utrzymanie porządku w kodzie, ale także szanuje Twoje osobiste preferencje w niektórych obszarach. Na przykład, jeśli usuniesz wcięcie wewnątrz bloku `script` procesu, formater pozostawi to bez zmian, ponieważ możesz celowo preferować ten styl. + +Obecnie nie ma ścisłego wymuszania stylu dla Nextflow, więc serwer języka oferuje pewną elastyczność. Jednak będzie spójnie stosować reguły formatowania wokół definicji metod i funkcji w celu utrzymania przejrzystości. + +### 6.2. Funkcje organizacji kodu + +#### Szybkie komentowanie + +Zaznacz blok kodu w swoim workflow i naciśnij **Ctrl+/** (lub **Cmd+/**), aby go zakomentować: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +To idealne do: + +- Tymczasowego wyłączania części workflow podczas programowania +- Dodawania wyjaśniających komentarzy do złożonych operacji na kanałach +- Dokumentowania sekcji workflow + +Użyj **Ctrl+/** (lub **Cmd+/**) ponownie, aby odkomentować kod. + +#### Składanie kodu do przeglądu + +W `complex_workflow.nf` zauważ małe strzałki obok definicji procesów. Kliknij je, aby złożyć (zwinąć) procesy: + +![Składanie kodu](img/code_folding.png) + +To daje Ci przegląd wysokiego poziomu struktury workflow bez gubienia się w szczegółach implementacji. + +#### Dopasowanie nawiasów + +Umieść kursor obok dowolnego nawiasu `{` lub `}`, a VS Code podświetli pasujący nawias. Użyj **Ctrl+Shift+\\** (lub **Cmd+Shift+\\**), aby przeskoczyć między pasującymi nawiasami. + +To jest kluczowe dla: + +- Zrozumienia granic procesów +- Znajdowania brakujących lub dodatkowych nawiasów +- Nawigacji zagnieżdżonych struktur workflow + +#### Wieloliniowe zaznaczanie i edycja + +Dla edycji wielu linii jednocześnie VS Code oferuje potężne możliwości wielokursorowe: + +- **Wieloliniowe zaznaczanie**: Przytrzymaj **Ctrl+Alt** (lub **Cmd+Option** dla MacOS) i użyj klawiszy strzałek do zaznaczenia wielu linii +- **Wieloliniowe wcięcia**: Zaznacz wiele linii i użyj **Tab** do wcięcia lub **Shift+Tab** do wycofania wcięcia całych bloków + +Jest to szczególnie przydatne do: + +- Spójnego wcięcia całych bloków procesów +- Dodawania komentarzy do wielu linii jednocześnie +- Edycji podobnych definicji parametrów w wielu procesach + +### Podsumowanie + +Możesz utrzymywać czysty, czytelny kod, używając automatycznego formatowania, funkcji komentowania, składania kodu, dopasowania nawiasów i wieloliniowej edycji do efektywnej organizacji złożonych workflow. + +### Co dalej? + +Dowiedz się, jak VS Code integruje się z Twoim szerszym procesem programistycznym poza samą edycją kodu. + +--- + +## 7. Integracja przepływu pracy programistycznej + +VS Code dobrze integruje się z przepływem pracy programistycznej poza samą edycją kodu. + +### 7.1. Integracja kontroli wersji + +!!! note "Codespaces i integracja z Git" + + Jeśli pracujesz w **GitHub Codespaces**, niektóre funkcje integracji Git mogą nie działać zgodnie z oczekiwaniami, szczególnie skróty klawiszowe dla Source Control. Mogłeś także odmówić otwarcia katalogu jako repozytorium Git podczas początkowej konfiguracji, co jest w porządku do celów szkoleniowych. + +Jeśli Twój projekt jest repozytorium git (tak jak ten jest), VS Code pokazuje: + +- Zmodyfikowane pliki z kolorowymi wskaźnikami +- Status Git na pasku stanu +- Widoki diff inline +- Możliwości commit i push + +Otwórz panel Source Control, używając przycisku kontroli źródła (![Ikona kontroli źródła](img/source_control_icon.png)) (`Ctrl+Shift+G` lub `Cmd+Shift+G`, jeśli pracujesz z VSCode lokalnie), aby zobaczyć zmiany git i dokonywać commit bezpośrednio w edytorze. + +![Panel Source Control](img/source_control.png) + +### 7.2. Uruchamianie i inspekcja workflow + +Uruchommy workflow, a następnie sprawdźmy wyniki. W zintegrowanym terminalu (`Ctrl+Shift+` backtick w Windows i MacOS), uruchom podstawowy workflow: + +```bash title="Uruchom podstawowy workflow" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Podczas działania workflow zobaczysz wyjście w czasie rzeczywistym w terminalu. Po zakończeniu możesz użyć VS Code do inspekcji wyników bez opuszczania edytora: + +1. **Nawiguj do katalogów work**: Użyj eksploratora plików lub terminala do przeglądania `.nextflow/work` +2. **Otwórz pliki logów**: Kliknij ścieżki plików logów w wyjściu terminala, aby otworzyć je bezpośrednio w VS Code +3. **Sprawdź wyjścia**: Przeglądaj opublikowane katalogi wyników w eksploratorze plików +4. **Wyświetl raporty wykonania**: Otwórz raporty HTML bezpośrednio w VS Code lub przeglądarce + +To utrzymuje wszystko w jednym miejscu zamiast przełączać się między wieloma aplikacjami. + +### Podsumowanie + +Możesz zintegrować VS Code z kontrolą wersji i wykonywaniem workflow, aby zarządzać całym procesem programistycznym z jednego interfejsu. + +### Co dalej? + +Zobacz, jak wszystkie te funkcje IDE współpracują w codziennym przepływie pracy programistycznej. + +--- + +## 8. Podsumowanie i szybkie notatki + +Oto kilka szybkich notatek na temat każdej z funkcji IDE omówionych powyżej: + +### 8.1. Rozpoczynanie nowej funkcjonalności + +1. **Szybkie otwieranie pliku** (`Ctrl+P` lub `Cmd+P`) do znalezienia odpowiednich istniejących modułów +2. **Podzielony edytor** do przeglądania podobnych procesów obok siebie +3. **Nawigacja po symbolach** (`Ctrl+Shift+O` lub `Cmd+Shift+O`) do zrozumienia struktury pliku +4. **Automatyczne uzupełnianie** do szybkiego pisania nowego kodu + +### 8.2. Debugowanie problemów + +1. **Panel problemów** (`Ctrl+Shift+M` lub `Cmd+Shift+M`) do zobaczenia wszystkich błędów jednocześnie +2. **Przejdź do definicji** (`Ctrl-klik` lub `Cmd-klik`) do zrozumienia interfejsów procesów +3. **Znajdź wszystkie odniesienia** do zobaczenia, jak procesy są używane +4. **Wyszukiwanie w całym projekcie** do znalezienia podobnych wzorców lub problemów + +### 8.3. Refaktoryzacja i ulepszanie + +1. **Wyszukiwanie w całym projekcie** (`Ctrl+Shift+F` lub `Cmd+Shift+F`) do znalezienia wzorców +2. **Automatyczne formatowanie** (`Shift+Alt+F` lub `Shift+Option+F`) do utrzymania spójności +3. **Składanie kodu** do skupienia się na strukturze +4. **Integracja z Git** do śledzenia zmian + +--- + +## Podsumowanie + +Właśnie odbyłeś ekspresową wycieczkę po funkcjach IDE VS Code dla programowania Nextflow. Te narzędzia uczynią Cię znacznie bardziej produktywnym poprzez: + +- **Zmniejszenie błędów** poprzez sprawdzanie składni w czasie rzeczywistym +- **Przyspieszenie programowania** dzięki inteligentnemu automatycznemu uzupełnianiu +- **Ulepszenie nawigacji** w złożonych wieloplikowych workflow +- **Utrzymanie jakości** poprzez spójne formatowanie +- **Zwiększenie zrozumienia** poprzez zaawansowane podświetlanie i wizualizację struktury + +Nie oczekujemy, że zapamiętasz wszystko, ale teraz wiesz, że te funkcje istnieją i będziesz w stanie je znaleźć, gdy będziesz ich potrzebować. Kontynuując programowanie workflow Nextflow, te funkcje IDE staną się drugą naturą, pozwalając Ci skupić się na pisaniu wysokiej jakości kodu zamiast zmagać się ze składnią i strukturą. + +### Co dalej? + +Zastosuj te umiejętności IDE podczas pracy z innymi modułami szkoleniowymi, na przykład: + +- **[nf-test](nf-test.md)**: Twórz kompleksowe zestawy testów dla swoich workflow +- **[Hello nf-core](../../hello_nf-core/)**: Buduj pipeline gotowe do produkcji ze standardami społeczności + +Prawdziwa siła tych funkcji IDE ujawnia się, gdy pracujesz nad większymi, bardziej złożonymi projektami. Zacznij stopniowo włączać je do swojego przepływu pracy - w ciągu kilku sesji staną się drugą naturą i zmienią sposób, w jaki podchodzisz do programowania Nextflow. + +Od wychwytywania błędów, zanim Cię spowolnią, po łatwą nawigację po złożonych bazach kodu, te narzędzia uczynią Cię bardziej pewnym i efektywnym programistą. + +Udanego kodowania! diff --git a/docs/pl/docs/side_quests/essential_scripting_patterns.md b/docs/pl/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..150818acad --- /dev/null +++ b/docs/pl/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1106 @@ +# Podstawowe Wzorce Skryptowe w Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow to język programowania działający na Java Virtual Machine. Chociaż Nextflow jest zbudowany na [Groovy](http://groovy-lang.org/) i dzieli wiele elementów składni, Nextflow to coś więcej niż tylko "Groovy z rozszerzeniami" -- jest to samodzielny język z w pełni określoną [składnią](https://nextflow.io/docs/latest/reference/syntax.html) i [biblioteką standardową](https://nextflow.io/docs/latest/reference/stdlib.html). + +Można pisać dużo kodu w Nextflow, nie wykraczając poza podstawową składnię zmiennych, map i list. Większość tutoriali Nextflow koncentruje się na orkiestracji workflow (kanały, procesy i przepływ danych) i można zajść zaskakująco daleko, używając tylko tego. + +Jednak gdy trzeba manipulować danymi, parsować złożone nazwy plików, implementować logikę warunkową lub budować solidne workflow produkcyjne, pomaga myślenie o dwóch odrębnych aspektach kodu: **przepływ danych** (kanały, operatory, procesy i workflow) oraz **skryptowanie** (kod wewnątrz closures, funkcji i skryptów procesów). Choć to rozróżnienie jest nieco arbitralne—to wszystko jest kodem Nextflow—zapewnia użyteczny model mentalny do zrozumienia, kiedy orkiestrujesz pipeline, a kiedy manipulujesz danymi. Opanowanie obu dramatycznie poprawia zdolność pisania przejrzystych, łatwych w utrzymaniu workflow. + +### Cele szkolenia + +Ten side quest zabiera Cię w praktyczną podróż od podstawowych konceptów do wzorców gotowych do produkcji. +Przekształcimy prosty workflow odczytujący CSV w zaawansowany pipeline bioinformatyczny, rozwijając go krok po kroku przez realistyczne wyzwania: + +- **Zrozumienie granic:** Rozróżnienie między operacjami przepływu danych a skryptowaniem i zrozumienie, jak współpracują +- **Manipulacja danymi:** Wyodrębnianie, transformowanie i wybieranie podzbiorów map i kolekcji przy użyciu potężnych operatorów +- **Przetwarzanie ciągów znaków:** Parsowanie złożonych schematów nazewnictwa plików za pomocą wzorców regex i opanowanie interpolacji zmiennych +- **Funkcje wielokrotnego użytku:** Wyodrębnianie złożonej logiki do nazwanych funkcji dla czystszych, łatwiejszych w utrzymaniu workflow +- **Dynamiczna logika:** Budowanie procesów, które dostosowują się do różnych typów wejściowych i używanie closures do dynamicznej alokacji zasobów +- **Warunkowe kierowanie:** Inteligentne kierowanie próbek przez różne procesy na podstawie ich cech metadanych +- **Bezpieczne operacje:** Bezpieczna obsługa brakujących danych z operatorami bezpiecznymi względem null i walidacja wejść z czytelnymi komunikatami błędów +- **Obsługa zdarzeń oparta na konfiguracji:** Użycie handlerów zdarzeń workflow do logowania, powiadomień i zarządzania cyklem życia + +### Wymagania wstępne + +Przed przystąpieniem do tego side questa powinieneś: + +- Ukończyć tutorial [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Czuć się komfortowo z podstawowymi konceptami i mechanizmami Nextflow (procesy, kanały, operatory, praca z plikami, metadane) +- Mieć podstawową znajomość popularnych konstrukcji programistycznych (zmienne, mapy, listy) + +Ten tutorial wyjaśni koncepty programistyczne w miarę ich pojawiania się, więc nie potrzebujesz rozległego doświadczenia programistycznego. +Zaczniemy od fundamentalnych konceptów i zbudujemy zaawansowane wzorce. + +--- + +## 0. Rozpoczęcie + +#### Otwórz codespace szkoleniowy + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzysz środowisko szkoleniowe zgodnie z opisem w [Konfiguracja Środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki dla tego tutoriala. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Przejrzyj materiały + +Znajdziesz główny plik workflow oraz katalog `data` zawierający przykładowe pliki danych. + +```console title="Zawartość katalogu" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Nasz przykładowy CSV zawiera informacje o próbkach biologicznych wymagających różnego przetwarzania w zależności od ich charakterystyki: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Użyjemy tego realistycznego zbioru danych do eksploracji praktycznych technik programistycznych, z którymi spotkasz się w rzeczywistych workflow bioinformatycznych. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### Lista kontrolna gotowości + +Uważasz, że jesteś gotowy do zanurzenia się? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace jest uruchomiony +- [ ] Ustawiłem odpowiednio mój katalog roboczy +<!-- - [ ] I understand the assignment --> + +Jeśli możesz zaznaczyć wszystkie pola, możesz zacząć. + +--- + +## 1. Przepływ Danych vs Skryptowanie: Zrozumienie Granic + +### 1.1. Identyfikowanie Co Jest Czym + +Pisząc workflow w Nextflow, ważne jest rozróżnienie między **przepływem danych** (jak dane przemieszczają się przez kanały i procesy) a **skryptowaniem** (kodem, który manipuluje danymi i podejmuje decyzje). Zbudujmy workflow demonstrujący, jak współpracują. + +#### 1.1.1. Podstawowy Workflow Nextflow + +Zacznij od prostego workflow, który po prostu odczytuje plik CSV (już to zrobiliśmy dla Ciebie w `main.nf`): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +Blok `workflow` definiuje naszą strukturę pipeline, podczas gdy `channel.fromPath()` tworzy kanał ze ścieżki pliku. Operator `.splitCsv()` przetwarza plik CSV i konwertuje każdy wiersz w strukturę danych map. + +Uruchom ten workflow, aby zobaczyć surowe dane CSV: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Dodawanie Operatora Map + +Teraz dodamy skryptowanie do transformacji danych, używając operatora `.map()`, który prawdopodobnie już znasz. Ten operator przyjmuje 'closure', w którym możemy pisać kod do transformacji każdego elementu. + +!!! note "Uwaga" + + **Closure** to blok kodu, który może być przekazywany i wykonywany później. Pomyśl o tym jak o funkcji, którą definiujesz inline. Closures są zapisywane za pomocą nawiasów klamrowych `{ }` i mogą przyjmować parametry. Są fundamentalne dla działania operatorów Nextflow i jeśli od jakiegoś czasu piszesz w Nextflow, możliwe, że już ich używałeś, nie zdając sobie z tego sprawy! + +Oto jak wygląda ta operacja map: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +To nasze pierwsze **closure** - funkcja anonimowa, którą możesz przekazać jako argument (podobnie jak lambdy w Python lub funkcje strzałkowe w JavaScript). Closures są niezbędne do pracy z operatorami Nextflow. + +Closure `{ row -> return row }` przyjmuje parametr `row` (może być dowolna nazwa: `item`, `sample`, itp.). + +Gdy operator `.map()` przetwarza każdy element kanału, przekazuje ten element do Twojego closure. Tutaj `row` przechowuje jeden wiersz CSV na raz. + +Zastosuj tę zmianę i uruchom workflow: + +```bash +nextflow run main.nf +``` + +Zobaczysz to samo wyjście co poprzednio, ponieważ po prostu zwracamy wejście bez zmian. To potwierdza, że operator map działa poprawnie. Teraz zacznijmy transformować dane. + +#### 1.1.3. Tworzenie Struktury Danych Map + +Teraz napiszemy logikę **skryptowania** wewnątrz naszego closure, aby transformować każdy wiersz danych. To tutaj przetwarzamy pojedyncze elementy danych zamiast orkiestrować przepływ danych. + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Skryptowanie do transformacji danych + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +Mapa `sample_meta` to struktura danych klucz-wartość (jak słowniki w Python, obiekty w JavaScript lub hasze w Ruby) przechowująca powiązane informacje: ID próbki, organizm, typ tkanki, głębokość sekwencjonowania i wynik jakości. + +Używamy metod manipulacji ciągami znaków jak `.toLowerCase()` i `.replaceAll()` do czyszczenia naszych danych oraz metod konwersji typów jak `.toInteger()` i `.toDouble()` do konwersji danych tekstowych z CSV na odpowiednie typy numeryczne. + +Zastosuj tę zmianę i uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Dodawanie Logiki Warunkowej + +Teraz dodajmy więcej skryptowania - tym razem używając operatora ternarnego do podejmowania decyzji na podstawie wartości danych. + +Wprowadź następującą zmianę: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +Operator ternarny to skrót dla instrukcji if/else zgodnie ze wzorcem `warunek ? wartość_jeśli_prawda : wartość_jeśli_fałsz`. Ta linia oznacza: "Jeśli jakość jest większa niż 40, użyj 'high', w przeciwnym razie użyj 'normal'". Jego kuzyn, **operator Elvis** (`?:`), zapewnia wartości domyślne, gdy coś jest null lub puste - zbadamy ten wzorzec później w tym tutorialu. + +Operator dodawania map `+` tworzy **nową mapę** zamiast modyfikować istniejącą. Ta linia tworzy nową mapę zawierającą wszystkie pary klucz-wartość z `sample_meta` plus nowy klucz `priority`. + +!!! Note "Uwaga" + + Nigdy nie modyfikuj map przekazanych do closures - zawsze twórz nowe używając `+` (na przykład). W Nextflow te same dane często przepływają przez wiele operacji jednocześnie. Modyfikowanie mapy w miejscu może powodować nieprzewidywalne efekty uboczne, gdy inne operacje odwołują się do tego samego obiektu. Tworzenie nowych map zapewnia, że każda operacja ma własną czystą kopię. + +Uruchom zmodyfikowany workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Pomyślnie dodaliśmy logikę warunkową do wzbogacenia naszych metadanych o poziom priorytetu oparty na wynikach jakości. + +#### 1.1.5. Wybieranie Podzbiorów Map za pomocą `.subMap()` + +Podczas gdy operator `+` dodaje klucze do mapy, czasami musisz zrobić coś odwrotnego - wyodrębnić tylko określone klucze. Metoda `.subMap()` jest do tego idealna. + +Dodajmy linię tworzącą uproszczoną wersję naszych metadanych zawierającą tylko pola identyfikacyjne: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Skryptowanie do transformacji danych + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Tylko pola ID: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Skryptowanie do transformacji danych + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Uruchom zmodyfikowany workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Tylko pola ID: [id:sample_001, organism:human, tissue:liver] + Tylko pola ID: [id:sample_002, organism:mouse, tissue:brain] + Tylko pola ID: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +To pokazuje zarówno pełne metadane wyświetlone przez operację `view()`, jak i wyodrębniony podzbiór, który wydrukowaliśmy za pomocą `println`. + +Metoda `.subMap()` przyjmuje listę kluczy i zwraca nową mapę zawierającą tylko te klucze. Jeśli klucz nie istnieje w oryginalnej mapie, po prostu nie jest uwzględniany w wyniku. + +Jest to szczególnie przydatne, gdy musisz tworzyć różne wersje metadanych dla różnych procesów - niektóre mogą potrzebować pełnych metadanych, podczas gdy inne potrzebują tylko minimalnych pól identyfikacyjnych. + +Teraz usuń te instrukcje println, aby przywrócić workflow do poprzedniego stanu, ponieważ nie będą nam potrzebne dalej. + +!!! tip "Podsumowanie Operacji na Mapach" + + - **Dodawanie kluczy**: `map1 + [new_key: value]` - Tworzy nową mapę z dodatkowymi kluczami + - **Wyodrębnianie kluczy**: `map1.subMap(['key1', 'key2'])` - Tworzy nową mapę z tylko określonymi kluczami + - **Obie operacje tworzą nowe mapy** - Oryginalne mapy pozostają niezmienione + +#### 1.1.6. Łączenie Map i Zwracanie Wyników + +Do tej pory zwracaliśmy tylko to, co społeczność Nextflow nazywa 'meta map', i ignorowaliśmy pliki, do których te metadane się odnoszą. Ale jeśli piszesz workflow w Nextflow, prawdopodobnie chcesz coś zrobić z tymi plikami. + +Wyprowadźmy strukturę kanału składającą się z krotki 2 elementów: wzbogaconej mapy metadanych i odpowiadającej ścieżki pliku. Jest to powszechny wzorzec w Nextflow do przekazywania danych do procesów. + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Zastosuj tę zmianę i uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Ta struktura krotki `[meta, file]` to powszechny wzorzec w Nextflow do przekazywania zarówno metadanych, jak i powiązanych plików do procesów. + +!!! note "Uwaga" + + **Mapy i Metadane**: Mapy są fundamentalne dla pracy z metadanymi w Nextflow. Bardziej szczegółowe wyjaśnienie pracy z mapami metadanych znajdziesz w side queście [Praca z metadanymi](./metadata.md). + +Nasz workflow demonstruje główny wzorzec: **operacje przepływu danych** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orkiestrują, jak dane przemieszczają się przez pipeline, podczas gdy **skryptowanie** (mapy `[key: value]`, metody na ciągach znaków, konwersje typów, operatory ternarne) wewnątrz closure `.map()` obsługuje transformację poszczególnych elementów danych. + +### 1.2. Zrozumienie Różnych Typów: Channel vs List + +Do tej pory wszystko dobrze, możemy rozróżnić operacje przepływu danych od skryptowania. Ale co z przypadkiem, gdy ta sama nazwa metody istnieje w obu kontekstach? + +Doskonałym przykładem jest metoda `collect`, która istnieje zarówno dla typów kanałów, jak i typów List w bibliotece standardowej Nextflow. Metoda `collect()` na List transformuje każdy element, podczas gdy operator `collect()` na kanale zbiera wszystkie emisje kanału w kanał jednoelementowy. + +Zademonstrujmy to na przykładowych danych, zaczynając od odświeżenia wiedzy o tym, co robi operator `collect()` na kanale. Sprawdź `collect.nf`: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - grupuje wiele emisji kanału w jedną +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Pojedynczy element kanału: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "wynik channel.collect(): ${list} (${list.size()} elementów zgrupowanych w 1)" } +``` + +Kroki: + +- Definiujemy listę ID próbek +- Tworzymy kanał za pomocą `fromList()`, który emituje każde ID próbki osobno +- Drukujemy każdy element za pomocą `view()` w miarę przepływu +- Zbieramy wszystkie elementy w jedną listę za pomocą operatora `collect()` kanału +- Drukujemy zebrany wynik (pojedynczy element zawierający wszystkie ID próbek) za pomocą drugiego `view()` + +Zmieniliśmy strukturę kanału, ale nie zmieniliśmy samych danych. + +Uruchom workflow, aby to potwierdzić: + +```bash +nextflow run collect.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Pojedynczy element kanału: sample_001 + Pojedynczy element kanału: sample_002 + Pojedynczy element kanału: sample_003 + wynik channel.collect(): [sample_001, sample_002, sample_003] (3 elementów zgrupowanych w 1) + ``` + +`view()` zwraca wyjście dla każdej emisji kanału, więc wiemy, że to pojedyncze wyjście zawiera wszystkie 3 oryginalne elementy zgrupowane w jedną listę. + +Teraz zobaczmy metodę `collect` na List w akcji. Zmodyfikuj `collect.nf`, aby zastosować metodę `collect` List do oryginalnej listy ID próbek: + +=== "Po" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - grupuje wiele emisji kanału w jedną + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Pojedynczy element kanału: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "wynik channel.collect(): ${list} (${list.size()} elementów zgrupowanych w 1)" } + + // List.collect() - transformuje każdy element, zachowuje strukturę + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "wynik List.collect(): ${formatted_ids} (${sample_ids.size()} elementów przekształconych w ${formatted_ids.size()})" + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - grupuje wiele emisji kanału w jedną + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Pojedynczy element kanału: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "wynik channel.collect(): ${list} (${list.size()} elementów zgrupowanych w 1)" } + ``` + +W tym nowym fragmencie: + +- Definiujemy nową zmienną `formatted_ids`, która używa metody `collect` List do transformacji każdego ID próbki w oryginalnej liście +- Drukujemy wynik używając `println` + +Uruchom zmodyfikowany workflow: + +```bash +nextflow run collect.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + wynik List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementów przekształconych w 3) + Pojedynczy element kanału: sample_001 + Pojedynczy element kanału: sample_002 + Pojedynczy element kanału: sample_003 + wynik channel.collect(): [sample_001, sample_002, sample_003] (3 elementów zgrupowanych w 1) + ``` + +Tym razem NIE zmieniliśmy struktury danych, wciąż mamy 3 elementy na liście, ale przekształciliśmy każdy element używając metody `collect` List, aby uzyskać nową listę ze zmodyfikowanymi wartościami. To podobne do użycia operatora `map` na kanale, ale operuje na strukturze danych List zamiast na kanale. + +`collect` to ekstremalny przypadek, którego używamy tutaj, aby podkreślić punkt. Kluczową lekcją jest to, że pisząc workflow, zawsze rozróżniaj między **strukturami danych** (Lists, Maps, itp.) a **kanałami** (konstrukcje przepływu danych). Operacje mogą mieć te same nazwy, ale zachowują się zupełnie inaczej w zależności od typu, na którym są wywoływane. + +### 1.3. Operator Rozprzestrzeniania (`*.`) - Skrót do Wyodrębniania Właściwości + +Powiązany z metodą `collect` List jest operator rozprzestrzeniania (`*.`), który zapewnia zwięzły sposób wyodrębniania właściwości z kolekcji. Jest to zasadniczo syntaktyczny cukier dla powszechnego wzorca `collect`. + +Dodajmy demonstrację do naszego pliku `collect.nf`: + +=== "Po" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - grupuje wiele emisji kanału w jedną + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Pojedynczy element kanału: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "wynik channel.collect(): ${list} (${list.size()} elementów zgrupowanych w 1)" } + + // List.collect() - transformuje każdy element, zachowuje strukturę + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "wynik List.collect(): ${formatted_ids} (${sample_ids.size()} elementów przekształconych w ${formatted_ids.size()})" + + // Operator rozprzestrzeniania - zwięzły dostęp do właściwości + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Wynik operatora rozprzestrzeniania: ${all_ids}" + ``` + +=== "Przed" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - grupuje wiele emisji kanału w jedną + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Pojedynczy element kanału: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "wynik channel.collect(): ${list} (${list.size()} elementów zgrupowanych w 1)" } + + // List.collect() - transformuje każdy element, zachowuje strukturę + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "wynik List.collect(): ${formatted_ids} (${sample_ids.size()} elementów przekształconych w ${formatted_ids.size()})" + ``` + +Uruchom zaktualizowany workflow: + +```bash title="Testuj operator rozprzestrzeniania" +nextflow run collect.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + wynik List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 elementów przekształconych w 3) + Wynik operatora rozprzestrzeniania: [s1, s2, s3] + Pojedynczy element kanału: sample_001 + Pojedynczy element kanału: sample_002 + Pojedynczy element kanału: sample_003 + wynik channel.collect(): [sample_001, sample_002, sample_003] (3 elementów zgrupowanych w 1) + ``` + +Operator rozprzestrzeniania `*.` jest skrótem dla powszechnego wzorca collect: + +```groovy +// Są równoważne: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Działa również z wywołaniami metod: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +Operator rozprzestrzeniania jest szczególnie przydatny, gdy musisz wyodrębnić pojedynczą właściwość z listy obiektów - jest bardziej czytelny niż pisanie pełnego closure `collect`. + +!!! tip "Kiedy Używać Spread vs Collect" + + - **Użyj spread (`*.`)** do prostego dostępu do właściwości: `samples*.id`, `files*.name` + - **Użyj collect** do transformacji lub złożonej logiki: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Wnioski + +W tej sekcji nauczyłeś się: + +- **Przepływ danych vs skryptowanie**: Operatory kanałów orkiestrują, jak dane przepływają przez Twój pipeline, podczas gdy skryptowanie transformuje poszczególne elementy danych +- **Zrozumienie typów**: Ta sama nazwa metody (jak `collect`) może zachowywać się inaczej w zależności od typu, na którym jest wywoływana (Channel vs List) +- **Kontekst ma znaczenie**: Zawsze bądź świadomy, czy pracujesz z kanałami (przepływ danych) czy strukturami danych (skryptowanie) + +Zrozumienie tych granic jest niezbędne do debugowania, dokumentacji i pisania łatwych w utrzymaniu workflow. + +Następnie zagłębimy się w możliwości przetwarzania ciągów znaków, które są niezbędne do obsługi rzeczywistych danych. + +--- + +## 2. Przetwarzanie Ciągów Znaków i Dynamiczne Generowanie Skryptów + +Opanowanie przetwarzania ciągów znaków oddziela kruche workflow od solidnych pipelineów. Ta sekcja obejmuje parsowanie złożonych nazw plików, dynamiczne generowanie skryptów i interpolację zmiennych. + +### 2.1. Dopasowywanie Wzorców i Wyrażenia Regularne + +Pliki bioinformatyczne często mają złożone konwencje nazewnictwa kodujące metadane. Wyodrębnijmy to automatycznie używając dopasowywania wzorców z wyrażeniami regularnymi. + +Wrócimy do naszego workflow `main.nf` i dodamy logikę dopasowywania wzorców, aby wyodrębnić dodatkowe informacje o próbkach z nazw plików. Pliki FASTQ w naszym zbiorze danych podążają za konwencjami nazewnictwa Illumina z nazwami jak `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Mogą wyglądać enigmatycznie, ale faktycznie kodują użyteczne metadane jak ID próbki, numer pasa i kierunek odczytu. Użyjemy możliwości regex do parsowania tych nazw. + +Wprowadź następującą zmianę do istniejącego workflow `main.nf`: + +=== "Po" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Skryptowanie do transformacji danych + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Skryptowanie do transformacji danych + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +To demonstruje kluczowe **koncepty przetwarzania ciągów znaków**: + +1. **Literały wyrażeń regularnych** używające składni `~/wzorzec/` - tworzy wzorzec regex bez konieczności escape'owania ukośników odwrotnych +2. **Dopasowywanie wzorców** z operatorem `=~` - próbuje dopasować ciąg znaków do wzorca regex +3. **Obiekty matcher**, które przechwytują grupy z `[0][1]`, `[0][2]`, itd. - `[0]` odnosi się do całego dopasowania, `[1]`, `[2]`, itd. odnoszą się do przechwyconych grup w nawiasach + +Przeanalizujmy wzorzec regex `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$`: + +| Wzorzec | Dopasowuje | Przechwytuje | +| ------------------- | ------------------------------------------- | ------------------------------------- | +| `^(.+)` | Nazwa próbki od początku | Grupa 1: nazwa próbki | +| `_S(\d+)` | Numer próbki `_S1`, `_S2`, itd. | Grupa 2: numer próbki | +| `_L(\d{3})` | Numer pasa `_L001` | Grupa 3: pas (3 cyfry) | +| `_(R[12])` | Kierunek odczytu `_R1` lub `_R2` | Grupa 4: kierunek odczytu | +| `_(\d{3})` | Numer fragmentu `_001` | Grupa 5: fragment (3 cyfry) | +| `\.fastq(?:\.gz)?$` | Rozszerzenie pliku `.fastq` lub `.fastq.gz` | Nieprzechwycone (?: to non-capturing) | + +To parsuje konwencje nazewnictwa Illumina, aby automatycznie wyodrębnić metadane. + +Uruchom zmodyfikowany workflow: + +```bash title="Testuj dopasowywanie wzorców" +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +To pokazuje metadane wzbogacone z nazw plików. + +### 2.2. Dynamiczne Generowanie Skryptów w Procesach + +Bloki skryptowe procesów są zasadniczo wieloliniowymi ciągami znaków, które są przekazywane do powłoki. Możesz używać **logiki warunkowej** (if/else, operatory ternarne) do dynamicznego generowania różnych ciągów skryptowych na podstawie charakterystyki wejścia. Jest to niezbędne do obsługi różnych typów wejściowych—jak odczyty single-end vs paired-end—bez duplikowania definicji procesów. + +Dodajmy proces do naszego workflow, który demonstruje ten wzorzec. Otwórz `modules/fastp.nf` i spójrz: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Proces przyjmuje pliki FASTQ jako wejście i uruchamia narzędzie `fastp` do przycinania adapterów i filtrowania odczytów niskiej jakości. Niestety, osoba, która napisała ten proces, nie uwzględniła odczytów single-end, które mamy w naszym przykładowym zbiorze danych. Dodajmy go do naszego workflow i zobaczmy, co się stanie: + +Najpierw dołącz moduł w samej pierwszej linii Twojego workflow `main.nf`: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Następnie zmodyfikuj blok `workflow`, aby połączyć kanał `ch_samples` z procesem `FASTP`: + +=== "Po" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Uruchom ten zmodyfikowany workflow: + +```bash +nextflow run main.nf +``` + +??? failure "Wyjście polecenia" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Widać, że proces próbuje uruchomić `fastp` z wartością `null` dla drugiego pliku wejściowego, co powoduje błąd. Dzieje się tak, ponieważ nasz zbiór danych zawiera odczyty single-end, ale proces jest zakodowany na stałe do oczekiwania odczytów paired-end (dwa pliki wejściowe na raz). + +Napraw to, dodając logikę warunkową do bloku `script:` procesu `FASTP`. Instrukcja if/else sprawdza liczbę plików odczytowych i odpowiednio dostosowuje polecenie. + +=== "Po" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Proste wykrywanie single-end vs paired-end + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Teraz workflow może płynnie obsługiwać zarówno odczyty single-end, jak i paired-end. Logika warunkowa sprawdza liczbę plików wejściowych i konstruuje odpowiednie polecenie dla `fastp`. Zobaczmy, czy działa: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +Wygląda dobrze! Jeśli sprawdzimy faktyczne polecenia, które zostały uruchomione (dostosuj dla swojego hasha zadania): + +```console title="Sprawdź wykonane polecenia" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Możemy zobaczyć, że Nextflow poprawnie wybrał właściwe polecenie dla odczytów single-end: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Inne powszechne zastosowanie dynamicznej logiki skryptowej można zobaczyć w [module Genomics kursu Nextflow for Science](../../nf4science/genomics/02_joint_calling). W tym module wywoływany proces GATK może przyjmować wiele plików wejściowych, ale każdy musi być poprzedzony `-V`, aby utworzyć poprawną linię poleceń. Proces używa skryptowania do transformacji kolekcji plików wejściowych (`all_gvcfs`) w poprawne argumenty polecenia: + +```groovy title="manipulacja linią poleceń dla GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Te wzorce używania skryptowania w blokach skryptowych procesów są niezwykle potężne i mogą być zastosowane w wielu scenariuszach - od obsługi zmiennych typów wejściowych po budowanie złożonych argumentów linii poleceń z kolekcji plików, czyniąc Twoje procesy naprawdę adaptacyjnymi do różnorodnych wymagań rzeczywistych danych. + +### 2.3. Interpolacja Zmiennych: Zmienne Nextflow i Shell + +Skrypty procesów mieszają zmienne Nextflow, zmienne powłoki i podstawienia poleceń, każde z inną składnią interpolacji. Użycie niewłaściwej składni powoduje błędy. Przeanalizujmy to na procesie tworzącym raport przetwarzania. + +Spójrz na plik modułu `modules/generate_report.nf`: + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Przetwarzanie ${reads}" > ${meta.id}_report.txt + echo "Próbka: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Ten proces zapisuje prosty raport z ID próbki i nazwą pliku. Teraz uruchommy go, aby zobaczyć, co się dzieje, gdy musimy mieszać różne typy zmiennych. + +Dołącz proces w swoim `main.nf` i dodaj go do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +Teraz uruchom workflow i sprawdź wygenerowane raporty w `results/reports/`. Powinny zawierać podstawowe informacje o każdej próbce. + +<!-- TODO: add the run command --> + +??? success "Wyjście polecenia" + + ```console + <!-- TODO: output --> + ``` + +Ale co, jeśli chcemy dodać informacje o tym, kiedy i gdzie przetwarzanie miało miejsce? Z diff --git a/docs/pl/docs/side_quests/ideas/containers.md b/docs/pl/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..2cb92ac41c --- /dev/null +++ b/docs/pl/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Część 1: Więcej o kontenerach + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Jak znaleźć lub stworzyć obrazy kontenerów + +Niektórzy twórcy oprogramowania udostępniają obrazy kontenerów dla swojego oprogramowania w rejestrach kontenerów, takich jak Docker Hub, ale wielu tego nie robi. +W tej opcjonalnej sekcji pokażemy Ci dwa sposoby na uzyskanie obrazu kontenera dla narzędzi, których chcesz użyć w swoich potokach Nextflow: za pomocą Seqera Containers oraz samodzielne budowanie obrazu kontenera. + +Będziesz uzyskiwać/budować obraz kontenera dla pakietu pip `quote`, który zostanie użyty w ćwiczeniu na końcu tej sekcji. + +### 1.1. Uzyskaj obraz kontenera z Seqera Containers + +Seqera Containers to darmowa usługa, która buduje obrazy kontenerów dla narzędzi instalowanych przez pip i conda (w tym bioconda). +Przejdź do [Seqera Containers](https://www.seqera.io/containers/) i wyszukaj pakiet pip `quote`. + +![Seqera Containers](img/seqera-containers-1.png) + +Kliknij "+Add", a następnie "Get Container", aby zażądać obrazu kontenera dla pakietu pip `quote`. + +![Seqera Containers](img/seqera-containers-2.png) + +Jeśli po raz pierwszy budowany jest kontener społecznościowy dla tej wersji pakietu, może to potrwać kilka minut. +Kliknij, aby skopiować URI (np. `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) utworzonego dla Ciebie obrazu kontenera. + +Możesz teraz użyć obrazu kontenera, aby uruchomić polecenie `quote` i uzyskać losowe powiedzenie Grace Hopper. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Wyjście: + +```console title="Wyjście" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Zbuduj obraz kontenera samodzielnie + +Wykorzystajmy szczegóły budowy ze strony Seqera Containers, aby samodzielnie zbudować obraz kontenera dla pakietu pip `quote`. +Wróć na stronę Seqera Containers i kliknij przycisk "Build Details". + +Pierwszym elementem, na który spojrzymy, jest `Dockerfile`, rodzaj pliku skryptu zawierającego wszystkie polecenia potrzebne do zbudowania obrazu kontenera. +Dodaliśmy wyjaśniające komentarze do poniższego Dockerfile, aby pomóc Ci zrozumieć, co robi każda część. + +```Dockerfile title="Dockerfile" +# Zacznij od bazowego obrazu docker micromamba +FROM mambaorg/micromamba:1.5.10-noble +# Skopiuj plik conda.yml do kontenera +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Zainstaluj różne narzędzia dla Nextflow oraz pakiety z pliku conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Uruchom kontener jako użytkownik root +USER root +# Ustaw zmienną środowiskową PATH tak, aby zawierała katalog instalacji micromamba +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +Drugim elementem, na który spojrzymy, jest plik `conda.yml`, który zawiera listę pakietów, które należy zainstalować w obrazie kontenera. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Skopiuj zawartość tych plików do zaślepek znajdujących się w katalogu `containers/build`, następnie uruchom poniższe polecenie, aby samodzielnie zbudować obraz kontenera. + +!!! note "Uwaga" + + Używamy flagi `-t quote:latest`, aby oznaczyć obraz kontenera nazwą `quote` i tagiem `latest`. + Będziemy mogli użyć tego tagu do odwoływania się do obrazu kontenera podczas uruchamiania go w tym systemie. + +```bash +docker build -t quote:latest containers/build +``` + +Po zakończeniu budowania możesz uruchomić właśnie zbudowany obraz kontenera. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Podsumowanie + +Nauczyłeś się dwóch różnych sposobów uzyskiwania obrazu kontenera dla narzędzia, którego chcesz użyć w swoich potokach Nextflow: za pomocą Seqera Containers oraz samodzielnego budowania obrazu kontenera. + +### Co dalej? + +Masz wszystko, czego potrzebujesz, aby przejść do [następnego rozdziału](./04_hello_genomics.md) tej serii szkoleniowej. +Możesz również kontynuować opcjonalne ćwiczenie, aby pobierać cytaty pionierów informatyki/biologii za pomocą kontenera `quote` i wyświetlać je za pomocą kontenera `cowsay`. + +--- + +## 2. Spraw, aby krowa cytowała słynnych naukowców + +Ta sekcja zawiera dodatkowe ćwiczenia, aby przećwiczyć to, czego się dotychczas nauczyłeś. +Wykonanie tych ćwiczeń _nie jest wymagane_ do zrozumienia późniejszych części szkolenia, ale stanowi zabawny sposób na utrwalenie swojej wiedzy poprzez wymyślenie, jak sprawić, aby krowa cytowała słynnych naukowców. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Zmodyfikuj skrypt `hello-containers.nf`, aby używał procesu getQuote + +Mamy listę pionierów informatyki i biologii w pliku `containers/data/pioneers.csv`. +Na wysokim poziomie, aby ukończyć to ćwiczenie, musisz: + +- Zmodyfikować domyślny `params.input_file`, aby wskazywał na plik `pioneers.csv`. +- Utworzyć proces `getQuote`, który używa kontenera `quote` do pobierania cytatu dla każdego wejścia. +- Połączyć wyjście procesu `getQuote` z procesem `cowsay`, aby wyświetlić cytat. + +Dla obrazu kontenera `quote` możesz użyć tego, który zbudowałeś samodzielnie w poprzednim dodatkowym ćwiczeniu lub tego, który uzyskałeś z Seqera Containers. + +!!! tip "Wskazówka" + + Dobrym wyborem dla bloku `script` Twojego procesu getQuote może być: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Rozwiązanie tego ćwiczenia znajdziesz w pliku `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Zmodyfikuj swój potok Nextflow, aby umożliwić jego wykonanie w trybach `quote` i `sayHello`. + +Dodaj logikę rozgałęzienia do swojego potoku, aby umożliwić mu akceptowanie wejść przeznaczonych zarówno dla `quote`, jak i `sayHello`. +Oto przykład użycia instrukcji `if` w workflow Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "Wskazówka" + + Możesz użyć `new_ch = processName.out`, aby przypisać nazwę do kanału wyjściowego procesu. + +Rozwiązanie tego ćwiczenia znajdziesz w pliku `containers/solutions/hello-containers-4.2.nf`. + +### Podsumowanie + +Wiesz już, jak używać kontenerów w Nextflow do uruchamiania procesów oraz jak zbudować logikę rozgałęzienia w swoich potokach! + +### Co dalej? + +Świętuj, zrób sobie przerwę na rozciąganie i wypij trochę wody! + +Kiedy będziesz gotowy, przejdź do Części 3 tej serii szkoleniowej, aby dowiedzieć się, jak zastosować to, czego się dotychczas nauczyłeś, do bardziej realistycznego przypadku analizy danych. diff --git a/docs/pl/docs/side_quests/ideas/if_else.md b/docs/pl/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..594a6809e4 --- /dev/null +++ b/docs/pl/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Część 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Spraw, aby krowa cytowała słynnych naukowców + +Ta sekcja zawiera dodatkowe ćwiczenia pozwalające na utrwalenie dotychczas zdobytej wiedzy. +Wykonanie tych ćwiczeń _nie jest wymagane_ do zrozumienia późniejszych części szkolenia, ale stanowi świetny sposób na utrwalenie wiedzy poprzez sprawdzenie, jak sprawić, aby krowa cytowała słynnych naukowców. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Zmodyfikuj skrypt `hello-containers.nf`, aby używał procesu getQuote + +Mamy listę pionierów informatyki i biologii w pliku `containers/data/pioneers.csv`. +Na wysokim poziomie, aby wykonać to ćwiczenie, będziesz musiał: + +- Zmodyfikować domyślny `params.input_file`, aby wskazywał na plik `pioneers.csv`. +- Utworzyć proces `getQuote`, który używa kontenera `quote` do pobrania cytatu dla każdego wejścia. +- Połączyć wyjście procesu `getQuote` z procesem `cowsay`, aby wyświetlić cytat. + +Dla obrazu kontenera `quote` możesz użyć albo tego, który sam zbudowałeś w poprzednim dodatkowym ćwiczeniu, albo tego z Seqera Containers. + +!!! Hint + + Dobrym wyborem dla bloku `script` Twojego procesu getQuote może być: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Rozwiązanie tego ćwiczenia znajdziesz w pliku `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Zmodyfikuj swój pipeline Nextflow, aby mógł wykonywać się w trybach `quote` i `sayHello`. + +Dodaj logikę rozgałęzień do swojego pipeline, aby mógł akceptować dane wejściowe przeznaczone zarówno dla `quote`, jak i `sayHello`. +Oto przykład użycia instrukcji `if` w workflow Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + Możesz użyć `new_ch = processName.out`, aby przypisać nazwę do kanału wyjściowego procesu. + +Rozwiązanie tego ćwiczenia znajdziesz w pliku `containers/solutions/hello-containers-4.2.nf`. + +### Podsumowanie + +Wiesz już, jak używać kontenerów w Nextflow do uruchamiania procesów oraz jak budować logikę rozgałęzień w swoich pipeline! + +### Co dalej? + +Świętuj, zrób sobie przerwę na rozciąganie i napij się wody! + +Kiedy będziesz gotowy, przejdź do Części 3 tej serii szkoleniowej, aby nauczyć się, jak zastosować dotychczas zdobytą wiedzę do bardziej realistycznego przypadku analizy danych. diff --git a/docs/pl/docs/side_quests/index.md b/docs/pl/docs/side_quests/index.md new file mode 100644 index 0000000000..93e58300f4 --- /dev/null +++ b/docs/pl/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: Zadania Poboczne +hide: + - toc +--- + +# Zadania Poboczne + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +To zbiór samodzielnych mini-kursów szkoleniowych, które zagłębiają się w konkretne tematy. Możesz przejść przez nie w dowolnej kolejności. + +Zaczynajmy! Kliknij przycisk "Open in GitHub Codespaces" poniżej, aby uruchomić środowisko szkoleniowe (najlepiej w osobnej karcie), a następnie czytaj dalej, podczas gdy się ładuje. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Wymagania wstępne + +Konkretne wymagania wstępne dla każdego mini-kursu różnią się i są udokumentowane na odpowiednich stronach. +Niemniej jednak wszystkie zakładają pewną minimalną znajomość następujących zagadnień: + +- Doświadczenie z linią poleceń +- Podstawowe pojęcia i narzędzia Nextflow omówione w kursie szkoleniowym dla początkujących [Hello Nextflow](../../hello_nextflow/). + +Wymagania techniczne i konfigurację środowiska znajdziesz w mini-kursie [Konfiguracja Środowiska](../../envsetup/). + +**Jeśli po raz pierwszy zagłębiasz się w Zadania Poboczne, upewnij się, że najpierw sprawdziłeś stronę [Orientacja](./orientation.md)!** + +W przeciwnym razie wybierz zadanie poboczne z poniższej tabeli. + +## Zadania Poboczne + +| Zadanie Poboczne | Szacowany Czas Nauczania | +| ------------------------------------------------------------------------------ | ------------------------ | +| [Przegląd środowiska programistycznego Nextflow](./ide_features.md) | 45 min | +| [Podstawowe Wzorce Skryptowania w Nextflow](./essential_scripting_patterns.md) | 90 min | +| [Metadane w przepływach pracy](./metadata.md) | 45 min | +| [Dzielenie i Grupowanie](./splitting_and_grouping.md) | 45 min | +| [Testowanie za pomocą nf-test](./nf-test.md) | 1 godzina | +| [Przepływy pracy złożone z przepływów pracy](./workflows_of_workflows.md) | 30 min | +| [Praca z plikami](./working_with_files.md) | 45 min | +| [Debugowanie przepływów pracy](./debugging.md) | 1 godzina | + +Daj nam znać, jakie inne dziedziny i przypadki użycia chciałbyś zobaczyć tutaj, publikując post w [sekcji Szkolenia](https://community.seqera.io/c/training/) na forum społeczności. diff --git a/docs/pl/docs/side_quests/metadata.md b/docs/pl/docs/side_quests/metadata.md new file mode 100644 index 0000000000..cff3c1c16e --- /dev/null +++ b/docs/pl/docs/side_quests/metadata.md @@ -0,0 +1,1195 @@ +# Metadane i mapy meta + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +W każdej analizie naukowej rzadko pracujemy jedynie z surowymi plikami danych. +Każdy plik zawiera dodatkowe informacje: czym jest, skąd pochodzi i co go wyróżnia. +Te dodatkowe informacje nazywamy metadanymi. + +Metadane to dane opisujące inne dane. +Metadane śledzą ważne szczegóły dotyczące plików i warunków eksperymentalnych oraz pomagają dostosować analizy do unikalnych cech każdego zestawu danych. + +Pomyśl o tym jak o katalogu bibliotecznym: podczas gdy książki zawierają faktyczną treść (surowe dane), karty katalogowe dostarczają istotnych informacji o każdej książce — kiedy została opublikowana, kto ją napisał, gdzie ją znaleźć (metadane). +W pipeline'ach Nextflow metadane mogą być wykorzystywane do: + +- Śledzenia informacji specyficznych dla pliku w całym workflow +- Konfigurowania procesów na podstawie cech pliku +- Grupowania powiązanych plików do wspólnej analizy + +### Cele edukacyjne + +W tym side queście zbadamy sposób obsługi metadanych w workflow. +Zaczynając od prostej tabeli danych (często nazywanej samplesheet w bioinformatyce) zawierającej podstawowe informacje o plikach, nauczysz się jak: + +- Odczytywać i analizować metadane plików z plików CSV +- Tworzyć i manipulować mapami metadanych +- Dodawać nowe pola metadanych podczas wykonywania workflow +- Wykorzystywać metadane do dostosowywania zachowania procesów + +Te umiejętności pomogą Ci tworzyć bardziej solidne i elastyczne pipeline'y, które potrafią obsługiwać złożone relacje między plikami i wymagania przetwarzania. + +### Wymagania wstępne + +Przed rozpoczęciem tego side questu powinieneś: + +- Ukończyć kurs [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Swobodnie posługiwać się podstawowymi koncepcjami i mechanizmami Nextflow (procesy, kanały, operatory) + +--- + +## 0. Rozpocznij pracę + +#### Otwórz środowisko szkoleniowe codespace + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzysz środowisko szkoleniowe zgodnie z opisem w [Konfiguracja środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki do tego kursu. + +```bash +cd side-quests/metadata +``` + +Możesz ustawić VSCode, aby skupił się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz główny plik workflow oraz katalog `data` zawierający tabelę danych i kilka plików danych. + +??? abstract "Zawartość katalogu" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +Workflow w pliku `main.nf` to szablon, który stopniowo rozwiniesz w w pełni funkcjonujący workflow. + +Tabela danych zawiera ścieżki do plików danych i powiązane metadane, zorganizowane w 3 kolumnach: + +- `id`: oczywiste, ID nadane plikowi +- `character`: nazwa postaci, której użyjemy później do rysowania różnych stworzeń +- `data`: ścieżki do plików `.txt`, które zawierają pozdrowienia w różnych językach + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Każdy plik danych zawiera tekst powitania w jednym z pięciu języków (fr: francuski, de: niemiecki, es: hiszpański, it: włoski, en: angielski). + +Dostarczymy Ci również konteneryzowane narzędzie do analizy języka o nazwie `langid`. + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest napisanie workflow Nextflow, który: + +1. **Zidentyfikuje** język w każdym pliku automatycznie +2. **Zgrupuje** pliki według rodziny językowej (języki germańskie kontra języki romańskie) +3. **Dostosuje** przetwarzanie dla każdego pliku na podstawie jego języka i metadanych +4. **Zorganizuje** wyjścia według grupy językowej + +To reprezentuje typowy wzorzec workflow, gdzie metadane specyficzne dla pliku sterują decyzjami dotyczącymi przetwarzania; dokładnie taki rodzaj problemu, który mapy metadanych rozwiązują elegancko. + +#### Lista kontrolna gotowości + +Myślisz, że jesteś gotowy, aby się zagłębić? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace jest uruchomiony +- [ ] Ustawiłem odpowiednio mój katalog roboczy +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +--- + +## 1. Wczytaj metadane z tabeli danych + +Otwórz plik workflow `main.nf`, aby przeanalizować szablon workflow, który dajemy Ci jako punkt wyjścia. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Możesz zobaczyć, że skonfigurowaliśmy podstawową fabrykę kanałów, aby wczytać przykładową tabelę danych jako plik, ale to jeszcze nie odczyta zawartości pliku. +Zacznijmy od dodania tego. + +### 1.1. Odczytaj zawartość za pomocą `splitCsv` + +Musimy wybrać operator, który odpowiednio zanalizuje zawartość pliku przy minimalnym wysiłku z naszej strony. +Ponieważ nasza tabela danych jest w formacie CSV, jest to zadanie dla operatora [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv), który wczytuje każdy wiersz w pliku jako element w kanale. + +Wprowadź następujące zmiany, aby dodać operację `splitCsv()` do kodu konstrukcji kanału, plus operację `view()`, aby sprawdzić, czy zawartość pliku jest poprawnie wczytywana do kanału. + +=== "Po" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Zauważ, że używamy opcji `header: true`, aby powiedzieć Nextflow, aby odczytał pierwszy wiersz pliku CSV jako wiersz nagłówka. + +Zobaczmy, co z tego wychodzi, dobrze? +Uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Możemy zobaczyć, że operator skonstruował mapę par klucz-wartość dla każdego wiersza w pliku CSV, z nagłówkami kolumn jako kluczami dla odpowiadających wartości. + +Każdy wpis mapy odpowiada kolumnie w naszej tabeli danych: + +- `id` +- `character` +- `recording` + +To jest świetne! Ułatwia to dostęp do określonych pól z każdego pliku. +Na przykład moglibyśmy uzyskać dostęp do ID pliku za pomocą `id` lub ścieżki do pliku txt za pomocą `recording`. + +??? info "(Opcjonalnie) Więcej o mapach" + + W Groovy, języku programowania, na którym zbudowany jest Nextflow, mapa to struktura danych klucz-wartość podobna do słowników w Python, obiektów w JavaScript lub haszy w Ruby. + + Oto skrypt do uruchomienia, który pokazuje, jak można zdefiniować mapę i uzyskać dostęp do jej zawartości w praktyce: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Utwórz prostą mapę + def my_map = [id:'sampleA', character:'squirrel'] + + // Wypisz całą mapę + println "map: ${my_map}" + + // Uzyskaj dostęp do pojedynczych wartości za pomocą notacji kropkowej + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Mimo że nie ma odpowiedniego bloku `workflow`, Nextflow może to uruchomić tak, jakby to był workflow: + + ```bash + nextflow run examples/map_demo.nf + ``` + + A oto, co możesz spodziewać się zobaczyć w wyjściu: + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Wyodrębnij określone pola za pomocą `map` + +Powiedzmy, że chcemy uzyskać dostęp do kolumny `character` z tabeli danych i ją wydrukować. +Możemy użyć operatora Nextflow `map`, aby iterować po każdym elemencie w naszym kanale i specyficznie wybrać wpis `character` z obiektu mapy. + +Wprowadź następujące edycje do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Teraz uruchom workflow ponownie: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Sukces! Wykorzystaliśmy strukturę mapy pochodzącą z naszej tabeli danych, aby uzyskać dostęp do wartości z poszczególnych kolumn dla każdego wiersza. + +Teraz, gdy pomyślnie odczytaliśmy tabelę danych i mamy dostęp do danych w każdym wierszu, możemy zacząć implementować logikę naszego pipeline. + +### 1.3. Zorganizuj metadane w 'mapę meta' + +W obecnym stanie workflow pliki wejściowe (pod kluczem `recording`) i powiązane metadane (`id`, `character`) są na tym samym poziomie, jak gdyby wszystkie były w jednej dużej torbie. +Praktyczną konsekwencją jest to, że każdy proces, który konsumuje ten kanał, musiałby być skonfigurowany z tą strukturą na myśli: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +To jest w porządku, dopóki liczba kolumn w tabeli danych się nie zmienia. +Jednakże, jeśli dodasz nawet tylko jedną kolumnę do tabeli danych, kształt kanału nie będzie już pasował do tego, czego oczekuje proces, a workflow będzie generował błędy. +Utrudnia to również dzielenie się procesem z innymi, którzy mogą mieć nieco inne dane wejściowe, i możesz skończyć na hardcodowaniu zmiennych do procesu, które nie są potrzebne przez blok script. + +Aby uniknąć tego problemu, musimy znaleźć sposób na utrzymanie struktury kanału spójnej niezależnie od tego, ile kolumn zawiera tabela danych. + +Możemy to zrobić, zbierając wszystkie metadane w element w krotce, który nazwiemy mapą metadanych, lub prościej 'mapą meta'. + +Wprowadź następujące edycje do operacji `map`: + +=== "Po" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Zrestrukturyzowaliśmy nasze elementy kanału w krotkę składającą się z dwóch elementów: mapy meta i odpowiadającego obiektu pliku. + +Uruchommy workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console title="View meta map" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Teraz każdy element w kanale zawiera najpierw mapę metadanych, a na drugim miejscu odpowiadający obiekt pliku: + +```console title="Przykładowa struktura wyjścia" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +W rezultacie dodanie większej liczby kolumn w tabeli danych udostępni więcej metadanych w mapie `meta`, ale nie zmieni kształtu kanału. +To umożliwia nam pisanie procesów, które konsumują kanał bez konieczności hardcodowania elementów metadanych w specyfikacji wejściowej: + +```groovy title="Przykład składni" + input: + tuple val(meta), file(recording) +``` + +Jest to powszechnie stosowana konwencja organizowania metadanych w workflow Nextflow. + +### Wnioski + +W tej sekcji nauczyłeś się: + +- **Dlaczego metadane są ważne:** Utrzymywanie metadanych wraz z danymi zachowuje ważne informacje o plikach w całym workflow. +- **Jak odczytywać tabele danych:** Używanie `splitCsv` do odczytu plików CSV z informacjami nagłówkowymi i przekształcania wierszy w ustrukturyzowane dane +- **Jak utworzyć mapę meta:** Oddzielanie metadanych od danych pliku za pomocą struktury krotki `[ [id:value, ...], file ]` + +--- + +## 2. Manipulowanie metadanymi + +Teraz, gdy mamy załadowane metadane, zróbmy z nimi coś! + +Użyjemy narzędzia o nazwie [`langid`](https://github.com/saffsd/langid.py) do identyfikacji języka zawartego w pliku nagrania każdego stworzenia. +Narzędzie jest wstępnie wytrenowane na zestawie języków i, biorąc fragment tekstu, wyprowadzi przewidywanie języka i powiązany wynik prawdopodobieństwa, oba do `stdout`. + +### 2.1. Zaimportuj proces i przeanalizuj kod + +Dostarczamy Ci wstępnie napisany moduł procesu o nazwie `IDENTIFY_LANGUAGE`, który opakowuje narzędzie `langid`, więc musisz tylko dodać instrukcję include przed blokiem workflow. + +Wprowadź następującą edycję do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Możesz otworzyć plik modułu, aby przeanalizować jego kod: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Użyj langid do przewidzenia języka każdego pliku wejściowego +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Jak widać, definicja wejściowa używa tej samej struktury `tuple val(meta), path(file)`, którą właśnie zastosowaliśmy do naszego kanału wejściowego. + +Definicja wyjściowa jest zbudowana jako krotka o podobnej strukturze do wejścia, z wyjątkiem tego, że zawiera również `stdout` jako trzeci element. +Ten wzorzec `tuple val(meta), path(file), <output>` utrzymuje metadane powiązane zarówno z danymi wejściowymi, jak i wyjściowymi w miarę przepływu przez pipeline. + +Zauważ, że używamy tu kwalifikatora wyjściowego [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) Nextflow, ponieważ narzędzie drukuje swoje wyjście bezpośrednio do konsoli zamiast zapisywać plik; i używamy `sed` w wierszu poleceń, aby usunąć wynik prawdopodobieństwa, oczyścić ciąg znaków poprzez usunięcie znaków nowej linii i zwrócić tylko przewidywanie języka. + +### 2.2. Dodaj wywołanie `IDENTIFY_LANGUAGE` + +Teraz, gdy proces jest dostępny dla workflow, możemy dodać wywołanie procesu `IDENTIFY_LANGUAGE`, aby uruchomić go na kanale danych. + +Wprowadź następujące edycje do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Zauważ, że usunęliśmy oryginalną operację `.view()` w konstrukcji kanału. + +Możemy teraz uruchomić workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Doskonale! Mamy teraz przewidywanie, w jakim języku mówi każda postać. + +I jak wspomniano wcześniej, uwzględniliśmy również plik wejściowy i mapę meta w wyjściu, co oznacza, że oba pozostają powiązane z nowymi informacjami, które właśnie wygenerowaliśmy. +To okaże się przydatne w następnym kroku. + +!!! note + + Bardziej ogólnie, ten wzorzec utrzymywania mapy meta powiązanej z wynikami ułatwia kojarzenie powiązanych wyników, które dzielą te same identyfikatory. + + Jak już się dowiedziałeś, nie możesz polegać na kolejności elementów w kanałach, aby dopasować wyniki między nimi. + Zamiast tego musisz używać kluczy do prawidłowego kojarzenia danych, a mapy meta zapewniają idealną strukturę do tego celu. + + Badamy ten przypadek użycia szczegółowo w side queście [Splitting & Grouping](./splitting_and_grouping.md). + +### 2.3. Rozszerz metadane o wyjścia procesu + +Biorąc pod uwagę, że wyniki, które właśnie wygenerowaliśmy, same w sobie są formą metadanych o zawartości plików, przydatne byłoby dodanie ich do naszej mapy meta. + +Jednakże nie chcemy modyfikować istniejącej mapy meta w miejscu. +Z technicznego punktu widzenia _możliwe_ jest to zrobienie, ale jest to niebezpieczne. + +Zamiast tego stworzymy nową mapę meta zawierającą zawartość istniejącej mapy meta plus nową parę klucz-wartość `lang: lang_id` przechowującą nowe informacje, używając operatora `+` (funkcja Groovy). +I połączymy to z operacją [`map`](https://www.nextflow.io/docs/latest/operator.html#map), aby zastąpić starą mapę nową. + +Oto edycje, które musisz wprowadzić do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Jeśli nie jesteś jeszcze zaznajomiony z operatorem `+`, lub jeśli wydaje się to mylące, poświęć kilka minut na przejrzenie szczegółowego wyjaśnienia poniżej. + +??? info "Tworzenie nowej mapy meta przy użyciu operatora `+`" + + **Po pierwsze, musisz wiedzieć, że możemy scalić zawartość dwóch map używając operatora Groovy `+`.** + + Powiedzmy, że mamy następujące mapy: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Możemy je scalić w ten sposób: + + ```groovy + new_map = map1 + map2 + ``` + + Zawartość `new_map` będzie: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Świetnie! + + **Ale co jeśli musisz dodać pole, które nie jest jeszcze częścią mapy?** + + Powiedzmy, że zaczynasz ponownie od `map1`, ale przewidywanie języka nie jest w swojej własnej mapie (nie ma `map2`). + Zamiast tego jest przechowywane w zmiennej o nazwie `lang_id` i wiesz, że chcesz przechować jej wartość (`'fr'`) z kluczem `lang`. + + Możesz faktycznie zrobić następująco: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Tutaj `[lang: new_info]` tworzy nową nienazwaną mapę w locie, a `map1 + ` scala `map1` z nową nienazwaną mapą, produkując tę samą zawartość `new_map` jak wcześniej. + + Ładne, prawda? + + **Teraz przetransponujmy to w kontekst operacji Nextflow `channel.map()`.** + + Kod staje się: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + To robi następującą rzecz: + + - `map1, lang_id ->` przyjmuje dwa elementy w krotce + - `[map1 + [lang: lang_id]]` tworzy nową mapę jak szczegółowo opisano powyżej + + Wyjściem jest jedna nienazwana mapa z tą samą zawartością co `new_map` w naszym przykładzie powyżej. + Więc skutecznie przekształciliśmy: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + w: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Miejmy nadzieję, że możesz zobaczyć, że jeśli zmienimy `map1` na `meta`, to w zasadzie wszystko, czego potrzebujemy, aby dodać przewidywanie języka do naszej mapy meta w naszym workflow. + + Z wyjątkiem jednej rzeczy! + + W przypadku naszego workflow **musimy również uwzględnić obecność obiektu `file` w krotce**, który składa się z `meta, file, lang_id`. + + Więc kod tutaj stałby się: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Jeśli masz trudności ze zrozumieniem, dlaczego `file` wydaje się poruszać w operacji `map`, wyobraź sobie, że zamiast `[meta + [lang: lang_id], file]`, ten wiersz brzmi `[new_map, file]`. + To powinno wyjaśnić, że po prostu pozostawiamy `file` w jego pierwotnym miejscu na drugiej pozycji w krotce. Po prostu wzięliśmy wartość `new_info` i włożyliśmy ją do mapy, która jest na pierwszej pozycji. + + **I to prowadzi nas z powrotem do struktury kanału `tuple val(meta), path(file)`!** + +Gdy będziesz pewny, że rozumiesz, co robi ten kod, uruchom workflow, aby zobaczyć, czy zadziałało: + +```bash +nextflow run main.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Tak, to się zgadza! +Starannie zreorganizowaliśmy wyjście procesu z `meta, file, lang_id` tak, że `lang_id` jest teraz jednym z kluczy w mapie meta, a krotki kanału ponownie pasują do modelu `meta, file`. + +### 2.4. Przypisz grupę językową używając instrukcji warunkowych + +Teraz, gdy mamy nasze przewidywania języków, użyjmy tych informacji do przypisania nowych grup. + +W naszych przykładowych danych języki używane przez nasze postacie można podzielić na języki germańskie (angielski, niemiecki) i języki romańskie (francuski, hiszpański, włoski). +Przydatne może być posiadanie tej klasyfikacji łatwo dostępnej gdzieś później w pipeline, więc dodajmy te informacje do mapy meta. + +I, dobra wiadomość, to kolejny przypadek, który idealnie nadaje się do użycia operatora `map`! + +Konkretnie, zdefiniujemy zmienną o nazwie `lang_group`, użyjemy prostej logiki warunkowej do określenia, jaką wartość przypisać `lang_group` dla każdego elementu danych. + +Ogólna składnia będzie wyglądać tak: + +```groovy +.map { meta, file -> + + // logika warunkowa definiująca lang_group idzie tutaj + + [meta + [lang_group: lang_group], file] +} +``` + +Możesz zobaczyć, że jest to bardzo podobne do operacji scalania map w locie, którą użyliśmy w poprzednim kroku. +Musimy tylko napisać instrukcje warunkowe. + +Oto logika warunkowa, którą chcemy zastosować: + +- Zdefiniuj zmienną o nazwie `lang_group` z wartością domyślną `'unknown'`. +- Jeśli `lang` to niemiecki (`'de'`) lub angielski (`'en'`), zmień `lang_group` na `germanic`. +- W przeciwnym razie, jeśli `lang` jest zawarty w liście zawierającej francuski (`'fr'`), hiszpański (`'es'`) i włoski (`'it'`), zmień `lang_group` na `romance`. + +Spróbuj napisać to sam, jeśli już wiesz, jak pisać instrukcje warunkowe w Nextflow. + +!!! tip + + Możesz uzyskać dostęp do wartości `lang` wewnątrz operacji map za pomocą `meta.lang`. + +Powinieneś wprowadzić następujące zmiany do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Oto kluczowe punkty: + +- Używamy `def lang_group = "unknown"` do utworzenia zmiennej `lang_group` z wartością domyślną ustawioną na `unknown`. +- Używamy struktury `if {} else if {}` dla logiki warunkowej, z alternatywnymi testami `.equals()` dla dwóch języków germańskich oraz testem istnienia w liście dla trzech języków romańskich. +- Używamy operacji scalania `meta + [lang_group:lang_group]` jak wcześniej do wygenerowania zaktualizowanej mapy meta. + +Gdy to wszystko ma sens, uruchom workflow ponownie, aby zobaczyć wynik: + +```bash +nextflow run main.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Jak widać, elementy kanału utrzymują swoją strukturę `[meta, file]`, ale mapa meta zawiera teraz tę nową klasyfikację. + +### Wnioski + +W tej sekcji nauczyłeś się, jak: + +- **Stosować metadane wejściowe do kanałów wyjściowych**: Kopiowanie metadanych w ten sposób pozwala nam później kojarzyć wyniki na podstawie zawartości metadanych. +- **Tworzyć niestandardowe klucze**: Utworzyłeś dwa nowe klucze w swojej mapie meta, scalając je za pomocą `meta + [new_key:value]` z istniejącą mapą meta. Jeden oparty na obliczonej wartości z procesu, a drugi oparty na warunku ustawionym w operatorze `map`. + +Pozwalają one kojarzyć nowe i istniejące metadane z plikami w miarę postępu w pipeline. +Nawet jeśli nie używasz metadanych jako części procesu, utrzymywanie mapy meta powiązanej z danymi w ten sposób ułatwia utrzymanie wszystkich istotnych informacji razem. + +--- + +## 3. Używanie informacji z mapy meta w procesie + +Teraz, gdy wiesz, jak tworzyć i aktualizować mapę meta, możemy przejść do naprawdę zabawnej części: faktycznego używania metadanych w procesie. + +Dokładniej, dodamy drugi krok do naszego workflow, aby narysować każde zwierzę jako sztukę ASCII i sprawić, że powie nagrany tekst w dymku. +Zrobimy to za pomocą narzędzia o nazwie [`cowpy`](https://github.com/jeffbuttars/cowpy). + +??? info "Co robi `cowpy`?" + + `cowpy` to narzędzie wiersza poleceń, które generuje sztukę ASCII do wyświetlania dowolnych wejść tekstowych w zabawny sposób. + Jest to implementacja w pythonie klasycznego narzędzia [cowsay](https://en.wikipedia.org/wiki/Cowsay) Tony'ego Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Opcjonalnie możesz wybrać postać (lub 'cowacter') do użycia zamiast domyślnej krowy. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Jeśli przeszedłeś kurs Hello Nextflow, już widziałeś to narzędzie w akcji. +Jeśli nie, nie martw się; omówimy wszystko, co musisz wiedzieć w trakcie. + +### 3.1. Zaimportuj proces i przeanalizuj kod + +Dostarczamy Ci wstępnie napisany moduł procesu o nazwie `COWPY`, który opakowuje narzędzie `cowpy`, więc musisz tylko dodać instrukcję include przed blokiem workflow. + +Wprowadź następującą edycję do workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Możesz otworzyć plik modułu, aby przeanalizować jego kod: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Wygeneruj grafikę ASCII za pomocą cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Jak widać, ten proces jest obecnie zaprojektowany tak, aby przyjmować plik wejściowy (zawierający tekst do wyświetlenia) i wartość określającą postać, która powinna być narysowana w sztuce ASCII, zwykle dostarczaną na poziomie workflow przez parametr wiersza poleceń. + +### 3.2. Przekaż pole mapy meta jako wejście + +Kiedy używaliśmy narzędzia `cowpy` w kursie Hello Nextflow, użyliśmy parametru wiersza poleceń do określenia, jakiej postaci użyć do narysowania końcowego obrazu. +To miało sens, ponieważ generowaliśmy tylko jeden obraz na uruchomienie pipeline. + +Jednakże w tym kursie chcemy wygenerować odpowiedni obraz dla każdego podmiotu, który przetwarzamy, więc użycie parametru wiersza poleceń byłoby zbyt ograniczające. + +Dobra wiadomość: mamy kolumnę `character` w naszej tabeli danych i dlatego w naszej mapie meta. +Użyjmy tego do ustawienia postaci, której proces powinien użyć dla każdego wpisu. + +W tym celu będziemy musieli zrobić trzy rzeczy: + +1. Nadać nazwę kanałowi wyjściowemu wychodzącemu z poprzedniego procesu, abyśmy mogli na nim wygodniej operować. +2. Określić, jak uzyskać dostęp do interesujących nas informacji +3. Dodać wywołanie drugiego procesu i odpowiednio wprowadzić informacje. + +Zaczynajmy. + +#### 3.2.1. Nazwij poprzedni kanał wyjściowy + +Zastosowaliśmy poprzednie manipulacje bezpośrednio na kanale wyjściowym pierwszego procesu, `IDENTIFY_LANGUAGE.out`. +Aby przekazać zawartość tego kanału do następnego procesu (i zrobić to w sposób jasny i łatwy do odczytania) chcemy nadać mu własną nazwę, `ch_languages`. + +Możemy to zrobić za pomocą operatora [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set). + +W głównym workflow zastąp operator `.view()` przez `.set { ch_languages }` i dodaj linię testującą, że możemy odwoływać się do kanału po nazwie. + +=== "Po" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Tymczasowe: podejrzyj ch_languages + ch_languages.view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Uruchom langid, aby zidentyfikować język każdego pozdrowienia + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Uruchommy to: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +To potwierdza, że możemy teraz odwoływać się do kanału po nazwie. + +#### 3.2.2. Uzyskaj dostęp do pliku i metadanych postaci + +Wiemy z przyjrzenia się kodowi modułu, że proces `COWPY` oczekuje, że zostanie mu podany plik tekstowy i wartość `character`. +Aby napisać wywołanie procesu `COWPY`, musimy tylko wiedzieć, jak wyodrębnić odpowiadający obiekt pliku i metadane z każdego elementu w kanale. + +Jak to często bywa, najprostszym sposobem jest użycie operacji `map`. + +Nasz kanał zawiera krotki zorganizowane jako `[meta, file]`, więc możemy uzyskać dostęp do obiektu `file` bezpośrednio, a możemy uzyskać dostęp do wartości `character` przechowywanej wewnątrz mapy meta, odwołując się do niej jako `meta.character`. + +W głównym workflow wprowadź następujące zmiany w kodzie: + +=== "Po" + + ```groovy title="main.nf" linenums="34" + // Tymczasowe: uzyskaj dostęp do pliku i postaci + ch_languages.map { meta, file -> file }.view { file -> "File: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Character: " + character } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="34" + // Tymczasowe: podejrzyj ch_languages + ch_languages.view() + ``` + +Zauważ, że używamy domknięć (takich jak `{ file -> "File: " + file }`), aby uczynić wyjście operacji `.view` bardziej czytelnym. + +Uruchommy to: + +```bash +nextflow run main.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Character: squirrel + File: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + File: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Character: tux + Character: turkey + File: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + File: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Character: sheep + Character: moose + Character: stegosaurus + File: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + File: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + File: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Character: turtle + ``` + +_Ścieżki plików i wartości postaci mogą pojawić się w innej kolejności w Twoim wyjściu._ + +To potwierdza, że jesteśmy w stanie uzyskać dostęp do pliku i postaci dla każdego elementu w kanale. + +#### 3.2.3. Wywołaj proces `COWPY` + +Teraz połóżmy to wszystko razem i faktycznie wywołajmy proces `COWPY` na kanale `ch_languages`. + +W głównym workflow wprowadź następujące zmiany w kodzie: + +=== "Po" + + ```groovy title="main.nf" linenums="34" + // Uruchom cowpy, aby wygenerować grafikę ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="34" + // Tymczasowe: uzyskaj dostęp do pliku i postaci + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Widzisz, że po prostu kopiujemy dwie operacje map (minus instrukcje `.view()`) jako wejścia do wywołania procesu. +Tylko upewnij się, że nie zapomnisz przecinka między nimi! + +To trochę niezgrabne, ale zobaczymy, jak to poprawić w następnej sekcji. + +Uruchommy to: + +```bash +nextflow run main.nf -resume +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Jeśli spojrzysz w katalog results, powinieneś zobaczyć poszczególne pliki zawierające sztukę ASCII każdego powitania wymówionego przez odpowiednią postać. + +??? abstract "Katalog i przykładowa zawartość pliku" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola.txt + └── cowpy-salut.txt + ``` + + ```text title="results/cowpy-bonjour.txt" + _________________ + / Bonjour \ + \ Salut, à demain / + ----------------- + \ + \ + _ _ + | \__/| .~ ~. + /oo `./ .' + {o__, \ { + / . . ) \ + `-` '-' \ } + .( _( )_.' + '---.~_ _ _| + ``` + +To pokazuje, że byliśmy w stanie użyć informacji w mapie meta do sparametryzowania polecenia w drugim kroku pipeline. + +Jednakże, jak wspomniano powyżej, część kodu była trochę niezgrabna, ponieważ musieliśmy rozpakować metadane będąc jeszcze w kontekście ciała workflow. +To podejście działa dobrze dla używania niewielkiej liczby pól z mapy meta, ale słabo by się skalowało, gdybyśmy chcieli użyć znacznie więcej. + +Jest inny operator o nazwie `multiMap()`, który pozwala nam to nieco usprawnić, ale nawet wtedy nie jest to idealne. + +??? info "(Opcjonalnie) Alternatywna wersja z `multiMap()`" + + W przypadku, gdy się zastanawiasz, nie mogliśmy po prostu napisać pojedynczej operacji `map()`, która wyprowadza zarówno `file`, jak i `character`, ponieważ to zwróciłoby je jako krotkę. + Musieliśmy napisać dwie oddzielne operacje `map()`, aby przekazać elementy `file` i `character` do procesu osobno. + + Technicznie istnieje inny sposób, aby to zrobić przez pojedynczą operację mapowania, używając operatora `multiMap()`, który jest w stanie emitować wiele kanałów. + Na przykład możesz zastąpić wywołanie `COWPY` powyżej następującym kodem: + + === "Po" + + ```groovy title="main.nf" linenums="34" + // Uruchom cowpy, aby wygenerować grafikę ASCII + COWPY( + ch_languages.multiMap { meta, file -> + file: file + character: meta.character + } + ) + ``` + + === "Przed" + + ```groovy title="main.nf" linenums="34" + // Uruchom cowpy, aby wygenerować grafikę ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + + To produkuje dokładnie taki sam wynik. + +W obu przypadkach jest niezręcznie, że musimy robić trochę rozpakowywania na poziomie workflow. + +Byłoby lepiej, gdybyśmy mogli przekazać całą mapę meta do procesu i wybrać, czego potrzebujemy, gdy tam jesteśmy. + +### 3.3. Przekaż i użyj całej ma diff --git a/docs/pl/docs/side_quests/nf-test.md b/docs/pl/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..0d07300ef0 --- /dev/null +++ b/docs/pl/docs/side_quests/nf-test.md @@ -0,0 +1,1194 @@ +# Testowanie z nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Możliwość systematycznego testowania, czy każda część przepływu pracy działa zgodnie z założeniami, jest kluczowa dla odtwarzalności i długoterminowej konserwacji, a także może być ogromną pomocą podczas procesu twórczego. + +Poświęćmy chwilę na omówienie, dlaczego testowanie jest tak ważne. Jeśli tworzysz przepływ pracy, jedną z pierwszych rzeczy, które zrobisz, jest pobranie danych testowych, o których wiesz, że są poprawne i powinny dać wynik. Dodajesz pierwszy proces do potoku i podłączasz go do swoich danych wejściowych, aby działał. Następnie, aby sprawdzić, czy wszystko działa, uruchamiasz go na danych testowych. Zakładając, że działa, przechodzisz do następnego procesu i ponownie uruchamiasz dane testowe. Powtarzasz ten proces, aż otrzymasz potok, z którego jesteś zadowolony. + +Następnie, być może dodajesz prosty parametr prawda lub fałsz, taki jak `--skip_process`. Teraz musisz uruchomić potok dwa razy, raz z każdym parametrem, aby upewnić się, że działa zgodnie z oczekiwaniami. Ale czekaj, jak sprawdzić, czy `--skip_process` faktycznie pomija proces? Musimy przejrzeć wyniki lub sprawdzić pliki logów! To jest uciążliwe i podatne na błędy. + +W miarę rozwoju potoku szybko stanie się on tak złożony, że ręczne testowanie każdej iteracji będzie wolne i podatne na błędy. Co więcej, jeśli znajdziesz błąd, bardzo trudno będzie dokładnie określić, skąd w potoku pochodzi błąd. Właśnie tutaj przydaje się testowanie. + +Testowanie pozwala systematycznie sprawdzać, czy każda część potoku działa zgodnie z oczekiwaniami. Korzyści dla programisty z dobrze napisanych testów są ogromne: + +- **Pewność**: Ponieważ testy obejmują cały potok, możesz być pewny, że zmiana czegoś nie wpłynie na nic innego +- **Zaufanie**: Kiedy wielu programistów pracuje nad potokiem, wiedzą, że inni programiści nie zepsuli potoku ani żadnego komponentu. +- **Przejrzystość**: Testy pokazują, gdzie potok zawodzi i ułatwiają wyśledzenie problemu. Działają również jako forma dokumentacji, pokazując, jak uruchomić proces lub przepływ pracy. +- **Szybkość**: Ponieważ testy są zautomatyzowane, można je uruchamiać bardzo szybko i wielokrotnie. Możesz szybko iterować z mniejszą obawy o wprowadzenie nowych błędów. + +Możemy napisać wiele różnych rodzajów testów: + +1. **Testy na poziomie modułu**: Dla pojedynczych procesów +2. **Testy na poziomie przepływu pracy**: Dla pojedynczego przepływu pracy +3. **Testy na poziomie potoku**: Dla potoku jako całości +4. **Testy wydajnościowe**: Dla szybkości i wydajności potoku +5. **Testy obciążeniowe**: Ocena wydajności potoku w ekstremalnych warunkach w celu określenia jego granic + +Testowanie pojedynczych procesów jest analogiczne do testów jednostkowych w innych językach. Testowanie przepływu pracy lub całego potoku jest analogiczne do tego, co nazywa się testami integracyjnymi w innych językach, gdzie testujemy interakcje komponentów. + +[**nf-test**](https://www.nf-test.com/) to narzędzie, które pozwala pisać testy na poziomie modułu, przepływu pracy i potoku. Krótko mówiąc, pozwala systematycznie sprawdzać, czy każda pojedyncza część potoku działa zgodnie z oczekiwaniami, _w izolacji_. + +### Cele nauki + +W tym side queście nauczysz się używać nf-test do pisania testów na poziomie przepływu pracy dla potoku, a także testów na poziomie modułu dla trzech procesów, które wywołuje. + +Pod koniec tego side questa będziesz w stanie efektywnie używać następujących technik: + +- Inicjalizowanie nf-test w projekcie +- Generowanie testów na poziomie modułu i przepływu pracy +- Dodawanie typowych rodzajów asercji +- Rozumienie, kiedy używać migawek a asercji zawartości +- Uruchamianie testów dla całego projektu + +Te umiejętności pomogą Ci wdrożyć kompleksową strategię testowania w projektach potoków, zapewniając, że są bardziej solidne i łatwe w utrzymaniu. + +### Wymagania wstępne + +Przed podjęciem tego side questa powinieneś: + +- Ukończyć samouczek [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Swobodnie posługiwać się podstawowymi koncepcjami i mechanizmami Nextflow (procesy, kanały, operatory, praca z plikami, metadane) + +--- + +## 0. Rozpoczęcie pracy + +#### Otwórz codespace szkoleniowy + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzyłeś środowisko szkoleniowe zgodnie z opisem w [Konfiguracja środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki dla tego samouczka. + +```bash +cd side-quests/nf-test +``` + +Możesz ustawić VSCode tak, aby skupił się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz główny plik przepływu pracy i plik CSV o nazwie `greetings.csv`, który zawiera dane wejściowe do potoku. + +```console title="Zawartość katalogu" +. +├── greetings.csv +└── main.nf +``` + +Aby uzyskać szczegółowy opis plików, zobacz [rozgrzewkę z Hello Nextflow](../hello_nextflow/00_orientation.md). + +Przepływ pracy, który będziemy testować, jest podzbiorem przepływu pracy Hello zbudowanego w [Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +??? example "Co robi przepływ pracy Hello Nextflow?" + + Jeśli nie ukończyłeś szkolenia [Hello Nextflow](../hello_nextflow/index.md), oto krótki przegląd tego, co robi ten prosty przepływ pracy. + + Przepływ pracy pobiera plik CSV zawierający pozdrowienia, przeprowadza na nich cztery kolejne kroki transformacji i wyprowadza pojedynczy plik tekstowy zawierający obraz ASCII zabawnej postaci wypowiadającej pozdrowienia. + + Cztery kroki są zaimplementowane jako procesy Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` i `cowpy`) przechowywane w oddzielnych plikach modułów. + + 1. **`sayHello`:** Zapisuje każde pozdrowienie do własnego pliku wyjściowego (np. "Hello-output.txt") + 2. **`convertToUpper`:** Konwertuje każde pozdrowienie na wielkie litery (np. "HELLO") + 3. **`collectGreetings`:** Zbiera wszystkie pozdrowienia z wielkimi literami do jednego pliku wsadowego + 4. **`cowpy`:** Generuje grafikę ASCII za pomocą narzędzia `cowpy` + + Wyniki są publikowane w katalogu o nazwie `results/`, a końcowe wyjście potoku (po uruchomieniu z domyślnymi parametrami) to zwykły plik tekstowy zawierający grafikę ASCII postaci wypowiadającej pozdrowienia z wielkimi literami. + + W tym side queście używamy pośredniej formy przepływu pracy Hello, która zawiera tylko dwa pierwsze procesy. + +Podzbiór, z którym będziemy pracować, składa się z dwóch procesów: `sayHello` i `convertToUpper`. +Pełny kod przepływu pracy możesz zobaczyć poniżej. + +??? example "Kod przepływu pracy" + + ```groovy title="main.nf" + /* + * Pipeline parameters + */ + params.input_file = "greetings.csv" + + /* + * Użyj echo do wypisania 'Hello World!' na standardowe wyjście + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Użyj narzędzia zamiany tekstu do przekształcenia pozdrowienia na wielkie litery + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // utwórz kanał dla danych wejściowych z pliku CSV + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // wyemituj pozdrowienie + sayHello(greeting_ch) + + // przekształć pozdrowienie na wielkie litery + convertToUpper(sayHello.out) + } + ``` + +#### Uruchom przepływ pracy + +Uruchommy przepływ pracy, aby upewnić się, że działa zgodnie z oczekiwaniami. + +```bash +nextflow run main.nf +``` + +```console title="Wynik uruchomienia przepływu pracy" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +GRATULACJE! Właśnie uruchomiłeś test! + +"Czekaj, co? Po prostu uruchomiłem przepływ pracy i zadziałał! Jak to jest test?" + +Dobre pytanie! + +Rozłóżmy to na czynniki pierwsze. + +Uruchomiłeś przepływ pracy z domyślnymi parametrami, potwierdziłeś, że działa i jesteś zadowolony z wyników. To jest istota testowania. Jeśli pracowałeś przez kurs szkoleniowy Hello Nextflow, zauważysz, że zawsze zaczynaliśmy każdą sekcję od uruchomienia przepływu pracy, którego używaliśmy jako punktu wyjścia, aby potwierdzić, że wszystko jest poprawnie skonfigurowane. + +Testowanie oprogramowania zasadniczo wykonuje ten proces za nas. + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest dodanie standardowych testów do tego przepływu pracy za pomocą nf-test, aby ułatwić weryfikację, że każda część nadal działa zgodnie z oczekiwaniami w przypadku wprowadzenia jakichkolwiek dalszych zmian. + +#### Lista kontrolna gotowości + +Myślisz, że jesteś gotowy, aby się zanurzyć? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace jest uruchomiony +- [ ] Odpowiednio ustawiłem katalog roboczy +- [ ] Pomyślnie uruchomiłem przepływ pracy +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, możesz rozpocząć. + +--- + +## 1. Inicjalizacja `nf-test` + +Pakiet `nf-test` zapewnia polecenie inicjalizacji, które konfiguruje kilka rzeczy, aby mogliśmy zacząć tworzyć testy dla naszego projektu. + +```bash +nf-test init +``` + +Powinno to dać następujące wyjście: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Tworzy również katalog `tests` zawierający szkielet pliku konfiguracyjnego. + +### 1.1. Wygeneruj nf-test + +`nf-test` zawiera zestaw narzędzi do budowania plików nf-test, oszczędzając nam większość pracy. Są one dostępne pod podpoleceniem `generate`. Wygenerujmy test dla potoku: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Wyjście" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +To utworzy plik `main.nf.test` w katalogu `tests`. To jest nasz plik testowy na poziomie potoku. Jeśli uruchomisz `tree tests/`, powinieneś zobaczyć coś takiego: + +```console title="Zawartość katalogu testów" +tests/ +├── main.nf.test +└── nextflow.config +``` + +Plik `main.nf.test` to nasz plik testowy na poziomie potoku. Otwórzmy go i przyjrzyjmy się zawartości. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Poświęćmy chwilę na zrozumienie struktury pliku testowego. + +Blok `nextflow_pipeline` jest punktem wejścia dla wszystkich testów na poziomie potoku. Zawiera następujące elementy: + +- `name`: Nazwa testu. +- `script`: Ścieżka do skryptu potoku. + +Blok `test` to rzeczywisty test. Zawiera następujące elementy: + +- `when`: Warunki, w których test powinien być uruchomiony. Obejmuje to parametry, które będą używane do uruchomienia potoku. +- `then`: Asercje, które powinny być wykonane. Obejmuje to oczekiwane wyniki potoku. + +Mówiąc prostym językiem, logika testu brzmi następująco: +"**Gdy** te _parametry_ są dostarczane do tego _potoku_, **wtedy** oczekujemy zobaczyć te wyniki." + +To nie jest test funkcjonalny, pokażemy, jak go przekształcić w taki w następnej sekcji. + +### Uwaga o nazewnictwie testów + +W powyższym przykładzie użyliśmy domyślnej nazwy "Should run without failures", która jest odpowiednia dla podstawowego testu, który tylko sprawdza, czy potok działa pomyślnie. Jednak gdy dodajemy bardziej szczegółowe przypadki testowe, powinniśmy używać bardziej opisowych nazw, które wskazują, co faktycznie testujemy. Na przykład: + +- "Should convert input to uppercase" - podczas testowania konkretnej funkcjonalności +- "Should handle empty input gracefully" - podczas testowania przypadków brzegowych +- "Should respect max memory parameter" - podczas testowania ograniczeń zasobów +- "Should create expected output files" - podczas testowania generowania plików + +Dobre nazwy testów powinny: + +1. Zaczynać się od "Should", aby było jasne, jakie jest oczekiwane zachowanie +2. Opisywać konkretną funkcjonalność lub scenariusz, który jest testowany +3. Być wystarczająco jasne, aby w przypadku niepowodzenia testu wiedzieć, jaka funkcjonalność jest uszkodzona + +Gdy później dodamy więcej asercji i konkretnych przypadków testowych, użyjemy tych bardziej opisowych nazw, aby było jasne, co weryfikuje każdy test. + +### 1.2. Uruchom test + +Uruchommy test, aby zobaczyć, co się stanie. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test pipeline fail" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Test nie powiódł się! Co się stało? + +1. nf-test próbował uruchomić potok w obecnej postaci, używając ustawień w bloku `when`: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test sprawdził status potoku i porównał go z blokiem `when`: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Zauważ, jak nf-test zgłosił, że potok nie powiódł się i dostarczył komunikat o błędzie z Nextflow: + +```console title="Błąd" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Jaki był więc problem? Pamiętaj, że potok ma plik greetings.csv w katalogu projektu. Gdy nf-test uruchamia potok, będzie szukał tego pliku, ale nie może go znaleźć. Plik jest tam, co się dzieje? Cóż, jeśli spojrzymy na ścieżkę, możemy zobaczyć, że test odbywa się w ścieżce `./nf-test/tests/longHashString/`. Podobnie jak Nextflow, nf-test tworzy nowy katalog dla każdego testu, aby wszystko było izolowane. Plik danych nie znajduje się tam, więc musimy poprawić ścieżkę do pliku w oryginalnym teście. + +Wróćmy do pliku testowego i zmieńmy ścieżkę do pliku w bloku `when`. + +Możesz się zastanawiać, jak będziemy wskazywać na katalog główny potoku w teście. Ponieważ jest to powszechna sytuacja, nf-test ma szereg zmiennych globalnych, których możemy użyć, aby ułatwić sobie życie. Pełną listę znajdziesz [tutaj](https://www.nf-test.com/docs/testcases/global_variables/), ale tymczasem użyjemy zmiennej `projectDir`, co oznacza katalog główny projektu potoku. + +_Przed:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Po:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Uruchommy test ponownie, aby zobaczyć, czy działa. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Potok przechodzi" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Sukces! Potok działa pomyślnie i test przechodzi. Uruchom go tyle razy, ile chcesz, a zawsze otrzymasz ten sam wynik! + +Domyślnie wyjście Nextflow jest ukryte, ale aby przekonać się, że nf-test na pewno uruchamia przepływ pracy, możesz użyć flagi `--verbose`: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Potok uruchamia wszystkie procesy" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Dodaj asercje + +Prostym sprawdzeniem jest upewnienie się, że nasz potok uruchamia wszystkie oczekiwane procesy i nie pomija żadnego w sposób cichy. Pamiętaj, że nasz potok uruchamia 6 procesów, jeden o nazwie `sayHello` i jeden o nazwie `convertToUpper` dla każdego z 3 pozdrowień. + +Dodajmy asercję do naszego testu, aby sprawdzić, czy potok uruchamia oczekiwaną liczbę procesów. Zaktualizujemy również nazwę naszego testu, aby lepiej odzwierciedlała to, co testujemy. + +**Przed:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Po:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Nazwa testu teraz lepiej odzwierciedla to, co faktycznie weryfikujemy - nie tylko to, że potok działa bez awarii, ale że uruchamia oczekiwaną liczbę procesów. + +Uruchommy test ponownie, aby zobaczyć, czy działa. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Potok przechodzi z asercjami" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Sukces! Potok działa pomyślnie i test przechodzi. Teraz zaczęliśmy testować szczegóły potoku, a także ogólny status. + +### 1.4. Testowanie wyjścia + +Dodajmy asercję do naszego testu, aby sprawdzić, czy plik wyjściowy został utworzony. Dodamy ją jako oddzielny test z informacyjną nazwą, aby ułatwić interpretację wyników. + +**Przed:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Po:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Uruchom test ponownie, aby zobaczyć, czy działa. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Potok przechodzi z asercjami plików" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Sukces! Testy przechodzą, ponieważ potok zakończył się pomyślnie, uruchomiona została prawidłowa liczba procesów, a pliki wyjściowe zostały utworzone. Powinno to również pokazać, jak przydatne jest dostarczanie tych informacyjnych nazw dla testów. + +To tylko powierzchnia, możemy dalej pisać asercje, aby sprawdzić szczegóły potoku, ale na razie przejdźmy do testowania wewnętrznych elementów potoku. + +### Wnioski + +Wiesz, jak napisać nf-test dla potoku. + +### Co dalej? + +Naucz się testować proces Nextflow. + +--- + +## 2. Testowanie procesu Nextflow + +Nie musimy pisać testów dla każdej części potoku, ale im więcej testów mamy, tym bardziej kompleksowo możemy ocenić potok i tym bardziej możemy być pewni, że działa zgodnie z oczekiwaniami. W tej sekcji będziemy testować oba procesy w potoku jako pojedyncze jednostki. + +### 2.1. Testowanie procesu `sayHello` + +Zacznijmy od procesu `sayHello`. + +Użyjmy ponownie polecenia `nf-test generate`, aby wygenerować testy dla procesu. + +```bash +nf-test generate process main.nf +``` + +```console title="Wyjście" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Skupmy się teraz na procesie `sayhello` w pliku `main.sayhello.nf.test`. + +Otwórzmy plik i przyjrzyjmy się zawartości. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Jak poprzednio, zaczynamy od szczegółów testu, po których następują bloki `when` i `then`. Jednak mamy również dodatkowy blok `process`, który pozwala nam zdefiniować wejścia do procesu. + +Uruchommy test, aby zobaczyć, czy działa. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Test procesu nie powiódł się" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Test nie powiódł się, ponieważ proces `sayHello` deklaruje 1 wejście, ale został wywołany z 0 argumentami. Naprawmy to, dodając wejście do procesu. Pamiętaj z [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (i sekcji rozgrzewkowej powyżej), że nasz proces `sayHello` przyjmuje pojedyncze wejście wartości, które musimy podać. Powinniśmy również poprawić nazwę testu, aby lepiej odzwierciedlała to, co testujemy. + +**Przed:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Po:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Uruchommy test ponownie, aby zobaczyć, czy działa. + +```console title="nf-test pipeline pass" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Sukces! Test przechodzi, ponieważ proces `sayHello` działał pomyślnie i wyjście zostało utworzone. + +### 2.2. Sprawdź migawkę utworzoną przez test + +Jeśli spojrzymy na plik `tests/main.sayhello.nf.test`, zobaczymy, że używa metody `snapshot()` w bloku asercji: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +To mówi nf-test, aby utworzyć migawkę wyjścia procesu `sayHello`. Przyjrzyjmy się zawartości pliku migawki. + +```console title="Zawartość pliku migawki" +code tests/main.sayhello.nf.test.snap +``` + +Nie wydrukujemy tego tutaj, ale powinieneś zobaczyć plik JSON zawierający szczegóły procesu i wyjść procesu. W szczególności możemy zobaczyć linię, która wygląda następująco: + +```json title="Zawartość pliku migawki" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +To reprezentuje wyjścia utworzone przez proces `sayHello`, które testujemy jawnie. Jeśli ponownie uruchomimy test, program sprawdzi, czy nowe wyjście pasuje do wyjścia, które zostało pierwotnie zarejestrowane. To jest szybki, prosty sposób testowania, że wyjścia procesu się nie zmieniają, dlatego nf-test zapewnia to jako wartość domyślną. + +!!!warning + + To oznacza, że musimy być pewni, że wyjście, które rejestrujemy w oryginalnym uruchomieniu, jest poprawne! + +Jeśli w trakcie przyszłego rozwoju coś w kodzie się zmieni, co spowoduje, że wyjście będzie inne, test nie powiedzie się i będziemy musieli określić, czy zmiana jest oczekiwana, czy nie. + +- Jeśli okaże się, że coś w kodzie się zepsuło, będziemy musieli to naprawić, oczekując, że naprawiony kod przejdzie test. +- Jeśli jest to oczekiwana zmiana (np. narzędzie zostało ulepszone, a wyniki są lepsze), będziemy musieli zaktualizować migawkę, aby zaakceptować nowe wyjście jako odniesienie do dopasowania. nf-test ma parametr `--update-snapshot` w tym celu. + +Możemy uruchomić test ponownie i zobaczyć, że test powinien przejść: + +```console title="nf-test process pass with snapshot" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Sukces! Test przechodzi, ponieważ proces `sayHello` działał pomyślnie, a wyjście pasowało do migawki. + +### 2.3. Alternatywa dla migawek: bezpośrednie asercje zawartości + +Chociaż migawki są świetne do wychwytywania wszelkich zmian w wyjściu, czasami chcesz zweryfikować konkretną zawartość bez bycia tak restrykcyjnym co do całego dopasowania pliku. Na przykład: + +- Gdy części wyjścia mogą się zmieniać (znaczniki czasu, losowe identyfikatory itp.), ale musi być obecna określona kluczowa zawartość +- Gdy chcesz sprawdzić konkretne wzorce lub wartości w wyjściu +- Gdy chcesz uczynić test bardziej jawnym co do tego, co stanowi sukces + +Oto jak moglibyśmy zmodyfikować nasz test, aby sprawdzić konkretną zawartość: + +**Przed:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Po:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Zauważ, że nf-test widzi wyjścia procesu jako listę list, więc `process.out[0][0]` pobiera pierwszą część pierwszego elementu kanału (lub 'emisji') z tego procesu. + +To podejście: + +- Wyraźnie pokazuje, czego dokładnie oczekujemy w wyjściu +- Jest bardziej odporne na nieistotne zmiany w wyjściu +- Zapewnia lepsze komunikaty o błędach, gdy testy nie przechodzą +- Pozwala na bardziej złożone walidacje (wzorce wyrażeń regularnych, porównania numeryczne itp.) + +Uruchommy test, aby zobaczyć, czy działa. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Test procesu nie powiódł się" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Testowanie procesu `convertToUpper` + +Otwórzmy plik `tests/main.converttoupper.nf.test` i przyjrzyjmy się zawartości: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +To jest podobny test do procesu `sayHello`, ale testuje proces `convertToUpper`. Wiemy, że ten nie powiedzie się, ponieważ podobnie jak z `sayHello`, proces `convertToUpper` przyjmuje pojedyncze wejście ścieżki, ale go nie określiliśmy. + +Teraz musimy dostarczyć pojedynczy plik wejściowy do procesu convertToUpper, który zawiera tekst, który chcemy przekonwertować na wielkie litery. Jest wiele sposobów, w jakie moglibyśmy to zrobić: + +- Moglibyśmy utworzyć dedykowany plik do testowania +- Moglibyśmy ponownie użyć istniejącego pliku data/greetings.csv +- Moglibyśmy utworzyć go w locie w teście + +Na razie ponownie użyjmy istniejącego pliku data/greetings.csv, używając przykładu, którego użyliśmy w teście na poziomie potoku. Jak poprzednio, możemy nazwać test, aby lepiej odzwierciedlał to, co testujemy, ale tym razem pozostawmy "migawkę" zawartości zamiast sprawdzania konkretnych ciągów (jak zrobiliśmy w innym procesie). + +**Przed:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Po:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +I uruchom test! + +```bash title="nf-test pipeline pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Zauważ, że utworzyliśmy plik migawki dla procesu `convertToUpper` w `tests/main.converttoupper.nf.test.snap`. Jeśli ponownie uruchomimy test, powinniśmy zobaczyć, że nf-test ponownie przechodzi. + +```bash title="nf-test process convertToUpper pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Wnioski + +Wiesz, jak pisać testy dla procesu Nextflow i je uruchamiać. + +### Co dalej? + +Naucz się uruchamiać testy dla wszystkiego na raz! + +## 3. Uruchomienie testów dla całego repozytorium + +Uruchamianie nf-test dla każdego komponentu jest w porządku, ale pracochłonne i podatne na błędy. Czy nie możemy po prostu przetestować wszystkiego na raz? + +Tak, możemy! + +Uruchommy nf-test na całym repozytorium. + +### 3.1. Uruchomienie nf-test na całym repozytorium + +Możemy uruchomić nf-test na całym repozytorium, wykonując polecenie `nf-test test`. + +```bash +nf-test test . +``` + +Zauważ, że używamy tylko `.`, aby uruchomić wszystko z naszego bieżącego katalogu. To będzie zawierać każdy test! + +```console title="nf-test repo pass" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Spójrz na to! Uruchomiliśmy 4 testy, 1 dla każdego procesu i 2 dla całego potoku za pomocą jednego polecenia. Wyobraź sobie, jak potężne jest to w dużej bazie kodu! + +--- + +## Podsumowanie + +W tym side queście nauczyłeś się wykorzystywać funkcje nf-test do tworzenia i uruchamiania testów dla pojedynczych procesów, a także testów end-to-end dla całego potoku. +Jesteś teraz świadomy dwóch głównych podejść do walidacji wyjścia, migawek i bezpośrednich asercji zawartości, oraz kiedy używać któregokolwiek z nich. +Wiesz również, jak uruchamiać testy pojedynczo lub dla całego projektu. + +Zastosowanie tych technik we własnej pracy pozwoli Ci zapewnić, że: + +- Twój kod działa zgodnie z oczekiwaniami +- Zmiany nie psują istniejącej funkcjonalności +- Inni programiści mogą wnosić wkład z pewnością +- Problemy mogą być szybko identyfikowane i naprawiane +- Zawartość wyjścia odpowiada oczekiwaniom + +### Kluczowe wzorce + +1. Testy na poziomie potoku: + - Podstawowe testowanie sukcesu + - Weryfikacja liczby procesów + - Sprawdzanie istnienia plików wyjściowych +2. Testy na poziomie procesu +3. Dwa podejścia do walidacji wyjścia: + - Używanie migawek do pełnej weryfikacji wyjścia + - Używanie bezpośrednich asercji zawartości do sprawdzania konkretnej zawartości +4. Uruchamianie wszystkich testów w repozytorium za pomocą jednego polecenia + +### Dodatkowe zasoby + +Sprawdź [dokumentację nf-test](https://www.nf-test.com/), aby poznać bardziej zaawansowane funkcje testowania i najlepsze praktyki. Możesz chcieć: + +- Dodać bardziej kompleksowe asercje do swoich testów +- Napisać testy dla przypadków brzegowych i warunków błędów +- Skonfigurować ciągłą integrację do automatycznego uruchamiania testów +- Dowiedzieć się więcej o innych typach testów, takich jak testy przepływów pracy i modułów +- Zbadać bardziej zaawansowane techniki walidacji zawartości + +**Pamiętaj:** Testy są żywą dokumentacją tego, jak powinien zachowywać się Twój kod. Im więcej testów napiszesz i im bardziej szczegółowe będą Twoje asercje, tym bardziej możesz być pewny niezawodności swojego potoku. + +--- + +## Co dalej? + +Wróć do [menu Side Questów](./index.md) lub kliknij przycisk w prawym dolnym rogu strony, aby przejść do następnego tematu na liście. diff --git a/docs/pl/docs/side_quests/orientation.md b/docs/pl/docs/side_quests/orientation.md new file mode 100644 index 0000000000..e028b62d73 --- /dev/null +++ b/docs/pl/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientacja + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Środowisko GitHub Codespaces zawiera wszystkie oprogramowanie, kod i dane niezbędne do przepracowania tego kursu szkoleniowego, więc nie musisz niczego instalować samodzielnie. +Jednak potrzebujesz (bezpłatnego) konta, aby się zalogować, i powinieneś poświęcić kilka minut na zapoznanie się z interfejsem. + +Jeśli jeszcze tego nie zrobiłeś, proszę kliknij [ten link](../../envsetup/) przed kontynuowaniem. + +## Dostarczone materiały + +Podczas tego kursu szkoleniowego będziemy pracować w katalogu `side-quests/`. +Ten katalog zawiera wszystkie pliki kodu, dane testowe i pliki pomocnicze, które będą potrzebne. + +Zachęcamy do zapoznania się z zawartością tego katalogu; najłatwiejszym sposobem jest użycie eksploratora plików po lewej stronie obszaru roboczego GitHub Codespaces. +Alternatywnie możesz użyć polecenia `tree`. +Podczas kursu używamy wyjścia `tree` do przedstawienia struktury i zawartości katalogów w czytelnej formie, czasami z niewielkimi modyfikacjami dla przejrzystości. + +Tutaj generujemy spis treści do drugiego poziomu w dół: + +```bash +tree . -L 2 +``` + +Jeśli uruchomisz to wewnątrz `side-quests`, powinieneś zobaczyć następujące wyjście: + +```console title="Zawartość katalogu" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Oto podsumowanie tego, co powinieneś wiedzieć na początek:** + +- **Każdy katalog odpowiada indywidualnemu zadaniu pobocznemum.** + Ich zawartość jest szczegółowo opisana na stronie odpowiedniego zadania pobocznego. + +- **Katalog `solutions`** zawiera ukończone skrypty workflow i/lub modułów, które powstają w wyniku wykonania różnych kroków każdego zadania pobocznego. + Mają one służyć jako punkt odniesienia do sprawdzenia Twojej pracy i rozwiązywania ewentualnych problemów. + +!!!tip "Wskazówka" + + Jeśli z jakiegokolwiek powodu opuścisz ten katalog, zawsze możesz uruchomić to polecenie, aby do niego wrócić: + + ```bash + cd /workspaces/training/side-quests + ``` + +Teraz, aby rozpocząć kurs, kliknij strzałkę w prawym dolnym rogu tej strony. diff --git a/docs/pl/docs/side_quests/splitting_and_grouping.md b/docs/pl/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..01bd8e7c95 --- /dev/null +++ b/docs/pl/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,976 @@ +# Dzielenie i Grupowanie + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow zapewnia potężne narzędzia do elastycznej pracy z danymi. Kluczową możliwością jest dzielenie danych na różne strumienie, a następnie grupowanie powiązanych elementów z powrotem. Jest to szczególnie cenne w przepływach pracy bioinformatycznych, gdzie trzeba przetwarzać różne typy próbek oddzielnie, a następnie łączyć wyniki do analizy. + +Pomyśl o tym jak o sortowaniu poczty: oddzielasz listy według miejsca przeznaczenia, przetwarzasz każdy stos inaczej, a następnie łączysz ponownie elementy idące do tej samej osoby. Nextflow używa specjalnych operatorów do wykonania tego z danymi naukowymi. To podejście jest również powszechnie znane jako wzorzec **scatter/gather** w obliczeniach rozproszonych i przepływach pracy bioinformatycznych. + +System kanałów Nextflow jest sercem tej elastyczności. Kanały łączą różne części przepływu pracy, umożliwiając przepływ danych przez analizę. Możesz utworzyć wiele kanałów z jednego źródła danych, przetwarzać każdy kanał inaczej, a następnie scalać kanały z powrotem, gdy jest to potrzebne. To podejście pozwala projektować przepływy pracy, które naturalnie odzwierciedlają rozgałęziające się i zbiegające się ścieżki złożonych analiz bioinformatycznych. + +### Cele szkolenia + +W tej misji pobocznej nauczysz się dzielić i grupować dane przy użyciu operatorów kanałów Nextflow. +Zaczniemy od pliku CSV zawierającego informacje o próbkach i powiązanych plikach danych, a następnie będziemy manipulować i reorganizować te dane. + +Pod koniec tej misji pobocznej będziesz w stanie efektywnie rozdzielać i łączyć strumienie danych, używając następujących technik: + +- Odczytywanie danych z plików za pomocą `splitCsv` +- Filtrowanie i transformowanie danych za pomocą `filter` i `map` +- Łączenie powiązanych danych za pomocą `join` i `groupTuple` +- Tworzenie kombinacji danych za pomocą `combine` do przetwarzania równoległego +- Optymalizacja struktury danych za pomocą `subMap` i strategii deduplikacji +- Budowanie funkcji wielokrotnego użytku z nazwanymi domknięciami, które pomogą Ci manipulować strukturami kanałów + +Te umiejętności pomogą Ci budować przepływy pracy, które mogą efektywnie obsługiwać wiele plików wejściowych i różne typy danych, zachowując czystą, łatwą w utrzymaniu strukturę kodu. + +### Wymagania wstępne + +Przed podjęciem się tej misji pobocznej powinieneś: + +- Ukończyć tutorial [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Swobodnie posługiwać się podstawowymi koncepcjami i mechanizmami Nextflow (procesy, kanały, operatory, praca z plikami, metadane) + +**Opcjonalnie:** Zalecamy najpierw ukończenie misji pobocznej [Metadane w przepływach pracy](./metadata.md). +Obejmuje ona podstawy odczytu plików CSV za pomocą `splitCsv` i tworzenia map meta, których będziemy tu intensywnie używać. + +--- + +## 0. Rozpoczęcie pracy + +#### Otwórz codespace szkoleniowy + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzysz środowisko szkoleniowe zgodnie z opisem w [Konfiguracja środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki do tego tutorialu. + +```bash +cd side-quests/splitting_and_grouping +``` + +Możesz ustawić VSCode, aby skupić się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz główny plik przepływu pracy i katalog `data` zawierający arkusz próbek o nazwie `samplesheet.csv`. + +```console title="Zawartość katalogu" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +Arkusz próbek zawiera informacje o próbkach od różnych pacjentów, w tym identyfikator pacjenta, numer powtórzenia próbki, typ (normalny lub nowotworowy) oraz ścieżki do hipotetycznych plików danych (które tak naprawdę nie istnieją, ale będziemy udawać, że istnieją). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Ten arkusz próbek zawiera osiem próbek od trzech pacjentów (A, B, C). + +Dla każdego pacjenta mamy próbki typu `tumor` (zazwyczaj pochodzące z biopsji guza) lub `normal` (pobrane ze zdrowej tkanki lub krwi). +Jeśli nie znasz analizy raka, wiedz tylko, że odpowiada to modelowi eksperymentalnemu, który używa sparowanych próbek guz/normalnych do wykonywania analiz kontrastowych. + +Dla pacjenta A mamy konkretnie dwa zestawy replikatów technicznych (powtórzeń). + +!!! note + + Nie martw się, jeśli nie znasz tego projektu eksperymentalnego, nie jest to kluczowe dla zrozumienia tego tutorialu. + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest napisanie przepływu pracy Nextflow, który: + +1. **Odczyta** dane próbek z pliku CSV i ustrukturyzuje je za pomocą map meta +2. **Rozdzieli** próbki na różne kanały na podstawie typu (normalny vs nowotworowy) +3. **Połączy** dopasowane pary guz/normalny według identyfikatora pacjenta i numeru replikatu +4. **Rozdzieli** próbki na interwały genomowe do przetwarzania równoległego +5. **Zgrupuje** powiązane próbki z powrotem dla analizy downstream + +Reprezentuje to powszechny wzorzec bioinformatyczny, w którym musisz podzielić dane do niezależnego przetwarzania, a następnie ponownie połączyć powiązane elementy dla analizy porównawczej. + +#### Lista kontrolna gotowości + +Myślisz, że jesteś gotowy do działania? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace jest uruchomiony +- [ ] Ustawiłem odpowiednio mój katalog roboczy +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, jesteś gotowy do działania. + +--- + +## 1. Odczytanie danych próbek + +### 1.1. Odczytanie danych próbek za pomocą `splitCsv` i utworzenie map meta + +Zacznijmy od odczytania danych próbek za pomocą `splitCsv` i uporządkowania ich w wzorzec mapy meta. W pliku `main.nf` zobaczysz, że już zaczęliśmy przepływ pracy. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note + + W całym tym tutorialu będziemy używać prefiksu `ch_` dla wszystkich zmiennych kanałów, aby wyraźnie wskazać, że są to kanały Nextflow. + +Jeśli ukończyłeś misję poboczną [Metadane w przepływach pracy](./metadata.md), rozpoznasz ten wzorzec. Użyjemy `splitCsv` do odczytu CSV i natychmiastowego ustrukturyzowania danych za pomocą mapy meta, aby oddzielić metadane od ścieżek plików. + +!!! info + + Napotkamy dwa różne koncepty nazywane `map` w tym szkoleniu: + + - **Struktura danych**: Mapa Groovy (odpowiednik słowników/haszy w innych językach), która przechowuje pary klucz-wartość + - **Operator kanału**: Operator `.map()`, który przekształca elementy w kanale + + Będziemy wyjaśniać, którą z nich mamy na myśli w kontekście, ale to rozróżnienie jest ważne do zrozumienia podczas pracy z Nextflow. + +Zastosuj te zmiany w `main.nf`: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +To łączy operację `splitCsv` (odczyt CSV z nagłówkami) i operację `map` (strukturyzowanie danych jako krotek `[meta, file]`) w jednym kroku. Zastosuj tę zmianę i uruchom pipeline: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Mamy teraz kanał, w którym każdy element jest krotką `[meta, file]` - metadane oddzielone od ścieżek plików. Ta struktura pozwala nam dzielić i grupować naszą pracę na podstawie pól metadanych. + +--- + +## 2. Filtrowanie i transformowanie danych + +### 2.1. Filtrowanie danych za pomocą `filter` + +Możemy użyć [operatora `filter`](https://www.nextflow.io/docs/latest/operator.html#filter) do filtrowania danych na podstawie warunku. Powiedzmy, że chcemy przetwarzać tylko próbki normalne. Możemy to zrobić, filtrując dane na podstawie pola `type`. Wstawmy to przed operatorem `view`. + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Uruchom przepływ pracy ponownie, aby zobaczyć przefiltrowany wynik: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Pomyślnie przefiltrowaliśmy dane, aby zawierały tylko próbki normalne. Podsumujmy, jak to działa. + +Operator `filter` przyjmuje domknięcie, które jest stosowane do każdego elementu w kanale. Jeśli domknięcie zwróci `true`, element jest uwzględniany; jeśli zwróci `false`, element jest wykluczany. + +W naszym przypadku chcemy zachować tylko próbki, gdzie `meta.type == 'normal'`. Domknięcie używa krotki `meta,file` do odwoływania się do każdej próbki, uzyskuje dostęp do typu próbki za pomocą `meta.type` i sprawdza, czy jest równy `'normal'`. + +Osiągamy to za pomocą pojedynczego domknięcia, które wprowadziliśmy powyżej: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Utworzenie oddzielnych przefiltrowanych kanałów + +Obecnie stosujemy filtr do kanału utworzonego bezpośrednio z CSV, ale chcemy filtrować to na więcej sposobów niż jeden, więc przepiszmy logikę, aby utworzyć oddzielny przefiltrowany kanał dla próbek normalnych: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Uruchom pipeline, aby zobaczyć wyniki: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Pomyślnie przefiltrowaliśmy dane i utworzyliśmy oddzielny kanał dla próbek normalnych. + +Utwórzmy również przefiltrowany kanał dla próbek nowotworowych: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Rozdzieliliśmy próbki normalne i nowotworowe na dwa różne kanały i użyliśmy domknięcia dostarczonego do `view()`, aby oznaczyć je inaczej w wyjściu: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Wnioski + +W tej sekcji nauczyłeś się: + +- **Filtrowanie danych**: Jak filtrować dane za pomocą `filter` +- **Dzielenie danych**: Jak dzielić dane na różne kanały na podstawie warunku +- **Wyświetlanie danych**: Jak używać `view` do wydrukowania danych i oznaczania wyjścia z różnych kanałów + +Rozdzieliliśmy teraz próbki normalne i nowotworowe na dwa różne kanały. Następnie połączymy próbki normalne i nowotworowe na polu `id`. + +--- + +## 3. Łączenie kanałów według identyfikatorów + +W poprzedniej sekcji rozdzieliliśmy próbki normalne i nowotworowe na dwa różne kanały. Mogą one być przetwarzane niezależnie przy użyciu określonych procesów lub przepływów pracy na podstawie ich typu. Ale co się dzieje, gdy chcemy porównać próbki normalne i nowotworowe tego samego pacjenta? W tym momencie musimy połączyć je z powrotem, upewniając się, że dopasowujemy próbki na podstawie ich pola `id`. + +Nextflow zawiera wiele metod łączenia kanałów, ale w tym przypadku najbardziej odpowiednim operatorem jest [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Jeśli znasz SQL, działa podobnie do operacji `JOIN`, gdzie określamy klucz, według którego łączymy, i typ łączenia do wykonania. + +### 3.1. Użyj `map` i `join` do łączenia na podstawie identyfikatora pacjenta + +Jeśli sprawdzimy dokumentację [`join`](https://www.nextflow.io/docs/latest/operator.html#join), zobaczymy, że domyślnie łączy dwa kanały na podstawie pierwszego elementu w każdej krotce. + +#### 3.1.1. Sprawdzenie struktury danych + +Jeśli nie masz jeszcze dostępnego wyjścia konsoli, uruchommy pipeline, aby sprawdzić naszą strukturę danych i zobaczyć, jak musimy ją zmodyfikować, aby połączyć według pola `id`. + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Widać, że pole `id` jest pierwszym elementem w każdej mapie meta. Aby `join` zadziałał, powinniśmy wyodrębnić pole `id` w każdej krotce. Po tym możemy po prostu użyć operatora `join`, aby połączyć dwa kanały. + +#### 3.1.2. Wyodrębnienie pola `id` + +Aby wyodrębnić pole `id`, możemy użyć [operatora `map`](https://www.nextflow.io/docs/latest/operator.html#map) do utworzenia nowej krotki z polem `id` jako pierwszym elementem. + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Może to być subtelne, ale powinieneś być w stanie zobaczyć, że pierwszy element w każdej krotce to pole `id`. + +#### 3.1.3. Połączenie dwóch kanałów + +Teraz możemy użyć operatora `join`, aby połączyć dwa kanały na podstawie pola `id`. + +Ponownie użyjemy `view`, aby wydrukować połączone wyjścia. + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Trochę trudno to powiedzieć, ponieważ jest tak szerokie, ale powinieneś być w stanie zobaczyć, że próbki zostały połączone według pola `id`. Każda krotka ma teraz format: + +- `id`: Identyfikator próbki +- `normal_meta_map`: Metadane próbki normalnej, w tym typ, replikat i ścieżka do pliku bam +- `normal_sample_file`: Plik próbki normalnej +- `tumor_meta_map`: Metadane próbki nowotworowej, w tym typ, replikat i ścieżka do pliku bam +- `tumor_sample`: Próbka nowotworowa, w tym typ, replikat i ścieżka do pliku bam + +!!! warning + + Operator `join` odrzuci wszystkie niedopasowane krotki. W tym przykładzie upewniliśmy się, że wszystkie próbki są dopasowane dla guza i normalne, ale jeśli to nie jest prawda, musisz użyć parametru `remainder: true`, aby zachować niedopasowane krotki. Sprawdź [dokumentację](https://www.nextflow.io/docs/latest/operator.html#join) po więcej szczegółów. + +Więc teraz wiesz, jak używać `map` do wyodrębnienia pola w krotce i jak używać `join` do łączenia krotek na podstawie pierwszego pola. +Dzięki tej wiedzy możemy pomyślnie łączyć kanały na podstawie wspólnego pola. + +Następnie rozważymy sytuację, w której chcesz łączyć na wielu polach. + +### 3.2. Łączenie na wielu polach + +Mamy 2 replikaty dla sampleA, ale tylko 1 dla sampleB i sampleC. W tym przypadku mogliśmy je skutecznie połączyć, używając pola `id`, ale co by się stało, gdyby były nie zsynchronizowane? Moglibyśmy pomylić próbki normalne i nowotworowe z różnych replikatów! + +Aby tego uniknąć, możemy łączyć na wielu polach. W rzeczywistości istnieje wiele sposobów, aby to osiągnąć, ale skupimy się na utworzeniu nowego klucza łączącego, który zawiera zarówno `id` próbki, jak i numer `replicate`. + +Zacznijmy od utworzenia nowego klucza łączącego. Możemy to zrobić w ten sam sposób co wcześniej, używając [operatora `map`](https://www.nextflow.io/docs/latest/operator.html#map) do utworzenia nowej krotki z polami `id` i `repeat` jako pierwszym elementem. + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Teraz powinniśmy zobaczyć, że łączenie odbywa się, ale przy użyciu zarówno pól `id`, jak i `repeat`. Uruchom przepływ pracy: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Zauważ, jak mamy krotkę dwóch elementów (pola `id` i `repeat`) jako pierwszy element każdego połączonego wyniku. To pokazuje, jak złożone elementy mogą być używane jako klucz łączący, umożliwiając dość skomplikowane dopasowywanie między próbkami z tych samych warunków. + +Jeśli chcesz zbadać więcej sposobów łączenia na różnych kluczach, sprawdź [dokumentację operatora join](https://www.nextflow.io/docs/latest/operator.html#join) po dodatkowe opcje i przykłady. + +### 3.3. Użyj `subMap` do utworzenia nowego klucza łączącego + +Poprzednie podejście traci nazwy pól z naszego klucza łączącego - pola `id` i `repeat` stają się tylko listą wartości. Aby zachować nazwy pól do późniejszego dostępu, możemy użyć [metody `subMap`](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>). + +Metoda `subMap` wyodrębnia tylko określone pary klucz-wartość z mapy. Tutaj wyodrębnimy tylko pola `id` i `repeat`, aby utworzyć nasz klucz łączący. + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Teraz mamy nowy klucz łączący, który nie tylko zawiera pola `id` i `repeat`, ale także zachowuje nazwy pól, więc możemy uzyskać do nich dostęp później według nazwy, np. `meta.id` i `meta.repeat`. + +### 3.4. Użyj nazwanego domknięcia w map + +Aby uniknąć duplikacji i zmniejszyć błędy, możemy użyć nazwanego domknięcia. Nazwane domknięcie pozwala nam utworzyć funkcję wielokrotnego użytku, którą możemy wywołać w wielu miejscach. + +Aby to zrobić, najpierw definiujemy domknięcie jako nową zmienną: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Zdefiniowaliśmy transformację map jako nazwaną zmienną, którą możemy ponownie wykorzystać. + +Zauważ, że również konwertujemy ścieżkę pliku na obiekt Path za pomocą `file()`, aby każdy proces otrzymujący ten kanał mógł prawidłowo obsłużyć plik (po więcej informacji zobacz [Praca z plikami](./working_with_files.md)). + +Zaimplementujmy domknięcie w naszym przepływie pracy: + +=== "Po" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note + + Operator `map` zmienił się z używania `{ }` na używanie `( )` do przekazania domknięcia jako argumentu. Dzieje się tak, ponieważ operator `map` oczekuje domknięcia jako argumentu, a `{ }` jest używane do definiowania anonimowego domknięcia. Podczas wywoływania nazwanego domknięcia użyj składni `( )`. + +Uruchom przepływ pracy jeszcze raz, aby sprawdzić, czy wszystko nadal działa: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Używanie nazwanego domknięcia pozwala nam ponownie wykorzystać tę samą transformację w wielu miejscach, zmniejszając ryzyko błędów i czyniąc kod bardziej czytelnym i łatwiejszym w utrzymaniu. + +### 3.5. Zmniejszenie duplikacji danych + +Mamy dużo zduplikowanych danych w naszym przepływie pracy. Każdy element w połączonych próbkach powtarza pola `id` i `repeat`. Ponieważ ta informacja jest już dostępna w kluczu grupującym, możemy uniknąć tej redundancji. Jako przypomnienie, nasza obecna struktura danych wygląda tak: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Ponieważ pola `id` i `repeat` są dostępne w kluczu grupującym, usuńmy je z reszty każdego elementu kanału, aby uniknąć duplikacji. Możemy to zrobić, używając metody `subMap` do utworzenia nowej mapy z tylko polem `type`. To podejście pozwala nam zachować wszystkie niezbędne informacje, eliminując redundancję w naszej strukturze danych. + +=== "Po" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Teraz domknięcie zwraca krotkę, gdzie pierwszy element zawiera pola `id` i `repeat`, a drugi element zawiera tylko pole `type`. To eliminuje redundancję, przechowując informacje `id` i `repeat` raz w kluczu grupującym, zachowując jednocześnie wszystkie niezbędne informacje. + +Uruchom przepływ pracy, aby zobaczyć, jak to wygląda: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Widać, że podajemy tylko pola `id` i `repeat` raz w kluczu grupującym i mamy pole `type` w danych próbki. Nie straciliśmy żadnych informacji, ale udało nam się uczynić zawartość naszego kanału bardziej zwięzłą. + +### 3.6. Usunięcie zbędnych informacji + +Usunęliśmy zduplikowane informacje powyżej, ale nadal mamy inne zbędne informacje w naszych kanałach. + +Na początku rozdzieliliśmy próbki normalne i nowotworowe za pomocą `filter`, a następnie połączyliśmy je na podstawie kluczy `id` i `repeat`. Operator `join` zachowuje kolejność, w jakiej krotki są łączone, więc w naszym przypadku, z próbkami normalnymi po lewej stronie i próbkami nowotworowymi po prawej, wynikowy kanał utrzymuje tę strukturę: `id, <elementy normalne>, <elementy nowotworowe>`. + +Ponieważ znamy pozycję każdego elementu w naszym kanale, możemy dalej uprościć strukturę, usuwając metadane `[type:normal]` i `[type:tumor]`. + +=== "Po" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Uruchom ponownie, aby zobaczyć wynik: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Wnioski + +W tej sekcji nauczyłeś się: + +- **Manipulowania krotkami**: Jak używać `map` do wyodrębnienia pola w krotce +- **Łączenia krotek**: Jak używać `join` do łączenia krotek na podstawie pierwszego pola +- **Tworzenia kluczy łączących**: Jak używać `subMap` do utworzenia nowego klucza łączącego +- **Nazwanych domknięć**: Jak używać nazwanego domknięcia w map +- **Łączenia na wielu polach**: Jak łączyć na wielu polach dla bardziej precyzyjnego dopasowania +- **Optymalizacji struktury danych**: Jak usprawnić strukturę kanału, usuwając zbędne informacje + +Masz teraz przepływ pracy, który może podzielić arkusz próbek, przefiltrować próbki normalne i nowotworowe, połączyć je według identyfikatora próbki i numeru replikatu, a następnie wydrukować wyniki. + +Jest to powszechny wzorzec w przepływach pracy bioinformatycznych, gdzie musisz dopasować próbki lub inne typy danych po przetworzeniu niezależnie, więc jest to przydatna umiejętność. Następnie przyjrzymy się powtarzaniu próbki wielokrotnie. + +## 4. Rozpraszanie próbek na interwały + +Kluczowym wzorcem w przepływach pracy bioinformatycznych jest dystrybucja analizy na regiony genomowe. Na przykład wywoływanie wariantów może być zrównoleglone poprzez podzielenie genomu na interwały (jak chromosomy lub mniejsze regiony). Ta strategia zrównoleglenia znacząco poprawia wydajność pipeline poprzez dystrybucję obciążenia obliczeniowego na wiele rdzeni lub węzłów, zmniejszając całkowity czas wykonania. + +W następnej sekcji pokażemy, jak rozdzielić nasze dane próbek na wiele interwałów genomowych. Sparujemy każdą próbkę z każdym interwałem, umożliwiając równoległe przetwarzanie różnych regionów genomowych. To pomnoży rozmiar naszego zbioru danych przez liczbę interwałów, tworząc wiele niezależnych jednostek analizy, które można później połączyć z powrotem. + +### 4.1. Rozproszenie próbek na interwały za pomocą `combine` + +Zacznijmy od utworzenia kanału interwałów. Aby zachować prostotę, użyjemy tylko 3 interwałów, które zdefiniujemy ręcznie. W rzeczywistym przepływie pracy możesz je odczytać z pliku wejściowego lub nawet utworzyć kanał z wieloma plikami interwałów. + +=== "Po" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Teraz pamiętaj, chcemy powtórzyć każdą próbkę dla każdego interwału. Jest to czasami określane jako iloczyn kartezjański próbek i interwałów. Możemy to osiągnąć za pomocą [operatora `combine`](https://www.nextflow.io/docs/latest/operator.html#combine). Weźmie każdy element z kanału 1 i powtórzy go dla każdego elementu w kanale 2. Dodajmy operator combine do naszego przepływu pracy: + +=== "Po" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Teraz uruchommy to i zobaczmy, co się stanie: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Sukces! Powtórzyliśmy każdą próbkę dla każdego pojedynczego interwału na naszej liście 3 interwałów. Skutecznie potroiliśmy liczbę elementów w naszym kanale. + +Trochę trudno to przeczytać, więc w następnej sekcji to uporządkujemy. + +### 4.2. Organizacja kanału + +Możemy użyć operatora `map` do uporządkowania i refaktoryzacji naszych danych próbek, aby były łatwiejsze do zrozumienia. Przenieśmy ciąg interwałów do mapy łączącej na pierwszym elemencie. + +=== "Po" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Rozłóżmy, co ta operacja map robi krok po kroku. + +Po pierwsze, używamy nazwanych parametrów, aby kod był bardziej czytelny. Używając nazw `grouping_key`, `normal`, `tumor` i `interval`, możemy odwoływać się do elementów w krotce według nazwy zamiast według indeksu: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Następnie łączymy `grouping_key` z polem `interval`. `grouping_key` jest mapą zawierającą pola `id` i `repeat`. Tworzymy nową mapę z `interval` i scalamy je za pomocą dodawania map Groovy (`+`): + +```groovy + grouping_key + [interval: interval], +``` + +Na koniec zwracamy to jako krotkę z trzema elementami: połączoną mapą metadanych, plikiem próbki normalnej i plikiem próbki nowotworowej: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Uruchommy to ponownie i sprawdźmy zawartość kanału: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Używanie `map` do wymuszenia, aby dane miały poprawną strukturę, może być trudne, ale jest kluczowe diff --git a/docs/pl/docs/side_quests/workflows_of_workflows.md b/docs/pl/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..01bcfa11da --- /dev/null +++ b/docs/pl/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Przepływy pracy złożone z przepływów pracy + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Podczas tworzenia potoku często zdarza się, że tworzysz podobne sekwencje procesów dla różnych typów danych lub etapów analizy. Możesz kończyć kopiując i wklejając te sekwencje procesów, co prowadzi do zduplikowanego kodu, który jest trudny w utrzymaniu; albo możesz stworzyć jeden masywny przepływ pracy, który jest trudny do zrozumienia i modyfikacji. + +Jedną z najpotężniejszych funkcji Nextflow jest jego zdolność do komponowania złożonych potoków z mniejszych, wielokrotnego użytku modułów przepływu pracy. To modularne podejście sprawia, że potoki są łatwiejsze do rozwijania, testowania i utrzymania. + +### Cele nauki + +W tej misji pobocznej zbadamy, jak rozwijać moduły przepływu pracy, które można testować i używać osobno, komponować te moduły w większy potok oraz zarządzać przepływem danych między modułami. + +Pod koniec tej misji pobocznej będziesz w stanie: + +- Rozbijać złożone potoki na logiczne, wielokrotnego użytku jednostki +- Testować każdy moduł przepływu pracy niezależnie +- Łączyć i dopasowywać przepływy pracy, aby tworzyć nowe potoki +- Udostępniać wspólne moduły przepływu pracy w różnych potokach +- Sprawić, by Twój kod był bardziej łatwy w utrzymaniu i zrozumieniu + +Te umiejętności pomogą Ci budować złożone potoki, zachowując czystą, łatwą w utrzymaniu strukturę kodu. + +### Wymagania wstępne + +Przed podjęciem tej misji pobocznej powinieneś: + +- Ukończyć tutorial [Hello Nextflow](../hello_nextflow/README.md) lub równoważny kurs dla początkujących. +- Swobodnie posługiwać się podstawowymi konceptami i mechanizmami Nextflow (procesy, kanały, operatory, moduły) + +--- + +## 0. Rozpoczęcie + +#### Otwórz środowisko szkoleniowe + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzysz środowisko szkoleniowe zgodnie z opisem w [Konfiguracja środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki do tego tutoriala. + +```bash +cd side-quests/workflows_of_workflows +``` + +Możesz ustawić VSCode, aby skupił się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz katalog `modules` zawierający kilka definicji procesów, które rozwijają to, czego nauczyłeś się w 'Hello Nextflow': + +```console title="Zawartość katalogu" +modules/ +├── say_hello.nf # Tworzy powitanie (z Hello Nextflow) +├── say_hello_upper.nf # Konwertuje na wielkie litery (z Hello Nextflow) +├── timestamp_greeting.nf # Dodaje znaczniki czasu do powitań +├── validate_name.nf # Waliduje nazwy wejściowe +└── reverse_text.nf # Odwraca zawartość tekstu +``` + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest złożenie tych modułów w dwa oddzielne przepływy pracy, które następnie skomponujemy w główny przepływ pracy: + +- `GREETING_WORKFLOW`, który waliduje nazwy, tworzy powitania i dodaje znaczniki czasu +- `TRANSFORM_WORKFLOW`, który konwertuje tekst na wielkie litery i odwraca go + +#### Lista gotowości + +Myślisz, że jesteś gotowy do rozpoczęcia? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Moje środowisko codespace działa +- [ ] Ustawiłem odpowiednio mój katalog roboczy +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +--- + +## 1. Utwórz przepływ pracy powitania + +Zacznijmy od stworzenia przepływu pracy, który waliduje nazwy i generuje powitania ze znacznikami czasu. + +### 1.1. Utwórz strukturę przepływu pracy + +```bash title="Utwórz katalog i plik przepływu pracy" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Dodaj kod pierwszego (pod)przepływu pracy + +Dodaj ten kod do `workflows/greeting.nf`: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Połącz procesy: waliduj -> utwórz pozdrowienie -> dodaj znacznik czasu + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +To jest kompletny przepływ pracy o strukturze podobnej do tych, które widziałeś w tutorialu 'Hello Nextflow', który możemy testować niezależnie. Spróbujmy tego teraz: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Działa zgodnie z oczekiwaniami, ale aby uczynić go komponowalnym, musimy zmienić kilka rzeczy. + +### 1.3. Uczyń przepływ pracy komponowalnym + +Komponowalne przepływy pracy mają kilka różnic w porównaniu z tymi, które widziałeś w tutorialu 'Hello Nextflow': + +- Blok workflow musi być nazwany +- Wejścia są deklarowane za pomocą słowa kluczowego `take:` +- Zawartość przepływu pracy jest umieszczona wewnątrz bloku `main:` +- Wyjścia są deklarowane za pomocą słowa kluczowego `emit:` + +Zaktualizujmy przepływ pracy powitania, aby pasował do tej struktury. Zmień kod na następujący: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Kanał wejściowy z imionami + + main: + // Połącz procesy: waliduj -> utwórz pozdrowienie -> dodaj znacznik czasu + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Oryginalne pozdrowienia + timestamped = timestamped_ch // Pozdrowienia ze znacznikiem czasu +} +``` + +Widać, że przepływ pracy jest teraz nazwany i ma bloki `take:` oraz `emit:`, a to są połączenia, których użyjemy do komponowania przepływu pracy wyższego poziomu. +Zawartość przepływu pracy jest również umieszczona wewnątrz bloku `main:`. Zauważ również, że usunęliśmy deklarację kanału wejściowego `names_ch`, ponieważ jest on teraz przekazywany jako argument do przepływu pracy. + +Przetestujmy przepływ pracy ponownie, aby zobaczyć, czy działa zgodnie z oczekiwaniami: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +To informuje Cię o kolejnym nowym koncepcje, 'przepływie pracy wejściowym'. Przepływ pracy wejściowy to przepływ pracy, który jest wywoływany po uruchomieniu skryptu Nextflow. Domyślnie Nextflow użyje nienazwanego przepływu pracy jako przepływu pracy wejściowego, gdy jest obecny, i to robiłeś do tej pory, z blokami workflow zaczynającymi się w ten sposób: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Ale nasz przepływ pracy powitania nie ma nienazwanego przepływu pracy, zamiast tego mamy nazwany przepływ pracy: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +Dlatego Nextflow zgłosił błąd i nie zrobił tego, czego chcieliśmy. + +Nie dodaliśmy składni `take:`/`emit:`, abyśmy mogli wywołać przepływ pracy bezpośrednio - zrobiliśmy to, abyśmy mogli komponować go z innymi przepływami pracy. Rozwiązaniem jest utworzenie głównego skryptu z nienazwanym przepływem pracy wejściowym, który importuje i wywołuje nasz nazwany przepływ pracy. + +### 1.4. Utwórz i przetestuj główny przepływ pracy + +Teraz utworzymy główny przepływ pracy, który importuje i używa przepływu pracy `greeting`. + +Utwórz `main.nf`: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Zauważ, że nasz wpis workflow w tym pliku jest nienazwany, i to dlatego, że będziemy go używać jako przepływu pracy wejściowego. + +Uruchom to i zobacz wyjście: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Działa! Opakaliśmy nazwany przepływ pracy powitania w główny przepływ pracy z nienazwanym blokiem wejściowym `workflow`. Główny przepływ pracy używa przepływu pracy `GREETING_WORKFLOW` prawie (nie całkiem) jak procesu i przekazuje kanał `names` jako argument. + +### Wnioski + +W tej sekcji nauczyłeś się kilku ważnych koncepcji: + +- **Nazwane przepływy pracy**: Tworzenie nazwanego przepływu pracy (`GREETING_WORKFLOW`), który można importować i ponownie używać +- **Interfejsy przepływu pracy**: Definiowanie jasnych wejść za pomocą `take:` i wyjść za pomocą `emit:`, aby utworzyć komponowalny przepływ pracy +- **Punkty wejścia**: Zrozumienie, że Nextflow potrzebuje nienazwanego przepływu pracy wejściowego, aby uruchomić skrypt +- **Komponowanie przepływu pracy**: Importowanie i używanie nazwanego przepływu pracy w innym przepływie pracy +- **Przestrzenie nazw przepływu pracy**: Dostęp do wyjść przepływu pracy za pomocą przestrzeni nazw `.out` (`GREETING_WORKFLOW.out.greetings`) + +Masz teraz działający przepływ pracy powitania, który: + +- Przyjmuje kanał nazw jako wejście +- Waliduje każdą nazwę +- Tworzy powitanie dla każdej poprawnej nazwy +- Dodaje znaczniki czasu do powitań +- Udostępnia zarówno oryginalne, jak i powitania ze znacznikami czasu jako wyjścia + +To modularne podejście pozwala testować przepływ pracy powitania niezależnie lub używać go jako komponentu w większych potokach. + +--- + +## 2. Dodaj przepływ pracy transformacji + +Teraz stwórzmy przepływ pracy, który stosuje transformacje tekstowe do powitań. + +### 2.1. Utwórz plik przepływu pracy + +```bash +touch workflows/transform.nf +``` + +### 2.2. Dodaj kod przepływu pracy + +Dodaj ten kod do `workflows/transform.nf`: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Kanał wejściowy z wiadomościami + + main: + // Zastosuj transformacje sekwencyjnie + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Pozdrowienia pisane wielkimi literami + reversed = reversed_ch // Odwrócone pozdrowienia pisane wielkimi literami +} +``` + +Nie będziemy powtarzać wyjaśnienia składni komponowalnej tutaj, ale zauważ, że nazwany przepływ pracy jest ponownie zadeklarowany z blokami `take:` i `emit:`, a zawartość przepływu pracy jest umieszczona wewnątrz bloku `main:`. + +### 2.3. Zaktualizuj główny przepływ pracy + +Zaktualizuj `main.nf`, aby używał obu przepływów pracy: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Uruchom workflow powitania + GREETING_WORKFLOW(names) + + // Uruchom workflow transformacji + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Wyświetl wyniki + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Uruchom kompletny potok: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Jeśli spojrzysz na jeden z tych odwróconych plików, zobaczysz, że jest to wersja powitania w wielkich literach, odwrócona: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Zawartość odwróconego pliku" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Wnioski + +Powinieneś teraz mieć kompletny potok, który: + +- Przetwarza nazwy przez przepływ pracy powitania +- Przekazuje powitania ze znacznikami czasu do przepływu pracy transformacji +- Produkuje zarówno wersje powitań w wielkich literach, jak i odwrócone + +--- + +## Podsumowanie + +W tej misji pobocznej zbadaliśmy potężną koncepcję komponowania przepływu pracy w Nextflow, która pozwala nam budować złożone potoki z mniejszych, wielokrotnego użytku komponentów. + +To modularne podejście oferuje kilka zalet w porównaniu z monolitycznymi potokami: + +- Każdy przepływ pracy można rozwijać, testować i debugować niezależnie +- Przepływy pracy można ponownie używać w różnych potokach +- Ogólna struktura potoku staje się bardziej czytelna i łatwiejsza w utrzymaniu +- Zmiany w jednym przepływie pracy niekoniecznie wpływają na inne, jeśli interfejsy pozostają spójne +- Punkty wejścia można skonfigurować do uruchamiania różnych części potoku w razie potrzeby + +_Ważne jest jednak, aby zauważyć, że chociaż wywoływanie przepływów pracy jest trochę podobne do wywoływania procesów, nie jest to tak naprawdę to samo. Nie możesz na przykład uruchomić przepływu pracy N razy, wywołując go z kanałem o rozmiarze N - musiałbyś przekazać kanał o rozmiarze N do przepływu pracy i iterować wewnętrznie._ + +Stosowanie tych technik w swojej pracy umożliwi Ci budowanie bardziej wyrafinowanych potoków Nextflow, które mogą obsługiwać złożone zadania bioinformatyczne, pozostając jednocześnie łatwymi w utrzymaniu i skalowalnymi. + +### Kluczowe wzorce + +1. **Struktura przepływu pracy**: Zdefiniowaliśmy jasne wejścia i wyjścia dla każdego przepływu pracy, używając składni `take:` i `emit:`, tworząc dobrze zdefiniowane interfejsy między komponentami, i opakaliśmy logikę przepływu pracy w bloku `main:`. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Kanały wejściowe są deklarowane tutaj + input_ch + + main: + // Logika workflow znajduje się tutaj + // Tutaj wywoływane są procesy i manipulowane są kanały + result_ch = SOME_PROCESS(input_ch) + + emit: + // Kanały wyjściowe są deklarowane tutaj + output_ch = result_ch + } + ``` + +2. **Importy przepływu pracy:** Zbudowaliśmy dwa niezależne moduły przepływu pracy i zaimportowaliśmy je do głównego potoku za pomocą instrukcji include. + + - Zaimportuj pojedynczy przepływ pracy + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Zaimportuj wiele przepływów pracy + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Zaimportuj z aliasem, aby uniknąć konfliktów nazw + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Punkty wejścia**: Nextflow wymaga nienazwanego przepływu pracy wejściowego, aby wiedzieć, gdzie rozpocząć wykonanie. Ten przepływ pracy wejściowy wywołuje Twoje nazwane przepływy pracy. + + - Nienazwany przepływ pracy (punkt wejścia) + + ```groovy + workflow { + // To jest punkt wejścia, gdy skrypt jest uruchamiany + NAMED_WORKFLOW(input_ch) + } + ``` + + - Nazwany przepływ pracy (wywoływany z przepływu pracy wejściowego) + + ```groovy + workflow NAMED_WORKFLOW { + // Musi być wywołany z głównego workflow + } + ``` + +4. **Zarządzanie przepływem danych:** Nauczyliśmy się, jak uzyskać dostęp do wyjść przepływu pracy za pomocą notacji przestrzeni nazw (`WORKFLOW_NAME.out.channel_name`) i przekazywać je do innych przepływów pracy. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Dodatkowe zasoby + +- [Dokumentacja Nextflow Workflow](https://www.nextflow.io/docs/latest/workflow.html) +- [Dokumentacja operatorów kanałów](https://www.nextflow.io/docs/latest/operator.html) +- [Dokumentacja strategii błędów](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## Co dalej? + +Wróć do [menu Misji pobocznych](./index.md) lub kliknij przycisk w prawym dolnym rogu strony, aby przejść do następnego tematu na liście. diff --git a/docs/pl/docs/side_quests/working_with_files.md b/docs/pl/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..2a34117021 --- /dev/null +++ b/docs/pl/docs/side_quests/working_with_files.md @@ -0,0 +1,1212 @@ +# Przetwarzanie plików wejściowych + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Przepływy pracy analizy naukowej często obejmują przetwarzanie dużej liczby plików. +Nextflow zapewnia potężne narzędzia do efektywnej obsługi plików, pomagając organizować i przetwarzać dane przy minimalnym nakładzie kodu. + +### Cele nauki + +W tym side queście zbadamy, jak Nextflow obsługuje pliki, od podstawowych operacji na plikach po bardziej zaawansowane techniki pracy z kolekcjami plików. +Nauczysz się wyodrębniać metadane z nazw plików, co jest powszechnym wymaganiem w pipeline'ach analizy naukowej. + +Pod koniec tego side questa będziesz potrafić: + +- Tworzyć obiekty Path z ciągów znaków ścieżek plików za pomocą metody `file()` w Nextflow +- Uzyskiwać dostęp do atrybutów pliku, takich jak nazwa, rozszerzenie i katalog nadrzędny +- Obsługiwać zarówno pliki lokalne, jak i zdalne w sposób przejrzysty przy użyciu URI +- Używać kanałów do automatyzacji obsługi plików za pomocą `channel.fromPath()` i `channel.fromFilePairs()` +- Wyodrębniać i strukturyzować metadane z nazw plików za pomocą manipulacji ciągami znaków +- Grupować powiązane pliki przy użyciu dopasowywania wzorców i wyrażeń glob +- Integrować operacje na plikach z procesami Nextflow z prawidłową obsługą wejścia +- Organizować wyjścia procesów przy użyciu struktur katalogów opartych na metadanych + +Te umiejętności pomogą Ci budować przepływy pracy, które mogą obsługiwać różne rodzaje plików wejściowych z dużą elastycznością. + +### Wymagania wstępne + +Przed podjęciem tego side questa powinieneś: + +- Ukończyć tutorial [Hello Nextflow](../../hello_nextflow/) lub równoważny kurs dla początkujących. +- Czuć się komfortowo z podstawowymi koncepcjami i mechanizmami Nextflow (procesy, kanały, operatory) + +--- + +## 0. Rozpocznij + +#### Otwórz środowisko szkoleniowe codespace + +Jeśli jeszcze tego nie zrobiłeś, upewnij się, że otworzyłeś środowisko szkoleniowe zgodnie z opisem w [Konfiguracja środowiska](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Przejdź do katalogu projektu + +Przejdźmy do katalogu, w którym znajdują się pliki do tego tutoriala. + +```bash +cd side-quests/working_with_files +``` + +Możesz ustawić VSCode, aby skupić się na tym katalogu: + +```bash +code . +``` + +#### Przejrzyj materiały + +Znajdziesz prosty plik workflow o nazwie `main.nf`, katalog `modules` zawierający dwa pliki modułów oraz katalog `data` zawierający przykładowe pliki danych. + +??? abstract "Zawartość katalogu" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Ten katalog zawiera dane sekwencjonowania paired-end od trzech pacjentów (A, B, C). + +Dla każdego pacjenta mamy próbki typu `tumor` (zazwyczaj pochodzące z biopsji guza) lub `normal` (pobrane ze zdrowej tkanki lub krwi). +Jeśli nie znasz analizy nowotworów, wiedz tylko, że odpowiada to modelowi eksperymentalnemu wykorzystującemu sparowane próbki guz/normalne do wykonywania analiz kontrastowych. + +Konkretnie dla pacjenta A mamy dwa zestawy replikatów technicznych (powtórzeń). + +Pliki danych sekwencjonowania są nazwane zgodnie z typową konwencją `_R1_` i `_R2_` dla tzw. 'odczytów w przód' i 'odczytów w tył'. + +_Nie martw się, jeśli nie znasz tego projektu eksperymentalnego, nie jest to krytyczne dla zrozumienia tego tutoriala._ + +#### Przejrzyj zadanie + +Twoim wyzwaniem jest napisanie workflow Nextflow, który będzie: + +1. **Wczytywać** pliki wejściowe przy użyciu metod obsługi plików Nextflow +2. **Wyodrębniać** metadane (ID pacjenta, replikat, typ próbki) ze struktury nazwy pliku +3. **Grupować** sparowane pliki (R1/R2) razem przy użyciu `channel.fromFilePairs()` +4. **Przetwarzać** pliki za pomocą dostarczonego modułu analizy +5. **Organizować** wyjścia w strukturę katalogów opartą na wyodrębnionych metadanych + +#### Lista gotowości + +Myślisz, że jesteś gotowy, aby zacząć? + +- [ ] Rozumiem cel tego kursu i jego wymagania wstępne +- [ ] Mój codespace działa +- [ ] Ustawiłem katalog roboczy odpowiednio +- [ ] Rozumiem zadanie + +Jeśli możesz zaznaczyć wszystkie pola, możesz zaczynać. + +--- + +## 1. Podstawowe operacje na plikach + +### 1.1. Zidentyfikuj typ obiektu za pomocą `.class` + +Spójrz na plik workflow `main.nf`: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +To mini-workflow (bez żadnych procesów), który odnosi się do pojedynczej ścieżki pliku w swoim workflow, następnie wypisuje ją do konsoli wraz z jej klasą. + +??? info "Co to jest `.class`?" + + W Nextflow, `.class` mówi nam, z jakim typem obiektu pracujemy. To jak pytanie "co to za rzecz?" aby dowiedzieć się, czy to ciąg znaków, liczba, plik czy coś innego. + To pomoże nam zilustrować różnicę między zwykłym ciągiem znaków a obiektem Path w następnych sekcjach. + +Uruchommy workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Jak widać, Nextflow wypisał ścieżkę ciągu dokładnie tak, jak ją napisaliśmy. + +To jest tylko wyjście tekstowe; Nextflow nie zrobił z tym jeszcze nic specjalnego. +Potwierdziliśmy również, że dla Nextflow jest to tylko ciąg znaków (klasy `java.lang.String`). +To ma sens, ponieważ nie powiedzieliśmy jeszcze Nextflow, że odpowiada to plikowi. + +### 1.2. Utwórz obiekt Path za pomocą file() + +Możemy powiedzieć Nextflow, jak obsługiwać pliki, tworząc [obiekty Path](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) z ciągów znaków ścieżek. + +W naszym workflow możemy przekonwertować ciąg ścieżki `data/patientA_rep1_normal_R1_001.fastq.gz` na obiekt Path używając metody `file()`, która zapewnia dostęp do właściwości i operacji na plikach. + +Edytuj `main.nf`, aby opakować ciąg za pomocą `file()` w następujący sposób: + +=== "Po" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Teraz uruchom workflow ponownie: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Tym razem widzisz pełną ścieżkę bezwzględną zamiast ścieżki względnej, którą podaliśmy jako wejście. + +Nextflow przekonwertował nasz ciąg na obiekt Path i rozwiązał go do rzeczywistej lokalizacji pliku w systemie. +Ścieżka pliku będzie teraz bezwzględna, jak w `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Zauważ również, że klasa obiektu Path to `sun.nio.fs.UnixPath`: to sposób Nextflow na reprezentowanie plików lokalnych. +Jak zobaczymy później, pliki zdalne będą miały inne nazwy klas (takie jak `nextflow.file.http.XPath` dla plików HTTP), ale wszystkie działają dokładnie w ten sam sposób i mogą być używane identycznie w Twoich workflow. + +!!! tip + + **Kluczowa różnica:** + + - **Ciąg ścieżki**: Tylko tekst, który Nextflow traktuje jako znaki + - **Obiekt Path**: Inteligentne odniesienie do pliku, z którym Nextflow może pracować + + Pomyśl o tym w ten sposób: ciąg ścieżki jest jak napisanie adresu na papierze, podczas gdy obiekt Path jest jak załadowanie adresu w urządzeniu GPS, które wie, jak tam dotrzeć i może podać szczegóły dotyczące podróży. + +### 1.3. Dostęp do atrybutów pliku + +Dlaczego to jest pomocne? Teraz, gdy Nextflow rozumie, że `myFile` jest obiektem Path, a nie tylko ciągiem znaków, możemy uzyskać dostęp do różnych atrybutów obiektu Path. + +Zaktualizujmy nasz workflow, aby wypisał wbudowane atrybuty pliku: + +=== "Po" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Widzisz różne atrybuty pliku wypisane w konsoli powyżej. + +### 1.4. Przekaż plik do procesu + +Różnica między ciągami znaków a obiektami Path staje się krytyczna, gdy zaczniesz budować rzeczywiste workflow z procesami. +Do tej pory zweryfikowaliśmy, że Nextflow traktuje teraz nasz plik wejściowy jako plik, ale zobaczmy, czy możemy faktycznie uruchomić coś na tym pliku w procesie. + +#### 1.4.1. Zaimportuj proces i zbadaj kod + +Udostępniamy wstępnie napisany moduł procesu o nazwie `COUNT_LINES`, który przyjmuje plik wejściowy i liczy, ile ma linii. + +Aby użyć procesu w workflow, wystarczy dodać instrukcję include przed blokiem workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Możesz otworzyć plik modułu, aby zbadać jego kod: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Jak widać, to dość prosty mały skrypt, który rozpakowuje plik i liczy, ile zawiera linii. + +??? info "Co robi `debug true`?" + + Dyrektywa `debug true` w definicji procesu powoduje, że Nextflow wypisuje wyjście ze skryptu (jak liczba linii "40") bezpośrednio w logu wykonania. + Bez tego zobaczyłbyś tylko status wykonania procesu, ale nie rzeczywiste wyjście ze skryptu. + + Więcej informacji na temat debugowania workflow Nextflow znajdziesz w side queście [Debugging Nextflow Workflows](debugging.md). + +#### 1.4.2. Dodaj wywołanie `COUNT_LINES` + +Teraz, gdy proces jest dostępny dla workflow, możemy dodać wywołanie procesu `COUNT_LINES`, aby uruchomić go na pliku wejściowym. + +Wprowadź następujące edycje w workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Policz linie w pliku + COUNT_LINES(myFile) + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +A teraz uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +To pokazuje, że jesteśmy w stanie odpowiednio operować na pliku wewnątrz procesu. + +Konkretnie, Nextflow wykonał następujące operacje pomyślnie: + +- Przeniósł plik do katalogu roboczego +- Zdekompresował plik .gz +- Policzył linie (40 linii w tym przypadku) +- Zakończył bez błędu + +Kluczem do tej płynnej operacji jest to, że wyraźnie mówimy Nextflow, że nasze wejście jest plikiem i powinno być traktowane jako takie. + +### 1.5. Rozwiązywanie problemów z podstawowymi błędami wejścia pliku + +To często wprowadza w błąd osoby nowe w Nextflow, więc poświęćmy kilka minut na przyjrzenie się, co się dzieje, gdy robisz to źle. + +Są dwa główne miejsca, w których możesz źle obsłużyć plik: na poziomie workflow i na poziomie procesu. + +#### 1.5.1. Błąd na poziomie workflow + +Zobaczmy, co się stanie, jeśli wrócimy do traktowania pliku jako ciągu znaków podczas określania wejścia w bloku workflow. + +Wprowadź następujące edycje w workflow, upewniając się, że zakomentowałeś instrukcje wypisywania specyficzne dla ścieżki: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Policz linie w pliku + COUNT_LINES(myFile) + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Policz linie w pliku + COUNT_LINES(myFile) + ``` + +A teraz uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +To jest ważna część: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Kiedy określasz wejście `path`, Nextflow waliduje, że przekazujesz rzeczywiste odniesienia do plików, a nie tylko ciągi znaków. +Ten błąd mówi ci, że `'data/patientA_rep1_normal_R1_001.fastq.gz'` nie jest prawidłową wartością ścieżki, ponieważ jest to ciąg znaków, a nie obiekt Path. + +Nextflow natychmiast wykrył problem i zatrzymał się przed rozpoczęciem procesu. + +#### 1.5.2. Błąd na poziomie procesu + +Drugim miejscem, w którym możemy zapomnieć określić, że chcemy, aby Nextflow traktował wejście jako plik, jest definicja procesu. + +!!! warning "Zachowaj błąd workflow z 1.5.1" + + Aby ten test działał poprawnie, zachowaj workflow w jego uszkodzonym stanie (używając zwykłego ciągu zamiast `file()`). + W połączeniu z `val` w procesie, to powoduje błąd pokazany poniżej. + +Wprowadź następującą edycję w module: + +=== "Po" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Przed" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +A teraz uruchom workflow ponownie: + +```bash +nextflow run main.nf +``` + +??? failure "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +To pokazuje wiele szczegółów dotyczących błędu, ponieważ proces jest ustawiony na wyświetlanie informacji debugowania, jak wspomniano powyżej. + +To są najbardziej istotne sekcje: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Mówi to, że system nie mógł znaleźć pliku; jednak jeśli sprawdzisz ścieżkę, istnieje plik o tej nazwie w tej lokalizacji. + +Kiedy to uruchomiliśmy, Nextflow przekazał wartość ciągu do skryptu, ale nie _przeniósł_ rzeczywistego pliku do katalogu roboczego. +Więc proces próbował użyć względnego ciągu, `data/patientA_rep1_normal_R1_001.fastq.gz`, ale ten plik nie istnieje w katalogu roboczym procesu. + +Razem wzięte, te dwa przykłady pokazują, jak ważne jest poinformowanie Nextflow, czy wejście powinno być obsługiwane jako plik. + +!!! note + + Upewnij się, że cofniesz i naprawisz oba celowe błędy przed kontynuowaniem następnej sekcji. + +### Wnioski + +- Ciągi ścieżek vs obiekty Path: Ciągi to tylko tekst, obiekty Path to inteligentne odniesienia do plików +- Metoda `file()` konwertuje ciąg ścieżki na obiekt Path, z którym Nextflow może pracować +- Możesz uzyskać dostęp do właściwości pliku, takich jak `name`, `simpleName`, `extension` i `parent` [używając atrybutów pliku](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) +- Używanie obiektów Path zamiast ciągów pozwala Nextflow prawidłowo zarządzać plikami w Twoim workflow +- Wyniki wejścia procesu: Prawidłowa obsługa plików wymaga obiektów Path, a nie ciągów, aby zapewnić, że pliki są prawidłowo przenoszone i dostępne do użycia przez procesy. + +--- + +## 2. Używanie plików zdalnych + +Jedną z kluczowych funkcji Nextflow jest możliwość płynnego przełączania między plikami lokalnymi (na tej samej maszynie) a plikami zdalnymi dostępnymi przez internet. + +Jeśli robisz to dobrze, nigdy nie powinieneś potrzebować zmieniać logiki swojego workflow, aby obsługiwać pliki pochodzące z różnych lokalizacji. +Wszystko, co musisz zrobić, aby użyć pliku zdalnego, to określić odpowiedni prefiks w ścieżce pliku podczas dostarczania go do workflow. + +Na przykład, `/path/to/data` nie ma prefiksu, co wskazuje, że jest to 'normalna' lokalna ścieżka pliku, podczas gdy `s3://path/to/data` zawiera prefiks `s3://`, wskazując, że znajduje się w magazynie obiektów S3 Amazon. + +Obsługiwanych jest wiele różnych protokołów: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Aby użyć któregokolwiek z nich, po prostu określ odpowiedni prefiks w ciągu, który jest następnie technicznie nazywany identyfikatorem URI (Uniform Resource Identifier) zamiast ścieżką pliku. +Nextflow zajmie się uwierzytelnianiem i przeniesieniem plików we właściwe miejsce, pobieraniem lub przesyłaniem oraz wszystkimi innymi operacjami na plikach, których można oczekiwać. + +Kluczową zaletą tego systemu jest to, że umożliwia nam przełączanie między środowiskami bez zmiany jakiejkolwiek logiki pipeline. +Na przykład możesz rozwijać z małym, lokalnym zestawem testowym przed przełączeniem na pełnoskalowy zestaw testowy znajdujący się w zdalnym magazynie, po prostu zmieniając URI. + +### 2.1. Użyj pliku z internetu + +Przetestujmy to, zamieniając lokalną ścieżkę, którą dostarczamy do naszego workflow, na ścieżkę HTTPS wskazującą na kopię tych samych danych przechowywanych w Github. + +!!! warning + + To będzie działać tylko wtedy, gdy masz aktywne połączenie internetowe. + +Otwórz `main.nf` ponownie i zmień ścieżkę wejściową w następujący sposób: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Użycie zdalnego pliku z internetu + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Uruchommy workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Działa! Możesz zobaczyć, że niewiele się zmieniło. + +Jedną różnicą w wyjściu konsoli jest to, że klasa obiektu ścieżki to teraz `nextflow.file.http.XPath`, podczas gdy dla ścieżki lokalnej klasa była `sun.nio.fs.UnixPath`. +Nie musisz pamiętać tych klas; wspominamy to tylko po to, aby pokazać, że Nextflow identyfikuje i obsługuje różne lokalizacje odpowiednio. + +Za kulisami Nextflow pobrał plik do katalogu tymczasowego znajdującego się w katalogu roboczym. +Ten przygotowany plik może być następnie traktowany jako plik lokalny i dowiązany symbolicznie do odpowiedniego katalogu procesu. + +Możesz zweryfikować, że tak się stało, przeglądając zawartość katalogu roboczego znajdującego się pod wartością hash procesu. + +??? abstract "Zawartość katalogu roboczego" + + Jeśli hash procesu był `8a/2ab7ca`, możesz zbadać katalog roboczy: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Dowiązanie symboliczne wskazuje na kopię przygotowaną pliku zdalnego, którą Nextflow automatycznie pobrał. + +Zauważ, że dla większych plików krok pobierania zajmie trochę więcej czasu w porównaniu z uruchomieniem na plikach lokalnych. +Jednak Nextflow sprawdza, czy już ma przygotowaną kopię, aby uniknąć niepotrzebnych pobrań. +Więc jeśli uruchomisz ponownie na tym samym pliku i nie usunąłeś przygotowanego pliku, Nextflow użyje przygotowanej kopii. + +To pokazuje, jak łatwo jest przełączać między danymi lokalnymi i zdalnymi za pomocą Nextflow, co jest kluczową funkcją Nextflow. + +!!! note + + Jednym ważnym wyjątkiem od tej zasady jest to, że nie możesz używać wzorców glob ani ścieżek katalogów z HTTPS, ponieważ HTTPS nie może wymieniać wielu plików, więc musisz określić dokładne adresy URL plików. + Jednak inne protokoły magazynowania, takie jak magazyn obiektów blob (`s3://`, `az://`, `gs://`) mogą używać zarówno globów, jak i ścieżek katalogów. + + Oto jak możesz używać wzorców glob z magazynem w chmurze: + + ```groovy title="Przykłady magazynu w chmurze (nie do uruchomienia w tym środowisku)" + // S3 with glob patterns - would match multiple files + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage ze wzorcami glob + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage ze wzorcami glob + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Pokażemy ci, jak pracować z globami w praktyce w następnej sekcji. + +### 2.2. Wróć do pliku lokalnego + +Wrócimy do używania naszych lokalnych przykładowych plików przez resztę tego side questa, więc przełączmy wejście workflow z powrotem na oryginalny plik: + +=== "Po" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Wnioski + +- Dostęp do danych zdalnych odbywa się przy użyciu URI (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow automatycznie pobierze i przeniesie dane we właściwe miejsce, o ile te ścieżki są przekazywane do procesów +- Nie pisz logiki do pobierania lub przesyłania plików zdalnych! +- Pliki lokalne i zdalne produkują różne typy obiektów, ale działają identycznie +- **Ważne**: HTTP/HTTPS działają tylko z pojedynczymi plikami (bez wzorców glob) +- Magazyn w chmurze (S3, Azure, GCS) obsługuje zarówno pojedyncze pliki, jak i wzorce glob +- Możesz bezproblemowo przełączać między lokalnymi i zdalnymi źródłami danych bez zmiany logiki kodu (o ile protokół obsługuje wymagane operacje) + +--- + +## 3. Używanie fabryki kanałów `fromPath()` + +Do tej pory pracowaliśmy z jednym plikiem na raz, ale w Nextflow zazwyczaj będziemy chcieli utworzyć kanał wejściowy z wieloma plikami wejściowymi do przetworzenia. + +Naiwnym sposobem byłoby połączenie metody `file()` z [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) w ten sposób: + +```groovy title="Przykład składni" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +To działa, ale jest nieporęczne. + +!!! tip "Kiedy używać `file()` vs `channel.fromPath()`" + + - Użyj `file()`, gdy potrzebujesz pojedynczego obiektu Path do bezpośredniej manipulacji (sprawdzanie, czy plik istnieje, odczytywanie jego atrybutów lub przekazywanie do pojedynczego wywołania procesu) + - Użyj `channel.fromPath()`, gdy potrzebujesz kanału, który może przechowywać wiele plików, szczególnie ze wzorcami glob, lub gdy pliki będą przepływać przez wiele procesów + +Tu wchodzi [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath): wygodna fabryka kanałów, która łączy wszystkie funkcje potrzebne do wygenerowania kanału z jednego lub więcej statycznych ciągów plików oraz wzorców glob. + +### 3.1. Dodaj fabrykę kanałów + +Zaktualizujmy nasz workflow, aby używał `channel.fromPath`. + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Wypisz atrybuty pliku + /* Comment these out for now, we'll come back to them! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Policz linie w pliku + // COUNT_LINES(myFile) + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Utwórz obiekt Path ze ścieżki tekstowej + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Wypisz atrybuty pliku + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Policz linie w pliku + COUNT_LINES(myFile) + ``` + +Zakomentowaliśmy również kod wypisujący atrybuty na razie i dodaliśmy instrukcję `.view` do wypisania tylko nazwy pliku. + +Uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Jak widać, ścieżka pliku jest ładowana jako obiekt typu `Path` w kanale. +Jest to podobne do tego, co zrobiłby `file()`, z wyjątkiem tego, że teraz mamy kanał, do którego możemy załadować więcej plików, jeśli chcemy. + +Używanie `channel.fromPath()` to wygodny sposób tworzenia nowego kanału wypełnionego listą plików. + +### 3.2. Wyświetl atrybuty plików w kanale + +W naszej pierwszej próbie użycia fabryki kanałów uprościliśmy kod i po prostu wypisaliśmy nazwę pliku. + +Wróćmy do wypisywania pełnych atrybutów pliku: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Policz linie w pliku + COUNT_LINES(ch_files) + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Policz linie w pliku + // COUNT_LINES(ch_files) + ``` + +Ponownie włączamy również wywołanie procesu `COUNT_LINES`, aby sprawdzić, czy przetwarzanie plików nadal działa poprawnie z naszym podejściem opartym na kanałach. + +Uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +I masz to, te same wyniki co wcześniej, ale teraz mamy plik w kanale, więc możemy dodać więcej. + +### 3.3. Używanie globu do dopasowywania wielu plików + +Jest kilka sposobów, w jakie moglibyśmy załadować więcej plików do kanału. +Tutaj pokażemy ci, jak używać wzorców glob, które są wygodnym sposobem dopasowywania i pobierania nazw plików i katalogów na podstawie znaków wieloznacznych. +Proces dopasowywania tych wzorców nazywa się "globbingiem" lub "rozszerzaniem nazw plików". + +!!! note + + Jak wspomniano wcześniej, Nextflow obsługuje globbing do zarządzania plikami wejściowymi i wyjściowymi w większości przypadków, z wyjątkiem ścieżek plików HTTPS, ponieważ HTTPS nie może wymieniać wielu plików. + +Powiedzmy, że chcemy pobrać oba pliki w parze plików związanych z danym pacjentem, `patientA`: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Ponieważ jedyną różnicą między nazwami plików jest numer replikatu, _czyli_ liczba po `R`, możemy użyć znaku wieloznacznego `*` do zastąpienia liczby w następujący sposób: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +To jest wzorzec glob, którego potrzebujemy. + +Teraz wszystko, co musimy zrobić, to zaktualizować ścieżkę pliku w fabryce kanałów, aby używała tego wzorca glob w następujący sposób: + +=== "Po" + + ```groovy title="main.nf" linenums="7" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow automatycznie rozpozna, że jest to wzorzec glob i obsłuży go odpowiednio. + +Uruchom workflow, aby to przetestować: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Jak widać, mamy teraz dwa obiekty Path w naszym kanale, co pokazuje, że Nextflow poprawnie wykonał rozszerzenie nazw plików i załadował i przetworzył oba pliki zgodnie z oczekiwaniami. + +Używając tej metody, możemy pobrać tyle lub tak niewiele plików, ile chcemy, po prostu zmieniając wzorzec glob. Gdybyśmy uczynili go bardziej ogólnym, na przykład zastępując wszystkie zmienne części nazw plików przez `*` (_np._ `data/patient*_rep*_*_R*_001.fastq.gz`) moglibyśmy pobrać wszystkie przykładowe pliki w katalogu `data`. + +### Wnioski + +- `channel.fromPath()` tworzy kanał z plikami pasującymi do wzorca +- Każdy plik jest emitowany jako oddzielny element w kanale +- Możemy użyć wzorca glob do dopasowania wielu plików +- Pliki są automatycznie konwertowane na obiekty Path z pełnymi atrybutami +- Metoda `.view()` umożliwia inspekcję zawartości kanału + +--- + +## 4. Wyodrębnianie podstawowych metadanych z nazw plików + +W większości dziedzin naukowych bardzo powszechne jest kodowanie metadanych w nazwach plików zawierających dane. +Na przykład w bioinformatyce pliki zawierające dane sekwencjonowania są często nazywane w sposób kodujący informacje o próbce, warunku, replikacie i numerze odczytu. + +Jeśli nazwy plików są konstruowane zgodnie z spójną konwencją, możesz wyodrębnić te metadane w znormalizowany sposób i użyć ich w trakcie analizy. +To jest duże „jeśli", oczywiście, i powinieneś być bardzo ostrożny, ilekroć polegasz na strukturze nazw plików; ale rzeczywistość jest taka, że to podejście jest bardzo szeroko stosowane, więc przyjrzyjmy się, jak to się robi w Nextflow. + +W przypadku naszych przykładowych danych wiemy, że nazwy plików zawierają konsekwentnie ustrukturyzowane metadane. +Na przykład nazwa pliku `patientA_rep1_normal_R2_001` koduje następujące: + +- ID pacjenta: `patientA` +- ID replikatu: `rep1` +- typ próbki: `normal` (w przeciwieństwie do `tumor`) +- zestaw odczytów: `R1` (w przeciwieństwie do `R2`) + +Zmodyfikujemy nasz workflow, aby pobrać te informacje w trzech krokach: + +1. Pobierz `simpleName` pliku, który zawiera metadane +2. Rozdziel metadane za pomocą metody zwanej `tokenize()` +3. Użyj mapy do zorganizowania metadanych + +!!! warning + + Nigdy nie powinieneś kodować wrażliwych informacji w nazwach plików, takich jak nazwiska pacjentów lub inne cechy identyfikujące, ponieważ może to zagrozić prywatności pacjentów lub innym odpowiednim ograniczeniom bezpieczeństwa. + +### 4.1. Pobierz `simpleName` + +`simpleName` jest atrybutem pliku, który odpowiada nazwie pliku pozbawionej ścieżki i rozszerzenia. + +Wprowadź następujące edycje w workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +To pobiera `simpleName` i kojarzy go z pełnym obiektem pliku za pomocą operacji `map()`. + +Uruchom workflow, aby sprawdzić, czy działa: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Każdy element w kanale jest teraz krotką zawierającą `simpleName` i oryginalny obiekt pliku. + +### 4.2. Wyodrębnij metadane z `simplename` + +W tym momencie metadane, które chcemy, są osadzone w `simplename`, ale nie możemy bezpośrednio uzyskać dostępu do poszczególnych elementów. +Więc musimy podzielić `simplename` na jego komponenty. +Na szczęście te komponenty są po prostu oddzielone podkreśleniami w oryginalnej nazwie pliku, więc możemy zastosować powszechną metodę Nextflow zwaną `tokenize()`, która jest idealna do tego zadania. + +Wprowadź następujące edycje w workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Przed" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +Metoda `tokenize()` podzieli ciąg `simpleName` wszędzie tam, gdzie znajdzie podkreślenia, i zwróci listę zawierającą podciągi. + +Uruchom workflow: + +```bash +nextflow run main.nf +``` + +??? success "Wyjście polecenia" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Teraz krotka dla każdego elementu w naszym kanale zawiera listę metadanych (_np._ `[patientA, rep1, normal, R1, 001]`) i oryginalny obiekt pliku. + +To świetnie! +Rozbiliśmy informacje o pacjencie z pojedynczego ciągu na listę ciągów. +Możemy teraz obsługiwać każdą część informacji o pacjencie osobno. + +### 4.3. Użyj mapy do zorganizowania metadanych + +Nasze metadane to obecnie po prostu płaska lista. +Łatwo ją użyć, ale trudno odczytać. + +```console +[patientA, rep1, normal, R1, 001] +``` + +Co to jest element o indeksie 3? Czy możesz powiedzieć bez odniesienia się do oryginalnego wyjaśnienia struktury metadanych? + +To świetna okazja do użycia magazynu klucz-wartość, gdzie każdy element ma zestaw kluczy i powiązanych z nimi wartości, więc możesz łatwo odwoływać się do każdego klucza, aby uzyskać odpowiednią wartość. + +W naszym przykładzie oznacza to przejście z tej organizacji: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +Do tej: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +W Nextflow nazywa się to [map](https://nextflow.io/docs/latest/script.html#maps). + +Przekonwertujmy teraz naszą płaską listę na mapę. +Wprowadź następujące edycje w workflow: + +=== "Po" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // Załaduj pliki za pomocą channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, read diff --git a/docs/pl/docs/training_collections/architects_toolkit_1.md b/docs/pl/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..08ae156c5d --- /dev/null +++ b/docs/pl/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: Zestaw Narzędzi Architekta I +hide: + - toc +--- + +# Zestaw Narzędzi Architekta I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nasze Kolekcje Szkoleniowe dostarczają wyselekcjonowane ścieżki uczenia się poprzez nasze zaawansowane materiały szkoleniowe (zwane [Side Quests](../../side_quests)). Ta kolekcja obejmuje cztery kluczowe tematy, które są często używane razem do budowania solidnych i skalowalnych przepływów pracy. + +## Cele szkolenia + +Po ukończeniu tej kolekcji zdobędziesz doświadczenie z: + +- **Złożonymi modułowymi architekturami przepływów pracy** - Łączenie wielu przepływów pracy w spójne pipeline'y +- **Kompleksowymi strategiami testowania** - Zapewnianie, że Twoje przepływy pracy są niezawodne i łatwe w utrzymaniu +- **Zarządzaniem metadanymi** - Efektywne przetwarzanie metadanych specyficznych dla próbek w całym przepływie pracy +- **Zaawansowanym przetwarzaniem danych** - Wdrażanie wydajnych wzorców dzielenia i grupowania danych + +Te umiejętności pozwolą Ci budować solidne, skalowalne i łatwe w utrzymaniu przepływy pracy Nextflow dla rzeczywistych zastosowań. + +## Odbiorcy i wymagania wstępne + +Ta kolekcja jest przeznaczona dla użytkowników, którzy ukończyli podstawowe szkolenie Nextflow i chcą zagłębić się w zaawansowane wzorce przepływów pracy, strategie testowania oraz techniki obsługi danych i metadanych. + +**Wymagania wstępne** + +- Ukończenie szkolenia [Hello Nextflow](../../hello_nextflow/) lub równoważne doświadczenie +- Podstawowa znajomość składni i koncepcji Nextflow +- Zrozumienie podstawowych wzorców tworzenia przepływów pracy +- Doświadczenie z narzędziami wiersza poleceń + +## Zawartość kolekcji + +Ta kolekcja składa się z czterech Side Quests, które obejmują uzupełniające się tematy inżynierii przepływów pracy: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - Złożona architektura i kompozycja przepływów pracy +2. **[Testing with nf-test](../../side_quests/nf-test)** - Strategie testowania przepływów pracy Nextflow +3. **[Metadata](../../side_quests/metadata)** - Obsługa metadanych dla elementów w kanałach Nextflow +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - Zaawansowane wzorce przetwarzania danych + +Każdy Side Quest jest samodzielny i obejmuje niezależne koncepcje, ale zalecamy ukończenie ich w kolejności wymienionej powyżej, aby zapewnić logiczną progresję przez tematy. + +## Jak korzystać z tej kolekcji + +Najpierw kliknij z wciśniętym klawiszem Ctrl przycisk "Open in GitHub Codespaces" poniżej, aby uruchomić środowisko szkoleniowe w osobnej karcie, następnie czytaj dalej podczas jego ładowania. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Gdy Twoje środowisko będzie uruchomione, pracuj nad kolekcją w następujący sposób: + +1. W tej karcie: Przejdź do pierwszego Side Quest wymienionego powyżej, który opisuje krok po kroku ćwiczenia rozwojowe. +2. W karcie Codespaces: Pracuj nad ćwiczeniami dla Side Quest. +3. Gdy ukończysz Side Quest, wróć na tę stronę i przejdź do następnego na liście powyżej. +4. Gdy ukończysz kolekcję, kliknij przycisk poniżej, aby wypełnić bardzo krótką ankietę. Twoja opinia pozwala nam na ciągłe ulepszanie materiałów szkoleniowych dla wszystkich. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Gotowy, aby zacząć? Zacznij od pierwszego modułu powyżej! diff --git a/docs/pl/docs/training_collections/index.md b/docs/pl/docs/training_collections/index.md new file mode 100644 index 0000000000..caaad07e3c --- /dev/null +++ b/docs/pl/docs/training_collections/index.md @@ -0,0 +1,31 @@ +```markdown +--- +title: Kolekcje Szkoleń +hide: + - toc +--- + +# Kolekcje Szkoleń + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tłumaczenie wspomagane przez AI - [dowiedz się więcej i zasugeruj ulepszenia](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ta sekcja zawiera wyselekcjonowane kolekcje modułów szkoleniowych zwanych [Side Quests](../side_quests/index.md), które mają na celu zapewnienie kompleksowego doświadczenia edukacyjnego wokół określonego tematu lub przypadku użycia. + +## Wymagania wstępne + +Każda kolekcja ma określone wymagania wstępne udokumentowane na swojej stronie indeksu. Jednak większość kolekcji zakłada: + +- Doświadczenie z linią poleceń +- Podstawowe koncepcje Nextflow i narzędzia omówione w kursie szkoleniowym dla początkujących [Hello Nextflow](../../hello_nextflow/) + +Wymagania techniczne i konfigurację środowiska można znaleźć w mini-kursie [Konfiguracja Środowiska](../../envsetup/). + +## Dostępne kolekcje + +- [Zestaw Narzędzi Architekta I](./architects_toolkit_1.md) - Kolekcja czterech Side Quests obejmujących wzorce architektury workflow do tworzenia złożonych pipeline'ów, wdrażania strategii testowania, zarządzania metadanymi oraz grupowania i dzielenia danych. _Szacowany czas trwania: 4 godziny w szkoleniu grupowym._ + +## Sugerowanie nowych kolekcji + +Aktywnie pracujemy nad rozwojem dodatkowych Side Quests i Kolekcji. +Prosimy o sugerowanie tematów, które Twoim zdaniem warto byłoby uwzględnić w Kolekcji, poprzez publikację na [forum społeczności w sekcji Szkolenia](https://community.seqera.io/c/training/). +``` diff --git a/docs/pl/llm-prompt.md b/docs/pl/llm-prompt.md new file mode 100644 index 0000000000..2d6a5a1f44 --- /dev/null +++ b/docs/pl/llm-prompt.md @@ -0,0 +1,168 @@ +# Translation Rules for Polish + +The target language for this translation is **Polish** (`pl`). + +## 1. Grammar & Tone + +- Use informal tone (Ty for one person, Wy for multiple, not Pan/Pani) +- Always capitalize second-person pronouns, including possessives (Twój, Wasz) +- Follow standard Polish spelling conventions +- Prefer active voice when possible +- Use natural Polish syntax and sentence structure; feel free to rephrase the English text wherever it improves clarity and naturalness +- Always use correct declension, even with English terms. Use apostrophe endings (e.g. "workflow'u") where necessary +- Use inanimate genders when referring to programming terms. Exception: use virile (animate masculine) to refer to Nextflow (i.e. Nextflow'a) + +### Terms with apostrophe endings + +Some English terms require Polish declension with apostrophe: + +- pipeline (pipeline'u, pipeline'owi, etc.) +- workflow (workflow'u, workflow'owi, etc.) + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Polish (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations; use Polish words where available unless referring to code keywords verbatim; always use Markdown inline code for keywords + +For example: + +- In prose: "Kanał wejściowy otrzymuje pliki..." (translate "channel" to "kanał") +- In prose with verbatim syntax: "kanały można tworzyć przy pomocy przestrzeni nazw `channel`" (keep `channel` in code formatting) +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// Wyemituj powitanie` + +## 3. Code Comments + +**Always translate code comments to Polish.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Polish translation +params.greeting = "Hello" // ustaw domyślne powitanie +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Polish: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Kanał.fromPath('*.fastq') +proces FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ wersja 24.04.0 +wykonawca > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Missing declension on English terms + +```markdown +// Wrong - no declension +Zainstaluj workflow na swoim komputerze. +Pracujemy z pipeline. + +// Correct - with proper Polish declension +Zainstaluj workflow'a na swoim komputerze. +Pracujemy z pipeline'em. +``` + +### ❌ Using formal Pan/Pani instead of Ty + +```markdown +// Wrong - too formal +Proszę uruchomić workflow... +Pan/Pani zobaczy wyniki... + +// Correct - informal Ty form +Uruchom workflow'a... +Zobaczysz wyniki... +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code). + +| English | Polish | Notes | +| --------------- | ------------------------ | ---------------------------- | +| channel | kanał / kanały | In prose | +| process | proces / procesy | In prose | +| workflow | workflow / workflow'y | Keep English, add declension | +| pipeline | pipeline / pipeline'y | Keep English, add declension | +| queue channel | kanał kolejki | | +| value channel | kanał wartości | | +| script | skrypt | | +| shell | powłoka | | +| params | parametry | In prose | +| directive | dyrektywa | | +| container | kontener | | +| input | wejście | | +| output | wyjście | | +| task | zadanie | | +| tuple | krotka | | +| operator | operator | | +| parameter | parametr | | +| environment | środowisko | | +| directory | katalog | | +| file | plik | | +| sample | próbka | | +| alignment | dopasowanie | | +| reference | referencja | | +| training | szkolenie | | +| module | moduł | | +| command | polecenie | | +| index | indeks | | +| run | uruchomić / uruchomienie | | +| parallelization | paralelizacja | | +| parallelize | paralelizować | | + +## 6. Admonition Titles + +| English | Polish | +| -------- | ----------- | +| Note | Uwaga | +| Tip | Wskazówka | +| Warning | Ostrzeżenie | +| Exercise | Ćwiczenie | +| Solution | Rozwiązanie | +| Example | Przykład | + +## 7. Section Headers + +| English | Polish | +| ----------------- | ----------------------- | +| Takeaway | Podsumowanie | +| What's next? | Co dalej? | +| Warmup | Rozgrzewka | +| Environment Setup | Konfiguracja środowiska | +| Getting Started | Pierwsze kroki | + +## 8. Tab Labels + +| English | Polish | +| ------- | -------- | +| After | Po | +| Before | Przed | +| Gitpod | Gitpod | +| Local | Lokalnie | diff --git a/docs/pl/mkdocs.yml b/docs/pl/mkdocs.yml new file mode 100644 index 0000000000..fc3e6f3f32 --- /dev/null +++ b/docs/pl/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: pl + custom_dir: ../en/overrides +extra: + consent: + title: "Zgoda na pliki cookie" + description: >- + Używamy plików cookie, aby rozpoznawać Twoje powtórne wizyty i preferencje, + a także mierzyć skuteczność naszej dokumentacji i sprawdzać, czy użytkownicy + znajdują to, czego szukają. Wyrażając zgodę, pomagasz nam ulepszać nasze + materiały szkoleniowe. + Dowiedz się więcej o tym, + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">jak używamy plików cookie</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/pl/ui-strings.yml b/docs/pl/ui-strings.yml new file mode 100644 index 0000000000..27ac06d1dc --- /dev/null +++ b/docs/pl/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - Polish (Polski) +# Te ciągi znaków są używane przez index_page_hook.py dla stron +# początkowych kursów oraz w mkdocs.yml dla zgody na pliki cookie. + +index_page: + course_summary: "Podsumowanie kursu" + additional_information: "Dodatkowe informacje" + technical_requirements: "Wymagania techniczne" + learning_objectives: "Cele szkoleniowe" + audience_prerequisites: "Odbiorcy i wymagania wstępne" + course_videos: "Filmy szkoleniowe" + +defaults: + technical_requirements: >- + Będziesz potrzebować konta GitHub LUB lokalnej instalacji Nextflow'a. + Szczegóły znajdziesz w [Opcjach środowiska](../envsetup/index.md). + videos: >- + Dla każdego rozdziału dostępne są filmy, w których instruktor + przeprowadza ćwiczenia. Film do każdej części kursu jest osadzony + na górze odpowiedniej strony. + view_playlist: "Zobacz playlistę na YouTube" diff --git a/docs/pt/docs/envsetup/01_setup.md b/docs/pt/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..6dfb03e205 --- /dev/null +++ b/docs/pt/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces é uma plataforma baseada na web que nos permite fornecer um ambiente pré-configurado para treinamento, suportado por máquinas virtuais na nuvem. +A plataforma é operada pelo GitHub (que pertence à Microsoft) e está acessível gratuitamente (com cotas de uso) para qualquer pessoa com uma conta GitHub. + +!!! warning "Aviso" + + Contas vinculadas a organizações podem estar sujeitas a certas restrições adicionais. + Se esse for o seu caso, você pode precisar usar uma conta pessoal independente ou usar uma instalação local. + +## Criando uma conta GitHub + +Você pode criar uma conta GitHub gratuita na [página inicial do GitHub](https://github.com/). + +## Iniciando seu GitHub Codespace + +Depois de fazer login no GitHub, abra este link no seu navegador para abrir o ambiente de treinamento Nextflow: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Como alternativa, você pode clicar no botão mostrado abaixo, que é repetido em cada curso de treinamento (normalmente na página de Orientação). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Você deve ver uma página onde pode criar um novo GitHub Codespace: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Configuração + +Para uso geral, você não deve precisar configurar nada. +A menos que seja especificado de outra forma no curso que você está iniciando, você pode simplesmente clicar no botão principal para continuar. + +No entanto, é possível personalizar o ambiente clicando no botão "Change options". + +??? info "Opções de configuração" + + Se você clicar no botão "Change options", terá a opção de personalizar o seguinte: + + #### Branch + + Isso permite que você selecione uma versão diferente dos materiais de treinamento. + O branch `master` geralmente contém correções de bugs e materiais que foram desenvolvidos e aprovados recentemente, mas ainda não foram lançados no site. + Outros branches contêm trabalhos em andamento que podem não estar totalmente funcionais. + + #### Machine type + + Isso permite que você personalize a máquina virtual que usará para trabalhar no treinamento. + + Usar uma máquina com mais núcleos permite aproveitar melhor a capacidade do Nextflow de paralelizar a execução do fluxo de trabalho. + No entanto, isso consumirá sua cota gratuita mais rapidamente, então não recomendamos alterar esta configuração, a menos que seja aconselhado nas instruções do curso que você planeja fazer. + + Veja 'Cotas do GitHub Codespaces' abaixo para mais detalhes sobre cotas. + +### Tempo de inicialização + +Abrir um novo ambiente GitHub Codespaces pela primeira vez pode levar vários minutos, porque o sistema precisa configurar sua máquina virtual, então não se preocupe se houver um tempo de espera. +No entanto, não deve levar mais de cinco minutos. + +## Navegando pela interface de treinamento + +Depois que seu GitHub Codespaces carregar, você deve ver algo semelhante ao seguinte (que pode abrir no modo claro, dependendo das preferências da sua conta): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +Esta é a interface do VSCode IDE, uma aplicação popular de desenvolvimento de código que recomendamos usar para o desenvolvimento com Nextflow. + +- **O editor principal** é onde o código Nextflow e outros arquivos de texto serão abertos. É aqui que você editará o código. Quando você abrir o codespace, isso mostrará uma prévia do arquivo `README.md`. +- **O terminal** abaixo do editor principal permite executar comandos. É aqui que você executará todas as linhas de comando fornecidas nas instruções do curso. +- **A barra lateral** permite personalizar seu ambiente e realizar tarefas básicas (copiar, colar, abrir arquivos, pesquisar, git, etc.). Por padrão, ela está aberta no explorador de arquivos, que permite navegar pelo conteúdo do repositório. Clicar em um arquivo no explorador o abrirá na janela do editor principal. + +Você pode ajustar as proporções relativas dos painéis da janela como preferir. + +<!-- TODO (future) Link to development best practices side quest? --> + +## Outras observações sobre o uso do GitHub Codespaces + +### Retomando uma sessão + +Depois de criar um ambiente, você pode facilmente retomá-lo ou reiniciá-lo e continuar de onde parou. +Seu ambiente expirará após 30 minutos de inatividade e salvará suas alterações por até 2 semanas. + +Você pode reabrir um ambiente em <https://github.com/codespaces/>. +Os ambientes anteriores serão listados. +Clique em uma sessão para retomá-la. + +![List GitHub Codespace sessions](img/codespaces_list.png) + +Se você salvou a URL do seu ambiente GitHub Codespaces anterior, pode simplesmente abri-la no seu navegador. +Como alternativa, clique no mesmo botão que você usou para criá-lo inicialmente: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Você deve ver a sessão anterior, a opção padrão é retomá-la: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Salvando arquivos na sua máquina local + +Para salvar qualquer arquivo do painel explorador, clique com o botão direito no arquivo e selecione `Download`. + +### Gerenciando cotas do GitHub Codespaces + +GitHub Codespaces oferece até 15 GB-mês de armazenamento por mês e 120 horas-núcleo por mês. +Isso é equivalente a cerca de 60 horas de tempo de execução do ambiente padrão usando o espaço de trabalho padrão (2 núcleos, 8 GB de RAM e 32 GB de armazenamento). + +Você pode criá-los com mais recursos (veja a explicação acima), mas isso consumirá seu uso gratuito mais rapidamente e você terá menos horas de acesso a este espaço. +Por exemplo, se você selecionar uma máquina de 4 núcleos em vez do padrão de 2 núcleos, sua cota se esgotará na metade do tempo. + +Opcionalmente, você pode comprar acesso a mais recursos. + +Para mais informações, consulte a documentação do GitHub: +[About billing for GitHub Codespaces](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/pt/docs/envsetup/02_local.md b/docs/pt/docs/envsetup/02_local.md new file mode 100644 index 0000000000..3587912407 --- /dev/null +++ b/docs/pt/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Instalação manual + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +É possível instalar tudo o que você precisa para executar o treinamento no seu próprio ambiente local manualmente. + +Aqui documentamos como fazer isso em sistemas compatíveis com POSIX padrão (assumindo uma máquina pessoal como um laptop). +Tenha em mente que alguns detalhes podem ser diferentes dependendo do seu sistema específico. + +!!! tip "Dica" + + Antes de prosseguir, você considerou usar a [abordagem de Devcontainers](03_devcontainer.md)? + Ela fornece todas as ferramentas e dependências necessárias sem exigir instalação manual. + +## Requisitos gerais de software + +Nextflow pode ser usado em qualquer sistema compatível com POSIX (Linux, macOS, Windows Subsystem for Linux, etc.) com Java instalado. +Nossos cursos de treinamento têm alguns requisitos adicionais. + +No total, você precisará ter o seguinte software instalado: + +- Bash ou shell equivalente +- [Java 11 (ou posterior, até 21)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (ou posterior) +- [VSCode](https://code.visualstudio.com) com a [extensão Nextflow](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) + +A aplicação VSCode é tecnicamente opcional, mas recomendamos fortemente que você a use para trabalhar nos cursos, bem como para seu trabalho de desenvolvimento em Nextflow em geral. + +O manual de documentação do Nextflow fornece instruções para instalar essas dependências em [Environment setup](https://www.nextflow.io/docs/latest/developer-env.html). + +## Nextflow e ferramentas nf-core + +Você precisará instalar o próprio Nextflow, mais as ferramentas nf-core, conforme detalhado nos artigos vinculados abaixo: + +- [Instalação do Nextflow](https://www.nextflow.io/docs/latest/install.html) +- [Ferramentas nf-core](https://nf-co.re/docs/nf-core-tools/installation) + +Recomendamos usar a opção de auto-instalação para Nextflow e a opção PyPI para ferramentas nf-core. + +!!! warning "Aviso" + + <!-- Any update to this content needs to be copied to the home page --> + **A partir de janeiro de 2026, todos os nossos cursos de treinamento em Nextflow requerem Nextflow versão 25.10.2 ou posterior, com sintaxe v2 estrita ativada, salvo indicação em contrário.** + + Para mais informações sobre requisitos de versão e sintaxe v2 estrita, consulte o guia [Versões do Nextflow](../info/nxf_versions.md). + + Versões mais antigas do material de treinamento correspondentes à sintaxe anterior estão disponíveis através do seletor de versão na barra de menu desta página web. + +## Materiais de treinamento + +A maneira mais fácil de baixar os materiais de treinamento é clonar o repositório inteiro usando este comando: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Cada curso tem seu próprio diretório. +Para trabalhar em um curso, abra uma janela de terminal (idealmente, de dentro da aplicação VSCode) e use `cd` para entrar no diretório relevante. + +Você pode então seguir as instruções do curso fornecidas no site. diff --git a/docs/pt/docs/envsetup/03_devcontainer.md b/docs/pt/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..99ef3d2798 --- /dev/null +++ b/docs/pt/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Devcontainers Locais + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Se você tem uma instalação local do Docker ou está disposto a instalar uma, a maneira mais fácil de trabalhar localmente com esses materiais é usar o recurso de devcontainer do Visual Studio Code. Essa abordagem fornece todas as ferramentas e dependências necessárias sem exigir instalação manual. + +## Requisitos + +Para usar a configuração de devcontainer local, você precisará de: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Uma instalação local do Docker, por exemplo: + - [Docker Desktop](https://docs.docker.com/get-docker/) (para Windows/macOS) + - [Docker Engine](https://docs.docker.com/engine/install/) (para Linux) + - [Colima](https://github.com/abiosoft/colima) (alternativa para macOS) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (incluído no Docker Desktop, mas pode precisar de instalação separada com outras configurações do Docker) +- [Extensão Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) para VS Code + +Sua instalação do Docker deve estar em execução antes de você tentar abrir o devcontainer. + +Para verificar se o Docker buildx está disponível, execute: + +```bash +docker buildx version +``` + +Se este comando falhar, você precisará instalar a extensão buildx antes de prosseguir. + +## Instruções de Configuração + +Siga estas etapas para configurar seu ambiente local usando devcontainers do VS Code: + +### Instalar a extensão "Dev Containers" no VS Code + +- Abra o VS Code +- Vá para Extensões (Ctrl+Shift+X ou Cmd+Shift+X no macOS) +- Pesquise por "Dev Containers" +- Clique em "Install" + +![Instalando a extensão Dev Containers no VS Code](img/install_extension.png) + +### Clone o repositório: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Abra o repositório no VS Code: + +- Inicie o VS Code +- Selecione **File -> Open Folder** no menu +- Navegue até e selecione a pasta do repositório de treinamento que você acabou de clonar +- Clique em **Open** + +### Reabrir no Contêiner + +Se solicitado pelo VS Code para "Reopen in Container", clique nele. Alternativamente: + +- Pressione F1 (ou Ctrl+Shift+P / Cmd+Shift+P no macOS) +- Digite "Dev Containers: Reopen in Container" +- **Importante**: Quando solicitado a selecionar uma configuração, escolha a configuração de devcontainer **local-dev** + +![Prompt Reopen in Container](img/reopen_prompt.png) + +![Selecionando configuração local](img/select_local_config.png) + +Aguarde a construção do contêiner. Isso pode levar alguns minutos na primeira vez, pois ele baixa e configura todos os componentes necessários. + +Uma vez que o contêiner esteja construído e em execução, você terá um ambiente totalmente configurado com todas as ferramentas necessárias instaladas, incluindo: + +- Java +- Nextflow +- Docker +- Git +- E todas as outras dependências necessárias para o treinamento + +![VS Code com devcontainer em execução](img/running_container.png) + +## Benefícios de Usar Devcontainers + +Usar a abordagem de devcontainer oferece várias vantagens: + +- **Consistência**: Garante um ambiente de desenvolvimento consistente em diferentes máquinas +- **Simplicidade**: Todas as dependências são pré-instaladas e configuradas +- **Isolamento**: O ambiente de desenvolvimento é isolado do seu sistema local +- **Reprodutibilidade**: Todos que usam o devcontainer obtêm a mesma configuração +- **Sem instalação manual**: Não é necessário instalar manualmente Java, Nextflow e outras ferramentas + +## Verificando Seu Ambiente + +Uma vez que seu devcontainer esteja em execução, você pode verificar se tudo está configurado corretamente executando: + +```bash +nextflow info +``` + +Isso deve exibir a versão do Nextflow e informações de tempo de execução, confirmando que seu ambiente está configurado corretamente. + +## Solução de Problemas + +Se você encontrar problemas com a configuração do devcontainer: + +1. Certifique-se de que sua instalação do Docker (Docker Desktop, Colima, Docker Engine, etc.) está em execução antes de abrir o devcontainer +2. Verifique se você selecionou a configuração **local-dev** quando solicitado +3. Verifique se o Docker buildx está instalado e funcionando executando `docker buildx version` +4. Se o contêiner falhar ao construir, tente reconstruí-lo executando o comando "Dev Containers: Rebuild Container" +5. Para problemas persistentes, consulte o [guia de solução de problemas do VS Code Dev Containers](https://code.visualstudio.com/docs/devcontainers/troubleshooting) diff --git a/docs/pt/docs/envsetup/index.md b/docs/pt/docs/envsetup/index.md new file mode 100644 index 0000000000..99fc16b90e --- /dev/null +++ b/docs/pt/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Opções de ambiente +description: Opções para configurar seu ambiente para os treinamentos Nextflow +hide: + - toc + - footer +--- + +# Opções de ambiente + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nosso objetivo é fornecer um ambiente consistente e completamente testado que permita aos alunos se concentrarem em aprender Nextflow sem ter que gastar tempo e esforço gerenciando software. +Para isso, desenvolvemos um ambiente em contêiner que contém todo o software necessário, arquivos de código e dados de exemplo para trabalhar em todos os nossos cursos. + +Este ambiente em contêiner pode ser executado diretamente no Github Codespaces ou localmente no VS Code com a extensão Devcontainers. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } __Github Codespaces__ + + --- + + GitHub Codespaces é um serviço baseado na web que nos permite fornecer um ambiente pré-construído para treinamento, com todas as ferramentas e dados incluídos, apoiado por máquinas virtuais na nuvem. É acessível gratuitamente para qualquer pessoa com uma conta Github. + + [Usar Github Codespaces:material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } __Devcontainers Locais__ + + --- + + VS Code com Devcontainers fornece um ambiente de desenvolvimento em contêiner executado localmente com todas as ferramentas de treinamento pré-configuradas. Oferece o mesmo ambiente pré-construído do Codespaces, mas executando inteiramente em seu hardware local. + + [Usar Devcontainers localmente :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Instruções para instalação manual + +Se nenhuma das opções acima atender às suas necessidades, você pode replicar este ambiente em seu próprio sistema local instalando as dependências de software manualmente e clonando o repositório de treinamento. + +[Instalação manual :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Descontinuação do Gitpod" + + O Treinamento Nextflow costumava usar o [Gitpod](https://gitpod.io) até fevereiro de 2025. + No entanto, os criadores do Gitpod decidiram encerrar a funcionalidade gratuita em favor do sistema [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex). + Por esse motivo, mudamos para o uso do GitHub Codespaces, que também oferece um ambiente de desenvolvimento com um clique, sem configuração prévia. + + Dependendo de quando você se cadastrou no Gitpod e quando exatamente eles encerrarem o serviço, você ainda pode conseguir iniciar o treinamento em seu antigo IDE na nuvem, embora não possamos garantir acesso confiável daqui para frente: + [Abrir no Gitpod](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/pt/docs/hello_nextflow/00_orientation.md b/docs/pt/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..541c189e07 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Começando + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/00_orientation.md). +/// + +!!! tip "Dica" + + Os vídeos do YouTube têm alguns superpoderes! + + - :fontawesome-solid-closed-captioning: Legendas de alta qualidade (manualmente curadas). Ative-as com o ícone :material-subtitles: + - :material-bookmark: Capítulos de vídeo na linha do tempo que correspondem aos títulos das páginas. + +## Inicie um ambiente de treinamento + +Para usar o ambiente pré-construído que fornecemos no GitHub Codespaces, clique no botão "Open in GitHub Codespaces" abaixo. Para outras opções, consulte [Opções de ambiente](../envsetup/index.md). + +Recomendamos abrir o ambiente de treinamento em uma nova aba ou janela do navegador (use clique com botão direito, ctrl-clique ou cmd-clique dependendo do seu equipamento) para que você possa continuar lendo enquanto o ambiente carrega. +Você precisará manter essas instruções abertas em paralelo para acompanhar o curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Noções básicas do ambiente + +Este ambiente de treinamento contém todo o software, código e dados necessários para trabalhar no curso de treinamento, então você não precisa instalar nada por conta própria. + +O codespace é configurado com uma interface VSCode, que inclui um explorador de sistema de arquivos, um editor de código e um terminal shell. +Todas as instruções dadas durante o curso (por exemplo, 'abra o arquivo', 'edite o código' ou 'execute este comando') se referem a essas três partes da interface do VSCode, salvo indicação em contrário. + +Se você está trabalhando neste curso por conta própria, por favor, familiarize-se com as [noções básicas do ambiente](../envsetup/01_setup.md) para mais detalhes. + +### Requisitos de versão + +Este treinamento é projetado para Nextflow 25.10.2 ou posterior **com o analisador de sintaxe v2 ATIVADO**. +Se você está usando um ambiente local ou personalizado, certifique-se de estar usando as configurações corretas conforme documentado [aqui](../info/nxf_versions.md). + +## Prepare-se para trabalhar + +Assim que seu codespace estiver em execução, há duas coisas que você precisa fazer antes de mergulhar no treinamento: definir seu diretório de trabalho para este curso específico e dar uma olhada nos materiais fornecidos. + +### Defina o diretório de trabalho + +Por padrão, o codespace abre com o diretório de trabalho definido na raiz de todos os cursos de treinamento, mas para este curso, trabalharemos no diretório `hello-nextflow/`. + +Mude de diretório agora executando este comando no terminal: + +```bash +cd hello-nextflow/ +``` + +Você pode configurar o VSCode para focar neste diretório, de modo que apenas os arquivos relevantes apareçam na barra lateral do explorador de arquivos: + +```bash +code . +``` + +!!! tip "Dica" + + Se por algum motivo você sair deste diretório (por exemplo, seu codespace adormecer), você pode sempre usar o caminho completo para retornar a ele, assumindo que você está executando isso dentro do ambiente de treinamento do GitHub Codespaces: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Agora vamos dar uma olhada no conteúdo. + +### Explore os materiais fornecidos + +Você pode explorar o conteúdo deste diretório usando o explorador de arquivos no lado esquerdo do espaço de trabalho de treinamento. +Alternativamente, você pode usar o comando `tree`. + +Ao longo do curso, usamos a saída do `tree` para representar a estrutura e o conteúdo do diretório de forma legível, às vezes com pequenas modificações para maior clareza. + +Aqui geramos um índice até o segundo nível: + +```bash +tree . -L 2 +``` + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Clique na caixa colorida para expandir a seção e visualizar seu conteúdo. +Usamos seções recolhíveis como esta para incluir a saída esperada do comando de forma concisa. + +- **Os arquivos `.nf`** são scripts de fluxo de trabalho que são nomeados com base em qual parte do curso eles são usados. + +- **O arquivo `nextflow.config`** é um arquivo de configuração que define propriedades mínimas do ambiente. + Você pode ignorá-lo por enquanto. + +- **O arquivo `greetings.csv`** em `data/` contém dados de entrada que usaremos na maior parte do curso. Ele é descrito na Parte 2 (Canais), quando o introduzimos pela primeira vez. + +- **Os arquivos `test-params.*`** são arquivos de configuração que usaremos na Parte 6 (Configuração). Você pode ignorá-los por enquanto. + +- **O diretório `solutions`** contém os scripts de fluxo de trabalho completos que resultam de cada etapa do curso. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + +## Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu ambiente está funcionando +- [ ] Eu defini meu diretório de trabalho apropriadamente + +Se você pode marcar todas as caixas, está pronto para começar. + +**Para continuar para a [Parte 1: Hello World](./01_hello_world.md), clique na seta no canto inferior direito desta página.** diff --git a/docs/pt/docs/hello_nextflow/01_hello_world.md b/docs/pt/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..5d15d83aa3 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1226 @@ +# Parte 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/01_hello_world.md). +/// + +Nesta primeira parte do curso de treinamento Hello Nextflow, começamos com um exemplo Hello World muito básico e independente de domínio, que vamos construir progressivamente para demonstrar o uso da lógica e componentes fundamentais do Nextflow. + +??? info "O que é um exemplo Hello World?" + + Um "Hello World!" é um exemplo minimalista que tem como objetivo demonstrar a sintaxe e estrutura básicas de uma linguagem de programação ou framework de software. + O exemplo geralmente consiste em imprimir a frase "Hello, World!" no dispositivo de saída, como o console ou terminal, ou escrevê-la em um arquivo. + +--- + +## 0. Aquecimento: Execute um exemplo Hello World diretamente + +Vamos demonstrar isso com um comando simples que executamos diretamente no terminal, para mostrar o que ele faz antes de encapsulá-lo no Nextflow. + +!!! tip "Dica" + + Lembre-se de que você deve estar dentro do diretório `hello-nextflow/` conforme descrito na página [Primeiros Passos](00_orientation.md). + +### 0.1. Faça o terminal dizer olá + +Execute o seguinte comando no seu terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Saída do comando" + + ```console + Hello World! + ``` + +Isso exibe o texto 'Hello World' diretamente no terminal. + +### 0.2. Escreva a saída em um arquivo + +A execução de pipelines envolve principalmente a leitura de dados de arquivos e a escrita de resultados em outros arquivos, então vamos modificar o comando para escrever a saída de texto em um arquivo para tornar o exemplo um pouco mais relevante. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Saída do comando" + + ```console + + ``` + +Isso não exibe nada no terminal. + +### 0.3. Encontre a saída + +O texto 'Hello World' agora deve estar no arquivo de saída que especificamos, chamado `output.txt`. +Você pode abri-lo no explorador de arquivos ou pela linha de comando usando o utilitário `cat`, por exemplo. + +??? abstract "Conteúdo do arquivo" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Isso é o que vamos tentar replicar com nosso primeiro fluxo de trabalho Nextflow. + +### Conclusão + +Você agora sabe como executar um comando simples no terminal que exibe algum texto e, opcionalmente, como fazer com que ele escreva a saída em um arquivo. + +### O que vem a seguir? + +Descubra como isso ficaria escrito como um fluxo de trabalho Nextflow. + +--- + +## 1. Examine o script e execute-o + +Fornecemos um script de fluxo de trabalho totalmente funcional, embora minimalista, chamado `hello-world.nf` que faz a mesma coisa que antes (escrever 'Hello World!'), mas com Nextflow. + +Para começar, vamos abrir o script do fluxo de trabalho para que você tenha uma noção de como ele está estruturado. +Então vamos executá-lo e procurar suas saídas. + +### 1.1. Examine o código + +Você encontrará o script `hello-world.nf` no seu diretório atual, que deve ser `hello-nextflow`. Abra-o no painel do editor. + +??? full-code "Arquivo de código completo" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // emite uma saudação + sayHello() + } + ``` + +Um script de fluxo de trabalho Nextflow normalmente inclui uma ou mais definições de **processo** e o **fluxo de trabalho** em si, além de alguns blocos opcionais (não presentes aqui) que apresentaremos mais tarde. + +Cada **processo** descreve quais operações a etapa correspondente no pipeline deve realizar, enquanto o **fluxo de trabalho** descreve a lógica de fluxo de dados que conecta as várias etapas. + +Vamos examinar primeiro o bloco **processo** e depois veremos o bloco **fluxo de trabalho**. + +#### 1.1.1. A definição de `process` + +O primeiro bloco de código descreve um **processo**. + +A definição do processo começa com a palavra-chave `process`, seguida pelo nome do processo e finalmente o corpo do processo delimitado por chaves. +O corpo do processo deve conter um bloco script que especifica o comando a ser executado, que pode ser qualquer coisa que você seria capaz de executar em um terminal de linha de comando. + +```groovy title="hello-world.nf" linenums="3" +/* +* Usa echo para imprimir 'Hello World!' em um arquivo +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Aqui temos um **processo** chamado `sayHello` que escreve sua **saída** em um arquivo chamado `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +Esta é uma definição de processo muito mínima que contém apenas uma definição de `output` e o `script` a ser executado. + +A definição de `output` inclui o qualificador `path`, que diz ao Nextflow que isso deve ser tratado como um caminho (inclui tanto caminhos de diretório quanto arquivos). +Outro qualificador comum é `val`. + +É importante notar que a definição de saída não _determina_ qual saída será criada. +Ela simplesmente _declara_ qual é a saída esperada, para que o Nextflow possa procurá-la assim que a execução estiver completa. +Isso é necessário para verificar se o comando foi executado com sucesso e para passar a saída para processos subsequentes, se necessário. A saída produzida que não corresponder ao que está declarado no bloco de saída não será passada para processos subsequentes. + +!!! warning "Aviso" + + Este exemplo é frágil porque codificamos o nome do arquivo de saída em dois lugares separados (o script e os blocos de saída). + Se mudarmos um mas não o outro, o script vai falhar. + Mais tarde, você aprenderá maneiras de usar variáveis para mitigar esse problema. + +Em um pipeline do mundo real, um processo geralmente contém blocos adicionais como diretivas e entradas, que apresentaremos em breve. + +#### 1.1.2. A definição de `workflow` + +O segundo bloco de código descreve o **fluxo de trabalho** em si. +A definição de fluxo de trabalho começa com a palavra-chave `workflow`, seguida por um nome opcional, depois o corpo do fluxo de trabalho delimitado por chaves. + +Aqui temos um **fluxo de trabalho** que consiste em um bloco `main:` (que diz 'este é o corpo principal do fluxo de trabalho') contendo uma chamada ao processo `sayHello`. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // emite uma saudação + sayHello() +} +``` + +Esta é uma definição de **fluxo de trabalho** muito mínima. +Em um pipeline do mundo real, o fluxo de trabalho geralmente contém múltiplas chamadas a **processos** conectados por **canais**, e os processos esperam uma ou mais **entradas** variáveis. + +Você aprenderá como adicionar entradas variáveis mais tarde neste módulo de treinamento; e aprenderá como adicionar mais processos e conectá-los por canais na Parte 3 deste curso. + +!!! tip "Dica" + + Tecnicamente, a linha `main:` não é necessária para fluxos de trabalho simples como este, então você pode encontrar fluxos de trabalho que não a tenham. + Mas precisaremos dela para aproveitar as saídas em nível de fluxo de trabalho, então podemos incluí-la desde o início. + +### 1.2. Execute o fluxo de trabalho + +Olhar para o código não é tão divertido quanto executá-lo, então vamos experimentar isso na prática. + +#### 1.2.1. Lance o fluxo de trabalho e monitore a execução + +No terminal, execute o seguinte comando: + +```bash +nextflow run hello-world.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Se a saída do seu console se parece com isso, então parabéns, você acabou de executar seu primeiro fluxo de trabalho Nextflow! + +A saída mais importante aqui é a última linha, que está destacada na saída acima: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Isso nos diz que o processo `sayHello` foi executado com sucesso uma vez (`1 of 1 ✔`). + +É importante notar que esta linha também informa onde encontrar a saída da chamada do processo `sayHello`. +Vamos ver isso agora. + +#### 1.2.2. Encontre a saída e os logs no diretório `work` + +Quando você executa o Nextflow pela primeira vez em um determinado diretório, ele cria um diretório chamado `work` onde escreverá todos os arquivos (e quaisquer links simbólicos) gerados durante a execução. + +Dentro do diretório `work`, o Nextflow organiza saídas e logs por chamada de processo. +Para cada chamada de processo, o Nextflow cria um subdiretório aninhado, nomeado com um hash para torná-lo único, onde preparará todas as entradas necessárias (usando links simbólicos por padrão), escreverá arquivos auxiliares e escreverá logs e quaisquer saídas do processo. + +O caminho para esse subdiretório é mostrado de forma truncada entre colchetes na saída do console. +Olhando para o que obtivemos na execução mostrada acima, a linha de log do console para o processo sayHello começa com `[65/7be2fa]`. Isso corresponde ao seguinte caminho de diretório: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +Vamos dar uma olhada no que há lá. + +??? abstract "Conteúdo do diretório" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Não está vendo a mesma coisa?" + + Os nomes exatos dos subdiretórios serão diferentes no seu sistema. + + Se você navegar pelo conteúdo do subdiretório de tarefa no explorador de arquivos do VSCode, verá todos os arquivos imediatamente. + No entanto, os arquivos de log estão configurados para serem invisíveis no terminal, então se você quiser usar `ls` ou `tree` para visualizá-los, precisará definir a opção relevante para exibir arquivos invisíveis. + + ```bash + tree -a work + ``` + +A primeira coisa que você deseja ver é a saída real do fluxo de trabalho, ou seja, o arquivo `output.txt` produzido pelo processo `sayHello`. +Abra-o e você encontrará a saudação `Hello World!`, que era o objetivo do nosso fluxo de trabalho minimalista. + +??? abstract "Conteúdo do arquivo" + + ```console title="output.txt" + Hello World! + ``` + +Funcionou! + +Concedido, pode parecer muito código de wrapper para um resultado tão pequeno, mas o valor de todo esse código de wrapper se tornará mais óbvio quando começarmos a ler arquivos de entrada e encadear várias etapas. + +Dito isso, vamos também olhar os outros arquivos naquele diretório. Esses são arquivos auxiliares e de log produzidos pelo Nextflow como parte da execução da tarefa. + +- **`.command.begin`**: Metadados relacionados ao início da execução da chamada do processo +- **`.command.err`**: Mensagens de erro (`stderr`) emitidas pela chamada do processo +- **`.command.log`**: Saída de log completa emitida pela chamada do processo +- **`.command.out`**: Saída regular (`stdout`) pela chamada do processo +- **`.command.run`**: Script completo executado pelo Nextflow para executar a chamada do processo +- **`.command.sh`**: O comando que foi realmente executado pela chamada do processo +- **`.exitcode`**: O código de saída resultante do comando + +O arquivo `.command.sh` é especialmente útil porque informa o comando principal que o Nextflow executou, não incluindo toda a contabilidade e configuração de tarefa/ambiente. + +??? abstract "Conteúdo do arquivo" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Isso corresponde ao que executamos anteriormente manualmente. + +Neste caso é muito direto porque o comando do processo foi codificado, mas mais adiante no curso você verá comandos de processo que envolvem alguma interpolação de variáveis. +Isso torna especialmente valioso poder ver exatamente como o Nextflow interpretou o código e qual comando foi produzido quando você está solucionando problemas de uma execução com falha. + +### 1.3. Execute o fluxo de trabalho novamente + +Tente executar novamente o fluxo de trabalho algumas vezes e depois olhe os diretórios de tarefa em `work/`. + +??? abstract "Conteúdo do diretório" + + ```console + 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 + ``` + +Você verá que um novo subdiretório com um conjunto completo de arquivos de saída e log foi criado para cada execução. +Isso mostra que executar o mesmo fluxo de trabalho várias vezes não sobrescreverá os resultados de execuções anteriores. + +### Conclusão + +Você sabe como decifrar um script Nextflow simples, executá-lo e encontrar a saída e arquivos de log relevantes no diretório work. + +### O que vem a seguir? + +Aprenda como publicar as saídas do fluxo de trabalho em um local mais conveniente. + +--- + +## 2. Publique saídas + +Como você acabou de aprender, a saída produzida pelo nosso pipeline está enterrada em um diretório de trabalho várias camadas abaixo. +Isso é feito propositalmente; o Nextflow está no controle deste diretório e não devemos interagir com ele. +No entanto, isso torna inconveniente recuperar saídas que nos interessam. + +Felizmente, o Nextflow fornece uma maneira de publicar saídas em um diretório designado usando [definições de saída em nível de fluxo de trabalho](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs). + +### 2.1. Uso básico + +Isso vai envolver dois novos pedaços de código: + +1. Um bloco `publish:` dentro do corpo do `workflow`, declarando saídas de processo. +2. Um bloco `output` no script especificando opções de saída como modo e localização. + +#### 2.1.1. Declare a saída do processo `sayHello` + +Precisamos adicionar um bloco `publish:` ao corpo do fluxo de trabalho (mesmo tipo de elemento de código que o bloco `main:`) e listar a saída do processo `sayHello()`. + +No arquivo de script do fluxo de trabalho `hello-world.nf`, adicione as seguintes linhas de código: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // emite uma saudação + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emite uma saudação + sayHello() + } + ``` + +Você vê que podemos nos referir à saída do processo simplesmente fazendo `sayHello().out`, e atribuir a ela um nome arbitrário, `first_output`. + +#### 2.1.2. Adicione um bloco `output:` ao script + +Agora só precisamos adicionar o bloco `output:` onde o caminho do diretório de saída será especificado. Note que este novo bloco fica **fora** e **abaixo** do bloco `workflow` dentro do script. + +No arquivo de script do fluxo de trabalho `hello-world.nf`, adicione as seguintes linhas de código: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // emite uma saudação + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // emite uma saudação + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Podemos usar isso para atribuir caminhos específicos a quaisquer saídas de processo declaradas no bloco `workflow`. +Mais tarde, você aprenderá sobre maneiras de gerar estruturas sofisticadas de diretório de saída, mas por enquanto, estamos apenas codificando um caminho mínimo para simplicidade. + +#### 2.1.3. Execute o fluxo de trabalho + +Agora execute o script de fluxo de trabalho modificado: + +```bash +nextflow run hello-world.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +A saída do terminal deve parecer familiar. Externamente, nada mudou. + +No entanto, verifique seu explorador de arquivos: desta vez, o Nextflow criou um novo diretório chamado `results/`. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +Dentro do diretório `results`, encontramos um link simbólico para o `output.txt` produzido no diretório work pelo comando que acabamos de executar. + +Isso nos permite recuperar facilmente arquivos de saída sem ter que vasculhar o subdiretório work. + +### 2.2. Defina um local personalizado + +Ter um local padrão é ótimo, mas você pode querer personalizar onde os resultados são salvos e como eles são organizados. + +Por exemplo, você pode querer organizar suas saídas em subdiretórios. +A maneira mais simples de fazer isso é atribuir um caminho de saída específico por saída. + +#### 2.2.1. Modifique o caminho de saída + +Mais uma vez, modificar o comportamento de publicação para uma saída específica é realmente direto. +Para definir um local personalizado, basta editar o `path` de acordo: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Como isso é definido no nível da saída individual, você pode especificar diferentes locais e subdiretórios para atender às suas necessidades. + +#### 2.2.2. Execute o fluxo de trabalho novamente + +Vamos experimentar. + +```bash +nextflow run hello-world.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Desta vez o resultado é escrito no subdiretório especificado. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Você vê que o resultado da execução anterior ainda está lá. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +Você pode usar quantos níveis de aninhamento desejar. +Também é possível usar o nome do processo ou outras variáveis para nomear os diretórios usados para organizar resultados, e é possível alterar o nome padrão do diretório de saída de nível superior (que é controlado pela variável especial `outputDir`). +Cobriremos essas opções em treinamentos posteriores. + +### 2.3. Defina o modo de publicação para copiar + +Por padrão, as saídas são publicadas como links simbólicos do diretório `work`. +Isso significa que há apenas um único arquivo no sistema de arquivos. + +Isso é ótimo quando você está lidando com arquivos muito grandes, para os quais você não quer armazenar várias cópias. +No entanto, se você excluir o diretório work em algum momento (abordaremos operações de limpeza em breve), você perderá o acesso ao arquivo. +Portanto, você precisa ter um plano para salvar cópias de quaisquer arquivos importantes em um local seguro. + +Uma opção fácil é mudar o modo de publicação para copiar para as saídas que você se importa. + +#### 2.3.1. Adicione a diretiva mode + +Esta parte é realmente direta. +Basta adicionar `mode 'copy'` à definição de saída relevante em nível de fluxo de trabalho: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Isso define o modo de publicação para essa saída específica. + +#### 2.3.2. Execute o fluxo de trabalho novamente + +Vamos experimentar. + +```bash +nextflow run hello-world.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Desta vez, se você olhar os resultados, o arquivo é uma cópia adequada em vez de apenas um link simbólico. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Como isso também é definido no nível da saída individual, permite que você defina o modo de publicação de forma granular. +Isso será especialmente útil mais tarde quando passarmos para pipelines de múltiplas etapas, onde você pode querer copiar apenas as saídas finais e deixar saídas intermediárias como links simbólicos, por exemplo. + +Como observado anteriormente, existem outras opções mais sofisticadas para controlar como as saídas são publicadas. +Mostraremos como usá-las no devido tempo em sua jornada com o Nextflow. + +### 2.4. Nota sobre diretivas `publishDir` em nível de processo + +Até muito recentemente, a forma estabelecida de publicar saídas era fazê-lo no nível de cada processo individual usando uma diretiva `publishDir`. + +Para conseguir o que acabamos de fazer para as saídas do processo `sayHello`, teríamos adicionado a seguinte linha à definição do processo: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Você ainda encontrará este padrão de código por toda parte em pipelines e módulos de processo Nextflow mais antigos, por isso é importante estar ciente dele. +No entanto, não recomendamos usá-lo em qualquer trabalho novo, pois eventualmente será proibido em versões futuras da linguagem Nextflow. + +### Conclusão + +Você sabe como publicar saídas de fluxo de trabalho em um local mais conveniente. + +### O que vem a seguir? + +Aprenda a fornecer uma entrada variável via parâmetro de linha de comando e utilizar valores padrão de forma eficaz. + +--- + +## 3. Use uma entrada variável passada na linha de comando + +Em seu estado atual, nosso fluxo de trabalho usa uma saudação codificada no comando do processo. +Queremos adicionar alguma flexibilidade usando uma variável de entrada, para que possamos mudar mais facilmente a saudação em tempo de execução. + +Isso requer que façamos três conjuntos de mudanças em nosso script: + +1. Alterar o processo para esperar uma entrada variável +2. Configurar um parâmetro de linha de comando para capturar a entrada do usuário +3. Passar a entrada para o processo no corpo do fluxo de trabalho + +Vamos fazer essas mudanças uma de cada vez. + +### 3.1. Altere o processo `sayHello` para esperar uma entrada variável + +Precisamos editar a definição do processo para (1) aceitar uma variável de entrada e (2) usar essa variável na linha de comando. + +#### 3.1.1. Adicione um bloco de entrada à definição do processo + +Primeiro, vamos adaptar a definição do processo para aceitar uma entrada chamada `greeting`. + +No bloco do processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +A variável `greeting` é prefixada por `val` para dizer ao Nextflow que é um valor (não um caminho). + +#### 3.1.2. Edite o comando do processo para usar a variável de entrada + +Agora trocamos o valor codificado original pelo valor da variável de entrada que esperamos receber. + +No bloco do processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +O símbolo `$` e as chaves (`{ }`) dizem ao Nextflow que este é um nome de variável que precisa ser substituído pelo valor de entrada real (=interpolado). + +!!! tip "Dica" + + As chaves (`{ }`) eram tecnicamente opcionais em versões anteriores do Nextflow, então você pode ver fluxos de trabalho mais antigos onde isso está escrito como `echo '$greeting' > output.txt`. + +Agora que o processo `sayHello()` está pronto para aceitar uma entrada variável, precisamos de uma maneira de fornecer um valor de entrada para a chamada do processo em nível de fluxo de trabalho. + +### 3.2. Configure um parâmetro de linha de comando para capturar a entrada do usuário + +Poderíamos simplesmente codificar uma entrada diretamente fazendo a chamada do processo `sayHello('Hello World!')`. +No entanto, quando estivermos fazendo trabalho real com nosso fluxo de trabalho, vamos querer ser capazes de controlar suas entradas a partir da linha de comando. + +Boa notícia: o Nextflow tem um sistema de parâmetros de fluxo de trabalho integrado chamado `params`, que facilita declarar e usar parâmetros CLI. + +A sintaxe geral é declarar `params.<nome_do_parâmetro>` para dizer ao Nextflow para esperar um parâmetro `--<nome_do_parâmetro>` na linha de comando. + +Aqui, queremos criar um parâmetro chamado `--input`, então precisamos declarar `params.input` em algum lugar no fluxo de trabalho. +Em princípio podemos escrevê-lo em qualquer lugar; mas como vamos querer passá-lo para a chamada do processo `sayHello()`, podemos conectá-lo lá diretamente escrevendo `sayHello(params.input)`. + +No bloco do fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emite uma saudação + sayHello(params.input) + ``` + +=== "Antes" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // emite uma saudação + sayHello() + ``` + +Isso diz ao Nextflow para executar o processo `sayHello` no valor fornecido através do parâmetro `--input`. + +Na prática, realizamos as etapas (2) e (3) descritas no início da seção de uma só vez. + +### 3.3. Execute o comando do fluxo de trabalho + +Vamos executá-lo! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Se você fez todas essas edições corretamente, deve obter outra execução bem-sucedida. + +Certifique-se de abrir o arquivo de saída para verificar se você agora tem a nova versão da saudação. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Note como a nova execução sobrescreveu o arquivo de saída publicado no diretório `results`. +No entanto, os resultados das execuções anteriores ainda estão preservados nos diretórios de tarefa em `work`. + +!!! tip "Dica" + + Você pode distinguir facilmente parâmetros em nível de Nextflow de parâmetros em nível de pipeline. + + - Parâmetros que se aplicam a um pipeline sempre levam um hífen duplo (`--`). + - Parâmetros que modificam uma configuração do Nextflow, _por exemplo_ o recurso `-resume` que usamos anteriormente, levam um hífen simples (`-`). + +### 3.4. Use valores padrão para parâmetros de linha de comando + +Ok, isso foi conveniente, mas em muitos casos, faz sentido fornecer um valor padrão para um determinado parâmetro para que você não precise especificá-lo para cada execução. + +#### 3.4.1. Defina um valor padrão para o parâmetro CLI + +Vamos dar ao parâmetro `input` um valor padrão declarando-o antes da definição do fluxo de trabalho. + +```groovy title="hello-world.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String = 'Holà mundo!' +} +``` + +Como você vê, podemos especificar o tipo de entrada que o fluxo de trabalho espera (Nextflow 25.10.2 e posterior). +A sintaxe é `nome: Tipo = valor_padrão`. +Os tipos suportados incluem `String`, `Integer`, `Float`, `Boolean` e `Path`. + +!!! info + + Em fluxos de trabalho mais antigos, você pode ver que todo o bloco `params` está escrito como apenas `input = 'Holà mundo!'`. + +À medida que você adiciona mais parâmetros ao seu pipeline, deve adicioná-los todos a este bloco, quer você precise ou não dar a eles um valor padrão. +Isso facilitará encontrar todos os parâmetros configuráveis de relance. + +#### 3.4.2. Execute o fluxo de trabalho novamente sem especificar o parâmetro + +Agora que você tem um valor padrão definido, pode executar o fluxo de trabalho novamente sem ter que especificar um valor na linha de comando. + +```bash +nextflow run hello-world.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +A saída estará no mesmo lugar que anteriormente, mas o conteúdo deve ser atualizado com o novo texto. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +O Nextflow usou o valor padrão do parâmetro de saudação para criar a saída. + +#### 3.4.3. Substitua o valor padrão + +Se você fornecer o parâmetro na linha de comando, o valor CLI substituirá o valor padrão. + +Experimente: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Mais uma vez, você deve encontrar a saída atualizada correspondente no seu diretório de resultados. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Nota" + + No Nextflow, há vários lugares onde você pode especificar valores para parâmetros. + Se o mesmo parâmetro for definido com valores diferentes em vários lugares, o Nextflow determinará qual valor usar com base na ordem de precedência descrita [aqui](https://www.nextflow.io/docs/latest/config.html). + + Cobriremos isso com mais detalhes na Parte 6 (Configuração). + +### Conclusão + +Você sabe como usar uma entrada variável simples fornecida em tempo de execução via parâmetro de linha de comando, bem como configurar, usar e substituir valores padrão. + +### O que vem a seguir? + +Aprenda como gerenciar execuções de forma mais conveniente. + +--- + +## 4. Gerencie execuções de fluxo de trabalho + +Saber como lançar fluxos de trabalho e recuperar saídas é ótimo, mas você rapidamente descobrirá que há alguns outros aspectos do gerenciamento de fluxo de trabalho que tornarão sua vida mais fácil, especialmente se você estiver desenvolvendo seus próprios fluxos de trabalho. + +Aqui mostramos como usar o recurso `resume` para quando você precisar relançar o mesmo fluxo de trabalho, como inspecionar o log de execuções passadas com `nextflow log`, e como excluir diretórios work mais antigos com `nextflow clean`. + +<!-- Any other cool options we should include? Added log --> + +### 4.1. Relance um fluxo de trabalho com `-resume` + +Às vezes, você vai querer executar novamente um pipeline que já lançou anteriormente sem refazer nenhuma etapa que já foi concluída com sucesso. + +O Nextflow tem uma opção chamada `-resume` que permite fazer isso. +Especificamente, neste modo, quaisquer processos que já foram executados com exatamente o mesmo código, configurações e entradas serão ignorados. +Isso significa que o Nextflow só executará processos que você adicionou ou modificou desde a última execução, ou aos quais você está fornecendo novas configurações ou entradas. + +Existem duas vantagens principais em fazer isso: + +- Se você está no meio do desenvolvimento do seu pipeline, pode iterar mais rapidamente, pois só precisa executar o(s) processo(s) em que está trabalhando ativamente para testar suas alterações. +- Se você está executando um pipeline em produção e algo dá errado, em muitos casos você pode corrigir o problema e relançar o pipeline, e ele retomará a execução do ponto de falha, o que pode economizar muito tempo e computação. + +Para usá-lo, basta adicionar `-resume` ao seu comando e executá-lo: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Saída do comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +A saída do console deve parecer familiar, mas há uma coisa que é um pouco diferente em comparação com antes. + +Procure pela parte `cached:` que foi adicionada na linha de status do processo (linha 5), o que significa que o Nextflow reconheceu que já fez este trabalho e simplesmente reutilizou o resultado da execução anterior bem-sucedida. + +Você também pode ver que o hash do subdiretório work é o mesmo da execução anterior. +O Nextflow está literalmente apontando para a execução anterior e dizendo "Eu já fiz isso lá." + +!!! tip "Dica" + + Quando você executa novamente um pipeline com `resume`, o Nextflow não sobrescreve nenhum arquivo publicado fora do diretório work por quaisquer execuções que foram executadas com sucesso anteriormente. + +### 4.2. Inspecione o log de execuções passadas + +Quer você esteja desenvolvendo um novo pipeline ou executando pipelines em produção, em algum momento você provavelmente precisará consultar informações sobre execuções passadas. +Aqui está como fazer isso. + +Sempre que você lança um fluxo de trabalho nextflow, uma linha é escrita em um arquivo de log chamado `history`, em um diretório oculto chamado `.nextflow` no diretório de trabalho atual. + +??? abstract "Conteúdo do arquivo" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Este arquivo fornece o timestamp, nome da execução, status, ID de revisão, ID de sessão e linha de comando completa para cada execução do Nextflow que foi lançada a partir do diretório de trabalho atual. + +Uma maneira mais conveniente de acessar essas informações é usar o comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Saída do comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Isso exibirá o conteúdo do arquivo de log no terminal, aumentado com uma linha de cabeçalho. + +Você notará que o ID de sessão muda sempre que você executa um novo comando `nextflow run`, EXCETO se você estiver usando a opção `-resume`. +Nesse caso, o ID de sessão permanece o mesmo. + +O Nextflow usa o ID de sessão para agrupar informações de cache de execução no diretório `cache`, também localizado em `.nextflow`. + +### 4.3. Exclua diretórios work mais antigos + +Durante o processo de desenvolvimento, você normalmente executará seu rascunho de pipeline um grande número de vezes, o que pode levar a um acúmulo de muitos arquivos em muitos subdiretórios. + +Felizmente, o Nextflow inclui um subcomando útil `clean` que pode excluir automaticamente os subdiretórios work de execuções passadas que você não se importa mais. + +#### 4.3.1. Determine os critérios de exclusão + +Existem várias [opções](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para determinar o que excluir. + +Aqui mostramos um exemplo que exclui todos os subdiretórios de execuções antes de uma determinada execução, especificada usando seu nome de execução. + +Procure a execução bem-sucedida mais recente onde você não usou `-resume`; no nosso caso, o nome da execução foi `golden_cantor`. + +O nome da execução é a string de duas partes gerada por máquina mostrada entre colchetes na linha de saída do console `Launching (...)`. +Você também pode usar o log do Nextflow para procurar uma execução com base em seu timestamp e/ou linha de comando. + +#### 4.3.2. Faça uma execução de teste + +Primeiro usamos a flag de execução de teste `-n` para verificar o que será excluído dado o comando: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Saída do comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Sua saída terá nomes de diretório de tarefa diferentes e pode ter um número diferente de linhas, mas deve parecer semelhante ao exemplo. + +Se você não ver nenhuma linha de saída, você não forneceu um nome de execução válido ou não há execuções passadas para excluir. Certifique-se de alterar `golden_cantor` no comando de exemplo para qualquer que seja o nome de execução mais recente correspondente no seu log. + +#### 4.3.3. Prossiga com a exclusão + +Se a saída parecer como esperado e você quiser prosseguir com a exclusão, execute novamente o comando com a flag `-f` em vez de `-n`: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Saída do comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +A saída deve ser semelhante à anterior, mas agora dizendo 'Removed' em vez de 'Would remove'. +Note que isso não remove os subdiretórios de dois caracteres (como `a3/` acima), mas esvazia seu conteúdo. + +!!! Warning "Aviso" + + Excluir subdiretórios work de execuções passadas os remove do cache do Nextflow e exclui quaisquer saídas que foram armazenadas nesses diretórios. + Isso significa que quebra a capacidade do Nextflow de retomar a execução sem executar novamente os processos correspondentes. + + Você é responsável por salvar quaisquer saídas que você se importa ou planeja confiar! Essa é a principal razão pela qual preferimos usar o modo `copy` em vez do modo `symlink` para a diretiva `publish`. + +### Conclusão + +Você sabe como publicar saídas em um diretório específico, relançar um pipeline sem repetir etapas que já foram executadas de forma idêntica e usar o comando `nextflow clean` para limpar diretórios work antigos. + +De forma mais geral, você sabe como interpretar um fluxo de trabalho Nextflow simples, gerenciar sua execução e recuperar saídas. + +### O que vem a seguir? + +Faça uma pequena pausa, você mereceu! + +Quando estiver pronto, passe para [**Parte 2: Hello Channels**](./02_hello_channels.md) para aprender como usar canais para alimentar entradas em seu fluxo de trabalho, o que permitirá que você aproveite o paralelismo de fluxo de dados integrado do Nextflow e outros recursos poderosos. + +--- + +## Quiz + +<quiz> +Quais são os componentes mínimos necessários de um processo Nextflow? +- [ ] Apenas blocos de entrada e saída +- [x] Blocos de saída e script +- [ ] Blocos de entrada, saída e script +- [ ] Apenas um bloco script + +Saiba mais: [1.1.1. A definição de processo](#111-a-definição-de-process) +</quiz> + +<quiz> +Qual é o propósito do bloco de saída em um processo? +- [ ] Imprimir resultados no console +- [ ] Salvar arquivos no diretório work +- [x] Declarar saídas esperadas do processo +- [ ] Definir variáveis de ambiente + +Saiba mais: [1.1.1. A definição de processo](#111-a-definição-de-process) +</quiz> + +<quiz> +Qual comando é usado para executar um fluxo de trabalho Nextflow? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Olhando para o diretório work de uma tarefa, qual arquivo contém o comando real que foi executado? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Saiba mais: [1.2.2. Encontre a saída e os logs no diretório `work`](#122-encontre-a-saída-e-os-logs-no-diretório-work) +</quiz> + +<quiz> +O que a flag `-resume` faz? +- [ ] Reinicia o fluxo de trabalho do início +- [ ] Pausa o fluxo de trabalho +- [x] Ignora processos que já foram concluídos com sucesso +- [ ] Cria um backup do fluxo de trabalho + +Saiba mais: [4.1. Relance um fluxo de trabalho com `-resume`](#41-relance-um-fluxo-de-trabalho-com--resume) +</quiz> + +<quiz> +Qual é o modo padrão para publicar saídas de fluxo de trabalho? +- [ ] Copiar arquivos para o diretório de saída +- [x] Criar links simbólicos no diretório de saída +- [ ] Mover arquivos para o diretório de saída +- [ ] Comprimir arquivos no diretório de saída + +Saiba mais: [2.3. Defina o modo de publicação para copiar](#23-defina-o-modo-de-publicação-para-copiar) +</quiz> + +<quiz> +Como você passa um valor de parâmetro para um fluxo de trabalho Nextflow a partir da linha de comando? +- [ ] `-parameter value` +- [ ] `--parameter:value` +- [x] `--parameter value` +- [ ] `-p parameter=value` + +Saiba mais: [3.2. Configure um parâmetro de linha de comando para capturar a entrada do usuário](#32-configure-um-parâmetro-de-linha-de-comando-para-capturar-a-entrada-do-usuário) +</quiz> + +<quiz> +Como você referencia uma variável dentro de um bloco script do Nextflow? +- [ ] Use a sintaxe `%variable%` +- [x] Use a sintaxe `#!groovy ${variable}` +- [ ] Use a sintaxe `{{variable}}` +- [ ] Use a sintaxe `[variable]` +</quiz> diff --git a/docs/pt/docs/hello_nextflow/02_hello_channels.md b/docs/pt/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..307803ddcb --- /dev/null +++ b/docs/pt/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1431 @@ +# Parte 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/02_hello_channels.md). +/// + +Na Parte 1 deste curso (Hello World), mostramos como fornecer uma entrada variável para um processo fornecendo a entrada diretamente na chamada do processo: `sayHello(params.input)`. +Essa foi uma abordagem deliberadamente simplificada. +Na prática, essa abordagem tem grandes limitações; ou seja, ela só funciona para casos muito simples onde queremos executar o processo apenas uma vez, em um único valor. +Na maioria dos casos de uso realistas de fluxos de trabalho, queremos processar múltiplos valores (dados experimentais para múltiplas amostras, por exemplo), então precisamos de uma maneira mais sofisticada de lidar com entradas. + +É para isso que servem os **canais** do Nextflow. +Canais são filas projetadas para lidar com entradas eficientemente e transportá-las de uma etapa para outra em fluxos de trabalho de múltiplas etapas, ao mesmo tempo que fornecem paralelismo integrado e muitos benefícios adicionais. + +Nesta parte do curso, você aprenderá como usar um canal para lidar com múltiplas entradas de uma variedade de fontes diferentes. +Você também aprenderá a usar **operadores** para transformar o conteúdo dos canais conforme necessário. + +??? info "Como começar a partir desta seção" + + Esta seção do curso pressupõe que você completou a Parte 1 do curso [Hello Nextflow](./index.md), mas se você está confortável com os conceitos básicos cobertos naquela seção, pode começar a partir daqui sem fazer nada especial. + +--- + +## 0. Aquecimento: Execute `hello-channels.nf` + +Vamos usar o script de fluxo de trabalho `hello-channels.nf` como ponto de partida. +Ele é equivalente ao script produzido ao trabalhar na Parte 1 deste curso de treinamento, exceto que mudamos o destino da saída: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Apenas para garantir que tudo está funcionando, execute o script uma vez antes de fazer qualquer alteração: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Como anteriormente, você encontrará o arquivo de saída chamado `output.txt` no diretório `results/hello_channels` (como especificado no bloco `output` do script de fluxo de trabalho, mostrado acima). + +??? abstract "Conteúdo do diretório" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Se isso funcionou para você, está pronto para aprender sobre canais. + +--- + +## 1. Forneça entradas variáveis através de um canal explicitamente + +Vamos criar um **canal** para passar a entrada variável para o processo `sayHello()` em vez de depender do tratamento implícito, que tem certas limitações. + +### 1.1. Crie um canal de entrada + +Existem várias **fábricas de canais** que podemos usar para configurar um canal. +Para manter as coisas simples por enquanto, vamos usar a fábrica de canais mais básica, chamada `channel.of`, que criará um canal contendo um único valor. +Funcionalmente, isso será semelhante a como tínhamos configurado antes, mas em vez de ter o Nextflow criando um canal implicitamente, estamos fazendo isso explicitamente agora. + +Esta é a linha de código que vamos usar: + +```console title="Sintaxe" +greeting_ch = channel.of('Hello Channels!') +``` + +Isso cria um canal chamado `greeting_ch` usando a fábrica de canais `channel.of()`, que configura um canal de fila simples, e carrega a string `'Hello Channels!'` para usar como o valor da saudação. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note + + Estamos temporariamente voltando a usar strings codificadas em vez de usar um parâmetro CLI para fins de legibilidade. Voltaremos a usar parâmetros CLI assim que tivermos coberto o que está acontecendo no nível do canal. + +No bloco workflow, adicione o código da fábrica de canais: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emite uma saudação + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // emite uma saudação + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Isso ainda não está funcional, pois ainda não mudamos a entrada para a chamada do processo. + +### 1.2. Adicione o canal como entrada para a chamada do processo + +Agora precisamos realmente conectar nosso canal recém-criado à chamada do processo `sayHello()`, substituindo o parâmetro CLI que estávamos fornecendo diretamente antes. + +No bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emite uma saudação + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Isso informa ao Nextflow para executar o processo `sayHello` no conteúdo do canal `greeting_ch`. + +Agora nosso fluxo de trabalho está devidamente funcional; é o equivalente explícito de escrever `sayHello('Hello Channels!')`. + +### 1.3. Execute o fluxo de trabalho + +Vamos executá-lo! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Se você fez ambas as edições corretamente, deve obter uma execução bem-sucedida. +Você pode verificar o diretório de resultados para se certificar de que o resultado ainda é o mesmo de antes. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Então aumentamos a flexibilidade do nosso fluxo de trabalho ao mesmo tempo que alcançamos o mesmo resultado final. +Isso pode parecer que estamos escrevendo mais código sem benefício tangível, mas o valor ficará claro assim que começarmos a lidar com mais entradas. + +Como uma prévia disso, vamos olhar mais uma coisa antes de seguir em frente: um benefício pequeno mas conveniente de usar um canal explícito para gerenciar a entrada de dados. + +### 1.4. Use `view()` para inspecionar o conteúdo do canal + +Os canais do Nextflow são construídos de uma maneira que nos permite operar em seu conteúdo usando operadores, que cobriremos em detalhes mais tarde neste capítulo. + +Por enquanto, vamos apenas mostrar como usar um operador super simples chamado [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) para inspecionar o conteúdo de um canal. +Você pode pensar em `view()` como uma ferramenta de depuração, como uma instrução `print()` em Python, ou seu equivalente em outras linguagens. + +Adicione esta pequena linha ao bloco workflow: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels!') + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels!') + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +A quantidade exata de espaços não importa, desde que seja um múltiplo de 4; estamos apenas tentando alinhar o início da instrução `.view()` com a parte `.of()` da construção do canal. + +Agora execute o fluxo de trabalho novamente: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Como você pode ver, isso exibe o conteúdo do canal no console. +Aqui temos apenas um elemento, mas quando começarmos a carregar múltiplos valores no canal na próxima seção, você verá que isso está configurado para exibir um elemento por linha. + +### Conclusão + +Você sabe como usar uma fábrica de canais básica para fornecer uma entrada a um processo. + +### O que vem a seguir? + +Aprenda como usar canais para fazer o fluxo de trabalho iterar sobre múltiplos valores de entrada. + +--- + +## 2. Modifique o fluxo de trabalho para executar em múltiplos valores de entrada + +Fluxos de trabalho normalmente executam em lotes de entradas que devem ser processadas em massa, então queremos atualizar o fluxo de trabalho para aceitar múltiplos valores de entrada. + +### 2.1. Carregue múltiplas saudações no canal de entrada + +Convenientemente, a fábrica de canais `channel.of()` que estivemos usando está bastante feliz em aceitar mais de um valor, então não precisamos modificar isso de jeito nenhum. +Podemos apenas carregar múltiplos valores no canal. + +Vamos fazê-los `'Hello'`, `'Bonjour'` e `'Holà'`. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_No diagrama, o canal é representado em verde, e a ordem dos elementos é representada como bolas de gude em um tubo: o primeiro carregado está à direita, depois o segundo no meio, depois o terceiro está à esquerda._ + +#### 2.1.1. Adicione mais saudações + +Antes do bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // cria um canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // cria um canal para entradas + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +A documentação nos diz que isso deve funcionar. Pode ser realmente tão simples? + +#### 2.1.2. Execute o comando e observe a saída do log + +Vamos tentar. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Certamente parece ter executado bem. +O monitor de execução mostra que `3 of 3` chamadas foram feitas para o processo `sayHello`, e vemos as três saudações enumeradas pela instrução `view()`, uma por linha como prometido. + +No entanto, ainda há apenas uma saída no diretório de resultados: + +??? abstract "Conteúdo do diretório" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Você deve ver uma das três saudações lá, mas a que você obteve pode ser diferente do que é mostrado aqui. +Consegue pensar por que isso pode ser? + +Olhando de volta para o monitor de execução, ele nos deu apenas um caminho de subdiretório (`f4/c9962c`). +Vamos dar uma olhada lá. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Conteúdo do arquivo" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +Essa nem é a mesma saudação que obtivemos no diretório de resultados! O que está acontecendo? + +Neste ponto, precisamos informar que, por padrão, o sistema de log ANSI escreve o log de múltiplas chamadas ao mesmo processo na mesma linha. +Então o status de todas as três chamadas ao processo sayHello() estão chegando no mesmo lugar. + +Felizmente, podemos desabilitar esse comportamento para ver a lista completa de chamadas de processo. + +#### 2.1.3. Execute o comando novamente com a opção `-ansi-log false` + +Para expandir o log para exibir uma linha por chamada de processo, adicione `-ansi-log false` ao comando. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Desta vez vemos todas as três execuções de processo e seus subdiretórios de trabalho associados listados na saída. + +Isso é muito melhor, pelo menos para um fluxo de trabalho simples. +Para um fluxo de trabalho complexo, ou um grande número de entradas, ter a lista completa exibida no terminal ficaria um pouco avassalador. +É por isso que `-ansi-log false` não é o comportamento padrão. + +!!! tip + + A maneira como o status é relatado é um pouco diferente entre os dois modos de log. + No modo condensado, o Nextflow relata se as chamadas foram concluídas com sucesso ou não. + Neste modo expandido, ele apenas relata que foram submetidas. + +De qualquer forma, agora que temos os subdiretórios de cada chamada de processo, podemos procurar seus logs e saídas. + +??? abstract "Conteúdo do diretório" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Conteúdo do arquivo" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Isso mostra que todos os três processos foram executados com sucesso (eba). + +Dito isso, ainda temos o problema de que há apenas um arquivo de saída no diretório de resultados. + +Você pode se lembrar de que codificamos o nome do arquivo de saída para o processo `sayHello`, então todas as três chamadas produziram um arquivo chamado `output.txt`. + +Enquanto os arquivos de saída permanecerem nos subdiretórios de trabalho, isolados dos outros processos, isso está ok. +Mas quando são publicados no mesmo diretório de resultados, aquele que foi copiado primeiro é sobrescrito pelo próximo, e assim por diante. + +### 2.2. Garanta que os nomes dos arquivos de saída sejam únicos + +Podemos continuar publicando todas as saídas no mesmo diretório de resultados, mas precisamos garantir que terão nomes únicos. +Especificamente, precisamos modificar o primeiro processo para gerar um nome de arquivo dinamicamente para que os nomes de arquivo finais sejam únicos. + +Então como tornamos os nomes de arquivo únicos? +Uma maneira comum de fazer isso é usar alguma informação única dos metadados das entradas (recebidos do canal de entrada) como parte do nome do arquivo de saída. +Aqui, por conveniência, vamos apenas usar a própria saudação, já que é apenas uma string curta, e prefixá-la ao nome base do arquivo de saída. + +#### 2.2.1. Construa um nome de arquivo de saída dinâmico + +No bloco process, faça as seguintes alterações de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +Certifique-se de substituir `output.txt` tanto na definição de saída quanto no bloco de comando `script:`. + +!!! tip + + Na definição de saída, você DEVE usar aspas duplas em torno da expressão do nome do arquivo (NÃO aspas simples), caso contrário falhará. + +Isso deve produzir um nome de arquivo de saída único toda vez que o processo for chamado, para que possa ser distinguido das saídas de outras chamadas ao mesmo processo no diretório de saída. + +#### 2.2.2. Execute o fluxo de trabalho + +Vamos executá-lo. Note que estamos de volta a executar com as configurações de log ANSI padrão. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Voltando à visualização de resumo, a saída é resumida em uma linha novamente. +Dê uma olhada no diretório `results` para ver se todas as saudações de saída estão lá. + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Sim! E cada uma tem o conteúdo esperado. + +??? abstract "Conteúdo do arquivo" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Sucesso! Agora podemos adicionar quantas saudações quisermos sem nos preocupar com arquivos de saída sendo sobrescritos. + +!!! tip + + Na prática, nomear arquivos com base nos dados de entrada em si é quase sempre impraticável. + A melhor maneira de gerar nomes de arquivo dinâmicos é passar metadados para um processo junto com os arquivos de entrada. + Os metadados são normalmente fornecidos através de uma 'planilha de amostras' ou equivalentes. + Você aprenderá como fazer isso mais tarde no seu treinamento de Nextflow (veja [Missão secundária de metadados](../side_quests/metadata.md)). + +### Conclusão + +Você sabe como alimentar múltiplos elementos de entrada através de um canal. + +### O que vem a seguir? + +Aprenda a usar um operador para transformar o conteúdo de um canal. + +--- + +## 3. Forneça múltiplas entradas através de um array + +Acabamos de mostrar como lidar com múltiplos elementos de entrada que foram codificados diretamente na fábrica de canais. +E se quisermos fornecer essas múltiplas entradas de uma maneira diferente? + +Por exemplo, imagine que configuramos uma variável de entrada contendo um array de elementos assim: + +`greetings_array = ['Hello','Bonjour','Holà']` + +Podemos carregar isso em nosso canal de saída e esperar que funcione? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Vamos descobrir. + +### 3.1. Forneça um array de valores como entrada para o canal + +O bom senso sugere que deveríamos ser capazes de simplesmente passar um array de valores em vez de um único valor. +Vamos tentar; precisaremos configurar a variável de entrada e carregá-la na fábrica de canais. + +#### 3.1.1. Configure a variável de entrada + +Vamos pegar a variável `greetings_array` que acabamos de imaginar e torná-la realidade adicionando-a ao bloco workflow: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // cria um canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Isso ainda não está funcional, apenas adicionamos uma declaração para o array. + +#### 3.1.2. Defina o array de saudações como entrada para a fábrica de canais + +Agora vamos substituir os valores `'Hello','Bonjour','Holà'` atualmente codificados na fábrica de canais pelo `greetings_array` que acabamos de criar. + +No bloco workflow, faça a seguinte alteração: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Isso deve estar funcional agora. + +#### 3.1.3. Execute o fluxo de trabalho + +Vamos tentar executá-lo: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Saída do comando" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +Oh não! Há um erro! + +Observe a saída de `view()` e as mensagens de erro. + +Parece que o Nextflow tentou executar uma única chamada de processo, usando `[Hello, Bonjour, Holà]` como um valor de string, em vez de usar as três strings no array como valores separados. + +Então é o 'empacotamento' que está causando o problema. +Como fazemos o Nextflow desempacotar o array e carregar as strings individuais no canal? + +### 3.2. Use um operador para transformar o conteúdo do canal + +É aqui que os **[operadores](https://www.nextflow.io/docs/latest/reference/operator.html)** entram em jogo. +Você já usou o operador `.view()`, que apenas observa o que está lá. +Agora vamos olhar para operadores que nos permitem agir sobre o conteúdo de um canal. + +Se você examinar a [lista de operadores](https://www.nextflow.io/docs/latest/reference/operator.html) na documentação do Nextflow, encontrará [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten), que faz exatamente o que precisamos: desempacotar o conteúdo de um array e emiti-los como itens individuais. + +#### 3.2.1. Adicione o operador `flatten()` + +Para aplicar o operador `flatten()` ao nosso canal de entrada, anexamos ele à declaração da fábrica de canais. + +No bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Aqui adicionamos o operador na próxima linha para legibilidade, mas você pode adicionar operadores na mesma linha que a fábrica de canais se preferir, assim: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. Refine a(s) instrução(ões) `view()` + +Poderíamos executar isso imediatamente para testar se funciona, mas enquanto estamos nisso, vamos refinar como inspecionamos o conteúdo do canal. + +Queremos ser capazes de contrastar como o conteúdo se parece antes e depois que o operador `flatten()` é aplicado, então vamos adicionar um segundo, E vamos adicionar um pouco de código para obtê-los rotulados mais claramente na saída. + +No bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Você vê que adicionamos uma segunda instrução `.view`, e para cada uma delas, substituímos os parênteses vazios (`()`) por chaves contendo algum código, como `{ greeting -> "Before flatten: $greeting" }`. + +Essas são chamadas _closures_. O código que elas contêm será executado para cada item no canal. +Definimos uma variável temporária para o valor interno, aqui chamada `greeting` (mas poderia ser qualquer nome arbitrário), que é usada apenas dentro do escopo dessa closure. + +Neste exemplo, `$greeting` representa cada item individual carregado no canal. +Isso resultará em uma saída de console bem rotulada. + +!!! info + + Em alguns pipelines você pode ver uma variável especial chamada `$it` usada dentro de closures de operadores. + Esta é uma variável _implícita_ que permite um acesso de forma abreviada à variável interna, + sem precisar defini-la com um `->`. + + Preferimos ser explícitos para ajudar na clareza do código, como tal a sintaxe `$it` é desencorajada e será lentamente eliminada da linguagem Nextflow. + +#### 3.2.3. Execute o fluxo de trabalho + +Finalmente, você pode tentar executar o fluxo de trabalho novamente! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + Before flatten: [Hello, Bonjour, Holà] + After flatten: Hello + After flatten: Bonjour + After flatten: Holà + ``` + +Desta vez funciona E nos dá a percepção adicional do que o conteúdo do canal parece antes e depois de executarmos o operador `flatten()`. + +- Você vê que obtemos uma única instrução `Before flatten:` porque nesse ponto o canal contém um item, o array original. + Então obtemos três instruções `After flatten:` separadas, uma para cada saudação, que agora são itens individuais no canal. + +Importante, isso significa que cada item agora pode ser processado separadamente pelo fluxo de trabalho. + +!!! tip + + É tecnicamente possível alcançar os mesmos resultados usando uma fábrica de canais diferente, [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist), que inclui uma etapa de mapeamento implícita em sua operação. + Aqui escolhemos não usar isso para demonstrar o uso de um operador em um caso de uso simples. + +### Conclusão + +Você sabe como usar um operador como `flatten()` para transformar o conteúdo de um canal, e como usar o operador `view()` para inspecionar o conteúdo do canal antes e depois de aplicar um operador. + +### O que vem a seguir? + +Aprenda como fazer o fluxo de trabalho receber um arquivo como sua fonte de valores de entrada. + +--- + +## 4. Leia valores de entrada de um arquivo CSV + +Realisticamente, raramente se alguma vez vamos começar de um array de valores. +Muito provavelmente, teremos um ou mais arquivos contendo os dados que precisam ser processados, em algum tipo de formato estruturado. + +Preparamos um arquivo CSV chamado `greetings.csv` que contém várias saudações de entrada, imitando o tipo de dados colunar que você pode querer processar em uma análise de dados real, armazenado em `data/`. +(Os números não são significativos, eles estão lá apenas para fins ilustrativos.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Nossa próxima tarefa é adaptar nosso fluxo de trabalho para ler os valores deste arquivo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Vamos ver como podemos fazer isso acontecer. + +### 4.1. Modifique o script para esperar um arquivo CSV como fonte de saudações + +Para começar, vamos precisar fazer duas alterações principais no script: + +- Mudar o parâmetro de entrada para apontar para o arquivo CSV +- Mudar a fábrica de canais para uma projetada para lidar com um arquivo + +#### 4.1.1. Mude o parâmetro de entrada para apontar para o arquivo CSV + +Lembra do parâmetro `params.input` que configuramos na Parte 1? +Vamos atualizá-lo para apontar para o arquivo CSV contendo nossas saudações. + +Faça a seguinte edição na declaração do parâmetro: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parameters + */ + input: String = 'Holà mundo!' + ``` + +Isso assume que o arquivo está localizado junto com o código do fluxo de trabalho. +Você aprenderá como lidar com outros locais de dados mais tarde em sua jornada com Nextflow. + +#### 4.1.2. Mude para uma fábrica de canais projetada para lidar com um arquivo + +Como agora queremos usar um arquivo em vez de strings simples como entrada, não podemos usar a fábrica de canais `channel.of()` de antes. +Precisamos mudar para usar uma nova fábrica de canais, [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path), que tem alguma funcionalidade integrada para lidar com caminhos de arquivo. + +No bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // declara um array de saudações de entrada + greetings_array = ['Hello','Bonjour','Holà'] + // cria um canal para entradas + greeting_ch = channel.of(greetings_array) + .view { greeting -> "Before flatten: $greeting" } + .flatten() + .view { greeting -> "After flatten: $greeting" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Você notará que mudamos a entrada do canal de volta para `param.input`, e deletamos a declaração `greetings_array` já que não precisaremos mais dela. +Também comentamos o `flatten()` e a segunda instrução `view()`. + +#### 4.1.3. Execute o fluxo de trabalho + +Vamos tentar executar o fluxo de trabalho com a nova fábrica de canais e o arquivo de entrada. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Saída do comando" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + Before flatten: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Oh não, não funciona. Dê uma olhada no início da saída do console e na mensagem de erro. +A parte `Command executed:` é especialmente útil aqui. + +Isso pode parecer um pouco familiar. +Parece que o Nextflow tentou executar uma única chamada de processo usando o próprio caminho do arquivo como um valor de string. +Então ele resolveu o caminho do arquivo corretamente, mas não analisou realmente seu conteúdo, que é o que queríamos. + +Como fazemos o Nextflow abrir o arquivo e carregar seu conteúdo no canal? + +Parece que precisamos de outro [operador](https://www.nextflow.io/docs/latest/reference/operator.html)! + +### 4.2. Use o operador `splitCsv()` para analisar o arquivo + +Olhando através da lista de operadores novamente, encontramos [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv), que é projetado para analisar e dividir texto formatado em CSV. + +#### 4.2.1. Aplique `splitCsv()` ao canal + +Para aplicar o operador, anexamos ele à linha da fábrica de canais como anteriormente. + +No bloco workflow, faça a seguinte alteração de código para substituir `flatten()` por `splitcsv()` (descomentado): + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "Before flatten: $greeting" } + // .flatten() + // .view { greeting -> "After flatten: $greeting" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Como você pode ver, também atualizamos as instruções `view()` de antes/depois. +Tecnicamente poderíamos ter usado o mesmo nome de variável (`greeting`) mas atualizamos para algo mais apropriado (`csv`) para tornar o código mais legível por outros. + +#### 4.2.2. Execute o fluxo de trabalho novamente + +Vamos tentar executar o fluxo de trabalho com a lógica de análise de CSV adicionada. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Saída do comando" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +Interessantemente, isso também falha, mas com um erro diferente. +Desta vez o Nextflow analisou o conteúdo do arquivo (eba!) mas carregou cada linha como um array, e cada array é um elemento no canal. + +Precisamos dizer a ele para pegar apenas a primeira coluna em cada linha. +Então como desempacotamos isso? + +Usamos anteriormente `flatten()` para desempacotar o conteúdo de um canal, mas isso não funcionaria aqui porque flatten desempacota _tudo_ (sinta-se livre para tentar se quiser ver por si mesmo). + +Em vez disso, usaremos outro operador chamado `map()` que é realmente útil e aparece muito em pipelines Nextflow. + +### 4.3. Use o operador `map()` para extrair as saudações + +O operador [`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) é uma ferramenta muito útil que nos permite fazer todos os tipos de mapeamentos para o conteúdo de um canal. + +Neste caso, vamos usá-lo para extrair aquele único elemento que queremos de cada linha em nosso arquivo de dados. +Esta é a aparência da sintaxe: + +```groovy title="Sintaxe" +.map { row -> row[0] } +``` + +Isso significa 'para cada linha no canal, pegue o 0º (primeiro) item que ela contém'. + +Então vamos aplicar isso à nossa análise de CSV. + +#### 4.3.1. Aplique `map()` ao canal + +No bloco workflow, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + .map { item -> item[0] } + .view { csv -> "After map: $csv" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .view { csv -> "Before splitCsv: $csv" } + .splitCsv() + .view { csv -> "After splitCsv: $csv" } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Você vê que adicionamos outra chamada `view()` para confirmar que o operador faz o que esperamos. + +#### 4.3.2. Execute o fluxo de trabalho + +Vamos executar isso mais uma vez: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + Before splitCsv: /workspaces/training/hello-nextflow/data/greetings.csv + After splitCsv: [Hello, English, 123] + After splitCsv: [Bonjour, French, 456] + After splitCsv: [Holà, Spanish, 789] + After map: Hello + After map: Bonjour + After map: Holà + ``` + +Desta vez deve executar sem erros. + +Olhando para a saída das instruções `view()`, você vê o seguinte: + +- Uma única instrução `Before splitCsv:`: nesse ponto o canal contém um item, o caminho do arquivo original. +- Três instruções `After splitCsv:` separadas: uma para cada saudação, mas cada uma está contida dentro de um array que corresponde àquela linha no arquivo. +- Três instruções `After map:` separadas: uma para cada saudação, que agora são elementos individuais no canal. + +Note que as linhas podem aparecer em uma ordem diferente na sua saída. + +Você também pode olhar os arquivos de saída para verificar que cada saudação foi corretamente extraída e processada através do fluxo de trabalho. + +Alcançamos o mesmo resultado de antes, mas agora temos muito mais flexibilidade para adicionar mais elementos ao canal de saudações que queremos processar modificando um arquivo de entrada, sem modificar nenhum código. +Você aprenderá abordagens mais sofisticadas para lidar com entradas complexas em um treinamento posterior. + +### Conclusão + +Você sabe como usar o construtor de canal `.fromPath()` e os operadores `splitCsv()` e `map()` para ler um arquivo de valores de entrada e lidar com eles apropriadamente. + +De forma mais geral, você tem uma compreensão básica de como o Nextflow usa **canais** para gerenciar entradas para processos e **operadores** para transformar seu conteúdo. + +### O que vem a seguir? + +Faça uma grande pausa, você trabalhou duro nesta seção! + +Quando estiver pronto, prossiga para [**Parte 3: Olá Fluxo de Trabalho**](./03_hello_workflow.md) para aprender como adicionar mais etapas e conectá-las em um fluxo de trabalho adequado. + +--- + +## Quiz + +<quiz> +O que é um canal no Nextflow? +- [ ] Uma especificação de caminho de arquivo +- [ ] Uma definição de processo +- [x] Uma estrutura tipo fila para passar dados entre processos +- [ ] Uma configuração de definição + +Saiba mais: [1.1. Crie um canal de entrada](#11-crie-um-canal-de-entrada) +</quiz> + +<quiz> +O que este código produzirá como saída? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (uma única lista) +- [x] Cada elemento em uma linha separada: `Hello`, `Bonjour`, `Hola` +- [ ] Nada (canais não imprimem por padrão) +- [ ] Um erro (sintaxe inválida) + +Saiba mais: [1.1. Crie um canal de entrada](#11-crie-um-canal-de-entrada) +</quiz> + +<quiz> +Quando um canal contém múltiplos valores, como o Nextflow lida com a execução do processo? +- [ ] O processo executa uma vez com todos os valores +- [x] O processo executa uma vez para cada valor no canal +- [ ] O processo executa apenas com o primeiro valor +- [ ] O processo executa apenas com o último valor + +Saiba mais: [2. Modifique o fluxo de trabalho para executar em múltiplos valores de entrada](#2-modifique-o-fluxo-de-trabalho-para-executar-em-multiplos-valores-de-entrada) +</quiz> + +<quiz> +O que o operador `flatten()` faz? +- [ ] Combina múltiplos canais em um +- [ ] Ordena elementos do canal +- [x] Desempacota arrays em elementos individuais +- [ ] Remove elementos duplicados + +Saiba mais: [3.2.1. Adicione o operador `flatten()`](#321-adicione-o-operador-flatten) +</quiz> + +<quiz> +Qual é o propósito do operador `view()`? +- [ ] Para filtrar o conteúdo do canal +- [ ] Para transformar elementos do canal +- [x] Para inspecionar e depurar o conteúdo do canal +- [ ] Para salvar o conteúdo do canal em um arquivo + +Saiba mais: [1.4. Use `view()` para inspecionar o conteúdo do canal](#14-use-view-para-inspecionar-o-conteudo-do-canal) +</quiz> + +<quiz> +O que `splitCsv()` faz? +- [ ] Cria um arquivo CSV a partir do conteúdo do canal +- [ ] Divide uma string por vírgulas +- [x] Analisa um arquivo CSV em arrays representando cada linha +- [ ] Mescla múltiplos arquivos CSV + +Saiba mais: [4.2. Use o operador `splitCsv()` para analisar o arquivo](#42-use-o-operador-splitcsv-para-analisar-o-arquivo) +</quiz> + +<quiz> +Qual é o propósito do operador `map()`? +- [ ] Para filtrar elementos de um canal +- [ ] Para combinar múltiplos canais +- [x] Para transformar cada elemento em um canal +- [ ] Para contar elementos em um canal + +Saiba mais: [4.3. Use o operador `map()` para extrair as saudações](#43-use-o-operador-map-para-extrair-as-saudacoes) +</quiz> + +<quiz> +Por que é importante usar nomes de arquivo de saída dinâmicos ao processar múltiplas entradas? +- [ ] Para melhorar o desempenho +- [ ] Para reduzir o espaço em disco +- [x] Para evitar que arquivos de saída se sobrescrevam +- [ ] Para habilitar a funcionalidade de resume + +Saiba mais: [2.2. Garanta que os nomes dos arquivos de saída sejam únicos](#22-garanta-que-os-nomes-dos-arquivos-de-saida-sejam-unicos) +</quiz> diff --git a/docs/pt/docs/hello_nextflow/03_hello_workflow.md b/docs/pt/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..9134ed1cca --- /dev/null +++ b/docs/pt/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Parte 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/03_hello_workflow.md). +/// + +A maioria dos fluxos de trabalho do mundo real envolve mais de uma etapa. +Neste módulo de treinamento, você aprenderá como conectar processos em um fluxo de trabalho de múltiplas etapas. + +Isso ensinará a você a maneira Nextflow de realizar o seguinte: + +1. Fazer os dados fluírem de um processo para o próximo +2. Coletar saídas de múltiplas chamadas de processo em uma única chamada de processo +3. Passar mais de uma entrada para um processo +4. Gerenciar múltiplas saídas vindas de um processo + +Para demonstrar, continuaremos construindo sobre o exemplo Hello World agnóstico de domínio das Partes 1 e 2. +Desta vez, faremos as seguintes alterações em nosso fluxo de trabalho para refletir melhor como as pessoas constroem fluxos de trabalho reais: + +1. Adicionar uma segunda etapa que converte a saudação para maiúsculas. +2. Adicionar uma terceira etapa que coleta todas as saudações transformadas e as escreve em um único arquivo. +3. Adicionar um parâmetro para nomear o arquivo de saída final e passá-lo como uma entrada secundária para a etapa de coleta. +4. Fazer a etapa de coleta também relatar uma estatística simples sobre o que foi processado. + +??? info "Como começar a partir desta seção" + + Esta seção do curso pressupõe que você completou as Partes 1-2 do curso [Hello Nextflow](./index.md), mas se você está confortável com os conceitos básicos cobertos nessas seções, pode começar a partir daqui sem fazer nada especial. + +--- + +## 0. Aquecimento: Execute `hello-workflow.nf` + +Vamos usar o script de fluxo de trabalho `hello-workflow.nf` como ponto de partida. +Ele é equivalente ao script produzido ao trabalhar na Parte 2 deste curso de treinamento, exceto que removemos as instruções `view()` e alteramos o destino de saída: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Apenas para ter certeza de que tudo está funcionando, execute o script uma vez antes de fazer quaisquer alterações: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Como anteriormente, você encontrará os arquivos de saída no local especificado no bloco `output`. +Para este capítulo, está em `results/hello_workflow/`. + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Se isso funcionou para você, você está pronto para aprender como montar um fluxo de trabalho de múltiplas etapas. + +--- + +## 1. Adicione uma segunda etapa ao fluxo de trabalho + +Vamos adicionar uma etapa para converter cada saudação para maiúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +Para isso, precisamos fazer três coisas: + +- Definir o comando que vamos usar para fazer a conversão para maiúsculas. +- Escrever um novo processo que envolve o comando de conversão para maiúsculas. +- Chamar o novo processo no bloco de fluxo de trabalho e configurá-lo para receber a saída do processo `sayHello()` como entrada. + +### 1.1. Defina o comando de conversão para maiúsculas e teste-o no terminal + +Para fazer a conversão das saudações para maiúsculas, vamos usar uma ferramenta UNIX clássica chamada `tr` para 'text replacement', com a seguinte sintaxe: + +```bash title="Sintaxe" +tr '[a-z]' '[A-Z]' +``` + +Esta é uma substituição de texto muito simples que não leva em conta letras acentuadas, então por exemplo 'Holà' se tornará 'HOLà', mas fará um trabalho bom o suficiente para demonstrar os conceitos do Nextflow e isso é o que importa. + +Para testá-lo, podemos executar o comando `echo 'Hello World'` e direcionar sua saída para o comando `tr`: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +A saída é um arquivo de texto chamado `UPPER-output.txt` que contém a versão em maiúsculas da string `Hello World`. + +??? abstract "Conteúdo do arquivo" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +Isso é basicamente o que vamos tentar fazer com nosso fluxo de trabalho. + +### 1.2. Escreva a etapa de conversão para maiúsculas como um processo Nextflow + +Podemos modelar nosso novo processo no primeiro, já que queremos usar todos os mesmos componentes. + +Adicione a seguinte definição de processo ao script de fluxo de trabalho, logo abaixo da primeira: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Use uma ferramenta de substituição de texto para converter a saudação para maiúsculas + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Neste, compomos o segundo nome de arquivo de saída baseado no nome do arquivo de entrada, de forma similar ao que fizemos originalmente para a saída do primeiro processo. + +### 1.3. Adicione uma chamada ao novo processo no bloco de fluxo de trabalho + +Agora precisamos dizer ao Nextflow para realmente chamar o processo que acabamos de definir. + +No bloco de fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Isso ainda não é funcional porque não especificamos o que deve ser entrada para o processo `convertToUpper()`. + +### 1.4. Passe a saída do primeiro processo para o segundo processo + +Agora precisamos fazer a saída do processo `sayHello()` fluir para o processo `convertToUpper()`. + +Convenientemente, o Nextflow empacota automaticamente a saída de um processo em um canal chamado `<process>.out`. +Então a saída do processo `sayHello` é um canal chamado `sayHello.out`, que podemos conectar diretamente na chamada para `convertToUpper()`. + +No bloco de fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // converte a saudação para maiúsculas + convertToUpper() + ``` + +Para um caso simples como este (uma saída para uma entrada), isso é tudo que precisamos fazer para conectar dois processos! + +### 1.5. Configure a publicação da saída do fluxo de trabalho + +Finalmente, vamos atualizar as saídas do fluxo de trabalho para publicar os resultados do segundo processo também. + +#### 1.5.1. Atualize a seção `publish:` do bloco `workflow` + +No bloco `workflow`, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +A lógica é a mesma de antes. + +#### 1.5.2. Atualize o bloco `output` + +No bloco `output`, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Mais uma vez, a lógica é a mesma de antes. + +Isso mostra que você pode controlar as configurações de saída em um nível muito granular, para cada saída individual. +Sinta-se à vontade para tentar mudar os caminhos ou o modo de publicação para um dos processos para ver o que acontece. + +Claro, isso significa que estamos repetindo algumas informações aqui, o que pode se tornar inconveniente se quisermos atualizar a localização para todas as saídas da mesma forma. +Mais tarde no curso, você aprenderá como configurar essas definições para múltiplas saídas de forma estruturada. + +### 1.6. Execute o fluxo de trabalho com `-resume` + +Vamos testar isso usando a flag `-resume`, já que já executamos a primeira etapa do fluxo de trabalho com sucesso. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Agora há uma linha extra na saída do console que corresponde ao novo processo que acabamos de adicionar. + +Você encontrará as saídas no diretório `results/hello_workflow` conforme definido no bloco `output`. + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Isso é conveniente! Mas ainda vale a pena dar uma olhada dentro do diretório de trabalho de uma das chamadas ao segundo processo. + +??? abstract "Conteúdo do diretório" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +Note que há dois arquivos `*-output`: a saída do primeiro processo assim como a saída do segundo. + +A saída do primeiro processo está lá porque o Nextflow a **preparou** (staged) ali para ter tudo o que é necessário para execução dentro do mesmo subdiretório. + +No entanto, é na verdade um link simbólico apontando para o arquivo original no subdiretório da primeira chamada de processo. +Por padrão, ao executar em uma única máquina como estamos fazendo aqui, o Nextflow usa links simbólicos em vez de cópias para preparar arquivos de entrada e intermediários. + +Agora, antes de prosseguir, pense em como tudo o que fizemos foi conectar a saída de `sayHello` à entrada de `convertToUpper` e os dois processos puderam ser executados em série. +O Nextflow fez o trabalho pesado de gerenciar arquivos individuais de entrada e saída e passá-los entre os dois comandos para nós. + +Esta é uma das razões pelas quais os canais do Nextflow são tão poderosos: eles cuidam do trabalho tedioso envolvido em conectar as etapas do fluxo de trabalho. + +### Conclusão + +Você sabe como encadear processos conectando a saída de uma etapa como entrada para a próxima etapa. + +### O que vem a seguir? + +Aprenda como coletar saídas de chamadas de processo em lote e alimentá-las em um único processo. + +--- + +## 2. Adicione uma terceira etapa para coletar todas as saudações + +Quando usamos um processo para aplicar uma transformação a cada um dos elementos em um canal, como estamos fazendo aqui para as múltiplas saudações, às vezes queremos coletar elementos do canal de saída desse processo e alimentá-los em outro processo que realiza algum tipo de análise ou soma. + +Para demonstrar, adicionaremos uma nova etapa ao nosso pipeline que coleta todas as saudações em maiúsculas produzidas pelo processo `convertToUpper` e as escreve em um único arquivo. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Sem estragar a surpresa, mas isso vai envolver um operador muito útil. + +### 2.1. Defina o comando de coleta e teste-o no terminal + +A etapa de coleta que queremos adicionar ao nosso fluxo de trabalho usará o comando `cat` para concatenar múltiplas saudações em maiúsculas em um único arquivo. + +Vamos executar o comando sozinho no terminal para verificar que funciona conforme esperado, assim como fizemos anteriormente. + +Execute o seguinte em seu terminal: + +```bash +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 +``` + +A saída é um arquivo de texto chamado `COLLECTED-output.txt` que contém as versões em maiúsculas das saudações originais. + +??? abstract "Conteúdo do arquivo" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Esse é o resultado que queremos alcançar com nosso fluxo de trabalho. + +### 2.2. Crie um novo processo para fazer a etapa de coleta + +Vamos criar um novo processo e chamá-lo de `collectGreetings()`. +Podemos começar a escrevê-lo com base no que já vimos antes. + +#### 2.2.1. Escreva as partes 'óbvias' do processo + +Adicione a seguinte definição de processo ao script de fluxo de trabalho: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Coleta saudações em maiúsculas em um único arquivo de saída + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +Isso é o que podemos escrever com confiança com base no que você aprendeu até agora. +Mas isso não é funcional! +Deixa de fora a(s) definição(ões) de entrada e a primeira metade do comando do script porque precisamos descobrir como escrever isso. + +#### 2.2.2. Defina as entradas para `collectGreetings()` + +Precisamos coletar as saudações de todas as chamadas ao processo `convertToUpper()`. +O que sabemos que podemos obter da etapa anterior no fluxo de trabalho? + +O canal de saída de `convertToUpper()` conterá os caminhos para os arquivos individuais contendo as saudações em maiúsculas. +Isso equivale a um slot de entrada; vamos chamá-lo de `input_files` por simplicidade. + +No bloco de processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Note que usamos o prefixo `path` mesmo esperando que isso contenha múltiplos arquivos. + +#### 2.2.3. Componha o comando de concatenação + +É aqui que as coisas podem ficar um pouco complicadas, porque precisamos ser capazes de lidar com um número arbitrário de arquivos de entrada. +Especificamente, não podemos escrever o comando antecipadamente, então precisamos dizer ao Nextflow como compô-lo em tempo de execução com base nas entradas que fluem para o processo. + +Em outras palavras, se tivermos um canal de entrada contendo o elemento `[file1.txt, file2.txt, file3.txt]`, precisamos que o Nextflow transforme isso em `cat file1.txt file2.txt file3.txt`. + +Felizmente, o Nextflow fica feliz em fazer isso por nós se simplesmente escrevermos `cat ${input_files}` no comando do script. + +No bloco de processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +Em teoria, isso deve lidar com qualquer número arbitrário de arquivos de entrada. + +!!! tip + + Algumas ferramentas de linha de comando exigem fornecer um argumento (como `-input`) para cada arquivo de entrada. + Nesse caso, teríamos que fazer um pouco de trabalho extra para compor o comando. + Você pode ver um exemplo disso no curso de treinamento [Nextflow for Genomics](../../nf4_science/genomics/). + +### 2.3. Adicione a etapa de coleta ao fluxo de trabalho + +Agora devemos apenas precisar chamar o processo de coleta na saída da etapa de conversão para maiúsculas. + +#### 2.3.1. Conecte as chamadas de processo + +No bloco de fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out) + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="75" + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + } + ``` + +Isso conecta a saída de `convertToUpper()` à entrada de `collectGreetings()`. + +#### 2.3.2. Execute o fluxo de trabalho com `-resume` + +Vamos tentar. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Saída do comando" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Ele é executado com sucesso, incluindo a terceira etapa. + +No entanto, olhe o número de chamadas para `collectGreetings()` na última linha. +Estávamos esperando apenas uma, mas há três. + +Agora dê uma olhada no conteúdo do arquivo de saída final. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Oh não. A etapa de coleta foi executada individualmente em cada saudação, o que NÃO é o que queríamos. + +Precisamos fazer algo para dizer ao Nextflow explicitamente que queremos que a terceira etapa seja executada em todos os elementos no canal de saída de `convertToUpper()`. + +### 2.4. Use um operador para coletar as saudações em uma única entrada + +Sim, mais uma vez a resposta para nosso problema é um operador. + +Especificamente, vamos usar o operador apropriadamente chamado [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect). + +#### 2.4.1. Adicione o operador `collect()` + +Desta vez vai parecer um pouco diferente porque não estamos adicionando o operador no contexto de uma fábrica de canal; estamos adicionando-o a um canal de saída. + +Pegamos o `convertToUpper.out` e acrescentamos o operador `collect()`, o que nos dá `convertToUpper.out.collect()`. +Podemos conectar isso diretamente na chamada do processo `collectGreetings()`. + +No bloco de fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Adicione algumas instruções `view()` + +Vamos também incluir algumas instruções `view()` para visualizar os estados antes e depois do conteúdo do canal. + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + + // instruções view opcionais + convertToUpper.out.view { contents -> "Antes do collect: $contents" } + convertToUpper.out.collect().view { contents -> "Depois do collect: $contents" } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + } + ``` + +As instruções `view()` podem ir em qualquer lugar que você quiser; as colocamos logo após a chamada para legibilidade. + +#### 2.4.3. Execute o fluxo de trabalho novamente com `-resume` + +Vamos tentar: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Saída do comando" + + ```console + 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 ✔ + Antes do collect: /workspaces/training/hello-nextflow/work/b3/d52708edba8b864024589285cb3445/UPPER-Bonjour-output.txt + Antes do collect: /workspaces/training/hello-nextflow/work/99/79394f549e3040dfc2440f69ede1fc/UPPER-Hello-output.txt + Antes do collect: /workspaces/training/hello-nextflow/work/aa/56bfe7cf00239dc5badc1d04b60ac4/UPPER-Holà-output.txt + Depois do 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] + ``` + +Ele é executado com sucesso, embora a saída de log possa parecer um pouco mais bagunçada do que isso (nós a limpamos para legibilidade). + +Desta vez a terceira etapa foi chamada apenas uma vez! + +Olhando para a saída das instruções `view()`, vemos o seguinte: + +- Três instruções `Antes do collect:`, uma para cada saudação: nesse ponto os caminhos dos arquivos são itens individuais no canal. +- Uma única instrução `Depois do collect:`: os três caminhos de arquivos agora estão empacotados em um único elemento. + +Dê uma olhada no conteúdo do arquivo de saída final. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Desta vez temos todas as três saudações no arquivo de saída final. Sucesso! + +!!! note + + Se você executar isso várias vezes sem `-resume`, verá que a ordem das saudações muda de uma execução para outra. + Isso mostra que a ordem na qual os elementos fluem através das chamadas de processo não é garantida ser consistente. + +#### 2.4.4. Remova as instruções `view()` para legibilidade + +Antes de passar para a próxima seção, recomendamos que você delete as instruções `view()` para evitar poluir a saída do console. + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="73" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + + // instruções view opcionais + convertToUpper.out.view { contents -> "Antes do collect: $contents" } + convertToUpper.out.collect().view { contents -> "Depois do collect: $contents" } + ``` + +Esta é basicamente a operação inversa do ponto 2.4.2. + +### Conclusão + +Você sabe como coletar saídas de um lote de chamadas de processo e alimentá-las em uma etapa de análise conjunta ou soma. + +### O que vem a seguir? + +Aprenda como passar mais de uma entrada para um processo. + +--- + +## 3. Passe mais de uma entrada para um processo + +Queremos ser capazes de nomear o arquivo de saída final com algo específico para processar lotes subsequentes de saudações sem sobrescrever os resultados finais. + +Para isso, faremos os seguintes refinamentos no fluxo de trabalho: + +- Modificar o processo coletor para aceitar um nome definido pelo usuário para o arquivo de saída +- Adicionar um parâmetro de linha de comando ao fluxo de trabalho e passá-lo ao processo coletor + +### 3.1. Modifique o processo coletor + +Vamos precisar declarar a entrada adicional e integrá-la ao nome do arquivo de saída. + +#### 3.1.1. Declare a entrada adicional + +Boas notícias: podemos declarar quantas variáveis de entrada quisermos na definição do processo. +Vamos chamar esta de `batch_name`. + +No bloco de processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Você pode configurar seus processos para esperar quantas entradas quiser. +Agora, todas estas estão configuradas para serem entradas obrigatórias; você _deve_ fornecer um valor para o fluxo de trabalho funcionar. + +Você aprenderá como gerenciar entradas obrigatórias versus opcionais mais tarde em sua jornada Nextflow. + +#### 3.1.2. Use a variável `batch_name` no nome do arquivo de saída + +Podemos inserir a variável no nome do arquivo de saída da mesma forma que compusemos nomes de arquivos dinâmicos antes. + +No bloco de processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Isso configura o processo para usar o valor `batch_name` para gerar um nome de arquivo específico para a saída final do fluxo de trabalho. + +### 3.2. Adicione um parâmetro de linha de comando `batch` + +Agora precisamos de uma forma de fornecer o valor para `batch_name` e alimentá-lo à chamada do processo. + +#### 3.2.1. Use `params` para configurar o parâmetro + +Você já sabe como usar o sistema `params` para declarar parâmetros CLI. +Vamos usar isso para declarar um parâmetro `batch` (com um valor padrão porque somos preguiçosos). + +Na seção de parâmetros do pipeline, faça as seguintes alterações de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Parâmetros do pipeline + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Parâmetros do pipeline + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +Assim como demonstramos para `--input`, você pode sobrescrever esse valor padrão especificando um valor com `--batch` na linha de comando. + +#### 3.2.2. Passe o parâmetro `batch` para o processo + +Para fornecer o valor do parâmetro ao processo, precisamos adicioná-lo na chamada do processo. + +No bloco de fluxo de trabalho, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect()) + ``` + +Você vê que para fornecer múltiplas entradas a um processo, você simplesmente as lista nos parênteses da chamada, separadas por vírgulas. + +!!! warning + + Você DEVE fornecer as entradas ao processo na MESMA ORDEM EXATA em que estão listadas no bloco de definição de entrada do processo. + +### 3.3. Execute o fluxo de trabalho + +Vamos tentar executar isso com um nome de lote na linha de comando. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Ele é executado com sucesso e produz a saída desejada: + +??? abstract "Conteúdo do arquivo" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Agora, contanto que especifiquemos o parâmetro apropriadamente, execuções subsequentes em outros lotes de entradas não destruirão os resultados anteriores. + +### Conclusão + +Você sabe como passar mais de uma entrada para um processo. + +### O que vem a seguir? + +Aprenda como emitir múltiplas saídas e manuseá-las convenientemente. + +--- + +## 4. Adicione uma saída à etapa coletora + +Até agora estivemos usando processos que produziam apenas uma saída cada. +Conseguimos acessar suas respectivas saídas muito convenientemente usando a sintaxe `<process>.out`, que usamos tanto no contexto de passar uma saída para o próximo processo (por exemplo, `convertToUpper(sayHello.out)`) quanto no contexto da seção `publish:` (por exemplo, `first_output = sayHello.out`). + +O que acontece quando um processo produz mais de uma? +Como lidamos com as múltiplas saídas? +Podemos selecionar e usar uma saída específica? + +Todas excelentes perguntas, e a resposta curta é sim, podemos! + +Múltiplas saídas serão empacotadas em canais separados. +Podemos escolher dar nomes a esses canais de saída, o que torna fácil referenciá-los individualmente mais tarde, ou podemos referenciá-los por índice. + +Vamos nos aprofundar com um exemplo. + +Para fins de demonstração, digamos que queremos contar o número de saudações que estão sendo coletadas para um determinado lote de entradas e relatá-lo em um arquivo. + +### 4.1. Modifique o processo para contar e gerar o número de saudações + +Isso exigirá duas mudanças-chave na definição do processo: precisamos de uma forma de contar as saudações e escrever um arquivo de relatório, então precisamos adicionar esse arquivo de relatório ao bloco `output` do processo. + +#### 4.1.1. Conte o número de saudações coletadas + +Convenientemente, o Nextflow nos permite adicionar código arbitrário no bloco `script:` da definição do processo, o que é muito útil para fazer coisas como essa. + +Isso significa que podemos usar a função integrada `size()` do Nextflow para obter o número de arquivos no array `input_files`, e escrever o resultado em arquivo com um comando `echo`. + +No bloco de processo `collectGreetings`, faça as seguintes alterações de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'Havia ${count_greetings} saudações neste lote.' > '${batch_name}-report.txt' + """ + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +A variável `count_greetings` será computada em tempo de execução. + +#### 4.1.2. Emita o arquivo de relatório e nomeie as saídas + +Em princípio, tudo o que precisamos fazer é adicionar o arquivo de relatório ao bloco `output:`. + +No entanto, enquanto estamos fazendo isso, também vamos adicionar algumas tags `emit:` às nossas declarações de saída. Estas nos permitirão selecionar as saídas por nome em vez de ter que usar índices posicionais. + +No bloco de processo, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +As tags `emit:` são opcionais, e poderíamos ter adicionado uma tag a apenas uma das saídas. +Mas como dizem, por que não ambos? + +!!! tip + + Se você não nomear as saídas de um processo usando `emit:`, ainda pode acessá-las individualmente usando seu respectivo índice (baseado em zero). + Por exemplo, você usaria `<process>.out[0]` para obter a primeira saída, `<process>.out[1]` para obter a segunda saída, e assim por diante. + + Preferimos nomear saídas porque caso contrário, é muito fácil pegar o índice errado por erro, especialmente quando o processo produz muitas saídas. + +### 4.2. Atualize as saídas do fluxo de trabalho + +Agora que temos duas saídas saindo do processo `collectGreetings`, a saída `collectGreetings.out` contém dois canais: + +- `collectGreetings.out.outfile` contém o arquivo de saída final +- `collectGreetings.out.report` contém o arquivo de relatório + +Precisamos atualizar as saídas do fluxo de trabalho adequadamente. + +#### 4.2.1. Atualize a seção `publish:` + +No bloco `workflow`, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Como você pode ver, referir-se a saídas específicas de processos agora é trivial. +Quando formos adicionar mais um passo ao nosso pipeline na Parte 5 (Contêineres), poderemos facilmente nos referir a `collectGreetings.out.outfile` e passá-lo ao novo processo (spoiler: o novo processo se chama `cowpy`). + +Mas por enquanto, vamos terminar de atualizar as saídas no nível do fluxo de trabalho. + +#### 4.2.2. Atualize o bloco `output` + +No bloco `output`, faça a seguinte alteração de código: + +=== "Depois" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Não precisamos atualizar a definição de saída `collected` já que esse nome não mudou. +Só precisamos adicionar a nova saída. + +### 4.3. Execute o fluxo de trabalho + +Vamos tentar executar isso com o lote atual de saudações. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +Se você olhar no diretório `results/hello_workflow/`, encontrará o novo arquivo de relatório, `trio-report.txt`. +Abra-o para verificar que o fluxo de trabalho relatou corretamente a contagem de saudações que foram processadas. + +??? abstract "Conteúdo do arquivo" + + ```txt title="trio-report.txt" + Havia 3 saudações neste lote. + ``` + +Sinta-se à vontade para adicionar mais saudações ao CSV e testar o que acontece. + +### Conclusão + +Você sabe como fazer um processo emitir múltiplas saídas nomeadas e como manuseá-las apropriadamente no nível do fluxo de trabalho. + +De forma mais geral, você entende os princípios-chave envolvidos em conectar processos de formas comuns. + +### O que vem a seguir? + +Faça uma pausa extra longa, você a merece. + +Quando estiver pronto, passe para [**Parte 4: Olá Módulos**](./04_hello_modules.md) para aprender como modularizar seu código para melhor manutenibilidade e eficiência de código. + +--- + +## Quiz + +<quiz> +Como você acessa a saída de um processo no bloco de fluxo de trabalho? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Saiba mais: [1.4. Passe a saída do primeiro processo para o segundo processo](#14-passe-a-saída-do-primeiro-processo-para-o-segundo-processo) +</quiz> + +<quiz> +O que determina a ordem de execução de processos no Nextflow? +- [ ] A ordem em que os processos são escritos no bloco de fluxo de trabalho +- [ ] Ordem alfabética pelo nome do processo +- [x] Dependências de dados entre processos +- [ ] Ordem aleatória para execução paralela + +Saiba mais: [1.4. Passe a saída do primeiro processo para o segundo processo](#14-passe-a-saída-do-primeiro-processo-para-o-segundo-processo) +</quiz> + +<quiz> +Qual operador deve substituir `???` para reunir todas as saídas em uma única lista para o processo downstream? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Saiba mais: [2.4. Use um operador para coletar as saudações em uma única entrada](#24-use-um-operador-para-coletar-as-saudações-em-uma-única-entrada) +</quiz> + +<quiz> +Quando você deve usar o operador `collect()`? +- [ ] Quando você quer processar itens em paralelo +- [ ] Quando você precisa filtrar conteúdo do canal +- [x] Quando um processo downstream precisa de todos os itens de um processo upstream +- [ ] Quando você quer dividir dados entre múltiplos processos + +Saiba mais: [2.4. Use um operador para coletar as saudações em uma única entrada](#24-use-um-operador-para-coletar-as-saudações-em-uma-única-entrada) +</quiz> + +<quiz> +Como você acessa uma saída nomeada de um processo? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Saiba mais: [4.1.2. Emita o arquivo de relatório e nomeie as saídas](#412-emita-o-arquivo-de-relatório-e-nomeie-as-saídas) +</quiz> + +<quiz> +Qual é a sintaxe correta para nomear uma saída em um processo? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Saiba mais: [4.1.2. Emita o arquivo de relatório e nomeie as saídas](#412-emita-o-arquivo-de-relatório-e-nomeie-as-saídas) +</quiz> + +<quiz> +Ao fornecer múltiplas entradas a um processo, o que deve ser verdadeiro? +- [ ] Todas as entradas devem ser do mesmo tipo +- [ ] As entradas devem ser fornecidas em ordem alfabética +- [x] A ordem das entradas deve corresponder à ordem definida no bloco de entrada +- [ ] Apenas duas entradas podem ser fornecidas por vez + +Saiba mais: [3. Passe mais de uma entrada para um processo](#3-passe-mais-de-uma-entrada-para-um-processo) +</quiz> diff --git a/docs/pt/docs/hello_nextflow/04_hello_modules.md b/docs/pt/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..bd9ce3c967 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Parte 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/04_hello_modules.md). +/// + +Esta seção aborda como organizar o código do seu fluxo de trabalho para tornar o desenvolvimento e a manutenção do seu pipeline mais eficientes e sustentáveis. +Especificamente, vamos demonstrar como usar **módulos**. + +No Nextflow, um **módulo** é uma única definição de processo que é encapsulada por si só em um arquivo de código independente. +Para usar um módulo em um fluxo de trabalho, você apenas adiciona uma única linha de declaração de importação ao seu arquivo de código do fluxo de trabalho; então você pode integrar o processo no fluxo de trabalho da mesma forma que normalmente faria. +Isso torna possível reutilizar definições de processos em múltiplos fluxos de trabalho sem produzir múltiplas cópias do código. + +Quando começamos a desenvolver nosso fluxo de trabalho, escrevemos tudo em um único arquivo de código. +Agora vamos mover os processos para módulos individuais. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Isso tornará nosso código mais compartilhável, flexível e de fácil manutenção. + +??? info "Como começar a partir desta seção" + + Esta seção do curso pressupõe que você completou as Partes 1-3 do curso [Olá Nextflow](./index.md), mas se você está confortável com os conceitos básicos abordados nessas seções, pode começar a partir daqui sem fazer nada especial. + +--- + +## 0. Aquecimento: Execute `hello-modules.nf` + +Vamos usar o script de fluxo de trabalho `hello-modules.nf` como ponto de partida. +Ele é equivalente ao script produzido ao trabalhar na Parte 3 deste curso de treinamento, exceto que mudamos os destinos de saída: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Apenas para ter certeza de que tudo está funcionando, execute o script uma vez antes de fazer quaisquer alterações: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Como anteriormente, você encontrará os arquivos de saída no diretório especificado no bloco `output` (aqui, `results/hello_modules/`). + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Se funcionou para você, você está pronto para aprender como modularizar o código do seu fluxo de trabalho. + +--- + +## 1. Crie um diretório para armazenar módulos + +É uma boa prática armazenar seus módulos em um diretório específico. +Você pode chamar esse diretório de qualquer nome, mas a convenção é chamá-lo de `modules/`. + +```bash +mkdir modules +``` + +!!! tip "Dica" + + Aqui estamos mostrando como usar **módulos locais**, ou seja, módulos armazenados localmente no mesmo repositório que o restante do código do fluxo de trabalho, em contraste com módulos remotos, que são armazenados em outros repositórios (remotos). + Para mais informações sobre **módulos remotos**, veja a [documentação](https://www.nextflow.io/docs/latest/module.html). + +--- + +## 2. Crie um módulo para `sayHello()` + +Na sua forma mais simples, transformar um processo existente em um módulo é pouco mais do que uma operação de copiar e colar. +Vamos criar um esboço de arquivo para o módulo, copiar o código relevante e então excluí-lo do arquivo principal do fluxo de trabalho. + +Então tudo o que precisaremos fazer é adicionar uma declaração de importação para que o Nextflow saiba trazer o código relevante em tempo de execução. + +### 2.1. Crie um esboço de arquivo para o novo módulo + +Vamos criar um arquivo vazio para o módulo chamado `sayHello.nf`. + +```bash +touch modules/sayHello.nf +``` + +Isso nos dá um lugar para colocar o código do processo. + +### 2.2. Mova o código do processo `sayHello` para o arquivo do módulo + +Copie toda a definição do processo do arquivo de fluxo de trabalho para o arquivo do módulo, certificando-se de copiar também o shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Uma vez feito isso, exclua a definição do processo do arquivo de fluxo de trabalho, mas certifique-se de deixar o shebang no lugar. + +### 2.3. Adicione uma declaração de importação antes do bloco de fluxo de trabalho + +A sintaxe para importar um módulo local é bastante direta: + +```groovy title="Sintaxe: Declaração de importação" +include { <NOME_DO_MÓDULO> } from '<caminho_para_o_módulo>' +``` + +Vamos inserir isso acima do bloco `params` e preenchê-lo adequadamente. + +=== "Depois" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Você vê que preenchemos o nome do módulo, `sayHello`, e o caminho para o arquivo contendo o código do módulo, `./modules/sayHello.nf`. + +### 2.4. Execute o fluxo de trabalho + +Estamos executando o fluxo de trabalho com essencialmente o mesmo código e entradas de antes, então vamos executar com a flag `-resume` e ver o que acontece. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Isso deve ser executado muito rapidamente porque tudo está em cache. +Sinta-se à vontade para verificar as saídas publicadas. + +O Nextflow reconheceu que ainda é todo o mesmo trabalho a ser feito, mesmo que o código esteja dividido em múltiplos arquivos. + +### Conclusão + +Você sabe como extrair um processo para um módulo local e você sabe que fazer isso não quebra a capacidade de retomada do fluxo de trabalho. + +### Qual é o próximo passo? + +Pratique criando mais módulos. +Uma vez que você fez um, você pode fazer um milhão mais... +Mas vamos fazer apenas mais dois por enquanto. + +--- + +## 3. Modularize o processo `convertToUpper()` + +### 3.1. Crie um esboço de arquivo para o novo módulo + +Crie um arquivo vazio para o módulo chamado `convertToUpper.nf`. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. Mova o código do processo `convertToUpper` para o arquivo do módulo + +Copie toda a definição do processo do arquivo de fluxo de trabalho para o arquivo do módulo, certificando-se de copiar também o shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usa uma ferramenta de substituição de texto para converter a saudação para maiúsculas + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Uma vez feito isso, exclua a definição do processo do arquivo de fluxo de trabalho, mas certifique-se de deixar o shebang no lugar. + +### 3.3. Adicione uma declaração de importação antes do bloco `params` + +Insira a declaração de importação acima do bloco `params` e preencha-a adequadamente. + +=== "Depois" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="23" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Isso deve começar a parecer muito familiar. + +### 3.4. Execute o fluxo de trabalho novamente + +Execute isso com a flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Isso ainda deve produzir a mesma saída de antes. + +Dois feitos, mais um para fazer! + +--- + +## 4. Modularize o processo `collectGreetings()` + +### 4.1. Crie um esboço de arquivo para o novo módulo + +Crie um arquivo vazio para o módulo chamado `collectGreetings.nf`. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. Mova o código do processo `collectGreetings` para o arquivo do módulo + +Copie toda a definição do processo do arquivo de fluxo de trabalho para o arquivo do módulo, certificando-se de copiar também o shebang `#!/usr/bin/env nextflow`. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Coleta saudações em maiúsculas em um único arquivo de saída + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ +} +``` + +Uma vez feito isso, exclua a definição do processo do arquivo de fluxo de trabalho, mas certifique-se de deixar o shebang no lugar. + +### 4.3. Adicione uma declaração de importação antes do bloco `params` + +Insira a declaração de importação acima do bloco `params` e preencha-a adequadamente. + +=== "Depois" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Antes" + + ```groovy title="hello-modules.nf" linenums="3" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parameters + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Último! + +### 4.4. Execute o fluxo de trabalho + +Execute isso com a flag `-resume`. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Isso ainda deve produzir a mesma saída de antes. + +### Conclusão + +Você sabe como modularizar múltiplos processos em um fluxo de trabalho. + +Parabéns, você fez todo esse trabalho e absolutamente nada mudou na forma como o pipeline funciona! + +Brincadeiras à parte, agora seu código é mais modular, e se você decidir escrever outro pipeline que chame um desses processos, você só precisa digitar uma curta declaração de importação para usar o módulo relevante. +Isso é melhor do que copiar e colar o código, porque se mais tarde você decidir melhorar o módulo, todos os seus pipelines herdarão as melhorias. + +### Qual é o próximo passo? + +Faça uma pequena pausa se quiser. + +Quando estiver pronto, passe para a [**Parte 5: Olá Contêineres**](./05_hello_containers.md) para aprender como usar contêineres para gerenciar dependências de software de forma mais conveniente e reproduzível. + +--- + +## Quiz + +<quiz> +O que é um módulo no Nextflow? +- [ ] Um arquivo de configuração +- [x] Um arquivo independente contendo uma única definição de processo +- [ ] Uma definição de fluxo de trabalho +- [ ] Um operador de canal + +Saiba mais: [2. Crie um módulo para `sayHello()`](#2-crie-um-modulo-para-sayhello) +</quiz> + +<quiz> +Qual é a convenção de nomenclatura recomendada para arquivos de módulo? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Onde os arquivos de módulo devem ser armazenados? +- [ ] No mesmo diretório que o fluxo de trabalho +- [ ] Em um diretório `bin/` +- [x] Em um diretório `modules/` +- [ ] Em um diretório `lib/` + +Saiba mais: [1. Crie um diretório para armazenar módulos](#1-crie-um-diretorio-para-armazenar-modulos) +</quiz> + +<quiz> +Qual é a sintaxe correta para importar um módulo? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Saiba mais: [2.3. Adicione uma declaração de importação](#23-adicione-uma-declaracao-de-importacao-antes-do-bloco-de-fluxo-de-trabalho) +</quiz> + +<quiz> +O que acontece com a funcionalidade `-resume` ao usar módulos? +- [ ] Ela não funciona mais +- [ ] Ela requer configuração adicional +- [x] Ela funciona da mesma forma que antes +- [ ] Ela funciona apenas para módulos locais +</quiz> + +<quiz> +Quais são os benefícios de usar módulos? (Selecione todas as opções aplicáveis) +- [x] Reutilização de código entre fluxos de trabalho +- [x] Manutenção mais fácil +- [x] Melhor organização do código do fluxo de trabalho +- [ ] Velocidade de execução mais rápida +</quiz> diff --git a/docs/pt/docs/hello_nextflow/05_hello_containers.md b/docs/pt/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..0219e21196 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Parte 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do Nextflow no YouTube. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/05_hello_containers.md). +/// + +Nas Partes 1-4 deste curso de treinamento, você aprendeu como usar os blocos de construção básicos do Nextflow para montar um fluxo de trabalho simples capaz de processar algum texto, paralelizar a execução se houvesse múltiplas entradas e coletar os resultados para processamento adicional. + +No entanto, você estava limitado às ferramentas básicas do UNIX disponíveis no seu ambiente. +Tarefas do mundo real frequentemente requerem várias ferramentas e pacotes não incluídos por padrão. +Tipicamente, você precisaria instalar essas ferramentas, gerenciar suas dependências e resolver quaisquer conflitos. + +Tudo isso é muito tedioso e irritante, então vamos mostrar como usar **contêineres** para resolver este problema de forma muito mais conveniente. + +Um **contêiner** é uma unidade leve, autônoma e executável de software criada a partir de uma **imagem** de contêiner que inclui tudo o que é necessário para executar uma aplicação, incluindo código, bibliotecas do sistema e configurações. +Como você pode imaginar, isso será muito útil para tornar seus pipelines mais reproduzíveis. + +Note que ensinaremos isso usando [Docker](https://www.docker.com/get-started/), mas tenha em mente que o Nextflow suporta [várias outras tecnologias de contêiner](https://www.nextflow.io/docs/latest/container.html#) também. + +??? info "Como começar a partir desta seção" + + Esta seção do curso assume que você completou as Partes 1-4 do curso [Hello Nextflow](./index.md) e tem um pipeline completo funcionando. + + Se você está começando o curso a partir deste ponto, você precisará copiar o diretório `modules` das soluções: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Aquecimento: Execute `hello-containers.nf` + +Vamos usar o script de fluxo de trabalho `hello-containers.nf` como ponto de partida. +Ele é equivalente ao script produzido ao trabalhar na Parte 4 deste curso de treinamento, exceto que mudamos os destinos de saída: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Apenas para garantir que tudo está funcionando, execute o script uma vez antes de fazer qualquer alteração: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Como anteriormente, você encontrará os arquivos de saída no diretório especificado no bloco `output` (`results/hello_containers/`). + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Se funcionou para você, você está pronto para aprender como usar contêineres. + +--- + +## 1. Use um contêiner 'manualmente' + +O que queremos fazer é adicionar uma etapa ao nosso fluxo de trabalho que usará um contêiner para execução. + +No entanto, primeiro vamos revisar alguns conceitos básicos e operações para solidificar sua compreensão do que são contêineres antes de começarmos a usá-los no Nextflow. + +### 1.1. Baixe a imagem do contêiner + +Para usar um contêiner, você normalmente baixa ou _puxa_ uma imagem de contêiner de um registro de contêineres e então executa a imagem de contêiner para criar uma instância de contêiner. + +A sintaxe geral é a seguinte: + +```bash title="Sintaxe" +docker pull '<container>' +``` + +A parte `docker pull` é a instrução ao sistema de contêiner para puxar uma imagem de contêiner de um repositório. + +A parte `'<container>'` é o endereço URI da imagem de contêiner. + +Como exemplo, vamos puxar uma imagem de contêiner que contém [cowpy](https://github.com/jeffbuttars/cowpy), uma implementação em Python de uma ferramenta chamada `cowsay` que gera arte ASCII para exibir entradas de texto arbitrárias de forma divertida. + +```txt title="Exemplo" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Existem vários repositórios onde você pode encontrar contêineres publicados. +Usamos o serviço [Seqera Containers](https://seqera.io/containers/) para gerar esta imagem de contêiner Docker a partir do pacote Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Execute o comando pull completo: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Saída do comando" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Se você nunca baixou a imagem antes, isso pode levar um minuto para completar. +Uma vez concluído, você tem uma cópia local da imagem de contêiner. + +### 1.2. Use o contêiner para executar `cowpy` como um comando único + +Uma maneira muito comum de as pessoas usarem contêineres é executá-los diretamente, _ou seja_, de forma não interativa. +Isso é ótimo para executar comandos únicos. + +A sintaxe geral é a seguinte: + +```bash title="Sintaxe" +docker run --rm '<container>' [tool command] +``` + +A parte `docker run --rm '<container>'` é a instrução ao sistema de contêiner para iniciar uma instância de contêiner a partir de uma imagem de contêiner e executar um comando nela. +A flag `--rm` diz ao sistema para desligar a instância de contêiner após o comando ter sido completado. + +A sintaxe `[tool command]` depende da ferramenta que você está usando e de como o contêiner está configurado. +Vamos começar apenas com `cowpy`. + +Totalmente montado, o comando de execução do contêiner fica assim; vá em frente e execute-o. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Saída do comando" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +O sistema iniciou o contêiner, executou o comando `cowpy` com seus parâmetros, enviou a saída para o console e finalmente desligou a instância de contêiner. + +### 1.3. Use o contêiner para executar `cowpy` interativamente + +Você também pode executar um contêiner interativamente, o que lhe dá um prompt de shell dentro do contêiner e permite que você brinque com o comando. + +#### 1.3.1. Inicie o contêiner + +Para executar interativamente, apenas adicionamos `-it` ao comando `docker run`. +Opcionalmente, podemos especificar o shell que queremos usar dentro do contêiner anexando _por exemplo_ `/bin/bash` ao comando. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Note que seu prompt muda para algo como `(base) root@b645838b3314:/tmp#`, o que indica que você está agora dentro do contêiner. + +Você pode verificar isso executando `ls /` para listar o conteúdo do diretório a partir da raiz do sistema de arquivos: + +```bash +ls / +``` + +??? abstract "Saída do comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Usamos `ls` aqui em vez de `tree` porque o utilitário `tree` não está disponível neste contêiner. +Você pode ver que o sistema de arquivos dentro do contêiner é diferente do sistema de arquivos no seu sistema hospedeiro. + +Uma limitação do que acabamos de fazer é que o contêiner está completamente isolado do sistema hospedeiro por padrão. +Isso significa que o contêiner não pode acessar nenhum arquivo no sistema hospedeiro a menos que você permita explicitamente que ele o faça. + +Vamos mostrar como fazer isso em um minuto. + +#### 1.3.2. Execute o(s) comando(s) da ferramenta desejada + +Agora que você está dentro do contêiner, você pode executar o comando `cowpy` diretamente e dar alguns parâmetros a ele. +Por exemplo, a documentação da ferramenta diz que podemos mudar o personagem ('cowacter') com `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Saída do comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Agora a saída mostra o pinguim do Linux, Tux, em vez da vaca padrão, porque especificamos o parâmetro `-c tux`. + +Como você está dentro do contêiner, você pode executar o comando `cowpy` quantas vezes quiser, variando os parâmetros de entrada, sem ter que se preocupar com comandos Docker. + +!!! Tip "Dica" + + Use a flag '-c' para escolher um personagem diferente, incluindo: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Isso é legal. O que seria ainda mais legal é se pudéssemos alimentar nosso `greetings.csv` como entrada nisso. +Mas como não temos acesso ao sistema de arquivos, não podemos. + +Vamos consertar isso. + +#### 1.3.3. Saia do contêiner + +Para sair do contêiner, você pode digitar `exit` no prompt ou usar o atalho de teclado ++ctrl+d++. + +```bash +exit +``` + +Seu prompt agora deve estar de volta ao que era antes de você iniciar o contêiner. + +#### 1.3.4. Monte dados no contêiner + +Como notado anteriormente, o contêiner está isolado do sistema hospedeiro por padrão. + +Para permitir que o contêiner acesse o sistema de arquivos do hospedeiro, você pode **montar** um **volume** do sistema hospedeiro no contêiner usando a seguinte sintaxe: + +```bash title="Sintaxe" +-v <outside_path>:<inside_path> +``` + +No nosso caso `<outside_path>` será o diretório de trabalho atual, então podemos apenas usar um ponto (`.`), e `<inside_path>` é apenas um alias que inventamos; vamos chamá-lo de `/my_project` (o caminho interno deve ser absoluto). + +Para montar um volume, substituímos os caminhos e adicionamos o argumento de montagem de volume ao comando docker run da seguinte forma: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Isso monta o diretório de trabalho atual como um volume que estará acessível em `/my_project` dentro do contêiner. + +Você pode verificar que funciona listando o conteúdo de `/my_project`: + +```bash +ls /my_project +``` + +??? success "Saída do comando" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Agora você pode ver o conteúdo do diretório de trabalho de dentro do contêiner, incluindo o arquivo `greetings.csv` em `data/`. + +Isso efetivamente estabeleceu um túnel através da parede do contêiner que você pode usar para acessar aquela parte do seu sistema de arquivos. + +#### 1.3.5. Use os dados montados + +Agora que montamos o diretório de trabalho no contêiner, podemos usar o comando `cowpy` para exibir o conteúdo do arquivo `greetings.csv`. + +Para fazer isso, usaremos `cat /my_project/data/greetings.csv | ` para canalizar o conteúdo do arquivo CSV para o comando `cowpy`. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Saída do comando" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Isso produz a arte ASCII desejada de um peru recitando nossas saudações de exemplo! +Exceto que aqui o peru está repetindo as linhas completas em vez de apenas as saudações. +Já sabemos que nosso fluxo de trabalho Nextflow fará um trabalho melhor! + +Sinta-se à vontade para brincar com este comando. +Quando terminar, saia do contêiner como anteriormente: + +```bash +exit +``` + +Você se encontrará de volta ao seu shell normal. + +### Conclusão + +Você sabe como puxar um contêiner e executá-lo como um comando único ou interativamente. Você também sabe como tornar seus dados acessíveis de dentro do seu contêiner, o que permite que você experimente qualquer ferramenta na qual esteja interessado com dados reais sem ter que instalar nenhum software no seu sistema. + +### O que vem a seguir? + +Aprenda como usar contêineres para a execução de processos Nextflow. + +--- + +## 2. Use contêineres no Nextflow + +O Nextflow tem suporte integrado para executar processos dentro de contêineres para permitir que você execute ferramentas que você não tem instaladas no seu ambiente de computação. +Isso significa que você pode usar qualquer imagem de contêiner que desejar para executar seus processos, e o Nextflow cuidará de puxar a imagem, montar os dados e executar o processo dentro dela. + +Para demonstrar isso, vamos adicionar uma etapa `cowpy` ao pipeline que estamos desenvolvendo, após a etapa `collectGreetings`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Muu se você está pronto para mergulhar! + +### 2.1. Escreva um módulo `cowpy` + +Primeiro, vamos criar o módulo do processo `cowpy`. + +#### 2.1.1. Crie um arquivo stub para o novo módulo + +Crie um arquivo vazio para o módulo chamado `cowpy.nf`. + +```bash +touch modules/cowpy.nf +``` + +Isso nos dá um lugar para colocar o código do processo. + +#### 2.1.2. Copie o código do processo `cowpy` no arquivo do módulo + +Podemos modelar nosso processo `cowpy` nos outros processos que escrevemos anteriormente. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Gera arte ASCII com cowpy +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +O processo espera um `input_file` contendo as saudações, bem como um valor `character`. + +A saída será um novo arquivo de texto contendo a arte ASCII gerada pela ferramenta `cowpy`. + +### 2.2. Adicione cowpy ao fluxo de trabalho + +Agora precisamos importar o módulo e chamar o processo. + +#### 2.2.1. Importe o processo `cowpy` para `hello-containers.nf` + +Insira a declaração de importação acima do bloco de fluxo de trabalho e preencha-a adequadamente. + +=== "Depois" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="3" + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Agora o módulo `cowpy` está disponível para uso no fluxo de trabalho. + +#### 2.2.2. Adicione uma chamada ao processo `cowpy` no fluxo de trabalho + +Vamos conectar o processo `cowpy()` à saída do processo `collectGreetings()`, que como você deve se lembrar produz duas saídas: + +- `collectGreetings.out.outfile` contém o arquivo de saída <--_o que queremos_ +- `collectGreetings.out.report` contém o arquivo de relatório com a contagem de saudações por lote + +No bloco de fluxo de trabalho, faça a seguinte mudança de código: + +=== "Depois" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Note que declaramos um novo parâmetro CLI, `params.character`, para especificar qual personagem queremos que diga as saudações. + +#### 2.2.3. Adicione o parâmetro `character` ao bloco `params` + +Isso é tecnicamente opcional, mas é a prática recomendada e é uma oportunidade de definir um valor padrão para o personagem enquanto estamos nisso. + +=== "Depois" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Agora podemos ser preguiçosos e pular a digitação do parâmetro de personagem em nossas linhas de comando. + +#### 2.2.4. Atualize as saídas do fluxo de trabalho + +Precisamos atualizar as saídas do fluxo de trabalho para publicar a saída do processo `cowpy`. + +##### 2.2.4.1. Atualize a seção `publish:` + +No bloco de `workflow`, faça a seguinte mudança de código: + +=== "Depois" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +O processo `cowpy` produz apenas uma saída, então podemos referenciá-la da maneira usual anexando `.out`. + +Mas por enquanto, vamos terminar de atualizar as saídas no nível do fluxo de trabalho. + +##### 2.2.4.2. Atualize o bloco `output` + +Precisamos adicionar a saída final `cowpy_art` ao bloco `output`. Enquanto estamos nisso, vamos também editar os destinos de publicação, já que agora nosso pipeline está completo e sabemos quais saídas realmente nos interessam. + +No bloco `output`, faça as seguintes mudanças de código: + +=== "Depois" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Agora as saídas publicadas estarão um pouco mais organizadas. + +#### 2.2.5. Execute o fluxo de trabalho + +Apenas para recapitular, isso é o que estamos buscando: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Você acha que vai funcionar? + +Vamos deletar as saídas publicadas anteriores para ter um slate limpo, e executar o fluxo de trabalho com a flag `-resume`. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Saída do comando (editada para clareza)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +Oh não, há um erro! +O código de erro dado por `error exit status (127)` significa que o executável que pedimos não foi encontrado. + +Isso faz sentido, já que estamos chamando a ferramenta `cowpy` mas não especificamos um contêiner ainda (ops). + +### 2.3. Use um contêiner para executar o processo `cowpy` + +Precisamos especificar um contêiner e dizer ao Nextflow para usá-lo no processo `cowpy()`. + +#### 2.3.1. Especifique um contêiner para `cowpy` + +Podemos usar a mesma imagem que estávamos usando diretamente na primeira seção deste tutorial. + +Edite o módulo `cowpy.nf` para adicionar a diretiva `container` à definição do processo da seguinte forma: + +=== "Depois" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Isso diz ao Nextflow que _se o uso de Docker estiver habilitado_, ele deve usar a imagem de contêiner especificada aqui para executar o processo. + +#### 2.3.2. Habilite o uso de Docker através do arquivo `nextflow.config` + +Note que dissemos _'se o uso de Docker estiver habilitado'_. Por padrão, não está, então precisamos dizer ao Nextflow que ele tem permissão para usar Docker. +Para esse fim, vamos antecipar um pouco o tópico da próxima e última parte deste curso (Parte 6), que cobre configuração. + +Uma das principais maneiras que o Nextflow oferece para configurar a execução do fluxo de trabalho é usar um arquivo `nextflow.config`. +Quando tal arquivo está presente no diretório atual, o Nextflow irá carregá-lo automaticamente e aplicar qualquer configuração que ele contém. + +Fornecemos um arquivo `nextflow.config` com uma única linha de código que desabilita explicitamente o Docker: `docker.enabled = false`. + +Agora, vamos mudar isso para `true` para habilitar o Docker: + +=== "Depois" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Antes" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "Dica" + + É possível habilitar a execução Docker a partir da linha de comando, por execução, usando o parâmetro `-with-docker <container>`. + No entanto, isso só nos permite especificar um contêiner para todo o fluxo de trabalho, enquanto a abordagem que acabamos de mostrar permite especificar um contêiner diferente por processo. + Isso é melhor para modularidade, manutenção de código e reprodutibilidade. + +#### 2.3.3. Execute o fluxo de trabalho com Docker habilitado + +Execute o fluxo de trabalho com a flag `-resume`: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Desta vez realmente funciona! +Como de costume, você pode encontrar as saídas do fluxo de trabalho no diretório de resultados correspondente, embora desta vez elas estejam um pouco mais organizadas, com apenas o relatório e a saída final no nível superior, e todos os arquivos intermediários empurrados para fora do caminho em um subdiretório. + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +A saída final de arte ASCII está no diretório `results/hello_containers/`, com o nome `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +E aí está, nosso lindo peru dizendo as saudações conforme desejado. + +#### 2.3.4. Inspecione como o Nextflow lançou a tarefa em contêiner + +Como um coda final para esta seção, vamos dar uma olhada no subdiretório de trabalho de uma das chamadas do processo `cowpy` para obter um pouco mais de insight sobre como o Nextflow trabalha com contêineres nos bastidores. + +Verifique a saída do seu comando `nextflow run` para encontrar o caminho para o subdiretório de trabalho do processo `cowpy`. +Olhando para o que obtivemos para a execução mostrada acima, a linha de log do console para o processo `cowpy` começa com `[98/656c6c]`. +Isso corresponde ao seguinte caminho de diretório truncado: `work/98/656c6c`. + +Nesse diretório, você encontrará o arquivo `.command.run` que contém todos os comandos que o Nextflow executou em seu nome no curso da execução do pipeline. + +??? abstract "Conteúdo do arquivo" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Se você procurar por `nxf_launch` neste arquivo, você deve ver algo assim: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Como você pode ver, o Nextflow está usando o comando `docker run` para lançar a chamada do processo. +Ele também monta o subdiretório de trabalho correspondente no contêiner, define o diretório de trabalho dentro do contêiner adequadamente e executa nosso script bash modelado no arquivo `.command.sh`. + +Todo o trabalho duro que tivemos que fazer manualmente na primeira seção? O Nextflow faz por nós nos bastidores! + +```txt + _______________________ +< Viva os robôs...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Conclusão + +Você sabe como usar contêineres no Nextflow para executar processos. + +### O que vem a seguir? + +Faça uma pausa! + +Quando estiver pronto, siga para [**Parte 6: Olá Configuração**](./06_hello_config.md) para aprender como configurar a execução do seu pipeline para se adequar à sua infraestrutura, bem como gerenciar configuração de entradas e parâmetros. + +É a última parte, e então você terá terminado este curso! + +--- + +## Quiz + +<quiz> +O que é um contêiner? +- [ ] Um tipo de máquina virtual +- [ ] Um formato de compressão de arquivo +- [x] Uma unidade leve, autônoma e executável que inclui tudo o que é necessário para executar uma aplicação +- [ ] Um protocolo de rede +</quiz> + +<quiz> +Qual é a diferença entre uma imagem de contêiner e uma instância de contêiner? +- [ ] São a mesma coisa +- [x] Uma imagem é um template; uma instância é um contêiner em execução criado a partir dessa imagem +- [ ] Uma instância é um template; uma imagem é um contêiner em execução +- [ ] Imagens são para Docker; instâncias são para Singularity +</quiz> + +<quiz> +O que a flag `-v` faz em um comando `docker run`? +- [ ] Habilita saída detalhada +- [ ] Valida o contêiner +- [x] Monta um volume do sistema hospedeiro no contêiner +- [ ] Especifica a versão do contêiner + +Saiba mais: [1.3.4. Monte dados no contêiner](#134-monte-dados-no-conteiner) +</quiz> + +<quiz> +Por que você precisa montar volumes ao usar contêineres? +- [ ] Para melhorar o desempenho do contêiner +- [ ] Para economizar espaço em disco +- [x] Porque contêineres estão isolados do sistema de arquivos do hospedeiro por padrão +- [ ] Para habilitar rede + +Saiba mais: [1.3.4. Monte dados no contêiner](#134-monte-dados-no-conteiner) +</quiz> + +<quiz> +Como você especifica um contêiner para um processo Nextflow? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Saiba mais: [2.3.1. Especifique um contêiner para cowpy](#231-especifique-um-conteiner-para-cowpy) +</quiz> + +<quiz> +Qual configuração do `nextflow.config` habilita Docker para seu fluxo de trabalho? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Saiba mais: [2.3.2. Habilite o uso de Docker através do arquivo `nextflow.config`](#232-habilite-o-uso-de-docker-atraves-do-arquivo-nextflowconfig) +</quiz> + +<quiz> +O que o Nextflow lida automaticamente ao executar um processo em um contêiner? (Selecione todas as opções que se aplicam) +- [x] Puxar a imagem do contêiner se necessário +- [x] Montar o diretório de trabalho +- [x] Executar o script do processo dentro do contêiner +- [x] Limpar a instância do contêiner após a execução + +Saiba mais: [2.3.4. Inspecione como o Nextflow lançou a tarefa em contêiner](#234-inspecione-como-o-nextflow-lancou-a-tarefa-em-conteiner) +</quiz> diff --git a/docs/pt/docs/hello_nextflow/06_hello_config.md b/docs/pt/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..22c96eb394 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1367 @@ +# Parte 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja [a playlist completa](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) no canal do YouTube do Nextflow. + +:green_book: A transcrição do vídeo está disponível [aqui](./transcripts/06_hello_config.md). +/// + +Esta seção explorará como configurar e gerenciar a configuração do seu pipeline Nextflow para que você possa personalizar seu comportamento, adaptá-lo a diferentes ambientes e otimizar o uso de recursos _sem alterar uma única linha do código do fluxo de trabalho_. + +Existem várias maneiras de fazer isso, que podem ser usadas em combinação e são interpretadas de acordo com a ordem de precedência descrita [aqui](https://www.nextflow.io/docs/latest/config.html). + +Nesta parte do curso, vamos mostrar o mecanismo de arquivo de configuração mais simples e comum, o arquivo `nextflow.config`, que você já encontrou na Parte 5: Hello Containers. + +Vamos abordar componentes essenciais da configuração do Nextflow, como diretivas de processos, executores, perfis e arquivos de parâmetros. +Ao aprender a utilizar essas opções de configuração de forma eficaz, você pode melhorar a flexibilidade, escalabilidade e desempenho dos seus pipelines. + +??? info "Como começar a partir desta seção" + + Esta seção do curso assume que você completou as Partes 1-5 do curso [Hello Nextflow](./index.md) e tem um pipeline completo funcionando. + + Se você está começando o curso a partir deste ponto, precisará copiar o diretório `modules` e o arquivo `nextflow.config` das soluções: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + O arquivo `nextflow.config` contém a linha `docker.enabled = true` que habilita o uso de contêineres Docker. + + Se você não está familiarizado com o pipeline Hello ou precisa relembrar, veja [esta página de informações](../info/hello_pipeline.md). + +--- + +## 0. Aquecimento: Execute `hello-config.nf` + +Vamos usar o script do fluxo de trabalho `hello-config.nf` como ponto de partida. +Ele é equivalente ao script produzido ao trabalhar na Parte 5 deste curso de treinamento, exceto que mudamos os destinos de saída: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Apenas para garantir que tudo está funcionando, execute o script uma vez antes de fazer qualquer alteração: + +```bash +nextflow run hello-config.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Como anteriormente, você encontrará os arquivos de saída no diretório especificado no bloco `output` (`results/hello_config/`). + +??? abstract "Conteúdo do diretório" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +A saída final em arte ASCII está no diretório `results/hello_config/`, com o nome `cowpy-COLLECTED-batch-output.txt`. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Se isso funcionou para você, está pronto para aprender como configurar seus pipelines. + +--- + +## 1. Gerencie parâmetros de entrada do fluxo de trabalho + +Vamos começar com um aspecto da configuração que é simplesmente uma extensão do que temos trabalhado até agora: o gerenciamento de parâmetros de entrada. + +Atualmente, nosso fluxo de trabalho está configurado para aceitar vários valores de parâmetros via linha de comando, com valores padrão definidos em um bloco `params` no próprio script do fluxo de trabalho. +No entanto, você pode querer substituir esses padrões sem ter que especificar parâmetros na linha de comando ou modificar o arquivo de script original. + +Existem várias maneiras de fazer isso; vamos mostrar três formas básicas que são muito comumente usadas. + +### 1.1. Mova os valores padrão para o `nextflow.config` + +Esta é a abordagem mais simples, embora seja possivelmente a menos flexível, já que o arquivo `nextflow.config` principal não é algo que você quer estar editando para cada execução. +Mas tem a vantagem de separar as preocupações de _declarar_ os parâmetros no fluxo de trabalho (que definitivamente pertence lá) versus fornecer _valores padrão_, que estão mais em casa em um arquivo de configuração. + +Vamos fazer isso em dois passos. + +#### 1.1.1. Crie um bloco `params` no arquivo de configuração + +Faça as seguintes alterações de código no arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Note que não simplesmente copiamos o bloco `params` do fluxo de trabalho para o arquivo de configuração. +A sintaxe é um pouco diferente. +No arquivo de fluxo de trabalho, essas são declarações tipadas. +Na configuração, essas são atribuições de valores. + +Tecnicamente, isso é suficiente para substituir os valores padrão ainda especificados no arquivo de fluxo de trabalho. +Você poderia modificar o caractere, por exemplo, e executar o fluxo de trabalho para se convencer de que o valor definido no arquivo de configuração substitui o definido no arquivo de fluxo de trabalho. + +Mas no espírito de mover a configuração completamente para o arquivo de configuração, vamos remover esses valores do arquivo de fluxo de trabalho inteiramente. + +#### 1.1.2. Remova os valores do bloco `params` no arquivo de fluxo de trabalho + +Faça as seguintes alterações de código no arquivo de fluxo de trabalho `hello-config.nf`: + +=== "Depois" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parameters + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Agora o arquivo de fluxo de trabalho em si não define nenhum valor padrão para esses parâmetros. + +#### 1.1.3. Execute o pipeline + +Vamos testar se funciona corretamente. + +```bash +nextflow run hello-config.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes. + +A saída final em arte ASCII está no diretório `results/hello_config/`, com o nome `cowpy-COLLECTED-batch-output.txt`, igual a antes. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funcionalmente, essa mudança não alterou nada, mas conceitualmente é um pouco mais limpo ter os valores padrão definidos no arquivo de configuração. + +### 1.2. Use um arquivo de configuração específico para a execução + +Isso é ótimo, mas às vezes você pode querer executar alguns experimentos temporários com diferentes valores padrão sem mexer no arquivo de configuração principal. +Você pode fazer isso criando um novo arquivo `nextflow.config` em um subdiretório que você usará como diretório de trabalho para seus experimentos. + +#### 1.2.1. Crie o diretório de trabalho com uma configuração em branco + +Vamos começar criando um novo diretório e entrando nele: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Em seguida, crie um arquivo de configuração em branco nesse diretório: + +```bash +touch nextflow.config +``` + +Isso produz um arquivo vazio. + +#### 1.2.2. Configure a configuração experimental + +Agora abra o novo arquivo e adicione os parâmetros que você deseja personalizar: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Note que o caminho para o arquivo de entrada deve refletir a estrutura de diretórios. + +#### 1.2.3. Execute o pipeline + +Agora podemos executar nosso pipeline de dentro do nosso novo diretório de trabalho. +Certifique-se de adaptar o caminho adequadamente! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Isso criará um novo conjunto de diretórios em `tux-run/` incluindo `tux-run/work/` e `tux-run/results/`. + +Nesta execução, o Nextflow combina o `nextflow.config` no nosso diretório atual com o `nextflow.config` no diretório raiz do pipeline, e assim substitui o caractere padrão (turkey) pelo caractere tux. + +O arquivo de saída final deve conter o caractere tux dizendo as saudações. + +??? abstract "Conteúdo do arquivo" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +É isso; agora você tem um espaço para experimentar sem modificar sua configuração 'normal'. + +!!! warning + + Certifique-se de voltar ao diretório anterior antes de passar para a próxima seção! + + ```bash + cd .. + ``` + +Agora vamos ver outra maneira útil de definir valores de parâmetros. + +### 1.3. Use um arquivo de parâmetros + +A abordagem de subdiretório funciona muito bem para experimentar, mas envolve um pouco de configuração e requer que você adapte os caminhos adequadamente. +Existe uma abordagem mais simples para quando você quer executar seu pipeline com um conjunto específico de valores, ou permitir que outra pessoa faça isso com o mínimo de esforço. + +O Nextflow nos permite especificar parâmetros via um arquivo de parâmetros no formato YAML ou JSON, o que torna muito conveniente gerenciar e distribuir conjuntos alternativos de valores padrão, por exemplo, assim como valores de parâmetros específicos da execução. + +#### 1.3.1. Examine o arquivo de parâmetros de exemplo + +Para demonstrar isso, fornecemos um arquivo de parâmetros de exemplo no diretório atual, chamado `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Este arquivo de parâmetros contém um par chave-valor para cada uma das entradas que queremos especificar. +Note o uso de dois pontos (`:`) em vez de sinais de igual (`=`) se você comparar a sintaxe com o arquivo de configuração. +O arquivo de configuração é escrito em Groovy, enquanto o arquivo de parâmetros é escrito em YAML. + +!!! info + + Também fornecemos uma versão JSON do arquivo de parâmetros como exemplo, mas não vamos executar com ela aqui. + Sinta-se livre para tentar essa por conta própria. + +#### 1.3.2. Execute o pipeline + +Para executar o fluxo de trabalho com este arquivo de parâmetros, simplesmente adicione `-params-file <filename>` ao comando base. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +O arquivo de saída final deve conter o caractere stegosaurus dizendo as saudações. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usar um arquivo de parâmetros pode parecer exagero quando você tem apenas alguns parâmetros para especificar, mas alguns pipelines esperam dezenas de parâmetros. +Nesses casos, usar um arquivo de parâmetros nos permitirá fornecer valores de parâmetros no tempo de execução sem ter que digitar linhas de comando enormes e sem modificar o script do fluxo de trabalho. + +Também torna mais fácil distribuir conjuntos de parâmetros para colaboradores, ou como informação de apoio para uma publicação, por exemplo. +Isso torna seu trabalho mais reproduzível por outros. + +### Conclusão + +Você sabe como aproveitar as principais opções de configuração para gerenciar entradas do fluxo de trabalho. + +### O que vem a seguir? + +Aprenda como gerenciar onde e como as saídas do seu fluxo de trabalho são publicadas. + +--- + +## 2. Gerencie saídas do fluxo de trabalho + +Até agora temos codificado todos os caminhos para declarações de saída no nível do fluxo de trabalho, e como notamos quando começamos a adicionar múltiplas saídas, pode haver um pouco de repetição envolvida. + +Vamos ver algumas maneiras comuns de configurar isso para ser mais flexível. + +### 2.1. Personalize o nome do diretório `outputDir` + +Para cada capítulo deste curso, temos publicado saídas em um subdiretório diferente codificado nas definições de saída. + +Vamos mudar isso para usar um parâmetro configurável pelo usuário. +Poderíamos criar um parâmetro totalmente novo para isso, mas vamos usar o parâmetro `batch` já que está bem ali. + +#### 2.1.1. Defina um valor para `outputDir` no arquivo de configuração + +O caminho que o Nextflow usa para publicar saídas é controlado pela opção `outputDir`. +Para mudar o caminho para todas as saídas, você pode definir um valor para esta opção no arquivo de configuração `nextflow.config`. + +Adicione o seguinte código ao arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Isso substituirá o caminho padrão integrado, `results/`, por `results/` mais o valor do parâmetro `batch` como subdiretório. +Você também poderia mudar a parte `results` se quisesse. + +Para uma mudança temporária, você poderia definir esta opção da linha de comando usando o parâmetro `-output-dir` no seu comando (mas então você não poderia usar o valor do parâmetro `batch`). + +#### 2.1.2. Remova a parte repetida do caminho codificado + +Ainda temos um subdiretório codificado nas opções de saída, então vamos nos livrar disso agora. + +Faça as seguintes alterações de código no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +Também poderíamos ter apenas adicionado `${params.batch}` a cada caminho em vez de modificar o padrão `outputDir`, mas isso é mais conciso. + +#### 2.1.3. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote como `outdir` a partir da linha de comando. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/outdir/`. + +??? abstract "Conteúdo do diretório" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Você pode combinar esta abordagem com definições de caminho personalizadas para construir qualquer hierarquia de diretórios que desejar. + +### 2.2. Organize saídas por processo + +Uma maneira popular de organizar ainda mais as saídas é fazer isso por processo, _ou seja_, criar subdiretórios para cada processo executado no pipeline. + +#### 2.2.1. Substitua os caminhos de saída por uma referência aos nomes dos processos + +Tudo o que você precisa fazer é referenciar o nome do processo como `<task>.name` na declaração do caminho de saída. + +Faça as seguintes alterações no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Isso remove os elementos codificados restantes da configuração do caminho de saída. + +#### 2.2.2. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote como `pnames` a partir da linha de comando. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/pnames/`, e elas estão agrupadas por processo. + +??? abstract "Conteúdo do diretório" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Note que aqui apagamos a distinção entre `intermediates` versus saídas finais estando no nível superior. +Você poderia, é claro, misturar e combinar essas abordagens, por exemplo, definindo o caminho da primeira saída como `intermediates/${sayHello.process}` + +### 2.3. Defina o modo de publicação no nível do fluxo de trabalho + +Finalmente, no espírito de reduzir a quantidade de código repetitivo, podemos substituir as declarações `mode` por saída com uma única linha na configuração. + +#### 2.3.1. Adicione `workflow.output.mode` ao arquivo de configuração + +Adicione o seguinte código ao arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Assim como a opção `outputDir`, dar a `workflow.output.mode` um valor no arquivo de configuração seria suficiente para substituir o que está definido no arquivo de fluxo de trabalho, mas vamos remover o código desnecessário de qualquer forma. + +#### 2.3.2. Remova o modo de saída do arquivo de fluxo de trabalho + +Faça as seguintes alterações no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Antes" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +Isso é mais conciso, não é? + +#### 2.3.3. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote como `outmode` a partir da linha de comando. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/outmode/`. +Todas ainda são cópias adequadas, não symlinks. + +??? abstract "Conteúdo do diretório" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +A principal razão pela qual você ainda pode querer usar a maneira por saída de definir o modo é se você quiser misturar e combinar dentro do mesmo fluxo de trabalho, _ou seja_, ter algumas saídas sendo copiadas e algumas sendo symlinkadas. + +Existem muitas outras opções que você pode personalizar dessa maneira, mas esperamos que isso lhe dê uma noção da gama de opções e como utilizá-las efetivamente para atender às suas preferências. + +### Conclusão + +Você sabe como controlar a nomenclatura e estrutura dos diretórios onde suas saídas são publicadas, bem como o modo de publicação de saída do fluxo de trabalho. + +### O que vem a seguir? + +Aprenda como adaptar a configuração do seu fluxo de trabalho ao seu ambiente de computação, começando com a tecnologia de empacotamento de software. + +--- + +## 3. Selecione uma tecnologia de empacotamento de software + +Até agora temos visto elementos de configuração que controlam como as entradas entram e onde as saídas saem. Agora é hora de focar mais especificamente em adaptar a configuração do seu fluxo de trabalho ao seu ambiente de computação. + +O primeiro passo nesse caminho é especificar de onde virão os pacotes de software que serão executados em cada etapa. +Eles já estão instalados no ambiente de computação local? +Precisamos recuperar imagens e executá-las via um sistema de contêineres? +Ou precisamos recuperar pacotes Conda e construir um ambiente Conda local? + +Na primeira parte deste curso de treinamento (Partes 1-4) apenas usamos software instalado localmente em nosso fluxo de trabalho. +Então na Parte 5, introduzimos contêineres Docker e o arquivo `nextflow.config`, que usamos para habilitar o uso de contêineres Docker. + +Agora vamos ver como podemos configurar uma opção alternativa de empacotamento de software via o arquivo `nextflow.config`. + +### 3.1. Desabilite o Docker e habilite o Conda no arquivo de configuração + +Vamos fingir que estamos trabalhando em um cluster HPC e o administrador não permite o uso do Docker por razões de segurança. +Felizmente para nós, o Nextflow suporta múltiplas outras tecnologias de contêineres, incluindo Singularity (que é mais amplamente usado em HPC), e gerenciadores de pacotes de software como Conda. + +Podemos mudar nosso arquivo de configuração para usar Conda em vez de Docker. +Para fazer isso, vamos mudar o valor de `docker.enabled` para `false`, e adicionar uma diretiva habilitando o uso do Conda: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Isso permitirá que o Nextflow crie e utilize ambientes Conda para processos que têm pacotes Conda especificados. +O que significa que agora precisamos adicionar um desses ao nosso processo `cowpy`! + +### 3.2. Especifique um pacote Conda na definição do processo + +Já recuperamos o URI para um pacote Conda contendo a ferramenta `cowpy`: `conda-forge::cowpy==1.1.5` + +Agora adicionamos o URI à definição do processo `cowpy` usando a diretiva `conda`: + +=== "Depois" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Para ser claro, não estamos _substituindo_ a diretiva `docker`, estamos _adicionando_ uma opção alternativa. + +!!! tip + + Existem algumas maneiras diferentes de obter o URI para um determinado pacote conda. + Recomendamos usar a consulta de busca [Seqera Containers](https://seqera.io/containers/), que lhe dará um URI que você pode copiar e colar, mesmo que você não esteja planejando criar um contêiner a partir dele. + +### 3.3. Execute o fluxo de trabalho para verificar que ele pode usar Conda + +Vamos experimentar. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Saída do comando" + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Isso deve funcionar sem problemas e produzir as mesmas saídas de antes em `results/conda`. + +Nos bastidores, o Nextflow recuperou os pacotes Conda e criou o ambiente, o que normalmente requer um pouco de trabalho; então é bom que não tenhamos que fazer nada disso nós mesmos! + +!!! note + + Isso executa rapidamente porque o pacote `cowpy` é bastante pequeno, mas se você estiver trabalhando com pacotes grandes, pode levar um pouco mais de tempo do que o normal na primeira vez, e você pode ver a saída do console ficar 'presa' por um minuto ou mais antes de completar. + Isso é normal e se deve ao trabalho extra que o Nextflow faz na primeira vez que você usa um novo pacote. + +Do nosso ponto de vista, parece que funciona exatamente da mesma forma que executar com Docker, embora no backend a mecânica seja um pouco diferente. + +Isso significa que estamos todos prontos para executar com ambientes Conda se necessário. + +??? info "Misturando e combinando Docker e Conda" + + Como essas diretivas são atribuídas por processo, é possível 'misturar e combinar', _ou seja_, configurar alguns dos processos em seu fluxo de trabalho para executar com Docker e outros com Conda, por exemplo, se a infraestrutura de computação que você está usando suporta ambos. + Nesse caso, você habilitaria tanto Docker quanto Conda no seu arquivo de configuração. + Se ambos estiverem disponíveis para um determinado processo, o Nextflow priorizará contêineres. + + E como observado anteriormente, o Nextflow suporta múltiplas outras tecnologias de empacotamento de software e contêineres, então você não está limitado a apenas essas duas. + +### Conclusão + +Você sabe como configurar qual pacote de software cada processo deve usar, e como alternar entre tecnologias. + +### O que vem a seguir? + +Aprenda como mudar a plataforma de execução usada pelo Nextflow para realmente fazer o trabalho. + +--- + +## 4. Selecione uma plataforma de execução + +Até agora, temos executado nosso pipeline com o executor local. +Isso executa cada tarefa na máquina em que o Nextflow está sendo executado. +Quando o Nextflow começa, ele verifica as CPUs e memória disponíveis. +Se os recursos das tarefas prontas para executar excedem os recursos disponíveis, o Nextflow manterá as últimas tarefas de volta da execução até que uma ou mais das tarefas anteriores tenham terminado, liberando os recursos necessários. + +O executor local é conveniente e eficiente, mas é limitado àquela única máquina. Para cargas de trabalho muito grandes, você pode descobrir que sua máquina local é um gargalo, seja porque você tem uma única tarefa que requer mais recursos do que você tem disponíveis, ou porque você tem tantas tarefas que esperar por uma única máquina para executá-las levaria muito tempo. + +O Nextflow suporta [muitos backends de execução diferentes](https://www.nextflow.io/docs/latest/executor.html), incluindo agendadores HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor e outros), bem como backends de execução em nuvem (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes e mais). + +### 4.1. Direcionando um backend diferente + +A escolha do executor é definida por uma diretiva de processo chamada `executor`. +Por padrão, é definido como `local`, então a seguinte configuração está implícita: + +```groovy title="Configuração integrada" +process { + executor = 'local' +} +``` + +Para definir o executor para direcionar um backend diferente, você simplesmente especificaria o executor que deseja usando sintaxe similar à descrita acima para alocações de recursos (veja a [documentação](https://www.nextflow.io/docs/latest/executor.html) para todas as opções). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning + + Não podemos realmente testar isso no ambiente de treinamento porque não está configurado para se conectar a um HPC. + +### 4.2. Lidando com sintaxe específica do backend para parâmetros de execução + +A maioria das plataformas de computação de alto desempenho permite (e às vezes exige) que você especifique certos parâmetros, como solicitações e limitações de alocação de recursos (por exemplo, número de CPUs e memória) e nome da fila de trabalhos a ser usada. + +Infelizmente, cada um desses sistemas usa tecnologias, sintaxes e configurações diferentes para definir como um trabalho deve ser definido e submetido ao agendador relevante. + +??? abstract "Exemplos" + + Por exemplo, o mesmo trabalho requerendo 8 CPUs e 4GB de RAM para ser executado na fila "my-science-work" precisa ser expresso das seguintes maneiras diferentes dependendo do backend. + + ```bash title="Config para SLURM / submeter usando sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config para PBS / submeter usando qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config para SGE / submeter usando qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Felizmente, o Nextflow simplifica tudo isso. +Ele fornece uma sintaxe padronizada para que você possa especificar as propriedades relevantes como `cpus`, `memory` e `queue` (veja a documentação para outras propriedades) apenas uma vez. +Então, no tempo de execução, o Nextflow usará essas configurações para gerar os scripts específicos do backend apropriados com base na configuração do executor. + +Vamos cobrir essa sintaxe padronizada na próxima seção. + +### Conclusão + +Você agora sabe como mudar o executor para usar diferentes tipos de infraestrutura de computação. + +### O que vem a seguir? + +Aprenda como avaliar e expressar alocações e limitações de recursos no Nextflow. + +--- + +## 5. Controle alocações de recursos de computação + +A maioria das plataformas de computação de alto desempenho permite (e às vezes exige) que você especifique certos parâmetros de alocação de recursos, como número de CPUs e memória. + +Por padrão, o Nextflow usará uma única CPU e 2GB de memória para cada processo. +As diretivas de processo correspondentes são chamadas `cpus` e `memory`, então a seguinte configuração está implícita: + +```groovy title="Configuração integrada" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Você pode modificar esses valores, seja para todos os processos ou para processos nomeados específicos, usando diretivas de processo adicionais no seu arquivo de configuração. +O Nextflow os traduzirá nas instruções apropriadas para o executor escolhido. + +Mas como você sabe quais valores usar? + +### 5.1. Execute o fluxo de trabalho para gerar um relatório de utilização de recursos + +Se você não sabe de antemão quanta CPU e memória seus processos provavelmente precisarão, você pode fazer algum perfil de recursos, o que significa que você executa o fluxo de trabalho com algumas alocações padrão, registra quanto cada processo usou e, a partir daí, estima como ajustar as alocações base. + +Convenientemente, o Nextflow inclui ferramentas integradas para fazer isso, e irá gerar alegremente um relatório para você mediante solicitação. + +Para fazer isso, adicione `-with-report <filename>.html` à sua linha de comando. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +O relatório é um arquivo html, que você pode baixar e abrir no seu navegador. Você também pode clicar com o botão direito nele no explorador de arquivos à esquerda e clicar em `Show preview` para visualizá-lo no ambiente de treinamento. + +Reserve alguns minutos para examinar o relatório e ver se você consegue identificar algumas oportunidades para ajustar recursos. +Certifique-se de clicar nas abas que mostram os resultados de utilização como uma porcentagem do que foi alocado. +Há alguma [documentação](https://www.nextflow.io/docs/latest/reports.html) descrevendo todos os recursos disponíveis. + +### 5.2. Defina alocações de recursos para todos os processos + +O perfil mostra que os processos em nosso fluxo de trabalho de treinamento são muito leves, então vamos reduzir a alocação de memória padrão para 1GB por processo. + +Adicione o seguinte ao seu arquivo `nextflow.config`, antes da seção de parâmetros do pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Isso ajudará a reduzir a quantidade de computação que consumimos. + +### 5.3. Defina alocações de recursos para um processo específico + +Ao mesmo tempo, vamos fingir que o processo `cowpy` requer mais recursos do que os outros, apenas para que possamos demonstrar como ajustar alocações para um processo individual. + +=== "Depois" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Com esta configuração, todos os processos solicitarão 1GB de memória e uma única CPU (o padrão implícito), exceto o processo `cowpy`, que solicitará 2GB e 2 CPUs. + +!!! tip + + Se você tiver uma máquina com poucas CPUs e alocar um número alto por processo, poderá ver chamadas de processo sendo enfileiradas uma atrás da outra. + Isso ocorre porque o Nextflow garante que não solicitemos mais CPUs do que as disponíveis. + +### 5.4. Execute o fluxo de trabalho com a configuração atualizada + +Vamos experimentar isso, fornecendo um nome de arquivo diferente para o relatório de perfil para que possamos comparar o desempenho antes e depois das mudanças de configuração. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Você provavelmente não notará nenhuma diferença real, pois esta é uma carga de trabalho tão pequena, mas esta é a abordagem que você usaria para analisar o desempenho e os requisitos de recursos de um fluxo de trabalho do mundo real. + +É muito útil quando seus processos têm requisitos de recursos diferentes. Ele o capacita a dimensionar corretamente as alocações de recursos que você configura para cada processo com base em dados reais, não em suposições. + +!!! tip + + Este é apenas um pequeno aperitivo do que você pode fazer para otimizar seu uso de recursos. + O próprio Nextflow tem uma [lógica de repetição dinâmica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) realmente interessante embutida para repetir trabalhos que falham devido a limitações de recursos. + Além disso, a Seqera Platform oferece ferramentas orientadas por IA para otimizar suas alocações de recursos automaticamente também. + +### 5.5. Adicione limites de recursos + +Dependendo de qual executor de computação e infraestrutura de computação você está usando, pode haver algumas restrições sobre o que você pode (ou deve) alocar. +Por exemplo, seu cluster pode exigir que você permaneça dentro de certos limites. + +Você pode usar a diretiva `resourceLimits` para definir as limitações relevantes. A sintaxe se parece com isso quando está sozinha em um bloco de processo: + +```groovy title="Exemplo de sintaxe" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +O Nextflow traduzirá esses valores nas instruções apropriadas dependendo do executor que você especificou. + +Não vamos executar isso, pois não temos acesso à infraestrutura relevante no ambiente de treinamento. +No entanto, se você tentasse executar o fluxo de trabalho com alocações de recursos que excedem esses limites, então procurasse o comando `sbatch` no arquivo de script `.command.run`, você veria que as solicitações que realmente são enviadas ao executor são limitadas aos valores especificados por `resourceLimits`. + +??? info "Configurações de referência institucionais" + + O projeto nf-core compilou uma [coleção de arquivos de configuração](https://nf-co.re/configs/) compartilhados por várias instituições ao redor do mundo, cobrindo uma ampla gama de executores HPC e nuvem. + + Essas configurações compartilhadas são valiosas tanto para pessoas que trabalham lá e, portanto, podem simplesmente utilizar a configuração de sua instituição pronta para uso, quanto como modelo para pessoas que estão procurando desenvolver uma configuração para sua própria infraestrutura. + +### Conclusão + +Você sabe como gerar um relatório de perfil para avaliar a utilização de recursos e como modificar alocações de recursos para todos os processos e/ou para processos individuais, bem como definir limitações de recursos para executar em HPC. + +### O que vem a seguir? + +Aprenda como configurar perfis de configuração predefinidos e alternar entre eles no tempo de execução. + +--- + +## 6. Use perfis para alternar entre configurações predefinidas + +Mostramos a você várias maneiras de personalizar a configuração do seu pipeline dependendo do projeto em que você está trabalhando ou do ambiente de computação que está usando. + +Você pode querer alternar entre configurações alternativas dependendo de qual infraestrutura de computação está usando. Por exemplo, você pode querer desenvolver e executar testes em pequena escala localmente no seu laptop, depois executar cargas de trabalho em escala completa em HPC ou nuvem. + +O Nextflow permite que você configure qualquer número de perfis que descrevem diferentes configurações, que você pode então selecionar no tempo de execução usando um argumento de linha de comando, em vez de ter que modificar o arquivo de configuração em si. + +### 6.1. Crie perfis para alternar entre desenvolvimento local e execução em HPC + +Vamos configurar dois perfis alternativos; um para executar cargas em pequena escala em um computador normal, onde usaremos contêineres Docker, e outro para executar em um HPC universitário com um agendador Slurm, onde usaremos pacotes Conda. + +#### 6.1.1. Configure os perfis + +Adicione o seguinte ao seu arquivo `nextflow.config`, após a seção de parâmetros do pipeline, mas antes das configurações de saída: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Você vê que para o HPC universitário, também estamos especificando limitações de recursos. + +#### 6.1.2. Execute o fluxo de trabalho com um perfil + +Para especificar um perfil na nossa linha de comando do Nextflow, usamos o argumento `-profile`. + +Vamos tentar executar o fluxo de trabalho com a configuração `my_laptop`. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Como você pode ver, isso nos permite alternar entre configurações muito convenientemente no tempo de execução. + +!!! warning + + O perfil `univ_hpc` não será executado corretamente no ambiente de treinamento, pois não temos acesso a um agendador Slurm. + +Se no futuro encontrarmos outros elementos de configuração que estão sempre co-ocorrendo com esses, podemos simplesmente adicioná-los ao(s) perfil(is) correspondente(s). +Também podemos criar perfis adicionais se houver outros elementos de configuração que queremos agrupar. + +### 6.2. Crie um perfil de parâmetros de teste + +Perfis não são apenas para configuração de infraestrutura. +Também podemos usá-los para definir valores padrão para parâmetros de fluxo de trabalho, para facilitar que outros experimentem o fluxo de trabalho sem ter que reunir valores de entrada apropriados por conta própria. +Você pode considerar isso uma alternativa ao uso de um arquivo de parâmetros. + +#### 6.2.1. Configure o perfil + +A sintaxe para expressar valores padrão neste contexto se parece com isso, para um perfil que nomeamos `test`: + +```groovy title="Exemplo de sintaxe" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Se adicionarmos um perfil de teste para nosso fluxo de trabalho, o bloco `profiles` se torna: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Assim como para perfis de configuração técnica, você pode configurar vários perfis diferentes especificando parâmetros sob qualquer diff --git a/docs/pt/docs/hello_nextflow/index.md b/docs/pt/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..422a973175 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Iniciar e gerenciar a execução de fluxos de trabalho Nextflow + - Encontrar e interpretar saídas (resultados) e arquivos de log gerados pelo Nextflow + - Solucionar problemas básicos + - Construir um fluxo de trabalho simples de múltiplas etapas a partir de componentes principais do Nextflow + - Distinguir entre tipos essenciais de fábricas de canais e operadores e utilizá-los efetivamente em um fluxo de trabalho simples + - Configurar a execução de pipelines para rodar em plataformas de computação comuns, incluindo HPC e nuvem + - Aplicar boas práticas para reprodutibilidade, portabilidade e reutilização de código que tornam pipelines FAIR, incluindo modularidade de código e contêineres de software + audience_prerequisites: + - "**Público:** Este curso é destinado a pessoas que são completamente novas no Nextflow e desejam desenvolver seus próprios pipelines." + - "**Habilidades:** Presume-se alguma familiaridade com a linha de comando, conceitos básicos de script e formatos de arquivo comuns." + - "**Domínio:** Os exercícios são todos agnósticos de domínio, portanto não é necessário conhecimento científico prévio." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow é uma introdução prática à construção de fluxos de trabalho de análise de dados reproduzíveis e escaláveis.** + +Trabalhando através de exemplos práticos e exercícios guiados, você aprenderá os fundamentos do desenvolvimento de pipelines com Nextflow, incluindo como definir processos, conectá-los em pipelines, gerenciar arquivos e dependências de software, paralelizar a execução sem esforço e executar fluxos de trabalho em diferentes ambientes computacionais. + +Você sairá com as habilidades e a confiança para começar a desenvolver e executar seus próprios fluxos de trabalho com Nextflow. + +<!-- additional_information --> + +## Visão geral do curso + +Este curso é projetado para ser prático, com exercícios orientados a objetivos estruturados para introduzir informações gradualmente. + +Você desenvolverá um pipeline simples do Nextflow que recebe algumas entradas de texto, executa algumas etapas de transformação e gera um único arquivo de texto contendo uma figura ASCII de um personagem dizendo o texto transformado. + +### Plano de aula + +Para evitar sobrecarregá-lo com conceitos e código, dividimos isso em seis partes que focarão em aspectos específicos do desenvolvimento de pipelines com Nextflow. + +| Capítulo do curso | Resumo | Duração estimada | +| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------- | +| [Parte 1: Hello World](./01_hello_world.md) | Componentes básicos e princípios envolvidos na montagem e execução de um fluxo de trabalho Nextflow | 30 mins | +| [Parte 2: Hello Channels](./02_hello_channels.md) | Usando canais e operadores para processar entradas e paralelizar a execução sem esforço | 45 mins | +| [Parte 3: Hello Workflow](./03_hello_workflow.md) | Usando canais para encadear múltiplas etapas juntas e lidar com a transferência de dados entre etapas | 60 mins | +| [Parte 4: Hello Modules](./04_hello_modules.md) | Aplicando princípios de modularidade de código para aumentar a reutilização e diminuir a carga de manutenção | 20 mins | +| [Parte 5: Hello Containers](./05_hello_containers.md)| Usando contêineres como um mecanismo para gerenciar dependências de software e aumentar a reprodutibilidade | 60 mins | +| [Parte 6: Hello Config](./06_hello_config.md) | Personalizando o comportamento do pipeline e otimizando o uso em diferentes ambientes computacionais | 60 mins | + +Ao final deste curso, você estará bem preparado para enfrentar os próximos passos em sua jornada para desenvolver fluxos de trabalho reproduzíveis para suas necessidades de computação científica. + +Pronto para fazer o curso? + +[Começar :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/pt/docs/hello_nextflow/next_steps.md b/docs/pt/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..5ce03f6e08 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Resumo do curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns por concluir o curso de treinamento Hello Nextflow! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Veja a [playlist completa no canal do YouTube do Nextflow](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik). + +:green_book: Você pode ler a [transcrição do vídeo](./transcripts/07_next_steps.md) junto com o vídeo. +/// + +## Sua jornada + +Você começou com um fluxo de trabalho muito básico que executava um comando hardcoded. +Ao longo de seis partes, você transformou esse fluxo de trabalho básico em um pipeline modular de múltiplas etapas que exercita recursos-chave do Nextflow, incluindo canais, operadores, suporte integrado para contêineres e opções de configuração. + +### O que você construiu + +- A forma final do fluxo de trabalho Hello recebe como entrada um arquivo CSV contendo saudações em texto. +- As quatro etapas são implementadas como processos Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) armazenados em arquivos de módulo separados. +- Os resultados são publicados em um diretório chamado `results/`. +- A saída final do pipeline é um arquivo de texto simples contendo arte ASCII de um personagem dizendo as saudações em maiúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Escreve cada saudação em seu próprio arquivo de saída (_ex._ "Hello-output.txt") +2. **`convertToUpper`:** Converte cada saudação para maiúsculas (_ex._ "HELLO") +3. **`collectGreetings`:** Coleta todas as saudações em maiúsculas em um único arquivo em lote +4. **`cowpy`:** Gera arte ASCII usando a ferramenta `cowpy` + +A configuração do fluxo de trabalho suporta fornecer entradas e parâmetros de forma flexível e reproduzível. + +### Habilidades adquiridas + +Através deste curso prático, você aprendeu como: + +- Descrever e utilizar componentes principais do Nextflow suficientes para construir um fluxo de trabalho simples de múltiplas etapas +- Descrever conceitos de próximo nível, como operadores e fábricas de canais +- Lançar um fluxo de trabalho Nextflow localmente +- Encontrar e interpretar saídas (resultados) e arquivos de log gerados pelo Nextflow +- Solucionar problemas básicos + +Você está agora equipado com o conhecimento fundamental para começar a desenvolver seus próprios pipelines no Nextflow. + +## Próximos passos para desenvolver suas habilidades + +Aqui estão nossas 3 principais sugestões do que fazer em seguida: + +- Aplique Nextflow a um caso de uso de análise científica com [Nextflow for Science](../nf4_science/index.md) +- Comece com nf-core através do [Hello nf-core](../../hello_nf-core/index.md) +- Explore recursos mais avançados do Nextflow com as [Side Quests](../side_quests/index.md) + +Finalmente, recomendamos que você dê uma olhada no [**Seqera Platform**](https://seqera.io/), uma plataforma baseada em nuvem desenvolvida pelos criadores do Nextflow que torna ainda mais fácil lançar e gerenciar seus fluxos de trabalho, bem como gerenciar seus dados e executar análises interativamente em qualquer ambiente. + +## Pesquisa de feedback + +Antes de prosseguir, por favor reserve um minuto para completar a pesquisa do curso! Seu feedback nos ajuda a melhorar nossos materiais de treinamento para todos. + +[Responder a pesquisa :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pt/docs/hello_nextflow/survey.md b/docs/pt/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..ddbe8ab5d2 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Pesquisa de feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de prosseguir, por favor complete esta breve pesquisa de 5 perguntas para avaliar o treinamento, compartilhar qualquer feedback que você possa ter sobre sua experiência e nos informar o que mais poderíamos fazer para ajudá-lo em sua jornada com Nextflow. + +Isso deve levar menos de um minuto para completar. Obrigado por nos ajudar a melhorar nossos materiais de treinamento para todos! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pt/docs/hello_nextflow/transcripts/00_orientation.md b/docs/pt/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..eae0b7cbdf --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Orientação - Transcrição do Vídeo + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Nota importante" + + Esta página mostra apenas a transcrição. Para instruções passo a passo completas, retorne ao [material do curso](../00_orientation.md). + +## Boas-vindas + +Olá, bem-vindo ao Hello Nextflow. Meu nome é Phil Ewels. Sou Gerente de Produto para Open Source na Seqera, e estou muito feliz em estar aqui hoje para guiá-lo por este primeiro curso de treinamento em Nextflow. + +Vamos passar pelos fundamentos do Nextflow, explicando como escrever e executar pipelines e configurá-los. + +E você vai construir seu próprio pipeline simples de múltiplas etapas. Vamos cobrir terminologia como operadores e fábricas de canais, e ao final do curso, você estará pronto para começar a construir seus próprios pipelines de bioinformática. + +Se você tiver alguma dúvida, entre em contato em community.seqera.io. Temos uma comunidade Nextflow muito ativa, há uma seção dedicada ao treinamento, então apenas nos avise onde você está com dificuldades e alguém poderá ajudar. + +Certo. Vamos começar. + +## Site de Treinamento + +Todo o material de treinamento para os cursos de Nextflow está em training.nextflow.io. Você pode acessá-lo no seu navegador. Então abra isso agora e podemos dar uma olhada. + +Estarei executando isso com a versão 2.1.1. Fazemos pequenas atualizações e correções aqui e ali, então não se preocupe se estiver um pouco diferente, mas se o material tiver mudado muito, você sempre pode usar este seletor de versão no topo para escolher a versão exata dos materiais que vou estar abordando. + +Se você prefere o modo claro, pode alterar o tema do site aqui. + +Veja as traduções aqui, embora no momento da gravação, realmente só o inglês cobre este novo material. + +E também veja todo o código-fonte do site de treinamento e tudo com o que trabalharemos no GitHub. + +A página inicial aqui lista todos os diferentes cursos de material de treinamento que temos. Então eu rolo para baixo, veremos Nextflow para iniciantes com o curso Hello Nextflow que faremos aqui. Você pode ver todos os outros cursos que também temos, que funcionam de maneira similar. + +## Configuração do Ambiente + +Na verdade, vou começar usando este primeiro aqui no topo, que é comum para todos os cursos de treinamento, e é especificamente sobre configurar nosso ambiente. + +Eu clico, me leva a esta seção, e podemos ver instruções para desenvolver localmente. Se você quiser usar seu próprio laptop com sua própria cópia do VS Code e suas próprias instalações de software, ou o que esperamos que a maioria das pessoas faça, que é usar algo chamado GitHub Codespaces. + +Codespaces é um serviço fornecido pelo GitHub onde eles executam um servidor web na nuvem, ao qual você pode se conectar. Esse servidor tem o VS Code instalado, onde você pode executá-lo no seu navegador, ou se preferir, conectá-lo à sua instalação local do VS Code. Toda a computação, todos os arquivos, toda a edição acontecem remotamente, o que significa que todo o software que você precisa vem pré-instalado e é o mesmo para todos. + +## Criando um GitHub Codespace + +Para criar o codespace com tudo que precisamos, procure pelos botões no material da documentação, que dizem "Abrir no GitHub Codespaces". Vou clicar nisso agora, abrir em uma nova aba. E me é apresentada esta página web. Agora você pode ver que está pré-configurado para definir com nextflow-io training. + +Posso apenas clicar em criar novo codespace. Mas na verdade recomendamos que usemos uma máquina um pouco maior para o treinamento Nextflow com quatro CPUs em vez de duas. Você pode alterar qual versão do material ele usa. Então isso está padronizado para 2.1.1 porque essa é a versão dos documentos de onde segui o link. Mas eu também poderia defini-lo para um branch específico do repositório se eu quiser. + +Agora vou clicar em criar codespace. E ele vai começar a configurar o ambiente para mim. + +## Criação do Codespace + +Agora, a primeira vez que você fizer isso, vai levar bastante tempo, então agora é um bom momento para ir tomar uma xícara de chá. Fique confortável, converse com a pessoa ao seu lado. + +Se você estiver interessado, pode clicar em building codespace aqui embaixo para ver os logs da configuração. E você pode ver aqui que está baixando uma imagem Docker com tudo que preciso e configurando o ambiente. + +Agora, você só tem que esperar assim na primeira vez que criar um codespace. Se você for para github.com/codespaces aqui, verá todos os diferentes Codespaces que você tem abertos. Aqui está o que acabei de criar. Na próxima vez que fizer isso, você pode vir aqui e pode selecionar o codespace anterior e simplesmente voltar direto para ele. E é um processo muito, muito mais rápido para reativar aquele ambiente existente. Isso também manterá todas as alterações que você fez no VS Code e nos arquivos, então você não perderá seu progresso se sair e voltar. + +Você pode clicar nos três pontos aqui para realizar outras ações. Por exemplo, se você o configurou com duas CPUs e agora quer quatro, pode alterar o tipo de máquina. Ou se você quiser começar do zero e fresco, pode deletar o codespace. + +## Introdução ao VS Code + +Ok, Codespaces terminou de configurar meu ambiente e agora me é apresentado o VS Code no navegador. + +Se você está acostumado com o VS Code. Isso vai parecer muito familiar se você não o usou antes, é bastante simples. Há algumas partes diferentes da página que você precisa conhecer. + +Aqui à esquerda, temos a barra lateral. Você pode ver o Explorer configurado com todos os diferentes arquivos no repositório GitHub do repositório de treinamento. + +Nestes botões na parte esquerda, podem estar diferentes ferramentas. Na barra lateral. Posso pesquisar todos os arquivos em todo o projeto. Posso trabalhar com Git, posso trabalhar com GitHub, todos os diferentes tipos de coisas assim. + +No topo aqui está o menu principal. O explorador de arquivos é o que teremos aberto na maioria das vezes aqui, e você pode clicar com o botão direito em qualquer um desses arquivos e fazer as coisas normais que você esperaria. Você pode precisar clicar através de alguns avisos como este onde ele como cortar copiar e você pode baixar para sua máquina local também. + +Quando o codespace carrega, ele nos dá uma prévia do arquivo markdown nesta área principal aqui. Este é exatamente o mesmo que o que renderiza em github.com. Posso fechar isso e se eu clicar duas vezes naquele arquivo Readme, você verá que ele abre como código no editor de código e assim como com qualquer outro arquivo, podemos editar este código diretamente. + +Finalmente, na parte inferior aqui, temos a janela do terminal. Eu estava olhando os logs enquanto ele construía, então isso é o que a coisa atual está mostrando. Também posso pressionar este botão de mais para iniciar uma nova sessão de terminal. Isso não está rodando na minha máquina. Lembre-se, isso está rodando na nuvem, e se eu fizer tree três até profundidade de dois, você verá todos os mesmos arquivos aqui, que estavam à esquerda. + +## Mostrando apenas os arquivos "hello-nextflow" + +Este repositório GitHub contém todos os diferentes conjuntos de treinamento, não apenas o que estamos fazendo. Então, se você quiser, pode focar apenas na pasta Hello Nextflow. Uma maneira de limpar isso um pouco é ir ao menu arquivo e então adicionar pasta ao workspace. + +Clicamos nisso vamos para training. Hello nextflow, e clicamos em adicionar. Vai atualizar sua tela. E então no Explorer, agora temos dois workspaces diferentes, o que tínhamos antes para training e um com apenas Hello Nextflow. + +Se você quiser, pode clicar com o botão direito em training e clicar em remover pasta do workspace para se livrar completamente dela da barra lateral. + +Agora temos apenas os arquivos para este curso de treinamento específico na lateral. Posso esconder aquele aviso e agora posso fazer a mesma coisa no terminal aqui e fazer CD para mudar de diretório. Hello, Nextflow. E novamente, temos os mesmos arquivos aqui, que estão na barra lateral. + +## Hello Nextflow: arquivos + +Olhando esses arquivos para o curso Hello Nextflow. + +Temos um monte de arquivos .nf, que são para Nextflow, e há um desses arquivos para cada um dos capítulos do curso de treinamento. Trabalharemos através desses arquivos e os modificaremos nos exercícios. + +Também temos um arquivo nextflow.config, que apenas tem configurações básicas de config para executar Nextflow neste ambiente, com as quais você realmente não precisa se preocupar neste ponto. Um arquivo greetings.csv, que usaremos para processar dados, que será introduzido na próxima parte deste curso, e um arquivo test-params.json, que será usado na parte seis e você pode ignorar por enquanto. + +Esses arquivos Nextflow são apenas o início de cada exercício. Se você quiser ver como eles devem ficar quando terminados, você pode ir para um diretório solutions e lá estão as respostas para cada parte do curso de treinamento, então você pode ver uma versão funcional do que você está almejando. + +## Abrindo um terminal + +Se a qualquer momento você fechar o terminal e não conseguir lembrar como voltar, não se preocupe com isso. Estes botões no topo, à direita, abrem e fecham diferentes painéis no workspace. Então clique neste para o painel inferior e ele reaparecerá. E apenas certifique-se de que você tem terminal selecionado aqui. Você também pode clicar neste botão aqui, a seta no lado direito de um terminal para deixá-lo em tela cheia. + +Você me verá fazendo isso bastante porque tenho o VS Code ampliado para que você possa ler o texto. Dependendo do tamanho da sua tela, você pode ou não precisar fazer isso. O mesmo vale para minimizar o painel lateral. + +Certo. Isso é suficiente para o ambiente. Acho que estamos prontos para começar. Junte-se a mim de volta no próximo vídeo para o capítulo um. + +[Próxima transcrição de vídeo :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/pt/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..b0f4821aaa --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Parte 1: Olá Mundo - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções passo a passo completas, retorne ao [material do curso](../01_hello_world.md). + + Os números das seções mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção dos materiais. + +## Boas-vindas + +Olá, bem-vindo ao Capítulo Um de Olá Nextflow. + +Nesta primeira parte de um curso de seis partes, vamos entrar nos conceitos mais básicos do Nextflow. Vamos começar executando alguns comandos em um terminal e então vamos pegar esses comandos Bash e ver como transformá-los em um script Nextflow. + +Vamos tentar executar esse primeiro pipeline Nextflow, ver o que o Nextflow faz, onde ele executa, quais arquivos ele cria e qual é o propósito desses arquivos. + +Tudo bem, vamos começar. + +## training.nextflow.io + +Primeiro de tudo, vá para training.nextflow.io. Assim como antes, todo o material está escrito aqui, e vou trabalhar através dele passo a passo. Vou mostrar minha tela enquanto faço as etapas do treinamento, mas tudo o que estou dizendo está no material de treinamento, então você pode seguir no seu próprio ritmo, e pode encontrar tudo escrito lá. + +Este vídeo também tem legendas habilitadas, então sinta-se à vontade para ativá-las e acompanhar exatamente o que estou dizendo enquanto falo. + +Ok, vamos para Olá Nextflow. Esse é o curso que vamos fazer hoje, e já fizemos a orientação no primeiro vídeo, então vamos direto para a parte um: Olá Mundo. + +Ok, vou sair deste material de treinamento agora e entrar no meu ambiente Codespaces. Isso é o que configuramos no primeiro vídeo. Espero que você tenha algo muito similar a isso em seu próprio sistema. Estou usando VS Code e estou olhando o material de treinamento e mudei de diretório para o diretório hello Nextflow. + +## 0. Aquecimento: Execute Olá Mundo diretamente + +Ok. Vamos começar com alguns conceitos básicos, que esperançosamente serão familiares para todos. Vou começar apenas escrevendo um comando muito básico no terminal. Aqui embaixo vou dizer 'echo Hello World!"' pressiono enter e, sem surpresas, o terminal faz o que peço e retorna aquela string. Hello world. + +Ok, então vou pressionar para cima para obter aquele comando e editá-lo um pouco mais. Vamos desta vez redirecionar aquela saída para um arquivo. Vou escrevê-la em vez disso para output.txt e pressionar enter, nada no terminal desta vez porque a saída não veio para o terminal. Ela foi para aquele arquivo. + +Posso então ler aquele arquivo fazendo 'cat output.txt' pressiono tab aqui para expandir automaticamente o nome do arquivo e pronto. O arquivo está lá. + +Também posso ver aquele arquivo na barra lateral no explorador de arquivos no VS Code. Posso clicar duas vezes nele e abri-lo aqui. Se você quiser abri-lo no VS Code sem clicar em nada, também pode fazer "code" e então "output.txt" e faz a mesma coisa. + +Ótimo. Esse é o primeiro passo. Muito simples. + +## 1. Examine o script inicial do fluxo de trabalho Olá Mundo + +Ok. Agora vamos fazer exatamente a mesma coisa, mas no Nextflow, em vez de diretamente no terminal. + +Vamos usar o primeiro script de exemplo para começar, este arquivo é chamado Hello World. Posso fazer "ls" para visualizá-lo em um terminal, e estou no Mac, então posso fazer command click para abrir aquele arquivo, ou poderia ter apenas clicado duas vezes na barra lateral aqui. + +Há algumas coisas que podemos ver neste arquivo. Logo no topo, há uma declaração com hash dizendo que este é um arquivo Nextflow e é assim que pode ser executado. Há alguns comentários aqui, apenas comentários regulares de código em cinza claro, que não afetam a execução e apenas nos ajudam a ler o script. + +E então há duas estruturas principais. Há um processo aqui e um fluxo de trabalho. + +Processos no Nextflow são as etapas do pipeline. São as partes que realmente fazem a lógica e fazem o processamento. + +O fluxo de trabalho então na parte inferior conecta esses processos juntos e governa a lógica do fluxo de trabalho, como tudo se conecta um ao outro. + +Vamos começar olhando um processo. Voltaremos ao fluxo de trabalho em um momento. + +## 1.2 A definição do processo + +Então todo processo começa com uma palavra-chave process. Tem um nome e então tem algumas chaves e tudo dentro dessas chaves é aquele único processo. + +Um processo deve ter uma seção script, e contida aqui está um trecho bash em uma string de múltiplas linhas, que é a parte do código que é realmente executada no ambiente de computação. + +Também temos uma declaração de saída aqui, que diz ao Nextflow quais arquivos são esperados serem criados pelo script. Note que a saída aqui tem uma palavra-chave path, que diz ao Nextflow que isso é um arquivo, não um valor ou uma string. + +Dentro do bloco script, isso é apenas uma declaração bash regular, e é exatamente a mesma que escrevemos no terminal. Estamos ecoando hello world para um arquivo chamado output.txt. Este output.txt é então capturado pela definição de saída. A definição de saída não está realmente fazendo nada. Está apenas dizendo ao Nextflow o que esperar, e se este arquivo não fosse criado, o Nextflow lançaria um erro. + +Note que este exemplo não é muito bom porque codificamos fixamente o nome do arquivo aqui, output.txt e output.txt. Se qualquer um destes fosse alterado, isso causaria um erro em nosso fluxo de trabalho. + +Há uma maneira melhor de fazer isso com variáveis, que vamos cobrir em um minuto. + +## 1.3 A definição do fluxo de trabalho + +Ok. Descendo para o fluxo de trabalho, podemos ver que temos um comentário e então executamos o processo chamado sayHello. Esta é a mesma palavra-chave que está aqui em cima. Isso é tão simples quanto um fluxo de trabalho pode ser. Estamos apenas chamando um único processo sem entrada variável, então não estamos conectando-o a mais nada. Na parte posterior deste curso, vamos falar sobre como tornar isso mais poderoso usando entradas variáveis e conectando coisas com canais. + +## 2. Execute o fluxo de trabalho + +Ok, isso é tudo que precisamos. Vamos ver se podemos executá-lo e ver o que acontece. Vou apenas limpar o terminal e então vou fazer "nextflow run", e vou chamar o nome do arquivo, que é hello-world.nf. Isso é tudo que precisamos para executar um pipeline Nextflow. Este pipeline não recebe nenhuma entrada, então não precisamos de nenhum outro argumento. + +Vamos pressionar enter e ver o que acontece. + +Ok. Esperançosamente você deve ter alguma saída que se parece com isso. Temos alguns pedaços de informação nos dizendo que o Nextflow executou e qual versão estava usando. Nos diz qual script foi lançado e nos dá um nome gerado aleatoriamente para esta execução particular do fluxo de trabalho. Neste caso, o meu foi chamado "gloomy_crick". + +A parte mais importante disso, porém, é que nos diz quais etapas executaram no pipeline. Você pode ver que nosso processo chamado sayHello executou, e executou uma vez e estava cem por cento completo. + +Esta parte aqui é o hash para aquela tarefa particular do fluxo de trabalho. Cada processo executa uma ou mais vezes, e cada uma dessas execuções é chamada de tarefa. + +## 2.2. Encontre a saída e os logs no diretório work + +Cada tarefa obtém seu próprio diretório isolado onde executa, então está separada do resto da execução do fluxo de trabalho. Este hash corresponde à estrutura de arquivos dentro do diretório work. Se eu fizer "tree work", podemos ver a0, e então uma versão mais longa de um hash curto, e então nosso arquivo output.txt. Você também pode vê-lo na barra lateral. + +Você pode ver na barra lateral que há alguns arquivos adicionais aqui. A razão pela qual estes não apareceram no terminal é porque são arquivos ocultos, eles começam com um ponto. E de fato, se eu fizer "tree -a" para todos, e "work", podemos vê-los aqui. + +Estes arquivos com ponto estão presentes em cada único diretório work que o Nextflow cria, e cada um tem uma tarefa ligeiramente diferente. Primeiro .command.begin apenas inclui algumas instruções para o Nextflow que configura a tarefa antes de executar. .command.run são as instruções reais executadas pelo próprio Nextflow. Então .command.sh é provavelmente o mais interessante. Este é o script que foi resolvido do nosso bloco script do processo. + +Se eu abri-lo, você pode ver que temos nosso "echo Hello World" para o arquivo output.txt. Isso é exatamente o mesmo que nosso processo neste caso, mas se tivermos quaisquer variáveis dentro do nosso código Nextflow, cada tarefa terá um .command.sh diferente, e você pode ver como essas variáveis foram resolvidas. + +Os outros arquivos são sobre como a tarefa executou. Então .command.err, .log e .out são o erro padrão, saída padrão e os dois combinados. E .exitcode diz ao Nextflow como esta tarefa executou com qual código de saída, se foi bem-sucedida ou não. + +Finalmente, temos nosso arquivo output.txt e com certeza, "Hello World" isso é o que estávamos esperando e isso é o que foi criado. + +Ok, ótimo. Essa foi sua primeira execução Nextflow. Parabéns. É realmente tão simples assim. + +A seguir, vamos ver como fazer isso de uma maneira um pouco mais conveniente para que não tenhamos que editar o código toda vez que quisermos fazer uma mudança em como o pipeline executa. + +## 3. Gerencie as execuções do fluxo de trabalho + +Esta estrutura de diretório é ótima para manter todas as tarefas separadas e tudo organizado, mas claro, não é muito conveniente para encontrar seus arquivos de saída. Você não quer estar cavando através de muitos diretórios aninhados tentando encontrar os resultados do seu pipeline. + +## 3.1. Publique saídas + +A boa notícia é que você não deveria. Os diretórios work são realmente apenas para o próprio Nextflow usar. Então o que vamos fazer é usar uma função do Nextflow chamada "publishDir". + +Voltamos ao nosso fluxo de trabalho, vamos ao processo. Podemos adicionar uma nova declaração aqui chamada diretiva. Isso é o que o Nextflow chama essas coisas no topo dos processos que aumentam como a funcionalidade funciona, e a que vamos usar é chamada publishDir. + +Você pode ver que comecei a digitar aqui e a extensão Nextflow para VS Code sugeriu a diretiva para mim, então posso apenas pressionar enter. + +Ok. Vou seguir isso com um diretório chamado "results" e vamos dizer para copiar os arquivos de saída lá. Então vou dizer mode copy. Ótimo. Vou salvar e vamos executar o fluxo de trabalho novamente. + +nextflow run hello-world.nf + +Executa exatamente da mesma forma. Embora note que temos um hash ligeiramente diferente desta vez. O Nextflow usará um hash diferente toda vez que você executar o fluxo de trabalho. E temos um conjunto diferente de diretórios work como resultado. Áreas, um chamado EB em vez disso, mas você pode ver que todos os arquivos são os mesmos. No entanto, o que é novo desta vez é que também temos um diretório chamado "results". + +Dentro de "results" aqui temos nosso arquivo de saída. Isso é o que dissemos ao Nextflow para fazer. Dissemos, salve os arquivos de resultados em um diretório chamado "results" e copie-os lá. E então isso agora é muito mais fácil de encontrar. Está apenas lá ao lado de onde lançamos o fluxo de trabalho e todos os diferentes arquivos podem ser organizados lá como quisermos, independentemente de onde ou como o Nextflow executou a execução real. + +Note que publishDir pode lidar com links simbólicos, o que é bom se você está trabalhando em um sistema de arquivos compartilhado e quer economizar espaço. E também você não tem que definir todos os arquivos que são criados por um processo como uma saída. + +O Nextflow só copiará as coisas que estão definidas neste bloco output. Então, se você tem arquivos intermediários criados pela etapa, que não são necessários a jusante deste processo, você simplesmente não os define na saída e eles não aparecerão no publishDir. Então esta é uma maneira de manter seus arquivos de saída de um pipeline limpos e facilmente deletar arquivos intermediários uma vez que o local de trabalho tenha terminado. + +Uma nota rápida aqui. Há uma nova sintaxe Nextflow chegando chamada definições de saída de fluxo de trabalho, que eventualmente substituirá publishDir. Isso nos dá uma maneira de definir todas as saídas de um fluxo de trabalho em nível de pipeline no bloco workflow. Isso é descrito na documentação do Nextflow se você quiser experimentar. Mas por enquanto, publishDir ainda estará por aí por um tempo, então ainda temos isso no treinamento para 2025. + +## 3.2. Relance um fluxo de trabalho com -resume + +Ok. Mencionei que o diretório work aqui agora tem dois conjuntos de resultados com um hash diferente de cada vez que executamos o fluxo de trabalho. Isso é bom. No entanto, às vezes não queremos recomputar etapas toda vez se não precisarmos. + +Talvez você esteja construindo iterativamente seu fluxo de trabalho e esteja adicionando etapas e queira que as primeiras etapas apenas reutilizem as versões em cache. Ou talvez algo deu errado em seu sistema de computação no meio do seu fluxo de trabalho e você quer que ele continue de onde parou, mas pule as etapas que já tinha completado. + +O Nextflow tem funcionalidade embutida para isso chamada resume. Vamos experimentar. Então primeiro, vou apenas dar uma olhada no diretório work para que possamos lembrar o que estava lá. + +E então vou fazer "nextflow run hello-world.nf" e vou adicionar um único comando aqui, "-resume". + +Note, um único traço, isso é realmente importante. Vou executá-lo e a saída vai parecer basicamente exatamente a mesma, com algumas pequenas diferenças. + +Note aqui que diz "cached" em cinza. Isso significa que o Nextflow não executou a tarefa. Desta vez ele encontrou algo que correspondia ao que eram requisitos e reutilizou essas saídas diretamente em vez de reexecutar a etapa. + +E com certeza, se você olhar o hash aqui, você pode ver que isso corresponde ao hash existente que tínhamos de uma execução anterior. + +## 3.3. Delete diretórios work mais antigos + +Ok. Mas se você está desenvolvendo iterativamente, vai acumular muitos desses arquivos de fluxo de trabalho. Isso pode ser um problema se você pode estar com pouco espaço. + +O Nextflow pode nos ajudar a limpar esses diretórios work com alguns comandos auxiliares. Se eu fizer "nextflow log". Isso me dará uma lista de todas as diferentes execuções de fluxo de trabalho que fiz neste diretório, e elas têm os nomes de execução aqui. Você pode ver o gloomy quick, que foi o primeiro que executamos, e então esses dois novos. + +Agora podemos pegar esse nome e usá-los com o comando "nextflow clean". Posso especificar um único nome de execução. Ou ainda melhor, posso dizer ao Nextflow para deletar tudo de antes de um único nome de fluxo de trabalho com "-before", e vou colocar "stupefied_shaw". Essa foi minha execução mais recente, "-n". + +O comando "-n" disse ao Nextflow para fazer isso como uma execução de teste sem realmente deletar nada de verdade, e nos diz quais dos diretórios hash teriam sido removidos. Com certeza, é apenas aquele da primeira execução. Ambas as segundas execuções usam o mesmo diretório hash. + +Vou executá-lo novamente, mas agora em vez de "-n" para execução de teste, vou fazer "-f" para forçar e ele removeu aquele diretório hash. Agora se eu fizer "tree work", podemos ver, temos apenas este arquivo de saída restante. + +Ótimo. Então conseguimos limpar um monte de espaço em disco ali. + +Algumas coisas a notar ao deletar diretórios work, se você fizer links simbólicos para seu diretório de resultados, essas fontes de links simbólicos agora serão deletadas e seus resultados se perderão para sempre. Então é por isso que usar o modo copy é uma coisa mais segura de fazer, e geralmente o que recomendamos. + +Em segundo lugar, a funcionalidade resume do Nextflow depende desses diretórios work. Então, se você deletá-los e executar o Nextflow novamente, a funcionalidade resume não funcionará mais. Então cabe a você acompanhar quais coisas você pode precisar ou não precisar, e apenas deletar coisas quando você tem certeza de que é seguro fazê-lo. + +A outra coisa que podemos fazer é apenas deletar o diretório work inteiro se terminarmos nossa execução de fluxo de trabalho e tivermos certeza de que não precisamos mais dele. + +Então posso fazer "rm -r work". Eu sei que não havia nada importante lá. Tenho meus resultados com os quais me importo no diretório de resultados onde os copiamos. E então foi seguro deletar o diretório work. Cabe a você qual dessas abordagens usar. + +## 4. Use uma entrada variável passada na linha de comando + +Ok, qual é o próximo passo? Mencionei que tínhamos codificado fixamente alguns dos valores em nosso script de fluxo de trabalho aqui, o arquivo output.txt, e que pode haver uma maneira melhor de fazer isso. + +Vamos começar com isso. O que vamos fazer são três coisas. Vamos adicionar uma nova entrada ao processo. Vamos dizer ao script do processo como usar essa entrada, e então vamos conectá-la no fluxo de trabalho para que possamos usá-la dinamicamente com uma flag de linha de comando ao executar o Nextflow. + +Então, primeiro de tudo. Vamos adicionar um bloco input aqui. Assim como output. Esta é uma nova seção para o processo, e vou dizer, "val greeting". + +Note aqui, estou dizendo "val", que diz que isso é uma variável, não um path. + +Posso então descer no script e então posso tirar este texto codificado fixamente aqui e fazer $greeting. Isso funciona como qualquer outra linguagem de programação. Estamos definindo uma variável aqui e estamos referenciando-a dentro deste bloco script. Quando o Nextflow executa este processo, a variável será interpolada. E quando formos olhar aquele arquivo .command.sh, veremos a string codificada fixamente real aqui em vez disso. + +## 4.1.3. Configure um parâmetro CLI e forneça-o como entrada para a chamada do processo + +Ok, mas onde fornecemos a variável? A seguir descemos para a seção workflow, e você pode ver que a extensão aqui está dizendo, agora esperamos uma entrada, e me deu um aviso. + +Agora, a coisa mais simples que poderíamos fazer é apenas codificá-la fixamente. Eu poderia escrever "Hello World" e fornecer aquela entrada de string para o processo. Mas novamente, isso realmente não resolveria nenhum problema. Ainda teríamos que voltar e editar o código do pipeline toda vez que quiséssemos mudar algo, o que não é bom. + +A boa notícia é que o Nextflow tem um sistema embutido para lidar com argumentos de linha de comando chamado parâmetros. Então, em vez disso, posso usar uma dessas variáveis especiais chamada params e posso chamá-la do que eu quiser, mas vou dizer greeting para que corresponda à lógica do fluxo de trabalho. + +Salvar e vamos ver o que podemos fazer com isso. + +Então, se eu voltar ao terminal. Então fazemos "nextflow run hello-world.nf". Assim como antes, mas a diferença chave é que fazemos --greeting + +Note, há dois traços aqui porque este é um parâmetro. Quando retomamos o fluxo de trabalho antes, era um único traço. Isso é porque resume é uma opção central do Nextflow, e este é um parâmetro que é específico para nosso pipeline. + +Não misture os dois. É fácil fazer isso. Se você fizesse --resume em vez de apenas um traço, então isso seria "params.resume", que não faria nada. Da mesma forma, se você fizesse um único traço aqui, o Nextflow não reconheceria como um argumento chave. + +Então é --greeting, que corresponde a params.greeting. + +Agora posso seguir isso com qualquer texto que eu quiser. Então estou na Suécia no momento, então vou dizer, "Hej världen". + +Então vamos executar, ver o que acontece, momento da verdade. + +Ok, então você pode ver que o processo executou novamente, assim como antes, sayHello com uma única execução. + +Isso terá sobrescrito o arquivo que estava no diretório publishDir "results". E então tenha cuidado quando estiver reexecutando os arquivos porque coisas no publishDir serão sobrescritas. + +Agora posso fazer "code results/output.txt", e com certeza, nossa saída foi atualizada e agora diz "Hej världen". + +## 4.2. Use valores padrão para parâmetros de linha de comando + +Ok, isso é ótimo. Mas o problema agora é que nosso fluxo de trabalho depende de sempre definirmos este parâmetro, e é bom ter padrões sensatos para que as coisas executem de uma maneira sensata para seu fluxo de trabalho, a menos que você sobrescreva os padrões. + +Então a maneira que fazemos isso é definindo um valor padrão para o parâmetro em nosso script de fluxo de trabalho. + +Então, se eu voltar ao meu arquivo hello-world.nf, posso ir no script logo acima de workflow, digitar "params.greeting" e defini-lo como qualquer outra variável. Então vamos colocar uma string aqui e vamos dizer "Holà mundo!" + +Agora este parâmetro tem um padrão definido, que será usado aqui, ou ainda podemos sobrescrevê-lo na linha de comando com --greeting, assim como fizemos antes. + +Então vamos verificar se funciona. "nextflow run hello-world.nf" + +Sem argumentos de linha de comando desta vez, e verificar se fez a coisa certa. + +"code results/output.txt". E lá está. Obtivemos nosso padrão. + +Ok, vamos tentar novamente, apenas verificar que não estou contando nenhuma mentira. Vamos executar novamente, mas fazer --greeting, e usar o exemplo do material de treinamento, vamos dizer "Konnichiwa!" + +Reexecuta o fluxo de trabalho, e com certeza, nosso arquivo de saída no topo foi apenas atualizado com o novo valor que fornecemos na linha de comando. + +Ótimo. Este é um aspecto realmente central para escrever qualquer fluxo de trabalho Nextflow. Definir padrões sensatos em seu código de pipeline, mas tornar muito fácil de configurar para o usuário final tendo argumentos de linha de comando no terminal. + +Note que o usuário final pode sobrescrever a configuração em múltiplos lugares diferentes. Você pode ter um arquivo de configuração em seu diretório home, que é aplicado a cada única execução Nextflow que você faz. Você pode ter um arquivo de configuração em um diretório de lançamento. Você pode ter um arquivo de configuração em um diretório de pipeline. Todos esses diferentes locais de configuração são carregados em uma ordem específica, que é descrita na documentação do Nextflow. + +Ok, esse é o fim da seção um. Tivemos nosso primeiro script de fluxo de trabalho no Nextflow com um processo e um fluxo de trabalho. Olhamos entradas, saídas, scripts e publicação, e como conectar parâmetros e um canal de entrada em nosso processo. + +Parabéns, seu primeiro passo em direção a escrever código Nextflow está completo. + +Faça uma pequena pausa e te vejo de volta em alguns minutos para o capítulo dois. + +[Próxima transcrição de vídeo :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/pt/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..d4468f4570 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Parte 2: Hello Channels - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções passo a passo completas, retorne ao [material do curso](../02_hello_channels.md). + + Os números de seção mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção dos materiais. + +## Boas-vindas + +Olá, bem-vindo à parte dois do Hello Nextflow. + +Este capítulo é chamado Hello Channels. Vamos falar tudo sobre esta parte fundamental do Nextflow. + +Canais são as coisas que conectam as diferentes etapas do seu pipeline, a maneira como seus dados e lógica fluem através do seu fluxo de trabalho. + +Ok, vamos começar. + +Vamos começar indo para training.nextflow.io + +Hello Nextflow na barra lateral e clicando na parte dois. Hello Channels. + +Todo o material está escrito aqui, então você pode seguir no seu próprio ritmo e revisar qualquer coisa que possa ter perdido. + +Depois de abrir o site, você pode carregar o Codespaces e continuaremos de onde paramos no final do último capítulo. + +## 0. Aquecimento: Execute hello-channels.nf + +Para este capítulo, vamos editar um arquivo diferente. Este se chama Hello Channels, então você pode encontrá-lo na barra lateral, clique duas vezes para abrir. + +Agora, se você acabou de vir do capítulo um, este arquivo parecerá muito familiar. O ponto de partida aqui é basicamente onde terminamos o capítulo um, com nosso processo chamado sayHello, nossa entrada, saída, nosso publishDir e nosso params.greeting, e nosso fluxo de trabalho simples. + +Estamos começando com um novo arquivo, então é um terreno nivelado para todos, mas você pode continuar com seu arquivo anterior se preferir. + +Observe, eu também deletei todos os arquivos .nextflow\* e os diretórios work aqui, apenas para que seja um ponto de partida limpo. Não importa se você faz isso ou não, fica a seu critério. + +Ok. Vamos começar verificando se este pipeline ainda funciona como esperamos. Vou abrir o terminal aqui. + +Faço "nextflow run hello-channels.nf" e aperto enter. + +Vai executar aquele pequeno fluxo de trabalho, executa nossa etapa sayHello, gera um diretório work com aquele hash, e aqui está nossa pasta results e lá está nosso arquivo de saída, exatamente como esperávamos do nosso params.greeting padrão. + +Então isso é ótimo. Exatamente o mesmo que o capítulo um, funcionando como esperávamos. + +## 1. Forneça entradas variáveis através de um canal explicitamente + +No capítulo um, você na verdade já estava usando canais, você só não percebeu. Quando especificamos uma string aqui, o Nextflow automaticamente criou um canal em torno dessa string para nós, apenas porque sabia que estávamos chamando um processo, então precisávamos de um canal de entrada. + +A primeira coisa que vamos fazer é torná-lo explícito, escrevendo realmente o canal em si. + +## 1.1. Crie um canal de entrada + +Então vou ir para o fluxo de trabalho aqui no final do script, e vou dizer greeting_ch. Esta é uma convenção que frequentemente usamos no código Nextflow de ter um underscore ch no final de um nome de variável quando é um canal, apenas para que seja fácil identificar que é um canal, mas você não precisa fazer isso. Igual a channel of Hello Channels. + +O que acabamos de usar é algo chamado "Channel Factory" na linguagem do Nextflow. É essa coisa aqui, estamos definindo esta variável para um novo canal, e esta fábrica de canais aqui está criando um canal para nós de uma maneira particular. + +Existem um punhado de diferentes fábricas de canais que o Nextflow tem, para criar canais de diferentes tipos de entradas. Dot of é a mais simples, e apenas recebe quaisquer strings que fornecemos. + +Observe que quando passo o mouse sobre essas palavras no VS Code, a extensão Nextflow está me dando um popup explicando o que esta sintaxe faz, e também há um texto de ler mais na parte inferior dessa janela popup. + +Se eu clicar nisso, vai abrir os documentos do Nextflow. Em uma nova aba e me levar direto para a documentação deste item específico. Neste caso para channel.of. + +## 1.2. Adicione o canal como entrada para a chamada do processo + +Observe que a extensão também está nos dando um aviso, dizendo que criamos um novo canal aqui, mas ele não está sendo usado por nada. + +Então, vamos corrigir isso. Vou pegar o novo nome do canal e vou substituir este params.greeting pelo nosso novo canal. + +Observe que não estamos mais usando o sinalizador de linha de comando --greeting agora, params.greeting não está sendo usado, estamos voltando a codificar esta string diretamente. Tudo bem. Estou apenas tentando manter as coisas simples. Voltaremos mais tarde e usaremos os params novamente. + +## 1.3. Execute o comando workflow novamente + +Ok, vamos apenas verificar se isso funciona. Abra o terminal e observe novamente. Nextflow run hello channels. Verifique output.txt, e lá está. + +Ótimo, um exemplo meio chato, fazendo exatamente a mesma coisa que fizemos antes, mas agora pelo menos a lógica está um pouco mais clara. Estamos sendo explícitos sobre escrever um novo canal. + +Efetivamente acabamos de escrever mais código para fazer a mesma coisa. Mas isso começará a fazer mais sentido conforme nos tornarmos um pouco mais complicados com a forma como criamos nossos canais. + +## 2. Modifique o fluxo de trabalho para executar em múltiplos valores de entrada + +Ok, vamos tornar isso um pouco mais interessante. É muito raro que você queira executar um pipeline Nextflow em uma única entrada, então vamos dar várias entradas a ele. + +## 2.1. Carregue múltiplas saudações no canal de entrada + +Da documentação aqui. Vou copiar essas diferentes strings, três delas. Hello, Bonjour, Olà. Oh, espere. O Copilot está sugerindo algumas outras. Então vamos apertar tab e digitar essas. + +A documentação do Nextflow aqui nos diz que podemos dar múltiplos valores para este operador, então deve funcionar, mas vamos tentar e ver o que acontece. + +## 2.1.2. Execute o comando e observe a saída do log + +Bem. Sim e não. Vamos ver. Diz que cinco de cinco tarefas foram executadas aqui, mas mostra apenas um hash, o que é um pouco estranho. Tudo bem. Tudo está como esperado aqui. Por padrão. O Nextflow usa um tipo especial de saída para um terminal chamado códigos de controle ANSI, o que significa que sobrescreve certas linhas para dar uma visão comprimida agradável de todos os diferentes processos que estão sendo executados. + +Isso faz muito mais sentido quando você tem fluxos de trabalho maiores e está executando centenas ou milhares de diferentes amostras. Você pode simplesmente gerar tanta saída no terminal que é impossível de ver, enquanto esta visão de atualização lhe dá um progresso em tempo real para você. + +## 2.1.3. Execute o comando novamente com a opção -ansi-log false + +Se você quiser, pode executá-lo novamente, e desta vez vou usar um argumento central adicional do Nextflow com um único hífen dizendo, "-ansi-log false". Isso usa a versão anterior da saída de log do Nextflow. E aqui você pode ver todos os processos individuais que foram lançados. + +Fica a seu critério fazer isso ou não. A saída do Nextflow é exatamente a mesma em ambos os casos. + +## 2.2. Certifique-se de que os nomes dos arquivos de saída serão únicos + +Ok, vamos dar uma olhada nos arquivos de saída, então iremos para results. Mas há apenas um único arquivo de saída. O que aconteceu? Vimos que o processo havia sido executado várias vezes. Podemos ir ao diretório work e ver todos os diferentes hashes, todas as tarefas foram executadas corretamente. Mas se você se lembrar no nosso processo aqui, estamos salvando tudo em um arquivo output.txt e depois publicando isso para este diretório. + +Então o mesmo arquivo foi criado cinco vezes, e então foi sobrescrito cinco vezes. E temos apenas qualquer tarefa que tenha sido executada por último. + +## 2.2.1. Construa um nome de arquivo de saída dinâmico + +A maneira como corrigimos isso é usando um nome de arquivo de saída dinâmico. Aqui já temos uma variável chamada greeting dentro do processo, então podemos usar isso no nome do arquivo de saída. Copio isso e faço $greeting-output.txt. + +Vou cercar isso com aspas, apenas para que o bash não fique confuso com quaisquer espaços que possam aparecer aqui. E então vou pegar o mesmo nome de arquivo e atualizar a saída aqui. + +É realmente importante que a saída corresponda a isso, porque caso contrário, este arquivo não será encontrado e o Nextflow vai travar. + +Vou fazer mais uma edição realmente importante, que é mudar essas aspas simples por aspas duplas. Observe que a cor do código mudou quando fiz isso. Esta variável só é expandida se usarmos aspas duplas. Se eu usar aspas simples aqui, é usado como um valor literal, e eu teria um único arquivo chamado $greeting-output, o que não é o que eu quero. + +## 2.2.2. Execute o fluxo de trabalho + +Então vamos colocar as aspas duplas de volta e tentar. + +Vou apenas limpar meu diretório antes de começar, para que seja fácil ver os novos arquivos. Vou deletar qualquer coisa chamada .nextflow, work e results. + +E vou executar aquele comando Nextflow novamente e vamos ver quais arquivos são criados. Então ele executa os cinco processos ali. Se você estivesse assistindo muito atentamente, pode ter visto aquela linha atualizar enquanto estava executando. + +E agora podemos ir ao diretório results, e com certeza, temos cinco saídas diferentes, e todas elas são prefixadas com a saudação diferente. + +Se eu abrir cada uma delas, veremos que cada uma contém a saudação correspondente. Fantástico. É isso que queremos. + +## 3. Use um operador para transformar o conteúdo de um canal + +Ok, então agora sabemos o que são canais e sabemos o que são fábricas de canais. E quanto aos operadores? Este é outro termo para parte da linguagem Nextflow, que é uma série de funções que nos permitem operar em canais para fazer certas coisas com eles. Nextflow, vem com um conjunto de operadores, que nos permitem manipular canais de várias maneiras diferentes. + +## 3.1. Forneça um array de valores como entrada para o canal + +Vamos trabalhar nisso com um exemplo. Digamos que queremos pegar essas strings de entrada, mas em vez de apenas colocá-las diretamente em uma fábrica de canais, queremos defini-las como um array. + +## 3.1.1. Configure a variável de entrada + +Então vou pegar isso e fazer isso como uma nova linha acima e dizer, greetings, array. + +Pronto. Vou pegar aquela variável array e colocá-la no channel.of, e salvar. + +## 3.1.3. Execute o fluxo de trabalho + +Agora, vamos ver o que acontece. Volto ao meu terminal. Vou apenas limpar todos aqueles arquivos temporários novamente. E vamos executar o fluxo de trabalho. + +Nada bom. Ok. Quebrou. Tudo bem. Eu estava esperando que quebrasse desta vez. Depurar o que dá errado quando um fluxo de trabalho Nextflow falha é uma parte fundamental de ser um desenvolvedor Nextflow. Isso vai acontecer muito e é importante entender o que a mensagem de erro diz e como lidar com isso. + +As mensagens de erro do Nextflow são na verdade bastante estruturadas. Nos diz qual processo deu errado. Nos dá uma mensagem de erro por uma razão. Diz qual foi o comando que tentou executar dentro daquela tarefa particular, qual foi o status de saída, qual foi a saída e onde estava o diretório work daquela tarefa. + +Observe que posso clicar com option nisto no VS Code e ele abre em uma barra lateral para que eu possa ir direto lá e visualizar todos esses arquivos ocultos, sobre os quais falamos no capítulo anterior, incluindo o arquivo .command.sh. Você pode ver que este é o mesmo que os comandos que foi executado aqui. + +Ao olhar para este arquivo, podemos ter uma ideia do que pode ter dado errado aqui em vez de executar uma única tarefa para cada elemento no array como fez da última vez, ele apenas forneceu o array inteiro de uma vez como uma string. Então precisamos desempacotar aquele array em valores individuais antes de passá-lo para o canal. Vamos voltar e ver se podemos fazer isso usando um operador. + +## 3.2. Use um operador para transformar o conteúdo do canal + +Neste caso, não vamos alterar o array antes de passá-lo para o canal. Vamos ajustar o canal para que ele se comporte da maneira que esperamos. Vamos fazer isso usando o operador flatten pode fazer dot começar a digitar e podemos ver que a extensão do VS Code começa a sugerir todos os diferentes operadores que temos disponíveis. + +## 3.2.1. Adicione o operador flatten() + +E vou selecionar flatten. Observe que o espaço em branco não importa neste contexto para o Nextflow. Então você pode colocar esses operadores em uma nova linha se quiser. Então posso soltar isso aqui e indentar para que fique embaixo de ".of" e você verá que as pessoas frequentemente encadeiam muitos operadores assim em um canal e indentam desta forma para que seja mais fácil de ler. + +Você também pode ver, como antes, posso passar o mouse sobre isso e ler o que o operador flatten está fazendo, e também seguir um link para a documentação se eu quiser. + +Então este operador está pegando este canal, que tem um único array dentro dele, e separando os valores do array. + +## 3.2.2. Adicione view() para inspecionar o conteúdo do canal + +Podemos espiar dentro dos canais usando o operador especial view, e vou adicionar alguns deles aqui. Isso é um pouco como usar instruções print em outras linguagens. Então vou fazer dot view e então vou usar esses colchetes ondulados. + +Isso é chamado de closure. Isso basicamente fornece código adicional para o operador view, que ele executará em cada item dentro do canal. Neste caso, vou dizer greeting before flatten. Greeting. + +Estou definindo uma variável aqui, que está apenas dentro do escopo deste closure. Então esta variável é usada apenas aqui e eu poderia chamá-la como quisesse. Não importa muito. Estou apenas usando greeting para tornar mais fácil de ler. + +Em alguns pipelines Nextflow, você pode ver pessoas usando uma variável implícita especial chamada "$it". Assim. Esta é uma variável especial dentro do código Nextflow, que é um atalho para que você não precise fazer a pequena definição de uma variável. No entanto, ao longo do tempo estamos pensando, isso não é muito claro para pessoas que são novas no Nextflow, e desencorajamos o uso de "$it" agora. + +Então vou ficar com o comportamento anterior de greeting e usá-lo assim porque isso é mais explícito e é mais claro sobre o que está acontecendo. + +Vou então copiar esta linha e fazer exatamente a mesma coisa novamente após os argumentos flatten. O operador view é um pouco especial porque faz algo nos elementos, mas também apenas continua passando-os para o próximo operador, então podemos encadeá-lo no meio de uma cadeia de operações assim, e ele imprimirá o status lá e continuará. Então, esperançosamente, isso nos mostrará como o canal se parece antes e depois do operador flatten. + +## 3.2.3. Execute o fluxo de trabalho + +Vamos tentar. Limpar. Limpar tudo no espaço de trabalho. Execute o pipeline novamente. + +Ok, então podemos ver que executou nossos cinco processos. Novamente, não travou com um erro, então isso é definitivamente bom. E agora temos o before flatten e com certeza temos nosso array e temos after flatten, impresso cinco vezes uma vez para cada elemento do array. Isso é exatamente o que esperávamos. Então isso é realmente uma boa notícia. E isso se encaixa exatamente com o que esperaríamos do código. + +Não precisamos mais dessas instruções de depuração, então posso comentá-las ou deletá-las. Vou deletá-las apenas para manter meu código limpo e organizado. Ok, ótimo. Este exemplo agora está funcionando bem e podemos começar a ver como os canais podem fazer uma lógica um pouco mais complicada. + +## 4. Use um operador para analisar valores de entrada de um arquivo CSV + +Agora vamos tentar fazer isso usando um arquivo com uma série de entradas. Esta é uma maneira muito comum de escrever pipelines Nextflow usando uma planilha de amostras ou um CSV de metadados. + +## 4.1. Modifique o script para esperar um arquivo CSV como fonte de saudações + +Se eu for à barra lateral, você pode ver greetings.csv no repositório de exemplo, e este é um arquivo CSV muito, muito simples que apenas contém três linhas com três saudações diferentes. Vamos ver se podemos usar este arquivo CSV dentro do nosso fluxo de trabalho. + +Agora vou voltar a usar params como fizemos no capítulo um, para que possamos ter uma entrada de linha de comando. + +Vou deletar este array greetings. + +## 4.1.1. Altere o parâmetro de entrada para apontar para o arquivo CSV + +Vou definir params greeting para o nome do arquivo, que é greetings.csv, e vou usar esta variável especial para gerar o canal. Vou colocar isso aí, e os erros desaparecem. Lembre-se de que isso está definindo esta variável por padrão agora. Então, se eu executar o pipeline sem nenhum argumento, ele usará greetings.csv, mas eu poderia fazer --greeting para sobrescrever esta variável se quisesse. + +## 4.1.2. Mude para uma fábrica de canais projetada para lidar com um arquivo + +Ok, estamos passando um arquivo agora em vez de uma string ou um array de strings, então provavelmente precisamos de uma fábrica de canais diferente. + +Vamos nos livrar de "of" que estamos usando até agora, e em vez disso usar .fromPath. Isso faz exatamente o que parece. Cria um canal com caminhos em vez de valores, usando um nome de arquivo ou glob string. Também vou remover o operador flatten, pois não precisamos mais disso, agora que estamos passando um arquivo. + +## 4.1.3. Execute o fluxo de trabalho + +Vou salvar, abrir o terminal, executar o fluxo de trabalho e então ver o que acontece. + +Ok. Travou novamente. Não se preocupe. Eu estava esperando este também. Vamos dar uma olhada na mensagem de erro e ver se conseguimos descobrir o que está dando errado. Aqui podemos ver o comando executado, e um pouco como antes onde tínhamos todo o array impresso. Agora temos o caminho do arquivo sendo ecoado no comando, em vez de passar pelo conteúdo do arquivo. + +## 4.2. Use o operador splitCsv() para analisar o arquivo + +Então, para usar o conteúdo do arquivo em vez disso, precisamos de outro operador. O operador que vamos usar para este é chamado splitCsv. Faz sentido, porque é um arquivo CSV que estamos carregando. + +## 4.2.1. Aplique splitCsv() ao canal + +Ok, então splitCsv. Fecha parêntese. Não precisamos de nenhum argumento aqui. E novamente, vou usar alguns operadores view para dar uma visão do que está acontecendo aqui. + +.view csv after splitCsv. Before split Csv.s + +## 4.2.2. Execute o fluxo de trabalho novamente + +Ok, vamos tentar executar isso e ver o que acontece. + +Ok, temos um pouco mais de saída desta vez, mas ainda falhou. Podemos olhar as instruções view, e aqui você pode ver before split CSV, e temos um caminho de arquivo como vimos na mensagem de erro anterior. After split CSV, agora temos três valores correspondentes às três linhas no arquivo CSV. + +No entanto, você pode ver que cada um desses valores está cercado por colchetes. Então cada um deles era um array por si só, e isso nos deu a mesma área que tínhamos antes, onde está tentando ecoar um array em vez de apenas uma única string. + +Se pensarmos sobre um arquivo CSV, isso meio que faz sentido. Normalmente, um arquivo CSV terá linhas e colunas, então split CSV faz array bidimensional. A primeira dimensão do array é cada linha, e então há uma segunda dimensão, que é cada coluna para cada linha. + +Então aqui temos apenas um único valor em cada linha, então temos uma única coluna, então temos um array de um elemento para cada linha do arquivo. + +Tudo bem. Precisamos apenas de outro operador para colapsar aquele array para cada linha do arquivo CSV analisado. Vamos limpar isso. Livrar-se de um terminal e ver o que podemos fazer. + +## 4.3. Use o operador map() para extrair as saudações + +Agora poderíamos usar o operador flatten novamente, que usamos antes. Vimos como ele pode colapsar um array em uma série de valores, o que funcionaria muito bem aqui. Mas vou usar a oportunidade para demonstrar outro operador, que é muito comum dentro de fluxos de trabalho chamado operador map. + +## 4.3.1. Aplique map() ao canal + +Vou fazer dot map e vou fazer item item[0]. + +Se você escreve muito código em outras linguagens, pode já estar familiarizado com o operador map. Ele pega um iterável, como um array ou um canal, e faz alguma operação em cada valor dele. + +Aqui estamos dizendo que devemos definir uma variável chamada item dentro do escopo deste closure, e então queremos retornar, apenas o primeiro valor naquele array. Então item índice zero. + +Isso está efetivamente achatando o array. Você pode ver como poderíamos estender isso para ser mais complexo, no entanto: se nosso arquivo CSV tivesse seis colunas, mas estivéssemos apenas interessados na quarta coluna, poderíamos acessar um índice específico aqui. Ou fazer qualquer outro tipo de operação no valor antes de passá-lo para processamento downstream. + +Então o operador map é extremamente flexível e muito poderoso para modificar canais em tempo de execução. Vamos colocar outra instrução view apenas para que possamos ver o que está fazendo em nossa execução. Pode adjudicar aquela linha e movê-la para baixo. E after map. + +## 4.3.2. Execute o fluxo de trabalho mais uma vez + +Vamos abrir o terminal e tentar executar o fluxo de trabalho. + +Ok, sem erros desta vez. Isso é um bom sinal. Agora podemos passar por todas essas diferentes saídas das instruções view. Before split CSV, tínhamos um único caminho. After split CSV, tínhamos os arrays de valor único, e então after map, temos apenas os valores sem nenhuma sintaxe de array. Vamos até o diretório results, e aqui estão nossos arquivos de saída se comportando exatamente como queríamos. + +Há um pequeno bônus aqui. Você pode realmente ver que os operadores view estão ligeiramente misturados na ordem em que fizeram a saída. Isso é porque o Nextflow está fazendo paralelização dessas diferentes tarefas. Então, depois que dividiu o CSV, há três elementos neste canal, e está lidando com o processamento desses três elementos em paralelo automaticamente. Isso significa que a ordem das saídas é estocástica e pode variar. Neste caso, apenas aconteceu que alguns dos operadores view retornaram depois que a etapa subsequente havia sido concluída, e então veio nesta ordem. + +Se eu executar o mesmo fluxo de trabalho novamente. Então com certeza, veio em uma ordem diferente e desta vez temos os split CSVs e os maps na ordem que esperaríamos. + +Então apenas tenha em mente, você não pode confiar na ordem das saídas de uma tarefa de processo porque o Nextflow está lidando com essa paralelização para você automaticamente. O Nextflow faz isso para você com sua lógica de fluxo de dados, e esse é o verdadeiro poder do Nextflow. + +Ok, este é provavelmente um dos capítulos mais importantes de todo o treinamento. Uma vez que você entende canais, fábricas de canais e operadores, você começa a entrar na força do Nextflow e no que o torna único como linguagem de programação. Esta funcionalidade permite ao Nextflow paralelizar todos os seus fluxos de trabalho para você e gerar lógica de fluxo de trabalho extremamente complexa com uma sintaxe muito limpa e um modelo de fluxo de dados push. Pode ser um conceito um pouco estranho no início, mas uma vez que você se acostuma a escrever código assim, rapidamente se sentirá natural e antes que você perceba, estará escrevendo fluxos de trabalho fantásticos. + +Faça uma pausa, uma xícara de chá, dê uma volta e vamos para o capítulo três, onde começamos a estender esses conceitos para fluxos de trabalho mais complexos. Vejo você no próximo vídeo. + +[Próxima transcrição de vídeo :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/pt/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..12dd675375 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Parte 3: Olá Workflow - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções passo a passo completas, retorne ao [material do curso](../03_hello_workflow.md). + + Os números de seção mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção nos materiais. + +## Boas-vindas + +Olá, bem-vindo à parte três do curso de treinamento "Olá Nextflow". + +Este capítulo é chamado "Olá Workflow". + +No capítulo dois, construímos um fluxo de trabalho simples de um processo, mas na realidade, pipelines são úteis porque podem encadear múltiplas etapas de análise juntas. + +Neste capítulo, vamos pegar aquele exemplo inicial e estendê-lo para ser um pouco mais realista. + +Vamos adicionar algumas etapas adicionais e veremos como usamos canais para conectar essas etapas. + +Vamos olhar para múltiplas tarefas, que podem colapsar em um único processo e vamos olhar para processos que podem ter múltiplas entradas e múltiplas saídas. + +Ok, vamos começar. + +Então vamos começar. Como antes. Vamos para training.nextflow.io. Olá Nextflow, capítulo três. Olá Workflow. E vamos abrir nosso workspace. Eu limpei todos os meus arquivos de trabalho dos capítulos anteriores e vou abrir Olá Workflow. + +Agora este é o mesmo arquivo com o qual temos trabalhado até agora, então isso deve parecer familiar. Temos nosso processo say hello. Temos nosso params.greeting com seu arquivo greetings CSV, e temos nosso fluxo de trabalho na parte inferior, que carrega aquele arquivo CSV, cria o canal e o passa para nosso processo. + +## 0. Aquecimento: Execute hello-workflow.nf + +Se você quiser, podemos experimentar isso e verificar se está funcionando como esperamos. Abra um terminal para nextflow run hello workflow nf e clique em enter. + +Ok, ótimo. Nossos três processos executaram. Temos nosso diretório results com nossas três saídas. Bonjour. Hello. Holà. Então vamos fechar esses arquivos, fechar o terminal, voltar ao script. + +## 1. Adicione um segundo passo ao fluxo de trabalho + +Ok. Para nosso exemplo, estamos mantendo o básico e tentando ser agnósticos de domínio. Então nosso segundo processo vai apenas manipular essas strings, essas palavras, de uma maneira simples. Vamos usar o comando Unix translate para pegar esses arquivos e torná-los todos em maiúsculas. Fazemos isso com o comando "tr". + +## 1.1. Defina o comando de conversão para maiúsculas e teste-o no terminal + +Podemos tentar isso apenas no terminal bash, e ver se funciona. Então você faz echo, Hello World, e então passa isso com o caractere pipe para tr, e damos a ele um padrão de reconhecimento, a to z e para o que deve traduzir. A to Z em maiúsculas. + +Isso é muito simples porque está literalmente fazendo os caracteres A a Z. Então não funcionará em nada que seja acentuado ou algo assim. Mas para os propósitos do exemplo, você deve entender a ideia. + +Vou pressionar enter e ele imprime no terminal, HELLO WORLD em maiúsculas. E assim como antes, poderíamos redirecionar isso para um arquivo se quiséssemos. Outfile. + +Ok. Vamos limpar isso. + +## 1.1. Escreva a etapa de conversão para maiúsculas como um processo Nextflow + +Vamos voltar ao nosso script e escrever um novo processo para lidar com este comando bash. Vou copiar o processo anterior, colá-lo abaixo, e chamá-lo de convert to upper. Para maiúsculas. Vou usar o mesmo publishDir results, mas vou fazer algumas mudanças aqui. Em vez de receber um val, vou receber um path input file, e vou ter um prefixo aqui upper, para que nossos arquivos de saída não sobrescrevam a saída. E vou usar o nome da variável da entrada. E então vou mudar o script aqui embaixo, e em vez disso vou usar cat no arquivo de entrada e assim como fizemos em Bash TR, a-z, upper input file .txt. Ok, vamos clicar em salvar. + +## 1.2. Adicione uma chamada ao novo processo no bloco workflow + +Agora se eu rolar para baixo, precisamos realmente chamar este processo. Apenas adicionar o processo em um script não é suficiente. Temos que dizer ao Nextflow que precisamos executar este processo e onde fazer isso. + +Então vou fazer aqui, convert to upper e + +ok, estamos recebendo um erro aqui dizendo que espera um argumento. Com certeza, precisamos passar algo para este processo para que ele realmente tenha algo para fazer. + +## 1.3. Passe a saída do primeiro processo para o segundo processo + +O que vamos fazer é pegar a saída deste processo. Então eu pego o nome, say hello, e quando eu faço dot out. + +Para um exemplo simples como este, onde temos um processo que tem apenas uma saída e estamos passando isso para um novo processo, então ele tem uma entrada, isso deve ser tudo que precisamos. Então vou clicar em salvar, abrir o terminal, e vamos tentar executar isso novamente. + +## 1.4. Execute o fluxo de trabalho novamente + +Agora, eu não limpei meu diretório work da última vez que executei este fluxo de trabalho. Vou executá-lo novamente e vou usar isso como uma oportunidade para mostrar como o cache parcial funciona. Então se eu fizer traço único resume. Esperançosamente deve reutilizar as saídas daquele primeiro processo, que eram exatamente as mesmas da última vez que executei. Mas agora temos um novo processo aqui que não foi executado antes, que executa do zero. E com certeza, você pode ver que o primeiro processo usou as saídas do cache, e a segunda saída executou três de três. Você também pode ver que temos ambos os nossos processos aqui agora, nosso primeiro processo, say hello, executou três vezes, e nosso segundo processo convert to upper executou três vezes. + +Se eu executar isso novamente, como lembrete, com -ansi-log false, devemos ver que seis tarefas de processo diferentes executam três para cada uma delas. Então isso está fazendo exatamente o que esperávamos. O primeiro processo está executando três vezes, passando essas saídas para um segundo processo, que está então executando três vezes. + +Então vamos dar uma olhada dentro do diretório work e ver como o Nextflow está manipulando essas entradas de arquivo. Se eu pegar este diretório hash aqui do segundo processo, podemos usar um comando tree novamente com -a apenas para olhar esses arquivos. Você pode ver aqui que temos nosso arquivo de entrada, que é o arquivo Bonjour-output.txt, e isso é na verdade um symlink. É isso que esta seta está nos mostrando, e está apontando para o arquivo no diretório work anterior. + +Isso faz sentido. O Nextflow manipula a execução de cada tarefa em seu próprio diretório encapsulado, então é completamente auto-contido. No entanto, ele precisa fornecer os arquivos de etapas anteriores como entrada. Em vez de alcançar fora do diretório work para obter esses arquivos, o Nextflow os prepara no diretório work. + +Se tivermos um sistema de arquivos compartilhado como aqui, ele faz isso usando um symlink para que não use nenhum espaço de arquivo adicional. Se usarmos armazenamento em nuvem com buckets em diferentes localizações, ele buscaria esses arquivos e realmente os copiaria para o diretório work. + +Vamos dar uma olhada no arquivo command sh. Se eu fizer code work, command sh, você pode ver, com certeza, ele está acessando aquele arquivo do diretório local. Então tudo é muito auto-contido e limpo. + +Também podemos verificar o diretório results e ter certeza de que esses arquivos foram emitidos adequadamente. E com certeza, em results, podemos ver todos os arquivos de saída do primeiro processo e todos os arquivos de saída do segundo. E eles estão todos em maiúsculas como esperávamos. + +É aqui que o poder do Nextflow começa a brilhar. Com algum código muito mínimo, o Nextflow lidou com a execução em paralelo dessas tarefas com encapsulamento limpo dentro de diretórios work separados e preparação de arquivos de entrada e saída e publicação de arquivos, tudo automaticamente para nós, logo de cara. Então você pode ver como, à medida que escalamos essa complexidade de nossos fluxos de trabalho de análise, essa funcionalidade é realmente, realmente valiosa. + +## 2. Adicione um terceiro passo para coletar todas as saudações + +Ok. Essas etapas foram um-para-um. Tivemos uma saída do primeiro processo indo para uma entrada para o segundo processo. Em seguida, vamos falar sobre como coletar essas diferentes saídas em uma única tarefa de processo, que é novamente, uma coisa muito comum de fazer. Então vamos rapidamente abrir o terminal e fazer uma execução de teste disso. + +## 2.1. Defina o comando de coleta e teste-o no terminal + +Vou trapacear e copiar o código bash de exemplo do material de treinamento e apenas pressionar enter. + +O que podemos ver aqui é que executamos este comando echo três vezes para três arquivos de saída diferentes, que posso ver aqui. E então usamos o comando cat para imprimir a saída de cada um desses três arquivos diferentes, e redirecionar isso para um único arquivo coletado. + +E se eu fizer "cat COLLECTED-output", você pode ver que tem o conteúdo daqueles três arquivos diferentes, agora em um único arquivo. + +## 2.2. Crie um novo processo para fazer a etapa de coleta + +Então vamos ver se podemos replicar a mesma coisa dentro do nosso pipeline Nextflow. + +Vamos rolar para cima e criar um terceiro processo. Vou copiar este anterior, e desta vez vou chamá-lo de Collect Greetings. + +No terminal bash, chamamos de collected output txt. Então vou dizer o mesmo path output aqui. E vou fazer o redirecionamento aqui, então é salvo da mesma maneira. + +Ok. Precisamos mudar o que acontece no início daquele comando, e precisamos pensar sobre o que é o arquivo de entrada aqui. Na verdade, este processo vai receber múltiplos arquivos de entrada. Vou manter path e vou mudar isso para uma nova variável chamada input files, plural. + +Vou então novamente, dar cat neles como fizemos em nosso script bash. E vou usar a variável aqui. + +Agora, você pode pensar que isso não funcionaria. Vimos anteriormente falhas onde um array de strings ou um array de paths foi passado para um processo e isso causou um erro. Mas na verdade, aqui o Nextflow vai lidar com isso automaticamente para nós da maneira certa. Ele vai pegar vários arquivos de entrada diferentes, e vai apenas imprimir os diferentes caminhos de arquivo aqui. + +Claro que ajuda que o comando cat pode receber uma série de nomes de arquivo assim. Se eu estivesse usando um comando diferente que requer um argumento antes de cada caminho de arquivo ou algo assim, teríamos que ter um pouco mais de código aqui e lógica para poder lidar com a iteração desses caminhos de arquivo. Mas neste caso, deve apenas funcionar. + +## 2.3. Adicione a etapa de coleta ao fluxo de trabalho + +Ok, vamos descer para o fluxo de trabalho e adicionar nosso novo processo. Collect greetings. E novamente, vamos pegar a saída de convert to upper out. Vamos salvar isso. + +Vamos tentar. nextflow run hello workflow. + +Ok, o fluxo de trabalho executou, mas algo está um pouco estranho aqui. Temos três execuções da primeira etapa, que esperamos. Três tarefas para a segunda, mas também temos três tarefas no final quando esperávamos ter apenas uma única tarefa aqui mesclando todas as saídas. + +Se formos ao nosso diretório results. Também vemos que o output coletado tem apenas um único valor em vez de todos os três. Isso é porque aquele arquivo de saída foi sobrescrito três vezes com três valores diferentes. + +Isso faz sentido porque passamos uma saída para uma entrada aqui da mesma maneira que fizemos na etapa anterior. + +## 2.4. Use um operador para coletar as saudações em uma única entrada + +Então precisamos de um operador aqui para pegar este canal com três elementos e colapsá-los em um único elemento, para que aquele processo final execute apenas uma vez. + +Para fazer isso, vamos usar o operador collect. Posso fazer isso diretamente dentro do fluxo de trabalho. Posso fazer .out e encadear em um operador aqui no final .collect. + +Pressione salvar. E então para os propósitos deste treinamento, também vou fazer alguns operadores view como fizemos antes, para que possamos dar uma olhada neste canal antes e depois de usarmos o operador collect, para que possamos entender o que está acontecendo. + +Vou pegar este canal, remover o collect e dot view greetings, e então vou duplicar esta linha, adicionar o operador collect. E mudar isso para after. + +Isso é separado de onde estamos chamando isso, mas tudo bem porque estamos usando as mesmas chamadas de operador no mesmo canal de saída. + +Ok, vamos salvar e vamos experimentar no terminal. Vou fazer nextflow run. Hello, workflow. Reexecutar nosso script. + +Ok. Isso está parecendo melhor. Como antes, podemos ver os primeiros dois processos executarem três vezes e agora nosso processo final executou apenas uma vez. + +Se olharmos o que foi impresso pelo operador view, aqui embaixo, dissemos before collect, que é esta saída aqui, e isso é impresso três vezes. E você pode ver que há um único path para cada um desses. E então after collect, você pode ver que temos este array de três paths. Então isso é como esperamos. + +Ok, vamos verificar o arquivo results e ver se é o que esperamos desta vez. Com certeza, agora há três linhas no arquivo - isso concatenou com sucesso essas três saídas em um único arquivo de saída. Fantástico. + +Ok, vou limpar e vamos para o próximo passo. E vou deletar essas declarações view apenas para manter as coisas limpas. + +## 3. Passe mais de uma entrada para um processo a fim de nomear o arquivo de saída final de forma única + +Ok. Até agora, todos os nossos processos receberam apenas uma única entrada. Agora vamos fazer um exercício onde adicionamos mais de uma entrada a um processo para ver como isso funciona. Para fazer isso, vamos usar este exemplo collect greetings. + +Cada vez que executei o fluxo de trabalho, ele sobrescreveu aquele arquivo no diretório results, o que pode não ser o que queremos. + +## 3.1. Modifique o processo coletor para aceitar um nome definido pelo usuário para o arquivo de saída + +Então para este exemplo, vamos passar um parâmetro adicional para que possamos personalizar o nome do arquivo de saída. + +Adicionar uma segunda entrada a um processo é muito simples. Apenas adiciono uma segunda linha no bloco input. Desta vez vai ser um value, em vez de um path, porque queremos passar uma string e vou chamá-lo de batch underscore name. + +Agora posso usar esta variável no bloco script, e vou dizer collected dash dollar batch name. + +Estou usando chaves aqui em torno do nome da variável. Isso é apenas para mantê-lo separado do resto da string, e provavelmente não é necessário neste caso, mas acho que torna mais fácil de ler. + +Ok. Finalmente, lembre-se de atualizar o path de saída porque agora o nome do arquivo mudou, então vou fazer a mesma coisa e colocar o batch name na saída do path como esperado. + +## 3.2. Adicione um parâmetro de linha de comando batch + +Agora precisamos passar um batch name de algum lugar, e vou criar um segundo parâmetro para fazer isso para que possamos fazer isso na linha de comando quando executarmos o fluxo de trabalho. + +Então vou fazer params batch name, e por padrão, vamos chamar isso de test batch. Agora posso usar esta variável de parâmetros especiais abaixo, onde chamamos o processo. + +E com certeza o VS Code está nos dizendo que não há argumentos suficientes para este processo agora, e que ele espera uma segunda entrada. + +Simplesmente faço vírgula e passo nossa nova variável e o erro desaparece. + +Note que a ordem das entradas aqui é realmente importante. A primeira entrada do processo foi o path, e a segunda entrada é o nome. Se eu mudar a ordem aqui, também devo mudar a ordem quando chamo o processo. Caso contrário. Em seguida, vamos passar o canal errado para a entrada errada. + +## 3.3. Execute o fluxo de trabalho + +Ok, vamos tentar e ver se funciona. Vamos fazer "nextflow run hello- workflow. Ok, executou como antes. Vamos dar uma olhada no diretório results. + +Com certeza, nosso nome de arquivo aqui agora é chamado "collected test batch output txt". Fantástico. + +E agora vamos ver se podemos sobrescrever isso executando novamente. Desta vez vou fazer --batch_name para combinar com aquele nome de variável de parâmetro especial aqui. E vou chamá-lo de demo output. + +Execute o fluxo de trabalho novamente e veremos se algo acontece. + +Ok, agora temos um collected demo output .txt. E porque este nome de arquivo é diferente daquele, ele não o sobrescreveu. Ambos agora estão presentes no diretório results. + +## 4. Adicione uma saída à etapa coletora + +Ok, então mostramos dar múltiplas entradas a um processo, mas e quanto a múltiplas saídas? Para este exemplo, vamos calcular o número de saudações que são processadas e emitir isso como uma saída secundária para esta etapa collect greeting. + +## 4.1. Modifique o processo para contar e emitir o número de saudações + +Vamos fazer um truque aqui. Os processos Nextflow têm este bloco script com uma string multi-linha, e isso é passado como saída bash para o ponto comando ponto sh. Mas na verdade podemos escrever qualquer código personalizado acima disso, e isso será executado como parte de uma tarefa mas não incluído dentro do script bash. + +Uma das funções integradas na sintaxe Nextflow é chamada size. Então vou pegar a entrada path, e vou dizer count underscore greetings, apenas para definir um nome de variável. Vou pegar os input files e vou chamar "size" nele. + +Esta função vai contar o tamanho deste canal de entrada e atribuir a uma variável. + +Agora podemos retornar aquela variável como parte do bloco output. Então dizemos, val, porque é valor, não um arquivo. E count greetings. + +Agora isso é suficiente por si só, e agora poderíamos acessar essas diferentes saídas deste processo. No entanto, teríamos que acessá-las de maneira posicional. Então usando uma chave de índice como zero e um. + +Para tornar um pouco mais fácil obter as saídas, podemos nomeá-las e fazemos isso usando uma declaração emit. + +Então fazemos vírgula emit out file ou como eu quiser chamar isso. E faço aqui emit count. Isso é basicamente apenas um decorador, que apenas nos ajuda a escrever código um pouco mais limpo para que possamos facilmente referenciar as saídas específicas mais tarde no bloco workflow. + +## 4.2. Relate a saída no final do fluxo de trabalho + +Ok. Se eu rolar para baixo para o bloco workflow, agora posso pegar as saídas de collect greetings, fazer collect greetings, dot out, e podemos ver nossas duas saídas nomeadas são sugeridas aqui pela extensão VS Code. Muito útil. + +Então vou fazer dot count para obter o valor de contagem que acabamos de criar, e vou fazer view, para que ele imprima na linha de comando. Então podemos vê-lo quando executarmos o fluxo de trabalho. + +Vamos escrever algo no closure aqui apenas para torná-lo um pouco mais agradável. num greetings, havia greetings saudações. + +E na verdade não nos importamos com a outra saída porque não estamos usando isso como entrada para quaisquer outros processos. Mas você pode ver como poderíamos facilmente passar isso como entrada para outro processo se quiséssemos, downstream. + +## 4.3. Execute o fluxo de trabalho + +Vamos clicar em salvar. Vamos dar uma olhada no terminal e tentar isso. + +Ok, fantástico. Aqui vamos nós. Há três saudações. Isso está exatamente certo. + +Ok, ótimo. Esse é o fim deste capítulo. Terminamos por ter chegado até aqui. Você está agora começando a construir um fluxo de trabalho bastante realista, onde somos capazes de lidar com entradas e saídas e lógica dentro do nosso fluxo de trabalho. + +À medida que esses arquivos de fluxo de trabalho ficam mais longos, eles começam a se tornar um pouco difíceis de manejar. Então no próximo capítulo, vamos olhar para como podemos modularizar o código Nextflow em arquivos separados para que seja mais fácil encontrar e manter o código dentro do fluxo de trabalho. + +Junte-se a nós no próximo vídeo para o capítulo quatro. Olá Modules. + +[Próxima transcrição de vídeo :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/pt/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..8064985a4e --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Parte 4: Olá Módulos - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções completas passo a passo, retorne ao [material do curso](../04_hello_modules.md). + + Os números de seção mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção dos materiais. + +## Boas-vindas + +Olá, bem-vindo à Parte Quatro do curso de treinamento Olá Nextflow. + +Este capítulo se chama Olá Módulos, e vamos falar sobre como modularizar código Nextflow. O que vamos fazer é pegar nosso script de fluxo de trabalho único e dividi-lo em arquivos separados. + +Isso torna o código mais fácil de navegar e manter conforme seu fluxo de trabalho cresce, e também torna possível compartilhar módulos entre pipelines, de modo que se você tiver múltiplos pipelines usando a mesma ferramenta, você só precisa escrever esse processo uma vez. + +Um exemplo clássico disso é o repositório de módulos nf-core, que possui milhares de diferentes ferramentas em módulos prontos para uso, que você pode instalar e usar em seu fluxo de trabalho. + +O Nextflow também pode trabalhar com sub fluxos de trabalho, que são como módulos, mas têm múltiplos processos. Isso está fora do escopo deste treinamento, mas funciona basicamente da mesma forma. + +Certo. Vamos dar uma olhada. + +Como sempre, comece indo para training.nextflow.io. + +Vá para "Olá Nextflow" na barra lateral, e estamos fazendo a parte quatro: "Olá Módulos". + +Agora vou pular para meu ambiente GitHub Code Spaces e dar uma olhada no arquivo "hello-modules". + +Assim como antes, estamos começando no ponto final do capítulo anterior, então este script deve parecer familiar. Temos nossos três processos, say hello, convert to upper e collect greetings, e em um fluxo de trabalho simples, que executa esses três comandos e emite uma mensagem no final. Temos dois parâmetros chamados greeting e batch, que especifica o nome, que é usado para o arquivo de saída coletada no final. + +## 0. Aquecimento: Execute hello-modules.nf + +Podemos verificar que este fluxo de trabalho ainda funciona como esperamos fazendo nextflow run hello, modules. + +Ótimo. Ele executou três tarefas com cada um desses processos, uma tarefa coletada, e nos disse que há três saudações neste lote. Se entrarmos em results, temos nossos diferentes arquivos de saída aqui, incluindo a saída do lote de teste coletado. + +## 1. Crie um diretório para armazenar módulos + +Certo. Vamos fazer alguma modularização. + +É geralmente uma boa ideia colocar módulos em uma subpasta no repositório do seu pipeline, apenas para manter as coisas organizadas. Você pode chamar isso do que quiser, mas por convenção geralmente chamamos de modules. + +Então vamos em frente, vamos para um terminal e fazemos make the modules. Você pode vê-lo aparecer na barra lateral e VS Code aqui. + +## 2. Crie um módulo para sayHello() + +Vou então criar um novo arquivo para meu primeiro módulo. Você pode fazer "touch" ou "code" ou você pode fazer isso na barra lateral, realmente não importa. Então vou fazer code modules e vou nomeá-lo após o processo. Então sayHello.nf. NF é uma extensão de arquivo tradicional para arquivos Nextflow. + +Vou apertar salvar aqui e podemos ver nosso novo arquivo de módulo aparecer. + +## 2.2. Mova o código do processo sayHello para o arquivo do módulo + +Certo, a seguir vou pegar o código do módulo do fluxo de trabalho. Também vou pegar o hash bang aqui e copiar isso primeiro para que seja claramente um arquivo Nextflow. E então vou pegar este processo e vou cortar. Então vou removê-lo do meu script de fluxo de trabalho principal e vou colá-lo neste novo módulo. + +Esse é todo o conteúdo que este arquivo de módulo vai conter. Apenas um único processo, sem fluxo de trabalho, sem lógica, apenas um processo sozinho. + +Agora posso fechar este arquivo. + +## 2.3. Adicione uma declaração de importação antes do bloco workflow + +Agora meu fluxo de trabalho está faltando esse primeiro processo, então precisamos trazê-lo de volta importando-o. A sintaxe para isso é muito similar a outras linguagens de programação, então pode parecer familiar. Fazemos include chaves, o nome do processo, say hello, e então from o caminho do arquivo modules, say hello, nf. Fantástico. + +Alguns truques aqui. A extensão VS Code é inteligente sobre isso. Ela reconhece este caminho de arquivo e você pode passar o mouse sobre ele e fazer follow link. Ou estou no Mac, posso fazer option click e ele abre este arquivo. Então podemos pular rapidamente para ele. + +Este nome de processo agora está sendo usado pelo fluxo de trabalho aqui embaixo, e podemos fazer a mesma coisa aqui. Ele nos mostra um pouco de informação sobre esse processo, e novamente, posso segurar option, clicar nele, e ele vai abri-lo no editor. + +Então é uma maneira realmente rápida quando você tem muitos arquivos para seus diferentes processos de navegar rapidamente pela sua base de código no VS Code. + +Ok. Isso é basicamente tudo para este capítulo. Agora apenas fazemos a mesma coisa novamente para os outros processos. + +## 3. Modularize o processo convertToUpper() + +Então vamos criar um novo arquivo aqui. Chamá-lo de Convert to upper nf. Novamente, copiar o hash bang. E então cortar o processo. + +Copiar o nome do processo ali, incluir uma nova declaração include com o novo nome do processo. + +## 4. Modularize o processo collectGreetings() + +E então fazer o mesmo para o terceiro processo. Novo arquivo, connect. Greetings, + +fazer o hash bang. Cortar o processo, colar o processo, e fazer uma nova declaração include. + +Agora você pode ver aqui que tenho um sublinhado de erro aqui dizendo invalid include source. E este é na verdade um erro genuíno que cometi porque estava me movendo um pouco rápido demais. Se você olhar com atenção, pode ver que perdi o T em convert to upper + +Então o VS Code muito utilmente me disse que cometi um erro ali. Se eu corrigir esse nome de arquivo, o erro desaparece. É um bom exemplo de por que a verificação de erros dentro do VS Code é tão útil para escrever código Nextflow. Caso contrário, eu não teria percebido isso e só teria descoberto muito mais tarde quando tentasse executar o fluxo de trabalho. + +Nosso script principal do pipeline agora está parecendo muito mais simples. Ele não tem nenhum processo, apenas temos três declarações include e nosso fluxo de trabalho. Não mudamos nenhuma lógica do fluxo de trabalho. Não mudamos nenhum código de processo, então esperançosamente deve funcionar exatamente da mesma forma. + +## 4.4. Execute o fluxo de trabalho para verificar que ele faz a mesma coisa de antes + +Vamos verificar. Vou abrir um terminal e vou executar exatamente o mesmo comando de antes. + +Com certeza, ele executou nossos processos, say hello, convert to upper collect greetings, e nos deu três saudações novamente. + +Então movemos nosso código, mas não mudamos nada sobre como o fluxo de trabalho executa e está completamente inalterado. A única diferença é que agora temos código mais limpo, mais fácil de manter e mais fácil de compartilhar com outros. + +E é isso. Foi um capítulo curto. É um conceito simples, mas é muito poderoso e fundamental para como escrevemos fluxos de trabalho Nextflow mais complexos. Então é importante que você entenda isso e adquira o hábito de usá-lo. + +No próximo capítulo, vamos ter uma mudança de ritmo e parar de pensar tanto sobre a sintaxe de escrever código Nextflow, e pensar um pouco sobre como usamos software nos processos em si. Junte-se a nós na parte cinco para Olá Contêineres. + +[Próxima transcrição de vídeo :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/pt/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..4851a942c3 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Parte 5: Olá Contêineres - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções passo a passo completas, retorne ao [material do curso](../05_hello_containers.md). + + Os números de seção mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção nos materiais. + +## Boas-vindas + +Olá, bem-vindo à Parte Cinco do curso de treinamento Hello Nextflow. + +Este capítulo se chama Olá Contêineres. Vamos falar sobre como o Nextflow se integra com ferramentas como Docker e Singularity para usar contêineres de software para provisionar software aos usuários do seu pipeline. + +Isso significa que quando as pessoas executarem seu pipeline, elas não precisarão instalar todas as diferentes ferramentas por conta própria. O Nextflow fará isso por elas. + +Os contêineres são uma tecnologia extremamente poderosa e crucial para reprodutibilidade e facilidade de uso. Vamos começar fazendo uma breve introdução aos próprios contêineres, executando alguns comandos docker manualmente, e então pegaremos esses mesmos contêineres e os colocaremos no nosso pipeline Nextflow. + +Ok. Vamos começar. + +Então, assim como antes, vamos começar carregando o material de treinamento. Vá para training.nextflow.io. Hello Nextflow, Capítulo Cinco, Olá Contêineres. + +Vou entrar no meu ambiente Codespaces e aqui à esquerda vemos hello containers ponto nf. + +Assim como antes, este é o mesmo script com o qual terminamos o capítulo quatro anterior, então deve parecer familiar. + +Temos nossos parâmetros de linha de comando para especificar o arquivo de entrada e o nome do lote. Estamos incluindo nossos três módulos, e temos nosso fluxo de trabalho onde executamos os três processos. + +## 0. Aquecimento: Execute hello-containers.nf + +Sinta-se à vontade para executar este fluxo de trabalho novamente e verificar se ele está produzindo as saídas que você espera. Por enquanto, na verdade vou fechá-lo e mergulhar no terminal. + +## 1. Use um contêiner 'manualmente' + +Para começar este capítulo, vamos fazer uma pequena recapitulação sobre tecnologia de contêineres. Se você está muito acostumado com docker ou singularity ou outras tecnologias de contêiner, então trate isso como uma atualização, ou sinta-se à vontade para pular completamente. + +O Nextflow suporta muitos tipos diferentes de tecnologias de contêiner. Isso inclui Docker, Singularity, Podman, Shifter, Charliecloud, e mais. + +Neste treinamento, vamos focar no Docker. Ele vem pré-instalado nos code spaces e é uma das tecnologias de contêiner mais populares, especialmente se você está desenvolvendo no seu próprio computador ou laptop. + +Se você está trabalhando em um ambiente acadêmico em um HPC compartilhado, você pode descobrir que o Singularity está disponível e não o Docker. Tudo bem. Todos os conceitos são exatamente os mesmos. Alguns dos comandos manuais são diferentes, mas se você entende Docker, você também entenderá singularity. + +Na verdade, Singularity também está instalado no ambiente Code Spaces. Então, se quiser, você pode tentar fazer as mesmas tarefas usando Singularity em vez de Docker. + +Ok, então o que é tecnologia de contêiner? A ideia por trás do Docker é que ele pode buscar uma imagem de uma fonte remota. Puxá-la para sua máquina local e então criar um contêiner baseado naquela imagem. + +Este contêiner em execução é um pouco como uma máquina virtual rodando no seu computador. Ele está isolado do seu ambiente, e vem pré-empacotado com um sistema operacional e um conjunto de software disponível. + +## 1.1. Faça o pull da imagem do contêiner + +A sintaxe que precisamos para buscar uma imagem pré-existente é "docker pull". Então vou digitar isso no meu terminal, mas agora precisamos de uma imagem para brincar. + +Você pode construir imagens você mesmo. Você pode encontrá-las em registros públicos como Docker Hub ou quay.io. Mas uma maneira realmente boa de obter imagens rapidamente é usando Seqera Containers. + +Este é um serviço comunitário gratuito que construímos em 2024, que você pode usar sem login ou qualquer coisa. + +Se você for para seqera.io/containers ou clicar em containers no topo aqui, você é apresentado a uma interface de busca e pode digitar o nome de qualquer ferramenta disponível no Conda ou no Python Package Index. + +Por padrão, ele busca nos canais Bioconda e Conda Forge, mas você pode prefixar qualquer canal Conda. Estou aqui se você quiser. + +Para nos divertir um pouco, vamos usar cowpy. Vou digitar cowpy. Me dá resultados do Python Package Index e Conda Forge. Vou clicar nisso para adicioná-lo ao meu contêiner. Eu poderia adicionar múltiplos pacotes aqui se quisesse. Seleciono Docker, seleciono linux/amd64, e clico em Get Container. + +Isso constrói a imagem para mim sob demanda se ela ainda não foi criada, e me dá uma URL que posso copiar. + +Se você estiver interessado, pode clicar em view Build Details, e isso te leva a uma página que mostra o arquivo de ambiente conda que foi usado e o log de construção completo para a construção, junto com os resultados da varredura de segurança. + +Se eu voltar para o meu code spaces, agora posso colar este nome de contêiner e apertar enter. + +O Docker agora baixa todas as diferentes camadas dentro desta imagem de contêiner, e agora nos diz que esta imagem está disponível para uso. + +## Fazendo pull de uma imagem Singularity + +Se você está usando singularity, o processo é basicamente o mesmo. Selecionamos nossos pacotes de imagem, selecionamos cowpy. Agora escolhemos Singularity em vez de Docker e clicamos em Get Container. Isso nos dá uma URL de imagem usando oras://. Ou se você preferir, pode usar https:// marcando aquela caixa. Copie aquela URL. Agora vá para Code Spaces. Na verdade temos Apptainer instalado neste espaço, que é o mesmo que Singularity, mas eles são aliases um do outro. Então vou fazer apptainer pull e então vou chamá-lo de cowpy sif, mas você pode chamá-lo do que quiser. Cole a URL. E isso vai baixar aquela imagem para mim. + +Eu poderia fazer ls -lh e ver cowpy.sif + +Singularity é diferente do Docker, pois singularity armazena todas as imagens em arquivos planos, enquanto Docker tem um registro onde mantém todas as camadas separadamente na sua máquina host, e tem um daemon em execução para manter controle de tudo isso. + +## 1.2. Use o contêiner para executar cowpy como um comando único + +Ok, vamos voltar ao Docker. Agora podemos tentar executar esta imagem que criamos fazendo docker run. + +Vou fazer dash dash rm, que apenas faz uma execução única da imagem. E vou colar a URL da imagem. E então finalmente, você finaliza isso com um comando que quer executar. + +A imagem que geramos tinha cowpy instalado, então vamos tentar cowpy. + +Pronto. Executou nosso comando. Não tenho cowpy instalado localmente. Você pode ver que se eu tento executá-lo, ele não existe. No entanto, neste comando, eu o executei usando Docker e ele gerou corretamente esta saída. + +## 1.3. Use o contêiner para executar cowpy interativamente + +Podemos ir além disso se quisermos e iniciar um contêiner interativamente e olhar por dentro. Novamente, faço "docker run dash dash rm". Agora vou fazer dash it, que diz ao Docker que queremos um terminal interativo. Faço a URL da imagem novamente, e desta vez, em vez de fazer cowpy, vou fazer bin bash porque o comando que queremos executar é bash. + +Isso nos leva para dentro deste contêiner em execução e você pode ver que o prompt mudou agora. + +Se eu fizer LS slash você pode ver que os diretórios aqui são diferentes. + +Se eu abrir um segundo terminal aqui do lado direito, que está apenas executando no GitHub Code Spaces e faço LS slash, você vê que temos diretórios como workspaces e temp, enquanto aqui no Docker é diferente. + +Então este ambiente está completamente separado dentro do Docker e isolado do meu ambiente host. Isso é uma coisa boa, porque isso isola a execução deste comando na imagem Docker e mantém reprodutível entre diferentes pessoas em diferentes sistemas host. + +Se você quiser usar dados do seu sistema host dentro da imagem Docker, você tem que explicitamente montar isso no contêiner. + +Vamos fazer isso em um segundo. + +## 1.3.2. Execute o(s) comando(s) da ferramenta desejada + +Primeiro, porém, vamos ver se conseguimos executar cowpy. Lá novamente, o comando está disponível agora diretamente na linha de comando, e podemos começar a fazer coisas mais complexas e passar argumentos. Hello containers e em vez da vaca, vamos fazer o pinguim tux. Vamos ver o que mais temos. + +Vamos fazer cheese. Maravilhoso. Que tal Dragon e Cow? Muito bom. + +## 1.3.3. Saia do contêiner + +Ok. Não posso fazer muito mais porque não tenho nenhum dado neste contêiner. Então vamos sair desta imagem em execução e ver se conseguimos montar alguns dados no contêiner. Posso fazer isso fazendo control D ou digitando exit. Ok, agora estou de volta no meu code space regular do GitHub. + +## 1.3.4. Monte dados no contêiner + +Para montar alguns dados no contêiner Docker, preciso usar dash V. Então vou pegar meu comando docker anterior, voltar ao início fazer dash v. Vou fazer "." para o diretório de trabalho local atual, e então dois pontos para dizer onde isso deve ser montado no diretório host e faço slash data. Então isso está montando este diretório particular no contêiner em slash data. + +Agora se eu fizer LS slash podemos ver que temos um novo diretório chamado data, e se eu fizer LS data, você pode ver todos os arquivos que temos na barra lateral aqui. Fantástico. + +## 1.3.5. Use os dados montados + +Agora podemos começar a usar alguns dos arquivos que estão no sistema host dentro da imagem Docker. Então posso dizer cat data greetings csv. Se você se lembra, este é nosso arquivo CSV com nossas diferentes saudações de antes, e posso direcionar isso para cowpy. Fantástico. Agora estamos chegando a algum lugar. + +Ok. Isso é suficiente para executar Docker interativamente. Esperançosamente você agora tem uma noção do que é Docker e como usá-lo tanto para executar um comando de forma única, quanto para usar uma imagem interativamente. Se você está usando singularity. Os comandos são todos muito similares exceto que você faz coisas como apptainer exec ou apptainer run, ou singularity exec ou singularity run. + +## 2. Use contêineres no Nextflow + +A seguir vamos voltar ao nosso fluxo de trabalho Nextflow e ver como usar esta tecnologia dentro do pipeline Nextflow. + +Vamos fechar o terminal e abrir Hello Containers novamente. + +## 2.1. Escreva um módulo cowpy + +Para ficar com nosso exemplo cowpy, vamos criar um novo processo no nosso fluxo de trabalho, que usa cowpy. Vamos até módulos, criar um novo arquivo e chamá-lo de cowpy nf. Agora vou trapacear um pouco e copiar o código do material de treinamento e apertar salvar. E vamos dar uma olhada. + +Então este é um processo simples. Esperançosamente agora você entende como são os blocos de construção de um processo. Temos nosso publishDir novamente, indo para results. Temos duas entradas, um arquivo de entrada e uma string chamada character. Temos uma saída cowpy input file, e temos um script que parece exatamente o mesmo que o que executamos manualmente dentro da nossa imagem docker há um segundo atrás: cat para imprimir um arquivo, direcionando para cowpy, dizendo qual tipo de caractere cowpy queremos usar, e direcionando isso para o arquivo de saída, que passamos como a saída aqui. + +## 2.2. Adicione cowpy ao fluxo de trabalho + +Ok, vamos voltar ao nosso fluxo de trabalho, importar este novo processo. Então cowpy de modules cowpy nf. Vamos criar um novo parâmetro para que possamos especificar qual caractere queríamos. Vamos dizer Turkey por padrão. E então vamos chamar este novo processo no final do fluxo de trabalho, + +cowpy. E vamos usar a saída aqui de Collect Greetings. Então collect greetings out, out file aqui. E então precisamos de um segundo argumento, que são os novos params que acabamos de fazer. params ponto character. + +## 2.2.4. Execute o fluxo de trabalho para verificar se funciona + +Ok, vamos ver se nosso novo processo funciona. Nextflow run hello containers. Isso deve executar aqueles primeiros três processos e então tentar executar cowpy no final. + +Tivemos um erro. O que está dizendo aqui, cowpy teve um erro e teve um status de saída 127 e com certeza, comando sh cowpy comando não encontrado. + +Não dissemos ao Nextflow que temos uma imagem Docker disponível para cowpy, então ele tentou executá-lo no nosso sistema host e não temos cowpy instalado no nosso sistema host, então disparou um erro. + +## 2.3. Use um contêiner para executá-lo + +Então o que precisamos fazer é precisamos dizer ao Nextflow que temos um contêiner disponível. Vamos ao nosso processo cowpy e vamos adicionar uma nova diretiva no topo do processo chamada container. + +Então encontramos nossa imagem, copiamos a URL, e colocamos isso em uma string. + +Isso não é suficiente por si só porque um pipeline Nextflow pode ter várias maneiras de especificar software. Eu poderia também fazer conda conda-forge cowpy, por exemplo. E o Nextflow precisa saber qual dessas tecnologias você quer usar. + +## 2.3.2. Habilite o uso de Docker via o arquivo nextflow.config + +Então para executar com Docker habilitado, vamos nos adiantar um pouco e usar o arquivo de configuração Nextflow, que é algo que vamos cobrir com mais detalhes no próximo capítulo. Você pode ver neste diretório que temos um arquivo chamado Nextflow Config, e aqui você já tem docker.enabled False. + +Vamos mudar isso para True para habilitar Docker, e então podemos tentar executar o fluxo de trabalho novamente. + +## 2.3.3. Execute o fluxo de trabalho com Docker habilitado + +Nextflow run hello containers nf e desta vez cowpy executou com sucesso. Vamos olhar em Results. cowpy collected test e lá está nosso Turkey. Maravilhoso. + +Então nos bastidores ali, o Nextflow sabia que tinha um contêiner disponível para aquele processo. + +Ele buscou a imagem e executou os comandos para nós. + +## 2.3.4. Inspecione como o Nextflow lançou a tarefa conteinerizada + +Se você está curioso, podemos realmente ver exatamente o que ele fez olhando no diretório work. Se eu fizer code work, e então o hash e então command run, que se você se lembra é o arquivo real que é executado para aquela tarefa, podemos entrar e podemos procurar por uma função chamada NXF launch. E aqui você pode ver o comando docker exato que o Nextflow usou, que parece muito com o que estávamos fazendo manualmente no terminal anteriormente. Docker run. Vinculando este diretório host no contêiner, e então especificando a URL do contêiner. + +Então não há mágica aqui. É apenas que o Nextflow está automaticamente fazendo o trabalho pesado para você de uma forma que significa que você pode facilmente especificar contêineres no seu pipeline, que estão então prontamente disponíveis para qualquer outra pessoa usar que execute seu fluxo de trabalho. E essas pessoas não precisam mais pensar sobre gerenciar software para executar seu pipeline de análise. + +Muito, muito simples, muito conveniente, e também realmente reprodutível. Bom em todos os aspectos. + +Ok, ótimo trabalho. Esse é o fim do Capítulo Cinco. Junte-se a nós no próximo vídeo para a parte seis, que é a parte final deste treinamento Hello Nextflow, onde falaremos sobre configuração Nextflow com mais detalhes. + +Vejo você no próximo vídeo. + +[Transcrição do próximo vídeo :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/pt/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..6622031fd6 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Parte 6: Hello Config - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções completas passo a passo, retorne ao [material do curso](../06_hello_config.md). + + Os números das seções mostrados na transcrição são fornecidos apenas para fins indicativos e podem não incluir todos os números de seção nos materiais. + +## Boas-vindas + +Olá, bem-vindo à parte seis do curso de treinamento Hello Nextflow. + +Este capítulo se chama Hello Config, e é a parte final do nosso curso de treinamento. + +Neste capítulo, vamos falar sobre configuração do Nextflow. A configuração do Nextflow é muito poderosa. Ela nos permite executar o mesmo pipeline em múltiplas infraestruturas computacionais diferentes com diferentes provisionamentos de software e diferentes opções no próprio pipeline. + +Isso significa que você pode pegar pipelines Nextflow construídos por outras pessoas e executá-los no seu sistema, mesmo que eles tenham sido construídos para uma infraestrutura completamente diferente. Esta capacidade de configurar o Nextflow torna os fluxos de trabalho verdadeiramente portáteis e compartilháveis. + +Neste capítulo, usaremos o fluxo de trabalho que construímos nas partes anteriores, mas não vamos editar o código do fluxo de trabalho. Vamos apenas olhar nosso arquivo de configuração do Nextflow e ver como alterar a configuração modifica a forma como o Nextflow é executado. + +Ok, vamos começar. + +Assim como antes, vamos começar indo para training.nextflow.io. Vá para o lado esquerdo em Hello Nextflow e capítulo seis. Hello config. Agora vou entrar no meu ambiente GitHub Codespaces e verificar o script que usaremos. + +## 0. Aquecimento: Verificar que o Docker está habilitado e executar o fluxo de trabalho Hello Config + +Este se chama Hello Config, e está começando de onde estávamos antes. Então parecendo exatamente o mesmo com nossos três parâmetros. Greetings para o arquivo CSV, batch para o nome do lote de saída e character para o nome do cowpy. Temos nossas quatro importações dos diferentes processos, e então temos um fluxo de trabalho onde os encadeamos. + +Na verdade, vou fechar este arquivo agora porque não vamos tocar no arquivo Nextflow em absoluto neste capítulo. Vamos trabalhar puramente dentro do arquivo de configuração. Se eu olhar para o arquivo Nextflow dot config que vimos brevemente no capítulo cinco anterior, podemos ver que temos uma única instrução aqui: Docker enabled equals true, que está dizendo ao Nextflow para usar Docker quando executar este fluxo de trabalho. + +Estou usando Nextflow dot config na raiz do pipeline aqui, que é carregado automaticamente quando executo o Nextflow. Mas lembre-se, o Nextflow pode carregar arquivos de configuração de múltiplos lugares. + +Se eu verificar com Nextflow docs vou para Configuration, você pode ver uma lista desses lugares e uma prioridade na qual eles são carregados. + +Ok. Vamos verificar se nosso fluxo de trabalho está executando como esperamos. Abrir um terminal. Fazer Nextflow. Run. Hello, config. E pressionar enter. Devemos ter esses quatro processos executando, terminando com um comando cowpy. Com certeza, isso funcionou corretamente. Eu tinha o Docker habilitado, puxou o Docker e executou o cowpy para mim, exatamente como fez no final do capítulo cinco. + +## 1. Determinar qual tecnologia de empacotamento de software usar + +Ok. Digamos que estou executando em um HPC e não tenho o Docker instalado. A melhor coisa a fazer neste cenário seria usar Singularity ou Apptainer. Se eu fosse fazer isso, iria para o módulo cowpy e mudaria este contêiner para usar a imagem singularity como mostrei no capítulo anterior, com um oras://, que você também pode obter do Seqera Containers. + +Eu então iria para Nextflow dot config definir Docker enabled para false e fazer singularity enabled equals true. Ou, se usar Apptainer, apptainer enabled equals true e isso funcionaria. + +O Nextflow suporta outras tecnologias também, além de contêineres, algo com que você pode estar familiarizado é conda. Aqui podemos fazer conda enabled equals true e definir Docker para false. conda não usa a mesma diretiva container. Em vez disso, podemos adicionar uma nova aqui chamada conda. Então especificamos o pacote conda que queremos usar. É uma boa prática ser o mais específico possível para tentar tornar o pipeline o mais reproduzível possível. Então vou especificar o canal conda, conda-forge, e então cowpy, e a versão exata, que era 1.1.5. + +Eu também poderia apenas escrever cowpy se quisesse, mas isso poderia resolver para uma versão diferente do cowpy em diferentes execuções do pipeline. + +O legal sobre isso é que não toquei na diretiva docker de forma alguma. Esta imagem Docker ainda está lá. Estou apenas fornecendo duas alternativas agora, e estas podem ser ligadas ou desligadas usando apenas um arquivo de configuração. + +## 1.3. Executar o fluxo de trabalho para verificar que ele pode usar Conda + +Conda está agora habilitado, então vamos experimentar. + +Ótimo. Está executando e você pode ver que há uma mensagem do Nextflow aqui dizendo que o Nextflow está criando um ambiente conda para mim, e está usando este local de cache. + +Nos bastidores, o Nextflow está executando comandos "conda create" para mim para criar um novo ambiente conda isolado com apenas os pacotes que eu quero, e então instalando e buscando esses pacotes conda para que possa executar o processo. + +Você pode ver que levou um pouco de tempo porque estava criando o ambiente e instalando o software pela primeira vez. No entanto, ele armazenou em cache este ambiente, então se eu executar o mesmo comando Nextflow novamente, deve ser muito mais rápido porque ele reutilizará o mesmo ambiente conda. + +Uma das coisas legais sobre isso é que essas diretivas podem ser especificadas no nível do processo, não apenas para o fluxo de trabalho inteiro. Então, se você quiser, pode misturar e combinar qual tecnologia é usada para diferentes processos. + +## 2. Alocar recursos computacionais com diretivas de processo + +O arquivo de configuração do Nextflow pode fazer muito mais do que apenas empacotamento de software. Também podemos dizer ao Nextflow como realmente executar os passos no pipeline. Um exemplo é dizer a um sistema host quais recursos devem ser disponibilizados para cada tarefa em execução. + +Por padrão, o Nextflow não dá muito. Ele dá uma única CPU e apenas dois gigabytes de memória para cada processo. + +Isso é provavelmente algo que gostaríamos de mudar, para que processos que demoram muito para executar possam ter mais recursos e executar mais rapidamente, mas pode ser difícil saber o que alocar para um processo. O Nextflow tem alguns truques legais para ajudá-lo com isso. + +## 2.1. Executar o fluxo de trabalho para gerar um relatório de utilização de recursos + +Vamos executar o fluxo de trabalho novamente. Desta vez, vou adicionar um argumento adicional, que é dash with reports. É uma opção central do Nextflow, então é um único hífen. E então qualquer nome de arquivo que eu goste. Neste caso, vou chamá-lo de report config one html. + +Vou executar o fluxo de trabalho novamente. Vai executar exatamente como antes, mas vai me dar um relatório auxiliar adicional, que você pode ver que apareceu aqui na barra lateral. + +Vou clicar com o botão direito neste arquivo, clicar em download, que o baixa do GitHub Codespaces para o meu sistema local, para que eu possa visualizá-lo facilmente no navegador da web aqui em cima. + +Este relatório pode ser gerado para qualquer execução do Nextflow, e tem muita informação. Começa no topo com alguns metadados sobre qual comando foi usado, quando o fluxo de trabalho foi executado, quanto tempo levou, mas à medida que você rola para baixo, obtemos informações mais detalhadas sobre os recursos que foram usados por cada passo no pipeline. + +Como cada processo é executado várias vezes para diferentes tarefas, temos um gráfico de caixa mostrando a variação dos recursos que usamos para cada processo. + +Se eu rolar um pouco mais para baixo, vejo informações similares sobre memória usada e duração do job. Também leitura e escrita de disco. + +Você pode imaginar que para um pipeline grande com tarefas de longa execução, isso pode ser muito informativo sobre como ajustar finamente a configuração dos recursos que você está solicitando para que você não solicite em excesso, mas também para que você possa fornecer o suficiente para que execute rapidamente. + +Se eu continuar rolando o relatório para baixo, também vemos uma tabela de tarefas, que nos mostra informações detalhadas sobre cada tarefa individual que foi executada no fluxo de trabalho. Isso inclui informações como o script resolvido, que foi executado. + +Ok, vamos voltar ao nosso arquivo de configuração. Vimos que realmente não precisávamos de muito para nosso fluxo de trabalho, então vamos dizer ao Nextflow que só precisamos de um gigabyte de memória para cada processo no fluxo de trabalho. + +Agora, quando definimos assim no nível de processo, isso é aplicado a cada processo individual no pipeline. + +## 2.3. Definir alocações de recursos para um processo individual + +Para fins de argumento, vamos fingir que cowpy está realmente fazendo muito trabalho pesado e precisa de mais recursos do que as outras tarefas. Podemos definir um bloco extra de configuração aqui, que se aplica apenas a esse processo usando, with name cowpy. + +Isso é chamado de seletor de configuração, e podemos definir diferentes padrões aqui para corresponder a diferentes processos. Por exemplo, eu poderia fazer cow star. Então eu sigo isso com algumas chaves e vamos dar dois gigabytes de memória em vez de um e vamos dizer duas CPUs. + +Agora o Nextflow estará dando a cada processo no fluxo de trabalho um gigabyte, exceto por esta solicitação, que é mais específica. Então ela sobrescreve. E apenas para quaisquer processos que são chamados cowpy, receberão dois gigs de memória e duas CPUs. + +Note que o Nextflow é inteligente sobre a utilização de recursos. Então, se você começar a colocar esses números em valores mais altos, verá que o Nextflow começa a enfileirar submissões de jobs uma após a outra, em vez de executar todas em paralelo, para que não solicite em excesso os recursos que estão disponíveis. + +## 2.4. Executar o fluxo de trabalho com a configuração modificada + +Vamos tentar executar o fluxo de trabalho novamente e vamos salvar um novo relatório desta vez. + +Ok, podemos baixar este arquivo e dar uma olhada. + +Sim, sem surpresas, parece basicamente exatamente o mesmo porque este é um fluxo de trabalho fictício, que não está fazendo nada real. Mas você pode imaginar como esta abordagem iterativa de definir limites e fazer fluxos de trabalho da vida real com este tipo de relatório permite que você faça uma abordagem baseada em evidências para definir configuração apropriada e realmente aproveitar ao máximo os recursos computacionais que você tem disponíveis. + +Você pode começar a ser realmente inteligente sobre isso. O Nextflow tem uma capacidade embutida para tentar novamente falhas, e você pode aproveitar em seu arquivo de configuração usando um closure como este e definindo dinamicamente os recursos que são disponibilizados. Então aqui eu disse ao Nextflow para multiplicar aqueles dois gigabytes pela tentativa de retry. Então a segunda tentativa receberá quatro gigs, a terceira tentativa receberá seis gigs e assim por diante. Isso está um pouco além do escopo deste curso de treinamento, mas se você estiver interessado, confira a documentação do Nextflow, que tem uma seção legal sobre lógica de retry dinâmica. + +## 2.5. Adicionar limites de recursos + +Agora, uma coisa que você pode notar sobre isso é que esse tipo de coisa pode tornar muito fácil acidentalmente ir além dos recursos disponíveis no seu sistema. Se você solicitar mais recursos do que estão disponíveis, o Nextflow lançará um erro sobre sua configuração e interromperá a execução. Para evitar isso, você pode usar algo chamado limites de recursos. + +No escopo de processo, em nosso fluxo de trabalho, podemos definir limites de recursos assim, que recebe um array, e podemos especificar a memória máxima, CPUs e tempo que estão disponíveis neste sistema. + +Definir valores altos aqui não aumenta a quantidade de recursos que são solicitados. Ainda vamos usar um gigabyte em nossas solicitações, mas significa que se qualquer uma dessas solicitações chegar a 750, elas atingirão esse teto e nada mais do que isso será solicitado, o que significa que o Nextflow continuará a executar e não travará por causa de recursos indisponíveis. + +Então, esta é uma boa proteção para usar, especialmente se você estiver usando lógica dinâmica com sua alocação de recursos. + +A outra situação onde isso é realmente útil é se você estiver usando pipelines que são públicos e não controlados por você. Eles podem vir com padrões de configuração, e o Nextflow automaticamente tomará a abordagem correta de limitar quaisquer solicitações de recursos para executar em seu sistema. + +Ok, ótimo. Falamos sobre software. Falamos sobre alocação de recursos, e descrevemos diferentes escopos de configuração, tanto para todos os processos quanto para processos específicos. + +## 3. Usar um arquivo de parâmetros para armazenar parâmetros do fluxo de trabalho + +Ok, a seguir vamos voltar nossa atenção para parâmetros. Podemos definir parâmetros no arquivo de configuração assim como fizemos antes no script Nextflow. Então params dot greeting equals hello ou ou usar escopo params e definir foo equals bar. + +E isso é ótimo para definir padrões para seu fluxo de trabalho. No entanto, quando você está executando pipelines, pode ser legal especificar parâmetros em um arquivo JSON ou YAML. + +Usar um arquivo como este é muito melhor do que especificar opções de linha de comando com dash dash. Pois quando você executa um fluxo de trabalho, você pode ter que especificar muitos parâmetros e pode ser tedioso escrevê-los todos em uma única CLI e propenso a erros. Além disso, é improvável que você se lembre de todos os parâmetros que usou, então se você codificar isso em um arquivo, é mais fácil lançar o fluxo de trabalho novamente, usando os mesmos parâmetros no futuro. + +Temos um arquivo de exemplo aqui chamado test params, e você pode ver que isso especifica os três parâmetros que temos em nosso fluxo de trabalho com três valores diferentes. Pessoalmente, acho YAML mais fácil de escrever do que JSON. Então, apenas para demonstrar que funciona, vou criar um novo arquivo chamado Test yaml e copiar estes, me livrar das aspas. E salvar. + +Esses arquivos JSON e YAML podem ser mais fáceis de escrever, pois são sintaxe mais familiar. Mas note que estes são apenas para parâmetros e eles só aceitam sintaxe de chave-valor assim. + +## 3.1. Executar o fluxo de trabalho usando um arquivo de parâmetros + +Vamos experimentar. Fazer o mesmo comando de antes. Livrar-se do relatório e vou fazer dash params file test params yaml. + +Não, esta é uma opção central do Nextflow, então é um único hífen. + +Ok. Executou o fluxo de trabalho e usou os parâmetros naquele arquivo YAML em vez de eu especificá-los todos na linha de comando. Pode parecer exagero apenas para este exemplo simples, mas você pode imaginar se você tem 10 ou 20 parâmetros diferentes, pode ser um incômodo digitar manualmente, e isso é apenas muito mais fácil de editar em um editor de código e manter para fins de reprodutibilidade. + +## 3. Determinar qual(is) executor(es) deve(m) ser usado(s) para fazer o trabalho + +Ok. Falamos sobre empacotamento de software com Docker e conda. Falamos sobre requisitos de recursos de processo com CPUs e memória. E falamos um pouco sobre como especificar parâmetros ao executar fluxos de trabalho. + +As partes finais da configuração realmente são a execução, a infraestrutura computacional subjacente em si, e esta é a verdadeira joia da coroa do Nextflow: que podemos executar esses mesmos fluxos de trabalho em múltiplas infraestruturas computacionais diferentes. + +Na verdade, vou mudar para o material de treinamento escrito por um segundo. Nesta parte do treinamento, podemos ver alguns exemplos diferentes de como diferentes executores, neste caso, escalonadores HPC, definem os requisitos de recursos necessários para submeter um job. + +Então para Slurm, você tem esses cabeçalhos SBATCH, que definem dash dash mem e o número de CPU. Se você está usando PBS, você tem cabeçalhos diferentes, e se você usa Grid Engine, você tem cabeçalhos diferentes novamente. + +Você pode imaginar que é ainda mais diferente se você quiser executar na nuvem, seja AWS batch, Google Cloud, Azure, ou mais. + +Cada uma dessas infraestruturas computacionais subjacentes é chamada de executor e o Nextflow sabe como falar com todos esses diferentes executores para submeter jobs com a sintaxe correta. + +A boa notícia é que você não precisa saber sobre isso. Tudo que você tem que fazer é dizer ao Nextflow, qual executor usar. + +## 3.1. Direcionando para um backend diferente + +Voltamos ao nosso arquivo de configuração e ao processo fazemos executor, e vou digitar local. + +Local é na verdade o padrão, se você não especificar nenhum outro executor, local é o que será usado, e isso apenas significa seu sistema host, onde quer que você tenha lançado o Nextflow, + +Eu poderia especificar em vez disso, Slurm. E isso submeteria jobs Slurm, ou eu poderia dizer AWS batch, e isso submeteria jobs para AWS batch. + +Você precisa de alguma configuração adicional em alguns casos, por exemplo, executar na nuvem precisará de certas credenciais, mas realmente este é o núcleo disso, e pode ser tão simples quanto uma ou duas linhas de configuração para executar seu fluxo de trabalho em um ambiente computacional completamente diferente. + +Mesmo que estejamos executando em um sistema simples dentro do Codespaces, ainda posso brincar com isso um pouco e fingir que estamos executando no Slurm. Se eu então lançar o fluxo de trabalho novamente, Nextflow run, hello config. Vai falhar porque não será capaz de submeter jobs para o Slurm. Mas ainda podemos ir para os diretórios de trabalho e ver o que o Nextflow fez. Então, se formos para este diretório de trabalho e olharmos para Command Run. Você pode ver no topo deste arquivo, agora temos essas linhas de cabeçalho sbatch, que tentaram especificar os recursos necessários para o job Slurm. + +## 4. Usar perfis para selecionar configurações predefinidas + +Ok, estamos quase lá. A parte final deste capítulo é falar sobre perfis de configuração. Se você está executando seu pipeline em vários sistemas diferentes, pode ser irritante ter todos esses arquivos de configuração Nextflow diferentes, que você precisa especificar toda vez. + +Em vez disso, você pode codificar agrupamentos de configuração dentro do seu arquivo Nextflow config, e ligar e desligar esses grupos usando uma flag de perfil. Vamos ver como isso se parece. + +## 4.1. Criar perfis para alternar entre desenvolvimento local e execução em HPC + +Vamos criar dois perfis em nosso exemplo aqui, um para o meu laptop e um para um sistema HPC mais pesado. Vou trapacear um pouco e apenas copiar o código do material de treinamento e colocá-lo aqui. + +Temos um novo escopo chamado profiles, e então temos um nome para cada perfil, que pode ser qualquer coisa. E dentro disso temos configuração, que parece exatamente o mesmo que a configuração de nível superior que já escrevemos. Então, novamente, temos escopo process. Escopo Docker. + +No perfil chamado my laptop. Estou dizendo para executar usando o executor local, então no meu sistema host e usar Docker. + +No perfil university HPC aqui estou dizendo para usar Slurm para submeter jobs, usar conda em vez de Docker, e estou especificando diferentes limites de recursos, que podem corresponder ao tamanho do sistema de nós no HPC que estou usando. + +Por padrão, nenhuma dessas configurações será usada quando eu executar o Nextflow, tenho que especificar que quero usar um desses perfis. + +## 4.2. Executar o fluxo de trabalho com um perfil + +Vamos fazer nextflow run hello config. E vou fazer dash profile, único hífen porque é uma opção central do Nextflow. E então o nome que dei a ele, que é my laptop. O Nextflow deve agora usar o bloco de configuração que foi especificado dentro daquele perfil de configuração, e aplicá-lo quando executar o Nextflow. Se eu quisesse usar o outro bloco de configuração, só tenho que mudar esse nome de perfil. Muito mais fácil de lembrar. Muito mais fácil de usar. + +## 4.3. Criar um perfil de teste + +Note, os perfis podem ter qualquer tipo de configuração, então não precisa estar relacionado ao seu ambiente de execução. Por exemplo, vamos criar um novo perfil aqui, que tem um conjunto de parâmetros. Podemos mudar isso para tux e mudar para my profile, e agora quando fazemos profile test, vai especificar esses parâmetros, que sobrescreverão os parâmetros que são especificados no nível superior do fluxo de trabalho. + +Quando você executa o Nextflow, você pode encadear múltiplos perfis e eles serão aplicados em sequência. + +## 4.4. Executar o fluxo de trabalho localmente com o perfil de teste + +Então posso pegar o comando anterior e fazer vírgula test. Isso aplicará o, my laptop config primeiro, e então aplicará o test config. Se houver alguma sobreposição, então o perfil à direita sobrescreverá qualquer configuração em perfis anteriores. Se eu pressionar enter, vamos ver o que acontece. + +Ok, temos um novo arquivo de resultados aqui. Você pode ver o My Profile, que eu especifiquei como uma das opções. E também podemos ver cowpy, my profile, e com certeza, está o tux. Então funcionou. + +## Conclusão + +Ok! Incrível. É isso. Você chegou ao final do curso. Você ganha um pouco de confete de celebração. Parabéns por terminar este capítulo. + +[Próxima transcrição do vídeo :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/pt/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/pt/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..2a27fee8b3 --- /dev/null +++ b/docs/pt/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Próximos Passos - Transcrição + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Notas importantes" + + Esta página mostra apenas a transcrição. Para instruções completas passo a passo, retorne ao [material do curso](../05_hello_containers.md). + +## Boas-vindas + +Parabéns, você conseguiu. Você completou o primeiro curso de treinamento Nextflow, chamado Hello Nextflow. + +Muito bem. Obrigado por persistir e nós realmente apreciamos o tempo e esforço que você dedicou para aprender Nextflow, e esperamos muito que seja útil para o seu trabalho. + +## Próximos Passos + +Para os próximos passos, fique de olho no portal de treinamento: training.nextflow.io. Estamos colocando novo material de curso lá o tempo todo e também atualizando. Então você pode encontrar treinamento mais avançado, ou treinamento específico para uma área de pesquisa na qual você está interessado. + +Especificamente, confira a página Nextflow for Science. Esta tem uma série de cursos curtos que são independentes, e eles estendem o que você aprendeu no Hello Nextflow para casos de uso específicos. + +Há um para Genômica e também um para RNA-seq. Esperamos trazer mais em breve. + +## Side Quests + +Há muitas coisas que poderíamos ter falado no Hello Nextflow, que teriam sido detalhes demais. Algumas dessas coisas estamos colocando em Side Quests, que são cursos curtos sobre tópicos específicos. + +Há também os cursos maiores de treinamento fundamentals e advanced, que podem incluir conteúdo que você acha interessante. + +## nf-core + +Foi mencionado uma ou duas vezes neste curso, mas definitivamente confira o projeto nf-core. Há mais de cem pipelines lá para diferentes tipos de dados, então é totalmente possível que você não precise construir seu próprio pipeline. + +Há também quase mil e quinhentos módulos de processo onde, se você usar as ferramentas de desenvolvimento nf-core, pode criar um pipeline e importar esses módulos em questão de segundos. + +## Seqera Platform + +Por último, uma propaganda rápida para Seqera Platform. Esta é sem dúvida a melhor maneira de executar Nextflow na prática, é uma plataforma baseada em nuvem, mas você conecta sua própria infraestrutura de computação, seja sua própria conta em nuvem na AWS, Google Batch, ou Azure, ou até mesmo seu próprio HPC. O nível gratuito está disponível para todos, e se você é acadêmico, pode se candidatar ao nosso programa acadêmico para acesso gratuito ao nível pro. + +Seqera Platform vai além de apenas uma interface gráfica para lançar e monitorar fluxos de trabalho. Há também ferramentas adicionais como Data Studios para executar sessões interativas, e ferramentas fundamentais como Fusion, que oferece acesso mais rápido e barato aos dados na nuvem. + +## Suporte e eventos + +Lembre-se, se você encontrar qualquer problema, basta ir para community.seqera.io. Nosso fórum lá é muito ativo, a comunidade Nextflow é super forte e quase sempre há pessoas à disposição prontas para ajudar, seja para treinamento ou qualquer coisa relacionada ao seu uso diário do Nextflow. + +E claro, um ótimo próximo passo é participar de um de nossos eventos comunitários, seja um hackathon nf-core ou um dos eventos Nextflow Summit. Eles são muito divertidos, e seria muito bom conhecê-lo lá e conversar sobre o que você está usando o Nextflow. + +## Agradecimentos + +Gostaria de dar um enorme agradecimento a todos que estiveram envolvidos na escrita deste material de treinamento. Eu estive apresentando, mas realmente todo o trabalho duro foi feito pela equipe de treinamento da Seqera. Especificamente Geraldine, que colocou uma enorme quantidade de trabalho na reescrita deste material. + +Também, Marcel, Ken, Adam, John, outros da equipe de desenvolvimento científico e outros na comunidade. + +## Pesquisa de feedback + +Agora que você terminou o curso, adoraríamos saber o que você achou. Em training.nextflow.io, você encontrará uma pesquisa de feedback abaixo da seção Hello Nextflow. + +São apenas quatro perguntas, mas é muito importante para nós. Se nada mais, nos diz aproximadamente quantas pessoas estão fazendo o treinamento. Também nos diz se você gostou e se você tem alguma sugestão, por favor, deixe no final. Lemos cada envio. + +Se você encontrar algum erro, tudo é código aberto no GitHub, então você pode criar uma issue ou fazer um pull request ou nos enviar uma mensagem no fórum. Adoraríamos ouvir o que você achou e como poderíamos melhorar. Obrigado novamente. Espero vê-lo em breve. diff --git a/docs/pt/docs/hello_nf-core/00_orientation.md b/docs/pt/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..5ecc230d82 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Primeiros Passos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Iniciar um ambiente de treinamento + +Para usar o ambiente pré-construído que fornecemos no GitHub Codespaces, clique no botão "Open in GitHub Codespaces" abaixo. Para outras opções, consulte [Opções de ambiente](../envsetup/index.md). + +Recomendamos abrir o ambiente de treinamento em uma nova aba ou janela do navegador (use clique-direito, ctrl+clique ou cmd+clique dependendo do seu equipamento) para que você possa continuar lendo enquanto o ambiente carrega. +Você precisará manter estas instruções abertas em paralelo para trabalhar no curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Básico do ambiente + +Este ambiente de treinamento contém todo o software, código e dados necessários para trabalhar no curso de treinamento, então você não precisa instalar nada por conta própria. + +O codespace é configurado com uma interface VSCode, que inclui um explorador de sistema de arquivos, um editor de código e um terminal shell. +Todas as instruções dadas durante o curso (por exemplo, 'abra o arquivo', 'edite o código' ou 'execute este comando') referem-se a essas três partes da interface VSCode, salvo especificação em contrário. + +Se você está trabalhando neste curso por conta própria, por favor familiarize-se com o [básico do ambiente](../envsetup/01_setup.md) para mais detalhes. + +### Requisitos de versão + +Este treinamento é projetado para **Nextflow 25.10.2** ou posterior **com o analisador de sintaxe v2 DESABILITADO**. + +#### Se você está usando nosso ambiente de treinamento: + +Você DEVE executar o seguinte comando antes de prosseguir: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Se você está usando um ambiente local ou personalizado: + +Por favor certifique-se de que está usando as configurações corretas conforme documentado [aqui](../info/nxf_versions.md). + +O treinamento adicionalmente requer **nf-core tools 3.4.1**. +Se você usar uma versão diferente das ferramentas nf-core, você pode ter dificuldades em acompanhar. + +Você pode verificar qual versão está instalada em seu ambiente usando o comando `nf-core --version`. + +## Prepare-se para trabalhar + +Uma vez que seu codespace esteja executando, há duas coisas que você precisa fazer antes de mergulhar no treinamento: configurar seu diretório de trabalho para este curso específico e dar uma olhada nos materiais fornecidos. + +### Configurar o diretório de trabalho + +Por padrão, o codespace abre com o diretório de trabalho configurado na raiz de todos os cursos de treinamento, mas para este curso, trabalharemos no diretório `hello-nf-core/`. + +Mude de diretório agora executando este comando no terminal: + +```bash +cd hello-nf-core/ +``` + +!!! tip "Dica" + + Se por algum motivo você sair deste diretório (por exemplo, seu codespace entrar em modo de espera), você sempre pode usar o caminho completo para retornar a ele, assumindo que você está executando isto dentro do ambiente de treinamento GitHub Codespaces: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Agora vamos dar uma olhada no conteúdo deste diretório. + +### Explorar os materiais fornecidos + +Você pode explorar o conteúdo deste diretório usando o explorador de arquivos no lado esquerdo do espaço de trabalho de treinamento. +Alternativamente, você pode usar o comando `tree`. + +Durante o curso, usamos a saída de `tree` para representar a estrutura e conteúdo do diretório de forma legível, às vezes com pequenas modificações para maior clareza. + +Aqui geramos um índice até o segundo nível: + +```bash +tree . -L 2 +``` + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Clique na caixa colorida para expandir a seção e visualizar seu conteúdo. +Usamos seções recolhíveis como esta para incluir a saída esperada de comandos de forma concisa. + +- **O arquivo `greetings.csv`** é um CSV contendo alguns dados colunares mínimos que usamos para fins de teste. + +- **O diretório `original-hello`** contém uma cópia do código fonte produzido ao trabalhar na série completa de treinamento Hello Nextflow (com Docker habilitado). + +- **O diretório `solutions`** contém os scripts de fluxo de trabalho completos que resultam de cada etapa do curso. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + +## Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu ambiente está ativo e funcionando +- [ ] Eu me certifiquei de que o analisador de sintaxe está configurado para **v1** +- [ ] Eu configurei meu diretório de trabalho apropriadamente + +Se você pode marcar todas as caixas, você está pronto para começar. + +**Para continuar para a Parte 1, clique na seta no canto inferior direito desta página.** diff --git a/docs/pt/docs/hello_nf-core/01_run_demo.md b/docs/pt/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..6a99d25901 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,645 @@ +# Parte 1: Executar um pipeline de demonstração + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta primeira parte do curso de treinamento Hello nf-core, mostramos como encontrar e experimentar um pipeline do nf-core, entender como o código é organizado e reconhecer como ele difere do código Nextflow simples, conforme mostrado em [Hello Nextflow](../hello_nextflow/index.md). + +Vamos usar um pipeline chamado nf-core/demo que é mantido pelo projeto nf-core como parte de seu inventário de pipelines para demonstrar estrutura de código e operações de ferramentas. + +Certifique-se de que seu diretório de trabalho esteja definido como `hello-nf-core/` conforme instruído na página [Primeiros passos](./00_orientation.md). + +--- + +## 1. Encontrar e recuperar o pipeline nf-core/demo + +Vamos começar localizando o pipeline nf-core/demo no site do projeto em [nf-co.re](https://nf-co.re), que centraliza todas as informações, como: documentação geral e artigos de ajuda, documentação para cada um dos pipelines, posts de blog, anúncios de eventos e assim por diante. + +### 1.1. Encontrar o pipeline no site + +No seu navegador web, vá para [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) e digite `demo` na barra de pesquisa. + +![search results](./img/search-results.png) + +Clique no nome do pipeline, `demo`, para acessar a página de documentação do pipeline. + +Cada pipeline lançado tem uma página dedicada que inclui as seguintes seções de documentação: + +- **Introduction:** Uma introdução e visão geral do pipeline +- **Usage:** Descrições de como executar o pipeline +- **Parameters:** Parâmetros do pipeline agrupados com descrições +- **Output:** Descrições e exemplos dos arquivos de saída esperados +- **Results:** Exemplos de arquivos de saída gerados a partir do conjunto de dados de teste completo +- **Releases & Statistics:** Histórico de versões do pipeline e estatísticas + +Sempre que você estiver considerando adotar um novo pipeline, você deve ler a documentação do pipeline cuidadosamente primeiro para entender o que ele faz e como deve ser configurado antes de tentar executá-lo. + +Dê uma olhada agora e veja se você consegue descobrir: + +- Quais ferramentas o pipeline executará (Verifique a aba: `Introduction`) +- Quais entradas e parâmetros o pipeline aceita ou requer (Verifique a aba: `Parameters`) +- Quais são as saídas produzidas pelo pipeline (Verifique a aba: `Output`) + +#### 1.1.1. Visão geral do pipeline + +A aba `Introduction` fornece uma visão geral do pipeline, incluindo uma representação visual (chamada de mapa de metrô) e uma lista de ferramentas que são executadas como parte do pipeline. + +![pipeline subway map](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Exemplo de linha de comando + +A documentação também fornece um arquivo de entrada de exemplo (discutido mais adiante) e um exemplo de linha de comando. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Você notará que o comando de exemplo NÃO especifica um arquivo de fluxo de trabalho, apenas a referência ao repositório do pipeline, `nf-core/demo`. + +Quando invocado dessa forma, o Nextflow assumirá que o código está organizado de uma certa maneira. +Vamos recuperar o código para que possamos examinar essa estrutura. + +### 1.2. Recuperar o código do pipeline + +Depois de determinarmos que o pipeline parece ser adequado para nossos propósitos, vamos experimentá-lo. +Felizmente, o Nextflow facilita a recuperação de pipelines de repositórios formatados corretamente sem precisar baixar nada manualmente. + +Vamos retornar ao terminal e executar o seguinte: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Saída do comando" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +O Nextflow faz um `pull` do código do pipeline, o que significa que ele baixa o repositório completo para sua unidade local. + +Para ser claro, você pode fazer isso com qualquer pipeline Nextflow que esteja configurado adequadamente no GitHub, não apenas pipelines do nf-core. +No entanto, o nf-core é a maior coleção de código aberto de pipelines Nextflow. + +Você pode fazer o Nextflow fornecer uma lista de quais pipelines você recuperou dessa maneira: + +```bash +nextflow list +``` + +??? success "Saída do comando" + + ```console + nf-core/demo + ``` + +Você notará que os arquivos não estão no seu diretório de trabalho atual. +Por padrão, o Nextflow os salva em `$NXF_HOME/assets`. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Conteúdo do diretório" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note "Nota" + + O caminho completo pode ser diferente no seu sistema se você não estiver usando nosso ambiente de treinamento. + +O Nextflow mantém o código-fonte baixado intencionalmente 'fora do caminho' com base no princípio de que esses pipelines devem ser usados mais como bibliotecas do que código com o qual você interagiria diretamente. + +No entanto, para os propósitos deste treinamento, queremos poder explorar e ver o que há lá dentro. +Então, para facilitar isso, vamos criar um link simbólico para esse local a partir do nosso diretório de trabalho atual. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Isso cria um atalho que facilita a exploração do código que acabamos de baixar. + +```bash +tree -L 2 pipelines +``` + +```console title="Conteúdo do diretório" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Agora podemos espiar o código-fonte mais facilmente conforme necessário. + +Mas primeiro, vamos tentar executar nosso primeiro pipeline do nf-core! + +### Conclusão + +Agora você sabe como encontrar um pipeline através do site do nf-core e recuperar uma cópia local do código-fonte. + +### Qual é o próximo passo? + +Aprenda como experimentar um pipeline do nf-core com o mínimo de esforço. + +--- + +## 2. Experimentar o pipeline com seu perfil de teste + +Convenientemente, todo pipeline do nf-core vem com um perfil de teste. +Este é um conjunto mínimo de configurações para o pipeline executar usando um pequeno conjunto de dados de teste hospedado no repositório [nf-core/test-datasets](https://github.com/nf-core/test-datasets). +É uma ótima maneira de experimentar rapidamente um pipeline em pequena escala. + +!!! note "Nota" + + O sistema de perfil de configuração do Nextflow permite que você alterne facilmente entre diferentes motores de contêiner ou ambientes de execução. + Para mais detalhes, consulte [Hello Nextflow Parte 6: Configuração](../hello_nextflow/06_hello_config.md). + +### 2.1. Examinar o perfil de teste + +É uma boa prática verificar o que o perfil de teste de um pipeline especifica antes de executá-lo. +O perfil `test` para `nf-core/demo` está no arquivo de configuração `conf/test.config` e é mostrado abaixo. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dados de entrada + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Você notará imediatamente que o bloco de comentário no topo inclui um exemplo de uso mostrando como executar o pipeline com este perfil de teste. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +As únicas coisas que precisamos fornecer são o que é mostrado entre colchetes angulares no comando de exemplo: `<docker/singularity>` e `<OUTDIR>`. + +Como lembrete, `<docker/singularity>` refere-se à escolha do sistema de contêiner. Todos os pipelines do nf-core são projetados para serem usáveis com contêineres (Docker, Singularity, etc.) para garantir reprodutibilidade e eliminar problemas de instalação de software. +Então precisaremos especificar se queremos usar Docker ou Singularity para testar o pipeline. + +A parte `--outdir <OUTDIR>` refere-se ao diretório onde o Nextflow escreverá as saídas do pipeline. +Precisamos fornecer um nome para ele, que podemos simplesmente inventar. +Se ainda não existir, o Nextflow o criará para nós em tempo de execução. + +Seguindo para a seção após o bloco de comentário, o perfil de teste nos mostra o que foi pré-configurado para teste: mais notavelmente, o parâmetro `input` já está configurado para apontar para um conjunto de dados de teste, então não precisamos fornecer nossos próprios dados. +Se você seguir o link para a entrada pré-configurada, verá que é um arquivo csv contendo identificadores de amostra e caminhos de arquivo para várias amostras experimentais. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Isso é chamado de planilha de amostras e é a forma mais comum de entrada para pipelines do nf-core. + +!!! note "Nota" + + Não se preocupe se você não estiver familiarizado com os formatos e tipos de dados, isso não é importante para o que se segue. + +Então isso confirma que temos tudo o que precisamos para experimentar o pipeline. + +### 2.2. Executar o pipeline + +Vamos decidir usar Docker para o sistema de contêiner e `demo-results` como o diretório de saída, e estamos prontos para executar o comando de teste: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Se sua saída corresponder a isso, parabéns! Você acabou de executar seu primeiro pipeline do nf-core. + +Você notará que há muito mais saída no console do que quando você executa um pipeline Nextflow básico. +Há um cabeçalho que inclui um resumo da versão do pipeline, entradas e saídas, e alguns elementos de configuração. + +!!! note "Nota" + + Sua saída mostrará carimbos de data/hora, nomes de execução e caminhos de arquivo diferentes, mas a estrutura geral e a execução do processo devem ser semelhantes. + +Seguindo para a saída de execução, vamos dar uma olhada nas linhas que nos dizem quais processos foram executados: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Isso nos diz que três processos foram executados, correspondendo às três ferramentas mostradas na página de documentação do pipeline no site do nf-core: FASTQC, SEQTK_TRIM e MULTIQC. + +Os nomes completos dos processos como mostrado aqui, como `NFCORE_DEMO:DEMO:MULTIQC`, são mais longos do que o que você pode ter visto no material introdutório do Hello Nextflow. +Estes incluem os nomes de seus fluxos de trabalho pai e refletem a modularidade do código do pipeline. +Vamos entrar em mais detalhes sobre isso daqui a pouco. + +### 2.3. Examinar as saídas do pipeline + +Finalmente, vamos dar uma olhada no diretório `demo-results` produzido pelo pipeline. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Conteúdo do diretório" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Isso pode parecer muito. +Para saber mais sobre as saídas do pipeline `nf-core/demo`, consulte sua [página de documentação](https://nf-co.re/demo/1.0.2/docs/output/). + +Nesta etapa, o que é importante observar é que os resultados são organizados por módulo, e há adicionalmente um diretório chamado `pipeline_info` contendo vários relatórios com carimbos de data/hora sobre a execução do pipeline. + +Por exemplo, o arquivo `execution_timeline_*` mostra quais processos foram executados, em que ordem e quanto tempo levaram para executar: + +![execution timeline report](./img/execution_timeline.png) + +!!! note "Nota" + + Aqui as tarefas não foram executadas em paralelo porque estamos executando em uma máquina minimalista no Github Codespaces. + Para ver essas execuções em paralelo, tente aumentar a alocação de CPU do seu codespace e os limites de recursos na configuração de teste. + +Esses relatórios são gerados automaticamente para todos os pipelines do nf-core. + +### Conclusão + +Você sabe como executar um pipeline do nf-core usando seu perfil de teste integrado e onde encontrar suas saídas. + +### Qual é o próximo passo? + +Aprenda como o código do pipeline é organizado. + +--- + +## 3. Examinar a estrutura do código do pipeline + +Agora que executamos o pipeline com sucesso como usuários, vamos mudar nossa perspectiva para ver como os pipelines do nf-core são estruturados internamente. + +O projeto nf-core impõe diretrizes fortes sobre como os pipelines são estruturados e como o código é organizado, configurado e documentado. +Entender como tudo isso é organizado é o primeiro passo para desenvolver seus próprios pipelines compatíveis com o nf-core, que abordaremos na Parte 2 deste curso. + +Vamos dar uma olhada em como o código do pipeline está organizado no repositório `nf-core/demo`, usando o link simbólico `pipelines` que criamos anteriormente. + +Você pode usar `tree` ou usar o explorador de arquivos para encontrar e abrir o diretório `nf-core/demo`. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Conteúdo do diretório" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Há muita coisa acontecendo lá, então vamos abordar isso passo a passo. + +Primeiro, vamos observar que no nível superior, você pode encontrar um arquivo README com informações resumidas, bem como arquivos acessórios que resumem informações do projeto, como licenciamento, diretrizes de contribuição, citação e código de conduta. +A documentação detalhada do pipeline está localizada no diretório `docs`. +Todo esse conteúdo é usado para gerar as páginas da web no site do nf-core programaticamente, então elas estão sempre atualizadas com o código. + +Agora, para o resto, vamos dividir nossa exploração em três etapas: + +1. Componentes de código do pipeline (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Configuração do pipeline +3. Entradas e validação + +Vamos começar com os componentes de código do pipeline. +Vamos nos concentrar na hierarquia de arquivos e na organização estrutural, em vez de mergulhar no código dentro de arquivos individuais. + +### 3.1. Componentes de código do pipeline + +A organização padrão de código de pipeline do nf-core segue uma estrutura modular que é projetada para maximizar a reutilização de código, conforme introduzido em [Hello Modules](../hello_nextflow/04_hello_modules.md), Parte 4 do curso [Hello Nextflow](../hello_nextflow/index.md), embora no verdadeiro estilo nf-core, isso seja implementado com um pouco de complexidade adicional. +Especificamente, os pipelines do nf-core fazem uso abundante de subworkflows, ou seja, scripts de fluxo de trabalho que são importados por um fluxo de trabalho pai. + +Isso pode parecer um pouco abstrato, então vamos dar uma olhada em como isso é usado na prática no pipeline `nf-core/demo`. + +!!! note "Nota" + + Não vamos passar pelo código real de _como_ esses componentes modulares são conectados, porque há alguma complexidade adicional associada ao uso de subworkflows que pode ser confusa, e entender isso não é necessário nesta etapa do treinamento. + Por enquanto, vamos nos concentrar na organização geral e na lógica. + +#### 3.1.1. Visão geral geral + +Aqui está como são as relações entre os componentes de código relevantes para o pipeline `nf-core/demo`: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +Há um script chamado _ponto de entrada_ chamado `main.nf`, que atua como um wrapper para dois tipos de fluxos de trabalho aninhados: o fluxo de trabalho contendo a lógica de análise real, localizado em `workflows/` e chamado `demo.nf`, e um conjunto de fluxos de trabalho de manutenção localizados em `subworkflows/`. +O fluxo de trabalho `demo.nf` chama **módulos** localizados em `modules/`; estes contêm os **processos** que realizarão as etapas de análise reais. + +!!! note "Nota" + + Subworkflows não estão limitados a funções de manutenção, e eles podem fazer uso de módulos de processo. + + O pipeline `nf-core/demo` mostrado aqui acontece de estar no lado mais simples do espectro, mas outros pipelines do nf-core (como `nf-core/rnaseq`) utilizam subworkflows que estão envolvidos na análise real. + +Agora, vamos revisar esses componentes por vez. + +#### 3.1.2. O script de ponto de entrada: `main.nf` + +O script `main.nf` é o ponto de entrada de onde o Nextflow começa quando executamos `nextflow run nf-core/demo`. +Isso significa que quando você executa `nextflow run nf-core/demo` para executar o pipeline, o Nextflow automaticamente encontra e executa o script `main.nf`. +Isso funciona para qualquer pipeline Nextflow que segue essa nomeação e estrutura convencional, não apenas pipelines do nf-core. + +Usar um script de ponto de entrada facilita a execução de subworkflows de 'manutenção' padronizados antes e depois da execução do script de análise real. +Vamos passar por eles depois de revisarmos o fluxo de trabalho de análise real e seus módulos. + +#### 3.1.3. O script de análise: `workflows/demo.nf` + +O fluxo de trabalho `workflows/demo.nf` é onde a lógica central do pipeline é armazenada. +Ele é estruturado muito como um fluxo de trabalho Nextflow normal, exceto que é projetado para ser chamado de um fluxo de trabalho pai, o que requer alguns recursos extras. +Vamos cobrir as diferenças relevantes na próxima parte deste curso, quando abordaremos a conversão do pipeline Hello simples do Hello Nextflow em uma forma compatível com o nf-core. + +O fluxo de trabalho `demo.nf` chama **módulos** localizados em `modules/`, que revisaremos a seguir. + +!!! note "Nota" + + Alguns fluxos de trabalho de análise do nf-core exibem níveis adicionais de aninhamento ao chamar subworkflows de nível inferior. + Isso é usado principalmente para envolver dois ou mais módulos que são comumente usados juntos em segmentos de pipeline facilmente reutilizáveis. + Você pode ver alguns exemplos navegando pelos [subworkflows do nf-core](https://nf-co.re/subworkflows/) disponíveis no site do nf-core. + + Quando o script de análise usa subworkflows, eles são armazenados no diretório `subworkflows/`. + +#### 3.1.4. Os módulos + +Os módulos são onde o código do processo reside, conforme descrito na [Parte 4 do curso de treinamento Hello Nextflow](../hello_nextflow/04_hello_modules.md). + +No projeto nf-core, os módulos são organizados usando uma estrutura aninhada de vários níveis que reflete tanto sua origem quanto seu conteúdo. +No nível superior, os módulos são diferenciados como `nf-core` ou `local` (não parte do projeto nf-core), e depois colocados em um diretório nomeado com base na(s) ferramenta(s) que eles envolvem. +Se a ferramenta pertence a um kit de ferramentas (ou seja, um pacote contendo várias ferramentas), então há um nível de diretório intermediário nomeado com base no kit de ferramentas. + +Você pode ver isso aplicado na prática aos módulos do pipeline `nf-core/demo`: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Conteúdo do diretório" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Aqui você vê que os módulos `fastqc` e `multiqc` estão no nível superior dentro dos módulos `nf-core`, enquanto o módulo `trim` está sob o kit de ferramentas ao qual pertence, `seqtk`. +Neste caso, não há módulos `local`. + +O arquivo de código do módulo que descreve o processo sempre se chama `main.nf`, e é acompanhado por testes e arquivos `.yml` que vamos ignorar por enquanto. + +Considerados em conjunto, o fluxo de trabalho de ponto de entrada, fluxo de trabalho de análise e módulos são suficientes para executar as partes 'interessantes' do pipeline. +No entanto, sabemos que também há subworkflows de manutenção lá, então vamos olhar para eles agora. + +#### 3.1.5. Os subworkflows de manutenção + +Como módulos, subworkflows são diferenciados em diretórios `local` e `nf-core`, e cada subworkflow tem sua própria estrutura de diretório aninhada com seu próprio script `main.nf`, testes e arquivo `.yml`. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Conteúdo do diretório" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Como observado acima, o pipeline `nf-core/demo` não inclui nenhum subworkflow específico de análise, então todos os subworkflows que vemos aqui são chamados fluxos de trabalho de 'manutenção' ou 'utilitário', como denotado pelo prefixo `utils_` em seus nomes. +Esses subworkflows são o que produz o cabeçalho sofisticado do nf-core na saída do console, entre outras funções acessórias. + +!!! tip "Dica" + + Além de seu padrão de nomenclatura, outra indicação de que esses subworkflows não executam nenhuma função verdadeiramente relacionada à análise é que eles não chamam nenhum processo. + +Isso completa o resumo dos componentes de código principais que constituem o pipeline `nf-core/demo`. +Agora vamos dar uma olhada nos elementos restantes que você deve saber um pouco antes de mergulhar no desenvolvimento: configuração do pipeline e validação de entrada. + +### 3.2. Configuração do pipeline + +Você aprendeu anteriormente que o Nextflow oferece muitas opções para configurar a execução do pipeline, seja em termos de entradas e parâmetros, recursos de computação e outros aspectos de orquestração. +O projeto nf-core aplica diretrizes altamente padronizadas para configuração de pipeline que visam construir sobre as opções de personalização flexíveis do Nextflow de uma maneira que forneça maior consistência e manutenibilidade entre os pipelines. + +O arquivo de configuração central `nextflow.config` é usado para definir valores padrão para parâmetros e outras opções de configuração. +A maioria dessas opções de configuração são aplicadas por padrão, enquanto outras (por exemplo, perfis de dependência de software) são incluídas como perfis opcionais. + +Existem vários arquivos de configuração adicionais que são armazenados na pasta `conf` e que podem ser adicionados à configuração por padrão ou opcionalmente como perfis: + +- `base.config`: Um arquivo de configuração 'em branco', apropriado para uso geral na maioria dos ambientes de computação de alto desempenho. Isso define bins amplos de uso de recursos, por exemplo, que são convenientes para aplicar aos módulos. +- `modules.config`: Diretivas de módulo adicionais e argumentos. +- `test.config`: Um perfil para executar o pipeline com dados de teste mínimos, que usamos quando executamos o pipeline de demonstração. +- `test_full.config`: Um perfil para executar o pipeline com um conjunto de dados de teste de tamanho completo. + +Vamos tocar em alguns desses arquivos mais tarde no curso. + +### 3.3. Entradas e validação + +Como observamos anteriormente, quando examinamos o perfil de teste do pipeline `nf-core/demo`, ele foi projetado para receber como entrada uma planilha de amostras contendo caminhos de arquivo e identificadores de amostra. +Os caminhos de arquivo vinculados a dados reais localizados no repositório `nf-core/test-datasets`. + +Um exemplo de planilha de amostras também é fornecido no diretório `assets`, embora os caminhos neste não sejam reais. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Esta planilha de amostras específica é bastante simples, mas alguns pipelines são executados em planilhas de amostras que são mais complexas, com muito mais metadados associados às entradas primárias. + +Infelizmente, como esses arquivos podem ser difíceis de verificar visualmente, a formatação inadequada de dados de entrada é uma fonte muito comum de falhas de pipeline. +Um problema relacionado é quando os parâmetros são fornecidos incorretamente. + +A solução para esses problemas é executar verificações de validação automatizadas em todos os arquivos de entrada para garantir que eles contenham os tipos esperados de informação, formatados corretamente, e em parâmetros para garantir que sejam do tipo esperado. +Isso é chamado de validação de entrada e, idealmente, deve ser feito _antes_ de tentar executar um pipeline, em vez de esperar que o pipeline falhe para descobrir que havia um problema com as entradas. + +Assim como para configuração, o projeto nf-core é muito opinativo sobre validação de entrada e recomenda o uso do [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/), um plugin Nextflow que fornece recursos abrangentes de validação para pipelines Nextflow. + +Vamos cobrir este tópico com mais detalhes na Parte 5 deste curso. +Por enquanto, apenas esteja ciente de que existem dois arquivos JSON fornecidos para esse propósito, `nextflow_schema.json` e `assets/schema_input.json`. + +O `nextflow_schema.json` é um arquivo usado para armazenar informações sobre os parâmetros do pipeline, incluindo tipo, descrição e texto de ajuda em um formato legível por máquina. +Isso é usado para vários propósitos, incluindo validação automatizada de parâmetros, geração de texto de ajuda e renderização interativa de formulário de parâmetros em interfaces de UI. + +O `schema_input.json` é um arquivo usado para definir a estrutura da planilha de amostras de entrada. +Cada coluna pode ter um tipo, padrão, descrição e texto de ajuda em um formato legível por máquina. +O schema é usado para vários propósitos, incluindo validação automatizada e fornecimento de mensagens de erro úteis. + +### Conclusão + +Você sabe quais são os principais componentes de um pipeline do nf-core e como o código é organizado; onde os elementos principais de configuração estão localizados; e está ciente de para que serve a validação de entrada. + +### Qual é o próximo passo? + +Faça uma pausa! Foi muita coisa. Quando você estiver se sentindo renovado e pronto, passe para a próxima seção para aplicar o que você aprendeu para escrever um pipeline compatível com o nf-core. + +!!! tip "Dica" + + Se você gostaria de aprender como compor fluxos de trabalho com subworkflows antes de passar para a próxima parte, confira a [Missão Secundária Workflows de Workflows](../side_quests/workflows_of_workflows.md). diff --git a/docs/pt/docs/hello_nf-core/02_rewrite_hello.md b/docs/pt/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..71ae8534cd --- /dev/null +++ b/docs/pt/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1434 @@ +# Parte 2: Reescrever Hello para nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta segunda parte do curso de treinamento Hello nf-core, mostramos como criar uma versão compatível com nf-core do pipeline produzido no curso para iniciantes [Hello Nextflow](../hello_nextflow/index.md). + +Você deve ter notado na primeira seção do treinamento que os pipelines nf-core seguem uma estrutura bastante elaborada com muitos arquivos acessórios. +Criar tudo isso do zero seria muito tedioso, então a comunidade nf-core desenvolveu ferramentas para fazer isso a partir de um template, para inicializar o processo. + +Vamos mostrar como usar essas ferramentas para criar uma estrutura de pipeline e então adaptar o código de pipeline 'regular' existente para a estrutura nf-core. + +Se você não está familiarizado com o pipeline Hello ou precisa relembrar, consulte [esta página de informações](../info/hello_pipeline.md). + +--- + +## 1. Criar um novo projeto de pipeline + +Primeiro, criamos a estrutura para o novo pipeline. + +!!! note "Nota" + + Certifique-se de estar no diretório `hello-nf-core` no seu terminal. + +### 1.1. Executar a ferramenta de criação de pipeline baseada em template + +Vamos começar criando um novo pipeline com o comando `nf-core pipelines create`. +Isso criará uma nova estrutura de pipeline usando o template base nf-core, customizado com um nome de pipeline, descrição e autor. + +```bash +nf-core pipelines create +``` + +Executar este comando abrirá uma Interface de Usuário de Texto (TUI) para criação de pipeline: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Esta TUI pedirá que você forneça informações básicas sobre seu pipeline e oferecerá uma escolha de recursos para incluir ou excluir na estrutura do seu pipeline. + +- Na tela de boas-vindas, clique em **Let's go!**. +- Na tela `Choose pipeline type`, clique em **Custom**. +- Insira os detalhes do seu pipeline como a seguir (substituindo `< SEU NOME >` pelo seu próprio nome), então clique em **Next**. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < SEU NOME > +``` + +- Na tela Template features, defina `Toggle all features` como **off**, então **habilite** seletivamente os seguintes. Verifique suas seleções e clique em **Continue**. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- Na tela `Final details`, clique em **Finish**. Aguarde o pipeline ser criado, então clique em **Continue**. +- Na tela Create GitHub repository, clique em **Finish without creating a repo**. Isso exibirá instruções para criar um repositório GitHub posteriormente. Ignore-as e clique em **Close**. + +Quando a TUI fechar, você deverá ver a seguinte saída no console. + +??? success "Saída do comando" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +Não há confirmação explícita na saída do console de que a criação do pipeline funcionou, mas você deverá ver um novo diretório chamado `core-hello`. + +Visualize o conteúdo do novo diretório para ver quanto trabalho você economizou usando o template. + +```bash +tree core-hello +``` + +??? abstract "Conteúdo do diretório" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +São muitos arquivos! + +Esperamos que você reconheça muitos deles como os mesmos que encontramos quando exploramos a estrutura do pipeline `nf-core/demo`. +Mas não se preocupe se ainda estiver se sentindo um pouco perdido; vamos percorrer as partes importantes juntos no decorrer deste treinamento. + +!!! note "Nota" + + Uma diferença importante em comparação com o pipeline `nf-core/demo` que examinamos na primeira parte deste treinamento é que não há diretório `modules`. + Isso ocorre porque não optamos por incluir nenhum dos módulos padrão nf-core. + +### 1.2. Testar que a estrutura é funcional + +Acredite ou não, mesmo que você ainda não tenha adicionado nenhum módulo para fazer trabalho real, a estrutura do pipeline pode realmente ser executada usando o perfil de teste, da mesma forma que executamos o pipeline `nf-core/demo`. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Isso mostra que toda a configuração básica está no lugar. +Então onde estão as saídas? Existem algumas? + +Na verdade, um novo diretório de resultados chamado `core-hello-results` foi criado contendo os relatórios de execução padrão: + +```bash +tree core-hello-results +``` + +??? abstract "Conteúdo do diretório" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Você pode dar uma olhada nos relatórios para ver o que foi executado, e a resposta é: nada! + +![relatório de timeline de execução vazio](./img/execution_timeline_empty.png) + +Vamos dar uma olhada no que realmente está no código. + +### 1.3. Examinar o fluxo de trabalho placeholder + +Se você olhar dentro do arquivo `main.nf`, verá que ele importa um fluxo de trabalho chamado `HELLO` de `workflows/hello`. + +Isso é equivalente ao fluxo de trabalho `workflows/demo.nf` que encontramos na Parte 1, e serve como um fluxo de trabalho placeholder para nosso fluxo de trabalho de interesse, com alguma funcionalidade nf-core já implementada. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Comparado a um fluxo de trabalho Nextflow básico como o desenvolvido em [Hello Nextflow](../hello_nextflow/index.md), você notará algumas coisas novas aqui (linhas destacadas acima): + +- O bloco workflow tem um nome +- As entradas do fluxo de trabalho são declaradas usando a palavra-chave `take:` e a construção do canal é movida para o fluxo de trabalho pai +- O conteúdo do fluxo de trabalho é colocado dentro de um bloco `main:` +- As saídas são declaradas usando a palavra-chave `emit:` + +Esses são recursos opcionais do Nextflow que tornam o fluxo de trabalho **componível**, o que significa que ele pode ser chamado de dentro de outro fluxo de trabalho. + +!!! note "Fluxos de trabalho componíveis em profundidade" + + A [Side Quest Workflows of Workflows](../side_quests/workflows_of_workflows.md) explora a composição de fluxos de trabalho em muito mais profundidade, incluindo como compor múltiplos fluxos de trabalho juntos e gerenciar fluxos de dados complexos entre eles. Estamos introduzindo a componibilidade aqui porque é um requisito fundamental da arquitetura de template nf-core, que usa fluxos de trabalho aninhados para organizar a inicialização do pipeline, o fluxo de trabalho de análise principal e tarefas de conclusão em componentes separados e reutilizáveis. + +Vamos precisar conectar a lógica relevante do nosso fluxo de trabalho de interesse nessa estrutura. +O primeiro passo para isso é tornar nosso fluxo de trabalho original componível. + +### Conclusão + +Agora você sabe como criar uma estrutura de pipeline usando ferramentas nf-core. + +### O que vem a seguir? + +Aprenda como tornar um fluxo de trabalho simples componível como prelúdio para torná-lo compatível com nf-core. + +--- + +## 2. Tornar o fluxo de trabalho Hello Nextflow original componível + +Agora é hora de trabalhar na integração do nosso fluxo de trabalho na estrutura nf-core. +Como lembrete, estamos trabalhando com o fluxo de trabalho apresentado no nosso curso de treinamento [Hello Nextflow](../hello_nextflow/index.md). + +!!! tip "Dica" + + Se você não está familiarizado com esse pipeline ou precisa relembrar, consulte [O pipeline Hello](../info/hello_pipeline.md). + +Fornecemos uma cópia limpa e totalmente funcional do fluxo de trabalho Hello Nextflow completo no diretório `original-hello` junto com seus módulos e o arquivo CSV padrão que ele espera usar como entrada. + +```bash +tree original-hello/ +``` + +??? abstract "Conteúdo do diretório" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Sinta-se à vontade para executá-lo para se convencer de que funciona: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Vamos abrir o arquivo de fluxo de trabalho `hello.nf` para inspecionar o código, que é mostrado completo abaixo (sem contar os processos, que estão em módulos): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Inclui módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Como você pode ver, este fluxo de trabalho foi escrito como um fluxo de trabalho simples sem nome que pode ser executado sozinho. +Para torná-lo executável de dentro de um fluxo de trabalho pai como o template nf-core requer, precisamos torná-lo **componível**. + +Vamos percorrer as mudanças necessárias uma a uma. + +### 2.1. Nomear o fluxo de trabalho + +Primeiro, vamos dar um nome ao fluxo de trabalho para que possamos nos referir a ele de um fluxo de trabalho pai. + +=== "Depois" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +As mesmas convenções se aplicam aos nomes de fluxos de trabalho e aos nomes de módulos. + +### 2.2. Substituir construção de canal por `take` + +Agora, substitua a construção do canal por uma simples declaração `take` declarando as entradas esperadas. + +=== "Depois" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // canal de saudações + greeting_ch + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="18" + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Isso deixa os detalhes de como as entradas são fornecidas para o fluxo de trabalho pai. + +Já que estamos nisso, também podemos comentar a linha `params.greeting = 'greetings.csv'` + +=== "Depois" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parameters + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note "Nota" + + Se você tiver a extensão do servidor de linguagem Nextflow instalada, o verificador de sintaxe iluminará seu código com rabiscos vermelhos. + Isso ocorre porque se você colocar uma declaração `take:`, também precisa ter um `main:`. + + Adicionaremos isso no próximo passo. + +### 2.3. Prefaciar operações do fluxo de trabalho com declaração `main` + +Em seguida, adicione uma declaração `main` antes das demais operações chamadas no corpo do fluxo de trabalho. + +=== "Depois" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="original-hello/hello.nf" linenums="21" + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Isso basicamente diz 'isto é o que este fluxo de trabalho _faz_'. + +### 2.4. Adicionar declaração `emit` + +Finalmente, adicione uma declaração `emit` declarando quais são as saídas finais do fluxo de trabalho. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Esta é uma adição completamente nova ao código em comparação com o fluxo de trabalho original. + +### 2.5. Recapitulação das mudanças concluídas + +Se você fez todas as mudanças conforme descrito, seu fluxo de trabalho deve agora se parecer com isto: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parameters +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Inclui módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // canal de saudações + greeting_ch + + main: + + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Isso descreve tudo que o Nextflow precisa EXCETO o que alimentar no canal de entrada. +Isso será definido no fluxo de trabalho pai, também chamado de fluxo de trabalho **entrypoint**. + +### 2.6. Fazer um fluxo de trabalho entrypoint de teste + +Antes de integrar nosso fluxo de trabalho componível na estrutura nf-core complexa, vamos verificar se funciona corretamente. +Podemos fazer um fluxo de trabalho entrypoint de teste simples para testar o fluxo de trabalho componível isoladamente. + +Crie um arquivo em branco chamado `main.nf` no mesmo diretório `original-hello`. + +```bash +touch original-hello/main.nf +``` + +Copie o seguinte código para o arquivo `main.nf`. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// importar o código do fluxo de trabalho do arquivo hello.nf +include { HELLO } from './hello.nf' + +// declarar parâmetro de entrada +params.greeting = 'greetings.csv' + +workflow { + // criar um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // chamar o fluxo de trabalho importado no canal de saudações + HELLO(greeting_ch) + + // visualizar as saídas emitidas pelo fluxo de trabalho + HELLO.out.view { output -> "Output: $output" } +} +``` + +Há duas observações importantes a fazer aqui: + +- A sintaxe para chamar o fluxo de trabalho importado é essencialmente a mesma que a sintaxe para chamar módulos. +- Tudo que está relacionado a trazer as entradas para o fluxo de trabalho (parâmetro de entrada e construção de canal) agora é declarado neste fluxo de trabalho pai. + +!!! note "Nota" + + Nomear o arquivo de fluxo de trabalho entrypoint `main.nf` é uma convenção, não um requisito. + + Se você seguir esta convenção, pode omitir a especificação do nome do arquivo de fluxo de trabalho no seu comando `nextflow run`. + O Nextflow procurará automaticamente por um arquivo chamado `main.nf` no diretório de execução. + + No entanto, você pode nomear o arquivo de fluxo de trabalho entrypoint de outra forma se preferir. + Nesse caso, certifique-se de especificar o nome do arquivo de fluxo de trabalho no seu comando `nextflow run`. + +### 2.7. Testar que o fluxo de trabalho executa + +Finalmente temos todas as peças que precisamos para verificar que o fluxo de trabalho componível funciona. +Vamos executá-lo! + +```bash +nextflow run ./original-hello +``` + +Aqui você vê a vantagem de usar a convenção de nomenclatura `main.nf`. +Se tivéssemos nomeado o fluxo de trabalho entrypoint `algo_diferente.nf`, teríamos que fazer `nextflow run original-hello/algo_diferente.nf`. + +Se você fez todas as mudanças corretamente, isso deve executar até a conclusão. + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Isso significa que atualizamos com sucesso nosso fluxo de trabalho HELLO para ser componível. + +### Conclusão + +Você sabe como tornar um fluxo de trabalho componível dando-lhe um nome e adicionando declarações `take`, `main` e `emit`, e como chamá-lo de um fluxo de trabalho entrypoint. + +### O que vem a seguir? + +Aprenda como enxertar um fluxo de trabalho componível básico na estrutura nf-core. + +--- + +## 3. Ajustar a lógica do fluxo de trabalho atualizado no fluxo de trabalho placeholder + +Agora que verificamos que nosso fluxo de trabalho componível funciona corretamente, vamos retornar à estrutura do pipeline nf-core que criamos na seção 1. +Queremos integrar o fluxo de trabalho componível que acabamos de desenvolver na estrutura do template nf-core, então o resultado final deve se parecer com isto. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Então como fazemos isso acontecer? Vamos dar uma olhada no conteúdo atual do fluxo de trabalho `HELLO` em `core-hello/workflows/hello.nf` (a estrutura nf-core). + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +No geral, este código faz muito pouco além de algumas tarefas administrativas relacionadas à captura da versão de qualquer ferramenta de software que seja executada no pipeline. + +Precisamos adicionar o código relevante da versão componível do fluxo de trabalho original que desenvolvemos na seção 2. + +Vamos abordar isso nos seguintes estágios: + +1. Copiar os módulos e configurar importações de módulos +2. Deixar a declaração `take` como está +3. Adicionar a lógica do fluxo de trabalho ao bloco `main` +4. Atualizar o bloco `emit` + +!!! note "Nota" + + Vamos ignorar a captura de versão nesta primeira passagem e veremos como conectar isso em uma parte posterior deste treinamento. + +### 3.1. Copiar os módulos e configurar importações de módulos + +Os quatro processos do nosso fluxo de trabalho Hello Nextflow são armazenados como módulos em `original-hello/modules/`. +Precisamos copiar esses módulos para a estrutura do projeto nf-core (em `core-hello/modules/local/`) e adicionar declarações de importação ao arquivo de fluxo de trabalho nf-core. + +Primeiro vamos copiar os arquivos de módulo de `original-hello/` para `core-hello/`: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Você deve agora ver o diretório de módulos listado em `core-hello/`. + +```bash +tree core-hello/modules +``` + +??? abstract "Conteúdo do diretório" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Agora vamos configurar as declarações de importação de módulos. + +Estas eram as declarações de importação no fluxo de trabalho `original-hello/hello.nf`: + +```groovy title="original-hello/hello.nf" linenums="9" +// Inclui módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +Abra o arquivo `core-hello/workflows/hello.nf` e transponha essas declarações de importação para ele conforme mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Mais duas observações interessantes aqui: + +- Adaptamos a formatação das declarações de importação para seguir a convenção de estilo nf-core. +- Atualizamos os caminhos relativos para os módulos para refletir que eles agora estão armazenados em um nível diferente de aninhamento. + +### 3.2. Deixar a declaração `take` como está + +O projeto nf-core tem muita funcionalidade pré-construída em torno do conceito de samplesheet, que é tipicamente um arquivo CSV contendo dados em colunas. +Como isso é essencialmente o que nosso arquivo `greetings.csv` é, vamos manter a declaração `take` atual como está, e simplesmente atualizar o nome do canal de entrada no próximo passo. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +O tratamento de entrada será feito antes deste fluxo de trabalho (não neste arquivo de código). + +### 3.3. Adicionar a lógica do fluxo de trabalho ao bloco `main` + +Agora que nossos módulos estão disponíveis para o fluxo de trabalho, podemos conectar a lógica do fluxo de trabalho no bloco `main`. + +Como lembrete, este é o código relevante no fluxo de trabalho original, que não mudou muito quando o tornamos componível (apenas adicionamos a linha `main:`): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) +``` + +Precisamos copiar o código que vem depois de `main:` para a nova versão do fluxo de trabalho. + +Já existe algum código lá que tem a ver com capturar as versões das ferramentas que são executadas pelo fluxo de trabalho. Vamos deixar isso em paz por enquanto (lidaremos com as versões de ferramentas mais tarde). +Manteremos a inicialização `ch_versions = channel.empty()` no topo, depois inseriremos nossa lógica de fluxo de trabalho, mantendo o código de coleta de versões no final. +Esta ordenação faz sentido porque em um pipeline real, os processos emitiriam informações de versão que seriam adicionadas ao canal `ch_versions` conforme o fluxo de trabalho executa. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // emitir uma saudação + sayHello(greeting_ch) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coletar todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +Você notará que também adicionamos uma linha em branco antes de `main:` para tornar o código mais legível. + +Isso parece ótimo, mas ainda precisamos atualizar o nome do canal que estamos passando para o processo `sayHello()` de `greeting_ch` para `ch_samplesheet` conforme mostrado abaixo, para corresponder ao que está escrito sob a palavra-chave `take:`. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir uma saudação (atualizado para usar a convenção nf-core para samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emite uma saudação + sayHello(greeting_ch) + ``` + +Agora a lógica do fluxo de trabalho está corretamente conectada. + +### 3.4. Atualizar o bloco `emit` + +Finalmente, precisamos atualizar o bloco `emit` para incluir a declaração das saídas finais do fluxo de trabalho. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +Isso conclui as modificações que precisamos fazer no próprio fluxo de trabalho HELLO. +Neste ponto, alcançamos a estrutura geral de código que nos propusemos a implementar. + +### Conclusão + +Você sabe como ajustar as peças principais de um fluxo de trabalho componível em um fluxo de trabalho placeholder nf-core. + +### O que vem a seguir? + +Aprenda como adaptar o tratamento de entradas na estrutura do pipeline nf-core. + +--- + +## 4. Adaptar o tratamento de entrada + +Agora que integramos com sucesso nossa lógica de fluxo de trabalho na estrutura nf-core, precisamos abordar mais uma peça crítica: garantir que nossos dados de entrada sejam processados corretamente. +O template nf-core vem com tratamento de entrada sofisticado projetado para conjuntos de dados de genômica complexos, então precisamos adaptá-lo para funcionar com nosso arquivo `greetings.csv` mais simples. + +### 4.1. Identificar onde as entradas são tratadas + +O primeiro passo é descobrir onde o tratamento de entrada é feito. + +Você pode se lembrar que quando reescrevemos o fluxo de trabalho Hello Nextflow para ser componível, movemos a declaração de parâmetro de entrada um nível acima, no fluxo de trabalho entrypoint `main.nf`. +Então vamos dar uma olhada no fluxo de trabalho entrypoint `main.nf` de nível superior que foi criado como parte da estrutura do pipeline: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Run main analysis pipeline depending on type of input +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Run pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Run initialisation tasks + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Run main workflow + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Run completion tasks + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +O projeto nf-core faz uso intenso de subfluxos de trabalho aninhados, então esta parte pode ser um pouco confusa na primeira abordagem. + +O que importa aqui é que existem dois fluxos de trabalho definidos: + +- `CORE_HELLO` é um wrapper fino para executar o fluxo de trabalho HELLO que acabamos de terminar de adaptar em `core-hello/workflows/hello.nf`. +- Um fluxo de trabalho sem nome que chama `CORE_HELLO` bem como dois outros subfluxos de trabalho, `PIPELINE_INITIALISATION` e `PIPELINE_COMPLETION`. + +Aqui está um diagrama de como eles se relacionam: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Importante, não podemos encontrar nenhum código construindo um canal de entrada neste nível, apenas referências a uma samplesheet fornecida via parâmetro `--input`. + +Um pouco de investigação revela que o tratamento de entrada é feito pelo subfluxo de trabalho `PIPELINE_INITIALISATION`, apropriadamente, que é importado de `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`. + +Se abrirmos esse arquivo e rolarmos para baixo, chegamos a este pedaço de código: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Cria canal a partir do arquivo de entrada fornecido através de params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +Esta é a fábrica de canais que analisa a samplesheet e a passa adiante em uma forma que está pronta para ser consumida pelo fluxo de trabalho HELLO. + +!!! note "Nota" + + A sintaxe acima é um pouco diferente do que usamos anteriormente, mas basicamente isto: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + é equivalente a isto: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Este código envolve algumas etapas de análise e validação que são altamente específicas para a samplesheet de exemplo incluída no template de pipeline nf-core, que no momento da escrita é muito específica de domínio e não adequada para nosso projeto de pipeline simples. + +### 4.2. Substituir o código de canal de entrada do template + +A boa notícia é que as necessidades do nosso pipeline são muito mais simples, então podemos substituir tudo isso pelo código de construção de canal que desenvolvemos no fluxo de trabalho Hello Nextflow original. + +Como lembrete, isto é como a construção de canal se parecia (como visto no diretório de soluções): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // criar um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Então só precisamos conectar isso no fluxo de trabalho de inicialização, com pequenas mudanças: atualizamos o nome do canal de `greeting_ch` para `ch_samplesheet`, e o nome do parâmetro de `params.greeting` para `params.input` (veja a linha destacada). + +=== "Depois" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Cria canal a partir do arquivo de entrada fornecido através de params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Cria canal a partir do arquivo de entrada fornecido através de params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Isso completa as mudanças que precisamos fazer para que o processamento de entrada funcione. + +Na sua forma atual, isso não nos permitirá aproveitar as capacidades integradas do nf-core para validação de schema, mas podemos adicionar isso mais tarde. +Por enquanto, estamos focados em mantê-lo o mais simples possível para chegar a algo que possamos executar com sucesso em dados de teste. + +### 4.3. Atualizar o perfil de teste + +Falando em dados de teste e parâmetros, vamos atualizar o perfil de teste para este pipeline para usar a mini-samplesheet `greetings.csv` em vez da samplesheet de exemplo fornecida no template. + +Em `core-hello/conf`, encontramos dois perfis de teste do template: `test.config` e `test_full.config`, que são destinados a testar uma pequena amostra de dados e uma de tamanho completo. +Dado o propósito do nosso pipeline, não há realmente sentido em configurar um perfil de teste de tamanho completo, então sinta-se à vontade para ignorar ou excluir `test_full.config`. +Vamos focar em configurar `test.config` para executar em nosso arquivo `greetings.csv` com alguns parâmetros padrão. + +#### 4.3.1. Copiar o arquivo `greetings.csv` + +Primeiro precisamos copiar o arquivo `greetings.csv` para um local apropriado em nosso projeto de pipeline. +Tipicamente pequenos arquivos de teste são armazenados no diretório `assets`, então vamos copiar o arquivo do nosso diretório de trabalho. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Agora o arquivo `greetings.csv` está pronto para ser usado como entrada de teste. + +#### 4.3.2. Atualizar o arquivo `test.config` + +Agora podemos atualizar o arquivo `test.config` da seguinte forma: + +=== "Depois" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dados de entrada + input = "${projectDir}/assets/greetings.csv" + + // Outros parâmetros + batch = 'test' + character = 'tux' + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Dados de entrada + // TODO nf-core: Specify the paths to your test data on nf-core/test-datasets + // TODO nf-core: Give any required params for the test so that command line flags are not needed + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Pontos-chave: + +- **Usando `${projectDir}`**: Esta é uma variável implícita do Nextflow que aponta para o diretório onde o script de fluxo de trabalho principal está localizado (a raiz do pipeline). Usá-la garante que o caminho funcione independentemente de onde o pipeline seja executado. +- **Caminhos absolutos**: Ao usar `${projectDir}`, criamos um caminho absoluto, o que é importante para dados de teste que são enviados com o pipeline. +- **Localização de dados de teste**: pipelines nf-core tipicamente armazenam dados de teste no diretório `assets/` dentro do repositório do pipeline para pequenos arquivos de teste, ou referenciam conjuntos de dados de teste externos para arquivos maiores. + +E já que estamos nisso, vamos apertar os limites de recursos padrão para garantir que isso seja executado em máquinas muito básicas (como as VMs mínimas no GitHub Codespaces): + +=== "Depois" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Antes" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Isso completa as modificações de código que precisamos fazer. + +### 4.4. Executar o pipeline com o perfil de teste + +Isso foi muito, mas finalmente podemos tentar executar o pipeline! +Note que temos que adicionar `--validate_params false` à linha de comando porque ainda não configuramos a validação (isso virá mais tarde). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Se você fez todas as modificações corretamente, deve executar até a conclusão. + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [81/7e2e34] CORE_HELLO:HELLO:collectGreetings [100%] 1 of 1 ✔ + [96/9442a1] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Como você pode ver, isso produziu o resumo típico nf-core no início graças ao subfluxo de trabalho de inicialização, e as linhas para cada módulo agora mostram os nomes completos PIPELINE:WORKFLOW:módulo. + +### 4.5. Encontrar as saídas do pipeline + +A questão agora é: onde estão as saídas do pipeline? +E a resposta é bastante interessante: agora há dois lugares diferentes para procurar os resultados. + +Como você pode se lembrar anteriormente, nossa primeira execução do fluxo de trabalho recém-criado produziu um diretório chamado `core-hello-results/` que continha vários relatórios de execução e metadados. + +```bash +tree core-hello-results +``` + +??? abstract "Conteúdo do diretório" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_report_2025-11-21_07-29-37.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_07-29-37.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── execution_trace_2025-11-21_07-29-37.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-13.json + ├── params_2025-11-21_07-29-41.json + └── pipeline_dag_2025-11-21_04-47-18.html + └── pipeline_dag_2025-11-21_07-29-37.html + + 1 directory, 12 files + ``` + +Você vê que obtivemos outro conjunto de relatórios de execução além dos que obtivemos da primeira execução, quando o fluxo de trabalho ainda era apenas um placeholder. +Desta vez você vê todas as tarefas que foram executadas como esperado. + +![relatório de timeline de execução para o pipeline Hello](./img/execution_timeline_hello.png) + +!!! note "Nota" + + Mais uma vez as tarefas não foram executadas em paralelo porque estamos executando em uma máquina minimalista no GitHub Codespaces. + Para ver essas executadas em paralelo, tente aumentar a alocação de CPU do seu codespace e os limites de recursos na configuração de teste. + +Isso é ótimo, mas nossos resultados reais do pipeline não estão lá! + +Aqui está o que aconteceu: não mudamos nada nos próprios módulos, então as saídas tratadas pelas diretivas `publishDir` em nível de módulo ainda vão para um diretório `results` conforme especificado no pipeline original. + +```bash +tree results +``` + +??? abstract "Conteúdo do diretório" + + ```console + results + ├── Bonjour-output.txt + ├── COLLECTED-test-batch-output.txt + ├── COLLECTED-test-output.txt + ├── cowpy-COLLECTED-test-batch-output.txt + ├── cowpy-COLLECTED-test-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + 0 directories, 10 files + ``` + +Ah, ali estão eles, misturados com as saídas de execuções anteriores do pipeline Hello original. + +Se quisermos que eles sejam organizados de forma organizada como as saídas do pipeline demo foram, precisaremos mudar como configuramos as saídas para serem publicadas. +Mostraremos como fazer isso mais tarde neste curso de treinamento. + +<!-- TODO: Update this once we've updated Hello Nextflow to use workflow-level outputs --> + +E aí está! Pode parecer muito trabalho para obter o mesmo resultado que o pipeline original, mas você obtém todos aqueles relatórios lindos gerados automaticamente, e agora tem uma base sólida para aproveitar recursos adicionais do nf-core, incluindo validação de entrada e alguns recursos legais de tratamento de metadados que cobriremos em uma seção posterior. + +--- + +### Conclusão + +Você sabe como converter um pipeline Nextflow regular em um pipeline no estilo nf-core usando o template nf-core. +Como parte disso, você aprendeu como tornar um fluxo de trabalho componível, e como identificar os elementos do template nf-core que mais comumente precisam ser adaptados ao desenvolver um pipeline customizado no estilo nf-core. + +### O que vem a seguir? + +Faça uma pausa, isso foi trabalho duro! Quando estiver pronto, prossiga para [Parte 3: Usar um módulo nf-core](./03_use_module.md) para aprender como aproveitar módulos mantidos pela comunidade do repositório nf-core/modules. diff --git a/docs/pt/docs/hello_nf-core/03_use_module.md b/docs/pt/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..c90e2a181a --- /dev/null +++ b/docs/pt/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Parte 3: Usar um módulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta terceira parte do curso de treinamento Hello nf-core, mostramos como encontrar, instalar e usar um módulo nf-core existente no seu pipeline. + +Um dos grandes benefícios de trabalhar com nf-core é a capacidade de aproveitar módulos pré-construídos e testados do repositório [nf-core/modules](https://github.com/nf-core/modules). +Em vez de escrever cada processo do zero, você pode instalar e usar módulos mantidos pela comunidade que seguem as melhores práticas. + +Para demonstrar como isso funciona, vamos substituir o módulo customizado `collectGreetings` pelo módulo `cat/cat` do nf-core/modules no pipeline `core-hello`. + +??? info "Como começar a partir desta seção" + + Esta seção do curso assume que você completou a [Parte 2: Reescrever Hello para nf-core](./02_rewrite_hello.md) e tem um pipeline `core-hello` funcionando. + + Se você não completou a Parte 2 ou quer começar do zero para esta parte, você pode usar a solução `core-hello-part2` como ponto de partida. + Execute este comando dentro do diretório `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Isso fornece um pipeline nf-core totalmente funcional pronto para adicionar módulos. + Você pode testar que ele executa com sucesso rodando o seguinte comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Encontrar e instalar um módulo nf-core adequado + +Primeiro, vamos aprender como encontrar um módulo nf-core existente e instalá-lo no nosso pipeline. + +Nosso objetivo é substituir o processo `collectGreetings`, que usa o comando Unix `cat` para concatenar múltiplos arquivos de saudações em um só. +Concatenar arquivos é uma operação muito comum, então é razoável que já exista um módulo no nf-core projetado para esse propósito. + +Vamos começar. + +### 1.1. Navegar pelos módulos disponíveis no site nf-core + +O projeto nf-core mantém um catálogo centralizado de módulos em [https://nf-co.re/modules](https://nf-co.re/modules). + +Navegue até a página de módulos no seu navegador e use a barra de busca para pesquisar 'concatenate'. + +![resultados da busca de módulos](./img/module-search-results.png) + +Como você pode ver, há muitos resultados, vários deles módulos projetados para concatenar tipos muito específicos de arquivos. +Entre eles, você deve ver um chamado `cat_cat` que é de uso geral. + +!!! note "Convenção de nomenclatura de módulos" + + O sublinhado (`_`) é usado como substituto para o caractere barra (`/`) nos nomes dos módulos. + + Os módulos nf-core seguem a convenção de nomenclatura `software/comando` quando uma ferramenta fornece múltiplos comandos, como `samtools/view` (pacote samtools, comando view) ou `gatk/haplotypecaller` (pacote GATK, comando HaplotypeCaller). + Para ferramentas que fornecem apenas um comando principal, os módulos usam um único nível como `fastqc` ou `multiqc`. + +Clique na caixa do módulo `cat_cat` para visualizar a documentação do módulo. + +A página do módulo mostra: + +- Uma breve descrição: "A module for concatenation of gzipped or uncompressed files" +- Comando de instalação: `nf-core modules install cat/cat` +- Estrutura dos canais de entrada e saída +- Parâmetros disponíveis + +### 1.2. Listar módulos disponíveis pela linha de comando + +Alternativamente, você também pode pesquisar módulos diretamente da linha de comando usando as ferramentas nf-core. + +```bash +nf-core modules list remote +``` + +Isso exibirá uma lista de todos os módulos disponíveis no repositório nf-core/modules, embora seja um pouco menos conveniente se você ainda não sabe o nome do módulo que está procurando. +No entanto, se você souber, pode canalizar a lista para `grep` para encontrar módulos específicos: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Saída do comando" + + ```console + │ cat/cat + ``` + +Tenha em mente que a abordagem com `grep` só extrairá resultados com o termo de busca em seu nome, o que não funcionaria para `cat_cat`. + +### 1.3. Obter informações detalhadas sobre o módulo + +Para ver informações detalhadas sobre um módulo específico da linha de comando, use o comando `info`: + +```bash +nf-core modules info cat/cat +``` + +Isso exibe a documentação sobre o módulo, incluindo suas entradas, saídas e informações básicas de uso. + +??? success "Saída do comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +Esta é exatamente a mesma informação que você pode encontrar no site. + +### 1.4. Instalar o módulo cat/cat + +Agora que encontramos o módulo que queremos, precisamos adicioná-lo ao código-fonte do nosso pipeline. + +A boa notícia é que o projeto nf-core inclui ferramentas para facilitar esta parte. +Especificamente, o comando `nf-core modules install` torna possível automatizar a recuperação do código e torná-lo disponível para seu projeto em um único passo. + +Navegue até o diretório do seu pipeline e execute o comando de instalação: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +A ferramenta pode primeiro solicitar que você especifique um tipo de repositório. +(Se não, pule para "Finalmente, a ferramenta procederá para instalar o módulo.") + +??? success "Saída do comando" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Se aparecer, pressione enter para aceitar a resposta padrão (`Pipeline`) e continuar. + +A ferramenta então oferecerá alterar a configuração do seu projeto para evitar esse prompt no futuro. + +??? success "Saída do comando" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +Por que não aproveitar essa ferramenta conveniente! +Pressione enter para aceitar a resposta padrão (sim). + +Finalmente, a ferramenta procederá para instalar o módulo. + +??? success "Saída do comando" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +O comando automaticamente: + +- Baixa os arquivos do módulo para `modules/nf-core/cat/cat/` +- Atualiza `modules.json` para rastrear o módulo instalado +- Fornece a declaração `include` correta para usar no seu fluxo de trabalho + +!!! tip + + Sempre certifique-se de que seu diretório de trabalho atual seja a raiz do projeto do seu pipeline antes de executar o comando de instalação de módulo. + +Vamos verificar que o módulo foi instalado corretamente: + +```bash +tree -L 4 modules +``` + +??? abstract "Conteúdo do diretório" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +Você também pode verificar a instalação pedindo ao utilitário nf-core para listar os módulos instalados localmente: + +```bash +nf-core modules list local +``` + +??? success "Saída do comando" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Isso confirma que o módulo `cat/cat` agora faz parte do código-fonte do seu projeto. + +No entanto, para realmente usar o novo módulo, precisamos importá-lo no nosso pipeline. + +### 1.5. Atualizar as importações de módulos + +Vamos substituir a declaração `include` do módulo `collectGreetings` pela do `CAT_CAT` na seção de importações do fluxo de trabalho `workflows/hello.nf`. + +Como lembrete, a ferramenta de instalação de módulos nos deu a declaração exata para usar: + +```groovy title="Declaração de importação produzida pelo comando de instalação" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +Observe que a convenção nf-core é usar letras maiúsculas para nomes de módulos ao importá-los. + +Abra [core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) e faça a seguinte substituição: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +Observe como o caminho para o módulo nf-core difere dos módulos locais: + +- **Módulo nf-core**: `'../modules/nf-core/cat/cat/main'` (referencia `main.nf`) +- **Módulo local**: `'../modules/local/collectGreetings.nf'` (referência de arquivo único) + +O módulo agora está disponível para o fluxo de trabalho, então tudo o que precisamos fazer é trocar a chamada de `collectGreetings` para usar `CAT_CAT`. Certo? + +Não tão rápido. + +Neste ponto, você pode estar tentado a mergulhar e começar a editar o código, mas vale a pena dedicar um momento para examinar cuidadosamente o que o novo módulo espera e o que ele produz. + +Vamos abordar isso como uma seção separada porque envolve um novo mecanismo que ainda não cobrimos: mapas de metadados. + +!!! note + + Você pode opcionalmente deletar o arquivo `collectGreetings.nf`: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + No entanto, você pode querer mantê-lo como referência para entender as diferenças entre módulos locais e nf-core. + +### Conclusão + +Você sabe como encontrar um módulo nf-core e torná-lo disponível para o seu projeto. + +### Qual é o próximo passo? + +Avaliar o que um novo módulo requer e identificar quaisquer mudanças importantes necessárias para integrá-lo em um pipeline. + +--- + +## 2. Avaliar os requisitos do novo módulo + +Especificamente, precisamos examinar a **interface** do módulo, ou seja, suas definições de entrada e saída, e compará-la com a interface do módulo que estamos buscando substituir. +Isso nos permitirá determinar se podemos simplesmente tratar o novo módulo como uma substituição direta ou se precisaremos adaptar parte da conexão. + +Idealmente, isso é algo que você deveria fazer _antes_ mesmo de instalar o módulo, mas ei, melhor tarde do que nunca. +(Vale ressaltar que existe um comando `uninstall` para se livrar de módulos que você decidir que não quer mais.) + +!!! note + + O processo CAT_CAT inclui um tratamento bastante inteligente de diferentes tipos de compressão, extensões de arquivo e assim por diante, que não são estritamente relevantes para o que estamos tentando mostrar aqui, então vamos ignorar a maior parte e focar apenas nas partes que são importantes. + +### 2.1. Comparar as interfaces dos dois módulos + +Como lembrete, esta é a aparência da interface do nosso módulo `collectGreetings`: + +```groovy title="modules/local/collectGreetings.nf (trecho)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +O módulo `collectGreetings` recebe duas entradas: + +- `input_files` contém um ou mais arquivos de entrada para processar; +- `batch_name` é um valor que usamos para atribuir um nome específico da execução ao arquivo de saída, que é uma forma de metadados. + +Após a conclusão, `collectGreetings` produz um único caminho de arquivo, emitido com a tag `outfile`. + +Em comparação, a interface do módulo `cat/cat` é mais complexa: + +```groovy title="modules/nf-core/cat/cat/main.nf (trecho)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +O módulo CAT_CAT recebe uma única entrada, mas essa entrada é uma tupla contendo duas coisas: + +- `meta` é uma estrutura contendo metadados, chamada de mapa de metadados (metamap); +- `files_in` contém um ou mais arquivos de entrada para processar, equivalente ao `input_files` de `collectGreetings`. + +Após a conclusão, CAT_CAT entrega suas saídas em duas partes: + +- Outra tupla contendo o mapa de metadados e o arquivo de saída concatenado, emitido com a tag `file_out`; +- Um arquivo `versions.yml` que captura informações sobre a versão do software que foi usada, emitido com a tag `versions`. + +Observe também que, por padrão, o arquivo de saída será nomeado com base em um identificador que faz parte dos metadados (código não mostrado aqui). + +Isso pode parecer muita coisa para acompanhar apenas olhando o código, então aqui está um diagrama para ajudá-lo a visualizar como tudo se encaixa. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +Você pode ver que os dois módulos têm requisitos de entrada semelhantes em termos de conteúdo (um conjunto de arquivos de entrada mais alguns metadados), mas expectativas muito diferentes sobre como esse conteúdo é empacotado. +Ignorando o arquivo de versões por enquanto, sua saída principal também é equivalente (um arquivo concatenado), exceto que CAT_CAT também emite o mapa de metadados em conjunto com o arquivo de saída. + +As diferenças de empacotamento serão relativamente fáceis de lidar, como você verá daqui a pouco. +No entanto, para entender a parte do mapa de metadados, precisamos apresentar algum contexto adicional. + +### 2.2. Entendendo mapas de metadados + +Acabamos de dizer que o módulo CAT_CAT espera um mapa de metadados como parte de sua tupla de entrada. +Vamos dedicar alguns minutos para examinar mais de perto o que isso é. + +O **mapa de metadados**, frequentemente referido como **metamap** para abreviar, é um mapa no estilo Groovy contendo informações sobre unidades de dados. +No contexto de pipelines Nextflow, unidades de dados podem ser qualquer coisa que você queira: amostras individuais, lotes de amostras ou conjuntos de dados inteiros. + +Por convenção, um mapa de metadados nf-core é nomeado `meta` e contém o campo obrigatório `id`, que é usado para nomear saídas e rastrear unidades de dados. + +Por exemplo, um mapa de metadados típico pode se parecer com isto: + +```groovy title="Exemplo de metamap em nível de amostra" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +Ou em um caso onde os metadados são anexados no nível de lote: + +```groovy title="Exemplo de metamap em nível de lote" +[id: 'batch1', date: '25.10.01'] +``` + +Agora vamos colocar isso no contexto do processo `CAT_CAT`, que espera que os arquivos de entrada sejam empacotados em uma tupla com um mapa de metadados, e também produz o mapa de metadados como parte da tupla de saída. + +```groovy title="modules/nf-core/cat/cat/main.nf (trecho)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +Como resultado, cada unidade de dados viaja através do pipeline com os metadados relevantes anexados. +Processos subsequentes podem então acessar prontamente esses metadados também. + +Lembra como dissemos que o arquivo produzido por `CAT_CAT` será nomeado com base em um identificador que faz parte dos metadados? +Este é o código relevante: + +```groovy title="modules/nf-core/cat/cat/main.nf (trecho)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Isso se traduz aproximadamente da seguinte forma: se um `prefix` for fornecido através do sistema de parâmetros externos de tarefa (`task.ext`), use-o para nomear o arquivo de saída; caso contrário, crie um usando `${meta.id}`, que corresponde ao campo `id` no mapa de metadados. + +Você pode imaginar o canal de entrada chegando a este módulo com conteúdo assim: + +```groovy title="Exemplo de conteúdo do canal de entrada" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Então o conteúdo do canal de saída saindo assim: + +```groovy title="Exemplo de conteúdo do canal de saída" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Como mencionado anteriormente, a configuração de entrada `tuple val(meta), path(files_in)` é um padrão usado em todos os módulos nf-core. + +Esperamos que você possa começar a ver como isso pode ser útil. +Não só permite nomear saídas com base em metadados, mas você também pode fazer coisas como usá-lo para aplicar diferentes valores de parâmetros e, em combinação com operadores específicos, você pode até agrupar, ordenar ou filtrar dados conforme eles fluem pelo pipeline. + +!!! note "Saiba mais sobre metadados" + + Para uma introdução abrangente ao trabalho com metadados em fluxos de trabalho Nextflow, incluindo como ler metadados de planilhas de amostras e usá-los para personalizar o processamento, consulte a missão paralela [Metadados em fluxos de trabalho](../side_quests/metadata). + +### 2.3. Resumir mudanças a serem feitas + +Com base no que revisamos, estas são as principais mudanças que precisamos fazer no nosso pipeline para utilizar o módulo `cat/cat`: + +- Criar um mapa de metadados contendo o nome do lote; +- Empacotar o mapa de metadados em uma tupla com o conjunto de arquivos de entrada para concatenar (vindo de `convertToUpper`); +- Trocar a chamada de `collectGreetings()` para `CAT_CAT`; +- Extrair o arquivo de saída da tupla produzida pelo processo `CAT_CAT` antes de passá-lo para `cowpy`. + +Isso deve resolver! Agora que temos um plano, estamos prontos para mergulhar. + +### Conclusão + +Você sabe como avaliar a interface de entrada e saída de um novo módulo para identificar seus requisitos, e aprendeu como os mapas de metadados são usados por pipelines nf-core para manter metadados intimamente associados aos dados conforme eles fluem por um pipeline. + +### Qual é o próximo passo? + +Integrar o novo módulo em um fluxo de trabalho. + +--- + +## 3. Integrar CAT_CAT no fluxo de trabalho `hello.nf` + +Agora que você sabe tudo sobre mapas de metadados (ou o suficiente para os propósitos deste curso, de qualquer forma), é hora de realmente implementar as mudanças que delineamos acima. + +Para maior clareza, vamos dividir isso e cobrir cada passo separadamente. + +!!! note + + Todas as mudanças mostradas abaixo são feitas na lógica do fluxo de trabalho no bloco `main` no arquivo de fluxo de trabalho `core-hello/workflows/hello.nf`. + +### 3.1. Criar um mapa de metadados + +Primeiro, precisamos criar um mapa de metadados para `CAT_CAT`, lembrando que os módulos nf-core exigem que o mapa de metadados tenha pelo menos um campo `id`. + +Como não precisamos de outros metadados, podemos manter simples e usar algo assim: + +```groovy title="Exemplo de sintaxe" +def cat_meta = [id: 'test'] +``` + +Exceto que não queremos codificar o valor `id`; queremos usar o valor do parâmetro `params.batch`. +Então o código fica: + +```groovy title="Exemplo de sintaxe" +def cat_meta = [id: params.batch] +``` + +Sim, é literalmente assim tão simples criar um mapa de metadados básico. + +Vamos adicionar essas linhas após a chamada de `convertToUpper`, removendo a chamada de `collectGreetings`: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // coletar todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Isso cria um mapa de metadados simples onde o `id` é definido como nosso nome de lote (que será `test` ao usar o perfil de teste). + +### 3.2. Criar um canal com tuplas de metadados + +Em seguida, transforme o canal de arquivos em um canal de tuplas contendo metadados e arquivos: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // criar um canal com metadados e arquivos no formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +A linha que adicionamos realiza duas coisas: + +- `.collect()` reúne todos os arquivos da saída de `convertToUpper` em uma única lista +- `.map { files -> tuple(cat_meta, files) }` cria uma tupla de `[metadados, arquivos]` no formato que `CAT_CAT` espera + +Isso é tudo que precisamos fazer para configurar a tupla de entrada para `CAT_CAT`. + +### 3.3. Chamar o módulo CAT_CAT + +Agora chame `CAT_CAT` no canal recém-criado: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // criar um canal com metadados e arquivos no formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar arquivos usando o módulo nf-core cat/cat + CAT_CAT(ch_for_cat) + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // criar um canal com metadados e arquivos no formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Isso completa a parte mais complicada desta substituição, mas ainda não terminamos: ainda precisamos atualizar como passamos a saída concatenada para o processo `cowpy`. + +### 3.4. Extrair o arquivo de saída da tupla para `cowpy` + +Anteriormente, o processo `collectGreetings` simplesmente produzia um arquivo que podíamos passar para `cowpy` diretamente. +No entanto, o processo `CAT_CAT` produz uma tupla que inclui o mapa de metadados além do arquivo de saída. + +Como `cowpy` ainda não aceita tuplas de metadados (vamos corrigir isso na próxima parte do curso), precisamos extrair o arquivo de saída da tupla produzida por `CAT_CAT` antes de entregá-lo a `cowpy`: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // criar um canal com metadados e arquivos no formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar as saudações + CAT_CAT(ch_for_cat) + + // extrair o arquivo da tupla já que cowpy ainda não usa metadados + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // gerar arte ASCII das saudações com cowpy + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // emitir uma saudação + sayHello(ch_samplesheet) + + // converter a saudação para maiúsculas + convertToUpper(sayHello.out) + + // criar mapa de metadados com o nome do lote como ID + def cat_meta = [ id: params.batch ] + + // criar um canal com metadados e arquivos no formato de tupla + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenar as saudações + CAT_CAT(ch_for_cat) + + // gerar arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + ``` + +A operação `.map{ meta, file -> file }` extrai o arquivo da tupla `[metadados, arquivo]` produzida por `CAT_CAT` em um novo canal, `ch_for_cowpy`. + +Então é só uma questão de passar `ch_for_cowpy` para `cowpy` em vez de `collectGreetings.out.outfile` naquela última linha. + +!!! note + + Na próxima parte do curso, atualizaremos `cowpy` para trabalhar diretamente com tuplas de metadados, então este passo de extração não será mais necessário. + +### 3.5. Testar o fluxo de trabalho + +Vamos testar que o fluxo de trabalho funciona com o módulo `cat/cat` recém-integrado: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Isso deve executar razoavelmente rápido. + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Observe que `CAT_CAT` agora aparece na lista de execução de processos em vez de `collectGreetings`. + +E é isso! Agora estamos usando um módulo robusto curado pela comunidade em vez de código customizado de nível de protótipo para essa etapa no pipeline. + +### Conclusão + +Você agora sabe como: + +- Encontrar e instalar módulos nf-core +- Avaliar os requisitos de um módulo nf-core +- Criar um mapa de metadados simples para usar com um módulo nf-core +- Integrar um módulo nf-core no seu fluxo de trabalho + +### Qual é o próximo passo? + +Aprender a adaptar seus módulos locais para seguir as convenções nf-core. +Também mostraremos como criar novos módulos nf-core a partir de um modelo usando as ferramentas nf-core. diff --git a/docs/pt/docs/hello_nf-core/04_make_module.md b/docs/pt/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..44a5287eb4 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1194 @@ +# Parte 4: Criar um módulo nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta quarta parte do curso de treinamento Hello nf-core, mostramos como criar um módulo nf-core aplicando as convenções principais que tornam os módulos portáteis e de fácil manutenção. + +O projeto nf-core fornece um comando (`nf-core modules create`) que gera templates de módulos estruturados corretamente de forma automática, semelhante ao que usamos para o fluxo de trabalho na Parte 2. +No entanto, para fins didáticos, vamos começar fazendo manualmente: transformar o módulo local `cowpy` em seu pipeline `core-hello` em um módulo no estilo nf-core passo a passo. +Depois disso, mostraremos como usar a criação de módulos baseada em template para trabalhar de forma mais eficiente no futuro. + +??? info "Como começar desta seção" + + Esta seção pressupõe que você completou a [Parte 3: Usar um módulo nf-core](./03_use_module.md) e integrou o módulo `CAT_CAT` ao seu pipeline. + + Se você não completou a Parte 3 ou deseja começar do zero para esta parte, pode usar a solução `core-hello-part3` como ponto de partida. + Execute estes comandos de dentro do diretório `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Isso fornece um pipeline com o módulo `CAT_CAT` já integrado. + Você pode testar que ele executa com sucesso executando o seguinte comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Transformar `cowpy` em um módulo nf-core + +Nesta seção, aplicaremos as convenções nf-core ao módulo local `cowpy` em seu pipeline `core-hello`, transformando-o em um módulo que segue os padrões da comunidade nf-core. + +Este é o código atual para o módulo de processo `cowpy`: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Aplicaremos as seguintes convenções nf-core incrementalmente: + +1. **Colocar o nome do processo em maiúsculas para `COWPY`** para seguir a convenção. +2. **Atualizar `COWPY` para usar tuplas de metadata** para propagar metadata da amostra através do fluxo de trabalho. +3. **Centralizar a configuração de argumentos da ferramenta com `ext.args`** para aumentar a versatilidade do módulo mantendo a interface mínima. +4. **Padronizar a nomeação de saída com `ext.prefix`** para promover consistência. +5. **Centralizar a configuração de publicação** para promover consistência. + +Após cada passo, executaremos o pipeline para testar que tudo funciona como esperado. + +!!! warning "Diretório de trabalho" + + Certifique-se de estar no diretório `core-hello` (a raiz do seu pipeline) para todas as edições de arquivo e execuções de comando nesta seção. + + ```bash + cd core-hello + ``` + +### 1.1. Colocar o nome do processo em maiúsculas + +Esta é puramente uma convenção estilística (não há justificativa técnica), mas como é a norma para módulos nf-core, vamos seguir. + +Precisamos fazer três conjuntos de alterações: + +1. Atualizar o nome do processo no módulo +2. Atualizar a declaração de importação do módulo no cabeçalho do fluxo de trabalho +3. Atualizar a chamada do processo e a declaração de emit no corpo do fluxo de trabalho + +Vamos começar! + +#### 1.1.1. Atualizar o nome do processo no módulo + +Abra o arquivo do módulo `cowpy.nf` (em `core-hello/modules/local/`) e modifique o nome do processo para maiúsculas: + +=== "Depois" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +Neste caso, a conversão para maiúsculas é completamente direta. + +Se o nome do processo fosse composto por várias palavras, por exemplo se tivéssemos um processo chamado MyCowpyTool originalmente em camel case, a convenção nf-core seria usar underscores para separá-las, resultando em MY_COWPY_TOOL. + +#### 1.1.2. Atualizar a declaração de importação do módulo + +Os nomes dos processos diferenciam maiúsculas de minúsculas, então agora que mudamos o nome do processo, precisamos atualizar a declaração de importação do módulo adequadamente no cabeçalho do fluxo de trabalho de `hello.nf`: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Poderíamos usar um alias na declaração de importação para evitar ter que atualizar as chamadas ao processo, mas isso de certa forma frustraria o objetivo de adotar a convenção de maiúsculas. + +#### 1.1.3. Atualizar a chamada do processo e a declaração de emit + +Então agora vamos atualizar as duas referências ao processo no bloco workflow de `hello.nf`: + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // gera arte ASCII das saudações com cowpy + COWPY(CAT_CAT.out.file_out) + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // gera arte ASCII das saudações com cowpy + cowpy(CAT_CAT.out.file_out) + + // + // Agrupar e salvar versões de software + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +Certifique-se de fazer **ambas** as alterações, caso contrário você obterá um erro ao executar isto. + +#### 1.1.4. Executar o pipeline para testá-lo + +Vamos executar o fluxo de trabalho para testar que tudo está funcionando corretamente após essas mudanças. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Certo, isso funciona! Agora vamos passar a fazer mudanças mais substanciais. + +### 1.2. Atualizar `COWPY` para usar tuplas de metadata + +Na versão atual do pipeline `core-hello`, estamos extraindo o arquivo da tupla de saída do `CAT_CAT` para passar ao `COWPY`, como mostrado na metade superior do diagrama abaixo. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +Seria melhor ter o `COWPY` aceitando tuplas de metadata diretamente, permitindo que os metadata fluam através do fluxo de trabalho, como mostrado na metade inferior do diagrama. + +Para isso, precisaremos fazer as seguintes alterações: + +1. Atualizar as definições de entrada e saída +2. Atualizar a chamada do processo no fluxo de trabalho +3. Atualizar o bloco emit no fluxo de trabalho + +Uma vez que tivermos feito tudo isso, executaremos o pipeline para testar que tudo ainda funciona como antes. + +#### 1.2.1. Atualizar as definições de entrada e saída + +Retorne ao arquivo do módulo `cowpy.nf` e modifique-o para aceitar tuplas de metadata como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Como você pode ver, mudamos tanto a **entrada principal** quanto a **saída** para uma tupla que segue o padrão `tuple val(meta), path(input_file)` introduzido na Parte 3 deste treinamento. +Para a saída, também aproveitamos esta oportunidade para adicionar `emit: cowpy_output` a fim de dar ao canal de saída um nome descritivo. + +Agora que mudamos o que o processo espera, precisamos atualizar o que fornecemos a ele na chamada do processo. + +#### 1.2.2. Atualizar a chamada do processo no fluxo de trabalho + +A boa notícia é que essa mudança simplificará a chamada do processo. +Agora que a saída do `CAT_CAT` e a entrada do `COWPY` têm a mesma 'forma', ou seja, ambas consistem em uma estrutura `tuple val(meta), path(input_file)`, podemos simplesmente conectá-las diretamente em vez de ter que extrair o arquivo explicitamente da saída do processo `CAT_CAT`. + +Abra o arquivo de fluxo de trabalho `hello.nf` (em `core-hello/workflows/`) e atualize a chamada para `COWPY` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // gera arte ASCII das saudações com cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extract the file from the tuple since cowpy doesn't use metadata yet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // gera arte ASCII das saudações com cowpy + COWPY(ch_for_cowpy, params.character) + ``` + +Agora chamamos `COWPY` em `CAT_CAT.out.file_out` diretamente. + +Como resultado, não precisamos mais construir o canal `ch_for_cowpy`, então essa linha (e sua linha de comentário) pode ser deletada inteiramente. + +#### 1.2.3. Atualizar o bloco emit no fluxo de trabalho + +Como `COWPY` agora emite uma saída nomeada, `cowpy_output`, podemos atualizar o bloco `emit:` do fluxo de trabalho `hello.nf` para usar isso. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Isso não é tecnicamente necessário, mas é uma boa prática referir-se a saídas nomeadas sempre que possível. + +#### 1.2.4. Executar o pipeline para testá-lo + +Vamos executar o fluxo de trabalho para testar que tudo está funcionando corretamente após essas mudanças. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +O pipeline deve executar com sucesso, com os metadata agora fluindo do `CAT_CAT` através do `COWPY`. + +Isso completa o que precisávamos fazer para que o `COWPY` manipule tuplas de metadata. +Agora, vamos ver o que mais podemos fazer para aproveitar os padrões de módulos nf-core. + +### 1.3. Centralizar a configuração de argumentos da ferramenta com `ext.args` + +Em seu estado atual, o processo `COWPY` espera receber um valor para o parâmetro `character`. +Como resultado, temos que fornecer um valor toda vez que chamamos o processo, mesmo se estivéssemos satisfeitos com os padrões definidos pela ferramenta. +Para o `COWPY` isso não é admitidamente um grande problema, mas para ferramentas com muitos parâmetros opcionais, pode se tornar bastante trabalhoso. + +O projeto nf-core recomenda usar um recurso do Nextflow chamado [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) para gerenciar argumentos de ferramentas de forma mais conveniente via arquivos de configuração. + +Em vez de declarar entradas de processo para cada opção da ferramenta, você escreve o módulo para referenciar `ext.args` na construção de sua linha de comando. +Então é só uma questão de configurar a variável `ext.args` para conter os argumentos e valores que você deseja usar no arquivo `modules.config`, que consolida detalhes de configuração para todos os módulos. +O Nextflow adicionará esses argumentos com seus valores à linha de comando da ferramenta em tempo de execução. + +Vamos aplicar essa abordagem ao módulo `COWPY`. +Vamos precisar fazer as seguintes alterações: + +1. Atualizar o módulo `COWPY` +2. Configurar `ext.args` no arquivo `modules.config` +3. Atualizar o fluxo de trabalho `hello.nf` + +Uma vez que tivermos feito tudo isso, executaremos o pipeline para testar que tudo ainda funciona como antes. + +#### 1.3.1. Atualizar o módulo `COWPY` + +Vamos fazer isso. +Abra o arquivo do módulo `cowpy.nf` (em `core-hello/modules/local/`) e modifique-o para referenciar `ext.args` como mostrado abaixo. + +=== "Depois" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Você pode ver que fizemos três mudanças. + +1. **No bloco `input:`, removemos a entrada `val character`.** + Daqui para frente, forneceremos esse argumento via a configuração `ext.args` conforme descrito abaixo. + +2. **No bloco `script:`, adicionamos a linha `def args = task.ext.args ?: ''`.** + Essa linha usa o operador `?:` para determinar o valor da variável `args`: o conteúdo de `task.ext.args` se não estiver vazio, ou uma string vazia se estiver. + Note que embora geralmente nos referimos a `ext.args`, este código deve referenciar `task.ext.args` para extrair a configuração `ext.args` no nível do módulo. + +3. **Na linha de comando, substituímos `-c "$character"` por `$args`.** + É aqui que o Nextflow injetará quaisquer argumentos de ferramenta definidos em `ext.args` no arquivo `modules.config`. + +Como resultado, a interface do módulo agora é mais simples: ela só espera as entradas essenciais de metadata e arquivo. + +!!! note + + O operador `?:` é frequentemente chamado de 'operador Elvis' porque se parece com um rosto de Elvis Presley de lado, com o caractere `?` simbolizando a onda em seu cabelo. + +#### 1.3.2. Configurar `ext.args` no arquivo `modules.config` + +Agora que tiramos a declaração de `character` do módulo, temos que adicioná-la ao `ext.args` no arquivo de configuração `modules.config`. + +Especificamente, vamos adicionar este pequeno pedaço de código ao bloco `process {}`: + +```groovy title="Código a adicionar" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +A sintaxe `withName:` atribui essa configuração apenas ao processo `COWPY`, e `ext.args = { "-c ${params.character}" }` simplesmente compõe uma string que incluirá o valor do parâmetro `character`. +Note o uso de chaves, que dizem ao Nextflow para avaliar o valor do parâmetro em tempo de execução. + +Faz sentido? Vamos adicionar. + +Abra `conf/modules.config` e adicione o código de configuração dentro do bloco `process {}` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Esperamos que você possa imaginar ter todos os módulos em um pipeline com seus `ext.args` especificados neste arquivo, com os seguintes benefícios: + +- A **interface do módulo permanece simples** - Ela só aceita as entradas essenciais de metadata e arquivo +- O **pipeline ainda expõe `params.character`** - Os usuários finais ainda podem configurá-lo como antes +- O **módulo agora é portátil** - Ele pode ser reutilizado em outros pipelines sem esperar um nome de parâmetro específico +- A configuração é **centralizada** em `modules.config`, mantendo a lógica do fluxo de trabalho limpa + +Ao usar o arquivo `modules.config` como o lugar onde todos os pipelines centralizam a configuração por módulo, tornamos nossos módulos mais reutilizáveis em diferentes pipelines. + +#### 1.3.3. Atualizar o fluxo de trabalho `hello.nf` + +Como o módulo `COWPY` não requer mais o parâmetro `character` como entrada, precisamos atualizar a chamada do fluxo de trabalho adequadamente. + +Abra o arquivo de fluxo de trabalho `hello.nf` (em `core-hello/workflows/`) e atualize a chamada para `COWPY` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // gera arte ASCII das saudações com cowpy + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Antes" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // gera arte ASCII das saudações com cowpy + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +O código do fluxo de trabalho agora está mais limpo: não precisamos passar `params.character` diretamente para o processo. +A interface do módulo é mantida mínima, tornando-a mais portátil, enquanto o pipeline ainda fornece a opção explícita através da configuração. + +#### 1.3.4. Executar o pipeline para testá-lo + +Vamos testar que o fluxo de trabalho ainda funciona como esperado, especificando um personagem diferente para verificar que a configuração `ext.args` está funcionando. + +Execute este comando usando `kosh`, uma das opções mais... enigmáticas: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Isso deve executar com sucesso como anteriormente. + +Vamos verificar que a configuração `ext.args` funcionou verificando a saída. +Encontre a saída no navegador de arquivos ou use o hash da tarefa (a parte `38/eb29ea` no exemplo acima) para visualizar o arquivo de saída: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Saída do comando" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +Você deve ver a arte ASCII exibida com o personagem `kosh`, confirmando que a configuração `ext.args` funcionou! + +??? info "(Opcional) Inspecionar o arquivo de comando" + + Se você quiser ver exatamente como a configuração foi aplicada, pode inspecionar o arquivo `.command.sh`: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + Você verá o comando `cowpy` com o argumento `-c kosh`: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Isso mostra que o arquivo `.command.sh` foi gerado corretamente com base na configuração `ext.args`. + +Reserve um momento para pensar sobre o que alcançamos aqui. +Esta abordagem mantém a interface do módulo focada em dados essenciais (arquivos, metadata e quaisquer parâmetros obrigatórios por amostra), enquanto opções que controlam o comportamento da ferramenta são tratadas separadamente através da configuração. + +Isso pode parecer desnecessário para uma ferramenta simples como `cowpy`, mas pode fazer uma grande diferença para ferramentas de análise de dados que têm muitos argumentos opcionais. + +Para resumir os benefícios desta abordagem: + +- **Interface limpa**: O módulo foca em entradas de dados essenciais (metadata e arquivos) +- **Flexibilidade**: Os usuários podem especificar argumentos de ferramentas via configuração, incluindo valores específicos por amostra +- **Consistência**: Todos os módulos nf-core seguem este padrão +- **Portabilidade**: Módulos podem ser reutilizados sem opções de ferramenta codificadas +- **Sem mudanças no fluxo de trabalho**: Adicionar ou alterar opções de ferramenta não requer atualizar o código do fluxo de trabalho + +!!! note + + O sistema `ext.args` tem capacidades adicionais poderosas não cobertas aqui, incluindo alternar valores de argumentos dinamicamente com base em metadata. Veja as [especificações de módulos nf-core](https://nf-co.re/docs/guidelines/components/modules) para mais detalhes. + +### 1.4. Padronizar a nomeação de saída com `ext.prefix` + +Agora que demos ao processo `COWPY` acesso ao metamap, podemos começar a aproveitar outro padrão útil do nf-core: nomear arquivos de saída com base em metadata. + +Aqui vamos usar um recurso do Nextflow chamado `ext.prefix` que nos permitirá padronizar a nomeação de arquivos de saída em todos os módulos usando `meta.id` (o identificador incluído no metamap), ainda sendo capaz de configurar módulos individualmente se desejado. + +Isso será semelhante ao que fizemos com `ext.args`, com algumas diferenças que detalharemos conforme avançamos. + +Vamos aplicar essa abordagem ao módulo `COWPY`. +Vamos precisar fazer as seguintes alterações: + +1. Atualizar o módulo `COWPY` +2. Configurar `ext.prefix` no arquivo `modules.config` + +(Nenhuma mudança necessária no fluxo de trabalho.) + +Uma vez que tivermos feito isso, executaremos o pipeline para testar que tudo ainda funciona como antes. + +#### 1.4.1. Atualizar o módulo `COWPY` + +Abra o arquivo do módulo `cowpy.nf` (em `core-hello/modules/local/`) e modifique-o para referenciar `ext.prefix` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Você pode ver que fizemos três mudanças. + +1. **No bloco `script:`, adicionamos a linha `prefix = task.ext.prefix ?: "${meta.id}"`.** + Essa linha usa o operador `?:` para determinar o valor da variável `prefix`: o conteúdo de `task.ext.prefix` se não estiver vazio, ou o identificador do metamap (`meta.id`) se estiver. + Note que embora geralmente nos referimos a `ext.prefix`, este código deve referenciar `task.ext.prefix` para extrair a configuração `ext.prefix` no nível do módulo. + +2. **Na linha de comando, substituímos `cowpy-${input_file}` por `${prefix}.txt`.** + É aqui que o Nextflow injetará o valor de `prefix` determinado pela linha acima. + +3. **No bloco `output:`, substituímos `path("cowpy-${input_file}")` por `path("${prefix}.txt")`.** + Isso simplesmente reitera qual será o caminho do arquivo de acordo com o que está escrito na linha de comando. + +Como resultado, o nome do arquivo de saída agora é construído usando um padrão sensato (o identificador do metamap) combinado com a extensão de formato de arquivo apropriada. + +#### 1.4.2. Configurar `ext.prefix` no arquivo `modules.config` + +Neste caso, o padrão sensato não é suficientemente expressivo para nosso gosto; queremos usar um padrão de nomeação personalizado que inclua o nome da ferramenta, `cowpy-<id>.txt`, como tínhamos antes. + +Faremos isso configurando `ext.prefix` em `modules.config`, assim como fizemos para o parâmetro `character` com `ext.args`, exceto que desta vez o bloco `withName: 'COWPY' {}` já existe, e só precisamos adicionar a seguinte linha: + +```groovy title="Código a adicionar" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Isso comporá a string que queremos. +Note que mais uma vez usamos chaves, desta vez para dizer ao Nextflow para avaliar o valor de `meta.id` em tempo de execução. + +Vamos adicionar. + +Abra `conf/modules.config` e adicione o código de configuração dentro do bloco `process {}` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Antes" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Caso você esteja se perguntando, a closure `ext.prefix` tem acesso ao pedaço correto de metadata porque a configuração é avaliada no contexto da execução do processo, onde os metadata estão disponíveis. + +#### 1.4.3. Executar o pipeline para testá-lo + +Vamos testar que o fluxo de trabalho ainda funciona como esperado. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dê uma olhada na saída no diretório de resultados. +Você deve ver o arquivo de saída do cowpy com a mesma nomeação de antes: `cowpy-test.txt`, baseado no nome de lote padrão. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Sinta-se à vontade para alterar a configuração `ext.prefix` em `conf/modules.config` para satisfazer-se de que você pode alterar o padrão de nomeação sem ter que fazer nenhuma mudança no código do módulo ou do fluxo de trabalho. + +Alternativamente, você também pode tentar executar isso novamente com um parâmetro `--batch` diferente especificado na linha de comando para satisfazer-se de que essa parte ainda é personalizável em tempo real. + +Isso demonstra como `ext.prefix` permite que você mantenha sua convenção de nomeação preferida enquanto mantém a interface do módulo flexível. + +Para resumir os benefícios desta abordagem: + +- **Nomeação padronizada**: Os arquivos de saída são tipicamente nomeados usando IDs de amostra dos metadata +- **Configurável**: Os usuários podem sobrescrever a nomeação padrão se necessário +- **Consistente**: Todos os módulos nf-core seguem este padrão +- **Previsível**: Fácil saber como os arquivos de saída serão chamados + +Muito bom, certo? +Bem, há mais uma mudança importante que precisamos fazer para melhorar nosso módulo para se ajustar às diretrizes nf-core. + +### 1.5. Centralizar a configuração de publicação + +Você pode ter notado que temos publicado saídas em dois diretórios diferentes: + +- **`results`** — O diretório de saída original que temos usado desde o início para nossos módulos locais, definido individualmente usando diretivas `publishDir` por módulo; +- **`core-hello-results`** — O diretório de saída definido com `--outdir` na linha de comando, que tem recebido os logs nf-core e os resultados publicados pelo `CAT_CAT`. + +Isso é confuso e subótimo; seria melhor ter um local para tudo. +Claro, poderíamos entrar em cada um de nossos módulos locais e atualizar a diretiva `publishDir` manualmente para usar o diretório `core-hello-results`, mas e na próxima vez que decidirmos mudar o diretório de saída? + +Ter módulos individuais tomando decisões de publicação claramente não é o caminho a seguir, especialmente em um mundo onde o mesmo módulo pode ser usado em muitos pipelines diferentes, por pessoas que têm necessidades ou preferências diferentes. +Queremos ser capazes de controlar onde as saídas são publicadas no nível da configuração do fluxo de trabalho. + +"Ei," você pode dizer, "`CAT_CAT` está enviando suas saídas para o `--outdir`. Talvez devêssemos copiar sua diretiva `publishDir`?" + +Sim, essa é uma ótima ideia. + +Exceto que ele não tem uma diretiva `publishDir`. (Vá em frente, olhe o código do módulo.) + +Isso porque os pipelines nf-core centralizam o controle no nível do fluxo de trabalho configurando `publishDir` em `conf/modules.config` em vez de em módulos individuais. +Especificamente, o template nf-core declara uma diretiva `publishDir` padrão (com uma estrutura de diretórios predefinida) que se aplica a todos os módulos, a menos que uma diretiva sobrescrevendo seja fornecida. + +Isso não parece incrível? Seria possível que para aproveitar essa diretiva padrão, tudo o que precisamos fazer é remover a diretiva `publishDir` atual de nossos módulos locais? + +Vamos tentar isso no `COWPY` para ver o que acontece, então veremos o código para a configuração padrão para entender como funciona. + +Finalmente, demonstraremos como sobrescrever o comportamento padrão se desejado. + +#### 1.5.1. Remover a diretiva `publishDir` do `COWPY` + +Vamos fazer isso. +Abra o arquivo do módulo `cowpy.nf` (em `core-hello/modules/local/`) e remova a diretiva `publishDir` como mostrado abaixo. + +=== "Depois" + + ```groovy title="core-hello/modules/local/cowpy.nf (trecho)" linenums="1" + #!/usr/bin/env nextflow + + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Antes" + + ```groovy title="core-hello/modules/local/cowpy.nf (trecho)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +É isso! + +#### 1.5.2. Executar o pipeline para testá-lo + +Vamos dar uma olhada no que acontece se executarmos o pipeline agora. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Dê uma olhada no seu diretório de trabalho atual. +Agora o `core-hello-results` também contém as saídas do módulo `COWPY`. + +??? abstract "Conteúdo do diretório" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Você pode ver que o Nextflow criou essa hierarquia de diretórios baseada nos nomes do fluxo de trabalho e do módulo. + +O código responsável vive no arquivo `conf/modules.config`. +Esta é a configuração `publishDir` padrão que faz parte do template nf-core e se aplica a todos os processos: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Isso pode parecer complicado, então vamos olhar cada um dos três componentes: + +- **`path:`** Determina o diretório de saída com base no nome do processo. + O nome completo de um processo contido em `task.process` inclui a hierarquia de importações de fluxo de trabalho e módulo (como `CORE_HELLO:HELLO:CAT_CAT`). + As operações `tokenize` removem essa hierarquia para obter apenas o nome do processo, então pegam a primeira parte antes de qualquer underscore (se aplicável), e convertem para minúsculas. + Isso é o que determina que os resultados do `CAT_CAT` sejam publicados em `${params.outdir}/cat/`. +- **`mode:`** Controla como os arquivos são publicados (copy, symlink, etc.). + Isso é configurável via o parâmetro `params.publish_dir_mode`. +- **`saveAs:`** Filtra quais arquivos publicar. + Este exemplo exclui arquivos `versions.yml` retornando `null` para eles, impedindo que sejam publicados. + +Isso fornece uma lógica consistente para organizar saídas. + +A saída fica ainda melhor quando todos os módulos em um pipeline adotam essa convenção, então sinta-se à vontade para ir deletar as diretivas `publishDir` dos outros módulos em seu pipeline. +Esse padrão será aplicado mesmo a módulos que não modificamos explicitamente para seguir as diretrizes nf-core. + +Dito isso, você pode decidir que deseja organizar suas entradas de forma diferente, e a boa notícia é que é fácil fazer isso. + +#### 1.5.3. Sobrescrever o padrão + +Para sobrescrever a diretiva `publishDir` padrão, você pode simplesmente adicionar suas próprias diretivas ao arquivo `conf/modules.config`. + +Por exemplo, você poderia sobrescrever o padrão para um único processo usando o seletor `withName:`, como neste exemplo onde adicionamos uma diretiva `publishDir` personalizada para o processo 'COWPY'. + +```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + publishDir = [ + path: 'my_custom_results' + ] + } +} +``` + +Não vamos realmente fazer essa mudança, mas sinta-se à vontade para experimentar isso e ver que lógica você pode implementar. + +O ponto é que esse sistema permite que você tenha o melhor de ambos os mundos: consistência por padrão e a flexibilidade para personalizar a configuração sob demanda. + +Para resumir, você obtém: + +- **Fonte única de verdade**: Toda configuração de publicação vive em `modules.config` +- **Padrão útil**: Processos funcionam prontos para uso sem configuração por módulo +- **Personalização fácil**: Sobrescreva o comportamento de publicação na configuração, não no código do módulo +- **Módulos portáteis**: Módulos não codificam locais de saída + +Isso completa o conjunto de recursos de módulos nf-core que você deve absolutamente aprender a usar, mas há outros que você pode ler sobre nas [especificações de módulos nf-core](https://nf-co.re/docs/guidelines/components/modules). + +### Conclusão + +Você agora sabe como adaptar módulos locais para seguir as convenções nf-core: + +- Projete seus módulos para aceitar e propagar tuplas de metadata; +- Use `ext.args` para manter as interfaces dos módulos mínimas e portáteis; +- Use `ext.prefix` para nomeação de arquivos de saída configurável e padronizada; +- Adote a diretiva `publishDir` centralizada padrão para uma estrutura consistente de diretório de resultados. + +### O que vem a seguir? + +Aprenda como usar as ferramentas integradas baseadas em template do nf-core para criar módulos de forma mais fácil. + +--- + +## 2. Criar um módulo com as ferramentas nf-core + +Agora que você aprendeu os padrões de módulos nf-core aplicando-os manualmente, vamos ver como você criaria módulos na prática. + +### 2.1. Gerar um scaffold de módulo a partir de um template + +Semelhante ao que existe para criar pipelines, o projeto nf-core fornece ferramentas para gerar módulos adequadamente estruturados baseados em um template, com todos esses padrões incorporados desde o início. + +#### 2.1.1. Executar o comando de criação de módulo + +O comando `nf-core modules create` gera um template de módulo que já segue todas as convenções que você aprendeu. + +Vamos criar uma nova versão do módulo `COWPY` com um template mínimo executando este comando: + +```bash +nf-core modules create --empty-template COWPY +``` + +A flag `--empty-template` cria um template inicial limpo sem código extra, facilitando ver a estrutura essencial. + +O comando é executado interativamente, guiando você pela configuração. +Ele automaticamente busca informações da ferramenta de repositórios de pacotes como Bioconda e bio.tools para pré-popular metadata. + +Você será solicitado para várias opções de configuração: + +- **Informações do autor**: Seu nome de usuário do GitHub para atribuição +- **Label de recurso**: Um conjunto predefinido de requisitos computacionais. + O projeto nf-core fornece labels padrão como `process_single` para ferramentas leves e `process_high` para as exigentes. + Essas labels ajudam a gerenciar alocação de recursos em diferentes ambientes de execução. +- **Requisito de metadata**: Se o módulo precisa de informações específicas da amostra via um map `meta` (geralmente sim para módulos de processamento de dados). + +A ferramenta lida com a complexidade de encontrar informações de pacotes e configurar a estrutura, permitindo que você se concentre em implementar a lógica específica da ferramenta. + +#### 2.1.2. Examinar o scaffold do módulo + +A ferramenta cria uma estrutura completa de módulo em `modules/local/` (ou `modules/nf-core/` se você estiver no repositório nf-core/modules): + +??? abstract "Conteúdo do diretório" + + ```console + modules/local/cowpy + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + └── main.nf.test + ``` + +Cada arquivo serve um propósito específico: + +- **`main.nf`**: Definição do processo com todos os padrões nf-core incorporados +- **`meta.yml`**: Documentação do módulo descrevendo entradas, saídas e a ferramenta +- **`environment.yml`**: Especificação de ambiente Conda para dependências +- **`tests/main.nf.test`**: Casos de teste nf-test para validar que o módulo funciona + +!!! tip "Saiba mais sobre testes" + + O arquivo de teste gerado usa nf-test, um framework de testes para pipelines e módulos Nextflow. Para aprender como escrever e executar esses testes, veja a [missão paralela nf-test](../side_quests/nf-test.md). + +O `main.nf` gerado inclui todos os padrões que você acabou de aprender, mais alguns recursos adicionais: + +```groovy title="modules/local/cowpy/main.nf" hl_lines="11 21 22" +process COWPY { + tag "$meta.id" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/YOUR-TOOL-HERE': + 'biocontainers/YOUR-TOOL-HERE' }" + + input: + tuple val(meta), path(input) // Padrão 1: Tuplas de metadata ✓ + + output: + tuple val(meta), path("*"), emit: output + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' // Padrão 2: ext.args ✓ + def prefix = task.ext.prefix ?: "${meta.id}" // Padrão +``` diff --git a/docs/pt/docs/hello_nf-core/05_input_validation.md b/docs/pt/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..4fd6b9d258 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Parte 5: Validação de entrada + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na quinta parte do curso de treinamento Hello nf-core, mostramos como usar o plugin nf-schema para validar entradas e parâmetros do pipeline. + +??? info "Como começar a partir desta seção" + + Esta seção assume que você completou a [Parte 4: Criar um módulo nf-core](./04_make_module.md) e atualizou o módulo de processo `COWPY` para os padrões nf-core em seu pipeline. + + Se você não completou a Parte 4 ou quer começar do zero para esta parte, pode usar a solução `core-hello-part4` como ponto de partida. + Execute estes comandos de dentro do diretório `hello-nf-core/`: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Isso fornece um pipeline com o módulo `COWPY` já atualizado para seguir os padrões nf-core. + Você pode testar se ele executa com sucesso executando o seguinte comando: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Aquecimento: Um pouco de contexto + +### 0.1. Por que a validação é importante + +Imagine executar seu pipeline por duas horas, apenas para ele falhar porque um usuário forneceu um arquivo com a extensão errada. Ou passar horas depurando erros enigmáticos, apenas para descobrir que um parâmetro foi escrito incorretamente. Sem validação de entrada, esses cenários são comuns. + +Considere este exemplo: + +```console title="Sem validação" +$ nextflow run my-pipeline --input data.txt --output results + +...2 horas depois... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +O pipeline aceitou entradas inválidas e executou por horas antes de falhar. Com validação adequada: + +```console title="Com validação" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +O pipeline falha imediatamente com mensagens de erro claras e acionáveis. Isso economiza tempo, recursos computacionais e frustração. + +### 0.2. O plugin nf-schema + +O [plugin nf-schema](https://nextflow-io.github.io/nf-schema/latest/) é um plugin Nextflow que fornece capacidades abrangentes de validação para pipelines Nextflow. +Embora o nf-schema funcione com qualquer fluxo de trabalho Nextflow, é a solução de validação padrão para todos os pipelines nf-core. + +O nf-schema fornece várias funções principais: + +- **Validação de parâmetros**: Valida parâmetros do pipeline contra `nextflow_schema.json` +- **Validação de planilha de amostras**: Valida arquivos de entrada contra `assets/schema_input.json` +- **Conversão de canal**: Converte planilhas de amostras validadas em canais Nextflow +- **Geração de texto de ajuda**: Gera automaticamente saída `--help` a partir de definições de schema +- **Resumo de parâmetros**: Exibe quais parâmetros diferem dos padrões + +O nf-schema é o sucessor do plugin nf-validation descontinuado e usa o padrão [JSON Schema Draft 2020-12](https://json-schema.org/) para validação. + +??? info "O que são plugins Nextflow?" + + Plugins são extensões que adicionam novas funcionalidades à própria linguagem Nextflow. Eles são instalados via um bloco `plugins{}` em `nextflow.config` e podem fornecer: + + - Novas funções e classes que podem ser importadas (como `samplesheetToList`) + - Novos recursos DSL e operadores + - Integração com serviços externos + + O plugin nf-schema é especificado em `nextflow.config`: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Uma vez instalado, você pode importar funções de plugins usando a sintaxe `include { functionName } from 'plugin/plugin-name'`. + +### 0.3. Dois arquivos de schema para dois tipos de validação + +Um pipeline nf-core utilizará dois arquivos de schema separados, que correspondem a dois tipos de validação: + +| Arquivo de Schema | Propósito | Valida | +| -------------------------- | ----------------------------- | ----------------------------------------------------------- | +| `nextflow_schema.json` | Validação de parâmetros | Flags de linha de comando: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Validação de dados de entrada | Conteúdo de planilhas de amostras e arquivos de entrada | + +Ambos os schemas usam o formato JSON Schema, um padrão amplamente adotado para descrever e validar estruturas de dados. + +**Validação de parâmetros** valida parâmetros de linha de comando (flags como `--outdir`, `--batch`, `--input`): + +- Verifica tipos, intervalos e formatos de parâmetros +- Garante que parâmetros obrigatórios sejam fornecidos +- Valida se os caminhos de arquivo existem +- Definida em `nextflow_schema.json` + +**Validação de dados de entrada** valida a estrutura de planilhas de amostras e arquivos de manifesto (arquivos CSV/TSV que descrevem seus dados): + +- Verifica estrutura de colunas e tipos de dados +- Valida se os caminhos de arquivo referenciados na planilha de amostras existem +- Garante que campos obrigatórios estejam presentes +- Definida em `assets/schema_input.json` + +!!! warning "O que a validação de dados de entrada NÃO faz" + + A validação de dados de entrada verifica a estrutura de *arquivos de manifesto* (planilhas de amostras, arquivos CSV), NÃO o conteúdo dos seus arquivos de dados reais (FASTQ, BAM, VCF, etc.). + + Para dados em larga escala, validar o conteúdo dos arquivos (como verificar a integridade de BAM) deve acontecer em processos do pipeline executando em nós de trabalho, não durante a etapa de validação na máquina de orquestração. + +### 0.4. Quando a validação deve ocorrer? + +```mermaid +graph LR + A[Usuário executa o pipeline] --> B[Validação de parâmetros] + B -->|✓ Válido| C[Validação de dados de entrada] + B -->|✗ Inválido| D[Erro: Corrigir parâmetros] + C -->|✓ Válido| E[Pipeline executa] + C -->|✗ Inválido| F[Erro: Corrigir dados de entrada] +``` + +A validação deve acontecer **antes** de qualquer processo do pipeline executar, para fornecer feedback rápido e evitar tempo de computação desperdiçado. + +Agora vamos aplicar esses princípios na prática, começando com a validação de parâmetros. + +--- + +## 1. Validação de parâmetros (nextflow_schema.json) + +Vamos começar adicionando validação de parâmetros ao nosso pipeline. Isso valida flags de linha de comando como `--input`, `--outdir` e `--batch`. + +### 1.1. Configurar a validação para ignorar validação de arquivo de entrada + +O template de pipeline nf-core vem com o nf-schema já instalado e configurado: + +- O plugin nf-schema é instalado via o bloco `plugins{}` em `nextflow.config` +- A validação de parâmetros é habilitada por padrão via `params.validate_params = true` +- A validação é realizada pelo subworkflow `UTILS_NFSCHEMA_PLUGIN` durante a inicialização do pipeline + +O comportamento de validação é controlado através do escopo `validation{}` em `nextflow.config`. + +Como estaremos trabalhando na validação de parâmetros primeiro (esta seção) e não configuraremos o schema de dados de entrada até a seção 2, precisamos temporariamente dizer ao nf-schema para ignorar a validação do conteúdo do arquivo do parâmetro `input`. + +Abra `nextflow.config` e encontre o bloco `validation` (por volta da linha 246). Adicione `ignoreParams` para ignorar a validação de arquivo de entrada: + +=== "Depois" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Esta configuração diz ao nf-schema para: + +- **`defaultIgnoreParams`**: Ignorar validação de parâmetros complexos como `genomes` (definido pelos desenvolvedores do template) +- **`ignoreParams`**: Ignorar validação do conteúdo do arquivo do parâmetro `input` (temporário; vamos reabilitar isso na seção 2) +- **`monochromeLogs`**: Desabilitar saída colorida em mensagens de validação quando definido como `true` (controlado por `params.monochrome_logs`) + +!!! note "Por que ignorar o parâmetro input?" + + O parâmetro `input` em `nextflow_schema.json` tem `"schema": "assets/schema_input.json"` que diz ao nf-schema para validar o *conteúdo* do arquivo CSV de entrada contra esse schema. + Como ainda não configuramos esse schema, temporariamente ignoramos essa validação. + Removeremos essa configuração na seção 2 após configurar o schema de dados de entrada. + +### 1.2. Examinar o schema de parâmetros + +Vamos olhar uma seção do arquivo `nextflow_schema.json` que veio com nosso template de pipeline: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +O schema de parâmetros é organizado em grupos. Aqui está o grupo `input_output_options`: + +```json title="core-hello/nextflow_schema.json (trecho)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Cada entrada descrita aqui tem as seguintes propriedades principais que podem ser validadas: + +- **`type`**: Tipo de dado (string, integer, boolean, number) +- **`format`**: Formatos especiais como `file-path` ou `directory-path` +- **`exists`**: Para caminhos de arquivo, verifica se o arquivo existe +- **`pattern`**: Expressão regular que o valor deve corresponder +- **`required`**: Array de nomes de parâmetros que devem ser fornecidos +- **`mimetype`**: Mimetype de arquivo esperado para validação + +Se você tem olhar afiado, pode perceber que o parâmetro de entrada `batch` que temos usado ainda não está definido no schema. +Vamos adicioná-lo na próxima seção. + +??? info "De onde vêm os parâmetros do schema?" + + A validação do schema usa `nextflow.config` como base para definições de parâmetros. + Parâmetros declarados em outros lugares nos seus scripts de fluxo de trabalho (como em `main.nf` ou arquivos de módulo) **não** são automaticamente capturados pelo validador de schema. + + Isso significa que você deve sempre declarar seus parâmetros de pipeline em `nextflow.config`, e então definir suas regras de validação em `nextflow_schema.json`. + +### 1.3. Adicionar o parâmetro batch + +Embora o schema seja um arquivo JSON que possa ser editado manualmente, **a edição manual é propensa a erros e não é recomendada**. +Em vez disso, o nf-core fornece uma ferramenta GUI interativa que manipula a sintaxe JSON Schema para você e valida suas alterações: + +```bash +nf-core pipelines schema build +``` + +Você deve ver algo assim: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Digite `y` e pressione Enter para iniciar a interface web interativa. + +Seu navegador abrirá mostrando o construtor de schema de parâmetros: + +![Interface do construtor de schema](./img/schema_build.png) + +Para adicionar o parâmetro `batch`: + +1. Clique no botão **"Add parameter"** no topo +2. Use a alça de arrastar (⋮⋮) para mover o novo parâmetro para cima no grupo "Input/output options", abaixo do parâmetro `input` +3. Preencha os detalhes do parâmetro: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: marque a caixa de seleção + - Opcionalmente, selecione um ícone do seletor de ícones (ex: `fas fa-layer-group`) + +![Adicionando o parâmetro batch](./img/schema_add.png) + +Quando terminar, clique no botão **"Finished"** no canto superior direito. + +De volta ao seu terminal, você verá: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Pressione `Ctrl+C` para sair do construtor de schema. + +A ferramenta agora atualizou seu arquivo `nextflow_schema.json` com o novo parâmetro `batch`, manipulando toda a sintaxe JSON Schema corretamente. + +### 1.4. Verificar as alterações + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (trecho)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +Você deve ver que o parâmetro `batch` foi adicionado ao schema com o campo "required" agora mostrando `["input", "outdir", "batch"]`. + +### 1.5. Testar a validação de parâmetros + +Agora vamos testar que a validação de parâmetros funciona corretamente. + +Primeiro, tente executar sem o parâmetro obrigatório `input`: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Saída do comando" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Perfeito! A validação captura o parâmetro obrigatório faltante antes do pipeline executar. + +Agora tente com um conjunto válido de parâmetros: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +O pipeline deve executar com sucesso, e o parâmetro `batch` agora está validado. + +### Conclusão + +Você aprendeu como usar a ferramenta interativa `nf-core pipelines schema build` para adicionar parâmetros ao `nextflow_schema.json` e viu a validação de parâmetros em ação. +A interface web manipula toda a sintaxe JSON Schema para você, facilitando o gerenciamento de schemas de parâmetros complexos sem edição JSON manual propensa a erros. + +### Próximos passos + +Agora que a validação de parâmetros está funcionando, vamos adicionar validação para o conteúdo do arquivo de dados de entrada. + +--- + +## 2. Validação de dados de entrada (schema_input.json) + +Vamos adicionar validação para o conteúdo do nosso arquivo CSV de entrada. +Enquanto a validação de parâmetros verifica flags de linha de comando, a validação de dados de entrada garante que os dados dentro do arquivo CSV estejam estruturados corretamente. + +### 2.1. Entender o formato greetings.csv + +Vamos relembrar como nossa entrada se parece: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Este é um CSV simples com: + +- Três colunas (sem cabeçalho) +- Em cada linha: uma saudação, um idioma e uma pontuação +- As duas primeiras colunas são strings de texto sem requisitos de formato especiais +- A terceira coluna é um inteiro + +Para nosso pipeline, apenas a primeira coluna é obrigatória. + +### 2.2. Projetar a estrutura do schema + +Para nosso caso de uso, queremos: + +1. Aceitar entrada CSV com pelo menos uma coluna +2. Tratar o primeiro elemento de cada linha como uma string de saudação +3. Garantir que as saudações não estejam vazias e não comecem com espaço em branco +4. Garantir que o campo de idioma corresponda a um dos códigos de idioma suportados (en, fr, es, it, de) +5. Garantir que o campo de pontuação seja um inteiro com valor entre 0 e 100 + +Vamos estruturar isso como um array de objetos, onde cada objeto tem pelo menos um campo `greeting`. + +### 2.3. Atualizar o arquivo de schema + +O template de pipeline nf-core inclui um `assets/schema_input.json` padrão projetado para dados de sequenciamento paired-end. +Precisamos substituí-lo por um schema mais simples para nosso caso de uso de saudações. + +Abra `assets/schema_input.json` e substitua as seções `properties` e `required`: + +=== "Depois" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Antes" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +As principais mudanças: + +- **`description`**: Atualizada para mencionar "greetings file" +- **`properties`**: Substituídas `sample`, `fastq_1` e `fastq_2` por `greeting`, `language` e `score` + - **`type:`** Impõe string (`greeting`, `language`) ou integer (`score`) + - **`pattern: "^\\S.*$"`**: A saudação deve começar com um caractere que não seja espaço em branco (mas pode conter espaços depois disso) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: O código de idioma deve estar no conjunto suportado + - **`"minimum": 0` e `"maximum": 100`**: O valor da pontuação deve estar entre 0 e 100 + - **`errorMessage`**: Mensagem de erro personalizada mostrada se a validação falhar +- **`required`**: Alterado de `["sample", "fastq_1"]` para `["greeting"]` + +### 2.4. Adicionar um cabeçalho ao arquivo greetings.csv + +Quando o nf-schema lê um arquivo CSV, ele espera que a primeira linha contenha cabeçalhos de colunas que correspondam aos nomes de campos no schema. + +Para nosso caso simples, precisamos adicionar uma linha de cabeçalho ao nosso arquivo de saudações: + +=== "Depois" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Antes" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Agora o arquivo CSV tem uma linha de cabeçalho que corresponde aos nomes de campos em nosso schema. + +O passo final é implementar a validação no código do pipeline usando `samplesheetToList`. + +### 2.5. Implementar validação no pipeline + +Agora precisamos substituir nossa análise CSV simples pela função `samplesheetToList` do nf-schema, que validará e analisará a planilha de amostras. + +A função `samplesheetToList`: + +1. Lê a planilha de amostras de entrada (CSV, TSV, JSON ou YAML) +2. Valida contra o schema JSON fornecido +3. Retorna uma lista Groovy onde cada entrada corresponde a uma linha +4. Lança mensagens de erro úteis se a validação falhar + +Vamos atualizar o código de manipulação de entrada: + +Abra `subworkflows/local/utils_nfcore_hello_pipeline/main.nf` e localize a seção onde criamos o canal de entrada (por volta da linha 80). + +Precisamos: + +1. Usar a função `samplesheetToList` (já importada no template) +2. Validar e analisar a entrada +3. Extrair apenas as strings de saudação para nosso fluxo de trabalho + +Primeiro, note que a função `samplesheetToList` já está importada no topo do arquivo (o template nf-core inclui isso por padrão): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subfluxo de trabalho com funcionalidade específica para o pipeline core/hello +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Agora atualize o código de criação do canal: + +=== "Depois" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Cria canal a partir do arquivo de entrada fornecido através de params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Antes" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Cria canal a partir do arquivo de entrada fornecido através de params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Vamos detalhar o que mudou: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Valida o arquivo de entrada contra nosso schema e retorna uma lista +2. **`Channel.fromList(...)`**: Converte a lista em um canal Nextflow + +Isso completa a implementação da validação de dados de entrada usando `samplesheetToList` e schemas JSON. + +Agora que configuramos o schema de dados de entrada, podemos remover a configuração de ignorar temporária que adicionamos anteriormente. + +### 2.6. Reabilitar validação de entrada + +Abra `nextflow.config` e remova a linha `ignoreParams` do bloco `validation`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Agora o nf-schema validará tanto os tipos de parâmetros QUANTO o conteúdo do arquivo de entrada. + +### 2.7. Testar validação de entrada + +Vamos verificar que nossa validação funciona testando entradas válidas e inválidas. + +#### 2.7.1. Testar com entrada válida + +Primeiro, confirme que o pipeline executa com sucesso com entrada válida. +Note que não precisamos mais de `--validate_params false` já que a validação está funcionando! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Saída do comando" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Ótimo! O pipeline executa com sucesso e a validação passa silenciosamente. +O aviso sobre `--character` é apenas informativo já que não está definido no schema. +Se quiser, use o que aprendeu para adicionar validação para esse parâmetro também! + +#### 2.7.2. Testar com entrada inválida + +Passar na validação é sempre uma boa sensação, mas vamos garantir que a validação realmente capturará erros. + +Para criar um arquivo de teste com um nome de coluna inválido, comece fazendo uma cópia do arquivo `greetings.csv`: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Agora abra o arquivo e mude o nome da primeira coluna, na linha de cabeçalho, de `greeting` para `message`: + +=== "Depois" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Antes" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Isso não corresponde ao nosso schema, então a validação deve lançar um erro. + +Tente executar o pipeline com esta entrada inválida: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Perfeito! A validação capturou o erro e forneceu uma mensagem de erro clara e útil apontando para: + +- Qual arquivo falhou na validação +- Qual entrada (linha 1, a primeira linha de dados) tem o problema +- Qual é o problema específico (campo obrigatório `greeting` ausente) + +A validação do schema garante que os arquivos de entrada tenham a estrutura correta antes do pipeline executar, economizando tempo e prevenindo erros confusos mais tarde na execução. + +Se quiser praticar isso, sinta-se livre para criar outros arquivos de entrada de saudações que violem o schema de outras maneiras divertidas. + +### Conclusão + +Você implementou e testou tanto a validação de parâmetros quanto a validação de dados de entrada. Seu pipeline agora valida entradas antes da execução, fornecendo feedback rápido e mensagens de erro claras. + +!!! tip "Leitura adicional" + + Para aprender mais sobre recursos e padrões avançados de validação, consulte a [documentação do nf-schema](https://nextflow-io.github.io/nf-schema/latest/). O comando `nf-core pipelines schema build` fornece uma GUI interativa para gerenciar schemas complexos. + +### Próximos passos + +Você completou todas as cinco partes do curso de treinamento Hello nf-core! + +Continue para o [Resumo](summary.md) para refletir sobre o que você construiu e aprendeu. diff --git a/docs/pt/docs/hello_nf-core/index.md b/docs/pt/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..5469c42fa8 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/index.md @@ -0,0 +1,67 @@ +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Recuperar, executar e gerenciar a execução de pipelines nf-core + - Descrever a estrutura do código e a organização do projeto dos pipelines nf-core + - Criar um pipeline básico compatível com nf-core a partir de um template + - Atualizar um fluxo de trabalho Nextflow simples para se adequar aos padrões nf-core + - Adicionar módulos nf-core a um pipeline compatível com nf-core + - Contribuir com seus próprios módulos para o nf-core + - Validar entradas e parâmetros usando ferramentas nf-core + audience_prerequisites: + - "**Público:** Este curso é projetado para alunos que já estão familiarizados com Nextflow básico e querem aprender a usar recursos e melhores práticas do nf-core." + - "**Habilidades:** Familiaridade com a linha de comando, conceitos básicos de script e formatos de arquivo comuns é assumida." + - "**Cursos:** Deve ter completado o curso [Hello Nextflow](../hello_nextflow/index.md) ou equivalente." + - "**Domínio:** Os exercícios são todos agnósticos de domínio, portanto nenhum conhecimento científico prévio é necessário." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core é uma introdução prática ao uso de recursos e melhores práticas do nf-core.** + +![nf-core logo](./img/nf-core-logo.png) + +Através de exemplos práticos e exercícios guiados, você aprenderá a usar e desenvolver módulos e pipelines compatíveis com nf-core, e a utilizar as ferramentas nf-core de forma eficaz. + +Você adquirirá as habilidades e a confiança para começar a desenvolver pipelines de acordo com as melhores práticas do nf-core. + +<!-- additional_information --> + +## Visão geral do curso + +Este curso é projetado para ser prático, com exercícios orientados a objetivos estruturados para introduzir informações gradualmente. + +Você será apresentado ao [**nf-core**](https://nf-co.re/), um esforço comunitário para desenvolver e manter um conjunto curado de pipelines científicos construídos usando Nextflow, bem como ferramentas e diretrizes relevantes que promovem desenvolvimento aberto, testes e revisão por pares ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +Os pipelines desenvolvidos pela comunidade nf-core são projetados para serem modulares, escaláveis e portáteis, permitindo que pesquisadores os adaptem e executem facilmente usando seus próprios dados e recursos computacionais. +As diretrizes de melhores práticas aplicadas pelo projeto garantem ainda que os pipelines sejam robustos, bem documentados e validados contra conjuntos de dados do mundo real. +Isso ajuda a aumentar a confiabilidade e reprodutibilidade das análises científicas e, em última análise, permite que pesquisadores acelerem suas descobertas científicas. + +Não cobriremos tudo o que há para saber sobre pipelines nf-core neste curso, porque o nf-core abrange muitos recursos e convenções desenvolvidos pela comunidade ao longo dos anos. +Em vez disso, focaremos nos conceitos essenciais que ajudarão você a começar e entender como o nf-core funciona. + +### Plano de aulas + +Dividimos isso em cinco partes, cada uma focando em aspectos específicos do uso de recursos nf-core. + +| Capítulo do curso | Resumo | Duração estimada | +| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | +| [Parte 1: Execute um pipeline demo](./01_run_demo.md) | Execute um pipeline nf-core existente e examine sua estrutura de código para ter uma noção do que torna esses pipelines diferentes de fluxos de trabalho Nextflow básicos | 30 minutos | +| [Parte 2: Reescreva Hello para nf-core](./02_rewrite_hello.md) | Adapte um fluxo de trabalho existente ao modelo de estrutura nf-core, começando pelo fluxo de trabalho simples produzido no curso [Hello Nextflow](../hello_nextflow/index.md) | 60 minutos | +| [Parte 3: Use um módulo nf-core](./03_use_module.md) | Explore a biblioteca de módulos da comunidade e aprenda a integrar módulos pré-construídos e testados que encapsulam ferramentas de bioinformática comuns | 30 minutos | +| [Parte 4: Crie um módulo nf-core](./04_make_module.md) | Crie seu próprio módulo no estilo nf-core usando a estrutura específica, convenções de nomenclatura e requisitos de metadados estabelecidos pelo nf-core | 30 minutos | +| [Parte 5: Adicione validação de entrada](./05_input_validation.md) | Implemente validação de entrada tanto para parâmetros de linha de comando quanto para arquivos de dados de entrada usando nf-schema | 30 minutos | + +Ao final deste curso, você será capaz de aproveitar a enorme riqueza de recursos oferecidos pelo projeto nf-core. + +Pronto para fazer o curso? + +[Começar a aprender :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/pt/docs/hello_nf-core/next_steps.md b/docs/pt/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..618f13350d --- /dev/null +++ b/docs/pt/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Resumo do curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns por concluir o curso de treinamento Hello nf-core! 🎉 + +<!-- placeholder for video --> + +## Sua jornada + +Você começou aprendendo a recuperar e executar um pipeline de demonstração, depois enfrentou a conversão de um fluxo de trabalho simples do Nextflow em um pipeline nf-core. +Você aprendeu como criar uma estrutura de pipeline usando um template e enxertou o pipeline existente nessa estrutura. +Em seguida, você refinou gradualmente o pipeline substituindo um dos módulos locais por um módulo nf-core, transformou outro dos módulos locais para se adequar aos padrões nf-core e adicionou validação de entrada. + +### O que você construiu + +Seu pipeline final `core-hello` agora possui: + +- **Estrutura padronizada** usando o template nf-core com diretórios organizados para fluxos de trabalho, subfluxos de trabalho, módulos e configuração +- **Módulos da comunidade** do repositório nf-core (`cat/cat`) junto com seus módulos personalizados +- **Validação abrangente** que verifica tanto parâmetros quanto dados de entrada antes da execução do pipeline +- **Configuração profissional** com perfis para diferentes ambientes de execução +- **Documentação completa** e metadados seguindo as convenções nf-core + +### Principais habilidades adquiridas + +Através deste curso prático, você aprendeu a: + +1. **Navegar e entender** a estrutura de pipelines nf-core explorando um pipeline existente +2. **Reestruturar fluxos de trabalho** para serem compostos e se ajustarem ao template nf-core +3. **Encontrar e integrar** módulos pré-construídos do repositório da comunidade +4. **Criar módulos personalizados** seguindo os padrões nf-core para nomenclatura, estrutura e metadados +5. **Implementar validação** usando nf-schema para detectar erros precocemente com feedback claro + +Você está agora equipado com o conhecimento fundamental para construir pipelines nf-core prontos para produção que seguem as melhores práticas da comunidade. + +## Próximos passos para desenvolver suas habilidades + +Aqui estão nossas 3 principais sugestões para o que fazer a seguir: + +- Aplique Nextflow a um caso de uso de análise científica com [Nextflow for Science](../nf4_science/index.md) +- Explore recursos mais avançados do Nextflow com as [Side Quests](../side_quests/index.md) +- Envolva-se [juntando-se à comunidade nf-core](https://nf-co.re/join). + +Por fim, recomendamos que você dê uma olhada na [**Seqera Platform**](https://seqera.io/), uma plataforma baseada em nuvem desenvolvida pelos criadores do Nextflow que torna ainda mais fácil lançar e gerenciar seus fluxos de trabalho, além de gerenciar seus dados e executar análises interativamente em qualquer ambiente. + +## Pesquisa de feedback + +Antes de prosseguir, reserve um minuto para completar a pesquisa do curso! Seu feedback nos ajuda a melhorar nossos materiais de treinamento para todos. + +[Responder à pesquisa :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pt/docs/hello_nf-core/survey.md b/docs/pt/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..ef74e36041 --- /dev/null +++ b/docs/pt/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Pesquisa de feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de prosseguir, por favor complete esta breve pesquisa de 5 perguntas para avaliar o treinamento, compartilhar qualquer feedback que você possa ter sobre sua experiência e nos informar o que mais poderíamos fazer para ajudá-lo em sua jornada com Nextflow. + +Isso deve levar menos de um minuto para completar. Obrigado por nos ajudar a melhorar nossos materiais de treinamento para todos! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pt/docs/help.md b/docs/pt/docs/help.md new file mode 100644 index 0000000000..787f8811b3 --- /dev/null +++ b/docs/pt/docs/help.md @@ -0,0 +1,78 @@ +--- +title: Obtendo ajuda +description: Recursos úteis quando você tiver um problema com o treinamento do Nextflow +hide: + - toc + - footer +--- + +# Obtendo ajuda + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Se você está tendo dificuldades para começar, ficou travado no meio do caminho ou tem perguntas adicionais, não hesite em entrar em contato! +Nossa equipe da comunidade está aqui para ajudar, e a comunidade Nextflow em geral é muito ativa, inclusiva e sempre disposta a ajudar. + +Aqui estão as principais opções disponíveis, dependendo do que você está procurando. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Fórum da comunidade__ + + --- + + Nosso fórum da comunidade tem uma categoria dedicada ao treinamento, que é um ótimo lugar para postar perguntas ou relatar quaisquer problemas que você possa estar tendo com o treinamento. Você pode até encontrar sua pergunta já feita --e respondida! + + [Acesse o fórum de treinamento:material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Canal no Slack__ + + --- + + Se você usa Slack, seja bem-vindo para entrar em contato conosco no canal de treinamento no workspace do Nextflow no Slack. O Slack do Nextflow é um ótimo lugar para conversar com outros desenvolvedores e interagir com a comunidade Nextflow em geral. + + [Acesse o Slack do Nextflow :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Issues no Github__ + + --- + + Se você identificar um erro nos materiais de treinamento, por favor, reporte abrindo uma issue no repositório do Github. Seja um erro de digitação, um problema de formatação ou um bug real que afeta o código, nos avise para que possamos corrigir! Também aceitamos PRs diretamente. + + [Reporte um problema:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Assistente de IA da Seqera__ + + --- + + O Seqera AI é um assistente de IA treinado com recursos do Nextflow e nf-core. Ele pode ajudá-lo a fazer debug do seu código, esclarecer conceitos do Nextflow e buscar documentação mais rapidamente. Pense nele como ter um tutor disponível 24 horas por dia, 7 dias por semana, enquanto você trabalha nos cursos. + + [Pergunte ao Seqera AI:material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Documentação do Nextflow__ + + --- + + A documentação oficial é o guia definitivo para todos os recursos da linguagem e opções de configuração. Use-a junto com este treinamento para se aprofundar em tópicos específicos, explorar recursos avançados e encontrar referências detalhadas de sintaxe. + + [Navegue pela documentação:material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Suporte profissional__ + + --- + + Nextflow é um software gratuito e de código aberto desenvolvido pela [Seqera](https://seqera.io/), uma empresa com sede na Espanha e escritórios satélites no Reino Unido e nos EUA. Oferecemos serviços de suporte profissional para Nextflow, incluindo treinamento personalizado. + + [Entre em contato:material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pt/docs/index.md b/docs/pt/docs/index.md new file mode 100644 index 0000000000..5e2538dc74 --- /dev/null +++ b/docs/pt/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Início +description: Bem-vindo ao portal de treinamento da comunidade Nextflow! +hide: + - toc + - footer +--- + +# Treinamento em Nextflow + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Cursos de autoaprendizado__ + + --- + + **Bem-vindo ao portal de treinamento da comunidade Nextflow!** + + Os cursos de treinamento listados abaixo foram projetados para serem usados como um recurso de autoaprendizado. + Você pode trabalhar neles por conta própria a qualquer momento, seja no ambiente baseado na web que fornecemos via Github Codespaces ou em seu próprio ambiente. + + [Explore os cursos :material-arrow-right:](#catalogo-de-cursos-de-treinamento-em-nextflow){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Informações adicionais__ + + --- + + ??? warning "Compatibilidade de versões" + + <!-- Any update to this content needs to be copied to the local installation page --> + **A partir de janeiro de 2026, todos os nossos cursos de treinamento em Nextflow requerem a versão 25.10.2 ou posterior do Nextflow, com sintaxe estrita ativada, salvo indicação em contrário.** + + Para mais informações sobre requisitos de versão e sintaxe estrita, consulte o [guia de migração da documentação do Nextflow](https://nextflow.io/docs/latest/strict-syntax.html). + + Versões mais antigas do material de treinamento correspondentes à sintaxe anterior estão disponíveis através do seletor de versão na barra de menu desta página web. + + ??? terminal "Opções de ambiente" + + Fornecemos um ambiente de treinamento baseado na web onde tudo o que você precisa para fazer o treinamento está pré-instalado, disponível através do Github Codespaces (requer uma conta gratuita no GitHub). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Se isso não atender às suas necessidades, consulte as outras [Opções de ambiente](./envsetup/index.md). + + ??? learning "Eventos de treinamento" + + Se você prefere fazer o treinamento em Nextflow como parte de um evento estruturado, há muitas oportunidades para fazê-lo. Recomendamos verificar as seguintes opções: + + - **[Semanas de Treinamento]()** organizadas trimestralmente pela equipe da Comunidade + - **[Eventos Seqera](https://seqera.io/events/)** incluem eventos de treinamento presenciais organizados pela Seqera (procure por 'Seqera Sessions' e 'Nextflow Summit') + - **[Embaixadores Nextflow]()** organizam eventos para sua comunidade local + - **[eventos nf-core](https://nf-co.re/events)** incluem hackathons da comunidade + + ??? people "Informações para instrutores" + + Se você é um instrutor realizando seus próprios treinamentos, pode usar nossos materiais diretamente do portal de treinamento, desde que atribua os créditos apropriados. Veja 'Créditos e contribuições' abaixo para detalhes. + + Além disso, adoraríamos ouvir de você sobre como poderíamos apoiar melhor seus esforços de treinamento! Entre em contato conosco em [community@seqera.io](mailto:community@seqera.io) ou no fórum da comunidade (veja a página de [Ajuda](help.md)). + + ??? licensing "Licença de código aberto e política de contribuição" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Este material de treinamento é desenvolvido e mantido pela [Seqera](https://seqera.io) e lançado sob uma licença de código aberto ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) para o benefício da comunidade. Se você deseja usar este material de uma forma que esteja fora do escopo da licença (observe as limitações sobre uso comercial e redistribuição), entre em contato conosco em [community@seqera.io](mailto:community@seqera.io) para discutir sua solicitação. + + Damos as boas-vindas a melhorias, correções e relatórios de bugs da comunidade. Cada página tem um ícone :material-file-edit-outline: no canto superior direito da página que leva ao repositório de código, onde você pode relatar problemas ou propor mudanças no material de treinamento através de um pull request. Veja o `README.md` no repositório para mais detalhes. + +</div> + +!!! note "Tradução assistida por IA" + + Esta tradução foi criada utilizando inteligência artificial e revisada por tradutores humanos. + Agradecemos seu feedback e sugestões de melhorias. + Consulte nosso [guia de tradução](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) para mais informações. + +## Catálogo de cursos de treinamento em Nextflow + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Trilha introdutória__ + + --- + + ### :material-compass:{.nextflow-primary} Nextflow para Iniciantes {.mt-1} + + Cursos independentes de domínio destinados àqueles que são completamente novos no Nextflow. Cada curso consiste em uma série de módulos de treinamento projetados para ajudar os aprendizes a desenvolver suas habilidades progressivamente. + + ??? courses "**Hello Nextflow:** Aprenda a desenvolver seus próprios pipelines" + + Este curso cobre os componentes principais da linguagem Nextflow com detalhes suficientes para permitir o desenvolvimento de pipelines simples, mas totalmente funcionais, além de elementos-chave de práticas de design, desenvolvimento e configuração de pipelines. + + [Comece o treinamento Hello Nextflow :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Aprenda a executar pipelines existentes" + + Uma introdução concisa para executar e configurar pipelines Nextflow, baseada no curso para desenvolvedores Hello Nextflow, mas com menos foco em código. Cobre execução, saídas, estrutura básica de código e configuração para diferentes ambientes computacionais. + + [Comece o treinamento Nextflow Run :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Nextflow para Ciência {.mt-1} + + Aprenda a aplicar os conceitos e componentes apresentados em 'Hello Nextflow' a casos de uso científicos específicos. + + ??? courses "**Nextflow para Genômica** (chamada de variantes)" + + Para pesquisadores que desejam aprender como desenvolver seus próprios pipelines de genômica. O curso usa um caso de uso de chamada de variantes para demonstrar como desenvolver um pipeline de genômica simples, mas funcional. + + [Comece o treinamento Nextflow para Genômica :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow para RNAseq** (RNAseq bulk)" + + Para pesquisadores que desejam aprender como desenvolver seus próprios pipelines de RNAseq. O curso usa um caso de uso de processamento de RNAseq bulk para demonstrar como desenvolver um pipeline de RNAseq simples, mas funcional. + + [Comece o treinamento Nextflow para RNAseq :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Nextflow para Imagens** (ômica espacial)" + + Para pesquisadores em imagens e ômica espacial que desejam aprender como executar e personalizar pipelines de análise. O curso usa o pipeline nf-core/molkart para fornecer um pipeline biologicamente relevante que demonstra como executar, configurar e gerenciar entradas para fluxos de trabalho de pipelines Nextflow. + + [Comece o treinamento Nextflow para Imagens :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __Trilha avançada__ + + --- + + ### :material-bridge:{.nextflow-primary} De Nextflow para nf-core {.mt-1} + + Aprenda a utilizar código e melhores práticas do projeto comunitário [nf-core](https://nf-co.re/). + + Esses cursos ajudam você a ir dos fundamentos do Nextflow às melhores práticas do nf-core. + Entenda como e por que a comunidade nf-core constrói pipelines, e como você pode contribuir e reutilizar essas técnicas. + + ??? courses "**Hello nf-core:** Comece com nf-core" + + Para desenvolvedores que desejam aprender a executar e desenvolver pipelines compatíveis com [nf-core](https://nf-co.re/). O curso cobre a estrutura de pipelines nf-core com detalhes suficientes para permitir o desenvolvimento de pipelines simples, mas totalmente funcionais, que seguem o template nf-core e as melhores práticas de desenvolvimento, além de usar módulos nf-core existentes. + + [Comece o treinamento Hello nf-core :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} Treinamento Avançado em Nextflow {.mt-1} + + Aprenda conceitos e mecanismos avançados para desenvolver e implantar pipelines Nextflow para lidar com casos de uso do mundo real. + + ??? courses "**Side Quests:** Mergulhos profundos em tópicos independentes" + + Mini-cursos independentes destinados a desenvolvedores Nextflow que desejam ampliar seu alcance e/ou aprofundar suas habilidades em tópicos específicos. Eles são apresentados linearmente, mas podem ser realizados em qualquer ordem (veja as dependências na visão geral de cada mini-curso). + + [Navegue pelos Side Quests :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Coleções de Treinamento:** Caminhos de aprendizado recomendados através dos Side Quests" + + As Coleções de Treinamento combinam múltiplos Side Quests para fornecer uma experiência de aprendizado abrangente em torno de um tema ou caso de uso específico. + + [Navegue pelas Coleções de Treinamento :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Procurando materiais de treinamento arquivados?" + + Materiais de treinamento mais antigos (Fundamentals Training, Advanced Training e outros cursos experimentais) foram removidos do portal de treinamento por serem incompatíveis com a sintaxe estrita do Nextflow 3.0. + Se você precisar de acesso a esses materiais, eles estão disponíveis no [histórico do git](https://github.com/nextflow-io/training) antes de janeiro de 2026. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pt/docs/info/conventions.md b/docs/pt/docs/info/conventions.md new file mode 100644 index 0000000000..9bab614645 --- /dev/null +++ b/docs/pt/docs/info/conventions.md @@ -0,0 +1,3 @@ +<!-- Local temporário para notas específicas que devem ser generalizadas --> + +Usamos o prefixo `ch_` para todas as variáveis de canal para indicar claramente que são canais Nextflow. diff --git a/docs/pt/docs/info/hello_pipeline.md b/docs/pt/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..37023ce93d --- /dev/null +++ b/docs/pt/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: O pipeline Hello +description: Recapitulação do que o pipeline Hello faz e como ele é estruturado. +hide: + - toc + - footer +--- + +# O pipeline Hello + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +A maioria dos nossos cursos de treinamento usa um pipeline simples e agnóstico de domínio para demonstrar conceitos e mecanismos do Nextflow. +O curso Hello Nextflow mostra como desenvolver este pipeline passo a passo, explicando cada decisão de design e implementação. +Outros treinamentos usam este pipeline, ou partes dele, como ponto de partida. + +Esta página resume o estado do pipeline como está ao final do curso Hello Nextflow. + +### Descrição resumida + +O fluxo de trabalho Hello recebe um arquivo CSV contendo saudações, escreve-as em arquivos separados, converte cada uma para maiúsculas, coleta-as de volta juntas e gera um único arquivo de texto contendo uma imagem ASCII de um personagem divertido dizendo as saudações. + +### Etapas do fluxo de trabalho (processos) + +As quatro etapas são implementadas como processos Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) armazenados em arquivos de módulo separados. + +1. **`sayHello`:** Escreve cada saudação em seu próprio arquivo de saída (ex: "Hello-output.txt") +2. **`convertToUpper`:** Converte cada saudação para maiúsculas (ex: "HELLO") +3. **`collectGreetings`:** Coleta todas as saudações em maiúsculas em um único arquivo de lote +4. **`cowpy`:** Gera arte ASCII usando a ferramenta `cowpy` + +### Diagrama + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Resultados + +Os resultados são publicados em um diretório chamado `results/`, e a saída final do pipeline (quando executado com parâmetros padrão) é um arquivo de texto contendo arte ASCII de um peru dizendo as saudações em maiúsculas. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Você pode encontrar algumas variações nos detalhes dependendo do curso em que o pipeline é apresentado. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pt/docs/info/nxf_versions.md b/docs/pt/docs/info/nxf_versions.md new file mode 100644 index 0000000000..8fdee89710 --- /dev/null +++ b/docs/pt/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Versões do Nextflow +description: Entendendo e gerenciando a evolução das versões de sintaxe do Nextflow +hide: + - toc + - footer +--- + +## Versão de sintaxe do Nextflow atualmente suportada e requisitos + +A partir da versão 3.0 do portal de treinamento, todos os nossos cursos de treinamento são baseados na versão 25.10.2 do Nextflow, a menos que especificado de outra forma na página de índice do curso (exceto materiais descontinuados ou arquivados que podem não incluir uma nota de versão). + +Como os cursos agora usam entradas tipadas no nível do fluxo de trabalho, bem como diretivas de saída no nível do fluxo de trabalho, eles requerem o uso do analisador de sintaxe V2. +Se você planeja usar o ambiente que fornecemos através do [Github Codespaces](../envsetup/01_setup.md) ou [devcontainers locais](../envsetup/03_devcontainer.md), você não precisa fazer nada, a menos que seja especificamente indicado nas instruções do curso. +No entanto, se você está planejando trabalhar através dos treinamentos em seu próprio ambiente ([Instalação manual](../envsetup/02_local.md)), você precisará garantir o uso do Nextflow versão 25.10.2 ou posterior com o analisador de sintaxe v2 habilitado. + +## Versões mais antigas dos materiais de treinamento + +Nossos materiais de treinamento são versionados desde fevereiro de 2025. + +Você pode acessar versões mais antigas dos materiais de treinamento que funcionam com versões do Nextflow **anteriores a 25.10.2** através do menu suspenso no topo de cada página que mostra a versão numerada dos materiais de treinamento. +Quando você seleciona uma versão mais antiga dos materiais de treinamento, os links para o ambiente de treinamento especificarão automaticamente a versão correspondente do ambiente. + +## Outras informações sobre versões de sintaxe do Nextflow + +O Nextflow tem dois conceitos de versionamento distintos que às vezes são confundidos: **versões DSL** e **versões do analisador de sintaxe**. + +**DSL1 vs DSL2** refere-se a maneiras fundamentalmente diferentes de escrever pipelines Nextflow. +DSL1 era a sintaxe original onde os processos eram implicitamente conectados através de canais. +DSL2, introduzido no Nextflow 20.07, adicionou recursos de modularidade: a capacidade de importar processos e fluxos de trabalho de outros arquivos, blocos `workflow` explícitos e saídas de processos nomeadas. +DSL1 foi descontinuado no Nextflow 22.03 e removido em 22.12. +Todo código Nextflow moderno usa DSL2. + +**Analisador de sintaxe v1 vs v2** refere-se a diferentes analisadores que ambos funcionam com código DSL2. +O analisador v1 é o original, mais permissivo. +O analisador v2 é mais rigoroso e habilita novos recursos de linguagem, como tipagem estática (entradas e saídas tipadas) e diretivas de saída no nível do fluxo de trabalho. +O analisador v2 também fornece melhores mensagens de erro e detecta mais erros no momento da análise, em vez de em tempo de execução. +O analisador v2 se tornará o padrão no Nextflow 26.04. + +Em resumo: DSL2 é a linguagem que você escreve; a versão do analisador de sintaxe determina quão rigorosamente essa linguagem é interpretada e quais recursos avançados estão disponíveis. + +### Verificando e definindo a versão do Nextflow + +Você pode verificar qual versão do Nextflow está instalada em seu sistema usando o comando `nextflow --version`. + +Para mais informações sobre como atualizar sua versão do Nextflow, consulte a documentação de referência sobre [Atualizando o Nextflow](https://www.nextflow.io/docs/latest/updating-nextflow.html). + +### Habilitando o analisador de sintaxe v2 + +Para **habilitar** o analisador de sintaxe v2 para sua sessão atual, execute o seguinte comando em seu terminal: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Para tornar isso permanente (enquanto v2 não se torna o padrão no Nextflow 26.04), adicione o comando export ao perfil do seu shell (`~/.bashrc`, `~/.zshrc`, etc.): + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +Note que a variável de ambiente `NXF_SYNTAX_PARSER=v2` é um requisito temporário. +A partir do Nextflow 26.04, o analisador v2 se tornará o padrão e essa configuração não será mais necessária. + +### Desabilitando o analisador de sintaxe v2 + +Para **desabilitar** o analisador de sintaxe v2 para sua sessão atual, execute o seguinte comando em seu terminal: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Migrando código existente + +Para orientações sobre a migração de código existente para estar em conformidade com versões mais recentes do Nextflow, consulte as [Notas de Migração](https://www.nextflow.io/docs/latest/migrations/index.html) na documentação de referência. + +Estes dois artigos são particularmente úteis para migrar para a versão mais recente: + +- [Migrando para saídas de fluxo de trabalho](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Migrando para tipos estáticos](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Ambos os recursos são abordados como parte do treinamento para iniciantes a partir da versão 3.0 dos materiais de treinamento. + +Dependendo da geração do código Nextflow que você pretende migrar, você pode conseguir fazer a maior parte do trabalho pelo linter do Nextflow usando o comando `nextflow lint -format`. +Consulte a referência CLI para [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) para mais detalhes. + +Esperamos que isso seja útil. +Se você precisar de ajuda, entre em contato no Slack ou no fórum. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/pt/docs/nextflow_run/00_orientation.md b/docs/pt/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..de7aea8d42 --- /dev/null +++ b/docs/pt/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Primeiros passos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Inicie um ambiente de treinamento + +Para usar o ambiente pré-construído que fornecemos no GitHub Codespaces, clique no botão "Open in GitHub Codespaces" abaixo. Para outras opções, veja [Opções de ambiente](../envsetup/index.md). + +Recomendamos abrir o ambiente de treinamento em uma nova aba ou janela do navegador (use clique direito, ctrl-clique ou cmd-clique dependendo do seu equipamento) para que você possa continuar lendo enquanto o ambiente carrega. +Você precisará manter estas instruções abertas em paralelo para trabalhar no curso. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Noções básicas do ambiente + +Este ambiente de treinamento contém todo o software, código e dados necessários para trabalhar no curso de treinamento, então você não precisa instalar nada. + +O codespace é configurado com uma interface VSCode, que inclui um explorador de sistema de arquivos, um editor de código e um terminal shell. +Todas as instruções dadas durante o curso (por exemplo, 'abra o arquivo', 'edite o código' ou 'execute este comando') referem-se a essas três partes da interface VSCode, a menos que especificado de outra forma. + +Se você está fazendo este curso sozinho, por favor familiarize-se com as [noções básicas do ambiente](../envsetup/01_setup.md) para mais detalhes. + +### Requisitos de versão + +Este treinamento é projetado para Nextflow 25.10.2 ou posterior **com o parser de sintaxe v2 HABILITADO**. +Se você está usando um ambiente local ou personalizado, certifique-se de estar usando as configurações corretas conforme documentado [aqui](../info/nxf_versions.md). + +## Prepare-se para trabalhar + +Uma vez que seu codespace esteja rodando, há duas coisas que você precisa fazer antes de mergulhar no treinamento: definir seu diretório de trabalho para este curso específico e dar uma olhada nos materiais fornecidos. + +### Defina o diretório de trabalho + +Por padrão, o codespace abre com o diretório de trabalho definido na raiz de todos os cursos de treinamento, mas para este curso, trabalharemos no diretório `nextflow-run/`. + +Mude de diretório agora executando este comando no terminal: + +```bash +cd nextflow-run/ +``` + +Você pode configurar o VSCode para focar neste diretório, para que apenas os arquivos relevantes apareçam na barra lateral do explorador de arquivos: + +```bash +code . +``` + +!!! tip "Dica" + + Se por qualquer razão você sair deste diretório (por exemplo, seu codespace adormecer), você sempre pode usar o caminho completo para retornar a ele, assumindo que está executando dentro do ambiente de treinamento do GitHub Codespaces: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Agora vamos dar uma olhada no conteúdo. + +### Explore os materiais fornecidos + +Você pode explorar o conteúdo deste diretório usando o explorador de arquivos no lado esquerdo do espaço de trabalho de treinamento. +Alternativamente, você pode usar o comando `tree`. + +Ao longo do curso, usamos a saída do `tree` para representar a estrutura e conteúdo de diretórios de forma legível, às vezes com pequenas modificações para clareza. + +Aqui geramos uma tabela de conteúdo até o segundo nível: + +```bash +tree . -L 2 +``` + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Clique na caixa colorida para expandir a seção e visualizar seu conteúdo. +Usamos seções recolhíveis como esta para exibir a saída esperada de comandos, bem como conteúdo de diretórios e arquivos de forma concisa. + +- **Os arquivos `.nf`** são scripts de fluxo de trabalho numerados com base na parte do curso em que são usados. + +- **O arquivo `nextflow.config`** é um arquivo de configuração que define propriedades mínimas do ambiente. + Você pode ignorá-lo por enquanto. + +- **O arquivo `greetings.csv`** em `data/` contém dados de entrada que usaremos na maior parte do curso. Ele é descrito na Parte 2 (Executar pipelines), quando o introduzimos pela primeira vez. + +- **Os arquivos `test-params.*`** são arquivos de configuração que usaremos na Parte 3 (Configuração). Você pode ignorá-los por enquanto. + +- **O diretório `solutions`** contém o estado final do fluxo de trabalho e seus arquivos acessórios (config e módulos) que resultam da conclusão do curso. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + +## Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu ambiente está funcionando +- [ ] Eu defini meu diretório de trabalho apropriadamente + +Se você pode marcar todas as caixas, está pronto para começar. + +**Para continuar para [Parte 1: Operações Básicas de Execução](./01_basics.md), clique na seta no canto inferior direito desta página.** diff --git a/docs/pt/docs/nextflow_run/01_basics.md b/docs/pt/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..7968c1c70f --- /dev/null +++ b/docs/pt/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Parte 1: Operações básicas de execução + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta primeira parte do curso de treinamento Nextflow Run, começamos suavemente o tópico com um exemplo muito básico Hello World independente de domínio, que usaremos para demonstrar operações essenciais e apontar os componentes de código Nextflow correspondentes. + +??? info "O que é um exemplo Hello World?" + + Um "Hello World!" é um exemplo minimalista que visa demonstrar a sintaxe básica e estrutura de uma linguagem de programação ou framework de software. + O exemplo tipicamente consiste em imprimir a frase "Hello, World!" para o dispositivo de saída, como o console ou terminal, ou escrevê-la em um arquivo. + +--- + +## 1. Execute um Hello World diretamente + +Vamos demonstrar este conceito com um comando simples que executamos diretamente no terminal, para mostrar o que ele faz antes de envolvê-lo no Nextflow. + +!!! tip "Dica" + + Lembre-se de que você agora deve estar dentro do diretório `nextflow-run/` conforme descrito na página [Primeiros Passos](00_orientation.md). + +### 1.1. Faça o terminal dizer olá + +Execute o seguinte comando no seu terminal. + +```bash +echo 'Hello World!' +``` + +??? success "Saída do comando" + + ```console + Hello World! + ``` + +Isso imprime o texto 'Hello World' ali mesmo no terminal. + +### 1.2. Escreva a saída em um arquivo + +Executar pipelines geralmente envolve ler dados de arquivos e escrever resultados em outros arquivos, então vamos modificar o comando para escrever a saída de texto em um arquivo para tornar o exemplo um pouco mais relevante. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Saída do comando" + + ```console + + ``` + +Isso não imprime nada no terminal. + +### 1.3. Encontre a saída + +O texto 'Hello World' agora deve estar no arquivo de saída que especificamos, chamado `output.txt`. +Você pode abri-lo no explorador de arquivos ou pela linha de comando usando o utilitário `cat`, por exemplo. + +??? abstract "Conteúdo do arquivo" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +Isso é o que vamos tentar replicar com nosso primeiro fluxo de trabalho Nextflow. + +### Conclusão + +Agora você sabe como executar um comando simples no terminal que produz algum texto e, opcionalmente, como fazê-lo escrever a saída em um arquivo. + +### O que vem a seguir? + +Descubra o que é necessário para executar um fluxo de trabalho Nextflow que alcança o mesmo resultado. + +--- + +## 2. Execute o fluxo de trabalho + +Fornecemos a você um script de fluxo de trabalho chamado `1-hello.nf` que recebe uma saudação de entrada através de um argumento de linha de comando chamado `--input` e produz um arquivo de texto contendo essa saudação. + +Não vamos olhar o código ainda; primeiro vamos ver como é executá-lo. + +### 2.1. Inicie o fluxo de trabalho e monitore a execução + +No terminal, execute o seguinte comando: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Saída do comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Se sua saída do console se parece com isso, então parabéns, você acabou de executar seu primeiro fluxo de trabalho Nextflow! + +A saída mais importante aqui é a última linha, que está destacada na saída acima: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Isso nos diz que o processo `sayHello` foi executado com sucesso uma vez (`1 of 1 ✔`). + +Ótimo, mas você pode estar se perguntando: onde está a saída? + +### 2.2. Encontre o arquivo de saída no diretório `results` + +Este fluxo de trabalho está configurado para publicar sua saída em um diretório de resultados. +Se você olhar para o seu diretório atual, verá que quando executou o fluxo de trabalho, o Nextflow criou um novo diretório chamado `results`, bem como um subdiretório chamado `1-hello` dentro dele, contendo um arquivo chamado `output.txt`. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Abra o arquivo; o conteúdo deve corresponder à string que você especificou na linha de comando. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +Ótimo, nosso fluxo de trabalho fez o que deveria fazer! + +No entanto, esteja ciente de que o resultado 'publicado' é uma cópia (ou em alguns casos um link simbólico) da saída real produzida pelo Nextflow quando ele executou o fluxo de trabalho. + +Então agora, vamos espiar sob o capô para ver onde o Nextflow realmente executou o trabalho. + +!!! Warning "Aviso" + + Nem todos os fluxos de trabalho serão configurados para publicar saídas em um diretório de resultados, e/ou os nomes de diretórios e estrutura podem ser diferentes. + Um pouco mais adiante nesta seção, mostraremos como descobrir onde esse comportamento é especificado. + +### 2.3. Encontre a saída original e os logs no diretório `work/` + +Quando você executa um fluxo de trabalho, o Nextflow cria um 'diretório de tarefa' distinto para cada invocação individual de cada processo no fluxo de trabalho (=cada etapa no pipeline). +Para cada um, ele prepara as entradas necessárias, executa a(s) instrução(ões) relevante(s) e escreve saídas e arquivos de log dentro desse diretório, que é nomeado automaticamente usando um hash para torná-lo único. + +Todos esses diretórios de tarefa ficarão sob um diretório chamado `work` dentro do seu diretório atual (onde você está executando o comando). + +Isso pode parecer confuso, então vamos ver como isso se parece na prática. + +Voltando à saída do console para o fluxo de trabalho que executamos anteriormente, tínhamos esta linha: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Vê como a linha começa com `[a3/7be2fa]`? +Essa é uma forma truncada do caminho do diretório de tarefa para aquela chamada de processo, e diz onde encontrar a saída do processo `sayHello` dentro do caminho do diretório `work/`. + +Você pode encontrar o caminho completo digitando o seguinte comando (substituindo `a3/7be2fa` pelo que você vê no seu próprio terminal) e pressionando a tecla tab para autocompletar o caminho ou adicionando um asterisco: + +```bash +ls work/a3/7be2fa* +``` + +Isso deve retornar o caminho completo do diretório: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Vamos dar uma olhada no que está lá dentro. + +??? abstract "Conteúdo do diretório" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Não está vendo a mesma coisa?" + + Os nomes exatos dos subdiretórios serão diferentes no seu sistema. + + Se você navegar pelo conteúdo do subdiretório de tarefa no explorador de arquivos do VSCode, verá todos os arquivos imediatamente. + No entanto, os arquivos de log estão configurados para serem invisíveis no terminal, então se você quiser usar `ls` ou `tree` para visualizá-los, precisará definir a opção relevante para exibir arquivos invisíveis. + + ```bash + tree -a work + ``` + +Você deve reconhecer imediatamente o arquivo `output.txt`, que é de fato a saída original do processo `sayHello` que foi publicada no diretório `results`. +Se você abri-lo, encontrará a saudação `Hello World!` novamente. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +E quanto a todos aqueles outros arquivos? + +Esses são os arquivos auxiliares e de log que o Nextflow escreveu como parte da execução da tarefa: + +- **`.command.begin`**: Arquivo sentinela criado assim que a tarefa é iniciada. +- **`.command.err`**: Mensagens de erro (`stderr`) emitidas pela chamada de processo +- **`.command.log`**: Saída de log completa emitida pela chamada de processo +- **`.command.out`**: Saída regular (`stdout`) pela chamada de processo +- **`.command.run`**: Script completo executado pelo Nextflow para executar a chamada de processo +- **`.command.sh`**: O comando que foi realmente executado pela chamada de processo +- **`.exitcode`**: O código de saída resultante do comando + +O arquivo `.command.sh` é especialmente útil porque mostra o comando principal que o Nextflow executou, não incluindo toda a contabilidade e configuração de tarefa/ambiente. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Isso confirma que o fluxo de trabalho compôs o mesmo comando que executamos diretamente na linha de comando anteriormente. + +Quando algo dá errado e você precisa solucionar o que aconteceu, pode ser útil olhar o script `command.sh` para verificar exatamente qual comando o Nextflow compôs com base nas instruções do fluxo de trabalho, interpolação de variáveis e assim por diante. + +### 2.4. Re-execute o fluxo de trabalho com diferentes saudações + +Tente re-executar o fluxo de trabalho algumas vezes com diferentes valores para o argumento `--input`, depois olhe os diretórios de tarefa. + +??? abstract "Conteúdo do diretório" + + ```console + 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 + ``` + +Você vê que um novo subdiretório com um conjunto completo de arquivos de saída e log foi criado para cada execução. + +Em contraste, se você olhar o diretório `results`, ainda há apenas um conjunto de resultados, e o conteúdo do arquivo de saída corresponde ao que você executou por último. + +??? abstract "Conteúdo do diretório" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Isso mostra que os resultados publicados serão sobrescritos por execuções subsequentes, enquanto os diretórios de tarefa em `work/` são preservados. + +### Conclusão + +Você sabe como executar um script Nextflow simples, monitorar sua execução e encontrar suas saídas. + +### O que vem a seguir? + +Aprenda a ler um script Nextflow básico e identificar como seus componentes se relacionam com sua funcionalidade. + +--- + +## 3. Examine o script inicial do fluxo de trabalho Hello World + +O que fizemos ali foi basicamente tratar o script de fluxo de trabalho como uma caixa preta. +Agora que vimos o que ele faz, vamos abrir a caixa e olhar dentro. + +Nosso objetivo aqui não é memorizar a sintaxe do código Nextflow, mas formar alguma intuição básica sobre quais são os principais componentes e como eles estão organizados. + +### 3.1. Examine a estrutura geral do código + +Você encontrará o script `1-hello.nf` no seu diretório atual, que deve ser `nextflow-run`. Abra-o no painel do editor. + +??? full-code "Arquivo de código completo" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parameters + */ + params { + input: String + } + + workflow { + + main: + // emite uma saudação + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Um script de fluxo de trabalho Nextflow tipicamente inclui uma ou mais definições de **processo**, o **fluxo de trabalho** em si, e alguns blocos opcionais como **params** e **output**. + +Cada **processo** descreve qual(is) operação(ões) a etapa correspondente no pipeline deve realizar, enquanto o **fluxo de trabalho** descreve a lógica de fluxo de dados que conecta as várias etapas. + +Vamos dar uma olhada mais de perto no bloco **processo** primeiro, depois olharemos o bloco **workflow**. + +### 3.2. A definição do `process` + +O primeiro bloco de código descreve um **processo**. +A definição do processo começa com a palavra-chave `process`, seguida pelo nome do processo e finalmente o corpo do processo delimitado por chaves. +O corpo do processo deve conter um bloco script que especifica o comando a executar, que pode ser qualquer coisa que você seria capaz de executar em um terminal de linha de comando. + +```groovy title="1-hello.nf" linenums="3" +/* +* Usa echo para imprimir uma saudação em um arquivo +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Aqui temos um **processo** chamado `sayHello` que recebe uma variável de **entrada** chamada `greeting` e escreve sua **saída** em um arquivo chamado `output.txt`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +Esta é uma definição de processo muito mínima que contém apenas uma definição de `input`, uma definição de `output` e o `script` a executar. + +A definição de `input` inclui o qualificador `val`, que diz ao Nextflow para esperar um valor de algum tipo (pode ser uma string, um número, qualquer coisa). + +A definição de `output` inclui o qualificador `path`, que diz ao Nextflow que isso deve ser tratado como um caminho (inclui tanto caminhos de diretório quanto arquivos). + +### 3.3. A definição do `workflow` + +O segundo bloco de código descreve o próprio **fluxo de trabalho**. +A definição do fluxo de trabalho começa com a palavra-chave `workflow`, seguida por um nome opcional, depois o corpo do fluxo de trabalho delimitado por chaves. + +Aqui temos um **fluxo de trabalho** que consiste em um bloco `main:` e um bloco `publish:`. +O bloco `main:` é o corpo principal do fluxo de trabalho e o bloco `publish:` lista as saídas que devem ser publicadas no diretório `results`. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // emite uma saudação + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +Neste caso, o bloco `main:` contém uma chamada ao processo `sayHello` e fornece a ele uma entrada chamada `params.input` para usar como saudação. + +Como discutiremos com mais detalhes em um momento, `params.input` contém o valor que demos ao parâmetro `--input` em nossa linha de comando. + +O bloco `publish:` lista a saída da chamada de processo `sayHello()`, que ele se refere como `sayHello.out` e dá o nome `first_output` (isso pode ser qualquer coisa que o autor do fluxo de trabalho quiser). + +Esta é uma definição de **fluxo de trabalho** muito mínima. +Em um pipeline do mundo real, o fluxo de trabalho tipicamente contém múltiplas chamadas a **processos** conectados por **canais**, e pode haver valores padrão configurados para as entradas variáveis. + +Entraremos nisso na Parte 2 do curso. +Por agora, vamos dar uma olhada mais de perto em como nosso fluxo de trabalho está lidando com entradas e saídas. + +### 3.4. O sistema `params` de parâmetros de linha de comando + +O `params.input` que fornecemos à chamada do processo `sayHello()` é um pedaço elegante de código Nextflow e vale a pena gastar um minuto extra nele. + +Como mencionado acima, é assim que passamos o valor do parâmetro de linha de comando `--input` para a chamada do processo `sayHello()`. +Na verdade, simplesmente declarar `params.someParameterName` é suficiente para dar ao fluxo de trabalho um parâmetro chamado `--someParameterName` da linha de comando. + +Aqui formalizamos essa declaração de parâmetro configurando um bloco `params` que especifica o tipo de entrada que o fluxo de trabalho espera (Nextflow 25.10.2 e posterior). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parameters + */ +params { + input: String +} +``` + +Os tipos suportados incluem `String`, `Integer`, `Float`, `Boolean` e `Path`. + +!!! tip "Dica" + + Parâmetros de fluxo de trabalho declarados usando o sistema `params` sempre levam dois traços na linha de comando (`--`). + Isso os distingue de parâmetros de nível Nextflow, que levam apenas um traço (`-`). + +### 3.5. A diretiva `publish` + +Na outra ponta do fluxo de trabalho, já demos uma olhada no bloco `publish:`. +Essa é uma metade do sistema de tratamento de saída; a outra metade é o bloco `output` localizado abaixo. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Isso especifica que a saída `first_output` listada no bloco `publish:` deve ser copiada para um subdiretório chamado `1-hello` sob o diretório de saída padrão `results`. + +A linha `mode 'copy'` substitui o comportamento padrão do sistema, que é criar um link simbólico (ou symlink) para o arquivo original no diretório `work/` em vez de uma cópia apropriada. + +Há mais opções do que as exibidas aqui para controlar o comportamento de publicação; cobriremos algumas mais tarde. +Você também verá que quando um fluxo de trabalho gera múltiplas saídas, cada uma é listada dessa forma no bloco `output`. + +??? info "Sintaxe mais antiga para publicar saídas usando `publishDir`" + + Até muito recentemente, a forma estabelecida de publicar saídas era fazer isso no nível de cada processo individual usando uma diretiva `publishDir`. + + Você ainda encontrará esse padrão de código por todo lugar em pipelines e módulos de processo Nextflow mais antigos, então é importante estar ciente disso. + + Em vez de ter um bloco `publish:` no fluxo de trabalho e um bloco `output` no nível superior, você veria uma linha `publishDir` na definição do processo `sayHello`: + + ```groovy title="Exemplo de sintaxe" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + No entanto, não recomendamos usar isso em nenhum trabalho novo, pois eventualmente será proibido em versões futuras da linguagem Nextflow. + +### Conclusão + +Agora você sabe como um fluxo de trabalho Nextflow simples é estruturado e como os componentes básicos se relacionam com sua funcionalidade. + +### O que vem a seguir? + +Aprenda a gerenciar suas execuções de fluxo de trabalho convenientemente. + +--- + +## 4. Gerencie execuções de fluxo de trabalho + +Saber como iniciar fluxos de trabalho e recuperar saídas é ótimo, mas você rapidamente descobrirá que há alguns outros aspectos do gerenciamento de fluxo de trabalho que facilitarão sua vida. + +Aqui mostramos como aproveitar o recurso `resume` para quando você precisar re-executar o mesmo fluxo de trabalho, como inspecionar os logs de execução com `nextflow log`, e como excluir diretórios de trabalho mais antigos com `nextflow clean`. + +### 4.1. Re-execute um fluxo de trabalho com `-resume` + +Às vezes, você vai querer re-executar um pipeline que já executou anteriormente sem refazer qualquer trabalho que já foi concluído com sucesso. + +O Nextflow tem uma opção chamada `-resume` que permite fazer isso. +Especificamente, neste modo, quaisquer processos que já foram executados com exatamente o mesmo código, configurações e entradas serão pulados. +Isso significa que o Nextflow executará apenas processos que você adicionou ou modificou desde a última execução, ou aos quais você está fornecendo novas configurações ou entradas. + +Há duas vantagens principais em fazer isso: + +- Se você está no meio do desenvolvimento de um pipeline, pode iterar mais rapidamente, pois só precisa executar o(s) processo(s) em que está trabalhando ativamente para testar suas mudanças. +- Se você está executando um pipeline em produção e algo dá errado, em muitos casos você pode corrigir o problema e relançar o pipeline, e ele retomará a execução do ponto de falha, o que pode economizar muito tempo e computação. + +Para usá-lo, simplesmente adicione `-resume` ao seu comando e execute: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Saída do comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +A saída do console deve parecer familiar, mas há uma coisa um pouco diferente comparado a antes. + +Procure pelo bit `cached:` que foi adicionado na linha de status do processo (linha 5), que significa que o Nextflow reconheceu que já fez este trabalho e simplesmente reutilizou o resultado da execução bem-sucedida anterior. + +Você também pode ver que o hash do subdiretório de trabalho é o mesmo da execução anterior. +O Nextflow está literalmente apontando para a execução anterior e dizendo "Eu já fiz isso ali." + +!!! tip "Dica" + + Quando você re-executa um pipeline com `resume`, o Nextflow não sobrescreve nenhum arquivo publicado fora do diretório de trabalho por quaisquer execuções que foram executadas com sucesso anteriormente. + +### 4.2. Inspecione o log de execuções passadas + +Sempre que você inicia um fluxo de trabalho Nextflow, uma linha é escrita em um arquivo de log chamado `history`, sob um diretório oculto chamado `.nextflow` no diretório de trabalho atual. + +??? abstract "Conteúdo do arquivo" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Este arquivo dá a você o timestamp, nome da execução, status, ID de revisão, ID de sessão e linha de comando completa para cada execução Nextflow que foi iniciada dentro do diretório de trabalho atual. + +Uma forma mais conveniente de acessar esta informação é usar o comando `nextflow log`. + +```bash +nextflow log +``` + +??? success "Saída do comando" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Isso exibirá o conteúdo do arquivo de log no terminal, aumentado com uma linha de cabeçalho. + +Você notará que o ID de sessão muda sempre que você executa um novo comando `nextflow run`, EXCETO se você está usando a opção `-resume`. +Nesse caso, o ID de sessão permanece o mesmo. + +O Nextflow usa o ID de sessão para agrupar informações de cache de execução sob o diretório `cache`, também localizado em `.nextflow`. + +### 4.3. Exclua diretórios de trabalho mais antigos + +Se você executar muitos pipelines, pode acabar acumulando muitos arquivos em muitos subdiretórios. +Como os subdiretórios são nomeados aleatoriamente, é difícil dizer pelos nomes quais são execuções mais antigas vs. mais recentes. + +Felizmente o Nextflow inclui um subcomando `clean` útil que pode excluir automaticamente os subdiretórios de trabalho para execuções passadas que você não se importa mais. + +#### 4.3.1. Determine os critérios de exclusão + +Há múltiplas [opções](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para determinar o que excluir. + +Aqui mostramos um exemplo que exclui todos os subdiretórios de execuções antes de uma determinada execução, especificada usando seu nome de execução. + +Procure a execução bem-sucedida mais recente onde você não usou `-resume`; no nosso caso o nome da execução era `backstabbing_swartz`. + +O nome da execução é a string de duas partes gerada pela máquina mostrada entre colchetes na linha de saída do console `Launching (...)`. +Você também pode usar o log do Nextflow para procurar uma execução com base em seu timestamp e/ou linha de comando. + +#### 4.3.2. Faça uma execução de teste + +Primeiro usamos a flag de execução de teste `-n` para verificar o que será excluído dado o comando: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Saída do comando" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Sua saída terá nomes de diretórios de tarefa diferentes e pode ter um número diferente de linhas, mas deve parecer similar ao exemplo. + +Se você não vir nenhuma linha de saída, você ou não forneceu um nome de execução válido ou não há execuções passadas para excluir. Certifique-se de mudar `backstabbing_swartz` no comando de exemplo para qualquer que seja o nome de execução mais recente correspondente no seu log. + +#### 4.3.3. Prossiga com a exclusão + +Se a saída parecer como esperado e você quiser prosseguir com a exclusão, re-execute o comando com a flag `-f` em vez de `-n`: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Saída do comando" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +A saída deve ser similar a antes, mas agora dizendo 'Removed' em vez de 'Would remove'. +Note que isso não remove os subdiretórios de dois caracteres (como `eb/` acima), mas esvazia seu conteúdo. + +!!! Warning "Aviso" + + Excluir subdiretórios de trabalho de execuções passadas os remove do cache do Nextflow e exclui quaisquer saídas que estavam armazenadas nesses diretórios. + Isso significa que quebra a capacidade do Nextflow de retomar a execução sem re-executar os processos correspondentes. + + Você é responsável por salvar quaisquer saídas que você se importe! Essa é a principal razão pela qual preferimos usar o modo `copy` em vez do modo `symlink` para a diretiva `publish`. + +### Conclusão + +Você sabe como relançar um pipeline sem repetir etapas que já foram executadas de forma idêntica, inspecionar o log de execução e usar o comando `nextflow clean` para limpar diretórios de trabalho antigos. + +### O que vem a seguir? + +Faça uma pequena pausa! Você acabou de absorver os blocos de construção da sintaxe Nextflow e instruções básicas de uso. + +Na próxima seção deste treinamento, vamos olhar quatro versões sucessivamente mais realistas do pipeline Hello World que demonstrarão como o Nextflow permite processar múltiplas entradas eficientemente, executar fluxos de trabalho compostos de múltiplas etapas conectadas, aproveitar componentes de código modulares e utilizar contêineres para maior reprodutibilidade e portabilidade. + +--- + +## Quiz + +<quiz> +Na linha de saída do console `[a3/7be2fa] SAYHELLO | 1 of 1 ✔`, o que `[a3/7be2fa]` representa? +- [ ] O número da versão do processo +- [ ] Um identificador único de execução +- [x] O caminho truncado para o diretório de trabalho da tarefa +- [ ] O checksum do arquivo de saída + +Saiba mais: [2.3. Encontre a saída original e os logs no diretório `work/`](#23-encontre-a-saida-original-e-os-logs-no-diretorio-work) +</quiz> + +<quiz> +Qual é o propósito do arquivo `.command.sh` em um diretório de tarefa? +- [ ] Ele armazena as configurações da tarefa +- [x] Ele mostra o comando real que foi executado pelo processo +- [ ] Ele contém mensagens de erro de tarefas que falharam +- [ ] Ele lista os arquivos de entrada preparados para a tarefa + +Saiba mais: [2.3. Encontre a saída original e os logs no diretório `work/`](#23-encontre-a-saida-original-e-os-logs-no-diretorio-work) +</quiz> + +<quiz> +O que acontece com os resultados publicados quando você re-executa um fluxo de trabalho sem `-resume`? +- [ ] Eles são preservados em diretórios separados com timestamp +- [x] Eles são sobrescritos pela nova execução +- [ ] O Nextflow impede a sobrescrita e falha +- [ ] Eles são automaticamente copiados como backup + +Saiba mais: [2.4. Re-execute o fluxo de trabalho com diferentes saudações](#24-re-execute-o-fluxo-de-trabalho-com-diferentes-saudacoes) +</quiz> + +<quiz> +O que esta saída do console indica? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] A tarefa falhou e foi pulada +- [ ] A tarefa está esperando em uma fila +- [x] O Nextflow reutilizou resultados de uma execução idêntica anterior +- [ ] A tarefa foi cancelada manualmente + +Saiba mais: [4.1. Re-execute um fluxo de trabalho com `-resume`](#41-re-execute-um-fluxo-de-trabalho-com--resume) +</quiz> + +<quiz> +Onde o Nextflow armazena o histórico de execução que o comando `nextflow log` exibe? +- [ ] No diretório results +- [ ] No diretório work +- [x] No arquivo `.nextflow/history` +- [ ] No `nextflow.config` + +Saiba mais: [4.2. Inspecione o log de execuções passadas](#42-inspecione-o-log-de-execucoes-passadas) +</quiz> + +<quiz> +Qual é o propósito do bloco `params` em um arquivo de fluxo de trabalho? +- [ ] Definir requisitos de recursos do processo +- [ ] Configurar o executor +- [x] Declarar e tipar parâmetros de entrada do fluxo de trabalho +- [ ] Especificar opções de publicação de saída + +Saiba mais: [3.4. O sistema params de parâmetros de linha de comando](#34-o-sistema-params-de-parametros-de-linha-de-comando) +</quiz> + +<quiz> +No bloco `output` do fluxo de trabalho, o que `mode 'copy'` faz? +- [ ] Cria um backup do diretório de trabalho +- [x] Faz uma cópia completa dos arquivos em vez de links simbólicos +- [ ] Copia o script do fluxo de trabalho para results +- [ ] Habilita cópia incremental de arquivos + +Saiba mais: [3.5. A diretiva publish](#35-a-diretiva-publish) +</quiz> + +<quiz> +Qual é a flag recomendada para usar com o comando `nextflow clean` antes de realmente excluir arquivos? +- [x] `-n` (dry run) para visualizar o que seria excluído +- [ ] `-v` (verbose) para ver saída detalhada +- [ ] `-a` (all) para selecionar todos os diretórios +- [ ] `-q` (quiet) para suprimir avisos + +Saiba mais: [4.3. Exclua diretórios de trabalho mais antigos](#43-exclua-diretorios-de-trabalho-mais-antigos) +</quiz> diff --git a/docs/pt/docs/nextflow_run/02_pipeline.md b/docs/pt/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..e117556ab6 --- /dev/null +++ b/docs/pt/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1516 @@ +# Parte 2: Executar pipelines reais + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na Parte 1 deste curso (Operações Básicas de Execução), começamos com um fluxo de trabalho de exemplo que tinha apenas recursos mínimos para manter a complexidade do código baixa. +Por exemplo, `1-hello.nf` usou um parâmetro de linha de comando (`--input`) para fornecer um único valor por vez. + +No entanto, a maioria dos pipelines do mundo real usa recursos mais sofisticados para permitir o processamento eficiente de grandes quantidades de dados em escala e aplicar múltiplas etapas de processamento encadeadas por lógica às vezes complexa. + +Nesta parte do treinamento, demonstramos recursos-chave de pipelines do mundo real experimentando versões expandidas do pipeline Hello World original. + +## 1. Processando dados de entrada de um arquivo + +Em um pipeline do mundo real, tipicamente queremos processar múltiplos pontos de dados (ou séries de dados) contidos em um ou mais arquivos de entrada. +E onde possível, queremos executar o processamento de dados independentes em paralelo, para encurtar o tempo gasto esperando pela análise. + +Para demonstrar como o Nextflow faz isso, preparamos um arquivo CSV chamado `greetings.csv` que contém várias saudações de entrada, imitando o tipo de dados colunares que você pode querer processar em uma análise de dados real. +Note que os números não são significativos, eles estão lá apenas para fins ilustrativos. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Também escrevemos uma versão melhorada do fluxo de trabalho original, agora chamada `2a-inputs.nf`, que lerá o arquivo CSV, extrairá as saudações e escreverá cada uma delas em um arquivo separado. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Vamos executar o fluxo de trabalho primeiro, e depois olharemos o código Nextflow relevante. + +### 1.1. Execute o fluxo de trabalho + +Execute o seguinte comando no seu terminal. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Empolgante, isso parece indicar que '3 of 3' chamadas foram feitas para o processo, o que é encorajador, já que havia três linhas de dados no CSV que fornecemos como entrada. +Isso sugere que o processo `sayHello()` foi chamado três vezes, uma vez em cada linha de entrada. + +### 1.2. Encontre as saídas publicadas no diretório `results` + +Vamos olhar o diretório 'results' para ver se nosso fluxo de trabalho ainda está escrevendo uma cópia de nossas saídas lá. + +??? abstract "Conteúdo do diretório" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Sim! Vemos um novo diretório chamado `2a-inputs` com três arquivos de saída com nomes diferentes, convenientemente. + +Você pode abrir cada um deles para se satisfazer de que contêm a string de saudação apropriada. + +??? abstract "Conteúdo dos arquivos" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Isso confirma que cada saudação no arquivo de entrada foi processada apropriadamente. + +### 1.3. Encontre as saídas originais e os logs + +Você pode ter notado que a saída do console acima se referiu a apenas um diretório de tarefa. +Isso significa que todas as três chamadas a `sayHello()` foram executadas dentro daquele único diretório de tarefa? + +#### 1.3.1. Examine o diretório de tarefa dado no terminal + +Vamos dar uma olhada dentro daquele diretório de tarefa `8e/0eb066`. + +??? abstract "Conteúdo do diretório" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Encontramos apenas a saída correspondente a uma das saudações (bem como os arquivos acessórios se habilitarmos a exibição de arquivos ocultos). + +Então o que está acontecendo aqui? + +Por padrão, o sistema de logging ANSI escreve as informações de status para todas as chamadas ao mesmo processo na mesma linha. +Como resultado, ele nos mostrou apenas um dos três caminhos de diretório de tarefa (`8e/0eb066`) na saída do console. +Há outros dois que não estão listados lá. + +#### 1.3.2. Faça o terminal mostrar mais detalhes + +Podemos modificar o comportamento de logging para ver a lista completa de chamadas de processo adicionando o `-ansi-log false` ao comando da seguinte forma: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Saída do comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Desta vez vemos todas as três execuções de processo e seus subdiretórios de trabalho associados listados na saída. +Desabilitar o logging ANSI também impediu o Nextflow de usar cores na saída do terminal. + +Note que a forma como o status é reportado é um pouco diferente entre os dois modos de logging. +No modo condensado, o Nextflow reporta se as chamadas foram completadas com sucesso ou não. +Neste modo expandido, ele apenas reporta que foram submetidas. + +Isso confirma que o processo `sayHello()` é chamado três vezes, e um diretório de tarefa separado é criado para cada um. + +Se olharmos dentro de cada um dos diretórios de tarefa listados lá, podemos verificar que cada um corresponde a uma das saudações. + +??? abstract "Conteúdo do diretório" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Isso confirma que cada chamada de processo é executada em isolamento de todas as outras. +Isso tem muitas vantagens, incluindo evitar colisões se o processo produzir quaisquer arquivos intermediários com nomes não-únicos. + +!!! tip "Dica" + + Para um fluxo de trabalho complexo, ou um grande número de entradas, ter a lista completa exibida no terminal pode ficar um pouco avassalador, então as pessoas normalmente não usam `-ansi-log false` no uso rotineiro. + +### 1.4. Examine o código do fluxo de trabalho + +Então esta versão do fluxo de trabalho é capaz de ler um arquivo CSV de entradas, processar as entradas separadamente e nomear as saídas de forma única. + +Vamos dar uma olhada no que torna isso possível no código do fluxo de trabalho. + +??? full-code "Arquivo de código completo" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + } + + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Novamente, você não precisa memorizar sintaxe de código, mas é bom aprender a reconhecer componentes-chave do fluxo de trabalho que fornecem funcionalidade importante. + +#### 1.4.1. Carregando os dados de entrada do CSV + +Esta é a parte mais interessante: como mudamos de receber um único valor da linha de comando para receber um arquivo CSV, analisá-lo e processar as saudações individuais que ele contém? + +No Nextflow, fazemos isso com um **canal**: uma construção projetada para lidar com entradas eficientemente e transportá-las de uma etapa para outra em fluxos de trabalho de múltiplas etapas, enquanto fornece paralelismo embutido e muitos benefícios adicionais. + +Vamos analisar. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) +``` + +Este código cria um canal chamado `greeting_ch` que lê o arquivo CSV, analisa-o e extrai a primeira coluna de cada linha. +O resultado é um canal contendo `Hello`, `Bonjour` e `Holà`. + +??? tip "Como isso funciona?" + + Aqui está o que essa linha significa em português simples: + + - `channel.fromPath` é uma **fábrica de canal** que cria um canal a partir de caminho(s) de arquivo + - `(params.input)` especifica que o caminho do arquivo é fornecido por `--input` na linha de comando + + Em outras palavras, essa linha diz ao Nextflow: pegue o caminho do arquivo dado com `--input` e prepare-se para tratar seu conteúdo como dados de entrada. + + Então as próximas duas linhas aplicam **operadores** que fazem a análise real do arquivo e o carregamento dos dados na estrutura de dados apropriada: + + - `.splitCsv()` diz ao Nextflow para analisar o arquivo CSV em um array representando linhas e colunas + - `.map { line -> line[0] }` diz ao Nextflow para pegar apenas o elemento na primeira coluna de cada linha + + Então na prática, começando do seguinte arquivo CSV: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Transformamos isso em um array que se parece com isso: + + ```txt title="Conteúdo do array" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + E então pegamos o primeiro elemento de cada uma das três linhas e os carregamos em um canal Nextflow que agora contém: `Hello`, `Bonjour` e `Holà`. + + Se você quiser entender canais e operadores em profundidade, incluindo como escrevê-los você mesmo, veja [Hello Nextflow Parte 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file). + +#### 1.4.2. Chame o processo em cada saudação + +A seguir, na última linha do bloco `main:` do fluxo de trabalho, fornecemos o canal `greeting_ch` carregado como entrada para o processo `sayHello()`. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) +``` + +Isso diz ao Nextflow para executar o processo individualmente em cada elemento no canal, _ou seja_, em cada saudação. +E porque o Nextflow é inteligente assim, ele executará essas chamadas de processo em paralelo se possível, dependendo da infraestrutura computacional disponível. + +É assim que você pode alcançar processamento eficiente e escalável de muitos dados (muitas amostras, ou pontos de dados, seja qual for sua unidade de pesquisa) com comparativamente muito pouco código. + +#### 1.4.3. Como as saídas são nomeadas + +Finalmente, vale a pena dar uma olhada rápida no código do processo para ver como fazemos os arquivos de saída serem nomeados de forma única. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Você vê que, comparado à versão deste processo em `1-hello.nf`, a declaração de saída e a parte relevante do comando mudaram para incluir o valor da saudação no nome do arquivo de saída. + +Esta é uma forma de garantir que os nomes dos arquivos de saída não colidirão quando forem publicados no diretório de resultados comum. + +E essa é a única mudança que tivemos que fazer dentro da declaração do processo! + +### Conclusão + +Você entende em um nível básico como canais e operadores nos permitem processar múltiplas entradas eficientemente. + +### O que vem a seguir? + +Descubra como fluxos de trabalho de múltiplas etapas são construídos e como eles operam. + +--- + +## 2. Executando fluxos de trabalho de múltiplas etapas + +A maioria dos fluxos de trabalho do mundo real envolve mais de uma etapa. +Vamos construir sobre o que acabamos de aprender sobre canais, e olhar como o Nextflow usa canais e operadores para conectar processos em um fluxo de trabalho de múltiplas etapas. + +Para isso, fornecemos a você um fluxo de trabalho de exemplo que encadeia três etapas separadas e demonstra o seguinte: + +1. Fazer dados fluírem de um processo para o próximo +2. Coletar saídas de múltiplas chamadas de processo em uma única chamada de processo + +Especificamente, fizemos uma versão expandida do fluxo de trabalho chamada `2b-multistep.nf` que pega cada saudação de entrada, converte-a para maiúsculas, depois coleta todas as saudações em maiúsculas em um único arquivo de saída. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Como anteriormente, executaremos o fluxo de trabalho primeiro e depois olharemos o código para ver o que é novo. + +### 2.1. Execute o fluxo de trabalho + +Execute o seguinte comando no seu terminal: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Saída do comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Você vê que como prometido, múltiplas etapas foram executadas como parte do fluxo de trabalho; as duas primeiras (`sayHello` e `convertToUpper`) foram presumivelmente executadas em cada saudação individual, e a terceira (`collectGreetings`) terá sido executada apenas uma vez, nas saídas de todas as três chamadas `convertToUpper`. + +### 2.2. Encontre as saídas + +Vamos verificar que isso é de fato o que aconteceu olhando no diretório `results`. + +??? abstract "Conteúdo do diretório" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Como você pode ver, temos um novo diretório chamado `2b-multistep`, e ele contém bem mais arquivos do que antes. +Alguns dos arquivos foram agrupados em um subdiretório chamado `intermediates`, enquanto dois arquivos estão localizados no nível superior. + +Esses dois são os resultados finais do fluxo de trabalho de múltiplas etapas. +Tire um minuto para olhar os nomes dos arquivos e verificar seu conteúdo para confirmar que são o que você espera. + +??? abstract "Conteúdo dos arquivos" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +O primeiro contém nossas três saudações, em maiúsculas e coletadas de volta em um único arquivo como prometido. +O segundo é um arquivo de relatório que resume algumas informações sobre a execução. + +### 2.3. Examine o código + +Vamos olhar o código e identificar os padrões-chave para fluxos de trabalho de múltiplas etapas. + +??? full-code "Arquivo de código completo" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Usa uma ferramenta de substituição de texto para converter a saudação para maiúsculas + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Coleta saudações em maiúsculas em um único arquivo de saída + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Há muita coisa acontecendo ali, mas a diferença mais óbvia comparada à versão anterior do fluxo de trabalho é que agora há múltiplas definições de processo, e correspondentemente, várias chamadas de processo no bloco workflow. + +Vamos dar uma olhada mais de perto e ver se conseguimos identificar as peças mais interessantes. + +#### 2.3.1. Visualizando a estrutura do fluxo de trabalho + +Se você está usando VSCode com a extensão Nextflow, você pode obter um diagrama útil de como os processos estão conectados clicando no pequeno link `DAG preview` exibido logo acima do bloco workflow em qualquer script Nextflow. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Isso dá a você uma boa visão geral de como os processos estão conectados e o que eles produzem. + +Você vê que além do processo `sayHello` original, agora também temos `convertToUpper` e `collectGreetings`, que correspondem aos nomes dos processos que vimos na saída do console. +As duas novas definições de processo são estruturadas da mesma forma que o processo `sayHello`, exceto que `collectGreetings` recebe um parâmetro de entrada adicional chamado `batch` e produz duas saídas. + +Não entraremos no código de cada um em detalhes, mas se você está curioso, pode consultar os detalhes em [Parte 2 do Hello Nextflow](../hello_nextflow/03_hello_workflow.md). + +Por agora, vamos investigar como os processos estão conectados uns aos outros. + +#### 2.3.2. Como os processos estão conectados + +A coisa realmente interessante a observar aqui é como as chamadas de processo estão encadeadas no bloco `main:` do fluxo de trabalho. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Você pode ver que a primeira chamada de processo, `sayHello(greeting_ch)`, está inalterada. +Então a próxima chamada de processo, para `convertToUpper`, se refere à saída de `sayHello` como `sayHello.out`. + +O padrão é simples: `processName.out` se refere ao canal de saída de um processo, que pode ser passado diretamente para o próximo processo. +É assim que transportamos dados de uma etapa para a próxima no Nextflow. + +#### 2.3.3. Um processo pode receber múltiplas entradas + +A terceira chamada de processo, para `collectGreetings`, é um pouco diferente. + +```groovy title="2b-multistep.nf" linenums="77" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Você vê que esta chamada recebe duas entradas, `convertToUpper.out.collect()` e `params.batch`. +Ignorando o bit `.collect()` por enquanto, podemos generalizar isso como `collectGreetings(input1, input2)`. + +Isso corresponde às duas declarações de entrada no módulo do processo: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Quando o Nextflow analisa isso, ele atribuirá a primeira entrada na chamada a `path input_files`, e a segunda a `val batch_name`. + +Então agora você sabe que um processo pode receber múltiplas entradas, e como a chamada se parece no bloco workflow. + +Agora vamos dar uma olhada mais de perto naquela primeira entrada, `convertToUpper.out.collect()`. + +#### 2.3.4. O que `collect()` faz na chamada `collectGreetings` + +Para passar a saída de `sayHello` para `convertToUpper`, simplesmente nos referimos ao canal de saída de `sayHello` como `sayHello.out`. Mas para a próxima etapa, estamos vendo uma referência a `convertToUpper.out.collect()`. + +O que é esse bit `collect()` e o que ele faz? + +É um operador, é claro. Assim como os operadores `splitCsv` e `map` que encontramos anteriormente. +Desta vez o operador é chamado `collect`, e é aplicado ao canal de saída produzido por `convertToUpper`. + +O operador `collect` é usado para coletar as saídas de múltiplas chamadas ao mesmo processo e empacotá-las em um único elemento de canal. + +No contexto deste fluxo de trabalho, ele está pegando as três saudações em maiúsculas no canal `convertToUpper.out` --que são três itens de canal separados, e normalmente seriam tratados em chamadas separadas pelo próximo processo-- e empacotando-os em um único item. + +Em termos mais práticos: se não aplicássemos `collect()` à saída de `convertToUpper()` antes de alimentá-la para `collectGreetings()`, o Nextflow simplesmente executaria `collectGreetings()` independentemente em cada saudação, o que não alcançaria nosso objetivo. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +Em contraste, usar `collect()` nos permite pegar todas as saudações em maiúsculas separadas produzidas pela segunda etapa do fluxo de trabalho e alimentá-las todas juntas para uma única chamada na terceira etapa do pipeline. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +É assim que colocamos todas as saudações de volta no mesmo arquivo. + +Há muitos outros [operadores](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) disponíveis para aplicar transformações ao conteúdo de canais entre chamadas de processo. + +Isso dá aos desenvolvedores de pipeline muita flexibilidade para personalizar a lógica de fluxo de seu pipeline. +A desvantagem é que às vezes pode tornar mais difícil decifrar o que o pipeline está fazendo. + +#### 2.3.5. Um parâmetro de entrada pode ter um valor padrão + +Você pode ter notado que `collectGreetings` recebe uma segunda entrada, `params.batch`: + +```groovy title="2b-multistep.nf" linenums="77" + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Isso passa um parâmetro CLI chamado `--batch` para o fluxo de trabalho. +No entanto, quando executamos o fluxo de trabalho anteriormente, não especificamos um parâmetro `--batch`. + +O que está acontecendo aí? +Dê uma olhada no bloco `params`: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Há um valor padrão configurado no fluxo de trabalho, então não precisamos fornecê-lo. +Mas se fornecermos um na linha de comando, o valor que especificarmos será usado em vez do padrão. + +Tente: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Saída do comando" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Você deve ver novas saídas finais nomeadas com seu nome de lote personalizado. + +??? abstract "Conteúdo do diretório" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Este é um aspecto da configuração de entrada, que cobriremos com mais detalhes na Parte 3, mas por enquanto o importante é saber que parâmetros de entrada podem receber valores padrão. + +#### 2.3.6. Um processo pode produzir múltiplas saídas + +Na definição do processo `collectGreetings`, vemos as seguintes declarações de saída: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Que são então referenciadas pelo nome dado com `emit:` no bloco `publish:`: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Isso torna fácil então passar saídas específicas individualmente para outros processos no fluxo de trabalho, em combinação com vários operadores. + +#### 2.3.7. Saídas publicadas podem ser organizadas + +No bloco `output`, usamos caminhos personalizados para agrupar resultados intermediários para tornar mais fácil destacar apenas as saídas finais do fluxo de trabalho. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Há formas mais sofisticadas de organizar saídas publicadas; abordaremos algumas na parte sobre configuração. + +!!! tip "Quer aprender mais sobre construir fluxos de trabalho?" + + Para cobertura detalhada de construir fluxos de trabalho de múltiplas etapas, veja [Hello Nextflow Parte 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +### Conclusão + +Você entende em um nível básico como fluxos de trabalho de múltiplas etapas são construídos usando canais e operadores e como eles operam. +Você também viu que processos podem receber múltiplas entradas e produzir múltiplas saídas, e que estas podem ser publicadas de forma estruturada. + +### O que vem a seguir? + +Aprenda como pipelines Nextflow podem ser modularizados para promover reutilização de código e manutenibilidade. + +--- + +## 3. Executando pipelines modularizados + +Até agora, todos os fluxos de trabalho que olhamos consistiram em um único arquivo de fluxo de trabalho contendo todo o código relevante. + +No entanto, pipelines do mundo real tipicamente se beneficiam de serem _modularizados_, significando que o código é dividido em diferentes arquivos. +Isso pode tornar seu desenvolvimento e manutenção mais eficientes e sustentáveis. + +Aqui vamos demonstrar a forma mais comum de modularidade de código no Nextflow, que é o uso de **módulos**. + +No Nextflow, um **módulo** é uma única definição de processo que é encapsulada sozinha em um arquivo de código autônomo. +Para usar um módulo em um fluxo de trabalho, você apenas adiciona uma declaração de importação de uma linha ao seu arquivo de código de fluxo de trabalho; então você pode integrar o processo no fluxo de trabalho da mesma forma que normalmente faria. +Isso torna possível reutilizar definições de processo em múltiplos fluxos de trabalho sem produzir múltiplas cópias do código. + +Até agora estávamos executando fluxos de trabalho que tinham todos os seus processos incluídos em um arquivo de código monolítico. +Agora vamos ver como fica quando os processos são armazenados em módulos individuais. + +Preparamos novamente um fluxo de trabalho adequado para fins de demonstração, chamado `2c-modules.nf`, junto com um conjunto de módulos localizados no diretório `modules/`. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Conteúdo do diretório" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Você vê que há quatro arquivos Nextflow, cada um nomeado após um dos processos. +Você pode ignorar o arquivo `cowpy.nf` por enquanto; chegaremos a ele mais tarde. + +### 3.1. Examine o código + +Desta vez vamos olhar o código primeiro. +Comece abrindo o arquivo de fluxo de trabalho `2c-modules.nf`. + +??? full-code "Arquivo de código completo" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Você vê que a lógica do fluxo de trabalho é exatamente a mesma da versão anterior do fluxo de trabalho. +No entanto, o código do processo foi removido do arquivo de fluxo de trabalho, e em vez disso há declarações `include` apontando para arquivos separados em `modules`. + +```groovy title="hello-modules.nf" linenums="3" +// Inclui módulos +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Abra um desses arquivos e você encontrará o código para o processo correspondente. + +??? full-code "Arquivo de código completo" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * Usa echo para imprimir 'Hello World!' em um arquivo + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Como você pode ver, o código do processo não mudou; ele foi apenas copiado para um arquivo de módulo individual em vez de estar no arquivo de fluxo de trabalho principal. +O mesmo se aplica aos outros dois processos. + +Então vamos ver como fica executar esta nova versão. + +### 3.2. Execute o fluxo de trabalho + +Execute este comando no seu terminal, com a flag `-resume`: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Você notará que as execuções de processo foram todas cacheadas com sucesso, significando que o Nextflow reconheceu que já fez o trabalho solicitado, mesmo que o código tenha sido dividido e o arquivo de fluxo de trabalho principal tenha sido renomeado. + +Nada disso importa para o Nextflow; o que importa é o script de job que é gerado uma vez que todo o código foi reunido e avaliado. + +!!! tip "Dica" + + Também é possível encapsular uma seção de um fluxo de trabalho como um 'subworkflow' que pode ser importado em um pipeline maior, mas isso está fora do escopo deste curso. + + Você pode aprender mais sobre desenvolver fluxos de trabalho composíveis na Side Quest sobre [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/). + +### Conclusão + +Você sabe como processos podem ser armazenados em módulos autônomos para promover reutilização de código e melhorar a manutenibilidade. + +### O que vem a seguir? + +Aprenda a usar contêineres para gerenciar dependências de software. + +--- + +## 4. Usando software em contêiner + +Até agora os fluxos de trabalho que estamos usando como exemplos só precisavam executar operações de processamento de texto muito básicas usando ferramentas UNIX disponíveis em nosso ambiente. + +No entanto, pipelines do mundo real tipicamente requerem ferramentas e pacotes especializados que não estão incluídos por padrão na maioria dos ambientes. +Normalmente, você precisaria instalar essas ferramentas, gerenciar suas dependências e resolver quaisquer conflitos. + +Tudo isso é muito tedioso e irritante. +Uma forma muito melhor de abordar este problema é usar **contêineres**. + +Um **contêiner** é uma unidade leve, autônoma e executável de software criada a partir de uma **imagem** de contêiner que inclui tudo necessário para executar uma aplicação incluindo código, bibliotecas de sistema e configurações. + +!!! Tip "Dica" + + Ensinamos isso usando a tecnologia [Docker](https://www.docker.com/get-started/), mas o Nextflow suporta [várias outras tecnologias de contêiner](https://www.nextflow.io/docs/latest/container.html#) também. + +### 4.1. Use um contêiner diretamente + +Primeiro, vamos tentar interagir com um contêiner diretamente. +Isso ajudará a solidificar seu entendimento do que são contêineres antes de começarmos a usá-los no Nextflow. + +#### 4.1.1. Baixe a imagem do contêiner + +Para usar um contêiner, você normalmente baixa ou "puxa" uma imagem de contêiner de um registro de contêiner, e então executa a imagem de contêiner para criar uma instância de contêiner. + +A sintaxe geral é a seguinte: + +```bash title="Sintaxe" +docker pull '<container>' +``` + +- `docker pull` é a instrução para o sistema de contêiner para puxar uma imagem de contêiner de um repositório. +- `'<container>'` é o endereço URI da imagem de contêiner. + +Como exemplo, vamos puxar uma imagem de contêiner que contém [cowpy](https://github.com/jeffbuttars/cowpy), uma implementação em python de uma ferramenta chamada `cowsay` que gera arte ASCII para exibir entradas de texto arbitrárias de forma divertida. + +Há vários repositórios onde você pode encontrar contêineres publicados. +Usamos o serviço [Seqera Containers](https://seqera.io/containers/) para gerar esta imagem de contêiner Docker a partir do pacote Conda `cowpy`: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Execute o comando de pull completo: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Saída do comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Isso diz ao sistema para baixar a imagem especificada. +Uma vez que o download esteja completo, você tem uma cópia local da imagem de contêiner. + +#### 4.1.2. Inicie o contêiner + +Contêineres podem ser executados como um comando único, mas você também pode usá-los interativamente, o que dá a você um prompt de shell dentro do contêiner e permite que você brinque com o comando. + +A sintaxe geral é a seguinte: + +```bash title="Sintaxe" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'` é a instrução para o sistema de contêiner para iniciar uma instância de contêiner a partir de uma imagem de contêiner e executar um comando nela. +- `--rm` diz ao sistema para desligar a instância de contêiner após o comando ter sido concluído. + +Completamente montado, o comando de execução do contêiner se parece com isto: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Execute esse comando, e você deve ver seu prompt mudar para algo como `(base) root@b645838b3314:/tmp#`, que indica que você agora está dentro do contêiner. + +Você pode verificar isso executando `ls` para listar o conteúdo do diretório: + +```bash +ls / +``` + +??? success "Saída do comando" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Você vê que o sistema de arquivos dentro do contêiner é diferente do sistema de arquivos no seu sistema host. + +!!! Tip "Dica" + + Quando você executa um contêiner, ele é isolado do sistema host por padrão. + Isso significa que o contêiner não pode acessar nenhum arquivo no sistema host a menos que você explicitamente permita fazê-lo especificando que quer montar um volume como parte do comando `docker run` usando a seguinte sintaxe: + + ```bash title="Sintaxe" + -v <outside_path>:<inside_path> + ``` + + Isso efetivamente estabelece um túnel através da parede do contêiner que você pode usar para acessar essa parte do seu sistema de arquivos. + + Isso é coberto em mais detalhes na [Parte 5 do Hello Nextflow](../hello_nextflow/05_hello_containers.md). + +#### 4.1.3. Execute a ferramenta `cowpy` + +De dentro do contêiner, você pode executar o comando `cowpy` diretamente. + +```bash +cowpy "Hello Containers" +``` + +??? success "Saída do comando" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Isso produz arte ASCII do personagem vaca padrão (ou 'cowacter') com um balão de fala contendo o texto que especificamos. + +Agora que você testou o uso básico, pode tentar dar alguns parâmetros. +Por exemplo, a documentação da ferramenta diz que podemos definir o personagem com `-c`. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Saída do comando" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Desta vez a saída de arte ASCII mostra o pinguim do Linux, Tux, porque especificamos o parâmetro `-c tux`. + +Como você está dentro do contêiner, pode executar o comando cowpy quantas vezes quiser, variando os parâmetros de entrada, sem se preocupar em instalar nenhuma biblioteca no seu próprio sistema. + +??? tip "Outros personagens disponíveis" + + Use a flag '-c' para escolher um personagem diferente, incluindo: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Sinta-se livre para brincar com isso. +Quando terminar, saia do contêiner usando o comando `exit`: + +```bash +exit +``` + +Você se encontrará de volta no seu shell normal. + +### 4.2. Use um contêiner em um fluxo de trabalho + +Quando executamos um pipeline, queremos ser capazes de dizer ao Nextflow qual contêiner usar em cada etapa, e importante, queremos que ele lide com todo aquele trabalho que acabamos de fazer: puxar o contêiner, iniciá-lo, executar o comando e derrubar o contêiner quando terminar. + +Boa notícia: é exatamente isso que o Nextflow vai fazer por nós. +Nós só precisamos especificar um contêiner para cada processo. + +Para demonstrar como isso funciona, fizemos outra versão do nosso fluxo de trabalho que executa `cowpy` no arquivo de saudações coletadas produzido na terceira etapa. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Isso deve produzir um arquivo contendo a arte ASCII com as três saudações no balão de fala. + +#### 4.2.1. Examine o código + +O fluxo de trabalho é muito similar ao anterior, mais a etapa extra para executar `cowpy`. + +??? full-code "Arquivo de código completo" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Inclui módulos + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // emite uma saudação + sayHello(greeting_ch) + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + // coleta todas as saudações em um arquivo + collectGreetings(convertToUpper.out.collect(), params.batch) + // gera arte ASCII das saudações com cowpy + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Você vê que este fluxo de trabalho importa um processo `cowpy` de um arquivo de módulo, e o chama na saída da chamada `collectGreetings()`, mais um parâmetro de entrada chamado `params.character`. + +```groovy title="2d-container.nf" linenums="25" +// gera arte ASCII com cowpy +cowpy(collectGreetings.out, params.character) +``` + +O processo `cowpy`, que envolve o comando cowpy para gerar arte ASCII, é definido no módulo `cowpy.nf`. + +??? full-code "Arquivo de código completo" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Gera arte ASCII com cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +O processo `cowpy` requer duas entradas: o caminho para um arquivo de entrada contendo o texto para colocar no balão de fala (`input_file`), e um valor para a variável de personagem. + +Importante, ele também inclui a linha `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`, que aponta para o URI do contêiner que usamos anteriormente. + +#### 4.2.2. Verifique se o Docker está habilitado na configuração + +Vamos antecipar ligeiramente a Parte 3 deste curso de treinamento introduzindo o arquivo de configuração `nextflow.config`, que é uma das principais formas que o Nextflow oferece para configurar a execução de fluxo de trabalho. +Quando um arquivo chamado `nextflow.config` está presente no diretório atual, o Nextflow o carregará automaticamente e aplicará qualquer configuração que ele contenha. + +Para isso, incluímos um arquivo `nextflow.config` com uma única linha de código que habilita o Docker. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Esta configuração diz ao Nextflow para usar Docker para qualquer processo que especifique um contêiner compatível. + +!!! tip "Dica" + + É tecnicamente possível habilitar a execução Docker da linha de comando, por execução, usando o parâmetro `-with-docker <container>` no seu comando. + No entanto, isso só nos permite especificar um contêiner para todo o fluxo de trabalho, enquanto a abordagem que acabamos de mostrar permite especificar um contêiner diferente por processo. + Este último é muito melhor para modularidade, manutenção de código e reprodutibilidade. + +#### 4.2.3. Execute o fluxo de trabalho + +Só para recapitular, isto é o que estamos prestes a executar: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Você acha que vai funcionar? + +Vamos executar o fluxo de trabalho com a flag `-resume`, e especificar que queremos que o personagem seja o peru. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +As três primeiras etapas foram cacheadas já que as executamos antes, mas o processo `cowpy` é novo então esse realmente é executado. + +Você pode encontrar a saída da etapa `cowpy` no diretório `results`. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Você vê que o personagem está dizendo todas as saudações, já que ele executou no arquivo de saudações em maiúsculas coletadas. + +Mais ao ponto, conseguimos executar isso como parte do nosso pipeline sem ter que fazer uma instalação apropriada do cowpy e todas as suas dependências. +E agora podemos compartilhar o pipeline com colaboradores e fazer com que eles o executem em sua infraestrutura sem que precisem instalar nada também, além do Docker ou uma de suas alternativas (como Singularity/Apptainer) conforme mencionado acima. + +#### 4.2.4. Inspecione como o Nextflow lançou a tarefa em contêiner + +Como uma coda final para esta seção, vamos dar uma olhada no subdiretório de trabalho para uma das chamadas de processo `cowpy` para ter um pouco mais de visão sobre como o Nextflow funciona com contêineres por baixo dos panos. + +Verifique a saída do seu comando `nextflow run` para encontrar o caminho para o subdiretório de trabalho do processo `cowpy`. +Olhando o que obtivemos para a execução mostrada acima, a linha de log do console para o processo `cowpy` começa com `[7f/caf718]`. +Isso corresponde ao seguinte caminho de diretório truncado: `work/7f/caf718`. + +Naquele diretório, você encontrará o arquivo `.command.run` que contém todos os comandos que o Nextflow executou em seu nome durante a execução do pipeline. + +??? abstract "Conteúdo do arquivo" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + ... + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf71890cce1667c094d880f4b6dcc/.command.sh + } + + ... + ``` + +Se você procurar por `nxf_launch` neste arquivo, você deve ver algo assim: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/nextflow-run/work:/workspaces/training/nextflow-run/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/pip_cowpy:131d6a1b707a8e65 /bin/bash -ue /workspaces/training/nextflow-run/work/7f/caf7189fca6c56ba627b75749edcb3/.command.sh +} +``` + +Este comando de lançamento mostra que o Nextflow está usando um comando `docker run` muito similar para lançar a chamada de processo como fizemos quando o executamos manualmente. +Ele também monta o subdiretório de trabalho correspondente no contêiner, define o diretório de trabalho dentro do contêiner de acordo, e executa nosso script bash modelado no arquivo `.command.sh`. + +Isso confirma que todo o trabalho duro que tivemos que fazer manualmente na seção anterior agora é feito para nós pelo Nextflow! + +### Conclusão + +Você entende qual papel os contêineres desempenham no gerenciamento de versões de ferramentas de software e garantindo reprodutibilidade. + +Mais geralmente, você tem uma compreensão básica de quais são os componentes principais de pipelines Nextflow do mundo real e como eles estão organizados. +Você conhece os fundamentos de como o Nextflow pode processar múltiplas entradas eficientemente, executar fluxos de trabalho compostos de múltiplas etapas conectadas, aproveitar componentes de código modulares e utilizar contêineres para maior reprodutibilidade e portabilidade. + +### O que vem a seguir? + +Faça outra pausa! Essa foi uma grande pilha de informações sobre como pipelines Nextflow funcionam. + +Na última seção deste treinamento, vamos mergulhar mais profundamente no tópico de configuração. +Você aprenderá como configurar a execução do seu pipeline para se adequar à sua infraestrutura, bem como gerenciar a configuração de entradas e parâmetros. + +--- + +## Quiz + +<quiz> +Por que o Nextflow cria um diretório de tarefa separado para cada chamada de processo? +- [ ] Para melhorar a velocidade de execução +- [ ] Para reduzir o uso de memória +- [x] Para isolar execuções e evitar colisões entre saídas +- [ ] Para habilitar compressão paralela de arquivos + +Saiba mais: [1.3. Encontre as saídas originais e os logs](#13-encontre-as-saidas-originais-e-os-logs) +</quiz> + +<quiz> +O que a opção `-ansi-log false` faz ao executar um fluxo de trabalho? +- [ ] Desabilita toda saída do console +- [x] Remove cores da saída +- [x] Mostra todos os caminhos de diretório de tarefa em vez de condensá-los em uma linha +- [ ] Habilita modo de depuração verboso + +Saiba mais: [1.3.2. Faça o terminal mostrar mais detalhes](#132-faca-o-terminal-mostrar-mais-detalhes) + +Você também pode usar qualquer uma das seguintes variáveis de ambiente se preferir este estilo: + +```bash +export NXF_ANSI_LOG=0 +# ou +export NO_COLOR=1 +``` + +</quiz> + +<quiz> +No código `#!groovy channel.fromPath(params.input).splitCsv().map { line -> line[0] }`, o que `#!groovy .map { line -> line[0] }` faz? +- [ ] Filtra linhas vazias +- [ ] Ordena as linhas alfabeticamente +- [x] Extrai a primeira coluna de cada linha CSV +- [ ] Conta o número de linhas + +Saiba mais: [1.4.1. Carregando os dados de entrada do CSV](#141-carregando-os-dados-de-entrada-do-csv) +</quiz> + +<quiz> +Por que é importante incluir o valor de entrada nos nomes de arquivos de saída (ex., `#!groovy "${greeting}-output.txt"`)? +- [ ] Para melhorar a velocidade de processamento +- [ ] Para habilitar funcionalidade de resume +- [x] Para evitar que arquivos de saída sobrescrevam uns aos outros ao processar múltiplas entradas +- [ ] Para tornar arquivos mais fáceis de comprimir + +Saiba mais: [1.4.3. Como as saídas são nomeadas](#143-como-as-saidas-sao-nomeadas) +</quiz> + +<quiz> +Qual é o propósito da declaração `include` em um fluxo de trabalho modularizado? +- [ ] Copiar código de processo para o arquivo de fluxo de trabalho +- [x] Importar uma definição de processo de um arquivo de módulo externo +- [ ] Incluir configurações de configuração +- [ ] Adicionar comentários de documentação + +Saiba mais: [3. Executando pipelines modularizados](#3-executando-pipelines-modularizados) +</quiz> + +<quiz> +Quando você modulariza um fluxo de trabalho e o executa com `-resume`, o que acontece? +- [ ] Caching é desabilitado para processos modulares +- [ ] Todas as tarefas devem ser re-executadas +- [x] Caching funciona normalmente baseado nos scripts de job gerados +- [ ] Apenas o arquivo de fluxo de trabalho principal é cacheado + +Saiba mais: [3.2. Execute o fluxo de trabalho](#32-execute-o-fluxo-de-trabalho) +</quiz> + +<quiz> +O que a diretiva `container` em uma definição de processo especifica? +- [ ] O diretório de trabalho para o processo +- [ ] A alocação máxima de memória +- [x] O URI da imagem de contêiner para usar na execução do processo +- [ ] O formato do arquivo de saída + +Saiba mais: [4.2. Use um contêiner em um fluxo de trabalho](#42-use-um-conteiner-em-um-fluxo-de-trabalho) +</quiz> + +<quiz> +No arquivo `.command.run`, o que a função `nxf_launch` contém? +- [ ] A informação de versão do Nextflow +- [ ] Os parâmetros do fluxo de trabalho +- [x] O comando `docker run` com montagens de volume e configurações de contêiner +- [ ] As declarações de entrada do processo + +Saiba mais: [4.2.4. Inspecione como o Nextflow lançou a tarefa em contêiner](#424-inspecione-como-o-nextflow-lancou-a-tarefa-em-conteiner) +</quiz> + +<quiz> +O que o Nextflow automaticamente lida ao executar um processo em contêiner? (Selecione todos que se aplicam) +- [x] Puxar a imagem do contêiner se necessário +- [x] Montar o diretório de trabalho no contêiner +- [x] Executar o script do processo dentro do contêiner +- [x] Limpar a instância do contêiner após a execução + +Saiba mais: [4. Usando software em contêiner](#4-usando-software-em-conteiner) +</quiz> diff --git a/docs/pt/docs/nextflow_run/03_config.md b/docs/pt/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..f1f37e656a --- /dev/null +++ b/docs/pt/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Parte 3: Configuração de execução + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta seção explorará como gerenciar a configuração de um pipeline Nextflow para personalizar seu comportamento, adaptá-lo a diferentes ambientes e otimizar o uso de recursos _sem alterar uma única linha do código do fluxo de trabalho em si_. + +Há múltiplas formas de fazer isso, que podem ser usadas em combinação e são interpretadas de acordo com a ordem de precedência descrita [aqui](https://www.nextflow.io/docs/latest/config.html). + +Nesta parte do curso, vamos mostrar o mecanismo de arquivo de configuração mais simples e mais comum, o arquivo `nextflow.config`, que você já encontrou na seção sobre contêineres na Parte 2. + +Vamos revisar componentes essenciais da configuração Nextflow como diretivas de processo, executores, perfis e arquivos de parâmetros. +Ao aprender a utilizar essas opções de configuração efetivamente, você pode aproveitar ao máximo a flexibilidade, escalabilidade e desempenho dos pipelines Nextflow. + +Para exercitar esses elementos de configuração, vamos executar uma cópia nova do fluxo de trabalho que executamos por último no final da Parte 2 deste curso de treinamento, renomeado `3-main.nf`. + +Se você não está familiarizado com o pipeline Hello ou poderia usar um lembrete, veja [esta página de informações](../info/hello_pipeline.md). + +--- + +## 1. Gerenciar parâmetros de entrada do fluxo de trabalho + +??? example "Cenário" + + Você baixou um pipeline e quer executá-lo repetidamente com os mesmos arquivos de entrada e configurações, mas não quer digitar todos os parâmetros toda vez. + Ou talvez você esteja configurando o pipeline para um colega que não está confortável com argumentos de linha de comando. + +Vamos começar com um aspecto da configuração que é simplesmente uma extensão do que estivemos trabalhando até agora: o gerenciamento de parâmetros de entrada. + +Atualmente, nosso fluxo de trabalho está configurado para aceitar vários valores de parâmetro via linha de comando, declarados em um bloco `params` no próprio script do fluxo de trabalho. +Um tem um valor padrão definido como parte de sua declaração. + +No entanto, você pode querer definir padrões para todos eles, ou substituir o padrão existente sem ter que especificar parâmetros na linha de comando ou modificar o arquivo de script original. + +Há múltiplas formas de fazer isso; vamos mostrar três formas básicas que são muito comumente usadas. + +### 1.1. Configure valores no `nextflow.config` + +Esta é a abordagem mais simples, embora seja possivelmente a menos flexível já que o arquivo principal `nextflow.config` não é algo que você quer estar editando para cada execução. +Mas tem a vantagem de separar as preocupações de _declarar_ os parâmetros no fluxo de trabalho (que definitivamente pertence lá) versus fornecer _valores padrão_, que estão mais em casa em um arquivo de configuração. + +Vamos fazer isso em duas etapas. + +#### 1.1.1. Crie um bloco `params` no arquivo de configuração + +Faça as seguintes mudanças de código no arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +Note que não simplesmente copiamos o bloco `params` do fluxo de trabalho para o arquivo de configuração. +Para o parâmetro `batch` que já tinha um valor padrão declarado, a sintaxe é um pouco diferente. +No arquivo de fluxo de trabalho, essa é uma declaração tipada. +Na configuração, essas são atribuições de valor. + +Tecnicamente, isso é suficiente para substituir os valores padrão ainda especificados no arquivo de fluxo de trabalho. +Você poderia modificar o valor padrão para `batch` e executar o fluxo de trabalho para se satisfazer de que o valor definido no arquivo de configuração substitui o definido no arquivo de fluxo de trabalho. + +Mas no espírito de mover a configuração completamente para o arquivo de configuração, vamos remover esse valor padrão do arquivo de fluxo de trabalho inteiramente. + +#### 1.1.2. Remova o valor padrão para `batch` no arquivo de fluxo de trabalho + +Faça a seguinte mudança de código no arquivo de fluxo de trabalho `3-main.nf`: + +=== "Depois" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parameters + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Agora o arquivo de fluxo de trabalho em si não define nenhum valor padrão para esses parâmetros. + +#### 1.1.3. Execute o pipeline + +Vamos testar se funciona corretamente sem especificar nenhum parâmetro na linha de comando. + +```bash +nextflow run 3-main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes. + +A saída final de arte ASCII está no diretório `results/3-main/`, sob o nome `cowpy-COLLECTED-batch-output.txt`, igual a antes. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Funcionalmente, essa mudança não alterou nada, mas conceitualmente é um pouco mais limpo ter os valores padrão definidos no arquivo de configuração. + +### 1.2. Use um arquivo de configuração específico para execução + +??? example "Cenário" + + Você quer experimentar com diferentes configurações sem modificar seu arquivo de configuração principal. + +Você pode fazer isso criando um novo arquivo `nextflow.config` em um subdiretório que você usará como diretório de trabalho para seus experimentos. + +#### 1.2.1. Crie o diretório de trabalho com uma configuração em branco + +Vamos começar criando um novo diretório e entrando nele: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Então, crie um arquivo de configuração em branco nesse diretório: + +```bash +touch nextflow.config +``` + +Isso produz um arquivo vazio. + +#### 1.2.2. Configure a configuração experimental + +Agora abra o novo arquivo e adicione os parâmetros que você quer personalizar: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Note que o caminho para o arquivo de entrada deve refletir a estrutura de diretórios. + +#### 1.2.3. Execute o pipeline + +Agora podemos executar nosso pipeline de dentro do nosso novo diretório de trabalho. +Certifique-se de adaptar o caminho de acordo! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Isso criará um novo conjunto de diretórios sob `tux-run/` incluindo `tux-run/work/` e `tux-run/results/`. + +Nesta execução, o Nextflow combina o `nextflow.config` em nosso diretório atual com o `nextflow.config` no diretório raiz do pipeline, e assim substitui o personagem padrão (turkey) pelo personagem tux. + +O arquivo de saída final deve conter o personagem tux dizendo as saudações. + +??? abstract "Conteúdo do arquivo" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +Pronto; agora você tem um espaço para experimentar sem modificar sua configuração 'normal'. + +!!! warning "Aviso" + + Certifique-se de voltar ao diretório anterior antes de passar para a próxima seção! + + ```bash + cd .. + ``` + +Agora vamos olhar outra forma útil de definir valores de parâmetros. + +### 1.3. Use um arquivo de parâmetros + +??? example "Cenário" + + Você precisa compartilhar parâmetros de execução exatos com um colaborador, ou registrá-los para uma publicação. + +A abordagem de subdiretório funciona muito bem para experimentar, mas envolve um pouco de configuração e requer que você adapte os caminhos de acordo. +Há uma abordagem mais simples para quando você quer executar seu pipeline com um conjunto específico de valores, ou permitir que outra pessoa faça isso com esforço mínimo. + +O Nextflow nos permite especificar parâmetros via um arquivo de parâmetros em formato YAML ou JSON, o que o torna muito conveniente para gerenciar e distribuir conjuntos alternativos de valores padrão, por exemplo, bem como valores de parâmetros específicos de execução. + +#### 1.3.1. Examine o arquivo de parâmetros de exemplo + +Para demonstrar isso, fornecemos um arquivo de parâmetros de exemplo no diretório atual, chamado `test-params.yaml`: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Este arquivo de parâmetros contém um par chave-valor para cada uma das entradas que queremos especificar. +Note o uso de dois-pontos (`:`) em vez de sinais de igual (`=`) se você comparar a sintaxe com o arquivo de configuração. +O arquivo de configuração é escrito em Groovy, enquanto o arquivo de parâmetros é escrito em YAML. + +!!! info "Informação" + + Também fornecemos uma versão JSON do arquivo de parâmetros como exemplo, mas não vamos executar com ele aqui. + Sinta-se livre para tentar esse por conta própria. + +#### 1.3.2. Execute o pipeline + +Para executar o fluxo de trabalho com este arquivo de parâmetros, simplesmente adicione `-params-file <filename>` ao comando base. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +O arquivo de saída final deve conter o personagem stegosaurus dizendo as saudações. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Usar um arquivo de parâmetros pode parecer exagero quando você tem apenas alguns parâmetros para especificar, mas alguns pipelines esperam dezenas de parâmetros. +Nesses casos, usar um arquivo de parâmetros nos permitirá fornecer valores de parâmetros em tempo de execução sem ter que digitar linhas de comando massivas e sem modificar o script de fluxo de trabalho. + +Também torna mais fácil distribuir conjuntos de parâmetros para colaboradores, ou como informação suplementar para uma publicação, por exemplo. +Isso torna seu trabalho mais reproduzível por outros. + +### Conclusão + +Você sabe como aproveitar opções de configuração-chave para gerenciar entradas de fluxo de trabalho. + +### O que vem a seguir? + +Aprenda como gerenciar onde e como as saídas do seu fluxo de trabalho são publicadas. + +--- + +## 2. Gerenciar saídas do fluxo de trabalho + +??? example "Cenário" + + Seu pipeline publica saídas em um diretório codificado, mas você quer organizar resultados por projeto ou nome de experimento sem editar o código do fluxo de trabalho toda vez. + +O fluxo de trabalho que herdamos usa caminhos para declarações de saída em nível de fluxo de trabalho, o que não é muito flexível e envolve muita repetição. + +Vamos olhar algumas formas comuns de configurar isso para ser mais flexível. + +### 2.1. Personalize o nome do diretório `outputDir` + +Cada versão do fluxo de trabalho que executamos até agora publicou suas saídas em um subdiretório diferente codificado nas definições de saída. + +Vamos mudar isso para usar um parâmetro configurável pelo usuário. +Poderíamos criar um parâmetro totalmente novo para isso, mas vamos usar o parâmetro `batch` já que ele está bem ali. + +#### 2.1.1. Defina um valor para `outputDir` no arquivo de configuração + +O caminho que o Nextflow usa para publicar saídas é controlado pela opção `outputDir`. +Para mudar o caminho para todas as saídas, você pode definir um valor para esta opção no arquivo de configuração `nextflow.config`. + +Adicione o seguinte código ao arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parameters + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Isso substituirá o caminho padrão embutido, `results/`, por `results/` mais o valor do parâmetro `batch` como subdiretório. +Você também poderia mudar a parte `results` se quisesse. + +Para uma mudança temporária, você poderia definir esta opção da linha de comando usando o parâmetro `-output-dir` no seu comando (mas então você não poderia usar o valor do parâmetro `batch`). + +#### 2.1.2. Remova a parte repetida do caminho codificado + +Ainda temos um subdiretório codificado nas opções de saída, então vamos nos livrar disso agora. + +Faça as seguintes mudanças de código no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +Também poderíamos ter apenas adicionado `${params.batch}` a cada caminho em vez de modificar o `outputDir` padrão, mas isso é mais conciso. + +#### 2.1.3. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote para `outdir` da linha de comando. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/outdir/`. + +??? abstract "Conteúdo do diretório" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Você pode combinar esta abordagem com definições de caminho personalizadas para construir qualquer hierarquia de diretórios que você goste. + +### 2.2. Organize saídas por processo + +Uma forma popular de organizar saídas ainda mais é fazê-lo por processo, _ou seja_, criar subdiretórios para cada processo executado no pipeline. + +#### 2.2.1. Substitua os caminhos de saída por uma referência aos nomes dos processos + +Tudo o que você precisa fazer é referenciar o nome do processo como `<task>.name` na declaração do caminho de saída. + +Faça as seguintes mudanças no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Isso remove os elementos codificados restantes da configuração do caminho de saída. + +#### 2.2.2. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote para `pnames` da linha de comando. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/pnames/`, e elas estão agrupadas por processo. + +??? abstract "Conteúdo do diretório" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Note que aqui apagamos a distinção entre `intermediates` versus saídas finais no nível superior. +Você poderia claro misturar e combinar essas abordagens, por exemplo definindo o caminho da primeira saída como `intermediates/${sayHello.name}` + +### 2.3. Defina o modo de publicação no nível do fluxo de trabalho + +Finalmente, no espírito de reduzir a quantidade de código repetitivo, podemos substituir as declarações de `mode` por saída por uma única linha na configuração. + +#### 2.3.1. Adicione `workflow.output.mode` ao arquivo de configuração + +Adicione o seguinte código ao arquivo `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +Assim como a opção `outputDir`, dar a `workflow.output.mode` um valor no arquivo de configuração seria suficiente para substituir o que está definido no arquivo de fluxo de trabalho, mas vamos remover o código desnecessário de qualquer forma. + +#### 2.3.2. Remova o modo de saída do arquivo de fluxo de trabalho + +Faça as seguintes mudanças no arquivo de fluxo de trabalho: + +=== "Depois" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Antes" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +Isso é mais conciso, não é? + +#### 2.3.3. Execute o pipeline + +Vamos testar se funciona corretamente, definindo o nome do lote para `outmode` da linha de comando. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Isso ainda produz a mesma saída de antes, exceto que desta vez encontramos nossas saídas em `results/outmode/`. +Elas ainda são todas cópias apropriadas, não symlinks. + +??? abstract "Conteúdo do diretório" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +A principal razão pela qual você ainda pode querer usar a forma por saída de definir o modo é se você quer misturar e combinar dentro do mesmo fluxo de trabalho, _ou seja_, ter algumas saídas sendo copiadas e algumas sendo symlinks. + +Há muitas outras opções que você pode personalizar dessa forma, mas esperamos que isso dê uma ideia da gama de opções e como utilizá-las efetivamente para se adequar às suas preferências. + +### Conclusão + +Você sabe como controlar a nomenclatura e estrutura dos diretórios onde suas saídas são publicadas, bem como o modo de publicação de saída do fluxo de trabalho. + +### O que vem a seguir? + +Aprenda como adaptar a configuração do seu fluxo de trabalho ao seu ambiente de computação, começando com a tecnologia de empacotamento de software. + +--- + +## 3. Selecione uma tecnologia de empacotamento de software + +Até agora estivemos olhando elementos de configuração que controlam como as entradas entram e onde as saídas saem. Agora é hora de focar mais especificamente em adaptar a configuração do seu fluxo de trabalho ao seu ambiente de computação. + +O primeiro passo nesse caminho é especificar de onde os pacotes de software que serão executados em cada etapa virão. +Eles já estão instalados no ambiente de computação local? +Precisamos recuperar imagens e executá-las via um sistema de contêiner? +Ou precisamos recuperar pacotes Conda e construir um ambiente Conda local? + +Na primeira parte deste curso de treinamento (Partes 1-4) apenas usamos software instalado localmente em nosso fluxo de trabalho. +Então na Parte 5, introduzimos contêineres Docker e o arquivo `nextflow.config`, que usamos para habilitar o uso de contêineres Docker. + +Agora vamos ver como podemos configurar uma opção alternativa de empacotamento de software via o arquivo `nextflow.config`. + +### 3.1. Desabilite Docker e habilite Conda no arquivo de configuração + +??? example "Cenário" + + Você está movendo seu pipeline para um cluster HPC onde Docker não é permitido por razões de segurança. + O cluster suporta Singularity e Conda, então você precisa mudar sua configuração de acordo. + +O Nextflow suporta múltiplas tecnologias de contêiner incluindo Singularity (que é mais amplamente usado em HPC), bem como gerenciadores de pacotes de software como Conda. + +Podemos mudar nosso arquivo de configuração para usar Conda em vez de Docker. +Para fazer isso, vamos mudar o valor de `docker.enabled` para `false`, e adicionar uma diretiva habilitando o uso de Conda: + +=== "Depois" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Isso permitirá que o Nextflow crie e utilize ambientes Conda para processos que tenham pacotes Conda especificados. +O que significa que agora precisamos adicionar um desses ao nosso processo `cowpy`! + +### 3.2. Especifique um pacote Conda na definição do processo + +Já recuperamos o URI para um pacote Conda contendo a ferramenta `cowpy`: `conda-forge::cowpy==1.1.5` + +Agora adicionamos o URI à definição do processo `cowpy` usando a diretiva `conda`: + +=== "Depois" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Antes" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Para ser claro, não estamos _substituindo_ a diretiva `docker`, estamos _adicionando_ uma opção alternativa. + +!!! tip "Dica" + + Há algumas formas diferentes de obter o URI para um determinado pacote conda. + Recomendamos usar a consulta de pesquisa do [Seqera Containers](https://seqera.io/containers/), que dará a você um URI que você pode copiar e colar, mesmo se você não está planejando criar um contêiner a partir dele. + +### 3.3. Execute o fluxo de trabalho para verificar que ele pode usar Conda + +Vamos testar. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Saída do comando" + + ```console title="Saída" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Isso deve funcionar sem problemas e produzir as mesmas saídas de antes em `results/conda`. + +Por trás dos bastidores, o Nextflow recuperou os pacotes Conda e criou o ambiente, o que normalmente dá um pouco de trabalho; então é bom que não tenhamos que fazer nada disso nós mesmos! + +!!! info "Informação" + + Isso executa rapidamente porque o pacote `cowpy` é bem pequeno, mas se você está trabalhando com pacotes grandes, pode levar um pouco mais do que o normal na primeira vez, e você pode ver a saída do console ficar 'travada' por um minuto ou mais antes de completar. + Isso é normal e é devido ao trabalho extra que o Nextflow faz na primeira vez que você usa um novo pacote. + +Do nosso ponto de vista, parece que funciona exatamente igual a executar com Docker, mesmo que no backend a mecânica seja um pouco diferente. + +Isso significa que estamos prontos para executar com ambientes Conda se necessário. + +??? info "Misturando Docker e Conda" + + Como essas diretivas são atribuídas por processo, é possível 'misturar e combinar', _ou seja_, configurar alguns dos processos no seu fluxo de trabalho para executar com Docker e outros com Conda, por exemplo, se a infraestrutura de computação que você está usando suporta ambos. + Nesse caso, você habilitaria tanto Docker quanto Conda no seu arquivo de configuração. + Se ambos estiverem disponíveis para um determinado processo, o Nextflow priorizará contêineres. + + E como notado anteriormente, o Nextflow suporta múltiplas outras tecnologias de empacotamento de software e contêiner, então você não está limitado a apenas essas duas. + +### Conclusão + +Você sabe como configurar qual pacote de software cada processo deve usar, e como alternar entre tecnologias. + +### O que vem a seguir? + +Aprenda como mudar a plataforma de execução usada pelo Nextflow para realmente fazer o trabalho. + +--- + +## 4. Selecione uma plataforma de execução + +??? example "Cenário" + + Você tem desenvolvido e testado seu pipeline no seu laptop, mas agora precisa executá-lo em milhares de amostras. + Sua instituição tem um cluster HPC com um scheduler Slurm que você gostaria de usar em vez disso. + +Até agora, estivemos executando nosso pipeline com o executor local. +Isso executa cada tarefa na máquina em que o Nextflow está rodando. +Quando o Nextflow começa, ele olha para os CPUs e memória disponíveis. +Se os recursos das tarefas prontas para executar excederem os recursos disponíveis, o Nextflow segurará as últimas tarefas da execução até que uma ou mais das tarefas anteriores tenham terminado, liberando os recursos necessários. + +O executor local é conveniente e eficiente, mas é limitado àquela única máquina. Para cargas de trabalho muito grandes, você pode descobrir que sua máquina local é um gargalo, seja porque você tem uma única tarefa que requer mais recursos do que você tem disponível, ou porque você tem tantas tarefas que esperar por uma única máquina para executá-las levaria muito tempo. + +O Nextflow suporta [muitos backends de execução diferentes](https://www.nextflow.io/docs/latest/executor.html), incluindo schedulers HPC (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor e outros) bem como backends de execução em nuvem (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes e mais). + +### 4.1. Mirando um backend diferente + +A escolha do executor é definida por uma diretiva de processo chamada `executor`. +Por padrão ela é definida como `local`, então a seguinte configuração está implícita: + +```groovy title="Configuração embutida" +process { + executor = 'local' +} +``` + +Para definir o executor para mirar um backend diferente, você simplesmente especificaria o executor que você quer usando sintaxe similar à descrita acima para alocações de recursos (veja [documentação](https://www.nextflow.io/docs/latest/executor.html) para todas as opções). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Aviso" + + Não podemos realmente testar isso no ambiente de treinamento porque ele não está configurado para conectar a um HPC. + +### 4.2. Lidando com sintaxe específica de backend para parâmetros de execução + +A maioria das plataformas de computação de alto desempenho permite (e às vezes requer) que você especifique certos parâmetros como solicitações e limitações de alocação de recursos (por exemplo, número de CPUs e memória) e nome da fila de jobs a usar. + +Infelizmente, cada um desses sistemas usa diferentes tecnologias, sintaxes e configurações para definir como um job deve ser definido e submetido ao scheduler relevante. + +??? abstract "Exemplos" + + Por exemplo, o mesmo job requerendo 8 CPUs e 4GB de RAM para ser executado na fila "my-science-work" precisa ser expresso de formas diferentes dependendo do backend. + + ```bash title="Config para SLURM / submeter usando sbatch" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="Config para PBS / submeter usando qsub" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="Config para SGE / submeter usando qsub" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Felizmente, o Nextflow simplifica tudo isso. +Ele fornece uma sintaxe padronizada para que você possa especificar as propriedades relevantes como `cpus`, `memory` e `queue` (veja documentação para outras propriedades) apenas uma vez. +Então, em tempo de execução, o Nextflow usará essas configurações para gerar os scripts específicos de backend apropriados baseados na configuração do executor. + +Cobriremos essa sintaxe padronizada na próxima seção. + +### Conclusão + +Agora você sabe como mudar o executor para usar diferentes tipos de infraestrutura de computação. + +### O que vem a seguir? + +Aprenda como avaliar e expressar alocações e limitações de recursos no Nextflow. + +--- + +## 5. Controlar alocações de recursos de computação + +??? example "Cenário" + + Seu pipeline continua falhando no cluster porque tarefas estão sendo mortas por exceder limites de memória. + Ou talvez você esteja sendo cobrado por recursos que não está usando e quer otimizar custos. + +A maioria das plataformas de computação de alto desempenho permite (e às vezes requer) que você especifique certos parâmetros de alocação de recursos como número de CPUs e memória. + +Por padrão, o Nextflow usará um único CPU e 2GB de memória para cada processo. +As diretivas de processo correspondentes são chamadas `cpus` e `memory`, então a seguinte configuração está implícita: + +```groovy title="Configuração embutida" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Você pode modificar esses valores, seja para todos os processos ou para processos nomeados específicos, usando diretivas de processo adicionais no seu arquivo de configuração. +O Nextflow as traduzirá nas instruções apropriadas para o executor escolhido. + +Mas como você sabe quais valores usar? + +### 5.1. Execute o fluxo de trabalho para gerar um relatório de utilização de recursos + +??? example "Cenário" + + Você não sabe quanta memória ou CPU seus processos precisam e quer evitar desperdiçar recursos ou ter jobs mortos. + +Se você não sabe antecipadamente quanta CPU e memória seus processos provavelmente precisarão, você pode fazer algum profiling de recursos, significando que você executa o fluxo de trabalho com algumas alocações padrão, registra quanto cada processo usou, e a partir daí, estima como ajustar as alocações base. + +Convenientemente, o Nextflow inclui ferramentas embutidas para fazer isso, e alegremente gerará um relatório para você sob demanda. + +Para fazer isso, adicione `-with-report <filename>.html` à sua linha de comando. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +O relatório é um arquivo html, que você pode baixar e abrir no seu navegador. Você também pode clicar com o botão direito nele no explorador de arquivos à esquerda e clicar em `Show preview` para visualizá-lo no ambiente de treinamento. + +Tire alguns minutos para olhar o relatório e ver se consegue identificar algumas oportunidades para ajustar recursos. +Certifique-se de clicar nas abas que mostram os resultados de utilização como uma porcentagem do que foi alocado. +Há alguma [documentação](https://www.nextflow.io/docs/latest/reports.html) descrevendo todos os recursos disponíveis. + +### 5.2. Defina alocações de recursos para todos os processos + +O profiling mostra que os processos em nosso fluxo de trabalho de treinamento são muito leves, então vamos reduzir a alocação padrão de memória para 1GB por processo. + +Adicione o seguinte ao seu arquivo `nextflow.config`, antes da seção de parâmetros do pipeline: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Isso ajudará a reduzir a quantidade de computação que consumimos. + +### 5.3. Defina alocações de recursos para um processo específico + +Ao mesmo tempo, vamos fingir que o processo `cowpy` requer mais recursos do que os outros, apenas para demonstrar como ajustar alocações para um processo individual. + +=== "Depois" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Antes" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Com esta configuração, todos os processos solicitarão 1GB de memória e um único CPU (o padrão implícito), exceto o processo `cowpy`, que solicitará 2GB e 2 CPUs. + +!!! info "Informação" + + Se você tem uma máquina com poucos CPUs e você aloca um número alto por processo, você pode ver chamadas de processo sendo enfileiradas atrás umas das outras. + Isso é porque o Nextflow garante que não solicitemos mais CPUs do que estão disponíveis. + +### 5.4. Execute o fluxo de trabalho com a configuração atualizada + +Vamos testar isso, fornecendo um nome de arquivo diferente para o relatório de profiling para que possamos comparar o desempenho antes e depois das mudanças de configuração. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Você provavelmente não notará nenhuma diferença real já que esta é uma carga de trabalho tão pequena, mas esta é a abordagem que você usaria para analisar o desempenho e requisitos de recursos de um fluxo de trabalho do mundo real. + +É muito útil quando seus processos têm requisitos de recursos diferentes. Isso te empodera a dimensionar corretamente as alocações de recursos que você configura para cada processo baseado em dados reais, não suposições. + +!!! tip "Dica" + + Este é apenas um pequeno gosto do que você pode fazer para otimizar seu uso de recursos. + O próprio Nextflow tem alguma [lógica de retry dinâmico](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) bem legal embutida para retentar jobs que falham devido a limitações de recursos. + Além disso, a Seqera Platform oferece ferramentas orientadas por IA para otimizar suas alocações de recursos automaticamente também. + +### 5.5. Adicione limites de recursos + +Dependendo de qual executor de computação e infraestrutura de computação você está usando, pode haver algumas restrições sobre o que você pode (ou deve) alocar. +Por exemplo, seu cluster pode requerer que você fique dentro de certos limites. + +Você pode usar a diretiva `resourceLimits` para definir as limitações relevantes. A sintaxe se parece com isso quando está sozinha em um bloco process: + +```groovy title="Exemplo de sintaxe" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +O Nextflow traduzirá esses valores nas instruções apropriadas dependendo do executor que você especificou. + +Não vamos executar isso, já que não temos acesso a infraestrutura relevante no ambiente de treinamento. +No entanto, se você tentasse executar o fluxo de trabalho com alocações de recursos que excedam esses limites, então procurasse o comando `sbatch` no arquivo de script `.command.run`, você veria que as solicitações que realmente são enviadas ao executor são limitadas aos valores especificados por `resourceLimits`. + +??? info "Configurações de referência institucionais" + + O projeto nf-core compilou uma [coleção de arquivos de configuração](https://nf-co.re/configs/) compartilhados por várias instituições ao redor do mundo, cobrindo uma ampla gama de executores HPC e cloud. + + Essas configs compartilhadas são valiosas tanto para pessoas que trabalham lá e podem portanto simplesmente utilizar a configuração da sua instituição prontas para uso, quanto como modelo para pessoas que estão procurando desenvolver uma configuração para sua própria infraestrutura. + +### Conclusão + +Você sabe como gerar um relatório de profiling para avaliar a utilização de recursos e como modificar alocações de recursos para todos os processos e/ou para processos individuais, bem como definir limitações de recursos para executar em HPC. + +### O que vem a seguir? + +Aprenda como configurar perfis de configuração predefinidos e alternar entre eles em tempo de execução. + +--- + +## 6. Use perfis para alternar entre configurações predefinidas + +??? example "Cenário" + + Você regularmente alterna entre executar pipelines no seu laptop para desenvolvimento e no HPC da sua instituição para execuções de produção. + Você está cansado de manualmente mudar configurações toda vez que muda de ambiente. + +Mostramos várias formas de personalizar a configuração do seu pipeline dependendo do projeto em que você está trabalhando ou do ambiente de computação que você está usando. + +Você pode querer alternar entre configurações alternativas dependendo de qual infraestrutura de computação você está usando. Por exemplo, você pode querer desenvolver e executar testes em pequena escala localmente no seu laptop, depois executar cargas de trabalho em escala completa em HPC ou cloud. + +O Nextflow te permite configurar qualquer número de perfis que descrevem diferentes configurações, que você pode então selecionar em tempo de execução usando um argumento de linha de comando, em vez de ter que modificar o arquivo de configuração em si. + +### 6.1. Crie perfis para alternar entre desenvolvimento local e execução em HPC + +Vamos configurar dois perfis alternativos; um para executar cargas em pequena escala em um computador regular, onde usaremos contêineres Docker, e um para executar em um HPC universitário com um scheduler Slurm, onde usaremos pacotes Conda. + +#### 6.1.1. Configure os perfis + +Adicione o seguinte ao seu arquivo `nextflow.config`, após a seção de parâmetros do pipeline mas antes das configurações de saída: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Você vê que para o HPC universitário, também estamos especificando limitações de recursos. + +#### 6.1.2. Execute o fluxo de trabalho com um perfil + +Para especificar um perfil na nossa linha de comando Nextflow, usamos o argumento `-profile`. + +Vamos tentar executar o fluxo de trabalho com a configuração `my_laptop`. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Como você pode ver, isso nos permite alternar entre configurações muito convenientemente em tempo de execução. + +!!! warning "Aviso" + + O perfil `univ_hpc` não funcionará corretamente no ambiente de treinamento já que não temos acesso a um scheduler Slurm. + +Se no futuro encontrarmos outros elementos de configuração que sempre co-ocorrem com esses, podemos simplesmente adicioná-los ao(s) perfil(s) correspondente(s). +Também podemos criar perfis adicionais se houver outros elementos de configuração que queremos agrupar. + +### 6.2. Crie um perfil de parâmetros de teste + +??? example "Cenário" + + Você quer que outros possam experimentar seu pipeline rapidamente sem reunir seus próprios dados de entrada. + +Perfis não são apenas para configuração de infraestrutura. +Também podemos usá-los para definir valores padrão para parâmetros de fluxo de trabalho, para facilitar que outros experimentem o fluxo de trabalho sem ter que reunir valores de entrada apropriados por conta própria. +Você pode considerar isso uma alternativa a usar um arquivo de parâmetros. + +#### 6.2.1. Configure o perfil + +A sintaxe para expressar valores padrão neste contexto se parece com isso, para um perfil que nomeamos `test`: + +```groovy title="Exemplo de sintaxe" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Se adicionarmos um perfil de teste para nosso fluxo de trabalho, o bloco `profiles` se torna: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Assim como para perfis de configuração técnica, você pode configurar múltiplos perfis diferentes especificando parâmetros sob qualquer nome arbitrário que você goste. + +#### 6.2.2. Execute o fluxo de trabalho localmente com o perfil de teste + +Convenientemente, perfis não são mutuamente exclusivos, então podemos especificar múltiplos perfis em nossa linha de comando usando a seguinte sintaxe `-profile <profile1>,<profile2>` (para qualquer número de perfis). + +Se você combinar perfis que definem valores para os mesmos elementos de configuração e são descritos no mesmo arquivo de configuração, o Nextflow resolverá o conflito usando qualquer valor que ele leu por último (_ou seja_, o que vem depois no arquivo). +Se as configurações conflitantes são definidas em diferentes fontes de configuração, a [ordem de precedência](https://www.nextflow.io/docs/latest/config.html) padrão se aplica. + +Vamos tentar adicionar o perfil de teste ao nosso comando anterior: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Isso usará Docker onde possível e produzirá saídas em `results/test`, e desta vez o personagem é a dupla cômica `dragonandcow`. + +??? abstract "Conteúdo do arquivo" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Isso significa que desde que distribuamos quaisquer arquivos de dados de teste com o código do fluxo de trabalho, qualquer um pode experimentar rapidamente o fluxo de trabalho sem ter que fornecer suas próprias entradas via linha de comando ou arquivo de parâmetros. + +!!! tip "Dica" + + Podemos apontar para URLs para arquivos maiores que estão armazenados externamente. + O Nextflow os baixará automaticamente desde que haja uma conexão aberta. + + Para mais detalhes, veja a Side Quest [Working with Files](../side_quests/working_with_files.md) + +### 6.3. Use `nextflow config` para ver a configuração resolvida + +Como notado acima, às vezes o mesmo parâmetro pode ser definido para valores diferentes em perfis que você quer combinar. +E mais geralmente, há numerosos lugares onde elementos de configuração podem ser armazenados, e às vezes as mesmas propriedades podem ser definidas para valores diferentes em diferentes lugares. + +O Nextflow aplica uma [ordem de precedência](https://www.nextflow.io/docs/latest/config.html) definida para resolver quaisquer conflitos, mas isso pode ser complicado de determinar você mesmo. +E mesmo que nada esteja conflitando, pode ser tedioso procurar em todos os lugares possíveis onde coisas poderiam estar configuradas. + +Felizmente, o Nextflow inclui uma ferramenta utilitária conveniente chamada `config` que pode automatizar todo esse processo para você. + +A ferramenta `config` explorará todo o conteúdo no seu diretório de trabalho atual, aspirará quaisquer arquivos de configuração, e produzirá a configuração completamente resolvida que o Nextflow usaria para executar o fluxo de trabalho. +Isso permite que você descubra quais configurações serão usadas sem ter que lançar nada. + +#### 6.3.1. Resolva a configuração padrão + +Execute este comando para resolver a configuração que seria aplicada por padrão. + +```bash +nextflow config +``` + +??? success "Saída do comando" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Isso mostra a configuração base que você obtém se não especificar nada extra na linha de comando. + +#### 6.3.2. Resolva a configuração com configurações específicas ativadas + +Se você fornecer parâmetros de linha de comando, por exemplo, habilitando um ou mais perfis ou carregando um arquivo de parâmetros, o comando adicionalmente levará esses em conta. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Saída do comando" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Isso se torna especialmente útil para projetos complexos que envolvem múltiplas camadas de configuração. + +### Conclusão + +Você sabe como usar perfis para selecionar uma configuração predefinida em tempo de execução com o mínimo de trabalho. +Mais geralmente, você sabe como configurar suas execuções de fluxo de trabalho para se adequar a diferentes plataformas de computação e melhorar a reprodutibilidade de suas análises. + +### O que vem a seguir? + +Aprenda como executar pipelines diretamente de repositórios remotos como GitHub. + +--- + +## 7. Execute pipelines de repositórios remotos + +??? example "Cenário" + + Você quer executar um pipeline bem estabelecido como os do nf-core sem ter que baixar e gerenciar o código você mesmo. + +Até agora estivemos executando scripts de fluxo de trabalho localizados no diretório atual. +Na prática, você frequentemente vai querer executar pipelines armazenados em repositórios remotos, como GitHub. + +O Nextflow torna isso direto: você pode executar qualquer pipeline diretamente de uma URL de repositório Git sem baixá-lo manualmente primeiro. + +### 7.1. Execute um pipeline do GitHub + +A sintaxe básica para executar um pipeline remoto é `nextflow run <repository>`, onde `<repository>` pode ser um caminho de repositório GitHub como `nextflow-io/hello`, uma URL completa, ou um caminho para GitLab, Bitbucket, ou outros serviços de hospedagem Git. + +Tente executar o pipeline demo oficial "hello" do Nextflow: + +```bash +nextflow run nextflow-io/hello +``` + +A primeira vez que você executa um pipeline remoto, o Nextflow o baixa e faz cache localmente. +Execuções subsequentes usam a versão cacheada a menos que você explicitamente solicite uma atualização. + +### 7.2. Especifique uma versão para reprodutibilidade + +Por padrão, o Nextflow executa a versão mais recente do branch padrão. +Você pode especificar uma versão particular, branch, ou commit usando a flag `-r`: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Especificar versões exatas é essencial para reprodutibilidade. + +### Conclusão + +Você sabe como executar pipelines diretamente do GitHub e outros repositórios remotos, e como especificar versões para reprodutibilidade. + +### O que vem a seguir? + +Dê-se um grande tapinha nas costas! +Você sabe tudo o que precisa saber para começar a executar e gerenciar pipelines Nextflow. + +Isso conclui este curso, mas se você está ansioso para continuar aprendendo, temos duas recomendações principais: + +- Se você quer se aprofundar no desenvolvimento de seus próprios pipelines, dê uma olhada em [Hello Nextflow](../hello_nextflow/index.md), um curso para iniciantes que cobre a mesma progressão geral que este mas entra em muito mais detalhes sobre canais e operadores. +- Se você gostaria de continuar aprendendo como executar pipelines Nextflow sem ir mais fundo no código, dê uma olhada na primeira parte de [Hello nf-core](../hello_nf-core/index.md), que introduz as ferramentas para encontrar e executar pipelines do projeto [nf-core](https://nf-co.re/) imensamente popular. + +Divirta-se! + +--- + +## Quiz + +<quiz> +Quando valores de parâmetros são definidos tanto no arquivo de fluxo de trabalho quanto no `nextflow.config`, qual tem precedência? +- [ ] O valor do arquivo de fluxo de trabalho +- [x] O valor do arquivo de configuração +- [ ] O primeiro valor encontrado +- [ ] Isso causa um erro + +Saiba mais: [1.1. Configure valores no `nextflow.config`](#11-configure-valores-no-nextflowconfig) +</quiz> + +<quiz> +Qual é a diferença de sintaxe entre definir um padrão de parâmetro em um arquivo de fluxo de trabalho vs. um arquivo de configuração? +- [ ] Eles usam a mesma sintaxe +- [x] Fluxo de trabalho usa declaração tipada (`#!groovy param: Type = value`), config usa atribuição (`#!groovy param = value`) +- [ ] Config usa declaração tipada, fluxo de trabalho usa atribuição +- [ ] Apenas arquivos de configuração podem definir valores padrão + +Saiba mais: [1.1. Configure valores no `nextflow.config`](#11-configure-valores-no-nextflowconfig) +</quiz> + +<quiz> +Como você especifica um arquivo de parâmetros ao executar um fluxo de trabalho? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Saiba mais: [1.3. Use um arquivo de parâmetros](#13-use-um-arquivo-de-parametros) +</quiz> + +<quiz> +O que a opção de configuração `outputDir` controla? +- [ ] A localização do diretório work +- [x] O caminho base onde as saídas do fluxo de trabalho são publicadas +- [ ] O diretório para arquivos de log +- [ ] A localização dos arquivos de módulo + +Saiba mais: [2.1. Personalize o nome do diretório outputDir](#21-personalize-o-nome-do-diretorio-outputdir) +</quiz> + +<quiz> +Como você referencia um nome de processo dinamicamente na configuração de caminho de saída? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Saiba mais: [2.2. Organize saídas por processo](#22-organize-saidas-por-processo) +</quiz> + +<quiz> +Se tanto Docker quanto Conda estão habilitados e um processo tem ambas as diretivas, qual é priorizado? +- [x] Docker (contêineres) +- [ ] Conda +- [ ] O primeiro definido no processo +- [ ] Isso causa um erro + +Saiba mais: [3. Selecione uma tecnologia de empacotamento de software](#3-selecione-uma-tecnologia-de-empacotamento-de-software) +</quiz> + +<quiz> +Qual é o executor padrão no Nextflow? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Saiba mais: [4. Selecione uma plataforma de execução](#4-selecione-uma-plataforma-de-execucao) +</quiz> + +<quiz> +Qual comando gera um relatório de utilização de recursos? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Saiba mais: [5.1. Execute o fluxo de trabalho para gerar um relatório de utilização de recursos](#51-execute-o-fluxo-de-trabalho-para-gerar-um-relatorio-de-utilizacao-de-recursos) +</quiz> + +<quiz> +Como você define requisitos de recursos para um processo específico chamado `cowpy` no arquivo de configuração? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Saiba mais: [5.3. Defina alocações de recursos para um processo específico](#53-defina-alocacoes-de-recursos-para-um-processo-especifico) +</quiz> + +<quiz> +O que a diretiva `resourceLimits` faz? +- [ ] Define requisitos mínimos de recursos +- [ ] Aloca recursos para processos +- [x] Limita os recursos máximos que podem ser solicitados +- [ ] Monitora o uso de recursos em tempo real + +Saiba mais: [5.5. Adicione limites de recursos](#55-adicione-limites-de-recursos) +</quiz> + +<quiz> +Como você especifica múltiplos perfis em um único comando? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Saiba mais: [6. Use perfis para alternar entre configurações predefinidas](#6-use-perfis-para-alternar-entre-configuracoes-predefinidas) +</quiz> + +<quiz> +Qual comando mostra a configuração completamente resolvida que o Nextflow usaria? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Saiba mais: [6.3. Use `nextflow config` para ver a configuração resolvida](#63-use-nextflow-config-para-ver-a-configuracao-resolvida) +</quiz> + +<quiz> +Para que os perfis podem ser usados? (Selecione todos que se aplicam) +- [x] Definir configurações específicas de infraestrutura (executores, contêineres) +- [x] Definir limites de recursos para diferentes ambientes +- [x] Fornecer parâmetros de teste para teste fácil de fluxo de trabalho +- [ ] Definir novos processos + +Saiba mais: [6. Use perfis para alternar entre configurações predefinidas](#6-use-perfis-para-alternar-entre-configuracoes-predefinidas) +</quiz> diff --git a/docs/pt/docs/nextflow_run/index.md b/docs/pt/docs/nextflow_run/index.md new file mode 100644 index 0000000000..3534e09a25 --- /dev/null +++ b/docs/pt/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Executar e gerenciar a execução de fluxos de trabalho Nextflow + - Encontrar e interpretar saídas (resultados) e arquivos de log + - Reconhecer os componentes principais do Nextflow em um fluxo de trabalho simples de múltiplas etapas + - Configurar a execução de pipelines para rodar em plataformas computacionais comuns, incluindo HPC e nuvem + - Resumir as melhores práticas para reprodutibilidade, portabilidade e reutilização de código que tornam os pipelines FAIR, incluindo modularidade de código e contêineres de software + audience_prerequisites: + - "**Público:** Este curso é projetado para alunos que são completamente novos no Nextflow e querem executar pipelines existentes." + - "**Habilidades:** Alguma familiaridade com a linha de comando, conceitos básicos de script e formatos de arquivo comuns é assumida." + - "**Domínio:** Os exercícios são todos independentes de domínio, então nenhum conhecimento científico prévio é necessário." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run é uma introdução prática para executar análises de dados reproduzíveis e escaláveis.** + +Trabalhando através de exemplos práticos e exercícios guiados, você aprenderá os fundamentos do uso do Nextflow, incluindo como executar pipelines, gerenciar arquivos e dependências de software, paralelizar a execução sem esforço e executar fluxos de trabalho em diferentes ambientes computacionais. + +Você levará consigo as habilidades e confiança para começar a executar fluxos de trabalho com Nextflow. + +<!-- additional_information --> + +## Visão geral do curso + +### O que você fará + +Este curso é prático, com exercícios orientados a objetivos estruturados para introduzir informações gradualmente. + +Você executará várias versões de um pipeline Nextflow que processa entradas de texto. +Você começará com uma versão simples que consiste em uma única etapa e eventualmente progredirá para uma versão de múltiplas etapas que recebe um arquivo CSV de entradas de texto tabulares, executa algumas etapas de transformação e produz um único arquivo de texto contendo uma imagem ASCII de um personagem dizendo o texto transformado. + +Este curso foca na execução de pipelines (nomeado após o comando principal `nextflow run`). +Se você está procurando uma introdução ao desenvolvimento de pipelines Nextflow, veja [Hello Nextflow](../hello_nextflow/index.md). + +### Plano de aula + +Dividimos isso em três partes que focarão em aspectos específicos da execução e gerenciamento de pipelines escritos em Nextflow. + +| Capítulo do curso | Resumo | Duração estimada | +| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| [Parte 1: Operações básicas de execução](./01_basics.md) | Executar e gerenciar a execução de um fluxo de trabalho simples | 30 mins | +| [Parte 2: Executar pipelines reais](./02_pipeline.md) | Processar entradas complexas, executar fluxos de trabalho de múltiplas etapas, usar contêineres e paralelizar execução sem esforço | 60 mins | +| [Parte 3: Configuração de execução](./03_config.md) | Personalizar o comportamento do pipeline e otimizar o uso em diferentes ambientes computacionais | 60 mins | + +Ao final deste curso, você estará bem preparado para enfrentar os próximos passos em sua jornada para executar fluxos de trabalho reproduzíveis para suas necessidades de computação científica. + +Pronto para fazer o curso? + +[Começar a aprender :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/pt/docs/nextflow_run/next_steps.md b/docs/pt/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..9fc17f1051 --- /dev/null +++ b/docs/pt/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Resumo do curso + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns por concluir o curso de treinamento Nextflow Run! 🎉 + +<!-- placeholder for video --> + +## Sua jornada + +Você começou com um fluxo de trabalho muito básico e aprendeu a executá-lo, encontrar as saídas e gerenciar sua execução. +Então, você trabalhou através de versões cada vez mais complexas daquele fluxo de trabalho e aprendeu a reconhecer os conceitos e mecanismos essenciais que alimentam os pipelines Nextflow, incluindo canais e operadores, modularização de código e contêineres. +Finalmente, você aprendeu como personalizar a configuração de um pipeline para se adequar às suas preferências e sua infraestrutura computacional. + +### O que você aprendeu + +Você agora é capaz de gerenciar a execução do pipeline Hello, descrever como ele está estruturado e identificar as principais peças de código envolvidas. + +- A forma final do fluxo de trabalho Hello recebe como entrada um arquivo CSV contendo saudações de texto. +- As quatro etapas são implementadas como processos Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) armazenados em arquivos de módulo separados. +- Os resultados são publicados em um diretório chamado `results/`. +- A saída final do pipeline é um arquivo de texto simples contendo arte ASCII de um personagem dizendo as saudações em maiúsculas. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Escreve cada saudação em seu próprio arquivo de saída (_ex._ "Hello-output.txt") +2. **`convertToUpper`:** Converte cada saudação para maiúsculas (_ex._ "HELLO") +3. **`collectGreetings`:** Coleta todas as saudações em maiúsculas em um único arquivo de lote +4. **`cowpy`:** Gera arte ASCII usando a ferramenta `cowpy` + +A configuração do fluxo de trabalho suporta fornecer entradas e parâmetros de forma flexível e reproduzível. + +### Habilidades adquiridas + +Através deste curso prático, você aprendeu como: + +- Iniciar um fluxo de trabalho Nextflow localmente +- Encontrar e interpretar saídas (resultados) e arquivos de log gerados pelo Nextflow +- Reconhecer os componentes principais do Nextflow que constituem um fluxo de trabalho simples de múltiplas etapas +- Descrever conceitos de próximos passos como operadores e fábricas de canal +- Configurar pipelines para diferentes ambientes de computação + +Você agora está equipado com o conhecimento fundamental para começar a integrar pipelines Nextflow existentes em seu próprio trabalho. + +## Próximos passos para construir suas habilidades + +Aqui estão nossas principais sugestões do que fazer a seguir: + +- Não apenas execute Nextflow, escreva! Torne-se um desenvolvedor Nextflow com [Hello Nextflow](../hello_nextflow/index.md) +- Aplique Nextflow a um caso de uso de análise científica com [Nextflow for Science](../nf4_science/index.md) +- Comece com nf-core com [Hello nf-core](../hello_nf-core/index.md) +- Aprenda técnicas de solução de problemas com a [Side Quest de Debugging](../side_quests/debugging.md) + +Finalmente, recomendamos que você dê uma olhada na [**Seqera Platform**](https://seqera.io/), uma plataforma baseada em nuvem desenvolvida pelos criadores do Nextflow que torna ainda mais fácil lançar e gerenciar seus fluxos de trabalho, bem como gerenciar seus dados e executar análises interativamente em qualquer ambiente. + +## Obtendo ajuda + +Para recursos de ajuda e suporte da comunidade, veja a [página de Ajuda](../help.md). + +## Pesquisa de feedback + +Antes de seguir em frente, por favor tire um minuto para completar a pesquisa do curso! Seu feedback nos ajuda a melhorar nossos materiais de treinamento para todos. + +[Fazer a pesquisa :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/pt/docs/nextflow_run/survey.md b/docs/pt/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..87d75820f1 --- /dev/null +++ b/docs/pt/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Pesquisa de feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de seguir em frente, por favor complete esta breve pesquisa de 5 perguntas para avaliar o treinamento, compartilhar qualquer feedback que você possa ter sobre sua experiência e nos informar o que mais poderíamos fazer para ajudá-lo em sua jornada com Nextflow. + +Isso deve levar menos de um minuto para completar. Obrigado por nos ajudar a melhorar nossos materiais de treinamento para todos! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pt/docs/nf4_science/genomics/00_orientation.md b/docs/pt/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..6f91ec93d4 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Orientação + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +O ambiente de treinamento contém todo o software, código e dados necessários para trabalhar neste curso de treinamento, então você não precisa instalar nada por conta própria. +No entanto, você precisa de uma conta (gratuita) para fazer login, e deve dedicar alguns minutos para se familiarizar com a interface. + +Se você ainda não o fez, por favor siga [este link](../../../envsetup/) antes de prosseguir. + +## Materiais fornecidos + +Ao longo deste curso de treinamento, trabalharemos no diretório `nf4-science/genomics/`, para o qual você precisa se mover quando abrir o workspace de treinamento. +Este diretório contém todos os arquivos de código, dados de teste e arquivos acessórios que você precisará. + +Sinta-se à vontade para explorar o conteúdo deste diretório; a maneira mais fácil de fazer isso é usar o explorador de arquivos no lado esquerdo do workspace de treinamento na interface do VSCode. +Alternativamente, você pode usar o comando `tree`. +Ao longo do curso, usamos a saída do `tree` para representar a estrutura e o conteúdo do diretório de forma legível, às vezes com pequenas modificações para maior clareza. + +Aqui geramos um índice de conteúdo até o segundo nível: + +```bash +tree . -L 2 +``` + +Se você executar isso dentro de `nf4-science/genomics`, você deverá ver a seguinte saída: + +```console title="Conteúdo do diretório" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Nota" + + Não se preocupe se isso parecer muito; vamos passar pelas partes relevantes em cada etapa do curso. + Isso é apenas para dar uma visão geral. + +**Aqui está um resumo do que você deve saber para começar:** + +- **Os arquivos `.nf`** são scripts de fluxo de trabalho que são nomeados com base em qual parte do curso eles são usados. + +- **O arquivo `nextflow.config`** é um arquivo de configuração que define propriedades mínimas do ambiente. + Você pode ignorá-lo por enquanto. + +- **O diretório `data`** contém dados de entrada e recursos relacionados, descritos posteriormente no curso. + +- **O diretório `solutions`** contém arquivos de módulo e configurações de teste que resultam das Partes 3 e 4 do curso. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + +!!!tip "Dica" + + Se por qualquer motivo você sair deste diretório, você sempre pode executar este comando para retornar a ele: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Agora, para começar o curso, clique na seta no canto inferior direito desta página. diff --git a/docs/pt/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/pt/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..0d9768405d --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,1054 @@ +# Parte 1: Chamada de variantes por amostra + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na primeira parte deste curso, mostramos como construir um pipeline simples de chamada de variantes que aplica a chamada de variantes do GATK a amostras individuais de sequenciamento. + +### Visão geral do método + +A chamada de variantes é um método de análise genômica que visa identificar variações em uma sequência genômica em relação a um genoma de referência. +Aqui vamos usar ferramentas e métodos projetados para chamar variantes curtas, _ou seja_, SNPs e indels. + +![Pipeline GATK](img/gatk-pipeline.png) + +Um pipeline completo de chamada de variantes normalmente envolve muitas etapas, incluindo mapeamento para a referência (às vezes chamado de alinhamento genômico) e filtragem e priorização de variantes. +Para simplificar, nesta parte do curso vamos focar apenas na parte de chamada de variantes. + +### Conjunto de dados + +Fornecemos os seguintes dados e recursos relacionados: + +- **Um genoma de referência** consistindo de uma pequena região do cromossomo 20 humano (de hg19/b37) e seus arquivos acessórios (índice e dicionário de sequências). +- **Três amostras de sequenciamento de genoma completo** correspondentes a um trio familiar (mãe, pai e filho), que foram reduzidas a uma pequena fatia de dados no cromossomo 20 para manter os tamanhos de arquivo pequenos. + Estes são dados de sequenciamento Illumina de leitura curta que já foram mapeados para o genoma de referência, fornecidos em formato [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) (Binary Alignment Map, uma versão comprimida de SAM, Sequence Alignment Map). +- **Uma lista de intervalos genômicos**, ou seja, coordenadas no genoma onde nossas amostras têm dados adequados para chamar variantes, fornecida em formato BED. + +### Fluxo de trabalho + +Nesta parte do curso, vamos desenvolver um fluxo de trabalho que faz o seguinte: + +1. Gerar um arquivo de índice para cada arquivo BAM de entrada usando [Samtools](https://www.htslib.org/) +2. Executar o GATK HaplotypeCaller em cada arquivo BAM de entrada para gerar chamadas de variantes por amostra em VCF (Variant Call Format) + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note "Nota" + + Arquivos de índice são uma característica comum dos formatos de arquivo de bioinformática; eles contêm informações sobre a estrutura do arquivo principal que permite que ferramentas como GATK acessem um subconjunto dos dados sem ter que ler o arquivo inteiro. + Isso é importante por causa de quão grandes esses arquivos podem ficar. + +--- + +## 0. Aquecimento: Testar os comandos Samtools e GATK interativamente + +Primeiro queremos experimentar os comandos manualmente antes de tentar envolvê-los em um fluxo de trabalho. +As ferramentas que precisamos (Samtools e GATK) não estão instaladas no ambiente GitHub Codespaces, então vamos usá-las via contêineres (veja [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Nota" + + Certifique-se de estar no diretório `nf4-science/genomics` para que a última parte do caminho mostrado quando você digita `pwd` seja `genomics`. + +### 0.1. Indexar um arquivo BAM de entrada com Samtools + +Vamos baixar um contêiner Samtools, iniciá-lo interativamente e executar o comando `samtools index` em um dos arquivos BAM. + +#### 0.1.1. Baixar o contêiner Samtools + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.1.2. Iniciar o contêiner Samtools interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.1.3. Executar o comando de indexação + +A [documentação do Samtools](https://www.htslib.org/doc/samtools-index.html) nos fornece a linha de comando para executar para indexar um arquivo BAM. + +Só precisamos fornecer o arquivo de entrada; a ferramenta irá gerar automaticamente um nome para a saída adicionando `.bai` ao nome do arquivo de entrada. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Isso deve ser concluído imediatamente, e você deve ver agora um arquivo chamado `reads_mother.bam.bai` no mesmo diretório que o arquivo BAM de entrada original. + +??? abstract "Conteúdo do diretório" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Sair do contêiner Samtools + +```bash +exit +``` + +### 0.2. Chamar variantes com GATK HaplotypeCaller + +Vamos baixar um contêiner GATK, iniciá-lo interativamente e executar o comando `gatk HaplotypeCaller` no arquivo BAM que acabamos de indexar. + +#### 0.2.1. Baixar o contêiner GATK + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.2.2. Iniciar o contêiner GATK interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.2.3. Executar o comando de chamada de variantes + +A [documentação do GATK](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) nos fornece a linha de comando para executar para realizar chamada de variantes em um arquivo BAM. + +Precisamos fornecer o arquivo BAM de entrada (`-I`) assim como o genoma de referência (`-R`), um nome para o arquivo de saída (`-O`) e uma lista de intervalos genômicos para analisar (`-L`). + +No entanto, não precisamos especificar o caminho para o arquivo de índice; a ferramenta irá procurá-lo automaticamente no mesmo diretório, baseado na convenção estabelecida de nomenclatura e colocalização. +O mesmo se aplica aos arquivos acessórios do genoma de referência (arquivos de índice e dicionário de sequências, `*.fai` e `*.dict`). + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +O arquivo de saída `reads_mother.vcf` é criado dentro do seu diretório de trabalho no contêiner, então você não o verá no explorador de arquivos do VS Code a menos que você mude o caminho do arquivo de saída. +No entanto, é um arquivo de teste pequeno, então você pode usar `cat` para abri-lo e visualizar o conteúdo. +Se você rolar até o início do arquivo, encontrará um cabeçalho composto de muitas linhas de metadados, seguido por uma lista de chamadas de variantes, uma por linha. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Cada linha descreve uma possível variante identificada nos dados de sequenciamento da amostra. Para orientação sobre como interpretar o formato VCF, veja [este artigo útil](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/). + +O arquivo VCF de saída é acompanhado por um arquivo de índice chamado `reads_mother.vcf.idx` que foi criado automaticamente pelo GATK. +Ele tem a mesma função que o arquivo de índice BAM, permitir que ferramentas busquem e recuperem subconjuntos de dados sem carregar o arquivo inteiro. + +#### 0.2.4. Sair do contêiner GATK + +```bash +exit +``` + +### Conclusão + +Você sabe como testar os comandos de indexação do Samtools e chamada de variantes do GATK em seus respectivos contêineres. + +### O que vem a seguir? + +Aprender como envolver esses mesmos comandos em um fluxo de trabalho de duas etapas que usa contêineres para executar o trabalho. + +--- + +## 1. Escrever um fluxo de trabalho de etapa única que executa Samtools index em um arquivo BAM + +Fornecemos um arquivo de fluxo de trabalho, `genomics-1.nf`, que delineia as partes principais do fluxo de trabalho. +Ele não é funcional; seu propósito é apenas servir como um esqueleto que você usará para escrever o fluxo de trabalho real. + +### 1.1. Definir o processo de indexação + +Vamos começar escrevendo um processo, que chamaremos de `SAMTOOLS_INDEX`, descrevendo a operação de indexação. + +```groovy title="genomics-1.nf" linenums="9" +/* + * Gerar arquivo de índice BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Você deve reconhecer todas as partes do que aprendeu na Parte 1 & Parte 2 desta série de treinamento. + +Este processo vai exigir que passemos um caminho de arquivo via entrada `input_bam`, então vamos configurar isso em seguida. + +### 1.2. Adicionar uma declaração de parâmetro de entrada + +No topo do arquivo, na seção `Pipeline parameters`, declaramos um parâmetro CLI chamado `reads_bam` e damos a ele um valor padrão. +Dessa forma, podemos ser preguiçosos e não especificar a entrada quando digitarmos o comando para iniciar o pipeline (para fins de desenvolvimento). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Parâmetros do pipeline + */ +params { + // Entrada principal + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Agora temos um processo pronto, assim como um parâmetro para dar a ele uma entrada para executar, então vamos conectar essas coisas juntas. + +!!! note "Nota" + + `${projectDir}` é uma variável embutida do Nextflow que aponta para o diretório onde o script de fluxo de trabalho Nextflow atual (`genomics-1.nf`) está localizado. + + Isso facilita a referência a arquivos, diretórios de dados e outros recursos incluídos no repositório do fluxo de trabalho sem codificar caminhos absolutos. + +### 1.3. Adicionar bloco de fluxo de trabalho para executar SAMTOOLS_INDEX + +No bloco `workflow`, precisamos configurar um **canal** para alimentar a entrada do processo `SAMTOOLS_INDEX`; então podemos chamar o próprio processo para executar no conteúdo desse canal. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Criar canal de entrada (arquivo único via parâmetro CLI) + reads_ch = channel.fromPath(params.reads_bam) + + // Criar arquivo de índice para arquivo BAM de entrada + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +O bloco workflow tem duas seções: + +- `main:` contém as operações de canal e chamadas de processo +- `publish:` declara quais saídas devem ser publicadas, atribuindo-as a alvos nomeados + +Você notará que estamos usando a mesma factory de canal `.fromPath` que usamos em [Hello Channels](../../hello_nextflow/02_hello_channels.md). +De fato, estamos fazendo algo muito similar. +A diferença é que estamos dizendo ao Nextflow para apenas carregar o próprio caminho do arquivo no canal como um elemento de entrada, em vez de ler seu conteúdo. + +### 1.4. Adicionar um bloco de saída para definir onde os resultados são publicados + +Após o bloco workflow, adicionamos um bloco `output` que especifica onde publicar as saídas do fluxo de trabalho. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +Cada alvo nomeado da seção `publish:` (como `bam_index`) recebe seu próprio bloco onde você pode configurar o caminho de saída relativo ao diretório de saída base. + +!!! note "Nota" + + Embora os arquivos de dados que estamos usando aqui sejam muito pequenos, em genômica eles podem ficar muito grandes. + Por padrão, o Nextflow cria links simbólicos para os arquivos de saída no diretório de publicação, o que evita cópias de arquivos desnecessárias. + Você pode mudar esse comportamento usando a opção `mode` (por exemplo, `mode 'copy'`) para criar cópias reais. + Esteja ciente de que os links simbólicos quebrarão quando você limpar seu diretório `work`, então para fluxos de trabalho de produção você pode querer usar `mode 'copy'`. + +### 1.5. Configurar o diretório de saída + +O diretório de saída base é definido via opção de configuração `outputDir`. Adicione-o ao `nextflow.config`: + +=== "Depois" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Antes" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Executar o fluxo de trabalho para verificar que a etapa de indexação funciona + +Vamos executar o fluxo de trabalho! Como lembrete, não precisamos especificar uma entrada na linha de comando porque configuramos um valor padrão para a entrada quando declaramos o parâmetro de entrada. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Você pode verificar que o arquivo de índice foi gerado corretamente olhando no diretório de trabalho ou no diretório de resultados. + +??? abstract "Conteúdo do diretório de trabalho" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Conteúdo do diretório de resultados" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +Lá está! + +### Conclusão + +Você sabe como envolver uma ferramenta de genômica em um fluxo de trabalho Nextflow de etapa única e fazê-la executar usando um contêiner. + +### O que vem a seguir? + +Adicionar uma segunda etapa que consome a saída da primeira. + +--- + +## 2. Adicionar um segundo processo para executar GATK HaplotypeCaller no arquivo BAM indexado + +Agora que temos um índice para nosso arquivo de entrada, podemos passar para configurar a etapa de chamada de variantes, que é a parte interessante do fluxo de trabalho. + +### 2.1. Definir o processo de chamada de variantes + +Vamos escrever um processo, que chamaremos de `GATK_HAPLOTYPECALLER`, descrevendo a operação de chamada de variantes. + +```groovy title="genomics-1.nf" linenums="44" +/* + * Chamar variantes com GATK HaplotypeCaller + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Você notará que introduzimos uma nova sintaxe aqui (`emit:`) para nomear exclusivamente cada um dos nossos canais de saída, e as razões para isso ficarão claras em breve. + +Este comando recebe muito mais entradas, porque o GATK precisa de mais informações para realizar a análise em comparação com um trabalho simples de indexação. +Mas você notará que existem ainda mais entradas definidas no bloco de entradas do que as listadas no comando GATK. Por quê? + +!!! note "Nota" + + O GATK sabe procurar o arquivo de índice BAM e os arquivos acessórios do genoma de referência porque está ciente das convenções em torno desses arquivos. + No entanto, o Nextflow é projetado para ser independente de domínio e não sabe nada sobre requisitos de formato de arquivo de bioinformática. + +Precisamos dizer ao Nextflow explicitamente que ele tem que preparar esses arquivos no diretório de trabalho em tempo de execução; caso contrário, ele não fará isso, e o GATK (corretamente) lançará um erro sobre os arquivos de índice estarem faltando. + +Da mesma forma, temos que listar o arquivo de índice do VCF de saída (o arquivo `"${input_bam}.vcf.idx"`) explicitamente para que o Nextflow saiba rastrear esse arquivo caso seja necessário em etapas subsequentes. + +### 2.2. Adicionar definições para entradas acessórias + +Como nosso novo processo espera um punhado de arquivos adicionais serem fornecidos, configuramos alguns parâmetros CLI para eles na seção `Pipeline parameters`, junto com alguns valores padrão (mesmas razões de antes). + +```groovy title="genomics-1.nf" linenums="8" + // Arquivos acessórios + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Criar variáveis para conter os caminhos dos arquivos acessórios + +Enquanto entradas de dados principais são transmitidas dinamicamente através de canais, existem duas abordagens para lidar com arquivos acessórios. A abordagem recomendada é criar canais explícitos, o que torna o fluxo de dados mais claro e consistente. Alternativamente, a função file() para criar variáveis pode ser usada para casos mais simples, particularmente quando você precisa referenciar o mesmo arquivo em múltiplos processos - embora esteja ciente de que isso ainda cria canais implicitamente. <!-- TODO: Clarificar: isso ainda é necessário com entradas tipadas? --> + +Adicione isso ao bloco workflow (após a criação do `reads_ch`, dentro da seção `main:`): + +```groovy title="genomics-1.nf" linenums="79" + // Carregar os caminhos de arquivo para os arquivos acessórios (referência e intervalos) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Isso tornará os caminhos dos arquivos acessórios disponíveis para fornecer como entrada a quaisquer processos que precisem deles. + +### 2.4. Adicionar uma chamada ao bloco de fluxo de trabalho para executar GATK_HAPLOTYPECALLER + +Agora que temos nosso segundo processo configurado e todas as entradas e arquivos acessórios estão prontos e disponíveis, podemos adicionar uma chamada ao processo `GATK_HAPLOTYPECALLER` no corpo do fluxo de trabalho. + +```groovy title="genomics-1.nf" linenums="88" + // Chamar variantes do arquivo BAM indexado + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Você deve reconhecer a sintaxe `*.out` da Parte 1 desta série de treinamento; estamos dizendo ao Nextflow para pegar a saída do canal por `SAMTOOLS_INDEX` e conectar isso na chamada do processo `GATK_HAPLOTYPECALLER`. + +!!! note "Nota" + + Você notará que as entradas são fornecidas exatamente na mesma ordem na chamada ao processo como estão listadas no bloco de entrada do processo. + No Nextflow, as entradas são posicionais, significando que você _deve_ seguir a mesma ordem; e é claro que tem que haver o mesmo número de elementos. + +### 2.5. Atualizar a seção publish e o bloco de saída + +Precisamos atualizar a seção `publish:` para incluir as saídas VCF, e adicionar alvos correspondentes no bloco `output`. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Executar o fluxo de trabalho para verificar que a etapa de chamada de variantes funciona + +Vamos executar o fluxo de trabalho expandido com `-resume` para que não tenhamos que executar a etapa de indexação novamente. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Agora, se olharmos para a saída do console, vemos os dois processos listados. + +O primeiro processo foi pulado graças ao cache, como esperado, enquanto o segundo processo foi executado por ser novo. + +Você encontrará os arquivos de saída no diretório de resultados (como links simbólicos para o diretório de trabalho). + +??? abstract "Conteúdo do diretório" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +Se você abrir o arquivo VCF, deve ver o mesmo conteúdo do arquivo que você gerou executando o comando GATK diretamente no contêiner. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Esta é a saída que nos importa gerar para cada amostra em nosso estudo. + +### Conclusão + +Você sabe como fazer um fluxo de trabalho básico de duas etapas que faz trabalho de análise real e é capaz de lidar com idiossincrasias de formato de arquivo de genômica como os arquivos acessórios. + +### O que vem a seguir? + +Fazer o fluxo de trabalho lidar com múltiplas amostras em lote. + +--- + +## 3. Adaptar o fluxo de trabalho para executar em um lote de amostras + +É muito bom ter um fluxo de trabalho que pode automatizar o processamento em uma única amostra, mas e se você tiver 1000 amostras? +Você precisa escrever um script bash que percorre todas as suas amostras? + +Não, graças aos céus! Basta fazer um pequeno ajuste no código e o Nextflow cuidará disso para você também. + +### 3.1. Transformar a declaração de parâmetro de entrada em um array listando as três amostras + +Vamos transformar aquele caminho de arquivo padrão na declaração do arquivo BAM de entrada em um array listando caminhos de arquivo para nossas três amostras de teste, na seção `Pipeline parameters`. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (array de três amostras) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note "Nota" + + Ao usar declarações de parâmetros tipadas (como `reads_bam: Path`), você não pode atribuir um valor de array. + Para arrays, omita a anotação de tipo. + +E isso é realmente tudo que precisamos fazer, porque a factory de canal que usamos no corpo do fluxo de trabalho (`.fromPath`) está tão feliz em aceitar múltiplos caminhos de arquivo para carregar no canal de entrada quanto estava em carregar um único. + +!!! note "Nota" + + Normalmente, você não iria querer codificar a lista de amostras no seu arquivo de fluxo de trabalho, mas estamos fazendo isso aqui para manter as coisas simples. + Apresentaremos maneiras mais elegantes de lidar com entradas mais tarde nesta série de treinamento. + +### 3.2. Executar o fluxo de trabalho para verificar que ele executa em todas as três amostras + +Vamos tentar executar o fluxo de trabalho agora que o encanamento está configurado para executar em todas as três amostras de teste. + +```bash +nextflow run genomics-1.nf -resume +``` + +Coisa engraçada: isso _pode funcionar_, OU _pode falhar_. Por exemplo, aqui está uma execução que teve sucesso: + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +Se sua execução de fluxo de trabalho teve sucesso, execute-a novamente até obter um erro como este: + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +Se você olhar para a saída de erro do comando GATK, haverá uma linha como esta: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Bem, isso é estranho, considerando que indexamos explicitamente os arquivos BAM na primeira etapa do fluxo de trabalho. Poderia haver algo errado com o encanamento? + +#### 3.2.1. Verificar os diretórios de trabalho para as chamadas relevantes + +Vamos dar uma olhada dentro do diretório de trabalho para a chamada de processo `GATK_HAPLOTYPECALLER` com falha listada na saída do console. + +??? abstract "Conteúdo do diretório" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Preste atenção particular aos nomes do arquivo BAM e do índice BAM que estão listados neste diretório: `reads_son.bam` e `reads_father.bam.bai`. + +Mas o quê? O Nextflow preparou um arquivo de índice no diretório de trabalho desta chamada de processo, mas é o errado. Como isso pôde acontecer? + +#### 3.2.2. Usar o [operador view()](https://www.nextflow.io/docs/latest/reference/operator.html#view) para inspecionar o conteúdo do canal + +Adicione estas duas linhas no corpo do fluxo de trabalho antes da chamada do processo `GATK_HAPLOTYPER`: + +```groovy title="genomics-1.nf" linenums="84" + // diagnósticos temporários + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Então execute o comando do fluxo de trabalho novamente. + +```bash +nextflow run genomics-1.nf +``` + +Mais uma vez, isso pode ter sucesso ou falhar. Aqui está uma execução bem-sucedida: + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +E aqui está uma com falha: + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Você pode precisar executá-lo várias vezes para que falhe novamente. +Este erro não se reproduzirá consistentemente porque depende de alguma variabilidade nos tempos de execução das chamadas de processo individuais. + +Isso é o que a saída das duas chamadas `.view()` que adicionamos parece para uma execução com falha: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +As primeiras três linhas correspondem ao canal de entrada e a segunda, ao canal de saída. +Você pode ver que os arquivos BAM e arquivos de índice para as três amostras não estão listados na mesma ordem! + +!!! note "Nota" + + Quando você chama um processo Nextflow em um canal contendo múltiplos elementos, o Nextflow tentará paralelizar a execução o máximo possível, e coletará saídas em qualquer ordem que elas se tornem disponíveis. + A consequência é que as saídas correspondentes podem ser coletadas em uma ordem diferente da que as entradas originais foram alimentadas. + +Como escrito atualmente, nosso script de fluxo de trabalho assume que os arquivos de índice sairão da etapa de indexação listados na mesma ordem mãe/pai/filho que as entradas foram dadas. +Mas isso não é garantido ser o caso, que é por que às vezes (embora nem sempre) os arquivos errados são emparelhados na segunda etapa. + +Para corrigir isso, precisamos garantir que os arquivos BAM e seus arquivos de índice viajem juntos através dos canais. + +!!! tip "Dica" + + As instruções `view()` no código do fluxo de trabalho não fazem nada, então não é um problema deixá-las. + No entanto, elas vão poluir sua saída do console, então recomendamos removê-las quando você terminar de resolver o problema. + +### 3.3. Mudar a saída do processo SAMTOOLS_INDEX para uma tupla que mantém o arquivo de entrada e seu índice juntos + +A maneira mais simples de garantir que um arquivo BAM e seu índice permaneçam intimamente associados é empacotá-los juntos em uma tupla saindo da tarefa de índice. + +!!! note "Nota" + + Uma **tupla** é uma lista finita e ordenada de elementos que é comumente usada para retornar múltiplos valores de uma função. Tuplas são particularmente úteis para passar múltiplas entradas ou saídas entre processos enquanto preservam sua associação e ordem. + +Primeiro, vamos mudar a saída do processo `SAMTOOLS_INDEX` para incluir o arquivo BAM em sua declaração de saída. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +Dessa forma, cada arquivo de índice será estreitamente acoplado com seu arquivo BAM original, e a saída geral da etapa de indexação será um único canal contendo pares de arquivos. + +### 3.4. Mudar a entrada para o processo GATK_HAPLOTYPECALLER para ser uma tupla + +Como mudamos a 'forma' da saída do primeiro processo no fluxo de trabalho, precisamos atualizar a definição de entrada do segundo processo para corresponder. + +Especificamente, onde anteriormente declaramos dois caminhos de entrada separados no bloco de entrada do processo `GATK_HAPLOTYPECALLER`, agora declaramos uma única entrada correspondendo à estrutura da tupla emitida por `SAMTOOLS_INDEX`. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +É claro, já que mudamos a forma das entradas que `GATK_HAPLOTYPECALLER` espera, precisamos atualizar a chamada do processo de acordo no corpo do fluxo de trabalho. + +### 3.5. Atualizar a chamada para GATK_HAPLOTYPECALLER no bloco de fluxo de trabalho + +Não precisamos mais fornecer o `reads_ch` original ao processo `GATK_HAPLOTYPECALLER`, já que o arquivo BAM agora está empacotado na saída do canal por `SAMTOOLS_INDEX`. + +Como resultado, podemos simplesmente deletar aquela linha. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +Essa é toda a reconexão necessária para resolver o problema de incompatibilidade de índice. + +### 3.6. Atualizar a seção publish e o bloco de saída para a tupla + +Como `SAMTOOLS_INDEX.out` agora é uma tupla contendo tanto o BAM quanto seu índice, ambos os arquivos serão publicados juntos. +Renomeamos o alvo de `bam_index` para `indexed_bam` para refletir que agora contém ambos os arquivos. + +=== "Depois" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Também precisamos atualizar o bloco output para usar o novo nome de alvo: + +=== "Depois" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Executar o fluxo de trabalho para verificar que funciona corretamente em todas as três amostras sempre + +É claro, a prova está no pudim, então vamos executar o fluxo de trabalho novamente algumas vezes para garantir que isso funcionará de forma confiável daqui para frente. + +```bash +nextflow run genomics-1.nf +``` + +Desta vez (e todas as vezes) tudo deve executar corretamente: + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +O diretório de resultados agora contém tanto arquivos BAM quanto BAI para cada amostra (da tupla), junto com as saídas VCF: + +??? abstract "Conteúdo do diretório de resultados" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +Se você quiser, pode usar `.view()` novamente para espiar como o conteúdo do canal de saída `SAMTOOLS_INDEX` se parece: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Você verá que o canal contém as três tuplas esperadas (caminhos de arquivo truncados para legibilidade). + +```console title="Saída" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Isso será muito mais seguro, daqui para frente. + +### Conclusão + +Você sabe como fazer seu fluxo de trabalho executar em múltiplas amostras (independentemente). + +### O que vem a seguir? + +Facilitar o manuseio de amostras em lote. + +--- + +## 4. Fazer o fluxo de trabalho aceitar um arquivo de texto contendo um lote de arquivos de entrada + +Uma maneira muito comum de fornecer múltiplos arquivos de dados de entrada para um fluxo de trabalho é fazê-lo com um arquivo de texto contendo os caminhos dos arquivos. +Pode ser tão simples quanto um arquivo de texto listando um caminho de arquivo por linha e nada mais, ou o arquivo pode conter metadados adicionais, caso em que é frequentemente chamado de samplesheet. + +Aqui vamos mostrar como fazer o caso simples. + +### 4.1. Examinar o arquivo de texto fornecido listando os caminhos dos arquivos de entrada + +Já fizemos um arquivo de texto listando os caminhos dos arquivos de entrada, chamado `sample_bams.txt`, que você pode encontrar no diretório `data/`. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Como você pode ver, listamos um caminho de arquivo por linha, e eles são caminhos absolutos. + +!!! note "Nota" + + Os arquivos que estamos usando aqui estão apenas no sistema de arquivos local do seu GitHub Codespaces, mas também poderíamos apontar para arquivos em armazenamento na nuvem. + +### 4.2. Atualizar o padrão do parâmetro + +Vamos mudar o valor padrão para nosso parâmetro de entrada `reads_bam` para apontar para o arquivo `sample_bams.txt`. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (arquivo de arquivos de entrada, um por linha) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="7" + // Entrada principal (array de três amostras) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +Dessa forma podemos continuar a ser preguiçosos, mas a lista de arquivos não vive mais no próprio código do fluxo de trabalho, o que é um grande passo na direção certa. + +### 4.3. Atualizar a factory de canal para ler linhas de um arquivo + +Atualmente, nossa factory de canal de entrada trata quaisquer arquivos que demos a ela como as entradas de dados que queremos alimentar ao processo de indexação. +Como agora estamos dando a ela um arquivo que lista caminhos de arquivo de entrada, precisamos mudar seu comportamento para analisar o arquivo e tratar os caminhos de arquivo que ele contém como as entradas de dados. + +Felizmente podemos fazer isso muito simplesmente, apenas adicionando o [operador `.splitText()`](https://www.nextflow.io/docs/latest/reference/operator.html#operator-splittext) à etapa de construção do canal. + +=== "Depois" + + ```groovy title="genomics-1.nf" linenums="68" + // Criar canal de entrada de um arquivo de texto listando caminhos de arquivo de entrada + reads_ch = channel.fromPath(params.reads_bam).splitText() + ``` + +=== "Antes" + + ```groovy title="genomics-1.nf" linenums="68" + // Criar canal de entrada (arquivo único via parâmetro CLI) + reads_ch = channel.fromPath(params.reads_bam) + ``` + +!!! tip "Dica" + + Esta é outra ótima oportunidade para usar o operador `.view()` para ver como o conteúdo do canal se parece antes e depois de aplicar um operador. + +### 4.4. Executar o fluxo de trabalho para verificar que funciona corretamente + +Vamos executar o fluxo de trabalho mais uma vez. Isso deve produzir o mesmo resultado de antes, certo? + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [sick_albattani] DSL2 - revision: 46d84642f6 + + [18/23b4bb] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [12/f727bb] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + ``` + +Sim! Na verdade, o Nextflow detecta corretamente que as chamadas de processo são exatamente as mesmas, e nem se preocupa em executar tudo novamente, já que estávamos executando com `-resume`. + +E é isso! Nosso fluxo de trabalho simples de chamada de variantes tem todas as características básicas que queríamos. + +### Conclusão + +Você sabe como fazer um fluxo de trabalho linear de múltiplas etapas para indexar um arquivo BAM e aplicar chamada de variantes por amostra usando GATK. + +De forma mais geral, você aprendeu como usar componentes e lógica essenciais do Nextflow para construir um pipeline de genômica simples que faz trabalho real, levando em conta as idiossincrasias dos formatos de arquivo de genômica e requisitos de ferramentas. + +### O que vem a seguir? + +Celebre seu sucesso e faça uma pausa extra longa! + +Na próxima parte deste curso, você aprenderá como usar alguns recursos adicionais do Nextflow (incluindo mais operadores de canal) para aplicar chamada conjunta de variantes aos dados. diff --git a/docs/pt/docs/nf4_science/genomics/02_joint_calling.md b/docs/pt/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..3997bcaaa4 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1026 @@ +# Parte 2: Chamada conjunta em uma coorte + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na primeira parte deste curso, você construiu um pipeline de chamada de variantes que era completamente linear e processava os dados de cada amostra independentemente das outras. +No entanto, em um caso de uso real de genômica, você normalmente precisará examinar as chamadas de variantes de múltiplas amostras em conjunto. + +Nesta segunda parte, mostramos como usar canais e operadores de canal para implementar a chamada conjunta de variantes com GATK, construindo sobre o pipeline da Parte 1. + +### Visão geral do método + +O método de chamada de variantes do GATK que usamos na primeira parte deste curso simplesmente gerou chamadas de variantes por amostra. +Isso é adequado se você quiser apenas examinar as variantes de cada amostra isoladamente, mas isso fornece informações limitadas. +Frequentemente é mais interessante examinar como as chamadas de variantes diferem entre múltiplas amostras, e para fazer isso, o GATK oferece um método alternativo chamado chamada conjunta de variantes, que demonstramos aqui. + +A chamada conjunta de variantes envolve gerar um tipo especial de saída de variantes chamado GVCF (Genomic VCF) para cada amostra, depois combinar os dados GVCF de todas as amostras e, finalmente, executar uma análise estatística de 'genotipagem conjunta'. + +![Análise conjunta](img/joint-calling.png) + +O que é especial sobre o GVCF de uma amostra é que ele contém registros resumindo estatísticas de dados de sequência sobre todas as posições na área alvo do genoma, não apenas as posições onde o programa encontrou evidências de variação. +Isso é crítico para o cálculo de genotipagem conjunta ([leitura adicional](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +O GVCF é produzido pelo GATK HaplotypeCaller, a mesma ferramenta que usamos na Parte 1, com um parâmetro adicional (`-ERC GVCF`). +A combinação dos GVCFs é feita com GATK GenomicsDBImport, que combina as chamadas por amostra em um armazenamento de dados (análogo a um banco de dados), então a análise de 'genotipagem conjunta' propriamente dita é feita com GATK GenotypeGVCFs. + +### Fluxo de trabalho + +Então, para recapitular, nesta parte do curso, vamos desenvolver um fluxo de trabalho que faz o seguinte: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Gerar um arquivo de índice para cada arquivo BAM de entrada usando Samtools +2. Executar o GATK HaplotypeCaller em cada arquivo BAM de entrada para gerar um GVCF de chamadas de variantes genômicas por amostra +3. Coletar todos os GVCFs e combiná-los em um armazenamento de dados GenomicsDB +4. Executar genotipagem conjunta nos dados GVCF combinados para produzir um VCF em nível de coorte + +Vamos aplicar isso ao mesmo conjunto de dados da Parte 1. + +--- + +## 0. Aquecimento: Execute Samtools e GATK diretamente + +Assim como anteriormente, queremos testar os comandos manualmente antes de tentar envolvê-los em um fluxo de trabalho. + +!!! note + + Certifique-se de estar no diretório de trabalho correto: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Indexar um arquivo BAM de entrada com Samtools + +Este primeiro passo é o mesmo da Parte 1, então deve parecer muito familiar, mas desta vez precisamos fazer isso para todas as três amostras. + +!!! note + + Tecnicamente já geramos arquivos de índice para as três amostras através do nosso pipeline, então poderíamos ir buscá-los no diretório de resultados. No entanto, é mais limpo apenas refazer isso manualmente, e levará apenas um minuto. + +#### 0.1.1. Iniciar o contêiner Samtools interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.1.2. Executar o comando de indexação para as três amostras + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Assim como anteriormente, isso deve produzir os arquivos de índice no mesmo diretório que os arquivos BAM correspondentes. + +??? abstract "Conteúdo do diretório" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Agora que temos arquivos de índice para todas as três amostras, podemos prosseguir para gerar os GVCFs para cada uma delas. + +#### 0.1.3. Sair do contêiner Samtools + +```bash +exit +``` + +### 0.2. Chamar variantes com GATK HaplotypeCaller em modo GVCF + +Este segundo passo é muito similar ao que fizemos na Parte 1: Hello Genomics, mas agora vamos executar o GATK em 'modo GVCF'. + +#### 0.2.1. Iniciar o contêiner GATK interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +#### 0.2.2. Executar o comando de chamada de variantes com a opção GVCF + +Para produzir um VCF genômico (GVCF), adicionamos a opção `-ERC GVCF` ao comando base, que ativa o modo GVCF do HaplotypeCaller. + +Também mudamos a extensão do arquivo de saída de `.vcf` para `.g.vcf`. +Tecnicamente isso não é um requisito, mas é uma convenção fortemente recomendada. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +Isso cria o arquivo de saída GVCF `reads_mother.g.vcf` no diretório de trabalho atual no contêiner. + +Se você usar `cat` para visualizar o conteúdo, verá que é muito mais longo do que o VCF equivalente que geramos na Parte 1. Você nem consegue rolar até o início do arquivo, e a maioria das linhas parece bem diferente do que vimos no VCF na Parte 1. + +```console title="Saída" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Estas representam regiões não variantes onde o chamador de variantes não encontrou evidências de variação, então ele capturou algumas estatísticas descrevendo seu nível de confiança na ausência de variação. Isso torna possível distinguir entre dois casos muito diferentes: (1) há dados de boa qualidade mostrando que a amostra é homozigota-referência, e (2) não há dados bons suficientes disponíveis para fazer uma determinação de qualquer maneira. + +Em um GVCF, normalmente há muitas dessas linhas não variantes, com um número menor de registros variantes espalhados entre elas. Tente executar `head -176` no GVCF para carregar apenas as primeiras 176 linhas do arquivo para encontrar uma chamada de variante real. + +```console title="Saída" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +A segunda linha mostra o primeiro registro variante no arquivo, que corresponde à primeira variante no arquivo VCF que examinamos na Parte 1. + +Assim como o VCF original, o arquivo de saída GVCF também é acompanhado por um arquivo de índice, chamado `reads_mother.g.vcf.idx`. + +#### 0.2.3. Repetir o processo nas outras duas amostras + +Para testar a etapa de genotipagem conjunta, precisamos de GVCFs para todas as três amostras, então vamos gerar esses manualmente agora. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +Uma vez que isso seja concluído, você deve ter três arquivos terminando em `.g.vcf` no seu diretório atual (um por amostra) e seus respectivos arquivos de índice terminando em `.g.vcf.idx`. + +### 0.3. Executar genotipagem conjunta + +Agora que temos todos os GVCFs, podemos finalmente testar a abordagem de genotipagem conjunta para gerar chamadas de variantes para uma coorte de amostras. +Como lembrete, é um método de duas etapas que consiste em combinar os dados de todos os GVCFs em um armazenamento de dados, e então executar a análise de genotipagem conjunta propriamente dita para gerar o VCF final de variantes chamadas conjuntamente. + +#### 0.3.1. Combinar todos os GVCFs por amostra + +Esta primeira etapa usa outra ferramenta GATK, chamada GenomicsDBImport, para combinar os dados de todos os GVCFs em um armazenamento de dados GenomicsDB. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +A saída desta etapa é efetivamente um diretório contendo um conjunto de diretórios ainda mais aninhados contendo os dados de variantes combinados na forma de múltiplos arquivos diferentes. +Você pode explorar, mas rapidamente verá que este formato de armazenamento de dados não é destinado a ser lido diretamente por humanos. + +!!! note + + GATK inclui ferramentas que tornam possível inspecionar e extrair dados de chamadas de variantes do armazenamento de dados conforme necessário. + +#### 0.3.2. Executar a análise de genotipagem conjunta propriamente dita + +Esta segunda etapa usa ainda outra ferramenta GATK, chamada GenotypeGVCFs, para recalcular estatísticas de variantes e genótipos individuais à luz dos dados disponíveis em todas as amostras da coorte. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +Isso cria o arquivo de saída VCF `family_trio.vcf` no diretório de trabalho atual no contêiner. +É outro arquivo razoavelmente pequeno, então você pode usar `cat` neste arquivo para ver seu conteúdo, e rolar para cima para encontrar as primeiras linhas de variantes. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Isso se parece mais com o VCF original que geramos na Parte 1, exceto que desta vez temos informações em nível de genótipo para todas as três amostras. +As últimas três colunas no arquivo são os blocos de genótipos para as amostras, listadas em ordem alfabética. + +Se olharmos para os genótipos chamados para nosso trio familiar de teste para a primeira variante, vemos que o pai é heterozigoto-variante (`0/1`), e a mãe e o filho são ambos homozigotos-variante (`1/1`). + +Essa é, em última análise, a informação que estamos procurando extrair do conjunto de dados! Então vamos envolver tudo isso em um fluxo de trabalho Nextflow para que possamos fazer isso em escala. + +#### 0.3.3. Sair do contêiner GATK + +```bash +exit +``` + +### Conclusão + +Você sabe como executar os comandos individuais envolvidos na chamada conjunta de variantes no terminal para verificar que eles produzirão as informações que você deseja. + +### O que vem a seguir? + +Envolver esses comandos em um pipeline real. + +--- + +## 1. Modificar a etapa de chamada de variantes por amostra para produzir um GVCF + +A boa notícia é que não precisamos começar tudo de novo, já que já escrevemos um fluxo de trabalho que faz parte desse trabalho na Parte 1. +No entanto, esse pipeline produz arquivos VCF, enquanto agora queremos arquivos GVCF para fazer a genotipagem conjunta. +Então precisamos começar ativando o modo de chamada de variantes GVCF e atualizando a extensão do arquivo de saída. + +!!! note + + Por conveniência, vamos trabalhar com uma cópia nova do fluxo de trabalho GATK como está no final da Parte 1, mas sob um nome diferente: `genomics-2.nf`. + +### 1.1. Dizer ao HaplotypeCaller para emitir um GVCF e atualizar a extensão de saída + +Vamos abrir o arquivo `genomics-2.nf` no editor de código. +Ele deve parecer muito familiar, mas sinta-se à vontade para executá-lo se quiser se convencer de que ele funciona como esperado. + +Vamos começar fazendo duas mudanças: + +- Adicionar o parâmetro `-ERC GVCF` ao comando GATK HaplotypeCaller; +- Atualizar o caminho do arquivo de saída para usar a extensão correspondente `.g.vcf`, conforme convenção do GATK. + +Certifique-se de adicionar uma barra invertida (`\`) no final da linha anterior quando adicionar `-ERC GVCF`. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +E isso é tudo que é necessário para fazer o HaplotypeCaller gerar GVCFs em vez de VCFs, certo? + +### 1.2. Executar o pipeline para verificar que você pode gerar GVCFs + +O comando de execução Nextflow é o mesmo de antes, exceto pelo próprio nome do arquivo de fluxo de trabalho. +Certifique-se de atualizar isso apropriadamente. + +```bash +nextflow run genomics-2.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +E a saída é... toda vermelha! Oh não. + +O comando que foi executado está correto, então estávamos certos de que isso era suficiente para mudar o comportamento da ferramenta GATK. +Mas olhe aquela linha sobre o arquivo de saída ausente. Nota algo? + +Isso mesmo, esquecemos de dizer ao Nextflow para esperar um novo nome de arquivo. Ops. + +### 1.3. Atualizar a extensão do arquivo de saída no bloco de saídas do processo também + +Porque não é suficiente apenas mudar a extensão do arquivo no próprio comando da ferramenta, você também precisa dizer ao Nextflow que o nome do arquivo de saída esperado mudou. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Atualizar os alvos de publicação para as novas saídas GVCF + +Já que agora estamos produzindo GVCFs em vez de VCFs, devemos atualizar a seção `publish:` do fluxo de trabalho para usar nomes mais descritivos. +Também vamos organizar os arquivos GVCF em seu próprio subdiretório para maior clareza. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Atualizar o bloco de saída para a nova estrutura de diretório + +Também precisamos atualizar o bloco `output` para colocar os arquivos GVCF em um subdiretório `gvcf`. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Executar o pipeline novamente + +Vamos executá-lo com `-resume` desta vez. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Desta vez funciona. + +A própria saída do Nextflow não parece diferente (comparada a uma execução bem-sucedida no modo VCF normal), mas agora podemos encontrar os arquivos `.g.vcf` e seus respectivos arquivos de índice, para todas as três amostras, organizados em subdiretórios. + +??? abstract "Conteúdo do diretório (symlinks encurtados)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Se você abrir um dos arquivos GVCF e percorrer por ele, poderá verificar que o GATK HaplotypeCaller produziu arquivos GVCF conforme solicitado. + +### Conclusão + +Ok, esta foi mínima em termos de aprendizado de Nextflow... +Mas foi uma boa oportunidade para reiterar a importância do bloco de saída do processo! + +### O que vem a seguir? + +Aprender a coletar o conteúdo de um canal e passá-los para o próximo processo como uma única entrada. + +--- + +## 2. Coletar e combinar os dados GVCF em todas as amostras + +Agora precisamos combinar os dados de todos os GVCFs por amostra em uma forma que suporte a análise de genotipagem conjunta que queremos fazer. + +### 2.1. Definir o processo que vai combinar os GVCFs + +Como lembrete do que fizemos anteriormente na seção de aquecimento, combinar os GVCFs é um trabalho para a ferramenta GATK GenomicsDBImport, que produzirá um armazenamento de dados no chamado formato GenomicsDB. + +Vamos escrever um novo processo para definir como isso vai funcionar, baseado no comando que usamos anteriormente na seção de aquecimento. + +```groovy title="genomics-2.nf" linenums="66" +/* + * Combinar GVCFs em armazenamento de dados GenomicsDB + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +O que você acha, parece razoável? + +Vamos conectá-lo e ver o que acontece. + +### 2.2. Adicionar um parâmetro `cohort_name` com um valor padrão + +Precisamos fornecer um nome arbitrário para a coorte. +Mais tarde na série de treinamento você aprenderá como usar metadados de amostra para esse tipo de coisa, mas por enquanto apenas declaramos um parâmetro CLI usando `params` e damos a ele um valor padrão por conveniência. + +```groovy title="genomics-2.nf" linenums="16" + // Nome base para o arquivo de saída final + cohort_name: String = "family_trio" +``` + +### 2.3. Reunir as saídas de GATK_HAPLOTYPECALLER entre amostras + +Se fôssemos apenas conectar o canal de saída do processo `GATK_HAPLOTYPECALLER` como está, o Nextflow chamaria o processo em cada GVCF de amostra separadamente. +No entanto, queremos agrupar todos os três GVCFs (e seus arquivos de índice) de forma que o Nextflow entregue todos eles juntos a uma única chamada de processo. + +Boas notícias: podemos fazer isso usando o operador de canal `collect()`. Vamos adicionar as seguintes linhas ao corpo do `workflow`, logo após a chamada a GATK_HAPLOTYPECALLER: + +```groovy title="genomics-2.nf" linenums="118" +// Coletar saídas de chamada de variantes entre amostras +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Isso parece um pouco complicado? Vamos quebrar isso e traduzir para linguagem simples. + +1. Estamos pegando o canal de saída do processo `GATK_HAPLOTYPECALLER`, referenciado usando a propriedade `.out`. +2. Cada 'elemento' saindo do canal é um par de arquivos: o GVCF e seu arquivo de índice, nessa ordem porque essa é a ordem em que estão listados no bloco de saída do processo. Convenientemente, porque na última sessão nomeamos as saídas deste processo (usando `emit:`), podemos selecionar os GVCFs por um lado adicionando `.vcf` e os arquivos de índice por outro adicionando `.idx` após a propriedade `.out`. Se não tivéssemos nomeado essas saídas, teríamos que nos referir a elas por `.out[0]` e `.out[1]`, respectivamente. +3. Anexamos o operador de canal `collect()` para agrupar todos os arquivos GVCF juntos em um único elemento em um novo canal chamado `all_gvcfs_ch`, e fazemos o mesmo com os arquivos de índice para formar o novo canal chamado `all_idxs_ch`. + +!!! tip + + Se você está tendo dificuldade em visualizar exatamente o que está acontecendo aqui, lembre-se de que você pode usar o operador `view()` para inspecionar o conteúdo dos canais antes e depois de aplicar operadores de canal. + +Os canais resultantes `all_gvcfs_ch` e `all_idxs_ch` são o que vamos conectar ao processo `GATK_GENOMICSDB` que acabamos de escrever. + +!!! note + + Caso você estivesse se perguntando, coletamos os GVCFs e seus arquivos de índice separadamente porque o comando GATK GenomicsDBImport só quer ver os caminhos dos arquivos GVCF. Felizmente, já que o Nextflow vai organizar todos os arquivos juntos para execução, não precisamos nos preocupar com a ordem dos arquivos como fizemos para BAMs e seus índices na Parte 1. + +### 2.4. Adicionar uma chamada ao bloco de fluxo de trabalho para executar GATK_GENOMICSDB + +Temos um processo, e temos canais de entrada. Só precisamos adicionar a chamada do processo. + +```groovy title="genomics-2.nf" linenums="122" + // Combinar GVCFs em um armazenamento de dados GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Ok, tudo está conectado. + +### 2.5. Executar o fluxo de trabalho + +Vamos ver se isso funciona. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +Ele executa razoavelmente rápido, já que estamos executando com `-resume`, mas falha! + +Ah. Pelo lado positivo, vemos que o Nextflow pegou o processo `GATK_GENOMICSDB`, e especificamente o chamou apenas uma vez. +Isso sugere que a abordagem `collect()` funcionou, até certo ponto. +Mas, e é um grande mas, a chamada do processo falhou. + +Quando investigamos a saída do console acima, podemos ver que o comando executado não está correto. + +Você consegue identificar o erro? +Olhe para este pedaço: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +Demos ao `gatk GenomicsDBImport` múltiplos arquivos GVCF para um único argumento `-V`, mas a ferramenta espera um argumento `-V` separado para cada arquivo GVCF. + +Como lembrete, este foi o comando que executamos no contêiner: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Então isso significa que precisamos de alguma forma transformar nosso pacote de arquivos GVCF em uma string de comando formatada adequadamente. + +### 2.6. Construir uma linha de comando com um argumento `-V` separado para cada GVCF de entrada + +É aqui que o Nextflow ser baseado em Groovy é útil, porque vai nos permitir usar algumas manipulações de string bastante diretas para construir a string de comando necessária. + +Especificamente, usando esta sintaxe: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Mais uma vez, vamos quebrar isso em seus componentes. + +1. Primeiro, pegamos o conteúdo do canal de entrada `all_gvcfs` e aplicamos `.collect()` nele (assim como antes). +2. Isso nos permite passar cada caminho de arquivo GVCF individual no pacote para o **closure**, `{ gvcf -> "-V ${gvcf}" }`, onde `gvcf` se refere a esse caminho de arquivo GVCF. + O closure é uma mini-função que usamos para prefixar `-V ` ao caminho do arquivo, na forma de `"-V ${gvcf}"`. +3. Então usamos `.join(' ')` para concatenar todas as três strings com um único espaço como separador. + +Com um exemplo concreto, fica assim: + +1. Temos três arquivos: + + `[A.ext, B.ext, C.ext]` + +2. O closure modifica cada um para criar as strings: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. A operação `.join(' ')` gera a string final: + + `"-V A.ext -V B.ext -V C.ext"` + +Uma vez que temos essa string, podemos atribuí-la a uma variável local, `gvcfs_line`, definida com a palavra-chave `def`: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Ok, então temos nossa coisinha de manipulação de string. Onde a colocamos? + +Queremos que isso vá dentro da definição do processo em algum lugar, porque queremos fazer isso _depois_ que canalizamos os caminhos dos arquivos GVCF para o processo. +Isso é porque o Nextflow deve vê-los como caminhos de arquivo para organizar os próprios arquivos corretamente para execução. + +Mas _onde_ no processo podemos adicionar isso? + +Fato curioso: você pode adicionar código arbitrário depois de `script:` e antes do `"""` ! + +Ótimo, vamos adicionar nossa linha de manipulação de string lá então, e atualizar o comando `gatk GenomicsDBImport` para usar a string concatenada que ela produz. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Isso deve ser tudo que é necessário para fornecer as entradas ao `gatk GenomicsDBImport` corretamente. + +!!! tip + + Quando você atualizar o comando `gatk GenomicsDBImport`, certifique-se de remover o prefixo `-V ` quando você trocar pela variável `${gvcfs_line}`. + +### 2.7. Executar o fluxo de trabalho para verificar que ele gera a saída GenomicsDB conforme esperado + +Certo, vamos ver se isso resolveu o problema. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha! Parece estar funcionando agora. + +As duas primeiras etapas foram puladas com sucesso, e a terceira etapa funcionou perfeitamente desta vez. +O armazenamento de dados GenomicsDB é criado no diretório de trabalho mas não publicado em resultados, já que é apenas um formato intermediário que usaremos para genotipagem conjunta. + +A propósito, não tivemos que fazer nada especial para lidar com a saída sendo um diretório em vez de um único arquivo. + +### Conclusão + +Agora você sabe como coletar saídas de um canal e agrupá-las como uma única entrada para outro processo. +Você também sabe como construir uma linha de comando para fornecer entradas a uma determinada ferramenta com a sintaxe apropriada. + +### O que vem a seguir? + +Aprender como adicionar um segundo comando ao mesmo processo. + +--- + +## 3. Executar a etapa de genotipagem conjunta como parte do mesmo processo + +Agora que temos as chamadas de variantes genômicas combinadas, podemos executar a ferramenta de genotipagem conjunta, que produzirá a saída final que realmente nos interessa: o VCF de chamadas de variantes em nível de coorte. + +Por razões logísticas, decidimos incluir a genotipagem conjunta dentro do mesmo processo. + +### 3.1. Renomear o processo de GATK_GENOMICSDB para GATK_JOINTGENOTYPING + +Como o processo estará executando mais de uma ferramenta, mudamos seu nome para referir-se à operação geral em vez de um único nome de ferramenta. + +=== "Depois" + + ```groovy title="genomics-2.nf" + /* + * Combinar GVCFs em armazenamento de dados GenomicsDB e executar genotipagem conjunta para produzir chamadas em nível de coorte + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" + /* + * Combinar GVCFs em armazenamento de dados GenomicsDB + */ + process GATK_GENOMICSDB { + ``` + +Lembre-se de manter seus nomes de processo o mais descritivos possível, para maximizar a legibilidade para seus colegas —e seu eu futuro! + +### 3.2. Adicionar o comando de genotipagem conjunta ao processo GATK_JOINTGENOTYPING + +Simplesmente adicione o segundo comando após o primeiro dentro da seção de script. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Os dois comandos serão executados em série, da mesma forma que seriam se os executássemos manualmente no terminal. + +### 3.3. Adicionar os arquivos do genoma de referência às definições de entrada do processo GATK_JOINTGENOTYPING + +O segundo comando requer os arquivos do genoma de referência, então precisamos adicioná-los às entradas do processo. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Pode parecer irritante digitar isso tudo, mas lembre-se, você só digita uma vez, e então pode executar o fluxo de trabalho um milhão de vezes. Vale a pena? + +### 3.4. Atualizar a definição de saída do processo para emitir o VCF de chamadas de variantes em nível de coorte + +Realmente não nos importamos em salvar o armazenamento de dados GenomicsDB, que é apenas um formato intermediário que só existe por razões logísticas, então podemos simplesmente removê-lo do bloco de saída se quisermos. + +A saída que realmente nos interessa é o VCF produzido pelo comando de genotipagem conjunta. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Estamos quase terminando! + +### 3.5. Atualizar a chamada do processo de GATK_GENOMICSDB para GATK_JOINTGENOTYPING + +Não vamos esquecer de renomear a chamada do processo no corpo do fluxo de trabalho de GATK_GENOMICSDB para GATK_JOINTGENOTYPING. E já que estamos nisso, também devemos adicionar os arquivos do genoma de referência como entradas, já que precisamos fornecê-los à ferramenta de genotipagem conjunta. + +=== "Depois" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinar GVCFs em um armazenamento de dados GenomicsDB e aplicar genotipagem conjunta + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Antes" + + ```groovy title="genomics-2.nf" linenums="126" + // Combinar GVCFs em um armazenamento de dados GenomicsDB + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Agora o processo está completamente conectado. + +### 3.6. Adicionar o VCF conjunto à seção de publicação + +Precisamos publicar as saídas do VCF conjunto do novo processo. +Adicione estas linhas à seção `publish:` do fluxo de trabalho: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Adicionar os alvos do VCF conjunto ao bloco de saída + +Finalmente, adicione alvos de saída para os arquivos VCF conjunto. +Vamos colocá-los na raiz do diretório de resultados já que esta é a saída final. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Agora tudo deve estar completamente conectado. + +### 3.8. Executar o fluxo de trabalho + +Finalmente, podemos executar o fluxo de trabalho modificado... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +E funciona! + +Você encontrará o arquivo de saída final, `family_trio.joint.vcf` (e seu índice de arquivo), no diretório de resultados. + +??? abstract "Conteúdo do diretório (symlinks encurtados)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Se você é do tipo cético, pode clicar no arquivo VCF conjunto para abri-lo e verificar que o fluxo de trabalho gerou as mesmas chamadas de variantes que você obteve executando as ferramentas manualmente no início desta seção. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Agora você tem um fluxo de trabalho de chamada conjunta de variantes automatizado e totalmente reproduzível! + +!!! note + + Tenha em mente que os arquivos de dados que fornecemos a você cobrem apenas uma pequena porção do cromossomo 20. + O tamanho real de um conjunto de chamadas de variantes seria contado em milhões de variantes. + É por isso que usamos apenas pequenos subconjuntos de dados para fins de treinamento! + +### Conclusão + +Você sabe como usar alguns operadores comuns, bem como closures Groovy, para controlar o fluxo de dados em seu fluxo de trabalho. + +### O que vem a seguir? + +Celebre seu sucesso e faça uma pausa bem merecida. + +Na próxima parte deste curso, você aprenderá como modularizar seu fluxo de trabalho extraindo definições de processo em módulos reutilizáveis. diff --git a/docs/pt/docs/nf4_science/genomics/03_modules.md b/docs/pt/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..d997b22dc3 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Parte 3: Movendo código para módulos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na primeira parte deste curso, você construiu um pipeline de chamada de variantes que era completamente linear e processava os dados de cada amostra independentemente das outras. + +Na segunda parte, mostramos como usar canais e operadores de canal para implementar chamada conjunta de variantes com GATK, construindo sobre o pipeline da Parte 1. + +Nesta parte, mostraremos como converter o código desse fluxo de trabalho em módulos. Para acompanhar esta parte do treinamento, você deve ter completado a Parte 1 e a Parte 2, assim como [Hello Modules](../../../hello_nextflow/hello_modules.md), que cobre os fundamentos de módulos. + +--- + +## 0. Aquecimento + +Quando começamos a desenvolver nosso fluxo de trabalho, colocamos tudo em um único arquivo de código. +Agora é hora de abordar a **modularização** do nosso código, _ou seja_, extrair as definições de processo em módulos. + +Vamos começar com o mesmo fluxo de trabalho da Parte 2, que fornecemos para você no arquivo `genomics-3.nf`. + +!!! note "Nota" + + Certifique-se de estar no diretório de trabalho correto: + `cd /workspaces/training/nf4-science/genomics` + +Execute o fluxo de trabalho para verificar o ponto de partida: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Saída" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Agora haverá um diretório `work` e um diretório `results_genomics` dentro do seu diretório do projeto. + +### Conclusão + +Você está pronto para começar a modularizar seu fluxo de trabalho. + +### Qual é o próximo passo? + +Mover os processos do fluxo de trabalho de Genômica para módulos. + +--- + +## 1. Mover processos para módulos + +Como você aprendeu em [Hello Modules](../../../hello_nextflow/hello_modules.md), você pode criar um módulo simplesmente copiando a definição do processo para seu próprio arquivo, em qualquer diretório, e pode nomear esse arquivo como quiser. + +Por razões que ficarão claras mais tarde (em particular quando chegarmos aos testes), neste treinamento seguiremos a convenção de nomear o arquivo como `main.nf`, e colocá-lo em uma estrutura de diretórios nomeada após o kit de ferramentas e o comando. + +### 1.1. Criar um módulo para o processo `SAMTOOLS_INDEX` + +No caso do processo `SAMTOOLS_INDEX`, 'samtools' é o kit de ferramentas e 'index' é o comando. Então, criaremos uma estrutura de diretórios `modules/samtools/index` e colocaremos a definição do processo `SAMTOOLS_INDEX` no arquivo `main.nf` dentro desse diretório. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +Abra o arquivo `main.nf` e copie a definição do processo `SAMTOOLS_INDEX` para ele. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * Gerar arquivo de índice BAM + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Então, remova a definição do processo `SAMTOOLS_INDEX` de `genomics-3.nf`, e adicione uma declaração de importação para o módulo antes da próxima definição de processo, assim: + +=== "Depois" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Incluir módulos + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * Chamar variantes com GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Antes" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * Chamar variantes com GATK HaplotypeCaller + */ + process GATK_HAPLOTYPECALLER { + ``` + +Agora você pode executar o fluxo de trabalho novamente, e ele deve funcionar da mesma forma que antes. Se você fornecer a flag `-resume`, nenhuma tarefa nova deve nem precisar ser executada: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. Criar módulos para os processos `GATK_HAPLOTYPECALLER` e `GATK_JOINTGENOTYPING` + +Repita os mesmos passos para os processos restantes. +Para cada processo: + +1. Crie a estrutura de diretórios (`modules/gatk/haplotypecaller/` e `modules/gatk/jointgenotyping/`) +2. Crie um arquivo `main.nf` contendo a definição do processo +3. Remova a definição do processo de `genomics-3.nf` +4. Adicione uma declaração de importação para o módulo + +Quando terminar, verifique se a estrutura de diretórios dos seus módulos está correta executando: + +```bash +tree modules/ +``` + +??? abstract "Conteúdo do diretório" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Você também deve ter algo assim no arquivo principal do fluxo de trabalho, após a seção de parâmetros: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Conclusão + +Você praticou modularizar um fluxo de trabalho, com o fluxo de trabalho de genômica como exemplo. + +### Qual é o próximo passo? + +Testar o fluxo de trabalho modularizado. + +--- + +## 2. Testar o fluxo de trabalho modularizado + +Execute o fluxo de trabalho modularizado para verificar se tudo ainda funciona. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Saída" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Tudo ainda funciona, incluindo a capacidade de retomada do pipeline. +Os resultados continuam sendo publicados no diretório `results_genomics`. + +```console title="Conteúdo do diretório" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Conclusão + +Você modularizou um fluxo de trabalho e verificou que ele ainda funciona da mesma forma que antes. + +### Qual é o próximo passo? + +Revisar o que você aprendeu e olhar adiante para testes. + +--- + +## 3. Resumo + +Você modularizou o fluxo de trabalho, e nada mudou em como o pipeline funciona. +Isso é intencional: você reestruturou o código sem impactar sua função. + +Os módulos contêm apenas a lógica do processo, tornando-os limpos e reutilizáveis. +O script principal controla o que é publicado e onde, enquanto os módulos permanecem focados em sua tarefa computacional. + +Você estabeleceu uma base para coisas que tornarão seu código mais fácil de manter. +Por exemplo, agora você pode adicionar testes ao seu pipeline usando o framework nf-test. +É isso que veremos na próxima parte deste curso. diff --git a/docs/pt/docs/nf4_science/genomics/04_testing.md b/docs/pt/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..52b1ddeef8 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Parte 4: Adicionando testes + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na primeira parte deste curso, você construiu um pipeline de chamada de variantes que era completamente linear e processava os dados de cada amostra independentemente das outras. + +Na segunda parte, mostramos como usar canais e operadores de canal para implementar chamada conjunta de variantes com GATK. + +Na terceira parte, modularizamos o pipeline. + +Nesta parte do treinamento, vamos mostrar como usar [**nf-test**](https://www.nf-test.com/), um framework de testes que se integra bem com Nextflow e facilita a adição de testes tanto em nível de módulo quanto em nível de fluxo de trabalho ao seu pipeline. Para acompanhar esta parte do treinamento, você deve ter completado a Parte 1, Parte 2 e Parte 3, bem como a [missão secundária nf-test](../../side_quests/nf-test.md), que cobre os fundamentos do nf-test e por que testar é importante. + +--- + +## 0. Aquecimento + +!!! note "Nota" + + Certifique-se de estar no diretório de trabalho correto: + `cd /workspaces/training/nf4-science/genomics` + +Se você trabalhou nas partes anteriores deste curso de treinamento, você deve ter uma versão funcional do pipeline de genômica com a estrutura de diretórios de módulos apropriada. + +??? abstract "Conteúdo do diretório" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Este diretório de módulos pode ser encontrado no diretório `solutions` se você precisar. + +Vamos começar com o mesmo fluxo de trabalho da Parte 3, que fornecemos para você no arquivo `genomics-4.nf`. Exatamente como na [missão secundária nf-test](../../side_quests/nf-test.md), vamos adicionar alguns tipos diferentes de testes aos três processos neste pipeline, bem como um teste em nível de fluxo de trabalho. + +### 0.1. Verificar se o fluxo de trabalho executa + +Antes de começarmos a adicionar testes, certifique-se de que o fluxo de trabalho executa conforme esperado. + +```bash +nextflow run genomics-4.nf -resume +``` + +Isso deve parecer muito familiar agora se você está acompanhando este curso de treinamento desde o início. + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Como anteriormente, agora haverá um diretório `work` e um diretório `results_genomics` dentro do seu diretório de projeto. Na verdade, usaremos esses resultados mais tarde em nossos testes. Mas a partir de agora vamos usar o pacote `nf-test` para testar o pipeline. + +### 0.2. Inicializar `nf-test` + +Como na [missão secundária nf-test](../../side_quests/nf-test.md), precisamos inicializar o pacote `nf-test`. + +```bash +nf-test init +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "Conteúdo do nf-test.config" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Ele também cria um diretório `tests` contendo um esboço de arquivo de configuração. + +### Conclusão + +Agora estamos prontos para começar a escrever testes para nosso pipeline de genômica. + +### O que vem a seguir? + +Escrever testes básicos que avaliem se as chamadas de processo foram bem-sucedidas e produziram as saídas corretas. + +--- + +## 1. Testar um processo quanto a sucesso e saídas correspondentes + +Começaremos testando o processo `SAMTOOLS_INDEX`, que cria arquivos de índice para arquivos BAM para permitir acesso aleatório eficiente. Este é um bom primeiro caso de teste porque: + +1. Possui uma única entrada bem definida (um arquivo BAM) +2. Produz uma saída previsível (um arquivo de índice BAI) +3. A saída deve ser idêntica para entradas idênticas + +### 1.1. Gerar um esboço de arquivo de teste + +Primeiro, gere um esboço de arquivo de teste: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Saída do comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Isso cria um arquivo no mesmo diretório que `main.nf`. +Você pode navegar até o diretório no explorador de arquivos e abrir o arquivo, que deve conter o seguinte código: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +As asserções iniciais devem ser familiares da [missão secundária nf-test](../../side_quests/nf-test.md): + +- `assert process.success` declara que esperamos que o processo execute com sucesso e complete sem falhas. +- `snapshot(process.out).match()` declara que esperamos que o resultado da execução seja idêntico ao resultado obtido em uma execução anterior (se aplicável). + Discutimos isso em mais detalhes posteriormente. + +Usando isso como ponto de partida, precisamos adicionar as entradas de teste corretas para o processo de índice do samtools, e quaisquer parâmetros se aplicável. + +### 1.2. Mover o arquivo de teste e atualizar o caminho do script + +Antes de começarmos a trabalhar no preenchimento do teste, precisamos mover o arquivo para sua localização definitiva. Parte da razão pela qual adicionamos um diretório para cada módulo é que agora podemos enviar testes em um diretório `tests` co-localizado com o arquivo `main.nf` de cada módulo. Crie esse diretório e mova o arquivo de teste para lá. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Agora podemos simplificar a seção `script` do arquivo de teste para um caminho relativo: + +=== "Depois" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Isso informa ao teste onde encontrar o arquivo `main.nf` do módulo, sem ter que especificar o caminho completo. + +### 1.3. Fornecer entradas de teste para SAMTOOLS_INDEX + +O arquivo esboço inclui um placeholder que precisamos substituir por uma entrada de teste real, apropriada para a entrada do `samtools index`. A entrada apropriada é um arquivo BAM, que temos disponível no diretório `data/bam`. + +=== "Depois" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Nomear o teste baseado na funcionalidade + +Como aprendemos antes, é uma boa prática renomear o teste para algo que faça sentido no contexto do teste. + +=== "Depois" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Isso recebe uma string arbitrária, então poderíamos colocar qualquer coisa que quisermos. + Aqui escolhemos nos referir ao nome do arquivo e seu formato. + +=== "Antes" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Executar o teste e examinar a saída + +Execute o teste: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Como aprendemos anteriormente, isso verificou a asserção básica sobre o sucesso do processo e criou um arquivo de snapshot baseado na saída do processo. Podemos ver o conteúdo do arquivo de snapshot em `tests/modules/samtools/index/tests/main.nf.test.snap`: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Também podemos executar o teste novamente e ver que ele passa, porque a saída é idêntica ao snapshot: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. Adicionar mais testes ao SAMTOOLS_INDEX + +Às vezes é útil testar uma variedade de diferentes arquivos de entrada para garantir que estamos testando uma variedade de possíveis problemas. Adicione testes para os arquivos BAM da mãe e do pai no trio de nossos dados de teste. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Então você pode executar o teste novamente: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +Observe o aviso, referindo-se ao efeito do parâmetro `--update-snapshot`. + +!!! note "Nota" + + Aqui estamos usando dados de teste que usamos anteriormente para demonstrar as saídas científicas do pipeline. + Se tivéssemos planejado operar esses testes em um ambiente de produção, teríamos gerado entradas menores para fins de teste. + + Em geral, é importante manter os testes unitários o mais leves possível usando os menores pedaços de dados necessários e suficientes para avaliar a funcionalidade do processo, caso contrário o tempo total de execução pode aumentar consideravelmente. + Uma suíte de testes que leva muito tempo para executar regularmente é uma suíte de testes que provavelmente será pulada no interesse da conveniência. + +### Conclusão + +Você escreveu seu primeiro teste de módulo para um processo de genômica, verificando que `SAMTOOLS_INDEX` cria corretamente arquivos de índice para diferentes arquivos BAM. A suíte de testes garante que: + +1. O processo executa com sucesso +2. Arquivos de índice são criados +3. As saídas são consistentes entre execuções +4. O processo funciona para todos os arquivos BAM de amostra + +### O que vem a seguir? + +Aprenda como escrever testes para outros processos em nosso fluxo de trabalho de genômica, usando o método setup para lidar com processos encadeados. Também avaliaremos se as saídas, especificamente nossos arquivos VCF, contêm chamadas de variantes esperadas. + +--- + +## 2. Adicionar testes a um processo encadeado e testar o conteúdo + +Para testar `GATK_HAPLOTYPECALLER`, precisamos fornecer ao processo a saída de `SAMTOOLS_INDEX` como entrada. Poderíamos fazer isso executando `SAMTOOLS_INDEX`, recuperando suas saídas e armazenando-as com os dados de teste do fluxo de trabalho. Essa é na verdade a abordagem recomendada para um pipeline polido, mas nf-test fornece uma abordagem alternativa, usando o método `setup`. + +Com o método setup, podemos acionar o processo `SAMTOOLS_INDEX` como parte da configuração do teste, e então usar sua saída como entrada para `GATK_HAPLOTYPECALLER`. Isso tem um custo: vamos ter que executar o processo `SAMTOOLS_INDEX` toda vez que executarmos o teste para `GATK_HAPLOTYPECALLER`. No entanto, talvez ainda estejamos desenvolvendo o fluxo de trabalho e não queiramos pré-gerar dados de teste que talvez tenhamos que mudar mais tarde. O processo `SAMTOOLS_INDEX` também é muito rápido, então talvez os benefícios de pré-gerar e armazenar suas saídas sejam negligenciáveis. Aqui está como o método setup funciona. + +### 2.1. Gerar e colocar o arquivo de teste + +Como anteriormente, primeiro geramos o esboço do arquivo: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Saída do comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Isso produz o seguinte esboço de teste: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Mover o arquivo de teste e atualizar o caminho do script + +Criamos um diretório para o arquivo de teste co-localizado com o arquivo `main.nf` do módulo: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +E movemos o arquivo esboço de teste para lá: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Finalmente, não esqueça de atualizar o caminho do script: + +=== "Depois" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Fornecer entradas usando o método setup + +Inserimos um bloco `setup` antes do bloco `when`, onde podemos acionar uma execução do processo `SAMTOOLS_INDEX` em um de nossos arquivos de entrada originais. Além disso, lembre-se como antes de mudar o nome do teste para algo significativo. + +=== "Depois" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Então podemos nos referir à saída desse processo no bloco `when` onde especificamos as entradas do teste: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Faça essa mudança e execute o teste novamente: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Ele também produz um arquivo de snapshot como anteriormente. + +### 2.4. Executar novamente e observar a falha + +Curiosamente, se você executar o mesmo comando novamente, desta vez o teste falhará. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +A mensagem de erro informa que houve diferenças entre os snapshots para as duas execuções; especificamente, os valores de md5sum são diferentes para os arquivos VCF. + +Por quê? Para encurtar a história, a ferramenta HaplotypeCaller inclui um timestamp no cabeçalho VCF que é diferente toda vez (por definição). +Como resultado, não podemos simplesmente esperar que os arquivos tenham md5sums idênticos mesmo se tiverem conteúdo idêntico em termos das próprias chamadas de variantes. + +Como lidamos com isso? + +### 2.5. Usar um método de asserção de conteúdo para verificar uma variante específica + +Uma maneira de resolver o problema é usar um [tipo diferente de asserção](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions). +Neste caso, vamos verificar conteúdo específico em vez de afirmar identidade. +Mais exatamente, faremos a ferramenta ler as linhas do arquivo VCF e verificar a existência de linhas específicas. + +Na prática, substituímos a segunda asserção no bloco `then` da seguinte forma: + +=== "Depois" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Antes" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Aqui estamos lendo o conteúdo completo do arquivo de saída VCF e procurando uma correspondência de conteúdo, o que é aceitável fazer em um pequeno arquivo de teste, mas você não gostaria de fazer isso em um arquivo maior. +Você pode optar por ler linhas específicas. + +Esta abordagem requer escolher com mais cuidado o que queremos usar como 'sinal' para testar. +Pelo lado positivo, ela pode ser usada para testar com grande precisão se uma ferramenta de análise pode identificar consistentemente características 'difíceis' (como variantes raras) à medida que passa por desenvolvimento adicional. + +### 2.6. Executar novamente e observar sucesso + +Uma vez que modificamos o teste desta forma, podemos executar o teste várias vezes, e ele passará consistentemente. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Adicionar mais testes + +Adicione testes similares para as amostras da mãe e do pai: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Executar o comando de teste + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Isso completa o plano de testes básico para esta segunda etapa do pipeline. Vamos para o terceiro e último teste em nível de módulo! + +### Conclusão + +Você aprendeu como: + +1. Testar processos que dependem de saídas de outros processos +2. Verificar variantes genômicas específicas em arquivos de saída VCF +3. Lidar com saídas não determinísticas verificando conteúdo específico +4. Testar chamada de variantes em várias amostras + +### O que vem a seguir? + +Aprenda como escrever testes que usam dados de teste pré-gerados para a etapa de genotipagem conjunta. + +--- + +## 3. Usar dados de teste pré-gerados + +Para a etapa de genotipagem conjunta, usaremos uma abordagem diferente - usando dados de teste pré-gerados. Isso geralmente é preferível para: + +1. Processos complexos com múltiplas dependências +2. Processos que levam muito tempo para executar +3. Processos que fazem parte de um pipeline estável e de produção + +### 3.1. Gerar dados de teste + +Inspecione os resultados que geramos no início desta seção: + +```bash +tree results_genomics/ +``` + +```console title="Conteúdo do diretório de resultados" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +A etapa de genotipagem conjunta precisa dos arquivos VCF produzidos pelas etapas do haplotype caller como entradas, junto com os índices. Então vamos copiar os resultados que temos para o diretório de testes do módulo `jointgenotyping`. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Agora podemos usar esses arquivos como entradas para o teste que vamos escrever para a etapa de genotipagem conjunta. + +### 3.2. Gerar o esboço do arquivo de teste + +Como anteriormente, primeiro geramos o esboço do arquivo: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Saída do comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Isso produz o seguinte esboço de teste: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Mover o arquivo de teste e atualizar o caminho do script + +Desta vez já temos um diretório para testes co-localizado com o arquivo `main.nf` do módulo, então podemos mover o arquivo esboço de teste para lá: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +E não esqueça de atualizar o caminho do script: + +=== "Depois" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Antes" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Fornecer entradas + +Preencha as entradas com base nas definições de entrada do processo e renomeie o teste adequadamente: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. Usar asserções de conteúdo + +A saída da etapa de genotipagem conjunta é outro arquivo VCF, então vamos usar uma asserção de conteúdo novamente. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Ao verificar o conteúdo de uma variante específica no arquivo de saída, este teste verifica que: + +1. O processo de genotipagem conjunta executa com sucesso +2. O VCF de saída contém todas as três amostras na ordem correta +3. Uma variante específica é chamada corretamente com: + - Genótipos precisos para cada amostra (0/1 para o pai, 1/1 para a mãe e o filho) + - Profundidades de leitura e qualidades de genótipo corretas + - Estatísticas em nível populacional como frequência alélica (AF=0.833) + +Não fizemos snapshot do arquivo inteiro, mas ao verificar uma variante específica, podemos ter confiança de que o processo de genotipagem conjunta está funcionando conforme esperado. + +### 3.6. Executar o teste + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +O teste passa, verificando que nosso processo de genotipagem conjunta corretamente: + +1. Combina VCFs de amostras individuais +2. Realiza chamada conjunta de variantes +3. Produz um VCF multi-amostra com chamadas de genótipo consistentes entre execuções + +### Conclusão + +Você sabe como: + +- Usar resultados previamente gerados como entradas para testes +- Escrever testes usando dados de teste pré-gerados + +### O que vem a seguir? + +Adicionar um teste em nível de fluxo de trabalho para verificar se todo o pipeline de chamada de variantes funciona de ponta a ponta. + +--- + +## 4. Adicionar um teste em nível de fluxo de trabalho + +Agora testaremos o pipeline completo de chamada de variantes, de arquivos BAM a genótipos conjuntos. Isso verifica que: + +1. Todos os processos trabalham juntos corretamente +2. Os dados fluem adequadamente entre as etapas +3. As chamadas de variantes finais são consistentes + +### 4.1. Gerar o teste de fluxo de trabalho + +Gere um arquivo de teste para o pipeline completo: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Saída do comando" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Isso cria um esboço de teste básico: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Apenas corrija o nome para algo significativo (você verá por que isso é útil em breve). + +=== "Depois" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Antes" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note "Nota" + + Neste caso, o arquivo de teste pode permanecer onde `nf-test` o criou. + +### 4.2. Especificar parâmetros de entrada + +Ainda precisamos especificar entradas, o que é feito de forma ligeiramente diferente em testes em nível de fluxo de trabalho comparado a testes em nível de módulo. +Existem várias maneiras de fazer isso, incluindo especificando um perfil. +No entanto, uma maneira mais simples é configurar um bloco `params {}` no arquivo `nextflow.config` que `nf-test init` originalmente criou no diretório `tests`. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow config file for running tests +======================================================================================== +*/ + +// Diretório de saída para saídas do fluxo de trabalho +outputDir = 'results_genomics' + +/* + * Pipeline parameters + */ + +params { + // Entrada primária (arquivo de arquivos de entrada, um por linha) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Arquivos acessórios + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Nome base para arquivo de saída final + cohort_name = "family_trio" +} +``` + +Quando executarmos o teste, `nf-test` pegará este arquivo de configuração e puxará as entradas adequadamente. + +### 4.3. Executar o teste de fluxo de trabalho + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +O teste passa, confirmando que nosso pipeline completo de chamada de variantes: + +1. Processa com sucesso todas as amostras +2. Encadeia corretamente todas as etapas + +### 4.4. Executar TODOS os testes + +nf-test tem mais um truque na manga. Podemos executar todos os testes de uma vez! Modifique o arquivo `nf-test.config` para que nf-test procure em cada diretório por arquivos nf-test. Você pode fazer isso modificando o parâmetro `testsDir`: + +=== "Depois" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Antes" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Agora, podemos simplesmente executar nf-test e ele executará _cada teste_ em nosso repositório: + +```bash +nf-test test +``` + +??? success "Saída do comando" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +8 testes em 1 comando! Gastamos muito tempo configurando muitos e muitos testes, mas quando chegou a hora de executá-los foi muito rápido e fácil. Você pode ver como isso é útil ao manter um pipeline grande, que pode incluir centenas de elementos diferentes. Gastamos tempo escrevendo testes uma vez para que possamos economizar tempo executando-os muitas vezes. + +Além disso, podemos automatizar isso! Imagine testes executando toda vez que você ou um colega tenta adicionar novo código. É assim que garantimos que nossos pipelines mantêm um alto padrão. + +## Resumo + +Você agora sabe como escrever e executar vários tipos de testes para seu pipeline de genômica usando nf-test. Este framework de testes ajuda a garantir que seu fluxo de trabalho de chamada de variantes produza resultados consistentes e confiáveis em diferentes ambientes e à medida que você faz mudanças no código. + +Você aprendeu a testar componentes críticos como: + +- O processo `SAMTOOLS_INDEX` que prepara arquivos BAM para chamada de variantes +- O processo `GATK_HAPLOTYPECALLER` que identifica variantes em amostras individuais +- O processo `GATK_JOINTGENOTYPING` que combina chamadas de variantes em uma coorte + +Você também implementou diferentes estratégias de teste específicas para dados genômicos: + +- Verificar que arquivos VCF contêm chamadas de variantes esperadas apesar de elementos não determinísticos como timestamps +- Testar com um conjunto de dados de trio familiar para garantir identificação adequada de variantes entre amostras relacionadas +- Verificar coordenadas genômicas específicas e informações de variantes em seus arquivos de saída + +Essas habilidades de teste são essenciais para desenvolver pipelines robustos de bioinformática que podem processar de forma confiável dados genômicos e produzir chamadas de variantes precisas. À medida que você continua trabalhando com Nextflow para análise genômica, essa base de testes ajudará você a manter código de alta qualidade que produz resultados científicos confiáveis. diff --git a/docs/pt/docs/nf4_science/genomics/05_configuration.md b/docs/pt/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..04330c69f0 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Parte 3: Perfil de recursos e otimização + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +ESTE É UM PLACEHOLDER + +!!!note "Nota" + + Este módulo de treinamento está sendo refeito. + +--- + +TODO + +### 1.1. Execute o fluxo de trabalho para gerar um relatório de utilização de recursos + +Para que o Nextflow gere o relatório automaticamente, basta adicionar `-with-report <nome-do-arquivo>.html` à sua linha de comando. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +O relatório é um arquivo html, que você pode baixar e abrir no seu navegador. Você também pode clicar com o botão direito nele no explorador de arquivos à esquerda e clicar em `Show preview` para visualizá-lo no VS Code. + +Reserve alguns minutos para analisar o relatório e ver se você consegue identificar algumas oportunidades para ajustar recursos. +Certifique-se de clicar nas abas que mostram os resultados de utilização como uma porcentagem do que foi alocado. +Há alguma [documentação](https://www.nextflow.io/docs/latest/reports.html) descrevendo todos os recursos disponíveis. + +<!-- TODO: insert images --> + +Uma observação é que o `GATK_JOINTGENOTYPING` parece estar muito faminto por CPU, o que faz sentido já que ele realiza muitos cálculos complexos. +Então poderíamos tentar aumentar isso e ver se reduz o tempo de execução. + +No entanto, parece que exageramos nas alocações de memória; todos os processos estão usando apenas uma fração do que estamos dando a eles. +Devemos reduzir isso e economizar alguns recursos. + +### 1.2. Ajuste as alocações de recursos para um processo específico + +Podemos especificar alocações de recursos para um determinado processo usando o seletor de processo `withName`. +A sintaxe fica assim quando está sozinha em um bloco de processo: + +```groovy title="Sintaxe" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Vamos adicionar isso ao bloco de processo existente no arquivo `nextflow.config`. + +```groovy title="nextflow.config" linenums="11" +process { + // padrões para todos os processos + cpus = 2 + memory = 2.GB + // alocações para um processo específico + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Com isso especificado, as configurações padrão se aplicarão a todos os processos **exceto** o processo `GATK_JOINTGENOTYPING`, que é um floco de neve especial que recebe muito mais CPU. +Esperamos que isso tenha um efeito. + +### 1.3. Execute novamente com a configuração modificada + +Vamos executar o fluxo de trabalho novamente com a configuração modificada e com o sinalizador de relatório ativado, mas observe que estamos dando ao relatório um nome diferente para que possamos diferenciá-los. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Mais uma vez, você provavelmente não notará uma diferença substancial no tempo de execução, porque esta é uma carga de trabalho muito pequena e as ferramentas gastam mais tempo em tarefas auxiliares do que na execução do trabalho 'real'. + +No entanto, o segundo relatório mostra que nossa utilização de recursos está mais equilibrada agora. + +<!-- **TODO: screenshots?** --> + +Como você pode ver, esta abordagem é útil quando seus processos têm requisitos de recursos diferentes. Ela permite que você dimensione adequadamente as alocações de recursos configuradas para cada processo com base em dados reais, não em suposições. + +!!!note "Nota" + + Isto é apenas um pequeno aperitivo do que você pode fazer para otimizar o uso de recursos. + O próprio Nextflow tem uma [lógica de repetição dinâmica](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) realmente interessante integrada para repetir tarefas que falham devido a limitações de recursos. + Além disso, a Seqera Platform oferece ferramentas orientadas por IA para otimizar suas alocações de recursos automaticamente também. + + Abordaremos ambas as abordagens em uma parte futura deste curso de treinamento. + +Dito isso, pode haver algumas restrições sobre o que você pode (ou deve) alocar dependendo de qual executor de computação e infraestrutura de computação você está usando. Por exemplo, seu cluster pode exigir que você permaneça dentro de certos limites que não se aplicam quando você está executando em outro lugar. diff --git a/docs/pt/docs/nf4_science/genomics/index.md b/docs/pt/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..6671f64927 --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/index.md @@ -0,0 +1,42 @@ +--- +title: Nextflow para Genômica +hide: + - toc +--- + +# Nextflow para Genômica + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de treinamento é destinado a pesquisadores em genômica e áreas relacionadas que estão interessados em desenvolver ou personalizar pipelines de análise de dados. +Ele se baseia no treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/) e demonstra como usar o Nextflow no contexto específico do domínio de genômica. + +Especificamente, este curso demonstra como implementar um pipeline simples de chamada de variantes com [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit), um pacote de software amplamente utilizado para analisar dados de sequenciamento de alto rendimento. + +Vamos começar! Clique no botão "Open in GitHub Codespaces" abaixo para iniciar o ambiente de treinamento (preferencialmente em uma aba separada) e continue lendo enquanto ele carrega. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizagem + +Ao trabalhar neste curso, você aprenderá como aplicar conceitos e ferramentas fundamentais do Nextflow a um caso de uso típico de genômica. + +Ao final deste workshop, você será capaz de: + +- Escrever um fluxo de trabalho linear para aplicar chamada de variantes a uma única amostra +- Manipular arquivos acessórios, como arquivos de índice e recursos de genoma de referência, adequadamente +- Aproveitar o paradigma de dataflow do Nextflow para paralelizar a chamada de variantes por amostra +- Implementar chamada de variantes multi-amostra usando operadores de canal relevantes +- Implementar testes de pipeline por etapa e de ponta a ponta que lidam com idiossincrasias específicas de genômica adequadamente + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Pré-requisitos + +O curso assume alguma familiaridade mínima com o seguinte: + +- Ferramentas e formatos de arquivo comumente usados neste domínio científico +- Experiência com a linha de comando +- Conceitos e ferramentas fundamentais do Nextflow cobertos no treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/) + +Para requisitos técnicos e configuração de ambiente, consulte o mini-curso [Configuração de Ambiente](../../envsetup/). diff --git a/docs/pt/docs/nf4_science/genomics/next_steps.md b/docs/pt/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..5f58d6bdfb --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Próximos Passos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns novamente por concluir o curso de treinamento Nextflow For Genomics e obrigado por completar nossa pesquisa! + +--- + +## 1. As 3 melhores maneiras de aprimorar suas habilidades em Nextflow + +Aqui estão nossas três principais recomendações sobre o que fazer a seguir com base no curso que você acabou de concluir. + +### 1.1. Aplicar Nextflow a outros casos de uso de análise científica + +**Confira a página [Nextflow for Science](../index.md)** para uma lista de outros cursos curtos e independentes que demonstram como aplicar os conceitos básicos e mecanismos apresentados no Hello Nextflow a casos de uso comuns de análise científica. + +Se você não vir seu domínio representado por um caso de uso relacionável, nos avise no [fórum da Comunidade](https://community.seqera.io/) para que possamos adicioná-lo à nossa lista de desenvolvimento. + +### 1.2. Começar com nf-core + +**[nf-core](https://nf-co.re/)** é um esforço colaborativo mundial para desenvolver pipelines padronizados de código aberto para uma ampla gama de aplicações de pesquisa científica. +O projeto inclui [mais de 100 pipelines](https://nf-co.re/pipelines/) que estão disponíveis para uso imediato e [bem mais de 1400 módulos de processos](https://nf-co.re/modules/) que podem ser integrados aos seus próprios projetos, além de um rico conjunto de ferramentas para desenvolvedores. + +O curso de treinamento **[Hello nf-core](../../hello_nf-core/index.md)** apresentará a você os pipelines curados pela comunidade nf-core e o framework de desenvolvimento, projetado para ajudá-lo a escrever fluxos de trabalho reproduzíveis, escaláveis e padronizados. Você aprenderá como usar pipelines nf-core existentes, contribuir para seu desenvolvimento e até começar a construir os seus próprios, apoiado por melhores práticas e uma comunidade vibrante. Se você está pronto para aplicar suas habilidades em Nextflow em projetos do mundo real, este é o próximo passo perfeito. + +### 1.3. Dominar recursos mais avançados do Nextflow + +Nos cursos Hello, mantemos o nível de complexidade técnica baixo propositalmente para evitar sobrecarregá-lo com informações que você não precisa para começar com Nextflow. +À medida que você avança com seu trabalho, vai querer aprender como usar o conjunto completo de recursos e o poder do Nextflow. + +Para esse fim, estamos trabalhando atualmente em uma **coleção de [Side Quests](../side_quests/index.md)**, que são cursos curtos e independentes que se aprofundam em tópicos específicos como testes e manipulação de metadados. + +--- + +## 2. Conheça o Seqera Platform + +**[Seqera Platform](https://seqera.io/) é a melhor maneira de executar Nextflow na prática.** + +É uma plataforma baseada em nuvem desenvolvida pelos criadores do Nextflow que você pode conectar à sua própria infraestrutura de computação (seja local, HPC ou nuvem) para facilitar muito o lançamento e gerenciamento de seus fluxos de trabalho, bem como gerenciar seus dados e executar análises de forma interativa em um ambiente de nuvem. + +O Free Tier está disponível para uso gratuito por todos (com cotas de uso). +Acadêmicos qualificados podem obter acesso gratuito de nível Pro (sem limitações de uso) através do [Programa Acadêmico](https://seqera.io/academic/program/). + +Dê uma olhada nos [tutoriais do Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) para ver se isso pode ser útil para você. + +--- + +### É isso por enquanto! + +**Boa sorte em sua jornada com Nextflow e não hesite em nos avisar no [fórum da Comunidade](https://community.seqera.io/) o que mais poderíamos fazer para ajudar.** diff --git a/docs/pt/docs/nf4_science/genomics/survey.md b/docs/pt/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..463cc1c02d --- /dev/null +++ b/docs/pt/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Pesquisa de feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de continuar, por favor complete esta breve pesquisa de 5 perguntas para avaliar o treinamento, compartilhar qualquer feedback que você possa ter sobre sua experiência e nos contar o que mais poderíamos fazer para ajudá-lo em sua jornada com Nextflow. + +Isso deve levar menos de um minuto para ser concluído. Obrigado por nos ajudar a melhorar nossos materiais de treinamento para todos! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pt/docs/nf4_science/imaging/00_orientation.md b/docs/pt/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..954f3fce8d --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Orientação + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta orientação pressupõe que você já abriu o ambiente de treinamento clicando no botão "Open in GitHub Codespaces". +Se não, por favor, faça isso agora, idealmente em uma segunda janela ou aba do navegador para que você possa consultar estas instruções. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Requisito de tamanho da máquina" + + Certifique-se de selecionar uma **máquina de 8 núcleos** ao criar seu Codespace para este curso de treinamento. Os fluxos de trabalho de bioimagem requerem recursos computacionais adicionais. + +## GitHub Codespaces + +O ambiente GitHub Codespaces contém todo o software, código e dados necessários para trabalhar neste curso de treinamento, então você não precisa instalar nada por conta própria. +No entanto, você precisa de uma conta GitHub (gratuita) para fazer login, e se você não está familiarizado com a interface, deve levar alguns minutos para se familiarizar com ela completando o mini-curso [Orientação do GitHub Codespaces](../../envsetup/index.md). + +## Pré-download das imagens Docker + +Depois de abrir seu Codespace, vamos fazer o pré-download de todas as imagens Docker que precisaremos para este curso de treinamento. +Isso economizará tempo mais tarde e garantirá a execução suave dos fluxos de trabalho. + +Abra uma nova aba do terminal e execute o seguinte comando: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Este comando fará o download de todas as imagens Docker necessárias em segundo plano. +Você pode continuar com o restante da orientação enquanto isso é executado. + +!!!tip "Dica" + + A flag `-stub` permite que o pipeline seja executado rapidamente sem processar dados reais, o que é perfeito para baixar imagens. Você pode monitorar o progresso na aba do terminal. + +## Diretório de trabalho + +Ao longo deste curso de treinamento, trabalharemos no diretório `nf4-science/imaging/`. + +Mude de diretório agora executando este comando no terminal: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "Dica" + + Se por qualquer motivo você sair deste diretório, você sempre pode usar o caminho completo para retornar a ele, assumindo que você está executando isso dentro do ambiente de treinamento GitHub Codespaces: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Agora, para começar o curso, clique na seta no canto inferior direito desta página.** diff --git a/docs/pt/docs/nf4_science/imaging/01_basics.md b/docs/pt/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..3f357bc684 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Parte 1: Executar operações básicas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta primeira parte do curso de treinamento Nextflow para Bioimagem, usaremos um exemplo básico Hello World agnóstico de domínio para demonstrar operações essenciais e apontar os componentes de código Nextflow correspondentes. + +## 1. Executar o fluxo de trabalho + +Fornecemos um script de fluxo de trabalho chamado `hello-world.nf` que recebe uma entrada via argumento de linha de comando chamado `--greeting` e produz um arquivo de texto contendo essa saudação. +Ainda não vamos olhar o código; primeiro vamos ver como é executá-lo. + +### 1.1. Iniciar o fluxo de trabalho e monitorar a execução + +No terminal, execute o seguinte comando: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +A saída do console deve se parecer com isto: + +```console title="Saída" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Parabéns, você acabou de executar seu primeiro fluxo de trabalho Nextflow! + +A saída mais importante aqui é a última linha (linha 6): + +```console title="Saída" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Isso nos diz que o processo `sayHello` foi executado com sucesso uma vez (`1 of 1 ✔`). + +Isso é ótimo, mas você pode estar se perguntando: onde está a saída? + +### 1.2. Encontrar o arquivo de saída no diretório `results` + +Este fluxo de trabalho está configurado para publicar sua saída em um diretório chamado `results`. +Se você olhar seu diretório atual, verá que quando você executou o fluxo de trabalho, o Nextflow criou um novo diretório chamado `results`, que contém um arquivo chamado `output.txt`. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Abra o arquivo; o conteúdo deve corresponder à saudação que você especificou na linha de comando. + +<details> + <summary>Conteúdo do arquivo</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +Isso é ótimo, nosso fluxo de trabalho fez o que deveria fazer! + +No entanto, esteja ciente de que o resultado 'publicado' é uma cópia (ou em alguns casos um symlink) da saída real produzida pelo Nextflow quando executou o fluxo de trabalho. + +Então agora, vamos olhar por baixo do capô para ver onde o Nextflow realmente executou o trabalho. + +!!! warning "Aviso" + + Nem todos os fluxos de trabalho estarão configurados para publicar saídas em um diretório results, e/ou o nome do diretório pode ser diferente. + Um pouco mais adiante nesta seção, mostraremos como descobrir onde esse comportamento é especificado. + +### 1.3. Encontrar a saída original e logs no diretório `work/` + +Quando você executa um fluxo de trabalho, o Nextflow cria um 'diretório de tarefa' distinto para cada invocação de cada processo no fluxo de trabalho (=cada etapa no pipeline). +Para cada um, ele preparará as entradas necessárias, executará a(s) instrução(ões) relevante(s) e gravará saídas e arquivos de log dentro daquele único diretório, que é nomeado automaticamente usando um hash para torná-lo único. + +Todos esses diretórios de tarefa ficarão em um diretório chamado `work` dentro do seu diretório atual (onde você está executando o comando). + +Isso pode parecer confuso, então vamos ver como isso se parece na prática. + +Voltando à saída do console para o fluxo de trabalho que executamos anteriormente, tínhamos esta linha: + +```console title="Trecho da saída do comando" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Vê como a linha começa com `[a3/7be2fa]`? +Essa é uma forma truncada do caminho do diretório de tarefa para aquela chamada de processo, e diz onde encontrar a saída da chamada do processo `sayHello` dentro do caminho do diretório `work/`. + +Você pode encontrar o caminho completo digitando o seguinte comando (substituindo `a3/7be2fa` pelo que você vê em seu próprio terminal) e pressionando a tecla tab para autocompletar o caminho ou adicionando um asterisco: + +```bash +tree work/a3/7be2fa* +``` + +Isso deve gerar o caminho completo do diretório: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Vamos dar uma olhada no que há lá dentro. + +!!! Tip "Dica" + + Se você navegar pelo conteúdo do subdiretório de tarefa no explorador de arquivos do VSCode, verá todos os arquivos imediatamente. + No entanto, os arquivos de log estão configurados para serem invisíveis no terminal, então se você quiser usar `ls` ou `tree` para visualizá-los, precisará definir a opção relevante para exibir arquivos invisíveis. + + ```bash + tree -a work + ``` + +Os nomes exatos dos subdiretórios serão diferentes no seu sistema. + +<details> + <summary>Conteúdo do diretório</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +Você deve reconhecer imediatamente o arquivo `output.txt`, que é de fato a saída original do processo `sayHello` que foi publicada no diretório `results`. +Se você abri-lo, encontrará a saudação `Hello World!` novamente. + +<details> + <summary>Conteúdo do arquivo output.txt</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +E quanto a todos aqueles outros arquivos? + +Estes são os arquivos auxiliares e de log que o Nextflow escreveu como parte da execução da tarefa: + +- **`.command.begin`**: Arquivo sentinela criado assim que a tarefa é lançada. +- **`.command.err`**: Mensagens de erro (`stderr`) emitidas pela chamada do processo +- **`.command.log`**: Saída de log completa emitida pela chamada do processo +- **`.command.out`**: Saída regular (`stdout`) pela chamada do processo +- **`.command.run`**: Script completo executado pelo Nextflow para executar a chamada do processo +- **`.command.sh`**: O comando que foi realmente executado pela chamada do processo +- **`.exitcode`**: O código de saída resultante do comando + +O arquivo `.command.sh` é especialmente útil porque mostra o comando principal que o Nextflow executou, não incluindo toda a contabilidade e configuração de tarefa/ambiente. + +<details> + <summary>Conteúdo do arquivo</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "Dica" + + Quando algo dá errado e você precisa solucionar o que aconteceu, pode ser útil olhar o script `command.sh` para verificar exatamente qual comando o Nextflow compôs com base nas instruções do fluxo de trabalho, interpolação de variáveis e assim por diante. + +### 1.4. Exercício opcional: executar novamente com saudações diferentes + +Tente executar novamente o fluxo de trabalho algumas vezes com valores diferentes para o argumento `--greeting`, depois olhe tanto o conteúdo do diretório `results/` quanto os diretórios de tarefa. + +Observe como as saídas e logs de diretórios de tarefa isolados são preservados, enquanto o conteúdo do diretório `results` é sobrescrito pela saída de execuções subsequentes. + +### Conclusão + +Você sabe como executar um script Nextflow simples, monitorar sua execução e encontrar suas saídas. + +### O que vem a seguir? + +Aprenda a ler um script Nextflow básico e identificar como seus componentes se relacionam com sua funcionalidade. + +--- + +## 2. Examinar o script inicial do fluxo de trabalho Hello World + +O que fizemos lá foi basicamente tratar o script do fluxo de trabalho como uma caixa preta. +Agora que vimos o que ele faz, vamos abrir a caixa e olhar dentro. + +_O objetivo aqui não é memorizar a sintaxe do código Nextflow, mas formar alguma intuição básica sobre quais são os componentes principais e como eles são organizados._ + +### 2.1. Examinar a estrutura geral do código + +Vamos abrir o script `hello-world.nf` no painel do editor. + +<details> + <summary>Código</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Usa echo para imprimir uma saudação em um arquivo + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // emite uma saudação + sayHello(params.greeting) +} +``` + +</details> + +Um script Nextflow envolve dois tipos principais de componentes centrais: um ou mais **processos**, e o **fluxo de trabalho** em si. +Cada **processo** descreve quais operação(ões) a etapa correspondente no pipeline deve realizar, enquanto o **fluxo de trabalho** descreve a lógica de fluxo de dados que conecta as várias etapas. + +Vamos dar uma olhada mais de perto no bloco **process** primeiro, depois veremos o bloco **workflow**. + +### 2.2. A definição de `process` + +O primeiro bloco de código descreve um **processo**. +A definição do processo começa com a palavra-chave `process`, seguida pelo nome do processo e finalmente o corpo do processo delimitado por chaves. +O corpo do processo deve conter um bloco script que especifica o comando a ser executado, que pode ser qualquer coisa que você seria capaz de executar em um terminal de linha de comando. + +Aqui temos um **processo** chamado `sayHello` que recebe uma variável de **entrada** chamada `greeting` e escreve sua **saída** em um arquivo chamado `output.txt`. + +<details> + <summary>Código</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Usa echo para imprimir uma saudação em um arquivo + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +Esta é uma definição de processo muito mínima que contém apenas uma definição de `input`, uma definição de `output` e o `script` a executar. + +A definição de `input` inclui o qualificador `val`, que diz ao Nextflow para esperar um valor de algum tipo (pode ser uma string, um número, qualquer coisa). + +A definição de `output` inclui o qualificador `path`, que diz ao Nextflow que isso deve ser tratado como um caminho (inclui tanto caminhos de diretório quanto arquivos). + +!!! Tip "Dica" + + A definição de saída não _determina_ qual saída será criada. + Ela simplesmente _declara_ onde encontrar o(s) arquivo(s) de saída esperado(s), para que o Nextflow possa procurá-lo uma vez que a execução esteja completa. + + Isso é necessário para verificar se o comando foi executado com sucesso e para passar a saída para processos posteriores, se necessário. + A saída produzida que não corresponder ao que é declarado no bloco de saída não será passada para processos posteriores. + +Em um pipeline do mundo real, um processo geralmente contém informações adicionais, como diretivas de processo, que introduziremos daqui a pouco. + +### 2.3. A definição de `workflow` + +O segundo bloco de código descreve o **fluxo de trabalho** em si. +A definição do fluxo de trabalho começa com a palavra-chave `workflow`, seguida por um nome opcional, depois o corpo do fluxo de trabalho delimitado por chaves. + +Aqui temos um **fluxo de trabalho** que consiste em uma chamada ao processo `sayHello`, que recebe uma entrada, `params.greeting`, que contém o valor que demos ao parâmetro `--greeting`. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // emite uma saudação + sayHello(params.greeting) +} +``` + +Esta é uma definição de **fluxo de trabalho** muito mínima. +Em um pipeline do mundo real, o fluxo de trabalho normalmente contém múltiplas chamadas a **processos** conectados por **canais**, e pode haver valores padrão configurados para as entradas de variáveis. + +Veremos isso em ação quando executarmos nf-core/molkart na Parte 2 do curso. + +### 2.4. O sistema `params` de parâmetros de linha de comando + +O `params.greeting` que fornecemos à chamada do processo `sayHello()` é um pedaço interessante de código Nextflow e vale a pena gastar um minuto extra nele. + +Como mencionado acima, é assim que passamos o valor do parâmetro de linha de comando `--greeting` para a chamada do processo `sayHello()`. +Na verdade, simplesmente declarar `params.someParameterName` nos permitirá dar ao fluxo de trabalho um parâmetro chamado `--someParameterName` a partir da linha de comando. + +!!! Tip "Dica" + + Esses parâmetros de fluxo de trabalho declarados usando o sistema `params` sempre levam dois traços (`--`). + Isso os distingue dos parâmetros de nível Nextflow, que levam apenas um traço (`-`). + +### Conclusão + +Você agora sabe como um fluxo de trabalho Nextflow simples é estruturado, e como os componentes básicos se relacionam com sua funcionalidade. + +### O que vem a seguir? + +Aprenda a gerenciar suas execuções de fluxo de trabalho de forma conveniente. + +--- + +## 3. Gerenciar execuções de fluxo de trabalho + +Saber como iniciar fluxos de trabalho e recuperar saídas é ótimo, mas você rapidamente descobrirá que existem alguns outros aspectos do gerenciamento de fluxo de trabalho que tornarão sua vida mais fácil. + +Aqui mostramos como aproveitar o recurso `resume` para quando você precisar relançar o mesmo fluxo de trabalho, como inspecionar os logs de execução com `nextflow log`, e como excluir diretórios de trabalho mais antigos com `nextflow clean`. + +### 3.1. Relançar um fluxo de trabalho com `-resume` + +Às vezes, você vai querer executar novamente um pipeline que você já lançou anteriormente sem refazer nenhum trabalho que já foi concluído com sucesso. + +O Nextflow tem uma opção chamada `-resume` que permite fazer isso. +Especificamente, neste modo, quaisquer processos que já foram executados com exatamente o mesmo código, configurações e entradas serão ignorados. +Isso significa que o Nextflow só executará processos que você adicionou ou modificou desde a última execução, ou aos quais você está fornecendo novas configurações ou entradas. + +Existem duas vantagens principais em fazer isso: + +- Se você está no meio do desenvolvimento de um pipeline, pode iterar mais rapidamente, já que só precisa executar o(s) processo(s) em que está trabalhando ativamente para testar suas alterações. +- Se você está executando um pipeline em produção e algo dá errado, em muitos casos você pode corrigir o problema e relançar o pipeline, e ele retomará a execução do ponto de falha, o que pode economizar muito tempo e computação. + +Para usá-lo, simplesmente adicione `-resume` ao seu comando e execute-o: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Procure pelo trecho `cached:` que foi adicionado na linha de status do processo (linha 5), o que significa que o Nextflow reconheceu que já fez este trabalho e simplesmente reutilizou o resultado da execução bem-sucedida anterior. + +Você também pode ver que o hash do subdiretório de trabalho é o mesmo da execução anterior. +O Nextflow está literalmente apontando para a execução anterior e dizendo "Eu já fiz isso ali." + +!!! Tip "Dica" + + Quando você executa novamente um pipeline com `resume`, o Nextflow não sobrescreve nenhum arquivo escrito em um diretório `publishDir` por qualquer chamada de processo que foi executada com sucesso anteriormente. + +### 3.2. Inspecionar o log de execuções passadas + +Sempre que você inicia um fluxo de trabalho nextflow, uma linha é escrita em um arquivo de log chamado `history`, em um diretório oculto chamado `.nextflow` no diretório de trabalho atual. + +Uma maneira mais conveniente de acessar essas informações é usar o comando `nextflow log`. + +```bash +nextflow log +``` + +Isso exibirá o conteúdo do arquivo de log no terminal, mostrando o timestamp, nome da execução, status e linha de comando completa para cada execução Nextflow que foi lançada de dentro do diretório de trabalho atual. + +### 3.3. Excluir diretórios de trabalho mais antigos + +Durante o processo de desenvolvimento, você normalmente executará seus rascunhos de pipelines um grande número de vezes, o que pode levar a uma acumulação de muitos arquivos em muitos subdiretórios. +Como os subdiretórios são nomeados aleatoriamente, é difícil dizer pelos nomes quais são execuções mais antigas vs. mais recentes. + +O Nextflow inclui um subcomando `clean` conveniente que pode excluir automaticamente os subdiretórios de trabalho de execuções passadas que você não se importa mais, com várias [opções](https://www.nextflow.io/docs/latest/reference/cli.html#clean) para controlar o que será excluído. + +Você pode usar o log do Nextflow para procurar uma execução com base em seu timestamp e/ou linha de comando, depois usar `nextflow clean -before <run_name> -f` para excluir diretórios de trabalho de execuções anteriores. + +!!! Warning "Aviso" + + Excluir subdiretórios de trabalho de execuções passadas os remove do cache do Nextflow e exclui quaisquer saídas que estavam armazenadas nesses diretórios. + Isso significa que quebra a capacidade do Nextflow de retomar a execução sem executar novamente os processos correspondentes. + + Você é responsável por salvar quaisquer saídas que você se importa ou planeja usar! Se você está usando a diretiva `publishDir` para esse propósito, certifique-se de usar o modo `copy`, não o modo `symlink`. + +### Conclusão + +Você sabe como relançar um pipeline sem repetir etapas que já foram executadas de forma idêntica, inspecionar o log de execução e usar o comando `nextflow clean` para limpar diretórios de trabalho antigos. + +### O que vem a seguir? + +Agora que você entende operações básicas do Nextflow, está pronto para executar um pipeline de bioimagem real com nf-core/molkart. diff --git a/docs/pt/docs/nf4_science/imaging/02_run_molkart.md b/docs/pt/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..d7c8ee6a7e --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Parte 2: Executar nf-core/molkart + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na Parte 1, executamos um fluxo de trabalho simples Hello World para entender os conceitos básicos da execução do Nextflow. +Agora vamos executar um pipeline de bioimagem do mundo real: **nf-core/molkart**. + +Este pipeline processa dados de transcriptômica espacial de Cartografia Molecular da Resolve Bioscience. +No entanto, os padrões do Nextflow que você aprenderá aqui se aplicam a qualquer pipeline nf-core ou fluxo de trabalho de produção. + +## 1. Entendendo pipelines nf-core + +Antes de executarmos o pipeline, vamos entender o que é o nf-core e por que ele é importante para executar fluxos de trabalho. + +### 1.1. O que é nf-core? + +[nf-core](https://nf-co.re/) é uma coleção orientada pela comunidade de pipelines Nextflow de alta qualidade. +Todos os pipelines nf-core seguem a mesma estrutura e convenções, o que significa que depois de aprender a executar um, você pode executar qualquer um deles. + +Principais características dos pipelines nf-core: + +- **Estrutura padronizada**: Todos os pipelines têm nomes de parâmetros e padrões de uso consistentes +- **Dados de teste integrados**: Cada pipeline inclui perfis de teste para validação rápida +- **Documentação abrangente**: Instruções de uso detalhadas e descrições de parâmetros +- **Controle de qualidade**: Relatórios de QC automatizados usando MultiQC +- **Suporte a contêineres**: Contêineres pré-construídos para reprodutibilidade + +!!! tip "Quer aprender mais sobre nf-core?" + + Para uma introdução aprofundada ao desenvolvimento de pipelines nf-core, confira o curso de treinamento [Hello nf-core](../../hello_nf-core/index.md). + Ele abrange como criar e personalizar pipelines nf-core do zero. + +### 1.2. O pipeline molkart + +![Pipeline nf-core/molkart](img/molkart.png) + +O pipeline [nf-core/molkart](https://nf-co.re/molkart) processa dados de imagem de transcriptômica espacial através de vários estágios: + +1. **Pré-processamento de imagem**: Preenchimento de padrão de grade e melhoria opcional de contraste +2. **Segmentação celular**: Múltiplas opções de algoritmo (Cellpose, Mesmer, ilastik, Stardist) +3. **Atribuição de pontos**: Atribuir pontos de transcritos a células segmentadas +4. **Controle de qualidade**: Gerar relatórios abrangentes de QC + +As principais saídas são: + +- Tabelas de contagem célula por transcrito +- Máscaras de segmentação +- Relatório de controle de qualidade MultiQC + +--- + +## 2. Executar molkart com dados de teste + +Antes de começarmos, vamos clonar o repositório molkart localmente para que possamos inspecionar seu código: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Isso cria um diretório `molkart/` contendo o código-fonte completo do pipeline. + +!!! note "Por que estamos clonando localmente?" + + Normalmente, você executaria pipelines nf-core diretamente do GitHub usando `nextflow run nf-core/molkart -r 1.2.0`. + O Nextflow baixa automaticamente a versão solicitada do pipeline para você em `$HOME/.nextflow/assets/nf-core/molkart` e o executa de lá. + No entanto, para este treinamento, estamos clonando o pipeline para um diretório local diferente para que possamos inspecionar o código mais facilmente. + +### 2.1. Entendendo requisitos de contêineres + +Antes de executar o pipeline completo, vamos aprender por que os contêineres são essenciais para pipelines nf-core. + +Vamos tentar executar o pipeline usando o conjunto de dados de teste e os parâmetros da configuração de teste do molkart: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Vamos analisar esses parâmetros: + +- `--input`: Caminho para a planilha contendo metadados da amostra +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Parâmetros para preenchimento de padrão de grade +- `--clahe_pyramid_tile`: Tamanho do kernel para melhoria de contraste +- `--segmentation_method`: Qual(is) algoritmo(s) usar para segmentação celular +- `--outdir`: Onde salvar os resultados + +!!! Warning "Este comando falhará - isso é intencional!" + + Estamos executando deliberadamente sem contêineres para demonstrar por que eles são necessários. + +Após alguns momentos, você verá um erro como este: + +??? failure "Saída do comando" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**O que está acontecendo aqui?** + +O erro `command not found` (status de saída 127) significa que o Nextflow tentou executar `duplicate_finder.py` mas não conseguiu encontrá-lo no seu sistema. +Isso ocorre porque: + +1. O pipeline espera que software especializado de bioinformática esteja instalado +2. Essas ferramentas (como `duplicate_finder.py`, `apply_clahe.dask.py`, etc.) não fazem parte de distribuições Linux padrão +3. Sem contêineres, o Nextflow tenta executar comandos diretamente na sua máquina local + +**De onde essas ferramentas deveriam vir?** + +Vamos inspecionar um dos módulos de processo para ver como ele declara seus requisitos de software. + +Abra o módulo de pré-processamento CLAHE: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +Observe a linha 5 - você verá: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Esta linha diz ao Nextflow: "Para executar este processo, use a imagem Docker `ghcr.io/schapirolabor/molkart-local:v0.0.4`, que contém todo o software necessário." + +Cada processo declara qual imagem de contêiner fornece suas ferramentas necessárias. +No entanto, o Nextflow só usa esses contêineres se você disser para ele fazer isso! + +**A solução: Habilitar Docker na configuração** + +### 2.2. Configurar Docker e iniciar o pipeline + +Para habilitar o Docker, precisamos mudar `docker.enabled` de `false` para `true` no arquivo `nextflow.config`. + +Abra o arquivo de configuração: + +```bash +code nextflow.config +``` + +Altere `docker.enabled = false` para `docker.enabled = true`: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Agora execute o pipeline novamente com o mesmo comando: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Desta vez, o Nextflow irá: + +1. Ler a configuração `docker.enabled = true` do arquivo de configuração +2. Baixar as imagens Docker necessárias (apenas na primeira vez) +3. Executar cada processo dentro de seu contêiner especificado +4. Executar com sucesso porque todas as ferramentas estão disponíveis dentro dos contêineres + +!!! Tip "Por que os contêineres são importantes" + + A maioria dos pipelines nf-core **requer** containerização (Docker, Singularity, Podman, etc.) porque: + + - Eles usam software especializado de bioinformática não disponível em ambientes padrão + - Os contêineres garantem reprodutibilidade - as mesmas versões exatas de software são executadas em todos os lugares + - Você não precisa instalar manualmente dezenas de ferramentas e suas dependências + + Para mais detalhes sobre contêineres no Nextflow, consulte [Hello Containers](../../hello_nextflow/05_hello_containers.md) do treinamento Hello Nextflow. + +### 2.3. Monitorar a execução + +Conforme o pipeline é executado, você verá uma saída semelhante a esta: + +??? success "Saída do comando" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Observe como esta saída é mais detalhada do que nosso exemplo Hello World por causa das convenções nf-core que o pipeline segue: + +- O pipeline mostra sua versão e logotipo +- Os parâmetros de configuração são exibidos +- Múltiplos processos são executados em paralelo (indicado por várias linhas de processo) +- Os nomes dos processos incluem o caminho completo do módulo (ex.: `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. Entendendo a execução de processos + +A linha do executor `executor > local (22)` informa: + +- **executor**: Qual ambiente de computação está sendo usado (`local` = sua máquina) +- **(22)**: Número total de tarefas iniciadas + +Cada linha de processo mostra: + +- **Hash** (`[1a/2b3c4d]`): Identificador do diretório de trabalho (como antes) +- **Nome do processo**: Caminho completo do módulo e nome do processo +- **Identificador de entrada**: Nome da amostra entre parênteses +- **Progresso**: Porcentagem completa e contagem (ex.: `1 of 1 ✔`) + +### Conclusão + +Você sabe como iniciar um pipeline nf-core com dados de teste e interpretar sua saída de execução. + +### O que vem a seguir? + +Aprenda onde encontrar os resultados e como interpretá-los. + +--- + +## 3. Encontrar e examinar as saídas + +Quando o pipeline é concluído com sucesso, você verá uma mensagem de conclusão e resumo de execução. + +### 3.1. Localizar o diretório de resultados + +Por padrão, os pipelines nf-core gravam saídas em um diretório especificado pelo parâmetro `outdir`, que definimos como `results/`. + +Liste o conteúdo: + +```bash +tree results/ +``` + +Você deve ver vários subdiretórios: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Cada subdiretório contém saídas de um estágio específico do pipeline: + +- **mindagap/**: Imagens preenchidas com grade da etapa de pré-processamento MindaGap +- **clahe/**: Imagens com contraste aprimorado do pré-processamento CLAHE +- **stack/**: Pilhas de imagens multicanal criadas para segmentação +- **segmentation/**: Resultados de segmentação de diferentes algoritmos (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Tabelas de contagem célula por transcrito +- **anndata/**: Objetos AnnData contendo matrizes célula por transcrito e coordenadas espaciais +- **molkartqc/**: Métricas de controle de qualidade para atribuição de pontos +- **multiqc/**: Relatório abrangente de controle de qualidade +- **pipeline_info/**: Relatórios de execução e logs + +### 3.2. Examinar o relatório MultiQC + +O relatório MultiQC é um arquivo HTML abrangente que agrega métricas de qualidade de todas as etapas do pipeline. + +Abra o relatório no navegador de arquivos e clique no botão "Show Preview" para vê-lo renderizado diretamente no VS Code. + +O relatório inclui: + +- Estatísticas gerais para todas as amostras +- Métricas de pré-processamento +- Métricas de qualidade de segmentação +- Número de células e pontos detectados + +!!! Tip + + Os relatórios MultiQC são normalmente incluídos em todos os pipelines nf-core. + Eles sempre fornecem uma visão geral de alto nível da execução do pipeline e qualidade dos dados. + +### 3.3. Examinar as tabelas célula por transcrito + +A saída científica mais importante é a tabela de contagem célula por transcrito. +Isso informa quantos de cada transcrito foram detectados em cada célula. + +Navegue até o diretório spot2cell: + +```bash +ls results/spot2cell/ +``` + +Você encontrará arquivos como: + +- `cellxgene_mem_only_cellpose.csv`: Tabela célula por transcrito usando segmentação Cellpose +- `cellxgene_mem_only_mesmer.csv`: Tabela célula por transcrito usando segmentação Mesmer +- `cellxgene_mem_only_stardist.csv`: Tabela célula por transcrito usando segmentação Stardist + +Executamos apenas 1 amostra neste conjunto de dados de teste, mas em um experimento real teríamos essas tabelas para cada amostra. +Observe como o Nextflow é capaz de processar múltiplos métodos de segmentação em paralelo, tornando fácil comparar resultados. + +### 3.4. Visualizar relatórios de execução + +O Nextflow gera vários relatórios de execução automaticamente. + +Verifique o diretório pipeline_info: + +```bash +ls results/pipeline_info/ +``` + +Arquivos principais: + +- **execution_report.html**: Visualização de linha do tempo e uso de recursos +- **execution_timeline.html**: Gráfico de Gantt da execução de processos +- **execution_trace.txt**: Métricas detalhadas de execução de tarefas +- **pipeline_dag.html**: Grafo acíclico dirigido mostrando a estrutura do fluxo de trabalho + +Abra o relatório de execução para ver o uso de recursos: + +```bash +code results/pipeline_info/execution_report.html +``` + +Isso mostra: + +- Quanto tempo cada processo levou +- Uso de CPU e memória +- Quais tarefas foram armazenadas em cache vs. executadas + +!!! Tip + + Esses relatórios são incrivelmente úteis para otimizar alocação de recursos e solucionar problemas de desempenho. + +### Conclusão + +Você sabe como localizar saídas do pipeline, examinar relatórios de controle de qualidade e acessar métricas de execução. + +### O que vem a seguir? + +Aprenda sobre o diretório de trabalho e como o Nextflow gerencia arquivos intermediários. + +--- + +## 4. Explorar o diretório de trabalho + +Assim como no nosso exemplo Hello World, todo o trabalho real acontece no diretório `work/`. + +### 4.1. Entendendo a estrutura do diretório de trabalho + +O diretório de trabalho contém um subdiretório para cada tarefa que foi executada. +Para este pipeline com 12 tarefas, haverá 12 subdiretórios de trabalho. + +Liste o diretório de trabalho: + +```bash +ls -d work/*/*/ | head -5 +``` + +Isso mostra os primeiros 5 diretórios de tarefas. + +### 4.2. Inspecionar um diretório de tarefa + +Escolha um dos hashes de processo de segmentação da saída do console (ex.: `[3m/4n5o6p]`) e olhe dentro: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Você verá: + +- **Arquivos .command.\***: Scripts e logs de execução do Nextflow (como antes) +- **Arquivos de entrada preparados**: Links simbólicos para os arquivos de entrada reais +- **Arquivos de saída**: Máscaras de segmentação, resultados intermediários, etc. + +A diferença principal do Hello World: + +- Pipelines reais preparam arquivos de entrada grandes (imagens, dados de referência) +- Arquivos de saída podem ser bastante grandes (máscaras de segmentação, imagens processadas) +- Múltiplos arquivos de entrada e saída por tarefa + +!!! Tip + + Se um processo falhar, você pode navegar até seu diretório de trabalho, examinar `.command.err` para mensagens de erro e até mesmo executar `.command.sh` manualmente para depurar o problema. + +### 4.3. Limpeza do diretório de trabalho + +O diretório de trabalho pode se tornar bastante grande ao longo de múltiplas execuções do pipeline. +Como aprendemos na Parte 1, você pode usar `nextflow clean` para remover diretórios de trabalho de execuções antigas. + +No entanto, para pipelines nf-core com arquivos intermediários grandes, é especialmente importante limpar regularmente. + +### Conclusão + +Você entende como os pipelines nf-core organizam seus diretórios de trabalho e como inspecionar tarefas individuais para depuração. + +### O que vem a seguir? + +Aprenda sobre o cache do Nextflow e como retomar execuções de pipeline que falharam. + +--- + +## 5. Retomar uma execução de pipeline + +Um dos recursos mais poderosos do Nextflow é a capacidade de retomar um pipeline do ponto de falha. + +### 5.1. O mecanismo de cache + +Quando você executa um pipeline com `-resume`, o Nextflow: + +1. Verifica o cache para cada tarefa +2. Se as entradas, código e parâmetros são idênticos, reutiliza o resultado em cache +3. Apenas executa novamente as tarefas que mudaram ou falharam + +Isso é essencial para pipelines de longa duração onde falhas podem ocorrer tarde na execução. + +### 5.2. Tentar resume com molkart + +Execute o mesmo comando novamente, mas adicione `-resume`: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Você deve ver uma saída como: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Observe `cached: 2` ou `cached: 1` para cada processo - nada foi executado novamente! + +### 5.3. Quando resume é útil + +Resume é particularmente valioso quando: + +- Um pipeline falha devido a limites de recursos (memória insuficiente, limite de tempo excedido) +- Você precisa modificar processos posteriores sem executar novamente etapas anteriores +- Sua conexão de rede cai durante o download de dados +- Você quer adicionar saídas adicionais sem refazer a computação + +!!! Warning + + Resume só funciona se você não alterou os dados de entrada, código do pipeline ou parâmetros. + Se você alterar qualquer um destes, o Nextflow irá corretamente executar novamente as tarefas afetadas. + +### Conclusão + +Você sabe como usar `-resume` para executar pipelines de forma eficiente sem repetir tarefas bem-sucedidas. + +### O que vem a seguir? + +Agora que você pode executar nf-core/molkart com dados de teste, você está pronto para aprender como configurá-lo para seus próprios conjuntos de dados. diff --git a/docs/pt/docs/nf4_science/imaging/03_inputs.md b/docs/pt/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..4232bed1a7 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Parte 3: Organizando entradas + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Na Parte 2, executamos o molkart com múltiplos parâmetros na linha de comando. +Agora vamos aprender duas abordagens melhores para gerenciar entradas: **arquivos de parâmetros** e **planilhas de amostras**. + +## 1. Usando arquivos de parâmetros + +### 1.1. O problema com linhas de comando longas + +Lembre-se do nosso comando da Parte 2: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Isso funciona, mas é difícil de reproduzir, compartilhar ou modificar. +E se você precisar executar a mesma análise novamente no próximo mês? +E se um colaborador quiser usar suas configurações exatas? + +### 1.2. Solução: Use um arquivo de parâmetros + +Crie um arquivo chamado `params.yaml`: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Agora seu comando se torna: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +É isso! O arquivo de parâmetros documenta sua configuração exata e facilita a reexecução ou compartilhamento. + +### 1.3. Sobrescrevendo parâmetros + +Você ainda pode sobrescrever parâmetros específicos da linha de comando: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +A linha acima altera o `segmentation_method` para `stardist` e o nome do `--outdir` para `stardist_results` em vez dos parâmetros no arquivo `params.yaml`. +Além disso, você pode ver que a flag `-resume` nos permitiu reutilizar os resultados de pré-processamento da execução anterior, economizando tempo. +Você pode usar esse padrão para testar rapidamente diferentes variações do fluxo de trabalho. + +### Conclusão + +Arquivos de parâmetros tornam suas análises reproduzíveis e fáceis de compartilhar. +Use-os para qualquer trabalho de análise real. + +### O que vem a seguir? + +Aprenda como as planilhas de amostras organizam informações sobre múltiplas amostras. + +--- + +## 2. O padrão de planilha de amostras + +### 2.1. O que é uma planilha de amostras? + +Uma planilha de amostras é um arquivo CSV que descreve suas amostras de entrada. +Cada linha é uma amostra, e as colunas especificam os arquivos e metadados para aquela amostra. + +Vamos olhar a planilha de amostras que estamos usando: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +As colunas são: + +- `sample`: Identificador único da amostra +- `nuclear_image`: Imagem de coloração nuclear (TIFF) +- `spot_table`: Pontos de transcrição (TXT) +- `membrane_image`: Imagem de coloração de membrana (TIFF, opcional) + +### 2.2. Caminhos de arquivos + +Planilhas de amostras aceitam múltiplos tipos de caminho: + +- **URLs**: Nextflow baixa automaticamente (como mostrado acima) +- **Caminhos locais**: `data/nuclear.tiff` ou `/absolute/path/to/nuclear.tiff` +- **Armazenamento em nuvem**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Você pode misturar tipos de caminho na mesma planilha de amostras. + +### 2.3. Criando sua própria planilha de amostras + +Primeiro, vamos baixar os arquivos de dados de teste localmente: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Agora vamos modificar a planilha de amostras para referenciar esses arquivos locais: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Aviso" + + Observe que os caminhos na planilha de amostras são relativos a onde você **executa** o Nextflow, não onde a planilha de amostras está localizada. + +Finalmente, vamos executar o nf-core/molkart mais uma vez com a planilha de amostras com caminhos de arquivos locais: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Como você pode ver, o Nextflow executa essa execução de forma similar a quando os arquivos foram baixados do Github. Esta é uma das grandes funcionalidades do Nextflow, ele prepara os dados adequadamente para você, independentemente de onde estão localizados. + +### Conclusão + +Planilhas de amostras organizam conjuntos de dados com múltiplas amostras de uma forma que permite definir explicitamente seus metadados junto com os caminhos dos arquivos. +A maioria dos fluxos de trabalho do nf-core usa esse padrão. + +### O que vem a seguir? + +Agora que cobrimos as entradas, vamos explorar como configurar fluxos de trabalho Nextflow para diferentes ambientes computacionais. diff --git a/docs/pt/docs/nf4_science/imaging/04_config.md b/docs/pt/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..b923dfb3a1 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Parte 4: Configuração + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nas Partes 1-3, aprendemos como executar Nextflow, executar um pipeline nf-core e gerenciar entradas com arquivos de parâmetros e samplesheets. +Agora vamos explorar como configurar pipelines para diferentes ambientes de computação usando **arquivos de configuração** e **profiles**. + +## Objetivos de aprendizagem + +Ao final desta parte, você será capaz de: + +- Entender como o Nextflow resolve a configuração de múltiplas fontes +- Usar profiles integrados do nf-core para contêineres e testes +- Criar profiles personalizados para diferentes ambientes de computação +- Personalizar solicitações de recursos usando process labels +- Gerenciar limites de recursos em ambientes restritos +- Inspecionar a configuração resolvida com `nextflow config` + +--- + +## 1. Entendendo a configuração do Nextflow + +### 1.1. O que é um arquivo de configuração? + +O Nextflow usa arquivos de configuração para separar a **lógica do fluxo de trabalho** (o que fazer) das **configurações de execução** (como e onde fazer). + +Arquivos de configuração controlam: + +- Engines de contêineres (Docker, Singularity, Conda) +- Recursos computacionais (CPUs, memória, tempo) +- Plataformas de execução (local, HPC, nuvem) +- Parâmetros do pipeline + +### 1.2. Precedência de configuração + +O Nextflow carrega a configuração de múltiplas fontes, com fontes posteriores sobrescrevendo as anteriores: + +1. **Configuração do pipeline**: `nextflow.config` no repositório do pipeline +2. **Configuração do diretório**: `nextflow.config` no seu diretório de trabalho atual +3. **Configuração do usuário**: `~/.nextflow/config` +4. **Linha de comando**: Parâmetros e opções passados diretamente + +Esta abordagem em camadas permite manter valores padrão no pipeline, sobrescrever com configurações específicas do usuário e fazer ajustes rápidos na linha de comando. + +### 1.3. Nossa configuração atual + +Vamos olhar a configuração que estivemos usando: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Vamos comentar ou alterar de volta a linha `docker.enabled = true` da Parte 2, e descobrir como podemos alcançar o mesmo resultado usando um profile no molkart. + +--- + +## 2. Usando profiles + +### 2.1. O que são profiles? + +Profiles são conjuntos nomeados de configuração que podem ser ativados com a flag `-profile` via o comando `nextflow run`. +Eles facilitam a alternância entre diferentes cenários de computação sem editar arquivos de configuração. + +Todos os pipelines nf-core vêm com diversos profiles padrão que podemos usar. + +### 2.2. Inspecionando profiles integrados + +Vamos inspecioná-los no arquivo `molkart/nextflow.config` associado à base de código do pipeline: + +```bash +code molkart/nextflow.config +``` + +Procure pelo bloco `profiles`: + +```groovy title="molkart/nextflow.config (trecho)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Profiles de contêineres comuns: + +- `docker`: Usa contêineres Docker (mais comum para desenvolvimento local) +- `singularity`: Usa Singularity/Apptainer (comum em HPC) +- `conda`: Usa ambientes Conda +- `apptainer`: Usa contêineres Apptainer + +### 2.3. Re-executando com profiles ao invés de nextflow.config + +Agora que desabilitamos a configuração do docker no nosso arquivo `nextflow.config` local e entendemos profiles, vamos re-executar o pipeline usando a flag `-profile`. + +Anteriormente na Parte 3, criamos um arquivo `params.yaml` com nossos parâmetros personalizados. +Agora podemos combinar isso com o profile Docker integrado: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Vamos detalhar o que cada flag faz: + +- `-profile docker`: Ativa o profile Docker do `nextflow.config` do molkart, que define `docker.enabled = true` +- `-params-file params.yaml`: Carrega todos os parâmetros do pipeline do nosso arquivo YAML +- `-resume`: Reutiliza resultados em cache de execuções anteriores + +Como estamos usando `-resume`, o Nextflow vai verificar se algo mudou desde a última execução. +Se os parâmetros, entradas e código forem os mesmos, todas as tarefas serão recuperadas do cache e o pipeline será concluído quase instantaneamente. + +```console title="Saída (trecho)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Note que todos os processos mostram `cached: 2` ou `cached: 1` - nada foi re-executado! + +### 2.4. Profiles de teste + +Profiles de teste fornecem maneiras rápidas de especificar parâmetros de entrada padrão e arquivos de dados para permitir que você verifique se o pipeline funciona. +Pipelines nf-core sempre incluirão pelo menos dois profiles de teste: + +- `test`: Dataset pequeno com parâmetros rápidos para testes rápidos +- `test_full`: Teste mais abrangente com dados maiores + +Vamos dar uma olhada mais de perto no profile `test` no molkart que é incluído usando a diretiva `includeConfig`: + +```groovy title="molkart/nextflow.config (trecho)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Isso significa que sempre que executamos o pipeline com `-profile test`, o Nextflow carregará a configuração de `conf/test.config`. + +```groovy title="molkart/conf/test.config (trecho)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Note que este profile contém os mesmos parâmetros que usamos no nosso arquivo `params.yaml` anteriormente. + +Você pode ativar múltiplos profiles separando-os com vírgulas. +Vamos usar isso para testar nosso pipeline sem precisar do nosso arquivo params: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Isso combina: + +- `docker`: Habilita contêineres Docker +- `test`: Usa dataset e parâmetros de teste + +Profiles são aplicados da esquerda para a direita, então profiles posteriores sobrescrevem os anteriores se definirem os mesmos valores. + +### Conclusão + +Pipelines nf-core vêm com profiles integrados para contêineres, testes e ambientes especiais. +Você pode combinar múltiplos profiles para construir a configuração que precisa. + +### Próximos passos + +Aprenda como criar seus próprios profiles personalizados para diferentes ambientes de computação. + +--- + +## 3. Criando profiles personalizados + +### 3.1. Criar profiles para alternar entre desenvolvimento local e execução em HPC + +Vamos criar profiles personalizados para dois cenários: + +1. Desenvolvimento local com Docker +2. HPC universitário com agendador Slurm e Singularity + +Adicione o seguinte ao seu `nextflow.config`: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Agora você pode alternar entre ambientes facilmente: + +```bash +# Para desenvolvimento local +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# Para HPC (quando disponível) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! note "Nota" + + Não podemos testar o profile HPC neste ambiente de treinamento, já que não temos acesso a um agendador Slurm. + Mas isso mostra como você configuraria para uso no mundo real. + +### 3.2. Use `nextflow config` para inspecionar a configuração + +O comando `nextflow config` mostra a configuração totalmente resolvida sem executar o pipeline. + +Visualize a configuração padrão: + +```bash +nextflow config ./molkart +``` + +Visualize a configuração com um profile específico: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Isso é extremamente útil para: + +- Depurar problemas de configuração +- Entender quais valores serão realmente usados +- Verificar como múltiplos profiles interagem + +### Conclusão + +Profiles personalizados permitem que você alterne entre diferentes ambientes de computação com uma única flag de linha de comando. +Use `nextflow config` para inspecionar a configuração resolvida antes de executar. + +### Próximos passos + +Aprenda como personalizar solicitações de recursos para processos individuais usando o sistema de process label do nf-core. + +--- + +## 4. Personalizando solicitações de recursos + +### 4.1. Entendendo process labels em pipelines nf-core + +Por simplicidade, pipelines nf-core usam [**process labels**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) para padronizar a alocação de recursos em todos os pipelines. +Cada processo é marcado com um label como `process_low`, `process_medium` ou `process_high` para descrever requisitos de recursos computacionais baixos, médios ou altos, respectivamente. +Esses labels são convertidos em solicitações de recursos específicas em um dos arquivos de configuração localizados no diretório `conf/` do pipeline. + +```groovy title="molkart/conf/base.config (trecho)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +Note o multiplicador `task.attempt` - isso permite que tentativas subsequentes de tarefas solicitem mais recursos, se o pipeline estiver definido com `process.maxRetries > 1`. + +### 4.2. Sobrescrevendo recursos para processos específicos + +Para controle refinado, direcione processos individuais pelo nome: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Se tentarmos executar este pipeline com a sobrescrita acima, o processo `CELLPOSE` solicitará 16 CPUs e 32 GB de memória ao invés do padrão definido por seu label. +Isso fará com que o pipeline falhe no nosso ambiente atual, já que não temos essa quantidade de RAM disponível. +Aprenderemos como prevenir esses tipos de falhas na próxima seção. + +!!! tip "Dica" + + Para encontrar nomes de processos, olhe a saída de execução do pipeline ou verifique `.nextflow.log`. + Nomes de processos seguem o padrão `WORKFLOW:SUBWORKFLOW:PROCESS`. + +### Conclusão + +Pipelines nf-core usam process labels para padronizar a alocação de recursos. +Você pode sobrescrever recursos por label (afeta múltiplos processos) ou por nome (afeta um processo específico). + +### Próximos passos + +Aprenda como gerenciar limites de recursos em ambientes restritos como GitHub Codespaces. + +--- + +## 5. Gerenciando recursos em ambientes restritos + +### 5.1. O problema dos limites de recursos + +Se tentássemos executar o molkart com um processo solicitando 16 CPUs e 32 GB de memória (como mostrado na seção 4.2), falharia no nosso ambiente atual porque não temos tantos recursos disponíveis. +Em um ambiente de cluster com nós maiores, tais solicitações seriam submetidas ao agendador. + +Em ambientes restritos como GitHub Codespaces, sem limites, o Nextflow se recusaria a executar processos que excedessem os recursos disponíveis. + +### 5.2. Definindo limites de recursos + +A diretiva `resourceLimits` limita as solicitações de recursos a valores especificados: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Isso diz ao Nextflow: "Se qualquer processo solicitar mais de 2 CPUs ou 7 GB de memória, limite a esses valores." + +### 5.3. Adicionando limites de recursos a profiles personalizados + +Atualize seus profiles personalizados para incluir limites apropriados: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! warning "Aviso" + + Definir limites de recursos muito baixos pode causar falhas nos processos ou execução lenta. + O pipeline pode precisar usar algoritmos menos intensivos em memória ou processar dados em pedaços menores. + +### Conclusão + +Use `resourceLimits` para executar pipelines em ambientes com recursos restritos limitando as solicitações de recursos dos processos. +Diferentes profiles podem ter diferentes limites apropriados para seu ambiente. + +### Próximos passos + +Você completou o treinamento principal de Nextflow para Bioimagem! + +--- + +## Conclusão + +Agora você entende como configurar pipelines Nextflow para diferentes ambientes de computação. + +Habilidades principais que você aprendeu: + +- **Precedência de configuração**: Como o Nextflow resolve configurações de múltiplas fontes +- **Profiles nf-core**: Usando profiles integrados para contêineres, testes e utilitários +- **Profiles personalizados**: Criando seus próprios profiles para diferentes ambientes +- **Process labels**: Entendendo e sobrescrevendo solicitações de recursos por label +- **Limites de recursos**: Gerenciando ambientes restritos com `resourceLimits` +- **Inspeção de configuração**: Usando `nextflow config` para depurar e verificar configurações + +Essas habilidades de configuração são transferíveis para qualquer pipeline Nextflow e ajudarão você a executar fluxos de trabalho de forma eficiente em máquinas locais, clusters HPC e plataformas de nuvem. + +### Próximos passos + +Parabéns por completar o curso Nextflow para Bioimagem! + +Próximos passos: + +- Preencha a pesquisa do curso para fornecer feedback +- Confira [Hello Nextflow](../hello_nextflow/index.md) para aprender mais sobre desenvolvimento de fluxos de trabalho +- Explore [Hello nf-core](../hello_nf-core/index.md) para mergulhar mais fundo nas ferramentas nf-core +- Navegue por outros cursos nas [coleções de treinamento](../training_collections/index.md) diff --git a/docs/pt/docs/nf4_science/imaging/index.md b/docs/pt/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..7e58d37ad1 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/index.md @@ -0,0 +1,40 @@ +```markdown +--- +title: Executar Nextflow para Imagens +hide: + - toc +--- + +# Executar Nextflow para Imagens + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de treinamento é destinado a pesquisadores em imagens e biologia espacial que estão interessados em executar e personalizar pipelines de análise de dados. +Ele ensina conceitos fundamentais do Nextflow relacionados à execução, organização e configuração de fluxos de trabalho usando [nf-core/molkart](https://nf-co.re/molkart), um pipeline para processar dados de transcriptômica espacial de Cartografia Molecular. +As habilidades que você aprenderá aqui são transferíveis para qualquer pipeline Nextflow ou nf-core. + +Vamos começar! Clique no botão "Open in GitHub Codespaces" abaixo para iniciar o ambiente de treinamento (de preferência em uma aba separada), depois continue lendo enquanto ele carrega. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizagem + +Ao trabalhar neste curso, você aprenderá como aplicar conceitos e ferramentas fundamentais do Nextflow para executar pipelines de análise de imagens. + +Ao final deste workshop você será capaz de: + +- Executar um fluxo de trabalho Nextflow localmente e monitorar a execução +- Encontrar e interpretar saídas (resultados) e arquivos de log gerados pelo Nextflow +- Executar um pipeline nf-core com dados de teste e entradas personalizadas +- Configurar a execução do pipeline usando perfis e arquivos de parâmetros +- Gerenciar entradas usando planilhas de amostras e parâmetros de linha de comando + +## Público e pré-requisitos + +Este curso pressupõe alguma familiaridade mínima com o seguinte: + +- Experiência com a linha de comando +- Familiaridade básica com formatos de arquivo de imagem (imagens TIFF, dados tabulares) + +Para requisitos técnicos e configuração do ambiente, consulte o mini-curso [Configuração do Ambiente](../../envsetup/). +``` diff --git a/docs/pt/docs/nf4_science/imaging/next_steps.md b/docs/pt/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..49bdc2d123 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Próximos passos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns por concluir o treinamento Nextflow para Bioimaging! + +Agora você possui as habilidades fundamentais para executar e configurar pipelines Nextflow para análise de dados de imagem. + +## Continue aprendendo + +Aqui estão alguns próximos passos recomendados para aprofundar seu conhecimento em Nextflow: + +### Explore mais pipelines nf-core + +- **Navegue por todos os pipelines**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Desenvolva seus próprios pipelines + +Se você quer aprender a escrever pipelines Nextflow: + +- **[Hello Nextflow](../../hello_nextflow/)**: Treinamento abrangente de desenvolvimento Nextflow +- **[Side Quests](../../side_quests/)**: Tópicos avançados para desenvolvedores de pipeline + +### Participe da comunidade + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Obtenha ajuda e conecte-se com outros usuários +- **[nf-core Slack](https://nf-co.re/join)**: Participe da comunidade nf-core +- **[Seqera Community Forum](https://community.seqera.io)**: Faça perguntas e compartilhe experiências + +### Recursos adicionais + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Documentação de referência completa +- **[nf-core Documentation](https://nf-co.re/docs)**: Diretrizes e melhores práticas + +## Envolva-se + +- **Contribua com nf-core**: Ajude a melhorar pipelines ou documentação +- **Compartilhe seus fluxos de trabalho**: Contribua com seus próprios pipelines para a comunidade +- **Participe de eventos**: Junte-se ao Nextflow Summit e sessões de treinamento da comunidade + +Obrigado por aprender conosco! diff --git a/docs/pt/docs/nf4_science/imaging/survey.md b/docs/pt/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..bbf31eb956 --- /dev/null +++ b/docs/pt/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Questionário + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Obrigado por completar o treinamento Nextflow para Bioimagem! + +Agradecemos muito o seu feedback para nos ajudar a melhorar este material de treinamento. + +Por favor, reserve alguns minutos para completar nossa breve pesquisa: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Suas respostas nos ajudarão a entender o que funcionou bem e o que podemos melhorar para futuros alunos. + +Obrigado pelo seu tempo e participação! diff --git a/docs/pt/docs/nf4_science/index.md b/docs/pt/docs/nf4_science/index.md new file mode 100644 index 0000000000..e2a3e6fc2f --- /dev/null +++ b/docs/pt/docs/nf4_science/index.md @@ -0,0 +1,43 @@ +--- +title: Nextflow para Ciência +hide: + - toc +--- + +# Nextflow para Ciência + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Estes são cursos que demonstram como aplicar os conceitos e componentes apresentados no curso para iniciantes [Hello Nextflow](../hello_nextflow/) a casos de uso científicos específicos. Cada curso consiste em uma série de módulos de treinamento projetados para ajudar os alunos a desenvolver suas habilidades progressivamente. + +!!! exercise "Nextflow para Genômica" + + !!! tip inline end "" + + :material-run-fast: Aprenda a desenvolver um pipeline para genômica em Nextflow. + + Este é um curso para pesquisadores que desejam aprender como desenvolver seus próprios pipelines de genômica. O curso usa um caso de uso de chamada de variantes para demonstrar como desenvolver um pipeline de genômica simples, mas funcional. + + [Iniciar o treinamento Nextflow para Genômica :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "Nextflow para RNAseq" + + !!! tip inline end "" + + :material-run-fast: Aprenda a desenvolver um pipeline para processamento de dados RNAseq em Nextflow. + + Este é um curso para pesquisadores que desejam aprender como desenvolver seus próprios pipelines de RNAseq. O curso usa um caso de uso de processamento de RNAseq em bulk para demonstrar como desenvolver um pipeline de RNAseq simples, mas funcional. + + [Iniciar o treinamento Nextflow para RNAseq :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Nextflow para Bioimagem" + + !!! tip inline end "" + + :material-run-fast: Aprenda a executar pipelines para dados de imagem em Nextflow. + + Este é um curso para pesquisadores que desejam aprender como executar e configurar pipelines de bioimagem. O curso usa nf-core/molkart para demonstrar padrões essenciais de uso do Nextflow aplicáveis a qualquer pipeline. + + [Iniciar o treinamento Nextflow para Bioimagem :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Informe-nos quais outros domínios e casos de uso você gostaria de ver abordados aqui, postando na [seção de Treinamento](https://community.seqera.io/c/training/) do fórum da comunidade. diff --git a/docs/pt/docs/nf4_science/rnaseq/00_orientation.md b/docs/pt/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..8fc5bc1219 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Orientação + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +O ambiente de treinamento contém todo o software, código e dados necessários para trabalhar neste curso de treinamento, então você não precisa instalar nada por conta própria. +No entanto, você precisa de uma conta (gratuita) para fazer login, e deve dedicar alguns minutos para se familiarizar com a interface. + +Se você ainda não o fez, por favor complete o mini-curso de [Configuração do Ambiente](../../envsetup/) antes de prosseguir. + +## Materiais fornecidos + +Ao longo deste curso de treinamento, trabalharemos no diretório `nf4-science/rnaseq/`, para o qual você precisa se mover ao abrir o espaço de trabalho de treinamento. +Este diretório contém todos os arquivos de código, dados de teste e arquivos acessórios que você precisará. + +Sinta-se à vontade para explorar o conteúdo deste diretório; a maneira mais fácil de fazer isso é usar o explorador de arquivos no lado esquerdo do espaço de trabalho de treinamento na interface do VSCode. +Como alternativa, você pode usar o comando `tree`. +Ao longo do curso, usamos a saída do `tree` para representar a estrutura e o conteúdo do diretório de forma legível, às vezes com pequenas modificações para maior clareza. + +Aqui geramos um índice de conteúdo até o segundo nível: + +```bash +tree . -L 3 +``` + +??? success "Conteúdo do diretório" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + Não se preocupe se isso parecer muito; vamos passar pelas partes relevantes em cada etapa do curso. + Isso é apenas para dar uma visão geral. + +**Aqui está um resumo do que você deve saber para começar:** + +- **O arquivo `rnaseq.nf`** é o esboço do script do fluxo de trabalho que desenvolveremos. + +- **O arquivo `nextflow.config`** é um arquivo de configuração que define propriedades mínimas do ambiente. Você pode ignorá-lo por enquanto. + +- **O diretório `data`** contém dados de entrada e recursos relacionados: + + - _Um genoma de referência_ chamado `genome.fa` consistindo de uma pequena região do cromossomo humano 20 (de hg19/b37). + - _Dados de RNAseq_ que foram reduzidos a uma pequena região para manter os tamanhos de arquivo menores, no diretório `reads/`. + - _Arquivos CSV_ listando os IDs e caminhos dos arquivos de dados de exemplo, para processamento em lotes. + +- **O diretório `solutions`** contém os scripts de fluxo de trabalho completos e módulos que resultam de cada etapa do curso. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + O número no nome do arquivo corresponde à etapa da parte relevante do curso. + +!!!tip + + Se por algum motivo você sair deste diretório, você sempre pode executar este comando para retornar a ele: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Agora, para começar o curso, clique na seta no canto inferior direito desta página. diff --git a/docs/pt/docs/nf4_science/rnaseq/01_method.md b/docs/pt/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..3ac3a5d4a8 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Parte 1: Visão geral do método e teste manual + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Existem múltiplos métodos válidos para processar e analisar dados de RNAseq em bulk. +Para este curso, estamos seguindo o método descrito [aqui](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) pelos Drs. Simon Andrews e Laura Biggins no [Babraham Institute](https://www.babraham.ac.uk/). + +Nosso objetivo é desenvolver um fluxo de trabalho que implementa as seguintes etapas de processamento: executar controle de qualidade inicial nas leituras de uma amostra de RNAseq em bulk, remover sequências de adaptadores das leituras, alinhar as leituras a um genoma de referência e produzir um relatório abrangente de controle de qualidade (QC). + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** Realizar QC nos dados de leitura antes da remoção usando FastQC +- **TRIM_GALORE:** Remover sequências de adaptadores e realizar QC após a remoção usando Trim Galore (agrupa Cutadapt e FastQC) +- **HISAT2_ALIGN:** Alinhar leituras ao genoma de referência usando Hisat2 +- **MULTIQC:** Gerar um relatório abrangente de QC usando MultiQC + +No entanto, antes de mergulharmos na escrita de qualquer código de fluxo de trabalho, vamos testar os comandos manualmente em alguns dados de teste. +As ferramentas que precisamos não estão instaladas no ambiente GitHub Codespaces, então vamos usá-las via contêineres (veja [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Nota" + + Certifique-se de estar no diretório `nf4-science/rnaseq`. A última parte do caminho mostrada quando você digita `pwd` deve ser `rnaseq`. + +--- + +## 1. QC inicial e remoção de adaptadores + +Vamos baixar uma imagem de contêiner que tem tanto `fastqc` quanto `trim_galore` instalados, iniciá-la interativamente e executar os comandos de remoção e QC em um dos arquivos de dados de exemplo. + +### 1.1. Baixar o contêiner + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Isso fornece a seguinte saída no console enquanto o sistema baixa a imagem: + +??? success "Saída do comando" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Iniciar o contêiner interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Saída do comando" + + ```console + + ``` +--> + +Seu prompt mudará para algo como `(base) root@b645838b3314:/tmp#`, o que indica que você está agora dentro do contêiner. + +A parte `-v ./data:/data` do comando nos permitirá acessar o conteúdo do diretório `data/` de dentro do contêiner. + +```bash +ls /data/reads +``` + +??? success "Saída do comando" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. Executar o primeiro comando `fastqc` + +Vamos executar `fastqc` para coletar métricas de controle de qualidade nos dados de leitura. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Saída do comando" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Isso deve executar muito rapidamente. +Você pode encontrar os arquivos de saída no mesmo diretório que os dados originais: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Saída" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. Remover sequências de adaptadores com `trim_galore` + +Agora vamos executar `trim_galore`, que agrupa Cutadapt e FastQC, para remover as sequências de adaptadores e coletar métricas de QC pós-remoção. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +A flag `--fastqc` faz com que o comando execute automaticamente uma etapa de coleta de QC após a conclusão da remoção. + +_A saída é muito detalhada, então o que segue está abreviado._ + +??? success "Saída do comando" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Você pode encontrar os arquivos de saída no diretório de trabalho: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Saída" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Mover os arquivos de saída para o sistema de arquivos fora do contêiner + +Qualquer coisa que permaneça dentro do contêiner ficará inacessível para trabalhos futuros, então vamos mover estes para um novo diretório. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Sair do contêiner + +```bash +exit +``` + +--- + +## 2. Alinhar as leituras ao genoma de referência + +Vamos baixar uma imagem de contêiner que tem `hisat2` instalado, iniciá-la interativamente e executar o comando de alinhamento para alinhar os dados de RNAseq a um genoma de referência. + +### 2.1. Baixar o contêiner `hisat2` + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Saída do comando" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. Iniciar o contêiner `hisat2` interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +O comando é o mesmo de antes, com o URI do contêiner relevante substituído. + +### 2.3. Criar os arquivos de índice do genoma Hisat2 + +Hisat2 requer que a referência do genoma seja fornecida em um formato muito específico e não pode simplesmente consumir o arquivo FASTA `genome.fa` que fornecemos, então vamos aproveitar esta oportunidade para criar os recursos relevantes. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +A saída é muito detalhada, então o seguinte está abreviado: + +<!-- TODO: switch to full output --> + +??? success "Saída do comando" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Isso cria múltiplos arquivos de índice do genoma, que você pode encontrar no diretório de trabalho. + +```bash +ls genome_index.* +``` + +```console title="Saída" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Vamos usá-los daqui a pouco, mas primeiro vamos gerar um tarball compactado com gzip com esses arquivos de índice do genoma; precisaremos deles mais tarde e gerar estes não é tipicamente algo que queremos fazer como parte de um fluxo de trabalho. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Isso armazena um tarball `genome_index.tar.gz` contendo os arquivos de índice do genoma no diretório `data/` no nosso sistema de arquivos, o que será útil na Parte 2 deste curso. + +### 2.4. Executar o comando `hisat2` + +Agora podemos executar o comando de alinhamento, que realiza a etapa de alinhamento com `hisat2` e então redireciona a saída para `samtools` para escrever a saída como um arquivo BAM. + +A entrada de dados de leitura é o arquivo `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` que geramos com `trim_galore` na etapa anterior. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Saída do comando" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Isso executa quase instantaneamente porque é um arquivo de teste muito pequeno. +Em escala real, isso poderia levar muito mais tempo. + +Mais uma vez, você pode encontrar os arquivos de saída no diretório de trabalho: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Saída" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Mover os arquivos de saída para o sistema de arquivos fora do contêiner + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Sair do contêiner + +```bash +exit +``` + +--- + +## 3. Gerar um relatório abrangente de QC + +Vamos baixar uma imagem de contêiner que tem `multiqc` instalado, iniciá-la interativamente e executar um comando de geração de relatório nos arquivos de relatório FastQC antes/depois. + +### 3.1. Baixar o contêiner `multiqc` + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Saída do comando" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. Iniciar o contêiner `multiqc` interativamente + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. Executar o comando `multiqc` + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Saída do comando" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC é capaz de pesquisar em diretórios por relatórios de QC compatíveis e agregará tudo o que encontrar. + +Aqui vemos que a ferramenta encontrou todos os três relatórios de QC que geramos: o QC inicial que fizemos com `fastqc`, o relatório pós-remoção do `cutadapt` (feito via `trim_galore`) e o QC pós-alinhamento produzido por `hisat2`. + +Os arquivos de saída estão mais uma vez no diretório de trabalho: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Saída" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Mover os arquivos de saída para o sistema de arquivos fora do contêiner + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Sair do contêiner + +```bash +exit +``` + +--- + +### Conclusão + +Você testou todos os comandos individuais interativamente nos contêineres relevantes. + +### Qual é o próximo passo? + +Aprenda como encapsular esses mesmos comandos em um fluxo de trabalho de múltiplas etapas que usa contêineres para executar o trabalho. diff --git a/docs/pt/docs/nf4_science/rnaseq/02_single-sample.md b/docs/pt/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..efd22d1d48 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Parte 2: Implementação de amostra única + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta parte do curso, vamos escrever o fluxo de trabalho mais simples possível que envolve todos os comandos que executamos na Parte 1 para automatizar sua execução, e vamos processar apenas uma amostra por vez. + +Faremos isso em três etapas: + +1. Escrever um fluxo de trabalho de estágio único que executa a etapa de QC inicial +2. Adicionar a remoção de adaptadores e QC pós-remoção +3. Adicionar o alinhamento ao genoma de referência + +!!! warning "Pré-requisito" + + Você deve trabalhar na Parte 1 do curso antes de iniciar esta lição. + Especificamente, trabalhar nas seções 2.1-3 cria o arquivo de índice do genoma (`data/genome_index.tar.gz`) necessário para a etapa de alinhamento nesta lição. + +--- + +## 1. Escrever um fluxo de trabalho de estágio único que executa o QC inicial + +Vamos começar escrevendo um fluxo de trabalho simples que executa a ferramenta FastQC em um arquivo FASTQ contendo reads de RNAseq single-end. + +Fornecemos um arquivo de fluxo de trabalho, `rnaseq.nf`, que descreve as principais partes do fluxo de trabalho. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Declarações de INCLUDE de módulo + +/* + * Pipeline parameters + */ + +// Entrada primária + +workflow { + + // Cria canal de entrada + + // Chama processos + +} +``` + +Tenha em mente que este código de fluxo de trabalho está correto, mas não é funcional; seu propósito é apenas servir como um esqueleto que você usará para escrever o fluxo de trabalho real. + +### 1.1. Criar um diretório para armazenar módulos + +Vamos criar módulos independentes para cada processo para facilitar o gerenciamento e reutilização, então vamos criar um diretório para armazená-los. + +```bash +mkdir modules +``` + +### 1.2. Criar um módulo para o processo de coleta de métricas de QC + +Vamos criar um arquivo de módulo chamado `modules/fastqc.nf` para abrigar o processo `FASTQC`: + +```bash +touch modules/fastqc.nf +``` + +Abra o arquivo no editor de código e copie o seguinte código nele: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Você deve reconhecer todas as peças do que aprendeu na Parte 1 e Parte 2 desta série de treinamento; a única mudança notável é que desta vez estamos usando `mode: symlink` para a diretiva `publishDir`, e estamos usando um parâmetro para definir o `publishDir`. + +!!! note "Nota" + + Embora os arquivos de dados que estamos usando aqui sejam muito pequenos, em genômica eles podem ficar muito grandes. Para fins de demonstração no ambiente de ensino, estamos usando o modo de publicação 'symlink' para evitar cópias desnecessárias de arquivos. Você não deve fazer isso em seus fluxos de trabalho finais, pois perderá resultados quando limpar seu diretório `work`. + +### 1.3. Importar o módulo para o arquivo de fluxo de trabalho + +Adicione a instrução `include { FASTQC } from './modules/fastqc.nf'` ao arquivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declarações de INCLUDE de módulo +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Adicionar uma declaração de entrada + +Declare um parâmetro de entrada com um valor padrão: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Entrada primária + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. Criar um canal de entrada no bloco workflow + +Use uma factory de canal básica `.fromPath()` para criar o canal de entrada: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Cria canal de entrada a partir de um caminho de arquivo + read_ch = channel.fromPath(params.reads) + + // Chama processos + +} +``` + +### 1.6. Chamar o processo `FASTQC` no canal de entrada + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Cria canal de entrada a partir de um caminho de arquivo + read_ch = channel.fromPath(params.reads) + + // Controle de qualidade inicial + FASTQC(read_ch) + +} +``` + +### 1.7. Executar o fluxo de trabalho para testar se funciona + +Poderíamos usar o parâmetro `--reads` para especificar uma entrada da linha de comando, mas durante o desenvolvimento podemos ser preguiçosos e apenas usar o padrão de teste que configuramos. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Isso deve executar muito rapidamente se você trabalhou na Parte 1 e já baixou o contêiner. +Se você pulou essa parte, o Nextflow baixará o contêiner para você; você não precisa fazer nada para que isso aconteça, mas pode precisar esperar até um minuto. + +Você pode encontrar as saídas em `results/fastqc` conforme especificado no processo `FASTQC` pela diretiva `publishDir`. + +```bash +ls results/fastqc +``` + +```console title="Saída" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Adicionar remoção de adaptadores e controle de qualidade pós-remoção + +Vamos usar o wrapper Trim_Galore, que agrupa o Cutadapt para a remoção em si e o FastQC para o controle de qualidade pós-remoção. + +### 2.1. Criar um módulo para o processo de remoção e QC + +Vamos criar um arquivo de módulo chamado `modules/trim_galore.nf` para abrigar o processo `TRIM_GALORE`: + +```bash +touch modules/trim_galore.nf +``` + +Abra o arquivo no editor de código e copie o seguinte código nele: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Importar o módulo para o arquivo de fluxo de trabalho + +Adicione a instrução `include { TRIM_GALORE } from './modules/trim_galore.nf'` ao arquivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declarações de INCLUDE de módulo +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Chamar o processo no canal de entrada + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Cria canal de entrada a partir de um caminho de arquivo + read_ch = channel.fromPath(params.reads) + + // Controle de qualidade inicial + FASTQC(read_ch) + + // Corte de adaptador e QC pós-corte + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Executar o fluxo de trabalho para testar se funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Isso também deve executar muito rapidamente, já que estamos executando em um arquivo de entrada tão pequeno. + +Você pode encontrar as saídas em `results/trimming` conforme especificado no processo `TRIM_GALORE` pela diretiva `publishDir`. + +```bash +ls results/trimming +``` + +```console title="Saída" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Alinhar os reads ao genoma de referência + +Finalmente podemos executar a etapa de alinhamento do genoma usando o Hisat2, que também emitirá métricas de controle de qualidade no estilo FastQC. + +### 3.1. Criar um módulo para o processo HiSat2 + +Vamos criar um arquivo de módulo chamado `modules/hisat2_align.nf` para abrigar o processo `HISAT2_ALIGN`: + +```bash +touch modules/hisat2_align.nf +``` + +Abra o arquivo no editor de código e copie o seguinte código nele: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Importar o módulo para o arquivo de fluxo de trabalho + +Adicione a instrução `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` ao arquivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declarações de INCLUDE de módulo +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Adicionar uma declaração de parâmetro para fornecer o índice do genoma + +Declare um parâmetro de entrada com um valor padrão: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Entrada primária + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Arquivo do genoma de referência + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. Chamar o processo `HISAT2_ALIGN` nos reads processados pela saída de `TRIM_GALORE` + +Os reads processados estão no canal de saída `TRIM_GALORE.out.trimmed_reads` produzido pela etapa anterior. + +Além disso, usamos `file (params.hisat2_index_zip)` para fornecer à ferramenta Hisat2 o arquivo tarball compactado do índice do genoma. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Cria canal de entrada a partir de um caminho de arquivo + read_ch = channel.fromPath(params.reads) + + // Controle de qualidade inicial + FASTQC(read_ch) + + // Corte de adaptador e QC pós-corte + TRIM_GALORE(read_ch) + + // Alinhamento a um genoma de referência + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Executar o fluxo de trabalho para testar se funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Você pode encontrar as saídas em `results/align` conforme especificado no processo `HISAT2_ALIGN` pela diretiva `publishDir`. + +```bash +ls results/align +``` + +```console title="Saída" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Isso completa o processamento básico que precisamos aplicar a cada amostra. + +_Vamos adicionar a agregação de relatórios MultiQC na Parte 2, depois de fazer o fluxo de trabalho aceitar várias amostras de uma vez._ + +--- + +### Conclusão + +Você sabe como envolver todas as etapas principais para processar amostras de RNAseq single-end individualmente. + +### O que vem a seguir? + +Aprenda como modificar o fluxo de trabalho para processar várias amostras em paralelo, agregar relatórios de QC em todas as etapas para todas as amostras e permitir a execução do fluxo de trabalho em dados de RNAseq paired-end. diff --git a/docs/pt/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/pt/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..603cdb96aa --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Parte 3: Implementação de múltiplas amostras com dados paired-end + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nesta parte final do curso, vamos levar nosso fluxo de trabalho simples ao próximo nível, transformando-o em uma poderosa ferramenta de automação em lote para lidar com números arbitrários de amostras. +E enquanto fazemos isso, também vamos alterá-lo para esperar dados paired-end, que são mais comuns em estudos mais recentes. + +Faremos isso em três etapas: + +1. Fazer o fluxo de trabalho aceitar múltiplas amostras de entrada e paralelizar a execução +2. Adicionar geração abrangente de relatório de QC +3. Mudar para dados de RNAseq paired-end + +--- + +## 1. Fazer o fluxo de trabalho aceitar múltiplas amostras de entrada e paralelizar a execução + +Vamos precisar mudar como gerenciamos a entrada. + +### 1.1. Mudar a entrada primária para ser um CSV de caminhos de arquivos em vez de um único arquivo + +Fornecemos um arquivo CSV contendo IDs de amostra e caminhos de arquivos FASTQ no diretório `data/`. +Este arquivo CSV inclui uma linha de cabeçalho. +Note que os caminhos dos arquivos FASTQ são caminhos absolutos. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Vamos renomear o parâmetro de entrada primária para `input_csv` e mudar o valor padrão para ser o caminho para o arquivo `single-end.csv`. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Entrada primária + input_csv: Path = "data/single-end.csv" + + // Arquivo do genoma de referência + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Atualizar a fábrica de canal de entrada para lidar com um CSV como entrada + +Vamos querer carregar o conteúdo do arquivo no canal em vez de apenas o caminho do arquivo em si, então usamos o operador `.splitCsv()` para analisar o formato CSV, depois o operador `.map()` para pegar a informação específica que queremos (o caminho do arquivo FASTQ). + +```groovy title="rnaseq.nf" linenums="16" + // Cria canal de entrada a partir do conteúdo de um arquivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. Executar o fluxo de trabalho para testar se funciona + +```bash +nextflow run rnaseq.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Desta vez vemos cada etapa sendo executada 6 vezes, em cada um dos 6 arquivos de dados que fornecemos. + +Foi só isso que precisamos para fazer o fluxo de trabalho executar em múltiplos arquivos! +O Nextflow lida com todo o paralelismo para nós. + +--- + +## 2. Agregar métricas de QC de pré-processamento em um único relatório MultiQC + +Tudo isso produz muitos relatórios de QC, e não queremos ter que vasculhar relatórios individuais. +Este é o ponto perfeito para colocar uma etapa de agregação de relatório MultiQC! + +### 2.1. Criar um módulo para o processo de agregação de QC + +Vamos criar um arquivo de módulo chamado `modules/multiqc.nf` para abrigar o processo `MULTIQC`: + +```bash +touch modules/multiqc.nf +``` + +Abra o arquivo no editor de código e copie o seguinte código nele: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Importar o módulo no arquivo do fluxo de trabalho + +Adicione a instrução `include { MULTIQC } from './modules/multiqc.nf'` ao arquivo `rnaseq.nf`: + +```groovy title="rnaseq.nf" linenums="3" +// Declarações de INCLUDE de módulo +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Adicionar um parâmetro `report_id` e dar a ele um padrão sensato + +```groovy title="rnaseq.nf" linenums="9" +params { + // Entrada primária + input_csv: Path = "data/single-end.csv" + + // Arquivo do genoma de referência + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID do relatório + report_id: String = "all_single-end" +} +``` + +### 2.4. Chamar o processo nas saídas das etapas anteriores + +Precisamos dar ao processo `MULTIQC` todas as saídas relacionadas a QC das etapas anteriores. + +Para isso, vamos usar o operador `.mix()`, que agrega múltiplos canais em um único. + +Se tivéssemos quatro processos chamados A, B, C e D com um canal simples `.out` cada, a sintaxe seria assim: `A.out.mix( B.out, C.out, D.out )`. Como você pode ver, você aplica ao primeiro dos canais que deseja combinar (não importa qual) e apenas adiciona todos os outros, separados por vírgulas, nos parênteses que seguem. + +No caso do nosso fluxo de trabalho, temos as seguintes saídas para agregar: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Então o exemplo de sintaxe se torna: + +```groovy title="Aplicando .mix() na chamada MULTIQC" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Isso coletará relatórios de QC por amostra. +Mas como queremos agregá-los em todas as amostras, precisamos adicionar o operador `collect()` para reunir os relatórios de todas as amostras em uma única chamada ao `MULTIQC`. +E também precisamos dar a ele o parâmetro `report_id`. + +Isso nos dá o seguinte: + +```groovy title="A chamada MULTIQC completa" linenums="33" + // Geração de relatório de QC abrangente + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +No contexto do bloco completo do fluxo de trabalho, acaba ficando assim: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Cria canal de entrada a partir do conteúdo de um arquivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + // Controle de qualidade inicial + FASTQC(read_ch) + + // Corte de adaptador e QC pós-corte + TRIM_GALORE(read_ch) + + // Alinhamento a um genoma de referência + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Geração de relatório de QC abrangente + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. Executar o fluxo de trabalho para testar se funciona + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Desta vez vemos uma única chamada ao MULTIQC adicionada após as chamadas de processo em cache: + +Você pode encontrar as saídas em `results/trimming` conforme especificado no processo `TRIM_GALORE` pela diretiva `publishDir`. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Saída" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Esse último arquivo `all_single-end.html` é o relatório agregado completo, convenientemente empacotado em um arquivo HTML fácil de navegar. + +--- + +## 3. Habilitar o processamento de dados de RNAseq paired-end + +Agora nosso fluxo de trabalho só pode lidar com dados de RNAseq single-end. +É cada vez mais comum ver dados de RNAseq paired-end, então queremos ser capazes de lidar com isso. + +Fazer o fluxo de trabalho completamente agnóstico do tipo de dado exigiria o uso de recursos de linguagem Nextflow um pouco mais avançados, então não vamos fazer isso aqui, mas podemos fazer uma versão de processamento paired-end para demonstrar o que precisa ser adaptado. + +### 3.1. Fazer uma cópia do fluxo de trabalho chamada `rnaseq_pe.nf` + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Modificar o `input_csv` padrão para apontar para os dados paired-end + +Fornecemos um segundo arquivo CSV contendo IDs de amostra e caminhos de arquivos FASTQ pareados no diretório `data/` + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +Vamos mudar o padrão de `input_csv` para ser o caminho para o arquivo `paired-end.csv`. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Entrada primária + input_csv: Path = "data/paired-end.csv" + + // Arquivo do genoma de referência + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID do relatório + report_id: String = "all_single-end" +} +``` + +### 3.3. Atualizar a fábrica de canal + +Precisamos dizer ao operador `.map()` para pegar ambos os caminhos de arquivo FASTQ agora. + +Então `row -> file(row.fastq_path)` se torna `row -> [file(row.fastq_1), file(row.fastq_2)]` + +```groovy title="rnaseq_pe.nf" linenums="19" + // Cria canal de entrada a partir do conteúdo de um arquivo CSV + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. Fazer uma versão paired-end do processo FASTQC + +Vamos fazer uma cópia do módulo para que possamos ter ambas as versões à mão. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Abra o novo arquivo de módulo `fastqc_pe.nf` no editor de código e faça as seguintes mudanças de código: + +- Mude `fastqc $reads` para `fastqc ${reads}` no bloco `script` (linha 17) para que a entrada `reads` seja desempacotada, já que agora é uma tupla de dois caminhos em vez de um único caminho. +- Substitua `${reads.simpleName}` por um curinga (`*`) para evitar ter que lidar com os arquivos de saída individualmente. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Tecnicamente isso generaliza o processo `FASTQC` de uma forma que o torna capaz de lidar com dados de RNAseq single-end ou paired-end. + +Finalmente, atualize a instrução de importação do módulo para usar a versão paired-end do módulo. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. Fazer uma versão paired-end do processo TRIM_GALORE + +Faça uma cópia do módulo para que possamos ter ambas as versões à mão. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Abra o novo arquivo de módulo `trim_galore_pe.nf` no editor de código e faça as seguintes mudanças de código: + +- Mude a declaração de entrada de `path reads` para `tuple path(read1), path(read2)` +- Atualize o comando no bloco `script`, substituindo `$reads` por `--paired ${read1} ${read2}` +- Atualize as declarações de saída para refletir os arquivos adicionados e diferentes convenções de nomenclatura, usando curingas para evitar ter que listar tudo. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Finalmente, atualize a instrução de importação do módulo para usar a versão paired-end do módulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. Atualizar a chamada ao processo MULTIQC para esperar dois relatórios de TRIM_GALORE + +O processo `TRIM_GALORE` agora produz um canal de saída adicional, então precisamos alimentar isso ao MultiQC. + +Substitua `TRIM_GALORE.out.fastqc_reports,` por `TRIM_GALORE.out.fastqc_reports_1,` mais `TRIM_GALORE.out.fastqc_reports_2,`: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Geração de relatório de QC abrangente + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Já que estamos no MultiQC, vamos também atualizar o padrão do parâmetro `report_id` de `"all_single-end"` para `"all_paired-end"`. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Entrada primária + input_csv: Path = "data/paired-end.csv" + + // Arquivo do genoma de referência + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // ID do relatório + report_id: String = "all_paired-end" +} +``` + +### 3.7. Fazer uma versão paired-end do processo HISAT2_ALIGN + +Faça uma cópia do módulo para que possamos ter ambas as versões à mão. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Abra o novo arquivo de módulo `hisat2_align_pe.nf` no editor de código e faça as seguintes mudanças de código: + +- Mude a declaração de entrada de `path reads` para `tuple path(read1), path(read2)` +- Atualize o comando no bloco `script`, substituindo `-U $reads` por `-1 ${read1} -2 ${read2}` +- Substitua todas as instâncias de `${reads.simpleName}` por `${read1.simpleName}` no comando no bloco `script` bem como nas declarações de saída. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Finalmente, atualize a instrução de importação do módulo para usar a versão paired-end do módulo. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. Executar o fluxo de trabalho para testar se funciona + +Não usamos `-resume` já que isso não usaria cache, e há duas vezes mais dados para processar do que antes, mas ainda deve ser completado em menos de um minuto. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +E é isso! Agora temos duas versões ligeiramente divergentes do nosso fluxo de trabalho, uma para dados de leitura single-end e uma para dados paired-end. +O próximo passo lógico seria fazer o fluxo de trabalho aceitar qualquer tipo de dado dinamicamente, o que está fora do escopo deste curso, mas podemos abordar isso em um acompanhamento. + +--- + +### Conclusão + +Você sabe como adaptar um fluxo de trabalho de amostra única para paralelizar o processamento de múltiplas amostras, gerar um relatório de QC abrangente e adaptar o fluxo de trabalho para usar dados de leitura paired-end se necessário. + +### O que vem a seguir? + +Parabéns, você completou o mini-curso Nextflow Para RNAseq! Celebre seu sucesso e faça uma pausa bem merecida! + +Em seguida, pedimos que você complete uma pesquisa muito breve sobre sua experiência com este curso de treinamento, então vamos levá-lo a uma página com links para recursos de treinamento adicionais e links úteis. diff --git a/docs/pt/docs/nf4_science/rnaseq/index.md b/docs/pt/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..bf7cf96408 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,46 @@ +--- +title: Nextflow para RNAseq +hide: + - toc +--- + +# Nextflow para RNAseq + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Este curso de treinamento é destinado a pesquisadores em transcriptômica e áreas relacionadas que estão interessados em desenvolver ou personalizar pipelines de análise de dados. +Ele se baseia no treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/) e demonstra como usar Nextflow no contexto específico de análise de RNAseq bulk. + +Especificamente, este curso demonstra como implementar um pipeline simples de processamento de RNAseq bulk para remover sequências adaptadoras, alinhar as reads a um genoma de referência e realizar controle de qualidade (QC) em várias etapas. + +Vamos começar! Clique no botão "Open in GitHub Codespaces" abaixo para iniciar o ambiente de treinamento (preferencialmente em uma aba separada), depois continue lendo enquanto ele carrega. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Objetivos de aprendizagem + +Ao trabalhar neste curso, você aprenderá como aplicar conceitos e ferramentas fundamentais do Nextflow a um caso de uso típico de RNAseq. + +Ao final deste workshop, você será capaz de: + +- Escrever um fluxo de trabalho linear para aplicar métodos básicos de processamento e QC de RNAseq +- Manipular arquivos específicos do domínio, como FASTQ e recursos de genoma de referência, de forma apropriada +- Manipular dados de sequenciamento single-end e paired-end +- Aproveitar o paradigma de dataflow do Nextflow para paralelizar o processamento de RNAseq por amostra +- Agregar relatórios de QC através de múltiplas etapas e amostras usando operadores de canal relevantes + +<!-- TODO +- Configurar a execução do pipeline e gerenciar e otimizar alocações de recursos +- Implementar testes por etapa e de ponta a ponta do pipeline que lidam apropriadamente com as idiossincrasias específicas de RNAseq +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Pré-requisitos + +O curso assume alguma familiaridade mínima com o seguinte: + +- Ferramentas e formatos de arquivo comumente usados neste domínio científico +- Experiência com a linha de comando +- Conceitos e ferramentas fundamentais do Nextflow abordados no treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/) + +Para requisitos técnicos e configuração do ambiente, consulte o mini-curso [Configuração do Ambiente](../../envsetup/). diff --git a/docs/pt/docs/nf4_science/rnaseq/next_steps.md b/docs/pt/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..ee5fe0c6d9 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Próximos Passos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Parabéns novamente por concluir o curso de treinamento Nextflow para RNAseq e obrigado por completar nossa pesquisa! + +--- + +## 1. As 3 principais maneiras de aprimorar suas habilidades em Nextflow + +Aqui estão nossas três principais recomendações sobre o que fazer a seguir com base no curso que você acabou de concluir. + +### 1.1. Aplicar Nextflow a outros casos de uso de análise científica + +**Confira a página [Nextflow para Ciência](../nf4_science/index.md)** para uma lista de outros cursos curtos e independentes que demonstram como aplicar os conceitos básicos e mecanismos apresentados no Hello Nextflow a casos de uso comuns de análise científica. + +Se você não vir seu domínio representado por um caso de uso relacionável, nos avise no [fórum da Comunidade](https://community.seqera.io/) para que possamos adicioná-lo à nossa lista de desenvolvimento. + +### 1.2. Começar com nf-core + +**[nf-core](https://nf-co.re/)** é um esforço colaborativo mundial para desenvolver pipelines de código aberto padronizados para uma ampla gama de aplicações de pesquisa científica. +O projeto inclui [mais de 100 pipelines](https://nf-co.re/pipelines/) que estão disponíveis para uso imediato e [bem mais de 1400 módulos de processo](https://nf-co.re/modules/) que podem ser integrados em seus próprios projetos, além de um rico conjunto de ferramentas para desenvolvedores. + +O curso de treinamento **[Hello nf-core](../../hello_nf-core/index.md)** irá apresentá-lo aos pipelines curados pela comunidade nf-core e ao framework de desenvolvimento, projetado para ajudá-lo a escrever fluxos de trabalho reproduzíveis, escaláveis e padronizados. Você aprenderá como usar pipelines nf-core existentes, contribuir para seu desenvolvimento e até começar a construir os seus próprios, apoiado por melhores práticas e uma comunidade vibrante. Se você está pronto para aplicar suas habilidades em Nextflow em projetos do mundo real, este é o próximo passo perfeito. + +### 1.3. Dominar recursos mais avançados do Nextflow + +Nos cursos Hello, mantemos o nível de complexidade técnica baixo propositalmente para evitar sobrecarregá-lo com informações que você não precisa para começar com Nextflow. +À medida que você avança com seu trabalho, você vai querer aprender como usar o conjunto completo de recursos e o poder do Nextflow. + +Para isso, estamos atualmente trabalhando em uma **coleção de [Missões Secundárias](../side_quests/index.md)**, que são cursos curtos e independentes que se aprofundam em tópicos específicos como testes e manipulação de metadados. + +--- + +## 2. Conheça o Seqera Platform + +**[Seqera Platform](https://seqera.io/) é a melhor maneira de executar Nextflow na prática.** + +É uma plataforma baseada em nuvem desenvolvida pelos criadores do Nextflow que você pode conectar à sua própria infraestrutura de computação (seja local, HPC ou nuvem) para facilitar muito o lançamento e gerenciamento de seus fluxos de trabalho, bem como gerenciar seus dados e executar análises interativamente em um ambiente de nuvem. + +O Free Tier está disponível para uso gratuito por todos (com cotas de uso). +Acadêmicos qualificados podem obter acesso gratuito de nível Pro (sem limitações de uso) através do [Programa Acadêmico](https://seqera.io/academic/program/). + +Dê uma olhada nos [tutoriais do Seqera Platform](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) para ver se isso pode ser útil para você. + +--- + +### É isso por enquanto! + +**Boa sorte em sua jornada com Nextflow e não hesite em nos informar no [fórum da Comunidade](https://community.seqera.io/) o que mais poderíamos fazer para ajudar.** diff --git a/docs/pt/docs/nf4_science/rnaseq/survey.md b/docs/pt/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..95330677e7 --- /dev/null +++ b/docs/pt/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Pesquisa de feedback + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Antes de prosseguir, por favor complete esta breve pesquisa de 5 perguntas para avaliar o treinamento, compartilhar qualquer feedback que você possa ter sobre sua experiência e nos informar o que mais poderíamos fazer para ajudá-lo em sua jornada com Nextflow. + +Isso deve levar menos de um minuto para completar. Obrigado por nos ajudar a melhorar nossos materiais de treinamento para todos! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/pt/docs/side_quests/README.md b/docs/pt/docs/side_quests/README.md new file mode 100644 index 0000000000..512cb4efab --- /dev/null +++ b/docs/pt/docs/side_quests/README.md @@ -0,0 +1 @@ +Este é um espaço reservado para as futuras Side Quests (treinamentos aprofundados). Os documentos atualmente aqui são esboços baseados em conteúdo reaproveitado de outras fontes. diff --git a/docs/pt/docs/side_quests/debugging.md b/docs/pt/docs/side_quests/debugging.md new file mode 100644 index 0000000000..7b1e3f4c6d --- /dev/null +++ b/docs/pt/docs/side_quests/debugging.md @@ -0,0 +1,1722 @@ +# Depurando Workflows + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Depuração é uma habilidade crítica que pode economizar horas de frustração e ajudá-lo a se tornar um desenvolvedor Nextflow mais eficaz. Ao longo da sua carreira, especialmente quando você está começando, você encontrará bugs ao construir e manter seus workflows. Aprender abordagens sistemáticas de depuração ajudará você a identificar e resolver problemas rapidamente. + +### Objetivos de aprendizagem + +Nesta missão lateral, exploraremos **técnicas sistemáticas de depuração** para workflows Nextflow: + +- **Depuração de erros de sintaxe**: Usando recursos de IDE e mensagens de erro do Nextflow efetivamente +- **Depuração de canais**: Diagnosticando problemas de fluxo de dados e problemas de estrutura de canais +- **Depuração de processos**: Investigando falhas de execução e problemas de recursos +- **Ferramentas de depuração integradas**: Aproveitando o modo de visualização, execução stub e diretórios de trabalho do Nextflow +- **Abordagens sistemáticas**: Uma metodologia de quatro fases para depuração eficiente + +Ao final, você terá uma metodologia robusta de depuração que transforma mensagens de erro frustrantes em roteiros claros para soluções. + +### Pré-requisitos + +Antes de assumir esta missão lateral, você deve: + +- Ter completado o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores) + +**Opcional:** Recomendamos completar a missão lateral [Recursos de IDE para Desenvolvimento Nextflow](./ide_features.md) primeiro. +Ela cobre cobertura abrangente de recursos de IDE que suportam depuração (destaque de sintaxe, detecção de erros, etc.), que usaremos bastante aqui. + +--- + +## 0. Começando + +#### Abra o codespace de treinamento + +Se você ainda não o fez, certifique-se de abrir o ambiente de treinamento conforme descrito na [Configuração do Ambiente](../envsetup/index.md). + +[![Abrir no GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mova para o diretório do projeto + +Vamos mover para o diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/debugging +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revise os materiais + +Você encontrará um conjunto de workflows de exemplo com vários tipos de bugs que usaremos para prática: + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Esses arquivos representam cenários comuns de depuração que você encontrará no desenvolvimento real. + +#### Revise a tarefa + +Seu desafio é executar cada workflow, identificar o(s) erro(s) e corrigi-los. + +Para cada workflow com bugs: + +1. **Execute o workflow** e observe o erro +2. **Analise a mensagem de erro**: o que o Nextflow está dizendo? +3. **Localize o problema** no código usando as pistas fornecidas +4. **Corrija o bug** e verifique se sua solução funciona +5. **Restaure o arquivo** antes de passar para a próxima seção (use `git checkout <filename>`) + +Os exercícios progridem de erros de sintaxe simples para problemas de runtime mais sutis. +Soluções são discutidas inline, mas tente resolver cada um você mesmo antes de ler adiante. + +#### Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Configurei meu diretório de trabalho adequadamente +- [ ] Eu entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Erros de Sintaxe + +Erros de sintaxe são o tipo mais comum de erro que você encontrará ao escrever código Nextflow. Eles ocorrem quando o código não está conforme as regras de sintaxe esperadas do Nextflow DSL. Esses erros impedem que seu workflow seja executado, então é importante aprender a identificá-los e corrigi-los rapidamente. + +### 1.1. Chaves ausentes + +Um dos erros de sintaxe mais comuns, e às vezes um dos mais complexos de depurar, é **chaves ausentes ou incompatíveis**. + +Vamos começar com um exemplo prático. + +#### Execute o pipeline + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Elementos-chave das mensagens de erro de sintaxe:** + +- **Arquivo e localização**: Mostra qual arquivo e linha/coluna contêm o erro (`bad_syntax.nf:24:1`) +- **Descrição do erro**: Explica o que o parser encontrou que não esperava (`Unexpected input: '<EOF>'`) +- **Indicador EOF**: A mensagem `<EOF>` (End Of File) indica que o parser alcançou o fim do arquivo enquanto ainda esperava mais conteúdo - um sinal clássico de chaves não fechadas + +#### Verifique o código + +Agora, vamos examinar `bad_syntax.nf` para entender o que está causando o erro: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Chave de fechamento ausente para o processo + +workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) +} +``` + +Para o propósito deste exemplo, deixamos um comentário para você mostrar onde está o erro. A extensão Nextflow do VSCode também deve estar dando algumas dicas sobre o que pode estar errado, colocando a chave incompatível em vermelho e destacando o fim prematuro do arquivo: + +![Bad syntax](img/bad_syntax.png) + +**Estratégia de depuração para erros de chaves:** + +1. Use a correspondência de chaves do VS Code (coloque o cursor ao lado de uma chave) +2. Verifique o painel Problemas para mensagens relacionadas a chaves +3. Certifique-se de que cada `{` de abertura tem um `}` de fechamento correspondente + +#### Corrija o código + +Substitua o comentário pela chave de fechamento ausente: + +=== "Depois" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Adiciona a chave de fechamento ausente + + workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Chave de fechamento ausente para o processo + + workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +#### Execute o pipeline + +Agora execute o workflow novamente para confirmar que funciona: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Usando palavras-chave ou diretivas de processo incorretas + +Outro erro de sintaxe comum é uma **definição de processo inválida**. Isso pode acontecer se você esquecer de definir blocos obrigatórios ou usar diretivas incorretas na definição do processo. + +#### Execute o pipeline + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +O erro indica uma "Definição de processo inválida" e mostra o contexto em torno do problema. Olhando para as linhas 3-7, podemos ver `inputs:` na linha 4, que é o problema. Vamos examinar `invalid_process.nf`: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // ERROR: Should be 'input' not 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) +} +``` + +Olhando para a linha 4 no contexto do erro, podemos identificar o problema: estamos usando `inputs` em vez da diretiva correta `input`. A extensão Nextflow do VSCode também sinalizará isso: + +![Invalid process message](img/invalid_process_message.png) + +#### Corrija o código + +Substitua a palavra-chave incorreta pela correta referenciando [a documentação](https://www.nextflow.io/docs/latest/process.html#): + +=== "Depois" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Corrigido: Mudou 'inputs' para 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // ERRO: Deveria ser 'input' não 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Cria canal de entrada + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // Chama o processo com o canal de entrada + PROCESS_FILES(input_ch) + } + ``` + +#### Execute o pipeline + +Agora execute o workflow novamente para confirmar que funciona: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Usando nomes de variáveis ruins + +Os nomes de variáveis que você usa em seus blocos de script devem ser válidos, derivados de entradas ou de código groovy inserido antes do script. Mas quando você está lidando com complexidade no início do desenvolvimento do pipeline, é fácil cometer erros na nomeação de variáveis, e o Nextflow vai avisar rapidamente. + +#### Execute o pipeline + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +O erro é capturado no momento da compilação e aponta diretamente para a variável indefinida na linha 17, com um cursor indicando exatamente onde está o problema. + +#### Verifique o código + +Vamos examinar `no_such_var.nf`: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +A mensagem de erro indica que a variável não é reconhecida no template do script, e lá você vê - `${undefined_var}` usado no bloco de script, mas não definido em outro lugar. + +#### Corrija o código + +Se você receber um erro 'No such variable', pode corrigi-lo definindo a variável (corrigindo nomes de variáveis de entrada ou editando código groovy antes do script), ou removendo-a do bloco de script se não for necessária: + +=== "Depois" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Removida a linha com undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Execute o pipeline + +Agora execute o workflow novamente para confirmar que funciona: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Mau uso de variáveis Bash + +Começando no Nextflow, pode ser difícil entender a diferença entre variáveis Nextflow (Groovy) e Bash. Isso pode gerar outra forma do erro de variável ruim que aparece ao tentar usar variáveis no conteúdo Bash do bloco de script. + +#### Execute o pipeline + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +O erro aponta para a linha 13 onde `${prefix}` é usado. Vamos examinar `bad_bash_var.nf` para ver o que está causando o problema: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +Neste exemplo, estamos definindo a variável `prefix` em Bash, mas em um processo Nextflow a sintaxe `$` que usamos para referenciá-la (`${prefix}`) é interpretada como uma variável Groovy, não Bash. A variável não existe no contexto Groovy, então recebemos um erro 'no such variable'. + +#### Corrija o código + +Se você quiser usar uma variável Bash, deve escapar o cifrão assim: + +=== "Depois" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +Isso diz ao Nextflow para interpretar isso como uma variável Bash. + +#### Execute o pipeline + +Agora execute o workflow novamente para confirmar que funciona: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Variáveis Groovy vs Bash" + + Para manipulações simples de variáveis como concatenação de strings ou operações de prefixo/sufixo, geralmente é mais legível usar variáveis Groovy na seção de script em vez de variáveis Bash no bloco de script: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Esta abordagem evita a necessidade de escapar cifrões e torna o código mais fácil de ler e manter. + +### 1.5. Declarações Fora do Bloco Workflow + +A extensão Nextflow do VSCode destaca problemas com a estrutura do código que causarão erros. Um exemplo comum é definir canais fora do bloco `workflow {}` - isso agora é imposto como um erro de sintaxe. + +#### Execute o pipeline + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +A mensagem de erro indica claramente o problema: declarações (como definições de canal) não podem ser misturadas com declarações de script fora de um bloco workflow ou process. + +#### Verifique o código + +Vamos examinar `badpractice_syntax.nf` para ver o que está causando o erro: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +A extensão VSCode também destacará a variável `input_ch` como sendo definida fora do bloco workflow: + +![Non-lethal syntax error](img/nonlethal.png) + +#### Corrija o código + +Mova a definição do canal para dentro do bloco workflow: + +=== "Depois" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Movido para dentro do bloco workflow + PROCESS_FILES(input_ch) + } + ``` + +=== "Antes" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variáveis no código Groovy antes do script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Execute o pipeline + +Execute o workflow novamente para confirmar que a correção funciona: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Mantenha seus canais de entrada definidos dentro do bloco workflow e, em geral, siga quaisquer outras recomendações que a extensão faça. + +### Conclusão + +Você pode identificar e corrigir erros de sintaxe sistematicamente usando mensagens de erro do Nextflow e indicadores visuais da IDE. Erros de sintaxe comuns incluem chaves ausentes, palavras-chave de processo incorretas, variáveis indefinidas e uso inadequado de variáveis Bash vs. Nextflow. A extensão VSCode ajuda a capturar muitos desses erros antes do runtime. Com essas habilidades de depuração de sintaxe em seu toolkit, você será capaz de resolver rapidamente os erros de sintaxe mais comuns do Nextflow e passar para lidar com problemas de runtime mais complexos. + +### O que vem a seguir? + +Aprenda a depurar erros de estrutura de canal mais complexos que ocorrem mesmo quando a sintaxe está correta. + +--- + +## 2. Erros de Estrutura de Canal + +Erros de estrutura de canal são mais sutis do que erros de sintaxe porque o código está sintaticamente correto, mas as formas dos dados não correspondem ao que os processos esperam. O Nextflow tentará executar o pipeline, mas pode descobrir que o número de entradas não corresponde ao que espera e falhar. Esses erros geralmente aparecem apenas no runtime e requerem compreensão dos dados fluindo através do seu workflow. + +!!! tip "Depurando Canais com `.view()`" + + Ao longo desta seção, lembre-se de que você pode usar o operador `.view()` para inspecionar o conteúdo do canal em qualquer ponto do seu workflow. Esta é uma das ferramentas de depuração mais poderosas para entender problemas de estrutura de canal. Exploraremos essa técnica em detalhes na seção 2.4, mas sinta-se livre para usá-la enquanto trabalha nos exemplos. + + ```groovy + my_channel.view() // Mostra o que está fluindo através do canal + ``` + +### 2.1. Número Errado de Canais de Entrada + +Este erro ocorre quando você passa um número diferente de canais do que um processo espera. + +#### Execute o pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +A mensagem de erro afirma claramente que a chamada esperava 1 argumento mas recebeu 2, e aponta para a linha 23. Vamos examinar `bad_number_inputs.nf`: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Processo espera apenas 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Cria dois canais separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Passing 2 channels but process expects only 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Você deve ver a chamada `PROCESS_FILES` incompatível, fornecendo múltiplos canais de entrada quando o processo define apenas um. A extensão VSCode também sublinhará a chamada do processo em vermelho e fornecerá uma mensagem de diagnóstico quando você passar o mouse: + +![Incorrect number of args message](img/incorrect_num_args.png) + +#### Corrija o código + +Para este exemplo específico, o processo espera um único canal e não requer o segundo canal, então podemos corrigi-lo passando apenas o canal `samples_ch`: + +=== "Depois" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Processo espera apenas 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Cria dois canais separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Corrigido: Passa apenas o canal que o processo espera + PROCESS_FILES(samples_ch) + } + ``` + +=== "Antes" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Processo espera apenas 1 entrada + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Cria dois canais separados + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERRO: Passando 2 canais mas o processo espera apenas 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Execute o pipeline + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Mais comumente do que neste exemplo, você pode adicionar entradas adicionais a um processo e esquecer de atualizar a chamada do workflow de acordo, o que pode levar a este tipo de erro. Felizmente, este é um dos erros mais fáceis de entender e corrigir, já que a mensagem de erro é bastante clara sobre a incompatibilidade. + +### 2.2. Exaustão de Canal (Processo Executa Menos Vezes do que o Esperado) + +Alguns erros de estrutura de canal são muito mais sutis e não produzem erros. Provavelmente o mais comum destes reflete um desafio que novos usuários Nextflow enfrentam ao entender que canais de fila podem ser esgotados e ficar sem itens, significando que o workflow termina prematuramente. + +#### Execute o pipeline + +```bash +nextflow run exhausted.nf +``` + +??? success "Saída do comando" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Este workflow completa sem erro, mas processa apenas uma única amostra! + +#### Verifique o código + +Vamos examinar `exhausted.nf` para ver se está correto: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Define variáveis no código Groovy antes do script + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +O processo executa apenas uma vez em vez de três vezes porque o canal `reference_ch` é um canal de fila que é esgotado após a primeira execução do processo. Quando um canal é esgotado, o processo inteiro para, mesmo que outros canais ainda tenham itens. + +Este é um padrão comum onde você tem um único arquivo de referência que precisa ser reutilizado em múltiplas amostras. A solução é converter o canal de referência em um canal de valor que pode ser reutilizado indefinidamente. + +#### Corrija o código + +Existem algumas maneiras de resolver isso dependendo de quantos arquivos são afetados. + +**Opção 1**: Você tem um único arquivo de referência que está reutilizando muito. Você pode simplesmente criar um tipo de canal de valor, que pode ser usado repetidamente. Existem três maneiras de fazer isso: + +**1a** Use `channel.value()`: + +```groovy title="exhausted.nf (corrigido - Opção 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Canal de valor pode ser reutilizado + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** Use o operador `first()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#first): + +```groovy title="exhausted.nf (corrigido - Opção 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Converte para canal de valor + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** Use o operador `collect()` [operator](https://www.nextflow.io/docs/latest/reference/operator.html#collect): + +```groovy title="exhausted.nf (corrigido - Opção 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Converte para canal de valor + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Opção 2**: Em cenários mais complexos, talvez onde você tenha múltiplos arquivos de referência para todas as amostras no canal de amostras, você pode usar o operador `combine` para criar um novo canal que combine os dois canais em tuplas: + +```groovy title="exhausted.nf (corrigido - Opção 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Cria produto cartesiano + + PROCESS_FILES(combined_ch) +} +``` + +O operador `.combine()` gera um produto cartesiano dos dois canais, então cada item em `reference_ch` será pareado com cada item em `input_ch`. Isso permite que o processo execute para cada amostra enquanto ainda usa a referência. + +Isso requer que a entrada do processo seja ajustada. No nosso exemplo, o início da definição do processo precisaria ser ajustado da seguinte forma: + +```groovy title="exhausted.nf (corrigido - Opção 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Esta abordagem pode não ser adequada em todas as situações. + +#### Execute o pipeline + +Tente uma das correções acima e execute o workflow novamente: + +```bash +nextflow run exhausted.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Você deve agora ver todas as três amostras sendo processadas em vez de apenas uma. + +### 2.3. Estrutura de Conteúdo de Canal Errada + +Quando os workflows atingem um certo nível de complexidade, pode ser um pouco difícil acompanhar as estruturas internas de cada canal, e as pessoas comumente geram incompatibilidades entre o que o processo espera e o que o canal realmente contém. Isso é mais sutil do que o problema que discutimos anteriormente, onde o número de canais estava incorreto. Neste caso, você pode ter o número correto de canais de entrada, mas a estrutura interna de um ou mais desses canais não corresponde ao que o processo espera. + +#### Execute o pipeline + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Saída do comando" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +Os colchetes na mensagem de erro fornecem a pista aqui - o processo está tratando a tupla como um único valor, o que não é o que queremos. Vamos examinar `bad_channel_shape.nf`: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Espera valor único, recebe tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Você pode ver que estamos gerando um canal composto de tuplas: `['sample1', 'file1.txt']`, mas o processo espera um único valor, `val sample_name`. O comando executado mostra que o processo está tentando criar um arquivo chamado `[sample3, file3.txt]_output.txt`, que não é a saída pretendida. + +#### Corrija o código + +Para corrigir isso, se o processo requer ambas as entradas, poderíamos ajustar o processo para aceitar uma tupla: + +=== "Opção 1: Aceitar tupla no processo" + + === "Depois" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Corrigido: Aceita tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Antes" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Espera valor único, recebe tupla + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Opção 2: Extrair primeiro elemento" + + === "Depois" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Corrigido: Extrai primeiro elemento + } + ``` + + === "Antes" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Execute o pipeline + +Escolha uma das soluções e execute novamente o workflow: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Técnicas de Depuração de Canal + +#### Usando `.view()` para Inspeção de Canal + +A ferramenta de depuração mais poderosa para canais é o operador `.view()`. Com `.view()`, você pode entender a forma dos seus canais em todos os estágios para ajudar na depuração. + +#### Execute o pipeline + +Execute `bad_channel_shape_viewed.nf` para ver isso em ação: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Verifique o código + +Vamos examinar `bad_channel_shape_viewed.nf` para ver como `.view()` é usado: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debug: Mostra conteúdo original do canal + .map { tuple -> tuple[0] } // Transforma: Extrai primeiro elemento + .view { "After mapping: $it" } // Debug: Mostra conteúdo do canal transformado + + PROCESS_FILES(input_ch) +} +``` + +#### Corrija o código + +Para evitar usar operações `.view()` excessivamente no futuro para entender o conteúdo do canal, é aconselhável adicionar alguns comentários para ajudar: + +```groovy title="bad_channel_shape_viewed.nf (com comentários)" linenums="16" hl_lines="8 9" +workflow { + + // Canal emite tuplas, mas o processo espera valores únicos + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Isso se tornará mais importante à medida que seus workflows crescem em complexidade e a estrutura do canal se torna mais opaca. + +#### Execute o pipeline + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Conclusão + +Muitos erros de estrutura de canal podem ser criados com sintaxe Nextflow válida. Você pode depurar erros de estrutura de canal compreendendo o fluxo de dados, usando operadores `.view()` para inspeção e reconhecendo padrões de mensagem de erro como colchetes indicando estruturas de tupla inesperadas. + +### O que vem a seguir? + +Aprenda sobre erros criados por definições de processo. + +--- + +## 3. Erros de Estrutura de Processo + +A maioria dos erros que você encontrará relacionados a processos estará relacionada a erros que você cometeu na formação do comando, ou a problemas relacionados ao software subjacente. Dito isso, similarmente aos problemas de canal acima, você pode cometer erros na definição do processo que não se qualificam como erros de sintaxe, mas que causarão erros no runtime. + +### 3.1. Arquivos de Saída Ausentes + +Um erro comum ao escrever processos é fazer algo que gera uma incompatibilidade entre o que o processo espera e o que é gerado. + +#### Execute o pipeline + +```bash +nextflow run missing_output.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +A mensagem de erro indica que o processo esperava produzir um arquivo de saída chamado `sample3.txt`, mas o script realmente cria `sample3_output.txt`. Vamos examinar a definição do processo em `missing_output.nf`: + +```groovy title="missing_output.nf" linenums="3" hl_lines="6 10" +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Espera: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Cria: sample3_output.txt + """ +} +``` + +Você deve ver que há uma incompatibilidade entre o nome do arquivo de saída no bloco `output:` e o usado no script. Esta incompatibilidade faz com que o processo falhe. Se você encontrar esse tipo de erro, volte e verifique se as saídas correspondem entre sua definição de processo e seu bloco de saída. + +Se o problema ainda não estiver claro, verifique o próprio diretório de trabalho para identificar os arquivos de saída reais criados: + +```bash +❯ ls -h work/02/9604d49fb8200a74d737c72a6c98ed +sample3_output.txt +``` + +Para este exemplo, isso destacaria para nós que um sufixo `_output` está sendo incorporado ao nome do arquivo de saída, contrário à nossa definição `output:`. + +#### Corrija o código + +Corrija a incompatibilidade tornando o nome do arquivo de saída consistente: + +=== "Depois" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" // Corrigido: Corresponde à saída do script + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + ``` + +=== "Antes" + + ```groovy title="missing_output.nf" hl_lines="6 10" linenums="3" + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}.txt" // Espera: sample3.txt + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt // Cria: sample3_output.txt + """ + } + ``` + +#### Execute o pipeline + +```bash +nextflow run missing_output.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [elated_hamilton] DSL2 - revision: 961938ee2b + + executor > local (3) + [16/1c437c] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +### 3.2. Software ausente + +Outra classe de erros ocorre devido a erros no provisionamento de software. `missing_software.nf` é um workflow sintaticamente válido, mas depende de algum software externo para fornecer o comando `cowpy` que ele usa. + +#### Execute o pipeline + +```bash +nextflow run missing_software.nf +``` + +??? failure "Saída do comando" + + ```console hl_lines="12 18" + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Process `PROCESS_FILES (3)` terminated with an error exit status (127) + + + Command executed: + + cowpy sample3 > sample3_output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/side-quests/debugging/work/82/42a5bfb60c9c6ee63ebdbc2d51aa6e + + Tip: you can try to figure out what's wrong by changing to the process work directory and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +O processo não tem acesso ao comando que estamos especificando. Às vezes isso ocorre porque um script está presente no diretório `bin` do workflow, mas não foi tornado executável. Outras vezes é porque o software não está instalado no contêiner ou ambiente onde o workflow está sendo executado. + +#### Verifique o código + +Fique atento ao código de saída `127` - ele diz exatamente qual é o problema. Vamos examinar `missing_software.nf`: + +```groovy title="missing_software.nf" linenums="3" hl_lines="3" +process PROCESS_FILES { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + cowpy ${sample_name} > ${sample_name}_output.txt + """ +} +``` + +#### Corrija o código + +Fomos um pouco desonestos aqui, e na verdade não há nada de errado com o código. Só precisamos especificar a configuração necessária para executar o processo de forma que ele tenha acesso ao comando em questão. Neste caso, o processo tem uma definição de contêiner, então tudo o que precisamos fazer é executar o workflow com Docker habilitado. + +#### Execute o pipeline + +Configuramos um perfil Docker para você em `nextflow.config`, então você pode executar o workflow com: + +```bash +nextflow run missing_software.nf -profile docker +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_software.nf` [awesome_stonebraker] DSL2 - revision: 0296d12839 + + executor > local (3) + [38/ab20d1] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +!!! note + + Para aprender mais sobre como o Nextflow usa contêineres, veja [Hello Nextflow](../hello_nextflow/05_hello_containers.md) + +### 3.3. Má configuração de recursos + +No uso em produção, você estará configurando recursos em seus processos. Por exemplo, `memory` define a quantidade máxima de memória disponível para seu processo, e se o processo exceder isso, seu agendador normalmente matará o processo e retornará um código de saída de `137`. Não podemos demonstrar isso aqui porque estamos usando o executor `local`, mas podemos mostrar algo similar com `time`. + +#### Execute o pipeline + +`bad_resources.nf` tem configuração de processo com um limite não realista de tempo de 1 milissegundo: + +```bash +nextflow run bad_resources.nf -profile docker +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_resources.nf` [disturbed_elion] DSL2 - revision: 27d2066e86 + + executor > local (3) + [c0/ded8e1] PROCESS_FILES (3) | 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (2)' + + Caused by: + Process exceeded running time limit (1ms) + + Command executed: + + cowpy sample2 > sample2_output.txt + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/53/f0a4cc56d6b3dc2a6754ff326f1349 + + Container: + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +#### Verifique o código + +Vamos examinar `bad_resources.nf`: + +```groovy + +``` diff --git a/docs/pt/docs/side_quests/dev_environment.md b/docs/pt/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..9e8e4c19a2 --- /dev/null +++ b/docs/pt/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Ambiente de Desenvolvimento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ambientes de Desenvolvimento Integrados (IDEs) modernos podem transformar dramaticamente sua experiência de desenvolvimento com Nextflow. Este side quest foca especificamente em aproveitar o VS Code e sua extensão Nextflow para escrever código mais rapidamente, detectar erros precocemente e navegar workflows complexos de forma eficiente. + +!!! note "Este não é um tutorial tradicional" + + Ao contrário de outros módulos de treinamento, este guia é organizado como uma coleção de dicas rápidas, sugestões e exemplos práticos em vez de um tutorial passo a passo. Cada seção pode ser explorada independentemente com base em seus interesses e necessidades atuais de desenvolvimento. Sinta-se à vontade para pular entre seções e focar nos recursos que serão mais imediatamente úteis para o desenvolvimento do seu fluxo de trabalho. + +## O que você deve saber primeiro + +Este guia assume que você completou o curso de treinamento [Hello Nextflow](../hello_nextflow/) e está confortável com conceitos fundamentais do Nextflow, incluindo: + +- **Estrutura básica de fluxo de trabalho**: Compreensão de processos, fluxos de trabalho e como eles se conectam +- **Operações de canal**: Criação de canais, passagem de dados entre processos e uso de operadores básicos +- **Módulos e organização**: Criação de módulos reutilizáveis e uso de declarações include +- **Fundamentos de configuração**: Uso do `nextflow.config` para parâmetros, diretivas de processo e perfis + +## O que você aprenderá aqui + +Este guia foca em **recursos de produtividade do IDE** que tornarão você um desenvolvedor Nextflow mais eficiente: + +- **Destaque de sintaxe avançado**: Compreender o que o VS Code está mostrando sobre a estrutura do seu código +- **Autocompletar inteligente**: Aproveitar sugestões sensíveis ao contexto para escrever código mais rapidamente +- **Detecção de erros e diagnósticos**: Capturar erros de sintaxe antes de executar seu fluxo de trabalho +- **Navegação de código**: Mover-se rapidamente entre processos, módulos e definições +- **Formatação e organização**: Manter estilo de código consistente e legível +- **Desenvolvimento assistido por IA** (opcional): Usar ferramentas modernas de IA integradas ao seu IDE + +!!! info "Por que recursos de IDE agora?" + + Você provavelmente já estava usando o VS Code durante o curso [Hello Nextflow](../hello_nextflow/), mas mantivemos o foco no aprendizado dos fundamentos do Nextflow em vez dos recursos do IDE. Agora que você está confortável com conceitos básicos do Nextflow como processos, fluxos de trabalho, canais e módulos, você está pronto para aproveitar os recursos sofisticados do IDE que o tornarão um desenvolvedor mais eficiente. + + Pense nisso como "subir de nível" seu ambiente de desenvolvimento - o mesmo editor que você tem usado possui capacidades muito mais poderosas que se tornam verdadeiramente valiosas uma vez que você entende com o que elas estão te ajudando. + +--- + +## 0. Configuração e Aquecimento + +Vamos configurar um espaço de trabalho especificamente para explorar recursos do IDE: + +```bash title="Navegue para o diretório de recursos do IDE" +cd side-quests/ide_features +``` + +Abra este diretório no VS Code: + +```bash title="Abra o VS Code no diretório atual" +code . +``` + +O diretório `ide_features` contém fluxos de trabalho de exemplo que demonstram vários recursos do IDE: + +```bash title="Mostre a estrutura de diretórios" +tree . +``` + +```console title="Estrutura do projeto" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "Sobre os Arquivos de Exemplo" + + - `basic_workflow.nf` é um fluxo de trabalho básico funcional que você pode executar e modificar + - `complex_workflow.nf` é projetado apenas para ilustração para demonstrar recursos de navegação - pode não executar com sucesso, mas mostra uma estrutura de fluxo de trabalho realista com múltiplos arquivos + +### Atalhos de Teclado + +Alguns dos recursos neste guia usarão atalhos de teclado opcionais. Você pode estar acessando este material via GitHub Codespaces no navegador, e neste caso às vezes os atalhos não funcionarão como esperado porque são usados para outras coisas no seu sistema. + +Se você estiver executando o VS Code localmente, como provavelmente estará quando realmente escrever fluxos de trabalho, os atalhos funcionarão conforme descrito. + +Se você estiver usando um Mac, alguns (não todos) atalhos de teclado usarão "cmd" em vez de "ctrl", e indicaremos isso no texto como `Ctrl/Cmd`. + +### 0.1. Instalando a Extensão Nextflow + +!!! note "Já Usando Devcontainers?" + + Se você estiver trabalhando no **GitHub Codespaces** ou usando um **devcontainer local**, a extensão Nextflow provavelmente já está instalada e configurada para você. Você pode pular as etapas de instalação manual abaixo e prosseguir diretamente para explorar os recursos da extensão. + +Para instalar a extensão manualmente: + +1. Abra o VS Code +2. Vá para a visualização de Extensões clicando no ícone de extensões à esquerda: ![ícone de extensões](img/extensions_icon.png) (atalho `Ctrl/Cmd+Shift+X` se você estiver executando o VSCode localmente) +3. Procure por "Nextflow" +4. Instale a extensão oficial do Nextflow + +![Instalar Extensão Nextflow](img/install_extension.png) + +### 0.2. Layout do Espaço de Trabalho + +Como você tem usado o VS Code durante o Hello Nextflow, você já está familiarizado com o básico. Aqui está como organizar seu espaço de trabalho eficientemente para esta sessão: + +- **Área do Editor**: Para visualizar e editar arquivos. Você pode dividir isso em vários painéis para comparar arquivos lado a lado. +- **Explorador de Arquivos** clique (![ícone do explorador de arquivos](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): Os arquivos e pastas locais no seu sistema. Mantenha isso aberto à esquerda para navegar entre arquivos +- **Terminal Integrado** (`Ctrl+Shift+` crase para Windows e MacOS): Um terminal para interagir com o computador na parte inferior. Use isso para executar Nextflow ou outros comandos. +- **Painel de Problemas** (`Ctrl+Shift+M`): O VS Code mostrará quaisquer erros e problemas que detectar aqui. Isso é útil para destacar questões rapidamente. + +Você pode arrastar painéis ou ocultá-los (`Ctrl/Cmd+B` para alternar a barra lateral) para personalizar seu layout enquanto trabalhamos nos exemplos. + +### Conclusão + +Você tem o VS Code configurado com a extensão Nextflow e entende o layout do espaço de trabalho para desenvolvimento eficiente. + +### Qual é o próximo passo? + +Aprenda como o destaque de sintaxe ajuda você a entender a estrutura do código Nextflow rapidamente. + +--- + +## 1. Destaque de Sintaxe e Estrutura de Código + +Agora que seu espaço de trabalho está configurado, vamos explorar como o destaque de sintaxe do VS Code ajuda você a ler e escrever código Nextflow de forma mais eficaz. + +### 1.1. Elementos de Sintaxe Nextflow + +Abra `basic_workflow.nf` para ver o destaque de sintaxe em ação: + +![Demonstração de Sintaxe](img/syntax_showcase.png) + +Observe como o VS Code destaca: + +- **Palavras-chave** (`process`, `workflow`, `input`, `output`, `script`) em cores distintas +- **Literais de string** e **parâmetros** com estilos diferentes +- **Comentários** em uma cor suave +- **Variáveis** e **chamadas de função** com ênfase apropriada +- **Blocos de código** com guias de indentação adequadas + +!!! note "Cores Dependentes do Tema" + + As cores específicas que você vê dependerão do seu tema do VS Code (modo escuro/claro), configurações de cores e quaisquer personalizações que você tenha feito. O importante é que diferentes elementos de sintaxe sejam visualmente distinguidos uns dos outros, tornando a estrutura do código mais fácil de entender independentemente do esquema de cores escolhido. + +### 1.2. Compreendendo a Estrutura de Código + +O destaque de sintaxe ajuda você a identificar rapidamente: + +- **Limites de processo**: Distinção clara entre diferentes processos +- **Blocos de entrada/saída**: Fácil de identificar definições de fluxo de dados +- **Blocos de script**: Os comandos reais sendo executados +- **Operações de canal**: Etapas de transformação de dados +- **Diretivas de configuração**: Configurações específicas do processo + +Esta organização visual se torna inestimável ao trabalhar com fluxos de trabalho complexos contendo múltiplos processos e fluxos de dados intrincados. + +### Conclusão + +Você entende como o destaque de sintaxe do VS Code ajuda você a ler a estrutura do código Nextflow e identificar diferentes elementos da linguagem para um desenvolvimento mais rápido. + +### Qual é o próximo passo? + +Aprenda como o autocompletar inteligente acelera a escrita de código com sugestões sensíveis ao contexto. + +--- + +## 2. Autocompletar Inteligente + +Os recursos de autocompletar do VS Code ajudam você a escrever código mais rapidamente e com menos erros, sugerindo opções apropriadas baseadas no contexto. + +### 2.1. Sugestões Sensíveis ao Contexto + +As opções de autocompletar variam dependendo de onde você está no seu código: + +#### Operações de Canal + +Abra `basic_workflow.nf` novamente e tente digitar `channel.` no bloco workflow: + +![Autocompletar de canal](img/autocomplete_channel.png) + +Você verá sugestões para: + +- `fromPath()` - Criar canal a partir de caminhos de arquivo +- `fromFilePairs()` - Criar canal a partir de arquivos pareados +- `of()` - Criar canal a partir de valores +- `fromSRA()` - Criar canal a partir de acessos SRA +- E muito mais... + +Isso ajuda você a encontrar rapidamente a factory de canal certa para usar sem precisar lembrar nomes exatos de métodos. + +Você também pode descobrir os operadores disponíveis para aplicar a canais. Por exemplo, digite `FASTQC.out.html.` para ver operações disponíveis: + +![Autocompletar de operações de canal](img/autocomplete_operators.png) + +#### Diretivas de Processo + +Dentro de um bloco de script de processo, digite `task.` para ver propriedades de runtime disponíveis: + +![Autocompletar de propriedades de task](img/autocomplete_task.png) + +#### Configuração + +Abra nextflow.config e digite `process.` em qualquer lugar para ver diretivas de processo disponíveis: + +![Autocompletar de configuração](img/autocomplete_config.png) + +Você verá sugestões para: + +- `executor` +- `memory` +- `cpus` + +Isso economiza tempo ao configurar processos e funciona em diferentes escopos de configuração. Por exemplo, tente digitar `docker.` para ver opções de configuração específicas do Docker. + +### Conclusão + +Você pode usar o autocompletar inteligente do VS Code para descobrir operações de canal disponíveis, diretivas de processo e opções de configuração sem memorizar sintaxe. + +### Qual é o próximo passo? + +Aprenda como a detecção de erros em tempo real ajuda você a capturar problemas antes de executar seu fluxo de trabalho, simplesmente lendo o código. + +## 3. Detecção de Erros e Diagnósticos + +A detecção de erros em tempo real do VS Code ajuda você a capturar problemas antes de executar seu fluxo de trabalho. + +### 3.1. Detecção de Erros de Sintaxe + +Vamos criar um erro deliberado para ver a detecção em ação. Abra `basic_workflow.nf` e mude o nome do processo de `FASTQC` para `FASTQ` (ou qualquer outro nome inválido). O VS Code imediatamente destacará o erro no bloco workflow com um sublinhado ondulado vermelho: + +![Sublinhado de erro](img/error_underline.png) + +### 3.2. Painel de Problemas + +Além do destaque individual de erros, o VS Code fornece um Painel de Problemas centralizado que agrega todos os erros, avisos e mensagens de informação em todo o seu espaço de trabalho. Abra-o com `Ctrl/Cmd+Shift+M` e use o ícone de filtro para mostrar apenas erros relevantes ao arquivo atual: + +![Filtrar o painel de problemas](img/active_file.png) + +Clique em qualquer problema para ir diretamente à linha problemática + +![Painel de Problemas](img/problems_panel.png) + +Corrija o erro mudando o nome do processo de volta para `FASTQC`. + +### 3.3. Padrões de Erros Comuns + +Erros comuns na sintaxe Nextflow incluem: + +- **Colchetes faltando**: `{` ou `}` não correspondidos +- **Blocos incompletos**: Seções obrigatórias ausentes em processos +- **Sintaxe inválida**: DSL Nextflow mal formado +- **Erros de digitação em palavras-chave**: Diretivas de processo escritas incorretamente +- **Incompatibilidades de canal**: Incompatibilidades de tipo + +O language server do Nextflow destaca esses problemas no Painel de Problemas. Você pode verificá-los cedo para evitar erros de sintaxe ao executar um pipeline. + +### Conclusão + +Você pode usar a detecção de erros do VS Code e o Painel de Problemas para capturar erros de sintaxe e problemas antes de executar seu fluxo de trabalho, economizando tempo e evitando frustrações. + +### Qual é o próximo passo? + +Aprenda como navegar eficientemente entre processos, módulos e definições em fluxos de trabalho complexos. + +--- + +## 4. Navegação de Código e Gerenciamento de Símbolos + +Navegação eficiente é crucial ao trabalhar com fluxos de trabalho complexos que abrangem múltiplos arquivos. Para entender isso, substitua a definição do processo em `basic_workflow.nf` com uma importação do módulo que fornecemos: + +=== "Depois" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Antes" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Ir para Definição + +Se você passar o mouse sobre um nome de processo como `FASTQC`, você verá um popup com a interface do módulo (entradas e saídas): + +![Ir para definição](img/syntax.png) + +Este recurso é particularmente valioso ao criar fluxos de trabalho, pois permite que você entenda a interface do módulo sem abrir o arquivo do módulo diretamente. + +Você pode navegar rapidamente para qualquer definição de processo, módulo ou variável usando **Ctrl/Cmd-click**. Passe o mouse sobre o link para o arquivo do módulo no topo do script e siga o link conforme sugerido: + +![Seguir link](img/follow_link.png) + +A mesma coisa funciona para nomes de processo. Volte para `basic_workflow.nf` e tente isso no nome do processo `FASTQC` no bloco workflow. Isso leva você diretamente ao nome do processo (que é o mesmo que o arquivo do módulo neste exemplo, mas poderia estar no meio de um arquivo muito maior). + +Para voltar para onde você estava, use **Alt+←** (ou **Ctrl+-** no Mac). Esta é uma maneira poderosa de explorar código sem perder sua posição. + +Agora vamos explorar a navegação em um fluxo de trabalho mais complexo usando `complex_workflow.nf` (o arquivo somente para ilustração mencionado anteriormente). Este fluxo de trabalho contém múltiplos processos definidos em arquivos de módulo separados, além de alguns inline. Embora estruturas complexas de múltiplos arquivos possam ser desafiadoras para navegar manualmente, a capacidade de pular para definições torna a exploração muito mais gerenciável. + +1. Abra `complex_workflow.nf` +2. Navegue para definições de módulo +3. Use **Alt+←** (ou **Ctrl+-**) para navegar de volta +4. Navegue para o nome do processo `FASTQC` no bloco workflow. Isso leva você diretamente ao nome do processo (que é o mesmo que o arquivo do módulo neste exemplo, mas poderia estar no meio de um arquivo muito maior). +5. Navegue de volta novamente +6. Navegue para o processo `TRIM_GALORE` no bloco workflow. Este é definido inline, então não levará você a um arquivo separado, mas ainda mostrará a definição do processo, e você ainda pode navegar de volta para onde estava. + +### 4.2. Navegação de Símbolos + +Com `complex_workflow.nf` ainda aberto, você pode obter uma visão geral de todos os símbolos no arquivo digitando `@` na barra de pesquisa no topo do VSCode (o atalho de teclado é `Ctrl/Cmd+Shift+O`, mas pode não funcionar no Codespaces). Isso abre o painel de navegação de símbolos, que lista todos os símbolos no arquivo atual: + +![Navegação de símbolos](img/symbols.png) + +Isso mostra: + +- Todas as definições de processo +- Definições de workflow (há dois workflows definidos neste arquivo) +- Definições de função + +Comece a digitar para filtrar resultados. + +### 4.3. Encontrar Todas as Referências + +Entender onde um processo ou variável é usado em toda a sua base de código pode ser muito útil. Por exemplo, se você quiser encontrar todas as referências ao processo `FASTQC`, comece navegando até sua definição. Você pode fazer isso abrindo `modules/fastqc.nf` diretamente, ou usando o recurso de navegação rápida do VS Code com `Ctrl/Cmd-click` como fizemos acima. Uma vez na definição do processo, clique com o botão direito no nome do processo `FASTQC` e selecione "Find All References" no menu de contexto para ver todas as instâncias onde ele é usado. + +![Encontrar referências](img/references.png) + +Este recurso exibe todas as instâncias onde `FASTQC` é referenciado dentro do seu espaço de trabalho, incluindo seu uso nos dois workflows distintos. Esta percepção é crucial para avaliar o impacto potencial de modificações no processo `FASTQC`. + +### 4.4. Painel Outline + +O painel Outline, localizado na barra lateral Explorer (clique ![ícone do Explorer](img/files_icon.png)), fornece uma visão geral conveniente de todos os símbolos no seu arquivo atual. Este recurso permite que você navegue e gerencie rapidamente a estrutura do seu código exibindo funções, variáveis e outros elementos-chave em uma visualização hierárquica. + +![Painel Outline](img/outline.png) + +Use o painel Outline para navegar rapidamente para diferentes partes do seu código sem usar o navegador de arquivos. + +### 4.5. Visualização DAG + +A extensão Nextflow do VS Code pode visualizar seu fluxo de trabalho como um Grafo Acíclico Direcionado (DAG). Isso ajuda você a entender o fluxo de dados e dependências entre processos. Abra `complex_workflow.nf` e clique no botão "Preview DAG" acima de `workflow {` (o segundo bloco `workflow` neste arquivo): + +![Visualização DAG](img/dag_preview.png) + +Este é apenas o workflow de 'entrada', mas você também pode visualizar o DAG para os workflows internos clicando no botão "Preview DAG" acima do workflow `RNASEQ_PIPELINE {` mais acima: + +![Visualização DAG workflow interno](img/dag_preview_inner.png) + +Para este fluxo de trabalho, você pode usar os nós no DAG para navegar até as definições de processo correspondentes no código. Clique em um nó e ele levará você à definição de processo relevante no editor. Particularmente quando um fluxo de trabalho cresce para um tamanho grande, isso pode realmente ajudá-lo a navegar pelo código e entender como os processos estão conectados. + +### Conclusão + +Você pode navegar fluxos de trabalho complexos eficientemente usando ir-para-definição, busca de símbolos, encontrar referências e visualização DAG para entender a estrutura do código e dependências. + +### Qual é o próximo passo? + +Aprenda como trabalhar efetivamente com múltiplos arquivos interconectados em projetos Nextflow maiores. + +## 5. Trabalhando com Múltiplos Arquivos + +O desenvolvimento real com Nextflow envolve trabalhar com múltiplos arquivos interconectados. Vamos explorar como o VS Code ajuda você a gerenciar projetos complexos eficientemente. + +### 5.1. Navegação Rápida de Arquivos + +Com `complex_workflow.nf` aberto, você notará que ele importa vários módulos. Vamos praticar navegação rápida entre eles. + +Pressione **Ctrl+P** (ou **Cmd+P**) e comece a digitar "fast": + +O VS Code mostrará arquivos correspondentes. Selecione `modules/fastqc.nf` para ir lá instantaneamente. Isso é muito mais rápido do que clicar no explorador de arquivos quando você sabe aproximadamente qual arquivo está procurando. + +Tente isso com outros padrões: + +- Digite "star" para encontrar o arquivo do módulo de alinhamento STAR (`star.nf`) +- Digite "utils" para encontrar o arquivo de funções utilitárias (`utils.nf`) +- Digite "config" para ir para arquivos de configuração (`nextflow.config`) + +### 5.2. Editor Dividido para Desenvolvimento Multi-arquivo + +Ao trabalhar com módulos, você frequentemente precisa ver tanto o fluxo de trabalho principal quanto as definições de módulo simultaneamente. Vamos configurar isso: + +1. Abra `complex_workflow.nf` +2. Abra `modules/fastqc.nf` em uma nova aba +3. Clique com o botão direito na aba `modules/fastqc.nf` e selecione "Split Right" +4. Agora você pode ver ambos os arquivos lado a lado + +![Editor dividido](img/split_editor.png) + +Isso é inestimável quando: + +- Verificando interfaces de módulo ao escrever chamadas de workflow, e a visualização não é suficiente +- Comparando processos similares em diferentes módulos +- Depurando fluxo de dados entre workflow e módulos + +### 5.3. Pesquisa em Todo o Projeto + +Às vezes você precisa encontrar onde padrões específicos são usados em todo o seu projeto. Pressione `Ctrl/Cmd+Shift+F` para abrir o painel de pesquisa. + +Tente pesquisar por `publishDir` em todo o espaço de trabalho: + +![Pesquisa no projeto](img/project_search.png) + +Isso mostra todo arquivo que usa diretórios de publicação, ajudando você a: + +- Entender padrões de organização de saída +- Encontrar exemplos de diretivas específicas +- Garantir consistência entre módulos + +### Conclusão + +Você pode gerenciar projetos complexos de múltiplos arquivos usando navegação rápida de arquivos, editores divididos e pesquisa em todo o projeto para trabalhar eficientemente com fluxos de trabalho e módulos. + +### Qual é o próximo passo? + +Aprenda como recursos de formatação de código e manutenção mantêm seus fluxos de trabalho organizados e legíveis. + +--- + +## 6. Formatação de Código e Manutenção + +Formatação adequada de código é essencial não apenas para estética, mas também para melhorar a legibilidade, compreensão e facilidade de atualização de fluxos de trabalho complexos. + +### 6.1. Formatação Automática em Ação + +Abra `basic_workflow.nf` e deliberadamente bagunce a formatação: + +- Remova alguma indentação: Destaque o documento inteiro e pressione `shift+tab` várias vezes para remover o máximo de indentações possível. +- Adicione espaços extras em lugares aleatórios: na declaração `channel.fromPath`, adicione 30 espaços após o `(`. +- Quebre algumas linhas de forma estranha: Adicione uma nova linha entre o operador `.view {` e a string `Processing sample:`, mas não adicione uma nova linha correspondente antes do parêntese de fechamento `}`. + +Agora pressione `Shift+Alt+F` (ou `Shift+Option+F` no MacOS) para formatar automaticamente: + +O VS Code imediatamente: + +- Corrige a indentação para mostrar a estrutura do processo claramente +- Alinha elementos similares de forma consistente +- Remove espaços em branco desnecessários +- Mantém quebras de linha legíveis + +Note que a formatação automática pode não resolver todos os problemas de estilo de código. O language server do Nextflow visa manter seu código organizado, mas também respeita suas preferências pessoais em certas áreas. Por exemplo, se você remover a indentação dentro do bloco `script` de um processo, o formatador deixará como está, já que você pode intencionalmente preferir esse estilo. + +Atualmente, não há uma imposição de estilo rigorosa para Nextflow, então o language server oferece alguma flexibilidade. No entanto, ele aplicará consistentemente regras de formatação em torno de definições de métodos e funções para manter a clareza. + +### 6.2. Recursos de Organização de Código + +#### Comentar Rapidamente + +Selecione um bloco de código no seu fluxo de trabalho e pressione **Ctrl+/** (ou **Cmd+/**) para comentá-lo: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +Isso é perfeito para: + +- Desabilitar temporariamente partes de fluxos de trabalho durante o desenvolvimento +- Adicionar comentários explicativos a operações de canal complexas +- Documentar seções de fluxo de trabalho + +Use **Ctrl+/** (ou **Cmd+/**) novamente para descomentar o código. + +#### Dobramento de Código para Visão Geral + +Em `complex_workflow.nf`, note as pequenas setas ao lado das definições de processo. Clique nelas para dobrar (colapsar) processos: + +![Dobramento de código](img/code_folding.png) + +Isso fornece uma visão geral de alto nível da estrutura do seu fluxo de trabalho sem se perder em detalhes de implementação. + +#### Correspondência de Colchetes + +Coloque seu cursor próximo a qualquer colchete `{` ou `}` e o VS Code destaca o colchete correspondente. Use **Ctrl+Shift+\\** (ou **Cmd+Shift+\\**) para pular entre colchetes correspondentes. + +Isso é crucial para: + +- Entender limites de processo +- Encontrar colchetes faltando ou extras +- Navegar estruturas de fluxo de trabalho aninhadas + +#### Seleção e Edição Multi-linha + +Para editar múltiplas linhas simultaneamente, o VS Code oferece recursos poderosos de múltiplos cursores: + +- **Seleção multi-linha**: Segure **Ctrl+Alt** (ou **Cmd+Option** para MacOS) e use as setas do teclado para selecionar múltiplas linhas +- **Indentação multi-linha**: Selecione múltiplas linhas e use **Tab** para indentar ou **Shift+Tab** para remover indentação de blocos inteiros + +Isso é particularmente útil para: + +- Indentar blocos de processo inteiros consistentemente +- Adicionar comentários a múltiplas linhas de uma vez +- Editar definições de parâmetros similares em múltiplos processos + +### Conclusão + +Você pode manter código limpo e legível usando formatação automática, recursos de comentário, dobramento de código, correspondência de colchetes e edição multi-linha para organizar fluxos de trabalho complexos eficientemente. + +### Qual é o próximo passo? + +Aprenda como o VS Code se integra ao seu fluxo de trabalho de desenvolvimento mais amplo além de apenas editar código. + +--- + +## 7. Integração com Fluxo de Trabalho de Desenvolvimento + +O VS Code se integra bem ao seu fluxo de trabalho de desenvolvimento além de apenas editar código. + +### 7.1. Integração com Controle de Versão + +!!! note "Codespaces e Integração Git" + + Se você estiver trabalhando no **GitHub Codespaces**, alguns recursos de integração Git podem não funcionar como esperado, particularmente atalhos de teclado para Controle de Código. Você também pode ter recusado abrir o diretório como um repositório Git durante a configuração inicial, o que é adequado para fins de treinamento. + +Se seu projeto é um repositório git (como este é), o VS Code mostra: + +- Arquivos modificados com indicadores coloridos +- Status Git na barra de status +- Visualizações de diff inline +- Capacidades de commit e push + +Abra o painel de Controle de Código usando o botão de controle de código (![Ícone de controle de código](img/source_control_icon.png)) (`Ctrl+Shift+G` ou `Cmd+Shift+G` se você estiver trabalhando com VSCode localmente) para ver alterações git e fazer stage de commits diretamente no editor. + +![Painel de Controle de Código](img/source_control.png) + +### 7.2. Executando e Inspecionando Fluxos de Trabalho + +Vamos executar um fluxo de trabalho e então inspecionar os resultados. No terminal integrado (`Ctrl+Shift+` crase tanto no Windows quanto no MacOS), execute o fluxo de trabalho básico: + +```bash title="Execute o fluxo de trabalho básico" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +Enquanto o fluxo de trabalho executa, você verá saída em tempo real no terminal. Após a conclusão, você pode usar o VS Code para inspecionar resultados sem sair do seu editor: + +1. **Navegar para diretórios de trabalho**: Use o explorador de arquivos ou terminal para navegar em `.nextflow/work` +2. **Abrir arquivos de log**: Clique em caminhos de arquivo de log na saída do terminal para abri-los diretamente no VS Code +3. **Inspecionar saídas**: Navegue pelos diretórios de resultados publicados no explorador de arquivos +4. **Visualizar relatórios de execução**: Abra relatórios HTML diretamente no VS Code ou no seu navegador + +Isso mantém tudo em um só lugar em vez de alternar entre múltiplas aplicações. + +### Conclusão + +Você pode integrar o VS Code com controle de versão e execução de fluxo de trabalho para gerenciar todo o seu processo de desenvolvimento a partir de uma única interface. + +### Qual é o próximo passo? + +Veja como todos esses recursos do IDE trabalham juntos no seu fluxo de trabalho de desenvolvimento diário. + +--- + +## 8. Recapitulação e notas rápidas + +Aqui estão algumas notas rápidas sobre cada um dos recursos do IDE discutidos acima: + +### 8.1. Iniciando um Novo Recurso + +1. **Abertura rápida de arquivo** (`Ctrl+P` ou `Cmd+P`) para encontrar módulos existentes relevantes +2. **Editor dividido** para visualizar processos similares lado a lado +3. **Navegação de símbolos** (`Ctrl+Shift+O` ou `Cmd+Shift+O`) para entender a estrutura do arquivo +4. **Autocompletar** para escrever novo código rapidamente + +### 8.2. Depurando Problemas + +1. **Painel de problemas** (`Ctrl+Shift+M` ou `Cmd+Shift+M`) para ver todos os erros de uma vez +2. **Ir para definição** (`Ctrl-click` ou `Cmd-click`) para entender interfaces de processo +3. **Encontrar todas as referências** para ver como processos são usados +4. **Pesquisa em todo o projeto** para encontrar padrões ou problemas similares + +### 8.3. Refatoração e Melhoria + +1. **Pesquisa em todo o projeto** (`Ctrl+Shift+F` ou `Cmd+Shift+F`) para encontrar padrões +2. **Formatação automática** (`Shift+Alt+F` ou `Shift+Option+F`) para manter consistência +3. **Dobramento de código** para focar na estrutura +4. **Integração Git** para rastrear mudanças + +--- + +## Resumo + +Você agora teve um tour rápido dos recursos do IDE do VS Code para desenvolvimento Nextflow. Essas ferramentas tornarão você significativamente mais produtivo ao: + +- **Reduzir erros** através de verificação de sintaxe em tempo real +- **Acelerar o desenvolvimento** com autocompletar inteligente +- **Melhorar a navegação** em fluxos de trabalho complexos de múltiplos arquivos +- **Manter a qualidade** através de formatação consistente +- **Melhorar a compreensão** através de destaque avançado e visualização de estrutura + +Não esperamos que você lembre de tudo, mas agora você sabe que esses recursos existem e poderá encontrá-los quando precisar. À medida que continua desenvolvendo fluxos de trabalho Nextflow, esses recursos do IDE se tornarão uma segunda natureza, permitindo que você se concentre em escrever código de alta qualidade em vez de lutar com sintaxe e estrutura. + +### Qual é o próximo passo? + +Aplique essas habilidades de IDE enquanto trabalha em outros módulos de treinamento, por exemplo: + +- **[nf-test](nf-test.md)**: Crie suítes de teste abrangentes para seus fluxos de trabalho +- **[Hello nf-core](../../hello_nf-core/)**: Construa pipelines de qualidade de produção com padrões da comunidade + +O verdadeiro poder desses recursos do IDE emerge à medida que você trabalha em projetos maiores e mais complexos. Comece a incorporá-los ao seu fluxo de trabalho gradualmente—dentro de algumas sessões, eles se tornarão uma segunda natureza e transformarão como você aborda o desenvolvimento Nextflow. + +Desde capturar erros antes que eles te desacelerem até navegar bases de código complexas com facilidade, essas ferramentas tornarão você um desenvolvedor mais confiante e eficiente. + +Bom código! diff --git a/docs/pt/docs/side_quests/essential_scripting_patterns.md b/docs/pt/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..42154b9e8f --- /dev/null +++ b/docs/pt/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,1182 @@ +# Padrões Essenciais de Script em Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow é uma linguagem de programação que roda na Máquina Virtual Java. Embora Nextflow seja construído sobre [Groovy](http://groovy-lang.org/) e compartilhe muito de sua sintaxe, Nextflow é mais do que apenas "Groovy com extensões" -- é uma linguagem autônoma com uma [sintaxe](https://nextflow.io/docs/latest/reference/syntax.html) e [biblioteca padrão](https://nextflow.io/docs/latest/reference/stdlib.html) totalmente especificadas. + +Você pode escrever muito código Nextflow sem ir além da sintaxe básica para variáveis, mapas e listas. A maioria dos tutoriais de Nextflow foca em orquestração de fluxo de trabalho (canais, processos e fluxo de dados), e você pode ir surpreendentemente longe com apenas isso. + +No entanto, quando você precisa manipular dados, analisar nomes de arquivo complexos, implementar lógica condicional ou construir fluxos de trabalho robustos para produção, ajuda pensar sobre dois aspectos distintos do seu código: **fluxo de dados** (canais, operadores, processos e fluxos de trabalho) e **scripting** (o código dentro de closures, funções e scripts de processo). Embora essa distinção seja um tanto arbitrária—é tudo código Nextflow—ela fornece um modelo mental útil para entender quando você está orquestrando seu pipeline versus quando você está manipulando dados. Dominar ambos melhora dramaticamente sua capacidade de escrever fluxos de trabalho claros e de fácil manutenção. + +### Objetivos de aprendizagem + +Esta missão secundária leva você em uma jornada prática desde conceitos básicos até padrões prontos para produção. +Vamos transformar um fluxo de trabalho simples de leitura de CSV em um pipeline sofisticado de bioinformática, evoluindo-o passo a passo através de desafios realistas: + +- **Entendendo limites:** Distinguir entre operações de fluxo de dados e scripting, e entender como eles trabalham juntos +- **Manipulação de dados:** Extrair, transformar e subconjuntos de mapas e coleções usando operadores poderosos +- **Processamento de strings:** Analisar esquemas complexos de nomenclatura de arquivos com padrões regex e dominar interpolação de variáveis +- **Funções reutilizáveis:** Extrair lógica complexa em funções nomeadas para fluxos de trabalho mais limpos e de fácil manutenção +- **Lógica dinâmica:** Construir processos que se adaptam a diferentes tipos de entrada e usar closures para alocação dinâmica de recursos +- **Roteamento condicional:** Rotear inteligentemente amostras através de diferentes processos com base em suas características de metadados +- **Operações seguras:** Lidar graciosamente com dados ausentes usando operadores seguros contra null e validar entradas com mensagens de erro claras +- **Handlers baseados em configuração:** Usar handlers de eventos de fluxo de trabalho para logging, notificações e gerenciamento de ciclo de vida + +### Pré-requisitos + +Antes de iniciar esta missão secundária, você deve: + +- Ter concluído o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos de Nextflow (processos, canais, operadores, trabalhar com arquivos, metadados) +- Ter familiaridade básica com construções comuns de programação (variáveis, mapas, listas) + +Este tutorial explicará conceitos de programação conforme os encontramos, então você não precisa de experiência extensa em programação. +Começaremos com conceitos fundamentais e construiremos até padrões avançados. + +--- + +## 0. Começando + +#### Abrir o codespace de treinamento + +Se você ainda não o fez, certifique-se de abrir o ambiente de treinamento conforme descrito em [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mover para o diretório do projeto + +Vamos mover para o diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Revisar os materiais + +Você encontrará um arquivo de fluxo de trabalho principal e um diretório `data` contendo arquivos de dados de exemplo. + +```console title="Conteúdo do diretório" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Nosso CSV de exemplo contém informações sobre amostras biológicas que precisam de processamento diferente com base em suas características: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Usaremos este conjunto de dados realista para explorar técnicas práticas de programação que você encontrará em fluxos de trabalho reais de bioinformática. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Defini meu diretório de trabalho apropriadamente +<!-- - [ ] I understand the assignment --> + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Fluxo de Dados vs Scripting: Entendendo os Limites + +### 1.1. Identificando o Que É o Quê + +Ao escrever fluxos de trabalho Nextflow, é importante distinguir entre **fluxo de dados** (como os dados se movem através de canais e processos) e **scripting** (o código que manipula dados e toma decisões). Vamos construir um fluxo de trabalho demonstrando como eles trabalham juntos. + +#### 1.1.1. Fluxo de Trabalho Básico Nextflow + +Comece com um fluxo de trabalho simples que apenas lê o arquivo CSV (já fizemos isso para você em `main.nf`): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +O bloco `workflow` define nossa estrutura de pipeline, enquanto `channel.fromPath()` cria um canal a partir de um caminho de arquivo. O operador `.splitCsv()` processa o arquivo CSV e converte cada linha em uma estrutura de dados de mapa. + +Execute este fluxo de trabalho para ver os dados brutos do CSV: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Adicionando o Operador Map + +Agora vamos adicionar scripting para transformar os dados, usando o operador `.map()` que você provavelmente já conhece. Este operador recebe uma 'closure' onde podemos escrever código para transformar cada item. + +!!! note + + Uma **closure** é um bloco de código que pode ser passado adiante e executado depois. Pense nela como uma função que você define inline. Closures são escritas com chaves `{ }` e podem receber parâmetros. Elas são fundamentais para como os operadores Nextflow funcionam e, se você tem escrito Nextflow há algum tempo, pode já ter estado usando-as sem perceber! + +Aqui está como essa operação map se parece: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +Esta é nossa primeira **closure** - uma função anônima que você pode passar como argumento (similar a lambdas em Python ou arrow functions em JavaScript). Closures são essenciais para trabalhar com operadores Nextflow. + +A closure `{ row -> return row }` recebe um parâmetro `row` (poderia ser qualquer nome: `item`, `sample`, etc.). + +Quando o operador `.map()` processa cada item do canal, ele passa esse item para sua closure. Aqui, `row` contém uma linha CSV por vez. + +Aplique esta mudança e execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +Você verá a mesma saída de antes, porque estamos simplesmente retornando a entrada inalterada. Isso confirma que o operador map está funcionando corretamente. Agora vamos começar a transformar os dados. + +#### 1.1.3. Criando uma Estrutura de Dados Map + +Agora vamos escrever lógica de **scripting** dentro de nossa closure para transformar cada linha de dados. É aqui que processamos itens de dados individuais em vez de orquestrar fluxo de dados. + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformação de dados + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +O mapa `sample_meta` é uma estrutura de dados chave-valor (como dicionários em Python, objetos em JavaScript, ou hashes em Ruby) armazenando informações relacionadas: ID da amostra, organismo, tipo de tecido, profundidade de sequenciamento e pontuação de qualidade. + +Usamos métodos de manipulação de string como `.toLowerCase()` e `.replaceAll()` para limpar nossos dados, e métodos de conversão de tipo como `.toInteger()` e `.toDouble()` para converter dados string do CSV nos tipos numéricos apropriados. + +Aplique esta mudança e execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Adicionando Lógica Condicional + +Agora vamos adicionar mais scripting - desta vez usando um operador ternário para tomar decisões baseadas em valores de dados. + +Faça a seguinte mudança: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +O operador ternário é uma forma abreviada de uma instrução if/else que segue o padrão `condição ? valor_se_verdadeiro : valor_se_falso`. Esta linha significa: "Se a qualidade for maior que 40, use 'high', caso contrário use 'normal'". Seu primo, o **operador Elvis** (`?:`), fornece valores padrão quando algo é null ou vazio - exploraremos esse padrão mais tarde neste tutorial. + +O operador de adição de mapa `+` cria um **novo mapa** em vez de modificar o existente. Esta linha cria um novo mapa que contém todos os pares chave-valor de `sample_meta` mais a nova chave `priority`. + +!!! Note + + Nunca modifique mapas passados em closures - sempre crie novos usando `+` (por exemplo). No Nextflow, os mesmos dados frequentemente fluem através de múltiplas operações simultaneamente. Modificar um mapa in-place pode causar efeitos colaterais imprevisíveis quando outras operações referenciam esse mesmo objeto. Criar novos mapas garante que cada operação tenha sua própria cópia limpa. + +Execute o fluxo de trabalho modificado: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Adicionamos com sucesso lógica condicional para enriquecer nossos metadados com um nível de prioridade baseado em pontuações de qualidade. + +#### 1.1.5. Criando Subconjuntos de Mapas com `.subMap()` + +Enquanto o operador `+` adiciona chaves a um mapa, às vezes você precisa fazer o oposto - extrair apenas chaves específicas. O método `.subMap()` é perfeito para isso. + +Vamos adicionar uma linha para criar uma versão simplificada de nossos metadados que contém apenas campos de identificação: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformação de dados + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Apenas campos de ID: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Scripting para transformação de dados + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Execute o fluxo de trabalho modificado: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Apenas campos de ID: [id:sample_001, organism:human, tissue:liver] + Apenas campos de ID: [id:sample_002, organism:mouse, tissue:brain] + Apenas campos de ID: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Isso mostra tanto os metadados completos exibidos pela operação `view()` quanto o subconjunto extraído que imprimimos com `println`. + +O método `.subMap()` recebe uma lista de chaves e retorna um novo mapa contendo apenas essas chaves. Se uma chave não existe no mapa original, ela simplesmente não é incluída no resultado. + +Isso é particularmente útil quando você precisa criar diferentes versões de metadados para diferentes processos - alguns podem precisar de metadados completos enquanto outros precisam apenas de campos mínimos de identificação. + +Agora remova essas instruções println para restaurar seu fluxo de trabalho ao estado anterior, já que não precisamos delas daqui para frente. + +!!! tip "Resumo de Operações com Map" + + - **Adicionar chaves**: `map1 + [new_key: value]` - Cria novo mapa com chaves adicionais + - **Extrair chaves**: `map1.subMap(['key1', 'key2'])` - Cria novo mapa com apenas as chaves especificadas + - **Ambas as operações criam novos mapas** - Mapas originais permanecem inalterados + +#### 1.1.6. Combinando Mapas e Retornando Resultados + +Até agora, apenas retornamos o que a comunidade Nextflow chama de 'meta map', e ignoramos os arquivos aos quais esses metadados se relacionam. Mas se você está escrevendo fluxos de trabalho Nextflow, provavelmente quer fazer algo com esses arquivos. + +Vamos gerar uma estrutura de canal compreendendo uma tupla de 2 elementos: o mapa de metadados enriquecido e o caminho de arquivo correspondente. Este é um padrão comum em Nextflow para passar dados para processos. + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Aplique esta mudança e execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Essa estrutura de tupla `[meta, file]` é um padrão comum em Nextflow para passar tanto metadados quanto arquivos associados para processos. + +!!! note + + **Mapas e Metadados**: Mapas são fundamentais para trabalhar com metadados no Nextflow. Para uma explicação mais detalhada sobre trabalhar com mapas de metadados, veja a missão secundária [Trabalhando com metadados](./metadata.md). + +Nosso fluxo de trabalho demonstra o padrão central: **operações de fluxo de dados** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) orquestram como os dados se movem através do pipeline, enquanto **scripting** (mapas `[key: value]`, métodos de string, conversões de tipo, operadores ternários) dentro da closure `.map()` lida com a transformação de itens de dados individuais. + +### 1.2. Entendendo Diferentes Tipos: Channel vs List + +Até aqui, tudo bem, podemos distinguir entre operações de fluxo de dados e scripting. Mas e quando o mesmo nome de método existe em ambos os contextos? + +Um exemplo perfeito é o método `collect`, que existe tanto para tipos de canal quanto para tipos List na biblioteca padrão Nextflow. O método `collect()` em uma List transforma cada elemento, enquanto o operador `collect()` em um canal reúne todas as emissões do canal em um canal de item único. + +Vamos demonstrar isso com alguns dados de exemplo, começando por refrescar o que o operador `collect()` de canal faz. Confira `collect.nf`: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - agrupa múltiplas emissões de canal em uma +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Item individual do canal: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} itens agrupados em 1)" } +``` + +Passos: + +- Definir uma List de IDs de amostra +- Criar um canal com `fromList()` que emite cada ID de amostra separadamente +- Imprimir cada item com `view()` conforme ele flui +- Reunir todos os itens em uma única lista com o operador `collect()` do canal +- Imprimir o resultado coletado (item único contendo todos os IDs de amostra) com um segundo `view()` + +Mudamos a estrutura do canal, mas não mudamos os dados em si. + +Execute o fluxo de trabalho para confirmar isso: + +```bash +nextflow run collect.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Item individual do canal: sample_001 + Item individual do canal: sample_002 + Item individual do canal: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 itens agrupados em 1) + ``` + +`view()` retorna uma saída para cada emissão de canal, então sabemos que esta única saída contém todos os 3 itens originais agrupados em uma lista. + +Agora vamos ver o método `collect` em uma List em ação. Modifique `collect.nf` para aplicar o método `collect` da List à lista original de IDs de amostra: + +=== "Depois" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiplas emissões de canal em uma + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Item individual do canal: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} itens agrupados em 1)" } + + // List.collect() - transforma cada elemento, preserva estrutura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} itens transformados em ${formatted_ids.size()})" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiplas emissões de canal em uma + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Item individual do canal: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} itens agrupados em 1)" } + ``` + +Neste novo trecho nós: + +- Definimos uma nova variável `formatted_ids` que usa o método `collect` da List para transformar cada ID de amostra na lista original +- Imprimimos o resultado usando `println` + +Execute o fluxo de trabalho modificado: + +```bash +nextflow run collect.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + Resultado de List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 itens transformados em 3) + Item individual do canal: sample_001 + Item individual do canal: sample_002 + Item individual do canal: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 itens agrupados em 1) + ``` + +Desta vez, NÃO mudamos a estrutura dos dados, ainda temos 3 itens na lista, mas transformamos cada item usando o método `collect` da List para produzir uma nova lista com valores modificados. Isso é similar a usar o operador `map` em um canal, mas está operando em uma estrutura de dados List em vez de um canal. + +`collect` é um caso extremo que estamos usando aqui para enfatizar um ponto. A lição chave é que quando você está escrevendo fluxos de trabalho, sempre distinga entre **estruturas de dados** (Lists, Maps, etc.) e **canais** (construções de fluxo de dados). Operações podem compartilhar nomes mas se comportar completamente diferente dependendo do tipo em que são chamadas. + +### 1.3. O Operador Spread (`*.`) - Atalho para Extração de Propriedades + +Relacionado ao método `collect` da List está o operador spread (`*.`), que fornece uma maneira concisa de extrair propriedades de coleções. É essencialmente açúcar sintático para um padrão comum de `collect`. + +Vamos adicionar uma demonstração ao nosso arquivo `collect.nf`: + +=== "Depois" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiplas emissões de canal em uma + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Item individual do canal: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} itens agrupados em 1)" } + + // List.collect() - transforma cada elemento, preserva estrutura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} itens transformados em ${formatted_ids.size()})" + + // Operador spread - acesso conciso a propriedades + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Resultado do operador spread: ${all_ids}" + ``` + +=== "Antes" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - agrupa múltiplas emissões de canal em uma + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Item individual do canal: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "Resultado de channel.collect(): ${list} (${list.size()} itens agrupados em 1)" } + + // List.collect() - transforma cada elemento, preserva estrutura + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "Resultado de List.collect(): ${formatted_ids} (${sample_ids.size()} itens transformados em ${formatted_ids.size()})" + ``` + +Execute o fluxo de trabalho atualizado: + +```bash title="Testar operador spread" +nextflow run collect.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + Resultado de List.collect(): [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 itens transformados em 3) + Resultado do operador spread: [s1, s2, s3] + Item individual do canal: sample_001 + Item individual do canal: sample_002 + Item individual do canal: sample_003 + Resultado de channel.collect(): [sample_001, sample_002, sample_003] (3 itens agrupados em 1) + ``` + +O operador spread `*.` é um atalho para um padrão comum de collect: + +```groovy +// Estes são equivalentes: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Também funciona com chamadas de método: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +O operador spread é particularmente útil quando você precisa extrair uma única propriedade de uma lista de objetos - é mais legível do que escrever a closure `collect` completa. + +!!! tip "Quando Usar Spread vs Collect" + + - **Use spread (`*.`)** para acesso simples a propriedades: `samples*.id`, `files*.name` + - **Use collect** para transformações ou lógica complexa: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Conclusão + +Nesta seção, você aprendeu: + +- **Fluxo de dados vs scripting**: Operadores de canal orquestram como os dados fluem através do seu pipeline, enquanto scripting transforma itens de dados individuais +- **Entendendo tipos**: O mesmo nome de método (como `collect`) pode se comportar diferentemente dependendo do tipo em que é chamado (Channel vs List) +- **Contexto importa**: Sempre esteja ciente se você está trabalhando com canais (fluxo de dados) ou estruturas de dados (scripting) + +Entender esses limites é essencial para debugging, documentação e escrever fluxos de trabalho de fácil manutenção. + +A seguir vamos nos aprofundar em capacidades de processamento de strings, que são essenciais para lidar com dados do mundo real. + +--- + +## 2. Processamento de Strings e Geração Dinâmica de Scripts + +Dominar o processamento de strings separa fluxos de trabalho frágeis de pipelines robustos. Esta seção cobre análise de nomes de arquivo complexos, geração dinâmica de scripts e interpolação de variáveis. + +### 2.1. Correspondência de Padrões e Expressões Regulares + +Arquivos de bioinformática frequentemente têm convenções de nomenclatura complexas que codificam metadados. Vamos extrair isso automaticamente usando correspondência de padrões com expressões regulares. + +Vamos retornar ao nosso fluxo de trabalho `main.nf` e adicionar alguma lógica de correspondência de padrões para extrair informações adicionais da amostra de nomes de arquivo. Os arquivos FASTQ em nosso conjunto de dados seguem convenções de nomenclatura estilo Illumina com nomes como `SAMPLE_001_S1_L001_R1_001.fastq.gz`. Estes podem parecer crípticos, mas na verdade codificam metadados úteis como ID da amostra, número de lane e direção de leitura. Vamos usar capacidades regex para analisar esses nomes. + +Faça a seguinte mudança em seu fluxo de trabalho `main.nf` existente: + +=== "Depois" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Scripting para transformação de dados + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Scripting para transformação de dados + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Isso demonstra **conceitos chave de processamento de strings**: + +1. **Literais de expressão regular** usando sintaxe `~/padrão/` - isso cria um padrão regex sem precisar escapar barras invertidas +2. **Correspondência de padrões** com o operador `=~` - isso tenta corresponder uma string a um padrão regex +3. **Objetos Matcher** que capturam grupos com `[0][1]`, `[0][2]`, etc. - `[0]` refere-se à correspondência inteira, `[1]`, `[2]`, etc. referem-se a grupos capturados entre parênteses + +Vamos detalhar o padrão regex `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$`: + +| Padrão | Corresponde | Captura | +| ------------------- | ------------------------------------------- | ----------------------------------- | +| `^(.+)` | Nome da amostra desde o início | Grupo 1: nome da amostra | +| `_S(\d+)` | Número da amostra `_S1`, `_S2`, etc. | Grupo 2: número da amostra | +| `_L(\d{3})` | Número da lane `_L001` | Grupo 3: lane (3 dígitos) | +| `_(R[12])` | Direção de leitura `_R1` ou `_R2` | Grupo 4: direção de leitura | +| `_(\d{3})` | Número do chunk `_001` | Grupo 5: chunk (3 dígitos) | +| `\.fastq(?:\.gz)?$` | Extensão de arquivo `.fastq` ou `.fastq.gz` | Não capturado (?: é não-capturante) | + +Isso analisa convenções de nomenclatura estilo Illumina para extrair metadados automaticamente. + +Execute o fluxo de trabalho modificado: + +```bash title="Testar correspondência de padrões" +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Isso mostra os metadados enriquecidos a partir dos nomes de arquivo. + +### 2.2. Geração Dinâmica de Scripts em Processos + +Blocos script de processo são essencialmente strings multi-linha que são passadas para o shell. Você pode usar **lógica condicional** (if/else, operadores ternários) para gerar dinamicamente diferentes strings de script com base nas características da entrada. Isso é essencial para lidar com diversos tipos de entrada—como leituras single-end vs paired-end—sem duplicar definições de processo. + +Vamos adicionar um processo ao nosso fluxo de trabalho que demonstra esse padrão. Abra `modules/fastp.nf` e dê uma olhada: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +O processo recebe arquivos FASTQ como entrada e executa a ferramenta `fastp` para aparar adaptadores e filtrar leituras de baixa qualidade. Infelizmente, a pessoa que escreveu este processo não permitiu as leituras single-end que temos em nosso conjunto de dados de exemplo. Vamos adicioná-lo ao nosso fluxo de trabalho e ver o que acontece: + +Primeiro, inclua o módulo na primeira linha do seu fluxo de trabalho `main.nf`: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Em seguida, modifique o bloco `workflow` para conectar o canal `ch_samples` ao processo `FASTP`: + +=== "Depois" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Execute este fluxo de trabalho modificado: + +```bash +nextflow run main.nf +``` + +??? failure "Saída do comando" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Você pode ver que o processo está tentando executar `fastp` com um valor `null` para o segundo arquivo de entrada, o que está causando a falha. Isso ocorre porque nosso conjunto de dados contém leituras single-end, mas o processo está codificado para esperar leituras paired-end (dois arquivos de entrada por vez). + +Corrija isso adicionando lógica condicional ao bloco `script:` do processo `FASTP`. Uma instrução if/else verifica a contagem de arquivos de leitura e ajusta o comando de acordo. + +=== "Depois" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Detecção simples de single-end vs paired-end + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Agora o fluxo de trabalho pode lidar graciosamente com leituras tanto single-end quanto paired-end. A lógica condicional verifica o número de arquivos de entrada e constrói o comando apropriado para `fastp`. Vamos ver se funciona: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +Parece bom! Se verificarmos os comandos reais que foram executados (personalize para seu hash de tarefa): + +```console title="Verificar comandos executados" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Podemos ver que o Nextflow escolheu corretamente o comando certo para leituras single-end: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Outro uso comum de lógica dinâmica de script pode ser visto em [o módulo Genomics do Nextflow for Science](../../nf4science/genomics/02_joint_calling). Nesse módulo, o processo GATK sendo chamado pode receber múltiplos arquivos de entrada, mas cada um deve ser prefixado com `-V` para formar uma linha de comando correta. O processo usa scripting para transformar uma coleção de arquivos de entrada (`all_gvcfs`) nos argumentos de comando corretos: + +```groovy title="manipulação de linha de comando para GATK" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Esses padrões de usar scripting em blocos script de processo são extremamente poderosos e podem ser aplicados em muitos cenários - desde lidar com tipos de entrada variáveis até construir argumentos complexos de linha de comando a partir de coleções de arquivos, tornando seus processos verdadeiramente adaptáveis aos requisitos diversos de dados do mundo real. + +### 2.3. Interpolação de Variáveis: Variáveis Nextflow e Shell + +Scripts de processo misturam variáveis Nextflow, variáveis shell e substituições de comando, cada uma com sintaxe de interpolação diferente. Usar a sintaxe errada causa erros. Vamos explorar isso com um processo que cria um relatório de processamento. + +Dê uma olhada no arquivo de módulo `modules/generate_report.nf`: + +```groovy title="modules/generate_report.nf" linenums="1" +process GENERATE_REPORT { + + publishDir 'results/reports', mode: 'copy' + + input: + tuple val(meta), path(reads) + + output: + path "${meta.id}_report.txt" + + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + """ +} +``` + +Este processo escreve um relatório simples com o ID da amostra e nome do arquivo. Agora vamos executá-lo para ver o que acontece quando precisamos misturar diferentes tipos de variáveis. + +Inclua o processo em seu `main.nf` e adicione-o ao fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="1" hl_lines="2 30" + include { FASTP } from './modules/fastp.nf' + include { GENERATE_REPORT } from './modules/generate_report.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + GENERATE_REPORT(ch_samples) + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" hl_lines="1 10-29" + include { FASTP } from './modules/fastp.nf' + + workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +Agora execute o fluxo de trabalho e verifique os relatórios gerados em `results/reports/`. Eles devem conter informações básicas sobre cada amostra. + +<!-- TODO: add the run command --> + +??? success "Saída do comando" + + ```console + <!-- TODO: output --> + ``` + +Mas e se quisermos adicionar informações sobre quando e onde o processamento ocorreu? Vamos modificar o processo para usar variáveis **shell** e um pouco de substituição de comando para incluir o usuário atual, hostname e data no relatório: + +=== "Depois" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + echo "Processed by: ${USER}" >> ${meta.id}_report.txt + echo "Hostname: $(hostname)" >> ${meta.id}_report.txt + echo "Date: $(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Antes" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + """ + ``` + +Se você executar isso, notará um erro - Nextflow tenta interpretar `${USER}` como uma variável Nextflow que não existe. + +??? failure "Saída do comando" + + ```console + Error modules/generate_report.nf:15:27: `USER` is not defined + │ 15 | echo "Processed by: ${USER}" >> ${meta.id}_report.txt + ╰ | ^^^^ + + ERROR ~ Script compilation failed + ``` + +Precisamos escapá-la para que o Bash possa lidar com ela. + +Corrija isso escapando as variáveis shell e substituições de comando com uma barra invertida (`\`): + +=== "Depois" + + ```groovy title="modules/generate_report.nf" linenums="10" hl_lines="5-7" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + echo "Processed by: \${USER}" >> ${meta.id}_report.txt + echo "Hostname: \$(hostname)" >> ${meta.id}_report.txt + echo "Date: \$(date)" >> ${meta.id}_report.txt + """ + ``` + +=== "Antes" + + ```groovy title="modules/generate_report.nf" linenums="10" + script: + """ + echo "Processing ${reads}" > ${meta.id}_report.txt + echo "Sample: ${meta.id}" >> ${meta.id}_report.txt + echo "Processed by: ${USER}" >> ${meta.id}_report.txt + echo "Hostname: $(hostname)" >> ${meta.id}_report.txt + echo "Date: $(date)" >> ${meta.id}_report.txt + """ + ``` + +Agora funciona! A barra invertida (`\`) diz ao Nextflow "não interprete isso, passe para o Bash." + +### Conclusão + +Nesta seção, você aprendeu técnicas de **processamento de strings**: + +- **Expressões regulares para análise de arquivos**: Usando o operador `=~` e padrões regex (`~/padrão/`) para extrair metadados de convenções complexas de nomenclatura de arquivos +- **Geração dinâmica de scripts**: Usando lógica condicional (if/else, operadores ternários) para gerar diferentes strings de script com base nas características da entrada +- **Interpolação de variáveis**: Entendendo quando o Nextflow interpreta strings vs quando o shell interpreta + - `${var}` diff --git a/docs/pt/docs/side_quests/ideas/containers.md b/docs/pt/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..0f7968b5bb --- /dev/null +++ b/docs/pt/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Parte 1: Mais Contêineres + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Como encontrar ou criar imagens de contêiner + +Alguns desenvolvedores de software fornecem imagens de contêiner para seus softwares que estão disponíveis em registros de contêineres como o Docker Hub, mas muitos não. +Nesta seção opcional, mostraremos duas maneiras de obter uma imagem de contêiner para ferramentas que você deseja usar em seus pipelines Nextflow: usando o Seqera Containers e construindo a imagem de contêiner você mesmo. + +Você irá obter/construir uma imagem de contêiner para o pacote pip `quote`, que será usado no exercício no final desta seção. + +### 1.1. Obter uma imagem de contêiner do Seqera Containers + +Seqera Containers é um serviço gratuito que constrói imagens de contêiner para ferramentas instaláveis via pip e conda (incluindo bioconda). +Navegue até [Seqera Containers](https://www.seqera.io/containers/) e procure pelo pacote pip `quote`. + +![Seqera Containers](img/seqera-containers-1.png) + +Clique em "+Add" e depois em "Get Container" para solicitar uma imagem de contêiner para o pacote pip `quote`. + +![Seqera Containers](img/seqera-containers-2.png) + +Se esta for a primeira vez que um contêiner da comunidade está sendo construído para esta versão do pacote, pode levar alguns minutos para ser concluído. +Clique para copiar o URI (por exemplo, `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) da imagem de contêiner que foi criada para você. + +Agora você pode usar a imagem de contêiner para executar o comando `quote` e obter uma citação aleatória de Grace Hopper. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Saída: + +```console title="Output" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Construir a imagem de contêiner você mesmo + +Vamos usar alguns detalhes de construção do site Seqera Containers para construir a imagem de contêiner para o pacote pip `quote` nós mesmos. +Retorne ao site Seqera Containers e clique no botão "Build Details". + +O primeiro item que veremos é o `Dockerfile`, um tipo de arquivo de script que contém todos os comandos necessários para construir a imagem de contêiner. +Adicionamos alguns comentários explicativos ao Dockerfile abaixo para ajudá-lo a entender o que cada parte faz. + +```Dockerfile title="Dockerfile" +# Começar a partir da imagem base docker micromamba +FROM mambaorg/micromamba:1.5.10-noble +# Copiar o arquivo conda.yml para dentro do contêiner +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Instalar vários utilitários para o Nextflow usar e os pacotes no arquivo conda.yml +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Executar o contêiner como usuário root +USER root +# Definir a variável de ambiente PATH para incluir o diretório de instalação do micromamba +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +O segundo item que veremos é o arquivo `conda.yml`, que contém a lista de pacotes que precisam ser instalados na imagem de contêiner. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Copie o conteúdo desses arquivos para os esboços localizados no diretório `containers/build`, depois execute o seguinte comando para construir a imagem de contêiner você mesmo. + +!!! Note "Nota" + + Usamos a flag `-t quote:latest` para marcar a imagem de contêiner com o nome `quote` e a tag `latest`. + Poderemos usar esta tag para nos referir à imagem de contêiner ao executá-la neste sistema. + +```bash +docker build -t quote:latest containers/build +``` + +Depois que terminar de construir, você pode executar a imagem de contêiner que acabou de construir. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Conclusão + +Você aprendeu duas maneiras diferentes de obter uma imagem de contêiner para uma ferramenta que deseja usar em seus pipelines Nextflow: usando Seqera Containers e construindo a imagem de contêiner você mesmo. + +### Qual é o próximo passo? + +Você tem tudo o que precisa para continuar para o [próximo capítulo](./04_hello_genomics.md) desta série de treinamento. +Você também pode continuar com um exercício opcional para buscar citações de pioneiros da computação/biologia usando o contêiner `quote` e exibi-las usando o contêiner `cowsay`. + +--- + +## 2. Fazer a vaca citar cientistas famosos + +Esta seção contém alguns exercícios extras, para praticar o que você aprendeu até agora. +Fazer esses exercícios _não é obrigatório_ para entender partes posteriores do treinamento, mas fornecem uma maneira divertida de reforçar seus aprendizados descobrindo como fazer a vaca citar cientistas famosos. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. Modificar o script `hello-containers.nf` para usar um processo getQuote + +Temos uma lista de pioneiros da computação e biologia no arquivo `containers/data/pioneers.csv`. +Em alto nível, para completar este exercício você precisará: + +- Modificar o `params.input_file` padrão para apontar para o arquivo `pioneers.csv`. +- Criar um processo `getQuote` que usa o contêiner `quote` para buscar uma citação para cada entrada. +- Conectar a saída do processo `getQuote` ao processo `cowsay` para exibir a citação. + +Para a imagem de contêiner `quote`, você pode usar aquela que construiu você mesmo no exercício extra anterior ou usar aquela que obteve do Seqera Containers. + +!!! Hint "Dica" + + Uma boa escolha para o bloco `script` do seu processo getQuote pode ser: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Você pode encontrar uma solução para este exercício em `containers/solutions/hello-containers-4.1.nf`. + +### 2.2. Modificar seu pipeline Nextflow para permitir a execução nos modos `quote` e `sayHello`. + +Adicione alguma lógica de ramificação ao seu pipeline para permitir que ele aceite entradas destinadas tanto a `quote` quanto a `sayHello`. +Aqui está um exemplo de como usar uma instrução `if` em um fluxo de trabalho Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint "Dica" + + Você pode usar `new_ch = processName.out` para atribuir um nome ao canal de saída de um processo. + +Você pode encontrar uma solução para este exercício em `containers/solutions/hello-containers-4.2.nf`. + +### Conclusão + +Você sabe como usar contêineres no Nextflow para executar processos, e como construir alguma lógica de ramificação em seus pipelines! + +### Qual é o próximo passo? + +Comemore, faça uma pausa para se alongar e beba um pouco de água! + +Quando estiver pronto, passe para a Parte 3 desta série de treinamento para aprender como aplicar o que você aprendeu até agora a um caso de uso de análise de dados mais realista. diff --git a/docs/pt/docs/side_quests/ideas/if_else.md b/docs/pt/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..9bb38c817c --- /dev/null +++ b/docs/pt/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Parte 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. Faça a vaca citar cientistas famosos + +Esta seção contém alguns exercícios de aprofundamento, para praticar o que você aprendeu até agora. +Fazer esses exercícios _não é necessário_ para entender as partes posteriores do treinamento, mas oferecem uma maneira divertida de reforçar seus aprendizados descobrindo como fazer a vaca citar cientistas famosos. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. Modifique o script `hello-containers.nf` para usar um processo getQuote + +Temos uma lista de pioneiros da computação e biologia no arquivo `containers/data/pioneers.csv`. +Em alto nível, para completar este exercício você precisará: + +- Modificar o `params.input_file` padrão para apontar para o arquivo `pioneers.csv`. +- Criar um processo `getQuote` que usa o contêiner `quote` para buscar uma citação para cada entrada. +- Conectar a saída do processo `getQuote` ao processo `cowsay` para exibir a citação. + +Para a imagem de contêiner `quote`, você pode usar a que você mesmo construiu no exercício de aprofundamento anterior ou usar a que você obteve do Seqera Containers. + +!!! Hint + + Uma boa escolha para o bloco `script` do seu processo getQuote poderia ser: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Você pode encontrar uma solução para este exercício em `containers/solutions/hello-containers-4.1.nf`. + +### 1.2. Modifique seu pipeline Nextflow para permitir a execução nos modos `quote` e `sayHello`. + +Adicione alguma lógica de ramificação ao seu pipeline para permitir que ele aceite entradas destinadas tanto a `quote` quanto a `sayHello`. +Aqui está um exemplo de como usar uma instrução `if` em um fluxo de trabalho Nextflow: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint + + Você pode usar `new_ch = processName.out` para atribuir um nome ao canal de saída de um processo. + +Você pode encontrar uma solução para este exercício em `containers/solutions/hello-containers-4.2.nf`. + +### Conclusão + +Você sabe como usar contêineres no Nextflow para executar processos e como construir alguma lógica de ramificação em seus pipelines! + +### Qual é o próximo passo? + +Comemore, faça uma pausa para se alongar e beba água! + +Quando estiver pronto, passe para a Parte 3 desta série de treinamento para aprender como aplicar o que você aprendeu até agora a um caso de uso de análise de dados mais realista. diff --git a/docs/pt/docs/side_quests/index.md b/docs/pt/docs/side_quests/index.md new file mode 100644 index 0000000000..da17037156 --- /dev/null +++ b/docs/pt/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: Missões Secundárias +hide: + - toc +--- + +# Missões Secundárias + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta é uma coleção de mini-cursos de treinamento independentes que se aprofundam em tópicos específicos. Você pode realizá-los em qualquer ordem. + +Vamos começar! Clique no botão "Open in GitHub Codespaces" abaixo para iniciar o ambiente de treinamento (preferencialmente em uma aba separada), e então continue lendo enquanto ele carrega. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Pré-requisitos + +Os pré-requisitos específicos de cada mini-curso variam e estão documentados nas páginas correspondentes. +No entanto, todos eles assumem alguma familiaridade mínima com o seguinte: + +- Experiência com a linha de comando +- Conceitos fundamentais de Nextflow e ferramentas abordadas no curso de treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/). + +Para requisitos técnicos e configuração do ambiente, consulte o mini-curso [Configuração do Ambiente](../../envsetup/). + +**Se esta é a primeira vez que você se aprofunda nas Missões Secundárias, certifique-se de conferir a página de [Orientação](./orientation.md) primeiro!** + +Caso contrário, selecione uma missão secundária na tabela abaixo. + +## Missões Secundárias + +| Missão Secundária | Tempo Estimado para Ensino | +| -------------------------------------------------------------------------------- | -------------------------- | +| [Visão geral do ambiente de desenvolvimento Nextflow](./ide_features.md) | 45 min | +| [Padrões Essenciais de Scripting em Nextflow](./essential_scripting_patterns.md) | 90 min | +| [Metadados em fluxos de trabalho](./metadata.md) | 45 min | +| [Divisão e Agrupamento](./splitting_and_grouping.md) | 45 min | +| [Testes com nf-test](./nf-test.md) | 1 hora | +| [Fluxos de trabalho de fluxos de trabalho](./workflows_of_workflows.md) | 30 min | +| [Trabalhando com arquivos](./working_with_files.md) | 45 min | +| [Depuração de fluxos de trabalho](./debugging.md) | 1 hora | + +Deixe-nos saber quais outros domínios e casos de uso você gostaria de ver cobertos aqui postando na [seção de Treinamento](https://community.seqera.io/c/training/) do fórum da comunidade. diff --git a/docs/pt/docs/side_quests/metadata.md b/docs/pt/docs/side_quests/metadata.md new file mode 100644 index 0000000000..fd78da3ada --- /dev/null +++ b/docs/pt/docs/side_quests/metadata.md @@ -0,0 +1,1281 @@ +# Metadados e mapas meta + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Em qualquer análise científica, raramente trabalhamos apenas com os arquivos de dados brutos. +Cada arquivo vem com suas próprias informações adicionais: o que é, de onde veio e o que o torna especial. +Essas informações extras são o que chamamos de metadados. + +Metadados são dados que descrevem outros dados. +Metadados rastreiam detalhes importantes sobre arquivos e condições experimentais, e ajudam a adaptar análises às características únicas de cada conjunto de dados. + +Pense nisso como um catálogo de biblioteca: enquanto os livros contêm o conteúdo real (dados brutos), as fichas do catálogo fornecem informações essenciais sobre cada livro—quando foi publicado, quem o escreveu, onde encontrá-lo (metadados). +Em pipelines Nextflow, os metadados podem ser usados para: + +- Rastrear informações específicas de arquivos ao longo do fluxo de trabalho +- Configurar processos com base nas características dos arquivos +- Agrupar arquivos relacionados para análise conjunta + +### Objetivos de aprendizado + +Nesta missão secundária, exploraremos como lidar com metadados em fluxos de trabalho. +Começando com uma planilha de dados simples (geralmente chamada de samplesheet em bioinformática) contendo informações básicas de arquivos, você aprenderá como: + +- Ler e analisar metadados de arquivos a partir de arquivos CSV +- Criar e manipular mapas de metadados +- Adicionar novos campos de metadados durante a execução do fluxo de trabalho +- Usar metadados para personalizar o comportamento de processos + +Essas habilidades ajudarão você a construir pipelines mais robustos e flexíveis que podem lidar com relações complexas de arquivos e requisitos de processamento. + +### Pré-requisitos + +Antes de assumir esta missão secundária, você deve: + +- Ter concluído o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores) + +--- + +## 0. Começando + +#### Abra o codespace de treinamento + +Se você ainda não o fez, certifique-se de abrir o ambiente de treinamento conforme descrito em [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mova-se para o diretório do projeto + +Vamos mover para o diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/metadata +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revise os materiais + +Você encontrará um arquivo de fluxo de trabalho principal e um diretório `data` contendo uma planilha de dados e alguns arquivos de dados. + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +O fluxo de trabalho no arquivo `main.nf` é um esboço que você expandirá gradualmente em um fluxo de trabalho totalmente funcional. + +A planilha de dados lista os caminhos para os arquivos de dados e alguns metadados associados, organizados em 3 colunas: + +- `id`: autoexplicativo, um ID dado ao arquivo +- `character`: um nome de personagem, que usaremos mais tarde para desenhar diferentes criaturas +- `data`: caminhos para arquivos `.txt` que contêm saudações em diferentes idiomas + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Cada arquivo de dados contém algum texto de saudação em um dos cinco idiomas (fr: francês, de: alemão, es: espanhol, it: italiano, en: inglês). + +Também forneceremos uma ferramenta de análise de idiomas containerizada chamada `langid`. + +#### Revise a tarefa + +Seu desafio é escrever um fluxo de trabalho Nextflow que irá: + +1. **Identificar** o idioma em cada arquivo automaticamente +2. **Agrupar** arquivos por família de idiomas (idiomas germânicos vs. idiomas românicos) +3. **Personalizar** o processamento para cada arquivo com base em seu idioma e metadados +4. **Organizar** as saídas por grupo de idiomas + +Isso representa um padrão típico de fluxo de trabalho onde metadados específicos de arquivos orientam decisões de processamento; exatamente o tipo de problema que os mapas de metadados resolvem elegantemente. + +#### Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Defini meu diretório de trabalho adequadamente +- [ ] Entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Carregar metadados de uma planilha de dados + +Abra o arquivo de fluxo de trabalho `main.nf` para examinar o esboço de fluxo de trabalho que estamos fornecendo como ponto de partida. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Você pode ver que configuramos uma fábrica de canal básica para carregar a planilha de dados de exemplo como um arquivo, mas isso ainda não lerá o conteúdo do arquivo. +Vamos começar adicionando isso. + +### 1.1. Ler o conteúdo com `splitCsv` + +Precisamos escolher um operador que analisará o conteúdo do arquivo adequadamente com o mínimo esforço de nossa parte. +Como nossa planilha de dados está no formato CSV, este é um trabalho para o operador [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv), que carrega cada linha do arquivo como um elemento no canal. + +Faça as seguintes alterações para adicionar uma operação `splitCsv()` ao código de construção do canal, mais uma operação `view()` para verificar se o conteúdo do arquivo está sendo carregado corretamente no canal. + +=== "Depois" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Observe que estamos usando a opção `header: true` para dizer ao Nextflow para ler a primeira linha do arquivo CSV como a linha de cabeçalho. + +Vamos ver o que sai disso, certo? +Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Podemos ver que o operador construiu um mapa de pares chave-valor para cada linha no arquivo CSV, com os cabeçalhos das colunas como chaves para os valores correspondentes. + +Cada entrada do mapa corresponde a uma coluna em nossa planilha de dados: + +- `id` +- `character` +- `recording` + +Isso é ótimo! Facilita o acesso a campos específicos de cada arquivo. +Por exemplo, poderíamos acessar o ID do arquivo com `id` ou o caminho do arquivo txt com `recording`. + +??? info "(Opcional) Mais sobre mapas" + + Em Groovy, a linguagem de programação sobre a qual o Nextflow é construído, um mapa é uma estrutura de dados chave-valor semelhante a dicionários em Python, objetos em JavaScript ou hashes em Ruby. + + Aqui está um script executável que mostra como você pode definir um mapa e acessar seu conteúdo na prática: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Criar um mapa simples + def my_map = [id:'sampleA', character:'squirrel'] + + // Imprimir o mapa inteiro + println "map: ${my_map}" + + // Acessar valores individuais usando notação de ponto + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Mesmo que não tenha um bloco `workflow` adequado, o Nextflow pode executar isso como se fosse um fluxo de trabalho: + + ```bash + nextflow run examples/map_demo.nf + ``` + + E aqui está o que você pode esperar ver na saída: + + ```console title="Output" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. Selecionar campos específicos com `map` + +Digamos que queremos acessar a coluna `character` da planilha de dados e imprimi-la. +Podemos usar o operador `map` do Nextflow para iterar sobre cada item em nosso canal e especificamente selecionar a entrada `character` do objeto mapa. + +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Agora execute o fluxo de trabalho novamente: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Sucesso! Aproveitamos a estrutura de mapa derivada de nossa planilha de dados para acessar os valores de colunas individuais para cada linha. + +Agora que lemos com sucesso a planilha de dados e temos acesso aos dados em cada linha, podemos começar a implementar nossa lógica de pipeline. + +### 1.3. Organizar os metadados em um 'mapa meta' + +No estado atual do fluxo de trabalho, os arquivos de entrada (sob a chave `recording`) e metadados associados (`id`, `character`) estão todos no mesmo nível, como se estivessem todos em uma grande sacola. +A consequência prática é que todo processo que consome este canal precisaria ser configurado com essa estrutura em mente: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +Isso é bom desde que o número de colunas na planilha de dados não mude. +No entanto, se você adicionar apenas uma coluna à planilha de dados, a forma do canal não corresponderá mais ao que o processo espera, e o fluxo de trabalho produzirá erros. +Também torna o processo difícil de compartilhar com outras pessoas que podem ter dados de entrada ligeiramente diferentes, e você pode acabar tendo que codificar variáveis no processo que não são necessárias pelo bloco de script. + +Para evitar esse problema, precisamos encontrar uma maneira de manter a estrutura do canal consistente independentemente de quantas colunas a planilha de dados contém. + +Podemos fazer isso coletando todos os metadados em um item dentro da tupla, que chamaremos de mapa de metadados, ou mais simplesmente 'mapa meta'. + +Faça as seguintes edições na operação `map`: + +=== "Depois" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Reestruturamos nossos elementos de canal em uma tupla consistindo de dois elementos, o mapa meta e o objeto de arquivo correspondente. + +Vamos executar o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console title="View meta map" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Agora, cada elemento no canal contém o mapa meta primeiro e o objeto de arquivo correspondente em segundo: + +```console title="Estrutura de saída de exemplo" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +Como resultado, adicionar mais colunas na planilha de dados tornará mais metadados disponíveis no mapa `meta`, mas não mudará a forma do canal. +Isso nos permite escrever processos que consomem o canal sem ter que codificar os itens de metadados na especificação de entrada: + +```groovy title="Exemplo de sintaxe" + input: + tuple val(meta), file(recording) +``` + +Esta é uma convenção amplamente usada para organizar metadados em fluxos de trabalho Nextflow. + +### Conclusão + +Nesta seção, você aprendeu: + +- **Por que os metadados são importantes:** Manter metadados com seus dados preserva informações importantes sobre arquivos ao longo do fluxo de trabalho. +- **Como ler planilhas de dados:** Usando `splitCsv` para ler arquivos CSV com informações de cabeçalho e transformar linhas em dados estruturados +- **Como criar um mapa meta:** Separando metadados de dados de arquivo usando a estrutura de tupla `[ [id:value, ...], file ]` + +--- + +## 2. Manipulando metadados + +Agora que temos nossos metadados carregados, vamos fazer algo com eles! + +Vamos usar uma ferramenta chamada [`langid`](https://github.com/saffsd/langid.py) para identificar o idioma contido em cada arquivo de gravação da criatura. +A ferramenta vem pré-treinada em um conjunto de idiomas e, dado um trecho de texto, ela produzirá uma previsão de idioma e uma pontuação de probabilidade associada, ambas para `stdout`. + +### 2.1. Importar o processo e examinar o código + +Fornecemos a você um módulo de processo pré-escrito chamado `IDENTIFY_LANGUAGE` que envolve a ferramenta `langid`, então você só precisa adicionar uma instrução include antes do bloco workflow. + +Faça a seguinte edição no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Você pode abrir o arquivo do módulo para examinar seu código: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Usar langid para prever o idioma de cada arquivo de entrada +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Como você pode ver, a definição de entrada usa a mesma estrutura `tuple val(meta), path(file)` que acabamos de aplicar ao nosso canal de entrada. + +A definição de saída é estruturada como uma tupla com estrutura similar à da entrada, exceto que também contém `stdout` como um terceiro elemento. +Este padrão `tuple val(meta), path(file), <output>` mantém os metadados associados tanto aos dados de entrada quanto às saídas conforme fluem pelo pipeline. + +Observe que estamos usando o qualificador de saída [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) do Nextflow aqui porque a ferramenta imprime sua saída diretamente no console em vez de escrever um arquivo; e usamos `sed` na linha de comando para remover a pontuação de probabilidade, limpar a string removendo caracteres de nova linha e retornar apenas a previsão de idioma. + +### 2.2. Adicionar uma chamada para `IDENTIFY_LANGUAGE` + +Agora que o processo está disponível para o fluxo de trabalho, podemos adicionar uma chamada ao processo `IDENTIFY_LANGUAGE` para executá-lo no canal de dados. + +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Observe que removemos a operação `.view()` original na construção do canal. + +Agora podemos executar o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Excelente! Agora temos uma previsão de que idioma cada personagem fala. + +E conforme observado anteriormente, também incluímos o arquivo de entrada e o mapa meta na saída, o que significa que ambos permanecem associados às novas informações que acabamos de produzir. +Isso se mostrará útil no próximo passo. + +!!! note + + De forma mais geral, esse padrão de manter o mapa meta associado aos resultados facilita associar resultados relacionados que compartilham os mesmos identificadores. + + Como você já deve ter aprendido, você não pode confiar na ordem dos itens nos canais para combinar resultados entre eles. + Em vez disso, você deve usar chaves para associar dados corretamente, e os mapas meta fornecem uma estrutura ideal para esse propósito. + + Exploramos esse caso de uso em detalhes na missão secundária [Dividindo e Agrupando](./splitting_and_grouping.md). + +### 2.3. Aumentar metadados com saídas de processo + +Dado que os resultados que acabamos de produzir são em si mesmos uma forma de metadados sobre o conteúdo dos arquivos, seria útil adicioná-los ao nosso mapa meta. + +No entanto, não queremos modificar o mapa meta existente no local. +Do ponto de vista técnico, é _possível_ fazer isso, mas não é seguro. + +Então, em vez disso, criaremos um novo mapa meta contendo o conteúdo do mapa meta existente mais um novo par chave-valor `lang: lang_id` contendo a nova informação, usando o operador `+` (um recurso do Groovy). +E combinaremos isso com uma operação [`map`](https://www.nextflow.io/docs/latest/operator.html#map) para substituir o mapa antigo pelo novo. + +Aqui estão as edições que você precisa fazer no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +Se você ainda não está familiarizado com o operador `+`, ou se isso parece confuso, reserve alguns minutos para examinar a explicação detalhada abaixo. + +??? info "Criação do novo mapa meta usando o operador `+`" + + **Primeiro, você precisa saber que podemos mesclar o conteúdo de dois mapas usando o operador Groovy `+`.** + + Digamos que temos os seguintes mapas: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Podemos mesclá-los assim: + + ```groovy + new_map = map1 + map2 + ``` + + O conteúdo de `new_map` será: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Ótimo! + + **Mas e se você precisar adicionar um campo que ainda não faz parte de um mapa?** + + Digamos que você comece novamente de `map1`, mas a previsão de idioma não está em seu próprio mapa (não há `map2`). + Em vez disso, ela é mantida em uma variável chamada `lang_id`, e você sabe que quer armazenar seu valor (`'fr'`) com a chave `lang`. + + Você pode realmente fazer o seguinte: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Aqui, `[lang: new_info]` cria um novo mapa sem nome dinamicamente, e `map1 + ` mescla `map1` com o novo mapa sem nome, produzindo o mesmo conteúdo `new_map` de antes. + + Legal, não é? + + **Agora vamos transpor isso para o contexto de uma operação `channel.map()` do Nextflow.** + + O código se torna: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Isso faz o seguinte: + + - `map1, lang_id ->` pega os dois itens na tupla + - `[map1 + [lang: lang_id]]` cria o novo mapa conforme detalhado acima + + A saída é um único mapa sem nome com o mesmo conteúdo de `new_map` em nosso exemplo acima. + Então, efetivamente transformamos: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + em: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Esperamos que você possa ver que se mudarmos `map1` para `meta`, isso é basicamente tudo o que precisamos para adicionar a previsão de idioma ao nosso mapa meta em nosso fluxo de trabalho. + + Exceto por uma coisa! + + No caso do nosso fluxo de trabalho, **também precisamos levar em conta a presença do objeto `file` na tupla**, que é composta de `meta, file, lang_id`. + + Então o código aqui se tornaria: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + Se você está tendo dificuldade em entender por que o `file` parece estar se movendo na operação `map`, imagine que em vez de `[meta + [lang: lang_id], file]`, essa linha diz `[new_map, file]`. + Isso deve deixar mais claro que estamos simplesmente deixando o `file` em seu lugar original na segunda posição da tupla. Apenas pegamos o valor `new_info` e o incorporamos no mapa que está na primeira posição. + + **E isso nos traz de volta à estrutura de canal `tuple val(meta), path(file)`!** + +Uma vez que você esteja confiante de que entende o que este código está fazendo, execute o fluxo de trabalho para ver se funcionou: + +```bash +nextflow run main.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Sim, isso está correto! +Reorganizamos ordenadamente a saída do processo de `meta, file, lang_id` para que `lang_id` seja agora uma das chaves no mapa meta, e as tuplas do canal se encaixam no modelo `meta, file` mais uma vez. + +### 2.4. Atribuir um grupo de idiomas usando condicionais + +Agora que temos nossas previsões de idioma, vamos usar as informações para atribuir alguns novos agrupamentos. + +Em nossos dados de exemplo, os idiomas usados por nossos personagens podem ser agrupados em idiomas germânicos (inglês, alemão) e idiomas românicos (francês, espanhol, italiano). +Pode ser útil ter essa classificação prontamente disponível em algum lugar mais adiante no pipeline, então vamos adicionar essa informação no mapa meta. + +E, boa notícia, este é mais um caso que se presta perfeitamente ao uso do operador `map`! + +Especificamente, vamos definir uma variável chamada `lang_group`, usar alguma lógica condicional simples para determinar qual valor atribuir ao `lang_group` para cada pedaço de dados. + +A sintaxe geral vai se parecer com isto: + +```groovy +.map { meta, file -> + + // lógica condicional definindo lang_group vai aqui + + [meta + [lang_group: lang_group], file] +} +``` + +Você pode ver que isso é muito semelhante à operação de mesclagem de mapa dinâmica que usamos no passo anterior. +Só precisamos escrever as declarações condicionais. + +Aqui está a lógica condicional que queremos aplicar: + +- Definir uma variável chamada `lang_group` com valor padrão `'unknown'`. +- Se `lang` for alemão (`'de'`) ou inglês (`'en'`), mudar `lang_group` para `germanic`. +- Senão, se `lang` estiver incluído em uma lista contendo francês (`'fr'`), espanhol (`'es'`) e italiano (`'it'`), mudar `lang_group` para `romance`. + +Tente escrever você mesmo se já souber como escrever declarações condicionais em Nextflow. + +!!! tip + + Você pode acessar o valor de `lang` dentro da operação map com `meta.lang`. + +Você deve acabar fazendo as seguintes alterações no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +Aqui estão os pontos-chave: + +- Usamos `def lang_group = "unknown"` para criar a variável `lang_group` com valor padrão definido como `unknown`. +- Usamos uma estrutura `if {} else if {}` para a lógica condicional, com testes `.equals()` alternativos para os dois idiomas germânicos, e um teste de existência em uma lista para os três idiomas românicos. +- Usamos a operação de mesclagem `meta + [lang_group:lang_group]` como anteriormente para gerar o mapa meta atualizado. + +Assim que tudo fizer sentido, execute o fluxo de trabalho novamente para ver o resultado: + +```bash +nextflow run main.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Como você pode ver, os elementos do canal mantêm sua estrutura `[meta, file]`, mas o mapa meta agora inclui esta nova classificação. + +### Conclusão + +Nesta seção, você aprendeu como: + +- **Aplicar metadados de entrada a canais de saída**: Copiar metadados dessa forma nos permite associar resultados posteriormente com base no conteúdo dos metadados. +- **Criar chaves personalizadas**: Você criou duas novas chaves em seu mapa meta, mesclando-as com `meta + [new_key:value]` no mapa meta existente. Uma baseada em um valor computado de um processo, e uma baseada em uma condição que você definiu no operador `map`. + +Isso permite que você associe metadados novos e existentes com arquivos conforme progride através do seu pipeline. +Mesmo que você não esteja usando metadados como parte de um processo, manter o mapa meta associado aos dados dessa forma facilita manter todas as informações relevantes juntas. + +--- + +## 3. Usando informações do mapa meta em um processo + +Agora que você sabe como criar e atualizar o mapa meta, podemos chegar à parte realmente divertida: realmente usar os metadados em um processo. + +Mais especificamente, vamos adicionar um segundo passo ao nosso fluxo de trabalho para desenhar cada animal como arte ASCII e fazê-lo dizer o texto gravado em um balão de fala. +Vamos fazer isso usando uma ferramenta chamada [`cowpy`](https://github.com/jeffbuttars/cowpy). + +??? info "O que o `cowpy` faz?" + + `cowpy` é uma ferramenta de linha de comando que gera arte ASCII para exibir entradas de texto arbitrárias de forma divertida. + É uma implementação em Python da clássica ferramenta [cowsay](https://en.wikipedia.org/wiki/Cowsay) de Tony Monroe. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + Opcionalmente, você pode selecionar um personagem (ou 'cowacter') para usar em vez da vaca padrão. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Se você trabalhou no curso Hello Nextflow, você já viu esta ferramenta em ação. +Se não, não se preocupe; cobriremos tudo o que você precisa saber enquanto avançamos. + +### 3.1. Importar o processo e examinar o código + +Fornecemos a você um módulo de processo pré-escrito chamado `COWPY` que envolve a ferramenta `cowpy`, então você só precisa adicionar uma instrução include antes do bloco workflow. + +Faça a seguinte edição no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Você pode abrir o arquivo do módulo para examinar seu código: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Gerar arte ASCII com cowpy +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Como você pode ver, este processo está atualmente projetado para receber um arquivo de entrada (contendo o texto a ser exibido) e um valor especificando o personagem que deve ser desenhado em arte ASCII, geralmente fornecido no nível do fluxo de trabalho por um parâmetro de linha de comando. + +### 3.2. Passar um campo do mapa meta como entrada + +Quando usamos a ferramenta `cowpy` no curso Hello Nextflow, usamos um parâmetro de linha de comando para determinar qual personagem usar para desenhar a imagem final. +Isso fazia sentido, porque estávamos gerando apenas uma imagem por execução do pipeline. + +No entanto, neste tutorial, queremos gerar uma imagem apropriada para cada sujeito que estamos processando, então usar um parâmetro de linha de comando seria muito limitante. + +Boa notícia: temos uma coluna `character` em nossa planilha de dados e, portanto, em nosso mapa meta. +Vamos usar isso para definir o personagem que o processo deve usar para cada entrada. + +Para isso, precisaremos fazer três coisas: + +1. Dar um nome ao canal de saída vindo do processo anterior para que possamos operá-lo mais convenientemente. +2. Determinar como acessar a informação de interesse +3. Adicionar uma chamada ao segundo processo e alimentar a informação adequadamente. + +Vamos começar. + +#### 3.2.1. Nomear o canal de saída anterior + +Aplicamos as manipulações anteriores diretamente no canal de saída do primeiro processo, `IDENTIFY_LANGUAGE.out`. +Para alimentar o conteúdo desse canal para o próximo processo (e fazer isso de uma forma que seja clara e fácil de ler), queremos dar a ele seu próprio nome, `ch_languages`. + +Podemos fazer isso usando o operador [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set). + +No fluxo de trabalho principal, substitua o operador `.view()` por `.set { ch_languages }`, e adicione uma linha testando que podemos nos referir ao canal pelo nome. + +=== "Depois" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Temporário: espiar em ch_languages + ch_languages.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Executar langid para identificar o idioma de cada saudação + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Vamos executar isto: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Isso confirma que agora podemos nos referir ao canal pelo nome. + +#### 3.2.2. Acessar o arquivo e os metadados do personagem + +Sabemos ao olhar o código do módulo que o processo `COWPY` espera receber um arquivo de texto e um valor `character`. +Para escrever a chamada para o processo `COWPY`, só precisamos saber como extrair o objeto de arquivo correspondente e os metadados de cada elemento no canal. + +Como é frequentemente o caso, a maneira mais simples de fazer isso é usar uma operação `map`. + +Nosso canal contém tuplas estruturadas como `[meta, file]`, então podemos acessar o objeto `file` diretamente, e podemos acessar o valor `character` armazenado dentro do mapa meta referindo-se a ele como `meta.character`. + +No fluxo de trabalho principal, faça as seguintes alterações de código: + +=== "Depois" + + ```groovy title="main.nf" linenums="34" + // Temporário: acessar o arquivo e o personagem + ch_languages.map { meta, file -> file }.view { file -> "File: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Character: " + character } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" + // Temporário: espiar em ch_languages + ch_languages.view() + ``` + +Observe que estamos usando closures (como `{ file -> "File: " + file }`) para tornar a saída das operações `.view` mais legível. + +Vamos executar isto: + +```bash +nextflow run main.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Character: squirrel + File: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + File: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Character: tux + Character: turkey + File: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + File: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Character: sheep + Character: moose + Character: stegosaurus + File: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + File: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + File: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Character: turtle + ``` + +_Os caminhos de arquivo e valores de personagem podem aparecer em uma ordem diferente em sua saída._ + +Isso confirma que somos capazes de acessar o arquivo e o personagem para cada elemento no canal. + +#### 3.2.3. Chamar o processo `COWPY` + +Agora vamos juntar tudo e realmente chamar o processo `COWPY` no canal `ch_languages`. + +No fluxo de trabalho principal, faça as seguintes alterações de código: + +=== "Depois" + + ```groovy title="main.nf" linenums="34" + // Executar cowpy para gerar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" + // Temporário: acessar o arquivo e o personagem + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Você vê que simplesmente copiamos as duas operações map (menos as declarações `.view()`) como entradas para a chamada do processo. +Apenas certifique-se de não esquecer a vírgula entre elas! + +É um pouco desajeitado, mas veremos como melhorar isso na próxima seção. + +Vamos executar isto: + +```bash +nextflow run main.nf -resume +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_crick] DSL2 - revision: 25541014c5 + + executor > local (7) + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [e7/317c18] COWPY (6) [100%] 7 of 7 ✔ + ``` + +Se você olhar no diretório de resultados, você deve ver os arquivos individuais contendo a arte ASCII de cada saudação falada pelo personagem correspondente. + +??? abstract "Diretório e conteúdo de arquivo de exemplo" + + ```console + results/ + ├── cowpy-bonjour.txt + ├── cowpy-ciao.txt + ├── cowpy-guten_tag.txt + ├── cowpy-hallo.txt + ├── cowpy-hello.txt + ├── cowpy-hola.txt + └── cowpy-salut.txt + ``` + + ```text title="results/cowpy-bonjour.txt" + _________________ + / Bonjour \ + \ Salut, à demain / + ----------------- + \ + \ + _ _ + | \__/| .~ ~. + /oo `./ .' + {o__, \ { + / . . ) \ + `-` '-' \ } + .( _( )_.' + '---.~_ _ _| + ``` + +Isso mostra que conseguimos usar as informações no mapa meta para parametrizar o comando no segundo passo do pipeline. + +No entanto, conforme observado acima, parte do código envolvido foi um pouco desajeitado, já que tivemos que desempacotar metadados ainda no contexto do corpo do fluxo de trabalho. +Essa abordagem funciona bem para usar um pequeno número de campos do mapa meta, mas escalaria mal se quiséssemos usar muito mais. + +Existe outro operador chamado `multiMap()` que nos permite simplificar isso um pouco, mas mesmo assim não é ideal. + +??? info "(Opcional) Versão alternativa com `multiMap()`" + + Caso você esteja se perguntando, não poderíamos apenas escrever uma única operação `map()` que gera tanto o `file` quanto o `character`, porque isso os retornaria como uma tupla. + Tivemos que escrever duas operações `map()` separadas para alimentar os elementos `file` e `character` ao processo separadamente. + + Tecnicamente existe outra maneira de fazer isso através de uma única operação de mapeamento, usando o operador `multiMap()`, que é capaz de emitir múltiplos canais. + Por exemplo, você poderia substituir a chamada para `COWPY` acima pelo seguinte código: + + === "Depois" + + ```groovy title="main.nf" linenums="34" + // Executar cowpy para gerar arte ASCII + COWPY( + ch_languages.multiMap { meta, file -> + file: file + character: meta.character + } + ) + ``` + + === "Antes" + + ```groovy title="main.nf" linenums="34" + // Executar cowpy para gerar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + + Isso produz exatamente o mesmo resultado. + +De qualquer forma, é estranho que tenhamos que fazer algum desempacotamento no nível do fluxo de trabalho. + +Seria melhor se pudéssemos alimentar o mapa meta inteiro para o processo e escolher o que precisamos uma vez lá. + +### 3.3. Passar e usar o mapa meta inteiro + +O ponto do mapa meta é, afinal, passar todos os metadados juntos como um pacote. +A única razão pela qual não pudemos fazer isso acima é que o processo não está configurado para aceitar um mapa meta. +Mas como controlamos o código do processo, podemos mudar isso. + +Vamos modificar o processo `COWPY` para aceitar a estrutura de tupla `[meta, file]` que usamos no primeiro processo para que possamos simplificar o fluxo de trabalho. + +Para isso, precisaremos fazer três coisas: + +1. Modificar as definições de entrada do módulo de processo `COWPY` +2. Atualizar o comando do processo para usar o mapa meta +3. Atualizar a chamada do processo no corpo do fluxo de trabalho + +Pronto? Vamos lá! + +#### 3.3.1. Modificar a entrada do módulo `COWPY` + +Faça as seguintes edições no arquivo de módulo `cowpy.nf`: + +=== "Depois" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2" + input: + tuple val(meta), path(input_file) + ``` + +=== "Antes" + + ```groovy title="cowpy.nf" linenums="10" hl_lines="2-3" + input: + path(input_file) + val character + ``` + +Isso nos permite usar a estrutura de tupla `[meta, file]` que cobrimos anteriormente no tutorial. + +Observe que não atualizamos a definição de saída do processo para produzir o mapa meta, a fim de manter o tutorial simplificado, mas sinta-se à vontade para fazer isso você mesmo como exercício seguindo o modelo do processo `IDENTIFY_LANGUAGE`. + +#### 3.3.2. Atualizar o comando para usar o campo do mapa meta + +O mapa meta inteiro agora está disponível dentro do processo, então podemos nos referir às informações que ele contém diretamente de dentro do bloco de comando. + +Faça as seguintes edições no arquivo de módulo `cowpy.nf`: + +=== "Depois" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${meta.character} > cowpy-${input_file} + """ + ``` + +=== "Antes" + + ```groovy title="cowpy.nf" linenums="16" hl_lines="3" + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ + ``` + +Substituímos a referência ao valor `character` previamente passado como uma entrada independente pelo valor mantido no mapa meta, ao qual nos referimos usando `meta.character`. + +Agora vamos atualizar a chamada do processo adequadamente. + +#### 3.3.3. Atualizar a chamada do processo e executá-lo + +O processo agora espera que sua entrada use a estrutura de tupla `[meta, file]`, que é o que o processo anterior produz, então podemos simplesmente passar o canal `ch_languages` inteiro para o processo `COWPY`. + +Faça as seguintes edições no fluxo de trabalho principal: + +=== "Depois" + + ```groovy title="main.nf" linenums="34" hl_lines="2" + // Executar cowpy para gerar arte ASCII + COWPY(ch_languages) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="34" hl_lines="3-4" + // Executar cowpy para gerar arte ASCII + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file diff --git a/docs/pt/docs/side_quests/nf-test.md b/docs/pt/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..727b7239d3 --- /dev/null +++ b/docs/pt/docs/side_quests/nf-test.md @@ -0,0 +1,1198 @@ +# Testando com nf-test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Ser capaz de testar sistematicamente que cada parte do seu fluxo de trabalho está fazendo o que deveria fazer é crítico para reprodutibilidade e manutenção a longo prazo, e pode ser uma grande ajuda durante o processo de desenvolvimento. + +Vamos reservar um minuto para falar sobre por que testar é tão importante. Se você está desenvolvendo um fluxo de trabalho, uma das primeiras coisas que você fará é pegar alguns dados de teste que você sabe que são válidos e devem produzir um resultado. Você adiciona o primeiro processo ao pipeline e o conecta às suas entradas para fazê-lo funcionar. Então, para verificar se está tudo funcionando, você o executa nos dados de teste. Assumindo que funciona, você passa para o próximo processo e executa os dados de teste novamente. Você repete esse processo até ter um pipeline com o qual está satisfeito. + +Então, talvez você adicione um parâmetro simples verdadeiro ou falso como `--skip_process`. Agora você deve executar o pipeline duas vezes, uma com cada parâmetro para ter certeza de que funciona como esperado. Mas espere, como verificamos se o `--skip_process` realmente pula o processo? Temos que vasculhar as saídas ou verificar os arquivos de log! Isso é trabalhoso e propenso a erros. + +À medida que você desenvolve seu pipeline, ele rapidamente se tornará tão complexo que testar manualmente cada iteração é lento e propenso a erros. Além disso, se você encontrar um erro, será muito difícil identificar exatamente de onde no seu pipeline o erro está vindo. É aqui que os testes entram. + +Testar permite que você verifique sistematicamente que cada parte do seu pipeline está funcionando como esperado. Os benefícios para um desenvolvedor de testes bem escritos são enormes: + +- **Confiança**: Como os testes cobrem o pipeline inteiro, você pode ter certeza de que mudar algo não afeta nada mais +- **Credibilidade**: Quando múltiplos desenvolvedores trabalham no pipeline, eles sabem que os outros desenvolvedores não quebraram o pipeline e cada componente. +- **Transparência**: Os testes mostram onde um pipeline está falhando e facilitam rastrear o problema. Eles também funcionam como uma forma de documentação, mostrando como executar um processo ou fluxo de trabalho. +- **Velocidade**: Como os testes são automatizados, eles podem ser executados muito rapidamente e repetidamente. Você pode iterar rapidamente com menos medo de introduzir novos bugs. + +Existem muitos tipos diferentes de testes que podemos escrever: + +1. **Testes no nível de módulo**: Para processos individuais +2. **Testes no nível de fluxo de trabalho**: Para um único fluxo de trabalho +3. **Testes no nível de pipeline**: Para o pipeline como um todo +4. **Testes de desempenho**: Para a velocidade e eficiência do pipeline +5. **Testes de estresse**: Avaliando o desempenho do pipeline sob condições extremas para determinar seus limites + +Testar processos individuais é análogo a testes unitários em outras linguagens. Testar o fluxo de trabalho ou o pipeline inteiro é análogo ao que é chamado de testes de integração em outras linguagens, onde testamos as interações dos componentes. + +[**nf-test**](https://www.nf-test.com/) é uma ferramenta que permite escrever testes no nível de módulo, fluxo de trabalho e pipeline. Em resumo, ele permite verificar sistematicamente que cada parte individual do pipeline está funcionando como esperado, _isoladamente_. + +### Objetivos de aprendizado + +Nesta missão secundária, você aprenderá a usar nf-test para escrever um teste no nível de fluxo de trabalho para o pipeline, bem como testes no nível de módulo para os três processos que ele chama. + +Ao final desta missão secundária, você será capaz de usar as seguintes técnicas efetivamente: + +- Inicializar nf-test no seu projeto +- Gerar testes no nível de módulo e de fluxo de trabalho +- Adicionar tipos comuns de asserções +- Entender quando usar snapshots vs. asserções de conteúdo +- Executar testes para um projeto inteiro + +Essas habilidades ajudarão você a implementar uma estratégia de teste abrangente nos seus projetos de pipeline, garantindo que eles sejam mais robustos e fáceis de manter. + +### Pré-requisitos + +Antes de assumir esta missão secundária, você deve: + +- Ter completado o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores, trabalhando com arquivos, metadados) + +--- + +## 0. Começar + +#### Abrir o codespace de treinamento + +Se você ainda não fez isso, certifique-se de abrir o ambiente de treinamento conforme descrito na [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mover para o diretório do projeto + +Vamos mover para o diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/nf-test +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revisar os materiais + +Você encontrará um arquivo de fluxo de trabalho principal e um arquivo CSV chamado `greetings.csv` que contém a entrada para o pipeline. + +```console title="Conteúdo do diretório" +. +├── greetings.csv +└── main.nf +``` + +Para uma descrição detalhada dos arquivos, consulte o [warmup do Hello Nextflow](../hello_nextflow/00_orientation.md). + +O fluxo de trabalho que testaremos é um subconjunto do fluxo de trabalho Hello construído em [Hello Workflow](../hello_nextflow/03_hello_workflow.md). + +??? example "O que o fluxo de trabalho Hello Nextflow faz?" + + Se você não fez o treinamento [Hello Nextflow](../hello_nextflow/index.md), aqui está uma rápida visão geral do que este fluxo de trabalho simples faz. + + O fluxo de trabalho pega um arquivo CSV contendo saudações, executa quatro etapas de transformação consecutivas nelas, e gera um único arquivo de texto contendo uma imagem ASCII de um personagem divertido dizendo as saudações. + + As quatro etapas são implementadas como processos Nextflow (`sayHello`, `convertToUpper`, `collectGreetings` e `cowpy`) armazenados em arquivos de módulo separados. + + 1. **`sayHello`:** Escreve cada saudação em seu próprio arquivo de saída (ex: "Hello-output.txt") + 2. **`convertToUpper`:** Converte cada saudação para maiúsculas (ex: "HELLO") + 3. **`collectGreetings`:** Coleta todas as saudações em maiúsculas em um único arquivo em lote + 4. **`cowpy`:** Gera arte ASCII usando a ferramenta `cowpy` + + Os resultados são publicados em um diretório chamado `results/`, e a saída final do pipeline (quando executado com parâmetros padrão) é um arquivo de texto simples contendo arte ASCII de um personagem dizendo as saudações em maiúsculas. + + Nesta missão secundária, usamos uma forma intermediária do fluxo de trabalho Hello que contém apenas os dois primeiros processos. <!-- TODO: change this to use the full finished workflow as suggested in https://github.com/nextflow-io/training/issues/735 --> + +O subconjunto com o qual trabalharemos é composto de dois processos: `sayHello` e `convertToUpper`. +Você pode ver o código completo do fluxo de trabalho abaixo. + +??? example "Código do fluxo de trabalho" + + ```groovy title="main.nf" + /* + * Parâmetros do pipeline + */ + params.input_file = "greetings.csv" + + /* + * Usa echo para imprimir 'Hello World!' na saída padrão + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Usa um utilitário de substituição de texto para converter a saudação para maiúsculas + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // cria um canal para entradas de um arquivo CSV + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // emite uma saudação + sayHello(greeting_ch) + + // converte a saudação para maiúsculas + convertToUpper(sayHello.out) + } + ``` + +#### Executar o fluxo de trabalho + +Vamos executar o fluxo de trabalho para ter certeza de que está funcionando como esperado. + +```bash +nextflow run main.nf +``` + +```console title="Resultado da execução do fluxo de trabalho" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +PARABÉNS! Você acabou de executar um teste! + +"Espera, o quê? Eu só executei o fluxo de trabalho e funcionou! Como isso é um teste?" + +Boa pergunta! + +Vamos analisar o que acabou de acontecer. + +Você executou o fluxo de trabalho com os parâmetros padrão, confirmou que funcionou e está satisfeito com os resultados. Esta é a essência dos testes. Se você trabalhou no curso de treinamento Hello Nextflow, terá notado que sempre começamos cada seção executando o fluxo de trabalho que estávamos usando como ponto de partida, para confirmar que tudo está configurado corretamente. + +Testar software essencialmente faz esse processo por nós. + +#### Revisar a tarefa + +Seu desafio é adicionar testes padronizados a este fluxo de trabalho usando nf-test, a fim de facilitar a verificação de que cada parte continua funcionando como esperado caso quaisquer alterações adicionais sejam feitas. + +<!-- TODO: give a bit more details, similar to how it's done in the Metadata side quest --> + +#### Checklist de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Defini meu diretório de trabalho apropriadamente +- [ ] Executei o fluxo de trabalho com sucesso +- [ ] Entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para ir. + +--- + +## 1. Inicializar `nf-test` + +O pacote `nf-test` fornece um comando de inicialização que configura algumas coisas para começarmos a desenvolver testes para nosso projeto. + +```bash +nf-test init +``` + +Isso deve produzir a seguinte saída: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Também cria um diretório `tests` contendo um stub de arquivo de configuração. + +### 1.1. Gerar um nf-test + +`nf-test` vem com um conjunto de ferramentas para construir arquivos nf-test, nos poupando a maior parte do trabalho. Elas vêm sob o subcomando `generate`. Vamos gerar um teste para o pipeline: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Saída" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Isso criará um arquivo `main.nf.test` dentro do diretório `tests`. Este é nosso arquivo de teste no nível de pipeline. Se você executar `tree tests/` você deverá ver algo assim: + +```console title="Conteúdo do diretório de testes" +tests/ +├── main.nf.test +└── nextflow.config +``` + +O arquivo `main.nf.test` é nosso arquivo de teste no nível de pipeline. Vamos abri-lo e dar uma olhada no conteúdo. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Vamos reservar um segundo para entender a estrutura do arquivo de teste. + +O bloco `nextflow_pipeline` é o ponto de entrada para todos os testes no nível de pipeline. Ele contém o seguinte: + +- `name`: O nome do teste. +- `script`: O caminho para o script do pipeline. + +O bloco `test` é o teste real. Ele contém o seguinte: + +- `when`: As condições sob as quais o teste deve ser executado. Isso inclui os parâmetros que serão usados para executar o pipeline. +- `then`: As asserções que devem ser feitas. Isso inclui os resultados esperados do pipeline. + +Em linguagem simples, a lógica do teste se lê da seguinte forma: +"**Quando** estes _parâmetros_ são fornecidos a este _pipeline_, **então** esperamos ver estes resultados." + +Este não é um teste funcional, demonstraremos como transformá-lo em um na próxima seção. + +### Uma Nota sobre Nomes de Testes + +No exemplo acima, usamos o nome padrão "Should run without failures" que é apropriado para um teste básico que apenas verifica se o pipeline é executado com sucesso. No entanto, à medida que adicionamos casos de teste mais específicos, devemos usar nomes mais descritivos que indiquem o que estamos realmente testando. Por exemplo: + +- "Should convert input to uppercase" - ao testar funcionalidade específica +- "Should handle empty input gracefully" - ao testar casos extremos +- "Should respect max memory parameter" - ao testar restrições de recursos +- "Should create expected output files" - ao testar geração de arquivos + +Bons nomes de testes devem: + +1. Começar com "Should" para deixar claro qual é o comportamento esperado +2. Descrever a funcionalidade ou cenário específico sendo testado +3. Ser claro o suficiente para que, se o teste falhar, você saiba qual funcionalidade está quebrada + +À medida que adicionarmos mais asserções e casos de teste específicos mais tarde, usaremos esses nomes mais descritivos para deixar claro o que cada teste está verificando. + +### 1.2. Executar o teste + +Vamos executar o teste para ver o que acontece. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test pipeline fail" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +O teste falha! O que aconteceu? + +1. nf-test tentou executar o pipeline como está, usando as configurações no bloco `when`: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test verificou o status do pipeline e o comparou com o bloco `when`: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +Note como nf-test reportou que o pipeline falhou e forneceu a mensagem de erro do Nextflow: + +```console title="Erro" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Então qual foi o problema? Lembre-se de que o pipeline tem um arquivo greetings.csv no diretório do projeto. Quando nf-test executa o pipeline, ele procurará por este arquivo, mas não consegue encontrá-lo. O arquivo está lá, o que está acontecendo? Bem, se olharmos para o caminho, podemos ver que o teste está ocorrendo no caminho `./nf-test/tests/longHashString/`. Assim como o Nextflow, nf-test cria um novo diretório para cada teste para manter tudo isolado. O arquivo de dados não está localizado lá, então devemos corrigir o caminho para o arquivo no teste original. + +Vamos voltar ao arquivo de teste e mudar o caminho para o arquivo no bloco `when`. + +Você pode estar se perguntando como vamos apontar para a raiz do pipeline no teste. Como esta é uma situação comum, nf-test tem uma série de variáveis globais que podemos usar para facilitar nossas vidas. Você pode encontrar a lista completa [aqui](https://www.nf-test.com/docs/testcases/global_variables/) mas, entretanto, usaremos a variável `projectDir`, que significa a raiz do projeto do pipeline. + +_Antes:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Depois:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +Vamos executar o teste novamente para ver se funciona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline passa" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Sucesso! O pipeline é executado com sucesso e o teste passa. Execute quantas vezes quiser e você sempre obterá o mesmo resultado! + +Por padrão, a saída do Nextflow está oculta, mas para se convencer de que nf-test está definitivamente executando o fluxo de trabalho, você pode usar a flag `--verbose`: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Pipeline executa todos os processos" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Adicionar asserções + +Uma verificação simples é garantir que nosso pipeline está executando todos os processos que esperamos e não pulando nenhum silenciosamente. Lembre-se de que nosso pipeline executa 6 processos, um chamado `sayHello` e um chamado `convertToUpper` para cada uma das 3 saudações. + +Vamos adicionar uma asserção ao nosso teste para verificar se o pipeline executa o número esperado de processos. Também atualizaremos o nome do nosso teste para refletir melhor o que estamos testando. + +**Antes:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Depois:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +O nome do teste agora reflete melhor o que estamos realmente verificando - não apenas que o pipeline é executado sem falhar, mas que ele executa o número esperado de processos. + +Vamos executar o teste novamente para ver se funciona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline passa com asserções" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Sucesso! O pipeline é executado com sucesso e o teste passa. Agora começamos a testar os detalhes do pipeline, bem como o status geral. + +### 1.4. Testar a saída + +Vamos adicionar uma asserção ao nosso teste para verificar se o arquivo de saída foi criado. Vamos adicioná-la como um teste separado, com um nome informativo, para facilitar a interpretação dos resultados. + +**Antes:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Depois:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +Execute o teste novamente para ver se funciona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline passa com asserções de arquivo" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Sucesso! Os testes passam porque o pipeline foi concluído com sucesso, o número correto de processos foi executado e os arquivos de saída foram criados. Isso também deve mostrar a você o quão útil é fornecer esses nomes informativos para seus testes. + +Isso é apenas a superfície, podemos continuar escrevendo asserções para verificar os detalhes do pipeline, mas por enquanto vamos seguir para testar os componentes internos do pipeline. + +### Conclusão + +Você sabe como escrever um nf-test para um pipeline. + +### O que vem a seguir? + +Aprenda como testar um processo Nextflow. + +--- + +## 2. Testar um processo Nextflow + +Não precisamos escrever testes para cada parte do pipeline, mas quanto mais testes tivermos, mais abrangentes podemos ser sobre o pipeline e mais confiantes podemos estar de que está funcionando como esperado. Nesta seção, vamos testar ambos os processos no pipeline como unidades individuais. + +### 2.1. Testar o processo `sayHello` + +Vamos começar com o processo `sayHello`. + +Vamos usar o comando `nf-test generate` novamente para gerar testes para o processo. + +```bash +nf-test generate process main.nf +``` + +```console title="Saída" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Vamos focar por enquanto no processo `sayhello` no arquivo `main.sayhello.nf.test`. + +Vamos abrir o arquivo e dar uma olhada no conteúdo. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Como antes, começamos com os detalhes do teste, seguidos pelos blocos `when` e `then`. No entanto, também temos um bloco `process` adicional que nos permite definir as entradas para o processo. + +Vamos executar o teste para ver se funciona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Teste de processo falha" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +O teste falha porque o processo `sayHello` declara 1 entrada mas foi chamado com 0 argumentos. Vamos corrigir isso adicionando uma entrada ao processo. Lembre-se de [Hello Workflow](../hello_nextflow/03_hello_workflow.md) (e da seção de warmup acima) que nosso processo `sayHello` recebe uma única entrada de valor, que precisaremos fornecer. Também devemos corrigir o nome do teste para refletir melhor o que estamos testando. + +**Antes:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Depois:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Vamos executar o teste novamente para ver se funciona. + +```console title="nf-test pipeline pass" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Sucesso! O teste passa porque o processo `sayHello` foi executado com sucesso e a saída foi criada. + +### 2.2. Verificar o snapshot criado pelo teste + +Se olharmos para o arquivo `tests/main.sayhello.nf.test`, podemos ver que ele usa um método `snapshot()` no bloco de asserção: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Isso está dizendo ao nf-test para criar um snapshot da saída do processo `sayHello`. Vamos dar uma olhada no conteúdo do arquivo de snapshot. + +```console title="Conteúdo do arquivo de snapshot" +code tests/main.sayhello.nf.test.snap +``` + +Não vamos imprimi-lo aqui, mas você deve ver um arquivo JSON contendo detalhes do processo e das saídas do processo. Em particular, podemos ver uma linha que se parece com isso: + +```json title="Conteúdo do arquivo de snapshot" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Isso representa as saídas criadas pelo processo `sayHello`, que estamos testando explicitamente. Se re-executarmos o teste, o programa verificará se a nova saída corresponde à saída que foi originalmente registrada. Esta é uma maneira rápida e simples de testar que as saídas do processo não mudam, razão pela qual nf-test a fornece como padrão. + +!!!warning + + Isso significa que temos que ter certeza de que a saída que registramos na execução original está correta! + +Se, no curso do desenvolvimento futuro, algo no código mudar que faça com que a saída seja diferente, o teste falhará e teremos que determinar se a mudança é esperada ou não. + +- Se acontecer de algo no código ter quebrado, teremos que consertar, com a expectativa de que o código consertado passará no teste. +- Se for uma mudança esperada (por exemplo, a ferramenta foi melhorada e os resultados são melhores), então precisaremos atualizar o snapshot para aceitar a nova saída como a referência a corresponder. nf-test tem um parâmetro `--update-snapshot` para este propósito. + +Podemos executar o teste novamente e ver que o teste deve passar: + +```console title="nf-test process pass com snapshot" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Sucesso! O teste passa porque o processo `sayHello` foi executado com sucesso e a saída correspondeu ao snapshot. + +### 2.3. Alternativa aos Snapshots: Asserções Diretas de Conteúdo + +Embora os snapshots sejam ótimos para capturar quaisquer mudanças na saída, às vezes você quer verificar conteúdo específico sem ser tão rigoroso sobre todo o arquivo corresponder. Por exemplo: + +- Quando partes da saída podem mudar (carimbos de data/hora, IDs aleatórios, etc.), mas certo conteúdo-chave deve estar presente +- Quando você quer verificar padrões ou valores específicos na saída +- Quando você quer tornar o teste mais explícito sobre o que constitui sucesso + +Aqui está como poderíamos modificar nosso teste para verificar conteúdo específico: + +**Antes:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Depois:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // definir parâmetros aqui + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +Note que nf-test vê as saídas do processo como uma lista de listas, então `process.out[0][0]` está buscando a primeira parte do primeiro item do canal (ou 'emissão') deste processo. + +Esta abordagem: + +- Deixa claro exatamente o que esperamos na saída +- É mais resiliente a mudanças irrelevantes na saída +- Fornece melhores mensagens de erro quando os testes falham +- Permite validações mais complexas (padrões regex, comparações numéricas, etc.) + +Vamos executar o teste para ver se funciona. + +```bash title="nf-test pipeline pass" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Teste de processo falha" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. Testar o processo `convertToUpper` + +Vamos abrir o arquivo `tests/main.converttoupper.nf.test` e dar uma olhada no conteúdo: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Este é um teste semelhante ao processo `sayHello`, mas está testando o processo `convertToUpper`. Sabemos que este falhará porque, assim como com `sayHello`, o processo `convertToUpper` recebe uma única entrada de caminho, mas não especificamos uma. + +Agora precisamos fornecer um único arquivo de entrada para o processo convertToUpper, que inclua algum texto que queremos converter para maiúsculas. Há muitas maneiras de fazer isso: + +- Poderíamos criar um arquivo dedicado para testar +- Poderíamos reutilizar o arquivo data/greetings.csv existente +- Poderíamos criá-lo dinamicamente dentro do teste + +Por enquanto, vamos reutilizar o arquivo data/greetings.csv existente usando o exemplo que usamos com o teste no nível de pipeline. Como antes, podemos nomear o teste para refletir melhor o que estamos testando, mas desta vez vamos deixá-lo fazer um 'snapshot' do conteúdo em vez de verificar strings específicas (como fizemos no outro processo). + +**Antes:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Depois:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +E execute o teste! + +```bash title="nf-test pipeline pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Note que criamos um arquivo de snapshot para o processo `convertToUpper` em `tests/main.converttoupper.nf.test.snap`. Se executarmos o teste novamente, deveremos ver que o nf-test passa novamente. + +```bash title="nf-test process convertToUpper pass" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test process convertToUpper pass" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Conclusão + +Você sabe como escrever testes para um processo Nextflow e executá-los. + +### O que vem a seguir? + +Aprenda como executar testes para tudo de uma vez! + +## 3. Executar testes para todo o repositório + +Executar nf-test em cada componente é bom, mas trabalhoso e propenso a erros. Não podemos simplesmente testar tudo de uma vez? + +Sim, podemos! + +Vamos executar nf-test em todo o repositório. + +### 3.1. Executar nf-test em todo o repositório + +Podemos executar nf-test em todo o repositório executando o comando `nf-test test`. + +```bash +nf-test test . +``` + +Note que estamos apenas usando o `.` para executar tudo do nosso diretório atual. Isso incluirá todos os testes! + +```console title="nf-test repo pass" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Olha só isso! Executamos 4 testes, 1 para cada processo e 2 para todo o pipeline com um único comando. Imagine o quão poderoso isso é em uma base de código grande! + +--- + +## Resumo + +Nesta missão secundária, você aprendeu a aproveitar os recursos do nf-test para criar e executar testes para processos individuais, bem como testes de ponta a ponta para todo o pipeline. +Agora você está ciente das duas principais abordagens para validação de saída, snapshots e asserções diretas de conteúdo, e quando usar cada uma. +Você também sabe como executar testes um por um ou para um projeto inteiro. + +Aplicar essas técnicas em seu próprio trabalho permitirá que você garanta que: + +- Seu código funciona como esperado +- Mudanças não quebram funcionalidades existentes +- Outros desenvolvedores podem contribuir com confiança +- Problemas podem ser identificados e corrigidos rapidamente +- O conteúdo da saída corresponde às expectativas + +### Padrões principais + +<!-- TODO: Can we add snippets of code below to illustrate? --> + +1. Testes no nível de pipeline: + - Teste básico de sucesso + - Verificação de contagem de processos + - Verificações de existência de arquivos de saída +2. Testes no nível de processo +3. Duas abordagens para validação de saída: + - Usando snapshots para verificação completa de saída + - Usando asserções diretas de conteúdo para verificações de conteúdo específicas +4. Executando todos os testes em um repositório com um único comando + +### Recursos adicionais + +Confira a [documentação do nf-test](https://www.nf-test.com/) para recursos de teste mais avançados e melhores práticas. Você pode querer: + +- Adicionar asserções mais abrangentes aos seus testes +- Escrever testes para casos extremos e condições de erro +- Configurar integração contínua para executar testes automaticamente +- Aprender sobre outros tipos de testes como testes de fluxo de trabalho e módulo +- Explorar técnicas mais avançadas de validação de conteúdo + +**Lembre-se:** Testes são documentação viva de como seu código deve se comportar. Quanto mais testes você escrever, e quanto mais específicas forem suas asserções, mais confiante você pode estar na confiabilidade do seu pipeline. + +--- + +## O que vem a seguir? + +Retorne ao [menu de Missões Secundárias](./index.md) ou clique no botão no canto inferior direito da página para seguir para o próximo tópico da lista. diff --git a/docs/pt/docs/side_quests/orientation.md b/docs/pt/docs/side_quests/orientation.md new file mode 100644 index 0000000000..21abb7c497 --- /dev/null +++ b/docs/pt/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Orientação + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +O ambiente GitHub Codespaces contém todo o software, código e dados necessários para trabalhar neste curso de treinamento, então você não precisa instalar nada por conta própria. +No entanto, você precisa de uma conta (gratuita) para fazer login, e deve dedicar alguns minutos para se familiarizar com a interface. + +Se você ainda não fez isso, por favor siga [este link](../../envsetup/) antes de prosseguir. + +## Materiais fornecidos + +Ao longo deste curso de treinamento, trabalharemos no diretório `side-quests/`. +Este diretório contém todos os arquivos de código, dados de teste e arquivos acessórios que você precisará. + +Sinta-se livre para explorar o conteúdo deste diretório; a maneira mais fácil de fazer isso é usar o explorador de arquivos no lado esquerdo do espaço de trabalho do GitHub Codespaces. +Como alternativa, você pode usar o comando `tree`. +Ao longo do curso, usamos a saída de `tree` para representar a estrutura e o conteúdo do diretório de forma legível, às vezes com pequenas modificações para maior clareza. + +Aqui geramos um índice de conteúdo até o segundo nível: + +```bash +tree . -L 2 +``` + +Se você executar isso dentro de `side-quests`, deverá ver a seguinte saída: + +```console title="Conteúdo do diretório" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Aqui está um resumo do que você deve saber para começar:** + +- **Cada diretório corresponde a uma missão secundária individual.** + Seus conteúdos são detalhados na página da missão secundária correspondente. + +- **O diretório `solutions`** contém os scripts de fluxo de trabalho e/ou módulo completos que resultam da execução de várias etapas de cada missão secundária. + Eles são destinados a serem usados como referência para verificar seu trabalho e solucionar quaisquer problemas. + +!!!tip "Dica" + + Se por qualquer motivo você sair deste diretório, você sempre pode executar este comando para retornar a ele: + + ```bash + cd /workspaces/training/side-quests + ``` + +Agora, para começar o curso, clique na seta no canto inferior direito desta página. diff --git a/docs/pt/docs/side_quests/splitting_and_grouping.md b/docs/pt/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..53a773ec1f --- /dev/null +++ b/docs/pt/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,1066 @@ +# Divisão e Agrupamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +O Nextflow fornece ferramentas poderosas para trabalhar com dados de forma flexível. Uma capacidade-chave é dividir dados em diferentes fluxos e depois agrupar itens relacionados de volta. Isso é especialmente valioso em fluxos de trabalho de bioinformática onde você precisa processar diferentes tipos de amostras separadamente antes de combinar resultados para análise. + +Pense nisso como classificar correspondências: você separa cartas por destino, processa cada pilha de forma diferente e depois recombina itens indo para a mesma pessoa. O Nextflow usa operadores especiais para realizar isso com dados científicos. Essa abordagem também é comumente conhecida como o padrão **scatter/gather** em computação distribuída e fluxos de trabalho de bioinformática. + +O sistema de canais do Nextflow está no centro dessa flexibilidade. Os canais conectam diferentes partes do seu fluxo de trabalho, permitindo que os dados fluam através da sua análise. Você pode criar múltiplos canais a partir de uma única fonte de dados, processar cada canal de forma diferente e depois mesclar canais de volta quando necessário. Essa abordagem permite que você projete fluxos de trabalho que naturalmente espelham os caminhos de ramificação e convergência de análises complexas de bioinformática. + +### Objetivos de aprendizado + +Nesta missão secundária, você aprenderá a dividir e agrupar dados usando os operadores de canal do Nextflow. +Começaremos com um arquivo CSV contendo informações de amostras e arquivos de dados associados, depois manipularemos e reorganizaremos esses dados. + +Ao final desta missão secundária, você será capaz de separar e combinar fluxos de dados de forma eficaz, usando as seguintes técnicas: + +- Ler dados de arquivos usando `splitCsv` +- Filtrar e transformar dados com `filter` e `map` +- Combinar dados relacionados usando `join` e `groupTuple` +- Criar combinações de dados com `combine` para processamento paralelo +- Otimizar a estrutura de dados usando `subMap` e estratégias de deduplicação +- Construir funções reutilizáveis com closures nomeados para ajudar a manipular estruturas de canal + +Essas habilidades ajudarão você a construir fluxos de trabalho que podem lidar com múltiplos arquivos de entrada e diferentes tipos de dados de forma eficiente, mantendo uma estrutura de código limpa e de fácil manutenção. + +### Pré-requisitos + +Antes de começar esta missão secundária, você deve: + +- Ter completado o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores, trabalhando com arquivos, metadados) + +**Opcional:** Recomendamos completar a missão secundária [Metadados em fluxos de trabalho](./metadata.md) primeiro. +Ela cobre os fundamentos de leitura de arquivos CSV com `splitCsv` e criação de mapas de metadados, que usaremos intensamente aqui. + +--- + +## 0. Primeiros passos + +#### Abrir o codespace de treinamento + +Se você ainda não o fez, certifique-se de abrir o ambiente de treinamento conforme descrito em [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mover para o diretório do projeto + +Vamos mover para o diretório onde os arquivos deste tutorial estão localizados. + +```bash +cd side-quests/splitting_and_grouping +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revisar os materiais + +Você encontrará um arquivo de fluxo de trabalho principal e um diretório `data` contendo uma planilha de amostras chamada `samplesheet.csv`. + +```console title="Conteúdo do diretório" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +A planilha de amostras contém informações sobre amostras de diferentes pacientes, incluindo o ID do paciente, número de repetição da amostra, tipo (normal ou tumor) e caminhos para arquivos de dados hipotéticos (que não existem de fato, mas vamos fingir que existem). + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Esta planilha lista oito amostras de três pacientes (A, B, C). + +Para cada paciente, temos amostras que são do tipo `tumor` (tipicamente originadas de biópsias de tumor) ou `normal` (coletadas de tecido saudável ou sangue). +Se você não está familiarizado com análise de câncer, saiba apenas que isso corresponde a um modelo experimental que usa amostras pareadas tumor/normal para realizar análises contrastivas. + +Para o paciente A especificamente, temos dois conjuntos de réplicas técnicas (repetições). + +!!! note "Nota" + + Não se preocupe se você não está familiarizado com este desenho experimental, não é crítico para entender este tutorial. + +#### Revisar a tarefa + +Seu desafio é escrever um fluxo de trabalho Nextflow que irá: + +1. **Ler** dados de amostras de um arquivo CSV e estruturá-los com mapas de metadados +2. **Separar** amostras em diferentes canais com base no tipo (normal vs tumor) +3. **Unir** pares correspondentes tumor/normal por ID do paciente e número de réplica +4. **Distribuir** amostras através de intervalos genômicos para processamento paralelo +5. **Agrupar** amostras relacionadas de volta para análise downstream + +Isso representa um padrão comum de bioinformática onde você precisa dividir dados para processamento independente, depois recombinar itens relacionados para análise comparativa. + +#### Lista de verificação de prontidão + +Acha que está pronto para começar? + +- [ ] Entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Defini meu diretório de trabalho apropriadamente +- [ ] Entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Ler dados de amostras + +### 1.1. Ler dados de amostras com `splitCsv` e criar mapas de metadados + +Vamos começar lendo os dados de amostras com `splitCsv` e organizando-os no padrão de mapa de metadados. No `main.nf`, você verá que já começamos o fluxo de trabalho. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note "Nota" + + Ao longo deste tutorial, usaremos o prefixo `ch_` para todas as variáveis de canal para indicar claramente que são canais Nextflow. + +Se você completou a missão secundária [Metadados em fluxos de trabalho](./metadata.md), você reconhecerá esse padrão. Usaremos `splitCsv` para ler o CSV e imediatamente estruturar os dados com um mapa de metadados para separar metadados de caminhos de arquivo. + +!!! info + + Encontraremos dois conceitos diferentes chamados `map` neste treinamento: + + - **Estrutura de dados**: O mapa Groovy (equivalente a dicionários/hashes em outras linguagens) que armazena pares chave-valor + - **Operador de canal**: O operador `.map()` que transforma itens em um canal + + Esclareceremos qual deles queremos dizer no contexto, mas essa distinção é importante para entender ao trabalhar com Nextflow. + +Aplique estas mudanças ao `main.nf`: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Isso combina a operação `splitCsv` (lendo o CSV com cabeçalhos) e a operação `map` (estruturando dados como tuplas `[meta, file]`) em uma etapa. Aplique essa mudança e execute o pipeline: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Agora temos um canal onde cada item é uma tupla `[meta, file]` - metadados separados de caminhos de arquivo. Esta estrutura nos permite dividir e agrupar nossa carga de trabalho com base em campos de metadados. + +--- + +## 2. Filtrar e transformar dados + +### 2.1. Filtrar dados com `filter` + +Podemos usar o [operador `filter`](https://www.nextflow.io/docs/latest/operator.html#filter) para filtrar os dados com base em uma condição. Digamos que queremos processar apenas amostras normais. Podemos fazer isso filtrando os dados com base no campo `type`. Vamos inserir isso antes do operador `view`. + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Execute o fluxo de trabalho novamente para ver o resultado filtrado: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Filtramos com sucesso os dados para incluir apenas amostras normais. Vamos recapitular como isso funciona. + +O operador `filter` recebe um closure que é aplicado a cada elemento no canal. Se o closure retornar `true`, o elemento é incluído; se retornar `false`, o elemento é excluído. + +No nosso caso, queremos manter apenas amostras onde `meta.type == 'normal'`. O closure usa a tupla `meta,file` para se referir a cada amostra, acessa o tipo de amostra com `meta.type` e verifica se é igual a `'normal'`. + +Isso é realizado com o único closure que introduzimos acima: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Criar canais filtrados separados + +Atualmente estamos aplicando o filtro ao canal criado diretamente do CSV, mas queremos filtrar isso de mais de uma maneira, então vamos reescrever a lógica para criar um canal filtrado separado para amostras normais: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Execute o pipeline para ver os resultados: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Filtramos com sucesso os dados e criamos um canal separado para amostras normais. + +Vamos criar um canal filtrado para as amostras de tumor também: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Separamos as amostras normais e de tumor em dois canais diferentes e usamos um closure fornecido a `view()` para rotulá-las de forma diferente na saída: `ch_tumor_samples.view{'Tumor sample: ' + it}`. + +### Conclusão + +Nesta seção, você aprendeu: + +- **Filtrar dados**: Como filtrar dados com `filter` +- **Dividir dados**: Como dividir dados em diferentes canais com base em uma condição +- **Visualizar dados**: Como usar `view` para imprimir os dados e rotular a saída de diferentes canais + +Agora separamos as amostras normais e de tumor em dois canais diferentes. Em seguida, vamos unir as amostras normais e de tumor no campo `id`. + +--- + +## 3. Unir canais por identificadores + +Na seção anterior, separamos as amostras normais e de tumor em dois canais diferentes. Elas poderiam ser processadas independentemente usando processos ou fluxos de trabalho específicos com base em seu tipo. Mas o que acontece quando queremos comparar as amostras normais e de tumor do mesmo paciente? Neste ponto, precisamos uni-las de volta, certificando-nos de combinar as amostras com base em seu campo `id`. + +O Nextflow inclui muitos métodos para combinar canais, mas neste caso o operador mais apropriado é [`join`](https://www.nextflow.io/docs/latest/operator.html#join). Se você está familiarizado com SQL, ele age como a operação `JOIN`, onde especificamos a chave para unir e o tipo de junção a ser executada. + +### 3.1. Usar `map` e `join` para combinar com base no ID do paciente + +Se verificarmos a documentação do [`join`](https://www.nextflow.io/docs/latest/operator.html#join), podemos ver que por padrão ele une dois canais com base no primeiro item em cada tupla. + +#### 3.1.1. Verificar a estrutura de dados + +Se você não tem a saída do console ainda disponível, vamos executar o pipeline para verificar nossa estrutura de dados e ver como precisamos modificá-la para unir no campo `id`. + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tumor sample: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal sample: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tumor sample: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Podemos ver que o campo `id` é o primeiro elemento em cada mapa de metadados. Para que `join` funcione, devemos isolar o campo `id` em cada tupla. Depois disso, podemos simplesmente usar o operador `join` para combinar os dois canais. + +#### 3.1.2. Isolar o campo `id` + +Para isolar o campo `id`, podemos usar o [operador `map`](https://www.nextflow.io/docs/latest/operator.html#map) para criar uma nova tupla com o campo `id` como o primeiro elemento. + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tumor sample: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tumor sample: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal sample: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal sample: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tumor sample: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tumor sample: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal sample: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal sample: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Pode ser sutil, mas você deve ser capaz de ver que o primeiro elemento em cada tupla é o campo `id`. + +#### 3.1.3. Combinar os dois canais + +Agora podemos usar o operador `join` para combinar os dois canais com base no campo `id`. + +Mais uma vez, usaremos `view` para imprimir as saídas unidas. + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal sample: ' + it} + ch_tumor_samples + .view{'Tumor sample: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +É um pouco difícil de ver porque é muito largo, mas você deve ser capaz de ver que as amostras foram unidas pelo campo `id`. Cada tupla agora tem o formato: + +- `id`: O ID da amostra +- `normal_meta_map`: Os metadados da amostra normal incluindo tipo, réplica e caminho para o arquivo bam +- `normal_sample_file`: O arquivo da amostra normal +- `tumor_meta_map`: Os metadados da amostra de tumor incluindo tipo, réplica e caminho para o arquivo bam +- `tumor_sample`: A amostra de tumor incluindo tipo, réplica e caminho para o arquivo bam + +!!! warning "Aviso" + + O operador `join` descartará quaisquer tuplas não correspondidas. Neste exemplo, garantimos que todas as amostras fossem correspondidas para tumor e normal, mas se isso não for verdade você deve usar o parâmetro `remainder: true` para manter as tuplas não correspondidas. Consulte a [documentação](https://www.nextflow.io/docs/latest/operator.html#join) para mais detalhes. + +Então agora você sabe como usar `map` para isolar um campo em uma tupla, e como usar `join` para combinar tuplas com base no primeiro campo. +Com esse conhecimento, podemos combinar com sucesso canais com base em um campo compartilhado. + +Em seguida, consideraremos a situação onde você quer unir em múltiplos campos. + +### 3.2. Unir em múltiplos campos + +Temos 2 réplicas para a sampleA, mas apenas 1 para sampleB e sampleC. Neste caso fomos capazes de uni-las efetivamente usando o campo `id`, mas o que aconteceria se estivessem fora de sincronia? Poderíamos misturar as amostras normais e de tumor de diferentes réplicas! + +Para evitar isso, podemos unir em múltiplos campos. Na verdade, existem várias maneiras de fazer isso, mas vamos focar em criar uma nova chave de junção que inclui tanto o `id` da amostra quanto o número de `replicate`. + +Vamos começar criando uma nova chave de junção. Podemos fazer isso da mesma forma que antes, usando o [operador `map`](https://www.nextflow.io/docs/latest/operator.html#map) para criar uma nova tupla com os campos `id` e `repeat` como o primeiro elemento. + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Agora devemos ver a junção ocorrendo, mas usando tanto os campos `id` quanto `repeat`. Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Note como temos uma tupla de dois elementos (campos `id` e `repeat`) como o primeiro elemento de cada resultado unido. Isso demonstra como itens complexos podem ser usados como uma chave de junção, permitindo correspondências bastante intrincadas entre amostras das mesmas condições. + +Se você quiser explorar mais maneiras de unir em chaves diferentes, consulte a [documentação do operador join](https://www.nextflow.io/docs/latest/operator.html#join) para opções e exemplos adicionais. + +### 3.3. Usar `subMap` para criar uma nova chave de junção + +A abordagem anterior perde os nomes dos campos da nossa chave de junção - os campos `id` e `repeat` se tornam apenas uma lista de valores. Para reter os nomes dos campos para acesso posterior, podemos usar o [método `subMap`](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>). + +O método `subMap` extrai apenas os pares chave-valor especificados de um mapa. Aqui extrairemos apenas os campos `id` e `repeat` para criar nossa chave de junção. + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Agora temos uma nova chave de junção que não apenas inclui os campos `id` e `repeat`, mas também retém os nomes dos campos para que possamos acessá-los mais tarde por nome, por exemplo `meta.id` e `meta.repeat`. + +### 3.4. Usar um closure nomeado em map + +Para evitar duplicação e reduzir erros, podemos usar um closure nomeado. Um closure nomeado nos permite criar uma função reutilizável que podemos chamar em vários lugares. + +Para fazer isso, primeiro definimos o closure como uma nova variável: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Definimos a transformação do map como uma variável nomeada que podemos reutilizar. + +Note que também convertemos o caminho do arquivo para um objeto Path usando `file()` para que qualquer processo recebendo este canal possa lidar com o arquivo corretamente (para mais informações veja [Trabalhando com arquivos](./working_with_files.md)). + +Vamos implementar o closure em nosso fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note "Nota" + + O operador `map` mudou de usar `{ }` para usar `( )` para passar o closure como um argumento. Isso ocorre porque o operador `map` espera um closure como argumento e `{ }` é usado para definir um closure anônimo. Ao chamar um closure nomeado, use a sintaxe `( )`. + +Execute o fluxo de trabalho mais uma vez para verificar se tudo ainda está funcionando: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Usar um closure nomeado nos permite reutilizar a mesma transformação em vários lugares, reduzindo o risco de erros e tornando o código mais legível e de fácil manutenção. + +### 3.5. Reduzir duplicação de dados + +Temos muitos dados duplicados em nosso fluxo de trabalho. Cada item nas amostras unidas repete os campos `id` e `repeat`. Como essa informação já está disponível na chave de agrupamento, podemos evitar essa redundância. Como lembrete, nossa estrutura de dados atual se parece com isso: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +Como os campos `id` e `repeat` estão disponíveis na chave de agrupamento, vamos removê-los do resto de cada item do canal para evitar duplicação. Podemos fazer isso usando o método `subMap` para criar um novo mapa com apenas o campo `type`. Essa abordagem nos permite manter todas as informações necessárias enquanto eliminamos redundância em nossa estrutura de dados. + +=== "Depois" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Agora o closure retorna uma tupla onde o primeiro elemento contém os campos `id` e `repeat`, e o segundo elemento contém apenas o campo `type`. Isso elimina redundância armazenando as informações de `id` e `repeat` uma vez na chave de agrupamento, mantendo todas as informações necessárias. + +Execute o fluxo de trabalho para ver como isso se parece: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +Podemos ver que só declaramos os campos `id` e `repeat` uma vez na chave de agrupamento e temos o campo `type` nos dados da amostra. Não perdemos nenhuma informação, mas conseguimos tornar o conteúdo do nosso canal mais sucinto. + +### 3.6. Remover informações redundantes + +Removemos informações duplicadas acima, mas ainda temos algumas outras informações redundantes em nossos canais. + +No início, separamos as amostras normais e de tumor usando `filter`, depois as unimos com base nas chaves `id` e `repeat`. O operador `join` preserva a ordem em que as tuplas são mescladas, então no nosso caso, com amostras normais no lado esquerdo e amostras de tumor no lado direito, o canal resultante mantém esta estrutura: `id, <elementos normais>, <elementos tumor>`. + +Como sabemos a posição de cada elemento em nosso canal, podemos simplificar ainda mais a estrutura removendo os metadados `[type:normal]` e `[type:tumor]`. + +=== "Depois" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Execute novamente para ver o resultado: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Conclusão + +Nesta seção, você aprendeu: + +- **Manipular Tuplas**: Como usar `map` para isolar um campo em uma tupla +- **Unir Tuplas**: Como usar `join` para combinar tuplas com base no primeiro campo +- **Criar Chaves de Junção**: Como usar `subMap` para criar uma nova chave de junção +- **Closures Nomeados**: Como usar um closure nomeado em map +- **Junção em Múltiplos Campos**: Como unir em múltiplos campos para correspondência mais precisa +- **Otimização da Estrutura de Dados**: Como simplificar a estrutura do canal removendo informações redundantes + +Você agora tem um fluxo de trabalho que pode dividir uma planilha de amostras, filtrar as amostras normais e de tumor, uni-las por ID de amostra e número de réplica, depois imprimir os resultados. + +Este é um padrão comum em fluxos de trabalho de bioinformática onde você precisa combinar amostras ou outros tipos de dados após processamento independente, então é uma habilidade útil. Em seguida, vamos olhar para repetir uma amostra várias vezes. + +## 4. Distribuir amostras em intervalos + +Um padrão-chave em fluxos de trabalho de bioinformática é distribuir análises através de regiões genômicas. Por exemplo, a chamada de variantes pode ser paralelizada dividindo o genoma em intervalos (como cromossomos ou regiões menores). Essa estratégia de paralelização melhora significativamente a eficiência do pipeline distribuindo a carga computacional entre múltiplos núcleos ou nós, reduzindo o tempo total de execução. + +Na seção seguinte, demonstraremos como distribuir nossos dados de amostras através de múltiplos intervalos genômicos. Vamos parear cada amostra com cada intervalo, permitindo processamento paralelo de diferentes regiões genômicas. Isso multiplicará o tamanho do nosso conjunto de dados pelo número de intervalos, criando múltiplas unidades de análise independentes que podem ser reunidas mais tarde. + +### 4.1. Distribuir amostras em intervalos usando `combine` + +Vamos começar criando um canal de intervalos. Para manter a vida simples, usaremos apenas 3 intervalos que definiremos manualmente. Em um fluxo de trabalho real, você poderia lê-los de uma entrada de arquivo ou até criar um canal com vários arquivos de intervalo. + +=== "Depois" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Agora lembre-se, queremos repetir cada amostra para cada intervalo. Isso às vezes é chamado de produto cartesiano das amostras e intervalos. Podemos conseguir isso usando o [operador `combine`](https://www.nextflow.io/docs/latest/operator.html#combine). Isso pegará cada item do canal 1 e o repetirá para cada item no canal 2. Vamos adicionar um operador combine ao nosso fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Agora vamos executá-lo e ver o que acontece: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Sucesso! Repetimos cada amostra para cada intervalo em nossa lista de 3 intervalos. Efetivamente triplicamos o número de itens em nosso canal. + +É um pouco difícil de ler, então na próxima seção vamos organizá-lo. + +### 4.2. Organizar o canal + +Podemos usar o operador `map` para organizar e refatorar nossos dados de amostras para que seja mais fácil de entender. Vamos mover a string de intervalos para o mapa de junção no primeiro elemento. + +=== "Depois" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Vamos analisar o que essa operação map faz passo a passo. + +Primeiro, usamos parâmetros nomeados para tornar o código mais legível. Ao usar os nomes `grouping_key`, `normal`, `tumor` e `interval`, podemos nos referir aos elementos na tupla por nome em vez de por índice: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Em seguida, combinamos o `grouping_key` com o campo `interval`. O `grouping_key` é um mapa contendo os campos `id` e `repeat`. Criamos um novo mapa com o `interval` e os mesclamos usando a adição de mapas do Groovy (`+`): + +```groovy + grouping_key + [interval: interval], +``` + +Finalmente, retornamos isso como uma tupla com três elementos: o mapa de metadados combinado, o arquivo da amostra normal e o arquivo da amostra de tumor: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Vamos executá-lo novamente e verificar o conteúdo do canal: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Usar `map` para forçar seus dados na estrutura correta pode ser complicado, mas é crucial para manipulação eficaz de dados. + +Agora temos cada amostra repetida em todos os intervalos genômicos, criando múltiplas unidades de análise independentes que podem ser processadas em paralelo. Mas e se quisermos trazer amostras relacionadas de volta? Na próxima seção, aprenderemos como agrupar amostras que compartilham atributos comuns. + +### Conclusão + +Nesta seção, você aprendeu: + +- **Distribuir amostras em intervalos**: Como usar `combine` para repetir amostras em intervalos +- **Criar produtos cartesianos**: Como gerar todas as combinações de amostras e intervalos +- **Organizar estrutura de canal**: Como usar `map` para reestruturar dados para melhor legibilidade +- **Preparação para processamento paralelo**: Como configurar dados para análise distribuída + +## 5. Agregar amostras usando `groupTuple` + +Nas seções anteriores, aprendemos como dividir dados de um arquivo de entrada e filtrar por campos específicos (no nosso caso amostras normais e de tumor). Mas isso cobre apenas um tipo de junção. E se quisermos agrupar amostras por um atributo específico? Por exemplo, em vez de unir pares correspondentes normal-tumor, podemos querer processar todas as amostras de "sampleA" juntas independentemente de seu tipo. Esse padrão é comum em fluxos de trabalho de bioinformática onde você pode querer processar amostras relacionadas separadamente por razões de eficiência antes de comparar ou combinar os resultados no final. + +O Nextflow inclui métodos integrados para fazer isso, o principal que vamos olhar é `groupTuple`. + +Vamos começar agrupando todas as nossas amostras que têm os mesmos campos `id` e `interval`, isso seria típico de uma análise onde quiséssemos agrupar réplicas técnicas mas manter amostras significativamente diferentes separadas. + +Para fazer isso, devemos separar nossas variáveis de agrupamento para que possamos usá-las isoladamente. + +O primeiro passo é similar ao que fizemos na seção anterior. Devemos isolar nossa variável de agrupamento como o primeiro elemento da tupla. Lembre-se, nosso primeiro elemento é atualmente um mapa dos campos `id`, `repeat` e `interval`: + +```groovy title="main.nf" linenums="1" +{ + "id": "sampleA", + "repeat": "1", + "interval": "chr1" +} +``` + +Podemos reutilizar o método `subMap` de antes para isolar nossos campos `id` e `interval` do mapa. Como antes, usaremos o operador `map` para aplicar o método `subMap` ao primeiro elemento da tupla para cada amostra. + +=== "Depois" + + ```groovy title="main.nf" linenums="20" hl_lines="11-19" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="20" hl_lines="10" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +Vamos executá-lo novamente e verificar o conteúdo do canal: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [hopeful_brenner] DSL2 - revision: 7f4f7fea76 + + [[id:patientA, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr1], patient diff --git a/docs/pt/docs/side_quests/workflows_of_workflows.md b/docs/pt/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..3d4e71dbfb --- /dev/null +++ b/docs/pt/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,467 @@ +# Fluxos de Trabalho de Fluxos de Trabalho + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Quando você está desenvolvendo um pipeline, frequentemente se encontra criando sequências semelhantes de processos para diferentes tipos de dados ou etapas de análise. Você pode acabar copiando e colando essas sequências de processos, levando a código duplicado que é difícil de manter; ou você pode criar um fluxo de trabalho massivo que é difícil de entender e modificar. + +Uma das características mais poderosas do Nextflow é sua capacidade de compor pipelines complexos a partir de módulos de fluxo de trabalho menores e reutilizáveis. Essa abordagem modular torna os pipelines mais fáceis de desenvolver, testar e manter. + +### Objetivos de aprendizado + +Nesta missão secundária, exploraremos como desenvolver módulos de fluxo de trabalho que podem ser testados e usados separadamente, compor esses módulos em um pipeline maior e gerenciar o fluxo de dados entre módulos. + +Ao final desta missão secundária, você será capaz de: + +- Dividir pipelines complexos em unidades lógicas e reutilizáveis +- Testar cada módulo de fluxo de trabalho independentemente +- Combinar e misturar fluxos de trabalho para criar novos pipelines +- Compartilhar módulos de fluxo de trabalho comuns entre diferentes pipelines +- Tornar seu código mais manutenível e fácil de entender + +Essas habilidades ajudarão você a construir pipelines complexos mantendo uma estrutura de código limpa e manutenível. + +### Pré-requisitos + +Antes de começar esta missão secundária você deve: + +- Ter completado o tutorial [Hello Nextflow](../hello_nextflow/README.md) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores, módulos) + +--- + +## 0. Começando + +#### Abra o codespace de treinamento + +Se você ainda não o fez, certifique-se de abrir o ambiente de treinamento conforme descrito em [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Mova-se para o diretório do projeto + +Vamos mover para o diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/workflows_of_workflows +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revise os materiais + +Você encontrará um diretório `modules` contendo várias definições de processos que se baseiam no que você aprendeu em 'Hello Nextflow': + +```console title="Conteúdo do diretório" +modules/ +├── say_hello.nf # Cria uma saudação (de Hello Nextflow) +├── say_hello_upper.nf # Converte para maiúsculas (de Hello Nextflow) +├── timestamp_greeting.nf # Adiciona timestamps às saudações +├── validate_name.nf # Valida nomes de entrada +└── reverse_text.nf # Reverte conteúdo de texto +``` + +#### Revise a tarefa + +Seu desafio é montar esses módulos em dois fluxos de trabalho separados que então comporemos em um fluxo de trabalho principal: + +- Um `GREETING_WORKFLOW` que valida nomes, cria saudações e adiciona timestamps +- Um `TRANSFORM_WORKFLOW` que converte texto para maiúsculas e o reverte + +#### Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Configurei meu diretório de trabalho apropriadamente +- [ ] Eu entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Crie o Fluxo de Trabalho de Saudação + +Vamos começar criando um fluxo de trabalho que valida nomes e gera saudações com timestamp. + +### 1.1. Crie a estrutura do fluxo de trabalho + +```bash title="Crie o diretório e arquivo do fluxo de trabalho" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. Adicione o código do primeiro (sub)fluxo de trabalho + +Adicione este código a `workflows/greeting.nf`: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Encadeia processos: validar -> criar saudação -> adicionar timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Este é um fluxo de trabalho completo, com uma estrutura semelhante aos que você viu no tutorial 'Hello Nextflow', que podemos testar independentemente. Vamos tentar isso agora: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Isso funciona como esperado, mas para torná-lo componível há algumas coisas que precisamos mudar. + +### 1.3. Torne o fluxo de trabalho componível + +Fluxos de trabalho componíveis têm algumas diferenças dos que você viu no tutorial 'Hello Nextflow': + +- O bloco workflow precisa ser nomeado +- Entradas são declaradas usando a palavra-chave `take:` +- O conteúdo do fluxo de trabalho é colocado dentro do bloco `main:` +- Saídas são declaradas usando a palavra-chave `emit:` + +Vamos atualizar o fluxo de trabalho de saudação para corresponder a esta estrutura. Mude o código para o seguinte: + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="6 7 9 15 16 17" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // Canal de entrada com nomes + + main: + // Encadeia processos: validar -> criar saudação -> adicionar timestamp + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Saudações originais + timestamped = timestamped_ch // Saudações com timestamp +} +``` + +Você pode ver que o fluxo de trabalho agora está nomeado e tem um bloco `take:` e `emit:`, e essas são as conexões que usaremos para compor um fluxo de trabalho de nível superior. +O conteúdo do fluxo de trabalho também é colocado dentro do bloco `main:`. Note também que removemos a declaração do canal de entrada `names_ch`, pois ele agora é passado como um argumento para o fluxo de trabalho. + +Vamos testar o fluxo de trabalho novamente para ver se funciona como esperado: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Isso informa sobre outro novo conceito, um 'fluxo de trabalho de entrada'. O fluxo de trabalho de entrada é o fluxo de trabalho que é chamado quando você executa um script Nextflow. Por padrão, o Nextflow usará um fluxo de trabalho sem nome como fluxo de trabalho de entrada, quando presente, e é isso que você tem feito até agora, com blocos workflow começando assim: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Mas nosso fluxo de trabalho de saudação não tem um fluxo de trabalho sem nome, em vez disso temos um fluxo de trabalho nomeado: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +É por isso que o Nextflow lançou um erro e não fez o que queríamos. + +Não adicionamos a sintaxe `take:`/`emit:` para que pudéssemos chamar o fluxo de trabalho diretamente - fizemos isso para que pudéssemos compô-lo com outros fluxos de trabalho. A solução é criar um script principal com um fluxo de trabalho de entrada sem nome que importa e chama nosso fluxo de trabalho nomeado. + +### 1.4. Crie e teste o fluxo de trabalho principal + +Agora criaremos um fluxo de trabalho principal que importa e usa o fluxo de trabalho `greeting`. + +Crie `main.nf`: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Original: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Timestamped: $it" } +} + +``` + +Note que nossa entrada de fluxo de trabalho neste arquivo não tem nome, e isso é porque vamos usá-la como um fluxo de trabalho de entrada. + +Execute isso e veja a saída: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Original: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Original: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Timestamped: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Funciona! Envolvemos o fluxo de trabalho de saudação nomeado em um fluxo de trabalho principal com um bloco `workflow` de entrada sem nome. O fluxo de trabalho principal está usando o fluxo de trabalho `GREETING_WORKFLOW` quase (não exatamente) como um processo, e passando o canal `names` como um argumento. + +### Conclusão + +Nesta seção, você aprendeu vários conceitos importantes: + +- **Fluxos de Trabalho Nomeados**: Criar um fluxo de trabalho nomeado (`GREETING_WORKFLOW`) que pode ser importado e reutilizado +- **Interfaces de Fluxo de Trabalho**: Definir entradas claras com `take:` e saídas com `emit:` para criar um fluxo de trabalho componível +- **Pontos de Entrada**: Entender que o Nextflow precisa de um fluxo de trabalho de entrada sem nome para executar um script +- **Composição de Fluxo de Trabalho**: Importar e usar um fluxo de trabalho nomeado dentro de outro fluxo de trabalho +- **Namespaces de Fluxo de Trabalho**: Acessar saídas de fluxo de trabalho usando o namespace `.out` (`GREETING_WORKFLOW.out.greetings`) + +Você agora tem um fluxo de trabalho de saudação funcionando que: + +- Recebe um canal de nomes como entrada +- Valida cada nome +- Cria uma saudação para cada nome válido +- Adiciona timestamps às saudações +- Expõe tanto as saudações originais quanto as com timestamp como saídas + +Essa abordagem modular permite que você teste o fluxo de trabalho de saudação independentemente ou o use como um componente em pipelines maiores. + +--- + +## 2. Adicione o Fluxo de Trabalho de Transformação + +Agora vamos criar um fluxo de trabalho que aplica transformações de texto às saudações. + +### 2.1. Crie o arquivo do fluxo de trabalho + +```bash +touch workflows/transform.nf +``` + +### 2.2. Adicione o código do fluxo de trabalho + +Adicione este código a `workflows/transform.nf`: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Canal de entrada com mensagens + + main: + // Aplica transformações em sequência + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Saudações em maiúsculas + reversed = reversed_ch // Saudações em maiúsculas revertidas +} +``` + +Não repetiremos a explicação da sintaxe componível aqui, mas note que o fluxo de trabalho nomeado é novamente declarado com um bloco `take:` e `emit:`, e o conteúdo do fluxo de trabalho é colocado dentro do bloco `main:`. + +### 2.3. Atualize o fluxo de trabalho principal + +Atualize `main.nf` para usar ambos os fluxos de trabalho: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Executa o fluxo de trabalho de saudação + GREETING_WORKFLOW(names) + + // Executa o fluxo de trabalho de transformação + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Visualiza os resultados + TRANSFORM_WORKFLOW.out.upper.view { "Uppercase: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Reversed: $it" } +} +``` + +Execute o pipeline completo: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Uppercase: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Reversed: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Se você der uma olhada em um desses arquivos revertidos, verá que é a versão em maiúsculas da saudação revertida: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Conteúdo do arquivo revertido" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Conclusão + +Você agora deve ter um pipeline completo que: + +- Processa nomes através do fluxo de trabalho de saudação +- Alimenta as saudações com timestamp no fluxo de trabalho de transformação +- Produz versões em maiúsculas e revertidas das saudações + +--- + +## Resumo + +Nesta missão secundária, exploramos o poderoso conceito de composição de fluxo de trabalho no Nextflow, que nos permite construir pipelines complexos a partir de componentes menores e reutilizáveis. + +Essa abordagem modular oferece várias vantagens sobre pipelines monolíticos: + +- Cada fluxo de trabalho pode ser desenvolvido, testado e depurado independentemente +- Fluxos de trabalho podem ser reutilizados em diferentes pipelines +- A estrutura geral do pipeline torna-se mais legível e manutenível +- Mudanças em um fluxo de trabalho não necessariamente afetam outros se as interfaces permanecerem consistentes +- Pontos de entrada podem ser configurados para executar diferentes partes do seu pipeline conforme necessário + +_É importante notar, no entanto, que embora chamar fluxos de trabalho seja um pouco como chamar processos, não é realmente a mesma coisa. Você não pode, por exemplo, executar um fluxo de trabalho N vezes chamando-o com um canal de tamanho N - você precisaria passar um canal de tamanho N para o fluxo de trabalho e iterar internamente._ + +Aplicar essas técnicas em seu próprio trabalho permitirá que você construa pipelines Nextflow mais sofisticados que podem lidar com tarefas complexas de bioinformática mantendo-se manuteníveis e escaláveis. + +### Padrões principais + +1. **Estrutura de fluxo de trabalho**: Definimos entradas e saídas claras para cada fluxo de trabalho usando a sintaxe `take:` e `emit:`, criando interfaces bem definidas entre componentes, e envolvemos a lógica do fluxo de trabalho dentro do bloco `main:`. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Canais de entrada são declarados aqui + input_ch + + main: + // Lógica do fluxo de trabalho vai aqui + // Aqui é onde processos são chamados e canais são manipulados + result_ch = SOME_PROCESS(input_ch) + + emit: + // Canais de saída são declarados aqui + output_ch = result_ch + } + ``` + +2. **Importações de fluxo de trabalho:** Construímos dois módulos de fluxo de trabalho independentes e os importamos em um pipeline principal com declarações include. + + - Incluir um único fluxo de trabalho + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Incluir múltiplos fluxos de trabalho + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Incluir com alias para evitar conflitos de nomes + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Pontos de entrada**: O Nextflow requer um fluxo de trabalho de entrada sem nome para saber onde começar a execução. Este fluxo de trabalho de entrada chama seus fluxos de trabalho nomeados. + + - Fluxo de trabalho sem nome (ponto de entrada) + + ```groovy + workflow { + // Este é o ponto de entrada quando o script é executado + NAMED_WORKFLOW(input_ch) + } + ``` + + - Fluxo de trabalho nomeado (chamado do fluxo de trabalho de entrada) + + ```groovy + workflow NAMED_WORKFLOW { + // Deve ser chamado do fluxo de trabalho de entrada + } + ``` + +4. **Gerenciando fluxo de dados:** Aprendemos como acessar saídas de fluxo de trabalho usando a notação de namespace (`WORKFLOW_NAME.out.channel_name`) e passá-las para outros fluxos de trabalho. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Recursos adicionais + +- [Documentação de Workflow do Nextflow](https://www.nextflow.io/docs/latest/workflow.html) +- [Referência de Operadores de Canal](https://www.nextflow.io/docs/latest/operator.html) +- [Documentação de Estratégia de Erro](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## O que vem a seguir? + +Retorne ao [menu de Missões Secundárias](./index.md) ou clique no botão no canto inferior direito da página para passar para o próximo tópico da lista. diff --git a/docs/pt/docs/side_quests/working_with_files.md b/docs/pt/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..a6de62eb75 --- /dev/null +++ b/docs/pt/docs/side_quests/working_with_files.md @@ -0,0 +1,1297 @@ +# Processamento de entrada de arquivos + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Fluxos de trabalho de análise científica frequentemente envolvem o processamento de grandes números de arquivos. +Nextflow fornece ferramentas poderosas para lidar com arquivos de forma eficiente, ajudando você a organizar e processar seus dados com o mínimo de código. + +### Objetivos de aprendizado + +Nesta side quest, vamos explorar como Nextflow lida com arquivos, desde operações básicas até técnicas mais avançadas para trabalhar com coleções de arquivos. +Você aprenderá como extrair metadados de nomes de arquivos, que é um requisito comum em pipelines de análise científica. + +Ao final desta side quest, você será capaz de: + +- Criar objetos Path a partir de strings de caminhos de arquivos usando o método `file()` do Nextflow +- Acessar atributos de arquivo como nome, extensão e diretório pai +- Lidar com arquivos locais e remotos de forma transparente usando URIs +- Usar canais para automatizar o manuseio de arquivos com `channel.fromPath()` e `channel.fromFilePairs()` +- Extrair e estruturar metadados de nomes de arquivos usando manipulação de strings +- Agrupar arquivos relacionados usando correspondência de padrões e expressões glob +- Integrar operações de arquivo em processos Nextflow com manuseio de entrada apropriado +- Organizar saídas de processos usando estruturas de diretórios baseadas em metadados + +Essas habilidades ajudarão você a construir fluxos de trabalho que podem lidar com diferentes tipos de entradas de arquivo com grande flexibilidade. + +### Pré-requisitos + +Antes de enfrentar esta side quest, você deve: + +- Ter completado o tutorial [Hello Nextflow](../../hello_nextflow/) ou curso equivalente para iniciantes. +- Estar confortável usando conceitos e mecanismos básicos do Nextflow (processos, canais, operadores) + +<!-- I removed the suggestion to do the metamaps SQ first because that works more naturally after --> + +--- + +## 0. Comece + +#### Abra o codespace de treinamento + +Se você ainda não fez isso, certifique-se de abrir o ambiente de treinamento conforme descrito em [Configuração do Ambiente](../envsetup/index.md). + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Entre no diretório do projeto + +Vamos entrar no diretório onde os arquivos para este tutorial estão localizados. + +```bash +cd side-quests/working_with_files +``` + +Você pode configurar o VSCode para focar neste diretório: + +```bash +code . +``` + +#### Revise os materiais + +Você encontrará um arquivo de fluxo de trabalho simples chamado `main.nf`, um diretório `modules` contendo dois arquivos de módulo, e um diretório `data` contendo alguns arquivos de dados de exemplo. + +??? abstract "Conteúdo do diretório" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Este diretório contém dados de sequenciamento paired-end de três pacientes (A, B, C). + +Para cada paciente, temos amostras que são do tipo `tumor` (tipicamente originando de biópsias de tumor) ou `normal` (retiradas de tecido saudável ou sangue). +Se você não está familiarizado com análise de câncer, saiba apenas que isso corresponde a um modelo experimental que usa amostras pareadas tumor/normal para realizar análises contrastivas. + +Para o paciente A especificamente, temos dois conjuntos de replicatas técnicas (repetições). + +Os arquivos de dados de sequenciamento são nomeados com uma convenção típica `_R1_` e `_R2_` para o que são conhecidas como 'reads forward' e 'reads reverse'. + +_Não se preocupe se você não está familiarizado com este desenho experimental, não é crítico para entender este tutorial._ + +#### Revise a tarefa + +Seu desafio é escrever um fluxo de trabalho Nextflow que vai: + +1. **Carregar** arquivos de entrada usando os métodos de manuseio de arquivos do Nextflow +2. **Extrair** metadados (ID do paciente, replicata, tipo de amostra) da estrutura do nome do arquivo +3. **Agrupar** arquivos pareados (R1/R2) juntos usando `channel.fromFilePairs()` +4. **Processar** os arquivos com um módulo de análise fornecido +5. **Organizar** saídas em uma estrutura de diretórios baseada nos metadados extraídos + +#### Lista de verificação de prontidão + +Acha que está pronto para mergulhar? + +- [ ] Eu entendo o objetivo deste curso e seus pré-requisitos +- [ ] Meu codespace está funcionando +- [ ] Eu configurei meu diretório de trabalho apropriadamente +- [ ] Eu entendo a tarefa + +Se você pode marcar todas as caixas, está pronto para começar. + +--- + +## 1. Operações básicas de arquivo + +### 1.1. Identifique o tipo de um objeto com `.class` + +Dê uma olhada no arquivo de fluxo de trabalho `main.nf`: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Cria um objeto Path a partir de uma string de caminho + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" +} +``` + +Este é um mini-fluxo de trabalho (sem nenhum processo) que se refere a um único caminho de arquivo em seu fluxo de trabalho, depois o imprime no console, junto com sua classe. + +??? info "O que é `.class`?" + + No Nextflow, `.class` nos diz com que tipo de objeto estamos trabalhando. É como perguntar "que tipo de coisa é isso?" para descobrir se é uma string, um número, um arquivo ou outra coisa. + Isso vai nos ajudar a ilustrar a diferença entre uma string simples e um objeto Path nas próximas seções. + +Vamos executar o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz is of class java.lang.String + ``` + +Como você pode ver, Nextflow imprimiu a string de caminho exatamente como nós escrevemos. + +Isso é apenas saída de texto; Nextflow ainda não fez nada especial com isso. +Também confirmamos que para o Nextflow, isso é apenas uma string (da classe `java.lang.String`). +Isso faz sentido, já que ainda não dissemos ao Nextflow que corresponde a um arquivo. + +### 1.2. Crie um objeto Path com file() + +Podemos dizer ao Nextflow como lidar com arquivos criando [objetos Path](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) a partir de strings de caminho. + +Em nosso fluxo de trabalho, podemos converter a string de caminho `data/patientA_rep1_normal_R1_001.fastq.gz` em um objeto Path usando o método `file()`, que fornece acesso a propriedades e operações de arquivo. + +Edite o `main.nf` para envolver a string com `file()` da seguinte forma: + +=== "Depois" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Cria um objeto Path a partir de uma string de caminho + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} is of class ${myFile.class}" + ``` + +Agora execute o fluxo de trabalho novamente: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz is of class class sun.nio.fs.UnixPath + ``` + +Desta vez, você vê o caminho absoluto completo em vez do caminho relativo que fornecemos como entrada. + +Nextflow converteu nossa string em um objeto Path e resolveu para a localização real do arquivo no sistema. +O caminho do arquivo agora será absoluto, como em `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz`. + +Note também que a classe do objeto Path é `sun.nio.fs.UnixPath`: esta é a forma do Nextflow de representar arquivos locais. +Como veremos mais tarde, arquivos remotos terão nomes de classe diferentes (como `nextflow.file.http.XPath` para arquivos HTTP), mas todos funcionam exatamente da mesma forma e podem ser usados identicamente em seus fluxos de trabalho. + +!!! tip + + **A diferença chave:** + + - **String de caminho**: Apenas texto que Nextflow trata como caracteres + - **Objeto Path**: Uma referência de arquivo inteligente com a qual Nextflow pode trabalhar + + Pense nisso assim: uma string de caminho é como escrever um endereço no papel, enquanto um objeto Path é como ter o endereço carregado em um dispositivo GPS que sabe como navegar até lá e pode te dizer detalhes sobre a jornada. + +### 1.3. Acesse atributos de arquivo + +Por que isso é útil? Bem, agora que Nextflow entende que `myFile` é um objeto Path e não apenas uma string, podemos acessar os vários atributos do objeto Path. + +Vamos atualizar nosso fluxo de trabalho para imprimir os atributos de arquivo embutidos: + +=== "Depois" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} is of class ${myFile.class}" + ``` + +Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + ``` + +Você vê os vários atributos de arquivo impressos no console acima. + +### 1.4. Forneça o arquivo para um processo + +A diferença entre strings e objetos Path se torna crítica quando você começa a construir fluxos de trabalho reais com processos. +Até agora verificamos que Nextflow está agora tratando nosso arquivo de entrada como um arquivo, mas vamos ver se realmente podemos executar algo nesse arquivo em um processo. + +#### 1.4.1. Importe o processo e examine o código + +Fornecemos um módulo de processo pré-escrito chamado `COUNT_LINES` que recebe uma entrada de arquivo e conta quantas linhas há nele. + +Para usar o processo no fluxo de trabalho, você só precisa adicionar uma declaração include antes do bloco workflow: + +=== "Depois" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Você pode abrir o arquivo de módulo para examinar seu código: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Processing file: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Como você pode ver, é um script bem direto que descompacta o arquivo e conta quantas linhas ele contém. + +??? info "O que faz `debug true`?" + + A diretiva `debug true` na definição do processo faz com que Nextflow imprima a saída do seu script (como a contagem de linhas "40") diretamente no log de execução. + Sem isso, você veria apenas o status de execução do processo, mas não a saída real do seu script. + + Para mais informações sobre depuração de processos Nextflow, veja a side quest [Debugging Nextflow Workflows](debugging.md). + +#### 1.4.2. Adicione uma chamada para `COUNT_LINES` + +Agora que o processo está disponível para o fluxo de trabalho, podemos adicionar uma chamada ao processo `COUNT_LINES` para executá-lo no arquivo de entrada. + +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Conta as linhas no arquivo + COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +E agora execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Isso mostra que somos capazes de operar no arquivo apropriadamente dentro de um processo. + +Especificamente, Nextflow realizou as seguintes operações com sucesso: + +- Staged o arquivo no diretório de trabalho +- Descomprimiu o arquivo .gz +- Contou as linhas (40 linhas neste caso) +- Completou sem erro + +A chave para esta operação suave é que estamos explicitamente dizendo ao Nextflow que nossa entrada é um arquivo e deve ser tratada como tal. + +### 1.5. Solucione erros básicos de entrada de arquivo + +Isso frequentemente confunde recém-chegados ao Nextflow, então vamos dedicar alguns minutos para ver o que acontece quando você faz isso errado. + +Há dois lugares principais onde você pode errar no manuseio de arquivos: no nível do fluxo de trabalho e no nível do processo. + +#### 1.5.1. Erro no nível do fluxo de trabalho + +Vamos ver o que acontece se voltarmos a tratar o arquivo como uma string quando especificamos a entrada no bloco workflow. + +Faça as seguintes edições no fluxo de trabalho, certificando-se de comentar as declarações print específicas de caminho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Cria um objeto Path a partir de uma string de caminho + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + /* + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Conta as linhas no arquivo + COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Conta as linhas no arquivo + COUNT_LINES(myFile) + ``` + +E agora execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Esta é a parte importante: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Quando você especifica uma entrada `path`, Nextflow valida que você está passando referências de arquivo reais, não apenas strings. +Este erro está dizendo que `'data/patientA_rep1_normal_R1_001.fastq.gz'` não é um valor de caminho válido porque é uma string, não um objeto Path. + +Nextflow detectou imediatamente o problema e parou antes mesmo de iniciar o processo. + +#### 1.5.2. Erro no nível do processo + +O outro lugar onde podemos esquecer de especificar que queremos que Nextflow trate a entrada como um arquivo é na definição do processo. + +!!! warning "Mantenha o erro do fluxo de trabalho de 1.5.1" + + Para este teste funcionar corretamente, mantenha o fluxo de trabalho em seu estado quebrado (usando uma string simples em vez de `file()`). + Quando combinado com `val` no processo, isso produz o erro mostrado abaixo. + +Faça a seguinte edição no módulo: + +=== "Depois" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Antes" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +E agora execute o fluxo de trabalho novamente: + +```bash +nextflow run main.nf +``` + +??? failure "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Isso mostra muitos detalhes sobre o erro porque o processo está configurado para produzir informações de depuração, como notado acima. + +Estas são as seções mais relevantes: + +```console +Command executed: + + set -o pipefail + echo "Processing file: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Processing file: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Isso diz que o sistema não conseguiu encontrar o arquivo; no entanto, se você procurar o caminho, há um arquivo com esse nome naquele local. + +Quando executamos isso, Nextflow passou o valor da string para o script, mas não _staged_ o arquivo real no diretório de trabalho. +Então o processo tentou usar a string relativa, `data/patientA_rep1_normal_R1_001.fastq.gz`, mas esse arquivo não existe dentro do diretório de trabalho do processo. + +Tomados em conjunto, esses dois exemplos mostram como é importante dizer ao Nextflow se uma entrada deve ser tratada como um arquivo. + +!!! note + + Certifique-se de voltar e corrigir ambos os erros intencionais antes de continuar para a próxima seção. + +### Conclusão + +- Strings de caminho vs objetos Path: Strings são apenas texto, objetos Path são referências de arquivo inteligentes +- O método `file()` converte uma string de caminho em um objeto Path com o qual Nextflow pode trabalhar +- Você pode acessar propriedades de arquivo como `name`, `simpleName`, `extension` e `parent` [usando atributos de arquivo](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) +- Usar objetos Path em vez de strings permite ao Nextflow gerenciar arquivos adequadamente em seu fluxo de trabalho +- Resultados de Entrada de Processo: O manuseio adequado de arquivos requer objetos Path, não strings, para garantir que os arquivos sejam corretamente staged e acessíveis para uso pelos processos. + +--- + +## 2. Usando arquivos remotos + +Uma das principais características do Nextflow é a capacidade de alternar perfeitamente entre arquivos locais (na mesma máquina) e arquivos remotos acessíveis pela internet. + +Se você estiver fazendo certo, nunca precisará mudar a lógica do seu fluxo de trabalho para acomodar arquivos vindos de diferentes locais. +Tudo o que você precisa fazer para usar um arquivo remoto é especificar o prefixo apropriado no caminho do arquivo quando você está fornecendo-o ao fluxo de trabalho. + +Por exemplo, `/path/to/data` não tem prefixo, indicando que é um caminho de arquivo local 'normal', enquanto `s3://path/to/data` inclui o prefixo `s3://`, indicando que está localizado no armazenamento de objetos S3 da Amazon. + +Muitos protocolos diferentes são suportados: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Para usar qualquer um destes, simplesmente especifique o prefixo relevante na string, que então é tecnicamente chamada de Uniform Resource Identifier (URI) em vez de caminho de arquivo. +Nextflow cuidará da autenticação e do staging dos arquivos no lugar certo, fazendo download ou upload e todas as outras operações de arquivo que você esperaria. + +A força chave deste sistema é que ele nos permite alternar entre ambientes sem mudar nenhuma lógica do pipeline. +Por exemplo, você pode desenvolver com um conjunto de teste pequeno e local antes de mudar para um conjunto de teste em escala completa localizado em armazenamento remoto simplesmente mudando a URI. + +### 2.1. Use um arquivo da internet + +Vamos testar isso mudando o caminho local que estamos fornecendo ao nosso fluxo de trabalho com um caminho HTTPS apontando para uma cópia dos mesmos dados que está armazenada no Github. + +!!! warning + + Isso só funcionará se você tiver uma conexão ativa com a internet. + +Abra `main.nf` novamente e mude o caminho de entrada da seguinte forma: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Usando um arquivo remoto da internet + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +Vamos executar o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + File object class: class nextflow.file.http.XPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Funciona! Você pode ver que muito pouco mudou. + +A única diferença na saída do console é que a classe do objeto path agora é `nextflow.file.http.XPath`, enquanto para o caminho local a classe era `sun.nio.fs.UnixPath`. +Você não precisa lembrar essas classes; mencionamos isso apenas para demonstrar que Nextflow identifica e lida com as diferentes localizações apropriadamente. + +Nos bastidores, Nextflow baixou o arquivo para um diretório de staging localizado dentro do diretório work. +Esse arquivo staged pode então ser tratado como um arquivo local e criar um link simbólico no diretório do processo relevante. + +Você pode verificar que isso aconteceu aqui olhando o conteúdo do diretório de trabalho localizado no valor de hash do processo. + +??? abstract "Conteúdo do diretório work" + + Se o hash do processo fosse `8a/2ab7ca`, você poderia explorar o diretório work: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + O link simbólico aponta para uma cópia staged do arquivo remoto que Nextflow baixou automaticamente. + +Note que para arquivos maiores, o passo de download levará algum tempo extra comparado à execução em arquivos locais. +No entanto, Nextflow verifica se já tem uma cópia staged para evitar downloads desnecessários. +Então se você executar novamente no mesmo arquivo e não tiver deletado o arquivo staged, Nextflow usará a cópia staged. + +Isso mostra como é fácil alternar entre dados locais e remotos usando Nextflow, que é uma característica chave do Nextflow. + +!!! note + + A única exceção importante a este princípio é que você não pode usar padrões glob ou caminhos de diretório com HTTPS porque HTTPS não pode listar múltiplos arquivos, então você deve especificar URLs exatas de arquivo. + No entanto, outros protocolos de armazenamento como blob storage (`s3://`, `az://`, `gs://`) podem usar tanto globs quanto caminhos de diretório. + + Aqui está como você poderia usar padrões glob com armazenamento em nuvem: + + ```groovy title="Exemplos de armazenamento em nuvem (não executáveis neste ambiente)" + // S3 com padrões glob - corresponderia a múltiplos arquivos + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Azure Blob Storage com padrões glob + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Google Cloud Storage com padrões glob + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Vamos mostrar como trabalhar com globs na prática na próxima seção. + +### 2.2. Volte para o arquivo local + +Vamos voltar a usar nossos arquivos de exemplo locais para o resto desta side quest, então vamos mudar a entrada do fluxo de trabalho de volta para o arquivo original: + +=== "Depois" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + ``` + +### Conclusão + +- Dados remotos são acessados usando uma URI (HTTP, FTP, S3, Azure, Google Cloud) +- Nextflow automaticamente fará download e stage dos dados no lugar certo, desde que esses caminhos sejam alimentados em processos +- Não escreva lógica para baixar ou fazer upload de arquivos remotos! +- Arquivos locais e remotos produzem tipos de objetos diferentes mas funcionam identicamente +- **Importante**: HTTP/HTTPS só funcionam com arquivos únicos (sem padrões glob) +- Armazenamento em nuvem (S3, Azure, GCS) suporta tanto arquivos únicos quanto padrões glob +- Você pode alternar perfeitamente entre fontes de dados locais e remotas sem mudar a lógica do código (desde que o protocolo suporte suas operações requeridas) + +--- + +## 3. Usando o channel factory `fromPath()` + +Até agora temos trabalhado com um arquivo por vez, mas no Nextflow, tipicamente vamos querer criar um canal de entrada com múltiplos arquivos de entrada para processar. + +Uma forma ingênua de fazer isso seria combinar o método `file()` com [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) assim: + +```groovy title="Exemplo de sintaxe" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Isso funciona, mas é desajeitado. + +!!! tip "Quando usar `file()` vs `channel.fromPath()`" + + - Use `file()` quando você precisar de um único objeto Path para manipulação direta (verificar se um arquivo existe, ler seus atributos, ou passar para uma única invocação de processo) + - Use `channel.fromPath()` quando você precisar de um canal que pode conter múltiplos arquivos, especialmente com padrões glob, ou quando arquivos fluirão através de múltiplos processos + +É aqui que [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) entra: um channel factory conveniente que agrupa toda a funcionalidade que precisamos para gerar um canal a partir de uma ou mais strings de arquivo estáticas, bem como padrões glob. + +### 3.1. Adicione o channel factory + +Vamos atualizar nosso fluxo de trabalho para usar `channel.fromPath`. + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Imprime atributos do arquivo + /* Comente isso por enquanto, voltaremos a eles! + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + */ + + // Conta as linhas no arquivo + // COUNT_LINES(myFile) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Cria um objeto Path a partir de uma string de caminho + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Imprime atributos do arquivo + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + + // Conta as linhas no arquivo + COUNT_LINES(myFile) + ``` + +Também comentamos o código que imprime os atributos por enquanto, e adicionamos uma declaração `.view` para imprimir apenas o nome do arquivo. + +Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Found file: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Como você pode ver, o caminho do arquivo está sendo carregado como um objeto do tipo `Path` no canal. +Isso é semelhante ao que `file()` teria feito, exceto que agora temos um canal no qual podemos carregar mais arquivos se quisermos. + +Usar `channel.fromPath()` é uma forma conveniente de criar um novo canal populado por uma lista de arquivos. + +### 3.2. Visualize atributos de arquivos no canal + +Em nossa primeira passagem usando o channel factory, simplificamos o código e apenas imprimimos o nome do arquivo. + +Vamos voltar a imprimir os atributos completos do arquivo: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + + // Conta as linhas no arquivo + COUNT_LINES(ch_files) + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Found file: $myFile" } + + // Conta as linhas no arquivo + // COUNT_LINES(ch_files) + ``` + +Também estamos reabilitando a chamada do processo `COUNT_LINES` para verificar que o processamento de arquivo ainda funciona corretamente com nossa abordagem baseada em canal. + +Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + File object class: sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +E aí está, mesmos resultados de antes, mas agora temos o arquivo em um canal, então podemos adicionar mais. + +### 3.3. Usando um glob para corresponder múltiplos arquivos + +Há várias formas que poderíamos carregar mais arquivos no canal. +Aqui vamos mostrar como usar padrões glob, que são uma forma conveniente de corresponder e recuperar nomes de arquivos e diretórios baseados em caracteres curinga. +O processo de corresponder esses padrões é chamado de "globbing" ou "expansão de nome de arquivo". + +!!! note + + Como notado anteriormente, Nextflow suporta globbing para gerenciar arquivos de entrada e saída na maioria dos casos, exceto com caminhos de arquivo HTTPS porque HTTPS não pode listar múltiplos arquivos. + +Digamos que queremos recuperar ambos os arquivos em um par de arquivos associados com um dado paciente, `patientA`: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Já que a única diferença entre os nomes de arquivo é o número de replicata, _i.e._ o número após `R`, podemos usar o caractere curinga `*` para substituir o número da seguinte forma: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +Esse é o padrão glob que precisamos. + +Agora tudo o que precisamos fazer é atualizar o caminho do arquivo no channel factory para usar esse padrão glob da seguinte forma: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow reconhecerá automaticamente que este é um padrão glob e o tratará apropriadamente. + +Execute o fluxo de trabalho para testar isso: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R1_001.fastq.gz + Simple name: patientA_rep1_normal_R1_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + File object class: class sun.nio.fs.UnixPath + File name: patientA_rep1_normal_R2_001.fastq.gz + Simple name: patientA_rep1_normal_R2_001 + Extension: gz + Parent directory: /workspaces/training/side-quests/working_with_files/data + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Como você pode ver, agora temos dois objetos Path em nosso canal, o que mostra que Nextflow fez a expansão de nome de arquivo corretamente, e carregou e processou ambos os arquivos como esperado. + +Usando este método, podemos recuperar tantos ou tão poucos arquivos quanto quisermos apenas mudando o padrão glob. Se o tornássemos mais generoso, por exemplo substituindo todas as partes variáveis dos nomes de arquivo por `*` (_e.g._ `data/patient*_rep*_*_R*_001.fastq.gz`) poderíamos pegar todos os arquivos de exemplo no diretório `data`. + +### Conclusão + +- `channel.fromPath()` cria um canal com arquivos correspondendo a um padrão +- Cada arquivo é emitido como um elemento separado no canal +- Podemos usar um padrão glob para corresponder múltiplos arquivos +- Arquivos são automaticamente convertidos em objetos Path com atributos completos +- O método `.view()` permite inspeção do conteúdo do canal + +--- + +## 4. Extraindo metadados básicos de nomes de arquivos + +Na maioria dos domínios científicos, é muito comum ter metadados codificados nos nomes dos arquivos que contêm os dados. +Por exemplo, em bioinformática, arquivos contendo dados de sequenciamento são frequentemente nomeados de uma forma que codifica informações sobre a amostra, condição, replicata e número de read. + +Se os nomes de arquivo são construídos de acordo com uma convenção consistente, você pode extrair esses metadados de maneira padronizada e usá-los no curso de sua análise. +Isso é um grande 'se', é claro, e você deve ser muito cauteloso sempre que depender da estrutura do nome do arquivo; mas a realidade é que esta abordagem é muito amplamente usada, então vamos ver como é feito no Nextflow. + +No caso de nossos dados de exemplo, sabemos que os nomes de arquivo incluem metadados estruturados de forma consistente. +Por exemplo, o nome de arquivo `patientA_rep1_normal_R2_001` codifica o seguinte: + +- ID do paciente: `patientA` +- ID da replicata: `rep1` +- tipo de amostra: `normal` (em oposição a `tumor`) +- conjunto de read: `R1` (em oposição a `R2`) + +Vamos modificar nosso fluxo de trabalho para recuperar esta informação em três passos: + +1. Recuperar o `simpleName` do arquivo, que inclui os metadados +2. Separar os metadados usando um método chamado `tokenize()` +3. Usar um mapa para organizar os metadados + +!!! warning + + Você nunca deve codificar informações sensíveis em nomes de arquivos, como nomes de pacientes ou outras características identificadoras, pois isso pode comprometer a privacidade do paciente ou outras restrições de segurança relevantes. + +### 4.1. Recupere o `simpleName` + +O `simpleName` é um atributo de arquivo que corresponde ao nome do arquivo desprovido de seu caminho e extensão. + +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "File object class: ${myFile.class}" + println "File name: ${myFile.name}" + println "Simple name: ${myFile.simpleName}" + println "Extension: ${myFile.extension}" + println "Parent directory: ${myFile.parent}" + } + ``` + +Isso recupera o `simpleName` e o associa com o objeto de arquivo completo usando uma operação `map()`. + +Execute o fluxo de trabalho para testar que funciona: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Cada elemento no canal agora é uma tupla contendo o `simpleName` e o objeto de arquivo original. + +### 4.2. Extraia os metadados do `simplename` + +Neste ponto, os metadados que queremos estão incorporados no `simplename`, mas não podemos acessar itens individuais diretamente. +Então precisamos dividir o `simplename` em seus componentes. +Felizmente, esses componentes são simplesmente separados por sublinhados no nome de arquivo original, então podemos aplicar um método comum do Nextflow chamado `tokenize()` que é perfeito para esta tarefa. + +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +O método `tokenize()` dividirá a string `simpleName` onde quer que encontre sublinhados, e retornará uma lista contendo as substrings. + +Execute o fluxo de trabalho: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Agora a tupla para cada elemento em nosso canal contém a lista de metadados (_e.g._ `[patientA, rep1, normal, R1, 001]`) e o objeto de arquivo original. + +Isso é ótimo! +Quebramos nossa informação de paciente de uma única string em uma lista de strings. +Agora podemos lidar com cada parte da informação do paciente separadamente. + +### 4.3. Use um mapa para organizar os metadados + +Nossos metadados são apenas uma lista plana no momento. +É fácil o suficiente de usar mas difícil de ler. + +```console +[patientA, rep1, normal, R1, 001] +``` + +O que é o item no índice 3? Você pode dizer sem se referir de volta à explicação original da estrutura de metadados? + +Esta é uma grande oportunidade para usar um armazenamento de chave-valor, onde cada item tem um conjunto de chaves e seus valores associados, então você pode facilmente se referir a cada chave para obter o valor correspondente. + +Em nosso exemplo, isso significa ir desta organização: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +Para esta: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +No Nextflow, isso é chamado de [mapa](https://nextflow.io/docs/latest/script.html#maps). + +Vamos converter nossa lista plana em um mapa agora. +Faça as seguintes edições no fluxo de trabalho: + +=== "Depois" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== "Antes" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // Carrega arquivos com channel.fromPath + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +As mudanças chave aqui são: + +- **Atribuição desestruturante**: `def (patient, replicate, type, readNum) = ...` extrai os valores tokenizados em variáveis nomeadas em uma linha +- **Sintaxe literal de mapa**: `[id: patient, replicate: ...]` cria um mapa onde cada chave (como `id`) é associada com um valor (como `patient`) +- **Estrutura aninhada**: A lista externa `[..., myFile]` emparelha o mapa de metadados com o objeto de arquivo original + +Também simplificamos algumas das strings de metadados usando um método de substituição de string chamado `replace()` para remover alguns caracteres que são desnecessários (_e.g._ `replicate.replace('rep', '')` para manter apenas o número dos IDs de replicata). + +Vamos executar o fluxo de trabalho novamente: + +```bash +nextflow run main.nf +``` + +??? success "Saída do comando" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [infallible_swartz] DSL2 - revision: 7f4e68c0cb + + executor > local (2) + [1b/e7fb27] COUNT_LINES (1) [100%] 2 of 2 ✔ + [[id:patientA, replicate:1, type:normal, readNum:2], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[id:patientA, replicate:1, type:normal, readNum:1], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Processing file: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Processing file: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Agora os metadados estão bem rotulados (_e.g._ `[id:patientA, replicate:1, type:normal, readNum:2]`) então é muito mais fácil dizer o que é o quê. + +Também será muito mais fácil realmente fazer uso de elementos de metadados no fluxo de trabalho, e tornará nosso código mais fácil de ler e mais sustentável. + +### Conclusão + +- Podemos lidar com nomes de arquivos no Nextflow com o poder de uma linguagem de programação completa +- Podemos tratar os nomes de arquivos como strings para extrair informação relevante +- Uso de métodos como `tokenize()` e `replace()` permite manipular strings no nome do arquivo +- A operação `.map()` transforma elementos de canal enquanto preserva a estrutura +- Metadados estruturados (mapas) tornam o código mais legível e sustentável do que listas posicionais + +A seguir, veremos como lidar com arquivos de dados pareados. + +--- + +## 5. Lidando com arquivos de dados pareados + +Muitos desenhos experimentais produzem arquivos de dados pareados que se beneficiam de serem tratados de forma explicitamente pareada. +Por exemplo, em bioinformática, dados de sequenciamento são frequentemente gerados na forma de reads pareados, significando strings de sequência que se originam do mesmo fragmento de DNA (frequentemente chamados de 'forward' e 'reverse' porque são lidos de extremidades opostas). + +Esse é o caso de nossos dados de exemplo, onde R1 e R2 se referem aos dois conjuntos de reads. + +```console +data/patientA_rep1_normal_R1_001.fastq.gz +data/patientA_rep1_normal_R2_001.fastq.gz +``` + +Nextflow fornece um channel factory especializado para trabalhar com arquivos pareados como este chamado `channel.fromFileP diff --git a/docs/pt/docs/training_collections/architects_toolkit_1.md b/docs/pt/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..8b16169722 --- /dev/null +++ b/docs/pt/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,63 @@ +```markdown +--- +title: Kit de Ferramentas do Arquiteto I +hide: + - toc +--- + +# Kit de Ferramentas do Arquiteto I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nossas Coleções de Treinamento fornecem caminhos de aprendizado curados através de nossos materiais de treinamento avançado (chamados [Side Quests](../../side_quests)). Esta coleção cobre quatro tópicos essenciais que são frequentemente usados juntos para construir fluxos de trabalho robustos e escaláveis. + +## Objetivos de aprendizado + +Ao final desta coleção, você terá experiência com: + +- **Arquiteturas complexas de fluxos de trabalho modulares** - Combinando múltiplos fluxos de trabalho em pipelines coesos +- **Estratégias abrangentes de testes** - Garantindo que seus fluxos de trabalho sejam confiáveis e sustentáveis +- **Gerenciamento de metadados** - Lidando com metadados específicos de amostras ao longo de seus fluxos de trabalho de forma eficaz +- **Processamento avançado de dados** - Implementando padrões eficientes de divisão e agrupamento de dados + +Essas habilidades permitirão que você construa fluxos de trabalho Nextflow robustos, escaláveis e sustentáveis para aplicações do mundo real. + +## Público-alvo e pré-requisitos + +Esta coleção é projetada para usuários que completaram o treinamento básico de Nextflow e desejam se aprofundar em padrões avançados de fluxo de trabalho, estratégias de testes e técnicas de manipulação de dados e metadados. + +**Pré-requisitos** + +- Conclusão do treinamento [Hello Nextflow](../../hello_nextflow/) ou experiência equivalente +- Familiaridade básica com a sintaxe e conceitos do Nextflow +- Compreensão de padrões básicos de desenvolvimento de fluxos de trabalho +- Experiência com ferramentas de linha de comando + +## Conteúdo da coleção + +Esta coleção consiste em quatro Side Quests que cobrem tópicos complementares de engenharia de fluxos de trabalho: + +1. **[Workflows of Workflows](../../side_quests/workflows_of_workflows)** - Arquitetura e composição complexa de fluxos de trabalho +2. **[Testing with nf-test](../../side_quests/nf-test)** - Estratégias de testes para fluxos de trabalho Nextflow +3. **[Metadata](../../side_quests/metadata)** - Manipulação de metadados para itens em canais Nextflow +4. **[Splitting and Grouping](../../side_quests/splitting_and_grouping)** - Padrões avançados de processamento de dados + +Cada Side Quest é independente e cobre conceitos específicos, mas recomendamos completá-los na ordem listada acima para uma progressão lógica através dos tópicos. + +## Como usar esta coleção + +Primeiro, clique com o botão de comando no botão "Open in GitHub Codespaces" abaixo para abrir o ambiente de treinamento em uma aba separada, depois continue lendo enquanto ele carrega. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Uma vez que seu ambiente esteja em execução, trabalhe através da coleção da seguinte forma: + +1. Nesta aba: Navegue até o primeiro Side Quest listado acima, que descreve exercícios de desenvolvimento passo a passo. +2. Na sua aba do Codespaces: Trabalhe através dos exercícios do Side Quest. +3. Quando você completar um Side Quest, retorne a esta página e navegue até o próximo da lista acima. +4. Quando você tiver completado a coleção, clique no botão abaixo para preencher uma pesquisa muito breve. Seu feedback nos permite continuar melhorando os materiais de treinamento para todos. + +[![Take the survey](https://img.shields.io/badge/Take%20the-Survey-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Pronto para começar? Comece com o primeiro módulo acima! +``` diff --git a/docs/pt/docs/training_collections/index.md b/docs/pt/docs/training_collections/index.md new file mode 100644 index 0000000000..f95b8bf047 --- /dev/null +++ b/docs/pt/docs/training_collections/index.md @@ -0,0 +1,31 @@ +```markdown +--- +title: Coleções de Treinamento +hide: + - toc +--- + +# Coleções de Treinamento + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Tradução assistida por IA - [saiba mais e sugira melhorias](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Esta seção contém coleções curadas de módulos de treinamento chamados [Side Quests](../side_quests/index.md) que visam fornecer uma experiência de aprendizado abrangente sobre um tema ou caso de uso específico. + +## Pré-requisitos + +Cada coleção possui pré-requisitos específicos documentados em sua página de índice. No entanto, a maioria das coleções assume: + +- Experiência com linha de comando +- Conceitos fundamentais de Nextflow e ferramentas cobertas no curso de treinamento para iniciantes [Hello Nextflow](../../hello_nextflow/) + +Para requisitos técnicos e configuração do ambiente, consulte o mini-curso de [Configuração do Ambiente](../../envsetup/). + +## Coleções disponíveis + +- [Kit de Ferramentas do Arquiteto I](./architects_toolkit_1.md) - Uma coleção de quatro Side Quests cobrindo padrões de arquitetura de fluxo de trabalho para montar pipelines complexos, implementar estratégias de teste, gerenciar metadados e agrupar e dividir dados. _Duração estimada: 4 horas em treinamento em grupo._ + +## Sugerindo novas coleções + +Estamos trabalhando ativamente no desenvolvimento de Side Quests e Coleções adicionais. +Sinta-se à vontade para sugerir tópicos que você acha que fariam sentido cobrir em uma Coleção postando na [seção de Treinamento](https://community.seqera.io/c/training/) do fórum da comunidade. +``` diff --git a/docs/pt/llm-prompt.md b/docs/pt/llm-prompt.md new file mode 100644 index 0000000000..4b82f3c8f4 --- /dev/null +++ b/docs/pt/llm-prompt.md @@ -0,0 +1,173 @@ +# Translation Rules for Portuguese + +The target language for this translation is **Brazilian Portuguese** (`pt`). + +## 1. Grammar & Tone + +- Use informal tone (você instead of o senhor/a senhora) +- Use Brazilian Portuguese spelling conventions (e.g., "arquivo" not "ficheiro", "diretório" not "pasta") +- Prefer active voice when possible +- Use a friendly, encouraging tone where appropriate (e.g., "Parabéns!" for congratulations, "Boas notícias" for good news) + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Portuguese (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "O canal de entrada recebe os arquivos..." (translate "channel" to "canal") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// emite uma saudação` + +## 3. Code Comments + +**Always translate code comments to Portuguese.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Portuguese translation +params.greeting = "Hello" // define a saudação padrão +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Portuguese: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Canal.fromPath('*.fastq') +processo FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ versão 24.04.0 +executor > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Mixing English keywords in prose + +```markdown +// Wrong - keeping "channel" in English when discussing concepts +O channel de entrada recebe os arquivos... + +// Correct - translate "channel" to "canal" in prose +O canal de entrada recebe os arquivos... +``` + +### ❌ Using European Portuguese + +```markdown +// Wrong - European Portuguese spelling +O ficheiro está na pasta... + +// Correct - Brazilian Portuguese +O arquivo está no diretório... +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code): + +| English | Portuguese | +| ------------- | ----------------------- | +| channel | canal / canais | +| process | processo / processos | +| workflow | fluxo de trabalho | +| directive | diretiva / diretivas | +| container | contêiner / contêineres | +| input | entrada | +| output | saída | +| task | tarefa | +| tuple | tupla | +| queue channel | canal de fila | +| value channel | canal de valor | +| operator | operador | +| parameter | parâmetro | +| environment | ambiente | +| directory | diretório | +| file | arquivo | +| sample | amostra | +| alignment | alinhamento | +| reference | referência | +| training | treinamento | +| module | módulo | +| command | comando | +| index | índice | +| run | executar / execução | + +## 6. Admonition Titles + +| English | Portuguese | +| -------- | ---------- | +| Note | Nota | +| Tip | Dica | +| Warning | Aviso | +| Exercise | Exercício | +| Solution | Solução | +| Example | Exemplo | + +## 7. Section Headers + +These recurring section headers should be translated consistently: + +| English | Portuguese | +| ------------------ | ------------------------------------------------ | +| Takeaway | Conclusão | +| What's next? | O que vem a seguir? | +| Warmup | Aquecimento | +| Directory contents | Conteúdo do diretório | +| Output | Saída (in prose) / Output (in code block titles) | + +## 8. Tab Labels + +| English | Portuguese | +| ------- | ---------- | +| After | Depois | +| Before | Antes | +| Gitpod | Gitpod | +| Local | Local | + +## 9. Common Expressions + +Brazilian Portuguese translations for common expressions: + +| English | Portuguese | +| ------------------ | ------------------------------- | +| Congratulations! | Parabéns! | +| Good news | Boas notícias | +| That said | Dito isso | +| free bonus | bônus gratuito | +| symbolic link | link simbólico | +| Ta-da! / Voilà! | Tcharam! (Brazilian colloquial) | +| Take a short break | Faça uma pequena pausa | +| you've earned it | você mereceu | + +## 10. UI Elements + +| English | Portuguese | +| ------------- | ---------------------- | +| file explorer | explorador de arquivos | +| sidebar | barra lateral | +| editor pane | painel do editor | +| terminal | terminal | diff --git a/docs/pt/mkdocs.yml b/docs/pt/mkdocs.yml new file mode 100644 index 0000000000..e9c207431c --- /dev/null +++ b/docs/pt/mkdocs.yml @@ -0,0 +1,16 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: pt + custom_dir: ../en/overrides +extra: + consent: + title: "Consentimento de cookies" + description: >- + Usamos cookies para reconhecer suas visitas repetidas e preferências, + bem como para medir a eficácia da nossa documentação e se os usuários + encontram o que procuram. Com seu consentimento, você nos ajuda a melhorar + nossos materiais de treinamento. + Saiba mais sobre + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">como usamos cookies</a>. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/pt/ui-strings.yml b/docs/pt/ui-strings.yml new file mode 100644 index 0000000000..ea844f31e9 --- /dev/null +++ b/docs/pt/ui-strings.yml @@ -0,0 +1,21 @@ +# UI strings for translation - Portuguese (Português) +# Estas strings são usadas pelo index_page_hook.py para as páginas +# iniciais dos cursos e no mkdocs.yml para o consentimento de cookies. + +index_page: + course_summary: "Resumo do curso" + additional_information: "Informações adicionais" + technical_requirements: "Requisitos técnicos" + learning_objectives: "Objetivos de aprendizado" + audience_prerequisites: "Público e pré-requisitos" + course_videos: "Vídeos do curso" + +defaults: + technical_requirements: >- + Você precisará de uma conta no GitHub OU de uma instalação local do Nextflow. + Consulte [Opções de ambiente](../envsetup/index.md) para mais detalhes. + videos: >- + Vídeos estão disponíveis para cada capítulo, com um instrutor trabalhando + nos exercícios. O vídeo de cada parte do curso está incorporado no topo + da página correspondente. + view_playlist: "Ver a playlist no YouTube" diff --git a/docs/side_quests/img/nf-core/nf-core-logo.png b/docs/side_quests/img/nf-core/nf-core-logo.png deleted file mode 100644 index 91ddb58d8a..0000000000 Binary files a/docs/side_quests/img/nf-core/nf-core-logo.png and /dev/null differ diff --git a/docs/tr/docs/envsetup/01_setup.md b/docs/tr/docs/envsetup/01_setup.md new file mode 100644 index 0000000000..9c841025c0 --- /dev/null +++ b/docs/tr/docs/envsetup/01_setup.md @@ -0,0 +1,113 @@ +# GitHub Codespaces + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces, buluttaki sanal makineler tarafından desteklenen, eğitim için önceden yapılandırılmış bir ortam sağlamamıza olanak tanıyan web tabanlı bir platformdur. +Platform, Github (Microsoft'a ait) tarafından işletilmektedir ve Github hesabı olan herkes için ücretsiz olarak (kullanım kotalarıyla) erişilebilir. + +!!! warning "Uyarı" + + Kuruluşlara bağlı hesaplar belirli ek kısıtlamalara tabi olabilir. + Bu sizin durumunuzsa, bağımsız bir kişisel hesap kullanmanız veya yerel kurulum yapmanız gerekebilir. + +## GitHub hesabı oluşturma + +[GitHub ana sayfasından](https://github.com/) ücretsiz bir GitHub hesabı oluşturabilirsiniz. + +## GitHub Codespace'inizi başlatma + +GitHub'a giriş yaptıktan sonra, Nextflow eğitim ortamını açmak için tarayıcınızda bu bağlantıyı açın: <https://codespaces.new/nextflow-io/training?quickstart=1&ref=master> + +Alternatif olarak, aşağıda gösterilen düğmeye tıklayabilirsiniz; bu düğme her eğitim kursunda (genellikle Oryantasyon sayfasında) tekrarlanmaktadır. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Yeni bir GitHub Codespace oluşturabileceğiniz bir sayfa ile karşılaşmalısınız: + +![Create a GitHub Codespace](img/codespaces_create.png) + +### Yapılandırma + +Genel kullanım için herhangi bir şey yapılandırmanız gerekmez. +Başlattığınız kursta aksi belirtilmedikçe, devam etmek için ana düğmeye tıklamanız yeterlidir. + +Ancak "Change options" düğmesine tıklayarak ortamı özelleştirmek mümkündür. + +??? info "Yapılandırma seçenekleri" + + "Change options" düğmesine tıklarsanız, aşağıdakileri özelleştirme seçeneği sunulur: + + #### Branch + + Bu, eğitim materyallerinin farklı bir sürümünü seçmenize olanak tanır. + `master` dalı genellikle hata düzeltmeleri ve yakın zamanda geliştirilmiş ve onaylanmış ancak henüz web sitesinde yayınlanmamış materyalleri içerir. + Diğer dallar, tam olarak işlevsel olmayabilecek devam eden çalışmaları içerir. + + #### Machine type + + Bu, eğitim üzerinde çalışmak için kullanacağınız sanal makineyi özelleştirmenize olanak tanır. + + Daha fazla çekirdeğe sahip bir makine kullanmak, Nextflow'un iş akışı yürütmeyi paralelleştirme yeteneğinden daha fazla yararlanmanızı sağlar. + Ancak ücretsiz kota tahsisatınızı daha hızlı tüketir, bu nedenle almayı planladığınız kursun talimatlarında tavsiye edilmedikçe bu ayarı değiştirmenizi önermiyoruz. + + Kotalar hakkında daha fazla ayrıntı için aşağıdaki 'GitHub Codespaces kotaları' bölümüne bakın. + +### Başlatma süresi + +İlk kez yeni bir GitHub Codespaces ortamı açmak birkaç dakika sürebilir, çünkü sistemin sanal makinenizi kurması gerekir, bu yüzden bir bekleme süresi olursa endişelenmeyin. +Ancak beş dakikadan fazla sürmemelidir. + +## Eğitim arayüzünde gezinme + +GitHub Codespaces'iniz yüklendikten sonra, aşağıdakine benzer bir şey görmelisiniz (hesap tercihlerinize bağlı olarak açık modda açılabilir): + +![GitHub Codespaces welcome](img/codespaces_welcome.png) + +Bu, Nextflow geliştirme için kullanmanızı önerdiğimiz popüler bir kod geliştirme uygulaması olan VSCode IDE'nin arayüzüdür. + +- **Ana düzenleyici**, Nextflow kodunun ve diğer metin dosyalarının açılacağı yerdir. Burası kodu düzenleyeceğiniz yerdir. Codespace'i açtığınızda, burada `README.md` dosyasının bir önizlemesi gösterilir. +- Ana düzenleyicinin altındaki **terminal**, komutları çalıştırmanıza olanak tanır. Kurs talimatlarında verilen tüm komut satırlarını burada çalıştıracaksınız. +- **Kenar çubuğu**, ortamınızı özelleştirmenize ve temel görevleri (kopyalama, yapıştırma, dosya açma, arama, git vb.) gerçekleştirmenize olanak tanır. Varsayılan olarak, deponun içeriğini görüntülemenize olanak tanıyan dosya gezginine açıktır. Gezginde bir dosyaya tıklamak, dosyayı ana düzenleyici penceresinde açar. + +Pencere bölmelerinin göreli oranlarını istediğiniz gibi ayarlayabilirsiniz. + +<!-- TODO (future) Link to development best practices side quest? --> + +## GitHub Codespaces kullanımı hakkında diğer notlar + +### Bir oturuma devam etme + +Bir ortam oluşturduğunuzda, kolayca devam edebilir veya yeniden başlatabilir ve kaldığınız yerden devam edebilirsiniz. +Ortamınız 30 dakikalık hareketsizlikten sonra zaman aşımına uğrar ve değişikliklerinizi 2 haftaya kadar kaydeder. + +<https://github.com/codespaces/> adresinden bir ortamı yeniden açabilirsiniz. +Önceki ortamlar listelenecektir. +Devam etmek için bir oturuma tıklayın. + +![List GitHub Codespace sessions](img/codespaces_list.png) + +Önceki GitHub Codespaces ortamınızın URL'sini kaydettiyseniz, tarayıcınızda açabilirsiniz. +Alternatif olarak, ilk başta oluşturmak için kullandığınız düğmeye tıklayın: + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Önceki oturumu görmelisiniz, varsayılan seçenek devam etmektir: + +![Resume a GitHub Codespace](img/codespaces_resume.png) + +### Dosyaları yerel makinenize kaydetme + +Gezgin panelinden herhangi bir dosyayı kaydetmek için, dosyaya sağ tıklayın ve `Download` seçeneğini seçin. + +### GitHub Codespaces kotalarını yönetme + +GitHub Codespaces, ayda 15 GB-ay depolama ve ayda 120 çekirdek-saat verir. +Bu, standart çalışma alanını (2 çekirdek, 8 GB RAM ve 32 GB depolama) kullanarak yaklaşık 60 saatlik varsayılan ortam çalışma süresine eşdeğerdir. + +Daha fazla kaynakla oluşturabilirsiniz (yukarıdaki açıklamaya bakın), ancak bu ücretsiz kullanımınızı daha hızlı tüketir ve bu alana daha az erişim saatiniz olur. +Örneğin, varsayılan 2 çekirdekli yerine 4 çekirdekli bir makine seçerseniz, kotanız yarı sürede tükenir. + +İsteğe bağlı olarak, daha fazla kaynağa erişim satın alabilirsiniz. + +Daha fazla bilgi için GitHub belgelerine bakın: +[GitHub Codespaces için faturalandırma hakkında](https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces) diff --git a/docs/tr/docs/envsetup/02_local.md b/docs/tr/docs/envsetup/02_local.md new file mode 100644 index 0000000000..d2e67dd106 --- /dev/null +++ b/docs/tr/docs/envsetup/02_local.md @@ -0,0 +1,62 @@ +# Manuel kurulum + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Eğitimi çalıştırmak için ihtiyacınız olan her şeyi kendi yerel ortamınızda manuel olarak kurmak mümkündür. + +Burada bunu standart POSIX uyumlu sistemlerde (dizüstü bilgisayar gibi kişisel bir makine varsayarak) nasıl yapacağınızı belgeledik. +Bazı ayrıntıların özel sisteminize bağlı olarak farklı olabileceğini unutmayın. + +!!! tip "İpucu" + + Devam etmeden önce, [Devcontainer'lar yaklaşımını](03_devcontainer.md) düşündünüz mü? + Manuel kurulum gerektirmeden gerekli tüm araçları ve bağımlılıkları sağlar. + +## Genel yazılım gereksinimleri + +Nextflow, Java yüklü herhangi bir POSIX uyumlu sistemde (Linux, macOS, Linux için Windows Alt Sistemi vb.) kullanılabilir. +Eğitim kurslarımızın birkaç ek gereksinimi vardır. + +Toplamda, aşağıdaki yazılımların yüklü olması gerekir: + +- Bash veya eşdeğer kabuk +- [Java 11 (veya sonrası, 21'e kadar)](https://www.oracle.com/technetwork/java/javase/downloads/index.html) +- [Git](https://git-scm.com/) +- [Docker](https://docs.docker.com/get-docker/) +- [Conda](https://conda.io/) 4.5 (veya sonrası) +- [Nextflow eklentisi](https://www.nextflow.io/docs/latest/developer-env.html#devenv-nextflow) ile [VSCode](https://code.visualstudio.com) + +VSCode uygulaması teknik olarak isteğe bağlıdır, ancak kurslar üzerinde çalışırken ve genel olarak Nextflow geliştirme çalışmalarınız için kullanmanızı şiddetle öneririz. + +Nextflow dokümantasyon kılavuzu, bu bağımlılıkları yüklemek için [Ortam kurulumu](https://www.nextflow.io/docs/latest/developer-env.html) altında talimatlar sağlar. + +## Nextflow ve nf-core araçları + +Aşağıda bağlantısı verilen makalelerde ayrıntılı olarak açıklandığı gibi Nextflow'un kendisini ve nf-core araçlarını yüklemeniz gerekecektir: + +- [Nextflow kurulumu](https://www.nextflow.io/docs/latest/install.html) +- [nf-core araçları](https://nf-co.re/docs/nf-core-tools/installation) + +Nextflow için kendi kendine kurulum seçeneğini ve nf-core araçları için PyPI seçeneğini kullanmanızı öneririz. + +!!! warning "Sürüm uyumluluğu" + + <!-- Any update to this content needs to be copied to the home page --> + **Ocak 2026 itibarıyla, aksi belirtilmedikçe tüm Nextflow eğitim kurslarımız strict v2 syntax etkinleştirilmiş Nextflow sürüm 25.10.2 veya üstünü gerektirir.** + + Sürüm gereksinimleri ve strict v2 syntax hakkında daha fazla bilgi için lütfen [Nextflow sürümleri](../info/nxf_versions.md) rehberine bakın. + + Önceki söz dizimine karşılık gelen eğitim materyallerinin eski sürümlerine bu web sayfasının menü çubuğundaki sürüm seçici aracılığıyla ulaşabilirsiniz. + +## Eğitim materyalleri + +Eğitim materyallerini indirmenin en kolay yolu, bu komutu kullanarak tüm depoyu klonlamaktır: + +```bash +git clone https://github.com/nextflow-io/training.git +``` + +Her kursun kendi dizini vardır. +Bir kurs üzerinde çalışmak için, bir terminal penceresi açın (ideal olarak VSCode uygulamasının içinden) ve ilgili dizine `cd` ile geçin. + +Daha sonra web sitesinde verilen kurs talimatlarını takip edebilirsiniz. diff --git a/docs/tr/docs/envsetup/03_devcontainer.md b/docs/tr/docs/envsetup/03_devcontainer.md new file mode 100644 index 0000000000..40c52e0182 --- /dev/null +++ b/docs/tr/docs/envsetup/03_devcontainer.md @@ -0,0 +1,108 @@ +# Yerel Devcontainer'lar + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Yerel bir Docker kurulumunuz varsa veya kurmaya hazırsanız, bu materyallerle yerel olarak çalışmanın en kolay yolu Visual Studio Code'un devcontainer özelliğini kullanmaktır. Bu yaklaşım, manuel kurulum gerektirmeden gerekli tüm araçları ve bağımlılıkları sağlar. + +## Gereksinimler + +Yerel devcontainer kurulumunu kullanmak için şunlara ihtiyacınız olacak: + +- [Visual Studio Code](https://code.visualstudio.com/) +- Yerel bir Docker kurulumu, örneğin: + - [Docker Desktop](https://docs.docker.com/get-docker/) (Windows/macOS için) + - [Docker Engine](https://docs.docker.com/engine/install/) (Linux için) + - [Colima](https://github.com/abiosoft/colima) (macOS için alternatif) +- [Docker Buildx](https://docs.docker.com/build/concepts/overview/#install-buildx) (Docker Desktop'a dahildir, ancak diğer Docker kurulumlarında ayrı kurulum gerekebilir) +- VS Code için [Dev Containers eklentisi](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +Devcontainer'ı açmaya çalışmadan önce Docker kurulumunuzun çalışıyor olması gerekir. + +Docker buildx'in kullanılabilir olduğunu doğrulamak için şunu çalıştırın: + +```bash +docker buildx version +``` + +Bu komut başarısız olursa, devam etmeden önce buildx eklentisini kurmanız gerekecektir. + +## Kurulum Talimatları + +VS Code devcontainer'larını kullanarak yerel ortamınızı kurmak için bu adımları izleyin: + +### VS Code'da "Dev Containers" eklentisini kurun + +- VS Code'u açın +- Extensions'a gidin (Ctrl+Shift+X veya macOS'ta Cmd+Shift+X) +- "Dev Containers" arayın +- "Install"a tıklayın + +![Installing Dev Containers extension in VS Code](img/install_extension.png) + +### Depoyu klonlayın: + +```bash +git clone https://github.com/nextflow-io/training.git +cd training +``` + +### Depoyu VS Code'da açın: + +- VS Code'u başlatın +- Menüden **File -> Open Folder** seçin +- Az önce klonladığınız training deposu klasörüne gidin ve seçin +- **Open**'a tıklayın + +### Konteyner'da Yeniden Aç + +VS Code tarafından "Reopen in Container" sorulursa, tıklayın. Alternatif olarak: + +- F1'e basın (veya Ctrl+Shift+P / macOS'ta Cmd+Shift+P) +- "Dev Containers: Reopen in Container" yazın +- **Önemli**: Yapılandırma seçmeniz istendiğinde, **local-dev** devcontainer yapılandırmasını seçin + +![Reopen in Container prompt](img/reopen_prompt.png) + +![Selecting local configuration](img/select_local_config.png) + +Konteyner'ın oluşturulmasını bekleyin. İlk seferde tüm gerekli bileşenleri indirip kurduğu için birkaç dakika sürebilir. + +Konteyner oluşturulup çalıştırıldığında, gerekli tüm araçların yüklü olduğu tam yapılandırılmış bir ortama sahip olacaksınız: + +- Java +- Nextflow +- Docker +- Git +- Ve eğitim için gereken diğer tüm bağımlılıklar + +![VS Code with devcontainer running](img/running_container.png) + +## Devcontainer'ları Kullanmanın Avantajları + +Devcontainer yaklaşımını kullanmak birçok avantaj sunar: + +- **Tutarlılık**: Farklı makinelerde tutarlı bir geliştirme ortamı sağlar +- **Basitlik**: Tüm bağımlılıklar önceden yüklenmiş ve yapılandırılmıştır +- **İzolasyon**: Geliştirme ortamı yerel sisteminizden izole edilmiştir +- **Tekrarlanabilirlik**: Devcontainer'ı kullanan herkes aynı kurulumu alır +- **Manuel kurulum yok**: Java, Nextflow ve diğer araçları manuel olarak kurmanıza gerek yok + +## Ortamınızı Kontrol Etme + +Devcontainer'ınız çalıştıktan sonra, her şeyin doğru şekilde kurulduğunu doğrulamak için şunu çalıştırabilirsiniz: + +```bash +nextflow info +``` + +Bu, ortamınızın düzgün yapılandırıldığını doğrulayan Nextflow sürümünü ve çalışma zamanı bilgilerini görüntülemelidir. + +## Sorun Giderme + +Devcontainer kurulumunda sorunlarla karşılaşırsanız: + +1. Devcontainer'ı açmadan önce Docker kurulumunuzun (Docker Desktop, Colima, Docker Engine vb.) çalıştığından emin olun +2. İstendiğinde **local-dev** yapılandırmasını seçtiğinizi doğrulayın +3. `docker buildx version` çalıştırarak Docker buildx'in kurulu ve çalışır durumda olduğunu doğrulayın +4. Konteyner oluşturma başarısız olursa, "Dev Containers: Rebuild Container" komutunu çalıştırarak yeniden oluşturmayı deneyin +5. Kalıcı sorunlar için [VS Code Dev Containers sorun giderme rehberine](https://code.visualstudio.com/docs/devcontainers/troubleshooting) bakın diff --git a/docs/tr/docs/envsetup/index.md b/docs/tr/docs/envsetup/index.md new file mode 100644 index 0000000000..313d9958e6 --- /dev/null +++ b/docs/tr/docs/envsetup/index.md @@ -0,0 +1,53 @@ +--- +title: Ortam seçenekleri +description: Nextflow eğitimleri için ortamınızı ayarlama seçenekleri +hide: + - toc + - footer +--- + +# Ortam seçenekleri + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Öğrencilerin yazılım yönetimi ile zaman ve çaba harcamak yerine Nextflow öğrenmeye odaklanmalarını sağlayan tutarlı ve kapsamlı olarak test edilmiş bir ortam sağlamayı hedefliyoruz. +Bu amaçla, tüm kurslarımızda çalışmak için gerekli tüm yazılımları, kod dosyalarını ve örnek verileri içeren konteynerize bir ortam geliştirdik. + +Bu konteynerize ortam, Github Codespaces üzerinde hazır olarak veya Devcontainers eklentisi ile VS Code'da yerel olarak çalıştırılabilir. + +<div class="grid cards" markdown> + +- :material-cloud-outline:{ .lg .middle } **Github Codespaces** + + *** + + GitHub Codespaces, buluttaki sanal makineler tarafından desteklenen, tüm araçlar ve veriler dahil önceden oluşturulmuş bir eğitim ortamı sağlamamıza olanak tanıyan web tabanlı bir hizmettir. Github hesabı olan herkes için ücretsiz olarak erişilebilir. + + [Github Codespaces kullanın :material-arrow-right:](01_setup.md){ .md-button .md-button--primary .mt-1 } + +- :material-laptop:{ .lg .middle } **Yerel Devcontainer'lar** + + *** + + Devcontainer'lı VS Code, tüm eğitim araçları önceden yapılandırılmış, yerel olarak çalışan konteynerize bir geliştirme ortamı sağlar. Codespaces ile aynı önceden oluşturulmuş ortamı sunar ancak tamamen yerel donanımınızda çalışır. + + [Devcontainer'ları yerel olarak kullanın :material-arrow-right:](03_devcontainer.md){ .md-button .md-button--primary .mt-1 } + +</div> + +## Manuel kurulum talimatları + +Yukarıdaki seçeneklerin hiçbiri ihtiyaçlarınıza uymuyorsa, yazılım bağımlılıklarını manuel olarak yükleyerek ve eğitim deposunu klonlayarak bu ortamı kendi yerel sisteminizde çoğaltabilirsiniz. + +[Manuel kurulum :material-arrow-right:](02_local.md){ .md-button .md-button--primary .mt-1 } + +--- + +!!! info "Gitpod'un kullanımdan kaldırılması" + + Nextflow Eğitimi, Şubat 2025'e kadar [Gitpod](https://gitpod.io) kullanıyordu. + Ancak Gitpod yapımcıları, ücretsiz işlevselliği [Gitpod Flex](https://www.gitpod.io/blog/introducing-gitpod-flex) sistemi lehine emekliye ayırmaya karar verdi. + Bu nedenle, önceden kurulum gerektirmeden tek tıklamayla geliştirici ortamı sunan GitHub Codespaces'e geçtik. + + Gitpod'a ne zaman kaydolduğunuza ve hizmeti tam olarak ne zaman emekliye ayıracaklarına bağlı olarak, eski bulut IDE'lerinde eğitimi başlatabilirsiniz, ancak ileriye dönük güvenilir erişimi garanti edemeyiz: + [Gitpod'da aç](https://gitpod.io/#https://github.com/nextflow-io/training). diff --git a/docs/tr/docs/hello_nextflow/00_orientation.md b/docs/tr/docs/hello_nextflow/00_orientation.md new file mode 100644 index 0000000000..5a52811e14 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/00_orientation.md @@ -0,0 +1,137 @@ +# Başlarken + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesine](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) bakın. + +:green_book: Video transkripti [burada](./transcripts/00_orientation.md) mevcuttur. +/// + +!!! tip "İpucu" + + YouTube videolarının bazı süper güçleri var! + + - :fontawesome-solid-closed-captioning: Yüksek kaliteli (manuel olarak düzenlenmiş) altyazılar. :material-subtitles: simgesi ile açabilirsiniz + - :material-bookmark: Sayfa başlıklarına karşılık gelen zaman çizelgesinde video bölümleri. + +## Eğitim ortamı başlatma + +GitHub Codespaces'te sunduğumuz önceden oluşturulmuş ortamı kullanmak için aşağıdaki "Open in GitHub Codespaces" düğmesine tıklayın. Diğer seçenekler için [Ortam seçenekleri](../envsetup/index.md) bölümüne bakın. + +Ortam yüklenirken okumaya devam edebilmeniz için eğitim ortamını yeni bir tarayıcı sekmesinde veya penceresinde açmanızı öneririz (ekipmanınıza bağlı olarak sağ tıklama, ctrl-tıklama veya cmd-tıklama kullanın). +Kurs boyunca çalışmak için bu talimatları paralel olarak açık tutmanız gerekecektir. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Ortam temelleri + +Bu eğitim ortamı, eğitim kursu boyunca çalışmak için gerekli tüm yazılım, kod ve verileri içerir, böylece kendiniz bir şey yüklemeniz gerekmez. + +Codespace, bir dosya sistemi gezgini, kod düzenleyici ve terminal kabuğu içeren VSCode arayüzü ile kurulmuştur. +Kurs boyunca verilen tüm talimatlar (örn. 'dosyayı açın', 'kodu düzenleyin' veya 'bu komutu çalıştırın') aksi belirtilmedikçe VScode arayüzünün bu üç bölümüne atıfta bulunur. + +Bu kursu kendiniz çalışıyorsanız, daha fazla ayrıntı için lütfen [ortam temelleri](../envsetup/01_setup.md) ile tanışın. + +### Sürüm gereksinimleri + +Bu eğitim, **v2 syntax parser ETKİNLEŞTİRİLMİŞ** Nextflow 25.10.2 veya üstü için tasarlanmıştır. +Yerel veya özel bir ortam kullanıyorsanız, lütfen [burada](../info/nxf_versions.md) belgelenen doğru ayarları kullandığınızdan emin olun. + +## Çalışmaya hazırlanın + +Codespace'iniz çalıştıktan sonra, eğitime dalmadan önce yapmanız gereken iki şey var: bu belirli kurs için çalışma dizininizi ayarlayın ve sağlanan materyallere bir göz atın. + +### Çalışma dizinini ayarlayın + +Varsayılan olarak, codespace tüm eğitim kurslarının kökünde çalışma dizini ayarlanmış olarak açılır, ancak bu kurs için `hello-nextflow/` dizininde çalışacağız. + +Terminalde bu komutu çalıştırarak şimdi dizini değiştirin: + +```bash +cd hello-nextflow/ +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz, böylece dosya gezgini kenar çubuğunda yalnızca ilgili dosyalar görünür: + +```bash +code . +``` + +!!! tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız (örn. codespace'iniz uykuya geçerse), Github Codespaces eğitim ortamında çalıştığınızı varsayarak her zaman tam yolu kullanarak geri dönebilirsiniz: + + ```bash + cd /workspaces/training/hello-nextflow + ``` + +Şimdi içeriğe bir göz atalım. + +### Sağlanan materyalleri keşfedin + +Bu dizinin içeriğini eğitim çalışma alanının sol tarafındaki dosya gezginini kullanarak keşfedebilirsiniz. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. + +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde temsil etmek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 2 +``` + +??? abstract "Dizin içerikleri" + + ```console + . + ├── data + │ └── greetings.csv + ├── hello-channels.nf + ├── hello-config.nf + ├── hello-containers.nf + ├── hello-modules.nf + ├── hello-workflow.nf + ├── hello-world.nf + ├── nextflow.config + ├── solutions + │ ├── 1-hello-world + │ ├── 2-hello-channels + │ ├── 3-hello-workflow + │ ├── 4-hello-modules + │ ├── 5-hello-containers + │ └── 6-hello-config + ├── test-params.json + └── test-params.yaml + ``` + +Bölümü genişletmek ve içeriğini görüntülemek için renkli kutuya tıklayın. +Bu tür daraltılabilir bölümleri, beklenen komut çıktısını özlü bir şekilde dahil etmek için kullanıyoruz. + +- **`.nf` dosyaları**, kursun hangi bölümünde kullanıldıklarına göre adlandırılmış iş akışı betikleridir. + +- **`nextflow.config` dosyası**, minimal ortam özelliklerini ayarlayan bir yapılandırma dosyasıdır. + Şimdilik görmezden gelebilirsiniz. + +- **`data/` altındaki `greetings.csv` dosyası**, kursun çoğunda kullanacağımız girdi verilerini içerir. Bölüm 2'de (Channels) ilk kez tanıtıldığında açıklanmaktadır. + +- **`test-params.*` dosyaları**, Bölüm 6'da (Configuration) kullanacağımız yapılandırma dosyalarıdır. Şimdilik görmezden gelebilirsiniz. + +- **`solutions` dizini**, kursun her adımından elde edilen tamamlanmış iş akışı betiklerini içerir. + Bunlar, çalışmanızı kontrol etmek ve herhangi bir sorunu gidermek için referans olarak kullanılmak üzere tasarlanmıştır. + +## Hazırlık kontrol listesi + +Başlamaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Ortamım hazır ve çalışıyor +- [ ] Çalışma dizinini uygun şekilde ayarladım + +Tüm kutuları işaretleyebiliyorsanız, hazırsınız. + +**[Bölüm 1: Hello World](./01_hello_world.md)'e devam etmek için, bu sayfanın sağ alt köşesindeki oka tıklayın.** diff --git a/docs/tr/docs/hello_nextflow/01_hello_world.md b/docs/tr/docs/hello_nextflow/01_hello_world.md new file mode 100644 index 0000000000..2c4d49f2a8 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/01_hello_world.md @@ -0,0 +1,1224 @@ +# Bölüm 1: Hello World + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesine](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) bakın. + +:green_book: Video transkripti [burada](./transcripts/01_hello_world.md) mevcuttur. +/// + +Hello Nextflow eğitim kursunun bu ilk bölümünde, temel Nextflow mantığını ve bileşenlerini göstermek için kademeli olarak oluşturacağımız çok basit, alana bağımlı olmayan bir Hello World örneğiyle konuya giriyoruz. + +??? info "Hello World örneği nedir?" + + "Hello World!", bir programlama dilinin veya yazılım çerçevesinin temel söz dizimini ve yapısını göstermek için tasarlanmış minimalist bir örnektir. + Örnek genellikle "Hello, World!" ifadesini konsol veya terminal gibi çıktı cihazına yazdırmaktan veya bir dosyaya yazmaktan oluşur. + +--- + +## 0. Isınma: Doğrudan Hello World örneği çalıştırın + +Bunu, Nextflow'a sarmadan önce ne yaptığını göstermek için terminalde doğrudan çalıştırdığımız basit bir komutla gösterelim. + +!!! tip "İpucu" + + [Başlarken](00_orientation.md) sayfasında açıklandığı gibi artık `hello-nextflow/` dizininin içinde olmalısınız. + +### 0.1. Terminalin merhaba demesini sağlayın + +Terminalinizde aşağıdaki komutu çalıştırın. + +```bash +echo 'Hello World!' +``` + +??? success "Komut çıktısı" + + ```console + Hello World! + ``` + +Bu, terminalde 'Hello World' metnini çıktı olarak verir. + +### 0.2. Çıktıyı bir dosyaya yazın + +İş akışlarını çalıştırmak çoğunlukla dosyalardan veri okumayı ve sonuçları diğer dosyalara yazmayı içerir, bu nedenle örneği biraz daha ilgili hale getirmek için metin çıktısını bir dosyaya yazacak şekilde komutu değiştirelim. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Komut çıktısı" + + ```console + + ``` + +Bu, terminale hiçbir şey çıktı vermez. + +### 0.3. Çıktıyı bulun + +'Hello World' metni artık belirttiğimiz `output.txt` adlı çıktı dosyasında olmalıdır. +Dosya gezgininde veya örneğin `cat` yardımcı programını kullanarak komut satırından açabilirsiniz. + +??? abstract "Dosya içerikleri" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +İşte ilk Nextflow iş akışımızla çoğaltmaya çalışacağımız şey bu. + +### Özet + +Artık terminalde metin çıktısı veren basit bir komutu nasıl çalıştıracağınızı ve isteğe bağlı olarak çıktıyı bir dosyaya nasıl yazdıracağınızı biliyorsunuz. + +### Sırada ne var? + +Bunun bir Nextflow iş akışı olarak nasıl yazıldığını öğrenin. + +--- + +## 1. Betiği inceleyin ve çalıştırın + +Size daha önce yaptığımız şeyi (Hello World!' yazmak) Nextflow ile yapan `hello-world.nf` adında tam işlevsel ama minimalist bir iş akışı betiği sağlıyoruz. + +Başlamanız için, nasıl yapılandırıldığını anlamanız için iş akışı betiğini açalım. +Sonra çalıştırıp çıktılarını arayacağız. + +### 1.1. Kodu inceleyin + +`hello-world.nf` betiğini mevcut dizininizde bulacaksınız, bu `hello-nextflow` olmalıdır. Düzenleyici bölmesinde açın. + +??? full-code "Tam kod dosyası" + + ```groovy title="hello-world.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ + process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + + workflow { + + main: + // bir selamlama yayınla + sayHello() + } + ``` + +Bir Nextflow iş akışı betiği genellikle bir veya daha fazla **process** tanımı ve **workflow**'un kendisini, ayrıca daha sonra tanıtacağımız birkaç isteğe bağlı blok (burada mevcut değil) içerir. + +Her **process**, iş akışındaki karşılık gelen adımın hangi işlem(ler)i gerçekleştirmesi gerektiğini açıklarken, **workflow** çeşitli adımları birbirine bağlayan veri akışı mantığını tanımlar. + +Önce **process** bloğuna daha yakından bakacağız, sonra **workflow** bloğuna bakacağız. + +#### 1.1.1. `process` tanımı + +İlk kod bloğu bir **process**'i tanımlar. + +Süreç tanımı `process` anahtar kelimesiyle başlar, ardından süreç adı ve son olarak süslü parantezlerle sınırlandırılmış süreç gövdesi gelir. +Süreç gövdesi, çalıştırılacak komutu belirten bir script bloğu içermelidir; bu, bir komut satırı terminalinde çalıştırabileceğiniz herhangi bir şey olabilir. + +```groovy title="hello-world.nf" linenums="3" +/* +* 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan +*/ +process sayHello { + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Burada **çıktısını** `output.txt` adlı bir dosyaya yazan `sayHello` adında bir **process** var. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world.svg" +</figure> + +Bu, yalnızca bir `output` tanımı ve yürütülecek `script`'i içeren çok minimal bir süreç tanımıdır. + +`output` tanımı, bunun bir yol olarak ele alınması gerektiğini Nextflow'a söyleyen `path` niteleyicisini içerir (hem dizin yollarını hem de dosyaları içerir). +Yaygın bir diğer niteleyici `val`'dır. + +Önemli olarak, çıktı tanımı hangi çıktının oluşturulacağını _belirlemez_. +Yalnızca beklenen çıktının ne olduğunu _bildirir_, böylece Nextflow yürütme tamamlandıktan sonra onu arayabilir. +Bu, komutun başarıyla yürütüldüğünü doğrulamak ve gerekirse çıktıyı aşağı akış süreçlerine iletmek için gereklidir. Çıktı bloğunda bildirilen şeyle eşleşmeyen üretilen çıktı, aşağı akış süreçlerine iletilmez. + +!!! warning "Uyarı" + + Bu örnek kırılgandır çünkü çıktı dosya adını iki ayrı yerde (script ve output blokları) sabit kodladık. + Birini değiştirip diğerini değiştirmezsek, betik bozulur. + Daha sonra, bu sorunu azaltmak için değişkenleri kullanmanın yollarını öğreneceksiniz. + +Gerçek dünya iş akışlarında, bir süreç genellikle biraz sonra tanıtacağımız yönergeler ve girdiler gibi ek bloklar içerir. + +#### 1.1.2. `workflow` tanımı + +İkinci kod bloğu **workflow**'un kendisini tanımlar. +İş akışı tanımı `workflow` anahtar kelimesiyle başlar, ardından isteğe bağlı bir ad, sonra süslü parantezlerle sınırlandırılmış iş akışı gövdesi gelir. + +Burada `sayHello` sürecine bir çağrı içeren `main:` bloğundan (iş akışının ana gövdesi olduğunu söyler) oluşan bir **workflow** var. + +```groovy title="hello-world.nf" linenums="17" +workflow { + + main: + // bir selamlama yayınla + sayHello() +} +``` + +Bu çok minimal bir **workflow** tanımıdır. +Gerçek dünya iş akışlarında, iş akışı genellikle **channel**'larla bağlanmış **process**'lere birden fazla çağrı içerir ve süreçler bir veya daha fazla değişken **girdi** bekler. + +Değişken girdilerin nasıl ekleneceğini bu eğitim modülünün ilerleyen bölümlerinde öğreneceksiniz; ve daha fazla süreç eklemeyi ve bunları kanallarla bağlamayı bu kursun 3. Bölümünde öğreneceksiniz. + +!!! tip "İpucu" + + Teknik olarak `main:` satırı bunun gibi basit iş akışları için gerekli değildir, bu nedenle sahip olmayan iş akışlarıyla karşılaşabilirsiniz. + Ancak iş akışı düzeyinde çıktılardan yararlanmak için buna ihtiyacımız olacak, bu yüzden en başından dahil edebiliriz. + +### 1.2. İş akışını çalıştırın + +Koda bakmak, çalıştırmak kadar eğlenceli değil, o halde bunu pratikte deneyelim. + +#### 1.2.1. İş akışını başlatın ve yürütmeyi izleyin + +Terminalde aşağıdaki komutu çalıştırın: + +```bash +nextflow run hello-world.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [65/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Konsol çıktınız buna benziyorsa, tebrikler, ilk Nextflow iş akışınızı çalıştırdınız! + +Buradaki en önemli çıktı, yukarıdaki çıktıda vurgulanan son satırdır: + +```console +[65/7be2fa] sayHello | 1 of 1 ✔ +``` + +Bu bize `sayHello` sürecinin bir kez başarıyla yürütüldüğünü (`1 of 1 ✔`) söyler. + +Önemli olarak, bu satır aynı zamanda `sayHello` süreç çağrısının çıktısını nerede bulacağınızı da söyler. +Şimdi buna bakalım. + +#### 1.2.2. `work` dizininde çıktıyı ve günlükleri bulun + +Nextflow'u belirli bir dizinde ilk kez çalıştırdığınızda, yürütme sırasında oluşturulan tüm dosyaları (ve sembolik bağlantıları) yazacağı `work` adlı bir dizin oluşturur. + +`work` dizini içinde, Nextflow çıktıları ve günlükleri süreç çağrısı başına düzenler. +Her süreç çağrısı için Nextflow, benzersiz olması için hash ile adlandırılmış iç içe bir alt dizin oluşturur ve gerekli tüm girdileri hazırlar (varsayılan olarak sembolik bağlantılar kullanarak), yardımcı dosyalar yazar ve sürecin herhangi bir çıktısını ve günlüklerini yazar. + +Bu alt dizinin yolu, konsol çıktısında köşeli parantez içinde kısaltılmış biçimde gösterilir. +Yukarıda gösterilen çalıştırma için elde ettiğimize bakıldığında, sayHello süreci için konsol günlük satırı `[65/7be2fa]` ile başlar. Bu şu dizin yoluna karşılık gelir: `work/65/7be2fa7be2fad5e71e5f49998f795677fd68` + +Orada ne olduğuna bir bakalım. + +??? abstract "Dizin içerikleri" + + ```console + work + └── 65 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Aynı şeyi görmüyor musunuz?" + + Tam alt dizin adları sisteminizde farklı olacaktır. + + VSCode dosya gezgininde görev alt dizininin içeriğine göz atarsanız, tüm dosyaları hemen göreceksiniz. + Ancak günlük dosyaları terminalde görünmez olarak ayarlanmıştır, bu nedenle bunları görüntülemek için `ls` veya `tree` kullanmak istiyorsanız, görünmez dosyaları görüntülemek için ilgili seçeneği ayarlamanız gerekir. + + ```bash + tree -a work + ``` + +Bakmak istediğiniz ilk şey, iş akışının gerçek çıktısı, yani `sayHello` süreci tarafından üretilen `output.txt` dosyasıdır. +Açın ve `Hello World!` selamlamasını bulacaksınız, ki minimalist iş akışımızın amacı buydu. + +??? abstract "Dosya içerikleri" + + ```console title="output.txt" + Hello World! + ``` + +İşe yaradı! + +Kuşkusuz, bu kadar küçük bir sonuç için çok fazla sarmalayıcı kod gibi görünebilir, ancak tüm bu sarmalayıcı kodun değeri, girdi dosyalarını okumaya ve birden fazla adımı bir araya getirmeye başladığımızda daha belirgin hale gelecektir. + +Bununla birlikte, o dizindeki diğer dosyalara da bakalım. Bunlar, görev yürütmenin bir parçası olarak Nextflow tarafından üretilen yardımcı ve günlük dosyalarıdır. + +- **`.command.begin`**: Süreç çağrısının yürütülmesinin başlangıcıyla ilgili meta veriler +- **`.command.err`**: Süreç çağrısı tarafından yayılan hata mesajları (`stderr`) +- **`.command.log`**: Süreç çağrısı tarafından yayılan tam günlük çıktısı +- **`.command.out`**: Süreç çağrısı tarafından yayılan normal çıktı (`stdout`) +- **`.command.run`**: Süreç çağrısını yürütmek için Nextflow tarafından çalıştırılan tam betik +- **`.command.sh`**: Süreç çağrısı tarafından gerçekte çalıştırılan komut +- **`.exitcode`**: Komuttan kaynaklanan çıkış kodu + +`.command.sh` dosyası özellikle kullanışlıdır çünkü tüm defter tutma ve görev/ortam kurulumu dahil değil, Nextflow'un yürüttüğü ana komutu söyler. + +??? abstract "Dosya içerikleri" + + ```console title=".command.sh" + #!/bin/bash -ue + echo 'Hello World!' > output.txt + ``` + +Bu, daha önce manuel olarak çalıştırdığımız şeyle eşleşir. + +Bu durumda süreç komutu sabit kodlanmış olduğu için çok basittir, ancak kursun ilerleyen bölümlerinde bazı değişken enterpolasyonu içeren süreç komutları göreceksiniz. +Bu, başarısız bir çalıştırmayı sorun giderirken Nextflow'un kodu nasıl yorumladığını ve hangi komutun üretildiğini tam olarak görebilmeyi özellikle değerli kılar. + +### 1.3. İş akışını tekrar çalıştırın + +İş akışını birkaç kez daha çalıştırmayı deneyin, ardından `work/` altındaki görev dizinlerine bakın. + +??? abstract "Dizin içerikleri" + + ```console + 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 + ``` + +Her çalıştırma için eksiksiz çıktı ve günlük dosyaları içeren yeni bir alt dizin oluşturulduğunu görüyorsunuz. +Bu, aynı iş akışını birkaç kez çalıştırmanın önceki çalıştırmaların sonuçlarını üzerine yazmayacağını gösterir. + +### Özet + +Basit bir Nextflow betiğini nasıl çözeceğinizi, çalıştıracağınızı ve work dizininde çıktı ve ilgili günlük dosyalarını nasıl bulacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışı çıktılarını daha uygun bir konuma nasıl yayınlayacağınızı öğrenin. + +--- + +## 2. Çıktıları yayınlayın + +Az önce öğrendiğiniz gibi, iş akışımız tarafından üretilen çıktı, birkaç seviye derinliğindeki bir çalışma dizininde gömülüdür. +Bu kasıtlı olarak yapılır; Nextflow bu dizini kontrol eder ve biz onunla etkileşime girmememiz gerekir. +Ancak bu, önemsediğimiz çıktıları almayı zorlaştırır. + +Neyse ki Nextflow, [iş akışı düzeyinde çıktı tanımlarını](https://www.nextflow.io/docs/latest/workflow.html#workflow-outputs) kullanarak çıktıları belirlenmiş bir dizine yayınlamanın bir yolunu sağlar. + +### 2.1. Temel kullanım + +Bu, iki yeni kod parçası içerecektir: + +1. `workflow` gövdesi içinde süreç çıktılarını bildiren bir `publish:` bloğu. +2. Mod ve konum gibi çıktı seçeneklerini belirten betiğe bir `output` bloğu. + +#### 2.1.1. `sayHello` sürecinin çıktısını bildirin + +İş akışı gövdesine (`main:` bloğuyla aynı türde kod öğesi) bir `publish:` bloğu eklememiz ve `sayHello()` sürecinin çıktısını listelememiz gerekir. + +İş akışı betik dosyası `hello-world.nf`'de aşağıdaki kod satırlarını ekleyin: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="7-8" + workflow { + + main: + // bir selamlama yayınla + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // bir selamlama yayınla + sayHello() + } + ``` + +Sürecin çıktısına basitçe `sayHello().out` yaparak başvurabileceğimizi ve ona rastgele bir ad, `first_output` atayabileceğimizi görüyorsunuz. + +#### 2.1.2. Betiğe bir `output:` bloğu ekleyin + +Şimdi çıktı dizini yolunun belirtileceği `output:` bloğunu eklememiz yeterli. Bu yeni bloğun betik içindeki `workflow` bloğunun **dışında** ve **altında** yer aldığını unutmayın. + +İş akışı betik dosyası `hello-world.nf`'de aşağıdaki kod satırlarını ekleyin: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="17" hl_lines="11-15" + workflow { + + main: + // bir selamlama yayınla + sayHello() + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '.' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="17" + workflow { + + main: + // bir selamlama yayınla + sayHello() + + publish: + first_output = sayHello.out + } + ``` + +Bunu, `workflow` bloğunda bildirilen herhangi bir süreç çıktısına belirli yollar atamak için kullanabiliriz. +Daha sonra, sofistike çıktı dizin yapıları oluşturmanın yollarını öğreneceksiniz, ancak şimdilik basitlik için minimal bir yolu sabit kodluyoruz. + +#### 2.1.3. İş akışını çalıştırın + +Şimdi değiştirilmiş iş akışı betiğini çalıştırın: + +```bash +nextflow run hello-world.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [jovial_mayer] DSL2 - revision: 35bd3425e5 + + executor > local (1) + [9f/48ef97] sayHello | 1 of 1 ✔ + ``` + +Terminal çıktısı tanıdık görünmeli. Dışarıdan hiçbir şey değişmedi. + +Ancak dosya gezgininizi kontrol edin: bu sefer Nextflow `results/` adında yeni bir dizin oluşturdu. + +??? abstract "Dizin içerikleri" + + ```console hl_lines="10-11 22" + . + ├── 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 + ``` + +`results` dizininin içinde, az önce çalıştırdığımız komut tarafından work dizininde üretilen `output.txt`'ye sembolik bir bağlantı buluyoruz. + +Bu, work alt dizinini araştırmak zorunda kalmadan çıktı dosyalarını kolayca almamızı sağlar. + +### 2.2. Özel bir konum ayarlayın + +Varsayılan bir konuma sahip olmak harikadır, ancak sonuçların nereye kaydedildiğini ve nasıl düzenlendiğini özelleştirmek isteyebilirsiniz. + +Örneğin, çıktılarınızı alt dizinler halinde düzenlemek isteyebilirsiniz. +Bunu yapmanın en basit yolu, çıktı başına belirli çıktı yolu atamaktır. + +#### 2.2.1. Çıktı yolunu değiştirin + +Bir kez daha, belirli bir çıktı için yayınlama davranışını değiştirmek gerçekten basittir. +Özel bir konum ayarlamak için `path`'i buna göre düzenlemeniz yeterlidir: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path 'hello_world' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="3" + output { + first_output { + path '.' + } + } + ``` + +Bu, bireysel çıktı seviyesinde ayarlandığından, ihtiyaçlarınıza uygun farklı konumlar ve alt dizinler belirleyebilirsiniz. + +#### 2.2.2. İş akışını tekrar çalıştırın + +Deneyelim. + +```bash +nextflow run hello-world.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [8c/79499c] process > sayHello [100%] 1 of 1 ✔ + ``` + +Bu sefer sonuç belirtilen alt dizine yazılır. + +??? abstract "Dizin içerikleri" + + ```console hl_lines="2-3" + results/ + ├── hello_world + │ └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c2e506b79e2e01acb808d9d12/output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Önceki yürütmenin sonucunun hâlâ orada olduğunu görüyorsunuz. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_output.svg" +</figure> + +İstediğiniz kadar iç içe geçme seviyesi kullanabilirsiniz. +Sonuçları düzenlemek için kullanılan dizinleri adlandırmak için süreç adını veya diğer değişkenleri kullanmak ve üst düzey çıktı dizininin varsayılan adını değiştirmek (özel `outputDir` değişkeni tarafından kontrol edilir) de mümkündür. +Bu seçenekleri sonraki eğitimlerde ele alacağız. + +### 2.3. Yayınlama modunu kopyalamaya ayarlayın + +Varsayılan olarak, çıktılar `work` dizininden sembolik bağlantılar olarak yayınlanır. +Bu, dosya sisteminde yalnızca tek bir dosya olduğu anlamına gelir. + +Bu, birden fazla kopya saklamak istemediğiniz çok büyük dosyalarla uğraşırken harikadır. +Ancak work dizinini herhangi bir noktada silerseniz (kısa süre sonra temizleme işlemlerini ele alacağız), dosyaya erişimi kaybedersiniz. +Bu nedenle, önemli dosyaların kopyalarını güvenli bir yere kaydetmek için bir planınız olması gerekir. + +Kolay bir seçenek, önemsediğiniz çıktılar için yayınlama modunu kopyalamaya geçirmektir. + +#### 2.3.1. Mod yönergesini ekleyin + +Bu kısım gerçekten basittir. +İlgili iş akışı düzeyinde çıktı tanımına `mode 'copy'` eklemeniz yeterlidir: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="27" hl_lines="4" + output { + first_output { + path 'hello_world' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="27" + output { + first_output { + path 'hello_world' + } + } + ``` + +Bu, söz konusu çıktı için yayınlama modunu ayarlar. + +#### 2.3.2. İş akışını tekrar çalıştırın + +Deneyelim. + +```bash +nextflow run hello-world.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [tiny_shaw] DSL2 - revision: 757723adc1 + + executor > local (1) + [df/521638] process > sayHello [100%] 1 of 1 ✔ + ``` + +Bu sefer, sonuçlara bakarsanız, dosya yalnızca bir sembolik bağlantı yerine düzgün bir kopyadır. + +??? abstract "Dizin içerikleri" + + ```console hl_lines="3" + results/ + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/65/f56f2cd75df1352e106fcdd084b97b/output.txt + ``` + +Bu da bireysel çıktı seviyesinde ayarlandığından, yayınlama modunu ayrıntılı bir şekilde ayarlamanıza olanak tanır. +Bu, daha sonra çok adımlı iş akışlarına geçtiğimizde özellikle işe yarayacaktır; örneğin yalnızca son çıktıları kopyalamak ve ara çıktıları sembolik bağlantı olarak bırakmak isteyebilirsiniz. + +Daha önce belirtildiği gibi, çıktıların nasıl yayınlandığını kontrol etmek için başka, daha sofistike seçenekler de vardır. +Nextflow yolculuğunuzda bunları nasıl kullanacağınızı zamanı geldiğinde göstereceğiz. + +### 2.4. Süreç düzeyinde `publishDir` yönergeleri hakkında not + +Çok yakın zamana kadar, çıktıları yayınlamanın yerleşik yolu, her bir süreç düzeyinde bir `publishDir` yönergesi kullanmaktı. + +`sayHello` sürecinin çıktıları için az önce yaptığımız şeyi başarmak için, bunun yerine süreç tanımına aşağıdaki satırı eklemiş olurduk: + +```groovy title="hello-world.nf" linenums="6" hl_lines="3" +process sayHello { + + publishDir 'results/hello_world', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ +} +``` + +Bu kod kalıbını eski Nextflow iş akışlarında ve süreç modüllerinde hâlâ her yerde bulacaksınız, bu nedenle bunun farkında olmak önemlidir. +Ancak, Nextflow dilinin gelecek sürümlerinde sonunda izin verilmeyeceğinden, yeni çalışmalarda kullanmanızı önermiyoruz. + +### Özet + +İş akışı çıktılarını daha uygun bir konuma nasıl yayınlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Komut satırı parametresi aracılığıyla değişken girdi sağlamayı ve varsayılan değerleri etkili bir şekilde kullanmayı öğrenin. + +--- + +## 3. Komut satırında iletilen değişken girdi kullanın + +Mevcut durumunda, iş akışımız süreç komutuna sabit kodlanmış bir selamlama kullanır. +Çalışma zamanında selamlamayı daha kolay değiştirebilmemiz için bir girdi değişkeni kullanarak biraz esneklik eklemek istiyoruz. + +Bu, betiğimizde üç dizi değişiklik yapmamızı gerektirir: + +1. Sürecin değişken girdi beklemesini sağlayın +2. Kullanıcı girdisini yakalamak için bir komut satırı parametresi ayarlayın +3. Girdiyi iş akışı gövdesindeki sürece iletin + +Bu değişiklikleri tek tek yapalım. + +### 3.1. `sayHello` sürecinin değişken girdi beklemesini sağlayın + +Süreç tanımını (1) bir girdi değişkenini kabul edecek ve (2) bu değişkeni komut satırında kullanacak şekilde düzenlememiz gerekir. + +#### 3.1.1. Süreç tanımına bir girdi bloğu ekleyin + +İlk olarak, süreç tanımını `greeting` adlı bir girdiyi kabul edecek şekilde uyarlayalım. + +Süreç bloğunda aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="6" hl_lines="3-4" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="6" + process sayHello { + + output: + path 'output.txt' + ``` + +`greeting` değişkeni, bunun bir değer olduğunu (yol değil) Nextflow'a söylemek için `val` ile ön eklenmiştir. + +#### 3.1.2. Süreç komutunu girdi değişkenini kullanacak şekilde düzenleyin + +Şimdi orijinal sabit kodlanmış değeri, almayı beklediğimiz girdi değişkeninin değeriyle değiştiriyoruz. + +Süreç bloğunda aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo '${greeting}' > output.txt + """ + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="14" hl_lines="3" + script: + """ + echo 'Hello World!' > output.txt + """ + ``` + +`$` simgesi ve süslü parantezler (`{ }`) Nextflow'a bunun gerçek girdi değeriyle değiştirilmesi gereken (=enterpolasyon) bir değişken adı olduğunu söyler. + +!!! tip "İpucu" + + Süslü parantezler (`{ }`) teknik olarak Nextflow'un önceki sürümlerinde isteğe bağlıydı, bu nedenle bunun `echo '$greeting' > output.txt` şeklinde yazıldığı eski iş akışları görebilirsiniz. + +Artık `sayHello()` süreci değişken girdi kabul etmeye hazır olduğuna göre, iş akışı düzeyinde süreç çağrısına bir girdi değeri sağlamanın bir yoluna ihtiyacımız var. + +### 3.2. Kullanıcı girdisini yakalamak için komut satırı parametresi ayarlayın + +Girdiyi doğrudan süreç çağrısını `sayHello('Hello World!')` yaparak sabit kodlayabiliriz. +Ancak, iş akışımızla gerçek iş yaptığımızda, girdilerini komut satırından kontrol edebilmek isteyeceğiz. + +İyi haber: Nextflow'un `params` adlı yerleşik iş akışı parametre sistemi vardır ve bu, CLI parametrelerini bildirmeyi ve kullanmayı kolaylaştırır. + +Genel söz dizimi, komut satırında bir `--<parametre_adı>` parametresi beklemek için `params.<parametre_adı>` bildirmektir. + +Burada `--input` adlı bir parametre oluşturmak istiyoruz, bu nedenle iş akışında bir yerde `params.input` bildirmemiz gerekiyor. +Prensipte bunu herhangi bir yere yazabiliriz; ancak bunu `sayHello()` süreç çağrısına vermek isteyeceğimiz için, doğrudan `sayHello(params.input)` yazarak oraya ekleyebiliriz. + +İş akışı bloğunda aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // bir selamlama yayınla + sayHello(params.input) + ``` + +=== "Önce" + + ```groovy title="hello-world.nf" linenums="23" hl_lines="2" + // bir selamlama yayınla + sayHello() + ``` + +Bu, Nextflow'a `sayHello` sürecini `--input` parametresi aracılığıyla sağlanan değer üzerinde çalıştırmasını söyler. + +Aslında, bölümün başında belirtilen (2) ve (3) adımlarını tek seferde başardık. + +### 3.3. İş akışı komutunu çalıştırın + +Çalıştıralım! + +```bash +nextflow run hello-world.nf --input 'Bonjour le monde!' +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elated_lavoisier] DSL2 - revision: 7c031b42ea + + executor > local (1) + [4b/654319] sayHello | 1 of 1 ✔ + ``` + +Tüm bu düzenlemeleri doğru yaptıysanız, başka bir başarılı yürütme elde etmelisiniz. + +Artık selamlamanın yeni sürümüne sahip olduğunuzdan emin olmak için çıktı dosyasını açtığınızdan emin olun. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_world/output.txt" + Bonjour le monde! + ``` + +Voilà! + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_world_input.svg" +</figure> + +Yeni yürütmenin `results` dizinine yayınlanan çıktı dosyasını nasıl üzerine yazdığına dikkat edin. +Ancak, önceki çalıştırmaların sonuçları `work` altındaki görev dizinlerinde hâlâ korunmaktadır. + +!!! tip "İpucu" + + Nextflow düzeyindeki parametreleri iş akışı düzeyindeki parametrelerden kolayca ayırt edebilirsiniz. + + - Bir iş akışına uygulanan parametreler her zaman çift tire (`--`) alır. + - Bir Nextflow ayarını değiştiren parametreler, örneğin daha önce kullandığımız `-resume` özelliği, tek tire (`-`) alır. + +### 3.4. Komut satırı parametreleri için varsayılan değerler kullanın + +Tamam, bu uygundu, ancak birçok durumda, her çalıştırma için belirtmek zorunda kalmamanız için belirli bir parametre için varsayılan bir değer sağlamak mantıklıdır. + +#### 3.4.1. CLI parametresi için varsayılan değer ayarlayın + +İş akışı tanımından önce bildirerek `input` parametresine varsayılan bir değer verelim. + +```groovy title="hello-world.nf" linenums="20" +/* + * Pipeline parametreleri + */ +params { + input: String = 'Holà mundo!' +} +``` + +Gördüğünüz gibi, iş akışının beklediği girdi türünü belirtebiliriz (Nextflow 25.10.2 ve sonrası). +Söz dizimi `ad: Tür = varsayılan_değer`'dir. +Desteklenen türler arasında `String`, `Integer`, `Float`, `Boolean` ve `Path` bulunur. + +!!! info "Bilgi" + + Eski iş akışlarında, tüm bu `params` bloğunun sadece `input = 'Holà mundo!'` olarak yazıldığını görebilirsiniz. + +İş akışınıza daha fazla parametre ekledikçe, varsayılan değer vermeniz gerekip gerekmediğine bakılmaksızın hepsini bu bloğa eklemelisiniz. +Bu, yapılandırılabilir tüm parametreleri bir bakışta bulmayı kolaylaştıracaktır. + +#### 3.4.2. İş akışını parametreyi belirtmeden tekrar çalıştırın + +Artık varsayılan bir değer ayarladığınıza göre, komut satırında bir değer belirtmek zorunda kalmadan iş akışını tekrar çalıştırabilirsiniz. + +```bash +nextflow run hello-world.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [determined_edison] DSL2 - revision: 3539118582 + + executor > local (1) + [72/394147] sayHello | 1 of 1 ✔ + ``` + +Çıktı daha önce olduğu gibi aynı yerde olacak, ancak içerikler yeni metinle güncellenmiş olmalıdır. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_world/output.txt" + Holà mundo! + ``` + +Nextflow, çıktıyı oluşturmak için selamlama parametresinin varsayılan değerini kullandı. + +#### 3.4.3. Varsayılan değeri geçersiz kılın + +Parametreyi komut satırında sağlarsanız, CLI değeri varsayılan değeri geçersiz kılar. + +Deneyin: + +```bash +nextflow run hello-world.nf --input 'Konnichiwa!' +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [elegant_faraday] DSL2 - revision: 3539118582 + + executor > local (1) + [6f/a12a91] sayHello | 1 of 1 ✔ + ``` + +Bir kez daha, sonuçlar dizininizde karşılık gelen güncellenmiş çıktıyı bulmalısınız. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_world/output.txt" + Konnichiwa! + ``` + +!!! note "Not" + + Nextflow'ta, parametreler için değerleri belirleyebileceğiniz birden fazla yer vardır. + Aynı parametre birden fazla yerde farklı değerlere ayarlanırsa, Nextflow hangi değeri kullanacağını [burada](https://www.nextflow.io/docs/latest/config.html) açıklanan öncelik sırasına göre belirler. + + Bunu Bölüm 6'da (Yapılandırma) daha ayrıntılı olarak ele alacağız. + +### Özet + +Komut satırı parametresi aracılığıyla çalışma zamanında sağlanan basit değişken girdiyi, ayrıca varsayılan değerleri ayarlamayı, kullanmayı ve geçersiz kılmayı nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışı yürütmelerini daha rahat nasıl yöneteceğinizi öğrenin. + +--- + +## 4. İş akışı yürütmelerini yönetin + +İş akışlarını nasıl başlatacağınızı ve çıktıları nasıl alacağınızı bilmek harikadır, ancak özellikle kendi iş akışlarınızı geliştiriyorsanız, hayatınızı kolaylaştıracak iş akışı yönetiminin birkaç diğer yönü olduğunu çabucak göreceksiniz. + +Burada, aynı iş akışını yeniden başlatmanız gerektiğinde `resume` özelliğini nasıl kullanacağınızı, `nextflow log` ile geçmiş yürütmelerin günlüğünü nasıl inceleyeceğinizi ve `nextflow clean` ile eski work dizinlerini nasıl sileceğinizi gösteriyoruz. + +### 4.1. `-resume` ile bir iş akışını yeniden başlatın + +Bazen, daha önce başlattığınız bir iş akışını, zaten başarıyla tamamlanmış adımları tekrarlamadan yeniden çalıştırmak isteyeceksiniz. + +Nextflow'un bunu yapmanızı sağlayan `-resume` adlı bir seçeneği vardır. +Özellikle, bu modda, zaten tam olarak aynı kod, ayarlar ve girdilerle çalıştırılmış olan tüm süreçler atlanacaktır. +Bu, Nextflow'un yalnızca son çalıştırmadan bu yana eklediğiniz veya değiştirdiğiniz süreçleri veya yeni ayarlar veya girdiler sağladığınız süreçleri çalıştıracağı anlamına gelir. + +Bunu yapmanın iki önemli avantajı vardır: + +- İş akışınızı geliştirme aşamasındaysanız, değişikliklerinizi test etmek için yalnızca üzerinde aktif olarak çalıştığınız süreci(leri) çalıştırmanız gerektiğinden daha hızlı iterasyon yapabilirsiniz. +- Bir iş akışını üretimde çalıştırıyorsanız ve bir şeyler ters giderse, birçok durumda sorunu düzeltip iş akışını yeniden başlatabilirsiniz ve arıza noktasından çalışmaya devam eder, bu da size çok zaman ve hesaplama tasarrufu sağlayabilir. + +Kullanmak için komutunuza `-resume` eklemeniz ve çalıştırmanız yeterlidir: + +```bash +nextflow run hello-world.nf -resume +``` + +??? success "Komut çıktısı" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-world.nf` [golden_cantor] DSL2 - revision: 35bd3425e5 + + [62/49a1f8] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Konsol çıktısı tanıdık görünmeli, ancak daha öncesine kıyasla biraz farklı bir şey var. + +Süreç durumu satırına (satır 5) eklenen `cached:` kısmına bakın, bu Nextflow'un bu işi zaten yaptığını ve önceki başarılı çalıştırmanın sonucunu yeniden kullandığını gösterir. + +Work alt dizini hash'inin önceki çalıştırmayla aynı olduğunu da görebilirsiniz. +Nextflow kelimenin tam anlamıyla sizi önceki yürütmeye yönlendiriyor ve "Bunu zaten orada yaptım" diyor. + +!!! tip "İpucu" + + `resume` ile bir iş akışını yeniden çalıştırdığınızda, Nextflow daha önce başarıyla çalıştırılmış yürütmeler tarafından work dizini dışına yayınlanan dosyaların üzerine yazmaz. + +### 4.2. Geçmiş yürütmelerin günlüğünü inceleyin + +İster yeni bir iş akışı geliştiriyor olun, ister iş akışlarını üretimde çalıştırıyor olun, bir noktada muhtemelen geçmiş çalıştırmalar hakkında bilgi aramanız gerekecektir. +İşte bunu nasıl yapacağınız. + +Bir nextflow iş akışı başlattığınızda, mevcut çalışma dizininde `.nextflow` adlı gizli bir dizin altında `history` adlı bir günlük dosyasına bir satır yazılır. + +??? abstract "Dosya içerikleri" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Bu dosya, mevcut çalışma dizininden başlatılan her Nextflow çalıştırması için zaman damgası, çalıştırma adı, durum, revizyon kimliği, oturum kimliği ve tam komut satırını verir. + +Bu bilgilere erişmenin daha uygun bir yolu `nextflow log` komutunu kullanmaktır. + +```bash +nextflow log +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Bu, günlük dosyasının içeriğini terminale çıkarır ve bir başlık satırıyla zenginleştirir. + +Yeni bir `nextflow run` komutu çalıştırdığınızda oturum kimliğinin değiştiğini, ANCAK `-resume` seçeneğini kullanıyorsanız değişmediğini fark edeceksiniz. +Bu durumda oturum kimliği aynı kalır. + +Nextflow, çalıştırma önbellek bilgilerini `.nextflow` altında bulunan `cache` dizini altında gruplandırmak için oturum kimliğini kullanır. + +### 4.3. Eski work dizinlerini silin + +Geliştirme sürecinde, taslak iş akışınızı genellikle çok sayıda çalıştırırsınız, bu da birçok alt dizinde birçok dosyanın birikmesine yol açabilir. + +Neyse ki Nextflow, artık umursamadığınız geçmiş çalıştırmaların work alt dizinlerini otomatik olarak silebilen yararlı bir `clean` alt komutu içerir. + +#### 4.3.1. Silme kriterlerini belirleyin + +Neyin silineceğini belirlemek için birden fazla [seçenek](https://www.nextflow.io/docs/latest/reference/cli.html#clean) vardır. + +Burada, çalıştırma adı kullanılarak belirtilen belirli bir çalıştırmadan önce tüm alt dizinleri silen bir örnek gösteriyoruz. + +`-resume` kullanmadığınız en son başarılı çalıştırmaya bakın; bizim durumumuzda çalıştırma adı `golden_cantor` idi. + +Çalıştırma adı, `Launching (...)` konsol çıktı satırında köşeli parantez içinde gösterilen makine tarafından oluşturulan iki parçalı dizedir. +Zaman damgası ve/veya komut satırına göre bir çalıştırmayı aramak için Nextflow günlüğünü de kullanabilirsiniz. + +#### 4.3.2. Kuru çalıştırma yapın + +Önce komut verildiğinde nelerin silineceğini kontrol etmek için kuru çalıştırma bayrağı `-n`'yi kullanıyoruz: + +```bash +nextflow clean -before golden_cantor -n +``` + +??? success "Komut çıktısı" + + ```console + Would remove /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Çıktınız farklı görev dizini adlarına sahip olacak ve farklı sayıda satır olabilir, ancak örneğe benzer görünmelidir. + +Herhangi bir satır çıktısı görmüyorsanız, ya geçerli bir çalıştırma adı sağlamadınız ya da silinecek geçmiş çalıştırma yok. Örnek komuttaki `golden_cantor`'u günlüğünüzdeki karşılık gelen en son çalıştırma adına değiştirdiğinizden emin olun. + +#### 4.3.3. Silme işlemine devam edin + +Çıktı beklendiği gibi görünüyorsa ve silme işlemine devam etmek istiyorsanız, `-n` yerine `-f` bayrağıyla komutu yeniden çalıştırın: + +```bash +nextflow clean -before golden_cantor -f +``` + +??? success "Komut çıktısı" + + ```console + Removed /workspaces/training/hello-nextflow/work/a3/7be2fad5e71e5f49998f795677fd68 + ``` + +Çıktı daha öncekine benzer olmalı, ancak şimdi 'Would remove' yerine 'Removed' diyor. +Bunun iki karakterlik alt dizinleri (yukarıdaki `a3/` gibi) kaldırmadığını, ancak içeriklerini boşalttığını unutmayın. + +!!! Warning "Uyarı" + + Geçmiş çalıştırmalardan work alt dizinlerini silmek onları Nextflow'un önbelleğinden kaldırır ve bu dizinlerde depolanan tüm çıktıları siler. + Bu, Nextflow'un karşılık gelen süreçleri yeniden çalıştırmadan yürütmeyi sürdürme yeteneğini bozar. + + Umursadığınız veya güvenmeyi planladığınız çıktıları kaydetmekten siz sorumlusunuz! Bu, `publish` yönergesi için `symlink` modu yerine `copy` modunu tercih etmemizin ana nedenidir. + +### Özet + +Çıktıları belirli bir dizine nasıl yayınlayacağınızı, zaten aynı şekilde çalıştırılmış adımları tekrarlamadan bir iş akışını nasıl yeniden başlatacağınızı ve eski work dizinlerini temizlemek için `nextflow clean` komutunu nasıl kullanacağınızı biliyorsunuz. + +Daha genel olarak, basit bir Nextflow iş akışını nasıl yorumlayacağınızı, yürütmesini nasıl yöneteceğinizi ve çıktıları nasıl alacağınızı biliyorsunuz. + +### Sırada ne var? + +Küçük bir mola verin, hak ettiniz! + +Hazır olduğunuzda, iş akışınıza girdileri beslemek için kanalları nasıl kullanacağınızı öğrenmek için [**Bölüm 2: Hello Channels**](./02_hello_channels.md)'a geçin; bu, Nextflow'un yerleşik veri akışı paralelliğinden ve diğer güçlü özelliklerden yararlanmanızı sağlayacaktır. + +--- + +## Quiz + +<quiz> +Bir Nextflow sürecinin minimum gerekli bileşenleri nelerdir? +- [ ] Yalnızca input ve output blokları +- [x] Output ve script blokları +- [ ] Input, output ve script blokları +- [ ] Yalnızca script bloğu + +Daha fazla bilgi: [1.1.1. Süreç tanımı](#111-process-tanımı) +</quiz> + +<quiz> +Bir süreçteki output bloğunun amacı nedir? +- [ ] Sonuçları konsola yazdırmak +- [ ] Dosyaları work dizinine kaydetmek +- [x] Süreçten beklenen çıktıları bildirmek +- [ ] Ortam değişkenlerini tanımlamak + +Daha fazla bilgi: [1.1.1. Süreç tanımı](#111-process-tanımı) +</quiz> + +<quiz> +Bir Nextflow iş akışını çalıştırmak için hangi komut kullanılır? +- [ ] `nextflow start` +- [ ] `nextflow execute` +- [x] `nextflow run` +- [ ] `nextflow launch` +</quiz> + +<quiz> +Bir görevin work dizinine bakıldığında, hangi dosya gerçekte yürütülen komutu içerir? + +``` +work/a3/7be2fa.../ +├── .command.begin +├── .command.err +├── .command.log +├── .command.out +├── .command.run +├── .command.sh +├── .exitcode +└── output.txt +``` + +- [ ] `.command.run` +- [x] `.command.sh` +- [ ] `.command.log` +- [ ] `.command.out` + +Daha fazla bilgi: [1.2.2. `work` dizininde çıktıyı ve günlükleri bulun](#122-work-dizininde-çıktıyı-ve-günlükleri-bulun) +</quiz> + +<quiz> +`-resume` bayrağı ne yapar? +- [ ] İş akışını baştan başlatır +- [ ] İş akışını duraklatır +- [x] Zaten başarıyla tamamlanmış süreçleri atlar +- [ ] İş akışının yedeğini oluşturur + +Daha fazla bilgi: [4.1. `-resume` ile bir iş akışını yeniden başlatın](#41--resume-ile-bir-iş-akışını-yeniden-başlatın) +</quiz> + +<quiz> +İş akışı çıktılarını yayınlamak için varsayılan mod nedir? +- [ ] Dosyaları çıktı dizinine kopyala +- [x] Çıktı dizininde sembolik bağlantılar oluştur +- [ ] Dosyaları çıktı dizinine taşı +- [ ] Dosyaları çıktı dizininde sıkıştır + +Daha fazla bilgi: [2.3. Yayınlama modunu kopyalamaya ayarlayın](#23-yayınlama-modunu-kopyalamaya-ayarlayın) +</quiz> + +<quiz> +Komut satırından bir Nextflow iş akışına parametre değeri nasıl iletilir? +- [ ] `-parameter değer` +- [ ] `--parameter:değer` +- [x] `--parameter değer` +- [ ] `-p parameter=değer` + +Daha fazla bilgi: [3.2. Kullanıcı girdisini yakalamak için komut satırı parametresi ayarlayın](#32-kullanıcı-girdisini-yakalamak-için-komut-satırı-parametresi-ayarlayın) +</quiz> + +<quiz> +Nextflow script bloğu içinde bir değişkene nasıl başvurulur? +- [ ] `%değişken%` söz dizimini kullan +- [x] `#!groovy ${değişken}` söz dizimini kullan +- [ ] `{{değişken}}` söz dizimini kullan +- [ ] `[değişken]` söz dizimini kullan +</quiz> diff --git a/docs/tr/docs/hello_nextflow/02_hello_channels.md b/docs/tr/docs/hello_nextflow/02_hello_channels.md new file mode 100644 index 0000000000..f606ff86c1 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/02_hello_channels.md @@ -0,0 +1,1430 @@ +# Bölüm 2: Hello Channels + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesini](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video transkripti [burada](./transcripts/02_hello_channels.md) mevcuttur. +/// + +Bu kursun 1. Bölümünde (Hello World), bir sürece değişken girdi sağlamak için girdiyi doğrudan süreç çağrısında nasıl ileteceğinizi gösterdik: `sayHello(params.input)`. +Bu kasıtlı olarak basitleştirilmiş bir yaklaşımdı. +Pratikte, bu yaklaşımın önemli sınırlamaları vardır; yani yalnızca süreci tek bir değer üzerinde yalnızca bir kez çalıştırmak istediğimiz çok basit durumlar için çalışır. +Çoğu gerçekçi iş akışı kullanım durumunda, birden fazla değeri işlemek istiyoruz (örneğin, birden fazla örnek için deneysel veriler), bu nedenle girdileri işlemek için daha sofistike bir yönteme ihtiyacımız var. + +Nextflow **kanalları** tam da bunun için var. +Kanallar, girdileri verimli bir şekilde işlemek ve çok adımlı iş akışlarında bir adımdan diğerine taşımak için tasarlanmış kuyruklardır; yerleşik paralellik ve birçok ek avantaj sağlarlar. + +Bu kursun bu bölümünde, çeşitli farklı kaynaklardan gelen birden fazla girdiyi işlemek için bir kanalı nasıl kullanacağınızı öğreneceksiniz. +Ayrıca kanal içeriklerini gerektiği gibi dönüştürmek için **operatörleri** nasıl kullanacağınızı da öğreneceksiniz. + +??? info "Bu bölümden nasıl başlanır" + + Bu kursun bu bölümü, [Hello Nextflow](./index.md) kursunun 1. Bölümünü tamamladığınızı varsayar, ancak o bölümde ele alınan temel konulara hakimseniz, özel bir şey yapmadan buradan başlayabilirsiniz. + +--- + +## 0. Isınma: `hello-channels.nf` dosyasını çalıştırın + +Başlangıç noktası olarak `hello-channels.nf` iş akışı betiğini kullanacağız. +Bu betik, bu eğitim kursunun 1. Bölümünde üretilen betiğe eşdeğerdir; ancak çıktı hedefini değiştirdik: + +```groovy title="hello-channels.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_channels' + mode 'copy' + } +} +``` + +Her şeyin çalıştığından emin olmak için, herhangi bir değişiklik yapmadan önce betiği bir kez çalıştırın: + +```bash +nextflow run hello-channels.nf --input 'Hello Channels!' +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [wise_jennings] DSL2 - revision: b24f4902d6 + + executor > local (1) + [6f/824bc1] process > sayHello [100%] 1 of 1 ✔ + ``` + +Daha önce olduğu gibi, çıktı dosyasını `output.txt` adıyla `results/hello_channels` dizininde bulacaksınız (yukarıda gösterilen iş akışı betiğinin `output` bloğunda belirtildiği gibi). + +??? abstract "Dizin içerikleri" + + ```console title="results/hello_channels" hl_lines="2-3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Bu sizin için çalıştıysa, kanallar hakkında öğrenmeye hazırsınız. + +--- + +## 1. Değişken girdileri bir kanal aracılığıyla açıkça sağlayın + +Örtük işlemeye güvenmek yerine, değişken girdiyi `sayHello()` sürecine iletmek için bir **kanal** oluşturacağız; örtük işlemenin belirli sınırlamaları vardır. + +### 1.1. Bir girdi kanalı oluşturun + +Bir kanal kurmak için kullanabileceğimiz çeşitli **kanal fabrikaları** vardır. +Şimdilik işleri basit tutmak için, tek bir değer içeren bir kanal oluşturacak olan `channel.of` adlı en temel kanal fabrikasını kullanacağız. +İşlevsel olarak bu, daha önce kurduğumuz yönteme benzer olacak, ancak Nextflow'un örtük olarak bir kanal oluşturmasına izin vermek yerine, bunu artık açıkça yapıyoruz. + +Kullanacağımız kod satırı şu: + +```console title="Sözdizimi" +greeting_ch = channel.of('Hello Channels!') +``` + +Bu, `channel.of()` kanal fabrikasını kullanarak `greeting_ch` adında bir kanal oluşturur; bu fabrika basit bir kuyruk kanalı kurar ve selamlama değeri olarak kullanılmak üzere `'Hello Channels!'` dizesini yükler. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel.svg" +</figure> + +!!! note "Not" + + Okunabilirlik adına geçici olarak sabit kodlanmış dizelere dönüyoruz ve CLI parametresi kullanmıyoruz. Kanal düzeyinde neler olduğunu ele aldıktan sonra CLI parametrelerini kullanmaya geri döneceğiz. + +İş akışı bloğunda, kanal fabrikası kodunu ekleyin: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels!') + // bir selamlama yayınla + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // bir selamlama yayınla + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Süreç çağrısına girdiyi henüz değiştirmediğimiz için bu henüz işlevsel değil. + +### 1.2. Kanalı süreç çağrısına girdi olarak ekleyin + +Şimdi yeni oluşturduğumuz kanalı `sayHello()` süreç çağrısına bağlamamız gerekiyor; daha önce doğrudan sağladığımız CLI parametresinin yerine geçecek. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels!') + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels!') + // bir selamlama yayınla + sayHello(params.input) + + publish: + first_output = sayHello.out + } + ``` + +Bu, Nextflow'a `sayHello` sürecini `greeting_ch` kanalının içerikleri üzerinde çalıştırmasını söyler. + +Artık iş akışımız düzgün bir şekilde işlevsel; `sayHello('Hello Channels!')` yazmanın açık eşdeğeridir. + +### 1.3. İş akışını çalıştırın + +Hadi çalıştıralım! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [fabulous_crick] DSL2 - revision: 23e20f76e8 + + executor > local (1) + [c0/4f1872] process > sayHello (1) [100%] 1 of 1 ✔ + ``` + +Her iki düzenlemeyi de doğru yaptıysanız, başarılı bir yürütme elde etmelisiniz. +Sonucun hâlâ daha önce olduğu gibi olduğundan emin olmak için results dizinini kontrol edebilirsiniz. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_channels/output.txt" + Hello Channels! + ``` + +Böylece aynı sonuca ulaşırken iş akışımızın esnekliğini artırdık. +Bu, somut bir fayda olmadan daha fazla kod yazmak gibi görünebilir, ancak daha fazla girdiyi işlemeye başladığımızda değeri netleşecek. + +Bunun bir önizlemesi olarak, devam etmeden önce bir şeye daha bakalım: veri girişini yönetmek için açık bir kanal kullanmanın küçük ama kullanışlı bir faydası. + +### 1.4. Kanal içeriklerini incelemek için `view()` kullanın + +Nextflow kanalları, içerikleri üzerinde operatörler kullanarak işlem yapmamıza olanak tanıyan bir şekilde oluşturulmuştur; operatörleri bu bölümde daha ayrıntılı ele alacağız. + +Şimdilik, size bir kanalın içeriklerini incelemek için [`view()`](https://www.nextflow.io/docs/latest/reference/operator.html#view) adlı çok basit bir operatörü nasıl kullanacağınızı göstereceğiz. +`view()`'ı Python'daki `print()` ifadesi veya diğer dillerdeki eşdeğeri gibi bir hata ayıklama aracı olarak düşünebilirsiniz. + +Bu küçük satırı iş akışı bloğuna ekleyin: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels!') + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels!') + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Tam boşluk miktarı 4'ün katı olduğu sürece önemli değil; amacımız `.view()` ifadesinin başlangıcını kanal yapımının `.of()` kısmına hizalamak. + +Şimdi iş akışını tekrar çalıştırın: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [scruffy_shaw] DSL2 - revision: 2ede41e14a + + executor > local (1) + [ef/f7e40a] sayHello (1) [100%] 1 of 1 ✔ + Hello Channels! + ``` + +Gördüğünüz gibi, bu kanal içeriklerini konsola çıktı olarak verir. +Burada yalnızca bir öğemiz var, ancak bir sonraki bölümde kanala birden fazla değer yüklemeye başladığımızda, bunun satır başına bir öğe çıktısı verecek şekilde ayarlandığını göreceksiniz. + +### Özet + +Bir sürece girdi sağlamak için temel bir kanal fabrikasını nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışının birden fazla girdi değeri üzerinde yineleme yapmasını sağlamak için kanalları nasıl kullanacağınızı öğrenin. + +--- + +## 2. İş akışını birden fazla girdi değeri üzerinde çalışacak şekilde değiştirin + +İş akışları genellikle toplu olarak işlenmesi gereken girdi grupları üzerinde çalışır, bu nedenle iş akışını birden fazla girdi değerini kabul edecek şekilde yükseltmek istiyoruz. + +### 2.1. Girdi kanalına birden fazla selamlama yükleyin + +Kullanışlı bir şekilde, kullandığımız `channel.of()` kanal fabrikası birden fazla değeri kabul etmekten memnuniyet duyar, bu nedenle bunu hiç değiştirmemize gerek yok. +Sadece kanala birden fazla değer yükleyebiliriz. + +Bunları `'Hello'`, `'Bonjour'` ve `'Holà'` yapalım. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-channel-multi.svg" +</figure> + +_Diyagramda, kanal yeşil renkte temsil edilmektedir ve öğelerin sırası bir borudaki misketler gibi temsil edilmektedir: ilk yüklenen sağda, sonra ikincisi ortada, sonra üçüncüsü soldadır._ + +#### 2.1.1. Daha fazla selamlama ekleyin + +İş akışı bloğundan önce, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="30" hl_lines="2" + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello Channels') + .view() + ``` + +Dokümantasyon bunun çalışması gerektiğini söylüyor. Gerçekten bu kadar basit olabilir mi? + +#### 2.1.2. Komutu çalıştırın ve log çıktısına bakın + +Hadi deneyelim. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [amazing_crick] DSL2 - revision: 59a9a5888a + + executor > local (3) + [f4/c9962c] process > sayHello (1) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Kesinlikle sorunsuz çalışmış görünüyor. +Yürütme monitörü `sayHello` süreci için `3 of 3` çağrı yapıldığını gösteriyor ve söz verildiği gibi `view()` ifadesi tarafından sıralanan üç selamlamayı satır başına bir tane olarak görüyoruz. + +Ancak, results dizininde hâlâ yalnızca bir çıktı var: + +??? abstract "Dizin içerikleri" + + ```console title="results/hello_channels" hl_lines="3" + results + ├── hello_channels + │ └── output.txt + ├── hello_world + │ └── output.txt + └── output.txt -> /workspaces/training/hello-nextflow/work/8c/79499c11beea6e9d43605141f2817f/output.txt + ``` + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_channels/output.txt" + Holà + ``` + +Orada üç selamlamadan birini görmelisiniz, ancak aldığınız burada gösterilenden farklı olabilir. +Bunun neden olabileceğini düşünebilir misiniz? + +Yürütme monitörüne geri baktığımızda, bize yalnızca bir alt dizin yolu verdi (`f4/c9962c`). +Hadi oraya bir göz atalım. + +??? abstract "Dizin içerikleri" + + ```console hl_lines="9" + work/f4/c9962ce91ef87480babcb86b2b9042/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Dosya içerikleri" + + ```console title="work/f4/c9962ce91ef87480babcb86b2b9042/output.txt" + Hello + ``` + +Bu results dizininde aldığımız selamlama bile değil! Neler oluyor? + +Bu noktada, varsayılan olarak ANSI loglama sisteminin aynı sürece yapılan birden fazla çağrının loglamasını aynı satıra yazdığını söylememiz gerekiyor. +Dolayısıyla sayHello() sürecine yapılan üç çağrının tamamının durumu aynı yere düşüyor. + +Neyse ki, süreç çağrılarının tam listesini görmek için bu davranışı devre dışı bırakabiliriz. + +#### 2.1.3. Komutu `-ansi-log false` seçeneğiyle tekrar çalıştırın + +Loglamayı süreç çağrısı başına bir satır görüntüleyecek şekilde genişletmek için komuta `-ansi-log false` ekleyin. + +```bash +nextflow run hello-channels.nf -ansi-log false +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + Launching `hello-channels.nf` [desperate_monod] DSL2 - revision: 59a9a5888a + Hello + Bonjour + Holà + [23/871c7e] Submitted process > sayHello (2) + [7f/21e2c2] Submitted process > sayHello (1) + [f4/ea10a6] Submitted process > sayHello (3) + ``` + +Bu sefer çıktıda listelenen üç süreç çalışmasını ve bunlarla ilişkili work alt dizinlerini görüyoruz. + +Bu çok daha iyi, en azından basit bir iş akışı için. +Karmaşık bir iş akışı veya çok sayıda girdi için, tam listenin terminale çıktı olarak verilmesi biraz bunaltıcı olurdu. +Bu nedenle `-ansi-log false` varsayılan davranış değil. + +!!! tip "İpucu" + + Durumun raporlanma şekli iki loglama modu arasında biraz farklıdır. + Yoğunlaştırılmış modda, Nextflow çağrıların başarıyla tamamlanıp tamamlanmadığını raporlar. + Bu genişletilmiş modda, yalnızca gönderildiklerini raporlar. + +Her neyse, artık her süreç çağrısının alt dizinlerine sahip olduğumuza göre, loglarına ve çıktılarına bakabiliriz. + +??? abstract "Dizin içerikleri" + + ```console + work/23/871c7ec3642a898ecd5e6090d21300/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/7f/21e2c2f3cc8833ef3858b236e5575c/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + + ```console + work/f4/ea10a680d5687596d3eaa3fcf69272/ + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? abstract "Dosya içerikleri" + + ```txt title="work/23/871c7ec3642a898ecd5e6090d21300/output.txt" + Bonjour + ``` + + ```txt title="work/7f/21e2c2f3cc8833ef3858b236e5575c/output.txt" + Hello + ``` + + ```txt title="work/f4/ea10a680d5687596d3eaa3fcf69272/output.txt" + Holà + ``` + +Bu, üç sürecin de başarıyla çalıştığını gösteriyor (yaşasın). + +Bununla birlikte, results dizininde hâlâ yalnızca bir çıktı dosyası olması sorunu var. + +`sayHello` süreci için çıktı dosya adını sabit kodladığımızı hatırlayabilirsiniz, bu nedenle üç çağrının tümü `output.txt` adlı bir dosya üretti. + +Çıktı dosyaları, diğer süreçlerden izole edilmiş work alt dizinlerinde kaldığı sürece, bu sorun değil. +Ancak aynı results dizinine yayınlandıklarında, ilk kopyalanan bir sonraki tarafından üzerine yazılır ve bu böyle devam eder. + +### 2.2. Çıktı dosya adlarının benzersiz olmasını sağlayın + +Tüm çıktıları aynı results dizinine yayınlamaya devam edebiliriz, ancak benzersiz adlara sahip olmalarını sağlamamız gerekiyor. +Özellikle, son dosya adlarının benzersiz olması için ilk süreci dinamik olarak bir dosya adı oluşturacak şekilde değiştirmemiz gerekiyor. + +Peki dosya adlarını nasıl benzersiz yaparız? +Bunu yapmanın yaygın bir yolu, girdilerden (girdi kanalından alınan) bazı benzersiz meta verileri çıktı dosya adının bir parçası olarak kullanmaktır. +Burada, kolaylık olsun diye, yalnızca kısa bir dize olduğu için selamlamanın kendisini kullanacağız ve bunu temel çıktı dosya adının önüne ekleyeceğiz. + +#### 2.2.1. Dinamik bir çıktı dosya adı oluşturun + +Süreç bloğunda, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="6" hl_lines="7 11" + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + ``` + +`output.txt` ifadesini hem çıktı tanımında hem de `script:` komut bloğunda değiştirdiğinizden emin olun. + +!!! tip "İpucu" + + Çıktı tanımında, çıktı dosya adı ifadesinin etrafında çift tırnak kullanmalısınız (tek tırnak DEĞİL), aksi takdirde başarısız olacaktır. + +Bu, süreç her çağrıldığında benzersiz bir çıktı dosya adı üretmelidir, böylece çıktı dizinindeki aynı sürece yapılan diğer çağrıların çıktılarından ayırt edilebilir. + +#### 2.2.2. İş akışını çalıştırın + +Hadi çalıştıralım. Varsayılan ANSI log ayarlarıyla çalıştırmaya geri döndüğümüzü unutmayın. + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sharp_minsky] DSL2 - revision: 16a291febe + + executor > local (3) + [e8/33ee64] sayHello (2) [100%] 3 of 3 ✔ + Hello + Bonjour + Holà + ``` + +Özet görünümüne geri döndüğümüzde, çıktı tekrar bir satırda özetleniyor. +Tüm çıktı selamlamalarının orada olup olmadığını görmek için `results` dizinine bakın. + +??? abstract "Dizin içerikleri" + + ```console + results/hello_channels/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + └── output.txt + ``` + +Evet! Ve her birinin beklenen içerikleri var. + +??? abstract "Dosya içerikleri" + + ```console title="Bonjour-output.txt" + Bonjour + ``` + + ```console title="Hello-output.txt" + Hello + ``` + + ```console title="Holà-output.txt" + Holà + ``` + +Başarılı! Artık çıktı dosyalarının üzerine yazılması konusunda endişelenmeden istediğimiz kadar selamlama ekleyebiliriz. + +!!! tip "İpucu" + + Pratikte, dosyaları girdi verilerine dayalı olarak adlandırmak neredeyse her zaman pratik değildir. + Dinamik dosya adları oluşturmanın daha iyi yolu, meta verileri girdi dosyalarıyla birlikte bir sürece iletmektir. + Meta veriler genellikle bir 'örnek sayfası' veya eşdeğerleri aracılığıyla sağlanır. + Bunu daha sonra Nextflow eğitiminizde öğreneceksiniz (bkz. [Meta veri yan görevi](../side_quests/metadata.md)). + +### Özet + +Bir kanal aracılığıyla birden fazla girdi öğesini nasıl besleyeceğinizi biliyorsunuz. + +### Sırada ne var? + +Bir kanalın içeriklerini dönüştürmek için bir operatörü nasıl kullanacağınızı öğrenin. + +--- + +## 3. Bir dizi aracılığıyla birden fazla girdi sağlayın + +Az önce, doğrudan kanal fabrikasında sabit kodlanmış birden fazla girdi öğesini nasıl işleyeceğinizi gösterdik. +Ya bu birden fazla girdiyi farklı bir şekilde sağlamak istersek? + +Örneğin, şöyle bir öğe dizisi içeren bir girdi değişkeni kurduğumuzu düşünün: + +`greetings_array = ['Hello','Bonjour','Holà']` + +Bunu çıktı kanalımıza yükleyip çalışmasını bekleyebilir miyiz? + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-array.svg" +</figure> + +Hadi öğrenelim. + +### 3.1. Kanala girdi olarak bir değer dizisi sağlayın + +Sağduyu, tek bir değer yerine bir değer dizisini basitçe iletebilmemiz gerektiğini öne sürüyor. +Hadi deneyelim; girdi değişkenini kurmamız ve kanal fabrikasına yüklememiz gerekecek. + +#### 3.1.1. Girdi değişkenini kurun + +Az önce hayal ettiğimiz `greetings_array` değişkenini iş akışı bloğuna ekleyerek gerçeğe dönüştürelim: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4 5" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Bu henüz işlevsel değil, sadece dizi için bir tanımlama ekledik. + +#### 3.1.2. Selamlama dizisini kanal fabrikasına girdi olarak ayarlayın + +Şimdi kanal fabrikasında şu anda sabit kodlanmış `'Hello','Bonjour','Holà'` değerlerini az önce oluşturduğumuz `greetings_array` ile değiştireceğiz. + +İş akışı bloğunda, aşağıdaki değişikliği yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="7" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of('Hello','Bonjour','Holà') + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Bu artık işlevsel olmalı. + +#### 3.1.3. İş akışını çalıştırın + +Hadi çalıştırmayı deneyelim: + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Komut çıktısı" + + ```console hl_lines="7 11 16" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [friendly_koch] DSL2 - revision: 97256837a7 + + executor > local (1) + [a8/1f6ead] sayHello (1) | 0 of 1 + [Hello, Bonjour, Holà] + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + Missing output file(s) `[Hello, Bonjour, Holà]-output.txt` expected by process `sayHello (1)` + + + Command executed: + + echo '[Hello, Bonjour, Holà]' > '[Hello, Bonjour, Holà]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/a8/1f6ead5f3fa30a3c508e2e7cf83ffb + + Tip: you can replicate the issue by changing to the process work dir and entering the command `bash .command.run` + + -- Check '.nextflow.log' file for details + ``` + +Hay aksi! Bir hata var! + +`view()` çıktısına ve hata mesajlarına bakın. + +Görünüşe göre Nextflow, dizideki üç dizeyi ayrı değerler olarak kullanmak yerine, `[Hello, Bonjour, Holà]`'yı bir dize değeri olarak kullanarak tek bir süreç çağrısı çalıştırmaya çalıştı. + +Yani soruna neden olan "paketleme". +Nextflow'un diziyi açmasını ve bireysel dizeleri kanala yüklemesini nasıl sağlarız? + +### 3.2. Kanal içeriklerini dönüştürmek için bir operatör kullanın + +İşte **[operatörler](https://www.nextflow.io/docs/latest/reference/operator.html)** burada devreye giriyor. +Zaten `.view()` operatörünü kullandınız, bu sadece içinde ne olduğuna bakar. +Şimdi bir kanalın içerikleri üzerinde işlem yapmamıza olanak tanıyan operatörlere bakacağız. + +Nextflow belgelerindeki [operatör listesine](https://www.nextflow.io/docs/latest/reference/operator.html) göz atarsanız, tam olarak ihtiyacımız olanı yapan [`flatten()`](https://www.nextflow.io/docs/latest/reference/operator.html#flatten) operatörünü bulacaksınız: bir dizinin içeriğini açar ve bunları ayrı öğeler olarak yayınlar. + +#### 3.2.1. `flatten()` operatörünü ekleyin + +`flatten()` operatörünü girdi kanalımıza uygulamak için, kanal fabrikası tanımlamasına ekliyoruz. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Burada okunabilirlik için operatörü bir sonraki satıra ekledik, ancak tercih ederseniz operatörleri kanal fabrikasıyla aynı satıra ekleyebilirsiniz, şöyle: +`greeting_ch = channel.of(greetings_array).view().flatten()` + +#### 3.2.2. `view()` ifadesini/ifadelerini iyileştirin + +Bunu hemen test etmek için çalıştırabiliriz, ancak bu sırada kanal içeriklerini nasıl incelediğimizi iyileştireceğiz. + +`flatten()` operatörü uygulanmadan önce ve sonra içeriklerin nasıl göründüğünü karşılaştırabilmek istiyoruz, bu yüzden ikinci bir tane ekleyeceğiz VE çıktıda daha net etiketlenmelerini sağlamak için biraz kod ekleyeceğiz. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-10" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view { greeting -> "flatten öncesi: $greeting" } + .flatten() + .view { greeting -> "flatten sonrası: $greeting" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="8-9" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view() + .flatten() + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +İkinci bir `.view` ifadesi eklediğimizi ve her biri için boş parantezleri (`()`) biraz kod içeren süslü parantezlerle değiştirdiğimizi görüyorsunuz, örneğin `{ greeting -> "flatten öncesi: $greeting" }`. + +Bunlara _closure_ denir. İçerdikleri kod, kanaldaki her öğe için yürütülecektir. +İç değer için burada `greeting` adında (ancak herhangi bir rastgele ad olabilir) geçici bir değişken tanımlıyoruz, bu yalnızca o closure kapsamında kullanılır. + +Bu örnekte, `$greeting` kanalda yüklenen her bir öğeyi temsil eder. +Bu, düzgün etiketlenmiş konsol çıktısı ile sonuçlanacaktır. + +!!! info "Bilgi" + + Bazı pipeline'larda operatör closure'ları içinde `$it` adlı özel bir değişkenin kullanıldığını görebilirsiniz. + Bu, `->` ile tanımlamaya gerek kalmadan iç değişkene kısa yoldan erişim sağlayan bir _örtük_ değişkendir. + + Kod netliğine yardımcı olmak için açık olmayı tercih ediyoruz, bu nedenle `$it` sözdizimi önerilmemektedir ve Nextflow dilinden yavaş yavaş kaldırılacaktır. + +#### 3.2.3. İş akışını çalıştırın + +Son olarak, iş akışını tekrar çalıştırabilirsiniz! + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7-10" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [sleepy_gutenberg] DSL2 - revision: 1db4f760ee + + executor > local (3) + [b1/6a1e15] sayHello (2) [100%] 3 of 3 ✔ + flatten öncesi: [Hello, Bonjour, Holà] + flatten sonrası: Hello + flatten sonrası: Bonjour + flatten sonrası: Holà + ``` + +Bu sefer çalışıyor VE `flatten()` operatörünü çalıştırmadan önce ve sonra kanal içeriklerinin nasıl göründüğüne dair ek bilgi veriyor. + +- Tek bir `flatten öncesi:` ifadesi görüyorsunuz çünkü o noktada kanal bir öğe içeriyor, orijinal dizi. + Sonra, artık kanalda bireysel öğeler olan her selamlama için bir tane olmak üzere üç ayrı `flatten sonrası:` ifadesi görüyorsunuz. + +Önemli olarak, bu her öğenin artık iş akışı tarafından ayrı ayrı işlenebileceği anlamına gelir. + +!!! tip "İpucu" + + Aynı sonuçları, işleminde örtük bir eşleme adımı içeren farklı bir kanal fabrikası [`channel.fromList`](https://nextflow.io/docs/latest/reference/channel.html#fromlist) kullanarak elde etmek teknik olarak mümkündür. + Burada, basit bir kullanım durumunda bir operatörün kullanımını göstermek için bunu kullanmamayı tercih ettik. + +### Özet + +Bir kanalın içeriklerini dönüştürmek için `flatten()` gibi bir operatörü nasıl kullanacağınızı ve bir operatör uygulamadan önce ve sonra kanal içeriklerini incelemek için `view()` operatörünü nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışının girdi değerlerinin kaynağı olarak bir dosya almasını nasıl sağlayacağınızı öğrenin. + +--- + +## 4. Bir CSV dosyasından girdi değerlerini okuyun + +Gerçekçi olarak, nadiren bir değer dizisinden başlayacağız. +Büyük olasılıkla, işlenmesi gereken verileri içeren bir veya daha fazla dosyamız olacak, bir tür yapılandırılmış formatta. + +`greetings.csv` adlı, gerçek bir veri analizinde işlemek isteyebileceğiniz türden sütunlu verileri taklit eden birkaç girdi selamlaması içeren bir CSV dosyası hazırladık; bu dosya `data/` altında depolanıyor. +(Sayılar anlamlı değil, sadece gösterim amaçlı oradalar.) + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Bir sonraki görevimiz, bu dosyadan değerleri okumak için iş akışımızı uyarlamak. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-pipeline-multi-inputs-csv.svg" +</figure> + +Bunu nasıl gerçekleştirebileceğimizi görelim. + +### 4.1. Betiği selamlamaların kaynağı olarak bir CSV dosyası bekleyecek şekilde değiştirin + +Başlamak için, betikte iki önemli değişiklik yapmamız gerekecek: + +- Girdi parametresini CSV dosyasına işaret edecek şekilde değiştirin +- Kanal fabrikasını bir dosyayı işlemek için tasarlanmış birine değiştirin + +#### 4.1.1. Girdi parametresini CSV dosyasına işaret edecek şekilde değiştirin + +1. Bölümde kurduğumuz `params.input` parametresini hatırlıyor musunuz? + Selamlamalarımızı içeren CSV dosyasına işaret edecek şekilde güncelleyeceğiz. + +Parametre tanımlamasında aşağıdaki düzenlemeyi yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="20" hl_lines="5" + /* + * Pipeline parametreleri + */ + input: String = 'Holà mundo!' + ``` + +Bu, dosyanın iş akışı koduyla aynı konumda olduğunu varsayar. +Diğer veri konumlarıyla nasıl başa çıkacağınızı Nextflow yolculuğunuzda daha sonra öğreneceksiniz. + +#### 4.1.2. Bir dosyayı işlemek için tasarlanmış bir kanal fabrikasına geçin + +Artık girdi olarak basit dizeler yerine bir dosya kullanmak istediğimiz için, önceki `channel.of()` kanal fabrikasını kullanamayız. +Dosya yollarını işlemek için yerleşik işlevselliğe sahip yeni bir kanal fabrikası olan [`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#channel-path) kullanmaya geçmemiz gerekiyor. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "flatten öncesi: $greeting" } + // .flatten() + // .view { greeting -> "flatten sonrası: $greeting" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="4-8" + workflow { + + main: + // bir girdi selamlama dizisi tanımla + greetings_array = ['Hello','Bonjour','Holà'] + // girdiler için bir kanal oluştur + greeting_ch = channel.of(greetings_array) + .view { greeting -> "flatten öncesi: $greeting" } + .flatten() + .view { greeting -> "flatten sonrası: $greeting" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Kanal girdisini `param.input`'a geri döndürdüğümüzü ve artık ihtiyacımız olmayacağı için `greetings_array` tanımlamasını sildiğimizi fark edeceksiniz. +Ayrıca `flatten()` ve ikinci `view()` ifadesini yorum satırı haline getirdik. + +#### 4.1.3. İş akışını çalıştırın + +Yeni kanal fabrikası ve girdi dosyası ile iş akışını çalıştırmayı deneyelim. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Komut çıktısı" + + ```console hl_lines="5 6 9 14" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [peaceful_poisson] DSL2 - revision: a286c08ad5 + + [- ] sayHello [ 0%] 0 of 1 + flatten öncesi: /workspaces/training/hello-nextflow/data/greetings.csv + ERROR ~ Error executing process > 'sayHello (1)' + + Caused by: + File `/workspaces/training/hello-nextflow/data/greetings.csv-output.txt` is outside the scope of the process work directory: /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + + Command executed: + + echo '/workspaces/training/hello-nextflow/data/greetings.csv' > '/workspaces/training/hello-nextflow/data/greetings.csv-output.txt' + + Command exit status: + - + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/30/e610cb4ea5ae8693f456ac3329c92f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Hay aksi, çalışmıyor. Konsol çıktısının ve hata mesajının başlangıcına bakın. +`Command executed:` kısmı burada özellikle faydalı. + +Bu biraz tanıdık görünebilir. +Görünüşe göre Nextflow, dosya yolunun kendisini bir dize değeri olarak kullanarak tek bir süreç çağrısı çalıştırmaya çalıştı. +Dosya yolunu doğru şekilde çözümledi, ancak istediğimiz şey olan içeriğini ayrıştırmadı. + +Nextflow'un dosyayı açmasını ve içeriğini kanala yüklemesini nasıl sağlarız? + +Görünüşe göre başka bir [operatöre](https://www.nextflow.io/docs/latest/reference/operator.html) ihtiyacımız var! + +### 4.2. Dosyayı ayrıştırmak için `splitCsv()` operatörünü kullanın + +Operatör listesine tekrar baktığımızda, CSV formatındaki metni ayrıştırmak ve bölmek için tasarlanmış [`splitCsv()`](https://www.nextflow.io/docs/latest/reference/operator.html#splitCsv) operatörünü buluyoruz. + +#### 4.2.1. `splitCsv()`'yi kanala uygulayın + +Operatörü uygulamak için, daha önce olduğu gibi kanal fabrikası satırına ekliyoruz. + +İş akışı bloğunda, `flatten()` yerine `splitcsv()` (yorum satırından çıkarılmış) koymak için aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .view { csv -> "splitCsv öncesi: $csv" } + .splitCsv() + .view { csv -> "splitCsv sonrası: $csv" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="6-8" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .view { greeting -> "flatten öncesi: $greeting" } + // .flatten() + // .view { greeting -> "flatten sonrası: $greeting" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Gördüğünüz gibi, önce/sonra `view()` ifadelerini de güncelledik. +Teknik olarak aynı değişken adını (`greeting`) kullanabilirdik ama kodu başkaları için daha okunabilir kılmak için daha uygun bir şeye (`csv`) güncelledik. + +#### 4.2.2. İş akışını tekrar çalıştırın + +Eklenen CSV ayrıştırma mantığıyla iş akışını çalıştırmayı deneyelim. + +```bash +nextflow run hello-channels.nf +``` + +??? failure "Komut çıktısı" + + ```console hl_lines="7-11 14 19" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [insane_fermat] DSL2 - revision: 8e62fcbeb1 + + executor > local (3) + [24/76da2f] sayHello (2) [ 0%] 0 of 3 ✘ + splitCsv öncesi: /workspaces/training/hello-nextflow/data/greetings.csv + splitCsv sonrası: [Hello, English, 123] + splitCsv sonrası: [Bonjour, French, 456] + splitCsv sonrası: [Holà, Spanish, 789] + ERROR ~ Error executing process > 'sayHello (2)' + + Caused by: + Missing output file(s) `[Bonjour, French, 456]-output.txt` expected by process `sayHello (2)` + + + Command executed: + + echo '[Bonjour, French, 456]' > '[Bonjour, French, 456]-output.txt' + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/hello-nextflow/work/24/76da2fcc4876b61632749f99e26a50 + + Tip: you can try to figure out what's wrong by changing to the process work dir and showing the script file named `.command.sh` + + -- Check '.nextflow.log' file for details + ``` + +İlginç bir şekilde, bu da başarısız oluyor, ancak farklı bir hatayla. +Bu sefer Nextflow dosyanın içeriğini ayrıştırdı (yaşasın!) ama her satırı bir dizi olarak yükledi ve her dizi kanalda bir öğe. + +Ona her satırdaki yalnızca ilk sütunu almasını söylememiz gerekiyor. +Peki bunu nasıl açarız? + +Daha önce bir kanalın içeriğini açmak için `flatten()` kullandık, ama bu burada işe yaramaz çünkü flatten _her şeyi_ açar (kendiniz görmek isterseniz denemekten çekinmeyin). + +Bunun yerine, Nextflow pipeline'larında gerçekten faydalı olan ve sık sık karşımıza çıkan `map()` adlı başka bir operatör kullanacağız. + +### 4.3. Selamlamaları çıkarmak için `map()` operatörünü kullanın + +[`map()`](https://www.nextflow.io/docs/latest/reference/operator.html#map) operatörü, bir kanalın içeriklerine her türlü eşlemeyi yapmamıza olanak tanıyan çok kullanışlı küçük bir araçtır. + +Bu durumda, veri dosyamızdaki her satırdan istediğimiz o tek öğeyi çıkarmak için kullanacağız. +Sözdizimi şöyle görünüyor: + +```groovy title="Sözdizimi" +.map { row -> row[0] } +``` + +Bu, 'kanaldaki her satır için, içerdiği 0. (birinci) öğeyi al' anlamına gelir. + +Şimdi bunu CSV ayrıştırmamıza uygulayalım. + +#### 4.3.1. `map()`'i kanala uygulayın + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-channels.nf" linenums="27" hl_lines="9 10" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .view { csv -> "splitCsv öncesi: $csv" } + .splitCsv() + .view { csv -> "splitCsv sonrası: $csv" } + .map { item -> item[0] } + .view { csv -> "map sonrası: $csv" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-channels.nf" linenums="27" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .view { csv -> "splitCsv öncesi: $csv" } + .splitCsv() + .view { csv -> "splitCsv sonrası: $csv" } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Operatörün beklediğimizi yaptığını doğrulamak için başka bir `view()` çağrısı eklediğimizi görüyorsunuz. + +#### 4.3.2. İş akışını çalıştırın + +Bunu bir kez daha çalıştıralım: + +```bash +nextflow run hello-channels.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-channels.nf` [focused_volhard] DSL2 - revision: de435e45be + + executor > local (3) + [54/6eebe3] sayHello (3) [100%] 3 of 3 ✔ + splitCsv öncesi: /workspaces/training/hello-nextflow/data/greetings.csv + splitCsv sonrası: [Hello, English, 123] + splitCsv sonrası: [Bonjour, French, 456] + splitCsv sonrası: [Holà, Spanish, 789] + map sonrası: Hello + map sonrası: Bonjour + map sonrası: Holà + ``` + +Bu sefer hatasız çalışmalı. + +`view()` ifadelerinin çıktısına bakarak şunları görüyorsunuz: + +- Tek bir `splitCsv öncesi:` ifadesi: o noktada kanal bir öğe içeriyor, orijinal dosya yolu. +- Üç ayrı `splitCsv sonrası:` ifadesi: her selamlama için bir tane, ama her biri dosyadaki o satıra karşılık gelen bir dizi içinde bulunuyor. +- Üç ayrı `map sonrası:` ifadesi: her selamlama için bir tane, bunlar artık kanalda bireysel öğeler. + +Satırların çıktınızda farklı bir sırada görünebileceğini unutmayın. + +Her selamlamanın doğru şekilde çıkarıldığını ve iş akışı boyunca işlendiğini doğrulamak için çıktı dosyalarına da bakabilirsiniz. + +Daha önce olduğu gibi aynı sonuca ulaştık, ancak şimdi herhangi bir kodu değiştirmeden bir girdi dosyasını değiştirerek işlemek istediğimiz selamlama kanalına daha fazla öğe ekleme konusunda çok daha fazla esnekliğe sahibiz. +Karmaşık girdileri işlemek için daha sofistike yaklaşımları daha sonraki bir eğitimde öğreneceksiniz. + +### Özet + +Bir girdi değerleri dosyasını okumak ve bunları uygun şekilde işlemek için `.fromPath()` kanal yapıcısını ve `splitCsv()` ile `map()` operatörlerini nasıl kullanacağınızı biliyorsunuz. + +Daha genel olarak, Nextflow'un süreçlere girdileri yönetmek için **kanalları** ve içeriklerini dönüştürmek için **operatörleri** nasıl kullandığına dair temel bir anlayışa sahipsiniz. + +### Sırada ne var? + +Büyük bir mola verin, bu bölümde çok çalıştınız! + +Hazır olduğunuzda, daha fazla adım eklemeyi ve bunları düzgün bir iş akışına bağlamayı öğrenmek için [**Bölüm 3: Merhaba İş Akışı**](./03_hello_workflow.md)'na geçin. + +--- + +## Quiz + +<quiz> +Nextflow'da kanal nedir? +- [ ] Bir dosya yolu belirtimi +- [ ] Bir süreç tanımı +- [x] Süreçler arasında veri iletmek için kuyruk benzeri bir yapı +- [ ] Bir yapılandırma ayarı + +Daha fazla bilgi: [1.1. Bir girdi kanalı oluşturun](#11-bir-girdi-kanali-olusturun) +</quiz> + +<quiz> +Bu kod ne çıktı verecek? + +```groovy +channel.of('Hello', 'Bonjour', 'Hola') + .view() +``` + +- [ ] `['Hello', 'Bonjour', 'Hola']` (tek bir liste) +- [x] Her öğe ayrı bir satırda: `Hello`, `Bonjour`, `Hola` +- [ ] Hiçbir şey (kanallar varsayılan olarak yazdırmaz) +- [ ] Bir hata (geçersiz sözdizimi) + +Daha fazla bilgi: [1.1. Bir girdi kanalı oluşturun](#11-bir-girdi-kanali-olusturun) +</quiz> + +<quiz> +Bir kanal birden fazla değer içerdiğinde, Nextflow süreç yürütmesini nasıl işler? +- [ ] Süreç tüm değerlerle bir kez çalışır +- [x] Süreç kanaldaki her değer için bir kez çalışır +- [ ] Süreç yalnızca ilk değerle çalışır +- [ ] Süreç yalnızca son değerle çalışır + +Daha fazla bilgi: [2. İş akışını birden fazla girdi değeri üzerinde çalışacak şekilde değiştirin](#2-is-akisini-birden-fazla-girdi-degeri-uzerinde-calisacak-sekilde-degistirin) +</quiz> + +<quiz> +`flatten()` operatörü ne yapar? +- [ ] Birden fazla kanalı bir araya getirir +- [ ] Kanal öğelerini sıralar +- [x] Dizileri bireysel öğelere açar +- [ ] Yinelenen öğeleri kaldırır + +Daha fazla bilgi: [3.2.1. `flatten()` operatörünü ekleyin](#321-flatten-operatorunu-ekleyin) +</quiz> + +<quiz> +`view()` operatörünün amacı nedir? +- [ ] Kanal içeriklerini filtrelemek +- [ ] Kanal öğelerini dönüştürmek +- [x] Kanal içeriklerini incelemek ve hata ayıklamak +- [ ] Kanal içeriklerini bir dosyaya kaydetmek + +Daha fazla bilgi: [1.4. Kanal içeriklerini incelemek için `view()` kullanın](#14-kanal-iceriklerini-incelemek-icin-view-kullanin) +</quiz> + +<quiz> +`splitCsv()` ne yapar? +- [ ] Kanal içeriklerinden bir CSV dosyası oluşturur +- [ ] Bir dizeyi virgüllerle böler +- [x] Bir CSV dosyasını her satırı temsil eden dizilere ayrıştırır +- [ ] Birden fazla CSV dosyasını birleştirir + +Daha fazla bilgi: [4.2. Dosyayı ayrıştırmak için `splitCsv()` operatörünü kullanın](#42-dosyayi-ayristirmak-icin-splitcsv-operatorunu-kullanin) +</quiz> + +<quiz> +`map()` operatörünün amacı nedir? +- [ ] Bir kanaldan öğeleri filtrelemek +- [ ] Birden fazla kanalı birleştirmek +- [x] Bir kanaldaki her öğeyi dönüştürmek +- [ ] Bir kanaldaki öğeleri saymak + +Daha fazla bilgi: [4.3. Selamlamaları çıkarmak için `map()` operatörünü kullanın](#43-selamlamalari-cikarmak-icin-map-operatorunu-kullanin) +</quiz> + +<quiz> +Birden fazla girdiyi işlerken dinamik çıktı dosya adları kullanmak neden önemlidir? +- [ ] Performansı iyileştirmek için +- [ ] Disk alanını azaltmak için +- [x] Çıktı dosyalarının birbirinin üzerine yazmasını önlemek için +- [ ] Devam etme işlevselliğini etkinleştirmek için + +Daha fazla bilgi: [2.2. Çıktı dosya adlarının benzersiz olmasını sağlayın](#22-cikti-dosya-adlarinin-benzersiz-olmasini-saglayin) +</quiz> diff --git a/docs/tr/docs/hello_nextflow/03_hello_workflow.md b/docs/tr/docs/hello_nextflow/03_hello_workflow.md new file mode 100644 index 0000000000..6b4e9251b8 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/03_hello_workflow.md @@ -0,0 +1,1172 @@ +# Bölüm 3: Hello Workflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesini](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video transkripti [burada](./transcripts/03_hello_workflow.md) mevcuttur. +/// + +Gerçek dünya iş akışlarının çoğu birden fazla adım içerir. +Bu eğitim modülünde, süreçleri çok adımlı bir iş akışında nasıl birbirine bağlayacağınızı öğreneceksiniz. + +Bu, aşağıdakileri başarmanın Nextflow yolunu size öğretecek: + +1. Verilerin bir süreçten diğerine akmasını sağlamak +2. Birden fazla süreç çağrısından gelen çıktıları tek bir süreç çağrısına toplamak +3. Bir sürece birden fazla girdi iletmek +4. Bir süreçten çıkan birden fazla çıktıyı işlemek + +Göstermek için, 1. ve 2. Bölümlerden alan-bağımsız Hello World örneği üzerinde geliştirmeye devam edeceğiz. +Bu sefer, insanların gerçek iş akışlarını nasıl oluşturduğunu daha iyi yansıtmak için iş akışımızda aşağıdaki değişiklikleri yapacağız: + +1. Selamlamayı büyük harfe dönüştüren ikinci bir adım eklemek. +2. Dönüştürülmüş tüm selamlamaları toparlayıp tek bir dosyaya yazan üçüncü bir adım eklemek. +3. Son çıktı dosyasını adlandırmak için bir parametre eklemek ve bunu toplama adımına ikincil bir girdi olarak iletmek. +4. Toplama adımının ayrıca işlenenler hakkında basit bir istatistik raporlamasını sağlamak. + +??? info "Bu bölümden nasıl başlanır" + + Bu kursun bu bölümü, [Hello Nextflow](./index.md) kursunun 1-2. Bölümlerini tamamladığınızı varsayar, ancak o bölümlerde ele alınan temel konulara hakimseniz, özel bir şey yapmadan buradan başlayabilirsiniz. + +--- + +## 0. Isınma: `hello-workflow.nf` dosyasını çalıştırın + +Başlangıç noktası olarak `hello-workflow.nf` iş akışı betiğini kullanacağız. +Bu betik, bu eğitim kursunun 2. Bölümünde üretilen betiğe eşdeğerdir; ancak `view()` ifadelerini kaldırdık ve çıktı hedefini değiştirdik: + +```groovy title="hello-workflow.nf" linenums="37" hl_lines="3" +output { + first_output { + path 'hello_workflow' + mode 'copy' + } +} +``` + +Her şeyin çalıştığından emin olmak için, herhangi bir değişiklik yapmadan önce betiği bir kez çalıştırın: + +```bash +nextflow run hello-workflow.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [admiring_lamarr] DSL2 - revision: 4d4053520d + + executor > local (3) + [b1/5826b5] process > sayHello (2) [100%] 3 of 3 ✔ + ``` + +Daha önce olduğu gibi, çıktı dosyalarını `output` bloğunda belirtilen konumda bulacaksınız. +Bu bölüm için, `results/hello_workflow/` altında. + +??? abstract "Dizin içerikleri" + + ```console + results/hello_workflow + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Bu sizin için çalıştıysa, çok adımlı bir iş akışı oluşturmayı öğrenmeye hazırsınız. + +--- + +## 1. İş akışına ikinci bir adım ekleyin + +Her selamlamayı büyük harfe dönüştürmek için bir adım ekleyeceğiz. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-multistep.svg" +</figure> + +Bu amaçla, üç şey yapmamız gerekiyor: + +- Büyük harf dönüşümü yapmak için kullanacağımız komutu tanımlamak. +- Büyük harf dönüşümü komutunu saran yeni bir süreç yazmak. +- İş akışı bloğunda yeni süreci çağırmak ve `sayHello()` sürecinin çıktısını girdi olarak alacak şekilde ayarlamak. + +### 1.1. Büyük harf dönüşümü komutunu tanımlayın ve terminalde test edin + +Selamlamaları büyük harfe dönüştürmek için, 'metin değiştirme' anlamına gelen `tr` adlı klasik bir UNIX aracını aşağıdaki sözdizimi ile kullanacağız: + +```bash title="Sözdizimi" +tr '[a-z]' '[A-Z]' +``` + +Bu, aksanlı harfleri dikkate almayan çok basit bir metin değiştirme tek satırıdır, bu nedenle örneğin 'Holà' 'HOLà' olacaktır, ancak Nextflow kavramlarını göstermek için yeterince iyi bir iş çıkaracaktır ve önemli olan da budur. + +Test etmek için, `echo 'Hello World'` komutunu çalıştırabilir ve çıktısını `tr` komutuna yönlendirebiliriz: + +```bash +echo 'Hello World' | tr '[a-z]' '[A-Z]' > UPPER-output.txt +``` + +Çıktı, `Hello World` dizesinin büyük harf versiyonunu içeren `UPPER-output.txt` adlı bir metin dosyasıdır. + +??? abstract "Dosya içerikleri" + + ```console title="UPPER-output.txt" + HELLO WORLD + ``` + +Temel olarak iş akışımızla yapmaya çalışacağımız şey budur. + +### 1.2. Büyük harf dönüşümü adımını bir Nextflow süreci olarak yazın + +Aynı bileşenlerin tümünü kullanmak istediğimiz için yeni sürecimizi ilkine göre modelleyebiliriz. + +Aşağıdaki süreç tanımını iş akışı betiğine, ilkinin hemen altına ekleyin: + +```groovy title="hello-workflow.nf" linenums="20" +/* + * Selamlamayı büyük harfe dönüştürmek için bir metin değiştirme aracı kullan + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Bu süreçte, ilk sürecin çıktısı için orijinal olarak yaptığımıza benzer şekilde, ikinci çıktı dosya adını girdi dosya adına dayalı olarak oluşturuyoruz. + +### 1.3. İş akışı bloğuna yeni süreç için bir çağrı ekleyin + +Şimdi Nextflow'a az önce tanımladığımız süreci gerçekten çağırmasını söylememiz gerekiyor. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="44" hl_lines="10-11" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper() + + publish: + first_output = sayHello.out + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="44" + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + ``` + +Bu henüz işlevsel değil çünkü `convertToUpper()` sürecine ne girilmesi gerektiğini belirtmedik. + +### 1.4. İlk sürecin çıktısını ikinci sürece iletin + +Şimdi `sayHello()` sürecinin çıktısını `convertToUpper()` sürecine akıtmamız gerekiyor. + +Kullanışlı bir şekilde, Nextflow bir sürecin çıktısını otomatik olarak `<process>.out` adlı bir kanala paketler. +Dolayısıyla `sayHello` sürecinin çıktısı `sayHello.out` adlı bir kanaldır ve bunu doğrudan `convertToUpper()` çağrısına bağlayabiliriz. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="53" hl_lines="2" + // selamlamayı büyük harfe dönüştür + convertToUpper() + ``` + +Bunun gibi basit bir durum için (bir çıktıdan bir girdiye), iki süreci bağlamak için yapmamız gereken tek şey bu! + +### 1.5. İş akışı çıktı yayınlamasını ayarlayın + +Son olarak, ikinci süreçten gelen sonuçları da yayınlamak için iş akışı çıktılarını güncelleyelim. + +#### 1.5.1. `workflow` bloğunun `publish:` bölümünü güncelleyin + +`workflow` bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="56" hl_lines="3" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="56" + publish: + first_output = sayHello.out + } + ``` + +Mantık daha önce olduğu gibi aynı. + +#### 1.5.2. `output` bloğunu güncelleyin + +`output` bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="61" hl_lines="6-9" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="61" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Yine mantık daha önce olduğu gibi aynı. + +Bu, çıktı ayarlarını her bir çıktı için çok ayrıntılı bir düzeyde kontrol edebileceğinizi gösterir. +Ne olduğunu görmek için süreçlerden birinin yollarını veya yayınlama modunu değiştirmeyi deneyebilirsiniz. + +Tabii ki, bu burada bazı bilgileri tekrar ettiğimiz anlamına gelir; bu, tüm çıktıların konumunu aynı şekilde güncellemek istesek uygunsuz olabilir. +Kursun ilerleyen bölümlerinde, bu ayarları birden fazla çıktı için yapılandırılmış bir şekilde nasıl yapılandıracağınızı öğreneceksiniz. + +### 1.6. İş akışını `-resume` ile çalıştırın + +İş akışının ilk adımını zaten başarıyla çalıştırdığımız için, bunu `-resume` bayrağını kullanarak test edelim. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [high_cantor] DSL2 - revision: d746983511 + + executor > local (3) + [ab/816321] process > sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [e0/ecf81b] process > convertToUpper (3) [100%] 3 of 3 ✔ + ``` + +Konsol çıktısında, az önce eklediğimiz yeni sürece karşılık gelen fazladan bir satır var. + +Çıktıları `output` bloğunda ayarlandığı gibi `results/hello_workflow` dizininde bulacaksınız. + +??? abstract "Dizin içerikleri" + + ```console + results/hello_workflow/ + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Bu kullanışlı! Ancak yine de ikinci sürece yapılan çağrılardan birinin work dizinine bakmaya değer. + +??? abstract "Dizin içerikleri" + + ```console + work/e0/ecf81b4cacc648b9b994218d5b29d7/ + ├── Holà-output.txt -> /workspaces/training/hello-nextflow/work/ab/81632178cd37e9e815959278808819/Holà-output.txt + └── UPPER-Holà-output.txt + ``` + +İki `*-output` dosyası olduğunu fark edin: ilk sürecin çıktısı ve ikincinin çıktısı. + +İlk sürecin çıktısı orada çünkü Nextflow, yürütme için gereken her şeyin aynı alt dizinde olması amacıyla onu oraya **hazırladı (staged)**. + +Ancak, aslında ilk süreç çağrısının alt dizinindeki orijinal dosyaya işaret eden sembolik bir bağlantıdır. +Varsayılan olarak, burada yaptığımız gibi tek bir makinede çalışırken, Nextflow girdi ve ara dosyaları hazırlamak için kopyalar yerine sembolik bağlantılar kullanır. + +Şimdi, devam etmeden önce, yaptığımız tek şeyin `sayHello`'nun çıktısını `convertToUpper`'ın girdisine bağlamak olduğunu ve iki sürecin seri olarak çalıştırılabildiğini düşünün. +Nextflow, bireysel girdi ve çıktı dosyalarını işleme ve bunları iki komut arasında iletme zorlu işini bizim için yaptı. + +Bu, Nextflow kanallarının bu kadar güçlü olmasının nedenlerinden biridir: iş akışı adımlarını birbirine bağlamayla ilgili zahmetli işlerle ilgilenirler. + +### Özet + +Bir adımın çıktısını bir sonraki adıma girdi olarak sağlayarak süreçleri nasıl zincirleme şeklinde bağlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Toplu süreç çağrılarından çıktıları nasıl toplayıp tek bir sürece besleyeceğinizi öğrenin. + +--- + +## 2. Tüm selamlamaları toplamak için üçüncü bir adım ekleyin + +Burada birden fazla selamlamaya yaptığımız gibi, bir kanaldaki öğelerin her birine bir dönüşüm uygulamak için bir süreç kullandığımızda, bazen o sürecin çıktı kanalındaki öğeleri toplamak ve bunları bir tür analiz veya özetleme yapan başka bir sürece beslemek istiyoruz. + +Göstermek için, pipeline'ımıza `convertToUpper` süreci tarafından üretilen tüm büyük harf selamlamaları toplayan ve bunları tek bir dosyaya yazan yeni bir adım ekleyeceğiz. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello-collect.svg" +</figure> + +Sürprizi bozmak istemiyoruz, ama bu çok kullanışlı bir operatör içerecek. + +### 2.1. Toplama komutunu tanımlayın ve terminalde test edin + +İş akışımıza eklemek istediğimiz toplama adımı, birden fazla büyük harfli selamlamayı tek bir dosyada birleştirmek için `cat` komutunu kullanacak. + +Daha önce yaptığımız gibi, beklenen şekilde çalıştığını doğrulamak için komutu terminalde tek başına çalıştıralım. + +Terminalinizde aşağıdakileri çalıştırın: + +```bash +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 +``` + +Çıktı, orijinal selamlamaların büyük harf versiyonlarını içeren `COLLECTED-output.txt` adlı bir metin dosyasıdır. + +??? abstract "Dosya içerikleri" + + ```console title="COLLECTED-output.txt" + HELLO + BONJOUR + HOLà + ``` + +İş akışımızla elde etmek istediğimiz sonuç budur. + +### 2.2. Toplama adımını yapmak için yeni bir süreç oluşturun + +Yeni bir süreç oluşturalım ve buna `collectGreetings()` diyelim. +Daha önce gördüklerimize dayalı olarak yazmaya başlayabiliriz. + +#### 2.2.1. Sürecin 'açık' kısımlarını yazın + +Aşağıdaki süreç tanımını iş akışı betiğine ekleyin: + +```groovy title="hello-workflow.nf" linenums="37" +/* + * Büyük harfli selamlamaları tek bir çıktı dosyasında topla + */ +process collectGreetings { + + input: + ??? + + output: + path "COLLECTED-output.txt" + + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ +} +``` + +Bu, şu ana kadar öğrendiklerinize dayalı olarak güvenle yazabileceğimiz şey. +Ama bu işlevsel değil! +Girdi tanımlarını ve script komutunun ilk yarısını dışarıda bırakıyor çünkü bunları nasıl yazacağımızı çözmemiz gerekiyor. + +#### 2.2.2. `collectGreetings()` için girdileri tanımlayın + +`convertToUpper()` sürecine yapılan tüm çağrılardan selamlamaları toplamamız gerekiyor. +İş akışındaki önceki adımdan ne alabileceğimizi biliyoruz? + +`convertToUpper()` tarafından çıktı olarak verilen kanal, büyük harfli selamlamaları içeren bireysel dosyaların yollarını içerecektir. +Bu bir girdi slotuna eşit; basitlik için buna `input_files` diyelim. + +Süreç bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + path input_files + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="2" + input: + ??? + ``` + +Birden fazla dosya beklememize rağmen `path` önekini kullandığımıza dikkat edin. + +#### 2.2.3. Birleştirme komutunu oluşturun + +İşler burada biraz karmaşık olabilir, çünkü rastgele sayıda girdi dosyasını işleyebilmemiz gerekiyor. +Özellikle, komutu önceden yazamayız, bu nedenle Nextflow'a sürece akan girdilere dayalı olarak çalışma zamanında nasıl oluşturacağını söylememiz gerekiyor. + +Başka bir deyişle, `[file1.txt, file2.txt, file3.txt]` öğesini içeren bir girdi kanalımız varsa, Nextflow'un bunu `cat file1.txt file2.txt file3.txt`'ye dönüştürmesine ihtiyacımız var. + +Neyse ki, script komutunda basitçe `cat ${input_files}` yazarsak Nextflow bunu bizim için yapmaktan mutluluk duyar. + +Süreç bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="54" hl_lines="3" + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="54" + script: + """ + cat ??? > 'COLLECTED-output.txt' + """ + ``` + +Teoride bu, rastgele sayıda girdi dosyasını işlemelidir. + +!!! tip "İpucu" + + Bazı komut satırı araçları, her girdi dosyası için bir argüman (örneğin `-input`) sağlamayı gerektirir. + Bu durumda, komutu oluşturmak için biraz fazladan çalışma yapmamız gerekir. + Bunun bir örneğini [Genomik için Nextflow](../../nf4_science/genomics/) eğitim kursunda görebilirsiniz. + +### 2.3. Toplama adımını iş akışına ekleyin + +Şimdi büyük harf dönüşümü adımının çıktısı üzerinde toplama sürecini çağırmamız yeterli olmalı. + +#### 2.3.1. Süreç çağrılarını bağlayın + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="75" hl_lines="4 5" + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out) + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="75" + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + } + ``` + +Bu, `convertToUpper()`'ın çıktısını `collectGreetings()`'in girdisine bağlar. + +#### 2.3.2. İş akışını `-resume` ile çalıştırın + +Hadi deneyelim. + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Komut çıktısı" + + ```console hl_lines="8" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [mad_gilbert] DSL2 - revision: 6acfd5e28d + + executor > local (3) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [47/50fe4a] collectGreetings (1) | 3 of 3 ✔ + ``` + +Üçüncü adım dahil başarıyla çalışıyor. + +Ancak, son satırdaki `collectGreetings()` için çağrı sayısına bakın. +Yalnızca bir tane bekliyorduk, ama üç tane var. + +Şimdi son çıktı dosyasının içeriğine bakın. + +??? abstract "Dosya içerikleri" + + ```console title="results/COLLECTED-output.txt" + Holà + ``` + +Hay aksi. Toplama adımı her selamlama için ayrı ayrı çalıştırıldı, bu istediğimiz şey DEĞİLDİ. + +Nextflow'a, o üçüncü adımın `convertToUpper()` tarafından çıktı olarak verilen kanaldaki tüm öğeler üzerinde çalışmasını istediğimizi açıkça söylemek için bir şey yapmamız gerekiyor. + +### 2.4. Selamlamaları tek bir girdide toplamak için bir operatör kullanın + +Evet, bir kez daha sorunumuzun cevabı bir operatör. + +Özellikle, uygun bir şekilde adlandırılmış [`collect()`](https://www.nextflow.io/docs/latest/reference/operator.html#collect) operatörünü kullanacağız. + +#### 2.4.1. `collect()` operatörünü ekleyin + +Bu sefer biraz farklı görünecek çünkü operatörü bir kanal fabrikası bağlamında eklemiyoruz; bir çıktı kanalına ekliyoruz. + +`convertToUpper.out`'u alıp `collect()` operatörünü ekliyoruz, bu bize `convertToUpper.out.collect()` veriyor. +Bunu doğrudan `collectGreetings()` süreç çağrısına bağlayabiliriz. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="2" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out) + } + ``` + +#### 2.4.2. Bazı `view()` ifadeleri ekleyin + +Kanal içeriklerinin önceki ve sonraki durumlarını görselleştirmek için birkaç `view()` ifadesi de ekleyelim. + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + + // isteğe bağlı view ifadeleri + convertToUpper.out.view { contents -> "collect öncesi: $contents" } + convertToUpper.out.collect().view { contents -> "collect sonrası: $contents" } + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="73" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + } + ``` + +`view()` ifadeleri istediğiniz yere konabilir; okunabilirlik için çağrının hemen arkasına koyduk. + +#### 2.4.3. İş akışını `-resume` ile tekrar çalıştırın + +Hadi deneyelim: + +```bash +nextflow run hello-workflow.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + 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 ✔ + collect öncesi: /workspaces/training/hello-nextflow/work/b3/d52708edba8b864024589285cb3445/UPPER-Bonjour-output.txt + collect öncesi: /workspaces/training/hello-nextflow/work/99/79394f549e3040dfc2440f69ede1fc/UPPER-Hello-output.txt + collect öncesi: /workspaces/training/hello-nextflow/work/aa/56bfe7cf00239dc5badc1d04b60ac4/UPPER-Holà-output.txt + collect sonrası: [/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] + ``` + +Başarıyla çalışıyor, ancak log çıktısı bundan biraz daha dağınık görünebilir (okunabilirlik için temizledik). + +Bu sefer üçüncü adım yalnızca bir kez çağrıldı! + +`view()` ifadelerinin çıktısına bakarak şunları görüyoruz: + +- Her selamlama için bir tane olmak üzere üç `collect öncesi:` ifadesi: o noktada dosya yolları kanalda bireysel öğeler. +- Tek bir `collect sonrası:` ifadesi: üç dosya yolu artık tek bir öğe içinde paketlenmiş. + +Son çıktı dosyasının içeriğine bakın. + +??? abstract "Dosya içerikleri" + + ```console title="results/COLLECTED-output.txt" + BONJOUR + HELLO + HOLà + ``` + +Bu sefer son çıktı dosyasında üç selamlamamızın hepsi var. Başarılı! + +!!! note "Not" + + Bunu `-resume` olmadan birkaç kez çalıştırırsanız, selamlamaların sırasının bir çalışmadan diğerine değiştiğini göreceksiniz. + Bu, öğelerin süreç çağrılarından geçme sırasının tutarlı olmasının garanti edilmediğini gösterir. + +#### 2.4.4. Okunabilirlik için `view()` ifadelerini kaldırın + +Bir sonraki bölüme geçmeden önce, konsol çıktısını karmaşıklaştırmamak için `view()` ifadelerini silmenizi öneririz. + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="73" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="73" hl_lines="4-6" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + + // isteğe bağlı view ifadeleri + convertToUpper.out.view { contents -> "collect öncesi: $contents" } + convertToUpper.out.collect().view { contents -> "collect sonrası: $contents" } + ``` + +Bu temelde 2.4.2 noktasının ters işlemidir. + +### Özet + +Toplu süreç çağrılarından çıktıları nasıl toplayıp ortak bir analiz veya özetleme adımına besleyeceğinizi biliyorsunuz. + +### Sırada ne var? + +Bir sürece birden fazla girdiyi nasıl ileteceğinizi öğrenin. + +--- + +## 3. Bir sürece birden fazla girdi iletin + +Önceki sonuçların üzerine yazmadan sonraki selamlama gruplarını işleyebilmek için son çıktı dosyasına belirli bir ad verebilmek istiyoruz. + +Bu amaçla, iş akışında aşağıdaki iyileştirmeleri yapacağız: + +- Toplayıcı süreci, çıktı dosyası için kullanıcı tanımlı bir ad kabul edecek şekilde değiştirmek +- İş akışına bir komut satırı parametresi eklemek ve bunu toplayıcı sürece iletmek + +### 3.1. Toplayıcı sürecini değiştirin + +Ek girdiyi tanımlamamız ve çıktı dosya adına entegre etmemiz gerekecek. + +#### 3.1.1. Ek girdiyi tanımlayın + +İyi haber: süreç tanımında istediğimiz kadar girdi değişkeni tanımlayabiliriz. +Buna `batch_name` diyelim. + +Süreç bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="42" hl_lines="3" + input: + path input_files + val batch_name + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="42" + input: + path input_files + ``` + +Süreçlerinizi istediğiniz kadar girdi bekleyecek şekilde ayarlayabilirsiniz. +Şu anda bunların hepsi zorunlu girdiler olarak ayarlanmış; iş akışının çalışması için bir değer sağlamalısınız. + +Zorunlu ve isteğe bağlı girdileri nasıl yöneteceğinizi Nextflow yolculuğunuzda daha sonra öğreneceksiniz. + +#### 3.1.2. `batch_name` değişkenini çıktı dosya adında kullanın + +Değişkeni, daha önce dinamik dosya adları oluşturduğumuz şekilde çıktı dosya adına ekleyebiliriz. + +Süreç bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-${batch_name}-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 6" + output: + path "COLLECTED-output.txt" + + script: + """ + cat ${input_files} > 'COLLECTED-output.txt' + """ + ``` + +Bu, süreci iş akışının son çıktısı için belirli bir dosya adı oluşturmak üzere `batch_name` değerini kullanacak şekilde ayarlar. + +### 3.2. Bir `batch` komut satırı parametresi ekleyin + +Şimdi `batch_name` için değer sağlamanın ve bunu süreç çağrısına beslemenin bir yoluna ihtiyacımız var. + +#### 3.2.1. Parametreyi ayarlamak için `params` kullanın + +CLI parametrelerini tanımlamak için `params` sistemini nasıl kullanacağınızı zaten biliyorsunuz. +Hadi bunu bir `batch` parametresi tanımlamak için kullanalım (tembel olduğumuz için varsayılan bir değerle). + +Pipeline parametreleri bölümünde, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="6" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="55" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + } + ``` + +`--input` için gösterdiğimiz gibi, komut satırında `--batch` ile bir değer belirterek bu varsayılan değeri geçersiz kılabilirsiniz. + +#### 3.2.2. `batch` parametresini sürece iletin + +Parametrenin değerini sürece sağlamak için, süreç çağrısına eklememiz gerekiyor. + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="74" hl_lines="2" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect()) + ``` + +Bir sürece birden fazla girdi sağlamak için, bunları çağrı parantezlerinde virgülle ayırarak listelemeniz yeterli. + +!!! warning "Uyarı" + + Girdileri sürece, sürecin girdi tanım bloğunda listelendikleri AYNI SIRADA sağlamalısınız. + +### 3.3. İş akışını çalıştırın + +Bunu komut satırında bir grup adıyla çalıştırmayı deneyelim. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [confident_rutherford] DSL2 - revision: bc58af409c + + executor > local (1) + [79/33b2f0] sayHello (2) | 3 of 3, cached: 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [b5/f19efe] collectGreetings | 1 of 1 ✔ + ``` + +Başarıyla çalışıyor ve istenen çıktıyı üretiyor: + +??? abstract "Dosya içerikleri" + + ```console title="results/COLLECTED-trio-output.txt" + HELLO + BONJOUR + HOLà + ``` + +Artık parametreyi uygun şekilde belirttiğimiz sürece, diğer girdi grupları üzerindeki sonraki çalıştırmalar önceki sonuçları bozmayacak. + +### Özet + +Bir sürece birden fazla girdi nasıl ileteceğinizi biliyorsunuz. + +### Sırada ne var? + +Birden fazla çıktıyı nasıl yayınlayıp uygun şekilde işleyeceğinizi öğrenin. + +--- + +## 4. Toplayıcı adıma bir çıktı ekleyin + +Şimdiye kadar her biri yalnızca bir çıktı üreten süreçler kullandık. +İlgili çıktılarına `<process>.out` sözdizimini kullanarak çok rahat bir şekilde erişebildik; bunu hem bir çıktıyı sonraki sürece iletme bağlamında (örn. `convertToUpper(sayHello.out)`) hem de `publish:` bölümü bağlamında (örn. `first_output = sayHello.out`) kullandık. + +Bir süreç birden fazla çıktı ürettiğinde ne olur? +Birden fazla çıktıyı nasıl işleriz? +Belirli bir çıktıyı seçip kullanabilir miyiz? + +Hepsi mükemmel sorular ve kısa cevap evet, yapabiliriz! + +Birden fazla çıktı ayrı kanallara paketlenecektir. +Bu çıktı kanallarına isimler vermeyi seçebiliriz, bu da daha sonra bunlara bireysel olarak atıfta bulunmayı kolaylaştırır, veya bunlara indeks ile atıfta bulunabiliriz. + +Bir örnekle inceleyelim. + +Gösterim amaçlı olarak, belirli bir girdi grubu için toplanan selamlama sayısını saymak ve bunu bir dosyada raporlamak istediğimizi varsayalım. + +### 4.1. Süreci selamlama sayısını sayacak ve çıktı olarak verecek şekilde değiştirin + +Bu, süreç tanımında iki temel değişiklik gerektirecektir: selamlamaları saymanın ve bir rapor dosyası yazmanın bir yoluna ihtiyacımız var, sonra bu rapor dosyasını sürecin `output` bloğuna eklememiz gerekiyor. + +#### 4.1.1. Toplanan selamlama sayısını sayın + +Kullanışlı bir şekilde, Nextflow süreç tanımının `script:` bloğuna rastgele kod eklememize izin verir, bu da böyle şeyler yapmak için gerçekten kullanışlıdır. + +Bu, `input_files` dizisindeki dosya sayısını almak için Nextflow'un yerleşik `size()` fonksiyonunu kullanabileceğimiz ve sonucu bir `echo` komutuyla dosyaya yazabileceğimiz anlamına gelir. + +`collectGreetings` süreç bloğunda, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="55" hl_lines="2 5" + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'Bu grupta ${count_greetings} selamlama vardı.' > '${batch_name}-report.txt' + """ + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="55" + script: + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + """ + ``` + +`count_greetings` değişkeni çalışma zamanında hesaplanacaktır. + +#### 4.1.2. Rapor dosyasını yayınlayın ve çıktıları adlandırın + +Prensipte yapmamız gereken tek şey rapor dosyasını `output:` bloğuna eklemek. + +Ancak, bu arada, çıktı tanımlarımıza bazı `emit:` etiketleri de ekleyeceğiz. Bunlar, konumsal indeksler kullanmak yerine çıktıları ada göre seçmemizi sağlayacak. + +Süreç bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="46" hl_lines="2 3" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt" + ``` + +`emit:` etiketleri isteğe bağlıdır ve çıktılardan yalnızca birine bir etiket ekleyebilirdik. +Ama deyişte olduğu gibi, neden ikisi de olmasın? + +!!! tip "İpucu" + + Bir sürecin çıktılarını `emit:` kullanarak adlandırmazsanız, bunlara yine de ilgili (sıfır tabanlı) indekslerini kullanarak ayrı ayrı erişebilirsiniz. + Örneğin, ilk çıktıyı almak için `<process>.out[0]`, ikinci çıktıyı almak için `<process>.out[1]` ve benzeri şekillerde kullanırsınız. + + Çıktıları adlandırmayı tercih ediyoruz çünkü aksi takdirde, özellikle süreç çok sayıda çıktı ürettiğinde, yanlışlıkla yanlış indeksi almak çok kolay. + +### 4.2. İş akışı çıktılarını güncelleyin + +Şimdi `collectGreetings` sürecinden iki çıktı geldiğine göre, `collectGreetings.out` çıktısı iki kanal içeriyor: + +- `collectGreetings.out.outfile` son çıktı dosyasını içerir +- `collectGreetings.out.report` rapor dosyasını içerir + +İş akışı çıktılarını buna göre güncellememiz gerekiyor. + +#### 4.2.1. `publish:` bölümünü güncelleyin + +`workflow` bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="80" hl_lines="4" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out + ``` + +Gördüğünüz gibi, belirli süreç çıktılarına atıfta bulunmak artık önemsiz. +Bölüm 5'te (Konteynerler) pipeline'ımıza bir adım daha eklediğimizde, `collectGreetings.out.outfile`'a kolayca atıfta bulunabilecek ve yeni sürece verebileceğiz (spoiler: yeni sürecin adı `cowpy`). + +Ama şimdilik, iş akışı düzeyindeki çıktıları güncellemeyi bitirelim. + +#### 4.2.2. `output` bloğunu güncelleyin + +`output` bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-workflow.nf" linenums="86" hl_lines="14-17" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + batch_report { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-workflow.nf" linenums="80" + output { + first_output { + path 'hello_workflow' + mode 'copy' + } + uppercased { + path 'hello_workflow' + mode 'copy' + } + collected { + path 'hello_workflow' + mode 'copy' + } + } + ``` + +Bu ad değişmediği için `collected` çıktı tanımını güncellememize gerek yok. +Sadece yeni çıktıyı eklememiz gerekiyor. + +### 4.3. İş akışını çalıştırın + +Bunu mevcut selamlama grubuyla çalıştırmayı deneyelim. + +```bash +nextflow run hello-workflow.nf -resume --batch trio +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-workflow.nf` [ecstatic_wilson] DSL2 - revision: c80285f8c8 + + executor > local (1) + [c5/4c6ca9] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [0e/6cbc59] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [02/61ead2] collectGreetings [100%] 1 of 1 ✔ + ``` + +`results/hello_workflow/` dizinine bakarsanız, yeni rapor dosyasını, `trio-report.txt`'yi bulacaksınız. +İş akışının işlenen selamlama sayısını doğru bir şekilde raporladığını doğrulamak için açın. + +??? abstract "Dosya içerikleri" + + ```txt title="trio-report.txt" + Bu grupta 3 selamlama vardı. + ``` + +CSV'ye daha fazla selamlama eklemekten ve ne olduğunu test etmekten çekinmeyin. + +### Özet + +Bir sürecin birden fazla adlandırılmış çıktı yayınlamasını nasıl sağlayacağınızı ve bunları iş akışı düzeyinde uygun şekilde nasıl işleyeceğinizi biliyorsunuz. + +Daha genel olarak, süreçleri yaygın yollarla birbirine bağlamayla ilgili temel ilkeleri anlıyorsunuz. + +### Sırada ne var? + +Ekstra uzun bir mola verin, bunu hak ettiniz. + +Hazır olduğunuzda, kodunuzu daha iyi sürdürülebilirlik ve kod verimliliği için nasıl modülerleştireceğinizi öğrenmek için [**Bölüm 4: Merhaba Modüller**](./04_hello_modules.md)'e geçin. + +--- + +## Quiz + +<quiz> +İş akışı bloğunda bir sürecin çıktısına nasıl erişirsiniz? +- [ ] `process.output` +- [ ] `output.processName` +- [x] `processName.out` +- [ ] `get(processName)` + +Daha fazla bilgi: [1.4. İlk sürecin çıktısını ikinci sürece iletin](#14-ilk-surecin-ciktisini-ikinci-surece-iletin) +</quiz> + +<quiz> +Nextflow'da süreç yürütme sırasını ne belirler? +- [ ] Süreçlerin iş akışı bloğunda yazıldıkları sıra +- [ ] Süreç adına göre alfabetik sıra +- [x] Süreçler arasındaki veri bağımlılıkları +- [ ] Paralel yürütme için rastgele sıra + +Daha fazla bilgi: [1.4. İlk sürecin çıktısını ikinci sürece iletin](#14-ilk-surecin-ciktisini-ikinci-surece-iletin) +</quiz> + +<quiz> +Aşağı akış süreci için tüm çıktıları tek bir listede toplamak için `???` yerine hangi operatör gelmelidir? + +```groovy hl_lines="4" +workflow { + greetings_ch = Channel.of('Hello', 'Bonjour', 'Hola') + SAYHELLO(greetings_ch) + GATHER_ALL(SAYHELLO.out.???) +} +``` + +- [ ] `flatten()` +- [x] `collect()` +- [ ] `mix()` +- [ ] `join()` + +Daha fazla bilgi: [2.4. Selamlamaları tek bir girdide toplamak için bir operatör kullanın](#24-selamlamalari-tek-bir-girdide-toplamak-icin-bir-operator-kullanin) +</quiz> + +<quiz> +`collect()` operatörünü ne zaman kullanmalısınız? +- [ ] Öğeleri paralel olarak işlemek istediğinizde +- [ ] Kanal içeriklerini filtrelemeniz gerektiğinde +- [x] Aşağı akış sürecinin yukarı akış sürecinden tüm öğelere ihtiyacı olduğunda +- [ ] Verileri birden fazla sürece bölmek istediğinizde + +Daha fazla bilgi: [2.4. Selamlamaları tek bir girdide toplamak için bir operatör kullanın](#24-selamlamalari-tek-bir-girdide-toplamak-icin-bir-operator-kullanin) +</quiz> + +<quiz> +Bir süreçten adlandırılmış bir çıktıya nasıl erişirsiniz? +- [ ] `processName.outputName` +- [ ] `processName.get(outputName)` +- [x] `processName.out.outputName` +- [ ] `output.processName.outputName` + +Daha fazla bilgi: [4.1.2. Rapor dosyasını yayınlayın ve çıktıları adlandırın](#412-rapor-dosyasini-yayinlayin-ve-ciktilari-adlandirin) +</quiz> + +<quiz> +Bir süreçte çıktıyı adlandırmak için doğru sözdizimi nedir? +- [ ] `name: outputName` +- [ ] `output: outputName` +- [x] `emit: outputName` +- [ ] `label: outputName` + +Daha fazla bilgi: [4.1.2. Rapor dosyasını yayınlayın ve çıktıları adlandırın](#412-rapor-dosyasini-yayinlayin-ve-ciktilari-adlandirin) +</quiz> + +<quiz> +Bir sürece birden fazla girdi sağlarken ne doğru olmalıdır? +- [ ] Tüm girdiler aynı türde olmalıdır +- [ ] Girdiler alfabetik sırada sağlanmalıdır +- [x] Girdilerin sırası girdi bloğunda tanımlanan sırayla eşleşmelidir +- [ ] Aynı anda yalnızca iki girdi sağlanabilir + +Daha fazla bilgi: [3. Bir sürece birden fazla girdi iletin](#3-bir-surece-birden-fazla-girdi-iletin) +</quiz> diff --git a/docs/tr/docs/hello_nextflow/04_hello_modules.md b/docs/tr/docs/hello_nextflow/04_hello_modules.md new file mode 100644 index 0000000000..7bce192048 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/04_hello_modules.md @@ -0,0 +1,512 @@ +# Bölüm 4: Hello Modules + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesini](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video transkripti [burada](./transcripts/04_hello_modules.md) mevcuttur. +/// + +Bu bölüm, pipeline'ınızın geliştirilmesini ve bakımını daha verimli ve sürdürülebilir hale getirmek için iş akışı kodunuzu nasıl organize edeceğinizi kapsar. +Özellikle, **modülleri** nasıl kullanacağınızı göstereceğiz. + +Nextflow'da bir **modül**, bağımsız bir kod dosyasında kendi başına kapsüllenmiş tek bir süreç tanımıdır. +Bir iş akışında bir modül kullanmak için, iş akışı kod dosyanıza tek satırlık bir import ifadesi eklemeniz yeterlidir; ardından süreci normalde yaptığınız gibi iş akışına entegre edebilirsiniz. +Bu, kodun birden fazla kopyasını üretmeden süreç tanımlarını birden fazla iş akışında yeniden kullanmayı mümkün kılar. + +İş akışımızı geliştirmeye başladığımızda, her şeyi tek bir kod dosyasına yazdık. +Şimdi süreçleri bireysel modüllere taşıyacağız. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/modules.svg" +</figure> + +Bu, kodumuzu daha paylaşılabilir, esnek ve bakımı kolay hale getirecek. + +??? info "Bu bölümden nasıl başlanır" + + Bu kursun bu bölümü, [Hello Nextflow](./index.md) kursunun 1-3. Bölümlerini tamamladığınızı varsayar, ancak o bölümlerde ele alınan temel konulara hakimseniz, özel bir şey yapmadan buradan başlayabilirsiniz. + +--- + +## 0. Isınma: `hello-modules.nf` dosyasını çalıştırın + +Başlangıç noktası olarak `hello-modules.nf` iş akışı betiğini kullanacağız. +Bu betik, bu eğitim kursunun 3. Bölümünde üretilen betiğe eşdeğerdir; ancak çıktı hedeflerini değiştirdik: + +```groovy title="hello-modules.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_modules' + mode 'copy' + } + uppercased { + path 'hello_modules' + mode 'copy' + } + collected { + path 'hello_modules' + mode 'copy' + } + batch_report { + path 'hello_modules' + mode 'copy' + } +} +``` + +Her şeyin çalıştığından emin olmak için, herhangi bir değişiklik yapmadan önce betiği bir kez çalıştırın: + +```bash +nextflow run hello-modules.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [hopeful_avogadro] DSL2 - revision: b09af1237d + + executor > local (7) + [0f/8795c9] sayHello (3) [100%] 3 of 3 ✔ + [6a/eb2510] convertToUpper (3) [100%] 3 of 3 ✔ + [af/479117] collectGreetings [100%] 1 of 1 ✔ + ``` + +Daha önce olduğu gibi, çıktı dosyalarını `output` bloğunda belirtilen dizinde bulacaksınız (burada, `results/hello_modules/`). + +??? abstract "Dizin içerikleri" + + ```console + results/hello_modules/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Bu sizin için çalıştıysa, iş akışı kodunuzu modülerleştirmeyi öğrenmeye hazırsınız. + +--- + +## 1. Modülleri depolamak için bir dizin oluşturun + +Modüllerinizi belirli bir dizinde saklamak en iyi pratiktir. +Bu dizine istediğiniz adı verebilirsiniz, ancak konvansiyon `modules/` olarak adlandırmaktır. + +```bash +mkdir modules +``` + +!!! tip "İpucu" + + Burada size **yerel modülleri** nasıl kullanacağınızı gösteriyoruz, yani uzak modüllerin aksine iş akışı kodunun geri kalanıyla aynı depoda yerel olarak depolanan modüller; uzak modüller diğer (uzak) depolarda saklanır. + **Uzak modüller** hakkında daha fazla bilgi için [dokümantasyona](https://www.nextflow.io/docs/latest/module.html) bakın. + +--- + +## 2. `sayHello()` için bir modül oluşturun + +En basit haliyle, mevcut bir süreci modüle dönüştürmek bir kopyala-yapıştır işleminden biraz fazlasıdır. +Modül için bir dosya taslağı oluşturacağız, ilgili kodu kopyalayacağız ve ardından ana iş akışı dosyasından sileceğiz. + +Sonra tek yapmamız gereken, Nextflow'un çalışma zamanında ilgili kodu çekmesini bilmesi için bir import ifadesi eklemek. + +### 2.1. Yeni modül için bir dosya taslağı oluşturun + +`sayHello.nf` adlı modül için boş bir dosya oluşturalım. + +```bash +touch modules/sayHello.nf +``` + +Bu bize süreç kodunu koyacağımız bir yer verir. + +### 2.2. `sayHello` süreç kodunu modül dosyasına taşıyın + +Tüm süreç tanımını iş akışı dosyasından modül dosyasına kopyalayın, `#!/usr/bin/env nextflow` shebang'ını da kopyaladığınızdan emin olun. + +```groovy title="modules/sayHello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Bu yapıldıktan sonra, süreç tanımını iş akışı dosyasından silin, ancak shebang'ı yerinde bıraktığınızdan emin olun. + +### 2.3. İş akışı bloğundan önce bir import tanımı ekleyin + +Yerel bir modülü içe aktarma sözdizimi oldukça basittir: + +```groovy title="Sözdizimi: Import tanımı" +include { <MODÜL_ADI> } from '<modül_yolu>' +``` + +Bunu `params` bloğunun üstüne ekleyelim ve uygun şekilde dolduralım. + +=== "Sonra" + + ```groovy title="hello-modules.nf" linenums="44" hl_lines="1 2" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Önce" + + ```groovy title="hello-modules.nf" linenums="44" + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Modül adını, `sayHello`, ve modül kodunu içeren dosyanın yolunu, `./modules/sayHello.nf`, doldurduğumuzu görüyorsunuz. + +### 2.4. İş akışını çalıştırın + +İş akışını temelde daha önce olduğu gibi aynı kod ve girdilerle çalıştırıyoruz, bu yüzden `-resume` bayrağıyla çalıştıralım ve ne olduğunu görelim. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [romantic_poisson] DSL2 - revision: 96edfa9ad3 + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Her şey önbelleklendiği için bu çok hızlı çalışmalıdır. +Yayınlanan çıktıları kontrol etmekten çekinmeyin. + +Nextflow, kod birden fazla dosyaya bölünmüş olsa bile yapılması gereken işin hâlâ aynı olduğunu fark etti. + +### Özet + +Bir süreci yerel bir modüle nasıl çıkaracağınızı biliyorsunuz ve bunun iş akışının devam ettirilebilirliğini bozmadığını biliyorsunuz. + +### Sırada ne var? + +Daha fazla modül yapmayı pratik edin. +Bir tane yaptıktan sonra, bir milyon tane daha yapabilirsiniz... +Ama şimdilik sadece iki tane daha yapalım. + +--- + +## 3. `convertToUpper()` sürecini modülerleştirin + +### 3.1. Yeni modül için bir dosya taslağı oluşturun + +`convertToUpper.nf` adlı modül için boş bir dosya oluşturun. + +```bash +touch modules/convertToUpper.nf +``` + +### 3.2. `convertToUpper` süreç kodunu modül dosyasına taşıyın + +Tüm süreç tanımını iş akışı dosyasından modül dosyasına kopyalayın, `#!/usr/bin/env nextflow` shebang'ını da kopyaladığınızdan emin olun. + +```groovy title="modules/convertToUpper.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Selamlamayı büyük harfe dönüştürmek için bir metin değiştirme aracı kullan + */ +process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ +} +``` + +Bu yapıldıktan sonra, süreç tanımını iş akışı dosyasından silin, ancak shebang'ı yerinde bıraktığınızdan emin olun. + +### 3.3. `params` bloğundan önce bir import tanımı ekleyin + +Import tanımını `params` bloğunun üstüne ekleyin ve uygun şekilde doldurun. + +=== "Sonra" + + ```groovy title="hello-modules.nf" linenums="23" hl_lines="3" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Önce" + + ```groovy title="hello-modules.nf" linenums="23" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Bu çok tanıdık görünmeye başlamalı. + +### 3.4. İş akışını tekrar çalıştırın + +Bunu `-resume` bayrağıyla çalıştırın. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [nauseous_heisenberg] DSL2 - revision: a04a9f2da0 + + [c9/763d42] sayHello (3) | 3 of 3, cached: 3 ✔ + [60/bc6831] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretmelidir. + +İkisi tamam, bir tane daha kaldı! + +--- + +## 4. `collectGreetings()` sürecini modülerleştirin + +### 4.1. Yeni modül için bir dosya taslağı oluşturun + +`collectGreetings.nf` adlı modül için boş bir dosya oluşturun. + +```bash +touch modules/collectGreetings.nf +``` + +### 4.2. `collectGreetings` süreç kodunu modül dosyasına taşıyın + +Tüm süreç tanımını iş akışı dosyasından modül dosyasına kopyalayın, `#!/usr/bin/env nextflow` shebang'ını da kopyaladığınızdan emin olun. + +```groovy title="modules/collectGreetings.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Büyük harfli selamlamaları tek bir çıktı dosyasında topla + */ +process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'Bu grupta ${count_greetings} selamlama vardı.' > '${batch_name}-report.txt' + """ +} +``` + +Bu yapıldıktan sonra, süreç tanımını iş akışı dosyasından silin, ancak shebang'ı yerinde bıraktığınızdan emin olun. + +### 4.3. `params` bloğundan önce bir import tanımı ekleyin + +Import tanımını `params` bloğunun üstüne ekleyin ve uygun şekilde doldurun. + +=== "Sonra" + + ```groovy title="hello-modules.nf" linenums="3" hl_lines="4" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +=== "Önce" + + ```groovy title="hello-modules.nf" linenums="3" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + + /* + * Pipeline parametreleri + */ + params { + greeting: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Sonuncusu! + +### 4.4. İş akışını çalıştırın + +Bunu `-resume` bayrağıyla çalıştırın. + +```bash +nextflow run hello-modules.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-modules.nf` [friendly_coulomb] DSL2 - revision: 7aa2b9bc0f + + [f6/cc0107] sayHello (1) | 3 of 3, cached: 3 ✔ + [3c/4058ba] convertToUpper (2) | 3 of 3, cached: 3 ✔ + [1a/bc5901] collectGreetings | 1 of 1, cached: 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretmelidir. + +### Özet + +Bir iş akışında birden fazla süreci nasıl modülerleştireceğinizi biliyorsunuz. + +Tebrikler, tüm bu işi yaptınız ve pipeline'ın çalışma şeklinde kesinlikle hiçbir şey değişmedi! + +Şakayı bir kenara bırakırsak, artık kodunuz daha modüler ve bu süreçlerden birini çağıran başka bir pipeline yazmaya karar verirseniz, ilgili modülü kullanmak için yalnızca bir kısa import ifadesi yazmanız gerekiyor. +Bu, kodu kopyala-yapıştır yapmaktan daha iyi çünkü daha sonra modülü geliştirmeye karar verirseniz, tüm pipeline'larınız bu iyileştirmeleri miras alacak. + +### Sırada ne var? + +İsterseniz kısa bir mola verin. + +Hazır olduğunuzda, yazılım bağımlılıklarını daha kullanışlı ve tekrarlanabilir bir şekilde yönetmek için konteynerleri nasıl kullanacağınızı öğrenmek için [**Bölüm 5: Merhaba Konteynerler**](./05_hello_containers.md)'e geçin. + +--- + +## Quiz + +<quiz> +Nextflow'da modül nedir? +- [ ] Bir yapılandırma dosyası +- [x] Tek bir süreç tanımı içeren bağımsız bir dosya +- [ ] Bir iş akışı tanımı +- [ ] Bir kanal operatörü + +Daha fazla bilgi: [2. `sayHello()` için bir modül oluşturun](#2-sayhello-icin-bir-modul-olusturun) +</quiz> + +<quiz> +Modül dosyaları için önerilen adlandırma kuralı nedir? +- [ ] `module_processName.nf` +- [ ] `processName_module.nf` +- [x] `processName.nf` +- [ ] `mod_processName.nf` +</quiz> + +<quiz> +Modül dosyaları nerede saklanmalıdır? +- [ ] İş akışıyla aynı dizinde +- [ ] Bir `bin/` dizininde +- [x] Bir `modules/` dizininde +- [ ] Bir `lib/` dizininde + +Daha fazla bilgi: [1. Modülleri depolamak için bir dizin oluşturun](#1-modulleri-depolamak-icin-bir-dizin-olusturun) +</quiz> + +<quiz> +Bir modülü içe aktarmak için doğru sözdizimi nedir? + +- [ ] `#!groovy import { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy require { SAYHELLO } from './modules/sayhello.nf'` +- [x] `#!groovy include { SAYHELLO } from './modules/sayhello.nf'` +- [ ] `#!groovy load { SAYHELLO } from './modules/sayhello.nf'` + +Daha fazla bilgi: [2.3. Bir import tanımı ekleyin](#23-is-akisi-blogundan-once-bir-import-tanimi-ekleyin) +</quiz> + +<quiz> +Modüller kullanıldığında `-resume` işlevselliğine ne olur? +- [ ] Artık çalışmaz +- [ ] Ek yapılandırma gerektirir +- [x] Daha önce olduğu gibi çalışır +- [ ] Yalnızca yerel modüller için çalışır +</quiz> + +<quiz> +Modül kullanmanın faydaları nelerdir? (Uygulanabilen tümünü seçin) +- [x] İş akışları arasında kod yeniden kullanılabilirliği +- [x] Daha kolay bakım +- [x] İş akışı kodunun daha iyi organizasyonu +- [ ] Daha hızlı yürütme hızı +</quiz> diff --git a/docs/tr/docs/hello_nextflow/05_hello_containers.md b/docs/tr/docs/hello_nextflow/05_hello_containers.md new file mode 100644 index 0000000000..1842163bd0 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/05_hello_containers.md @@ -0,0 +1,1162 @@ +# Bölüm 5: Hello Containers + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesini](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video transkripti [burada](./transcripts/05_hello_containers.md) mevcuttur. +/// + +Bu eğitim kursunun 1-4. Bölümlerinde, bazı metinleri işleyebilen, birden fazla girdi varsa yürütmeyi paralelleştirebilen ve sonuçları daha fazla işleme için toplayabilen basit bir iş akışı oluşturmak için Nextflow'un temel yapı taşlarını nasıl kullanacağınızı öğrendiniz. + +Ancak, ortamınızda bulunan temel UNIX araçlarıyla sınırlıydınız. +Gerçek dünya görevleri genellikle varsayılan olarak dahil edilmeyen çeşitli araçlar ve paketler gerektirir. +Tipik olarak, bu araçları yüklemeniz, bağımlılıklarını yönetmeniz ve olası çatışmaları çözmeniz gerekirdi. + +Bunların hepsi çok sıkıcı ve can sıkıcı, bu nedenle size bu sorunu çok daha kullanışlı bir şekilde çözmek için **konteynerleri** nasıl kullanacağınızı göstereceğiz. + +Bir **konteyner**, kod, sistem kütüphaneleri ve ayarlar dahil olmak üzere bir uygulamayı çalıştırmak için gereken her şeyi içeren bir konteyner **imajından** oluşturulan hafif, bağımsız, çalıştırılabilir bir yazılım birimidir. +Tahmin edebileceğiniz gibi, bu pipeline'larınızı daha tekrarlanabilir hale getirmek için çok yardımcı olacak. + +Bunu [Docker](https://www.docker.com/get-started/) kullanarak öğreteceğimizi, ancak Nextflow'un [diğer birçok konteyner teknolojisini](https://www.nextflow.io/docs/latest/container.html#) de desteklediğini unutmayın. + +??? info "Bu bölümden nasıl başlanır" + + Bu kursun bu bölümü, [Hello Nextflow](./index.md) kursunun 1-4. Bölümlerini tamamladığınızı ve eksiksiz çalışan bir pipeline'ınız olduğunu varsayar. + + Kursa bu noktadan başlıyorsanız, `modules` dizinini çözümlerden kopyalamanız gerekecek: + + ```bash + cp -r solutions/4-hello-modules/modules . + ``` + +--- + +## 0. Isınma: `hello-containers.nf` dosyasını çalıştırın + +Başlangıç noktası olarak `hello-containers.nf` iş akışı betiğini kullanacağız. +Bu betik, bu eğitim kursunun 4. Bölümünde üretilen betiğe eşdeğerdir; ancak çıktı hedeflerini değiştirdik: + +```groovy title="hello-containers.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } +} +``` + +Her şeyin çalıştığından emin olmak için, herhangi bir değişiklik yapmadan önce betiği bir kez çalıştırın: + +```bash +nextflow run hello-containers.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [5a/ec1fa1] sayHello (2) [100%] 3 of 3 ✔ + [30/32b5b8] convertToUpper (3) [100%] 3 of 3 ✔ + [d3/be01bc] collectGreetings [100%] 1 of 1 ✔ + + ``` + +Daha önce olduğu gibi, çıktı dosyalarını `output` bloğunda belirtilen dizinde bulacaksınız (`results/hello_containers/`). + +??? abstract "Dizin içerikleri" + + ```console + results/hello_containers/ + ├── Bonjour-output.txt + ├── COLLECTED-batch-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── batch-report.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Bu sizin için çalıştıysa, konteynerleri nasıl kullanacağınızı öğrenmeye hazırsınız. + +--- + +## 1. Bir konteyneri 'manuel olarak' kullanın + +Yapmak istediğimiz şey, iş akışımıza yürütme için bir konteyner kullanacak bir adım eklemek. + +Ancak, önce Nextflow'da kullanmaya başlamadan önce konteynerlerin ne olduğuna dair anlayışınızı sağlamlaştırmak için bazı temel kavramları ve işlemleri gözden geçireceğiz. + +### 1.1. Konteyner imajını çekin + +Bir konteyner kullanmak için, genellikle bir konteyner kayıt defterinden bir konteyner imajı indirir veya _çekersiniz_ ve ardından bir konteyner örneği oluşturmak için konteyner imajını çalıştırırsınız. + +Genel sözdizimi şu şekildedir: + +```bash title="Sözdizimi" +docker pull '<container>' +``` + +`docker pull` kısmı, konteyner sistemine bir depodan konteyner imajı çekme talimatıdır. + +`'<container>'` kısmı, konteyner imajının URI adresidir. + +Örnek olarak, rastgele metin girdilerini eğlenceli bir şekilde görüntülemek için ASCII sanatı üreten `cowsay` adlı bir aracın python uygulaması olan [cowpy](https://github.com/jeffbuttars/cowpy) içeren bir konteyner imajı çekelim. + +```txt title="Örnek" + ________________________ +< Are we having fun yet? > + ------------------------ + \ ___-------___ + \ _-~~ ~~-_ + \ _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) +``` + +Yayınlanmış konteynerleri bulabileceğiniz çeşitli depolar var. +Bu Docker konteyner imajını `cowpy` Conda paketinden oluşturmak için [Seqera Containers](https://seqera.io/containers/) hizmetini kullandık: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Tam çekme komutunu çalıştırın: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Komut çıktısı" + + ```console + 1.1.5--3db457ae1977a273: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + c23bdb422167: Pull complete + e1686ff32a11: Pull complete + Digest: sha256:1ebc0043e8cafa61203bf42d29fd05bd14e7b4298e5e8cf986504c15f5aa4160 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +İmajı daha önce hiç indirmediyseniz, bunun tamamlanması bir dakika sürebilir. +Bittiğinde, konteyner imajının yerel bir kopyasına sahipsiniz. + +### 1.2. `cowpy`'yi tek seferlik bir komut olarak çalıştırmak için konteyneri kullanın + +İnsanların konteynerleri kullanmasının çok yaygın bir yolu, onları doğrudan çalıştırmaktır, _yani_ etkileşimsiz olarak. +Bu, tek seferlik komutları çalıştırmak için harikadır. + +Genel sözdizimi şu şekildedir: + +```bash title="Sözdizimi" +docker run --rm '<container>' [araç komutu] +``` + +`docker run --rm '<container>'` kısmı, konteyner sistemine bir konteyner imajından bir konteyner örneği başlatma ve içinde bir komut yürütme talimatıdır. +`--rm` bayrağı, sisteme komut tamamlandıktan sonra konteyner örneğini kapatmasını söyler. + +`[araç komutu]` sözdizimi, kullandığınız araca ve konteynerin nasıl kurulduğuna bağlıdır. +Sadece `cowpy` ile başlayalım. + +Tam olarak birleştirilmiş konteyner yürütme komutu şöyle görünür; devam edin ve çalıştırın. + +```bash +docker run --rm 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' cowpy +``` + +??? success "Komut çıktısı" + + ```console + ______________________________________________________ + < Cowacter, eyes:default, tongue:False, thoughts:False > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Sistem konteyneri başlattı, `cowpy` komutunu parametreleriyle çalıştırdı, çıktıyı konsola gönderdi ve son olarak konteyner örneğini kapattı. + +### 1.3. `cowpy`'yi etkileşimli olarak çalıştırmak için konteyneri kullanın + +Bir konteyneri etkileşimli olarak da çalıştırabilirsiniz, bu size konteyner içinde bir kabuk istemi verir ve komutla oynamanıza olanak tanır. + +#### 1.3.1. Konteyneri başlatın + +Etkileşimli olarak çalıştırmak için, `docker run` komutuna `-it` eklememiz yeterli. +İsteğe bağlı olarak, komutun sonuna _örn._ `/bin/bash` ekleyerek konteyner içinde kullanmak istediğimiz kabuğu belirtebiliriz. + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +İsteminizin `(base) root@b645838b3314:/tmp#` gibi bir şeye dönüştüğüne dikkat edin, bu artık konteyner içinde olduğunuzu gösterir. + +Bunu doğrulamak için dosya sisteminin kökünden dizin içeriklerini listelemek için `ls /` komutunu çalıştırabilirsiniz: + +```bash +ls / +``` + +??? abstract "Komut çıktısı" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +`tree` yardımcı programı bu konteynerde mevcut olmadığı için burada `ls` kullanıyoruz. +Konteyner içindeki dosya sisteminin ana sisteminizden farklı olduğunu görebilirsiniz. + +Az önce yaptığımızın bir sınırlaması, konteynerin varsayılan olarak ana sistemden tamamen izole olmasıdır. +Bu, açıkça izin vermediğiniz sürece konteynerin ana sistemdeki hiçbir dosyaya erişemeyeceği anlamına gelir. + +Bunu nasıl yapacağınızı bir dakika içinde göstereceğiz. + +#### 1.3.2. İstenen araç komutunu/komutlarını çalıştırın + +Artık konteynerin içinde olduğunuza göre, `cowpy` komutunu doğrudan çalıştırabilir ve ona bazı parametreler verebilirsiniz. +Örneğin, araç dokümantasyonu karakteri ('cowacter') `-c` ile değiştirebileceğimizi söylüyor. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Komut çıktısı" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Şimdi çıktı varsayılan inek yerine Linux pengueni Tux'u gösteriyor, çünkü `-c tux` parametresini belirttik. + +Konteyner içinde olduğunuz için, Docker komutlarıyla uğraşmak zorunda kalmadan girdi parametrelerini değiştirerek `cowpy` komutunu istediğiniz kadar çalıştırabilirsiniz. + +!!! tip "İpucu" + + Farklı bir karakter seçmek için '-c' bayrağını kullanın, şunlar dahil: + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Bu hoş. Daha da hoş olacak şey, `greetings.csv` dosyamızı buna girdi olarak besleyebilmek. +Ancak dosya sistemine erişimimiz olmadığı için yapamayız. + +Bunu düzeltelim. + +#### 1.3.3. Konteynerden çıkın + +Konteynerden çıkmak için, istemde `exit` yazabilir veya ++ctrl+d++ klavye kısayolunu kullanabilirsiniz. + +```bash +exit +``` + +İsteminiz artık konteyneri başlatmadan önceki haline geri dönmüş olmalı. + +#### 1.3.4. Verileri konteynere bağlayın + +Daha önce belirtildiği gibi, konteyner varsayılan olarak ana sistemden izole edilmiştir. + +Konteynerin ana dosya sistemine erişmesine izin vermek için, aşağıdaki sözdizimini kullanarak ana sistemden konteynere bir **hacim (volume)** **bağlayabilirsiniz**: + +```bash title="Sözdizimi" +-v <dış_yol>:<iç_yol> +``` + +Bizim durumumuzda `<dış_yol>` mevcut çalışma dizini olacak, bu yüzden sadece bir nokta (`.`) kullanabiliriz ve `<iç_yol>` uydurduğumuz bir takma addır; buna `/my_project` diyelim (iç yol mutlak olmalıdır). + +Bir hacim bağlamak için, yolları değiştirip hacim bağlama argümanını docker run komutuna şu şekilde ekliyoruz: + +```bash +docker run --rm -it -v .:/my_project 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' /bin/bash +``` + +Bu, mevcut çalışma dizinini konteyner içinde `/my_project` altında erişilebilir olacak bir hacim olarak bağlar. + +`/my_project`'in içeriğini listeleyerek çalıştığını kontrol edebilirsiniz: + +```bash +ls /my_project +``` + +??? success "Komut çıktısı" + + ```console + data hello-config.nf hello-modules.nf hello-world.nf nextflow.config solutions work + hello-channels.nf hello-containers.nf hello-workflow.nf modules results test-params.json + ``` + +Artık `data/` altındaki `greetings.csv` dosyası dahil olmak üzere çalışma dizininin içeriğini konteyner içinden görebilirsiniz. + +Bu, dosya sisteminizin o kısmına erişmek için kullanabileceğiniz konteyner duvarından bir tünel oluşturdu. + +#### 1.3.5. Bağlanmış verileri kullanın + +Artık çalışma dizinini konteynere bağladığımıza göre, `greetings.csv` dosyasının içeriğini görüntülemek için `cowpy` komutunu kullanabiliriz. + +Bunu yapmak için, CSV dosyasının içeriğini `cowpy` komutuna yönlendirmek için `cat /my_project/data/greetings.csv | ` kullanacağız. + +```bash +cat /my_project/data/greetings.csv | cowpy -c turkey +``` + +??? success "Komut çıktısı" + + ```console title="data/greetings.csv" + ____________________ + / Hello,English,123 \ + | Bonjour,French,456 | + \ Holà,Spanish,789 / + -------------------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Bu, örnek selamlamalarımızı söyleyen bir hindi ASCII sanatını üretiyor! +Ancak burada hindi yalnızca selamlamalar yerine tam satırları tekrarlıyor. +Nextflow iş akışımızın daha iyi bir iş çıkaracağını zaten biliyoruz! + +Bu komutla oynamaktan çekinmeyin. +İşiniz bittiğinde, daha önce olduğu gibi konteynerden çıkın: + +```bash +exit +``` + +Normal kabuğunuza geri döneceksiniz. + +### Özet + +Bir konteyneri nasıl çekip tek seferlik veya etkileşimli olarak çalıştıracağınızı biliyorsunuz. Ayrıca verilerinizi konteynerinizin içinden erişilebilir hale getirmeyi biliyorsunuz, bu da sisteminize herhangi bir yazılım yüklemeden ilgilendiğiniz herhangi bir aracı gerçek veriler üzerinde denemenizi sağlar. + +### Sırada ne var? + +Nextflow süreçlerinin yürütülmesi için konteynerleri nasıl kullanacağınızı öğrenin. + +--- + +## 2. Nextflow'da konteynerleri kullanın + +Nextflow, hesaplama ortamınızda yüklü olmayan araçları çalıştırmanıza izin vermek için süreçleri konteynerler içinde çalıştırmak için yerleşik desteğe sahiptir. +Bu, süreçlerinizi çalıştırmak için istediğiniz herhangi bir konteyner imajını kullanabileceğiniz ve Nextflow'un imajı çekme, verileri bağlama ve süreci içinde çalıştırma işlemlerini halledeceği anlamına gelir. + +Bunu göstermek için, geliştirdiğimiz pipeline'a `collectGreetings` adımından sonra bir `cowpy` adımı ekleyeceğiz. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Dalmaya hazırsanız möö deyin! + +### 2.1. Bir `cowpy` modülü yazın + +İlk olarak, `cowpy` süreç modülünü oluşturalım. + +#### 2.1.1. Yeni modül için bir dosya taslağı oluşturun + +`cowpy.nf` adlı modül için boş bir dosya oluşturun. + +```bash +touch modules/cowpy.nf +``` + +Bu bize süreç kodunu koyacağımız bir yer verir. + +#### 2.1.2. `cowpy` süreç kodunu modül dosyasına kopyalayın + +`cowpy` sürecimizi daha önce yazdığımız diğer süreçlere göre modelleyebiliriz. + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy ile ASCII sanatı oluştur +process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + +} +``` + +Süreç, selamlamaları içeren bir `input_file` ve bir `character` değeri bekler. + +Çıktı, `cowpy` aracı tarafından oluşturulan ASCII sanatını içeren yeni bir metin dosyası olacaktır. + +### 2.2. cowpy'yi iş akışına ekleyin + +Şimdi modülü içe aktarmamız ve süreci çağırmamız gerekiyor. + +#### 2.2.1. `cowpy` sürecini `hello-containers.nf`'ye içe aktarın + +Import tanımını workflow bloğunun üstüne ekleyin ve uygun şekilde doldurun. + +=== "Sonra" + + ```groovy title="hello-containers.nf" linenums="3" hl_lines="5" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + ``` + +=== "Önce" + + ```groovy title="hello-containers.nf" linenums="3" + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + ``` + +Artık `cowpy` modülü iş akışında kullanılabilir durumda. + +#### 2.2.2. İş akışına `cowpy` süreci için bir çağrı ekleyin + +`cowpy()` sürecini, hatırlayabileceğiniz gibi iki çıktı üreten `collectGreetings()` sürecinin çıktısına bağlayalım: + +- `collectGreetings.out.outfile` çıktı dosyasını içerir <--_istediğimiz şey_ +- `collectGreetings.out.report` grup başına selamlama sayısını içeren rapor dosyasını içerir + +İş akışı bloğunda, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-containers.nf" linenums="19" hl_lines="12-13" + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Önce" + + ```groovy title="hello-containers.nf" linenums="19" + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + ``` + +Selamlamaları hangi karakterin söylemesini istediğimizi belirtmek için yeni bir CLI parametresi olan `params.character` tanımladığımıza dikkat edin. + +#### 2.2.3. `character` parametresini `params` bloğuna ekleyin + +Bu teknik olarak isteğe bağlıdır ama önerilen bir pratiktir ve bu arada karakter için varsayılan bir değer belirleme fırsatıdır. + +=== "Sonra" + + ```groovy title="hello-containers.nf" linenums="9" hl_lines="7" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +=== "Önce" + + ```groovy title="hello-containers.nf" linenums="9" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + } + ``` + +Artık tembel olabilir ve komut satırlarımızda karakter parametresini yazmayı atlayabiliriz. + +#### 2.2.4. İş akışı çıktılarını güncelleyin + +`cowpy` sürecinin çıktısını yayınlamak için iş akışı çıktılarını güncellememiz gerekiyor. + +##### 2.2.4.1. `publish:` bölümünü güncelleyin + +`workflow bloğunda`, aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="hello-containers.nf" linenums="34" hl_lines="6" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + ``` + +=== "Önce" + + ```groovy title="hello-containers.nf" linenums="34" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + ``` + +`cowpy` süreci yalnızca bir çıktı üretir, bu yüzden `.out` ekleyerek her zamanki şekilde atıfta bulunabiliriz. + +Ama şimdilik, iş akışı düzeyindeki çıktıları güncellemeyi bitirelim. + +##### 2.2.4.2. `output` bloğunu güncelleyin + +Son `cowpy_art` çıktısını `output` bloğuna eklememiz gerekiyor. Bu arada, pipeline'ımız artık tamamlandığı ve hangi çıktıları gerçekten önemsediğimizi bildiğimiz için yayınlama hedeflerini de düzenleyelim. + +`output` bloğunda, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15 18-21" + output { + first_output { + path 'hello_containers/intermediates' + mode 'copy' + } + uppercased { + path 'hello_containers/intermediates' + mode 'copy' + } + collected { + path 'hello_containers/intermediates' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + cowpy_art { + path 'hello_containers' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-containers.nf" linenums="42" hl_lines="3 7 11 15" + output { + first_output { + path 'hello_containers' + mode 'copy' + } + uppercased { + path 'hello_containers' + mode 'copy' + } + collected { + path 'hello_containers' + mode 'copy' + } + batch_report { + path 'hello_containers' + mode 'copy' + } + } + ``` + +Artık yayınlanan çıktılar biraz daha düzenli olacak. + +#### 2.2.5. İş akışını çalıştırın + +Özetlemek gerekirse, hedeflediğimiz şey şu: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Çalışacağını düşünüyor musunuz? + +Temiz bir sayfa açmak için önceki yayınlanmış çıktıları silelim ve iş akışını `-resume` bayrağıyla çalıştıralım. + +```bash +rm -r hello_containers/ +nextflow run hello-containers.nf -resume +``` + +??? failure "Komut çıktısı (netlik için düzenlendi)" + + ```console hl_lines="10 13 20-21 26-27" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [lonely_woese] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [9b/02e776] cowpy [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'cowpy' + + Caused by: + Process `cowpy` terminated with an error exit status (127) + + + Command executed: + + cat COLLECTED-batch-output.txt | cowpy -c "turkey" > cowpy-COLLECTED-batch-output.txt + + Command exit status: + 127 + + Command output: + (empty) + + Command error: + .command.sh: line 2: cowpy: command not found + + Work dir: + /workspaces/training/hello-nextflow/work/9b/02e7761db848f82db3c3e59ff3a9b6 + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ERROR ~ Cannot access first() element from an empty List + + -- Check '.nextflow.log' file for details + ``` + +Hay aksi, bir hata var! +`error exit status (127)` tarafından verilen hata kodu, istediğimiz çalıştırılabilir dosyanın bulunamadığı anlamına gelir. + +Bu mantıklı, çünkü `cowpy` aracını çağırıyoruz ama henüz bir konteyner belirtmedik (tüh). + +### 2.3. `cowpy` sürecini çalıştırmak için bir konteyner kullanın + +Bir konteyner belirtmemiz ve Nextflow'a `cowpy()` süreci için kullanmasını söylememiz gerekiyor. + +#### 2.3.1. `cowpy` için bir konteyner belirtin + +Bu öğreticinin ilk bölümünde doğrudan kullandığımız aynı imajı kullanabiliriz. + +`cowpy.nf` modülünü düzenleyerek süreç tanımına `container` yönergesini şu şekilde ekleyin: + +=== "Sonra" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="3" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +=== "Önce" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +Bu, Nextflow'a _Docker kullanımı etkinleştirilmişse_, süreci yürütmek için burada belirtilen konteyner imajını kullanması gerektiğini söyler. + +#### 2.3.2. `nextflow.config` dosyası aracılığıyla Docker kullanımını etkinleştirin + +_'Docker kullanımı etkinleştirilmişse'_ dediğimize dikkat edin. Varsayılan olarak etkin değildir, bu nedenle Nextflow'a Docker kullanmasına izin verildiğini söylememiz gerekiyor. +Bu amaçla, bu kursun son ve sonuncu bölümünün (Bölüm 6) konusunu biraz önceden ele alacağız; bu bölüm yapılandırmayı kapsar. + +Nextflow'un iş akışı yürütmesini yapılandırmak için sunduğu ana yollardan biri `nextflow.config` dosyası kullanmaktır. +Mevcut dizinde böyle bir dosya bulunduğunda, Nextflow otomatik olarak onu yükler ve içerdiği herhangi bir yapılandırmayı uygular. + +Docker'ı açıkça devre dışı bırakan tek satırlık bir kod içeren bir `nextflow.config` dosyası sağladık: `docker.enabled = false`. + +Şimdi, Docker'ı etkinleştirmek için bunu `true` olarak değiştirelim: + +=== "Sonra" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +=== "Önce" + + ```console title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = false + ``` + +!!! tip "İpucu" + + `-with-docker <container>` parametresini kullanarak Docker yürütmesini komut satırından, çalıştırma bazında etkinleştirmek mümkündür. + Ancak, bu tüm iş akışı için yalnızca bir konteyner belirtmemize izin verirken, az önce gösterdiğimiz yaklaşım süreç başına farklı bir konteyner belirtmemize olanak tanır. + Bu, modülerlik, kod bakımı ve tekrarlanabilirlik için daha iyidir. + +#### 2.3.3. Docker etkinken iş akışını çalıştırın + +İş akışını `-resume` bayrağıyla çalıştırın: + +```bash +nextflow run hello-containers.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-containers.nf` [drunk_perlman] DSL2 - revision: abf1dccf7f + + executor > local (1) + [c9/f5c686] sayHello (3) [100%] 3 of 3, cached: 3 ✔ + [ef/3135a8] convertToUpper (3) [100%] 3 of 3, cached: 3 ✔ + [7f/f435e3] collectGreetings [100%] 1 of 1, cached: 1 ✔ + [98/656c6c] cowpy [100%] 1 of 1 ✔ + ``` + +Bu sefer gerçekten çalışıyor! +Her zamanki gibi iş akışı çıktılarını ilgili results dizininde bulabilirsiniz, ancak bu sefer biraz daha düzgün organize edilmiş; yalnızca rapor ve son çıktı üst düzeyde, tüm ara dosyalar bir alt dizine taşınmış. + +??? abstract "Dizin içerikleri" + + ```console + results/hello_containers/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Son ASCII sanat çıktısı `results/hello_containers/` dizininde, `cowpy-COLLECTED-batch-output.txt` adı altında. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_containers/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +İşte orada, istenildiği gibi selamlamaları söyleyen güzel hindimiz. + +#### 2.3.4. Nextflow'un konteynerleştirilmiş görevi nasıl başlattığını inceleyin + +Bu bölümün son notası olarak, Nextflow'un kaputun altında konteynerlerle nasıl çalıştığı hakkında biraz daha bilgi edinmek için `cowpy` süreç çağrılarından birinin work alt dizinine bakalım. + +`cowpy` süreci için work alt dizininin yolunu bulmak için `nextflow run` komutunuzun çıktısını kontrol edin. +Yukarıda gösterilen çalışmadan aldığımıza bakıldığında, `cowpy` süreci için konsol log satırı `[98/656c6c]` ile başlıyor. +Bu, şu kısaltılmış dizin yoluna karşılık gelir: `work/98/656c6c`. + +Bu dizinde, Nextflow'un pipeline'ı yürütme sürecinde sizin adınıza çalıştırdığı tüm komutları içeren `.command.run` dosyasını bulacaksınız. + +??? abstract "Dosya içerikleri" + + ```console title="work/98/656c6c90cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + + nxf_env() { + echo '============= task environment =============' + env | sort | sed "s/\(.*\)AWS\(.*\)=\(.\{6\}\).*/\1AWS\2=\3xxxxxxxxxxxxx/" + echo '============= task output ==================' + } + + nxf_kill() { + declare -a children + while read P PP;do + children[$PP]+=" $P" + done < <(ps -e -o pid= -o ppid=) + + kill_all() { + [[ $1 != $$ ]] && kill $1 2>/dev/null || true + for i in ${children[$1]:=}; do kill_all $i; done + } + + kill_all $1 + } + + nxf_mktemp() { + local base=${1:-/tmp} + mkdir -p "$base" + if [[ $(uname) = Darwin ]]; then mktemp -d $base/nxf.XXXXXXXXXX + else TMPDIR="$base" mktemp -d -t nxf.XXXXXXXXXX + fi + } + + nxf_fs_copy() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + cp -fRL $source $target/$basedir + } + + nxf_fs_move() { + local source=$1 + local target=$2 + local basedir=$(dirname $1) + mkdir -p $target/$basedir + mv -f $source $target/$basedir + } + + nxf_fs_rsync() { + rsync -rRl $1 $2 + } + + nxf_fs_rclone() { + rclone copyto $1 $2/$1 + } + + nxf_fs_fcp() { + fcp $1 $2/$1 + } + + on_exit() { + local last_err=$? + local exit_status=${nxf_main_ret:=0} + [[ ${exit_status} -eq 0 && ${nxf_unstage_ret:=0} -ne 0 ]] && exit_status=${nxf_unstage_ret:=0} + [[ ${exit_status} -eq 0 && ${last_err} -ne 0 ]] && exit_status=${last_err} + printf -- $exit_status > /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.exitcode + set +u + docker rm $NXF_BOXID &>/dev/null || true + exit $exit_status + } + + on_term() { + set +e + docker stop $NXF_BOXID + } + + nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh + } + + nxf_stage() { + true + # stage input files + rm -f COLLECTED-batch-output.txt + ln -s /workspaces/training/hello-nextflow/work/7f/f435e3f2cf95979b5f3d7647ae6696/COLLECTED-batch-output.txt COLLECTED-batch-output.txt + } + + nxf_unstage_outputs() { + true + } + + nxf_unstage_controls() { + true + } + + nxf_unstage() { + if [[ ${nxf_main_ret:=0} == 0 ]]; then + (set -e -o pipefail; (nxf_unstage_outputs | tee -a .command.out) 3>&1 1>&2 2>&3 | tee -a .command.err) + nxf_unstage_ret=$? + fi + nxf_unstage_controls + } + + nxf_main() { + trap on_exit EXIT + trap on_term TERM INT USR2 + trap '' USR1 + + [[ "${NXF_CHDIR:-}" ]] && cd "$NXF_CHDIR" + export NXF_BOXID="nxf-$(dd bs=18 count=1 if=/dev/urandom 2>/dev/null | base64 | tr +/ 0A | tr -d '\r\n')" + NXF_SCRATCH='' + [[ $NXF_DEBUG > 0 ]] && nxf_env + touch /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.begin + set +u + set -u + [[ $NXF_SCRATCH ]] && cd $NXF_SCRATCH + export NXF_TASK_WORKDIR="$PWD" + nxf_stage + + set +e + (set -o pipefail; (nxf_launch | tee .command.out) 3>&1 1>&2 2>&3 | tee .command.err) & + pid=$! + wait $pid || nxf_main_ret=$? + nxf_unstage + } + + $NXF_ENTRY + + ``` + +Bu dosyada `nxf_launch`'ı ararsanız, şöyle bir şey görmelisiniz: + +```console +nxf_launch() { + docker run -i --cpu-shares 1024 -e "NXF_TASK_WORKDIR" -v /workspaces/training/hello-nextflow/work:/workspaces/training/hello-nextflow/work -w "$NXF_TASK_WORKDIR" --name $NXF_BOXID community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 /bin/bash -ue /workspaces/training/hello-nextflow/work/98/656c6c90cce1667c094d880f4b6dcc/.command.sh +} +``` + +Gördüğünüz gibi, Nextflow süreç çağrısını başlatmak için `docker run` komutunu kullanıyor. +Ayrıca ilgili work alt dizinini konteynere bağlıyor, konteyner içindeki çalışma dizinini buna göre ayarlıyor ve `.command.sh` dosyasındaki şablonlu bash betiğimizi çalıştırıyor. + +İlk bölümde manuel olarak yapmak zorunda kaldığımız tüm zor işler mi? Nextflow bunları perde arkasında bizim için yapıyor! + +```txt + _______________________ +< Hurray for robots...! > + ----------------------- + ,-----. + | | + ,--| |-. + __,----| | | | + ,;:: | `_____' | + `._______| i^i | + `----| |---'| . + ,-------._| |== ||// + | |_|P`. /'/ + `-------' 'Y Y/'/' + .==\ /_\ + ^__^ / /'| `i + (oo)\_______ /' / | | + (__)\ )\/\ /' / | `i + ||----w | ___,;`----'.___L_,-'`\__ + || || i_____;----\.____i""\____\ +``` + +### Özet + +Nextflow'da süreçleri çalıştırmak için konteynerleri nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +Bir mola verin! + +Hazır olduğunuzda, pipeline'ınızın yürütülmesini altyapınıza uyacak şekilde yapılandırmayı ve girdiler ile parametrelerin yapılandırmasını yönetmeyi öğrenmek için [**Bölüm 6: Merhaba Yapılandırma**](./06_hello_config.md)'ya geçin. + +Bu en son bölüm ve sonra bu kursla işiniz bitmiş olacak! + +--- + +## Quiz + +<quiz> +Konteyner nedir? +- [ ] Bir sanal makine türü +- [ ] Bir dosya sıkıştırma formatı +- [x] Bir uygulamayı çalıştırmak için gereken her şeyi içeren hafif, bağımsız çalıştırılabilir bir birim +- [ ] Bir ağ protokolü +</quiz> + +<quiz> +Konteyner imajı ile konteyner örneği arasındaki fark nedir? +- [ ] Aynı şeyler +- [x] İmaj bir şablondur; örnek o imajdan oluşturulan çalışan bir konteynerdir +- [ ] Örnek bir şablondur; imaj çalışan bir konteynerdir +- [ ] İmajlar Docker içindir; örnekler Singularity içindir +</quiz> + +<quiz> +`docker run` komutunda `-v` bayrağı ne yapar? +- [ ] Ayrıntılı çıktıyı etkinleştirir +- [ ] Konteyneri doğrular +- [x] Ana sistemden konteynere bir hacim bağlar +- [ ] Konteynerin sürümünü belirtir + +Daha fazla bilgi: [1.3.4. Verileri konteynere bağlayın](#134-verileri-konteynere-baglayin) +</quiz> + +<quiz> +Konteynerler kullanırken neden hacimleri bağlamanız gerekiyor? +- [ ] Konteyner performansını artırmak için +- [ ] Disk alanından tasarruf etmek için +- [x] Konteynerler varsayılan olarak ana dosya sisteminden izole olduğu için +- [ ] Ağı etkinleştirmek için + +Daha fazla bilgi: [1.3.4. Verileri konteynere bağlayın](#134-verileri-konteynere-baglayin) +</quiz> + +<quiz> +Bir Nextflow süreci için konteyneri nasıl belirtirsiniz? +- [ ] `docker 'container-uri'` +- [ ] `image 'container-uri'` +- [x] `container 'container-uri'` +- [ ] `use 'container-uri'` + +Daha fazla bilgi: [2.3.1. cowpy için bir konteyner belirtin](#231-cowpy-icin-bir-konteyner-belirtin) +</quiz> + +<quiz> +İş akışınız için Docker'ı hangi `nextflow.config` ayarı etkinleştirir? +- [ ] `#!groovy process.docker = true` +- [x] `#!groovy docker.enabled = true` +- [ ] `#!groovy container.engine = 'docker'` +- [ ] `#!groovy docker.activate = true` + +Daha fazla bilgi: [2.3.2. `nextflow.config` dosyası aracılığıyla Docker kullanımını etkinleştirin](#232-nextflowconfig-dosyasi-araciligiyla-docker-kullanimini-etkinlestirin) +</quiz> + +<quiz> +Bir süreci konteyner içinde çalıştırırken Nextflow otomatik olarak neyi yönetir? (Uygulanabilen tümünü seçin) +- [x] Gerekirse konteyner imajını çekmek +- [x] Work dizinini bağlamak +- [x] Süreç betiğini konteyner içinde çalıştırmak +- [x] Yürütme sonrası konteyner örneğini temizlemek + +Daha fazla bilgi: [2.3.4. Nextflow'un konteynerleştirilmiş görevi nasıl başlattığını inceleyin](#234-nextflowun-konteynerlestirilmis-gorevi-nasil-baslattigini-inceleyin) +</quiz> diff --git a/docs/tr/docs/hello_nextflow/06_hello_config.md b/docs/tr/docs/hello_nextflow/06_hello_config.md new file mode 100644 index 0000000000..4a51cb41ea --- /dev/null +++ b/docs/tr/docs/hello_nextflow/06_hello_config.md @@ -0,0 +1,1646 @@ +# Bölüm 6: Hello Config + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } Nextflow YouTube kanalında [tüm oynatma listesini](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video transkripti [burada](./transcripts/06_hello_config.md) mevcuttur. +/// + +Bu bölüm, _iş akışı kodunun tek bir satırını değiştirmeden_ davranışını özelleştirebilmeniz, farklı ortamlara uyarlayabilmeniz ve kaynak kullanımını optimize edebilmeniz için Nextflow pipeline'ınızın yapılandırmasını nasıl kuracağınızı ve yöneteceğinizi keşfedecektir. + +Bunu yapmanın birden fazla yolu vardır; bunlar birlikte kullanılabilir ve [burada](https://www.nextflow.io/docs/latest/config.html) açıklanan öncelik sırasına göre yorumlanır. + +Bu kursun bu bölümünde, Bölüm 5: Merhaba Konteynerler'de zaten karşılaştığınız en basit ve en yaygın yapılandırma dosyası mekanizması olan `nextflow.config` dosyasını göstereceğiz. + +Süreç yönergeleri, yürütücüler, profiller ve parametre dosyaları gibi Nextflow yapılandırmasının temel bileşenlerini gözden geçireceğiz. +Bu yapılandırma seçeneklerini etkin bir şekilde kullanmayı öğrenerek, pipeline'larınızın esnekliğini, ölçeklenebilirliğini ve performansını artırabilirsiniz. + +??? info "Bu bölümden nasıl başlanır" + + Bu kursun bu bölümü, [Hello Nextflow](./index.md) kursunun 1-5. Bölümlerini tamamladığınızı ve eksiksiz çalışan bir pipeline'ınız olduğunu varsayar. + + Kursa bu noktadan başlıyorsanız, `modules` dizinini ve `nextflow.config` dosyasını çözümlerden kopyalamanız gerekecek: + + ```bash + cp -r solutions/5-hello-containers/modules . + cp solutions/5-hello-containers/nextflow.config . + ``` + + `nextflow.config` dosyası, Docker konteynerlerinin kullanımını etkinleştiren `docker.enabled = true` satırını içerir. + + Hello pipeline'ına aşina değilseniz veya bir hatırlatmaya ihtiyacınız varsa, [bu bilgi sayfasına](../info/hello_pipeline.md) bakın. + +--- + +## 0. Isınma: `hello-config.nf` dosyasını çalıştırın + +Başlangıç noktası olarak `hello-config.nf` iş akışı betiğini kullanacağız. +Bu betik, bu eğitim kursunun 5. Bölümünde üretilen betiğe eşdeğerdir; ancak çıktı hedeflerini değiştirdik: + +```groovy title="hello-config.nf" linenums="37" hl_lines="3 7 11 15" +output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } +} +``` + +Her şeyin çalıştığından emin olmak için, herhangi bir değişiklik yapmadan önce betiği bir kez çalıştırın: + +```bash +nextflow run hello-config.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [nice_escher] DSL2 - revision: d5dfdc9872 + + executor > local (7) + [6a/bc46a6] sayHello (2) [100%] 3 of 3 ✔ + [33/67bc48] convertToUpper (3) [100%] 3 of 3 ✔ + [b5/de03ba] collectGreetings [100%] 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Daha önce olduğu gibi, çıktı dosyalarını `output` bloğunda belirtilen dizinde bulacaksınız (`results/hello_config/`). + +??? abstract "Dizin içerikleri" + + ```console + results/hello_config/ + ├── cowpy-COLLECTED-batch-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-batch-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── batch-report.txt + ``` + +Son ASCII sanat çıktısı `results/hello_config/` dizininde, `cowpy-COLLECTED-batch-output.txt` adı altında. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Bu sizin için çalıştıysa, pipeline'larınızı nasıl yapılandıracağınızı öğrenmeye hazırsınız. + +--- + +## 1. İş akışı girdi parametrelerini yönetin + +Şimdiye kadar üzerinde çalıştığımız şeyin basit bir uzantısı olan bir yapılandırma yönüyle başlayacağız: girdi parametrelerinin yönetimi. + +Şu anda, iş akışımız komut satırı aracılığıyla çeşitli parametre değerlerini kabul edecek şekilde ayarlanmış, varsayılan değerler iş akışı betiğinin kendisindeki bir `params` bloğunda ayarlanmış. +Ancak, bu varsayılanları, komut satırında parametreler belirtmek veya orijinal betik dosyasını değiştirmek zorunda kalmadan geçersiz kılmak isteyebilirsiniz. + +Bunu yapmanın birden fazla yolu vardır; size çok yaygın olarak kullanılan üç temel yolu göstereceğiz. + +### 1.1. Varsayılan değerleri `nextflow.config`'e taşıyın + +Bu en basit yaklaşımdır, ancak ana `nextflow.config` dosyası her çalıştırma için düzenlemek isteyeceğiniz bir şey olmadığından muhtemelen en az esnek olanıdır. +Ancak, parametreleri iş akışında _tanımlamak_ (kesinlikle oraya ait) ile _varsayılan değerler_ sağlamak (bir yapılandırma dosyasında daha uygun) arasındaki endişeleri ayırma avantajına sahiptir. + +Bunu iki adımda yapalım. + +#### 1.1.1. Yapılandırma dosyasında bir `params` bloğu oluşturun + +`nextflow.config` dosyasında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +`params` bloğunu iş akışından yapılandırma dosyasına basitçe kopyalamadığımıza dikkat edin. +Sözdizimi biraz farklı. +İş akışı dosyasında, bunlar tip tanımlı bildirimlerdir. +Yapılandırmada, bunlar değer atamalarıdır. + +Teknik olarak, bu hâlâ iş akışı dosyasında belirtilen varsayılan değerleri geçersiz kılmak için yeterlidir. +Karakteri değiştirebilir, örneğin, ve yapılandırma dosyasında ayarlanan değerin iş akışı dosyasında ayarlanan değeri geçersiz kıldığından emin olmak için iş akışını çalıştırabilirsiniz. + +Ancak, yapılandırmayı tamamen yapılandırma dosyasına taşıma ruhuna uygun olarak, bu değerleri iş akışı dosyasından tamamen kaldıralım. + +#### 1.1.2. İş akışı dosyasındaki `params` bloğundan değerleri kaldırın + +`hello-config.nf` iş akışı dosyasında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Önce" + + ```groovy title="hello-config.nf" linenums="9" hl_lines="5-7" + /* + * Pipeline parametreleri + */ + params { + input: Path = 'data/greetings.csv' + batch: String = 'batch' + character: String = 'turkey' + } + ``` + +Artık iş akışı dosyasının kendisi bu parametreler için herhangi bir varsayılan değer ayarlamıyor. + +#### 1.1.3. Pipeline'ı çalıştırın + +Doğru çalışıp çalışmadığını test edelim. + +```bash +nextflow run hello-config.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretiyor. + +Son ASCII sanat çıktısı `results/hello_config/` dizininde, daha önce olduğu gibi `cowpy-COLLECTED-batch-output.txt` adı altında. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_config/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +İşlevsel olarak, bu taşıma hiçbir şeyi değiştirmedi, ancak kavramsal olarak varsayılan değerlerin yapılandırma dosyasında ayarlanması biraz daha temiz. + +### 1.2. Çalıştırmaya özgü bir yapılandırma dosyası kullanın + +Harika, ama bazen ana yapılandırma dosyasıyla uğraşmadan farklı varsayılan değerlerle bazı geçici deneyler yapmak isteyebilirsiniz. +Bunu, deneyeleriniz için çalışma dizini olarak kullanacağınız bir alt dizinde yeni bir `nextflow.config` dosyası oluşturarak yapabilirsiniz. + +#### 1.2.1. Boş bir yapılandırma ile çalışma dizini oluşturun + +Yeni bir dizin oluşturarak ve içine girerek başlayalım: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Ardından, o dizinde boş bir yapılandırma dosyası oluşturun: + +```bash +touch nextflow.config +``` + +Bu boş bir dosya üretir. + +#### 1.2.2. Deneysel yapılandırmayı kurun + +Şimdi yeni dosyayı açın ve özelleştirmek istediğiniz parametreleri ekleyin: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Girdi dosyasının yolunun dizin yapısını yansıtması gerektiğini unutmayın. + +#### 1.2.3. Pipeline'ı çalıştırın + +Artık pipeline'ımızı yeni çalışma dizinimizin içinden çalıştırabiliriz. +Yolu buna göre uyarladığınızdan emin olun! + +```bash +nextflow run ../hello-config.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../hello-config.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Bu, `tux-run/work/` ve `tux-run/results/` dahil olmak üzere `tux-run/` altında yeni bir dizi dizin oluşturacaktır. + +Bu çalıştırmada, Nextflow mevcut dizinimizdeki `nextflow.config`'i pipeline'ın kök dizinindeki `nextflow.config` ile birleştirir ve böylece varsayılan karakteri (turkey) tux karakteriyle geçersiz kılar. + +Son çıktı dosyası, tux karakterinin selamlamaları söylediğini içermelidir. + +??? abstract "Dosya içerikleri" + + ```console title="tux-run/results/hello_config/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +İşte bu kadar; artık 'normal' yapılandırmanızı değiştirmeden deney yapmak için bir alanınız var. + +!!! warning "Uyarı" + + Bir sonraki bölüme geçmeden önce önceki dizine geri döndüğünüzden emin olun! + + ```bash + cd .. + ``` + +Şimdi parametre değerlerini ayarlamanın başka kullanışlı bir yoluna bakalım. + +### 1.3. Bir parametre dosyası kullanın + +Alt dizin yaklaşımı deney yapmak için harika çalışır, ancak biraz kurulum gerektirir ve yolları buna göre uyarlamanızı gerektirir. +Pipeline'ınızı belirli bir değer kümesiyle çalıştırmak veya başkasının minimum çabayla yapmasını sağlamak istediğinizde daha basit bir yaklaşım vardır. + +Nextflow, parametreleri YAML veya JSON formatında bir parametre dosyası aracılığıyla belirtmemize olanak tanır; bu, örneğin alternatif varsayılan değer kümelerini ve çalıştırmaya özgü parametre değerlerini yönetmeyi ve dağıtmayı çok kullanışlı hale getirir. + +#### 1.3.1. Örnek parametre dosyasını inceleyin + +Bunu göstermek için, mevcut dizinde `test-params.yaml` adında bir örnek parametre dosyası sağlıyoruz: + +```yaml title="test-params.yaml" linenums="1" +{ + input: "greetings.csv" + batch: "yaml" + character: "stegosaurus" +} +``` + +Bu parametre dosyası, belirtmek istediğimiz girdilerin her biri için bir anahtar-değer çifti içerir. +Sözdizimini yapılandırma dosyasıyla karşılaştırırsanız, eşit işaretleri (`=`) yerine iki nokta üst üste (`:`) kullanıldığına dikkat edin. +Yapılandırma dosyası Groovy'de yazılmışken, parametre dosyası YAML'de yazılmıştır. + +!!! info "Bilgi" + + Ayrıca parametre dosyasının bir JSON versiyonunu örnek olarak sağlıyoruz ancak burada onunla çalıştırmayacağız. + Onu kendi başınıza denemekten çekinmeyin. + +#### 1.3.2. Pipeline'ı çalıştırın + +İş akışını bu parametre dosyasıyla çalıştırmak için, temel komuta `-params-file <dosyaadı>` eklemeniz yeterli. + +```bash +nextflow run hello-config.nf -params-file test-params.yaml +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Son çıktı dosyası, stegosaurus karakterinin selamlamaları söylediğini içermelidir. + +??? abstract "Dosya içerikleri" + + ```console title="results/hello_config/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Yalnızca birkaç parametreniz olduğunda bir parametre dosyası kullanmak aşırı gibi görünebilir, ancak bazı pipeline'lar düzinelerce parametre bekler. +Bu durumlarda, bir parametre dosyası kullanmak, büyük komut satırları yazmak zorunda kalmadan ve iş akışı betiğini değiştirmeden çalışma zamanında parametre değerleri sağlamamıza olanak tanıyacaktır. + +Ayrıca parametre kümelerini işbirlikçilere veya örneğin bir yayın için destekleyici bilgi olarak dağıtmayı kolaylaştırır. +Bu, çalışmanızı başkaları tarafından daha tekrarlanabilir hale getirir. + +### Özet + +İş akışı girdilerini yönetmek için temel yapılandırma seçeneklerinden nasıl yararlanacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışı çıktılarınızın nerede ve nasıl yayınlanacağını nasıl yöneteceğinizi öğrenin. + +--- + +## 2. İş akışı çıktılarını yönetin + +Şimdiye kadar iş akışı düzeyindeki çıktı tanımlamaları için tüm yolları sabit kodluyorduk ve birden fazla çıktı eklemeye başladığımızda belirttiğimiz gibi, biraz tekrar olabilir. + +Bunu daha esnek yapılandırmak için birkaç yaygın yola bakalım. + +### 2.1. `outputDir` dizin adını özelleştirin + +Bu kursun her bölümü için, çıktıları çıktı tanımlarına sabit kodlanmış farklı bir alt dizine yayınlıyorduk. + +Bunu kullanıcı tarafından yapılandırılabilir bir parametre kullanacak şekilde değiştirelim. +Bunun için tamamen yeni bir parametre oluşturabiliriz, ancak zaten orada olduğu için `batch` parametresini kullanalım. + +#### 2.1.1. Yapılandırma dosyasında `outputDir` için bir değer ayarlayın + +Nextflow'un çıktıları yayınlamak için kullandığı yol, `outputDir` seçeneği tarafından kontrol edilir. +Tüm çıktılar için yolu değiştirmek üzere, `nextflow.config` yapılandırma dosyasında bu seçenek için bir değer ayarlayabilirsiniz. + +`nextflow.config` dosyasına aşağıdaki kodu ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Çıktı ayarları + */ + outputDir = "results/${params.batch}" + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Bu, yerleşik varsayılan yolu, `results/`, `results/` artı alt dizin olarak `batch` parametresinin değeriyle değiştirecektir. +İsterseniz `results` kısmını da değiştirebilirsiniz. + +Geçici bir değişiklik için, komutunuzda `-output-dir` parametresini kullanarak bu seçeneği komut satırından ayarlayabilirsiniz (ancak o zaman `batch` parametre değerini kullanamazsınız). + +#### 2.1.2. Sabit kodlanmış yolun tekrarlanan kısmını kaldırın + +Çıktı seçeneklerinde hâlâ sabit kodlanmış bir alt dizinimiz var, o yüzden şimdi ondan kurtulalım. + +İş akışı dosyasında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'hello_config/intermediates' + mode 'copy' + } + uppercased { + path 'hello_config/intermediates' + mode 'copy' + } + collected { + path 'hello_config/intermediates' + mode 'copy' + } + batch_report { + path 'hello_config' + mode 'copy' + } + cowpy_art { + path 'hello_config' + mode 'copy' + } + } + ``` + +`outputDir` varsayılanını değiştirmek yerine her yola `${params.batch}` ekleyebilirdik, ancak bu daha kısa. + +#### 2.1.3. Pipeline'ı çalıştırın + +Doğru çalışıp çalışmadığını test edelim, grup adını komut satırından `outdir` olarak ayarlayarak. + +```bash +nextflow run hello-config.nf --batch outdir +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/outdir/` altında buluyoruz. + +??? abstract "Dizin içerikleri" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Bu yaklaşımı özel yol tanımlarıyla birleştirerek istediğiniz herhangi bir dizin hiyerarşisini oluşturabilirsiniz. + +### 2.2. Çıktıları sürece göre organize edin + +Çıktıları daha fazla organize etmenin popüler bir yolu, bunu sürece göre yapmaktır, _yani_ pipeline'da çalıştırılan her süreç için alt dizinler oluşturmak. + +#### 2.2.1. Çıktı yollarını süreç adlarına referansla değiştirin + +Yapmanız gereken tek şey, çıktı yolu tanımında sürecin adını `<task>.name` olarak referans vermektir. + +İş akışı dosyasında aşağıdaki değişiklikleri yapın: + +=== "Sonra" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Bu, çıktı yolu yapılandırmasından kalan sabit kodlanmış öğeleri kaldırır. + +#### 2.2.2. Pipeline'ı çalıştırın + +Doğru çalışıp çalışmadığını test edelim, grup adını komut satırından `pnames` olarak ayarlayarak. + +```bash +nextflow run hello-config.nf --batch pnames +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/pnames/` altında buluyoruz ve sürece göre gruplandırılmışlar. + +??? abstract "Dizin içerikleri" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Burada `intermediates` ile son çıktıların üst düzeyde olması arasındaki ayrımı sildiğimizi unutmayın. +Tabii ki bu yaklaşımları karıştırabilirsiniz, örneğin ilk çıktının yolunu `intermediates/${sayHello.process}` olarak ayarlayarak + +### 2.3. Yayınlama modunu iş akışı düzeyinde ayarlayın + +Son olarak, tekrarlayan kod miktarını azaltma ruhuna uygun olarak, çıktı başına `mode` tanımlarını yapılandırmada tek bir satırla değiştirebiliriz. + +#### 2.3.1. Yapılandırma dosyasına `workflow.output.mode` ekleyin + +`nextflow.config` dosyasına aşağıdaki kodu ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Çıktı ayarları + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="12" + /* + * Çıktı ayarları + */ + outputDir = "results/${params.batch}" + ``` + +Tıpkı `outputDir` seçeneği gibi, yapılandırma dosyasında `workflow.output.mode`'a bir değer vermek, iş akışı dosyasında ayarlananı geçersiz kılmak için yeterli olurdu, ancak yine de gereksiz kodu kaldıralım. + +#### 2.3.2. Çıktı modunu iş akışı dosyasından kaldırın + +İş akışı dosyasında aşağıdaki değişiklikleri yapın: + +=== "Sonra" + + ```groovy title="hello-config.nf" linenums="42" + output { + first_output { + path { sayHello.process } + } + uppercased { + path { convertToUpper.process } + } + collected { + path { collectGreetings.process } + } + batch_report { + path { collectGreetings.process } + } + cowpy_art { + path { cowpy.process } + } + } + ``` + +=== "Önce" + + ```groovy title="hello-config.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.process } + mode 'copy' + } + uppercased { + path { convertToUpper.process } + mode 'copy' + } + collected { + path { collectGreetings.process } + mode 'copy' + } + batch_report { + path { collectGreetings.process } + mode 'copy' + } + cowpy_art { + path { cowpy.process } + mode 'copy' + } + } + ``` + +Bu daha kısa, değil mi? + +#### 2.3.3. Pipeline'ı çalıştırın + +Doğru çalışıp çalışmadığını test edelim, grup adını komut satırından `outmode` olarak ayarlayarak. + +```bash +nextflow run hello-config.nf --batch outmode +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hâlâ daha önce olduğu gibi aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/outmode/` altında buluyoruz. +Hepsi hâlâ düzgün kopyalar, sembolik bağlantılar değil. + +??? abstract "Dizin içerikleri" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Çıktı başına mod ayarlama yolunu hâlâ kullanmak istemenizin ana nedeni, aynı iş akışı içinde karıştırıp eşleştirmek istemeniz olabilir, _yani_ bazı çıktıların kopyalanması ve bazılarının sembolik bağlantı olması. + +Bu şekilde özelleştirebileceğiniz birçok başka seçenek var, ancak umarız bu size seçenek yelpazesi ve tercihlerinize uygun olarak bunları etkili bir şekilde nasıl kullanacağınız hakkında bir fikir verir. + +### Özet + +Çıktılarınızın yayınlandığı dizinlerin adlandırılmasını ve yapısını ve iş akışı çıktısı yayınlama modunu nasıl kontrol edeceğinizi biliyorsunuz. + +### Sırada ne var? + +İş akışı yapılandırmanızı yazılım paketleme teknolojisinden başlayarak hesaplama ortamınıza nasıl uyarlayacağınızı öğrenin. + +--- + +## 3. Bir yazılım paketleme teknolojisi seçin + +Şimdiye kadar girdilerin nasıl girdiğini ve çıktıların nereden çıktığını kontrol eden yapılandırma öğelerine bakıyorduk. Şimdi iş akışı yapılandırmanızı hesaplama ortamınıza uyarlamaya daha özel olarak odaklanma zamanı. + +Bu yoldaki ilk adım, her adımda çalıştırılacak yazılım paketlerinin nereden geleceğini belirtmektir. +Yerel hesaplama ortamında zaten yüklü mü? +İmajları alıp bir konteyner sistemi aracılığıyla çalıştırmamız mı gerekiyor? +Yoksa Conda paketlerini alıp yerel bir Conda ortamı mı oluşturmamız gerekiyor? + +Bu eğitim kursunun en başında (Bölüm 1-4) iş akışımızda sadece yerel olarak yüklenmiş yazılımı kullandık. +Ardından Bölüm 5'te, Docker konteynerlerini ve Docker konteynerlerinin kullanımını etkinleştirmek için kullandığımız `nextflow.config` dosyasını tanıttık. + +Şimdi `nextflow.config` dosyası aracılığıyla alternatif bir yazılım paketleme seçeneğini nasıl yapılandırabileceğimizi görelim. + +### 3.1. Yapılandırma dosyasında Docker'ı devre dışı bırakın ve Conda'yı etkinleştirin + +Bir HPC kümesinde çalıştığımızı ve yöneticinin güvenlik nedeniyle Docker kullanımına izin vermediğini varsayalım. +Neyse ki bizim için, Nextflow, Singularity (HPC'de daha yaygın olarak kullanılır) gibi birden fazla başka konteyner teknolojisini ve Conda gibi yazılım paket yöneticilerini destekler. + +Yapılandırma dosyamızı Docker yerine Conda kullanacak şekilde değiştirebiliriz. +Bunu yapmak için, `docker.enabled` değerini `false` olarak değiştirelim ve Conda kullanımını etkinleştiren bir yönerge ekleyelim: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Bu, Nextflow'un Conda paketleri belirtilmiş süreçler için Conda ortamları oluşturmasına ve kullanmasına olanak tanıyacaktır. +Bu, şimdi `cowpy` sürecimize bunlardan birini eklememiz gerektiği anlamına gelir! + +### 3.2. Süreç tanımında bir Conda paketi belirtin + +`cowpy` aracını içeren bir Conda paketi için URI'yi zaten aldık: `conda-forge::cowpy==1.1.5` + +Şimdi `conda` yönergesini kullanarak URI'yi `cowpy` süreç tanımına ekliyoruz: + +=== "Sonra" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Önce" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Açık olmak gerekirse, `docker` yönergesini _değiştirmiyoruz_, alternatif bir seçenek _ekliyoruz_. + +!!! tip "İpucu" + + Belirli bir conda paketi için URI almanın birkaç farklı yolu var. + [Seqera Containers](https://seqera.io/containers/) arama sorgusunu kullanmanızı öneriyoruz; bu, ondan bir konteyner oluşturmayı planlamasanız bile kopyalayıp yapıştırabileceğiniz bir URI verecektir. + +### 3.3. Conda kullanabildiğini doğrulamak için iş akışını çalıştırın + +Hadi deneyelim. + +```bash +nextflow run hello-config.nf --batch conda +``` + +??? success "Komut çıktısı" + + ```console title="Çıktı" + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Bu sorunsuz çalışmalı ve `results/conda` altında daha önce olduğu gibi aynı çıktıları üretmelidir. + +Perde arkasında, Nextflow Conda paketlerini aldı ve ortamı oluşturdu, bu normalde biraz iş gerektirir; bu yüzden bunların hiçbirini kendimiz yapmak zorunda kalmamamız güzel! + +!!! note "Not" + + Bu hızlı çalışır çünkü `cowpy` paketi oldukça küçüktür, ancak büyük paketlerle çalışıyorsanız, ilk seferde normalden biraz daha uzun sürebilir ve konsol çıktısının tamamlanmadan önce bir dakika kadar 'takılı' kaldığını görebilirsiniz. + Bu normaldir ve Nextflow'un yeni bir paketi ilk kullandığınızda yaptığı ekstra işten kaynaklanır. + +Bizim açımızdan, arka uçta mekanikler biraz farklı olsa da Docker ile çalıştırmakla tamamen aynı görünüyor. + +Bu, gerektiğinde Conda ortamlarıyla çalıştırmaya hazır olduğumuz anlamına gelir. + +??? info "Docker ve Conda'yı karıştırıp eşleştirme" + + Bu yönergeler süreç başına atandığından, 'karıştırıp eşleştirmek' mümkündür, _yani_ kullandığınız hesaplama altyapısı her ikisini de destekliyorsa, iş akışınızdaki bazı süreçleri Docker ile ve diğerlerini Conda ile çalıştıracak şekilde yapılandırabilirsiniz. + Bu durumda, yapılandırma dosyanızda hem Docker hem de Conda'yı etkinleştirirsiniz. + Her ikisi de belirli bir süreç için mevcutsa, Nextflow konteynerlere öncelik verecektir. + + Ve daha önce belirtildiği gibi, Nextflow birden fazla başka yazılım paketleme ve konteyner teknolojisini destekler, bu nedenle yalnızca bu ikisiyle sınırlı değilsiniz. + +### Özet + +Her sürecin hangi yazılım paketini kullanması gerektiğini nasıl yapılandıracağınızı ve teknolojiler arasında nasıl geçiş yapacağınızı biliyorsunuz. + +### Sırada ne var? + +Nextflow'un işi gerçekten yapmak için kullandığı yürütme platformunu nasıl değiştireceğinizi öğrenin. + +--- + +## 4. Bir yürütme platformu seçin + +Şimdiye kadar, pipeline'ımızı local yürütücüyle çalıştırıyorduk. +Bu, her görevi Nextflow'un çalıştığı makinede yürütür. +Nextflow başladığında, mevcut CPU'lara ve belleğe bakar. +Çalıştırılmaya hazır görevlerin kaynakları mevcut kaynakları aşarsa, Nextflow son görevleri, önceki görevlerden biri veya daha fazlası tamamlanıp gerekli kaynakları serbest bırakana kadar yürütmeden alıkoyacaktır. + +Local yürütücü kullanışlı ve verimlidir, ancak o tek makineyle sınırlıdır. Çok büyük iş yükleri için, yerel makinenizin bir darboğaz olduğunu keşfedebilirsiniz; ya mevcut olandan daha fazla kaynak gerektiren tek bir göreviniz olduğu için ya da tek bir makinenin bunları çalıştırmasını beklemenin çok uzun süreceği kadar çok göreviniz olduğu için. + +Nextflow, HPC zamanlayıcıları (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor ve diğerleri) dahil olmak üzere [birçok farklı yürütme arka ucunu](https://www.nextflow.io/docs/latest/executor.html) ve ayrıca bulut yürütme arka uçlarını (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes ve daha fazlası) destekler. + +### 4.1. Farklı bir arka ucu hedefleme + +Yürütücü seçimi, `executor` adlı bir süreç yönergesiyle belirlenir. +Varsayılan olarak `local` olarak ayarlanmıştır, bu nedenle aşağıdaki yapılandırma ima edilir: + +```groovy title="Yerleşik yapılandırma" +process { + executor = 'local' +} +``` + +Yürütücüyü farklı bir arka ucu hedefleyecek şekilde ayarlamak için, kaynak tahsisleri için yukarıda açıklandığı gibi benzer sözdizimi kullanarak istediğiniz yürütücüyü belirtmeniz yeterlidir (tüm seçenekler için [dokümantasyona](https://www.nextflow.io/docs/latest/executor.html) bakın). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Uyarı" + + Bunu eğitim ortamında gerçekten test edemeyiz çünkü bir HPC'ye bağlanacak şekilde ayarlanmamış. + +### 4.2. Yürütme parametreleri için arka uca özgü sözdizimi ile başa çıkma + +Çoğu yüksek performanslı hesaplama platformu, kaynak tahsisi istekleri ve sınırlamaları (örn. CPU sayısı ve bellek) ve kullanılacak iş kuyruğunun adı gibi belirli parametreleri belirtmenize izin verir (ve bazen gerektirir). + +Ne yazık ki, bu sistemlerin her biri, bir işin nasıl tanımlanması ve ilgili zamanlayıcıya nasıl gönderilmesi gerektiğini belirlemek için farklı teknolojiler, sözdizimiler ve yapılandırmalar kullanır. + +??? abstract "Örnekler" + + Örneğin, 8 CPU ve 4GB RAM gerektiren ve "my-science-work" kuyruğunda yürütülecek aynı iş, arka uca bağlı olarak aşağıdaki farklı şekillerde ifade edilmelidir. + + ```bash title="SLURM için yapılandırma / sbatch kullanarak gönder" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="PBS için yapılandırma / qsub kullanarak gönder" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="SGE için yapılandırma / qsub kullanarak gönder" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Neyse ki, Nextflow tüm bunları basitleştirir. +`cpus`, `memory` ve `queue` gibi ilgili özellikleri (diğer özellikler için dokümantasyona bakın) yalnızca bir kez belirtebilmeniz için standartlaştırılmış bir sözdizimi sağlar. +Ardından, çalışma zamanında, Nextflow bu ayarları kullanarak yürütücü ayarına dayalı olarak uygun arka uca özgü betikleri oluşturacaktır. + +Bu standartlaştırılmış sözdizimini bir sonraki bölümde ele alacağız. + +### Özet + +Artık farklı türde hesaplama altyapısı kullanmak için yürütücüyü nasıl değiştireceğinizi biliyorsunuz. + +### Sırada ne var? + +Nextflow'da kaynak tahsislerini ve sınırlamalarını nasıl değerlendirip ifade edeceğinizi öğrenin. + +--- + +## 5. Hesaplama kaynak tahsislerini kontrol edin + +Çoğu yüksek performanslı hesaplama platformu, CPU sayısı ve bellek gibi belirli kaynak tahsis parametrelerini belirtmenize izin verir (ve bazen gerektirir). + +Varsayılan olarak, Nextflow her süreç için tek bir CPU ve 2GB bellek kullanacaktır. +İlgili süreç yönergeleri `cpus` ve `memory` olarak adlandırılır, bu nedenle aşağıdaki yapılandırma ima edilir: + +```groovy title="Yerleşik yapılandırma" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Bu değerleri, yapılandırma dosyanızdaki ek süreç yönergelerini kullanarak tüm süreçler veya belirli adlandırılmış süreçler için değiştirebilirsiniz. +Nextflow bunları seçilen yürütücü için uygun talimatlara çevirecektir. + +Ancak hangi değerleri kullanacağınızı nasıl bilirsiniz? + +### 5.1. Kaynak kullanım raporu oluşturmak için iş akışını çalıştırın + +Süreçlerinizin ne kadar CPU ve belleğe ihtiyaç duyacağını önceden bilmiyorsanız, bazı kaynak profilleme yapabilirsiniz; yani iş akışını bazı varsayılan tahsislerle çalıştırırsınız, her sürecin ne kadar kullandığını kaydedersiniz ve oradan temel tahsisleri nasıl ayarlayacağınızı tahmin edersiniz. + +Kullanışlı bir şekilde, Nextflow bunu yapmak için yerleşik araçlar içerir ve istek üzerine sizin için bir rapor oluşturmaktan mutluluk duyar. + +Bunu yapmak için, komut satırınıza `-with-report <dosyaadı>.html` ekleyin. + +```bash +nextflow run hello-config.nf -with-report report-config-1.html +``` + +Rapor, tarayıcınızda indirip açabileceğiniz bir html dosyasıdır. Eğitim ortamında görüntülemek için soldaki dosya gezgininde sağ tıklayıp `Show preview`'a da tıklayabilirsiniz. + +Raporu incelemek ve kaynakları ayarlama fırsatlarını belirleyip belirleyemeyeceğinizi görmek için birkaç dakika ayırın. +Kullanım sonuçlarını tahsis edilenin yüzdesi olarak gösteren sekmelere tıkladığınızdan emin olun. +Mevcut tüm özellikleri açıklayan bazı [dokümantasyon](https://www.nextflow.io/docs/latest/reports.html) var. + +### 5.2. Tüm süreçler için kaynak tahsisleri ayarlayın + +Profilleme, eğitim iş akışımızdaki süreçlerin çok hafif olduğunu gösteriyor, bu yüzden varsayılan bellek tahsisini süreç başına 1GB'a düşürelim. + +`nextflow.config` dosyanıza, pipeline parametreleri bölümünden önce aşağıdakileri ekleyin: + +```groovy title="nextflow.config" linenums="4" +/* +* Süreç ayarları +*/ +process { + memory = 1.GB +} +``` + +Bu, tükettiğimiz hesaplama miktarını azaltmaya yardımcı olacaktır. + +### 5.3. Belirli bir süreç için kaynak tahsisleri ayarlayın + +Aynı zamanda, `cowpy` sürecinin diğerlerinden daha fazla kaynak gerektirdiğini varsayacağız, böylece bireysel bir süreç için tahsisleri nasıl ayarlayacağımızı gösterebiliriz. + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Süreç ayarları + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="4" + /* + * Süreç ayarları + */ + process { + memory = 1.GB + } + ``` + +Bu yapılandırmayla, `cowpy` süreci dışında tüm süreçler 1GB bellek ve tek bir CPU (ima edilen varsayılan) isteyecektir; `cowpy` süreci 2GB ve 2 CPU isteyecektir. + +!!! tip "İpucu" + + Az sayıda CPU'ya sahip bir makineniz varsa ve süreç başına yüksek sayıda tahsis ederseniz, süreç çağrılarının birbiri ardına sıraya girdiğini görebilirsiniz. + Bunun nedeni, Nextflow'un mevcut olandan daha fazla CPU talep etmememizi sağlamasıdır. + +### 5.4. Güncellenmiş yapılandırma ile iş akışını çalıştırın + +Bunu deneyelim, yapılandırma değişikliklerinden önce ve sonra performansı karşılaştırabilmemiz için profilleme raporu için farklı bir dosya adı sağlayarak. + +```bash +nextflow run hello-config.nf -with-report report-config-2.html +``` + +Bu kadar küçük bir iş yükü olduğundan muhtemelen gerçek bir fark fark etmeyeceksiniz, ancak bu, gerçek dünya bir iş akışının performansını ve kaynak gereksinimlerini analiz etmek için kullanacağınız yaklaşımdır. + +Süreçlerinizin farklı kaynak gereksinimleri olduğunda çok faydalıdır. Tahminde bulunmak yerine gerçek verilere dayalı olarak her süreç için ayarladığınız kaynak tahsislerini doğru boyutlandırmanızı sağlar. + +!!! tip "İpucu" + + Bu, kaynak kullanımınızı optimize etmek için yapabileceklerinizin sadece küçük bir tadımıdır. + Nextflow'un kendisi, kaynak sınırlamaları nedeniyle başarısız olan işleri yeniden denemek için gerçekten zarif [dinamik yeniden deneme mantığı](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) yerleşik olarak içerir. + Ek olarak, Seqera Platform kaynak tahsislerinizi otomatik olarak optimize etmek için yapay zeka destekli araçlar da sunmaktadır. + +### 5.5. Kaynak sınırları ekleyin + +Hangi hesaplama yürütücüsü ve hesaplama altyapısı kullandığınıza bağlı olarak, tahsis edebileceğiniz (veya etmeniz gereken) konusunda bazı kısıtlamalar olabilir. +Örneğin, kümeniz belirli sınırlar içinde kalmanızı gerektirebilir. + +İlgili sınırlamaları ayarlamak için `resourceLimits` yönergesini kullanabilirsiniz. Sözdizimi, bir process bloğunda tek başına olduğunda şöyle görünür: + +```groovy title="Sözdizimi örneği" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow bu değerleri, belirttiğiniz yürütücüye bağlı olarak uygun talimatlara çevirecektir. + +Bunu çalıştırmayacağız, çünkü eğitim ortamında ilgili altyapıya erişimimiz yok. +Ancak, bu sınırları aşan kaynak tahsisleriyle iş akışını çalıştırmayı deneyecek olsaydınız, ardından `.command.run` betik dosyasındaki `sbatch` komutunu ararsanız, yürütücüye gönderilen isteklerin `resourceLimits` tarafından belirtilen değerlerde sınırlandığını görürdünüz. + +??? info "Kurumsal referans yapılandırmaları" + + nf-core projesi, çok çeşitli HPC ve bulut yürütücülerini kapsayan, dünya çapındaki çeşitli kurumlar tarafından paylaşılan bir [yapılandırma dosyaları koleksiyonu](https://nf-co.re/configs/) derlemiştir. + + Bu paylaşılan yapılandırmalar, hem orada çalışan ve dolayısıyla kurumlarının yapılandırmasını kutudan çıktığı gibi kullanabilen insanlar için hem de kendi altyapıları için bir yapılandırma geliştirmek isteyen insanlar için model olarak değerlidir. + +### Özet + +Kaynak kullanımını değerlendirmek için profilleme raporu oluşturmayı ve tüm süreçler ve/veya bireysel süreçler için kaynak tahsislerini nasıl değiştireceğinizi ve HPC'de çalıştırma için kaynak sınırlamalarını nasıl ayarlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Önceden ayarlanmış yapılandırma profillerini nasıl kuracağınızı ve çalışma zamanında aralarında nasıl geçiş yapacağınızı öğrenin. + +--- + +## 6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın + +Size, üzerinde çalıştığınız projeye veya kullandığınız hesaplama ortamına bağlı olarak pipeline yapılandırmanızı özelleştirebileceğiniz birkaç yol gösterdik. + +Hangi hesaplama altyapısını kullandığınıza bağlı olarak alternatif ayarlar arasında geçiş yapmak isteyebilirsiniz. Örneğin, dizüstü bilgisayarınızda yerel olarak geliştirip küçük ölçekli testler yapmak, ardından tam ölçekli iş yüklerini HPC veya bulutta çalıştırmak isteyebilirsiniz. + +Nextflow, farklı yapılandırmaları tanımlayan herhangi bir sayıda profil ayarlamanıza olanak tanır; bunları yapılandırma dosyasını değiştirmek yerine bir komut satırı argümanı kullanarak çalışma zamanında seçebilirsiniz. + +### 6.1. Yerel geliştirme ve HPC'de yürütme arasında geçiş yapmak için profiller oluşturun + +İki alternatif profil kuralım; biri normal bir bilgisayarda küçük ölçekli yükler çalıştırmak için, burada Docker konteynerlerini kullanacağız, ve biri Slurm zamanlayıcısına sahip bir üniversite HPC'sinde çalıştırmak için, burada Conda paketlerini kullanacağız. + +#### 6.1.1. Profilleri kurun + +`nextflow.config` dosyanıza, pipeline parametreleri bölümünden sonra ancak çıktı ayarlarından önce aşağıdakileri ekleyin: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiller +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Üniversite HPC'si için kaynak sınırlamalarını da belirttiğimizi görüyorsunuz. + +#### 6.1.2. İş akışını bir profille çalıştırın + +Nextflow komut satırımızda bir profil belirtmek için `-profile` argümanını kullanıyoruz. + +İş akışını `my_laptop` yapılandırmasıyla çalıştırmayı deneyelim. + +```bash +nextflow run hello-config.nf -profile my_laptop +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Gördüğünüz gibi, bu yapılandırmalar arasında çalışma zamanında çok kullanışlı bir şekilde geçiş yapmamıza olanak tanır. + +!!! warning "Uyarı" + + `univ_hpc` profili eğitim ortamında düzgün çalışmayacaktır çünkü bir Slurm zamanlayıcısına erişimimiz yok. + +Gelecekte bunlarla her zaman birlikte olan başka yapılandırma öğeleri bulursak, bunları ilgili profile/profillere ekleyebiliriz. +Birlikte gruplandırmak istediğimiz başka yapılandırma öğeleri varsa ek profiller de oluşturabiliriz. + +### 6.2. Test parametreleri profili oluşturun + +Profiller yalnızca altyapı yapılandırması için değildir. +Başkalarının uygun girdi değerlerini kendileri toplamak zorunda kalmadan iş akışını denemesini kolaylaştırmak için iş akışı parametreleri için varsayılan değerler ayarlamak amacıyla da kullanabiliriz. +Bunu bir parametre dosyası kullanmaya alternatif olarak düşünebilirsiniz. + +#### 6.2.1. Profili kurun + +Bu bağlamda varsayılan değerleri ifade etme sözdizimi şöyle görünür, `test` olarak adlandırdığımız bir profil için: + +```groovy title="Sözdizimi örneği" + test { + params.<parametre1> + params.<parametre2> + ... + } +``` + +İş akışımız için bir test profili eklersek, `profiles` bloğu şöyle olur: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiller +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.greeting = 'greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Teknik yapılandırma profilleri gibi, istediğiniz herhangi bir rastgele ad altında parametreleri belirten birden fazla farklı profil ayarlayabilirsiniz. + +#### 6.2.2. İş akışını test profiliyle yerel olarak çalıştırın + +Kullanışlı bir şekilde, profiller birbirini dışlamaz, bu nedenle `-profile <profil1>,<profil2>` sözdizimini (herhangi bir sayıda profil için) kullanarak komut satırımızda birden fazla profil belirtebiliriz. + +Aynı yapılandırma öğeleri için değerler ayarlayan ve aynı yapılandırma dosyasında tanımlanan profilleri birleştirirseniz, Nextflow çatışmayı en son okuduğu değeri kullanarak çözecektir (_yani_ dosyada daha sonra gelen). +Çakışan ayarlar farklı yapılandırma kaynaklarında ayarlanmışsa, varsayılan [öncelik sırası](https://www.nextflow.io/docs/latest/config.html) geçerlidir. + +Önceki komutumuzda test profilini eklemeyi deneyelim: + +```bash +nextflow run hello-config.nf -profile my_laptop,test +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `hello-config.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Bu, mümkün olduğunda Docker kullanacak ve çıktıları `results/test` altında üretecektir ve bu sefer karakter komik ikili `dragonandcow`'dur. + +??? abstract "Dosya içerikleri" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Bu, test veri dosyalarını iş akışı koduyla birlikte dağıttığımız sürece, herkesin komut satırı veya parametre dosyası aracılığıyla kendi girdilerini sağlamak zorunda kalmadan iş akışını hızlıca deneyebileceği anlamına gelir. + +!!! tip "İpucu" + + Harici olarak depolanan daha büyük dosyalar için URL'lere işaret edebiliriz. + Açık bir bağlantı olduğu sürece Nextflow bunları otomatik olarak indirecektir. + + Daha fazla ayrıntı için, [Dosyalarla Çalışma](../side_quests/working_with_files.md) Yan Görevi'ne bakın + +### 6.3. Çözümlenmiş yapılandırmayı görmek için `nextflow config` kullanın + +Yukarıda belirtildiği gibi, bazen aynı parametre birleştirmek istediğiniz profillerde farklı değerlere ayarlanabilir. +Ve daha genel olarak, yapılandırma öğelerinin depolanabileceği çok sayıda yer vardır ve bazen aynı özellikler farklı yerlerde farklı değerlere ayarlanabilir. + +Nextflow, herhangi bir çatışmayı çözmek için belirlenmiş bir [öncelik sırası](https://www.nextflow.io/docs/latest/config.html) uygular, ancak bunu kendiniz belirlemek zor olabilir. +Ve hiçbir şey çakışmıyor olsa bile, şeylerin yapılandırılabileceği tüm olası yerlere bakmak sıkıcı olabilir. + +Neyse ki, Nextflow bu tüm süreci sizin için otomatikleştirebilen `config` adlı kullanışlı bir yardımcı araç içerir. + +`config` aracı mevcut çalışma dizininizdeki tüm içerikleri keşfedecek, tüm yapılandırma dosyalarını toplayacak ve Nextflow'un iş akışını çalıştırmak için kullanacağı tamamen çözümlenmiş yapılandırmayı üretecektir. +Bu, hiçbir şey başlatmak zorunda kalmadan hangi ayarların kullanılacağını öğrenmenizi sağlar. + +#### 6.3.1. Varsayılan yapılandırmayı çözümleyin + +Varsayılan olarak uygulanacak yapılandırmayı çözümlemek için bu komutu çalıştırın. + +```bash +nextflow config +``` + +??? success "Komut çıktısı" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Bu, komut satırında fazladan bir şey belirtmezseniz elde ettiğiniz temel yapılandırmayı gösterir. + +#### 6.3.2. Belirli ayarlar etkinleştirilmiş yapılandırmayı çözümleyin + +Komut satırı parametreleri sağlarsanız, örn. bir veya daha fazla profili etkinleştirme veya bir parametre dosyası yükleme, komut bunları da dikkate alacaktır. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Komut çıktısı" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Bu, birden fazla yapılandırma katmanı içeren karmaşık projeler için özellikle faydalı olur. + +### Özet + +Çalışma zamanında minimum güçlükle önceden ayarlanmış bir yapılandırma seçmek için profilleri nasıl kullanacağınızı biliyorsunuz. +Daha genel olarak, iş akışı yürütmelerinizi farklı hesaplama platformlarına uyacak şekilde yapılandırmayı ve analizlerinizin tekrarlanabilirliğini artırmayı biliyorsunuz. + +### Sırada ne var? + +Kutlayın ve kendinize büyük bir övgü verin! İlk Nextflow geliştirici kursunuzu tamamladınız. + +Ne öğrendiğinizi gözden geçirmek ve sırada ne olduğunu öğrenmek için son [kurs özeti](./next_steps.md)'ne gidin. + +--- + +## Quiz + +<quiz> +Nextflow'un otomatik olarak yüklediği yapılandırma dosyasının adı nedir? +- [ ] `config.nf` +- [ ] `pipeline.config` +- [x] `nextflow.config` +- [ ] `workflow.config` +</quiz> + +<quiz> +Aynı parametre hem yapılandırma dosyasında hem de komut satırında ayarlandığında hangisi öncelik alır? +- [ ] Yapılandırma dosyası değeri +- [x] Komut satırı değeri +- [ ] İlk karşılaşılan değer +- [ ] Hiçbiri; bir hataya neden olur + +Daha fazla bilgi: [1.1. Varsayılan değerleri `nextflow.config`'e taşıyın](#11-varsayilan-degerleri-nextflowconfige-tasiyin) +</quiz> + +<quiz> +Aynı yapılandırmada hem Docker hem de Conda etkinleştirilebilir mi? +- [x] Evet, Nextflow süreç yönergelerine bağlı olarak her ikisini de kullanabilir +- [ ] Hayır, aynı anda yalnızca biri etkinleştirilebilir +- [ ] Evet, ama sadece profillerde +- [ ] Hayır, birbirini dışlarlar +</quiz> + +<quiz> +Hem Docker hem de Conda etkinse ve bir süreçte her iki yönerge de varsa, hangisi öncelikli? +- [x] Docker (konteynerler) +- [ ] Conda +- [ ] İlk tanımlanan +- [ ] Bir hataya neden olur + +Daha fazla bilgi: [3. Bir yazılım paketleme teknolojisi seçin](#3-bir-yazilim-paketleme-teknolojisi-secin) +</quiz> + +<quiz> +Nextflow süreçleri için varsayılan bellek tahsisi nedir? +- [ ] 1 GB +- [x] 2 GB +- [ ] 4 GB +- [ ] Sınır yok +</quiz> + +<quiz> +Yapılandırma dosyasında belirli bir süreç için kaynak gereksinimlerini nasıl ayarlarsınız? +- [ ] `#!groovy processName.memory = '4 GB'` +- [ ] `#!groovy process.memory.processName = '4 GB'` +- [x] `#!groovy process { withName: 'processName' { memory = '4 GB' } }` +- [ ] `#!groovy resources.processName.memory = '4 GB'` + +Daha fazla bilgi: [5.3. Belirli bir süreç için kaynak tahsisleri ayarlayın](#53-belirli-bir-surec-icin-kaynak-tahsisleri-ayarlayin) +</quiz> + +<quiz> +Hangi komut satırı seçeneği kaynak kullanım raporu oluşturur? +- [ ] `-with-metrics` +- [ ] `-with-stats` +- [x] `-with-report` +- [ ] `-with-profile` + +Daha fazla bilgi: [5.1. Kaynak kullanım raporu oluşturmak için iş akışını çalıştırın](#51-kaynak-kullanim-raporu-olusturmak-icin-is-akisini-calistirin) +</quiz> + +<quiz> +`resourceLimits` yönergesi ne yapar? +- [ ] Minimum kaynak gereksinimlerini ayarlar +- [ ] Süreçlere kaynak tahsis eder +- [x] Talep edilebilecek maksimum kaynakları sınırlar +- [ ] Kaynak kullanımını izler + +Daha fazla bilgi: [5.5. Kaynak sınırları ekleyin](#55-kaynak-sinirlari-ekleyin) +</quiz> + +<quiz> +Nextflow'daki varsayılan yürütücü nedir? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Daha fazla bilgi: [4. Bir yürütme platformu seçin](#4-bir-yurutme-platformu-secin) +</quiz> + +<quiz> +Nextflow çalıştırırken bir parametre dosyasını nasıl belirtirsiniz? +- [ ] `--params params.json` +- [ ] `-config params.json` +- [x] `-params-file params.json` +- [ ] `--input params.json` + +Daha fazla bilgi: [1.3. Bir parametre dosyası kullanın](#13-bir-parametre-dosyasi-kullanin) +</quiz> + +<quiz> +Profiller ne için kullanılabilir? (Uygulanabilen tümünü seçin) +- [x] Altyapıya özgü ayarları tanımlamak +- [x] Farklı ortamlar için kaynak sınırları ayarlamak +- [x] Test parametreleri sağlamak +- [ ] Yeni süreçler tanımlamak + +Daha fazla bilgi: [6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın](#6-onceden-ayarlanmis-yapilandirmalar-arasinda-gecis-yapmak-icin-profilleri-kullanin) +</quiz> + +<quiz> +Tek bir komutta birden fazla profili nasıl belirtirsiniz? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Daha fazla bilgi: [6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın](#6-onceden-ayarlanmis-yapilandirmalar-arasinda-gecis-yapmak-icin-profilleri-kullanin) +</quiz> diff --git a/docs/tr/docs/hello_nextflow/index.md b/docs/tr/docs/hello_nextflow/index.md new file mode 100644 index 0000000000..577d268647 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/index.md @@ -0,0 +1,62 @@ +--- +title: Hello Nextflow +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow iş akışlarının çalıştırılmasını başlatma ve yönetme + - Nextflow tarafından oluşturulan çıktıları (sonuçlar) ve günlük dosyalarını bulma ve yorumlama + - Temel sorunları giderme + - Temel Nextflow bileşenlerinden basit bir çok adımlı iş akışı oluşturma + - Temel kanal fabrikaları ve operatör türlerini ayırt etme ve bunları basit bir iş akışında etkili bir şekilde kullanma + - HPC ve bulut dahil olmak üzere yaygın hesaplama platformlarında çalışacak şekilde iş akışı yürütmeyi yapılandırma + - Kod modülerliği ve yazılım konteynerleri dahil olmak üzere iş akışlarını FAIR yapan tekrarlanabilirlik, taşınabilirlik ve kod yeniden kullanımı için en iyi uygulamaları uygulama + audience_prerequisites: + - "**Hedef kitle:** Bu kurs, Nextflow'a tamamen yeni olan ve kendi iş akışlarını geliştirmek isteyen öğrenciler için tasarlanmıştır." + - "**Beceriler:** Komut satırı, temel betik kavramları ve yaygın dosya formatları ile biraz aşinalık varsayılmaktadır." + - "**Alan:** Alıştırmaların tümü alana bağımlı değildir, bu nedenle önceden bilimsel bilgi gerekmez." + videos_playlist: https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik +--- + +# Hello Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello Nextflow, tekrarlanabilir ve ölçeklenebilir veri analizi iş akışları oluşturmaya pratik bir giriştir.** + +Pratik örnekler ve rehberli alıştırmalar üzerinde çalışarak, süreçleri tanımlama, bunları iş akışlarına bağlama, dosya ve yazılım bağımlılıklarını yönetme, yürütmeyi zahmetsizce paralelleştirme ve farklı hesaplama ortamlarında iş akışlarını çalıştırma dahil olmak üzere Nextflow ile iş akışları geliştirmenin temellerini öğreneceksiniz. + +Nextflow ile kendi iş akışlarınızı geliştirmeye ve çalıştırmaya başlamak için gereken beceri ve özgüveni kazanacaksınız. + +<!-- additional_information --> + +## Kurs genel bakışı + +Bu kurs, bilgileri kademeli olarak tanıtan hedef odaklı alıştırmalarla uygulamalı olacak şekilde tasarlanmıştır. + +Bazı metin girdilerini alan, birkaç dönüştürme adımı çalıştıran ve dönüştürülmüş metni söyleyen bir karakterin ASCII resmini içeren tek bir metin dosyası çıktısı üreten basit bir Nextflow iş akışı geliştireceksiniz. + +### Ders planı + +Sizi kavramlar ve kodla bunaltmamak için, bunu her biri Nextflow ile iş akışları geliştirmenin belirli yönlerine odaklanan altı bölüme ayırdık. + +| Kurs bölümü | Özet | Tahmini süre | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------ | +| [Bölüm 1: Hello World](./01_hello_world.md) | Bir Nextflow iş akışını birleştirme ve çalıştırmaya dahil olan temel bileşenler ve ilkeler | 30 dk | +| [Bölüm 2: Hello Channels](./02_hello_channels.md) | Girdileri işlemek ve yürütmeyi zahmetsizce paralelleştirmek için kanalları ve operatörleri kullanma | 45 dk | +| [Bölüm 3: Hello Workflow](./03_hello_workflow.md) | Birden fazla adımı birbirine bağlamak ve adımlar arasında veri aktarımını yönetmek için kanalları kullanma | 60 dk | +| [Bölüm 4: Hello Modules](./04_hello_modules.md) | Yeniden kullanılabilirliği artırmak ve bakım yükünü azaltmak için kod modülerliği ilkelerini uygulama | 20 dk | +| [Bölüm 5: Hello Containers](./05_hello_containers.md) | Yazılım bağımlılıklarını yönetmek ve tekrarlanabilirliği artırmak için konteynerleri bir mekanizma olarak kullanma | 60 dk | +| [Bölüm 6: Hello Config](./06_hello_config.md) | Farklı hesaplama ortamlarında iş akışı davranışını özelleştirme ve kullanımı optimize etme | 60 dk | + +Bu kursun sonunda, bilimsel hesaplama ihtiyaçlarınız için tekrarlanabilir iş akışları geliştirme yolculuğunuzdaki sonraki adımları atmaya iyi hazırlanmış olacaksınız. + +Kursa başlamaya hazır mısınız? + +[Başlayın :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } + +<!-- Clearfix for float --> +<div style="content: ''; clear: both; display: table;"></div> diff --git a/docs/tr/docs/hello_nextflow/next_steps.md b/docs/tr/docs/hello_nextflow/next_steps.md new file mode 100644 index 0000000000..ba05da580b --- /dev/null +++ b/docs/tr/docs/hello_nextflow/next_steps.md @@ -0,0 +1,66 @@ +# Kurs özeti + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello Nextflow eğitim kursunu tamamladığınız için tebrikler! 🎉 + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +/// caption +:fontawesome-brands-youtube:{ .youtube } [Tüm oynatma listesini Nextflow YouTube kanalında](https://www.youtube.com/playlist?list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik) izleyin. + +:green_book: Video ile birlikte [video transkriptini](./transcripts/07_next_steps.md) okuyabilirsiniz. +/// + +## Yolculuğunuz + +Sabit kodlanmış bir komut çalıştıran çok basit bir iş akışı ile başladınız. +Altı bölüm boyunca, bu basit iş akışını kanallar, operatörler, konteynerler için yerleşik destek ve yapılandırma seçenekleri dahil olmak üzere Nextflow'un temel özelliklerini kullanan modüler çok adımlı bir iş akışına dönüştürdünüz. + +### Ne inşa ettiniz + +- Hello iş akışının son hali, metin selamlamaları içeren bir CSV dosyasını girdi olarak alır. +- Dört adım, ayrı modül dosyalarında saklanan Nextflow süreçleri (`sayHello`, `convertToUpper`, `collectGreetings` ve `cowpy`) olarak uygulanmıştır. +- Sonuçlar `results/` adlı bir dizine yayınlanır. +- İş akışının son çıktısı, büyük harfli selamlamaları söyleyen bir karakterin ASCII sanatını içeren düz metin dosyasıdır. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Her selamlamayı kendi çıktı dosyasına yazar (örn. "Hello-output.txt") +2. **`convertToUpper`:** Her selamlamayı büyük harfe dönüştürür (örn. "HELLO") +3. **`collectGreetings`:** Tüm büyük harfli selamlamaları tek bir toplu dosyada toplar +4. **`cowpy`:** `cowpy` aracını kullanarak ASCII sanatı oluşturur + +İş akışı yapılandırması, girdileri ve parametreleri esnek ve tekrarlanabilir bir şekilde sağlamayı destekler. + +### Edinilen beceriler + +Bu uygulamalı kurs boyunca şunları öğrendiniz: + +- Basit bir çok adımlı iş akışı oluşturmaya yetecek temel Nextflow bileşenlerini tanımlama ve kullanma +- Operatörler ve kanal fabrikaları gibi sonraki adım kavramlarını açıklama +- Nextflow iş akışını yerel olarak başlatma +- Nextflow tarafından oluşturulan çıktıları (sonuçlar) ve günlük dosyalarını bulma ve yorumlama +- Temel sorunları giderme + +Artık Nextflow'da kendi iş akışlarınızı geliştirmeye başlamak için temel bilgilerle donatıldınız. + +## Becerilerinizi geliştirmek için sonraki adımlar + +Bundan sonra ne yapılacağına dair en iyi 3 önerimiz: + +- [Bilim için Nextflow](../nf4_science/index.md) ile Nextflow'u bilimsel bir analiz kullanım durumuna uygulayın +- [Hello nf-core](../../hello_nf-core/index.md) ile nf-core'a başlayın +- [Side Quest'ler](../side_quests/index.md) ile daha gelişmiş Nextflow özelliklerini keşfedin + +Son olarak, Nextflow'un yaratıcıları tarafından geliştirilen, iş akışlarınızı başlatmayı ve yönetmeyi, verilerinizi yönetmeyi ve herhangi bir ortamda etkileşimli analizler çalıştırmayı daha da kolaylaştıran bulut tabanlı bir platform olan [**Seqera Platform**](https://seqera.io/)'a göz atmanızı öneririz. + +## Geri bildirim anketi + +Devam etmeden önce, lütfen kurs anketini tamamlamak için bir dakikanızı ayırın! Geri bildirimleriniz, eğitim materyallerimizi herkes için geliştirmemize yardımcı olur. + +[Ankete katılın :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/tr/docs/hello_nextflow/survey.md b/docs/tr/docs/hello_nextflow/survey.md new file mode 100644 index 0000000000..eb5cbd69c0 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/survey.md @@ -0,0 +1,9 @@ +# Geri bildirim anketi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Devam etmeden önce, lütfen eğitimi değerlendirmek, deneyiminiz hakkında geri bildirim paylaşmak ve Nextflow yolculuğunuzda size yardımcı olmak için başka neler yapabileceğimizi bildirmek için bu kısa 5 soruluk anketi doldurun. + +Bunu tamamlamanız bir dakikadan az sürecektir. Eğitim materyallerimizi herkes için geliştirmemize yardımcı olduğunuz için teşekkür ederiz! + +<div data-tf-live="01JMHYE82Z92J2Q6Q3Z7QJ1BFW"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/tr/docs/hello_nextflow/transcripts/00_orientation.md b/docs/tr/docs/hello_nextflow/transcripts/00_orientation.md new file mode 100644 index 0000000000..267250a8a1 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/00_orientation.md @@ -0,0 +1,109 @@ +# Oryantasyon - Video Metni + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/G3CV-FcV-rc?si=nyLvwhrSB2m1NPc5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli not" + + Bu sayfa yalnızca metni göstermektedir. Tam adım adım talimatlar için [kurs materyaline](../00_orientation.md) geri dönün. + +## Hoş Geldiniz + +Merhaba, Hello Nextflow'a hoş geldiniz. Benim adım Phil Ewels. Seqera'da Açık Kaynak Ürün Müdürüyüm ve bugün bu ilk Nextflow eğitim kursunda size rehberlik etmekten büyük mutluluk duyuyorum. + +Nextflow'un temellerini inceleyeceğiz, pipeline'ları nasıl yazacağınızı, çalıştıracağınızı ve yapılandıracağınızı açıklayacağız. + +Ve kendi basit çok adımlı pipeline'ınızı oluşturacaksınız. Operatörler ve channel fabrikaları gibi terimleri ele alacağız ve kursun sonunda kendi biyoinformatik pipeline'larınızı oluşturmaya başlamak için hazır olacaksınız. + +Herhangi bir sorunuz varsa, lütfen community.seqera.io üzerinden bize ulaşın. Gerçekten aktif bir Nextflow topluluğumuz var, eğitime ayrılmış bir bölüm var, bu yüzden nerede takıldığınızı bize bildirin ve birisi yardımcı olabilecektir. + +Tamam. Hadi başlayalım. + +## Eğitim Web Sitesi + +Nextflow kursları için tüm eğitim materyalleri training.nextflow.io adresinde bulunmaktadır. Web tarayıcınızda oraya gidebilirsiniz. Şimdi onu açın ve birlikte göz atalım. + +Bunu 2.1.1 sürümüyle çalıştıracağım. Burada küçük güncellemeler ve düzeltmeler yayınlıyoruz, bu yüzden biraz farklıysa endişelenmeyin, ancak materyal çok fazla değiştiyse, konuşacağım materyalin tam sürümünü seçmek için en üstteki bu sürüm seçiciyi her zaman kullanabilirsiniz. + +Daha çok açık mod insanıysanız, web sitesinin temasını buradan değiştirebilirsiniz. + +Çevirileri burada görün, ancak kayıt sırasında bu yeni materyali kapsayan gerçekten yalnızca İngilizce var. + +Ve GitHub'da eğitim web sitesi ve üzerinde çalışacağımız her şey için tüm kaynak kodunu görün. + +Buradaki ana sayfa, sahip olduğumuz tüm farklı eğitim materyali kurslarını listeler. Aşağı kaydırdığımda, burada yapacağımız Hello Nextflow kursuyla birlikte Yeni Başlayanlar için Nextflow'u göreceğiz. Benzer şekilde çalışan sahip olduğumuz diğer tüm kursları da görebilirsiniz. + +## Ortam Kurulumu + +Aslında en üstteki bu ilkini kullanarak başlayacağım, bu tüm eğitim kursları için ortak ve özellikle ortamımızı kurmakla ilgili. + +Tıkladığımda, beni bu bölüme götürüyor ve yerel olarak geliştirme için talimatları görebiliyoruz. Kendi dizüstü bilgisayarınızı kendi VS Code kopyanız ve kendi yazılım kurulumlarınızla kullanmak istiyorsanız veya çoğu insanın yapmasını beklediğimiz şey, GitHub Codespaces adlı bir şey kullanmaktır. + +Codespaces, GitHub tarafından sağlanan, bulutta bir web sunucusu çalıştıran bir hizmettir ve ona bağlanabilirsiniz. Bu sunucuda VS code yüklü, bunu web tarayıcınızda çalıştırabilirsiniz veya isterseniz yerel VS code kurulumunuza bağlayabilirsiniz. Tüm hesaplama, tüm dosyalar, tüm düzenleme uzaktan gerçekleşir, bu da ihtiyacınız olan tüm yazılımın önceden yüklenmiş geldiği ve herkes için aynı olduğu anlamına gelir. + +## GitHub Codespace Oluşturma + +İhtiyacımız olan her şeyle codespace'i oluşturmak için dokümantasyon materyalinde "GitHub Codespaces'te Aç" yazan düğmeleri arayın. Şimdi ona tıklayacağım, yeni bir sekmede açacağım. Ve bu web sayfasıyla karşılaşıyorum. Şimdi bunun nextflow-io training ile ayarlanmış olduğunu görebilirsiniz. + +Sadece yeni codespace oluştur'a tıklayabilirim. Ancak aslında Nextflow eğitimi için iki yerine dört CPU'lu biraz daha büyük bir makine kullanmayı öneriyoruz. Materyalin hangi sürümünü kullandığını değiştirebilirsiniz. Yani bu, bağlantıyı takip ettiğim dokümanların sürümü olduğu için 2.1.1'e varsayılan oluyor. Ancak istersem deponun belirli bir dalına da ayarlayabilirim. + +Şimdi codespace oluştur'a tıklayacağım. Ve benim için ortamı kurmaya başlayacak. + +## Codespace oluşturma + +Şimdi, bunu ilk kez yaptığınızda çok uzun sürecek, bu yüzden şimdi gidip bir fincan çay almanın tam zamanı. Kendinizi rahat ettirin, yanınızda oturan kişiyle sohbet edin. + +İlgileniyorsanız, kurulum günlüklerini görmek için buraya codespace oluşturuluyor'a tıklayabilirsiniz. Ve burada ihtiyacım olan her şeyi içeren bir Docker imajını çektiğini ve ortamı yapılandırdığını görebilirsiniz. + +Şimdi, bu şekilde sadece ilk kez bir codespace oluşturduğunuzda beklemeniz gerekir. github.com/codespaces adresine giderseniz, açık olan tüm farklı Codespace'leri göreceksiniz. İşte yeni oluşturduğum. Bir dahaki sefere bunu yaptığınızda, buraya gidebilir ve önceki codespace'i seçebilir ve doğrudan içine atlayabilirsiniz. Ve mevcut ortamı ısıtmak çok, çok daha hızlı bir işlemdir. Bu ayrıca VS Code'a ve dosyalara yaptığınız tüm değişiklikleri de tutacak, böylece ayrılıp geri dönerseniz ilerlemenizi kaybetmezsiniz. + +Diğer işlemleri yapmak için buradaki üç noktaya tıklayabilirsiniz. Örneğin, iki CPU ile yapılandırdıysanız ve şimdi dört istiyorsanız, makine türünü değiştirebilirsiniz. Veya sıfırdan ve temiz başlamak istiyorsanız, codespace'i silebilirsiniz. + +## VS Code'a Giriş + +Tamam, Codespaces ortamımı kurmayı bitirdi ve şimdi web tarayıcısında VS Code ile karşılaşıyorum. + +VS code'a alışkınsanız. Bu çok tanıdık gelecek, daha önce kullanmadıysanız, oldukça basittir. Sayfanın farkında olmanız gereken birkaç farklı bölümü var. + +Burada solda yan çubuğumuz var. Eğitim deposundan GitHub deposundaki tüm farklı dosyalarla Explorer'ın kurulduğunu görebilirsiniz. + +Soldaki bu düğmelerde farklı araçlar olabilir. Yan çubukta. Projedeki tüm dosyaları arayabilirim. Git ile çalışabilirim, GitHub ile çalışabilirim, bunun gibi tüm farklı şeyler. + +En üstte burada ana menü var. Dosya gezgini çoğunlukla burada sahip olacağımız şey ve bu dosyalardan herhangi birine sağ tıklayabilir ve beklediğiniz normal şeyleri yapabilirsiniz. Kes kopyala gibi bazı uyarıları tıklamanız gerekebilir ve yerel makinenize de indirebilirsiniz. + +Codespace yüklendiğinde, bize bu ana alanda markdown dosyasının bir önizlemesini verir. Bu, github.com'da oluşturulanla aynı. Bunu kapatabilir ve Readme dosyasına çift tıklarsam, kod düzenleyicide kod olarak açıldığını göreceksiniz ve diğer herhangi bir dosyada olduğu gibi, bu kodu doğrudan düzenleyebiliriz. + +Son olarak burada altta terminal penceremiz var. Oluşturulurken günlüklere bakıyordum, bu yüzden gösterdiği mevcut şey bu. Ayrıca yeni bir terminal oturumu başlatmak için bu artı düğmesine basabilirim. Bu benim makinemde çalışmıyor. Unutmayın, bu bulutta çalışıyor ve ikinin derinliğinde tree üç yaparsam, solda olan tüm aynı dosyaları burada göreceksiniz. + +## Sadece "hello-nextflow" dosyalarını gösterme + +Bu GitHub deposu, sadece yaptığımız değil, tüm farklı eğitim setlerini içerir. İsterseniz, sadece Hello Nextflow klasörüne odaklanabilirsiniz. Bunu biraz temizlemenin bir yolu, menü dosyasına gitmek ve ardından çalışma alanına klasör eklemektir. + +Bunu tıklıyoruz, training'e gidiyoruz. Hello nextflow, ve ekle'ye tıklayın. Ekranınızı yenileyecek. Ve sonra Explorer'da, şimdi iki farklı çalışma alanımız var, daha önce training için sahip olduğumuz ve sadece Hello Nextflow ile bir tane. + +İsterseniz, training'e sağ tıklayabilir ve çalışma alanından klasörü kaldır'a tıklayarak yan çubuktan tamamen kaldırabilirsiniz. + +Şimdi yan çubukta sadece bu belirli eğitim kursu için dosyalarımız var. O uyarıyı gizleyebilir ve şimdi burada terminalde de aynı şeyi yapabilir ve dizin değiştirmek için CD yapabilirim. Hello, Nextflow. Ve yine, yan çubukta olan aynı dosyalara burada sahibiz. + +## Hello Nextflow: dosyalar + +Hello Nextflow kursu için bu dosyalara bakıyoruz. + +Nextflow için olan bir dizi .nf dosyamız var ve eğitim kursunun her bölümü için bu dosyalardan biri var. Bu dosyalar üzerinde çalışacağız ve alıştırmalarda onları değiştireceğiz. + +Ayrıca sadece bu ortamda Nextflow'u çalıştırmak için temel yapılandırma ayarlarına sahip bir nextflow.config dosyamız var, bu noktada gerçekten endişelenmenize gerek yok. Veri işlemek için kullanacağımız bir greetings.csv dosyası, bu kursun bir sonraki bölümünde tanıtılacak ve altıncı bölümde kullanılacak bir test-params.json dosyası, şimdilik göz ardı edebilirsiniz. + +Bu Nextflow dosyaları sadece her alıştırmanın başlangıcıdır. Bitirdiklerinde nasıl görünmeleri gerektiğini görmek isterseniz, bir solutions dizinine gidebilirsiniz ve eğitim kursunun her bölümü için cevaplar vardır, böylece hedeflediğiniz şeyin çalışan bir sürümünü görebilirsiniz. + +## Terminal açma + +Herhangi bir noktada terminali kapatırsanız ve nasıl geri döneceğinizi hatırlayamazsanız, endişelenmeyin. En üstteki sağdaki bu düğmeler, çalışma alanında farklı panelleri açar ve kapatır. Bu yüzden alt panel için buna tıklayın ve yeniden görünecektir. Ve burada terminal seçildiğinden emin olun. Terminali tam ekran yapmak için buradaki bu düğmeye, sağ taraftaki terminaldeki oka da tıklayabilirsiniz. + +Bunu çok sık yaptığımı göreceksiniz çünkü metni okuyabilmeniz için VS Code'u yakınlaştırdım. Ekran boyutunuza bağlı olarak, bunu yapmanız gerekebilir veya gerekmeyebilir. Aynı şey yan paneli küçültmek için de geçerlidir. + +Tamam. Ortam için bu kadar yeterli sanırım. Başlamaya hazırız. Bir sonraki videoda birinci bölüm için benimle buluşun. + +[Sonraki video metni :octicons-arrow-right-24:](01_hello_world.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/01_hello_world.md b/docs/tr/docs/hello_nextflow/transcripts/01_hello_world.md new file mode 100644 index 0000000000..98b916b56b --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/01_hello_world.md @@ -0,0 +1,245 @@ +# Bölüm 1: Merhaba Dünya - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/8X2hHI-9vms?si=F0t9LFYLjAWoyRXj&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa yalnızca transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../01_hello_world.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca bilgilendirme amaçlıdır ve materyallerdeki tüm bölüm numaralarını içermeyebilir. + +## Hoş geldiniz + +Merhaba, Merhaba Nextflow'un Birinci Bölümüne hoş geldiniz. + +Altı bölümden oluşan bu kursun ilk bölümünde, Nextflow'un en temel konularına gireceğiz. Terminalde bazı komutlar çalıştırarak başlayacağız ve ardından bu Bash komutlarını alıp bunları bir Nextflow betiğine nasıl dönüştüreceğimizi göreceğiz. + +İlk Nextflow işlem hattımızı çalıştırmayı deneyeceğiz, Nextflow'un ne yaptığını, nerede çalıştığını, hangi dosyaları oluşturduğunu ve bu dosyaların amacının ne olduğunu göreceğiz. + +Pekala, hadi başlayalım. + +## training.nextflow.io + +Öncelikle, training.nextflow.io adresine gidin. Daha önce olduğu gibi, tüm materyaller burada yazılı ve ben bunları adım adım çalışacağım. Eğitimin adımlarını yaparken ekranımı göstereceğim, ancak söylediğim her şey eğitim materyalinde yazılı, böylece kendi hızınızda takip edebilir ve hepsini orada yazılı bulabilirsiniz. + +Bu videonun ayrıca video altyazıları etkinleştirilmiş, bu yüzden bunları açıp söylediklerimi tam olarak takip edebilirsiniz. + +Tamam, hadi Merhaba Nextflow'a gidelim. Bugün yapacağımız kurs bu ve oryantasyonu ilk videoda zaten yaptık, bu yüzden doğrudan birinci bölüme geçeceğiz. Merhaba Dünya. + +Tamam, şimdi bu eğitim materyalinden ayrılıp Code Spaces ortamıma geçeceğim. Bu, ilk videoda kurduğumuz şey. Umarım sizin sisteminizde de buna çok benzer bir şey vardır. VS Code kullanıyorum ve eğitim materyaline bakıyorum ve hello Nextflow dizinine geçiş yaptım. + +## 0. Isınma: Merhaba Dünya'yı doğrudan çalıştırın + +Tamam. Herkese tanıdık gelecek birkaç temel şeyle başlayalım. Terminalde çok basit bir komut yazarak başlayacağım. Burada 'echo Merhaba Dünya!' yazacağım, enter'a basacağım ve sürpriz yok, terminal istediğimi yapıyor ve o dizgiyi döndürüyor. Merhaba dünya. + +Tamam, sonra o komutu geri almak için yukarı tuşuna basacağım ve biraz daha düzenleyeceğim. Bu sefer çıktıyı bir dosyaya yönlendirelim. Bunun yerine output.txt dosyasına yazacağım ve enter'a basacağım, bu sefer terminalde hiçbir şey yok çünkü çıktı terminale gelmedi. Dosyaya gitti. + +Sonra o dosyayı 'cat output.txt' yaparak okuyabilirim, dosya adını otomatik genişletmek için tab tuşuna basıyorum ve işte. Dosya orada. + +Bu dosyayı VS Code'daki kenar çubuğunda, dosya gezgininde de görebilirim. Çift tıklayıp burada açabilirim. Hiçbir şeye tıklamadan VS Code'da açmak isterseniz, "code" ve ardından "output.txt" de yapabilirsiniz ve aynı şeyi yapar. + +Harika. Bu ilk adım. Çok basit. + +## 1. Merhaba Dünya iş akışı başlangıç betiğini inceleyin + +Tamam. Şimdi aynı şeyi yapacağız, ancak doğrudan terminalde değil, Nextflow'da. + +Başlangıç için ilk örnek betiği kullanacağız, bu dosyanın adı Merhaba Dünya. Terminalde görmek için "ls" yapabilirim ve Mac'teyim, bu yüzden o dosyayı açmak için command tuşuyla tıklayabilirim veya kenar çubuğunda burada çift tıklayabilirdim. + +Bu dosyada görebileceğimiz birkaç şey var. En üstte, bunun bir Nextflow dosyası olduğunu ve bu şekilde çalıştırılabileceğini söyleyen bir hash ifadesi var. Burada açık gri renkte, yürütmeyi etkilemeyen ve sadece betiği okumamıza yardımcı olan bazı yorumlar var. + +Ve sonra iki ana yapı var. Burada bir process ve bir workflow var. + +Nextflow'daki process'ler, işlem hattının adımlarıdır. Aslında mantığı uygulayan ve işlemi yapan parçalardır. + +Alttaki workflow ise bu process'leri birbirine bağlar ve iş akışının mantığını, her şeyin birbirine nasıl bağlandığını yönetir. + +Bir process'e bakarak başlayacağız. Birazdan workflow'a geri döneceğiz. + +## 1.2 Process tanımı + +Her process, process anahtar kelimesiyle başlar. Bir adı vardır ve sonra bazı süslü parantezler vardır ve bu süslü parantezlerin içindeki her şey o tek process'tir. + +Bir process'in script bölümü olmalıdır ve burada, hesaplama ortamında gerçekten yürütülen kodun parçası olan çok satırlı bir dize içinde bir bash kod parçası bulunur. + +Burada ayrıca Nextflow'a betik tarafından hangi dosyaların oluşturulmasının beklendiğini söyleyen bir output ifadesi var. Buradaki çıktının, Nextflow'a bunun bir değer veya dize değil, bir dosya olduğunu söyleyen path anahtar kelimesine sahip olduğunu unutmayın. + +Script bloğu içinde, bu sadece normal bir bash ifadesidir ve terminalde yazdığımızla tamamen aynıdır. output.txt adlı bir dosyaya merhaba dünya yazdırıyoruz. Bu output.txt daha sonra output tanımı tarafından yakalanır. Output tanımı aslında hiçbir şey yapmıyor. Sadece Nextflow'a neyi bekleyeceğini söylüyor ve bu dosya oluşturulmazsa, Nextflow bir hata verecektir. + +Bu örneğin harika olmadığını unutmayın çünkü dosya adını burada sabit kodladık, output.txt ve output.txt. Bunlardan biri değiştirilirse, bu iş akışımızda bir hataya neden olur. + +Bunu değişkenlerle yapmanın daha iyi bir yolu var, bunu birazdan ele alacağız. + +## 1.3 Workflow tanımı + +Tamam. Workflow'a geçersek, bir yorumum olduğunu ve sonra sayHello adlı process'i çalıştırdığımızı görebiliriz. Bu, yukarıdaki ile aynı anahtar kelimedir. Bu, bir iş akışının olabileceği kadar basittir. Değişken girdi olmadan tek bir process çağırıyoruz, bu yüzden onu başka bir şeye bağlamıyoruz. Bu kursun ilerleyen bölümlerinde, değişken girdiler kullanarak ve kanallarla bağlantı kurarak bunu nasıl daha güçlü hale getireceğimizden bahsedeceğiz. + +## 2. İş akışını çalıştırın + +Tamam, ihtiyacımız olan tek şey bu. Hadi çalıştırıp ne olacağını görelim. Terminali temizleyeceğim ve sonra "nextflow run" yapacağım ve dosya adını çağıracağım, bu da hello-world.nf. Bir Nextflow işlem hattını çalıştırmak için ihtiyacımız olan tek şey bu. Bu işlem hattı herhangi bir girdi almıyor, bu yüzden başka argümanlara ihtiyacımız yok. + +Hadi enter'a basalım ve ne olacağını görelim. + +Tamam. Umarım buna benzer bir çıktınız olmuştur. Nextflow'un çalıştığını ve hangi sürümü kullandığını söyleyen birkaç bilgi parçamız var. Hangi betiğin başlatıldığını söylüyor ve bu belirli iş akışı çalıştırması için rastgele oluşturulmuş bir ad veriyor. Bu durumda, benimki "gloomy_crick" olarak adlandırıldı. + +Bunun en önemli kısmı, işlem hattında hangi adımların çalıştığını söylemesidir. sayHello adlı process'imizin çalıştığını görebilirsiniz ve bir kez çalıştı ve yüzde yüz tamamlandı. + +Buradaki bu kısım, o belirli iş akışı görevi için hash'tir. Her process bir veya daha fazla kez çalışır ve bu çalıştırmaların her birine görev denir. + +## 2.2. Çıktıyı ve kayıtları work dizininde bulun + +Her görev, çalıştığı kendi izole dizinine sahiptir, bu nedenle iş akışının geri kalanının yürütülmesinden ayrıdır. Bu hash, work dizinindeki dosya yapısına karşılık gelir. "tree work" yaparsam, a0 ve sonra kısa hash'in daha uzun bir versiyonunu ve sonra output.txt dosyamızı görebiliriz. Bunu kenar çubuğunda da görebilirsiniz. + +Kenar çubuğunda burada bazı ek dosyalar olduğunu görebilirsiniz. Bunların terminalde görünmemesinin nedeni, bunların gizli dosyalar olmasıdır, nokta ile başlarlar. Ve gerçekten de, "tree -a" (tümü için) ve "work" yaparsam, onları burada görebiliriz. + +Bu nokta dosyaları, Nextflow'un oluşturduğu her work dizininde bulunur ve her birinin biraz farklı bir görevi vardır. İlk olarak .command.begin, Nextflow için çalıştırılmadan önce görevi kuran bazı talimatlar içerir. .command.run, Nextflow'un kendisi tarafından yürütülen gerçek talimatlardır. Sonra .command.sh muhtemelen en ilginç olanıdır. Bu, process bloğu betiğimizden çözülen betiktir. + +Açarsam, output.txt dosyasına "echo Merhaba Dünya" yaptığımızı görebilirsiniz. Bu, bu durumda process'imizle tamamen aynıdır, ancak Nextflow kodumuzdaki herhangi bir değişkenimiz varsa, her görevin farklı bir .command.sh'si olacak ve bu değişkenlerin nasıl çözüldüğünü görebilirsiniz. + +Diğer dosyalar görevin nasıl yürütüldüğüyle ilgilidir. Yani .command.err, .log ve .out standart hata, standart çıktı ve ikisinin birleşimidir. Ve .exitcode, Nextflow'a bu görevin hangi çıkış koduyla yürütüldüğünü, başarılı olup olmadığını söyler. + +Son olarak, output.txt dosyamız var ve evet, "Merhaba Dünya" beklediğimiz şey bu ve oluşturulan bu. + +Tamam, harika. Bu sizin ilk Nextflow çalıştırmanızdı. Tebrikler. Gerçekten bu kadar basit. + +Sırada, her seferinde işlem hattının nasıl çalışacağı konusunda bir değişiklik yapmak istediğimizde kodu düzenlemek zorunda kalmamak için bunu biraz daha rahat nasıl yapacağımıza geçeceğiz. + +## 3. İş akışı çalıştırmalarını yönetin + +Bu dizin yapısı, tüm görevleri ayrı tutmak ve her şeyi düzenli tutmak için harikadır, ancak tabii ki çıktı dosyalarınızı bulmak çok kullanışlı değildir. İşlem hattınızın sonuçlarını bulmaya çalışarak bir sürü iç içe dizin arasında dolaşmak istemezsiniz. + +## 3.1. Çıktıları yayınlayın + +İyi haber şu ki yapmanız gerekmiyor. Work dizinleri gerçekten sadece Nextflow'un kendisinin kullanması içindir. Bu yüzden yapacağımız şey, Nextflow için "publishDir" adlı bir fonksiyon kullanmak. + +İş akışımıza geri dönüyoruz, process'e gidiyoruz. Burada directive adı verilen yeni bir ifade ekleyebiliriz. Nextflow'un bu işlevselliğin nasıl çalıştığını artıran process'lerin üstünde bulunan bu şeylere böyle der ve kullanacağımız publishDir adındadır. + +Burada yazmaya başladığımı görebilirsiniz ve VS Code için Nextflow uzantısı bana directive'i önerdi, bu yüzden sadece enter'a basabilirim. + +Tamam, bunu "results" adlı bir dizinle takip edeceğim ve çıktı dosyalarını oraya kopyalamasını söyleyeceğiz. Bu yüzden mode copy diyeceğim. Harika. Kaydet'e basacağım ve iş akışını tekrar çalıştıralım. + +nextflow run hello-world.nf + +Tamamen aynı şekilde çalışıyor. Bu sefer biraz farklı bir hash'imiz olduğunu unutmayın. Nextflow, iş akışını her çalıştırdığınızda farklı bir hash kullanır. Ve sonuç olarak farklı bir work dizinleri setimiz var. Alanlar, EB adında olanlar, ancak tüm dosyaların aynı olduğunu görebilirsiniz. Ancak, bu sefer yeni olan şey, "results" adlı bir dizinimizin de olması. + +Burada "results" içinde çıktı dosyamız var. Nextflow'a bunu söyledik. Sonuç dosyalarını "results" adlı bir dizine kaydet ve oraya kopyala dedik. Ve bu şimdi bulmak çok daha kolay. İş akışını başlattığımız yerin yanında orada ve Nextflow'un gerçek yürütmeyi nerede veya nasıl çalıştırdığından bağımsız olarak, tüm farklı dosyalar orada istediğiniz gibi organize edilebilir. + +publishDir'in sembolik bağlantıları işleyebildiğini unutmayın, bu paylaşılan bir dosya sisteminde çalışıyorsanız ve alanda tasarruf etmek istiyorsanız iyidir. Ayrıca, bir process tarafından oluşturulan tüm dosyaları çıktı olarak tanımlamanız gerekmez. + +Nextflow yalnızca bu output bloğunda tanımlanan şeyleri kopyalayacaktır. Bu nedenle, bu process'in aşağı akışında gerekmeyen adım tarafından oluşturulan ara dosyalarınız varsa, bunları çıktıda tanımlamazsınız ve publishDir'de görünmezler. Bu nedenle, bu bir işlem hattından çıktı dosyalarınızı temiz tutmanın ve iş yerinin bittiği anda ara dosyaları kolayca silmenin bir yoludur. + +Hızlı bir not. Workflow output definitions adında, sonunda publishDir'in yerini alacak yeni Nextflow sözdizimi geliyor. Bu bize iş akışından tüm çıktıları workflow bloğunun içinde işlem hattı düzeyinde tanımlamanın bir yolunu veriyor. Denemek isterseniz bu Nextflow dokümanlarında açıklanmıştır. Ancak şimdilik, publishDir bir süre daha kullanılacak, bu yüzden 2025 eğitiminde hala bu var. + +## 3.2. İş akışını -resume ile yeniden başlatın + +Tamam. Work dizininin burada şimdi iş akışını her çalıştırdığımızda farklı hash'lerle iki sonuç setine sahip olduğunu belirttim. Bu iyi. Ancak bazen gerekli olmadığında her seferinde adımları yeniden hesaplamak istemeyiz. + +Belki iş akışınızı yinelemeli olarak oluşturuyorsunuz ve adımlar ekliyorsunuz ve ilk adımların önbelleğe alınmış sürümleri yeniden kullanmasını istiyorsunuz. Veya belki hesaplama sisteminizde iş akışınızın ortasında bir şeyler ters gitti ve kaldığı yerden devam etmesini istiyorsunuz, ancak zaten tamamladığı adımları atlamasını istiyorsunuz. + +Nextflow'un bunun için resume adında yerleşik işlevselliği var. Hadi deneyelim. Öncelikle, ne olduğunu hatırlayabilmemiz için work dizinine bir göz atacağım. + +Ve sonra "nextflow run hello-world.nf" yapacağım ve burada tek bir komut ekleyeceğim, "-resume". + +Tek çizgi olduğuna dikkat edin, bu gerçekten önemli. Çalıştıracağım ve çıktı temelde tamamen aynı görünecek, birkaç küçük farkla. + +Burada gri renkte "cached" yazıyor. Bu, Nextflow'un bu sefer görevi çalıştırmadığı anlamına gelir. Gereksinimlerimizle eşleşen bir şey buldu ve adımı yeniden çalıştırmak yerine bu çıktıları doğrudan yeniden kullandı. + +Ve evet, buradaki hash'e bakarsanız, bunun önceki bir çalıştırmadan sahip olduğumuz mevcut hash'e karşılık geldiğini görebilirsiniz. + +## 3.3. Eski work dizinlerini silin + +Tamam. Ancak yinelemeli olarak geliştirme yapıyorsanız, bu iş akışı dosyalarının çoğunu oluşturacaksınız. Alanda sıkıntı çekiyorsanız bu bir sorun olabilir. + +Nextflow, birkaç yardımcı komutla bu work dizinlerini temizlememize yardımcı olabilir. "nextflow log" yaparsam. Bu bana bu dizinde yaptığım tüm farklı iş akışı çalıştırmalarının bir listesini verir ve burada çalıştırma adları var. Çalıştırdığımız ilk olan gloomy quick'i görebilirsiniz ve sonra bu iki yeni. + +Şimdi o adı alıp "nextflow clean" komutuyla kullanabiliriz. Tek bir çalıştırma adı belirtebilirim. Ya da daha da iyisi, Nextflow'a "-before" ile tek bir iş akışı adından önceki her şeyi silmesini söyleyebilirim ve "stupefied_shaw" yazacağım. Bu benim en son çalıştırmam, "-n". + +"-n" komutu Nextflow'a bunu gerçekten hiçbir şeyi silmeden kuru bir çalıştırma olarak yapmasını söyledi ve hangi hash dizinlerinin kaldırılmış olacağını söylüyor. Evet, bu sadece ilk çalıştırmadan olan. İkinci çalıştırmaların her ikisi de aynı hash dizinini kullanıyor. + +Yine çalıştıracağım, ama şimdi kuru çalıştırma için "-n" yerine, "-f" yapacağım, force için ve o hash dizinini kaldırdı. Şimdi "tree work" yaparsam, sadece bu çıktı dosyasının kaldığını görebiliriz. + +Harika. Böylece orada bir sürü disk alanı temizlemeyi başardık. + +Work dizinlerini silerken dikkat edilmesi gereken birkaç şey, sonuçlar dizininize sembolik bağlantı şeyleri yaparsanız, o sembolik bağlantı kaynakları şimdi silinecek ve sonuçlarınız sonsuza kadar gidecek. Bu yüzden copy modunu kullanmak daha güvenli bir şeydir ve genel olarak önerdiğimiz şeydir. + +İkincisi, Nextflow'un resume işlevselliği bu work dizinlerine dayanır. Bu nedenle bunları silerseniz ve Nextflow'u tekrar çalıştırırsanız, resume işlevselliği artık çalışmayacaktır. Bu nedenle, hangi şeylere ihtiyacınız olabileceğini veya olmayabileceğini takip etmek size kalmış ve yalnızca bunun güvenli olduğundan emin olduğunuzda şeyleri silin. + +Yapabileceğimiz diğer şey, iş akışı çalıştırmamızı bitirdikten ve artık ihtiyacımız olmadığından emin olduğumuzda tüm work dizinini silmektir. + +Yani "rm -r work" yapabilirim. Orada önemli bir şey olmadığını biliyorum. Results dizininde kopyaladığımız yerde önem verdiğim sonuçlarım var. Ve bu yüzden work dizinini silmek güvenliydi. Bu yaklaşımlardan hangisini kullanacağınız size kalmış. + +## 4. Komut satırında iletilen değişken girdiyi kullanın + +Tamam, sırada ne var? İş akışı betiğimizde burada output.txt dosyasında bazı değerleri sabit kodladığımızı ve bunun için daha iyi bir yol olabileceğini belirtmiştim. + +Hadi buna başlayalım. Yapacağımız üç şey var. Process'e yeni bir girdi ekleyeceğiz. Process betiğine bu girdiyi nasıl kullanacağını söyleyeceğiz ve sonra Nextflow'u çalıştırırken komut satırında bir flag ile dinamik olarak kullanabilmemiz için iş akışında bunu bağlayacağız. + +İlk önce öncelikler. Hadi buraya bir input bloğu ekleyelim. Çıktı ile aynı. Bu, process için yeni bir bölüm ve "val greeting" diyeceğim. + +Burada "val" dediğime dikkat edin, bu bunun bir path değil, bir değişken olduğunu söylüyor. + +Sonra betiğe inebilirim ve sonra bu sabit kodlanmış metni buradan çıkarıp $greeting yapabilirim. Bu diğer programlama dilleri gibi çalışır. Burada bir değişken tanımlıyoruz ve bu script bloğu içinde ona başvuruyoruz. Nextflow bu process'i çalıştırdığında, değişken enterpolasyon yapılacak. Ve o .command.sh dosyasına gittiğimizde, bunun yerine gerçek sabit kodlanmış dizgiyi göreceğiz. + +## 4.1.3. Bir CLI parametresi ayarlayın ve bunu process çağrısına girdi olarak sağlayın + +Tamam, ama değişkeni nerede sağlıyoruz? Sonra workflow bölümüne gidiyoruz ve buradaki uzantının artık bir girdi beklediğini söylediğini ve bana bir uyarı verdiğini görebilirsiniz. + +Şimdi, yapabileceğimiz en basit şey sadece sabit kodlamak. "Merhaba Dünya" yazabilir ve o dize girdisini process'e sağlayabilirim. Ama yine, bu gerçekten hiçbir sorunu çözmezdi. Her seferinde bir şeyi değiştirmek istediğimizde yine geri dönüp işlem hattı kodunu düzenlemek zorunda kalırdık, bu da iyi değil. + +İyi haber şu ki Nextflow'un parametreler adı verilen komut satırı argümanlarını işlemek için yerleşik bir sistemi var. Bu yüzden bunun yerine, params adında bu özel değişkenlerden birini kullanabilirim ve istediğim gibi adlandırabilirim, ama iş akışı mantığıyla eşleşmesi için greeting diyeceğim. + +Kaydet'e bas ve bununla ne yapabileceğimizi görelim. + +Terminale geri dönersem. Yani "nextflow run hello-world.nf" yapıyoruz. Daha önce olduğu gibi, ancak temel fark --greeting yapmamız + +Burada iki çizgi olduğuna dikkat edin çünkü bu bir parametredir. Daha önce iş akışını devam ettirdiğimizde, bu tek bir çizgiydi. Bunun nedeni resume'un temel bir Nextflow seçeneği olması ve bunun işlem hattımıza özgü bir parametre olmasıdır. + +İkisini karıştırmayın. Bunu yapmak kolay. --resume yerine --resume yapsaydınız, o zaman bu "params.resume" olurdu, bu da hiçbir şey yapmazdı. Aynı şekilde, burada tek bir çizgi yapsaydınız, Nextflow bunu anahtar bir argüman olarak tanımazdı. + +Yani params.greeting'e karşılık gelen --greeting. + +Şimdi bunu istediğim herhangi bir metinle takip edebilirim. Yani şu anda İsveç'teyim, bu yüzden "Hej världen" diyeceğim. + +Hadi çalıştıralım, ne olacağını görelim, hakikatin anı. + +Tamam, daha önce olduğu gibi, process'in tekrar çalıştığını görebilirsiniz, tek bir yürütmeyle sayHello. + +Bu, publishDir "results" dizinindeki dosyanın üzerine yazmış olacak. Bu yüzden dosyaları yeniden çalıştırırken dikkatli olun çünkü yayınlanan havadaki şeyler üzerine yazılacak. + +Şimdi "code results/output.txt" yapabilirim ve evet, çıktımız güncellendi ve şimdi "Hej världen" yazıyor. + +## 4.2. Komut satırı parametreleri için varsayılan değerleri kullanın + +Tamam, bu harika. Ancak şimdi sorun, iş akışımızın her zaman bu parametreyi tanımlamamıza bağımlı olması ve iş akışınız için şeylerin mantıklı bir şekilde çalışması için varsayılanları geçersiz kılmadığınız sürece mantıklı varsayılanlara sahip olmanın güzel olmasıdır. + +Bunu yapma şeklimiz, iş akışı betiğimizde parametre için varsayılan bir değer ayarlamaktır. + +Bu yüzden hello-world.nf dosyama geri dönersem, workflow'un hemen üstündeki betiğe girebilirim, "params.greeting" yazabilir ve bunu diğer değişkenler gibi tanımlayabilirim. Hadi buraya bir dize koyalım ve "Holà mundo!" diyelim. + +Şimdi bu parametrenin tanımlanmış varsayılanı var, burada kullanılacak, veya hala --greeting ile komut satırında geçersiz kılabiliriz, daha önce yaptığımız gibi. + +Hadi çalışıp çalışmadığını kontrol edelim. "nextflow run hello-world.nf" + +Bu sefer komut satırı argümanı yok ve doğru şeyi yapıp yapmadığını kontrol edin. + +"code results/output.txt". Ve işte orada. Varsayılanımızı aldık. + +Tamam, tekrar deneyelim, size yalan söylemediğimi kontrol edelim. Tekrar çalıştıralım, ama --greeting yapalım ve eğitim materyalinden örneği kullanalım, "Konnichiwa!" diyelim. + +İş akışını yeniden çalıştırır ve evet, üstteki çıktı dosyamız komut satırında sağladığımız yeni değerle güncellendi. + +Harika. Bu, herhangi bir Nextflow iş akışı yazmak için gerçek merkezi bir yönüdür. İşlem hattı kodunuzda mantıklı varsayılanlar tanımlamak, ancak terminalde komut satırı argümanlarına sahip olarak son kullanıcı için yapılandırmayı çok kolay hale getirmek. + +Son kullanıcının yapılandırmayı birden fazla farklı yerde geçersiz kılabileceğini unutmayın. Yaptığınız her Nextflow çalıştırmasına uygulanan ana dizininizde bir yapılandırma dosyanız olabilir. Başlatma dizininde bir yapılandırma dosyanız olabilir. İşlem hattı dizininde bir yapılandırma dosyanız olabilir. Tüm bu farklı yapılandırma konumları, Nextflow dokümanlarında açıklanan belirli bir sırayla yüklenir. + +Tamam, birinci bölümün sonu bu. Nextflow'da bir process ve workflow ile ilk iş akışı betiğimize sahip olduk. Girdilere, çıktılara, betiklere ve yayınlamaya ve parametreleri ve bir girdi kanalını process'imize nasıl bağlayacağımıza baktık. + +Tebrikler, Nextflow kodu yazmaya doğru ilk adımınız tamamlandı. + +Biraz mola verin ve birkaç dakika sonra ikinci bölümde görüşürüz. + +[Sonraki video transkripti :octicons-arrow-right-24:](02_hello_channels.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/02_hello_channels.md b/docs/tr/docs/hello_nextflow/transcripts/02_hello_channels.md new file mode 100644 index 0000000000..e0eb73568b --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/02_hello_channels.md @@ -0,0 +1,279 @@ +# Bölüm 2: Merhaba Kanallar - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/lJ41WMMm44M?si=xCItHLiOQWqoqBB9&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa yalnızca transkripti göstermektedir. Adım adım talimatların tamamı için [eğitim materyaline](../02_hello_channels.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca yönlendirici amaçlıdır ve materyallerdeki tüm bölüm numaralarını içermeyebilir. + +## Hoş Geldiniz + +Merhaba, Merhaba Nextflow'un ikinci bölümüne hoş geldiniz. + +Bu bölümün adı Merhaba Kanallar. Nextflow'un bu temel parçası hakkında konuşacağız. + +Kanallar, pipeline'ınızdaki farklı adımları birbirine bağlayan şeylerdir, verilerinizin ve mantığınızın iş akışınız boyunca akmasının yoludur. + +Pekala, hadi başlayalım. + +training.nextflow.io adresine giderek başlayalım + +Yan çubukta Merhaba Nextflow'u bulun ve ikinci bölüme tıklayın. Merhaba Kanallar. + +Tüm materyal burada yazılı, böylece kendi hızınızda ilerleyebilir ve kaçırmış olabileceğiniz herhangi bir şeyi yakalayabilirsiniz. + +Web sitesini açtıktan sonra, Codespaces'i yükleyebilirsiniz ve son bölümün sonunda kaldığımız yerden devam edeceğiz. + +## 0. Isınma: hello-channels.nf dosyasını çalıştırın + +Bu bölüm için farklı bir dosyayı düzenleyeceğiz. Bu dosyanın adı Merhaba Kanallar, böylece yan çubukta bulabilirsiniz, açmak için çift tıklayın. + +Şimdi, eğer birinci bölümden yeni geldiyseniz, bu dosya size çok tanıdık gelecektir. Buradaki başlangıç noktası temelde birinci bölümü bitirdiğimiz yer, sayHello adlı işlememiz, girdimiz, çıktımız, publishDir'imiz ve params.greeting'imiz ve basit iş akışımız ile. + +Yeni bir dosya ile başlıyoruz, bu yüzden herkes için eşit bir zemin, ama isterseniz önceki dosyanızla devam edebilirsiniz. + +Not edin, temiz bir başlangıç noktası olması için buradaki tüm .nextflow\* dosyalarını ve work dizinlerini de sildim. Bunu yapıp yapmadığınız önemli değil, size kalmış. + +Pekala. Bu pipeline'ın beklediğimiz gibi çalıştığını kontrol ederek başlayalım. Burada terminali açacağım. + +"nextflow run hello-channels.nf" yazıp enter'a basıyorum. + +O küçük iş akışını çalıştıracak, sayHello adımımızı çalıştıracak, o hash ile bir work dizini oluşturacak ve işte results klasörümüz ve varsayılan params.greeting'imizden çıktı dosyamız. + +Bu harika. Birinci bölümle tamamen aynı, beklediğimiz gibi çalışıyor. + +## 1. Değişken girdileri bir kanal aracılığıyla açıkça sağlayın + +Birinci bölümde, aslında zaten kanalları kullanıyordunuz, sadece farkında değildiniz. Burada bir string belirttiğimizde, Nextflow otomatik olarak bizim için o string'in etrafında bir kanal oluşturdu, sadece bir process çağırdığımızı bildiği için, bu yüzden bir girdi kanalına ihtiyacımız vardı. + +Yapacağımız ilk şey, kanalın kendisini yazarak bunu açık hale getirmek. + +## 1.1. Bir girdi kanalı oluşturun + +Bu yüzden betiğin altındaki workflow'a gideceğim ve greeting_ch diyeceğim. Bu, bir değişken adının sonuna \_ch koymak için Nextflow kodunda sık kullandığımız bir gelenektir, böylece bir kanal olduğunu belirlemek kolaydır, ama bunu yapmak zorunda değilsiniz. Eşittir channel of Merhaba Kanallar. + +Az önce kullandığımız şey, Nextflow dilinde "Channel Factory" denen bir şeydir. İşte bu şey, bu değişkeni yeni bir kanala ayarlıyoruz ve buradaki bu channel factory bize belirli bir şekilde bir kanal oluşturuyor. + +Nextflow'un farklı türde girdilerden kanallar oluşturmak için bir avuç farklı channel factory'si vardır. Dot of en basit olanıdır ve ona verdiğimiz herhangi bir string'i alır. + +VS Code'da bu kelimelerin üzerine geldiğimde, Nextflow uzantısının bana bu sözdiziminin ne yaptığını açıklayan bir açılır pencere verdiğini fark edin ve o açılır pencerenin altında da daha fazla oku metni var. + +Buna tıklarsam, Nextflow dokümanlarını açacak. Yeni bir sekmede ve beni doğrudan bu spesifik şeyin dokümantasyonuna götürecek. Bu durumda channel.of için. + +## 1.2. Kanalı process çağrısına girdi olarak ekleyin + +Uzantının bize ayrıca bir uyarı verdiğini, burada yeni bir kanal oluşturduğumuzu ama herhangi bir şey tarafından kullanılmadığını söylediğini unutmayın. + +Öyleyse, hadi bunu düzeltelim. Yeni kanal adını alacağım ve bu params.greeting'i yeni kanalımızla değiştireceğim. + +Artık --greeting komut satırı bayrağını kullanmıyoruz, params.greeting kullanılmıyor, bu string'i tekrar sabit kodlamaya geri dönüyoruz. Bu tamam. Sadece işleri basit tutmaya çalışıyorum. Daha sonra geri gelip params'ı tekrar kullanacağız. + +## 1.3. Workflow komutunu tekrar çalıştırın + +Pekala, bunun çalıştığını bir kontrol edelim. Terminali açıyorum ve tekrar not ediyorum. Nextflow run hello channels. output.txt'yi kontrol edin, ve işte orada. + +Harika, biraz sıkıcı bir örnek, daha önce yaptığımızla tamamen aynı şeyi yapıyor, ama şimdi en azından mantık biraz daha net. Yeni bir kanal yazmak konusunda açık oluyoruz. + +Aynı şeyi yapmak için etkili bir şekilde daha fazla kod yazdık. Ancak kanallarımızı nasıl oluşturduğumuz konusunda biraz daha karmaşık hale geldikçe bu daha mantıklı olmaya başlayacak. + +## 2. İş akışını birden fazla girdi değerinde çalışacak şekilde değiştirin + +Pekala, bunu biraz daha ilginç hale getirelim. Bir Nextflow pipeline'ını tek bir girdi üzerinde çalıştırmak istemeniz çok nadirdir, o yüzden ona birkaç girdi verelim. + +## 2.1. Girdi kanalına birden fazla karşılama yükleyin + +Buradan dokümanlardan. Bu farklı string'leri, üç tanesini kopyalayacağım. Hello, Bonjour, Olà. Oh, umut. Copilot birkaç tane daha öneriyor. Öyleyse bunları tab enter ile girelim. + +Buradaki Nextflow dokümanları bize bu operatöre birden fazla değer verebileceğimizi söylüyor, bu yüzden çalışması gerekir, ama deneyelim ve ne olduğunu görelim. + +## 2.1.2. Komutu çalıştırın ve günlük çıktısına bakın + +Evet ve hayır. Bakalım. Burada beş görevden beşinin çalıştığını söylüyor, ama bize sadece bir hash gösteriyor, bu biraz garip. Sorun değil. Her şey burada beklendiği gibi. Varsayılan olarak. Nextflow, terminale ANSI kontrol kodları adı verilen özel bir çıktı türü kullanır, bu da çalıştırılan tüm farklı işlemlerin güzel bir sıkıştırılmış görünümünü vermek için belirli satırların üzerine yazar. + +Bu, daha büyük iş akışlarınız olduğunda ve yüzlerce veya binlerce farklı örnek çalıştırdığınızda çok daha mantıklıdır. Terminalde o kadar çok çıktı oluşturabilirsiniz ki, bakmak imkansızdır, oysa bu güncellenen görünüm size gerçek zamanlı bir ilerleme sağlar. + +## 2.1.3. Komutu tekrar -ansi-log false seçeneğiyle çalıştırın + +İsterseniz, tekrar çalıştırabilirsiniz ve bu sefer "-ansi-log false" diyen tek bir tire ile ek bir Nextflow çekirdek argümanı kullanacağım. Bu, Nextflow günlük çıktısının önceki sürümünü kullanır. Ve burada başlatılan tüm bireysel işlemleri görebilirsiniz. + +Bunu yapıp yapmamak size kalmış. Nextflow'dan gelen çıktı her iki durumda da tamamen aynıdır. + +## 2.2. Çıktı dosya adlarının benzersiz olacağından emin olun + +Pekala, çıktı dosyalarına bakalım o zaman, results'a gideceğiz. Ama sadece tek bir çıktı dosyası var. Ne oldu? İşlemin birçok kez çalıştığını gördük. Work dizinine gidebilir ve tüm farklı hash'leri görebiliriz, tüm görevler düzgün bir şekilde yürütüldü. Ama burada işlememizde hatırlarsanız, her şeyi bir output.txt dosyasına kaydediyor ve sonra bunu bu dizine yayınlıyoruz. + +Yani aynı dosya beş kez oluşturuldu ve sonra beş kez üzerine yazıldı. Ve sadece hangi görevin en son yürütülmüş olduğuna sahibiz. + +## 2.2.1. Dinamik bir çıktı dosya adı oluşturun + +Bunu düzeltme yolumuz dinamik bir çıktı dosya adı kullanmaktır. Burada işlem içinde zaten greeting adında bir değişkenimiz var, bu yüzden bunu çıktı dosya adında kullanabiliriz. Bunu kopyalıyorum ve $greeting-output.txt yapıyorum. + +Bunu tırnak içine alacağım, böylece bash burada sızabilecek herhangi bir boşluktan kafası karışmasın. Ve sonra aynı dosya adını alacağım ve buradaki çıktıyı güncelleyeceğim. + +Çıktının bununla eşleşmesi gerçekten önemlidir, çünkü aksi takdirde bu dosya bulunamayacak ve Nextflow çökecektir. + +Gerçekten önemli bir düzenleme daha yapacağım, bu tek tırnakları çift tırnaklara çevireceğim. Bunu yaptığımda kodun renginin değiştiğini fark edin. Bu değişken yalnızca çift tırnak kullanırsak genişletilir. Burada tek tırnak kullanırsam, gerçek bir değer olarak kullanılır ve $greeting-output adında tek bir dosya elde ederim, bu da istediğim şey değil. + +## 2.2.2. İş akışını çalıştırın + +Öyleyse çift tırnakları geri koyalım ve bir deneyelim. + +Başlamadan önce dizinimı temizleyeceğim, böylece yeni dosyaları görmek kolay olur. .nextflow, work ve results adlı her şeyi sileceğim. + +Ve o Nextflow komutunu tekrar çalıştıracağım ve hangi dosyaların oluşturulduğuna bakalım. Yani orada beş işlemi çalıştırıyor. Çok yakından izliyorsanız, çalışırken o satırın güncellendiğini görmüş olabilirsiniz. + +Ve şimdi results dizinine gidebiliriz ve elbette beş farklı çıktımız var ve hepsi farklı karşılama ile öneklenmiş. + +Bunların her birini açarsam, her birinin karşılık gelen karşılamayı içerdiğini göreceğiz. Harika. İstediğimiz bu. + +## 3. Bir kanalın içeriğini dönüştürmek için bir operatör kullanın + +Pekala, şimdi kanalların ne olduğunu ve channel factory'lerin ne olduğunu biliyoruz. Peki ya operatörler? Bu, Nextflow dilinin bir başka terimi olup, bize belirli şeyler yapmak için kanallar üzerinde işlem yapmamıza izin veren bir dizi fonksiyondur. Nextflow, kanalları çeşitli şekillerde manipüle etmemize izin veren bir operatör paketi ile birlikte gelir. + +## 3.1. Kanala girdi olarak bir değer dizisi sağlayın + +Bunu bir örnekle inceleyelim. Diyelim ki bu girdi string'lerini almak istiyoruz, ama bunları doğrudan bir channel factory'ye koymak yerine, onları bir dizi olarak tanımlamak istiyoruz. + +## 3.1.1. Girdi değişkenini ayarlayın + +Öyleyse bunları alacağım ve yukarıda yeni bir satır olarak yapacağım ve greetings, dizi diyeceğim. + +İşte oldu. O dizi değişkenini alacağım ve onu channel.of'a koyacağım ve kaydedeceğim. + +## 3.1.3. İş akışını çalıştırın + +Şimdi, bakalım ne olacak. Terminalime geri dönüyorum. Sadece o geçici dosyaların hepsini tekrar temizleyeceğim. Ve iş akışını çalıştıralım. + +İyi değil. Pekala. Bozuldu. Sorun değil. Bu sefer bozulmasını bekliyordum. Bir Nextflow iş akışı başarısız olduğunda neyin yanlış gittiğini hata ayıklamak, bir Nextflow geliştiricisi olmanın önemli bir parçasıdır. Bu çok olacak ve hata mesajının ne söylediğini ve bununla nasıl başa çıkılacağını anlamak önemlidir. + +Nextflow hata mesajları aslında oldukça yapılandırılmıştır. Bize hangi işlemin yanlış gittiğini söyler. Bir sebep için bize bir hata mesajı verir. Çalıştırmaya çalıştığı komutun o belirli görev içinde ne olduğunu, çıkış durumunun ne olduğunu, çıktının o görev work dizininin nerede olduğunu söyler. + +VS Code'da buna option, tıklayabiliceğimi ve yan çubukta açtığını unutmayın, böylece doğrudan oraya gidebilir ve .command.sh dosyası dahil olmak üzere önceki bölümde bahsettiğimiz tüm bu gizli dosyaları görüntüleyebilirim. Bunun burada yürütülen komutlarla aynı olduğunu görebilirsiniz. + +Bu dosyaya bakarak, burada neyin yanlış gitmiş olabileceğine dair bir fikir edinebiliriz, dizideki her öğe için tek bir görev çalıştırmak yerine, sadece tüm diziyi bir string olarak bir kerede sağladı. Bu yüzden o diziyi kanala geçirmeden önce bireysel değerlere açmamız gerekiyor. Geri dönelim ve bir operatör kullanarak bunu yapıp yapamayacağımızı görelim. + +## 3.2. Kanal içeriğini dönüştürmek için bir operatör kullanın + +Bu durumda, diziyi kanala geçirmeden önce değiştirmeyeceğiz. Kanalı beklediğimiz şekilde davranacak şekilde ayarlayacağız. Bunu flatten operatörünü kullanarak yapacağız, dot yazmaya başlayabilirim ve VS Code uzantısının elimizde olan tüm farklı operatörleri önermeye başladığını görebiliriz. + +## 3.2.1. flatten() operatörünü ekleyin + +Ve flatten'ı seçeceğim. Bu bağlamda Nextflow için beyaz boşluğun önemli olmadığını unutmayın. Yani isterseniz bu operatörleri yeni bir satıra koyabilirsiniz. Böylece bunu buraya bırakabilirim ve ".of" altında oturacak şekilde girintileyebilirim ve insanların genellikle bu şekilde bir kanala çok sayıda operatör zincirlediğini ve okumayı kolaylaştırmak için bu şekilde girintilediğini göreceksiniz. + +Ayrıca görebilirsiniz, daha önce olduğu gibi bunun üzerine gelebilir ve flatten operatörünün ne yaptığını okuyabilir ve ayrıca istersem dokümantasyona bir bağlantı izleyebilirim. + +Bu operatör, içinde tek bir dizi olan bu kanalı alıyor ve dizi değerlerini ayırıyor. + +## 3.2.2. Kanal içeriğini incelemek için view() ekleyin + +view operatörünü kullanarak kanallara göz atabiliriz ve burada birkaç tane ekleyeceğim. Bu, diğer dillerde print ifadeleri kullanmak gibidir. Bu yüzden dot view yapacağım ve sonra bu kıvrımlı parantezleri kullanacağım. + +Buna closure denir. Bu temelde view operatörüne, kanal içindeki her öğe üzerinde yürüteceği ek kod verir. Bu durumda, flatten'dan önce karşılama diyeceğim. Karşılama. + +Burada sadece bu closure'ın kapsamı içinde olan bir değişken tanımlıyorum. Yani bu değişken sadece burada kullanılıyor ve istediğimi çağırabilirim. Önemli değil. Okumayı kolaylaştırmak için sadece greeting kullanıyorum. + +Bazı Nextflow pipeline'larında, insanların "$it" adlı özel bir örtük değişken kullandığını görebilirsiniz. Bunun gibi. Bu, Nextflow kodu içinde özel bir değişkendir, bir değişken tanımı yapmak zorunda kalmamanız için bir kısayoldur. Ancak zamanla, bunun Nextflow'a yeni başlayanlar için çok net olmadığını düşünüyoruz ve artık "$it" kullanımını caydırıyoruz. + +Bu yüzden greeting ile önceki davranışa sadık kalacağım ve bunu bu şekilde kullanacağım çünkü bu daha açık ve neler olup bittiği konusunda daha net. + +Sonra bu satırı kopyalayacağım ve flatten argümanlarından sonra tamamen aynı şeyi tekrar yapacağım. view operatörü biraz özeldir çünkü öğeler üzerinde bir şey yapar, ancak aynı zamanda bunları bir sonraki operatöre geçirmeye devam eder, böylece bunu bu şekilde bir operasyon zincirinin ortasına zincirleyebiliriz ve oradaki durumu yazdıracak ve devam edecektir. Umarım bu bize flatten operatöründen önce ve sonra kanalın nasıl göründüğünü gösterecektir. + +## 3.2.3. İş akışını çalıştırın + +Hadi deneyelim. Temizle. Çalışma alanındaki her şeyi temizle. Pipeline'ı tekrar çalıştır. + +Tamam, yani beş işlemimizi tekrar çalıştırdığını görebiliriz. Bir hata ile çökmedi, bu kesinlikle iyi. Ve şimdi flatten'dan öncesi var ve elbette dizimiz var ve flatten'dan sonra, dizinin her öğesi için bir kez olmak üzere beş kez yazdırılmış. Tam olarak umduğumuz şey bu. Yani bu gerçekten iyi bir haber. Ve bu tam olarak koddan beklediğimizle uyuyor. + +Artık bu hata ayıklama ifadelerine ihtiyacımız yok, bu yüzden ya bunları yorumlayabilirim ya da silebilirim. Kodumu güzel ve temiz tutmak için onları sileceğim. Pekala, harika. Bu örnek artık güzel bir şekilde çalışıyor ve kanalların biraz daha karmaşık mantık yapabildiğini görmeye başlayabiliriz. + +## 4. Bir CSV dosyasından girdi değerlerini ayrıştırmak için bir operatör kullanın + +Şimdi bunu bir dizi girdi içeren bir dosya kullanarak yapmayı deneyeceğiz. Bu, bir örnek sayfası veya bir metadata CSV'si kullanarak Nextflow pipeline'ları yazmanın çok yaygın bir yoludur. + +## 4.1. Betiği, karşılamaların kaynağı olarak bir CSV dosyası bekleyecek şekilde değiştirin + +Yan çubuğa gidersem, örnek deposunda greetings.csv'yi görebilirsiniz ve bu, üç farklı karşılama ile sadece üç satır içeren çok, çok basit bir CSV dosyasıdır. Bakalım bu CSV dosyasını iş akışımız içinde kullanabilecek miyiz. + +Şimdi birinci bölümde yaptığımız gibi params kullanmaya geri döneceğim, böylece bir komut satırı girdisi alabiliriz. + +Bu greetings dizisini sileceğim. + +## 4.1.1. Girdi parametresini CSV dosyasına işaret edecek şekilde değiştirin + +params greeting'i dosya adına ayarlayacağım, bu da greetings.csv ve bu özel değişkeni kanalı oluşturmak için kullanacağım. Bunu oraya koyacağım ve hatalar kaybolacak. Bunun bu değişkeni varsayılan olarak şimdi ayarladığını unutmayın. Bu yüzden pipeline'ı herhangi bir argüman olmadan çalıştırırsam, greetings.csv kullanacak, ama istersem bu değişkeni üzerine yazmak için --greeting yapabilirim. + +## 4.1.2. Bir dosyayı işlemek için tasarlanmış bir channel factory'ye geçin + +Pekala, şimdi bir string veya bir string dizisi yerine bir dosya geçiriyoruz, bu yüzden muhtemelen farklı bir channel factory'ye ihtiyacımız var. + +Şimdiye kadar kullandığımız "of"'tan kurtulacağız ve bunun yerine .fromPath kullanacağız. Bu tam olarak kulağa geldiği gibi bir şey yapar. Bir string dosya adı veya glob kullanarak değerler yerine yollarla bir kanal oluşturur. Ayrıca flatten operatörünü kaldıracağım çünkü artık bir dosya geçirdiğimize göre buna ihtiyacımız yok. + +## 4.1.3. İş akışını çalıştırın + +Kaydet'e basacağım, terminali açacağım, iş akışını çalıştıracağım ve sonra ne olduğunu göreceğim. + +Pekala. Yine çöktü. Endişelenmeyin. Bunu da bekliyordum. Hata mesajına bakalım ve neyin yanlış gittiğini anlayıp anlayamayacağımızı görelim. Burada yürütülen komutu görebiliriz ve daha önce tüm dizinin yazdırıldığı gibi, şimdi dosyanın içeriğinden geçmek yerine dosya yolunun komuta yankılandığını görüyoruz. + +## 4.2. Dosyayı ayrıştırmak için splitCsv() operatörünü kullanın + +Yani bunun yerine dosyanın içeriğini kullanmak için başka bir operatöre ihtiyacımız var. Bunun için kullanacağımız operatör splitCsv olarak adlandırılır. Mantıklı, çünkü yüklediğimiz bir CSV dosyası. + +## 4.2.1. Kanala splitCsv() uygulayın + +Tamam, yani splitCsv. Parantezi kapat. Burada herhangi bir argümana ihtiyacımız yok. Ve yine, burada neler olup bittiğine dair bir içgörü vermek için bazı view operatörleri kullanacağım. + +.view csv splitCsv'den sonra. splitCsv'den önce. + +## 4.2.2. İş akışını tekrar çalıştırın + +Pekala, bunu çalıştırmayı deneyelim ve ne olduğunu görelim. + +Tamam, bu sefer biraz daha fazla çıktımız var, ama yine başarısız oldu. view ifadelerine bakabiliriz ve burada split CSV'den önce görüyorsunuz ve önceki hata mesajında gördüğümüz gibi bir dosya yolumuz var. split CSV'den sonra, şimdi CSV dosyasındaki üç satıra karşılık gelen üç değerimiz var. + +Ancak, bu değerlerin her birinin köşeli parantezlerle çevrelendiğini görebilirsiniz. Yani bunların her biri kendi başına bir diziydi ve bu bize daha önce sahip olduğumuz aynı alanı verdi, burada sadece tek bir string yerine bir diziyi yankılamaya çalışıyor. + +Bir CSV dosyası hakkında düşünürsek, bu bir anlamda mantıklıdır. Tipik olarak, bir CSV dosyasının satırları ve sütunları olacaktır, bu yüzden split CSV iki boyutlu dizi yapar. Dizinin ilk boyutu her satırdır ve sonra her satır için her sütun olan ikinci bir boyut vardır. + +Yani burada her satırda sadece tek bir değerimiz var, bu yüzden tek bir sütunumuz var, bu yüzden dosyanın her satırı için tek öğeli bir dizimiz var. + +Bu iyi. Ayrıştırılmış CSV dosyasının her satırı için o diziyi daraltmak için sadece başka bir operatöre ihtiyacımız var. Bunu temizleyelim. Terminalden kurtulalım ve ne yapabileceğimize bakalım. + +## 4.3. Karşılamaları çıkarmak için map() operatörünü kullanın + +Şimdi daha önce kullandığımız flatten operatörünü tekrar kullanabiliriz. Bunun bir diziyi bir dizi değere nasıl daraltabileceğini gördük, bu burada çok iyi çalışırdı. Ancak, iş akışları içinde çok yaygın olan map operatörü adlı başka bir operatörü göstermek için fırsatı kullanacağım. + +## 4.3.1. Kanala map() uygulayın + +Dot map yapacağım ve item item[0] yapacağım. + +Eğer çok sayıda başka kod dili yazıyorsanız, map operatörüne zaten aşina olabilirsiniz. Bir dizi veya kanal gibi yinelenebilir bir şey alır ve bunun her değeri üzerinde bir işlem yapar. + +Burada, bu closure'ın kapsamı içinde item adında bir değişken tanımlamamız gerektiğini ve sonra o dizinin sadece ilk değerini döndürmek istediğimizi söylüyoruz. Yani item index sıfır. + +Bu etkili bir şekilde diziyi düzleştiriyor. Bunun nasıl daha karmaşık olacak şekilde genişletebileceğimizi görebilirsiniz: CSV dosyamızın altı sütunu olsaydı, ancak sadece dördüncü sütunla ilgileniyorsak, burada belirli bir indekse erişebiliriz. Veya değeri aşağı akış işlemeye geçirmeden önce üzerinde başka herhangi bir işlem türü yapabiliriz. + +Yani map operatörü son derece esnektir ve uçuş halindeki kanalları değiştirmek için çok güçlüdür. Yürütmemizde ne yaptığını görebilmemiz için başka bir view ifadesi koyalım. O satırı tanımlayabilir ve aşağı taşıyabiliriz. Ve map'ten sonra. + +## 4.3.2. İş akışını bir kez daha çalıştırın + +Terminali açalım ve iş akışını çalıştırmayı deneyelim. + +Tamam, bu sefer hata yok. Bu iyi bir işaret. Şimdi view ifadelerinden gelen tüm bu farklı çıktıları gözden geçirebiliriz. split CSV'den önce, tek bir yolumuz vardı. split CSV'den sonra, tek değerli dizilerimiz vardı ve sonra map'ten sonra, herhangi bir dizi sözdizimi olmadan sadece değerlerimiz var. results dizinine gidelim ve işte tam olarak istediğimiz gibi davranan çıktı dosyalarımız. + +Burada küçük bir bonus var. view operatörlerinin yaptıkları çıktının sırasında biraz karışık olduğunu görebilirsiniz. Bunun nedeni Nextflow'un bu farklı görevlerin paralelleştirilmesini yapıyor olmasıdır. Yani CSV'yi böldükten sonra, bu kanalda üç öğe var ve bu üç öğenin işlenmesini otomatik olarak paralel olarak gerçekleştiriyor. Bu, çıktıların sırasının stokastik olduğu ve değişebileceği anlamına gelir. Bu durumda, sadece bazı view operatörlerinin sonraki adım tamamlandıktan sonra geri döndüğü oldu ve bu yüzden bu sırayla geldi. + +Aynı iş akışını tekrar çalıştırırsam. O zaman elbette, farklı bir sırayla geldi ve bu sefer split CSV'lerimizi ve map'lerimizi beklediğimiz sırada aldık. + +Bu yüzden sadece unutmayın, bir process görevinden gelen çıktıların sırasına güvenemezsiniz çünkü Nextflow bu paralelleştirmeyi sizin için otomatik olarak gerçekleştiriyor. Nextflow bunu sizin için veri akışı mantığıyla yapıyor ve bu Nextflow'un gerçek gücüdür. + +Tamam, bu muhtemelen tüm eğitimin en önemli bölümlerinden biridir. Kanalları, channel factory'leri ve operatörleri anladığınızda, Nextflow'un gücünü ve onu bir programlama dili olarak benzersiz yapan şeyi kavramaya başlarsınız. Bu işlevsellik, Nextflow'un tüm iş akışlarınızı sizin için paralelleştirmesine ve çok temiz bir sözdizimi ve bir itme veri akışı modeliyle son derece karmaşık iş akışı mantığı oluşturmasına izin verir. İlk başta biraz garip bir kavram olabilir, ama böyle kod yazmaya alıştıktan sonra, hızla doğal hissedecek ve farkına varmadan harika iş akışları yazıyor olacaksınız. + +Bir mola verin, bir fincan çay, etrafta dolaşın ve üçüncü bölüme geçelim, burada bu kavramları daha karmaşık iş akışlarına genişletmeye başlıyoruz. Bir sonraki videoda görüşürüz. + +[Sonraki video transkripti :octicons-arrow-right-24:](03_hello_workflow.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/03_hello_workflow.md b/docs/tr/docs/hello_nextflow/transcripts/03_hello_workflow.md new file mode 100644 index 0000000000..f56da9ea68 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/03_hello_workflow.md @@ -0,0 +1,237 @@ +# Bölüm 3: Merhaba İş Akışı - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/zJP7cUYPEbA?si=Irl9nAQniDyICp2b&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa yalnızca transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../03_hello_workflow.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca bilgilendirme amaçlıdır ve materyaldeki tüm bölüm numaralarını içermeyebilir. + +## Hoş Geldiniz + +Merhaba, "Merhaba Nextflow" eğitim kursunun üçüncü bölümüne hoş geldiniz. + +Bu bölümün adı "Merhaba İş Akışı". + +İkinci bölümde, tek bir işlemden oluşan basit bir iş akışı oluşturduk, ancak gerçekte, boru hatları birden fazla analiz adımını birbirine zincirleme olarak bağlayabildikleri için faydalıdır. + +Bu bölümde, o başlangıç örneğini alıp biraz daha gerçekçi olacak şekilde genişleteceğiz. + +Bazı ek adımlar ekleyeceğiz ve bu adımları bağlamak için kanalları nasıl kullandığımıza bakacağız. + +Tek bir işlemde birleşebilen birden fazla göreve bakacağız ve birden fazla girdiye ve birden fazla çıktıya sahip olabilen işlemlere göz atacağız. + +Pekala, hadi başlayalım. + +Baştan başlayalım. Daha önceki gibi. training.nextflow.io'ya gidelim. Merhaba Nextflow, üçüncü bölüm. Merhaba İş Akışı. Ve çalışma alanımızı açalım. Önceki bölümlerden tüm çalışma dosyalarımı temizledim ve Merhaba İş Akışını açacağım. + +Şimdi bu, şimdiye kadar üzerinde çalıştığımız aynı dosya, bu yüzden tanıdık gelmelidir. Say hello işlemimiz var. greetings CSV dosyasıyla params.greeting'imiz var ve altta, o CSV dosyasını yükleyen, kanalı oluşturan ve işlemimize ileten iş akışımız var. + +## 0. Isınma: hello-workflow.nf'yi Çalıştırma + +İsterseniz, bunu deneyebilir ve beklediğimiz gibi çalıştığını iki kez kontrol edebiliriz. nextflow run hello workflow nf için bir terminal açın ve enter'a basın. + +Tamam, harika. Üç işlemimiz çalıştı. Üç çıktımızla birlikte results dizinimiz var. Bonjour. Hello. Holà. O yüzden bu dosyaları kapatalım, terminali kapatalım, betiğe geri dönelim. + +## 1. İş Akışına İkinci Bir Adım Ekleme + +Tamam. Örneğimiz için, temel kalmaya çalışıyoruz ve alan bağımsız olmaya çalışıyoruz. Bu yüzden ikinci işlemimiz sadece bu dizeleri, bu kelimeleri, basit bir şekilde manipüle edecek. Bu dosyaları alıp hepsini büyük harf yapmak için Unix'in translate komutunu kullanacağız. Bunu "tr" komutuyla yapıyoruz. + +## 1.1. Büyük Harf Yapma Komutunu Tanımlama ve Terminalde Test Etme + +Bunu sadece bash terminalinde deneyebilir ve çalışıp çalışmadığını görebiliriz. Echo, Hello World yapıyorsunuz ve sonra bunu pipe karakteriyle tr'ye iletiyorsunuz, ve ona bir tanıma deseni veriyoruz, a'dan z'ye ve neye dönüştürmesi gerektiği. Büyük harfle A'dan Z'ye. + +Bu çok basit çünkü tam anlamıyla A'dan Z karakterlerini yapıyor. Bu yüzden aksanlı veya bunun gibi herhangi bir şey üzerinde çalışmayacaktır. Ama örneğin amaçları için, resmi anlamalısınız. + +Enter'a basacağım ve terminale büyük harflerle HELLO WORLD yazdırıyor. Ve daha önce olduğu gibi, istersek bunu bir dosyaya yönlendirebiliriz. Outfile. + +Tamam. Bunu temizleyelim. + +## 1.1. Büyük Harf Yapma Adımını Nextflow İşlemi Olarak Yazma + +Betiğimize geri dönelim ve bu bash komutunu yönetmek için yeni bir işlem yazalım. Önceki işlemi kopyalayacağım, altına yapıştıracağım ve buna convert to upper diyeceğim. Büyük harf için. publishDir results'ı aynı şekilde kullanacağım, ancak burada birkaç değişiklik yapacağım. Bir val almak yerine, path input file alacağım ve çıktı dosyalarımızın üst üste binmemesi için burada bir upper öneki kullanacağım. Ve girdiden değişken adını kullanacağım. Sonra aşağıdaki betiği değiştireceğim ve bunun yerine girdi dosyasında cat kullanacağım ve Bash TR'de yaptığımız gibi, a-z, upper input file .txt. Tamam, kaydet'e tıklayalım. + +## 1.2. Workflow Bloğuna Yeni İşlem Çağrısı Ekleme + +Şimdi aşağı kaydırırsam, bu işlemi gerçekten çağırmamız gerekiyor. Betiğe sadece işlemi eklemek yeterli değildir. Nextflow'a bu işlemi çalıştırmamız gerektiğini ve nerede yapacağımızı söylemeliyiz. + +Buraya convert to upper yazacağım ve + +tamam, burada bir argüman beklediğini söyleyen bir hata alıyoruz. Elbette, bu işlemin gerçekten yapacak bir şeyi olması için bu işleme bir şeyler iletmemiz gerekiyor. + +## 1.3. İlk İşlemin Çıktısını İkinci İşleme İletme + +Yapacağımız şey bu işlemden çıktıyı almak. Yani adı alıyorum, say hello, ve dot out yaptığımda. + +Bunun gibi basit bir örnek için, sadece bir çıktısı olan ve bunu yeni bir işleme ilettiğimiz bir işleme sahip olduğumuzda, bir girdisi var, ihtiyacımız olan tek şey bu olmalı. Kaydet'e tıklayacağım, terminali açacağım ve bunu tekrar çalıştırmayı deneyelim. + +## 1.4. İş Akışını Tekrar Çalıştırma + +Şimdi, bu iş akışını en son çalıştırdığımdan beri work dizinini temizlemedim. Tekrar çalıştıracağım ve bunu kısmi önbelleklemenin nasıl çalıştığını göstermek için bir fırsat olarak kullanacağım. Eğer tek tire resume yaparsam. Umarım, en son çalıştırdığımla tamamen aynı olan o ilk işlemden gelen çıktıları yeniden kullanmalıdır. Ama şimdi daha önce çalışmamış, sıfırdan çalışan yeni bir işlemimiz var. Ve elbette, ilk işlemin önbellek çıktılarını kullandığını ve ikinci çıktının üçte üçünü çalıştırdığını görebilirsiniz. Ayrıca şimdi her iki işlemimizin de burada olduğunu görebilirsiniz, ilk işlemimiz, say hello, üç kez çalıştı ve ikinci işlemimiz convert to upper üç kez çalıştı. + +Bunu tekrar çalıştırırsam, hatırlatma olarak, -ansi-log false ile, altı farklı işlem görevinin çalıştığını görmeliyiz, her biri için üçer. Bu tam olarak umduğumuz şeyi yapıyor. İlk işlem üç kez çalışıyor, bu çıktıları ikinci bir işleme iletiyor, o da sonra üç kez çalışıyor. + +Hadi work dizininin içine bakalım ve Nextflow'un bu dosya girdilerini nasıl yönettiğini görelim. Eğer buradaki ikinci işlemden bu hash dizinini alırsam, bu dosyalara bakmak için tree komutunu tekrar -a ile kullanabiliriz. Burada girdi dosyamız olan Bonjour-output.txt dosyasını görebilirsiniz ve bu aslında bir symlink. Bu okun bize gösterdiği şey bu ve önceki work dizinindeki dosyaya işaret ediyor. + +Bu mantıklı. Nextflow her görevin yürütülmesini kendi kapsüllenmiş dizininde yönetir, böylece tamamen kendi kendine yeterlidir. Ancak, önceki adımlardan gelen dosyaları girdi olarak sağlaması gerekiyor. Work dizininin dışına uzanmak yerine bu dosyaları almak için, Nextflow onları work dizinine aşamalar. + +Burada olduğu gibi paylaşımlı bir dosya sistemimiz varsa, bunu ek dosya alanı kullanmaması için bir symlink kullanarak yapar. Farklı konumlarda bucket'lı bulut depolaması kullanırsak, o dosyaları getirir ve gerçekten work dizinine kopyalar. + +command sh dosyasına bakalım. Eğer code work, command sh yaparsam, elbette, o dosyaya yerel dizinden eriştiğini görebilirsiniz. Yani her şey çok kendi içinde ve temiz. + +Ayrıca results dizinini kontrol edebilir ve bu dosyaların düzgün şekilde çıktılandığından emin olabiliriz. Ve elbette, results'ta, ilk işlemden gelen tüm çıktı dosyalarını ve ikinciden gelen tüm çıktı dosyalarını görebiliriz. Ve umduğumuz gibi hepsi büyük harf. + +Nextflow'un gücünün parlamaya başladığı yer burası. Çok az kodla ve Nextflow, bu görevlerin paralel olarak yürütülmesini, ayrı work dizinlerinde temiz kapsülleme ile, girdi ve çıktı dosyalarını aşamalama ve dosya yayımlama işlemlerini otomatik olarak bizim için sadece kutunun dışında yönetti. Yani, bu analiz iş akışlarımızın karmaşıklığını ölçeklendirdikçe, bu işlevselliğin gerçekten çok değerli olduğunu görebilirsiniz. + +## 2. Tüm Selamlamaları Toplamak İçin Üçüncü Bir Adım Ekleme + +Tamam. Bu adımlar bire-bir idi. İlk işlemden ikinci işlem için bir girdiye giden bir çıktımız vardı. Sonra, bu farklı çıktıları tek bir işlem görevinde nasıl toplayacağımızdan bahsedeceğiz, ki bu da yine çok yaygın bir şey. O yüzden hızlıca terminali açalım ve bunun bir kuru çalıştırmasını yapalım. + +## 2.1. Toplama Komutunu Tanımlama ve Terminalde Test Etme + +Hile yapacağım ve eğitim materyalinden örnek bash kodunu kopyalayıp enter'a basacağım. + +Burada gördüğümüz, bu echo komutunu üç farklı çıktı dosyasına üç kez çalıştırdık, bunu burada görebilirim. Ve sonra bu üç farklı dosyanın her birinin çıktısını yazdırmak için cat komutunu kullandık ve bunu tek bir toplanmış dosyaya yönlendirdik. + +Ve eğer "cat COLLECTED-output" yaparsam, bu üç farklı dosyanın içeriğine sahip olduğunu, şimdi tek bir dosyada olduğunu görebilirsiniz. + +## 2.2. Toplama Adımını Yapmak İçin Yeni Bir İşlem Oluşturma + +Öyleyse aynı şeyi Nextflow boru hattımızda kopyalayıp kopyalayamayacağımıza bakalım. + +Yukarı kaydıralım ve üçüncü bir işlem oluşturalım. Bu önceki olanı kopyalayacağım ve bu sefer buna Collect Greetings diyeceğim. + +Bash terminalinde, buna collected output txt dedik. Yani burada aynı path output'u söyleyeceğim. Ve aynı şekilde kaydedilmesi için yönlendirmeyi burada yapacağım. + +Tamam. O komutun başında ne olduğunu değiştirmemiz gerekiyor ve burada girdi dosyasının ne olduğunu düşünmemiz gerekiyor. Aslında, bu işlem birden fazla girdi dosyası alacak. Path'i tutacağım ve bunu yeni bir değişken olan input files, çoğul, olarak değiştireceğim. + +Sonra tekrar, bash betiğimizde yaptığımız gibi cat yapacağım. Ve burada değişkeni kullanacağım. + +Şimdi, bunun işe yaramayacağını düşünebilirsiniz. Daha önce bir dizi dizenin veya bir dizi path'in bir işleme iletildiği ve bunun hataya neden olduğu başarısızlıklar gördük. Ama aslında, burada Nextflow bunu bizim için otomatik olarak doğru şekilde yönetecek. Birkaç farklı girdi dosyası alacak ve burada sadece farklı dosya yollarını yazdıracak. + +Tabii ki, cat komutunun bunun gibi bir dizi dosya adı alabiliyor olması yardımcı oluyor. Eğer her dosya yolundan önce bir argüman gerektiren veya bunun gibi bir şey gerektiren farklı bir komut kullanıyor olsaydım, bu dosya yollarının yinelemesini işleyebilmek için burada biraz daha kod ve mantığa sahip olmamız gerekirdi. Ama bu durumda, sadece çalışmalı. + +## 2.3. İş Akışına Toplama Adımını Ekleme + +Tamam, iş akışına gidelim ve yeni işlemimizi ekleyelim. Collect greetings. Ve tekrar, convert to upper out'tan çıktı alalım. Bunu kaydedelim. + +Bir deneyin. nextflow run hello workflow. + +Tamam, iş akışı çalıştı, ama burada biraz garip bir şey var. İlk adımın üç yürütmesi var, beklediğimiz gibi. İkinci için üç görev, ama sonunda tüm çıktıları birleştirmek için burada sadece tek bir görev beklediğimizde üç görevimiz var. + +Results dizinimize girersek. Ayrıca collected output'un üç yerine sadece tek bir değere sahip olduğunu görürüz. Bunun nedeni, o çıktı dosyasının üç farklı değerle üç kez üzerine yazılmış olması. + +Bu mantıklı çünkü önceki adımda yaptığımız gibi bir çıktıyı bir girdiye burada iletiyoruz. + +## 2.4. Selamlamaları Tek Bir Girdide Toplamak İçin Bir Operatör Kullanma + +O yüzden burada üç elemanlı bu kanalı alıp bunları tek bir elemana daraltmak için bir operatöre ihtiyacımız var, böylece o son işlem sadece bir kez çalışır. + +Bunu yapmak için, collect operatörünü kullanacağız. Bunu doğrudan iş akışı içinde yapabilirim. .out yapabilirim ve sonunda bir operatöre zincirleyebilirim .collect. + +Kaydet'e basın. Ve sonra bu eğitimin amaçları için, daha önce yaptığımız gibi bazı view operatörleri de yapacağım, böylece iş akışını çalıştırdığımızda komut satırında görebiliriz, böylece ne olduğunu anlayabiliriz. + +Bu kanalı alacağım, collect'i kaldıracağım ve dot view greetings yapacağım, ve sonra bu satırı kopyalayacağım, collect operatörünü ekleyeceğim. Ve bunu after olarak değiştireceğim. + +Bu, bunu çağırdığımız yerden ayrı, ama sorun değil çünkü aynı çıktı kanalında aynı operatör çağrılarını kullanıyoruz. + +Tamam, kaydet'e basalım ve terminalde deneyelim. nextflow run yapacağım. Hello, workflow. Betiğimizi yeniden çalıştır. + +Tamam. Bu daha iyi görünüyor. Daha önce olduğu gibi ilk iki işlemin üç kez çalıştığını görebiliriz ve şimdi son işlemimiz sadece bir kez çalıştı. + +View operatörü tarafından yazdırılanı bakarsak, aşağıda, collect'ten önce dedik, bu buradaki çıktı, ve bu üç kez yazdırılıyor. Ve bunların her biri için tek bir path olduğunu görebilirsiniz. Ve sonra collect'ten sonra, üç path'lik bu diziye sahip olduğumuzu görebilirsiniz. Yani beklediğimiz gibi. + +Tamam, results dosyasını kontrol edelim ve bu sefer beklediğimiz gibi olup olmadığına bakalım. Elbette, dosyada şimdi üç satır var - bu üç çıktıyı başarıyla tek bir çıktı dosyasında birleştirdi. Fantastik. + +Tamam, temizleyeceğim ve bir sonraki adıma geçelim. Ve işleri temiz tutmak için bu view ifadelerini sileceğim. + +## 3. Nihai Çıktı Dosyasını Benzersiz Şekilde Adlandırmak İçin Bir İşleme Birden Fazla Girdi İletme + +Tamam. Şimdiye kadar, tüm işlemlerimiz sadece tek bir girdi aldı. Şimdi bunun nasıl çalıştığını görmek için bir işleme birden fazla girdi eklediğimiz bir alıştırma yapacağız. Bunu yapmak için, bu collect greetings örneğini kullanacağız. + +İş akışını her çalıştırdığımda, results dizinindeki o dosyanın üzerine yazdı, ki bu istediğimiz şey olmayabilir. + +## 3.1. Çıktı Dosyası İçin Kullanıcı Tanımlı Bir Ad Kabul Edecek Şekilde Toplayıcı İşlemi Değiştirme + +Bu örnek için, çıktı dosyası adını özelleştirebilmemiz için ek bir parametre ileteceğiz. + +Bir işleme ikinci bir girdi eklemek çok basit. Input bloğunda sadece ikinci bir satır eklerim. Bu sefer bir path yerine bir value olacak, çünkü bir dize iletmek istiyoruz ve buna batch underscore name diyeceğim. + +Artık bu değişkeni script bloğunda kullanabilirim ve collected tire dollar batch name diyeceğim. + +Burada değişken adının etrafında süslü parantezler kullanıyorum. Bu sadece onu dizenin geri kalanından ayrı tutmak için, ve bu durumda muhtemelen gerekli değil, ama bence okunmasını kolaylaştırıyor. + +Tamam. Son olarak, output path'i güncellemeyi unutmayın çünkü artık dosya adı değişti, bu yüzden aynı şeyi yapacağım ve beklendiği gibi batch name'i output path'ine koyacağım. + +## 3.2. Komut Satırı Batch Parametresi Ekleme + +Şimdi bir yerden batch name iletmemiz gerekiyor ve bunu iş akışını çalıştırdığımızda komut satırında yapabilmemiz için ikinci bir parametre oluşturacağım. + +Yani params batch name yapacağım ve varsayılan olarak, buna test batch diyelim. Şimdi bu özel parametreler değişkenini aşağıda, işlemi çağırdığımız yerde kullanabilirim. + +Ve elbette VS Code bize şimdi bu işleme yeterli argüman olmadığını ve ikinci bir girdi beklediğini söylüyor. + +Basitçe virgül yapın ve yeni değişkenimizi iletin ve hata kayboluyor. + +Buradaki girdilerin sırası gerçekten önemlidir. İlk işlem girdisi path idi ve ikinci girdi ad. Eğer burada sırayı değiştirirsem, işlemi çağırdığımda da sırayı değiştirmeliyim. Aksi takdirde. Sonraki, yanlış kanalı yanlış girdiye ileteceğiz. + +## 3.3. İş Akışını Çalıştırma + +Tamam, deneyelim ve çalışıp çalışmadığına bakalım. "nextflow run hello- workflow" yapalım. Tamam, daha önce olduğu gibi çalıştı. Results dizinine bakalım. + +Elbette, dosya adımız şimdi "collected test batch output txt" olarak adlandırılıyor. Fantastik. + +Ve şimdi tekrar çalıştırarak bunun üzerine yazıp yazamayacağımızı görelim. Bu sefer --batch_name yapacağım, buradaki özel parametre değişken adıyla eşleşecek şekilde. Ve buna demo output diyeceğim. + +İş akışını tekrar çalıştırın ve bir şey olup olmadığını göreceğiz. + +Tamam, şimdi collected demo output .txt var. Ve bu dosya adı ondan farklı olduğu için, üzerine yazmadı. Her ikisi de şimdi results dizininde mevcut. + +## 4. Toplayıcı Adıma Bir Çıktı Ekleme + +Tamam, orada bir işleme birden fazla girdi vermeyi gösterdik, ama birden fazla çıktıya ne dersiniz? Bu örnek için, işlenen selamlama sayısını hesaplayacağız ve bunu bu collect greeting adımı için ikincil bir çıktı olarak çıktılayacağız. + +## 4.1. Selamlama Sayısını Saymak ve Çıktılamak İçin İşlemi Değiştirme + +Burada biraz hile yapacağız. Nextflow işlemleri çok satırlı bir dizeyle bu script bloğuna sahiptir ve bu, dot command dot sh'ye bash çıktısı olarak iletilir. Ama aslında bunun üzerinde herhangi bir özel kod yazabiliriz ve bu, görevin bir parçası olarak yürütülecek ancak bash betiğine dahil edilmeyecek. + +Nextflow sözdizimindeki yerleşik işlevlerden biri size olarak adlandırılır. Bu yüzden path input'u alacağım ve count underscore greetings diyeceğim, sadece bir değişken adı tanımlamak için. Input files'ı alacağım ve üzerinde "size" çağıracağım. + +Bu işlev, bu girdi kanalının boyutunu sayacak ve bir değişkene atayacak. + +Artık bu değişkeni output bloğunun bir parçası olarak döndürebiliriz. Yani val diyoruz, çünkü bir dosya değil value. Ve count greetings. + +Şimdi bu kendi başına yeterli ve artık bu işlemden bu farklı çıktılara erişebiliriz. Ancak, onlara konumsal bir şekilde erişmemiz gerekir. Yani sıfır ve bir gibi bir dizin anahtarı kullanarak. + +Çıktılara ulaşmayı biraz daha kolaylaştırmak için, onları adlandırabiliriz ve bunu bir emit ifadesi kullanarak yapıyoruz. + +Yani virgül emit out file yapıyoruz veya bunu her ne adlandırmak istersem. Ve burada emit count yapıyorum. Bu temelde sadece bir dekoratördür, bu sadece biraz daha temiz kod yazmamıza yardımcı olur, böylece daha sonra workflow bloğunda belirli çıktılara kolayca başvurabiliriz. + +## 4.2. İş Akışının Sonunda Çıktıyı Raporlama + +Tamam. Eğer workflow bloğuna kaydırırsam, artık collect greetings'in çıktılarını alabilirim, collect greetings, dot out yapın ve VS Code uzantısı tarafından burada önerilen iki adlandırılmış çıktımızı görebiliriz. Çok kullanışlı. + +Bu yüzden방금 oluşturduğumuz count değerini almak için dot count yapacağım ve iş akışını çalıştırdığımızda komut satırında yazdırması için view yapacağım. Yani çalıştırdığımızda görebiliriz. + +Biraz daha güzel yapmak için closure içine bir şeyler yazalım. num greetings, greetings selamlama vardı. + +Ve aslında diğer çıktıyı umursamıyoruz çünkü bunu başka hiçbir işlem için girdi olarak kullanmıyoruz. Ama bunu istersek, aşağıda başka bir işleme girdi olarak kolayca nasıl iletebileceğimizi görebilirsiniz. + +## 4.3. İş Akışını Çalıştırma + +Kaydet'e tıklayacağız. Terminale bakalım ve deneyelim. + +Tamam, fantastik. İşte burada. Üç selamlama var. Bu tamamen doğru. + +Tamam, harika. Bu bölümün sonu. Buraya kadar geldiğiniz için hepiniz bitirdiniz. Artık oldukça gerçekçi bir iş akışı oluşturmaya başlıyorsunuz, burada girdileri ve çıktıları ve iş akışımızdaki mantığı yönetebiliyoruz. + +Bu iş akışı dosyaları uzadıkça, biraz hantal hale gelmeye başlıyorlar. Bu yüzden bir sonraki bölümde, iş akışı içindeki kodu bulmanın ve sürdürmenin daha kolay olması için Nextflow kodunu ayrı dosyalara nasıl modülerleştirebileceğimize bakacağız. + +Bir sonraki videoda, dördüncü bölüm için bize katılın. Merhaba Modüller. + +[Sonraki video transkripti :octicons-arrow-right-24:](04_hello_modules.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/04_hello_modules.md b/docs/tr/docs/hello_nextflow/transcripts/04_hello_modules.md new file mode 100644 index 0000000000..3489504338 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/04_hello_modules.md @@ -0,0 +1,107 @@ +# Bölüm 4: Merhaba Modüller - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/Xxp_menS0E8?si=0AWnXB7xqHAzJdJV&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa yalnızca transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../04_hello_modules.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca bilgilendirme amaçlıdır ve materyallerdeki tüm bölüm numaralarını içermeyebilir. + +## Hoş Geldiniz + +Merhaba, Merhaba Nextflow eğitim kursunun Dördüncü Bölümüne hoş geldiniz. + +Bu bölümün adı Merhaba Modüller ve Nextflow kodunun nasıl modülerleştirileceğinden bahsedeceğiz. Yapacağımız şey, tek bir workflow betiğimizi alıp ayrı dosyalara bölmek. + +Bu, workflow'unuz büyüdükçe kodun gezinmesini ve bakımını kolaylaştırır ve ayrıca pipeline'lar arasında modüllerin paylaşılmasını mümkün kılar, böylece aynı aracı kullanan birden fazla pipeline'ınız varsa, o process'i yalnızca bir kez yazmanız yeterli olur. + +Bunun klasik bir örneği nf-core modül deposudur; kullanıma hazır modüllerde binlerce farklı aracı vardır ve bunları kurabilir ve workflow'unuzda kullanabilirsiniz. + +Nextflow ayrıca alt workflow'larla da çalışabilir; bunlar modüller gibidir, ancak birden fazla process içerirler. Bu eğitimin kapsamı dışındadır, ancak temelde aynı şekilde çalışır. + +Tamam. Hadi bir göz atalım. + +Her zamanki gibi, training.nextflow.io adresine giderek başlayın. + +Kenar çubuğunda "Hello Nextflow"a gidin ve dördüncü bölümü yapıyoruz: "Hello Modules". + +Şimdi GitHub Code Spaces ortamıma geçeceğim ve "hello-modules" dosyasına bakacağım. + +Daha önce olduğu gibi, önceki bölümün son noktasından başlıyoruz, bu yüzden bu betik tanıdık gelmeli. Üç process'imiz var: say hello, convert to upper ve collect greetings, ve bu üç komutu çalıştıran ve sonunda bir mesaj yayan basit bir workflow. Greeting ve batch adında iki parametremiz var; batch, sonunda toplanan çıktı dosyası için kullanılan adı belirtir. + +## 0. Isınma: hello-modules.nf'yi çalıştırın + +Bu workflow'un beklediğimiz gibi çalıştığını nextflow run hello, modules yaparak doğrulayabiliriz. + +Harika. Her bir process'ten üç görev, bir toplama görevi çalıştırdı ve bu toplu işteki üç karşılama olduğunu söyledi. Results'a gidersek, toplanan test batch çıktısı dahil olmak üzere farklı çıktı dosyalarımızı burada aldık. + +## 1. Modülleri depolamak için bir dizin oluşturun + +Pekala. Hadi biraz modülerleştirme yapalım. + +Modülleri pipeline deponuzda bir alt klasöre koymak genellikle iyi bir fikirdir, sadece işleri düzenli tutmak için. Bunu istediğiniz gibi adlandırabilirsiniz, ancak geleneksel olarak genellikle modules diyoruz. + +O halde devam edelim, bir terminale gidelim ve modules'u oluşturalım. VS Code'da kenar çubuğunda belirdiğini görebilirsiniz. + +## 2. sayHello() için bir modül oluşturun + +Ardından ilk modülüm için yeni bir dosya oluşturacağım. "touch" veya "code" yapabilirsiniz veya bunu kenar çubuğunda yapabilirsiniz, gerçekten önemli değil. Bu yüzden code modules yapacağım ve process'in adını vereceğim. Yani sayHello.nf. NF, Nextflow dosyaları için geleneksel dosya uzantısıdır. + +Burada kaydet'e basacağım ve yeni modül dosyamızın ortaya çıktığını göreceğiz. + +## 2.2. sayHello process kodunu modül dosyasına taşıyın + +Sağda, modül kodunu workflow'dan alacağım. Ayrıca önce burada hash bang'i alacağım ve açıkça bir Nextflow dosyası olması için kopyalayacağım. Sonra bu process'i alacağım ve keseceğim. Yani ana workflow betiğimden kaldıracağım ve bu yeni modüle yapıştıracağım. + +Bu modül dosyasının içereceği tüm içerik bu. Sadece tek bir process, workflow yok, mantık yok, sadece tek başına bir process. + +Şimdi bu dosyayı kapatabilirim. + +## 2.3. workflow bloğundan önce bir import bildirimi ekleyin + +Şimdi workflow'umda o ilk process eksik, bu yüzden onu içe aktararak geri getirmemiz gerekiyor. Bunun sözdizimi diğer programlama dillerine çok benzer, bu yüzden tanıdık gelebilir. Include'u süslü parantezlerle yaparız, process'in adı say hello, ve sonra dosya yolu modules, say hello, nf'den. Harika. + +Burada birkaç püf noktası var. VS Code uzantısı bu konuda akıllı. Bu dosya yolunu tanır ve üzerine gelip follow link yapabilirsiniz. Ya da Mac'teyim, option tuşuna tıklayabilirim ve bu dosyayı açar. Böylece hızlıca ona geçebiliriz. + +Bu process adı şimdi aşağıdaki workflow tarafından kullanılıyor ve burada aynı şeyi yapabiliriz. Bize o process hakkında biraz bilgi gösteriyor ve yine option tuşunu basılı tutabilirim, üzerine tıklayabilirim ve editörde açılacak. + +Yani farklı process'leriniz için çok sayıda dosyanız olduğunda VS Code'da kod tabanınızda hızlıca gezinmenin gerçekten hızlı bir yolu. + +Tamam. Bu bölüm için temelde bu kadar. Şimdi sadece diğer process'ler için aynı şeyi tekrar yapıyoruz. + +## 3. convertToUpper() process'ini modülerleştirin + +O halde burada yeni bir dosya oluşturalım. Convert to upper nf olarak adlandıralım. Yine hash bang'i kopyalayın. Ve sonra process'i kesin. + +Process adını oraya kopyalayın, yeni process adıyla yeni bir include ifadesi ekleyin. + +## 4. collectGreetings() process'ini modülerleştirin + +Ve sonra üçüncü process için aynısını yapın. Yeni dosya, connect. Greetings, + +hash bang'i yapın. Process'i kesin, process'i yapıştırın ve yeni bir include ifadesi yapın. + +Şimdi burada geçersiz include kaynağı diyen bir hata alt çizgisi aldığımı görebilirsiniz. Ve bu aslında biraz fazla hızlı hareket ettiğim için yaptığım gerçek bir hata. Yakından bakarsanız, T'yi kaçırdığımı ve convert to upper'a dönüştürdüğümü görebilirsiniz. + +Bu yüzden VS Code çok faydalı bir şekilde bana orada bir hata yaptığımı söyledi. O dosya adını düzeltirsem, hata ortadan kalkar. Bu, VS Code içindeki hata kontrolünün Nextflow kodu yazmak için neden bu kadar yararlı olduğunun iyi bir örneği. Aksi takdirde bunu fark etmezdim ve ancak çok daha sonra workflow'u çalıştırmayı denediğimde öğrenirdim. + +Ana pipeline betiğimiz artık çok daha basit görünüyor. İçinde hiçbir process yok, sadece üç include ifademiz ve workflow'umuz var. Workflow'un mantığını değiştirmedik. Process kodunu değiştirmedik, bu yüzden umarım tamamen aynı şekilde çalışmalı. + +## 4.4. Daha önce olduğu gibi aynı şeyi yaptığını doğrulamak için workflow'u çalıştırın + +Kontrol edelim. Bir terminal açacağım ve daha önce olduğu gibi tamamen aynı komutu çalıştıracağım. + +Kesinlikle, process'lerimizi çalıştırdı, say hello, convert to upper collect greetings ve bize tekrar üç karşılama verdi. + +Yani kodumuzun yerini değiştirdik, ancak workflow'un nasıl yürütüldüğü hakkında hiçbir şeyi değiştirmedik ve tamamen değişmedi. Tek fark, artık daha temiz kodumuz var, bakımı daha kolay ve başkalarıyla paylaşılması daha kolay. + +Ve bu kadar. Kısa bir bölümdü. Basit bir kavram, ancak çok güçlü ve daha karmaşık Nextflow workflow'ları yazma şeklimizin anahtarı. Bu yüzden bunu anlamanız ve kullanma alışkanlığı kazanmanız önemli. + +Bir sonraki bölümde, biraz tempomuz değişecek ve Nextflow kodu yazma sözdizimi hakkında bu kadar fazla düşünmeyi bırakacağız ve process'lerin kendilerinde yazılımı nasıl kullandığımız hakkında biraz düşüneceğiz. Bölüm beşte Merhaba Konteynerler için bize katılın. + +[Sonraki video transkripti :octicons-arrow-right-24:](05_hello_containers.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/05_hello_containers.md b/docs/tr/docs/hello_nextflow/transcripts/05_hello_containers.md new file mode 100644 index 0000000000..a825e63ea7 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/05_hello_containers.md @@ -0,0 +1,193 @@ +# Bölüm 5: Merhaba Konteynerler - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/5PyOWjKnNmg?si=QinuAnFwFj-Z8CrO&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa sadece transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../05_hello_containers.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca bilgilendirme amaçlıdır ve materyallerdeki tüm bölüm numaralarını içermeyebilir. + +## Hoş Geldiniz + +Merhaba, Merhaba Nextflow eğitim kursunun Beşinci Bölümüne hoş geldiniz. + +Bu bölümün adı Merhaba Konteynerler. Nextflow'un Docker ve Singularity gibi araçlarla nasıl entegre olduğundan ve yazılım konteynerlerini kullanarak pipeline'ınızın kullanıcılarına yazılım sağlamaktan bahsedeceğiz. + +Bu, insanlar pipeline'ınızı çalıştırdığında, tüm farklı araçları kendilerinin yüklemek zorunda kalmadıkları anlamına gelir. Nextflow bunu onlar için yapacaktır. + +Konteynerler son derece güçlü bir teknolojidir ve tekrarlanabilirlik ve kullanım kolaylığı açısından çok önemlidir. Konteynerlerin kendilerine kısa bir giriş yaparak başlayacağız, bazı docker komutlarını manuel olarak çalıştıracağız ve sonra aynı konteynerleri Nextflow pipeline'ımıza koyacağız. + +Tamam. Hadi başlayalım. + +Daha önce olduğu gibi, eğitim materyalini yükleyerek başlayalım. training.nextflow.io adresine gidin. Merhaba Nextflow, Bölüm Beş, Merhaba Konteynerler. + +Codespaces ortamıma atlayacağım ve burada solda hello containers dot nf'i görüyoruz. + +Daha önce olduğu gibi, bu dördüncü bölümü bitirdiğimiz aynı betik, bu yüzden tanıdık gelmeli. + +Girdi dosyasını ve batch adını belirtmek için komut satırı parametrelerimiz var. Üç modülümüzü dahil ediyoruz ve üç işlemi çalıştırdığımız workflow'umuz var. + +## 0. Isınma: hello-containers.nf'yi Çalıştırın + +Bu workflow'u tekrar çalıştırmaktan ve beklediğiniz çıktıları ürettiğini iki kez kontrol etmekten çekinmeyin. Şimdilik, aslında kapatacağım ve terminale dalacağım. + +## 1. Bir konteyneri 'manuel olarak' kullanın + +Bu bölüme başlamak için, konteyner teknolojisi üzerine bir özet yapacağız. Docker veya singularity ya da diğer konteyner teknolojilerine çok alışkınsanız, bunu bir tazeleme olarak düşünün veya tamamen atlamaktan çekinmeyin. + +Nextflow birçok farklı konteyner teknolojisini destekler. Buna Docker, Singularity, Podman, Shifter, Charliecloud ve daha fazlası dahildir. + +Bu eğitimde Docker'a odaklanacağız. Code spaces ortamında önceden yüklenmiş olarak gelir ve özellikle kendi bilgisayarınızda veya dizüstü bilgisayarınızda geliştirme yapıyorsanız en popüler konteyner teknolojilerinden biridir. + +Paylaşımlı bir HPC'de akademik bir ortamda çalışıyorsanız, Singularity'nin mevcut olduğunu ve Docker'ın olmadığını görebilirsiniz. Sorun değil. Tüm kavramlar tamamen aynıdır. Birkaç manuel komut farklıdır, ancak Docker'ı anlıyorsanız, singularity'yi de anlayacaksınız. + +Aslında, Singularity da Code Spaces ortamında yüklüdür. İsterseniz, aynı görevleri Docker yerine Singularity kullanarak yapmayı deneyebilirsiniz. + +Peki, konteyner teknolojisi nedir? Docker'ın arkasındaki fikir, uzak bir kaynaktan bir imaj çekebilmesi, yerel makinenize çekebilmesi ve ardından bu imaja dayalı bir konteyner oluşturabilmesidir. + +Bu çalışan konteyner, bilgisayarınızda çalışan bir sanal makineye biraz benzer. Ortamınızdan izole edilmiştir ve önceden paketlenmiş bir işletim sistemi ve bir dizi mevcut yazılımla birlikte gelir. + +## 1.1. Konteyner imajını çekin + +Önceden var olan bir imajı çekmek için ihtiyacımız olan sözdizimi "docker pull". Terminalime yazacağım, ancak şimdi oynayacak bir imaja ihtiyacımız var. + +İmajları kendiniz oluşturabilirsiniz. Onları Docker Hub veya quay.io gibi genel kayıt defterlerinde bulabilirsiniz. Ancak imajları hızlı bir şekilde almanın gerçekten iyi bir yolu Seqera Containers kullanmaktır. + +Bu, 2024'te oluşturduğumuz, giriş yapmadan veya herhangi bir şey olmadan kullanabileceğiniz, kullanımı ücretsiz bir topluluk hizmetidir. + +seqera.io/containers adresine giderseniz veya burada üstteki containers'a tıklarsanız, size bir arama arayüzü sunulur ve Conda'da veya Python Package Index'te bulunan herhangi bir aracın adını yazabilirsiniz. + +Varsayılan olarak, Bioconda ve Conda Forge kanallarını arar, ancak istiyorsanız herhangi bir Conda kanalını önek olarak ekleyebilirsiniz. + +Biraz eğlenmek için cowpy kullanalım. cowpy yazacağım. Bana Python Package Index ve Conda Forge'dan sonuçlar veriyor. Konteynerime eklemek için buna tıklayacağım. İsteseydim buraya birden fazla paket ekleyebilirdim. Docker'ı seçin, linux/amd64'ü seçin ve Get Container'a tıklayın. + +Bu, henüz oluşturulmadıysa imajı benim için talep üzerine oluşturur ve kopyalayabileceğim bir URL verir. + +İlgileniyorsanız, view Build Details'e tıklayabilirsiniz ve bu sizi kullanılan conda ortam dosyasını ve güvenlik tarama sonuçlarıyla birlikte yapı için tam yapı günlüğünü gösteren bir sayfaya götürür. + +Code spaces'e geri dönersem, artık bu konteyner adını yapıştırabilir ve enter tuşuna basabilirim. + +Docker şimdi bu konteyner imajı içindeki tüm farklı katmanları indirir ve şimdi bu imajın kullanıma hazır olduğunu söyler. + +## Bir Singularity imajı çekme + +Singularity kullanıyorsanız, süreç temelde aynıdır. İmaj paketlerimizi seçiyoruz, cowpy'yi seçiyoruz. Şimdi Docker yerine Singularity'yi seçiyoruz ve Get Container'a tıklıyoruz. Bu bize oras:// kullanan bir imaj URL'si verir. Veya isterseniz, bu kutuyu işaretleyerek https:// kullanabilirsiniz. Bu URL'yi kopyalayın. Şimdi Code Spaces'e gidin. Aslında bu alanda Singularity ile aynı olan Apptainer yüklü, ancak birbirlerinin takma adılar. Bu yüzden apptainer pull yapacağım ve sonra ona cowpy sif diyeceğim, ama istediğiniz gibi adlandırabilirsiniz. URL'yi yapıştırın. Ve bu imajı benim için indirecek. + +ls -lh yapabilir ve cowpy.sif'i görebilirim + +Singularity Docker'dan farklıdır, singularity tüm imajları düz dosyalarda saklar, oysa Docker, tüm katmanları ana makinenizde ayrı ayrı tutan bir kayıt defterine sahiptir ve tüm bunları takip etmek için çalışan bir daemon'a sahiptir. + +## 1.2. Cowpy'yi tek seferlik bir komut olarak çalıştırmak için konteyneri kullanın + +Tamam, Docker'a geri dönelim. Artık docker run yaparak oluşturduğumuz bu imajı çalıştırmayı deneyebiliriz. + +Dash dash rm yapacağım, bu sadece imajın tek seferlik bir çalıştırmasını yapar. Ve imaj URL'sini yapıştıracağım. Ve son olarak, bunu çalıştırmak istediğiniz bir komutla bitirirsiniz. + +Oluşturduğumuz imajda cowpy yüklüydü, o yüzden cowpy'yi deneyelim. + +İşte. Komutumuzu çalıştırdı. Yerel olarak yüklü cowpy'm yok. Çalıştırmayı denersem, mevcut olmadığını görebilirsiniz. Ancak bu komutta, Docker kullanarak çalıştırdım ve bu çıktıyı doğru bir şekilde üretti. + +## 1.3. Cowpy'yi etkileşimli olarak çalıştırmak için konteyneri kullanın + +İstersek bundan daha ileri gidebilir ve etkileşimli olarak bir konteyner başlatıp içeride etrafta bakınabiliriz. Yine, "docker run dash dash rm" yapıyorum. Şimdi dash it yapacağım, bu Docker'a etkileşimli bir terminal istediğimizi söyler. İmaj URL'sini tekrar yapıyorum ve bu sefer cowpy yapmak yerine, bin bash yapacağım çünkü çalıştırmak istediğimiz komut bash. + +Bu bizi bu çalışan konteynere götürür ve prompt'un şimdi değiştiğini görebilirsiniz. + +LS slash yaparsam buradaki dizinlerin farklı olduğunu görebilirsiniz. + +Sağ tarafta GitHub Code Spaces'te çalışan ikinci bir terminal açarsam ve LS slash yaparsam, workspaces ve temp gibi dizinlerimiz olduğunu görürsünüz, oysa burada Docker'da farklı. + +Bu ortam Docker içinde tamamen ayrı ve ana ortamımdan izole. Bu iyi bir şey, çünkü bu komutun yürütülmesini Docker imajına izole eder ve farklı ana sistemlerde farklı insanlar arasında tekrarlanabilir tutar. + +Ana sisteminizdeki verileri Docker imajı içinde kullanmak istiyorsanız, bunu açıkça konteynere monte etmeniz gerekir. + +Bunu birazdan yapacağız. + +## 1.3.2. İstenen araç komut(lar)ını çalıştırın + +Ama önce, cowpy'yi çalıştırıp çalıştıramayacağımızı görelim. Yine, komut artık doğrudan komut satırında mevcut ve daha karmaşık şeyler yapmaya ve argümanlar geçirmeye başlayabiliriz. Hello containers ve inek yerine, tux penguenini yapalım. Başka nelerimiz var görelim. + +Cheese yapalım. Harika. Dragon ve Cow'a ne dersiniz? Oldukça iyi. + +## 1.3.3. Konteynerden çıkın + +Tamam. Bu konteynerde hiç verim olmadığı için daha fazla bir şey yapamam. O halde bu çalışan imajdan çıkalım ve konteynere bazı verileri monte edip edemeyeceğimizi görelim. Bunu control D yaparak veya exit yazarak yapabilirim. Tamam, şimdi normal GitHub code space'ime geri döndüm. + +## 1.3.4. Verileri konteynere monte edin + +Docker konteynerine bazı verileri monte etmek için dash V kullanmam gerekiyor. Bu yüzden önceki docker komutumu alacağım, başa gidip dash v yapacağım. Mevcut yerel çalışma dizini için "." yapacağım ve sonra bunun ana dizinde nereye monte edilmesi gerektiğini söylemek için bir iki nokta yapıp slash data yapacağım. Yani bu özel dizini konteynerdeki slash data konumuna monte ediyor. + +Şimdi LS slash yaparsam data adında yeni bir dizin görebiliriz ve LS data yaparsam, burada yan çubukta sahip olduğumuz tüm dosyaları görebilirsiniz. Harika. + +## 1.3.5. Monte edilen verileri kullanın + +Şimdi Docker imajı içinde ana sistemde bulunan bazı dosyaları kullanmaya başlayabiliriz. Yani cat data greetings csv diyebilirim. Hatırlarsanız, bu daha önceki farklı selamlamalarımızın bulunduğu CSV dosyamız ve bunu cowpy'ye pipe edebilirim. Harika. Şimdi bir yerlere varıyoruz. + +Tamam. Docker'ı etkileşimli olarak çalıştırmak için bu kadar yeter. Umarım artık Docker'ın kabaca ne olduğu ve hem tek seferlik bir şekilde komut çalıştırmak hem de bir imajı etkileşimli olarak kullanmak için nasıl kullanılacağı konusunda bir fikriniz olmuştur. Singularity kullanıyorsanız, komutların hepsi çok benzerdir, sadece apptainer exec veya apptainer run veya singularity exec veya singularity run gibi şeyler yaparsınız. + +## 2. Nextflow'da konteynerler kullanın + +Sonra Nextflow workflow'umuza geri döneceğiz ve bu teknolojiyi Nextflow pipeline'ı içinde nasıl kullanacağımızı göreceğiz. + +Hadi terminali kapatalım ve Hello Containers'ı tekrar açalım. + +## 2.1. Bir cowpy modülü yazın + +Cowpy örneğimize bağlı kalmak için, workflow'umuzda cowpy kullanan yeni bir işlem oluşturalım. Modüllere gidelim, yeni bir dosya oluşturalım ve ona cowpy nf diyelim. Şimdi biraz hile yapacağım ve eğitim materyalinden kodu kopyalayıp kaydet'e basacağım. Ve bir bakalım. + +Yani bu basit bir işlem. Umarım artık bir işlemin yapı taşlarının nasıl göründüğünü anlıyorsunuzdur. publishDir'imiz tekrar var, results'a gidiyor. İki girdimiz var, bir girdi dosyası ve character adında bir string. Bir çıktımız var cowpy input file ve tam olarak Docker imajımızda bir saniye önce manuel olarak çalıştırdığımıza benzeyen bir betiğimiz var: bir dosyayı yazdırmak için cat, bunu cowpy'ye pipe ederek, hangi tür cowpy karakterini kullanmak istediğimizi söyleyerek ve bunu burada çıktı olarak geçirdiğimiz çıktı dosyasına çıktılayarak. + +## 2.2. Workflow'a cowpy ekleyin + +Tamam, workflow'umuza geri dönelim, bu yeni işlemi içe aktaralım. Yani modules cowpy nf'den cowpy. Hangi karakteri istediğimizi belirtebilmemiz için yeni bir parametre oluşturalım. Varsayılan olarak Turkey diyelim. Ve sonra workflow'un sonunda bu yeni işlemi çağıralım, + +cowpy. Ve burada Collect Greetings'ten çıktıyı kullanalım. Yani collect greetings out, burada out file. Ve sonra ihtiyacımız olan ikinci bir argüman var, bu da az önce yaptığımız yeni params. params dot character. + +## 2.2.4. Çalıştığını doğrulamak için workflow'u çalıştırın + +Tamam, yeni işlemimizin çalışıp çalışmadığını görelim. Nextflow run hello containers. Bu, ilk üç işlemi çalıştırmalı ve sonra sonunda cowpy'yi çalıştırmaya çalışmalı. + +Bir hata aldık. Burada söylediği şey, cowpy'de bir hata oldu ve 127 çıkış durumu vardı ve elbette, komut sh cowpy komutu bulunamadı. + +Nextflow'a cowpy için mevcut bir Docker imajımız olduğunu söylemedik, bu yüzden onu ana sistemimizde çalıştırmaya çalıştı ve ana sistemimizde yüklü cowpy'miz yok, bu yüzden bir hata tetikledi. + +## 2.3. Çalıştırmak için bir konteyner kullanın + +Yapmamız gereken şey, Nextflow'a mevcut bir konteynerimiz olduğunu söylememiz. Cowpy işlemimize gidelim ve işlemin üstüne container adında yeni bir yönerge ekleyeceğiz. + +Sonra imajımızı buluyoruz, URL'yi kopyalıyoruz ve bunu bir string'e koyuyoruz. + +Bu tek başına yeterli değil çünkü bir X Flow pipeline'ı yazılımı belirtmenin birkaç yolu olabilir. Örneğin conda conda-forge cowpy da yapabilirim. Ve Nextflow'un hangi teknolojiyi kullanmak istediğinizi bilmesi gerekir. + +## 2.3.2. nextflow.config dosyası aracılığıyla Docker kullanımını etkinleştirin + +Bu yüzden Docker etkinken çalıştırmak için, kendimizi biraz ileride atacağız ve bir sonraki bölümde daha ayrıntılı olarak ele alacağımız Nextflow config dosyasını kullanacağız. Bu dizinde Nextflow Config adında bir dosyamız olduğunu görebilirsiniz ve burada zaten docker.enabled False var. + +Docker'ı etkinleştirmek için bunu True olarak değiştireceğiz ve sonra workflow'u tekrar çalıştırmayı deneyebiliriz. + +## 2.3.3. Docker etkinken workflow'u çalıştırın + +Nextflow run hello containers nf ve bu sefer cowpy başarıyla çalıştı. Results'a bakalım. cowpy collected test ve işte Turkey'imiz. Harika. + +Yani arka planda, Nextflow o işlem için mevcut bir konteyneri olduğunu biliyordu. + +İmajı çekti ve komutları bizim için çalıştırdı. + +## 2.3.4. Nextflow'un konteynerli görevi nasıl başlattığını inceleyin + +Merak ediyorsanız, aslında tam olarak ne yaptığını work dizinine bakarak görebiliriz. Code work yaparsam, sonra hash ve sonra command run, hatırlarsanız o görev için yürütülen gerçek dosya, içeri girebilir ve NXF launch adlı bir fonksiyon arayabiliriz. Ve burada Nextflow'un kullandığı tam docker komutunu görebilirsiniz, bu daha önce terminalde manuel olarak yaptığımıza çok benziyor. Docker run. Bu ana dizini konteynere bağlama ve sonra konteyner URL'sini belirtme. + +Yani burada sihir yok. Sadece Nextflow sizin için ağır işi otomatik olarak yapıyor, pipeline'ınızda konteynerleri kolayca belirtebileceğiniz ve sonra workflow'unuzu çalıştıran diğer herkesin kolayca kullanabileceği bir şekilde. Ve bu insanların artık analiz pipeline'ınızı çalıştırmak için yazılım yönetimi hakkında düşünmelerine gerek kalmıyor. + +Çok, çok basit, çok kullanışlı ve aynı zamanda gerçekten tekrarlanabilir. Her açıdan iyi. + +Tamam, harika iş. Bu Beşinci Bölümün sonu. Nextflow yapılandırmasından daha ayrıntılı olarak bahsedeceğimiz bu Merhaba Nextflow eğitiminin son bölümü olan altıncı bölüm için bir sonraki videoda bize katılın. + +Bir sonraki videoda görüşürüz. + +[Sonraki video transkripti :octicons-arrow-right-24:](06_hello_config.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/06_hello_config.md b/docs/tr/docs/hello_nextflow/transcripts/06_hello_config.md new file mode 100644 index 0000000000..8a6406a6e6 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/06_hello_config.md @@ -0,0 +1,217 @@ +# Bölüm 6: Merhaba Config - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/IuDO2HeKvXk?si=tnXTi6mRkITY0zW_&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa yalnızca transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../06_hello_config.md) geri dönün. + + Transkriptte gösterilen bölüm numaraları yalnızca bilgilendirme amaçlıdır ve materyallerdeki tüm bölüm numaralarını içermeyebilir. + +## Hoş Geldiniz + +Merhaba, Merhaba Nextflow eğitim kursunun altıncı bölümüne hoş geldiniz. + +Bu bölümün adı Merhaba Config ve eğitim kursumuzun son bölümü. + +Bu bölümde Nextflow konfigürasyonundan bahsedeceğiz. Nextflow konfigürasyonu gerçekten güçlüdür. Aynı pipeline'ı farklı yazılım sağlama yöntemleriyle, farklı hesaplama altyapılarında ve pipeline'ın kendisinde farklı seçeneklerle çalıştırmamızı sağlar. + +Bu, başkaları tarafından oluşturulmuş Nextflow pipeline'larını, tamamen farklı bir altyapı için oluşturulmuş olsalar bile, kendi sisteminizde çalıştırabileceğiniz anlamına gelir. Nextflow'u yapılandırma yeteneği, iş akışlarını gerçekten taşınabilir ve paylaşılabilir hale getirir. + +Bu bölümde, önceki bölümlerde oluşturduğumuz iş akışını kullanacağız, ancak iş akışı kodunu hiç düzenlemeyeceğiz. Sadece Nextflow yapılandırma dosyamıza bakacağız ve yapılandırmayı değiştirmenin Nextflow'un çalışma şeklini nasıl değiştirdiğini göreceğiz. + +Tamam, hadi başlayalım. + +Daha önce olduğu gibi, training.nextflow.io adresine giderek başlayalım. Sol tarafta Merhaba Nextflow ve altıncı bölüm. Merhaba config. Şimdi GitHub Codespaces ortamıma gidip kullanacağımız betiği kontrol edeceğim. + +## 0. Isınma: Docker'ın etkin olduğunu kontrol edin ve Hello Config iş akışını çalıştırın + +Bu betik Hello Config olarak adlandırılıyor ve daha önce olduğumuz yerden başlıyor. Yani üç parametremizle tamamen aynı görünüyor. CSV dosyası için greetings, çıktı toplu iş adı için batch ve cowpy adı için character. Farklı süreçlerin dört içe aktarımı var ve sonra bunları birbirine zincirleyen bir iş akışımız var. + +Aslında bu dosyayı şimdi kapatacağım çünkü bu bölümde Nextflow dosyasına hiç dokunmayacağız. Tamamen yapılandırma dosyası içinde çalışacağız. Önceki beşinci bölümde kısaca baktığımız nextflow.config dosyasına bakarsam, burada tek bir ifade görebiliriz: docker.enabled = true, bu da Nextflow'a bu iş akışını çalıştırırken Docker kullanmasını söylüyor. + +Burada, pipeline kökünde, Nextflow'u çalıştırdığımda otomatik olarak yüklenen nextflow.config kullanıyorum. Ancak unutmayın, Nextflow yapılandırma dosyalarını birden fazla yerden yükleyebilir. + +Nextflow dokümanlarını kontrol edersem, Configuration'a gidersem, bu yerlerin bir listesini ve yüklendikleri önceliği görebilirsiniz. + +Tamam. İş akışımızın beklediğimiz gibi çalıştığını kontrol edelim. Bir terminal açın. nextflow run hello-config yazın ve enter'a basın. Bu dört sürecin çalışması ve bir cowpy komutuyla bitmesi gerekiyor. Evet, bu düzgün çalıştı. Docker etkin olduğundan, Docker'ı çekti ve beşinci bölümün sonunda olduğu gibi benim için cowpy'yi çalıştırdı. + +## 1. Hangi yazılım paketleme teknolojisinin kullanılacağını belirleyin + +Tamam. Diyelim ki bir HPC üzerinde çalışıyorum ve Docker yüklü değil. Bu senaryoda yapılacak en iyi şey Singularity veya Apptainer kullanmak olurdu. Bunu yapacak olsaydım, cowpy modülüne gidip bu konteyneri Seqera Containers'dan da alabileceğiniz bir oras:// ile singularity imajı kullanacak şekilde değiştirirdim, önceki bölümde gösterdiğim gibi. + +Sonra nextflow.config'e gidip docker.enabled'ı false olarak ayarlayıp singularity.enabled = true yapardım. Ya da Apptainer kullanıyorsam, apptainer.enabled = true yapardım ve bu işe yarardı. + +Nextflow, konteynerler dışında başka teknolojileri de destekliyor, aşina olabileceğiniz bir şey conda. Burada conda.enabled = true yapıp Docker'ı false olarak ayarlayabiliriz. conda aynı container yönergesini kullanmıyor. Bunun yerine, conda adında yeni bir tane ekleyebiliriz. Sonra kullanmak istediğimiz conda paketini belirtiriz. Pipeline'ı mümkün olduğunca tekrarlanabilir kılmak için mümkün olduğunca spesifik olmak iyi bir pratiktir. Bu yüzden conda kanalını, conda-forge'u ve ardından cowpy'yi ve tam sürümü olan 1.1.5'i belirteceğim. + +İsterse sadece cowpy da yazabilirdim, ancak bu pipeline'ın farklı çalıştırmalarında cowpy'nin farklı bir sürümüne çözümlenebilir. + +Bunun güzel yanı docker yönergesine hiç dokunmamış olmam. Bu Docker imajı hala orada. Şimdi sadece iki alternatif sağlıyorum ve bunlar yalnızca bir yapılandırma dosyası kullanılarak açılıp kapatılabilir. + +## 1.3. Conda kullanabileceğini doğrulamak için iş akışını çalıştırın + +Conda artık etkin, o halde deneyelim. + +Harika. Çalışıyor ve Nextflow'dan burada bir mesaj görebilirsiniz, Nextflow'un benim için bir conda ortamı oluşturduğunu söylüyor ve bu önbellek konumunu kullanıyor. + +Arka planda, Nextflow benim için "conda create" komutları çalıştırarak sadece istediğim paketleri içeren yeni bir izole conda ortamı oluşturuyor ve ardından süreci çalıştırabilmesi için bu conda paketlerini yüklüyor ve indiriyor. + +Orada biraz zaman aldığını görebilirsiniz çünkü ilk kez ortamı oluşturuyor ve yazılımı yüklüyordu. Ancak, bu ortamı önbelleğe aldı, bu yüzden aynı Nextflow komutunu tekrar çalıştırırsam, aynı conda ortamını yeniden kullanacağı için çok daha hızlı olmalı. + +Bunun harika yanlarından biri, bu yönergelerin sadece tüm iş akışı için değil, süreç seviyesinde de belirtilebilmesidir. Yani istersen, farklı süreçler için hangi teknolojinin kullanıldığını karıştırıp eşleştirebilirsin. + +## 2. Süreç yönergeleriyle hesaplama kaynaklarını tahsis edin + +Nextflow yapılandırma dosyası sadece yazılım paketlemeden çok daha fazlasını yapabilir. Ayrıca Nextflow'a pipeline'daki adımları gerçekte nasıl çalıştıracağını da söyleyebiliriz. Bir örnek, bir ana sistem sistemine her çalıştırılan göreve hangi kaynakların kullanılabilir hale getirilmesi gerektiğini söylemektir. + +Varsayılan olarak, Nextflow çok fazla şey vermez. Her sürece tek bir CPU ve sadece iki gigabayt bellek verir. + +Bu muhtemelen değiştirmek isteyeceğimiz bir şeydir, böylece çalışması uzun süren süreçler daha fazla kaynağa sahip olabilir ve daha hızlı çalışabilir, ancak bir sürece ne tahsis edeceğinizi bilmek zor olabilir. Nextflow bunun için size yardımcı olacak bazı güzel hilelere sahip. + +## 2.1. Bir kaynak kullanım raporu oluşturmak için iş akışını çalıştırın + +İş akışını tekrar çalıştıralım. Bu sefer ek bir argüman ekleyeceğim, -with-report. Bu bir temel Nextflow seçeneği, bu yüzden tek bir tire. Ve sonra istediğim dosya adı. Bu durumda, buna report-config-one.html diyeceğim. + +İş akışını tekrar çalıştıracağım. Daha önce olduğu gibi çalışacak, ancak bana ek bir yardımcı rapor verecek, görebilirsiniz şimdi kenar çubuğunda ortaya çıktı. + +Bu dosyaya sağ tıklayacağım, download'a tıklayacağım, bu dosyayı GitHub Codespaces'den yerel sistemime indirir, böylece web tarayıcısında kolayca görüntüleyebilirim. + +Bu rapor herhangi bir Nextflow çalıştırması için oluşturulabilir ve içinde çok fazla bilgi var. En üstte, hangi komutun kullanıldığı, iş akışının ne zaman çalıştığı, ne kadar sürdüğü hakkında bazı metaverilerle başlar, ancak aşağı kaydırdıkça, pipeline'daki her adım tarafından kullanılan kaynaklar hakkında daha ayrıntılı bilgi alırız. + +Her süreç farklı görevler için birden çok kez çalıştığından. Kullandığımız kaynakların her süreç için varyasyonunu gösteren bir kutu grafiğimiz var. + +Biraz daha aşağı kaydırırsam, kullanılan bellek ve görev süresi hakkında benzer bilgiler görürüm. Ayrıca disk okuma yazma. + +Uzun süren görevlere sahip büyük bir pipeline için, bu, talep ettiğiniz kaynakların konfigürasyonunu ince ayarlamak için, fazla talep etmemeniz ama aynı zamanda hızlı çalışması için yeterli sağlayabilmeniz için çok bilgilendirici olabilir. + +Raporu aşağı kaydırmaya devam edersem, ayrıca bir görev tablosu görürüz, bu bize iş akışında çalıştırılan her bir görev hakkında ayrıntılı bilgi gösterir. Bu, çalıştırılan çözümlenmiş betik gibi bilgileri içerir. + +Tamam, yapılandırma dosyamıza geri dönelim. İş akışımız için gerçekten fazla bir şeye ihtiyacımız olmadığını gördük, o halde Nextflow'a iş akışındaki her süreç için sadece bir gigabayt belleğe ihtiyacımız olduğunu söyleyelim. + +Şimdi bunu bu şekilde process seviyesinde tanımladığımızda, bu pipeline'daki her bir sürece uygulanır. + +## 2.3. Tek bir süreç için kaynak tahsisleri ayarlayın + +Tartışma uğruna, cowpy'nin gerçekten çok fazla iş yaptığını ve diğer görevlerden daha fazla kaynağa ihtiyaç duyduğunu varsayalım. Burada sadece o sürece uygulanan ekstra bir yapılandırma bloğu tanımlayabiliriz, withName: cowpy kullanarak. + +Buna yapılandırma seçici denir ve burada farklı süreçlerle eşleşmek için farklı desenler tanımlayabiliriz. Örneğin, cow\* yapabilirim. Sonra bunu bazı süslü parantezlerle takip ediyorum ve ona bir yerine iki gigabayt bellek verelim ve diyelim ki iki CPU. + +Şimdi Nextflow iş akışındaki her sürece bir gigabayt verecek, bu istek hariç, daha spesifik. Yani onu geçersiz kılar. Ve sadece cowpy olarak adlandırılan süreçler için iki gig bellek ve iki CPU alacak. + +Nextflow'un kaynak kullanımı konusunda akıllı olduğunu unutmayın. Bu nedenle, bu sayıları daha yüksek değerlere getirmeye başlarsanız, Nextflow'un tüm görevleri paralel olarak çalıştırmak yerine, görev gönderimlerini birbiri ardına kuyruğa almaya başladığını göreceksiniz, böylece mevcut kaynakları fazla talep etmez. + +## 2.4. Değiştirilmiş yapılandırmayla iş akışını çalıştırın + +İş akışını tekrar çalıştırmayı deneyelim ve bu sefer yeni bir rapor kaydedelim. + +Tamam, bu dosyayı indirebilir ve bir göz atabiliriz. + +Evet, şaşırtıcı olmayan bir şekilde, temelde tamamen aynı görünüyor çünkü bu gerçek bir şey yapmayan sahte bir iş akışı. Ancak sınırları tanımlamanın ve bu tür raporlamayla gerçek hayattan iş akışları yapmanın bu yinelemeli yaklaşımının, uygun yapılandırma ayarlamak ve sahip olduğunuz hesaplama kaynaklarından gerçekten en iyi şekilde yararlanmak için kanıta dayalı bir yaklaşım yapmanızı nasıl sağladığını hayal edebilirsiniz. + +Bu konuda gerçekten akıllı olmaya başlayabilirsiniz. Nextflow'un hataları yeniden deneme yerleşik bir yeteneği vardır ve yapılandırma dosyanızda bir closure kullanarak ve kullanılabilir hale getirilen kaynakları dinamik olarak ayarlayarak bundan yararlanabilirsiniz. Yani burada Nextflow'a bu iki gigabaytı yeniden deneme denemesiyle çarmasını söyledim. Yani ikinci yeniden deneme dört gig alacak, üçüncü yeniden deneme altı gig alacak ve böyle devam edecek. Bu biraz bu eğitim kursunun kapsamının ötesinde, ancak ilgileniyorsanız, dinamik yeniden deneme mantığı hakkında güzel bir bölümü olan Nextflow dokümanlarına göz atın. + +## 2.5. Kaynak sınırları ekleyin + +Şimdi, bu konuda fark edebileceğiniz bir şey, bu tür şeylerin yanlışlıkla sisteminizdeki mevcut kaynaklardan fazlasını istemek oldukça kolay hale getirebileceğidir. Mevcut olandan daha fazla kaynak talep ederseniz Nextflow yapılandırmanız hakkında bir hata verecek ve çalıştırmayı durduracaktır. Bunu önlemek için kaynak sınırları adı verilen bir şey kullanabilirsiniz. + +İş akışımızda process kapsamı altında, bu şekilde bir dizi alan kaynak sınırları tanımlayabiliriz ve bu sistemde mevcut olan maksimum bellek, CPU ve zamanı belirtebiliriz. + +Burada yüksek değerler ayarlamak, istenen kaynakların miktarını artırmaz. İsteklerimizde hala bir gigabayt kullanıyor olacağız, ancak bu isteklerden herhangi biri 750'ye ulaşırsa, o tavana çarpacakları ve bundan fazlası istenmeyeceği anlamına gelir, bu da Nextflow'un çalışmaya devam edeceği ve kullanılamayan kaynaklar nedeniyle çökmeyeceği anlamına gelir. + +Yani bu kullanılacak güzel bir güvenlik önlemidir, özellikle kaynak tahsisinizle dinamik mantık kullanıyorsanız. + +Bunun gerçekten yararlı olduğu diğer durum, herkese açık ve sizin tarafınızdan kontrol edilmeyen pipeline'lar kullanıyorsanızdır. Yapılandırma varsayılanlarıyla gelebilirler ve Nextflow otomatik olarak herhangi bir kaynak talebini sisteminizde çalışacak şekilde eşiklemenin doğru yaklaşımını alacaktır. + +Tamam, harika. Yazılımdan bahsettik. Kaynak tahsisinden bahsettik ve tüm süreçler ve belirli süreçler için hem yapılandırmanın farklı kapsamlarını açıkladık. + +## 3. İş akışı parametrelerini saklamak için bir parametre dosyası kullanın + +Tamam, şimdi dikkatimizi parametrelere çevireceğiz. Yapılandırma dosyasında daha önce Nextflow betiğinde yaptığımız gibi parametreler tanımlayabiliriz. Yani params.greeting = 'hello' veya params kapsamını kullanıp foo = 'bar' ayarlayabiliriz. + +Ve bu, iş akışınız için varsayılanları ayarlamak için harika. Ancak, pipeline'ları çalıştırdığınızda, parametreleri bir JSON veya bir YAML dosyasında belirtmek güzel olabilir. + +Böyle bir dosya kullanmak, tire tire ile komut satırı seçenekleri belirtmekten çok daha iyidir. Bir iş akışını çalıştırdığınızda, birçok parametre belirtmeniz gerekebilir ve hepsini tek bir CLI'de yazmak sıkıcı ve hataya açık olabilir. Ayrıca, kullandığınız tüm parametreleri hatırlamanız olası değildir, bu yüzden bunu bir dosyaya kodlarsanız, gelecekte aynı parametreleri kullanarak iş akışını tekrar başlatmak daha kolaydır. + +Burada test-params adında örnek bir dosyamız var ve bunun iş akışımızda sahip olduğumuz üç parametreyi üç farklı değerle belirttiğini görebilirsiniz. Şahsen, YAML'ı JSON'dan yazmayı daha kolay buluyorum. O yüzden sadece işe yaradığını göstermek için, test.yaml adında yeni bir dosya oluşturacağım ve bunları kopyalayacağım, tırnak işaretlerinden kurtulacağım. Ve kaydet'e basacağım. + +Bu JSON ve YAML dosyalarının yazılması daha kolay olabilir çünkü daha tanıdık bir sözdizimi vardır. Ancak bunların yalnızca parametreler için olduğunu ve yalnızca bunun gibi anahtar değer sözdizimi aldıklarını unutmayın. + +## 3.1. Bir parametre dosyası kullanarak iş akışını çalıştırın + +Hadi deneyelim. Daha önce olduğu gibi aynı komutu yapın. Raporu kaldırın ve -params-file test-params.yaml yapacağım. + +Hayır, bu bir temel Nextflow seçeneği, yani tek bir tire. + +Tamam. İş akışını çalıştırdı ve hepsini komut satırında belirtmem yerine o YAML dosyasındaki parametreleri kullandı. Sadece bu basit örnek için aşırıya kaçmış gibi görünebilir, ancak 10 veya 20 farklı parametreniz varsa, manuel olarak yazmak acı verici olabilir ve bu, bir kod düzenleyicide düzenlemek ve tekrarlanabilirlik adına saklamak için çok daha kolaydır. + +## 3. İşi yapmak için hangi yürütücü(ler)in kullanılması gerektiğini belirleyin + +Tamam. Docker ve conda ile yazılım paketlemeden bahsettik. CPU ve bellekle süreç kaynak gereksinimlerinden bahsettik. Ve iş akışlarını çalıştırırken parametrelerin nasıl belirtileceği hakkında biraz konuştuk. + +Yapılandırmanın son kısımları gerçekten yürütme, temel hesaplama altyapısının kendisidir ve bu Nextflow'un taçındaki gerçek mücevherdir: bu aynı iş akışını birden fazla farklı hesaplama altyapısında çalıştırabiliriz. + +Aslında bir saniyeliğine yazılı eğitim materyaline geçeceğim. Bu eğitim bölümünün altında, farklı yürütücülerin, bu durumda HPC zamanlayıcıların, bir iş göndermek için gereken kaynak gereksinimlerini nasıl tanımladıklarının birkaç farklı örneğini görebiliriz. + +Yani Slurm için, --mem ve CPU numarasını tanımlayan bu SBATCH başlıkları var. PBS kullanıyorsanız, farklı başlıklarınız var ve Grid Engine kullanıyorsanız, yine farklı başlıklar var. + +AWS Batch, Google Cloud, Azure veya daha fazlası olsun, bulutta çalıştırmak istiyorsanız bunun daha da farklı olduğunu hayal edebilirsiniz. + +Bu temel hesaplama altyapılarının her birine yürütücü denir ve Nextflow bu farklı yürütücülerin hepsine doğru sözdizimi ile iş göndermek için nasıl konuşacağını bilir. + +İyi haber şu ki bunun hakkında bilmenize gerek yok. Tek yapmanız gereken Nextflow'a hangi yürütücüyü kullanacağını söylemek. + +## 3.1. Farklı bir arka ucu hedefleme + +Yapılandırma dosyamıza geri dönüyoruz ve process altında executor yapıyoruz ve local yazacağım. + +Local aslında varsayılandır, başka bir yürütücü belirtmezseniz, local kullanılacaktır ve bu sadece ana sisteminiz anlamına gelir, Nextflow'u nerede başlattıysanız. + +Bunun yerine Slurm belirtebilirim. Ve bu Slurm işleri gönderir ya da AWS Batch diyebilirim ve bu AWS batch'e işler gönderir. + +Bazı durumlarda ek yapılandırmaya ihtiyacınız var, örneğin bulutta çalışmak belirli kimlik bilgileri gerektirecektir, ancak gerçekten bunun özü budur ve iş akışınızı tamamen farklı bir hesaplama ortamında çalıştırmak için bir veya iki satır yapılandırma kadar basit olabilir. + +Codespaces içinde basit bir sistemde çalışıyor olsak bile, yine de bununla biraz oynayabilir ve Slurm üzerinde çalışıyormuşuz gibi davranabilirim. Eğer sonra iş akışını tekrar başlatırsam, nextflow run hello-config. Slurm'a iş gönderemeyeceği için başarısız olacak. Ancak yine de çalışma dizinlerine gidip Nextflow'un ne yaptığını görebiliriz. Yani bu çalışma dizinine gidersek ve .command.run'a bakarsak. Bu dosyanın en üstünde, Slurm işi için gereken kaynakları belirtmeye çalışan bu sbatch başlık satırlarına sahibiz. + +## 4. Önceden ayarlanmış yapılandırmaları seçmek için profiller kullanın + +Tamam, neredeyse geldik. Bu bölümün son kısmı yapılandırma profilleri hakkında konuşmak. Pipeline'ınızı birkaç farklı sistemde çalıştırıyorsanız, her seferinde belirtmeniz gereken tüm bu farklı Nextflow yapılandırma dosyalarına sahip olmak can sıkıcı olabilir. + +Bunun yerine, Nextflow yapılandırma dosyanızda yapılandırma gruplamalarını kodlayabilir ve bu grupları bir profil bayrağı kullanarak açıp kapatabilirsiniz. Bunun nasıl göründüğüne bakalım. + +## 4.1. Yerel geliştirme ve HPC'de yürütme arasında geçiş yapmak için profiller oluşturun + +Örneğimizde iki profil oluşturacağız, biri dizüstü bilgisayarım için diğeri daha ağır bir HPC sistemi için. Biraz hile yapacağım ve kodu eğitim materyalinden kopyalayıp buraya yapıştıracağım. + +profiles adında yeni bir kapsamımız var ve sonra her profil için, herhangi bir şey olabilecek bir adımız var. Ve bunun içinde, daha önce yazdığımız üst düzey yapılandırmayla tamamen aynı görünen bir yapılandırmamız var. Yani yine, process kapsamımız var. Docker kapsamı. + +my_laptop adlı profilde. Local yürütücüsü kullanarak çalıştırmasını, yani ana sistemimde çalışmasını ve Docker kullanmasını söylüyorum. + +university_hpc profilinde burada, iş göndermek için Slurm kullanmasını, Docker yerine conda kullanmasını ve kullanıyorum HPC'deki düğümlerin sistem boyutuyla eşleşebilecek farklı kaynak sınırları belirtiyorum. + +Varsayılan olarak, Nextflow'u çalıştırdığımda bu yapılandırmanın hiçbiri kullanılmayacak, bu profillerden birini kullanmak istediğimi belirtmem gerekiyor. + +## 4.2. Bir profille iş akışını çalıştırın + +Hadi nextflow run hello-config yapalım. Ve -profile yapacağım, tek tire çünkü bu bir temel Nextflow seçeneği. Ve sonra verdiğim ad, my_laptop. Nextflow şimdi bu yapılandırma profili içinde belirtilen yapılandırma bloğunu kullanmalı ve Nextflow'u çalıştırdığında onu uygulamalı. Diğer yapılandırma bloğunu kullanmak isterse, sadece o profil adını değiştirmem gerekiyor. Hatırlaması çok daha kolay. Kullanması çok daha kolay. + +## 4.3. Bir test profili oluşturun + +Not, profiller her türlü yapılandırmaya sahip olabilir, bu yüzden yürütme ortamınızla ilgili olması gerekmez. Örneğin, burada bir dizi parametreye sahip yeni bir profil oluşturalım. Bunu tux olarak değiştirebilir ve my_profile olarak değiştirebiliriz ve şimdi profile test yaptığımızda, iş akışının en üst düzeyinde belirtilen parametrelerin üzerine yazılacak bu parametreleri belirtecektir. + +Nextflow'u çalıştırdığınızda, birden fazla profili zincirleyebilirsiniz ve sırayla uygulanacaklardır. + +## 4.4. Test profiliyle iş akışını yerel olarak çalıştırın + +Yani önceki komutu alıp virgül test yapabilirim. Bu önce my_laptop yapılandırmasını uygulayacak ve sonra test yapılandırmasını uygulayacaktır. Herhangi bir örtüşme varsa, o zaman sağdaki profil önceki profillerdeki herhangi bir yapılandırmanın üzerine yazacaktır. Enter'a basarsam, bakalım ne olacak. + +Tamam, burada yeni bir sonuç dosyamız var. Seçeneklerden biri olarak belirttiğim My Profile'ı görebilirsiniz. Ve ayrıca cowpy, my_profile'ı görebiliriz ve elbette orada tux var. Yani bu işe yaradı. + +## Özet + +Tamam! İnanılmaz. Bu kadar. Kursun sonuna geldiniz. Biraz kutlama konfetisi alıyorsunuz. Bu bölümü bitirdiğiniz için tebrikler. + +[Sonraki video transkripti :octicons-arrow-right-24:](07_next_steps.md) diff --git a/docs/tr/docs/hello_nextflow/transcripts/07_next_steps.md b/docs/tr/docs/hello_nextflow/transcripts/07_next_steps.md new file mode 100644 index 0000000000..c518b07c13 --- /dev/null +++ b/docs/tr/docs/hello_nextflow/transcripts/07_next_steps.md @@ -0,0 +1,63 @@ +# Sonraki Adımlar - Transkript + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +<div class="video-wrapper"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/xHOcx_4Ancg?si=Lp8hS8RdaMwbp5j5&list=PLPZ8WHdZGxmXiHf8B26oB_fTfoKQdhlik" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> +</div> + +!!!note "Önemli notlar" + + Bu sayfa sadece transkripti göstermektedir. Adım adım talimatların tamamı için [kurs materyaline](../05_hello_containers.md) geri dönün. + +## Hoş Geldiniz + +Tebrikler, başardınız. Hello Nextflow adlı ilk Nextflow eğitim kursunu tamamladınız. + +Aferin. Sonuna kadar devam ettiğiniz için teşekkür ederiz ve Nextflow öğrenmek için harcadığınız zaman ve çabayı gerçekten takdir ediyoruz. Bunun çalışmalarınız için faydalı olacağını umuyoruz. + +## Sonraki Adımlar + +Sonraki adımlar için eğitim portalını takip edin: training.nextflow.io. Oraya sürekli olarak yeni kurs materyalleri ekliyoruz ve bunları yeniliyoruz. Böylece daha ileri düzey eğitimler veya ilgilendiğiniz araştırma alanına özel eğitimler bulabilirsiniz. + +Özellikle Nextflow for Science sayfasına göz atın. Bu sayfada, Hello Nextflow'da öğrendiklerinizi belirli kullanım senaryolarına genişleten, bağımsız kısa kurslar serisi bulunmaktadır. + +Genomik için bir tane ve ayrıca RNA-seq için bir tane var. Yakında daha fazlasını getirmeyi umuyoruz. + +## Yan Görevler + +Hello Nextflow'da bahsedebileceğimiz ama çok fazla detay olacak birçok şey var. Bu konuların bazılarını, belirli konularda kısa kurslar olan Yan Görevler içine koyuyoruz. + +İlginizi çekebilecek içerikler içeren daha büyük temel eğitim ve ileri düzey eğitim kursları da bulunmaktadır. + +## nf-core + +Bu kursta bir iki kez bahsedildi, ancak kesinlikle nf-core projesine göz atın. Farklı veri türleri için yüzün üzerinde pipeline var, bu nedenle kendi pipeline'ınızı oluşturmanıza gerek kalmayabilir. + +Ayrıca nf-core geliştirici araçlarını kullandığınızda, bir pipeline oluşturabileceğiniz ve bu modülleri saniyeler içinde içe aktarabileceğiniz bine yakın süreç modülü bulunmaktadır. + +## Seqera Platform + +Son olarak, Seqera Platform için kısa bir tanıtım. Bu, hiç şüphesiz Nextflow'u pratikte çalıştırmanın en iyi yoludur. Bulut tabanlı bir platformdur, ancak kendi hesaplama altyapınızı eklersiniz; ister AWS, Google Batch veya Azure'da kendi bulut hesabınız olsun, ister kendi HPC'niz olsun. Ücretsiz katman herkes için mevcuttur ve akademisyenseniz, ücretsiz profesyonel düzey erişim için akademik programımıza başvurabilirsiniz. + +Seqera Platform, iş akışlarını başlatmak ve izlemek için sadece bir grafik arayüzün ötesine geçer. İnteraktif oturumlar çalıştırmak için Data Studios gibi ek araçlar ve bulut üzerinden verilere daha hızlı ve daha ucuz erişim sağlayan Fusion gibi temel araçlar da vardır. + +## Destek ve etkinlikler + +Unutmayın, herhangi bir sorunla karşılaşırsanız, sadece community.seqera.io adresine gidin. Oradaki forumumuz gerçekten aktiftir, Nextflow topluluğu çok güçlüdür ve yardıma hazır insanlar neredeyse her zaman mevcuttur; ister eğitim, ister Nextflow'un günlük kullanımıyla ilgili herhangi bir şey olsun. + +Ve tabii ki, harika bir sonraki adım, nf-core hackathon'larından biri veya Nextflow Summit etkinliklerinden birine katılmaktır. Çok eğlenceliler ve orada sizinle tanışıp Nextflow'u ne için kullandığınız hakkında konuşmak gerçekten güzel olurdu. + +## Teşekkürler + +Bu eğitim materyalinin yazılmasında yer alan herkese büyük bir teşekkür etmek istiyorum. Ben sundum, ama gerçekten tüm zor işler Seqera'daki eğitim ekibi tarafından yapıldı. Özellikle, bu materyali yeniden yazmak için büyük miktarda çalışma yapan Geraldine'e. + +Ayrıca Marcel, Ken, Adam, John, bilimsel geliştirme ekibinden diğerleri ve topluluktaki diğerlerine. + +## Geri Bildirim Anketi + +Kursu tamamladığınıza göre, ne düşündüğünüzü bilmek isteriz. training.nextflow.io'da, Hello Nextflow bölümünün altında bir geri bildirim anketi bulacaksınız. + +Sadece dört soru var ama bizim için gerçekten önemli. Hiçbir şey yoksa, bize kabaca kaç kişinin eğitim aldığını söyler. Ayrıca beğenip beğenmediğinizi de söyler ve herhangi bir öneriniz varsa, lütfen sonunda bunları bırakın. Her bir gönderimi okuyoruz. + +Herhangi bir hata görürseniz, her şey GitHub'da açık kaynaklıdır, bu nedenle bir issue oluşturabilir veya bir pull request yapabilir veya forumda bize bir mesaj bırakabilirsiniz. Ne düşündüğünüzü ve nasıl geliştirebileceğimizi duymayı çok isteriz. Tekrar teşekkürler. Yakında görüşmek üzere. diff --git a/docs/tr/docs/hello_nf-core/00_orientation.md b/docs/tr/docs/hello_nf-core/00_orientation.md new file mode 100644 index 0000000000..d55bff1561 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/00_orientation.md @@ -0,0 +1,120 @@ +# Başlarken + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Eğitim ortamını başlatma + +GitHub Codespaces üzerinde sağladığımız hazır ortamı kullanmak için aşağıdaki "GitHub Codespaces'te Aç" düğmesine tıklayın. Diğer seçenekler için [Ortam seçenekleri](../envsetup/index.md) sayfasına bakın. + +Ortam yüklenirken okumaya devam edebilmeniz için eğitim ortamını yeni bir tarayıcı sekmesinde veya penceresinde açmanızı öneririz (ekipmanınıza bağlı olarak sağ tıklama, ctrl+tıklama veya cmd+tıklama kullanın). +Kursu takip edebilmek için bu talimatları paralel olarak açık tutmanız gerekecektir. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Ortam temelleri + +Bu eğitim ortamı, eğitim kursu boyunca çalışmak için gerekli tüm yazılım, kod ve veriyi içerir, dolayısıyla kendiniz herhangi bir şey yüklemenize gerek yoktur. + +Codespace, bir dosya sistemi gezgini, bir kod düzenleyici ve bir terminal kabuğu içeren bir VSCode arayüzü ile kurulmuştur. +Kurs boyunca verilen tüm talimatlar (örn. 'dosyayı açın', 'kodu düzenleyin' veya 'bu komutu çalıştırın') aksi belirtilmedikçe VSCode arayüzünün bu üç bölümünü ifade eder. + +Bu kursu kendi başınıza takip ediyorsanız, lütfen daha fazla ayrıntı için [ortam temellerine](../envsetup/01_setup.md) göz atın. + +### Sürüm gereksinimleri + +Bu eğitim, **v2 sözdizimi ayrıştırıcısı DEVRE DIŞI** olan **Nextflow 25.10.2** veya sonrası için tasarlanmıştır. + +#### Eğitim ortamımızı kullanıyorsanız: + +Daha ileriye gitmeden önce aşağıdaki komutu çalıştırmanız GEREKMEKTEDİR: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +#### Yerel veya özel bir ortam kullanıyorsanız: + +Lütfen [burada](../info/nxf_versions.md) belgelenen doğru ayarları kullandığınızdan emin olun. + +Eğitim ayrıca **nf-core tools 3.4.1** gerektirir. +nf-core araçlarının farklı bir sürümünü kullanırsanız, takip etmekte zorluk yaşayabilirsiniz. + +Ortamınızda hangi sürümün yüklü olduğunu `nf-core --version` komutunu kullanarak kontrol edebilirsiniz. + +## Çalışmaya hazır olun + +Codespace'iniz çalışmaya başladığında, eğitime dalmadan önce yapmanız gereken iki şey vardır: bu özel kurs için çalışma dizininizi ayarlamak ve sağlanan materyallere göz atmak. + +### Çalışma dizinini ayarlama + +Varsayılan olarak, codespace tüm eğitim kurslarının kök dizininde ayarlanmış çalışma dizini ile açılır, ancak bu kurs için `hello-nf-core/` dizininde çalışacağız. + +Terminalde şu komutu çalıştırarak şimdi dizini değiştirin: + +```bash +cd hello-nf-core/ +``` + +!!! tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız (örn. codespace'iniz uykuya geçerse), Github Codespaces eğitim ortamında çalıştığınızı varsayarak, geri dönmek için her zaman tam yolu kullanabilirsiniz: + + ```bash + cd /workspaces/training/hello-nf-core + ``` + +Şimdi bu dizinin içeriğine göz atalım. + +### Sağlanan materyalleri keşfetme + +Bu dizinin içeriğini, eğitim çalışma alanının sol tarafındaki dosya gezginini kullanarak keşfedebilirsiniz. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. + +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde göstermek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar bir içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 2 +``` + +??? abstract "Dizin içeriği" + + ```console + . + ├── greetings.csv + ├── original-hello + │ ├── hello.nf + │ ├── modules + │ └── nextflow.config + └── solutions + ├── composable-hello + ├── core-hello-part2 + ├── core-hello-part3 + ├── core-hello-part4 + ├── core-hello-part5 + └── core-hello-start + ``` + +Bölümü genişletmek ve içeriğini görüntülemek için renkli kutuya tıklayın. +Beklenen komut çıktısını özlü bir şekilde dahil etmek için bunun gibi daraltılabilir bölümler kullanıyoruz. + +- **`greetings.csv` dosyası**, test amaçlı kullandığımız bazı minimal sütunsal verileri içeren bir CSV'dir. + +- **`original-hello` dizini**, Hello Nextflow eğitim serisinin tamamı boyunca çalışarak üretilen kaynak kodun bir kopyasını içerir (Docker etkinleştirilmiş olarak). + +- **`solutions` dizini**, kursun her adımından kaynaklanan tamamlanmış workflow betiklerini içerir. + Bunlar, çalışmanızı kontrol etmek ve herhangi bir sorunu gidermek için referans olarak kullanılmak üzere tasarlanmıştır. + +## Hazırlık kontrol listesi + +Başlamaya hazır olduğunuzu mu düşünüyorsunuz? + +- [ ] Bu kursun hedefini ve ön koşullarını anlıyorum +- [ ] Ortamım çalışır durumda +- [ ] Sözdizimi ayrıştırıcısının **v1** olarak ayarlandığından emin oldum +- [ ] Çalışma dizinini uygun şekilde ayarladım + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +**Bölüm 1'e devam etmek için bu sayfanın sağ alt köşesindeki oka tıklayın.** diff --git a/docs/tr/docs/hello_nf-core/01_run_demo.md b/docs/tr/docs/hello_nf-core/01_run_demo.md new file mode 100644 index 0000000000..128a488e00 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/01_run_demo.md @@ -0,0 +1,644 @@ +# Bölüm 1: Demo pipeline çalıştırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core eğitim kursunun bu ilk bölümünde, bir nf-core pipeline'ının nasıl bulunacağını ve deneneceğini, kodun nasıl düzenlendiğini ve [Hello Nextflow](../hello_nextflow/index.md)'da gösterilen düz Nextflow kodundan nasıl farklılaştığını öğreneceksiniz. + +nf-core projesi tarafından kod yapısını ve araç işlemlerini göstermek amacıyla pipeline envanterinin bir parçası olarak sürdürülen nf-core/demo adlı bir pipeline kullanacağız. + +Çalışma dizininizin [Başlarken](./00_orientation.md) sayfasında belirtildiği şekilde `hello-nf-core/` olarak ayarlandığından emin olun. + +--- + +## 1. nf-core/demo pipeline'ını bulma ve edinme + +[nf-co.re](https://nf-co.re) adresindeki proje web sitesinde nf-core/demo pipeline'ını bularak başlayalım. Bu site, genel dokümantasyon ve yardım makaleleri, her pipeline için dokümantasyon, blog yazıları, etkinlik duyuruları vb. gibi tüm bilgileri merkezileştirir. + +### 1.1. Pipeline'ı web sitesinde bulma + +Web tarayıcınızda [https://nf-co.re/pipelines/](https://nf-co.re/pipelines/) adresine gidin ve arama çubuğuna `demo` yazın. + +![arama sonuçları](./img/search-results.png) + +Pipeline dokümantasyon sayfasına erişmek için pipeline adına, `demo`, tıklayın. + +Yayınlanan her pipeline, aşağıdaki dokümantasyon bölümlerini içeren özel bir sayfaya sahiptir: + +- **Introduction:** Pipeline'ın tanıtımı ve genel bakışı +- **Usage:** Pipeline'ın nasıl çalıştırılacağına dair açıklamalar +- **Parameters:** Açıklamalarla birlikte gruplandırılmış pipeline parametreleri +- **Output:** Beklenen çıktı dosyalarının açıklamaları ve örnekleri +- **Results:** Tam test veri setinden oluşturulan örnek çıktı dosyaları +- **Releases & Statistics:** Pipeline sürüm geçmişi ve istatistikleri + +Yeni bir pipeline'ı kullanmayı düşündüğünüzde, ne yaptığını ve çalıştırmayı denemeden önce nasıl yapılandırılması gerektiğini anlamak için önce pipeline dokümantasyonunu dikkatlice okumalısınız. + +Şimdi göz atın ve şunları bulup bulamayacağınızı görün: + +- Pipeline hangi araçları çalıştıracak (Sekmeyi kontrol edin: `Introduction`) +- Pipeline hangi girdileri ve parametreleri kabul ediyor veya gerektiriyor (Sekmeyi kontrol edin: `Parameters`) +- Pipeline tarafından üretilen çıktılar nelerdir (Sekmeyi kontrol edin: `Output`) + +#### 1.1.1. Pipeline'a genel bakış + +`Introduction` sekmesi, görsel bir temsil (metro haritası olarak adlandırılır) ve pipeline'ın bir parçası olarak çalıştırılan araçların listesi dahil olmak üzere pipeline'a genel bir bakış sağlar. + +![pipeline metro haritası](./img/nf-core-demo-subway-cropped.png) + +1. Read QC (FASTQC) +2. Adapter and quality trimming (SEQTK_TRIM) +3. Present QC for raw reads (MULTIQC) + +#### 1.1.2. Örnek komut satırı + +Dokümantasyon ayrıca örnek bir girdi dosyası (aşağıda daha ayrıntılı olarak tartışılacak) ve örnek bir komut satırı sağlar. + +```bash +nextflow run nf-core/demo \ + -profile <docker/singularity/.../institute> \ + --input samplesheet.csv \ + --outdir <OUTDIR> +``` + +Örnek komutun bir workflow dosyası belirtmediğini, sadece pipeline deposuna referans olan `nf-core/demo`'yu içerdiğini fark edeceksiniz. + +Bu şekilde çağrıldığında, Nextflow kodun belirli bir şekilde düzenlendiğini varsayacaktır. +Bu yapıyı inceleyebilmemiz için kodu edinelim. + +### 1.2. Pipeline kodunu edinme + +Pipeline'ın amacımıza uygun göründüğünü belirledikten sonra, deneyelim. +Neyse ki Nextflow, doğru biçimlendirilmiş depolardan pipeline'ları manuel olarak bir şey indirmeye gerek kalmadan kolayca edinmeyi sağlar. + +Terminale dönelim ve şunu çalıştıralım: + +```bash +nextflow pull nf-core/demo +``` + +??? success "Komut çıktısı" + + ```console + Checking nf-core/demo ... + downloaded from https://github.com/nf-core/demo.git - revision: 04060b4644 [master] + ``` + +Nextflow, pipeline kodunun bir `pull` işlemini yapar, yani tüm depoyu yerel diskinize indirir. + +Açık olmak gerekirse, bunu sadece nf-core pipeline'larıyla değil, GitHub'da uygun şekilde kurulmuş herhangi bir Nextflow pipeline'ı ile yapabilirsiniz. +Ancak nf-core, Nextflow pipeline'larının en büyük açık kaynak koleksiyonudur. + +Nextflow'dan bu şekilde edindiğiniz pipeline'ların listesini almanızı sağlayabilir: + +```bash +nextflow list +``` + +??? success "Komut çıktısı" + + ```console + nf-core/demo + ``` + +Dosyaların mevcut çalışma dizininizde olmadığını fark edeceksiniz. +Varsayılan olarak, Nextflow bunları `$NXF_HOME/assets` dizinine kaydeder. + +```bash +tree -L 2 $NXF_HOME/assets/ +``` + +```console title="Dizin içeriği" +/workspaces/.nextflow/assets/ +└── nf-core + └── demo + +2 directories, 0 files +``` + +!!! note + + Eğitim ortamımızı kullanmıyorsanız, tam yol sisteminizde farklı olabilir. + +Nextflow, indirilen kaynak kodunu, bu pipeline'ların doğrudan etkileşimde bulunacağınız kod yerine daha çok kütüphaneler gibi kullanılması gerektiği ilkesiyle kasıtlı olarak 'yolun dışında' tutar. + +Ancak, bu eğitimin amaçları doğrultusunda, oraya göz atabilmek ve içinde ne olduğunu görmek istiyoruz. +Bunu kolaylaştırmak için, mevcut çalışma dizinimizden o konuma sembolik bir bağlantı oluşturalım. + +```bash +ln -s $NXF_HOME/assets pipelines +``` + +Bu, az önce indirdiğimiz kodu keşfetmeyi kolaylaştıran bir kısayol oluşturur. + +```bash +tree -L 2 pipelines +``` + +```console title="Dizin içeriği" +pipelines +└── nf-core + └── demo + +2 directories, 0 files +``` + +Artık gerektiğinde kaynak koduna daha kolay göz atabiliriz. + +Ama önce, ilk nf-core pipeline'ımızı çalıştırmayı deneyelim! + +### Çıkarım + +Artık nf-core web sitesi üzerinden bir pipeline'ı nasıl bulacağınızı ve kaynak kodunun yerel bir kopyasını nasıl edineceğinizi biliyorsunuz. + +### Sırada ne var? + +Minimum çabayla bir nf-core pipeline'ını nasıl deneyeceğinizi öğrenin. + +--- + +## 2. Pipeline'ı test profiliyle deneme + +Kolaylık sağlamak için, her nf-core pipeline'ı bir test profiliyle birlikte gelir. +Bu, [nf-core/test-datasets](https://github.com/nf-core/test-datasets) deposunda barındırılan küçük bir test veri setini kullanarak pipeline'ın çalıştırılması için minimum yapılandırma ayarları kümesidir. +Küçük ölçekte bir pipeline'ı hızlıca denemenin harika bir yoludur. + +!!! note + + Nextflow'un yapılandırma profil sistemi, farklı konteyner motorları veya çalıştırma ortamları arasında kolayca geçiş yapmanızı sağlar. + Daha fazla ayrıntı için [Hello Nextflow Bölüm 6: Yapılandırma](../hello_nextflow/06_hello_config.md) bölümüne bakın. + +### 2.1. Test profilini inceleme + +Bir pipeline'ın test profilinin çalıştırmadan önce ne belirttiğini kontrol etmek iyi bir uygulamadır. +`nf-core/demo` için `test` profili `conf/test.config` yapılandırma dosyasında bulunur ve aşağıda gösterilmiştir. + +```groovy title="conf/test.config" linenums="1" hl_lines="8 26" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Nextflow config file for running minimal tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Defines input files and everything required to run a fast and simple pipeline test. + + Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> + +---------------------------------------------------------------------------------------- +*/ + +process { + resourceLimits = [ + cpus: 4, + memory: '4.GB', + time: '1.h' + ] +} + +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Girdi verileri + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + +} +``` + +Üstteki yorum bloğunun, bu test profiliyle pipeline'ın nasıl çalıştırılacağını gösteren bir kullanım örneği içerdiğini hemen fark edeceksiniz. + +```groovy title="conf/test.config" linenums="7" +Use as follows: + nextflow run nf-core/demo -profile test,<docker/singularity> --outdir <OUTDIR> +``` + +Sağlamamız gereken tek şeyler örnek komutta açılı parantezler içinde gösterilenlerdir: `<docker/singularity>` ve `<OUTDIR>`. + +Hatırlatmak gerekirse, `<docker/singularity>` konteyner sistemi seçimini ifade eder. Tüm nf-core pipeline'ları, tekrarlanabilirliği sağlamak ve yazılım kurulum sorunlarını ortadan kaldırmak için konteynerler (Docker, Singularity, vb.) ile kullanılabilir olacak şekilde tasarlanmıştır. +Bu nedenle pipeline'ı test etmek için Docker veya Singularity kullanmak isteyip istemediğimizi belirtmemiz gerekecek. + +`--outdir <OUTDIR>` kısmı, Nextflow'un pipeline'ın çıktılarını yazacağı dizini ifade eder. +Bunun için uydurulabilecek bir ad vermemiz gerekiyor. +Zaten mevcut değilse, Nextflow çalışma zamanında bizim için oluşturacaktır. + +Yorum bloğundan sonraki bölüme geçersek, test profili bize test için önceden yapılandırılmış olanları gösterir: en önemlisi, `input` parametresi zaten bir test veri setine işaret edecek şekilde ayarlanmıştır, bu nedenle kendi verilerimizi sağlamamıza gerek yoktur. +Önceden yapılandırılmış girdinin bağlantısını takip ederseniz, bunun birkaç deneysel örnek için örnek tanımlayıcıları ve dosya yolları içeren bir csv dosyası olduğunu göreceksiniz. + +```csv title="samplesheet_test_illumina_amplicon.csv" +sample,fastq_1,fastq_2 +SAMPLE1_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R2.fastq.gz +SAMPLE2_PE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R2.fastq.gz +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample1_R1.fastq.gz, +SAMPLE3_SE,https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/illumina/amplicon/sample2_R1.fastq.gz, +``` + +Buna samplesheet denir ve nf-core pipeline'larına en yaygın girdi biçimidir. + +!!! note + + Veri formatlarına ve türlerine aşina değilseniz endişelenmeyin, takip edenler için önemli değil. + +Bu, pipeline'ı denemek için ihtiyacımız olan her şeye sahip olduğumuzu doğrular. + +### 2.2. Pipeline'ı çalıştırma + +Konteyner sistemi için Docker'ı ve çıktı dizini olarak `demo-results`'ı kullanmaya karar verelim ve test komutunu çalıştırmaya hazırız: + +```bash +nextflow run nf-core/demo -profile docker,test --outdir demo-results +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/demo` [magical_pauling] DSL2 - revision: db7f526ce1 [master] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/demo 1.0.2 + ------------------------------------------------------ + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : demo-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-57-41 + + Core Nextflow options + revision : master + runName : magical_pauling + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/.nextflow/assets/nf-core/demo + userName : root + profile : docker,test + configFiles : /workspaces/.nextflow/assets/nf-core/demo/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.12192442 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/demo/blob/master/CITATIONS.md + + + executor > local (7) + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ + -[nf-core/demo] Pipeline completed successfully- + ``` + +Çıktınız bununla eşleşiyorsa, tebrikler! İlk nf-core pipeline'ınızı çalıştırdınız. + +Temel bir Nextflow pipeline'ı çalıştırdığınızda olduğundan çok daha fazla konsol çıktısı olduğunu fark edeceksiniz. +Pipeline'ın sürümünün, girdilerinin ve çıktılarının bir özetini ve birkaç yapılandırma öğesini içeren bir başlık vardır. + +!!! note + + Çıktınız farklı zaman damgaları, çalıştırma adları ve dosya yolları gösterecektir, ancak genel yapı ve process çalıştırması benzer olmalıdır. + +Çalıştırma çıktısına geçerek, hangi process'lerin çalıştırıldığını bize söyleyen satırlara bakalım: + +```console + [ff/a6976b] NFCORE_DEMO:DEMO:FASTQC (SAMPLE3_SE) | 3 of 3 ✔ + [39/731ab7] NFCORE_DEMO:DEMO:SEQTK_TRIM (SAMPLE3_SE) | 3 of 3 ✔ + [7c/78d96e] NFCORE_DEMO:DEMO:MULTIQC | 1 of 1 ✔ +``` + +Bu bize üç process'in çalıştırıldığını söyler; bunlar nf-core web sitesindeki pipeline dokümantasyon sayfasında gösterilen üç araca karşılık gelir: FASTQC, SEQTK_TRIM ve MULTIQC. + +Burada gösterildiği gibi `NFCORE_DEMO:DEMO:MULTIQC` gibi tam process adları, tanıtıcı Hello Nextflow materyalinde görmüş olabileceğinizden daha uzundur. +Bunlar üst workflow'larının adlarını içerir ve pipeline kodunun modülerliğini yansıtır. +Buna birazdan daha ayrıntılı gireceğiz. + +### 2.3. Pipeline çıktılarını inceleme + +Son olarak, pipeline tarafından üretilen `demo-results` dizinine bakalım. + +```bash +tree -L 2 demo-results +``` + +??? abstract "Dizin içeriği" + + ```console + demo-results + ├── fastqc + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── fq + │ ├── SAMPLE1_PE + │ ├── SAMPLE2_PE + │ └── SAMPLE3_SE + ├── multiqc + │ ├── multiqc_data + │ ├── multiqc_plots + │ └── multiqc_report.html + └── pipeline_info + ├── execution_report_2025-11-21_04-57-41.html + ├── execution_timeline_2025-11-21_04-57-41.html + ├── execution_trace_2025-11-21_04-57-41.txt + ├── nf_core_demo_software_mqc_versions.yml + ├── params_2025-11-21_04-57-46.json + └── pipeline_dag_2025-11-21_04-57-41.html + ``` + +Bu çok fazla görünebilir. +`nf-core/demo` pipeline'ının çıktıları hakkında daha fazla bilgi edinmek için [dokümantasyon sayfasına](https://nf-co.re/demo/1.0.2/docs/output/) bakın. + +Bu aşamada, gözlemlenmesi gereken önemli şey, sonuçların modüle göre düzenlenmiş olması ve ek olarak pipeline çalıştırması hakkında çeşitli zaman damgalı raporlar içeren `pipeline_info` adlı bir dizinin bulunmasıdır. + +Örneğin, `execution_timeline_*` dosyası hangi process'lerin çalıştırıldığını, hangi sırayla ve çalışmalarının ne kadar sürdüğünü gösterir: + +![çalıştırma zaman çizelgesi raporu](./img/execution_timeline.png) + +!!! note + + Burada görevler paralel olarak çalıştırılmadı çünkü Github Codespaces'te minimalist bir makine üzerinde çalışıyoruz. + Bunların paralel olarak çalıştığını görmek için, codespace'inizin CPU tahsisini ve test yapılandırmasındaki kaynak sınırlarını artırmayı deneyin. + +Bu raporlar tüm nf-core pipeline'ları için otomatik olarak oluşturulur. + +### Çıkarım + +Yerleşik test profili kullanarak bir nf-core pipeline'ını nasıl çalıştıracağınızı ve çıktılarını nerede bulacağınızı biliyorsunuz. + +### Sırada ne var? + +Pipeline kodunun nasıl düzenlendiğini öğrenin. + +--- + +## 3. Pipeline kod yapısını inceleme + +Pipeline'ı kullanıcılar olarak başarıyla çalıştırdığımıza göre, şimdi nf-core pipeline'larının dahili olarak nasıl yapılandırıldığına bakmak için bakış açımızı değiştirelim. + +nf-core projesi, pipeline'ların nasıl yapılandırılacağı ve kod, yapılandırma ve dokümantasyonun nasıl düzenleneceği konusunda güçlü yönergeler uygular. +Bunun nasıl düzenlendiğini anlamak, bu kursun 2. Bölümünde ele alacağımız kendi nf-core uyumlu pipeline'larınızı geliştirmeye yönelik ilk adımdır. + +Daha önce oluşturduğumuz `pipelines` sembolik bağlantısını kullanarak pipeline kodunun `nf-core/demo` deposunda nasıl düzenlendiğine bakalım. + +`nf-core/demo` dizinini bulmak ve açmak için `tree` kullanabilir veya dosya gezginini kullanabilirsiniz. + +```bash +tree -L 1 pipelines/nf-core/demo +``` + +??? abstract "Dizin içeriği" + + ```console + pipelines/nf-core/demo + ├── assets + ├── CHANGELOG.md + ├── CITATIONS.md + ├── CODE_OF_CONDUCT.md + ├── conf + ├── docs + ├── LICENSE + ├── main.nf + ├── modules + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── nf-test.config + ├── README.md + ├── ro-crate-metadata.json + ├── subworkflows + ├── tests + ├── tower.yml + └── workflows + ``` + +Orada çok şey oluyor, bu yüzden bunu adım adım ele alacağız. + +İlk olarak, en üst düzeyde, özet bilgileri içeren bir README dosyası ve lisanslama, katkı yönergeleri, alıntı ve davranış kuralları gibi proje bilgilerini özetleyen yardımcı dosyalar bulabilirsiniz. +Ayrıntılı pipeline dokümantasyonu `docs` dizininde bulunur. +Tüm bu içerik, nf-core web sitesindeki web sayfalarını programatik olarak oluşturmak için kullanılır, bu nedenle her zaman kodla günceldir. + +Şimdi, geri kalanlar için keşfimizi üç aşamaya böleceğiz: + +1. Pipeline kod bileşenleri (`main.nf`, `workflows`, `subworkflows`, `modules`) +2. Pipeline yapılandırması +3. Girdiler ve doğrulama + +Pipeline kod bileşenleriyle başlayalım. +Bireysel dosyalar içindeki koda dalmak yerine, dosya hiyerarşisine ve yapısal organizasyona odaklanacağız. + +### 3.1. Pipeline kod bileşenleri + +Standart nf-core pipeline kod organizasyonu, [Hello Nextflow](../hello_nextflow/index.md) kursunun 4. Bölümü olan [Hello Modüller](../hello_nextflow/04_hello_modules.md)'de tanıtıldığı gibi, kod yeniden kullanımını en üst düzeye çıkarmak için tasarlanmış modüler bir yapıyı takip eder, ancak gerçek nf-core tarzında bu, biraz ek karmaşıklıkla uygulanır. +Özellikle, nf-core pipeline'ları, yani bir üst workflow tarafından içe aktarılan workflow betiklerini bolca kullanır. + +Bu biraz soyut gelebilir, bu yüzden bunun pratikte `nf-core/demo` pipeline'ında nasıl kullanıldığına bakalım. + +!!! note + + Bu modüler bileşenlerin _nasıl_ bağlandığına dair gerçek kodu incelemeyeceğiz, çünkü subworkflow'ların kullanımıyla ilişkili, kafa karıştırıcı olabilecek bazı ek karmaşıklıklar vardır ve bunu anlamak eğitimin bu aşamasında gerekli değildir. + Şimdilik, genel organizasyona ve mantığa odaklanacağız. + +#### 3.1.1. Genel bakış + +`nf-core/demo` pipeline'ı için ilgili kod bileşenleri arasındaki ilişkiler şöyle görünür: + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/nf-core_demo_code_organization.svg" +</figure> + +`main.nf` adlı, iki tür iç içe workflow için sarmalayıcı görevi gören bir _giriş noktası_ betiği vardır: `workflows/` altında bulunan ve `demo.nf` olarak adlandırılan gerçek analiz mantığını içeren workflow ve `subworkflows/` altında bulunan bir dizi bakım workflow'u. +`demo.nf` workflow'u `modules/` altında bulunan **modülleri** çağırır; bunlar gerçek analiz adımlarını gerçekleştirecek **process'leri** içerir. + +!!! note + + Subworkflow'lar bakım işlevleriyle sınırlı değildir ve process modülleri kullanabilirler. + + Burada gösterilen `nf-core/demo` pipeline'ı spektrumun daha basit tarafında olmaktadır, ancak diğer nf-core pipeline'ları (`nf-core/rnaseq` gibi) gerçek analizde yer alan subworkflow'lar kullanır. + +Şimdi, bu bileşenleri sırayla gözden geçirelim. + +#### 3.1.2. Giriş noktası betiği: `main.nf` + +`main.nf` betiği, `nextflow run nf-core/demo` çalıştırdığımızda Nextflow'un başladığı giriş noktasıdır. +Bu, pipeline'ı çalıştırmak için `nextflow run nf-core/demo` komutunu çalıştırdığınızda, Nextflow'un otomatik olarak `main.nf` betiğini bulup çalıştırdığı anlamına gelir. +Bu, sadece nf-core pipeline'ları için değil, bu geleneksel adlandırma ve yapıyı takip eden herhangi bir Nextflow pipeline'ı için çalışır. + +Bir giriş noktası betiği kullanmak, gerçek analiz betiği çalıştırılmadan önce ve sonra standartlaştırılmış 'bakım' subworkflow'larını çalıştırmayı kolaylaştırır. +Bunları, gerçek analiz workflow'unu ve modüllerini gözden geçirdikten sonra ele alacağız. + +#### 3.1.3. Analiz betiği: `workflows/demo.nf` + +`workflows/demo.nf` workflow'u, pipeline'ın merkezi mantığının saklandığı yerdir. +Normal bir Nextflow workflow'u gibi yapılandırılmıştır, ancak bir üst workflow'dan çağrılmak üzere tasarlanmıştır, bu da birkaç ekstra özellik gerektirir. +Kursun bir sonraki bölümünde, Hello Nextflow'daki basit Hello pipeline'ının nf-core uyumlu bir forma dönüştürülmesiyle uğraştığımızda ilgili farklılıkları ele alacağız. + +`demo.nf` workflow'u, daha sonra gözden geçireceğimiz `modules/` altında bulunan **modülleri** çağırır. + +!!! note + + Bazı nf-core analiz workflow'ları, alt düzey subworkflow'ları çağırarak ek iç içe geçme düzeyleri sergiler. + Bu çoğunlukla, yaygın olarak birlikte kullanılan iki veya daha fazla modülü kolayca yeniden kullanılabilir pipeline segmentlerine sarmak için kullanılır. + nf-core web sitesinde mevcut [nf-core subworkflow'larına](https://nf-co.re/subworkflows/) göz atarak bazı örnekler görebilirsiniz. + + Analiz betiği subworkflow'lar kullandığında, bunlar `subworkflows/` dizini altında saklanır. + +#### 3.1.4. Modüller + +Modüller, [Hello Nextflow eğitim kursunun 4. Bölümünde](../hello_nextflow/04_hello_modules.md) açıklandığı gibi process kodunun bulunduğu yerdir. + +nf-core projesinde modüller, hem kökenlerini hem de içeriklerini yansıtan çok düzeyli iç içe geçmiş bir yapı kullanılarak düzenlenir. +En üst düzeyde, modüller `nf-core` veya `local` (nf-core projesinin parçası değil) olarak ayırt edilir ve daha sonra sardıkları araç(lar)dan sonra adlandırılan bir dizine yerleştirilir. +Araç bir araç kitine aitse (yani birden fazla araç içeren bir paket) o zaman araç kitinden sonra adlandırılan bir ara dizin düzeyi vardır. + +Bunu `nf-core/demo` pipeline modüllerine uygulandığını görebilirsiniz: + +```bash +tree -L 3 pipelines/nf-core/demo/modules +``` + +??? abstract "Dizin içeriği" + + ```console + pipelines/nf-core/demo/modules + └── nf-core + ├── fastqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── multiqc + │ ├── environment.yml + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── seqtk + └── trim + + 7 directories, 6 files + ``` + +Burada `fastqc` ve `multiqc` modüllerinin `nf-core` modüllerinin üst düzeyinde oturduğunu görüyorsunuz, oysa `trim` modülü ait olduğu araç kiti olan `seqtk` altında oturuyor. +Bu durumda `local` modül yoktur. + +Process'i tanımlayan modül kod dosyası her zaman `main.nf` olarak adlandırılır ve şimdilik göz ardı edeceğimiz testler ve `.yml` dosyalarıyla birlikte gelir. + +Birlikte ele alındığında, giriş noktası workflow'u, analiz workflow'u ve modüller, pipeline'ın 'ilginç' kısımlarını çalıştırmak için yeterlidir. +Ancak, orada bakım subworkflow'ları da olduğunu biliyoruz, o yüzden şimdi onlara bakalım. + +#### 3.1.5. Bakım subworkflow'ları + +Modüller gibi, subworkflow'lar da `local` ve `nf-core` dizinlerine ayrılır ve her subworkflow'un kendi `main.nf` betiği, testleri ve `.yml` dosyası olan kendi iç içe dizin yapısı vardır. + +```bash +tree -L 3 pipelines/nf-core/demo/subworkflows +``` + +??? abstract "Dizin içeriği" + + ```console + pipelines/nf-core/demo/subworkflows + ├── local + │ └── utils_nfcore_demo_pipeline + │ └── main.nf + └── nf-core + ├── utils_nextflow_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + ├── utils_nfcore_pipeline + │ ├── main.nf + │ ├── meta.yml + │ └── tests + └── utils_nfschema_plugin + ├── main.nf + ├── meta.yml + └── tests + + 9 directories, 7 files + ``` + +Yukarıda belirtildiği gibi, `nf-core/demo` pipeline'ı herhangi bir analize özgü subworkflow içermez, bu nedenle burada gördüğümüz tüm subworkflow'lar, adlarındaki `utils_` öneki ile gösterildiği gibi, 'bakım' veya 'yardımcı' workflow'lar olarak adlandırılır. +Bu subworkflow'lar, diğer yardımcı işlevlerin yanı sıra konsol çıktısında süslü nf-core başlığını üreten şeydir. + +!!! tip + + Adlandırma desenlerinin yanı sıra, bu subworkflow'ların gerçekten analizle ilgili herhangi bir işlev gerçekleştirmediğinin bir başka göstergesi de hiçbir process çağırmamasıdır. + +Bu, `nf-core/demo` pipeline'ını oluşturan temel kod bileşenlerinin bir özetini tamamlar. +Şimdi geliştirmeye dalmadan önce hakkında biraz bilgi sahibi olmanız gereken kalan öğelere bakalım: pipeline yapılandırması ve girdi doğrulama. + +### 3.2. Pipeline yapılandırması + +Daha önce Nextflow'un, girdiler ve parametreler, hesaplama kaynakları ve orkestrasyon ile ilgili diğer yönler açısından pipeline çalıştırmasını yapılandırmak için birçok seçenek sunduğunu öğrendiniz. +nf-core projesi, Nextflow'un esnek özelleştirme seçenekleri üzerine inşa ederek pipeline'lar arasında daha fazla tutarlılık ve sürdürülebilirlik sağlamayı amaçlayan, pipeline yapılandırması için son derece standartlaştırılmış yönergeler uygular. + +Merkezi yapılandırma dosyası `nextflow.config`, parametreler ve diğer yapılandırma seçenekleri için varsayılan değerleri ayarlamak için kullanılır. +Bu yapılandırma seçeneklerinin çoğu varsayılan olarak uygulanırken diğerleri (örneğin, yazılım bağımlılık profilleri) isteğe bağlı profiller olarak dahil edilir. + +`conf` klasöründe saklanan ve varsayılan olarak veya isteğe bağlı olarak profil olarak yapılandırmaya eklenebilen birkaç ek yapılandırma dosyası vardır: + +- `base.config`: Çoğu yüksek performanslı hesaplama ortamında genel kullanım için uygun bir 'boş sayfa' yapılandırma dosyası. Bu, örneğin modüllere uygulanması kolay olan geniş kaynak kullanımı gruplarını tanımlar. +- `modules.config`: Ek modül yönergeleri ve argümanları. +- `test.config`: Demo pipeline'ı çalıştırdığımızda kullandığımız, minimum test verileriyle pipeline'ı çalıştırmak için bir profil. +- `test_full.config`: Pipeline'ı tam boyutlu bir test veri setiyle çalıştırmak için bir profil. + +Kursta bu dosyalardan birkaçına değineceğiz. + +### 3.3. Girdiler ve doğrulama + +Daha önce `nf-core/demo` pipeline'ının test profilini incelerken belirttiğimiz gibi, girdi olarak `nf-core/test-datasets` deposunda bulunan gerçek verilere bağlanan dosya yolları ve örnek tanımlayıcıları içeren bir samplesheet alacak şekilde tasarlanmıştır. + +`assets` dizini altında da örnek bir samplesheet sağlanmıştır, ancak bunda bulunan yollar gerçek değildir. + +```csv title="assets/samplesheet.csv" linenums="1" +sample,fastq_1,fastq_2 +SAMPLE_PAIRED_END,/path/to/fastq/files/AEG588A1_S1_L002_R1_001.fastq.gz,/path/to/fastq/files/AEG588A1_S1_L002_R2_001.fastq.gz +SAMPLE_SINGLE_END,/path/to/fastq/files/AEG588A4_S4_L003_R1_001.fastq.gz, + +``` + +Bu belirli samplesheet oldukça basittir, ancak bazı pipeline'lar, birincil girdilerle ilişkili çok daha fazla meta veriye sahip, daha karmaşık samplesheet'ler üzerinde çalışır. + +Ne yazık ki, bu dosyaların göz ile kontrol edilmesi zor olabileceğinden, girdi verilerinin uygunsuz biçimlendirilmesi çok yaygın bir pipeline başarısızlık kaynağıdır. +İlgili bir sorun, parametrelerin yanlış sağlanmasıdır. + +Bu sorunların çözümü, tüm girdi dosyalarında beklenen bilgi türlerini içerdiklerinden ve doğru biçimlendirildiğinden emin olmak için otomatik doğrulama kontrolleri çalıştırmak ve parametrelerin beklenen türde olduğundan emin olmak içindir. +Buna girdi doğrulama denir ve ideal olarak pipeline'ı çalıştırmayı denemeden _önce_ yapılmalıdır, girdilerde bir sorun olduğunu öğrenmek için pipeline'ın başarısız olmasını beklemek yerine. + +Yapılandırma için olduğu gibi, nf-core projesi girdi doğrulama konusunda çok kararlıdır ve Nextflow pipeline'ları için kapsamlı doğrulama yetenekleri sağlayan bir Nextflow eklentisi olan [nf-schema eklentisinin](https://nextflow-io.github.io/nf-schema/latest/) kullanılmasını önerir. + +Bu konuyu bu kursun 5. Bölümünde daha ayrıntılı olarak ele alacağız. +Şimdilik, bu amaç için sağlanan `nextflow_schema.json` ve `assets/schema_input.json` olmak üzere iki JSON dosyası olduğunun farkında olun. + +`nextflow_schema.json`, tip, açıklama ve yardım metni dahil olmak üzere pipeline parametreleri hakkında bilgileri makine tarafından okunabilir bir formatta saklamak için kullanılan bir dosyadır. +Bu, otomatik parametre doğrulama, yardım metni oluşturma ve UI arayüzlerinde etkileşimli parametre formu oluşturma dahil olmak üzere çeşitli amaçlar için kullanılır. + +`schema_input.json`, girdi samplesheet yapısını tanımlamak için kullanılan bir dosyadır. +Her sütun, makine tarafından okunabilir bir formatta bir tip, desen, açıklama ve yardım metnine sahip olabilir. +Şema, otomatik doğrulama ve yararlı hata mesajları sağlama dahil olmak üzere çeşitli amaçlar için kullanılır. + +### Çıkarım + +Bir nf-core pipeline'ının ana bileşenlerinin neler olduğunu ve kodun nasıl düzenlendiğini; yapılandırmanın ana öğelerinin nerede bulunduğunu biliyorsunuz; ve girdi doğrulamanın ne için olduğunun farkındasınız. + +### Sırada ne var? + +Bir mola verin! Bu çoktu. Kendinizi tazelenmiş ve hazır hissettiğinizde, öğrendiklerinizi bir nf-core uyumlu pipeline yazmak için uygulamak üzere bir sonraki bölüme geçin. + +!!! tip + + Bir sonraki bölüme geçmeden önce subworkflow'larla workflow'ların nasıl oluşturulacağını öğrenmek isterseniz, [Workflow'ların Workflow'ları](../side_quests/workflows_of_workflows.md) Yan Görevi'ne göz atın. diff --git a/docs/tr/docs/hello_nf-core/02_rewrite_hello.md b/docs/tr/docs/hello_nf-core/02_rewrite_hello.md new file mode 100644 index 0000000000..47910c3eb7 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/02_rewrite_hello.md @@ -0,0 +1,1340 @@ +# Bölüm 2: Hello'yu nf-core için yeniden yazma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu Hello nf-core eğitim kursunun ikinci bölümünde, [Hello Nextflow](../hello_nextflow/index.md) başlangıç kursu tarafından üretilen pipeline'ın nf-core uyumlu bir versiyonunu nasıl oluşturacağınızı gösteriyoruz. + +Eğitimin ilk bölümünde nf-core pipeline'larının çok sayıda yardımcı dosya ile oldukça detaylı bir yapıyı takip ettiğini fark etmişsinizdir. +Tüm bunları sıfırdan oluşturmak çok yorucu olurdu, bu yüzden nf-core topluluğu, süreci başlatmak için bunun yerine bir şablondan yapılmasını sağlayan araçlar geliştirmiştir. + +Bu araçları kullanarak bir pipeline iskeleti oluşturmayı, ardından mevcut 'normal' pipeline kodunu nf-core iskeleti üzerine nasıl uyarlayacağınızı göstereceğiz. + +Eğer Hello pipeline'ına aşina değilseniz veya hatırlatmaya ihtiyacınız varsa, [bu bilgi sayfasına](../info/hello_pipeline.md) bakın. + +--- + +## 1. Yeni bir pipeline projesi oluşturma + +İlk olarak, yeni pipeline için iskeleyi oluşturuyoruz. + +!!! note + + Terminalinizde `hello-nf-core` dizininde olduğunuzdan emin olun. + +### 1.1. Şablon tabanlı pipeline oluşturma aracını çalıştırma + +Yeni bir pipeline oluşturmak için `nf-core pipelines create` komutu ile başlayalım. +Bu, nf-core temel şablonunu kullanarak, bir pipeline adı, açıklaması ve yazarı ile özelleştirilmiş yeni bir pipeline iskeleti oluşturacaktır. + +```bash +nf-core pipelines create +``` + +Bu komutu çalıştırmak, pipeline oluşturma için bir Metin Kullanıcı Arayüzü (TUI) açacaktır: + +<div style="text-align: center;"> + <iframe width="560" height="315" src="https://www.youtube.com/embed/VwjXNXONHlY?si=d0HkFSISnKn76TeI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" data-ruffle-polyfilled=""></iframe> +</div> + +Bu TUI, pipeline'ınız hakkında temel bilgiler sağlamanızı isteyecek ve pipeline iskelenize dahil edilecek veya hariç tutulacak özellikler seçeneği sunacaktır. + +- Hoş geldiniz ekranında **Let's go!** butonuna tıklayın. +- `Choose pipeline type` ekranında **Custom**'a tıklayın. +- Pipeline bilgilerinizi aşağıdaki gibi girin (`< YOUR NAME >` kısmını kendi adınızla değiştirerek), ardından **Next**'e tıklayın. + +``` +[ ] GitHub organisation: core +[ ] Workflow name: hello +[ ] A short description of your pipeline: A basic nf-core style version of Hello Nextflow +[ ] Name of the main author(s): < YOUR NAME > +``` + +- Template features ekranında, `Toggle all features`'ı **kapalı** olarak ayarlayın, ardından aşağıdakileri seçerek **etkinleştirin**. Seçimlerinizi kontrol edin ve **Continue**'ye tıklayın. + +``` +[ ] Add testing profiles +[ ] Use nf-core components +[ ] Use nf-schema +[ ] Add configuration files +[ ] Add documentation +``` + +- `Final details` ekranında **Finish**'e tıklayın. Pipeline'ın oluşturulmasını bekleyin, ardından **Continue**'ye tıklayın. +- Create GitHub repository ekranında **Finish without creating a repo**'ya tıklayın. Bu, daha sonra bir GitHub repository'si oluşturmak için talimatları görüntüleyecektir. Bunları görmezden gelin ve **Close**'a tıklayın. + +TUI kapandığında, aşağıdaki konsol çıktısını görmelisiniz. + +??? success "Komut çıktısı" + + ```console + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + INFO Launching interactive nf-core pipeline creation tool. + ``` + +Pipeline oluşturmanın çalıştığına dair konsol çıktısında açık bir onay yoktur, ancak `core-hello` adında yeni bir dizin görmelisiniz. + +Şablonu kullanarak kendinize ne kadar iş kazandırdığınızı görmek için yeni dizinin içeriğini görüntüleyin. + +```bash +tree core-hello +``` + +??? abstract "Dizin içeriği" + + ```console + core-hello/ + ├── assets + │ ├── samplesheet.csv + │ └── schema_input.json + ├── conf + │ ├── base.config + │ ├── modules.config + │ ├── test.config + │ └── test_full.config + ├── docs + │ ├── output.md + │ ├── README.md + │ └── usage.md + ├── main.nf + ├── modules.json + ├── nextflow.config + ├── nextflow_schema.json + ├── README.md + ├── subworkflows + │ ├── local + │ │ └── utils_nfcore_hello_pipeline + │ │ └── main.nf + │ └── nf-core + │ ├── utils_nextflow_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ └── nextflow.config + │ ├── utils_nfcore_pipeline + │ │ ├── main.nf + │ │ ├── meta.yml + │ │ └── tests + │ │ ├── main.function.nf.test + │ │ ├── main.function.nf.test.snap + │ │ ├── main.workflow.nf.test + │ │ ├── main.workflow.nf.test.snap + │ │ └── nextflow.config + │ └── utils_nfschema_plugin + │ ├── main.nf + │ ├── meta.yml + │ └── tests + │ ├── main.nf.test + │ ├── nextflow.config + │ └── nextflow_schema.json + └── workflows + └── hello.nf + + 14 directories, 34 files + ``` + +Bu çok fazla dosya! + +Umarız bunların çoğunu `nf-core/demo` pipeline yapısını incelediğimizde karşılaştığımız dosyalarla aynı olarak tanırsınız. +Ancak hala biraz kaybolmuş hissediyorsanız endişelenmeyin; bu eğitim boyunca önemli kısımları birlikte inceleyeceğiz. + +!!! note + + Bu eğitimin ilk bölümünde incelediğimiz `nf-core/demo` pipeline'ına kıyasla önemli bir fark, `modules` dizininin olmamasıdır. + Bunun nedeni, varsayılan nf-core modüllerinden herhangi birini dahil etmeyi seçmemiş olmamızdır. + +### 1.2. İskeletin işlevsel olduğunu test etme + +İnanın ya da inanmayın, gerçek iş yapmak için henüz herhangi bir modül eklememiş olsanız bile, pipeline iskeleti aslında test profilini kullanarak çalıştırılabilir, tıpkı `nf-core/demo` pipeline'ını çalıştırdığımız gibi. + +```bash +nextflow run ./core-hello -profile docker,test --outdir core-hello-results +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./core-hello/main.nf` [scruffy_marconi] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-11-21_04-47-18 + + Core Nextflow options + runName : scruffy_marconi + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : docker,test + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + -[core/hello] Pipeline completed successfully- + ``` + +Bu, tüm temel bağlantıların yerinde olduğunu gösterir. +Peki çıktılar nerede? Var mı? + +Aslında, standart yürütme raporlarını içeren `core-hello-results` adında yeni bir sonuç dizini oluşturuldu: + +```bash +tree core-hello-results +``` + +??? abstract "Dizin içeriği" + + ```console + core-hello-results + └── pipeline_info + ├── execution_report_2025-11-21_04-47-18.html + ├── execution_timeline_2025-11-21_04-47-18.html + ├── execution_trace_2025-11-21_04-47-18.txt + ├── hello_software_versions.yml + ├── params_2025-11-21_04-47-18.json + └── pipeline_dag_2025-11-21_04-47-18.html + + 1 directory, 6 files + ``` + +Ne çalıştırıldığını görmek için raporlara bir göz atabilirsiniz ve cevap şu: hiçbir şey! + +![boş yürütme zaman çizelgesi raporu](./img/execution_timeline_empty.png) + +Kodda gerçekte ne olduğuna bir göz atalım. + +### 1.3. Yer tutucu workflow'u inceleme + +`main.nf` dosyasının içine bakarsanız, `workflows/hello` içinden `HELLO` adlı bir workflow import ettiğini göreceksiniz. + +Bu, Bölüm 1'de karşılaştığımız `workflows/demo.nf` workflow'una eşdeğerdir ve bazı nf-core işlevleri zaten yerinde olan ilgilendiğimiz workflow için yer tutucu olarak hizmet eder. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="15 17 19 35" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +[Hello Nextflow](../hello_nextflow/index.md)'da geliştirilen temel bir Nextflow workflow'una kıyasla, burada yeni olan birkaç şey fark edeceksiniz (yukarıdaki vurgulanan satırlar): + +- Workflow bloğunun bir adı var +- Workflow girdileri `take:` anahtar kelimesi kullanılarak bildirilir ve kanal oluşturma üst workflow'a taşınır +- Workflow içeriği bir `main:` bloğunun içine yerleştirilir +- Çıktılar `emit:` anahtar kelimesi kullanılarak bildirilir + +Bunlar, workflow'u **birleştirilebilir** yapan Nextflow'un isteğe bağlı özellikleridir, yani başka bir workflow içinden çağrılabilir. + +!!! note "Derinlemesine birleştirilebilir workflow'lar" + + [Workflows of Workflows](../side_quests/workflows_of_workflows.md) Side Quest, workflow kompozisyonunu çok daha derinlemesine inceliyor, birden fazla workflow'u birlikte nasıl oluşturacağınızı ve aralarındaki karmaşık veri akışlarını nasıl yöneteceğinizi içeriyor. Burada birleştirilebilirliği tanıtıyoruz çünkü bu, pipeline başlatma, ana analiz workflow'u ve tamamlama görevlerini ayrı, yeniden kullanılabilir bileşenlere organize etmek için iç içe workflow'lar kullanan nf-core şablon mimarisinin temel bir gereksinimidir. + +İlgilendiğimiz workflow'dan ilgili mantığı bu yapıya eklemek zorunda kalacağız. +Bunun için ilk adım orijinal workflow'umuzu birleştirilebilir hale getirmektir. + +### Çıkarım + +Artık nf-core araçlarını kullanarak bir pipeline iskeleti oluşturmayı biliyorsunuz. + +### Sırada ne var? + +Basit bir workflow'u nf-core uyumlu hale getirmenin bir ön adımı olarak nasıl birleştirilebilir yapacağınızı öğrenin. + +--- + +## 2. Orijinal Hello Nextflow workflow'unu birleştirilebilir hale getirme + +Şimdi workflow'umuzu nf-core iskeletine entegre etmek için çalışma zamanı. Hatırlatma olarak, [Hello Nextflow](../hello_nextflow/index.md) eğitim kursumuzdaki workflow ile çalışıyoruz. + +!!! tip + + O pipeline'a aşina değilseniz veya hatırlatmaya ihtiyacınız varsa, [The Hello pipeline](../info/hello_pipeline.md) sayfasına bakın. + +Size, tamamlanmış Hello Nextflow workflow'unun temiz, tamamen işlevsel bir kopyasını `original-hello` dizininde modülleri ve girdi olarak kullanmasını beklediği varsayılan CSV dosyası ile birlikte sağlıyoruz. + +```bash +tree original-hello/ +``` + +??? abstract "Dizin içeriği" + + ```console + original-hello/ + ├── hello.nf + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nextflow.config + + 1 directory, 6 files + ``` + +Çalıştığından emin olmak için çekinmeden çalıştırın: + +```bash +nextflow run original-hello/hello.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/hello.nf` [goofy_babbage] DSL2 - revision: e9e72441e9 + + executor > local (8) + [a4/081cec] sayHello (1) | 3 of 3 ✔ + [e7/7e9058] convertToUpper (3) | 3 of 3 ✔ + [0c/17263b] collectGreetings | 1 of 1 ✔ + [94/542280] cowpy | 1 of 1 ✔ + ``` + +Kodu incelemek için `hello.nf` workflow dosyasını açalım, aşağıda tam olarak gösterilmiştir (modüller içinde olan process'ler sayılmaz): + +```groovy title="original-hello/hello.nf" linenums="1" +#!/usr/bin/env nextflow + +/* +* Pipeline parametreleri +*/ +params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Modülleri dahil et +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow { + + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(collectGreetings.out.outfile, params.character) +} +``` + +Gördüğünüz gibi, bu workflow kendi başına çalıştırılabilen basit bir adsız workflow olarak yazılmıştır. +Bunu nf-core şablonunun gerektirdiği gibi bir üst workflow içinden çalıştırılabilir hale getirmek için **birleştirilebilir** yapmamız gerekiyor. + +Gerekli değişiklikleri tek tek inceleyelim. + +### 2.1. Workflow'a ad verme + +İlk olarak, workflow'a bir üst workflow'dan ona başvurabilmek için bir ad verelim. + +=== "Sonra" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow HELLO { + ``` + +=== "Önce" + + ```groovy title="original-hello/hello.nf" linenums="16" + workflow { + ``` + +Workflow adları için modül adlarında olduğu gibi aynı kurallar geçerlidir. + +### 2.2. Kanal oluşturmayı `take` ile değiştirme + +Şimdi, kanal oluşturmayı beklenen girdileri bildiren basit bir `take` ifadesi ile değiştirin. + +=== "Sonra" + + ```groovy title="original-hello/hello.nf" linenums="18" + take: + // channel of greetings + greeting_ch + ``` + +=== "Önce" + + ```groovy title="original-hello/hello.nf" linenums="18" + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + ``` + +Bu, girdilerin nasıl sağlandığının ayrıntılarını üst workflow'a bırakır. + +Bu arada, `params.greeting = 'greetings.csv'` satırını da yorum satırı yapabiliriz + +=== "Sonra" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parametreleri + */ + //params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +=== "Önce" + + ```groovy title="original-hello/hello.nf" linenums="3" hl_lines="4" + /* + * Pipeline parametreleri + */ + params.greeting = 'greetings.csv' + params.batch = 'test-batch' + params.character = 'turkey' + ``` + +!!! note + + Nextflow dil sunucusu uzantısı yüklüyse, sözdizimi denetleyicisi kodunuzu kırmızı dalgalı çizgilerle işaretleyecektir. + Bunun nedeni, bir `take:` ifadesi koyarsanız, aynı zamanda bir `main:` de olması gerektiğidir. + + Bunu bir sonraki adımda ekleyeceğiz. + +### 2.3. Workflow işlemlerinin önüne `main` ifadesi ekleme + +Ardından, workflow gövdesinde çağrılan işlemlerin geri kalanından önce bir `main` ifadesi ekleyin. + +=== "Sonra" + + ```groovy title="original-hello/hello.nf" linenums="22" hl_lines="1" + main: + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Önce" + + ```groovy title="original-hello/hello.nf" linenums="21" + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Bu temel olarak 'bu workflow'un _yaptığı_ budur' der. + +### 2.4. `emit` ifadesi ekleme + +Son olarak, workflow'un son çıktılarının ne olduğunu bildiren bir `emit` ifadesi ekleyin. + +```groovy title="original-hello/hello.nf" linenums="35" + emit: + cowpy_hellos = cowpy.out +``` + +Bu, orijinal workflow'a kıyasla koda tamamen yeni bir eklentidir. + +### 2.5. Tamamlanan değişikliklerin özeti + +Tüm değişiklikleri açıklandığı gibi yaptıysanız, workflow'unuz şimdi şöyle görünmelidir: + +```groovy title="original-hello/hello.nf" linenums="1" hl_lines="16 18-20 22 36-37" +#!/usr/bin/env nextflow + +/* +* Pipeline parametreleri +*/ +// params.greeting = 'greetings.csv' +params.batch = 'test-batch' +params.character = 'turkey' + +// Modülleri dahil et +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' + +workflow HELLO { + + take: + // channel of greetings + greeting_ch + + main: + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(collectGreetings.out.outfile, params.character) + + emit: + cowpy_hellos = cowpy.out +} +``` + +Bu, Nextflow'un ihtiyaç duyduğu her şeyi açıklar, girdi kanalına ne besleyeceğimiz HARİÇ. +Bu, **giriş noktası** workflow'u olarak da adlandırılan üst workflow'da tanımlanacaktır. + +### 2.6. Kukla bir giriş noktası workflow'u yapma + +Birleştirilebilir workflow'umuzu karmaşık nf-core iskeletine entegre etmeden önce, doğru çalıştığını doğrulayalım. +Birleştirilebilir workflow'u izole bir şekilde test etmek için basit bir kukla giriş noktası workflow'u yapabiliriz. + +Aynı `original-hello` dizininde `main.nf` adında boş bir dosya oluşturun. + +```bash +touch original-hello/main.nf +``` + +Aşağıdaki kodu `main.nf` dosyasına kopyalayın. + +```groovy title="original-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow + +// import the workflow code from the hello.nf file +include { HELLO } from './hello.nf' + +// declare input parameter +params.greeting = 'greetings.csv' + +workflow { + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } + + // call the imported workflow on the channel of greetings + HELLO(greeting_ch) + + // view the outputs emitted by the workflow + HELLO.out.view { output -> "Output: $output" } +} +``` + +Burada yapılacak iki önemli gözlem var: + +- İçe aktarılan workflow'u çağırma sözdizimi, modülleri çağırma sözdizimi ile esasen aynıdır. +- Girdileri workflow'a çekmeyle ilgili her şey (girdi parametresi ve kanal oluşturma) artık bu üst workflow'da bildirilir. + +!!! note + + Giriş noktası workflow dosyasını `main.nf` olarak adlandırmak bir kural, bir gereklilik değildir. + + Bu kurala uyarsanız, `nextflow run` komutunuzda workflow dosya adını belirtmeyi atlayabilirsiniz. + Nextflow, yürütme dizininde `main.nf` adlı bir dosyayı otomatik olarak arayacaktır. + + Ancak, isterseniz giriş noktası workflow dosyasını başka bir şey olarak adlandırabilirsiniz. + Bu durumda, `nextflow run` komutunuzda workflow dosya adını belirttiğinizden emin olun. + +### 2.7. Workflow'un çalıştığını test etme + +Sonunda birleştirilebilir workflow'un çalıştığını doğrulamak için ihtiyacımız olan tüm parçalara sahibiz. +Hadi çalıştıralım! + +```bash +nextflow run ./original-hello +``` + +Burada `main.nf` adlandırma kuralını kullanmanın avantajını görüyorsunuz. +Giriş noktası workflow'unu `something_else.nf` olarak adlandırsaydık, `nextflow run original-hello/something_else.nf` yapmak zorunda kalacaktık. + +Tüm değişiklikleri doğru yaptıysanız, bu tamamlanana kadar çalışmalıdır. + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `original-hello/main.nf` [friendly_wright] DSL2 - revision: 1ecd2d9c0a + + executor > local (8) + [24/c6c0d8] HELLO:sayHello (3) | 3 of 3 ✔ + [dc/721042] HELLO:convertToUpper (3) | 3 of 3 ✔ + [48/5ab2df] HELLO:collectGreetings | 1 of 1 ✔ + [e3/693b7e] HELLO:cowpy | 1 of 1 ✔ + Output: /workspaces/training/hello-nf-core/work/e3/693b7e48dc119d0c54543e0634c2e7/cowpy-COLLECTED-test-batch-output.txt + ``` + +Bu, HELLO workflow'umuzu başarıyla birleştirilebilir hale getirdiğimiz anlamına gelir. + +### Çıkarım + +Bir workflow'u adlandırarak ve `take`, `main` ve `emit` ifadeleri ekleyerek nasıl birleştirilebilir yapacağınızı ve bir giriş noktası workflow'undan nasıl çağıracağınızı biliyorsunuz. + +### Sırada ne var? + +Temel bir birleştirilebilir workflow'u nf-core iskeletine nasıl aşılayacağınızı öğrenin. + +--- + +## 3. Güncellenmiş workflow mantığını yer tutucu workflow'a uydurma + +Artık birleştirilebilir workflow'umuzun doğru çalıştığını doğruladığımıza göre, bölüm 1'de oluşturduğumuz nf-core pipeline iskeletine geri dönelim. +Az önce geliştirdiğimiz birleştirilebilir workflow'u nf-core şablon yapısına entegre etmek istiyoruz, böylece sonuç şuna benzer bir şey olmalıdır. + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/core-hello.svg" +</figure> + +Peki bunu nasıl gerçekleştiririz? `core-hello/workflows/hello.nf` içindeki (nf-core iskeleti) `HELLO` workflow'unun mevcut içeriğine bir göz atalım. + +```groovy title="core-hello/workflows/hello.nf" linenums="1" +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +include { paramsSummaryMap } from 'plugin/nf-schema' +include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +Genel olarak bu kod, workflow'da çalıştırılan herhangi bir yazılım aracının sürümünü yakalamakla ilgisi olan bazı temizlik dışında çok az şey yapar. + +Bölüm 2'de geliştirdiğimiz orijinal workflow'un birleştirilebilir versiyonundan ilgili kodu eklememiz gerekiyor. + +Bunu şu aşamalarda ele alacağız: + +1. Modülleri kopyalama ve modül import'larını kurma +2. `take` bildirimini olduğu gibi bırakma +3. Workflow mantığını `main` bloğuna ekleme +4. `emit` bloğunu güncelleme + +!!! note + + Bu ilk geçiş için versiyon yakalamayı görmezden geliyoruz ve bunun nasıl bağlanacağını bu eğitimin daha sonraki bir bölümünde inceleyeceğiz. + +### 3.1. Modülleri kopyalama ve modül import'larını kurma + +Hello Nextflow workflow'umuzdaki dört process, `original-hello/modules/` içinde modül olarak saklanır. +Bu modülleri nf-core proje yapısına (`core-hello/modules/local/` altına) kopyalamamız ve nf-core workflow dosyasına import ifadeleri eklememiz gerekiyor. + +İlk olarak modül dosyalarını `original-hello/`'dan `core-hello/`'ya kopyalayalım: + +```bash +mkdir -p core-hello/modules/local/ +cp original-hello/modules/* core-hello/modules/local/. +``` + +Şimdi modül dizininin `core-hello/` altında listelendiğini görmelisiniz. + +```bash +tree core-hello/modules +``` + +??? abstract "Dizin içeriği" + + ```console + core-hello/modules + └── local + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + + 1 directory, 4 files + ``` + +Şimdi modül import ifadelerini kuralım. + +Bunlar `original-hello/hello.nf` workflow'undaki import ifadeleriydi: + +```groovy title="original-hello/hello.nf" linenums="9" +// Modülleri dahil et +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +include { cowpy } from './modules/cowpy.nf' +``` + +`core-hello/workflows/hello.nf` dosyasını açın ve bu import ifadelerini aşağıda gösterildiği gibi ona aktarın. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="8-11" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + ``` + +Burada iki ilginç gözlem daha: + +- Import ifadelerinin biçimlendirmesini nf-core stil kuralına uyacak şekilde uyarladık. +- Modüllerin göreceli yollarını, artık farklı bir iç içe yerleşme seviyesinde saklandıklarını yansıtacak şekilde güncelledik. + +### 3.2. `take` bildirimini olduğu gibi bırakma + +nf-core projesinin, tipik olarak sütunsal veri içeren bir CSV dosyası olan samplesheet kavramı etrafında çok sayıda önceden oluşturulmuş işlevselliği vardır. +`greetings.csv` dosyamız esasen bu olduğundan, mevcut `take` bildirimini olduğu gibi tutacağız ve bir sonraki adımda sadece girdi kanalının adını güncelleyeceğiz. + +```groovy title="core-hello/workflows/hello.nf" linenums="21" + take: + ch_samplesheet // channel: samplesheet read in from --input +``` + +Girdi işleme bu workflow'un yukarısında yapılacaktır (bu kod dosyasında değil). + +### 3.3. Workflow mantığını `main` bloğuna ekleme + +Şimdi modüllerimiz workflow'a açık olduğuna göre, workflow mantığını `main` bloğuna ekleyebiliriz. + +Hatırlatma olarak, orijinal workflow'daki ilgili kod şudur, birleştirilebilir yaptığımızda pek değişmedi (sadece `main:` satırını ekledik): + +```groovy title="original-hello/hello.nf" linenums="22" + main: + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(collectGreetings.out.outfile, params.character) +``` + +`main:`'den sonra gelen kodu workflow'un yeni versiyonuna kopyalamamız gerekiyor. + +Orada zaten workflow tarafından çalıştırılan araçların sürümlerini yakalamakla ilgili bazı kodlar var. Şimdilik bunu olduğu gibi bırakacağız (araç versiyonlarıyla daha sonra ilgileneceğiz). +`ch_versions = channel.empty()` başlatmasını en üstte tutacağız, ardından workflow mantığımızı ekleyeceğiz, versiyon harmanlama kodunu sonda tutacağız. +Bu sıralama mantıklıdır çünkü gerçek bir pipeline'da, process'ler workflow çalışırken `ch_versions` kanalına eklenecek sürüm bilgisi yayar. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" hl_lines="10-20" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + + main: + + ch_versions = Channel.empty() + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="19" + workflow HELLO { + + take: + ch_samplesheet // channel: samplesheet read in from --input + main: + + ch_versions = Channel.empty() + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + + } + ``` + +Ayrıca kodu daha okunabilir yapmak için `main:`'den önce boş bir satır eklediğimizi fark edeceksiniz. + +Bu harika görünüyor, ancak `sayHello()` process'ine ilettiğimiz kanalın adını aşağıda gösterildiği gibi `greeting_ch`'den `ch_samplesheet`'e, `take:` anahtar kelimesi altında yazılanla eşleşecek şekilde güncellememiz gerekiyor. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // bir selamlama yayınla (updated to use the nf-core convention for samplesheets) + sayHello(ch_samplesheet) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // bir selamlama yayınla + sayHello(greeting_ch) + ``` + +Şimdi workflow mantığı doğru şekilde bağlandı. + +### 3.4. `emit` bloğunu güncelleme + +Son olarak, workflow'un son çıktılarının bildirimini içerecek şekilde `emit` bloğunu güncellememiz gerekiyor. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" hl_lines="2" + emit: + cowpy_hellos = cowpy.out + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="55" + emit: + versions = ch_versions // channel: [ path(versions.yml) ] + ``` + +Bu, HELLO workflow'unun kendisinde yapmamız gereken değişiklikleri tamamlar. +Bu noktada, uygulamaya koymayı amaçladığımız genel kod yapısına ulaştık. + +### Çıkarım + +Birleştirilebilir bir workflow'un temel parçalarını bir nf-core yer tutucu workflow'una nasıl yerleştireceğinizi biliyorsunuz. + +### Sırada ne var? + +nf-core pipeline iskeletinde girdilerin nasıl işlendiğini nasıl uyarlayacağınızı öğrenin. + +--- + +## 4. Girdi işlemeyi uyarlama + +Artık workflow mantığımızı nf-core iskeletine başarıyla entegre ettiğimize göre, bir kritik parçayı daha ele almamız gerekiyor: girdi verilerimizin doğru şekilde işlendiğinden emin olmak. +nf-core şablonu, karmaşık genomik veri kümeleri için tasarlanmış sofistike girdi işleme ile birlikte gelir, bu yüzden onu daha basit `greetings.csv` dosyamızla çalışacak şekilde uyarlamamız gerekiyor. + +### 4.1. Girdilerin nerede işlendiğini belirleme + +İlk adım, girdi işlemenin nerede yapıldığını bulmaktır. + +Hello Nextflow workflow'unu birleştirilebilir olacak şekilde yeniden yazdığımızda, girdi parametresi bildirimini bir seviye yukarı, `main.nf` giriş noktası workflow'una taşıdığımızı hatırlayabilirsiniz. +O halde, pipeline iskeleti kapsamında oluşturulan üst düzey `main.nf` giriş noktası workflow'una bir göz atalım: + +```groovy title="core-hello/main.nf" linenums="1" +#!/usr/bin/env nextflow +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + core/hello +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Github : https://github.com/core/hello +---------------------------------------------------------------------------------------- +*/ + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS / WORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { HELLO } from './workflows/hello' +include { PIPELINE_INITIALISATION } from './subworkflows/local/utils_nfcore_hello_pipeline' +include { PIPELINE_COMPLETION } from './subworkflows/local/utils_nfcore_hello_pipeline' +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + NAMED WORKFLOWS FOR PIPELINE +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +// +// WORKFLOW: Run main analysis pipeline depending on type of input +// +workflow CORE_HELLO { + + take: + samplesheet // channel: samplesheet read in from --input + + main: + + // + // WORKFLOW: Run pipeline + // + HELLO ( + samplesheet + ) +} +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + RUN MAIN WORKFLOW +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +workflow { + + main: + // + // SUBWORKFLOW: Run initialisation tasks + // + PIPELINE_INITIALISATION ( + params.version, + params.validate_params, + params.monochrome_logs, + args, + params.outdir, + params.input + ) + + // + // WORKFLOW: Run main workflow + // + CORE_HELLO ( + PIPELINE_INITIALISATION.out.samplesheet + ) + // + // SUBWORKFLOW: Run completion tasks + // + PIPELINE_COMPLETION ( + params.outdir, + params.monochrome_logs, + ) +} + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + THE END +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ +``` + +nf-core projesi iç içe subworkflow'ları yoğun bir şekilde kullanır, bu yüzden bu kısım ilk yaklaşımda biraz kafa karıştırıcı olabilir. + +Burada önemli olan iki workflow tanımlanmıştır: + +- `CORE_HELLO`, `core-hello/workflows/hello.nf` içinde az önce uyarlamayı bitirdiğimiz HELLO workflow'unu çalıştırmak için ince bir sarmalayıcıdır. +- `CORE_HELLO`'yu ve iki diğer subworkflow'u, `PIPELINE_INITIALISATION` ve `PIPELINE_COMPLETION`'ı çağıran adsız bir workflow. + +İşte birbirleriyle nasıl ilişkili olduklarının bir diyagramı: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/hello-nested-workflows.svg" +</figure> + +Önemlisi, bu seviyede bir girdi kanalı oluşturan herhangi bir kod bulamıyoruz, yalnızca `--input` parametresi aracılığıyla sağlanan bir samplesheet'e referanslar. + +Biraz araştırma, girdi işlemenin uygun bir şekilde `core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf`'den import edilen `PIPELINE_INITIALISATION` subworkflow'u tarafından yapıldığını ortaya çıkarır. + +Bu dosyayı açıp aşağı kaydırırsak, bu kod bloğuna geliriz: + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions +``` + +Bu, samplesheet'i ayrıştıran ve HELLO workflow'u tarafından tüketilmeye hazır bir biçimde ileten kanal fabrikasıdır. + +!!! note + + Yukarıdaki sözdizimi daha önce kullandığımızdan biraz farklı, ancak temelde bu: + + ```groovy + channel.<...>.set { ch_samplesheet } + ``` + + şuna eşdeğerdir: + + ```groovy + ch_samplesheet = channel.<...> + ``` + +Bu kod, yazım zamanında çok alana özgü olan ve basit pipeline projemiz için uygun olmayan nf-core pipeline şablonuna dahil edilen örnek samplesheet'e oldukça özgü bazı ayrıştırma ve doğrulama adımları içerir. + +### 4.2. Şablonlu girdi kanalı kodunu değiştirme + +İyi haber, pipeline'ımızın ihtiyaçlarının çok daha basit olması, bu yüzden tüm bunları orijinal Hello Nextflow workflow'unda geliştirdiğimiz kanal oluşturma koduyla değiştirebiliriz. + +Hatırlatma olarak, kanal oluşturma şöyle görünüyordu (çözümler dizininde görüldüğü gibi): + +```groovy title="solutions/composable-hello/main.nf" linenums="10" hl_lines="4" + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.greeting) + .splitCsv() + .map { line -> line[0] } +``` + +Yani sadece bunu küçük değişikliklerle başlatma workflow'una eklememiz gerekiyor: kanal adını `greeting_ch`'den `ch_samplesheet`'e ve parametre adını `params.greeting`'den `params.input`'a güncelliyoruz (vurgulanan satıra bakın). + +=== "Sonra" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-7" + // + // Create channel from input file provided through params.input + // + + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Önce" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="76" hl_lines="5-23" + // + // Create channel from input file provided through params.input + // + + channel + .fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { + meta, fastq_1, fastq_2 -> + if (!fastq_2) { + return [ meta.id, meta + [ single_end:true ], [ fastq_1 ] ] + } else { + return [ meta.id, meta + [ single_end:false ], [ fastq_1, fastq_2 ] ] + } + } + .groupTuple() + .map { samplesheet -> + validateInputSamplesheet(samplesheet) + } + .map { + meta, fastqs -> + return [ meta, fastqs.flatten() ] + } + .set { ch_samplesheet } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Bu, girdi işlemenin çalışmasını sağlamak için yapmamız gereken değişiklikleri tamamlar. + +Mevcut haliyle, bu bizi şema doğrulaması için nf-core'un yerleşik yeteneklerinden yararlanmamıza izin vermez, ancak bunu daha sonra ekleyebiliriz. +Şimdilik, test verileri üzerinde başarıyla çalıştırabileceğimiz bir şeye ulaşmak için mümkün olduğunca basit tutmaya odaklanıyoruz. + +### 4.3. Test profilini güncelleme + +Test verileri ve parametrelerden bahsetmişken, bu pipeline'ın test profilini şablonda sağlanan örnek samplesheet yerine `greetings.csv` mini-samplesheet'i kullanacak şekilde güncelleyelim. + +`core-hello/conf` altında, küçük bir veri örneğini ve tam boyutlu birini test etmek için tasarlanan iki şablonlu test profili buluyoruz: `test.config` ve `test_full.config`. +Pipeline'ımızın amacı göz önüne alındığında, tam boyutlu bir test profili kurmanın gerçekten bir anlamı yok, bu yüzden `test_full.config`'i görmezden gelmekten veya silmekten çekinmeyin. +Birkaç varsayılan parametreyle `greetings.csv` dosyamızda çalışacak şekilde `test.config`'i kurmaya odaklanacağız. + +#### 4.3.1. `greetings.csv` dosyasını kopyalama + +Öncelikle `greetings.csv` dosyasını pipeline projemizde uygun bir yere kopyalamamız gerekiyor. +Tipik olarak küçük test dosyaları `assets` dizininde saklanır, o halde dosyayı çalışma dizinimizden kopyalayalım. + +```bash +cp greetings.csv core-hello/assets/. +``` + +Şimdi `greetings.csv` dosyası test girdisi olarak kullanılmaya hazır. + +#### 4.3.2. `test.config` dosyasını güncelleme + +Şimdi `test.config` dosyasını aşağıdaki gibi güncelleyebiliriz: + +=== "Sonra" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-10" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Girdi verileri + input = "${projectDir}/assets/greetings.csv" + + // Diğer parametreler + batch = 'test' + character = 'tux' + } + ``` + +=== "Önce" + + ```groovy title="core-hello/conf/test.config" linenums="21" hl_lines="6-8" + params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + // Girdi verileri + // TODO nf-core: Test verilerinizin nf-core/test-datasets üzerindeki yollarını belirtin + // TODO nf-core: Test için gerekli parametreleri verin, böylece komut satırı bayrakları gerekmez + input = params.pipelines_testdata_base_path + 'viralrecon/samplesheet/samplesheet_test_illumina_amplicon.csv' + } + ``` + +Önemli noktalar: + +- **`${projectDir}` kullanımı**: Bu, ana workflow betiğinin bulunduğu dizine (pipeline kökü) işaret eden bir Nextflow örtük değişkenidir. Bunu kullanmak, yolun pipeline'ın nereden çalıştırıldığından bağımsız olarak çalışmasını sağlar. +- **Mutlak yollar**: `${projectDir}` kullanarak, küçük test dosyaları için önemli olan mutlak bir yol oluşturuyoruz. +- **Test verisi konumu**: nf-core pipeline'ları tipik olarak küçük test dosyaları için pipeline repository'si içindeki `assets/` dizininde test verilerini saklar veya daha büyük dosyalar için harici test veri kümelerine referans verir. + +Ve bu arada, bunun çok basit makinelerde (Github Codespaces'teki minimal VM'ler gibi) çalışacağından emin olmak için varsayılan kaynak limitlerini sıkılaştıralım: + +=== "Sonra" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 2, + memory: '4.GB', + time: '1.h' + ] + } + ``` + +=== "Önce" + + ```groovy title="core-hello/config/test.config" linenums="13" hl_lines="3-4" + process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] + } + ``` + +Bu, yapmamız gereken kod değişikliklerini tamamlar. + +### 4.4. Pipeline'ı test profiliyle çalıştırma + +Bu çok şeydi, ancak sonunda pipeline'ı çalıştırmayı deneyebiliriz! +Henüz doğrulamayı kurmadığımız için komut satırına `--validate_params false` eklememiz gerektiğini unutmayın (bu daha sonra gelecek). + +```bash +nextflow run core-hello --outdir core-hello-results -profile test,docker --validate_params false +``` + +Tüm değişiklikleri doğru yaptıysanız, tamamlanana kadar çalışmalıdır. + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `core-hello/main.nf` [condescending_allen] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-11-21_07-29-37 + + Core Nextflow options + runName : condescending_allen + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core + workDir : /workspaces/training/hello-nf-core/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (1) + [ed/727b7e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [45/bb6096] CORE_ diff --git a/docs/tr/docs/hello_nf-core/03_use_module.md b/docs/tr/docs/hello_nf-core/03_use_module.md new file mode 100644 index 0000000000..54c5ae2b90 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/03_use_module.md @@ -0,0 +1,810 @@ +# Bölüm 3: Bir nf-core modülü kullanma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core eğitim kursunun bu üçüncü bölümünde, mevcut bir nf-core modülünü nasıl bulacağınızı, kuracağınızı ve pipeline'ınızda kullanacağınızı gösteriyoruz. + +nf-core ile çalışmanın en büyük avantajlarından biri, [nf-core/modules](https://github.com/nf-core/modules) deposundan önceden oluşturulmuş ve test edilmiş modüllerden yararlanabilmektir. +Her işlemi sıfırdan yazmak yerine, en iyi uygulamaları takip eden topluluk tarafından sürdürülen modülleri kurabilir ve kullanabilirsiniz. + +Bunun nasıl çalıştığını göstermek için, `core-hello` pipeline'ındaki özel `collectGreetings` modülünü nf-core/modules'ten `cat/cat` modülü ile değiştireceğiz. + +??? info "Bu bölüme nasıl başlanır" + + Kursun bu bölümü, [Bölüm 2: Hello'yu nf-core için yeniden yazma](./02_rewrite_hello.md) bölümünü tamamladığınızı ve çalışan bir `core-hello` pipeline'ına sahip olduğunuzu varsayar. + + Bölüm 2'yi tamamlamadıysanız veya bu bölüm için yeni başlamak istiyorsanız, `core-hello-part2` çözümünü başlangıç noktanız olarak kullanabilirsiniz. + `hello-nf-core/` dizini içinden şu komutu çalıştırın: + + ```bash + cp -r solutions/core-hello-part2 core-hello + cd core-hello + ``` + + Bu, modül eklemeye hazır tamamen işlevsel bir nf-core pipeline'ı sağlar. + Aşağıdaki komutu çalıştırarak başarıyla çalıştığını test edebilirsiniz: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. Uygun bir nf-core modülü bulma ve kurma + +İlk olarak, mevcut bir nf-core modülünü nasıl bulacağımızı ve pipeline'ımıza nasıl kuracağımızı öğrenelim. + +`collectGreetings` işlemini değiştirmeyi hedefliyoruz. Bu işlem, birden fazla selamlama dosyasını tek bir dosyada birleştirmek için Unix `cat` komutunu kullanıyor. +Dosyaları birleştirmek çok yaygın bir işlemdir, bu nedenle bu amaç için nf-core'da zaten tasarlanmış bir modül olması mantıklıdır. + +Hadi başlayalım. + +### 1.1. nf-core web sitesinde mevcut modüllere göz atma + +nf-core projesi, [https://nf-co.re/modules](https://nf-co.re/modules) adresinde merkezi bir modül kataloğu tutar. + +Web tarayıcınızda modüller sayfasına gidin ve 'concatenate' aramak için arama çubuğunu kullanın. + +![module search results](./img/module-search-results.png) + +Gördüğünüz gibi, birçok sonuç var ve bunların çoğu çok spesifik dosya türlerini birleştirmek için tasarlanmış modüller. +Bunlar arasında, genel amaçlı olan `cat_cat` adlı bir modül görmelisiniz. + +!!! note "Modül adlandırma kuralı" + + Alt çizgi (`_`) karakteri, modül adlarında eğik çizgi (`/`) karakterinin yerine kullanılır. + + nf-core modülleri, bir araç birden fazla komut sağladığında `yazılım/komut` adlandırma kuralını takip eder, örneğin `samtools/view` (samtools paketi, view komutu) veya `gatk/haplotypecaller` (GATK paketi, HaplotypeCaller komutu). + Yalnızca bir ana komut sağlayan araçlar için modüller `fastqc` veya `multiqc` gibi tek seviyeli isimler kullanır. + +Modül belgelerini görüntülemek için `cat_cat` modül kutusuna tıklayın. + +Modül sayfası şunları gösterir: + +- Kısa bir açıklama: "A module for concatenation of gzipped or uncompressed files" +- Kurulum komutu: `nf-core modules install cat/cat` +- Girdi ve çıktı kanal yapısı +- Mevcut parametreler + +### 1.2. Komut satırından mevcut modülleri listeleme + +Alternatif olarak, nf-core araçlarını kullanarak doğrudan komut satırından modülleri de arayabilirsiniz. + +```bash +nf-core modules list remote +``` + +Bu, nf-core/modules deposundaki tüm mevcut modüllerin bir listesini görüntüler, ancak aradığınız modülün adını önceden bilmiyorsanız biraz daha az kullanışlıdır. +Ancak, biliyorsanız, listeyi belirli modülleri bulmak için `grep`'e yönlendirebilirsiniz: + +```bash +nf-core modules list remote | grep 'cat/cat' +``` + +??? success "Komut çıktısı" + + ```console + │ cat/cat + ``` + +Unutmayın ki `grep` yaklaşımı yalnızca adında arama terimi olan sonuçları çeker, bu `cat_cat` için işe yaramaz. + +### 1.3. Modül hakkında detaylı bilgi alma + +Komut satırından belirli bir modül hakkında ayrıntılı bilgi görmek için `info` komutunu kullanın: + +```bash +nf-core modules info cat/cat +``` + +Bu, modül hakkında, girdileri, çıktıları ve temel kullanım bilgileri dahil olmak üzere belgeleri görüntüler. + +??? success "Komut çıktısı" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + ╭─ Module: cat/cat ─────────────────────────────────────────────────╮ + │ 🌐 Repository: https://github.com/nf-core/modules.git │ + │ 🔧 Tools: cat │ + │ 📖 Description: A module for concatenation of gzipped or │ + │ uncompressed files │ + ╰────────────────────────────────────────────────────────────────────╯ + ╷ ╷ + 📥 Inputs │Description │Pattern + ╺━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━╸ + input[0] │ │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + meta (map) │Groovy Map containing sample information │ + │e.g. [ id:'test', single_end:false ] │ + ╶─────────────────┼──────────────────────────────────────────┼───────╴ + files_in (file)│List of compressed / uncompressed files │ * + ╵ ╵ + ╷ ╷ + 📥 Outputs │Description │ Pattern + ╺━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━╸ + file_out │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + meta (map) │Groovy Map containing sample │ + │information │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + ${prefix} (file) │Concatenated file. Will be │ ${file_out} + │gzipped if file_out ends with │ + │".gz" │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions │ │ + ╶─────────────────────┼─────────────────────────────────┼────────────╴ + versions.yml (file)│File containing software versions│versions.yml + ╵ ╵ + + 💻 Installation command: nf-core modules install cat/cat + + ``` + +Bu, web sitesinde bulabileceğiniz bilgilerin tamamen aynısıdır. + +### 1.4. cat/cat modülünü kurma + +Artık istediğimiz modülü bulduğumuza göre, onu pipeline'ımızın kaynak koduna eklememiz gerekiyor. + +İyi haber şu ki nf-core projesi bunu kolaylaştıran bazı araçlar içeriyor. +Özellikle, `nf-core modules install` komutu, kodu almayı ve projenizde kullanılabilir hale getirmeyi tek adımda otomatikleştirmeyi mümkün kılar. + +Pipeline dizininize gidin ve kurulum komutunu çalıştırın: + +```bash +cd core-hello +nf-core modules install cat/cat +``` + +Araç önce bir depo türü belirtmenizi isteyebilir. +(İstemezse, "Son olarak, araç modülü kurmaya devam edecektir" kısmına atlayın.) + +??? success "Komut çıktısı" + + ```console + + ,--./,-. + ___ __ __ __ ___ /,-._.--~\ + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + + nf-core/tools version 3.4.1 - https://nf-co.re + + + WARNING 'repository_type' not defined in .nf-core.yml + ? Is this repository a pipeline or a modules repository? (Use arrow keys) + » Pipeline + Modules repository + ``` + +Öyleyse, varsayılan yanıtı (`Pipeline`) kabul etmek için enter'a basın ve devam edin. + +Araç daha sonra gelecekte bu istemden kaçınmak için projenizin yapılandırmasını değiştirmeyi teklif edecektir. + +??? success "Komut çıktısı" + + ```console + INFO To avoid this prompt in the future, add the 'repository_type' key to your .nf-core.yml file. + ? Would you like me to add this config now? [y/n] (y): + ``` + +Bu kullanışlı araçlardan yararlanmak iyi olur! +Varsayılan yanıtı (evet) kabul etmek için enter'a basın. + +Son olarak, araç modülü kurmaya devam edecektir. + +??? success "Komut çıktısı" + + ```console + INFO Config added to '.nf-core.yml' + INFO Reinstalling modules found in 'modules.json' but missing from directory: + INFO Installing 'cat/cat' + INFO Use the following statement to include this module: + + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Komut otomatik olarak: + +- Modül dosyalarını `modules/nf-core/cat/cat/` dizinine indirir +- Kurulu modülü izlemek için `modules.json` dosyasını günceller +- Workflow'unuzda kullanmak için doğru `include` ifadesini size sağlar + +!!! tip + + Modül kurulum komutunu çalıştırmadan önce geçerli çalışma dizininizin pipeline projenizin kök dizini olduğundan emin olun. + +Modülün doğru şekilde kurulduğunu kontrol edelim: + +```bash +tree -L 4 modules +``` + +??? abstract "Dizin içeriği" + + ```console + modules + ├── local + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + └── nf-core + └── cat + └── cat + ├── environment.yml + ├── main.nf + ├── meta.yml + └── tests + + 5 directories, 7 files + ``` + +Ayrıca nf-core yardımcı programına yerel olarak kurulu modülleri listelemesini söyleyerek kurulumu doğrulayabilirsiniz: + +```bash +nf-core modules list local +``` + +??? success "Komut çıktısı" + + ```console + INFO Repository type: pipeline + INFO Modules installed in '.': + + ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ + ┃ Module Name ┃ Repository ┃ Version SHA ┃ Message ┃ Date ┃ + ┡━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ + │ cat/cat │ nf-core/modules │ 41dfa3f │ update meta.yml of all modules (#8747) │ 2025-07-07 │ + └─────────────┴─────────────────┴─────────────┴────────────────────────────────────────┴────────────┘ + ``` + +Bu, `cat/cat` modülünün artık projenizin kaynak kodunun bir parçası olduğunu doğrular. + +Ancak, yeni modülü gerçekten kullanmak için onu pipeline'ımıza aktarmamız gerekiyor. + +### 1.5. Modül içe aktarmalarını güncelleme + +`workflows/hello.nf` workflow'unun içe aktarma bölümünde `collectGreetings` modülü için olan `include` ifadesini `CAT_CAT` için olan ifade ile değiştirelim. + +Hatırlatma olarak, modül kurulum aracı bize kullanacağımız tam ifadeyi verdi: + +```groovy title="Kurulum komutu tarafından üretilen içe aktarma ifadesi" +include { CAT_CAT } from '../modules/nf-core/cat/cat/main'` +``` + +nf-core kuralının modülleri içe aktarırken büyük harf kullanmak olduğunu unutmayın. + +[core-hello/workflows/hello.nf](core-hello/workflows/hello.nf) dosyasını açın ve aşağıdaki değişikliği yapın: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { collectGreetings } from '../modules/local/collectGreetings.nf' + include { cowpy } from '../modules/local/cowpy.nf' + ``` + +nf-core modülü için yolun yerel modüllerden nasıl farklı olduğuna dikkat edin: + +- **nf-core modülü**: `'../modules/nf-core/cat/cat/main'` (`main.nf` dosyasına referans verir) +- **Yerel modül**: `'../modules/local/collectGreetings.nf'` (tek dosya referansı) + +Modül artık workflow için kullanılabilir, bu nedenle tek yapmamız gereken `collectGreetings` çağrısını `CAT_CAT` kullanacak şekilde değiştirmek. Değil mi? + +O kadar kolay değil. + +Bu noktada, koda dalıp düzenlemeye başlamak cazip gelebilir, ancak yeni modülün ne beklediğini ve ne ürettiğini dikkatlice incelemek için bir an ayırmaya değer. + +Bunu ayrı bir bölüm olarak ele alacağız çünkü henüz ele almadığımız yeni bir mekanizma içeriyor: metadata map'leri (metadata haritaları). + +!!! note + + İsteğe bağlı olarak `collectGreetings.nf` dosyasını silebilirsiniz: + + ```bash + rm modules/local/collectGreetings.nf + ``` + + Ancak, yerel ve nf-core modülleri arasındaki farkları anlamak için referans olarak saklamak isteyebilirsiniz. + +### Önemli çıkarımlar + +Bir nf-core modülünü nasıl bulacağınızı ve projenizde kullanılabilir hale getireceğinizi biliyorsunuz. + +### Sırada ne var? + +Yeni bir modülün ne gerektirdiğini değerlendirin ve onu bir pipeline'a entegre etmek için gereken önemli değişiklikleri belirleyin. + +--- + +## 2. Yeni modülün gereksinimlerini değerlendirme + +Özellikle, modülün **arayüzünü**, yani girdi ve çıktı tanımlarını incelememiz ve değiştirmeye çalıştığımız modülün arayüzüyle karşılaştırmamız gerekiyor. +Bu, yeni modülü doğrudan yerine geçecek bir modül olarak kullanıp kullanamayacağımızı veya kablolamada bazı uyarlamalar yapmamız gerekip gerekmediğini belirlememizi sağlayacaktır. + +İdeal olarak bu, modülü kurmadan _önce_ yapmanız gereken bir şeydir, ama hiç olmamasından iyidir. +(Değeri bilinsin ki, artık istemediğinize karar verdiğiniz modüllerden kurtulmak için bir `uninstall` komutu vardır.) + +!!! note + + CAT_CAT işlemi, farklı sıkıştırma türleri, dosya uzantıları ve benzeri konularla ilgili oldukça akıllı bir işleme içerir, bunlar burada size göstermeye çalıştığımız şeyle doğrudan alakalı değil, bu yüzden çoğunu görmezden geleceğiz ve yalnızca önemli olan kısımlara odaklanacağız. + +### 2.1. İki modülün arayüzlerini karşılaştırma + +Hatırlatma olarak, `collectGreetings` modülümüzün arayüzü şöyle görünüyor: + +```groovy title="modules/local/collectGreetings.nf (alıntı)" linenums="1" hl_lines="6-7 10" +process collectGreetings { + + publishDir 'results', mode: 'copy' + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt" , emit: outfile +``` + +`collectGreetings` modülü iki girdi alır: + +- `input_files` işlenecek bir veya daha fazla girdi dosyası içerir; +- `batch_name` çıktı dosyasına çalıştırmaya özgü bir ad atamak için kullandığımız bir değerdir, bu bir metadata biçimidir. + +Tamamlandığında, `collectGreetings` `outfile` etiketi ile yayınlanan tek bir dosya yolu çıktılar. + +Karşılaştırmalı olarak, `cat/cat` modülünün arayüzü daha karmaşıktır: + +```groovy title="modules/nf-core/cat/cat/main.nf (alıntı)" linenums="1" hl_lines="11 14" +process CAT_CAT { + tag "$meta.id" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/pigz:2.3.4' : + 'biocontainers/pigz:2.3.4' }" + + input: + tuple val(meta), path(files_in) + + output: + tuple val(meta), path("${prefix}"), emit: file_out + path "versions.yml" , emit: versions +``` + +CAT_CAT modülü tek bir girdi alır, ancak bu girdi iki şey içeren bir demettir: + +- `meta`, metamap adı verilen metadata içeren bir yapıdır; +- `files_in`, `collectGreetings`'in `input_files`'ına eşdeğer olan, işlenecek bir veya daha fazla girdi dosyası içerir. + +Tamamlandığında, CAT_CAT çıktılarını iki kısımda sunar: + +- Metamap ve birleştirilmiş çıktı dosyasını içeren başka bir demet, `file_out` etiketi ile yayınlanır; +- Kullanılan yazılım sürümü hakkında bilgi yakalayan bir `versions.yml` dosyası, `versions` etiketi ile yayınlanır. + +Ayrıca varsayılan olarak çıktı dosyasının metadata'nın bir parçası olan bir tanımlayıcıya göre adlandırılacağını unutmayın (kod burada gösterilmemiştir). + +Sadece koda bakarak bunları takip etmek çok fazla gibi görünebilir, bu yüzden her şeyin nasıl bir araya geldiğini görselleştirmenize yardımcı olacak bir diyagram burada: + +<figure class="excalidraw"> +--8<-- "docs/hello_nf-core/img/module_comparison.svg" +</figure> + +İki modülün içerik açısından benzer girdi gereksinimlerine sahip olduğunu (bir dizi girdi dosyası artı bazı metadata) ancak bu içeriğin nasıl paketleneceği konusunda çok farklı beklentileri olduğunu görebilirsiniz. +Versions dosyasını şimdilik görmezden gelecek olursak, ana çıktıları da eşdeğerdir (birleştirilmiş bir dosya), ancak CAT_CAT ayrıca çıktı dosyasıyla birlikte metamap'i de yayınlar. + +Birazdan göreceğiniz gibi, paketleme farklarıyla başa çıkmak oldukça kolay olacak. +Ancak, metamap kısmını anlamak için size biraz ek bağlam sunmamız gerekiyor. + +### 2.2. Metamap'leri anlama + +Size CAT_CAT modülünün girdi demetinin bir parçası olarak bir metadata map beklediğini söyledik. +Bunun ne olduğuna daha yakından bakmak için birkaç dakika ayıralım. + +**Metadata map**, genellikle kısaca **metamap** olarak adlandırılır, veri birimleri hakkında bilgi içeren Groovy tarzı bir map'tir. +Nextflow pipeline'ları bağlamında, veri birimleri istediğiniz herhangi bir şey olabilir: bireysel örnekler, örnek grupları veya tüm veri kümeleri. + +Geleneksel olarak, bir nf-core metamap'i `meta` olarak adlandırılır ve çıktıları adlandırmak ve veri birimlerini izlemek için kullanılan gerekli `id` alanını içerir. + +Örneğin, tipik bir metadata map şöyle görünebilir: + +```groovy title="Örnek seviyesinde metamap örneği" +[id: 'sample1', single_end: false, strandedness: 'forward'] +``` + +Veya metadata'nın batch seviyesinde eklendiği bir durumda: + +```groovy title="Batch seviyesinde metamap örneği" +[id: 'batch1', date: '25.10.01'] +``` + +Şimdi bunu `CAT_CAT` işlemi bağlamına koyalım; bu işlem girdi dosyalarının bir metamap ile bir demet halinde paketlenmesini bekler ve çıktı demetinin bir parçası olarak metamap'i de çıktılar. + +```groovy title="modules/nf-core/cat/cat/main.nf (alıntı)" linenums="1" hl_lines="2 5" +input: +tuple val(meta), path(files_in) + +output: +tuple val(meta), path("${prefix}"), emit: file_out +``` + +Sonuç olarak, her veri birimi ilgili metadata eklenmiş olarak pipeline üzerinden ilerler. +Sonraki işlemler de bu metadata'ya kolayca erişebilir. + +Size `CAT_CAT` tarafından çıktılanan dosyanın metadata'nın bir parçası olan bir tanımlayıcıya göre adlandırılacağını söylediğimizi hatırlıyor musunuz? +İlgili kod şudur: + +```groovy title="modules/nf-core/cat/cat/main.nf (alıntı)" linenums="35" +prefix = task.ext.prefix ?: "${meta.id}${getFileSuffix(file_list[0])}" +``` + +Bu kabaca şu anlama gelir: eğer harici görev parametre sistemi (`task.ext`) aracılığıyla bir `prefix` sağlanırsa, çıktı dosyasını adlandırmak için onu kullan; aksi takdirde metamap'teki `id` alanına karşılık gelen `${meta.id}` kullanarak bir tane oluştur. + +Bu modüle gelen girdi kanalının şöyle içeriklerle geldiğini hayal edebilirsiniz: + +```groovy title="Örnek girdi kanalı içeriği" +ch_input = [[[id: 'batch1', date: '25.10.01'], ['file1A.txt', 'file1B.txt']], + [[id: 'batch2', date: '25.10.26'], ['file2A.txt', 'file2B.txt']], + [[id: 'batch3', date: '25.11.14'], ['file3A.txt', 'file3B.txt']]] +``` + +Ardından çıkan çıktı kanalı içeriği şöyle çıkar: + +```groovy title="Örnek çıktı kanalı içeriği" +ch_input = [[[id: 'batch1', date: '25.10.01'], 'batch1.txt'], + [[id: 'batch2', date: '25.10.26'], 'batch2.txt'], + [[id: 'batch3', date: '25.11.14'], 'batch3.txt']] +``` + +Daha önce de belirtildiği gibi, `tuple val(meta), path(files_in)` girdi kurulumu tüm nf-core modüllerinde kullanılan standart bir modeldir. + +Umarım bunun ne kadar yararlı olabileceğini görmeye başlıyorsunuzdur. +Sadece metadata'ya göre çıktıları adlandırmanıza izin vermekle kalmaz, aynı zamanda farklı parametre değerlerini uygulamak gibi şeyler de yapabilirsiniz ve belirli operatörlerle kombinasyon halinde, pipeline üzerinden akarken verileri gruplayabilir, sıralayabilir veya filtreleyebilirsiniz. + +!!! note "Metadata hakkında daha fazla bilgi" + + Nextflow workflow'larında metadata ile çalışma hakkında, samplesheet'lerden metadata okuma ve işlemeyi özelleştirmek için nasıl kullanılacağı dahil olmak üzere kapsamlı bir giriş için [Workflow'larda metadata](../side_quests/metadata) yan görevine bakın. + +### 2.3. Yapılacak değişiklikleri özetleme + +İncelediklerimize dayanarak, `cat/cat` modülünü kullanmak için pipeline'ımızda yapmamız gereken ana değişiklikler şunlardır: + +- Batch adını içeren bir metamap oluşturma; +- Metamap'i birleştirilecek girdi dosyaları kümesiyle bir demet halinde paketleme (`convertToUpper`'dan çıkan); +- Çağrıyı `collectGreetings()`'ten `CAT_CAT`'e değiştirme; +- `CAT_CAT` işlemi tarafından üretilen demetten çıktı dosyasını `cowpy`'ye geçirmeden önce çıkarma. + +Bu işe yaramalı! Artık bir planımız olduğuna göre, dalmaya hazırız. + +### Önemli çıkarımlar + +Yeni bir modülün girdi ve çıktı arayüzünü gereksinimlerini belirlemek için nasıl değerlendireceğinizi biliyorsunuz ve metamap'lerin nf-core pipeline'ları tarafından metadata'yı pipeline üzerinden akarken verilerle yakından ilişkili tutmak için nasıl kullanıldığını öğrendiniz. + +### Sırada ne var? + +Yeni modülü bir workflow'a entegre edin. + +--- + +## 3. CAT_CAT'i `hello.nf` workflow'una entegre etme + +Artık metamap'ler hakkında her şeyi bildiğinize göre (veya en azından bu kursun amaçları için yeterince), yukarıda özetlediğimiz değişiklikleri gerçekten uygulamanın zamanı geldi. + +Netlik adına, bunu parçalara ayıracağız ve her adımı ayrı ayrı ele alacağız. + +!!! note + + Aşağıda gösterilen tüm değişiklikler `core-hello/workflows/hello.nf` workflow dosyasındaki `main` bloğundaki workflow mantığına yapılır. + +### 3.1. Bir metadata map oluşturma + +İlk olarak, nf-core modüllerinin metamap'in en azından bir `id` alanı içermesini gerektirdiğini aklımızda tutarak, `CAT_CAT` için bir metadata map oluşturmamız gerekiyor. + +Başka metadata'ya ihtiyacımız olmadığından, basit tutabilir ve şöyle bir şey kullanabiliriz: + +```groovy title="Sözdizimi örneği" +def cat_meta = [id: 'test'] +``` + +Ancak `id` değerini sabit kodlamak istemiyoruz; `params.batch` parametresinin değerini kullanmak istiyoruz. +Yani kod şöyle olur: + +```groovy title="Sözdizimi örneği" +def cat_meta = [id: params.batch] +``` + +Evet, temel bir metamap oluşturmak kelimenin tam anlamıyla bu kadar basit. + +Bu satırları `convertToUpper` çağrısından sonra ekleyelim ve `collectGreetings` çağrısını kaldıralım: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="7-8" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Bu, `id`'nin batch adımıza (test profilini kullanırken `test` olacaktır) ayarlandığı basit bir metadata map oluşturur. + +### 3.2. Metadata demetleri içeren bir kanal oluşturma + +Ardından, dosya kanalını metadata ve dosyalar içeren demet kanalına dönüştürün: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="10-11" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // metadata ve dosyaları demet formatında içeren bir kanal oluştur + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Eklediğimiz satır iki şey başarır: + +- `.collect()` `convertToUpper` çıktısından tüm dosyaları tek bir listede toplar +- `.map { files -> tuple(cat_meta, files) }` `CAT_CAT`'in beklediği formatta `[metadata, dosyalar]` demeti oluşturur + +`CAT_CAT` için girdi demetini kurmak için yapmamız gereken tek şey bu. + +### 3.3. CAT_CAT modülünü çağırma + +Şimdi yeni oluşturulan kanal üzerinde `CAT_CAT`'i çağırın: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="13-14" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // metadata ve dosyaları demet formatında içeren bir kanal oluştur + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // nf-core cat/cat modülünü kullanarak dosyaları birleştir + CAT_CAT(ch_for_cat) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // metadata ve dosyaları demet formatında içeren bir kanal oluştur + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +Bu, bu değiştirmenin en karmaşık kısmını tamamlar, ancak henüz bitirmedik: birleştirilmiş çıktıyı `cowpy` işlemine nasıl ileteceğimizi güncellememiz gerekiyor. + +### 3.4. `cowpy` için çıktı dosyasını demetten çıkarma + +Daha önce, `collectGreetings` işlemi doğrudan `cowpy`'ye aktarabileceğimiz bir dosya üretiyordu. +Ancak, `CAT_CAT` işlemi çıktı dosyasına ek olarak metamap'i de içeren bir demet üretir. + +`cowpy` henüz metadata demetlerini kabul etmediğinden (bunu kursun sonraki bölümünde düzelteceğiz), `CAT_CAT` tarafından üretilen demetten çıktı dosyasını `cowpy`'ye vermeden önce çıkarmamız gerekiyor: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="16-17 20" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // metadata ve dosyaları demet formatında içeren bir kanal oluştur + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenate the greetings + CAT_CAT(ch_for_cat) + + // cowpy henüz metadata kullanmadığı için dosyayı demetten çıkar + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(ch_for_cowpy, params.character) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="26" hl_lines="17" + // bir selamlama yayınla + sayHello(ch_samplesheet) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + + // batch adını ID olarak içeren metadata map oluştur + def cat_meta = [ id: params.batch ] + + // metadata ve dosyaları demet formatında içeren bir kanal oluştur + ch_for_cat = convertToUpper.out.collect().map { files -> tuple(cat_meta, files) } + + // concatenate the greetings + CAT_CAT(ch_for_cat) + + // cowpy ile ASCII art oluştur + cowpy(collectGreetings.out.outfile, params.character) + ``` + +`.map{ meta, file -> file }` işlemi, `CAT_CAT` tarafından üretilen `[metadata, dosya]` demetinden dosyayı yeni bir kanala, `ch_for_cowpy`'ye çıkarır. + +Ardından o son satırda `collectGreetings.out.outfile` yerine `ch_for_cowpy`'yi `cowpy`'ye iletmek yeterlidir. + +!!! note + + Kursun sonraki bölümünde, `cowpy`'yi doğrudan metadata demetleriyle çalışacak şekilde güncelleyeceğiz, böylece bu çıkarma adımı artık gerekli olmayacak. + +### 3.5. Workflow'u test etme + +Workflow'un yeni entegre edilen `cat/cat` modülüyle çalıştığını test edelim: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +Bu makul bir hızda çalışmalıdır. + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [evil_pike] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-10-30_18-50-58 + + Core Nextflow options + runName : evil_pike + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b3/f005fd] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [08/f923d0] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [34/3729a9] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [24/df918a] CORE_HELLO:HELLO:cowpy [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +İşlem yürütme listesinde `collectGreetings` yerine artık `CAT_CAT`'in göründüğünü fark edin. + +Ve hepsi bu kadar! Artık pipeline'daki bu adım için özel prototip düzeyinde kod yerine sağlam, topluluk tarafından düzenlenen bir modül kullanıyoruz. + +### Önemli çıkarımlar + +Artık nasıl yapılacağını biliyorsunuz: + +- nf-core modüllerini bulma ve kurma +- Bir nf-core modülünün gereksinimlerini değerlendirme +- Bir nf-core modülüyle kullanmak için basit bir metadata map oluşturma +- Bir nf-core modülünü workflow'unuza entegre etme + +### Sırada ne var? + +Yerel modüllerinizi nf-core kurallarına uyacak şekilde nasıl uyarlayacağınızı öğrenin. +Ayrıca nf-core araçlarını kullanarak bir şablondan yeni nf-core modülleri nasıl oluşturacağınızı da göstereceğiz. diff --git a/docs/tr/docs/hello_nf-core/04_make_module.md b/docs/tr/docs/hello_nf-core/04_make_module.md new file mode 100644 index 0000000000..9ce7e73463 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/04_make_module.md @@ -0,0 +1,1046 @@ +# Bölüm 4: Bir nf-core modülü oluşturma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core eğitim kursunun bu dördüncü bölümünde, modülleri taşınabilir ve sürdürülebilir kılan temel kuralları uygulayarak bir nf-core modülünün nasıl oluşturulacağını göstereceğiz. + +nf-core projesi, Bölüm 2'de iş akışı için kullandığımıza benzer şekilde, düzgün yapılandırılmış modül şablonlarını otomatik olarak oluşturan bir komut (`nf-core modules create`) sağlar. +Ancak öğretim amaçları için, manuel olarak başlayacağız: `core-hello` iş hattınızdaki yerel `cowpy` modülünü adım adım nf-core tarzı bir modüle dönüştüreceğiz. +Bundan sonra, gelecekte daha verimli çalışmak için şablon tabanlı modül oluşturma yöntemini size göstereceğiz. + +??? info "Bu bölüme nasıl başlanır" + + Bu bölüm, [Bölüm 3: Bir nf-core modülü kullanma](./03_use_module.md) kısmını tamamladığınızı ve `CAT_CAT` modülünü iş hattınıza entegre ettiğinizi varsayar. + + Bölüm 3'ü tamamlamadıysanız veya bu bölüm için yeni başlamak istiyorsanız, başlangıç noktanız olarak `core-hello-part3` çözümünü kullanabilirsiniz. + Bu komutları `hello-nf-core/` dizini içinden çalıştırın: + + ```bash + cp -r solutions/core-hello-part3 core-hello + cd core-hello + ``` + + Bu size `CAT_CAT` modülünün zaten entegre edildiği bir iş hattı verir. + Başarıyla çalıştığını test etmek için aşağıdaki komutu çalıştırabilirsiniz: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 1. `cowpy`'yi bir nf-core modülüne dönüştürme + +Bu bölümde, `core-hello` iş hattınızdaki yerel `cowpy` modülüne nf-core kurallarını uygulayarak onu nf-core topluluk standartlarını izleyen bir modüle dönüştüreceğiz. + +Mevcut `cowpy` process modülünün kodu şu şekildedir: + +```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) +process cowpy { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ +} +``` + +Aşağıdaki nf-core kurallarını adım adım uygulayacağız: + +1. **Process adını `COWPY` olarak büyük harfe çevir** - Kurala uymak için. +2. **`COWPY`'yi metadata demetlerini kullanacak şekilde güncelle** - Örnek metadatasını iş akışı boyunca yaymak için. +3. **Araç argüman yapılandırmasını `ext.args` ile merkezileştir** - Arayüzü minimal tutarken modül çok yönlülüğünü artırmak için. +4. **Çıktı adlandırmasını `ext.prefix` ile standartlaştır** - Tutarlılığı teşvik etmek için. +5. **Yayınlama yapılandırmasını merkezileştir** - Tutarlılığı teşvik etmek için. + +Her adımdan sonra, her şeyin beklendiği gibi çalıştığını test etmek için iş hattını çalıştıracağız. + +!!! warning "Çalışma dizini" + + Bu bölümdeki tüm dosya düzenlemeleri ve komut çalıştırmaları için `core-hello` dizininde (iş hattı kök dizininizde) olduğunuzdan emin olun. + + ```bash + cd core-hello + ``` + +### 1.1. Process adını büyük harfe çevirme + +Bu tamamen stilistik bir kuraldır (teknik bir gerekçesi yoktur) ancak nf-core modülleri için norm olduğu için uyalım. + +Üç dizi değişiklik yapmamız gerekiyor: + +1. Modüldeki process adını güncelle +2. İş akışı başlığındaki modül import ifadesini güncelle +3. İş akışı gövdesindeki process çağrısını ve emit bildirimini güncelle + +Başlayalım! + +#### 1.1.1. Modüldeki process adını güncelleme + +`cowpy.nf` modül dosyasını açın (`core-hello/modules/local/` altında) ve process adını büyük harfe çevirin: + +=== "Sonra" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + ``` + +=== "Önce" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="3" hl_lines="2" + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + ``` + +Bu durumda büyük harfe çevirme tamamen basittir. + +Eğer process adı birkaç kelimeden oluşsaydı, örneğin orijinalde camel case ile yazılmış MyCowpyTool gibi bir process'imiz olsaydı, nf-core kuralı onları ayırmak için alt çizgi kullanmak olurdu, bu da MY_COWPY_TOOL sonucunu verir. + +#### 1.1.2. Modül import ifadesini güncelleme + +Process adları büyük/küçük harfe duyarlıdır, bu nedenle process adını değiştirdiğimize göre, modül import ifadesini `hello.nf` iş akışı başlığında buna göre güncellememiz gerekiyor: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { COWPY } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="1" hl_lines="10" + /* + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT MODULES / SUBWORKFLOWS / FUNCTIONS + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + include { paramsSummaryMap } from 'plugin/nf-schema' + include { softwareVersionsToYAML } from '../subworkflows/nf-core/utils_nfcore_pipeline' + include { sayHello } from '../modules/local/sayHello.nf' + include { convertToUpper } from '../modules/local/convertToUpper.nf' + include { cowpy } from '../modules/local/cowpy/main.nf' + include { CAT_CAT } from '../modules/nf-core/cat/cat/main' + ``` + +Process çağrılarını güncellemek zorunda kalmamak için import ifadesinde bir alias kullanabilirdik, ancak bu büyük harfe çevirme kuralını benimsemenin amacını biraz bozardı. + +#### 1.1.3. Process çağrısını ve emit bildirimini güncelleme + +Şimdi `hello.nf` workflow bloğundaki process'e yapılan iki referansı güncelleyelim: + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy ile selamlamaların ASCII sanatını oluştur + COWPY(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2 17" + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(CAT_CAT.out.file_out) + + // + // Collate and save software versions + // + softwareVersionsToYAML(ch_versions) + .collectFile( + storeDir: "${params.outdir}/pipeline_info", + name: 'hello_software_' + 'versions.yml', + sort: true, + newLine: true + ).set { ch_collated_versions } + + + emit: + cowpy_hellos = cowpy.out.cowpy_output + versions = ch_versions + ``` + +**Her iki** değişikliği de yaptığınızdan emin olun, aksi takdirde bunu çalıştırdığınızda hata alırsınız. + +#### 1.1.4. Test etmek için iş hattını çalıştırma + +Bu değişikliklerden sonra her şeyin doğru çalıştığını test etmek için iş akışını çalıştıralım. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [elegant_plateau] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2026-01-06_04-51-29 + + Core Nextflow options + runName : elegant_plateau + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [7b/66ceb5] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [8e/1bafb9] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [bb/203575] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [39/715489] CORE_HELLO:HELLO:COWPY | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Pekala, bu çalışıyor! Şimdi daha önemli değişiklikler yapmaya geçelim. + +### 1.2. `COWPY`'yi metadata demetlerini kullanacak şekilde güncelleme + +`core-hello` iş hattının mevcut versiyonunda, aşağıdaki diyagramın üst yarısında gösterildiği gibi, `CAT_CAT`'in çıktı demetinden dosyayı çıkarıp `COWPY`'ye aktarıyoruz. + +<figure class="excalidraw"> + --8<-- "docs/hello_nf-core/img/cowpy-inputs.svg" +</figure> + +`COWPY`'nin metadata demetlerini doğrudan kabul etmesi daha iyi olurdu, bu da metadatanın diyagramın alt yarısında gösterildiği gibi iş akışı boyunca akmasına izin verir. + +Bu amaçla, aşağıdaki değişiklikleri yapmamız gerekecek: + +1. Girdi ve çıktı tanımlarını güncelle +2. İş akışındaki process çağrısını güncelle +3. İş akışındaki emit bloğunu güncelle + +Tüm bunları yaptıktan sonra, her şeyin daha önce olduğu gibi çalıştığını test etmek için iş hattını çalıştıracağız. + +#### 1.2.1. Girdi ve çıktı tanımlarını güncelleme + +`cowpy.nf` modül dosyasına dönün ve aşağıda gösterildiği gibi metadata demetlerini kabul edecek şekilde değiştirin. + +=== "Sonra" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + ``` + +=== "Önce" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="11" hl_lines="2 6" + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + ``` + +Gördüğünüz gibi, hem **ana girdide** hem de **çıktıda** Bölüm 3'te tanıtılan `tuple val(meta), path(input_file)` desenini izleyen bir demet kullanacak şekilde değiştirdik. +Çıktı için, bu fırsattan yararlanarak çıktı kanalına açıklayıcı bir ad vermek için `emit: cowpy_output` ekledik. + +Artık process'in ne beklediğini değiştirdiğimize göre, process çağrısında ona sağladığımız şeyi güncellememiz gerekiyor. + +#### 1.2.2. İş akışındaki process çağrısını güncelleme + +İyi haber şu ki bu değişiklik process çağrısını basitleştirecek. +Artık `CAT_CAT` çıktısı ve `COWPY` girdisi aynı 'şekle' sahip, yani her ikisi de bir `tuple val(meta), path(input_file)` yapısından oluşuyor, bu nedenle `CAT_CAT` process'inin çıktısından dosyayı açıkça çıkarmak yerine onları doğrudan bağlayabiliriz. + +`hello.nf` iş akışı dosyasını açın (`core-hello/workflows/` altında) ve `COWPY` çağrısını aşağıda gösterildiği gibi güncelleyin. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="2" + // cowpy ile selamlamaların ASCII sanatını oluştur + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="43" hl_lines="1-2 5" + // extract the file from the tuple since cowpy doesn't use metadata yet + ch_for_cowpy = CAT_CAT.out.file_out.map{ meta, file -> file } + + // cowpy ile selamlamaların ASCII sanatını oluştur + COWPY(ch_for_cowpy, params.character) + ``` + +Artık `COWPY`'yi doğrudan `CAT_CAT.out.file_out` üzerinde çağırıyoruz. + +Sonuç olarak, artık `ch_for_cowpy` kanalını oluşturmamıza gerek yok, bu nedenle o satır (ve yorum satırı) tamamen silinebilir. + +#### 1.2.3. İş akışındaki emit bloğunu güncelleme + +`COWPY` artık adlandırılmış bir çıktı, `cowpy_output`, yayınladığından, `hello.nf` iş akışının `emit:` bloğunu bunu kullanacak şekilde güncelleyebiliriz. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out.cowpy_output + versions = ch_versions + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="60" hl_lines="2" + emit: + cowpy_hellos = COWPY.out + versions = ch_versions + ``` + +Bu teknik olarak gerekli değil, ancak mümkün olduğunda adlandırılmış çıktılara başvurmak iyi bir uygulamadır. + +#### 1.2.4. Test etmek için iş hattını çalıştırma + +Bu değişikliklerden sonra her şeyin doğru çalıştığını test etmek için iş akışını çalıştıralım. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [modest_saha] DSL2 - revision: b9e9b3b8de + + Downloading plugin nf-schema@2.5.1 + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-16-55 + + Core Nextflow options + runName : modest_saha + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [a8/447993] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [00/1fc59c] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [57/ac800d] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [b7/092f2b] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +İş hattı başarıyla çalışmalı, metadata artık `CAT_CAT`'ten `COWPY`'ye akıyor. + +`COWPY`'yi metadata demetlerini işleyecek şekilde yapmak için yapmamız gerekenleri tamamladık. +Şimdi, nf-core modül desenlerinden yararlanmak için başka neler yapabileceğimize bakalım. + +### 1.3. Araç argüman yapılandırmasını `ext.args` ile merkezileştirme + +Mevcut durumunda, `COWPY` process'i `character` parametresi için bir değer almayı bekler. +Sonuç olarak, process'i her çağırdığımızda, araç tarafından belirlenen varsayılanlarla mutlu olsak bile bir değer sağlamamız gerekir. +`COWPY` için bu kabul edilebilir bir sorun değil, ancak birçok opsiyonel parametresi olan araçlar için oldukça zahmetli olabilir. + +nf-core projesi, araç argümanlarını yapılandırma dosyaları aracılığıyla daha rahat yönetmek için [`ext.args`](https://www.nextflow.io/docs/latest/reference/process.html#ext) adlı bir Nextflow özelliği kullanmayı önerir. + +Her araç seçeneği için process girdileri bildirmek yerine, modülü komut satırının oluşturulmasında `ext.args`'a başvuracak şekilde yazarsınız. +Sonra sadece tüm modüller için yapılandırma detaylarını merkezileştiren `modules.config` dosyasında kullanmak istediğiniz argümanları ve değerleri tutacak şekilde `ext.args` değişkenini ayarlamanız yeterlidir. +Nextflow bu argümanları değerleriyle birlikte çalışma zamanında araç komut satırına ekleyecektir. + +Bu yaklaşımı `COWPY` modülüne uygulayalım. +Aşağıdaki değişiklikleri yapmamız gerekecek: + +1. `COWPY` modülünü güncelle +2. `modules.config` dosyasında `ext.args`'ı yapılandır +3. `hello.nf` iş akışını güncelle + +Tüm bunları yaptıktan sonra, her şeyin daha önce olduğu gibi çalıştığını test etmek için iş hattını çalıştıracağız. + +#### 1.3.1. `COWPY` modülünü güncelleme + +Hadi yapalım. +`cowpy.nf` modül dosyasını açın (`core-hello/modules/local/` altında) ve aşağıda gösterildiği gibi `ext.args`'a başvuracak şekilde değiştirin. + +=== "Sonra" + + ```groovy title="modules/local/cowpy.nf" linenums="1" hl_lines="18 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +=== "Önce" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="13 20" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + tuple val(meta), path(input_file) + val character + + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + """ + cat $input_file | cowpy -c "$character" > cowpy-${input_file} + """ + } + ``` + +Üç değişiklik yaptığımızı görebilirsiniz. + +1. **`input:` bloğunda, `val character` girdisini kaldırdık.** + Bundan sonra, bu argümanı aşağıda açıklandığı gibi `ext.args` yapılandırması aracılığıyla sağlayacağız. + +2. **`script:` bloğunda, `def args = task.ext.args ?: ''` satırını ekledik.** + Bu satır, `args` değişkeninin değerini belirlemek için `?:` operatörünü kullanır: boş değilse `task.ext.args` içeriği, boşsa boş bir string. + Genel olarak `ext.args`'a atıfta bulunsak da, bu kodun modül düzeyindeki `ext.args` yapılandırmasını çekmek için `task.ext.args`'a başvurması gerektiğini unutmayın. + +3. **Komut satırında, `-c "$character"` yerine `$args` kullandık.** + Nextflow'un `modules.config` dosyasındaki `ext.args` içinde ayarlanan tüm araç argümanlarını enjekte edeceği yer burasıdır. + +Sonuç olarak, modül arayüzü artık daha basit: sadece temel metadata ve dosya girdilerini bekliyor. + +!!! note + + `?:` operatörü genellikle 'Elvis operatörü' olarak adlandırılır çünkü yanal olarak Elvis Presley yüzüne benzer, `?` karakteri saçındaki dalgayı simgeler. + +#### 1.3.2. `modules.config` dosyasında `ext.args`'ı yapılandırma + +Artık `character` bildirimini modülden çıkardığımıza göre, onu `modules.config` yapılandırma dosyasındaki `ext.args`'a eklememiz gerekiyor. + +Özellikle, `process {}` bloğuna şu kod parçasını ekleyeceğiz: + +```groovy title="Eklenecek kod" +withName: 'COWPY' { + ext.args = { "-c ${params.character}" } +} +``` + +`withName:` sözdizimi bu yapılandırmayı yalnızca `COWPY` process'ine atar ve `ext.args = { "-c ${params.character}" }` basitçe `character` parametresinin değerini içerecek bir string oluşturur. +Nextflow'a parametre değerini çalışma zamanında değerlendirmesini söyleyen küme parantezlerinin kullanımına dikkat edin. + +Anlamlı mı? Hadi ekleyelim. + +`conf/modules.config` dosyasını açın ve yapılandırma kodunu aşağıda gösterildiği gibi `process {}` bloğu içine ekleyin. + +=== "Sonra" + + ```groovy title="core-hello/conf/modules.config" linenums="13" hl_lines="8-10" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + } + ``` + +=== "Önce" + + ```groovy title="core-hello/conf/modules.config" linenums="13" + process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] + } + ``` + +Umarım bir iş hattındaki tüm modüllerin `ext.args` değerlerinin bu dosyada belirtildiğini hayal edebilirsiniz, bu da aşağıdaki faydaları sağlar: + +- **Modül arayüzü basit kalır** - Sadece temel metadata ve dosya girdilerini kabul eder +- **İş hattı hala `params.character` gösterir** - Son kullanıcılar daha önce olduğu gibi yapılandırabilir +- **Modül artık taşınabilir** - Belirli bir parametre adı beklemeden diğer iş hatlarında yeniden kullanılabilir +- **Yapılandırma merkezileştirilmiş** - `modules.config` içinde, iş akışı mantığını temiz tutar + +`modules.config` dosyasını tüm iş hatlarının modül başına yapılandırmayı merkezileştirdiği yer olarak kullanarak, modüllerimizi farklı iş hatlarında daha yeniden kullanılabilir hale getiriyoruz. + +#### 1.3.3. `hello.nf` iş akışını güncelleme + +`COWPY` modülü artık girdi olarak `character` parametresini gerektirmediğinden, iş akışı çağrısını buna göre güncellememiz gerekiyor. + +`hello.nf` iş akışı dosyasını açın (`core-hello/workflows/` altında) ve `COWPY` çağrısını aşağıda gösterildiği gibi güncelleyin. + +=== "Sonra" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy ile selamlamaların ASCII sanatını oluştur + COWPY(CAT_CAT.out.file_out) + ``` + +=== "Önce" + + ```groovy title="core-hello/workflows/hello.nf" linenums="39" hl_lines="2" + // cowpy ile selamlamaların ASCII sanatını oluştur + COWPY(CAT_CAT.out.file_out, params.character) + ``` + +İş akışı kodu artık daha temiz: `params.character`'ı doğrudan process'e geçirmemize gerek yok. +Modül arayüzü minimal tutularak daha taşınabilir hale getirilirken, iş hattı hala yapılandırma aracılığıyla açık seçeneği sağlar. + +#### 1.3.4. Test etmek için iş hattını çalıştırma + +İş akışının hala beklendiği gibi çalıştığını test edelim, `ext.args` yapılandırmasının çalıştığını doğrulamak için farklı bir karakter belirterek. + +Daha... gizemli seçeneklerden biri olan `kosh` kullanarak bu komutu çalıştırın: + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false --character kosh +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [exotic_planck] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-23-13 + + Core Nextflow options + runName : exotic_planck + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [13/9e3c0e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [e2/5b0ee5] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b6/4fb569] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [38/eb29ea] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Bu daha önce olduğu gibi başarıyla çalışmalıdır. + +`ext.args` yapılandırmasının çalıştığını doğrulamak için çıktıyı kontrol edelim. +Çıktıyı dosya tarayıcıda bulun veya çıktı dosyasına bakmak için görev hash'ini (yukarıdaki örnekte `38/eb29ea` kısmı) kullanın: + +```bash +cat work/38/eb29ea*/cowpy-test.txt +``` + +??? success "Komut çıktısı" + + ```console + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ + \ + \ + ___ _____ ___ + / \ / /| / \ + | | / / | | | + | | /____/ | | | + | | | | | | | + | | | {} | / | | + | | |____|/ | | + | | |==| | | + | \___________/ | + | | + | | + ``` + +`kosh` karakteriyle gösterilen ASCII sanatını görmelisiniz, `ext.args` yapılandırmasının çalıştığını doğrulayarak! + +??? info "(Opsiyonel) Komut dosyasını inceleyin" + + Yapılandırmanın tam olarak nasıl uygulandığını görmek istiyorsanız, `.command.sh` dosyasını inceleyebilirsiniz: + + ```bash + cat work/38/eb29ea*/.command.sh + ``` + + `-c kosh` argümanıyla `cowpy` komutunu göreceksiniz: + + ```console + #!/usr/bin/env bash + ... + cat test.txt | cowpy -c kosh > cowpy-test.txt + ``` + + Bu, `.command.sh` dosyasının `ext.args` yapılandırmasına göre doğru şekilde oluşturulduğunu gösterir. + +Burada ne başardığımızı düşünmek için bir dakikanızı ayırın. +Bu yaklaşım, modül arayüzünü temel verilere (dosyalar, metadata ve zorunlu örnek başına parametreler) odaklı tutarken, aracın davranışını kontrol eden seçenekler ayrı olarak yapılandırma yoluyla ele alınır. + +Bu, `cowpy` gibi basit bir araç için gereksiz görünebilir, ancak çok sayıda opsiyonel argümanı olan veri analiz araçları için büyük fark yaratabilir. + +Bu yaklaşımın faydalarını özetlemek gerekirse: + +- **Temiz arayüz**: Modül temel veri girdilerine (metadata ve dosyalar) odaklanır +- **Esneklik**: Kullanıcılar, örneğe özel değerler dahil olmak üzere, yapılandırma yoluyla araç argümanlarını belirtebilir +- **Tutarlılık**: Tüm nf-core modülleri bu deseni takip eder +- **Taşınabilirlik**: Modüller sabit kodlanmış araç seçenekleri olmadan yeniden kullanılabilir +- **İş akışı değişikliği yok**: Araç seçeneklerini eklemek veya değiştirmek iş akışı kodunu güncellemeyi gerektirmez + +!!! note + + `ext.args` sistemi, burada ele alınmayan, metadata'ya göre argüman değerlerini dinamik olarak değiştirme dahil olmak üzere güçlü ek yeteneklere sahiptir. Daha fazla ayrıntı için [nf-core modül spesifikasyonlarına](https://nf-co.re/docs/guidelines/components/modules) bakın. + +### 1.4. Çıktı adlandırmasını `ext.prefix` ile standartlaştırma + +Artık `COWPY` process'ine metamap'e erişim verdiğimize göre, başka bir yararlı nf-core deseninden yararlanmaya başlayabiliriz: çıktı dosyalarını metadata'ya göre adlandırma. + +Burada `ext.prefix` adlı bir Nextflow özelliğini kullanacağız, bu da `meta.id` kullanarak (metamap'e dahil edilen tanımlayıcı) modüller arasında çıktı dosya adlandırmasını standartlaştırmamıza ve yine de istenirse modülleri ayrı ayrı yapılandırabilmemize olanak tanıyacak. + +Bu, `ext.args` ile yaptığımıza benzer olacak, ilerledikçe detaylandıracağımız birkaç farkla birlikte. + +Bu yaklaşımı `COWPY` modülüne uygulayalım. +Aşağıdaki değişiklikleri yapmamız gerekecek: + +1. `COWPY` modülünü güncelle +2. `modules.config` dosyasında `ext.prefix` yapılandır + +(İş akışında değişiklik gerekmez.) + +Bunları yaptıktan sonra, her şeyin daha önce olduğu gibi çalıştığını test etmek için iş hattını çalıştıracağız. + +#### 1.4.1. `COWPY` modülünü güncelleme + +`cowpy.nf` modül dosyasını açın (`core-hello/modules/local/` altında) ve aşağıda gösterildiği gibi `ext.prefix`'e başvuracak şekilde değiştirin. + +=== "Sonra" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 6 8" + output: + tuple val(meta), path("${prefix}.txt"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + """ + cat $input_file | cowpy $args > ${prefix}.txt + """ + } + ``` + +=== "Önce" + + ```groovy title="core-hello/modules/local/cowpy.nf" linenums="1" hl_lines="2 7" + output: + tuple val(meta), path("cowpy-${input_file}"), emit: cowpy_output + + script: + def args = task.ext.args ?: '' + """ + cat $input_file | cowpy $args > cowpy-${input_file} + """ + } + ``` + +Üç değişiklik yaptığımızı görebilirsiniz. + +1. **`script:` bloğunda, `prefix = task.ext.prefix ?: "${meta.id}"` satırını ekledik.** + Bu satır, `prefix` değişkeninin değerini belirlemek için `?:` operatörünü kullanır: boş değilse `task.ext.prefix` içeriği, boşsa metamap'ten (`meta.id`) tanımlayıcı. + Genel olarak `ext.prefix`'e atıfta bulunsak da, bu kodun modül düzeyindeki `ext.prefix` yapılandırmasını çekmek için `task.ext.prefix`'e başvurması gerektiğini unutmayın. + +2. **Komut satırında, `cowpy-${input_file}` yerine `${prefix}.txt` kullandık.** + Nextflow'un yukarıdaki satır tarafından belirlenen `prefix` değerini enjekte edeceği yer burasıdır. + +3. **`output:` bloğunda, `path("cowpy-${input_file}")` yerine `path("${prefix}.txt")` kullandık.** + Bu sadece komut satırında yazılana göre dosya yolunun ne olacağını yeniden ifade eder. + +Sonuç olarak, çıktı dosya adı artık mantıklı bir varsayılan (metamap'ten tanımlayıcı) ve uygun dosya formatı uzantısı kullanılarak oluşturuluyor. + +#### 1.4.2. `modules.config` dosyasında `ext.prefix` yapılandırma + +Bu durumda mantıklı varsayılan bizim zevkimiz için yeterince ifade edici değil; daha önce olduğu gibi `cowpy-<id>.txt` araç adını içeren özel bir adlandırma deseni kullanmak istiyoruz. + +Bunu, `ext.args` ile `character` parametresi için yaptığımız gibi `modules.config` dosyasında `ext.prefix` yapılandırarak yapacağız, bu sefer `withName: 'COWPY' {}` bloğu zaten mevcut ve sadece aşağıdaki satırı eklememiz gerekiyor: + +```groovy title="Eklenecek kod" +ext.prefix = { "cowpy-${meta.id}" } +``` + +Bu istediğimiz string'i oluşturacak. +Bu sefer Nextflow'a `meta.id` değerini çalışma zamanında değerlendirmesini söylemek için bir kez daha küme parantezleri kullandığımıza dikkat edin. + +Hadi ekleyelim. + +`conf/modules.config` dosyasını açın ve yapılandırma kodunu aşağıda gösterildiği gibi `process {}` bloğu içine ekleyin. + +=== "Sonra" + + ```groovy title="core-hello/conf/modules.config" linenums="21" hl_lines="3" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + ext.prefix = { "cowpy-${meta.id}" } + } + ``` + +=== "Önce" + + ```groovy title="core-hello/conf/modules.config" linenums="21" + withName: 'COWPY' { + ext.args = { "-c ${params.character}" } + } + ``` + +Merak ediyorsanız, `ext.prefix` closure'ı doğru metadata parçasına erişime sahiptir çünkü yapılandırma, metadata'nın mevcut olduğu process yürütmesi bağlamında değerlendirilir. + +#### 1.4.3. Test etmek için iş hattını çalıştırma + +İş akışının hala beklendiği gibi çalıştığını test edelim. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [admiring_turing] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-29-02 + + Core Nextflow options + runName : admiring_turing + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [b2/e08524] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [13/88939f] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [23/4554e1] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [a3/c6cbe9] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Sonuçlar dizinindeki çıktıya bir göz atın. +Varsayılan batch adına göre, cowpy çıktı dosyasını daha önce olduğu gibi aynı adlandırmayla görmelisiniz: `cowpy-test.txt`. + +??? abstract "Dizin içeriği" + + ```console hl_lines="3" + results + ├── Bonjour-output.txt + ├── cowpy-test.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Modül veya iş akışı kodunda herhangi bir değişiklik yapmak zorunda kalmadan adlandırma desenini değiştirebileceğinizi kendinize kanıtlamak için `conf/modules.config` dosyasındaki `ext.prefix` yapılandırmasını değiştirmekten çekinmeyin. + +Alternatif olarak, bu kısmın hala anında özelleştirilebilir olduğunu kendinize kanıtlamak için komut satırında farklı bir `--batch` parametresi belirterek bunu tekrar çalıştırmayı da deneyebilirsiniz. + +Bu, `ext.prefix`'in modül arayüzünü esnek tutarken tercih ettiğiniz adlandırma kuralını korumanıza nasıl izin verdiğini gösterir. + +Bu yaklaşımın faydalarını özetlemek gerekirse: + +- **Standartlaştırılmış adlandırma**: Çıktı dosyaları genellikle metadata'dan örnek ID'leri kullanılarak adlandırılır +- **Yapılandırılabilir**: Kullanıcılar gerekirse varsayılan adlandırmayı geçersiz kılabilir +- **Tutarlı**: Tüm nf-core modülleri bu deseni takip eder +- **Öngörülebilir**: Çıktı dosyalarının ne olarak adlandırılacağını bilmek kolay + +Oldukça iyi, değil mi? +Peki, modülümüzü nf-core yönergelerine uyacak şekilde iyileştirmek için yapmamız gereken bir önemli değişiklik daha var. + +### 1.5. Yayınlama yapılandırmasını merkezileştirme + +Çıktıları iki farklı dizine yayınladığımızı fark etmiş olabilirsiniz: + +- **`results`** — Başlangıçtan beri yerel modüllerimiz için kullandığımız, modül başına `publishDir` yönergeleri kullanılarak ayrı ayrı ayarlanan orijinal çıktı dizini; +- **`core-hello-results`** — Komut satırında `--outdir` ile ayarlanan, nf-core loglarını ve `CAT_CAT` tarafından yayınlanan sonuçları alan çıktı dizini. + +Bu dağınık ve optimal değil; her şey için tek bir konuma sahip olmak daha iyi olurdu. +Tabii ki, yerel modüllerimizin her birine gidip `publishDir` yönergesini `core-hello-results` dizinini kullanacak şekilde manuel olarak güncelleyebiliriz, ancak bir dahaki sefere çıktı dizinini değiştirmeye karar verirsek ne olur? + +Bireysel modüllerin yayınlama kararları vermesi açıkça gidilecek yol değil, özellikle aynı modülün birçok farklı iş hattında, farklı ihtiyaçları veya tercihleri olan insanlar tarafından kullanılabileceği bir dünyada. +Çıktıların nereye yayınlanacağını iş akışı yapılandırma düzeyinde kontrol edebilmek istiyoruz. + +"Hey," diyebilirsiniz, "`CAT_CAT` çıktılarını `--outdir`'e gönderiyor. Belki onun `publishDir` yönergesini kopyalamalıyız?" + +Evet, bu harika bir fikir. + +Ama onun bir `publishDir` yönergesi yok. (Devam edin, modül koduna bakın.) + +Bunun nedeni, nf-core iş hatlarının, bireysel modüllerde değil `conf/modules.config` dosyasında `publishDir` yapılandırarak iş akışı düzeyinde kontrolü merkezileştirmesidir. +Özellikle, nf-core şablonu, geçersiz kılıcı bir yönerge sağlanmadıkça tüm modüllere uygulanan varsayılan bir `publishDir` yönergesi (önceden tanımlanmış bir dizin yapısıyla) bildirir. + +Bu harika gelmiyor mu? Bu varsayılan yönergeden yararlanmak için yapmamız gereken tek şey yerel modüllerimizden mevcut `publishDir` yönergesini kaldırmak olabilir mi? + +Ne olacağını görmek için bunu `COWPY` üzerinde deneyelim, sonra nasıl çalıştığını anlamak için varsayılan yapılandırma koduna bakacağız. + +Son olarak, istenirse varsayılan davranışın nasıl geçersiz kılınacağını göstereceğiz. + +#### 1.5.1. `COWPY`'den `publishDir` yönergesini kaldırma + +Hadi bunu yapalım. +`cowpy.nf` modül dosyasını açın (`core-hello/modules/local/` altında) ve aşağıda gösterildiği gibi `publishDir` yönergesini kaldırın. + +=== "Sonra" + + ```groovy title="core-hello/modules/local/cowpy.nf (alıntı)" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + ``` + +=== "Önce" + + ```groovy title="core-hello/modules/local/cowpy.nf (alıntı)" linenums="1" hl_lines="6" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process COWPY { + + publishDir 'results', mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + ``` + +Bu kadar! + +#### 1.5.2. Test etmek için iş hattını çalıştırma + +Şimdi iş hattını çalıştırırsak ne olacağına bakalım. + +```bash +nextflow run . --outdir core-hello-results -profile test,docker --validate_params false +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [silly_caravaggio] DSL2 - revision: b9e9b3b8de + + Input/output options + input : /workspaces/training/hello-nf-core/core-hello/assets/greetings.csv + outdir : core-hello-results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + validate_params : false + trace_report_suffix : 2025-12-27_06-35-56 + + Core Nextflow options + runName : silly_caravaggio + containerEngine : docker + launchDir : /workspaces/training/hello-nf-core/core-hello + workDir : /workspaces/training/hello-nf-core/core-hello/work + projectDir : /workspaces/training/hello-nf-core/core-hello + userName : root + profile : test,docker + configFiles : /workspaces/training/hello-nf-core/core-hello/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + executor > local (8) + [db/39978e] CORE_HELLO:HELLO:sayHello (3) [100%] 3 of 3 ✔ + [b5/bf6a8d] CORE_HELLO:HELLO:convertToUpper (3) [100%] 3 of 3 ✔ + [b7/c61842] CORE_HELLO:HELLO:CAT_CAT (test) [100%] 1 of 1 ✔ + [46/5839d6] CORE_HELLO:HELLO:COWPY [100%] 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Mevcut çalışma dizininize bir göz atın. +Şimdi `core-hello-results` ayrıca `COWPY` modülünün çıktılarını da içeriyor. + +??? abstract "Dizin içeriği" + + ```console hl_lines="4-5" + core-hello-results/ + ├── cat + │ └── test.txt + ├── cowpy + │ └── cowpy-test.txt + └── pipeline_info + ├── execution_report_2025-12-27_06-16-55.html + ├── execution_report_2025-12-27_06-23-13.html + ├── execution_report_2025-12-27_06-29-02.html + ├── execution_report_2025-12-27_06-35-56.html + ├── execution_timeline_2025-12-27_06-16-55.html + ├── execution_timeline_2025-12-27_06-23-13.html + ├── execution_timeline_2025-12-27_06-29-02.html + ├── execution_timeline_2025-12-27_06-35-56.html + ├── execution_trace_2025-12-27_06-16-55.txt + ├── execution_trace_2025-12-27_06-23-13.txt + ├── execution_trace_2025-12-27_06-29-02.txt + ├── execution_trace_2025-12-27_06-35-56.txt + ├── hello_software_versions.yml + ├── params_2025-12-27_06-17-00.json + ├── params_2025-12-27_06-23-17.json + ├── params_2025-12-27_06-29-07.json + ├── params_2025-12-27_06-36-01.json + ├── pipeline_dag_2025-12-27_06-16-55.html + ├── pipeline_dag_2025-12-27_06-23-13.html + ├── pipeline_dag_2025-12-27_06-29-02.html + └── pipeline_dag_2025-12-27_06-35-56.html + ``` + +Nextflow'un iş akışı ve modül adlarına göre bu dizin hiyerarşisini oluşturduğunu görebilirsiniz. + +Sorumlu kod `conf/modules.config` dosyasında bulunur. +Bu, nf-core şablonunun bir parçası olan ve tüm process'lere uygulanan varsayılan `publishDir` yapılandırmasıdır: + +```groovy +process { + publishDir = [ + path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" }, + mode: params.publish_dir_mode, + saveAs: { filename -> filename.equals('versions.yml') ? null : filename } + ] +} +``` + +Bu karmaşık görünebilir, bu yüzden üç bileşenin her birine bakalım: + +- **`path:`** Process adına göre çıktı dizinini belirler. + `task.process` içinde yer alan bir process'in tam adı, iş akışı ve modül import hiyerarşisini içerir (`CORE_HELLO:HELLO:CAT_CAT` gibi). + `tokenize` işlemleri bu hiyerarşiyi soyarak sadece process adını alır, sonra herhangi bir alt çizgiden önceki ilk kısmı alır (varsa) ve küçük harfe dönüştürür. + Bu, `CAT_CAT diff --git a/docs/tr/docs/hello_nf-core/05_input_validation.md b/docs/tr/docs/hello_nf-core/05_input_validation.md new file mode 100644 index 0000000000..b2f0e9b951 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/05_input_validation.md @@ -0,0 +1,796 @@ +# Bölüm 5: Girdi doğrulaması + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu Hello nf-core eğitim kursunun beşinci bölümünde, pipeline girdi ve parametrelerini doğrulamak için nf-schema eklentisinin nasıl kullanılacağını gösteriyoruz. + +??? info "Bu bölüme nasıl başlanır" + + Bu bölüm, [Bölüm 4: Bir nf-core modülü oluşturma](./04_make_module.md) kısmını tamamladığınızı ve `COWPY` süreç modülünü pipeline'ınızda nf-core standartlarına göre güncellediğinizi varsayar. + + Bölüm 4'ü tamamlamadıysanız veya bu bölüm için yeni başlamak istiyorsanız, başlangıç noktanız olarak `core-hello-part4` çözümünü kullanabilirsiniz. + Bu komutları `hello-nf-core/` dizininin içinden çalıştırın: + + ```bash + cp -r solutions/core-hello-part4 core-hello + cd core-hello + ``` + + Bu size `COWPY` modülü zaten nf-core standartlarına uygun şekilde yükseltilmiş bir pipeline verir. + Başarılı bir şekilde çalıştığını aşağıdaki komutu çalıştırarak test edebilirsiniz: + + ```bash + nextflow run . --outdir core-hello-results -profile test,docker --validate_params false + ``` + +--- + +## 0. Isınma: Biraz arka plan bilgisi + +### 0.1. Doğrulama neden önemlidir + +Pipeline'ınızı iki saat boyunca çalıştırdığınızı, ancak bir kullanıcının yanlış uzantılı bir dosya sağlaması nedeniyle çöktüğünü düşünün. Ya da saatlerce şifreli hataları ayıklamaya çalıştıktan sonra, bir parametrenin yanlış yazıldığını keşfettiğinizi. Girdi doğrulaması olmadan, bu senaryolar yaygındır. + +Bu örneği düşünün: + +```console title="Doğrulama olmadan" +$ nextflow run my-pipeline --input data.txt --output results + +...2 saat sonra... + +ERROR ~ No such file: 'data.fq.gz' + Expected FASTQ format but received TXT +``` + +Pipeline geçersiz girdileri kabul etti ve başarısız olmadan önce saatlerce çalıştı. Uygun doğrulama ile: + +```console title="Doğrulama ile" +$ nextflow run my-pipeline --input data.txt --output results + +ERROR ~ Validation of pipeline parameters failed! + + * --input (data.txt): File extension '.txt' does not match required pattern '.fq.gz' or '.fastq.gz' + * --output: required parameter is missing (expected: --outdir) + +Pipeline failed before execution - please fix the errors above +``` + +Pipeline hemen net, eyleme dönüştürülebilir hata mesajlarıyla başarısız olur. Bu zaman, hesaplama kaynakları ve hayal kırıklığı tasarrufu sağlar. + +### 0.2. nf-schema eklentisi + +[nf-schema eklentisi](https://nextflow-io.github.io/nf-schema/latest/), Nextflow pipeline'ları için kapsamlı doğrulama yetenekleri sağlayan bir Nextflow eklentisidir. +nf-schema herhangi bir Nextflow workflow'u ile çalışsa da, tüm nf-core pipeline'ları için standart doğrulama çözümüdür. + +nf-schema birkaç temel işlev sağlar: + +- **Parametre doğrulaması**: `nextflow_schema.json` dosyasına karşı pipeline parametrelerini doğrular +- **Örnek çizelgesi doğrulaması**: `assets/schema_input.json` dosyasına karşı girdi dosyalarını doğrular +- **Kanal dönüşümü**: Doğrulanmış örnek çizelgelerini Nextflow kanallarına dönüştürür +- **Yardım metni oluşturma**: Şema tanımlarından otomatik olarak `--help` çıktısı oluşturur +- **Parametre özeti**: Hangi parametrelerin varsayılanlardan farklı olduğunu gösterir + +nf-schema, kullanımdan kaldırılmış nf-validation eklentisinin halefidir ve doğrulama için standart [JSON Schema Draft 2020-12](https://json-schema.org/) kullanır. + +??? info "Nextflow eklentileri nedir?" + + Eklentiler, Nextflow dilinin kendisine yeni işlevsellik ekleyen uzantılardır. `nextflow.config` içindeki bir `plugins{}` bloğu aracılığıyla kurulurlar ve şunları sağlayabilirler: + + - İçe aktarılabilen yeni fonksiyonlar ve sınıflar (`samplesheetToList` gibi) + - Yeni DSL özellikleri ve operatörler + - Harici hizmetlerle entegrasyon + + nf-schema eklentisi `nextflow.config` içinde belirtilir: + + ```groovy + plugins { + id 'nf-schema@2.1.1' + } + ``` + + Kurulduktan sonra, `include { functionName } from 'plugin/plugin-name'` sözdizimini kullanarak eklentilerden fonksiyonları içe aktarabilirsiniz. + +### 0.3. İki tür doğrulama için iki şema dosyası + +Bir nf-core pipeline'ı, iki doğrulama türüne karşılık gelen iki ayrı şema dosyası kullanacaktır: + +| Şema Dosyası | Amaç | Doğruladığı | +| -------------------------- | ------------------------ | --------------------------------------------------------- | +| `nextflow_schema.json` | Parametre doğrulaması | Komut satırı bayrakları: `--input`, `--outdir`, `--batch` | +| `assets/schema_input.json` | Girdi verisi doğrulaması | Örnek çizelgelerin ve girdi dosyalarının içeriği | + +Her iki şema da JSON Schema formatını kullanır; bu, veri yapılarını tanımlamak ve doğrulamak için yaygın olarak benimsenmiş bir standarttır. + +**Parametre doğrulaması** komut satırı parametrelerini (`--outdir`, `--batch`, `--input` gibi bayrakları) doğrular: + +- Parametre türlerini, aralıklarını ve formatlarını kontrol eder +- Gerekli parametrelerin sağlandığından emin olur +- Dosya yollarının var olduğunu doğrular +- `nextflow_schema.json` içinde tanımlanır + +**Girdi verisi doğrulaması** örnek çizelgelerin ve manifest dosyalarının yapısını (verilerinizi tanımlayan CSV/TSV dosyaları) doğrular: + +- Sütun yapısını ve veri türlerini kontrol eder +- Örnek çizelgesinde referans verilen dosya yollarının var olduğunu doğrular +- Gerekli alanların bulunduğundan emin olur +- `assets/schema_input.json` içinde tanımlanır + +!!! warning "Girdi verisi doğrulamasının YAPMADIKLARI" + + Girdi verisi doğrulaması *manifest dosyalarının* (örnek çizelgeler, CSV dosyaları) yapısını kontrol eder, gerçek veri dosyalarınızın (FASTQ, BAM, VCF, vb.) içeriğini DEĞİL. + + Büyük ölçekli veriler için, dosya içeriklerini doğrulamak (BAM bütünlüğünü kontrol etmek gibi), orkestra makinesindeki doğrulama aşamasında değil, çalışan düğümlerinde çalışan pipeline süreçlerinde gerçekleşmelidir. + +### 0.4. Doğrulama ne zaman gerçekleşmelidir? + +```mermaid +graph LR + A[Kullanıcı pipeline'ı çalıştırır] --> B[Parametre doğrulaması] + B -->|✓ Geçerli| C[Girdi verisi doğrulaması] + B -->|✗ Geçersiz| D[Hata: Parametreleri düzeltin] + C -->|✓ Geçerli| E[Pipeline çalışır] + C -->|✗ Geçersiz| F[Hata: Girdi verisini düzeltin] +``` + +Doğrulama, herhangi bir pipeline süreci çalışmadan **önce** gerçekleşmeli, böylece hızlı geri bildirim sağlanır ve hesaplama süresi boşa harcanmaz. + +Şimdi bu ilkeleri uygulamaya koyalım, parametre doğrulamasıyla başlayarak. + +--- + +## 1. Parametre doğrulaması (nextflow_schema.json) + +Pipeline'ımıza parametre doğrulaması ekleyerek başlayalım. Bu, `--input`, `--outdir` ve `--batch` gibi komut satırı bayraklarını doğrular. + +### 1.1. Doğrulamayı girdi dosyası doğrulamasını atlayacak şekilde yapılandırın + +nf-core pipeline şablonu nf-schema ile birlikte gelir ve zaten kurulmuş ve yapılandırılmıştır: + +- nf-schema eklentisi `nextflow.config` içindeki `plugins{}` bloğu aracılığıyla kurulur +- Parametre doğrulaması varsayılan olarak `params.validate_params = true` aracılığıyla etkinleştirilir +- Doğrulama, pipeline başlatma sırasında `UTILS_NFSCHEMA_PLUGIN` alt workflow'u tarafından gerçekleştirilir + +Doğrulama davranışı `nextflow.config` içindeki `validation{}` kapsamı aracılığıyla kontrol edilir. + +İlk olarak parametre doğrulaması üzerinde çalışacağımız (bu bölüm) ve girdi verisi şemasını bölüm 2'ye kadar yapılandırmayacağımız için, geçici olarak nf-schema'ya `input` parametresinin dosya içeriğini doğrulamayı atlamasını söylememiz gerekiyor. + +`nextflow.config` dosyasını açın ve `validation` bloğunu bulun (yaklaşık 246. satır). Girdi dosyası doğrulamasını atlamak için `ignoreParams` ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +Bu yapılandırma nf-schema'ya şunları söyler: + +- **`defaultIgnoreParams`**: `genomes` gibi karmaşık parametrelerin doğrulamasını atla (şablon geliştiricileri tarafından ayarlanır) +- **`ignoreParams`**: `input` parametresinin dosya içeriğinin doğrulamasını atla (geçici; bunu bölüm 2'de yeniden etkinleştireceğiz) +- **`monochromeLogs`**: `true` olarak ayarlandığında doğrulama mesajlarında renkli çıktıyı devre dışı bırak (`params.monochrome_logs` tarafından kontrol edilir) + +!!! note "Input parametresi neden yok sayılıyor?" + + `nextflow_schema.json` içindeki `input` parametresi, `"schema": "assets/schema_input.json"` içerir; bu da nf-schema'ya girdi CSV dosyasının *içeriğini* bu şemaya karşı doğrulamasını söyler. + Bu şemayı henüz yapılandırmadığımız için, bu doğrulamayı geçici olarak yok sayıyoruz. + Girdi verisi şemasını yapılandırdıktan sonra bölüm 2'de bu ayarı kaldıracağız. + +### 1.2. Parametre şemasını inceleyin + +Pipeline şablonumuzla gelen `nextflow_schema.json` dosyasının bir bölümüne bakalım: + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +Parametre şeması gruplara ayrılmıştır. İşte `input_output_options` grubu: + +```json title="core-hello/nextflow_schema.json (alıntı)" linenums="8" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "outdir": { + "type": "string", + "format": "directory-path", + "description": "The output directory where the results will be saved. You have to use absolute paths to storage on Cloud infrastructure.", + "fa_icon": "fas fa-folder-open" + } + } + }, +``` + +Burada açıklanan her girdinin doğrulanabilecek aşağıdaki temel özellikleri vardır: + +- **`type`**: Veri türü (string, integer, boolean, number) +- **`format`**: `file-path` veya `directory-path` gibi özel formatlar +- **`exists`**: Dosya yolları için, dosyanın var olup olmadığını kontrol et +- **`pattern`**: Değerin eşleşmesi gereken düzenli ifade +- **`required`**: Sağlanması gereken parametre adlarının dizisi +- **`mimetype`**: Doğrulama için beklenen dosya mimetype'ı + +Keskin bir gözünüz varsa, kullandığımız `batch` girdi parametresinin şemada henüz tanımlanmadığını fark edebilirsiniz. +Bunu bir sonraki bölümde ekleyeceğiz. + +??? info "Şema parametreleri nereden geliyor?" + + Şema doğrulaması, parametre tanımları için temel olarak `nextflow.config` kullanır. + Workflow betiklerinizin başka yerlerinde (`main.nf` veya modül dosyalarında olduğu gibi) bildirilen parametreler şema doğrulayıcısı tarafından **otomatik olarak** alınmaz. + + Bu, pipeline parametrelerinizi her zaman `nextflow.config` içinde bildirmeniz ve ardından doğrulama kurallarını `nextflow_schema.json` içinde tanımlamanız gerektiği anlamına gelir. + +### 1.3. Batch parametresini ekleyin + +Şema manuel olarak düzenlenebilen bir JSON dosyası olsa da, **manuel düzenleme hataya açıktır ve önerilmez**. +Bunun yerine, nf-core sizin için JSON Schema sözdizimini işleyen ve değişikliklerinizi doğrulayan etkileşimli bir GUI aracı sağlar: + +```bash +nf-core pipelines schema build +``` + +Şöyle bir şey görmelisiniz: + +```console + ,--./,-. + ___ __ __ __ ___ /,-._.--\ +|\ | |__ __ / ` / \ |__) |__ } { +| \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + +nf-core/tools version 3.4.1 - https://nf-co.re + +INFO [✓] Default parameters match schema validation +INFO [✓] Pipeline schema looks valid (found 17 params) +INFO Writing schema with 17 params: 'nextflow_schema.json' +🚀 Launch web builder for customisation and editing? [y/n]: +``` + +Etkileşimli web arayüzünü başlatmak için `y` yazın ve Enter tuşuna basın. + +Tarayıcınız Parametre şeması oluşturucusunu göstererek açılacaktır: + +![Şema oluşturucu arayüzü](./img/schema_build.png) + +`batch` parametresini eklemek için: + +1. Üstteki **"Add parameter"** düğmesine tıklayın +2. Yeni parametreyi "Input/output options" grubuna, `input` parametresinin altına taşımak için sürükleme tutamacını (⋮⋮) kullanın +3. Parametre ayrıntılarını doldurun: + - **ID**: `batch` + - **Description**: `Name for this batch of greetings` + - **Type**: `string` + - **Required**: onay kutusunu işaretleyin + - İsteğe bağlı olarak, simge seçiciden bir simge seçin (örn., `fas fa-layer-group`) + +![Batch parametresinin eklenmesi](./img/schema_add.png) + +İşiniz bittiğinde, sağ üstteki **"Finished"** düğmesine tıklayın. + +Terminalinize döndüğünüzde, şunu göreceksiniz: + +```console +INFO Writing schema with 18 params: 'nextflow_schema.json' +⣾ Use ctrl+c to stop waiting and force exit. +``` + +Şema oluşturucudan çıkmak için `Ctrl+C` tuşlarına basın. + +Araç şimdi `nextflow_schema.json` dosyanızı yeni `batch` parametresiyle güncelledi ve tüm JSON Schema sözdizimini doğru bir şekilde ele aldı. + +### 1.4. Değişiklikleri doğrulayın + +```bash +grep -A 25 '"input_output_options"' nextflow_schema.json +``` + +```json title="core-hello/nextflow_schema.json (alıntı)" linenums="8" hl_lines="19-23" + "input_output_options": { + "title": "Input/output options", + "type": "object", + "fa_icon": "fas fa-terminal", + "description": "Define where the pipeline should find input data and save output data.", + "required": ["input", "outdir", "batch"], + "properties": { + "input": { + "type": "string", + "format": "file-path", + "exists": true, + "schema": "assets/schema_input.json", + "mimetype": "text/csv", + "pattern": "^\\S+\\.csv$", + "description": "Path to comma-separated file containing information about the samples in the experiment.", + "help_text": "You will need to create a design file with information about the samples in your experiment before running the pipeline. Use this parameter to specify its location. It has to be a comma-separated file with 3 columns, and a header row.", + "fa_icon": "fas fa-file-csv" + }, + "batch": { + "type": "string", + "description": "Name for this batch of greetings", + "fa_icon": "fas fa-layer-group" + }, +``` + +`batch` parametresinin şemaya eklendiğini ve "required" alanının artık `["input", "outdir", "batch"]` gösterdiğini görmelisiniz. + +### 1.5. Parametre doğrulamasını test edin + +Şimdi parametre doğrulamasının doğru çalıştığını test edelim. + +İlk olarak, gerekli `input` parametresi olmadan çalıştırmayı deneyin: + +```bash +nextflow run . --outdir test-results -profile docker +``` + +??? warning "Komut çıktısı" + + ```console + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): input, batch + ``` + +Mükemmel! Doğrulama, pipeline çalışmadan önce eksik gerekli parametreyi yakalar. + +Şimdi geçerli bir parametre seti ile deneyin: + +```bash +nextflow run . --input assets/greetings.csv --outdir results --batch my-batch -profile test,docker +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `./main.nf` [peaceful_wozniak] DSL2 - revision: b9e9b3b8de + + executor > local (8) + [de/a1b2c3] CORE_HELLO:HELLO:sayHello (3) | 3 of 3 ✔ + [4f/d5e6f7] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [8a/b9c0d1] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e2/f3a4b5] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Pipeline başarıyla çalışmalı ve `batch` parametresi artık doğrulanıyor. + +### Çıkarım + +Etkileşimli `nf-core pipelines schema build` aracını kullanarak `nextflow_schema.json` dosyasına parametre eklemeyi öğrendiniz ve parametre doğrulamasını eylemde gördünüz. +Web arayüzü sizin için tüm JSON Schema sözdizimini işleyerek, hataya açık manuel JSON düzenlemesi olmadan karmaşık parametre şemalarını yönetmeyi kolaylaştırır. + +### Sırada ne var? + +Artık parametre doğrulaması çalıştığına göre, girdi verisi dosya içeriği için doğrulama ekleyelim. + +--- + +## 2. Girdi verisi doğrulaması (schema_input.json) + +Girdi CSV dosyamızın içeriği için doğrulama ekleyeceğiz. +Parametre doğrulaması komut satırı bayraklarını kontrol ederken, girdi verisi doğrulaması CSV dosyasının içindeki verilerin doğru yapılandırıldığından emin olur. + +### 2.1. greetings.csv formatını anlayın + +Girdimizin nasıl göründüğünü kendimize hatırlatalım: + +```bash +cat assets/greetings.csv +``` + +```csv title="assets/greetings.csv" +Hello,en,87 +Bonjour,fr,96 +Holà,es,98 +``` + +Bu, şunlarla basit bir CSV'dir: + +- Üç sütun (başlık yok) +- Her satırda: bir selamlama, bir dil ve bir puan +- İlk iki sütun özel format gereksinimleri olmayan metin dizileridir +- Üçüncü sütun bir tam sayıdır + +Pipeline'ımız için yalnızca ilk sütun gereklidir. + +### 2.2. Şema yapısını tasarlayın + +Kullanım senaryomuz için şunları istiyoruz: + +1. En az bir sütunlu CSV girdisini kabul et +2. Her satırın ilk öğesini bir selamlama dizisi olarak ele al +3. Selamlamaların boş olmadığından ve boşlukla başlamadığından emin ol +4. Dil alanının desteklenen dil kodlarından biriyle eşleştiğinden emin ol (en, fr, es, it, de) +5. Puan alanının 0 ile 100 arasında bir değere sahip bir tam sayı olduğundan emin ol + +Bunu her nesnenin en azından bir `greeting` alanına sahip olduğu bir nesne dizisi olarak yapılandıracağız. + +### 2.3. Şema dosyasını güncelleyin + +nf-core pipeline şablonu, çift sonlu dizileme verisi için tasarlanmış varsayılan bir `assets/schema_input.json` içerir. +Bunu selamlamalar kullanım senaryomuz için daha basit bir şema ile değiştirmemiz gerekiyor. + +`assets/schema_input.json` dosyasını açın ve `properties` ve `required` bölümlerini değiştirin: + +=== "Sonra" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-25 27" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the greetings file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "greeting": { + "type": "string", + "pattern": "^\\S.*$", + "errorMessage": "Greeting must be provided and cannot be empty or start with whitespace" + }, + "language": { + "type": "string", + "enum": ["en", "fr", "es", "it", "de"], + "errorMessage": "Language must be one of: en, fr, es, it, de" + }, + "score": { + "type": "integer", + "minimum": 0, + "maximum": 100, + "errorMessage": "Score must be an integer with a value between 0 and 100" + } + }, + "required": ["greeting"] + } + } + ``` + +=== "Önce" + + ```json title="assets/schema_input.json" linenums="1" hl_lines="10-29 31" + { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://raw.githubusercontent.com/core/hello/main/assets/schema_input.json", + "title": "core/hello pipeline - params.input schema", + "description": "Schema for the file provided with params.input", + "type": "array", + "items": { + "type": "object", + "properties": { + "sample": { + "type": "string", + "pattern": "^\\S+$", + "errorMessage": "Sample name must be provided and cannot contain spaces", + "meta": ["id"] + }, + "fastq_1": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 1 must be provided, cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + }, + "fastq_2": { + "type": "string", + "format": "file-path", + "exists": true, + "pattern": "^([\\S\\s]*\\/)?[^\\s\\/]+\\.f(ast)?q\\.gz$", + "errorMessage": "FastQ file for reads 2 cannot contain spaces and must have extension '.fq.gz' or '.fastq.gz'" + } + }, + "required": ["sample", "fastq_1"] + } + } + ``` + +Temel değişiklikler: + +- **`description`**: "greetings file" ifadesini içerecek şekilde güncellendi +- **`properties`**: `sample`, `fastq_1` ve `fastq_2` yerine `greeting`, `language` ve `score` konuldu + - **`type:`** String (`greeting`, `language`) veya integer (`score`) zorla + - **`pattern: "^\\S.*$"`**: Selamlama boşluk olmayan bir karakterle başlamalı (ancak bundan sonra boşluk içerebilir) + - **`"enum": ["en", "fr", "es", "it", "de"]`**: Dil kodu desteklenen sette olmalı + - **`"minimum": 0` ve `"maximum": 100`**: Puan değeri 0 ile 100 arasında olmalı + - **`errorMessage`**: Doğrulama başarısız olursa gösterilen özel hata mesajı +- **`required`**: `["sample", "fastq_1"]` yerine `["greeting"]` olarak değiştirildi + +### 2.4. greetings.csv dosyasına bir başlık ekleyin + +nf-schema bir CSV dosyası okuduğunda, ilk satırın şemadaki alan adlarıyla eşleşen sütun başlıkları içermesini bekler. + +Basit durumumuz için, selamlamalar dosyamıza bir başlık satırı eklememiz gerekiyor: + +=== "Sonra" + + ```csv title="assets/greetings.csv" linenums="1" hl_lines="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Önce" + + ```csv title="assets/greetings.csv" linenums="1" + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Artık CSV dosyası, şemamızdaki alan adlarıyla eşleşen bir başlık satırına sahip. + +Son adım, `samplesheetToList` kullanarak pipeline kodunda doğrulamayı uygulamaktır. + +### 2.5. Pipeline'da doğrulamayı uygulayın + +Şimdi basit CSV ayrıştırmamızı nf-schema'nın `samplesheetToList` fonksiyonu ile değiştirmemiz gerekiyor; bu, örnek çizelgesini doğrulayacak ve ayrıştıracak. + +`samplesheetToList` fonksiyonu: + +1. Girdi örnek çizelgesini okur (CSV, TSV, JSON veya YAML) +2. Sağlanan JSON şemasına karşı doğrular +3. Her girdinin bir satıra karşılık geldiği bir Groovy listesi döndürür +4. Doğrulama başarısız olursa yararlı hata mesajları atar + +Girdi işleme kodunu güncelleyelim: + +`subworkflows/local/utils_nfcore_hello_pipeline/main.nf` dosyasını açın ve girdi kanalını oluşturduğumuz bölümü bulun (yaklaşık 80. satır). + +Yapmamız gerekenler: + +1. `samplesheetToList` fonksiyonunu kullan (şablonda zaten içe aktarılmış) +2. Girdiyi doğrula ve ayrıştır +3. Workflow'umuz için sadece selamlama dizilerini çıkar + +İlk olarak, `samplesheetToList` fonksiyonunun dosyanın üst kısmında zaten içe aktarıldığını unutmayın (nf-core şablonu bunu varsayılan olarak içerir): + +```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="1" hl_lines="13" +// +// Subworkflow with functionality specific to the core/hello pipeline +// + +/* +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + IMPORT FUNCTIONS / MODULES / SUBWORKFLOWS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +*/ + +include { UTILS_NFSCHEMA_PLUGIN } from '../../nf-core/utils_nfschema_plugin' +include { paramsSummaryMap } from 'plugin/nf-schema' +include { samplesheetToList } from 'plugin/nf-schema' +include { paramsHelp } from 'plugin/nf-schema' +include { completionSummary } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NFCORE_PIPELINE } from '../../nf-core/utils_nfcore_pipeline' +include { UTILS_NEXTFLOW_PIPELINE } from '../../nf-core/utils_nextflow_pipeline' +``` + +Şimdi kanal oluşturma kodunu güncelleyin: + +=== "Sonra" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromList(samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")) + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +=== "Önce" + + ```groovy title="core-hello/subworkflows/local/utils_nfcore_hello_pipeline/main.nf" linenums="80" hl_lines="4 5" + // + // Create channel from input file provided through params.input + // + ch_samplesheet = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + + emit: + samplesheet = ch_samplesheet + versions = ch_versions + ``` + +Ne değiştiğini açıklayalım: + +1. **`samplesheetToList(params.input, "${projectDir}/assets/schema_input.json")`**: Girdi dosyasını şemamıza karşı doğrular ve bir liste döndürür +2. **`Channel.fromList(...)`**: Listeyi bir Nextflow kanalına dönüştürür + +Bu, `samplesheetToList` ve JSON şemaları kullanarak girdi verisi doğrulamasının uygulanmasını tamamlar. + +Artık girdi verisi şemasını yapılandırdığımıza göre, daha önce eklediğimiz geçici yok sayma ayarını kaldırabiliriz. + +### 2.6. Girdi doğrulamasını yeniden etkinleştirin + +`nextflow.config` dosyasını açın ve `validation` bloğundan `ignoreParams` satırını kaldırın: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + monochromeLogs = params.monochrome_logs + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" hl_lines="3" linenums="246" + validation { + defaultIgnoreParams = ["genomes"] + ignoreParams = ['input'] + monochromeLogs = params.monochrome_logs + } + ``` + +Artık nf-schema hem parametre türlerini HEM de girdi dosyası içeriğini doğrulayacak. + +### 2.7. Girdi doğrulamasını test edin + +Doğrulamanın hem geçerli hem de geçersiz girdilerle çalıştığını test ederek doğrulayalım. + +#### 2.7.1. Geçerli girdi ile test edin + +İlk olarak, pipeline'ın geçerli girdi ile başarıyla çalıştığını onaylayın. +Doğrulama çalıştığı için artık `--validate_params false` kullanmamıza gerek olmadığını unutmayın! + +```bash +nextflow run . --outdir core-hello-results -profile test,docker +``` + +??? success "Komut çıktısı" + + ```console + ------------------------------------------------------ + WARN: The following invalid input values have been detected: + + * --character: tux + + + executor > local (8) + [c1/39f64a] CORE_HELLO:HELLO:sayHello (1) | 3 of 3 ✔ + [44/c3fb82] CORE_HELLO:HELLO:convertToUpper (3) | 3 of 3 ✔ + [62/80fab2] CORE_HELLO:HELLO:CAT_CAT (test) | 1 of 1 ✔ + [e1/4db4fd] CORE_HELLO:HELLO:COWPY (test) | 1 of 1 ✔ + -[core/hello] Pipeline completed successfully- + ``` + +Harika! Pipeline başarıyla çalışır ve doğrulama sessizce geçer. +`--character` hakkındaki uyarı sadece bilgilendiricidir çünkü şemada tanımlı değildir. +İsterseniz, öğrendiklerinizi kullanarak o parametre için de doğrulama ekleyebilirsiniz! + +#### 2.7.2. Geçersiz girdi ile test edin + +Doğrulamayı geçmek her zaman iyi bir histir, ancak doğrulamanın gerçekten hataları yakalayacağından emin olalım. + +Geçersiz bir sütun adına sahip bir test dosyası oluşturmak için, `greetings.csv` dosyasının bir kopyasını oluşturarak başlayın: + +```bash +cp assets/greetings.csv assets/invalid_greetings.csv +``` + +Şimdi dosyayı açın ve başlık satırındaki ilk sütunun adını `greeting` yerine `message` olarak değiştirin: + +=== "Sonra" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + message,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +=== "Önce" + + ```csv title="tmp_invalid_greetings.csv" hl_lines="1" linenums="1" + greeting,language,score + Hello,en,87 + Bonjour,fr,96 + Holà,es,98 + ``` + +Bu, şemamızla eşleşmez, bu nedenle doğrulama bir hata atmalıdır. + +Pipeline'ı bu geçersiz girdi ile çalıştırmayı deneyin: + +```bash +nextflow run . --input assets/invalid_greetings.csv --outdir test-results -profile docker +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.4 + + Launching `./main.nf` [trusting_ochoa] DSL2 - revision: b9e9b3b8de + + Input/output options + input : assets/invalid_greetings.csv + outdir : test-results + + Generic options + trace_report_suffix: 2025-01-27_03-16-04 + + Core Nextflow options + runName : trusting_ochoa + containerEngine : docker + launchDir : /workspace/hello-nf-core + workDir : /workspace/hello-nf-core/work + projectDir : /workspace/hello-nf-core + userName : user + profile : docker + configFiles : /workspace/hello-nf-core/nextflow.config + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + ERROR ~ Validation of pipeline parameters failed! + + -- Check '.nextflow.log' file for details + The following invalid input values have been detected: + + * Missing required parameter(s): batch + * --input (assets/invalid_greetings.csv): Validation of file failed: + -> Entry 1: Missing required field(s): greeting + -> Entry 2: Missing required field(s): greeting + -> Entry 3: Missing required field(s): greeting + + -- Check script 'subworkflows/nf-core/utils_nfschema_plugin/main.nf' at line: 68 or see '.nextflow.log' file for more details + ``` + +Mükemmel! Doğrulama hatayı yakaladı ve şunları gösteren net, yararlı bir hata mesajı sağladı: + +- Hangi dosya doğrulamayı geçemedi +- Hangi girdinin (satır 1, ilk veri satırı) sorunu var +- Belirli sorunun ne olduğu (gerekli `greeting` alanı eksik) + +Şema doğrulaması, pipeline çalışmadan önce girdi dosyalarının doğru yapıya sahip olduğundan emin olarak zaman kazandırır ve yürütme sırasında daha sonra kafa karıştırıcı hataları önler. + +İsterseniz, şemayı başka eğlenceli şekillerde ihlal eden başka selamlamalar girdi dosyaları oluşturarak bunu uygulayabilirsiniz. + +### Çıkarım + +Hem parametre doğrulaması hem de girdi verisi doğrulamasını uyguladınız ve test ettiniz. Pipeline'ınız artık yürütmeden önce girdileri doğrulayarak hızlı geri bildirim ve net hata mesajları sağlıyor. + +!!! tip "Daha fazla bilgi" + + Gelişmiş doğrulama özellikleri ve kalıpları hakkında daha fazla bilgi edinmek için [nf-schema belgelerine](https://nextflow-io.github.io/nf-schema/latest/) göz atın. `nf-core pipelines schema build` komutu, karmaşık şemaları yönetmek için etkileşimli bir GUI sağlar. + +### Sırada ne var? + +Hello nf-core eğitim kursunun beş bölümünün tamamını tamamladınız! + +Oluşturduklarınızı ve öğrendiklerinizi düşünmek için [Özet](summary.md) bölümüne devam edin. diff --git a/docs/tr/docs/hello_nf-core/index.md b/docs/tr/docs/hello_nf-core/index.md new file mode 100644 index 0000000000..13e7ffd571 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/index.md @@ -0,0 +1,69 @@ +```yaml +--- +title: Hello nf-core +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - nf-core pipeline'larını almak, çalıştırmak ve yürütülmesini yönetmek + - nf-core pipeline'larının kod yapısını ve proje organizasyonunu açıklamak + - Bir şablondan temel nf-core uyumlu pipeline oluşturmak + - Düz bir Nextflow iş akışını nf-core standartlarına uyacak şekilde yükseltmek + - nf-core uyumlu bir pipeline'a nf-core modülleri eklemek + - Kendi modüllerinizi nf-core'a katkıda bulunmak + - nf-core araçlarını kullanarak girdileri ve parametreleri doğrulamak + audience_prerequisites: + - "**Hedef Kitle:** Bu kurs, temel Nextflow'a zaten aşina olan ve nf-core kaynaklarını ve en iyi uygulamalarını kullanmayı öğrenmek isteyen katılımcılar için tasarlanmıştır." + - "**Beceriler:** Komut satırı, temel betik yazma kavramları ve yaygın dosya formatları hakkında bilgi sahibi olunduğu varsayılmaktadır." + - "**Kurslar:** [Hello Nextflow](../hello_nextflow/index.md) kursunu veya eşdeğerini tamamlamış olmalıdır." + - "**Alan:** Alıştırmaların tümü alandan bağımsızdır, dolayısıyla önceden bilimsel bilgi gerekmemektedir." +--- + +# Hello nf-core + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Hello nf-core, nf-core kaynaklarını ve en iyi uygulamalarını kullanmaya yönelik uygulamalı bir giriştir.** + +![nf-core logo](./img/nf-core-logo.png) + +Pratik örnekler ve rehberli alıştırmalar üzerinden çalışarak, nf-core uyumlu modüller ve pipeline'lar kullanmayı ve geliştirmeyi, ayrıca nf-core araçlarını etkili bir şekilde kullanmayı öğreneceksiniz. + +nf-core en iyi uygulamalarına göre pipeline geliştirmeye başlamak için gereken becerileri ve özgüveni kazanacaksınız. + +<!-- additional_information --> + +## Kursa genel bakış + +Bu kurs, bilgileri kademeli olarak tanıtmak üzere yapılandırılmış, hedefe yönelik alıştırmalar içeren, uygulamalı bir şekilde tasarlanmıştır. + +Nextflow kullanılarak oluşturulmuş, küratörlüğü yapılmış bir bilimsel pipeline seti geliştirmek ve sürdürmek için bir topluluk çabası olan [**nf-core**](https://nf-co.re/)'un yanı sıra, açık geliştirme, test etme ve akran değerlendirmesini teşvik eden ilgili araçlar ve yönergeler ile tanıştırılacaksınız ([Nat Biotechnol 38, 276–278 (2020)](https://www.nature.com/articles/s41587-020-0439-x), [Genome Biol 26, 228 (2025)](https://genomebiology.biomedcentral.com/articles/10.1186/s13059-025-03673-9)). + +nf-core topluluğu tarafından geliştirilen pipeline'lar modüler, ölçeklenebilir ve taşınabilir olacak şekilde tasarlanmıştır, bu da araştırmacıların kendi verilerini ve hesaplama kaynaklarını kullanarak bunları kolayca uyarlayıp çalıştırmalarına olanak tanır. +Proje tarafından uygulanan en iyi uygulama yönergeleri, pipeline'ların sağlam, iyi belgelenmiş ve gerçek dünya veri setlerine karşı doğrulanmış olmasını sağlar. +Bu, bilimsel analizlerin güvenilirliğini ve tekrarlanabilirliğini artırmaya yardımcı olur ve sonuçta araştırmacıların bilimsel keşiflerini hızlandırmasını sağlar. + +Bu kursta nf-core pipeline'ları hakkında bilmeniz gereken her şeyi ele almayacağız, çünkü nf-core, topluluk tarafından yıllar içinde geliştirilen birçok özellik ve konvansiyonu kapsar. +Bunun yerine, başlamanıza ve nf-core'un nasıl çalıştığını anlamanıza yardımcı olacak temel kavramlara odaklanacağız. + +### Ders planı + +Bunu, nf-core kaynaklarını kullanmanın belirli yönlerine odaklanan beş bölüme ayırdık. + +| Kurs bölümü | Özet | Tahmini süre | +| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| [Bölüm 1: Demo pipeline çalıştırma](./01_run_demo.md) | Mevcut bir nf-core pipeline'ı çalıştırın ve bu pipeline'ları temel Nextflow iş akışlarından farklı kılan şeyleri anlamak için kod yapısını inceleyin | 30 dakika | +| [Bölüm 2: Hello'yu nf-core için yeniden yazma](./02_rewrite_hello.md) | Mevcut bir iş akışını nf-core şablon iskeletine uyarlayın, [Hello Nextflow](../hello_nextflow/index.md) kursunda üretilen basit iş akışından başlayarak | 60 dakika | +| [Bölüm 3: nf-core modülü kullanma](./03_use_module.md) | Topluluk modülleri kütüphanesini keşfedin ve yaygın biyoinformatik araçlarını sarmalayan önceden oluşturulmuş, test edilmiş modülleri entegre etmeyi öğrenin | 30 dakika | +| [Bölüm 4: nf-core modülü oluşturma](./04_make_module.md) | nf-core tarafından belirlenen belirli yapı, adlandırma konvansiyonları ve metadata gereksinimlerini kullanarak kendi nf-core tarzı modülünüzü oluşturun | 30 dakika | +| [Bölüm 5: Girdi doğrulama ekleme](./05_input_validation.md) | nf-schema kullanarak hem komut satırı parametreleri hem de girdi veri dosyaları için girdi doğrulama uygulayın | 30 dakika | + +Bu kursun sonunda, nf-core projesi tarafından sunulan muazzam kaynak zenginliğinden yararlanabileceksiniz. + +Kursa başlamaya hazır mısınız? + +[Öğrenmeye başlayın :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } +``` diff --git a/docs/tr/docs/hello_nf-core/next_steps.md b/docs/tr/docs/hello_nf-core/next_steps.md new file mode 100644 index 0000000000..0e1da9fce5 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/next_steps.md @@ -0,0 +1,51 @@ +# Kurs özeti + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hello nf-core eğitim kursunu tamamladığınız için tebrikler! 🎉 + +<!-- placeholder for video --> + +## Yolculuğunuz + +Bir demo pipeline'ı almayı ve çalıştırmayı öğrenerek başladınız, ardından basit bir Nextflow workflow'unu bir nf-core pipeline'ına dönüştürme görevine girdiniz. +Bir şablon kullanarak bir pipeline iskelesi oluşturmayı ve mevcut pipeline'ı bu iskeleye nasıl yerleştireceğinizi öğrendiniz. +Daha sonra yerel modüllerden birini bir nf-core modülü ile değiştirerek, bir diğer yerel modülü nf-core standartlarına uyacak şekilde dönüştürerek ve girdi doğrulaması ekleyerek pipeline'ı kademeli olarak geliştirdiniz. + +### Oluşturduğunuz yapı + +Final `core-hello` pipeline'ınız artık şunlara sahip: + +- **Standartlaştırılmış yapı**: workflows, subworkflows, modüller ve yapılandırma için düzenlenmiş dizinler içeren nf-core şablonu kullanıyor +- **Topluluk modülleri**: nf-core deposundan (`cat/cat`) özel modüllerinizin yanı sıra +- **Kapsamlı doğrulama**: pipeline çalışmadan önce hem parametreleri hem de girdi verilerini kontrol ediyor +- **Profesyonel yapılandırma**: farklı çalıştırma ortamları için profiller içeriyor +- **Eksiksiz dokümantasyon**: nf-core kurallarına uygun meta veriler + +### Kazanılan temel beceriler + +Bu uygulamalı kurs boyunca şunları öğrendiniz: + +1. Mevcut bir pipeline'ı inceleyerek nf-core pipeline yapısında **gezinme ve anlama** +2. **Workflow'ları yeniden yapılandırma**: birleştirilebilir hale getirme ve nf-core şablonuna uygun hale getirme +3. Topluluk deposundan önceden oluşturulmuş modülleri **bulma ve entegre etme** +4. nf-core standartlarına uygun olarak adlandırma, yapı ve meta veriler için **özel modüller oluşturma** +5. nf-schema kullanarak hataları erken yakalamak ve net geri bildirim sağlamak için **doğrulama uygulama** + +Artık topluluk en iyi uygulamalarını takip eden, üretime hazır nf-core pipeline'ları oluşturmak için temel bilgiye sahipsiniz. + +## Becerilerinizi geliştirmek için sonraki adımlar + +Sırada ne yapabileceğinize dair en iyi 3 önerimiz: + +- [Nextflow for Science](../nf4_science/index.md) ile Nextflow'u bilimsel bir analiz kullanım senaryosuna uygulayın +- [Side Quests](../side_quests/index.md) ile daha gelişmiş Nextflow özelliklerini keşfedin +- [nf-core topluluğuna katılarak](https://nf-co.re/join) katkıda bulunun. + +Son olarak, Nextflow'un yaratıcıları tarafından geliştirilen bulut tabanlı bir platform olan [**Seqera Platform**](https://seqera.io/)'a göz atmanızı öneririz. Bu platform, workflow'larınızı başlatmayı ve yönetmeyi, verilerinizi yönetmeyi ve herhangi bir ortamda etkileşimli olarak analiz çalıştırmayı daha da kolaylaştırır. + +## Geri bildirim anketi + +Devam etmeden önce, lütfen kurs anketini tamamlamak için bir dakikanızı ayırın! Geri bildiriminiz, eğitim materyallerimizi herkes için geliştirmemize yardımcı olur. + +[Anketi doldurun :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/tr/docs/hello_nf-core/survey.md b/docs/tr/docs/hello_nf-core/survey.md new file mode 100644 index 0000000000..09424e71e1 --- /dev/null +++ b/docs/tr/docs/hello_nf-core/survey.md @@ -0,0 +1,9 @@ +# Geri bildirim anketi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Devam etmeden önce, lütfen bu kısa 5 soruluk anketi tamamlayarak eğitimi değerlendirin, deneyiminiz hakkındaki geri bildirimlerinizi paylaşın ve Nextflow yolculuğunuzda size yardımcı olmak için başka neler yapabileceğimizi bize bildirin. + +Bu anketin tamamlanması bir dakikadan kısa sürecektir. Eğitim materyallerimizi herkes için geliştirmemize yardımcı olduğunuz için teşekkür ederiz! + +<div data-tf-live="01KAV2WZ80CXPEKXMK3N1VX740"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/tr/docs/help.md b/docs/tr/docs/help.md new file mode 100644 index 0000000000..7b4817eb90 --- /dev/null +++ b/docs/tr/docs/help.md @@ -0,0 +1,77 @@ +--- +title: Yardım alma +description: Nextflow eğitimiyle ilgili bir sorununuz olduğunda yararlı kaynaklar +hide: + - toc + - footer +--- + +# Yardım alma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +İster başlamakta zorlanıyor olun, ister ortada takılıp kalın veya takip soruları olsun, iletişime geçmekten çekinmeyin! Topluluk ekibimiz yardım etmek için burada ve genel olarak Nextflow topluluğu çok aktif, kapsayıcı ve yardımseverdir. + +Aradığınıza bağlı olarak mevcut olan temel seçenekler şunlardır. + +<div class="grid cards" markdown> + +- :material-forum-outline:{ .lg .middle } __Topluluk forumu__ + + --- + + Topluluk forumumuzda eğitime ayrılmış bir kategori bulunmaktadır ve bu, soru sormak veya yaşadığınız sorunları bildirmek için harika bir yerdir. Sorunuzun zaten sorulmuş ve cevaplanmış olduğunu bile görebilirsiniz! + + [Eğitim forumuna katılın :material-arrow-right:](https://community.seqera.io/c/training/39){ .md-button .md-button--primary .mt-1 } + +- :material-slack:{ .lg .middle } __Slack kanalı__ + + --- + + Slack kullanıyorsanız, Nextflow Slack çalışma alanındaki eğitim kanalından bize ulaşabilirsiniz. Nextflow Slack, diğer geliştiricilerle sohbet etmek ve genel olarak Nextflow topluluğuyla etkileşim kurmak için harika bir yerdir. + + [Nextflow Slack'e katılın :material-arrow-right:](https://www.nextflow.io/slack-invite.html){ .md-button .md-button--primary .mt-1 } + +- :material-github:{ .lg .middle } __Github sorunları__ + + --- + + Eğitim materyallerinde bir hata fark ederseniz, lütfen Github deposunda bir sorun açarak bildirin. İster yazım hatası, ister biçimlendirme sorunu veya kodu etkileyen gerçek bir hata olsun, düzeltebilmemiz için bize bildirin! Doğrudan PR'ları da memnuniyetle karşılıyoruz. + + [Sorun bildirin :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :octicons-comment-ai-16:{ .lg .middle } __Seqera AI asistanı__ + + --- + + Seqera AI, Nextflow ve nf-core kaynakları üzerinde eğitilmiş bir yapay zeka asistanıdır. Kodunuzu hata ayıklamanıza, Nextflow kavramlarını netleştirmenize ve dokümantasyonu daha hızlı aramanıza yardımcı olabilir. Bunu, kurslar üzerinde çalışırken 7/24 yanınızda olan bir öğretmen olarak düşünün. + + [Seqera AI'a sorun :material-arrow-right:](https://github.com/nextflow-io/training/issues){ .md-button .md-button--primary .mt-1 } + +- :material-book-open-variant:{ .lg .middle } __Nextflow dokümantasyonu__ + + --- + + Resmi dokümantasyon, tüm dil özellikleri ve yapılandırma seçenekleri için nihai rehberdir. Belirli konulara daha derinlemesine dalmak, gelişmiş özellikleri keşfetmek ve ayrıntılı söz dizimi referansları bulmak için bu eğitimle birlikte kullanın. + + [Dokümantasyonu inceleyin :material-arrow-right:](https://www.nextflow.io/docs/latest){ .md-button .md-button--primary .mt-1 } + +- :material-account-hard-hat:{ .lg .middle } __Profesyonel destek__ + + --- + + Nextflow, İspanya merkezli olup İngiltere ve ABD'de uydu ofisleri bulunan [Seqera](https://seqera.io/) tarafından geliştirilen ücretsiz, açık kaynaklı bir yazılımdır. Özel eğitim dahil olmak üzere Nextflow için profesyonel destek hizmetleri sunuyoruz. + + [İletişime geçin :material-arrow-right:](https://seqera.io/demo/){ .md-button .md-button--primary .mt-1 } + +</div> + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/tr/docs/index.md b/docs/tr/docs/index.md new file mode 100644 index 0000000000..0cb5a3e2fa --- /dev/null +++ b/docs/tr/docs/index.md @@ -0,0 +1,174 @@ +--- +title: Ana Sayfa +description: Nextflow topluluk eğitim portalına hoş geldiniz! +hide: + - toc + - footer +--- + +# Nextflow Eğitimi + +<div class="grid cards" markdown> + +- :material-book-open-variant:{ .lg .middle } __Bireysel çalışma kursları__ + + --- + + **Nextflow topluluk eğitim portalına hoş geldiniz!** + + Aşağıda listelenen eğitim kursları, bireysel çalışma kaynağı olarak kullanılabilecek şekilde tasarlanmıştır. + Bu kursları istediğiniz zaman, Github Codespaces aracılığıyla sunduğumuz web tabanlı ortamda veya kendi ortamınızda kendi başınıza çalışabilirsiniz. + + [Kursları keşfedin :material-arrow-right:](#nextflow-egitim-kurslari-katalogu){ .md-button .md-button--primary .mt-1 } + +- :material-information-outline:{ .lg .middle } __Ek bilgiler__ + + --- + + ??? warning "Sürüm uyumluluğu" + + <!-- Any update to this content needs to be copied to the local installation page --> + **Ocak 2026 itibarıyla, aksi belirtilmedikçe tüm Nextflow eğitim kurslarımız strict syntax etkinleştirilmiş Nextflow sürüm 25.10.2 veya üstünü gerektirir.** + + Sürüm gereksinimleri ve strict syntax hakkında daha fazla bilgi için lütfen [Nextflow dokümantasyonu geçiş rehberine](https://nextflow.io/docs/latest/strict-syntax.html) bakın. + + Önceki söz dizimine karşılık gelen eğitim materyallerinin eski sürümlerine bu web sayfasının menü çubuğundaki sürüm seçici aracılığıyla ulaşabilirsiniz. + + ??? terminal "Ortam seçenekleri" + + Eğitim için ihtiyacınız olan her şeyin önceden yüklendiği, Github Codespaces aracılığıyla erişilebilen web tabanlı bir eğitim ortamı sunuyoruz (ücretsiz bir GitHub hesabı gerektirir). + + [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + + Bu sizin ihtiyaçlarınızı karşılamıyorsa, lütfen diğer [Ortam seçeneklerine](./envsetup/index.md) bakın. + + ??? learning "Eğitim etkinlikleri" + + Nextflow eğitimini yapılandırılmış bir etkinlik kapsamında almayı tercih ediyorsanız, bunun için birçok fırsat mevcuttur. Aşağıdaki seçeneklere göz atmanızı öneririz: + + - Topluluk ekibi tarafından üç ayda bir düzenlenen **[Eğitim Haftaları]()** + - **[Seqera Etkinlikleri](https://seqera.io/events/)** Seqera tarafından düzenlenen yüz yüze eğitim etkinliklerini içerir ('Seqera Sessions' ve 'Nextflow Summit' için arama yapın) + - **[Nextflow Elçileri]()** yerel topluluklarınız için etkinlikler düzenler + - **[nf-core etkinlikleri](https://nf-co.re/events)** topluluk hackathon'larını içerir + + ??? people "Eğitmenler için bilgiler" + + Kendi eğitimlerinizi yürüten bir eğitmen iseniz, uygun atıf yaptığınız sürece materyallerimizi doğrudan eğitim portalından kullanabilirsiniz. Ayrıntılar için aşağıdaki 'Katkılar ve atıf' bölümüne bakın. + + Ayrıca, eğitim çalışmalarınızı nasıl daha iyi destekleyebileceğimizi öğrenmek isteriz! Lütfen bize [community@seqera.io](mailto:community@seqera.io) adresinden veya topluluk forumundan (bkz. [Yardım](help.md) sayfası) ulaşın. + + ??? licensing "Açık kaynak lisansı ve katkı politikası" + + [![Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](assets/img/cc_by-nc-sa.svg){ align=right }](https://creativecommons.org/licenses/by-nc-sa/4.0/) + + Bu eğitim materyali [Seqera](https://seqera.io) tarafından geliştirilip sürdürülmektedir ve topluluk yararına açık kaynak lisansı ([CC BY-NC-SA](https://creativecommons.org/licenses/by-nc-sa/4.0/)) altında yayınlanmaktadır. Bu materyali lisans kapsamı dışında kullanmak istiyorsanız (ticari kullanım ve yeniden dağıtım kısıtlamalarına dikkat edin), lütfen talebinizi görüşmek için [community@seqera.io](mailto:community@seqera.io) adresinden bize ulaşın. + + Topluluktan gelen iyileştirmeleri, düzeltmeleri ve hata raporlarını memnuniyetle karşılıyoruz. Her sayfanın sağ üst köşesinde kod deposuna bağlanan bir :material-file-edit-outline: simgesi bulunur; burada sorunları bildirebilir veya pull request aracılığıyla eğitim kaynak materyalinde değişiklik önerebilirsiniz. Daha fazla ayrıntı için depodaki `README.md` dosyasına bakın. + +</div> + +!!! note "Yapay Zeka Destekli Çeviri" + + Bu çeviri yapay zeka kullanılarak oluşturulmuş ve insan çevirmenler tarafından gözden geçirilmiştir. + Geri bildirimlerinizi ve iyileştirme önerilerinizi memnuniyetle karşılıyoruz. + Daha fazla bilgi için [çeviri kılavuzumuza](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md) bakın. + +## Nextflow eğitim kursları kataloğu + +<div class="grid cards" markdown> + +- :material-walk:{ .lg .middle } __Giriş seviyesi__ + + --- + + ### :material-compass:{.nextflow-primary} Yeni Başlayanlar için Nextflow {.mt-1} + + Nextflow'a tamamen yeni olanlar için tasarlanmış alana bağımlı olmayan kurslar. Her kurs, öğrencilerin becerilerini kademeli olarak geliştirmelerine yardımcı olmak için tasarlanmış bir dizi eğitim modülünden oluşur. + + ??? courses "**Hello Nextflow:** Kendi iş akışlarınızı geliştirmeyi öğrenin" + + Bu kurs, basit ama tam işlevsel iş akışları geliştirmeye yetecek kadar ayrıntıyla Nextflow dilinin temel bileşenlerini, ayrıca iş akışı tasarımı, geliştirme ve yapılandırma uygulamalarının temel öğelerini kapsar. + + [Hello Nextflow eğitimine başlayın :material-arrow-right:](hello_nextflow/index.md){ .md-button .md-button--secondary } + + ??? courses "**Nextflow Run:** Mevcut iş akışlarını çalıştırmayı öğrenin" + + Hello Nextflow geliştirici kursuna dayanan, ancak kod üzerine daha az odaklanan, Nextflow iş akışlarını çalıştırma ve yapılandırmaya kısa bir giriş. Çalıştırma, çıktılar, temel kod yapısı ve farklı hesaplama ortamları için yapılandırmayı kapsar. + + [Nextflow Run eğitimine başlayın :material-arrow-right:](nextflow_run/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-microscope:{.nextflow-primary} Bilim için Nextflow {.mt-1} + + 'Hello Nextflow'da sunulan kavram ve bileşenleri belirli bilimsel kullanım durumlarına uygulamayı öğrenin. + + ??? courses "**Genomik için Nextflow** (varyant çağırma)" + + Kendi genomik iş akışlarını geliştirmek isteyen araştırmacılar için. Bu kurs, basit ama işlevsel bir genomik iş akışının nasıl geliştirileceğini göstermek için varyant çağırma kullanım örneğini kullanır. + + [Genomik için Nextflow eğitimine başlayın :material-arrow-right:](nf4_science/genomics/){ .md-button .md-button--secondary } + + ??? courses "**RNAseq için Nextflow** (toplu RNAseq)" + + Kendi RNAseq iş akışlarını geliştirmek isteyen araştırmacılar için. Bu kurs, basit ama işlevsel bir RNAseq iş akışının nasıl geliştirileceğini göstermek için toplu RNAseq işleme kullanım örneğini kullanır. + + [RNAseq için Nextflow eğitimine başlayın :material-arrow-right:](nf4_science/rnaseq/){ .md-button .md-button--secondary } + + ??? courses "**Görüntüleme için Nextflow** (mekansal omikler)" + + Analiz iş akışlarını çalıştırmayı ve özelleştirmeyi öğrenmek isteyen görüntüleme ve mekansal omikler alanındaki araştırmacılar için. Bu kurs, Nextflow iş akışlarının nasıl çalıştırılacağını, yapılandırılacağını ve girdilerinin nasıl yönetileceğini göstermek için biyolojik olarak ilgili bir iş akışı sağlamak üzere nf-core/molkart iş akışını kullanır. + + [Görüntüleme için Nextflow eğitimine başlayın :material-arrow-right:](nf4_science/imaging/){ .md-button .md-button--secondary } + +- :material-run:{ .lg .middle } __İleri seviye__ + + --- + + ### :material-bridge:{.nextflow-primary} Nextflow'dan nf-core'a {.mt-1} + + [nf-core](https://nf-co.re/) topluluk projesinden kod ve en iyi uygulamaları kullanmayı öğrenin. + + Bu kurslar, Nextflow temellerinden nf-core en iyi uygulamalarına geçmenize yardımcı olur. + nf-core topluluğunun iş akışlarını nasıl ve neden oluşturduğunu ve bu tekniklere nasıl katkıda bulunabileceğinizi ve yeniden kullanabileceğinizi anlayın. + + ??? courses "**Hello nf-core:** nf-core ile başlayın" + + [nf-core](https://nf-co.re/) uyumlu iş akışlarını çalıştırmayı ve geliştirmeyi öğrenmek isteyen geliştiriciler için. Bu kurs, nf-core şablonunu ve geliştirme en iyi uygulamalarını izleyen basit ama tam işlevsel iş akışları geliştirmeyi sağlayacak kadar ayrıntıyla nf-core iş akışlarının yapısını ve mevcut nf-core modüllerinin kullanımını kapsar. + + [Hello nf-core eğitimine başlayın :material-arrow-right:](hello_nf-core/index.md){ .md-button .md-button--secondary } + + --- + + ### :material-rocket-launch:{.nextflow-primary} İleri Nextflow Eğitimi {.mt-1} + + Gerçek dünya kullanım durumlarını ele almak için Nextflow iş akışlarını geliştirme ve dağıtma konusunda ileri kavramları ve mekanizmaları öğrenin. + + ??? courses "**Side Quest'ler:** Bağımsız konulara derinlemesine dalışlar" + + Belirli konularda beceri yelpazelerini genişletmek ve/veya derinleştirmek isteyen Nextflow geliştiricileri için bağımsız mini kurslar. Doğrusal olarak sunulurlar ancak herhangi bir sırayla alınabilirler (her mini kurs genel bakışındaki bağımlılıklara bakın). + + [Side Quest'leri keşfedin :material-arrow-right:](side_quests/){ .md-button .md-button--secondary } + + ??? courses "**Eğitim Koleksiyonları:** Side Quest'ler aracılığıyla önerilen öğrenme yolları" + + Eğitim Koleksiyonları, belirli bir tema veya kullanım durumu etrafında kapsamlı bir öğrenme deneyimi sağlamak için birden fazla Side Quest'i birleştirir. + + [Eğitim Koleksiyonlarını keşfedin :material-arrow-right:](training_collections/){ .md-button .md-button--secondary } + +</div> + +!!! info "Arşivlenmiş eğitim materyallerini mi arıyorsunuz?" + + Eski eğitim materyalleri (Temel Eğitim, İleri Eğitim ve diğer deneysel kurslar) Nextflow 3.0 strict syntax ile uyumsuz oldukları için eğitim portalından kaldırılmıştır. + Bu materyallere erişmeniz gerekiyorsa, Ocak 2026 öncesi [git geçmişinde](https://github.com/nextflow-io/training) mevcutturlar. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](assets/img/seqera_logo.png#only-light) + +![Seqera](assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/tr/docs/info/conventions.md b/docs/tr/docs/info/conventions.md new file mode 100644 index 0000000000..a81abd4444 --- /dev/null +++ b/docs/tr/docs/info/conventions.md @@ -0,0 +1 @@ +Tüm kanal değişkenleri için, bunların Nextflow kanalları olduğunu açıkça belirtmek amacıyla `ch_` ön ekini kullanıyoruz. diff --git a/docs/tr/docs/info/hello_pipeline.md b/docs/tr/docs/info/hello_pipeline.md new file mode 100644 index 0000000000..206ad8ea76 --- /dev/null +++ b/docs/tr/docs/info/hello_pipeline.md @@ -0,0 +1,81 @@ +--- +title: Hello pipeline'ı +description: Hello pipeline'ının ne yaptığı ve nasıl yapılandırıldığının özeti. +hide: + - toc + - footer +--- + +# Hello pipeline'ı + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Eğitim kurslarımızın çoğu, Nextflow kavramlarını ve mekanizmalarını göstermek için basit, alan bağımsız bir pipeline kullanır. +Hello Nextflow kursu, bu pipeline'ı her tasarım ve uygulama kararını açıklayan adım adım bir şekilde nasıl geliştireceğinizi gösterir. +Diğer eğitimler bu pipeline'ı veya parçalarını başlangıç noktası olarak kullanır. + +Bu sayfa, Hello Nextflow kursunun tamamlanmasındaki pipeline'ın durumunu özetlemektedir. + +### Özet açıklama + +Hello workflow'u, selamlamalar içeren bir CSV dosyası alır, bunları ayrı dosyalara yazar, her birini büyük harfe dönüştürür, hepsini tekrar bir araya toplar ve selamlamaları söyleyen eğlenceli bir karakterin ASCII resmini içeren tek bir metin dosyası çıktılar. + +### Workflow adımları (process'ler) + +Dört adım, ayrı modül dosyalarında saklanan Nextflow process'leri (`sayHello`, `convertToUpper`, `collectGreetings` ve `cowpy`) olarak uygulanmıştır. + +1. **`sayHello`:** Her selamlamayı kendi çıktı dosyasına yazar (örn. "Hello-output.txt") +2. **`convertToUpper`:** Her selamlamayı büyük harfe dönüştürür (örn. "HELLO") +3. **`collectGreetings`:** Tüm büyük harfli selamlamaları tek bir toplu dosyada toplar +4. **`cowpy`:** `cowpy` aracını kullanarak ASCII sanatı oluşturur + +### Diyagram + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +### Sonuçlar + +Sonuçlar `results/` adlı bir dizine yayınlanır ve pipeline'ın son çıktısı (varsayılan parametrelerle çalıştırıldığında), büyük harfli selamlamaları söyleyen bir hindinin ASCII sanatını içeren düz metin dosyasıdır. + +```txt title="results/cowpy-COLLECTED-test-batch-output.txt" + _________ +/ BONJOUR \ +| HELLO | +\ HOLà / +--------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ +``` + +Pipeline'ın yer aldığı kursa bağlı olarak ayrıntılarda bazı farklılıklarla karşılaşabilirsiniz. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/tr/docs/info/nxf_versions.md b/docs/tr/docs/info/nxf_versions.md new file mode 100644 index 0000000000..30d2f04b08 --- /dev/null +++ b/docs/tr/docs/info/nxf_versions.md @@ -0,0 +1,101 @@ +--- +title: Nextflow sürümleri +description: Nextflow sözdizimi sürümlerinin evrimini anlama ve yönetme +hide: + - toc + - footer +--- + +## Şu anda desteklenen Nextflow sözdizimi sürümü ve gereksinimleri + +Eğitim portalının 3.0 sürümünden itibaren, tüm eğitim kurslarımız, kurs indeks sayfasında aksi belirtilmedikçe Nextflow'un 25.10.2 sürümüne dayanmaktadır (sürüm bildirimi içermeyen kullanımdan kaldırılmış veya arşivlenmiş materyaller hariç). + +Kurslar artık workflow seviyesinde tipli girdiler ve workflow seviyesinde çıktı yönergeleri kullandığından, V2 sözdizimi ayrıştırıcısının kullanılması gerekmektedir. +[Github Codespaces](../envsetup/01_setup.md) veya [yerel devcontainer'lar](../envsetup/03_devcontainer.md) aracılığıyla sağladığımız ortamı kullanmayı planlıyorsanız, kurs talimatlarında özellikle belirtilmedikçe bir şey yapmanıza gerek yoktur. +Ancak, eğitimleri kendi ortamınızda çalışmayı planlıyorsanız ([Manuel kurulum](../envsetup/02_local.md)), v2 sözdizimi ayrıştırıcısı etkinleştirilmiş olarak Nextflow 25.10.2 veya sonraki bir sürümü kullandığınızdan emin olmanız gerekecektir. + +## Eğitim materyallerinin eski sürümleri + +Eğitim materyallerimiz Şubat 2025'ten beri sürümlendirilmektedir. + +**25.10.2 öncesi** Nextflow sürümleriyle çalışan eğitim materyallerinin eski sürümlerine, her sayfanın üstündeki eğitim materyallerinin numaralı sürümünü gösteren açılır menü öğesi aracılığıyla erişebilirsiniz. +Eğitim materyallerinin daha eski bir sürümünü seçtiğinizde, eğitim ortamına bağlantılar otomatik olarak ortamın ilgili sürümünü belirtecektir. + +## Nextflow sözdizimi sürümleri hakkında diğer bilgiler + +Nextflow'un bazen karıştırılan iki farklı sürümleme kavramı vardır: **DSL sürümleri** ve **sözdizimi ayrıştırıcı sürümleri**. + +**DSL1 ve DSL2**, Nextflow pipeline'ları yazmanın temelden farklı yollarını ifade eder. +DSL1, process'lerin channel'lar aracılığıyla örtük olarak bağlandığı orijinal sözdizimiydi. +Nextflow 20.07'de tanıtılan DSL2, modülerlik özellikleri ekledi: diğer dosyalardan process'leri ve workflow'ları içe aktarma yeteneği, açık `workflow` blokları ve adlandırılmış process çıktıları. +DSL1, Nextflow 22.03'te kullanımdan kaldırıldı ve 22.12'de kaldırıldı. +Tüm modern Nextflow kodu DSL2 kullanır. + +**Sözdizimi ayrıştırıcı v1 ve v2**, her ikisi de DSL2 koduyla çalışan farklı ayrıştırıcıları ifade eder. +v1 ayrıştırıcısı, daha toleranslı olan orijinal ayrıştırıcıdır. +v2 ayrıştırıcısı daha katıdır ve statik tipleme (tipli girdiler ve çıktılar) ile workflow seviyesinde çıktı yönergeleri gibi yeni dil özelliklerini etkinleştirir. +v2 ayrıştırıcısı ayrıca daha iyi hata mesajları sağlar ve çalışma zamanı yerine ayrıştırma zamanında daha fazla hata yakalar. +v2 ayrıştırıcısı Nextflow 26.04'te varsayılan olacaktır. + +Özetle: DSL2 yazdığınız dildir; sözdizimi ayrıştırıcı sürümü, bu dilin ne kadar katı yorumlandığını ve hangi gelişmiş özelliklerin mevcut olduğunu belirler. + +### Nextflow sürümünü kontrol etme ve ayarlama + +Sisteminizde hangi Nextflow sürümünün yüklü olduğunu `nextflow --version` komutuyla kontrol edebilirsiniz. + +Nextflow sürümünüzü nasıl güncelleyeceğiniz hakkında daha fazla bilgi için lütfen referans belgelerindeki [Nextflow'u Güncelleme](https://www.nextflow.io/docs/latest/updating-nextflow.html) bölümüne bakın. + +### v2 sözdizimi ayrıştırıcısını etkinleştirme + +Mevcut oturumunuz için v2 sözdizimi ayrıştırıcısını **etkinleştirmek** için terminalinizde aşağıdaki komutu çalıştırın: + +```bash +export NXF_SYNTAX_PARSER=v2 +``` + +Bunu kalıcı hale getirmek için (v2'nin Nextflow 26.04'te varsayılan olmasını beklerken), export komutunu shell profilinize (`~/.bashrc`, `~/.zshrc`, vb.) ekleyin: + +```bash +echo 'export NXF_SYNTAX_PARSER=v2' >> ~/.bashrc +source ~/.bashrc +``` + +`NXF_SYNTAX_PARSER=v2` ortam değişkeninin geçici bir gereklilik olduğunu unutmayın. +Nextflow 26.04'ten itibaren v2 ayrıştırıcısı varsayılan olacak ve bu ayar artık gerekli olmayacaktır. + +### v2 sözdizimi ayrıştırıcısını devre dışı bırakma + +Mevcut oturumunuz için v2 sözdizimi ayrıştırıcısını **devre dışı bırakmak** için terminalinizde aşağıdaki komutu çalıştırın: + +```bash +export NXF_SYNTAX_PARSER=v1 +``` + +<!-- Will it be possible to disable it in versions after 26.04? --> + +### Mevcut kodun taşınması + +Mevcut kodun daha yeni Nextflow sürümlerine uyacak şekilde taşınmasına ilişkin rehberlik için lütfen referans belgelerindeki [Taşıma Notları](https://www.nextflow.io/docs/latest/migrations/index.html)'na bakın. + +Bu iki makale, en son sürüme taşıma için özellikle faydalıdır: + +- [Workflow çıktılarına taşıma](https://www.nextflow.io/docs/latest/tutorials/workflow-outputs.html) +- [Statik tiplere taşıma](https://www.nextflow.io/docs/latest/tutorials/static-types.html) + +Bu özelliklerin her ikisi de eğitim materyallerinin 3.0 sürümünden başlayarak başlangıç eğitiminin bir parçası olarak ele alınmaktadır. + +Taşımayı planladığınız Nextflow kodunun nesline bağlı olarak, `nextflow lint -format` komutunu kullanarak Nextflow linter'ı ile çoğunu yapabilirsiniz. +Daha fazla ayrıntı için [`lint`](https://www.nextflow.io/docs/latest/reference/cli.html#lint) CLI referansına bakın. + +Bunun faydalı olacağını umuyoruz. +Yardıma ihtiyacınız olursa Slack'te veya forumda bize ulaşın. + +--- + +<div markdown class="homepage_logos"> + +![Seqera](../assets/img/seqera_logo.png#only-light) + +![Seqera](../assets/img/seqera_logo_dark.png#only-dark) + +</div> diff --git a/docs/tr/docs/nextflow_run/00_orientation.md b/docs/tr/docs/nextflow_run/00_orientation.md new file mode 100644 index 0000000000..f3d4a03522 --- /dev/null +++ b/docs/tr/docs/nextflow_run/00_orientation.md @@ -0,0 +1,122 @@ +# Başlangıç + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +## Eğitim ortamını başlatın + +GitHub Codespaces'te sağladığımız önceden oluşturulmuş ortamı kullanmak için aşağıdaki "Open in GitHub Codespaces" butonuna tıklayın. Diğer seçenekler için [Ortam seçenekleri](../envsetup/index.md) bölümüne bakın. + +Ortam yüklenirken okumaya devam edebilmeniz için eğitim ortamını yeni bir tarayıcı sekmesinde veya penceresinde açmanızı öneririz (cihazınıza bağlı olarak sağ tıklama, ctrl-tıklama veya cmd-tıklama kullanın). +Kurs boyunca çalışmak için bu talimatları paralel olarak açık tutmanız gerekecektir. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +### Ortam temelleri + +Bu eğitim ortamı, eğitim kursunda çalışmak için gerekli tüm yazılım, kod ve verileri içerir, böylece kendiniz hiçbir şey yüklemeniz gerekmez. + +Codespace, dosya sistemi gezgini, kod editörü ve terminal shell içeren bir VSCode arayüzüyle kurulmuştur. +Kurs sırasında verilen tüm talimatlar (örn. 'dosyayı açın', 'kodu düzenleyin' veya 'bu komutu çalıştırın') aksi belirtilmedikçe VScode arayüzünün bu üç bölümüne atıfta bulunur. + +Bu kursu kendi başınıza çalışıyorsanız, daha fazla ayrıntı için [ortam temelleri](../envsetup/01_setup.md) ile tanışın. + +### Versiyon gereksinimleri + +Bu eğitim, v2 sözdizimi ayrıştırıcısı ETKİNLEŞTİRİLMİŞ olarak Nextflow 25.10.2 veya üstü için tasarlanmıştır. +Yerel veya özel bir ortam kullanıyorsanız, [burada](../info/nxf_versions.md) belgelendiği gibi doğru ayarları kullandığınızdan emin olun. + +## Çalışmaya hazırlanın + +Codespace'iniz çalışmaya başladığında, eğitime dalmadan önce yapmanız gereken iki şey var: bu kursa özel çalışma dizininizi ayarlayın ve sağlanan materyallere göz atın. + +### Çalışma dizinini ayarlayın + +Varsayılan olarak, codespace tüm eğitim kurslarının kökünde çalışma dizini ayarlanmış şekilde açılır, ancak bu kurs için `nextflow-run/` dizininde çalışacağız. + +Şimdi terminalde bu komutu çalıştırarak dizini değiştirin: + +```bash +cd nextflow-run/ +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz, böylece dosya gezgini kenar çubuğunda yalnızca ilgili dosyalar görünür: + +```bash +code . +``` + +!!! tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız (örn. codespace'iniz uyursa), Github Codespaces eğitim ortamında çalıştığınızı varsayarak, ona geri dönmek için her zaman tam yolu kullanabilirsiniz: + + ```bash + cd /workspaces/training/nextflow-run + ``` + +Şimdi içeriğine bir göz atalım. + +### Sağlanan materyalleri keşfedin + +Bu dizinin içeriğini eğitim çalışma alanının sol tarafındaki dosya gezginini kullanarak keşfedebilirsiniz. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. + +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde temsil etmek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar bir içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 2 +``` + +??? abstract "Dizin içeriği" + + ```console + . + ├── 1-hello.nf + ├── 2a-inputs.nf + ├── 2b-multistep.nf + ├── 2c-modules.nf + ├── 2d-container.nf + ├── 3-main.nf + ├── data + │ └── greetings.csv + ├── modules + │ ├── collectGreetings.nf + │ ├── convertToUpper.nf + │ ├── cowpy.nf + │ └── sayHello.nf + ├── nextflow.config + ├── solutions + │ ├── 3-main.nf + │ ├── modules + │ └── nextflow.config + ├── test-params.json + └── test-params.yaml + ``` + +Bölümü genişletmek ve içeriğini görüntülemek için renkli kutuya tıklayın. +Beklenen komut çıktısının yanı sıra dizin ve dosya içeriğini özlü bir şekilde görüntülemek için bu tür daraltılabilir bölümler kullanıyoruz. + +- **`.nf` dosyaları**, kursun hangi bölümünde kullanıldıklarına göre numaralandırılmış workflow betikleridir. + +- **`nextflow.config` dosyası**, minimum ortam özelliklerini ayarlayan bir yapılandırma dosyasıdır. + Şimdilik görmezden gelebilirsiniz. + +- **`data/` altındaki `greetings.csv` dosyası**, kursun büyük bölümünde kullanacağımız girdi verilerini içerir. İlk kez tanıttığımız Bölüm 2'de (Pipeline'ları çalıştırma) açıklanmıştır. + +- **`test-params.*`** dosyaları, Bölüm 3'te (Yapılandırma) kullanacağımız yapılandırma dosyalarıdır. Şimdilik görmezden gelebilirsiniz. + +- **`solutions` dizini**, kursu tamamlamanın sonucunda oluşan workflow'un ve yardımcı dosyalarının (yapılandırma ve modüller) son halini içerir. + Çalışmanızı kontrol etmek ve herhangi bir sorunu gidermek için referans olarak kullanılması amaçlanmıştır. + +## Hazırlık kontrol listesi + +Dalmaya hazır olduğunuzu mu düşünüyorsunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Ortamım çalışıyor +- [ ] Çalışma dizinimi uygun şekilde ayarladım + +Tüm kutuları işaretleyebiliyorsanız, hazırsınız. + +**[Bölüm 1: Temel İşlemleri Çalıştırma](./01_basics.md) bölümüne devam etmek için bu sayfanın sağ alt köşesindeki oka tıklayın.** diff --git a/docs/tr/docs/nextflow_run/01_basics.md b/docs/tr/docs/nextflow_run/01_basics.md new file mode 100644 index 0000000000..9069738a4b --- /dev/null +++ b/docs/tr/docs/nextflow_run/01_basics.md @@ -0,0 +1,772 @@ +# Bölüm 1: Temel işlemleri çalıştırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run eğitim kursunun bu ilk bölümünde, temel işlemleri göstermek ve ilgili Nextflow kod bileşenlerini işaret etmek için kullanacağımız çok temel, alandan bağımsız bir Hello World örneğiyle konuya yumuşak bir giriş yapıyoruz. + +??? info "Hello World örneği nedir?" + + "Hello World!", bir programlama dilinin veya yazılım çerçevesinin temel sözdizimini ve yapısını göstermek için tasarlanmış minimalist bir örnektir. + Örnek genellikle "Hello, World!" ifadesini konsol veya terminal gibi çıktı aygıtına yazdırmak veya bir dosyaya yazmaktan oluşur. + +--- + +## 1. Doğrudan bir Hello World çalıştırın + +Nextflow'a sarmadan önce ne yaptığını göstermek için doğrudan terminalde çalıştırdığımız basit bir komutla bu kavramı gösterelim. + +!!! tip "İpucu" + + [Başlangıç](00_orientation.md) sayfasında açıklandığı gibi artık `nextflow-run/` dizininde olmanız gerektiğini unutmayın. + +### 1.1. Terminalin merhaba demesini sağlayın + +Terminalinizde aşağıdaki komutu çalıştırın. + +```bash +echo 'Hello World!' +``` + +??? success "Komut çıktısı" + + ```console + Hello World! + ``` + +Bu, 'Hello World' metnini doğrudan terminalde çıktı olarak verir. + +### 1.2. Çıktıyı bir dosyaya yazın + +Pipeline'ları çalıştırmak çoğunlukla dosyalardan veri okumayı ve sonuçları başka dosyalara yazmayı içerir, bu yüzden örneği biraz daha ilgili hale getirmek için metin çıktısını bir dosyaya yazacak şekilde komutu değiştirelim. + +```bash +echo 'Hello World!' > output.txt +``` + +??? success "Komut çıktısı" + + ```console + + ``` + +Bu, terminale hiçbir şey çıktı vermez. + +### 1.3. Çıktıyı bulun + +'Hello World' metni artık belirttiğimiz çıktı dosyasında, `output.txt` adıyla olmalıdır. +Dosya gezgininde açabilir veya örneğin `cat` yardımcı programını kullanarak komut satırından açabilirsiniz. + +??? abstract "Dosya içeriği" + + ```console title="output.txt" linenums="1" + Hello World! + ``` + +İlk Nextflow workflow'umuzla çoğaltmaya çalışacağımız şey budur. + +### Özet + +Artık terminalde bazı metinler çıktı veren basit bir komutu nasıl çalıştıracağınızı ve isteğe bağlı olarak çıktıyı bir dosyaya nasıl yazdıracağınızı biliyorsunuz. + +### Sırada ne var? + +Aynı sonucu elde eden bir Nextflow workflow'u çalıştırmanın ne gerektirdiğini öğrenin. + +--- + +## 2. Workflow'u çalıştırın + +Size `--input` adlı bir komut satırı argümanı aracılığıyla bir girdi selamlama alan ve bu selamlamayı içeren bir metin dosyası üreten `1-hello.nf` adlı bir workflow betiği sağlıyoruz. + +Henüz koda bakmayacağız; önce çalıştırmanın nasıl göründüğünü görelim. + +### 2.1. Workflow'u başlatın ve çalışmayı izleyin + +Terminalde aşağıdaki komutu çalıştırın: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' +``` + +??? success "Komut çıktısı" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + + executor > local (1) + [a3/7be2fa] sayHello | 1 of 1 ✔ + ``` + +Konsol çıktınız buna benzer görünüyorsa, tebrikler, ilk Nextflow workflow'unuzu çalıştırdınız! + +Buradaki en önemli çıktı, yukarıdaki çıktıda vurgulanan son satırdır: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Bu bize `sayHello` process'inin bir kez başarıyla çalıştırıldığını söyler (`1 of 1 ✔`). + +Bu harika, ama merak ediyor olabilirsiniz: çıktı nerede? + +### 2.2. Çıktı dosyasını `results` dizininde bulun + +Bu workflow, çıktısını bir results dizinine yayınlamak üzere yapılandırılmıştır. +Geçerli dizininize bakarsanız, workflow'u çalıştırdığınızda Nextflow'un `results` adında yeni bir dizin ve bunun altında `output.txt` adlı bir dosya içeren `1-hello` adlı bir alt dizin oluşturduğunu göreceksiniz. + +```console title="results/" +results +└── 1-hello + └── output.txt +``` + +Dosyayı açın; içerik, komut satırında belirttiğiniz dizeyle eşleşmelidir. + +```console title="results/1-hello/output.txt" linenums="1" +Hello World! +``` + +Harika, workflow'umuz yapması gerekeni yaptı! + +Ancak, 'yayınlanan' sonucun, Nextflow'un workflow'u çalıştırırken ürettiği gerçek çıktının bir kopyası (veya bazı durumlarda sembolik bir bağlantı) olduğunu unutmayın. + +Şimdi, Nextflow'un işi gerçekte nerede yaptığını görmek için kaputun altına bir göz atacağız. + +!!! Warning "Uyarı" + + Tüm workflow'lar çıktıları bir results dizinine yayınlamak üzere ayarlanmayacaktır ve/veya dizin adları ve yapısı farklı olabilir. + Bu bölümde biraz ileride, bu davranışın nerede belirtildiğini nasıl bulacağınızı göstereceğiz. + +### 2.3. Orijinal çıktıyı ve logları `work/` dizininde bulun + +Bir workflow çalıştırdığınızda, Nextflow workflow'daki her bir process'in her çağrısı için (=pipeline'daki her adım) ayrı bir 'görev dizini' oluşturur. +Her biri için gerekli girdileri hazırlar, ilgili talimatları yürütür ve çıktıları ve log dosyalarını, benzersiz hale getirmek için otomatik olarak bir hash kullanılarak adlandırılan bu tek dizine yazar. + +Bu görev dizinlerinin tümü, geçerli dizininizdeki (komutu çalıştırdığınız yer) `work` adlı bir dizin altında yaşayacaktır. + +Bu karmaşık gelebilir, bu yüzden pratikte nasıl göründüğüne bakalım. + +Daha önce çalıştırdığımız workflow için konsol çıktısına geri dönersek, şu satır vardı: + +```console +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Satırın `[a3/7be2fa]` ile nasıl başladığını görüyor musunuz? +Bu, o process çağrısı için görev dizini yolunun kısaltılmış halidir ve `work/` dizin yolu içinde `sayHello` process çağrısının çıktısını nerede bulacağınızı söyler. + +Aşağıdaki komutu yazarak (kendi terminalinizde gördüğünüzle `a3/7be2fa`yı değiştirerek) ve tab tuşuna basarak yolu otomatik tamamlayarak veya bir yıldız işareti ekleyerek tam yolu bulabilirsiniz: + +```bash +ls work/a3/7be2fa* +``` + +Bu, tam dizin yolunu vermeli: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +İçinde ne olduğuna bir göz atalım. + +??? abstract "Dizin içeriği" + + ```console + work + └── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt + ``` + +??? question "Aynı şeyi görmüyor musunuz?" + + Tam alt dizin adları sisteminizde farklı olacaktır. + + VSCode dosya gezgininde görev alt dizininin içeriğine göz atarsanız, tüm dosyaları hemen göreceksiniz. + Ancak, log dosyaları terminalde görünmez olarak ayarlanmıştır, bu nedenle `ls` veya `tree` kullanarak görüntülemek istiyorsanız, görünmez dosyaları görüntülemek için ilgili seçeneği ayarlamanız gerekir. + + ```bash + tree -a work + ``` + +`output.txt` dosyasını hemen tanımalısınız, bu aslında `results` dizinine yayınlanan `sayHello` process'inin orijinal çıktısıdır. +Açarsanız, `Hello World!` selamlamasını tekrar bulacaksınız. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" +Hello World! +``` + +Peki ya diğer tüm dosyalar? + +Bunlar, Nextflow'un görev yürütmesinin bir parçası olarak yazdığı yardımcı ve log dosyalarıdır: + +- **`.command.begin`**: Görev başlatıldığında oluşturulan sentinel dosyası. +- **`.command.err`**: Process çağrısı tarafından yayılan hata mesajları (`stderr`) +- **`.command.log`**: Process çağrısı tarafından yayılan tam log çıktısı +- **`.command.out`**: Process çağrısı tarafından normal çıktı (`stdout`) +- **`.command.run`**: Nextflow tarafından process çağrısını yürütmek için çalıştırılan tam betik +- **`.command.sh`**: Process çağrısı tarafından gerçekte çalıştırılan komut +- **`.exitcode`**: Komuttan kaynaklanan çıkış kodu + +`.command.sh` dosyası özellikle yararlıdır çünkü size Nextflow'un yürüttüğü ana komutu gösterir, tüm defter tutma ve görev/ortam kurulumu dahil değildir. + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/command.sh" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +Bu, workflow'un daha önce doğrudan komut satırında çalıştırdığımız aynı komutu oluşturduğunu doğrular. + +Bir şeyler ters gittiğinde ve ne olduğunu gidermeniz gerektiğinde, Nextflow'un workflow talimatlarına, değişken enterpolasyonuna vb. göre tam olarak hangi komutu oluşturduğunu kontrol etmek için `command.sh` betiğine bakmak yararlı olabilir. + +### 2.4. Workflow'u farklı selamlamalarla yeniden çalıştırın + +Workflow'u `--input` argümanı için farklı değerlerle birkaç kez yeniden çalıştırmayı deneyin, ardından görev dizinlerine bakın. + +??? abstract "Dizin içeriği" + + ```console + 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 + ``` + +Her çalıştırma için tam bir çıktı ve log dosyası seti içeren yeni bir alt dizin oluşturulduğunu görüyorsunuz. + +Buna karşılık, `results` dizinine bakarsanız, hala yalnızca bir sonuç seti vardır ve çıktı dosyasının içeriği en son çalıştırdığınız şeye karşılık gelir. + +??? abstract "Dizin içeriği" + + ```console title="results/" + results + └── 1-hello + └── output.txt + ``` + +Bu size yayınlanan sonuçların sonraki çalıştırmalar tarafından üzerine yazılacağını, oysa `work/` altındaki görev dizinlerinin korunduğunu gösterir. + +### Özet + +Basit bir Nextflow betiğini nasıl çalıştıracağınızı, yürütülmesini nasıl izleyeceğinizi ve çıktılarını nasıl bulacağınızı biliyorsunuz. + +### Sırada ne var? + +Temel bir Nextflow betiğini nasıl okuyacağınızı ve bileşenlerinin işlevselliğiyle nasıl ilişkili olduğunu öğrenin. + +--- + +## 3. Hello World workflow başlangıç betiğini inceleyin + +Orada yaptığımız şey temelde workflow betiğini bir kara kutu gibi ele almaktı. +Şimdi ne yaptığını gördüğümüze göre, kutuyu açalım ve içine bakalım. + +Buradaki amacımız Nextflow kodunun sözdizimini ezberlemek değil, ana bileşenlerin ne olduğu ve nasıl organize edildikleri hakkında temel bir sezgi oluşturmaktır. + +### 3.1. Genel kod yapısını inceleyin + +`1-hello.nf` betiğini `nextflow-run` olması gereken geçerli dizininizde bulacaksınız. Editör bölmesinde açın. + +??? full-code "Tam kod dosyası" + + ```groovy title="1-hello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ + process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ + } + + /* + * Pipeline parametreleri + */ + params { + input: String + } + + workflow { + + main: + // bir selamlama yayınla + sayHello(params.input) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '1-hello' + mode 'copy' + } + } + ``` + +Bir Nextflow workflow betiği tipik olarak bir veya daha fazla **process** tanımı, **workflow**'un kendisi ve **params** ve **output** gibi birkaç isteğe bağlı blok içerir. + +Her **process**, pipeline'daki ilgili adımın hangi işlem(ler)i gerçekleştirmesi gerektiğini açıklarken, **workflow** çeşitli adımları birbirine bağlayan veri akışı mantığını tanımlar. + +Önce **process** bloğuna daha yakından bakalım, ardından **workflow** bloğuna bakacağız. + +### 3.2. `process` tanımı + +İlk kod bloğu bir **process**'i tanımlar. +Process tanımı `process` anahtar kelimesiyle başlar, ardından process adı ve son olarak süslü parantezlerle sınırlandırılmış process gövdesi gelir. +Process gövdesi, çalıştırılacak komutu belirten bir script bloğu içermelidir; bu, komut satırı terminalinde çalıştırabileceğiniz herhangi bir şey olabilir. + +```groovy title="1-hello.nf" linenums="3" +/* +* Bir selamlamayı bir dosyaya yazdırmak için echo kullan +*/ +process sayHello { + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '${greeting}' > output.txt + """ +} +``` + +Burada `greeting` adlı bir **input** değişkeni alan ve **output**'unu `output.txt` adlı bir dosyaya yazan `sayHello` adlı bir **process**'imiz var. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/sayhello_with_input.svg" +</figure> + +Bu, yalnızca bir `input` tanımı, bir `output` tanımı ve yürütülecek `script`'i içeren çok minimal bir process tanımıdır. + +`input` tanımı, Nextflow'a bir tür değer beklediğini söyleyen `val` niteleyicisini içerir (bir dize, bir sayı veya herhangi bir şey olabilir). + +`output` tanımı, bunun bir yol olarak işlenmesi gerektiğini söyleyen `path` niteleyicisini içerir (hem dizin yollarını hem de dosyaları içerir). + +### 3.3. `workflow` tanımı + +İkinci kod bloğu **workflow**'un kendisini tanımlar. +Workflow tanımı `workflow` anahtar kelimesiyle başlar, ardından isteğe bağlı bir ad ve süslü parantezlerle sınırlandırılmış workflow gövdesi gelir. + +Burada `main:` bloğu ve `publish:` bloğundan oluşan bir **workflow**'umuz var. +`main:` bloğu workflow'un ana gövdesidir ve `publish:` bloğu `results` dizinine yayınlanması gereken çıktıları listeler. + +```groovy title="1-hello.nf" linenums="27" +workflow { + + main: + // bir selamlama yayınla + sayHello(params.input) + + publish: + first_output = sayHello.out +} +``` + +Bu durumda `main:` bloğu `sayHello` process'ine bir çağrı içerir ve selamlama olarak kullanması için `params.input` adlı bir girdi verir. + +Birazdan daha ayrıntılı tartışacağımız gibi, `params.input` komut satırımızda `--input` parametresine verdiğimiz değeri tutar. + +`publish:` bloğu, `sayHello()` process çağrısının çıktısını listeler, buna `sayHello.out` olarak atıfta bulunur ve `first_output` adını verir (bu, workflow yazarının istediği herhangi bir şey olabilir). + +Bu çok minimal bir **workflow** tanımıdır. +Gerçek dünya pipeline'larında, workflow tipik olarak **channel**'larla bağlanan birden fazla **process** çağrısı içerir ve değişken girdiler için varsayılan değerler ayarlanmış olabilir. + +Kursun 2. Bölümünde buna gireceğiz. +Şimdilik, workflow'umuzun girdileri ve çıktıları nasıl işlediğine daha yakından bakalım. + +### 3.4. Komut satırı parametreleri için `params` sistemi + +`sayHello()` process çağrısına sağladığımız `params.input`, şık bir Nextflow kod parçasıdır ve üzerinde ekstra bir dakika harcamaya değer. + +Yukarıda belirtildiği gibi, `--input` komut satırı parametresinin değerini `sayHello()` process çağrısına bu şekilde geçiriyoruz. +Aslında, sadece `params.someParameterName` bildirmek, workflow'a komut satırından `--someParameterName` adlı bir parametre vermek için yeterlidir. + +Burada bu parametre bildirimini, workflow'un beklediği girdi türünü belirten bir `params` bloğu kurarak resmileştirdik (Nextflow 25.10.2 ve sonrası). + +```groovy title="1-hello.nf" linenums="20" +/* + * Pipeline parametreleri + */ +params { + input: String +} +``` + +Desteklenen türler arasında `String`, `Integer`, `Float`, `Boolean` ve `Path` bulunur. + +!!! tip "İpucu" + + `params` sistemi kullanılarak bildirilen workflow parametreleri komut satırında her zaman iki tire alır (`--`). + Bu, onları yalnızca bir tire alan (`-`) Nextflow düzeyindeki parametrelerden ayırır. + +### 3.5. `publish` direktifi + +Workflow'un diğer ucunda, `publish:` bloğuna zaten göz attık. +Bu, çıktı işleme sisteminin yarısıdır; diğer yarısı aşağıda bulunan `output` bloğudur. + +```groovy title="1-hello.nf" linenums="37" +output { + first_output { + path '1-hello' + mode 'copy' + } +} +``` + +Bu, `publish:` bloğunda listelenen `first_output` çıktısının varsayılan `results` çıktı dizini altında `1-hello` adlı bir alt dizine kopyalanması gerektiğini belirtir. + +`mode 'copy'` satırı, sistemin varsayılan davranışını geçersiz kılar, bu davranış düzgün bir kopya yerine `work/` dizinindeki orijinal dosyaya sembolik bir bağlantı (veya symlink) yapmaktır. + +Yayınlama davranışını kontrol etmek için burada gösterilenden daha fazla seçenek vardır; daha sonra birkaçını ele alacağız. +Bir workflow birden fazla çıktı ürettiğinde, her birinin `output` bloğunda bu şekilde listelendiğini de göreceksiniz. + +??? info "`publishDir` kullanarak çıktıları yayınlamak için eski sözdizimi" + + Çok yakın zamana kadar, çıktıları yayınlamanın yerleşik yolu, `publishDir` direktifi kullanarak her bir process düzeyinde yapmaktı. + + Bu kod kalıbını eski Nextflow pipeline'larında ve process modüllerinde hala her yerde bulacaksınız, bu yüzden bunun farkında olmak önemlidir. + + Workflow'da `publish:` bloğu ve üst düzeyde `output` bloğu yerine, `sayHello` process tanımında bir `publishDir` satırı görürdünüz: + + ```groovy title="Sözdizimi örneği" linenums="1" hl_lines="3" + process sayHello { + + publishDir 'results/1-hello', mode: 'copy' + + output: + path 'output.txt' + + script: + """ + echo 'Hello World!' > output.txt + """ + } + ``` + + Ancak, gelecekteki Nextflow dil sürümlerinde sonunda yasaklanacağı için bunu herhangi bir yeni çalışmada kullanmanızı önermiyoruz. + +### Özet + +Artık basit bir Nextflow workflow'unun nasıl yapılandırıldığını ve temel bileşenlerin işlevselliğiyle nasıl ilişkili olduğunu biliyorsunuz. + +### Sırada ne var? + +Workflow çalıştırmalarınızı rahatça yönetmeyi öğrenin. + +--- + +## 4. Workflow çalıştırmalarını yönetin + +Workflow'ları başlatmayı ve çıktıları almayı bilmek harikadır, ancak hayatınızı kolaylaştıracak workflow yönetiminin birkaç başka yönü olduğunu hızla keşfedeceksiniz. + +Burada size aynı workflow'u yeniden başlatmanız gerektiğinde `resume` özelliğinden nasıl yararlanacağınızı, çalıştırma loglarını `nextflow log` ile nasıl inceleyeceğinizi ve eski çalışma dizinlerini `nextflow clean` ile nasıl sileceğinizi gösteriyoruz. + +### 4.1. `-resume` ile bir workflow'u yeniden başlatın + +Bazen, daha önce başlattığınız bir pipeline'ı, önceden başarıyla tamamlanmış herhangi bir işi yeniden yapmadan çalıştırmak isteyeceksiniz. + +Nextflow'un bunu yapmanıza olanak tanıyan `-resume` adlı bir seçeneği vardır. +Özellikle, bu modda, tam olarak aynı kod, ayarlar ve girdilerle zaten çalıştırılmış olan tüm process'ler atlanacaktır. +Bu, Nextflow'un yalnızca son çalıştırmadan bu yana eklediğiniz veya değiştirdiğiniz ya da yeni ayarlar veya girdiler sağladığınız process'leri çalıştıracağı anlamına gelir. + +Bunu yapmanın iki önemli avantajı vardır: + +- Bir pipeline geliştirmenin ortasındaysanız, değişikliklerinizi test etmek için yalnızca aktif olarak üzerinde çalıştığınız process(ler)i çalıştırmanız gerektiğinden daha hızlı iterasyon yapabilirsiniz. +- Üretimde bir pipeline çalıştırıyorsanız ve bir şeyler ters giderse, birçok durumda sorunu düzeltebilir ve pipeline'ı yeniden başlatabilirsiniz ve başarısızlık noktasından itibaren çalışmaya devam eder, bu da size çok zaman ve hesaplama tasarrufu sağlayabilir. + +Kullanmak için, komutunuza `-resume` ekleyin ve çalıştırın: + +```bash +nextflow run 1-hello.nf --input 'Hello World!' -resume +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `1-hello.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] sayHello | 1 of 1, cached: 1 ✔ + ``` + +Konsol çıktısı tanıdık görünmeli, ancak öncekine kıyasla biraz farklı olan bir şey var. + +Process durum satırında (satır 5) eklenen `cached:` kısmına bakın, bu Nextflow'un bu işi zaten yaptığını tanıdığı ve önceki başarılı çalıştırmanın sonucunu yeniden kullandığı anlamına gelir. + +Ayrıca çalışma alt dizini hash'inin önceki çalıştırmayla aynı olduğunu görebilirsiniz. +Nextflow kelimenin tam anlamıyla size önceki çalıştırmayı gösteriyor ve "Bunu zaten orada yaptım" diyor. + +!!! tip "İpucu" + + Bir pipeline'ı `resume` ile yeniden çalıştırdığınızda, Nextflow daha önce başarıyla çalıştırılan çalıştırmalar tarafından çalışma dizininin dışında yayınlanan hiçbir dosyanın üzerine yazmaz. + +### 4.2. Geçmiş çalıştırmaların logunu inceleyin + +Bir nextflow workflow'u başlattığınızda, geçerli çalışma dizininde `.nextflow` adlı gizli bir dizin altında `history` adlı bir log dosyasına bir satır yazılır. + +??? abstract "Dosya içeriği" + + ```txt title=".nextflow/history" linenums="1" + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582ccde68dde471cc2c66295c a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582ccde68dde471cc2c66295c 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582ccde68dde471cc2c66295c 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582ccde68dde471cc2c66295c 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Bu dosya size geçerli çalışma dizininden başlatılan her Nextflow çalıştırması için zaman damgası, çalıştırma adı, durum, revizyon kimliği, oturum kimliği ve tam komut satırını verir. + +Bu bilgilere erişmenin daha uygun bir yolu `nextflow log` komutunu kullanmaktır. + +```bash +nextflow log +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + TIMESTAMP DURATION RUN NAME STATUS REVISION ID SESSION ID COMMAND + 2025-07-04 19:27:09 1.8s wise_watson OK 3539118582 a02c9c46-c3c7-4085-9139-d1b9b5b194c8 nextflow run 1-hello.nf --input 'Hello World' + 2025-07-04 19:27:20 2.9s spontaneous_blackwell OK 3539118582 59a5db23-d83c-4c02-a54e-37ddb73a337e nextflow run 1-hello.nf --input Bonjour + 2025-07-04 19:27:31 1.8s gigantic_yonath OK 3539118582 5acaa83a-6ad6-4509-bebc-cb25d5d7ddd0 nextflow run 1-hello.nf --input 'Dobry den' + 2025-07-04 19:27:45 2.4s backstabbing_swartz OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa + 2025-07-04 19:27:57 2.1s goofy_wilson OK 3539118582 5f4b3269-5b53-404a-956c-cac915fbb74e nextflow run 1-hello.nf --input Konnichiwa -resume + ``` + +Bu, log dosyasının içeriğini bir başlık satırıyla zenginleştirerek terminale çıktı verecektir. + +`-resume` seçeneğini kullanmıyorsanız, yeni bir `nextflow run` komutu çalıştırdığınızda oturum kimliğinin değiştiğini fark edeceksiniz. +Bu durumda, oturum kimliği aynı kalır. + +Nextflow, çalıştırma önbellekleme bilgilerini gruplamak için oturum kimliğini, ayrıca `.nextflow` altında bulunan `cache` dizini altında kullanır. + +### 4.3. Eski çalışma dizinlerini silin + +Çok sayıda pipeline çalıştırırsanız, birçok alt dizin boyunca çok sayıda dosya biriktirebilirsiniz. +Alt dizinler rastgele adlandırıldığından, adlarından hangilerinin daha eski veya daha yeni çalıştırmalar olduğunu söylemek zordur. + +Neyse ki Nextflow, artık umursamadığınız geçmiş çalıştırmalar için çalışma alt dizinlerini otomatik olarak silebilen yararlı bir `clean` alt komutu içerir. + +#### 4.3.1. Silme kriterlerini belirleyin + +Neyin silineceğini belirlemek için birden fazla [seçenek](https://www.nextflow.io/docs/latest/reference/cli.html#clean) vardır. + +Burada size belirli bir çalıştırmadan önceki tüm alt dizinleri silen bir örnek gösteriyoruz, çalıştırma adı kullanılarak belirtilir. + +`-resume` kullanmadığınız en son başarılı çalıştırmayı bulun; bizim durumumuzda çalıştırma adı `backstabbing_swartz` idi. + +Çalıştırma adı, `Launching (...)` konsol çıktı satırında köşeli parantezler içinde gösterilen makine tarafından oluşturulan iki parçalı dizedir. +Ayrıca zaman damgası ve/veya komut satırına göre bir çalıştırmayı aramak için Nextflow logunu kullanabilirsiniz. + +#### 4.3.2. Kuru çalıştırma yapın + +Önce, komut verildiğinde neyin silineceğini kontrol etmek için kuru çalıştırma bayrağı `-n` kullanıyoruz: + +```bash +nextflow clean -before backstabbing_swartz -n +``` + +??? success "Komut çıktısı" + + ```console + Would remove /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Would remove /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Would remove /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Çıktınız farklı görev dizini adlarına sahip olacak ve farklı sayıda satır olabilir, ancak örneğe benzer görünmelidir. + +Herhangi bir satır çıktı görmüyorsanız, ya geçerli bir çalıştırma adı sağlamadınız ya da silecek geçmiş çalıştırma yok. Örnek komuttaki `backstabbing_swartz`'ı loginizdeki ilgili en son çalıştırma adıyla değiştirdiğinizden emin olun. + +#### 4.3.3. Silme işlemine devam edin + +Çıktı beklendiği gibi görünüyorsa ve silme işlemine devam etmek istiyorsanız, `-n` yerine `-f` bayrağıyla komutu yeniden çalıştırın: + +```bash +nextflow clean -before backstabbing_swartz -f +``` + +??? success "Komut çıktısı" + + ```console + Removed /workspaces/training/hello-nextflow/work/eb/1a5de36637b475afd88fca7f79e024 + Removed /workspaces/training/hello-nextflow/work/6b/19b0e002ea13486d3a0344c336c1d0 + Removed /workspaces/training/hello-nextflow/work/45/9a6dd7ab771f93003d040956282883 + ``` + +Çıktı daha önceye benzer olmalı, ancak şimdi 'Would remove' yerine 'Removed' diyor. +Bunun iki karakterli alt dizinleri (yukarıdaki `eb/` gibi) kaldırmadığını, ancak içeriklerini boşalttığını unutmayın. + +!!! Warning "Uyarı" + + Geçmiş çalıştırmalardan çalışma alt dizinlerini silmek, onları Nextflow'un önbelleğinden kaldırır ve bu dizinlerde depolanan tüm çıktıları siler. + Bu, Nextflow'un ilgili process'leri yeniden çalıştırmadan çalışmaya devam etme yeteneğini bozar. + + Önemsediğiniz çıktıları kaydetmekten siz sorumlusunuz! Bu, `publish` direktifi için `symlink` modu yerine `copy` modunu tercih etmemizin ana nedenidir. + +### Özet + +Aynı şekilde zaten çalıştırılmış adımları tekrarlamadan bir pipeline'ı nasıl yeniden başlatacağınızı, çalıştırma logunu nasıl inceleyeceğinizi ve eski çalışma dizinlerini temizlemek için `nextflow clean` komutunu nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +Biraz ara verin! Nextflow sözdiziminin ve temel kullanım talimatlarının yapı taşlarını yeni absorbe ettiniz. + +Bu eğitimin bir sonraki bölümünde, Nextflow'un birden fazla girdiyi verimli bir şekilde işlemenize, birbirine bağlı birden fazla adımdan oluşan workflow'ları çalıştırmanıza, modüler kod bileşenlerinden yararlanmanıza ve daha fazla tekrar üretilebilirlik ve taşınabilirlik için konteynerları kullanmanıza nasıl izin verdiğini gösteren Hello World pipeline'ının art arda daha gerçekçi dört versiyonuna bakacağız. + +--- + +## Quiz + +<quiz> +`[a3/7be2fa] SAYHELLO | 1 of 1 ✔` konsol çıktı satırında `[a3/7be2fa]` neyi temsil eder? +- [ ] Process versiyon numarası +- [ ] Benzersiz bir çalıştırma tanımlayıcısı +- [x] Görevin çalışma dizinine kısaltılmış yol +- [ ] Çıktı dosyasının sağlama toplamı + +Daha fazla bilgi: [2.3. Orijinal çıktıyı ve logları `work/` dizininde bulun](#23-orijinal-ciktiyi-ve-loglari-work-dizininde-bulun) +</quiz> + +<quiz> +Görev dizinindeki `.command.sh` dosyasının amacı nedir? +- [ ] Görevin yapılandırma ayarlarını saklar +- [x] Process tarafından yürütülen gerçek komutu gösterir +- [ ] Başarısız görevlerden hata mesajlarını içerir +- [ ] Görev için hazırlanan girdi dosyalarını listeler + +Daha fazla bilgi: [2.3. Orijinal çıktıyı ve logları `work/` dizininde bulun](#23-orijinal-ciktiyi-ve-loglari-work-dizininde-bulun) +</quiz> + +<quiz> +`-resume` olmadan bir workflow'u yeniden çalıştırdığınızda yayınlanan sonuçlara ne olur? +- [ ] Ayrı zaman damgalı dizinlerde korunurlar +- [x] Yeni çalıştırma tarafından üzerine yazılırlar +- [ ] Nextflow üzerine yazmayı engeller ve başarısız olur +- [ ] Otomatik olarak yedeklenirler + +Daha fazla bilgi: [2.4. Workflow'u farklı selamlamalarla yeniden çalıştırın](#24-workflowu-farkli-selamlamalarla-yeniden-calistirin) +</quiz> + +<quiz> +Bu konsol çıktısı neyi gösterir? + +```console +[skipped ] process > sayHello (1) [100%] 1 of 1, cached: 1 ✔ +``` + +- [ ] Görev başarısız oldu ve atlandı +- [ ] Görev bir kuyrukta bekliyor +- [x] Nextflow önceki özdeş bir çalıştırmadan sonuçları yeniden kullandı +- [ ] Görev manuel olarak iptal edildi + +Daha fazla bilgi: [4.1. `-resume` ile bir workflow'u yeniden başlatın](#41--resume-ile-bir-workflowu-yeniden-baslatin) +</quiz> + +<quiz> +`nextflow log` komutunun görüntülediği çalıştırma geçmişini Nextflow nerede saklar? +- [ ] results dizininde +- [ ] work dizininde +- [x] `.nextflow/history` dosyasında +- [ ] `nextflow.config` dosyasında + +Daha fazla bilgi: [4.2. Geçmiş çalıştırmaların logunu inceleyin](#42-gecmis-calistirmalarin-logunu-inceleyin) +</quiz> + +<quiz> +Bir workflow dosyasındaki `params` bloğunun amacı nedir? +- [ ] Process kaynak gereksinimlerini tanımlamak +- [ ] Executor'ı yapılandırmak +- [x] Workflow girdi parametrelerini bildirmek ve türünü belirlemek +- [ ] Çıktı yayınlama seçeneklerini belirtmek + +Daha fazla bilgi: [3.4. Komut satırı parametreleri için params sistemi](#34-komut-satiri-parametreleri-icin-params-sistemi) +</quiz> + +<quiz> +Workflow'un `output` bloğunda `mode 'copy'` ne yapar? +- [ ] work dizininin bir yedeğini oluşturur +- [x] Sembolik bağlantılar yerine dosyaların tam kopyasını yapar +- [ ] Workflow betiğini sonuçlara kopyalar +- [ ] Artımlı dosya kopyalamayı etkinleştirir + +Daha fazla bilgi: [3.5. publish direktifi](#35-publish-direktifi) +</quiz> + +<quiz> +Dosyaları gerçekten silmeden önce `nextflow clean` komutuyla kullanılması önerilen bayrak nedir? +- [x] `-n` (kuru çalıştırma) neyin silineceğini önizlemek için +- [ ] `-v` (ayrıntılı) ayrıntılı çıktı görmek için +- [ ] `-a` (tümü) tüm dizinleri seçmek için +- [ ] `-q` (sessiz) uyarıları bastırmak için + +Daha fazla bilgi: [4.3. Eski çalışma dizinlerini silin](#43-eski-calisma-dizinlerini-silin) +</quiz> diff --git a/docs/tr/docs/nextflow_run/02_pipeline.md b/docs/tr/docs/nextflow_run/02_pipeline.md new file mode 100644 index 0000000000..20c00dcd00 --- /dev/null +++ b/docs/tr/docs/nextflow_run/02_pipeline.md @@ -0,0 +1,1404 @@ +# Bölüm 2: Gerçek pipeline'ları çalıştırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun 1. Bölümünde (Temel İşlemleri Çalıştırma), kod karmaşıklığını düşük tutmak için yalnızca minimal özelliklere sahip örnek bir workflow ile başladık. +Örneğin, `1-hello.nf` bir seferde tek bir değer sağlamak için komut satırı parametresi (`--input`) kullandı. + +Ancak, gerçek dünya pipeline'larının çoğu, büyük miktarda veriyi ölçekte verimli bir şekilde işlemek ve bazen karmaşık mantıkla birbirine zincirlenen birden fazla işleme adımı uygulamak için daha sofistike özellikler kullanır. + +Eğitimin bu bölümünde, orijinal Hello World pipeline'ının genişletilmiş versiyonlarını deneyerek gerçek dünya pipeline'larının temel özelliklerini gösteriyoruz. + +## 1. Bir dosyadan girdi verilerini işleme + +Gerçek dünya pipeline'larında, tipik olarak bir veya daha fazla girdi dosyasında bulunan birden fazla veri noktasını (veya veri serisini) işlemek istiyoruz. +Ve mümkün olduğunda, analiz için harcanan süreyi kısaltmak için bağımsız verilerin işlenmesini paralel olarak çalıştırmak istiyoruz. + +Nextflow'un bunu nasıl yaptığını göstermek için, gerçek bir veri analizinde işlemek isteyebileceğiniz türden sütunlu verileri taklit eden birkaç girdi selamlama içeren `greetings.csv` adlı bir CSV dosyası hazırladık. +Sayıların anlamlı olmadığını, sadece açıklama amaçlı olduğunu unutmayın. + +```csv title="data/greetings.csv" linenums="1" +Hello,English,123 +Bonjour,French,456 +Holà,Spanish,789 +``` + +Ayrıca, CSV dosyasını okuyacak, selamlamaları çıkaracak ve her birini ayrı bir dosyaya yazacak olan `2a-inputs.nf` adlı orijinal workflow'un geliştirilmiş bir versiyonunu yazdık. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-inputs.svg" +</figure> + +Önce workflow'u çalıştıralım ve ardından ilgili Nextflow koduna bakacağız. + +### 1.1. Workflow'u çalıştırın + +Terminalinizde aşağıdaki komutu çalıştırın. + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2a-inputs.nf` [mighty_sammet] DSL2 - revision: 29fb5352b3 + + executor > local (3) + [8e/0eb066] sayHello (2) [100%] 3 of 3 ✔ + ``` + +Heyecan verici bir şekilde, bu process için '3 of 3' çağrının yapıldığını gösteriyor gibi görünüyor, bu cesaret verici, çünkü girdi olarak sağladığımız CSV'de üç veri satırı vardı. +Bu, `sayHello()` process'inin her girdi satırında bir kez olmak üzere üç kez çağrıldığını gösteriyor. + +### 1.2. Yayınlanan çıktıları `results` dizininde bulun + +Workflow'umuzun hala çıktılarımızın bir kopyasını oraya yazıp yazmadığını görmek için 'results' dizinine bakalım. + +??? abstract "Dizin içeriği" + + ```console linenums="1" hl_lines="4-7" + results + ├── 1-hello + | └── output.txt + └── 2a-inputs + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Evet! Yeterince uygun bir şekilde farklı adlara sahip üç çıktı dosyası içeren `2a-inputs` adlı yeni bir dizin görüyoruz. + +Uygun selamlama dizesini içerdiklerinden emin olmak için her birini açabilirsiniz. + +??? abstract "Dosya içeriği" + + ```console title="results/2a-inputs/Hello-output.txt" + Hello + ``` + + ```console title="results/2a-inputs/Bonjour-output.txt" + Bonjour + ``` + + ```console title="results/2a-inputs/Holà-output.txt" + Holà + ``` + +Bu, girdi dosyasındaki her selamlamanın uygun şekilde işlendiğini doğrular. + +### 1.3. Orijinal çıktıları ve logları bulun + +Yukarıdaki konsol çıktısının yalnızca bir görev dizinine atıfta bulunduğunu fark etmiş olabilirsiniz. +Bu, `sayHello()` çağrısının üçünün de bu tek görev dizininde yürütüldüğü anlamına mı geliyor? + +#### 1.3.1. Terminalde verilen görev dizinini inceleyin + +`8e/0eb066` görev dizininin içine bakalım. + +??? abstract "Dizin içeriği" + + ```console title="8e/0eb066" + work/8e/0eb066071cdb4123906b7b4ea8b047/ + └── Bonjour-output.txt + ``` + +Yalnızca selamlamalardan birine karşılık gelen çıktıyı buluyoruz (gizli dosyaların görüntülenmesini etkinleştirirsek yardımcı dosyaları da). + +Peki ne oluyor? + +Varsayılan olarak, ANSI loglama sistemi aynı process'e yapılan tüm çağrılar için durum bilgisini aynı satıra yazar. +Sonuç olarak, konsol çıktısında bize üç görev dizini yolundan yalnızca birini (`8e/0eb066`) gösterdi. +Orada listelenmeyen iki tane daha var. + +#### 1.3.2. Terminalin daha fazla ayrıntı göstermesini sağlayın + +Process çağrılarının tam listesini görmek için loglama davranışını aşağıdaki gibi komuta `-ansi-log false` ekleyerek değiştirebiliriz: + +```bash +nextflow run 2a-inputs.nf --input data/greetings.csv -ansi-log false +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + Launching `2a-inputs.nf` [pedantic_hamilton] DSL2 - revision: 6bbc42e49f + [ab/1a8ece] Submitted process > sayHello (1) + [0d/2cae24] Submitted process > sayHello (2) + [b5/0df1d6] Submitted process > sayHello (3) + ``` + +Bu sefer çıktıda üç process çalıştırmasını ve ilişkili çalışma alt dizinlerini görüyoruz. +ANSI loglamasını devre dışı bırakmak, Nextflow'un terminal çıktısında renk kullanmasını da engelledi. + +Durumun iki loglama modu arasında biraz farklı raporlandığına dikkat edin. +Yoğunlaştırılmış modda, Nextflow çağrıların başarıyla tamamlanıp tamamlanmadığını raporlar. +Bu genişletilmiş modda, yalnızca gönderildiklerini raporlar. + +Bu, `sayHello()` process'inin üç kez çağrıldığını ve her biri için ayrı bir görev dizini oluşturulduğunu doğrular. + +Orada listelenen her görev dizininin içine bakarsak, her birinin selamlamalardan birine karşılık geldiğini doğrulayabiliriz. + +??? abstract "Dizin içeriği" + + ```console title="ab/1a8ece" + work/ab/1a8ece307e53f03fce689dde904b64/ + └── Hello-output.txt + ``` + + ```console title="0d/2cae24" + work/0d/2cae2481a53593bc607077c80c9466/ + └── Bonjour-output.txt + ``` + + ```console title="b5/0df1d6" + work/b5/0df1d642353269909c2ce23fc2a8fa/ + └── Holà-output.txt + ``` + +Bu, her process çağrısının diğerlerinden izole olarak yürütüldüğünü doğrular. +Bunun, process'in benzersiz olmayan adlara sahip ara dosyalar üretmesi durumunda çakışmaları önlemek de dahil olmak üzere birçok avantajı vardır. + +!!! tip "İpucu" + + Karmaşık bir workflow veya çok sayıda girdi için, tam listenin terminale çıktı verilmesi biraz bunaltıcı olabilir, bu nedenle insanlar normalde rutin kullanımda `-ansi-log false` kullanmazlar. + +### 1.4. Workflow kodunu inceleyin + +Bu workflow versiyonu bir CSV girdi dosyasını okuyabilir, girdileri ayrı ayrı işleyebilir ve çıktıları benzersiz şekilde adlandırabilir. + +Workflow kodunda bunu mümkün kılan şeylere bir göz atalım. + +??? full-code "Tam kod dosyası" + + ```groovy title="2a-inputs.nf" linenums="1" hl_lines="31-33 35" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Pipeline parametreleri + */ + params { + input: Path + } + + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + + publish: + first_output = sayHello.out + } + + output { + first_output { + path '2a-inputs' + mode 'copy' + } + } + ``` + +Yine, kod sözdizimini ezberlememeniz gerekmez, ancak önemli işlevsellik sağlayan workflow'un temel bileşenlerini tanımayı öğrenmek iyidir. + +#### 1.4.1. CSV'den girdi verilerini yükleme + +En ilginç kısım şudur: komut satırından tek bir değer almaktan, bir CSV dosyası almaya, ayrıştırmaya ve içerdiği bireysel selamlamaları işlemeye nasıl geçtik? + +Nextflow'da bunu bir **channel** ile yapıyoruz: girdileri verimli bir şekilde işlemek ve çok adımlı workflow'larda bir adımdan diğerine taşımak için tasarlanmış, yerleşik paralellik ve birçok ek avantaj sağlayan bir yapı. + +Parçalayalım. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="3-5" + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) +``` + +Bu kod, CSV dosyasını okuyan, ayrıştıran ve her satırdan ilk sütunu çıkaran `greeting_ch` adlı bir channel oluşturur. +Sonuç, `Hello`, `Bonjour` ve `Holà` içeren bir channel'dır. + +??? tip "Bu nasıl çalışır?" + + Bu satırın düz İngilizce'de anlamı şudur: + + - `channel.fromPath`, dosya yollarından bir channel oluşturan bir **channel factory**'dir + - `(params.input)`, dosya yolunun komut satırında `--input` ile sağlandığını belirtir + + Başka bir deyişle, bu satır Nextflow'a şunu söyler: `--input` ile verilen dosya yolunu al ve içeriğini girdi verisi olarak işlemeye hazırlan. + + Sonra, sonraki iki satır dosyanın gerçek ayrıştırmasını yapan ve verileri uygun veri yapısına yükleyen **operatör**leri uygular: + + - `.splitCsv()` Nextflow'a CSV dosyasını satırları ve sütunları temsil eden bir diziye ayrıştırmasını söyler + - `.map { line -> line[0] }` Nextflow'a her satırdan yalnızca ilk sütundaki elemanı almasını söyler + + Yani pratikte, aşağıdaki CSV dosyasından başlayarak: + + ```csv title="greetings.csv" linenums="1" + Hello,English,123 + Bonjour,French,456 + Holà,Spanish,789 + ``` + + Bunu şuna benzer bir diziye dönüştürdük: + + ```txt title="Dizi içeriği" + [[Hello,English,123],[Bonjour,French,456],[Holà,Spanish,789]] + ``` + + Ve sonra üç satırın her birinden ilk elemanı aldık ve artık `Hello`, `Bonjour` ve `Holà` içeren bir Nextflow channel'ına yükledik. + + Channel'ları ve operatörleri derinlemesine anlamak istiyorsanız, bunları kendiniz nasıl yazacağınız da dahil, [Hello Nextflow Bölüm 2: Hello Channels](../hello_nextflow/02_hello_channels.md#4-read-input-values-from-a-csv-file) bölümüne bakın. + +#### 1.4.2. Her selamlamada process'i çağırma + +Sonra, workflow'un `main:` bloğunun son satırında, yüklenen `greeting_ch` channel'ını `sayHello()` process'ine girdi olarak sağlıyoruz. + +```groovy title="2a-inputs.nf" linenums="29" hl_lines="7" + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) +``` + +Bu, Nextflow'a process'i channel'daki her eleman üzerinde, yani her selamlamada bireysel olarak çalıştırmasını söyler. +Ve Nextflow bu kadar akıllı olduğundan, mevcut hesaplama altyapısına bağlı olarak bu process çağrılarını mümkünse paralel olarak çalıştıracaktır. + +Çok sayıda veriyi (birçok örnek veya veri noktası, araştırma biriminiz ne olursa olsun) karşılaştırmalı olarak çok az kodla verimli ve ölçeklenebilir bir şekilde bu şekilde işleyebilirsiniz. + +#### 1.4.3. Çıktılar nasıl adlandırılır + +Son olarak, çıktı dosyalarının benzersiz şekilde adlandırılmasını nasıl sağladığımızı görmek için process koduna hızlıca bakmaya değer. + +```groovy title="2a-inputs.nf" linenums="6" hl_lines="7 11" +process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ +} +``` + +Gördüğünüz gibi, `1-hello.nf`'deki bu process versiyonuna kıyasla, çıktı bildirimi ve komutun ilgili kısmı, selamlama değerini çıktı dosya adına dahil edecek şekilde değişti. + +Bu, ortak results dizinine yayınlandıklarında çıktı dosya adlarının çakışmamasını sağlamanın bir yoludur. + +Ve process bildiriminde yapmak zorunda olduğumuz tek değişiklik bu! + +### Özet + +Channel'ların ve operatörlerin birden fazla girdiyi verimli bir şekilde işlememizi nasıl sağladığını temel düzeyde anlıyorsunuz. + +### Sırada ne var? + +Çok adımlı workflow'ların nasıl oluşturulduğunu ve nasıl çalıştığını keşfedin. + +--- + +## 2. Çok adımlı workflow'ları çalıştırma + +Gerçek dünya workflow'larının çoğu birden fazla adım içerir. +Channel'lar hakkında öğrendiklerimizi temel alarak, Nextflow'un çok adımlı bir workflow'da process'leri birbirine bağlamak için channel'ları ve operatörleri nasıl kullandığına bakalım. + +Bu amaçla, aşağıdakileri gösteren, üç ayrı adımı birbirine zincirleyen örnek bir workflow sağlıyoruz: + +1. Bir process'ten diğerine veri akışı sağlama +2. Birden fazla process çağrısından gelen çıktıları tek bir process çağrısında toplama + +Özellikle, her girdi selamlamasını alan, büyük harfe dönüştüren ve ardından tüm büyük harfli selamlamaları tek bir çıktı dosyasında toplayan `2b-multistep.nf` adlı genişletilmiş bir workflow versiyonu yaptık. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-multi-steps.svg" +</figure> + +Daha önce olduğu gibi, önce workflow'u çalıştıracağız, ardından yeni olan şeyi görmek için koda bakacağız. + +### 2.1. Workflow'u çalıştırın + +Terminalinizde aşağıdaki komutu çalıştırın: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [d6/cdf466] sayHello (1) | 3 of 3 ✔ + [99/79394f] convertToUpper (2) | 3 of 3 ✔ + [1e/83586c] collectGreetings | 1 of 1 ✔ + ``` + +Gördüğünüz gibi, vaat edildiği gibi, workflow'un bir parçası olarak birden fazla adım çalıştırıldı; ilk ikisi (`sayHello` ve `convertToUpper`) muhtemelen her bir selamlamada çalıştırıldı ve üçüncüsü (`collectGreetings`) yalnızca bir kez, üç `convertToUpper` çağrısının çıktılarında çalıştırıldı. + +### 2.2. Çıktıları bulun + +Gerçekten olan şeyin bu olduğunu `results` dizinine bakarak doğrulayalım. + +??? abstract "Dizin içeriği" + + ```console linenums="1" hl_lines="8-16" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── batch-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + + ``` + +Gördüğünüz gibi, `2b-multistep` adında yeni bir dizinimiz var ve öncekinden çok daha fazla dosya içeriyor. +Dosyaların bazıları `intermediates` adlı bir alt dizinde gruplandırılmış, iki dosya ise üst düzeyde bulunuyor. + +Bu ikisi, çok adımlı workflow'un nihai sonuçlarıdır. +Dosya adlarına bakıp beklediğiniz gibi olduklarını doğrulamak için içeriklerini kontrol etmek üzere bir dakikanızı ayırın. + +??? abstract "Dosya içeriği" + + ```txt title="results/2b-multistep/COLLECTED-batch-output.txt" + HELLO + BONJOUR + HOLà + ``` + + ```txt title="results/2b-multistep/batch-report.txt" + There were 3 greetings in this batch. + ``` + +İlki, vaat edildiği gibi büyük harfe dönüştürülmüş ve tek bir dosyada toplanmış üç selamlamamızı içeriyor. +İkincisi, çalıştırma hakkında bazı bilgileri özetleyen bir rapor dosyasıdır. + +### 2.3. Kodu inceleyin + +Koda bakalım ve çok adımlı workflow'lar için temel kalıpları tanımlayalım. + +??? full-code "Tam kod dosyası" + + ```groovy title="2b-multistep.nf" linenums="1" hl_lines="63 75-78 82-84" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + + /* + * Use a text replacement tool to convert the greeting to uppercase + */ + process convertToUpper { + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '${input_file}' | tr '[a-z]' '[A-Z]' > 'UPPER-${input_file}' + """ + } + + /* + * Collect uppercase greetings into a single output file + */ + process collectGreetings { + + input: + path input_files + val batch_name + + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report + + script: + count_greetings = input_files.size() + """ + cat ${input_files} > 'COLLECTED-${batch_name}-output.txt' + echo 'There were ${count_greetings} greetings in this batch.' > '${batch_name}-report.txt' + """ + } + + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } + } + ``` + +Orada çok şey oluyor, ancak önceki workflow versiyonuna kıyasla en belirgin fark, şimdi birden fazla process tanımının olması ve buna bağlı olarak workflow bloğunda birkaç process çağrısının olmasıdır. + +Daha yakından bakalım ve en ilginç parçaları tanımlayabilecek miyiz görelim. + +#### 2.3.1. Workflow yapısını görselleştirme + +Nextflow uzantısıyla VSCode kullanıyorsanız, herhangi bir Nextflow betiğinde workflow bloğunun hemen üzerinde görüntülenen küçük `DAG preview` bağlantısına tıklayarak process'lerin nasıl bağlandığına dair yararlı bir diyagram alabilirsiniz. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/DAG-multistep.svg" +</figure> + +Bu size process'lerin nasıl bağlandığına ve ne ürettiklerine dair güzel bir genel bakış sunar. + +Orijinal `sayHello` process'ine ek olarak, şimdi konsol çıktısında gördüğümüz process'lerin adlarıyla eşleşen `convertToUpper` ve `collectGreetings`'in de olduğunu görüyorsunuz. +İki yeni process tanımı, `sayHello` process'i ile aynı şekilde yapılandırılmıştır, ancak `collectGreetings` `batch` adlı ek bir girdi parametresi alır ve iki çıktı üretir. + +Her birinin koduna ayrıntılı olarak girmeyeceğiz, ancak merak ediyorsanız, ayrıntıları [Hello Nextflow Bölüm 2](../hello_nextflow/03_hello_workflow.md)'de bulabilirsiniz. + +Şimdilik, process'lerin birbirine nasıl bağlandığını inceleyelim. + +#### 2.3.2. Process'ler nasıl bağlanır + +Burada bakılması gereken gerçekten ilginç şey, process çağrılarının workflow'un `main:` bloğunda nasıl birbirine zincirlendiğidir. + +```groovy title="2b-multistep.nf" linenums="68" hl_lines="9 11" + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +İlk process çağrısı olan `sayHello(greeting_ch)`'nin değişmediğini görebilirsiniz. +Sonra, `convertToUpper`'a yapılan sonraki process çağrısı, `sayHello`'nun çıktısına `sayHello.out` olarak atıfta bulunur. + +Kalıp basit: `processName.out` bir process'in çıktı channel'ına atıfta bulunur ve bu doğrudan sonraki process'e geçirilebilir. +Nextflow'da verileri bir adımdan diğerine bu şekilde taşıyoruz. + +#### 2.3.3. Bir process birden fazla girdi alabilir + +Üçüncü process çağrısı olan `collectGreetings` biraz farklıdır. + +```groovy title="2b-multistep.nf" linenums="77" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Bu çağrıya `convertToUpper.out.collect()` ve `params.batch` olmak üzere iki girdi verildiğini görüyorsunuz. +Şimdilik `.collect()` kısmını göz ardı edersek, bunu `collectGreetings(input1, input2)` olarak genelleyebiliriz. + +Bu, process modülündeki iki girdi bildirimiyle eşleşir: + +```groovy title="2b-multistep.nf" linenums="40" +process collectGreetings { + + input: + path input_files + val batch_name +``` + +Nextflow bunu ayrıştırdığında, çağrıdaki ilk girdiyi `path input_files`'a, ikinciyi `val batch_name`'e atayacaktır. + +Böylece artık bir process'in birden fazla girdi alabileceğini ve workflow bloğundaki çağrının nasıl göründüğünü biliyorsunuz. + +Şimdi ilk girdiye daha yakından bakalım, `convertToUpper.out.collect()`. + +#### 2.3.4. `collectGreetings` çağrısında `collect()` ne yapar + +`sayHello`'nun çıktısını `convertToUpper`'a geçirmek için, `sayHello`'nun çıktı channel'ına `sayHello.out` olarak atıfta bulunduk. Ancak bir sonraki adım için `convertToUpper.out.collect()` referansı görüyoruz. + +Bu `collect()` kısmı nedir ve ne yapar? + +Bu elbette bir operatördür. Daha önce karşılaştığımız `splitCsv` ve `map` operatörleri gibi. +Bu sefer operatör `collect` olarak adlandırılır ve `convertToUpper` tarafından üretilen çıktı channel'ına uygulanır. + +`collect` operatörü, aynı process'e yapılan birden fazla çağrıdan gelen çıktıları toplamak ve tek bir channel elemanına paketlemek için kullanılır. + +Bu workflow bağlamında, `convertToUpper.out` channel'ındaki üç büyük harfli selamlamayı --bunlar üç ayrı channel öğesidir ve normalde sonraki process tarafından ayrı çağrılarda işlenirler-- alıp tek bir öğeye paketliyor. + +Daha pratik terimlerle: `collectGreetings()`'e beslemeden önce `convertToUpper()`'ın çıktısına `collect()` uygulamasaydık, Nextflow basitçe `collectGreetings()`'i her selamlamada bağımsız olarak çalıştırırdı, bu da amacımıza ulaşmazdı. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/without-collect-operator.svg" +</figure> + +Buna karşılık, `collect()` kullanmak, workflow'un ikinci adımı tarafından üretilen tüm ayrı büyük harfli selamlamaları almamıza ve pipeline'ın üçüncü adımında tek bir çağrıya hepsini birlikte beslememize olanak tanır. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/with-collect-operator.svg" +</figure> + +Tüm selamlamaları aynı dosyaya bu şekilde geri alıyoruz. + +Process çağrıları arasında channel içeriklerine dönüşümler uygulamak için birçok başka [operatör](https://www.nextflow.io/docs/latest/reference/operator.html#operator-page) mevcuttur. + +Bu, pipeline geliştiricilerine pipeline'larının akış mantığını özelleştirmek için çok fazla esneklik sağlar. +Dezavantajı, bazen pipeline'ın ne yaptığını çözmeyi zorlaştırabilmesidir. + +#### 2.3.5. Bir girdi parametresinin varsayılan değeri olabilir + +`collectGreetings`'in ikinci bir girdi aldığını, `params.batch`'i fark etmiş olabilirsiniz: + +```groovy title="2b-multistep.nf" linenums="77" + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) +``` + +Bu, workflow'a `--batch` adlı bir CLI parametresi geçirir. +Ancak, workflow'u daha önce başlattığımızda bir `--batch` parametresi belirtmedik. + +Burada ne oluyor? +`params` bloğuna bir göz atın: + +```groovy title="2b-multistep.nf" linenums="61" hl_lines="3" +params { + input: Path + batch: String = 'batch' +} +``` + +Workflow'da yapılandırılmış bir varsayılan değer var, bu yüzden sağlamamız gerekmiyor. +Ancak komut satırında bir tane sağlarsak, belirttiğimiz değer varsayılan yerine kullanılacaktır. + +Deneyin: + +```bash +nextflow run 2b-multistep.nf --input data/greetings.csv --batch test +``` + +??? success "Komut çıktısı" + + ```console linenums="1" + N E X T F L O W ~ version 25.10.2 + + Launching `2b-multistep.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [a5/cdff26] sayHello (1) | 3 of 3 ✔ + [c5/78794f] convertToUpper (2) | 3 of 3 ✔ + [d3/b4d86c] collectGreetings | 1 of 1 ✔ + ``` + +Özel batch adınızla adlandırılmış yeni nihai çıktılar görmelisiniz. + +??? abstract "Dizin içeriği" + + ```console linenums="1" hl_lines="10 12" + results + ├── 1-hello + | └── output.txt + ├── 2a-inputs + | ├── Bonjour-output.txt + | ├── Hello-output.txt + | └── Holà-output.txt + └── 2b-multistep + ├── COLLECTED-batch-output.txt + ├── COLLECTED-test-output.txt + ├── batch-report.txt + ├── test-report.txt + └── intermediates + ├── Bonjour-output.txt + ├── Hello-output.txt + ├── Holà-output.txt + ├── UPPER-Bonjour-output.txt + ├── UPPER-Hello-output.txt + └── UPPER-Holà-output.txt + ``` + +Bu, Bölüm 3'te daha ayrıntılı olarak ele alacağımız girdi yapılandırmasının bir yönüdür, ancak şimdilik önemli olan girdi parametrelerine varsayılan değerler verilebileceğini bilmektir. + +#### 2.3.6. Bir process birden fazla çıktı üretebilir + +`collectGreetings` process tanımında aşağıdaki çıktı bildirimlerini görüyoruz: + +```groovy title="2b-multistep.nf" linenums="46" + output: + path "COLLECTED-${batch_name}-output.txt", emit: outfile + path "${batch_name}-report.txt", emit: report +``` + +Bunlara daha sonra `publish:` bloğunda `emit:` ile verilen adla atıfta bulunulur: + +```groovy title="2b-multistep.nf" linenums="80" hl_lines="4 5" + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report +``` + +Bu, belirli çıktıları çeşitli operatörlerle birlikte workflow'daki diğer process'lere bireysel olarak geçirmeyi kolaylaştırır. + +#### 2.3.7. Yayınlanan çıktılar organize edilebilir + +`output` bloğunda, workflow'un yalnızca nihai çıktılarını seçmeyi kolaylaştırmak için ara sonuçları gruplamak üzere özel yollar kullandık. + +```groovy title="2b-multistep.nf" linenums="87" hl_lines="3 7 11 15" +output { + first_output { + path '2b-multistep/intermediates' + mode 'copy' + } + uppercased { + path '2b-multistep/intermediates' + mode 'copy' + } + collected { + path '2b-multistep' + mode 'copy' + } + batch_report { + path '2b-multistep' + mode 'copy' + } +} +``` + +Yayınlanan çıktıları organize etmenin daha sofistike yolları var; yapılandırma bölümünde birkaçına değineceğiz. + +!!! tip "Workflow oluşturma hakkında daha fazla bilgi edinmek ister misiniz?" + + Çok adımlı workflow'lar oluşturmanın ayrıntılı ele alınması için [Hello Nextflow Bölüm 3: Hello Workflow](../hello_nextflow/03_hello_workflow.md) bölümüne bakın. + +### Özet + +Çok adımlı workflow'ların channel'lar ve operatörler kullanılarak nasıl oluşturulduğunu ve nasıl çalıştığını temel düzeyde anlıyorsunuz. +Ayrıca process'lerin birden fazla girdi alabileceğini ve birden fazla çıktı üretebileceğini ve bunların yapılandırılmış bir şekilde yayınlanabileceğini gördünüz. + +### Sırada ne var? + +Nextflow pipeline'larının kod yeniden kullanımını ve sürdürülebilirliği teşvik etmek için nasıl modülerleştirilebileceğini öğrenin. + +--- + +## 3. Modülerleştirilmiş pipeline'ları çalıştırma + +Şu ana kadar baktığımız tüm workflow'lar, tüm ilgili kodu içeren tek bir workflow dosyasından oluşuyordu. + +Ancak, gerçek dünya pipeline'ları tipik olarak _modülerleştirilmiş_ olmaktan fayda görür, yani kod farklı dosyalara bölünür. +Bu, geliştirmelerini ve bakımlarını daha verimli ve sürdürülebilir hale getirebilir. + +Burada Nextflow'da en yaygın kod modülerlik biçimini göstereceğiz, bu da **modül** kullanımıdır. + +Nextflow'da bir **modül**, bağımsız bir kod dosyasında kendi başına kapsüllenmiş tek bir process tanımıdır. +Bir workflow'da modül kullanmak için, workflow kod dosyanıza tek satırlık bir import ifadesi eklemeniz yeterlidir; ardından process'i normalde yapacağınız şekilde workflow'a entegre edebilirsiniz. +Bu, kodun birden fazla kopyasını üretmeden birden fazla workflow'da process tanımlarını yeniden kullanmayı mümkün kılar. + +Şu ana kadar tüm process'leri monolitik bir kod dosyasına dahil edilmiş workflow'ları çalıştırıyorduk. +Şimdi process'ler ayrı modüllerde saklandığında nasıl göründüğünü göreceğiz. + +Elbette yine gösterim amacıyla uygun bir workflow, `2c-modules.nf` adlı, `modules/` dizininde bulunan bir modül setiyle birlikte hazırladık. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/modules.svg" +</figure> + +??? abstract "Dizin içeriği" + + ```console + modules/ + ├── collectGreetings.nf + ├── convertToUpper.nf + ├── cowpy.nf + └── sayHello.nf + ``` + +Her biri process'lerden birinin adını taşıyan dört Nextflow dosyası olduğunu görüyorsunuz. +Şimdilik `cowpy.nf` dosyasını görmezden gelebilirsiniz; ona daha sonra geleceğiz. + +### 3.1. Kodu inceleyin + +Bu sefer önce koda bakacağız. +`2c-modules.nf` workflow dosyasını açarak başlayın. + +??? full-code "Tam kod dosyası" + + ```groovy title="2c-modules.nf" linenums="1" + #!/usr/bin/env nextflow + + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String = 'batch' + } + + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + } + + output { + first_output { + path '2c-modules/intermediates' + mode 'copy' + } + uppercased { + path '2c-modules/intermediates' + mode 'copy' + } + collected { + path '2c-modules' + mode 'copy' + } + batch_report { + path '2c-modules' + mode 'copy' + } + } + ``` + +Workflow mantığının önceki workflow versiyonuyla tamamen aynı olduğunu görüyorsunuz. +Ancak, process kodu workflow dosyasından gitmiş ve yerine `modules` altındaki ayrı dosyalara işaret eden `include` ifadeleri var. + +```groovy title="hello-modules.nf" linenums="3" +// Modülleri dahil et +include { sayHello } from './modules/sayHello.nf' +include { convertToUpper } from './modules/convertToUpper.nf' +include { collectGreetings } from './modules/collectGreetings.nf' +``` + +Bu dosyalardan birini açın ve ilgili process'in kodunu bulacaksınız. + +??? full-code "Tam kod dosyası" + + ```groovy title="modules/sayHello.nf" linenums="1" + #!/usr/bin/env nextflow + + /* + * 'Hello World!' ifadesini bir dosyaya yazdırmak için echo kullan + */ + process sayHello { + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '${greeting}' > '${greeting}-output.txt' + """ + } + ``` + +Gördüğünüz gibi, process kodu değişmedi; sadece ana workflow dosyasında olmak yerine bireysel bir modül dosyasına kopyalandı. +Aynısı diğer iki process için de geçerlidir. + +Şimdi bu yeni versiyonu çalıştırmanın nasıl göründüğüne bakalım. + +### 3.2. Workflow'u çalıştırın + +Bu komutu `-resume` bayrağıyla terminalinizde çalıştırın: + +```bash +nextflow run 2c-modules.nf --input data/greetings.csv -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2c-modules.nf` [soggy_franklin] DSL2 - revision: bc8e1b2726 + + [j6/cdfa66] sayHello (1) | 3 of 3, cached: ✔ + [95/79484f] convertToUpper (2) | 3 of 3, cached: ✔ + [5e/4358gc] collectGreetings | 1 of 1, cached: ✔ + ``` + +Process çalıştırmalarının hepsinin başarıyla önbelleğe alındığını fark edeceksiniz, yani Nextflow istenen işi zaten yaptığını tanıdı, kod bölünmüş ve ana workflow dosyası yeniden adlandırılmış olsa bile. + +Bunların hiçbiri Nextflow için önemli değil; önemli olan tüm kod bir araya getirilip değerlendirildikten sonra oluşturulan iş betiğidir. + +!!! tip "İpucu" + + Bir workflow'un bir bölümünü daha büyük bir pipeline'a aktarılabilecek bir 'alt workflow' olarak kapsüllemek de mümkündür, ancak bu kursun kapsamı dışındadır. + + [Workflows of Workflows](https://training.nextflow.io/latest/side_quests/workflows_of_workflows/) Yan Görevinde birleştirilebilir workflow'lar geliştirme hakkında daha fazla bilgi edinebilirsiniz. + +### Özet + +Process'lerin kod yeniden kullanımını teşvik etmek ve sürdürülebilirliği artırmak için bağımsız modüllerde nasıl saklanabileceğini biliyorsunuz. + +### Sırada ne var? + +Yazılım bağımlılıklarını yönetmek için konteynerleri kullanmayı öğrenin. + +--- + +## 4. Konteynerleştirilmiş yazılım kullanma + +Şu ana kadar örnek olarak kullandığımız workflow'lar, ortamımızda bulunan UNIX araçlarını kullanarak çok temel metin işleme işlemlerini çalıştırmak zorunda kaldı. + +Ancak, gerçek dünya pipeline'ları tipik olarak çoğu ortamda varsayılan olarak dahil edilmeyen özel araçlar ve paketler gerektirir. +Genellikle bu araçları yüklemeniz, bağımlılıklarını yönetmeniz ve herhangi bir çakışmayı çözmeniz gerekirdi. + +Bunların hepsi çok sıkıcı ve can sıkıcıdır. +Bu sorunu ele almanın çok daha iyi bir yolu **konteyner** kullanmaktır. + +Bir **konteyner**, kod, sistem kütüphaneleri ve ayarlar dahil bir uygulamayı çalıştırmak için gereken her şeyi içeren bir konteyner **imajından** oluşturulan hafif, bağımsız, çalıştırılabilir bir yazılım birimidir. + +!!! Tip "İpucu" + + Bunu [Docker](https://www.docker.com/get-started/) teknolojisini kullanarak öğretiyoruz, ancak Nextflow [birkaç başka konteyner teknolojisini](https://www.nextflow.io/docs/latest/container.html#) de destekler. + +### 4.1. Bir konteyneri doğrudan kullanın + +Önce bir konteynerle doğrudan etkileşime geçelim. +Bu, Nextflow'da kullanmaya başlamadan önce konteynerlerin ne olduğunu anlamanıza yardımcı olacaktır. + +#### 4.1.1. Konteyner imajını çekin + +Bir konteyneri kullanmak için, genellikle bir konteyner kaydından bir konteyner imajı indirirsiniz veya "çekersiniz" ve ardından bir konteyner örneği oluşturmak için konteyner imajını çalıştırırsınız. + +Genel sözdizimi şöyledir: + +```bash title="Sözdizimi" +docker pull '<container>' +``` + +- `docker pull`, konteyner sistemine bir havuzdan konteyner imajı çekmesi için talimat verir. +- `'<container>'`, konteyner imajının URI adresidir. + +Örnek olarak, rastgele metin girdilerini eğlenceli bir şekilde görüntülemek için ASCII art üreten `cowsay` adlı bir aracın python uygulaması olan [cowpy](https://github.com/jeffbuttars/cowpy) içeren bir konteyner imajı çekelim. + +Yayınlanmış konteynerleri bulabileceğiniz çeşitli havuzlar vardır. +Bu Docker konteyner imajını `cowpy` Conda paketinden oluşturmak için [Seqera Containers](https://seqera.io/containers/) hizmetini kullandık: `'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'`. + +Tam çekme komutunu çalıştırın: + +```bash +docker pull 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +??? success "Komut çıktısı" + + ```console + Unable to find image 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' locally + 131d6a1b707a8e65: Pulling from library/cowpy + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 622dd7f15040: Pull complete + 895fb5d0f4df: Pull complete + Digest: sha256:fa50498b32534d83e0a89bb21fec0c47cc03933ac95c6b6587df82aaa9d68db3 + Status: Downloaded newer image for community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273 + ``` + +Bu, sisteme belirtilen imajı indirmesini söyler. +İndirme tamamlandığında, konteyner imajının yerel bir kopyasına sahip olursunuz. + +#### 4.1.2. Konteyneri başlatın + +Konteynerler tek seferlik bir komut olarak çalıştırılabilir, ancak bunları etkileşimli olarak da kullanabilirsiniz, bu size konteynerin içinde bir shell promptu verir ve komutla oynamanıza olanak tanır. + +Genel sözdizimi şöyledir: + +```bash title="Sözdizimi" +docker run --rm '<container>' [tool command] +``` + +- `docker run --rm '<container>'`, konteyner sistemine bir konteyner imajından bir konteyner örneği başlatması ve içinde bir komut yürütmesi için talimat verir. +- `--rm`, sisteme komut tamamlandıktan sonra konteyner örneğini kapatmasını söyler. + +Tam olarak birleştirilmiş konteyner yürütme komutu şöyle görünür: + +```bash +docker run --rm -it 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' +``` + +Bu komutu çalıştırın ve promptunuzun `(base) root@b645838b3314:/tmp#` gibi bir şeye dönüştüğünü görmelisiniz, bu artık konteynerin içinde olduğunuzu gösterir. + +Bunu, dizin içeriğini listelemek için `ls` çalıştırarak doğrulayabilirsiniz: + +```bash +ls / +``` + +??? success "Komut çıktısı" + + ```console + bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var + ``` + +Konteynerin içindeki dosya sisteminin ana sisteminizden farklı olduğunu görüyorsunuz. + +!!! Tip "İpucu" + + Bir konteyneri çalıştırdığınızda, varsayılan olarak ana sistemden izole edilir. + Bu, konteynerin ana sistemdeki hiçbir dosyaya erişemeyeceği anlamına gelir, bunu aşağıdaki sözdizimini kullanarak `docker run` komutunun bir parçası olarak bir birim bağlamak istediğinizi belirterek açıkça izin vermediğiniz sürece: + + ```bash title="Sözdizimi" + -v <outside_path>:<inside_path> + ``` + + Bu, dosya sisteminizin o bölümüne erişmek için kullanabileceğiniz, konteyner duvarından bir tünel oluşturur. + + Bu, [Hello Nextflow Bölüm 5](../hello_nextflow/05_hello_containers.md)'te daha ayrıntılı olarak ele alınmaktadır. + +#### 4.1.3. `cowpy` aracını çalıştırın + +Konteynerin içinden `cowpy` komutunu doğrudan çalıştırabilirsiniz. + +```bash +cowpy "Hello Containers" +``` + +??? success "Komut çıktısı" + + ```console + ______________________________________________________ + < Hello Containers > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + +Bu, belirttiğimiz metni içeren bir konuşma balonuyla varsayılan inek karakterinin (veya 'cowacter') ASCII art'ını üretir. + +Temel kullanımı test ettiğinize göre, ona bazı parametreler vermeyi deneyebilirsiniz. +Örneğin, araç belgeleri karakteri `-c` ile ayarlayabileceğimizi söylüyor. + +```bash +cowpy "Hello Containers" -c tux +``` + +??? success "Komut çıktısı" + + ```console + __________________ + < Hello Containers > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Bu sefer ASCII art çıktısı Linux pengueni Tux'u gösteriyor, çünkü `-c tux` parametresini belirttik. + +Konteynerin içinde olduğunuz için, sisteminize herhangi bir kütüphane yüklemek zorunda kalmadan girdi parametrelerini değiştirerek cowpy komutunu istediğiniz kadar çalıştırabilirsiniz. + +??? tip "Diğer mevcut karakterler" + + Farklı bir karakter seçmek için '-c' bayrağını kullanın, bunlar dahil: + + `beavis`, `cheese`, `daemon`, `dragonandcow`, `ghostbusters`, `kitty`, `moose`, `milk`, `stegosaurus`, `turkey`, `turtle`, `tux` + +Bununla oynamaktan çekinmeyin. +İşiniz bittiğinde, `exit` komutunu kullanarak konteynerden çıkın: + +```bash +exit +``` + +Normal shell'inize geri döneceksiniz. + +### 4.2. Bir workflow'da konteyner kullanın + +Bir pipeline çalıştırdığımızda, Nextflow'a her adımda hangi konteynerin kullanılacağını söyleyebilmek istiyoruz ve önemlisi, az önce yaptığımız tüm işi onun halletmesini istiyoruz: konteyneri çekmek, başlatmak, komutu çalıştırmak ve bittiğinde konteyneri kapatmak. + +İyi haber: tam olarak Nextflow'un bizim için yapacağı şey bu. +Sadece her process için bir konteyner belirtmemiz gerekiyor. + +Bunun nasıl çalıştığını göstermek için, üçüncü adımda üretilen toplanan selamlamalar dosyasında `cowpy` çalıştıran workflow'umuzun başka bir versiyonunu yaptık. + +<figure class="excalidraw"> +--8<-- "docs/nextflow_run/img/hello-pipeline-cowpy.svg" +</figure> + +Bu, konuşma balonunda üç selamlama içeren ASCII art içeren bir dosya çıktısı vermelidir. + +#### 4.2.1. Kodu inceleyin + +Workflow, öncekine çok benzer, artı `cowpy` çalıştırmak için ekstra adım. + +??? full-code "Tam kod dosyası" + + ```groovy title="2d-container.nf" linenums="1" hl_lines="7 15 32 39 59-62" + #!/usr/bin/env nextflow + + // Modülleri dahil et + include { sayHello } from './modules/sayHello.nf' + include { convertToUpper } from './modules/convertToUpper.nf' + include { collectGreetings } from './modules/collectGreetings.nf' + include { cowpy } from './modules/cowpy.nf' + + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String = 'batch' + character: String + } + + workflow { + + main: + // bir CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input) + .splitCsv() + .map { line -> line[0] } + // bir selamlama yayınla + sayHello(greeting_ch) + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + // tüm selamlamaları tek bir dosyada topla + collectGreetings(convertToUpper.out.collect(), params.batch) + // cowpy ile selamlamaların ASCII sanatını oluştur + cowpy(collectGreetings.out.outfile, params.character) + + publish: + first_output = sayHello.out + uppercased = convertToUpper.out + collected = collectGreetings.out.outfile + batch_report = collectGreetings.out.report + cowpy_art = cowpy.out + } + + output { + first_output { + path '2d-container/intermediates' + mode 'copy' + } + uppercased { + path '2d-container/intermediates' + mode 'copy' + } + collected { + path '2d-container/intermediates' + mode 'copy' + } + batch_report { + path '2d-container' + mode 'copy' + } + cowpy_art { + path '2d-container' + mode 'copy' + } + } + ``` + +Bu workflow'un bir modül dosyasından bir `cowpy` process'i içe aktardığını ve bunu `collectGreetings()` çağrısının çıktısında, artı `params.character` adlı bir girdi parametresinde çağırdığını görüyorsunuz. + +```groovy title="2d-container.nf" linenums="25" +// cowpy ile ASCII sanatı oluştur +cowpy(collectGreetings.out, params.character) +``` + +ASCII art oluşturmak için cowpy komutunu saran `cowpy` process'i, `cowpy.nf` modülünde tanımlanmıştır. + +??? full-code "Tam kod dosyası" + + ```groovy title="modules/cowpy.nf" linenums="1" + #!/usr/bin/env nextflow + + // Generate ASCII art with cowpy (https://github.com/jeffbuttars/cowpy) + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c "${character}" > cowpy-${input_file} + """ + } + ``` + +`cowpy` process'i iki girdi gerektirir: konuşma balonuna konulacak metni içeren bir girdi dosyasının yolu (`input_file`) ve karakter değişkeni için bir değer. + +Önemlisi, daha önce kullandığımız konteyner URI'sine işaret eden `container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273'` satırını da içerir. + +#### 4.2.2. Yapılandırmada Docker'ın etkinleştirildiğini kontrol edin + +Bu eğitim kursunun 3. Bölümünü biraz öne çekerek, Nextflow'un workflow çalıştırmasını yapılandırmanın ana yollarından biri olan `nextflow.config` yapılandırma dosyasını tanıtacağız. +Geçerli dizinde `nextflow.config` adlı bir dosya bulunduğunda, Nextflow otomatik olarak yükleyecek ve içerdiği yapılandırmayı uygulayacaktır. + +Bu amaçla, Docker'ı etkinleştiren tek satırlık kod içeren bir `nextflow.config` dosyası ekledik. + +```groovy title="nextflow.config" linenums="1" +docker.enabled = true +``` + +Bu yapılandırma, Nextflow'a uyumlu bir konteyner belirten herhangi bir process için Docker kullanmasını söyler. + +!!! tip "İpucu" + + Docker çalıştırmasını komut satırından, çalıştırma başına bazında `-with-docker <container>` parametresini kullanarak etkinleştirmek teknik olarak mümkündür. + Ancak, bu yalnızca tüm workflow için bir konteyner belirtmemize izin verirken, az önce gösterdiğimiz yaklaşım process başına farklı bir konteyner belirtmemize olanak tanır. + İkincisi modülerlik, kod bakımı ve tekrar üretilebilirlik için çok daha iyidir. + +#### 4.2.3. Workflow'u çalıştırın + +Özetlemek gerekirse, çalıştırmak üzere olduğumuz şey: + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +Çalışacak mı sizce? + +Workflow'u `-resume` bayrağıyla çalıştıralım ve karakterin hindi olmasını istediğimizi belirtelim. + +```bash +nextflow run 2d-container.nf --input data/greetings.csv --character turkey -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `2d-container.nf` [elegant_brattain] DSL2 - revision: 028a841db1 + + executor > local (1) + [95/fa0bac] sayHello (3) | 3 of 3, cached: 3 ✔ + [92/32533f] convertToUpper (3) | 3 of 3, cached: 3 ✔ + [aa/e697a2] collectGreetings | 1 of 1, cached: 1 ✔ + [7f/caf718] cowpy | 1 of 1 ✔ + ``` + +İlk üç adım daha önce çalıştırdığımız için önbelleğe alındı, ancak `cowpy` process'i yeni olduğu için gerçekten çalıştırılıyor. + +`cowpy` adımının çıktısını `results` dizininde bulabilirsiniz. + +??? abstract "Dosya içeriği" + + ```console title="results/2d-container/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +Karakterin tüm selamlamaları söylediğini görüyorsunuz, çünkü toplanan büyük harfli selamlamalar dosyasında çalıştı. + +Daha da önemlisi, cowpy ve tüm bağımlılıklarının düzgün bir kurulumunu yapmak zorunda kalmadan bunu pipeline'ımızın bir parçası olarak çalıştırabildik. +Ve şimdi pipeline'ı iş arkadaşlarımızla paylaşabilir ve Docker veya yukarıda belirtildiği gibi alternatiflerinden biri (Singularity/Apptainer gibi) dışında hiçbir şey yüklemelerine gerek kalmadan kendi altyapılarında çalıştırmalarını sağlayabiliriz. + +#### 4.2.4. Nextflow'un konteynerleştirilmiş görevi nasıl başlattığını inceleyin + +Bu bölüme son bir koda olarak, Nextflow'un kaputun altında konteynerlerle nasıl çalıştığı hakkında biraz daha fazla bilgi edinmek için `cowpy` process çağrılarından birinin çalışma alt dizinine bir göz atalım. + +`cowpy` process'inin çalışma alt dizininin yolunu bulmak için `nextflow run` komutunuzun çıktısını kontrol edin. +Yukarıda gösterilen çalıştırma için aldığımıza bakarsak, `cowpy` process'i için konsol log satırı `[7f/caf718]` ile başlıyor. +Bu, şu kısaltılmış dizin yoluna karşılık gelir: `work/7f/caf718`. + +Bu dizinde, Nextflow'un pipeline'ı yürütme sürecinde sizin adınıza çalıştırdığı tüm komutları içeren `.command.run` dosyasını bulacaksınız. + +??? abstract "Dosya içeriği" + + ```console title="work/7f/caf71890cce1667c094d880f4b6dcc/.command.run" + #!/bin/bash + ### --- + ### name: 'cowpy' + ### container: 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + ### outputs: + ### - 'cowpy-COLLECTED-batch-output.txt' + ### ... + set -e + set -u + NXF_DEBUG=${NXF_DEBUG:=0}; [[ $NXF_DEBUG > 1 ]] && set -x + NXF_ENTRY=${1:-nxf_main} + + + nxf_sleep() { + sleep $1 2>/dev/null || sleep 1; + } + + nxf_date() { + local ts=$(date +%s%3N); + if [[ ${#ts} == 10 ]]; then echo ${ts}000 + elif [[ $ts == *%3N ]]; then echo ${ts/\%3N/000} + elif [[ $ts == *3N ]]; then echo ${ts/3N/000} + elif [[ ${#ts} == 13 ]]; then echo $ts + else echo "Unexpected timestamp value: $ts"; exit 1 + fi + } + ... + ``` + +Bu dosyada ilerlerseniz, her şeyin nasıl kurulduğunu ve konteynerin nasıl başlatıldığını görebilirsiniz; bu epey bir iş ki biz hiç yapmak zorunda kalmadık! + +### Özet + +Bir workflow'da konteynerleştirilmiş araçların nasıl kullanılacağını ve bir process modülünde konteyner direktifinin nasıl belirtileceğini biliyorsunuz. + +### Sırada ne var? + +Çalıştırma yapılandırmasıyla pipeline'ı nasıl özelleştireceğinizi öğrenin. diff --git a/docs/tr/docs/nextflow_run/03_config.md b/docs/tr/docs/nextflow_run/03_config.md new file mode 100644 index 0000000000..b2ffb753b7 --- /dev/null +++ b/docs/tr/docs/nextflow_run/03_config.md @@ -0,0 +1,1630 @@ +# Bölüm 3: Çalıştırma yapılandırması + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu bölümde, bir Nextflow pipeline'ının yapılandırmasını yönetmeyi keşfedeceğiz; davranışını özelleştirmek, farklı ortamlara uyarlamak ve kaynak kullanımını optimize etmek için _workflow kodunun tek bir satırını değiştirmeden_. + +Bunu yapmanın birden fazla yolu vardır; bunlar birlikte kullanılabilir ve [burada](https://www.nextflow.io/docs/latest/config.html) açıklanan öncelik sırasına göre yorumlanır. + +Kursun bu bölümünde, Bölüm 2'de konteynerler bölümünde zaten karşılaştığınız `nextflow.config` dosyası olan en basit ve en yaygın yapılandırma dosyası mekanizmasını göstereceğiz. + +Process direktifleri, executor'lar, profiller ve parametre dosyaları gibi Nextflow yapılandırmasının temel bileşenlerini inceleyeceğiz. +Bu yapılandırma seçeneklerini etkili bir şekilde kullanmayı öğrenerek, Nextflow pipeline'larının esnekliğinden, ölçeklenebilirliğinden ve performansından tam olarak yararlanabilirsiniz. + +Bu yapılandırma öğelerini uygulamak için, bu eğitim kursunun 2. Bölümünün sonunda çalıştırdığımız workflow'un `3-main.nf` olarak yeniden adlandırılmış yeni bir kopyasını çalıştıracağız. + +Hello pipeline'ına aşina değilseniz veya bir hatırlatmaya ihtiyacınız varsa, [bu bilgi sayfasına](../info/hello_pipeline.md) bakın. + +--- + +## 1. Workflow girdi parametrelerini yönetme + +??? example "Senaryo" + + Bir pipeline indirdiniz ve aynı girdi dosyaları ve ayarlarla tekrar tekrar çalıştırmak istiyorsunuz, ancak her seferinde tüm parametreleri yazmak istemiyorsunuz. + Ya da belki komut satırı argümanlarıyla rahat olmayan bir meslektaşınız için pipeline'ı kuruyorsunuz. + +Şu ana kadar üzerinde çalıştığımız şeyin bir uzantısı olan bir yapılandırma yönüyle başlayacağız: girdi parametrelerinin yönetimi. + +Şu anda workflow'umuz, workflow betiğinde bir `params` bloğunda bildirilen komut satırı aracılığıyla birkaç parametre değeri kabul edecek şekilde ayarlanmıştır. +Bunlardan birinin bildiriminin bir parçası olarak varsayılan değeri ayarlanmıştır. + +Ancak, hepsi için varsayılan değerler ayarlamak veya mevcut varsayılanı komut satırında parametre belirtmek ya da orijinal betik dosyasını değiştirmek zorunda kalmadan geçersiz kılmak isteyebilirsiniz. + +Bunu yapmanın birden fazla yolu vardır; size çok yaygın olarak kullanılan üç temel yolu göstereceğiz. + +### 1.1. `nextflow.config`'de değerler ayarlayın + +Bu en basit yaklaşımdır, ancak muhtemelen en az esnektir çünkü ana `nextflow.config` dosyası her çalıştırma için düzenlemek isteyeceğiniz bir şey değildir. +Ancak, workflow'da parametreleri _bildirme_ (ki kesinlikle oraya aittir) ile bir yapılandırma dosyasında daha evde olan _varsayılan değerler_ sağlama endişelerini ayırma avantajına sahiptir. + +Bunu iki adımda yapalım. + +#### 1.1.1. Yapılandırma dosyasında bir `params` bloğu oluşturun + +`nextflow.config` dosyasında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="1" hl_lines="3-10" + docker.enabled = true + + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="1" + docker.enabled = true + ``` + +`params` bloğunu workflow'dan yapılandırma dosyasına sadece kopyalamadığımıza dikkat edin. +Zaten varsayılan değeri bildirilen `batch` parametresi için sözdizimi biraz farklıdır. +Workflow dosyasında bu türlenmiş bir bildirimdir. +Yapılandırmada bunlar değer atamalarıdır. + +Teknik olarak, bu workflow dosyasında hala belirtilen varsayılan değerleri geçersiz kılmak için yeterlidir. +`batch` için varsayılan değeri değiştirebilir ve yapılandırma dosyasında ayarlanan değerin workflow dosyasında ayarlanan değeri geçersiz kıldığını kendiniz doğrulamak için workflow'u çalıştırabilirsiniz. + +Ancak yapılandırmayı tamamen yapılandırma dosyasına taşıma ruhuyla, bu varsayılan değeri workflow dosyasından tamamen kaldıralım. + +#### 1.1.2. Workflow dosyasındaki `batch` için varsayılan değeri kaldırın + +`3-main.nf` workflow dosyasında aşağıdaki kod değişikliğini yapın: + +=== "Sonra" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String + character: String + } + ``` + +=== "Önce" + + ```groovy title="3-main.nf" linenums="9" hl_lines="6" + /* + * Pipeline parametreleri + */ + params { + input: Path + batch: String = 'batch' + character: String + } + ``` + +Artık workflow dosyasının kendisi bu parametreler için herhangi bir varsayılan değer ayarlamıyor. + +#### 1.1.3. Pipeline'ı çalıştırın + +Komut satırında herhangi bir parametre belirtmeden doğru çalışıp çalışmadığını test edelim. + +```bash +nextflow run 3-main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hala daha önce olduğu gibi aynı çıktıyı üretiyor. + +Nihai ASCII art çıktısı `results/3-main/` dizininde, öncekiyle aynı şekilde `cowpy-COLLECTED-batch-output.txt` adı altında. + +??? abstract "Dosya içeriği" + + ```console title="results/3-main/cowpy-COLLECTED-batch-output.txt" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ,+*^^*+___+++_ + \ ,*^^^^ ) + \ _+* ^**+_ + \ +^ _ _++*+_+++_, ) + _+^^*+_ ( ,+*^ ^ \+_ ) + { ) ( ,( ,_+--+--, ^) ^\ + { (\@) } f ,( ,+-^ __*_*_ ^^\_ ^\ ) + {:;-/ (_+*-+^^^^^+*+*<_ _++_)_ ) ) / + ( / ( ( ,___ ^*+_+* ) < < \ + U _/ ) *--< ) ^\-----++__) ) ) ) + ( ) _(^)^^)) ) )\^^^^^))^*+/ / / + ( / (_))_^)) ) ) ))^^^^^))^^^)__/ +^^ + ( ,/ (^))^)) ) ) ))^^^^^^^))^^) _) + *+__+* (_))^) ) ) ))^^^^^^))^^^^^)____*^ + \ \_)^)_)) ))^^^^^^^^^^))^^^^) + (_ ^\__^^^^^^^^^^^^))^^^^^^^) + ^\___ ^\__^^^^^^))^^^^^^^^)\\ + ^^^^^\uuu/^^\uuu/^^^^\^\^\^\^\^\^\^\ + ___) >____) >___ ^\_\_\_\_\_\_\) + ^^^//\\_^^//\\_^ ^(\_\_\_\) + ^^^ ^^ ^^^ ^ + ``` + +İşlevsel olarak bu taşıma hiçbir şeyi değiştirmedi, ancak kavramsal olarak varsayılan değerlerin yapılandırma dosyasında ayarlanması biraz daha temizdir. + +### 1.2. Çalıştırmaya özel yapılandırma dosyası kullanın + +??? example "Senaryo" + + Ana yapılandırma dosyanızı değiştirmeden farklı ayarlarla denemeler yapmak istiyorsunuz. + +Bunu, deneyler için çalışma dizini olarak kullanacağınız bir alt dizinde yeni bir `nextflow.config` dosyası oluşturarak yapabilirsiniz. + +#### 1.2.1. Boş bir yapılandırmayla çalışma dizini oluşturun + +Yeni bir dizin oluşturup içine girerek başlayalım: + +```bash +mkdir -p tux-run +cd tux-run +``` + +Ardından, bu dizinde boş bir yapılandırma dosyası oluşturun: + +```bash +touch nextflow.config +``` + +Bu boş bir dosya üretir. + +#### 1.2.2. Deneysel yapılandırmayı kurun + +Şimdi yeni dosyayı açın ve özelleştirmek istediğiniz parametreleri ekleyin: + +```groovy title="tux-run/nextflow.config" linenums="1" +params { + input = '../data/greetings.csv' + batch = 'experiment' + character = 'tux' +} +``` + +Girdi dosyasının yolunun dizin yapısını yansıtması gerektiğini unutmayın. + +#### 1.2.3. Pipeline'ı çalıştırın + +Artık pipeline'ımızı yeni çalışma dizinimizin içinden çalıştırabiliriz. +Yolu buna göre uyarladığınızdan emin olun! + +```bash +nextflow run ../3-main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `../3-main.nf` [trusting_escher] DSL2 - revision: 356df0818d + + executor > local (8) + [59/b66913] sayHello (2) [100%] 3 of 3 ✔ + [ad/f06364] convertToUpper (3) [100%] 3 of 3 ✔ + [10/714895] collectGreetings [100%] 1 of 1 ✔ + [88/3ece98] cowpy [100%] 1 of 1 ✔ + ``` + +Bu, `tux-run/` altında `tux-run/work/` ve `tux-run/results/` dahil yeni dizinler oluşturacaktır. + +Bu çalıştırmada, Nextflow mevcut dizinimizdeki `nextflow.config`'i pipeline'ın kök dizinindeki `nextflow.config` ile birleştirir ve böylece varsayılan karakteri (turkey) tux karakteriyle geçersiz kılar. + +Nihai çıktı dosyası, selamlamaları söyleyen tux karakterini içermelidir. + +??? abstract "Dosya içeriği" + + ```console title="tux-run/results/3-main/cowpy-COLLECTED-experiment-output.txt" + _________ + / HELLO \ + | BONJOUR | + \ HOLà / + --------- + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + + ``` + +İşte bu kadar; artık 'normal' yapılandırmanızı değiştirmeden denemeler yapmak için bir alanınız var. + +!!! warning "Uyarı" + + Bir sonraki bölüme geçmeden önce önceki dizine geri dönmeyi unutmayın! + + ```bash + cd .. + ``` + +Şimdi parametre değerlerini ayarlamanın başka bir yararlı yoluna bakalım. + +### 1.3. Parametre dosyası kullanın + +??? example "Senaryo" + + Tam çalıştırma parametrelerini bir iş arkadaşınızla paylaşmanız veya bir yayın için kaydetmeniz gerekiyor. + +Alt dizin yaklaşımı denemeler için harika çalışır, ancak biraz kurulum içerir ve yolları buna göre uyarlamanızı gerektirir. +Pipeline'ınızı belirli bir değer setiyle çalıştırmak veya başka birinin bunu minimum çabayla yapmasını sağlamak istediğinizde daha basit bir yaklaşım vardır. + +Nextflow, parametreleri YAML veya JSON formatında bir parametre dosyası aracılığıyla belirtmemize olanak tanır; bu, örneğin alternatif varsayılan değer setlerini ve çalıştırmaya özel parametre değerlerini yönetmeyi ve dağıtmayı çok uygun hale getirir. + +#### 1.3.1. Örnek parametre dosyasını inceleyin + +Bunu göstermek için, geçerli dizinde `test-params.yaml` adlı örnek bir parametre dosyası sağlıyoruz: + +```yaml title="test-params.yaml" linenums="1" +input: "data/greetings.csv" +batch: "yaml" +character: "stegosaurus" +``` + +Bu parametre dosyası, belirtmek istediğimiz girdilerin her biri için bir anahtar-değer çifti içerir. +Sözdizimini yapılandırma dosyasıyla karşılaştırırsanız eşittir işaretleri (`=`) yerine iki nokta üst üste (`:`) kullanımına dikkat edin. +Yapılandırma dosyası Groovy'de yazılırken, parametre dosyası YAML'de yazılır. + +!!! info "Bilgi" + + Ayrıca örnek olarak parametre dosyasının JSON versiyonunu da sağlıyoruz ancak burada onunla çalıştırmayacağız. + Onu kendi başınıza denemeye çekinmeyin. + +#### 1.3.2. Pipeline'ı çalıştırın + +Workflow'u bu parametre dosyasıyla çalıştırmak için, temel komuta `-params-file <filename>` eklemeniz yeterlidir. + +```bash +nextflow run 3-main.nf -params-file test-params.yaml +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_sammet] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Nihai çıktı dosyası, selamlamaları söyleyen stegosaurus karakterini içermelidir. + +??? abstract "Dosya içeriği" + + ```console title="results/3-main/cowpy-COLLECTED-yaml-output.txt" + _________ + / HELLO \ + | HOLà | + \ BONJOUR / + --------- + \ . . + \ / `. .' " + \ .---. < > < > .---. + \ | \ \ - ~ ~ - / / | + _____ ..-~ ~-..-~ + | | \~~~\.' `./~~~/ + --------- \__/ \__/ + .' O \ / / \ " + (_____, `._.' | } \/~~~/ + `----. / } | / \__/ + `-. | / | / `. ,~~| + ~-.__| /_ - ~ ^| /- _ `..-' + | / | / ~-. `-. _ _ _ + |_____| |_____| ~ - . _ _ _ _ _> + ``` + +Yalnızca birkaç parametreniz olduğunda parametre dosyası kullanmak aşırı görünebilir, ancak bazı pipeline'lar düzinelerce parametre bekler. +Bu durumlarda, bir parametre dosyası kullanmak, devasa komut satırları yazmak zorunda kalmadan ve workflow betiğini değiştirmeden çalışma zamanında parametre değerleri sağlamamıza olanak tanır. + +Ayrıca parametre setlerini iş arkadaşlarına veya örneğin bir yayın için destekleyici bilgi olarak dağıtmayı kolaylaştırır. +Bu, çalışmanızı başkaları tarafından daha tekrar üretilebilir hale getirir. + +### Özet + +Workflow girdilerini yönetmek için temel yapılandırma seçeneklerinden nasıl yararlanacağınızı biliyorsunuz. + +### Sırada ne var? + +Workflow çıktılarınızın nerede ve nasıl yayınlandığını yönetmeyi öğrenin. + +--- + +## 2. Workflow çıktılarını yönetme + +??? example "Senaryo" + + Pipeline'ınız çıktıları sabit kodlanmış bir dizine yayınlıyor, ancak her seferinde workflow kodunu düzenlemeden sonuçları proje veya deney adına göre organize etmek istiyorsunuz. + +Miras aldığımız workflow, workflow düzeyinde çıktı bildirimleri için yollar kullanıyor, bu çok esnek değil ve çok tekrar içeriyor. + +Bunu daha esnek yapılandırmak için birkaç yaygın yola bakalım. + +### 2.1. `outputDir` dizin adını özelleştirme + +Şu ana kadar çalıştırdığımız workflow'un her versiyonu çıktılarını çıktı tanımlarına sabit kodlanmış farklı bir alt dizine yayınladı. + +Bunu kullanıcı tarafından yapılandırılabilir bir parametre kullanacak şekilde değiştirelim. +Bunun için tamamen yeni bir parametre oluşturabilirdik, ancak `batch` parametresi tam orada olduğu için onu kullanalım. + +#### 2.1.1. Yapılandırma dosyasında `outputDir` için bir değer ayarlayın + +Nextflow'un çıktıları yayınlamak için kullandığı yol `outputDir` seçeneğiyle kontrol edilir. +Tüm çıktılar için yolu değiştirmek için bu seçenek için `nextflow.config` yapılandırma dosyasında bir değer ayarlayabilirsiniz. + +`nextflow.config` dosyasına aşağıdaki kodu ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="9" hl_lines="10-13" + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="9" + /* + * Pipeline parametreleri + */ + params { + input = 'data/greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Bu, yerleşik varsayılan yol olan `results/`'ı `results/` artı alt dizin olarak `batch` parametresinin değeriyle değiştirecektir. +İsterseniz `results` kısmını da değiştirebilirsiniz. + +Geçici bir değişiklik için, komutunuzda `-output-dir` parametresini kullanarak komut satırından bu seçeneği ayarlayabilirsiniz (ancak bu durumda `batch` parametre değerini kullanamazsınız). + +#### 2.1.2. Sabit kodlanmış yolun tekrarlanan kısmını kaldırın + +Çıktı seçeneklerinde hala sabit kodlanmış bir alt dizinimiz var, bu yüzden şimdi onu kaldıralım. + +Workflow dosyasında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path '3-main/intermediates' + mode 'copy' + } + uppercased { + path '3-main/intermediates' + mode 'copy' + } + collected { + path '3-main/intermediates' + mode 'copy' + } + batch_report { + path '3-main' + mode 'copy' + } + cowpy_art { + path '3-main' + mode 'copy' + } + } + ``` + +`outputDir` varsayılanını değiştirmek yerine her yola `${params.batch}` eklemiş de olabilirdik, ancak bu daha özlüdür. + +#### 2.1.3. Pipeline'ı çalıştırın + +Batch adını komut satırından `outdir` olarak ayarlayarak doğru çalışıp çalışmadığını test edelim. + +```bash +nextflow run 3-main.nf --batch outdir +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [disturbed_einstein] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hala öncekiyle aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/outdir/` altında buluyoruz. + +??? abstract "Dizin içeriği" + + ```console + results/outdir/ + ├── cowpy-COLLECTED-outdir-output.txt + ├── intermediates + │ ├── Bonjour-output.txt + │ ├── COLLECTED-outdir-output.txt + │ ├── Hello-output.txt + │ ├── Holà-output.txt + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + └── outdir-report.txt + ``` + +Bu yaklaşımı özel yol tanımlarıyla birleştirerek istediğiniz herhangi bir dizin hiyerarşisini oluşturabilirsiniz. + +### 2.2. Çıktıları process'e göre organize etme + +Çıktıları daha fazla organize etmenin popüler bir yolu, process'e göre yapmaktır, yani pipeline'da çalıştırılan her process için alt dizinler oluşturmak. + +#### 2.2.1. Çıktı yollarını process adlarına referansla değiştirin + +Tek yapmanız gereken, çıktı yolu bildiriminde process adına `<task>.name` olarak referans vermektir. + +Workflow dosyasında aşağıdaki değişiklikleri yapın: + +=== "Sonra" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +=== "Önce" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path 'intermediates' + mode 'copy' + } + uppercased { + path 'intermediates' + mode 'copy' + } + collected { + path 'intermediates' + mode 'copy' + } + batch_report { + path '' + mode 'copy' + } + cowpy_art { + path '' + mode 'copy' + } + } + ``` + +Bu, çıktı yolu yapılandırmasından kalan sabit kodlanmış öğeleri kaldırır. + +#### 2.2.2. Pipeline'ı çalıştırın + +Batch adını komut satırından `pnames` olarak ayarlayarak doğru çalışıp çalışmadığını test edelim. + +```bash +nextflow run 3-main.nf --batch pnames +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_mcclintock] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hala öncekiyle aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/pnames/` altında buluyoruz ve process'e göre gruplandırılmışlar. + +??? abstract "Dizin içeriği" + + ```console + results/pnames/ + ├── collectGreetings + │ ├── COLLECTED-pnames-output.txt + │ └── pnames-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-pnames-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Burada `intermediates` ile nihai çıktıların üst düzeyde olması arasındaki ayrımı sildiğimizi unutmayın. +Elbette bu yaklaşımları karıştırıp eşleştirebilirsiniz, örneğin ilk çıktının yolunu `intermediates/${sayHello.name}` olarak ayarlayarak. + +### 2.3. Workflow düzeyinde yayınlama modunu ayarlama + +Son olarak, tekrarlayan kod miktarını azaltma ruhuyla, çıktı başına `mode` bildirimlerini yapılandırmada tek bir satırla değiştirebiliriz. + +#### 2.3.1. Yapılandırma dosyasına `workflow.output.mode` ekleyin + +`nextflow.config` dosyasına aşağıdaki kodu ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="2" hl_lines="5" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + workflow.output.mode = 'copy' + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="12" + /* + * Output settings + */ + outputDir = "results/${params.batch}" + ``` + +`outputDir` seçeneği gibi, yapılandırma dosyasında `workflow.output.mode`'a bir değer vermek, workflow dosyasında ayarlanmış olanı geçersiz kılmak için yeterli olurdu, ancak yine de gereksiz kodu kaldıralım. + +#### 2.3.2. Workflow dosyasından çıktı modunu kaldırın + +Workflow dosyasında aşağıdaki değişiklikleri yapın: + +=== "Sonra" + + ```groovy title="3-main.nf" linenums="42" + output { + first_output { + path { sayHello.name } + } + uppercased { + path { convertToUpper.name } + } + collected { + path { collectGreetings.name } + } + batch_report { + path { collectGreetings.name } + } + cowpy_art { + path { cowpy.name } + } + } + ``` + +=== "Önce" + + ```groovy title="3-main.nf" linenums="42" hl_lines="3 7 11 15 19" + output { + first_output { + path { sayHello.name } + mode 'copy' + } + uppercased { + path { convertToUpper.name } + mode 'copy' + } + collected { + path { collectGreetings.name } + mode 'copy' + } + batch_report { + path { collectGreetings.name } + mode 'copy' + } + cowpy_art { + path { cowpy.name } + mode 'copy' + } + } + ``` + +Bu daha özlü, değil mi? + +#### 2.3.3. Pipeline'ı çalıştırın + +Batch adını komut satırından `outmode` olarak ayarlayarak doğru çalışıp çalışmadığını test edelim. + +```bash +nextflow run 3-main.nf --batch outmode +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [rowdy_sagan] DSL2 - revision: ede9037d02 + + executor > local (8) + [f0/35723c] sayHello (2) | 3 of 3 ✔ + [40/3efd1a] convertToUpper (3) | 3 of 3 ✔ + [17/e97d32] collectGreetings | 1 of 1 ✔ + [98/c6b57b] cowpy | 1 of 1 ✔ + ``` + +Bu hala öncekiyle aynı çıktıyı üretiyor, ancak bu sefer çıktılarımızı `results/outmode/` altında buluyoruz. +Hala hepsi düzgün kopyalar, symlink değil. + +??? abstract "Dizin içeriği" + + ```console + results/outmode/ + ├── collectGreetings + │ ├── COLLECTED-outmode-output.txt + │ └── outmode-report.txt + ├── convertToUpper + │ ├── UPPER-Bonjour-output.txt + │ ├── UPPER-Hello-output.txt + │ └── UPPER-Holà-output.txt + ├── cowpy + │ └── cowpy-COLLECTED-outmode-output.txt + └── sayHello + ├── Bonjour-output.txt + ├── Hello-output.txt + └── Holà-output.txt + ``` + +Çıktı başına mod ayarlama yolunu hala kullanmak istemenizin ana nedeni, aynı workflow içinde karıştırıp eşleştirmek istemeniz durumudur, yani bazı çıktıların kopyalanmasını ve bazılarının symlink olmasını isterseniz. + +Bu şekilde özelleştirebileceğiniz birçok başka seçenek var, ancak umarız bu size seçeneklerin kapsamı ve bunları tercihlerinize uygun şekilde etkili bir şekilde nasıl kullanacağınız hakkında bir fikir verir. + +### Özet + +Çıktılarınızın yayınlandığı dizinlerin adlandırmasını ve yapısını ve workflow çıktı yayınlama modunu nasıl kontrol edeceğinizi biliyorsunuz. + +### Sırada ne var? + +Yazılım paketleme teknolojisiyle başlayarak workflow yapılandırmanızı hesaplama ortamınıza nasıl uyarlayacağınızı öğrenin. + +--- + +## 3. Yazılım paketleme teknolojisi seçme + +Şu ana kadar girdilerin nasıl girdiğini ve çıktıların nereden çıktığını kontrol eden yapılandırma öğelerine baktık. Şimdi workflow yapılandırmanızı hesaplama ortamınıza uyarlamaya daha özel olarak odaklanma zamanı. + +Bu yoldaki ilk adım, her adımda çalıştırılacak yazılım paketlerinin nereden geleceğini belirlemektir. +Zaten yerel hesaplama ortamında yüklü mü? +İmajları alıp bir konteyner sistemi aracılığıyla çalıştırmamız mı gerekiyor? +Yoksa Conda paketlerini alıp yerel bir Conda ortamı mı oluşturmamız gerekiyor? + +Bu eğitim kursunun ilk bölümünde (Bölümler 1-4) workflow'umuzda yalnızca yerel olarak yüklenmiş yazılımları kullandık. +Ardından Bölüm 5'te Docker konteynerlarını ve Docker konteynerların kullanımını etkinleştirmek için kullandığımız `nextflow.config` dosyasını tanıttık. + +Şimdi `nextflow.config` dosyası aracılığıyla alternatif bir yazılım paketleme seçeneğini nasıl yapılandırabileceğimizi görelim. + +### 3.1. Docker'ı devre dışı bırakın ve yapılandırma dosyasında Conda'yı etkinleştirin + +??? example "Senaryo" + + Pipeline'ınızı güvenlik nedenleriyle Docker'ın izin verilmediği bir HPC kümesine taşıyorsunuz. + Küme Singularity ve Conda'yı destekliyor, bu yüzden yapılandırmanızı buna göre değiştirmeniz gerekiyor. + +Nextflow, HPC'de daha yaygın olarak kullanılan Singularity ve Conda gibi yazılım paket yöneticileri dahil birden fazla konteyner teknolojisini destekler. + +Yapılandırma dosyamızı Docker yerine Conda kullanacak şekilde değiştirebiliriz. +Bunu yapmak için `docker.enabled` değerini `false` olarak değiştirelim ve Conda kullanımını etkinleştiren bir direktif ekleyelim: + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1-2" + docker.enabled = false + conda.enabled = true + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="1" hl_lines="1" + docker.enabled = true + ``` + +Bu, Nextflow'un Conda paketleri belirtilmiş process'ler için Conda ortamları oluşturmasına ve kullanmasına izin verecektir. +Bu da artık `cowpy` process'imize bunlardan birini eklememiz gerektiği anlamına gelir! + +### 3.2. Process tanımında bir Conda paketi belirtin + +`cowpy` aracını içeren bir Conda paketi için URI'yi zaten aldık: `conda-forge::cowpy==1.1.5` + +Şimdi `conda` direktifini kullanarak URI'yi `cowpy` process tanımına ekliyoruz: + +=== "Sonra" + + ```groovy title="modules/cowpy.nf" linenums="4" hl_lines="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + conda 'conda-forge::cowpy==1.1.5' + + input: + ``` + +=== "Önce" + + ```groovy title="modules/cowpy.nf" linenums="4" + process cowpy { + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + ``` + +Açık olmak gerekirse, `docker` direktifini _değiştirmiyoruz_, alternatif bir seçenek _ekliyoruz_. + +!!! tip "İpucu" + + Belirli bir conda paketi için URI almanın birkaç farklı yolu vardır. + [Seqera Containers](https://seqera.io/containers/) arama sorgusunu kullanmanızı öneririz; bu size kopyalayıp yapıştırabileceğiniz bir URI verecektir, ondan bir konteyner oluşturmayı planlamasanız bile. + +### 3.3. Conda'yı kullanabildiğini doğrulamak için workflow'u çalıştırın + +Deneyelim. + +```bash +nextflow run 3-main.nf --batch conda +``` + +??? success "Komut çıktısı" + + ```console title="Çıktı" + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [trusting_lovelace] DSL2 - revision: 028a841db1 + + executor > local (8) + [ee/4ca1f2] sayHello (3) | 3 of 3 ✔ + [20/2596a7] convertToUpper (1) | 3 of 3 ✔ + [b3/e15de5] collectGreetings | 1 of 1 ✔ + [c5/af5f88] cowpy | 1 of 1 ✔ + ``` + +Bu sorunsuz çalışmalı ve `results/conda` altında öncekiyle aynı çıktıları üretmelidir. + +Arka planda, Nextflow Conda paketlerini aldı ve ortamı oluşturdu, bu normalde biraz iş gerektirir; bu yüzden bunların hiçbirini kendimiz yapmak zorunda kalmamamız güzel! + +!!! info "Bilgi" + + Bu hızlı çalışır çünkü `cowpy` paketi oldukça küçüktür, ancak büyük paketlerle çalışıyorsanız, ilk seferinde normalden biraz daha uzun sürebilir ve tamamlanmadan önce konsol çıktısının bir dakika kadar 'takılı' kaldığını görebilirsiniz. + Bu normaldir ve Nextflow'un yeni bir paket kullandığınızda ilk seferinde yaptığı ekstra işten kaynaklanır. + +Bizim bakış açımızdan, arka planda mekanikler biraz farklı olsa bile, Docker ile çalıştırmakla tamamen aynı görünüyor. + +Bu, gerekirse Conda ortamlarıyla çalıştırmaya hazır olduğumuz anlamına gelir. + +??? info "Docker ve Conda'yı karıştırma ve eşleştirme" + + Bu direktifler process başına atandığından, 'karıştırıp eşleştirmek' mümkündür, yani örneğin kullandığınız hesaplama altyapısı her ikisini de destekliyorsa, workflow'unuzdaki bazı process'leri Docker ile ve diğerlerini Conda ile çalışacak şekilde yapılandırmak mümkündür. + Bu durumda, yapılandırma dosyanızda hem Docker'ı hem de Conda'yı etkinleştirirsiniz. + Belirli bir process için her ikisi de mevcutsa, Nextflow konteynerleri önceliklendirecektir. + + Ve daha önce belirtildiği gibi, Nextflow birden fazla başka yazılım paketleme ve konteyner teknolojisini destekler, bu yüzden sadece bu ikisiyle sınırlı değilsiniz. + +### Özet + +Her process'in hangi yazılım paketini kullanması gerektiğini nasıl yapılandıracağınızı ve teknolojiler arasında nasıl geçiş yapacağınızı biliyorsunuz. + +### Sırada ne var? + +Nextflow'un işi gerçekten yapmak için kullandığı çalıştırma platformunu nasıl değiştireceğinizi öğrenin. + +--- + +## 4. Çalıştırma platformu seçme + +??? example "Senaryo" + + Pipeline'ınızı dizüstü bilgisayarınızda geliştiriyordunuz ve test ediyordunuz, ancak şimdi binlerce örnek üzerinde çalıştırmanız gerekiyor. + Kurumunuzun bunun yerine kullanmak istediğiniz Slurm scheduler'lı bir HPC kümesi var. + +Şu ana kadar pipeline'ımızı yerel executor ile çalıştırıyorduk. +Bu, her görevi Nextflow'un çalıştığı makinede yürütür. +Nextflow başladığında, mevcut CPU'lara ve belleğe bakar. +Çalıştırılmaya hazır görevlerin kaynakları mevcut kaynakları aşarsa, Nextflow önceki görevlerden bir veya daha fazlası tamamlanıp gerekli kaynakları serbest bırakana kadar son görevleri çalıştırmaktan geri tutar. + +Yerel executor uygun ve verimlidir, ancak tek bir makineyle sınırlıdır. Çok büyük iş yükleri için, yerel makinenizin bir darboğaz olduğunu keşfedebilirsiniz; ya mevcut kaynaklardan daha fazlasını gerektiren tek bir göreviniz var ya da tek bir makinenin onları çalıştırmasını beklemenin çok uzun süreceği kadar çok göreviniz var. + +Nextflow, HPC scheduler'ları (Slurm, LSF, SGE, PBS, Moab, OAR, Bridge, HTCondor ve diğerleri) ve bulut çalıştırma backend'leri (AWS Batch, Google Cloud Batch, Azure Batch, Kubernetes ve daha fazlası) dahil [birçok farklı çalıştırma backend'ini](https://www.nextflow.io/docs/latest/executor.html) destekler. + +### 4.1. Farklı bir backend'i hedefleme + +Executor seçimi `executor` adlı bir process direktifi ile ayarlanır. +Varsayılan olarak `local` olarak ayarlanmıştır, bu yüzden aşağıdaki yapılandırma ima edilir: + +```groovy title="Yerleşik yapılandırma" +process { + executor = 'local' +} +``` + +Executor'ı farklı bir backend'i hedefleyecek şekilde ayarlamak için, kaynak tahsisleri için yukarıda açıklanan benzer sözdizimini kullanarak istediğiniz executor'ı belirtmeniz yeterlidir (tüm seçenekler için [belgelere](https://www.nextflow.io/docs/latest/executor.html) bakın). + +```groovy title="nextflow.config" +process { + executor = 'slurm' +} +``` + +!!! warning "Uyarı" + + Bunu eğitim ortamında gerçekten test edemiyoruz çünkü bir HPC'ye bağlanacak şekilde ayarlanmamış. + +### 4.2. Çalıştırma parametreleri için backend'e özgü sözdizimi ile başa çıkma + +Çoğu yüksek performanslı hesaplama platformu, kaynak tahsis istekleri ve sınırlamaları (örn. CPU sayısı ve bellek) ve kullanılacak iş kuyruğunun adı gibi belirli parametreleri belirtmenize izin verir (ve bazen gerektirir). + +Ne yazık ki, bu sistemlerin her biri, bir işin nasıl tanımlanması ve ilgili scheduler'a nasıl gönderilmesi gerektiğini tanımlamak için farklı teknolojiler, sözdizimler ve yapılandırmalar kullanır. + +??? abstract "Örnekler" + + Örneğin, 8 CPU ve 4GB RAM gerektiren ve "my-science-work" kuyruğunda çalıştırılacak aynı iş, backend'e bağlı olarak farklı şekillerde ifade edilmelidir. + + ```bash title="SLURM için yapılandırma / sbatch ile gönder" + #SBATCH -o /path/to/my/task/directory/my-task-1.log + #SBATCH --no-requeue + #SBATCH -c 8 + #SBATCH --mem 4096M + #SBATCH -p my-science-work + ``` + + ```bash title="PBS için yapılandırma / qsub ile gönder" + #PBS -o /path/to/my/task/directory/my-task-1.log + #PBS -j oe + #PBS -q my-science-work + #PBS -l nodes=1:ppn=5 + #PBS -l mem=4gb + ``` + + ```bash title="SGE için yapılandırma / qsub ile gönder" + #$ -o /path/to/my/task/directory/my-task-1.log + #$ -j y + #$ -terse + #$ -notify + #$ -q my-science-work + #$ -l slots=5 + #$ -l h_rss=4096M,mem_free=4096M + ``` + +Neyse ki, Nextflow tüm bunları basitleştirir. +İlgili özellikleri, `cpus`, `memory` ve `queue` gibi (diğer özellikler için belgelere bakın) yalnızca bir kez belirtebilmeniz için standartlaştırılmış bir sözdizimi sağlar. +Ardından, çalışma zamanında, Nextflow executor ayarına göre uygun backend'e özgü betikleri oluşturmak için bu ayarları kullanacaktır. + +Bu standartlaştırılmış sözdizimini bir sonraki bölümde ele alacağız. + +### Özet + +Artık farklı türde hesaplama altyapısı kullanmak için executor'ı nasıl değiştireceğinizi biliyorsunuz. + +### Sırada ne var? + +Nextflow'da kaynak tahsislerini ve sınırlamalarını değerlendirmeyi ve ifade etmeyi öğrenin. + +--- + +## 5. Hesaplama kaynak tahsislerini kontrol etme + +??? example "Senaryo" + + Pipeline'ınız kümede sürekli başarısız oluyor çünkü görevler bellek sınırlarını aştığı için sonlandırılıyor. + Ya da belki kullanmadığınız kaynaklar için ücretlendiriliyorsunuz ve maliyetleri optimize etmek istiyorsunuz. + +Çoğu yüksek performanslı hesaplama platformu, CPU sayısı ve bellek gibi belirli kaynak tahsis parametrelerini belirtmenize izin verir (ve bazen gerektirir). + +Varsayılan olarak, Nextflow her process için tek bir CPU ve 2GB bellek kullanacaktır. +İlgili process direktifleri `cpus` ve `memory` olarak adlandırılır, bu yüzden aşağıdaki yapılandırma ima edilir: + +```groovy title="Yerleşik yapılandırma" linenums="1" +process { + cpus = 1 + memory = 2.GB +} +``` + +Bu değerleri, yapılandırma dosyanızda ek process direktifleri kullanarak tüm process'ler veya belirli adlandırılmış process'ler için değiştirebilirsiniz. +Nextflow bunları seçilen executor için uygun talimatlara çevirecektir. + +Peki hangi değerleri kullanacağınızı nasıl biliyorsunuz? + +### 5.1. Kaynak kullanım raporu oluşturmak için workflow'u çalıştırın + +??? example "Senaryo" + + Process'lerinizin ne kadar bellek veya CPU'ya ihtiyaç duyduğunu bilmiyorsunuz ve kaynakları israf etmekten veya işlerin sonlandırılmasından kaçınmak istiyorsunuz. + +Process'lerinizin ne kadar CPU ve belleğe ihtiyaç duyacağını önceden bilmiyorsanız, biraz kaynak profilleme yapabilirsiniz; yani workflow'u bazı varsayılan tahsislerle çalıştırırsınız, her process'in ne kadar kullandığını kaydedersiniz ve oradan temel tahsisleri nasıl ayarlayacağınızı tahmin edersiniz. + +Uygun bir şekilde, Nextflow bunu yapmak için yerleşik araçlar içerir ve istek üzerine sizin için bir rapor oluşturmaktan mutluluk duyar. + +Bunu yapmak için, komut satırınıza `-with-report <filename>.html` ekleyin. + +```bash +nextflow run 3-main.nf -with-report report-config-1.html +``` + +Rapor, tarayıcınızda indirebileceğiniz ve açabileceğiniz bir html dosyasıdır. Ayrıca eğitim ortamında görüntülemek için soldaki dosya gezgininde sağ tıklayıp `Show preview`'a tıklayabilirsiniz. + +Kaynakları ayarlama fırsatlarını tanımlayıp tanımlayamayacağınızı görmek için rapora bakıp birkaç dakikanızı ayırın. +Kullanım sonuçlarını tahsis edilenin yüzdesi olarak gösteren sekmelere tıkladığınızdan emin olun. +Mevcut tüm özellikleri açıklayan bazı [belgeler](https://www.nextflow.io/docs/latest/reports.html) var. + +### 5.2. Tüm process'ler için kaynak tahsislerini ayarlama + +Profilleme, eğitim workflow'umuzdaki process'lerin çok hafif olduğunu gösteriyor, bu yüzden process başına varsayılan bellek tahsisini 1GB'a düşürelim. + +`nextflow.config` dosyanıza, pipeline parametreleri bölümünden önce aşağıdakini ekleyin: + +```groovy title="nextflow.config" linenums="4" +/* +* Process settings +*/ +process { + memory = 1.GB +} +``` + +Bu, tükettiğimiz hesaplama miktarını azaltmaya yardımcı olacaktır. + +### 5.3. Belirli bir process için kaynak tahsislerini ayarlama + +Aynı zamanda, tek bir process için tahsislerin nasıl ayarlanacağını gösterebilmemiz için `cowpy` process'inin diğerlerinden daha fazla kaynak gerektirdiğini varsayacağız. + +=== "Sonra" + + ```groovy title="nextflow.config" linenums="4" hl_lines="6-9" + /* + * Process settings + */ + process { + memory = 1.GB + withName: 'cowpy' { + memory = 2.GB + cpus = 2 + } + } + ``` + +=== "Önce" + + ```groovy title="nextflow.config" linenums="4" + /* + * Process settings + */ + process { + memory = 1.GB + } + ``` + +Bu yapılandırmayla, `cowpy` process'i hariç tüm process'ler 1GB bellek ve tek bir CPU (ima edilen varsayılan) isteyecektir; `cowpy` process'i 2GB ve 2 CPU isteyecektir. + +!!! info "Bilgi" + + Birkaç CPU'ya sahip bir makineniz varsa ve process başına yüksek sayıda tahsis ederseniz, process çağrılarının birbiri ardına kuyruğa alındığını görebilirsiniz. + Bunun nedeni, Nextflow'un mevcut olandan daha fazla CPU istememizi sağlamasıdır. + +### 5.4. Güncellenmiş yapılandırmayla workflow'u çalıştırın + +Bunu deneyelim, yapılandırma değişikliklerinden önce ve sonra performansı karşılaştırabilmemiz için profilleme raporu için farklı bir dosya adı sağlayalım. + +```bash +nextflow run 3-main.nf -with-report report-config-2.html +``` + +Bu kadar küçük bir iş yükü olduğu için muhtemelen gerçek bir fark fark etmeyeceksiniz, ancak gerçek dünya workflow'unun performansını ve kaynak gereksinimlerini analiz etmek için kullanacağınız yaklaşım budur. + +Process'leriniz farklı kaynak gereksinimlerine sahip olduğunda çok yararlıdır. Tahmin değil, gerçek verilere dayalı olarak her process için ayarladığınız kaynak tahsislerini doğru boyutlandırmanızı sağlar. + +!!! tip "İpucu" + + Bu, kaynakları optimize etmek için yapabileceğiniz şeylerin sadece küçük bir tadımlığı. + Nextflow'un kendisi, kaynak sınırlamaları nedeniyle başarısız olan işleri yeniden denemek için gerçekten şık bir [dinamik yeniden deneme mantığı](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) yerleşik olarak içerir. + Ayrıca, Seqera Platform kaynak tahsislerinizi otomatik olarak optimize etmek için AI odaklı araçlar da sunmaktadır. + +### 5.5. Kaynak sınırları ekleme + +Hangi hesaplama executor'ını ve hesaplama altyapısını kullandığınıza bağlı olarak, tahsis edebileceğiniz (veya etmeniz gereken) konusunda bazı kısıtlamalar olabilir. +Örneğin, kümeniz belirli sınırlar içinde kalmanızı gerektirebilir. + +İlgili sınırlamaları ayarlamak için `resourceLimits` direktifini kullanabilirsiniz. Sözdizimi, tek başına bir process bloğunda olduğunda şöyle görünür: + +```groovy title="Sözdizimi örneği" +process { + resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] +} +``` + +Nextflow bu değerleri belirttiğiniz executor'a bağlı olarak uygun talimatlara çevirecektir. + +Bunu çalıştırmayacağız, çünkü eğitim ortamında ilgili altyapıya erişimimiz yok. +Ancak, bu sınırları aşan kaynak tahsisleriyle workflow'u çalıştırmaya çalışsaydınız, ardından `.command.run` betik dosyasındaki `sbatch` komutuna baksaydınız, executor'a gerçekten gönderilen isteklerin `resourceLimits` tarafından belirtilen değerlerle sınırlandırıldığını görürdünüz. + +??? info "Kurumsal referans yapılandırmaları" + + nf-core projesi, çok çeşitli HPC ve bulut executor'larını kapsayan, dünya genelindeki çeşitli kurumlar tarafından paylaşılan bir [yapılandırma dosyaları koleksiyonu](https://nf-co.re/configs/) derlemiştir. + + Bu paylaşılan yapılandırmalar hem orada çalışan ve bu nedenle kurumlarının yapılandırmasını hazır olarak kullanabilen insanlar için hem de kendi altyapıları için bir yapılandırma geliştirmek isteyen insanlar için bir model olarak değerlidir. + +### Özet + +Kaynak kullanımını değerlendirmek için bir profilleme raporu oluşturmayı ve tüm process'ler ve/veya bireysel process'ler için kaynak tahsislerini nasıl değiştireceğinizi ve HPC'de çalıştırmak için kaynak sınırlamalarını nasıl ayarlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Önceden ayarlanmış yapılandırma profillerini nasıl kuracağınızı ve çalışma zamanında bunlar arasında nasıl geçiş yapacağınızı öğrenin. + +--- + +## 6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın + +??? example "Senaryo" + + Geliştirme için dizüstü bilgisayarınızda ve üretim çalıştırmaları için kurumunuzun HPC'sinde pipeline'ları çalıştırmak arasında düzenli olarak geçiş yapıyorsunuz. + Her ortam değiştirdiğinizde yapılandırma ayarlarını manuel olarak değiştirmekten yoruldunuz. + +Size pipeline yapılandırmanızı üzerinde çalıştığınız projeye veya kullandığınız hesaplama ortamına bağlı olarak özelleştirebileceğiniz birkaç yol gösterdik. + +Hangi hesaplama altyapısını kullandığınıza bağlı olarak alternatif ayarlar arasında geçiş yapmak isteyebilirsiniz. Örneğin, dizüstü bilgisayarınızda küçük ölçekli testler geliştirmek ve yerel olarak çalıştırmak, ardından HPC veya bulutta tam ölçekli iş yükleri çalıştırmak isteyebilirsiniz. + +Nextflow, farklı yapılandırmaları tanımlayan istediğiniz sayıda profil kurmanıza olanak tanır; bunları daha sonra yapılandırma dosyasını değiştirmek yerine bir komut satırı argümanı kullanarak çalışma zamanında seçebilirsiniz. + +### 6.1. Yerel geliştirme ve HPC'de çalıştırma arasında geçiş yapmak için profiller oluşturun + +İki alternatif profil kuralım; biri Docker konteynerları kullanacağımız normal bir bilgisayarda küçük ölçekli yükler çalıştırmak için, biri de Conda paketleri kullanacağımız Slurm scheduler'lı bir üniversite HPC'sinde çalıştırmak için. + +#### 6.1.1. Profilleri kurun + +`nextflow.config` dosyanıza, pipeline parametreleri bölümünden sonra ancak çıktı ayarlarından önce aşağıdakini ekleyin: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } +} +``` + +Üniversite HPC için ayrıca kaynak sınırlamalarını da belirttiğimizi görüyorsunuz. + +#### 6.1.2. Workflow'u bir profille çalıştırın + +Nextflow komut satırımızda bir profil belirtmek için `-profile` argümanını kullanıyoruz. + +Workflow'u `my_laptop` yapılandırmasıyla çalıştırmayı deneyelim. + +```bash +nextflow run 3-main.nf -profile my_laptop +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [gigantic_brazil] DSL2 - revision: ede9037d02 + + executor > local (8) + [58/da9437] sayHello (3) | 3 of 3 ✔ + [35/9cbe77] convertToUpper (2) | 3 of 3 ✔ + [67/857d05] collectGreetings | 1 of 1 ✔ + [37/7b51b5] cowpy | 1 of 1 ✔ + ``` + +Gördüğünüz gibi, bu bize çalışma zamanında yapılandırmalar arasında çok rahatça geçiş yapma imkanı veriyor. + +!!! warning "Uyarı" + + `univ_hpc` profili, bir Slurm scheduler'a erişimimiz olmadığı için eğitim ortamında düzgün çalışmayacaktır. + +Gelecekte bunlarla her zaman birlikte oluşan başka yapılandırma öğeleri bulursak, bunları ilgili profil(ler)e ekleyebiliriz. +Ayrıca birlikte gruplamak istediğimiz başka yapılandırma öğeleri varsa ek profiller oluşturabiliriz. + +### 6.2. Test parametreleri profili oluşturun + +??? example "Senaryo" + + Başkalarının kendi girdi verilerini toplamadan pipeline'ınızı hızlıca denemesini istiyorsunuz. + +Profiller yalnızca altyapı yapılandırması için değildir. +Başkalarının uygun girdi değerlerini kendileri toplamak zorunda kalmadan workflow'u denemelerini kolaylaştırmak için workflow parametreleri için varsayılan değerler ayarlamak için de kullanabiliriz. +Bunu bir parametre dosyası kullanmaya alternatif olarak düşünebilirsiniz. + +#### 6.2.1. Profili kurun + +Bu bağlamda varsayılan değerleri ifade etmek için sözdizimi, `test` olarak adlandırdığımız bir profil için şöyle görünür: + +```groovy title="Sözdizimi örneği" + test { + params.<parameter1> + params.<parameter2> + ... + } +``` + +Workflow'umuz için bir test profili eklersek, `profiles` bloğu şöyle olur: + +```groovy title="nextflow.config" linenums="24" +/* +* Profiles +*/ +profiles { + my_laptop { + process.executor = 'local' + docker.enabled = true + } + univ_hpc { + process.executor = 'slurm' + conda.enabled = true + process.resourceLimits = [ + memory: 750.GB, + cpus: 200, + time: 30.d + ] + } + test { + params.input = 'data/greetings.csv' + params.batch = 'test' + params.character = 'dragonandcow' + } +} +``` + +Teknik yapılandırma profilleri için olduğu gibi, istediğiniz herhangi bir ad altında parametreleri belirten birden fazla farklı profil kurabilirsiniz. + +#### 6.2.2. Workflow'u yerel olarak test profiliyle çalıştırın + +Uygun bir şekilde, profiller karşılıklı olarak dışlayıcı değildir, bu yüzden komut satırımızda `-profile <profile1>,<profile2>` sözdizimini kullanarak birden fazla profil belirtebiliriz (herhangi bir sayıda profil için). + +Aynı yapılandırma öğeleri için değerler ayarlayan ve aynı yapılandırma dosyasında tanımlanan profilleri birleştirirseniz, Nextflow hangi değeri en son okuduğunu kullanarak çakışmayı çözecektir (yani dosyada daha sonra gelen). +Çakışan ayarlar farklı yapılandırma kaynaklarında ayarlanmışsa, varsayılan [öncelik sırası](https://www.nextflow.io/docs/latest/config.html) geçerlidir. + +Önceki komutumza test profilini eklemeyi deneyelim: + +```bash +nextflow run 3-main.nf -profile my_laptop,test +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `3-main.nf` [jovial_coulomb] DSL2 - revision: 46a6763141 + + executor > local (8) + [9b/687cdc] sayHello (2) | 3 of 3 ✔ + [ca/552187] convertToUpper (3) | 3 of 3 ✔ + [e8/83e306] collectGreetings | 1 of 1 ✔ + [fd/e84fa9] cowpy | 1 of 1 ✔ + ``` + +Bu, mümkün olduğunda Docker kullanacak ve `results/test` altında çıktılar üretecek ve bu sefer karakter komik ikili `dragonandcow`. + +??? abstract "Dosya içeriği" + + ```console title="results/test/" + _________ + / HOLà \ + | HELLO | + \ BONJOUR / + --------- + \ ^ /^ + \ / \ // \ + \ |\___/| / \// .\ + \ /O O \__ / // | \ \ *----* + / / \/_/ // | \ \ \ | + \@___\@` \/_ // | \ \ \/\ \ + 0/0/| \/_ // | \ \ \ \ + 0/0/0/0/| \/// | \ \ | | + 0/0/0/0/0/_|_ / ( // | \ _\ | / + 0/0/0/0/0/0/`/,_ _ _/ ) ; -. | _ _\.-~ / / + ,-} _ *-.|.-~-. .~ ~ + \ \__/ `/\ / ~-. _ .-~ / + \____(oo) *. } { / + ( (--) .----~-.\ \-` .~ + //__\\ \__ Ack! ///.----..< \ _ -~ + // \\ ///-._ _ _ _ _ _ _{^ - - - - ~ + ``` + +Bu, herhangi bir test veri dosyasını workflow koduyla birlikte dağıttığımız sürece, herkesin komut satırı veya parametre dosyası aracılığıyla kendi girdilerini sağlamak zorunda kalmadan workflow'u hızlıca deneyebileceği anlamına gelir. + +!!! tip "İpucu" + + Harici olarak depolanan daha büyük dosyalar için URL'lere işaret edebiliriz. + Nextflow, açık bir bağlantı olduğu sürece bunları otomatik olarak indirecektir. + + Daha fazla ayrıntı için [Working with Files](../side_quests/working_with_files.md) Yan Görevine bakın. + +### 6.3. Çözülmüş yapılandırmayı görmek için `nextflow config` kullanın + +Yukarıda belirtildiği gibi, bazen aynı parametre birleştirmek istediğiniz profillerde farklı değerlere ayarlanabilir. +Ve daha genel olarak, yapılandırma öğelerinin saklanabileceği çok sayıda yer vardır ve bazen aynı özellikler farklı yerlerde farklı değerlere ayarlanabilir. + +Nextflow, herhangi bir çakışmayı çözmek için belirli bir [öncelik sırası](https://www.nextflow.io/docs/latest/config.html) uygular, ancak bunu kendiniz belirlemeniz zor olabilir. +Ve hiçbir şey çakışmasa bile, şeylerin yapılandırılabileceği tüm olası yerlere bakmak sıkıcı olabilir. + +Neyse ki, Nextflow bu süreci sizin için otomatikleştirebilen `config` adlı uygun bir yardımcı araç içerir. + +`config` aracı, mevcut çalışma dizininizdeki tüm içeriği keşfedecek, tüm yapılandırma dosyalarını toplayacak ve Nextflow'un workflow'u çalıştırmak için kullanacağı tamamen çözülmüş yapılandırmayı üretecektir. +Bu, herhangi bir şey başlatmak zorunda kalmadan hangi ayarların kullanılacağını öğrenmenizi sağlar. + +#### 6.3.1. Varsayılan yapılandırmayı çözün + +Varsayılan olarak uygulanacak yapılandırmayı çözmek için bu komutu çalıştırın. + +```bash +nextflow config +``` + +??? success "Komut çıktısı" + + ```groovy + docker { + enabled = false + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + } + + params { + input = 'greetings.csv' + batch = 'batch' + character = 'turkey' + } + ``` + +Bu, komut satırında ekstra bir şey belirtmezseniz elde ettiğiniz temel yapılandırmayı gösterir. + +#### 6.3.2. Belirli ayarlar etkinleştirilmiş yapılandırmayı çözün + +Komut satırı parametreleri sağlarsanız, örneğin bir veya daha fazla profil etkinleştirmek veya bir parametre dosyası yüklemek, komut bunları da dikkate alacaktır. + +```bash +nextflow config -profile my_laptop,test +``` + +??? success "Komut çıktısı" + + ```groovy + docker { + enabled = true + } + + conda { + enabled = true + } + + process { + memory = '1 GB' + withName:cowpy { + memory = '2 GB' + cpus = 2 + } + executor = 'local' + } + + params { + input = 'greetings.csv' + batch = 'test' + character = 'dragonandcow' + } + ``` + +Bu, birden fazla yapılandırma katmanı içeren karmaşık projeler için özellikle yararlı olur. + +### Özet + +Çalışma zamanında minimum güçlükle önceden ayarlanmış bir yapılandırmayı seçmek için profilleri nasıl kullanacağınızı biliyorsunuz. +Daha genel olarak, workflow çalıştırmalarınızı farklı hesaplama platformlarına uyacak şekilde ve analizlerinizin tekrar üretilebilirliğini artırmak için nasıl yapılandıracağınızı biliyorsunuz. + +### Sırada ne var? + +Pipeline'ları doğrudan GitHub gibi uzak havuzlardan nasıl çalıştıracağınızı öğrenin. + +--- + +## 7. Uzak havuzlardan pipeline'ları çalıştırma + +??? example "Senaryo" + + nf-core'dan olanlar gibi köklü bir pipeline'ı kodu kendiniz indirmeden ve yönetmeden çalıştırmak istiyorsunuz. + +Şu ana kadar mevcut dizinde bulunan workflow betiklerini çalıştırıyorduk. +Pratikte, genellikle GitHub gibi uzak havuzlarda depolanan pipeline'ları çalıştırmak isteyeceksiniz. + +Nextflow bunu kolaylaştırır: herhangi bir pipeline'ı önce manuel olarak indirmeden doğrudan bir Git havuzu URL'sinden çalıştırabilirsiniz. + +### 7.1. GitHub'dan bir pipeline çalıştırma + +Uzak bir pipeline çalıştırmak için temel sözdizimi `nextflow run <repository>`'dir; burada `<repository>` `nextflow-io/hello` gibi bir GitHub havuz yolu, tam bir URL veya GitLab, Bitbucket veya diğer Git barındırma hizmetlerine giden bir yol olabilir. + +Resmi Nextflow "hello" demo pipeline'ını çalıştırmayı deneyin: + +```bash +nextflow run nextflow-io/hello +``` + +Uzak bir pipeline'ı ilk kez çalıştırdığınızda, Nextflow onu indirir ve yerel olarak önbelleğe alır. +Sonraki çalıştırmalar, açıkça bir güncelleme istemediğiniz sürece önbelleğe alınmış versiyonu kullanır. + +### 7.2. Tekrar üretilebilirlik için versiyon belirtin + +Varsayılan olarak, Nextflow varsayılan daldan en son versiyonu çalıştırır. +`-r` bayrağını kullanarak belirli bir versiyon, dal veya commit belirtebilirsiniz: + +```bash +nextflow run nextflow-io/hello -r v1.1 +``` + +Tam versiyonları belirtmek tekrar üretilebilirlik için önemlidir. + +### Özet + +Pipeline'ları doğrudan GitHub ve diğer uzak havuzlardan nasıl çalıştıracağınızı ve tekrar üretilebilirlik için versiyonları nasıl belirteceğinizi biliyorsunuz. + +### Sırada ne var? + +Kendinize büyük bir tebrik verin! +Nextflow pipeline'larını çalıştırmaya ve yönetmeye başlamak için bilmeniz gereken her şeyi biliyorsunuz. + +Bu, bu kursu sonlandırıyor, ancak öğrenmeye devam etmek istiyorsanız, iki ana önerimiz var: + +- Kendi pipeline'larınızı geliştirmeyi daha derinlemesine incelemek istiyorsanız, bu kursla aynı genel ilerlemeyi kapsayan ancak channel'lar ve operatörler hakkında çok daha ayrıntılı giden yeni başlayanlar için bir kurs olan [Hello Nextflow](../hello_nextflow/index.md)'a bakın. +- Koda daha derinlemesine girmeden Nextflow pipeline'larını çalıştırmayı öğrenmeye devam etmek istiyorsanız, son derece popüler [nf-core](https://nf-co.re/) projesinden pipeline'ları bulmak ve çalıştırmak için araçları tanıtan [Hello nf-core](../hello_nf-core/index.md)'un ilk bölümüne bakın. + +İyi eğlenceler! + +--- + +## Quiz + +<quiz> +Parametre değerleri hem workflow dosyasında hem de `nextflow.config`'de ayarlandığında, hangisi önceliklidir? +- [ ] Workflow dosyası değeri +- [x] Yapılandırma dosyası değeri +- [ ] Karşılaşılan ilk değer +- [ ] Bir hataya neden olur + +Daha fazla bilgi: [1.1. `nextflow.config`'de değerler ayarlayın](#11-nextflowconfigde-degerler-ayarlayin) +</quiz> + +<quiz> +Workflow dosyasında vs. yapılandırma dosyasında varsayılan parametre ayarlama arasındaki sözdizimi farkı nedir? +- [ ] Aynı sözdizimini kullanırlar +- [x] Workflow türlenmiş bildirim kullanır (`#!groovy param: Type = value`), yapılandırma atama kullanır (`#!groovy param = value`) +- [ ] Yapılandırma türlenmiş bildirim kullanır, workflow atama kullanır +- [ ] Yalnızca yapılandırma dosyaları varsayılan değerler ayarlayabilir + +Daha fazla bilgi: [1.1. `nextflow.config`'de değerler ayarlayın](#11-nextflowconfigde-degerler-ayarlayin) +</quiz> + +<quiz> +Bir workflow çalıştırırken parametre dosyası nasıl belirtilir? +- [ ] `--params params.yaml` +- [ ] `-config params.yaml` +- [x] `-params-file params.yaml` +- [ ] `--input-params params.yaml` + +Daha fazla bilgi: [1.3. Parametre dosyası kullanın](#13-parametre-dosyasi-kullanin) +</quiz> + +<quiz> +`outputDir` yapılandırma seçeneği neyi kontrol eder? +- [ ] work dizininin konumu +- [x] Workflow çıktılarının yayınlandığı temel yol +- [ ] Log dosyaları için dizin +- [ ] Modül dosyalarının konumu + +Daha fazla bilgi: [2.1. outputDir dizin adını özelleştirme](#21-outputdir-dizin-adini-ozellestirme) +</quiz> + +<quiz> +Çıktı yolu yapılandırmasında bir process adına dinamik olarak nasıl referans verilir? +- [ ] `#!groovy ${processName}` +- [ ] `process.name` +- [x] `#!groovy { meta.id }` +- [ ] `@processName` + +Daha fazla bilgi: [2.2. Çıktıları process'e göre organize etme](#22-ciktilari-processe-gore-organize-etme) +</quiz> + +<quiz> +Hem Docker hem de Conda etkinleştirilmişse ve bir process'in her iki direktifi de varsa, hangisi önceliklendirilir? +- [x] Docker (konteynerlar) +- [ ] Conda +- [ ] Process'te tanımlanan ilki +- [ ] Bir hataya neden olur + +Daha fazla bilgi: [3. Yazılım paketleme teknolojisi seçme](#3-yazilim-paketleme-teknolojisi-secme) +</quiz> + +<quiz> +Nextflow'daki varsayılan executor nedir? +- [x] `local` +- [ ] `slurm` +- [ ] `kubernetes` +- [ ] `aws` + +Daha fazla bilgi: [4. Çalıştırma platformu seçme](#4-calistirma-platformu-secme) +</quiz> + +<quiz> +Kaynak kullanım raporu oluşturan komut nedir? +- [ ] `nextflow run workflow.nf -with-metrics` +- [ ] `nextflow run workflow.nf -with-stats` +- [x] `nextflow run workflow.nf -with-report report.html` +- [ ] `nextflow run workflow.nf -profile report` + +Daha fazla bilgi: [5.1. Kaynak kullanım raporu oluşturmak için workflow'u çalıştırın](#51-kaynak-kullanim-raporu-olusturmak-icin-workflowu-calistirin) +</quiz> + +<quiz> +Yapılandırma dosyasında `cowpy` adlı belirli bir process için kaynak gereksinimleri nasıl ayarlanır? +- [ ] `#!groovy cowpy.memory = '2.GB'` +- [ ] `#!groovy process.cowpy.memory = '2.GB'` +- [x] `#!groovy process { withName: 'cowpy' { memory = '2.GB' } }` +- [ ] `#!groovy resources.cowpy.memory = '2.GB'` + +Daha fazla bilgi: [5.3. Belirli bir process için kaynak tahsislerini ayarlama](#53-belirli-bir-process-icin-kaynak-tahsislerini-ayarlama) +</quiz> + +<quiz> +`resourceLimits` direktifi ne yapar? +- [ ] Minimum kaynak gereksinimlerini ayarlar +- [ ] Process'lere kaynak tahsis eder +- [x] İstenebilecek maksimum kaynakları sınırlar +- [ ] Kaynak kullanımını gerçek zamanlı izler + +Daha fazla bilgi: [5.5. Kaynak sınırları ekleme](#55-kaynak-sinirlari-ekleme) +</quiz> + +<quiz> +Tek bir komutta birden fazla profil nasıl belirtilir? +- [ ] `-profile profile1 -profile profile2` +- [ ] `-profiles profile1,profile2` +- [x] `-profile profile1,profile2` +- [ ] `--profile profile1 --profile profile2` + +Daha fazla bilgi: [6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın](#6-onceden-ayarlanmis-yapilandirmalar-arasinda-gecis-yapmak-icin-profilleri-kullanin) +</quiz> + +<quiz> +Nextflow'un kullanacağı tamamen çözülmüş yapılandırmayı gösteren komut nedir? +- [ ] `nextflow show-config` +- [ ] `nextflow settings` +- [x] `nextflow config` +- [ ] `nextflow resolve` + +Daha fazla bilgi: [6.3. Çözülmüş yapılandırmayı görmek için `nextflow config` kullanın](#63-cozulmus-yapilandirmayi-gormek-icin-nextflow-config-kullanin) +</quiz> + +<quiz> +Profiller ne için kullanılabilir? (Geçerli olanların hepsini seçin) +- [x] Altyapıya özgü ayarları tanımlama (executor'lar, konteynerlar) +- [x] Farklı ortamlar için kaynak sınırlarını ayarlama +- [x] Kolay workflow testi için test parametreleri sağlama +- [ ] Yeni process'ler tanımlama + +Daha fazla bilgi: [6. Önceden ayarlanmış yapılandırmalar arasında geçiş yapmak için profilleri kullanın](#6-onceden-ayarlanmis-yapilandirmalar-arasinda-gecis-yapmak-icin-profilleri-kullanin) +</quiz> diff --git a/docs/tr/docs/nextflow_run/index.md b/docs/tr/docs/nextflow_run/index.md new file mode 100644 index 0000000000..28205c2dfa --- /dev/null +++ b/docs/tr/docs/nextflow_run/index.md @@ -0,0 +1,59 @@ +--- +title: Nextflow Run +hide: + - toc +page_type: index_page +index_type: course +additional_information: + technical_requirements: true + learning_objectives: + - Nextflow workflow'larının çalıştırılması ve yönetimi + - Çıktıların (sonuçlar) ve log dosyalarının bulunması ve yorumlanması + - Basit çok adımlı bir workflow'da temel Nextflow bileşenlerinin tanınması + - Pipeline çalıştırmasının HPC ve bulut dahil yaygın hesaplama platformlarında yapılandırılması + - Kod modülerliği ve yazılım konteynerları dahil, pipeline'ları FAIR yapan tekrar üretilebilirlik, taşınabilirlik ve kod yeniden kullanımı için en iyi uygulamaların özetlenmesi + audience_prerequisites: + - "**Hedef Kitle:** Bu kurs, Nextflow'a tamamen yeni başlayan ve mevcut pipeline'ları çalıştırmak isteyen öğrenciler için tasarlanmıştır." + - "**Beceriler:** Komut satırı, temel betik yazma kavramları ve yaygın dosya formatları hakkında bir miktar bilgi sahibi olunduğu varsayılmaktadır." + - "**Alan:** Alıştırmaların tümü alandan bağımsızdır, bu nedenle önceden bilimsel bilgi gerekmez." +--- + +# Nextflow Run + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +**Nextflow Run, tekrar üretilebilir ve ölçeklenebilir veri analizi workflow'larını çalıştırmaya yönelik uygulamalı bir giriştir.** + +Pratik örnekler ve rehberli alıştırmalar üzerinde çalışarak, pipeline'ları çalıştırma, dosyaları ve yazılım bağımlılıklarını yönetme, çalıştırmayı zahmetsizce paralelleştirme ve farklı hesaplama ortamlarında workflow'ları çalıştırma dahil olmak üzere Nextflow kullanmanın temellerini öğreneceksiniz. + +Workflow'ları Nextflow ile çalıştırmaya başlamak için gerekli becerileri ve özgüveni kazanacaksınız. + +<!-- additional_information --> + +## Kurs genel bakış + +### Ne yapacaksınız + +Bu kurs, bilgileri kademeli olarak tanıtmak üzere yapılandırılmış hedefe yönelik alıştırmalarla uygulamalıdır. + +Metin girdilerini işleyen bir Nextflow pipeline'ının birkaç versiyonunu çalıştıracaksınız. +Tek bir adımdan oluşan basit bir versiyonla başlayacak ve sonunda tablo şeklinde metin girdileri içeren bir CSV dosyası alan, birkaç dönüşüm adımı çalıştıran ve dönüştürülmüş metni söyleyen bir karakterin ASCII resmini içeren tek bir metin dosyası çıktı veren çok adımlı bir versiyona ilerleyeceksiniz. + +Bu kurs, pipeline'ları çalıştırmaya odaklanır (temel `nextflow run` komutunun adını almıştır). +Nextflow pipeline'ları geliştirmeye giriş arıyorsanız, [Hello Nextflow](../hello_nextflow/index.md) bölümüne bakın. + +### Ders planı + +Bunu, Nextflow'da yazılmış pipeline'ları çalıştırmanın ve yönetmenin belirli yönlerine odaklanacak üç bölüme ayırdık. + +| Kurs bölümü | Özet | Tahmini süre | +| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ------------ | +| [Bölüm 1: Temel işlemleri çalıştırma](./01_basics.md) | Basit bir workflow'un başlatılması ve çalıştırılmasının yönetilmesi | 30 dk | +| [Bölüm 2: Gerçek pipeline'ları çalıştırma](./02_pipeline.md) | Karmaşık girdilerin işlenmesi, çok adımlı workflow'ların çalıştırılması, konteynerların kullanılması ve zahmetsiz paralelleştirme | 60 dk | +| [Bölüm 3: Çalıştırma yapılandırması](./03_config.md) | Pipeline davranışının özelleştirilmesi ve farklı hesaplama ortamlarında kullanımın optimize edilmesi | 60 dk | + +Bu kursun sonunda, bilimsel hesaplama ihtiyaçlarınız için tekrar üretilebilir workflow'ları çalıştırma yolculuğunuzdaki sonraki adımları atmaya hazır olacaksınız. + +Kursu almaya hazır mısınız? + +[Öğrenmeye başla :material-arrow-right:](00_orientation.md){ .md-button .md-button--primary } diff --git a/docs/tr/docs/nextflow_run/next_steps.md b/docs/tr/docs/nextflow_run/next_steps.md new file mode 100644 index 0000000000..b18800cc54 --- /dev/null +++ b/docs/tr/docs/nextflow_run/next_steps.md @@ -0,0 +1,66 @@ +# Kurs özeti + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Run eğitim kursunu tamamladığınız için tebrikler! + +<!-- placeholder for video --> + +## Yolculuğunuz + +Çok temel bir workflow ile başladınız ve onu çalıştırmayı, çıktıları bulmayı ve çalışmasını yönetmeyi öğrendiniz. +Ardından, bu workflow'un giderek daha karmaşık versiyonları üzerinde çalıştınız ve channel'lar ile operatörler, kod modülerleştirme ve konteynerlar dahil Nextflow pipeline'larına güç veren temel kavramları ve mekanizmaları tanımayı öğrendiniz. +Son olarak, tercihlerinize ve hesaplama altyapınıza uyması için bir pipeline'ın yapılandırmasını nasıl özelleştireceğinizi öğrendiniz. + +### Ne öğrendiniz + +Artık Hello pipeline'ının çalışmasını yönetebilir, nasıl yapılandırıldığını tanımlayabilir ve dahil olan ana kod parçalarını tanımlayabilirsiniz. + +- Hello workflow'unun son hali, girdi olarak metin selamlamaları içeren bir CSV dosyası alır. +- Dört adım, ayrı modül dosyalarında saklanan Nextflow process'leri olarak uygulanır (`sayHello`, `convertToUpper`, `collectGreetings` ve `cowpy`). +- Sonuçlar `results/` adlı bir dizine yayınlanır. +- Pipeline'ın nihai çıktısı, büyük harfli selamlamaları söyleyen bir karakterin ASCII art'ını içeren düz metin dosyasıdır. + +<figure class="excalidraw"> +--8<-- "docs/hello_nextflow/img/hello_pipeline_complete.svg" +</figure> + +1. **`sayHello`:** Her selamlamayı kendi çıktı dosyasına yazar (örn. "Hello-output.txt") +2. **`convertToUpper`:** Her selamlamayı büyük harfe dönüştürür (örn. "HELLO") +3. **`collectGreetings`:** Tüm büyük harfli selamlamaları tek bir batch dosyasına toplar +4. **`cowpy`:** `cowpy` aracını kullanarak ASCII art oluşturur + +Workflow yapılandırması, girdilerin ve parametrelerin esnek, tekrar üretilebilir bir şekilde sağlanmasını destekler. + +### Kazanılan beceriler + +Bu uygulamalı kurs sayesinde şunları öğrendiniz: + +- Nextflow workflow'unu yerel olarak başlatma +- Nextflow tarafından oluşturulan çıktıları (sonuçlar) ve log dosyalarını bulma ve yorumlama +- Basit çok adımlı bir workflow'u oluşturan temel Nextflow bileşenlerini tanıma +- Operatörler ve channel factory'leri gibi ileri adım kavramlarını tanımlama +- Pipeline'ları farklı hesaplama ortamları için yapılandırma + +Artık mevcut Nextflow pipeline'larını kendi çalışmanıza entegre etmeye başlamak için temel bilgilerle donatıldınız. + +## Becerilerinizi geliştirmek için sonraki adımlar + +Sırada ne yapacağınız için en iyi önerilerimiz: + +- Sadece Nextflow çalıştırmayın, yazın! [Hello Nextflow](../hello_nextflow/index.md) ile Nextflow geliştiricisi olun +- Bilimsel analiz kullanım durumlarına Nextflow uygulayın: [Nextflow for Science](../nf4_science/index.md) +- [Hello nf-core](../hello_nf-core/index.md) ile nf-core'a başlayın +- [Debugging Side Quest](../side_quests/debugging.md) ile hata ayıklama tekniklerini öğrenin + +Son olarak, Nextflow'un yaratıcıları tarafından geliştirilen bulut tabanlı bir platform olan [**Seqera Platform**](https://seqera.io/)'a bakmanızı öneririz; workflow'larınızı başlatmayı ve yönetmeyi, verilerinizi yönetmeyi ve herhangi bir ortamda etkileşimli analizler çalıştırmayı çok daha kolay hale getirir. + +## Yardım alma + +Yardım kaynakları ve topluluk desteği için [Yardım sayfasına](../help.md) bakın. + +## Geri bildirim anketi + +Devam etmeden önce, lütfen kurs anketini doldurmak için bir dakikanızı ayırın! Geri bildirimleriniz, eğitim materyallerimizi herkes için iyileştirmemize yardımcı olur. + +[Ankete katıl :material-arrow-right:](survey.md){ .md-button .md-button--primary } diff --git a/docs/tr/docs/nextflow_run/survey.md b/docs/tr/docs/nextflow_run/survey.md new file mode 100644 index 0000000000..5807363143 --- /dev/null +++ b/docs/tr/docs/nextflow_run/survey.md @@ -0,0 +1,9 @@ +# Geri bildirim anketi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Devam etmeden önce, lütfen eğitimi değerlendirmek, deneyiminiz hakkında geri bildirim paylaşmak ve Nextflow yolculuğunuzda size yardımcı olmak için başka neler yapabileceğimizi bildirmek için bu kısa 5 soruluk anketi doldurun. + +Bu anketin tamamlanması bir dakikadan az sürer. Eğitim materyallerimizi herkes için iyileştirmemize yardımcı olduğunuz için teşekkür ederiz! + +<div data-tf-live="01K85R7F5HMAGCD298M2W7R93Y"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/tr/docs/nf4_science/genomics/00_orientation.md b/docs/tr/docs/nf4_science/genomics/00_orientation.md new file mode 100644 index 0000000000..d9c302da15 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/00_orientation.md @@ -0,0 +1,74 @@ +# Yönlendirme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Eğitim ortamı, bu eğitim kursunda çalışmak için gerekli tüm yazılımı, kodu ve veriyi içerir, bu nedenle kendiniz herhangi bir şey yüklemenize gerek yoktur. +Ancak, giriş yapmak için (ücretsiz) bir hesaba ihtiyacınız var ve arayüzü tanımak için birkaç dakikanızı ayırmalısınız. + +Henüz yapmadıysanız, lütfen daha ileri gitmeden önce [bu bağlantıyı](../../../envsetup/) takip edin. + +## Sağlanan Materyaller + +Bu eğitim kursu boyunca, `nf4-science/genomics/` dizininde çalışacağız; eğitim çalışma alanını açtığınızda bu dizine geçmeniz gerekir. +Bu dizin, ihtiyaç duyacağınız tüm kod dosyalarını, test verilerini ve yardımcı dosyaları içerir. + +Bu dizinin içeriğini keşfetmekten çekinmeyin; bunu yapmanın en kolay yolu, VSCode arayüzündeki eğitim çalışma alanının sol tarafındaki dosya gezginini kullanmaktır. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde temsil etmek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar bir içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 2 +``` + +Bunu `nf4-science/genomics` içinde çalıştırırsanız, aşağıdaki çıktıyı görmelisiniz: + +```console title="Dizin içeriği" + +. +├── data +│ ├── bam +│ ├── ref +│ ├── sample_bams.txt +│ └── samplesheet.csv +├── genomics-1.nf +├── genomics-2.nf +├── genomics-3.nf +├── genomics-4.nf +├── nextflow.config +└── solutions + ├── modules + ├── nf-test.config + └── tests + +6 directories, 8 files + +``` + +!!!note "Not" + + Bu çok fazla gibi görünse de endişelenmeyin; kursun her adımında ilgili parçaları ele alacağız. + Bu sadece size bir genel bakış sunmak için. + +**Başlamak için bilmeniz gerekenler burada özetlenmiştir:** + +- **`.nf` dosyaları**, kursun hangi bölümünde kullanıldıklarına göre adlandırılmış iş akışı betikleridir. + +- **`nextflow.config` dosyası**, minimal ortam özelliklerini ayarlayan bir yapılandırma dosyasıdır. + Şimdilik bunu göz ardı edebilirsiniz. + +- **`data` dizini**, girdi verilerini ve ilgili kaynakları içerir; kursta daha sonra açıklanacaktır. + +- **`solutions` dizini**, kursun 3. ve 4. Bölümlerinden kaynaklanan modül dosyalarını ve test yapılandırmalarını içerir. + Çalışmanızı kontrol etmek ve sorunları gidermek için referans olarak kullanılması amaçlanmıştır. + +!!!tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız, her zaman buraya dönmek için bu komutu çalıştırabilirsiniz: + + ```bash + cd /workspaces/training/nf4-science/genomics + ``` + +Şimdi, kursa başlamak için bu sayfanın sağ alt köşesindeki oka tıklayın. diff --git a/docs/tr/docs/nf4_science/genomics/01_per_sample_variant_calling.md b/docs/tr/docs/nf4_science/genomics/01_per_sample_variant_calling.md new file mode 100644 index 0000000000..74e6aa4891 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/01_per_sample_variant_calling.md @@ -0,0 +1,999 @@ +# Bölüm 1: Örnek başına varyant çağırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun ilk bölümünde, bireysel sekanslama örneklerine GATK varyant çağırma uygulayan basit bir varyant çağırma pipeline'ı oluşturmayı göstereceğiz. + +### Yöntem genel bakışı + +Varyant çağırma, bir referans genoma göre bir genom dizisindeki varyasyonları tanımlamayı amaçlayan bir genomik analiz yöntemidir. +Burada kısa varyantları, _yani_ SNP'leri ve indel'leri çağırmak için tasarlanmış araçları ve yöntemleri kullanacağız. + +![GATK pipeline](img/gatk-pipeline.png) + +Tam bir varyant çağırma pipeline'ı tipik olarak referansa haritalama (bazen genom hizalaması olarak da anılır) ve varyant filtreleme ve önceliklendirme dahil olmak üzere birçok adım içerir. +Kolaylık sağlamak için, bu kurs bölümünde sadece varyant çağırma kısmına odaklanacağız. + +### Veri seti + +Aşağıdaki veriyi ve ilgili kaynakları sağlıyoruz: + +- İnsan kromozom 20'sinin (hg19/b37'den) küçük bir bölgesinden oluşan **bir referans genom** ve yardımcı dosyaları (dizin ve sekans sözlüğü). +- Bir aile üçlüsüne (anne, baba ve oğul) karşılık gelen **üç tam genom sekanslama örneği**, dosya boyutlarını küçük tutmak için kromozom 20 üzerindeki küçük bir veri dilimine alt kümelenmiştir. + Bu, referans genoma zaten haritalanmış Illumina kısa okuma sekanslama verisidir ve [BAM](https://samtools.github.io/hts-specs/SAMv1.pdf) formatında (Binary Alignment Map, SAM'in sıkıştırılmış versiyonu, Sequence Alignment Map) sağlanmıştır. +- **Genomik aralıkların bir listesi**, yani örneklerimizin varyant çağırmaya uygun veriye sahip olduğu genomdaki koordinatlar, BED formatında sağlanmıştır. + +### İş akışı + +Bu kurs bölümünde, aşağıdakileri yapan bir iş akışı geliştireceğiz: + +1. [Samtools](https://www.htslib.org/) kullanarak her BAM girdi dosyası için bir dizin dosyası oluşturun +2. Her BAM girdi dosyası üzerinde GATK HaplotypeCaller'ı çalıştırarak örnek başına varyant çağrılarını VCF (Variant Call Format) formatında oluşturun + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-1.svg" +</figure> + +!!! note + + Dizin dosyaları biyoinformatik dosya formatlarının yaygın bir özelliğidir; ana dosyanın yapısı hakkında bilgi içerirler ve GATK gibi araçların tüm dosyayı okumak zorunda kalmadan verinin bir alt kümesine erişmesine olanak tanır. + Bu, bu dosyaların ne kadar büyük olabileceği düşünüldüğünde önemlidir. + +--- + +## 0. Isınma: Samtools ve GATK komutlarını etkileşimli olarak test edin + +Öncelikle komutları bir iş akışına sarmaya çalışmadan önce manuel olarak denemek istiyoruz. +İhtiyacımız olan araçlar (Samtools ve GATK) GitHub Codespaces ortamında yüklü değil, bu yüzden bunları konteynerler aracılığıyla kullanacağız (bkz. [Hello Containers](../../hello_nextflow/05_hello_containers.md)). + +!!! note + + `nf4-science/genomics` dizininde olduğunuzdan emin olun, böylece `pwd` yazdığınızda gösterilen yolun son kısmı `genomics` olsun. + +### 0.1. Samtools ile bir BAM girdi dosyasını dizinleyin + +Bir Samtools konteyneri çekip etkileşimli olarak başlatacağız ve BAM dosyalarından biri üzerinde `samtools index` komutunu çalıştıracağız. + +#### 0.1.1. Samtools konteynerini çekin + +```bash +docker pull community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.1.2. Samtools konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.1.3. Dizinleme komutunu çalıştırın + +[Samtools dokümantasyonu](https://www.htslib.org/doc/samtools-index.html) bize bir BAM dosyasını dizinlemek için çalıştırılacak komut satırını verir. + +Sadece girdi dosyasını sağlamamız gerekir; araç, girdi dosya adına `.bai` ekleyerek çıktı için otomatik olarak bir isim oluşturacaktır. + +```bash +samtools index /data/bam/reads_mother.bam +``` + +Bu hemen tamamlanmalıdır ve şimdi orijinal BAM girdi dosyasıyla aynı dizinde `reads_mother.bam.bai` adlı bir dosya görmelisiniz. + +??? abstract "Dizin içeriği" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_mother.bam + ├── reads_mother.bam.bai + └── reads_son.bam + ``` + +#### 0.1.4. Samtools konteynerinden çıkın + +```bash +exit +``` + +### 0.2. GATK HaplotypeCaller ile varyantları çağırın + +Bir GATK konteyneri çekip etkileşimli olarak başlatacağız ve az önce dizinlediğimiz BAM dosyası üzerinde `gatk HaplotypeCaller` komutunu çalıştıracağız. + +#### 0.2.1. GATK konteynerini çekin + +```bash +docker pull community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.2.2. GATK konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.2.3. Varyant çağırma komutunu çalıştırın + +[GATK dokümantasyonu](https://gatk.broadinstitute.org/hc/en-us/articles/21905025322523-HaplotypeCaller) bize bir BAM dosyası üzerinde varyant çağırma gerçekleştirmek için çalıştırılacak komut satırını verir. + +BAM girdi dosyasını (`-I`) ve referans genomu (`-R`), çıktı dosyası için bir isim (`-O`) ve analiz edilecek genomik aralıkların bir listesini (`-L`) sağlamamız gerekir. + +Ancak, dizin dosyasının yolunu belirtmemize gerek yok; araç, yerleşik adlandırma ve birlikte konumlandırma kuralına göre otomatik olarak aynı dizinde arayacaktır. +Aynısı referans genomun yardımcı dosyaları (dizin ve sekans sözlüğü dosyaları, `*.fai` ve `*.dict`) için de geçerlidir. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.vcf \ + -L /data/ref/intervals.bed +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +Çıktı dosyası `reads_mother.vcf`, konteynerdeki çalışma dizininizin içinde oluşturulur, bu nedenle çıktı dosya yolunu değiştirmediğiniz sürece VS Code dosya gezgininde görmezsiniz. +Ancak küçük bir test dosyasıdır, bu nedenle içeriği açmak ve görüntülemek için `cat` komutunu kullanabilirsiniz. +Dosyanın başlangıcına kadar kaydırırsanız, birçok meta veri satırından oluşan bir başlık ve ardından satır başına bir olmak üzere varyant çağrılarının bir listesini bulacaksınız. + +```console title="reads_mother.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Her satır, örneğin sekanslama verisinde tanımlanan olası bir varyantı açıklar. VCF formatını yorumlama konusunda rehberlik için [bu faydalı makaleye](https://www.ebi.ac.uk/training/online/courses/human-genetic-variation-introduction/variant-identification-and-analysis/understanding-vcf-format/) bakın. + +Çıktı VCF dosyasına, GATK tarafından otomatik olarak oluşturulan `reads_mother.vcf.idx` adlı bir dizin dosyası eşlik eder. +BAM dizin dosyasıyla aynı işleve sahiptir, araçların tüm dosyayı yüklemeden veri alt kümelerini aramasına ve almasına olanak tanır. + +#### 0.2.4. GATK konteynerinden çıkın + +```bash +exit +``` + +### Çıkarımlar + +Samtools dizinleme ve GATK varyant çağırma komutlarını ilgili konteynerlerinde nasıl test edeceğinizi biliyorsunuz. + +### Sırada ne var? + +Aynı komutları, işi yürütmek için konteynerler kullanan iki adımlı bir iş akışına nasıl saracağınızı öğrenin. + +--- + +## 1. Bir BAM dosyası üzerinde Samtools index çalıştıran tek aşamalı bir iş akışı yazın + +Size iş akışının ana bölümlerini özetleyen `genomics-1.nf` adlı bir iş akışı dosyası sağlıyoruz. +İşlevsel değildir; amacı sadece gerçek iş akışını yazmak için kullanacağınız bir iskelet olarak hizmet etmektir. + +### 1.1. Dizinleme işlemini tanımlayın + +Dizinleme işlemini açıklayan `SAMTOOLS_INDEX` adını vereceğimiz bir işlem yazarak başlayalım. + +```groovy title="genomics-1.nf" linenums="9" +/* + * BAM dizin dosyası oluştur + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + path "${input_bam}.bai" + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Bu eğitim serisinin Bölüm 1 ve Bölüm 2'sinde öğrendiğiniz tüm parçaları tanımalısınız. + +Bu işlem, `input_bam` girdisi aracılığıyla bir dosya yolu iletmemizi gerektirecek, o halde bunu bir sonraki adımda ayarlayalım. + +### 1.2. Bir girdi parametre bildirimi ekleyin + +Dosyanın üst kısmında, `Pipeline parameters` bölümü altında, `reads_bam` adlı bir CLI parametresi bildiriyor ve ona varsayılan bir değer veriyoruz. +Bu şekilde, tembel olabiliriz ve pipeline'ı başlatmak için komutu yazdığımızda girdiyi belirtmeyiz (geliştirme amaçları için). + +```groovy title="genomics-1.nf" linenums="3" +/* + * Pipeline parametreleri + */ +params { + // Birincil girdi + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" +} +``` + +Şimdi hazır bir işlemimiz ve ona çalışması için bir girdi verecek bir parametremiz var, o halde bu şeyleri birlikte bağlayalım. + +!!! note + + `${projectDir}`, mevcut Nextflow iş akışı betiğinin (`genomics-1.nf`) bulunduğu dizini işaret eden yerleşik bir Nextflow değişkenidir. + + Bu, mutlak yolları sabit kodlamadan iş akışı deposuna dahil edilen dosyalara, veri dizinlerine ve diğer kaynaklara başvurmayı kolaylaştırır. + +### 1.3. SAMTOOLS_INDEX'i çalıştırmak için workflow bloğu ekleyin + +`workflow` bloğunda, `SAMTOOLS_INDEX` işlemine girdi beslemek için bir **kanal** kurmamız gerekir; ardından o kanalın içeriği üzerinde çalışmak için işlemin kendisini çağırabiliriz. + +```groovy title="genomics-1.nf" linenums="24" +workflow { + + main: + // Girdi kanalı oluştur (CLI parametresi aracılığıyla tek dosya) + reads_ch = channel.fromPath(params.reads_bam) + + // Girdi BAM dosyası için dizin dosyası oluştur + SAMTOOLS_INDEX(reads_ch) + + publish: + bam_index = SAMTOOLS_INDEX.out +} +``` + +Workflow bloğunun iki bölümü vardır: + +- `main:` kanal işlemlerini ve işlem çağrılarını içerir +- `publish:` hangi çıktıların yayınlanması gerektiğini bildirir, bunları adlandırılmış hedeflere atar + +[Hello Channels](../../hello_nextflow/02_hello_channels.md) bölümünde kullandığımız `.fromPath` kanal fabrikasını kullandığımızı fark edeceksiniz. +Gerçekten de çok benzer bir şey yapıyoruz. +Fark, Nextflow'a dosya yolunun kendisini bir girdi öğesi olarak kanala yüklemesini söylememizdir, içeriğini okumak yerine. + +### 1.4. Sonuçların nereye yayınlanacağını tanımlamak için bir output bloğu ekleyin + +Workflow bloğundan sonra, iş akışı çıktılarının nereye yayınlanacağını belirten bir `output` bloğu ekliyoruz. + +```groovy title="genomics-1.nf" linenums="37" +output { + bam_index { + path '.' + } +} +``` + +`publish:` bölümündeki her adlandırılmış hedef (`bam_index` gibi), temel çıktı dizinine göre çıktı yolunu yapılandırabileceğiniz kendi bloğuna sahip olur. + +!!! note + + Burada kullandığımız veri dosyaları çok küçük olsa da, genomik verilerde çok büyük olabilirler. + Varsayılan olarak, Nextflow gereksiz dosya kopyalarından kaçınmak için yayın dizinindeki çıktı dosyalarına sembolik bağlantılar oluşturur. + `mode` seçeneğini kullanarak bu davranışı değiştirebilirsiniz (örn. `mode 'copy'`) gerçek kopyalar oluşturmak için. + Sembolik bağlantıların `work` dizininizi temizlediğinizde bozulacağını unutmayın, bu nedenle üretim iş akışları için `mode 'copy'` kullanmak isteyebilirsiniz. + +### 1.5. Çıktı dizinini yapılandırın + +Temel çıktı dizini `outputDir` yapılandırma seçeneği aracılığıyla ayarlanır. Bunu `nextflow.config` dosyasına ekleyin: + +=== "Sonra" + + ```groovy title="nextflow.config" hl_lines="2" + docker.enabled = true + outputDir = 'results_genomics' + ``` + +=== "Önce" + + ```groovy title="nextflow.config" + docker.enabled = true + ``` + +### 1.6. Dizinleme adımının çalıştığını doğrulamak için iş akışını çalıştırın + +Hadi iş akışını çalıştıralım! Hatırlatma olarak, girdi parametresini bildirdiğimizde girdi için varsayılan bir değer ayarladığımız için komut satırında bir girdi belirtmemize gerek yok. + +```bash +nextflow run genomics-1.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [reverent_sinoussi] DSL2 - revision: 41d43ad7fe + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1 ✔ + ``` + +Dizin dosyasının doğru şekilde oluşturulduğunu çalışma dizinine veya sonuçlar dizinine bakarak kontrol edebilirsiniz. + +??? abstract "Çalışma dizini içeriği" + + ```console + work/2a/e695367b2f60df09cf826b07192dc3 + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + └── reads_mother.bam.bai + ``` + +??? abstract "Sonuçlar dizini içeriği" + + ```console + results_genomics/ + └── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ``` + +İşte burada! + +### Çıkarımlar + +Bir genomik aracı tek adımlı bir Nextflow iş akışına nasıl saracağınızı ve bir konteyner kullanarak çalıştırmayı biliyorsunuz. + +### Sırada ne var? + +İlkinin çıktısını tüketen ikinci bir adım ekleyin. + +--- + +## 2. Dizinlenmiş BAM dosyası üzerinde GATK HaplotypeCaller çalıştırmak için ikinci bir işlem ekleyin + +Artık girdi dosyamız için bir dizinimiz olduğuna göre, iş akışının ilginç kısmı olan varyant çağırma adımını kurmaya geçebiliriz. + +### 2.1. Varyant çağırma işlemini tanımlayın + +Varyant çağırma işlemini açıklayan `GATK_HAPLOTYPECALLER` adını vereceğimiz bir işlem yazalım. + +```groovy title="genomics-1.nf" linenums="44" +/* + * GATK HaplotypeCaller ile varyantları çağır + */ +process GATK_HAPLOTYPECALLER { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path input_bam + path input_bam_index + path ref_fasta + path ref_index + path ref_dict + path interval_list + + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + + script: + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ +} +``` + +Burada her bir çıktı kanalımızı benzersiz şekilde adlandırmak için yeni bir sözdizimi (`emit:`) kullandığımızı fark edeceksiniz ve bunun nedenleri yakında netleşecektir. + +Bu komut oldukça fazla girdi alır, çünkü GATK basit bir dizinleme işine kıyasla analizi gerçekleştirmek için daha fazla bilgiye ihtiyaç duyar. +Ancak girdi bloğunda tanımlanan girdilerden daha fazlasının GATK komutunda listelendiğini fark edeceksiniz. Bunun nedeni nedir? + +!!! note + + GATK, BAM dizin dosyasını ve referans genomun yardımcı dosyalarını aramayı bilir çünkü bu dosyaları çevreleyen kurallara aşindir. + Ancak Nextflow alan bağımsız olacak şekilde tasarlanmıştır ve biyoinformatik dosya formatı gereksinimleri hakkında hiçbir şey bilmez. + +Nextflow'a bu dosyaları çalışma zamanında çalışma dizininde aşamalı olarak yerleştirmesi gerektiğini açıkça söylememiz gerekir; aksi takdirde yapmayacaktır ve GATK (haklı olarak) dizin dosyalarının eksik olduğu hakkında bir hata verecektir. + +Benzer şekilde, çıktı VCF'nin dizin dosyasını (`"${input_bam}.vcf.idx"` dosyası) açıkça listelememiz gerekir, böylece Nextflow sonraki adımlarda gerekli olması durumunda bu dosyayı takip etmeyi bilir. + +### 2.2. Yardımcı girdiler için tanımlar ekleyin + +Yeni işlemimiz sağlanacak bir avuç ek dosya beklediğinden, `Pipeline parameters` bölümü altında bunlar için bazı CLI parametreleri ve bazı varsayılan değerler (daha öncekiyle aynı nedenlerle) ayarlıyoruz. + +```groovy title="genomics-1.nf" linenums="8" + // Yardımcı dosyalar + reference: Path = "${projectDir}/data/ref/ref.fasta" + reference_index: Path = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict: Path = "${projectDir}/data/ref/ref.dict" + intervals: Path = "${projectDir}/data/ref/intervals.bed" +``` + +### 2.3. Yardımcı dosya yollarını tutacak değişkenler oluşturun + +Ana veri girdileri kanallar aracılığıyla dinamik olarak aktarılırken, yardımcı dosyaları ele almanın iki yaklaşımı vardır. Önerilen yaklaşım, veri akışını daha net ve tutarlı hale getiren açık kanallar oluşturmaktır. Alternatif olarak, file() fonksiyonu daha basit durumlar için kullanılabilir, özellikle aynı dosyaya birden fazla işlemde başvurmanız gerektiğinde - ancak bunun hala dolaylı olarak kanallar oluşturduğuna dikkat edin. <!-- TODO: Açıklık: bu hala yazılan girdilerle gerekli mi? --> + +Bunu workflow bloğuna ekleyin (`reads_ch` oluşturulduktan sonra, `main:` bölümünün içine): + +```groovy title="genomics-1.nf" linenums="79" + // Yardımcı dosyalar için dosya yollarını yükle (referans ve aralıklar) + ref_file = file(params.reference) + ref_index_file = file(params.reference_index) + ref_dict_file = file(params.reference_dict) + intervals_file = file(params.intervals) +``` + +Bu, yardımcı dosya yollarının bunlara ihtiyaç duyan herhangi bir işleme girdi olarak sağlanabilmesi için hazır hale getirir. + +### 2.4. GATK_HAPLOTYPECALLER'ı çalıştırmak için workflow bloğuna bir çağrı ekleyin + +Artık ikinci işlemimizi kurduk ve tüm girdiler ve yardımcı dosyalar hazır ve mevcut, workflow gövdesine `GATK_HAPLOTYPECALLER` işlemine bir çağrı ekleyebiliriz. + +```groovy title="genomics-1.nf" linenums="88" + // Dizinlenmiş BAM dosyasından varyantları çağır + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ref_file, + ref_index_file, + ref_dict_file, + intervals_file + ) +``` + +Bu eğitim serisinin Bölüm 1'inden `*.out` sözdizimini tanımalısınız; Nextflow'a `SAMTOOLS_INDEX` tarafından çıktılanan kanalı almasını ve bunu `GATK_HAPLOTYPECALLER` işlem çağrısına bağlamasını söylüyoruz. + +!!! note + + Girdilerin işlem çağrısında işlemin girdi bloğunda listelendikleriyle tamamen aynı sırada sağlandığını fark edeceksiniz. + Nextflow'da girdiler konumsaldır, yani aynı sıraya _uymalısınız_; ve elbette aynı sayıda öğe olmalıdır. + +### 2.5. publish bölümünü ve output bloğunu güncelleyin + +VCF çıktılarını içerecek şekilde `publish:` bölümünü güncellememiz ve `output` bloğuna karşılık gelen hedefler eklememiz gerekiyor. + +```groovy title="genomics-1.nf" linenums="99" + publish: + bam_index = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx +} + +output { + bam_index { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } +} +``` + +### 2.6. Varyant çağırma adımının çalıştığını doğrulamak için iş akışını çalıştırın + +Genişletilmiş iş akışını `-resume` ile çalıştıralım, böylece dizinleme adımını tekrar çalıştırmamız gerekmez. + +```bash +nextflow run genomics-1.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [grave_volta] DSL2 - revision: 4790abc96a + + executor > local (1) + [2a/e69536] SAMTOOLS_INDEX (1) | 1 of 1, cached: 1 ✔ + [53/e18e98] GATK_HAPLOTYPECALLER (1) | 1 of 1 ✔ + ``` + +Şimdi konsol çıktısına bakarsak, listelenen iki işlemi görüyoruz. + +İlk işlem önbellekleme sayesinde beklendiği gibi atlandı, ikinci işlem ise yepyeni olduğu için çalıştırıldı. + +Çıktı dosyalarını sonuçlar dizininde (çalışma dizinine sembolik bağlantılar olarak) bulacaksınız. + +??? abstract "Dizin içeriği" + + ```console + results_genomics/ + ├── reads_mother.bam.bai -> */87/908bba*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */cf/36f756*/reads_mother.bam.vcf + └── reads_mother.bam.vcf.idx -> */cf/36f756*/reads_mother.bam.vcf.idx + ``` + +VCF dosyasını açarsanız, GATK komutunu doğrudan konteynerde çalıştırarak oluşturduğunuz dosyayla aynı içeriği görmelisiniz. + +```console title="reads_mother.bam.vcf" linenums="26" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother +20_10037292_10066351 3480 . C CT 503.03 . AC=2;AF=1.00;AN=2;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=27.95;SOR=1.179 GT:AD:DP:GQ:PL 1/1:0,18:18:54:517,54,0 +20_10037292_10066351 3520 . AT A 609.03 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.83;SOR=0.693 GT:AD:DP:GQ:PL 1/1:0,18:18:54:623,54,0 +20_10037292_10066351 3529 . T A 155.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.544;DP=21;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=7.78;ReadPosRankSum=-1.158;SOR=1.034 GT:AD:DP:GQ:PL 0/1:12,8:20:99:163,0,328 +``` + +Bu, çalışmamızdaki her örnek için oluşturmayı önemsediğimiz çıktıdır. + +### Çıkarımlar + +Gerçek analiz işi yapan ve yardımcı dosyalar gibi genomik dosya formatı özellikleriyle başa çıkabilen çok basit iki adımlı bir iş akışı nasıl yapacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışının birden fazla örneği toplu olarak işlemesini sağlayın. + +--- + +## 3. İş akışını bir örnek grubu üzerinde çalışacak şekilde uyarlayın + +Tek bir örnek üzerinde işlemeyi otomatikleştirebilen bir iş akışına sahip olmak güzel, ama ya 1000 örneğiniz varsa? +Tüm örneklerinizde döngü yapan bir bash betiği yazmanız mı gerekiyor? + +Hayır, şükürler olsun! Sadece kodda küçük bir değişiklik yapın ve Nextflow bunu da sizin için halledecektir. + +### 3.1. Girdi parametre bildirimini üç örneği listeleyen bir diziye çevirin + +Gelin girdi BAM dosyası bildirimindeki o varsayılan dosya yolunu, `Pipeline parameters` bölümünün altında üç test örneğimiz için dosya yollarını listeleyen bir diziye çevirelim. + +=== "Sonra" + + ```groovy title="genomics-1.nf" linenums="7" + // Birincil girdi (üç örnek dizisi) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" linenums="7" + // Birincil girdi + reads_bam: Path = "${projectDir}/data/bam/reads_mother.bam" + ``` + +!!! note + + Yazılan parametre bildirimleri (`reads_bam: Path` gibi) kullanırken, bir dizi değeri atayamazsınız. + Diziler için, tür açıklamasını atlayın. + +Ve aslında yapmamız gereken tek şey bu, çünkü workflow gövdesinde kullandığımız kanal fabrikası (`.fromPath`) girdi kanalına yüklemek için birden fazla dosya yolunu kabul etmekten tek bir tane yüklemek kadar mutlu. + +!!! note + + Normalde, örnek listesini iş akışı dosyanıza sabit kodlamak istemezsiniz, ancak işleri basit tutmak için burada bunu yapıyoruz. + Bu eğitim serisinin ilerleyen bölümlerinde girdileri işlemek için daha zarif yollar sunacağız. + +### 3.2. Üç örnek üzerinde çalıştığını doğrulamak için iş akışını çalıştırın + +Artık boru tesisatı üç test örneğinin tamamında çalışacak şekilde ayarlandığına göre iş akışını çalıştırmayı deneyelim. + +```bash +nextflow run genomics-1.nf -resume +``` + +Komik şey: bu _çalışabilir_, VEYA _başarısız olabilir_. Örneğin, işte başarılı bir çalıştırma: + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [peaceful_yalow] DSL2 - revision: a256d113ad + + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3, cached: 1 ✔ + [7a/89bc43] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 1 ✔ + ``` + +İş akışı çalıştırmanız başarılı olduysa, şuna benzer bir hata alana kadar tekrar çalıştırın: + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [loving_pasteur] DSL2 - revision: d2a8e63076 + + executor > local (4) + [01/eea165] SAMTOOLS_INDEX (2) | 3 of 3, cached: 1 ✔ + [a5/fa9fd0] GATK_HAPLOTYPECALLER (3) | 1 of 3, cached: 1 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Process `GATK_HAPLOTYPECALLER (2)` terminated with an error exit status (2) + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_father.bam -O reads_father.bam.vcf -L intervals.bed + + Command exit status: + 2 + + Command error: + ... + A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. + ... + ``` + +GATK komut hata çıktısına bakarsanız, şuna benzer bir satır olacaktır: + +```console +A USER ERROR has occurred: Traversal by intervals was requested but some input files are not indexed. +``` + +Bu garip, iş akışının ilk adımında BAM dosyalarını açıkça dizinlediğimizi düşünürsek. Boru tesisatında bir sorun mu olabilir? + +#### 3.2.1. İlgili çağrılar için çalışma dizinlerini kontrol edin + +Konsol çıktısında listelenen başarısız `GATK_HAPLOTYPECALLER` işlem çağrısı için çalışma dizininin içine bakalım. + +??? abstract "Dizin içeriği" + + ```console + work/a5/fa9fd0994b6beede5fb9ea073596c2 + ├── intervals.bed -> /workspaces/training/nf4-science/genomics/data/ref/intervals.bed + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/01/eea16597bd6e810fb4cf89e60f8c2d/reads_father.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + ├── reads_son.bam.vcf + ├── reads_son.bam.vcf.idx + ├── ref.dict -> /workspaces/training/nf4-science/genomics/data/ref/ref.dict + ├── ref.fasta -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta + └── ref.fasta.fai -> /workspaces/training/nf4-science/genomics/data/ref/ref.fasta.fai + ``` + +Bu dizinde listelenen BAM dosyasının ve BAM dizininin adlarına özellikle dikkat edin: `reads_son.bam` ve `reads_father.bam.bai`. + +Ne demek? Nextflow bu işlem çağrısının çalışma dizininde bir dizin dosyası aşamalı olarak yerleştirmiş, ancak yanlış olanı. Bu nasıl olabilir? + +#### 3.2.2. Kanal içeriğini incelemek için [view() operatörünü](https://www.nextflow.io/docs/latest/reference/operator.html#view) kullanın + +Workflow gövdesinde `GATK_HAPLOTYPER` işlem çağrısından önce bu iki satırı ekleyin: + +```groovy title="genomics-1.nf" linenums="84" + // geçici tanılama + reads_ch.view() + SAMTOOLS_INDEX.out.view() +``` + +Ardından iş akışı komutunu tekrar çalıştırın. + +```bash +nextflow run genomics-1.nf +``` + +Bir kez daha, bu başarılı olabilir veya başarısız olabilir. İşte başarılı bir çalıştırma: + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [fervent_pasteur] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + [a2/dbd8d5] GATK_HAPLOTYPECALLER (3) | 3 of 3 ✔ + ``` + +Ve işte başarısız bir tane: + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [angry_hamilton] DSL2 - revision: a256d113ad + + /workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_father.bam + /workspaces/training/nf4-science/genomics/data/bam/reads_son.bam + executor > local (6) + [4f/7071b0] SAMTOOLS_INDEX (3) | 3 of 3 ✔ + /workspaces/training/nf4-science/genomics/work/4f/7071b082b45dd85b1c9b6b3b32cb69/reads_father.bam.bai + /workspaces/training/nf4-science/genomics/work/3c/331645a9e20e67edae10da5ba17c7b/reads_son.bam.bai + /workspaces/training/nf4-science/genomics/work/b4/45a376f0e724be1dc626a6807f73d8/reads_mother.bam.bai + [a3/cf3a89] GATK_HAPLOTYPECALLER (3) | 1 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (3)' + ... + ``` + +Tekrar başarısız olması için birkaç kez çalıştırmanız gerekebilir. +Bu hata tutarlı bir şekilde yeniden üretilmeyecektir çünkü bireysel işlem çağrılarının yürütme sürelerindeki bazı değişkenliklere bağlıdır. + +Eklediğimiz iki `.view()` çağrısının çıktısı başarısız bir çalıştırma için şöyle görünür: + +```console +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +/workspaces/training/nf4-science/genomics/work/9c/53492e3518447b75363e1cd951be4b/reads_father.bam.bai +/workspaces/training/nf4-science/genomics/work/cc/37894fffdf6cc84c3b0b47f9b536b7/reads_son.bam.bai +/workspaces/training/nf4-science/genomics/work/4d/dff681a3d137ba7d9866e3d9307bd0/reads_mother.bam.bai +``` + +İlk üç satır girdi kanalına, ikincisi ise çıktı kanalına karşılık gelir. +Üç örnek için BAM dosyalarının ve dizin dosyalarının aynı sırada listelenmediğini görebilirsiniz! + +!!! note + + Birden fazla öğe içeren bir kanal üzerinde bir Nextflow işlemi çağırdığınızda, Nextflow yürütmeyi mümkün olduğunca paralelleştirmeye çalışacak ve çıktıları kullanılabilir oldukları sırayla toplayacaktır. + Sonuç olarak, karşılık gelen çıktılar orijinal girdilerin verildiğinden farklı bir sırada toplanabilir. + +Şu anda yazıldığı şekliyle, iş akışı betiğimiz dizin dosyalarının dizinleme adımından girdilerin verildiği anne/baba/oğul sırasıyla aynı sırada listelenerek çıkacağını varsayıyor. +Ancak bunun böyle olacağının garantisi yoktur, bu yüzden bazen (her zaman olmasa da) yanlış dosyalar ikinci adımda eşleştirilir. + +Bunu düzeltmek için, BAM dosyalarının ve dizin dosyalarının kanallar aracılığıyla birlikte seyahat etmesini sağlamamız gerekir. + +!!! tip + + İş akışı kodundaki `view()` ifadeleri hiçbir şey yapmaz, bu nedenle bunları içeride bırakmak bir sorun değildir. + Ancak konsol çıktınızı karıştıracaklar, bu nedenle sorunu gidermekle işiniz bittiğinde bunları kaldırmanızı öneririz. + +### 3.3. SAMTOOLS_INDEX işleminin çıktısını, girdi dosyasını ve dizinini birlikte tutan bir demete değiştirin + +Bir BAM dosyasının ve dizininin yakından ilişkili kalmasını sağlamanın en basit yolu, onları dizin görevinden çıkan bir demete paketlemektir. + +!!! note + + Bir **demet**, bir fonksiyondan birden fazla değer döndürmek için yaygın olarak kullanılan sonlu, sıralı bir öğe listesidir. Demetler, birden fazla girdi veya çıktıyı işlemler arasında aktarırken ilişkilerini ve sıralarını korumak için özellikle kullanışlıdır. + +İlk olarak, `SAMTOOLS_INDEX` işleminin çıktısını, çıktı bildiriminde BAM dosyasını içerecek şekilde değiştirelim. + +=== "Sonra" + + ```groovy title="genomics-1.nf" linenums="20" + output: + tuple path(input_bam), path("${input_bam}.bai") + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" linenums="20" + output: + path "${input_bam}.bai" + ``` + +Bu şekilde, her dizin dosyası orijinal BAM dosyasıyla sıkı bir şekilde eşleştirilecek ve dizinleme adımının genel çıktısı, dosya çiftlerini içeren tek bir kanal olacaktır. + +### 3.4. GATK_HAPLOTYPECALLER işleminin girdisini bir demet olacak şekilde değiştirin + +İş akışındaki ilk işlemin çıktısının 'şeklini' değiştirdiğimize göre, ikinci işlemin girdi tanımını eşleşecek şekilde güncellememiz gerekiyor. + +Özellikle, daha önce `GATK_HAPLOTYPECALLER` işleminin girdi bloğunda iki ayrı girdi yolu bildirdiğimiz yerde, şimdi `SAMTOOLS_INDEX` tarafından yayılan demetin yapısıyla eşleşen tek bir girdi bildiriyoruz. + +=== "Sonra" + + ```groovy title="genomics-1.nf" linenums="51" + input: + tuple path(input_bam), path(input_bam_index) + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" linenums="51" + input: + path input_bam + path input_bam_index + ``` + +Elbette, `GATK_HAPLOTYPECALLER`ın beklediği girdilerin şeklini değiştirdiğimize göre, işlem çağrısını buna göre workflow gövdesinde güncellememiz gerekiyor. + +### 3.5. Workflow bloğundaki GATK_HAPLOTYPECALLER çağrısını güncelleyin + +Artık BAM dosyası `SAMTOOLS_INDEX` tarafından kanal çıktısına paketlendiğinden, orijinal `reads_ch`'yi `GATK_HAPLOTYPECALLER` işlemine sağlamamıza gerek yok. + +Sonuç olarak, o satırı basitçe silebiliriz. + +=== "Sonra" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + SAMTOOLS_INDEX.out, + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" linenums="88" + GATK_HAPLOTYPECALLER( + reads_ch, + SAMTOOLS_INDEX.out, + ``` + +Dizin uyumsuzluğu sorununu çözmek için gerekli olan tüm yeniden kablolama budur. + +### 3.6. Demet için publish bölümünü ve output bloğunu güncelleyin + +`SAMTOOLS_INDEX.out` artık hem BAM'i hem de dizinini içeren bir demet olduğundan, her iki dosya da birlikte yayınlanacaktır. +Artık her iki dosyayı da içerdiğini yansıtmak için hedefi `bam_index`'ten `indexed_bam`'e yeniden adlandırıyoruz. + +=== "Sonra" + + ```groovy title="genomics-1.nf" hl_lines="2" + publish: + indexed_bam = SAMTOOLS_INDEX.out + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" + publish: + bam_index = SAMTOOLS_INDEX.out + ``` + +Ayrıca yeni hedef adını kullanmak için output bloğunu güncellememiz gerekiyor: + +=== "Sonra" + + ```groovy title="genomics-1.nf" hl_lines="2" + output { + indexed_bam { + path '.' + } + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" + output { + bam_index { + path '.' + } + ``` + +### 3.7. Her seferinde üç örnek üzerinde doğru çalıştığını doğrulamak için iş akışını çalıştırın + +Elbette, kanıt pudingin içindedir, bu yüzden bunun ileriye dönük güvenilir bir şekilde çalışacağından emin olmak için iş akışını birkaç kez daha çalıştıralım. + +```bash +nextflow run genomics-1.nf +``` + +Bu sefer (ve her seferinde) her şey doğru şekilde çalışmalıdır: + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-1.nf` [special_goldstine] DSL2 - revision: 4cbbf6ea3e + + executor > local (6) + [d6/10c2c4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [88/1783aa] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Sonuçlar dizini artık her örnek için (demetten) hem BAM hem de BAI dosyalarını ve VCF çıktılarını içermektedir: + +??? abstract "Sonuçlar dizini içeriği" + + ```console + results_genomics/ + ├── reads_father.bam -> */60/e2614c*/reads_father.bam + ├── reads_father.bam.bai -> */60/e2614c*/reads_father.bam.bai + ├── reads_father.bam.vcf -> */b8/91b3c8*/reads_father.bam.vcf + ├── reads_father.bam.vcf.idx -> */b8/91b3c8*/reads_father.bam.vcf.idx + ├── reads_mother.bam -> */3e/fededc*/reads_mother.bam + ├── reads_mother.bam.bai -> */3e/fededc*/reads_mother.bam.bai + ├── reads_mother.bam.vcf -> */32/5ca037*/reads_mother.bam.vcf + ├── reads_mother.bam.vcf.idx -> */32/5ca037*/reads_mother.bam.vcf.idx + ├── reads_son.bam -> */3c/36d1c2*/reads_son.bam + ├── reads_son.bam.bai -> */3c/36d1c2*/reads_son.bam.bai + ├── reads_son.bam.vcf -> */d7/a6b046*/reads_son.bam.vcf + └── reads_son.bam.vcf.idx -> */d7/a6b046*/reads_son.bam.vcf.idx + ``` + +İsterseniz, `SAMTOOLS_INDEX` çıktı kanalının içeriğinin nasıl göründüğüne bakmak için `.view()`'i tekrar kullanabilirsiniz: + +```groovy title="genomics-1.nf" linenums="92" +SAMTOOLS_INDEX.out.view() +``` + +Kanalın beklenen üç demeti içerdiğini göreceksiniz (okunabilirlik için dosya yolları kısaltılmıştır). + +```console title="Çıktı" +[*/60/e2614c*/reads_father.bam, */60/e2614c*/reads_father.bam.bai] +[*/3e/fededc*/reads_mother.bam, */3e/fededc*/reads_mother.bam.bai] +[*/3c/36d1c2*/reads_son.bam, */3c/36d1c2*/reads_son.bam.bai] +``` + +Bu, ileriye dönük çok daha güvenli olacaktır. + +### Çıkarımlar + +İş akışınızı birden fazla örnek üzerinde (bağımsız olarak) çalıştırmayı biliyorsunuz. + +### Sırada ne var? + +Örnekleri toplu olarak işlemeyi kolaylaştırın. + +--- + +## 4. İş akışının bir grup girdi dosyası içeren bir metin dosyasını kabul etmesini sağlayın + +Bir iş akışına birden fazla veri girdi dosyası sağlamanın çok yaygın bir yolu, dosya yollarını içeren bir metin dosyasıyla yapmaktır. +Satır başına bir dosya yolu listeleyen ve başka hiçbir şey olmayan basit bir metin dosyası kadar basit olabilir veya dosya ek meta veriler içerebilir, bu durumda genellikle örnek listesi olarak adlandırılır. + +Burada size basit durumu nasıl yapacağınızı göstereceğiz. + +### 4.1. Girdi dosya yollarını listeleyen sağlanan metin dosyasını inceleyin + +`data/` dizininde bulabileceğiniz `sample_bams.txt` adlı girdi dosya yollarını listeleyen bir metin dosyası zaten yaptık. + +```txt title="sample_bams.txt" +/workspaces/training/nf4-science/genomics/data/bam/reads_mother.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_father.bam +/workspaces/training/nf4-science/genomics/data/bam/reads_son.bam +``` + +Gördüğünüz gibi, satır başına bir dosya yolu listeledik ve bunlar mutlak yollardır. + +!!! note + + Burada kullandığımız dosyalar sadece GitHub Codespaces'inizin yerel dosya sistemindedir, ancak bulut depolamadaki dosyalara da işaret edebiliriz. + +### 4.2. Parametre varsayılanını güncelleyin + +`reads_bam` girdi parametremiz için varsayılan değeri `sample_bams.txt` dosyasına işaret edecek şekilde değiştirelim. + +=== "Sonra" + + ```groovy title="genomics-1.nf" linenums="7" + // Birincil girdi (girdi dosyalarının dosyası, satır başına bir tane) + reads_bam: Path = "${projectDir}/data/sample_bams.txt" + ``` + +=== "Önce" + + ```groovy title="genomics-1.nf" linenums="7" + // Birincil girdi (üç örnek dizisi) + reads_bam = [ + "${projectDir}/data/bam/reads_mother.bam", + "${projectDir}/data/bam/reads_father.bam", + "${projectDir}/data/bam/reads_son.bam" + ] + ``` + +Bu şekilde tembel olmaya devam edebiliriz, ancak dosya listesi artık iş akışı kodunun kendisinde yaşamıyor, bu da doğru yönde büyük bir adımdır. + +### 4.3. Bir dosyadan satırları okumak için kanal fabrikasını güncelleyin + +Şu anda, girdi kanal fabrikamız kendisine verdiğimiz herhangi bir dosyayı dizinleme işlemine beslemek istediğimiz veri girdileri olarak ele alıyor. +Şimdi ona girdi dosya yollarını listeleyen bir dosya verdiğimize göre, dosyayı ayrıştırmak ve içer diff --git a/docs/tr/docs/nf4_science/genomics/02_joint_calling.md b/docs/tr/docs/nf4_science/genomics/02_joint_calling.md new file mode 100644 index 0000000000..2b1973a418 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/02_joint_calling.md @@ -0,0 +1,1005 @@ +# Bölüm 2: Bir kohort üzerinde birleşik çağrı yapma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun ilk bölümünde, tamamen doğrusal olan ve her örneğin verilerini diğerlerinden bağımsız olarak işleyen bir varyant çağırma pipeline'ı oluşturdunuz. +Ancak gerçek bir genomik kullanım durumunda, tipik olarak birden fazla örneğin varyant çağrılarına birlikte bakmanız gerekecektir. + +Bu ikinci bölümde, Bölüm 1'deki pipeline'ı temel alarak GATK ile birleşik varyant çağırma işlemini uygulamak için kanalları ve kanal operatörlerini nasıl kullanacağınızı gösteriyoruz. + +### Yönteme genel bakış + +Bu kursun ilk bölümünde kullandığımız GATK varyant çağırma yöntemi basitçe örnek başına varyant çağrıları üretti. +Her örneğin varyantlarına yalnızca izole olarak bakmak istiyorsanız bu iyidir, ancak bu sınırlı bilgi verir. +Varyant çağrılarının birden fazla örnek arasında nasıl farklılaştığına bakmak genellikle daha ilgi çekicidir ve bunu yapmak için GATK, burada gösterdiğimiz birleşik varyant çağırma adında alternatif bir yöntem sunar. + +Birleşik varyant çağırma, her örnek için GVCF (Genomik VCF için) adı verilen özel bir varyant çıktısı türü oluşturmayı, ardından tüm örneklerden GVCF verilerini birleştirmeyi ve son olarak bir 'birleşik genotipleme' istatistiksel analizi çalıştırmayı içerir. + +![Birleşik analiz](img/joint-calling.png) + +Bir örneğin GVCF'sinin özel yanı, genomun hedeflenen alanındaki tüm pozisyonlar hakkında dizi veri istatistiklerini özetleyen kayıtlar içermesidir, yalnızca programın varyasyon kanıtı bulduğu pozisyonları değil. +Bu, birleşik genotipleme hesaplaması için kritiktir ([daha fazla okuma](https://gatk.broadinstitute.org/hc/en-us/articles/360035890431-The-logic-of-joint-calling-for-germline-short-variants)). + +GVCF, Bölüm 1'de kullandığımız aynı araç olan GATK HaplotypeCaller tarafından ek bir parametre (`-ERC GVCF`) ile üretilir. +GVCF'leri birleştirmek, örnek başına çağrıları bir veri deposuna (bir veritabanına benzer) birleştiren GATK GenomicsDBImport ile yapılır, ardından gerçek 'birleşik genotipleme' analizi GATK GenotypeGVCFs ile yapılır. + +### İş akışı + +Özetlemek gerekirse, kursun bu bölümünde aşağıdakileri yapan bir iş akışı geliştireceğiz: + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/genomics/img/hello-gatk-2.svg" +</figure> + +1. Samtools kullanarak her BAM girdi dosyası için bir dizin dosyası oluşturma +2. Her BAM girdi dosyası üzerinde örnek başına genomik varyant çağrılarının bir GVCF'sini oluşturmak için GATK HaplotypeCaller'ı çalıştırma +3. Tüm GVCF'leri toplayıp bunları bir GenomicsDB veri deposunda birleştirme +4. Kohort düzeyinde bir VCF üretmek için birleştirilmiş GVCF veri deposu üzerinde birleşik genotipleme çalıştırma + +Bunu Bölüm 1'dekiyle aynı veri setine uygulayacağız. + +--- + +## 0. Isınma: Samtools ve GATK'yi doğrudan çalıştırın + +Daha önce olduğu gibi, komutları bir iş akışına sarmaya çalışmadan önce manuel olarak denemek istiyoruz. + +!!! note + + Doğru çalışma dizininde olduğunuzdan emin olun: + `cd /workspaces/training/nf4-science/genomics` + +### 0.1. Samtools ile bir BAM girdi dosyasını indeksleyin + +Bu ilk adım Bölüm 1'dekiyle aynıdır, dolayısıyla çok tanıdık gelmeli, ancak bu sefer bunu üç örnek için de yapmamız gerekiyor. + +!!! note + + Teknik olarak pipeline'ımız aracılığıyla üç örnek için zaten dizin dosyaları oluşturduk, bu yüzden gidip bunları sonuçlar dizininden çıkarabiliriz. Ancak bunu manuel olarak yeniden yapmak daha temizdir ve sadece bir dakika sürecektir. + +#### 0.1.1. Samtools konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.1.2. Üç örnek için indeksleme komutunu çalıştırın + +```bash +samtools index /data/bam/reads_mother.bam +samtools index /data/bam/reads_father.bam +samtools index /data/bam/reads_son.bam +``` + +Daha önce olduğu gibi, bu dizin dosyalarını ilgili BAM dosyalarıyla aynı dizinde üretmelidir. + +??? abstract "Dizin içeriği" + + ```console + data/bam/ + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai + ``` + +Artık üç örneğin tümü için dizin dosyalarımız olduğuna göre, her biri için GVCF'leri oluşturmaya geçebiliriz. + +#### 0.1.3. Samtools konteynerinden çıkın + +```bash +exit +``` + +### 0.2. GATK HaplotypeCaller ile GVCF modunda varyantları çağırın + +Bu ikinci adım Bölüm 1: Merhaba Genomik'te yaptığımıza çok benzer, ancak şimdi GATK'yi 'GVCF modunda' çalıştıracağız. + +#### 0.2.1. GATK konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +#### 0.2.2. Varyant çağırma komutunu GVCF seçeneğiyle çalıştırın + +Genomik bir VCF (GVCF) üretmek için temel komuta `-ERC GVCF` seçeneğini ekliyoruz, bu da HaplotypeCaller'ın GVCF modunu açar. + +Ayrıca çıktı dosyası için dosya uzantısını `.vcf`'den `.g.vcf`'ye değiştiriyoruz. +Bu teknik olarak bir gereklilik değil, ancak şiddetle tavsiye edilen bir kuraldır. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_mother.bam \ + -O reads_mother.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +Bu, konteynerdeki mevcut çalışma dizininde `reads_mother.g.vcf` GVCF çıktı dosyasını oluşturur. + +İçeriğini görüntülemek için `cat` yaparsanız, Bölüm 1'de oluşturduğumuz eşdeğer VCF'den çok daha uzun olduğunu göreceksiniz. Dosyanın başlangıcına bile kaydıramazsınız ve satırların çoğu Bölüm 1'deki VCF'de gördüklerimizden oldukça farklı görünüyor. + +```console title="Çıktı" linenums="1674" +20_10037292_10066351 14714 . T <NON_REF> . . END=14718 GT:DP:GQ:MIN_DP:PL 0/0:37:99:37:0,99,1192 +20_10037292_10066351 14719 . T <NON_REF> . . END=14719 GT:DP:GQ:MIN_DP:PL 0/0:36:82:36:0,82,1087 +20_10037292_10066351 14720 . T <NON_REF> . . END=14737 GT:DP:GQ:MIN_DP:PL 0/0:42:99:37:0,100,1160 +``` + +Bunlar, varyant çağırıcının varyasyon kanıtı bulmadığı varyant olmayan bölgeleri temsil eder, bu nedenle varyasyonun yokluğuna olan güven düzeyini açıklayan bazı istatistikler yakalamıştır. Bu, iki çok farklı durum rakamını ayırt etmeyi mümkün kılar: (1) örneğin homozigot-referans olduğunu gösteren kaliteli veriler vardır ve (2) her iki şekilde de bir belirleme yapmak için yeterli iyi veri mevcut değildir. + +Bir GVCF'de, tipik olarak aralarına serpiştirilmiş daha az sayıda varyant kaydı ile birlikte bu tür çok sayıda varyant olmayan satır vardır. Gerçek bir varyant çağrısını bulmak için dosyanın ilk 176 satırını yüklemek için GVCF üzerinde `head -176` çalıştırmayı deneyin. + +```console title="Çıktı" linenums="174" +20_10037292_10066351 3479 . T <NON_REF> . . END=3479 GT:DP:GQ:MIN_DP:PL 0/0:34:36:34:0,36,906 +20_10037292_10066351 3480 . C CT,<NON_REF> 503.03 . DP=23;ExcessHet=0.0000;MLEAC=2,0;MLEAF=1.00,0.00;RAW_MQandDP=82800,23 GT:AD:DP:GQ:PL:SB 1/1:0,18,0:18:54:517,54,0,517,54,517:0,0,7,11 +20_10037292_10066351 3481 . T <NON_REF> . . END=3481 GT:DP:GQ:MIN_DP:PL 0/0:21:51:21:0,51,765 +``` + +İkinci satır dosyadaki ilk varyant kaydını gösterir; bu, Bölüm 1'de baktığımız VCF dosyasındaki ilk varyanta karşılık gelir. + +Orijinal VCF'nin olduğu gibi, çıktı GVCF dosyasına da `reads_mother.g.vcf.idx` adlı bir dizin dosyası eşlik eder. + +#### 0.2.3. İşlemi diğer iki örnek üzerinde tekrarlayın + +Birleşik genotipleme adımını test etmek için üç örneğin tümü için GVCF'lere ihtiyacımız var, bu yüzden şimdi bunları manuel olarak oluşturalım. + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_father.bam \ + -O reads_father.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +```bash +gatk HaplotypeCaller \ + -R /data/ref/ref.fasta \ + -I /data/bam/reads_son.bam \ + -O reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + -ERC GVCF +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +Bu tamamlandığında, mevcut dizininizde `.g.vcf` ile biten üç dosyanız (örnek başına bir) ve `.g.vcf.idx` ile biten ilgili dizin dosyalarınız olmalıdır. + +### 0.3. Birleşik genotipleme çalıştırın + +Artık tüm GVCF'lere sahip olduğumuza göre, sonunda bir örnek kohortu için varyant çağrıları oluşturmak için birleşik genotipleme yaklaşımını deneyebiliriz. +Hatırlatma olarak, tüm GVCF'lerden verileri bir veri deposunda birleştirmeyi ve ardından birleşik çağrılmış varyantların nihai VCF'sini oluşturmak için asıl birleşik genotipleme analizini çalıştırmayı içeren iki adımlı bir yöntemdir. + +#### 0.3.1. Tüm örnek başına GVCF'leri birleştirin + +Bu ilk adım, tüm GVCF'lerden verileri bir GenomicsDB veri deposunda birleştirmek için GenomicsDBImport adlı başka bir GATK aracını kullanır. + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +Bu adımın çıktısı, etkin bir şekilde, birleştirilmiş varyant verilerini birden fazla farklı dosya biçiminde tutan daha fazla iç içe dizin içeren bir dizindir. +Etrafına göz atabilirsiniz ancak bu veri deposu formatının doğrudan insanlar tarafından okunması amaçlanmadığını hızla göreceksiniz. + +!!! note + + GATK, gerektiğinde veri deposundan varyant çağrı verilerini incelemeyi ve çıkarmayı mümkün kılan araçlar içerir. + +#### 0.3.2. Asıl birleşik genotipleme analizini çalıştırın + +Bu ikinci adım, kohorttaki tüm örnekler arasında mevcut veriler ışığında varyant istatistiklerini ve bireysel genotipleri yeniden hesaplamak için GenotypeGVCFs adlı başka bir GATK aracını kullanır. + +```bash +gatk GenotypeGVCFs \ + -R /data/ref/ref.fasta \ + -V gendb://family_trio_gdb \ + -O family_trio.vcf +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +Bu, konteynerdeki mevcut çalışma dizininde `family_trio.vcf` VCF çıktı dosyasını oluşturur. +Oldukça küçük bir başka dosya, bu yüzden içeriğini görüntülemek için bu dosyayı `cat` yapabilir ve ilk birkaç varyant satırını bulmak için yukarı kaydırabilirsiniz. + +```console title="family_trio.vcf" linenums="40" +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son +20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0 +20_10037292_10066351 3520 . AT A 1678.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=1.03;DP=80;ExcessHet=0.0000;FS=2.290;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=22.39;ReadPosRankSum=0.701;SOR=0.730 GT:AD:DP:GQ:PL 0/1:18,13:31:99:296,0,424 1/1:0,18:18:54:623,54,0 1/1:0,26:26:78:774,78,0 +20_10037292_10066351 3529 . T A 154.29 . AC=1;AF=0.167;AN=6;BaseQRankSum=-5.440e-01;DP=104;ExcessHet=0.0000;FS=1.871;MLEAC=1;MLEAF=0.167;MQ=60.00;MQRankSum=0.00;QD=7.71;ReadPosRankSum=-1.158e+00;SOR=1.034 GT:AD:DP:GQ:PL 0/0:44,0:44:99:0,112,1347 0/1:12,8:20:99:163,0,328 0/0:39,0:39:99:0,105,1194 +``` + +Bu, Bölüm 1'de oluşturduğumuz orijinal VCF'ye daha çok benziyor, ancak bu sefer üç örneğin tümü için genotip düzeyinde bilgiye sahibiz. +Dosyadaki son üç sütun, alfabetik sırada listelenen örnekler için genotip bloklarıdır. + +İlk varyant için test aile üçlümüz için çağrılan genotiplere bakarsak, babanın heterozigot-varyant (`0/1`) ve anne ve oğulun her ikisinin de homozigot-varyant (`1/1`) olduğunu görüyoruz. + +Sonuçta veri setinden çıkarmak istediğimiz bilgi budur! O halde gidelim tüm bunları bir Nextflow iş akışına saralım ki bunu ölçekte yapabilelim. + +#### 0.3.3. GATK konteynerinden çıkın + +```bash +exit +``` + +### Çıkarım + +Örnek başına varyant çağırmada yer alan bireysel komutları terminalde çalıştırarak istediğiniz bilgiyi üreteceklerini doğrulamayı biliyorsunuz. + +### Sırada ne var? + +Bu komutları gerçek bir pipeline'a sarın. + +--- + +## 1. Örnek başına varyant çağırma adımını GVCF üretecek şekilde değiştirin + +İyi haber şu ki, Bölüm 1'de bu işin bir kısmını yapan bir iş akışı yazdığımız için baştan başlamamıza gerek yok. +Ancak bu pipeline VCF dosyaları üretirken, şimdi birleşik genotipleme yapmak için GVCF dosyaları istiyoruz. +Bu yüzden GVCF varyant çağırma modunu açarak ve çıktı dosyası uzantısını güncelleyerek başlamamız gerekiyor. + +!!! note + + Kolaylık sağlamak için, Bölüm 1'in sonunda olduğu gibi GATK iş akışının yeni bir kopyasıyla çalışacağız, ancak farklı bir ad altında: `genomics-2.nf`. + +### 1.1. HaplotypeCaller'a bir GVCF yaymasını söyleyin ve çıktı uzantısını güncelleyin + +Kod düzenleyicide `genomics-2.nf` dosyasını açalım. +Çok tanıdık gelmeli, ancak beklendiği gibi çalıştığından emin olmak istiyorsanız çalıştırmaktan çekinmeyin. + +İki değişiklik yaparak başlayacağız: + +- GATK HaplotypeCaller komutuna `-ERC GVCF` parametresini ekleyin; +- GATK kuralına göre ilgili `.g.vcf` uzantısını kullanmak için çıktı dosyası yolunu güncelleyin. + +`-ERC GVCF` eklediğinizde önceki satırın sonuna bir ters eğik çizgi (`\`) eklediğinizden emin olun. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4 6" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.g.vcf \ + -L ${interval_list} \ + -ERC GVCF + """ + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="56" hl_lines="4" + """ + gatk HaplotypeCaller \ + -R ${ref_fasta} \ + -I ${input_bam} \ + -O ${input_bam}.vcf \ + -L ${interval_list} + """ + ``` + +HaplotypeCaller'ı VCF'ler yerine GVCF'ler oluşturacak şekilde değiştirmek için gereken tek şey bu, değil mi? + +### 1.2. GVCF'leri oluşturabildiğinizi doğrulamak için pipeline'ı çalıştırın + +Nextflow yürütme komutu daha öncekiyle aynıdır, iş akışı dosyası adının kendisi hariç. +Bunu uygun şekilde güncellediğinizden emin olun. + +```bash +nextflow run genomics-2.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_venter] DSL2 - revision: a2d6f6f09f + + executor > local (6) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [72/3249ca] GATK_HAPLOTYPECALLER (3) | 0 of 3 + ERROR ~ Error executing process > 'GATK_HAPLOTYPECALLER (2)' + + Caused by: + Missing output file(s) `reads_son.bam.vcf` expected by process `GATK_HAPLOTYPECALLER (2)` + + Command executed: + + gatk HaplotypeCaller -R ref.fasta -I reads_son.bam -O reads_son.bam.g.vcf -L intervals.bed -ERC GVCF + ``` + +Ve çıktı... tamamen kırmızı! Ah hayır. + +Yürütülen komut doğru, bu yüzden GATK aracının davranışını değiştirmek için bunun yeterli olduğu konusunda haklıydık. +Ancak eksik çıktı dosyasıyla ilgili o satıra bakın. Bir şey fark ettiniz mi? + +Evet, Nextflow'a yeni bir dosya adı beklemesini söylemeyi unuttuk. Hata. + +### 1.3. Süreç çıktıları bloğundaki çıktı dosyası uzantısını da güncelleyin + +Çünkü araç komutunun kendisinde dosya uzantısını değiştirmek yeterli değildir, Nextflow'a beklenen çıktı dosya adının değiştiğini de söylemeniz gerekir. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.g.vcf" , emit: vcf + path "${input_bam}.g.vcf.idx" , emit: idx + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="50" hl_lines="2 3" + output: + path "${input_bam}.vcf" , emit: vcf + path "${input_bam}.vcf.idx" , emit: idx + ``` + +### 1.4. Yeni GVCF çıktıları için yayın hedeflerini güncelleyin + +Artık VCF'ler yerine GVCF'ler ürettiğimize göre, iş akışının `publish:` bölümünü daha açıklayıcı isimler kullanacak şekilde güncellememiz gerekir. +Ayrıca netlik için GVCF dosyalarını kendi alt dizinlerine düzenleyeceğiz. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="88" hl_lines="3 4" + publish: + indexed_bam = SAMTOOLS_INDEX.out + gvcf = GATK_HAPLOTYPECALLER.out.vcf + gvcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="88" + publish: + indexed_bam = SAMTOOLS_INDEX.out + vcf = GATK_HAPLOTYPECALLER.out.vcf + vcf_idx = GATK_HAPLOTYPECALLER.out.idx + ``` + +### 1.5. Yeni dizin yapısı için çıktı bloğunu güncelleyin + +GVCF dosyalarını bir `gvcf` alt dizinine koymak için `output` bloğunu da güncellememiz gerekiyor. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="94" hl_lines="3 5 6 8 9" + output { + indexed_bam { + path 'indexed_bam' + } + gvcf { + path 'gvcf' + } + gvcf_idx { + path 'gvcf' + } + } + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="94" + output { + indexed_bam { + path '.' + } + vcf { + path '.' + } + vcf_idx { + path '.' + } + } + ``` + +### 1.6. Pipeline'ı tekrar çalıştırın + +Bu sefer `-resume` ile çalıştıralım. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [nostalgic_franklin] DSL2 - revision: f2c0a93c6a + + executor > local (3) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + ``` + +Bu sefer çalışıyor. + +Nextflow çıktısının kendisi (normal VCF modunda başarılı bir çalıştırmaya kıyasla) farklı görünmüyor, ancak şimdi alt dizinlerde düzenlenmiş `.g.vcf` dosyalarını ve ilgili dizin dosyalarını, üç örneğin tümü için bulabiliriz. + +??? abstract "Dizin içeriği (sembolik bağlantılar kısaltılmış)" + + ```console + results_genomics/ + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +GVCF dosyalarından birini açıp içinde gezinirseniz, GATK HaplotypeCaller'ın istendiği gibi GVCF dosyaları ürettiğini doğrulayabilirsiniz. + +### Çıkarım + +Tamam, bu Nextflow öğrenimi açısından minimaldi... +Ancak süreç çıktı bloğunun önemini yinelemek için güzel bir fırsattı! + +### Sırada ne var? + +Bir kanalın içeriğini toplamayı ve bunları tek bir girdi olarak bir sonraki sürece aktarmayı öğrenin. + +--- + +## 2. Tüm örnekler arasında GVCF verilerini toplayın ve birleştirin + +Şimdi tüm örnek başına GVCF'lerden verileri, yapmak istediğimiz birleşik genotipleme analizini destekleyen bir forma birleştirmemiz gerekiyor. + +### 2.1. GVCF'leri birleştirecek süreci tanımlayın + +Isınma bölümünde daha önce yaptığımızı hatırlayalım, GVCF'leri birleştirmek, sözde GenomicsDB formatında bir veri deposu üretecek olan GATK aracı GenomicsDBImport'un işidir. + +Bunun nasıl çalışacağını tanımlamak için, ısınma bölümünde daha önce kullandığımız komuta dayalı olarak yeni bir süreç yazalım. + +```groovy title="genomics-2.nf" linenums="66" +/* + * GVCF'leri GenomicsDB veri deposunda birleştirin + */ +process GATK_GENOMICSDB { + + container "community.wave.seqera.io/library/gatk4:4.5.0.0--730ee8817e436867" + + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + + output: + path "${cohort_name}_gdb" + + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +} +``` + +Ne düşünüyorsunuz, makul görünüyor mu? + +Hadi bağlayalım ve ne olacağını görelim. + +### 2.2. Varsayılan değeri olan bir `cohort_name` parametresi ekleyin + +Kohort için rastgele bir ad sağlamamız gerekiyor. +Eğitim serisinin ilerleyen bölümlerinde bu tür şeyler için örnek meta verilerinin nasıl kullanılacağını öğreneceksiniz, ancak şimdilik sadece `params` kullanarak bir CLI parametresi bildiriyoruz ve kolaylık için ona varsayılan bir değer veriyoruz. + +```groovy title="genomics-2.nf" linenums="16" + // Nihai çıktı dosyası için temel ad + cohort_name: String = "family_trio" +``` + +### 2.3. GATK_HAPLOTYPECALLER çıktılarını örnekler arasında toplayın + +`GATK_HAPLOTYPECALLER` sürecinin çıktı kanalını olduğu gibi takmış olsaydık, Nextflow süreci her örnek GVCF'si üzerinde ayrı ayrı çağırırdı. +Ancak, Nextflow'un üçünü de tek bir süreç çağrısına birlikte teslim edecek şekilde tüm üç GVCF'yi (ve dizin dosyalarını) paketlemek istiyoruz. + +İyi haber: Bunu `collect()` kanal operatörünü kullanarak yapabiliriz. `workflow` gövdesine, GATK_HAPLOTYPECALLER çağrısından hemen sonra aşağıdaki satırları ekleyelim: + +```groovy title="genomics-2.nf" linenums="118" +// Örnekler arasında varyant çağırma çıktılarını toplayın +all_gvcfs_ch = GATK_HAPLOTYPECALLER.out.vcf.collect() +all_idxs_ch = GATK_HAPLOTYPECALLER.out.idx.collect() +``` + +Bu biraz karmaşık görünüyor mu? Hadi bunu parçalara ayıralım ve sade bir dile çevirelim. + +1. `.out` özelliğini kullanarak başvurulan `GATK_HAPLOTYPECALLER` sürecinin çıktı kanalını alıyoruz. +2. Kanaldan çıkan her 'öğe' bir çift dosyadır: GVCF ve dizin dosyası, bu sırayla çünkü süreç çıktı bloğunda bu sırada listeleniyorlar. Kolaylıkla, son oturumda bu sürecin çıktılarını adlandırdığımız için (`emit:` kullanarak), bir yandan `.vcf` ekleyerek GVCF'leri, diğer yandan `.out` özelliğinden sonra `.idx` ekleyerek dizin dosyalarını seçebiliriz. Bu çıktıları adlandırmamış olsaydık, sırasıyla `.out[0]` ve `.out[1]` ile başvurmamız gerekirdi. +3. Tüm GVCF dosyalarını `all_gvcfs_ch` adlı yeni bir kanalda tek bir öğe halinde paketlemek için `collect()` kanal operatörünü ekliyoruz ve dizin dosyalarıyla aynısını yaparak `all_idxs_ch` adlı yeni kanalı oluşturuyoruz. + +!!! tip + + Burada tam olarak ne olduğunu gözünüzde canlandırmakta zorlanıyorsanız, kanal operatörlerini uygulamadan önce ve sonra kanalların içeriğini incelemek için `view()` operatörünü kullanabileceğinizi unutmayın. + +Elde edilen `all_gvcfs_ch` ve `all_idxs_ch` kanalları, yeni yazdığımız `GATK_GENOMICSDB` sürecine takacağımız şeylerdir. + +!!! note + + Merak ediyorsanız, GVCF'leri ve dizin dosyalarını ayrı ayrı topluyoruz çünkü GATK GenomicsDBImport komutu yalnızca GVCF dosya yollarını görmek istiyor. Neyse ki, Nextflow tüm dosyaları yürütme için birlikte sahnelediğinden, Bölüm 1'de BAM'ler ve dizinleri için yaptığımız gibi dosyaların sırası konusunda endişelenmemize gerek yok. + +### 2.4. GATK_GENOMICSDB'yi çalıştırmak için iş akışı bloğuna bir çağrı ekleyin + +Bir sürecimiz var ve girdi kanallarımız var. Sadece süreç çağrısını eklememiz gerekiyor. + +```groovy title="genomics-2.nf" linenums="122" + // GVCF'leri bir GenomicsDB veri deposunda birleştirin + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) +``` + +Tamam, her şey bağlandı. + +### 2.5. İş akışını çalıştırın + +Bakalım bu çalışacak mı. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [disturbed_bell] DSL2 - revision: 57942246cc + + executor > local (1) + [f1/8d8486] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [51/d350ea] GATK_GENOMICSDB | 0 of 1 + ERROR ~ Error executing process > 'GATK_GENOMICSDB' + + Caused by: + Process `GATK_GENOMICSDB` terminated with an error exit status (1) + + Command executed: + + gatk GenomicsDBImport -V reads_son.bam.g.vcf reads_father.bam.g.vcf reads_mother.bam.g.vcf -L intervals.bed --genomicsdb-workspace-path family_trio_gdb + ``` + +`-resume` ile çalıştırdığımız için oldukça hızlı çalışıyor, ancak başarısız oluyor! + +Ah. İyi tarafından bakarsak, Nextflow'un `GATK_GENOMICSDB` sürecini aldığını ve özellikle onu yalnızca bir kez çağırdığını görüyoruz. +Bu, `collect()` yaklaşımının bir noktaya kadar çalıştığını gösteriyor. +Ama, ve büyük bir ama, süreç çağrısı başarısız oldu. + +Yukarıdaki konsol çıktısını incelediğimizde, yürütülen komutun doğru olmadığını görebiliriz. + +Hatayı görebiliyor musunuz? +Bu kısma bakın: `-V reads_father.bam.g.vcf reads_son.bam.g.vcf reads_mother.bam.g.vcf` + +`gatk GenomicsDBImport`'a tek bir `-V` argümanı için birden fazla GVCF dosyası verdik, ancak araç her GVCF dosyası için ayrı bir `-V` argümanı bekliyor. + +Hatırlatma olarak, konteynerde çalıştırdığımız komut buydu: + +```bash +gatk GenomicsDBImport \ + -V reads_mother.g.vcf \ + -V reads_father.g.vcf \ + -V reads_son.g.vcf \ + -L /data/ref/intervals.bed \ + --genomicsdb-workspace-path family_trio_gdb +``` + +Bu demektir ki GVCF dosyaları paketimizi bir şekilde düzgün biçimlendirilmiş bir komut dizisine dönüştürmemiz gerekiyor. + +### 2.6. Her girdi GVCF'si için ayrı bir `-V` argümanı olan bir komut satırı oluşturun + +Nextflow'un Groovy'ye dayalı olmasının işe yaradığı yer burası, çünkü gerekli komut dizisini oluşturmak için oldukça basit bazı dizi manipülasyonları kullanmamıza izin verecek. + +Özellikle, bu sözdizimini kullanarak: `all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Bir kez daha, bunu bileşenlerine ayıralım. + +1. İlk olarak, `all_gvcfs` girdi kanalının içeriğini alıyoruz ve üzerine `.collect()` uyguluyoruz (daha önceki gibi). +2. Bu, paketteki her bir GVCF dosya yolunu **closure**'a, `{ gvcf -> "-V ${gvcf}" }` iletmemize izin verir; burada `gvcf` o GVCF dosya yolunu ifade eder. + Closure, dosya yolunun başına `-V ` eklemek için kullandığımız bir mini fonksiyondur, `"-V ${gvcf}"` biçiminde. +3. Ardından ayırıcı olarak tek bir boşlukla üç dizeyi birleştirmek için `.join(' ')` kullanırız. + +Somut bir örnekle şöyle görünür: + +1. Üç dosyamız var: + + `[A.ext, B.ext, C.ext]` + +2. Closure, dizeleri oluşturmak için her birini değiştirir: + + `"-V A.ext", "-V B.ext", "-V C.ext"` + +3. `.join(' ')` işlemi nihai dizeyi oluşturur: + + `"-V A.ext -V B.ext -V C.ext"` + +Bu dizeye sahip olduğumuzda, onu `def` anahtar sözcüğüyle tanımlanan yerel bir değişkene, `gvcfs_line`'a atayabiliriz: + +`def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ')` + +Tamam, dizi manipülasyon şeyimiz var. Nereye koyacağız? + +Bunu süreç tanımının içinde bir yere koymak istiyoruz, çünkü GVCF dosya yollarını sürece kanalize ettikten _sonra_ yapmak istiyoruz. +Bunun nedeni, Nextflow'un dosyaların kendilerini yürütme için doğru şekilde sahneleyebilmesi için onları dosya yolları olarak görmesi gerektiğidir. + +Ama süreçte _tam olarak nereye_ ekleyebiliriz? + +İlginç gerçek: `script:`'ten sonra ve `"""` öncesinde rastgele kod ekleyebilirsiniz! + +Harika, o halde dizi manipülasyon satırımızı oraya ekleyelim ve oluşturduğu birleştirilmiş dizeyi kullanmak için `gatk GenomicsDBImport` komutunu güncelleyelim. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="4" + script: + """ + gatk GenomicsDBImport \ + -V ${all_gvcfs} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +Bu, girdileri `gatk GenomicsDBImport`'a doğru şekilde sağlamak için gereken her şey olmalı. + +!!! tip + + `gatk GenomicsDBImport` komutunu güncellediğinizde, `${gvcfs_line}` değişkenini değiştirirken `-V ` önekini kaldırdığınızdan emin olun. + +### 2.7. GenomicsDB çıktısını beklendiği gibi oluşturduğunu doğrulamak için iş akışını çalıştırın + +Pekala, bakalım bu sorunu çözdü mü. + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [peaceful_gates] DSL2 - revision: ca0bf847ed + + executor > local (1) + [cc/fbc705] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ + [27/0d7eb9] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [76/d13861] GATK_GENOMICSDB | 1 of 1 ✔ + ``` + +Aha! Şimdi çalışıyor gibi görünüyor. + +İlk iki adım başarıyla atlandı ve üçüncü adım bu sefer harika çalıştı. +GenomicsDB veri deposu çalışma dizininde oluşturuldu ancak sonuçlara yayınlanmadı, çünkü bu sadece birleşik genotipleme için kullanacağımız bir ara formattır. + +Bu arada, çıktının tek bir dosya yerine bir dizin olmasını işlemek için özel bir şey yapmamız gerekmedi. + +### Çıkarım + +Artık bir kanaldan çıktıları nasıl toplayacağınızı ve bunları başka bir sürece tek bir girdi olarak nasıl paketleyeceğinizi biliyorsunuz. +Ayrıca girdileri uygun sözdizimi ile belirli bir araca sağlamak için bir komut satırının nasıl oluşturulacağını biliyorsunuz. + +### Sırada ne var? + +Aynı sürece ikinci bir komut eklemeyi öğrenin. + +--- + +## 3. Birleşik genotipleme adımını aynı sürecin parçası olarak çalıştırın + +Artık birleştirilmiş genomik varyant çağrılarına sahip olduğumuza göre, gerçekten önemsediğimiz nihai çıktıyı üretecek birleşik genotipleme aracını çalıştırabiliriz: kohort düzeyindeki varyant çağrılarının VCF'si. + +Lojistik nedenlerle, birleşik genotiplemeyi aynı sürecin içine dahil etmeye karar veriyoruz. + +### 3.1. Süreci GATK_GENOMICSDB'den GATK_JOINTGENOTYPING olarak yeniden adlandırın + +Süreç birden fazla araç çalıştıracağından, adını tek bir araç adından ziyade genel işleme atıfta bulunacak şekilde değiştiriyoruz. + +=== "Sonra" + + ```groovy title="genomics-2.nf" + /* + * GVCF'leri GenomicsDB veri deposunda birleştirin ve kohort düzeyinde çağrılar üretmek için birleşik genotipleme çalıştırın + */ + process GATK_JOINTGENOTYPING { + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" + /* + * GVCF'leri GenomicsDB veri deposunda birleştirin + */ + process GATK_GENOMICSDB { + ``` + +Süreç adlarınızı mümkün olduğunca açıklayıcı tutmayı unutmayın, meslektaşlarınız için —ve gelecekteki kendiniz için— okunabilirliği en üst düzeye çıkarmak için! + +### 3.2. Birleşik genotipleme komutunu GATK_JOINTGENOTYPING sürecine ekleyin + +Script bölümünün içinde birinci komuttan sonra ikinci komutu basitçe ekleyin. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="89" hl_lines="6-10" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + + gatk GenotypeGVCFs \ + -R ${ref_fasta} \ + -V gendb://${cohort_name}_gdb \ + -L ${interval_list} \ + -O ${cohort_name}.joint.vcf + """ + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="89" + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ + ``` + +İki komut, terminalden manuel olarak çalıştırsaydık aynı şekilde seri olarak çalıştırılacaktır. + +### 3.3. Referans genom dosyalarını GATK_JOINTGENOTYPING süreç girdi tanımlarına ekleyin + +İkinci komut referans genom dosyalarını gerektirdiğinden, bunları süreç girdilerine eklememiz gerekiyor. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="78" hl_lines="6-8" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + path ref_fasta + path ref_index + path ref_dict + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="78" + input: + path all_gvcfs + path all_idxs + path interval_list + val cohort_name + ``` + +Bunları yazmak can sıkıcı görünebilir, ancak unutmayın, bunları yalnızca bir kez yazarsınız ve ardından iş akışını bir milyon kez çalıştırabilirsiniz. Değer mi? + +### 3.4. Kohort düzeyindeki varyant çağrılarının VCF'sini yayacak şekilde süreç çıktı tanımını güncelleyin + +GenomicsDB veri deposunu kaydetmeyi gerçekten umursamıyoruz, bu sadece lojistik nedenlerle var olan bir ara formattır, bu yüzden istersek onu çıktı bloğundan kaldırabiliriz. + +Gerçekten ilgilendiğimiz çıktı, birleşik genotipleme komutu tarafından üretilen VCF'dir. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="87" hl_lines="2 3" + output: + path "${cohort_name}.joint.vcf" , emit: vcf + path "${cohort_name}.joint.vcf.idx" , emit: idx + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="87" + output: + path "${cohort_name}_gdb" + ``` + +Neredeyse bitti! + +### 3.5. Süreç çağrısını GATK_GENOMICSDB'den GATK_JOINTGENOTYPING'e güncelleyin + +İş akışı gövdesindeki süreç çağrısını GATK_GENOMICSDB'den GATK_JOINTGENOTYPING'e yeniden adlandırmayı unutmayalım. Ve bunu yaparken, birleşik genotipleme aracına sağlamamız gerektiğinden referans genom dosyalarını da girdi olarak eklemeliyiz. + +=== "Sonra" + + ```groovy title="genomics-2.nf" linenums="126" + // GVCF'leri bir GenomicsDB veri deposunda birleştirin ve birleşik genotipleme uygulayın + GATK_JOINTGENOTYPING( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name, + ref_file, + ref_index_file, + ref_dict_file + ) + ``` + +=== "Önce" + + ```groovy title="genomics-2.nf" linenums="126" + // GVCF'leri bir GenomicsDB veri deposunda birleştirin + GATK_GENOMICSDB( + all_gvcfs_ch, + all_idxs_ch, + intervals_file, + params.cohort_name + ) + ``` + +Artık süreç tamamen bağlandı. + +### 3.6. Birleşik VCF'yi yayın bölümüne ekleyin + +Yeni süreçten birleşik VCF çıktılarını yayınlamamız gerekiyor. +İş akışının `publish:` bölümüne bu satırları ekleyin: + +```groovy title="genomics-2.nf" linenums="145" + joint_vcf = GATK_JOINTGENOTYPING.out.vcf + joint_vcf_idx = GATK_JOINTGENOTYPING.out.idx +``` + +### 3.7. Birleşik VCF hedeflerini çıktı bloğuna ekleyin + +Son olarak, birleşik VCF dosyaları için çıktı hedefleri ekleyin. +Bu nihai çıktı olduğundan bunları sonuçlar dizininin köküne koyacağız. + +```groovy title="genomics-2.nf" linenums="157" + joint_vcf { + path '.' + } + joint_vcf_idx { + path '.' + } +``` + +Artık her şey tamamen bağlanmış olmalı. + +### 3.8. İş akışını çalıştırın + +Sonunda, değiştirilmiş iş akışını çalıştırabiliriz... + +```bash +nextflow run genomics-2.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + ┃ Launching `genomics-2.nf` [crazy_marconi] DSL2 - revision: 5da9afc841 + + executor > local (1) + [9a/c7a873] SAMTOOLS_INDEX (2) | 3 of 3, cached: 3 ✔ + [e4/4ed55e] GATK_HAPLOTYPECALLER (2) | 3 of 3, cached: 3 ✔ + [a6/7cc8ed] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Ve çalışıyor! + +Nihai çıktı dosyasını, `family_trio.joint.vcf`'i (ve dosya dizinini), sonuçlar dizininde bulacaksınız. + +??? abstract "Dizin içeriği (sembolik bağlantılar kısaltılmış)" + + ```console + results_genomics/ + ├── family_trio.joint.vcf -> */a6/7cc8ed*/family_trio.joint.vcf + ├── family_trio.joint.vcf.idx -> */a6/7cc8ed*/family_trio.joint.vcf.idx + ├── gvcf/ + │ ├── reads_father.bam.g.vcf -> */27/0d7eb9*/reads_father.bam.g.vcf + │ ├── reads_father.bam.g.vcf.idx -> */27/0d7eb9*/reads_father.bam.g.vcf.idx + │ ├── reads_mother.bam.g.vcf -> */e4/4ed55e*/reads_mother.bam.g.vcf + │ ├── reads_mother.bam.g.vcf.idx -> */e4/4ed55e*/reads_mother.bam.g.vcf.idx + │ ├── reads_son.bam.g.vcf -> */08/e95962*/reads_son.bam.g.vcf + │ └── reads_son.bam.g.vcf.idx -> */08/e95962*/reads_son.bam.g.vcf.idx + └── indexed_bam/ + ├── reads_father.bam -> */9a/c7a873*/reads_father.bam + ├── reads_father.bam.bai -> */9a/c7a873*/reads_father.bam.bai + ├── reads_mother.bam -> */f1/8d8486*/reads_mother.bam + ├── reads_mother.bam.bai -> */f1/8d8486*/reads_mother.bam.bai + ├── reads_son.bam -> */cc/fbc705*/reads_son.bam + └── reads_son.bam.bai -> */cc/fbc705*/reads_son.bam.bai + ``` + +Şüpheci tipteyseniz, birleşik VCF dosyasını açmak için tıklayabilir ve iş akışının bu bölümün başında araçları manuel olarak çalıştırarak elde ettiğiniz aynı varyant çağrılarını oluşturduğunu doğrulayabilirsiniz. + +```console title="family_trio.joint.vcf" linenums="40" +#CHROM POS +``` diff --git a/docs/tr/docs/nf4_science/genomics/03_modules.md b/docs/tr/docs/nf4_science/genomics/03_modules.md new file mode 100644 index 0000000000..d2f8b59c17 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/03_modules.md @@ -0,0 +1,246 @@ +# Bölüm 3: Kodu modüllere taşıma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun ilk bölümünde, tamamen doğrusal olan ve her örneğin verisini diğerlerinden bağımsız olarak işleyen bir varyant çağırma pipeline'ı oluşturdunuz. + +İkinci bölümde, Bölüm 1'deki pipeline üzerine inşa ederek GATK ile ortak varyant çağırmayı uygulamak için kanalları ve kanal operatörlerini nasıl kullanacağınızı gösterdik. + +Bu bölümde, o workflow'daki kodu modüllere nasıl dönüştüreceğinizi göstereceğiz. Bu eğitim bölümünü takip etmek için Bölüm 1 ve Bölüm 2'yi ve modüllerin temellerini kapsayan [Merhaba Modüller](../../../hello_nextflow/hello_modules.md) bölümünü tamamlamış olmanız gerekir. + +--- + +## 0. Isınma + +Workflow'umuzu geliştirmeye başladığımızda, her şeyi tek bir kod dosyasına koyduk. +Şimdi kodumuzu **modülerleştirme** zamanı, _yani_ process tanımlarını modüllere çıkarma. + +Bölüm 2'deki ile aynı workflow ile başlayacağız, bunu sizin için `genomics-3.nf` dosyasında sağladık. + +!!! note "Not" + + Doğru çalışma dizininde olduğunuzdan emin olun: + `cd /workspaces/training/nf4-science/genomics` + +Başlangıç noktasını doğrulamak için workflow'u çalıştırın: + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Çıktı" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [serene_borg] DSL2 - revision: 0cbebb67a1 + +executor > local (7) +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (1) | 3 of 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1 ✔ +``` + +Proje dizininizin içinde artık bir `work` dizini ve bir `results_genomics` dizini olacak. + +### Çıkarım + +Workflow'unuzu modülerleştirmeye başlamaya hazırsınız. + +### Sırada ne var? + +Genomics workflow'unun process'lerini modüllere taşıyın. + +--- + +## 1. Process'leri modüllere taşıma + +[Merhaba Modüller](../../../hello_nextflow/hello_modules.md) bölümünde öğrendiğiniz gibi, process tanımını herhangi bir dizindeki kendi dosyasına kopyalayarak bir modül oluşturabilirsiniz ve bu dosyaya istediğiniz adı verebilirsiniz. + +Daha sonra (özellikle teste geldiğimizde) netleşecek nedenlerle, bu eğitimde dosyayı `main.nf` olarak adlandırma ve araç kiti ile komuttan sonra adlandırılmış bir dizin yapısına yerleştirme konvansiyonunu takip edeceğiz. + +### 1.1. `SAMTOOLS_INDEX` process'i için bir modül oluşturma + +`SAMTOOLS_INDEX` process'i durumunda, 'samtools' araç kiti ve 'index' komuttur. Bu yüzden, `modules/samtools/index` dizin yapısını oluşturacağız ve `SAMTOOLS_INDEX` process tanımını bu dizinin içindeki `main.nf` dosyasına koyacağız. + +```bash +mkdir -p modules/samtools/index +touch modules/samtools/index/main.nf +``` + +`main.nf` dosyasını açın ve `SAMTOOLS_INDEX` process tanımını içine kopyalayın. + +```groovy title="modules/samtools/index/main.nf" linenums="1" +/* + * BAM dizin dosyası oluştur + */ +process SAMTOOLS_INDEX { + + container 'community.wave.seqera.io/library/samtools:1.20--b5dfbd93de237464' + + input: + path input_bam + + output: + tuple path(input_bam), path("${input_bam}.bai") + + script: + """ + samtools index '$input_bam' + """ +} +``` + +Ardından, `SAMTOOLS_INDEX` process tanımını `genomics-3.nf` dosyasından kaldırın ve bir sonraki process tanımından önce modül için bir import bildirimi ekleyin, şu şekilde: + +=== "Sonra" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1 2" + // Modülleri dahil et + include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' + + /* + * GATK HaplotypeCaller ile varyant çağır + */ + process GATK_HAPLOTYPECALLER { + ``` + +=== "Önce" + + ```groovy title="genomics-3.nf" linenums="1" hl_lines="1" + /* + * GATK HaplotypeCaller ile varyant çağır + */ + process GATK_HAPLOTYPECALLER { + ``` + +Artık workflow'u tekrar çalıştırabilirsiniz ve öncekiyle aynı şekilde çalışması gerekir. `-resume` bayrağını sağlarsanız, hiçbir yeni görevin çalıştırılması bile gerekmez: + +```bash +nextflow run genomics-3.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-3.nf` [sleepy_snyder] DSL2 - revision: aa68d06c43 + + [0f/71b55e] SAMTOOLS_INDEX (1) | 3 of 3, cached: 3 ✔ + [f1/18971b] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ + [0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ + ``` + +### 1.2. `GATK_HAPLOTYPECALLER` ve `GATK_JOINTGENOTYPING` process'leri için modüller oluşturma + +Kalan process'ler için aynı adımları tekrarlayın. +Her process için: + +1. Dizin yapısını oluşturun (`modules/gatk/haplotypecaller/` ve `modules/gatk/jointgenotyping/`) +2. Process tanımını içeren bir `main.nf` dosyası oluşturun +3. Process tanımını `genomics-3.nf` dosyasından kaldırın +4. Modül için bir import bildirimi ekleyin + +İşiniz bittiğinde, şunu çalıştırarak modüller dizin yapınızın doğru olduğunu kontrol edin: + +```bash +tree modules/ +``` + +??? abstract "Dizin içeriği" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + + 5 directories, 3 files + ``` + +Ana workflow dosyasında, parametreler bölümünden sonra şuna benzer bir şey de olmalıdır: + +``` +include { SAMTOOLS_INDEX } from './modules/samtools/index/main.nf' +include { GATK_HAPLOTYPECALLER } from './modules/gatk/haplotypecaller/main.nf' +include { GATK_JOINTGENOTYPING } from './modules/gatk/jointgenotyping/main.nf' + +workflow { +``` + +### Çıkarım + +Genomics workflow'u örnek olarak kullanarak bir workflow'u modülerleştirme pratiği yaptınız. + +### Sırada ne var? + +Modülerleştirilmiş workflow'u test edin. + +--- + +## 2. Modülerleştirilmiş workflow'u test etme + +Her şeyin hala çalıştığını doğrulamak için modülerleştirilmiş workflow'u çalıştırın. + +```bash +nextflow run genomics-3.nf -resume +``` + +```console title="Çıktı" + N E X T F L O W ~ version 25.10.2 + +Launching `genomics-3.nf` [astonishing_venter] DSL2 - revision: ca27264c13 + +[6f/83ee72] SAMTOOLS_INDEX (3) | 3 of 3, cached: 3 ✔ +[53/b9d342] GATK_HAPLOTYPECALLER (3) | 3 of 3, cached: 3 ✔ +[0c/fa6d15] GATK_JOINTGENOTYPING | 1 of 1, cached: 1 ✔ +``` + +Her şey hala çalışıyor, pipeline'ın yeniden başlatılabilirliği dahil. +Sonuçlar `results_genomics` dizinine yayınlanmaya devam ediyor. + +```console title="Dizin içeriği" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam + ├── reads_father.bam.bai + ├── reads_mother.bam + ├── reads_mother.bam.bai + ├── reads_son.bam + └── reads_son.bam.bai +``` + +### Çıkarım + +Bir workflow'u modülerleştirdiniz ve öncekiyle aynı şekilde çalıştığını doğruladınız. + +### Sırada ne var? + +Öğrendiklerinizi gözden geçirin ve teste ilerleyin. + +--- + +## 3. Özet + +Workflow'u modülerleştirdiniz ve pipeline'ın çalışma şeklinde hiçbir şey değişmedi. +Bu kasıtlıdır: kodu işlevselliğini etkilemeden yeniden yapılandırdınız. + +Modüller yalnızca process mantığını içerir, bu da onları temiz ve yeniden kullanılabilir yapar. +Ana betik neyin nereye yayınlanacağını kontrol ederken, modüller hesaplama görevi üzerine odaklanmış kalır. + +Kodunuzu sürdürmeyi kolaylaştıracak şeyler için bir temel oluşturdunuz. +Örneğin, artık nf-test framework'ü kullanarak pipeline'ınıza testler ekleyebilirsiniz. +Bu kursun bir sonraki bölümünde bakacağımız şey budur. diff --git a/docs/tr/docs/nf4_science/genomics/04_testing.md b/docs/tr/docs/nf4_science/genomics/04_testing.md new file mode 100644 index 0000000000..98afeb5551 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/04_testing.md @@ -0,0 +1,1266 @@ +# Bölüm 4: Test ekleme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun ilk bölümünde, tamamen doğrusal olan ve her örneğin verisini diğerlerinden bağımsız olarak işleyen bir varyant çağırma pipeline'ı oluşturdunuz. + +İkinci bölümde, GATK ile ortak varyant çağırma işlemini gerçekleştirmek için kanalları ve kanal operatörlerini nasıl kullanacağınızı gösterdik. + +Üçüncü bölümde, pipeline'ı modülerleştirdik. + +Eğitimin bu bölümünde, Nextflow ile iyi entegre olan ve pipeline'ınıza hem modül düzeyinde hem de workflow düzeyinde testler eklemeyi kolaylaştıran bir test framework'ü olan [**nf-test**](https://www.nf-test.com/) kullanımını göstereceğiz. Eğitimin bu bölümünü takip edebilmek için Bölüm 1, Bölüm 2 ve Bölüm 3'ü tamamlamış olmanız ve ayrıca nf-test'in temellerini ve test yapmanın neden önemli olduğunu kapsayan [nf-test yan görevi](../../side_quests/nf-test.md)'ni tamamlamış olmanız gerekmektedir. + +--- + +## 0. Isınma + +!!! note + + Doğru çalışma dizininde olduğunuzdan emin olun: + `cd /workspaces/training/nf4-science/genomics` + +Bu eğitim kursunun önceki bölümlerini tamamladıysanız, uygun modül dizin yapısına sahip genomik pipeline'ın çalışan bir versiyonuna sahip olmalısınız. + +??? abstract "Dizin içeriği" + + ```console + modules/ + ├── gatk + │ ├── haplotypecaller + │ │ └── main.nf + │ └── jointgenotyping + │ └── main.nf + └── samtools + └── index + └── main.nf + ``` + +Bu modül dizini, ihtiyacınız olması durumunda `solutions` dizininde bulunabilir. + +Bölüm 3'teki ile aynı workflow ile başlayacağız, bunu sizin için `genomics-4.nf` dosyasında sağladık. [nf-test yan görevi](../../side_quests/nf-test.md) için olduğu gibi, bu pipeline'daki üç process'e birkaç farklı türde test ekleyeceğiz ve ayrıca bir workflow düzeyinde test ekleyeceğiz. + +### 0.1. Workflow'un çalıştığını kontrol edin + +Test eklemeye başlamadan önce, workflow'un beklendiği gibi çalıştığından emin olun. + +```bash +nextflow run genomics-4.nf -resume +``` + +Bu eğitim kursunu baştan beri takip ediyorsanız, artık çok tanıdık gelmelidir. + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `genomics-4.nf` [gloomy_poincare] DSL2 - revision: 43203316e0 + + executor > local (7) + [18/89dfa4] SAMTOOLS_INDEX (1) | 3 of 3 ✔ + [30/b2522b] GATK_HAPLOTYPECALLER (2) | 3 of 3 ✔ + [a8/d2c189] GATK_JOINTGENOTYPING | 1 of 1 ✔ + ``` + +Daha önce olduğu gibi, şimdi proje dizininizin içinde bir `work` dizini ve bir `results_genomics` dizini olacak. Aslında bu sonuçları daha sonra testlerimizde kullanacağız. Ancak şu andan itibaren pipeline'ı test etmek için `nf-test` paketini kullanacağız. + +### 0.2. `nf-test`'i başlatın + +[nf-test yan görevi](../../side_quests/nf-test.md)'nde olduğu gibi, `nf-test` paketini başlatmamız gerekiyor. + +```bash +nf-test init +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + Project configured. Configuration is stored in nf-test.config + ``` + +??? abstract "nf-test.config içeriği" + + ```groovy title="nf-test.config" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Ayrıca bir yapılandırma dosyası taslağı içeren bir `tests` dizini oluşturur. + +### Çıkarım + +Artık genomik pipeline'ımız için testler yazmaya hazırız. + +### Sırada ne var? + +Process çağrılarının başarılı olduğunu ve doğru çıktılar ürettiğini değerlendiren temel testler yazın. + +--- + +## 1. Başarı ve eşleşen çıktılar için bir process'i test edin + +BAM dosyaları için verimli rastgele erişimi etkinleştirmek üzere indeks dosyaları oluşturan `SAMTOOLS_INDEX` process'ini test ederek başlayacağız. Bu iyi bir ilk test durumudur çünkü: + +1. Tek, iyi tanımlanmış bir girdiye (bir BAM dosyası) sahiptir +2. Tahmin edilebilir bir çıktı (bir BAI indeks dosyası) üretir +3. Çıktı, aynı girdiler için özdeş olmalıdır + +### 1.1. Bir test dosyası taslağı oluşturun + +İlk olarak, bir test dosyası taslağı oluşturun: + +```bash +nf-test generate process modules/samtools/index/main.nf +``` + +??? success "Komut çıktısı" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/samtools/index/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/samtools/index/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Bu, `main.nf` ile aynı dizinde bir dosya oluşturur. +Dosya gezgininde dizine gidebilir ve dosyayı açabilirsiniz, aşağıdaki kodu içermelidir: + +```groovy title="tests/modules/samtools/index/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Başlangıç onaylamaları [nf-test yan görevi](../../side_quests/nf-test.md)'nden tanıdık olmalıdır: + +- `assert process.success` process'in başarılı bir şekilde çalışmasını ve herhangi bir hata olmadan tamamlanmasını beklediğimizi belirtir. +- `snapshot(process.out).match()` çalıştırma sonucunun önceki bir çalıştırmada (varsa) elde edilen sonuçla özdeş olmasını beklediğimizi belirtir. + Bunu daha sonra daha ayrıntılı olarak tartışacağız. + +Bunu başlangıç noktası olarak kullanarak, samtools index process için doğru test girdilerini ve varsa parametreleri eklememiz gerekiyor. + +### 1.2. Test dosyasını taşıyın ve script yolunu güncelleyin + +Testi doldurma işine başlamadan önce, dosyayı kesin konumuna taşımamız gerekiyor. Her modül için bir dizin eklememizin nedenlerinden biri, artık her modülün `main.nf` dosyasıyla birlikte konumlanmış bir `tests` dizininde testleri gönderebilmemizdir. O dizini oluşturun ve test dosyasını oraya taşıyın. + +```bash +mkdir -p modules/samtools/index/tests +mv tests/modules/samtools/index/main.nf.test modules/samtools/index/tests/ +``` + +Şimdi test dosyasının `script` bölümünü göreceli bir yola basitleştirebiliriz: + +=== "Sonra" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "../main.nf" + process "SAMTOOLS_INDEX" + ``` + +=== "Önce" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process SAMTOOLS_INDEX" + script "modules/samtools/index/main.nf" + process "SAMTOOLS_INDEX" + ``` + +Bu, teste modülün `main.nf` dosyasını tam yolu belirtmek zorunda kalmadan nerede bulacağını söyler. + +### 1.3. SAMTOOLS_INDEX için test girdileri sağlayın + +Taslak dosya, `samtools index` girdisine uygun gerçek bir test girdisiyle değiştirmemiz gereken bir yer tutucu içerir. Uygun girdi, `data/bam` dizininde mevcut olan bir BAM dosyasıdır. + +=== "Sonra" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + ``` + +=== "Önce" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="14" + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + ``` + +### 1.4. Testi işlevselliğe göre adlandırın + +Daha önce öğrendiğimiz gibi, testi test bağlamında anlam ifade eden bir şeyle yeniden adlandırmak iyi bir uygulamadır. + +=== "Sonra" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should index reads_son.bam correctly") { + ``` + + Bu rastgele bir string alır, bu yüzden istediğimiz her şeyi koyabiliriz. + Burada dosya adına ve formatına atıfta bulunmayı seçiyoruz. + +=== "Önce" + + ```groovy title="modules/samtools/index/tests/main.nf.test" linenums="7" + test("Should run without failures") { + ``` + +### 1.5. Testi çalıştırın ve çıktıyı inceleyin + +Testi çalıştırın: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.717s) + Snapshots: + 1 created [Should index reads_son.bam correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 7.727s + ``` + +Daha önce öğrendiğimiz gibi, bu process'in başarısı hakkındaki temel onaylamayı doğruladı ve process'in çıktısına dayalı bir anlık görüntü dosyası oluşturdu. Anlık görüntü dosyasının içeriğini `tests/modules/samtools/index/tests/main.nf.test.snap` dosyasında görebiliriz: + +```json title="modules/samtools/index/tests/main.nf.test.snap" linenums="1" +{ + "Should index reads_son.bam correctly": { + "content": [ + { + "0": [ + [ + "reads_son.bam:md5,af5956d9388ba017944bef276b71d809", + "reads_son.bam.bai:md5,a2ca7b84998218ee77eff14af8eb8ca2" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-01-27T15:09:48.394063389" + } +} +``` + +Ayrıca testi tekrar çalıştırabilir ve çıktının anlık görüntüyle özdeş olduğu için geçtiğini görebiliriz: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.938s) + + + SUCCESS: Executed 1 tests in 7.987s + ``` + +### 1.6. SAMTOOLS_INDEX'e daha fazla test ekleyin + +Bazen çeşitli potansiyel sorunlar için test yaptığımızdan emin olmak için bir dizi farklı girdi dosyasını test etmek yararlıdır. Test verilerimizden üçlüdeki anne ve babanın BAM dosyaları için testler ekleyin. + +```groovy + test("Should index reads_mother.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + + test("Should index reads_father.bam correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Ardından testi tekrar çalıştırabilirsiniz: + +```bash +nf-test test modules/samtools/index/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (7.185s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (6.576s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (6.31s) + Snapshots: + 2 created [Should index reads_father.bam correctly, Should index reads_mother.bam correctly] + + + Snapshot Summary: + 2 created + + SUCCESS: Executed 3 tests in 20.117s + ``` + +`--update-snapshot` parametresinin etkisine atıfta bulunan uyarıya dikkat edin. + +!!! note + + Burada daha önce pipeline'ın bilimsel çıktılarını göstermek için kullandığımız test verilerini kullanıyoruz. + Bu testleri bir üretim ortamında çalıştırmayı planlıyor olsaydık, test amaçları için daha küçük girdiler üretmiş olurduk. + + Genel olarak, process işlevselliğini değerlendirmek için gerekli ve yeterli olan en küçük veri parçalarını kullanarak birim testleri mümkün olduğunca hafif tutmak önemlidir, aksi takdirde toplam çalışma süresi oldukça ciddi bir şekilde artabilir. + Düzenli olarak çalıştırılması çok uzun süren bir test paketi, uygunluk adına atlanması muhtemel bir test paketidir. + +### Çıkarım + +Bir genomik process için ilk modül testinizi yazdınız, `SAMTOOLS_INDEX`'in farklı BAM dosyaları için doğru şekilde indeks dosyaları oluşturduğunu doğruladınız. Test paketi şunları sağlar: + +1. Process başarıyla çalışır +2. İndeks dosyaları oluşturulur +3. Çıktılar çalıştırmalar arasında tutarlıdır +4. Process tüm örnek BAM dosyaları için çalışır + +### Sırada ne var? + +Genomik workflow'umuzdaki diğer process'ler için testlerin nasıl yazılacağını öğrenin, zincirleme process'leri ele almak için kurulum yöntemini kullanın. Ayrıca çıktıların, özellikle VCF dosyalarımızın, beklenen varyant çağrılarını içerip içermediğini değerlendireceğiz. + +--- + +## 2. Zincirleme bir process'e testler ekleyin ve içerik için test edin + +`GATK_HAPLOTYPECALLER`'ı test etmek için, process'e girdi olarak `SAMTOOLS_INDEX` çıktısını sağlamamız gerekiyor. Bunu `SAMTOOLS_INDEX`'i çalıştırarak, çıktılarını alarak ve bunları workflow için test verileriyle saklayarak yapabiliriz. Bu aslında cilalı bir pipeline için önerilen yaklaşımdır, ancak nf-test, `setup` yöntemini kullanarak alternatif bir yaklaşım sağlar. + +Setup yöntemiyle, test kurulumunun bir parçası olarak `SAMTOOLS_INDEX` process'ini tetikleyebilir ve ardından çıktısını `GATK_HAPLOTYPECALLER` için bir girdi olarak kullanabiliriz. Bunun bir maliyeti var: `GATK_HAPLOTYPECALLER` için testi her çalıştırdığımızda `SAMTOOLS_INDEX` process'ini çalıştırmak zorunda kalacağız. Ancak belki hala workflow'u geliştiriyoruz ve daha sonra değiştirmek zorunda kalabileceğimiz test verilerini önceden oluşturmak istemiyoruz. `SAMTOOLS_INDEX` process'i de çok hızlıdır, bu nedenle belki de çıktılarını önceden oluşturmanın ve saklamanın faydaları ihmal edilebilir düzeydedir. Setup yöntemi şu şekilde çalışır. + +### 2.1. Test dosyasını oluşturun ve yerleştirin + +Daha önce olduğu gibi, önce dosya taslağını oluştururuz: + +```bash +nf-test generate process modules/gatk/haplotypecaller/main.nf +``` + +??? success "Komut çıktısı" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/haplotypecaller/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/haplotypecaller/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Bu, aşağıdaki test taslağını üretir: + +```groovy title="tests/modules/gatk/haplotypecaller/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 2.2. Test dosyasını taşıyın ve script yolunu güncelleyin + +Modülün `main.nf` dosyasıyla birlikte konumlanmış test dosyası için bir dizin oluştururuz: + +```bash +mkdir -p modules/gatk/haplotypecaller/tests +``` + +Ve test taslak dosyasını oraya taşırız: + +```bash +mv tests/modules/gatk/haplotypecaller/main.nf.test modules/gatk/haplotypecaller/tests/ +``` + +Son olarak, script yolunu güncellemeyi unutmayın: + +=== "Sonra" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "../main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +=== "Önce" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_HAPLOTYPECALLER" + script "modules/gatk/haplotypecaller/main.nf" + process "GATK_HAPLOTYPECALLER" + ``` + +### 2.3. Setup yöntemini kullanarak girdiler sağlayın + +`when` bloğundan önce bir `setup` bloğu ekliyoruz, burada orijinal girdi dosyalarımızdan birinde `SAMTOOLS_INDEX` process'inin bir çalıştırmasını tetikleyebiliriz. Ayrıca, daha önce olduğu gibi test adını anlamlı bir şeyle değiştirmeyi unutmayın. + +=== "Sonra" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1-12" + test("Should call son's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_son.bam") + """ + } + } + } + + when { + ``` + +=== "Önce" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="7" hl_lines="1" + test("Should run without failures") { + + when { + ``` + +Daha sonra test girdilerini belirttiğimiz `when` bloğunda o process'in çıktısına başvurabiliriz: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="20" + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } +``` + +Bu değişikliği yapın ve testi tekrar çalıştırın: + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Snapshots: + 1 created [Should call son's haplotype correctly] + + + Snapshot Summary: + 1 created + + SUCCESS: Executed 1 tests in 40.555s + ``` + +Ayrıca daha önce olduğu gibi bir anlık görüntü dosyası üretir. + +### 2.4. Tekrar çalıştırın ve hatayı gözlemleyin + +İlginç bir şekilde, aynı komutu tekrar çalıştırırsanız, bu sefer test başarısız olacaktır. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? failure "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' FAILED (40.123s) + + java.lang.RuntimeException: Different Snapshot: + [ [ + { { + "0": [ "0": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ], ], + "1": [ "1": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "idx": [ "idx": [ + "reads_son.bam.g.vcf.idx:md5,dc36c18f2afdc546f41e68b2687e9334" | "reads_son.bam.g.vcf.idx:md5,dbad4b76a4b90c158ffc9c9740764242" + ], ], + "vcf": [ "vcf": [ + "reads_son.bam.g.vcf:md5,069316cdd4328542ffc6ae247b1dac39" | "reads_son.bam.g.vcf:md5,005f1a13ee39f11b0fc9bea094850eac" + ] ] + } } + ] ] + + Nextflow stdout: + + Nextflow stderr: + + + Obsolete snapshots can only be checked if all tests of a file are executed successful. + + + FAILURE: Executed 1 tests in 40.156s (1 failed) + ``` + +Hata mesajı size iki çalıştırma için anlık görüntüler arasında farklılıklar olduğunu söyler; özellikle, VCF dosyaları için md5sum değerleri farklıdır. + +Neden? Uzun lafın kısası, HaplotypeCaller aracı VCF başlığına her seferinde farklı olan bir zaman damgası ekler (tanım gereği). +Sonuç olarak, varyant çağrılarının kendileri açısından özdeş içeriğe sahip olsalar bile, dosyaların özdeş md5sum'lara sahip olmasını bekleyemeyiz. + +Bununla nasıl başa çıkıyoruz? + +### 2.5. Belirli bir varyantı kontrol etmek için bir içerik onaylama yöntemi kullanın + +Sorunu çözmenin bir yolu [farklı türde bir onaylama](https://nf-co.re/docs/contributing/tutorials/nf-test_assertions) kullanmaktır. +Bu durumda, özdeşlik onaylamak yerine belirli içerik için kontrol yapacağız. +Daha kesin olarak, aracın VCF dosyasının satırlarını okumasını ve belirli satırların varlığını kontrol etmesini sağlayacağız. + +Pratikte, `then` bloğundaki ikinci onaylamayı aşağıdaki gibi değiştiriyoruz: + +=== "Sonra" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3 4" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3282 GT:DP:GQ:MIN_DP:PL 0/0:25:72:24:0,72,719') + } + ``` + +=== "Önce" + + ```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="35" hl_lines="3" + then { + assert process.success + assert snapshot(process.out).match() + } + ``` + +Burada VCF çıktı dosyasının tam içeriğini okuyoruz ve bir içerik eşleşmesi arıyoruz, bunu küçük bir test dosyasında yapmak sorun değil, ancak bunu daha büyük bir dosyada yapmak istemezsiniz. +Bunun yerine belirli satırları okumayı seçebilirsiniz. + +Bu yaklaşım, test için 'sinyal' olarak ne kullanmak istediğimizi daha dikkatli seçmeyi gerektirir. +İyi tarafı, bir analiz aracının daha fazla geliştirme geçirirken 'zor' özellikleri (nadir varyantlar gibi) tutarlı bir şekilde tanımlayıp tanımlayamadığını büyük hassasiyetle test etmek için kullanılabilir. + +### 2.6. Tekrar çalıştırın ve başarıyı gözlemleyin + +Testi bu şekilde değiştirdiğimizde, testi birden çok kez çalıştırabiliriz ve tutarlı bir şekilde geçecektir. + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + + + SUCCESS: Executed 1 tests in 40.555s + ``` + +### 2.7. Daha fazla test ekleyin + +Anne ve baba örnekleri için benzer testler ekleyin: + +```groovy title="modules/gatk/haplotypecaller/tests/main.nf.test" linenums="43" + test("Should call mother's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_mother.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_mother') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3278 GT:DP:GQ:MIN_DP:PL 0/0:38:99:37:0,102,1530') + } + } + + test("Should call father's haplotype correctly") { + + setup { + run("SAMTOOLS_INDEX") { + script "../../../samtools/index/main.nf" + process { + """ + input[0] = file("${projectDir}/data/bam/reads_father.bam") + """ + } + } + } + + when { + params { + // define parameters here + } + process { + """ + input[0] = SAMTOOLS_INDEX.out + input[1] = file("${projectDir}/data/ref/ref.fasta") + input[2] = file("${projectDir}/data/ref/ref.fasta.fai") + input[3] = file("${projectDir}/data/ref/ref.dict") + input[4] = file("${projectDir}/data/ref/intervals.bed") + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3277 . G <NON_REF> . . END=3281 GT:DP:GQ:MIN_DP:PL 0/0:44:99:42:0,120,1800') + } + } +``` + +### 2.8. Test komutunu çalıştırın + +```bash +nf-test test modules/gatk/haplotypecaller/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (40.53s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (41.47s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (45.556s) + + + SUCCESS: Executed 3 tests in 127.586s + ``` + +Bu, pipeline'daki bu ikinci adım için temel test planını tamamlar. Üçüncü ve son modül düzeyinde teste geçiyoruz! + +### Çıkarım + +Şunları yapmayı öğrendiniz: + +1. Diğer process'lerin çıktılarına bağlı olan process'leri test etmek +2. VCF çıktı dosyalarında belirli genomik varyantları doğrulamak +3. Belirli içeriği kontrol ederek deterministik olmayan çıktıları ele almak +4. Birden çok örnek üzerinde varyant çağırmayı test etmek + +### Sırada ne var? + +Ortak genotipleme adımı için önceden oluşturulmuş test verilerini kullanan testlerin nasıl yazılacağını öğrenin. + +--- + +## 3. Önceden oluşturulmuş test verilerini kullanın + +Ortak genotipleme adımı için, farklı bir yaklaşım kullanacağız - önceden oluşturulmuş test verilerini kullanma. Bu genellikle şunlar için tercih edilir: + +1. Birden çok bağımlılığı olan karmaşık process'ler +2. Çalışması uzun süren process'ler +3. Kararlı, üretim pipeline'ının parçası olan process'ler + +### 3.1. Test verisi oluşturun + +Bu bölümün başında oluşturduğumuz sonuçları inceleyin: + +```bash +tree results_genomics/ +``` + +```console title="Sonuçlar dizini içeriği" +results_genomics/ +├── family_trio.joint.vcf +├── family_trio.joint.vcf.idx +├── gvcf +│ ├── reads_father.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf +│ ├── reads_father.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/30/b2522b83c63baff8c3cf75704512a2/reads_father.bam.g.vcf.idx +│ ├── reads_mother.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf +│ ├── reads_mother.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/f6/be2efa58e625d08cf8d0da1d0e9f09/reads_mother.bam.g.vcf.idx +│ ├── reads_son.bam.g.vcf -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf +│ └── reads_son.bam.g.vcf.idx -> /workspaces/training/nf4-science/genomics/work/fe/2f22d56aa16ed45f8bc419312894f6/reads_son.bam.g.vcf.idx +└── indexed_bam + ├── reads_father.bam -> /workspaces/training/nf4-science/genomics/work/42/a3bf19dbfaf1f3672b16a5d5e6a8be/reads_father.bam + ├── reads_father.bam.bai -> /workspaces/training/nf4-science/genomics/work/cf/289c2d264f496d60a69e3e9ba6463e/reads_father.bam.bai + ├── reads_mother.bam -> /workspaces/training/nf4-science/genomics/work/af/f31a6ade82cc0cf853c4f61c8bc473/reads_mother.bam + ├── reads_mother.bam.bai -> /workspaces/training/nf4-science/genomics/work/18/89dfa40a3def17e45421e54431a126/reads_mother.bam.bai + ├── reads_son.bam -> /workspaces/training/nf4-science/genomics/work/9f/9615dd553d6f13d8bec4f006ac395f/reads_son.bam + └── reads_son.bam.bai -> /workspaces/training/nf4-science/genomics/work/4d/cb384a97db5687cc9daab002017c7c/reads_son.bam.bai + +2 directories, 14 files +``` + +Ortak genotipleme adımı, indekslerle birlikte haplotip çağırma adımları tarafından üretilen VCF dosyalarına girdi olarak ihtiyaç duyar. O halde sahip olduğumuz sonuçları `jointgenotyping` modülünün test dizinine kopyalayalım. + +```bash +mkdir -p modules/gatk/jointgenotyping/tests/inputs/ +cp results_genomics/gvcf/*.g.vcf results_genomics/gvcf/*.g.vcf.idx modules/gatk/jointgenotyping/tests/inputs/ +``` + +Şimdi bu dosyaları ortak genotipleme adımı için yazacağımız testin girdileri olarak kullanabiliriz. + +### 3.2. Test dosyası taslağını oluşturun + +Daha önce olduğu gibi, önce dosya taslağını oluştururuz: + +```bash +nf-test generate process modules/gatk/jointgenotyping/main.nf +``` + +??? success "Komut çıktısı" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/modules/gatk/jointgenotyping/main.nf' + Wrote process test file '/workspaces/training/nf4-science/genomics/tests/modules/gatk/jointgenotyping/main.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Bu, aşağıdaki test taslağını üretir: + +```groovy title="tests/modules/gatk/jointgenotyping/main.nf.test" linenums="1" +nextflow_process { + + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +### 3.3. Test dosyasını taşıyın ve script yolunu güncelleyin + +Bu sefer zaten modülün `main.nf` dosyasıyla birlikte konumlanmış testler için bir dizinimiz var, bu yüzden test taslak dosyasını oraya taşıyabiliriz: + +```bash +mv tests/modules/gatk/jointgenotyping/main.nf.test modules/gatk/jointgenotyping/tests/ +``` + +Ve script yolunu güncellemeyi unutmayın: + +=== "Sonra" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "../main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +=== "Önce" + + ```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="3" hl_lines="2" + name "Test Process GATK_JOINTGENOTYPING" + script "modules/gatk/jointgenotyping/main.nf" + process "GATK_JOINTGENOTYPING" + ``` + +### 3.4. Girdileri sağlayın + +Process girdi tanımlarına göre girdileri doldurun ve testi buna göre yeniden adlandırın: + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="7" + test("Should call trio's joint genotype correctly") { + + when { + params { + // define parameters here + } + process { + """ + input[0] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf") + ] + input[1] = [ + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_father.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_mother.bam.g.vcf.idx"), + file("${projectDir}/modules/gatk/jointgenotyping/tests/inputs/reads_son.bam.g.vcf.idx") + ] + input[2] = file("${projectDir}/data/ref/intervals.bed") + input[3] = "family_trio" + input[4] = file("${projectDir}/data/ref/ref.fasta") + input[5] = file("${projectDir}/data/ref/ref.fasta.fai") + input[6] = file("${projectDir}/data/ref/ref.dict") + """ + } + } +``` + +### 3.5. İçerik onaylamalarını kullanın + +Ortak genotipleme adımının çıktısı başka bir VCF dosyasıdır, bu yüzden yine bir içerik onaylaması kullanacağız. + +```groovy title="modules/gatk/jointgenotyping/tests/main.nf.test" linenums="25" + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT reads_father reads_mother reads_son') + assert path(process.out[0][0]).readLines().contains('20_10037292_10066351 3480 . C CT 1625.89 . AC=5;AF=0.833;AN=6;BaseQRankSum=0.220;DP=85;ExcessHet=0.0000;FS=2.476;MLEAC=5;MLEAF=0.833;MQ=60.00;MQRankSum=0.00;QD=21.68;ReadPosRankSum=-1.147e+00;SOR=0.487 GT:AD:DP:GQ:PL 0/1:15,16:31:99:367,0,375 1/1:0,18:18:54:517,54,0 1/1:0,26:26:78:756,78,0') + } +``` + +Çıktı dosyasındaki belirli bir varyantın içeriğini kontrol ederek, bu test şunları doğrular: + +1. Ortak genotipleme process'i başarıyla çalışır +2. Çıktı VCF'si üç örneği de doğru sırayla içerir +3. Belirli bir varyant aşağıdaki bilgilerle doğru şekilde çağrılır: + - Her örnek için doğru genotipler (baba için 0/1, anne ve oğul için 1/1) + - Doğru okuma derinlikleri ve genotip kaliteleri + - Alel frekansı (AF=0.833) gibi popülasyon düzeyinde istatistikler + +Tüm dosyayı anlık görüntülemedik, ancak belirli bir varyantı kontrol ederek, ortak genotipleme process'inin beklendiği gibi çalıştığından emin olabiliriz. + +### 3.6. Testi çalıştırın + +```bash +nf-test test modules/gatk/jointgenotyping/tests/main.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (53.827s) + + + SUCCESS: Executed 1 tests in 53.837s + ``` + +Test geçer ve ortak genotipleme process'imizin şunları doğru yaptığını doğrular: + +1. Bireysel örnek VCF'lerini birleştirir +2. Ortak varyant çağırma gerçekleştirir +3. Çalıştırmalar arasında tutarlı genotip çağrılarıyla çok örnekli bir VCF üretir + +### Çıkarım + +Şunları yapmayı biliyorsunuz: + +- Testler için girdi olarak önceden oluşturulmuş sonuçları kullanmak +- Önceden oluşturulmuş test verilerini kullanarak testler yazmak + +### Sırada ne var? + +Tüm varyant çağırma pipeline'ının uçtan uca çalıştığını doğrulamak için bir workflow düzeyinde test ekleyin. + +--- + +## 4. Workflow düzeyinde test ekleyin + +Şimdi BAM dosyalarından ortak genotiplere kadar tam varyant çağırma pipeline'ını test edeceğiz. Bu şunları doğrular: + +1. Tüm process'ler doğru şekilde birlikte çalışır +2. Veriler adımlar arasında düzgün akar +3. Son varyant çağrıları tutarlıdır + +### 4.1. Workflow testini oluşturun + +Tam pipeline için bir test dosyası oluşturun: + +```bash +nf-test generate pipeline genomics-4.nf +``` + +??? success "Komut çıktısı" + + ```console + Load source file '/workspaces/training/nf4-science/genomics/genomics-4.nf' + Wrote pipeline test file '/workspaces/training/nf4-science/genomics/tests/genomics-4.nf.test' + + SUCCESS: Generated 1 test files. + ``` + +Bu, temel bir test taslağı oluşturur: + +```groovy title="tests/genomics-4.nf.test" linenums="1" +nextflow_pipeline { + + name "Test Workflow genomics-4.nf" + script "genomics-4.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Sadece adı anlamlı bir şeye düzeltin (bunun neden yararlı olduğunu kısa süre sonra göreceksiniz). + +=== "Sonra" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run the pipeline without failures") { + ``` + +=== "Önce" + + ```groovy title="tests/genomics-4.nf.test" linenums="6" hl_lines="1" + test("Should run without failures") { + ``` + +!!! note + + Bu durumda test dosyası `nf-test`'in oluşturduğu yerde kalabilir. + +### 4.2. Girdi parametrelerini belirtin + +Hala girdileri belirtmemiz gerekiyor, bu modül düzeyinde testlere göre workflow düzeyinde biraz farklı yapılır. +Bir profil belirlemek de dahil olmak üzere bunu yapmanın birkaç yolu vardır. +Ancak, daha basit bir yol, `nf-test init`'in `tests` dizininde başlangıçta oluşturduğu `nextflow.config` dosyasında bir `params {}` bloğu kurmaktır. + +```groovy title="tests/nextflow.config" linenums="1" +/* +======================================================================================== + Nextflow config file for running tests +======================================================================================== +*/ + +// Output directory for workflow outputs +outputDir = 'results_genomics' + +/* + * Pipeline parametreleri + */ + +params { + // Birincil girdi (satır başına bir tane olmak üzere girdi dosyalarının dosyası) + reads_bam = "${projectDir}/data/sample_bams.txt" + + // Yardımcı dosyalar + reference = "${projectDir}/data/ref/ref.fasta" + reference_index = "${projectDir}/data/ref/ref.fasta.fai" + reference_dict = "${projectDir}/data/ref/ref.dict" + intervals = "${projectDir}/data/ref/intervals.bed" + + // Son çıktı dosyası için temel ad + cohort_name = "family_trio" +} +``` + +Testi çalıştırdığımızda, `nf-test` bu yapılandırma dosyasını alacak ve girdileri buna göre çekecektir. + +### 4.3. Workflow testini çalıştırın + +```bash +nf-test test tests/genomics-4.nf.test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (171.019s) + + + SUCCESS: Executed 1 tests in 171.056s + ``` + +Test geçer ve tam varyant çağırma pipeline'ımızın şunları yaptığını onaylar: + +1. Tüm örnekleri başarıyla işler +2. Tüm adımları doğru şekilde zincirleme yapar + +### 4.4. TÜM testleri çalıştırın + +nf-test'in kolunda bir numara daha var. Tüm testleri aynı anda çalıştırabiliriz! `nf-test.config` dosyasını değiştirin, böylece nf-test her dizinde nf-test dosyalarını arar. Bunu `testsDir` parametresini değiştirerek yapabilirsiniz: + +=== "Sonra" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "." + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +=== "Önce" + + ```groovy title="nf-test.config" linenums="1" hl_lines="3" + config { + + testsDir "tests" + workDir ".nf-test" + configFile "tests/nextflow.config" + profile "" + + } + ``` + +Şimdi, sadece nf-test'i çalıştırabiliriz ve depomuzda _her bir testi_ çalıştıracaktır: + +```bash +nf-test test +``` + +??? success "Komut çıktısı" + + ```console + 🚀 nf-test 0.9.3 + https://www.nf-test.com + (c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + + Test Process GATK_HAPLOTYPECALLER + + Test [c5156c2b] 'Should call son's haplotype correctly' PASSED (39.947s) + Test [10de94a8] 'Should call mother's haplotype correctly' PASSED (43.17s) + Test [c0386fc7] 'Should call father's haplotype correctly' PASSED (44.244s) + + Test Process GATK_JOINTGENOTYPING + + Test [ac2067de] 'Should call trio's joint genotype correctly' PASSED (61.129s) + + Test Process SAMTOOLS_INDEX + + Test [625e39ee] 'Should index reads_son.bam correctly' PASSED (8.671s) + Test [a8b28f36] 'Should index reads_mother.bam correctly' PASSED (8.518s) + Test [c15852a1] 'Should index reads_father.bam correctly' PASSED (5.378s) + + Test Workflow genomics-4.nf + + Test [1b4c6936] 'Should run the pipeline without failures' PASSED (169.714s) + + + SUCCESS: Executed 8 tests in 380.801s + ``` + +1 komutta 8 test! Çok sayıda test yapılandırmak için uzun zaman harcadık, ancak onları çalıştırmaya gelince çok hızlı ve kolaydı. Testleri bir kez yazmak için zaman harcadığımızı, böylece onları birçok kez çalıştırmaktan zaman kazanabileceğimizi görebilirsiniz. + +Ayrıca, bunu otomatikleştirebiliriz! Siz veya bir meslektaşınız yeni kod eklemeye çalıştığında testlerin her seferinde çalıştığını hayal edin. Pipeline'larımızın yüksek bir standart korumasını sağlamamızın yolu budur. + +## Çıkarım + +Artık nf-test kullanarak genomik pipeline'ınız için çeşitli testlerin nasıl yazılacağını ve çalıştırılacağını biliyorsunuz. Bu test framework'ü, varyant çağırma workflow'unuzun farklı ortamlarda ve kod değişiklikleri yaptığınızda tutarlı, güvenilir sonuçlar üretmesini sağlamaya yardımcı olur. + +Şu kritik bileşenleri test etmeyi öğrendiniz: + +- Varyant çağırma için BAM dosyalarını hazırlayan `SAMTOOLS_INDEX` process'i +- Bireysel örneklerde varyantları tanımlayan `GATK_HAPLOTYPECALLER` process'i +- Bir kohort genelinde varyant çağrılarını birleştiren `GATK_JOINTGENOTYPING` process'i + +Ayrıca genomik verilere özgü farklı test stratejileri uyguladınız: + +- Zaman damgaları gibi deterministik olmayan öğelere rağmen VCF dosyalarının beklenen varyant çağrılarını içerdiğini doğrulamak +- İlgili örnekler arasında uygun varyant tanımlamasını sağlamak için bir aile üçlüsü veri setiyle test etmek +- Çıktı dosyalarınızda belirli genomik koordinatları ve varyant bilgilerini kontrol etmek + +Bu test becerileri, diff --git a/docs/tr/docs/nf4_science/genomics/05_configuration.md b/docs/tr/docs/nf4_science/genomics/05_configuration.md new file mode 100644 index 0000000000..e387e46bb5 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/05_configuration.md @@ -0,0 +1,91 @@ +# Bölüm 3: Kaynak profilleme ve optimizasyon + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +BU BİR YER TUTUCUDUR + +!!!note "Not" + + Bu eğitim modülü yeniden geliştirilme aşamasındadır. + +--- + +YAPILACAK + +### 1.1. Kaynak kullanım raporu oluşturmak için iş akışını çalıştırın + +Nextflow'un raporu otomatik olarak oluşturmasını sağlamak için komut satırınıza `-with-report <dosyaadi>.html` ekleyin. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-1.html +``` + +Rapor bir html dosyasıdır, tarayıcınızda indirebilir ve açabilirsiniz. Ayrıca soldaki dosya gezgininde sağ tıklayıp `Show preview`'e tıklayarak VS Code içinde görüntüleyebilirsiniz. + +Raporu incelemek için birkaç dakika ayırın ve kaynak ayarlamalarını yapabileceğiniz bazı fırsatları belirlemeye çalışın. +Kullanım sonuçlarını ayrılan kaynakların yüzdesi olarak gösteren sekmelere tıkladığınızdan emin olun. +Tüm mevcut özellikleri açıklayan [dokümantasyon](https://www.nextflow.io/docs/latest/reports.html) mevcuttur. + +<!-- TODO: insert images --> + +Bir gözlem, `GATK_JOINTGENOTYPING`'in CPU açısından oldukça açgözlü göründüğüdür; bu mantıklıdır çünkü çok sayıda karmaşık hesaplama gerçekleştirir. +Bu nedenle bunu artırmayı deneyebilir ve çalışma süresini kısaltıp kısaltmadığına bakabiliriz. + +Ancak, bellek tahsislerinde hedefi aşmış görünüyoruz; tüm görevler yalnızca onlara verdiğimizin bir kısmını kullanıyor. +Bunu geri çekmeli ve bazı kaynakları tasarruf etmeliyiz. + +### 1.2. Belirli bir görev için kaynak tahsislerini ayarlayın + +Belirli bir görev için kaynak tahsisleri belirtmek üzere `withName` process seçicisini kullanabiliriz. +Process bloğunda tek başına olduğunda sözdizimi şu şekilde görünür: + +```groovy title="Sözdizimi" +process { + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Bunu `nextflow.config` dosyasındaki mevcut process bloğuna ekleyelim. + +```groovy title="nextflow.config" linenums="11" +process { + // tüm görevler için varsayılanlar + cpus = 2 + memory = 2.GB + // belirli bir görev için tahsisler + withName: 'GATK_JOINTGENOTYPING' { + cpus = 4 + } +} +``` + +Bu şekilde belirtildiğinde, varsayılan ayarlar tüm görevlere uygulanacaktır **hariç** `GATK_JOINTGENOTYPING` görevi, bu özel bir durumdur ve çok daha fazla CPU alır. +Umarım bunun bir etkisi olur. + +### 1.3. Değiştirilmiş yapılandırma ile tekrar çalıştırın + +İş akışını değiştirilmiş yapılandırma ile ve raporlama bayrağı açık şekilde tekrar çalıştıralım, ancak onları ayırt edebilmek için rapora farklı bir ad verdiğimize dikkat edin. + +```bash +nextflow run main.nf -profile my_laptop -with-report report-config-2.html +``` + +Bir kez daha, çalışma süresinde önemli bir fark fark etmeyebilirsiniz, çünkü bu çok küçük bir iş yükü ve araçlar 'gerçek' işi yapmaktan çok yardımcı görevlerde daha fazla zaman harcıyor. + +Ancak, ikinci rapor kaynak kullanımımızın artık daha dengeli olduğunu gösteriyor. + +<!-- **TODO: screenshots?** --> + +Gördüğünüz gibi, bu yaklaşım görevleriniz farklı kaynak gereksinimleri olduğunda faydalıdır. Tahminlere değil, gerçek verilere dayanarak her görev için ayarladığınız kaynak tahsislerini doğru boyutlandırmanızı sağlar. + +!!!note "Not" + + Bu, kaynaklarınızı optimize etmek için yapabileceklerinizin sadece küçük bir tadımlığıdır. + Nextflow'un kendisinde kaynak sınırlamaları nedeniyle başarısız olan işleri yeniden denemek için gerçekten güzel bir [dinamik yeniden deneme mantığı](https://www.nextflow.io/docs/latest/process.html#dynamic-task-resources) bulunmaktadır. + Ek olarak, Seqera Platform kaynak tahsislerinizi otomatik olarak optimize etmek için yapay zeka destekli araçlar sunar. + + Bu eğitim kursunun yaklaşan bir bölümünde bu yaklaşımların her ikisini de ele alacağız. + +Bununla birlikte, hangi computing executor ve bilgi işlem altyapısını kullandığınıza bağlı olarak tahsis edebileceğiniz (veya etmeniz gereken) konusunda bazı kısıtlamalar olabilir. Örneğin, kümeniz başka yerde çalıştırırken geçerli olmayan belirli sınırlar içinde kalmanızı gerektirebilir. diff --git a/docs/tr/docs/nf4_science/genomics/index.md b/docs/tr/docs/nf4_science/genomics/index.md new file mode 100644 index 0000000000..ec10794cb9 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/index.md @@ -0,0 +1,36 @@ +# Genomik için Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu eğitim kursu, veri analizi pipeline'larını geliştirmek veya özelleştirmek isteyen genomik ve ilgili alanlardaki araştırmacılar için tasarlanmıştır. +[Hello Nextflow](../../hello_nextflow/) başlangıç eğitimi üzerine inşa edilmiştir ve Nextflow'un genomik alanının özel bağlamında nasıl kullanılacağını gösterir. + +Özellikle bu kurs, yüksek verimli dizileme verilerini analiz etmek için yaygın olarak kullanılan bir yazılım paketi olan [GATK](https://gatk.broadinstitute.org/) (Genome Analysis Toolkit) ile basit bir varyant çağırma pipeline'ının nasıl uygulanacağını göstermektedir. + +Haydi başlayalım! Eğitim ortamını başlatmak için aşağıdaki "Open in GitHub Codespaces" düğmesine tıklayın (tercihen ayrı bir sekmede), ardından yüklenirken okumaya devam edin. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Öğrenme hedefleri + +Bu kursta çalışarak, temel Nextflow kavramlarını ve araçlarını tipik bir genomik kullanım senaryosuna nasıl uygulayacağınızı öğreneceksiniz. + +Bu atölye çalışmasının sonunda şunları yapabileceksiniz: + +- Tek bir örneğe varyant çağırma uygulamak için doğrusal bir workflow yazma +- Dizin dosyaları ve referans genom kaynakları gibi yardımcı dosyaları uygun şekilde işleme +- Örnek başına varyant çağırmayı paralelleştirmek için Nextflow'un veri akışı paradigmasından yararlanma +- İlgili channel operatörlerini kullanarak çok örnekli varyant çağırma uygulama +- Genomik-spesifik özgünlükleri uygun şekilde işleyen adım başına ve uçtan uca pipeline testleri uygulama + +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Ön koşullar + +Kurs aşağıdakilerle ilgili minimal bir aşinalık varsayar: + +- Bu bilimsel alanda yaygın olarak kullanılan araçlar ve dosya formatları +- Komut satırı deneyimi +- [Hello Nextflow](../../hello_nextflow/) başlangıç eğitiminde kapsanan temel Nextflow kavramları ve araçları + +Teknik gereksinimler ve ortam kurulumu için [Ortam Kurulumu](../../envsetup/) mini-kursuna bakın. diff --git a/docs/tr/docs/nf4_science/genomics/next_steps.md b/docs/tr/docs/nf4_science/genomics/next_steps.md new file mode 100644 index 0000000000..a4f8124c67 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/next_steps.md @@ -0,0 +1,50 @@ +# Sonraki Adımlar + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For Genomics eğitim kursunu tamamladığınız için tekrar tebrikler ve anketimizi doldurduğunuz için teşekkür ederiz! + +--- + +## 1. Nextflow becerilerinizi geliştirmenin en iyi 3 yolu + +Az önce tamamladığınız kursa dayanarak, sırada ne yapmanızı önerdiğimize dair en iyi üç tavsiyemiz. + +### 1.1. Nextflow'u diğer bilimsel analiz kullanım senaryolarına uygulayın + +**Diğer kısa bağımsız kursların listesi için [Nextflow for Science](../index.md) sayfasına göz atın**. Bu kurslar, Hello Nextflow'da sunulan temel kavramların ve mekanizmaların yaygın bilimsel analiz kullanım senaryolarına nasıl uygulanacağını gösterir. + +Alanınızın ilişkilendirebileceğiniz bir kullanım senaryosu ile temsil edilmediğini görüyorsanız, geliştirme listemize ekleyebilmemiz için bize [Topluluk forumunda](https://community.seqera.io/) bildirin. + +### 1.2. nf-core ile başlayın + +**[nf-core](https://nf-co.re/)**, geniş bir bilimsel araştırma uygulamaları yelpazesi için standartlaştırılmış açık kaynaklı pipeline'lar geliştirmeye yönelik dünya çapında bir işbirliği çabasıdır. +Proje, kullanıma hazır [100'den fazla pipeline](https://nf-co.re/pipelines/) ve kendi projelerinize entegre edilebilecek [1400'den fazla process modülü](https://nf-co.re/modules/)'nün yanı sıra zengin bir geliştirici araçları seti içerir. + +**[Hello nf-core](../../hello_nf-core/index.md)** eğitim kursu, sizi nf-core topluluk tarafından düzenlenmiş pipeline'lar ve geliştirme çerçevesi ile tanıştıracaktır. Bu çerçeve, tekrarlanabilir, ölçeklenebilir ve standartlaştırılmış iş akışları yazmanıza yardımcı olmak için tasarlanmıştır. Mevcut nf-core pipeline'larını nasıl kullanacağınızı, geliştirilmelerine nasıl katkıda bulunacağınızı ve hatta en iyi uygulamalar ve canlı bir topluluk desteğiyle kendinizinkini oluşturmaya nasıl başlayacağınızı öğreneceksiniz. Nextflow becerilerinizi gerçek dünya projelerinde uygulamaya hazırsanız, bu mükemmel bir sonraki adımdır. + +### 1.3. Daha gelişmiş Nextflow özelliklerinde ustalaşın + +Hello kurslarında, sizi Nextflow ile başlamak için ihtiyacınız olmayan bilgilerle aşırı yüklemekten kaçınmak amacıyla teknik karmaşıklık seviyesini kasıtlı olarak düşük tutuyoruz. +Çalışmanızla ilerledikçe, Nextflow'un tam özellik setini ve gücünü nasıl kullanacağınızı öğrenmek isteyeceksiniz. + +Bu amaçla, şu anda test etme ve metadata işleme gibi belirli konulara derinlemesine inen kısa bağımsız kurslar olması amaçlanan bir **[Side Quests](../side_quests/index.md) koleksiyonu** üzerinde çalışıyoruz. + +--- + +## 2. Seqera Platform'a göz atın + +**[Seqera Platform](https://seqera.io/), pratikte Nextflow çalıştırmanın en iyi yoludur.** + +Nextflow'un yaratıcıları tarafından geliştirilen, kendi bilgi işlem altyapınıza (ister yerel, ister HPC veya bulut olsun) bağlanabileceğiniz bulut tabanlı bir platformdur. Bu platform, iş akışlarınızı başlatmayı ve yönetmeyi, ayrıca verilerinizi yönetmeyi ve analizleri bulut ortamında etkileşimli olarak çalıştırmayı çok daha kolay hale getirir. + +Ücretsiz Katman, herkes tarafından ücretsiz kullanım için mevcuttur (kullanım kotaları ile). +Nitelikli akademisyenler, [Akademik Program](https://seqera.io/academic/program/) aracılığıyla ücretsiz Pro seviyesi erişimi (kullanım sınırlaması olmadan) alabilirler. + +Bunun size faydalı olup olmayacağını görmek için [Seqera Platform eğitimlerine](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) göz atın. + +--- + +### Şimdilik bu kadar! + +**Nextflow yolculuğunuzda iyi şanslar ve size yardımcı olmak için başka neler yapabileceğimizi [Topluluk forumunda](https://community.seqera.io/) bize bildirmekten çekinmeyin.** diff --git a/docs/tr/docs/nf4_science/genomics/survey.md b/docs/tr/docs/nf4_science/genomics/survey.md new file mode 100644 index 0000000000..ca68ec32d1 --- /dev/null +++ b/docs/tr/docs/nf4_science/genomics/survey.md @@ -0,0 +1,9 @@ +# Geri bildirim anketi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Devam etmeden önce, lütfen eğitimi değerlendirmek, deneyiminiz hakkındaki geri bildirimlerinizi paylaşmak ve Nextflow yolculuğunuzda size yardımcı olmak için başka neler yapabileceğimizi bildirmek üzere bu kısa 5 soruluk anketi tamamlayın. + +Bu anketin tamamlanması bir dakikadan daha kısa sürecektir. Eğitim materyallerimizi herkes için geliştirmemize yardımcı olduğunuz için teşekkür ederiz! + +<div data-tf-live="01JWWJP7GKFMSDV16VEDVCKM6G"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/tr/docs/nf4_science/imaging/00_orientation.md b/docs/tr/docs/nf4_science/imaging/00_orientation.md new file mode 100644 index 0000000000..9812f5b359 --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/00_orientation.md @@ -0,0 +1,55 @@ +# Yönlendirme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu yönlendirme, "Open in GitHub Codespaces" düğmesine tıklayarak eğitim ortamını zaten açtığınızı varsayar. +Henüz açmadıysanız, lütfen şimdi açın; ideal olarak ikinci bir tarayıcı penceresi veya sekmesinde açarak bu talimatlara geri dönebilirsiniz. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=master&repo=290790519&skip_quickstart=true&machine=premiumLinux&devcontainer_path=.devcontainer%2Fdevcontainer.json) + +!!!warning "Makine boyutu gereksinimi" + + Bu eğitim kursu için Codespace oluştururken mutlaka **8 çekirdekli makine** seçtiğinizden emin olun. Biyogörüntüleme iş akışları ek hesaplama kaynakları gerektirir. + +## GitHub Codespaces + +GitHub Codespaces ortamı, bu eğitim kursunda çalışmak için gerekli tüm yazılımı, kodu ve veriyi içerir, bu nedenle kendiniz herhangi bir şey yüklemenize gerek yoktur. +Ancak, giriş yapmak için (ücretsiz) bir GitHub hesabına ihtiyacınız var ve arayüze aşina değilseniz, [GitHub Codespaces Yönlendirmesi](../../envsetup/index.md) mini kursunu tamamlayarak birkaç dakikanızı ayırıp arayüze alışmalısınız. + +## Docker imajlarını önceden indirin + +Codespace'inizi açtıktan sonra, bu eğitim kursu için ihtiyaç duyacağımız tüm Docker imajlarını önceden indirelim. +Bu, daha sonra zaman kazandıracak ve iş akışlarının sorunsuz çalışmasını sağlayacaktır. + +Yeni bir terminal sekmesi açın ve aşağıdaki komutu çalıştırın: + +```bash +nextflow run nf-core/molkart -profile docker,test -stub -resume --outdir results +``` + +Bu komut, gerekli tüm Docker imajlarını arka planda indirecektir. +Bu çalışırken yönlendirmenin geri kalanıyla devam edebilirsiniz. + +!!!tip "İpucu" + + `-stub` bayrağı, pipeline'ın gerçek veri işlemeden hızlıca çalışmasını sağlar, bu da imajları indirmek için mükemmeldir. Terminal sekmesinde ilerlemeyi izleyebilirsiniz. + +## Çalışma dizini + +Bu eğitim kursu boyunca, `nf4-science/imaging/` dizininde çalışacağız. + +Şimdi terminalde şu komutu çalıştırarak dizini değiştirin: + +```bash +cd nf4-science/imaging/ +``` + +!!!tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız, GitHub Codespaces eğitim ortamında çalıştığınızı varsayarak, her zaman tam yolu kullanarak geri dönebilirsiniz: + + ```bash + cd /workspaces/training/nf4-science/imaging + ``` + +**Şimdi, kursa başlamak için bu sayfanın sağ alt köşesindeki oka tıklayın.** diff --git a/docs/tr/docs/nf4_science/imaging/01_basics.md b/docs/tr/docs/nf4_science/imaging/01_basics.md new file mode 100644 index 0000000000..1b4401d7bb --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/01_basics.md @@ -0,0 +1,410 @@ +# Bölüm 1: Temel işlemleri çalıştırın + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow for Bioimaging eğitim kursunun bu ilk bölümünde, temel işlemleri göstermek ve ilgili Nextflow kod bileşenlerine işaret etmek için çok basit, alan-bağımsız bir Hello World örneği kullanacağız. + +## 1. Workflow'u çalıştırın + +Size `hello-world.nf` adında, `--greeting` adlı bir komut satırı argümanı aracılığıyla girdi alan ve bu selamlamayı içeren bir metin dosyası üreten bir workflow betiği sağlıyoruz. +Henüz koda bakmayacağız; önce çalıştırmanın nasıl göründüğünü görelim. + +### 1.1. Workflow'u başlatın ve çalışmayı izleyin + +Terminalde aşağıdaki komutu çalıştırın: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' +``` + +Konsol çıktınız şuna benzer görünmelidir: + +```console title="Çıktı" linenums="1" + N E X T F L O W ~ version 25.04.3 + +Launching `hello-world.nf` [goofy_torvalds] DSL2 - revision: c33d41f479 + +executor > local (1) +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Tebrikler, ilk Nextflow workflow'unuzu çalıştırdınız! + +Buradaki en önemli çıktı son satırdır (satır 6): + +```console title="Çıktı" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Bu bize `sayHello` sürecinin bir kez başarıyla çalıştırıldığını söylüyor (`1 of 1 ✔`). + +Bu harika, ancak merak ediyor olabilirsiniz: çıktı nerede? + +### 1.2. `results` dizininde çıktı dosyasını bulun + +Bu workflow, çıktısını `results` adlı bir dizine yayınlamak üzere yapılandırılmıştır. +Mevcut dizininize bakarsanız, workflow'u çalıştırdığınızda Nextflow'un `results` adında yeni bir dizin oluşturduğunu göreceksiniz; bu dizin `output.txt` adlı bir dosya içerir. + +```console title="results/" linenums="1" +results +└── output.txt +``` + +Dosyayı açın; içeriği komut satırında belirttiğiniz selamlama ile eşleşmelidir. + +<details> + <summary>Dosya içeriği</summary> + +```console title="results/output.txt" linenums="1" +Hello World! +``` + +</details> + +Harika, workflow'umuz yapması gerekeni yaptı! + +Ancak, 'yayınlanmış' sonucun, Nextflow'un workflow'u çalıştırırken ürettiği gerçek çıktının bir kopyası (veya bazı durumlarda bir sembolik bağlantısı) olduğunu unutmayın. + +Şimdi, Nextflow'un çalışmayı gerçekte nerede yürüttüğünü görmek için kaputun altına bakacağız. + +!!! warning "Uyarı" + + Tüm workflow'lar çıktıları bir results dizinine yayınlayacak şekilde ayarlanmamış olabilir ve/veya dizin adı farklı olabilir. + Bu bölümde biraz ilerledikten sonra, bu davranışın nerede belirtildiğini nasıl öğreneceğinizi göstereceğiz. + +### 1.3. `work/` dizininde orijinal çıktıyı ve günlükleri bulun + +Bir workflow çalıştırdığınızda, Nextflow workflow'daki her sürecin her çağrısı için (=pipeline'daki her adım) ayrı bir 'görev dizini' oluşturur. +Her biri için gerekli girdileri hazırlar, ilgili komut(lar)ı çalıştırır ve o dizin içinde çıktıları ve günlük dosyalarını yazar; dizin benzersiz hale getirmek için otomatik olarak bir hash kullanılarak adlandırılır. + +Tüm bu görev dizinleri, mevcut dizininizin içinde (komutu çalıştırdığınız yerde) `work` adlı bir dizin altında bulunacaktır. + +Bu kafa karıştırıcı gelebilir, o yüzden pratikte bunun nasıl göründüğünü görelim. + +Daha önce çalıştırdığımız workflow'un konsol çıktısına geri dönersek, şu satırımız vardı: + +```console title="Komut çıktısından alıntı" linenums="6" +[a3/7be2fa] sayHello | 1 of 1 ✔ +``` + +Satırın `[a3/7be2fa]` ile nasıl başladığını görüyor musunuz? +Bu, o süreç çağrısı için görev dizini yolunun kısaltılmış bir biçimidir ve `sayHello` süreç çağrısının çıktısını `work/` dizin yolu içinde nerede bulacağınızı söyler. + +Tam yolu aşağıdaki komutu yazarak (kendi terminalinizde gördüğünüzle `a3/7be2fa` yerine koyarak) ve tab tuşuna basarak yolu otomatik tamamlayarak veya bir yıldız işareti ekleyerek bulabilirsiniz: + +```bash +tree work/a3/7be2fa* +``` + +Bu, tam dizin yolunu vermelidir: `work/a3/7be2fa7be2fad5e71e5f49998f795677fd68` + +Orada ne olduğuna bir göz atalım. + +!!! Tip "İpucu" + + VSCode dosya gezgininde görev alt dizininin içeriğine göz atarsanız, tüm dosyaları hemen göreceksiniz. + Ancak, günlük dosyaları terminalde görünmez olarak ayarlanmıştır, bu nedenle bunları görüntülemek için `ls` veya `tree` kullanmak istiyorsanız, görünmez dosyaları görüntülemek için ilgili seçeneği ayarlamanız gerekecektir. + + ```bash + tree -a work + ``` + +Tam alt dizin adları sisteminizde farklı olacaktır. + +<details> + <summary>Dizin içeriği</summary> + +```console title="work/" +work +└── a3 + └── 7be2fad5e71e5f49998f795677fd68 + ├── .command.begin + ├── .command.err + ├── .command.log + ├── .command.out + ├── .command.run + ├── .command.sh + ├── .exitcode + └── output.txt +``` + +</details> + +`output.txt` dosyasını hemen tanımalısınız; aslında bu, `results` dizinine yayınlanan `sayHello` sürecinin orijinal çıktısıdır. +Açarsanız, yine `Hello World!` selamlamasını bulacaksınız. + +<details> + <summary>output.txt dosyasının içeriği</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/output.txt" linenums="1" +Hello World! +``` + +</details> + +Peki ya diğer tüm dosyalar? + +Bunlar, Nextflow'un görev yürütmenin bir parçası olarak yazdığı yardımcı ve günlük dosyalarıdır: + +- **`.command.begin`**: Görev başlatılır başlatılmaz oluşturulan gözetleyici dosya. +- **`.command.err`**: Süreç çağrısı tarafından yayılan hata mesajları (`stderr`) +- **`.command.log`**: Süreç çağrısı tarafından yayılan tam günlük çıktısı +- **`.command.out`**: Süreç çağrısı tarafından düzenli çıktı (`stdout`) +- **`.command.run`**: Süreç çağrısını çalıştırmak için Nextflow tarafından çalıştırılan tam betik +- **`.command.sh`**: Süreç çağrısı tarafından gerçekten çalıştırılan komut +- **`.exitcode`**: Komuttan kaynaklanan çıkış kodu + +`.command.sh` dosyası özellikle yararlıdır çünkü Nextflow'un tüm kayıt tutma ve görev/ortam kurulumu dahil edilmeden çalıştırdığı ana komutu size gösterir. + +<details> + <summary>Dosya içeriği</summary> + +```console title="work/a3/7be2fa7be2fad5e71e5f49998f795677fd68/.command.sh" linenums="1" +#!/bin/bash -ue +echo 'Hello World!' > output.txt + +``` + +</details> + +!!! Tip "İpucu" + + Bir şeyler ters gittiğinde ve ne olduğunu sorun gidermeniz gerektiğinde, Nextflow'un workflow talimatlarına, değişken enterpolasyonuna vb. dayalı olarak tam olarak hangi komutu oluşturduğunu kontrol etmek için `command.sh` betiğine bakmak yararlı olabilir. + +### 1.4. İsteğe bağlı alıştırma: farklı selamlamalarla yeniden çalıştırın + +`--greeting` argümanı için farklı değerlerle workflow'u birkaç kez yeniden çalıştırmayı deneyin, ardından hem `results/` dizininin hem de görev dizinlerinin içeriğine bakın. + +İzole görev dizinlerinin çıktılarının ve günlüklerinin nasıl korunduğunu, `results` dizininin içeriğinin ise sonraki çalıştırmaların çıktısıyla nasıl üzerine yazıldığını gözlemleyin. + +### Çıkarım + +Basit bir Nextflow betiğini nasıl çalıştıracağınızı, çalışmasını nasıl izleyeceğinizi ve çıktılarını nasıl bulacağınızı biliyorsunuz. + +### Sırada ne var? + +Temel bir Nextflow betiğini nasıl okuyacağınızı ve bileşenlerinin işlevselliğiyle nasıl ilişkili olduğunu nasıl belirleyeceğinizi öğrenin. + +--- + +## 2. Hello World workflow başlangıç betiğini inceleyin + +Orada yaptığımız temelde workflow betiğini bir kara kutu gibi ele almaktı. +Artık ne yaptığını gördüğümüze göre, kutuyu açalım ve içine bakalım. + +_Buradaki amaç Nextflow kodunun sözdizimini ezberlemek değil, ana bileşenlerin neler olduğu ve nasıl organize edildikleri konusunda temel bir sezgi oluşturmaktır._ + +### 2.1. Genel kod yapısını inceleyin + +`hello-world.nf` betiğini düzenleyici bölmesinde açalım. + +<details> + <summary>Kod</summary> + +```groovy title="hello-world.nf" linenums="1" +#!/usr/bin/env nextflow + +/* + * Bir selamlamayı bir dosyaya yazdırmak için echo kullan + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} + +workflow { + + // bir selamlama yayınla + sayHello(params.greeting) +} +``` + +</details> + +Bir Nextflow betiği iki ana temel bileşen türü içerir: bir veya daha fazla **process** ve **workflow**'un kendisi. +Her **process**, pipeline'daki ilgili adımın hangi işlem(ler)i gerçekleştirmesi gerektiğini tanımlarken, **workflow** çeşitli adımları birbirine bağlayan veri akışı mantığını tanımlar. + +Önce **process** bloğuna daha yakından bakalım, ardından **workflow** bloğuna bakacağız. + +### 2.2. `process` tanımı + +Kodun ilk bloğu bir **process** tanımlar. +Process tanımı `process` anahtar kelimesiyle başlar, ardından süreç adı ve son olarak süslü parantezlerle sınırlandırılmış süreç gövdesi gelir. +Süreç gövdesi, çalıştırılacak komutu belirten bir script bloğu içermelidir; bu, komut satırı terminalinde çalıştırabileceğiniz herhangi bir şey olabilir. + +Burada `greeting` adlı bir **input** değişkeni alan ve **output**'unu `output.txt` adlı bir dosyaya yazan `sayHello` adında bir **process**'imiz var. + +<details> + <summary>Kod</summary> + +```groovy title="hello-world.nf" linenums="3" +/* + * Bir selamlamayı bir dosyaya yazdırmak için echo kullan + */ +process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path 'output.txt' + + script: + """ + echo '$greeting' > output.txt + """ +} +``` + +</details> + +Bu, sadece bir `input` tanımı, bir `output` tanımı ve çalıştırılacak `script` içeren çok minimal bir süreç tanımıdır. + +`input` tanımı, Nextflow'a bir tür değer (bir string, bir sayı, her ne olursa olsun) beklemesini söyleyen `val` niteleyicisini içerir. + +`output` tanımı, Nextflow'a bunun bir yol olarak ele alınması gerektiğini söyleyen `path` niteleyicisini içerir (hem dizin yollarını hem de dosyaları içerir). + +!!! Tip "İpucu" + + Çıktı tanımı hangi çıktının oluşturulacağını _belirlemez_. + Sadece beklenen çıktı dosya(lar)ının nerede bulunacağını _bildirir_, böylece Nextflow çalıştırma tamamlandığında bunu arayabilir. + + Bu, komutun başarıyla çalıştırıldığını doğrulamak ve gerekirse çıktıyı aşağı akış süreçlerine aktarmak için gereklidir. + Çıktı bloğunda bildirilenle eşleşmeyen üretilen çıktı, aşağı akış süreçlerine aktarılmayacaktır. + +Gerçek dünyadaki bir pipeline'da, bir süreç genellikle birazdan tanıtacağımız süreç yönergeleri gibi ek bilgiler içerir. + +### 2.3. `workflow` tanımı + +İkinci kod bloğu **workflow**'un kendisini tanımlar. +Workflow tanımı `workflow` anahtar kelimesiyle başlar, ardından isteğe bağlı bir ad ve süslü parantezlerle sınırlandırılmış workflow gövdesi gelir. + +Burada, `--greeting` parametresine verdiğimiz değeri tutan `params.greeting` girdisini alan `sayHello` sürecine bir çağrıdan oluşan bir **workflow**'umuz var. + +```groovy title="hello-world.nf" linenums="22" +workflow { + + // bir selamlama yayınla + sayHello(params.greeting) +} +``` + +Bu çok minimal bir **workflow** tanımıdır. +Gerçek dünyadaki bir pipeline'da, workflow tipik olarak **channel**'lar tarafından birbirine bağlanan **process**'lere birden fazla çağrı içerir ve değişken girdiler için varsayılan değerler ayarlanmış olabilir. + +Bunu kursun 2. Bölümünde nf-core/molkart'ı çalıştırdığımızda uygulamada göreceğiz. + +### 2.4. Komut satırı parametrelerinin `params` sistemi + +`sayHello()` süreç çağrısına sağladığımız `params.greeting`, Nextflow kodunun düzgün bir parçasıdır ve üzerine fazladan bir dakika harcamaya değer. + +Yukarıda belirtildiği gibi, `--greeting` komut satırı parametresinin değerini `sayHello()` süreç çağrısına bu şekilde aktarıyoruz. +Aslında, sadece `params.someParameterName` bildirmek, workflow'a komut satırından `--someParameterName` adında bir parametre vermemizi sağlayacaktır. + +!!! Tip "İpucu" + + `params` sistemi kullanılarak bildirilen bu workflow parametreleri her zaman iki tire (`--`) alır. + Bu, onları sadece bir tire (`-`) alan Nextflow seviyesi parametrelerden ayırır. + +### Çıkarım + +Artık basit bir Nextflow workflow'unun nasıl yapılandırıldığını ve temel bileşenlerin işlevselliği ile nasıl ilişkili olduğunu biliyorsunuz. + +### Sırada ne var? + +Workflow çalıştırmalarınızı rahatça yönetmeyi öğrenin. + +--- + +## 3. Workflow çalıştırmalarını yönetin + +Workflow'ları nasıl başlatacağınızı ve çıktıları nasıl alacağınızı bilmek harika, ancak yaşamınızı kolaylaştıracak workflow yönetiminin birkaç başka yönü olduğunu hızla fark edeceksiniz. + +Burada size aynı workflow'u yeniden başlatmanız gerektiğinde `resume` özelliğinden nasıl yararlanacağınızı, çalıştırma günlüklerini `nextflow log` ile nasıl inceleyeceğinizi ve eski çalışma dizinlerini `nextflow clean` ile nasıl sileceğinizi gösteriyoruz. + +### 3.1. `-resume` ile bir workflow'u yeniden başlatın + +Bazen, daha önce başlattığınız bir pipeline'ı, zaten başarıyla tamamlanmış herhangi bir işi yeniden yapmadan tekrar çalıştırmak isteyeceksiniz. + +Nextflow'un bunu yapmanıza izin veren `-resume` adlı bir seçeneği vardır. +Özellikle, bu modda, tamamen aynı kod, ayarlar ve girdilerle zaten çalıştırılmış olan tüm süreçler atlanacaktır. +Bu, Nextflow'un yalnızca son çalıştırmadan bu yana eklediğiniz veya değiştirdiğiniz süreçleri veya yeni ayarlar veya girdiler sağladığınız süreçleri çalıştıracağı anlamına gelir. + +Bunu yapmanın iki temel avantajı vardır: + +- Bir pipeline geliştiriyorsanız, değişikliklerinizi test etmek için yalnızca aktif olarak üzerinde çalıştığınız süreç(ler)i çalıştırmanız gerekeceğinden daha hızlı iterasyon yapabilirsiniz. +- Üretimde bir pipeline çalıştırıyorsanız ve bir şeyler ters giderse, çoğu durumda sorunu düzeltebilir ve pipeline'ı yeniden başlatabilirsiniz ve başarısızlık noktasından çalışmaya devam edecektir, bu size çok fazla zaman ve hesaplama tasarrufu sağlayabilir. + +Kullanmak için komutunuza `-resume` ekleyin ve çalıştırın: + +```bash +nextflow run hello-world.nf --greeting 'Hello World!' -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.04.3 + + Launching `hello-world.nf` [tiny_noyce] DSL2 - revision: c33d41f479 + + [a3/7be2fa] process > sayHello [100%] 1 of 1, cached: 1 ✔ + ``` + +Süreç durum satırına eklenmiş olan `cached:` kısmına bakın (satır 5), bu Nextflow'un bu çalışmayı zaten yaptığını tanıdığı ve önceki başarılı çalıştırmadan sonucu yeniden kullandığı anlamına gelir. + +Ayrıca çalışma alt dizini hash'inin önceki çalıştırmayla aynı olduğunu görebilirsiniz. +Nextflow tam anlamıyla size önceki çalıştırmayı gösteriyor ve "Bunu zaten orada yaptım" diyor. + +!!! Tip "İpucu" + + Pipeline'ınızı `resume` ile yeniden çalıştırdığınızda, Nextflow daha önce başarıyla çalıştırılan herhangi bir süreç çağrısı tarafından bir `publishDir` dizinine yazılan dosyaların üzerine yazmaz. + +### 3.2. Geçmiş çalıştırmaların günlüğünü inceleyin + +Bir nextflow workflow'u başlattığınızda, mevcut çalışma dizinindeki `.nextflow` adlı gizli bir dizin altında `history` adlı bir günlük dosyasına bir satır yazılır. + +Bu bilgilere erişmenin daha uygun bir yolu `nextflow log` komutunu kullanmaktır. + +```bash +nextflow log +``` + +Bu, günlük dosyasının içeriğini terminale çıktı olarak verir ve mevcut çalışma dizini içinden başlatılmış her Nextflow çalıştırması için zaman damgasını, çalıştırma adını, durumunu ve tam komut satırını gösterir. + +### 3.3. Eski çalışma dizinlerini silin + +Geliştirme sürecinde, tipik olarak taslak pipeline'larınızı çok sayıda kez çalıştırırsınız, bu da birçok alt dizinde çok sayıda dosyanın birikmesine yol açabilir. +Alt dizinler rastgele adlandırıldığından, hangilerinin daha eski ve hangilerinin daha yeni çalıştırmalar olduğunu adlarından söylemek zordur. + +Nextflow, artık umursamadığınız geçmiş çalıştırmaların çalışma alt dizinlerini otomatik olarak silebilen, neyin silineceğini kontrol etmek için çeşitli [seçenekler](https://www.nextflow.io/docs/latest/reference/cli.html#clean) içeren kullanışlı bir `clean` alt komutu içerir. + +Zaman damgasına ve/veya komut satırına göre bir çalıştırmayı aramak için Nextflow günlüğünü kullanabilir, ardından önceki çalıştırmalardaki çalışma dizinlerini silmek için `nextflow clean -before <run_name> -f` kullanabilirsiniz. + +!!! Warning "Uyarı" + + Geçmiş çalıştırmalardan çalışma alt dizinlerini silmek onları Nextflow'un önbelleğinden kaldırır ve bu dizinlerde depolanan tüm çıktıları siler. + Bu, Nextflow'un ilgili süreçleri yeniden çalıştırmadan çalıştırmayı sürdürme yeteneğini bozduğu anlamına gelir. + + Önem verdiğiniz veya güvenmeyi planladığınız çıktıları kaydetmek sizin sorumluluğunuzdadır! Bu amaçla `publishDir` yönergesini kullanıyorsanız, `symlink` modunu değil `copy` modunu kullandığınızdan emin olun. + +### Çıkarım + +Bir pipeline'ı zaten aynı şekilde çalıştırılmış adımları tekrarlamadan nasıl yeniden başlatacağınızı, çalıştırma günlüğünü nasıl inceleyeceğinizi ve eski çalışma dizinlerini temizlemek için `nextflow clean` komutunu nasıl kullanacağınızı biliyorsunuz. + +### Sırada ne var? + +Artık temel Nextflow işlemlerini anladığınıza göre, nf-core/molkart ile gerçek bir bioimaging pipeline'ı çalıştırmaya hazırsınız. diff --git a/docs/tr/docs/nf4_science/imaging/02_run_molkart.md b/docs/tr/docs/nf4_science/imaging/02_run_molkart.md new file mode 100644 index 0000000000..645da08086 --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/02_run_molkart.md @@ -0,0 +1,565 @@ +# Bölüm 2: nf-core/molkart'ı Çalıştırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bölüm 1'de, Nextflow çalıştırmasının temellerini anlamak için basit bir Hello World iş akışı çalıştırdık. +Şimdi gerçek dünyadan bir biyogörüntüleme pipeline'ı çalıştıracağız: **nf-core/molkart**. + +Bu pipeline, Resolve Bioscience'dan gelen Molecular Cartography uzamsal transkriptomik verilerini işler. +Ancak, burada öğreneceğiniz Nextflow kalıpları herhangi bir nf-core pipeline'ı veya üretim iş akışı için geçerlidir. + +## 1. nf-core pipeline'larını anlama + +Pipeline'ı çalıştırmadan önce, nf-core'un ne olduğunu ve iş akışlarını çalıştırmak için neden önemli olduğunu anlayalım. + +### 1.1. nf-core nedir? + +[nf-core](https://nf-co.re/), topluluk tarafından yönlendirilen yüksek kaliteli Nextflow pipeline'ları koleksiyonudur. +Tüm nf-core pipeline'ları aynı yapı ve kurallara uyar, bu da birini çalıştırmayı öğrendiğinizde herhangi birini çalıştırabileceğiniz anlamına gelir. + +nf-core pipeline'larının temel özellikleri: + +- **Standartlaştırılmış yapı**: Tüm pipeline'lar tutarlı parametre adlarına ve kullanım kalıplarına sahiptir +- **Yerleşik test verileri**: Her pipeline, hızlı doğrulama için test profilleri içerir +- **Kapsamlı dokümantasyon**: Detaylı kullanım talimatları ve parametre açıklamaları +- **Kalite kontrol**: MultiQC kullanarak otomatik kalite kontrol raporları +- **Konteyner desteği**: Tekrarlanabilirlik için önceden hazırlanmış konteynerler + +!!! tip "nf-core hakkında daha fazla bilgi edinmek ister misiniz?" + + nf-core pipeline geliştirmeye derinlemesine bir giriş için [Hello nf-core](../../hello_nf-core/index.md) eğitim kursuna göz atın. + Sıfırdan nf-core pipeline'ları oluşturmayı ve özelleştirmeyi kapsar. + +### 1.2. molkart pipeline'ı + +![nf-core/molkart pipeline'ı](img/molkart.png) + +[nf-core/molkart](https://nf-co.re/molkart) pipeline'ı, uzamsal transkriptomik görüntüleme verilerini birkaç aşamadan geçirerek işler: + +1. **Görüntü ön işleme**: Izgara deseni doldurma ve isteğe bağlı kontrast iyileştirme +2. **Hücre segmentasyonu**: Çoklu algoritma seçenekleri (Cellpose, Mesmer, ilastik, Stardist) +3. **Nokta ataması**: Transkript noktalarını segmente edilmiş hücrelere atama +4. **Kalite kontrol**: Kapsamlı kalite kontrol raporları oluşturma + +Temel çıktılar şunlardır: + +- Hücre-transkript sayım tabloları +- Segmentasyon maskeleri +- MultiQC kalite kontrol raporu + +--- + +## 2. Test verileri ile molkart çalıştırma + +Başlamadan önce, kodunu inceleyebilmemiz için molkart deposunu yerel olarak klonlayalım: + +```bash +cd /workspaces/training/nf4-science/imaging +git clone --branch 1.2.0 --depth 1 https://github.com/nf-core/molkart +``` + +Bu, tam pipeline kaynak kodunu içeren bir `molkart/` dizini oluşturur. + +!!! note "Neden yerel olarak klonluyoruz?" + + Genellikle, nf-core pipeline'larını doğrudan GitHub'dan `nextflow run nf-core/molkart -r 1.2.0` kullanarak çalıştırırsınız. + Nextflow, istenen pipeline sürümünü sizin için otomatik olarak `$HOME/.nextflow/assets/nf-core/molkart` dizinine indirir ve oradan çalıştırır. + Ancak, bu eğitim için, kodu daha kolay inceleyebilmemiz için pipeline'ı farklı bir yerel dizine klonluyoruz. + +### 2.1. Konteyner gereksinimlerini anlama + +Tam pipeline'ı çalıştırmadan önce, konteynerların neden nf-core pipeline'ları için gerekli olduğunu öğrenelim. + +Pipeline'ı molkart test yapılandırmasından test veri seti ve parametrelerini kullanarak çalıştırmayı deneyelim: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "mesmer,cellpose,stardist" \ + --outdir results +``` + +Bu parametreleri açıklayalım: + +- `--input`: Örnek meta verilerini içeren samplesheet'in yolu +- `--mindagap_tilesize`, `--mindagap_boxsize`, `--mindagap_loopnum`: Izgara deseni doldurma için parametreler +- `--clahe_pyramid_tile`: Kontrast iyileştirme için çekirdek boyutu +- `--segmentation_method`: Hücre segmentasyonu için hangi algoritma(lar)ın kullanılacağı +- `--outdir`: Sonuçların nereye kaydedileceği + +!!! Warning "Bu komut başarısız olacak - bu kasıtlı!" + + Neden gerekli olduklarını göstermek için kasıtlı olarak bunu konteynerler olmadan çalıştırıyoruz. + +Birkaç dakika sonra, şuna benzer bir hata göreceksiniz: + +??? failure "Komut çıktısı" + + ```console + ERROR ~ Error executing process > 'NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)' + + Caused by: + Process `NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only)` terminated with an error exit status (127) + + Command executed: + + duplicate_finder.py \ + spots.txt \ + 90 + + Command exit status: + 127 + + Command error: + .command.sh: line 3: duplicate_finder.py: command not found + ``` + +**Ne oluyor?** + +`command not found` hatası (çıkış durumu 127), Nextflow'un `duplicate_finder.py` çalıştırmayı denediği ancak sisteminizde bulamadığı anlamına gelir. +Bunun nedeni: + +1. Pipeline'ın özel biyoinformatik yazılımlarının kurulu olmasını beklemesi +2. Bu araçların (örneğin `duplicate_finder.py`, `apply_clahe.dask.py`, vb.) standart Linux dağıtımlarının bir parçası olmaması +3. Konteynerler olmadan, Nextflow'un komutları doğrudan yerel makinenizde çalıştırmaya çalışması + +**Bu araçların nereden gelmesi gerekiyor?** + +Yazılım gereksinimlerini nasıl bildirdiğini görmek için işlem modüllerinden birini inceleyelim. + +CLAHE ön işleme modülünü açın: + +```bash +code molkart/modules/local/clahe/main.nf +``` + +5. satıra bakın - şunu göreceksiniz: + +```groovy +container 'ghcr.io/schapirolabor/molkart-local:v0.0.4' +``` + +Bu satır Nextflow'a şunu söyler: "Bu işlemi çalıştırmak için, gerekli tüm yazılımları içeren `ghcr.io/schapirolabor/molkart-local:v0.0.4` Docker imajını kullan." + +Her işlem, hangi konteyner imajının gerekli araçları sağladığını bildirir. +Ancak, Nextflow bu konteynerları yalnızca ona söylerseniz kullanır! + +**Çözüm: Yapılandırmada Docker'ı etkinleştirin** + +### 2.2. Docker'ı yapılandırma ve pipeline'ı başlatma + +Docker'ı etkinleştirmek için `nextflow.config` dosyasında `docker.enabled` değerini `false`'dan `true`'ya değiştirmemiz gerekir. + +Yapılandırma dosyasını açın: + +```bash +code nextflow.config +``` + +`docker.enabled = false` ifadesini `docker.enabled = true` olarak değiştirin: + +```groovy +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} +``` + +Şimdi pipeline'ı aynı komutla tekrar çalıştırın: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose,mesmer,stardist" \ + --outdir results +``` + +Bu sefer, Nextflow: + +1. Yapılandırmadan `docker.enabled = true` ayarını okuyacak +2. Gerekli Docker imajlarını çekecek (yalnızca ilk seferde) +3. Her işlemi belirtilen konteyner içinde çalıştıracak +4. Tüm araçlar konteynerler içinde mevcut olduğu için başarıyla çalıştıracak + +!!! Tip "Konteynerlar neden önemlidir" + + Çoğu nf-core pipeline'ı konteynerizasyonu (Docker, Singularity, Podman, vb.) **gerektirir** çünkü: + + - Standart ortamlarda bulunmayan özel biyoinformatik yazılımları kullanırlar + - Konteynerler tekrarlanabilirliği sağlar - aynı yazılım sürümleri her yerde çalışır + - Düzinelerce aracı ve bağımlılıklarını manuel olarak kurmanız gerekmez + + Nextflow'da konteynerler hakkında daha fazla bilgi için, Hello Nextflow eğitiminden [Hello Containers](../../hello_nextflow/05_hello_containers.md) bölümüne bakın. + +### 2.3. Çalıştırmayı izleme + +Pipeline çalışırken, buna benzer bir çıktı göreceksiniz: + +??? success "Komut çıktısı" + + ```console + Nextflow 25.04.8 is available - Please consider updating your version to it + + N E X T F L O W ~ version 25.04.3 + + Launching `https://github.com/nf-core/molkart` [soggy_kalam] DSL2 - revision: 5e54b29cb3 [dev] + + + ------------------------------------------------------ + ,--./,-. + ___ __ __ __ ___ /,-._.--~' + |\ | |__ __ / ` / \ |__) |__ } { + | \| | \__, \__/ | \ |___ \`-._,-`-, + `._,._,' + nf-core/molkart 1.2.0dev + ------------------------------------------------------ + Segmentation methods and options + segmentation_method : mesmer,cellpose,stardist + + Image preprocessing + mindagap_boxsize : 7 + mindagap_loopnum : 100 + clahe_kernel : 25 + mindagap_tilesize : 90 + clahe_pyramid_tile : 368 + + Input/output options + input : https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv + outdir : results + + Institutional config options + config_profile_name : Test profile + config_profile_description: Minimal test dataset to check pipeline function + + Generic options + trace_report_suffix : 2025-10-18_22-22-21 + + Core Nextflow options + revision : dev + runName : soggy_kalam + containerEngine : docker + launchDir : /workspaces/training/nf4-science/imaging + workDir : /workspaces/training/nf4-science/imaging/work + projectDir : /workspaces/.nextflow/assets/nf-core/molkart + userName : root + profile : docker,test + configFiles : + + !! Only displaying parameters that differ from the pipeline defaults !! + ------------------------------------------------------ + * The pipeline + https://doi.org/10.5281/zenodo.10650748 + + * The nf-core framework + https://doi.org/10.1038/s41587-020-0439-x + + * Software dependencies + https://github.com/nf-core/molkart/blob/master/CITATIONS.md + + executor > local (22) + [c1/da5009] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2 ✔ + [73/8f5e8a] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2 ✔ + [ec/8f84d5] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1 ✔ + [a2/99349b] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1 ✔ + [95/c9b4b1] NFCORE_MOLKART:MOLKART:DEEPCELL_MESMER (mem_only) [100%] 1 of 1 ✔ + [d4/1ebd1e] NFCORE_MOLKART:MOLKART:STARDIST (mem_only) [100%] 1 of 1 ✔ + [3e/3c0736] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1 ✔ + [a0/415c6a] NFCORE_MOLKART:MOLKART:MASKFILTER (mem_only) [100%] 3 of 3 ✔ + [14/a830c9] NFCORE_MOLKART:MOLKART:SPOT2CELL (mem_only) [100%] 3 of 3 ✔ + [b5/391836] NFCORE_MOLKART:MOLKART:CREATE_ANNDATA (mem_only) [100%] 3 of 3 ✔ + [77/aed558] NFCORE_MOLKART:MOLKART:MOLKARTQC (mem_only) [100%] 3 of 3 ✔ + [e6/b81475] NFCORE_MOLKART:MOLKART:MULTIQC [100%] 1 of 1 ✔ + -[nf-core/molkart] Pipeline completed successfully- + Completed at: 19-Oct-2025 22:23:01 + Duration : 2m 52s + CPU hours : 0.1 + Succeeded : 22 + ``` + +Bu çıktının, pipeline'ın takip ettiği nf-core kuralları nedeniyle Hello World örneğimizden daha detaylı olduğuna dikkat edin: + +- Pipeline, sürümünü ve logosunu gösterir +- Yapılandırma parametreleri görüntülenir +- Birden fazla işlem paralel olarak çalışır (birden fazla işlem satırıyla gösterilir) +- İşlem adları tam modül yolunu içerir (örneğin, `NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP`) + +### 2.4. İşlem çalıştırmasını anlama + +`executor > local (22)` satırı size şunları söyler: + +- **executor**: Hangi hesaplama ortamının kullanıldığı (`local` = makineniz) +- **(22)**: Başlatılan toplam görev sayısı + +Her işlem satırı şunları gösterir: + +- **Hash** (`[1a/2b3c4d]`): Çalışma dizini tanımlayıcısı (önceki gibi) +- **İşlem adı**: Tam modül yolu ve işlem adı +- **Girdi tanımlayıcısı**: Parantez içinde örnek adı +- **İlerleme**: Tamamlanma yüzdesi ve sayısı (örneğin, `1 of 1 ✔`) + +### Çıkarım + +Bir nf-core pipeline'ını test verileri ile nasıl başlatacağınızı ve çalıştırma çıktısını nasıl yorumlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Sonuçları nerede bulacağınızı ve nasıl yorumlayacağınızı öğrenin. + +--- + +## 3. Çıktıları bulma ve inceleme + +Pipeline başarıyla tamamlandığında, bir tamamlanma mesajı ve çalıştırma özeti göreceksiniz. + +### 3.1. Sonuçlar dizinini bulma + +Varsayılan olarak, nf-core pipeline'ları çıktıları `outdir` parametresiyle belirtilen bir dizine yazar, bunu `results/` olarak ayarladık. + +İçeriği listeleyin: + +```bash +tree results/ +``` + +Birkaç alt dizin görmelisiniz: + +```console title="results/" +results/ +├── anndata/ +├── clahe/ +├── mindagap/ +├── molkartqc/ +├── multiqc/ +├── pipeline_info/ +├── segmentation/ +├── spot2cell/ +└── stack/ +``` + +Her alt dizin, pipeline'ın belirli bir aşamasından çıktılar içerir: + +- **mindagap/**: MindaGap ön işleme adımından ızgara doldurulmuş görüntüler +- **clahe/**: CLAHE ön işlemeden kontrast artırılmış görüntüler +- **stack/**: Segmentasyon için oluşturulan çok kanallı görüntü yığınları +- **segmentation/**: Farklı algoritmalardan segmentasyon sonuçları (cellpose/, mesmer/, stardist/, filtered_masks/) +- **spot2cell/**: Hücre-transkript sayım tabloları +- **anndata/**: Hücre-transkript matrisleri ve uzamsal koordinatları içeren AnnData nesneleri +- **molkartqc/**: Nokta ataması için kalite kontrol metrikleri +- **multiqc/**: Kapsamlı kalite kontrol raporu +- **pipeline_info/**: Çalıştırma raporları ve loglar + +### 3.2. MultiQC raporunu inceleme + +MultiQC raporu, tüm pipeline adımlarından kalite metriklerini toplayan kapsamlı bir HTML dosyasıdır. + +Raporu dosya tarayıcısında açın ve ardından doğrudan VS Code'da işlenmiş olarak görmek için "Show Preview" düğmesine tıklayın. + +Rapor şunları içerir: + +- Tüm örnekler için genel istatistikler +- Ön işleme metrikleri +- Segmentasyon kalite metrikleri +- Tespit edilen hücre ve nokta sayısı + +!!! Tip + + MultiQC raporları genellikle tüm nf-core pipeline'larına dahil edilir. + Her zaman pipeline çalıştırması ve veri kalitesi hakkında üst düzey bir genel bakış sağlarlar. + +### 3.3. Hücre-transkript tablolarını inceleme + +En önemli bilimsel çıktı, hücre-transkript sayım tablosudur. +Bu, her hücrede her transkriptten kaç tanesinin tespit edildiğini söyler. + +spot2cell dizinine gidin: + +```bash +ls results/spot2cell/ +``` + +Şunlar gibi dosyalar bulacaksınız: + +- `cellxgene_mem_only_cellpose.csv`: Cellpose segmentasyonu kullanarak hücre-transkript tablosu +- `cellxgene_mem_only_mesmer.csv`: Mesmer segmentasyonu kullanarak hücre-transkript tablosu +- `cellxgene_mem_only_stardist.csv`: Stardist segmentasyonu kullanarak hücre-transkript tablosu + +Bu test veri setinde sadece 1 örnek çalıştırdık, ancak gerçek bir deneyde bu tabloları her örnek için elde ederdik. +Nextflow'un birden fazla segmentasyon yöntemini paralel olarak işleyerek sonuçları karşılaştırmayı nasıl kolaylaştırdığına dikkat edin. + +### 3.4. Çalıştırma raporlarını görüntüleme + +Nextflow otomatik olarak birkaç çalıştırma raporu oluşturur. + +pipeline_info dizinini kontrol edin: + +```bash +ls results/pipeline_info/ +``` + +Anahtar dosyalar: + +- **execution_report.html**: Zaman çizelgesi ve kaynak kullanım görselleştirmesi +- **execution_timeline.html**: İşlem çalıştırmasının Gantt grafiği +- **execution_trace.txt**: Detaylı görev çalıştırma metrikleri +- **pipeline_dag.html**: İş akışı yapısını gösteren yönlendirilmiş döngüsüz grafik + +Kaynak kullanımını görmek için çalıştırma raporunu açın: + +```bash +code results/pipeline_info/execution_report.html +``` + +Bu şunları gösterir: + +- Her işlemin ne kadar sürdüğü +- CPU ve bellek kullanımı +- Hangi görevlerin önbellekte olduğu ve hangilerinin çalıştırıldığı + +!!! Tip + + Bu raporlar, kaynak tahsisini optimize etmek ve performans sorunlarını gidermek için son derece kullanışlıdır. + +### Çıkarım + +Pipeline çıktılarını nasıl bulacağınızı, kalite kontrol raporlarını nasıl inceleyeceğinizi ve çalıştırma metriklerine nasıl erişeceğinizi biliyorsunuz. + +### Sırada ne var? + +Çalışma dizini ve Nextflow'un ara dosyaları nasıl yönettiği hakkında bilgi edinin. + +--- + +## 4. Çalışma dizinini keşfetme + +Hello World örneğimizde olduğu gibi, tüm gerçek çalışma `work/` dizininde gerçekleşir. + +### 4.1. Çalışma dizini yapısını anlama + +Çalışma dizini, çalıştırılan her görev için bir alt dizin içerir. +22 göreve sahip bu pipeline için 22 çalışma alt dizini olacaktır. + +Çalışma dizinini listeleyin: + +```bash +ls -d work/*/*/ | head -5 +``` + +Bu, ilk 5 görev dizinini gösterir. + +### 4.2. Bir görev dizinini inceleme + +Konsol çıktısından segmentasyon işlem hash'lerinden birini seçin (örneğin, `[3m/4n5o6p]`) ve içine bakın: + +```bash +ls -la work/3m/4n5o6p*/ +``` + +Şunları göreceksiniz: + +- **.command.\*** dosyaları: Nextflow çalıştırma betikleri ve loglar (önceki gibi) +- **Hazırlanmış girdi dosyaları**: Gerçek girdi dosyalarına sembolik bağlantılar +- **Çıktı dosyaları**: Segmentasyon maskeleri, ara sonuçlar, vb. + +Hello World'den temel fark: + +- Gerçek pipeline'lar büyük girdi dosyalarını hazırlar (görüntüler, referans verileri) +- Çıktı dosyaları oldukça büyük olabilir (segmentasyon maskeleri, işlenmiş görüntüler) +- Görev başına birden fazla girdi ve çıktı dosyası + +!!! Tip + + Bir işlem başarısız olursa, çalışma dizinine gidebilir, hata mesajları için `.command.err` dosyasını inceleyebilir ve hatta sorunu ayıklamak için `.command.sh` dosyasını manuel olarak yeniden çalıştırabilirsiniz. + +### 4.3. Çalışma dizini temizliği + +Çalışma dizini, birden fazla pipeline çalıştırması üzerinden oldukça büyüyebilir. +Bölüm 1'de öğrendiğimiz gibi, eski çalıştırmalardan çalışma dizinlerini kaldırmak için `nextflow clean` kullanabilirsiniz. + +Ancak, büyük ara dosyalara sahip nf-core pipeline'ları için düzenli olarak temizlik yapmak özellikle önemlidir. + +### Çıkarım + +nf-core pipeline'larının çalışma dizinlerini nasıl düzenlediğini ve hata ayıklama için bireysel görevleri nasıl inceleyeceğinizi anlıyorsunuz. + +### Sırada ne var? + +Nextflow önbelleği ve başarısız pipeline çalıştırmalarını nasıl devam ettireceğinizi öğrenin. + +--- + +## 5. Bir pipeline çalıştırmasını devam ettirme + +Nextflow'un en güçlü özelliklerinden biri, bir pipeline'ı hata noktasından devam ettirme yeteneğidir. + +### 5.1. Önbellek mekanizması + +Bir pipeline'ı `-resume` ile çalıştırdığınızda, Nextflow: + +1. Her görev için önbelleği kontrol eder +2. Girdiler, kod ve parametreler özdeşse, önbellekteki sonucu yeniden kullanır +3. Yalnızca değişen veya başarısız olan görevleri yeniden çalıştırır + +Bu, çalıştırmanın geç aşamalarında hataların oluşabileceği uzun süreli pipeline'lar için gereklidir. + +### 5.2. molkart ile resume deneme + +Aynı komutu tekrar çalıştırın, ancak `-resume` ekleyin: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results \ + -resume +``` + +Şuna benzer bir çıktı görmelisiniz: <!-- TODO: full output --> + +```console +executor > local (0) +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +[7f/8g9h0i] NFCORE_MOLKART:MOLKART:CREATE_STACK (mem_only) [100%] 1 of 1, cached: 1 ✔ +[9h/0i1j2k] NFCORE_MOLKART:MOLKART:MINDAGAP_DUPLICATEFINDER (mem_only) [100%] 1 of 1, cached: 1 ✔ +[2k/3l4m5n] NFCORE_MOLKART:MOLKART:CELLPOSE (mem_only) [100%] 1 of 1, cached: 1 ✔ +... +``` + +Her işlem için `cached: 2` veya `cached: 1` ifadesine dikkat edin - hiçbir şey yeniden çalıştırılmadı! + +### 5.3. Resume ne zaman yararlıdır + +Resume özellikle şu durumlarda değerlidir: + +- Bir pipeline kaynak sınırları nedeniyle başarısız olduğunda (yetersiz bellek, zaman sınırı aşımı) +- Üst akış adımlarını yeniden çalıştırmadan alt akış işlemlerini değiştirmeniz gerektiğinde +- Veri indirme sırasında ağ bağlantınız düştüğünde +- Hesaplamayı yeniden yapmadan ek çıktılar eklemek istediğinizde + +!!! Warning + + Resume yalnızca girdi verilerini, pipeline kodunu veya parametreleri değiştirmemişseniz çalışır. + Bunlardan herhangi birini değiştirirseniz, Nextflow etkilenen görevleri doğru bir şekilde yeniden çalıştıracaktır. + +### Çıkarım + +Başarılı görevleri tekrarlamadan pipeline'ları verimli bir şekilde yeniden çalıştırmak için `-resume` kullanmayı biliyorsunuz. + +### Sırada ne var? + +Artık nf-core/molkart'ı test verileri ile çalıştırabildiğinize göre, kendi veri setleriniz için nasıl yapılandıracağınızı öğrenmeye hazırsınız. diff --git a/docs/tr/docs/nf4_science/imaging/03_inputs.md b/docs/tr/docs/nf4_science/imaging/03_inputs.md new file mode 100644 index 0000000000..792829367c --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/03_inputs.md @@ -0,0 +1,145 @@ +# Bölüm 3: Girdileri düzenleme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bölüm 2'de molkart'ı komut satırında birden fazla parametre ile çalıştırdık. +Şimdi girdileri yönetmek için iki daha iyi yaklaşım öğreneceğiz: **parametre dosyaları** ve **örnek tabloları**. + +## 1. Parametre dosyalarını kullanma + +### 1.1. Uzun komut satırlarıyla ilgili sorun + +Bölüm 2'deki komutumuzu hatırlayın: + +```bash +nextflow run ./molkart \ + --input 'data/samplesheet.csv' \ + --mindagap_tilesize 90 \ + --mindagap_boxsize 7 \ + --mindagap_loopnum 100 \ + --clahe_pyramid_tile 368 \ + --segmentation_method "cellpose" \ + --outdir results +``` + +Bu işe yarar, ancak tekrar üretmek, paylaşmak veya değiştirmek zordur. +Aynı analizi önümüzdeki ay tekrar çalıştırmanız gerekirse ne olur? +Bir iş arkadaşınız tam ayarlarınızı kullanmak isterse ne olur? + +### 1.2. Çözüm: Parametre dosyası kullanın + +`params.yaml` adında bir dosya oluşturun: + +```yaml title="params.yaml" +input: "data/samplesheet.csv" +outdir: "results" +mindagap_tilesize: 90 +mindagap_boxsize: 7 +mindagap_loopnum: 100 +clahe_pyramid_tile: 368 +segmentation_method: "cellpose" +``` + +Artık komutunuz şu hale gelir: + +```bash +nextflow run ./molkart -params-file params.yaml -resume +``` + +Bu kadar! Parametre dosyası tam yapılandırmanızı belgelendirir ve tekrar çalıştırmayı veya paylaşmayı kolaylaştırır. + +### 1.3. Parametreleri geçersiz kılma + +Komut satırından belirli parametreleri geçersiz kılmaya devam edebilirsiniz: + +```bash +nextflow run ./molkart -params-file params.yaml --segmentation_method "stardist" --outdir stardist_results -resume +``` + +Yukarıdaki satır, `segmentation_method`'u `stardist` olarak değiştirir ve `--outdir` adını `params.yaml` dosyasındaki parametreler yerine `stardist_results` olarak ayarlar. +Ayrıca, `-resume` bayrağının önceki çalıştırmadaki ön işleme sonuçlarını yeniden kullanmamıza izin vererek zaman tasarrufu sağladığını görebilirsiniz. +Bu kalıbı, ardışık düzenin farklı varyasyonlarını hızlıca test etmek için kullanabilirsiniz. + +### Çıkarım + +Parametre dosyaları analizlerinizi tekrar üretilebilir ve paylaşımı kolay hale getirir. +Gerçek analiz çalışmaları için bunları kullanın. + +### Sırada ne var? + +Örnek tablolarının birden fazla örnek hakkındaki bilgileri nasıl düzenlediğini öğrenin. + +--- + +## 2. Örnek tablosu kalıbı + +### 2.1. Örnek tablosu nedir? + +Örnek tablosu, girdi örneklerinizi açıklayan bir CSV dosyasıdır. +Her satır bir örnektir ve sütunlar o örnek için dosyaları ve meta verileri belirtir. + +Kullandığımız örnek tablosuna bakalım: + +```bash +cat data/samplesheet.csv +``` + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt,https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +``` + +Sütunlar şunlardır: + +- `sample`: Benzersiz örnek tanımlayıcısı +- `nuclear_image`: Çekirdek boyama görüntüsü (TIFF) +- `spot_table`: Transkript noktaları (TXT) +- `membrane_image`: Membran boyama görüntüsü (TIFF, isteğe bağlı) + +### 2.2. Dosya yolları + +Örnek tabloları birden fazla yol türünü kabul eder: + +- **URL'ler**: Nextflow otomatik olarak indirir (yukarıda gösterildiği gibi) +- **Yerel yollar**: `data/nuclear.tiff` veya `/absolute/path/to/nuclear.tiff` +- **Bulut depolama**: `s3://bucket/nuclear.tiff`, `gs://bucket/nuclear.tiff`, `az://container/nuclear.tiff` + +Aynı örnek tablosunda yol türlerini karıştırabilirsiniz. + +### 2.3. Kendi örnek tablonuzu oluşturma + +Önce test veri dosyalarını yerel olarak indirelim: + +```bash +cd /workspaces/training/nf4-science/imaging/data +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/nuclear.tiff +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/spots.txt +curl -O https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/input_data/membrane.tiff +cd .. +``` + +Şimdi örnek tablosunu bu yerel dosyalara referans verecek şekilde değiştirelim: + +```csv title="samplesheet.csv" +sample,nuclear_image,spot_table,membrane_image +mem_only,data/nuclear.tiff,data/spots.txt,data/membrane.tiff +``` + +!!! warning "Uyarı" + + Örnek tablosundaki yolların, örnek tablosunun bulunduğu yere değil, Nextflow'u **çalıştırdığınız** yere göre göreceli olduğuna dikkat edin. + +Son olarak, yerel dosya yollarına sahip örnek tablosuyla nf-core/molkart'ı bir kez daha çalıştıralım: + +`nextflow run ./molkart -params-file params.yaml -resume` + +Gördüğünüz gibi, Nextflow bu çalıştırmayı dosyalar Github'dan indirildiğinde olduğu gibi benzer şekilde yürütür. Bu, Nextflow'un harika özelliklerinden biridir, verinin nerede bulunduğuna bakılmaksızın verileri sizin için uygun şekilde hazırlar. + +### Çıkarım + +Örnek tabloları, dosya yollarıyla birlikte meta verilerinizi açıkça tanımlamanıza olanak tanıyan bir şekilde çok örnekli veri setlerini düzenler. +Çoğu nf-core ardışık düzeni bu kalıbı kullanır. + +### Sırada ne var? + +Artık girdileri ele aldığımıza göre, Nextflow ardışık düzenlerini farklı hesaplama ortamları için nasıl yapılandıracağımızı keşfedelim. diff --git a/docs/tr/docs/nf4_science/imaging/04_config.md b/docs/tr/docs/nf4_science/imaging/04_config.md new file mode 100644 index 0000000000..af6544b19a --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/04_config.md @@ -0,0 +1,452 @@ +# Bölüm 4: Yapılandırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bölüm 1-3'te Nextflow'u nasıl çalıştıracağımızı, bir nf-core pipeline'ını nasıl çalıştıracağımızı ve girdileri parametre dosyaları ve örnek listelerini kullanarak nasıl yöneteceğimizi öğrendik. +Şimdi, **yapılandırma dosyaları** ve **profiller** kullanarak pipeline'ları farklı hesaplama ortamları için nasıl yapılandıracağımızı keşfedeceğiz. + +## Öğrenme hedefleri + +Bu bölümün sonunda şunları yapabileceksiniz: + +- Nextflow'un yapılandırmayı birden fazla kaynaktan nasıl çözdüğünü anlamak +- Konteynerler ve test için nf-core yerleşik profillerini kullanmak +- Farklı hesaplama ortamları için özel profiller oluşturmak +- Process etiketlerini kullanarak kaynak taleplerini özelleştirmek +- Sınırlı ortamlarda kaynak limitlerini yönetmek +- `nextflow config` ile çözümlenmiş yapılandırmayı incelemek + +--- + +## 1. Nextflow yapılandırmasını anlamak + +### 1.1. Yapılandırma dosyası nedir? + +Nextflow, **iş akışı mantığını** (ne yapılacağını) **çalıştırma ayarlarından** (nasıl ve nerede yapılacağından) ayırmak için yapılandırma dosyalarını kullanır. + +Yapılandırma dosyaları şunları kontrol eder: + +- Konteyner motorları (Docker, Singularity, Conda) +- Hesaplama kaynakları (CPU'lar, bellek, zaman) +- Çalıştırma platformları (yerel, HPC, bulut) +- Pipeline parametreleri + +### 1.2. Yapılandırma önceliği + +Nextflow yapılandırmayı birden fazla kaynaktan yükler ve sonraki kaynaklar önceki olanları geçersiz kılar: + +1. **Pipeline yapılandırması**: Pipeline deposundaki `nextflow.config` +2. **Dizin yapılandırması**: Mevcut çalışma dizininizdeki `nextflow.config` +3. **Kullanıcı yapılandırması**: `~/.nextflow/config` +4. **Komut satırı**: Doğrudan aktarılan parametreler ve seçenekler + +Bu katmanlı yaklaşım, varsayılanları pipeline'da tutmanıza, kullanıcıya özel ayarlarla geçersiz kılmanıza ve komut satırında hızlı ayarlamalar yapmanıza olanak tanır. + +### 1.3. Mevcut yapılandırmamız + +Kullandığımız yapılandırmaya bakalım: + +```groovy title="nextflow.config" +docker.enabled = true +process { + resourceLimits = [ + cpus: 2, + memory: '7.GB', + ] +} + +``` + +Bölüm 2'den `docker.enabled = true` satırını yorum satırına alalım veya geri değiştirelim ve bunun yerine molkart'ta bir profil kullanarak aynı sonuca nasıl ulaşabileceğimizi bulalım. + +--- + +## 2. Profilleri kullanma + +### 2.1. Profiller nedir? + +Profiller, `nextflow run` komutu aracılığıyla `-profile` bayrağı ile etkinleştirilebilen adlandırılmış yapılandırma kümeleridir. +Yapılandırma dosyalarını düzenlemeden farklı hesaplama senaryoları arasında geçiş yapmayı kolaylaştırırlar. + +Tüm nf-core pipeline'ları, kullanabileceğimiz bir dizi varsayılan profille birlikte gelir. + +### 2.2. Yerleşik profilleri inceleme + +Pipeline kod tabanıyla ilişkili `molkart/nextflow.config` dosyasında bunları inceleyelim: + +```bash +code molkart/nextflow.config +``` + +`profiles` bloğunu arayın: + +```groovy title="molkart/nextflow.config (alıntı)" +profiles { + docker { + docker.enabled = true + singularity.enabled = false + conda.enabled = false + } + singularity { + singularity.enabled = true + singularity.autoMounts = true + docker.enabled = false + } + conda { + conda.enabled = true + docker.enabled = false + conda.channels = ['conda-forge', 'bioconda'] + } +} +``` + +Yaygın konteyner profilleri: + +- `docker`: Docker konteynerlerini kullan (yerel geliştirme için en yaygın) +- `singularity`: Singularity/Apptainer kullan (HPC'de yaygın) +- `conda`: Conda ortamlarını kullan +- `apptainer`: Apptainer konteynerlerini kullan + +### 2.3. nextflow.config yerine profiller kullanarak yeniden çalıştırma + +Şimdi yerel `nextflow.config` dosyamızdaki docker yapılandırmasını devre dışı bıraktığımıza ve profilleri anladığımıza göre, `-profile` bayrağını kullanarak pipeline'ı yeniden çalıştıralım. + +Daha önce Bölüm 3'te özel parametrelerimizi içeren bir `params.yaml` dosyası oluşturduk. +Şimdi bunu yerleşik Docker profiliyle birleştirebiliriz: + +```bash +nextflow run ./molkart \ + -profile docker \ + -params-file params.yaml \ + -resume +``` + +Her bayrağın ne yaptığını inceleyelim: + +- `-profile docker`: molkart'ın `nextflow.config` dosyasından Docker profilini etkinleştirir, bu da `docker.enabled = true` ayarını yapar +- `-params-file params.yaml`: Tüm pipeline parametrelerini YAML dosyamızdan yükler +- `-resume`: Önceki çalıştırmalardan önbelleğe alınmış sonuçları yeniden kullanır + +`-resume` kullandığımız için Nextflow, son çalıştırmadan bu yana bir şeyin değişip değişmediğini kontrol edecektir. +Parametreler, girdiler ve kod aynıysa, tüm görevler önbellekten alınacak ve pipeline neredeyse anında tamamlanacaktır. + +```console title="Çıktı (alıntı)" +executor > local (12) +... +[1a/2b3c4d] NFCORE_MOLKART:MOLKART:MINDAGAP_MINDAGAP (mem_only) [100%] 2 of 2, cached: 2 ✔ +[5e/6f7g8h] NFCORE_MOLKART:MOLKART:CLAHE (mem_only) [100%] 2 of 2, cached: 2 ✔ +... +-[nf-core/molkart] Pipeline completed successfully- +``` + +Tüm proseslerin `cached: 2` veya `cached: 1` gösterdiğine dikkat edin - hiçbir şey yeniden yürütülmedi! + +### 2.4. Test profilleri + +Test profilleri, pipeline'ın çalıştığını doğrulamanıza olanak tanımak için varsayılan girdi parametrelerini ve veri dosyalarını belirtmenin hızlı yollarını sağlar. +nf-core pipeline'ları her zaman en az iki test profili içerecektir: + +- `test`: Hızlı test için küçük veri seti ve hızlı parametreler +- `test_full`: Daha büyük verilerle daha kapsamlı test + +`includeConfig` yönergesi kullanılarak dahil edilen molkart'taki `test` profiline daha yakından bakalım: + +```groovy title="molkart/nextflow.config (alıntı)" +profiles { + ... + test { includeConfig 'conf/test.config' } +} +``` + +Bu, pipeline'ı `-profile test` ile ne zaman çalıştırsak, Nextflow'un yapılandırmayı `conf/test.config` dosyasından yükleyeceği anlamına gelir. + +```groovy title="molkart/conf/test.config (alıntı)" +params { + config_profile_name = 'Test profile' + config_profile_description = 'Minimal test dataset to check pipeline function' + + input = 'https://raw.githubusercontent.com/nf-core/test-datasets/molkart/test_data/samplesheets/samplesheet_membrane.csv' + mindagap_tilesize = 90 + mindagap_boxsize = 7 + mindagap_loopnum = 100 + clahe_pyramid_tile = 368 + segmentation_method = "mesmer,cellpose,stardist" +} + +process { + resourceLimits = [ + cpus: 4, + memory: '15.GB', + time: '1.h' + ] +} +``` + +Bu profilin, daha önce `params.yaml` dosyamızda kullandığımız parametrelerin aynısını içerdiğine dikkat edin. + +Birden fazla profili virgülle ayırarak etkinleştirebilirsiniz. +Params dosyamıza ihtiyaç duymadan pipeline'ımızı test etmek için bunu kullanalım: + +```bash +nextflow run ./molkart -profile docker,test --outdir results -resume +``` + +Bu şunları birleştirir: + +- `docker`: Docker konteynerlerini etkinleştir +- `test`: Test veri setini ve parametrelerini kullan + +Profiller soldan sağa uygulanır, bu nedenle sonraki profiller aynı değerleri ayarlarlarsa önceki olanları geçersiz kılar. + +### Çıkarım + +nf-core pipeline'ları konteynerler, test ve özel ortamlar için yerleşik profillerle birlikte gelir. +İhtiyacınız olan yapılandırmayı oluşturmak için birden fazla profili birleştirebilirsiniz. + +### Sırada ne var? + +Farklı hesaplama ortamları için kendi özel profillerinizi nasıl oluşturacağınızı öğrenin. + +--- + +## 3. Özel profiller oluşturma + +### 3.1. Yerel geliştirme ve HPC üzerinde çalıştırma arasında geçiş için profiller oluşturma + +İki senaryo için özel profiller oluşturalım: + +1. Docker ile yerel geliştirme +2. Slurm zamanlayıcı ve Singularity ile üniversite HPC'si + +`nextflow.config` dosyanıza aşağıdakini ekleyin: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'standard_queue' + singularity.cacheDir = '/shared/containers' + } +} +``` + +Artık ortamlar arasında kolayca geçiş yapabilirsiniz: + +```bash +# Yerel geliştirme için +nextflow run ./molkart -profile local_dev --input data/samplesheet.csv --outdir results + +# HPC için (kullanılabilir olduğunda) +nextflow run ./molkart -profile hpc_cluster --input data/samplesheet.csv --outdir results +``` + +!!! Note "Not" + + Slurm zamanlayıcısına erişimimiz olmadığı için bu eğitim ortamında HPC profilini test edemeyiz. + Ancak bu, gerçek dünya kullanımı için nasıl yapılandıracağınızı gösterir. + +### 3.2. Yapılandırmayı incelemek için `nextflow config` kullanma + +`nextflow config` komutu, pipeline'ı çalıştırmadan tamamen çözümlenmiş yapılandırmayı gösterir. + +Varsayılan yapılandırmayı görüntüleyin: + +```bash +nextflow config ./molkart +``` + +Belirli bir profille yapılandırmayı görüntüleyin: + +```bash +nextflow config -profile local_dev ./molkart +``` + +Bu şunlar için son derece kullanışlıdır: + +- Yapılandırma sorunlarını hata ayıklama +- Hangi değerlerin gerçekte kullanılacağını anlama +- Birden fazla profilin nasıl etkileşime girdiğini kontrol etme + +### Çıkarım + +Özel profiller, tek bir komut satırı bayrağıyla farklı hesaplama ortamları arasında geçiş yapmanıza olanak tanır. +Çalıştırmadan önce çözümlenmiş yapılandırmayı incelemek için `nextflow config` kullanın. + +### Sırada ne var? + +nf-core'un process etiketi sistemini kullanarak bireysel prosesler için kaynak taleplerini nasıl özelleştireceğinizi öğrenin. + +--- + +## 4. Kaynak taleplerini özelleştirme + +### 4.1. nf-core pipeline'larında process etiketlerini anlamak + +Basitlik için nf-core pipeline'ları, tüm pipeline'larda kaynak tahsisini standartlaştırmak için [**process etiketlerini**](https://www.nextflow.io/docs/latest/reference/process.html#process-label) kullanır. +Her proses, sırasıyla düşük, orta veya yüksek hesaplama kaynak gereksinimlerini tanımlamak için `process_low`, `process_medium` veya `process_high` gibi bir etiketle işaretlenir. +Bu etiketler, pipeline'ın `conf/` dizininde bulunan yapılandırma dosyalarından birinde belirli kaynak taleplerine dönüştürülür. + +```groovy title="molkart/conf/base.config (alıntı)" +process { + cpus = { 1 * task.attempt } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + + errorStrategy = { task.exitStatus in ((130..145) + 104) ? 'retry' : 'finish' } + maxRetries = 1 + maxErrors = '-1' + + withLabel:process_single { + cpus = { 1 } + memory = { 6.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_low { + cpus = { 2 * task.attempt } + memory = { 12.GB * task.attempt } + time = { 4.h * task.attempt } + } + withLabel:process_medium { + cpus = { 6 * task.attempt } + memory = { 36.GB * task.attempt } + time = { 8.h * task.attempt } + } + withLabel:process_high { + cpus = { 12 * task.attempt } + memory = { 72.GB * task.attempt } + time = { 16.h * task.attempt } + } +} +``` + +`task.attempt` çarpanına dikkat edin - bu, pipeline `process.maxRetries > 1` ile ayarlanmışsa, sonraki görev yeniden denemelerinin daha fazla kaynak talep etmesine olanak tanır. + +### 4.2. Belirli prosesler için kaynakları geçersiz kılma + +İnce ayarlı kontrol için, prosesleri isme göre hedefleyin: + +```groovy title="nextflow.config" +process { + withName: 'NFCORE_MOLKART:MOLKART:CELLPOSE' { + cpus = 16 + memory = 32.GB + } +} +``` + +Bu pipeline'ı yukarıdaki geçersiz kılmayla çalıştırmayı denersek, `CELLPOSE` prosesi, etiketi tarafından tanımlanan varsayılan yerine 16 CPU ve 32 GB bellek talep edecektir. +Bu, mevcut ortamımızda bu kadar RAM'imiz olmadığı için pipeline'ın başarısız olmasına neden olacaktır. +Bu tür başarısızlıkları bir sonraki bölümde nasıl önleyeceğimizi öğreneceğiz. + +!!! Tip "İpucu" + + Proses isimlerini bulmak için, pipeline yürütme çıktısına bakın veya `.nextflow.log` dosyasını kontrol edin. + Proses isimleri `WORKFLOW:SUBWORKFLOW:PROCESS` desenini takip eder. + +### Çıkarım + +nf-core pipeline'ları kaynak tahsisini standartlaştırmak için process etiketlerini kullanır. +Kaynakları etikete göre (birden fazla prosesi etkiler) veya isme göre (belirli bir prosesi etkiler) geçersiz kılabilirsiniz. + +### Sırada ne var? + +GitHub Codespaces gibi sınırlı ortamlarda kaynak limitlerini nasıl yöneteceğinizi öğrenin. + +--- + +## 5. Sınırlı ortamlarda kaynakları yönetme + +### 5.1. Kaynak limitleri sorunu + +molkart'ı 16 CPU ve 32 GB bellek talep eden bir prosesle çalıştırmaya çalışsaydık (bölüm 4.2'de gösterildiği gibi), mevcut ortamımızda bu kadar kaynağımız olmadığı için başarısız olurdu. +Daha büyük düğümlere sahip bir küme ortamında, bu tür talepler zamanlayıcıya gönderilirdi. + +GitHub Codespaces gibi sınırlı ortamlarda, limitler olmadan Nextflow, mevcut kaynakları aşan prosesleri çalıştırmayı reddederdi. + +### 5.2. Kaynak limitlerini ayarlama + +`resourceLimits` yönergesi, kaynak taleplerini belirtilen değerlerde sınırlar: + +```groovy title="nextflow.config" +process { + resourceLimits = [ cpus: 2, memory: 7.GB ] +} +``` + +Bu, Nextflow'a şunu söyler: "Herhangi bir proses 2 CPU'dan veya 7 GB bellekten fazlasını talep ederse, bunun yerine bu limitlere kadar sınırla." + +### 5.3. Özel profillere kaynak limitleri ekleme + +Uygun limitleri içerecek şekilde özel profillerinizi güncelleyin: + +```groovy title="nextflow.config" +profiles { + local_dev { + docker.enabled = true + process.executor = 'local' + process.resourceLimits = [ + cpus: 2, + memory: 7.GB + ] + } + + hpc_cluster { + singularity.enabled = true + process.executor = 'slurm' + process.queue = 'batch' + process.resourceLimits = [ + cpus: 32, + memory: 128.GB, + time: 24.h + ] + } +} +``` + +!!! Warning "Uyarı" + + Kaynak limitlerini çok düşük ayarlamak proseslerin başarısız olmasına veya yavaş çalışmasına neden olabilir. + Pipeline'ın daha az bellek yoğun algoritmalar kullanması veya verileri daha küçük parçalar halinde işlemesi gerekebilir. + +### Çıkarım + +Proses kaynak taleplerini sınırlayarak kaynak kısıtlı ortamlarda pipeline'ları çalıştırmak için `resourceLimits` kullanın. +Farklı profiller, ortamlarına uygun farklı limitlere sahip olabilir. + +### Sırada ne var? + +Nextflow for Bioimaging temel eğitimini tamamladınız! + +--- + +## Sonuç + +Artık Nextflow pipeline'larını farklı hesaplama ortamları için nasıl yapılandıracağınızı anlıyorsunuz. + +Öğrendiğiniz temel beceriler: + +- **Yapılandırma önceliği**: Nextflow'un ayarları birden fazla kaynaktan nasıl çözdüğü +- **nf-core profilleri**: Konteynerler, test ve yardımcı programlar için yerleşik profilleri kullanma +- **Özel profiller**: Farklı ortamlar için kendi profillerinizi oluşturma +- **Process etiketleri**: Etikete göre kaynak taleplerini anlama ve geçersiz kılma +- **Kaynak limitleri**: `resourceLimits` ile sınırlı ortamları yönetme +- **Yapılandırma incelemesi**: Ayarları hata ayıklamak ve doğrulamak için `nextflow config` kullanma + +Bu yapılandırma becerileri herhangi bir Nextflow pipeline'ına aktarılabilir ve iş akışlarını yerel makineler, HPC kümeleri ve bulut platformlarında verimli bir şekilde çalıştırmanıza yardımcı olacaktır. + +### Sırada ne var? + +Nextflow for Bioimaging kursunu tamamladığınız için tebrikler! + +Sonraki adımlar: + +- Geri bildirim sağlamak için kurs anketini doldurun +- İş akışları geliştirme hakkında daha fazla bilgi edinmek için [Hello Nextflow](../hello_nextflow/index.md) sayfasına göz atın +- nf-core araçlarına daha derinlemesine dalmak için [Hello nf-core](../hello_nf-core/index.md) sayfasını keşfedin +- [Eğitim koleksiyonlarında](../training_collections/index.md) diğer kurslara göz atın diff --git a/docs/tr/docs/nf4_science/imaging/index.md b/docs/tr/docs/nf4_science/imaging/index.md new file mode 100644 index 0000000000..78efb8bd41 --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/index.md @@ -0,0 +1,40 @@ +```yaml +--- +title: Görüntüleme için Nextflow Çalıştırma +hide: + - toc +--- + +# Görüntüleme için Nextflow Çalıştırma + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu eğitim kursu, veri analizi pipeline'larını çalıştırmak ve özelleştirmekle ilgilenen görüntüleme ve uzamsal biyoloji alanındaki araştırmacılar için tasarlanmıştır. +Molecular Cartography uzamsal transkriptomik verilerini işlemek için kullanılan bir pipeline olan [nf-core/molkart](https://nf-co.re/molkart) kullanarak workflow'ları çalıştırma, düzenleme ve yapılandırma ile ilgili temel Nextflow kavramlarını öğretir. +Burada öğrendiğiniz beceriler herhangi bir Nextflow veya nf-core pipeline'ına aktarılabilir. + +Hadi başlayalım! Eğitim ortamını başlatmak için aşağıdaki "Open in GitHub Codespaces" düğmesine tıklayın (tercihen ayrı bir sekmede), ardından yüklenirken okumaya devam edin. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Öğrenme hedefleri + +Bu kursu tamamlayarak, görüntüleme analizi pipeline'larını çalıştırmak için temel Nextflow kavramlarını ve araçlarını nasıl uygulayacağınızı öğreneceksiniz. + +Bu workshop'un sonunda şunları yapabileceksiniz: + +- Bir Nextflow workflow'unu yerel olarak başlatmak ve yürütmeyi izlemek +- Nextflow tarafından oluşturulan çıktıları (sonuçları) ve log dosyalarını bulmak ve yorumlamak +- Bir nf-core pipeline'ını test verileri ve özel girdilerle çalıştırmak +- Profiller ve parametre dosyalarını kullanarak pipeline yürütmesini yapılandırmak +- Örnek sayfaları (samplesheet) ve komut satırı parametrelerini kullanarak girdileri yönetmek + +## Hedef kitle ve ön koşullar + +Bu kurs aşağıdakiler konusunda minimal bir aşinalık varsayar: + +- Komut satırı deneyimi +- Görüntüleme dosya formatları hakkında temel bilgi (TIFF görüntüleri, tablo verileri) + +Teknik gereksinimler ve ortam kurulumu için [Ortam Kurulumu](../../envsetup/) mini kursuna bakın. +``` diff --git a/docs/tr/docs/nf4_science/imaging/next_steps.md b/docs/tr/docs/nf4_science/imaging/next_steps.md new file mode 100644 index 0000000000..12bf2617c4 --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/next_steps.md @@ -0,0 +1,41 @@ +# Sonraki adımlar + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow Biogörüntüleme eğitimini tamamladığınız için tebrikler! + +Artık görüntüleme verisi analizi için Nextflow pipeline'larını çalıştırmak ve yapılandırmak için temel becerilere sahipsiniz. + +## Öğrenmeye devam edin + +Nextflow bilginizi derinleştirmek için önerilen sonraki adımlar: + +### Daha fazla nf-core pipeline'ı keşfedin + +- **Tüm pipeline'lara göz atın**: [https://nf-co.re/pipelines](https://nf-co.re/pipelines) + +### Kendi pipeline'larınızı geliştirin + +Nextflow pipeline'ları yazmayı öğrenmek istiyorsanız: + +- **[Hello Nextflow](../../hello_nextflow/)**: Kapsamlı Nextflow geliştirme eğitimi +- **[Side Quests](../../side_quests/)**: Pipeline geliştiricileri için ileri düzey konular + +### Topluluğa katılın + +- **[Nextflow Slack](https://www.nextflow.io/slack-invite.html)**: Yardım alın ve diğer kullanıcılarla bağlantı kurun +- **[nf-core Slack](https://nf-co.re/join)**: nf-core topluluğuna katılın +- **[Seqera Community Forum](https://community.seqera.io)**: Sorular sorun ve deneyimlerinizi paylaşın + +### Ek kaynaklar + +- **[Nextflow Documentation](https://www.nextflow.io/docs/latest/)**: Eksiksiz referans dokümantasyonu +- **[nf-core Documentation](https://nf-co.re/docs)**: Kılavuzlar ve en iyi uygulamalar + +## Dahil olun + +- **nf-core'a katkıda bulunun**: Pipeline'ları veya dokümantasyonu geliştirmeye yardımcı olun +- **Workflow'larınızı paylaşın**: Kendi pipeline'larınızı topluluğa katkı olarak sunun +- **Etkinliklere katılın**: Nextflow Summit ve topluluk eğitim oturumlarına katılın + +Bizimle öğrendiğiniz için teşekkür ederiz! diff --git a/docs/tr/docs/nf4_science/imaging/survey.md b/docs/tr/docs/nf4_science/imaging/survey.md new file mode 100644 index 0000000000..f112be9e17 --- /dev/null +++ b/docs/tr/docs/nf4_science/imaging/survey.md @@ -0,0 +1,15 @@ +# Anket + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Biyogörüntüleme için Nextflow eğitimini tamamladığınız için teşekkür ederiz! + +Bu eğitim materyalini geliştirmemize yardımcı olmak için geri bildiriminizi almaktan büyük memnuniyet duyarız. + +Lütfen kısa anketimizi tamamlamak için birkaç dakikanızı ayırın: + +<div data-tf-live="01K8GYZC9RJ7ASGKJYVG5ZETQW"></div><script src="//embed.typeform.com/next/embed.js"></script> + +Yanıtlarınız, neyin iyi çalıştığını ve gelecekteki öğrenenler için neleri geliştirebileceğimizi anlamamıza yardımcı olacaktır. + +Zaman ayırdığınız ve katılımınız için teşekkür ederiz! diff --git a/docs/tr/docs/nf4_science/index.md b/docs/tr/docs/nf4_science/index.md new file mode 100644 index 0000000000..f718d1e8a2 --- /dev/null +++ b/docs/tr/docs/nf4_science/index.md @@ -0,0 +1,45 @@ +```markdown +--- +title: Bilim için Nextflow +hide: + - toc +--- + +# Bilim için Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kurslar, [Hello Nextflow](../hello_nextflow/) başlangıç kursunda sunulan kavramların ve bileşenlerin belirli bilimsel kullanım durumlarına nasıl uygulanacağını gösterir. Her kurs, öğrencilerin becerilerini aşamalı olarak geliştirmelerine yardımcı olmak için tasarlanmış bir dizi eğitim modülünden oluşur. + +!!! exercise "Genomik için Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow'da genomik için bir pipeline geliştirmeyi öğrenin. + + Bu kurs, kendi genomik pipeline'larını geliştirmek isteyen araştırmacılar içindir. Kurs, basit ama işlevsel bir genomik pipeline'ın nasıl geliştirileceğini göstermek için bir varyant çağırma kullanım durumu kullanır. + + [Genomik için Nextflow eğitimine başlayın :material-arrow-right:](genomics/){ .md-button .md-button--primary } + +!!! exercise "RNAseq için Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow'da RNAseq veri işleme için bir pipeline geliştirmeyi öğrenin. + + Bu kurs, kendi RNAseq pipeline'larını geliştirmek isteyen araştırmacılar içindir. Kurs, basit ama işlevsel bir RNAseq pipeline'ının nasıl geliştirileceğini göstermek için bir bulk RNAseq işleme kullanım durumu kullanır. + + [RNAseq için Nextflow eğitimine başlayın :material-arrow-right:](rnaseq/){ .md-button .md-button--primary } + +!!! exercise "Biyogörüntüleme için Nextflow" + + !!! tip inline end "" + + :material-run-fast: Nextflow'da görüntüleme verileri için pipeline'ları çalıştırmayı öğrenin. + + Bu kurs, biyogörüntüleme pipeline'larını çalıştırmayı ve yapılandırmayı öğrenmek isteyen araştırmacılar içindir. Kurs, herhangi bir pipeline'a uygulanabilir temel Nextflow kullanım desenlerini göstermek için nf-core/molkart kullanır. + + [Biyogörüntüleme için Nextflow eğitimine başlayın :material-arrow-right:](imaging/){ .md-button .md-button--primary } + +Topluluk forumunun [Eğitim bölümüne](https://community.seqera.io/c/training/) gönderi yaparak burada hangi diğer alanların ve kullanım durumlarının ele alınmasını istediğinizi bize bildirin. +``` diff --git a/docs/tr/docs/nf4_science/rnaseq/00_orientation.md b/docs/tr/docs/nf4_science/rnaseq/00_orientation.md new file mode 100644 index 0000000000..2c706c6552 --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/00_orientation.md @@ -0,0 +1,94 @@ +# Oryantasyon + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Eğitim ortamı, bu eğitim kursunu tamamlamak için gerekli tüm yazılımı, kodu ve veriyi içermektedir, dolayısıyla kendiniz herhangi bir şey yüklemenize gerek yoktur. +Ancak, giriş yapmak için bir (ücretsiz) hesaba ihtiyacınız var ve arayüze aşina olmak için birkaç dakikanızı ayırmalısınız. + +Henüz yapmadıysanız, lütfen daha ileri gitmeden önce [Ortam Kurulumu](../../envsetup/) mini kursunu tamamlayın. + +## Sağlanan materyaller + +Bu eğitim kursu boyunca, eğitim çalışma alanını açtığınızda içine girmeniz gereken `nf4-science/rnaseq/` dizininde çalışacağız. +Bu dizin, ihtiyaç duyacağınız tüm kod dosyalarını, test verilerini ve yardımcı dosyaları içermektedir. + +Bu dizinin içeriğini keşfetmekten çekinmeyin; bunu yapmanın en kolay yolu VSCode arayüzündeki eğitim çalışma alanının sol tarafındaki dosya gezginini kullanmaktır. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde göstermek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar bir içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 3 +``` + +??? success "Dizin içeriği" + + ```console + rnaseq + ├── data + │ ├── genome.fa + │ ├── paired-end.csv + │ ├── reads + │ │ ├── ENCSR000COQ1_1.fastq.gz + │ │ ├── ENCSR000COQ1_2.fastq.gz + │ │ ├── ENCSR000COQ2_1.fastq.gz + │ │ ├── ENCSR000COQ2_2.fastq.gz + │ │ ├── ENCSR000COR1_1.fastq.gz + │ │ ├── ENCSR000COR1_2.fastq.gz + │ │ ├── ENCSR000COR2_1.fastq.gz + │ │ ├── ENCSR000COR2_2.fastq.gz + │ │ ├── ENCSR000CPO1_1.fastq.gz + │ │ ├── ENCSR000CPO1_2.fastq.gz + │ │ ├── ENCSR000CPO2_1.fastq.gz + │ │ └── ENCSR000CPO2_2.fastq.gz + │ └── single-end.csv + ├── nextflow.config + ├── rnaseq.nf + └── solutions + ├── modules + │ ├── fastqc.nf + │ ├── fastqc_pe.nf + │ ├── hisat2_align.nf + │ ├── hisat2_align_pe.nf + │ ├── multiqc.nf + │ ├── trim_galore.nf + │ └── trim_galore_pe.nf + ├── rnaseq-2.1.nf + ├── rnaseq-2.2.nf + ├── rnaseq-2.3.nf + ├── rnaseq-3.1.nf + ├── rnaseq-3.2.nf + └── rnaseq_pe-3.3.nf + ``` + +!!!note + + Bu çok fazla gibi görünüyorsa endişelenmeyin; kursun her adımında ilgili parçaları ele alacağız. + Bu sadece size bir genel bakış sağlamak için. + +**İşte başlamak için bilmeniz gerekenlerın bir özeti:** + +- **`rnaseq.nf` dosyası**, geliştireceğimiz iş akışı betiğinin ana hatlarıdır. + +- **`nextflow.config` dosyası**, minimum ortam özelliklerini ayarlayan bir yapılandırma dosyasıdır. Şimdilik bunu göz ardı edebilirsiniz. + +- **`data` dizini**, girdi verilerini ve ilgili kaynakları içerir: + + - İnsan kromozomu 20'nin küçük bir bölgesinden oluşan (hg19/b37'den) `genome.fa` adlı _bir referans genom_. + - Dosya boyutlarını küçük tutmak için küçük bir bölgeye indirilmiş, `reads/` dizinindeki _RNAseq verileri_. + - Örnek veri dosyalarının kimliklerini ve yollarını listeleyen, toplu işleme için _CSV dosyaları_. + +- **`solutions` dizini**, kursun her adımından kaynaklanan tamamlanmış iş akışı betiklerini ve modüllerini içerir. + Bunlar, çalışmanızı kontrol etmek ve sorunları gidermek için referans olarak kullanılmak üzere tasarlanmıştır. + Dosya adındaki numara, kursun ilgili bölümünün adımına karşılık gelir. + +!!!tip + + Herhangi bir nedenle bu dizinden çıkarsanız, oraya geri dönmek için her zaman şu komutu çalıştırabilirsiniz: + + ```bash + cd /workspaces/training/nf4-science/rnaseq + ``` + +Şimdi, kursa başlamak için bu sayfanın sağ alt köşesindeki oka tıklayın. diff --git a/docs/tr/docs/nf4_science/rnaseq/01_method.md b/docs/tr/docs/nf4_science/rnaseq/01_method.md new file mode 100644 index 0000000000..37291eca86 --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/01_method.md @@ -0,0 +1,438 @@ +# Bölüm 1: Yönteme genel bakış ve manuel test + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Toplu RNAseq verilerini işlemek ve analiz etmek için birden fazla geçerli yöntem bulunmaktadır. +Bu kurs için, [Babraham Enstitüsü](https://www.babraham.ac.uk/)'nden Dr. Simon Andrews ve Laura Biggins tarafından [burada](https://www.bioinformatics.babraham.ac.uk/training/RNASeq_Course/Analysing%20RNA-Seq%20data%20Exercise.pdf) açıklanan yöntemi takip ediyoruz. + +Amacımız, aşağıdaki işleme adımlarını uygulayan bir iş akışı geliştirmektir: toplu RNAseq örneğindeki okumalar üzerinde ilk kalite kontrolünü çalıştırmak, okumalardan adaptör dizilerini kırpmak, okumaları referans genoma hizalamak ve kapsamlı bir kalite kontrol (QC) raporu oluşturmak. + +<figure class="excalidraw"> +--8<-- "docs/nf4_science/rnaseq/img/preprocess.svg" +</figure> + +- **FASTQC:** Kırpma öncesi okuma verileri üzerinde FastQC kullanarak QC gerçekleştirin +- **TRIM_GALORE:** Trim Galore kullanarak adaptör dizilerini kırpın ve kırpma sonrası QC gerçekleştirin (Cutadapt ve FastQC'yi bir araya getirir) +- **HISAT2_ALIGN:** Hisat2 kullanarak okumaları referans genoma hizalayın +- **MULTIQC:** MultiQC kullanarak kapsamlı bir QC raporu oluşturun + +Ancak, herhangi bir iş akışı kodu yazmaya başlamadan önce, komutları bazı test verileri üzerinde manuel olarak deneyeceğiz. +İhtiyacımız olan araçlar GitHub Codespaces ortamında yüklü olmadığından, bunları konteynerler aracılığıyla kullanacağız (bkz. [Merhaba Konteynerler](../../hello_nextflow/05_hello_containers.md)). + +!!! note "Not" + + `nf4-science/rnaseq` dizininde olduğunuzdan emin olun. `pwd` yazdığınızda gösterilen yolun son kısmı `rnaseq` olmalıdır. + +--- + +## 1. İlk QC ve adaptör kırpma + +Hem `fastqc` hem de `trim_galore` yüklü bir konteyner imajını çekeceğiz, etkileşimli olarak başlatacağız ve örnek veri dosyalarından biri üzerinde kırpma ve QC komutlarını çalıştıracağız. + +### 1.1. Konteyneri çekin + +```bash +docker pull community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +Bu, sistem imajı indirirken aşağıdaki konsol çıktısını verir: + +??? success "Komut çıktısı" + + ```console + 0.6.10--1bf8ca4e1967cd18: Pulling from library/trim-galore + dafa2b0c44d2: Pull complete + dec6b097362e: Pull complete + f88da01cff0b: Pull complete + 4f4fb700ef54: Pull complete + 92dc97a3ef36: Pull complete + 403f74b0f85e: Pull complete + 10b8c00c10a5: Pull complete + 17dc7ea432cc: Pull complete + bb36d6c3110d: Pull complete + 0ea1a16bbe82: Pull complete + 030a47592a0a: Pull complete + 32ec762be2d0: Pull complete + d2cb90387285: Pull complete + Digest: sha256:4f00e7b2a09f3c8d8a9ce955120e177152fb1e56f63a2a6e186088b1250d9907 + Status: Downloaded newer image for community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 + ``` + +### 1.2. Konteyneri etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18 +``` + +<!-- +??? success "Komut çıktısı" + + ```console + + ``` +--> + +İsteminiz `(base) root@b645838b3314:/tmp#` gibi bir şeye dönüşecek, bu da artık konteynerin içinde olduğunuzu gösterir. + +Komutun `-v ./data:/data` kısmı, `data/` dizininin içeriğine konteyner içinden erişmemizi sağlayacaktır. + +```bash +ls /data/reads +``` + +??? success "Komut çıktısı" + + ```console + ENCSR000COQ1_1.fastq.gz ENCSR000COQ2_2.fastq.gz ENCSR000COR2_1.fastq.gz ENCSR000CPO1_2.fastq.gz + ENCSR000COQ1_2.fastq.gz ENCSR000COR1_1.fastq.gz ENCSR000COR2_2.fastq.gz ENCSR000CPO2_1.fastq.gz + ENCSR000COQ2_1.fastq.gz ENCSR000COR1_2.fastq.gz ENCSR000CPO1_1.fastq.gz ENCSR000CPO2_2.fastq.gzO + ``` + +### 1.3. İlk `fastqc` komutunu çalıştırın + +Okuma verileri üzerinde kalite kontrol metriklerini toplamak için `fastqc`'yi çalıştıralım. + +```bash +fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +??? success "Komut çıktısı" + + ```console + application/gzip + Started analysis of ENCSR000COQ1_1.fastq.gz + Approx 5% complete for ENCSR000COQ1_1.fastq.gz + Approx 10% complete for ENCSR000COQ1_1.fastq.gz + Approx 15% complete for ENCSR000COQ1_1.fastq.gz + Approx 20% complete for ENCSR000COQ1_1.fastq.gz + Approx 25% complete for ENCSR000COQ1_1.fastq.gz + Approx 30% complete for ENCSR000COQ1_1.fastq.gz + Approx 35% complete for ENCSR000COQ1_1.fastq.gz + Approx 40% complete for ENCSR000COQ1_1.fastq.gz + Approx 45% complete for ENCSR000COQ1_1.fastq.gz + Approx 50% complete for ENCSR000COQ1_1.fastq.gz + Approx 55% complete for ENCSR000COQ1_1.fastq.gz + Approx 60% complete for ENCSR000COQ1_1.fastq.gz + Approx 65% complete for ENCSR000COQ1_1.fastq.gz + Approx 70% complete for ENCSR000COQ1_1.fastq.gz + Approx 75% complete for ENCSR000COQ1_1.fastq.gz + Approx 80% complete for ENCSR000COQ1_1.fastq.gz + Approx 85% complete for ENCSR000COQ1_1.fastq.gz + Approx 90% complete for ENCSR000COQ1_1.fastq.gz + Approx 95% complete for ENCSR000COQ1_1.fastq.gz + Analysis complete for ENCSR000COQ1_1.fastq.gz + ``` + +Bu çok hızlı çalışmalıdır. +Çıktı dosyalarını orijinal verilerle aynı dizinde bulabilirsiniz: + +```bash +ls /data/reads/ENCSR000COQ1_1_fastqc* +``` + +<!-- switch to tree --> + +```console title="Çıktı" +/data/reads/ENCSR000COQ1_1_fastqc.html /data/reads/ENCSR000COQ1_1_fastqc.zip +``` + +### 1.4. `trim_galore` ile adaptör dizilerini kırpın + +Şimdi adaptör dizilerini kırpmak ve kırpma sonrası QC metriklerini toplamak için Cutadapt ve FastQC'yi bir araya getiren `trim_galore`'ı çalıştıralım. + +```bash +trim_galore --fastqc /data/reads/ENCSR000COQ1_1.fastq.gz +``` + +`--fastqc` bayrağı, kırpma tamamlandıktan sonra komutun otomatik olarak bir QC toplama adımı çalıştırmasını sağlar. + +_Çıktı çok ayrıntılı olduğu için aşağıdaki kısaltılmıştır._ + +??? success "Komut çıktısı" + + ```console + Multicore support not enabled. Proceeding with single-core trimming. + Path to Cutadapt set as: 'cutadapt' (default) + Cutadapt seems to be working fine (tested command 'cutadapt --version') + Cutadapt version: 4.9 + single-core operation. + igzip command line interface 2.31.0 + igzip detected. Using igzip for decompressing + + <...> + + Analysis complete for ENCSR000COQ1_1_trimmed.fq.gz + ``` + +Çıktı dosyalarını çalışma dizininde bulabilirsiniz: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Çıktı" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.html +ENCSR000COQ1_1_trimmed.fq.gz ENCSR000COQ1_1_trimmed_fastqc.zip +``` + +### 1.5. Çıktı dosyalarını konteyner dışındaki dosya sistemine taşıyın + +Konteyner içinde kalan her şey gelecekteki çalışmalara erişilemez olacağından bunları yeni bir dizine taşıyalım. + +```bash +mkdir /data/trimmed +mv ENCSR000COQ1_1* /data/trimmed +``` + +### 1.6. Konteynerden çıkın + +```bash +exit +``` + +--- + +## 2. Okumaları referans genoma hizalayın + +`hisat2`'nin yüklü olduğu bir konteyner imajını çekeceğiz, etkileşimli olarak başlatacağız ve RNAseq verilerini referans genoma hizalamak için hizalama komutunu çalıştıracağız. + +### 2.1. `hisat2` konteynerini çekin + +```bash +docker pull community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +??? success "Komut çıktısı" + + ```console + Unable to find image 'community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e' locally + 5e49f68a37dc010e: Pulling from library/hisat2_samtools + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + e74ed5dd390b: Pull complete + abfcf0185e51: Pull complete + Digest: sha256:29d8e1a3172a2bdde7be813f7ebec22d331388194a7c0de872b4ccca4bed8f45 + Status: Downloaded newer image for community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e + ``` + +### 2.2. `hisat2` konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e +``` + +Komut daha öncekiyle aynıdır, ilgili konteyner URI'si değiştirilmiştir. + +### 2.3. Hisat2 genom dizin dosyalarını oluşturun + +Hisat2, genom referansının çok özel bir biçimde sağlanmasını gerektirir ve sağladığımız `genome.fa` FASTA dosyasını doğrudan kullanamaz, bu nedenle bu fırsatı ilgili kaynakları oluşturmak için kullanacağız. + +```bash +hisat2-build /data/genome.fa genome_index +``` + +Çıktı çok ayrıntılı olduğundan aşağıdaki kısaltılmıştır: + +<!-- TODO: switch to full output --> + +??? success "Komut çıktısı" + + ```console + Settings: + Output files: "genome_index.*.ht2" + <...> + Total time for call to driver() for forward index: 00:00:16 + ``` + +Bu, çalışma dizininde bulabileceğiniz birden fazla genom dizin dosyası oluşturur. + +```bash +ls genome_index.* +``` + +```console title="Çıktı" +genome_index.1.ht2 genome_index.3.ht2 genome_index.5.ht2 genome_index.7.ht2 +genome_index.2.ht2 genome_index.4.ht2 genome_index.6.ht2 genome_index.8.ht2 +``` + +Bunları birazdan kullanacağız, ancak önce bu genom dizin dosyalarıyla sıkıştırılmış bir tarball oluşturalım; bunlara daha sonra ihtiyacımız olacak ve bunları oluşturmak tipik olarak bir iş akışının parçası olarak yapmak istediğimiz bir şey değildir. + +```bash +tar -czvf /data/genome_index.tar.gz genome_index.* +``` + +Bu, genom dizin dosyalarını içeren bir `genome_index.tar.gz` tarball'ını dosya sistemimizde `data/` dizininde saklar, bu da bu kursun 2. Bölümünde işimize yarayacaktır. + +### 2.4. `hisat2` komutunu çalıştırın + +Şimdi hizalama komutunu çalıştırabiliriz, bu komut `hisat2` ile hizalama adımını gerçekleştirir ve ardından çıktıyı bir BAM dosyası olarak yazmak için `samtools`'a aktarır. + +Okuma verisi girdisi, önceki adımda `trim_galore` ile oluşturduğumuz `/data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz` dosyasıdır. + +```bash +hisat2 -x genome_index -U /data/trimmed/ENCSR000COQ1_1_trimmed.fq.gz \ + --new-summary --summary-file ENCSR000COQ1_1_trimmed.hisat2.log | \ + samtools view -bS -o ENCSR000COQ1_1_trimmed.bam +``` + +??? success "Komut çıktısı" + + ```console + HISAT2 summary stats: + Total reads: 27816 + Aligned 0 time: 1550 (5.57%) + Aligned 1 time: 25410 (91.35%) + Aligned >1 times: 856 (3.08%) + Overall alignment rate: 94.43% + ``` + +Bu, çok küçük bir test dosyası olduğu için neredeyse anında çalışır. +Gerçek ölçekte bu çok daha uzun sürebilir. + +Bir kez daha çıktı dosyalarını çalışma dizininde bulabilirsiniz: + +```bash +ls ENCSR000COQ1_1* +``` + +```console title="Çıktı" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +### 2.5. Çıktı dosyalarını konteyner dışındaki dosya sistemine taşıyın + +```bash +mkdir /data/aligned +mv ENCSR000COQ1_1* /data/aligned +``` + +### 2.6. Konteynerden çıkın + +```bash +exit +``` + +--- + +## 3. Kapsamlı bir QC raporu oluşturun + +`multiqc`'nin yüklü olduğu bir konteyner imajını çekeceğiz, etkileşimli olarak başlatacağız ve öncesi/sonrası FastQC rapor dosyaları üzerinde bir rapor oluşturma komutu çalıştıracağız. + +### 3.1. `multiqc` konteynerini çekin + +```bash +docker pull community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +??? success "Komut çıktısı" + + ```console + ad8f247edb55897c: Pulling from library/pip_multiqc + dafa2b0c44d2: Already exists + dec6b097362e: Already exists + f88da01cff0b: Already exists + 4f4fb700ef54: Already exists + 92dc97a3ef36: Already exists + 403f74b0f85e: Already exists + 10b8c00c10a5: Already exists + 17dc7ea432cc: Already exists + bb36d6c3110d: Already exists + 0ea1a16bbe82: Already exists + 030a47592a0a: Already exists + 3f229294c69a: Pull complete + 5a5ad47fd84c: Pull complete + Digest: sha256:0ebb1d9605395a7df49ad0eb366b21f46afd96a5090376b0d8941cf5294a895a + Status: Downloaded newer image for community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c + ``` + +### 3.2. `multiqc` konteynerini etkileşimli olarak başlatın + +```bash +docker run -it -v ./data:/data community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c +``` + +### 3.3. `multiqc` komutunu çalıştırın + +```bash +multiqc /data/reads /data/trimmed /data/aligned -n ENCSR000COQ1_1_QC +``` + +??? success "Komut çıktısı" + + ```console + + /// MultiQC 🔍 v1.27.1 + + file_search | Search path: /data/reads + file_search | Search path: /data/trimmed + file_search | Search path: /data/aligned + searching | ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 20/20 + hisat2 | Found 1 reports + cutadapt | Found 1 reports + fastqc | Found 1 reports + write_results | Data : ENCSR000COQ1_1_QC_data + write_results | Report : ENCSR000COQ1_1_QC.html + multiqc | MultiQC complete + ``` + +MultiQC, uyumlu QC raporları için dizinlerde arama yapabilir ve bulduğu her şeyi birleştirir. + +Burada aracın oluşturduğumuz üç QC raporunu da bulduğunu görüyoruz: `fastqc` ile yaptığımız ilk QC, `cutadapt`'ten (via `trim_galore`) kırpma sonrası rapor ve `hisat2` tarafından üretilen hizalama sonrası QC. + +Çıktı dosyaları bir kez daha çalışma dizinindedir: + +```bash +ls ENCSR000COQ1_1_QC* +``` + +```console title="Çıktı" +ENCSR000COQ1_1_QC.html + +ENCSR000COQ1_1_QC_data: +cutadapt_filtered_reads_plot.txt fastqc_top_overrepresented_sequences_table.txt +cutadapt_trimmed_sequences_plot_3_Counts.txt hisat2_se_plot.txt +cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt multiqc.log +fastqc-status-check-heatmap.txt multiqc_citations.txt +fastqc_adapter_content_plot.txt multiqc_cutadapt.txt +fastqc_per_base_n_content_plot.txt multiqc_data.json +fastqc_per_base_sequence_quality_plot.txt multiqc_fastqc.txt +fastqc_per_sequence_gc_content_plot_Counts.txt multiqc_general_stats.txt +fastqc_per_sequence_gc_content_plot_Percentages.txt multiqc_hisat2.txt +fastqc_per_sequence_quality_scores_plot.txt multiqc_software_versions.txt +fastqc_sequence_counts_plot.txt multiqc_sources.txt +fastqc_sequence_duplication_levels_plot.txt +``` + +### 3.4. Çıktı dosyalarını konteyner dışındaki dosya sistemine taşıyın + +```bash +mkdir /data/final_qc +mv ENCSR000COQ1_1_QC** /data/final_qc +``` + +### 3.5. Konteynerden çıkın + +```bash +exit +``` + +--- + +### Çıkarımlar + +Tüm bireysel komutları ilgili konteynerlerde etkileşimli olarak test ettiniz. + +### Sırada ne var? + +Aynı komutları, çalışmayı yürütmek için konteynerler kullanan çok adımlı bir iş akışına nasıl sarmalayacağınızı öğrenin. diff --git a/docs/tr/docs/nf4_science/rnaseq/02_single-sample.md b/docs/tr/docs/nf4_science/rnaseq/02_single-sample.md new file mode 100644 index 0000000000..801810e7ad --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/02_single-sample.md @@ -0,0 +1,402 @@ +# Bölüm 2: Tek örnek implementasyonu + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kurumun bu bölümünde, Bölüm 1'de çalıştırdığımız tüm komutları otomatikleştirmek için mümkün olan en basit iş akışını yazacağız ve her seferinde yalnızca bir örnek işlemeyi hedefleyeceğiz. + +Bunu üç aşamada yapacağız: + +1. İlk kalite kontrol adımını çalıştıran tek aşamalı bir iş akışı yazın +2. Adaptör kırpma ve kırpma sonrası kalite kontrolünü ekleyin +3. Referans genoma hizalamayı ekleyin + +!!! warning "Ön Koşul" + + Bu derse başlamadan önce kursun Bölüm 1'ini tamamlamanız gerekmektedir. + Özellikle, 2.1-3 bölümlerini tamamlamak bu dersteki hizalama adımı için gereken genom dizin dosyasını (`data/genome_index.tar.gz`) oluşturur. + +--- + +## 1. İlk kalite kontrolünü çalıştıran tek aşamalı bir iş akışı yazın + +Tek uçlu RNAseq okumalarını içeren bir FASTQ dosyası üzerinde FastQC aracını çalıştıran basit bir iş akışı yazarak başlayalım. + +Size iş akışının ana bölümlerini özetleyen `rnaseq.nf` adında bir iş akışı dosyası sağlıyoruz. + +```groovy title="rnaseq.nf" linenums="1" +#!/usr/bin/env nextflow + +// Modül INCLUDE ifadeleri + +/* + * Pipeline parametreleri + */ + +// Birincil girdi + +workflow { + + // Girdi kanalı oluştur + + // Process'leri çağır + +} +``` + +Bu iş akışı kodunun doğru ancak işlevsel olmadığını unutmayın; amacı yalnızca gerçek iş akışını yazmak için kullanacağınız bir iskelet görevi görmektir. + +### 1.1. Modülleri depolamak için bir dizin oluşturun + +Her bir process için bağımsız modüller oluşturacağız, böylece bunları yönetmeyi ve yeniden kullanmayı kolaylaştıracağız. Hadi bunları depolamak için bir dizin oluşturalım. + +```bash +mkdir modules +``` + +### 1.2. Kalite kontrol metrikleri toplama process'i için bir modül oluşturun + +`FASTQC` process'ini barındırmak için `modules/fastqc.nf` adında bir modül dosyası oluşturalım: + +```bash +touch modules/fastqc.nf +``` + +Dosyayı kod düzenleyicide açın ve içine aşağıdaki kodu kopyalayın: + +```groovy title="modules/fastqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process FASTQC { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/fastqc", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_fastqc.zip", emit: zip + path "${reads.simpleName}_fastqc.html", emit: html + + script: + """ + fastqc $reads + """ +} +``` + +Bu eğitim serisinin Bölüm 1 ve Bölüm 2'de öğrendiklerinizden tüm parçaları tanıyor olmalısınız; dikkate değer tek değişiklik bu sefer `publishDir` yönergesi için `mode: symlink` kullanıyor olmamız ve `publishDir` tanımlamak için bir parametre kullanıyor olmamızdır. + +!!! note + + Burada kullandığımız veri dosyaları çok küçük olsa da, genomikte çok büyük olabilirler. Öğretim ortamında gösterim amacıyla, gereksiz dosya kopyalarından kaçınmak için 'symlink' yayınlama modunu kullanıyoruz. Bunu son iş akışlarınızda yapmamalısınız, çünkü `work` dizininizi temizlediğinizde sonuçları kaybedersiniz. + +### 1.3. Modülü iş akışı dosyasına import edin + +`rnaseq.nf` dosyasına `include { FASTQC } from './modules/fastqc.nf'` ifadesini ekleyin: + +```groovy title="rnaseq.nf" linenums="3" +// Modül INCLUDE ifadeleri +include { FASTQC } from './modules/fastqc.nf' +``` + +### 1.4. Bir girdi bildirimi ekleyin + +Varsayılan değere sahip bir girdi parametresi bildirin: + +```groovy title="rnaseq.nf" linenums="10" +params { + // Birincil girdi + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" +} +``` + +### 1.5. İş akışı bloğunda bir girdi kanalı oluşturun + +Girdi kanalını oluşturmak için temel bir `.fromPath()` kanal fabrikası kullanın: + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Girdi kanalı oluştur from a file path + read_ch = channel.fromPath(params.reads) + + // Process'leri çağır + +} +``` + +### 1.6. Girdi kanalı üzerinde `FASTQC` process'ini çağırın + +```groovy title="rnaseq.nf" linenums="13" +workflow { + + // Girdi kanalı oluştur from a file path + read_ch = channel.fromPath(params.reads) + + // İlk kalite kontrolü + FASTQC(read_ch) + +} +``` + +### 1.7. Çalıştığını test etmek için iş akışını çalıştırın + +Komut satırından bir girdi belirtmek için `--reads` parametresini kullanabiliriz, ancak geliştirme sırasında tembel olabilir ve kurduğumuz test varsayılanını kullanabiliriz. + +```bash +nextflow run rnaseq.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + ``` + +Bölüm 1'i tamamladıysanız ve konteyneri zaten çektiyseniz bu çok hızlı çalışmalıdır. +Eğer atladıysanız, Nextflow konteyneri sizin için çekecektir; bunun gerçekleşmesi için bir şey yapmanıza gerek yok, ancak bir dakika kadar beklemeniz gerekebilir. + +Çıktıları `FASTQC` process'inde `publishDir` yönergesi tarafından belirtildiği şekilde `results/fastqc` altında bulabilirsiniz. + +```bash +ls results/fastqc +``` + +```console title="Çıktı" +ENCSR000COQ1_1_fastqc.html ENCSR000COQ1_1_fastqc.zip +``` + +--- + +## 2. Adaptör kırpma ve kırpma sonrası kalite kontrolünü ekleyin + +Kırpma işlemi için Cutadapt'i ve kırpma sonrası kalite kontrolü için FastQC'yi bir araya getiren Trim_Galore sarmalayıcısını kullanacağız. + +### 2.1. Kırpma ve kalite kontrol process'i için bir modül oluşturun + +`TRIM_GALORE` process'ini barındırmak için `modules/trim_galore.nf` adında bir modül dosyası oluşturalım: + +```bash +touch modules/trim_galore.nf +``` + +Dosyayı kod düzenleyicide açın ve içine aşağıdaki kodu kopyalayın: + +```groovy title="modules/trim_galore.nf" linenums="1" +#!/usr/bin/env nextflow + +process TRIM_GALORE { + + container "community.wave.seqera.io/library/trim-galore:0.6.10--1bf8ca4e1967cd18" + publishDir "results/trimming", mode: 'symlink' + + input: + path reads + + output: + path "${reads.simpleName}_trimmed.fq.gz", emit: trimmed_reads + path "${reads}_trimming_report.txt", emit: trimming_reports + path "${reads.simpleName}_trimmed_fastqc.{zip,html}", emit: fastqc_reports + + script: + """ + trim_galore --fastqc $reads + """ +} +``` + +### 2.2. Modülü iş akışı dosyasına import edin + +`rnaseq.nf` dosyasına `include { TRIM_GALORE } from './modules/trim_galore.nf'` ifadesini ekleyin: + +```groovy title="rnaseq.nf" linenums="3" +// Modül INCLUDE ifadeleri +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +``` + +### 2.3. Girdi kanalı üzerinde process'i çağırın + +```groovy title="rnaseq.nf" linenums="14" +workflow { + + // Girdi kanalı oluştur from a file path + read_ch = channel.fromPath(params.reads) + + // İlk kalite kontrolü + FASTQC(read_ch) + + // Adaptör kırpma ve kırpma sonrası QC + TRIM_GALORE(read_ch) +} +``` + +### 2.4. Çalıştığını test etmek için iş akışını çalıştırın + +```bash +nextflow run rnaseq.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [fabulous_snyder] DSL2 - revision: 3394c725ee + + executor > local (1) + [d6/d94c3a] FASTQC (1) [100%] 1 of 1 ✔ + [c2/e4a9bb] TRIM_GALORE (1) [100%] 1 of 1 ✔ + ``` + +Bu da çok hızlı çalışmalıdır, çünkü çok küçük bir girdi dosyası üzerinde çalışıyoruz. + +Çıktıları `TRIM_GALORE` process'inde `publishDir` yönergesi tarafından belirtildiği şekilde `results/trimming` altında bulabilirsiniz. + +```bash +ls results/trimming +``` + +```console title="Çıktı" +ENCSR000COQ1_1.fastq.gz_trimming_report.txt ENCSR000COQ1_1_trimmed_fastqc.zip +ENCSR000COQ1_1_trimmed_fastqc.html ENCSR000COQ1_1_trimmed.fq.gz +``` + +--- + +## 3. Okumaları referans genoma hizalayın + +Son olarak, FastQC tarzı kalite kontrol metriklerini de yayınlayacak olan Hisat2 kullanarak genom hizalama adımını çalıştırabiliriz. + +### 3.1. HiSat2 process'i için bir modül oluşturun + +`HISAT2_ALIGN` process'ini barındırmak için `modules/hisat2_align.nf` adında bir modül dosyası oluşturalım: + +```bash +touch modules/hisat2_align.nf +``` + +Dosyayı kod düzenleyicide açın ve içine aşağıdaki kodu kopyalayın: + +```groovy title="modules/hisat2_align.nf" linenums="1" +#!/usr/bin/env nextflow + +process HISAT2_ALIGN { + + container "community.wave.seqera.io/library/hisat2_samtools:5e49f68a37dc010e" + publishDir "results/align", mode: 'symlink' + + input: + path reads + path index_zip + + output: + path "${reads.simpleName}.bam", emit: bam + path "${reads.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -U $reads \ + --new-summary --summary-file ${reads.simpleName}.hisat2.log | \ + samtools view -bS -o ${reads.simpleName}.bam + """ +} +``` + +### 3.2. Modülü iş akışı dosyasına import edin + +`rnaseq.nf` dosyasına `include { HISAT2_ALIGN } from './modules/hisat2_align.nf'` ifadesini ekleyin: + +```groovy title="rnaseq.nf" linenums="3" +// Modül INCLUDE ifadeleri +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +``` + +### 3.3. Genom dizinini sağlamak için bir parametre bildirimi ekleyin + +Varsayılan değere sahip bir girdi parametresi bildirin: + +```groovy title="rnaseq.nf" linenums="8" +params { + // Birincil girdi + reads: Path = "data/reads/ENCSR000COQ1_1.fastq.gz" + + // Referans genom arşivi + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 3.4. `TRIM_GALORE` tarafından çıktılanan kırpılmış okumalar üzerinde `HISAT2_ALIGN` process'ini çağırın + +Kırpılmış okumalar, önceki adım tarafından çıktılanan `TRIM_GALORE.out.trimmed_reads` kanalındadır. + +Ek olarak, Hisat2 aracına sıkıştırılmış genom dizini tarball'ını sağlamak için `file (params.hisat2_index_zip)` kullanıyoruz. + +```groovy title="rnaseq.nf" linenums="16" +workflow { + + // Girdi kanalı oluştur from a file path + read_ch = channel.fromPath(params.reads) + + // İlk kalite kontrolü + FASTQC(read_ch) + + // Adaptör kırpma ve kırpma sonrası QC + TRIM_GALORE(read_ch) + + // Referans genoma hizalama + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) +} +``` + +### 3.5. Çalıştığını test etmek için iş akışını çalıştırın + +```bash +nextflow run rnaseq.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [extravagant_khorana] DSL2 - revision: 701b41bd16 + + executor > local (3) + [e4/d15ad4] FASTQC (1) [100%] 1 of 1 ✔ + [c6/12b2be] TRIM_GALORE (1) [100%] 1 of 1 ✔ + [c6/7a9f13] HISAT2_ALIGN (1) [100%] 1 of 1 ✔ + ``` + +Çıktıları `HISAT2_ALIGN` process'inde `publishDir` yönergesi tarafından belirtildiği şekilde `results/align` altında bulabilirsiniz. + +```bash +ls results/align +``` + +```console title="Çıktı" +ENCSR000COQ1_1_trimmed.bam ENCSR000COQ1_1_trimmed.hisat2.log +``` + +Bu, her bir örneğe uygulamamız gereken temel işlemi tamamlar. + +_MultiQC rapor toplama işlemini Bölüm 2'de, iş akışını aynı anda birden fazla örneği kabul edecek şekilde değiştirdikten sonra ekleyeceğiz._ + +--- + +### Çıkarımlar + +Tek uçlu RNAseq örneklerini tek tek işlemek için tüm temel adımları nasıl sarmalayacağınızı biliyorsunuz. + +### Sırada ne var? + +İş akışını birden fazla örneği paralel olarak işleyecek şekilde nasıl değiştireceğinizi, tüm örnekler için tüm adımlarda kalite kontrol raporlarını nasıl toplayacağınızı ve iş akışını çift uçlu RNAseq verileri üzerinde çalışacak şekilde nasıl etkinleştireceğinizi öğrenin. diff --git a/docs/tr/docs/nf4_science/rnaseq/03_multi-sample.md b/docs/tr/docs/nf4_science/rnaseq/03_multi-sample.md new file mode 100644 index 0000000000..1fe86b0f12 --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/03_multi-sample.md @@ -0,0 +1,524 @@ +# Bölüm 3: Çok-örnekli paired-end uygulaması + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu kursun son bölümünde, basit iş akışımızı bir üst seviyeye taşıyarak keyfi sayıda örneği işleyebilen güçlü bir toplu otomasyon aracına dönüştüreceğiz. +Bunu yaparken, aynı zamanda yeni çalışmalarda daha yaygın olan paired-end verileri kabul edecek şekilde de değiştireceğiz. + +Bunu üç aşamada yapacağız: + +1. İş akışının birden fazla girdi örneğini kabul etmesini ve yürütmeyi paralelleştirmesini sağlama +2. Kapsamlı QC raporu oluşturma ekleme +3. Paired-end RNAseq verilerine geçiş + +--- + +## 1. İş akışının birden fazla girdi örneğini kabul etmesini ve yürütmeyi paralelleştirmesini sağlama + +Girdileri nasıl yönettiğimizi değiştirmemiz gerekecek. + +### 1.1. Birincil girdiyi tek bir dosya yerine dosya yollarının CSV'si olacak şekilde değiştirme + +`data/` dizininde örnek ID'leri ve FASTQ dosya yollarını içeren bir CSV dosyası sağlıyoruz. +Bu CSV dosyası bir başlık satırı içerir. +FASTQ dosya yollarının mutlak yollar olduğuna dikkat edin. + +```csv title="data/single-end.csv" linenums="1" +sample_id,fastq_path +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz +``` + +Birincil girdi parametresini `input_csv` olarak yeniden adlandıralım ve varsayılanı `single-end.csv` dosyasının yolu olacak şekilde değiştirelim. + +```groovy title="rnaseq.nf" linenums="13" +params { + // Birincil girdi + input_csv: Path = "data/single-end.csv" + + // Referans genom arşivi + hisat2_index_zip: Path = "data/genome_index.tar.gz" +} +``` + +### 1.2. Girdi olarak bir CSV'yi işlemek için girdi kanalı fabrikasını güncelleme + +Dosyanın içeriğini sadece dosya yolu yerine kanala yüklemek isteyeceğiz, bu nedenle CSV formatını ayrıştırmak için `.splitCsv()` operatörünü, ardından istediğimiz belirli bilgi parçasını (FASTQ dosya yolunu) almak için `.map()` operatörünü kullanıyoruz. + +```groovy title="rnaseq.nf" linenums="16" + // Bir CSV dosyasının içeriğinden girdi kanalı oluşturma + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } +``` + +### 1.3. İş akışının çalıştığını test etmek için çalıştırma + +```bash +nextflow run rnaseq.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [golden_curry] DSL2 - revision: 2a5ba5be1e + + executor > local (18) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6 ✔ + [cc/16859f] TRIM_GALORE (6) [100%] 6 of 6 ✔ + [68/4c27b5] HISAT2_ALIGN (6) [100%] 6 of 6 ✔ + ``` + +Bu sefer her adımın sağladığımız 6 veri dosyasının her birinde 6 kez çalıştırıldığını görüyoruz. + +İş akışını birden fazla dosya üzerinde çalıştırmak için gereken tek şey buydu! +Nextflow tüm paralelliği bizim için yönetiyor. + +--- + +## 2. Ön işleme QC metriklerini tek bir MultiQC raporunda toplama + +Tüm bunlar çok sayıda QC raporu üretiyor ve bireysel raporları incelemek zorunda kalmak istemiyoruz. +Bu, bir MultiQC raporu toplama adımı eklemek için mükemmel bir nokta! + +### 2.1. QC toplama işlemi için bir modül oluşturma + +`MULTIQC` işlemini barındırmak için `modules/multiqc.nf` adlı bir modül dosyası oluşturalım: + +```bash +touch modules/multiqc.nf +``` + +Dosyayı kod düzenleyicide açın ve aşağıdaki kodu içine kopyalayın: + +```groovy title="modules/multiqc.nf" linenums="1" +#!/usr/bin/env nextflow + +process MULTIQC { + + container "community.wave.seqera.io/library/pip_multiqc:a3c26f6199d64b7c" + publishDir "results/multiqc", mode: 'symlink' + + input: + path '*' + val output_name + + output: + path "${output_name}.html", emit: report + path "${output_name}_data", emit: data + + script: + """ + multiqc . -n ${output_name}.html + """ +} +``` + +### 2.2. Modülü iş akışı dosyasına aktarma + +`rnaseq.nf` dosyasına `include { MULTIQC } from './modules/multiqc.nf'` ifadesini ekleyin: + +```groovy title="rnaseq.nf" linenums="3" +// Modül INCLUDE ifadeleri +include { FASTQC } from './modules/fastqc.nf' +include { TRIM_GALORE } from './modules/trim_galore.nf' +include { HISAT2_ALIGN } from './modules/hisat2_align.nf' +include { MULTIQC } from './modules/multiqc.nf' +``` + +### 2.3. Bir `report_id` parametresi ekleme ve mantıklı bir varsayılan değer verme + +```groovy title="rnaseq.nf" linenums="9" +params { + // Birincil girdi + input_csv: Path = "data/single-end.csv" + + // Referans genom arşivi + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Rapor ID'si + report_id: String = "all_single-end" +} +``` + +### 2.4. İşlemi önceki adımların çıktıları üzerinde çağırma + +`MULTIQC` işlemine önceki adımlardan gelen tüm QC ile ilgili çıktıları vermemiz gerekiyor. + +Bunun için, birden fazla kanalı tek bir kanalda toplayan `.mix()` operatörünü kullanacağız. + +A, B, C ve D adlı dört işlemimiz olsaydı ve her birinin basit bir `.out` kanalı olsaydı, sözdizimi şöyle görünürdü: `A.out.mix( B.out, C.out, D.out )`. Gördüğünüz gibi, onu birleştirmek istediğiniz kanalların ilkine (hangisi olduğu önemli değil) uyguluyorsunuz ve virgülle ayrılmış diğerlerini takip eden parantez içine ekliyorsunuz. + +İş akışımızda, toplanması gereken şu çıktılar var: + +- `FASTQC.out.zip` +- `FASTQC.out.html` +- `TRIM_GALORE.out.trimming_reports` +- `TRIM_GALORE.out.fastqc_reports` +- `HISAT2_ALIGN.out.log` + +Yani sözdizimi örneği şu hale geliyor: + +```groovy title="MULTIQC çağrısında .mix() uygulaması" + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ) +``` + +Bu, örnek başına QC raporlarını toplayacak. +Ancak bunları tüm örnekler arasında toplamak istediğimiz için, tüm örneklere ait raporları tek bir `MULTIQC` çağrısında toplamak amacıyla `collect()` operatörünü eklememiz gerekiyor. +Ayrıca ona `report_id` parametresini de vermemiz gerekiyor. + +Bu bize şunu verir: + +```groovy title="Tamamlanmış MULTIQC çağrısı" linenums="33" + // Kapsamlı QC raporu oluşturma + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +Tam iş akışı bloğu bağlamında, sonuç şöyle görünüyor: + +```groovy title="rnaseq.nf" linenums="18" +workflow { + // Bir CSV dosyasının içeriğinden girdi kanalı oluşturma + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> file(row.fastq_path) } + + /// İlk kalite kontrolü + FASTQC(read_ch) + + // Adaptör kırpma ve kırpma sonrası QC + TRIM_GALORE(read_ch) + + // Bir referans genoma hizalama + HISAT2_ALIGN(TRIM_GALORE.out.trimmed_reads, file (params.hisat2_index_zip)) + + // Kapsamlı QC raporu oluşturma + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +} +``` + +### 2.5. İş akışının çalıştığını test etmek için çalıştırma + +```bash +nextflow run rnaseq.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq.nf` [modest_pare] DSL2 - revision: fc724d3b49 + + executor > local (1) + [07/3ff9c5] FASTQC (6) [100%] 6 of 6, cached: 6 ✔ + [2c/8d8e1e] TRIM_GALORE (5) [100%] 6 of 6, cached: 6 ✔ + [a4/7f9c44] HISAT2_ALIGN (6) [100%] 6 of 6, cached: 6 ✔ + [56/e1f102] MULTIQC [100%] 1 of 1 ✔ + ``` + +Bu sefer önbelleğe alınmış işlem çağrılarından sonra eklenen tek bir MULTIQC çağrısı görüyoruz: + +Çıktıları `TRIM_GALORE` işleminde `publishDir` yönergesi tarafından belirtildiği gibi `results/trimming` altında bulabilirsiniz. + +```bash +tree -L 2 results/multiqc +``` + +```console title="Çıktı" +results/multiqc +├── all_single-end_data +│ ├── cutadapt_filtered_reads_plot.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Counts.txt +│ ├── cutadapt_trimmed_sequences_plot_3_Obs_Exp.txt +│ ├── fastqc_adapter_content_plot.txt +│ ├── fastqc_overrepresented_sequences_plot.txt +│ ├── fastqc_per_base_n_content_plot.txt +│ ├── fastqc_per_base_sequence_quality_plot.txt +│ ├── fastqc_per_sequence_gc_content_plot_Counts.txt +│ ├── fastqc_per_sequence_gc_content_plot_Percentages.txt +│ ├── fastqc_per_sequence_quality_scores_plot.txt +│ ├── fastqc_sequence_counts_plot.txt +│ ├── fastqc_sequence_duplication_levels_plot.txt +│ ├── fastqc_sequence_length_distribution_plot.txt +│ ├── fastqc-status-check-heatmap.txt +│ ├── fastqc_top_overrepresented_sequences_table.txt +│ ├── hisat2_se_plot.txt +│ ├── multiqc_citations.txt +│ ├── multiqc_cutadapt.txt +│ ├── multiqc_data.json +│ ├── multiqc_fastqc.txt +│ ├── multiqc_general_stats.txt +│ ├── multiqc_hisat2.txt +│ ├── multiqc.log +│ ├── multiqc_software_versions.txt +│ └── multiqc_sources.txt +└── all_single-end.html +``` + +Son `all_single-end.html` dosyası, göz atmayı kolaylaştıran tek bir HTML dosyasında pratik bir şekilde paketlenmiş tam toplu rapordur. + +--- + +## 3. Paired-end RNAseq verilerinin işlenmesini etkinleştirme + +Şu anda iş akışımız yalnızca single-end RNAseq verilerini işleyebiliyor. +Paired-end RNAseq verilerini görmek giderek daha yaygın hale geliyor, bu nedenle bunu da işleyebilmek istiyoruz. + +İş akışını veri türünden tamamen bağımsız hale getirmek biraz daha gelişmiş Nextflow dil özelliklerini kullanmayı gerektirecektir, bu yüzden bunu burada yapmayacağız, ancak neyin uyarlanması gerektiğini göstermek için paired-end işleme versiyonu yapabiliriz. + +### 3.1. `rnaseq_pe.nf` adlı bir iş akışı kopyası oluşturma + +```bash +cp rnaseq.nf rnaseq_pe.nf +``` + +### 3.2. Varsayılan `input_csv`'yi paired-end verilere işaret edecek şekilde değiştirme + +`data/` dizininde örnek ID'leri ve paired FASTQ dosya yollarını içeren ikinci bir CSV dosyası sağlıyoruz + +```csv title="data/paired-end.csv" linenums="1" +sample_id,fastq_1,fastq_2 +ENCSR000COQ1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ1_2.fastq.gz +ENCSR000COQ2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COQ2_2.fastq.gz +ENCSR000COR1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR1_2.fastq.gz +ENCSR000COR2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000COR2_2.fastq.gz +ENCSR000CPO1,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO1_2.fastq.gz +ENCSR000CPO2,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_1.fastq.gz,/workspaces/training/nf4-science/rnaseq/data/reads/ENCSR000CPO2_2.fastq.gz +``` + +`input_csv` varsayılanını `paired-end.csv` dosyasının yolu olacak şekilde değiştirelim. + +```groovy title="rnaseq_pe.nf" linenums="15" +params { + // Birincil girdi + input_csv: Path = "data/paired-end.csv" + + // Referans genom arşivi + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Rapor ID'si + report_id: String = "all_single-end" +} +``` + +### 3.3. Kanal fabrikasını güncelleme + +`.map()` operatörüne artık her iki FASTQ dosya yolunu da almasını söylememiz gerekiyor. + +Yani `row -> file(row.fastq_path)`, `row -> [file(row.fastq_1), file(row.fastq_2)]` olur + +```groovy title="rnaseq_pe.nf" linenums="19" + // Bir CSV dosyasının içeriğinden girdi kanalı oluşturma + read_ch = channel.fromPath(params.input_csv) + .splitCsv(header:true) + .map { row -> [file(row.fastq_1), file(row.fastq_2)] } +``` + +### 3.4. FASTQC işleminin paired-end versiyonunu oluşturma + +Her iki versiyonu da elimizde bulundurmak için modülün bir kopyasını oluşturalım. + +```bash +cp modules/fastqc.nf modules/fastqc_pe.nf +``` + +Yeni `fastqc_pe.nf` modül dosyasını kod düzenleyicide açın ve aşağıdaki kod değişikliklerini yapın: + +- `script` bloğunda (satır 17) `fastqc $reads`'i `fastqc ${reads}` olarak değiştirin, böylece `reads` girdisi artık tek bir yol yerine iki yoldan oluşan bir demet olduğu için açılacaktır. +- Çıktı dosyalarını ayrı ayrı işlemek zorunda kalmamak için `${reads.simpleName}`'i bir joker karakterle (`*`) değiştirin. + +```groovy title="modules/fastqc_pe.nf" linenums="8" + input: + path reads + + output: + path "*_fastqc.zip", emit: zip + path "*_fastqc.html", emit: html + + script: + """ + fastqc ${reads} + """ +``` + +Teknik olarak bu, `FASTQC` işlemini single-end veya paired-end RNAseq verilerinden birini işleyebilecek şekilde genelleştirir. + +Son olarak, modülün paired-end versiyonunu kullanmak için modül içe aktarma ifadesini güncelleyin. + +```groovy title="rnaseq_pe.nf" linenums="4" +include { FASTQC } from './modules/fastqc_pe.nf' +``` + +### 3.5. TRIM_GALORE işleminin paired-end versiyonunu oluşturma + +Her iki versiyonu da elimizde bulundurmak için modülün bir kopyasını oluşturun. + +```bash +cp modules/trim_galore.nf modules/trim_galore_pe.nf +``` + +Yeni `trim_galore_pe.nf` modül dosyasını kod düzenleyicide açın ve aşağıdaki kod değişikliklerini yapın: + +- Girdi bildirimini `path reads`'ten `tuple path(read1), path(read2)` olarak değiştirin +- `script` bloğundaki komutu güncelleyin, `$reads`'i `--paired ${read1} ${read2}` ile değiştirin +- Eklenen dosyaları ve farklı adlandırma kurallarını yansıtacak şekilde çıktı bildirimlerini güncelleyin, her şeyi listelemek zorunda kalmamak için joker karakterler kullanın. + +```groovy title="modules/trim_galore_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + + output: + tuple path("*_val_1.fq.gz"), path("*_val_2.fq.gz"), emit: trimmed_reads + path "*_trimming_report.txt", emit: trimming_reports + path "*_val_1_fastqc.{zip,html}", emit: fastqc_reports_1 + path "*_val_2_fastqc.{zip,html}", emit: fastqc_reports_2 + + script: + """ + trim_galore --fastqc --paired ${read1} ${read2} + """ +``` + +Son olarak, modülün paired-end versiyonunu kullanmak için modül içe aktarma ifadesini güncelleyin. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { TRIM_GALORE } from './modules/trim_galore_pe.nf' +``` + +### 3.6. MULTIQC işlemine yapılan çağrıyı TRIM_GALORE'dan iki rapor bekleyecek şekilde güncelleme + +`TRIM_GALORE` işlemi artık ek bir çıktı kanalı üretiyor, bu yüzden bunu MultiQC'ye beslememiz gerekiyor. + +`TRIM_GALORE.out.fastqc_reports,`'i `TRIM_GALORE.out.fastqc_reports_1,` artı `TRIM_GALORE.out.fastqc_reports_2,` ile değiştirin: + +```groovy title="rnaseq_pe.nf" linenums="33" + // Kapsamlı QC raporu oluşturma + MULTIQC( + FASTQC.out.zip.mix( + FASTQC.out.html, + TRIM_GALORE.out.trimming_reports, + TRIM_GALORE.out.fastqc_reports_1, + TRIM_GALORE.out.fastqc_reports_2, + HISAT2_ALIGN.out.log + ).collect(), + params.report_id + ) +``` + +MultiQC üzerindeyken, `report_id` parametresinin varsayılanını da `"all_single-end"`'den `"all_paired-end"`'e güncelleyelim. + +```groovy title="rnaseq_pe.nf" linenums="9" +params { + // Birincil girdi + input_csv: Path = "data/paired-end.csv" + + // Referans genom arşivi + hisat2_index_zip: Path = "data/genome_index.tar.gz" + + // Rapor ID'si + report_id: String = "all_paired-end" +} +``` + +### 3.7. HISAT2_ALIGN işleminin paired-end versiyonunu oluşturma + +Her iki versiyonu da elimizde bulundurmak için modülün bir kopyasını oluşturun. + +```bash +cp modules/hisat2_align.nf modules/hisat2_align_pe.nf +``` + +Yeni `hisat2_align_pe.nf` modül dosyasını kod düzenleyicide açın ve aşağıdaki kod değişikliklerini yapın: + +- Girdi bildirimini `path reads`'ten `tuple path(read1), path(read2)` olarak değiştirin +- `script` bloğundaki komutu güncelleyin, `-U $reads`'i `-1 ${read1} -2 ${read2}` ile değiştirin +- `${reads.simpleName}`'in tüm örneklerini `script` bloğundaki komutta ve çıktı bildirimlerinde `${read1.simpleName}` ile değiştirin. + +```groovy title="modules/hisat2_align_pe.nf" linenums="8" + input: + tuple path(read1), path(read2) + path index_zip + + output: + path "${read1.simpleName}.bam", emit: bam + path "${read1.simpleName}.hisat2.log", emit: log + + script: + """ + tar -xzvf $index_zip + hisat2 -x ${index_zip.simpleName} -1 ${read1} -2 ${read2} \ + --new-summary --summary-file ${read1.simpleName}.hisat2.log | \ + samtools view -bS -o ${read1.simpleName}.bam + """ +``` + +Son olarak, modülün paired-end versiyonunu kullanmak için modül içe aktarma ifadesini güncelleyin. + +```groovy title="rnaseq_pe.nf" linenums="5" +include { HISAT2_ALIGN } from './modules/hisat2_align_pe.nf' +``` + +### 3.8. İş akışının çalıştığını test etmek için çalıştırma + +Bu önbelleğe almayacağı ve işlenecek verilerin öncekinden iki kat daha fazla olduğu için `-resume` kullanmıyoruz, ancak yine de bir dakikadan kısa sürede tamamlanması gerekiyor. + +```bash +nextflow run rnaseq_pe.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + + Launching `rnaseq_pe.nf` [reverent_kare] DSL2 - revision: 9c376cc219 + + executor > local (19) + [c5/cbde15] FASTQC (5) [100%] 6 of 6 ✔ + [e4/fa2784] TRIM_GALORE (5) [100%] 6 of 6 ✔ + [3a/e23049] HISAT2_ALIGN (5) [100%] 6 of 6 ✔ + [e6/a3ccd9] MULTIQC [100%] 1 of 1 ✔ + ``` + +İşte bu kadar! Şimdi iş akışımızın biri single-end okuma verileri için, diğeri paired-end veriler için olmak üzere biraz farklılaşan iki versiyonuna sahibiz. +Bir sonraki mantıklı adım, iş akışının her iki veri türünü de anında kabul etmesini sağlamak olacaktır; bu, bu kursun kapsamı dışındadır, ancak bunu bir takip kursunda ele alabiliriz. + +--- + +### Çıkarımlar + +Tek örnekli bir iş akışını birden fazla örneğin işlenmesini paralelleştirmek, kapsamlı bir QC raporu oluşturmak ve gerekirse iş akışını paired-end okuma verilerini kullanacak şekilde uyarlamak için nasıl uyarlayacağınızı biliyorsunuz. + +### Sırada ne var? + +Tebrikler, Nextflow For RNAseq mini-kursunu tamamladınız! Başarınızı kutlayın ve hak ettiğiniz bir mola verin! + +Ardından, bu eğitim kursu hakkındaki deneyiminizle ilgili çok kısa bir anketi tamamlamanızı rica ediyoruz, sonra sizi daha fazla eğitim kaynağı ve yararlı bağlantılara sahip bir sayfaya götüreceğiz. diff --git a/docs/tr/docs/nf4_science/rnaseq/index.md b/docs/tr/docs/nf4_science/rnaseq/index.md new file mode 100644 index 0000000000..4434bc8cd6 --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/index.md @@ -0,0 +1,48 @@ +```yaml +--- +title: RNAseq için Nextflow +hide: + - toc +--- + +# RNAseq için Nextflow + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu eğitim kursu, transkriptomik ve ilgili alanlarda veri analizi pipeline'ları geliştirmek veya özelleştirmek isteyen araştırmacılar için tasarlanmıştır. +[Hello Nextflow](../../hello_nextflow/) başlangıç eğitimi üzerine inşa edilmiş olup, Nextflow'un toplu RNAseq analizi bağlamında nasıl kullanılacağını göstermektedir. + +Özellikle, bu kurs adaptör dizilerini kırpmak, okumaları genom referansına hizalamak ve birkaç aşamada kalite kontrol (QC) gerçekleştirmek için basit bir toplu RNAseq işleme pipeline'ının nasıl uygulanacağını göstermektedir. + +Hadi başlayalım! Eğitim ortamını başlatmak için aşağıdaki "Open in GitHub Codespaces" düğmesine tıklayın (tercihen ayrı bir sekmede), ardından yüklenirken okumaya devam edin. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Öğrenim hedefleri + +Bu kursu tamamlayarak, temel Nextflow kavramlarını ve araçlarını tipik bir RNAseq kullanım durumuna nasıl uygulayacağınızı öğreneceksiniz. + +Bu atölye sonunda şunları yapabileceksiniz: + +- Temel RNAseq işleme ve QC yöntemlerini uygulamak için doğrusal bir workflow yazmak +- FASTQ gibi alana özgü dosyaları ve genom referans kaynaklarını uygun şekilde ele almak +- Tek uçlu ve çift uçlu dizileme verilerini işlemek +- Nextflow'un dataflow paradigmasından yararlanarak örnek başına RNAseq işlemesini paralelleştirmek +- İlgili channel operatörlerini kullanarak birden fazla adım ve örnek genelinde QC raporlarını birleştirmek + +<!-- TODO +- Configure pipeline execution and manage and optimize resource allocations +- Implement per-step and end-to-end pipeline tests that handle RNAseq-specific idiosyncrasies appropriately +--> +<!-- TODO for future expansion: add metadata/samplesheet handling --> + +## Ön koşullar + +Kurs, aşağıdakilerle ilgili minimal bir aşinalık varsaymaktadır: + +- Bu bilimsel alanda yaygın olarak kullanılan araçlar ve dosya formatları +- Komut satırı deneyimi +- [Hello Nextflow](../../hello_nextflow/) başlangıç eğitiminde ele alınan temel Nextflow kavramları ve araçları. + +Teknik gereksinimler ve ortam kurulumu için [Ortam Kurulumu](../../envsetup/) mini kursuna bakın. +``` diff --git a/docs/tr/docs/nf4_science/rnaseq/next_steps.md b/docs/tr/docs/nf4_science/rnaseq/next_steps.md new file mode 100644 index 0000000000..120525bd7e --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/next_steps.md @@ -0,0 +1,50 @@ +# Sonraki Adımlar + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow For RNAseq eğitim kursunu tamamladığınız için tekrar tebrikler ve anketimizi doldurduğunuz için teşekkür ederiz! + +--- + +## 1. Nextflow becerilerinizi geliştirmenin en iyi 3 yolu + +Az önce tamamladığınız kursa dayanarak bir sonraki adım için en iyi üç önerimiz: + +### 1.1. Nextflow'u diğer bilimsel analiz kullanım durumlarına uygulayın + +**[Nextflow for Science](../nf4_science/index.md) sayfasına göz atın** - Hello Nextflow'da sunulan temel kavramların ve mekanizmaların yaygın bilimsel analiz kullanım durumlarına nasıl uygulanacağını gösteren kısa, bağımsız kursların listesi için. + +Eğer alanınızın ilişkilendirilebilir bir kullanım örneğiyle temsil edilmediğini görüyorsanız, geliştirme listemize ekleyebilmemiz için bize [Topluluk forumu](https://community.seqera.io/)'nda bildirin. + +### 1.2. nf-core ile başlayın + +**[nf-core](https://nf-co.re/)**, geniş bir bilimsel araştırma uygulamaları yelpazesi için standartlaştırılmış açık kaynaklı pipeline'lar geliştirmek üzere dünya çapında bir işbirliği çabasıdır. +Proje, kullanıma hazır [100'den fazla pipeline](https://nf-co.re/pipelines/) ve kendi projelerinize entegre edilebilecek [1400'ün üzerinde process modülü](https://nf-co.re/modules/)'nün yanı sıra zengin bir geliştirici araçları setini içerir. + +**[Hello nf-core](../../hello_nf-core/index.md)** eğitim kursu, size nf-core topluluk tarafından hazırlanmış pipeline'ları ve geliştirme çerçevesini tanıtacaktır; bu çerçeve, yeniden üretilebilir, ölçeklenebilir ve standartlaştırılmış workflow'lar yazmanıza yardımcı olmak için tasarlanmıştır. Mevcut nf-core pipeline'larını nasıl kullanacağınızı, geliştirilmelerine nasıl katkıda bulunacağınızı ve hatta en iyi uygulamalar ve canlı bir topluluk desteğiyle kendinizinkini nasıl oluşturmaya başlayacağınızı öğreneceksiniz. Nextflow becerilerinizi gerçek dünya projelerinde uygulamaya hazırsanız, bu mükemmel bir sonraki adımdır. + +### 1.3. Daha gelişmiş Nextflow özelliklerinde ustalaşın + +Hello kurslarında, Nextflow'a başlamak için ihtiyacınız olmayan bilgilerle sizi aşırı yüklemekten kaçınmak amacıyla teknik karmaşıklık seviyesini kasıtlı olarak düşük tutuyoruz. +Çalışmanızla ilerlerken, Nextflow'un tam özellik setini ve gücünü nasıl kullanacağınızı öğrenmek isteyeceksiniz. + +Bu amaçla, şu anda test ve metadata yönetimi gibi belirli konulara derinlemesine inen kısa bağımsız kurslar olması amaçlanan **[Side Quests](../side_quests/index.md) koleksiyonu** üzerinde çalışıyoruz. + +--- + +## 2. Seqera Platform'u inceleyin + +**[Seqera Platform](https://seqera.io/), Nextflow'u pratikte çalıştırmanın en iyi yoludur.** + +Nextflow'un yaratıcıları tarafından geliştirilen bulut tabanlı bir platformdur ve kendi bilgi işlem altyapınıza (ister yerel, ister HPC veya bulut olsun) bağlanarak workflow'larınızı başlatmayı ve yönetmeyi, ayrıca verilerinizi yönetmeyi ve bulut ortamında etkileşimli olarak analiz çalıştırmayı çok daha kolay hale getirir. + +Ücretsiz Katman, herkes tarafından ücretsiz kullanım için mevcuttur (kullanım kotaları ile). +Nitelikli akademisyenler, [Akademik Program](https://seqera.io/academic/program/) aracılığıyla ücretsiz Pro düzeyinde erişim alabilir (kullanım sınırlaması yok). + +Bunun sizin için faydalı olup olmayacağını görmek için [Seqera Platform eğitimlerine](https://docs.seqera.io/platform/latest/getting-started/quickstart-demo/comm-showcase) göz atın. + +--- + +### Şimdilik bu kadar! + +**Nextflow yolculuğunuzda iyi şanslar ve size yardımcı olmak için başka neler yapabileceğimizi [Topluluk forumu](https://community.seqera.io/)'nda bize bildirmekten çekinmeyin.** diff --git a/docs/tr/docs/nf4_science/rnaseq/survey.md b/docs/tr/docs/nf4_science/rnaseq/survey.md new file mode 100644 index 0000000000..973b1fa51e --- /dev/null +++ b/docs/tr/docs/nf4_science/rnaseq/survey.md @@ -0,0 +1,9 @@ +# Geri bildirim anketi + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Devam etmeden önce, lütfen eğitimi değerlendirmek, deneyiminiz hakkında geri bildirimlerinizi paylaşmak ve Nextflow yolculuğunuzda size yardımcı olmak için başka neler yapabileceğimizi bize bildirmek için bu kısa 5 soruluk anketi tamamlayın. + +Bu anketin tamamlanması bir dakikadan kısa sürecektir. Eğitim materyallerimizi herkes için geliştirmemize yardımcı olduğunuz için teşekkür ederiz! + +<div data-tf-live="01JN3E01A2B3HF317JR9ANW7MY"></div><script src="//embed.typeform.com/next/embed.js"></script> diff --git a/docs/tr/docs/side_quests/README.md b/docs/tr/docs/side_quests/README.md new file mode 100644 index 0000000000..033c89a124 --- /dev/null +++ b/docs/tr/docs/side_quests/README.md @@ -0,0 +1 @@ +Bu, gelecekteki Yan Görevler (derinlemesine eğitimler) için bir yer tutucudur. Şu anda buradaki dokümanlar, başka yerlerden geri dönüştürülmüş içeriğe dayanan taslak metinlerdir. diff --git a/docs/tr/docs/side_quests/debugging.md b/docs/tr/docs/side_quests/debugging.md new file mode 100644 index 0000000000..3f3475dd48 --- /dev/null +++ b/docs/tr/docs/side_quests/debugging.md @@ -0,0 +1,1495 @@ +# İş Akışlarında Hata Ayıklama + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Hata ayıklama, saatlerce süren hayal kırıklığından sizi kurtarabilecek ve sizi daha etkili bir Nextflow geliştiricisi haline getirebilecek kritik bir beceridir. Kariyeriniz boyunca, özellikle yeni başlarken, iş akışlarınızı oluştururken ve sürdürürken hatalarla karşılaşacaksınız. Sistematik hata ayıklama yaklaşımlarını öğrenmek, sorunları hızla belirlemenize ve çözmenize yardımcı olacaktır. + +### Öğrenme hedefleri + +Bu yan görevde, Nextflow iş akışları için **sistematik hata ayıklama tekniklerini** keşfedeceğiz: + +- **Sözdizimi hatası ayıklama**: IDE özelliklerini ve Nextflow hata mesajlarını etkili şekilde kullanma +- **Kanal hata ayıklama**: Veri akışı sorunlarını ve kanal yapısı problemlerini teşhis etme +- **Process hata ayıklama**: Çalıştırma hatalarını ve kaynak sorunlarını araştırma +- **Yerleşik hata ayıklama araçları**: Nextflow'un önizleme modu, stub çalıştırma ve çalışma dizinlerinden yararlanma +- **Sistematik yaklaşımlar**: Verimli hata ayıklama için dört aşamalı bir metodoloji + +Sonunda, sinir bozucu hata mesajlarını çözümler için net yol haritalarına dönüştüren sağlam bir hata ayıklama metodolojisine sahip olacaksınız. + +### Ön koşullar + +Bu yan görevi üstlenmeden önce şunları yapmalısınız: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olun. +- Temel Nextflow kavramlarını ve mekanizmalarını (process'ler, kanal'lar, operatör'ler) rahatça kullanabilin + +**İsteğe bağlı:** [Nextflow Geliştirme için IDE Özellikleri](./ide_features.md) yan görevini önce tamamlamanızı öneririz. +Bu, burada yoğun olarak kullanacağımız hata ayıklamayı destekleyen IDE özelliklerinin (sözdizimi vurgulama, hata algılama vb.) kapsamlı bir şekilde ele alınmasını sağlar. + +--- + +## 0. Başlangıç + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md) bölümünde açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine gidin + +Bu eğitim için dosyaların bulunduğu dizine geçelim. + +```bash +cd side-quests/debugging +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri inceleyin + +Pratik için kullanacağımız çeşitli hata türlerine sahip örnek iş akışları bulacaksınız: + +??? abstract "Dizin içeriği" + + ```console + . + ├── bad_bash_var.nf + ├── bad_channel_shape.nf + ├── bad_channel_shape_viewed_debug.nf + ├── bad_channel_shape_viewed.nf + ├── bad_number_inputs.nf + ├── badpractice_syntax.nf + ├── bad_resources.nf + ├── bad_syntax.nf + ├── buggy_workflow.nf + ├── data + │ ├── sample_001.fastq.gz + │ ├── sample_002.fastq.gz + │ ├── sample_003.fastq.gz + │ ├── sample_004.fastq.gz + │ ├── sample_005.fastq.gz + │ └── sample_data.csv + ├── exhausted.nf + ├── invalid_process.nf + ├── missing_output.nf + ├── missing_software.nf + ├── missing_software_with_stub.nf + ├── nextflow.config + └── no_such_var.nf + ``` + +Bu dosyalar, gerçek dünya geliştirmede karşılaşacağınız yaygın hata ayıklama senaryolarını temsil eder. + +#### Ödevi inceleyin + +Göreviniz her bir iş akışını çalıştırmak, hataları belirlemek ve düzeltmektir. + +Her hatalı iş akışı için: + +1. **İş akışını çalıştırın** ve hatayı gözlemleyin +2. **Hata mesajını analiz edin**: Nextflow size ne söylüyor? +3. **Sorunu belirleyin** sağlanan ipuçlarını kullanarak kodda +4. **Hatayı düzeltin** ve çözümünüzün çalıştığını doğrulayın +5. Bir sonraki bölüme geçmeden önce **dosyayı sıfırlayın** (`git checkout <dosyaadı>` kullanın) + +Alıştırmalar basit sözdizimi hatalarından daha ince çalışma zamanı sorunlarına doğru ilerler. +Çözümler satır içinde tartışılır, ancak ilerlemeden önce her birini kendiniz çözmeye çalışın. + +#### Hazırlık kontrol listesi + +Dalmaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışıyor +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] Ödevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Sözdizimi Hataları + +Sözdizimi hataları, Nextflow kodu yazarken karşılaşacağınız en yaygın hata türüdür. Kod, Nextflow DSL'nin beklenen sözdizimi kurallarına uymadığında meydana gelirler. Bu hatalar iş akışınızın hiç çalışmasını engellerler, bu nedenle bunları nasıl hızlı bir şekilde belirleyip düzelteceğinizi öğrenmek önemlidir. + +### 1.1. Eksik parantezler + +En yaygın sözdizimi hatalarından biri ve bazen hata ayıklaması en karmaşık olanlardan biri **eksik veya uyumsuz parantezlerdir**. + +Pratik bir örnekle başlayalım. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_syntax.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [stupefied_bhabha] DSL2 - revision: ca6327fad2 + + Error bad_syntax.nf:24:1: Unexpected input: '<EOF>' + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +**Sözdizimi hata mesajlarının ana öğeleri:** + +- **Dosya ve konum**: Hatayı içeren dosya ve satır/sütunu gösterir (`bad_syntax.nf:24:1`) +- **Hata açıklaması**: Ayrıştırıcının beklemediği şeyi bulduğunu açıklar (`Unexpected input: '<EOF>'`) +- **EOF göstergesi**: `<EOF>` (End Of File) mesajı, ayrıştırıcının hala daha fazla içerik beklerken dosyanın sonuna ulaştığını gösterir - kapatılmamış parantezlerin klasik bir işareti + +#### Kodu kontrol edin + +Şimdi, hatanın nedenini anlamak için `bad_syntax.nf` dosyasını inceleyelim: + +```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +// Missing closing brace for the process + +workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) +} +``` + +Bu örneğin amacı için, hatanın nerede olduğunu göstermek için size bir yorum bıraktık. Nextflow VSCode uzantısı da size neyin yanlış olabileceği konusunda bazı ipuçları vermelidir, uyumsuz parantezi kırmızıya boyar ve dosyanın erken bitişini vurgular: + +![Kötü sözdizimi](img/bad_syntax.png) + +**Parantez hataları için hata ayıklama stratejisi:** + +1. VS Code'un parantez eşleştirmesini kullanın (imleci bir parantezin yanına yerleştirin) +2. Parantezle ilgili mesajlar için Sorunlar panelini kontrol edin +3. Her açılan `{` için karşılık gelen kapatan `}` olduğundan emin olun + +#### Kodu düzeltin + +Yorumu eksik kapatan parantez ile değiştirin: + +=== "Sonra" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } // Add the missing closing brace + + workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) + } + ``` + +=== "Önce" + + ```groovy title="bad_syntax.nf" hl_lines="14" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + // Missing closing brace for the process + + workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +Şimdi çalıştığını doğrulamak için iş akışını tekrar çalıştırın: + +```bash +nextflow run bad_syntax.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_syntax.nf` [insane_faggin] DSL2 - revision: 961938ee2b + + executor > local (3) + [48/cd7f54] PROCESS_FILES (1) | 3 of 3 ✔ + ``` + +### 1.2. Yanlış process anahtar kelimelerini veya yönergelerini kullanma + +Bir diğer yaygın sözdizimi hatası **geçersiz bir process tanımıdır**. Bu, gerekli blokları tanımlamayı unutursanız veya process tanımında yanlış yönergeler kullanırsanız meydana gelebilir. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run invalid_process.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [nasty_jepsen] DSL2 - revision: da9758d614 + + Error invalid_process.nf:3:1: Invalid process definition -- check for missing or out-of-order section labels + │ 3 | process PROCESS_FILES { + │ | ^^^^^^^^^^^^^^^^^^^^^^^ + │ 4 | inputs: + │ 5 | val sample_name + │ 6 | + ╰ 7 | output: + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Kodu kontrol edin + +Hata "Geçersiz process tanımı" belirtiyor ve sorunun etrafındaki bağlamı gösteriyor. 3-7. satırlara bakıldığında, 4. satırda `inputs:` görebiliriz, bu sorun. `invalid_process.nf` dosyasını inceleyelim: + +```groovy title="invalid_process.nf" hl_lines="4" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + inputs: // ERROR: Should be 'input' not 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) +} +``` + +Hata bağlamındaki 4. satıra bakıldığında, sorunu tespit edebiliriz: doğru `input` yönergesi yerine `inputs` kullanıyoruz. Nextflow VSCode uzantısı bunu da işaretleyecektir: + +![Geçersiz process mesajı](img/invalid_process_message.png) + +#### Kodu düzeltin + +[Belgelere](https://www.nextflow.io/docs/latest/process.html#) başvurarak yanlış anahtar kelimeyi doğru olanla değiştirin: + +=== "Sonra" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: // Fixed: Changed 'inputs' to 'input' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) + } + ``` + +=== "Önce" + + ```groovy title="invalid_process.nf" hl_lines="4" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + inputs: // ERROR: Should be 'input' not 'inputs' + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Girdi kanalı oluştur + input_ch = channel.of('sample1', 'sample2', 'sample3') + + // İşlemi girdi kanalıyla çağır + PROCESS_FILES(input_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +Şimdi çalıştığını doğrulamak için iş akışını tekrar çalıştırın: + +```bash +nextflow run invalid_process.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `invalid_process.nf` [silly_fermi] DSL2 - revision: 961938ee2b + + executor > local (3) + [b7/76cd9d] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.3. Kötü değişken isimleri kullanma + +Script bloklarınızda kullandığınız değişken isimleri geçerli olmalıdır, girdilerden veya script'ten önce eklenen groovy kodundan türetilmelidir. Ancak pipeline geliştirmenin başında karmaşıklıkla boğuşurken değişken adlandırmada hata yapmak kolaydır ve Nextflow bunu size hızlıca bildirecektir. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run no_such_var.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [gloomy_meninsky] DSL2 - revision: 0c4d3bc28c + + Error no_such_var.nf:17:39: `undefined_var` is not defined + │ 17 | echo "Using undefined variable: ${undefined_var}" >> ${output_pref + ╰ | ^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Hata derleme zamanında yakalanır ve doğrudan 17. satırdaki tanımsız değişkeni gösterir, sorunun tam olarak nerede olduğunu gösteren bir şapka ile. + +#### Kodu kontrol edin + +`no_such_var.nf` dosyasını inceleyelim: + +```groovy title="no_such_var.nf" hl_lines="17" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ +} + +workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) +} +``` + +Hata mesajı değişkenin script şablonunda tanınmadığını belirtir ve işte orada- script bloğunda kullanılan ancak başka yerde tanımlanmamış `${undefined_var}` görmelisiniz. + +#### Kodu düzeltin + +'Böyle bir değişken yok' hatası alırsanız, değişkeni tanımlayarak (girdi değişken adlarını düzelterek veya script'ten önce groovy kodunu düzenleyerek) veya gerekli değilse script bloğundan kaldırarak düzeltebilirsiniz: + +=== "Sonra" + + ```groovy title="no_such_var.nf" hl_lines="15-17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ // Removed the line with undefined_var + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Önce" + + ```groovy title="no_such_var.nf" hl_lines="17" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + echo "Using undefined variable: ${undefined_var}" >> ${output_prefix}.txt // ERROR: undefined_var not defined + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +Şimdi çalıştığını doğrulamak için iş akışını tekrar çalıştırın: + +```bash +nextflow run no_such_var.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `no_such_var.nf` [suspicious_venter] DSL2 - revision: 6ba490f7c5 + + executor > local (3) + [21/237300] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 1.4. Bash değişkenlerinin kötü kullanımı + +Nextflow'a başlarken, Nextflow (Groovy) ve Bash değişkenleri arasındaki farkı anlamak zor olabilir. Bu, script bloğunun Bash içeriğinde değişkenleri kullanmaya çalışırken görünen başka bir kötü değişken hatası biçimi oluşturabilir. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_bash_var.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [infallible_mandelbrot] DSL2 - revision: 0853c11080 + + Error bad_bash_var.nf:13:42: `prefix` is not defined + │ 13 | echo "Processing ${sample_name}" > ${prefix}.txt + ╰ | ^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Kodu kontrol edin + +Hata, `${prefix}` kullanılan 13. satırı gösterir. Neyin soruna neden olduğunu görmek için `bad_bash_var.nf` dosyasını inceleyelim: + +```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ +} +``` + +Bu örnekte, `prefix` değişkenini Bash'te tanımlıyoruz, ancak bir Nextflow process'inde ona atıfta bulunmak için kullandığımız `$` sözdizimi (`${prefix}`) Bash değil Groovy değişkeni olarak yorumlanır. Değişken Groovy bağlamında mevcut olmadığından, 'böyle bir değişken yok' hatası alırız. + +#### Kodu düzeltin + +Bash değişkeni kullanmak istiyorsanız, dolar işaretini şu şekilde kaçırmalısınız: + +=== "Sonra" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > \${prefix}.txt # Fixed: Escaped the dollar sign + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') + PROCESS_FILES(input_ch) + } + ``` + +=== "Önce" + + ```groovy title="bad_bash_var.nf" hl_lines="13" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_output.txt" + + script: + """ + prefix="${sample_name}_output" + echo "Processing ${sample_name}" > ${prefix}.txt # ERROR: ${prefix} is Groovy syntax, not Bash + """ + } + ``` + +Bu, Nextflow'a bunu bir Bash değişkeni olarak yorumlamasını söyler. + +#### Pipeline'ı çalıştırın + +Şimdi çalıştığını doğrulamak için iş akışını tekrar çalıştırın: + +```bash +nextflow run bad_bash_var.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_bash_var.nf` [naughty_franklin] DSL2 - revision: 58c1c83709 + + executor > local (3) + [4e/560285] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +!!! tip "Groovy vs Bash Değişkenleri" + + String birleştirme veya önek/sonek işlemleri gibi basit değişken manipülasyonları için, script bloğundaki Bash değişkenleri yerine script bölümünde Groovy değişkenleri kullanmak genellikle daha okunabilir: + + ```groovy linenums="1" + script: + def output_prefix = "${sample_name}_processed" + def output_file = "${output_prefix}.txt" + """ + echo "Processing ${sample_name}" > ${output_file} + """ + ``` + + Bu yaklaşım dolar işaretlerini kaçırmaya gerek bırakmaz ve kodu okumayı ve sürdürmeyi kolaylaştırır. + +### 1.5. Workflow Bloğu Dışında İfadeler + +Nextflow VSCode uzantısı, hatalara neden olacak kod yapısıyla ilgili sorunları vurgular. Yaygın bir örnek, `workflow {}` bloğunun dışında kanal tanımlamaktır - bu artık bir sözdizimi hatası olarak zorlanmaktadır. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run badpractice_syntax.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [intergalactic_colden] DSL2 - revision: 5e4b291bde + + Error badpractice_syntax.nf:3:1: Statements cannot be mixed with script declarations -- move statements into a process or workflow + │ 3 | input_ch = channel.of('sample1', 'sample2', 'sample3') + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +Hata mesajı sorunu açıkça belirtir: ifadeler (kanal tanımları gibi) bir workflow veya process bloğunun dışında script bildirimleriyle karıştırılamaz. + +#### Kodu kontrol edin + +Hataya neyin neden olduğunu görmek için `badpractice_syntax.nf` dosyasını inceleyelim: + +```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" +#!/usr/bin/env nextflow + +input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + +process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + PROCESS_FILES(input_ch) +} +``` + +VSCode uzantısı ayrıca `input_ch` değişkenini workflow bloğunun dışında tanımlandığı için vurgulayacaktır: + +![Ölümcül olmayan sözdizimi hatası](img/nonlethal.png) + +#### Kodu düzeltin + +Kanal tanımını workflow bloğunun içine taşıyın: + +=== "Sonra" + + ```groovy title="badpractice_syntax.nf" hl_lines="21" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + input_ch = channel.of('sample1', 'sample2', 'sample3') // Moved inside workflow block + PROCESS_FILES(input_ch) + } + ``` + +=== "Önce" + + ```groovy title="badpractice_syntax.nf" hl_lines="3" linenums="1" + #!/usr/bin/env nextflow + + input_ch = channel.of('sample1', 'sample2', 'sample3') // ERROR: Channel defined outside workflow + + process PROCESS_FILES { + input: + val sample_name + + output: + path "${sample_name}_processed.txt" + + script: + // Define variables in Groovy code before the script + def output_prefix = "${sample_name}_processed" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ + } + + workflow { + PROCESS_FILES(input_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +Düzeltmenin çalıştığını doğrulamak için iş akışını tekrar çalıştırın: + +```bash +nextflow run badpractice_syntax.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `badpractice_syntax.nf` [naughty_ochoa] DSL2 - revision: 5e4b291bde + + executor > local (3) + [6a/84a608] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +Girdi kanallarınızı workflow bloğu içinde tanımlanmış tutun ve genel olarak uzantının yaptığı diğer önerileri takip edin. + +### Çıkarımlar + +Nextflow hata mesajlarını ve IDE görsel göstergelerini kullanarak sözdizimi hatalarını sistematik olarak belirleyebilir ve düzeltebilirsiniz. Yaygın sözdizimi hataları arasında eksik parantezler, yanlış process anahtar kelimeleri, tanımsız değişkenler ve Bash ile Nextflow değişkenlerinin uygunsuz kullanımı bulunur. VSCode uzantısı bunların çoğunu çalışma zamanından önce yakalamanıza yardımcı olur. Bu sözdizimi hata ayıklama becerileri araç setinizde olduğunda, en yaygın Nextflow sözdizimi hatalarını hızlı bir şekilde çözebilecek ve daha karmaşık çalışma zamanı sorunlarıyla başa çıkmaya geçebileceksiniz. + +### Sırada ne var? + +Sözdizimi doğru olsa bile ortaya çıkan daha karmaşık kanal yapısı hatalarında hata ayıklamayı öğrenin. + +--- + +## 2. Kanal Yapısı Hataları + +Kanal yapısı hataları sözdizimi hatalarından daha inceliklidir çünkü kod sözdizimsel olarak doğrudur, ancak veri şekilleri process'lerin beklediği ile eşleşmez. Nextflow pipeline'ı çalıştırmaya çalışacaktır, ancak girdi sayısının beklediği ile eşleşmediğini bulabilir ve başarısız olabilir. Bu hatalar genellikle yalnızca çalışma zamanında görünür ve iş akışınız boyunca akan verilerin anlaşılmasını gerektirir. + +!!! tip "`.view()` ile Kanallarda Hata Ayıklama" + + Bu bölüm boyunca, iş akışınızdaki herhangi bir noktada kanal içeriğini incelemek için `.view()` operatörünü kullanabileceğinizi unutmayın. Bu, kanal yapısı sorunlarını anlamak için en güçlü hata ayıklama araçlarından biridir. Bu tekniği 2.4. bölümünde ayrıntılı olarak keşfedeceğiz, ancak örnekler üzerinde çalışırken kullanmaktan çekinmeyin. + + ```groovy + my_channel.view() // Kanaldan ne aktığını gösterir + ``` + +### 2.1. Yanlış Sayıda Girdi Kanalı + +Bu hata, bir process'in beklediğinden farklı sayıda kanal geçirdiğinizde oluşur. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_number_inputs.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [happy_swartz] DSL2 - revision: d83e58dcd3 + + Error bad_number_inputs.nf:23:5: Incorrect number of call arguments, expected 1 but received 2 + │ 23 | PROCESS_FILES(samples_ch, files_ch) + ╰ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ERROR ~ Script compilation failed + + -- Check '.nextflow.log' file for details + ``` + +#### Kodu kontrol edin + +Hata mesajı, çağrının 1 argüman beklediğini ancak 2 aldığını açıkça belirtir ve 23. satırı gösterir. `bad_number_inputs.nf` dosyasını inceleyelim: + +```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Passing 2 channels but process expects only 1 + PROCESS_FILES(samples_ch, files_ch) +} +``` + +Process yalnızca bir tane tanımlarken birden fazla girdi kanalı sağlayan uyumsuz `PROCESS_FILES` çağrısını görmelisiniz. VSCode uzantısı ayrıca process çağrısının altını kırmızıya çizer ve fare ile üzerine geldiğinizde bir tanı mesajı sağlar: + +![Yanlış sayıda argüman mesajı](img/incorrect_num_args.png) + +#### Kodu düzeltin + +Bu özel örnek için, process tek bir kanal bekler ve ikinci kanala ihtiyaç duymaz, bu nedenle yalnızca `samples_ch` kanalını geçirerek düzeltebiliriz: + +=== "Sonra" + + ```groovy title="bad_number_inputs.nf" hl_lines="23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // Fixed: Pass only the channel the process expects + PROCESS_FILES(samples_ch) + } + ``` + +=== "Önce" + + ```groovy title="bad_number_inputs.nf" hl_lines="5 23" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Process expects only 1 input + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Create two separate channels + samples_ch = channel.of('sample1', 'sample2', 'sample3') + files_ch = channel.of('file1.txt', 'file2.txt', 'file3.txt') + + // ERROR: Passing 2 channels but process expects only 1 + PROCESS_FILES(samples_ch, files_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_number_inputs.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_number_inputs.nf` [big_euler] DSL2 - revision: e302bd87be + + executor > local (3) + [48/497f7b] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Bu örnekten daha yaygın olarak, bir process'e ek girdiler ekleyebilir ve workflow çağrısını buna göre güncellemeyi unutabilirsiniz, bu da bu tür bir hataya yol açabilir. Neyse ki, hata mesajı uyumsuzluk hakkında oldukça açık olduğundan, bu anlaşılması ve düzeltilmesi daha kolay hatalardan biridir. + +### 2.2. Kanal Tükenmesi (Process Beklenenden Daha Az Çalışır) + +Bazı kanal yapısı hataları çok daha inceliklidir ve hiç hata üretmezler. Muhtemelen bunların en yaygını, yeni Nextflow kullanıcılarının queue kanallarının tükenebileceğini ve öğelerin bitebileceğini anlamalarındaki zorluğu yansıtır, bu da iş akışının erken bitmesi anlamına gelir. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run exhausted.nf +``` + +??? success "Komut çıktısı" + +```console title="Exhausted channel output" + N E X T F L O W ~ version 25.10.2 + +Launching `exhausted.nf` [extravagant_gauss] DSL2 - revision: 08cff7ba2a + +executor > local (1) +[bd/f61fff] PROCESS_FILES (1) [100%] 1 of 1 ✔ +``` + +Bu iş akışı hatasız tamamlanır, ancak yalnızca tek bir örneği işler! + +#### Kodu kontrol edin + +Bunun doğru olup olmadığını görmek için `exhausted.nf` dosyasını inceleyelim: + +```groovy title="exhausted.nf" hl_lines="23 24" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val reference + val sample_name + + output: + path "${output_prefix}.txt" + + script: + // Define variables in Groovy code before the script + output_prefix = "${reference}_${sample_name}" + def timestamp = new Date().format("yyyy-MM-dd") + + """ + echo "Processing ${sample_name} on ${timestamp}" > ${output_prefix}.txt + """ +} + +workflow { + + reference_ch = channel.of('baseline_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +Process üç kez yerine yalnızca bir kez çalışır çünkü `reference_ch` kanalı, ilk process yürütmesinden sonra tükenen bir queue kanalıdır. Bir kanal tükendiğinde, diğer kanalların hala öğeleri olsa bile tüm process durur. + +Bu, birden çok örnek arasında yeniden kullanılması gereken tek bir referans dosyanız olduğu yaygın bir desendir. Çözüm, referans kanalını süresiz olarak yeniden kullanılabilecek bir value kanalına dönüştürmektir. + +#### Kodu düzeltin + +Kaç dosyanın etkilendiğine bağlı olarak bunu ele almanın birkaç yolu vardır. + +**Seçenek 1**: Çok fazla yeniden kullandığınız tek bir referans dosyanız var. Defalarca kullanılabilecek bir value kanal türü oluşturabilirsiniz. Bunu yapmanın üç yolu vardır: + +**1a** `channel.value()` kullanın: + +```groovy title="exhausted.nf (fixed - Option 1a)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.value('baseline_reference') // Value channel can be reused + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1b** `first()` [operatörünü](https://www.nextflow.io/docs/latest/reference/operator.html#first) kullanın: + +```groovy title="exhausted.nf (fixed - Option 1b)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').first() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**1c.** `collect()` [operatörünü](https://www.nextflow.io/docs/latest/reference/operator.html#collect) kullanın: + +```groovy title="exhausted.nf (fixed - Option 1c)" hl_lines="2" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference').collect() // Convert to value channel + input_ch = channel.of('sample1', 'sample2', 'sample3') + + PROCESS_FILES(reference_ch, input_ch) +} +``` + +**Seçenek 2**: Daha karmaşık senaryolarda, belki de sample kanalındaki tüm örnekler için birden fazla referans dosyanız olduğunda, iki kanalı tuple'lara birleştiren yeni bir kanal oluşturmak için `combine` operatörünü kullanabilirsiniz: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="4" linenums="21" +workflow { + reference_ch = channel.of('baseline_reference','other_reference') + input_ch = channel.of('sample1', 'sample2', 'sample3') + combined_ch = reference_ch.combine(input_ch) // Creates cartesian product + + PROCESS_FILES(combined_ch) +} +``` + +`.combine()` operatörü iki kanalın kartezyen çarpımını oluşturur, bu nedenle `reference_ch` içindeki her öğe `input_ch` içindeki her öğe ile eşleştirilecektir. Bu, process'in her örnek için çalışmasına izin verirken yine de referansı kullanmasını sağlar. + +Bu, process girdisinin ayarlanmasını gerektirir. Örneğimizde, process tanımının başlangıcının aşağıdaki gibi ayarlanması gerekecektir: + +```groovy title="exhausted.nf (fixed - Option 2)" hl_lines="5" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + tuple val(reference), val(sample_name) +``` + +Bu yaklaşım tüm durumlarda uygun olmayabilir. + +#### Pipeline'ı çalıştırın + +Yukarıdaki düzeltmelerden birini deneyin ve iş akışını tekrar çalıştırın: + +```bash +nextflow run exhausted.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `exhausted.nf` [maniac_leavitt] DSL2 - revision: f372a56a7d + + executor > local (3) + [80/0779e9] PROCESS_FILES (3) | 3 of 3 ✔ + ``` + +Artık yalnızca bir tane yerine üç örneğin de işlendiğini görmelisiniz. + +### 2.3. Yanlış Kanal İçerik Yapısı + +İş akışları belirli bir karmaşıklık düzeyine ulaştığında, her kanalın iç yapılarını takip etmek biraz zor olabilir ve insanlar yaygın olarak process'in beklediği ile kanalın gerçekte içerdiği arasında uyumsuzluklar yaratırlar. Bu, daha önce tartıştığımız, kanal sayısının yanlış olduğu sorundan daha inceliklidir. Bu durumda, doğru sayıda girdi kanalına sahip olabilirsiniz, ancak bu kanallardan birinin veya daha fazlasının iç yapısı process'in beklediği ile eşleşmez. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_channel_shape.nf +``` + +??? failure "Komut çıktısı" + + ```console + Launching `bad_channel_shape.nf` [hopeful_pare] DSL2 - revision: ffd66071a1 + + executor > local (3) + executor > local (3) + [3f/c2dcb3] PROCESS_FILES (3) [ 0%] 0 of 3 ✘ + ERROR ~ Error executing process > 'PROCESS_FILES (1)' + + Caused by: + Missing output file(s) `[sample1, file1.txt]_output.txt` expected by process `PROCESS_FILES (1)` + + + Command executed: + + echo "Processing [sample1, file1.txt]" > [sample1, file1.txt]_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/d6/1fb69d1d93300bbc9d42f1875b981e + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Kodu kontrol edin + +Hata mesajındaki köşeli parantezler burada ipucunu sağlar - process tuple'ı tek bir değer olarak ele alır, bu bizim istediğimiz şey değil. `bad_channel_shape.nf` dosyasını inceleyelim: + +```groovy title="bad_channel_shape.nf" hl_lines="5 20-22" linenums="1" +#!/usr/bin/env nextflow + +process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ +} + +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) +} +``` + +Tuple'lardan oluşan bir kanal oluşturduğumuzu görebilirsiniz: `['sample1', 'file1.txt']`, ancak process tek bir değer bekliyor, `val sample_name`. Yürütülen komut, process'in `[sample3, file3.txt]_output.txt` adında bir dosya oluşturmaya çalıştığını gösterir, bu amaçlanan çıktı değildir. + +#### Kodu düzeltin + +Bunu düzeltmek için, process her iki girdiyi de gerektiriyorsa process'i bir tuple kabul edecek şekilde ayarlayabiliriz: + +=== "Seçenek 1: Process'te tuple kabul et" + + === "Sonra" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + tuple val(sample_name), val(file_name) // Fixed: Accept tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + + === "Önce" + + ```groovy title="bad_channel_shape.nf" hl_lines="5" linenums="1" + #!/usr/bin/env nextflow + + process PROCESS_FILES { + input: + val sample_name // Expects single value, gets tuple + + output: + path "${sample_name}_output.txt" + + script: + """ + echo "Processing ${sample_name}" > ${sample_name}_output.txt + """ + } + + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +=== "Seçenek 2: İlk öğeyi çıkar" + + === "Sonra" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch.map { it[0] }) // Fixed: Extract first element + } + ``` + + === "Önce" + + ```groovy title="bad_channel_shape.nf" hl_lines="9" linenums="16" + workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + PROCESS_FILES(input_ch) + } + ``` + +#### Pipeline'ı çalıştırın + +Çözümlerden birini seçin ve iş akışını yeniden çalıştırın: + +```bash +nextflow run bad_channel_shape.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape.nf` [clever_thompson] DSL2 - revision: 8cbcae3746 + + executor > local (3) + [bb/80a958] PROCESS_FILES (2) | 3 of 3 ✔ + ``` + +### 2.4. Kanal Hata Ayıklama Teknikleri + +#### Kanal İncelemesi için `.view()` Kullanımı + +Kanallar için en güçlü hata ayıklama aracı `.view()` operatörüdür. `.view()` ile hata ayıklamaya yardımcı olmak için kanallarınızın şeklini tüm aşamalarda anlayabilirsiniz. + +#### Pipeline'ı çalıştırın + +Bunu eylemde görmek için `bad_channel_shape_viewed.nf` dosyasını çalıştırın: + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [maniac_poisson] DSL2 - revision: b4f24dc9da + + executor > local (3) + [c0/db76b3] PROCESS_FILES (3) [100%] 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +#### Kodu kontrol edin + +`.view()` öğesinin nasıl kullanıldığını görmek için `bad_channel_shape_viewed.nf` dosyasını inceleyelim: + +```groovy title="bad_channel_shape_viewed.nf" linenums="16" hl_lines="9 11" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'] + ) + .view { "Channel content: $it" } // Debug: Show original channel content + .map { tuple -> tuple[0] } // Transform: Extract first element + .view { "After mapping: $it" } // Debug: Show transformed channel content + + PROCESS_FILES(input_ch) +} +``` + +#### Kodu düzeltin + +Gelecekte kanal içeriğini anlamak için `.view()` işlemlerini aşırı kullanmaktan sizi kurtarmak için yardımcı olması için bazı yorumlar eklemeniz tavsiye edilir: + +```groovy title="bad_channel_shape_viewed.nf (with comments)" linenums="16" hl_lines="8 9" +workflow { + + // Channel emits tuples, but process expects single values + input_ch = channel.of( + ['sample1', 'file1.txt'], + ['sample2', 'file2.txt'], + ['sample3', 'file3.txt'], + ) // [sample_name, file_name] + .map { tuple -> tuple[0] } // sample_name + + PROCESS_FILES(input_ch) +} +``` + +Bu, iş akışlarınız karmaşıklık olarak büyüdükçe ve kanal yapısı daha opak hale geldikçe daha önemli hale gelecektir. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run bad_channel_shape_viewed.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `bad_channel_shape_viewed.nf` [marvelous_koch] DSL2 - revision: 03e79cdbad + + executor > local (3) + [ff/d67cec] PROCESS_FILES (2) | 3 of 3 ✔ + Channel content: [sample1, file1.txt] + Channel content: [sample2, file2.txt] + Channel content: [sample3, file3.txt] + After mapping: sample1 + After mapping: sample2 + After mapping: sample3 + ``` + +### Çıkarımlar + +Birçok kanal yapısı hatası geçerli Nextflow sözdizimi ile oluşturulabilir. Veri akışını anlayarak, inceleme için `.view()` operatörlerini kullanarak ve beklenmedik tuple yapılarını gösteren köşeli parantezler gibi hata mesajı desenlerini tanıyarak kanal yapısı hatalarında hata ayıklayabilirsiniz. + +### Sırada ne var? + +Process tanımlarından kaynaklanan hatalar hakkında bilgi edinin. + +--- + +## 3. Process Yapısı Hataları + +Process'lerle ilgili karşılaşacağınız hataların çoğu, komutu oluştururken yaptığınız hatalara veya temel yazılımla ilgili sorunlara bağlı olacaktır. Bununla birlikte, yukarıdaki kanal sorunlarına benzer şekilde, sözdizimi hatası olarak nitelendirilmeyen ancak çalışma zamanında hatalara neden olacak process tanımında hatalar yapabilirsiniz. + +### 3.1. Eksik Çıktı Dosyaları + +Process'leri yazarken yaygın bir hata, process'in beklediği ile oluşturulan arasında uyumsuzluk yaratan bir şey yapmaktır. + +#### Pipeline'ı çalıştırın + +```bash +nextflow run missing_output.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `missing_output.nf` [zen_stone] DSL2 - revision: 37ff61f926 + + executor > local (3) + executor > local (3) + [fd/2642e9] process > PROCESS_FILES (2) [ 66%] 2 of 3, failed: 2 + ERROR ~ Error executing process > 'PROCESS_FILES (3)' + + Caused by: + Missing output file(s) `sample3.txt` expected by process `PROCESS_FILES (3)` + + + Command executed: + + echo "Processing sample3" > sample3_output.txt + + Command exit status: + 0 + + Command output: + (empty) + + Work dir: + /workspaces/training/side-quests/debugging/work/02/9604d49fb8200a74d737c72a6c98ed + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +#### Kodu kontrol edin + +Hata mesajı, process'in `sample3.txt` adında bir çıktı dosyası üretmesini beklediğini, ancak script'in aslında `sample3_output.txt` oluşturduğunu gösterir. `missing_output.nf` içindeki process tanımını inc diff --git a/docs/tr/docs/side_quests/dev_environment.md b/docs/tr/docs/side_quests/dev_environment.md new file mode 100644 index 0000000000..04277327f0 --- /dev/null +++ b/docs/tr/docs/side_quests/dev_environment.md @@ -0,0 +1,630 @@ +# Geliştirme Ortamı + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Modern Entegre Geliştirme Ortamları (IDE'ler) Nextflow geliştirme deneyiminizi önemli ölçüde dönüştürebilir. Bu yan görev, özellikle VS Code ve Nextflow eklentisini kullanarak daha hızlı kod yazma, hataları erken yakalama ve karmaşık iş akışlarında verimli gezinme konularına odaklanır. + +!!! note "Bu geleneksel bir eğitim değildir" + + Diğer eğitim modüllerinin aksine, bu kılavuz adım adım bir eğitimden ziyade hızlı ipuçları, tavsiyeler ve pratik örnekler koleksiyonu olarak düzenlenmiştir. Her bölüm, mevcut geliştirme ihtiyaçlarınıza ve ilgi alanlarınıza göre bağımsız olarak keşfedilebilir. İstediğiniz gibi gezinin ve iş akışı geliştirmeniz için en faydalı olacak özelliklere odaklanın. + +## Önce bilmeniz gerekenler + +Bu kılavuz, [Hello Nextflow](../hello_nextflow/) eğitim kursunu tamamladığınızı ve aşağıdakiler dahil temel Nextflow kavramlarında rahat olduğunuzu varsayar: + +- **Temel iş akışı yapısı**: Süreçleri, iş akışlarını ve bunların nasıl birbirine bağlandığını anlama +- **Kanal işlemleri**: Kanal oluşturma, süreçler arasında veri aktarma ve temel operatörleri kullanma +- **Modüller ve organizasyon**: Yeniden kullanılabilir modüller oluşturma ve include ifadelerini kullanma +- **Yapılandırma temelleri**: Parametreler, süreç yönergeleri ve profiller için `nextflow.config` kullanma + +## Burada neler öğreneceksiniz + +Bu kılavuz, sizi daha verimli bir Nextflow geliştiricisi yapacak **IDE üretkenlik özelliklerine** odaklanır: + +- **Gelişmiş sözdizimi vurgulama**: VS Code'un kod yapınız hakkında size ne gösterdiğini anlama +- **Akıllı otomatik tamamlama**: Daha hızlı kod yazımı için içeriğe duyarlı önerilerden yararlanma +- **Hata algılama ve tanılama**: İş akışınızı çalıştırmadan önce sözdizimi hatalarını yakalama +- **Kod gezinmesi**: Süreçler, modüller ve tanımlar arasında hızlıca geçiş yapma +- **Biçimlendirme ve organizasyon**: Tutarlı, okunabilir kod stilini koruma +- **Yapay zeka destekli geliştirme** (opsiyonel): IDE'nizle entegre modern yapay zeka araçlarını kullanma + +!!! info "Neden şimdi IDE özellikleri?" + + [Hello Nextflow](../hello_nextflow/) kursu sırasında muhtemelen VS Code'u zaten kullanıyordunuz, ancak odağı IDE özelliklerinden ziyade Nextflow temellerini öğrenmeye yönlendirdik. Artık süreçler, iş akışları, kanallar ve modüller gibi temel Nextflow kavramlarında rahatsınız, sizi daha verimli bir geliştirici yapacak gelişmiş IDE özelliklerinden yararlanmaya hazırsınız. + + Bunu geliştirme ortamınızı "seviye atlama" olarak düşünün - kullandığınız aynı editör, ne konusunda size yardımcı olduklarını anladıktan sonra gerçekten değerli hale gelen çok daha güçlü yeteneklere sahip. + +--- + +## 0. Kurulum ve Isınma + +IDE özelliklerini keşfetmek için özel olarak bir çalışma alanı oluşturalım: + +```bash title="IDE özellikleri dizinine gidin" +cd side-quests/ide_features +``` + +Bu dizini VS Code'da açın: + +```bash title="Geçerli dizinde VS Code'u açın" +code . +``` + +`ide_features` dizini çeşitli IDE özelliklerini gösteren örnek iş akışlarını içerir: + +```bash title="Dizin yapısını göster" +tree . +``` + +```console title="Proje yapısı" +tree . +. +├── basic_workflow.nf +├── complex_workflow.nf +├── data +│ ├── sample_001.fastq.gz +│ ├── sample_002.fastq.gz +│ ├── sample_003.fastq.gz +│ ├── sample_004.fastq.gz +│ ├── sample_005.fastq.gz +│ └── sample_data.csv +├── modules +│ ├── fastqc.nf +│ ├── star.nf +│ └── utils.nf +└── nextflow.config + +3 directories, 12 files +``` + +!!! note "Örnek Dosyalar Hakkında" + + - `basic_workflow.nf` çalıştırabileceğiniz ve değiştirebileceğiniz çalışan temel bir iş akışıdır + - `complex_workflow.nf` sadece gösterim amaçlı tasarlanmıştır ve gezinme özelliklerini gösterir - başarıyla çalışmayabilir ancak gerçekçi çok dosyalı iş akışı yapısını gösterir + +### Klavye Kısayolları + +Bu kılavuzdaki bazı özellikler opsiyonel klavye kısayollarını kullanacaktır. Bu materyale tarayıcı üzerinden GitHub Codespaces aracılığıyla erişiyor olabilirsiniz ve bu durumda bazen kısayollar beklendiği gibi çalışmayabilir çünkü sisteminizde başka şeyler için kullanılıyorlar. + +VS Code'u yerel olarak çalıştırıyorsanız, muhtemelen gerçekte iş akışları yazarken olacağınız gibi, kısayollar açıklandığı gibi çalışacaktır. + +Mac kullanıyorsanız, bazı (hepsi değil) klavye kısayolları "ctrl" yerine "cmd" kullanacaktır ve bunu metinde `Ctrl/Cmd` şeklinde belirteceğiz. + +### 0.1. Nextflow Eklentisini Kurma + +!!! note "Zaten Devcontainer Kullanıyor musunuz?" + + **GitHub Codespaces**'te çalışıyorsanız veya **yerel bir devcontainer** kullanıyorsanız, Nextflow eklentisi muhtemelen sizin için zaten kurulu ve yapılandırılmış durumdadır. Aşağıdaki manuel kurulum adımlarını atlayabilir ve doğrudan eklenti özelliklerini keşfetmeye devam edebilirsiniz. + +Eklentiyi manuel olarak kurmak için: + +1. VS Code'u açın +2. Sol taraftaki eklentiler simgesine tıklayarak Extensions görünümüne gidin: ![eklentiler simgesi](img/extensions_icon.png) (VSCode'u yerel olarak çalıştırıyorsanız kısayol `Ctrl/Cmd+Shift+X`) +3. "Nextflow" arayın +4. Resmi Nextflow eklentisini kurun + +![Nextflow Eklentisini Kur](img/install_extension.png) + +### 0.2. Çalışma Alanı Düzeni + +Hello Nextflow boyunca VS Code kullandığınız için temellere zaten aşinasınız. Bu oturum için çalışma alanınızı verimli bir şekilde nasıl düzenleyeceğiniz aşağıda açıklanmıştır: + +- **Editör Alanı**: Dosyaları görüntülemek ve düzenlemek için. Dosyaları yan yana karşılaştırmak için bunu birden fazla bölmeye ayırabilirsiniz. +- **Dosya Gezgini** tıklayın (![dosya gezgini simgesi](img/files_icon.png)) (`Ctrl/Cmd+Shift+E`): Sisteminizdeki yerel dosyalar ve klasörler. Dosyalar arasında gezinmek için bunu solda açık tutun +- **Entegre Terminal** (`Ctrl+Shift+` ters tırnak hem Windows hem de MacOS için): Alt kısımda bilgisayarla etkileşim için bir terminal. Nextflow veya diğer komutları çalıştırmak için bunu kullanın. +- **Sorunlar Paneli** (`Ctrl+Shift+M`): VS Code algıladığı hataları ve sorunları burada gösterecektir. Bu, sorunları bir bakışta vurgulamak için kullanışlıdır. + +Örnekler üzerinde çalışırken düzeninizi özelleştirmek için panelleri sürükleyebilir veya gizleyebilirsiniz (kenar çubuğunu açıp kapatmak için `Ctrl/Cmd+B`). + +### Çıkarım + +VS Code'u Nextflow eklentisi ile kurdunuz ve verimli geliştirme için çalışma alanı düzenini anlıyorsunuz. + +### Sırada ne var? + +Sözdizimi vurgulamanın Nextflow kod yapısını bir bakışta anlamanıza nasıl yardımcı olduğunu öğrenin. + +--- + +## 1. Sözdizimi Vurgulama ve Kod Yapısı + +Artık çalışma alanınız hazır olduğuna göre, VS Code'un sözdizimi vurgulamasının Nextflow kodunu daha etkili bir şekilde okumanıza ve yazmanıza nasıl yardımcı olduğunu keşfedelim. + +### 1.1. Nextflow Sözdizimi Öğeleri + +Sözdizimi vurgulamayı çalışırken görmek için `basic_workflow.nf`'i açın: + +![Sözdizimi Vitrini](img/syntax_showcase.png) + +VS Code'un nasıl vurguladığına dikkat edin: + +- **Anahtar kelimeler** (`process`, `workflow`, `input`, `output`, `script`) farklı renklerde +- **Dize değişmezleri** ve **parametreler** farklı stillerde +- **Yorumlar** sönük bir renkte +- **Değişkenler** ve **fonksiyon çağrıları** uygun vurguyla +- **Kod blokları** uygun girinti kılavuzlarıyla + +!!! note "Temaya Bağlı Renkler" + + Gördüğünüz belirli renkler VS Code temanıza (karanlık/açık mod), renk ayarlarınıza ve yaptığınız özelleştirmelere bağlı olacaktır. Önemli olan, kod yapısının seçtiğiniz renk şemasından bağımsız olarak anlaşılmasını kolaylaştırmak için farklı sözdizimi öğelerinin görsel olarak birbirinden ayırt edilmesidir. + +### 1.2. Kod Yapısını Anlama + +Sözdizimi vurgulaması size şunları hızlıca belirlemenize yardımcı olur: + +- **Süreç sınırları**: Farklı süreçler arasında net ayrım +- **Girdi/çıktı blokları**: Veri akışı tanımlarını bulmayı kolaylaştırır +- **Script blokları**: Yürütülen gerçek komutlar +- **Kanal işlemleri**: Veri dönüştürme adımları +- **Yapılandırma yönergeleri**: Sürece özgü ayarlar + +Bu görsel organizasyon, birden fazla süreç ve karmaşık veri akışları içeren karmaşık iş akışlarıyla çalışırken paha biçilmez hale gelir. + +### Çıkarım + +VS Code'un sözdizimi vurgulamasının Nextflow kod yapısını okumanıza ve daha hızlı geliştirme için farklı dil öğelerini belirlemenize nasıl yardımcı olduğunu anlıyorsunuz. + +### Sırada ne var? + +Akıllı otomatik tamamlamanın içeriğe duyarlı önerilerle kod yazmayı nasıl hızlandırdığını öğrenin. + +--- + +## 2. Akıllı Otomatik Tamamlama + +VS Code'un otomatik tamamlama özellikleri, içeriğe göre uygun seçenekler önererek daha hızlı ve daha az hatayla kod yazmanıza yardımcı olur. + +### 2.1. İçeriğe Duyarlı Öneriler + +Otomatik tamamlama seçenekleri kodunuzda nerede olduğunuza bağlı olarak değişir: + +#### Kanal İşlemleri + +`basic_workflow.nf`'i tekrar açın ve workflow bloğunda `channel.` yazmayı deneyin: + +![Kanal otomatik tamamlama](img/autocomplete_channel.png) + +Şunlar için öneriler göreceksiniz: + +- `fromPath()` - Dosya yollarından kanal oluştur +- `fromFilePairs()` - Eşleştirilmiş dosyalardan kanal oluştur +- `of()` - Değerlerden kanal oluştur +- `fromSRA()` - SRA erişim numaralarından kanal oluştur +- Ve daha fazlası... + +Bu, tam metod adlarını hatırlamak zorunda kalmadan kullanılacak doğru kanal fabrikasını hızlıca bulmanıza yardımcı olur. + +Ayrıca kanallara uygulanabilecek operatörleri de keşfedebilirsiniz. Örneğin, mevcut işlemleri görmek için `FASTQC.out.html.` yazın: + +![Kanal işlemleri otomatik tamamlama](img/autocomplete_operators.png) + +#### Süreç Yönergeleri + +Bir süreç script bloğunun içinde, mevcut çalışma zamanı özelliklerini görmek için `task.` yazın: + +![Görev özellikleri otomatik tamamlama](img/autocomplete_task.png) + +#### Yapılandırma + +nextflow.config dosyasını açın ve mevcut süreç yönergelerini görmek için herhangi bir yere `process.` yazın: + +![Yapılandırma otomatik tamamlama](img/autocomplete_config.png) + +Şunlar için öneriler göreceksiniz: + +- `executor` +- `memory` +- `cpus` + +Bu, süreçleri yapılandırırken zamandan tasarruf sağlar ve farklı yapılandırma kapsamlarında çalışır. Örneğin, Docker'a özgü yapılandırma seçeneklerini görmek için `docker.` yazmayı deneyin. + +### Çıkarım + +Sözdizimini ezberlemeden mevcut kanal işlemlerini, süreç yönergelerini ve yapılandırma seçeneklerini keşfetmek için VS Code'un akıllı otomatik tamamlamasını kullanabilirsiniz. + +### Sırada ne var? + +Gerçek zamanlı hata algılamanın, iş akışınızı çalıştırmadan önce sorunları sadece kodu okuyarak yakalamanıza nasıl yardımcı olduğunu öğrenin. + +## 3. Hata Algılama ve Tanılama + +VS Code'un gerçek zamanlı hata algılaması, iş akışınızı çalıştırmadan önce sorunları yakalamanıza yardımcı olur. + +### 3.1. Sözdizimi Hatası Algılama + +Algılamayı çalışırken görmek için kasıtlı bir hata oluşturalım. `basic_workflow.nf`'i açın ve süreç adını `FASTQC`'den `FASTQ`'ya (veya başka geçersiz bir ada) değiştirin. VS Code hatayı workflow bloğunda kırmızı dalgalı alt çizgiyle hemen vurgulayacaktır: + +![Hata alt çizgisi](img/error_underline.png) + +### 3.2. Sorunlar Paneli + +Bireysel hata vurgulamanın ötesinde, VS Code çalışma alanınızdaki tüm hataları, uyarıları ve bilgi mesajlarını toplayan merkezi bir Sorunlar paneli sağlar. `Ctrl/Cmd+Shift+M` ile açın ve yalnızca geçerli dosyayla ilgili hataları göstermek için filtre simgesini kullanın: + +![Sorunlar panelini filtrele](img/active_file.png) + +Sorunlu satıra doğrudan atlamak için herhangi bir soruna tıklayın + +![Sorunlar Paneli](img/problems_panel.png) + +Süreç adını tekrar `FASTQC` olarak değiştirerek hatayı düzeltin. + +### 3.3. Yaygın Hata Kalıpları + +Nextflow sözdizimindeki yaygın hatalar şunlardır: + +- **Eksik parantezler**: Eşleşmeyen `{` veya `}` +- **Eksik bloklar**: Süreçlerde gerekli bölümlerin eksik olması +- **Geçersiz sözdizimi**: Hatalı biçimlendirilmiş Nextflow DSL +- **Anahtar kelimelerde yazım hataları**: Yanlış yazılmış süreç yönergeleri +- **Kanal uyumsuzlukları**: Tür uyumsuzlukları + +Nextflow dil sunucusu bu sorunları Sorunlar panelinde vurgular. Bir boru hattı çalıştırırken sözdizimi hatalarından kaçınmak için bunları erken kontrol edebilirsiniz. + +### Çıkarım + +İş akışınızı çalıştırmadan önce sözdizimi hatalarını ve sorunları yakalamak için VS Code'un hata algılamasını ve Sorunlar panelini kullanabilir, zamandan tasarruf edebilir ve hayal kırıklığını önleyebilirsiniz. + +### Sırada ne var? + +Karmaşık iş akışlarında süreçler, modüller ve tanımlar arasında nasıl verimli gezineceğinizi öğrenin. + +--- + +## 4. Kod Gezinmesi ve Sembol Yönetimi + +Birden fazla dosyaya yayılan karmaşık iş akışlarıyla çalışırken verimli gezinme çok önemlidir. Bunu anlamak için, `basic_workflow.nf`'deki süreç tanımını size sağladığımız modül için bir import ile değiştirin: + +=== "Sonra" + + ```groovy title="basic_workflow.nf" linenums="3" + include { FASTQC } from './modules/fastqc.nf' + ``` + +=== "Önce" + + ```groovy title="basic_workflow.nf" linenums="3" + process FASTQC { + tag "${sample_id}" + publishDir "${params.output_dir}/fastqc", mode: 'copy' + + input: + tuple val(sample_id), path(reads) + + output: + tuple val(sample_id), path("*.html"), emit: html + tuple val(sample_id), path("*.zip"), emit: zip + + script: + def args = task.ext.args ?: '' + """ + fastqc \\ + ${args} \\ + --threads ${task.cpus} \\ + ${reads} + """ + } + ``` + +### 4.1. Tanıma Git + +`FASTQC` gibi bir süreç adının üzerine fareyle gelirseniz, modül arayüzünü (girdiler ve çıktılar) içeren bir açılır pencere göreceksiniz: + +![Tanıma git](img/syntax.png) + +Bu özellik, modül dosyasını doğrudan açmadan modül arayüzünü anlamanıza olanak tanıdığı için iş akışları yazarken özellikle değerlidir. + +**Ctrl/Cmd-tıklama** kullanarak herhangi bir süreç, modül veya değişken tanımına hızlıca gidebilirsiniz. Betiğin üst kısmındaki modül dosyasına bağlantı üzerine fareyle gelin ve önerildiği gibi bağlantıyı takip edin: + +![Bağlantıyı takip et](img/follow_link.png) + +Aynı şey süreç adları için de çalışır. `basic_workflow.nf`'e geri dönün ve bunu workflow bloğundaki `FASTQC` süreç adında deneyin. Bu sizi doğrudan süreç adına bağlar (bu örnekte modül dosyasıyla aynıdır, ancak çok daha büyük bir dosyanın ortasında olabilir). + +Bulunduğunuz yere geri dönmek için **Alt+←** (veya Mac'te **Ctrl+-**) kullanın. Bu, yerinizi kaybetmeden kodu keşfetmenin güçlü bir yoludur. + +Şimdi `complex_workflow.nf`'i (daha önce bahsedilen sadece gösterim amaçlı dosya) kullanarak daha karmaşık bir iş akışında gezinmeyi keşfedelim. Bu iş akışı, ayrı modül dosyalarında tanımlanan birden fazla süreç ve bazı satır içi süreçler içerir. Karmaşık çok dosyalı yapılar manuel olarak gezinmek zor olabilse de, tanımlara atlama yeteneği keşfetmeyi çok daha yönetilebilir hale getirir. + +1. `complex_workflow.nf`'i açın +2. Modül tanımlarına gidin +3. Geri gitmek için **Alt+←** (veya **Ctrl+-**) kullanın +4. Workflow bloğundaki `FASTQC` süreç adına gidin. Bu sizi doğrudan süreç adına bağlar (bu örnekte modül dosyasıyla aynıdır, ancak çok daha büyük bir dosyanın ortasında olabilir). +5. Tekrar geri gidin +6. Workflow bloğundaki `TRIM_GALORE` sürecine gidin. Bu satır içi tanımlanmıştır, bu nedenle sizi ayrı bir dosyaya götürmez, ancak yine de süreç tanımını gösterir ve bulunduğunuz yere geri gidebilirsiniz. + +### 4.2. Sembol Gezinmesi + +`complex_workflow.nf` hala açıkken, VSCode'un üst kısmındaki arama çubuğuna `@` yazarak dosyadaki tüm sembollerin genel görünümünü elde edebilirsiniz (klavye kısayolu `Ctrl/Cmd+Shift+O`'dur, ancak Codespaces'te çalışmayabilir). Bu, geçerli dosyadaki tüm sembolleri listeleyen sembol gezinme panelini açar: + +![Sembol gezinmesi](img/symbols.png) + +Bu şunları gösterir: + +- Tüm süreç tanımları +- Workflow tanımları (bu dosyada iki workflow tanımlanmıştır) +- Fonksiyon tanımları + +Sonuçları filtrelemek için yazmaya başlayın. + +### 4.3. Tüm Referansları Bul + +Bir sürecin veya değişkenin kod tabanınız boyunca nerede kullanıldığını anlamak çok yardımcı olabilir. Örneğin, `FASTQC` sürecine yapılan tüm referansları bulmak istiyorsanız, önce tanımına giderek başlayın. Bunu doğrudan `modules/fastqc.nf`'i açarak veya yukarıda yaptığımız gibi VS Code'un `Ctrl/Cmd-tıklama` ile hızlı gezinme özelliğini kullanarak yapabilirsiniz. Süreç tanımına ulaştıktan sonra, `FASTQC` süreç adına sağ tıklayın ve kullanıldığı tüm örnekleri görmek için bağlam menüsünden "Find All References"ı seçin. + +![Referansları bul](img/references.png) + +Bu özellik, `FASTQC`'nin çalışma alanınızda referans verildiği tüm örnekleri, iki farklı iş akışındaki kullanımı dahil olmak üzere gösterir. Bu içgörü, `FASTQC` sürecindeki değişikliklerin potansiyel etkisini değerlendirmek için çok önemlidir. + +### 4.4. Anahat Paneli + +Explorer kenar çubuğunda bulunan (![Explorer simgesi](img/files_icon.png) tıklayın) Outline paneli, geçerli dosyanızdaki tüm sembollerin kullanışlı bir genel görünümünü sağlar. Bu özellik, fonksiyonları, değişkenleri ve diğer anahtar öğeleri hiyerarşik bir görünümde göstererek kodunuzun yapısında hızlıca gezinmenize ve yönetmenize olanak tanır. + +![Anahat paneli](img/outline.png) + +Dosya tarayıcısını kullanmadan kodunuzun farklı bölümlerine hızlıca gitmek için Outline panelini kullanın. + +### 4.5. DAG görselleştirme + +VS Code'un Nextflow eklentisi iş akışınızı Yönlendirilmiş Döngüsüz Grafik (DAG) olarak görselleştirebilir. Bu, veri akışını ve süreçler arasındaki bağımlılıkları anlamanıza yardımcı olur. `complex_workflow.nf`'i açın ve `workflow {`'ın üzerindeki "Preview DAG" düğmesine tıklayın (bu dosyadaki ikinci `workflow` bloğu): + +![DAG önizlemesi](img/dag_preview.png) + +Bu sadece 'giriş' iş akışıdır, ancak yukarıdaki `workflow RNASEQ_PIPELINE {`'nin üzerindeki "Preview DAG" düğmesine tıklayarak iç iş akışları için DAG'yi de önizleyebilirsiniz: + +![DAG önizlemesi iç iş akışı](img/dag_preview_inner.png) + +Bu iş akışı için, koddaki ilgili süreç tanımlarına gitmek için DAG'deki düğümleri kullanabilirsiniz. Bir düğüme tıklayın ve sizi editörde ilgili süreç tanımına götürecektir. Özellikle bir iş akışı büyük bir boyuta ulaştığında, bu gerçekten kod etrafında gezinmenize ve süreçlerin nasıl bağlandığını anlamanıza yardımcı olabilir. + +### Çıkarım + +Kod yapısını ve bağımlılıkları anlamak için tanıma git, sembol arama, referansları bul ve DAG görselleştirme özelliklerini kullanarak karmaşık iş akışlarında verimli gezinebilirsiniz. + +### Sırada ne var? + +Daha büyük Nextflow projelerinde birbirine bağlı birden fazla dosyayla nasıl etkili çalışacağınızı öğrenin. + +## 5. Birden Fazla Dosyada Çalışma + +Gerçek Nextflow geliştirme, birbirine bağlı birden fazla dosyayla çalışmayı içerir. VS Code'un karmaşık projeleri verimli bir şekilde yönetmenize nasıl yardımcı olduğunu keşfedelim. + +### 5.1. Hızlı Dosya Gezinmesi + +`complex_workflow.nf` açıkken, birkaç modülü içe aktardığını fark edeceksiniz. Aralarında hızlı gezinme pratiği yapalım. + +**Ctrl+P** (veya **Cmd+P**) tuşuna basın ve "fast" yazmaya başlayın: + +VS Code size eşleşen dosyaları gösterecektir. Anında atlamak için `modules/fastqc.nf`'i seçin. Bu, hangi dosyayı aradığınızı kabaca bildiğinizde dosya gezgini arasında tıklamaktan çok daha hızlıdır. + +Bunu diğer kalıplarla deneyin: + +- STAR hizalama modül dosyasını (`star.nf`) bulmak için "star" yazın +- Yardımcı fonksiyonlar dosyasını (`utils.nf`) bulmak için "utils" yazın +- Yapılandırma dosyalarına (`nextflow.config`) atlamak için "config" yazın + +### 5.2. Çok Dosyalı Geliştirme için Bölünmüş Editör + +Modüllerle çalışırken, genellikle hem ana iş akışını hem de modül tanımlarını aynı anda görmeniz gerekir. Bunu kuralım: + +1. `complex_workflow.nf`'i açın +2. Yeni bir sekmede `modules/fastqc.nf`'i açın +3. `modules/fastqc.nf` sekmesine sağ tıklayın ve "Split Right" seçin +4. Şimdi her iki dosyayı yan yana görebilirsiniz + +![Bölünmüş editör](img/split_editor.png) + +Bu şu durumlarda paha biçilmezdir: + +- Workflow çağrılarını yazarken modül arayüzlerini kontrol etme ve önizleme yeterli değil +- Farklı modüller arasında benzer süreçleri karşılaştırma +- Workflow ve modüller arasındaki veri akışında hata ayıklama + +### 5.3. Proje Genelinde Arama + +Bazen belirli kalıpların tüm projenizde nerede kullanıldığını bulmanız gerekir. Arama panelini açmak için `Ctrl/Cmd+Shift+F` tuşlarına basın. + +Çalışma alanı genelinde `publishDir` aramayı deneyin: + +![Proje araması](img/project_search.png) + +Bu size yayınlama dizinlerini kullanan her dosyayı gösterir ve şunlarda yardımcı olur: + +- Çıktı organizasyon kalıplarını anlama +- Belirli yönergelerin örneklerini bulma +- Modüller arasında tutarlılık sağlama + +### Çıkarım + +Hızlı dosya gezinmesi, bölünmüş editörler ve proje genelinde arama kullanarak karmaşık çok dosyalı projeleri yönetebilir ve iş akışları ve modüller arasında verimli çalışabilirsiniz. + +### Sırada ne var? + +Kod biçimlendirme ve bakım özelliklerinin iş akışlarınızı nasıl organize ve okunabilir tuttuğunu öğrenin. + +--- + +## 6. Kod Biçimlendirme ve Bakım + +Uygun kod biçimlendirmesi sadece estetik için değil, aynı zamanda okunabilirliği, anlaşılabilirliği ve karmaşık iş akışlarını güncelleme kolaylığını artırmak için de gereklidir. + +### 6.1. Otomatik Biçimlendirme Çalışırken + +`basic_workflow.nf`'i açın ve kasıtlı olarak biçimlendirmeyi bozun: + +- Bazı girintileri kaldırın: Tüm belgeyi vurgulayın ve mümkün olduğunca çok girintiyi kaldırmak için `shift+tab` tuşlarına birçok kez basın. +- Rastgele yerlere ekstra boşluklar ekleyin: `channel.fromPath` ifadesinde, `(` sonrasına 30 boşluk ekleyin. +- Bazı satırları garip şekilde bölün: `.view {` operatörü ile `Processing sample:` dizesi arasına yeni bir satır ekleyin ancak kapanış parantezi `}` öncesine karşılık gelen bir yeni satır eklemeyin. + +Şimdi otomatik biçimlendirme için `Shift+Alt+F` (veya MacOS'ta `Shift+Option+F`) tuşlarına basın: + +VS Code hemen: + +- Süreç yapısını net göstermek için girintiyi düzeltir +- Benzer öğeleri tutarlı bir şekilde hizalar +- Gereksiz boşlukları kaldırır +- Okunabilir satır sonlarını korur + +Otomatik biçimlendirmenin her kod stili sorununu çözemeyebileceğini unutmayın. Nextflow dil sunucusu kodunuzu düzenli tutmayı amaçlar, ancak belirli alanlarda kişisel tercihlerinize de saygı gösterir. Örneğin, bir sürecin `script` bloğu içindeki girintiyi kaldırırsanız, biçimlendirici olduğu gibi bırakacaktır, çünkü kasıtlı olarak o stili tercih ediyor olabilirsiniz. + +Şu anda Nextflow için katı bir stil zorlaması yoktur, bu nedenle dil sunucusu biraz esneklik sunar. Ancak, netliği korumak için metod ve fonksiyon tanımları etrafında biçimlendirme kurallarını tutarlı bir şekilde uygulayacaktır. + +### 6.2. Kod Organizasyonu Özellikleri + +#### Hızlı Yorum Yapma + +İş akışınızda bir kod bloğu seçin ve yorum satırı haline getirmek için **Ctrl+/** (veya **Cmd+/**) tuşlarına basın: + +```groovy +// workflow { +// ch_input = channel.fromPath(params.input) +// .splitCsv(header: true) +// .map { row -> [row.sample_id, file(row.fastq_path)] } +// +// FASTQC(ch_input) +// } +``` + +Bu şu durumlarda mükemmeldir: + +- Geliştirme sırasında iş akışlarının bölümlerini geçici olarak devre dışı bırakma +- Karmaşık kanal işlemlerine açıklayıcı yorumlar ekleme +- İş akışı bölümlerini belgeleme + +Kodu yorumsuz hale getirmek için tekrar **Ctrl+/** (veya **Cmd+/**) kullanın. + +#### Genel Bakış için Kod Katlama + +`complex_workflow.nf`'de, süreç tanımlarının yanındaki küçük oklara dikkat edin. Süreçleri katlamak (daraltmak) için onlara tıklayın: + +![Kod katlama](img/code_folding.png) + +Bu, uygulama detaylarında kaybolmadan iş akışı yapınızın üst düzey bir genel görünümünü sağlar. + +#### Parantez Eşleştirme + +İmlecinizi herhangi bir `{` veya `}` parantezinin yanına yerleştirin ve VS Code eşleşen parantezi vurgular. Eşleşen parantezler arasında atlamak için **Ctrl+Shift+\\** (veya **Cmd+Shift+\\**) kullanın. + +Bu şunlar için çok önemlidir: + +- Süreç sınırlarını anlama +- Eksik veya fazla parantezleri bulma +- İç içe geçmiş iş akışı yapılarında gezinme + +#### Çok Satırlı Seçim ve Düzenleme + +Birden fazla satırı aynı anda düzenlemek için VS Code güçlü çok imleç yetenekleri sunar: + +- **Çok satırlı seçim**: **Ctrl+Alt** (veya MacOS için **Cmd+Option**) basılı tutun ve birden fazla satır seçmek için ok tuşlarını kullanın +- **Çok satırlı girinti**: Birden fazla satır seçin ve tüm blokları girintili hale getirmek için **Tab** veya girintiyi kaldırmak için **Shift+Tab** kullanın + +Bu özellikle şunlar için kullanışlıdır: + +- Tüm süreç bloklarını tutarlı bir şekilde girintileme +- Aynı anda birden fazla satıra yorum ekleme +- Birden fazla süreçte benzer parametre tanımlarını düzenleme + +### Çıkarım + +Karmaşık iş akışlarını verimli bir şekilde organize etmek için otomatik biçimlendirme, yorum yapma özellikleri, kod katlama, parantez eşleştirme ve çok satırlı düzenleme kullanarak temiz, okunabilir kod koruyabilirsiniz. + +### Sırada ne var? + +VS Code'un sadece kod düzenlemesinin ötesinde daha geniş geliştirme iş akışınızla nasıl entegre olduğunu öğrenin. + +--- + +## 7. Geliştirme İş Akışı Entegrasyonu + +VS Code, sadece kod düzenlemenin ötesinde geliştirme iş akışınızla iyi entegre olur. + +### 7.1. Versiyon Kontrol Entegrasyonu + +!!! note "Codespaces ve Git Entegrasyonu" + + **GitHub Codespaces**'te çalışıyorsanız, bazı Git entegrasyon özellikleri, özellikle Source Control için klavye kısayolları beklendiği gibi çalışmayabilir. Ayrıca ilk kurulum sırasında dizini Git deposu olarak açmayı reddetmiş olabilirsiniz, bu eğitim amaçları için sorun değil. + +Projeniz bir git deposu ise (bunun gibi), VS Code şunları gösterir: + +- Renkli göstergelerle değiştirilmiş dosyalar +- Durum çubuğunda Git durumu +- Satır içi diff görünümleri +- Commit ve push yetenekleri + +Git değişikliklerini görmek ve commit'leri doğrudan editörde hazırlamak için source control düğmesini (![Source control simgesi](img/source_control_icon.png)) kullanarak Source Control panelini açın (`Ctrl+Shift+G` veya VSCode'u yerel olarak çalıştırıyorsanız `Cmd+Shift+G`). + +![Source Control Paneli](img/source_control.png) + +### 7.2. İş Akışlarını Çalıştırma ve İnceleme + +Bir iş akışı çalıştıralım ve ardından sonuçları inceleyelim. Entegre terminalde (hem Windows hem de MacOS için `Ctrl+Shift+` ters tırnak), temel iş akışını çalıştırın: + +```bash title="Temel iş akışını çalıştır" +nextflow run basic_workflow.nf --input data/sample_data.csv --output_dir results +``` + +İş akışı çalışırken terminalde gerçek zamanlı çıktı göreceksiniz. Tamamlandıktan sonra, editörünüzden ayrılmadan sonuçları incelemek için VS Code'u kullanabilirsiniz: + +1. **Work dizinlerine gidin**: `.nextflow/work`'e göz atmak için dosya gezgini veya terminali kullanın +2. **Log dosyalarını açın**: Onları doğrudan VS Code'da açmak için terminal çıktısındaki log dosyası yollarına tıklayın +3. **Çıktıları inceleyin**: Dosya gezgininde yayınlanmış sonuç dizinlerine göz atın +4. **Yürütme raporlarını görüntüleyin**: HTML raporlarını doğrudan VS Code'da veya tarayıcınızda açın + +Bu, birden fazla uygulama arasında geçiş yapmak yerine her şeyi tek bir yerde tutar. + +### Çıkarım + +Tüm geliştirme sürecinizi tek bir arayüzden yönetmek için VS Code'u versiyon kontrol ve iş akışı yürütme ile entegre edebilirsiniz. + +### Sırada ne var? + +Tüm bu IDE özelliklerinin günlük geliştirme iş akışınızda nasıl birlikte çalıştığını görün. + +--- + +## 8. Özet ve Hızlı Notlar + +Yukarıda tartışılan her bir IDE özelliği hakkında bazı hızlı notlar: + +### 8.1. Yeni Bir Özelliğe Başlama + +1. İlgili mevcut modülleri bulmak için **Hızlı dosya açma** (`Ctrl+P` veya `Cmd+P`) +2. Benzer süreçleri yan yana görüntülemek için **Bölünmüş editör** +3. Dosya yapısını anlamak için **Sembol gezinmesi** (`Ctrl+Shift+O` veya `Cmd+Shift+O`) +4. Yeni kodu hızlıca yazmak için **Otomatik tamamlama** + +### 8.2. Sorunları Giderme + +1. Tüm hataları bir kerede görmek için **Sorunlar paneli** (`Ctrl+Shift+M` veya `Cmd+Shift+M`) +2. Süreç arayüzlerini anlamak için **Tanıma git** (`Ctrl-tıklama` veya `Cmd-tıklama`) +3. Süreçlerin nasıl kullanıldığını görmek için **Tüm referansları bul** +4. Benzer kalıpları veya sorunları bulmak için **Proje genelinde arama** + +### 8.3. Yeniden Düzenleme ve İyileştirme + +1. Kalıpları bulmak için **Proje genelinde arama** (`Ctrl+Shift+F` veya `Cmd+Shift+F`) +2. Tutarlılığı korumak için **Otomatik biçimlendirme** (`Shift+Alt+F` veya `Shift+Option+F`) +3. Yapıya odaklanmak için **Kod katlama** +4. Değişiklikleri izlemek için **Git entegrasyonu** + +--- + +## Özet + +Şimdi Nextflow geliştirme için VS Code'un IDE özelliklerinin hızlı bir turunu tamamladınız. Bu araçlar sizi şu şekillerde önemli ölçüde daha üretken hale getirecektir: + +- Gerçek zamanlı sözdizimi kontrolü ile **hataları azaltma** +- Akıllı otomatik tamamlama ile **geliştirmeyi hızlandırma** +- Karmaşık çok dosyalı iş akışlarında **gezinmeyi iyileştirme** +- Tutarlı biçimlendirme ile **kaliteyi koruma** +- Gelişmiş vurgulama ve yapı görselleştirme ile **anlamayı geliştirme** + +Her şeyi hatırlamanızı beklemiyoruz, ancak şimdi bu özelliklerin var olduğunu biliyorsunuz ve ihtiyacınız olduğunda onları bulabileceksiniz. Nextflow iş akışları geliştirmeye devam ettikçe, bu IDE özellikleri doğal hale gelecek ve sözdizimi ve yapıyla boğuşmak yerine yüksek kaliteli kod yazmaya odaklanmanızı sağlayacaktır. + +### Sırada ne var? + +Bu IDE becerilerini diğer eğitim modülleri üzerinde çalışırken uygulayın, örneğin: + +- **[nf-test](nf-test.md)**: İş akışlarınız için kapsamlı test paketleri oluşturun +- **[Hello nf-core](../../hello_nf-core/)**: Topluluk standartlarıyla üretim kalitesinde boru hatları oluşturun + +Bu IDE özelliklerinin gerçek gücü, daha büyük, daha karmaşık projeler üzerinde çalışırken ortaya çıkar. Onları iş akışınıza kademeli olarak dahil etmeye başlayın—birkaç oturum içinde doğal hale gelecekler ve Nextflow geliştirmeye yaklaşım şeklinizi dönüştüreceklerdir. + +Sizi yavaşlatmadan önce hataları yakalamaktan karmaşık kod tabanlarında kolayca gezinmeye kadar, bu araçlar sizi daha özgüvenli ve verimli bir geliştirici yapacaktır. + +Mutlu kodlamalar! diff --git a/docs/tr/docs/side_quests/essential_scripting_patterns.md b/docs/tr/docs/side_quests/essential_scripting_patterns.md new file mode 100644 index 0000000000..70fcaad5de --- /dev/null +++ b/docs/tr/docs/side_quests/essential_scripting_patterns.md @@ -0,0 +1,995 @@ +# Temel Nextflow Kodlama Kalıpları + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow, Java Sanal Makinesi üzerinde çalışan bir programlama dilidir. Nextflow, [Groovy](http://groovy-lang.org/) üzerine kurulu olsa ve sözdiziminin çoğunu onunla paylaşsa da, Nextflow "uzantılı Groovy"den fazlasıdır -- tam olarak belirtilmiş bir [sözdizimi](https://nextflow.io/docs/latest/reference/syntax.html) ve [standart kütüphane](https://nextflow.io/docs/latest/reference/stdlib.html) ile bağımsız bir dildir. + +Değişkenler, map'ler ve listeler için temel sözdiziminin ötesine geçmeden çok sayıda Nextflow kodu yazabilirsiniz. Çoğu Nextflow eğitimi iş akışı düzenlemesine (kanallar, process'ler ve veri akışı) odaklanır ve sadece bununla bile şaşırtıcı derecede ileri gidebilirsiniz. + +Ancak, veri manipüle etmeniz, karmaşık dosya adlarını ayrıştırmanız, koşullu mantık uygulamanız veya sağlam üretim iş akışları oluşturmanız gerektiğinde, kodunuzun iki ayrı yönünü düşünmek yardımcı olur: **dataflow** (kanallar, operatörler, process'ler ve workflow'lar) ve **scripting** (closure'lar, fonksiyonlar ve process script'leri içindeki kod). Bu ayrım bir nebze keyfi olsa da -hepsi Nextflow kodu- ne zaman pipeline'ınızı düzenleyip ne zaman veriyi manipüle ettiğinizi anlamak için yararlı bir zihinsel model sağlar. Her ikisinde de ustalaşmak, açık ve bakımı yapılabilir iş akışları yazma yeteneğinizi önemli ölçüde artırır. + +### Öğrenme hedefleri + +Bu yan görev, sizi temel kavramlardan üretime hazır kalıplara kadar uygulamalı bir yolculuğa çıkarır. +Basit bir CSV okuyan iş akışını gerçekçi zorluklarla adım adım geliştirerek karmaşık bir biyoinformatik pipeline'a dönüştüreceğiz: + +- **Sınırları anlamak:** Dataflow işlemleri ile scripting arasında ayrım yapmak ve bunların birlikte nasıl çalıştığını anlamak +- **Veri manipülasyonu:** Güçlü operatörler kullanarak map'leri ve koleksiyonları çıkartmak, dönüştürmek ve alt kümelemek +- **String işleme:** Regex kalıpları ile karmaşık dosya adlandırma şemalarını ayrıştırmak ve değişken enterpolasyonunda ustalaşmak +- **Yeniden kullanılabilir fonksiyonlar:** Daha temiz, daha bakımı kolay iş akışları için karmaşık mantığı adlandırılmış fonksiyonlara çıkartmak +- **Dinamik mantık:** Farklı girdi türlerine uyum sağlayan process'ler oluşturmak ve dinamik kaynak tahsisi için closure'lar kullanmak +- **Koşullu yönlendirme:** Örnekleri meta veri özelliklerine göre farklı process'lerden akıllıca yönlendirmek +- **Güvenli işlemler:** Eksik verileri null-safe operatörlerle zarif bir şekilde işlemek ve girdileri açık hata mesajlarıyla doğrulamak +- **Yapılandırma tabanlı işleyiciler:** Günlükleme, bildirimler ve yaşam döngüsü yönetimi için workflow olay işleyicileri kullanmak + +### Ön koşullar + +Bu yan göreve başlamadan önce: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramları ve mekanizmalarını (process'ler, kanallar, operatörler, dosyalarla çalışma, meta veri) kullanmakta rahat olmalısınız +- Yaygın programlama yapılarına (değişkenler, map'ler, listeler) temel aşinalığınız olmalı + +Bu eğitim, karşılaştığımız programlama kavramlarını açıklayacaktır, bu nedenle kapsamlı programlama deneyimine ihtiyacınız yoktur. +Temel kavramlarla başlayıp gelişmiş kalıplara doğru ilerleyeceğiz. + +--- + +## 0. Başlayın + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md) bölümünde açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine geçin + +Bu eğitim için dosyaların bulunduğu dizine geçelim. + +```bash +cd side-quests/essential_scripting_patterns +``` + +#### Materyalleri gözden geçirin + +Ana iş akışı dosyasını ve örnek veri dosyalarını içeren bir `data` dizini bulacaksınız. + +```console title="Dizin içeriği" +. +├── collect.nf +├── data +│ ├── samples.csv +│ └── sequences +│ ├── SAMPLE_001_S1_L001_R1_001.fastq +│ ├── SAMPLE_002_S2_L001_R1_001.fastq +│ └── SAMPLE_003_S3_L001_R1_001.fastq +├── main.nf +├── modules +│ ├── fastp.nf +│ ├── generate_report.nf +│ └── trimgalore.nf +└── nextflow.config +``` + +Örnek CSV dosyamız, özelliklerine göre farklı işleme ihtiyacı olan biyolojik örnekler hakkında bilgi içerir: + +```console title="samples.csv" +sample_id,organism,tissue_type,sequencing_depth,file_path,quality_score +SAMPLE_001,human,liver,30000000,data/sequences/SAMPLE_001_S1_L001_R1_001.fastq,38.5 +SAMPLE_002,mouse,brain,25000000,data/sequences/SAMPLE_002_S2_L001_R1_001.fastq,35.2 +SAMPLE_003,human,kidney,45000000,data/sequences/SAMPLE_003_S3_L001_R1_001.fastq,42.1 +``` + +Gerçek biyoinformatik iş akışlarında karşılaşacağınız pratik programlama tekniklerini keşfetmek için bu gerçekçi veri setini kullanacağız. + +<!-- TODO: Can we make this more domain-agnostic? --> + +<!-- TODO: add an assignment statement? #### Review the assignment --> + +#### Hazırlık kontrol listesi + +Dalmaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun hedefini ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışır durumda +- [ ] Çalışma dizinini uygun şekilde ayarladım +<!-- - [ ] I understand the assignment --> + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Dataflow vs Scripting: Sınırları Anlamak + +### 1.1. Neyin Ne Olduğunu Belirleme + +Nextflow iş akışları yazarken, **dataflow** (verinin kanallar ve process'ler arasında nasıl hareket ettiği) ile **scripting** (veriyi manipüle eden ve kararlar veren kod) arasında ayrım yapmak önemlidir. Bunların birlikte nasıl çalıştığını gösteren bir iş akışı oluşturalım. + +#### 1.1.1. Temel Nextflow İş Akışı + +Sadece CSV dosyasını okuyan basit bir iş akışıyla başlayın (bunu `main.nf` dosyasında sizin için zaten yaptık): + +```groovy title="main.nf" linenums="1" +workflow { + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() +} +``` + +`workflow` bloğu pipeline yapımızı tanımlarken, `channel.fromPath()` bir dosya yolundan bir kanal oluşturur. `.splitCsv()` operatörü CSV dosyasını işler ve her satırı bir map veri yapısına dönüştürür. + +Ham CSV verilerini görmek için bu iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + Launching `main.nf` [marvelous_tuckerman] DSL2 - revision: 6113e05c17 + + [sample_id:SAMPLE_001, organism:human, tissue_type:liver, sequencing_depth:30000000, file_path:data/sequences/SAMPLE_001_S1_L001_R1_001.fastq, quality_score:38.5] + [sample_id:SAMPLE_002, organism:mouse, tissue_type:brain, sequencing_depth:25000000, file_path:data/sequences/SAMPLE_002_S2_L001_R1_001.fastq, quality_score:35.2] + [sample_id:SAMPLE_003, organism:human, tissue_type:kidney, sequencing_depth:45000000, file_path:data/sequences/SAMPLE_003_S3_L001_R1_001.fastq, quality_score:42.1] + ``` + +#### 1.1.2. Map Operatörünü Ekleme + +Şimdi veriyi dönüştürmek için scripting ekleyeceğiz, muhtemelen zaten aşina olduğunuz `.map()` operatörünü kullanarak. Bu operatör, her öğeyi dönüştürmek için kod yazabileceğimiz bir 'closure' alır. + +!!! note + + **Closure**, etrafta taşınabilen ve daha sonra çalıştırılabilen bir kod bloğudur. Bunu satır içinde tanımladığınız bir fonksiyon gibi düşünün. Closure'lar süslü parantezlerle `{ }` yazılır ve parametre alabilir. Nextflow operatörlerinin nasıl çalıştığının temelindedirler ve bir süredir Nextflow yazıyorsanız, farkında bile olmadan onları kullanıyor olabilirsiniz! + +İşte o map işlemi nasıl görünüyor: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="3-6" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="3" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .view() + ``` + +Bu bizim ilk **closure**'ımız - argüman olarak geçebileceğiniz anonim bir fonksiyon (Python'daki lambda'lara veya JavaScript'teki ok fonksiyonlarına benzer). Closure'lar Nextflow operatörleriyle çalışmak için esastır. + +`{ row -> return row }` closure'ı bir parametre alır: `row` (herhangi bir isim olabilir: `item`, `sample`, vb.). + +`.map()` operatörü her kanal öğesini işlediğinde, o öğeyi closure'ınıza geçirir. Burada `row`, her seferinde bir CSV satırını tutar. + +Bu değişikliği uygulayın ve iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +Girdinin değişmeden geri döndüğü için öncekiyle aynı çıktıyı göreceksiniz. Bu, map operatörünün doğru çalıştığını doğrular. Şimdi veriyi dönüştürmeye başlayalım. + +#### 1.1.3. Bir Map Veri Yapısı Oluşturma + +Şimdi her veri satırını dönüştürmek için closure'ımızın içinde **scripting** mantığı yazacağız. Veri akışını düzenlemek yerine bireysel veri öğelerini işlediğimiz yer burasıdır. + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="4-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Veri dönüşümü için scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="4" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + return row + } + .view() + ``` + +`sample_meta` map'i, ilgili bilgileri depolayan bir anahtar-değer veri yapısıdır (Python'daki sözlükler, JavaScript'teki nesneler veya Ruby'deki hash'ler gibi): örnek kimliği, organizma, doku tipi, dizileme derinliği ve kalite skoru. + +Verimizi temizlemek için `.toLowerCase()` ve `.replaceAll()` gibi string manipülasyon yöntemlerini, CSV'den gelen string verileri uygun sayısal türlere dönüştürmek için de `.toInteger()` ve `.toDouble()` gibi tür dönüştürme yöntemlerini kullanıyoruz. + +Bu değişikliği uygulayın ve iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1] + ``` + +#### 1.1.4. Koşullu Mantık Ekleme + +Şimdi daha fazla scripting ekleyelim - bu sefer veri değerlerine göre karar vermek için üçlü operatör kullanarak. + +Aşağıdaki değişikliği yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="11-12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="11" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + return sample_meta + } + .view() + ``` + +Üçlü operatör, `koşul ? doğruysa_değer : yanlışsa_değer` kalıbını izleyen bir if/else ifadesinin kısaltmasıdır. Bu satır şu anlama gelir: "Kalite 40'tan büyükse 'high' kullan, aksi takdirde 'normal' kullan". Kuzeni **Elvis operatörü** (`?:`), bir şey null veya boş olduğunda varsayılan değerler sağlar - bu kalıbı bu eğitimde daha sonra keşfedeceğiz. + +Map toplama operatörü `+`, mevcut olanı değiştirmek yerine **yeni bir map** oluşturur. Bu satır, `sample_meta`daki tüm anahtar-değer çiftlerini artı yeni `priority` anahtarını içeren yeni bir map oluşturur. + +!!! Note + + Closure'lara geçirilen map'leri asla değiştirmeyin - her zaman `+` kullanarak yenilerini oluşturun (örneğin). Nextflow'da, aynı veri genellikle aynı anda birden fazla işlemden geçer. Bir map'i yerinde değiştirmek, diğer işlemler aynı nesneye başvurduğunda öngörülemeyen yan etkilere neden olabilir. Yeni map'ler oluşturmak, her işlemin kendi temiz kopyasına sahip olmasını sağlar. + +Değiştirilmiş iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Meta verimizi kalite skorlarına göre bir öncelik seviyesiyle zenginleştirmek için başarıyla koşullu mantık ekledik. + +#### 1.1.5. `.subMap()` ile Map'leri Alt Kümeleme + +`+` operatörü bir map'e anahtar eklerken, bazen tersini yapmanız gerekir - sadece belirli anahtarları çıkartmak. `.subMap()` yöntemi bunun için mükemmeldir. + +Meta verimizin sadece tanımlama alanlarını içeren basitleştirilmiş bir versiyonunu oluşturmak için bir satır ekleyelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="12-15" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Veri dönüşümü için scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def id_only = sample_meta.subMap(['id', 'organism', 'tissue']) + println "Sadece ID alanları: ${id_only}" + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + // Veri dönüşümü için scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Değiştirilmiş iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [peaceful_cori] DSL2 - revision: 4cc4a8340f + + Sadece ID alanları: [id:sample_001, organism:human, tissue:liver] + Sadece ID alanları: [id:sample_002, organism:mouse, tissue:brain] + Sadece ID alanları: [id:sample_003, organism:human, tissue:kidney] + [id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal] + [id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal] + [id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high] + ``` + +Bu, hem `view()` işlemi tarafından görüntülenen tam meta veriyi hem de `println` ile yazdırdığımız çıkarılmış alt kümeyi gösterir. + +`.subMap()` yöntemi bir anahtar listesi alır ve sadece o anahtarları içeren yeni bir map döndürür. Eğer bir anahtar orijinal map'te yoksa, sonuçta yer almaz. + +Bu özellikle farklı process'ler için farklı meta veri versiyonları oluşturmanız gerektiğinde kullanışlıdır - bazıları tam meta veriye ihtiyaç duyabilirken diğerleri sadece minimal tanımlama alanlarına ihtiyaç duyar. + +Şimdi ileriye dönük ihtiyacımız olmadığı için iş akışınızı önceki durumuna döndürmek üzere o println ifadelerini kaldırın. + +!!! tip "Map İşlemleri Özeti" + + - **Anahtar ekle**: `map1 + [new_key: value]` - Ek anahtarlarla yeni map oluşturur + - **Anahtar çıkart**: `map1.subMap(['key1', 'key2'])` - Sadece belirtilen anahtarlarla yeni map oluşturur + - **Her iki işlem de yeni map'ler oluşturur** - Orijinal map'ler değişmeden kalır + +#### 1.1.6. Map'leri Birleştirme ve Sonuçları Döndürme + +Şimdiye kadar sadece Nextflow topluluğunun 'meta map' dediği şeyi döndürüyorduk ve o meta verilerin ilişkili olduğu dosyaları göz ardı ediyorduk. Ancak Nextflow iş akışları yazıyorsanız, muhtemelen o dosyalarla bir şeyler yapmak istersiniz. + +2 elementten oluşan bir tuple içeren bir kanal yapısı çıkaralım: zenginleştirilmiş meta veri map'i ve ilgili dosya yolu. Bu, Nextflow'da process'lere veri geçirmek için yaygın bir kalıptır. + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple( sample_meta + [priority: priority], file(row.file_path) ) + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="12" + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return sample_meta + [priority: priority] + } + .view() + ``` + +Bu değişikliği uygulayın ve iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Bu `[meta, file]` tuple yapısı, Nextflow'da hem meta veriyi hem de ilişkili dosyaları process'lere geçirmek için yaygın bir kalıptır. + +!!! note + + **Map'ler ve Meta Veri**: Map'ler Nextflow'da meta veriyle çalışmanın temelidir. Meta veri map'leriyle çalışmanın daha ayrıntılı açıklaması için [Meta veriyle çalışma](./metadata.md) yan görevine bakın. + +İş akışımız temel kalıbı göstermektedir: **dataflow işlemleri** (`workflow`, `channel.fromPath()`, `.splitCsv()`, `.map()`, `.view()`) verinin pipeline boyunca nasıl hareket ettiğini düzenlerken, `.map()` closure'ı içindeki **scripting** (map'ler `[key: value]`, string yöntemleri, tür dönüşümleri, üçlü operatörler) bireysel veri öğelerinin dönüşümünü ele alır. + +### 1.2. Farklı Türleri Anlamak: Channel vs List + +Şimdiye kadar çok iyi, dataflow işlemleri ile scripting arasında ayrım yapabiliyoruz. Peki ya aynı yöntem adı hem dataflow hem de scripting bağlamlarında bulunduğunda? + +Mükemmel bir örnek, Nextflow standart kütüphanesinde hem kanal türleri hem de List türleri için var olan `collect` yöntemidir. List üzerindeki `collect()` yöntemi her elementi dönüştürürken, kanal üzerindeki `collect()` operatörü tüm kanal emisyonlarını tek öğeli bir kanalda toplar. + +Bunu bazı örnek verilerle gösterelim, kanal `collect()` operatörünün ne yaptığını hatırlayarak başlayalım. `collect.nf` dosyasına bakın: + +```groovy title="collect.nf" linenums="1" +def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + +// channel.collect() - birden fazla kanal emisyonunu bir araya toplar +ch_input = channel.fromList(sample_ids) +ch_input.view { sample -> "Bireysel kanal öğesi: ${sample}" } +ch_collected = ch_input.collect() +ch_collected.view { list -> "channel.collect() sonucu: ${list} (${list.size()} öğe 1'de toplandı)" } +``` + +Adımlar: + +- Örnek kimliklerin bir listesini tanımla +- Her örnek kimliğini ayrı ayrı yayan `fromList()` ile bir kanal oluştur +- Akıştan geçerken her öğeyi `view()` ile yazdır +- Tüm öğeleri kanalın `collect()` operatörü ile tek bir listede topla +- Toplanan sonucu (tüm örnek kimliklerini içeren tek öğe) ikinci bir `view()` ile yazdır + +Kanalın yapısını değiştirdik ama verinin kendisini değiştirmedik. + +Bunu onaylamak için iş akışını çalıştırın: + +```bash +nextflow run collect.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [loving_mendel] DSL2 - revision: e8d054a46e + + Bireysel kanal öğesi: sample_001 + Bireysel kanal öğesi: sample_002 + Bireysel kanal öğesi: sample_003 + channel.collect() sonucu: [sample_001, sample_002, sample_003] (3 öğe 1'de toplandı) + ``` + +`view()` her kanal emisyonu için bir çıktı döndürür, bu yüzden bu tek çıktının 3 orijinal öğenin hepsini bir listede topladığını biliyoruz. + +Şimdi List üzerindeki `collect` yöntemini iş başında görelim. Orijinal örnek kimlik listesine List'in `collect` yöntemini uygulamak için `collect.nf` dosyasını değiştirin: + +=== "Sonra" + + ```groovy title="main.nf" linenums="1" hl_lines="9-13" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - birden fazla kanal emisyonunu bir araya toplar + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Bireysel kanal öğesi: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() sonucu: ${list} (${list.size()} öğe 1'de toplandı)" } + + // List.collect() - her elementi dönüştürür, yapıyı korur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() sonucu: ${formatted_ids} (${sample_ids.size()} öğe ${formatted_ids.size()}'e dönüştürüldü)" + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - birden fazla kanal emisyonunu bir araya toplar + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Bireysel kanal öğesi: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() sonucu: ${list} (${list.size()} öğe 1'de toplandı)" } + ``` + +Bu yeni kod parçasında: + +- Orijinal listedeki her örnek kimliğini dönüştürmek için List'in `collect` yöntemini kullanan yeni bir `formatted_ids` değişkeni tanımla +- `println` kullanarak sonucu yazdır + +Değiştirilmiş iş akışını çalıştırın: + +```bash +nextflow run collect.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cheeky_stonebraker] DSL2 - revision: 2d5039fb47 + + List.collect() sonucu: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 öğe 3'e dönüştürüldü) + Bireysel kanal öğesi: sample_001 + Bireysel kanal öğesi: sample_002 + Bireysel kanal öğesi: sample_003 + channel.collect() sonucu: [sample_001, sample_002, sample_003] (3 öğe 1'de toplandı) + ``` + +Bu sefer, bazı örnekleri dışlayan bir filtre seçtiğimiz için verinin yapısını değiştirmedik, hala listede 3 öğemiz var, ancak değiştirilmiş değerlere sahip yeni bir liste üretmek için List'in `collect` yöntemini kullanarak her öğeyi dönüştürdük. Bu, bir kanal üzerinde `map` operatörü kullanmaya benzer, ancak kanal yerine bir List veri yapısı üzerinde çalışıyor. + +`collect` burada bir nokta belirtmek için kullandığımız uç bir durumdur. Önemli ders şudur: iş akışları yazarken her zaman **veri yapıları** (Listeler, Map'ler, vb.) ile **kanallar** (dataflow yapıları) arasında ayrım yapın. İşlemler aynı adları paylaşabilir ancak üzerinde çağrıldıkları türe bağlı olarak tamamen farklı davranabilir. + +### 1.3. Yayılma Operatörü (`*.`) - Özellik Çıkarımı için Kısayol + +List'in `collect` yöntemiyle ilgili olan yayılma operatörü (`*.`), koleksiyonlardan özellikleri çıkartmanın özlü bir yolunu sağlar. Esasen yaygın bir `collect` kalıbı için sözdizimsel şekerdir. + +Bir gösterimi `collect.nf` dosyamıza ekleyelim: + +=== "Sonra" + + ```groovy title="collect.nf" linenums="1" hl_lines="15-18" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - birden fazla kanal emisyonunu bir araya toplar + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Bireysel kanal öğesi: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() sonucu: ${list} (${list.size()} öğe 1'de toplandı)" } + + // List.collect() - her elementi dönüştürür, yapıyı korur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() sonucu: ${formatted_ids} (${sample_ids.size()} öğe ${formatted_ids.size()}'e dönüştürüldü)" + + // Yayılma operatörü - özlü özellik erişimi + def sample_data = [[id: 's1', quality: 38.5], [id: 's2', quality: 42.1], [id: 's3', quality: 35.2]] + def all_ids = sample_data*.id + println "Yayılma operatörü sonucu: ${all_ids}" + ``` + +=== "Önce" + + ```groovy title="collect.nf" linenums="1" + def sample_ids = ['sample_001', 'sample_002', 'sample_003'] + + // channel.collect() - birden fazla kanal emisyonunu bir araya toplar + ch_input = channel.fromList(sample_ids) + ch_input.view { sample -> "Bireysel kanal öğesi: ${sample}" } + ch_collected = ch_input.collect() + ch_collected.view { list -> "channel.collect() sonucu: ${list} (${list.size()} öğe 1'de toplandı)" } + + // List.collect() - her elementi dönüştürür, yapıyı korur + def formatted_ids = sample_ids.collect { id -> + id.toUpperCase().replace('SAMPLE_', 'SPECIMEN_') + } + println "List.collect() sonucu: ${formatted_ids} (${sample_ids.size()} öğe ${formatted_ids.size()}'e dönüştürüldü)" + ``` + +Güncellenmiş iş akışını çalıştırın: + +```bash title="Yayılma operatörünü test et" +nextflow run collect.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="6" + N E X T F L O W ~ version 25.10.2 + + Launching `collect.nf` [cranky_galileo] DSL2 - revision: 5f3c8b2a91 + + List.collect() sonucu: [SPECIMEN_001, SPECIMEN_002, SPECIMEN_003] (3 öğe 3'e dönüştürüldü) + Yayılma operatörü sonucu: [s1, s2, s3] + Bireysel kanal öğesi: sample_001 + Bireysel kanal öğesi: sample_002 + Bireysel kanal öğesi: sample_003 + channel.collect() sonucu: [sample_001, sample_002, sample_003] (3 öğe 1'de toplandı) + ``` + +Yayılma operatörü `*.`, yaygın bir collect kalıbı için kısayoldur: + +```groovy +// Bunlar eşdeğerdir: +def ids = samples*.id +def ids = samples.collect { it.id } + +// Yöntem çağrılarıyla da çalışır: +def names = files*.getName() +def names = files.collect { it.getName() } +``` + +Yayılma operatörü, özellikle bir nesne listesinden tek bir özelliği çıkartmanız gerektiğinde kullanışlıdır - tam `collect` closure'ını yazmaktan daha okunabilirdir. + +!!! tip "Yayılma vs Collect Ne Zaman Kullanılır" + + - **Yayılma (`*.`) kullan** basit özellik erişimi için: `samples*.id`, `files*.name` + - **Collect kullan** dönüşümler veya karmaşık mantık için: `samples.collect { it.id.toUpperCase() }`, `samples.collect { [it.id, it.quality > 40] }` + +### Çıkarımlar + +Bu bölümde şunları öğrendiniz: + +- **Dataflow vs scripting**: Kanal operatörleri verinin pipeline'ınız boyunca nasıl aktığını düzenlerken, scripting bireysel veri öğelerini dönüştürür +- **Türleri anlamak**: Aynı yöntem adı (örneğin `collect`) üzerinde çağrıldığı türe bağlı olarak farklı davranabilir (Channel vs List) +- **Bağlam önemlidir**: Kanallarla mı (dataflow) yoksa veri yapılarıyla mı (scripting) çalıştığınızın her zaman farkında olun + +Bu sınırları anlamak hata ayıklama, dokümantasyon ve bakımı yapılabilir iş akışları yazmak için esastır. + +Sonrasında, gerçek dünya verileriyle başa çıkmak için gerekli olan string işleme yeteneklerine daha derinlemesine dalacağız. + +--- + +## 2. String İşleme ve Dinamik Script Oluşturma + +String işlemede ustalaşmak, kırılgan iş akışlarını sağlam pipeline'lardan ayırır. Bu bölüm karmaşık dosya adlarını ayrıştırmayı, dinamik script oluşturmayı ve değişken enterpolasyonunu kapsar. + +### 2.1. Kalıp Eşleme ve Düzenli İfadeler + +Biyoinformatik dosyaları genellikle meta veri kodlayan karmaşık adlandırma kurallarına sahiptir. Bunları düzenli ifadelerle kalıp eşleme kullanarak otomatik olarak çıkaralım. + +`main.nf` iş akışımıza geri döneceğiz ve dosya adlarından ek örnek bilgilerini çıkartmak için bazı kalıp eşleme mantığı ekleyeceğiz. Veri setimizdeki FASTQ dosyaları `SAMPLE_001_S1_L001_R1_001.fastq.gz` gibi isimlerle Illumina tarzı adlandırma kurallarını takip eder. Bunlar gizemli görünebilir, ancak aslında örnek kimliği, şerit numarası ve okuma yönü gibi yararlı meta verileri kodlarlar. Bu isimleri ayrıştırmak için regex yeteneklerini kullanacağız. + +Mevcut `main.nf` iş akışınıza aşağıdaki değişikliği yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="4" hl_lines="10-21" + .map { row -> + // Veri dönüşümü için scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="4" hl_lines="10-11" + .map { row -> + // Veri dönüşümü için scripting + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + [priority: priority], file(row.file_path)) + } + ``` + +Bu, anahtar **string işleme kavramlarını** gösterir: + +1. **Düzenli ifade değişmezleri** `~/pattern/` sözdizimi kullanarak - bu ters eğik çizgileri kaçırmaya gerek kalmadan bir regex kalıbı oluşturur +2. **Kalıp eşleme** `=~` operatörü ile - bu bir string'i bir regex kalıbıyla eşleştirmeye çalışır +3. **Eşleştirici nesneler** `[0][1]`, `[0][2]`, vb. ile grupları yakalar - `[0]` tüm eşleşmeyi ifade eder, `[1]`, `[2]`, vb. parantez içindeki yakalanan gruplara işaret eder + +Regex kalıbını `^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$` parçalayalım: + +| Kalıp | Eşleşir | Yakalar | +| ------------------- | ---------------------------------------- | --------------------------------- | +| `^(.+)` | Başlangıçtan örnek adı | Grup 1: örnek adı | +| `_S(\d+)` | Örnek numarası `_S1`, `_S2`, vb. | Grup 2: örnek numarası | +| `_L(\d{3})` | Şerit numarası `_L001` | Grup 3: şerit (3 basamak) | +| `_(R[12])` | Okuma yönü `_R1` veya `_R2` | Grup 4: okuma yönü | +| `_(\d{3})` | Parça numarası `_001` | Grup 5: parça (3 basamak) | +| `\.fastq(?:\.gz)?$` | Dosya uzantısı `.fastq` veya `.fastq.gz` | Yakalanmadı (?: yakalamama grubu) | + +Bu, meta verileri otomatik olarak çıkartmak için Illumina tarzı adlandırma kurallarını ayrıştırır. + +Değiştirilmiş iş akışını çalıştırın: + +```bash title="Kalıp eşlemeyi test et" +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [clever_pauling] DSL2 - revision: 605d2058b4 + + [[id:sample_001, organism:human, tissue:liver, depth:30000000, quality:38.5, sample_num:1, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_001_S1_L001_R1_001.fastq] + [[id:sample_002, organism:mouse, tissue:brain, depth:25000000, quality:35.2, sample_num:2, lane:001, read:R1, chunk:001, priority:normal], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_002_S2_L001_R1_001.fastq] + [[id:sample_003, organism:human, tissue:kidney, depth:45000000, quality:42.1, sample_num:3, lane:001, read:R1, chunk:001, priority:high], /workspaces/training/side-quests/essential_scripting_patterns/data/sequences/SAMPLE_003_S3_L001_R1_001.fastq] + ``` + +Bu, dosya adlarından zenginleştirilmiş meta verileri gösterir. + +### 2.2. Process'lerde Dinamik Script Oluşturma + +Process script blokları esasen shell'e geçirilen çok satırlı string'lerdir. Girdi özelliklerine göre dinamik olarak farklı script string'leri oluşturmak için **koşullu mantık** (if/else, üçlü operatörler) kullanabilirsiniz. Bu, process tanımlarını çoğaltmadan tek uçlu ve çift uçlu dizileme okumaları gibi çeşitli girdi türlerini işlemek için esastır. + +Bu kalıbı gösteren iş akışımıza bir process ekleyelim. `modules/fastp.nf` dosyasını açın ve bakın: + +```groovy title="modules/fastp.nf" linenums="1" +process FASTP { + container 'community.wave.seqera.io/library/fastp:0.24.0--62c97b06e8447690' + + input: + tuple val(meta), path(reads) + + output: + tuple val(meta), path("*_trimmed*.fastq.gz"), emit: reads + + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ +} +``` + +Process girdi olarak FASTQ dosyaları alır ve adaptörleri kesmek ve düşük kaliteli okumaları filtrelemek için `fastp` aracını çalıştırır. Ne yazık ki, bu process'i yazan kişi örnek veri setimizde sahip olduğumuz tek uçlu okumalara izin vermemiş. Bunu iş akışımıza ekleyelim ve ne olduğunu görelim: + +İlk olarak, `main.nf` iş akışınızın en ilk satırına modülü dahil edin: + +```groovy title="main.nf" linenums="1" +include { FASTP } from './modules/fastp.nf' +``` + +Sonra `ch_samples` kanalını `FASTP` process'ine bağlamak için `workflow` bloğunu değiştirin: + +=== "Sonra" + + ```groovy title="main.nf" linenums="25" hl_lines="27" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return tuple(sample_meta + file_meta + [priority: priority], fastq_path) + } + + ch_fastp = FASTP(ch_samples) + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="25" hl_lines="26" + workflow { + + ch_samples = channel.fromPath("./data/samples.csv") + .splitCsv(header: true) + .map { row -> + def sample_meta = [ + id: row.sample_id.toLowerCase(), + organism: row.organism, + tissue: row.tissue_type.replaceAll('_', ' ').toLowerCase(), + depth: row.sequencing_depth.toInteger(), + quality: row.quality_score.toDouble() + ] + def fastq_path = file(row.file_path) + + def m = (fastq_path.name =~ /^(.+)_S(\d+)_L(\d{3})_(R[12])_(\d{3})\.fastq(?:\.gz)?$/) + def file_meta = m ? [ + sample_num: m[0][2].toInteger(), + lane: m[0][3], + read: m[0][4], + chunk: m[0][5] + ] : [:] + + def priority = sample_meta.quality > 40 ? 'high' : 'normal' + return [sample_meta + file_meta + [priority: priority], file(row.file_path)] + } + .view() + } + ``` + +Bu değiştirilmiş iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? failure "Komut çıktısı" + + ```console + ERROR ~ Error executing process > 'FASTP (3)' + + Caused by: + Process `FASTP (3)` terminated with an error exit status (255) + + + Command executed: + + fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --in2 null \ + --out1 sample_003_trimmed_R1.fastq.gz \ + --out2 sample_003_trimmed_R2.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 + + Command exit status: + 255 + + Command output: + (empty) + ``` + +Process'in ikinci girdi dosyası için `null` değeriyle `fastp` çalıştırmaya çalıştığını görebilirsiniz, bu da başarısız olmasına neden oluyor. Bunun nedeni, veri setimizin tek uçlu okumalar içermesi, ancak process'in çift uçlu okumaları (bir seferde iki girdi dosyası) bekleyecek şekilde sabit kodlanmış olmasıdır. + +Bunu, `FASTP` process'inin `script:` bloğuna koşullu mantık ekleyerek düzeltin. Bir if/else ifadesi okuma dosya sayısını kontrol eder ve komutu buna göre ayarlar. + +=== "Sonra" + + ```groovy title="main.nf" linenums="10" hl_lines="3-27" + script: + // Basit tek uçlu vs çift uçlu tespit + def is_single = reads instanceof List ? reads.size() == 1 : true + + if (is_single) { + def input_file = reads instanceof List ? reads[0] : reads + """ + fastp \\ + --in1 ${input_file} \\ + --out1 ${meta.id}_trimmed.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } else { + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="10" hl_lines="2-11" + script: + """ + fastp \\ + --in1 ${reads[0]} \\ + --in2 ${reads[1]} \\ + --out1 ${meta.id}_trimmed_R1.fastq.gz \\ + --out2 ${meta.id}_trimmed_R2.fastq.gz \\ + --json ${meta.id}.fastp.json \\ + --html ${meta.id}.fastp.html \\ + --thread $task.cpus + """ + } + ``` + +Şimdi iş akışı hem tek uçlu hem de çift uçlu okumaları zarif bir şekilde işleyebilir. Koşullu mantık girdi dosya sayısını kontrol eder ve `fastp` için uygun komutu oluşturur. Çalışıp çalışmadığını görelim: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [adoring_rosalind] DSL2 - revision: 04b1cd93e9 + + executor > local (3) + [31/a8ad4d] process > FASTP (3) [100%] 3 of 3 ✔ + ``` + +İyi görünüyor! Gerçekten çalıştırılan komutları kontrol edersek (görev hash'inizi özelleştirin): + +```console title="Çalıştırılan komutları kontrol et" +cat work/31/a8ad4d95749e685a6d842d3007957f/.command.sh +``` + +Nextflow'un tek uçlu okumalar için doğru komutu seçtiğini görebiliriz: + +```bash title=".command.sh" +#!/bin/bash -ue +fastp \ + --in1 SAMPLE_003_S3_L001_R1_001.fastq \ + --out1 sample_003_trimmed.fastq.gz \ + --json sample_003.fastp.json \ + --html sample_003.fastp.html \ + --thread 2 +``` + +Dinamik script mantığının bir başka yaygın kullanımı [Bilim için Nextflow Genomik modülünde](../../nf4science/genomics/02_joint_calling) görülebilir. O modülde, çağrılan GATK process'i birden fazla girdi dosyası alabilir, ancak her birinin doğru bir komut satırı oluşturmak için `-V` ile öneklenmesi gerekir. Process, bir girdi dosyaları koleksiyonunu (`all_gvcfs`) doğru komut argümanlarına dönüştürmek için scripting kullanır: + +```groovy title="GATK için komut satırı manipülasyonu" linenums="1" hl_lines="2 5" + script: + def gvcfs_line = all_gvcfs.collect { gvcf -> "-V ${gvcf}" }.join(' ') + """ + gatk GenomicsDBImport \ + ${gvcfs_line} \ + -L ${interval_list} \ + --genomicsdb-workspace-path ${cohort_name}_gdb + """ +``` + +Process script bloklarında scripting kullanmanın bu kalıpları son derece güçlüdür ve birçok senaryoda uygulanabilir - değişken girdi türlerini işlemekten dosya koleksiyonlarından karmaşık komut satırı argü diff --git a/docs/tr/docs/side_quests/ideas/containers.md b/docs/tr/docs/side_quests/ideas/containers.md new file mode 100644 index 0000000000..733e03dc52 --- /dev/null +++ b/docs/tr/docs/side_quests/ideas/containers.md @@ -0,0 +1,191 @@ +# Bölüm 1: Daha Fazla Konteyner + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[YAPILACAK] + +--- + +## 1. Konteyner imajlarını nasıl bulabilir veya oluşturabilirsiniz + +Bazı yazılım geliştiricileri, yazılımları için Docker Hub gibi konteyner kayıt defterlerinde mevcut olan konteyner imajları sağlar, ancak birçoğu sağlamaz. +Bu isteğe bağlı bölümde, Nextflow pipeline'larınızda kullanmak istediğiniz araçlar için konteyner imajı elde etmenin iki yolunu göstereceğiz: Seqera Containers'ı kullanmak ve konteyner imajını kendiniz oluşturmak. + +Bu bölümün sonundaki alıştırmada kullanılacak olan `quote` pip paketi için bir konteyner imajı elde edecek/oluşturacaksınız. + +### 1.1. Seqera Containers'dan konteyner imajı alın + +Seqera Containers, pip ve conda (bioconda dahil) ile yüklenebilen araçlar için konteyner imajları oluşturan ücretsiz bir hizmettir. +[Seqera Containers](https://www.seqera.io/containers/) sitesine gidin ve `quote` pip paketini arayın. + +![Seqera Containers](img/seqera-containers-1.png) + +`quote` pip paketi için bir konteyner imajı talep etmek üzere "+Add" ve ardından "Get Container" düğmesine tıklayın. + +![Seqera Containers](img/seqera-containers-2.png) + +Paketin bu sürümü için bir topluluk konteyneri ilk kez oluşturuluyorsa, tamamlanması birkaç dakika sürebilir. +Sizin için oluşturulan konteyner imajının URI'sini (örneğin `community.wave.seqera.io/library/pip_quote:ae07804021465ee9`) kopyalamak için tıklayın. + +Artık konteyner imajını kullanarak `quote` komutunu çalıştırabilir ve Grace Hopper'dan rastgele bir söz alabilirsiniz. + +```bash +docker run --rm community.wave.seqera.io/library/pip_quote:ae07804021465ee9 quote "Grace Hopper" +``` + +Çıktı: + +```console title="Çıktı" +Humans are allergic to change. They love to say, 'We've always done it +this way.' I try to fight that. That's why I have a clock on my wall +that runs counter-clockwise. +``` + +### 1.2. Konteyner imajını kendiniz oluşturun + +Seqera Containers web sitesindeki bazı derleme ayrıntılarını kullanarak `quote` pip paketi için konteyner imajını kendimiz oluşturalım. +Seqera Containers web sitesine dönün ve "Build Details" düğmesine tıklayın. + +Bakacağımız ilk öğe, konteyner imajını oluşturmak için gereken tüm komutları içeren bir tür betik dosyası olan `Dockerfile`'dır. +Her bir bölümün ne yaptığını anlamanıza yardımcı olmak için aşağıdaki Dockerfile'a bazı açıklayıcı yorumlar ekledik. + +```Dockerfile title="Dockerfile" +# Micromamba temel docker imajından başla +FROM mambaorg/micromamba:1.5.10-noble +# conda.yml dosyasını konteynere kopyala +COPY --chown=$MAMBA_USER:$MAMBA_USER conda.yml /tmp/conda.yml +# Nextflow'un kullanması için çeşitli yardımcı programları ve conda.yml dosyasındaki paketleri yükle +RUN micromamba install -y -n base -f /tmp/conda.yml \ + && micromamba install -y -n base conda-forge::procps-ng \ + && micromamba env export --name base --explicit > environment.lock \ + && echo ">> CONDA_LOCK_START" \ + && cat environment.lock \ + && echo "<< CONDA_LOCK_END" \ + && micromamba clean -a -y +# Konteyneri root kullanıcısı olarak çalıştır +USER root +# PATH ortam değişkenini micromamba kurulum dizinini içerecek şekilde ayarla +ENV PATH="$MAMBA_ROOT_PREFIX/bin:$PATH" +``` + +Bakacağımız ikinci öğe, konteyner imajına yüklenmesi gereken paketlerin listesini içeren `conda.yml` dosyasıdır. + +```conda.yml title="conda.yml" +channels: +- conda-forge +- bioconda +dependencies: +- pip +- pip: + - quote==3.0.0 # +``` + +Bu dosyaların içeriğini `containers/build` dizininde bulunan taslakların içine kopyalayın, ardından konteyner imajını kendiniz oluşturmak için aşağıdaki komutu çalıştırın. + +!!! note "Not" + + Konteyner imajını `quote` adı ve `latest` etiketi ile etiketlemek için `-t quote:latest` bayrağını kullanıyoruz. + Bu sistemi çalıştırırken konteyner imajına atıfta bulunmak için bu etiketi kullanabileceğiz. + +```bash +docker build -t quote:latest containers/build +``` + +Oluşturma işlemi tamamlandıktan sonra, az önce oluşturduğunuz konteyner imajını çalıştırabilirsiniz. + +```bash +docker run --rm quote:latest quote "Margaret Oakley Dayhoff" +``` + +### Önemli Noktalar + +Nextflow pipeline'larınızda kullanmak istediğiniz bir araç için konteyner imajı almanın iki farklı yolunu öğrendiniz: Seqera Containers'ı kullanmak ve konteyner imajını kendiniz oluşturmak. + +### Sırada ne var? + +Bu eğitim serisinin [sonraki bölümüne](./04_hello_genomics.md) devam etmek için ihtiyacınız olan her şeye sahipsiniz. +Ayrıca `quote` konteynerini kullanarak bilgisayar/biyoloji öncüleri hakkında alıntılar almak ve bunları `cowsay` konteynerini kullanarak görüntülemek için isteğe bağlı bir alıştırmayla devam edebilirsiniz. + +--- + +## 2. İneği ünlü bilim insanlarından alıntı yaptırın + +Bu bölüm, şimdiye kadar öğrendiklerinizi pratik yapmak için bazı ek alıştırmalar içerir. +Bu alıştırmaları yapmak, eğitimin sonraki bölümlerini anlamak için _gerekli değildir_, ancak ineği ünlü bilim insanlarından alıntı yaptırmayı nasıl yapacağınızı çözerek öğrendiklerinizi pekiştirmenin eğlenceli bir yolunu sağlar. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 2.1. getQuote process kullanmak için `hello-containers.nf` betiğini değiştirin + +`containers/data/pioneers.csv` dosyasında bilgisayar ve biyoloji öncülerinin bir listesi var. +Üst düzeyde, bu alıştırmayı tamamlamak için şunları yapmanız gerekecek: + +- Varsayılan `params.input_file` parametresini `pioneers.csv` dosyasını işaret edecek şekilde değiştirin. +- Her girdi için bir alıntı almak üzere `quote` konteynerini kullanan bir `getQuote` process oluşturun. +- Alıntıyı görüntülemek için `getQuote` process'inin çıktısını `cowsay` process'ine bağlayın. + +`quote` konteyner imajı için, önceki ek alıştırmada kendiniz oluşturduğunuz imajı veya Seqera Containers'dan aldığınız imajı kullanabilirsiniz. + +!!! tip "İpucu" + + getQuote process'inizin `script` bloğu için iyi bir seçenek şu olabilir: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Bu alıştırmanın çözümünü `containers/solutions/hello-containers-4.1.nf` dosyasında bulabilirsiniz. + +### 2.2. Nextflow pipeline'ınızı `quote` ve `sayHello` modlarında çalışabilecek şekilde değiştirin + +Pipeline'ınıza hem `quote` hem de `sayHello` için tasarlanmış girdileri kabul etmesine izin verecek bazı dallanma mantığı ekleyin. +İşte bir Nextflow workflow'unda `if` ifadesinin nasıl kullanılacağına dair bir örnek: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! tip "İpucu" + + Bir process'in çıktı kanalına bir ad atamak için `new_ch = processName.out` kullanabilirsiniz. + +Bu alıştırmanın çözümünü `containers/solutions/hello-containers-4.2.nf` dosyasında bulabilirsiniz. + +### Önemli Noktalar + +Nextflow'da process'leri çalıştırmak için konteynerleri nasıl kullanacağınızı ve pipeline'larınıza bazı dallanma mantığını nasıl ekleyeceğinizi biliyorsunuz! + +### Sırada ne var? + +Kutlama yapın, bir germe molası verin ve biraz su için! + +Hazır olduğunuzda, şimdiye kadar öğrendiklerinizi daha gerçekçi bir veri analizi kullanım durumuna nasıl uygulayacağınızı öğrenmek için bu eğitim serisinin Bölüm 3'üne geçin. diff --git a/docs/tr/docs/side_quests/ideas/if_else.md b/docs/tr/docs/side_quests/ideas/if_else.md new file mode 100644 index 0000000000..b8509b0be7 --- /dev/null +++ b/docs/tr/docs/side_quests/ideas/if_else.md @@ -0,0 +1,89 @@ +# Bölüm 2: If - Else + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +[TODO] + +--- + +## 1. İneğe ünlü bilim insanlarından alıntılar yaptırın + +Bu bölüm, şimdiye kadar öğrendiklerinizi pratik yapmak için bazı ek alıştırmalar içermektedir. +Bu alıştırmaları yapmak, eğitimin sonraki bölümlerini anlamak için _gerekli değildir_, ancak ineğe ünlü bilim insanlarından alıntılar yaptırmayı çözerek öğrendiklerinizi pekiştirmenin eğlenceli bir yolunu sunar. + +```console title="cowsay-output-Grace-Hopper.txt" + _________________________________________________ + / \ +| Humans are allergic to change. They love to | +| say, 'We've always done it this way.' I try to fi | +| ght that. That's why I have a clock on my wall th | +| at runs counter-clockwise. | +| -Grace Hopper | + \ / + ================================================= + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +### 1.1. `hello-containers.nf` betiğini getQuote süreci kullanacak şekilde değiştirin + +`containers/data/pioneers.csv` dosyasında bilgisayar ve biyoloji öncülerinin bir listesi bulunmaktadır. +Üst düzeyde, bu alıştırmayı tamamlamak için şunları yapmanız gerekecektir: + +- Varsayılan `params.input_file` parametresini `pioneers.csv` dosyasına işaret edecek şekilde değiştirin. +- Her girdi için bir alıntı almak üzere `quote` konteynerini kullanan bir `getQuote` süreci oluşturun. +- `getQuote` sürecinin çıktısını, alıntıyı görüntülemek için `cowsay` sürecine bağlayın. + +`quote` konteyner imajı için, önceki ek alıştırmada kendiniz oluşturduğunuz imajı ya da Seqera Containers'dan aldığınız imajı kullanabilirsiniz. + +!!! Hint "İpucu" + + getQuote sürecinizin `script` bloğu için iyi bir seçenek şu olabilir: + ```groovy + script: + def safe_author = author.tokenize(' ').join('-') + """ + quote "$author" > quote-${safe_author}.txt + echo "-${author}" >> quote-${safe_author}.txt + """ + ``` + +Bu alıştırmanın çözümünü `containers/solutions/hello-containers-4.1.nf` dosyasında bulabilirsiniz. + +### 1.2. Nextflow pipeline'ınızı `quote` ve `sayHello` modlarında çalışacak şekilde değiştirin. + +Pipeline'ınıza hem `quote` hem de `sayHello` için tasarlanmış girdileri kabul edebilmesi için dallanma mantığı ekleyin. +İşte bir Nextflow workflow'unda `if` ifadesinin nasıl kullanılacağına dair bir örnek: + +```groovy title="hello-containers.nf" +workflow { + if (params.quote) { + ... + } + else { + ... + } + cowSay(text_ch) +} +``` + +!!! Hint "İpucu" + + Bir sürecin çıktı kanalına bir isim atamak için `new_ch = processName.out` kullanabilirsiniz. + +Bu alıştırmanın çözümünü `containers/solutions/hello-containers-4.2.nf` dosyasında bulabilirsiniz. + +### Çıkarımlar + +Nextflow'da süreçleri çalıştırmak için konteynerlerin nasıl kullanılacağını ve pipeline'larınıza bazı dallanma mantıkları oluşturmayı öğrendiniz! + +### Sırada ne var? + +Kendinizi kutlayın, bir mola verin ve biraz su için! + +Hazır olduğunuzda, şimdiye kadar öğrendiklerinizi daha gerçekçi bir veri analizi kullanım durumuna nasıl uygulayacağınızı öğrenmek için bu eğitim serisinin 3. Bölümüne geçin. diff --git a/docs/tr/docs/side_quests/index.md b/docs/tr/docs/side_quests/index.md new file mode 100644 index 0000000000..f50705cd23 --- /dev/null +++ b/docs/tr/docs/side_quests/index.md @@ -0,0 +1,44 @@ +--- +title: Yan Görevler +hide: + - toc +--- + +# Yan Görevler + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu, belirli konuları daha derinlemesine ele alan bağımsız eğitim mini kurslarının bir koleksiyonudur. Bunları istediğiniz sırada tamamlayabilirsiniz. + +Hadi başlayalım! Eğitim ortamını başlatmak için aşağıdaki "GitHub Codespaces'te Aç" düğmesine tıklayın (tercihen ayrı bir sekmede), ardından yüklenirken okumaya devam edin. + +[![GitHub Codespaces'te Aç](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +## Ön Koşullar + +Her mini kursun özel ön koşulları farklılık gösterir ve ilgili sayfalarda belgelenmiştir. +Bununla birlikte, hepsi aşağıdakilerle ilgili minimal bir aşinalık varsayar: + +- Komut satırı deneyimi +- [Hello Nextflow](../../hello_nextflow/) başlangıç eğitim kursunda ele alınan temel Nextflow kavramları ve araçları. + +Teknik gereksinimler ve ortam kurulumu için [Ortam Kurulumu](../../envsetup/) mini kursuna bakın. + +**Yan Görevlere ilk kez dalıyorsanız, önce [Oryantasyon](./orientation.md) sayfasına göz atmayı unutmayın!** + +Aksi takdirde, aşağıdaki tablodan bir yan görev seçin. + +## Yan Görevler + +| Yan Görev | Öğretim için Tahmini Süre | +| ------------------------------------------------------------------- | ------------------------- | +| [Nextflow geliştirme ortamı açıklaması](./ide_features.md) | 45 dakika | +| [Temel Nextflow Betik Kalıpları](./essential_scripting_patterns.md) | 90 dakika | +| [İş akışlarında üst veri](./metadata.md) | 45 dakika | +| [Bölme ve Gruplama](./splitting_and_grouping.md) | 45 dakika | +| [nf-test ile Test Etme](./nf-test.md) | 1 saat | +| [İş akışlarının iş akışları](./workflows_of_workflows.md) | 30 dakika | +| [Dosyalarla çalışma](./working_with_files.md) | 45 dakika | +| [İş akışlarında hata ayıklama](./debugging.md) | 1 saat | + +Burada hangi diğer alanların ve kullanım durumlarının ele alınmasını istediğinizi topluluk forumunun [Eğitim bölümünde](https://community.seqera.io/c/training/) paylaşarak bize bildirin. diff --git a/docs/tr/docs/side_quests/metadata.md b/docs/tr/docs/side_quests/metadata.md new file mode 100644 index 0000000000..e39f2a4c92 --- /dev/null +++ b/docs/tr/docs/side_quests/metadata.md @@ -0,0 +1,1101 @@ +# Metadata ve meta map'ler + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Herhangi bir bilimsel analizde, sadece ham veri dosyalarıyla çalışmayız. +Her dosya kendi ek bilgileriyle birlikte gelir: ne olduğu, nereden geldiği ve onu özel kılan nedir. +Bu ek bilgilere metadata (üst veri) diyoruz. + +Metadata, diğer verileri tanımlayan veridir. +Metadata, dosyalar ve deneysel koşullar hakkındaki önemli ayrıntıları takip eder ve analizlerin her veri setinin benzersiz özelliklerine göre uyarlanmasına yardımcı olur. + +Bunu bir kütüphane kataloğu gibi düşünün: kitaplar gerçek içeriği (ham veri) içerirken, katalog kartları her kitap hakkında temel bilgiler sağlar—ne zaman yayınlandığı, kimin yazdığı, nerede bulunacağı (metadata). +Nextflow pipeline'larında metadata şunlar için kullanılabilir: + +- Dosyaya özgü bilgileri workflow boyunca takip etmek +- Dosya özelliklerine göre process'leri yapılandırmak +- İlgili dosyaları ortak analiz için gruplamak + +### Öğrenme hedefleri + +Bu yan görevde, workflow'larda metadata'nın nasıl ele alınacağını keşfedeceğiz. +Temel dosya bilgilerini içeren basit bir veri tablosundan (biyoinformatikte genellikle samplesheet olarak adlandırılır) başlayarak, şunları öğreneceksiniz: + +- CSV dosyalarından dosya metadata'sını okuma ve ayrıştırma +- Metadata map'lerini oluşturma ve manipüle etme +- Workflow yürütme sırasında yeni metadata alanları ekleme +- Process davranışını özelleştirmek için metadata kullanma + +Bu beceriler, karmaşık dosya ilişkilerini ve işleme gereksinimlerini işleyebilen daha sağlam ve esnek pipeline'lar oluşturmanıza yardımcı olacaktır. + +### Ön koşullar + +Bu yan göreve başlamadan önce: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramlarını ve mekanizmalarını (process'ler, channel'lar, operatörler) rahatça kullanabiliyor olmalısınız + +--- + +## 0. Başlangıç + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md) bölümünde açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![GitHub Codespaces'te Aç](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine gidin + +Bu eğitimin dosyalarının bulunduğu dizine geçelim. + +```bash +cd side-quests/metadata +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri inceleyin + +Bir ana workflow dosyası ve bir veri tablosu ile birkaç veri dosyası içeren bir `data` dizini bulacaksınız. + +??? abstract "Dizin içeriği" + + ```console + . + ├── data + │ ├── bonjour.txt + │ ├── ciao.txt + │ ├── guten_tag.txt + │ ├── hallo.txt + │ ├── hello.txt + │ ├── hola.txt + │ ├── salut.txt + │ └── datasheet.csv + ├── main.nf + └── nextflow.config + ``` + +`main.nf` dosyasındaki workflow, kademeli olarak tam işlevli bir workflow'a genişleteceğiniz bir taslaktır. + +Veri tablosu, veri dosyalarına giden yolları ve ilişkili bazı metadata'yı 3 sütunda düzenlenmiş şekilde listeler: + +- `id`: açıklayıcı, dosyaya verilen bir ID +- `character`: bir karakter adı, daha sonra farklı yaratıklar çizmek için kullanacağız +- `data`: farklı dillerde selamlaşmalar içeren `.txt` dosyalarının yolları + +```console title="datasheet.csv" +id,character,recording +sampleA,squirrel,/workspaces/training/side-quests/metadata/data/bonjour.txt +sampleB,tux,/workspaces/training/side-quests/metadata/data/guten_tag.txt +sampleC,sheep,/workspaces/training/side-quests/metadata/data/hallo.txt +sampleD,turkey,/workspaces/training/side-quests/metadata/data/hello.txt +sampleE,stegosaurus,/workspaces/training/side-quests/metadata/data/hola.txt +sampleF,moose,/workspaces/training/side-quests/metadata/data/salut.txt +sampleG,turtle,/workspaces/training/side-quests/metadata/data/ciao.txt +``` + +Her veri dosyası, beş dilden birinde (fr: Fransızca, de: Almanca, es: İspanyolca, it: İtalyanca, en: İngilizce) selamlaşma metni içerir. + +Ayrıca size `langid` adında konteynerleştirilmiş bir dil analiz aracı sağlayacağız. + +#### Görevi inceleyin + +Meydan okumanız, şunları yapacak bir Nextflow workflow'u yazmaktır: + +1. Her dosyadaki dili otomatik olarak **Tanımlama** +2. Dosyaları dil ailesine göre **Gruplama** (Cermen dilleri vs Roman dilleri) +3. Her dosya için dilini ve metadata'sına göre işlemeyi **Özelleştirme** +4. Çıktıları dil grubuna göre **Organize etme** + +Bu, dosyaya özgü metadata'nın işleme kararlarını yönlendirdiği tipik bir workflow modelini temsil eder; tam olarak metadata map'lerinin zarif bir şekilde çözdüğü sorun türü. + +#### Hazırlık kontrol listesi + +Dalmaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışır durumda +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] Görevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Bir veri tablosundan metadata yükleme + +Başlangıç noktası olarak size verdiğimiz workflow taslağını incelemek için `main.nf` workflow dosyasını açın. + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + +} +``` + +Örnek veri tablosunu bir dosya olarak yüklemek için temel bir channel factory kurduğumuzu görebilirsiniz, ancak bu henüz dosyanın içeriğini okumayacaktır. +Bunu ekleyerek başlayalım. + +### 1.1. `splitCsv` ile içeriği okuma + +Dosya içeriğini minimal çabayla uygun şekilde ayrıştıracak bir operatör seçmemiz gerekiyor. +Veri tablomuz CSV formatında olduğundan, bu iş [`splitCsv`](https://www.nextflow.io/docs/latest/reference/operator.html#splitcsv) operatörü içindir, bu operatör dosyadaki her satırı channel'da bir öğe olarak yükler. + +Channel oluşturma koduna bir `splitCsv()` işlemi eklemek için aşağıdaki değişiklikleri yapın, artı dosyanın içeriğinin channel'a doğru şekilde yüklendiğini kontrol etmek için bir `view()` işlemi. + +=== "Sonra" + + ```groovy title="main.nf" linenums="3" hl_lines="4-5" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + + } + ``` + +Nextflow'a CSV dosyasının ilk satırını başlık satırı olarak okumasını söylemek için `header: true` seçeneğini kullandığımıza dikkat edin. + +Bundan ne çıktığını görelim mi? +Workflow'u çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + [id:sampleA, character:squirrel, recording:/workspaces/training/side-quests/metadata/data/bonjour.txt] + [id:sampleB, character:tux, recording:/workspaces/training/side-quests/metadata/data/guten_tag.txt] + [id:sampleC, character:sheep, recording:/workspaces/training/side-quests/metadata/data/hallo.txt] + [id:sampleD, character:turkey, recording:/workspaces/training/side-quests/metadata/data/hello.txt] + [id:sampleE, character:stegosaurus, recording:/workspaces/training/side-quests/metadata/data/hola.txt] + [id:sampleF, character:moose, recording:/workspaces/training/side-quests/metadata/data/salut.txt] + [id:sampleG, character:turtle, recording:/workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Operatörün CSV dosyasındaki her satır için, sütun başlıklarını karşılık gelen değerlerin anahtarları olarak kullanarak bir anahtar-değer çifti map'i oluşturduğunu görebiliriz. + +Her map girişi veri tablomuzun bir sütununa karşılık gelir: + +- `id` +- `character` +- `recording` + +Bu harika! Belirli alanlara her dosyadan erişmeyi kolaylaştırıyor. +Örneğin, dosya ID'sine `id` ile veya txt dosya yoluna `recording` ile erişebiliriz. + +??? info "(İsteğe bağlı) Map'ler hakkında daha fazla bilgi" + + Nextflow'un üzerine kurulu olduğu programlama dili olan Groovy'de, map, Python'daki dictionary'lere, JavaScript'teki object'lere veya Ruby'deki hash'lere benzer bir anahtar-değer veri yapısıdır. + + İşte pratikte bir map'i nasıl tanımlayabileceğinizi ve içeriğine nasıl erişebileceğinizi gösteren çalıştırılabilir bir script: + + ```groovy title="examples/map_demo.nf" + #!/usr/bin/env nextflow + + // Basit bir map oluştur + def my_map = [id:'sampleA', character:'squirrel'] + + // Tüm map'i yazdır + println "map: ${my_map}" + + // Nokta notasyonu kullanarak bireysel değerlere eriş + println "id: ${my_map.id}" + println "character: ${my_map.character}" + ``` + + Düzgün bir `workflow` bloğu olmasa bile, Nextflow bunu bir workflow gibi çalıştırabilir: + + ```bash + nextflow run examples/map_demo.nf + ``` + + Ve çıktıda görmeyi bekleyebileceğiniz şey: + + ```console title="Çıktı" + N E X T F L O W ~ version 25.10.2 + + Launching `map_demo.nf` [cheesy_plateau] DSL2 - revision: fae5b8496e + + map: [id:sampleA, character:squirrel] + id: sampleA + character: squirrel + ``` + +### 1.2. `map` ile belirli alanları seçme + +Diyelim ki veri tablosundan `character` sütununa erişmek ve yazdırmak istiyoruz. +Channel'ımızdaki her öğe üzerinde yineleme yapmak ve map nesnesinden özellikle `character` girişini seçmek için Nextflow `map` operatörünü kullanabiliriz. + +Workflow'da aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="3" hl_lines="5-7" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="3" + workflow { + + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .view() + + } + ``` + +Şimdi workflow'u tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [exotic_albattani] DSL2 - revision: c0d03cec83 + + squirrel + tux + sheep + turkey + stegosaurus + moose + turtle + ``` + +Başarılı! Veri tablomuzdan türetilen map yapısından yararlanarak her satır için bireysel sütunlardan değerlere eriştik. + +Şimdi veri tablosunu başarıyla okuduk ve her satırdaki verilere erişimimiz var, pipeline mantığımızı uygulamaya başlayabiliriz. + +### 1.3. Metadata'yı bir 'meta map' olarak organize etme + +Workflow'un mevcut durumunda, girdi dosyaları (`recording` anahtarı altında) ve ilişkili metadata (`id`, `character`) hepsi aynı düzeydedir, sanki hepsi aynı büyük çantadalar. +Pratik sonuç, bu channel'ı tüketen her process'in bu yapıyı göz önünde bulundurarak yapılandırılması gerektiğidir: + +```groovy + input: + tuple val(id), val(character), file(recording) +``` + +Veri tablosundaki sütun sayısı değişmediği sürece bu iyidir. +Ancak, veri tablosuna sadece bir sütun daha eklerseniz, channel'ın şekli artık process'in beklediğiyle eşleşmeyecek ve workflow hata üretecektir. +Ayrıca process'i, script bloğu tarafından gerekli olmayan değişkenleri sabit kodlamak zorunda kalabileceğiniz için, biraz farklı girdi verilerine sahip olabilecek başkalarıyla paylaşmayı zorlaştırır. + +Bu sorunu önlemek için, veri tablosunun kaç sütun içerdiğinden bağımsız olarak channel yapısını tutarlı tutmanın bir yolunu bulmamız gerekiyor. + +Bunu, tüm metadata'yı tuple içindeki bir öğede toplayarak yapabiliriz, buna metadata map veya daha basit ifadeyle 'meta map' diyeceğiz. + +`map` işleminde aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [ [id: row.id, character: row.character], row.recording ] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map{ row -> + row.character + } + .view() + ``` + +Channel öğelerimizi, meta map ve karşılık gelen dosya nesnesi olmak üzere iki öğeden oluşan bir tuple olarak yeniden yapılandırdık. + +Workflow'u çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console title="Meta map'i görüntüle" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [lethal_booth] DSL2 - revision: 0d8f844c07 + + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Şimdi, channel'daki her öğe önce metadata map'i, sonra da karşılık gelen dosya nesnesini içerir: + +```console title="Örnek çıktı yapısı" +[ + [id:sampleA, character:squirrel], + /workspaces/training/side-quests/metadata/data/bonjour.txt +] +``` + +Sonuç olarak, veri tablosuna daha fazla sütun eklemek `meta` map'inde daha fazla metadata kullanılabilir hale getirecek, ancak channel şeklini değiştirmeyecektir. +Bu, metadata öğelerini girdi belirtimine sabit kodlamak zorunda kalmadan channel'ı tüketen process'ler yazmamızı sağlar: + +```groovy title="Sözdizimi örneği" + input: + tuple val(meta), file(recording) +``` + +Bu, Nextflow workflow'larında metadata'yı organize etmek için yaygın olarak kullanılan bir kuraldır. + +### Çıkarımlar + +Bu bölümde, şunları öğrendiniz: + +- **Metadata neden önemlidir:** Metadata'yı verinizle birlikte tutmak, workflow boyunca önemli dosya bilgilerini korur. +- **Veri tablolarını nasıl okuyacağınız:** Başlık bilgisine sahip CSV dosyalarını okumak ve satırları yapılandırılmış verilere dönüştürmek için `splitCsv` kullanımı +- **Meta map nasıl oluşturulur:** Tuple yapısı `[ [id:value, ...], file ]` kullanarak metadata'yı dosya verisinden ayırma + +--- + +## 2. Metadata'yı manipüle etme + +Artık metadata'mız yüklendiğine göre, onunla bir şeyler yapalım! + +Her yaratığın kayıt dosyasında bulunan dili tanımlamak için [`langid`](https://github.com/saffsd/langid.py) adlı bir araç kullanacağız. +Araç bir dizi dil üzerinde önceden eğitilmiş olarak gelir ve bir metin parçası verildiğinde, `stdout`'a bir dil tahmini ve ilişkili bir olasılık puanı çıktısı verir. + +### 2.1. Process'i içe aktarın ve kodu inceleyin + +Size `langid` aracını saran `IDENTIFY_LANGUAGE` adlı önceden yazılmış bir process modülü sağlıyoruz, bu nedenle sadece workflow bloğundan önce bir include ifadesi eklemeniz gerekiyor. + +Workflow'da aşağıdaki düzenlemeyi yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Kodunu incelemek için modül dosyasını açabilirsiniz: + +```groovy title="modules/langid.nf" linenums="1" hl_lines="9 12" +#!/usr/bin/env nextflow + +// Her girdi dosyasının dilini tahmin etmek için langid kullan +process IDENTIFY_LANGUAGE { + + container 'community.wave.seqera.io/library/pip_langid:b2269f456a5629ff' + + input: + tuple val(meta), path(file) + + output: + tuple val(meta), path(file), stdout + + script: + """ + langid < ${file} -l en,de,fr,es,it | sed -E "s/.*\\('([a-z]+)'.*/\\1/" | tr -d '\\n' + """ +} +``` + +Gördüğünüz gibi, girdi tanımı girdi channel'ımıza uyguladığımız aynı `tuple val(meta), path(file)` yapısını kullanıyor. + +Çıktı tanımı, girdi yapısına benzer bir yapıya sahip bir tuple olarak yapılandırılmıştır, ancak üçüncü öğe olarak `stdout` da içerir. +Bu `tuple val(meta), path(file), <output>` modeli, metadata'yı hem girdi verisiyle hem de çıktılarla ilişkili tutar ve pipeline boyunca akar. + +Burada Nextflow'un [`stdout`](https://www.nextflow.io/docs/latest/process.html#outputs) çıktı niteleyicisini kullandığımızı unutmayın çünkü araç çıktısını dosya yazmak yerine doğrudan konsola yazdırır; ve komut satırında olasılık puanını kaldırmak, yeni satır karakterlerini kaldırarak dizeyi temizlemek ve yalnızca dil tahminini döndürmek için `sed` kullanırız. + +### 2.2. `IDENTIFY_LANGUAGE`'e bir çağrı ekleyin + +Artık process workflow için kullanılabilir olduğuna göre, veri channel'ında çalıştırmak için `IDENTIFY_LANGUAGE` process'ine bir çağrı ekleyebiliriz. + +Workflow'da aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="6" + ch_datasheet = channel.fromPath("./data/datasheet.csv") + .splitCsv(header: true) + .map { row -> + [[id: row.id, character: row.character], row.recording] + } + .view() + ``` + +Orijinal `.view()` işlemini channel oluşturmada kaldırdığımızı unutmayın. + +Artık workflow'u çalıştırabiliriz: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [voluminous_mcnulty] DSL2 - revision: f9bcfebabb + + executor > local (7) + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7 ✔ + [[id:sampleA, character:squirrel], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt, fr] + [[id:sampleB, character:tux], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt, de] + [[id:sampleD, character:turkey], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt, en] + [[id:sampleC, character:sheep], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt, de] + [[id:sampleF, character:moose], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt, fr] + [[id:sampleE, character:stegosaurus], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt, es] + [[id:sampleG, character:turtle], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt, it] + ``` + +Mükemmel! Şimdi her karakterin hangi dilde konuştuğuna dair bir tahminimiz var. + +Ve daha önce belirtildiği gibi, çıktıya girdi dosyasını ve meta map'i de dahil ettik, bu da her ikisinin de az önce ürettiğimiz yeni bilgiyle ilişkili kalması anlamına gelir. +Bu, bir sonraki adımda faydalı olacaktır. + +!!! note + + Daha genel olarak, meta map'i sonuçlarla ilişkili tutmanın bu modeli, aynı tanımlayıcıları paylaşan ilgili sonuçları ilişkilendirmeyi kolaylaştırır. + + Zaten öğrenmiş olduğunuz gibi, sonuçları bunlar arasında eşleştirmek için channel'lardaki öğelerin sırasına güvenemezsiniz. + Bunun yerine, verileri doğru şekilde ilişkilendirmek için anahtarlar kullanmalısınız ve meta map'ler bu amaç için ideal bir yapı sağlar. + + Bu kullanım senaryosunu [Splitting & Grouping](./splitting_and_grouping.md) yan görevinde ayrıntılı olarak inceliyoruz. + +### 2.3. Process çıktılarıyla metadata'yı genişletme + +Az önce ürettiğimiz sonuçların kendilerinin dosyaların içeriği hakkında bir metadata türü olduğu göz önüne alındığında, bunları meta map'imize eklemek faydalı olacaktır. + +Ancak, mevcut meta map'i yerinde değiştirmek istemiyoruz. +Teknik bir bakış açısından, bunu yapmak _mümkündür_, ancak güvenli değildir. + +Bu nedenle, bunun yerine `+` operatörünü (bir Groovy özelliği) kullanarak mevcut meta map'in içeriğini artı yeni bilgileri tutan yeni bir `lang: lang_id` anahtar-değer çiftini içeren yeni bir meta map oluşturacağız. +Ve bunu eski map'i yenisiyle değiştirmek için bir [`map`](https://www.nextflow.io/docs/latest/operator.html#map) işlemiyle birleştireceğiz. + +Workflow'da yapmanız gereken düzenlemeler şunlardır: + +=== "Sonra" + + ```groovy title="main.nf" linenums="13" hl_lines="3-7" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="13" hl_lines="3" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out.view() + ``` + +`+` operatörüne henüz aşina değilseniz veya bu kafa karıştırıcı geliyorsa, aşağıdaki ayrıntılı açıklamayı gözden geçirmek için birkaç dakika ayırın. + +??? info "`+` operatörü kullanarak yeni meta map'in oluşturulması" + + **İlk olarak, Groovy `+` operatörünü kullanarak iki map'in içeriğini birleştirebileceğimizi bilmeniz gerekir.** + + Diyelim ki aşağıdaki map'lere sahibiz: + + ```groovy + map1 = [id: 'sampleA', character: 'squirrel'] + map2 = [lang: 'fr'] + ``` + + Bunları şu şekilde birleştirebiliriz: + + ```groovy + new_map = map1 + map2 + ``` + + `new_map`'in içeriği şu şekilde olacaktır: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Harika! + + **Peki zaten bir map'in parçası olmayan bir alan eklemeniz gerekirse ne olur?** + + Diyelim ki `map1`'den tekrar başlıyorsunuz, ancak dil tahmini kendi map'inde değil (bir `map2` yok). + Bunun yerine, `lang_id` adlı bir değişkende tutuluyor ve değerini (`'fr'`) `lang` anahtarıyla saklamak istediğinizi biliyorsunuz. + + Aslında şunu yapabilirsiniz: + + ```groovy + new_map = [map1 + [lang: lang_id]] + ``` + + Burada, `[lang: new_info]` anında yeni bir adsız map oluşturur ve `map1 + ` `map1`'i yeni adsız map ile birleştirerek daha önce olduğu gibi aynı `new_map` içeriğini üretir. + + Düzgün, değil mi? + + **Şimdi bunu bir Nextflow `channel.map()` işlemi bağlamına aktaralım.** + + Kod şöyle olur: + + ```groovy + .map { map1, lang_id -> + [map1 + [lang: lang_id]] + } + ``` + + Bu şunları yapar: + + - `map1, lang_id ->` tuple'daki iki öğeyi alır + - `[map1 + [lang: lang_id]]` yukarıda detaylandırıldığı gibi yeni map'i oluşturur + + Çıktı, yukarıdaki örneğimizdeki `new_map` ile aynı içeriğe sahip tek bir adsız map'tir. + Yani etkin bir şekilde şunu dönüştürdük: + + ```groovy + [id: 'sampleA', character: 'squirrel'], 'it' + ``` + + şuna: + + ```groovy + [id: 'sampleA', character: 'squirrel', lang: 'fr'] + ``` + + Umarım `map1`'i `meta` olarak değiştirirsek, bunun temelde workflow'umuzda meta map'imize dil tahminini eklemek için ihtiyacımız olan her şey olduğunu görebilirsiniz. + + Bir şey dışında! + + Workflow'umuz söz konusu olduğunda, **`meta, file, lang_id`'den oluşan tuple'da `file` nesnesinin varlığını da hesaba katmamız gerekir**. + + Yani buradaki kod şöyle olur: + + ```groovy + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + ``` + + `file`'ın `map` işleminde neden dolaştığını anlamakta zorlanıyorsanız, `[meta + [lang: lang_id], file]` yerine o satırın `[new_map, file]` olduğunu hayal edin. + Bu, basitçe `file`'ı tuple'daki ikinci pozisyondaki orijinal yerinde bıraktığımızı daha açık hale getirmelidir. Sadece `new_info` değerini aldık ve onu birinci pozisyondaki map'e katladık. + + **Ve bu bizi `tuple val(meta), path(file)` channel yapısına geri getiriyor!** + +Bu kodun ne yaptığını anladığınızdan emin olduğunuzda, çalışıp çalışmadığını görmek için workflow'u çalıştırın: + +```bash +nextflow run main.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_fermat] DSL2 - revision: d096281ee4 + + [4e/f722fe] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr], /workspaces/training/side-quests/metadata/work/eb/f7148ebdd898fbe1136bec6a714acb/bonjour.txt] + [[id:sampleB, character:tux, lang:de], /workspaces/training/side-quests/metadata/work/16/71d72410952c22cd0086d9bca03680/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de], /workspaces/training/side-quests/metadata/work/ea/04f5d979429e4455e14b9242fb3b45/hallo.txt] + [[id:sampleD, character:turkey, lang:en], /workspaces/training/side-quests/metadata/work/c4/b7562adddc1cc0b7d414ec45d436eb/hello.txt] + [[id:sampleF, character:moose, lang:fr], /workspaces/training/side-quests/metadata/work/5a/6c2b84bf8fadb98e28e216426be079/salut.txt] + [[id:sampleE, character:stegosaurus, lang:es], /workspaces/training/side-quests/metadata/work/af/ee7c69bcab891c40d0529305f6b9e7/hola.txt] + [[id:sampleG, character:turtle, lang:it], /workspaces/training/side-quests/metadata/work/4e/f722fe47271ba7ebcd69afa42964ca/ciao.txt] + ``` + +Evet, bu kontrol edildi! +Process'in çıktısını `meta, file, lang_id`'den düzgün bir şekilde yeniden düzenledik, böylece `lang_id` artık meta map'teki anahtarlardan biri ve channel'ın tuple'ları tekrar `meta, file` modeline uyuyor. + +<!-- TODO (future) subMap kullanarak bir anahtarın nasıl kaldırılacağını da göstermeli miyiz?! Veya bunu nerede bulacağımızı not edelim. --> + +### 2.4. Koşullu ifadeler kullanarak bir dil grubu atama + +Artık dil tahminlerimiz olduğuna göre, yeni gruplamalar atamak için bilgileri kullanalım. + +Örnek verilerimizde, karakterlerimiz tarafından kullanılan diller cermen dilleri (İngilizce, Almanca) ve roman dilleri (Fransızca, İspanyolca, İtalyanca) olarak gruplandırılabilir. +Pipeline'da daha sonra bu sınıflandırmanın hazır bir şekilde mevcut olması faydalı olabilir, bu yüzden o bilgiyi meta map'e ekleyelim. + +Ve, iyi haber, bu map operatörünü kullanmaya mükemmel bir şekilde uyan bir başka durumdur! + +Özellikle, `lang_group` adında bir değişken tanımlayacağız, her veri parçası için `lang_group`'a hangi değerin atanacağını belirlemek için bazı basit koşullu mantık kullanacağız. + +Genel sözdizimi şöyle görünecek: + +```groovy +.map { meta, file -> + + // lang_group'u tanımlayan koşullu mantık buraya gelir + + [meta + [lang_group: lang_group], file] +} +``` + +Gördüğünüz gibi bu, önceki adımda kullandığımız anında map birleştirme işlemine çok benziyor. +Sadece koşullu ifadeleri yazmamız gerekiyor. + +İşte uygulamak istediğimiz koşullu mantık: + +- Varsayılan değeri `'unknown'` olan `lang_group` adında bir değişken tanımlayın. +- Eğer `lang` Almanca (`'de'`) veya İngilizce (`'en'`) ise, `lang_group`'u `germanic` olarak değiştirin. +- Değilse eğer `lang` Fransızca (`'fr'`), İspanyolca (`'es'`) ve İtalyanca (`'it'`) içeren bir listede yer alıyorsa, `lang_group`'u `romance` olarak değiştirin. + +Nextflow'da koşullu ifadeleri nasıl yazacağınızı zaten biliyorsanız kendiniz yazmayı deneyin. + +!!! tip + + Map işlemi içinde `lang` değerine `meta.lang` ile erişebilirsiniz. + +Workflow'da aşağıdaki değişiklikleri yapmayı tamamlamalısınız: + +=== "Sonra" + + ```groovy title="main.nf" linenums="13" hl_lines="7-19" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="13" hl_lines="7" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .view() + ``` + +İşte ana noktalar: + +- Varsayılan değeri `unknown` olarak ayarlanmış `lang_group` değişkenini oluşturmak için `def lang_group = "unknown"` kullanırız. +- İki cermen dili için alternatif `.equals()` testleri ve üç roman dili için bir listede varlık testi ile koşullu mantık için bir `if {} else if {}` yapısı kullanırız. +- Güncellenmiş meta map'i oluşturmak için daha önce olduğu gibi `meta + [lang_group:lang_group]` birleştirme işlemini kullanırız. + +<!-- TODO (future) Ek kaynaklar bölümünde ilgili belgelere not/bağlantılar ekle --> + +Hepsi mantıklı olduğunda, sonucu görmek için workflow'u tekrar çalıştırın: + +```bash +nextflow run main.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [wise_almeida] DSL2 - revision: 46778c3cd0 + + [da/652cc6] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/bonjour.txt] + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/guten_tag.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/data/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/data/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/data/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/data/ciao.txt] + ``` + +Gördüğünüz gibi, channel öğeleri `[meta, file]` yapısını korur, ancak meta map artık bu yeni sınıflandırmayı içerir. + +### Çıkarımlar + +Bu bölümde, nasıl yapılacağını öğrendiniz: + +- **Girdi metadata'sını çıktı channel'larına uygulama**: Metadata'yı bu şekilde kopyalamak, sonuçları daha sonra metadata içeriğine göre ilişkilendirmemize olanak tanır. +- **Özel anahtarlar oluşturma**: Meta map'inizde iki yeni anahtar oluşturdunuz, bunları `meta + [new_key:value]` ile mevcut meta map'e birleştirerek. Biri bir process'ten hesaplanan bir değere, diğeri `map` operatöründe belirlediğiniz bir koşula dayalı olarak. + +Bunlar, pipeline boyunca ilerlerken yeni ve mevcut metadata'yı dosyalarla ilişkilendirmenize olanak tanır. +Bir process'in parçası olarak metadata kullanmasanız bile, meta map'i bu şekilde veriyle ilişkili tutmak tüm ilgili bilgileri bir arada tutmayı kolaylaştırır. + +--- + +## 3. Bir process'te meta map bilgisini kullanma + +Artık meta map'i nasıl oluşturup güncelleyeceğinizi bildiğinize göre, gerçekten eğlenceli kısma geçebiliriz: metadata'yı bir process'te gerçekten kullanma. + +Daha spesifik olarak, workflow'umuza her hayvanı ASCII art olarak çizmek ve kaydedilen metni bir konuşma balonunda söyletmek için ikinci bir adım ekleyeceğiz. +Bunu [`cowpy`](https://github.com/jeffbuttars/cowpy) adlı bir araç kullanarak yapacağız. + +??? info "`cowpy` ne yapar?" + + `cowpy`, keyfi metin girdilerini eğlenceli bir şekilde görüntülemek için ASCII art üreten bir komut satırı aracıdır. + Tony Monroe'nun klasik [cowsay](https://en.wikipedia.org/wiki/Cowsay) aracının python implementasyonudur. + + ```console + cowpy "Hello Nextflow" + ``` + + ```console + ______________________________________________________ + < Hello Nextflow > + ------------------------------------------------------ + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + ``` + + İsteğe bağlı olarak, varsayılan inek yerine kullanılacak bir karakter (veya 'cowacter') seçebilirsiniz. + + ```console + cowpy "Hello Nextflow" -c tux + ``` + + ```console + __________________ + < Hello Nextflow > + ------------------ + \ + \ + .--. + |o_o | + |:_/ | + // \ \ + (| | ) + /'\_ _/`\ + \___)=(___/ + ``` + +Hello Nextflow kursunu tamamladıysanız, bu aracı zaten çalışırken gördünüz. +Eğer görmediyseniz, endişelenmeyin; ilerlerken bilmeniz gereken her şeyi ele alacağız. + +### 3.1. Process'i içe aktarın ve kodu inceleyin + +Size `cowpy` aracını saran `COWPY` adlı önceden yazılmış bir process modülü sağlıyoruz, bu nedenle sadece workflow bloğundan önce bir include ifadesi eklemeniz gerekiyor. + +Workflow'da aşağıdaki düzenlemeyi yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="1" hl_lines="4" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + include { COWPY } from './modules/cowpy.nf' + + workflow { + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + include { IDENTIFY_LANGUAGE } from './modules/langid.nf' + + workflow { + ``` + +Kodunu incelemek için modül dosyasını açabilirsiniz: + +```groovy title="modules/cowpy.nf" linenums="1" +#!/usr/bin/env nextflow + +// cowpy ile ASCII art oluştur +process COWPY { + + publishDir "results/", mode: 'copy' + + container 'community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273' + + input: + path input_file + val character + + output: + path "cowpy-${input_file}" + + script: + """ + cat ${input_file} | cowpy -c ${character} > cowpy-${input_file} + """ +} +``` + +Gördüğünüz gibi, bu process şu anda bir girdi dosyası (görüntülenecek metni içeren) ve ASCII art'ta çizilmesi gereken karakteri belirten bir değer almak üzere tasarlanmıştır, genellikle workflow seviyesinde bir komut satırı parametresi ile sağlanır. + +### 3.2. Bir meta map alanını girdi olarak geçirme + +Hello Nextflow kursunda `cowpy` aracını kullandığımızda, nihai görüntüyü çizmek için hangi karakterin kullanılacağını belirlemek için bir komut satırı parametresi kullandık. +Bu mantıklıydı, çünkü pipeline'ın her çalıştırması başına sadece bir görüntü oluşturuyorduk. + +Ancak, bu eğitimde, işlediğimiz her konu için uygun bir görüntü oluşturmak istiyoruz, bu nedenle bir komut satırı parametresi kullanmak çok sınırlayıcı olurdu. + +İyi haber: veri tablomuzda ve dolayısıyla meta map'imizde bir `character` sütunumuz var. +Process'in her girdi için kullanması gereken karakteri ayarlamak için bunu kullanalım. + +Bu amaçla, üç şey yapmamız gerekecek: + +1. Üzerinde daha rahat çalışabilmemiz için önceki process'ten çıkan çıktı channel'ına bir isim verin +2. İlgilendiğimiz bilgilere nasıl erişeceğimizi belirleyin +3. İkinci process'e bir çağrı ekleyin ve bilgiyi uygun şekilde besleyin + +Başlayalım. + +#### 3.2.1. Önceki çıktı channel'ını adlandırma + +Önceki manipülasyonları doğrudan ilk process'in çıktı channel'ı üzerinde uyguladık, `IDENTIFY_LANGUAGE.out`. +Bir sonraki process'e channel'ın içeriğini beslemek için (ve bunu açık ve kolay okunur bir şekilde yapmak için) ona kendi adını vermek istiyoruz, `ch_languages`. + +Bunu [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set) operatörünü kullanarak yapabiliriz. + +Ana workflow'da, `.view()` operatörünü `.set { ch_languages }` ile değiştirin ve channel'a ismiyle başvurabileceğimizi test eden bir satır ekleyin. + +=== "Sonra" + + ```groovy title="main.nf" linenums="14" hl_lines="19 21 22" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .set { ch_languages } + + // Geçici: ch_languages'a göz at + ch_languages.view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="14" hl_lines="19" + // Her selamlaşmanın dilini tanımlamak için langid çalıştır + IDENTIFY_LANGUAGE(ch_datasheet) + IDENTIFY_LANGUAGE.out + .map { meta, file, lang_id -> + [meta + [lang: lang_id], file] + } + .map { meta, file -> + + def lang_group = "unknown" + if (meta.lang.equals("de") || meta.lang.equals('en')) { + lang_group = "germanic" + } + else if (meta.lang in ["fr", "es", "it"]) { + lang_group = "romance" + } + + [meta + [lang_group: lang_group], file] + } + .view() + ``` + +Bunu çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [friendly_austin] DSL2 - revision: 3dbe460fd6 + + [36/cca6a7] IDENTIFY_LANGUAGE (7) | 7 of 7 ✔ + [[id:sampleB, character:tux, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/e2/6db2402d83cf72081bcd2d11784714/guten_tag.txt] + [[id:sampleA, character:squirrel, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/6c/114c818317d169457d6e7336d5d55b/bonjour.txt] + [[id:sampleC, character:sheep, lang:de, lang_group:germanic], /workspaces/training/side-quests/metadata/work/55/68c69c5efb527f3604ddb3daab8057/hallo.txt] + [[id:sampleD, character:turkey, lang:en, lang_group:germanic], /workspaces/training/side-quests/metadata/work/2a/4752055ccb5d1370b0ef9da41d3993/hello.txt] + [[id:sampleE, character:stegosaurus, lang:es, lang_group:romance], /workspaces/training/side-quests/metadata/work/f4/fcd3186dc666d5d239ffa6c37d125d/hola.txt] + [[id:sampleF, character:moose, lang:fr, lang_group:romance], /workspaces/training/side-quests/metadata/work/c3/3b2627f733f278a7088332a5806108/salut.txt] + [[id:sampleG, character:turtle, lang:it, lang_group:romance], /workspaces/training/side-quests/metadata/work/36/cca6a7dbfa26ac24f9329787a32e9d/ciao.txt] + ``` + +Bu, artık channel'a ismiyle başvurabileceğimizi doğruluyor. + +#### 3.2.2. Dosya ve karakter metadata'sına erişim + +Modül koduna bakarak `COWPY` process'inin bir metin dosyası ve bir `character` değeri verilmesini beklediğini biliyoruz. +`COWPY` process çağrısını yazmak için, channel'daki her öğeden karşılık gelen dosya nesnesini ve metadata'yı nasıl çıkaracağımızı bilmemiz gerekiyor. + +Genellikle olduğu gibi, bunu yapmanın en basit yolu bir `map` işlemi kullanmaktır. + +Channel'ımız `[meta, file]` olarak yapılandırılmış tuple'lar içerir, bu nedenle `file` nesnesine doğrudan erişebiliriz ve meta map içinde saklanan `character` değerine `meta.character` olarak başvurarak erişebiliriz. + +Ana workflow'da, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="34" + // Geçici: dosya ve karaktere eriş + ch_languages.map { meta, file -> file }.view { file -> "File: " + file } + ch_languages.map { meta, file -> meta.character }.view { character -> "Character: " + character } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="34" + // Geçici: ch_languages'a göz at + ch_languages.view() + ``` + +`.view` işlemlerinin çıktısını daha okunabilir hale getirmek için closure'ları (örneğin `{ file -> "File: " + file }`) kullandığımızı unutmayın. + +Bunu çalıştıralım: + +```bash +nextflow run main.nf -resume +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [cheesy_cantor] DSL2 - revision: 15af9c1ec7 + + [43/05df08] IDENTIFY_LANGUAGE (7) [100%] 7 of 7, cached: 7 ✔ + Character: squirrel + File: /workspaces/training/side-quests/metadata/work/8d/4b9498bbccb7a74f04e41877cdc3e5/bonjour.txt + File: /workspaces/training/side-quests/metadata/work/d3/604274985406e40d79021dea658e60/guten_tag.txt + Character: tux + Character: turkey + File: /workspaces/training/side-quests/metadata/work/d4/fafcc9415b61d2b0fea872e6a05e8a/hello.txt + File: /workspaces/training/side-quests/metadata/work/02/468ac9efb27f636715e8144b37e9a7/hallo.txt + Character: sheep + Character: moose + Character: stegosaurus + File: /workspaces/training/side-quests/metadata/work/d4/61a7e1188b4f2742bc72004e226eca/salut.txt + File: /workspaces/training/side-quests/metadata/work/ae/68364be238c11149c588bf6fc858b1/hola.txt + File: /workspaces/training/side-quests/metadata/work/43/05df081af5d879ab52e5828fa0357e/ciao.txt + Character: turtle + ``` + +_Dosya yolları ve karakter değerleri çıktınızda farklı bir sırayla gelebilir._ + +Bu, channel'daki her öğe için dosyaya ve karaktere erişebildiğimizi doğruluyor. + +#### 3.2.3. `COWPY` process'ini çağırma + +Şimdi hepsini bir araya getirelim ve gerçekten `ch_languages` channel'ında `COWPY` process'ini çağıralım. + +Ana workflow'da, aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="34" + // ASCII art oluşturmak için cowpy çalıştır + COWPY( + ch_languages.map { meta, file -> file }, + ch_languages.map { meta, file -> meta.character } + ) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="34" + // Geçici: dosya ve karaktere eriş + ch_languages.map { meta, file -> [file, meta.character] } + .view() + ``` + +Sadece iki diff --git a/docs/tr/docs/side_quests/nf-test.md b/docs/tr/docs/side_quests/nf-test.md new file mode 100644 index 0000000000..1dbf035cb4 --- /dev/null +++ b/docs/tr/docs/side_quests/nf-test.md @@ -0,0 +1,1194 @@ +# nf-test ile Test Etme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +İş akışınızın her bir parçasının yapması gerekeni yaptığını sistematik olarak test edebilmek, tekrarlanabilirlik ve uzun vadeli bakım için kritik öneme sahiptir ve geliştirme sürecinde büyük bir yardımcı olabilir. + +Test etmenin neden bu kadar önemli olduğu hakkında biraz konuşalım. Bir iş akışı geliştiriyorsanız, yapacağınız ilk şeylerden biri geçerli olduğunu bildiğiniz ve sonuç üretmesi gereken bazı test verilerini almaktır. Pipeline'a ilk süreci ekler ve çalışması için girdilerinize bağlarsınız. Ardından, her şeyin çalıştığını kontrol etmek için test verileri üzerinde çalıştırırsınız. Bunun işe yaradığını varsayarsak, bir sonraki sürece geçer ve test verilerini tekrar çalıştırırsınız. Pipeline'dan memnun kalana kadar bu süreci tekrarlarsınız. + +Ardından, belki de `--skip_process` gibi basit bir doğru ya da yanlış parametresi eklersiniz. Şimdi pipeline'ı beklendiği gibi çalıştığından emin olmak için her parametre ile bir kez olmak üzere iki kez çalıştırmalısınız. Ama bekleyin, `--skip_process`'in gerçekten süreci atladığını nasıl kontrol ederiz? Çıktıları incelemeli veya log dosyalarını kontrol etmeliyiz! Bu zahmetli ve hataya açık bir durumdur. + +İş akışınızı geliştirirken, her iterasyonu manuel olarak test etmek hızla o kadar karmaşık hale gelir ki yavaş ve hataya açık olur. Dahası, bir hata bulursanız hatanın pipeline'ınızda tam olarak nereden kaynaklandığını belirlemek çok zor olacaktır. Test etme işte burada devreye girer. + +Test etme, pipeline'ınızın her bir parçasının beklendiği gibi çalıştığını sistematik olarak kontrol etmenizi sağlar. İyi yazılmış testlerin bir geliştirici için faydaları çok büyüktür: + +- **Güven**: Testler tüm pipeline'ı kapsadığı için, bir şeyi değiştirmenin başka bir şeyi etkilemediğinden emin olabilirsiniz +- **Güvenilirlik**: Birden fazla geliştirici pipeline üzerinde çalıştığında, diğer geliştiricilerin pipeline'ı ve her bileşeni bozmadığını bilirler. +- **Şeffaflık**: Testler, pipeline'ın nerede başarısız olduğunu gösterir ve sorunu takip etmeyi kolaylaştırır. Ayrıca bir tür dokümantasyon işlevi görürler ve bir sürecin veya iş akışının nasıl çalıştırılacağını gösterirler. +- **Hız**: Testler otomatik olduğu için çok hızlı ve tekrarlı bir şekilde çalıştırılabilir. Yeni hatalar ekleme korkusu daha az olarak hızlı iterasyon yapabilirsiniz. + +Yazabileceğimiz birçok farklı test türü vardır: + +1. **Modül seviyesi testler**: Bireysel süreçler için +2. **İş akışı seviyesi testler**: Tek bir iş akışı için +3. **Pipeline seviyesi testler**: Pipeline'ın bir bütün olarak testi için +4. **Performans testleri**: Pipeline'ın hız ve verimliliği için +5. **Stres testleri**: Aşırı koşullar altında pipeline'ın performansını değerlendirerek limitlerini belirleme + +Bireysel süreçleri test etmek, diğer dillerdeki birim testlere benzerdir. İş akışını veya tüm pipeline'ı test etmek, diğer dillerde entegrasyon testleri olarak adlandırılan, bileşenlerin etkileşimlerini test ettiğimiz teste benzerdir. + +[**nf-test**](https://www.nf-test.com/) modül, iş akışı ve pipeline seviyesi test yazmanıza olanak tanıyan bir araçtır. Kısacası, pipeline'ın her bir parçasının _izole bir şekilde_ beklendiği gibi çalışıp çalışmadığını sistematik olarak kontrol etmenizi sağlar. + +### Öğrenme hedefleri + +Bu yan görevde, pipeline için bir iş akışı seviyesi test ve çağırdığı üç süreç için modül seviyesi testler yazmak üzere nf-test'i kullanmayı öğreneceksiniz. + +Bu yan görevin sonunda, aşağıdaki teknikleri etkin bir şekilde kullanabileceksiniz: + +- Projenizde nf-test'i başlatma +- Modül seviyesi ve iş akışı seviyesi testler oluşturma +- Yaygın onaylama türlerini ekleme +- Snapshot'ların ne zaman kullanılacağını vs. içerik onaylamalarını anlama +- Tüm bir proje için testleri çalıştırma + +Bu beceriler, pipeline projelerinizde kapsamlı bir test stratejisi uygulamanıza yardımcı olarak onların daha sağlam ve sürdürülebilir olmasını sağlayacaktır. + +### Ön koşullar + +Bu yan görevi üstlenmeden önce: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramlarını ve mekanizmalarını (süreçler, kanallar, operatörler, dosyalarla çalışma, meta veri) kullanma konusunda rahat olmalısınız + +--- + +## 0. Başlayın + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md)'nda açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine gidin + +Bu eğitimin dosyalarının bulunduğu dizine geçelim. + +```bash +cd side-quests/nf-test +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri gözden geçirin + +Ana iş akışı dosyasını ve pipeline'a girdi içeren `greetings.csv` adlı bir CSV dosyası bulacaksınız. + +```console title="Dizin içeriği" +. +├── greetings.csv +└── main.nf +``` + +Dosyaların ayrıntılı açıklaması için [Hello Nextflow'dan ısınma](../hello_nextflow/00_orientation.md) bölümüne bakın. + +Test edeceğimiz iş akışı, [Hello Workflow](../hello_nextflow/03_hello_workflow.md)'da oluşturulan Hello iş akışının bir alt kümesidir. + +??? example "Hello Nextflow iş akışı ne yapar?" + + [Hello Nextflow](../hello_nextflow/index.md) eğitimini yapmadıysanız, bu basit iş akışının ne yaptığına dair kısa bir genel bakış: + + İş akışı, selamlamalar içeren bir CSV dosyasını alır, bunlar üzerinde ardışık dört dönüştürme adımı çalıştırır ve selamlamaları söyleyen eğlenceli bir karakterin ASCII resmini içeren tek bir metin dosyası çıktılar. + + Dört adım, ayrı modül dosyalarında saklanan Nextflow süreçleri (`sayHello`, `convertToUpper`, `collectGreetings` ve `cowpy`) olarak uygulanır. + + 1. **`sayHello`:** Her selamlamayı kendi çıktı dosyasına yazar (örn., "Hello-output.txt") + 2. **`convertToUpper`:** Her selamlamayı büyük harfe dönüştürür (örn., "HELLO") + 3. **`collectGreetings`:** Tüm büyük harf selamlamalarını tek bir toplu dosyada toplar + 4. **`cowpy`:** `cowpy` aracını kullanarak ASCII sanatı oluşturur + + Sonuçlar `results/` adlı bir dizine yayınlanır ve pipeline'ın nihai çıktısı (varsayılan parametrelerle çalıştırıldığında) büyük harfe dönüştürülmüş selamlamaları söyleyen bir karakterin ASCII sanatını içeren düz bir metin dosyasıdır. + + Bu yan görevde, yalnızca ilk iki süreci içeren Hello iş akışının ara bir formunu kullanıyoruz. + +Üzerinde çalışacağımız alt küme iki süreçten oluşur: `sayHello` ve `convertToUpper`. +Tam iş akışı kodunu aşağıda görebilirsiniz. + +??? example "İş akışı kodu" + + ```groovy title="main.nf" + /* + * Pipeline parametreleri + */ + params.input_file = "greetings.csv" + + /* + * 'Hello World!' yazdırmak için echo kullan + */ + process sayHello { + + publishDir 'results', mode: 'copy' + + input: + val greeting + + output: + path "${greeting}-output.txt" + + script: + """ + echo '$greeting' > '$greeting-output.txt' + """ + } + + /* + * Selamlamayı büyük harfe dönüştürmek için metin değiştirme aracı kullan + */ + process convertToUpper { + + publishDir 'results', mode: 'copy' + + input: + path input_file + + output: + path "UPPER-${input_file}" + + script: + """ + cat '$input_file' | tr '[a-z]' '[A-Z]' > UPPER-${input_file} + """ + } + + workflow { + + // CSV dosyasından girdiler için bir kanal oluştur + greeting_ch = channel.fromPath(params.input_file).splitCsv().flatten() + + // bir selamlama yayınla + sayHello(greeting_ch) + + // selamlamayı büyük harfe dönüştür + convertToUpper(sayHello.out) + } + ``` + +#### İş akışını çalıştırın + +İş akışının beklendiği gibi çalıştığından emin olmak için çalıştıralım. + +```bash +nextflow run main.nf +``` + +```console title="İş akışını çalıştırma sonucu" + N E X T F L O W ~ version 24.10.2 + +Launching `main.nf` [soggy_linnaeus] DSL2 - revision: bbf79d5c31 + +executor > local (6) +[f7/c3be66] sayHello (3) | 3 of 3 ✔ +[cd/e15303] convertToUpper (3) | 3 of 3 ✔ +``` + +TEBRİKLER! Az önce bir test çalıştırdınız! + +"Dur, ne? Sadece iş akışını çalıştırdım ve işe yaradı! Bu nasıl bir test?" + +İyi soru! + +Az önce ne olduğunu inceleyelim. + +İş akışını varsayılan parametrelerle çalıştırdınız, çalıştığını onayladınız ve sonuçlardan memnunsunuz. Bu, test etmenin özüdür. Hello Nextflow eğitim kursunu çalıştıysanız, her bölüme her zaman kullandığımız iş akışını çalıştırarak başladığımızı fark etmişsinizdir, her şeyin doğru şekilde kurulduğunu onaylamak için. + +Yazılım testi esasen bu süreci bizim için yapar. + +#### Görevi gözden geçirin + +Zorluk, herhangi bir değişiklik yapılması durumunda her parçanın beklendiği gibi çalışmaya devam ettiğini doğrulamayı kolaylaştırmak için bu iş akışına nf-test kullanarak standartlaştırılmış testler eklemektir. + +#### Hazırlık kontrol listesi + +Dalmaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun hedefini ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışır durumda +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] İş akışını başarıyla çalıştırdım +- [ ] Görevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. `nf-test`'i başlatın + +`nf-test` paketi, projemiz için test geliştirmeye başlamamız için birkaç şeyi ayarlayan bir başlatma komutu sağlar. + +```bash +nf-test init +``` + +Bu, aşağıdaki çıktıyı üretmelidir: + +```bash +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + +Project configured. Configuration is stored in nf-test.config +``` + +Ayrıca bir yapılandırma dosyası taslağı içeren bir `tests` dizini oluşturur. + +### 1.1. Bir nf-test oluşturun + +`nf-test`, nf-test dosyalarını oluşturmak için bir dizi araçla birlikte gelir ve işin çoğunu bizim için yapar. Bunlar `generate` alt komutu altında gelir. Pipeline için bir test oluşturalım: + +```bash +nf-test generate pipeline main.nf +``` + +```console title="Çıktı" +> nf-test generate pipeline main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote pipeline test file '/workspaces/training/side-quests/nf-test/tests/main.nf.test + +SUCCESS: Generated 1 test files. +``` + +Bu, `tests` dizini içinde bir `main.nf.test` dosyası oluşturacaktır. Bu bizim pipeline seviyesi test dosyamızdır. `tree tests/` komutunu çalıştırırsanız şöyle bir şey görmelisiniz: + +```console title="Test dizini içeriği" +tests/ +├── main.nf.test +└── nextflow.config +``` + +`main.nf.test` dosyası bizim pipeline seviyesi test dosyamızdır. Açıp içeriğine bir göz atalım. + +```groovy title="tests/main.nf.test" +nextflow_pipeline { + + name "Test Workflow main.nf" + script "main.nf" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + } + + then { + assert workflow.success + } + + } + +} +``` + +Test dosyasının yapısını anlamak için bir saniye ayıralım. + +`nextflow_pipeline` bloğu, tüm pipeline seviyesi testler için giriş noktasıdır. Aşağıdakileri içerir: + +- `name`: Testin adı. +- `script`: Pipeline betiğinin yolu. + +`test` bloğu gerçek testtir. Aşağıdakileri içerir: + +- `when`: Testin çalıştırılması gereken koşullar. Bu, pipeline'ı çalıştırmak için kullanılacak parametreleri içerir. +- `then`: Yapılması gereken onaylamalar. Bu, pipeline'ın beklenen sonuçlarını içerir. + +Düz Türkçe ile, testin mantığı şöyle okunur: +"**When** bu _parametreler_ bu _pipeline_'a sağlandığında, **then** bu sonuçları görmeyi bekliyoruz." + +Bu işlevsel bir test değildir, bir sonraki bölümde bunu nasıl işlevsel bir teste dönüştüreceğimizi göstereceğiz. + +### Test Adları Hakkında Bir Not + +Yukarıdaki örnekte, yalnızca pipeline'ın başarılı bir şekilde çalışıp çalışmadığını kontrol eden temel bir test için uygun olan varsayılan "Should run without failures" adını kullandık. Ancak, daha spesifik test durumları ekledikçe, gerçekte neyi test ettiğimizi gösteren daha açıklayıcı adlar kullanmalıyız. Örneğin: + +- "Should convert input to uppercase" - belirli işlevselliği test ederken +- "Should handle empty input gracefully" - uç durumları test ederken +- "Should respect max memory parameter" - kaynak kısıtlamalarını test ederken +- "Should create expected output files" - dosya oluşturmayı test ederken + +İyi test adları şunları içermelidir: + +1. Beklenen davranışın ne olduğunu açık hale getirmek için "Should" ile başlamalı +2. Test edilen belirli işlevselliği veya senaryoyu tanımlamalı +3. Test başarısız olursa, hangi işlevselliğin bozuk olduğunu bilecek kadar açık olmalı + +Daha sonra daha fazla onaylama ve spesifik test durumu ekledikçe, her testin neyi doğruladığını açık hale getirmek için bu daha açıklayıcı adları kullanacağız. + +### 1.2. Testi çalıştırın + +Ne olduğunu görmek için testi çalıştıralım. + +```bash +nf-test test tests/main.nf.test +``` + +```console title="nf-test pipeline başarısız" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' FAILED (4.652s) + + Assertion failed: + + assert workflow.success + | | + workflow false + + Nextflow stdout: + + ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv + + -- Check '/workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/meta/nextflow.log' file for details + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.679s (1 failed) +``` + +Test başarısız oluyor! Ne oldu? + +1. nf-test, `when` bloğundaki ayarları kullanarak pipeline'ı olduğu gibi çalıştırmaya çalıştı: + +```groovy title="tests/main.nf.test" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +2. nf-test, pipeline'ın durumunu kontrol etti ve `when` bloğuyla karşılaştırdı: + +```groovy title="tests/main.nf.test" +then { + assert workflow.success +} +``` + +nf-test'in pipeline'ın başarısız olduğunu nasıl bildirdiğine ve Nextflow'dan hata mesajını sağladığına dikkat edin: + +```console title="Hata" +ERROR ~ No such file or directory: /workspaces/training/side-quests/nf-test/.nf-test/tests/693ba951a20fec36a5a9292ed1cc8a9f/greetings.csv +``` + +Peki sorun neydi? Pipeline'ın proje dizininde bir greetings.csv dosyası olduğunu hatırlayın. nf-test pipeline'ı çalıştırdığında bu dosyayı arayacaktır, ancak bulamaz. Dosya orada, ne oluyor? Yola bakarsak testin `./nf-test/tests/longHashString/` yolunda gerçekleştiğini görebiliriz. Tıpkı Nextflow gibi, nf-test de her şeyi izole tutmak için her test için yeni bir dizin oluşturur. Veri dosyası orada bulunmadığı için orijinal testteki dosyanın yolunu düzeltmeliyiz. + +Test dosyasına geri dönelim ve `when` bloğundaki dosyanın yolunu değiştirelim. + +Testte pipeline'ın köküne nasıl işaret edeceğimizi merak ediyor olabilirsiniz. Bu yaygın bir durum olduğu için, nf-test hayatımızı kolaylaştırmak için bir dizi global değişken sağlar. Tam listeyi [burada](https://www.nf-test.com/docs/testcases/global_variables/) bulabilirsiniz, ancak şimdilik pipeline projesinin kökü anlamına gelen `projectDir` değişkenini kullanacağız. + +_Önce:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3 4" +when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } +} +``` + +_Sonra:_ + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="3" +when { + params { + input_file = "${projectDir}/greetings.csv" + } +} +``` + +İşe yarayıp yaramadığını görmek için testi tekrar çalıştıralım. + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline başarılı" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run without failures' PASSED (1.619s) + + +SUCCESS: Executed 1 tests in 1.626s +``` + +Başarılı! Pipeline başarıyla çalışıyor ve test geçiyor. İstediğiniz kadar çalıştırın ve her zaman aynı sonucu alacaksınız! + +Varsayılan olarak, Nextflow çıktısı gizlidir, ancak nf-test'in kesinlikle iş akışını çalıştırdığına kendinizi ikna etmek için `--verbose` bayrağını kullanabilirsiniz: + +```bash +nf-test test tests/main.nf.test --verbose +``` + +```console title="Pipeline tüm süreçleri çalıştırıyor" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [693ba951] 'Should run without failures' + > Nextflow 24.10.4 is available - Please consider updating your version to it + > N E X T F L O W ~ version 24.10.0 + > Launching `/workspaces/training/side-quests/nf-test/main.nf` [zen_ampere] DSL2 - revision: bbf79d5c31 + > [2b/61e453] Submitted process > sayHello (2) + > [31/4e1606] Submitted process > sayHello (1) + > [bb/5209ee] Submitted process > sayHello (3) + > [83/83db6f] Submitted process > convertToUpper (2) + > [9b/3428b1] Submitted process > convertToUpper (1) + > [ca/0ba51b] Submitted process > convertToUpper (3) + PASSED (5.206s) + + +SUCCESS: Executed 1 tests in 5.239s +``` + +### 1.3. Onaylamalar ekleyin + +Basit bir kontrol, pipeline'ımızın beklediğimiz tüm süreçleri çalıştırdığından ve hiçbirini sessizce atlamadığından emin olmaktır. Pipeline'ımızın 3 selamlamanın her biri için bir `sayHello` ve bir `convertToUpper` olmak üzere 6 süreç çalıştırdığını hatırlayın. + +Testımıze pipeline'ın beklenen sayıda süreci çalıştırdığını kontrol etmek için bir onaylama ekleyelim. Ayrıca test adımızı test ettiğimiz şeyi daha iyi yansıtacak şekilde güncelleyelim. + +**Önce:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1" + test("Should run without failures") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + } + + } +``` + +**Sonra:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="1 11" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +Test adı artık gerçekte neyi doğruladığımızı daha iyi yansıtıyor - sadece pipeline'ın başarısız olmadan çalıştığını değil, aynı zamanda beklenen sayıda süreci çalıştırdığını. + +İşe yarayıp yaramadığını görmek için testi tekrar çalıştıralım. + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline onaylamalarla başarılı" +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [1d4aaf12] 'Should run successfully with correct number of processes' PASSED (1.567s) + + +SUCCESS: Executed 1 tests in 1.588s +``` + +Başarılı! Pipeline başarıyla çalışıyor ve test geçiyor. Artık genel durumun yanı sıra pipeline'ın ayrıntılarını da test etmeye başladık. + +### 1.4. Çıktıyı test edin + +Testımıze çıktı dosyasının oluşturulduğunu kontrol etmek için bir onaylama ekleyelim. Sonuçları yorumlamayı kolaylaştırmak için bilgilendirici bir adla ayrı bir test olarak ekleyeceğiz. + +**Önce:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } +``` + +**Sonra:** + +```groovy title="tests/main.nf.test" linenums="1" hl_lines="14-33" + test("Should run successfully with correct number of processes") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert workflow.success + assert workflow.trace.tasks().size() == 6 + } + + } + + test("Should produce correct output files") { + + when { + params { + input_file = "${projectDir}/greetings.csv" + } + } + + then { + assert file("$launchDir/results/Bonjour-output.txt").exists() + assert file("$launchDir/results/Hello-output.txt").exists() + assert file("$launchDir/results/Holà-output.txt").exists() + assert file("$launchDir/results/UPPER-Bonjour-output.txt").exists() + assert file("$launchDir/results/UPPER-Hello-output.txt").exists() + assert file("$launchDir/results/UPPER-Holà-output.txt").exists() + } + + } +``` + +İşe yarayıp yaramadığını görmek için testi tekrar çalıştırın. + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.nf.test +``` + +```console title="Pipeline dosya onaylamalarıyla başarılı" +> nf-test test tests/main.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Workflow main.nf + + Test [f0e08a68] 'Should run successfully with correct number of processes' PASSED (8.144s) + Test [d7e32a32] 'Should produce correct output files' PASSED (6.994s) + + +SUCCESS: Executed 2 tests in 15.165s +``` + +Başarılı! Testler geçer çünkü pipeline başarıyla tamamlandı, doğru sayıda süreç çalıştı ve çıktı dosyaları oluşturuldu. Bu aynı zamanda testleriniz için bilgilendirici adlar sağlamanın ne kadar yararlı olduğunu göstermelidir. + +Bu sadece yüzey, pipeline'ın ayrıntılarını kontrol etmek için onaylamalar yazmaya devam edebiliriz, ancak şimdilik pipeline'ın içini test etmeye geçelim. + +### Çıkarım + +Bir pipeline için nf-test yazmayı biliyorsunuz. + +### Sırada ne var? + +Bir Nextflow sürecini test etmeyi öğrenin. + +--- + +## 2. Bir Nextflow sürecini test edin + +Pipeline'ın her parçası için test yazmak zorunda değiliz, ancak ne kadar çok testımız olursa pipeline hakkında o kadar kapsamlı olabiliriz ve beklendiği gibi çalıştığından o kadar emin olabiliriz. Bu bölümde pipeline'daki her iki süreci de bireysel birimler olarak test edeceğiz. + +### 2.1. `sayHello` sürecini test edin + +`sayHello` süreci ile başlayalım. + +Süreç için testler oluşturmak üzere `nf-test generate` komutunu tekrar kullanalım. + +```bash +nf-test generate process main.nf +``` + +```console title="Çıktı" +> nf-test generate process main.nf + +Load source file '/workspaces/training/side-quests/nf-test/main.nf' +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.sayhello.nf.test +Wrote process test file '/workspaces/training/side-quests/nf-test/tests/main.converttoupper.nf.test + +SUCCESS: Generated 2 test files. +``` + +Şimdilik `main.sayhello.nf.test` dosyasındaki `sayhello` sürecine odaklanalım. + +Dosyayı açıp içeriğine bir göz atalım. + +```groovy title="tests/main.sayhello.nf.test" +nextflow_process { + + name "Test Process sayHello" + script "main.nf" + process "sayHello" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Daha önce olduğu gibi, test ayrıntılarıyla başlıyoruz, ardından `when` ve `then` blokları geliyor. Ancak, sürece girdileri tanımlamamıza izin veren ek bir `process` bloğumuz da var. + +İşe yarayıp yaramadığını görmek için testi çalıştıralım. + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Süreç testi başarısız" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [1eaad118] 'Should run without failures' FAILED (4.876s) + + Assertion failed: + + assert process.success + | | + | false + sayHello + + Nextflow stdout: + + Process `sayHello` declares 1 input but was called with 0 arguments + Nextflow stderr: + +FAILURE: Executed 1 tests in 4.884s (1 failed) +``` + +Test başarısız oluyor çünkü `sayHello` süreci 1 girdi bildiriyor ancak 0 argümanla çağrıldı. Sürece bir girdi ekleyerek bunu düzeltelim. [Hello Workflow](../hello_nextflow/03_hello_workflow.md)'dan (ve yukarıdaki ısınma bölümünden) `sayHello` sürecimizin sağlamamız gereken tek bir değer girdisi aldığını hatırlayın. Ayrıca test adını test ettiğimiz şeyi daha iyi yansıtacak şekilde düzeltmeliyiz. + +**Önce:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Sonra:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +İşe yarayıp yaramadığını görmek için testi tekrar çalıştıralım. + +```console title="nf-test pipeline başarılı" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.604s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.611s +``` + +Başarılı! Test geçer çünkü `sayHello` süreci başarıyla çalıştı ve çıktı oluşturuldu. + +### 2.2. Test tarafından oluşturulan snapshot'a göz atın + +`tests/main.sayhello.nf.test` dosyasına bakarsak, onaylama bloğunda bir `snapshot()` metodu kullandığını görebiliriz: + +```groovy title="tests/main.sayhello.nf.test" +assert snapshot(process.out).match() +``` + +Bu, nf-test'e `sayHello` sürecinin çıktısının bir snapshot'ını oluşturmasını söylüyor. Snapshot dosyasının içeriğine bir göz atalım. + +```console title="Snapshot dosyası içeriği" +code tests/main.sayhello.nf.test.snap +``` + +Burada yazdırmayacağız, ancak süreç ve süreç çıktılarının ayrıntılarını içeren bir JSON dosyası görmelisiniz. Özellikle, şuna benzeyen bir satır görebiliriz: + +```json title="Snapshot dosyası içeriği" +"0": [ + "hello-output.txt:md5,b1946ac92492d2347c6235b4d2611184" +] +``` + +Bu, açıkça test ettiğimiz `sayHello` süreci tarafından oluşturulan çıktıları temsil eder. Testi yeniden çalıştırırsak, program yeni çıktının başlangıçta kaydedilen çıktıyla eşleşip eşleşmediğini kontrol edecektir. Bu, süreç çıktılarının değişmediğini test etmenin hızlı, basit bir yoludur, bu nedenle nf-test bunu varsayılan olarak sağlar. + +!!!warning + + Bu, orijinal çalıştırmada kaydettiğimiz çıktının doğru olduğundan emin olmamız gerektiği anlamına gelir! + +Gelecekteki geliştirme sırasında, kodda çıktının farklı olmasına neden olan bir şey değişirse, test başarısız olacak ve değişikliğin beklenip beklenmediğini belirlememiz gerekecektir. + +- Kodda bir şeyin bozulduğu ortaya çıkarsa, testin geçeceği beklentisiyle düzeltmemiz gerekecektir. +- Beklenen bir değişiklikse (örn., araç iyileştirildi ve sonuçlar daha iyi) o zaman yeni çıktıyı eşleştirilecek referans olarak kabul etmek için snapshot'ı güncellememiz gerekecektir. nf-test bu amaç için bir `--update-snapshot` parametresine sahiptir. + +Testi tekrar çalıştırabiliriz ve testin geçmesi gerektiğini görebiliriz: + +```console title="snapshot ile nf-test süreci başarılı" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [f91a1bcd] 'Should run without failures and produce correct output' PASSED (1.675s) + + +SUCCESS: Executed 1 tests in 1.685s +``` + +Başarılı! Test geçer çünkü `sayHello` süreci başarıyla çalıştı ve çıktı snapshot ile eşleşti. + +### 2.3. Snapshot'lara Alternatif: Doğrudan İçerik Onaylamaları + +Snapshot'lar çıktıdaki herhangi bir değişikliği yakalamak için harika olsa da, bazen tüm dosyanın eşleşmesi konusunda bu kadar katı olmadan belirli içeriği doğrulamak isteyebilirsiniz. Örneğin: + +- Çıktının bazı kısımları değişebilir (zaman damgaları, rastgele kimlikler, vb.) ancak belirli anahtar içerik mevcut olmalıdır +- Çıktıda belirli desenler veya değerleri kontrol etmek istediğinizde +- Testi başarıyı neyin oluşturduğu konusunda daha açık hale getirmek istediğinizde + +Testımızı belirli içeriği kontrol edecek şekilde nasıl değiştirebileceğimiz aşağıda: + +**Önce:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 6 17" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Sonra:** + +```groovy title="tests/main.sayhello.nf.test" linenums="1" hl_lines="1 5 16 17" + test("Should run without failures and contain expected greeting") { + + when { + params { + // parametreleri burada tanımlayın + } + process { + """ + input[0] = "hello" + """ + } + } + + then { + assert process.success + assert path(process.out[0][0]).readLines().contains('hello') + assert !path(process.out[0][0]).readLines().contains('HELLO') + } + + } +``` + +nf-test'in süreç çıktılarını liste listeleri olarak gördüğüne dikkat edin, bu nedenle `process.out[0][0]` bu süreçten ilk kanal öğesinin (veya 'emisyonunun') ilk kısmını getiriyor. + +Bu yaklaşım: + +- Çıktıda tam olarak ne beklediğimizi açık hale getirir +- Çıktıdaki alakasız değişikliklere karşı daha dayanıklıdır +- Testler başarısız olduğunda daha iyi hata mesajları sağlar +- Daha karmaşık doğrulamalara izin verir (regex desenleri, sayısal karşılaştırmalar, vb.) + +İşe yarayıp yaramadığını görmek için testi çalıştıralım. + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.sayhello.nf.test +``` + +```console title="Süreç testi başarısız" +> nf-test test tests/main.sayhello.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (7.196s) + + +SUCCESS: Executed 1 tests in 7.208s +``` + +### 2.4. `convertToUpper` sürecini test edin + +`tests/main.converttoupper.nf.test` dosyasını açıp içeriğine bir göz atalım: + +```groovy title="tests/main.converttoupper.nf.test" +nextflow_process { + + name "Test Process convertToUpper" + script "main.nf" + process "convertToUpper" + + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } + +} +``` + +Bu, `sayHello` sürecine benzer bir testtir, ancak `convertToUpper` sürecini test ediyor. Bunun başarısız olacağını biliyoruz çünkü tıpkı `sayHello` gibi, `convertToUpper` süreci tek bir yol girdisi alır, ancak biz bir tane belirtmedik. + +Şimdi convertToUpper sürecine büyük harfe dönüştürmek istediğimiz bazı metinler içeren tek bir girdi dosyası sağlamamız gerekiyor. Bunu yapmanın birçok yolu var: + +- Test için özel bir dosya oluşturabiliriz +- Mevcut data/greetings.csv dosyasını yeniden kullanabiliriz +- Test içinde anında oluşturabiliriz + +Şimdilik, pipeline seviyesi testinde kullandığımız örneği kullanarak mevcut data/greetings.csv dosyasını yeniden kullanalım. Daha önce olduğu gibi, testi test ettiğimiz şeyi daha iyi yansıtacak şekilde adlandırabiliriz, ancak bu sefer içeriği belirli dizeler için kontrol etmek yerine (diğer süreçte yaptığımız gibi) 'snapshot' ile bırakalım. + +**Önce:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10 11" + test("Should run without failures") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + // define inputs of the process here. Example: + // input[0] = file("test-file.txt") + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +**Sonra:** + +```groovy title="tests/main.converttoupper.nf.test" linenums="1" hl_lines="1 10" + test("Should run without failures and produce correct output") { + + when { + params { + // define parameters here. Example: + // outdir = "tests/results" + } + process { + """ + input[0] = "${projectDir}/greetings.csv" + """ + } + } + + then { + assert process.success + assert snapshot(process.out).match() + } + + } +``` + +Ve testi çalıştırın! + +```bash title="nf-test pipeline başarılı" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test süreci convertToUpper başarılı" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.755s) + Snapshots: + 1 created [Should run without failures and produce correct output] + + +Snapshot Summary: + 1 created + +SUCCESS: Executed 1 tests in 1.764s +``` + +Not: `tests/main.converttoupper.nf.test.snap` adresinde `convertToUpper` süreci için bir snapshot dosyası oluşturduk. Testi tekrar çalıştırırsak, nf-test'in tekrar geçtiğini görmeliyiz. + +```bash title="nf-test süreci convertToUpper başarılı" +nf-test test tests/main.converttoupper.nf.test +``` + +```console title="nf-test süreci convertToUpper başarılı" +> nf-test test tests/main.converttoupper.nf.test + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [c59b6044] 'Should run without failures and produce correct output' PASSED (1.798s) + + +SUCCESS: Executed 1 tests in 1.811s +``` + +### Çıkarım + +Bir Nextflow süreci için test yazmayı ve çalıştırmayı biliyorsunuz. + +### Sırada ne var? + +Her şey için aynı anda testleri nasıl çalıştıracağınızı öğrenin! + +## 3. Tüm depo için testleri çalıştırın + +Her bileşen üzerinde nf-test çalıştırmak iyidir, ancak zahmetli ve hataya açıktır. Her şeyi aynı anda test edemez miyiz? + +Evet yapabiliriz! + +Tüm repo üzerinde nf-test çalıştıralım. + +### 3.1. Tüm repo üzerinde nf-test çalıştırın + +`nf-test test` komutunu çalıştırarak tüm repo üzerinde nf-test çalıştırabiliriz. + +```bash +nf-test test . +``` + +Not: Her testi içerecek şekilde mevcut dizinimizden her şeyi çalıştırmak için sadece `.` kullanıyoruz! + +```console title="nf-test repo başarılı" +> nf-test test . + +🚀 nf-test 0.9.3 +https://www.nf-test.com +(c) 2021 - 2024 Lukas Forer and Sebastian Schoenherr + + +Test Process convertToUpper + + Test [3d26d9af] 'Should run without failures and produce correct output' PASSED (4.155s) + +Test Workflow main.nf + + Test [f183df37] 'Should run successfully with correct number of processes' PASSED (3.33s) + Test [d7e32a32] 'Should produce correct output files' PASSED (3.102s) + +Test Process sayHello + + Test [58df4e4b] 'Should run without failures and contain expected greeting' PASSED (2.614s) + + +SUCCESS: Executed 4 tests in 13.481s +``` + +Buna bakın! Tek bir komutla her süreç için 1 ve tüm pipeline için 2 olmak üzere 4 test çalıştırdık. Büyük bir kod tabanında bunun ne kadar güçlü olduğunu hayal edin! + +--- + +## Özet + +Bu yan görevde, bireysel süreçler için testler oluşturmanın yanı sıra tüm pipeline için uçtan uca testler oluşturmak üzere nf-test'in özelliklerinden yararlanmayı öğrendiniz. +Artık çıktı doğrulama için iki ana yaklaşımın, snapshot'ların ve doğrudan içerik onaylamalarının ve her birinin ne zaman kullanılacağının farkındasınız. +Ayrıca testleri tek tek veya tüm bir proje için nasıl çalıştıracağınızı biliyorsunuz. + +Bu teknikleri kendi çalışmanızda uygulamak şunları sağlamanıza olanak tanıyacaktır: + +- Kodunuzun beklendiği gibi çalışması +- Değişikliklerin mevcut işlevselliği bozmaması +- Diğer geliştiricilerin güvenle katkıda bulunabilmesi +- Sorunların hızlı bir şekilde tespit edilip düzeltilebilmesi +- Çıktı içeriğinin beklentileri karşılaması + +### Anahtar desenler + +1. Pipeline seviyesi testler: + - Temel başarı testi + - Süreç sayısı doğrulama + - Çıktı dosyası varlığı kontrolleri +2. Süreç seviyesi testler +3. Çıktı doğrulama için iki yaklaşım: + - Tam çıktı doğrulama için snapshot'lar kullanma + - Belirli içerik kontrolleri için doğrudan içerik onaylamaları kullanma +4. Tek bir komutla bir depodaki tüm testleri çalıştırma + +### Ek kaynaklar + +Daha gelişmiş test özellikleri ve en iyi uygulamalar için [nf-test dokümantasyonuna](https://www.nf-test.com/) göz atın. Şunları yapmak isteyebilirsiniz: + +- Testlerinize daha kapsamlı onaylamalar ekleyin +- Uç durumlar ve hata koşulları için testler yazın +- Testleri otomatik olarak çalıştırmak için sürekli entegrasyon kurun +- İş akışı ve modül testleri gibi diğer test türleri hakkında bilgi edinin +- Daha gelişmiş içerik doğrulama tekniklerini keşfedin + +**Unutmayın:** Testler, kodunuzun nasıl davranması gerektiğinin canlı dokümantasyonudur. Ne kadar çok test yazarsanız ve onaylamalarınız ne kadar spesifik olursa, pipeline'ınızın güvenilirliğinden o kadar emin olabilirsiniz. + +--- + +## Sırada ne var? + +[Yan Görevler menüsüne](./index.md) dönün veya listedeki bir sonraki konuya geçmek için sayfanın sağ altındaki düğmeye tıklayın. diff --git a/docs/tr/docs/side_quests/orientation.md b/docs/tr/docs/side_quests/orientation.md new file mode 100644 index 0000000000..5f955e66c1 --- /dev/null +++ b/docs/tr/docs/side_quests/orientation.md @@ -0,0 +1,53 @@ +# Yönlendirme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +GitHub Codespaces ortamı, bu eğitim kursunu tamamlamak için gerekli tüm yazılımları, kodları ve verileri içerir, bu nedenle kendiniz herhangi bir şey yüklemenize gerek yoktur. +Ancak, oturum açmak için (ücretsiz) bir hesaba ihtiyacınız var ve arayüze aşina olmak için birkaç dakikanızı ayırmalısınız. + +Henüz yapmadıysanız, lütfen daha ileri gitmeden önce [bu bağlantıyı](../../envsetup/) takip edin. + +## Sağlanan materyaller + +Bu eğitim kursu boyunca, `side-quests/` dizininde çalışacağız. +Bu dizin, ihtiyacınız olacak tüm kod dosyalarını, test verilerini ve ek dosyaları içerir. + +Bu dizinin içeriğini keşfetmekten çekinmeyin; bunu yapmanın en kolay yolu, GitHub Codespaces çalışma alanının sol tarafındaki dosya gezginini kullanmaktır. +Alternatif olarak, `tree` komutunu kullanabilirsiniz. +Kurs boyunca, dizin yapısını ve içeriğini okunabilir bir biçimde temsil etmek için `tree` çıktısını kullanıyoruz, bazen netlik için küçük değişikliklerle. + +Burada ikinci seviyeye kadar bir içindekiler tablosu oluşturuyoruz: + +```bash +tree . -L 2 +``` + +Bunu `side-quests` içinde çalıştırırsanız, aşağıdaki çıktıyı görmelisiniz: + +```console title="Dizin içeriği" +. +├── metadata +├── nf-core +├── nf-test +├── solutions +├── splitting_and_grouping +└── workflows_of_workflows +``` + +**Başlamak için bilmeniz gerekenler şunlardır:** + +- **Her dizin ayrı bir yan göreve karşılık gelir.** + İçerikleri ilgili yan görevin sayfasında ayrıntılı olarak açıklanmıştır. + +- **`solutions` dizini**, her yan görevin çeşitli adımlarını tamamlamaktan kaynaklanan tamamlanmış workflow ve/veya modül scriptlerini içerir. + Çalışmanızı kontrol etmek ve sorunları gidermek için referans olarak kullanılmaları amaçlanmıştır. + +!!!tip "İpucu" + + Herhangi bir nedenle bu dizinden çıkarsanız, buraya geri dönmek için her zaman bu komutu çalıştırabilirsiniz: + + ```bash + cd /workspaces/training/side-quests + ``` + +Şimdi, kursa başlamak için bu sayfanın sağ alt köşesindeki oka tıklayın. diff --git a/docs/tr/docs/side_quests/splitting_and_grouping.md b/docs/tr/docs/side_quests/splitting_and_grouping.md new file mode 100644 index 0000000000..c0f201074a --- /dev/null +++ b/docs/tr/docs/side_quests/splitting_and_grouping.md @@ -0,0 +1,1251 @@ +# Bölme ve Gruplama + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Nextflow, verilerle esnek bir şekilde çalışmak için güçlü araçlar sağlar. Temel bir özellik, verileri farklı akışlara bölmek ve ardından ilişkili öğeleri tekrar birleştirmektir. Bu, özellikle analiz için sonuçları birleştirmeden önce farklı örnek türlerini ayrı ayrı işlemeniz gereken biyoinformatik iş akışlarında değerlidir. + +Bunu mektup sıralama gibi düşünün: mektupları varış yerine göre ayırırsınız, her yığını farklı şekilde işlersiniz, ardından aynı kişiye giden öğeleri yeniden birleştirirsiniz. Nextflow, bilimsel verilerle bunu başarmak için özel operatörler kullanır. Bu yaklaşım aynı zamanda dağıtık hesaplama ve biyoinformatik iş akışlarında yaygın olarak **scatter/gather** deseni olarak bilinir. + +Nextflow'un channel sistemi bu esnekliğin merkezindedir. Channel'lar iş akışınızın farklı bölümlerini bağlayarak verilerin analiziniz boyunca akmasını sağlar. Tek bir veri kaynağından birden fazla channel oluşturabilir, her channel'ı farklı şekilde işleyebilir ve gerektiğinde channel'ları tekrar birleştirebilirsiniz. Bu yaklaşım, karmaşık biyoinformatik analizlerin dallanma ve birleşme yollarını doğal olarak yansıtan iş akışları tasarlamanıza olanak tanır. + +### Öğrenme hedefleri + +Bu yan görevde, Nextflow'un channel operatörlerini kullanarak verileri bölmeyi ve gruplamayı öğreneceksiniz. +Örnek bilgileri ve ilişkili veri dosyalarını içeren bir CSV dosyasıyla başlayacak, ardından bu verileri manipüle edip yeniden düzenleyeceğiz. + +Bu yan görevin sonunda, aşağıdaki teknikleri kullanarak veri akışlarını etkili bir şekilde ayırıp birleştirebileceksiniz: + +- `splitCsv` kullanarak dosyalardan veri okuma +- `filter` ve `map` ile verileri filtreleme ve dönüştürme +- `join` ve `groupTuple` kullanarak ilişkili verileri birleştirme +- Paralel işleme için `combine` ile veri kombinasyonları oluşturma +- `subMap` ve tekilleştirme stratejileri kullanarak veri yapısını optimize etme +- Channel yapılarını manipüle etmenize yardımcı olacak adlandırılmış closure'lar ile yeniden kullanılabilir fonksiyonlar oluşturma + +Bu beceriler, temiz ve bakımı kolay kod yapısını korurken birden fazla girdi dosyası ve farklı veri türlerini verimli bir şekilde işleyebilen iş akışları oluşturmanıza yardımcı olacaktır. + +### Ön koşullar + +Bu yan göreve başlamadan önce: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramları ve mekanizmalarını (process'ler, channel'lar, operatörler, dosyalarla çalışma, meta veri) rahatça kullanabiliyor olmalısınız + +**İsteğe bağlı:** Önce [İş akışlarında meta veri](./metadata.md) yan görevini tamamlamanızı öneririz. +Bu, burada yoğun şekilde kullanacağımız `splitCsv` ile CSV dosyalarını okuma ve meta map oluşturma temellerini kapsar. + +--- + +## 0. Başlangıç + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md)'nda açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine geçin + +Bu eğitim için dosyaların bulunduğu dizine geçelim. + +```bash +cd side-quests/splitting_and_grouping +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri inceleyin + +Bir ana workflow dosyası ve `samplesheet.csv` adlı bir örnek sayfası içeren bir `data` dizini bulacaksınız. + +```console title="Dizin içeriği" +. +├── data +│ └── samplesheet.csv +└── main.nf +``` + +Örnek sayfası, hasta kimliği, örnek tekrar numarası, tür (normal veya tümör) ve varsayımsal veri dosyalarına giden yollar (gerçekte mevcut değil, ancak varmış gibi davranacağız) dahil olmak üzere farklı hastalardan alınan örnekler hakkında bilgi içerir. + +```console title="samplesheet.csv" +id,repeat,type,bam +patientA,1,normal,patientA_rep1_normal.bam +patientA,1,tumor,patientA_rep1_tumor.bam +patientA,2,normal,patientA_rep2_normal.bam +patientA,2,tumor,patientA_rep2_tumor.bam +patientB,1,normal,patientB_rep1_normal.bam +patientB,1,tumor,patientB_rep1_tumor.bam +patientC,1,normal,patientC_rep1_normal.bam +patientC,1,tumor,patientC_rep1_tumor.bam +``` + +Bu örnek sayfası, üç hastadan (A, B, C) sekiz örnek listeler. + +Her hasta için `tumor` (genellikle tümör biyopsilerinden kaynaklanan) veya `normal` (sağlıklı doku veya kandan alınan) türünde örneklerimiz var. +Kanser analiziyle tanışık değilseniz, bunun karşılaştırmalı analizler gerçekleştirmek için eşleştirilmiş tümör/normal örnekleri kullanan deneysel bir modele karşılık geldiğini bilin. + +Özellikle A hastası için iki set teknik replik (tekrar) var. + +!!! note "Not" + + Bu deneysel tasarıma aşina değilseniz endişelenmeyin, bu eğitimi anlamak için kritik değil. + +#### Görevi inceleyin + +Göreviniz şunları yapacak bir Nextflow iş akışı yazmaktır: + +1. Bir CSV dosyasından örnek verilerini **okuma** ve meta map'lerle yapılandırma +2. Türe göre (normal vs tümör) örnekleri farklı channel'lara **ayırma** +3. Hasta kimliği ve replik numarasına göre eşleşen tümör/normal çiftlerini **birleştirme** +4. Paralel işleme için örnekleri genomik aralıklara **dağıtma** +5. Aşağı akış analizi için ilişkili örnekleri tekrar **gruplama** + +Bu, verileri bağımsız işleme için bölmeniz ve ardından karşılaştırmalı analiz için ilişkili öğeleri yeniden birleştirmeniz gereken yaygın bir biyoinformatik desenidir. + +#### Hazırlık kontrol listesi + +Başlamaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışıyor +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] Görevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Örnek verilerini okuma + +### 1.1. `splitCsv` ile örnek verilerini okuma ve meta map'ler oluşturma + +`splitCsv` ile örnek verilerini okuyarak ve meta map deseninde organize ederek başlayalım. `main.nf` dosyasında, iş akışını zaten başlattığımızı göreceksiniz. + +```groovy title="main.nf" linenums="1" hl_lines="2" +workflow { + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") +} +``` + +!!! note "Not" + + Bu eğitim boyunca, Nextflow channel'ları olduklarını açıkça belirtmek için tüm channel değişkenleri için `ch_` önekini kullanacağız. + +[İş akışlarında meta veri](./metadata.md) yan görevini tamamladıysanız, bu deseni tanıyacaksınız. Meta veriyi dosya yollarından ayırmak için CSV'yi okumak ve verileri hemen bir meta map ile yapılandırmak için `splitCsv` kullanacağız. + +!!! info "Bilgi" + + Bu eğitimde `map` olarak adlandırılan iki farklı kavramla karşılaşacağız: + + - **Veri yapısı**: Anahtar-değer çiftlerini saklayan Groovy map (diğer dillerdeki sözlükler/hash'ler ile eşdeğer) + - **Channel operatörü**: Bir channel'daki öğeleri dönüştüren `.map()` operatörü + + Bağlamda hangisini kastettiğimizi açıklayacağız, ancak Nextflow ile çalışırken bu ayrımı anlamak önemlidir. + +Bu değişiklikleri `main.nf` dosyasına uygulayın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="2-6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="1" + ch_samplesheet = channel.fromPath("./data/samplesheet.csv") + ``` + +Bu, `splitCsv` işlemini (başlıklarla CSV'yi okuma) ve `map` işlemini (verileri `[meta, file]` tuple'ları olarak yapılandırma) tek adımda birleştirir. Bu değişikliği uygulayın ve pipeline'ı çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [deadly_mercator] DSL2 - revision: bd6b0224e9 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Artık her öğenin bir `[meta, file]` tuple'ı olduğu bir channel'ımız var - meta veri dosya yollarından ayrılmış durumda. Bu yapı, meta veri alanlarına göre iş yükümüzü bölmemize ve gruplamamıza olanak tanır. + +--- + +## 2. Verileri filtreleme ve dönüştürme + +### 2.1. `filter` ile verileri filtreleme + +Bir koşula göre verileri filtrelemek için [`filter` operatörünü](https://www.nextflow.io/docs/latest/operator.html#filter) kullanabiliriz. Diyelim ki sadece normal örnekleri işlemek istiyoruz. Bunu `type` alanına göre verileri filtreleyerek yapabiliriz. Bunu `view` operatöründen önce ekleyelim. + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="6" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .view() + ``` + +Filtrelenmiş sonucu görmek için iş akışını tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [admiring_brown] DSL2 - revision: 194d61704d + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Verileri başarıyla sadece normal örnekleri içerecek şekilde filtreledik. Bunun nasıl çalıştığını özetleyelim. + +`filter` operatörü, channel'daki her öğeye uygulanan bir closure alır. Closure `true` döndürürse, öğe dahil edilir; `false` döndürürse, öğe hariç tutulur. + +Bizim durumumuzda, sadece `meta.type == 'normal'` olan örnekleri tutmak istiyoruz. Closure, her örneğe başvurmak için `meta,file` tuple'ını kullanır, `meta.type` ile örnek türüne erişir ve `'normal'`'e eşit olup olmadığını kontrol eder. + +Bu, yukarıda tanıttığımız tek closure ile gerçekleştirilir: + +```groovy title="main.nf" linenums="7" + .filter { meta, file -> meta.type == 'normal' } +``` + +### 2.2. Ayrı filtrelenmiş channel'lar oluşturma + +Şu anda filtreyi doğrudan CSV'den oluşturulan channel'a uyguluyoruz, ancak bunu birden fazla şekilde filtrelemek istiyoruz, bu yüzden mantığı normal örnekler için ayrı bir filtrelenmiş channel oluşturmak üzere yeniden yazalım: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="6 8" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + .filter { meta, file -> meta.type == 'normal' } + .view() + ``` + +Sonuçları görmek için pipeline'ı çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [trusting_poisson] DSL2 - revision: 639186ee74 + + [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Verileri başarıyla filtreledik ve normal örnekler için ayrı bir channel oluşturduk. + +Tümör örnekleri için de filtrelenmiş bir channel oluşturalım: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3-8" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal örnek: ' + it} + ch_tumor_samples + .view{'Tümör örnek: ' + it} + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3 4" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_normal_samples + .view() + ``` + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tümör örnek: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tümör örnek: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal örnek: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal örnek: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal örnek: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal örnek: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tümör örnek: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tümör örnek: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Normal ve tümör örneklerini iki farklı channel'a ayırdık ve çıktıda farklı şekilde etiketlemek için `view()`'a bir closure sağladık: `ch_tumor_samples.view{'Tümör örnek: ' + it}`. + +### Özet + +Bu bölümde öğrendikleriniz: + +- **Verileri filtreleme**: `filter` ile verileri nasıl filtreleyeceğiniz +- **Verileri bölme**: Bir koşula göre verileri farklı channel'lara nasıl böleceğiniz +- **Verileri görüntüleme**: `view` kullanarak verileri yazdırma ve farklı channel'lardan çıktıları nasıl etiketleyeceğiniz + +Artık normal ve tümör örneklerini iki farklı channel'a ayırdık. Şimdi normal ve tümör örneklerini `id` alanına göre birleştireceğiz. + +--- + +## 3. Channel'ları tanımlayıcılara göre birleştirme + +Önceki bölümde, normal ve tümör örneklerini iki farklı channel'a ayırdık. Bunlar türlerine göre belirli process'ler veya iş akışları kullanılarak bağımsız olarak işlenebilir. Ancak aynı hastadan normal ve tümör örneklerini karşılaştırmak istediğimizde ne olur? Bu noktada, örnekleri `id` alanına göre eşleştirerek tekrar birleştirmemiz gerekir. + +Nextflow, channel'ları birleştirmek için birçok yöntem içerir, ancak bu durumda en uygun operatör [`join`](https://www.nextflow.io/docs/latest/operator.html#join)'dir. SQL'e aşinaysanız, birleştirme anahtarını ve gerçekleştirilecek birleştirme türünü belirttiğimiz `JOIN` işlemi gibi çalışır. + +### 3.1. Hasta kimliğine göre birleştirmek için `map` ve `join` kullanma + +[`join`](https://www.nextflow.io/docs/latest/operator.html#join) belgelerine bakarsak, varsayılan olarak her tuple'daki ilk öğeye göre iki channel'ı birleştirdiğini görebiliriz. + +#### 3.1.1. Veri yapısını kontrol etme + +Konsol çıktısı hala mevcut değilse, veri yapımızı kontrol etmek ve `id` alanına göre birleştirmek için nasıl değiştirmemiz gerektiğini görmek için pipeline'ı çalıştıralım. + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [maniac_boltzmann] DSL2 - revision: 3636b6576b + + Tümör örnek: [[id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tümör örnek: [[id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal örnek: [[id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal örnek: [[id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Normal örnek: [[id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal örnek: [[id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + Tümör örnek: [[id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tümör örnek: [[id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +`id` alanının her meta map'teki ilk öğe olduğunu görebiliriz. `join`'in çalışması için her tuple'daki `id` alanını izole etmeliyiz. Bundan sonra, iki channel'ı birleştirmek için `join` operatörünü kolayca kullanabiliriz. + +#### 3.1.2. `id` alanını izole etme + +`id` alanını izole etmek için, ilk öğe olarak `id` alanıyla yeni bir tuple oluşturmak üzere [`map` operatörünü](https://www.nextflow.io/docs/latest/operator.html#map) kullanabiliriz. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal örnek: ' + it} + ch_tumor_samples + .view{'Tümör örnek: ' + it} + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + ch_normal_samples + .view{'Normal örnek: ' + it} + ch_tumor_samples + .view{'Tümör örnek: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mad_lagrange] DSL2 - revision: 9940b3f23d + + Tümör örnek: [patientA, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + Tümör örnek: [patientA, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + Normal örnek: [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam] + Normal örnek: [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam] + Tümör örnek: [patientB, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + Tümör örnek: [patientC, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + Normal örnek: [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam] + Normal örnek: [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam] + ``` + +Belki de ince bir fark, ancak her tuple'daki ilk öğenin `id` alanı olduğunu görmelisiniz. + +#### 3.1.3. İki channel'ı birleştirme + +Artık `id` alanına göre iki channel'ı birleştirmek için `join` operatörünü kullanabiliriz. + +Bir kez daha, birleştirilmiş çıktıları yazdırmak için `view` kullanacağız. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="7-9" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_joined_samples = ch_normal_samples + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="7-10" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ch_normal_samples + .view{'Normal örnek: ' + it} + ch_tumor_samples + .view{'Tümör örnek: ' + it} + ``` + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_wiles] DSL2 - revision: 3bc1979889 + + [patientA, [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [patientA, [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [patientB, [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [patientC, [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Çok geniş olduğu için söylemek biraz zor, ancak örneklerin `id` alanına göre birleştirildiğini görmelisiniz. Her tuple artık şu formata sahip: + +- `id`: Örnek kimliği +- `normal_meta_map`: Tür, replik ve bam dosyası yolu dahil normal örnek meta verisi +- `normal_sample_file`: Normal örnek dosyası +- `tumor_meta_map`: Tür, replik ve bam dosyası yolu dahil tümör örnek meta verisi +- `tumor_sample`: Tür, replik ve bam dosyası yolu dahil tümör örneği + +!!! warning "Uyarı" + + `join` operatörü eşleşmeyen tuple'ları atacaktır. Bu örnekte, tüm örneklerin tümör ve normal için eşleştirildiğinden emin olduk, ancak bu doğru değilse eşleşmeyen tuple'ları tutmak için `remainder: true` parametresini kullanmanız gerekir. Daha fazla ayrıntı için [belgelere](https://www.nextflow.io/docs/latest/operator.html#join) bakın. + +Artık bir tuple'daki bir alanı izole etmek için `map`'i ve tuple'ları ilk alana göre birleştirmek için `join`'i nasıl kullanacağınızı biliyorsunuz. +Bu bilgiyle, paylaşılan bir alana göre channel'ları başarıyla birleştirebilirsiniz. + +Şimdi, birden fazla alanda birleştirmek istediğiniz durumu ele alacağız. + +### 3.2. Birden fazla alanda birleştirme + +ÖrnekA için 2 replikimiz var, ancak örnekB ve örnekC için sadece 1'er tane. Bu durumda `id` alanını kullanarak bunları etkili bir şekilde birleştirebildik, ancak eşzamanlı olmasalardı ne olurdu? Farklı repliklerden normal ve tümör örneklerini karıştırabilirdik! + +Bunu önlemek için birden fazla alanda birleştirme yapabiliriz. Bunu başarmanın aslında birden fazla yolu var, ancak hem örnek `id`'sini hem de `replicate` numarasını içeren yeni bir birleştirme anahtarı oluşturmaya odaklanacağız. + +Yeni bir birleştirme anahtarı oluşturarak başlayalım. Bunu, ilk öğe olarak `id` ve `repeat` alanlarıyla yeni bir tuple oluşturmak için [`map` operatörünü](https://www.nextflow.io/docs/latest/operator.html#map) kullanarak daha önce yaptığımız gibi yapabiliriz. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.id, meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.id, meta, file] } + ``` + +Şimdi birleştirmenin hem `id` hem de `repeat` alanlarını kullanarak gerçekleştiğini görmeliyiz. İş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_wing] DSL2 - revision: 3bebf22dee + + [[patientA, 1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[patientA, 2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[patientB, 1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[patientC, 1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Her birleştirilmiş sonucun ilk öğesi olarak iki öğeli bir tuple (`id` ve `repeat` alanları) olduğunu not edin. Bu, karmaşık öğelerin birleştirme anahtarı olarak nasıl kullanılabileceğini gösterir ve aynı koşullardan gelen örnekler arasında oldukça karmaşık eşleştirme sağlar. + +Farklı anahtarlarda birleştirmenin daha fazla yolunu keşfetmek istiyorsanız, ek seçenekler ve örnekler için [join operatörü belgelerine](https://www.nextflow.io/docs/latest/operator.html#join) bakın. + +### 3.3. Yeni bir birleştirme anahtarı oluşturmak için `subMap` kullanma + +Önceki yaklaşım, birleştirme anahtarımızdaki alan adlarını kaybeder - `id` ve `repeat` alanları sadece bir değerler listesi haline gelir. Daha sonra erişim için alan adlarını korumak için [`subMap` metodunu](<https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#subMap(java.util.Collection)>) kullanabiliriz. + +`subMap` metodu, bir map'ten yalnızca belirtilen anahtar-değer çiftlerini çıkarır. Burada birleştirme anahtarımızı oluşturmak için sadece `id` ve `repeat` alanlarını çıkaracağız. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [[meta.id, meta.repeat], meta, file] } + ``` + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [reverent_wing] DSL2 - revision: 847016c3b7 + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Artık yalnızca `id` ve `repeat` alanlarını içeren değil, aynı zamanda alan adlarını koruyan yeni bir birleştirme anahtarımız var, böylece daha sonra bunlara `meta.id` ve `meta.repeat` gibi adla erişebiliriz. + +### 3.4. map'te adlandırılmış closure kullanma + +Çoğaltmayı önlemek ve hataları azaltmak için adlandırılmış bir closure kullanabiliriz. Adlandırılmış bir closure, birden fazla yerde çağırabileceğimiz yeniden kullanılabilir bir fonksiyon oluşturmamıza olanak tanır. + +Bunu yapmak için, önce closure'ı yeni bir değişken olarak tanımlarız: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="7" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + ``` + +Map dönüşümünü yeniden kullanabileceğimiz adlandırılmış bir değişken olarak tanımladık. + +Ayrıca dosya yolunu `file()` kullanarak bir Path nesnesine dönüştürdüğümüzü not edin, böylece bu channel'ı alan herhangi bir process dosyayı doğru şekilde işleyebilir (daha fazla bilgi için [Dosyalarla çalışma](./working_with_files.md)'ya bakın). + +Closure'ı iş akışımızda uygulayalım: + +=== "Sonra" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map ( getSampleIdAndReplicate ) + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map ( getSampleIdAndReplicate ) + + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="10" hl_lines="3 6" + ch_normal_samples = ch_samples + .filter { meta, file -> meta.type == 'normal' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ch_tumor_samples = ch_samples + .filter { meta, file -> meta.type == 'tumor' } + .map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ``` + +!!! note "Not" + + `map` operatörü closure'ı argüman olarak geçirmek için `{ }` yerine `( )` kullanmaya geçti. Bunun nedeni, `map` operatörünün argüman olarak bir closure beklemesi ve `{ }` işaretinin anonim bir closure tanımlamak için kullanılmasıdır. Adlandırılmış bir closure çağırırken `( )` sözdizimini kullanın. + +Her şeyin hala çalıştığını kontrol etmek için iş akışını bir kez daha çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_meninsky] DSL2 - revision: 2edc226b1d + + [[id:patientA, repeat:1], [id:patientA, repeat:1, type:normal], patientA_rep1_normal.bam, [id:patientA, repeat:1, type:tumor], patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [id:patientA, repeat:2, type:normal], patientA_rep2_normal.bam, [id:patientA, repeat:2, type:tumor], patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [id:patientB, repeat:1, type:normal], patientB_rep1_normal.bam, [id:patientB, repeat:1, type:tumor], patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [id:patientC, repeat:1, type:normal], patientC_rep1_normal.bam, [id:patientC, repeat:1, type:tumor], patientC_rep1_tumor.bam] + ``` + +Adlandırılmış bir closure kullanmak, aynı dönüşümü birden fazla yerde yeniden kullanmamıza olanak tanır, hata riskini azaltır ve kodu daha okunabilir ve bakımı kolay hale getirir. + +### 3.5. Veri çoğaltmasını azaltma + +İş akışımızda çok fazla çoğaltılmış veri var. Birleştirilmiş örneklerdeki her öğe `id` ve `repeat` alanlarını tekrarlar. Bu bilgi zaten gruplama anahtarında mevcut olduğundan, bu fazlalıktan kaçınabiliriz. Hatırlatma olarak, mevcut veri yapımız şöyle görünüyor: + +```groovy +[ + [ + "id": "sampleC", + "repeat": "1", + ], + [ + "id": "sampleC", + "repeat": "1", + "type": "normal", + ], + "sampleC_rep1_normal.bam" + [ + "id": "sampleC", + "repeat": "1", + "type": "tumor", + ], + "sampleC_rep1_tumor.bam" +] +``` + +`id` ve `repeat` alanları gruplama anahtarında mevcut olduğundan, çoğaltmayı önlemek için bunları her channel öğesinin geri kalanından kaldıralım. Bunu, yalnızca `type` alanıyla yeni bir map oluşturmak için `subMap` metodunu kullanarak yapabiliriz. Bu yaklaşım, veri yapımızdaki fazlalığı ortadan kaldırırken tüm gerekli bilgileri korumamıza olanak tanır. + +=== "Sonra" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file(bam) ] } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, bam -> [ meta.subMap(['id', 'repeat']), meta, file(bam) ] } + ``` + +Şimdi closure, ilk öğenin `id` ve `repeat` alanlarını, ikinci öğenin sadece `type` alanını içerdiği bir tuple döndürüyor. Bu, `id` ve `repeat` bilgilerini gruplama anahtarında bir kez saklayarak fazlalığı ortadan kaldırır ve tüm gerekli bilgileri korur. + +Bunun nasıl göründüğünü görmek için iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + [[id:patientA, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], [type:normal], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_normal.bam, [type:tumor], /workspaces/training/side-quests/splitting_and_grouping/patientC_rep1_tumor.bam] + ``` + +`id` ve `repeat` alanlarını gruplama anahtarında yalnızca bir kez belirttiğimizi ve örnek verisinde `type` alanına sahip olduğumuzu görebiliriz. Hiçbir bilgi kaybetmedik ama channel içeriklerimizi daha öz hale getirmeyi başardık. + +### 3.6. Gereksiz bilgileri kaldırma + +Yukarıda çoğaltılmış bilgileri kaldırdık, ancak channel'larımızda hala başka gereksiz bilgiler var. + +Başlangıçta, `filter` kullanarak normal ve tümör örneklerini ayırdık, ardından `id` ve `repeat` anahtarlarına göre birleştirdik. `join` operatörü tuple'ların birleştirildiği sırayı korur, bu nedenle bizim durumumuzda, normal örnekler sol tarafta ve tümör örnekleri sağ tarafta, ortaya çıkan channel bu yapıyı korur: `id, <normal öğeleri>, <tümör öğeleri>`. + +Channel'ımızdaki her öğenin konumunu bildiğimiz için, `[type:normal]` ve `[type:tumor]` meta verilerini bırakarak yapıyı daha da basitleştirebiliriz. + +=== "Sonra" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), file ] } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="8" hl_lines="1" + getSampleIdAndReplicate = { meta, file -> [ meta.subMap(['id', 'repeat']), meta.subMap(['type']), file ] } + ``` + +Sonucu görmek için tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [confident_leavitt] DSL2 - revision: a2303895bd + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +### Özet + +Bu bölümde öğrendikleriniz: + +- **Tuple'ları manipüle etme**: Bir tuple'daki bir alanı izole etmek için `map` nasıl kullanılır +- **Tuple'ları birleştirme**: Tuple'ları ilk alana göre birleştirmek için `join` nasıl kullanılır +- **Birleştirme anahtarları oluşturma**: Yeni bir birleştirme anahtarı oluşturmak için `subMap` nasıl kullanılır +- **Adlandırılmış Closure'lar**: map'te adlandırılmış bir closure nasıl kullanılır +- **Çoklu alan birleştirme**: Daha hassas eşleştirme için birden fazla alanda nasıl birleştirme yapılır +- **Veri yapısı optimizasyonu**: Gereksiz bilgileri kaldırarak channel yapısı nasıl düzenlenir + +Artık bir örnek sayfasını bölebilen, normal ve tümör örneklerini filtreleyebilen, bunları örnek kimliği ve replik numarasına göre birleştirebilen ve sonuçları yazdırabilen bir iş akışınız var. + +Bu, bağımsız olarak işledikten sonra örnekleri veya diğer veri türlerini eşleştirmeniz gereken biyoinformatik iş akışlarında yaygın bir desendir, bu yüzden yararlı bir beceridir. Şimdi, bir örneği birden fazla kez tekrarlamaya bakacağız. + +## 4. Örnekleri aralıklara yayma + +Biyoinformatik iş akışlarında temel bir desen, analizi genomik bölgelere dağıtmaktır. Örneğin, varyant çağırma, genomu aralıklara (kromozomlar veya daha küçük bölgeler gibi) bölerek paralelleştirilebilir. Bu paralelleştirme stratejisi, hesaplama yükünü birden fazla çekirdeğe veya düğüme dağıtarak pipeline verimliliğini önemli ölçüde artırır ve toplam yürütme süresini azaltır. + +Aşağıdaki bölümde, örnek verilerimizi birden fazla genomik aralığa nasıl dağıtacağımızı göstereceğiz. Her örneği her aralıkla eşleştireceğiz, bu da farklı genomik bölgelerin paralel işlenmesine olanak tanır. Bu, veri kümemizin boyutunu aralık sayısıyla çarpacak ve daha sonra bir araya getirilebilecek birden fazla bağımsız analiz birimi oluşturacaktır. + +### 4.1. `combine` kullanarak örnekleri aralıklara yayma + +Bir aralık channel'ı oluşturarak başlayalım. İşleri basit tutmak için, manuel olarak tanımlayacağımız sadece 3 aralık kullanacağız. Gerçek bir iş akışında, bunları bir dosya girdisinden okuyabilir veya hatta çok sayıda aralık dosyasıyla bir channel oluşturabilirsiniz. + +=== "Sonra" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="17" hl_lines="2" + .join(ch_tumor_samples) + ch_joined_samples.view() + ``` + +Şimdi hatırlayın, her örneği her aralık için tekrarlamak istiyoruz. Bu bazen örneklerin ve aralıkların Kartezyen çarpımı olarak adlandırılır. Bunu [`combine` operatörünü](https://www.nextflow.io/docs/latest/operator.html#combine) kullanarak başarabiliriz. Bu, channel 1'den her öğeyi alacak ve channel 2'deki her öğe için tekrarlayacaktır. İş akışımıza bir combine operatörü ekleyelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="18" hl_lines="3-5" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="18" + ch_intervals = channel.of('chr1', 'chr2', 'chr3') + ``` + +Şimdi çalıştıralım ve ne olduğunu görelim: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [mighty_tesla] DSL2 - revision: ae013ab70b + + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr1] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr2] + [[id:patientA, repeat:1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam, chr3] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr1] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr2] + [[id:patientA, repeat:2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam, chr3] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr1] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr2] + [[id:patientB, repeat:1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam, chr3] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr1] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr2] + [[id:patientC, repeat:1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam, chr3] + ``` + +Başarılı! Her örneği 3 aralıklık listemizdeki her bir aralık için tekrarladık. Channel'ımızdaki öğe sayısını etkili bir şekilde üçe katladık. + +Okumak biraz zor olsa da, bir sonraki bölümde düzenleyeceğiz. + +### 4.2. Channel'ı düzenleme + +Örnek verilerimizi daha kolay anlaşılır hale getirmek için `map` operatörünü kullanarak düzenleyip yeniden yapılandırabiliriz. Aralık dizesini ilk öğedeki birleştirme map'ine taşıyalım. + +=== "Sonra" + + ```groovy title="main.nf" linenums="20" hl_lines="3-9" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="20" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .view() + ``` + +Bu map işleminin adım adım ne yaptığını açıklayalım. + +İlk olarak, kodu daha okunabilir hale getirmek için adlandırılmış parametreler kullanıyoruz. `grouping_key`, `normal`, `tumor` ve `interval` adlarını kullanarak, tuple'daki öğelere dizin yerine adla başvurabiliriz: + +```groovy + .map { grouping_key, normal, tumor, interval -> +``` + +Ardından, `grouping_key`'i `interval` alanıyla birleştiriyoruz. `grouping_key`, `id` ve `repeat` alanlarını içeren bir map'tir. `interval` ile yeni bir map oluşturuyoruz ve Groovy'nin map toplama (`+`) işlemini kullanarak bunları birleştiriyoruz: + +```groovy + grouping_key + [interval: interval], +``` + +Son olarak, bunu üç öğeli bir tuple olarak döndürüyoruz: birleştirilmiş meta veri map'i, normal örnek dosyası ve tümör örnek dosyası: + +```groovy + [ + grouping_key + [interval: interval], + normal, + tumor + ] +``` + +Tekrar çalıştıralım ve channel içeriklerini kontrol edelim: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [sad_hawking] DSL2 - revision: 1f6f6250cd + + [[id:patientA, repeat:1, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:1, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, repeat:2, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, repeat:2, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, repeat:1, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, repeat:1, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, repeat:1, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +Verilerinizi doğru yapıya zorlamak için `map` kullanmak zor olabilir, ancak etkili veri manipülasyonu için çok önemlidir. + +Artık her örneği tüm genomik aralıklarda tekrarladık, paralel olarak işlenebilecek birden fazla bağımsız analiz birimi oluşturduk. Peki ya ilişkili örnekleri tekrar bir araya getirmek istersek? Bir sonraki bölümde, ortak özellikleri paylaşan örnekleri nasıl gruplayacağımızı öğreneceğiz. + +### Özet + +Bu bölümde öğrendikleriniz: + +- **Örnekleri aralıklara yayma**: Örnekleri aralıklara yaymak için `combine` nasıl kullanılır +- **Kartezyen çarpımlar oluşturma**: Örneklerin ve aralıkların tüm kombinasyonları nasıl oluşturulur +- **Channel yapısını düzenleme**: Daha iyi okunabilirlik için verileri yeniden yapılandırmak üzere `map` nasıl kullanılır +- **Paralel işleme hazırlığı**: Dağıtık analiz için veriler nasıl ayarlanır + +## 5. `groupTuple` kullanarak örnekleri toplama + +Önceki bölümlerde, bir girdi dosyasından verileri bölmeyi ve belirli alanlara göre filtrelemeyi (bizim durumumuzda normal ve tümör örnekleri) öğrendik. Ancak bu yalnızca tek bir birleştirme türünü kapsar. Ya örnekleri belirli bir özelliğe göre gruplamak istersek? Örneğin, eşleşen normal-tümör çiftlerini birleştirmek yerine, türlerine bakılmaksızın "sampleA"dan tüm örnekleri birlikte işlemek isteyebiliriz. Bu desen, verimlilik nedenleriyle ilişkili örnekleri ayrı ayrı işlemek ve sonunda sonuçları karşılaştırmak veya birleştirmek istediğiniz biyoinformatik iş akışlarında yaygındır. + +Nextflow bunu yapmak için yerleşik yöntemler içerir, bakacağımız ana yöntem `groupTuple`'dır. + +Aynı `id` ve `interval` alanlarına sahip tüm örneklerimizi gruplayarak başlayalım, bu teknik replikleri gruplamak istediğimiz ancak anlamlı olarak farklı örnekleri ayrı tutmak istediğimiz bir analizin tipik örneği olur. + +Bunu yapmak için, gruplama değişkenlerimizi izole etmek için ayırmalıyız. + +İlk adım, önceki bölümde yaptığımıza benzer. Gruplama değişkenimizi tuple'ın ilk öğesi olarak izole etmeliyiz. Hatırlayın, ilk öğemiz şu anda `id`, `repeat` ve `interval` alanlarının bir map'i: + +```groovy title="main.nf" linenums="1" +{ + "id": "sampleA", + "repeat": "1", + "interval": "chr1" +} +``` + +`id` ve `interval` alanlarımızı map'ten izole etmek için daha önceki `subMap` metodunu yeniden kullanabiliriz. Daha önce olduğu gibi, her örnek için tuple'ın ilk öğesine `subMap` metodunu uygulamak için `map` operatörünü kullanacağız. + +=== "Sonra" + + ```groovy title="main.nf" linenums="20" hl_lines="11-19" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="20" hl_lines="10" + ch_combined_samples = ch_joined_samples + .combine(ch_intervals) + .map { grouping_key, normal, tumor, interval -> + [ + grouping_key + [interval: interval], + normal, + tumor + ] + } + .view() + ``` + +Channel içeriklerini kontrol etmek için tekrar çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [hopeful_brenner] DSL2 - revision: 7f4f7fea76 + + [[id:patientA, interval:chr1], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr2], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr3], patientA_rep1_normal.bam, patientA_rep1_tumor.bam] + [[id:patientA, interval:chr1], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, interval:chr2], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientA, interval:chr3], patientA_rep2_normal.bam, patientA_rep2_tumor.bam] + [[id:patientB, interval:chr1], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, interval:chr2], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientB, interval:chr3], patientB_rep1_normal.bam, patientB_rep1_tumor.bam] + [[id:patientC, interval:chr1], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, interval:chr2], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + [[id:patientC, interval:chr3], patientC_rep1_normal.bam, patientC_rep1_tumor.bam] + ``` + +`id` ve `interval` alanlarını başarıyla izole ettiğimizi ancak örnekleri henüz gruplamadığımızı görebiliriz. + +!!! note "Not" + + Burada `replicate` alanını atıyoruz. Bunun nedeni, daha aşağı akış işleme için buna ihtiyacımız olmamasıdır. Bu eğitimi tamamladıktan sonra, sonraki gruplamayı etkilemeden bunu dahil edip edemeyeceğinize bakın! + +Şimdi [`groupTuple` operatörünü](https://www.nextflow.io/docs/latest/operator.html#grouptuple) kullanarak örnekleri bu yeni gruplama öğesine göre gruplayalım. + +=== "Sonra" + + ```groovy title="main.nf" linenums="30" hl_lines="9" + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .groupTuple() + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="30" + ch_grouped_samples = ch_combined_samples + .map { grouping_key, normal, tumor -> + [ + grouping_key.subMap('id', 'interval'), + normal, + tumor + ] + } + .view() + ``` + +Hepsi bu kadar! Sadece tek bir satır kod ekledik. Çalıştırdığımızda ne olacağını görelim: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_jang] DSL2 - revision: a1bee1c55d + + [[id:patientA, interval:chr1], [patientA_rep1_normal.bam, patientA_rep2_normal.bam], [patientA_rep1_tumor.bam, patientA_rep2_tumor.bam]] + [[id:patientA, interval:chr2], [patientA_rep1_normal.bam, patientA_rep2_normal.bam], [patientA_rep1_tumor.bam, patientA_rep2_tumor.bam]] + [[id:patientA, interval:chr3], [patientA_rep1_normal.bam, patientA_rep2_normal.bam], [patientA_rep1_tumor.bam, patientA_rep2_tumor.bam]] + [[id:patientB, interval:chr1], [patientB_rep1_normal.bam], [patientB_rep1_tumor.bam]] + [[id:patientB, interval:chr2], [patientB_rep1_normal.bam], [patientB_rep1_tumor.bam]] + [[id:patientB, interval:chr3], [patientB_rep1_normal.bam], [patientB_rep1_tumor.bam]] + [[id:patientC, interval:chr1], [patientC_rep1_normal.bam], [patientC_rep1_tumor.bam]] + [[id:patientC, interval:chr2], [patientC_rep1_normal.bam], [patientC_rep1_tumor.bam]] + [[id:patientC, interval:chr3], [patientC_rep1_normal.bam], [patientC_rep1_tumor.bam]] + ``` + +Verilerimizin yapısının değiştiğini ve her channel öğesinde dosyaların artık `[patientA_rep1_normal.bam, patientA_rep2_normal.bam]` gibi tuple'lar içinde yer aldığını not edin. Bunun nedeni, `groupTuple` kullandığımızda, Nextflow'un bir grubun her örneği için tekil dosyaları birleştirmesidir. Aşağı akışta verileri işlemeye çalışırken bunu hatırlamak önemlidir. + +!!! note "Not" + + [`transpose`](https://www.nextflow.io/docs/latest/reference/operator.html#transpose) groupTuple'ın tersidir. Bir channel'daki öğeleri açar ve düzleştirir. Yukarıda gerçekleştirdiğimiz gruplamayı geri almak için `transpose` eklemeyi deneyin! + +### Özet + +Bu bölümde öğrendikleriniz: + +- **Gruplama anahtarlarını izole etme**: Gruplama için belirli alanları çıkarmak üzere `subMap` nasıl kullanılır +- **Gruplanmış veri yapılarını işleme**: `groupTuple` tarafından oluşturulan iç içe yapıyla nasıl çalışılır +- **Teknik replik işleme**: Aynı deneysel koşulları paylaşan örnekler nasıl gruplandırılır + +--- + +## Özet + +Bu yan görevde, channel'ları kullanarak verileri bölmeyi ve gruplamayı öğrendiniz. + +Verileri pipeline boyunca akarken değiştirerek, döngüler veya while ifadeleri kullanmadan ölçeklenebilir bir pipeline oluşturabilirsiniz; bu, daha geleneksel yaklaşımlara göre çeşitli avantajlar sunar: + +- Ek kod olmadan istediğimiz kadar çok veya az girdiyle ölçeklenebiliriz +- Yineleme yerine verilerin pipeline boyunca akışını yönetmeye odaklanıyoruz +- Gerektiği kadar karmaşık veya basit olabiliriz +- Pipeline daha bildirimsel hale gelir, nasıl yapılacağı yerine ne yapılması gerektiğine odaklanır +- Nextflow, bağımsız işlemleri paralel olarak çalıştırarak yürütmeyi bizim için optimize eder + +Bu channel işlemlerinde ustalaşmak, karmaşık veri ilişkilerini döngülere veya yinelemeli programlamaya başvurmadan ele alan esnek, ölçeklenebilir pipeline'lar oluşturmanıza olanak tanır ve Nextflow'un yürütmeyi optimize etmesine ve bağımsız işlemleri otomatik olarak paralelleştirmesine izin verir. + +### Temel desenler + +1. **Yapılandırılmış girdi verileri oluşturma:** Meta map'lerle bir CSV dosyasından başlama ([İş akışlarında meta veri](./metadata.md)'den desenlere dayanarak) + + ```groovy + ch_samples = channel.fromPath("./data/samplesheet.csv") + .splitCsv(header: true) + .map{ row -> + [[id:row.id, repeat:row.repeat, type:row.type], row.bam] + } + ``` + +2. **Verileri ayrı channel'lara bölme:** `type` alanına göre verileri bağımsız akışlara bölmek için `filter` kullandık + + ```groovy + channel.filter { it.type == 'tumor' } + ``` + +3. **Eşleşen örnekleri birleştirme:** `id` ve `repeat` alanlarına göre ilişkili örnekleri yeniden birleştirmek için `join` kullandık + + - İki channel'ı anahtara göre birleştirme (tuple'ın ilk öğesi) + + ```groovy + tumor_ch.join(normal_ch) + ``` + + - Birleştirme anahtarını çıkarma ve bu değere göre birleştirme + + ```groovy + tumor_ch.map { meta, file -> [meta.id, meta, file] } + .join( + normal_ch.map { meta, file -> [meta.id, meta, file] } + ) + ``` + + - subMap kullanarak birden fazla alanda birleştirme + + ```groovy + tumor_ch.map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + .join( + normal_ch.map { meta, file -> [meta.subMap(['id', 'repeat']), meta, file] } + ) + ``` + +4. **Aralıklara dağıtma:** Paralel işleme için örneklerin genomik aralıklarla Kartezyen çarpımlarını oluşturmak üzere `combine` kullandık. + + ```groovy + samples_ch.combine(intervals_ch) + ``` + +5. **Gruplama anahtarlarına göre toplama:** Her tuple'daki ilk öğeye göre gruplamak için `groupTuple` kullandık, böylece `id` ve `interval` alanlarını paylaşan örnekleri topladık ve teknik replikleri birleştirdik. + + ```groovy + channel.groupTuple() + ``` + +6. **Veri yapısını optimize etme:** Belirli alanları çıkarmak için `subMap` kullandık ve dönüşümleri yeniden kullanılabilir hale getirmek için adlandırılmış bir closure oluşturduk. + + - Bir map'ten belirli alanları çıkarma + + ```groovy + meta.subMap(['id', 'repeat']) + ``` + + - Yeniden kullanılabilir dönüşümler için adlandırılmış closure kullanma + + ```groovy + getSampleIdAndReplicate = { meta, file -> [meta.subMap(['id', 'repeat']), file] } + channel.map(getSampleIdAndReplicate) + ``` + +### Ek kaynaklar + +- [filter](https://www.nextflow.io/docs/latest/operator.html#filter) +- [map](https://www.nextflow.io/docs/latest/operator.html#map) +- [join](https://www.nextflow.io/docs/latest/operator.html#join) +- [groupTuple](https://www.nextflow.io/docs/latest/operator.html#grouptuple) +- [combine](https://www.nextflow.io/docs/latest/operator.html#combine) + +--- + +## Sırada ne var? + +[Yan Görevler menüsüne](./index.md) dönün veya listedeki bir sonraki konuya geçmek için sayfanın sağ alt köşesindeki düğmeye tıklayın. diff --git a/docs/tr/docs/side_quests/workflows_of_workflows.md b/docs/tr/docs/side_quests/workflows_of_workflows.md new file mode 100644 index 0000000000..3c31740716 --- /dev/null +++ b/docs/tr/docs/side_quests/workflows_of_workflows.md @@ -0,0 +1,471 @@ +# İç İçe Workflow'lar + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bir pipeline geliştirirken, kendinizi farklı veri türleri veya analiz adımları için benzer process dizileri oluştururken bulursunuz. Bu process dizilerini kopyalayıp yapıştırarak, bakımı zor çoğaltılmış kod oluşturabilirsiniz; veya anlaşılması ve değiştirilmesi zor tek bir devasa iş akışı oluşturabilirsiniz. + +Nextflow'un en güçlü özelliklerinden biri, karmaşık pipeline'ları daha küçük, yeniden kullanılabilir workflow modüllerinden oluşturma yeteneğidir. Bu modüler yaklaşım, pipeline'ların geliştirilmesini, test edilmesini ve bakımını kolaylaştırır. + +### Öğrenme hedefleri + +Bu yan görevde, ayrı ayrı test edilebilen ve kullanılabilen workflow modülleri geliştirmeyi, bu modülleri daha büyük bir pipeline'da birleştirmeyi ve modüller arasında veri akışını yönetmeyi keşfedeceğiz. + +Bu yan görevin sonunda şunları yapabileceksiniz: + +- Karmaşık pipeline'ları mantıksal, yeniden kullanılabilir birimlere ayırma +- Her workflow modülünü bağımsız olarak test etme +- Yeni pipeline'lar oluşturmak için workflow'ları birleştirme +- Ortak workflow modüllerini farklı pipeline'lar arasında paylaşma +- Kodunuzu daha bakımı kolay ve anlaşılır hale getirme + +Bu beceriler, temiz ve bakımı kolay kod yapısını korurken karmaşık pipeline'lar oluşturmanıza yardımcı olacaktır. + +### Ön koşullar + +Bu yan göreve başlamadan önce: + +- [Hello Nextflow](../hello_nextflow/README.md) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramları ve mekanizmalarını (process'ler, channel'lar, operatörler, modüller) rahatça kullanabiliyor olmalısınız + +--- + +## 0. Başlangıç + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md)'nda açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine geçin + +Bu eğitim için dosyaların bulunduğu dizine geçelim. + +```bash +cd side-quests/workflows_of_workflows +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri inceleyin + +'Hello Nextflow'da öğrendiklerinizin üzerine inşa eden birkaç process tanımı içeren bir `modules` dizini bulacaksınız: + +```console title="Dizin içeriği" +modules/ +├── say_hello.nf # Bir selamlama oluşturur (Hello Nextflow'dan) +├── say_hello_upper.nf # Büyük harfe dönüştürür (Hello Nextflow'dan) +├── timestamp_greeting.nf # Selamlamalara zaman damgası ekler +├── validate_name.nf # Girdi isimlerini doğrular +└── reverse_text.nf # Metin içeriğini tersine çevirir +``` + +#### Görevi inceleyin + +Göreviniz, bu modülleri iki ayrı workflow'da birleştirmek ve ardından bunları ana bir workflow'da compose etmektir: + +- İsimleri doğrulayan, selamlamalar oluşturan ve zaman damgaları ekleyen bir `GREETING_WORKFLOW` +- Metni büyük harfe dönüştüren ve tersine çeviren bir `TRANSFORM_WORKFLOW` + +<!-- TODO: Metadata yan görevinde yapıldığına benzer şekilde biraz daha ayrıntı verin --> + +#### Hazırlık kontrol listesi + +Başlamaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışıyor +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] Görevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Greeting Workflow'u Oluşturma + +İsimleri doğrulayan ve zaman damgalı selamlamalar oluşturan bir workflow oluşturarak başlayalım. + +### 1.1. Workflow yapısını oluşturma + +```bash title="Workflow dizini ve dosyası oluşturma" +mkdir -p workflows +touch workflows/greeting.nf +``` + +### 1.2. İlk (alt)workflow kodunu ekleme + +Bu kodu `workflows/greeting.nf` dosyasına ekleyin: + +```groovy title="workflows/greeting.nf" linenums="1" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow { + + names_ch = channel.of('Alice', 'Bob', 'Charlie') + + // Process'leri zincirle: doğrula -> selamlama oluştur -> zaman damgası ekle + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) +} +``` + +Bu, 'Hello Nextflow' eğitiminde gördüklerinize benzer bir yapıya sahip, bağımsız olarak test edebileceğimiz tam bir workflow. Şimdi deneyelim: + +```bash +nextflow run workflows/greeting.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [peaceful_montalcini] DSL2 - revision: 90f61b7093 + executor > local (9) + [51/4f980f] process > VALIDATE_NAME (validating Bob) [100%] 3 of 3 ✔ + [2b/dd8dc2] process > SAY_HELLO (greeting Bob) [100%] 3 of 3 ✔ + [8e/882565] process > TIMESTAMP_GREETING (adding timestamp to greeting) [100%] 3 of 3 ✔ + ``` + +Bu beklendiği gibi çalışıyor, ancak composable yapmak için değiştirmemiz gereken birkaç şey var. + +### 1.3. Workflow'u composable yapma + +Composable workflow'ların 'Hello Nextflow' eğitiminde gördüklerinizden bazı farklılıkları vardır: + +- Workflow bloğunun adlandırılması gerekir +- Girdiler `take:` anahtar kelimesi kullanılarak bildirilir +- Workflow içeriği `main:` bloğunun içine yerleştirilir +- Çıktılar `emit:` anahtar kelimesi kullanılarak bildirilir + +Greeting workflow'u bu yapıya uygun hale getirelim. Kodu aşağıdaki gibi değiştirin: + +<!-- TODO: önce/sonra sekmelerine geçin --> + +```groovy title="workflows/greeting.nf" linenums="1" hl_lines="5 6 8 14 15 16" +include { VALIDATE_NAME } from '../modules/validate_name' +include { SAY_HELLO } from '../modules/say_hello' +include { TIMESTAMP_GREETING } from '../modules/timestamp_greeting' + +workflow GREETING_WORKFLOW { + take: + names_ch // İsimler içeren girdi channel'ı + + main: + // Process'leri zincirle: doğrula -> selamlama oluştur -> zaman damgası ekle + validated_ch = VALIDATE_NAME(names_ch) + greetings_ch = SAY_HELLO(validated_ch) + timestamped_ch = TIMESTAMP_GREETING(greetings_ch) + + emit: + greetings = greetings_ch // Orijinal selamlamalar + timestamped = timestamped_ch // Zaman damgalı selamlamalar +} +``` + +Workflow'un artık adlandırıldığını ve `take:` ile `emit:` bloğuna sahip olduğunu görebilirsiniz; bunlar daha üst düzey bir workflow oluşturmak için kullanacağımız bağlantılardır. +Workflow içeriği de `main:` bloğunun içine yerleştirilmiştir. Ayrıca `names_ch` girdi channel bildirimini kaldırdığımızı not edin, çünkü artık workflow'a argüman olarak geçiriliyor. + +Workflow'un beklendiği gibi çalışıp çalışmadığını görmek için tekrar test edelim: + +```bash +nextflow run workflows/greeting.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `workflows/greeting.nf` [high_brahmagupta] DSL2 - revision: 8f5857af25 + No entry workflow specified + ``` + +Bu size başka bir yeni kavram hakkında bilgi veriyor, bir 'giriş workflow'u'. Giriş workflow'u, bir Nextflow script'i çalıştırdığınızda çağrılan workflow'dur. Varsayılan olarak, Nextflow mevcut olduğunda adlandırılmamış bir workflow'u giriş workflow'u olarak kullanır ve şimdiye kadar yaptığınız şey de buydu, şöyle başlayan workflow bloklarıyla: + +```groovy title="hello.nf" linenums="1" +workflow { +``` + +Ancak greeting workflow'umuzda adlandırılmamış bir workflow yok, bunun yerine adlandırılmış bir workflow var: + +```groovy title="workflows/greeting.nf" linenums="1" +workflow GREETING_WORKFLOW { +``` + +Bu yüzden Nextflow hata verdi ve istediğimizi yapmadı. + +`take:`/`emit:` sözdizimini workflow'u doğrudan çağırabilmek için eklemedik - diğer workflow'larla compose edebilmek için ekledik. Çözüm, adlandırılmış workflow'umuzu içe aktaran ve çağıran adlandırılmamış bir giriş workflow'una sahip bir ana script oluşturmaktır. + +### 1.4. Ana workflow'u oluşturma ve test etme + +Şimdi `greeting` workflow'unu içe aktaran ve kullanan bir ana workflow oluşturacağız. + +`main.nf` oluşturun: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + GREETING_WORKFLOW(names) + + GREETING_WORKFLOW.out.greetings.view { "Orijinal: $it" } + GREETING_WORKFLOW.out.timestamped.view { "Zaman damgalı: $it" } +} + +``` + +Bu dosyadaki workflow girişimizin adlandırılmamış olduğunu not edin, çünkü onu bir giriş workflow'u olarak kullanacağız. + +Bunu çalıştırın ve çıktıyı görün: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [goofy_mayer] DSL2 - revision: 543f8742fe + executor > local (9) + [05/3cc752] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Char... [100%] 3 of 3 ✔ + [b1/b56ecf] process > GREETING_WORKFLOW:SAY_HELLO (greeting Charlie) [100%] 3 of 3 ✔ + [ea/342168] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + Orijinal: /workspaces/training/side_quests/workflows_of_workflows/work/bb/c8aff3df0ebc15a4d7d35f736db44c/Alice-output.txt + Orijinal: /workspaces/training/side_quests/workflows_of_workflows/work/fb/fa877776e8a5d90b537b1bcd3b6f5b/Bob-output.txt + Orijinal: /workspaces/training/side_quests/workflows_of_workflows/work/b1/b56ecf938fda8bcbec211847c8f0be/Charlie-output.txt + Zaman damgalı: /workspaces/training/side_quests/workflows_of_workflows/work/06/877bc909f140bbf8223343450cea36/timestamped_Alice-output.txt + Zaman damgalı: /workspaces/training/side_quests/workflows_of_workflows/work/aa/bd31b71cdb745b7c155ca7f8837b8a/timestamped_Bob-output.txt + Zaman damgalı: /workspaces/training/side_quests/workflows_of_workflows/work/ea/342168d4ba04cc899a89c56cbfd9b0/timestamped_Charlie-output.txt + ``` + +Çalışıyor! Adlandırılmış greeting workflow'unu, adlandırılmamış bir giriş `workflow` bloğuna sahip bir ana workflow'a sardık. Ana workflow, `GREETING_WORKFLOW` workflow'unu neredeyse (tam olarak değil) bir process gibi kullanıyor ve `names` channel'ını argüman olarak geçiriyor. + +### Özet + +Bu bölümde birkaç önemli kavram öğrendiniz: + +- **Adlandırılmış Workflow'lar**: İçe aktarılabilen ve yeniden kullanılabilen adlandırılmış bir workflow (`GREETING_WORKFLOW`) oluşturma +- **Workflow Arayüzleri**: Composable bir workflow oluşturmak için `take:` ile net girdiler ve `emit:` ile çıktılar tanımlama +- **Giriş Noktaları**: Nextflow'un bir script'i çalıştırmak için adlandırılmamış bir giriş workflow'una ihtiyaç duyduğunu anlama +- **Workflow Kompozisyonu**: Başka bir workflow içinde adlandırılmış bir workflow'u içe aktarma ve kullanma +- **Workflow Ad Alanları**: `.out` ad alanını kullanarak workflow çıktılarına erişme (`GREETING_WORKFLOW.out.greetings`) + +Artık şunları yapan çalışan bir greeting workflow'unuz var: + +- Girdi olarak bir isimler channel'ı alır +- Her ismi doğrular +- Her geçerli isim için bir selamlama oluşturur +- Selamlamalara zaman damgaları ekler +- Hem orijinal hem de zaman damgalı selamlamaları çıktı olarak sunar + +Bu modüler yaklaşım, greeting workflow'unu bağımsız olarak test etmenize veya daha büyük pipeline'larda bir bileşen olarak kullanmanıza olanak tanır. + +--- + +## 2. Transform Workflow'unu Ekleme + +Şimdi selamlamalara metin dönüşümleri uygulayan bir workflow oluşturalım. + +### 2.1. Workflow dosyasını oluşturma + +```bash +touch workflows/transform.nf +``` + +### 2.2. Workflow kodunu ekleme + +Bu kodu `workflows/transform.nf` dosyasına ekleyin: + +```groovy title="workflows/transform.nf" linenums="1" +include { SAY_HELLO_UPPER } from '../modules/say_hello_upper' +include { REVERSE_TEXT } from '../modules/reverse_text' + +workflow TRANSFORM_WORKFLOW { + take: + input_ch // Mesajlar içeren girdi channel'ı + + main: + // Dönüşümleri sırayla uygula + upper_ch = SAY_HELLO_UPPER(input_ch) + reversed_ch = REVERSE_TEXT(upper_ch) + + emit: + upper = upper_ch // Büyük harfli selamlamalar + reversed = reversed_ch // Tersine çevrilmiş büyük harfli selamlamalar +} +``` + +Composable sözdiziminin açıklamasını burada tekrarlamayacağız, ancak adlandırılmış workflow'un yine `take:` ve `emit:` bloğuyla bildirildiğini ve workflow içeriğinin `main:` bloğunun içine yerleştirildiğini not edin. + +### 2.3. Ana workflow'u güncelleme + +Her iki workflow'u da kullanmak için `main.nf`'i güncelleyin: + +```groovy title="main.nf" linenums="1" +include { GREETING_WORKFLOW } from './workflows/greeting' +include { TRANSFORM_WORKFLOW } from './workflows/transform' + +workflow { + names = channel.of('Alice', 'Bob', 'Charlie') + + // Greeting workflow'unu çalıştır + GREETING_WORKFLOW(names) + + // Transform workflow'unu çalıştır + TRANSFORM_WORKFLOW(GREETING_WORKFLOW.out.timestamped) + + // Sonuçları görüntüle + TRANSFORM_WORKFLOW.out.upper.view { "Büyük harf: $it" } + TRANSFORM_WORKFLOW.out.reversed.view { "Tersine çevrilmiş: $it" } +} +``` + +Tam pipeline'ı çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 24.10.0 + Launching `main.nf` [sick_kimura] DSL2 - revision: 8dc45fc6a8 + executor > local (13) + executor > local (15) + [83/1b51f4] process > GREETING_WORKFLOW:VALIDATE_NAME (validating Alice) [100%] 3 of 3 ✔ + [68/556150] process > GREETING_WORKFLOW:SAY_HELLO (greeting Alice) [100%] 3 of 3 ✔ + [de/511abd] process > GREETING_WORKFLOW:TIMESTAMP_GREETING (adding tim... [100%] 3 of 3 ✔ + [cd/e6a7e0] process > TRANSFORM_WORKFLOW:SAY_HELLO_UPPER (converting t... [100%] 3 of 3 ✔ + [f0/74ba4a] process > TRANSFORM_WORKFLOW:REVERSE_TEXT (reversing UPPER... [100%] 3 of 3 ✔ + Büyük harf: /workspaces/training/side_quests/workflows_of_workflows/work/a0/d4f5df4d6344604498fa47a6084a11/UPPER-timestamped_Bob-output.txt + Büyük harf: /workspaces/training/side_quests/workflows_of_workflows/work/69/b5e37f6c79c2fd38adb75d0eca8f87/UPPER-timestamped_Charlie-output.txt + Büyük harf: /workspaces/training/side_quests/workflows_of_workflows/work/cd/e6a7e0b17e7d5a2f71bb8123cd53a7/UPPER-timestamped_Alice-output.txt + Tersine çevrilmiş: /workspaces/training/side_quests/workflows_of_workflows/work/7a/7a222f7957b35d1d121338566a24ac/REVERSED-UPPER-timestamped_Bob-output.txt + Tersine çevrilmiş: /workspaces/training/side_quests/workflows_of_workflows/work/46/8d19af62e33a5a6417c773496e0f90/REVERSED-UPPER-timestamped_Charlie-output.txt + Tersine çevrilmiş: /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt + ``` + +Tersine çevrilmiş dosyalardan birine bakarsanız, bunun selamlamanın büyük harfli versiyonunun tersine çevrilmiş hali olduğunu göreceksiniz: + +```bash +cat /workspaces/training/side_quests/workflows_of_workflows/work/f0/74ba4a10d9ef5c82f829d1c154d0f6/REVERSED-UPPER-timestamped_Alice-output.txt +``` + +```console title="Tersine çevrilmiş dosya içeriği" +!ECILA ,OLLEH ]04:50:71 60-30-5202[ +``` + +### Özet + +Artık şunları yapan tam bir pipeline'ınız olmalı: + +- İsimleri greeting workflow'u aracılığıyla işler +- Zaman damgalı selamlamaları transform workflow'una besler +- Selamlamaların hem büyük harfli hem de tersine çevrilmiş versiyonlarını üretir + +--- + +## Özet + +Bu yan görevde, daha küçük, yeniden kullanılabilir bileşenlerden karmaşık pipeline'lar oluşturmamıza olanak tanıyan Nextflow'daki güçlü workflow kompozisyonu kavramını keşfettik. + +Bu modüler yaklaşım, monolitik pipeline'lara göre çeşitli avantajlar sunar: + +- Her workflow bağımsız olarak geliştirilebilir, test edilebilir ve hata ayıklanabilir +- Workflow'lar farklı pipeline'lar arasında yeniden kullanılabilir +- Genel pipeline yapısı daha okunabilir ve bakımı kolay hale gelir +- Arayüzler tutarlı kaldığı sürece bir workflow'daki değişiklikler diğerlerini etkilemez +- Giriş noktaları, pipeline'ınızın farklı bölümlerini gerektiği gibi çalıştırmak için yapılandırılabilir + +_Ancak, workflow'ları çağırmanın process'leri çağırmak gibi olduğunu ancak aslında aynı şey olmadığını not etmek önemlidir. Örneğin, N boyutunda bir channel ile çağırarak bir workflow'u N kez çalıştıramazsınız - workflow'a N boyutunda bir channel geçirmeniz ve dahili olarak yinelemeniz gerekir._ + +Bu teknikleri kendi çalışmanıza uygulamak, bakımı ve ölçeklenebilir kalırken karmaşık biyoinformatik görevleri işleyebilen daha sofistike Nextflow pipeline'ları oluşturmanıza olanak tanıyacaktır. + +### Temel desenler + +1. **Workflow yapısı**: `take:` ve `emit:` sözdizimini kullanarak her workflow için net girdiler ve çıktılar tanımladık, bileşenler arasında iyi tanımlanmış arayüzler oluşturduk ve workflow mantığını `main:` bloğu içine sardık. + + ```groovy + workflow EXAMPLE_WORKFLOW { + take: + // Girdi channel'ları burada bildirilir + input_ch + + main: + // Workflow mantığı buraya gelir + // Process'ler çağrılır ve channel'lar manipüle edilir + result_ch = SOME_PROCESS(input_ch) + + emit: + // Çıktı channel'ları burada bildirilir + output_ch = result_ch + } + ``` + +2. **Workflow içe aktarmaları:** İki bağımsız workflow modülü oluşturduk ve bunları include ifadeleriyle ana pipeline'a aktardık. + + - Tek bir workflow'u içe aktarma + + ```groovy + include { WORKFLOW_NAME } from './path/to/workflow' + ``` + + - Birden fazla workflow'u içe aktarma + + ```groovy + include { WORKFLOW_A; WORKFLOW_B } from './path/to/workflows' + ``` + + - Ad çakışmalarını önlemek için takma adla içe aktarma + + ```groovy + include { WORKFLOW_A as WORKFLOW_A_ALIAS } from './path/to/workflow' + ``` + +3. **Giriş noktaları**: Nextflow, yürütmeye nereden başlayacağını bilmek için adlandırılmamış bir giriş workflow'u gerektirir. Bu giriş workflow'u, adlandırılmış workflow'larınızı çağırır. + + - Adlandırılmamış workflow (giriş noktası) + + ```groovy + workflow { + // Script çalıştırıldığında burası giriş noktasıdır + NAMED_WORKFLOW(input_ch) + } + ``` + + - Adlandırılmış workflow (giriş workflow'undan çağrılır) + + ```groovy + workflow NAMED_WORKFLOW { + // Giriş workflow'undan çağrılmalıdır + } + ``` + +4. **Veri akışını yönetme:** Ad alanı gösterimini (`WORKFLOW_NAME.out.channel_name`) kullanarak workflow çıktılarına erişmeyi ve bunları diğer workflow'lara geçirmeyi öğrendik. + + ```nextflow + WORKFLOW_A(input_ch) + WORKFLOW_B(WORKFLOW_A.out.some_channel) + ``` + +### Ek kaynaklar + +- [Nextflow Workflow Belgeleri](https://www.nextflow.io/docs/latest/workflow.html) +- [Channel Operatörleri Referansı](https://www.nextflow.io/docs/latest/operator.html) +- [Error Strategy Belgeleri](https://www.nextflow.io/docs/latest/process.html#errorstrategy) + +--- + +## Sırada ne var? + +[Yan Görevler menüsüne](./index.md) dönün veya listedeki bir sonraki konuya geçmek için sayfanın sağ alt köşesindeki düğmeye tıklayın. diff --git a/docs/tr/docs/side_quests/working_with_files.md b/docs/tr/docs/side_quests/working_with_files.md new file mode 100644 index 0000000000..ea009aba3a --- /dev/null +++ b/docs/tr/docs/side_quests/working_with_files.md @@ -0,0 +1,2039 @@ +# Dosya Girdi İşleme + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bilimsel analiz iş akışları genellikle çok sayıda dosyanın işlenmesini içerir. +Nextflow, dosyaları verimli bir şekilde yönetmek için güçlü araçlar sağlar ve verilerinizi minimum kodla düzenlemenize ve işlemenize yardımcı olur. + +### Öğrenme hedefleri + +Bu yan görevde, Nextflow'un dosyaları nasıl işlediğini, temel dosya işlemlerinden dosya koleksiyonlarıyla çalışmak için daha gelişmiş tekniklere kadar keşfedeceğiz. +Bilimsel analiz pipeline'larında yaygın bir gereksinim olan dosya adlarından meta veri çıkarmayı öğreneceksiniz. + +Bu yan görevin sonunda şunları yapabileceksiniz: + +- Nextflow'un `file()` metodunu kullanarak dosya yolu dizelerinden Path nesneleri oluşturma +- Ad, uzantı ve üst dizin gibi dosya özelliklerine erişme +- URI'ler kullanarak hem yerel hem de uzak dosyaları şeffaf bir şekilde işleme +- `channel.fromPath()` ve `channel.fromFilePairs()` ile dosya işlemeyi otomatikleştirmek için channel'ları kullanma +- Dize manipülasyonu kullanarak dosya adlarından meta veri çıkarma ve yapılandırma +- Desen eşleştirme ve glob ifadeleri kullanarak ilişkili dosyaları gruplama +- Doğru girdi işleme ile dosya işlemlerini Nextflow process'lerine entegre etme +- Meta veri odaklı dizin yapıları kullanarak process çıktılarını düzenleme + +Bu beceriler, farklı dosya girdilerini büyük esneklikle işleyebilen iş akışları oluşturmanıza yardımcı olacaktır. + +### Ön koşullar + +Bu yan göreve başlamadan önce: + +- [Hello Nextflow](../../hello_nextflow/) eğitimini veya eşdeğer bir başlangıç kursunu tamamlamış olmalısınız. +- Temel Nextflow kavramları ve mekanizmalarını (process'ler, channel'lar, operatörler) rahatça kullanabiliyor olmalısınız + +<!-- Meta map'ler yan görevini önce yapmayı öneren kısmı kaldırdım çünkü bu daha sonra doğal olarak çalışıyor --> + +--- + +## 0. Başlangıç + +#### Eğitim codespace'ini açın + +Henüz yapmadıysanız, [Ortam Kurulumu](../envsetup/index.md)'nda açıklandığı gibi eğitim ortamını açtığınızdan emin olun. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +#### Proje dizinine geçin + +Bu eğitim için dosyaların bulunduğu dizine geçelim. + +```bash +cd side-quests/working_with_files +``` + +VSCode'u bu dizine odaklanacak şekilde ayarlayabilirsiniz: + +```bash +code . +``` + +#### Materyalleri inceleyin + +`main.nf` adlı basit bir workflow dosyası, iki modül dosyası içeren bir `modules` dizini ve bazı örnek veri dosyaları içeren bir `data` dizini bulacaksınız. + +??? abstract "Dizin içeriği" + + ```console + . + ├── data + │ ├── patientA_rep1_normal_R1_001.fastq.gz + │ ├── patientA_rep1_normal_R2_001.fastq.gz + │ ├── patientA_rep1_tumor_R1_001.fastq.gz + │ ├── patientA_rep1_tumor_R2_001.fastq.gz + │ ├── patientA_rep2_normal_R1_001.fastq.gz + │ ├── patientA_rep2_normal_R2_001.fastq.gz + │ ├── patientA_rep2_tumor_R1_001.fastq.gz + │ ├── patientA_rep2_tumor_R2_001.fastq.gz + │ ├── patientB_rep1_normal_R1_001.fastq.gz + │ ├── patientB_rep1_normal_R2_001.fastq.gz + │ ├── patientB_rep1_tumor_R1_001.fastq.gz + │ ├── patientB_rep1_tumor_R2_001.fastq.gz + │ ├── patientC_rep1_normal_R1_001.fastq.gz + │ ├── patientC_rep1_normal_R2_001.fastq.gz + │ ├── patientC_rep1_tumor_R1_001.fastq.gz + │ └── patientC_rep1_tumor_R2_001.fastq.gz + ├── main.nf + └── modules + ├── analyze_reads.nf + └── count_lines.nf + ``` + +Bu dizin, üç hastadan (A, B, C) paired-end dizileme verilerini içerir. + +Her hasta için `tumor` (genellikle tümör biyopsilerinden kaynaklanan) veya `normal` (sağlıklı doku veya kandan alınan) türünde örneklerimiz var. +Kanser analiziyle tanışık değilseniz, bunun karşılaştırmalı analizler gerçekleştirmek için eşleştirilmiş tümör/normal örnekleri kullanan deneysel bir modele karşılık geldiğini bilin. + +Özellikle A hastası için iki set teknik replik (tekrar) var. + +Dizileme veri dosyaları, 'forward reads' ve 'reverse reads' olarak bilinen şeyler için tipik `_R1_` ve `_R2_` adlandırma kuralıyla adlandırılmıştır. + +_Bu deneysel tasarıma aşina değilseniz endişelenmeyin, bu eğitimi anlamak için kritik değil._ + +#### Görevi inceleyin + +Göreviniz şunları yapacak bir Nextflow iş akışı yazmaktır: + +1. Nextflow'un dosya işleme yöntemlerini kullanarak girdi dosyalarını **yükleme** +2. Dosya adı yapısından meta verileri (hasta kimliği, replik, örnek türü) **çıkarma** +3. `channel.fromFilePairs()` kullanarak eşleştirilmiş dosyaları (R1/R2) **gruplama** +4. Sağlanan bir analiz modülü ile dosyaları **işleme** +5. Çıkarılan meta verilere dayalı bir dizin yapısına çıktıları **düzenleme** + +#### Hazırlık kontrol listesi + +Başlamaya hazır olduğunuzu düşünüyor musunuz? + +- [ ] Bu kursun amacını ve ön koşullarını anlıyorum +- [ ] Codespace'im çalışıyor +- [ ] Çalışma dizinini uygun şekilde ayarladım +- [ ] Görevi anlıyorum + +Tüm kutuları işaretleyebiliyorsanız, başlamaya hazırsınız. + +--- + +## 1. Temel dosya işlemleri + +### 1.1. `.class` ile bir nesnenin türünü belirleme + +`main.nf` workflow dosyasına bakın: + +```groovy title="main.nf" linenums="1" +#!/usr/bin/env nextflow + +workflow { + + // Bir dize yolundan Path nesnesi oluştur + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} sınıfı ${myFile.class}" +} +``` + +Bu, workflow'unda tek bir dosya yoluna başvuran, ardından onu sınıfıyla birlikte konsola yazdıran (herhangi bir process olmadan) mini bir workflow'dur. + +??? info "`.class` nedir?" + + Nextflow'da `.class` bize hangi tür nesneyle çalıştığımızı söyler. "Bu ne tür bir şey?" diye sormak gibidir; bir dize mi, sayı mı, dosya mı yoksa başka bir şey mi olduğunu öğrenmek için. + Bu, sonraki bölümlerde düz bir dize ile Path nesnesi arasındaki farkı göstermemize yardımcı olacaktır. + +İş akışını çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [romantic_chandrasekhar] DSL2 - revision: 5a4a89bc3a + + data/patientA_rep1_normal_R1_001.fastq.gz sınıfı java.lang.String + ``` + +Gördüğünüz gibi, Nextflow yazdığımız dize yolunu aynen yazdırdı. + +Bu sadece metin çıktısıdır; Nextflow henüz bununla özel bir şey yapmadı. +Ayrıca Nextflow'un bakış açısına göre bunun sadece bir dize (`java.lang.String` sınıfında) olduğunu doğruladık. +Bu mantıklı, çünkü henüz Nextflow'a bunun bir dosyaya karşılık geldiğini söylemedik. + +### 1.2. `file()` ile Path nesnesi oluşturma + +Nextflow'a dosyaları nasıl işleyeceğini, yol dizelerinden [Path nesneleri](https://www.nextflow.io/docs/latest/reference/stdlib-types.html#path) oluşturarak söyleyebiliriz. + +Workflow'umuzda, `file()` metodunu kullanarak `data/patientA_rep1_normal_R1_001.fastq.gz` dize yolunu dosya özelliklerine ve işlemlerine erişim sağlayan bir Path nesnesine dönüştürebiliriz. + +`main.nf`'i düzenleyerek dizeyi aşağıdaki gibi `file()` ile sarın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} sınıfı ${myFile.class}" + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="5" hl_lines="2" + // Bir dize yolundan Path nesnesi oluştur + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + println "${myFile} sınıfı ${myFile.class}" + ``` + +Şimdi iş akışını tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [kickass_coulomb] DSL2 - revision: 5af44b1b59 + + /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz sınıfı class sun.nio.fs.UnixPath + ``` + +Bu sefer, girdi olarak sağladığımız göreli yol yerine tam mutlak yolu görüyorsunuz. + +Nextflow, dizemizi bir Path nesnesine dönüştürdü ve sistemdeki gerçek dosya konumuna çözümledi. +Dosya yolu artık `/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz` gibi mutlak olacaktır. + +Ayrıca Path nesne sınıfının `sun.nio.fs.UnixPath` olduğuna dikkat edin: bu Nextflow'un yerel dosyaları temsil etme şeklidir. +Daha sonra göreceğimiz gibi, uzak dosyalar farklı sınıf adlarına sahip olacak (HTTP dosyaları için `nextflow.file.http.XPath` gibi), ancak hepsi aynı şekilde çalışır ve iş akışlarınızda aynı şekilde kullanılabilir. + +!!! tip "İpucu" + + **Temel fark:** + + - **Yol dizesi**: Nextflow'un karakter olarak işlediği sadece metin + - **Path nesnesi**: Nextflow'un çalışabileceği akıllı bir dosya referansı + + Şöyle düşünün: yol dizesi kağıda bir adres yazmak gibidir, Path nesnesi ise oraya nasıl gidileceğini bilen ve yolculuk hakkında ayrıntılar söyleyebilen bir GPS cihazına yüklenmiş adresi gibidir. + +### 1.3. Dosya özelliklerine erişme + +Bu neden yararlı? Şimdi Nextflow, `myFile`'ın sadece bir dize değil, bir Path nesnesi olduğunu anladığından, Path nesnesinin çeşitli özelliklerine erişebiliriz. + +Yerleşik dosya özelliklerini yazdırmak için iş akışımızı güncelleyelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="5" hl_lines="4-9" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="5" hl_lines="4" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + println "${myFile} sınıfı ${myFile.class}" + ``` + +İş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [ecstatic_ampere] DSL2 - revision: f3fa3dcb48 + + Dosya nesne sınıfı: sun.nio.fs.UnixPath + Dosya adı: patientA_rep1_normal_R1_001.fastq.gz + Basit ad: patientA_rep1_normal_R1_001 + Uzantı: gz + Üst dizin: /workspaces/training/side-quests/working_with_files/data + ``` + +Çeşitli dosya özelliklerinin yukarıda konsola yazdırıldığını görüyorsunuz. + +### 1.4. Dosyayı bir process'e besleme + +Dizeler ve Path nesneleri arasındaki fark, process'lerle gerçek iş akışları oluşturmaya başladığınızda kritik hale gelir. +Şimdiye kadar Nextflow'un girdi dosyamızı bir dosya olarak işlediğini doğruladık, ancak bu dosyayı bir process'te gerçekten çalıştırıp çalıştıramayacağımıza bakalım. + +#### 1.4.1. Process'i içe aktarma ve kodu inceleme + +Size, bir dosya girdisi alan ve içinde kaç satır olduğunu sayan `COUNT_LINES` adlı önceden yazılmış bir process modülü sağlıyoruz. + +Process'i iş akışında kullanmak için, workflow bloğundan önce bir include ifadesi eklemeniz yeterlidir: + +=== "Sonra" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { COUNT_LINES } from './modules/count_lines.nf' + + workflow { + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Modül dosyasını açarak kodunu inceleyebilirsiniz: + +```groovy title="modules/count_lines.nf" linenums="1" +#!/usr/bin/env nextflow + +process COUNT_LINES { + debug true + + input: + path input_file + + script: + """ + set -o pipefail + echo "Dosya işleniyor: $input_file" + gzip -dc $input_file | wc -l + """ +} +``` + +Gördüğünüz gibi, dosyayı açan ve kaç satır içerdiğini sayan oldukça basit bir script. + +??? info "`debug true` ne yapar?" + + Process tanımındaki `debug true` yönergesi, Nextflow'un script'inizden çıktıyı (satır sayısı "40" gibi) doğrudan yürütme günlüğünde yazdırmasına neden olur. + Bu olmadan, yalnızca process yürütme durumunu görürsünüz, ancak script'inizden gerçek çıktıyı görmezsiniz. + + Nextflow process'lerini hata ayıklama hakkında daha fazla bilgi için [Nextflow İş Akışlarında Hata Ayıklama](debugging.md) yan görevine bakın. + +#### 1.4.2. `COUNT_LINES`'a bir çağrı ekleme + +Artık process iş akışında kullanılabilir olduğundan, girdi dosyası üzerinde çalıştırmak için `COUNT_LINES` process'ine bir çağrı ekleyebiliriz. + +İş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="11-12" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + + // Dosyadaki satırları say + COUNT_LINES(myFile) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +Şimdi iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [cheeky_hypatia] DSL2 - revision: 281d13c414 + + Dosya nesne sınıfı: class sun.nio.fs.UnixPath + Dosya adı: patientA_rep1_normal_R1_001.fastq.gz + Basit ad: patientA_rep1_normal_R1_001 + Uzantı: gz + Üst dizin: /workspaces/training/side-quests/working_with_files/data + executor > local (1) + [e9/341c05] COUNT_LINES [100%] 1 of 1 ✔ + Dosya işleniyor: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Bu, bir process içinde dosya üzerinde uygun şekilde işlem yapabildiğimizi gösterir. + +Özellikle, Nextflow aşağıdaki işlemleri başarıyla gerçekleştirdi: + +- Dosyayı çalışma dizinine hazırladı +- .gz dosyasını açtı +- Satırları saydı (bu durumda 40 satır) +- Hatasız tamamlandı + +Bu sorunsuz işlemin anahtarı, girdimizin bir dosya olduğunu ve bu şekilde işlenmesi gerektiğini Nextflow'a açıkça söylememizdir. + +### 1.5. Temel dosya girdi hatalarını giderme + +Bu genellikle Nextflow'a yeni başlayanları yanıltır, bu yüzden yanlış yaptığınızda ne olacağına bakmak için birkaç dakika ayıralım. + +Dosya işlemeyi yanlış yapabileceğiniz iki ana yer vardır: iş akışı düzeyinde ve process düzeyinde. + +#### 1.5.1. İş akışı düzeyinde hata + +Workflow bloğunda girdiyi belirtirken dosyayı bir dize olarak işlemeye geri dönersek ne olacağını görelim. + +Path'e özgü print ifadelerini yorumlamayı unutmadan iş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="2 6-11" + // Bir dize yolundan Path nesnesi oluştur + myFile = 'data/patientA_rep1_normal_R1_001.fastq.gz' + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + /* + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + */ + + // Dosyadaki satırları say + COUNT_LINES(myFile) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="4-9" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + + // Dosyadaki satırları say + COUNT_LINES(myFile) + ``` + +Şimdi iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [friendly_goodall] DSL2 - revision: ae50609b20 + + [- ] COUNT_LINES - + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' + + + + Tip: view the complete command output by changing to the process work dir and entering the command `cat .command.out` + + -- Check '.nextflow.log' file for details + ``` + +Önemli olan kısım şu: + +```console +Not a valid path value: 'data/patientA_rep1_normal_R1_001.fastq.gz' +``` + +Bir `path` girdisi belirttiğinizde, Nextflow sadece dizeler değil, gerçek dosya referansları geçirdiğinizi doğrular. +Bu hata, `'data/patientA_rep1_normal_R1_001.fastq.gz'`'nin geçerli bir yol değeri olmadığını söylüyor çünkü bu bir dize, Path nesnesi değil. + +Nextflow sorunu hemen algıladı ve process'i başlatmadan önce durdurdu. + +#### 1.5.2. Process düzeyinde hata + +Nextflow'a girdiyi bir dosya olarak işlemesini söylemeyi unutabileceğimiz diğer yer process tanımındadır. + +!!! warning "1.5.1'deki iş akışı hatasını koruyun" + + Bu testin doğru çalışması için, iş akışını bozuk durumunda tutun (`file()` yerine düz dize kullanarak). + Process'te `val` ile birleştirildiğinde, bu aşağıda gösterilen hatayı üretir. + +Modülde aşağıdaki düzenlemeyi yapın: + +=== "Sonra" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + val input_file + ``` + +=== "Önce" + + ```groovy title="modules/count_lines.nf" linenums="3" hl_lines="5" + process COUNT_LINES { + debug true + + input: + path input_file + ``` + +Şimdi iş akışını tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? failure "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [soggy_golick] DSL2 - revision: ae50609b20 + + executor > local (1) + [b3/b3023c] COUNT_LINES [ 0%] 0 of 1 ✘ + ERROR ~ Error executing process > 'COUNT_LINES' + + Caused by: + Process `COUNT_LINES` terminated with an error exit status (1) + + + Command executed: + + set -o pipefail + echo "Dosya işleniyor: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l + + Command exit status: + 1 + + Command output: + Dosya işleniyor: data/patientA_rep1_normal_R1_001.fastq.gz + 0 + + Command error: + Dosya işleniyor: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 + + Work dir: + /workspaces/training/side-quests/working_with_files/work/b3/b3023cb2ccb986851301d8e369e79f + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Bu, process hata ayıklama bilgisi çıkarmak üzere ayarlandığı için hata hakkında çok fazla ayrıntı gösterir. + +En alakalı bölümler şunlardır: + +```console +Command executed: + + set -o pipefail + echo "Dosya işleniyor: data/patientA_rep1_normal_R1_001.fastq.gz" + gzip -dc data/patientA_rep1_normal_R1_001.fastq.gz | wc -l +``` + +```console +Command error: + Dosya işleniyor: data/patientA_rep1_normal_R1_001.fastq.gz + gzip: data/patientA_rep1_normal_R1_001.fastq.gz: No such file or directory + 0 +``` + +Bu, sistemin dosyayı bulamadığını söylüyor; ancak yola bakarsanız, o konumda o isimde bir dosya var. + +Bunu çalıştırdığımızda, Nextflow dize değerini script'e geçirdi, ancak gerçek dosyayı çalışma dizinine _hazırlamadı_. +Bu nedenle process göreli dizeyi, `data/patientA_rep1_normal_R1_001.fastq.gz`'yi kullanmaya çalıştı, ancak bu dosya process çalışma dizini içinde mevcut değil. + +Bu iki örnek birlikte, Nextflow'a bir girdinin dosya olarak işlenmesi gerektiğini söylemenin ne kadar önemli olduğunu gösterir. + +!!! note "Not" + + Bir sonraki bölüme geçmeden önce her iki kasıtlı hatayı da düzelttiğinizden emin olun. + +### Özet + +- Yol dizeleri vs Path nesneleri: Dizeler sadece metindir, Path nesneleri akıllı dosya referanslarıdır +- `file()` metodu bir dize yolunu Nextflow'un çalışabileceği bir Path nesnesine dönüştürür +- [Dosya özelliklerini kullanarak](https://www.nextflow.io/docs/latest/working-with-files.html#getting-file-attributes) `name`, `simpleName`, `extension` ve `parent` gibi dosya özelliklerine erişebilirsiniz +- Dizeler yerine Path nesneleri kullanmak, Nextflow'un iş akışınızdaki dosyaları düzgün bir şekilde yönetmesine olanak tanır +- Process Girdi Sonuçları: Doğru dosya işleme, dosyaların process'ler tarafından kullanılmak üzere doğru şekilde hazırlanmasını ve erişilebilir olmasını sağlamak için dizeler yerine Path nesneleri gerektirir. + +--- + +## 2. Uzak dosyaları kullanma + +Nextflow'un temel özelliklerinden biri, yerel dosyalar (aynı makinede) ile internet üzerinden erişilebilen uzak dosyalar arasında sorunsuz geçiş yapabilme yeteneğidir. + +Doğru yapıyorsanız, farklı konumlardan gelen dosyaları barındırmak için iş akışınızın mantığını asla değiştirmenize gerek kalmamalıdır. +Uzak bir dosya kullanmak için tek yapmanız gereken, iş akışına sağlarken dosya yolunda uygun öneki belirtmektir. + +Örneğin, `/path/to/data` önek içermez, bu da 'normal' bir yerel dosya yolu olduğunu gösterir, oysa `s3://path/to/data` `s3://` önekini içerir, bu da Amazon'un S3 nesne deposunda bulunduğunu gösterir. + +Birçok farklı protokol desteklenir: + +- HTTP(S)/FTP (http://, https://, ftp://) +- Amazon S3 (s3://) +- Azure Blob Storage (az://) +- Google Cloud Storage (gs://) + +Bunlardan herhangi birini kullanmak için, dizedeki ilgili öneki belirtmeniz yeterlidir; bu teknik olarak dosya yolu yerine Tekdüzen Kaynak Tanımlayıcısı (URI) olarak adlandırılır. +Nextflow, kimlik doğrulama ve dosyaları doğru yere hazırlama, indirme veya yükleme ve beklediğiniz tüm diğer dosya işlemlerini yönetir. + +Bu sistemin temel gücü, herhangi bir pipeline mantığını değiştirmeden ortamlar arasında geçiş yapmamızı sağlamasıdır. +Örneğin, sadece URI'yi değiştirerek uzak depoda bulunan tam ölçekli bir test setine geçmeden önce küçük, yerel bir test setiyle geliştirebilirsiniz. + +### 2.1. İnternetten bir dosya kullanma + +İş akışımıza sağladığımız yerel yolu, GitHub'da depolanan aynı verilerin bir kopyasına işaret eden bir HTTPS yoluyla değiştirerek bunu test edelim. + +!!! warning "Uyarı" + + Bu yalnızca aktif bir internet bağlantınız varsa çalışır. + +`main.nf`'i tekrar açın ve girdi yolunu aşağıdaki gibi değiştirin: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // İnternetten uzak bir dosya kullanma + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +İş akışını çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + Dosya nesne sınıfı: class nextflow.file.http.XPath + Dosya adı: patientA_rep1_normal_R1_001.fastq.gz + Basit ad: patientA_rep1_normal_R1_001 + Uzantı: gz + Üst dizin: /nextflow-io/training/master/side-quests/working_with_files/data + executor > local (1) + [8a/2ab7ca] COUNT_LINES [100%] 1 of 1 ✔ + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Çalışıyor! Çok az şeyin değiştiğini görebilirsiniz. + +Konsol çıktısındaki tek fark, path nesne sınıfının artık `nextflow.file.http.XPath` olmasıdır, yerel yol için sınıf `sun.nio.fs.UnixPath` idi. +Bu sınıfları hatırlamanıza gerek yok; bunu sadece Nextflow'un farklı konumları tanımladığını ve uygun şekilde işlediğini göstermek için belirtiyoruz. + +Perde arkasında, Nextflow dosyayı çalışma dizini içinde bulunan bir hazırlama dizinine indirdi. +Bu hazırlanan dosya daha sonra yerel bir dosya olarak işlenebilir ve ilgili process dizinine sembolik olarak bağlanabilir. + +Bunun burada gerçekleştiğini, process'in hash değerinde bulunan çalışma dizininin içeriğine bakarak doğrulayabilirsiniz. + +??? abstract "Çalışma dizini içeriği" + + Process hash'i `8a/2ab7ca` ise, çalışma dizinini keşfedebilirsiniz: + + ```console + $ ls -la work/8a/2ab7ca*/ + total 16 + drwxr-xr-x 6 user staff 192 Jan 28 10:00 . + drwxr-xr-x 3 user staff 96 Jan 28 10:00 .. + -rw-r--r-- 1 user staff 0 Jan 28 10:00 .command.begin + -rw-r--r-- 1 user staff 127 Jan 28 10:00 .command.sh + lrwxr-xr-x 1 user staff 89 Jan 28 10:00 patientA_rep1_normal_R1_001.fastq.gz -> /path/to/work/stage/.../patientA_rep1_normal_R1_001.fastq.gz + ``` + + Sembolik bağlantı, Nextflow'un otomatik olarak indirdiği uzak dosyanın hazırlanmış bir kopyasına işaret eder. + +Daha büyük dosyalar için, indirme adımı yerel dosyalarda çalışmaya kıyasla biraz ekstra zaman alacaktır. +Ancak, Nextflow gereksiz indirmeleri önlemek için hazırlanmış bir kopyasının zaten olup olmadığını kontrol eder. +Bu nedenle, aynı dosyayı tekrar çalıştırır ve hazırlanmış dosyayı silmediyseniz, Nextflow hazırlanmış kopyayı kullanır. + +Bu, Nextflow kullanarak yerel ve uzak veriler arasında geçiş yapmanın ne kadar kolay olduğunu gösterir; bu Nextflow'un temel bir özelliğidir. + +!!! note "Not" + + Bu ilkenin tek önemli istisnası, HTTPS birden fazla dosyayı listeleyemediği için HTTPS ile glob desenleri veya dizin yolları kullanamamanızdır. + Ancak, blob depolama (`s3://`, `az://`, `gs://`) gibi diğer depolama protokolleri hem glob'ları hem de dizin yollarını kullanabilir. + + Bulut depolamayla glob desenlerini şu şekilde kullanabilirsiniz: + + ```groovy title="Bulut depolama örnekleri (bu ortamda çalıştırılamaz)" + // Glob desenleriyle S3 - birden fazla dosyayla eşleşir + ch_s3_files = channel.fromPath('s3://my-bucket/data/*.fastq.gz') + + // Glob desenleriyle Azure Blob Storage + ch_azure_files = channel.fromPath('az://container/data/patient*_R{1,2}.fastq.gz') + + // Glob desenleriyle Google Cloud Storage + ch_gcs_files = channel.fromPath('gs://bucket/data/sample_*.fastq.gz') + ``` + + Bir sonraki bölümde glob'larla pratikte nasıl çalışacağınızı göstereceğiz. + +### 2.2. Yerel dosyaya geri dönme + +Bu yan görevin geri kalanında yerel örnek dosyalarımızı kullanmaya devam edeceğiz, bu yüzden iş akışı girdisini orijinal dosyaya geri çevirelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="2" hl_lines="2" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('https://raw.github.com/nextflow-io/training/master/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + ``` + +### Özet + +- Uzak verilere bir URI (HTTP, FTP, S3, Azure, Google Cloud) kullanılarak erişilir +- Nextflow, bu yollar process'lere beslendiği sürece verileri otomatik olarak indirir ve doğru yere hazırlar +- Uzak dosyaları indirmek veya yüklemek için mantık yazmayın! +- Yerel ve uzak dosyalar farklı nesne türleri üretir ancak aynı şekilde çalışır +- **Önemli**: HTTP/HTTPS yalnızca tekil dosyalarla çalışır (glob desenleri yok) +- Bulut depolama (S3, Azure, GCS) hem tekil dosyaları hem de glob desenlerini destekler +- Protokol gerekli işlemlerinizi desteklediği sürece kod mantığını değiştirmeden yerel ve uzak veri kaynakları arasında sorunsuz geçiş yapabilirsiniz + +--- + +## 3. `fromPath()` channel factory kullanma + +Şimdiye kadar tek seferde tek bir dosyayla çalışıyorduk, ancak Nextflow'da genellikle işlenecek birden fazla girdi dosyasıyla bir girdi channel'ı oluşturmak isteyeceğiz. + +Bunu yapmanın naif bir yolu, `file()` metodunu [`channel.of()`](https://www.nextflow.io/docs/latest/reference/channel.html#of) ile şu şekilde birleştirmek olurdu: + +```groovy title="Sözdizimi örneği" +ch_files = channel.of([file('data/patientA_rep1_normal_R1_001.fastq.gz')], + [file('data/patientA_rep1_normal_R1_001.fastq.gz')]) +``` + +Bu çalışır, ancak hantal. + +!!! tip "`file()` vs `channel.fromPath()` ne zaman kullanılır" + + - Doğrudan manipülasyon için tek bir Path nesnesine ihtiyacınız olduğunda (bir dosyanın var olup olmadığını kontrol etme, özelliklerini okuma veya tek bir process çağrısına geçirme) `file()` kullanın + - Özellikle glob desenleriyle birden fazla dosya tutabilen veya dosyalar birden fazla process'ten geçecekse bir channel'a ihtiyacınız olduğunda `channel.fromPath()` kullanın + +[`channel.fromPath()`](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) burada devreye girer: bir veya daha fazla statik dosya dizesinden ve glob desenlerinden bir channel oluşturmak için ihtiyacımız olan tüm işlevselliği bir araya getiren kullanışlı bir channel factory. + +### 3.1. Channel factory'yi ekleme + +İş akışımızı `channel.fromPath` kullanacak şekilde güncelleyelim. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="1-3" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Dosya bulundu: $myFile" } + + // Dosya özelliklerini yazdır + /* Şimdilik bunları yorumlayın, daha sonra geri döneceğiz! + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + */ + + // Dosyadaki satırları say + // COUNT_LINES(myFile) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // Bir dize yolundan Path nesnesi oluştur + myFile = file('data/patientA_rep1_normal_R1_001.fastq.gz') + + // Dosya özelliklerini yazdır + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + + // Dosyadaki satırları say + COUNT_LINES(myFile) + ``` + +Ayrıca özellikleri yazdıran kodu şimdilik yorumladık ve bunun yerine sadece dosya adını yazdırmak için bir `.view` ifadesi ekledik. + +İş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [grave_meucci] DSL2 - revision: b09964a583 + + Dosya bulundu: /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz + ``` + +Gördüğünüz gibi, dosya yolu channel'da `Path` türü nesne olarak yükleniyor. +Bu, `file()`'ın yapacağına benzer, ancak şimdi istersek daha fazla dosya yükleyebileceğimiz bir channel'ımız var. + +`channel.fromPath()` kullanmak, bir dosya listesiyle doldurulmuş yeni bir channel oluşturmanın uygun bir yoludur. + +### 3.2. Channel'daki dosyaların özelliklerini görüntüleme + +Channel factory kullanımımızın ilk geçişinde, kodu basitleştirdik ve sadece dosya adını yazdırdık. + +Tam dosya özelliklerini yazdırmaya geri dönelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9 12" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + } + + // Dosyadaki satırları say + COUNT_LINES(ch_files) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ch_files.view { myFile -> "Dosya bulundu: $myFile" } + + // Dosyadaki satırları say + // COUNT_LINES(ch_files) + ``` + +Ayrıca dosya işlemenin channel tabanlı yaklaşımımızla hala doğru çalıştığını doğrulamak için `COUNT_LINES` process çağrısını yeniden etkinleştiriyoruz. + +İş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [furious_swanson] DSL2 - revision: c35c34950d + + executor > local (1) + [9d/6701a6] COUNT_LINES (1) [100%] 1 of 1 ✔ + Dosya nesne sınıfı: sun.nio.fs.UnixPath + Dosya adı: patientA_rep1_normal_R1_001.fastq.gz + Basit ad: patientA_rep1_normal_R1_001 + Uzantı: gz + Üst dizin: /workspaces/training/side-quests/working_with_files/data + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +İşte, öncekiyle aynı sonuçlar ancak şimdi dosya bir channel'da, bu yüzden daha fazla ekleyebiliriz. + +### 3.3. Birden fazla dosyayla eşleşmek için glob kullanma + +Channel'a daha fazla dosya yüklemenin birkaç yolu var. +Burada, joker karakterlere dayalı olarak dosya ve dizin adlarını eşleştirmenin ve almanın uygun bir yolu olan glob desenlerini nasıl kullanacağınızı göstereceğiz. +Bu desenleri eşleştirme işlemine "globbing" veya "dosya adı genişletme" denir. + +!!! note "Not" + + Daha önce belirtildiği gibi, Nextflow girdi ve çıktı dosyalarını yönetmek için çoğu durumda globbing'i destekler, ancak HTTPS birden fazla dosyayı listeleyemediği için HTTPS dosya yollarıyla istisna olarak desteklemez. + +Diyelim ki belirli bir hastayla, `patientA` ile ilişkili bir çift dosyadaki her iki dosyayı da almak istiyoruz: + +```console +patientA_rep1_normal_R1_001.fastq.gz +patientA_rep1_normal_R2_001.fastq.gz +``` + +Dosya adları arasındaki tek fark replik numarası olduğundan, yani `R`'den sonraki sayı, aşağıdaki gibi sayı yerine joker karakter `*`'yi kullanabiliriz: + +```console +patientA_rep1_normal_R*_001.fastq.gz +``` + +Bu, ihtiyacımız olan glob desenidir. + +Şimdi tek yapmamız gereken channel factory'deki dosya yolunu bu glob desenini kullanacak şekilde güncellemektir: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R1_001.fastq.gz') + ``` + +Nextflow, bunun bir glob deseni olduğunu otomatik olarak tanıyacak ve uygun şekilde işleyecektir. + +Bunu test etmek için iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [boring_sammet] DSL2 - revision: d2aa789c9a + + executor > local (2) + [3c/a65de5] COUNT_LINES (2) [100%] 2 of 2 ✔ + Dosya nesne sınıfı: class sun.nio.fs.UnixPath + Dosya adı: patientA_rep1_normal_R1_001.fastq.gz + Basit ad: patientA_rep1_normal_R1_001 + Uzantı: gz + Üst dizin: /workspaces/training/side-quests/working_with_files/data + Dosya nesne sınıfı: class sun.nio.fs.UnixPath + Dosya adı: patientA_rep1_normal_R2_001.fastq.gz + Basit ad: patientA_rep1_normal_R2_001 + Uzantı: gz + Üst dizin: /workspaces/training/side-quests/working_with_files/data + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Dosya işleniyor: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Gördüğünüz gibi, şimdi channel'ımızda iki Path nesnemiz var, bu da Nextflow'un dosya adı genişletmesini doğru şekilde yaptığını ve her iki dosyayı da beklendiği gibi yükleyip işlediğini gösteriyor. + +Bu yöntemi kullanarak, sadece glob desenini değiştirerek istediğimiz kadar çok veya az dosyayı alabiliriz. Daha cömert yaparsak, örneğin dosya adlarının tüm değişken kısımlarını `*` ile değiştirerek (_örneğin_ `data/patient*_rep*_*_R*_001.fastq.gz`) `data` dizinindeki tüm örnek dosyaları yakalayabiliriz. + +### Özet + +- `channel.fromPath()` bir desenle eşleşen dosyalarla bir channel oluşturur +- Her dosya channel'da ayrı bir öğe olarak yayılır +- Birden fazla dosyayla eşleşmek için bir glob deseni kullanabiliriz +- Dosyalar otomatik olarak tam özelliklere sahip Path nesnelerine dönüştürülür +- `.view()` metodu channel içeriklerinin incelenmesine olanak tanır + +--- + +## 4. Dosya adlarından temel meta veri çıkarma + +Çoğu bilimsel alanda, meta verilerin verileri içeren dosyaların adlarına kodlanması çok yaygındır. +Örneğin, biyoinformatikte, dizileme verilerini içeren dosyalar genellikle örnek, koşul, replik ve okuma numarası hakkında bilgi kodlayan bir şekilde adlandırılır. + +Dosya adları tutarlı bir kurala göre oluşturulmuşsa, bu meta veriyi standart bir şekilde çıkarabilir ve analiziniz sırasında kullanabilirsiniz. +Bu elbette büyük bir "eğer"dir ve dosya adı yapısına güvenirken çok dikkatli olmalısınız; ancak gerçek şu ki bu yaklaşım çok yaygın olarak kullanılmaktadır, bu yüzden Nextflow'da nasıl yapıldığına bir göz atalım. + +Örnek verilerimiz söz konusu olduğunda, dosya adlarının tutarlı bir şekilde yapılandırılmış meta veri içerdiğini biliyoruz. +Örneğin, `patientA_rep1_normal_R2_001` dosya adı aşağıdakileri kodlar: + +- hasta kimliği: `patientA` +- replik kimliği: `rep1` +- örnek türü: `normal` (`tumor`'un aksine) +- okuma seti: `R1` (`R2`'nin aksine) + +Bu bilgiyi üç adımda almak için iş akışımızı değiştireceğiz: + +1. Meta veriyi içeren dosyanın `simpleName`'ini alma +2. `tokenize()` adlı bir metot kullanarak meta veriyi ayırma +3. Meta veriyi düzenlemek için bir map kullanma + +!!! warning "Uyarı" + + Hasta adları veya diğer tanımlayıcı özellikler gibi hassas bilgileri asla dosya adlarına kodlamamalısınız, çünkü bu hasta gizliliğini veya diğer ilgili güvenlik kısıtlamalarını tehlikeye atabilir. + +### 4.1. `simpleName`'i alma + +`simpleName`, yolu ve uzantısından soyulmuş dosya adına karşılık gelen bir dosya özelliğidir. + +İş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3-6" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3-9" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.view { myFile -> + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + } + ``` + +Bu, `simpleName`'i alır ve bir `map()` işlemi kullanarak tam dosya nesnesiyle ilişkilendirir. + +Çalıştığını test etmek için iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [suspicious_mahavira] DSL2 - revision: ae8edc4e48 + + executor > local (2) + [e9/55774b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [patientA_rep1_normal_R2_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [patientA_rep1_normal_R1_001, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + + Dosya işleniyor: patientA_rep1_normal_R2_001.fastq.gz + 40 + ``` + +Channel'daki her öğe artık `simpleName`'i ve orijinal dosya nesnesini içeren bir tuple'dır. + +### 4.2. `simplename`'den meta veriyi çıkarma + +Bu noktada, istediğimiz meta veri `simplename`'e gömülü, ancak tek tek öğelere doğrudan erişemiyoruz. +Bu yüzden `simplename`'i bileşenlerine ayırmamız gerekiyor. +Neyse ki, bu bileşenler orijinal dosya adında sadece alt çizgilerle ayrılmış, bu yüzden bu görev için mükemmel olan `tokenize()` adlı yaygın bir Nextflow metodunu uygulayabiliriz. + +İş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName, myFile ] + } + ``` + +`tokenize()` metodu, alt çizgi bulduğu her yerde `simpleName` dizesini böler ve alt dizeleri içeren bir liste döndürür. + +İş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [gigantic_gauss] DSL2 - revision: a39baabb57 + + executor > local (2) + [e7/da2f4b] COUNT_LINES (2) [100%] 2 of 2 ✔ + [[patientA, rep1, normal, R2, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[patientA, rep1, normal, R1, 001], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Dosya işleniyor: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Şimdi channel'ımızdaki her öğenin tuple'ı meta veri listesini (_örneğin_ `[patientA, rep1, normal, R1, 001]`) ve orijinal dosya nesnesini içeriyor. + +Harika! +Hasta bilgilerimizi tek bir dizeden bir dize listesine ayırdık. +Artık hasta bilgilerinin her bir parçasını ayrı ayrı işleyebiliriz. + +### 4.3. Meta veriyi düzenlemek için map kullanma + +Meta verimiz şu anda sadece düz bir liste. +Kullanması kolay ama okumak zor. + +```console +[patientA, rep1, normal, R1, 001] +``` + +Dizin 3'teki öğe nedir? Meta veri yapısının orijinal açıklamasına başvurmadan söyleyebilir misiniz? + +Bu, her öğenin bir dizi anahtar ve ilişkili değerlere sahip olduğu bir anahtar-değer deposu kullanmak için harika bir fırsattır, böylece karşılık gelen değeri almak için her anahtara kolayca başvurabilirsiniz. + +Örneğimizde, bu şu organizasyondan: + +```groovy +data = [patientA, 1, normal, R1] + +println data[3] +``` + +Şu organizasyona geçmek anlamına gelir: + +```groovy +data = [id: patientA, replicate: 1, type: normal, readNum: 1] + +println data.readNum +``` + +Nextflow'da buna [map](https://nextflow.io/docs/latest/script.html#maps) denir. + +Şimdi düz listemizi bir map'e dönüştürelim. +İş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="4-13" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (patient, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: patient, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum.replace('R', ''), + ], + myFile + ] + } + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="4" + // channel.fromPath ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + [ myFile.simpleName.tokenize('_'), myFile ] + } + ``` + +Buradaki temel değişiklikler şunlardır: + +- **Yapı bozma ataması**: `def (patient, replicate, type, readNum) = ...` tokenize edilmiş değerleri tek satırda adlandırılmış değişkenlere çıkarır +- **Map literal sözdizimi**: `[id: patient, replicate: ...]` her anahtarın (örneğin `id`) bir değerle (örneğin `patient`) ilişkilendirildiği bir map oluşturur +- **İç içe yapı**: Dıştaki liste `[..., myFile]` meta veri map'ini orijinal dosya nesnesiyle eşleştirir + +Ayrıca gereksiz olan bazı karakterleri kaldırmak için `replace()` adlı bir dize değiştirme metodu kullanarak meta veri dizelerinin birkaçını basitleştirdik (_örneğin_ replik kimliklerinden sadece sayıyı tutmak için `replicate.replace('rep', '')`). + +İş akışını tekrar çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [infallible_swartz] DSL2 - revision: 7f4e68c0cb + + executor > local (2) + [1b/e7fb27] COUNT_LINES (1) [100%] 2 of 2 ✔ + [[id:patientA, replicate:1, type:normal, readNum:2], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz] + [[id:patientA, replicate:1, type:normal, readNum:1], /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz] + Dosya işleniyor: patientA_rep1_normal_R2_001.fastq.gz + 40 + + Dosya işleniyor: patientA_rep1_normal_R1_001.fastq.gz + 40 + ``` + +Şimdi meta veri düzgün bir şekilde etiketlenmiş (_örneğin_ `[id:patientA, replicate:1, type:normal, readNum:2]`) bu yüzden neyin ne olduğunu söylemek çok daha kolay. + +İş akışında meta veri öğelerini gerçekten kullanmak da çok daha kolay olacak ve kodumuzu okumayı ve bakımını kolaylaştıracak. + +### Özet + +- Nextflow'da dosya adlarını tam bir programlama dilinin gücüyle işleyebiliriz +- İlgili bilgileri çıkarmak için dosya adlarını dize olarak işleyebiliriz +- `tokenize()` ve `replace()` gibi metotların kullanımı, dosya adındaki dizeleri manipüle etmemize olanak tanır +- `.map()` işlemi yapıyı korurken channel öğelerini dönüştürür +- Yapılandırılmış meta veri (map'ler) konumsal listelerden daha okunabilir ve bakımı kolay kod sağlar + +Şimdi, eşleştirilmiş veri dosyalarını nasıl işleyeceğimize bakacağız. + +--- + +## 5. Eşleştirilmiş veri dosyalarını işleme + +Birçok deneysel tasarım, açıkça eşleştirilmiş bir şekilde işlenmekten fayda sağlayan eşleştirilmiş veri dosyaları üretir. +Örneğin, biyoinformatikte, dizileme verileri genellikle eşleştirilmiş okumalar biçiminde üretilir, yani aynı DNA parçasından kaynaklanan dizi dizileri (genellikle zıt uçlardan okudukları için 'forward' ve 'reverse' olarak adlandırılır). + +Bu, R1 ve R2'nin iki okuma setine atıfta bulunduğu örnek verilerimiz için de geçerlidir. + +```console +data/patientA_rep1_normal_R1_001.fastq.gz +data/patientA_rep1_normal_R2_001.fastq.gz +``` + +Nextflow, paylaşılan bir adlandırma desenine göre dosyaları otomatik olarak gruplayan `channel.fromFilePairs()` adlı eşleştirilmiş dosyalarla çalışmak için özel bir channel factory sağlar. Bu, eşleştirilmiş dosyaları daha az çabayla daha sıkı bir şekilde ilişkilendirmenize olanak tanır. + +Bundan yararlanmak için iş akışımızı değiştireceğiz. +İki adım alacak: + +1. Channel factory'yi `channel.fromFilePairs()`'a geçirme +2. Meta veriyi çıkarma ve eşleme + +### 5.1. Channel factory'yi `channel.fromFilePairs()`'a geçirme + +`channel.fromFilePairs` kullanmak için, Nextflow'un bir çiftteki iki üyeyi tanımlamak için kullanması gereken deseni belirtmemiz gerekir. + +Örnek verilerimize geri dönersek, adlandırma desenini aşağıdaki gibi resmileştirebiliriz: + +```console +data/patientA_rep1_normal_R{1,2}_001.fastq.gz +``` + +Bu, daha önce kullandığımız glob desenine benzer, ancak bu özellikle çiftin iki üyesini tanımlayan alt dizeleri (R'den hemen sonra `1` veya `2` gelen) numaralandırır. + +İş akışı `main.nf`'i buna göre güncelleyelim: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + /* Eşlemeyi şimdilik yorumlayın, daha sonra geri döneceğiz! + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + */ + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="1-2" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromPath('data/patientA_rep1_normal_R*_001.fastq.gz') + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + .view() + ``` + +Channel factory'yi değiştirdik ve dosya eşleştirme desenini uyarladık, ve bunu yaparken map işlemini yorumladık. +Daha sonra birkaç değişiklikle bunu geri ekleyeceğiz. + +Test etmek için iş akışını çalıştırın: + +```bash +nextflow run main.nf +``` + +??? failure "Komut çıktısı" + + ```console hl_lines="7-8" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [angry_koch] DSL2 - revision: 44fdf66105 + + [- ] COUNT_LINES - + [- ] COUNT_LINES - + [patientA_rep1_normal_R, [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ERROR ~ Error executing process > 'COUNT_LINES (1)' + + Caused by: + Not a valid path value: 'patientA_rep1_normal_R' + + + + Tip: when you have fixed the problem you can continue the execution adding the option `-resume` to the run command line + + -- Check '.nextflow.log' file for details + ``` + +Eyvah, bu sefer çalıştırma başarısız oldu! + +Hata mesajının ilgili kısmı burada: + +```console +Not a valid path value: 'patientA_rep1_normal_R' +``` + +Bunun nedeni channel factory'yi değiştirmiş olmamızdır. +Şimdiye kadar, orijinal girdi channel'ı yalnızca dosya yollarını içeriyordu. +Yaptığımız tüm meta veri manipülasyonu aslında channel içeriklerini etkilemedi. + +Artık `.fromFilePairs` channel factory'yi kullandığımıza göre, ortaya çıkan channel'ın içerikleri farklı. +Sadece bir channel öğesi görüyoruz, iki öğe içeren bir tuple'dan oluşuyor: iki dosya tarafından paylaşılan `simpleName` kısmı, bir tanımlayıcı görevi görüyor, ve iki dosya nesnesini içeren bir tuple, `id, [ file1, file2 ]` formatında. + +Bu harika, çünkü Nextflow paylaşılan öneki inceleyerek ve bunu hasta tanımlayıcısı olarak kullanarak hasta adını çıkarmanın zor işini yaptı. + +Ancak, mevcut iş akışımızı bozuyor. +`COUNT_LINES`'ı process'i değiştirmeden aynı şekilde çalıştırmak istersek, dosya yollarını çıkarmak için bir eşleme işlemi uygulamamız gerekir. +Ancak bunu yapmayacağız, çünkü nihai hedefimiz dosya çiftlerini uygun şekilde işleyen farklı bir process, `ANALYZE_READS` kullanmaktır. + +Bu yüzden sadece `COUNT_LINES`'a yapılan çağrıyı yorumlayalım (veya silelim) ve devam edelim. + +=== "Sonra" + + ```groovy title="main.nf" linenums="26" hl_lines="2" + // Dosyadaki satırları say + // COUNT_LINES(ch_files) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="26" hl_lines="2" + // Dosyadaki satırları say + COUNT_LINES(ch_files) + ``` + +`COUNT_LINES` include ifadesini de yorumlayabilir veya silebilirsiniz, ancak bunun işlevsel bir etkisi olmayacaktır. + +Şimdi iş akışını tekrar çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console hl_lines="5" + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [fabulous_davinci] DSL2 - revision: 22b53268dc + + [patientA_rep1_normal_R, [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +Yaşasın, bu sefer iş akışı başarılı! + +Ancak, yine de `id` alanından meta verinin geri kalanını almamız gerekiyor. + +### 5.2. Dosya çiftlerinden meta veriyi çıkarma ve düzenleme + +Önceki `map` işlemimiz veri yapısıyla eşleşmediği için çalışmayacak, ancak çalışması için değiştirebiliriz. + +Zaten `fromFilePairs()`'ın tanımlayıcı olarak kullandığı dizede gerçek hasta tanımlayıcısına erişimimiz var, bu yüzden daha önce yaptığımız gibi Path nesnesinden `simpleName`'i almadan meta veriyi çıkarmak için bunu kullanabiliriz. + +İş akışındaki map işlemini yorumdan çıkarın ve aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="3-4 9 11 13" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="3-5 11 13" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + /* Eşlemeyi şimdilik yorumlayın, daha sonra geri döneceğiz! + ch_files.map { myFile -> + def (sample, replicate, type, readNum) = myFile.simpleName.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type, + readNum: readNum, + ], + myFile + ] + } + */ + .view() + ``` + +Bu sefer map sadece `myFile` yerine `id, files`'dan başlıyor ve `tokenize()` `myFile.simpleName` yerine `id`'ye uygulanıyor. + +Ayrıca `readNum`'u `tokenize()` satırından çıkardığımıza dikkat edin; özellikle adlandırmadığımız alt dizeler (soldan başlayarak) sessizce atılacaktır. +Bunu yapabiliriz çünkü eşleştirilmiş dosyalar artık sıkıca ilişkili, bu yüzden meta veri map'inde artık `readNum`'a ihtiyacımız yok. + +İş akışını çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [prickly_stonebraker] DSL2 - revision: f62ab10a3f + + [[id:patientA, replicate:1, type:normal], [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +İşte burada: çıktı tuple'ının ilk pozisyonunda meta veri map'imiz (`[id:patientA, replicate:1, type:normal]`) var, ardından amaçlandığı gibi eşleştirilmiş dosyalar tuple'ı geliyor. + +Elbette, bu yalnızca belirli dosya çiftini alacak ve işleyecektir. +Birden fazla çifti işlemeyi denemek isterseniz, girdi desenine joker karakterler eklemeyi ve ne olacağını görmeyi deneyebilirsiniz. +Örneğin, `data/patientA_rep1_*_R{1,2}_001.fastq.gz` kullanmayı deneyin + +### Özet + +- [`channel.fromFilePairs()` ilişkili dosyaları otomatik olarak bulur ve eşleştirir](https://www.nextflow.io/docs/latest/reference/channel.html#fromfilepairs) +- Bu, pipeline'ınızda paired-end okumaları işlemeyi basitleştirir +- Eşleştirilmiş dosyalar `[id, [file1, file2]]` tuple'ları olarak gruplanabilir +- Meta veri çıkarma, tek tek dosyalar yerine eşleştirilmiş dosya kimliğinden yapılabilir + +--- + +## 6. Process'lerde dosya işlemlerini kullanma + +Şimdi, bir Nextflow process içinde dosya işlemlerini nasıl kullanacağımızı pekiştirmek için tüm bunları basit bir process'te bir araya getirelim. + +Size, bir meta veri tuple'ı ve bir çift girdi dosyası alan ve bunları analiz eden `ANALYZE_READS` adlı önceden yazılmış bir process modülü sağlıyoruz. +Bu işlemin dizilim hizalaması, varyant çağırma veya bu veri türü için anlamlı olan başka herhangi bir adımı yaptığını hayal edebiliriz. + +Başlayalım. + +### 6.1. Process'i içe aktarma ve kodu inceleme + +Bu process'i iş akışında kullanmak için, workflow bloğundan önce bir modül include ifadesi eklememiz yeterlidir. + +İş akışında aşağıdaki düzenlemeyi yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="1" hl_lines="3" + #!/usr/bin/env nextflow + + include { ANALYZE_READS } from './modules/analyze_reads.nf' + + workflow { + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="1" + #!/usr/bin/env nextflow + + workflow { + ``` + +Modül dosyasını açarak kodunu inceleyebilirsiniz: + +```groovy title="modules/analyze_reads.nf - process örneği" linenums="1" +#!/usr/bin/env nextflow + +process ANALYZE_READS { + tag { meta.id } + + publishDir { "results/${meta.id}" }, mode: 'copy' + + input: + tuple val(meta), path(files) + + output: + tuple val(meta.id), path("${meta.id}_stats.txt") + + script: + """ + echo "Örnek meta verisi: ${meta.id}" > ${meta.id}_stats.txt + echo "Replik: ${meta.replicate}" >> ${meta.id}_stats.txt + echo "Tür: ${meta.type}" >> ${meta.id}_stats.txt + echo "Okuma 1: ${files[0]}" >> ${meta.id}_stats.txt + echo "Okuma 2: ${files[1]}" >> ${meta.id}_stats.txt + echo "Okuma 1 boyutu: \$(gunzip -dc ${files[0]} | wc -l | awk '{print \$1/4}') okuma" >> ${meta.id}_stats.txt + echo "Okuma 2 boyutu: \$(gunzip -dc ${files[1]} | wc -l | awk '{print \$1/4}') okuma" >> ${meta.id}_stats.txt + """ +} +``` + +!!! note "Not" + + `tag` ve `publishDir` yönergeleri, dize interpolasyonu (`"${...}"`) yerine closure sözdizimi (`{ ... }`) kullanır. + Bunun nedeni, bu yönergelerin çalışma zamanına kadar mevcut olmayan girdi değişkenlerine (`meta`) başvurmasıdır. + Closure sözdizimi, değerlendirmeyi process gerçekten çalışana kadar erteler. + +!!! note "Not" + + Meta veri map'imizi kural olarak `meta` olarak adlandırıyoruz. + Meta map'lere daha derin bir bakış için [Meta veri ve meta map'ler](./metadata.md) yan görevine bakın. + +### 6.2. İş akışında process'i çağırma + +Artık process iş akışında kullanılabilir olduğundan, çalıştırmak için `ANALYZE_READS` process'ine bir çağrı ekleyebiliriz. + +Örnek verilerimizde çalıştırmak için iki şey yapmamız gerekecek: + +1. Yeniden eşlenen channel'a bir ad verme +2. Process'e bir çağrı ekleme + +#### 6.2.1. Yeniden eşlenen girdi channel'ını adlandırma + +Daha önce eşleme manipülasyonlarını doğrudan girdi channel'ına uygulamıştık. +Yeniden eşlenen içerikleri `ANALYZE_READS` process'ine beslemek için (ve bunu açık ve okunması kolay bir şekilde yapmak için) `ch_samples` adlı yeni bir channel oluşturmak istiyoruz. + +Bunu [`set`](https://www.nextflow.io/docs/latest/reference/operator.html#set) operatörünü kullanarak yapabiliriz. + +Ana iş akışında, `.view()` operatörünü `.set { ch_samples }` ile değiştirin ve channel'a adla başvurabileceğimizi test eden bir satır ekleyin. + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="14 16-17" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .set { ch_samples } + + // Geçici: ch_samples'a bakış + ch_samples.view() + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="14" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .view() + } + ``` + +Bunu çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `main.nf` [goofy_kirch] DSL2 - revision: 3313283e42 + + [[id:patientA, replicate:1, type:normal], [/workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R1_001.fastq.gz, /workspaces/training/side-quests/working_with_files/data/patientA_rep1_normal_R2_001.fastq.gz]] + ``` + +Bu, artık channel'a adla başvurabileceğimizi doğrular. + +#### 6.2.2. Veri üzerinde process'i çağırma + +Şimdi `ch_samples` channel'ı üzerinde `ANALYZE_READS` process'ini gerçekten çağıralım. + +Ana iş akışında aşağıdaki kod değişikliklerini yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="23" + // Analizi çalıştır + ANALYZE_READS(ch_samples) + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="23" + // Geçici: ch_samples'a bakış + ch_samples.view() + ``` + +Bunu çalıştıralım: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [shrivelled_cori] DSL2 - revision: b546a31769 + + executor > local (1) + [b5/110360] process > ANALYZE_READS (patientA) [100%] 1 of 1 ✔ + ``` + +Bu process çıktılarını bir `results` dizinine yayınlamak üzere ayarlanmış, bu yüzden oraya bakın. + +??? abstract "Dizin ve dosya içeriği" + + ```console + results + └── patientA + └── patientA_stats.txt + ``` + + ```txt title="patientA_stats.txt" + Örnek meta verisi: patientA + Replik: 1 + Tür: normal + Okuma 1: patientA_rep1_normal_R1_001.fastq.gz + Okuma 2: patientA_rep1_normal_R2_001.fastq.gz + Okuma 1 boyutu: 10 okuma + Okuma 2 boyutu: 10 okuma + ``` + +Process girdilerimizi aldı ve tasarlandığı gibi hasta meta verilerini içeren yeni bir dosya oluşturdu. +Mükemmel! + +### 6.3. Çok daha fazla hasta dahil etme + +Elbette, bu sadece tek bir hasta için tek bir dosya çiftini işliyor, bu da Nextflow ile elde etmeyi umduğunuz yüksek verimlilik türü değil. +Muhtemelen aynı anda çok daha fazla veri işlemek isteyeceksiniz. + +`channel.fromPath()`'in girdi olarak bir _glob_ kabul ettiğini unutmayın, bu da desenle eşleşen herhangi sayıda dosyayı kabul edebileceği anlamına gelir. +Bu nedenle, tüm hastaları dahil etmek istiyorsak, daha önce geçerken belirtildiği gibi daha fazla hasta içerecek şekilde girdi dizesini değiştirebiliriz. + +Mümkün olduğunca açgözlü olmak istediğimizi varsayalım. +İş akışında aşağıdaki düzenlemeleri yapın: + +=== "Sonra" + + ```groovy title="main.nf" linenums="7" hl_lines="2" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/*_R{1,2}_001.fastq.gz') + ``` + +=== "Önce" + + ```groovy title="main.nf" linenums="7" hl_lines="2" + // channel.fromFilePairs ile dosyaları yükle + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ``` + +Pipeline'ı tekrar çalıştırın: + +```bash +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [big_stonebraker] DSL2 - revision: f7f9b8a76c + + executor > local (8) + [d5/441891] process > ANALYZE_READS (patientC) [100%] 8 of 8 ✔ + ``` + +Results dizini artık tüm mevcut veriler için sonuçlar içermelidir. + +??? abstract "Dizin içeriği" + + ```console + results + ├── patientA + │ └── patientA_stats.txt + ├── patientB + │ └── patientB_stats.txt + └── patientC + └── patientC_stats.txt + ``` + +Başarılı! Tüm hastaları tek seferde analiz ettik! Değil mi? + +Belki de hayır. +Daha yakından bakarsanız, bir sorunumuz var: patientA için iki replikimiz var, ama sadece bir çıktı dosyası var! +Her seferinde çıktı dosyasını üzerine yazıyoruz. + +### 6.4. Yayınlanan dosyaları benzersiz yapma + +Hasta meta verisine erişimimiz olduğundan, bunu dizin yapısında veya dosya adlarının kendisinde farklılaştırıcı meta veri ekleyerek yayınlanan dosyaları benzersiz yapmak için kullanabiliriz. + +İş akışında aşağıdaki değişikliği yapın: + +=== "Sonra" + + ```groovy title="modules/analyze_reads.nf" linenums="6" + publishDir { "results/${meta.type}/${meta.id}/${meta.replicate}" }, mode: 'copy' + ``` + +=== "Önce" + + ```groovy title="modules/analyze_reads.nf" linenums="6" + publishDir { "results/${meta.id}" }, mode: 'copy' + ``` + +Burada örnek türlerini ve replikleri hesaba katmak için ek dizin seviyeleri kullanma seçeneğini gösteriyoruz, ancak bunu dosya adı seviyesinde yapmayı da deneyebilirsiniz. + +Şimdi pipeline'ı bir kez daha çalıştırın, ancak kendinize temiz bir çalışma alanı sağlamak için önce results dizinini sildiğinizden emin olun: + +```bash +rm -r results +nextflow run main.nf +``` + +??? success "Komut çıktısı" + + ```console + N E X T F L O W ~ version 25.10.2 + + Launching `./main.nf` [insane_swartz] DSL2 - revision: fff18abe6d + + executor > local (8) + [e3/449081] process > ANALYZE_READS (patientC) [100%] 8 of 8 ✔ + ``` + +Şimdi results dizinini kontrol edin: + +??? abstract "Dizin içeriği" + + ```console + results/ + ├── normal + │ ├── patientA + │ │ ├── 1 + │ │ │ └── patientA_stats.txt + │ │ └── 2 + │ │ └── patientA_stats.txt + │ ├── patientB + │ │ └── 1 + │ │ └── patientB_stats.txt + │ └── patientC + │ └── 1 + │ └── patientA_stats.txt + └── tumor + ├── patientA + │ ├── 1 + │ │ └── patientA_stats.txt + │ └── 2 + │ └── patientA_stats.txt + ├── patientB + │ └── 1 + │ └── patientB_stats.txt + └── patientC + └── 1 + └── patientA_stats.txt + ``` + +İşte burada, tüm meta verilerimiz düzgünce organize edilmiş. Bu başarı! + +Meta verinizi böyle bir map'e yükledikten sonra yapabileceğiniz çok daha fazla şey var: + +1. Hasta özelliklerine göre organize çıktı dizinleri oluşturma +2. Hasta özelliklerine göre process'lerde kararlar verme +3. Meta veri değerlerine göre verileri bölme, birleştirme ve yeniden birleştirme + +Meta veriyi açık ve veriye bağlı tutma deseni (dosya adlarına kodlanmak yerine), sağlam, bakımı kolay analiz iş akışları oluşturmayı sağlayan Nextflow'un temel en iyi uygulamasıdır. +Bu hakkında daha fazla bilgiyi [Meta veri ve meta map'ler](./metadata.md) yan görevinde öğrenebilirsiniz. + +### Özet + +- `publishDir` yönergesi, çıktıları meta veri değerlerine göre organize edebilir +- Tuple'lardaki meta veri, sonuçların yapılandırılmış organizasyonuna olanak tanır +- Bu yaklaşım, açık veri kaynağı ile bakımı kolay iş akışları oluşturur +- Process'ler meta veri ve dosya tuple'larını girdi olarak alabilir +- `tag` yönergesi, yürütme günlüklerinde process tanımlama sağlar +- İş akışı yapısı, channel oluşturmayı process yürütmesinden ayırır + +--- + +## Özet + +Bu yan görevde, Nextflow'da dosyalarla nasıl çalışacağınızı, temel işlemlerden dosya koleksiyonlarıyla çalışmak için daha gelişmiş tekniklere kadar öğrendiniz. + +Bu teknikleri kendi çalışmanıza uygulamak, özellikle karmaşık adlandırma kurallarına sahip çok sayıda dosyayla çalışırken daha verimli ve bakımı kolay iş akışları oluşturmanıza olanak tanır. + +### Temel desenler + +1. **Temel Dosya İşlemleri:** `file()` ile Path nesneleri oluşturduk ve ad, uzantı ve üst dizin gibi dosya özelliklerine eriştik, dizeler ve Path nesneleri arasındaki farkı öğrendik. + + - `file()` ile Path nesnesi oluşturma + + ```groovy + myFile = file('path/to/file.txt') + ``` + + - Dosya özelliklerini alma + + ```groovy + println myFile.name // file.txt + println myFile.baseName // file + println myFile.extension // txt + println myFile.parent // path/to + ``` + +2. **Uzak Dosyaları Kullanma**: URI'ler kullanarak yerel ve uzak dosyalar arasında şeffaf geçiş yapmayı öğrendik, Nextflow'un iş akışı mantığını değiştirmeden çeşitli kaynaklardan dosyaları işleme yeteneğini gösterdik. + + - Yerel dosya + + ```groovy + myFile = file('path/to/file.txt') + ``` + + - FTP + + ```groovy + myFile = file('ftp://path/to/file.txt') + ``` + + - HTTPS + + ```groovy + myFile = file('https://path/to/file.txt') + ``` + + - Amazon S3 + + ```groovy + myFile = file('s3://path/to/file.txt') + ``` + + - Azure Blob Storage + + ```groovy + myFile = file('az://path/to/file.txt') + ``` + + - Google Cloud Storage + + ```groovy + myFile = file('gs://path/to/file.txt') + ``` + +3. **`fromPath()` channel factory ile dosyaları yükleme:** `channel.fromPath()` ile dosya desenlerinden channel'lar oluşturduk ve nesne türleri dahil dosya özelliklerini görüntüledik. + + - Dosya deseninden channel oluşturma + + ```groovy + ch_files = channel.fromPath('data/*.fastq.gz') + ``` + + - Dosya özelliklerini alma + + ```groovy + ch_files.view { myFile -> + println "Dosya nesne sınıfı: ${myFile.class}" + println "Dosya adı: ${myFile.name}" + println "Basit ad: ${myFile.simpleName}" + println "Uzantı: ${myFile.extension}" + println "Üst dizin: ${myFile.parent}" + } + ``` + +4. **Dosya Adlarından Hasta Meta Verisi Çıkarma:** Dosya adlarından meta veriyi çıkarmak ve yapılandırmak için `tokenize()` ve `replace()` kullandık, bunları organize map'lere dönüştürdük. + + ```groovy + def name = file.name.tokenize('_') + def patientId = name[0] + def replicate = name[1].replace('rep', '') + def type = name[2] + def readNum = name[3].replace('R', '') + ``` + +5. **channel.fromFilePairs ile Basitleştirme:** İlişkili dosyaları otomatik olarak eşleştirmek ve eşleştirilmiş dosya kimliklerinden meta veri çıkarmak için `channel.fromFilePairs()` kullandık. + + ```groovy + ch_pairs = channel.fromFilePairs('data/*_R{1,2}_001.fastq.gz') + ``` + +6. **Process'lerde Dosya İşlemlerini Kullanma:** Doğru girdi işleme ile dosya işlemlerini Nextflow process'lerine entegre ettik, çıktıları meta veriye göre organize etmek için `publishDir` kullandık. + + - Process girdileriyle bir meta map ilişkilendirme + + ```groovy + ch_files = channel.fromFilePairs('data/patientA_rep1_normal_R{1,2}_001.fastq.gz') + ch_files.map { id, files -> + def (sample, replicate, type, readNum) = id.tokenize('_') + [ + [ + id: sample, + replicate: replicate.replace('rep', ''), + type: type + ], + files + ] + } + .set { ch_samples } + + ANALYZE_READS(ch_samples) + ``` + + - Çıktıları meta veriye göre düzenleme + + ```groovy + publishDir { "results/${meta.type}/${meta.id}/${meta.replicate}" }, mode: 'copy' + ``` + +### Ek kaynaklar + +- [Nextflow Belgeleri: Dosyalarla Çalışma](https://www.nextflow.io/docs/latest/working-with-files.html) +- [channel.fromPath](https://www.nextflow.io/docs/latest/reference/channel.html#frompath) +- [channel.fromFilePairs](https://www.nextflow.io/docs/latest/reference/channel.html#fromfilepairs) + +--- + +## Sırada ne var? + +[Yan Görevler menüsüne](./index.md) dönün veya listedeki bir sonraki konuya geçmek için sayfanın sağ alt köşesindeki düğmeye tıklayın. diff --git a/docs/tr/docs/training_collections/architects_toolkit_1.md b/docs/tr/docs/training_collections/architects_toolkit_1.md new file mode 100644 index 0000000000..5662abff75 --- /dev/null +++ b/docs/tr/docs/training_collections/architects_toolkit_1.md @@ -0,0 +1,61 @@ +--- +title: Mimar Araç Seti I +hide: + - toc +--- + +# Mimar Araç Seti I + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Eğitim Koleksiyonlarımız, gelişmiş eğitim materyallerimiz ([Yan Görevler](../../side_quests) olarak adlandırılır) aracılığıyla küratörlü öğrenme yolları sunar. Bu koleksiyon, sağlam ve ölçeklenebilir iş akışları oluşturmak için sıklıkla birlikte kullanılan dört temel konuyu kapsar. + +## Öğrenme hedefleri + +Bu koleksiyonun sonunda şu konularda deneyim kazanmış olacaksınız: + +- **Karmaşık modüler workflow mimarileri** - Birden fazla workflow'u tutarlı pipeline'larda birleştirme +- **Kapsamlı test stratejileri** - İş akışlarınızın güvenilir ve bakımı kolay olmasını sağlama +- **Meta veri yönetimi** - İş akışlarınız boyunca örneğe özgü meta verileri etkili bir şekilde işleme +- **Gelişmiş veri işleme** - Verimli veri bölme ve gruplama desenlerini uygulama + +Bu beceriler, gerçek dünya uygulamaları için sağlam, ölçeklenebilir ve bakımı kolay Nextflow iş akışları oluşturmanıza olanak tanıyacaktır. + +## Hedef kitle ve ön koşullar + +Bu koleksiyon, temel Nextflow eğitimini tamamlamış ve gelişmiş iş akışı desenleri, test stratejileri ve veri ile meta veri işleme tekniklerine daha derinlemesine dalmak isteyen kullanıcılar için tasarlanmıştır. + +**Ön koşullar** + +- [Hello Nextflow](../../hello_nextflow/) eğitiminin veya eşdeğer deneyimin tamamlanması +- Nextflow sözdizimi ve kavramlarına temel aşinalık +- Temel iş akışı geliştirme desenlerinin anlaşılması +- Komut satırı araçlarıyla deneyim + +## Koleksiyon içeriği + +Bu koleksiyon, tamamlayıcı iş akışı mühendisliği konularını kapsayan dört Yan Görevden oluşur: + +1. **[İç İçe Workflow'lar](../../side_quests/workflows_of_workflows)** - Karmaşık workflow mimarisi ve kompozisyonu +2. **[nf-test ile Test Etme](../../side_quests/nf-test)** - Nextflow iş akışları için test stratejileri +3. **[Meta Veri](../../side_quests/metadata)** - Nextflow channel'larındaki öğeler için meta veri işleme +4. **[Bölme ve Gruplama](../../side_quests/splitting_and_grouping)** - Gelişmiş veri işleme desenleri + +Her Yan Görev bağımsızdır ve bağımsız kavramları kapsar, ancak konular arasında mantıksal bir ilerleme için yukarıda listelenen sırayla tamamlamanızı öneririz. + +## Bu koleksiyonu nasıl kullanmalı + +İlk olarak, eğitim ortamını ayrı bir sekmede başlatmak için aşağıdaki "Open in GitHub Codespaces" düğmesine command-click yapın, ardından yüklenirken okumaya devam edin. + +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/nextflow-io/training?quickstart=1&ref=master) + +Ortamınız çalışmaya başladığında, koleksiyon üzerinde şu şekilde çalışın: + +1. Bu sekmede: Adım adım geliştirme alıştırmalarını açıklayan yukarıda listelenen ilk Yan Göreve gidin. +2. Codespaces sekmenizde: Yan Görev için alıştırmaları tamamlayın. +3. Bir Yan Görevi tamamladığınızda, bu sayfaya dönün ve yukarıdaki listedeki bir sonrakine gidin. +4. Koleksiyonu tamamladığınızda, çok kısa bir anketi doldurmak için aşağıdaki düğmeye tıklayın. Geri bildiriminiz, eğitim materyallerini herkes için geliştirmeye devam etmemizi sağlar. + +[![Anketi Doldurun](https://img.shields.io/badge/Anketi-Doldurun-blue?style=flat-square)](https://seqera.typeform.com/to/Q9pc2YKw) + +Başlamaya hazır mısınız? Yukarıdaki ilk modülden başlayın! diff --git a/docs/tr/docs/training_collections/index.md b/docs/tr/docs/training_collections/index.md new file mode 100644 index 0000000000..d62f574909 --- /dev/null +++ b/docs/tr/docs/training_collections/index.md @@ -0,0 +1,29 @@ +--- +title: Eğitim Koleksiyonları +hide: + - toc +--- + +# Eğitim Koleksiyonları + +<span class="ai-translation-notice">:material-information-outline:{ .ai-translation-notice-icon } Yapay Zeka Destekli Çeviri - [daha fazla bilgi ve iyileştirme önerileri](https://github.com/nextflow-io/training/blob/master/TRANSLATING.md)</span> + +Bu bölüm, belirli bir tema veya kullanım senaryosu etrafında kapsamlı bir öğrenme deneyimi sağlamayı amaçlayan [Yan Görevler](../side_quests/index.md) adlı eğitim modüllerinin küratörlü koleksiyonlarını içerir. + +## Ön koşullar + +Her koleksiyonun kendi dizin sayfasında belgelenmiş özel ön koşulları vardır. Ancak çoğu koleksiyon şunları varsayar: + +- Komut satırı ile deneyim +- [Hello Nextflow](../../hello_nextflow/) başlangıç eğitim kursunda kapsanan temel Nextflow kavramları ve araçları + +Teknik gereksinimler ve ortam kurulumu için [Ortam Kurulumu](../../envsetup/) mini kursuna bakın. + +## Mevcut koleksiyonlar + +- [Mimar Araç Seti I](./architects_toolkit_1.md) - Karmaşık pipeline'ları birleştirmek için workflow mimari desenleri, test stratejilerini uygulama, meta veri yönetimi ve verileri gruplama ve bölme konularını kapsayan dört Yan Görevden oluşan bir koleksiyon. _Tahmini süre: Grup eğitiminde 4 saat._ + +## Yeni koleksiyonlar önerme + +Ek Yan Görevler ve Koleksiyonlar geliştirmek için aktif olarak çalışıyoruz. +Bir Koleksiyonda ele alınmasının mantıklı olacağını düşündüğünüz konuları topluluk forumunun [Eğitim bölümünde](https://community.seqera.io/c/training/) paylaşarak önermekten çekinmeyin. diff --git a/docs/tr/llm-prompt.md b/docs/tr/llm-prompt.md new file mode 100644 index 0000000000..7e3c8dc3d8 --- /dev/null +++ b/docs/tr/llm-prompt.md @@ -0,0 +1,148 @@ +# Translation Rules for Turkish + +The target language for this translation is **Turkish** (`tr`). + +## 1. Grammar & Tone + +- Use formal tone (siz instead of sen) +- Follow Turkish Language Association (TDK) spelling conventions +- Prefer active voice when possible +- Pay attention to vowel harmony in suffixes + +## 2. Translation Context Rules + +**Important distinction**: Some technical terms have different translation rules depending on context: + +1. **In code blocks**: Keep ALL Nextflow syntax in English (the code must run) +2. **In code comments**: TRANSLATE comments to Turkish (they are not executable) +3. **In prose/explanatory text**: Follow the glossary below for translations + +For example: + +- In prose: "Giriş kanalı dosyaları alır..." (translate "channel" to "kanal") +- In code: `channel.fromPath('*.fastq')` (keep "channel" in English) +- In comments: `// emit a greeting` → `// bir selamlama yayınla` + +## 3. Code Comments + +**Always translate code comments to Turkish.** Comments are not executable code and should be in the target language for better comprehension. + +```groovy +// English original +params.greeting = "Hello" // set default greeting + +// Turkish translation +params.greeting = "Hello" // varsayılan selamlamayı ayarla +``` + +## 4. Common Mistakes + +Avoid these translation errors specific to Turkish: + +### ❌ Translating code syntax + +```groovy +// Wrong - translating Nextflow keywords +Kanal.fromPath('*.fastq') +süreç FOO { } + +// Correct - keep Nextflow keywords in English +Channel.fromPath('*.fastq') +process FOO { } +``` + +### ❌ Translating console output + +Console output shows exactly what users will see and must not be translated: + +```console +// Wrong +N E X T F L O W ~ sürüm 24.04.0 +yürütücü > local (3) + +// Correct - leave exactly as-is +N E X T F L O W ~ version 24.04.0 +executor > local (3) +``` + +### ❌ Incorrect vowel harmony + +```markdown +// Wrong - vowel harmony violation +workflow'a koşalım +container'lar + +// Correct - proper vowel harmony +workflow'u çalıştıralım +container'lar (or konteynırlar) +``` + +### ❌ Using informal sen instead of siz + +```markdown +// Wrong - too informal +Workflow'u çalıştır. Sonuçları göreceksin. + +// Correct - formal siz form +Workflow'u çalıştırın. Sonuçları göreceksiniz. +``` + +## 5. Terms to Translate + +These terms should be translated in prose (but kept in English in code): + +| English | Turkish | +| ----------- | ------------------------ | +| channel | kanal | +| process | süreç | +| workflow | iş akışı | +| pipeline | boru hattı / pipeline | +| directive | yönerge | +| container | konteyner | +| input | girdi | +| output | çıktı | +| task | görev | +| tuple | demet | +| operator | operatör | +| parameter | parametre | +| environment | ortam | +| directory | dizin | +| file | dosya | +| sample | örnek | +| alignment | hizalama | +| reference | referans | +| training | eğitim | +| module | modül | +| command | komut | +| index | dizin (index for files) | +| run | çalıştırmak / çalıştırma | + +## 6. Admonition Titles + +| English | Turkish | +| -------- | --------- | +| Note | Not | +| Tip | İpucu | +| Warning | Uyarı | +| Exercise | Alıştırma | +| Solution | Çözüm | +| Example | Örnek | + +## 7. Section Headers + +| English | Turkish | +| ----------------- | -------------- | +| Takeaway | Özet | +| What's next? | Sırada ne var? | +| Warmup | Isınma | +| Environment Setup | Ortam Kurulumu | +| Getting Started | Başlarken | + +## 8. Tab Labels + +| English | Turkish | +| ------- | ------- | +| After | Sonra | +| Before | Önce | +| Gitpod | Gitpod | +| Local | Yerel | diff --git a/docs/tr/mkdocs.yml b/docs/tr/mkdocs.yml new file mode 100644 index 0000000000..ad4fd1d9f1 --- /dev/null +++ b/docs/tr/mkdocs.yml @@ -0,0 +1,15 @@ +INHERIT: ../en/mkdocs.yml +theme: + language: tr + custom_dir: ../en/overrides +extra: + consent: + title: "Çerez Onayı" + description: >- + Tekrarlayan ziyaretlerinizi ve tercihlerinizi tanımak, dokümantasyonumuzun + etkinliğini ölçmek ve kullanıcıların aradıklarını bulup bulmadığını belirlemek + için çerezler kullanıyoruz. Onayınızla eğitim materyallerimizi geliştirmemize + yardımcı oluyorsunuz. + <a href="https://seqera.io/privacy-policy/#cookies" target="_blank" rel="noopener">Çerezleri nasıl kullandığımız</a> hakkında daha fazla bilgi edinin. + cookies: + posthog: "PostHog Analytics" diff --git a/docs/tr/ui-strings.yml b/docs/tr/ui-strings.yml new file mode 100644 index 0000000000..4bd42cc83f --- /dev/null +++ b/docs/tr/ui-strings.yml @@ -0,0 +1,20 @@ +# UI strings for translation - Turkish (Türkçe) +# Bu dizeler, kurs giriş sayfaları için index_page_hook.py tarafından +# ve çerez onayı için mkdocs.yml'de kullanılır. + +index_page: + course_summary: "Kurs Özeti" + additional_information: "Ek Bilgiler" + technical_requirements: "Teknik Gereksinimler" + learning_objectives: "Öğrenme Hedefleri" + audience_prerequisites: "Hedef Kitle ve Ön Koşullar" + course_videos: "Kurs Videoları" + +defaults: + technical_requirements: >- + Bir GitHub hesabına VEYA yerel bir Nextflow kurulumuna ihtiyacınız olacak. + Daha fazla ayrıntı için [Ortam seçenekleri](../envsetup/index.md) sayfasına bakın. + videos: >- + Her bölüm için eğitmenin alıştırmaları yaptığı videolar mevcuttur. + Kursun her bölümüne ait video, ilgili sayfanın üst kısmına yerleştirilmiştir. + view_playlist: "YouTube'da oynatma listesini görüntüle" diff --git a/netlify.toml b/netlify.toml index f1dcd5a9a1..c143096ef9 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,5 +1,5 @@ # ONLY USED FOR DEPLOYMENT PREVIEWS # production deploys go from gh-pages and are pre-built using Mike, for versioning [build] - command = "pip install -r requirements.txt && mkdocs build" + command = "curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH=$HOME/.local/bin:$PATH && uv run _scripts/docs.py build-all" publish = "site/" diff --git a/preview_release.py b/preview_release.py index d3d54e0d37..f66c359b39 100755 --- a/preview_release.py +++ b/preview_release.py @@ -19,6 +19,7 @@ """ import atexit +import concurrent.futures import hashlib import json import os @@ -46,6 +47,7 @@ CERTS_DIR = WORK_DIR / "certs" SITE_DIR = WORK_DIR / "site" CADDYFILE = WORK_DIR / "Caddyfile" +DOCS_DIR = Path("docs") # Rich console console = Console() @@ -205,6 +207,15 @@ def check_dependencies(): status_msg("setup", "mkcert CA trusted by system", success=True) +def discover_languages() -> list[str]: + """Discover all available language directories with mkdocs.yml.""" + languages = [] + for lang_dir in sorted(DOCS_DIR.iterdir()): + if lang_dir.is_dir() and (lang_dir / "mkdocs.yml").exists(): + languages.append(lang_dir.name) + return languages + + def generate_certificates(): """Generate TLS certificates for the domain.""" status_msg("setup", "Generating certificates...") @@ -279,77 +290,117 @@ def fetch_gh_pages(): ) -def compute_source_hash(): - """Compute a hash of source files to detect changes.""" +def compute_source_hash(lang: str) -> str: + """Compute a hash of source files for a specific language to detect changes.""" hasher = hashlib.md5() - - # Hash key source directories and files - source_paths = [ - Path("docs"), - Path("mkdocs.yml"), - ] - - for source_path in source_paths: - if not source_path.exists(): - continue - if source_path.is_file(): - hasher.update(source_path.read_bytes()) - else: - # For directories, hash all markdown and config files - for file in sorted(source_path.rglob("*")): - if file.is_file() and file.suffix in ( - ".md", - ".yml", - ".yaml", - ".css", - ".js", - ".html", - ): - try: - hasher.update(str(file).encode()) - hasher.update(file.read_bytes()) - except (IOError, OSError): - pass + source_path = DOCS_DIR / lang + + for file in sorted(source_path.rglob("*")): + if file.is_file() and file.suffix in ( + ".md", + ".yml", + ".yaml", + ".css", + ".js", + ".html", + ): + hasher.update(str(file).encode()) + hasher.update(file.read_bytes()) return hasher.hexdigest()[:12] -def build_docs(version: str): - """Build docs for the specified version using Docker.""" - version_dir = SITE_DIR / version - hash_file = WORK_DIR / f"{version}.hash" +def get_lang_paths(version: str, lang: str) -> tuple[Path, Path]: + """Get output directory and hash file paths for a language. + + English is built at the version root, other languages in subdirectories. + """ + if lang == "en": + return SITE_DIR / version, WORK_DIR / f"{version}-{lang}.hash" + return SITE_DIR / version / lang, WORK_DIR / f"{version}-{lang}.hash" - # Compute current source hash - current_hash = compute_source_hash() - # Check if we can skip the build - if ( - version_dir.exists() - and (version_dir / "index.html").exists() +def is_cached(output_dir: Path, hash_file: Path, current_hash: str) -> bool: + """Check if a build is cached and up-to-date.""" + return ( + output_dir.exists() + and (output_dir / "index.html").exists() and hash_file.exists() - ): - stored_hash = hash_file.read_text().strip() - if stored_hash == current_hash: - status_msg( - "setup", - f"v{version} already built [dim](source unchanged)[/dim]", - success=True, - ) - return - else: - status_msg("setup", "Source files changed, rebuilding...") - shutil.rmtree(version_dir) + and hash_file.read_text().strip() == current_hash + ) + + +def build_single_language( + version: str, lang: str, repo_root: Path +) -> tuple[str, bool, str]: + """Build docs for a single language. Returns (lang, success, error_message).""" + output_dir, hash_file = get_lang_paths(version, lang) + current_hash = compute_source_hash(lang) + + if is_cached(output_dir, hash_file, current_hash): + return (lang, True, "cached") + + # Clean and prepare build directory + if output_dir.exists(): + subprocess.run(["rm", "-rf", str(output_dir)], check=False) + output_dir.mkdir(parents=True, exist_ok=True) + subprocess.run(["chmod", "-R", "777", str(output_dir)], check=False) + + # Build using Docker + result = subprocess.run( + [ + "docker", + "run", + "--rm", + "-v", + f"{repo_root}:/docs", + "-w", + f"/docs/docs/{lang}", + "ghcr.io/nextflow-io/training-mkdocs:latest", + "build", + "-d", + f"/docs/{output_dir}", + ], + capture_output=True, + text=True, + ) + + if result.returncode != 0: + return (lang, False, result.stderr + result.stdout) + + hash_file.write_text(current_hash) + return (lang, True, "built") - # Ensure clean build directory (use rm -rf to handle root-owned files from Docker) - if version_dir.exists(): - run_cmd(["rm", "-rf", str(version_dir)], check=False) - version_dir.mkdir(parents=True, exist_ok=True) - # Make directory world-writable so Docker container can write to it - run_cmd(["chmod", "-R", "777", str(version_dir)], check=False) - # Get absolute paths +def build_docs(version: str, languages: list[str], parallel: bool = True): + """Build docs for the specified version and languages using Docker.""" repo_root = Path.cwd().resolve() + (SITE_DIR / version).mkdir(parents=True, exist_ok=True) + + # Check which languages need building + to_build = [] + cached = [] + for lang in languages: + output_dir, hash_file = get_lang_paths(version, lang) + if is_cached(output_dir, hash_file, compute_source_hash(lang)): + cached.append(lang) + else: + to_build.append(lang) + if cached: + status_msg( + "setup", + f"Cached: {', '.join(cached)} [dim](source unchanged)[/dim]", + success=True, + ) + + if not to_build: + status_msg("setup", f"v{version} already built", success=True) + return + + status_msg("setup", f"Building: {', '.join(to_build)}...") + + failed = [] with Progress( TextColumn(""), SpinnerColumn(), @@ -357,38 +408,43 @@ def build_docs(version: str): console=console, transient=True, ) as progress: - progress.add_task( - f"Building v{version} docs (this may take a few minutes)...", total=None - ) + if parallel and len(to_build) > 1: + progress.add_task( + f"Building {len(to_build)} languages in parallel...", total=None + ) + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: + futures = { + executor.submit( + build_single_language, version, lang, repo_root + ): lang + for lang in to_build + } + for future in concurrent.futures.as_completed(futures): + lang, success, msg = future.result() + if not success: + failed.append((lang, msg)) + else: + for lang in to_build: + progress.add_task(f"Building {lang}...", total=None) + lang, success, msg = build_single_language(version, lang, repo_root) + if not success: + failed.append((lang, msg)) - result = run_cmd( - [ - "docker", - "run", - "--rm", - "-v", - f"{repo_root}:/docs", - "-e", - "CARDS=false", - "ghcr.io/nextflow-io/training-mkdocs:latest", - "build", - "-d", - f"/docs/{WORK_DIR}/site/{version}", - ], - check=False, - capture=True, + if failed: + status_msg( + "setup", + f"Build failed for: {', '.join(l for l, _ in failed)}", + success=False, ) - - if result.returncode != 0: - status_msg("setup", "Docker build failed", success=False) - console.print(result.stderr) - console.print(result.stdout) + for lang, msg in failed: + console.print(f"[red]{lang}:[/red] {msg}") sys.exit(1) - # Save hash for future cache checks - hash_file.write_text(current_hash) - - status_msg("setup", f"v{version} built successfully", success=True) + status_msg( + "setup", + f"v{version} built successfully ({len(languages)} languages)", + success=True, + ) def update_versions_json(version: str): @@ -538,8 +594,20 @@ def run_server(version: str): is_flag=True, help="Delete work directory on exit (default: keep for faster restart)", ) +@click.option( + "--all-languages", + "-a", + is_flag=True, + help="Build all languages (default: English only)", +) +@click.option( + "--sequential", + "-s", + is_flag=True, + help="Build languages sequentially instead of in parallel", +) @click.pass_context -def cli(ctx, version: str | None, clean: bool): +def cli(ctx, version: str | None, clean: bool, all_languages: bool, sequential: bool): """ **Preview Release** - Serve training docs locally at production URL. @@ -550,6 +618,9 @@ def cli(ctx, version: str | None, clean: bool): **First-time setup:** Run `mkcert -install` once as your regular user. **Note:** Do not run with sudo. The script will prompt for sudo when needed. + + **Languages:** By default, only English is built for faster iteration. + Use `--all-languages` to build all available translations. """ global _keep_files _keep_files = not clean @@ -559,7 +630,7 @@ def cli(ctx, version: str | None, clean: bool): return # Ensure we're in the repo root - if not Path("mkdocs.yml").exists(): + if not Path("docs/en/mkdocs.yml").exists(): console.print("[red]Error:[/red] Must be run from the training repository root") sys.exit(1) @@ -572,6 +643,14 @@ def cli(ctx, version: str | None, clean: bool): ) sys.exit(1) + # Determine which languages to build + if all_languages: + languages = discover_languages() + status_msg("setup", f"Building all languages: {', '.join(languages)}") + else: + languages = ["en"] + status_msg("setup", "Building English only (use -a for all languages)") + # Register cleanup handlers atexit.register(cleanup) signal.signal(signal.SIGINT, lambda s, f: sys.exit(0)) @@ -582,7 +661,7 @@ def cli(ctx, version: str | None, clean: bool): modify_hosts() # Do this early so user isn't prompted after long build generate_certificates() fetch_gh_pages() - build_docs(version) + build_docs(version, languages, parallel=not sequential) update_versions_json(version) create_caddyfile() @@ -597,7 +676,7 @@ def cli(ctx, version: str | None, clean: bool): def status(): """Show current preview release status.""" # Ensure we're in the repo root - if not Path("mkdocs.yml").exists(): + if not Path("docs/en/mkdocs.yml").exists(): console.print("[red]Error:[/red] Must be run from the training repository root") sys.exit(1) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 5681015d8d..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -mkdocs -mkdocs-material -mkdocs-static-i18n -pymdown-extensions>=10.12 -pillow -cairosvg -mkdocs-enumerate-headings-plugin>=0.6.0 -mkdocs-quiz>=1.5.0 -mike diff --git a/scripts/build-multilang.sh b/scripts/build-multilang.sh new file mode 100755 index 0000000000..43cb578809 --- /dev/null +++ b/scripts/build-multilang.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# Build multilingual MkDocs site for deployment with mike +# Usage: ./build-multilang.sh <version> [output_dir] + +set -e + +VERSION="${1:-latest}" +OUTPUT_DIR="${2:-/tmp/multilang-build}" +DOCS_DIR="$(cd "$(dirname "$0")/../docs" && pwd)" + +# Dynamically discover languages from docs/ directories containing mkdocs.yml +LANGUAGES=($(find "$DOCS_DIR" -maxdepth 2 -name "mkdocs.yml" -exec dirname {} \; | xargs -n1 basename | sort)) + +echo "Building multilingual site for version: $VERSION" +echo "Output directory: $OUTPUT_DIR" +echo "Languages: ${LANGUAGES[*]}" + +# Clean output directory +rm -rf "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" + +# Build each language +for lang in "${LANGUAGES[@]}"; do + echo "" + echo "=== Building $lang ===" + + CONFIG_FILE="$DOCS_DIR/$lang/mkdocs.yml" + + if [ ! -f "$CONFIG_FILE" ]; then + echo "Warning: Config not found for $lang at $CONFIG_FILE, skipping..." + continue + fi + + # Determine the output path based on language + if [ "$lang" = "en" ]; then + LANG_OUTPUT="$OUTPUT_DIR" + else + LANG_OUTPUT="$OUTPUT_DIR/$lang" + fi + + # Build with overridden site_url + # For EN: site_url is base (e.g., https://training.nextflow.io/latest/) + # For other langs: site_url includes lang (e.g., https://training.nextflow.io/latest/pt/) + if [ "$lang" = "en" ]; then + SITE_URL="https://training.nextflow.io/$VERSION/" + else + SITE_URL="https://training.nextflow.io/$VERSION/$lang/" + fi + + echo "Building to: $LANG_OUTPUT" + echo "Site URL: $SITE_URL" + + # Run mkdocs build with proper site_url + cd "$DOCS_DIR/$lang" + mkdocs build -f "$CONFIG_FILE" -d "$LANG_OUTPUT" 2>&1 | tail -5 + + echo "Built $lang successfully" +done + +echo "" +echo "=== Build complete ===" +echo "Output: $OUTPUT_DIR" +ls -la "$OUTPUT_DIR"